abril 28, 2015

Control de Acceso

El Network Access Control (NAC) o control de acceso a una red, es siempre tema de discusión. Cada organización o sysadmin tiene sus preferencias en cuanto a las técnicas, herramientas, equipos y sistema operativo ideal para lograr este cometido.
Existen infinidades de métodos para controlar el/los puntos de entrada a una red local y rechazar a los indeseados. Incluso hay aplicaciones y hardware dedicado, diseñados exclusivamente para lidiar con este problema.
El NAC implica tantas capas de seguridad (routers, switches, firewall, etc) y son tan extensos y variados los métodos existentes para cada uno de los sistemas operativos, que abarcarlo todo en un solo post sería imposible (tal vez en un libro, que solo Dios sabe cuántas páginas y tomos tendría)
Es por esta razón que dedicaremos este post a exponer algunas métodos para controlar el acceso a una red local (de hogares y pequeñas/medianas organizaciones), con técnicas sencillas, utilizando herramientas gratuitas, disponibles en cualquier distribución de Linux.
Manos a la obra
Asumiendo que ya tenemos a la mano una VM o equipo físico, el cual utilizaremos como administrador, y que lo pondremos entre nuestra red local y el punto de entrada/salida a internet, que este tiene alguna distribución de linux (preferentemente basada en Debian), que nuestro rango de red local ipv4 es clase C (192.168.1.0/24), y el equipo o VM tiene como mínimo dos interfaces de red (una para el enlace de internet -eth0- y la segunda para la red local -eth1-), el primer paso lógico de cualquier sysadmin es determinar los equipos que tiene en su red y crear una o varias listas de control de acceso (ACL) con los datos más relevantes de los terminales (ip, mac, host, etc). De esta manera, si un intruso accede, podría ser detectado con mayor facilidad y eventualmente ser rechazado.
Existen varias formas de obtener estos datos, sin necesidad de ir equipo por equipo y tomarlos manualmente. Podemos lanzar cualquier app tipo escaner de red para capturar esta información, como por ejemplo la archifamosa nmap
sudo apt-get -y install nmap
Con esta herramienta podemos lanzar cualquiera de los siguientes comandos en el terminal y volcar el resultado a un reporte...
sudo nmap -sU -sT -O 192.168.1.1-254 > reporte_nmap
sudo nmap -sn 192.168.1.0/24 > reporte_nmap
sudo nmap -sn 192.168.1.0/24 | grep "report for" | awk '{print $5}' > reporte_nmap
sudo nmap -sP 192.168.1.0/24 > reporte_nmap
sudo nmap -Pn 192.168.1.0/24 > reporte_nmap
... y muchos otros comandos; sin embargo, si queremos obtener información mucho más detallada de nuestra red local, como por ejemplo validar su topología (verificar si el mapeo es correcto), podemos echar mano de la versión gráfica de nmap: zenmap
Lo ejecutamos como root y colocamos, por ejemplo, lo siguiente:
nmap -sP -PE -PA21,23,80,3389 192.168.1.0/24
sudo apt-get -y install zenmap
Otra manera de conseguir la información deseada es a través del servidor DHCP
sudo apt-get -y install isc-dhcp-server
Una vez instalado, permitimos que le "arriende" las ips autorizadas por su rango (previamente validado en el dhcpd.conf) a los terminales de nuestra red local y luego extraer la información. Existen dos archivos de donde podemos extraerla.
/var/lib/dhcp/dhcpd.leases # Para Ubuntu 10x la carpeta cambia a dhcp3
# y
/var/log/messages
O también podemos obtenerla del "dhcpd.conf", si ponemos la información manualmente
/etc/dhcp/dhcpd.conf # Para Ubuntu 10x la carpeta cambia a dhcp3
Y ejecutamos lo siguiente:
# las IPs
cat /var/lib/dhcp/dhcpd.leases|gawk '/^lease/{print $2}'
# los HOSTs
cat /var/lib/dhcp/dhcpd.leases|gawk '/^  client/{print $2}'
# las MACs
cat /var/lib/dhcp/dhcpd.leases|gawk '/^  hardware/{print $3}'
# o todo
cat /var/lib/dhcp/dhcpd.leases|tr -d "\n"|tr "}" "\n"|tr -d "\""|tr -d ";"
Awk también nos puede ser útil. Ejecutamos en el terminal (o en un script):
awk ' /lease/ { ip = $2 } ; /hardware/ { mac = $3 } ; /client-hostname/ { hname = $2 }; { print " host " hname " { hardware ethernet " mac " fixed-address " ip "; }" } ' /var/lib/dhcp/dhcpd.leases
Validación NAC
Ya tenemos la información, pero el DHCP está constantemente generando nuevos arrendamientos a aquellos terminales que ingresan al punto de entrada, sin que estos necesariamente sean de nuestra red local y no podemos confiarnos de la seguridad de los puntos de acceso WiFi, ya que son el eslabón más débil de la cadena. En este orden de ideas, hay que establecer un filtrado para determinar cuáles terminales pueden o no a nuestra red y de paso automatizar este proceso.
Filtrar el DHCP (udp 68) usando una regla en un firewall (como Iptables) probablemente no causaría ningún efecto ya que trabajan en diferentes capas. Tampoco creemos que es una solución "saludable" llenar con macs "negras" las tablas de los puntos AP Wifi, router o cualquier otro dispositivo de hardware. No obstante si quiere bloquear las macs o puntos WiFi falsos (rogue) a nivel de hardware, puede consultar el post de hackplayers que aborda el tema.
Pero si no tiene el hardware apropiado para hacer estos filtrados, considere algo económico y fácil de manejar, como lo es la extracción y validación de datos con el servidor isc-dhcp-server.
Hay dos tipos de soluciones en dependencia del nivel de seguridad que se requiera. La primera consiste en validar las direcciones MAC, y la segunda en validar con la IP+MAC "amarrada".
En la primera, creamos un script (al que llamaremos "leases.sh" y lo pondremos en /etc/init.d con sus permisos chmod +x y que se ejecutará con root) que capture la información y la mande a una acl de salida que llamaremos "macslocal".
#!/bin/bash
# by maravento.com and novatoz.com

