The bug affects Shorewall 2.2.x and 2.4.x but the only affected Debian package is shorewall_2.2.3-1 which is currently in Sarge.
The problem with this bug is that clients which mac addresses are known can bypass the firewall rules and do whatever they want: if MACLIST_DISPOSITION is set to ACCEPT or MACLIST_TTL is not set to ZERO then any client which mac address is listed in /etc/shorewall/maclist is allowed to perform any kind of traffic on the network as the firewall doesn't filter its requests. In my opinion this is a vulnerability. MACLIST_DISPOSITION is set to ACCEPT to indicate that a client, which mac address is not know, is allowed to use the network and that its packets can be treated as the ones coming from any other hosts of the same network (or firewall zone). According the documentation: MACLIST_DISPOSITION determines the disposition of connection requests that fail MAC verification. MACLIST_TTL is used to set the lifetime of mac addresses cache to reduce the overhead of addresses lookup in /etc/shorewall/maclist (using ipt_recent netfilter module). I tested the bug on my home system: the desktop pc acts as firewall and the laptop was connected to it via a wireless link. The wlan interface of the firewall used the mac-filtering (i.e. maclist option is set for that interface in /etc/shorewall/interfaces) and MACLIST_DISPOSITION was set to REJECT and MACLIST_TTL to ZERO. The client traffic was perfectly allowed or rejected according the rules of the firewall. When I set to 10 MACLIST_TTL the laptop became allowed to pass silently through the firewall: traffic previously allowed was still allowed and traffic previously denied became allowed too. The same happened when I set MACLIST_DISPOSITION to ACCEPT and with other possible combinations of these options. I attached to this email a copy of the patch that fixes the security problem. It is a backport of the upstream author patch for version 2.2.5. The BTS already contains a link to an updated version of the package. -- lorenzo
diff -urNad shorewall-2.2.3/firewall /tmp/dpep.v6MqTc/shorewall-2.2.3/firewall --- shorewall-2.2.3/firewall 2005-04-10 23:58:12.000000000 +0200 +++ /tmp/dpep.v6MqTc/shorewall-2.2.3/firewall 2005-07-18 21:04:43.000000000 +0200 @@ -464,11 +464,6 @@ echo $(chain_base $1)_mac } -macrecent_target() # $1 - interface -{ - [ -n "$MACLIST_TTL" ] && echo $(chain_base $1)_rec || echo RETURN -} - # # Functions for creating dynamic zone rules # @@ -494,6 +489,11 @@ echo ${c}_dyni ${c}_dynf ${c}_dyno } +macrecent_target() # $1 - interface +{ + [ -n "$MACLIST_TTL" ] && echo $(chain_base $1)_rec || echo RETURN +} + # # DNAT Chain from a zone # @@ -2035,13 +2035,14 @@ for interface in $maclist_interfaces; do chain=$(mac_chain $interface) createchain $chain no - + if [ -n "$MACLIST_TTL" ]; then chain1=$(macrecent_target $interface) createchain $chain1 no - run_iptables -A $chain -m recent --rcheck --seconds $MACLIST_TTL --name $chain -j $chain1 - run_iptables -A $chain1 -m recent --update --name $chain -j ACCEPT - run_iptables -A $chain1 -m recent --set --name $chain -j ACCEPT + run_iptables -A $chain -m recent --rcheck --seconds $MACLIST_TTL --name $chain -j RETURN + run_iptables -A $chain -j $chain1 + run_iptables -A $chain -m recent --update --name $chain -j RETURN + run_iptables -A $chain -m recent --set --name $chain fi done # @@ -2061,8 +2062,7 @@ esac fi - chain=$(mac_chain $interface) - chain1=$(macrecent_target $interface) + [ -n "$MACLIST_TTL" ] && chain=$(macrecent_target $interface) || chain=$(mac_chain $interface) if ! havechain $chain ; then fatal_error "No hosts on $interface have the maclist option specified" @@ -2071,10 +2071,10 @@ macpart=$(mac_match $mac) if [ -z "$addresses" ]; then - run_iptables -A $chain $macpart $physdev_part -j $chain1 + run_iptables -A $chain $macpart $physdev_part -j RETURN else for address in $(separate_list $addresses) ; do - run_iptables2 -A $chain $macpart -s $address $physdev_part -j $chain1 + run_iptables2 -A $chain $macpart -s $address $physdev_part -j RETURN done fi done < $TMP_DIR/maclist @@ -2083,8 +2083,7 @@ # chains # for interface in $maclist_interfaces; do - chain=$(mac_chain $interface) - chain1=$(macrecent_target $interface) + [ -n "$MACLIST_TTL" ] && chain=$(macrecent_target $interface) || chain=$(mac_chain $interface) blob=$(ip link show $interface 2> /dev/null) @@ -2092,12 +2091,13 @@ fatal_error "Interface $interface must be up before Shorewall can start" ip -f inet addr show $interface 2> /dev/null | grep 'inet.*brd' | sed 's/inet //; s/brd //; s/scope.*//;' | while read address broadcast; do + address=${address%/*} if [ -n "$broadcast" ]; then - run_iptables -A $chain -s ${address%/*} -d $broadcast -j $chain1 + run_iptables -A $chain -s $address -d $broadcast -j RETURN fi - run_iptables -A $chain -s $address -d 255.255.255.255 -j $chain1 - run_iptables -A $chain -s $address -d 224.0.0.0/4 -j $chain1 + run_iptables -A $chain -s $address -d 255.255.255.255 -j RETURN + run_iptables -A $chain -s $address -d 224.0.0.0/4 -j RETURN done if [ -n "$MACLIST_LOG_LEVEL" ]; then @@ -7418,8 +7418,11 @@ case $MACLIST_DISPOSITION in REJECT) ;; - ACCEPT|DROP) - maclist_target=$MACLIST_DISPOSITION + DROP) + maclist_target=DROP + ;; + ACCEPT) + maclist_target=RETURN ;; *) startup_error "Invalid value ($MACLIST_DISPOSITION) for MACLIST_DISPOSITION" @@ -7486,7 +7489,7 @@ [ "$MACLIST_TTL" = "0" ] && MACLIST_TTL= if [ -n "$MACLIST_TTL" -a -z "$RECENT_MATCH" ]; then - startup_error "MACLIST_TTL requires the Recent Match capability which is not present in your Kernel and/or iptables" + startup_error "MACLIST_TTL requires the Recent Match capability which is not present in your Kernel and/or iptables" fi # # Strip the files that we use often