martes, 28 de febrero de 2017

Having fun with symlinks in Hostinger


Since my last blog post I have been looking for new vulnerabilities in Hostinger in my spare time (I have not had too much :P).

In this blog post I will speak about two vulnerabilities I found in Hostinger. Both are exploited by using symbolic links.
As you know, symbolic links (symlinks) are files which points to another files, I mean, you can create a symbolic link called “hello” which points to “/etc/passwd”. So, when you try to write in “hello” you are writing to “/etc/passwd”.

In order to create a symlink in the server I used the “Import Site” feature. It allows to the user to upload a Zip file and it automatically decompress the file in “public_html” directory. I created a symlink in my computer using the command: ln -s /path/to/file symlinkname
And then, I added the symlink to a Zip file using: zip -y symlinkname.

The first vulnerability is related to a bad configuration in the server. By using symlinks we are able to read other files in the server, outside of our user home directory (remember that hostinger offers shared hosting plans; multiple users share the same server but using different Linux users with different permissions). We were able to create a symlink to “/“ and use it over FTP in order to browse the server files. One of the most important directories is “/backup”, which stores all the backup files in the server (other clients backups).
I tried to browse “/backup” over FTP, but my user did not have the permissions to do that :)
But, I created the symlink on the “public_html” directory, so I was able to browse the filesystem by using a web browser. Using a web browser I was able to read files that I did not have permission by using FTP, and “/bakcup” and all their files was one of the affected directories I was able to read if I used the web browser. It seems that the Apache user had privileges to read those files.

I reported this issue and Hostinger solved it. They also rewarded me with a bounty :)

After that, I thought that maybe there was a vulnerability which could allow me to write files I did not have permissions to write (like /etc/passwd or similar).

I used the PHP configuration file “/opt/php.conf.d/USER.ini”, where “USER” is the name of my user in the Linux server. In this configuration file, PHP functions such as “system”, “exec” or “shell_exec” were disabled for security reasons. My objective was to find a way to edit that file and enable these functions. To do that, I tried different tools available on the client area. But only one of them worked fine.

One of the functions allows to the user to set a password for a directory in the website. It is done by creating/writing a “.htpasswd” file in that folder and writing the password selected by the user. I was able to write any file in the server by using this feature.

In order to exploit it to write any file in the server, firstly, I created a symlink to the file I wanted to overwrite. The name of the symlink should be “.htpasswd”. And then, as you are thinking, you have to set a password for the directory by using the “Password Protect dirs” feature. This feature seems to execute as root, so it will write in the file pointed by the symlink without problems. After this tool writes on the file, it set proper permissions for the file, so the original file will be readable and writable by our user after that. 
We only have to access by FTP or create a PHP script in order to write whatever we want to the file. 

I reported this vulnerability and they rewarded me with a bounty :)

If you want to read more about vulnerabilities on shared hosting servers based on symlinks, you can read this blog post written by @alvaroh5 in fwhibbit: 

sábado, 11 de febrero de 2017

Command Injection Vulnerability in Hostinger


This is my first blog post in English, and probably next blog posts will be written in English too :)

Today I am going to speak about a vulnerability I recently found in Hostinger. As the title says, I found a Command Injection vulneravility in Hostinger. This kind of vulnerabilities allow an attacker to execute remote OS commands on the machine.

I realized that Hostinger has a GIT repository feature which allows you clone a GIT repo and deploy your website using that repo. And yes, here we find the vulnerability. As you should know, you can clone a repository using the following command:

git clone http://domain/path/to/repo folder

Their feature uses this command in order to clone the repo, they allow you to provide 3 elements:

- Repo URL
- Repo branch to be cloned
- folder in which the repo will be cloned

An attacker was able to use the "folder" input to inject OS commands. By using ";" we were able to close the "git clone" command and inject other commands to be executed. In the following picture you can see the UI of the feature in the Hostinger CPanel, which will break the "git clone" command to finally execute "wget".

I used "wget" to see if the command was being executed by receiving the GET request in Then I realized that you can see a log output of the deployment and you can see the output of the command execution on it (see picture 2).

