Una de las premisas básicas en el proceso de hardening de un servidor Web consiste en minimizar la cantidad de directorios donde el mismo tiene escritura. De esta forma se minimizan la cantidad de directorios donde un atacante pueda explotar una vulnerabilidad que le permita subir archivos (los cuales pueden ser shells, backdoors, etc.) Para ello, es necesario determinar todos los directorios donde el usuario bajo el que corre el demonio del servidor Web tiene acceso de escritura a nivel filesystem.

En este artículo presento un script Bash que realiza dicha tarea en servidores GNU/Linux. Tal vez los usuarios avanzados se preguntarán por qué no usar directamente find, el cual es capaz de examinar y testear los atributos de los archivos tales como permisos UNIX, usuario (UID) y grupo (GID). Esto estaría bien cuando se tiene un filesystem que utiliza los permisos UNIX tradicionales, pero si utilizamos ACLs, find se queda "corto", ya que no posee la funcionalidad necesaria para examinarlas.

Por ello tuve la necesidad de implementar un script Bash que busque directorios y luego ejecute getfacl sobre cada uno para examinar las listas de control de acceso.

#!/bin/bash
# listar_dirs_rw_apache.sh
# Script para listar directorios en los que un usuario posee permiso de escritura
# Desarrollado por Linuxito (http://linuxito.com)

if [ $# -lt 2 ]
then
    echo "uso: $0 <user> <basedir>"
    exit -1
fi

# Directorio desde donde comenzar la búsqueda, pasado como parámetro
BASEDIR=$2

# Usuario con el que corre Apache, pasado como parámetro
$USER=$1

echo "Listado de directorios donde Apache tiene escritura:"
echo "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"

# Buscar directorios
IFS="$(printf '\n\t')"
for DIR in $(find $BASEDIR -type d)
do
    # Determinar si "$USER" u "other" tiene escritura sobre el directorio
    RW=$(getfacl $DIR 2>/dev/null | grep "$USER\|other" | grep "rw" | wc -l)
    # RW > 0 --> $USER y/o other tienen escritura
    # RW = 0 --> ni $USER ni other tienen escritura
    if [[ $RW -gt 0 ]]
    then
        #echo $DIR [SI]
        echo $DIR
    else
        echo $DIR [NO] > /dev/null
    fi
done

 

Ahora bien, este script funciona perfectamente independientemente si los directorios tienen o no ACLs. Esto se debe a que si se utiliza la herramienta getfacl sobre un directorio o filesystem que no soporta ACLs, getfacl muestra los permisos de acceso definidos por los bits de modo tradicionales de UNIX.

Para mayor información consultar la página de manual de getfacl.

El script toma dos parámetros, el primero indica el nombre de usuario con el que corre el servidor Web y el segundo un directorio base desde donde comenzar la búsqueda. En mi caso se trata de un servidor Apache, por lo tanto el usuario con el que corre es "www-data" si es un servidor Debian y "httpd" si es un servidor CentOS.

Al trabajar de esta forma, el script queda bastante genérico, lo que implica que sirve para buscar permisos de escritura para cualquier usuario en cualquier rama de directorio. Por lo tanto tiene usos múltiples, no sólo sirve para hacer un hardening de un filesystem donde trabaja un servidor Web Apache.

Ejemplo de ejecución del script:

[admin@www ~]$ ./listar_dirs_rw_apache.sh www-data /var/www
Listado de directorios donde Apache tiene escritura:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/var/www/linuxito/httpdocs/uploads
/var/www/linuxito/httpdocs/tmp
/var/www/linuxito/httpdocs/filemanager/images
/var/www/linuxito/httpdocs/admin/logfiles
/var/www/linuxito/httpdocs/useruploads
/var/www/testing/public_html/logs
/var/www/testing/tmp
/var/www/testing/tmp/sitio/admin
/var/www/testing/tmp/logs
/var/www/testing/logs

¡Espero que les sea útil!


Tal vez pueda interesarte


Compartí este artículo