基于windows _ XP-slmail服务的缓冲区溢出实践。
一次基于windows_xp--SLmail服务的缓冲区溢出实践
20191331lyx
一、基本概念
缓冲区溢出:当缓冲区边界限制不严格时,由于变量或程序运行错误引入的异常数据,缓冲区被填满并覆盖相邻内存区域的数据。它可以修改内存数据、导致进程劫持、执行恶意代码、获取服务器控制权限等。
Windows XP或2k3服务器中的SLMail 5.5.0 Mail Server程序的POP3 PASS命令存在缓冲区溢出漏洞,因此无需身份验证即可实现远程代码执行。
Win7以上系统的防范机制可有效防止该缓冲区漏洞的利用:
DEP:防止从数据页执行代码;
ASLR:在随机内存地址加载执行器和dll,每次重启地址都会改变。
二、实验环境准备
(1)攻击机:kali。
(2)目标机器:windows xp(关闭防火墙)。
目标飞机的环境准备;
邮件服务:SLMail 5.5.0邮件服务器。
调试工具:免疫调试器_ 1 _ 85 _ setup.exe。
链接跟踪工具:mona.py
SLmail安装:
将本地帐户导入邮件服务器:
检查SLMail的端口是否正常打开。
检查邮件相关服务是否已启动。
将mona.py复制到免疫调试器的PyCommands目录中。
连通性测试
三、缓冲区溢出攻击
使用nc验证端口连接是否正常,并测试pop3命令的执行情况。
测试PASS命令在接收大量数据时是否溢出。
EIP寄存器:存储下一条指令的地址。
pop3邮件服务监听端口110和进程标识832。
使用免疫调试器。
文件-附加-选择pid号为832的进程-附加调用。
监控程序的运行状态。
明确思路
利用原理:在“PASS”命令后,当输入一些特殊的自定义命令时,会造成缓冲区溢出,并上传shellcode,可以控制目标系统,所以不需要经过身份验证,也不需要获取权限。
(1)编写测试脚本,使用socket自动连接。
(2)增加发送的数据量,通过Debug判断是否会溢出。
观察EIP确认溢出
EIP的41是十六进制数,换算成字母就是a,也就是说此时EIP寄存器全部填满了A和ESP寄存器也被填满了A每四个字节作为一个存储单元存储,EIP是当前邮件服务器SLmail要执行的下一条指令的内存地址,所发送的A把下一条指令的内存地址给覆盖了.发生缓冲区溢出此时cpu会在EIP所在的内存地址中查找指令代码, 并且指令内存已经被a完全覆盖,此时程序会崩溃,无法继续运行。
我们可以用shellcode填充EIP寄存器地址,这样就可能控制目标机器.
请注意,每次溢出都会导致服务崩溃,因此有必要在每次实验之前重新启动SLmail服务。
(3)准确定位溢出的四个字节。
使用唯一字符串方法,您可以在Kali Linux的/usr/share/metasploit-framework/tools/exploit/pattern _ create . Rb脚本中生成唯一字符串:
调试中发现溢出字节8Di9。
计算偏移量
的精确匹配偏移量为2606,即前面有2606个字符,即8Di9中的8是第2607个字符。
(4)确认和验证。
缓冲区='A' * 2606 'LYXQ' 'C'*20
前2606个字符用A替换,后4个字符用B替换,后20个字符用C替换,确认LYXQ是否能准确写入EIP寄存器。
确认
下一步思路:被修改为壳码的内存地址,壳码被写入地址空间。程序读取EIP寄存器值,跳转到shellcode段并执行它。
寻找存储shellcode的内存空间(考虑ESP),修改EIP指向ESP所在的shellc。
ode内存空间。
(5)修改字符C的填充量,判断内存空间大小能否存放shellcodebuffer = 'A' * 2606+'LYXQ'+'C'*(3500-2606+4)
让C去填满ESP的内存空间,判断C的个数。
可以看到ESP起始地址为:01E7A154 终止地址为:01E7A2F4
使用结束地址01E7A2F4的后三位2F4减去开始地址01E7A154的后三位154,结果再转化为十进制,得结果为416
意味着ESP空间大小为416字节可以放下一个shellcode
(6)查找坏字符
由于不同类型的程序、协议、漏洞,会将某些字符认为是坏字符,这些字符有固定用途。如:
null byte (0x00)空字符,用于终止字符串的拷贝操作;return (0x0D)回车操作,表示POP3 PASS指令操作完毕。
而,返回地址、shellcode、buffer都不能出现坏字符。
所以我们筛查坏字符,发送0x00-0xff 256个字符进行筛查。
验证得0A 为坏字符 ;0D为坏字符不出现,缩进一格,全部检查,发现00也被过滤,则可发现该实验中坏字符为:0x00 0x0D 0x0A
(7)重定向数据流
重定向数据流,用ESP的地址替换EIP的值,但是ESP的地址是变化的,不能使用硬编码。在SLMali线程应用程序中,操作系统为每个线程分配一段的地址范围,每个线程地址范围不确定。
所以我们可以从内存地址中寻找固定的系统模块,在模块中寻找JMP ESP指令的地址跳转,再由该指令间接跳转到ESP,从而执行shellcode。
JMP ESP是汇编指令,需要使用kali将其转换为二进制。
!mona find -s "\xff\xe4" -m openc32.dll:在该进程模块查找是否有执行JMP ESP的命令
通过检查openc32.dll进程模块中没有可以执行JMP ESP的命令。
继续查找发现SLMFC.DLL支持执行JMP ESP的命令,并且有20个内存地址可以执行。
打开内存地图,找到SLMFC模块的基地址5F400000,可以看到该内存中存放的是一个pe文件头。地址5F401000存放code。
找到JMP ESP地址为5F4B41E3。
(8)生成shellcode
这里为了绕过防火墙生成一个反弹shell
过滤坏字符并重新编码编码(将病毒的特征字符冲编写,可以在一定程度上实现免杀)
(9)缓冲区溢出攻击
将shellcode放入脚本。
建立本地侦听 nc -nvlp 8888
执行脚本发送shellcode
缓冲区攻击成功,成功拿到靶机shell。
四、实践体会:
缓冲区溢出攻击,是利用“缓冲区溢出漏洞”所进行的攻击行动。“缓冲区溢出”是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用“缓冲区溢出”进行攻击,可以导致程序运行失败、系统关机、重新启动等后果。
缓冲区溢出,是指当计算机向缓冲区内填充数据位数时,超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上。理想的情况是:程序会检查数据长度,而且并不允许输入超过缓冲区长度的字符。但是绝大多数程序都会假设数据长度,总是与所分配的储存空间相匹配,这就为“缓冲区溢出”埋下了隐患。
操作系统所使用的缓冲区,又被称为“堆栈”,在各个操作进程之间,指令会被临时储存在“堆栈”当中,“堆栈”也会出现缓冲区溢出。
缓冲区溢出的危害非常大,通过植入并且执行攻击代码。攻击者可以利用“堆栈溢出”,在函数返回时,改变返回程序的地址,让其跳转到任意地址。这带来的危害,一种是程序崩溃导致拒绝服务;另外一种就是跳转并且执行一段恶意代码,然后得到shell,为所欲为。
五、思考
在进行程序设计时,为了防范缓冲区溢出攻击,可以采用哪些方法
1、强制写正确的代码的方法
谨慎使用各种可能导致缓冲区溢出的函数,系统调用等。增加代码的健壮性,规范性,安全性。
2、通过操作系统使得缓冲区不可执行,从而阻止攻击者植入攻击代码
3、利用编译器的边界检查,来实现缓冲区的保护
4、在程序指针失效前进行完整性检查
5、定时检查你的计算机,关闭不必要的系统服务,并监控好已开启的服务
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/61491.html