Covert Tunnelling in ICMP 0x00 ECHO REPLY messages for Windows.
4262694dbb61e796e99741c6d41e263dbe37a5eee399e98fdd70e9d047dc32cc
/*
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);
}
};