教室停电h嗯啊好硬好湿,双性美人被调教到喷水a片,在按摩店和女老板做爰,狠狠挺进稚嫩学生小身体

數(shù)字經(jīng)濟(jì)的安全基石

首頁 > 關(guān)于我們 > 安恒動(dòng)態(tài) > 2020 > 正文

一個(gè)指針引發(fā)的“血案”

閱讀量:

腳本引擎開發(fā)者在設(shè)計(jì)GC(Garbage Collect,簡稱GC)時(shí)追蹤指針不善導(dǎo)致的UAF(Use-After-Free),是一類常見的漏洞。本文通過一個(gè)例子來向讀者介紹這類漏洞的成因與分析思路。

漏洞描述

CVE-2018-8353是谷歌的Ivan Fratric發(fā)現(xiàn)的一個(gè)jscript漏洞,該漏洞在2018年8月被修復(fù)。這是一個(gè)UAF漏洞,Ivan Fratric在披露頁清晰地描述了該漏洞的成因:

通俗一點(diǎn)說就是RegExp類的lastIndex成員沒有被加入GC追蹤列表,如果給它賦值,在GC時(shí)會(huì)導(dǎo)致lastIndex處存儲(chǔ)的指針變?yōu)閼掖怪羔槨:罄m(xù)再訪問lastIndex時(shí),即造成一個(gè)典型的Use-After-Free場景。

jscript模塊目前已發(fā)現(xiàn)多個(gè)類似漏洞,例如CVE-2017-11793,CVE-2017-11903,CVE-2018-0866,CVE-2018-0935,CVE-2018-8353,CVE-2018-8653,CVE-2018-8389,CVE-2019-1429

本文試圖通過CVE-2018-8353一窺這類漏洞的成因,并在此基礎(chǔ)上分析谷歌PoC中的信息泄露利用代碼。讀者將會(huì)看到一個(gè)GC導(dǎo)致的UAF如何被轉(zhuǎn)化為高質(zhì)量的信息泄露漏洞。

?

PoC

以下為Ivan Fratric給出的PoC,下一小節(jié)將通過該P(yáng)oC分析漏洞成因。

UAF

@0Patch團(tuán)隊(duì)已通過補(bǔ)丁分析發(fā)現(xiàn),x86下lastIndex位于RegExpObj對象的+A8偏移處,如下:

現(xiàn)在RegExpObj::Create函數(shù)內(nèi)下斷點(diǎn),在RegExpObj對象創(chuàng)建完成后,對其偏移+A8處下一個(gè)硬件寫入斷點(diǎn),這個(gè)偏移處存儲(chǔ)一個(gè)VAR結(jié)構(gòu)體,此結(jié)構(gòu)體在x86下大小為0x10。重點(diǎn)觀察+B0處的數(shù)據(jù)變化。

為了更清晰地解釋成因,筆者并沒有開啟頁堆,但開啟了用戶模式下堆申請的?;厮?,以下為調(diào)試日志:

重占位

到這里已經(jīng)獲得了一個(gè)非常好的UAF,接下來的問題是:如何使用它?

從調(diào)試日志中可以看出,用來存儲(chǔ)VAR變量的內(nèi)存塊是從GcBlockFactory::PblkAlloc申請的,x86下其申請大小固定為0x648(《Garbage Collection Internals of JScript》這篇文章有解釋為什么x86下這個(gè)大小是0x648):

如果要重用被釋放的內(nèi)存,得在GC后迅速用大小為0x648的內(nèi)存申請去占用之。如何做到?

一個(gè)比較好的方法是借助NameList。jscript對象在創(chuàng)建成員變量時(shí),如果成員變量的名稱過長(谷歌的文章中說這個(gè)長度閾值為4),會(huì)在NameList::FCreateVval函數(shù)內(nèi)單獨(dú)申請內(nèi)存,以存儲(chǔ)對應(yīng)的成員變量,并且會(huì)以第一個(gè)成員名稱的長度去申請?zhí)囟ù笮〉膬?nèi)存,而相關(guān)計(jì)算公式是固定的。

通過逆向調(diào)試,可以得到x86下的計(jì)算公式:

現(xiàn)在,令alloc_size=0x648,解上述方程,可得到x=0x178(0n376)。于是可以通過下面的代碼重用被釋放的內(nèi)存:

在調(diào)試器中觀察驗(yàn)證重用:

從UAF到信息泄露

前一小節(jié)已經(jīng)在合適的時(shí)機(jī)控制了被Free的內(nèi)存,接下來要哦那個(gè)過這個(gè)UAF漏洞實(shí)現(xiàn)信息泄露,以得到被重用內(nèi)存的起始地址。

NameList::FCreateVval點(diǎn)

