Skip to content

Commit 44a0015

Browse files
committed
make src address for arpspoof cleanup configurable
1 parent ca785d1 commit 44a0015

File tree

2 files changed

+44
-6
lines changed

2 files changed

+44
-6
lines changed

arpspoof.8

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ intercept packets on a switched LAN
99
.na
1010
.nf
1111
.fi
12-
\fBarpspoof\fR [\fB-i \fIinterface\fR] [\fB-t \fItarget\fR] [\fB-r\fR] \fIhost\fR
12+
\fBarpspoof\fR [\fB-i \fIinterface\fR] [\fB-c \fIown|host|both\fR] [\fB-t \fItarget\fR] [\fB-r\fR] \fIhost\fR
1313
.SH DESCRIPTION
1414
.ad
1515
.fi
@@ -23,6 +23,10 @@ same, e.g. fragrouter(8)) must be turned on ahead of time.
2323
.SH OPTIONS
2424
.IP "\fB-i \fIinterface\fR"
2525
Specify the interface to use.
26+
.IP "\fB-c \fIown|host|both\fR"
27+
Specify which hardware address t use when restoring the arp configuration;
28+
while cleaning up, packets can be send with the own address as well as with
29+
the address of the host.
2630
.IP "\fB-t \fItarget\fR"
2731
Specify a particular host to ARP poison (if not specified, all hosts
2832
on the LAN). Repeat to specify multiple hosts.

arpspoof.c

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,14 @@ static int poison_reverse;
4343
static uint8_t *my_ha = NULL;
4444
static uint8_t *brd_ha = "\xff\xff\xff\xff\xff\xff";
4545

46+
static int cleanup_src_own = 1;
47+
static int cleanup_src_host = 0;
48+
4649
static void
4750
usage(void)
4851
{
4952
fprintf(stderr, "Version: " VERSION "\n"
50-
"Usage: arpspoof [-i interface] [-t target] [-r] host\n");
53+
"Usage: arpspoof [-i interface] [-c own|host|both] [-t target] [-r] host\n");
5154
exit(1);
5255
}
5356

@@ -152,18 +155,23 @@ cleanup(int sig)
152155
int fw = arp_find(spoof.ip, &spoof.mac);
153156
int bw = poison_reverse && targets[0].ip && arp_find_all();
154157
int i;
158+
int rounds = (cleanup_src_own*5 + cleanup_src_host*5);
155159

156160
fprintf(stderr, "Cleaning up and re-arping targets...\n");
157-
for (i = 0; i < 10; i++) {
161+
for (i = 0; i < rounds; i++) {
158162
struct host *target = targets;
159163
while(target->ip) {
164+
uint8_t *src_ha = NULL;
165+
if (cleanup_src_own && (i%2 || !cleanup_src_host)) {
166+
src_ha = my_ha;
167+
}
160168
/* XXX - on BSD, requires ETHERSPOOF kernel. */
161169
if (fw) {
162170
arp_send(l, ARPOP_REPLY,
163171
(u_int8_t *)&spoof.mac, spoof.ip,
164172
(target->ip ? (u_int8_t *)&target->mac : brd_ha),
165173
target->ip,
166-
(i%2 ? my_ha : NULL));
174+
src_ha);
167175
/* we have to wait a moment before sending the next packet */
168176
sleep(1);
169177
}
@@ -172,7 +180,7 @@ cleanup(int sig)
172180
(u_int8_t *)&target->mac, target->ip,
173181
(u_int8_t *)&spoof.mac,
174182
spoof.ip,
175-
(i%2 ? my_ha : NULL));
183+
src_ha);
176184
sleep(1);
177185
}
178186
target++;
@@ -191,6 +199,7 @@ main(int argc, char *argv[])
191199
char libnet_ebuf[LIBNET_ERRBUF_SIZE];
192200
int c;
193201
int n_targets;
202+
char *cleanup_src = NULL;
194203

195204
spoof.ip = 0;
196205
intf = NULL;
@@ -200,7 +209,7 @@ main(int argc, char *argv[])
200209
/* allocate enough memory for target list */
201210
targets = calloc( argc+1, sizeof(struct host) );
202211

203-
while ((c = getopt(argc, argv, "ri:t:h?V")) != -1) {
212+
while ((c = getopt(argc, argv, "ri:t:c:h?V")) != -1) {
204213
switch (c) {
205214
case 'i':
206215
intf = optarg;
@@ -212,6 +221,9 @@ main(int argc, char *argv[])
212221
case 'r':
213222
poison_reverse = 1;
214223
break;
224+
case 'c':
225+
cleanup_src = optarg;
226+
break;
215227
default:
216228
usage();
217229
}
@@ -227,6 +239,28 @@ main(int argc, char *argv[])
227239
usage();
228240
}
229241

242+
if (!cleanup_src || strcmp(cleanup_src, "host")==0) { /* default! */
243+
/* only use the target hw address when cleaning up;
244+
* this can screw up some bridges and scramble access
245+
* for our own host.
246+
*/
247+
cleanup_src_own = 0;
248+
cleanup_src_host = 1;
249+
} else if (strcmp(cleanup_src, "own")==0) {
250+
/* only use our own hw address when cleaning up,
251+
* not jeopardizing any bridges on the way to our
252+
* target
253+
*/
254+
cleanup_src_own = 1;
255+
cleanup_src_host = 0;
256+
} else if (strcmp(cleanup_src, "both")==0) {
257+
cleanup_src_own = 1;
258+
cleanup_src_host = 1;
259+
} else {
260+
errx(1, "Invalid parameter to -c: use 'own', 'host' or 'both'.");
261+
usage();
262+
}
263+
230264
if ((spoof.ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1)
231265
usage();
232266

0 commit comments

Comments
 (0)