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."

Comentarios

Selecciona arriba tu forma preferida de visualizar los comentarios y pulsa el botón para guardar tu elección para próximas visitas (sólo si eres usuario registrado).
borinquin's picture

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.

Fernando Acero's picture

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

"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".

"Copyleft Fernando Acero Martí­n. Verbatim copying, translation and distribution of this entire article is permitted in any digital medium, provided this notice is preserved. Quotation is allowed."

Andy's picture

.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á robado tomado 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

Fernando Acero's picture

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

"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".

"Copyleft Fernando Acero Martí­n. Verbatim copying, translation and distribution of this entire article is permitted in any digital medium, provided this notice is preserved. Quotation is allowed."

admin's picture

Corregido


es .htaccess, no .htpaccess

Ya lo he corregido en el comentario original.

Andy's picture

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.

Fernando Acero's picture

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 $RETVAL
"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".

"Copyleft Fernando Acero Martí­n. Verbatim copying, translation and distribution of this entire article is permitted in any digital medium, provided this notice is preserved. Quotation is allowed."

anónimo's picture

mod_security


Si estáis interesados en el tema, no dejéis de echar un vistazo al mod_security.