NameList::FCreateVval函數(shù)內(nèi)在申請成員變量名內(nèi)存時(shí),若成員名長度超過一定值,就會(huì)額外申請內(nèi)存去存儲(chǔ)這些名稱。第一個(gè)成員名可以用來控制申請的內(nèi)存大小,相關(guān)計(jì)算過程已經(jīng)在前面說明。后面的成員名稱只要長度合適,就可以在第一個(gè)成員名稱初始化時(shí)申請的內(nèi)存中使用剩余的部分,從而用來布控內(nèi)存。

在x86環(huán)境下,通過逆向NameList::FCreateVval函數(shù),發(fā)現(xiàn)每個(gè)成員名稱前面會(huì)額外留0x30大小的空間作為頭部,用于初始化各種數(shù)據(jù)。每次成員名稱進(jìn)行申請時(shí),還會(huì)按照下圖的計(jì)算公式按4字節(jié)對齊并保存與返回相關(guān)偏移:

整個(gè)計(jì)算公式比較復(fù)雜,但設(shè)計(jì)思路很簡單,筆者在這里描述一遍,讀者大致了解即可:x86下,第一個(gè)成員名初始化時(shí),先申請(2x+0x32)*2+4的內(nèi)存大小,得到內(nèi)存后,最初的0x30作為頭部使用,用來初始化各種數(shù)據(jù),包括本次字符串長度,指向下一個(gè)成員名頭的指針(這個(gè)指針會(huì)后面的成員名初始化時(shí)被更新),然后因?yàn)槭堑谝粋€(gè)成員,按照公式直接加4字節(jié)進(jìn)行對齊,所以從前面的調(diào)試日志也可以看到,第一個(gè)成員名從+0x34開始被復(fù)制。只要第一次申請的內(nèi)存空間夠,第二個(gè)成員名按照base+offset+4的方式進(jìn)行內(nèi)存地址獲取,然后前0x30又是頭部,接著再開始復(fù)制,以此類推。

?

泄露被重用內(nèi)存首地址

接下來是泄露被重用內(nèi)存的首地址。

由于被重用的內(nèi)容之前存儲(chǔ)著lastIndex引用的VAR數(shù)據(jù),所以只要用長度及內(nèi)容合適的字符串設(shè)計(jì)類成員名稱,就可以控制指定地址處的VAR結(jié)構(gòu)。

從這里開始,使用Ivan Fratric在附件中給出的infoleak.html代碼,為便于展示,去除了部分注釋:

name1用來申請大小為0x648的內(nèi)存。name2可調(diào)節(jié),用來對齊。name3用來指定類型,以泄露特定偏移處的一個(gè)指針,這個(gè)后面再會(huì)提及。name4用來布控0x1337對應(yīng)的VAR,用于jscript代碼中的條件判斷。

上面的小節(jié)中只關(guān)心了name1,現(xiàn)在開始來具體設(shè)計(jì)name4,name3,name2。

  • 鎖定偏移值

首先得計(jì)算垂懸指針指向的VAR結(jié)構(gòu)在被重用內(nèi)存的偏移值。Ivan Fratric的適配的是x64的版本,原poc在筆者的環(huán)境中運(yùn)行后0x1337對應(yīng)的i為十進(jìn)制的115。

x64與x86的原理一致,以x86的版本進(jìn)行說明。既然x64環(huán)境中對應(yīng)的i為115。x32環(huán)境中,也以115為例進(jìn)行偏移計(jì)算。在上述代碼中在第115個(gè)RegExpObj對象創(chuàng)建時(shí)下斷點(diǎn),相關(guān)方法在前面UAF小結(jié)已經(jīng)描述,這個(gè)偏移很容易計(jì)算得到。

筆者的環(huán)境中這個(gè)偏移每次固定為0x3d8,如下:

  • 設(shè)計(jì)name

現(xiàn)在來設(shè)計(jì)name,在每個(gè)成員名稱初始化時(shí),都會(huì)有0x30的頭部,在這個(gè)頭部的+0x24處是一個(gè)指針(這個(gè)指針要到初始化下一個(gè)成員名時(shí)才會(huì)被初始化),指向下一個(gè)變量名的0x30頭部,下圖中字體為紅色的即為這些指針。如果能讀取其中一個(gè)指針,減去其相對內(nèi)存起始地址的偏移,就可以得到被重用內(nèi)存的首地址。

下圖中字體顏色為橙黃的是被拷貝的成員名稱,每個(gè)名稱最后會(huì)多拷貝兩個(gè)0x00。字體顏色為藍(lán)色的是每個(gè)成員名稱的實(shí)際長度(轉(zhuǎn)化為unicode后的長度)。字體顏色為紅色上面已經(jīng)進(jìn)行解釋。字體背景為灰色的一個(gè)個(gè)0x30內(nèi)存區(qū)域?yàn)閚ame2、name3、name4三個(gè)成員名的頭部。

