逆向攻防世界CTF系列54-crypt
64位无壳
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| int __fastcall main(int argc, const char **argv, const char **envp){ strcpy(Str, "12345678abcdefghijklmnopqrspxyz"); memset(&Str[32], 0, 0x60ui64); memset(v10, 0, 0x17ui64); sub_1400054D0("%s", v10); v9 = malloc(0x408ui64); v3 = strlen(Str); sub_140001120(v9, Str, v3); v4 = strlen(v10); sub_140001240(v9, v10, v4); for ( i = 0; i < 22; ++i ){ if (((unsigned __int8)v10[i] ^ 0x22) != byte_14013B000[i]){ v5 = (void *)sub_1400015A0(&off_14013B020, "error"); _CallMemberFunction0(v5, sub_140001F10); return 0; } } v7 = (void *)sub_1400015A0(&off_14013B020, "nice job"); _CallMemberFunction0(v7, sub_140001F10); return 0; }
|
看起来是一个flag解密校验题,先提出byte_14013B000
1 2 3 4 5
| [ 0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B, 0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E, 0x8D, 0x2B, 0x00, 0x00 ]
|
1240和1120应该做了某种处理,跟进看了1240后,发现用到v9,所以先看1120
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| __int64 __fastcall sub_140001120(_DWORD *a1, __int64 a2, int a3){ *a1 = 0; a1[1] = 0; v9 = a1 + 2; for ( i = 0; i < 256; ++i ) v9[i] = i; v6 = 0; result = 0i64; LOBYTE(v7) = 0; for ( j = 0; j < 256; ++j ){ v8 = v9[j]; v7 = (unsigned __int8)(*(_BYTE *)(a2 + v6) + v8 + v7); v9[j] = v9[v7]; v9[v7] = v8; if ( ++v6 >= a3 ) v6 = 0; result = (unsigned int)(j + 1); } return result; }
|
先初始化,然后交换v9[j]和v9[v7]也就是v9[byte(Str[v6]) + v8 + v7],得v9脚本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| def sub_140001120(a2: bytes, a3: int): v9 = list(range(256)) v6 = 0 v7 = 0 for j in range(256): v7 = (v7 + a2[v6] + v9[j]) % 256 v9[j], v9[v7] = v9[v7], v9[j] v6 += 1 if v6 >= a3: v6 = 0
return v9
def main(): Str = b"12345678abcdefghijklmnopqrspxyz" v3 = len(Str) v9 = sub_140001120(Str, v3) print("v9 = ", v9)
if __name__ == "__main__": main()
|
逆向就行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| _DWORD *__fastcall sub_140001240(_DWORD *a1, __int64 a2, int a3){ v5 = *a1; v6 = a1[1]; v9 = a1 + 2; for ( i = 0; i < a3; ++i ){ v5 = (unsigned __int8)(v5 + 1); v7 = v9[v5]; v6 = (unsigned __int8)(v7 + v6); v8 = v9[v6]; v9[v5] = v8; v9[v6] = v7; *(_BYTE *)(a2 + i) ^= LOBYTE(v9[(unsigned __int8)(v8 + v7)]); } *a1 = v5; result = a1; a1[1] = v6; return result; }
|
最终代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| def sub_140001120(a2: bytes, a3: int): v9 = list(range(256)) v6 = 0 v7 = 0 for j in range(256): v7 = (v7 + a2[v6] + v9[j]) % 256 v9[j], v9[v7] = v9[v7], v9[j] v6 += 1 if v6 >= a3: v6 = 0
return v9
def sub_140001240(v9: list, v10: list, a3: int): v5 = 0 v6 = 0 for i in range(a3): v5 = (v5 + 1) % 256 v7 = v9[v5] v6 = (v6 + v7) % 256 v9[v5], v9[v6] = v9[v6], v9[v5] v10[i] ^= v9[(v9[v5] + v9[v6]) % 256] return v10
def main(): Str = b"12345678abcdefghijklmnopqrspxyz" v3 = len(Str) v9 = sub_140001120(Str, v3) print("v9 = ", v9) v10 = [ 0x9E, 0xE7, 0x30, 0x5F, 0xA7, 0x01, 0xA6, 0x53, 0x59, 0x1B, 0x0A, 0x20, 0xF1, 0x73, 0xD1, 0x0E, 0xAB, 0x09, 0x84, 0x0E, 0x8D, 0x2B ] v10 = [k ^ 0x22 for k in v10] print("v10 = ", v10) v10 = sub_140001240(v9, v10, 22) for i in range(len(v10)): print(chr(v10[i]), end="")
if __name__ == "__main__": main()
|
flag{nice_to_meet_you}
但其实这是个RC4算法,先生成S盒,再生成密钥流,这种异或类得加密算法只需要重写逻辑即可