# Path Traversal

## Overview

Acabo de completar todos los laboratorios de la vulnerabilidad Path Traversal en PortSwigger.

1. Simple case.
2. Traversal sequences blocked with absolute path bypass.
3. Traversal sequences stripped non-recursively.
4. Traversal sequences stripped with superfluous URL-decode.
5. Validation of start of path.
6. Validation of file extension with null byte bypass.

Son los primeros labs que resuelvo de la plataforma y todavía estoy dando mis primeros pasitos con BurpSuite, pero me quedo con la experiencia que me resultó súper amena. Vale la pena revisar todo el contenido que ofrecen porque está muy bien explicado.

***

## Simple case

**Nivel: Apprentice.**

Nos encontramos con una aplicación de compras, donde la vulnerabilidad reside a la hora de mostrar las imágenes de los productos. El objetivo es leer el archivo `/etc/passwd`. Esta dinámica se va a mantener a lo largo de todos los labs para esta vulnerabilidad en concreto.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FOMwg3EI7rfzv2RM4AgAJ%2Fimage1.png?alt=media&#x26;token=3580348e-ef46-4416-8a03-4d728529cbf2" alt=""><figcaption></figcaption></figure>

Hacemos click derecho sobre cualquiera de los ítems y seleccionamos la opción para abrir la imagen en una nueva ventana.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2F5MPRit5HV0VTGHRX810G%2Fimage2.png?alt=media&#x26;token=c8eb816c-c623-4f51-b7fd-cb1b7327fb85" alt=""><figcaption></figcaption></figure>

Ahora podemos ver en la URL un parámetro `filename`, a través del cual podemos controlar qué imagen queremos cargar de las que se encuentran almacenadas en la ruta `/var/www/images`. Sin embargo, si es vulnerable, podríamos intentar retroceder unos directorios hacia atrás para llegar a la raíz y cargar otro archivo al que no deberíamos tener acceso.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FC0KiF8TZfEKpRnblsp1z%2Fimage3.png?alt=media&#x26;token=5ad1d315-499a-4d5e-98f1-b3eb381e250e" alt=""><figcaption></figcaption></figure>

Algo a tener en cuenta es que estoy utilizando el propio navegador que trae BurpSuite. Si estuviera con otro navegador, debería usar alguna extensión como FoxyProxy y configurar un proxy; BurpSuite por defecto escucha por el equipo local por el puerto 8080.&#x20;

Interceptamos la petición con BurpSuite y con `Ctrl + R` la emitimos al Repeater:

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FXHdupqbVGNSjBjnPldBl%2Fimage4.png?alt=media&#x26;token=74e7f7b6-a0f7-459b-b603-1b3a2cdc01dd" alt=""><figcaption></figcaption></figure>

Desde ahí modificamos lo que vale `filename` para intentar acontecer un Directory Path Traversal e incluir un archivo local de la máquina: `/image?filename=../../../etc/passwd`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2F6rX8kKc8yfaMJxSKSwT9%2Fimage5.png?alt=media&#x26;token=8263bf24-7c09-48de-8d30-584dad405b5d" alt=""><figcaption></figcaption></figure>

¡Y listo! Pudimos listar el `/etc/passwd.`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FDbAg3FPuyQ4gFwK2zzvM%2Fimage6.png?alt=media&#x26;token=4194f2e3-6370-455e-b64a-db4bb2becfea" alt=""><figcaption></figcaption></figure>

***

## Traversal sequences blocked with absolute path bypass

**Nivel: Practitioner.**

Volvemos a encontrarnos con el mismo sitio, así que seleccionamos una imagen e interceptamos la petición con Burp.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FXJgL5EJ1zOxwgWjHX48g%2Fimage7.png?alt=media&#x26;token=9286cb5d-0e7d-4112-969e-7c4c4ae3f677" alt=""><figcaption></figcaption></figure>

En este caso, las secuencias típicas de un Path Traversal se encuentras bloqueadas, pero podemos intentar cargar directamente el archivo por si parte desde la raíz indicando su ruta absoluta:                `/image?filename=/etc/passwd`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FxU2cVahoFSlmtvNRMOWA%2Fimage8.png?alt=media&#x26;token=ccde8855-58f2-4afe-abcd-3de3bdb29bd6" alt=""><figcaption></figcaption></figure>

De esta forma, llegamos a ver el contenido del `/etc/passwd` y damos este lab por concluido.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2F5sT4vJKYItQaeZ0InqfF%2Fimage9.png?alt=media&#x26;token=bb14c46f-34cc-49ef-9640-0a8440088dd1" alt=""><figcaption></figcaption></figure>

***

## Traversal sequences stripped non-recursively

**Nivel: Practitioner.**

Abrimos una imagen e interceptamos con Burp.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FlSrLkZn44IwEgEIytwOm%2Fimage10.png?alt=media&#x26;token=29882bad-3612-4f2a-8b11-69a033b8354b" alt=""><figcaption></figcaption></figure>

En esta ocasión, se está aplicando una pequeña sanitización respecto al input del usuario, eliminando todos los `../`

```php
$ echo str_replace("../", "", "../../../etc/passwd");
etc/passwd
```

