Tienda Wifi

Tienda Wifi
CiudadWireless es la tienda Wifi recomendada por elhacker.NET

Buscador

Entradas Mensuales

Suscripción

¿Quieres recibir las últimas novedades del blog en tu correo?

¡Suscríbete al feed!

Foro de elhacker.net - Noticias

elhacker.NET en Facebook

Entradas populares

PostHeaderIcon DDoS Deflate, script bash para mitigar ataques DoS




Ya hemos hablado muchas veces sobre los ataques DDoS y DoS, pero hoy os presentamos un sencillo pero útil script en bash para controlar y banear ip's que realizan demasiadas conexiones "persistentes" y banearlas automáticamente mediante APF o iptables durante un cierto período de tiempo



Básicamente lo único que hace el script bash es un netstat para ver el número de conexiones abiertas en el puerto que sea (no sólo nos protege de ataques http, también de otro tipo de conexiones simultáneas a otros puertos).

netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -n
Si el resultado del comando detecta más de n conexiones de una misma ip la banea automáticamente mediante iptables, añadiendo una entrada en iptables  con la instrucción:

iptables -D INPUT -s $ip -j DROP

Instalación


wget http://www.inetbase.com/scripts/ddos/install.sh
chmod 0700 install.sh
./install.sh

Lo que hace el script es bajar los ficheros de configuración y el propio script y copiarlos al directorio /usr/local/ddos

#!/bin/sh
if [ -d '/usr/local/ddos' ]; then
    echo; echo; echo "Please un-install the previous version first"
    exit 0
else
    mkdir /usr/local/ddos
fi
clear
echo; echo 'Installing DOS-Deflate 0.6'; echo
echo; echo -n 'Downloading source files...'
wget -q -O /usr/local/ddos/ddos.conf http://www.inetbase.com/scripts/ddos/ddos.conf
echo -n '.'
wget -q -O /usr/local/ddos/LICENSE http://www.inetbase.com/scripts/ddos/LICENSE
echo -n '.'
wget -q -O /usr/local/ddos/ignore.ip.list http://www.inetbase.com/scripts/ddos/ignore.ip.list
echo -n '.'
wget -q -O /usr/local/ddos/ddos.sh http://www.inetbase.com/scripts/ddos/ddos.sh
chmod 0755 /usr/local/ddos/ddos.sh
cp -s /usr/local/ddos/ddos.sh /usr/local/sbin/ddos
echo '...done'

echo; echo -n 'Creating cron to run script every minute.....(Default setting)'
/usr/local/ddos/ddos.sh --cron > /dev/null 2>&1
echo '.....done'
echo; echo 'Installation has completed.'
echo 'Config file is at /usr/local/ddos/ddos.conf'
echo 'Please send in your comments and/or suggestions to zaf@vsnl.com'
echo
cat /usr/local/ddos/LICENSE | less

 En el fichero de configuración ddos.conf del directorio /usr/local/ddos

 ##### Paths of the script and other files
PROGDIR="/usr/local/ddos"
PROG="/usr/local/ddos/ddos.sh"
IGNORE_IP_LIST="/usr/local/ddos/ignore.ip.list"
CRON="/etc/cron.d/ddos.cron"
APF="/etc/apf/apf"
IPT="/sbin/iptables"

##### frequency in minutes for running the script
##### Caution: Every time this setting is changed, run the script with --cron
#####          option so that the new frequency takes effect
FREQ=1

##### How many connections define a bad IP? Indicate that below.
NO_OF_CONNECTIONS=150

##### APF_BAN=1 (Make sure your APF version is atleast 0.96)
##### APF_BAN=0 (Uses iptables for banning ips instead of APF)
APF_BAN=0

##### KILL=0 (Bad IPs are'nt banned, good for interactive execution of script)
##### KILL=1 (Recommended setting)
KILL=1

##### An email is sent to the following address when an IP is banned.
##### Blank would suppress sending of mails
EMAIL_TO="webmaster@elhacker.net"

##### Number of seconds the banned ip should remain in blacklist.
BAN_PERIOD=600

Nota: Si tenemos un servidor con muchas descargas de ficheros grandes (ejemplo isos) puede ser que algún cliente legítimo (falso positivo) usando alguna herramienta de descargas alcance 150 conexiones en el servidor web).



Por defecto el programa añade una entrada en cron jobs para ejecutarse cada minuto y si detecta una ip con más de 150 conexiones la banea durante un período de 600  segundos (10 minutos), manda un e-mail a root (podemos editar el email de root en el fichero /etc/aliases) añadiendo una entrada:

root: webmaster@elhacker.net

El script mira si una ip tiene más de 150 conexiones abiertas y la banea automáticamente durante 10 minutos.

La entrada del cron job se añade en /etc/cron.d con el nombre ddos.cron

 SHELL=/bin/sh
