Blog gratis
Reportar
Editar
¡Crea tu blog!
Compartir
¡Sorpréndeme!
Blog de la Escuela de Educación Secundaria Técnica N 8 de Quilmes
Administrador Prof. Claudio Enrique Alonso Alvite
img
13 de Noviembre, 2014    General

Cifrando los logs de Apache con libCryptoLog

En muchas ocasiones sucede que es necesario tener una política de cifrado de logs y no siempre es fácil 'convencer' a los servidores para que guarden la información cifrada.

Para abordar ese tipo de escenarios he liberado la versión 0.1 (mini-beta?) de libCryptoLog que permite manipular 'al vuelo' la forma en la que cualquier servidor guarda los logs. Y digo cualquiera porque en realidad, si bien este post va de Apache, el método que voy a explicar sirve para cualquier otro servicio (Postfix, Nginx ...).

De lo que se trata es de 'convencer' al servidor en cuestión de que toda información que vuelque al fichero que nos interese cifrar se almacene cifrada desde el minuto 0.

Después de pensar y re-pensar una forma que me convenciese para abordar este problema, programé libCryptoLog con la idea de que fuese 'plugeable', es decir, en vez de hardcodear en la librería las rutinas de cifrado, he decidido que eso caiga en un 'helper' externo para que cualquiera pueda adaptarlo fácilmente a sus requerimientos.

El funcionamiento es fácil: Por lo general, cuando Apache o cualquier otro servidor van a escribir a disco, suelen emplear dos funciones: fprintf() o write(), en el caso de Apache el 'meollo' está en write().

Como muchos de vosotros en este punto ya habréis deducido, lo que estoy haciendo es 'hookear' ambas funciones y alterar la forma en la que procesan los datos que van a almacenar a fichero.

El procedimiento es muy fácil de entender:

1- fprintf() y write() toman una cadena y la vuelcan a un fichero

2- libCryptoLog intercepta esas llamadas y extrae la cadena de texto

3- Esa cadena de texto se le pasa a un programa externo para que la cifre, le ponga colores o lo que sea

4- libCryptoLog toma el resultado de ese programa y ES ESO lo que almacena empleando fprintf o write

De esa forma los logs, antes de que 'toquen disco' ya están cifrados.

Este modelo permite que cualquiera, en cualquier lenguaje, programe sus propios helpers para decidir como transformar la cadena de texto. Junto con la librería van unos cuantos helpers para cifrar logs con RSA.

Vamos a ver un ejemplo con Apache en Centos 6.5:

Lo primero es descargar la librería desde aquí y descomprimirla con:

# tar -xvzf libCryptoLog.tgz

Para usar los helpers escritos en Perl, es necesario tener disponible la librería perl-Crypt-RSA, la instalamos

# yum -y install perl-Crypt-RSA

Una vez instalada, ya podemos generar nuestras claves publica y privada, es MUY CONVENIENTE que la clave privada no esté en el sitio donde vamos a cifrar por razones más que obvias. Esa clave es la llave para acceder al contenido de los logs por lo que se ha de guardar en un sitio externo donde se vayan a descifrar los logs.

Ejecutando:

# perl rsacreate.pl

Vemos que en el directorio han aparecido dos nuevos ficheros: key.public y key.private

Copiamos key.public a /usr/local/etc/

# cp key.public /usr/local/etc/

Igualmente copiamos el 'helper' a /usr/local/bin

# cp rsacrypt.pl /usr/local/bin/

Este es el script que se encargará de cifrar los logs 'al vuelo' usando la clave pública.

Con esto hecho, toca compilar la librería. Aquí hay una parte que se debe configurar. La función write() toma un ID como parámetro para saber en que descriptor debe escribir. No se puede manipular todas las llamadas a write() porque esa función se usa para muchas cosas, es necesario determinar los IDs que corresponden a los ficheros que vamos a cifrar.

Para obtener esta información debemos buscar un PID de Apache y consultar con lsof los IDs de los ficheros que tiene abiertos.

# ps aux | grep -i httpd

root      1508  0.0  1.6 135832 17328 ?        Ss   09:26   0:00 /usr/sbin/httpd
apache    1540  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1541  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1542  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1543  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1544  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1545  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1546  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd
apache    1547  0.0  0.6 135832  6932 ?        S    09:26   0:00 /usr/sbin/httpd

Y luego

# lsof -p 1508

