martes, 30 de junio de 2009

Redifiniendo directivas PHP: .htaccess

Saludos!!

Bueeeeeeeeno, hace mucho tiempo que no me podía pasar por el blog. El caso es que estuve con los exámenes y demas parafernália universitarias que paso de comentar. Ahora mismo he vuelto a mi rutina noctámbula delante del ordenador, con una línea magnífica de 24kbps. Por suerte esta situación "precaria" en cuanto a internet sólo durará hasta Septiembre, cuando vuelva al mundo normal AKA Salamanca.

Pero bueno, veo que mis compañeros de aventuras en el blog han continuado posteando para que esto no muriera, tarea muy loable. Hoy vengo con la típica energía y entusiasmo que da el iniciar las vacaciones, así que vamos a aprovecharla para hablar de un tema interesante que ya se tocó muy por encima en el post sobre servidores: modificar directivas para tener más "margen de movimiento".


Para empezar, debemos de comprender que el comportamiento de los scripts PHP que corremos en un servidor están basados en una configuración preestablecida, indicada en el archivo php.ini. Este archivo contiene lo que a partir de ahora denominaremos como directivas, que son las instrucciones que marcarán las pautas de comportamiento de PHP, incluyendo limitaciones (que básicamente es la parte que a nosotros nos interesa). Estas directivas están compuestas por una clave y un valor para dicha clave.


Las directivas que más nos van a ir interesando (por que tal vez nos puedan tocar un tanto las narices) van a ser safe_mode, Magic_Quotes, open_basedir, disable_functions...

Safe_Mode, como su propio nombre indica, activa el "Modo Seguro" de PHP, bloqueando ciertas funciones. Sus posibles valores son On y Off. Despues tenemos magic_quotes_[gpc/runtime/sybase], directiva desaconsejada por la mayoría de webmaster, (aunque a la hora de las SQLi es un impedimento desalentador en muchos casos) y básicamente funciona añadiendo una barra invertida (o una comilla simple) a a los caracteres /, ','' y NULL. De esta forma se pretende impedir las inyecciones... Al igual que safe_mode, sus valores son On y OFF.

Por otro lado tenemos Open_basedir, cuya utilidad es determinar un área de trabajo de PHP, e impedir al ejecución de funciones en puntos más altos del árbol de directorios (más adelante lo explico de forma sencilla). Por último, explicar una de las directivas más restrictivas de cara a una intrusión: disable_functions. Esta directiva se encarga de inhabilitar aquellas funciones que le indiquemos. Hay que aclarar que presenta independencia con respecto a Safe_Mode.


Todas estas directivas suelen emplearse en servidores de hosting que emplean para diferentes webs un mismo servidor. Para impedir que los usuarios intervengan (de forma maliciosa o por error) en el espacio de otros, ya sea en los archivos, configuraciones, directorios, etc. Por ejemplo, mediante open_basedir, podemos impedir que desde el espacio empleado por el usuario A pueda ejecutar algún script/programa que pueda afectar a un usuario B.


Vale, sé que esta introducción es un tanto básica y que se conoce, pero así espero que la gente pueda comprender todo desde 0. Así que continuemos. Estas directivas pueden ser modificadas desde diferentes puntos, siendo éste uno de los objetivos primoridales cuando obtenemos acceso a un servidor, puesto que lo primero es poder tener cierto margen de maniobrabilidad para poder avanzar en nuestra intrusión. Pero claro, no todas las directivas pueden ser modificable de "tantas formas". Existe una pequeña clasificación de las directivas.

La modificabilidad de las directivas viene definida por las constantes PHP_INI_USER,PHP_INI_PERDIR , PHP_INI_SYSTEM y PHP_INI_ALL.

Bien, aquellas directivas PHP_INI_USER, pueden ser modificadas desde un script por parte del usuario (usando la función ini_set(), por ejemplo); PHP_INI_PERDIR desde .htaccess, httpd.conf y desde el propio php.ini; PHP_INI_SYSTEM desde php.ini o httpd.conf; PHP_INI_ALL desde cualquier lugar. Para conocer a qué categoría pertenecen las directivas, clickad aquí (PHP-ES.COM). Existe otro tipo de directivas, entre las que se encuentra disable_functions, que únicamente son modfiicable a través de php.ini.



