1 /*
2
3 NST Simple HTTP Scanner v0.4
4
5 ChangeLog: v0.1 - Initial realease
6 v0.2 - Security bugs fixed
7 - Add some error handling
8 - New feature: HTML report at the end of the scan
9 - New feature: detection of directory listing
10 - Default requests.txt improved
11 v0.3 - Security bugs fixed
12 - New feature: options handling
13 - New feature: added some headers detection
14 - New feature: support for proxy servers (HTTP Tunneling)
15 - Default requests.txt improved
16 v0.4 - Security bugs fixed
17 - HTML Report improved
18 - New feature: subdomains scanning
19 - New feature: option -u for updates check
20 - New feature: use of POSIX threads (the scanner is much more faster)
21 - Default requests.txt improved
22
23 Author: Paisterist
24 Date: 2006-09-16
25
26 [N]eo [S]ecurity [T]eam - http://www.neosecurityteam.net
27
28 [root@home shttpscanner]# gcc 0.4.c -o 0.4 -lpthread
29 [root@home shttpscanner]# ./0.4
30 [!] NST Simple HTTP Scanner v0.4 by Paisterist - 2006/07/30
31 [!] [N]eo [S]ecurity [T]eam - http://www.neosecurityteam.net
32
33 [+] Usage: ./0.4 -h host -d path -p port
34 [+] Example: ./0.4 -h www.google.com -d / -p 80 -P 216.155.15.57:3128 -e
35
36 [+] Options:
37 ------------
38 -h: hostname. Example: www.google.com
39 -p: port number to connect by (80 by default).
40 -d: path ("/ by default"). Example: /web/
41 -e: use it for evading the responses used for not found errors.
42 -P: proxy server and port. Example: 216.155.15.57:3128
43 -r: requests file (requests.txt by default)
44 -m: scanning mode. O (by default) for get requests, 1 for scanning subdomains and 2 for both of them
45 -s: subdomains file (subdomains.txt by default)
46 -t: number of threads (64 by default). Must be between 0 and 1000
47 -u: use this option alone to check for updates.
48 [root@home shttpscanner]#
49
50 */
51
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <string.h>
55 #include <time.h>
56 #include <pthread.h>
57 #ifdef WIN32
58 #pragma comment(lib, "ws2_32")
59 #include <winsock.h>
60 #else
61 #include <sys/types.h>
62 #include <sys/socket.h>
63 #include <netinet/in.h>
64 #include <arpa/inet.h>
65 #include <netdb.h>
66 #endif
67
68 #define CURRENT_VERSION 0.4
69 #define HTML_CODE_SIZE 999999
70 #define RECEIVE_SIZE 9999
71 #define REQUEST_SIZE 1000
72 #define REQUESTS_FILE "/usr/local/share/shttpscanner/requests.txt"
73 #define SUBDOMAINS_FILE "/usr/local/share/shttpscanner/subdomains.txt"
74 #define MAX_REQUESTS 10000
75 #define URL_SIZE 100
76 #define THREADS 64
77
78 int Usage(char *argv[]);
79 void Rights(void);
80 char* GetBanner(char *hostname, int port, char *c_host, int c_port, struct sockaddr_in *host, int opt);
81 char* Get404(char *hostname, int port, char *c_host, int c_port, struct sockaddr_in *host, char *dir);
82 char* Get404Subdomain(char *hostname, int port, struct sockaddr_in host, struct hostent *h);
83 int CheckPort(char *hostname, int port, struct sockaddr_in *host);
84 int DirectoryListing(char *dir, char *rec, char *hostname, char *banner);
85 void CRLF(char *string);
86 char* stripSlash(char *string);
87 char* stripWWW(char *string);
88 char* time_format(time_t *begin, time_t *end);
89 char* formatProxy(char *string, int ret);
90 int invalidData(char *string, int limit);
91
92 void Report_Header(char *host, char *html);
93 int Report_Save(char *host, char *html);
94 int Report_Add(char *dir, char *response, char *html, char *extra, int type, int s_type);
95 int Report_Add_Details(int type, char *extra, char *html);
96 void Report_Start(char *html, int type);
97
98 void FATAL_ERROR(char *message);
99 void *ThreadGETRoutine(void* r_data);
100 void *ThreadSubdomainRoutine(void* r_data);
101
102 int CheckUpdate();
103
104 int COLOR=0;
105 int n_requests=0, n_subdomains=0;
106 int n_total, n_total1;
107 int n, n1;
108 int rounds = 0;
109
110 char *html;
111
112 struct OPTIONS {
113 char O_C_HOST[50];
114 int O_C_PORT;
115 char O_PROXY_HOST[50];
116 int O_PROXY_PORT;
117 char O_HOST[50];
118 char O_PATH[50];
119 char O_REQUESTS[50];
120 char O_HTML[50];
121 int O_PORT;
122 int O_CHECK_UPDATE;
123 int O_EVADING;
124 int O_THREADS;
125 int S_MODE;
126 char O_SUBDOMAINS[50];
127 };
128
129 struct request_data {
130 struct sockaddr_in host;
131 char* request;
132 char* subdomain;
133 char* error_response;
134 char* banner;
135 };
136
137 struct OPTIONS o_handler;
138 struct request_data *r_data;
139
140 pthread_t *threads;
141
main(int argc,char * argv[])142 int main(int argc, char *argv[]) {
143 #ifdef WIN32
144 WSADATA ws;
145 SOCKET sock;
146 #else
147 int sock;
148 #endif
149
150 time_t begin, begin1, begin2, end, end1, end2;
151 char *requests[MAX_REQUESTS], *p;
152 char *subdomains[MAX_REQUESTS];
153 char *banner;
154 char *error_response;
155 char *serror_response;
156 char *nulo = NULL;
157 int n_threads = 0;
158
159 int error=0, count=0, i, lapso=0, arg_i;
160 int pos;
161
162 double div;
163
164 struct sockaddr_in host;
165 struct sockaddr_in remote;
166 struct hostent *h;
167
168 FILE *fp;
169
170 #ifdef WIN32
171 WSAStartup(MAKEWORD(2, 2), &ws);
172 #endif
173
174 html = (char *) malloc(sizeof(char) * 999999);
175 error_response = (char *) malloc(sizeof(char) * 4);
176 serror_response = (char *) malloc(sizeof(char) * 4);
177
178 time(&begin);
179 if (argc<2) {
180 Usage(argv);
181 return 0;
182 }
183
184 o_handler.O_PORT = 80;
185 o_handler.O_EVADING = 0;
186 o_handler.O_CHECK_UPDATE = 0;
187
188 for (arg_i = 1; arg_i < argc; arg_i++) {
189 switch (argv[arg_i][0]) {
190 case '-': {
191 if (((int) argv[arg_i][1] >= 97 && (int) argv[arg_i][1] <= 122) || ((int) argv[arg_i][1] >= 65 && (int) argv[arg_i][1] <= 90)) {
192 switch (argv[arg_i][1]) {
193 case 'h': {
194 if (strlen(o_handler.O_HOST)>0) {
195 Usage(argv);
196 return 0;
197 }
198
199 if (argv[arg_i + 1][0] == '-') {
200 Usage(argv);
201 return 0;
202 }
203 else {
204 strncpy(o_handler.O_HOST, argv[arg_i + 1], sizeof(o_handler.O_HOST));
205 }
206 } break;
207 case 'p': {
208 if (atoi(argv[arg_i + 1]) <=0 || atoi(argv[arg_i + 1]) >65535) FATAL_ERROR("[+] Invalid port number: it must be between 0 and 65535. Quiting...\n");
209 else {
210 o_handler.O_PORT = atoi(argv[arg_i + 1]);
211 }
212 } break;
213 case 'd': {
214 if (strlen(o_handler.O_PATH) > 0) {
215 Usage(argv);
216 return 0;
217 }
218
219 if (strstr(argv[arg_i + 1], "/") != argv[arg_i + 1] || argv[arg_i + 1][strlen(argv[arg_i + 1])-1] != '/') {
220 printf("[!] Invalid directory path: it must contain slashes. Quiting...\n");
221 return 0;
222 }
223 else strncpy(o_handler.O_PATH, argv[arg_i + 1], sizeof(o_handler.O_PATH));
224 } break;
225 case 'r': {
226 if (strlen(o_handler.O_REQUESTS) > 0 || argv[arg_i + 1][0] == '-') {
227 Usage(argv);
228 return 0;
229 }
230
231 strncpy(o_handler.O_REQUESTS, argv[arg_i + 1], sizeof(o_handler.O_REQUESTS));
232 } break;
233 case 'e': {
234 if (o_handler.O_EVADING != 0) {
235 Usage(argv);
236 return 0;
237 }
238
239 o_handler.O_EVADING = 1;
240
241 } break;
242 case 'P': {
243 if (strlen(o_handler.O_PROXY_HOST) > 0 || !strstr(argv[arg_i + 1], ":") || strlen(argv[arg_i + 1]) < 10) {
244 Usage(argv);
245 return 0;
246 }
247 if (formatProxy(argv[arg_i + 1], 0) != NULL && formatProxy(argv[arg_i + 1], 1) != NULL) {
248 strncpy(o_handler.O_PROXY_HOST, formatProxy(argv[arg_i + 1], 0), sizeof(o_handler.O_PROXY_HOST));
249 o_handler.O_PROXY_PORT = atoi(formatProxy(argv[arg_i + 1], 1));
250 }
251 else {
252 Usage(argv);
253 return 0;
254 }
255 } break;
256 case 'm': {
257 if (atoi(argv[arg_i +1]) >= 0 && atoi(argv[arg_i + 1]) <= 2 && argv[arg_i + 1] && !o_handler.S_MODE) {
258 o_handler.S_MODE = atoi(argv[arg_i + 1]);
259 }
260 else {
261 Usage(argv);
262 return 0;
263 }
264 } break;
265 case 's': {
266 if (strlen(o_handler.O_SUBDOMAINS) > 0 || argv[arg_i + 1][0] == '-') {
267 Usage(argv);
268 return 0;
269 }
270
271 strncpy(o_handler.O_SUBDOMAINS, argv[arg_i + 1], sizeof(o_handler.O_SUBDOMAINS));
272 } break;
273 case 't': {
274 if (atoi(argv[arg_i + 1]) <= 0 || atoi(argv[arg_i + 1]) > 1000 || o_handler.O_THREADS) {
275 Usage(argv);
276 return 0;
277 }
278 o_handler.O_THREADS = atoi(argv[arg_i + 1]);
279 } break;
280 case 'u': {
281 if (o_handler.O_CHECK_UPDATE == 1) {
282 Usage(argv);
283 return 0;
284 }
285
286 o_handler.O_CHECK_UPDATE = 1;
287 } break;
288 default: {
289 Usage(argv);
290 return 0;
291 }
292 }
293 }
294 }
295 }
296 }
297
298 if (o_handler.O_CHECK_UPDATE == 1) {
299 CheckUpdate();
300 return 0;
301 }
302
303 if (!o_handler.O_HOST) Usage(argv);
304 if (strlen(o_handler.O_PATH) <= 0) strcpy(o_handler.O_PATH, "/");
305 if (strlen(o_handler.O_REQUESTS) <= 0) strcpy(o_handler.O_REQUESTS, REQUESTS_FILE);
306 if (strlen(o_handler.O_SUBDOMAINS) <= 0) strcpy(o_handler.O_SUBDOMAINS, SUBDOMAINS_FILE);
307 if ((h = gethostbyname(o_handler.O_HOST)) == NULL) FATAL_ERROR("[!] Fatal error: unrecognized host. Quiting...\n");
308 if (!o_handler.S_MODE) o_handler.S_MODE = 0;
309 if (!o_handler.O_THREADS) o_handler.O_THREADS = THREADS;
310
311 threads = (pthread_t *) malloc(sizeof(pthread_t) * o_handler.O_THREADS);
312 r_data = (struct request_data *) malloc(sizeof(struct request_data) * o_handler.O_THREADS);
313
314 if (strlen(o_handler.O_PROXY_HOST) > 0 && o_handler.O_PROXY_PORT > 0) {
315 if ((h = gethostbyname(o_handler.O_PROXY_HOST)) == NULL) FATAL_ERROR("[!] Fatal error: unrecognized proxy server. Quiting...\n");
316
317 host.sin_family=AF_INET;
318 host.sin_port=htons((short) o_handler.O_PROXY_PORT);
319 host.sin_addr.s_addr=inet_addr(o_handler.O_PROXY_HOST);
320
321 memcpy(&host.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
322
323 strcpy(o_handler.O_C_HOST, o_handler.O_PROXY_HOST);
324 o_handler.O_C_PORT = o_handler.O_PROXY_PORT;
325 }
326 else {
327 strcpy(o_handler.O_C_HOST, o_handler.O_HOST);
328 o_handler.O_C_PORT = o_handler.O_PORT;
329 }
330
331 host.sin_family=AF_INET;
332 host.sin_port=htons((short) o_handler.O_C_PORT);
333 host.sin_addr.s_addr=inet_addr(o_handler.O_C_HOST);
334
335 memcpy(&host.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
336
337 CheckPort(o_handler.O_C_HOST, o_handler.O_C_PORT, &host);
338
339 Report_Header(o_handler.O_HOST, html);
340
341 Report_Add_Details(0, o_handler.O_HOST, html);
342 banner = GetBanner(o_handler.O_HOST, o_handler.O_PORT, o_handler.O_C_HOST, o_handler.O_C_PORT, &host, 0);
343 GetBanner(o_handler.O_HOST, o_handler.O_PORT, o_handler.O_C_HOST, o_handler.O_C_PORT, &host, 1);
344
345 if (banner) Report_Add_Details(1, banner, html);
346
347 error_response = Get404(o_handler.O_HOST, o_handler.O_PORT, o_handler.O_C_HOST, o_handler.O_C_PORT, &host, o_handler.O_PATH);
348 serror_response = Get404Subdomain(o_handler.O_HOST, o_handler.O_PORT, host, h);
349
350 Report_Add_Details(-1, error_response, html);
351 Report_Add_Details(5, serror_response, html);
352
353 printf("\n");
354
355 if (o_handler.S_MODE == 0 || o_handler.S_MODE == 2) {
356 time(&begin1);
357 fp=fopen(o_handler.O_REQUESTS, "r");
358
359 if (!fp) {
360 printf("[!] Can't open %s for reading requests. Quiting...\n", o_handler.O_REQUESTS);
361 return 0;
362 }
363
364 while (!feof(fp) && count<MAX_REQUESTS) {
365 requests[count] = (char *) malloc(sizeof(char) * 1000);
366 fgets(requests[count], 1000, fp);
367 CRLF(requests[count]);
368 if (strlen(requests[count])>0 && *requests[count] == '/') count++;
369 else requests[count] = (char *) NULL;
370 }
371
372
373 if (count == 0) {
374 printf("[!] No requests found at %s. Quiting...\n", o_handler.O_REQUESTS);
375 return 0;
376 }
377
378 n = n_total = count;
379
380 printf("[+] Starting GET scaning with %d requests...\n\n", count);
381
382 count = 0;
383 n_threads = 0;
384
385 Report_Start(html, 0);
386
387 while (requests[count]) {
388 if (n_threads == o_handler.O_THREADS) {
389 rounds++;
390 n_threads = 0;
391 pthread_join(threads[n_threads], NULL);
392 }
393
394 r_data[n_threads].request = requests[count];
395 r_data[n_threads].host = host;
396 r_data[n_threads].error_response = error_response;
397 r_data[n_threads].banner = banner;
398 r_data[n_threads].subdomain = NULL;
399
400 if (n_threads > 0 && rounds > 0)
401 pthread_join(threads[n_threads], NULL);
402
403 if (pthread_create(&threads[n_threads], NULL, &ThreadGETRoutine, (void *) &r_data[n_threads]) == -1)
404 FATAL_ERROR("[!] Can't create thread. Quiting...\n");
405
406 count++;
407 n_threads++;
408 }
409
410 count = 0;
411 n_threads--;
412
413 if (rounds == 0) n_threads = 0;
414 while (n_threads < o_handler.O_THREADS) {
415 pthread_join(threads[n_threads], NULL);
416 n_threads++;
417 }
418
419 rounds = 0;
420 n_threads = 0;
421 n_requests = 0;
422
423 time(&end1);
424 }
425
426 if (o_handler.S_MODE == 1 || o_handler.S_MODE == 2) {
427 time(&begin2);
428 count=0;
429 strcpy(o_handler.O_HOST, stripWWW(o_handler.O_HOST));
430 fp=fopen(o_handler.O_SUBDOMAINS, "r");
431
432 if (!fp) {
433 printf("[!] Can't open %s for reading subdomains. Quiting...\n", o_handler.O_SUBDOMAINS);
434 return 0;
435 }
436
437 while (!feof(fp) && count<MAX_REQUESTS) {
438 subdomains[count] = (char *) malloc(sizeof(char) * 1000);
439 fgets(subdomains[count], 1000, fp);
440 CRLF(subdomains[count]);
441 if (strlen(subdomains[count])>0) count++;
442 else subdomains[count] = (char *) NULL;
443 }
444
445
446 if (count == 0) {
447 printf("[!] No subdomains found at %s. Quiting...\n", o_handler.O_SUBDOMAINS);
448 return 0;
449 }
450
451 n1 = n_total1 = count;
452
453 if (o_handler.S_MODE == 2) printf("\n");
454 printf("[+] Starting subdomain scaning with %d entries...\n\n", count);
455
456 count = 0;
457
458 Report_Start(html, 1);
459
460 while (subdomains[count]) {
461 if (n_threads == o_handler.O_THREADS) {
462 rounds++;
463 n_threads = 0;
464 pthread_join(threads[n_threads], NULL);
465 }
466
467 if (n_threads > 0 && rounds > 0)
468 pthread_join(threads[n_threads], NULL);
469
470 r_data[n_threads].request = NULL;
471 r_data[n_threads].host = host;
472 r_data[n_threads].error_response = serror_response;
473 r_data[n_threads].banner = banner;
474 r_data[n_threads].subdomain = subdomains[count];
475
476 if (pthread_create(&threads[n_threads], NULL, &ThreadSubdomainRoutine, (void *) &r_data[n_threads]) == -1) {
477 FATAL_ERROR("[!] Can't create thread. Quiting...\n");
478 }
479
480 n_threads++;
481 count++;
482 }
483
484 count = 0;
485 n_threads--;
486 if (rounds == 0) n_threads = 0;
487
488 while (n_threads < n_total1) {
489 pthread_join(threads[n_threads],NULL);
490 n_threads++;
491 }
492
493 time(&end2);
494 }
495
496 time(&end);
497 printf("\n");
498 if (o_handler.S_MODE == 0 || o_handler.S_MODE == 2)
499 printf("[+] %d GET requests done, %d were successfull on %s. Leaving...\n", n_total, n, time_format(&begin1, &end1));
500
501 if (o_handler.S_MODE == 1 || o_handler.S_MODE ==2)
502 printf("[+] %d subdomain requests done, %d were successfull on %s. Leaving...\n", n_total1, n1, time_format(&begin2, &end2));
503
504 printf("[+] Scan took %s.\n", time_format(&begin, &end));
505 #ifdef WIN32
506 WSACleanup();
507 #endif
508 Report_Save(o_handler.O_HOST, html);
509 return 0;
510 }
511
Usage(char * argv[])512 int Usage(char *argv[]) {
513 Rights();
514 printf("[+] Usage: %s -h host -d path -p port\n"
515 "[+] Example: %s -h www.google.com -d / -p 80 -P 216.155.15.57:3128 -e\n\n"
516 "[+] Options:\n"
517 "------------\n"
518 "\t-h: hostname. Example: www.google.com\n"
519 "\t-p: port number to connect by (80 by default).\n"
520 "\t-d: path (\"/ by default\"). Example: /web/\n"
521 "\t-e: use it for evading the responses used for not found errors.\n"
522 "\t-P: proxy server and port. Example: 216.155.15.57:3128\n"
523 "\t-r: requests file (%s by default)\n"
524 "\t-m: scanning mode. O (by default) for get requests, 1 for scanning subdomains and 2 for both of them\n"
525 "\t-s: subdomains file (%s by default)\n"
526 "\t-t: number of threads (%d by default). Must be between 0 and 1000\n"
527 "\t-u: use this option alone to check for updates.\n", argv[0], argv[0], REQUESTS_FILE, SUBDOMAINS_FILE, THREADS);
528 return 0;
529 }
530
Rights(void)531 void Rights(void) {
532 printf("[!] NST Simple HTTP Scanner v0.4 by Paisterist - 2006/07/30\n"
533 "[!] [N]eo [S]ecurity [T]eam - http://www.neosecurityteam.net\n\n");
534 }
535
GetBanner(char * hostname,int port,char * c_host,int c_port,struct sockaddr_in * host,int opt)536 char* GetBanner(char *hostname, int port, char *c_host, int c_port, struct sockaddr_in *host, int opt) {
537 #ifdef WIN32
538 SOCKET sock;
539 #else
540 int sock;
541 #endif
542
543 char buffer[300];
544 char rec[RECEIVE_SIZE];
545 char *server;
546 char powered[100];
547
548 char *p;
549
550 int i, error;
551
552 server = (char *) malloc(sizeof(char) * 200);
553
554 sock = socket(AF_INET, SOCK_STREAM, 0);
555
556 if (!sock) {
557 printf("[!] Fatal error: failed to create the socket\n");
558 return NULL;
559 }
560
561 error=connect(sock, (const struct sockaddr*) host, sizeof(*host));
562
563 if (error != 0) {
564 printf("[!] Fatal error: Can't connect to %s by port %d\n", c_host, c_port);
565 return (char *) NULL;
566 }
567
568 if (opt != 0) {
569 sprintf(buffer, "OPTIONS http://%s:%d/ HTTP/1.0\r\n"
570 "User-agent: NST Bot Scanner\r\n"
571 "Host: %s\r\n\r\n", hostname, port, hostname);
572
573 send(sock, buffer, strlen(buffer), 0);
574 recv(sock, rec, sizeof(rec), 0);
575
576 if (!(p = strstr(rec, "Allow: " ))) return (char *) NULL;
577 p += 7;
578 i = 0;
579
580 while ((int) *p != 13 && i<200) {
581 server[i] = *p;
582 i++;
583 p++;
584 }
585
586 server[i] = '\0';
587
588 printf("[+] HTTP allowed methods: %s.\n", server);
589 Report_Add_Details(4, server, html);
590
591 #ifdef WIN32
592 closesocket(sock);
593 #else
594 shutdown(sock, SHUT_WR);
595 close(sock);
596 #endif
597
598 return (char *) NULL;
599 }
600
601 sprintf(buffer,"GET http://%s:%d/ HTTP/1.1\r\n"
602 "Connection: close\r\n"
603 "User-agent: NST Bot Scanner\r\n"
604 "Host: %s\r\n\r\n", hostname, port, c_host);
605
606 send(sock, buffer, strlen(buffer), 0);
607 recv(sock, rec, sizeof(rec), 0);
608
609 if (!(p = strstr(rec, "Server: "))) {
610 return (char *) NULL;
611 }
612
613 p += 8;
614 i = 0;
615
616 while ((int) *p != 13 && i<200) {
617 server[i] = *p;
618 i++;
619 p++;
620 }
621
622 server[i] = '\0';
623 i = 0;
624
625 printf("[+] Server header: %s. This header can be modified manually.\n", server);
626 // ERROR EN WINDOWS CON ARGENTINA.COM
627 if (p = strstr(rec, "X-Powered-By: ")) {
628 p += 14;
629 while ((int) *p != 13 && i<100) {
630 powered[i] = *p;
631 i++;
632 p++;
633 }
634
635 powered[i] = '\0';
636 printf("[+] X-Powered-By header found: %s\n", powered);
637 Report_Add_Details(2, powered, html);
638 memset(powered, 0x00, strlen(powered));
639 i = 0;
640 }
641
642 if (p = strstr(rec, "X-AspNet-Version: ")) {
643 p += 18;
644 while ((int) *p != 13 && i<100) {
645 powered[i] = *p;
646 i++;
647 p++;
648 }
649
650 powered[i] = '\0';
651 printf("[+] X-AspNet-Version header found: %s\n", powered);
652 Report_Add_Details(3, powered, html);
653 }
654
655 #ifdef WIN32
656 closesocket(sock);
657 #else
658 shutdown(sock, SHUT_WR);
659 close(sock);
660 #endif
661 return server;
662 }
663
Get404(char * hostname,int port,char * c_host,int c_port,struct sockaddr_in * host,char * dir)664 char* Get404(char *hostname, int port, char *c_host, int c_port, struct sockaddr_in *host, char *dir) {
665 #ifdef WIN32
666 SOCKET sock;
667 #else
668 int sock;
669 #endif
670
671 char buffer[150];
672 char *response;
673 char rec[RECEIVE_SIZE];
674
675 int error;
676
677 response = (char *) malloc(sizeof(char) * 4);
678 sock = socket(AF_INET, SOCK_STREAM, 0);
679
680 if (!sock) FATAL_ERROR("[!] Fatal error: failed to create the socket\n");
681
682 error=connect(sock, (const struct sockaddr*) host, sizeof(*host));
683
684 if (error != 0) {
685 printf("[!] Fatal error: Can't connect to %s by port %d", c_host, c_port);
686 exit(-1);
687 }
688
689 sprintf(buffer, "HEAD http://%s:%d%s404_NotFuND2.ex HTTP/1.1\r\n"
690 "Proxy-Connection: close\r\n"
691 "User-Agent: NST Bot Scanner\r\n"
692 "Host: %s\r\n\r\n", hostname, port, dir, c_host);
693
694 send(sock, buffer, strlen(buffer), 0);
695 recv(sock, rec, sizeof(rec), 0);
696
697 sprintf(response, "%c%c%c", rec[9], rec[10], rec[11]);
698
699 if (strcmp(response, "404") == 0) {
700 printf("[+] Server respond normally with 404 messages for not found errors.\n");
701 }
702 else printf("[+] Server uses %s messages for not found errors. That can make the scan less precise, use -e for evading.\n", response);
703
704 #ifdef WIN32
705 closesocket(sock);
706 #else
707 shutdown(sock, SHUT_WR);
708 close(sock);
709 #endif
710
711 return response;
712 }
713
Get404Subdomain(char * hostname,int port,struct sockaddr_in host,struct hostent * h)714 char* Get404Subdomain(char *hostname, int port, struct sockaddr_in host, struct hostent *h) {
715 #ifdef WIN32
716 SOCKET sock;
717 #else
718 int sock;
719 #endif
720
721 char buffer[150];
722 char *response;
723 char *subdomain;
724 char rec[RECEIVE_SIZE];
725
726 int error;
727
728 response = (char *) malloc(sizeof(char) * 4);
729 subdomain = (char *) malloc((sizeof(char) * strlen(hostname)) + 20);
730 sock = socket(AF_INET, SOCK_STREAM, 0);
731
732 sprintf(subdomain, "n0tex4sistant.%s", stripWWW(hostname));
733
734 if (!sock) FATAL_ERROR("[!] Fatal error: failed to create the socket\n");
735 host.sin_addr.s_addr=inet_addr(subdomain);
736
737 if ((h = gethostbyname(subdomain)) != NULL)
738 memcpy(&host.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
739
740 error=connect(sock, (const struct sockaddr*) &host, sizeof(host));
741
742 if (error != 0) {
743 printf("[+] Server uses normal response for non existant subdomains.\n");
744 return (char *) NULL;
745 }
746
747 sprintf(buffer, "HEAD http://%s:%d HTTP/1.1\r\n"
748 "Proxy-Connection: close\r\n"
749 "User-Agent: NST Bot Scanner\r\n"
750 "Host: %s:%d\r\n\r\n", subdomain, port, subdomain, port);
751
752 send(sock, buffer, strlen(buffer), 0);
753 recv(sock, rec, sizeof(rec), 0);
754
755 sprintf(response, "%c%c%c", rec[9], rec[10], rec[11]);
756
757 printf("[+] Server uses %s messages for not found subdomains. That can make the scan less precise.\n", response);
758
759 #ifdef WIN32
760 closesocket(sock);
761 #else
762 shutdown(sock, SHUT_WR);
763 close(sock);
764 #endif
765
766 return response;
767 }
768
CheckPort(char * hostname,int port,struct sockaddr_in * host)769 int CheckPort(char *hostname, int port, struct sockaddr_in *host) {
770 #ifdef WIN32
771 SOCKET sock;
772 #else
773 int sock;
774 #endif
775
776 int error;
777 int FATAL=0;
778
779 char buffer[200];
780 char rec[5];
781
782 sock = socket(AF_INET, SOCK_STREAM, 0);
783
784 if (!sock) {
785 printf("[!] Fatal error: failed to create the socket\n");
786 return 0;
787 }
788
789 error=connect(sock, (const struct sockaddr*) host, sizeof(*host));
790
791 if (error != 0) {
792 printf("[!] Fatal error: Can't connect to %s by port %d. Quiting...\n", hostname, port);
793 FATAL=1;
794 }
795
796 sprintf(buffer, "GET / HTTP/1.0\r\n"
797 "User-agent: NST Bot Scanner\r\n"
798 "Host: %s\r\n\r\n", hostname);
799
800 send(sock, buffer, strlen(buffer), 0);
801 recv(sock, rec, sizeof(rec), 0);
802
803 if (strlen(rec) == 0 || invalidData(rec, sizeof(rec)) == -1) {
804 printf("[!] Fatal error: Can't receive data from %s by port %d. Quiting...\n", hostname, port);
805 FATAL=1;
806 }
807 #ifdef WIN32
808 closesocket(sock);
809 #else
810 shutdown(sock, SHUT_WR);
811 close(sock);
812 #endif
813
814 if (FATAL == 1) exit(0);
815 return 0;
816 }
817
CRLF(char * string)818 void CRLF(char *string) {
819 int i=0;
820 for (i=0; i<strlen(string); i++) if ((int) string[i] == 13 || (int) string[i] == 10 || (int) string[i] == 32 || (int) string[i] == 9) string[i]=(char) NULL;
821 }
822
stripSlash(char * string)823 char *stripSlash(char *string) {
824 int len = strlen(string);
825 int i;
826 char *new_string = (char *) malloc(sizeof(char) * len);
827
828 if (string[0] != '/') return (char *) NULL;
829
830 for (i = 1; i<len; i++) {
831 new_string[i-1] = string[i];
832 }
833
834 new_string[i-1] = '\0';
835 return new_string;
836 }
837
time_format(time_t * begin,time_t * end)838 char* time_format(time_t *begin, time_t *end) {
839 int lapso, m, s;
840 char *format;
841
842 format =(char *) malloc(sizeof(char) * 50);
843 lapso = *end - *begin;
844
845 if (lapso >= 60) {
846 m = lapso / 60;
847 s = lapso % 60;
848
849 if (s == 0) sprintf(format, "%d minutes", m);
850 else sprintf(format, "%d minutes and %d seconds", m, s);
851 }
852 else sprintf(format, "%d seconds", lapso);
853 return format;
854 }
855
DirectoryListing(char * dir,char * rec,char * hostname,char * banner)856 int DirectoryListing(char *dir, char *rec, char *hostname, char *banner) {
857 char *serverAt;
858
859 serverAt = (char *) malloc (sizeof(char) * (strlen(hostname) + strlen(banner) + 20));
860
861 strcpy(serverAt, banner);
862 strcat(serverAt, " Server at ");
863 strcat(serverAt, hostname);
864 if (dir[strlen(dir) - 1] != '/' || banner == NULL) return 0;
865 if (strstr(rec, "Index of") != NULL) return 1;
866 if (strstr(rec, serverAt) != NULL) return 1;
867
868 return 0;
869 }
870
Report_Header(char * host,char * html)871 void Report_Header(char *host, char *html) {
872 sprintf(html, "<html>\n"
873 "<head>\n"
874 "<title>Simple HTTP Scanner - Scan report for %s</title>\n"
875 "</head>\n"
876 "<body bgcolor=\"#FFFFFF\" text=\"#000000\">\n"
877 "<table align=\"center\" width=\"100%%\" cellspacing=\"0\">\n"
878 "<tr align=\"center\" bgcolor=\"#0000FF\">\n"
879 "<td style=\"color: #FFFFFF; font-size: 20px; font-weight: bold;\" colspan=\"3\">Scan report for %s</td>\n"
880 "</tr>\n"
881 "<tr align=\"center\" bgcolor=\"#0066FF\"><td colspan=\"3\" style=\"font-weight: bold; color: #FFFFFF;\">Server details</td></tr>\n", host, host);
882 }
883
Report_Save(char * host,char * html)884 int Report_Save(char *host, char *html) {
885 FILE *fp;
886 char *filename;
887
888 filename = (char *) malloc(sizeof(char) * ( strlen(host) + 15 ));
889 sprintf(filename, "report-%s.html", host);
890
891 strcat(html, "</table><br /><br />\n"
892 "<table align=\"center\">\n"
893 "<tr align=\"center\">\n"
894 "<td style=\"font-size: 12px;\">Simple HTTP Scanner v0.4 by Paisterist<br />"
895 "Neo Security Team � 2004 - 2006 || <a href=\"http://www.neosecurityteam.net\">http://www.neosecurityteam.net</a></td>\n"
896 "</tr>\n"
897 "</table>\n"
898 "</body>\n"
899 "</html>\n");
900 fp = fopen(filename, "w");
901
902 if (!fp) {
903 printf("[+] Unknown error: the report couldn't be written. Please check the directory permissions.\n");
904 return 0;
905 }
906 fwrite(html, sizeof(char), strlen(html), fp);
907
908 fclose(fp);
909
910 printf("[+] Report saved successfully at %s.\n\n", filename);
911 return 0;
912 }
913
Report_Add(char * dir,char * response,char * html,char * extra,int type,int s_type)914 int Report_Add(char *dir, char *response, char *html, char *extra, int type, int s_type) {
915 char message[200];
916 char cat[1000];
917 char color[8];
918 char url[100];
919
920 if (COLOR == 0) {
921 COLOR = 1;
922 strcpy(color, "#CCCCCC");
923 }
924 else {
925 COLOR = 0;
926 strcpy(color, "#FFFFFF");
927 }
928
929 switch (type) {
930 case 0: sprintf(message, "Content-Location header was detected. The source has taken from %s.", extra); break;
931 case 1: sprintf(message, "Location header was detected. The web server redirects to %s.", extra); break;
932 case 2: sprintf(message, "The web server allows you to see the content of directories without a index document. Check it out."); break;
933 case 3: sprintf(message, "The requested document requires a web based authentication, there is a restricted area."); break;
934 case 4: sprintf(message, "The requested document is forbidden. Maybe there is some confidential or sensitive information in there."); break;
935 default: sprintf(message, "Normal response received, the document exists. You should take a look."); break;
936 }
937 if (s_type == 0) sprintf(url, "%s%s", o_handler.O_PATH, stripSlash(dir));
938 else sprintf(url, "http://%s", dir);
939
940 sprintf(cat, "<tr bgcolor=\"%s\">\n"
941 "<td>%s</td>\n"
942 "<td>%s</td>\n"
943 "<td>%s</td>\n"
944 "</tr>\n", color, url, response, message);
945
946 strncat(html, cat, sizeof(cat));
947 return 0;
948 }
949
Report_Add_Details(int type,char * extra,char * html)950 int Report_Add_Details(int type, char *extra, char *html) {
951 char message[200];
952 char detail[30];
953 char color[8];
954 char *ret;
955
956 if (COLOR == 0) {
957 COLOR = 1;
958 strcpy(color, "#CCCCCC");
959 }
960 else {
961 COLOR = 0;
962 strcpy(color, "#FFFFFF");
963 }
964
965 switch (type) {
966 case 0: {
967 sprintf(detail, "Hostname: ");
968 strcpy(message, extra);
969 } break;
970 case 1: {
971 sprintf(detail, "Server information: ");
972 strcpy(message, extra);
973 } break;
974 case 2: {
975 sprintf(detail, "X-Powered-By: ");
976 strcpy(message, extra);
977 } break;
978 case 3: {
979 sprintf(detail, "X-AspNet-Version: ");
980 strcpy(message, extra);
981 } break;
982 case 4: {
983 sprintf(detail, "HTTP allowed methods: ");
984 strcpy(message, extra);
985 } break;
986 case 5: {
987 sprintf(detail, "Not found subdomain errors: ");
988 if (extra != NULL)
989 sprintf(message, "The web server use %s messages for not found subdomains.", extra);
990 else
991 strcpy(message, "The web servers respond normally to not found subdomains.");
992 } break;
993 default: {
994 sprintf(detail, "Not found errors: ");
995 if (strcmp(extra, "404") != 0)
996 sprintf(message, "The web server use %s messages for not found errors. This can make the scan less precise.", extra);
997 else
998 sprintf(message, "The web server use %s messages for not found errors. This is normal.", extra);
999 } break;
1000 }
1001
1002 ret = (char *) malloc(sizeof(char) * ((strlen(message) + strlen(detail)) + 100));
1003 sprintf(ret, "<tr bgcolor=\"%s\">\n"
1004 "<td width=\"150\"><b>%s</b></td>\n"
1005 "<td colspan=\"2\">%s</td>\n"
1006 "</tr>\n", color, detail, message);
1007
1008 strcat(html, ret);
1009
1010 return 0;
1011 }
1012
Report_Start(char * html,int type)1013 void Report_Start(char *html, int type) {
1014 COLOR = 0;
1015 char mode[30];
1016 char cat[210];
1017 char request[10];
1018
1019 if (type == 0) {
1020 strcpy(mode, "GET scanning");
1021 strcpy(request, "Path");
1022 }
1023 else {
1024 strcpy(mode, "Subdomain scanning");
1025 strcpy(request, "Domain");
1026 }
1027
1028 sprintf(cat, "<tr bgcolor=\"#0066FF\" style=\"color: #FFFFFF; text-align: center;\">\n"
1029 "<td colspan=\"3\"><b>%s</b></td>\n"
1030 "</tr>\n"
1031 "<tr bgcolor=\"#0099FF\" style=\"color: #FFFFFF;\">\n"
1032 "<td><b>%s</b></td>\n"
1033 "<td><b>Response</b></td>\n"
1034 "<td><b>Comments</b></td>\n"
1035 "</tr>\n", mode, request);
1036
1037 strcat(html, cat);
1038
1039 }
1040
FATAL_ERROR(char * message)1041 void FATAL_ERROR(char *message) {
1042 printf("%s", message);
1043 fflush(stdout);
1044 exit(-1);
1045 }
1046
formatProxy(char * string,int ret)1047 char* formatProxy(char *string, int ret) {
1048 char *p;
1049 char *port = (char *) malloc(sizeof(char) * 6);
1050 char *host = (char *) malloc(sizeof(char) * strlen(string));
1051 int pos, count=0;
1052
1053 if ((p = strstr(string, ":")) == NULL) return (char *) NULL;
1054
1055
1056 for (pos = 0; pos < (p - string); pos++) {
1057 host[pos] = string[pos];
1058 }
1059
1060 host[pos]='\0';
1061
1062 p++;
1063
1064 while (*p != '\0' && count < 5) {
1065 port[count] = *p;
1066 count++;
1067 p++;
1068 }
1069
1070 port[count] = '\0';
1071
1072 if (atoi(port) <= 0 || atoi(port) >= 65536) {
1073 return (char *) NULL;
1074 }
1075
1076 return ret == 1 ? port : host;
1077 }
1078
invalidData(char * string,int limit)1079 int invalidData(char *string, int limit) {
1080 int i, len = strlen(string);
1081
1082 for (i = 0; i < limit; i++)
1083 if ((int) string[i] < 32) return -1;
1084
1085 return 0;
1086 }
1087
stripWWW(char * string)1088 char* stripWWW(char *string) {
1089 int i;
1090 char *ret = (char *) malloc(sizeof(char) * strlen(string));
1091 if (strstr(string, "www.") == string) {
1092 for (i=4; i < strlen(string); i++) {
1093 ret[i-4] = string[i];
1094 }
1095 ret[i-4]='\0';
1096 return ret;
1097 }
1098
1099 return string;
1100 }
1101
ThreadGETRoutine(void * r_data)1102 void *ThreadGETRoutine(void* r_data) {
1103 #ifdef WIN32
1104 SOCKET sock;
1105 #else
1106 int sock;
1107 #endif
1108
1109 struct request_data *data;
1110
1111 char url[URL_SIZE];
1112 char response[3];
1113 char rec[RECEIVE_SIZE];
1114 char request[REQUEST_SIZE];
1115 char *request_s;
1116 char *error_response;
1117 char *banner;
1118 char *p;
1119
1120 int error, size, i;
1121
1122 float div, porcentaje;
1123
1124 data = (struct request_data *) r_data;
1125
1126 request_s = data->request;
1127 error_response = data->error_response;
1128 banner = data->banner;
1129
1130 sock = socket(AF_INET, SOCK_STREAM, 0);
1131
1132 if (!sock) {
1133 printf("[!] Fatal error: failed to create the socket. Quiting...\n");
1134 n--;
1135 return 0;
1136 }
1137
1138 error = connect(sock, (const struct sockaddr*) &data->host, sizeof(data->host));
1139
1140 if (error != 0) {
1141 printf("[!] Unknown error: Can't connect to %s by port %d. Quiting...\n", o_handler.O_C_HOST, o_handler.O_C_PORT);
1142 n--;
1143 return 0;
1144 }
1145
1146 sprintf(request, "GET http://%s:%d%s%s HTTP/1.0\r\n"
1147 "Connection: Keep-Alive\r\n"
1148 "User-Agent: NST Bot Scanner\r\n"
1149 "Host: %s\r\n\r\n", o_handler.O_HOST, o_handler.O_PORT, o_handler.O_PATH, stripSlash(request_s), o_handler.O_C_HOST);
1150
1151 size=sizeof(struct sockaddr);
1152
1153 send(sock, request, sizeof(request), 0);
1154 recv(sock, rec, sizeof(rec), 0);
1155
1156 n_requests++;
1157 div = (float) (n_requests) / n_total;
1158 porcentaje = (float) (div * 100);
1159
1160 sprintf(response, "%c%c%c", rec[9], rec[10], rec[11]);
1161 response[3] = '\0';
1162
1163 if (strcmp(response, error_response) != 0 || (strcmp(response, error_response) == 0 && o_handler.O_EVADING == 0)) {
1164 if (strcmp("200", response) == 0) {
1165 if (p = strstr(rec, "Content-Location: ")) {
1166 p += 18;
1167 i = 0;
1168 while (*p != (int) 13 && *p != 32 && i<URL_SIZE) {
1169 url[i] = *p;
1170 p++;
1171 i++;
1172 }
1173 url[i] = '\0';
1174
1175 printf("%s 200 OK. Content-Location (source of the content): %s %.2f%%\n", request_s, url, porcentaje);
1176 Report_Add(request_s, response, html, url, 0, 0);
1177 }
1178 else if (DirectoryListing(request_s, rec, o_handler.O_HOST, banner) == 1) {
1179 printf("%s 200 OK. Directory listing enabled... this should be unsecure... %.2f%%\n", request_s, porcentaje);
1180 Report_Add(request_s, response, html, url, 2, 0);
1181 }
1182 else {
1183 printf("%s 200 OK. This can be interesting... %.2f%%\n", request_s, porcentaje);
1184 Report_Add(request_s, response, html, url, 999, 0);
1185 }
1186 }
1187 else if (strcmp("401", response) == 0) {
1188 printf("%s 401 Unauthorized. Restricted area, check it out. %.2f%%\n", request_s, porcentaje);
1189 Report_Add(request_s, response, html, url, 3, 0);
1190 }
1191 else if (strcmp("403", response) == 0) {
1192 printf("%s 403 Forbidden. Some good info? %.2f%%\n", request_s, porcentaje);
1193 Report_Add(request_s, response, html, url, 4, 0);
1194 }
1195 else {
1196 if (p = strstr(rec, "Location: ")) {
1197 p += 10;
1198 i = 0;
1199
1200 while ((int) *p != 13 && *p != 32 && i<URL_SIZE) {
1201 url[i] = *p;
1202 p++;
1203 i++;
1204 }
1205
1206 url[i] = '\0';
1207
1208 printf("%s %s - Redirects to %s. Try it... %.2f%%\n", request_s, response, url, porcentaje);
1209 Report_Add(request_s, response, html, url, 1, 0);
1210 }
1211 else
1212 n--;
1213 }
1214 } else
1215 n--;
1216
1217 memset(rec, 0x00, strlen(rec));
1218 memset(response, 0x00, 3);
1219 memset(request_s, 0x00, strlen(request));
1220 memset(url, 0x00, URL_SIZE);
1221 #ifdef WIN32
1222 closesocket(sock);
1223 #else
1224 shutdown(sock, SHUT_WR);
1225 close(sock);
1226 #endif
1227 }
1228
ThreadSubdomainRoutine(void * r_data)1229 void *ThreadSubdomainRoutine(void* r_data) {
1230 #ifdef WIN32
1231 SOCKET sock;
1232 #else
1233 int sock;
1234 #endif
1235
1236 struct request_data *data;
1237 struct hostent *h;
1238
1239 char url[URL_SIZE];
1240 char response[3];
1241 char rec[RECEIVE_SIZE];
1242 char request[REQUEST_SIZE];
1243 char *r_subdomain;
1244 char *serror_response;
1245 char *banner;
1246 char *p;
1247 char *subdomain = (char *) malloc(sizeof(char) * 1051);
1248
1249 int error, size, i;
1250
1251 float div, porcentaje;
1252
1253 data = (struct request_data *) r_data;
1254
1255 n_subdomains++;
1256 div = (float) (n_subdomains) / n_total;
1257 porcentaje = (float) (div * 100);
1258
1259 r_subdomain = data->subdomain;
1260 serror_response = data->error_response;
1261 banner = data->banner;
1262
1263 strcpy(subdomain, r_subdomain);
1264 strcat(subdomain, ".");
1265 strcat(subdomain, o_handler.O_HOST);
1266
1267 if (serror_response == NULL) {
1268 serror_response = (char *) malloc(sizeof(char) * 4); // This way strcmp() don't crash
1269 }
1270
1271 if (strcmp(o_handler.O_C_HOST, o_handler.O_PROXY_HOST) != 0) {
1272 strcpy(o_handler.O_C_HOST, subdomain);
1273 data->host.sin_addr.s_addr=inet_addr(o_handler.O_C_HOST);
1274
1275 if ((h = gethostbyname(o_handler.O_C_HOST)) != NULL)
1276 memcpy(&data->host.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
1277 }
1278
1279 sock = socket(AF_INET, SOCK_STREAM, 0);
1280
1281 if (!sock) {
1282 printf("[!] Fatal error: failed to create the socket. Quiting...\n");
1283 n1--;
1284 return NULL;
1285 }
1286
1287 error=connect(sock, (const struct sockaddr*) &data->host, sizeof(data->host));
1288
1289 if (error == 0 && h != NULL) {
1290 sprintf(request, "GET http://%s/ HTTP/1.0\r\n"
1291 "Connection: Keep-Alive\r\n"
1292 "User-Agent: NST Bot Scanner\r\n"
1293 "Host: %s\r\n\r\n", subdomain, o_handler.O_C_HOST);
1294
1295 size=sizeof(struct sockaddr);
1296
1297 send(sock, request, sizeof(request), 0);
1298 recv(sock, rec, sizeof(rec), 0);
1299
1300 sprintf(response, "%c%c%c", rec[9], rec[10], rec[11]);
1301
1302 if (strcmp(response, serror_response) != 0 || (strcmp(response, serror_response) == 0 && o_handler.O_EVADING == 0)) {
1303 if (strcmp("200", response) == 0) {
1304 if (p = strstr(rec, "Content-Location: ")) {
1305 p += 18;
1306 i = 0;
1307 while (*p != (int) 13 && i<URL_SIZE) {
1308 url[i] = *p;
1309 p++;
1310 i++;
1311 }
1312 url[i]='\0';
1313
1314 printf("http://%s/ 200 OK. Content-Location (source of the content): %s %.2f%%\n", subdomain, url, porcentaje);
1315 Report_Add(subdomain, response, html, url, 0, 1);
1316 }
1317 else if (DirectoryListing(subdomain, rec, o_handler.O_HOST, banner) == 1) {
1318 printf("http://%s/ 200 OK. Directory listing enabled... this should be unsecure... %.2f%%\n", subdomain, porcentaje);
1319 Report_Add(subdomain, response, html, url, 2, 1);
1320 }
1321 else {
1322 printf("http://%s/ 200 OK. This can be interesting... %.2f%%\n", subdomain, porcentaje, n_subdomains);
1323 Report_Add(subdomain, response, html, url, 999, 1);
1324 }
1325 }
1326 else if (strcmp("401", response) == 0) {
1327 printf("http://%s/ 401 Unauthorized. Restricted area, check it out. %.2f%%\n", subdomain, porcentaje);
1328 Report_Add(subdomain, response, html, url, 3, 1);
1329 }
1330 else if (strcmp("403", response) == 0) {
1331 printf("http://%s/ 403 Forbidden. Some good info? %.2f%%\n", subdomain, porcentaje);
1332 Report_Add(subdomain, response, html, url, 4, 1);
1333 }
1334 else {
1335 if (p = strstr(rec, "Location: ")) {
1336 p += 10;
1337 i = 0;
1338 while ((int) *p != 13 && i<URL_SIZE) {
1339 url[i] = *p;
1340 p++;
1341 i++;
1342 }
1343 url[i]='\0';
1344
1345 printf("http://%s/ %s - Redirects to %s. Try it... %.2f%%\n", subdomain, response, url, porcentaje);
1346 Report_Add(subdomain, response, html, url, 1, 1);
1347 }
1348 else
1349 n1--;
1350 }
1351 } //else
1352 //n_subdomains++;
1353
1354 free(subdomain);
1355
1356 #ifdef WIN32
1357 closesocket(sock);
1358 #else
1359 shutdown(sock, SHUT_WR);
1360 close(sock);
1361 #endif
1362 } else n1--;
1363 }
1364
CheckUpdate()1365 int CheckUpdate() {
1366 #ifdef WIN32
1367 SOCKET sock;
1368 #else
1369 int sock;
1370 #endif
1371
1372 int error, i=0, pos, t_count = 0;
1373
1374 char buffer[500];
1375 char rec[1000];
1376 char *update;
1377 char response[4];
1378 char *version, *date, *url, *p, *p1;
1379
1380 struct sockaddr_in host;
1381 struct hostent *h;
1382
1383 if ((h = gethostbyname("shttpscanner.sourceforge.net")) == NULL) {
1384 printf("[!] Can't retrieve the updates: shttpscanner.sourceforge.net unrecognized host\n");
1385 return -1;
1386 }
1387
1388 sock = socket(AF_INET, SOCK_STREAM, 0);
1389
1390 if (!sock) {
1391 printf("[!] Can't create socket for retrieving updates.\n");
1392 return -1;
1393 }
1394
1395 host.sin_family=AF_INET;
1396 host.sin_port=htons(80);
1397 host.sin_addr.s_addr=inet_addr("shttpscanner.sourceforge.net");
1398
1399 memcpy(&host.sin_addr.s_addr, h->h_addr_list[0], h->h_length);
1400
1401 error = connect(sock, (const struct sockaddr*) &host, sizeof(struct sockaddr));
1402
1403 if (error != 0) {
1404 printf("[!] Can't connect to shttpscanner.sourceforge.net by port 80 for retrieving updates.\n", o_handler.O_C_HOST, o_handler.O_C_PORT);
1405 return -1;
1406 }
1407
1408 strcpy(buffer, "GET /updates.csv HTTP/1.1\r\n"
1409 "User-agent: NST Bot Updater\r\n"
1410 "Host: shttpscanner.sourceforge.net\r\n\r\n");
1411
1412 send(sock, buffer, strlen(buffer), 0);
1413 recv(sock, rec, sizeof(rec), 0);
1414
1415 sprintf(response, "%c%c%c", rec[9], rec[10], rec[11]);
1416
1417 if (strcmp(response, "200") != 0) {
1418 printf("[!] Can't find updates.csv on shttpscanner.sourceforge.net\n");
1419 return -1;
1420 }
1421
1422 i = strlen(rec);
1423
1424 while (i >= 0) {
1425 if ((int) rec[i] == 10) {
1426 if (t_count == 0) t_count++;
1427 else {
1428 pos = i + 1;
1429 i = 0;
1430 }
1431 }
1432
1433 i--;
1434 }
1435
1436 update = (char *) malloc(sizeof(char) * (strlen(rec) - pos) + 3);
1437
1438 //printf("%d", (strlen(rec) - pos));
1439 for (i = 0; rec[pos + i] != (char) NULL && (int) rec[pos + i] != 10; i++) update[i] = rec[pos + i];
1440 update[i] = '\0';
1441
1442 p = strstr(update, ",");
1443 i = 0;
1444
1445 version = (char *) malloc((sizeof(char) * (p - update)) + 10);
1446
1447 while (i < (p - update)) {
1448 version[i] = update[i];
1449 i++;
1450 }
1451 version[i] = '\0';
1452 p++;
1453 i = 0;
1454 p1 = strstr(p, ",");
1455
1456 date = (char *) malloc((sizeof(char) * (p1 - p)) + 10);
1457
1458 while (i < (p1 - p)) {
1459 date[i] = update[i + (p - update)];
1460 i++;
1461 }
1462 date[i] = '\0';
1463
1464 p1++;
1465
1466 url = (char *) malloc((sizeof(char) * (strlen(update) - (p1 - update))) + 10);
1467 i = 0;
1468
1469 while ((int) *p1 != 0 && (int) *p1 != 10) {
1470 url[i] = *p1;
1471 i++;
1472 p1++;
1473 }
1474
1475 url[i] = '\0';
1476
1477 if (atof(version) > CURRENT_VERSION)
1478 printf("[+] The %s version was released on %s. You can download it on %s.\n", version, date, url);
1479 else
1480 printf("[+] There isn't a new version of NST Simple HTTP Scanner available.\n");
1481
1482 #ifdef WIN32
1483 closesocket(sock);
1484 #else
1485 shutdown(sock, SHUT_WR);
1486 close(sock);
1487 #endif
1488
1489 return 0;
1490 }
1491