Scan the entire Internet looking for webservers

This revision is from 2024/02/10 16:50. You can Restore it.

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SERVER_ADDR_SIZE sizeof(struct sockaddr_in)

#define PORT_80 80
#define PORT_443 443
#define IP_FILE "last_ip.txt"


int is_address_reachable(const char *ip_address, int port) {
    struct sockaddr_in sa;
    int sock;
    fd_set fdset;
    struct timeval tv;
    int flags;

    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr(ip_address);
    sa.sin_port = htons(port);

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("Socket creation error");
        return 0;
    }

    // Set the socket to non-blocking mode
    flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);

    if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        if (errno == EINPROGRESS) {
            // Connection attempt is in progress, wait for it to complete or timeout
            FD_ZERO(&fdset);
            FD_SET(sock, &fdset);
            tv.tv_sec = 2; // Timeout value in seconds
            tv.tv_usec = 0;
            if (select(sock + 1, NULL, &fdset, NULL, &tv) > 0) {
                int optval;
                socklen_t optlen = sizeof(optval);
                getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen);
                if (optval == 0) {
                    // Connection succeeded
                    close(sock);
                    return 1;
                }
            }
        }
        // Either connection failed or timed out
        perror("Connection error");
        close(sock);
        return 0;
    }

    // Connection succeeded immediately
    close(sock);
    return 1;
}


void save_last_ip(char *ip_address) {
    FILE *ip_file = fopen(IP_FILE, "w");
    if (ip_file != NULL) {
        fprintf(ip_file, "%sn", ip_address);
        fclose(ip_file);
    }
}

void load_last_ip(char *ip_address) {
    FILE *ip_file = fopen(IP_FILE, "r");
    if (ip_file != NULL) {
        fscanf(ip_file, "%s", ip_address);
        fclose(ip_file);
    }
}

int main() {
    int sock = 0;
    FILE *ssl_file = fopen("ssl.csv", "w");
    FILE *http_file = fopen("http.csv", "w");
    
    if (ssl_file == NULL || http_file == NULL) {
        perror("Failed to open CSV file");
        return 1;
    }

    char last_ip[16];
    load_last_ip(last_ip);

    int start_octet, start_octet_2, start_octet_3, start_octet_4;
    sscanf(last_ip, "%d.%d.%d.%d", &start_octet, &start_octet_2, &start_octet_3, &start_octet_4);

    for (int i = start_octet; i < 256; ++i) { // Loop for first octet
        for (int j = start_octet_2; j < 256; ++j) { // Loop for second octet
            for (int k = start_octet_3; k < 256; ++k) { // Loop for third octet
                for (int l = start_octet_4; l <= 255; ++l) { // Loop for fourth octet, start from 1 to exclude 0.0.0.0

                    char ip_address[16];
                    snprintf(ip_address, 16, "%d.%d.%d.%d", i, j, k, l);
                    printf("Scanning: %sn", ip_address); // Output the current IP being scanned

                        // Inside the loop where connection attempts are made
                        if (is_address_reachable(ip_address, 80)) {
                            fprintf(http_file, "%sn", ip_address);
                            fflush(http_file); // Ensure the data is written to the file immediately
                        }

                        if (is_address_reachable(ip_address, 443)) {
                            fprintf(ssl_file, "%sn", ip_address);
                            fflush(ssl_file); // Ensure the data is written to the file immediately
                        }

                            save_last_ip(ip_address);

                }
                start_octet_4 = 1; // Reset the fourth octet after finishing the loop
            }
            start_octet_3 = 0; // Reset the third octet after finishing the loop
        }
        start_octet_2 = 0; // Reset the second octet after finishing the loop
    }

    fclose(ssl_file);
    fclose(http_file);
    return 0;
}

Multi-Threded

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define SERVER_ADDR_SIZE sizeof(struct sockaddr_in)
#define PORT_53 53
#define PORT_80 80
#define PORT_443 443
#define IP_FILE "last_ip.txt"
#define NUM_THREADS 999

// Structure to hold thread arguments
struct ThreadArgs {
    char ip_address[16];
};

// Global variable to store the last IP address
char last_ip[16];

int is_address_reachable(const char *ip_address, int port) {
    struct sockaddr_in sa;
    int sock;
    fd_set fdset;
    struct timeval tv;
    int flags;

    memset(&sa, 0, sizeof(sa));
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = inet_addr(ip_address);
    sa.sin_port = htons(port);

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("Socket creation error");
        return 0;
    }

    // Set the socket to non-blocking mode
    flags = fcntl(sock, F_GETFL, 0);
    fcntl(sock, F_SETFL, flags | O_NONBLOCK);

    if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
        if (errno == EINPROGRESS) {
            // Connection attempt is in progress, wait for it to complete or timeout
            FD_ZERO(&fdset);
            FD_SET(sock, &fdset);
            tv.tv_sec = 2; // Timeout value in seconds
            tv.tv_usec = 0;
            if (select(sock + 1, NULL, &fdset, NULL, &tv) > 0) {
                int optval;
                socklen_t optlen = sizeof(optval);
                getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&optval, &optlen);
                if (optval == 0) {
                    // Connection succeeded
                    close(sock);
                    return 1;
                }
            }
        }
        // Either connection failed or timed out
        perror("Connection error");
        close(sock);
        return 0;
    }

    // Connection succeeded immediately
    close(sock);
    return 1;
}

