summaryrefslogtreecommitdiffstats
path: root/network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch
diff options
context:
space:
mode:
Diffstat (limited to 'network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch')
-rw-r--r--network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch230
1 files changed, 230 insertions, 0 deletions
diff --git a/network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch b/network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch
new file mode 100644
index 0000000000..95da6a1651
--- /dev/null
+++ b/network/dsniff/patches/28_arpspoof-allow-selection-of-source-hw-address.patch
@@ -0,0 +1,230 @@
+>From 21773ccf18a5fc49d35e510a8797b0a1e83858c4 Mon Sep 17 00:00:00 2001
+From: Stefan Tomanek <stefan@pico.ruhr.de>
+Date: Sun, 20 Nov 2011 21:32:53 +0100
+Subject: [PATCH 3/3] arpspoof: allow selection of source hw address
+
+In certain networks, sending with the wrong hardware source address can
+jeopardize the network connection of the host running arpspoof. This
+patch makes it possible to specify whether arpspoof should use the own
+hardware address or the one of the real host when resetting the arp
+table of the target systems; it is also possible to use both.
+
+Signed-off-by: Stefan Tomanek <stefan@pico.ruhr.de>
+---
+ arpspoof.8 | 9 +++++-
+ arpspoof.c | 90 ++++++++++++++++++++++++++++++++++++++++++-----------------
+ 2 files changed, 72 insertions(+), 27 deletions(-)
+---
+This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
+
+--- a/arpspoof.8
++++ b/arpspoof.8
+@@ -9,7 +9,7 @@
+ .na
+ .nf
+ .fi
+-\fBarpspoof\fR [\fB\-i \fIinterface\fR] [\fB\-t \fItarget\fR] [\fB\-r\fR] \fIhost\fR
++\fBarpspoof\fR [\fB\-i \fIinterface\fR] [\fB\-c \fIown|host|both\fR] [\fB\-t \fItarget\fR] [\fB\-r\fR] \fIhost\fR
+ .SH DESCRIPTION
+ .ad
+ .fi
+@@ -23,6 +23,13 @@
+ .SH OPTIONS
+ .IP "\fB-i \fIinterface\fR"
+ Specify the interface to use.
++.IP "\fB-c \fIown|host|both\fR"
++Specify which hardware address t use when restoring the arp configuration;
++while cleaning up, packets can be send with the own address as well as with
++the address of the host. Sending packets with a fake hw address can disrupt
++connectivity with certain switch/ap/bridge configurations, however it works
++more reliably than using the own address, which is the default way arpspoof
++cleans up afterwards.
+ .IP "\fB-t \fItarget\fR"
+ Specify a particular host to ARP poison (if not specified, all hosts
+ on the LAN). Repeat to specify multiple hosts.
+--- a/arpspoof.c
++++ b/arpspoof.c
+@@ -40,37 +40,36 @@
+ static char *intf;
+ static int poison_reverse;
+
++static uint8_t *my_ha = NULL;
++static uint8_t *brd_ha = "\xff\xff\xff\xff\xff\xff";
++
++static int cleanup_src_own = 1;
++static int cleanup_src_host = 0;
++
+ static void
+ usage(void)
+ {
+ fprintf(stderr, "Version: " VERSION "\n"
+- "Usage: arpspoof [-i interface] [-t target] [-r] host\n");
++ "Usage: arpspoof [-i interface] [-c own|host|both] [-t target] [-r] host\n");
+ exit(1);
+ }
+
+ static int
+-arp_send(libnet_t *l, int op, u_int8_t *sha,
+- in_addr_t spa, u_int8_t *tha, in_addr_t tpa)
++arp_send(libnet_t *l, int op,
++ u_int8_t *sha, in_addr_t spa,
++ u_int8_t *tha, in_addr_t tpa,
++ u_int8_t *me)
+ {
+ int retval;
+
+- if (sha == NULL &&
+- (sha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) {
+- return (-1);
+- }
+- if (spa == 0) {
+- if ((spa = libnet_get_ipaddr4(l)) == -1)
+- return (-1);
+- }
+- if (tha == NULL)
+- tha = "\xff\xff\xff\xff\xff\xff";
+-
++ if (!me) me = sha;
++
+ libnet_autobuild_arp(op, sha, (u_int8_t *)&spa,
+ tha, (u_int8_t *)&tpa, l);
+- libnet_build_ethernet(tha, sha, ETHERTYPE_ARP, NULL, 0, l, 0);
++ libnet_build_ethernet(tha, me, ETHERTYPE_ARP, NULL, 0, l, 0);
+
+ fprintf(stderr, "%s ",
+- ether_ntoa((struct ether_addr *)sha));
++ ether_ntoa((struct ether_addr *)me));
+
+ if (op == ARPOP_REQUEST) {
+ fprintf(stderr, "%s 0806 42: arp who-has %s tell %s\n",
+@@ -129,7 +128,7 @@
+ /* XXX - force the kernel to arp. feh. */
+ arp_force(ip);
+ #else
+- arp_send(l, ARPOP_REQUEST, NULL, 0, NULL, ip);
++ arp_send(l, ARPOP_REQUEST, NULL, 0, NULL, ip, NULL);
+ #endif
+ sleep(1);
+ }
+@@ -156,17 +155,23 @@
+ int fw = arp_find(spoof.ip, &spoof.mac);
+ int bw = poison_reverse && targets[0].ip && arp_find_all();
+ int i;
++ int rounds = (cleanup_src_own*5 + cleanup_src_host*5);
+
+ fprintf(stderr, "Cleaning up and re-arping targets...\n");
+- for (i = 0; i < 5; i++) {
++ for (i = 0; i < rounds; i++) {
+ struct host *target = targets;
+ while(target->ip) {
++ uint8_t *src_ha = NULL;
++ if (cleanup_src_own && (i%2 || !cleanup_src_host)) {
++ src_ha = my_ha;
++ }
+ /* 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);
++ (target->ip ? (u_int8_t *)&target->mac : brd_ha),
++ target->ip,
++ src_ha);
+ /* we have to wait a moment before sending the next packet */
+ sleep(1);
+ }
+@@ -174,7 +179,8 @@
+ arp_send(l, ARPOP_REPLY,
+ (u_int8_t *)&target->mac, target->ip,
+ (u_int8_t *)&spoof.mac,
+- spoof.ip);
++ spoof.ip,
++ src_ha);
+ sleep(1);
+ }
+ target++;
+@@ -193,6 +199,7 @@
+ char libnet_ebuf[LIBNET_ERRBUF_SIZE];
+ int c;
+ int n_targets;
++ char *cleanup_src = NULL;
+
+ spoof.ip = 0;
+ intf = NULL;
+@@ -202,7 +209,7 @@
+ /* 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:c:h?V")) != -1) {
+ switch (c) {
+ case 'i':
+ intf = optarg;
+@@ -214,6 +221,9 @@
+ case 'r':
+ poison_reverse = 1;
+ break;
++ case 'c':
++ cleanup_src = optarg;
++ break;
+ default:
+ usage();
+ }
+@@ -229,6 +239,29 @@
+ usage();
+ }
+
++ if (!cleanup_src || strcmp(cleanup_src, "own")==0) { /* default! */
++ /* only use our own hw address when cleaning up,
++ * not jeopardizing any bridges on the way to our
++ * target
++ */
++ cleanup_src_own = 1;
++ cleanup_src_host = 0;
++ } else if (strcmp(cleanup_src, "host")==0) {
++ /* only use the target hw address when cleaning up;
++ * this can screw up some bridges and scramble access
++ * for our own host, however it resets the arp table
++ * more reliably
++ */
++ cleanup_src_own = 0;
++ cleanup_src_host = 1;
++ } else if (strcmp(cleanup_src, "both")==0) {
++ cleanup_src_own = 1;
++ cleanup_src_host = 1;
++ } else {
++ errx(1, "Invalid parameter to -c: use 'own' (default), 'host' or 'both'.");
++ usage();
++ }
++
+ if ((spoof.ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
+ usage();
+
+@@ -253,6 +286,10 @@
+ }
+ }
+
++ if ((my_ha = (u_int8_t *)libnet_get_hwaddr(l)) == NULL) {
++ errx(1, "Unable to determine own mac address");
++ }
++
+ signal(SIGHUP, cleanup);
+ signal(SIGINT, cleanup);
+ signal(SIGTERM, cleanup);
+@@ -263,11 +300,12 @@
+ } else {
+ 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);
++ arp_send(l, ARPOP_REPLY, my_ha, spoof.ip,
++ (target->ip ? (u_int8_t *)&target->mac : brd_ha),
++ target->ip,
++ my_ha);
+ if (poison_reverse) {
+- arp_send(l, ARPOP_REPLY, NULL, target->ip, (uint8_t *)&spoof.mac, spoof.ip);
++ arp_send(l, ARPOP_REPLY, my_ha, target->ip, (uint8_t *)&spoof.mac, spoof.ip, my_ha);
+ }
+ target++;
+ }