---------------------[ previous ]---[ index ]---[ next ]----------------------

==============================================================================
------------[ BFi numero 7, anno 2 - 25/12/1999 - file 13 di 22 ]-------------
==============================================================================


-[ HACKiNG ]------------------------------------------------------------------
---[ UNDERC0VER W0RK - Dashie


Tempo Impiegato:  tante ore a leggere la documentazione MicroSux e 10 minuti
 		  a scrivere il codice...

Cibo Ingerito: mezzo litro di Gatorade skifosa all'arancia rossa
	       tonnellate di gelato
	       1,5 litri di coca allungata con la fanta.... Dio che caldo!!!

Dedicato a: Miky, la ragazza che mi ha sconvolto la vita
	    Benares, il suo attuale ragazzo nonche' mio prezioso amico
	    \sPIRIT\, perche' le sue vaccate estive mi fan sempre squartare
	    pIGpEN, perche' altrimenti mi dimenticherei dell'esistenza dello
		    unix
	    FuSyS, per avermi fatto venir voglia di leggere TUTTO il
		   TCP/IP Illustrated
	    Microsoft, Dio Bit perdonali perche' non sanno quello che fanno...

Eccomi qui! L'Oscuro Distruttore, l'Adamo dell'oscurita', il salvatore degli
Inferi e' tornato! Eheh...
Dopo mesi di girovagare nei piu' profondi recessi dell'Abisso sono magicamente
riapparso portando con me qualcosa di carino... Un interessante spunto per
tutti quelli che avranno letto l'articolo di FuSyS sull'ICMP tunnelling...
In poche parole questa e' una libreria, esattamente come quella proposta da
FuSyS, che fornisce funzioni per l'incapsulamento di dati nei pacchetti ICMP.
L'unica differenza e' che la suddetta libreria e' stata riadattata per essere
compilata anche sotto winsozzz.
Il libero arbitrio vi consente di farne cio' che volete, e siccome di spunti
ve ne ha dati gia' FuSyS a sufficienza, direi che e' il caso vi guardiate il
codice e proviate a scriverci qualcosa...

icmp_tunnel.h
---------- snip ----------
/*

Covert Tunnelling in ICMP 0x00 ECHO REPLY messages

  Many thanks to FuSyS and Richard Stevens ^_^

Dark Schneider X1999

*/

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>

#define ICMP_ECHOREPLY	0
#define ICMP_ECHO	8

// definizione di alcune costanti 

#define IP_HDR	20
#define ICMP_HDR 8
#define ICMP_MINLEN	8
#define MAXMESG	4096
#define MAXPACKET 5004
#define LAST	1
#define REPLY	1
#define ECHO_TAG	0xF001
#define ECHO_LAST	0xF002

// Strutture e Variabili
// Lancio un doveroso Porko D*io liberatorio... dopo ore ho trovato come fare
// a togliermi dalle palle la fottuta icmp.dll (winsock maledette)

// IP Header
struct ip
{
	unsigned char	Hlen:4;         
	unsigned char	Version:4;       
	unsigned char	Tos;            
	unsigned short	LungTot;    
	unsigned short	Id;         
	unsigned short	Flags;
	unsigned char	Ttl; 
	unsigned char	Proto;           
	unsigned short	Checksum;       
	unsigned int	SourceIP;
	unsigned int	DestIP;

};

// ICMP Header
struct icmp {
			BYTE		Type;
			BYTE		Code; 
			USHORT		CheckSum;
			USHORT		Id;
			USHORT		Seq;
			ULONG		Dati;
			};

SOCKET				sockfd;
u_int				icmp_init =1;
struct sockaddr_in	clisrc;

// Funzione di checksum 

USHORT checksum(USHORT *buffer, int size)
{

  unsigned long cksum=0;

  while(size >1)
  {
	cksum+=*buffer++;
	size -=sizeof(USHORT);
  }
  
  if(size )
  {
	cksum += *(UCHAR*)buffer;
  }

  cksum = (cksum >> 16) + (cksum & 0xffff);
  cksum += (cksum >>16);
  return (USHORT)(~cksum);
}

// Reimplemento bcopy e bzero... Ma perche' cavolo windows non le
// rende disponibili?

void bzero(char *pnt, int dim_pnt )
{
	memset((char *)&pnt, 0, dim_pnt);
};

void bcopy(char *src, char *dest, int dim_src)
{
	memmove((char *)&dest, (char *)&src, dim_src);
};

// Micro$oft Sucks
// Funzioni di gestione dei pacchetti ICMP
// Fankulo a quegli stronzi maledetti che si sono inventati la icmp.dll
// Brutti bastardi pezzi di merda, la compatibilita' ve la siete ficcata su
// per il culo?
// Micro$oft Sucks

void ICMP_init(void)
	{
	if(icmp_init)
		{
		if((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == INVALID_SOCKET)
			{
			fprintf(stderr, "impossibile creare raw ICMP socket");
			exit(0);
			}
		}
	icmp_init = 0;
	};

void ICMP_reset(void)
	{
	closesocket(sockfd);
	icmp_init = 1;
	};

int ICMP_send(char *send_mesg, size_t mesglen, ULONG dest_ip, int echo, int last)
	{
	int						sparato;
	struct tunnel
		{
		struct icmp		 icmp;
		UCHAR			 data[MAXMESG];
		} icmp_pk;
	int						icmplen	= sizeof(struct icmp);
	int						pack_dim;
	struct sockaddr_in		dest;
	int						destlen;

	if(mesglen > MAXMESG) return(-1);
	
	if(icmp_init) ICMP_init();

	destlen						= sizeof(dest);
	bzero((char *)&dest, destlen);
	dest.sin_family				= AF_INET;
	dest.sin_addr.s_addr		= dest_ip;
	pack_dim					= mesglen + sizeof(struct icmp);
	memset(&icmp_pk, 0, pack_dim);
	icmp_pk.icmp.Type			= ICMP_ECHOREPLY;
	bcopy(send_mesg, (char *)&icmp_pk.icmp.Dati, mesglen);
	icmp_pk.icmp.CheckSum		= checksum((USHORT *) &icmp_pk.icmp, (sizeof(struct icmp) + mesglen));
	if(echo) icmp_pk.icmp.Seq	= ECHO_TAG;
	if(last) icmp_pk.icmp.Seq	= ECHO_LAST;

	if(sparato = sendto(sockfd, (char *)&icmp_pk, pack_dim, 0, (struct sockaddr *)&dest, destlen) < 0)
		{
		perror("RAW ICMP SendTo: ");
		return(-1);
		} 
		else if(sparato != pack_dim)
		{
		perror("dimensioni pacchetto IP errate: ");
		return(-1);
		}
		return(sparato);
	};

int ICMP_recv(char *recv_mesg, size_t mesglen, int echo)
	{
	struct recv
		{
		struct ip	ip;
		struct icmp icmp;
		char		data[MAXMESG];
		} rcv_pk;
	int				pack_dim;
	int				accolto;
	int				iphdrlen;
	int				clilen = sizeof(clisrc);

	if(icmp_init) ICMP_init();
	while(1)
		{
		pack_dim = mesglen + sizeof(struct ip) + sizeof(struct icmp);
		memset(&rcv_pk, 0, pack_dim);
		if((accolto = recvfrom(sockfd, (char *)&rcv_pk, pack_dim, 0, (struct sockaddr *) &clisrc, &clilen)) < 0) continue;

		iphdrlen = rcv_pk.ip.Hlen << 2;
		if(accolto < (iphdrlen + ICMP_MINLEN)) continue;
		accolto -= iphdrlen;

		if(!echo)
			{
			if(!rcv_pk.icmp.Id && !rcv_pk.icmp.Code && rcv_pk.icmp.Type == ICMP_ECHOREPLY && rcv_pk.icmp.Seq != ECHO_TAG && rcv_pk.icmp.Seq != ECHO_LAST) break;
			}
		if(echo)
			{
			if(!rcv_pk.icmp.Id && !rcv_pk.icmp.Code && rcv_pk.icmp.Type == ICMP_ECHOREPLY && (rcv_pk.icmp.Seq == ECHO_TAG || rcv_pk.icmp.Seq == ECHO_LAST)) break;
			}
		}
		if(!echo)
			{
			accolto -= ICMP_HDR;
			bcopy((char *)&rcv_pk.icmp.Dati, recv_mesg, accolto);
			return(accolto);
			}
		if(echo)
			{
			if(rcv_pk.icmp.Seq == ECHO_TAG)
				{
				accolto -= ICMP_HDR;
				bzero(recv_mesg, sizeof(recv_mesg));
				bcopy((char *)&rcv_pk.icmp.Dati, recv_mesg, accolto);
				return(accolto);
				}
			return(-666);
			}
	};

Qua finisce il codice della libreria. Per scrivere programmi e' inoltre
assolutamente necessario inserire alcune righe di codice nel main:

void main(int argc, char **argv)
	{

	WSADATA ws;
	int status;

	// Inizializzazione delle Winsock
	if(status = WSAStartup(0x101, &ws) != 0)
		{
		fprintf(stderr, "Impossibile inizializzare Winsock");
		exit(0);
		}

// qua ci va il codice vero e proprio, ma devo dire che mi passa la voglia di
// scriverlo dopo le madonne che ho tirato per far girare il codice ICMP...

	// Chiusura e deallocazione
	WSACleanup();
	}

Questo e' dovuto al fatto che le winsock hanno la necessita' di essere
inizializzate: in pratica e' un po' come se si dovesse dire al sistema
"Occhio che da qui in poi uso le Winsock e quindi prepara tutte le interfacce"
o una roba del genere... So che non e' molto tecnico, ma non ho trovato
nessuna definizione rigorosa del perche' sia necessaria una dichiarazione
esplicita di inizializzazione... Misteri imperscrutabili di mamma Miciosoft...


==============================================================================
--------------------------------[ EOF 13/22 ]---------------------------------
==============================================================================

---------------------[ previous ]---[ index ]---[ next ]----------------------