Mod Security y detener subida de ficheros maliciosos usando File Inspection con tus Home-Made Script.

Poco o nada hemos hablado en Inseguros del Firewall para web por excelencia en el mundo Open Source, Mod Security.

Me gustaría comentar una pequeña regla para implementar una medida para nuestros webserver que sin duda recomiendo.


El objetivo de la regla es inspeccionar todas las subidas de ficheros que se realizan por HTTP, para ejecutar un script a nuestro gusto.

Uno de los vectores de ataque conocidos en aplicaciones Web es RFI y la temida subida de ficheros tipo defacement o shells. La mayoría de los plugins de seguridad para los CMS famosos ( WordPress, Drupal, Joomla etc) tiene capada la subida de shell´s en PHP. Incluso desde HTACCESS. Pero cabe la posibilidad de enmascarar una shell bajo un fichero gráfico (Jpeg, Png, etc).

Con esta regla de Mod Security y la ejecución de nuestro script podemos analizar el contenido del supuesto fichero gráfico en busca de contenido php por ejemplo y las típicas funciones incluidas en la mayoría de shell´s.


La regla en cuestión, que habilitamos en nuestro fichero de reglas personal, podría ser esta:

SecRule FILES_TMPNAMES "@inspectFile /usr/bin/scan.sh" "log,deny,msg:'Restricted Upload File Type',id:123456,ctl:debugLogLevel=9"

La opción final del debug no es necesaria, pero para su primer uso os la recomiendo.

En el fichero de configuración general de Mod Security debemos habilitar SecUploadFileMode 0644

También debemos asegurarnos que el usuario que ejecuta Apache tiene permisos de ejecución del fichero.

El script en cuestión debe retornar un echo 0 si queremos que corte, o echo 1 si queremos que pase la subida.

Lo primero que debéis hacer es crear un script que SOLO tire un echo 0, y monitorizar el log de Mod Security. Probamos a subir un fichero editando un post en un CMS, subiendo una imagen en un foro, o cualquier subida de ficheros que tengamos habilitada en nuestra aplicación web.

Una vez hayamos comprobado que la regla se ejecuta, podemos implementar la lógica de nuestro script, por ejemplo, buscando esto dentro del fichero:

egrep -i "(mail|proc_open|str_rot13|preg_replace|gzinflate|stream_socket_client|myshellexec|curl_multi_exec|shell_exec|chmod|fwrite|curl_exec|popen|show_source|fsockopen|pfsockopen|stream_socket_client|exec|system|passthru|eval|base64_decode) 

Un ejemplo de alerta sobre una subida no autorizada por nuestro script:

Message: Access denied with code 403 (phase 2). File "/var/lib/mod_security/20140903-093438-VAbEjl4XF@AAAFN3IhIAAAAF-file-mheR1Z" rejected by the approver script "/usr/bin/scan.sh": 0 [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_15_customrules.conf"] [line "3"] [id "123456"] [msg "Restricted Upload File Type"]
Action: Intercepted (phase 2)
Apache-Handler: php5-script
Stopwatch: 1409729678296075 17577 (- - -)
Stopwatch2: 1409729678296075 17577; combined=15400, p1=168, p2=15221, p3=0, p4=0, p5=10, sr=60, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.7.3 (http://www.modsecurity.org/); OWASP_CRS/2.2.6.
Server: Apache
Engine-Mode: "ENABLED"

--a5a20472-J--
7,3,"php.jpg",""
Total,3

Fijaros en la ruta del archivo. Podemos configurar en Mod Security la ruta temporal del archivo mientras procesa la regla. Importante conocer la ubicación del archivo si queremos realizar con nuestro script alguna tarea de copia de seguridad para análisis posterior y similares.
Para configurar la ruta temportal de ficheros:

SecTmpDir /var/lib/mod_security
SecDataDir /var/lib/mod_security

Un ejemplo retocado del debug de la regla:

[03/Sep/2014:09:36:32 +0200] [URL DE TU SITIO/sid#7f0a29389c88][rid#7f0a2a633508][/wp-admin/async-upload.php][4] Ctl: Set debugLogLevel to 9.

empieza el debug de la regla

[03/Sep/2014:09:36:32 +0200] [URL DE TU SITIO/sid#7f0a29389c88][rid#7f0a2a633508][/wp-admin/async-upload.php][4] Rule returned 1.

el 1 es la regla de modsec, no el script

[03/Sep/2014:09:36:32 +0200] [URL DE TU SITIO/sid#7f0a29389c88][rid#7f0a2a633508][/wp-admin/async-upload.php][9] Match, intercepted -> returning.

[03/Sep/2014:09:36:32 +0200] [URL DE TU SITIO/sid#7f0a29389c88][rid#7f0a2a633508][/wp-admin/async-upload.php][1] Access denied with code 403 (phase 2). File "/var/lib/mod_security/20140903-093632-VAbFAF4XF@AAAFW0OaoAAAAK-file-vxoE0C" rejected by the approver script "/usr/bin/scan.sh": 0

este es el cero que debe retornar el script

 [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_15_customrules.conf"] [line "****"] [id "123456"] [msg "Restricted Upload File Type"]

Como siempre espero que os guste, gracias por leerme !!!