Sin embargo, esta sanitización no es recursiva. Es decir que se aplica una única vez. Por ende, para bypassear esta restricción, basta con utilizar `....//` en lugar de `../`

<pre class="language-php"><code class="lang-php"><strong>$ echo str_replace("../", "", "....//....//....//etc/passwd");
</strong>../../../etc/passwd
</code></pre>

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2F71K4p6k5Kgq4p7qfZ7w7%2Fimage11.png?alt=media&#x26;token=d3349c91-e57d-4d2e-b0db-6c829289f82b" alt=""><figcaption></figcaption></figure>

Lab completado.&#x20;

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Fj2rXJvWDffzRi76tTB3s%2Fimage12.png?alt=media&#x26;token=aea41ac9-4c00-431c-8522-5dc87048895c" alt=""><figcaption></figcaption></figure>

***

## Traversal sequences stripped with superfluous URL-decode

**Nivel: Practitioner.**

Interceptamos la petición con BurpSuite y la emitimos al Repeater.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Fbdb4zLHrbYhNbXb9NHKg%2Fimage13.png?alt=media&#x26;token=203aec16-124a-4008-8f77-84ac7a9f573c" alt=""><figcaption></figcaption></figure>

No vamos a poder aplicar ninguna de las técnicas anteriores. Sabemos que la aplicación bloquea cualquier secuencia de Path Traversal, pero también se nos informa que realiza un URL-decode del input antes de cargar la imagen.

`../` no es la única forma que tenemos de escribir esta secuencia. Por ejemplo, primero representamos la barra en formato URL-encode, por lo que ahora la cadena se convierte en `..%2f`.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Ft9BE3ahn4YFZ3M29PK2S%2Fimage14.png?alt=media&#x26;token=747be1d6-b66b-4ee9-a060-71dc716264db" alt=""><figcaption></figcaption></figure>

Posteriormente volvemos a aplicar un URL-encode al porcentaje: `..%252f`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Frf2Sglf28lYYpiHVd8Wa%2Fimage15.png?alt=media&#x26;token=b133f155-6922-4034-b393-0848e25d47b9" alt=""><figcaption></figcaption></figure>

Repetimos esa secuencia varias veces y quedaría así:&#x20;

`/image?filename=..%252f..%252f..%252f/etc/passwd`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Ff1NEnxM6GA6IkEAarN4X%2Fimage16.png?alt=media&#x26;token=10c913ac-8cd9-4b60-9058-58d40e1f729a" alt=""><figcaption></figcaption></figure>

Ahora sí funciona y logramos cargar el `/etc/passwd`.&#x20;

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FCbjYthx9OICIokU54I0J%2Fimage17.png?alt=media&#x26;token=8def411b-de2d-4408-b709-cd809e2a1167" alt=""><figcaption></figcaption></figure>

***

## Validation of start of path

**Nivel: Practitioner.**

Lo mismo que en los labs anteriores; seleccionamos una imagen, interceptamos con Burp y emitimos al Repeater.&#x20;

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FFjD5sFbsAXQWk5r8d5I4%2Fimage18.png?alt=media&#x26;token=6d56053c-e33a-4f51-9410-c2b8e7185517" alt=""><figcaption></figcaption></figure>

La aplicación valida que nuestro input comience por un directorio determinado, en este caso: `/var/www/images`. Sin problemas podemos colocar ese path y luego retroceder tres directorios para llegar a la raíz porque `../` es una secuencia válida y de ahí en más cargar el `/etc/passwd`.

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FhB5ejzLMvwodUIXY8HZd%2Fimage19.png?alt=media&#x26;token=84c78425-e073-4436-a020-f42244c1bc03" alt=""><figcaption></figcaption></figure>

¡Lab resuelto!

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FdkuJzfvejtpKxXooxhTu%2Fimage20.png?alt=media&#x26;token=ae9a50f1-61c6-41e3-bb83-24381072cecc" alt=""><figcaption></figcaption></figure>

***

## Validation of file extension with null byte bypass

**Nivel: Practitioner.**

Interceptamos la petición y la emitimos al Repeater.&#x20;

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FYPBeMb22venY4WRuuQhU%2Fimage21.png?alt=media&#x26;token=757c25fe-bb0f-41f3-9272-88a5cb10e740" alt=""><figcaption></figcaption></figure>

En este caso, la aplicación valida que el nombre de archivo que proporcionamos termine con una extensión determinada (.jpg), pero podemos usar un null byte `%00` para aislar la extensión y que no se interprete: `/image?filename=../../../etc/passwd%00.jpg`

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2Fg0YB1fCTV1FJ6zDVMQWg%2Fimage22.png?alt=media&#x26;token=2ed7801b-6cfb-4ea2-994a-267551779552" alt=""><figcaption></figcaption></figure>

De esta forma, completamos el último lab.&#x20;

<figure><img src="https://2256246714-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FuERcU4lwQo3nz1NqRbDl%2Fuploads%2FVd55uL8WTsHRWWg6DzZf%2Fimage23.png?alt=media&#x26;token=3b31f758-485a-40b0-a6d7-1a839ed7431d" alt=""><figcaption></figcaption></figure>
