diff --git a/dsniff-2.4-arpspoof_hwaddr.patch b/dsniff-2.4-arpspoof_hwaddr.patch new file mode 100644 index 0000000..9d03533 --- /dev/null +++ b/dsniff-2.4-arpspoof_hwaddr.patch @@ -0,0 +1,218 @@ +Patch by Stefan Tomanek for dsniff >= 2.4b1 to allow the +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. + +For some more information, please have a look to Debian bug ID #650752. + +--- dsniff-2.4/arpspoof.8 2013-12-20 20:54:25.000000000 +0100 ++++ dsniff-2.4/arpspoof.8.arpspoof_hwaddr 2013-12-20 20:55:19.000000000 +0100 +@@ -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. +--- dsniff-2.4/arpspoof.c 2013-12-20 20:54:25.000000000 +0100 ++++ dsniff-2.4/arpspoof.c.arpspoof_hwaddr 2013-12-20 21:02:10.000000000 +0100 +@@ -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,22 @@ + 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 +178,7 @@ + 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 +197,7 @@ + char libnet_ebuf[LIBNET_ERRBUF_SIZE]; + int c; + int n_targets; ++ char *cleanup_src = NULL; + + spoof.ip = 0; + intf = NULL; +@@ -202,7 +207,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 +219,9 @@ + case 'r': + poison_reverse = 1; + break; ++ case 'c': ++ cleanup_src = optarg; ++ break; + default: + usage(); + } +@@ -229,6 +237,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 +284,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); +@@ -260,11 +295,11 @@ + for (;;) { + 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++; + } diff --git a/dsniff-2.4-arpspoof_multiple.patch b/dsniff-2.4-arpspoof_multiple.patch new file mode 100644 index 0000000..fced529 --- /dev/null +++ b/dsniff-2.4-arpspoof_multiple.patch @@ -0,0 +1,186 @@ +Patch by Stefan Tomanek for dsniff >= 2.4b1 to allow the use +of of multiple targets. For some more information, please have a look to Debian bug +ID #650751. + +--- dsniff-2.4/arpspoof.8 2013-12-20 20:40:36.000000000 +0100 ++++ dsniff-2.4/arpspoof.8.arpspoof_multiple 2013-12-20 20:41:45.000000000 +0100 +@@ -25,7 +25,7 @@ + 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) +--- dsniff-2.4/arpspoof.c 2013-12-20 20:40:36.000000000 +0100 ++++ dsniff-2.4/arpspoof.c.arpspoof_multiple 2013-12-20 20:50:34.000000000 +0100 +@@ -27,11 +27,16 @@ + #include "arp.h" + #include "version.h" + ++struct host { ++ in_addr_t ip; ++ struct ether_addr mac; ++}; ++ + extern char *ether_ntoa(struct ether_addr *); + + 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 @@ + 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 @@ + 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 @@ + 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 @@ + 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) +@@ -212,14 +238,18 @@ + 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 @@ + 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); + } diff --git a/dsniff-2.4-arpspoof_reverse.patch b/dsniff-2.4-arpspoof_reverse.patch new file mode 100644 index 0000000..7087937 --- /dev/null +++ b/dsniff-2.4-arpspoof_reverse.patch @@ -0,0 +1,142 @@ +Patch by Stefan Tomanek for dsniff >= 2.4b1 to add add -r +switch to poison both directions. For some more information, please have a look to +Debian bug ID #650749. + +--- dsniff-2.4/arpspoof.8 2000-11-28 08:43:43.000000000 +0100 ++++ dsniff-2.4/arpspoof.8.arpspoof_reverse 2013-12-20 20:27:49.000000000 +0100 +@@ -9,7 +9,7 @@ + .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 @@ + .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). +--- dsniff-2.4/arpspoof.c 2013-12-20 20:25:04.000000000 +0100 ++++ dsniff-2.4/arpspoof.c.arpspoof_reverse 2013-12-20 20:34:31.000000000 +0100 +@@ -7,6 +7,8 @@ + * Copyright (c) 1999 Dug Song + * + * $Id: arpspoof.c,v 1.5 2001/03/15 08:32:58 dugsong Exp $ ++ * ++ * Improved 2011 by Stefan Tomanek + */ + + #include "config.h" +@@ -31,12 +33,13 @@ + 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 @@ + 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); + } + +@@ -159,8 +174,9 @@ + + intf = NULL; + spoof_ip = target_ip = 0; ++ poison_reverse = 0; + +- while ((c = getopt(argc, argv, "i:t:h?V")) != -1) { ++ while ((c = getopt(argc, argv, "ri:t:h?V")) != -1) { + switch (c) { + case 'i': + intf = optarg; +@@ -169,6 +185,9 @@ + if ((target_ip = libnet_name2addr4(l, optarg, LIBNET_RESOLVE)) == -1) + usage(); + break; ++ case 'r': ++ poison_reverse = 1; ++ break; + default: + usage(); + } +@@ -179,6 +198,11 @@ + 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(); + +@@ -192,6 +216,13 @@ + 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); +@@ -200,6 +231,9 @@ + 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 */ diff --git a/dsniff-2.4-libnet_name2addr4.patch b/dsniff-2.4-libnet_name2addr4.patch new file mode 100644 index 0000000..b5c9749 --- /dev/null +++ b/dsniff-2.4-libnet_name2addr4.patch @@ -0,0 +1,140 @@ +Patch by Robert Scheck for dsniff >= 2.4b1 which fixes +possible segmentation faults of arpspoof, sshmitm, webmitm and webspy if any non- +resolving hostname is passed. Issue was introduced by dsniff-2.4-libnet_11.patch; +libnet_name_resolve() was replaced by libnet_name2addr4() while there must be the +structure libnet_t passed additionally. And if that structure is not initialized +using libnet_init() and the passed name can't be resolved (like "192.168.2."), it +causes a snprintf() to NULL and thus the segmentation fault. Note that macof isn't +affected as no resolving was involved here ever. Please also have a look to Red Hat +Bugzilla ID #1009879 for further information. + +--- dsniff-2.4/sshmitm.c 2013-12-20 21:19:58.000000000 +0100 ++++ dsniff-2.4/sshmitm.c.libnet_name2addr4 2013-12-20 21:29:44.000000000 +0100 +@@ -45,6 +45,8 @@ + struct sockaddr_in csin, ssin; + int sig_pipe[2]; + ++static libnet_t *l; ++ + static void + usage(void) + { +@@ -364,6 +366,7 @@ + u_long ip; + u_short lport, rport; + int c; ++ char libnet_ebuf[LIBNET_ERRBUF_SIZE]; + + lport = rport = 22; + +@@ -390,12 +393,15 @@ + if (argc < 1) + usage(); + +- if ((ip = libnet_name2addr4(NULL, argv[0], LIBNET_RESOLVE)) == -1) +- usage(); +- + if (argc == 2 && (rport = atoi(argv[1])) == 0) + usage(); + ++ if ((l = libnet_init(LIBNET_LINK, NULL, libnet_ebuf)) == NULL) ++ errx(1, "%s", libnet_ebuf); ++ ++ if ((ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) ++ usage(); ++ + record_init(NULL); + + mitm_init(lport, ip, rport); +--- dsniff-2.4/webmitm.c 2013-12-20 21:19:58.000000000 +0100 ++++ dsniff-2.4/webmitm.c.libnet_name2addr4 2013-12-20 21:40:09.000000000 +0100 +@@ -47,6 +47,8 @@ + int do_ssl, sig_pipe[2]; + in_addr_t static_host = 0; + ++static libnet_t *l; ++ + extern int decode_http(char *, int, char *, int); + + static void +@@ -242,7 +244,7 @@ + word = buf_tok(&msg, "/", 1); + vhost = buf_strdup(word); + } +- ssin.sin_addr.s_addr = libnet_name2addr4(NULL, vhost, 1); ++ ssin.sin_addr.s_addr = libnet_name2addr4(l, vhost, LIBNET_RESOLVE); + free(vhost); + + if (ssin.sin_addr.s_addr == ntohl(INADDR_LOOPBACK) || +@@ -496,6 +498,7 @@ + extern char *optarg; + extern int optind; + int c; ++ char libnet_ebuf[LIBNET_ERRBUF_SIZE]; + + while ((c = getopt(argc, argv, "dh?V")) != -1) { + switch (c) { +@@ -509,8 +512,11 @@ + argc -= optind; + argv += optind; + ++ if ((l = libnet_init(LIBNET_LINK, NULL, libnet_ebuf)) == NULL) ++ errx(1, "%s", libnet_ebuf); ++ + if (argc == 1) { +- if ((static_host = libnet_name2addr4(NULL, argv[0], 1)) == -1) ++ if ((static_host = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) + usage(); + } + else if (argc != 0) usage(); +--- dsniff-2.4/webspy.c 2013-12-20 21:19:58.000000000 +0100 ++++ dsniff-2.4/webspy.c.libnet_name2addr4 2013-12-20 21:45:57.000000000 +0100 +@@ -33,6 +33,7 @@ + extern int mozilla_remote_commands (Display *, Window, char **); + char *expected_mozilla_version = "4.7"; + char *progname = "webspy"; ++static libnet_t *l; + + Display *dpy; + char cmd[2048], *cmdtab[2]; +@@ -183,6 +184,7 @@ + extern char *optarg; + extern int optind; + int c; ++ char libnet_ebuf[LIBNET_ERRBUF_SIZE]; + + while ((c = getopt(argc, argv, "i:p:h?V")) != -1) { + switch (c) { +@@ -205,7 +207,10 @@ + cmdtab[0] = cmd; + cmdtab[1] = NULL; + +- if ((host = libnet_name2addr4(NULL, argv[0], 1)) == -1) ++ if ((l = libnet_init(LIBNET_LINK, NULL, libnet_ebuf)) == NULL) ++ errx(1, "%s", libnet_ebuf); ++ ++ if ((host = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) + errx(1, "unknown host"); + + if ((dpy = XOpenDisplay(NULL)) == NULL) +--- dsniff-2.4/arpspoof.c 2013-12-20 22:00:53.000000000 +0100 ++++ dsniff-2.4/arpspoof.c.libnet_name2addr4 2013-12-20 22:00:38.000000000 +0100 +@@ -207,6 +207,9 @@ + /* allocate enough memory for target list */ + targets = calloc( argc+1, sizeof(struct host) ); + ++ if ((l = libnet_init(LIBNET_LINK, NULL, libnet_ebuf)) == NULL) ++ errx(1, "%s", libnet_ebuf); ++ + while ((c = getopt(argc, argv, "ri:t:c:h?V")) != -1) { + switch (c) { + case 'i': +@@ -263,6 +266,8 @@ + if ((spoof.ip = libnet_name2addr4(l, argv[0], LIBNET_RESOLVE)) == -1) + usage(); + ++ libnet_destroy(l); ++ + if (intf == NULL && (intf = pcap_lookupdev(pcap_ebuf)) == NULL) + errx(1, "%s", pcap_ebuf); + diff --git a/dsniff-2.4-modernize_pop.patch b/dsniff-2.4-modernize_pop.patch new file mode 100644 index 0000000..479cfd2 --- /dev/null +++ b/dsniff-2.4-modernize_pop.patch @@ -0,0 +1,122 @@ +Patch by Stefan Tomanek for dsniff >= 2.4b1 to rewrite and +modernize the POP decoder. For some more information, please have a look to Debian +bug ID #647583. + +--- dsniff-2.4/decode_pop.c 2013-12-20 21:06:13.000000000 +0100 ++++ dsniff-2.4/decode_pop.c.modernize_pop 2013-12-20 21:12:58.000000000 +0100 +@@ -6,6 +6,8 @@ + * Copyright (c) 2000 Dug Song + * + * $Id: decode_pop.c,v 1.4 2001/03/15 08:33:02 dugsong Exp $ ++ * ++ * Rewritten by Stefan Tomanek 2011 + */ + + #include "config.h" +@@ -45,32 +47,87 @@ + decode_pop(u_char *buf, int len, u_char *obuf, int olen) + { + char *p; ++ char *s; ++ int n; + int i, j; ++ char *user; ++ char *password; ++ enum { ++ NONE, ++ AUTHPLAIN, ++ AUTHLOGIN, ++ USERPASS ++ } mode = NONE; + + obuf[0] = '\0'; + + for (p = strtok(buf, "\r\n"); p != NULL; p = strtok(NULL, "\r\n")) { +- if (strncasecmp(p, "AUTH PLAIN", 10) == 0 || +- strncasecmp(p, "AUTH LOGIN", 10) == 0) { +- strlcat(obuf, p, olen); +- strlcat(obuf, "\n", olen); +- +- /* Decode SASL auth. */ +- for (i = 0; i < 2 && (p = strtok(NULL, "\r\n")); i++) { +- strlcat(obuf, p, olen); +- j = base64_pton(p, p, strlen(p)); +- p[j] = '\0'; +- strlcat(obuf, " [", olen); +- strlcat(obuf, p, olen); +- strlcat(obuf, "]\n", olen); ++ if (mode == NONE) { ++ user = NULL; ++ password = NULL; ++ if (strncasecmp(p, "AUTH PLAIN", 10) == 0) { ++ mode = AUTHPLAIN; ++ continue; ++ } ++ if (strncasecmp(p, "AUTH LOGIN", 10) == 0) { ++ mode = AUTHLOGIN; ++ continue; ++ } ++ if (strncasecmp(p, "USER ", 5) == 0) { ++ mode = USERPASS; ++ /* the traditional login cuts right to the case, ++ * so no continue here ++ */ + } + } +- /* Save regular POP2, POP3 auth info. */ +- else if (strncasecmp(p, "USER ", 5) == 0 || +- strncasecmp(p, "PASS ", 5) == 0 || +- strncasecmp(p, "HELO ", 5) == 0) { +- strlcat(obuf, p, olen); +- strlcat(obuf, "\n", olen); ++ printf("(%d) %s\n", mode, p); ++ if (mode == USERPASS) { ++ if (strncasecmp(p, "USER ", 5) == 0) { ++ user = &p[5]; ++ } else if (strncasecmp(p, "PASS ", 5) == 0) { ++ password = &p[5]; ++ } ++ } ++ ++ if (mode == AUTHPLAIN) { ++ j = base64_pton(p, p, strlen(p)); ++ p[j] = '\0'; ++ n = 0; ++ s = p; ++ /* p consists of three parts, divided by \0 */ ++ while (s <= &p[j] && n<=3) { ++ if (n == 0) { ++ /* we do not process this portion yet */ ++ } else if (n == 1) { ++ user = s; ++ } else if (n == 2) { ++ password = s; ++ } ++ n++; ++ while (*s) s++; ++ s++; ++ } ++ } ++ ++ if (mode == AUTHLOGIN) { ++ j = base64_pton(p, p, strlen(p)); ++ p[j] = '\0'; ++ if (!user) { ++ user = p; ++ } else { ++ password = p; ++ /* got everything we need :-) */ ++ } ++ } ++ ++ if (user && password) { ++ strlcat(obuf, "\nusername [", olen); ++ strlcat(obuf, user, olen); ++ strlcat(obuf, "] password [", olen); ++ strlcat(obuf, password, olen); ++ strlcat(obuf, "]\n", olen); ++ ++ mode = NONE; + } + } + return (strlen(obuf)); diff --git a/dsniff-2.4-pntohl_shift.patch b/dsniff-2.4-pntohl_shift.patch new file mode 100644 index 0000000..d4c7086 --- /dev/null +++ b/dsniff-2.4-pntohl_shift.patch @@ -0,0 +1,15 @@ +Patch by Matthew Boyle for dsniff >= 2.4b1 which corrects +the incorrect bit-shift in pntohl(), the left-shift should be 8 bits, not 18. For +further information please have a look to Red Hat Bugzilla ID #714958 and #850496. + +--- dsniff-2.4/decode.h 2001-03-15 09:33:06.000000000 +0100 ++++ dsniff-2.4/decode.h.pntohl_shift 2013-12-20 22:16:52.000000000 +0100 +@@ -35,7 +35,7 @@ + (u_short)*((u_char *)p+0)<<8)) + + #define pntohl(p) ((u_int32_t)*((u_char *)p+3)<<0| \ +- (u_int32_t)*((u_char *)p+2)<<18| \ ++ (u_int32_t)*((u_char *)p+2)<<8| \ + (u_int32_t)*((u_char *)p+1)<<16| \ + (u_int32_t)*((u_char *)p+0)<<24) + diff --git a/dsniff-2.4-rpc_segfault.patch b/dsniff-2.4-rpc_segfault.patch new file mode 100644 index 0000000..6db6144 --- /dev/null +++ b/dsniff-2.4-rpc_segfault.patch @@ -0,0 +1,17 @@ +Patch based on suggestion by Matthew Boyle for dsniff >= +2.4b1 which avoids xdrs being used without being initialised first. Without this +patch dsniff segfaults when decoding RPC packets on x86_64. For further information +please also have a look to Red Hat Bugzilla ID #715042 and #850494. + +--- dsniff-2.4/rpc.c 2001-03-15 09:33:04.000000000 +0100 ++++ dsniff-2.4/rpc.c.rpc_segfault 2013-12-20 22:49:34.000000000 +0100 +@@ -125,6 +125,9 @@ + return (0); + } + } ++ else ++ return (0); ++ + stat = xdr_getpos(&xdrs); + xdr_destroy(&xdrs); + diff --git a/dsniff-2.4-tds_decoder.patch b/dsniff-2.4-tds_decoder.patch index 6dbb981..3bd18c4 100644 --- a/dsniff-2.4-tds_decoder.patch +++ b/dsniff-2.4-tds_decoder.patch @@ -1,18 +1,19 @@ Patch by Hilko Bengen for dsniff >= 2.4b1, to avoid a possible DoS opportunity in the Tabular Data Stream protocol handler. For -further information, please have a look to Debian bug ID #609988. +further information, please have a look to the Debian bug ID #609988 and +#712648. ---- dsniff-2.4/decode_tds.c 2011-10-09 18:13:49.000000000 +0200 -+++ dsniff-2.4/decode_tds.c.tds_decoder 2011-10-09 18:14:43.000000000 +0200 -@@ -140,6 +140,11 @@ - - obuf[0] = '\0'; - -+ if (th->size != 8) { -+ /* wrong header length */ -+ return (strlen(obuf)); -+ } -+ - for (th = (struct tds_hdr *)buf; +--- dsniff-2.4/decode_tds.c 2013-12-19 23:36:26.000000000 +0100 ++++ dsniff-2.4/decode_tds.c.tds_decoder 2013-12-19 23:38:01.000000000 +0100 +@@ -144,6 +144,11 @@ len > sizeof(*th) && len >= ntohs(th->size); buf += ntohs(th->size), len -= ntohs(th->size)) { + ++ if (th->size != 8) { ++ /* wrong header length */ ++ break; ++ } ++ + if (th->type == 2) { + /* Version 4.x, 5.0 */ + if (len < sizeof(*th) + sizeof(*tl)) diff --git a/dsniff.spec b/dsniff.spec index da3c407..115d7f6 100644 --- a/dsniff.spec +++ b/dsniff.spec @@ -1,7 +1,7 @@ Summary: Tools for network auditing and penetration testing Name: dsniff Version: 2.4 -Release: 0.16.b1%{?dist} +Release: 0.17.b1%{?dist} License: BSD Group: Applications/Internet URL: http://www.monkey.org/~dugsong/%{name}/ @@ -29,6 +29,13 @@ Patch19: dsniff-2.4-link_layer_offset.patch Patch20: dsniff-2.4-tds_decoder.patch Patch21: dsniff-2.4-msgsnarf_segfault.patch Patch22: dsniff-2.4-urlsnarf_timestamp.patch +Patch23: dsniff-2.4-arpspoof_reverse.patch +Patch24: dsniff-2.4-arpspoof_multiple.patch +Patch25: dsniff-2.4-arpspoof_hwaddr.patch +Patch26: dsniff-2.4-modernize_pop.patch +Patch27: dsniff-2.4-libnet_name2addr4.patch +Patch28: dsniff-2.4-pntohl_shift.patch +Patch29: dsniff-2.4-rpc_segfault.patch BuildRequires: libnet-devel, openssl-devel, libnids-devel, glib2-devel, %{_includedir}/pcap.h %if 0%{?rhel}%{?fedora} > 6 BuildRequires: libdb-devel @@ -78,6 +85,13 @@ by exploiting weak bindings in ad-hoc PKI. %patch20 -p1 -b .tds_decoder %patch21 -p1 -b .msgsnarf_segfault %patch22 -p1 -b .urlsnarf_timestamp +%patch23 -p1 -b .arpspoof_reverse +%patch24 -p1 -b .arpspoof_multiple +%patch25 -p1 -b .arpspoof_hwaddr +%patch26 -p1 -b .modernize_pop +%patch27 -p1 -b .libnet_name2addr4 +%patch28 -p1 -b .pntohl_shift +%patch29 -p1 -b .rpc_segfault %build %configure @@ -125,6 +139,16 @@ rm -rf $RPM_BUILD_ROOT %{_mandir}/man8/webspy.8* %changelog +* Fri Dec 20 2013 Robert Scheck 2.4-0.17.b1 +- Corrected patch which touches tabular data stream protocol handler +- Added a patch to add both communication partners in arpspoof +- Added patch to allow multiple targets to be imitated simultaniously +- Added patch to allow the selection of source hw address in arpspoof +- Added a patch which fixes and modernizes the POP decoder +- Fixed segmentation faults related to libnet_name2addr4() (#1009879) +- Added a patch to fix bit-shift in pntohl() macro (#714958, #850496) +- Avoid xdrs being used without being initialised (#715042, #850494) + * Sat Aug 03 2013 Fedora Release Engineering - 2.4-0.16.b1 - Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild