A data diode is a network device that only allows data to travel in one direction, they are
used primarily in high security applications like nuclear plants, industrial automation, and
armies all over the world. There reason they aren't more widely used, the sacrifice for
their high security is that normal transport protocols don't work over data diodes, as
they require a bidirectional connection.
And here is where everything becomes muddy, because to overcome this limitation some data
diodes use a secondary channel from the isolated side to the untrusted side to send flow
control information back so TCP connection can pass through. This makes them potentially
vulnerable to a covert channel attack,
but there's almost no information on vulnerabilities, attacks, or test tools.
So I wrote leaky diode a test tool to check
if they are resistant to a couple of a very simple attacks.
The Attacks
The attacks described in this post require a compromised host on the isolated side, and have
a very low throughput (aroud 1 Bytes/min), so they can't realistically be used to leak more
than a few KB of data.
Regardless of the limitations there're still many fields where even such small leaks
would be catastrophic, and would love to be able to test their diodes so lets dive in.
Close Delay
Close delay uses the delay between the start of a connection and the time it's closed
by the server to encode the secret bits.
1 (CLIENT) Open a connection to the server.
2 (CLIENT) Send a request for one of the secret bits and a threshold delay,
then continue sending junk data to keep the connection alive.
3 (SERVER) After receiving a request, close the connection inmediately if the value
of the secret bit is 0, or wait threshold delay before closing the connection if the
value is 1.
4 (CLIENT) If the delay between sending the request to the server and the server
closing the connection is greater than threshold/2 then the bit value is
1, and 0 otherwise.
This attack works well in almost all circunstances, as it doesn't require much bandwith
and is not affected by network lattency or buffers in the data diodes. The drawback is
that uses so many connections tha can be easily detected.
Flow Modulation
Flow modulation uses the flow control mechanisms of TCP to transmit data using the
throughput of a connection as the carrier.
1 (CLIENT) Connect with the server and set the tx rates to signal low and high bits.
(i.e- 60KB/sec for low 300KB/sec for high bits)
2 (CLIENT) Send a request for one of the secret's bits, and start sending random
data at a rate greater than the max encoding rate.
3 (SERVER) On reception of a request start throttling the connection to the
to the speed that encodes the value of the requested bit/bits. (as provided in step 1)
4 (CLIENT) Wait until the data rate stabilizes/settles and then sample it to obtain the bit
value.
5 (CLIENT) Go to step 1 until all the secret bits have been read.
This attack is harder to detect than close delay as it uses a single connection and not
thousands to exfiltrate the data, the data sent can also be made to mimic another protocol
like http to make it even harder to detect. And with enough care a finely tunned tool could
use very close tx rates for high and low values, so it's indistinguishable from a legitimate
connection.
The drawback is that it's vulnerable to network congestion, QoS, and large TCP stack
buffers that can make it inconsistent.
Lower level attacks
If you have privileges to directly manipulate the stack, there are few more possible attacks
that may work depending on the diode:
Using the ACK delay since the reception of a packet.
Only sending ACK on even or odd sequence numbers, to encode low/high bits.
Manipulating the window size.
Some of these are harder to implement and easier to defend against by the diode, but are
great candidades to embed into the OS. Just to be clear I haven't tested any of them.
Test tool
If you have a diode you want to test, download leaky diode
On the isolated side launch the server:
$leaky_server public_ip port 'secret string to leak'
$leaky_client server_ip server_port --mode close --partial
Then wait for a few minutes until the first bytes start to arrive, or if you are impacient add
--verbose argument to show notifications on each bit sent/received.
En el artículo Ataquest TCP Comunes expliqué
algunos de los ataques más comunes, en este post explico como configurar
linux para protegerse de esos ataques, y alguno más.
Ataque SYN Flood
SYN Cookies
Linux implementa un metodo llamado
SYN Cookies
para la protección contra este ataque, la técnica se consiste en elegir el
numero de secuencia del paquete SYN+ACK de manera que el servidor no
necesite guardar el estado de la conexión, y pueda usas el numero de secuencia
de la respuesta ACK del cliente, para reconstruir la entrada en la tabla de
conexiones.
Desde la versión del kernel 2.6.33, donde el sistema se modificó para
soportar window scaling, esta opción está activada por defecto. Puedes
comprobarlo usando:
cat /proc/sys/net/ipv4/tcp_syncookies
sysctl -n net.ipv4.tcp_syncookies
Si no está activado, puedes editar el archivo de configuración
/etc/sysctl.conf y añadir:
net.ipv4.tcp_syncookies =1
Despues de salvar el archivo, puedes activarlo usando:
sudo sysctl -p
Un servidor con tcp_syncookies activado se comporta de forma normal, hasta que
la cola de conexiones pendientes está llena, a partir de ese momento comienza
a enviar SYN cookies hasta que la congestión se alivie.
Si el servidor esta soportando mucha carga, puede ocurrir que tcp_syncookies
se active y cierre conexiones legítimas. En esos casos es importante tener en
cuenta que aunque puede ser un alivio temporal, SYN Cookies está diseñado para
proteger el sistema de ataques SYN Flood, y que usarlo para solucionar
problemas de congestión reiterados es contraproducente.
Iptables
La segunda opción es usar iptables para limitar el número de paquetes SYN,
que son aceptados para cada dirección IP en un intervalo de tiempo. Para ello
usamos el patch recent de iptables.
iptables -A INPUT -p tcp -m state --state NEW -m recent --set --name sattack
iptables -A INPUT -p tcp -m state --state NEW -m recent --rcheck --name sattack --seconds 60 --hitcount 20 -j DROP
La primera regla añade la dirección de origen de los paquetes SYN a una
tabla llamada sattack, la segunda regla comprueba si en los últimos 60
segundos ha habido más de 20 paquetes SYN, desde la dirección de origen
del paquete, de ser así el paquete es descartado.
En caso de que se esté usando IP Spoofing junto a SYN Flood, la única opción
restante es intenta detectar alguna particularidad de la cabecera,
que permita diferenciar los paquetes del atacante del resto,
por ejemplo si MSS no tiene un valor correcto:
iptables -t mangle -I PREROUTING -p tcp -m tcp --dport 80 -m state --state NEW -m tcpmss ! --mss 536:65535 -j DROP
Estas reglas pueden interferir con proxies, y con clientes detrás de un NAT,
así que no es recomendable usarlas en un sistema que no esté bajo ataque.
TCP Scans
El sistema más sencillo y general para detectar/detener un scan, es usar
puertos cerrados como centinelas, de manera que si detectamos un paquete
que llega a alguno de esos puertos, podamos asumir que el paquete es parte
de un scan, y bloquear el acceso de la ip de origen temporalmente.
Es probable que el scan se centre únicamente en los puertos de servicios
más comunes, por lo que es recomendable usar como centinelas puertos
reservados por algún servicio, pero que no estén abiertos en ese servidor,
por ejemplo SMTP(25), DNS(53), NETBIOS(139). Ademas de esos puertos deberemos
añadir cuantos sean necesarios, para intentar detectar un scan, antes de que
el atacante consiga escanear un puerto abierto.
Por ejemplo si se ha cambiado el puerto por defecto de ssh es muy recomendable
añadir el puerto 22. Ten cuidado de NO usar como centinela un puerto abierto.
# Añadimos los puertos ftp, telnet, smtp, netbios-ssn
iptables -A INPUT -p tcp --dport 21 -m recent --name portscan --set
iptables -A INPUT -p tcp --dport 23 -m recent --name portscan --set
iptables -A INPUT -p tcp --dport 25 -m recent --name portscan --set
iptables -A INPUT -p tcp --dport 139 -m recent --name portscan --set
# Usar como centinelas el puerto ssh y su substituto más común
iptables -A INPUT -p tcp --dport 22 -m recent --name portscan --set
iptables -A INPUT -p tcp --dport 2222 -m recent --name portscan --set
# Bloquear IP por 12 horas si el paquete esta en la tabla portscan
iptables -A INPUT -m recent --name portscan --rchek --seconds 43200 -j DROP
Algunos tipos de scan, usan paquetes construidos de manera que son fáciles de
diferenciar del tráfico legítimo, en ese caso es posible descartarlos
directamente:
# XMAS Scan
iptables -A INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP
# NULL Scan
iptables -A INPUT -p tcp --tcp-flags ALL NONE -j DROP
# SYN/RST Scan
iptables -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
# SYN/FIN Scan
iptables -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
IP Spoofing
Ip spoofing consiste en falsificar la dirección de origen de los paquetes,
en conjunción con algún ataque (pej SYN Flood), hace más dificil detectar
su origen, complica el filtrado de los paquetes, y según la configuración
pueden permitir saltarse algún firewall.
La única posibilidad es eliminar los paquetes que lleguen a un interface de
red, con una dirección de origen que no esten en el rango de direcciones
validas para ese interface:
iptables -A INPUT -i eth0 -s 0.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 127.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 10.0.0.0/8 -j DROP
iptables -A INPUT -i eth0 -s 172.16.0.0/12 -j DROP
iptables -A INPUT -i eth0 -s 192.168.0.0/16 -j DROP
iptables -A INPUT -i eth0 -s 224.0.0.0/3 -j DROP
Tambien se puede activar la verificación de direcciones de origen del kernel,
que proporciona protección anti spoofing. Para comprobar si está activo:
sysctl -n net.ipv4.conf.all.rp_filter
Si no lo esta edita /etc/sysctl.conf y añade:
# Proteccion contra IP Spoofing
net.ipv4.conf.all.rp_filter =1
Ataque Smurf
Consiste en enviar paquetes de broadcast ICMP con la dirección de origen
falseada, de manera que la respuesta al paquete por parte de todos los equipos
en la red, genere una denegación de servicio en el equipo cuya direccion
fue suplantada en los paquetes.
La solución es no responde a los paquetes ICMP de broadcast.
El kernel se puede configurar para que ignore estos paquetes, así que iptables
no son necesarias. Si por defecto no esta activado, añade a /etc/sysctl.cof:
Aviso:Este artículo asume conocimiento del protocolo TCP
Este es un listado de los ataques TCP más comunes que te puedes encontrar en
un servidor en internet.
SYN Flood
Cuando un cliente inicia una conexión TCP con el servidor, lo hace en un
intercambio de 3 paquetes llamado 3-way handshake:
1 El cliente inicia la petición de conexión enviando un paquete SYN
al servidor
2 El servidor responde enviando un paquete SYN-ACK
3 El cliente responde con un paquete ACK para estableces la conexión
El ataque consiste en iniciar la petición de conexión enviando un paquete
SYN tras otro, al llegar al servidor cada petición abre una nueva entrada
en la tabla de conexiones, y envía un paquete SYN/ACK que el atacante
ignora.
El servidor espera un tiempo antes de descartar un conexión que no fue exitosa,
y con la llegada de cada vez más peticiones, la tabla de conexiones se va
llenando hasta que no quedan recursos para gestionar el trafico legitimo.
Las ventajas desde el punto de vista del atacante, es que el ancho de banda
necesario para este ataque es relativamente bajo, especialmente si se usa
ip-spoofing para falsificar la dirección IP de origen de los paquetes SYN,
de manera que la respuesta SYN/ACK se envían a un tercero.
Un escaneo no es un ataque per se, pero suele ser un precursor a un ataque en
el que se escanean los puertos, para buscar servicios disponibles.
En un escaneo SYN en lugar de conectar al puerto para determinar si está
abierto, un atacante envía un paquete SYN y espera a la respuesta, si es
SYN/ACK indica que el puerto esta abierto, si no hay respuesta o es un
paquete RST el puerto está cerrado.
Si la respuesta es un paquete SYN/ACK, el atacante no envía el paquete
ACK de respuesta, no finalizando la conexión lo que hace que sea más
difícil de detectar.
XMAS/FIN/NULL Scan
Un escaneo XMAS envía un paquete tcp con los flagsFIN, URG, y
PSH activados.
Si el puerto esta abierto no hay respuesta, pero si el puerto está cerrado
el destinatario responde con un paquete RST/ACK. Este método sólo funciona
en sistemas que siguen las especificaciones RFC793.
Un escaneo FIN es similar a un scan XMAS pero envía un paquete con el flagFIN activo, recibe las mismas respuestas que XMAS
NULL es similar a los otros dos pero envía un paquete con ningún flag activo.
Acabo de configurar un
VPS
como servidor web, y estas son las reglas iptables con las que empiezo todo
firewall, a partir de aquí voy añadiendo todos los servicios adicionales
que se necesiten.
#!/bin/bash
# Limpiar todas las reglas.
iptables -F
iptables -t nat -F
iptables -t mangle -F
# Creamos tabla para reglas de seguridad eth0
iptables -N security_eth0
iptables -F security_eth0
iptables -A INPUT -i eth0 -j security_eth0
# Admitimos todos los paquetes en interface loopback.
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Aceptamos todos los paquetes de conexiones ya establecidas
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Permitir todas conexiones HTTP entrantes
iptables -A INPUT -i eth0 -p tcp --dport 80 -m state --state NEW -j ACCEPT
# Permitir todas conexiones SSH entrantes
iptables -A INPUT -i eth0 -p tcp --dport 22 -m state --state NEW -j ACCEPT
# Permitir conexiones SSH salientes (DESACTIVADO)
# iptables -A OUTPUT -o eth0 -p tcp --dport 22 -m state --state NEW -j ACCEPT
# Permitir icmp (ping,....)
iptables -A INPUT -p icmp -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
# Permitir acceso DNS saliente
iptables -A OUTPUT -p udp -o eth0 --dport 53 --sport 1024:65535 -j ACCEPT
iptables -A INPUT -p udp -i eth0 --sport 53 --dport 1024:65535 -j ACCEPT
# Por defecto descartamos los paquetes no aceptados explicitamente
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
#
# Medidas de seguridad para paquetes entrantes eth0
#
# echo 1 > /proc/sys/net/ipv4/tcp_syncookies
# Descomentar la siguiente linea para desactivar la tabla security_eth0
# iptables -A security_eth0 -j RETURN
# Ignoramos paquetes nuevos que no tengan flag SYN activado
iptables -A security_eth0 -p tcp ! --syn -m state --state NEW -j DROP
# Ignoramos paquetes invalidos
iptables -A security_eth0 -m state --state INVALID -j DROP
# Descartar paqueter fragmentados
iptables -A security_eth0 -f -j DROP
# Descartar paquetes XMAS
iptables -A security_eth0 -p tcp --tcp-flags ALL ALL -j DROP
# Descartart paquetes NULL
iptables -A security_eth0 -p tcp --tcp-flags ALL NONE -j DROP
# Descartar ip falsas (spoofing)
iptables -A security_eth0 -s 0.0.0.0/8 -j DROP
iptables -A security_eth0 -s 127.0.0.0/8 -j DROP
iptables -A security_eth0 -s 10.0.0.0/8 -j DROP
iptables -A security_eth0 -s 172.16.0.0/12 -j DROP
iptables -A security_eth0 -s 192.168.0.0/16 -j DROP
iptables -A security_eth0 -s 224.0.0.0/3 -j DROP
Este script bloquea todo tráfico entrante y saliente, excepto conexiones
entrantes a los puertos html y ssh, el protocolo icmp, y las consultas DNS
salientes.
También crea la tabla security_eth0, donde se filtran todos los paquetes
entrantes por eth0, para realizar algunos chequeos de seguridad.
Si no quieres añadir el script directamente a init.d, puedes introducir las
reglas manualmente en el shell, y luego usar iptables-persistent para
salvarlas.
$ sudo apt-get install iptables-persistent
Durante la instalación preguntará si quieres salvar las reglas de iptables,
responde si, y serán salvadas en /etc/iptables/rules.v4 para ipv4, y
/etc/iptables/rules.v6 para ipv6. Por último iniciamos el servicio:
Hace unos días encontré un video interesante sobre
inyección SQL en PHP
(Inglés), y lo que me pareció más curioso, es que aún siga siendo un
problema de seguridad tan extendido, he buscado las cifras y es el segundo
ataque más usado con un 16%, detras de
cross-site scripting con
un 37%.
Si te ha gustado el video, el canal
Computerphile
tiene muchos más videos interesantes relacionados con la informática.
AIDE (Advanced Intrusion Detection Environment) es un programa de detección
de intrusos, en especifico un monitor de integridad de archivos. Cuando un
intruso consigue acceso a un sistema, una sus primera acciones será modificar
los logs del sistema, y/o modificar algún programa para mantener el control,
y ocultar su presencia. Por ejemplo puede sustituir el programa ps para que
no liste determinados procesos, añadir el bit SUID a una copia del shell,
o instalar algún rootkit.
Detectar esto es prácticamente imposible manualmente, AIDE en cambio nos
permite hacerlo de forma rápida y sencilla, haciendo imposible cualquier
manipulación de los archivo o directorios monitorizados.
Instalación
La instalación es sencilla la única dependencia del paquete, es un servidor
de correo para poder enviar los informes y alertas al root, o a la dirección
especificada, asegurate de que esta funcionando correctamente, antes de
continuar con la configuración.
sudo apt-get install aide
Configuración
Antes de modificar la configuración por defecto de aide, vamos a comprobar que
funciona correctamente, para ello generamos la primera base de datos. Este
proceso puede ser muy lento dependiendo del ordenador, y del numero de archivos
a monitorizar.
sudo aideinit
Una vez generada, la copiamos para instalarla:
sudo cp /var/lib/aide.db.new /var/lib/aide.db
Ahora podemos modificar la configuración para incluir cualquier directorio
que necesitemos monitorizar, o eliminar algún directorio en el que no estemos
interesados. Los archivos de configuración de AIDE en Debian/Ubuntu,
son /etc/aide/aide.conf y el directorio /etc/aide/aide.conf.d/
, estos no son usados directamente por AIDE, sino que el script
update-aide.config recopila toda la información y, crea el archivo
final /var/lib/aide/config.autogenerated.
Para añadir nuestros directorios a la configuración, tenemos que crear un
archivo en el directorio /etc/aide/aide.conf.d
El número al inicio indica el orden en el que el archivo es cargado,
hay que asegurarse de que el numero de nuestro archivo es el mayor del
directorio, de esta manera nuestra configuración sea la última en cargar y no
tengamos conflictos.
Cada archivo contiene la lista de directorios y archivos que tienen que ser
monitorizados por AIDE, por ejemplo los archivos de configuración de una
aplicación, el directorio de contenidos estáticos de una pagina web, o el
directorio donde se guardan los backups, etc. Tras cada una de esas rutas,
se añade la lista de aspectos que tiene que ser monitorizados, usando el
mismo formato definido en el manual de AIDE
En el siguiente ejemplo se pueden ver algunas de las posibilidades que ofrece
AIDE, otra buena fuente son los archivos de configuración en
/etc/aide/aide.conf.d/
# Parametros que pueden ser comprobados## p: permissions# ftype: file type# i: inode# n: number of links# l: link name# u: user# g: group# s: size# b: block count# m: mtime# a: atime# c: ctime# S: check for growing size# I: ignore changed filename# md5: md5 checksum# sha1: sha1 checksum# sha256: sha256 checksum# sha512: sha512 checksum# rmd160: rmd160 checksum# tiger: tiger checksum# haval: haval checksum# crc32: crc32 checksum# R: p+ftupe+i+l+n+u+g+s+m+c+md5# L: p+ftype+i+l+n+u+g# E: Empty group# >: Growing logfile p+ftype+l+u+g+i+n+S# The following are available if you have mhash support enabled:# gost: gost checksum# whirlpool: whirlpool checksum# The following are available and added to the default groups R, L and ># only when explicitly enabled using configure:# acl: access control list# selinux SELinux security context# xattrs: extended file attributes# e2fsattrs: file attributes on a second extended file system# Creamos nuestras reglas.MinimalCheck= p+i+u+g
FullCheck= p+i+n+u+g+s+b+c+sha256
# Directorios a monitorizar
/home/secnot/private/website MinimalCheck
/home/secnot/chroot FullCheck
# Archivo a monitorizar# a diferencia de los directorios los archivos son terminados en '$'# antes de '.' hace falta un caracter de escape '\'
/home/secnot/mi_aplicacion\.conf$ FullCheck
# Usar las reglas no es necesario pero es más legible
/etc/mi_otra_aplicacion\.conf$ p+i+g+d
# Podemos usar las reglas definidas en /etc/aide/aide.conf,# como en los otros archivos de configuración
/home/webuser/webapp VarLog
# Forzamos que se ignore un archivo o varios
!/etc/app\.conf$
!/var/log/.*
Por último solo nos queda editar /etc/default/aide, en el cual podemos
definir donde deseamos que lleguen los informes generados periódicamente
(por defecto root), junto algunas opciones más sobre los mismos.
Uso
Cada vez que realicemos alguna modificación, instalemos, o eliminemos algún
programa, generamos una nueva base de datos, a partir de ese momento cada
vez que se ejecute AIDE se comprobará que nada ha sido alterado con respecto
al estado almacenado en la base de datos.
Como medida de seguridad adicional, es recomendable calcular un hash de la base
de datos, para poder comprobar manualmente que no ha sido modificada por un
atacante. Guarda una copia del hash en un lugar seguro.
sha256sum /var/lib/aide/aide.db
AIDE es ejecutado automáticamente todos los días por cron, a través de un
script en /etc/cron.daily/, este ejecuta update-aide.config para generar un
archivo de configuración actualizado, y después llama aide.
Una vez la comprobación ha terminado, almacena la información en los archivos
de log /var/log/aide/aide.log y de errores /var/log/aide/error.log,
por último envía un informe a la dirección de correo configurada si es que
una existe.
Si queremos comprobar si ha habido alguna modificación manualmente, primero
es recomendable comprobar que la base de datos no ha sido modificada usando
sha256sum, después podemos ejecutar el script:
sudo /usr/bin/aide.wrapper
O podemos generar manualmente el archivo de configuración, y después
ejecutar aide.