checksec
开了canary和NX,没开reload和pie,考虑使用hijack got
反编译
可以看到一个明显的格式化字符串漏洞
测试得到偏移为12,这里需要注意的是我们的输入是跟在"Please tell me your name… “这句话的后头的,这句话本身长度为18,那么我们需要先输入两个字符使地址对齐,然后再用%p输出
但是这道题的格式化字符串漏洞是在return的时候,也就是说按照往常实现任意地址写一次就会退出
这里需要用到.fini_array劫持。是以前没接触过的新知识
关于这个fini_array的详细介绍可以参考这篇文章,这位老哥语言比较诙谐但是内容写的挺不错
简单来讲就是main函数在退出到__libc_start_main之后还会有一个执行.fini_array的步骤,具体就是执行这一块地址的每一个函数指针
细说到main的执行流程,有一篇Patrick Horgan写的名字叫做"Linux x86 Program Start Up or - How the heck do we get to main()?“的文章:(http://dbp-consulting.com/tutorials/debugging/linuxProgramStartup.html)
这里放一张很不错的流程图:
思路就是覆盖fini_array里面的函数指针为start,就可以做到回到main函数。
接下来就是需要思考怎么获取shell
程序给了system,没有后门函数,那么我们思路就是修改某个函数的got表为system,然后传递参数”/bin/sh”,这里注意到在程序的getnline这个函数里面有调用strlen
这个函数的参数和system一样是个字符串,因此我们考虑把strlen的got覆盖为system的plt
目前我们有strlen的got:0x08049A54,system的plt:0x08048490,.fini_array:0x08049934,start地址:0x080484F0
先覆盖strlen_got的高16位,覆盖成0x804,需要写入字符数的就是0x804-18-2-4=2020(D),然后写入低16位,需要再写入的字符数是0x8490-0x804=31884(D),再写入fini_array,需要再写入0x84F0-0x8490=96(D)
第二次写入/bin/sh即可
exp
1 | from pwn import* |
如果您喜欢此博客或发现它对您有用,则欢迎对此发表评论。 也欢迎您共享此博客,以便更多人可以参与。 如果博客中使用的图像侵犯了您的版权,请与作者联系以将其删除。 谢谢 !