今天多提幾個 case study 來看看實務上的案例。
CVE-2018-18440 是 U-Boot Verified Boot 的Bypass 漏洞。
U-Boot 可以從 filesystem 載入 image 到 RAM,但對 image 大小與載入範圍缺乏足夠限制。攻擊者可以提供過大的 image,讓資料覆蓋到 U-Boot 自己的記憶體區域,最終在 signature verification 之前或驗證流程中取得 code execution。
早期 U-Boot 很多 image loading API 都接受:
load_addr
image_size
source
但缺少統一的 protection 去確認:
load_addr + image_size
是否碰到:
U-Boot text
U-Boot data
stack
heap
malloc arena
relocated U-Boot
概念上 vulnerable pattern 類似:
void load_image(void *dst, size_t len)
{
filesystem_read(dst, len);
}
缺少:
if (overlaps_uboot(dst, len))
return -EINVAL;
如果:
dst = 0x81000000
len = attacker_controlled
而 U-Boot runtime region 在:
0x81f00000 - 0x82000000
就可能透過 oversized image 寫進 bootloader 本體。
這類 exploit 通常不需要碰 RSA。
攻擊流程:
1. 準備大型 filesystem image
2. 控制 image metadata / file size
3. 讓 U-Boot 把內容讀進固定 RAM address
4. overflow 到 U-Boot runtime structure
5. 覆蓋 function pointer / return data / control structure
6. redirect execution
7. 修改 verification path 或直接執行 payload
CVE-2022-33967 影響 U-Boot v2020.10-rc2 到 v2022.07-rc5。
漏洞位於 SquashFS metadata parsing。
crafted SquashFS image 可以造成 heap-based buffer overflow,可能導致 crash 或 arbitrary code execution。NVD
malicious squashfs
|
v
metadata parser
|
v
wrong size calculation
|
v
heap allocation
|
v
copy too much data
|
v
heap overflow
SquashFS metadata 本身包含大量 attacker-controlled length、offset 與 block information。
漏洞出現在 U-Boot 讀取 metadata 時,allocation size 與實際解壓/複製長度沒有正確對應。
概念上:
size = metadata_length;
buf = malloc(size);
read_metadata(buf, attacker_controlled_length);
如果:
allocated size < copied size
就會:
heap chunk
+--------------------+
| allocated metadata |
+--------------------+
| next heap object |
+--------------------+
^
overwritten
bootloader environment 通常又缺少:
ASLR
heap hardening
stack protections
guard pages
攻擊者需要製作 malformed SquashFS filesystem。
通常控制:
metadata block size
compressed size
uncompressed size
inode data
directory table
PoC 方向可以直接 patch filesystem binary。
例如:
with open("rootfs.squashfs", "rb") as f:
data = bytearray(f.read())
# overwrite metadata length / block field
data[offset:offset+2] = b"\xff\xff"
with open("evil.squashfs", "wb") as f:
f.write(data)
U-Boot 端:
=> sqfsls mmc 0:1 /
或:
=> sqfsload mmc 0:1 0x82000000 /file
觸發 parser。
才發現幾天前說的是要先寫patch diff,娃QQ
明天再來寫