目录
011_java逆向解密
用jadx打开,看源码
package defpackage;
import java.util.ArrayList;
import java.util.Scanner;
/* renamed from: Reverse reason: default package */
public class Reverse {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("Please input the flag :");
String str = s.next();
System.out.println("Your input is :");
System.out.println(str);
Encrypt(str.toCharArray());
}
public static void Encrypt(char[] arr) {
ArrayList<Integer> Resultlist = new ArrayList<>();
for (char c : arr) {
Resultlist.add(Integer.valueOf((c + '@') ^ 32));
}
int[] KEY = {180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65};
ArrayList<Integer> KEYList = new ArrayList<>();
for (int valueOf : KEY) {
KEYList.add(Integer.valueOf(valueOf));
}
System.out.println("Result:");
if (Resultlist.equals(KEYList)) {
System.out.println("Congratulations!");
} else {
System.err.println("Error!");
}
}
}
直接给出字符值为+0x40再异或32,解反顺序处理一下
key = [180, 136, 137, 147, 191, 137, 147, 191, 148, 136, 133, 191, 134, 140, 129, 135, 191, 65]
print(bytes([( i^32 + 0xc0)&0xff for i in key ]))
#This_is_the_flag_\xa1
#flag{This_is_the_flag_!}
012_[GXYCTF2019]luck_guy
主函数在get_flag
unsigned __int64 get_flag()
{
unsigned int v0; // eax
int i; // [rsp+4h] [rbp-3Ch]
int j; // [rsp+8h] [rbp-38h]
__int64 s[5]; // [rsp+10h] [rbp-30h] BYREF
unsigned __int64 v5; // [rsp+38h] [rbp-8h]
v5 = __readfsqword(0x28u);
v0 = time(0LL);
srand(v0);
for ( i = 0; i <= 4; ++i )
{
switch ( rand() % 200 )
{
case 1:
puts("OK, it's flag:");
memset(s, 0, sizeof(s));
strcat((char *)s, f1);
strcat((char *)s, &f2);
printf("%s", (const char *)s);
break;
case 2:
printf("Solar not like you");
break;
case 3:
printf("Solar want a girlfriend");
break;
case 4:
strcpy((char *)s, "icug`of\x7F");
strcat(&f2, (const char *)s);
break;
case 5:
for ( j = 0; j <= 7; ++j )
{
if ( j % 2 == 1 )
*(&f2 + j) -= 2;
else
--*(&f2 + j);
}
break;
default:
puts("emmm,you can't find flag 23333");
break;
}
}
return __readfsqword(0x28u) ^ v5;
}
这个运行不了,但可以看到先是把给定串按奇偶位处理一下再输出
f2 = '\x7Ffo`guci'[::-1]
f2a = ''
for i in range(8):
if i%2 == 1:
f2a += chr(ord(f2[i]) - 2)
else:
f2a += chr(ord(f2[i]) - 1)
flag = 'GXY{do_not_'+f2a
print(flag )
#GXY{do_not_hate_me}
#flag{do_not_hate_me}
013_刮开有奖
程序运行不了,除了sub_4010F0都很容易理解
INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[2]; // [esp+8h] [ebp-20030h] BYREF
int v8; // [esp+10h] [ebp-20028h]
int v9; // [esp+14h] [ebp-20024h]
int v10; // [esp+18h] [ebp-20020h]
int v11; // [esp+1Ch] [ebp-2001Ch]
int v12; // [esp+20h] [ebp-20018h]
int v13; // [esp+24h] [ebp-20014h]
int v14; // [esp+28h] [ebp-20010h]
int v15; // [esp+2Ch] [ebp-2000Ch]
int v16; // [esp+30h] [ebp-20008h]
CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
char v18[65536]; // [esp+10034h] [ebp-10004h] BYREF
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 )
{
v7[0] = 90;
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
sub_4010F0((int)v7, 0, 10);
memset(v18, 0, 0xFFFFu);
v18[0] = String[5];
v18[2] = String[7];
v18[1] = String[6];
v4 = sub_401000((int)v18, strlen(v18));
memset(v18, 0, 0xFFFFu);
v18[1] = String[3];
v18[0] = String[2];
v18[2] = String[4];
v5 = sub_401000((int)v18, strlen(v18));
if ( String[0] == v7[0] + 34
&& String[1] == v10
&& 4 * String[2] - 141 == 3 * v8
&& String[3] / 4 == 2 * (v13 / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
sub_4010F0每次选一个最大的放到最后,实际上就是个冒泡
INT_PTR __stdcall DialogFunc(HWND hDlg, UINT a2, WPARAM a3, LPARAM a4)
{
const char *v4; // esi
const char *v5; // edi
int v7[2]; // [esp+8h] [ebp-20030h] BYREF
int v8; // [esp+10h] [ebp-20028h]
int v9; // [esp+14h] [ebp-20024h]
int v10; // [esp+18h] [ebp-20020h]
int v11; // [esp+1Ch] [ebp-2001Ch]
int v12; // [esp+20h] [ebp-20018h]
int v13; // [esp+24h] [ebp-20014h]
int v14; // [esp+28h] [ebp-20010h]
int v15; // [esp+2Ch] [ebp-2000Ch]
int v16; // [esp+30h] [ebp-20008h]
CHAR String[65536]; // [esp+34h] [ebp-20004h] BYREF
char v18[65536]; // [esp+10034h] [ebp-10004h] BYREF
memset(String, 0, 0xFFFFu);
GetDlgItemTextA(hDlg, 1000, String, 0xFFFF);
if ( strlen(String) == 8 )
{
v7[0] = 90;
v7[1] = 74;
v8 = 83;
v9 = 69;
v10 = 67;
v11 = 97;
v12 = 78;
v13 = 72;
v14 = 51;
v15 = 110;
v16 = 103;
sub_4010F0((int)v7, 0, 10);
memset(v18, 0, 0xFFFFu);
v18[0] = String[5];
v18[2] = String[7];
v18[1] = String[6];
v4 = sub_401000((int)v18, strlen(v18));
memset(v18, 0, 0xFFFFu);
v18[1] = String[3];
v18[0] = String[2];
v18[2] = String[4];
v5 = sub_401000((int)v18, strlen(v18));
if ( String[0] == v7[0] + 34
&& String[1] == v10
&& 4 * String[2] - 141 == 3 * v8
&& String[3] / 4 == 2 * (v13 / 9)
&& !strcmp(v4, "ak1w")
&& !strcmp(v5, "V1Ax") )
{
MessageBoxA(hDlg, "U g3t 1T!", "@_@", 0);
}
}
return 0;
}
解法也算简单
v18 = [90,74,83,69,67,97,78,72,51,110,103]
v18.sort()
from base64 import b64decode
v18 = bytes([v18[0]+34, v18[4]] ) + b64decode('V1Axak1w') #01,234567
print(v18)
#UJWP1jMp
#flag{UJWP1jMp}
014_[BJDCTF2020]JustRE
几乎是直接给,把19999和0直接写进去就行了
INT_PTR __stdcall DialogFunc(HWND hWnd, UINT a2, WPARAM a3, LPARAM a4)
{
CHAR String[100]; // [esp+0h] [ebp-64h] BYREF
if ( a2 != 272 )
{
if ( a2 != 273 )
return 0;
if ( (_WORD)a3 != 1 && (_WORD)a3 != 2 )
{
sprintf(String, &Format, ++dword_4099F0);
if ( dword_4099F0 == 19999 )
{
sprintf(String, " BJD{%d%d2069a45792d233ac}", 19999, 0);
SetWindowTextA(hWnd, String);
return 0;
}
SetWindowTextA(hWnd, String);
return 0;
}
EndDialog(hWnd, (unsigned __int16)a3);
}
return 1;
}
015_findit
onCreate方法
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_main);
final EditText edit = (EditText) findViewById(R.id.widget2);
final TextView text = (TextView) findViewById(R.id.widget1);
final char[] a = {'T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e'};
final char[] b = {'p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}'};
((Button) findViewById(R.id.widget3)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
char[] x = new char[17];
char[] y = new char[38];
for (int i = 0; i < 17; i++) {
if ((a[i] < 'I' && a[i] >= 'A') || (a[i] < 'i' && a[i] >= 'a')) {
x[i] = (char) (a[i] + 18);
} else if ((a[i] < 'A' || a[i] > 'Z') && (a[i] < 'a' || a[i] > 'z')) {
x[i] = a[i];
} else {
x[i] = (char) (a[i] - 8);
}
}
if (String.valueOf(x).equals(edit.getText().toString())) {
for (int i2 = 0; i2 < 38; i2++) {
if ((b[i2] < 'A' || b[i2] > 'Z') && (b[i2] < 'a' || b[i2] > 'z')) {
y[i2] = b[i2];
} else {
y[i2] = (char) (b[i2] + 16);
if ((y[i2] > 'Z' && y[i2] < 'a') || y[i2] >= 'z') {
y[i2] = (char) (y[i2] - 26);
}
}
}
text.setText(String.valueOf(y));
return;
}
text.setText("答案错了肿么办。。。不给你又不好意思。。。哎呀好纠结啊~~~");
}
});
}
翻译成python
a = ['T', 'h', 'i', 's', 'I', 's', 'T', 'h', 'e', 'F', 'l', 'a', 'g', 'H', 'o', 'm', 'e']
b = ['p', 'v', 'k', 'q', '{', 'm', '1', '6', '4', '6', '7', '5', '2', '6', '2', '0', '3', '3', 'l', '4', 'm', '4', '9', 'l', 'n', 'p', '7', 'p', '9', 'm', 'n', 'k', '2', '8', 'k', '7', '5', '}']
a = ''.join(a).encode()
b = ''.join(b).encode()
x = [0]*17
y = [0]*38
for i,v in enumerate(a):
if (v < ord('I') and v>= ord('A')) or (v < ord('i') and v>= ord('a')):
x[i] = v+18
elif (v < ord('A') or v>= ord('Z')) and (v < ord('a') and v> ord('z')):
x[i] = v
else:
x[i] = v -8
print(bytes(x))
for i,v in enumerate(b):
if (v < ord('A') or v> ord('Z')) and (v < ord('a') or v> ord('z')):
y[i] = v
else:
y[i] = v +16
if (y[i] > ord('Z') and y[i]< ord('a')) or (y[i] >= ord('z')):
y[i] = y[i]-26
print(bytes(y))
#flag{c164675262033b4c49bdf7f9cda28a75}
016_简单注册器
又一个apk的题,onCreate有算法
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView((int) R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction().add((int) R.id.container, (Fragment) new PlaceholderFragment()).commit();
}
final TextView textview = (TextView) findViewById(R.id.textView1);
final EditText editview = (EditText) findViewById(R.id.editText1);
((Button) findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
public void onClick(View v) {
int flag = 1;
String xx = editview.getText().toString();
if (!(xx.length() == 32 && xx.charAt(31) == 'a' && xx.charAt(1) == 'b' && (xx.charAt(0) + xx.charAt(2)) - 48 == 56)) {
flag = 0;
}
if (flag == 1) {
char[] x = "dd2940c04462b4dd7c450528835cca15".toCharArray();
x[2] = (char) ((x[2] + x[3]) - 50);
x[4] = (char) ((x[2] + x[5]) - 48);
x[30] = (char) ((x[31] + x[9]) - 48);
x[14] = (char) ((x[27] + x[28]) - 97);
for (int i = 0; i < 16; i++) {
char a = x[31 - i];
x[31 - i] = x[i];
x[i] = a;
}
textview.setText("flag{" + String.valueOf(x) + "}");
return;
}
textview.setText("输入注册码错误");
}
});
}
翻译
x = list(b'dd2940c04462b4dd7c450528835cca15')
x[2] = (x[2]+x[3]-50)
x[4] = (x[2]+x[5]-48)
x[30] = (x[31]+x[9]-48)
x[14] = (x[27]+x[28]-97)
print(b'flag{'+bytes(x)[::-1]+b'}')
#flag{59acc538825054c7de4b26440c0999dd}
017_[GWCTF 2019]pyre
一个pyc程序,网上直接反编译
print 'Welcome to Re World!'
print 'Your input1 is your flag~'
l = len(input1)
for i in range(l):
num = ((input1[i] + i) % 128 + 128) % 128
code += num
for i in range(l - 1):
code[i] = code[i] ^ code[i + 1]
print code
code = [
'\x1f', ...... ]
逆回
code = [
'\x1f','\x12','\x1d', '(', '0', '4', '\x01', '\x06', '\x14', '4', ',', '\x1b', 'U', '?', 'o', '6', '*', ':', '\x01', 'D', ';', '%', '\x13']
code = [ord(i) for i in code]
for i in range(len(code)-2,-1,-1):
code[i] = code[i]^code[i+1]
print(bytes([(v-i+128)%128 for i,v in enumerate(code) ]))
#GWHT{Just_Re_1s_Ha66y!}
#flag{Just_Re_1s_Ha66y!}
018_[ACTF新生赛2020]easyre
简单的查表
int __cdecl main(int argc, const char **argv, const char **envp)
{
_BYTE v4[12]; // [esp+12h] [ebp-2Eh] BYREF
_DWORD v5[3]; // [esp+1Eh] [ebp-22h]
_BYTE v6[5]; // [esp+2Ah] [ebp-16h] BYREF
int v7; // [esp+2Fh] [ebp-11h]
int v8; // [esp+33h] [ebp-Dh]
int v9; // [esp+37h] [ebp-9h]
char v10; // [esp+3Bh] [ebp-5h]
int i; // [esp+3Ch] [ebp-4h]
__main();
qmemcpy(v4, "*F'\"N,\"(I?+@", sizeof(v4));
printf("Please input:");
scanf("%s", v6);
if ( v6[0] != 65 || v6[1] != 67 || v6[2] != 84 || v6[3] != 70 || v6[4] != 123 || v10 != 125 )
return 0;
v5[0] = v7;
v5[1] = v8;
v5[2] = v9;
for ( i = 0; i <= 11; ++i )
{
if ( v4[i] != _data_start__[*((char *)v5 + i) - 1] )
return 0;
}
printf("You are correct!");
return 0;
}
回查
v4 = b"*F'\"N,\"(I?+@"
code = b'\x7e}|{zyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$# !"@'
#v4[i] != _data_start__[*((char *)v5 + i) - 1]
print(bytes([code.index(i)+1 for i in v4]))
#U9X_1S_W6@T?
#flag{U9X_1S_W6@T?}
019_rsa
rsa不放到crypto放到reverse,直接给了一个很小可以分解的分解
from gmpy2 import *
from libnum import s2n,n2s
n = 86934482296048119190666062003494800588905656017203025617216654058378322103517
p = 285960468890451637935629440372639283459
q = n // p
e = 65537
phi = (p-1)*(q-1)
d = invert(e, phi )
c = open('flag.enc', 'rb').read()
c = s2n(c)
m = pow(c, d, n )
print(m)
print(n2s(int(m)))
#flag{decrypt_256}
020_[ACTF新生赛2020]rome
一个不太复杂的移位操作
v1[0] = v7;
v1[1] = v8;
v1[2] = v9;
v1[3] = v10;
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 64 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 90 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 51) % 26 + 65;
if ( *((char *)v1 + *(_DWORD *)&v12[17]) > 96 && *((char *)v1 + *(_DWORD *)&v12[17]) <= 122 )
*((_BYTE *)v1 + *(_DWORD *)&v12[17]) = (*((char *)v1 + *(_DWORD *)&v12[17]) - 79) % 26 + 97;
++*(_DWORD *)&v12[17];
}
*(_DWORD *)&v12[17] = 0;
while ( *(int *)&v12[17] <= 15 )
{
result = (unsigned __int8)v12[*(_DWORD *)&v12[17]];
if ( *((_BYTE *)v1 + *(_DWORD *)&v12[17]) != (_BYTE)result )
return result;
++*(_DWORD *)&v12[17];
}
return printf("You are correct!");
爆破
import string
s = b"Qsw3sj_lz4_Ujw@l"
letter = string.ascii_lowercase + string.ascii_uppercase + string.digits + '_@'
flag = ''
for i in range(16):
for j in letter:
if j.isupper():
v = (ord(j)-51)%26 + 65
elif j.islower():
v = (ord(j)-79)%26 + 97
else:
v = ord(j)
#print(v, j )
if v == s[i]:
flag += j
print(flag)
break
#Cae3ar_th4_Gre@t
#flag{Cae3ar_th4_Gre@t}
021_CrackRTF
第一步求6位数据的sha1,这个需要爆破
第二步就复杂了,不过后边有人漏洞,它用这个密钥加密后得到的文件有固定文件头(大多数文件都有固定文件头),这个第二步就不用解了,直接用固定头异或得到
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
DWORD v3; // eax
DWORD v4; // eax
char Str[260]; // [esp+4Ch] [ebp-310h] BYREF
int v7; // [esp+150h] [ebp-20Ch]
char String1[260]; // [esp+154h] [ebp-208h] BYREF
char Destination[260]; // [esp+258h] [ebp-104h] BYREF
memset(Destination, 0, sizeof(Destination));
memset(String1, 0, sizeof(String1));
v7 = 0;
printf("pls input the first passwd(1): ");
scanf("%s", Destination);
if ( strlen(Destination) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
v7 = atoi(Destination);
if ( v7 < 100000 )
ExitProcess(0);
strcat(Destination, "@DBApp");
v3 = strlen(Destination);
sub_40100A((BYTE *)Destination, v3, String1);
if ( !_strcmpi(String1, "6E32D0943418C2C33385BC35A1470250DD8923A9") )
{
printf("continue...\n\n");
printf("pls input the first passwd(2): ");
memset(Str, 0, sizeof(Str));
scanf("%s", Str);
if ( strlen(Str) != 6 )
{
printf("Must be 6 characters!\n");
ExitProcess(0);
}
strcat(Str, Destination);
memset(String1, 0, sizeof(String1));
v4 = strlen(Str);
sub_401019((BYTE *)Str, v4, String1);
if ( !_strcmpi("27019e688a4e62a649fd99cadaafdb4e", String1) )
{
if ( !(unsigned __int8)sub_40100F(Str) )
{
printf("Error!!\n");
ExitProcess(0);
}
printf("bye ~~\n");
}
}
return 0;
}
解码
from hashlib import sha1, md5
import string
#https://docs.microsoft.com/zh-cn/windows/win32/seccrypto/alg-id?redirectedfrom=MSDN
#0x8004 sha1
for i in range(100000, 1000000):
#print(sha1(str(i).encode() +b'@DBApp').hexdigest())
if sha1(str(i).encode() +b'@DBApp').hexdigest().upper() == "6E32D0943418C2C33385BC35A1470250DD8923A9":
print(i)
break
#123321
#ResourceHacker 程序中的文件资源AAA 与密钥异或后生成 dbapp.rtf文件,rtf文件头固定格式,前6字符得到密钥,输入密钥生成文件
aaa = [0x05, 0x7D, 0x41, 0x15, 0x26, 0x01]
rtf = [0x7b, 0x5c, 0x72, 0x74, 0x66, 0x31]
for i in range(6):
print(chr(aaa[i]^rtf[i]), end='')
#~!3a@0
#Flag{N0_M0re_Free_Bugs}
#flag{N0_M0re_Free_Bugs}
022_[FlareOn4]login
FlareOn都有固定格式,这题比较特殊是javascript,就一句
var rotFlag = flag.replace(/[a-zA-Z]/g, function(c){return String.fromCharCode((c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26);});
if ("PyvragFvqrYbtvafNerRnfl@syner-ba.pbz" == rotFlag) {
alert("Correct flag!");
} else {
alert("Incorrect flag, rot again");
}
解密,没有方便的三元运算符,写得较js长
#(c <= "Z" ? 90 : 122) >= (c = c.charCodeAt(0) + 13) ? c : c - 26
import string
a = b'PyvragFvqrYbtvafNerRnfl@syner-ba.pbz' #@syner-ba.pbz
for i,v in enumerate(a):
if chr(v) in '@-.':
print(chr(v), end='')
else:
for jj in string.ascii_uppercase+string.ascii_lowercase:
j = ord(jj)
if j <= ord('Z'):
k = 90
else:
k = 122
c = j +13
if c > k:
c -=26
if c == v:
print(chr(j), end='')
break
#ClientSideLoginsAreEasy@flare-on.com
#flag{ClientSideLoginsAreEasy@flare-on.com}
023_[2019红帽杯]easyRE
第1段没啥用,第2段是10次base64编译
__int64 sub_4009C6()
{
__int64 result; // rax
int i; // [rsp+Ch] [rbp-114h]
__int64 v2; // [rsp+10h] [rbp-110h]
__int64 v3; // [rsp+18h] [rbp-108h]
__int64 v4; // [rsp+20h] [rbp-100h]
__int64 v5; // [rsp+28h] [rbp-F8h]
__int64 v6; // [rsp+30h] [rbp-F0h]
__int64 v7; // [rsp+38h] [rbp-E8h]
__int64 v8; // [rsp+40h] [rbp-E0h]
__int64 v9; // [rsp+48h] [rbp-D8h]
__int64 v10; // [rsp+50h] [rbp-D0h]
__int64 v11; // [rsp+58h] [rbp-C8h]
char v12[13]; // [rsp+60h] [rbp-C0h] BYREF
char v13[4]; // [rsp+6Dh] [rbp-B3h] BYREF
char v14[19]; // [rsp+71h] [rbp-AFh] BYREF
char v15[32]; // [rsp+90h] [rbp-90h] BYREF
int v16; // [rsp+B0h] [rbp-70h]
char v17; // [rsp+B4h] [rbp-6Ch]
char v18[72]; // [rsp+C0h] [rbp-60h] BYREF
unsigned __int64 v19; // [rsp+108h] [rbp-18h]
v19 = __readfsqword(0x28u);
qmemcpy(v12, "Iodl>Qnb(ocy", 12);
v12[12] = 127;
qmemcpy(v13, "y.i", 3);
v13[3] = 127;
qmemcpy(v14, "d`3w}wek9{iy=~yL@EC", sizeof(v14));
memset(v15, 0, sizeof(v15));
v16 = 0;
v17 = 0;
readn(0, v15, 0x25uLL);
v17 = 0;
if ( strlen(v15) == 36 )
{
for ( i = 0; i < (unsigned __int64)strlen(v15); ++i )
{
if ( (unsigned __int8)(v15[i] ^ i) != v12[i] )
{
result = 4294967294LL;
goto LABEL_13;
}
}
sub_410CC0("continue!");
memset(v18, 0, 65);
readn(0, v18, 0x40uLL);
v18[39] = 0;
if ( strlen(v18) == 39 )
{
v2 = base64encode(v18);
v3 = base64encode(v2);
v4 = base64encode(v3);
v5 = base64encode(v4);
v6 = base64encode(v5);
v7 = base64encode(v6);
v8 = base64encode(v7);
v9 = base64encode(v8);
v10 = base64encode(v9);
v11 = base64encode(v10);
if ( !(unsigned int)sub_400360(v11, off_6CC090) )
{
sub_410CC0("You found me!!!");
sub_410CC0("bye bye~");
}
result = 0LL;
}
else
{
result = 4294967293LL;
}
}
else
{
result = 0xFFFFFFFFLL;
}
LABEL_13:
if ( __readfsqword(0x28u) != v19 )
sub_444020();
return result;
}
解回
from base64 import b64decode
a = b"Iodl>Qnb(ocy\x7fy.i\x7fd`3w}wek9{iy=~yL@EC"
print(bytes([i^v for i,v in enumerate(a)])) #b'Info:The first four chars are `flag`'
from base64 import b64decode
a = 'Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJsbDNXa1pPVlUxV2NIcFhhMk0xVmpKS1NHVkdXbFpOYmtKVVZtcEtTMUl5VGtsaVJtUk9ZV3hhZVZadGVHdFRNVTVYVW01T2FGSnRVbGhhVjNoaFZWWmtWMXBFVWxSTmJFcElWbTAxVDJGV1NuTlhia0pXWWxob1dGUnJXbXRXTVZaeVdrWm9hVlpyV1hwV1IzaGhXVmRHVjFOdVVsWmlhMHBZV1ZSR1lWZEdVbFZTYlhSWFRWWndNRlZ0TVc5VWJGcFZWbXR3VjJKSFVYZFdha1pXWlZaT2NtRkhhRk5pVjJoWVYxZDBhMVV3TlhOalJscFlZbGhTY1ZsclduZGxiR1J5VmxSR1ZXSlZjRWhaTUZKaFZqSktWVkZZYUZkV1JWcFlWV3BHYTFkWFRrZFRiV3hvVFVoQ1dsWXhaRFJpTWtsM1RVaG9hbEpYYUhOVmJUVkRZekZhY1ZKcmRGTk5Wa3A2VjJ0U1ExWlhTbFpqUldoYVRVWndkbFpxUmtwbGJVWklZVVprYUdFeGNHOVhXSEJIWkRGS2RGSnJhR2hTYXpWdlZGVm9RMlJzV25STldHUlZUVlpXTlZadE5VOVdiVXBJVld4c1dtSllUWGhXTUZwell6RmFkRkpzVWxOaVNFSktWa1phVTFFeFduUlRhMlJxVWxad1YxWnRlRXRXTVZaSFVsUnNVVlZVTURrPQ=='
for i in range(10):
a = b64decode(a)
print(a) #https://bbs.pediy.com/thread-254172.htm
#flag{Act1ve_Defen5e_Test}
024_[GUET-CTF2019]re
这个人得有多恶心
if ( 1629056 * *a1 != 166163712 )
return 0LL;
if ( 6771600 * a1[1] != 731332800 )
return 0LL;
if ( 3682944 * a1[2] != 357245568 )
return 0LL;
if ( 10431000 * a1[3] != 1074393000 )
return 0LL;
if ( 3977328 * a1[4] != 489211344 )
return 0LL;
if ( 5138336 * a1[5] != 518971936 )
return 0LL;
if ( 7532250 * a1[7] != 406741500 )
return 0LL;
if ( 5551632 * a1[8] != 294236496 )
return 0LL;
......
然后一个个抄下来
def getc(a, b):
print(chr(b//a), end='')
getc(1629056,166163712)
getc(6771600,731332800)
getc(3682944,357245568)
getc(10431000,1074393000)
getc(3977328,489211344)
getc(5138336,518971936)
print('?', end='')
getc(7532250,406741500)
getc(5551632,294236496)
getc(3409728,177305856)
getc(13013670,650683500)
getc(6088797,298351053)
getc(7884663,386348487)
getc(8944053,438258597)
getc(5198490, 249527520 )
getc(4544518,445362764)
getc(10115280,981182160)
getc(3645600,174988800)
getc(9667504,493042704)
getc(5364450,257493600)
getc(13464540,767478780)
getc(5488432,312840624)
getc(14479500,1404511500)
getc(6451830,316139670)
getc(6252576,619005024)
getc(7763364,372641472)
getc(7327320,373693320)
getc(8741520,498266640)
getc(8871876,452465676)
getc(4086720,208422720)
getc(9374400,515592000)
getc(5759124,719890500)
#flag{e?65421110ba03099a1c039337}
#flag{e165421110ba03099a1c039337}
025_[WUSTCTF2020]level1
一堆数字的简单运算,分奇偶
for ( i = 1; i <= 19; ++i )
{
if ( (i & 1) != 0 )
printf("%ld\n", (unsigned int)(ptr[i] << i));
else
printf("%ld\n", (unsigned int)(i * ptr[i]));
}
解码
a = [198,232,816,200,1536,300,6144,984,51200,570,92160,1200,565248,756,1474560,800,6291456,1782,65536000]
for i in range(1,20):
if i&1 != 0:
print(chr(a[i-1]>>i), end='')
else:
print(chr(a[i-1]//i), end='')
#ctf2020{d9-dE6-20c}
#flag{d9-dE6-20c}
026_[SUCTF2019]SignIn
模幂运算,又是rsa
from gmpy2 import invert
from libnum import n2s
c = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
e = 65537
n = 103461035900816914121390101299049044413950405173712170434161686539878160984549
p = 282164587459512124844245113950593348271
q = n//p
phi = (p-1)*(q-1)
d = invert(e, phi)
m = pow(c,d,n)
print(n2s(int(m)))
#suctf{Pwn_@_hundred_years}
#flag{Pwn_@_hundred_years}
027_[MRCTF2020]Transform
异或运算
for ( i = 0; i <= 32; ++i )
{
byte_414040[i] = Str[dword_40F040[i]];
byte_414040[i] ^= LOBYTE(dword_40F040[i]);
}
解码
ae0 = [0x67, 0x79, 0x7B, 0x7F, 0x75, 0x2B, 0x3C, 0x52, 0x53, 0x79, 0x57, 0x5E, 0x5D, 0x42, 0x7B, 0x2D, 0x2A, 0x66, 0x42, 0x7E, 0x4C, 0x57, 0x79, 0x41, 0x6B, 0x7E, 0x65, 0x3C, 0x5C, 0x45, 0x6F, 0x62, 0x4D, 0x3F]
a40 = [9, 0xA, 0x0F, 0x17, 7, 0x18, 0x0C, 0x6, 1, 0x10, 0x3, 0x11, 0x20, 0x1D, 0x0B, 0x1E, 0x1B, 0x16, 4, 0xD, 0x13, 0x14, 0x15, 2, 0x19, 5, 0x1F, 8, 0x12, 0x1A, 0x1C, 0x0E, 0]
print(len(ae0), len(a40))
str = [0]*33
for i in range(33):
str[a40[i]] = ae0[i]^a40[i]
print(bytes(str))
#MRCTF{Tr4nsp0sltiON_Clph3r_1s_3z}
#flag{Tr4nsp0sltiON_Clph3r_1s_3z}
028_[WUSTCTF2020]level2
直接给了
mov [ebp+var_C], offset flag ; "wctf2020{Just_upx_-d}"
sub esp, 0Ch
push offset aWhereIsIt ; "where is it?"
029_[ACTF新生赛2020]usualCrypt
变码表的base64
第1变
int sub_401000()
{
int result; // eax
char v1; // cl
for ( result = 6; result < 15; ++result )
{
v1 = byte_40E0AA[result];
byte_40E0AA[result] = byte_40E0A0[result];
byte_40E0A0[result] = v1;
}
return result;
}
第2变
int __cdecl sub_401030(const char *a1)
{
__int64 v1; // rax
char v2; // al
v1 = 0i64;
if ( strlen(a1) )
{
do
{
v2 = a1[HIDWORD(v1)];
if ( v2 < 97 || v2 > 122 )
{
if ( v2 < 65 || v2 > 90 )
goto LABEL_9;
LOBYTE(v1) = v2 + 32; // 大写+32
}
else
{
LOBYTE(v1) = v2 - 32; // 小写-32
}
a1[HIDWORD(v1)] = v1;
LABEL_9:
LODWORD(v1) = 0;
++HIDWORD(v1);
}
while ( HIDWORD(v1) < strlen(a1) );
}
return v1;
}
逆回
a = b'zMXHz3TIgnxLxJhFAdtZn2fFk3lYCrtPC2l9'
pcode = b'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
ncode = list(pcode)
for i in range(6,15):
ncode[i], ncode[i+10] = ncode[i+10], ncode[i]
b = [0]*len(a)
for i,v in enumerate(a):
if v>=ord('A') and v<=ord('Z'):
b[i] = v+32
elif v>=ord('a') and v<=ord('z'):
b[i] = v-32
else:
b[i] = v
b[i] = pcode[ncode.index(b[i])]
from base64 import b64decode
print(b64decode(bytes(b)))
#flag{bAse64_h2s_a_Surprise}
030_Youngter-drive
感觉特复杂,先是用两个进程共享一个值,作到仅对奇数位处理
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
void *v3; // ecx
HANDLE Thread; // [esp+D0h] [ebp-14h]
HANDLE hObject; // [esp+DCh] [ebp-8h]
sub_4110FF(v3); // 读flag到Source
::hObject = CreateMutexW(0, 0, 0);
j_strcpy(Destination, Source);
hObject = CreateThread(0, 0, StartAddress, 0, 0, 0);// 411B10,StartAddress_0交互执行418008 -1,仅单位执行加密处理
Thread = CreateThread(0, 0, j_ex_418008, 0, 0, 0);// 418008 初始值为29,flag共30字符,最后1位未校验
CloseHandle(hObject);
CloseHandle(Thread);
while ( dword_418008 != -1 )
;
j_check();
CloseHandle(::hObject);
return 0;
}
StartAddress里有加密处理
// positive sp value has been detected, the output may be wrong!
char *__cdecl enc(int a1, int a2)
{
char *result; // eax
char v3; // [esp+D3h] [ebp-5h]
v3 = *(_BYTE *)(a2 + a1);
if ( (v3 < 97 || v3 > 122) && (v3 < 65 || v3 > 90) )
exit(0);
if ( v3 < 97 || v3 > 122 )
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 38];
}
else
{
result = off_418000[0];
*(_BYTE *)(a2 + a1) = off_418000[0][*(char *)(a2 + a1) - 96];
}
return result;
}
然后是一个检查
int check()
{
int i; // [esp+D0h] [ebp-8h]
for ( i = 0; i < 29; ++i )
{
if ( Source[i] != off_418004[i] )
exit(0);
}
return printf("\nflag{%s}\n\n", Destination);
}
看似简单但不对,网上搜了下,问题在这,初始值为0x1d一共30位。但检查运算只有29位。只能爆破提交网站补未位
.data:00418008 1D 00 00 00 dword_418008 dd 1Dh
结果
a = b'TOiZiZtOrYaToUwPnToBsOaOapsyS'
b = b'QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm '
import string
for i in range(len(a)):
if i%2 == 0:
print(chr(a[i]), end='')
continue
for d in string.ascii_uppercase+string.ascii_lowercase:
if d>='A' and d<='Z':
c = b[ord(d)-38]
else:
c = b[ord(d)-96]
if c == a[i]:
print(d, end='')
break
#ThisisthreadofwindowshahaIsES
#flag{ThisisthreadofwindowshahaIsESE} ?输入30,前面只对比29
得来1分题也不简单,1分题只是因为能搜到wp
031_相册
apk题用jni打开找到这个,解开后得到18218465125@163.com
EXPORT Java_com_net_cn_NativeMethod_m
Java_com_net_cn_NativeMethod_m
; __unwind {
PUSH {R3,LR}
LDR R2, [R0]
LDR R1, =(aMtgymtg0njuxmj_0 - 0xC8E) ; "MTgyMTg0NjUxMjVAMTYzLmNvbQ=="
MOVS R3, #0x29C
ADD R1, PC ; "MTgyMTg0NjUxMjVAMTYzLmNvbQ=="
LDR R3, [R2,R3]
BLX R3
POP {R3,PC}
; End of function Java_com_net_cn_NativeMethod_m
其实这题要的就是email的地址
flag{18218465125@163.com}
032_[HDCTF2019]Maze
这个一般都是迷宫,找到一个串
.data:00408030 2A 2A 2A 2A 2A 2A 2A 2B 2A 2A+db '*******+********* ****** **** ******* **F****** **************',0
处理得到
'''
upx去壳
start跳转nop花指令第1字节e8
在main处生成函数
发现是迷宫,横纵坐标78,7c,跟到,发现前面的迷宫,横坐标7,确定是10*7迷宫,折行后得到迷宫,走出线路
*******+**
******* **
**** **
** *****
** **F****
** ****
**********
ssaaasaassdddw
'''
#flag{ssaaasaassdddw}