iT邦幫忙

2026 iThome 鐵人賽

DAY 23
0

今天的主角是 LadyBird[1],一款近期由團隊自研(不使用任何現代引擎/框架去改)的瀏覽器。
儘管脫離了現代那些引擎(像是 v8, spidermonkey)架構,因為要遵守 ECMA 等訂定的 JS 規範 2,他在基本的內部結構上還是高度相似地,導致可攻擊的手法其實蠻相近的?!(其實我也是看了 Calif 的 Post 才知道)

(值得一提的是,為了消除記憶體 Bug,LadyBird 目標是用 Rust 寫完整個 Browser)

今天要講的故事主角文章有兩篇

蝦為什麼有兩個,這故事蠻有趣的。
Calif 團隊剛好挑了 LadyBird 瀏覽器作為一個 "呒先備知識/材料" 又複雜的 Exploit Target,卻在發現了今天這個 Use After Free 的漏洞並通報後才驚覺與 tsune 這位漏洞研究員撞洞。

果然還是到了機器跟人類搶飯吃的年代

The PoC

今天的漏洞是出在 WASM (Web Assembly) 上,所謂的 Web Assembly 就是一種在現代瀏覽器中以接近原生速度執行的低階二進位程式語言,並且它支援 JS API 呼叫,因為它對資源的友善導致像 Unity/Godot 這類型的遊戲引擎得以在瀏覽器上跑。

直接看 PoC 應該比較好懂 XD

const m = new WebAssembly.Memory({initial:1,maximum:16,shared:true});
const v = new Uint32Array(m.buffer);
m.grow(1);

在定義好一段 wasm memory 後,先讓一個變數 v 以 Array 型別造訪/讀取它
最後再用 m.grow(1) 來 allocate 一塊新的 wasm 記憶體 page 並且它的 page 數是當前的量值 + 1(宣告說不夠用了這樣)

雖然現在 wasm memory page pointer 應該重新指向新的 allocated page,但是剛剛的這個 array 在內部其實還是指向舊的,已經被 free 掉的 memory page。
接著嘗試用一個大 array 來不斷 allocate object array (一個 Array 裡面都是 JS Object),來想辦法 claim 到剛剛被 free,可是我們可以透過 v 造訪的 page

const target = { _id: "TARGET_SENTINEL", magic: 0xCAFEBABE };
const rA = new Array(6500).fill(target);

後面,因為 JS Array 中的 Object 會是以 "指向那個 Object 的指針" 作為 Element 儲存在 JS Array,透過這樣的前提結合前面的攻擊(利用 v 完整讀寫 Object Array 那塊 Page),我們又可以達成 Fake Object (從特定地址抓一個 Object 出來,有沒有!)
接著一路串去任意地址讀寫 RCE!

喔先別急著高興,畢竟任意物件記憶體地址洩漏還沒完成呢~大家可以想想看為什麼可以做到

||Hint: 我們既然可以寫...那反過來把 Object Array 當作 Int Array 讀取會讀到的就是...?||

對於這個漏洞來自原始 blog 的執行流程:
image

一些 Murmur

回答一下前面 calif 的提問,LLM 能打新的引擎嗎?
答案是...能,但我更傾向於這只是一個 Pattern Matching 的範例?!
因為人類已經大量用過類似的技巧完成 Exploit,AI 在 Match 出這樣的 Pattern 時自然可以很簡單完成典範轉移。

但我認為這其實已經足及可怕,畢竟一年前的 LLM + MCP 還在為能在 V8 CTF 題目中達成把 Shellcode 轉成 Float 執行開心呢 xDD
(詳見: https://x.com/ruikai/status/1932225823056257438 [5])

References


上一篇
Day 22. JS Engine Pwn 101:從假冒一個物件開始
系列文
Agentic Era,一年來 LLM 到底都挖了些什麼洞! 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言