新聞中心
Metasploit是一款開(kāi)源的安全漏洞檢測(cè)工具,可以幫助安全和IT專業(yè)人士識(shí)別安全性問(wèn)題,驗(yàn)證漏洞的緩解措施,并管理專家驅(qū)動(dòng)的安全性進(jìn)行評(píng)估,提供真正的安全風(fēng)險(xiǎn)情報(bào)。這些功能包括智能開(kāi)發(fā),代碼審計(jì),Web應(yīng)用程序掃描,社會(huì)工程。團(tuán)隊(duì)合作,在Metasploit和綜合報(bào)告提出了他們的發(fā)現(xiàn)。

成都創(chuàng)新互聯(lián)公司主營(yíng)老邊網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營(yíng)網(wǎng)站建設(shè)方案,成都app軟件開(kāi)發(fā),老邊h5小程序定制開(kāi)發(fā)搭建,老邊網(wǎng)站營(yíng)銷推廣歡迎老邊等地區(qū)企業(yè)咨詢
本文研究的惡意樣本的MD5哈希:9d7e34250477acf632c6c32fc2c50d3b。
Shllcode分析第1階段:靜態(tài)分析
首先,你要在你選擇的反匯編程序中打開(kāi)shellcode ,我個(gè)人更喜歡IDA Pro,但是我不會(huì)使用偽代碼功能,而是將重點(diǎn)放在反匯編視圖上,因此這應(yīng)該適用于你選擇的任何工具。通過(guò)IDA Pro,你可以選擇如何加載二進(jìn)制數(shù)據(jù)(16位、32位或64位),因此,我將首先選擇32位,如果反匯編有任何錯(cuò)誤,我們可以對(duì)其進(jìn)行簡(jiǎn)單地更改。加載二進(jìn)制文件后,選擇第一個(gè)字節(jié)并按“ C”,這將嘗試將第一個(gè)字節(jié)轉(zhuǎn)換為代碼。因此,重新分析該文件,然后嘗試將其余字節(jié)反匯編為部件。如下所示,入口點(diǎn)從位置0x00開(kāi)始,shellcode一直向上到達(dá)位置0x2A,此時(shí)IDA無(wú)法將剩余的字節(jié)轉(zhuǎn)換為程序集。
僅基于這個(gè)事實(shí),我們就可以假定這部分?jǐn)?shù)據(jù)是以某種方式加密的,并且上面的shellcode解密并執(zhí)行它。因此,讓我們來(lái)看看第一個(gè)要運(yùn)行的函數(shù)sub_0()。此函數(shù)僅負(fù)責(zé)跳轉(zhuǎn)到偏移量0x25,它將執(zhí)行sub_2(),我將其命名為main_func(),因?yàn)樗舜蟛糠执a,因此,讓我們繼續(xù)研究該函數(shù)。
因此,這個(gè)函數(shù)內(nèi)部的解密相當(dāng)簡(jiǎn)單,只是一個(gè)基本的XOR循環(huán),它將[edi]指向的XOR數(shù)據(jù)與[esi]指向的數(shù)據(jù)結(jié)合起來(lái)。在每一次XOR操作之后,edi(存儲(chǔ)器地址)都會(huì)增加,并且程序會(huì)將[esi:esi + 1]與0x550D進(jìn)行比較。在本例中,IDA以Little-Endian顯示該值,,因此它被顯示為0x0D55。如果值匹配,它將跳到ecx指向的地址,否則它將增加esi,將它現(xiàn)在指向的數(shù)據(jù)與0x73進(jìn)行比較,如果匹配,它將恢復(fù)原始地址(存儲(chǔ)在ebx中)。如果不匹配,它將循環(huán)回到XOR代碼并繼續(xù)。
基于以上分析,我們知道esi用作密鑰,而edi被用作加密的shellcode。我們還知道密鑰長(zhǎng)度可以是任何長(zhǎng)度,并且ebx將包含指向密鑰首字節(jié)的地址。
利用所有這些信息,讓我們首先嘗試找出加密數(shù)據(jù)的開(kāi)始和停止位置。從XOR循環(huán)(loc_F)開(kāi)始并向上移動(dòng)。我們可以首先看到存儲(chǔ)在edi中的地址被移動(dòng)到ecx中,這是有意義的,因?yàn)橐坏┙饷芡瓿桑绦蚓蜁?huì)跳轉(zhuǎn)到ecx中的地址。
現(xiàn)在,我們找到edi從ebx處獲取加密代碼地址,在函數(shù)的最頂部,彈出堆棧頂部的值,并將其存儲(chǔ)在ebx中,然后將該值移到edi中,然后將0x73移動(dòng)到eax的較低位,調(diào)用cld,然后輸入a scasb循環(huán)。問(wèn)題是,當(dāng)它彈出ebx時(shí),堆棧的頂部是什么?
好了,簡(jiǎn)單地看一下調(diào)試器中的堆棧,可以發(fā)現(xiàn),當(dāng)調(diào)用一個(gè)函數(shù)時(shí),堆棧頂部的值是要返回的地址,這是調(diào)用指令之后的指令地址。在下圖中,返回地址為0x013B1CAB,調(diào)用該函數(shù)的地址為0x013B1CA6(此處的調(diào)用指令占用5個(gè)字節(jié))。那么,這如何適用于我們的shellcode?
上面我們說(shuō)過(guò),main_func是從位置0x25調(diào)用的。無(wú)法識(shí)別的數(shù)據(jù)從0x2A開(kāi)始。位置0x25之后的5個(gè)字節(jié)可為調(diào)用指令騰出空間。因此,main_func()中位于堆棧頂部的數(shù)據(jù)為值0x2A。現(xiàn)在,我們終于知道了加密數(shù)據(jù)的起始位置!
不過(guò)不要高興得太早,還記得0x73移入al后如何調(diào)用cld嗎? cld指令負(fù)責(zé)刪除(設(shè)置為0)EFLAGS寄存器中的DF(direction)標(biāo)志。當(dāng)此標(biāo)志為0時(shí),任何字符串操作都會(huì)根據(jù)操作中使用的寄存器來(lái)遞增索引寄存器,尤其是esi或edi。調(diào)用cld后,將進(jìn)入一個(gè)循環(huán),該循環(huán)不斷執(zhí)行scasb,直到ZF(0)標(biāo)志被設(shè)置(設(shè)置為1)。 scasb會(huì)做什么?它所做的只是將al中的字節(jié)與[edi]進(jìn)行比較,并根據(jù)結(jié)果設(shè)置狀態(tài)標(biāo)志。如果不匹配,則ZF將保持刪除狀態(tài),否則將被設(shè)置,并且程序會(huì)跳出循環(huán)。此外,由于scasb是字符串操作,因此它將在每個(gè)循環(huán)后增加edi中的地址,這意味著直到[edi]等于0x73為止,程序?qū)⒂肋h(yuǎn)不會(huì)執(zhí)行解密功能?,F(xiàn)在我們知道,加密的數(shù)據(jù)從0x73開(kāi)始,密鑰是從地址0x2A一直到[address] = 0x73的數(shù)據(jù)。如上圖所示,0x73是ebx指向的數(shù)據(jù)中的第二個(gè)字節(jié)。因此,XOR密鑰為0x06,加密的數(shù)據(jù)從0x2B開(kāi)始!向下滾動(dòng)到函數(shù)的最后,我們可以找到字節(jié)0x550D,這意味著加密的數(shù)據(jù)長(zhǎng)401個(gè)字節(jié)!
了解了所有內(nèi)容之后,讓我們進(jìn)入解密階段!
Shllcode分析第2階段:解密
因此,我們現(xiàn)在有了XOR密鑰:0x06,以及加密數(shù)據(jù)開(kāi)始的位置:0x2B。有了這些知識(shí),我們就可以輕松地用Python編寫(xiě)一個(gè)基本的XOR解密函數(shù),該函數(shù)帶有2個(gè)參數(shù):密鑰和加密的數(shù)據(jù)。向函數(shù)添加一個(gè)簡(jiǎn)單的檢查,以查看數(shù)據(jù)是否與0x550D匹配并且腳本是否已完成!
但是,為了實(shí)際使用它,我們需要手動(dòng)或使用YARA或Regex從IDA提取數(shù)據(jù)來(lái)定位它。然后我們必須在新的IDA會(huì)話中將其打開(kāi),并且在某些情況下第二個(gè)“階段”從第一階段開(kāi)始調(diào)用函數(shù),可能是對(duì)另一部分?jǐn)?shù)據(jù)進(jìn)行XOR。幸運(yùn)的是,我們可以將此基本腳本轉(zhuǎn)換為IDAPython格式,并用解密的Shellcode覆蓋加密的Shellcode!
不用擔(dān)心,遷移到IDAPython的過(guò)程非常簡(jiǎn)單。首先,我們需要導(dǎo)入所需的庫(kù)idaapi,然后將for循環(huán)更改為while循環(huán),然后才能對(duì)傳入的數(shù)據(jù)調(diào)用len(),但是在這種情況下,我們不知道數(shù)據(jù)的長(zhǎng)度如何,因?yàn)槲覀儸F(xiàn)在正在傳遞加密數(shù)據(jù)的地址。
除此之外,只要在address + i中仍有數(shù)據(jù),就可以使while循環(huán)連續(xù)循環(huán)。這可以通過(guò)使用Byte()函數(shù)來(lái)實(shí)現(xiàn),該函數(shù)從給定地址獲取一個(gè)字節(jié)的數(shù)據(jù)。在本文的示例中,該地址就是我們的加密blob。現(xiàn)在,我們就可以將該數(shù)據(jù)字節(jié)分配給一個(gè)變量字節(jié),然后將其與0x55進(jìn)行比較。我們還將address+(i+1)與0x0D進(jìn)行比較,以確保這兩個(gè)標(biāo)記都存在。
如果這些標(biāo)記不存在,則使用給定的輸入執(zhí)行XOR字節(jié)操作,然后調(diào)用PatchByte(),它將用我們的變量byte在address+i處覆蓋字節(jié)。最后,將i增加1,循環(huán)繼續(xù)!
將它導(dǎo)入IDA,并在命令行中輸入ida_xor_crypt(0x06, 0x2B),將執(zhí)行我們的函數(shù),覆蓋數(shù)據(jù),如下圖所示!它不再以0x73開(kāi)頭,因?yàn)楝F(xiàn)在是0x75。
將它導(dǎo)入IDA,并在命令行中輸入ida_xor_crypt(0x06, 0x2B),將執(zhí)行我們的函數(shù),覆蓋數(shù)據(jù),如下圖所示我們可以在選擇0x75的情況下再次按“ C”,然后將其完全分解。
本文翻譯自:https://0ffset.net/reverse-engineering/malware-analysis/common-shellcode-techniques/如若轉(zhuǎn)載,請(qǐng)注明原文地址
網(wǎng)頁(yè)標(biāo)題:靜態(tài)逆向工程Shellcode技術(shù)(上)
網(wǎng)址分享:http://www.5511xx.com/article/cohchds.html


咨詢
建站咨詢