# dhcpd source
dhcpd=/var/lib/dhcp/dhcpd.leases # for Ubuntu 12x or later
#dhcpd=/var/lib/dhcp3/dhcpd.leases # for Ubuntu 10x
#dhcpd=/var/log/messages
#dhcpd=/etc/dhcp/dhcpd.conf # for Ubuntu 12x or later
#dhcpd=/etc/dhcp3/dhcpd.conf # for Ubuntu 10x

# acls
black=/home/sysadmin/acl/macsblack
local=/home/sysadmin/acl/macslocal
leases=/home/sysadmin/acl/leases

cat $dhcpd | while read line; do
      if $(echo $line | grep -q 'hardware ethernet'); then
       macs=$(echo $line | sed -e 's,.*hardware ethernet *,,' -e 's,;.*,,')
 echo $macs >> $leases | sort -u $leases -o $leases
        fi
    done

toRemove=$(cat $black | tr "\n" "|" | sed 's:|:\\|:g')
grep -v -e "^\($toRemove\)$" $leases >> $local | sort -u > $local
Y lo ponemos en el cron para que se ejecute en el menor tiempo posible y esté alimentando nuestra acl "macslocal" y así nos evitaremos estar copiando y pegando direcciones macs.
0-59/1 * * * * root /etc/init.d/leases.sh
En el ejemplo anterior, lo único que debemos hacer manualmente es revisar la ACL resultante "macslocal" y extraer las direcciones MAC que no sean de nuestra red local y ponerlas en la acl "macsblack" y la próxima vez que corra el script, verificará la lista negra y excluirá del proceso de validación las direcciones macs que estén en "macsblack".
Sin embargo, para mayor seguridad, se recomienda hacer el proceso a la inversa, o sea, todas las direcciones MACs que capture el script leases.sh van a parar directo a la ACL macsblack, y por defecto no ingresan a la red, hasta tanto el administrador IT no las saque de esa "lista negra" y las ingrese manualmente a la acl macslocal
#!/bin/bash
# by maravento.com and novatoz.com

# dhcpd source
dhcpd=/var/lib/dhcp/dhcpd.leases # for Ubuntu 12x or later
#dhcpd=/var/lib/dhcp3/dhcpd.leases # for Ubuntu 10x
#dhcpd=/var/log/messages
#dhcpd=/etc/dhcp/dhcpd.conf # for Ubuntu 12x or later
#dhcpd=/etc/dhcp3/dhcpd.conf # for Ubuntu 10x

# acls
black=/home/sysadmin/acl/macsblack
local=/home/sysadmin/acl/macslocal
leases=/home/sysadmin/acl/leases

cat $dhcpd | while read line; do
      if $(echo $line | grep -q 'hardware ethernet'); then
       macs=$(echo $line | sed -e 's,.*hardware ethernet *,,' -e 's,;.*,,')
 echo $macs >> $leases | sort -u $leases -o $leases
        fi
    done

