WebAssembly StackOverflow

  • WebAssembly StackOverflow已关闭评论
  • 10 views
  • A+
所属分类:安全百科

WebAssembly StackOverflow

Mon Apr 30 16:50:47 2018

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

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

有什麼不同

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

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

一個例子

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

Rust 代碼:

```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。

Read Stack Overflow

侷限

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

柳暗花明

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

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

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

XSS Game

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


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

CN-SEC.COM中文网|本文百科收录于:https://quininer.github.io/

相关推荐: 关于expressjs的一个小坑

关于expressjs的一个小坑 Tue Dec 9 01:07:53 2014 都知道在PHP里,/?key[arr]=value 会被解析为 array(1) { ["key"]=> array(1) { ["arr"]=> string(5)…