作者:張漢東
原文鏈接:https://mp.weixin.qq.com/s/RsfEKl7FAGs2L9vXKC0rWQ
相關閱讀:
Rust生態安全漏洞總結系列 | Part 1
Rust生態安全漏洞總結系列 | Part 2
本系列主要是分析RustSecurity 安全數據庫庫[1]中記錄的Rust生態社區中發現的安全問題,從中總結一些教訓,學習Rust安全編程的經驗。
本期分析了下面十一個安全問題:
-
RUSTSEC-2021-0110: Vulnerability in wasmtime[2]
-
RUSTSEC-2021-0098: Vulnerability in openssl-src[3]
-
RUSTSEC-2021-0082: Unsoundness in vec-const[4]
-
RUSTSEC-2021-0093: Vulnerability in crossbeam-deque[5]
-
RUSTSEC-2021-0077: Vulnerability in better-macro[6]
-
RUSTSEC-2021-0106: Vulnerability in bat[7]
-
RUSTSEC-2021-0073: Vulnerability in prost-types[8]
-
RUSTSEC-2021-0078: Vulnerability in hyper[9]
-
RUSTSEC-2021-0072: Vulnerability in tokio[10]
-
RUSTSEC-2021-0070: Vulnerability in nalgebra[11]
-
CVE-2021-31162: Vulnerability in std[12]
看是否能給我們一些啟示。
RUSTSEC-2021-0110: Vulnerability in wasmtime[13]
在 Wasmtime 中發現多個代碼缺陷。包括 UAF(use-after-free)、越界讀寫等。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:memory-corruption/ memory-exposure
- CVE 編號:CVE-2021-39216[14]、CVE-2021-39219[15]、CVE-2021-39218[16]
- 詳細:https://rustsec.org/advisories/RUSTSEC-2021-0110.html
- 補丁:
>=0.30.0 - 關鍵字:
use-after-free/out-of-bounds read /out-of-bounds write / Wasm/garbage collection
漏洞分析
背景:
externref是 WebAssembly 引用類型(Reference Types)中引入的概念,用于表示 Host 引用。
Use after free passing externrefs to Wasm in Wasmtime[17]
當從 Host 傳遞給 Guest externrefs 時會引發 UAF 。滿足下列條件之一可觸發此 Bug :
- 同時明確地從Host傳遞多個
externrefs給wasm實例 - 通過將多個
externrefs作為參數從 Host 代碼傳遞給wasm函數 - 從Host定義的多值返回函數中返回多個
externrefs給wasm
如果 Wasmtime 的 VMExternRefActivationsTable在傳入第一個externref后容量被填滿,那么傳入第二個externref可能會觸發垃圾回收。然而,在把控制權傳給Wasm之前,第一個externref是沒有根(root)的,因此,如果沒有其他東西持有對它的引用或以其他方式保持它的live,就會被GC回收。然后,當控制權在垃圾收集后被傳遞給Wasm時,Wasm可以使用第一個externref,但這時它已經被釋放了。
Out-of-bounds read/write and invalid free with externrefs and GC safepoints in Wasmtime[18]
在Wasmtime運行使用externrefs的Wasm時,存在一個無效釋放和越界讀寫的錯誤。
要觸發這個錯誤,Wasmtime需要運行使用externrefs的Wasm,Host 創建非空的externrefs,Wasmtime執行一個垃圾收集(GC),并且堆棧上必須有一個Wasm幀,它處于GC Safepoint(安全點就是指代碼運行到這個地方,它的狀態是確定的, GC就可以安全的進行一些操作),在這個安全點上沒有 Live 的引用,這種情況下 Wasmtime 會錯誤地使用 GC Stack map 而非 安全點。這就會導致釋放一些不應該釋放的內存,以及潛在的越界讀寫。
Wrong type for Linker-define functions when used across two Engines[19]
Engine,是在 wasmtime 中被用于跨線程管理wasm模塊的全局上下文。Linker,是用于支持模塊鏈接的結構。
在 Linker::func_* 安全函數中發現了一個問題。wasmtime 不支持函數的跨 engine 使用,這可能導致函數指針的類型混亂,導致能夠安全地調用一個類型錯誤的函數。這種情況應該 panic!
RUSTSEC-2021-0098: Vulnerability in openssl-src[20]
openssl-src[21] 是用于構建 OpenSSL 給 openssl-sys 庫使用的。OpenSSL 最近又發現了很多新的安全缺陷,也記錄到這里了。
具體這個漏洞是指 處理ASN.1字符串時的讀取緩沖區超限問題。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:denial-of-service / crypto-failure
- CVE 編號:CVE-2021-3712
- 詳細:https://www.openssl.org/news/secadv/20210824.txt
- 補丁:
>=111.16
漏洞分析
ASN.1字符串在OpenSSL內部被表示為一個ASN1_STRING結構,它包含一個容納字符串數據的緩沖區和一個容納緩沖區長度的字段。這與普通的C語言字符串不同,后者表示為一個字符串數據的緩沖區,以NUL(0)字節結束。
雖然不是嚴格的要求,但使用OpenSSL自己的 "d2i "函數(和其他類似的解析函數)解析的ASN.1字符串,以及任何用ASN1_STRING_set()函數設置值的字符串,都會在ASN1_STRING結構中以NUL結束字節數。
然而,應用程序有可能直接構建有效的ASN1_STRING結構,通過直接設置ASN1_STRING數組中的 "data "和 "length "字段,不以NUL方式終止字節數組。這也可以通過使用ASN1_STRING_set0()函數來實現。
許多打印ASN.1數據的OpenSSL函數被認為ASN1_STRING字節數組將以NUL結尾,盡管這對直接構建的字符串來說是不保證的。如果應用程序要求打印一個ASN.1結構,而該ASN.1結構包含由應用程序直接構建的ASN1_STRING,而沒有以NUL結束 "data "字段,那么就會發生讀取緩沖區超限。
如果一個惡意行為者可以使一個應用程序直接構建一個ASN1_STRING,然后通過受影響的OpenSSL函數之一處理它,那么這個問題可能會被擊中。這可能導致崩潰(造成拒絕服務攻擊,DOS)。它還可能導致私人內存內容(如私人密鑰或敏感明文)的泄露。
其他 OpenSSL 問題
OpenSSL 缺陷列表:https://rustsec.org/packages/openssl-src.html
RUSTSEC-2021-0082: Unsoundness in vec-const[22]
vec-const試圖從一個指向常量切片的指針構造一個Vec。
漏洞描述:
- 漏洞類型:Unsound
- 漏洞分類:memory-corruption
- CVE 編號:CVE-2021-3711
- 詳細:https://github.com/Eolu/vec-const/issues/1#issuecomment-898908241
- 補丁:暫無,不建議使用該 crate
- 關鍵字:memory-safety
漏洞分析
這個crate 違反了Rust的規則,使用起來會有危害。你不應該使用這個crate。這個crate不應該存在。它創建了不健全的抽象,允許不安全的代碼偽裝成安全代碼。
這個crate聲稱要構造一個長度和容量都不為零的const Vec,但這是做不到的,因為這樣的Vec需要一個來自分配器(allocator)的指針。參見:https://github.com/rust-lang/const-eval/issues/20
RUSTSEC-2021-0093: Vulnerability in crossbeam-deque[23]
crossbeam-deque中發生了數據競爭。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:memory-corruption
- CVE 編號:GHSA-pqqp-xmhj-wgcw、 CVE-2021-32810[24]
- 詳細:https://github.com/Eolu/vec-const/issues/1#issuecomment-898908241
- 補丁:
>=0.7.4, <0.8.0/>=0.8.1
漏洞分析
在受影響的版本中,隊列的一個或多個任務會被彈出兩次,如果在堆上分配,會導致 dobule free 和 內存泄漏。如果不是堆上分配,則會引起邏輯錯誤。
修復PR :https://github.com/crossbeam-rs/crossbeam/pull/726
問題是因為任務竊取相關條件判斷錯誤導致的,是邏輯 Bug。
RUSTSEC-2021-0077: Vulnerability in better-macro[25]
better-macro 是一個假的 crate,它在 "證明一個觀點",即proc-macros可以運行任意的代碼。這是一個特別新穎或有趣的觀察。
它目前打開的https://github.com/raycar5/better-macro/blob/master/doc/hi.md,似乎沒有任何惡意的內容,但不能保證會一直如此。
這個 crate 沒有任何有用的功能,不應該被使用。
#[proc_macro]
pub fn println(input: TokenStream) -> TokenStream {
if let Ok(_) = Command::new("xdg-open").arg(URL).output() {
} else if let Ok(_) = Command::new("open").arg(URL).output() {
} else if let Ok(_) = Command::new("explorer.exe").arg(URL).output() {
}
let input: proc_macro2::TokenStream = input.into();
let out = quote! {::std::println!(#input)};
out.into()
}
RUSTSEC-2021-0106: Vulnerability in bat[26]
bat[27] 中存在不受控制的搜索路徑元素,可能會導致非預期代碼執行。
0.18.2之前的windows系統中的bat會從當前工作目錄中執行名為less.exe的程序。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:code-execution
- CVE 編號:CVE-2021-36753[28] 、 GHSA-p24j-h477-76q3
- 詳細:https://nvd.nist.gov/vuln/detail/CVE-2021-36753
- 補丁:
>=0.18.2 - 平臺:Windows
漏洞分析
修復 PR:https://github.com/sharkdp/bat/pull/1724
對傳入的 Path 進行了合法驗證。使用的庫是 grep_cli。
RUSTSEC-2021-0073: Vulnerability in prost-types[29]
從prost_types::Timestamp到SystemTime的轉換可能導致溢出和恐慌。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:denial-of-service
- CVE 編號:CVE-2021-36753[30] 、 GHSA-p24j-h477-76q3
- 詳細:https://github.com/tokio-rs/prost/issues/438
- 補丁:
>=0.8.0
漏洞分析
在prost-types 0.7.0中,從Timestamp到SystemTime的轉換使用UNIX_EPOCH上的+和-運算符。如果輸入的Timestamp是不被信任的,這可能會溢出和恐慌,造成拒絕服務的漏洞。因為 SystimeTime 內部實現的 + 和 - 使用 checked_add/checked_sub會發生 panic。
use prost_types::Timestamp;
use std::time::SystemTime;
SystemTime::from(Timestamp {
seconds: i64::MAX,
nanos: 0,
}); // panics on i686-unknown-linux-gnu (but not x86_64) with default compiler settings
SystemTime::from(Timestamp {
seconds: i64::MAX,
nanos: i32::MAX,
}); // panics on x86_64-unknown-linux-gnu with default compiler settings
另外,轉換涉及到調用Timestamp::normalize,它使用了+和-運算符。這可能會引起恐慌或環繞(wrap around,取決于編譯器設置),如果應用程序被編譯為溢出時恐慌,也會產生拒絕服務的漏洞。
解決問題的思路是:
Timestamp::normalize可能應該使用 saturating_{add,sub}[31] 方法,如果時間戳的nanos字段超出了范圍,這可能會默默地改變時間戳,最多3秒,但這樣的時間戳可以說是無效的,所以這可能是好的。
SystemTime 沒有Saturating_{add,sub}方法,也沒有MIN和MAX常數,應該再次使用 SystemTime::checked_{add,sub} 進行轉換。
修復 PR:https://github.com/tokio-rs/prost/pull/439
RUSTSEC-2021-0078: Vulnerability in hyper[32]
對Content-Length進行寬松的 header 解析,可能會使請求被偷渡(走私,smuggling)。
背景:請求偷渡 不合法的請求被夾雜在合法請求中被得到處理。需要通過
content-length和Transfer-Encoding兩個header 來構造攻擊。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:http、parsing
- CVE 編號:CVE-2021-32715
- 詳細:https://github.com/hyperium/hyper/security/advisories/GHSA-f3pg-qwvg-p99c
- 補丁:
>=0.14.10
漏洞分析
hyper的HTTP/1服務器代碼存在一個缺陷,即錯誤地解析和接受帶有前綴加號的Content-Length頭的請求,而這一請求本應作為非法請求被拒絕。這與上游HTTP代理不解析這種Content-Length頭而轉發的情況相結合,可能導致 "請求偷渡("request smuggling) "或 "去同步攻擊(desync attacks)"。
修復代碼:https://github.com/hyperium/hyper/commit/06335158ca48724db9bf074398067d2db08613e7
需要判斷 content-lenght 是不是可以正常轉換為有效數位。
RUSTSEC-2021-0072: Vulnerability in tokio[33]
當用JoinHandle::abort中止一個任務時,對于 LocalSet上生成的任務不正確, 容易導致競態條件。
漏洞描述:
-
漏洞類型:Vulnerability
-
漏洞分類:memory-corruption
-
CVE 編號:CVE-2021-32715
-
補丁:
>=1.5.1, <1.6.0 >=1.6.3, <1.7.0 >=1.7.2, <1.8.0 >=1.8.1
漏洞分析
當用JoinHandle::abort中止一個任務時,如果該任務當前沒有被執行,那么在調用abort的線程中,Future會被 Drop。這對于在LocalSet上生成的任務是不正確的。
這很容易導致競態條件,因為許多項目在它們的Tokio任務中使用Rc或RefCell以獲得更好的性能。
修復 PR:https://github.com/tokio-rs/tokio/pull/3934
RUSTSEC-2021-0070: Vulnerability in nalgebra[34]
nalgebra 庫中VecStorage 的Deserialize實現沒有保持元素數量必須等于nrows * ncols的不變性。對特制的輸入進行反序列化時,可能會允許超出向量分配的內存訪問。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:memory-corruption/ memory-exposure
- CVE 編號:CVE-2021-32715
- 詳細:https://github.com/dimforge/nalgebra/issues/883
- 補丁:
>=0.27.1
漏洞分析
這個缺陷是在v0.11.0(086e6e)中引入的,因為為MatrixVec增加了一個自動派生(derive)的Deserialize實現。MatrixVec后來在v0.16.13(0f66403)中被改名為VecStorage,并繼續使用自動派生的Deserialize實現。
修復 PR :https://github.com/dimforge/nalgebra/pull/889
在反序列化的過程中,對 nrows.value() * ncols.value() == data.len()進行校驗。
CVE-2021-31162: Vulnerability in std[35]
在 Rust 1.52.0之前的Rust標準庫中,如果釋放元素時出現panic ,在Vec::from_iter函數中會出現 double free。
漏洞描述:
- 漏洞類型:Vulnerability
- 漏洞分類:memory-corruption
- CVE 編號:CVE-2021-31162
- 詳細:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-31162
- 補丁:
>=1.52.0
漏洞分析
漏洞復現代碼:
use std::iter::FromIterator;
#[derive(Debug)]
enum MyEnum {
DroppedTwice(Box<i32>),
PanicOnDrop,
}
impl Drop for MyEnum {
fn drop(&mut self) {
match self {
MyEnum::DroppedTwice(_) => println!("Dropping!"),
MyEnum::PanicOnDrop => {
if !std::thread::panicking() {
panic!();
}
}
}
}
}
fn main() {
let v = vec![MyEnum::DroppedTwice(Box::new(123)), MyEnum::PanicOnDrop];
Vec::from_iter(v.into_iter().take(0));
}
// Output : free(): double free detected in tcache 2
因為枚舉MyEnum在 析構的時候panic,導致資源泄漏,而引發了雙重 free 的問題。
修復 PR:https://github.com/rust-lang/rust/pull/84603
在 Vec::from_iter 中執行 forget_allocation_drop_remaining,即,忘記已經被drop的src的元素分配的內存,即便 drop 發生了 panic,也不會泄漏資源。
參考資料
[1]RustSecurity 安全數據庫庫: https://rustsec.org/advisories/
[2]RUSTSEC-2021-0110: Vulnerability in wasmtime: https://rustsec.org/advisories/RUSTSEC-2021-0110.html
[3]RUSTSEC-2021-0098: Vulnerability in openssl-src: https://rustsec.org/advisories/RUSTSEC-2021-0098.html
[4]RUSTSEC-2021-0082: Unsoundness in vec-const: https://rustsec.org/advisories/RUSTSEC-2021-0082.html
[5]RUSTSEC-2021-0093: Vulnerability in crossbeam-deque: https://rustsec.org/advisories/RUSTSEC-2021-0093.html
[6]RUSTSEC-2021-0077: Vulnerability in better-macro: https://rustsec.org/advisories/RUSTSEC-2021-0077.html
[7]RUSTSEC-2021-0106: Vulnerability in bat: https://rustsec.org/advisories/RUSTSEC-2021-0106.html
[8]RUSTSEC-2021-0073: Vulnerability in prost-types: https://rustsec.org/advisories/RUSTSEC-2021-0073.html
[9]RUSTSEC-2021-0078: Vulnerability in hyper: https://rustsec.org/advisories/RUSTSEC-2021-0078.html
[10]RUSTSEC-2021-0072: Vulnerability in tokio: https://rustsec.org/advisories/RUSTSEC-2021-0072.html
[11]RUSTSEC-2021-0070: Vulnerability in nalgebra: https://rustsec.org/advisories/RUSTSEC-2021-0070.html
[12]CVE-2021-31162: Vulnerability in std: https://rustsec.org/advisories/CVE-2021-31162.html
[13]RUSTSEC-2021-0110: Vulnerability in wasmtime: https://rustsec.org/advisories/RUSTSEC-2021-0110.html
[14]CVE-2021-39216: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-39216
[15]CVE-2021-39219: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-39219
[16]CVE-2021-39218: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-39218
[17]Use after free passing externrefs to Wasm in Wasmtime:
https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-v4cp-h94r-m7xf
[18]Out-of-bounds read/write and invalid free with externrefs and GC safepoints in Wasmtime:
https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-4873-36h9-wv49
[19]Wrong type for Linker-define functions when used across two Engines:
https://github.com/bytecodealliance/wasmtime/security/advisories/GHSA-q879-9g95-56mx
[20]RUSTSEC-2021-0098: Vulnerability in openssl-src: https://rustsec.org/advisories/RUSTSEC-2021-0098.html
[21]openssl-src: https://crates.io/crates/openssl-src
[22]RUSTSEC-2021-0082: Unsoundness in vec-const: https://rustsec.org/advisories/RUSTSEC-2021-0082.html
[23]RUSTSEC-2021-0093: Vulnerability in crossbeam-deque: https://rustsec.org/advisories/RUSTSEC-2021-0093.html
[24]CVE-2021-32810: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-32810
[25]RUSTSEC-2021-0077: Vulnerability in better-macro: https://rustsec.org/advisories/RUSTSEC-2021-0077.html
[26]RUSTSEC-2021-0106: Vulnerability in bat: https://rustsec.org/advisories/RUSTSEC-2021-0106.html
[27]bat: https://rustsec.org/packages/bat.html
[28]CVE-2021-36753: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-36753
[29]RUSTSEC-2021-0073: Vulnerability in prost-types: https://rustsec.org/advisories/RUSTSEC-2021-0073.html
[30]CVE-2021-36753: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-36753
[31]saturating_{add,sub}:https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.saturating_add
[32]RUSTSEC-2021-0078: Vulnerability in hyper: https://rustsec.org/advisories/RUSTSEC-2021-0078.html
[33]RUSTSEC-2021-0072: Vulnerability in tokio: https://rustsec.org/advisories/RUSTSEC-2021-0072.html
[34]RUSTSEC-2021-0070: Vulnerability in nalgebra: https://rustsec.org/advisories/RUSTSEC-2021-0070.html
[35]CVE-2021-31162:Vulnerability in std: https://rustsec.org/advisories/CVE-2021-31162.html
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1731/
暫無評論