toRemove=$(cat $local | tr "\n" "|" | sed 's:|:\\|:g')
grep -v -e "^\($toRemove\)$" $leases >> $black | sort -u > $black
Finalmente, el iptables se encargará de validar la acl "macslocal" y cerrarle el paso al resto de las conexiones, por lo que se recomienda poner ambos scripts en el cron para automatizar el proceso
# nomenclatura
internet=eth0
lan=eth1
local=192.168.10.0
iptables=/sbin/iptables
route=/home/sysadmin/acl
alias cat="sed '/#.*/d'"

# SOLO SE ACEPTAN PETICIONES DE LA RED LOCAL (macslocal)
for mac in `cat $route/macslocal | tr '[A-Z]' '[a-z]' | sort -u`; do
$iptables -t mangle -A PREROUTING -i $lan -m mac --mac-source $mac -j ACCEPT
done
$iptables -t mangle -A PREROUTING -i $lan -j DROP
La segunda solución es un poco más compleja, ya que vamos a crear un amarre IP+MAC. Hoy traemos dos maneras de hacerlo; La primera ya fue publicada anteriormente en la serie Firewall:
#!/bin/bash
# by maravento.com and novatoz.com
lan=eth1
local=192.168.1.0
leases=/var/lib/dhcp/dhcpd.leases
path_ips=/home/sysadmin/acl/ips_dhcp 
path_macs=/home/sysadmin/acl/macs_dhcp
alias sed="sed '/#.*/d'"
iptables=/sbin/iptables

# mac2ip
mac2ip=$(sed -n '/^\s\+hardware\|^\s\+fixed/ s:hardware ethernet \|fixed-address ::p' $dhcp_conf | sed 's/;//')

# create acl mac-ip
create_acl() {
    ips="# ips"
    macs="# macs"
    while [ "$1" ]; do
        mac="$1"
        shift
        ip="$1"
        shift
        $iptables -t mangle -A PREROUTING -i $lan -m mac --mac-source $mac -s $ip -j ACCEPT
        ips="$ips\n$ip"
        macs="$macs\n$mac"
    done
    echo $ips > $path_ips
    echo $macs > $path_macs
}
create_acl $mac2ip
En el script anterior, creamos una regla que busca toda la información necesaria de los terminales en el archivo de arrendamientos dhcpd.leases (también pueden buscarla en /var/log/messages o en el dhcpd.conf). Una vez obtenida, es volcada hacia dos ACLs llamadas ips_dhcp y macs_dhcp (creadas dentro de la carpeta "acl" en la cuenta de usuario, que elegimos como "sysadmin" -reemplacela por su ruta preferida-) y luego las une para validar el amarre IP+MAC. y finalmente cerraremos la entrada con mangle
$iptables -t mangle -A PREROUTING -i $lan -j DROP
La segunda variante es la planteada por Pejman Moghadam. Hace lo mismo que la anterior con la diferencia que utiliza el módulo (-m) comment para agregar el nombre del HOST.
# MAC address filtering based on dhcpd
    #!/bin/bash
    
    # Configuration
    INTIF="eth1"
    DHCPDCONF="/etc/dhcp/dhcpd.conf"
    TMP="/tmp/firewall.sh"
    FW="/etc/rc.d/rc.firewall"
    
    # Making new firewall
    echo "#!/bin/bash" > "${TMP}"
    echo "echo 'Starting Firewall : ${FW}'" >> "${TMP}"
    echo "# Flush Previous rules" >> "${TMP}"
    echo "iptables -F FORWARD" >> "${TMP}" 
    cat "${DHCPDCONF}" | while read line; do
      if $(echo "$line" | grep -q 'host') && $(echo "$line" | grep -q '{'); then
          HOST=$(echo $line | sed -e 's,.*host *,,' -e 's, *{.*,,')
      fi
      if $(echo "$line" | grep -q 'hardware ethernet'); then
       MAC=$(echo $line | sed -e 's,.*hardware ethernet *,,' -e 's,;.*,,')
      fi
      if $(echo "$line" | grep -q 'fixed-address'); then
       IP=$(echo $line | sed -e 's,.*fixed-address *,,' -e 's,;.*,,')
      fi
      if [ "$HOST" != "" ] && [ "$MAC" != "" ] && [ "$IP" != "" ]; then
        echo "# $HOST $MAC $IP" >> "${TMP}"
        echo "iptables -A FORWARD -i $INTIF -s $IP -m mac --mac-source $MAC -j ACCEPT -m comment --comment '$HOST'"  >> "${TMP}"
        HOST=""
        MAC=""
        IP=""
      fi
    done
    echo "# Change default policy" >> "${TMP}"
    echo "iptables -A FORWARD -i $INTIF -j LOG --log-prefix 'Firewall: ' -m comment --comment 'Log everything else'" >> "${TMP}"
    echo "iptables -A FORWARD -i $INTIF -j DROP -m comment --comment 'Drop everything else'" >> "${TMP}" 
    
    # Exit if previous and current firewalls are the same
    if [ -e "${FW}" ] && diff "${FW}" "${TMP}" &> /dev/null; then
      exit 
    fi
    
    # Run new firewall if thay are different
    cp "${TMP}" "${FW}"
    chmod +x "${FW}"
    "${FW}"
