PoPToP PPTP server remotely exploitable buffer overflow

From: Timo Sirainen (tssat_private)
Date: Wed Apr 09 2003 - 09:19:33 PDT

  • Next message: Daniel Ahlberg: "GLSA: samba (200304-02)"

    Versions older than 1.1.4-b3 and 1.1.3-20030409 affected. This seems to be
    exploitable only with Linux.
    
    PPTP?
    -----
    
    PPTP-over-IPSEC is commonly used to create VPNs. Windows plays quite nicely
    with it.
    
    
    problem
    -------
    
    PPTP packet header contain 16bit length which specifies the full size of
    the packet:
    
    	bytes_this = read(clientFd, packet + bytes_ttl, 2 - bytes_ttl);
    	// ...
            bytes_ttl += bytes_this;
    	// ...
    	length = htons(*(u_int16_t *) packet);
    	if (length > PPTP_MAX_CTRL_PCKT_SIZE) {
    	  // abort
    	}
    
    Looks good so far, except:
    
    	bytes_this = read(clientFd, packet + bytes_ttl, length - bytes_ttl);
    
    If given length was 0 or 1, the "length - bytes_ttl" result is -1 or -2,
    which means that it reads unlimited amount of data from client into
    "packet", which is a buffer located in stack.
    
    The exploitability only depends on if libc allows the size parameter to be
    larger than SSIZE_MAX bytes. GLIBC does, Solaris and *BSD don't.
    
    
    tips of the day
    ---------------
    
    Don't do arithmetic in parameters specifying buffer size.
    
    Block PPTP port for non-IPSEC connections, if you don't already.
    
    
    patch
    -----
    
    This is the same as in latest versions:
    
    --- ctrlpacket.c.old	1999-12-23 23:43:33.000000000 +0200
    +++ ctrlpacket.c	2003-04-09 18:58:21.000000000 +0300
    @@ -254,8 +254,8 @@
     	}
     	/* OK, we have (at least) the first 2 bytes, and there is data waiting */
     	length = htons(*(u_int16_t *) packet);
    -	if (length > PPTP_MAX_CTRL_PCKT_SIZE) {
    -		syslog(LOG_ERR, "CTRL: Control packet > PPTP_MAX_CTRL_PCKT_SIZE (length = %d)", length);
    +	if (length <= 10 || length > PPTP_MAX_CTRL_PCKT_SIZE) {
    +		syslog(LOG_ERR, "CTRL: 11 < Control packet (length=%d) < ", length);
     		/* we loose sync (unless we malloc something big, which isn't a good
     		 * idea - potential DoS) so we must close connection (draft states that
     		 * if you loose sync you must close the control connection immediately)
    



    This archive was generated by hypermail 2b30 : Wed Apr 09 2003 - 22:05:22 PDT