前言:
某些实用小技巧,虽然不能让你直接控制程序执行流,但是在pwn之前的信息搜集比较有用。大多原理比较简单,但是很杂乱,在这里整理一下吧,主要当笔记用,不定时更新。我也是不是安全专业的,学习中,写错了请大家指正。
利用输出函数泄露栈地址:
有个专门的漏洞叫格式化字符串漏洞,但是这里虽然也是个漏洞但更加初级和简单,我们只是想泄露点栈上的地址而已,而且利用给原理稍有不同。
为什么要泄露栈上的地址:因为有时候需要向某个地址写入字符串“/bin/sh”,所以需要一个相对于old ebp的地址。也可能是为了泄露canary,从而绕过保护。
原理:类似printf函数和puts函数输出字符串的时候是遇到‘\x00’才会截止输出,如果我们能将这些‘\x00’覆盖成别的东西,那么后边的一些数据就会被连带着输出。
举个例子:我们目标是打印出old ebp
//printleck.c
#include <stdio.h>
#include <unistd.h>
void vul()
{
char s[6];
read(0,s,100);
printf("%s",s);
}
int main()
{
vul();
return 0;
}
gcc -g -m32 -z execstack -z norelro -fno-stack-protector -no-pie -fno-pie printleak.c
在vul函数打断点:
图1
图1就是vul函数里的汇编指令,根据汇编指令发现ebp-0xe就是缓冲区s的首地址,所以我们填充0xe的数据就能将old ebp连带打印出来。
先看一下还没输入时的栈布局:
图2
然后输入123456789abcde
图3
从图3中看,绿框中就是我们输入的数据了,可以看到输入的数据刚好没有覆盖old ebp,然后下一步单步执行,就打印出了红框的东西,由于old ebp的地址转换为字符后是不可见字符就打印出了乱码。我们由此就获得了old ebp的地址!