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+'}')

 

posted @ 2021-01-18 15:36  hktk1643  阅读(289)  评论(0编辑  收藏  举报