httpd   1508 root    0r   CHR    1,3      0t0   3903 /dev/null
httpd   1508 root    1w   CHR    1,3      0t0   3903 /dev/null
httpd   1508 root    2w   REG  253,0     3522 398650 /var/log/httpd/error_log
httpd   1508 root    3r   CHR    1,9      0t0   3908 /dev/urandom
httpd   1508 root    4u  sock    0,6      0t0  10395 can't identify protocol
httpd   1508 root    5u  IPv6  10396      0t0    TCP *:http (LISTEN)
httpd   1508 root    6r  FIFO    0,8      0t0  10489 pipe
httpd   1508 root    7w  FIFO    0,8      0t0  10489 pipe
httpd   1508 root    8w   REG  253,0   265970 398649 /var/log/httpd/access_log

Justo al final podemos ver qué /var/log/httpd/error_log y
/var/log/httpd/access_log tienen asociados los IDs 2 y 8. Esto se puede ver en la cuarta columna en formato numero+w, en este caso 2w y 8w

Como solo queremos que estos dos ficheros queden cifrados (son los que guardan la información sensible ...) editamos el fichero libCryptoLog.c y en la parte de:

int filedesyes[2] = {3, 10};

La cambiamos a 

int filedesyes[2] = {2, 8};

Para que la librería sepa cuales llamadas a write debe modificar y cuales simplemente las debe dejar pasar sin hacer nada.

Una vez hecho eso, compilamos:

# gcc -Wall -fPIC -shared -o libCryptoLog.so libCryptoLog.c -ldl -lssl

Y copiamos nuestra flamante nueva librería en /usr/local/lib

# cp libCryptoLog.so /usr/local/lib/

¡¡ Ya casi casi estamos !!

Ahora, para que se produzca el 'hooking' tenemos que instruir al fichero de arranque de Apache para que defina la variable LD_PRELOAD correctamente en los procesos que genere.

# vi /etc/init.d/httpd

En la parte de start localizamos algo como

start() {
        echo -n $"Starting $prog: "
        LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}

Y debemos modificarla para que quede algo así (he puesto en negrita lo que he añadido)

start() {
        echo -n $"Starting $prog: "
        LD_PRELOAD=/usr/local/lib/libCryptoLog.so LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}

Y si todo ha ido bien, en cuanto hagamos un stop / start nuestros ficheros de log pasarían a quedar cifrados.

# service httpd stop
# service httpd start

Si hacemos un tail a /var/log/http/error.log ya podemos ver que Apache está guardando la información cifrada:

BEGINCRYPTO
gRNmfi/yS9Vaya37VJ7sM+iZtoYDG976SWPa4XTLnPGccBTd56J8Bk0uLZyK86vopcjdKp2JPDr7
oHWk/TKA00IStIgvTofUH9DeZGepqikIkjJg9wylAJ0ROjpcerozOX1LQWuj+ZoOxRu7K+UIeQmc
389SjDAyqNs/U8UHc75ntbVHy/A1e95fWUAHnkcD/1au463ugNHQmCJoSHA4NgwhDmwUJLafWSKr
T/L6BaOsruxDtkUqu0gBfROadVuc9oALSdRSc5WqA3T5HuS10a49szZ5zedqtQJiQFjikJCRo/v6
tzYHHs3Es+8yfpZti/l3pChW8+zHCxuPRKNccg==
ENDCRYPTO
BEGINCRYPTO
VB68V3MyG7yNHfYc8UR69ZbaC4ztBkOigWnKZzlKTMiXNdSBFEJ++TPKQXUFo4j8AfrgQPL6DQQ8
nd0yoMSaA3ojq+MvBY5cSLstVeEGaIJSXRboZMGyq6UpfOAqvWLvd48w63ND9cKKDBkEQcfUM3a7
S5KPss/qqSKYcsSHsqk=
ENDCRYPTO
BEGINCRYPTO
DN0d0oa8DJrVj7GGuiGUuhRMc8bDIPGUL39Ae51YFwZl1mRoq5EgipcTxyPThTngw7rOobUGrCaS
YY/MlO4FV4HGAsBWsQksfqYzsgbC7Lv+Ek4oe+01rhJ2L70BKPWPiRdr9oQHsWcL8aTDtLj8X/H4
R3XJ76mvNUSOPAPjijE2WZiAIRYmU+0fzTrbJTYaV3GrGYm2rWkoFQu7aImQHqWRsnSs9k9RmLij
3KoX/MpBBd+a0hOhBsZQmLf915VJgp5E2zrqXMwutdyS3+UJ7o+lesK8LfC2jl40aYvVZXZXNPv+
uDsNbkPJIRzXpfmwnR5KtMFcNOdEJ+1378BRrQ==
ENDCRYPTO

 
Ahora queda la parte final ¿y como revierto el cifrado para tener el log original? Para eso, hay un script llamado rsadecrypt.pl que toma como parámetro un fichero entrada y otro salida, en este caso entrada sería error.log y salida error2.log, quedando en este último el formato descifrado.

