source: trollforge/misc/scansyn_tx.c @ 666

Revision 605, 9.6 KB checked in by literalka, 16 months ago (diff)

more sorting, jesus fuck

Line 
1/* sloth@ww88.org - 01/05/2010
2 *
3 * Product of the GNAA
4 *
5 * Receiver code isn't done but this works just fine:
6 * tcpdump -i eth0 -n -s 50 dst port <your port> and 'tcp[13] = 18'
7 *
8 * Spoofed TCP SYN scan to offload ip reputation hits from port scanning
9 * use your fast server to send the packets and use your cheap DSL/VPS
10 * to listen for the SYN/SYNACK.
11 */
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <unistd.h>
17#include <netdb.h>
18#include <netinet/in.h>
19#include <arpa/inet.h>
20#include <sys/socket.h>
21#include <sys/time.h>
22#include <sys/types.h>
23#include <sys/select.h>
24#include <signal.h>
25#include <time.h>
26
27struct ip_header {
28  uint8_t  len:4,
29           version:4;
30  uint8_t  tos;
31  uint16_t tot_len;
32  uint16_t id;
33  uint16_t frag_off;
34  uint8_t  ttl;
35  uint8_t  protocol;
36  uint16_t sum;
37  uint32_t saddr;
38  uint32_t daddr;
39} __attribute__((packed));
40
41struct tcp_header {
42  uint16_t sport;
43  uint16_t dport;
44  uint32_t seq;
45  uint32_t ack_seq;
46  uint8_t  len;
47  uint8_t  flags;
48  uint16_t win;
49  uint16_t sum;
50  uint16_t urg;
51} __attribute__((packed));
52
53struct tcp_packet {
54  struct ip_header iph;
55  struct tcp_header tcph;
56};
57
58struct Receiver {
59  struct in_addr       addr;
60  uint16_t             sport;
61  int                  sock;
62  struct tcp_packet    *tcp_packet;
63  struct sockaddr_in   sin;
64};
65
66uint32_t tot_count = 0, last_count = 0;
67uint8_t  timer = 10;
68
69void usage(char *message) {
70  fprintf(stderr, "usage: ./flood_ns [options]\n"
71         "  -r <ip>/<bitmask>  * random scan ex: 192.168.1.0/24\n"
72         "  -p <port>          * scan port\n"
73         "  -l <filename>      * host[:port] list of receivers\n"
74         "  -u <number>        * random scan reusable seed\n"
75         "  -C <number>        * random scan resume count\n"
76         "%s", message ? message : "");
77  exit(-1);
78}
79
80void fatal(char *reason) {
81  fprintf(stderr, "fatal: %s\n", reason);
82  exit(-1);
83}
84
85void update_count() {
86  uint32_t delta;
87
88  delta = tot_count - last_count;
89  printf("--------------------------------\n"
90         "  Counter:          %u\n"
91         "  hosts/second:     %u\n"
92         "  kilobits/second:  %u\n",
93         tot_count, delta / timer,
94         ((sizeof(struct tcp_header) * 8) * (delta / timer)) / 1000);
95  last_count = tot_count;
96  alarm(timer);
97}
98
99struct tcp_packet *alloc_packet() {
100  struct tcp_packet *packet;
101  struct ip_header  *iph;
102  struct tcp_header *tcph;
103
104  if(!(packet = malloc(sizeof(struct tcp_packet))))
105    fatal("error: allocating tcp packet");
106
107  iph  = &packet->iph;
108  tcph = &packet->tcph;
109
110  iph->len       = 5;
111  iph->version   = 4;
112  iph->tos       = 0;
113  iph->tot_len   = htons(sizeof(struct tcp_packet));
114  iph->id        = 0xffff; //1 + (int)(65000.0 * (rand() / (RAND_MAX + 1.0)));;
115  iph->frag_off  = 0;
116  iph->ttl       = 255;
117
118  iph->protocol  = 6;
119
120  tcph->seq      = random();
121  tcph->ack_seq  = random();
122  tcph->win      = htons(8192);
123  tcph->len      = 5 << 4;
124  tcph->flags    = 2;
125  return(packet);
126}
127
128void init_packet(long source, int sport, long dest, int port,
129                 struct tcp_packet *tcp_packet) {
130  struct ip_header *iph;
131  struct tcp_header *tcph;
132
133  iph  = &tcp_packet->iph;
134  tcph = &tcp_packet->tcph;
135
136  iph->saddr  = source;
137  iph->daddr  = dest;
138  iph->sum    = 0; // csum((unsigned short *)iph, sizeof(struct ip_header));
139
140  tcph->sum   = 0;
141  tcph->sport = htons(sport);
142  tcph->dport = htons(port);
143}
144
145void do_scan(uint16_t dport, struct Receiver *rx_list, uint32_t ip_base, 
146             uint32_t seed, char shift) {
147  struct tcp_packet *tcp_packet;
148  struct ip_header  *iph;
149  struct tcp_header *tcph;
150  char *pos;
151  uint16_t sport;
152  uint32_t x, y, i, s, olen, tmp[32];
153  register int count = 20 >> 1,sum;
154  register unsigned short *p;
155  struct in_addr ip;
156
157  /* pre-init packets */
158  for(i = 0; rx_list[i].addr.s_addr; i++) {
159
160    tcp_packet        = alloc_packet();
161
162    if(!rx_list[i].sport) 
163      rx_list[i].sport = 1024 + (int)(65000.0 * (rand() / (RAND_MAX + 1024.0)));
164
165    sport = rx_list[i].sport;
166    init_packet(rx_list[i].addr.s_addr, sport, 0, dport, tcp_packet);
167
168    rx_list[i].tcp_packet          = tcp_packet;
169
170    rx_list[i].sin.sin_family      = AF_INET;
171    rx_list[i].sin.sin_addr.s_addr = inet_addr("1.1.1.1");
172    rx_list[i].sin.sin_port        = htons(sport);
173
174    if((s = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
175      fprintf(stderr, "ERROR send_packet() -> socket()\n");
176    }
177    else if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, &olen, sizeof(olen)) < 0) {
178      fprintf(stderr, "ERROR: could not set socket option IP_HDRINCL.\n");
179      close(s);
180    }
181
182    rx_list[i].sock = s;
183
184  }
185
186  /* initialize random scan parameters */
187  if(seed)
188    srand(seed);
189  else {
190    seed = 1;
191    printf("resume seed: %d\n", seed);
192    srand(seed);
193  }
194
195  if(!(pos = malloc(shift))) {
196    fprintf(stderr, "malloc()\n");
197    exit(-1);
198  }
199
200  memset(pos, 0, shift);
201  memset(&tmp, 0, shift * 4);
202
203  for(i = 0; i < shift;) {
204    x = (int)((float)shift*rand()/(RAND_MAX+1.0));
205
206    if(tmp[x] || x == i)
207      continue;
208
209    pos[i] = x;
210    tmp[x] = x+1;
211    i++;
212  }
213
214  /* scan */
215  signal(SIGALRM, update_count);
216  alarm(timer);
217
218  for(i = 0; tot_count < (0xffffffff >> (32 - shift)); tot_count++, i++) {
219
220    if(!rx_list[i].addr.s_addr)
221      i = 0;
222
223    iph  = &rx_list[i].tcp_packet->iph;
224    tcph = &rx_list[i].tcp_packet->tcph;
225
226    for(y = 0, x = 0; y < shift; y++) {
227      tmp[y] = ((tot_count >> y) & 1) << pos[y];
228      x += tmp[y];
229    }
230
231    iph->daddr = htonl(x + htonl(ip_base));
232
233    count = 20 >> 1;
234    tcph->sum = 0;
235    p = (uint16_t *)&rx_list[i].tcp_packet->tcph;
236
237    sum = (iph->saddr >> 16) + (iph->saddr & 0xffff) + (iph->daddr >> 16)
238          + (iph->daddr & 0xffff) + 1536 + htons(count << 1);
239
240    while(count--) sum += *p++;
241
242    sum = (sum >> 16) + (sum & 0xffff);
243    tcph->sum = ~(sum += (sum >> 16));
244
245    if(sendto(rx_list[i].sock, rx_list[i].tcp_packet, sizeof(struct tcp_packet),
246       0, (struct sockaddr *)&rx_list[i].sin, sizeof(rx_list[i].sin)) < 1) {
247      printf("sendto() failed, backing off\n");
248      usleep(50);
249    }
250       
251
252  }
253
254}
255
256long resolve(char *host) {
257  struct in_addr ip;
258  struct hostent *he;
259
260  if((ip.s_addr = inet_addr(host)) == -1) {
261    if(!(he = gethostbyname(host)))
262      return(-1);
263    else
264      memcpy(&ip.s_addr, he->h_addr, 4);
265  }
266  return(ip.s_addr);
267}
268
269struct Receiver *read_rxs(char *filename) {
270  FILE *fp;
271  uint32_t len = 0, count = 0, i;
272  struct Receiver *rx_list;
273  struct in_addr ip;
274  char buffer[256], *p;
275
276  if(!(fp = fopen(filename, "r"))) {
277    fprintf(stderr, "Error: can't open file: %s\n", filename);
278    exit(-1);
279  }
280
281  len = 256 * sizeof(struct Receiver);
282
283  if(!(rx_list = malloc(len))) {
284    fprintf(stderr, "Error: malloc\n");
285    exit(-1);
286  }
287
288  while(fgets(buffer, sizeof(buffer), fp)) {
289
290    if (count >= (len / sizeof(struct Receiver)) - 2) {
291      if (!(rx_list = realloc(rx_list, len + 
292                              (256 * sizeof(struct Receiver))))) {
293        fprintf(stderr, "Error: realloc\n");
294        exit(-1);
295      }
296
297      len += 256 * sizeof(struct Receiver);
298    }
299
300    if(buffer[strlen(buffer) - 1] == '\n')
301      buffer[strlen(buffer) - 1] = 0;
302
303    if(!(p = strchr(buffer, ':'))) 
304      rx_list[count].sport = 0;
305    else {
306      *p = 0;
307      p++;
308      rx_list[count].sport = atoi(p);
309//printf("%d %d\n", rx_list[count].sport, atoi(p));
310    }
311
312    if((rx_list[count].addr.s_addr = resolve(buffer)) == -1)
313      continue;
314
315    printf("%s:%u\n", inet_ntoa(rx_list[count].addr), rx_list[count].sport);
316    count++;
317
318  }
319
320  printf("*** Loaded %u Receivers ***\n", count);
321
322  if(!count) {
323    fprintf(stderr, "Error: 0 Receivers Found\n");
324    exit(-1);
325  }
326
327  return(rx_list);
328}
329
330int main(int argc, char *argv[]) {
331  struct Receiver *rx_list;
332  struct in_addr ip_base;
333  uint16_t shift = 0;
334  uint32_t c, i, dport, stime, rseed, dtime;
335  char rxlist_file[255], *p;
336
337  printf("###### scansyn_tx.c - sloth@ww88.org ######\n");
338
339  if(argc == 1)
340    usage(NULL);
341
342  ip_base.s_addr = 0;
343  rxlist_file[0] = 0;
344
345  while((c = getopt(argc, argv, "l:p:r:u:C:")) != -1) {
346
347    switch(c) {
348
349      case 'l':
350
351        strncpy(rxlist_file, optarg, sizeof(rxlist_file) - 1);
352        break;
353
354      case 'p':
355
356        dport = atoi(optarg);
357        break;
358
359      case 'r':
360
361        if(!(p = strchr(optarg, '/')))
362          usage("error: invalid range ex: 192.168.1.0/24\n");
363
364        p[0] = 0;
365        if(!inet_aton(optarg, &ip_base))
366          usage("error: invalid random base address\n");
367
368        p++;
369        shift = 32 - atoi(p);
370        if(shift > 32)
371          usage("error: invalid range ex: 192.168.1.0/24\n");
372
373        printf("random scanning %s/%d\n", inet_ntoa(ip_base), 32 - shift);
374        break;
375
376      case 'u':
377
378        rseed = atoi(optarg);
379        printf("resumable seed: %d\n", rseed);
380        break;
381
382      case 'C':
383
384        tot_count = atol(optarg);
385        printf("resumable count: %d\n", tot_count);
386        break;
387
388      default:
389
390        usage(NULL);
391        exit(-1);
392
393    }
394
395  }
396
397  if(!dport)
398    usage("-p is required\n");
399
400  if(!ip_base.s_addr && !shift)
401    usage("-r is required\n");
402
403  if(!rxlist_file[0])
404    usage("-l is required\n");
405
406  printf("hosts to scan: %d\n", 0xffffffff >> (32 - shift));
407
408  rx_list = read_rxs(rxlist_file);
409
410  stime = time(0);
411  srand(getpid() * getuid() + time(0));
412
413  do_scan(dport, rx_list, ip_base.s_addr, rseed, shift);
414
415  if(!(dtime = time(0) - stime))
416    dtime = 1;
417
418  printf("-------- COMPLETED SCAN ---------\n"
419         "  Hosts Scanned:     %u\n"
420         "  Total Seconds:     %u\n"
421         "  hosts/second:      %u\n"
422         "  kilobits/second:   %u\n",
423         tot_count, 
424         dtime, 
425         tot_count / dtime, 
426         ((tot_count * sizeof(struct tcp_packet) * 8) / 1000) / dtime);
427}
428
Note: See TracBrowser for help on using the repository browser.