*本文原创作者:Traxexsc,本文属于1024rd原创奖励计划,禁止转载
本文介绍一个在xp下的对sqmail的缓冲区溢出漏洞利用的完整过程,帮助新手更好的理解缓冲区溢出漏洞的原理以及应用方式。大牛请绕过。
环境:windows xp
SLMail 5.5.0
mona.py(将mona脚本放到/Immunity Inc/Immunity Debugger/PyCommands目录下)
ImmunityDebugger_1_85_
首先确保pop3服务已经启动,关闭xp的防火墙
然后,我们先打开kali,利用nc手动连接该服务,看看会发生什么
我们发现,我们可以输入用户名和密码来访问xp上的pop3服务
缓冲区溢出大家应该或多或少都有些了解,我们可以输入一串很长很长的字符,使系统的栈发生溢出,从而利用该漏洞,这里我们测试PASS 这里的溢出漏洞。
然后我们打开ImmunityDebugger,点击attach

打开我们的slmai服务,右键attach


但是我们怎么知道输入多少个字符的时候,会发生溢出呢?这时候我们需要先写一个python的小脚本,

这个脚本可以取代我们来访问slmail

我们发现该脚本成功运行了,接下来,我们就需要让我们的脚本自动化的增加字符串的数量,来测试到底PASS的字符到达多少时,会发生溢出漏洞
这时候我们首先要在我们的ImmunityDebugger下点击红色的运行按钮,让我们的slmail跑起来

打开第二个脚本
脚本的代码很简单,就不做解释了,运行我们的脚本,

我们可以发现,当输入的PASS字符为2700的时候,程序不会在运行下去了,在xp下的slmail崩溃了
这时候打开我们的imdebug查看一下,注意右上角的寄存器窗口

我们发现,EIP寄存器内充满了4141,而41,其实就是我们A的ASCII码,我们可以推测出,当我们发送的字符串为2700个A的时候,缓冲区发生了溢出,这里先解释一下eip寄存器,EIP寄存器存放该进程的下一步要执行指令的地址,在这里我们就可以利用EIP寄存器,存放我们想要执行的shellcode的地址,这样就可以达到控制该系统的目的。那么问题来了,EIP寄存器内的A到底是2700个字符串内的第几个A呢?因为只有当我们知道EIP寄存器内的A的位置,我们才可以将我们想令程序执行的地址精确的填入到该寄存器当中,这里我们可以用2分法来测字符的位置,比如先测2600,2600不对测2650。。。我们也可以用唯一字符串法,就是说我们发给pass的2700个字符串里四个为一组,这四个字符串唯一,这样我们也可以来确定位置,kali下也有现成的工具。
这里需要大家注意一个问题:每次我们发送完我们的python脚本,slmail都会崩溃,所以我们需要重启我们的pop3服务
有时候pop3会被直接打挂,这时候启动即可。
这时候我们先在kali下创建唯一字符串

打开我们的三号脚本
![]()
重启pop3,重新打开imdebug运行smail(别忘记点红色的小箭头),然后运行我们的三号脚本
再次观察我们的EIP寄存器


里面的数字为39694438
再次打开我们的kali
由此我们可以知道,从第2606个开始,就是打入EIP寄存器的字符的位置,来验证一下,运行我们的四号脚本,别忘记重启服务

再来看一下我们的寄存器

看来我们判断正确了,EIP寄存器放入了四个大写字母B
这个时候,我们再关注一下ESP里面的内容,我们发现那里面放入了我们跟在4个B后面的20个C,这时候我们就应该有点思路了,只要我们在eip里面放入esp的地址,再在esp内放入我们的shellcode,那么不就可以拿到系统权限了吗?当然,我们先来判断一下esp有多大,够放下我们的shellcode吗?
重启服务,将我们刚才的脚本的20个c改为200个c,运行。
点击我们的esp


