Broadcast ip tcp connection in bsd systems Published: 19. 03. 02

Дата канвертавання24.04.2016
Памер37.05 Kb.
Broadcast IP TCP connection in BSD systems

Published: 19.03.02


Type: remote

Level: 5

Description: TCP SYN packets to broadcast address are accepted.

Affected products:FREEBSD:FreeBSD 5.0

Original text: Crist J. Clark, TCP Connections to a Broadcast Address on BSD-Based




Crist J. Clark <>


19 марта 2002 г.


TCP Connections to a Broadcast Address on BSD-Based Systems

BSD-based TCP/IP code has a bug with respect to creating TCP

connections to a broadcast address. This bug can potentially be a

security vulnerability when firewall administrators assume that the

TCP implementation works correctly and do not block broadcast

addresses. If good security practices have been followed on a

firewall host or gateway, the potential for exploitation is probably

FreeBSD and NetBSD both have the bug. OpenBSD appears to have it from

examination of the code, but I have been unable to test it.

The Standard:

TCP connections are only valid when the destination address is a

unicast address. That is, the destination must not be a multicast or

broadcast address. One place this is clearly specified in the

Standards is RFC 1122, Remote Address Validation
A TCP implementation MUST silently discard an incoming SYN

segment that is addressed to a broadcast or multicast


The Bug:
Uncorrected BSD-based TCP implementations do not actually check if the

destination IP address is a broadcast address. Rather, the packet's

link layer address is checked. Here is the old code from FreeBSD's

* RFC1122, p. 104: discard bcast/mcast SYN

* in_broadcast() should never return true on a received

* packet with M_BCAST not set.


* Packets with a multicast source address should also

* be discarded.


if (m->m_flags & (M_BCAST|M_MCAST))

goto drop;

#ifdef INET6

if (isipv6) {

if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst) ||


goto drop;

} else


if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) ||

IN_MULTICAST(ntohl(ip->ip_src.s_addr)) ||

ip->ip_src.s_addr == htonl(INADDR_BROADCAST))

goto drop;

The comment in the code reveals the reason for the mistake. The

authors assume that no one would accidentally or maliciously break the

rules. One can easily send packets with a unicast link-layer address,

but containing an IP broadcast address. No check is made in the above

code for such a situation.


There are many ways to take advantage of this bug. Here is one easy

way that will not interfere with normal operations of the test

1) On the victim machine add an alias for an unused network,
# ifconfig if0 inet alias
2) On the attack machine, which must be local to the victim on

the interface configured in step (1), add a route(8),

# route add
3) Now from the attacker, try to establish a TCP connection to

the victim's broadcast address on any port that might be

listening on the victim,
# ssh
The connection should succeed. Another slightly scarier attack, since

it doesn't require any changes to the victim host, is to just change

the attacker's idea of the netmask, making the network "bigger," so

that the broadcast address of the network now looks like a unicast to

the attacker. The attacker needs to manually add an entry in the ARP

cache. But remember this might break some things on the attacker while

the network is misconfigured.

The Vulnerability:

This creates a potential security vulnerability. The firewall

administrator may assume that it is not possible to establish TCP

connections to a broadcast address and therefore may not protect it


This vulnerability is mitigated by a number of factors:
- If the firewall follows a more secure

explicit-pass-default-deny policy, this probably will not be a

- An attacking or misconfigured host must be local to the victim.
- The attacking host can only connect to broadcast addresses on the

