1.一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,包括以下步驟:
2.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟1中代碼注入利用通過(guò)緩沖區(qū)溢出漏洞將攻擊代碼shellcode寫(xiě)入進(jìn)程內(nèi)存,并劫持程序控制流到shellcode所在內(nèi)存,當(dāng)可控內(nèi)存塊無(wú)法容納shellcode時(shí),首先根據(jù)可控內(nèi)存塊symbuf[i],0≤i≤n的大小將shellcode分為n段,接著把shellcode片段依次存放在多個(gè)可控內(nèi)存塊symbuf[i]中,并使用跳轉(zhuǎn)指令連接分布在不同內(nèi)存塊中的攻擊代碼,進(jìn)而完成攻擊過(guò)程;
3.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟1中使用跳板繞過(guò)aslr中通過(guò)分析函數(shù)調(diào)用過(guò)程的棧操作可知,程序在執(zhí)行ret指令返回時(shí)會(huì)將返回地址彈出棧幀,ret指令執(zhí)行完后esp寄存器指向棧中返回地址的后一個(gè)內(nèi)存單位,并且esp中的內(nèi)容不會(huì)被溢出數(shù)據(jù)修改;把shellcode寫(xiě)入棧內(nèi)存中返回地址后的位置,然后借助“jmpesp”指令動(dòng)態(tài)定位內(nèi)存中的shellcode,可抽象為公式(3)所示的利用約束表達(dá)式描述;
4.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟1中return-to-libc繞過(guò)nx通過(guò)跳轉(zhuǎn)指令連接內(nèi)存中已有的代碼片段構(gòu)造出可完成特定功能的攻擊鏈,接著劫持控制流到攻擊鏈執(zhí)行完成利用過(guò)程;return-to-libc通過(guò)在棧中設(shè)置合適的參數(shù)調(diào)用c語(yǔ)言動(dòng)態(tài)鏈接庫(kù)libc中的函數(shù)實(shí)現(xiàn)任意代碼執(zhí)行,其攻擊鏈的構(gòu)造過(guò)程可用公式(4)表示;
5.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟2中shellcode注入利用的構(gòu)建有兩種方式:
6.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟2中ropexploit生成具體為當(dāng)二進(jìn)制程序開(kāi)啟棧不可執(zhí)行的保護(hù)時(shí),意味著注入的shellcode代碼無(wú)法被執(zhí)行,利用也就無(wú)法成功;利用內(nèi)存中已經(jīng)存在的代碼片段gadget,將這些gadget的起始地址拼湊成一個(gè)gadgetchain,劫持程序的控制流,使程序在這些gadget之間跳轉(zhuǎn),執(zhí)行g(shù)adget所擁有的功能,從而拼湊成一個(gè)完整的更為復(fù)雜的功能,可以無(wú)視棧不可執(zhí)行保護(hù),達(dá)到利用的目的。
7.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟2中在基于程序本身的gadgetchain構(gòu)造過(guò)程中,首先需要找到二進(jìn)制程序中調(diào)用的system庫(kù)函數(shù)的地址值;system函數(shù)的執(zhí)行還需要一個(gè)參數(shù),即“/bin/sh”字符串的地址;由于二進(jìn)制程序中不一定存在“/bin/sh”這樣的字符串,因此最為簡(jiǎn)便的方法就是自行將“/bin/sh”寫(xiě)入,將寫(xiě)入的地址作為system函數(shù)的參數(shù);向內(nèi)存寫(xiě)入數(shù)據(jù)需要調(diào)用read或gets這樣的函數(shù),因此同樣需要在二進(jìn)制程序中找到調(diào)用read或gets這樣的庫(kù)函數(shù)的地址值。
8.根據(jù)權(quán)利要求1所述的一種基于符號(hào)求解的自動(dòng)化漏洞利用構(gòu)造方法,其特征在于,所述步驟2中采用從動(dòng)態(tài)鏈接庫(kù)中尋找所需的gadget地址,構(gòu)造基于動(dòng)態(tài)鏈接庫(kù)的gadgetchain;linuxelf程序在被執(zhí)行時(shí),其使用的動(dòng)態(tài)鏈接庫(kù)被動(dòng)態(tài)地加載到內(nèi)存中的某一地址段,如果系統(tǒng)開(kāi)啟aslr,則其加載的地址段是變化的,否則是固定不變的;動(dòng)態(tài)鏈接庫(kù)中的函數(shù)在內(nèi)存中的實(shí)際地址會(huì)隨著動(dòng)態(tài)鏈接庫(kù)加載的地址變化而變化,但是庫(kù)函數(shù)相對(duì)于動(dòng)態(tài)鏈接庫(kù)起始位置的相對(duì)偏移量是固定保持不變的;如果知道其中一個(gè)庫(kù)函數(shù)在內(nèi)存中的實(shí)際地址,那么根據(jù)該庫(kù)函數(shù)在動(dòng)態(tài)鏈接庫(kù)中的偏移量計(jì)算出動(dòng)態(tài)鏈接庫(kù)的加載基地址;在得知?jiǎng)討B(tài)鏈接庫(kù)的加載基地址之后,只要知道動(dòng)態(tài)鏈接庫(kù)中任意函數(shù)在庫(kù)中的偏移量,就能夠計(jì)算得到任意庫(kù)函數(shù)在內(nèi)存中的實(shí)際地址;動(dòng)態(tài)鏈接庫(kù)被加載到內(nèi)存中的某一位置,在得知庫(kù)函數(shù)function1的實(shí)際地址addr時(shí),計(jì)算出動(dòng)態(tài)鏈接庫(kù)加載的基地址libbaseaddr=addr1–offset1,如果想要利用庫(kù)函數(shù)function2,計(jì)算function2在內(nèi)存中的實(shí)際地址addr2=libbaseaddr+offset2;當(dāng)程序被運(yùn)行并加載進(jìn)內(nèi)存后,程序中調(diào)用的庫(kù)函數(shù)在內(nèi)存中的實(shí)際地址會(huì)被保存在程序的got表項(xiàng)中;這里通過(guò)泄露出某一庫(kù)函數(shù)在.got表項(xiàng)中保存的函數(shù)實(shí)際地址,利用上述方法間接計(jì)算出所需的system函數(shù)地址,用于構(gòu)造system(‘/bin/sh’)開(kāi)啟shell。