天天看點

攻防世界 reverse evil

這是2017 ddctf的一道逆向題,

挑戰:《惡意軟體分析》

賽題背景: 員工小A收到了一封郵件,帶一個文檔附件,小A随手打開了附件。随後IT部門發現小A的電腦發出了異常網絡通路請求,進一步調查發現小A當時所打開的附件其實是一個僞裝成word文檔的惡意可執行檔案。

賽題描述: 請在試着分析evil.exe和其所下載下傳的x.jpg, 從中找出key.

評分标準: 密鑰正确則可進入下一題。

攻防世界隻給了exe檔案,沒有給x.jpg檔案,(每個人的x.jpg檔案是不同的,解得的flag也是不一樣的。)

查殼: UPX(3.91)[NRV,best]

脫殼:

工具脫殼失敗,手動脫殼。

兩次esp脫殼法,dump。

(第一次脫沒脫幹淨,但發現可以靜态分析,0.0)

具體分析可參考:

【CTF習題】惡意軟體分析

https://www.52pojie.cn/thread-679122-1-1.html

(出處: 吾愛破解論壇)

1 int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
 2 {
 3   char *new_data; // ST10_4
 4   int key[67]; // [esp+4h] [ebp-118h]
 5   size_t dwSize; // [esp+114h] [ebp-8h]
 6   void *jpg_data; // [esp+118h] [ebp-4h]
 7 
 8   if ( sub_401370(hInstance) == 6 )
 9     return 0;
10   sub_401620();
11   jpg_data = download_xjpg_4018F0(&dwSize);
12   if ( jpg_data )
13   {
14     if ( dwSize )
15     {
16       new_data = malloc(dwSize);
17       init_key_401740(key, 0x4A8754F5745174ui64);
18       decrypt_401800(key, jpg_data, new_data, dwSize);
19       exec_shellcode_401220(new_data, dwSize);
20     }
21     free(jpg_data);
22   }
23   return 0;
24 }      

在decrypt_401800函數中,我把參數一定義成了個結構體,兩個int型成員,一個byte[256]數組

00000000 key_struct      struc ; (sizeof=0x108, mappedto_22)
00000000 x               dd ?
00000004 y               dd ?
00000008 key_data        db 256 dup(?)
00000108 key_struct      ends      

這樣再看清晰了一些

1 void __cdecl decrypt_401800(key_struct *key, char *jpg_data, char *new_data, unsigned int dwsize)
 2 {
 3   unsigned __int8 v4; // ST02_1
 4   unsigned __int8 v5; // ST03_1
 5   unsigned int i; // [esp+4h] [ebp-4h]
 6 
 7   for ( i = 0; i < dwsize; ++i )
 8   {
 9     key->x = (key->x + 1) % 256;
10     key->y = (key->key_data[key->x] + key->y) % 256;
11     v4 = key->key_data[key->x];
12     v5 = key->key_data[key->y];
13     key->key_data[key->x] = v5;
14     key->key_data[key->y] = v4;
15     new_data[i] = key->key_data[(v5 + v4) % 256] ^ jpg_data[i];
16   }
17 }      

wp:

1 key=[]
 2 a=0x4A8754F5745174
 3 temp=[0 for i in range(8)]
 4 for i in range(8):
 5     temp[i]=a
 6     a=a>>8
 7 for i in range(256):
 8     key.append((i+temp[i%8])&0xff)
 9 
10 
11 f=open('x.jpg','rb')
12 jpg_data=f.read()
13 new_data=[]
14 f.close()
15 x=0
16 y=0
17 for i in range(len(jpg_data)):
18     x=(x+1)%256
19     y=(key[x]+y)%256
20     key[x],key[y]=key[y],key[x]
21     new_data.append(((key[(key[x]+key[y])%256]^jpg_data[i])^i)&0xff)
22 # print(new_data)
23 mf=open('mydecrypt','wb')
24 mf.write(bytes(new_data))
25 mf.close()
26 
27 new_data=bytes(new_data)
28 flag = []
29 i = 0
30 while(i<len(new_data)):
31     if(new_data[i]==0x68):#這裡是解析push指令,儲存壓棧資料
32         flag.append(new_data[i+1:i+5])
33         i += 3
34     i += 1
35 
36 for i in flag[::-1]:    #輸出壓棧資料
37     print(str(i)[2:-1], end='')
38 print()      

輸出:

Key: [email protected]   user32.dll A\x8eN\x0e\xec

這題做的話最簡單的方法就是搭本地服務,然後動态調試,省時省力。

整體上程式流程清晰,算法還原也不複雜。

脫殼請參考:https://www.cnblogs.com/dliv3/p/6909066.html

攻防世界 key來源:https://blog.csdn.net/qq_38025365/article/details/89389311

[email protected]


(滴滴的題還是蠻有趣的)