选择follow in dump
把目光聚到左下角的窗口,改一下显示的格式

用计算器减一下地址,我们就可以判断出esp的大小了,这里放一个shellcode绰绰有余了,
但是还有一个问题不能忽视,我们都知道,程序运行的时候会碰到一些坏字符,这些字符会阻止程序的运行,如果让这些坏字符出现在我们的shellcode里面,那我们不依然无法执行shellcode吗?那么首先我们先来判断一下哪些是坏字符,运行我们的脚本


我们向slmail发送所有的16进制字符,别忘记重启服务和debug
还是向刚才一样follow in dump以后关注左下角的窗口

我们发现到09仍然是正常的,但是后一个就不正常了,这就说明我们的0a是坏字符,同理,
我们一共可以找出三个坏字符他们分别是
0A 0D 00那么我们是否可以开始写我们的shellcode了呢?
还没有!
多试几次我们就可以悲催的发现,esp的地址是在改变的,那么我们就无法将eip的地址改为esp的地址来运行我们的shellcode了。
这时候我们要进行一下绕过,我们如果可以在系统模块内找到能跳转到esp的指令,那么只要我们将eip寄存器里的内容改为跳转到esp指令的模块的地址,我们不就可以再次的执行我们的shellcode了吗?
我们的mona脚本要起作用了,
先重启服务,跑起来我们的smail
左下角输入指令

我们可以发现系统正在运行的模块都出现了,那么如何找到合适的模块呢,先介绍一下上面的参数
rebase(操作系统重启以后是否发生变化,如变化,则为true,否则为false)这里寻找false的
safeseh aslr nxcompat 是操作系统的安全机制,都选false
OS dll表示每个操作系统都有的这里都选为TRUE
但是我们必须输入汇编语言的机器指令才可以寻找,所以再次用我们的kali帮忙

然后开始搜索合适的模块,
试了一下第一个合适的模块,没有找到我们想要的指令,别气馁,再找下面的
成功找到了一个包含jmp esp指令的模块
随便取一个jpm指令的位置来验证一下,首先我们要下一个断点。双击想要的指令,然后修改一下视图
点击第一条指令jmp esp

点击on acess下一个断点。
然后运行我们的脚本

运行完以后我们可以发现debug的右下角

程序暂停了,按F7进行下一步
在右上角的视图中我们可以发现下一步要执行的地址就是我们ESP寄存器的地址
看来我们通过系统模块跳转到esp寄存器的想法实现了,
接下来来写我们的shellcode,还是靠我们的kali帮忙
当然我们需要去掉我们的坏字符。

这就是我们的shellcode了,然后我们在写一个小脚本


这里大家会发现我在buffer里面增加了/x90,这个是为了防止esp执行的时候把我的shellcode的前面几个字符忽略掉
用nc侦听我们的443端口,
运行我们的脚本

大功告成,想干什么就干什么了!
当然有些人觉得命令行不舒服,那么我们当然可以利用远程桌面来控制我们的服务器,
先通过修改注册表的方式来开放我们的3389端口
echo Windows Registry Editor Version 5.00>>3389.reg
echo [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Terminal Server]>>3389.reg
echo "fDenyTSConnections"=dword:00000000>>3389.reg
echo [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Terminal Server/Wds/rdpwd/Tds/tcp]>>3389.reg
echo "PortNumber"=dword:00000d3d>>3389.reg
echo [HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Terminal Server/WinStations/RDP-Tcp]>>3389.reg
echo "PortNumber"=dword:00000d3d>>3389.reg
regedit /s 3389.reg
一.新增用户:
net user 用户名 密码 /expires:never /active:yes /add二.归属于用户组:
上述命令执行后,会默认归属到users用户组,若要将其归属到Administrators用户组,则其命令如下:
net localgroup Administrators 用户名 /add


大功告成 !
*本文原创作者:Traxexsc,本文属于1024rd原创奖励计划,禁止转载