As you can see in the picture, we have a command execution with root permissions... No need to use any other exploit to obtain root permissions. An attacker have all he need in order to use Hostinger server, for example to do DDoS attacks. Or maybe to delete all the data of other clients in the same server (remember that Hostinger is a shared web hosting service ;))

The vulnerability was reported to Hostinger and fixed in less than 48 hours (good job).
Anyway, I have to say that I did not received any response to my report, so once I realized that the vulnerability was fixed, I wrote another email to ask if the vulnerability was finally fixed and if my vulnerability was elegible for a reward (supposedly they have a bug bounty reward program:

Finally I received a response, they appreciate my help but they said "after analyzing the impact of it and we confirmed that a bonus cannot be provided this time."

So they analyzed the impact of the vulnerability and is not elegible for a reward, OK. I understand that they are the ones who must decide if a vulnerability is or not elegible for a reward, and I accept their decision. But if a vulnerability which allows a malicious user take total control of their servers with root permissions to do whatever he want with the server and the clients data is not elegible for a reward, I don’t know what kind of vulnerability could be more dangerous in order to be elegible for a reward.

If you have reported some vulnerability to Hostinger, tell us your experience on the comments!

I hope you like this blog post! :)
I will try to write more frequently here, because I have not written a blog post since September 2016 :S

You can also follow me on Twitter:

UPDATE (13-02-2017):

Today the Customer Success manager at Hostinger has written an email saying he has reviewed my case. He has explained why they did not provide a reward for the bug. The git command was running in a Docker container which is created in order to do the deploy and destroyed after that. Even so, they have finally rewarded me with a bounty because they had to fix other issue to prevent additional errors.

Hostinger, thank you very much for the reward! :)

And thanks to all who have read and shared this blog post!

lunes, 12 de septiembre de 2016

¿Como actualizar un Gear S2 sin un dispositivo Android compatible?

La respuesta corta es: por cojones.

Antes de nada, decir que después de tanto tiempo sin escribir en el blog, me apetecía contar esto, aunque técnicamente no es demasiado complicado. Quizás a partir de ahora escriba con más frecuencia, ya que, al menos, tengo pensada otra entrada más sobre Yomvi (el nuevo Movistar+).

Empecemos con esta entrada!

Hace unas semanas Samsung lanzó su aplicación de administración de su smartwatch, el Gear S2, para iOS. Hacía mucho tiempo que la estaba esperando, así que en cuanto me enteré de que habían lanzado el programa de pruebas, me registré para probarla. Después de ser aceptado e instalar la aplicación, estuve durante un rato intentado sin éxito conectar mi reloj a la aplicación. Entonces, buscando por internet, me di cuenta de que la versión del firmware de mi reloj era demasiado antigua, tan antigua que no era posible actualizarlo por Wifi. Al parecer, el único modo de actualizarlo era utilizando la aplicación de Android, ya que al ser una versión antigua de firmware, esta no era compatible con la app de iOS.

En este punto, surgen los problemas, ya que no dispongo de ningún dispositivo "compatible" con la aplicación. Los requisitos de la aplicación son:

  1. Tener una versión de Android mayor o igual a la 4.4
  2. Tener un dispositivo con al menos 1.5GB de RAM

Podéis ver aquí una lista con los dispositivos compatibles.

Como podemos observar, hay una gran cantidad de dispositivos compatibles (notese la ironía).

Bien, como os imaginais, no tengo un dispositivo "compatible", pero si que dispongo de un Xperia M2, que estaba seguro que era igualmente suficiente para utilizar la app.

Visto lo visto, estaba claro que si quería actualizar mi reloj y que sirviese para algo tenía que buscarme la vida por mi cuenta, y eso hice. Lo primero que se me ocurrió fue obtener el APK de la aplicación. Ya que tenía la app instalada, la obtuve de mi dispositivo utilizando ADB. Los comandos necesario para ello son:

adb shell pm list packages