Algunas directivas pueden ser modificables a través del archivo .htaccess. Para ello, tenemos dos opciones y son a través de php_flag y php_value. Si creamos un archivo .htaccess en el servidor en el que estamos, podemos redefinir aquellas directivas cuyos posibles valores sean on u off usando php_flag:

php_flag magic_quotes_gpc on

Y cuando existe polivalencia para la instrucción, empleamos php_value. Si lo que deseamos es eliminar algún valor, utilizaremos none.

El hecho de poder crear un .htaccess que redifina las directivas (principalmente las de seguridad) es algo muy sencillo de hacer y que nos puede ayudar en muchas ocasiones.

La configuración, viene dada por el archivo php.ini (como ya dijimos en un principio), y por los archivos .htaccess (y httpd.conf). Si tenemos un .htacces redifiniendo directivas en la raíz, a la hora de decidir cuál se van a emplear ( si que aparecen indicadas en php.ini o por el contrario las que aparecen en .htacces), la balanza se va a del lado del .htaccess. Además, en esto de las preferencias, interviene un detalle crucial y que es, en síntesis, aquél por el cual podemos emplear este método a modo de "bypass" de restricciones, y es la heredabilidad.

Cuando hablamos de la heredabilidad de .htacces, hacemos referencia a que si hay un archivo de este tipo en un directorio, y existe otro en la raíz, las indicaciones presente en el archivo existente en el propio directorio donde se está ejecutando el script PHP seran aquellas que se tengan en cuenta.


Espero que este artículo se entienda más o menos (si existe algún error comunicadmelo). La verdad es que .htaccess es una herramienta muy útil, y que se le está dando bastante uso: desde asociar scripts PHP a extensiones tipo jpeg, gif, etc, hasta bypassear mod_security.

Byt3z
5 0verl0ad Labs: junio 2009 Saludos!! Bueeeeeeeeno, hace mucho tiempo que no me podía pasar por el blog. El caso es que estuve con los exámenes y demas parafernália ...

martes, 9 de junio de 2009

Blog System v1.5 - XSS por post

Name: Blog System v1.5
Vuln: XSS
Web: http://www.netartmedia.net/blogsystem/
Dork: WTF!
Author: >> s E t H <<
My blog: http://0verl0ad.blogspot.com/
Email: seth /A\ el-hacker /D\ org

Ver exploit
Para probar, pueden apuntar el form a http://www.blog23.com/index.php
5 0verl0ad Labs: junio 2009 Name: Blog System v1.5 Vuln: XSS Web: http://www.netartmedia.net/blogsystem/ Dork: WTF! Author: >> s E t H << My b...

jueves, 4 de junio de 2009

ServerInfo 0.1

Es un poco molesto estar conectando con netcat y mandando heads y options cada vez que queres ver los headers de un servidor web, asi que hice este script muy sencillo que te muestra esa información.
Pueden bajarlo de acá y acá.

una demostracion de lo que hace y como se usa:
seth@debian:~$ chmod +x sinfo.sh
seth@debian:~$ ./sinfo.sh microsoft.com OPTIONS
********************************
* ServerInfo 0.1 *
* http://0verl0ad.blogspot.com *
* seth /A\ el-hacker.org *
********************************
Uso: ./sinfo.sh host [GET|HEAD|OPTIONS]


Allow: OPTIONS, TRACE, GET, HEAD
Server: Microsoft-IIS/6.0
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
X-UA-Compatible: IE=EmulateIE7
Date: Wed, 03 Jun 2009 23:18:58 GMT
seth@debian:~$ ./sinfo.sh www.google.com.ar HEAD
********************************
* ServerInfo 0.1 *
* http://0verl0ad.blogspot.com *
* seth /A\ el-hacker.org *
********************************
Uso: ./sinfo.sh host [GET|HEAD|OPTIONS]


Date: Wed, 03 Jun 2009 23:19:05 GMT
Server: gws
seth@debian:~$ ./sinfo.sh foro.undersecurity.net GET
********************************
* ServerInfo 0.1 *
* http://0verl0ad.blogspot.com *
* seth /A\ el-hacker.org *
********************************
Uso: ./sinfo.sh host [GET|HEAD|OPTIONS]


