攻防世界--key

测试文件:https://adworld.xctf.org.cn/media/task/attachments/c6cf449ae4b7498eba5027c533386a40.exe

 

1.准备

获取信息:

  • 32位文件

 

2.IDA打开

反汇编main函数

  1 void sub_401100()
  2 {
  3   signed int v0; // esi
  4   signed int v1; // esi
  5   unsigned int v2; // edi
  6   void **v3; // ebx
  7   void **v4; // eax
  8   int v5; // ecx
  9   int v6; // ST04_4
 10   int v7; // ST08_4
 11   int v8; // ST0C_4
 12   int v9; // eax
 13   int v10; // ST0C_4
 14   char *v11; // esi
 15   int v12; // ecx
 16   void **v13; // eax
 17   int v14; // eax
 18   int v15; // ST0C_4
 19   int v16; // eax
 20   int v17; // ST0C_4
 21   int v18; // eax
 22   int v19; // ST0C_4
 23   int v20; // eax
 24   int v21; // ST0C_4
 25   int v22; // eax
 26   int v23; // ST0C_4
 27   int v24; // eax
 28   int v25; // ST0C_4
 29   int v26; // eax
 30   int v27; // ST0C_4
 31   int v28; // eax
 32   int v29; // [esp-4h] [ebp-13Ch]
 33   int Dst; // [esp+14h] [ebp-124h]
 34   char v31[4]; // [esp+20h] [ebp-118h]
 35   char v32; // [esp+24h] [ebp-114h]
 36   int v33; // [esp+5Ch] [ebp-DCh]
 37   char v34; // [esp+61h] [ebp-D7h]
 38   int v35; // [esp+64h] [ebp-D4h]
 39   int v36; // [esp+68h] [ebp-D0h]
 40   char v37; // [esp+6Ch] [ebp-CCh]
 41   FILE *File; // [esp+70h] [ebp-C8h]
 42   char v39; // [esp+84h] [ebp-B4h]
 43   void *v40; // [esp+CCh] [ebp-6Ch]
 44   int v41; // [esp+DCh] [ebp-5Ch]
 45   unsigned int v42; // [esp+E0h] [ebp-58h]
 46   void *v43; // [esp+E4h] [ebp-54h]
 47   unsigned int v44; // [esp+F4h] [ebp-44h]
 48   unsigned int v45; // [esp+F8h] [ebp-40h]
 49   void *Memory[4]; // [esp+FCh] [ebp-3Ch]
 50   unsigned int v47; // [esp+10Ch] [ebp-2Ch]
 51   unsigned int v48; // [esp+110h] [ebp-28h]
 52   __int128 v49; // [esp+114h] [ebp-24h]
 53   __int16 v50; // [esp+124h] [ebp-14h]
 54   char v51; // [esp+126h] [ebp-12h]
 55   int v52; // [esp+134h] [ebp-4h]
 56 
 57   v45 = 15;
 58   v44 = 0;
 59   LOBYTE(v43) = 0;
 60   v52 = 0;
 61   v42 = 15;
 62   v41 = 0;
 63   LOBYTE(v40) = 0;
 64   LOBYTE(v52) = 1;
 65   v0 = 0;
 66   v47 = 'dime';
 67   LOWORD(v48) = 'a';
 68   *(_OWORD *)Memory = xmmword_40528C;           // htadimehtadimeht
 69   v50 = '.<';
 70   v51 = 0;
 71   v49 = xmmword_4052A4;                         // <<<....++++---->
 72   do
 73   {
 74     sub_4021E0(&v40, 1u, (*((_BYTE *)Memory + v0) ^ *((_BYTE *)&v49 + v0)) + 22);
 75     ++v0;
 76   }
 77   while ( v0 < 18 );
 78   v1 = 0;
 79   v48 = 15;
 80   v47 = 0;
 81   LOBYTE(Memory[0]) = 0;
 82   LOBYTE(v52) = 2;
 83   v2 = v42;
 84   v3 = (void **)v40;
 85   do
 86   {
 87     v4 = &v40;
 88     if ( v2 >= 0x10 )
 89       v4 = v3;
 90     sub_4021E0(Memory, 1u, *((_BYTE *)v4 + v1++) + 9);
 91   }
 92   while ( v1 < 18 );
 93   memset(&Dst, 0, 0xB8u);
 94   sub_401620(v5, v6, v7, v8);
 95   LOBYTE(v52) = 3;
 96   if ( v31[*(_DWORD *)(Dst + 4)] & 6 )
 97   {
 98     v9 = sub_402A00(std::cerr, "?W?h?a?t h?a?p?p?e?n?", sub_402C50);
 99     std::basic_ostream<char,std::char_traits<char>>::operator<<(v9, v10);
100     exit(-1);
101   }
102   sub_402E90(&Dst, &v43);
103   v11 = &v32;
104   if ( File )
105   {
106     if ( !(unsigned __int8)sub_4022F0(&v32) )
107       v11 = 0;
108     if ( fclose(File) )
109       v11 = 0;
110   }
111   else
112   {
113     v11 = 0;
114   }
115   v37 = 0;
116   v34 = 0;
117   std::basic_streambuf<char,std::char_traits<char>>::_Init(&v32);
118   v35 = dword_408590;
119   File = 0;
120   v36 = dword_408594;
121   v33 = 0;
122   if ( !v11 )
123     std::basic_ios<char,std::char_traits<char>>::setstate((char *)&Dst + *(_DWORD *)(Dst + 4), 2, 0);
124   v13 = Memory;
125   if ( v48 >= 0x10 )
126     v13 = (void **)Memory[0];
127   if ( sub_4020C0(&v43, v12, v44, (int)v13, v47) )
128   {
129     v28 = sub_402A00(std::cout, "=W=r=o=n=g=K=e=y=", sub_402C50);
130   }
131   else
132   {
133     v14 = sub_402A00(std::cout, "|------------------------------|", sub_402C50);
134     std::basic_ostream<char,std::char_traits<char>>::operator<<(v14, v15);
135     v16 = sub_402A00(std::cout, "|==============================|", sub_402C50);
136     std::basic_ostream<char,std::char_traits<char>>::operator<<(v16, v17);
137     v18 = sub_402A00(std::cout, "|==============================|", sub_402C50);
138     std::basic_ostream<char,std::char_traits<char>>::operator<<(v18, v19);
139     v20 = sub_402A00(std::cout, "|==============================|", sub_402C50);
140     std::basic_ostream<char,std::char_traits<char>>::operator<<(v20, v21);
141     v22 = sub_402A00(std::cout, "\\  /\\  /\\  /\\  /\\==============|", sub_402C50);
142     std::basic_ostream<char,std::char_traits<char>>::operator<<(v22, v23);
143     v24 = sub_402A00(std::cout, " \\/  \\/  \\/  \\/  \\=============|", sub_402C50);
144     std::basic_ostream<char,std::char_traits<char>>::operator<<(v24, v25);
145     v26 = sub_402A00(std::cout, "                 |-------------|", sub_402C50);
146     std::basic_ostream<char,std::char_traits<char>>::operator<<(v26, v27);
147     std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout, sub_402C50);
148     v28 = sub_402A00(std::cout, "Congrats You got it!", sub_402C50);
149   }
150   std::basic_ostream<char,std::char_traits<char>>::operator<<(v28, v29);
151   sub_401570(&v39);
152   std::basic_ios<char,std::char_traits<char>>::~basic_ios<char,std::char_traits<char>>(&v39);
153   if ( v48 >= 0x10 )
154     sub_402630(Memory[0], v48 + 1);
155   if ( v2 >= 0x10 )
156     sub_402630(v3, v2 + 1);
157   if ( v45 >= 0x10 )
158     sub_402630(v43, v45 + 1);
159 }

 

