Backdoor
这是一个有后门的程序,有个参数可以触发该程序执行后门操作,请找到这个参数,并提交其SHA256摘要。(小写)
FLAG:PCTF{参数的sha256}
下载下来发现是一个windows程序,拖进IDA
int __cdecl wmain(int a1, int a2) { char v3[148]; // [esp+50h] [ebp-2C8h] BYREF char v4[28]; // [esp+E4h] [ebp-234h] BYREF char Source[4]; // [esp+100h] [ebp-218h] BYREF char v6; // [esp+104h] [ebp-214h] __int16 i; // [esp+108h] [ebp-210h] char Destination[2]; // [esp+10Ch] [ebp-20Ch] BYREF char v9[510]; // [esp+10Eh] [ebp-20Ah] BYREF __int16 v10; // [esp+30Ch] [ebp-Ch] LPSTR lpMultiByteStr; // [esp+310h] [ebp-8h] int cbMultiByte; // [esp+314h] [ebp-4h] cbMultiByte = WideCharToMultiByte(1u, 0, *(LPCWCH *)(a2 + 4), -1, 0, 0, 0, 0); lpMultiByteStr = (LPSTR)sub_4011F0(cbMultiByte); WideCharToMultiByte(1u, 0, *(LPCWCH *)(a2 + 4), -1, lpMultiByteStr, cbMultiByte, 0, 0); v10 = *(_WORD *)lpMultiByteStr; if ( v10 < 0 ) return -1; v10 ^= 0x6443u; strcpy(Destination, "0"); memset(v9, 0, sizeof(v9)); for ( i = 0; i < v10; ++i ) Destination[i] = 65; *(_DWORD *)Source = 2147108114; v6 = 0; strcpy(&Destination[v10], Source); qmemcpy(v4, &unk_4021FC, 0x1Au); strcpy(&v9[v10 + 2], v4); qmemcpy(v3, &unk_402168, 0x91u); v3[145] = 0; strcpy(&v9[v10 + 27], v3); sub_401000(Destination); return 0; }
查看unk_4021FC:
是一串nop(0x90)
查看unk_402168:
应该是一个shellcode
分析后wmain如下:
int __cdecl wmain(int argc, char **argv) { char v3[145]; // [esp+50h] [ebp-2C8h] BYREF char v4; // [esp+E1h] [ebp-237h] char Source[28]; // [esp+E4h] [ebp-234h] BYREF char jmp_esp[4]; // [esp+100h] [ebp-218h] BYREF char v7; // [esp+104h] [ebp-214h] __int16 i; // [esp+108h] [ebp-210h] char payload[512]; // [esp+10Ch] [ebp-20Ch] BYREF __int16 offset; // [esp+30Ch] [ebp-Ch] LPSTR lpMultiByteStr; // [esp+310h] [ebp-8h] int cbMultiByte; // [esp+314h] [ebp-4h] cbMultiByte = WideCharToMultiByte(1u, 0, (LPCWCH)argv[1], -1, 0, 0, 0, 0); lpMultiByteStr = (LPSTR)sub_4011F0(cbMultiByte); WideCharToMultiByte(1u, 0, (LPCWCH)argv[1], -1, lpMultiByteStr, cbMultiByte, 0, 0); offset = *(_WORD *)lpMultiByteStr; if ( offset < 0 ) return -1; offset ^= 0x6443u; strcpy(payload, "0"); memset(&payload[2], 0, 0x1FEu); for ( i = 0; i < offset; ++i ) // padding payload[i] = 'A'; *(_DWORD *)jmp_esp = 0x7FFA4512; // win2000,xp,2003:jmp esp v7 = 0; strcpy(&payload[offset], jmp_esp); qmemcpy(Source, &nop, 0x1Au); strcpy(&payload[offset + 4], Source); qmemcpy(v3, &shellcode, sizeof(v3)); v4 = 0; strcpy(&payload[offset + 29], v3); sub_401000(payload); return 0; }
(0x7FFA4512是一个万能的jmp esp)
查看sub_401000:
int __cdecl sub_401000(char *Source) { char Destination[2]; // [esp+4Ch] [ebp-20h] BYREF int v3; // [esp+4Eh] [ebp-1Eh] int v4; // [esp+52h] [ebp-1Ah] int v5; // [esp+56h] [ebp-16h] int v6; // [esp+5Ah] [ebp-12h] int v7; // [esp+5Eh] [ebp-Eh] int v8; // [esp+62h] [ebp-Ah] int v9; // [esp+66h] [ebp-6h] __int16 v10; // [esp+6Ah] [ebp-2h] strcpy(Destination, "0"); v3 = 0; v4 = 0; v5 = 0; v6 = 0; v7 = 0; v8 = 0; v9 = 0; v10 = 0; strcpy(Destination, Source); return 0; }
发现该处存在栈溢出,于是跟踪Source
发现Source的构成如下:
用户传入的第一个参数(argv[1])传递给v10,然后v10异或0x6443,之后Source填充v10个'A',之后加上jmp esp,nop和shellcode
因此,只需要让这一串payload覆盖返回地址就可以执行后门了
所以v10^0x6443就应该等于0x24
因此可以获得flag:
(注意小端序)
from hashlib import * import codecs flag = 0x24 ^ 0x6443 flag = hex(flag)[2:] flag = sha256(codecs.decode(flag, 'hex')[::-1]).hexdigest() print('PCTF{'+flag+'}')