local interface (on FreeBSD, others not extensively tested if at

One issue may exacerbates the problem for ipfw(8) users on

FreeBSD. The 'me' destination in an ipfw(8) rule does NOT match the

interface's broadcast address. So,
deny tcp from any to me via if0
Would not block a TCP connection to the broadcast address on if0.

Using rules like the above on a firewall machine meant to allow

forwarded traffic through the external interface, but not allow direct

connections to the firewall is probably not uncommon, but it creates a

vulnerable configuration.

The Fix:
Adding in_broadcast() checks in tcp_input.c trivially fix the

problem. If you cannot patch your kernel, make sure your firewall

rules block TCP on broadcast addresses. If you are not firewalling,

there is little additional security exposure due to this bug (why

bother getting fancy and connecting to the broadcast address of the

interface when you can connect to the regular, bound IP?). But it is

still a bug.

I notified security-officer@{free,open,net} on Feburary

17th. From examining OpenBSD source code, it appears to have the

flaw. I have confirmed that NetBSD is vulnerable. I have been unable

to actually test the vulnerability on an operational OpenBSD system. I

have not heard anything from either NetBSD or OpenBSD, and no changes

related to this bug appear to have been committed to their code. Patches

for NetBSD and OpenBSD are attached below.
I committed changes to FreeBSD 5-CURRENT on Feburary 25th (CVS

revision 1.148) and to 4-STABLE on February 28th (revision After discussion with the FreeBSD security-officer@ team,

these changes will not be incorporated into the RELENG_4_{3,4,5}

security-fix branches nor will an advisory be released.

Greetz^W Acknowledgements:

Thanks to Igor M Podlesny
for bringing this to our

attention in FreeBSD PR misc/35022,
Thanks to Ruslan Ermilov for diggigng out the origins

of the bug and pointing out that the RST-response should be blocked as

well as dropping incoming SYNs.
Thanks to the Security Officer Team at FreeBSD for their quick

response (especially

Thanks to the rest of the FreeBSD developers on freebsd-net@.

Patch for NetBSD (tested):

Index: src/sys/netinet/tcp_input.c


RCS file: /export/netbsd/ncvs/syssrc/sys/netinet/tcp_input.c,v

retrieving revision

diff -u -r1.108.4.10 tcp_input.c

--- src/sys/netinet/tcp_input.c 24 Jan 2002 22:44:21 -0000

+++ src/sys/netinet/tcp_input.c 16 Mar 2002 23:14:14 -0000

@@ -677,7 +677,8 @@

* Make sure destination address is not multicast.

* Source address checked in ip_input().


- if (IN_MULTICAST(ip->ip_dst.s_addr)) {

+ if (IN_MULTICAST(ip->ip_dst.s_addr) ||

+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {

/* XXX stat */

goto drop;


@@ -2183,6 +2184,11 @@


if (tiflags & TH_RST)

goto drop;


+ if (IN_MULTICAST(ip->ip_dst.s_addr) ||

+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))

+ goto drop;




* need to recover version # field, which was overwritten on

Patch for OpenBSD (untested, problem not verified):

Index: src/sys/netinet/tcp_input.c


RCS file: /export/openbsd/ncvs/src/sys/netinet/tcp_input.c,v

retrieving revision 1.109

diff -u -r1.109 tcp_input.c

--- src/sys/netinet/tcp_input.c 15 Mar 2002 18:19:52 -0000 1.109

+++ src/sys/netinet/tcp_input.c 17 Mar 2002 01:08:35 -0000

@@ -1080,8 +1080,6 @@


* RFC1122, p. 104: discard bcast/mcast SYN

- * in_broadcast() should never return true on a received

- * packet with M_BCAST not set.


if (m->m_flags & (M_BCAST|M_MCAST))

goto drop;

@@ -1094,7 +1092,8 @@


#endif /* INET6 */

case AF_INET:

- if (IN_MULTICAST(ip->ip_dst.s_addr))

+ if (IN_MULTICAST(ip->ip_dst.s_addr) ||

+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) {

goto drop;



@@ -2139,7 +2138,8 @@


#endif /* INET6 */

case AF_INET:

- if (IN_MULTICAST(ip->ip_dst.s_addr))

+ if (IN_MULTICAST(ip->ip_dst.s_addr) ||

+ in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif))

goto drop;


if (tiflags & TH_ACK) {


Crist J. Clark |

| |

База данных защищена авторским правом © 2016
звярнуцца да адміністрацыі

    Галоўная старонка