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

Reply via email to