本發(fā)明涉及信息安全技術(shù)領(lǐng)域,涉及一種移動(dòng)智能終端的操作系統(tǒng)的堆溢出漏洞驗(yàn)證方法,更具體地,涉及一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證方法。
背景技術(shù):
隨著移動(dòng)互聯(lián)網(wǎng)的快速發(fā)展,Android系統(tǒng)已經(jīng)成為目前全球市場(chǎng)占比最高的移動(dòng)智能終端操作系統(tǒng)?;贏ndroid系統(tǒng)的智能設(shè)備作為用戶日常社交通信和移動(dòng)辦公的媒介,存儲(chǔ)了大量的用戶隱私信息和敏感數(shù)據(jù),因此很容易成為惡意攻擊的主要目標(biāo)。
近年來(lái),Android系統(tǒng)不斷曝光各種漏洞,嚴(yán)重影響了系統(tǒng)自身的安全性,進(jìn)而威脅到上層應(yīng)用軟件的數(shù)據(jù)、業(yè)務(wù)和代碼安全。Android系統(tǒng)更新機(jī)制慢、更新周期長(zhǎng)和版本碎片化問(wèn)題,使得系統(tǒng)漏洞的補(bǔ)丁無(wú)法及時(shí)有效地部署到用戶的終端設(shè)備上,這在無(wú)形中提升了系統(tǒng)漏洞的利用價(jià)值,為攻擊者提供了可乘之機(jī)。
其中,堆溢出漏洞是一類危害很大的Android系統(tǒng)漏洞。堆溢出漏洞能導(dǎo)致堆內(nèi)存空間中的緩沖區(qū)溢出,覆蓋一些關(guān)鍵數(shù)據(jù),讓攻擊者有機(jī)會(huì)篡改系統(tǒng)的執(zhí)行流程,控制系統(tǒng)去執(zhí)行惡意代碼,達(dá)到竊取隱私信息和敏感數(shù)據(jù)的目的。為了提升系統(tǒng)安全性,有必要對(duì)各個(gè)版本的Android系統(tǒng)中的堆溢出漏洞進(jìn)行驗(yàn)證,以判斷Android系統(tǒng)是否存在特定的堆溢出漏洞,并且這些漏洞能否被攻擊者利用。
中國(guó)發(fā)明專利CN104751056A披露了一種基于攻擊庫(kù)的漏洞驗(yàn)證系統(tǒng)與方法,該方法以漏洞掃描結(jié)果為基礎(chǔ)設(shè)計(jì)驗(yàn)證方法,在虛擬機(jī)中構(gòu)建合適的模擬攻擊環(huán)境,編寫漏洞驗(yàn)證腳本進(jìn)行測(cè)試,以驗(yàn)證目 標(biāo)漏洞的存在性和危害性。多個(gè)漏洞驗(yàn)證腳本形成一個(gè)攻擊庫(kù),當(dāng)新的漏洞出現(xiàn)時(shí),匹配攻擊庫(kù)中的漏洞驗(yàn)證腳本進(jìn)行驗(yàn)證。該方案是在Windows平臺(tái)上實(shí)現(xiàn)的,Windows是電腦操作系統(tǒng),而Android是移動(dòng)智能終端操作系統(tǒng),二者實(shí)現(xiàn)機(jī)制完全不一樣,因此該方案不適用于Android系統(tǒng)。另外,該方案需要在虛擬機(jī)中構(gòu)建合適的模擬攻擊環(huán)境,配置模擬環(huán)境的過(guò)程需要人工進(jìn)行,開(kāi)發(fā)成本高。此外,Android模擬器雖然支持在電腦上模擬終端設(shè)備的運(yùn)行環(huán)境,但是它受限于硬件配置,無(wú)法完全還原出真實(shí)設(shè)備的環(huán)境,因此該方案并不適用于Android系統(tǒng)。
Ke Yan等人在論文《A Highly Automated Binary Software Vulnerability Risk Evaluation Method For Off-by-one Stack Based Buffer Overflow》中提出了一個(gè)棧緩沖區(qū)溢出漏洞的驗(yàn)證方案。該漏洞驗(yàn)證方案會(huì)構(gòu)造畸形的輸入數(shù)據(jù),觸發(fā)棧內(nèi)存空間的緩沖區(qū)溢出,覆蓋函數(shù)返回地址;當(dāng)程序完成函數(shù)調(diào)用后嘗試返回時(shí),被覆蓋的函數(shù)返回地址會(huì)將程序控制流引導(dǎo)到其它地址,執(zhí)行注入的漏洞驗(yàn)證代碼;通過(guò)確定目標(biāo)漏洞的存在性和可利用性,完成漏洞驗(yàn)證。該方案是在Windows平臺(tái)上實(shí)現(xiàn)的;Windows是電腦操作系統(tǒng),而Android是移動(dòng)智能終端操作系統(tǒng),二者實(shí)現(xiàn)機(jī)制完全不一樣,因此該方案不適用于Android系統(tǒng)。該方案針對(duì)二進(jìn)制軟件的棧溢出漏洞進(jìn)行驗(yàn)證,棧內(nèi)存空間與堆內(nèi)存空間的實(shí)現(xiàn)機(jī)制和內(nèi)存布局有很大差別,因此該方案不適用于堆溢出漏洞。
技術(shù)實(shí)現(xiàn)要素:
為了克服上述問(wèn)題,本發(fā)明提供一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證方法。根據(jù)本發(fā)明的一個(gè)方面,提供一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證裝置,包括漏洞檢測(cè)模塊、利用判定模塊和利用驗(yàn)證模塊;
其中,漏洞檢測(cè)模塊,用于向堆緩沖區(qū)填寫第一輸入樣本,檢測(cè)是否發(fā)生堆溢出,以確定堆溢出漏洞的存在性;
利用判定模塊,用于根據(jù)漏洞檢測(cè)模塊的結(jié)果,向堆緩沖區(qū)填寫第二輸入樣本,通過(guò)執(zhí)行漏洞引發(fā)Android系統(tǒng)的系統(tǒng)進(jìn)程崩潰,以確定堆溢出漏洞被利用的可能性;
利用驗(yàn)證模塊,用于根據(jù)利用判定模塊的結(jié)果,向堆緩沖區(qū)填寫第三輸入樣本,通過(guò)執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程,以驗(yàn)證堆溢出漏洞的可利用性。
根據(jù)本發(fā)明的另一方面,提供一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證方法,包括:
步驟1,向堆緩沖區(qū)填寫第一輸入樣本,檢測(cè)是否發(fā)生堆溢出,以確定Android系統(tǒng)是否存在堆溢出漏洞;
步驟2,基于堆溢出漏洞存在的檢測(cè)結(jié)果,向堆緩沖區(qū)填寫第二輸入樣本,執(zhí)行漏洞引發(fā)Android系統(tǒng)的系統(tǒng)進(jìn)程崩潰,確定堆溢出漏洞被利用的可能性;
步驟3,基于堆溢出漏洞可能可利用,向堆緩沖區(qū)填寫第三輸入樣本,執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程,驗(yàn)證堆溢出漏洞的可利用性。
本申請(qǐng)?zhí)岢龅难b置和方法對(duì)Android系統(tǒng)中存在的堆溢出漏洞進(jìn)行驗(yàn)證,以確定漏洞的存在性和可利用性,所述方法針對(duì)Android系統(tǒng)漏洞,不需要構(gòu)建模擬環(huán)境,可以直接在真實(shí)的終端設(shè)備中進(jìn)行驗(yàn)證。
本發(fā)明提出的Android系統(tǒng)堆溢出漏洞驗(yàn)證裝置和方法可以有效判斷Android系統(tǒng)是否存在特定的堆溢出漏洞,并且這些漏洞能否被攻擊者利用,從而評(píng)估堆溢出漏洞給Android系統(tǒng)帶來(lái)的安全風(fēng)險(xiǎn),促使安全研究人員及時(shí)采取保護(hù)措施來(lái)加固系統(tǒng),提升系統(tǒng)安全性。該裝置和方法的針對(duì)性強(qiáng),準(zhǔn)確度高,可擴(kuò)展性良好。
附圖說(shuō)明
圖1為含虛函數(shù)的C++對(duì)象的內(nèi)存布局示意圖;
圖2為根據(jù)本發(fā)明實(shí)施例的Android系統(tǒng)堆溢出漏洞驗(yàn)證裝置的示 意圖;
圖3為根據(jù)本發(fā)明實(shí)施例的堆溢出漏洞驗(yàn)證的利用判定步驟的流程圖;
圖4為根據(jù)本發(fā)明實(shí)施例的堆溢出漏洞驗(yàn)證的利用驗(yàn)證步驟的流程圖;
圖5為根據(jù)本發(fā)明實(shí)施例的緩沖區(qū)輸入樣本的結(jié)構(gòu)示意圖。
具體實(shí)施方式
下面結(jié)合附圖和實(shí)施例,對(duì)本發(fā)明的具體實(shí)施方式作進(jìn)一步詳細(xì)描述。以下實(shí)施例用于說(shuō)明本發(fā)明,但不用來(lái)限制本發(fā)明的范圍。
在Android系統(tǒng)中,一個(gè)C++對(duì)象的實(shí)例通常被分配在堆內(nèi)存空間中。如果這個(gè)C++對(duì)象實(shí)現(xiàn)了虛函數(shù),那么它在內(nèi)存中的基本布局如圖1所示,圖1為含虛函數(shù)的C++對(duì)象的內(nèi)存布局的示意圖。
可見(jiàn),這個(gè)C++對(duì)象的實(shí)例被分配在堆內(nèi)存空間中,其內(nèi)存起始位置存放四字節(jié)長(zhǎng)度的虛函數(shù)表指針。成員變量等其它數(shù)據(jù)被分配在這個(gè)虛函數(shù)表指針的后面。虛函數(shù)表指針指向代碼段中的一個(gè)虛函數(shù)表。這個(gè)虛函數(shù)表默認(rèn)由構(gòu)造函數(shù)進(jìn)行初始化,包含這個(gè)C++對(duì)象所有虛函數(shù)的函數(shù)指針。這些函數(shù)指針指向代碼段中對(duì)應(yīng)的函數(shù)片段。
當(dāng)Android系統(tǒng)中的某個(gè)系統(tǒng)進(jìn)程調(diào)用這個(gè)C++對(duì)象的虛函數(shù)時(shí),它會(huì)通過(guò)對(duì)象實(shí)例在堆內(nèi)存空間中的地址得到虛函數(shù)表指針,根據(jù)虛函數(shù)表指針找到代碼段中對(duì)應(yīng)的虛函數(shù)表,然后遍歷其中的函數(shù)指針,找到對(duì)應(yīng)的函數(shù)片段并執(zhí)行相應(yīng)的函數(shù)。如果虛函數(shù)表指針被非法破壞,這個(gè)C++對(duì)象的虛函數(shù)調(diào)用就會(huì)出現(xiàn)異常。
如下可以知道,Android系統(tǒng)堆溢出漏洞的成因。向堆緩沖區(qū)填寫數(shù)據(jù)時(shí),沒(méi)有正確檢查緩沖區(qū)的邊界,導(dǎo)致填寫的數(shù)據(jù)長(zhǎng)度超過(guò)了緩沖區(qū)的大小。超出的數(shù)據(jù)會(huì)覆蓋堆緩沖區(qū)后面的內(nèi)存區(qū)域。如果C++ 對(duì)象的虛函數(shù)表指針恰好被溢出的數(shù)據(jù)覆蓋,指向了堆緩沖區(qū)所在的內(nèi)存區(qū)域,那么系統(tǒng)進(jìn)程在調(diào)用這個(gè)C++對(duì)象的虛函數(shù)時(shí),會(huì)被錯(cuò)誤地引導(dǎo)到堆緩沖區(qū),去尋找虛函數(shù)表和函數(shù)指針并執(zhí)行相應(yīng)函數(shù)。
由于Android系統(tǒng)默認(rèn)將堆內(nèi)存標(biāo)記為不可執(zhí)行,因此堆溢出后的虛函數(shù)調(diào)用過(guò)程會(huì)發(fā)生錯(cuò)誤,拋出違反執(zhí)行約束的異常信息,導(dǎo)致系統(tǒng)進(jìn)程崩潰。
本申請(qǐng)的實(shí)施例將利用上述原理進(jìn)行漏洞驗(yàn)證,提供一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證裝置和方法。圖2示出根據(jù)本發(fā)明實(shí)施例的Android系統(tǒng)堆溢出漏洞驗(yàn)證裝置的運(yùn)行示意圖,如圖2所示,該裝置包括三個(gè)功能模塊:漏洞檢測(cè)模塊、利用判定模塊以及利用驗(yàn)證模塊。其中,漏洞檢測(cè)模塊用于向堆緩沖區(qū)填寫第一輸入樣本,檢測(cè)是否發(fā)生堆溢出,以確定堆溢出漏洞的存在性;利用判定模塊用于根據(jù)漏洞檢測(cè)模塊的結(jié)果,向堆緩沖區(qū)填寫第二輸入樣本,通過(guò)執(zhí)行漏洞引發(fā)Android系統(tǒng)的系統(tǒng)進(jìn)程崩潰,以確定堆溢出漏洞被利用的可能性;利用驗(yàn)證模塊用于根據(jù)利用判定模塊的結(jié)果,向堆緩沖區(qū)填寫第三輸入樣本,通過(guò)執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程,以驗(yàn)證堆溢出漏洞的可利用性。其中,本申請(qǐng)的漏洞驗(yàn)證結(jié)果有三種:漏洞不存在、漏洞存在但不可利用、漏洞存在且可利用,分別可以在三個(gè)模塊的結(jié)果中得到。漏洞是否可利用的依據(jù)是:攻擊者可以通過(guò)執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程。
其中,漏洞檢測(cè)模塊用于向堆緩沖區(qū)填寫合適的第一輸入樣本,檢測(cè)是否發(fā)生堆溢出,以確定Android系統(tǒng)是否存在堆溢出漏洞。
其中,漏洞檢測(cè)模塊中所構(gòu)造的第一輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié)。多出的該四個(gè)字節(jié)為溢出值value1,用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。
其中,在漏洞檢測(cè)模塊中,堆溢出的檢測(cè)方法是:創(chuàng)建C++對(duì)象后,監(jiān)控該對(duì)象所在的堆內(nèi)存區(qū)域;該內(nèi)存區(qū)域的前四個(gè)字節(jié)存放的是虛函數(shù)表指針,記錄該值為vftp1;向堆緩沖區(qū)填寫第一輸入樣本后,記錄該內(nèi)存區(qū)域的前四個(gè)字節(jié)的值為vftp2;如果滿足條件vftp2?。絭ftp1,且vftp2=value1,說(shuō)明這個(gè)C++對(duì)象的虛函數(shù)表指針被第一輸入樣本的溢出值value1覆蓋,證明堆溢出漏洞存在,進(jìn)入利用判定模塊。反之,說(shuō)明沒(méi)有發(fā)生堆溢出,直接得出漏洞不存在的驗(yàn)證結(jié)果。
在一個(gè)實(shí)施例中,利用動(dòng)態(tài)調(diào)試工具IDA Pro遠(yuǎn)程附加Android系統(tǒng)的系統(tǒng)進(jìn)程,實(shí)現(xiàn)對(duì)C++對(duì)象堆內(nèi)存區(qū)域的監(jiān)控。
其中,利用判定模塊在漏洞存在的基礎(chǔ)上,進(jìn)一步判定堆溢出漏洞是否可利用。漏洞是否可利用的依據(jù)是:攻擊者可以通過(guò)執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程。圖3為根據(jù)本發(fā)明實(shí)施例的堆溢出漏洞驗(yàn)證的利用判定模塊的運(yùn)行流程圖,如圖3所示。
首先,模塊構(gòu)造一個(gè)緩沖區(qū)第二輸入樣本。所構(gòu)造的第二輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié),多出的該四個(gè)字節(jié)為溢出值,并且該值恰好位于堆緩沖區(qū)的內(nèi)存地址區(qū)間內(nèi),用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。然后,向堆緩沖區(qū)填寫該第二輸入樣本,判斷Android系統(tǒng)進(jìn)程是否崩潰。如果堆溢出后引發(fā)系統(tǒng)進(jìn)程崩潰,說(shuō)明這個(gè)堆溢出漏洞能夠影響系統(tǒng)進(jìn)程,進(jìn)行下一步判定。否則,分析原因,重新構(gòu)造緩沖區(qū)輸入樣本。Android系統(tǒng)進(jìn)程崩潰的判斷方法是:使用Android調(diào)試橋(ADB)運(yùn)行l(wèi)ogcat命令訪問(wèn)系統(tǒng)日志,觀察是否有關(guān)于系統(tǒng)進(jìn)程的崩潰日志。如果有該系統(tǒng)進(jìn)程的崩潰日志,說(shuō)明發(fā)生了進(jìn)程崩潰,反之則沒(méi)有。
如果Android系統(tǒng)進(jìn)程發(fā)生崩潰,通過(guò)分析崩潰日志,判斷這個(gè)系統(tǒng)進(jìn)程是否在虛函數(shù)調(diào)用點(diǎn)崩潰。如果這個(gè)系統(tǒng)進(jìn)程在虛函數(shù)調(diào)用點(diǎn)崩潰,得出一個(gè)漏洞驗(yàn)證的中間結(jié)果:漏洞存在且可能可利用,進(jìn)入 利用驗(yàn)證模塊。否則,得到最終的漏洞驗(yàn)證結(jié)果:漏洞存在但不可利用。
Android系統(tǒng)進(jìn)程是否在虛函數(shù)調(diào)用點(diǎn)崩潰的判斷方法是:如果崩潰日志中含有違反執(zhí)行約束的異常信息,并且崩潰地址位于堆緩沖區(qū)的內(nèi)存地址區(qū)間內(nèi),說(shuō)明系統(tǒng)進(jìn)程被錯(cuò)誤地引導(dǎo)到堆緩沖區(qū)去尋找虛函數(shù)表和函數(shù)指針并執(zhí)行相應(yīng)函數(shù),則認(rèn)為系統(tǒng)進(jìn)程是在虛函數(shù)調(diào)用點(diǎn)崩潰;否則不是。
其中,利用驗(yàn)證模塊用于在漏洞存在且可能可利用的基礎(chǔ)上,對(duì)這個(gè)堆溢出漏洞的可利用性進(jìn)行驗(yàn)證。圖4為根據(jù)本發(fā)明實(shí)施例的堆溢出漏洞驗(yàn)證的利用驗(yàn)證模塊的運(yùn)行圖,如圖4所示。
首先,構(gòu)造一個(gè)緩沖區(qū)第三輸入樣本;所構(gòu)造的第三輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié),包含四部分內(nèi)容:溢出值、偽造的虛函數(shù)表、偽造的函數(shù)以及填充數(shù)據(jù),如圖5所示。多出的該四個(gè)字節(jié)為溢出值,并且該值恰好是偽造的虛函數(shù)表在堆內(nèi)存空間中的起始地址,用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。
其中,如圖5所示,偽造的虛函數(shù)表中含有一個(gè)偽造的函數(shù)指針,其值被設(shè)置為偽造的函數(shù)在堆內(nèi)存空間中的起始地址,用來(lái)誤導(dǎo)系統(tǒng)進(jìn)程調(diào)用相應(yīng)的虛函數(shù),執(zhí)行偽造的函數(shù)。
其中,偽造的函數(shù)由多個(gè)匯編指令組成,實(shí)現(xiàn)了兩個(gè)功能:1,將堆緩沖區(qū)的內(nèi)存區(qū)域標(biāo)記為可執(zhí)行,允許系統(tǒng)進(jìn)程在堆緩沖區(qū)中執(zhí)行指令,避免違反執(zhí)行約束;2,實(shí)現(xiàn)一個(gè)顯式的功能,例如在Android文件系統(tǒng)/sdcard/目錄下創(chuàng)建新文件newfile.txt。
其中,如果偽造的虛函數(shù)表和偽造的函數(shù)不是四字節(jié)對(duì)齊的,需要在其后放置填充數(shù)據(jù),以保證堆內(nèi)存空間的字節(jié)對(duì)齊。同時(shí),填充數(shù)據(jù)還需要保證所構(gòu)造的第三輸入樣本的大小比緩沖區(qū)大小多四個(gè)字節(jié)。
如圖4所示,然后,向堆緩沖區(qū)填寫該第三輸入樣本,觸發(fā)堆緩沖區(qū)溢出;溢出后,C++對(duì)象的虛函數(shù)表指針將會(huì)被溢出值覆蓋,指向堆內(nèi)存空間中偽造的虛函數(shù)表;隨后系統(tǒng)進(jìn)程在調(diào)用虛函數(shù)時(shí),會(huì)根據(jù)被覆蓋的虛函數(shù)表指針找到偽造的虛函數(shù)表,然后被偽造的函數(shù)指針錯(cuò)誤地引導(dǎo)到偽造的函數(shù)處去執(zhí)行匯編指令。
最后,通過(guò)查看顯式的功能是否被執(zhí)行,來(lái)判斷Android系統(tǒng)的系統(tǒng)進(jìn)程是否執(zhí)行了偽造的函數(shù)。例如查看Android文件系統(tǒng)/sdcard/目錄下是否已創(chuàng)建了新文件newfile.txt。如果已執(zhí)行,說(shuō)明已成功利用這個(gè)堆溢出漏洞,得到漏洞驗(yàn)證結(jié)果:漏洞存在且可利用。否則,分析原因,重新構(gòu)造堆緩沖區(qū)輸入樣本。
根據(jù)本申請(qǐng)的另一個(gè)實(shí)施例,提供一種Android系統(tǒng)的堆溢出漏洞驗(yàn)證方法,該方法包括:步驟1,向堆緩沖區(qū)填寫第一輸入樣本,檢測(cè)是否發(fā)生堆溢出,以確定Android系統(tǒng)是否存在堆溢出漏洞;步驟2,基于堆溢出漏洞存在的檢測(cè)結(jié)果,向堆緩沖區(qū)填寫第二輸入樣本,執(zhí)行漏洞引發(fā)Android系統(tǒng)的系統(tǒng)進(jìn)程崩潰,以確定堆溢出漏洞被利用的可能性;步驟3,基于堆溢出漏洞可能可利用,向堆緩沖區(qū)填寫第三輸入樣本,通過(guò)執(zhí)行漏洞控制Android系統(tǒng)的系統(tǒng)進(jìn)程的執(zhí)行流程,以驗(yàn)證堆溢出漏洞的可利用性。
其中,本申請(qǐng)的漏洞驗(yàn)證結(jié)果有三種:漏洞不存在、漏洞存在但不可利用、漏洞存在且可利用,分別可以在三個(gè)步驟的結(jié)果中得到。漏洞是否可利用的依據(jù)是:攻擊者可以通過(guò)執(zhí)行漏洞控制Android系統(tǒng)進(jìn)程的執(zhí)行流程。
其中,步驟1中,所構(gòu)造的第一輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié)。多出的該四個(gè)字節(jié)為溢出值value1,用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。其中,步驟1中,堆溢出的檢測(cè)方法是:創(chuàng)建C++對(duì)象后,監(jiān)控該對(duì)象所在的堆內(nèi)存區(qū)域;該內(nèi)存區(qū)域的前四個(gè)字節(jié)存 放的是虛函數(shù)表指針,記錄該值為vftp1;向堆緩沖區(qū)填寫第一輸入樣本后,記錄該內(nèi)存區(qū)域的前四個(gè)字節(jié)的值為vftp2;如果滿足條件vftp2?。絭ftp1,且vftp2=value1,說(shuō)明這個(gè)C++對(duì)象的虛函數(shù)表指針被第一輸入樣本的溢出值value1覆蓋,證明堆溢出漏洞存在,進(jìn)入步驟2。反之,說(shuō)明沒(méi)有發(fā)生堆溢出,直接得出漏洞不存在的驗(yàn)證結(jié)果。
在一個(gè)實(shí)施例中,利用動(dòng)態(tài)調(diào)試工具IDA Pro遠(yuǎn)程附加Android系統(tǒng)的系統(tǒng)進(jìn)程,實(shí)現(xiàn)對(duì)C++對(duì)象堆內(nèi)存區(qū)域的監(jiān)控。
其中,步驟2中,基于漏洞存在的基礎(chǔ)上,進(jìn)一步判定堆溢出漏洞是否可利用。漏洞是否可利用的依據(jù)是:攻擊者可以通過(guò)執(zhí)行漏洞控制Android系統(tǒng)進(jìn)程的執(zhí)行流程,具體包括如下步驟。
步驟21,構(gòu)造一個(gè)緩沖區(qū)第二輸入樣本。所構(gòu)造的第二輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié)。多出的該四個(gè)字節(jié)為溢出值,并且該值恰好位于堆緩沖區(qū)的內(nèi)存地址區(qū)間內(nèi),用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。
步驟22,向堆緩沖區(qū)填寫該第二輸入樣本,判斷Android系統(tǒng)進(jìn)程是否崩潰。如果堆溢出后引發(fā)系統(tǒng)進(jìn)程崩潰,說(shuō)明這個(gè)堆溢出漏洞能夠影響系統(tǒng)進(jìn)程,進(jìn)入步驟3判定。否則,分析原因,重新構(gòu)造緩沖區(qū)輸入樣本。Android系統(tǒng)進(jìn)程崩潰的判斷方法是:使用Android調(diào)試橋(ADB)運(yùn)行l(wèi)ogcat命令訪問(wèn)系統(tǒng)日志,觀察是否有關(guān)于系統(tǒng)進(jìn)程的崩潰日志。如果有該系統(tǒng)進(jìn)程的崩潰日志,說(shuō)明發(fā)生了進(jìn)程崩潰,反之則沒(méi)有。
如果Android系統(tǒng)進(jìn)程發(fā)生崩潰,通過(guò)分析崩潰日志,判斷這個(gè)系統(tǒng)進(jìn)程是否在虛函數(shù)調(diào)用點(diǎn)崩潰。如果這個(gè)系統(tǒng)進(jìn)程在虛函數(shù)調(diào)用點(diǎn)崩潰,得出一個(gè)漏洞驗(yàn)證的中間結(jié)果:漏洞存在且可能可利用,進(jìn)入步驟3。否則,得到最終的漏洞驗(yàn)證結(jié)果:漏洞存在但不可利用。
Android系統(tǒng)進(jìn)程是否在虛函數(shù)調(diào)用點(diǎn)崩潰的判斷方法是:如果崩潰日志中含有違反執(zhí)行約束的異常信息,并且崩潰地址位于堆緩沖區(qū)的內(nèi)存地址區(qū)間內(nèi),說(shuō)明系統(tǒng)進(jìn)程被錯(cuò)誤地引導(dǎo)到堆緩沖區(qū)去尋找虛函數(shù)表和函數(shù)指針并執(zhí)行相應(yīng)函數(shù),則認(rèn)為系統(tǒng)進(jìn)程是在虛函數(shù)調(diào)用點(diǎn)崩潰;否則不是。
其中,步驟3進(jìn)一步包括如下步驟:
步驟31,構(gòu)造一個(gè)緩沖區(qū)第三輸入樣本;所構(gòu)造的第三輸入樣本比緩沖區(qū)大小多四個(gè)字節(jié),包含四部分內(nèi)容:溢出值、偽造的虛函數(shù)表、偽造的函數(shù)以及填充數(shù)據(jù),如圖5所示。多出的該四個(gè)字節(jié)為溢出值,并且該值恰好是偽造的虛函數(shù)表在堆內(nèi)存空間中的起始地址,用來(lái)精確覆蓋堆中C++對(duì)象的虛函數(shù)表指針。
其中,偽造的虛函數(shù)表中含有一個(gè)偽造的函數(shù)指針,其值被設(shè)置為偽造的函數(shù)在堆內(nèi)存空間中的起始地址,用來(lái)誤導(dǎo)系統(tǒng)進(jìn)程調(diào)用相應(yīng)的虛函數(shù),執(zhí)行偽造的函數(shù)。其中,偽造的函數(shù)由多個(gè)匯編指令組成,實(shí)現(xiàn)了兩個(gè)功能:1,將堆緩沖區(qū)的內(nèi)存區(qū)域標(biāo)記為可執(zhí)行,允許系統(tǒng)進(jìn)程在堆緩沖區(qū)中執(zhí)行指令,避免違反執(zhí)行約束;2,實(shí)現(xiàn)一個(gè)顯式的功能,例如在Android文件系統(tǒng)/sdcard/目錄下創(chuàng)建新文件newfile.txt。其中,如果偽造的虛函數(shù)表和偽造的函數(shù)不是四字節(jié)對(duì)齊的,需要在其后放置填充數(shù)據(jù),以保證堆內(nèi)存空間的字節(jié)對(duì)齊。同時(shí),填充數(shù)據(jù)還需要保證所構(gòu)造的第三輸入樣本的大小比緩沖區(qū)大小多四個(gè)字節(jié)。
步驟32,向堆緩沖區(qū)填寫該第三輸入樣本,觸發(fā)堆緩沖區(qū)溢出;溢出后,C++對(duì)象的虛函數(shù)表指針將會(huì)被溢出值覆蓋,指向堆內(nèi)存空間中偽造的虛函數(shù)表;隨后系統(tǒng)進(jìn)程在調(diào)用虛函數(shù)時(shí),會(huì)根據(jù)被覆蓋的虛函數(shù)表指針找到偽造的虛函數(shù)表,然后被偽造的函數(shù)指針錯(cuò)誤地引導(dǎo)到偽造的函數(shù)處去執(zhí)行匯編指令。最后,通過(guò)查看顯式的功能是否 被執(zhí)行,來(lái)判斷Android系統(tǒng)的系統(tǒng)進(jìn)程是否執(zhí)行了偽造的函數(shù)。例如查看Android文件系統(tǒng)/sdcard/目錄下是否已創(chuàng)建了新文件newfile.txt。如果已執(zhí)行,說(shuō)明已成功利用這個(gè)堆溢出漏洞,得到漏洞驗(yàn)證結(jié)果:漏洞存在且可利用。否則,分析原因,重新構(gòu)造堆緩沖區(qū)輸入樣本。
最后,本申請(qǐng)的裝置和方法僅為較佳的實(shí)施方案,并非用于限定本發(fā)明的保護(hù)范圍。凡在本發(fā)明的精神和原則之內(nèi),所作的任何修改、等同替換、改進(jìn)等,均應(yīng)包含在本發(fā)明的保護(hù)范圍之內(nèi)。