BUUCTF Reverse/[2019红帽杯]childRE

查看信息

BUUCTF Reverse/[2019红帽杯]childRE_第1张图片

分析代码

int __cdecl main(int argc, const char **argv, const char **envp)
{
  __int64 v3; // rax
  _QWORD *v4; // rax
  const CHAR *v5; // r11
  __int64 v6; // r10
  int v7; // er9
  const CHAR *v8; // r10
  __int64 v9; // rcx
  __int64 v10; // rax
  unsigned int v12; // ecx
  __int64 v13; // r9
  __int128 input[2]; // [rsp+20h] [rbp-38h] BYREF

  memset(input, 0, sizeof(input));
  sub_7FF714171080("%s", (const char *)input);
  v3 = -1i64;
  do
    ++v3;
  while ( *((_BYTE *)input + v3) );
  if ( v3 != 0x1F )                             // 输入字符串长度为32
  {
    while ( 1 )
      Sleep(0x3E8u);
  }
  v4 = sub_7FF714171280(input);                 // 加密(打乱顺序)
  v5 = name;
  if ( v4 )
  {
    sub_7FF7141715C0((unsigned __int8 *)v4[1]);  //打乱顺序
    sub_7FF7141715C0(*(unsigned __int8 **)(v6 + 16));
    v7 = dword_7FF7141757E0;
    v5[dword_7FF7141757E0] = *v8;
    dword_7FF7141757E0 = v7 + 1;
  }
  UnDecorateSymbolName(v5, outputString, 0x100u, 0);
  v9 = -1i64;
  do
    ++v9;
  while ( outputString[v9] );
  if ( v9 == 0x3E )
  {
    v12 = 0;
    v13 = 0i64;
    do                                                  //比较结果
    {
      if ( a1234567890Qwer[outputString[v13] % 23] != a46200860044218[v13] )
        _exit(v12);
      if ( a1234567890Qwer[outputString[v13] / 23] != a55565653255552[v13] )
        _exit(v12 * v12);
      ++v12;
      ++v13;
    }
    while ( v12 < 62 );
    sub_7FF714171020("flag{MD5(your input)}\n");
    return 0;
  }
  else
  {
    v10 = sub_7FF7141718A0(std::cout);
    std::ostream::operator<<(v10, sub_7FF714171A60);
    return -1;
  }
}

可以先写脚本将outputstring中的值给求出来

a123 = [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 
  0x2D, 0x3D, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 
  0x28, 0x29, 0x5F, 0x2B, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 
  0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x51, 0x57, 0x45, 0x52, 
  0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x61, 0x73, 
  0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x41, 
  0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 
  0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 
  0x7A, 0x78, 0x63, 0x76, 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 
  ]
a462 = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&"
a555 = "55565653255552225565565555243466334653663544426565555525555222"


outputString = ""

for i in range(62):
    for j in range(33,128):
        if(a123[j % 23] == ord(a462[i]) and a123[j // 23] == ord(a555[i]) ):
            outputString += chr(j)
            break
        else:
            continue
print(outputString)
#  结果
private:char*__thiscallR0Pxx::My_Aut0_PWN(unsignedchar*)

然后就是这个函数了,可以参考unDecorateSymbolName 函数 以及 c, c++函数名编译符号修饰符说明

 UnDecorateSymbolName(v5, outputString, 0x100u, 0);

思路可以参考这个大佬的博客

C++的类成员函数(其调用方式是thiscall)。函数的名字修饰与非成员的C++函数稍有不同,首先就是在函数名字和參数表之间插入以“@”字 符引导的类名

简单来说就是以 @ 来分割,对应关系如下

?         My_Aut0_PWN  @R0Pxx        @@AAE                    PA            D              PA        E                 @Z
以?开始    函数名       类名    私有(private)成员函数的标识    返回指针  char拼写代号          参数指针  unsigned拼写代号          结束

合起来就是 ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

接下来分析这段代码

  if ( v4 )
  {
    sub_7FF7141715C0((unsigned __int8 *)v4[1]);
    sub_7FF7141715C0(*(unsigned __int8 **)(v6 + 16));
    v7 = dword_7FF7141757E0;
    v5[dword_7FF7141757E0] = *v8;
    dword_7FF7141757E0 = v7 + 1;
  }

感觉像个二叉树遍历,试了下还原二叉树但是咋搞都不对

__int64 __fastcall sub_7FF7141715C0(unsigned __int8 *a1)
{
  int v2; // er8
  __int64 result; // rax

  if ( a1 )
  {
    sub_7FF7141715C0(*((_QWORD *)a1 + 1));
    sub_7FF7141715C0(*((_QWORD *)a1 + 2));
    v2 = dword_7FF7141757E0;
    result = *a1;
    name[dword_7FF7141757E0] = result;
    dword_7FF7141757E0 = v2 + 1;
  }
  return result;
}

参考这个大佬的博客
直接在输入的时候使用 “ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_” 刚好对应65~95

得出结果为 “PQHRSIDTUJVWKEBXYLZ[MF\]N^_OGCA”,减去 ‘A’ 刚好对应每个数的下标

写出脚本

from hashlib import md5

index = "PQHRSIDTUJVWKEBXYLZ[MF\]N^_OGCA"

s = "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"

flag_1 = [0] * 31

for i in range(31):
    flag_1[ord(index[i]) - ord('A')] = s[i]
flag = ""
for i in flag_1:
    flag = flag + str(i)
print(flag)
print(md5(flag.encode('utf-8')).hexdigest())

得到结果为

Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP
63b148e750fed3a33419168ac58083f5

flag{63b148e750fed3a33419168ac58083f5}

你可能感兴趣的:(CTF,#,BUUCTF,Reverse,CTF,ctfhub)