DawgCTF{+h@nk_Y0U}
__int64 __fastcall main(__int64 a1, char **a2, char **a3) { puts("Let me search ya."); fgets(string, 44, stdin); if ( strnlen(string, 0x2BuLL) != 43 ) { sub_1195(); exit(1); } sub_12F2(); sub_11F7(); sub_11BB(); return 0LL; }
sub_1195函数:输出错误信息
int sub_1195() { return puts("Wrong. You need to work it."); }
sub_12F2函数:对输入进行取反
__int64 sub_12F2() { __int64 result; // rax signed int i; // [rsp+0h] [rbp-4h] for ( i = 0; i <= 42; ++i ) { result = i; string[i] = ~string[i]; } return result; }
sub_11F7:二进制取反与顺序取反
__int64 sub_11F7() { __int64 result; // rax char v1; // ST07_1 char v2; // [rsp+1h] [rbp-13h] signed int i; // [rsp+4h] [rbp-10h] unsigned int j; // [rsp+8h] [rbp-Ch] signed int k; // [rsp+Ch] [rbp-8h] v2 = 0; for ( i = 0; i <= 42; ++i ) { for ( j = 0; j < 8; ++j ) { if ( (unsigned __int8)string[i] & (unsigned __int8)(1 << j) ) v2 |= 1 << (8 - j - 1); } result = i; string[i] = v2; v2 = 0; } for ( k = 0; k <= 20; ++k ) { v1 = string[k]; string[k] = string[42 - k]; result = 42 - k; string[result] = v1; } return result; }
所谓二进制取反,例如:23表示为二进制00010111,转换后为:11101000,232
sub_11BB:字符串比较
int sub_11BB() { char *v0; // rsi int result; // eax v0 = s2; if ( !strncmp(string, s2, 0x2CuLL) ) result = sub_11A8(string, v0); else result = sub_1195(); return result; }
s2的值已知,因此我们只需要逆向解就行。
脚本
# -*- coding:utf-8 -*- model = [0x41,0xF5,0x51,0xD1,0x4d,0x61,0xd5,0xe9, 0x69,0x89,0x19,0xdd,0x09,0x11,0x89,0xcb, 0x9d,0xc9,0x69,0xf1,0x6d,0xd1,0x7d,0x89, 0xd9,0xb5,0x59,0x91,0x59,0xb1,0x31,0x59, 0x6d,0xd1,0x8b,0x21,0x9d,0xd5,0x3d,0x19, 0x11,0x79,0xd0] for i in range(21): model[i],model[42-i] = model[42-i],model[i] for i in range(43): tmp = int(bin(model[i]).replace('0b','').rjust(8,'0')[::-1],2) tmp = ~tmp&0xFF print (chr(tmp),end="")
get flag!
DawgCTF{.tIesreveRdnAtIpilF,nwoDgnihTyMtuP}
文件分析
里面有4408个文件,我们通过分析文件,发现里面的math函数算法都相同,不过里面的运算不同,整个文件分为了加,减,异或,取反和直接比较。
加法
/x83/xc2 特征码为加法,操作符号读取位置:0x116e,[rbp+var_1]数据读取位置:0x1165,减数读取位置:0x1170
.text:000000000000115F 88 45 EC mov [rbp+var_14], al .text:0000000000001162 C6 45 FF 0D mov [rbp+var_1], 0Dh .text:0000000000001166 0F BE 45 FF movsx eax, [rbp+var_1] .text:000000000000116A 0F BE 55 EC movsx edx, [rbp+var_14] .text:000000000000116E 83 C2 0D add edx, 0Dh .text:0000000000001171 39 D0 cmp eax, edx .text:0000000000001173 75 0E jnz short loc_1183
减法
/x83/xea 特征码为减法,操作符号读取位置:0x116e,[rbp+var_1]数据读取位置:0x1165,减数读取位置:0x1170
.text:000000000000115D 89 F8 mov eax, edi .text:000000000000115F 88 45 EC mov [rbp+var_14], al .text:0000000000001162 C6 45 FF 4B mov [rbp+var_1], 4Bh ; 'K' .text:0000000000001166 0F BE 45 FF movsx eax, [rbp+var_1] .text:000000000000116A 0F BE 55 EC movsx edx, [rbp+var_14] .text:000000000000116E 83 EA 01 sub edx, 1 .text:0000000000001171 39 D0 cmp eax, edx
异或
x83xf0 特征码为异或,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165,异或值读取位置:0x116c
.text:000000000000115D 89 F8 mov eax, edi .text:000000000000115F 88 45 EC mov [rbp+var_14], al .text:0000000000001162 C6 45 FF 26 mov [rbp+var_1], 26h ; '&' .text:0000000000001166 0F B6 45 EC movzx eax, [rbp+var_14] .text:000000000000116A 83 F0 59 xor eax, 59h .text:000000000000116D 38 45 FF cmp [rbp+var_1], al .text:0000000000001170 75 0E jnz short loc_1180
取反
xf7xd0 特征码为取反,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165
.text:000000000000115F 88 45 EC mov [rbp+var_14], al .text:0000000000001162 C6 45 FF FF mov [rbp+var_1], 0FFh .text:0000000000001166 0F B6 45 EC movzx eax, [rbp+var_14] .text:000000000000116A F7 D0 not eax .text:000000000000116C 38 45 FF cmp [rbp+var_1], al .text:000000000000116F 75 0E jnz short loc_117F .text:0000000000001171 48 8D 3D 8C 0E 00 00 lea rdi, s ; "Correct"
直接比较
x3ax45 特征码为直接比较,操作方式读取位置:0x116A,[rbp+var_1]数据读取位置:0x1165
.text:000000000000115D 89 F8 mov eax, edi .text:000000000000115F 88 45 EC mov [rbp+var_14], al .text:0000000000001162 C6 45 FF 00 mov [rbp+var_1], 0 .text:0000000000001166 0F B6 45 FF movzx eax, [rbp+var_1] .text:000000000000116A 3A 45 EC cmp al, [rbp+var_14] .text:000000000000116D 75 0E jnz short loc_117D .text:000000000000116F 48 8D 3D 8E 0E 00 00 lea rdi, s ; "Correct"
总结
因为[rbp+var_1]数据读取位置都在0x1165,而加减法可以归为同一类,操作数的特征码第二位不同,因此我们对于加减法和异或,各需要一个变量读取另一个数据。
因为在这几个操作中,同一位置特征码不同,因此我们可以用异或的另一数据位置的特征码,判断加减操作;用加减的数据的特征码,判断异或,取反,直接比较。
文件多合一
# -*- coding:utf-8 -*- enc = [] filep = "C:\Users\10245\Desktop\elfs\elf_" for i in range(4408): path = filep + str(i) print (path) with open(path, 'rb') as f: f.seek(0x1165,0) # [rbp+var_1]数据读取位置 rnum = ord(f.read(1)) f.seek(0x116c,0) # 加减法判断,异或数据 lnum = ord(f.read(1)) f.seek(0x1170,0) # 加减法数据 rrnum = ord(f.read(1)) print (rnum,lnum,rrnum) if lnum == 0x55: f.seek(0x116f,0) sm = ord(f.read(1)) if sm == 0xc2: enc.append((rnum-rrnum)&0xff) else: enc.append((rnum+rrnum)&0xff) elif rrnum == 0x75: enc.append(rnum^lnum) elif rrnum == 0x8d: enc.append(rnum) elif rrnum == 0xe: enc.append((~rnum)&0xff) else: print ('error') exit(0) with open(r'C:Users10245Desktopflag','wb') as f: s = bytearray(enc) # print (s) f.write(s)
得到flag文件
这就是一段异或操作
脚本
# -*- coding:utf-8 -*- model = [0x2d,0x08,0x1e,0x0e,0x2a,0x3d,0x2f,0x12,0x1a,0x1e,0x29, 0x0e,0x36,0x58,0x07,0x36,0x1d,0x01,0x5a,0x36,0x0f,0x05, 0x29,0x0e,0x14,0x63] for i in model: print (chr(i^0x69),end="")
get flag!
DawgCTF{sw@g_1n_th3_fl@g}