【TSCTF-J】新生赛debugMe WP
下载附件,放到Exeinfo PE里面查一下
发现是64位,无壳,用IDA64打开,F5读伪代码。
发现buffer就是flag,于是要对上面的代码进行编译运行,输出buffer。
#include<cstdio> #include<iostream> #include<cstring> using namespace std; typedef unsigned int uint32; typedef unsigned char uint8; typedef unsigned long long ull; typedef ull uint64; #define __int64 long long #define _BYTE uint8 #define _QWORD uint64 int i; // [rsp+Ch] [rbp-584h] int i_0; // [rsp+10h] [rbp-580h] int *ptr; // [rsp+18h] [rbp-578h] _BYTE key[72]; // [rsp+30h] [rbp-560h] OVERLAPPED BYREF char input[256]; // [rsp+80h] [rbp-510h] BYREF uint8 buffer[1024]; // [rsp+180h] [rbp-410h] BYREF unsigned __int64 v10; // [rsp+588h] [rbp-8h] unsigned char reverse_map[] = { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 36, 255, 255, 255, 37, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 255, 255, 255, 255, 255, 255, 255, 0, 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, 255, 255, 255, 255, 255, 255, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 255, 255, 255, 255, 255 }; void __cdecl decrypt(int *v, int *k) { int v0; // [rsp+1Ch] [rbp-24h] int v1; // [rsp+20h] [rbp-20h] int sum; // [rsp+24h] [rbp-1Ch] int j; // [rsp+28h] [rbp-18h] v0 = *v; v1 = v[1]; sum = -957401312; for ( j = 0; j <= 31; ++j ) { v1 -= (v0 + sum) ^ ((v0 >> 5) + k[3]) ^ (16 * v0 + k[2]); v0 -= (v1 + sum) ^ ((v1 >> 5) + k[1]) ^ (16 * v1 + *k); sum += 1640531527; } *v = v0; v[1] = v1; } uint32 __cdecl base64_decode(const uint8 *code, uint32 code_len, uint8 *plain) { uint32 v3; // rax uint32 v4; // rax uint32 v5; // rax uint32 i; // [rsp+28h] [rbp-28h] uint32 j; // [rsp+30h] [rbp-20h] uint32 k; // [rsp+38h] [rbp-18h] uint8 quad[4]; // [rsp+44h] [rbp-Ch] j = 0LL; for ( i = 0LL; i < code_len; i += 4LL ) { for ( k = 0LL; k <= 3; ++k ) quad[k] = reverse_map[code[k + i]]; v3 = j++; plain[v3] = (quad[1] >> 4) | (4 * quad[0]); if ( quad[2] > 0x3Fu ) break; if ( quad[3] > 0x3Fu ) { v4 = j++; plain[v4] = (quad[2] >> 2) | (16 * quad[1]); return j; } plain[j] = (quad[2] >> 2) | (16 * quad[1]); v5 = j + 1; j += 2LL; plain[v5] = quad[3] | (quad[2] << 6); } return j; } int main() { memset(buffer, 0, sizeof(buffer)); memcpy(key, "flag{fake_flag!}\xB0\xCB\x3E\xC9\x24\x9F+i", 24); *(_QWORD *)&key[24] = 0x4C84B46449C15A4ELL; *(_QWORD *)&key[32] = 0x7BDFB74A90AED151LL; *(_QWORD *)&key[40] = 0x2954405AD89B1055LL; *(_QWORD *)&key[48] = 0xFA7ECCD6EBB7FD3ELL; *(_QWORD *)&key[56] = 0x84E7B0309D4C973FLL; *(_QWORD *)&key[64] = 0xBACEB9973E970C85LL; i = 7; ptr = (int *)&key[16]; do { decrypt(ptr, (int *)key); ptr += 2; --i; }while ( i ); buffer[(int)base64_decode(&key[16], 0x38uLL, buffer)] = 0; for(int i=0; i<40; i++) cout<<buffer[i]; return 0; }
需要注意的是很多没见过的数据类型都需要自己重定义,还有里面用到的函数也需要一起copy过来,最后在网上搜到qmemcpy与memcpy相同,进行替换后,就可以正常编译运行了。
得到flag。