- 文件夹里突然发现的一篇远古复现wp,发出来
一. CSGO
-
go1.18写的exe,找到main函数
-
void __golang main_main() { __int64 v0; // r14 _QWORD *v1; // rax __int64 i; // rax __int64 v3; // rdi main__Ctype_char *v4; // rax void (**v5)(void); // rax __int64 v6; // rbx main__Ctype_char *v7; // rax char v8; // al io_Writer_0 p0; // [rsp+0h] [rbp-C8h] runtime__type_0 *p0b; // [rsp+0h] [rbp-C8h] io_Writer_0 p0c; // [rsp+0h] [rbp-C8h] io_Reader_0 p0d; // [rsp+0h] [rbp-C8h] _BYTE p0a[40]; // [rsp+0h] [rbp-C8h] OVERLAPPED main__Ctype_char *p0e; // [rsp+0h] [rbp-C8h] string p0f; // [rsp+0h] [rbp-C8h] uint8 *p0g; // [rsp+0h] [rbp-C8h] _slice_interface_ v17; // [rsp+10h] [rbp-B8h] _slice_interface_ v18; // [rsp+10h] [rbp-B8h] string v19; // [rsp+10h] [rbp-B8h] _slice_interface_ v20; // [rsp+20h] [rbp-A8h] main__Ctype_char *p1; // [rsp+50h] [rbp-78h] _QWORD *v22; // [rsp+60h] [rbp-68h] __int128 v23; // [rsp+78h] [rbp-50h] BYREF const char *v24; // [rsp+88h] [rbp-40h] _QWORD *v25; // [rsp+90h] [rbp-38h] void *v26; // [rsp+98h] [rbp-30h] char **v27; // [rsp+A0h] [rbp-28h] void *v28; // [rsp+A8h] [rbp-20h] char **v29; // [rsp+B0h] [rbp-18h] void (**v30)(void); // [rsp+B8h] [rbp-10h] if ( (unsigned __int64)&v23 + 8 <= *(_QWORD *)(v0 + 16) ) runtime_morestack_noctxt_abi0(); v30 = 0LL; v28 = &unk_17E120; v29 = &main__stmp_0; fmt_Fprintln(p0, v17); p0c.data = runtime_newobject(p0b); v22 = v1; *v1 = 0LL; v26 = &unk_17E120; v27 = &main__stmp_1; *(_OWORD *)&v20.len = (unsigned __int128)fmt_Fprint(p0c, v18); v24 = "\b"; v25 = v22; fmt_Fscanf(p0d, v19, v20); for ( i = 0LL; i < 64; i = v3 + 1 ) { v3 = i; if ( (unsigned __int64)(i - ((i + 11) >> 6 << 6) + 11) >= 0x40 ) runtime_panicIndex(); *(string *)&p0a[16] = runtime_intstring(*(uint8 (**)[4])p0a, *(int64 *)&p0a[8]); runtime_concatstring2(*(runtime_tmpBuf **)p0a, *(string *)&p0a[8], *(string *)&p0a[24]); } main__Cfunc_CString(*(string *)p0a); p1 = v4; p0f.len = (__int64)main_main_func1(p0e); v30 = v5; v6 = v22[1]; main__Cfunc_CString(p0f); main__Cfunc_enc_abi0(v7, p1); *(string *)&p0a[8] = runtime_gostring(p0g); if ( v6 == 60 && (runtime_memequal(), v8) ) { fmt_Fprintln(*(io_Writer_0 *)p0a, *(_slice_interface_ *)&p0a[16]); } else { *((_QWORD *)&v23 + 1) = &main__stmp_2; fmt_Fprintln(*(io_Writer_0 *)p0a, *(_slice_interface_ *)&p0a[16]); } (*v30)(); }
-
分析逻辑:输入字符串,base64换表加密,比较
-
动调得到表:LMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ABCDEFGHIJK
-
解密得到:DASCTF{73913519-A0A6-5575-0F10-DDCBF50FA8CA}
二. Blast
-
控制流混淆,写脚本去除
-
from idc import * def patch(start, end): i = start while i < end: if print_insn_mnem(i) == 'jnz' and print_insn_mnem(i + 6) == 'jmp' and print_operand(i + 0xb, 0) == '$+5' and print_insn_mnem(i + 0xb) == 'jmp': print(hex(i)) for j in range(i, i + 0x10): patch_byte(j, 0x90) i += 0xf i += 1 for seg in Segments(): if get_segm_name(seg) == '.text': patch(seg, 0x40B7E4)
-
可以用findcrypt插件或动调识别出其实就是两次md5加密,最后比较
-
直接爆破
-
from hashlib import * result = [ '14d89c38cd0fb23a14be2798d449c182', 'a94837b18f8f43f29448b40a6e7386ba', 'af85d512594fc84a5c65ec9970956ea5', 'af85d512594fc84a5c65ec9970956ea5', '10e21da237a4a1491e769df6f4c3b419', 'a705e8280082f93f07e3486636f3827a', '297e7ca127d2eef674c119331fe30dff', 'b5d2099e49bdb07b8176dff5e23b3c14', '83be264eb452fcf0a1c322f2c7cbf987', 'a94837b18f8f43f29448b40a6e7386ba', '71b0438bf46aa26928c7f5a371d619e1', 'a705e8280082f93f07e3486636f3827a', 'ac49073a7165f41c57eb2c1806a7092e', 'a94837b18f8f43f29448b40a6e7386ba', 'af85d512594fc84a5c65ec9970956ea5', 'ed108f6919ebadc8e809f8b86ef40b05', '10e21da237a4a1491e769df6f4c3b419', '3cfd436919bc3107d68b912ee647f341', 'a705e8280082f93f07e3486636f3827a', '65c162f7c43612ba1bdf4d0f2912bbc0', '10e21da237a4a1491e769df6f4c3b419', 'a705e8280082f93f07e3486636f3827a', '3cfd436919bc3107d68b912ee647f341', '557460d317ae874c924e9be336a83cbe', 'a705e8280082f93f07e3486636f3827a', '9203d8a26e241e63e4b35b3527440998', '10e21da237a4a1491e769df6f4c3b419', 'f91b2663febba8a884487f7de5e1d249', 'a705e8280082f93f07e3486636f3827a', 'd7afde3e7059cd0a0fe09eec4b0008cd', '488c428cd4a8d916deee7c1613c8b2fd', '39abe4bca904bca5a11121955a2996bf', 'a705e8280082f93f07e3486636f3827a', '3cfd436919bc3107d68b912ee647f341', '39abe4bca904bca5a11121955a2996bf', '4e44f1ac85cd60e3caa56bfd4afb675e', '45cf8ddfae1d78741d8f1c622689e4af', '3cfd436919bc3107d68b912ee647f341', '39abe4bca904bca5a11121955a2996bf', '4e44f1ac85cd60e3caa56bfd4afb675e', '37327bb06c83cb29cefde1963ea588aa', 'a705e8280082f93f07e3486636f3827a', '23e65a679105b85c5dc7034fded4fb5f', '10e21da237a4a1491e769df6f4c3b419', '71b0438bf46aa26928c7f5a371d619e1', 'af85d512594fc84a5c65ec9970956ea5', '39abe4bca904bca5a11121955a2996bf', ] for i in range(len(result)): for j in range(30,128): if md5(md5(chr(j).encode()).hexdigest().encode()).hexdigest() == result[i]: print(chr(j),end="")
-
得到Hello_Ctfer_Velcom_To_my_Mov_and_md5(md5)_world
三. ez加密器
-
根据字符串提示找到如下:
-
__int64 sub_1400140E0() { char *v0; // r8 char *v1; // rcx char *v2; // r9 char v3; // si unsigned __int8 v4; // di int v5; // eax int v6; // edx int v7; // edi int v8; // eax int v9; // edi int v10; // ebp int v11; // edi int v12; // r12d int v13; // edi char v14; // di int v15; // eax int v16; // edx int v18; // esi int v19; // eax int v20; // esi int v21; // edi int v22; // esi int v23; // ebp int v24; // esi char *v25; // [rsp+20h] [rbp-D8h] BYREF __int64 v26; // [rsp+28h] [rbp-D0h] char v27[8]; // [rsp+38h] [rbp-C0h] BYREF char Str2[184]; // [rsp+40h] [rbp-B8h] BYREF sub_140003D87(); sub_140003C30((__int64)a000000, (__int64)a11111111111111); sub_1400036A0((__int64)a000000, 6u, (unsigned __int8 *)v27); sub_140003AE0((__int64)&v25, (__int64)v27, a11111111111111, 40); v0 = v25; if ( (int)v26 <= 0 ) { v2 = Str2; } else { v1 = Str2; v2 = &Str2[2 * (int)v26]; do { v3 = *v0; v4 = (unsigned __int8)*v0 >> 4; v5 = v4; if ( v4 <= 9u ) { LOBYTE(v6) = v4 ^ 0x30; if ( !v4 ) LOBYTE(v6) = 48; } else { v6 = 65; do { v7 = v6 & v5; v6 ^= v5; v5 = 2 * v7; } while ( 2 * v7 ); v8 = 0xFFFFFFF5; v9 = 1; do { v10 = v9; v11 = v8 & v9; v12 = v8; v8 ^= v10; v9 = 2 * v11; } while ( v9 ); if ( v10 != v12 ) { do { v13 = v6 & v8; v6 ^= v8; v8 = 2 * v13; } while ( 2 * v13 ); } } *v1 = v6; v1 += 2; v14 = v3 & 0xF; v15 = v3 & 0xF; if ( (v3 & 0xFu) > 9 ) { v16 = 65; do { v18 = v16 & v15; v16 ^= v15; v15 = 2 * v18; } while ( 2 * v18 ); v19 = -11; v20 = 1; do { v21 = v20; v22 = v19 & v20; v23 = v19; v19 ^= v21; v20 = 2 * v22; } while ( v20 ); if ( v21 != v23 ) { do { v24 = v16; v16 ^= v19; v19 = 2 * (v19 & v24); } while ( v19 ); } } else { LOBYTE(v16) = v14 ^ 0x30; if ( !v14 ) LOBYTE(v16) = 48; } *(v1 - 1) = v16; ++v0; } while ( v1 != v2 ); } *v2 = 0; if ( !strcmp(Big_Numbers1_1400150A0, Str2) ) sub_1400016E0((__int64)"------\nGetFlag!\n------"); system("pause"); return 0i64; }
-
__int64 __fastcall sub_140003C30(__int64 a1, __int64 a2) { __int64 result; // rax sub_1400016E0((__int64)"Please enter the verification code: \n"); sub_140001730(&unk_140016000, a1); if ( !(unsigned __int8)sub_140003A20(a1) || (sub_1400016E0((__int64)"Please enter the flag: \n"), sub_140001730(&unk_140016000, a2), result = sub_140003910(a2), !(_BYTE)result) ) { exit(-1); } return result; }
-
输入函数,输入6位code以及flag
-
__int64 __fastcall sub_1400036A0(__int64 a1, unsigned __int16 a2, unsigned __int8 *a3) { signed int v6; // esi unsigned int v7; // edx __int64 v8; // rdi int v9; // ecx _BYTE *v10; // r12 _BYTE *v11; // rbp int v12; // eax int v13; // r9d int v14; // eax unsigned int v15; // r9d unsigned __int8 *v16; // rax __int64 v17; // rcx __int16 v18; // r11 _BYTE *v19; // r9 unsigned __int8 *v20; // r11 _BYTE *v21; // rbx int v22; // eax int v23; // ecx _BYTE *v25; // r11 unsigned __int8 *v26; // r10 int v27; // eax int v28; // ecx v6 = 3 * (a2 / 3u); if ( a2 <= 2u ) goto LABEL_19; LOWORD(v7) = 0; v8 = 0i64; v9 = 0; do { v10 = (_BYTE *)(a1 + v8 + 1); a3[(unsigned __int16)v7] = *(_BYTE *)(a1 + v8) >> 2; v11 = (_BYTE *)(a1 + v8 + 2); a3[(unsigned __int16)v7 + 1] = (*v10 >> 4) | (16 * *(_BYTE *)(a1 + v8)) & 0x30; a3[(unsigned __int16)v7 + 2] = (*v11 >> 6) | (4 * *v10) & 0x3C; a3[(unsigned __int16)v7 + 3] = *v11 & 0x3F; v12 = 3; do { v13 = v9 & v12; v9 ^= v12; v12 = 2 * v13; } while ( 2 * v13 ); v8 = (unsigned __int16)v9; v7 = (unsigned __int16)v7; v14 = 4; do { v15 = v7; v7 ^= v14; v14 = 2 * (v14 & v15); } while ( v14 ); v9 = (unsigned __int16)v9; } while ( (unsigned __int16)v9 < v6 ); if ( (_WORD)v7 ) { v16 = a3; do { v17 = *v16++; *(v16 - 1) = off_140015108[v17]; } while ( v16 != &a3[(unsigned __int16)(v7 - 1) + 1] ); } else { LABEL_19: v7 = 0; } v18 = a2 - 3 * (a2 / 3u); if ( v18 == 1 ) { v7 = (unsigned __int16)v7; v25 = (_BYTE *)(a1 + a2 - 1); v26 = &a3[(unsigned __int16)v7]; *v26 = *v25 >> 2; v26[1] = (16 * *v25) & 0x30; *v26 = off_140015108[*v26]; v26[1] = off_140015108[v26[1]]; v27 = 4; v26[2] = 61; v26[3] = 61; do { v28 = v7 & v27; v7 ^= v27; v27 = 2 * v28; } while ( 2 * v28 ); return v7; } else { if ( v18 == 2 ) { v7 = (unsigned __int16)v7; v19 = (_BYTE *)(a1 + a2 - 2); v20 = &a3[(unsigned __int16)v7]; v21 = (_BYTE *)(a1 + a2 - 1); *v20 = *v19 >> 2; v20[1] = (*v21 >> 4) | (16 * *v19) & 0x30; v20[2] = (4 * *v21) & 0x3C; *v20 = off_140015108[*v20]; v20[1] = off_140015108[v20[1]]; v20[2] = off_140015108[v20[2]]; v22 = 4; v20[3] = 61; do { v23 = v7 & v22; v7 ^= v22; v22 = 2 * v23; } while ( 2 * v23 ); } return v7; } }
-
BASE64换表加密,对code进行加密
-
__int64 __fastcall sub_140003AE0(__int64 a1, __int64 a2, const void *a3, int a4) { size_t v6; // rbx unsigned __int8 v8; // r14 int v9; // ebp char *v10; // rdi __int64 *v11; // r8 __int64 v12; // rdx char *v13; // rbx char *v14; // r8 char *v15; // rcx __int64 result; // rax unsigned __int64 v17; // r9 unsigned int v18; // eax unsigned int v19; // ecx __int64 v20; // r8 char v21[184]; // [rsp+20h] [rbp-B8h] BYREF v6 = a4; sub_1400016E0(&unk_140016003); sub_140001A20(a2, v21); v8 = ((unsigned int)((int)v6 >> 31) >> 29) - ((v6 + ((unsigned int)((int)v6 >> 31) >> 29)) & 7) + 8; v9 = v6 + v8; v10 = (char *)malloc(v9); memcpy(v10, a3, v6); v11 = (__int64 *)&v10[v6]; v12 = 0x101010101010101i64 * v8; if ( v8 >= 8u ) { *v11 = v12; v17 = (unsigned __int64)(v11 + 1) & 0xFFFFFFFFFFFFFFF8ui64; *(__int64 *)((char *)v11 + v8 - 8) = v12; if ( (((_DWORD)v11 - (_DWORD)v17 + v8) & 0xFFFFFFF8) >= 8 ) { v18 = ((_DWORD)v11 - v17 + v8) & 0xFFFFFFF8; v19 = 0; do { v20 = v19; v19 += 8; *(_QWORD *)(v17 + v20) = v12; } while ( v19 < v18 ); } } else if ( (v8 & 4) != 0 ) { *(_DWORD *)v11 = v12; *(_DWORD *)((char *)v11 + v8 - 4) = v12; } else if ( ((unsigned int)((int)v6 >> 31) >> 29) - (((_BYTE)v6 + ((unsigned int)((int)v6 >> 31) >> 29)) & 7) != 0xF8 ) { *(_BYTE *)v11 = v8; if ( (v8 & 2) != 0 ) *(_WORD *)((char *)v11 + v8 - 2) = v12; } if ( v9 > 0 ) { v13 = v10; do { v14 = v13; v15 = v13; v13 += 8; sub_140002180(v15, v21, v14); } while ( v13 != &v10[8 * ((unsigned int)(v9 - 1) >> 3) + 8] ); } sub_1400016E0(&unk_140016003); result = a1; *(_QWORD *)a1 = v10; *(_DWORD *)(a1 + 8) = v9; return result; }
-
DES,用加密后的code进行flag的加密,此时code正好8字节,符合DES加密标准
-
故爆破六位code
-
from Crypto.Cipher import DES import base64 c= bytes.fromhex("0723105D5C12217DCDC3601F5ECB54DA9CCEC2279F1684A13A0D716D17217F4C9EA85FF1A42795731CA3C55D3A4D7BEA") tab1 = 'abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ+/' tab2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' for i in range(1000000): key = base64.b64encode(str(i).rjust(6,"0").encode()).decode().translate(str.maketrans(tab2,tab1)).encode() cipher = DES.new(key, DES.MODE_ECB) m= cipher.decrypt(c) if b"DASCTF{" in m: print(m) exit(1)
-
DASCTF{f771b96b71514bb6bc20f3275fa9404e}
四. vm_wo
-
逻辑很简单
-
写个反汇编脚本提取指令
-
opcode= [26, 0, 3, 25, 1, 1, 13, 2, 7, 24, 1, 2, 1, 0, 3, 26, 0, 3, 25, 1, 2, 13, 2, 6, 24, 1, 2, 1, 0, 4, 26, 0, 3, 25, 1, 3, 13, 2, 5, 24, 1, 2, 1, 0, 5, 26, 0, 3, 25, 1, 4, 13, 2, 4, 24, 1, 2, 1, 0, 6] pc=0 while pc<len(opcode): print('0x%04x: '%pc,end="") if opcode[pc] == 0: print('swap reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==1: print('xor reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==2: print('add reg%d %d'%(opcode[pc+1],pc+2)) elif opcode[pc]==3: print('add reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==4: print('sub reg%d %d'% (opcode[pc+1],pc+2)) elif opcode[pc]==5: print('sub reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==6: print('mul reg%d %d'% (opcode[pc+1],pc+2)) elif opcode[pc]==7: print('mul reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==8: print('div reg%d %d'% (opcode[pc+1],pc+2)) elif opcode[pc]==9: print('div reg%d reg%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==13: print('mov reg%d reg0<<%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc] == 24: print('reg0 = reg2 | reg1') elif opcode[pc]==25: print('mov reg%d reg0>>%d'% (opcode[pc+1],opcode[pc+2])) elif opcode[pc]==26: print('mov reg%d %d'% (opcode[pc+1],opcode[pc+2])) pc+=3
-
0x0000: mov reg0 3 0x0003: mov reg1 reg0>>1 0x0006: mov reg2 reg0<<7 0x0009: reg0 = reg2 | reg1 0x000c: xor reg0 reg3 0x000f: mov reg0 3 0x0012: mov reg1 reg0>>2 0x0015: mov reg2 reg0<<6 0x0018: reg0 = reg2 | reg1 0x001b: xor reg0 reg4 0x001e: mov reg0 3 0x0021: mov reg1 reg0>>3 0x0024: mov reg2 reg0<<5 0x0027: reg0 = reg2 | reg1 0x002a: xor reg0 reg5 0x002d: mov reg0 3 0x0030: mov reg1 reg0>>4 0x0033: mov reg2 reg0<<4 0x0036: reg0 = reg2 | reg1 0x0039: xor reg0 reg6
-
逻辑比较简单
-
直接找到reg3到reg6的值逆就完了
-
enc = [0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, 0xBF, 0xE9, 0xB1, 0x89, 0xE9, 0x91, 0x89, 0x89, 0x8F, 0xAD] key = 0xBEEDBEEF.to_bytes(4, 'little') def decode(s): s = (s >> 3 | s << 5) & 0xFF s = s ^ key[3] s = (s << 4 | s >> 4) & 0xFF s = s ^ key[2] s = (s << 3 | s >> 5) & 0xFF s = s ^ key[1] s = (s << 2 | s >> 6) & 0xFF s = s ^ key[0] s = (s << 1 | s >> 7) & 0xFF return s flag='' for i in range(len(enc)): flag+=chr(decode(enc[i])) print(flag)
-
DASCTF{you_are_right_so_cool}