0-59/1 * * * * root /usr/local/ddos/ddos.sh >/dev/null 2>&1

En el fichero /usr/local/ddos/ignore.ip.list podemos definir la lista blanca de ip's que serán ignoradas aunque tengan más de 150 conexiones. Sería una buena idea añadir nuestra propia ip

127.0.0.1
144.76.224.7

 Si el script detecta una ip atacante nos enviará un e-mail con el asunto "IP addresses banned", la fecha de la detección y la ip baneada con el número de conexiones que ha detectado.

IP addresses banned on Mon Dec 23 21:46:01 CET 2013

Banned the following ip addresses on Mon Dec 23 21:46:01 CET 2013

192.147.213.222 with 453 connections

Podemos ver con el comando iptables las reglas actuales activas para ver como la ip atacante ha sido añadida:

iptables -L

 Resultado, entrada añadida para la ip 192.147.213.222

DROP       all  --  192.147.213.222  anywhere   

También podemos añadir de forma permanente la ip baneada añadiendo una entrada al fichero /etc/sysconfig/iptables

-A INPUT -s 192.147.213.222 -j DROP

Si el script banea ip's incorrectas (del tipo ::ffff)

netstat -ntu | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr > $BAD_IP_LIST

deberíamos reemplazar la línea 117 por:

netstat -ntu | grep ‘:’ | awk ‘{print $5}’ | sed ‘s/::ffff://’ | cut -f1 -d ‘:’ | sort | uniq -c | sort -nr > $BAD_IP_LIST

De hecho los cambios  están en un fork en github:

https://github.com/chrisnharvey/DDoS-Deflate

O una versión muy similar pero re-escrita que añade nuevas opciones:

  • Reverso de ip's (reverso dns)
  • Posibilidad de avisar (warning) si son más de x conexiones y banear si son más x
  • Guardar un log con la fecha y las ip's baneadas
https://github.com/colinmollenhour/ddos-deflate

Aunque deberíamos quitar el grep ESTAB ( de Established), ya que si estamos recibiendo un ataque syn-flood, los estados podrían ser: SYN_RECV, TIME_WAIT, FIN_WAIT2, LAST_ACK

Línea 184:

netstat -ntu | grep ESTAB | grep ':' | awk '{print $5}' | sed 's/::ffff://' | cut -f1 -d ':' \ | sort | grep -v -f <(grep -vF '#' $IGNORE_IP_LIST | sort) | uniq -c \ | awk "{ if (\$1 >= $WARN_LIMIT) print; }" | sort -nr \
Cambiar por:

netstat -ntu | grep ':' | awk '{print $5}' | sed 's/::ffff://' | cut -f1 -d ':' \ | sort | grep -v -f <(grep -vF '#' $IGNORE_IP_LIST | sort) | uniq -c \ | awk "{ if (\$1 >= $WARN_LIMIT) print; }" | sort -nr \

Un script muy similar pero escrito en perl es Citadel

Desinstalación


wget http://www.inetbase.com/scripts/ddos/uninstall.ddos
chmod 0700 uninstall.ddos
./uninstall.ddos

O eliminar el cronjob y el directorio /usr/local/ddos

Otras maneras de detectar un ataque DoS

 Ordenar el número  de conexiones al puerto 80 de menor a mayor:

 netstat -an | grep :80 | awk '{ print $5 }' | awk -F: '{ print $1 }' | sort | uniq -c | sort -n

Ejemplo resultado en caso de un ataque:
      
[..]
169 190.11.90.215
221 190.228.135.10
424 186.11.240.81
526 179.12.27.14 
Muy probablemente una ip con 526 conexiones o 424 nada bueno puede estar haciendo

Contar número de peticiones abiertas en el servidor web (puerto 80) sea Apache o Nginx)

netstat -an | grep :80|wc -l
Contar número de conexiones en estado SYN_RECV

netstat -an | grep :80 | grep -i syn | wc -l

Con iptables una de las maneras más sencillas pero efectivas de mitigar un ataque es con el módulo recent:

/sbin/iptables -I INPUT -p tcp -m state --state NEW --dport 80 -m recent --update --seconds 15 --hitcount 10 -j DROP

Ver las ip's conectadas sin usar netstat:

cat /proc/net/ip_conntrack | awk '{print $5" "$6}' | sort -nr | uniq -c

Ordenar por consumo de tráfico (bandwidth) usando iptables

/sbin/iptables -L -v -n | sort -n

 Limitar ataques SYN_Flood usando limit y limit-burst

Con iptables:

--limit rate[/second|/minute|/hour|/day] Maximum average matching rate: specified as a number, with an optional `/second’, `/minute’, `/hour’, or `/day’ suffix; the default is 3/hour.

--limit-burst

