Date: Tue, 30 Dec 2003 00:23:11 +0700 From: "Roman Y. Bogdanov" <brj@vzletka.net> To: freebsd-bugs@FreeBSD.org Subject: http://www.freebsd.org/cgi/query-pr.cgi?pr=60293 Message-ID: <52609734843.20031230002311@vzletka.net>
next in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] http://www.freebsd.org/cgi/query-pr.cgi?pr=60293 =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= From: Maxim Artemev <bert_raccoon@freemail.ru> To: brj@vzletka.net <brj@vzletka.net> Date: Monday, December 29, 2003, 11:40:25 PM Subject: kern/60293: FreeBSD arp poison patch Files: if_ether.c.patch --====----====----====----====----====----====----====----====----====----===-- Hello. Here the updated patch (v1.2) for arp poison. Feautures: * Mark as 'static' entry only via sysctl variable. Not default as it was in old version. * Timeout of verifying. P.S. Can be forward to FreeBSD bugs team. --- WBR, Max Artemev úáï íã îôô, éÔÅÌ. íÏÓË×Á. http://www.ntt.ru/ [http://freecap.ru/] [http://theraccoons.ru/] =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= -- Roman Y. Bogdanov [-- Attachment #2 --] --- if_ether.c.orig Mon Dec 8 14:01:47 2003 +++ if_ether.c Tue Dec 9 11:30:04 2003 @@ -40,6 +40,10 @@ * add "inuse/lock" bit (or ref. count) along with valid bit */ +/* + * ARP-posion Antidote code (c) 2003 by Bert <bert@furry.ru> + */ + #include "opt_inet.h" #include "opt_bdg.h" @@ -82,6 +86,11 @@ static int arpt_keep = (20*60); /* once resolved, good for 20 more minutes */ static int arpt_down = 20; /* once declared down, don't send for 20 sec */ +static int arp_secure = 1; +static int arpt_debug = 0; +static int arpt_static = 0; + + SYSCTL_INT(_net_link_ether_inet, OID_AUTO, prune_intvl, CTLFLAG_RW, &arpt_prune, 0, ""); SYSCTL_INT(_net_link_ether_inet, OID_AUTO, max_age, CTLFLAG_RW, @@ -96,6 +105,10 @@ struct rtentry *la_rt; struct mbuf *la_hold; /* last packet until resolved/timeout */ long la_asked; /* last time we QUERIED for this addr */ + long la_ack; /* Arp reply acknowledgement flag */ + u_char check_eth[ETHER_ADDR_LEN]; /* Original MAC address */ + u_char new_eth[ETHER_ADDR_LEN]; /* New MAC address */ + struct in_addr check_ip; #define la_timer la_rt->rt_rmx.rmx_expire /* deletion time in seconds */ }; @@ -115,6 +128,19 @@ SYSCTL_INT(_net_link_ether_inet, OID_AUTO, proxyall, CTLFLAG_RW, &arp_proxyall, 0, ""); +/* sysctl arp antidote variable. Default is "on" */ +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_antidote, CTLFLAG_RW, + &arp_secure, 0, "Enable antidote for ARP poison"); + +/* sysctl arp debug variable. Default is "off" */ +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_debug, CTLFLAG_RW, + &arpt_debug, 0, "Dump arp packets"); + +/* sysctl arp static variable. Default is "off" */ +SYSCTL_INT(_net_link_ether_inet, OID_AUTO, arp_static, CTLFLAG_RW, + &arpt_static, 0, "Make ARP entry static if poisoning detected"); + + static void arp_rtrequest __P((int, struct rtentry *, struct rt_addrinfo *)); static void arprequest __P((struct ifnet *, struct in_addr *, struct in_addr *, u_char *)); @@ -149,8 +175,14 @@ while ((ola = la) != 0) { register struct rtentry *rt = la->la_rt; la = la->la_le.le_next; - if (rt->rt_expire && rt->rt_expire <= time_second) - arptfree(ola); /* timer has expired, clear */ + if ((rt->rt_expire && rt->rt_expire <= time_second) || ola->la_ack == 1) + { + if (ola->la_ack && arpt_debug) { + log(LOG_INFO, "arp: Timeout of verifying for MAC address %*D.\n", + sizeof(ola->new_eth), (u_char *)&ola->new_eth, ":"); + } + arptfree(ola); /* timer has expired, clear */ + } } splx(s); } @@ -663,14 +695,77 @@ ifp->if_name, ifp->if_unit); goto reply; } + + /* Print announced packet if debug is enabled */ + if (sdl->sdl_alen && arpt_debug) { + log(LOG_INFO, "arp: Got MAC address %*D from %s via %s%d\n", + ifp->if_addrlen, (u_char *)ar_sha(ah), ":", + inet_ntoa(isaddr), + ifp->if_name, ifp->if_unit); + } + + + if (arp_secure && rt->rt_expire && + sdl->sdl_alen && la->la_ack) + { + int b_equals = (bcmp(ar_sha(ah), &la->check_eth, sdl->sdl_alen) == 0) && + (bcmp(ar_sha(ah), &la->new_eth, sdl->sdl_alen) == 0); + + /* Check possible reply with old MAC-address*/ + if (b_equals) { + /* Both addresses are equal. MAC address verified */ + if (arpt_debug) + log(LOG_INFO, "arp: MAC address %*D from %s verified.\n", + ifp->if_addrlen, (u_char *)ar_sha(ah), ":", + inet_ntoa(isaddr)); + la->la_ack = 0; + } else { + /* Reply was with another MAC */ + log(LOG_ERR, "arp: ARP poison detected!, attacker from %*D trying to infect %*D (%s) in my ARP table!\n", + sdl->sdl_alen, (u_char *)&la->new_eth, ":", + sdl->sdl_alen, (u_char *)&la->check_eth, ":", + inet_ntoa(la->check_ip)); + if (arpt_static) + rt->rt_expire = 0; + + /* Clear cached MAC */ + bzero(&la->check_eth, sizeof(la->check_eth)); + la->la_ack = 0; + m_free(m); + return; + } + } + if (sdl->sdl_alen && bcmp(ar_sha(ah), LLADDR(sdl), sdl->sdl_alen)) { - if (rt->rt_expire) - log(LOG_INFO, "arp: %s moved from %*D to %*D on %s%d\n", - inet_ntoa(isaddr), - ifp->if_addrlen, (u_char *)LLADDR(sdl), ":", - ifp->if_addrlen, (u_char *)ar_sha(ah), ":", - ifp->if_name, ifp->if_unit); + if (rt->rt_expire) { + if (arp_secure) { + if (la->la_ack == 0) { + if (arpt_debug) + log(LOG_INFO, "arp: Got new MAC address %*D from %s (%s%d). Now verifying.\n", + ifp->if_addrlen, (u_char *)ar_sha(ah), ":", + inet_ntoa(isaddr), + ifp->if_name, ifp->if_unit); + /* Check old MAC address for alive */ + arprequest(ifp, &myaddr, &isaddr, IF_LLADDR(ifp)); + (void)memcpy((u_char *)&la->check_eth, LLADDR(sdl), sdl->sdl_alen); + (void)memcpy((u_char *)&la->new_eth, (u_char *)ar_sha(ah), sdl->sdl_alen); + + la->check_ip.s_addr = isaddr.s_addr; + + la->la_ack++; + la->la_asked++; + m_free(m); + return; + } + } else { + log(LOG_INFO, "arp: %s moved from %*D to %*D on %s%d\n", + inet_ntoa(isaddr), + ifp->if_addrlen, (u_char *)LLADDR(sdl), ":", + ifp->if_addrlen, (u_char *)ar_sha(ah), ":", + ifp->if_name, ifp->if_unit); + } + } else { log(LOG_ERR, "arp: %*D attempts to modify permanent entry for %s on %s%d\n",
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?52609734843.20031230002311>