第74行调用sub_4021E0函数的最后一个参数生成了一个字符传入。连起来生成字符串

#include <iostream>

#define _BYTE unsigned char

using namespace std;

int main()
{
    const char* Memory = "themidathemidathemid";
    const char* v50 = ">----++++....<<<<.";
    signed int v0 = 0;
    char str;
    do {
        str = (*(Memory + v0) ^ *(v50 + v0)) + 22;
        cout << str;
        ++v0;
    } while (v0 < 18);
    system("PAUSE");
    return 0;
}

 

`[^VZe`uYaY]`s^joY

 

3.OD打开

程序打开输出是这样

 

使用OD打开之后,定位到字符串处,发现前面有条指令是可以跳过这段字符串输出的

00211233   .  8B40 04       mov eax,dword ptr ds:[eax+0x4]
00211236   .  F68405 E8FEFF>test byte ptr ss:[ebp+eax-0x118],0x6
0021123E      74 25         je Xkey.00211265
00211240   .  8B0D C8502100 mov ecx,dword ptr ds:[<&MSVCP140.std::ce>;  MSVCP140.std::cerr
00211246   .  BA E4522100   mov edx,key.002152E4                     ;  ASCII "?W?h?a?t h?a?p?p?e?n?"
0021124B   .  68 502C2100   push key.00212C50
00211250   .  E8 AB170000   call key.00212A00
00211255   .  8BC8          mov ecx,eax
00211257   .  FF15 98502100 call dword ptr ds:[<&MSVCP140.std::basic>;  MSVCP140.std::basic_ostream<wchar_t,std::char_traits<wchar_t> >::operator<<
0021125D   .  6A FF         push -0x1                                ; /status = FFFFFFFF (-1.)
0021125F   .  FF15 68512100 call dword ptr ds:[<&api-ms-win-crt-runt>; \exit

 

因此我们可以判断出,这段字符串就是个烟雾弹,让我们不能进入真正的程序的,而真正的key就在下面。

 

4.代码分析

  if ( v48 >= 0x10 )
    v13 = (void **)Memory[0];
  if ( sub_4020C0(&v43, v12, v44, (int)v13, v47) )
  {
    v28 = sub_402A00(std::cout, "=W=r=o=n=g=K=e=y=", sub_402C50);
  }
  else
  {
...

通过这段代码我们可以知道,sub_4020C0函数就藏着key,OD中找到对应的代码,设置断点

00211317   .  FF75 D4       push dword ptr ss:[ebp-0x2C]
0021131A   .  0F4345 C4     cmovnb eax,dword ptr ss:[ebp-0x3C]
0021131E   .  50            push eax
0021131F   .  FF75 BC       push dword ptr ss:[ebp-0x44]
00211322   .  51            push ecx
00211323   .  8D4D AC       lea ecx,dword ptr ss:[ebp-0x54]
00211326   .  E8 950D0000   call key.002120C0

前面都是函数的参数,运行到断点处

 

在寄存器处,我们找到了我们需要的key

 

5.get flag!

idg_cni~bjbfi|gsxb

posted @ 2019-09-22 15:34  Hk_Mayfly  阅读(805)  评论(0编辑  收藏  举报