InjectionDenied: detección y bloqueo de ataques PHP y SQL
Por Fernando Acero
Después de revisar un poco lo que hace DenyHosts, vamos a ver la forma de configurar e instalar InjectionDenied, que es un sencillo programa de Jordi Blasco Pallarés, que hace algo muy similar a lo que hace DenyHosts con el demonio SSH, pero en este caso bloquea las IPs desde las que se intentan hacer inyecciones PHP o SQL a un servidor web. Este programa está basado en bash/gawk, por lo que es muy sencillo de entender y modificar aunque, como es lógico, tenemos que tener instalado gawk en nuestro sistema si queremos que InjectionDenied funcione adecuadamente...
INSTALACIÓN Y CONFIGURACIÓN DEL PROGRAMA
Para instalar el programa, basta con bajarse la última versión de Sourceforge, la 0.0.1:
wget http://downloads.sourceforge.net/injectiondenied/injectiondenied-0.01.tar
Una vez que tengamos el programa, será necesario extraer los archivos:
tar -xf injectiondenied-0.01.tar
El programa consta de tres archivos, que deben estar en las trayectorias que se indican:
/etc/init.d/injectdenied (que debe ser ejecutable) /etc/injectiondenied/rules (que contiene las reglas) /usr/local/bin/hackreport.sh (que tiene que ser ejecutable).
Yo soy usuario de Mandriva y este programa está pensado para Debian, por lo que usa ciertos recursos específicos para Debian, como start-stop-daemon. La solución es instalar el paquete dpkg que contiene este recurso; para ello, usaremos el comando siguiente:
urpmi dpkg
El programa tal como está no funciona; es necesario configurar algunas cosas antes de arrancarlo por primera vez. Primero editaremos /usr/local/bin/hackreport.sh y cambiaremos las líneas siguientes, para que apunten a nuestro archivo de logs de acceso al Apache, en mi caso /var/log/httpd/access_log:
gawk -v RULE="$i" '{if(match ($7,RULE)!=0){print $1}}' /var/log/httpd/access_log >> /tmp/banned_ip.dat
gawk -v RULE="$i" '{if(match ($7,RULE)!=0){print $1 "\t " $6 " " $7}}' /var/log/httpd/access_log >> /tmp/hack.log
También modificaremos las líneas siguientes, para que los correos con las alertas lleguen a la cuenta de correo que deseemos:
mail -s "[INJECT] Possibles intents de Hack" root@server.com < /tmp/hack.log mail -s "[INJECT] Entrades al hosts.deny" root@server.com < /etc/hosts.deny
Finalmente hay que modificar /etc/init.d/injectdenied para que permita la opción restart, elimine el proceso y para que muestre información sobre el PID que se ha arrancado. El código de pruebas que estoy usando es éste; es muy parecido al original, pero no me convence demasiado y es posible que lo cambie para que use el mandato "daemon" en lugar de start-stop-daemon, por ser más cercano al Linux Standard Base:
start)
# Modificado por Fernando Acero 16SEP08
echo -n "Iniciando $DESC: $NAME"
start-stop-daemon -b --start --quiet --pidfile /var/run/injectiondenied.pid --exec $DAEMON
ps -fea | grep hackreport|head -1| gawk '{print $2}' > /var/run/injectiondenied.pid
# Modificado por Fernando Acero 16SEP08 (cambiado texto)
echo "ARRANCADO"
;;
stop)
# Modificado por Fernando Acero 16SEP08 (cambiado texto)
echo -n "Deteniendo $DESC: injectiondenied"
start-stop-daemon --stop --quiet --pidfile /var/run/injectiondenied.pid
# Modificado por Fernando Acero 16SEP08 (activado kill)
kill $PID
# Modificado por Fernando Acero 16SEP08 (cambiado texto)
echo "DETENIDO"
;;
# Bloque restart modificado por Fernando Acero 16SEP08 (añadido bloque completo)
restart)
echo -n "Deteniendo $DESC: injectiondenied"
start-stop-daemon --stop --quiet --pidfile /var/run/injectiondenied.pid
kill $PID
echo "DETENIDO"
echo -n "Iniciando $DESC: $NAME"
start-stop-daemon -b --start --quiet --pidfile /var/run/injectiondenied.pid --exec $DAEMON
ps -fea | grep hackreport|head -1| gawk '{print $2}' > /var/run/injectiondenied.pid
echo "ARRANCADO $PID"
;;
*)Como se puede ver, el mandato restart es simplemente la copia de los mandatos stop y start sin la finalización de stop ";;" para que siga con la ejecución del arranque tras parar de forma efectiva el proceso.
Como no estoy seguro de su estabilidad, lo he metido en cron.hourly para que se reinicie cada hora. Por el momento tengo este programa en pruebas, por lo que poco puedo decir de su funcionamiento en este momento, aunque también es cierto que en algunas cosas me parece algo incompleto, por ejemplo, no tenía el código para restart. De todos modos, también estoy usando Snort con psad y los módulos apache_ModSecurity y suhosin, entre otros en mi servidor, todos ellos más que recomendables, por lo que no creo que su funcionamiento sea demasiado crítico para mejorar la seguridad de mi servidor, pero por probar no se pierde nada.
"Copyleft 2008 Fernando Acero Martín. Verbatim copying, translation and distribution of this entire article is permitted in any digital medium, provided this notice is preserved."

