WebAssembly StackOverflow

admin 2024年4月22日03:25:09WebAssembly StackOverflow已关闭评论2 views字数 1721阅读5分44秒阅读模式

WebAssembly 是一個設計運行在瀏覽器上的類彙編語言,
藉助它可以令 C / C++ 之類的語言運行在瀏覽器上,以期得到性能提升。

新功能自然會引入新攻擊面,可以預見 C / C++ 上經常出現的緩衝區溢出並不會在 WebAssembly 上消失。

有什麼不同

WebAssembly 同常見的彙編有很多不同的地方,例如

因爲第三點,WebAssembly 在一定程度上是 Harvard architecture,這爲 WebAssembly 帶來了很大的安全優勢,但棧溢出仍是可能的。

一個例子

我們舉個虛構的例子來證明 WebAssembly 棧溢出的可行性。

Rust 代碼:

// ...

#[wasm_bindgen]
pub fn hash_with_key(key: &str, data: &str) -> u32 {
    let mut val = [0; 32];
    let key = key.as_bytes();
    let data = data.as_bytes();

    val[..3].copy_from_slice(&key[..3]);
    val[3] = 0x33;
    val[4..][..data.len()].copy_from_slice(&data);

    js_hash(&val)
}

#[wasm_bindgen]
pub fn table_index(i: usize) -> u8 {
    let a = [b'a', b'd', b'c', b'b'];
    unsafe { *a.get_unchecked(i) }
}

WebAssembly 的 wat 格式基於 S-expression,指令精簡,與傳統彙編相比,相對容易閱讀。

但鑑於編譯出的 wasm 較長,下面我們只看我們關心的內容,
完整的內容可以看這裏

(global (;0;) (mut i32) (i32.const 1050544))

指令 global 定義了一塊可變的全局內存。
其中 1MB 是棧空間,剩下的是數據段。

  (func $hash_with_key (type 2) (param i32 i32) (result i32)
    (local i32 i32 i32)
    get_global 0
    i32.const 32
    i32.sub

    ;; ...

        get_local 2
        get_local 0
        i32.load16_u align=1
        i32.store16
        get_local 2
        get_local 0
        i32.const 2
        i32.add
        i32.load8_u
        i32.store8 offset=2

    ;; ...
  )

函數 hash_with_key 在棧上開闢 32bytes,將 key 寫入棧上,而退棧時未將其清零。

  (func $table_index (type 4) (param i32) (result i32)
    (local i32)
    get_global 0
    i32.const 16
    i32.sub

    ;; ...

    i32.const 12
    i32.add
    get_local 0
    i32.add
    i32.load8_u)

函數 table_index 在棧上開闢 16bytes,偏移 12bytes 讀取一個 byte。

簡單分析可以知道,在用戶正常調用 hash_with_key(..) 之後,
攻擊者只需要調用 table_index(16 - 12 - 32 + x) 便可獲得寫入棧上的 key。

WebAssembly StackOverflow

侷限

雖然棧溢出是可行的,
但指令與數據的分離,使得我們只能讀寫棧內容而不能改變控制流。
這意味著 ROP、return2libc 之類的技巧不再有效,
棧溢出將只能在邏輯方面造成一些影響,危險度下降不止一個等級。

柳暗花明

而 WebAssembly 想要支持 函數指針、虛函數、trait 對象,就必須引入一些動態方案。

WebAssembly 的方案是將所有需要動態使用的函數放入 Table
在運行時通過引索指定,並且在調用時會檢查函數簽名。

這個設計試圖在最大程度上降低風險,但無可避免的爲攻擊者開了一扇窗。

XSS Game

基於 WebAssembly 棧溢出,我做了一個簡單的 XSS Challenge
源代碼託管在 wasm-xss-game
有興趣的讀者可以一試。

  • 本文有意忽略堆溢出,以避免引入衆多 Allocator 的複雜性。
  • 作者不熟悉二進制安全、計算機原理。胡言亂語不知所云,有錯勿怪。

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月22日03:25:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   WebAssembly StackOverflowhttp://cn-sec.com/archives/2629018.html