# perl rsadecrypt.pl /var/log/httpd/error_log error2.log

Si hacemos un tail en error2.log

[Fri Jun 06 09:55:34 2014] [notice] suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Fri Jun 06 09:55:34 2014] [notice] Digest: generating secret for digest authentication ...
[Fri Jun 06 09:55:34 2014] [notice] Digest: done
[Fri Jun 06 09:55:34 2014] [notice] Apache/2.2.15 (Unix) DAV/2 PHP/5.3.3 mod_perl/2.0.4 Perl/v5.10.1 configured -- resuming normal operations

Vemos que lo que antes era base64 cifrada, ahora es plain text :)

Evidentemente no todo es gratis, el añadir este 'extra' de cifrado penaliza bastante el rendimiento porque las operaciones RSA son 'pesadas' y además desde un script aun más. 

Hay que tener mucho cuidado en qué servidores se activa esta medida de seguridad y si tienen la capacidad adecuada para soportar el cambio.

Como última cosa, reiterar que en este ejemplo se están usando mis scripts para tratar los logs, en el código de la librería se puede ver el comando definido 

char *command = "perl /usr/local/bin/rsacrypt.pl "";

Pero ahí puede ir cualquier cosa que trate el texto de los logs.

Autor: Yago Jesus
Palabras claves , , , ,
publicado por alonsoclaudio a las 21:46 · Sin comentarios  ·  Recomendar
 
Más sobre este tema ·  Participar
Comentarios (0) ·  Enviar comentario
Enviar comentario

Nombre:

E-Mail (no será publicado):

Sitio Web (opcional):

Recordar mis datos.
Escriba el código que visualiza en la imagen Escriba el código [Regenerar]:
Formato de texto permitido: <b>Negrita</b>, <i>Cursiva</i>, <u>Subrayado</u>,
<li>· Lista</li>
CALENDARIO
Ver mes anterior Marzo 2024 Ver mes siguiente
DOLUMAMIJUVISA
12
3456789
10111213141516
17181920212223
24252627282930
31
BUSCADOR
Blog   Web
TÓPICOS
» General (2606)
NUBE DE TAGS  [?]
SECCIONES
» Inicio
ENLACES
MÁS LEÍDOS
» Analizando el LiveBox 2.1 de Orange
» Cómo espiar WhatsApp
» Cómo usar Metashield protector for Client y por qué utilizarlo
» Detectando tráfico de conexiones HTTP inversas de Meterpreter (Snort)
» Ejecución remota de código arbitrario en OpenSSH
» Ganar dinero con 1.200 Millones de identidades robadas
» Hardware y sus 4 Funcionamientos Basicos y Principales en una Computadora
» Redes de la Deep Web: CJDNS y la Red Hyperboria
» Unidad Central de Procesamiento CPU
» Wassap, la aplicación que permite usar WhatsApp desde la PC
SE COMENTA...
» Cómo espiar WhatsApp
595 Comentarios: Scott, Scott, Jarlinson mercy, [...] ...
» Qué hacer ante el robo de un teléfono móvil o una tableta
2 Comentarios: best buy security cameras swann, best buy security cameras swann
» Espiando usuarios gracias a la vulnerabilidad en cámaras TRENDnet
1 Comentario: Coin
» Recopilatorio de aplicaciones y sistemas vulnerables para practicar
2 Comentarios: vera rodrigez ...
» SoftPerfect WiFi Guard permite saber quién esta conectado a mi WiFi
2 Comentarios: firdous ...
SOBRE MÍ
FOTO

Prof. Claudio Enrique Alonso Alvite



» Ver perfil

AL MARGEN
Escuela de Educacion Secundaria Tecnica N 8 de Quilmes
(Técnicos en Informática Personal y Profesional)
FULLServices Network | Blogger | Privacidad