Y el dhcpd.conf tendría que ser similar al siguiente:
### dhcpd.conf example
    ddns-update-style none;
    subnet 192.168.0.0 netmask 255.255.255.0 {
      option routers                192.168.0.1;
      option subnet-mask            255.255.255.0;
      option domain-name-servers    8.8.8.8, 8.8.4.4;
      default-lease-time 60;
      max-lease-time 600;
    
      host sysop {
        hardware ethernet 6c:f0:49:45:e9:ba; 
        fixed-address 192.168.0.11;
      }
    
      host station01 {
        hardware ethernet 00:11:2f:4b:63:1b;
        fixed-address 192.168.0.12;
      }
    
      host station02 {
        hardware ethernet 00:14:85:ee:92:3a;
        fixed-address 192.168.0.13;
      }
    
      host station03 {
        hardware ethernet 1c:af:f7:10:56:8b; 
        fixed-address 192.168.0.14;
      }
    }
Sin embargo este script puede generar error de tipo "Bad Mac Address", ya que Iptables maneja un formato diferente a DHCP. Una explicación más detallada sobre el problema y la solución puede encontrarla AQUI y AQUI
Si quiere automatizar aún más el proceso de bloqueo y evitar que el servidor DHCP le siga arrendando ips a "blacklist", puede consultar el siguiente post de serverfault
El Inventario
Nada de lo anterior nos garantiza una red libre de intrusos y sin accesos ilegales. No es suficiente con conocer el triplete HOST+IP+MAC de cada terminal de nuestra red local, ya que esta información es falseable. Así las cosas, una buena alternativa es "el inventario".
Sin llenarnos de tecnicismos, concretamente hay que hacer un inventario tanto de hardware como del software de cada equipo de nuestra red. Sistema operativo, suite ofimática y demás aplicaciones, antivirus, hardware, etc. Pero también de los puertos abiertos, incluso secuencia de apertura de puertos, promedio de tráfico (horas, días, etc), tiempos y fechas de acceso, en fin, todo un abanico de información, en dependencia de qué tanta seguridad necesitemos. El propósito es que si el intruso logra falsear el triplete, lo cual haría saltar las alarmas en los sistemas Windows con su típico mensaje "IP duplicada", lo delataría el inventario de su terminal.
Es difícil clonar con éxito un equipo tanto en hardware como software, y adicionalmente. el intruso deberá tener también los mismos puertos abiertos que regularmente tiene su víctima, sus aplicaciones, registros, etc, etc... Un ataque APT demasiado sofisticado.
Hay muchas aplicaciones que nos pueden ayudar a obtener estos datos. Por ejemplo, con nmap y xsltproc podemos generar un reporte completo de nuestra red local y exportarlo a html
sudo apt-get -install xsltproc
sudo nmap -sV -T4 -O -F --version-light 192.168.1.0/24 -oX reporte.xml
xsltproc reporte.xml -o reporte.html
También podemos echar mano de herramientas como Nagios, Cacti, Monitorix, Sarg, Zabbix, Nessus, Speccy, Belarc Advisor, OCS Inventory NG, GLPI, WireShark, OSSIM, Ntop-NG, etc, etc; y aumentar la protección, estableciendo un perímetro de defensa, WAF, derivar el tráfico por una vpn segura y otras protecciones; en fin, "el infierno es el límite".
Maravento, Actualizado en: 12:26
Escrito por: Maravento Studio
 
© 2017 Maravento. All Rights Reserved | Powered by Maravento
Design by Novatoz and Maravento | Bloggerized By LawnyDesignz
# https://github.com/google/code-prettify