![cover](https://img-blog.csdnimg.cn/66e2ea6118514c999fb31538c8d89e54.png)
PWN入门(1)基础知识和环境设置
pwn"这个词的源起以及它被广泛地普遍使用的原因,源自于魔兽争霸某段讯息上设计师打字时拼错而造成的,原先的字词应该是"own"这个字,因为 ‘p’ 与 ‘o’ 在标准英文键盘上的位置是相邻的,PWN 也是一个黑客语法的俚语词,是指攻破设备或者系统。发音类似"砰”,对黑客而言,这就是成功实施黑客攻击的声音,而在ctf比赛里,pwn是对二进制漏洞的利用。
简介
“pwn"这个词的源起以及它被广泛地普遍使用的原因,源自于魔兽争霸某段讯息上设计师打字时拼错而造成的,原先的字词应该是"own"这个字,因为 ‘p’ 与 ‘o’ 在标准英文键盘上的位置是相邻的,PWN 也是一个黑客语法的俚语词,是指攻破设备或者系统。发音类似"砰”,对黑客而言,这就是成功实施黑客攻击的声音,而在ctf比赛里,pwn是对二进制漏洞的利用
缓冲区溢出
当系统向缓冲区写入的数据多于它可以容纳的数据时,就会发生缓冲区溢出或缓冲区溢出,用更简单的话说就是在程序运行时,系统会为程序在内存里生成一个固定空间,如果超过了这个空间,就会造成缓冲区溢出,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,甚至可以取得系统特权,进而进行各种非法操作。
关于缓冲区更多的解释,可以看我之前这一篇文章(用简单易懂的话语来快速入门windows缓冲区溢出)
https://blog.csdn.net/qq_45894840/article/details/123373180?spm=1001.2014.3001.5502
从这个显示图里可以看到缓冲区溢出的过程,在进行缓冲区溢出攻击后,缓冲区(buffer)里的字符向上溢出到了返回函数,从而导致程序错误,我们还可以利用这个返回地址,来达到远程入侵的目的
环境安装
gdb
gdb是一个linux的动态调试器,可以调试各种二进制文件
apt install gdb
pwndbg
pwndbg是一个 GDB 插件,它可以减少使用 GDB 进行调试,重点关注低级软件开发人员、硬件黑客、逆向工程师和漏洞利用开发人员所需的功能
git clone https://github.com/pwndbg/pwndbg
cd pwndbg
./setup.sh
cd ..
mv pwndbg ~/pwndbg-src
echo "source ~/pwndbg-src/gdbinit.py" > ~/.gdbinit_pwndbg
pwntools
pwntools是一个模块,可以让我们写脚本时更加方便
python3 -m pip install --upgrade pwntools
动态调试
下载这个github库,进入第一个目录
https://github.com/Crypto-Cat/CTF/tree/main/pwn/binary_exploitation_101
这里可以看到两个文件,第一个是编译后的文件,第二个是源文件
我们用vim打开源文件看看
vim vuln.c
这是一个非常简单的c语言程序
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[16]; //定义了一个变量,名为buffer,有16个字节的缓冲区
printf("Give me data plz: \n"); //输出字符Give me data plz:
gets(buffer); //获取我们输入的字符,并存入到buffer变量里
return 0;
}
乍一看是不是没什么问题,其实是函数的问题
gets
在gets函数的官方文档里,有这么一句话:
永远不要使用gets函数,因为如果事先不知道数据,gets将就无法判断读取多少个字符,因为gets将继续存储字符当超过缓冲区的末端,使用它是极其危险的,它会破坏计算机安全,请改用fgets。
用之前的图片来解释
程序信息
我们输入超过16个字节,缓冲区(buffer)就会向上溢出,覆盖程序本来正常的内容,从而造成程序崩溃
然后我们查看一下编译后的文件信息
file vuln
这是一个32位的可执行程序
intel x86架构的
动态链接,意思是程序内的函数都是在链接库里调用的,而不是本身就自带的
链接库地址为/lib/ld-linux.so.2
没有开启stripped,意思是如果我们用gdb去调试这个程序,可以看到函数名称,可以更方便的分析程序
使用checksec工具可以查看程序更详细的信息
从上到下依次是
32位程序
部分RELRO,基本上所有程序都默认的有这个
没有开启栈保护
未启用nx,nx:数据执行
没有pie,意思是程序的内存空间不会被随机化
有读,写,和执行的段,意思是我们可以在程序里写入shellcode
现在我们执行程序,输入16个以上的字符试试
可以看到,程序已经报错了,因为我们溢出后覆盖了程序原本的一些参数
使用gdb调试程序
现在我们使用gdb来动态调试程序
gdb vuln
然后我们查看程序里所有调用的函数
info functions
然后查看主函数main的汇编代码
disassemble main
然后在main函数开头下一个断点,方便我们调试,断点的意思是程序运行时,遇到断点处会停下来
b main
run //运行程序
第一段是显示了寄存器里的所有内容,寄存器是内存中非常靠近cpu的区域,因此cpu可以快速访问它们,但是在这些寄存器里面能存储的东西非常有限
第二段是当前程序停下来的位置和程序的汇编代码地址
第三段是查看当前堆栈里的内容
输入next执行下一个汇编指令
或者一直输入n来到fget函数执行的地址
输入一大堆A看看
可以看到,寄存器里的值都被A覆盖了
但最重要的是EIP这个寄存器,他是程序的指针,指针就是寻找地址的,指到什么地址,就会运行该地址的参数,控制了这个指针,就能控制整个程序的运行
静态调试
在linux里,我们可以使用ghidra这个工具来静态调试程序
下载地址:
https://github.com/NationalSecurityAgency/ghidra
程序安装和基本使用可以看我之前写过的文章(Ghidra逆向分析工具使用与实战)
https://blog.csdn.net/qq_45894840/article/details/124556441?spm=1001.2014.3001.5502
看我那篇文章创建了工作组后导入这个程序
然后双击进入分析
选择yes,对程序进行默认解析
在函数这个文件夹可以找到程序调用的所有函数
点击main,中间的是汇编界面,右边是伪代码界面,通过分析汇编函数,程序会自动生成伪代码来帮助我们理解程序,可以看到,这里的伪代码和程序的源文件代码很相似
在程序的window窗口可以查看程序里所有的字符串
单击后点击字符串被调用的地址就可以立即跳转到调用地方
总结
有什么不会或者是错误的地方的可以私信我,看到必回
![Logo](https://devpress.csdnimg.cn/79de2bf0b7994defa4242ef90d5513fa.jpg)
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)