Con el obtendremos la lista de paquetes instalados en nuestro dispositivo. Podemos mejorar el comando si utilizamos: adb shell pm list packages | grep samsung. De esta forma nos aparecerá directamente el paquete que nos interesa, cuyo nombre es:

El siguiente comando: 

adb shell pm path

Que nos devolverá la ruta de nuestro dispositivo en la que podemos encontrar el APK.

Y finalmente usaremos:

adb pull ./destino

Para descargar el APK en la carpeta "destino".

Con esto, ya tendremos en nuestro PC el APK de la aplicación. El siguiente paso es utilizar una herramienta para descompilar el APK y obtener los ficheros de código Smali. Para ello, yo he utilizado apktool, en su versión 2.0.3 (podéis descargar su última versión en: Para descompilar simplemente es necesario utilizar el siguiente comando:

java -jar apktool.jar d

Una vez ejecutado, nos generará una carpeta con todos los recursos de la aplicación, incluyendo lo que nos interesa, el código Smali. 

Después de un rato mirando el código, nos daremos cuenta que existe una clase llamada "HostManagerUtils", que contiene un método que parece interesante: isSupportedInHostDevice. Efectivamente, este método devuelve true o false (1 ó 0) en función de si el dispositivo es compatible o no, es decir, si cumple los requisitos anteriormente indicados. 

Llegados a este punto, existen dos opciones en función de las posibilidades de vuestro dispositivo:

  1. Si está rooteado, utilizar alguna herramienta que permita hookear funciones, de modo que podamos modificar durante la ejecución el resultado de esta función. En mi caso he utilizado Frida (
  2. Si no está rooteado, modificar el código Smali para que siempre devuelva verdadero.

Yo utilicé Frida, puesto que mi dispositivo estaba rooteado y es más rápido que compilar la aplicación e instalarla, sobretodo la primera vez, cuando lo que queremos es comprobar si realmente esa función hace lo que parece. El script de Frida que he utilizado lo dejo aquí. Podéis utilizar la documentación de Frida para ver como se instala y como utilizar Frida en vuestro dispositivo (

Para la segunda opción, necesitaremos modificar el código, compilar e instalar de nuevo la aplicación. Como podemos observar en el código de la función "isSupportedInHostDevice", esta es bastante extensa, puesto que comprueba la cantidad de RAM y versión del sistema operativo. Nuestra modificación será realmente simple, al comienzo devolveremos directamente verdadero, y ya está.

Como vemos en la imagen, al inicio he modificado la inicialización de v0, para que en lugar de inicializarse a 0 (false) se inicialice a 1 (true), e inmediatamente después devuelvo v0. Con esto siempre se devuelve verdadero.

Ahora solamente resta compilar, firmar e instalar. Para compilar, utilizaremos de nuevo apktool, en este caso utilizaremos el comando (en el directorio en el que nos ha descompilado la app):

java -jar apktool.jar b -f -d .

Con esto nos construirá un nuevo APK en el directorio "dist". Antes de instalar ese APK, necesitaremos firmarlo. Para ello, usaremos la herramienta signapk (disponible aquí), con el siguiente comando:

signapk.jar testkey.x509.pem testkey.pk8 dist/ dist/

Como vemos, se pasan como parámetro los dos ficheros de clave para firmar el APK. Estos ficheros son los que lleva para probar signapk, recomiendo utilizarlos por simplicidad.

Con esto, tendremos un APK firmado y listo para usar. A continuación instalamos con el siguiente comando:

adb install dist/

Y una vez instalado tendremos la aplicación en nuestro dispositivo, lista para iniciar y actualizar nuestro reloj.

En mi caso, funcionó así sin problemas, pero existe una función llamada "isSamsungDeviceWithCustomBinary" que comprueba si la aplicación ha sido modificada. En principio no detecta esta modificación, pero por si acaso, se puede modificar de igual forma que hemos hecho con la que comprueba si el dispositivo es compatible. En este caso nos interesa que siempre devuelva 0 (false), que significa que la aplicación no ha sido modificada. Por tanto, introduciremos al comienzo de la función lo mismo que antes excepto el valor de v0, que será 0 en este caso:

const/4 v0, 0x0
return v0

Y después de todo esto, ya podremos utilizar nuestro Gear S2 con nuestro dispositivo Android.

ADVERTENCIA: No me hago responsable de cualquier daño sufrido por vuestro teléfono o reloj. Haz esto bajo tu propia responsabilidad.

No es nada complicado, ni muy técnico, pero me parecía interesante compartirlo, puesto que seguramente haya alguien al que le pueda resultar útil.

Con esto me despido hasta la próxima, que espero sea pronto y sea explicando algunas curiosidades de la app de Yomvi (ahora Movistar+) ;)

sábado, 10 de mayo de 2014

Vulnerabilidad Hostinger [0Day?]

Después de mucho tiempo sin escribir nada, hoy he sacado un hueco. Por que creo que lo que voy a contar hoy puede ser muy interesante.

Como bien dice el título, hoy vamos a hablar sobre Hostinger y una vulnerabilidad de seguridad (probablemente un 0day) presente en la mayoría de webs alojadas en este hosting.
La vulnerabilidad es muy fácil de aprovechar, de hecho, me parece un fail tremendo, una chapuza..

El caso es que mientras miraba un par de cosas en una web para pruebas que tengo en este hosting, me pregunté, ¿Como funciona el FileManager? Si habéis usado algún hosting, sabréis que permiten subir, modificar y borrar archivos desde una interfaz web, generalmente llamada FileManager o Administrador de Archivos en español.
El caso es que si nos fijamos en como funciona, podemos ver que no son más que peticiones GET o POST, pero, ¿a donde? Pues depende del FileManager que usemos.. Con Hostinger puedes usar dos FileManager distintos, si usas el que te ponen como principal, eres vulnerable, aunque solo lo hayas usado una vez. ¿Por que? Por que el filemanager se "instala" en tu carpeta de hosting web, como los archivos que subes para tu web.
Como podemos ver en la siguiente imagen, es una carpeta como cualquier otra en nuestro hosting (Imagen obtenida con el Filemanager 2)

Con esto, ya os imagináis como funciona el FileManager.. Básicamente se realizan peticiones a los scripts de esta carpeta para crear, modificar o borrar ficheros de nuestro hosting.
Lo bonito es que no hay ningún tipo de control sobre estas peticiones, es decir, no se usan cookies, ni nada que puedas imaginar para controlar que el que realiza la petición para gestinar el hosting sea realmente el dueño.

Algunas de las peticiones son:
Para abrir directorios:

Para ver contenido de archivos:

Para editar archivos:
Petición POST a: http://domain/_file-manager/php/connector.php
Con parámetros por POST:
content=<?php echo "Modifico!"; ?>

Las variables son bastante intuitivas, cmd es el comando, es decir, lo que quieres hacer (abrir, obtener o modificar). Por otro lado tenemos la variable content, que sirve para indicar el nuevo contenido del archivo que vamos a modificar. Y por último, target, que indica el archivo que vamos a modificar.
Target si tiene algo más de complicación, pues no es un path ni un nombre de archivo el valor que debe tomar, sino que es un hash. Cada archivo tendrá su hash y usaremos este para modificarlo o para abrir el directorio. ¿Como conseguimos el hash? Muy sencillo, el hash de la raiz todos los hostings es l1_Lw, y usando la petición con cmd=open, nos devuelve el listado de archivos con toda la información necesaria, incluido el hash. De este modo podemos ir listando cualquier directorio al mas puro estilo "ls" de Linux.

Y si necesitamos ver los archivos pues usamos cmd=get y listo.

Y por mi parte, creo que no es necesario explicar nada más. La vulnerabilidad, como pueden ver es muy simple.

Si tienen un hosting con hostinger pueden protegerse eliminando la carpeta de instalación del filemanager usando el segundo filemanager que tiene hostinger o usando algún software para acceder por FTP.

Espero que les haya gustado. Nos leemos!


viernes, 6 de septiembre de 2013

Facebook te regala una base de datos con los emails de tus amigos

Buenos días!
El otro día os enseñe como modificar la base de datos de triviados para ganar siempre en un dispositivo iOS.
Pues he seguido trasteando con otras apps, entre ella facebook. Y me he dado cuenta de que en la base de datos que guarda en nuestro dispositivo, guarda también los emails de nuestros amigos de facebook! Sí, los emails que usan para acceder a su cuenta!
Esto podría facilitar que se realizase phishing enviando un email..

Pero donde esta la base de datos? Como la obtengo? Si leiste la entrada de triviados ya sabrás como conseguir la base de datos de facebook de tu iPhone.

Por tanto, necesitaremos iTools 2013 para acceder a los archivos de las apps de nuestro dispositivo. Accedemos a los archivos de Facebook (como ya se dijo en el post de Triviados). Una vez dentro, la base de datos que nos interesa se encuentra en: "/Library/Caches". Y es el archivo llamado "fbsyncstore.db". Para poder abrirlo, ya sabéis, arrastramos al escritorio y lo abrimos con SQLite Manager (extensión de Firefox).

Una vez abierto, la tabla que nos interesa, es la llamada "contact_points". En esta tabla tenemos los emails de nuestros contactos e incluso los teléfonos móviles. Como podréis ver, en la  tabla no hay columna de nombre o apellidos, solo de ID, así que nos es fácil ver a quien pertenece cada email.. Pero tenemos una tabla llamada "people" que si tiene relacionados los IDs y los nombres y apellidos.. Así que con una simple consulta SQL podemos ver fácilmente a quien corresponde cada email. Esta consulta, por ejemplo:
SELECT first, last, value FROM contact_points E, people P where contact_point_id like '%contact_email%' and P.person_id=E.person_id

Y nos dará un resultado como este:

Y esto es todo! Me parecía curioso e interesante publicar esto :)

Espero les haya gustado!
Un saludo y hasta la próxima!

domingo, 1 de septiembre de 2013

Ganando SIEMPRE a Atriviate (Triviados) en iOS (iPhone/iPad/iPod)

Buenas tardes a todos! Después de tanto tiempo sin escribir nada, hoy os voy a enseñar como ganar siempre en Atriviate(Triviados) para iOS. Aunque puede aplicarse a cualquier las app de iOS.

Para hacer esto necesitaremos usar Windows, el programa para gestión de dispositivos iOS iTools 2013 y SQLite Manager (plugin para Firefox).

Lo primero es conectar por USB nuestro dispositivo iOS. Una vez conectado cerramos iTunes si se ha abierto e iniciamos el iTools.
En el menu de la izquierda nos vamos al apartado "Applications", y nos aparecera una lista con las apps que tenemos instaladas.

Buscamos Atriviate, hacemos click sobre ella y despues hacemos click sobre el boton "Browse".
A continuación se nos abre una ventana dentro del iTools con la carpeta en la que esta instalada la app. Debeis saber que las bases de datos que usan las apps están en "/Documents" y son archivos .sqlite. En esta entrada nos vamos a centrar en la base de datos, pero podéis mirar mas archivos de otros directorios según lo que busquéis (otro archivo interesante es el de preferencias, que se encuentra en "/Library/Preferences", es el único .plist que te dejará abrir)

Como se puede ver en la imagen, el archivo de base de datos que buscamos es "Model.sqlite". Ahora lo arrastramos al escritorio, para poder modificarlo con SQLite Manager. Para abrir la base de datos con SQLite Manager. Abrimos SQLite Manager y vamos a: "Archivo->Conectar Base de Datos" y abrimos el archivo Model.sqlite que guardamos en el escritorio. Ahora podemos ir viendo las tablas que forman la base de datos. Nos centraremos en la tabla "ZPREGUNTAS", en esta tabla se guardan todas las preguntas que se van solicitando al servidor. ¿Por qué? Porque la app funciona de manera que la primera vez que jugamos pide las preguntas de la categoría que nos ha tocado jugar, y este nos envía unas 20 preguntas de esa categoría. De este modo, las preguntas se guardan, y conforme se van contestando esas 20 preguntas se van eliminando, cuando no quedan mas se piden nuevas. Ya podéis ir intuyendo que es lo que vamos a hacer.. Si, lo que vamos a hacer es rellenar la tabla de preguntas con preguntas que tengan la misma respuesta como correcta. Pues como veis, en esta tabla se guarda el enunciado, las respuestas, la respuesta correcta (un numero del 1 al 4) y el id de pregunta en el servidor, entre otras cosas..
Ya sabéis lo que vamos a hacer, así que si no sabeis SQL lo mas sencillo es jugar una partida y obtener preguntas con ids validos.

Despues podéis cambiar la categoria haciendo doble click en la columna, para no tener que jugar todas las categorias de preguntas.

Una vez que tenemos al menos 1 pregunta de cada categoria(son 7 categorias, la columna categoria puede tomar valores del 1 al 7, dependiendo de la categoria), hacemos que todas las respuestas correctas sean la misma, por ejemplo, que todas sean la primera opción. Esto lo podemos hacer facilmente haciendo click en "Ejecutar SQL" y ejecutando lo siguiente:

Y damos en "Ejecutar SQL". Una vez hecho esto todas las preguntas que tengamos en la base de datos tendrán como opción correcta la primera respuesta.
Pero hay un problema.. Si tenemos pocas preguntas en la base de datos, en cuanto se acaben se pedirán mas al servidor ... :S
Por este motivo, debemos insertar mas preguntas "personalizadas". La manera mas sencilla es usar las que ya tenemos, para repetirlas en la base de datos. Así que simplemente usamos la siguiente instrucción SQL:

Lo que hace es simplemente insertar en la tabla preguntas, preguntas con esas columnas (las que van entre parentesis), usando las filas (preguntas) que ya existen en la tabla. Para los que sepan de SQL, como veréis, "duplicamos" las preguntas con todos los campos excepto el campo "Z_PK", ya que este campo es la clave primaria, que como sabréis no puede ser la misma para mas de una fila.
Una vez hecho esto se nos duplican todas las preguntas, si lo repetimos varias veces tendremos mas preguntas. No os paséis porque si creáis demasiadas preguntas, la app luego irá muy lenta, pues tiene que cargar demasiadas preguntas de la base de datos.
Bien, pues ahora queda usar la nueva base de datos en la app.. pero este archivo esta protegido, así que no bastará con arrastrarlo a la capeta "/Documents" de la app y reemplazar la antigua (si lo probáis veréis que da error). El único modo es  crear un backup de la app usando iTools.

Usando la opción que veis en la imagen "Backup program and documents". Esto nos generará un archivo IPA en nuestro escritorio. Lo que haremos será abrirlo con WinRar y entrar en la carpeta "/Container/Documents" y ahora arrastramos nuestra nueva base de datos con nuestras preguntas al archivo, lo que reemplazará la base de datos que se guardo en el backup. Y ya simplemente eliminamos nuestra app del dispositivo y despues instalamos el backup en nuestro dispositivo, arrastrando el archivo IPA a iTools.

Una vez se haya instalado la app, podremos usarla como siempre y podremos ganar siempre respondiendo con la primera opción :)

He escrito un poco a prisa y corriendo esta entrada, así que espero que sea entendible para todos. Si tienen algún problema diganlo por comentarios. No sean malos!! :P

miércoles, 24 de julio de 2013

phpTuenti API

Buenos días!
Después de bastante tiempo si escribir nada, hoy escribo para compartir con vosotros una pequeña API no oficial en PHP para Tuenti hecha por mi.

El enlace a GitHub:

Ahí tienen la API y para cada función una breve descripción.
Espero que les sea útil :)

Si alguien quiere añadir algo a la API o modificar algo para mejorarla puede decirlo y colaborar :)

Por cierto, como alguno me comentó cuando hice la API para Python que por que no le ponía una licencia, he decidido añadirle una licencia Creative Commons a la API !

Intentaré escribir con mas frecuencia!! Hasta la próxima! :)