Package: dsniff
Version: 2.4b1+debian-21.1
Severity: wishlist
Tags: patch upstream

This patch allows multiple targets to be imitated simultaniously
by arpspoof.
>From 25c761ebb1a8001d05da8b3dba36e96ac07ad586 Mon Sep 17 00:00:00 2001
From: Stefan Tomanek <ste...@pico.ruhr.de>
Date: Mon, 7 Nov 2011 17:40:50 +0100
Subject: [PATCH 2/3] arpspoof: allow use of of multiple targets


Signed-off-by: Stefan Tomanek <ste...@pico.ruhr.de>
---
 arpspoof.8 |    2 +-
 arpspoof.c |  102 ++++++++++++++++++++++++++++++++++++++++--------------------
 2 files changed, 69 insertions(+), 35 deletions(-)

diff --git a/arpspoof.8 b/arpspoof.8
index 544e06c..af7ff63 100644
--- a/arpspoof.8
+++ b/arpspoof.8
@@ -25,7 +25,7 @@ same, e.g. fragrouter(8)) must be turned on ahead of time.
 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).
+on the LAN). Repeat to specify multiple hosts.
 .IP "\fB-r\fR"
 Poison both hosts (host and target) to capture traffic in both directions.
 (only valid in conjuntion with -t)
diff --git a/arpspoof.c b/arpspoof.c
index f51b699..a819678 100644
--- a/arpspoof.c
+++ b/arpspoof.c
@@ -29,9 +29,14 @@
 
 extern char *ether_ntoa(struct ether_addr *);
 
+struct host {
+       in_addr_t ip;
+       struct ether_addr mac;
+};
+
 static libnet_t *l;
-static struct ether_addr spoof_mac, target_mac;
-static in_addr_t spoof_ip, target_ip;
+static struct host spoof = {0};
+static struct host *targets;
 static char *intf;
 static int poison_reverse;
 
@@ -133,30 +138,46 @@ arp_find(in_addr_t ip, struct ether_addr *mac)
        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
 cleanup(int sig)
 {
-       int fw = arp_find(spoof_ip, &spoof_mac);
-       int bw = poison_reverse && target_ip && arp_find(target_ip, 
&target_mac);
+       int fw = arp_find(spoof.ip, &spoof.mac);
+       int bw = poison_reverse && targets[0].ip && arp_find_all();
        int i;
 
        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);
+               struct host *target = targets;
+               while(target->ip) {
+                       /* 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);
+                       }
+                       target++;
                }
        }
 
@@ -171,10 +192,15 @@ main(int argc, char *argv[])
        char pcap_ebuf[PCAP_ERRBUF_SIZE];
        char libnet_ebuf[LIBNET_ERRBUF_SIZE];
        int c;
+       int n_targets;
 
+       spoof.ip = 0;
        intf = NULL;
-       spoof_ip = target_ip = 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) {
                switch (c) {
@@ -182,7 +208,7 @@ main(int argc, char *argv[])
                        intf = optarg;
                        break;
                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();
                        break;
                case 'r':
@@ -198,12 +224,12 @@ main(int argc, char *argv[])
        if (argc != 1)
                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).");
                usage();
        }
 
-       if ((spoof_ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
+       if ((spoof.ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
                usage();
        
        if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL)
@@ -211,15 +237,19 @@ main(int argc, char *argv[])
        
        if ((l = libnet_init(LIBNET_LINK, intf, libnet_ebuf)) == NULL)
                errx(1, "%s", libnet_ebuf);
-       
-       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));
+
+       struct host *target = targets;
+       while(target->ip) {
+               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 (!arp_find(spoof_ip, &spoof_mac)) {
+               if (!arp_find(spoof.ip, &spoof.mac)) {
                        errx(1, "couldn't arp for spoof host %s",
-                            libnet_addr2name4(spoof_ip, LIBNET_DONT_RESOLVE));
+                            libnet_addr2name4(spoof.ip, LIBNET_DONT_RESOLVE));
                }
        }
 
@@ -228,11 +258,15 @@ main(int argc, char *argv[])
        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);
+               struct host *target = targets;
+               while(target->ip) {
+                       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);
+                       }
+                       target++;
                }
 
                sleep(2);
-- 
1.7.5.4

Reply via email to