操屁眼的视频在线免费看,日本在线综合一区二区,久久在线观看免费视频,欧美日韩精品久久综

新聞資訊

    家都知道,咱大宋有一堵非常礙人的“墻”,當(dāng)你想要科學(xué)上網(wǎng)的時(shí)候,常常會(huì)想到網(wǎng)上找免費(fèi)的代理網(wǎng)站,但是免費(fèi)的代理網(wǎng)站,網(wǎng)速慢得那是相當(dāng)?shù)母腥耍绻氵@時(shí)候再打開一個(gè)國(guó)內(nèi)的網(wǎng)站,同樣你會(huì)感受到一股深深的惡意,因?yàn)槟銙炝舜怼?br>

    掛了代理訪問國(guó)內(nèi)的網(wǎng)站,同樣也會(huì)去代理服務(wù)器上繞一圈回來,這一點(diǎn)確實(shí)很不科學(xué),要是可以自動(dòng)過濾一些網(wǎng)站不過代理服務(wù)器,不就可以解決這個(gè)問題了。所以,今天給大家介紹這個(gè)神器——PAC文件。PAC文件的全稱是Proxy auto-config,也就是自動(dòng)配置代理的意思,它的核心就是一個(gè)函數(shù)“FindProxyForURL(url, host)”,輸入一個(gè)要訪問的url和它的域名,則返回一個(gè)或者多個(gè)代理服務(wù)器的地址,也可以返回一個(gè)命令,告訴瀏覽器不用代理訪問該url。

    有了這個(gè)文件后,就不用在訪問被墻的網(wǎng)站和其它網(wǎng)站的時(shí)候,手動(dòng)來回切換代理。可是有那么多被GFW干掉的網(wǎng)站,不可能我們自己一個(gè)一個(gè)添加進(jìn)這個(gè)PAC文件。這時(shí)候中國(guó)人多力量大就體現(xiàn)出來了,大家都有這個(gè)需要,于是就有一個(gè)公共的列表(著名的GFW List),訪問名單中網(wǎng)站需要通過代理,不在名單中的網(wǎng)站直接訪問,在遇到新的無法訪問的網(wǎng)站時(shí),就會(huì)有人去完善這個(gè)列表,然后受益于大家。

    還有一種情況,很多公司老板不想看到員工整天刷微博逛淘寶,下令要禁掉這些網(wǎng)站,于是網(wǎng)絡(luò)管理員直接弄一個(gè)代理服務(wù)器中轉(zhuǎn),配置一個(gè)PAC文件,來控制一些允許訪問的網(wǎng)站通過公司的代理服務(wù)器訪問,其余的就打不開了,從而達(dá)到控制訪問的目的。如果你也有被阻止訪問的網(wǎng)站,那么把PAC文件下載到本地,增加一條后引用本地文件,然后你懂的: P

    引子

    從20/20事后來看,許多廣泛部署的技術(shù)似乎是一種奇怪或不必要的冒極大風(fēng)險(xiǎn)的想法。IT工程決策往往是由信息不完善和時(shí)間壓力造成的,而IT系統(tǒng)中的一些古怪問題最好用“當(dāng)時(shí)看來是個(gè)好主意”來解釋。在這篇文章的作者個(gè)人觀點(diǎn)中,WPAD(“WebProxy Auto Discovery Protocol” --更具體地說是“Proxy Auto-Config”)是這些怪異之一。

    在互聯(lián)網(wǎng)早些時(shí)候 - 1996年以前,Netscape的工程師認(rèn)為JavaScript是編寫配置文件的好語言。這就產(chǎn)生了PAC--一種配置文件格式,其工作原理如下:瀏覽器連接到預(yù)先配置的服務(wù)器,下載PAC文件,并執(zhí)行特定的JavaScript函數(shù)以確定完整的代理配置。為什么不呢?它確實(shí)比XML(比方說)更具表現(xiàn)力和詳細(xì),而且似乎是向許多客戶提供配置的合理方式。

    PAC本身伴隨了一個(gè)名為WPAD的協(xié)議 --一個(gè)協(xié)議,使得瀏覽器不需要預(yù)先配置的服務(wù)器來連接。相反,WPAD允許計(jì)算機(jī)查詢本地網(wǎng)絡(luò)以確定加載PAC文件的服務(wù)器。

    不知何故,這項(xiàng)技術(shù)最終成為1999年到期的IETF草案,現(xiàn)在,在2017年,每臺(tái)Windows機(jī)器都會(huì)詢問本地網(wǎng)絡(luò):“嘿,我在哪里可以找到一個(gè)Javascript文件來執(zhí)行?”。這可以通過多種機(jī)制來現(xiàn):DNS,WINS,但也許最有趣的是DHCP。

    近年來,瀏覽器的攻擊已經(jīng)從主要面向DOM的方向發(fā)展到直接面向Javascript引擎,所以只要我們可以在沒有瀏覽器的情況下通過網(wǎng)絡(luò)來執(zhí)行Javascript執(zhí)行就是激動(dòng)人心的。最初調(diào)查顯示,JS引擎負(fù)責(zé)執(zhí)行這些配置文件是JSCRIPT.DLL - JS引擎也支持IE7和IE8(如果使用適當(dāng)?shù)哪_本屬性,仍然可以在IE11在IE7 / 8兼容模式中使用)。這有好有壞 -- 一方面,這意味著并不是每一個(gè)Chakra bug自動(dòng)成為本地網(wǎng)絡(luò)的遠(yuǎn)程攻擊,但另一方面,這意味著一些很老的代碼將負(fù)責(zé)執(zhí)行我們的JavaScript。

    安全研究人員之前曾警告WPAD的危險(xiǎn)。 但就我們所知,這是第一次發(fā)現(xiàn)對(duì)WPAD的攻擊,結(jié)果導(dǎo)致使用WPAD用戶機(jī)器的完全破壞。

    Windows并不是實(shí)現(xiàn)WPAD的唯一系統(tǒng),其他操作系統(tǒng)和應(yīng)用程序也是如此。例如Google Chrome也有一個(gè)WPAD實(shí)現(xiàn),但在Chrome中,評(píng)估來自PAC文件的JavaScript代碼發(fā)生在一個(gè)沙箱內(nèi)。而其他支持WPAD的操作系統(tǒng)默認(rèn)不啟用它。這就是為什么Windows是目前這種攻擊最有趣的目標(biāo)。

    Web Proxy Auto-Discovery

    如上所述,WPAD將查詢DHCP和DNS(按此順序)以獲取要連接的URL -- 如果沒有可用的DNS響應(yīng),顯然LLMNR和Netbios也可以使用。WPAD-over-DNS的一些特性使得攻擊向量能夠出人意料地發(fā)揮作用。

    攻擊場(chǎng)景:通過DHCP的本地網(wǎng)絡(luò)

    在最常見的情況下,一臺(tái)機(jī)器將使用選項(xiàng)碼252查詢本地DHCP服務(wù)器.DHCP服務(wù)器回復(fù)一個(gè)字符串-- 比如“http://server.domain/proxyconfig.pac”,它指定一個(gè)配置文件的URL。 然后客戶端繼續(xù)獲取這個(gè)文件,并將內(nèi)容作為Javascript執(zhí)行。

    在本地網(wǎng)絡(luò)中,攻擊者可以簡(jiǎn)單地模仿DHCP服務(wù)器 -- 可以通過ARP游戲或通過合法DHCP進(jìn)行競(jìng)爭(zhēng)。然后,攻擊者可以提供一個(gè)惡意JavaScript文件所在的URL。

    攻擊場(chǎng)景:通過特權(quán)地位和DNS進(jìn)行遠(yuǎn)程攻擊

    除了本地網(wǎng)絡(luò)攻擊場(chǎng)景,WPAD查找也可能通過DNS發(fā)生的事實(shí)會(huì)產(chǎn)生一個(gè)輔助攻擊場(chǎng)景。許多用戶將他們的計(jì)算機(jī)配置為針對(duì)公共的,全局可見的DNS服務(wù)器(如8.8.8.8, 8.8.4.4, 208.67.222.222和208.67.220.220)來執(zhí)行DNS查找。 在這種情況下,一臺(tái)機(jī)器會(huì)發(fā)送DNS查詢(如wpad.local)到位于本地網(wǎng)絡(luò)之外的服務(wù)器。 處于網(wǎng)絡(luò)特權(quán)位置的攻擊者(例如網(wǎng)關(guān)或任何其他上游主機(jī))可以監(jiān)視DNS查詢并偽造應(yīng)答,指示客戶端下載并執(zhí)行惡意的JavaScript文件。

    像這些設(shè)置似乎是常見的 - 根據(jù)這個(gè)維基百科條目,DNS根服務(wù)器流量的一小部分是本地請(qǐng)求。

    攻擊場(chǎng)景:通過惡意的wpad.tld遠(yuǎn)程攻擊

    WPAD的特殊之處在于遞歸地遍歷本地機(jī)器名稱以查找要查詢的域。如果一臺(tái)機(jī)器被稱為“l(fā)aptop01.us.division.company.com”,則按照以下方式查詢以下域名:

    1.wpad.us.division.company.com

    2.wpad.division.company.com

    3.wpad.company.com

    4.wpad.com

    這(根據(jù)這個(gè)維基百科條目)導(dǎo)致人們注冊(cè)wpad.co.uk并將流量重定向到在線拍賣網(wǎng)站。進(jìn)一步引用該條目:

    通過WPAD文件,攻擊者可以將用戶的瀏覽器指向自己的代理,攔截并修改所有的http流量。盡管2005年對(duì)WindowsWPAD處理進(jìn)行了簡(jiǎn)單的修復(fù),但它只解決了.com域的問題。在Kiwicon的一次演講顯示,世界其他地區(qū)仍然受到這個(gè)安全漏洞的嚴(yán)重威脅,為測(cè)試,我們?cè)谛挛魈m注冊(cè)一個(gè)樣本域,接收來自全國(guó)各地的代理請(qǐng)求,幾秒鐘就接受到大量的請(qǐng)求。一些wpad.tld域名(包括COM,NET,ORG和US)現(xiàn)今會(huì)指向客戶端回送地址,以防止此漏洞,盡管有些名稱仍然是注冊(cè)的(wpad.co.uk)。

    因此,管理員應(yīng)確保用戶可以信任網(wǎng)絡(luò)中中的所有DHCP服務(wù)器,并且網(wǎng)絡(luò)中所有可能的wpad域都受到控制。此外,如果沒有為網(wǎng)絡(luò)配置wpad域,則用戶將轉(zhuǎn)到外部位置的具有域?qū)哟谓Y(jié)構(gòu)中下一個(gè)wpad站點(diǎn),并將其用于配置。這就允許攻擊者在某個(gè)特定的國(guó)家注冊(cè)wpad子域名,通過將自己設(shè)置為所有流量感興趣站點(diǎn)的代理,對(duì)該國(guó)的大部分互聯(lián)網(wǎng)流量進(jìn)行中間人攻擊。

    另一方面,IETF草案明確要求客戶只允許“典型域”(例如非頂級(jí)域名)。我們還沒有調(diào)查客戶在什么程度上實(shí)施這個(gè),或者二級(jí)域名(如.co.uk)是否是流量重定向案例的罪魁禍?zhǔn)住?/p>

    無論哪種方式:如果某個(gè)特定組織的頂級(jí)域名(TLD)注冊(cè)了$ TLD,只要該頂級(jí)域名(TLD)未被客戶端明確列入黑名單,就可以通過互聯(lián)網(wǎng)遠(yuǎn)程利用Javascript引擎中的bug。 鑒于1999年的IETF草案提到了1994年的TLD列表(RFC1591),客戶不太可能已經(jīng)更新了最新的TLD。

    Bugs

    我們花了一些時(shí)間采用手動(dòng)分析和fuzz尋找jscript.dll中的bug。 Jscript存在著一些挑戰(zhàn),因?yàn)楹芏嘤糜谟|發(fā)JavaScript引擎中的bug的“特性”不能在JScript中使用,只是由于它太舊而無法支持它們。例如:

    沒有多個(gè)數(shù)組類型(int數(shù)組,float數(shù)組等)。因此混淆一個(gè)數(shù)組類型是不可能的。

    沒有像更新,更快的JavaScript引擎那樣的優(yōu)化(“fast path”)。這些fast path往往是bug的來源。

    在通用JavaScript對(duì)象上定義getter / setter是不可能的。可以調(diào)用defineProperty,但只能調(diào)用不適合我們的DOM對(duì)象,因?yàn)樵赪PAD過程中不會(huì)有DOM。即使存在,當(dāng)調(diào)用一個(gè)帶有“JScript object expected”消息的DOM對(duì)象時(shí),很多JScript函數(shù)也會(huì)失敗。

    不可能改變已經(jīng)創(chuàng)建對(duì)象的原型(即沒有“__proto__”屬性)。

    但是,JScript確實(shí)有很多的“老派”漏洞,比如UAF。 JScript的垃圾回收器在這個(gè)老的MSDN文章中有描述。 JScript使用非世代的標(biāo)記和清理垃圾收集器。從本質(zhì)上講,無論何時(shí)垃圾收集被觸發(fā),它都會(huì)標(biāo)記所有的JScript對(duì)象。然后從一組“根”對(duì)象(有時(shí)也稱為“清道夫”)開始掃描它們,并從所遇到的所有對(duì)象中清除標(biāo)記。所有仍被標(biāo)記的對(duì)象都被刪除。一個(gè)反復(fù)出現(xiàn)的問題是默認(rèn)情況下,堆棧上的局部變量不會(huì)被添加到根對(duì)象列表中,這意味著程序員需要記住將它們添加到垃圾回收器的根列表中,特別是如果這些變量引用可以在函數(shù)生命周期中被刪除。

    其他可能的漏洞類型包括緩沖區(qū)溢出,未初始化的變量等。

    為了fuzzing,我們使用了基于語法的Domato fuzz引擎,并專門為JScript寫了一個(gè)新的語法。我們通過查看各種JScript對(duì)象的EnsureBuiltin方法來識(shí)別有趣的內(nèi)置屬性和函數(shù),以添加到語法中。 JScript語法已經(jīng)被添加到這里的Domato倉庫中。

    通過fuzz和手動(dòng)分析,我們確定了七個(gè)安全漏洞。它們總結(jié)在下表中:

    在這篇博文發(fā)布之前,所有以上的漏洞都已經(jīng)唄微軟所修復(fù)。

    該表中的漏洞通過觸發(fā)它們所需的類和兼容模式來觸發(fā)。WPAD中的JScript相當(dāng)于在IE7兼容模式下運(yùn)行腳本,這意味著盡管我們發(fā)現(xiàn)了7個(gè)漏洞,但WPAD中只能觸發(fā)5個(gè)。但是,其他漏洞仍然可以在Internet ExplorerIE8兼容模式下被惡意網(wǎng)頁使用(包括IE11)。

    利用

    理解Jscript的變量和字符串

    在這篇博文的其余部分中,我們將討論JScript VAR和Strings,在深入探討漏洞的工作方式之前,先描述這些內(nèi)容是非常有用的。

    JScript VAR是一個(gè)24字節(jié)(在64位版本上)的結(jié)構(gòu),表示一個(gè)JavaScript變量,并且與MSDN文章中描述的VARIANT數(shù)據(jù)結(jié)構(gòu)基本相同。在大多數(shù)情況下(足以跟蹤漏洞)其內(nèi)存布局如下所示:

    例如,我們可以通過將5寫入前2個(gè)字節(jié)(表示雙重類型)的VAR表示雙精度數(shù),后在偏移8跟一個(gè)實(shí)際的雙精度值.最后8個(gè)字節(jié)將是未使用的,但它們?nèi)绻麖倪@個(gè)VAR復(fù)制另一個(gè)VAR的值,將被復(fù)制。

    JScript字符串是一種類型為8,偏移量8處為指針的VAR。指針指向這里描述的BSTR結(jié)構(gòu)。在64位構(gòu)建BSTR布局看起來像這樣:

    一個(gè)字符串VAR直接指向字符數(shù)組,這意味著,要獲得一個(gè)字符串的長(zhǎng)度,指針需要減少4,并從那里讀取長(zhǎng)度。請(qǐng)注意,BSTR由OleAut32.dll處理,并分配在一個(gè)單獨(dú)的堆上(即與其他JScript對(duì)象不同的堆)。

    BSTR的釋放也不同于大多數(shù)對(duì)象,并不是直接釋放BSTR,而是在調(diào)用SysFreeString時(shí),它首先將一個(gè)字符串放入由OleAut32.dll控制的緩存中。 這個(gè)機(jī)制在JavaScript的堆風(fēng)水(原文HeapFeng Shui)中有詳細(xì)的介紹。

    階段1:信息泄露

    infoleak的目的是獲得我們完全控制的字符串的內(nèi)存地址。此時(shí)我們不會(huì)泄露任何可執(zhí)行的模塊地址,這將在稍后進(jìn)行。相反,其目標(biāo)是挫敗高熵堆的隨機(jī)化,使第二階段的利用可靠,而不必使用堆噴射。

    對(duì)于infoleak,我們要在RegExp.lastParen中使用這個(gè)bug。為了理解這個(gè)bug,我們先來仔細(xì)看看jscript!RegExpFncObj的內(nèi)存布局,它對(duì)應(yīng)于JScript RegExp對(duì)象。在偏移量0xAC處,RegExpFncObj包含20個(gè)整數(shù)的緩沖區(qū)。實(shí)際上這些是10對(duì)整數(shù):第一個(gè)元素是輸入字符串的起始索引,第二個(gè)元素是結(jié)束索引。只要RegExp.test,RegExp.exec 或帶有RegExp參數(shù)的String.search遇到捕獲組(RegExp語法中的圓括號(hào)),匹配到的開始和結(jié)束索引就會(huì)存儲(chǔ)在這里。顯然在緩沖區(qū)中只有10個(gè)匹配的空間,所以只有前10個(gè)匹配組被存儲(chǔ)在這個(gè)緩沖區(qū)中。

    但是,如果RegExp.lastParen被調(diào)用,并且有超過10個(gè)捕獲組,RegExpFncObj :: LastParen會(huì)很高興地使用捕獲組的數(shù)量作為索引進(jìn)入緩沖區(qū),導(dǎo)致越界讀取。這是一個(gè)PoC:

    var r=new RegExp(Array(100).join('()'));

    ''.search(r);

    alert(RegExp.lastParen);

    這兩個(gè)索引(我們稱之為start_index和end_index)是在緩沖區(qū)邊界之外讀取的,因此可以任意大。假設(shè)這第一次越界訪問不會(huì)導(dǎo)致崩潰,如果這些索引中的值大于輸入字符串的長(zhǎng)度,那么將發(fā)生第二次越界訪問,這允許我們讀取輸入字符串的邊界之外的數(shù)據(jù)。像這樣越界讀取的字符串內(nèi)容會(huì)返回給調(diào)用者一個(gè)可被檢查的字符串變量。

    我們要使用的是第二次越界讀取,但首先我們需要弄清楚如何將受控?cái)?shù)據(jù)寫入start_index和end_index。幸運(yùn)的是,查看RegExpFncObj的布局,在索引緩沖區(qū)結(jié)束后就是我們控制的數(shù)據(jù):RegExp.input值。通過將RegExp.input設(shè)置為整數(shù)值并使用由41組空括號(hào)組成的RegExp,當(dāng)調(diào)用RegExp.lastParen時(shí),start_index將為0,end_index將為我們寫入RegExp.input的任何值。

    如果我們把一個(gè)輸入字符串與一個(gè)被釋放的字符串相鄰,那么通過在輸入字符串的邊界之后讀取,我們可以獲得堆的元數(shù)據(jù),例如指向其他空閑堆段的指針(在紅黑色中的Left,Right和Parent節(jié)點(diǎn)堆的樹塊,請(qǐng)參閱Windows10 Segment堆內(nèi)部了解更多信息)。圖1顯示了infoleak時(shí)的相關(guān)對(duì)象。

    我們使用20000字節(jié)長(zhǎng)的字符串作為輸入,以便它們不會(huì)分配到低碎片堆(LFH只能用于16K字節(jié)或更小的分配),因?yàn)長(zhǎng)FH堆的元數(shù)據(jù)是不同的,并且不包括Windows 10 Segment堆中有用的指針。此外,LFH引入了隨機(jī)性,這會(huì)干擾我們將輸入字符串放在釋放字符串旁邊的操作。

    通過從返回字符串讀取堆中的元數(shù)據(jù),我們可以獲得一個(gè)釋放字符串的地址。那么,如果我們分配一個(gè)與被釋放字符串大小相同的字符串,它就可以被放置在這個(gè)地址。我們實(shí)現(xiàn)了我們的目標(biāo),那就是我們知道一個(gè)內(nèi)容由我們控制的字符串的內(nèi)存地址。

    整個(gè)infoleak過程如下所示:

    分配1000個(gè)10000字符的字符串(注意:10000個(gè)字符==20000字節(jié))。

    釋放2,4,6字符串……

    觸發(fā)信息泄漏錯(cuò)誤。使用剩余的字符串之一作為輸入字符串并讀取20080字節(jié)。

    分析泄漏的字符串并獲取指向一個(gè)釋放字符串的指針。

    分配與釋放的字符串(10000個(gè)字符)長(zhǎng)度相同的特定內(nèi)容的500個(gè)字符串。

    特制字符串內(nèi)容在這個(gè)階段并不重要,但在下一個(gè)階段是重要的,所以在這里不會(huì)描述。另外請(qǐng)注意,通過檢查堆元數(shù)據(jù),我們可以輕松地確定進(jìn)程正在使用的堆(Segment Heap vs NT Heap)。

    圖2和圖3顯示了在infoleak時(shí)使用Heap History Viewer創(chuàng)建的堆可視化圖像。綠色條紋表示分配的塊(被字符串占據(jù)),灰色條紋表示分配的塊被釋放,然后再次被分配(字符串釋放并在觸發(fā)infoleak bug后被重新分配)白色條紋表示從未分配的數(shù)據(jù)(保護(hù)頁)。你可以看到隨著時(shí)間的推移字符串是如何分配的,一半被釋放(灰色的),一段時(shí)間后又被分配(條紋變成綠色)。

    我們可以看到每隔3次分配這個(gè)大小后就會(huì)有一個(gè)保護(hù)頁。我們的漏洞從來沒有實(shí)際觸及任何這些保護(hù)頁(它讀取的字符串末尾的數(shù)據(jù)太少,以至于不會(huì)發(fā)生這種情況),但在這種情況下,在輸入字符串之后不會(huì)有空閑字符串infoleak,所以預(yù)期的堆元數(shù)據(jù)將會(huì)丟失。但是,我們可以很容易地檢測(cè)到這種情況,并使用另一個(gè)輸入字符串觸發(fā)infoleak bug,或者悄悄地中止exploit(注意:到目前為止我們沒有觸發(fā)任何內(nèi)存損壞)。

    Image 2: Heap Diagram: Showing the evolution ofthe heap over time

    Image 3: Step-by-step illustration ofleaking a pointer to a string.

    階段2:溢出

    在攻擊的第二階段,我們將使用Array.sort中的堆溢出bug。如果輸入數(shù)組中的元素?cái)?shù)量大于Array.length / 2,則JsArrayStringHeapSort(如果未指定比較函數(shù),則由Array.sort調(diào)用)將分配一個(gè)相同大小的臨時(shí)緩沖區(qū)(注意:可以小于array.lenght)。然后嘗試從0到Array.length索引檢索相應(yīng)的元素,如果該元素存在,則將其添加到緩沖區(qū)并轉(zhuǎn)換為字符串。如果數(shù)組在JsArrayStringHeapSort的生命周期中沒有改變,這將工作正常。但是,JsArrayStringHeapSort將數(shù)組元素轉(zhuǎn)換為可以觸發(fā)toString()回調(diào)的字符串。如果在其中一個(gè)toString()回調(diào)元素被添加到未定義的數(shù)組中,將發(fā)生溢出。

    為了更好地理解這個(gè)bug及其可利用性,我們來仔細(xì)看看溢出的緩沖區(qū)的結(jié)構(gòu)。已經(jīng)提到過,數(shù)組的大小與當(dāng)前在輸入數(shù)組中的元素的數(shù)量相同(確切地說,它將是元素的數(shù)量+1)。數(shù)組中的每個(gè)元素的大小都是48字節(jié)(64位版本),結(jié)構(gòu)如下:

    在JsArrayStringHeapSort期間,index

    1.?dāng)?shù)組元素被讀入偏移量為16的VAR

    2.原始的VAR被轉(zhuǎn)換成一個(gè)字符串VAR。指向字符串VAR的指針寫在偏移量0處。

    3.在偏移8處,寫入數(shù)組中當(dāng)前元素的索引

    4.根據(jù)原始的VAR類型,在偏移量40寫0或1

    觀察臨時(shí)緩沖區(qū)的結(jié)構(gòu),我們不能直接控制很多細(xì)節(jié)。如果一個(gè)數(shù)組成員是一個(gè)字符串,那么在偏移量為0和24時(shí),我們將會(huì)有一個(gè)指針,當(dāng)它被取消引用時(shí),偏移量為8的指針包含另一個(gè)指向由我們控制的數(shù)據(jù)的指針。然而,這是一個(gè)間接的在大多數(shù)情況下對(duì)我們有用的大方向。

    然而,如果數(shù)組的成員是一個(gè)雙精度數(shù),則在偏移24(對(duì)應(yīng)于偏移量8原始VAR),該數(shù)的值將直接被寫入,并且是我們的控制之下。如果我們創(chuàng)建具有相同代表double的如在階段1中獲得的指針的數(shù),那么我們可以溢出覆蓋指向緩沖區(qū)之外的指針為指向我們直接控制內(nèi)存中。

    現(xiàn)在問題變成了,我們?cè)摪凑者@樣的方式覆蓋什么指針來利用。如果我們仔細(xì)研究一下對(duì)象如何在JScript中工作那么就會(huì)發(fā)現(xiàn)一個(gè)可能的答案。

    每個(gè)對(duì)象(更具體地說,一個(gè)NameList的JScript對(duì)象)將有一個(gè)指向哈希表的指針。這個(gè)哈希表是一個(gè)指針數(shù)組。當(dāng)一個(gè)對(duì)象的成員元素被訪問時(shí),先計(jì)算元素名稱的hash。然后取消對(duì)應(yīng)于哈希最低位偏移處的指針。這個(gè)指針指向一個(gè)對(duì)象元素的鏈表,然后這個(gè)鏈表被遍歷,直到我們到達(dá)一個(gè)與請(qǐng)求元素具有相同名字的元素。這在圖4中顯示。

    Image 4: JScript 內(nèi)部對(duì)象元素

    請(qǐng)注意,當(dāng)元素的名稱少于4個(gè)字節(jié)時(shí),它將存儲(chǔ)在與VAR(元素值)相同的結(jié)構(gòu)中。否則,將會(huì)有一個(gè)指向元素名稱的指針。名稱長(zhǎng)度<=4對(duì)于我們來說已經(jīng)足夠了,所以我們不需要深入了解這個(gè)細(xì)節(jié)。

    一個(gè)對(duì)象散列表是一個(gè)很好的覆蓋候選,因?yàn)椋?/p>

    我們可以通過訪問相應(yīng)的對(duì)象成員來控制哪些元素被取笑引用。我們用不受控制的數(shù)據(jù)覆蓋的元素將永遠(yuǎn)不會(huì)被訪問。

    通過控制相應(yīng)對(duì)象的成員個(gè)數(shù),我們對(duì)散列表大小有著有限控制。例如,散列表以1024字節(jié)開始,但如果我們向?qū)ο筇砑映^512個(gè)元素,散列表將被重新分配為8192個(gè)字節(jié)。

    通過用指向控制數(shù)據(jù)的指針覆蓋散列表指針,我們可以在控制數(shù)據(jù)中創(chuàng)建假的JScript變量,并通過訪問相應(yīng)的對(duì)象成員來訪問它們。

    要可靠地進(jìn)行覆蓋,我們執(zhí)行以下操作:

    分配和釋放大量大小為8192的內(nèi)存塊.這將打開Low Fragmentation Heap使得分配大小為8192。這將確保我們溢出的緩沖區(qū),以及我們溢出的散列表將被分配LFH。這一點(diǎn)很重要,因?yàn)檫@意味著附近不會(huì)有其他大小的分配來破壞漏洞攻擊(因?yàn)長(zhǎng)FH只能包含特定大小的分配)。這反過來確保我們將高度可靠地覆蓋我們想要的東西。

    創(chuàng)建2000個(gè)對(duì)象,每個(gè)對(duì)象包含512個(gè)成員。在這種狀態(tài)下,每個(gè)對(duì)象都有一個(gè)1024字節(jié)的散列表。但是,向其中一個(gè)對(duì)象添加一個(gè)元素將導(dǎo)致其散列表增長(zhǎng)到8192個(gè)字節(jié)。

    將513元素添加到前1000個(gè)對(duì)象中,導(dǎo)致1000個(gè)8192字節(jié)哈希表的分配。使用長(zhǎng)度為300和170個(gè)元素的數(shù)組觸發(fā)Array.sort。這將分配一個(gè)大小為(170 + 1)* 48=8208字節(jié)的緩沖區(qū)。由于LFH的粒度,這個(gè)對(duì)象將被分配在與8192字節(jié)哈希表相同的LFH中。

    立即(在第一個(gè)數(shù)組元素的toString()方法中)向第二個(gè)1000對(duì)象添加第513個(gè)元素。這使得我們非常確定現(xiàn)在排序緩沖區(qū)是相鄰的哈希表之一。在相同的toString()方法中也向數(shù)組中添加更多的元素,這會(huì)導(dǎo)致它超出邊界。

    圖5顯示了排序緩沖區(qū)地址時(shí)的堆可視化(紅線)。您可以看到排序緩沖區(qū)被大小相近的分配所包圍,這些分配都與對(duì)象哈希表相對(duì)應(yīng)。你也可以觀察到LFH的隨機(jī)性,因?yàn)殡S后的分配不一定在隨后的地址上,然而這對(duì)我們的利用沒有任何影響。

    Image5: Heap visualization around the overflow buffer

    正如前面提到的,我們以這樣一種方式造成了溢出:一個(gè)不幸的JScript對(duì)象的hashtable指針會(huì)被覆蓋為指向到我們控制的數(shù)據(jù)的指針。現(xiàn)在終于輪到我們的數(shù)據(jù)來起作用:我們以這樣一種方式創(chuàng)建一個(gè)包含5個(gè)(假的)JavaScript變量:

    變量1只包含數(shù)字1337。

    變量2是特殊類型的0x400C。 這個(gè)類型基本上告訴JavaScript,實(shí)際的VAR是由偏移量為8的指針指向的,在讀取或?qū)懭脒@個(gè)變量之前,這個(gè)指針應(yīng)該被解除引用。在我們的例子中,這個(gè)指針指向變量1之前的16個(gè)字節(jié)。這基本上意味著變量2的最后8字節(jié)的qword和變量1的第一個(gè)8字節(jié)的qword重疊。

    變量3,變量4和變量5是簡(jiǎn)單的整數(shù)。它們的特殊之處在于它們分別在其最后8個(gè)字節(jié)中包含數(shù)字5,8和0x400C。

    圖6中顯示了溢出之后被破壞的對(duì)象的狀態(tài)。

    圖6:溢出后的對(duì)象狀態(tài)紅色區(qū)域表示溢出發(fā)生的地方。 底行中的每個(gè)框(除了那些標(biāo)記為“...”的)對(duì)應(yīng)于8個(gè)字節(jié)。 為清楚起見,“...”框中的數(shù)據(jù)被省略

    我們只需訪問正確索引處(我們稱之為index1)的已損壞對(duì)象就可以訪問變量1,對(duì)于變量2-5也是如此。實(shí)際上,我們可以通過訪問所有對(duì)象的index1來檢測(cè)哪個(gè)對(duì)象被破壞,并查看哪個(gè)對(duì)象現(xiàn)在具有值1337。

    重疊變量1和變量2的作用是可以將變量1的類型(第一個(gè)WORD)更改為5(double),8(string)或0x400C(pointer)。我們通過讀取變量2,3或4然后將讀取的值寫入變量2來實(shí)現(xiàn)。例如,語句

    corruptedobject [index2]=corruptedobject[index4];

    具有將變量1的類型更改為String(8)的效果,而變量1的所有其他字段將保持不變。

    這種布局給了我們幾個(gè)非常強(qiáng)大的利用權(quán)限:

    如果我們將一個(gè)包含一個(gè)指針的變量寫入變量1,我們可以通過將變量1的類型改為double(5)并讀出它來泄露這個(gè)指針的值

    我們可以通過在該地址偽造一個(gè)字符串來在任意地址上泄露(讀取)內(nèi)存。我們可以通過首先將與我們想要讀取的地址對(duì)應(yīng)的double值寫入變量1,然后將變量1的類型更改為String(8)來完成此操作。

    首先將對(duì)應(yīng)地址的數(shù)值寫入變量1,然后將變量1的類型更改為0x400C(指針),最后將一些數(shù)據(jù)寫入變量1,從而寫入任意地址。

    有了這些利用權(quán)限,通常獲得代碼執(zhí)行將非常簡(jiǎn)單,但是由于我們正在利用Windows 10,我們首先需要繞過Control Flow Guard(CFG)。

    階段3 繞過CFG

    這里可能有已經(jīng)公開的方法,但事實(shí)證明,jscript.dll有一些非常方便的繞過方法(一旦攻擊者有一個(gè)讀/寫權(quán)限)。我們將利用以下事實(shí):

    返回地址不受CFG保護(hù)

    一些Jscript對(duì)象有指向本地堆棧的指針

    具體來說,每個(gè)NameTbl對(duì)象(在Jscript中,所有的JavaScript對(duì)象都繼承自NameTbl),在偏移量為24的位置持有一個(gè)指向CSession對(duì)象的指針。CSession對(duì)象在偏移量為80的地方保存一個(gè)指向本地堆棧頂部附近的指針。

    因此,通過任意讀取,跟隨來自任何JScript對(duì)象的指針鏈,可以檢索指向本地堆棧的指針。然后,通過任意寫入,可以覆蓋返回地址,繞過CFG。

    階段4 在本地服務(wù)實(shí)現(xiàn)任意代碼執(zhí)行

    利用所有的漏洞元素,我們現(xiàn)在可以開始編寫poc。 我們正在這樣做:

    1.從任何JScript對(duì)象的vtable讀取jscript.dll的地址

    2.通過閱讀jscript.dll的導(dǎo)入表讀取kernel32.dll的地址

    3.通過讀取kernel32.dll的導(dǎo)入表來讀取kernelbase.dll的地址

    4.在kernel32.dll掃描我們需要的rop gadget

    5.從kernel32.dll的導(dǎo)出表中獲取WinExec的地址

    6.如上一節(jié)所述,泄漏堆棧地址

    7.準(zhǔn)備ROP鏈并將其寫入堆棧,從最接近我們泄漏堆棧地址的返回地址開始。

    我們使用的ROP鏈如下所示:

    [addressof RET] //needed to align the stack to16 bytes

    [address of POPRCX; RET] //loads the first parameter into rcx

    [address ofcommand to execute]

    [address of POPRDX; RET] //loads the second parameter into rdx

    1

    [address ofWinExec]

    通過執(zhí)行這個(gè)ROP鏈,我們用指定的命令調(diào)用WinExec。例如,如果我們運(yùn)行命令“cmd”,我們將看到一個(gè)命令提示符被生成,以本地服務(wù)運(yùn)行(運(yùn)行WPAD服務(wù)的相同用戶)。

    不幸的是,從作為本地服務(wù)運(yùn)行的子進(jìn)程中,我們不能與網(wǎng)絡(luò)通信,但是我們可以做的是將提權(quán)載荷從內(nèi)存中放入到磁盤中。本地服務(wù)可以從那里寫入并執(zhí)行它。

    階段5:提權(quán)

    雖然本地服務(wù)帳戶是服務(wù)帳戶,但它不具有管理權(quán)限。這意味著攻擊者在系統(tǒng)上可以訪問和修改的東西是非常有限的,尤其是在利用之后或系統(tǒng)重啟之后維持訪問。雖然在Windows中總有可能存在未固定的特權(quán)升級(jí),但我們不需要找到新的漏洞來升級(jí)我們的特權(quán)。相反,我們可以濫用內(nèi)置功能從本地服務(wù)升級(jí)到SYSTEM帳戶。我們來看看已授予WPAD服務(wù)帳戶的權(quán)限:

    Image7: Service Access Token’s Privileges showing Impersonate Privilege

    我們只有三個(gè)權(quán)限,但突出顯示的權(quán)限SeImpersonatePrivilege非常重要。此權(quán)限允許服務(wù)模擬本地系統(tǒng)上的其他用戶。服務(wù)具有模擬特權(quán)的原因是它接受來自本地系統(tǒng)上所有用戶的請(qǐng)求,可能需要代表他們執(zhí)行操作。但是,只要我們能夠獲取我們想要模擬的帳戶的訪問令牌,我們就可以獲得令牌帳戶的完全訪問權(quán)限,包括SYSTEM,這會(huì)使我們獲得本地系統(tǒng)上的管理員權(quán)限。

    濫用模擬是Windows安全模型的一個(gè)已知問題(您可以通過搜索令牌綁架找到更多詳細(xì)信息)。微軟已經(jīng)試圖讓獲得特權(quán)用戶訪問令牌變得更加困難,但幾乎不可能關(guān)閉所有可能門路。例如,James在Windows的DCOM實(shí)現(xiàn)中發(fā)現(xiàn)了一個(gè)漏洞,允許任何用戶訪問SYSTEM訪問令牌。雖然微軟修復(fù)了直接特權(quán)提升漏洞,但是他們沒有,也許不能修復(fù)令牌綁架問題。我們可以利用這個(gè)功能來捕獲SYSTEM令牌,冒充令牌,然后完全破壞系統(tǒng),比如安裝特權(quán)服務(wù)。

    有一個(gè)通過DCOM(RottenPotato)令牌綁架的現(xiàn)有實(shí)現(xiàn),但是實(shí)現(xiàn)被設(shè)計(jì)為與Metasploit框架的getsystem命令一起使用,但我們并沒有使用msf。因此,我們?cè)贑 ++中實(shí)現(xiàn)了我們自己的更簡(jiǎn)單的版本,它使用CreateProcessWithToken API直接生成一個(gè)帶有SYSTEM標(biāo)記的任意進(jìn)程。我們能夠?qū)⑺幾g成11KiB的可執(zhí)行文件,比RottenPotato小得多,這使得它更容易放入磁盤并從ROP載荷運(yùn)行。

    將它們聯(lián)系在一起

    當(dāng)WPAD服務(wù)查詢PAC文件時(shí),我們提供利用WPAD服務(wù)的漏洞文件并運(yùn)行WinExec來釋放和執(zhí)行權(quán)限提升的二進(jìn)制文件。這個(gè)二進(jìn)制然后執(zhí)行一個(gè)系統(tǒng)命令(在我們的情況下,硬編碼'CMD')。

    這個(gè)漏洞在我們的實(shí)驗(yàn)中非常可靠地工作,但是有趣的是,不需要100%可靠的漏洞 - 如果漏洞使WPAD服務(wù)崩潰,當(dāng)客戶端發(fā)出另一個(gè)來自WPAD的請(qǐng)求時(shí),將會(huì)產(chǎn)生一個(gè)新的實(shí)例服務(wù),所以攻擊者可以再試一次。雖然窗口錯(cuò)誤報(bào)告可能會(huì)發(fā)生崩潰并將其報(bào)告給Microsoft,但用戶沒有禁用它,UI中將沒有任何跡象表明WPAD服務(wù)已經(jīng)崩潰。

    事實(shí)上,我們的利用沒有很好的回收措施,一旦運(yùn)行載荷就會(huì)使WPAD服務(wù)崩潰,所以如果我們?cè)诜?wù)被利用后繼續(xù)提供PAC文件,它將會(huì)被再次利用。你可以在圖7中看到這個(gè)效果,這個(gè)效果是在漏洞利用服務(wù)器運(yùn)行了幾分鐘并且在受害者機(jī)器上發(fā)出大量的HTTP請(qǐng)求之后得到的。

    稍后我們會(huì)將漏洞利用源碼發(fā)布在issuehacker中

    總結(jié)

    執(zhí)行不受信任的JavaScript代碼是危險(xiǎn)的,并且在非沙箱環(huán)境中執(zhí)行它更是如此。即使它是由相對(duì)強(qiáng)健的JavaScript引擎(如jscript.dll)也是如此。我們確定了7個(gè)安全漏洞,并成功地演示了在安裝了Fall Creator Update的Windows 10 64位完全打補(bǔ)丁(撰寫本文)時(shí)從本地網(wǎng)絡(luò)(以及其他地方)執(zhí)行任意代碼。

    由于錯(cuò)誤現(xiàn)在已經(jīng)修復(fù),這是否意味著我們已經(jīng)完成并可以休息?不太可能。盡管我們花費(fèi)了相當(dāng)多的時(shí)間,精力和計(jì)算能力來查找jscript.dll錯(cuò)誤,但是我們沒有聲稱我們發(fā)現(xiàn)了所有這些錯(cuò)誤。事實(shí)上,有第7個(gè)bug,就可能會(huì)有第8個(gè)。所以如果有什么東西沒有改變的話,我們很有可能會(huì)看到這樣的一個(gè)鏈條,就像有一天在野外一樣(當(dāng)然,樂觀地認(rèn)為攻擊者已經(jīng)沒有這個(gè)能力了)。

    那么,微軟可以做些什么來使今后的攻擊變得更加困難:

    默認(rèn)情況下禁用WPAD。實(shí)際上,在其他操作系統(tǒng)支持WPAD的情況下,Windows是唯一一個(gè)默認(rèn)啟用的。

    在WPAD服務(wù)內(nèi)部提供JScript解釋器。由于解釋器需要執(zhí)行一個(gè)定義好輸入的JavaScript函數(shù)并返回輸出字符串,因此沙盒應(yīng)該非常簡(jiǎn)單。考慮到輸入輸出模型的簡(jiǎn)單性,如果微軟在 seccomp-strict 中引入了一個(gè)類似限制性的沙箱,那將是非常好的:有些進(jìn)程真的不需要比“接收一點(diǎn)數(shù)據(jù)” “執(zhí)行一些計(jì)算“,”返回一點(diǎn)數(shù)據(jù)“更多的特權(quán)。

    如果您想自行采取措施,唯一能夠使用新的,防止此類攻擊以及目前未知漏洞的方法似乎是完全禁用WinHttpAutoProxySvc服務(wù)。有時(shí)候,由于其他服務(wù)依賴于WPAD,所以在“服務(wù)”UI中無法完成(“啟動(dòng)類型”控件將變灰),但可以通過相應(yīng)的注冊(cè)表項(xiàng)來完成。在“HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WinHttpAutoProxySvc”下,將“Start的值從3(手動(dòng))更改為4(禁用)。

    以下是在搜索“禁用WPAD”時(shí)通常在網(wǎng)上找到的一些建議,這些建議在我們的實(shí)驗(yàn)中無法防止攻擊:

    在控制面板中關(guān)閉“自動(dòng)檢測(cè)設(shè)置”

    設(shè)置“WpadOverride”注冊(cè)表項(xiàng)

    將“255.255.255.255 wpad”放在主機(jī)文件中(這將停止DNS變體,但可能不是DHCP變體)

    本文由看雪翻譯小組 wangrin 編譯 轉(zhuǎn)載請(qǐng)注明來自看雪社區(qū)

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號(hào):冀ICP備2024067069號(hào)-3 北京科技有限公司版權(quán)所有