題目描述如下:
賽題背景: 員工小A收到了一封郵件,帶一個檔案附件,小A隨手打開了附件,隨后IT部門發現小A的電腦發出了例外網路訪問請求,進一步調查發現小A當時所打開的附件其實是一個偽裝成word檔案的惡意可執行檔案,
賽題描述: 請在試著分析evil.exe和其所下載的x.jpg, 從中找出key.
評分標準: 密鑰正確則可進入下一題,
主要附件為一個evil.exe程式和一個x.jpg.點擊evil.exe運行后發現生成了一個evil.docx的檔案(附加:要交的flag為郵箱地址!)
一開始思路以為是會有類似于與dll注入的現象,后來使用PEview發現并沒有可疑的dll,隨后用正常思路分析
①使用exeinfope查看該exe檔案發現說有三個節區像是被upx壓縮,使用upx解壓縮失敗
②使用ollydebug動態除錯找到OEP,并脫殼
程式入口點在0043dc85處,繼續除錯會發現要經歷eax(1190)次才能運行到0043dca3 即jmp evil.043dab0處(我最開始除錯不用這么多次的!!!不知道為什么后來就是這么多次了,有試著改匯編代碼讓它直接跳過去,后來不行!!!這部分也是很關鍵的部分,f9運行到斷點處時會在retn停下來,呀呀呀,只能能不停按了)

2)運行到0043dca3處,執行跳到43dab0處,發現

執行完pushad操作后,在相應的堆疊地址處設定硬體斷點(圖里面不小心多運行了幾步>^<,不過問題不大,設定斷點的操作是一樣的)

設定完斷點后,直接f9件運行,程式會在執行popad訪問到設定斷點的地址后自動停下來,在其之后的jmp指令跳到的地方,也就是oep處

OEP處如下:

此時使用od的dump即可成功脫殼!

③使用ida打開脫殼后的檔案,f5反編譯進入主函式,代碼片段如下:
int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { void *v5; // ST10_4 char v6; // [esp+4h] [ebp-118h] size_t dwSize; // [esp+114h] [ebp-8h] void *v8; // [esp+118h] [ebp-4h] if ( sub_401370(hInstance) == 6 ) return 0; sub_401620(); v8 = (void *)sub_4018F0(&dwSize); if ( v8 ) { if ( dwSize ) { v5 = malloc(dwSize); sub_401740(&v6, -176926348, 4884308);//Initkey sub_401800(&v6, v8, v5, dwSize);//decrypt sub_401220(v5, dwSize);//Execshellcode } free(v8); } return 0; }
逐個點擊函式,sub_4018f0()函式如下:

可發現此函式通過使用InternetOpenUrlA()API函式從網站上下載x.jpg檔案(也就是附件中所給處的檔案),最后函式回傳,v8為資料的首地址,dwsize為資料大小
④繼續往下看,發現三個不知名函式(不曉得用途,猜測和要求的flag有關,之后實在有點不明所以,看writeup發現那個v6是key,函式名注釋中給出),因此大概的流程就是根據x.jpg中的資料以及經過sub_401740函式(Initkey)給出的key來求出原本從網上下載來的資料,
⑤進入sub_401740(&v6, 0x4A8754F5745174)函式,如下:

這里求出了key的值,通過寫腳本,我們也可以得到
⑥進入sub_401800(v6, (int)v8, (int)v5, dwSize);函式,如下:

此函式對下載檔案中的內容進行了一輪異或運算,最終的結果放在了a3中,也就是主函式中的v5
⑦進入sub_401220(v5, dwSize);函式中,如下:

此函式對經過decrypt函式處理后的資料再進行了一次異或運算 ,因此到這里程式的運行流程就清楚了!
⑧寫出腳本,如下:
a=open("D:\Desktop\做題檔案\8.4\\rebuilt.3.Evil.exe\\x.jpg","rb") b=a.read() print(b) a2=[] c=0x4A8754F5745174 v6=[] v6.append(0) v6.append(0) v4=[] for i in range(8): v4.append(c&0xff) c=c>>8 for i in range(256):#求出key值 x=i+v4[i%8] v6.append(x) #print(v6) d=open("D:\Desktop\做題檔案\8.4\\dump.txt","wb") temp=b'' for i in range(len(b)): v6[0]=(v6[0]+1)%256 v6[1]=(v6[v6[0]+2]+v6[1])%256#這里要注意!IDA代碼中型別從int轉變為了int8型別 v4=v6[v6[0]+2] v5=v6[v6[1]+2] v6[v6[0]+2]=v5 v6[v6[1]+2]=v4 x=(b[i]^v6[(v5+v4)%256+2]^i)%256 print(hex(x),end=' ') temp+=bytes([x]) print(temp) d.write(temp)#將資料寫入dump.txt檔案中 d.close()
運行后,dump.txt中結果如下:

emmm感覺flag已經出來了哈但又不對勁,看了writeup說這是shellcode,里面的元資料0x68代表push,每個push后的資料就是我們的flag片段,因此寫腳本可得出(注意資料在記憶體中的順序為小端順序!!!),這里還可以把資料在ollydebug中直接copy上去,od會將硬編碼轉換為看的懂的匯編代碼,從中篩選處有push的,把資料結合起來一樣是答案!
如下:
flag = [] i = 0 while(i<len(dump)): if(new_data[i]==0x68): flag.append(dump[i+1:i+5]) i += 3 i += 1 print(flag[::-1])#轉換順序 for i in flag[::-1]: print(str(i)[2:-1], end='')#去掉資料前的b'以及資料末尾的'
運行結果如下
到這里就得到了我們的flag!!!(程序艱辛!除錯程序中,電腦還崩潰了>~<)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/71745.html
標籤:其他
上一篇:jarvisoj-軟體密碼破解-2(CFF_100_1)
下一篇:記一次偶然的CTF經歷