Date: Wed, 03 Jun 2009 23:19:17 GMT
Server: Apache/1.3.37 (Unix) mod_throttle/3.1.2 FrontPage/5.0.2.2635 mod_psoft_traffic/0.2 mod_ssl/2.8.28 OpenSSL/0.9.8b
X-Powered-By: PHP/5.2.6
seth@debian:~$ ./sinfo.sh foro.undersecurity.net OPTIONS
********************************
* ServerInfo 0.1 *
* http://0verl0ad.blogspot.com *
* seth /A\ el-hacker.org *
********************************
Uso: ./sinfo.sh host [GET|HEAD|OPTIONS]


Date: Wed, 03 Jun 2009 23:19:27 GMT
Server: Apache/1.3.37 (Unix) mod_throttle/3.1.2 FrontPage/5.0.2.2635 mod_psoft_traffic/0.2 mod_ssl/2.8.28 OpenSSL/0.9.8b
Location: http://www.google.com/search?q=Como%20puedo%20ser%201337%20h4x0r?!?!!1
seth@debian:~$ ./sinfo.sh foro.portalhacker.net OPTIONS
********************************
* ServerInfo 0.1 *
* http://0verl0ad.blogspot.com *
* seth /A\ el-hacker.org *
********************************
Uso: ./sinfo.sh host [GET|HEAD|OPTIONS]


Date: Wed, 03 Jun 2009 23:19:47 GMT
Server: Apache/1.3.41 (Unix) mod_log_bytes/1.2 mod_bwlimited/1.4 mod_auth_passthrough/1.8 FrontPage/5.0.2.2635 mod_ssl/2.8.31 OpenSSL/0.9.8b
Allow: GET, HEAD, OPTIONS, TRACE
seth@debian:~$

Lo que hace es mandar una petición http (con pocas cabeceras, se puede agregar mas para que parezca de un usuario normal) usándo los métodos GET, OPTIONS o HEAD y muestra lo mas interesante de la respuesta.

C1c4Tr1Z (Blog) me respondió con una version mucho mas corta usando curl (tiene cosas a favor y en contra):

Te recomendaría usar curl:
Language: Bash
c1c4tr1z(bash) % ~ $ data=( localhost OPTIONS );curl -X "${data[1]}" -H "Host: ${data[0]}" -I -A "one-user-agent/1.1.1.1" ${data[0]}
HTTP/1.1 200 OK
Date: Thu, 04 Jun 2009 00:40:53 GMT
Server: Apache
Allow: GET,HEAD,POST,OPTIONS,TRACE
Content-Length: 0
Content-Type: httpd/unix-directory

Pero despues se podría hacer mas especifico con awk , por ejemplo, para checkear si nos responde con un código 200 (OK):
Language: Bash
c1c4tr1z(bash) % ~ $ data=( localhost OPTIONS );curl -X "${data[1]}" -H "Host: ${data[0]}" -I -A "one-user-agent/1.1.1.1" ${data[0]} | awk '
BEGIN{a=0}
$1~/^HTTP\/1\.[0-1]$/{if($2=="200"){a=1}}
{if(a==1){print$0}}'

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
HTTP/1.1 200 OK
Date: Thu, 04 Jun 2009 00:51:38 GMT
Server: Apache
Allow: GET,HEAD,POST,OPTIONS,TRACE
Content-Length: 0
Content-Type: httpd/unix-directory

c1c4tr1z(bash) % ~ $ data=( localhost/no-existe/ OPTIONS );curl -X "${data[1]}" -H "Host: ${data[0]}" -I -A "one-user-agent/1.1.1.1" ${data[0]} | awk '
BEGIN{a=0}
$1~/^HTTP\/1\.[0-1]$/{if($2=="200"){a=1}}
{if(a==1){print$0}}'

% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 296 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
c1c4tr1z(bash) % ~ $
Entonces, si el código HTTP devuelto es 200 (OK) el valor de a, que comienza siendo 0, va a ser 1 lo que haría que awk de como output todo el resultado de la cabecera.
Si querés mas información del tema:
HTTP/1.1: Header Field Definitions
Posts sobre http en el blog

No necesito que me digan que no soy bueno en bash, pero acepto sugerencias, mejoras, opiniones, etc.
5 0verl0ad Labs: junio 2009 Es un poco molesto estar conectando con netcat y mandando heads y options cada vez que queres ver los headers de un servidor web, asi que hi...
< >