“攻防世界”pwn之format2

原理:

栈溢出、后门

环境:

ubuntu14

工具:

pwntools 、IDA

步骤:

查看程序的基本信息:

在这里插入图片描述
可以看出程序是32位,斌开了canary和nx

在IDA进行分析查看
“攻防世界”pwn之format2_第1张图片
看到程序并没有canary的压栈,我当时很奇怪为什么,让你后又看了几个函数,发现也没有,后来看大佬的 WP说是部分函数有,这里的canary是个迷惑。这没有canary就方便很多了。
“攻防世界”pwn之format2_第2张图片
一点一点看,发现这就是一个base64解密再MD5加密的程序,如果最后的MD5值一样的则,但是程序里的对应MD5值没有查到对应的明文,而且MD5加密的也不是咱们输入的,而是一个脏数据,也就是“正道”走不通了。
仔细看auth()函数。
“攻防世界”pwn之format2_第3张图片
细看发现v4即decode(s),据里距离ebp只有8个byte,而前面对decode(s)的长度的判断,是要小于0xc即最大为12个字节,也就是我们可以覆盖整个ebp,而无法覆盖ret的地址,我原来以为可以直接覆盖ret地址,后来发现有长度限制。
“攻防世界”pwn之format2_第4张图片
分析发现有后门函数
“攻防世界”pwn之format2_第5张图片
所以我们现在可以利用的就是1、可以覆盖auth()函数里存main()ebp的内容;2、右后门函数。
所以我们想到
可以在auth函数里面,将存main()的ebp位置里的内容覆盖成我们我想要的地址,进而返回到mian()的时候main()的ebp地址就是我们构造的了,进而在main函数结束返回的时候,就会去执行ebp地址+4位置的ret地址。而因为这个ebp地址是我们任意写的,因而ebp地址+4的内用也是可控的,此时我们就可以将ebp+4的内容改成后门函数的地址,进而拿到shell。
要想可控,这个ebp地址只能写成input(=v4)的地址,因为其他变量的地址都是变化的,而input得地址不变且内容是我们输入的字符出base64解密之后的值。
我们还要用v4进行溢出,v4要满足v4=“a”*8+(伪造的ebp地址)
而伪造的ebp地址==&input,我们还要将ebp地址+4的内容写成ret的地址,也就是
input=v4=‘a’*4+(ret)+(&input)这样,当返回到main函数的时候,ebp地址位&input,进而又&input+4=(ret),进而拿到shell.
exp:


```python
from pwn import *
import base64
a='aaaa'
b=0x08049284    #ret地址,即system("./bin/sh)地址
c=0x0811EB40    #&input地址
b=p32(b)
c=p32(c)
format2=base64.b64encode(a+b+c)
print(format2)  #得到我们要输入的s


你可能感兴趣的:(ctf-pwn)