# PicoCTF - Let's get dynamic ## Source code :::spoiler IDA Main Function ```cpp= int __cdecl main(int argc, const char **argv, const char **envp) { int i; // [rsp+1Ch] [rbp-114h] char s2[64]; // [rsp+20h] [rbp-110h] BYREF char s[64]; // [rsp+60h] [rbp-D0h] BYREF char v7[8]; // [rsp+A0h] [rbp-90h] BYREF __int64 v8; // [rsp+A8h] [rbp-88h] __int64 v9; // [rsp+B0h] [rbp-80h] __int64 v10; // [rsp+B8h] [rbp-78h] __int64 v11; // [rsp+C0h] [rbp-70h] __int64 v12; // [rsp+C8h] [rbp-68h] __int16 v13; // [rsp+D0h] [rbp-60h] __int64 v14[6]; // [rsp+E0h] [rbp-50h] __int16 v15; // [rsp+110h] [rbp-20h] unsigned __int64 v16; // [rsp+118h] [rbp-18h] v16 = __readfsqword(0x28u); *v7 = 0xFD872AC7CA737102LL; v8 = 0x4915F12BF9F82DCBLL; v9 = 0xA7EF0D4C54003C10LL; v10 = 0x9399CCF74D02A843LL; v11 = 0x2AC6F818989688D7LL; v12 = 0x9F51EBCA33584C85LL; v13 = 231; v14[0] = 0x92D46893B5010A61LL; v14[1] = 0xA6BDE59D58F4EB4LL; v14[2] = 0xFC993A3238355027LL; v14[3] = 0xEDA7B28D7054D179LL; v14[4] = 0x419FBB499BD4CFBBLL; v14[5] = 0x935AE3903F554688LL; v15 = 185; fgets(s, 49, _bss_start); for ( i = 0; i < strlen(v7); ++i ) s2[i] = *(v14 + i) ^ v7[i] ^ i ^ 0x13; if ( !memcmp(s, s2, 49uLL) ) { puts("No, that's not right."); return 1; } else { puts("Correct! You entered the flag."); return 0; } } ``` ::: ## Recon 這一題也沒有很難,就要用dbg細心的跟一下,然後不太確定這一題設計的用意,但無論如何還是蠻直觀的 可以看到IDA解析的source code中間有一段是在進行encryption,然後只要反著做就可以拿到flag,但重點是他實際跑起來會和肉眼觀察到的有一點不一樣,一開始讀取的時候會從v7的後端以及v14[0]的後端開始xor,所以如果像我要從兩者最後一個byte開始解密的話,index的i就要特別注意,不過我也是建議要從第一個byte開始解密,因為這樣會對應到flag的第一個字元,所以如果不知道這支程式怎麼加密的話,可以直接跑下面的script,用debugger追一下就知道了 ## Exploit ```python= enc_flag = [[0x92, 0xD4, 0x68, 0x93, 0xB5, 0x01, 0x0A, 0x61, ], [0x0A, 0x6B, 0xDE, 0x59, 0xD5, 0x8F, 0x4E, 0xB4, ], [0xFC, 0x99, 0x3A, 0x32, 0x38, 0x35, 0x50, 0x27, ], [0xED, 0xA7, 0xB2, 0x8D, 0x70, 0x54, 0xD1, 0x79, ], [0x41, 0x9F, 0xBB, 0x49, 0x9B, 0xD4, 0xCF, 0xBB, ], [0x93, 0x5A, 0xE3, 0x90, 0x3F, 0x55, 0x46, 0x88]]# 0x7fffffffd660 key = [[0xFD, 0x87, 0x2A, 0xC7, 0xCA, 0x73, 0x71, 0x02, ], [0x49, 0x15, 0xF1, 0x2B, 0xF9, 0xF8, 0x2D, 0xCB, ], [0xA7, 0xEF, 0x0D, 0x4C, 0x54, 0x00, 0x3C, 0x10, ], [0x93, 0x99, 0xCC, 0xF7, 0x4D, 0x02, 0xA8, 0x43, ], [0x2A, 0xC6, 0xF8, 0x18, 0x98, 0x96, 0x88, 0xD7, ], [0x9F, 0x51, 0xEB, 0xCA, 0x33, 0x58, 0x4C, 0x85]]# 0x7fffffffd620 FLAG = [] for i in range(len(enc_flag)): for j in range(len(enc_flag[0])): FLAG.append(bytes.fromhex(hex(enc_flag[i][7-j] ^ key[i][7-j] ^ 0x13 ^ (j + 8 * i))[2:]).decode('utf-8')) print("".join(FLAG) + "}") ``` Flag: `picoCTF{dyn4m1c_4n4ly1s_1s_5up3r_us3ful_6044e660}`