void save_last_ip(char *ip_address) {
    FILE *ip_file = fopen(IP_FILE, "w");
    if (ip_file != NULL) {
        fprintf(ip_file, "%sn", ip_address);
        fclose(ip_file);
    }
}

void load_last_ip(char *ip_address) {
    FILE *ip_file = fopen(IP_FILE, "r");
    if (ip_file != NULL) {
        fscanf(ip_file, "%s", ip_address);
        fclose(ip_file);
    }
}

void *scan_ip(void *arg) {
    struct ThreadArgs *args = (struct ThreadArgs *)arg;

    char *ip_address = args->ip_address;

    printf("Scanning: %s, ", ip_address);

    if (is_address_reachable(ip_address, PORT_80)) {
        FILE *http_file = fopen("http.csv", "a");
        if (http_file != NULL) {
            fprintf(http_file, "%sn", ip_address);
            fclose(http_file);
        }
    }

    if (is_address_reachable(ip_address, PORT_443)) {
        FILE *ssl_file = fopen("ssl.csv", "a");
        if (ssl_file != NULL) {
            fprintf(ssl_file, "%sn", ip_address);
            fclose(ssl_file);
        }
    }

    if (is_address_reachable(ip_address, PORT_53)) {
        FILE *dns_file = fopen("dns.csv", "a");
        if (dns_file != NULL) {
            fprintf(dns_file, "%sn", ip_address);
            fclose(dns_file);
        }
    }

    strcpy(last_ip, ip_address); // Update last_ip

    return NULL;
}


// Signal handler for termination signals
void signal_handler(int signum) {
    // Save the last IP address to the file before exiting
    save_last_ip(last_ip);
    exit(signum);
}

// Function to check if a key is pressed
int kbhit(void) {
    struct termios oldt, newt;
    int ch;
    int oldf;

    // Set terminal to non-canonical mode
    tcgetattr(STDIN_FILENO, &oldt);
    newt = oldt;
    newt.c_lflag &= ~(ICANON | ECHO);
    tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);

    // Check for input
    ch = getchar();

    // Reset terminal to canonical mode
    tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    fcntl(STDIN_FILENO, F_SETFL, oldf);

    // If input is available, put it back into input buffer
    if(ch != EOF) {
        ungetc(ch, stdin);
        return 1;
    }

    return 0;
}

int main() {
    // Register signal handler for termination signals
    signal(SIGINT, signal_handler); // SIGINT (Ctrl+C)
    signal(SIGTERM, signal_handler); // SIGTERM

    pthread_t threads[NUM_THREADS];
    struct ThreadArgs thread_args[NUM_THREADS];

    load_last_ip(last_ip);

    int start_octet, start_octet_2, start_octet_3, start_octet_4;
    sscanf(last_ip, "%d.%d.%d.%d", &start_octet, &start_octet_2, &start_octet_3, &start_octet_4);

    int thread_index = 0;

    for (int i = start_octet; i < 256; ++i) { // Loop for first octet
        for (int j = start_octet_2; j < 256; ++j) { // Loop for second octet
            for (int k = start_octet_3; k < 256; ++k) { // Loop for third octet
                for (int l = start_octet_4; l <= 255; ++l) { // Loop for fourth octet, start from 1 to exclude 0.0.0.0

                    snprintf(thread_args[thread_index].ip_address, 16, "%d.%d.%d.%d", i, j, k, l);

                    // Create a thread for each IP address
                    pthread_create(&threads[thread_index], NULL, scan_ip, &thread_args[thread_index]);

                    // Increment thread index
                    ++thread_index;

                    // Ensure thread index doesn't exceed the number of threads
                    if (thread_index >= NUM_THREADS) {
                        // Join threads
                        for (int t = 0; t < NUM_THREADS; ++t) {
                            pthread_join(threads[t], NULL);
                        }

                        // Reset thread index
                        thread_index = 0;
                    }

                    // Check if a key is pressed
                    if (kbhit()) {
                        printf("Key pressed. Exiting...n");
                        save_last_ip(last_ip); // Save the last IP address before exiting
                        exit(0);
                    }

                }
                start_octet_4 = 1; // Reset the fourth octet after finishing the loop
            }
            start_octet_3 = 0; // Reset the third octet after finishing the loop
        }
        start_octet_2 = 0; // Reset the second octet after finishing the loop
    }

    // Join remaining threads
    for (int t = 0; t < thread_index; ++t) {
        pthread_join(threads[t], NULL);
    }

    save_last_ip(last_ip); 

    return 0;
}

  

📝 📜 ⏱️ ⬆️