- 785 lecturas
Twitter

petición formal
Igual suena a lo que no quiero que suene.
Esto me ha impresionado hasta el punto de decidirme a sugerir a admin que tal vez sea el momento de lanzar una distro "kriptópolis", implementada con todas aquellas cosas que se han estudiado en este sitio y que se han revelado eficaces. Yo pagaría por ello con mucho gusto si sirve para elevar el nivel de calidad del sitio.
Lo digo por que, tal vez, muchos de nosotros estamos en el umbral que separa el "entender" de el "realizar".
No pretendo molestar a nadie, sino solo lanzar con el mayor de los respetos una idea que, por supuesto, puede terminar en la papelera. Lo entendería.
Enhorabuena a Fernado Acero una vez más... estoy impresionado.
Estimado amigo...
Hola borinquin, no es para tanto, cualquiera puede hacer esto con un poco de paciencia y una caña.
Por cierto, como me temía y esperaba, el código de /etc/init.d/injectiondenied no ha marchado demasiado bien esta noche, ya que si muere el proceso, el sistema no lo vuelve a arrancar, estoy en ello ya que ese archivo estaba incompleto como he comentado en mi artículo y muy verde para ser funcional en un servidor en producción. Cuando tenga algo lo publicaré aquí.
Un saludo, Fernando Acero
.htpaccess
Hola Fernando,
Te paso mi .htaccess, que quizás te ayude a protegerte contra ataques de inyecciones SQL.
Puedes cambiar la última línea por una redirección a la página de tu elección.
Está
robadotomado prestado del excelente blog de rvdh en www.0x000000.com. Hay un tutorial aquí.RewriteEngine On
Options +FollowSymLinks
ServerSignature Off
RewriteCond %{REQUEST_METHOD} ^(HEAD|TRACE|DELETE|TRACK) [NC,OR]
RewriteCond %{THE_REQUEST} ^.*(\\r|\\n|%0A|%0D).* [NC,OR]
RewriteCond %{HTTP_REFERER} ^(.*)(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{HTTP_COOKIE} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{REQUEST_URI} ^/(,|;|:|<|>|">|"<|/|\\\.\.\\).{0,9999}.* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^$ [OR]
RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(libwww|curl|wget|python|nikto|scan).* [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(;|<|>|'|"|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|cast|set|declare|drop|update|md5|benchmark).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(localhost|loopback|127\.0\.0\.1).* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*\.[A-Za-z0-9].* [NC,OR]
RewriteCond %{QUERY_STRING} ^.*(<|>|'|%0A|%0D|%27|%3C|%3E|%00).* [NC]
RewriteRule ^(.*)$ error.php
Una buena opción
Gracias Andy, ya conocía esta técnica basada en el módulo rewrite de apache, que lo que hace es "limpiar" las peticiones malévolas. Hay un pequeño error en tu comentario, el nombre del archivo es .htaccess, no .htpaccess, es decir, sobra la "p".
Este archivo es muy interesante ya que además de ser el archivo por omisión para la configuración de directorios de Apache, también permite personalizar la configuración de las directivas definidas en el archivo de configuración principal. Para ello, las directivas de configuración necesitan estar en el contexto de .htaccess y el usuario necesita los permisos apropiados, siendo este uno de los errores más comunes cuando se configura este archivo.
Por ejemplo, también se pueden bloquear robots maliciosos usando la misma técnica:
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} ^BlackWidow [OR]
...
...
RewriteCond %{HTTP_USER_AGENT} ^ChinaClaw [OR]
...
...
...
RewriteRule .* - [F]
Incluso, se pueden eliminar las www:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{http_host} ^www\.ejemplo\.com[nc]
RewriteRule ^(.*)$ http://ejemplo.com/$1 [r=301,nc]
En cada carpeta del navegador puede haber un archivo .htaccess con configuraciones particulares. Se pueden hacer muchas cosas interesantes mediante este archivo y que la gente ni se imagina, por ejemplo, limitar el acceso a usuarios que vienen desde determinadas páginas, evitando así referers maliciosos o incluso, eliminar la posibilidad de eliminar el hotlinking a archivos que pesen demasiado en nuestra web, conservando así nuestro ancho de banda.
Un saludo, Fernando Acero
Corregido
Ya lo he corregido en el comentario original.
Se agradece
Gracias por la corrección y gracias también a Fernando por puntualizar el error.
Es lo que tiene escribir comentarios a las prisas y corriendo antes de salir para la oficina.
Otro código que funciona mejor
Sigue siendo un poco chapuza todavía pero funciona mejor que el de ayer, queda mucho por depurar todavía, pero ya no se queda colgado el demonio, aunque hay el riesgo de lanzar varios de ellos en ciertas condiciones:
#!/bin/bash . /etc/rc.d/init.d/functions DAEMON=/usr/local/bin/hackreport.sh NAME=InjectionDenied DESC="Injection Denied" RETVAL=0 PID_FILE=/var/run/injectiondenied.pid test -x $DAEMON || exit 0 PID=0 set -e #---------------- start() { gprintf "Starting %s:" "$NAME" start-stop-daemon -b --start --quiet --pidfile /var/run/injectiondenied.pid --exec $DAEMON && success "startup" || failure "startup" ps -fea | grep hackreport|head -1| gawk '{print $2}' > /var/run/injectiondenied.pid PID=`ps -fea | grep hackreport|head -1| gawk '{print $2}'` RETVAL=$? echo [ "$RETVAL" = 0 ] && touch /var/lock/subsys/injectiondenied echo " / ARRANCADO $PID" } stop() { gprintf "Stopping %s:" "$NAME" PID=0 PID=`ps -fea | grep hackreport|head -1| gawk '{print $2}'` if [ -r /var/run/injectiondenied.pid ]; then echo " / PARANDO $PID" kill -TERM `cat /var/run/injectiondenied.pid` RETVAL=$? [ "$RETVAL" = 0 ] && success "stop" || failure "stop" echo else [ "$RETVAL" = 0 ] && failure "already stoped" || sucess "already stopped" echo fi rm -rf /var/lock/subsys/injectiondenied rm -rf /var/run/injectiondenied.pid echo } case "$1" in start) start ;; stop) stop ;; restart) stop sleep 2 start ;; *) gprintf "Usage: %s {start|stop|restart|reload|condrestart|status}\n" "$0" RETVAL=1 esac exit $RETVALmod_security
Si estáis interesados en el tema, no dejéis de echar un vistazo al mod_security.