字體背景為黃色高亮的區(qū)域,實(shí)驗(yàn)時(shí)發(fā)現(xiàn)會(huì)與name3的值相同(意思就是給3得3,給5得5)。后面需要借助這個(gè)值來讀取它后面偏移8字節(jié)的一個(gè)紅色指針。

  • 最后一個(gè)注意點(diǎn)

因?yàn)橐孤赌硞€(gè)紅色指針,所以x86下必須保證這個(gè)紅色指針之前8字節(jié)處的type為long型,這可以通過設(shè)計(jì)name3來實(shí)現(xiàn)?,F(xiàn)在的問題是:VAR與某個(gè)特定的lastIndex對應(yīng)起來?

幸運(yùn)的是,通過調(diào)試觀察發(fā)現(xiàn),當(dāng)連續(xù)申請VAR結(jié)構(gòu)時(shí),一個(gè)個(gè)大小為0x10的VAR似乎是從高內(nèi)存往低內(nèi)存次第排列。筆者用下圖來通俗地解釋一下VAR的分布(name2中b的數(shù)量被用來調(diào)節(jié)這里的對齊):

所以,在x86下,如果找到了0x1337對應(yīng)的regexps[i].lastIndex,就可以通過讀取regexps[i+5].lastIndex來泄露相關(guān)指針,減去固定偏移就得到被重用內(nèi)存的起始地址了。如下:

到這里已經(jīng)將這個(gè)UAF漏洞轉(zhuǎn)為了信息泄露,泄露出一塊(aaa...部分)完全可控的內(nèi)存的首地址。如果讀者之前看過筆者之前的一篇文章,就會(huì)明白這里已經(jīng)將CVE-2018-8353轉(zhuǎn)換為和CVE-2017-11906具有相同功能的信息泄露漏洞。

?

從信息泄露到RCE

此類信息泄露漏洞與其他堆溢出漏洞一起使用可以實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行。筆者將這個(gè)漏洞的利用代碼稍加改動(dòng),并配合CVE-2017-11907一起使用,可以在未打補(bǔ)丁的機(jī)器上完成概念驗(yàn)證。

考慮到CVE-2018-8653或CVE-2019-1429這類在野0day的利用方式,應(yīng)該是用了更高級的利用手法,通過UAF直接實(shí)現(xiàn)了任意地址讀寫,通過單個(gè)UAF即可實(shí)現(xiàn)遠(yuǎn)程代碼執(zhí)行,并不需要其他漏洞進(jìn)行輔助。

此類UAF漏洞后面一定還會(huì)出現(xiàn),請大家做好防范工作。

?

參考文章

Issue 1587: Windows: use-after-free in JScript in RegExp.lastIndex

Garbage Collection Internals of JScript

關(guān)閉

客服在線咨詢?nèi)肟冢诖c您交流

線上咨詢
聯(lián)系我們

咨詢電話:400-6059-110

產(chǎn)品試用

即刻預(yù)約免費(fèi)試用,我們將在24小時(shí)內(nèi)聯(lián)系您

微信咨詢
安恒信息聯(lián)系方式
成人电影在线免费观看| 最近国语视频在线观看免费播放| 小sao货cao得你舒服吗男男| 蜜臀av无码精品人妻色欲| 无码精品国产av在线观看| 亚洲av成人无码网天堂| 十大免费软件不收费软件| 小荡货女友h调教| 久久精品亚洲av无码乱码三区| 久久精品国产亚洲av麻豆色欲| 波多野结衣456| 久久久久久av无码免费网站下载| 国产毛a片啊久久久久久保和丸| 日本黄色视频| 日日噜噜噜噜夜夜爽亚洲精品| 欧美mv日韩mv国产网站| 欧美熟妇vivoe精品| 国产伦精品一区二区三区| 与80岁老太做爰a片免费看| 狠狠在啪线香蕉777视频| 亚洲人成色777777在线观看| 亚洲看片lutube在线观看| 人妻被按摩师玩弄到潮喷| 精品无人区无码乱码毛片国产| 精品人妻少妇嫩草av无码专区| 精跪趴灌满白浊共妻np老师学生| 国产精品久久久久久亚洲av| 伸进内衣揉捏她的乳尖视频| 门卫老李干了校花琦琦| 人鲁交yazhonghucxx| 公交车强摁做开腿呻吟h视频| 无码精品人妻一区二区三区影院| 24小时在线看免费观看直播| 7777久久亚洲中文字幕| 一次灌浆与二次灌浆| 公车系强女奷校花雪柔| 欧美熟妇dodk巨大| 年轻又漂亮的后妈2| 无码精品国产av在线观看| 欧美猛交xxx无码黑寡妇| 调教女m屁股撅虐调教|