hackme 【攻防世界】Reverse

demo41發表於2024-03-24

題目:


丟到PE裡, 無殼,64bit

丟到IDA裡,shift+F12,檢視字串,找到一個很可疑的字串

跟進去看看,找到目標函式,我另外搜尋了一下,沒有mian函式,sub_400F8E應該就是解題的關鍵函式

有部分變數我修改的名字,為了方便理解

 1 __int64 __fastcall sub_400F8E(__int64 a1, int a2, int a3, int a4, int a5, int a6)
 2 {
 3   int v6; // edx
 4   int v7; // ecx
 5   int v8; // r8d
 6   int v9; // r9d
 7   int v10; // ecx
 8   int v11; // r8d
 9   int v12; // r9d
10   char v14; // [rsp+0h] [rbp-C0h]
11   char v15; // [rsp+0h] [rbp-C0h]
12   char input[136]; // [rsp+10h] [rbp-B0h] BYREF
13   int v17; // [rsp+98h] [rbp-28h]
14   char v18; // [rsp+9Fh] [rbp-21h]
15   int v19; // [rsp+A0h] [rbp-20h]
16   unsigned __int8 input_1; // [rsp+A6h] [rbp-1Ah]
17   char key; // [rsp+A7h] [rbp-19h]
18   int v22; // [rsp+A8h] [rbp-18h]
19   int v23; // [rsp+ACh] [rbp-14h]
20   int v24; // [rsp+B0h] [rbp-10h]
21   int v25; // [rsp+B4h] [rbp-Ch]
22   _BOOL4 bool_type; // [rsp+B8h] [rbp-8h]
23   int i; // [rsp+BCh] [rbp-4h]
24 
25   sub_407470((unsigned int)"Give me the password: ", a2, a3, a4, a5, a6, a2);
26   sub_4075A0((unsigned int)"%s", (unsigned int)input, v6, v7, v8, v9, v14);
27   for ( i = 0; input[i]; ++i )
28     ;
29   bool_type = i == 22;                          // 下面要列印Congras,那if裡面的bool_type必須為1
30                                                 // i=22
31   v25 = 10;
32   do
33   {
34     v10 = (int)sub_406D90() % 22;               // v10的範圍0~21
35     v22 = v10;
36     v24 = 0;
37     key = byte_6B4270[v10];
38     input_1 = input[v10];
39     v19 = v10 + 1;
40     v23 = 0;
41     while ( v23 < v19 )
42     {
43       ++v23;
44       v24 = 1828812941 * v24 + 12345;
45     }
46     v18 = v24 ^ input_1;
47     if ( key != ((unsigned __int8)v24 ^ input_1) )
48       bool_type = 0;
49     --v25;
50   }
51   while ( v25 );
52   if ( bool_type )
53     v17 = sub_407470((unsigned int)"Congras\n", (unsigned int)input, v24, v10, v11, v12, v15);
54   else
55     v17 = sub_407470((unsigned int)"Oh no!\n", (unsigned int)input, v24, v10, v11, v12, v15);
56   return 0LL;
57 }
  • sub_407470((unsigned int)"Give me the password: ", a2, a3, a4, a5, a6, a2); sub_4075A0((unsigned int)"%s", (unsigned int)input, v6, v7, v8, v9, v14);我一開始猜測是輸出輸入用的,預防萬一後面查了資料,就是根據C語言函式可變引數的特性反彙編出來的,就是普通輸出輸入函式
    至於為什麼五個變數就第一個我修改了名稱————是看後面程式碼,透過個人理解,推出是輸入量。
  • v10 = (int)sub_406D90() % 22;可以得知v10的範圍是0~21,`sub_406D90`點進去跟蹤,我沒有得到什麼有用的東西,大佬說`v10`是一個隨機數,範圍也的確是0 ~ 21,但是不是順序來取值的——就算不知道`v10`的具體數值,但是肯定是0~21中的一個,寫逆向指令碼的時候遍歷也是可以得出的。

  • key = byte_6B4270[v10];雙擊byte_6B4270得到一串東西,應該是關鍵字串了,結合上面可以理解為:`v10`是一個隨機的下標,根據下標從`byte_6B4270`中隨機抽取一個放到`key`裡面
  • input_1 = input[v10];在輸入中隨機抽取一個放到`input_1`裡面,方便後面的異或操作
  • while ( v23 < v19 ){++v23;v24 = 1828812941 * v24 + 12345;}v18 = v24 ^ input_1這就是變換的關鍵部分了。經過加法乘法異或一系列操作,得到`v18`

  • if ( key != ((unsigned __int8)v24 ^ input_1) )這個if的作用就是檢查變換後得出的`v18`與`key`是否相等

解題指令碼

 1 key = [95,242,94,139,78,14,163,170,199,147,129,61,95,116,163,9,145,43,73,40,147,103]
 2 flag = ""
 3 
 4 for j in range(22):
 5     v23 = 0
 6     v24 = 0
 7     v19 = j + 1
 8     while v23 < v19:
 9         v23 += 1
10         v24 = 1828812941 * v24 + 12345
11     flag += chr((v24 ^ key[j])&0xff)
12 
13 print(flag)

flag: flag{d826e6926098ef46}