Maximum initial number of packets to match: this number gets recharged by one every time the limit specified above is not reached, up to this number; the default is 5.
iptables -N DDoS
iptables -A DDoS -m limit –limit 1/s –limit-burst 10 -j RETURN
iptables -A DDoS -j LOG –log-prefix “[Recibiendo ataque DDOS]“
iptables -A DDoS -j DROP

iptables -N syn-flood
iptables -A syn-flood -m limit --limit 50/second --limit-burst 100 -j LOG --log-prefix "Firewall syn-flood "
iptables -A syn-flood -j DROP
Con --limit se especifica una media, no un caudal. Por ejemplo: decir 3/minuto puede significar que en el primer minuto se reciben 3 paquetes y en el segundo también 3 o puede significar que en el primer minuto se reciben 5 y en el segundo 1... la media sigue siendo 3/minuto.

--limit-bust especifica un máximo, si no se especifica un --limit-burst por defecto vale 5 y significa que se aceptaran los primeros 5 paquetes y luego se esperara hasta alcanzar la media para seguir aceptando. Parece complicado pero no lo es.

Ejemplo: especificaste un --limit 3/segundo y un --limit-burst 6, entonces se aceptarán los primeros 6 paquetes, no importa que tan seguido vengan, luego se dejara de aceptar hasta alcanzar la media, es decir se esperará a que se cumplan 2 segundos y luego se volverá a permitir un máximo de 6.

-A INPUT -p tcp -m tcp --dport 80 -m limit --limit 75/second --limit-burst 120 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -m limit --limit 75/second --limit-burst 200 -j LOG
-A INPUT -p tcp -m tcp --dport 80 -j DROP

Con la herramienta (script floodmon)

Floodmon: alerta, detecta y mitiga ataques SYN Flood


Quizás sea el momento para instalar soluciones más avanzadas como  APF (Advanced Policy Firewall) o BFD (Brute Force Detect).

O usar servicios gratuitos como la CDN de CloudFlare que permite:


  • Ocultar la ip real (Usando las DNS de CloudFlare)
  • Crear un front end para la web (WAF (Web Application Firewall)
  • Bloquear visitantes por País (CloudFlare Threat Control Block list)
  • Crear reglas (Redireccionar http a https o viciversa, redireccionar una url con un 301 o 302, cachear)
  • Añadir test Captcha para verificar si son humanos o bots


Detectar patrones del tráfico recibido con tcpdump

tcpdump -nn 'tcp[13] == 2' and port 80 -c 100 -i any
tcpdump -Annvvs 1500 'tcp[13] == 2' and port 80 -c 100 -i any

Otras soluciones y contramedidas ya fueron vistas en el manual  de Intentando Detener un Ataque DDoS



Error en Apache que suele estar causado por denegación de servicio (DoS o distribuido DDoS)
[Mon Dec 23 07:19:34 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:35 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:39 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:40 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:40 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:19:46 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:20:05 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:21:07 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:21:11 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:21:22 2013] [error] [client 186.58.83.79] request failed: error reading the headers
[Mon Dec 23 07:21:25 2013] [error] [client 186.58.83.79] request failed: error reading the headers

Puede estar provocado por herramientas DoS bastante efectivas como Slowris o más rudimentarias como LOIC (Low Orbit Ion Cannon)


Si en el fichero de errores del Apache:
grep -i maxclient /usr/local/apache2/logs/error_log

Aparecen errores como:

server reached MaxClients setting, consider raising the MaxClients setting

Significa que el número de conexiones simultáneas del Apache (podemos verlo fácilmente con el server-status) ha sido alacanzado y deberíamos considerar aumentarlo, siempre y cuando tengamos recursos suficientes para hacerlo.

1 comentarios :

Maravento Studio dijo...

muy bueno.
Una aclaratoria:
En el caso de la versión modificada https://github.com/colinmollenhour/ddos-deflate cambia ignore.ip.list por solo ignore

una duda:
En el github modificado https://github.com/colinmollenhour/ddos-deflate
se sugiere
4. Add the cron job (optional)
/usr/local/ddos/ddos.sh --cron
Sin embargo en el original de instalacion http://www.inetbase.com/scripts/ddos/install.sh
Aparece lo siguiente:
echo; echo -n 'Creating cron to run script every minute.....(Default setting)'
/usr/local/ddos/ddos.sh --cron > /dev/null 2>&1
echo '.....done'
La duda es: Por qué 2 cronjob iguales????
Gracias

Publicar un comentario en la entrada

Los comentarios pueden ser revisados en cualquier momento por los moderadores.

Serán publicados aquellos que cumplan las siguientes condiciones:
- Comentario acorde al contenido del post.
- Prohibido mensajes de tipo SPAM.
- Evite incluir links innecesarios en su comentario.
- Contenidos ofensivos, amenazas e insultos no serán permitidos.

Debe saber que los comentarios de los lectores no reflejan necesariamente la opinión del STAFF.