Re: Telnetd AYT overflow scanner and linux telnet 0.17

From: H D Moore (hdmat_private)
Date: Tue Jul 31 2001 - 11:02:56 PDT

  • Next message: Blue Boar: "Administrivia #14344"

    Linux telnetd is very buggy, whether or not it is exploitable is a different 
    story.  By sending many AYT's, you overwrite the netoprintf variable with the 
    string "\r\n[ hostname : yes]\r\n", which will eventually cause a crash when 
    it hits something important.  First off, some background:
    
    The telnetd I tested was from the SuSE 7.1 netkit package (0.5.1), I am not 
    sure what the "real" version of this code is.
    
    The telnetd bug is not immediately exploitable through the initial buffer 
    overflow, yes you can smash the stack, but no you cant control the data.
    
    [ nkit-0.5.1/telnetd/utility.c line 55 ]
    _______________________________
    void
    netoprintf(const char *fmt, ...)
    {
       int len, maxsize;
       va_list ap;
       int done=0;
    
       while (!done) {
          maxsize = sizeof(netobuf) - (nfrontp - netobuf);
    
          va_start(ap, fmt);
          len = vsnprintf(nfrontp, maxsize, fmt, ap);  /* overflow is here */
          va_end(ap);
    
          if (len<0 || len==maxsize) {
    	 /* didn't fit */
    	 netflush();
          }
          else {
    	 done = 1;
          }
       }
       nfrontp += len; /* no sanity checks are done */
    }
    _______________________________
    
    
    By sending around 2000 "ayt" requests at once, the nfrontp pointer is moved 
    far enough to smash the return address.   An interesting side effect is the 
    maxsize variable starts going into the negatives, alhtough it doesnt seem to 
    affect the *nprintf functions..  
    
    A remote attacker cannot control the fmt string or argument passed to this 
    function, with the "ayt" overflow, they are:
    
    fmt = "\r\n[%s : yes]\r\n"
    args = HOSTNAME (whatever the hostname is)
    
    [ this is the current stack, we overflow netobuf ]
    netobuf (8254)
    pcc (30)
    ptyobuf (8254)
    ncc (30)
    subbuffer (510)
    envinit (30)
    progname (30)
    ptyibuf (???)
    
    Gcc seems to be alocating 30 bytes to each integer, whether this is because 
    of the -ggdb options I compiled with or some normal padding, I don't know. A 
    normal (4000 ayt's) only seems to get about halfway into subbuffer before the 
    program exits.
    
    pcc and ncc are int's
    
    pcc = read from tty byte count
    ncc = read from network byte count
    ptyobuf = pty output buffer
    
    How to calculate the number of bytes each AYT request causes to be written to 
    netoprintf:
    
    (strlen(hostname) + 12) * ayt
    
    To exploit this, you would need to use the AYT overflow to overwrite one of 
    the internal stack variables (and create a secondary vulnerability), then 
    exploit this newly created vulnerability to launch a shell.  
    
    The path to /bin/login is stored under the memory address we can write to, so 
    there is no chance of just rewriting /bin/login to /bin/sh or something ;)
    
    Any ideas on how to exploit this?
    
    -HD
    
    http://www.digitaldefense.net (work)
    http://www.digitaloffense.net (play)
    
    On Tuesday 31 July 2001 12:52 am, Dawes, Rogan (ZA - Johannesburg) wrote:
    > [Resent after 4 days passed and not seen on the list]
    >
    > Hi,
    >
    > I ran the Perl code supplied by David Maxwell (on Bugtraq) against Linux
    > with telnet 0.17-7,
    > and saw some funny results.
    



    This archive was generated by hypermail 2b30 : Tue Jul 31 2001 - 11:36:58 PDT