栈溢出的定义:当程序尝试将超过预定大小的数据写入栈上分配的内存区域时,就会导致栈溢出,其危害为:攻击者可以覆盖服务器的重要数据,来控制整个程序的执行流
1.工具
对于PWN,首先就是Linux自带的file、nano和objdump,file的作用是查看二进制文件的信息,nano是文件编辑器,objdump是一个反汇编工具,相当于IDA IDA Free (hex-rays.com)
给大家写一个helloworld.c展示一下file
然后file 1
在此可以看到它是一个64位的ELF文件,interpreter /lib64/ld-linux-x86-64.so.2是他的库,hash是BuildID[sha1]=41e37d56d84755002baf024032f52178f70946d3
objdump -d 1
这样他就反汇编了所有的函数
由于寄存器前有百分号,可以得出他是ATMT格式的,我们可以用objdump -M来指定它的格式,比如指定intel格式
那这样,反出来的就是intel格式的代码,和ida相同
由于-d是直接把所有函数反汇编并返回,有些难浏览,这个时候就可以用--disassemble=xxx来查看指定的函数
此外,还有一个工具是pwmtools,是一个python的库,集成了很多漏洞利用的工具
我们可以用from pwn import *来导入
对于pwn的process这个库,它的作用是运行程序,比如process("1"),就是运行1文件,运行后它会返回一个句柄,我们能通过返回值来对其操作
然后我这里写一个C文件:
创建一个数组,读x10字节,最后输出
效果就是输入什么输出什么
那么我们就可以用py文件来控制这个程序
这个就是打开文件后,输入114514
除了send,还有sendline可以输入,这个是发送一行数据
可以看到多了个换行
除了发数据,还有收数据的函数:recv()
这里可以收114514b大小的数据
这里就返回了114514,如果我把114514改为5,那么他只能打印11451
对应着sendline,pwntools还有个recvline()函数,这里就不过多赘述
然后对于interactive,如果我们不加这个函数,运行技术以后程序就会自动退出,不会显示$
interactive很重要,当我们拿到shell时,它可以让shell保持存活
此外,pwn还有context函数,如:
context.os = "linux" ##系统为linux
context.arch = "amd64" ##架构为amd64
context.log_level = "debug" ##调试等级为debug
context默认是linux系统,i386(32位)
我们都知道,程序运行的时候会有进程号,那么可以用gdb.attach来调试
除了以上三个工具,还有一个是gdb
开启gdb以后,我们可以在里面用file指定要调试的目标程序
然后我们可以在gdb里面r/run,就是运行这个程序
如果程序被终端,可以用c/continue继续运行
此外还有n,n是逐行的运行程序(C语言方面的)
如果程序有调试符号的话可以用汇编模式来调试(ni/si)
如果没有调试符号,以上全部命令效果相同
然后就是b,用于打断点
打断点后面要有一个地址(16进制),比如b *0x1111或b main,gcc打包的时候我们可以跟一个-g,这样文件就有调试符号了,可以使用b来调试
这样0x115d就有两个断点
取消断点可以用clear
打断点之后,程序就会在这里停止
如果要打印数据的十进制,就可以用p
p/x就是以十进制打印
然后x,x是打印地址里面的函数用的,x/20就是打印20条,x/20g是 每一组数据是八个字节x/20gx就是显示为16进制
如果g改为w,那么一组就是4字节
直接x/20i就是打印汇编代码
2.栈溢出漏洞利用
首先我写一个存在栈溢出的文件:
运行结果如上
开始渗透,直接ida看main函数
我推测,可以直接覆盖到输出success的地方
跟进success
可见,0000000000002022就是输出success的地址
然后创建个1.txt,构建20字节的内容,最后四个字节要改成要覆盖的地址,也就是00 00 20 22
给这个数据输入进去:
也是运行失败了,那么再细看:
栈地址已被成功修改
之后,继续运行会报错,原因是覆盖过程中将原EBP也覆盖了,那么main函数找不到EBP,也就找不到之前输入的值,最后输出success
栈溢出基础部分到这里就讲完了,希望对各位师傅有所帮助
欢迎各位师傅加入我们的交流群
原文始发于微信公众号(黄豆安全实验室):PWN基础入门/栈溢出漏洞简单利用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论