Skip to content

Commit ccdeade

Browse files
authored
Merge pull request #2038 from HackTricks-wiki/research_update_src_binary-exploitation_stack-overflow_pointer-redirecting_20260320_023644
Research Update Enhanced src/binary-exploitation/stack-overf...
2 parents 7a1c330 + da55bc2 commit ccdeade

1 file changed

Lines changed: 55 additions & 2 deletions

File tree

src/binary-exploitation/stack-overflow/pointer-redirecting.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,22 @@ If a function call is going to use an address of a string that is located in the
88

99
If for example a **`system`** function call is going to **use the address of a string to execute a command**, an attacker could place the **address of a different string in the stack**, **`export PATH=.:$PATH`** and create in the current directory an **script with the name of the first letter of the new string** as this will be executed by the binary.
1010

11+
In real targets, **repointing a stack string pointer is usually more interesting than just changing the printed text**:
12+
13+
- Redirect a later **`system`/`popen`/`execl*`** argument to an existing `"/bin/sh"` or attacker-controlled command string already present in memory.
14+
- Redirect a later **read** sink such as **`puts("%s", ptr)`** or **`write(fd, ptr, len)`** to leak stack, heap or binary data.
15+
- Redirect a later **write** sink such as **`strcpy(dst, ...)`**, **`memcpy(dst, src, len)`**, or a structure field assignment through `ptr->field = value` to turn the stack overflow into a **second-stage arbitrary write**.
16+
17+
When auditing, prioritise stack locals such as **`char *cmd`**, **`char *path`**, **`char *buf`**, **`FILE *fp`**, or **pointers inside temporary request/response structs** that are used **after** the overflow but **before** the function returns. This is especially useful when the overflow cannot safely reach the saved return address because of a canary or because corrupting a nearby pointer is enough.
18+
19+
If the corruption is limited to a **partial overwrite** (for example because the bug appends a `0x00`), try to redirect the pointer to:
20+
21+
- A nearby string in the **same stack frame**
22+
- Another object in the **same module / non-PIE image**
23+
- A controlled region whose **high bytes stay unchanged**
24+
25+
For the related ASLR-oriented case where a trailing NUL modifies an **existing stack pointer** instead of a dedicated local variable, check [Ret2ret & Reo2pop](../common-binary-protections-and-bypasses/aslr/ret2ret.md).
26+
1127
You can find an **example** of this in:
1228

1329
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/strptr.c)
@@ -18,15 +34,52 @@ You can find an **example** of this in:
1834

1935
Same as string pointer but applying to functions, if the **stack contains the address of a function** that will be called, it's possible to **change it** (e.g. to call **`system`**).
2036

37+
Useful targets are not only explicit callback variables such as `void (*fp)()`. In practice, look for:
38+
39+
- **Callbacks stored in local structs** passed later to helper functions
40+
- **Destructor / cleanup handlers** invoked on error paths
41+
- **Parser dispatch tables** or **state-machine handlers** copied to the stack
42+
- **Local structs / objects** that later dispatch through an indirect call
43+
44+
In modern exploitation, **pointer redirection is often the last primitive available before touching the canary**. A 2024 exploitation writeup for CVE-2024-20017 shows the typical pattern: the overflow reaches several local variables before the stack canary, the attacker corrupts a **stack pointer plus its associated length/value**, and a later assignment through that pointer becomes an **arbitrary write** without ever needing to return through the corrupted frame.
45+
46+
### Pointer corruption to second-stage primitives
47+
48+
If a nearby pointer is later dereferenced for a store, the goal is usually not to jump directly with the first overflow, but to **upgrade the primitive**:
49+
50+
1. Overflow a local buffer and corrupt a **pointer** plus any associated **length / integer / index**.
51+
2. Wait for the function to perform a **post-overflow dereference** such as `ptr->len = x`, `memcpy(ptr, src, n)` or `*ptr = value`.
52+
3. Use that resulting **write-what-where** to overwrite a GOT slot, callback, config pointer, or another indirect callsite.
53+
54+
This is a good option when:
55+
56+
- The bug stops at the canary
57+
- The function pointer itself is not directly reachable
58+
- A 4-byte or 8-byte **data write** is easier to get than an immediate control-flow hijack
59+
60+
The same idea also works for **read** primitives if the corrupted pointer is later passed to logging, printing, or network send helpers.
61+
62+
### Modern AArch64 note: PAC / BTI
63+
64+
On current AArch64 targets, a classic **saved return address overwrite** may fail because the epilogue authenticates `x30` with PAC. In those cases, **non-return hijacks** such as corrupted local function pointers or callback pointers become more attractive.
65+
66+
However, if **BTI** is enabled, the overwritten indirect-call target must still land on a **valid landing pad** (typically a function entry with **`bti c`**, or in PAC-enabled code a prologue starting with **`paciasp`/`pacibsp`**). Therefore, when redirecting a stack function pointer on AArch64, prefer:
67+
68+
- Real function entries instead of mid-function gadgets
69+
- Targets whose prologue already satisfies BTI
70+
- Targets where the indirect-call pointer is not additionally authenticated before use
71+
72+
For a related AArch64 stack-overflow context, check [ret2win-arm64](ret2win/ret2win-arm64.md).
73+
2174
You can find an example in:
2275

2376
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/ASLR%20Smack%20and%20Laugh%20reference%20-%20Tilo%20Mueller/funcptr.c)
2477

2578
## References
2679

2780
- [https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting](https://github.com/florianhofhammer/stack-buffer-overflow-internship/blob/master/NOTES.md#pointer-redirecting)
81+
- [https://blog.coffinsec.com/0day/2024/08/30/exploiting-CVE-2024-20017-four-different-ways.html](https://blog.coffinsec.com/0day/2024/08/30/exploiting-CVE-2024-20017-four-different-ways.html)
82+
- [https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64](https://developer.arm.com/community/arm-community-blogs/b/architectures-and-processors-blog/posts/enabling-pac-and-bti-on-aarch64)
2883

2984
{{#include ../../banners/hacktricks-training.md}}
3085

31-
32-

0 commit comments

Comments
 (0)