格式化字符串漏洞学习
2019-02-09 本文已影响0人
小白King
一些小技巧和知识:
![](https://img.haomeiwen.com/i9085575/ecb4cb1ae7523d0a.png)
![](https://img.haomeiwen.com/i9085575/b4f946cef413fa4e.png)
![](https://img.haomeiwen.com/i9085575/0e979517f23356b9.png)
计算偏移量:
找漏洞函数printf家族,在printf(s)中下断点,然后输入AAAA,在gdb中计算偏移量:
p/d (0xbbbb-0xaaaa)/4
新姿势之替换got表的真实地址:
payload = fmtstr_payload(offset ,{xxx_got:system_addr})
新姿势之任意写:payload = p32(magic_bss) + '%214c' + %7 x"(泄露真实地址)
%A$n,是把栈地址的内容进行修改,如果内容是地址,就改这个内容地址里面的东西
![](https://img.haomeiwen.com/i9085575/4925077771a77e4b.png)
练习题:LAB7:
按照惯例分析一波,checksec,拖进ida分析:
![](https://img.haomeiwen.com/i9085575/6e8cedaaf74977ef.png)
![](https://img.haomeiwen.com/i9085575/61f7450ecc6ced0c.png)
开启栈溢出保护,但是有格式化字符串漏洞可以用。
分析逻辑大概可以知道是输入名字和密码,正确的密码是文件中的随机数,先从文件中读取出来放到password里面,自己输入的密码则放在栈的ntpr中,然后进行比较,很明显是printf的格式化字符串漏洞,介绍两种方法:第一种找到password的地址直接修改password的值为1,第二种直接泄露出password的随机值:
即可构造payload:
![](https://img.haomeiwen.com/i9085575/1fb28eedd10c4af3.png)
![](https://img.haomeiwen.com/i9085575/b28eb3e09a214421.png)
因为我们泄露的随机数可能 大于4位,而我们泄露的只到4位,所以有时成功不了~但是方法一是绝对可以的。
练习题LAB8:
还是按照套路和逻辑来,栈溢出保护,格式化字符串漏洞~
![](https://img.haomeiwen.com/i9085575/4a3987c3803018af.png)
![](https://img.haomeiwen.com/i9085575/e1bf5a859e58ceab.png)
接下来分析逻辑:
![](https://img.haomeiwen.com/i9085575/2973a13ad2c9828a.png)
很清晰的逻辑,要么修改magic的值,要么直接调用system函数。
在printf那里下断点,计算出偏移量为7,直接上payload:
![](https://img.haomeiwen.com/i9085575/be284f1f10967c7d.png)
![](https://img.haomeiwen.com/i9085575/7bdb2c838f7a2e9e.png)
练习题LAB9:
逻辑一样,checksec,再拖进去ida分析:
![](https://img.haomeiwen.com/i9085575/b91bed7a8b14dbc5.png)
![](https://img.haomeiwen.com/i9085575/43529838ea9c021f.png)
发现是在bss段
由于第一次遇见在bss段中,所以无法直接利用格式化字符串漏洞向栈中写入数据,只能利用间接地写入,在printf那里下一个断点,找到ebp的地址,作为每一次返回的使用:
![](https://img.haomeiwen.com/i9085575/0914d8dbfc829f24.png)
来进行构造:
这里有用的就是这四条,分别是设置为ebp1、fmt7、ebp2、fmt11,而他们相对于格式化字符串的偏移分别是6、7、10、11(直接数),思路如下:
1.通过ebp_1使ebp_2指向fmt_7
2.通过ebp_2将fmt_7处的内容覆盖成printf_got
3.通过ebp_1使ebp_2指向fmt_11
4.通过ebp_2将fmt_11处的内容修改成printf_got+2
5.通过fmt_7将printf_got地址泄露出来
6.计算出system函数的地址 ,将system函数地址写入printf在got表的地址
具体做法是将 system函数地址的前两个字节写入fmt_7,后两个字节写入 fmt_11
7.执行printf函数相当于执行system函数
8.输入"/bin/sh"字符串,让system函数从栈中取参数getshell
我们一步一步地分析思路,首先%数字
![](https://img.haomeiwen.com/i9085575/67152da493af1d79.png)
![](https://img.haomeiwen.com/i9085575/b13f1ee23c43fe85.png)
![](https://img.haomeiwen.com/i9085575/8f4359fda058ba1b.png)
![](https://img.haomeiwen.com/i9085575/a72dc0a7f2ffd5c6.png)
在这里解释下那个str(printf_got&0xffff)操作,是获得低位的两个字节,(高位是不变的情况下),例如原操作数是printf_got=0x12345678,那么printf_got&0xffff=0x5678,
![](https://img.haomeiwen.com/i9085575/5f2d83c590b3ade5.png)
这里是因为%A