mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
Translated ['src/binary-exploitation/ios-exploiting/ios-physical-uaf-ios
This commit is contained in:
parent
d9b26161b4
commit
feac8e3e40
1
.gitignore
vendored
1
.gitignore
vendored
@ -11,3 +11,4 @@ book
|
||||
book/*
|
||||
hacktricks-preprocessor.log
|
||||
hacktricks-preprocessor-error.log
|
||||
searchindex.js
|
||||
|
@ -3,95 +3,105 @@
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
|
||||
## Physical use-after-free
|
||||
## iOS Exploit Mitigations
|
||||
|
||||
- **Code Signing** in iOS works by requiring every piece of executable code (apps, libraries, extensions, etc.) to be cryptographically signed with a certificate issued by Apple. When code is loaded, iOS verifies the digital signature against Apple’s trusted root. If the signature is invalid, missing, or modified, the OS refuses to run it. This prevents attackers from injecting malicious code into legitimate apps or running unsigned binaries, effectively stopping most exploit chains that rely on executing arbitrary or tampered code.
|
||||
- **CoreTrust** is the iOS subsystem responsible for enforcing code signing at runtime. It directly verifies signatures using Apple’s root certificate without relying on cached trust stores, meaning only binaries signed by Apple (or with valid entitlements) can execute. CoreTrust ensures that even if an attacker tampers with an app after installation, modifies system libraries, or tries to load unsigned code, the system will block execution unless the code is still properly signed. This strict enforcement closes many post-exploitation vectors that older iOS versions allowed through weaker or bypassable signature checks.
|
||||
- **Data Execution Prevention (DEP)** marks memory regions as non-executable unless they explicitly contain code. This stops attackers from injecting shellcode into data regions (like the stack or heap) and running it, forcing them to rely on more complex techniques like ROP (Return-Oriented Programming).
|
||||
- **ASLR (Address Space Layout Randomization)** randomizes the memory addresses of code, libraries, stack, and heap every time the system runs. This makes it much harder for attackers to predict where useful instructions or gadgets are, breaking many exploit chains that depend on fixed memory layouts.
|
||||
- **KASLR (Kernel ASLR)** applies the same randomization concept to the iOS kernel. By shuffling the kernel’s base address at each boot, it prevents attackers from reliably locating kernel functions or structures, raising the difficulty of kernel-level exploits that would otherwise gain full system control.
|
||||
- **Kernel Patch Protection (KPP)** also known as **AMCC (Apple Mobile File Integrity)** in iOS, continuously monitors the kernel’s code pages to ensure they haven’t been modified. If any tampering is detected—such as an exploit trying to patch kernel functions or insert malicious code—the device will immediately panic and reboot. This protection makes persistent kernel exploits far harder, as attackers can’t simply hook or patch kernel instructions without triggering a system crash.
|
||||
- **Kernel Text Readonly Region (KTRR)** is a hardware-based security feature introduced on iOS devices. It uses the CPU’s memory controller to mark the kernel’s code (text) section as permanently read-only after boot. Once locked, even the kernel itself cannot modify this memory region. This prevents attackers—and even privileged code—from patching kernel instructions at runtime, closing off a major class of exploits that relied on modifying kernel code directly.
|
||||
- **Pointer Authentication Codes (PAC)** use cryptographic signatures embedded into unused bits of pointers to verify their integrity before use. When a pointer (like a return address or function pointer) is created, the CPU signs it with a secret key; before dereferencing, the CPU checks the signature. If the pointer was tampered with, the check fails and execution stops. This prevents attackers from forging or reusing corrupted pointers in memory corruption exploits, making techniques like ROP or JOP much harder to pull off reliably.
|
||||
- **Privilege Access never (PAN)** is a hardware feature that prevents the kernel (privileged mode) from directly accessing user-space memory unless it explicitly enables access. This stops attackers who gained kernel code execution from easily reading or writing user memory to escalate exploits or steal sensitive data. By enforcing strict separation, PAN reduces the impact of kernel exploits and blocks many common privilege-escalation techniques.
|
||||
- **Page Protection Layer (PPL)** is an iOS security mechanism that protects critical kernel-managed memory regions, especially those related to code signing and entitlements. It enforces strict write protections using the MMU (Memory Management Unit) and additional checks, ensuring that even privileged kernel code cannot arbitrarily modify sensitive pages. This prevents attackers who gain kernel-level execution from tampering with security-critical structures, making persistence and code-signing bypasses significantly harder.
|
||||
|
||||
Este es un resumen del post en [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html). Además, más información sobre exploits que usan esta técnica puede encontrarse en [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
|
||||
|
||||
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
|
||||
|
||||
El espacio de direcciones de memoria virtual para procesos de usuario en iOS abarca desde 0x0 hasta 0x8000000000. Sin embargo, estas direcciones no se corresponden directamente con la memoria física. En su lugar, el kernel usa tablas de páginas para traducir direcciones virtuales a direcciones físicas reales.
|
||||
The **virtual memory address space** for user processes on iOS spans from **0x0 to 0x8000000000**. However, these addresses don’t directly map to physical memory. Instead, the **kernel** uses **page tables** to translate virtual addresses into actual **physical addresses**.
|
||||
|
||||
#### Levels of Page Tables in iOS
|
||||
|
||||
Las tablas de páginas están organizadas jerárquicamente en tres niveles:
|
||||
Page tables are organized hierarchically in three levels:
|
||||
|
||||
1. Tabla de páginas L1 (Level 1):
|
||||
* Cada entrada aquí representa un rango grande de memoria virtual.
|
||||
* Cubre 0x1000000000 bytes (o 256 GB) de memoria virtual.
|
||||
2. Tabla de páginas L2 (Level 2):
|
||||
* Una entrada aquí representa una región más pequeña de memoria virtual, específicamente 0x2000000 bytes (32 MB).
|
||||
* Una entrada L1 puede apuntar a una tabla L2 si no puede mapear toda la región por sí misma.
|
||||
3. Tabla de páginas L3 (Level 3):
|
||||
* Este es el nivel más fino, donde cada entrada mapea una página de memoria de 4 KB.
|
||||
* Una entrada L2 puede apuntar a una tabla L3 si se necesita un control más granular.
|
||||
1. **L1 Page Table (Level 1)**:
|
||||
* Each entry here represents a large range of virtual memory.
|
||||
* It covers **0x1000000000 bytes** (or **256 GB**) of virtual memory.
|
||||
2. **L2 Page Table (Level 2)**:
|
||||
* An entry here represents a smaller region of virtual memory, specifically **0x2000000 bytes** (32 MB).
|
||||
* An L1 entry may point to an L2 table if it can't map the entire region itself.
|
||||
3. **L3 Page Table (Level 3)**:
|
||||
* This is the finest level, where each entry maps a single **4 KB** memory page.
|
||||
* An L2 entry may point to an L3 table if more granular control is needed.
|
||||
|
||||
#### Mapping Virtual to Physical Memory
|
||||
|
||||
* Direct Mapping (Block Mapping):
|
||||
* Algunas entradas en una tabla de páginas mapean directamente un rango de direcciones virtuales a un rango contiguo de direcciones físicas (como un atajo).
|
||||
* Pointer to Child Page Table:
|
||||
* Si se necesita mayor granularidad, una entrada en un nivel (por ejemplo, L1) puede apuntar a una tabla de páginas hija en el siguiente nivel (por ejemplo, L2).
|
||||
* **Direct Mapping (Block Mapping)**:
|
||||
* Some entries in a page table directly **map a range of virtual addresses** to a contiguous range of physical addresses (like a shortcut).
|
||||
* **Pointer to Child Page Table**:
|
||||
* If finer control is needed, an entry in one level (e.g., L1) can point to a **child page table** at the next level (e.g., L2).
|
||||
|
||||
#### Example: Mapping a Virtual Address
|
||||
|
||||
Imagina que intentas acceder a la dirección virtual 0x1000000000:
|
||||
Let’s say you try to access the virtual address **0x1000000000**:
|
||||
|
||||
1. L1 Table:
|
||||
* El kernel comprueba la entrada de la tabla L1 correspondiente a esa dirección virtual. Si tiene un pointer to an L2 page table, va a esa tabla L2.
|
||||
2. L2 Table:
|
||||
* El kernel comprueba la tabla L2 para un mapeo más detallado. Si esta entrada apunta a una L3 page table, procede allí.
|
||||
3. L3 Table:
|
||||
* El kernel consulta la entrada final L3, que apunta a la dirección física de la página de memoria real.
|
||||
1. **L1 Table**:
|
||||
* The kernel checks the L1 page table entry corresponding to this virtual address. If it has a **pointer to an L2 page table**, it goes to that L2 table.
|
||||
2. **L2 Table**:
|
||||
* The kernel checks the L2 page table for a more detailed mapping. If this entry points to an **L3 page table**, it proceeds there.
|
||||
3. **L3 Table**:
|
||||
* The kernel looks up the final L3 entry, which points to the **physical address** of the actual memory page.
|
||||
|
||||
#### Example of Address Mapping
|
||||
|
||||
Si escribes la dirección física 0x800004000 en el primer índice de la tabla L2, entonces:
|
||||
If you write the physical address **0x800004000** into the first index of the L2 table, then:
|
||||
|
||||
* Las direcciones virtuales desde 0x1000000000 hasta 0x1002000000 se mapean a direcciones físicas desde 0x800004000 hasta 0x802004000.
|
||||
* Esto es un block mapping a nivel L2.
|
||||
* Virtual addresses from **0x1000000000** to **0x1002000000** map to physical addresses from **0x800004000** to **0x802004000**.
|
||||
* This is a **block mapping** at the L2 level.
|
||||
|
||||
Alternativamente, si la entrada L2 apunta a una tabla L3:
|
||||
Alternatively, if the L2 entry points to an L3 table:
|
||||
|
||||
* Cada página de 4 KB en el rango virtual 0x1000000000 -> 0x1002000000 sería mapeada por entradas individuales en la tabla L3.
|
||||
* Each 4 KB page in the virtual address range **0x1000000000 -> 0x1002000000** would be mapped by individual entries in the L3 table.
|
||||
|
||||
### Physical use-after-free
|
||||
## Physical use-after-free
|
||||
|
||||
Un Physical use-after-free (UAF) ocurre cuando:
|
||||
A **physical use-after-free** (UAF) occurs when:
|
||||
|
||||
1. Un proceso aloja (allocate) memoria como readable and writable.
|
||||
2. Las page tables se actualizan para mapear esa memoria a una dirección física específica a la que el proceso puede acceder.
|
||||
3. El proceso desaloca (free) la memoria.
|
||||
4. Sin embargo, debido a un bug, el kernel se olvida de eliminar el mapping de las tablas de páginas, aunque marca la memoria física correspondiente como libre.
|
||||
5. El kernel puede entonces reallocar esa memoria física "liberada" para otros propósitos, como datos del kernel.
|
||||
6. Como el mapping no se eliminó, el proceso aún puede read y write a esa memoria física.
|
||||
1. A process **allocates** some memory as **readable and writable**.
|
||||
2. The **page tables** are updated to map this memory to a specific physical address that the process can access.
|
||||
3. The process **deallocates** (frees) the memory.
|
||||
4. However, due to a **bug**, the kernel **forgets to remove the mapping** from the page tables, even though it marks the corresponding physical memory as free.
|
||||
5. The kernel can then **reallocate this "freed" physical memory** for other purposes, like **kernel data**.
|
||||
6. Since the mapping wasn’t removed, the process can still **read and write** to this physical memory.
|
||||
|
||||
Esto significa que el proceso puede acceder a páginas de kernel memory, que podrían contener datos sensibles o estructuras, permitiendo potencialmente a un atacante manipular kernel memory.
|
||||
This means the process can access **pages of kernel memory**, which could contain sensitive data or structures, potentially allowing an attacker to **manipulate kernel memory**.
|
||||
|
||||
### IOSurface Heap Spray
|
||||
|
||||
Dado que el atacante no puede controlar qué páginas del kernel serán asignadas a la memoria liberada, usa una técnica llamada heap spray:
|
||||
Since the attacker can’t control which specific kernel pages will be allocated to freed memory, they use a technique called **heap spray**:
|
||||
|
||||
1. El atacante crea un gran número de objetos IOSurface en kernel memory.
|
||||
2. Cada objeto IOSurface contiene un valor mágico en uno de sus campos, lo que facilita su identificación.
|
||||
3. Escanean las páginas liberadas para ver si alguno de estos objetos IOSurface cayó en una página liberada.
|
||||
4. Cuando encuentran un objeto IOSurface en una página liberada, pueden usarlo para read and write kernel memory.
|
||||
1. The attacker **creates a large number of IOSurface objects** in kernel memory.
|
||||
2. Each IOSurface object contains a **magic value** in one of its fields, making it easy to identify.
|
||||
3. They **scan the freed pages** to see if any of these IOSurface objects landed on a freed page.
|
||||
4. When they find an IOSurface object on a freed page, they can use it to **read and write kernel memory**.
|
||||
|
||||
Más información sobre esto en [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
|
||||
More info about this in [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
|
||||
|
||||
> [!TIP]
|
||||
> Ten en cuenta que los dispositivos iOS 16+ (A12+) incorporan mitigaciones de hardware (como PPL o SPTM) que hacen que las técnicas de physical UAF sean mucho menos viables.
|
||||
> PPL impone protecciones MMU estrictas en páginas relacionadas con code signing, entitlements y datos sensibles del kernel, por lo que, incluso si una página se reutiliza, los writes desde userland o código de kernel comprometido a páginas protegidas por PPL son bloqueados.
|
||||
> Secure Page Table Monitor (SPTM) amplía PPL endureciendo las propias actualizaciones de page tables. Asegura que incluso el código privilegiado del kernel no pueda remapear silenciosamente páginas liberadas o manipular mappings sin pasar por comprobaciones seguras.
|
||||
> KTRR (Kernel Text Read-Only Region), que bloquea la sección de código del kernel como read-only después del arranque. Esto evita modificaciones en tiempo de ejecución al código del kernel, cerrando una vía de ataque principal de la que dependen muchos exploits de physical UAF.
|
||||
> Además, las asignaciones de IOSurface son menos predictibles y más difíciles de mapear en regiones accesibles por el usuario, lo que hace que el truco de "scanear por el valor mágico" sea mucho menos fiable. Y IOSurface ahora está protegido por entitlements y restricciones de sandbox.
|
||||
> Be aware that iOS 16+ (A12+) devices bring hardware mitigations (like PPL or SPTM) that make physical UAF techniques far less viable.
|
||||
> PPL enforces strict MMU protections on pages related to code signing, entitlements, and sensitive kernel data, so, even if a page gets reused, writes from userland or compromised kernel code to PPL-protected pages are blocked.
|
||||
> Secure Page Table Monitor (SPTM) extends PPL by hardening page table updates themselves. It ensures that even privileged kernel code cannot silently remap freed pages or tamper with mappings without going through secure checks.
|
||||
> KTRR (Kernel Text Read-Only Region), which locks down the kernel’s code section as read-only after boot. This prevents any runtime modifications to kernel code, closing off a major attack vector that physical UAF exploits often rely on.
|
||||
> Moreover, `IOSurface` allocations are less predictable and harder to map into user-accessible regions, which makes the “magic value scanning” trick much less reliable. And `IOSurface` is now guarded by entitlements and sandbox restrictions.
|
||||
|
||||
### Step-by-Step Heap Spray Process
|
||||
|
||||
1. Spray IOSurface Objects: El atacante crea muchos objetos IOSurface con un identificador especial ("magic value").
|
||||
2. Scan Freed Pages: Comprueban si alguno de los objetos ha sido asignado en una página liberada.
|
||||
3. Read/Write Kernel Memory: Manipulando campos en el objeto IOSurface, obtienen la capacidad de realizar arbitrary reads and writes en kernel memory. Esto les permite:
|
||||
* Usar un campo para read any 32-bit value en kernel memory.
|
||||
* Usar otro campo para write 64-bit values, logrando una stable kernel read/write primitive.
|
||||
1. **Spray IOSurface Objects**: The attacker creates many IOSurface objects with a special identifier ("magic value").
|
||||
2. **Scan Freed Pages**: They check if any of the objects have been allocated on a freed page.
|
||||
3. **Read/Write Kernel Memory**: By manipulating fields in the IOSurface object, they gain the ability to perform **arbitrary reads and writes** in kernel memory. This lets them:
|
||||
* Use one field to **read any 32-bit value** in kernel memory.
|
||||
* Use another field to **write 64-bit values**, achieving a stable **kernel read/write primitive**.
|
||||
|
||||
Generate IOSurface objects with the magic value IOSURFACE\_MAGIC to later search for:
|
||||
```c
|
||||
@ -148,20 +158,20 @@ free(surfaceIDs);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
### Lograr Kernel Read/Write con IOSurface
|
||||
### Lograr lectura/escritura del kernel con IOSurface
|
||||
|
||||
Después de obtener control sobre un objeto IOSurface en la memoria del kernel (mapeado a una página física liberada accesible desde userspace), podemos usarlo para **arbitrary kernel read and write operations**.
|
||||
Después de controlar un objeto IOSurface en la memoria del kernel (mapeado a una página física liberada accesible desde userspace), podemos usarlo para operaciones **arbitrarias de lectura y escritura en el kernel**.
|
||||
|
||||
**Campos clave en IOSurface**
|
||||
|
||||
El objeto IOSurface tiene dos campos cruciales:
|
||||
|
||||
1. **Use Count Pointer**: Permite un **32-bit read**.
|
||||
2. **Indexed Timestamp Pointer**: Permite un **64-bit write**.
|
||||
1. **Use Count Pointer**: Permite una **lectura de 32 bits**.
|
||||
2. **Indexed Timestamp Pointer**: Permite una **escritura de 64 bits**.
|
||||
|
||||
Al sobrescribir estos punteros, los redirigimos a direcciones arbitrarias en la memoria del kernel, habilitando capacidades de read/write.
|
||||
Al sobrescribir estos punteros, los redirigimos a direcciones arbitrarias en la memoria del kernel, habilitando capacidades de lectura/escritura.
|
||||
|
||||
#### Lectura Kernel de 32 bits
|
||||
#### Lectura de 32 bits del kernel
|
||||
|
||||
Para realizar una lectura:
|
||||
|
||||
@ -188,7 +198,7 @@ return value;
|
||||
|
||||
Para realizar una escritura:
|
||||
|
||||
1. Sobrescribe el **indexed timestamp pointer** con la dirección objetivo.
|
||||
1. Sobrescribe el **puntero de timestamp indexado** con la dirección objetivo.
|
||||
2. Usa el método `set_indexed_timestamp` para escribir un valor de 64 bits.
|
||||
```c
|
||||
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
|
||||
@ -203,13 +213,13 @@ set_indexed_timestamp(info.client, info.surface, value);
|
||||
iosurface_set_indexed_timestamp_pointer(info.object, orig);
|
||||
}
|
||||
```
|
||||
#### Exploit Flow Recap
|
||||
#### Resumen del flujo del exploit
|
||||
|
||||
1. **Trigger Physical Use-After-Free**: Las páginas liberadas están disponibles para su reutilización.
|
||||
2. **Spray IOSurface Objects**: Asigna muchos objetos IOSurface con un "magic value" único en kernel memory.
|
||||
3. **Identify Accessible IOSurface**: Localiza un IOSurface en una página liberada que controlas.
|
||||
4. **Abuse Use-After-Free**: Modifica punteros en el objeto IOSurface para habilitar arbitrary **kernel read/write** vía los métodos de IOSurface.
|
||||
1. **Trigger Physical Use-After-Free**: Las páginas liberadas quedan disponibles para su reutilización.
|
||||
2. **Spray IOSurface Objects**: Asigna muchos objetos IOSurface con un "magic value" único en la memoria del kernel.
|
||||
3. **Identify Accessible IOSurface**: Localiza un IOSurface en una página liberada que controlas.
|
||||
4. **Abuse Use-After-Free**: Modifica punteros en el objeto IOSurface para habilitar kernel read/write arbitrarios mediante métodos de IOSurface.
|
||||
|
||||
Con estas primitivas, el exploit proporciona **lecturas de 32-bit** controladas y **escrituras de 64-bit** en kernel memory. Pasos adicionales de jailbreak podrían implicar primitivas de read/write más estables, que pueden requerir eludir protecciones adicionales (p. ej., PPL en dispositivos arm64e más recientes).
|
||||
Con estas primitivas, el exploit proporciona lecturas controladas de 32 bits y escrituras de 64 bits en la memoria del kernel. Pasos adicionales del jailbreak podrían implicar primitivas de lectura/escritura más estables, lo que puede requerir eludir protecciones adicionales (p. ej., PPL en dispositivos arm64e más recientes).
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -4,66 +4,144 @@
|
||||
|
||||
## Introducción
|
||||
|
||||
Para detectar un intento de phishing es importante **entender las técnicas de phishing que se están utilizando hoy en día**. En la página principal de esta publicación, puedes encontrar esta información, así que si no estás al tanto de qué técnicas se están utilizando hoy, te recomiendo que vayas a la página principal y leas al menos esa sección.
|
||||
Para detectar un intento de phishing es importante **entender las técnicas de phishing que se están usando hoy en día**. En la página padre de esta entrada puedes encontrar esa información, así que si no conoces qué técnicas se usan actualmente te recomiendo ir a la página padre y leer al menos esa sección.
|
||||
|
||||
Esta publicación se basa en la idea de que los **atacantes intentarán de alguna manera imitar o usar el nombre de dominio de la víctima**. Si tu dominio se llama `example.com` y eres víctima de phishing utilizando un nombre de dominio completamente diferente por alguna razón como `youwonthelottery.com`, estas técnicas no lo descubrirán.
|
||||
Esta entrada se basa en la idea de que **los atacantes intentarán de alguna manera imitar o usar el nombre de dominio de la víctima**. Si tu dominio se llama `example.com` y eres phished usando un nombre de dominio completamente diferente por alguna razón como `youwonthelottery.com`, estas técnicas no lo van a descubrir.
|
||||
|
||||
## Variaciones de nombres de dominio
|
||||
## Variaciones del nombre de dominio
|
||||
|
||||
Es bastante **fácil** **descubrir** esos intentos de **phishing** que utilizarán un **nombre de dominio similar** dentro del correo electrónico.\
|
||||
Es suficiente con **generar una lista de los nombres de phishing más probables** que un atacante puede usar y **verificar** si está **registrado** o simplemente comprobar si hay alguna **IP** usándolo.
|
||||
Es bastante **fácil** **descubrir** esos intentos de **phishing** que usarán un **dominio similar** dentro del correo.\
|
||||
Basta con **generar una lista de los nombres de phishing más probables** que un atacante puede usar y **comprobar** si está **registrado** o simplemente verificar si hay alguna **IP** usándolo.
|
||||
|
||||
### Encontrar dominios sospechosos
|
||||
|
||||
Para este propósito, puedes usar cualquiera de las siguientes herramientas. Ten en cuenta que estas herramientas también realizarán solicitudes DNS automáticamente para verificar si el dominio tiene alguna IP asignada:
|
||||
Para este propósito puedes usar cualquiera de las siguientes herramientas. Ten en cuenta que estas herramientas también realizarán consultas DNS automáticamente para comprobar si el dominio tiene alguna IP asignada:
|
||||
|
||||
- [**dnstwist**](https://github.com/elceef/dnstwist)
|
||||
- [**urlcrazy**](https://github.com/urbanadventurer/urlcrazy)
|
||||
|
||||
Tip: Si generas una lista de candidatos, también introdúcela en los logs de tu DNS resolver para detectar **NXDOMAIN lookups from inside your org** (usuarios intentando alcanzar un typo antes de que el atacante lo registre realmente). Sinkhole o pre-block estos dominios si la política lo permite.
|
||||
|
||||
### Bitflipping
|
||||
|
||||
**Puedes encontrar una breve explicación de esta técnica en la página principal. O leer la investigación original en** [**https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/**](https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/)
|
||||
**Puedes encontrar una breve explicación de esta técnica en la página padre. O lee la investigación original en** [**https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/**](https://www.bleepingcomputer.com/news/security/hijacking-traffic-to-microsoft-s-windowscom-with-bitflipping/)
|
||||
|
||||
Por ejemplo, una modificación de 1 bit en el dominio microsoft.com puede transformarlo en _windnws.com._\
|
||||
**Los atacantes pueden registrar tantos dominios de bit-flipping como sea posible relacionados con la víctima para redirigir a usuarios legítimos a su infraestructura**.
|
||||
**Los atacantes pueden registrar tantos dominios bit-flipping como les sea posible relacionados con la víctima para redirigir usuarios legítimos a su infraestructura**.
|
||||
|
||||
**Todos los posibles nombres de dominio de bit-flipping también deben ser monitoreados.**
|
||||
**Todos los posibles nombres de dominio bit-flipping también deben ser monitorizados.**
|
||||
|
||||
Si además necesitas considerar homoglyph/IDN lookalikes (p. ej., mezcla de caracteres Latinos/Cirílicos), revisa:
|
||||
|
||||
{{#ref}}
|
||||
homograph-attacks.md
|
||||
{{#endref}}
|
||||
|
||||
### Comprobaciones básicas
|
||||
|
||||
Una vez que tengas una lista de nombres de dominio potencialmente sospechosos, debes **verificarlos** (principalmente los puertos HTTP y HTTPS) para **ver si están utilizando algún formulario de inicio de sesión similar** al de alguno de los dominios de la víctima.\
|
||||
También podrías verificar el puerto 3333 para ver si está abierto y ejecutando una instancia de `gophish`.\
|
||||
También es interesante saber **cuán antiguo es cada dominio sospechoso descubierto**, cuanto más joven es, más riesgoso es.\
|
||||
También puedes obtener **capturas de pantalla** de la página web sospechosa en HTTP y/o HTTPS para ver si es sospechosa y en ese caso **acceder a ella para echar un vistazo más profundo**.
|
||||
Una vez que tengas una lista de nombres de dominio potencialmente sospechosos deberías **comprobarlos** (principalmente los puertos HTTP y HTTPS) para **ver si están usando algún formulario de login similar** a los de alguno de los dominios de la víctima.\
|
||||
También podrías comprobar el puerto 3333 para ver si está abierto y ejecutando una instancia de `gophish`.\
|
||||
También es interesante saber **qué edad tiene cada dominio sospechoso descubierto**, cuanto más joven sea, más riesgo implica.\
|
||||
También puedes obtener **capturas de pantalla** de la página web HTTP y/o HTTPS sospechosa para ver si resulta sospechosa y, en ese caso, **acceder a ella para inspeccionarla más a fondo**.
|
||||
|
||||
### Comprobaciones avanzadas
|
||||
|
||||
Si deseas ir un paso más allá, te recomendaría **monitorear esos dominios sospechosos y buscar más** de vez en cuando (¿cada día? solo toma unos segundos/minutos). También deberías **verificar** los **puertos** abiertos de las IP relacionadas y **buscar instancias de `gophish` o herramientas similares** (sí, los atacantes también cometen errores) y **monitorear las páginas web HTTP y HTTPS de los dominios y subdominios sospechosos** para ver si han copiado algún formulario de inicio de sesión de las páginas web de la víctima.\
|
||||
Para **automatizar esto**, te recomendaría tener una lista de formularios de inicio de sesión de los dominios de la víctima, rastrear las páginas web sospechosas y comparar cada formulario de inicio de sesión encontrado dentro de los dominios sospechosos con cada formulario de inicio de sesión del dominio de la víctima utilizando algo como `ssdeep`.\
|
||||
Si has localizado los formularios de inicio de sesión de los dominios sospechosos, puedes intentar **enviar credenciales falsas** y **verificar si te redirige al dominio de la víctima**.
|
||||
Si quieres ir un paso más allá te recomendaría **monitorizar esos dominios sospechosos y buscar más** de vez en cuando (¿cada día? solo toma unos segundos/minutos). También deberías **comprobar** los **puertos** abiertos de las IPs relacionadas y **buscar instancias de `gophish` o herramientas similares** (sí, los atacantes también cometen errores) y **monitorizar las páginas web HTTP y HTTPS de los dominios y subdominios sospechosos** para ver si han copiado algún formulario de login de las páginas de la víctima.\
|
||||
Para **automatizar esto** recomendaría tener una lista de formularios de login de los dominios de la víctima, spiderear las páginas sospechosas y comparar cada formulario de login encontrado dentro de los dominios sospechosos con cada formulario de login del dominio de la víctima usando algo como `ssdeep`.\
|
||||
Si has localizado los formularios de login de los dominios sospechosos, puedes intentar **enviar credenciales basura** y **comprobar si te redirige al dominio de la víctima**.
|
||||
|
||||
## Nombres de dominio que utilizan palabras clave
|
||||
---
|
||||
|
||||
La página principal también menciona una técnica de variación de nombres de dominio que consiste en poner el **nombre de dominio de la víctima dentro de un dominio más grande** (por ejemplo, paypal-financial.com para paypal.com).
|
||||
### Hunting by favicon and web fingerprints (Shodan/ZoomEye/Censys)
|
||||
|
||||
### Transparencia de Certificados
|
||||
Muchos kits de phishing reutilizan favicons de la marca que suplantan. Los escáneres a escala de Internet calculan un MurmurHash3 del favicon codificado en base64. Puedes generar el hash y pivotar en él:
|
||||
|
||||
No es posible tomar el enfoque anterior de "Fuerza Bruta", pero en realidad es **posible descubrir tales intentos de phishing** también gracias a la transparencia de certificados. Cada vez que un certificado es emitido por una CA, los detalles se hacen públicos. Esto significa que al leer la transparencia de certificados o incluso monitorearla, es **posible encontrar dominios que están utilizando una palabra clave dentro de su nombre**. Por ejemplo, si un atacante genera un certificado de [https://paypal-financial.com](https://paypal-financial.com), al ver el certificado es posible encontrar la palabra clave "paypal" y saber que se está utilizando un correo electrónico sospechoso.
|
||||
Ejemplo en Python (mmh3):
|
||||
```python
|
||||
import base64, requests, mmh3
|
||||
url = "https://www.paypal.com/favicon.ico" # change to your brand icon
|
||||
b64 = base64.encodebytes(requests.get(url, timeout=10).content)
|
||||
print(mmh3.hash(b64)) # e.g., 309020573
|
||||
```
|
||||
- Consulta en Shodan: `http.favicon.hash:309020573`
|
||||
- Con herramientas: revisa herramientas comunitarias como favfreak para generar hashes y dorks para Shodan/ZoomEye/Censys.
|
||||
|
||||
La publicación [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) sugiere que puedes usar Censys para buscar certificados que afecten a una palabra clave específica y filtrar por fecha (solo "nuevos" certificados) y por el emisor de la CA "Let's Encrypt":
|
||||
Notes
|
||||
- Favicons se reutilizan; trata las coincidencias como pistas y valida el contenido y los certs antes de actuar.
|
||||
- Combina con heurísticas de domain-age y keyword para mejorar la precisión.
|
||||
|
||||
### Búsqueda de telemetría de URL (urlscan.io)
|
||||
|
||||
`urlscan.io` almacena capturas de pantalla históricas, DOM, requests y metadata TLS de las URLs enviadas. Puedes buscar abuso de marca y clones:
|
||||
|
||||
Example queries (UI or API):
|
||||
- Find lookalikes excluding your legit domains: `page.domain:(/.*yourbrand.*/ AND NOT yourbrand.com AND NOT www.yourbrand.com)`
|
||||
- Find sites hotlinking your assets: `domain:yourbrand.com AND NOT page.domain:yourbrand.com`
|
||||
- Restrict to recent results: append `AND date:>now-7d`
|
||||
|
||||
API example:
|
||||
```bash
|
||||
# Search recent scans mentioning your brand
|
||||
curl -s 'https://urlscan.io/api/v1/search/?q=page.domain:(/.*yourbrand.*/%20AND%20NOT%20yourbrand.com)%20AND%20date:>now-7d' \
|
||||
-H 'API-Key: <YOUR_URLSCAN_KEY>' | jq '.results[].page.url'
|
||||
```
|
||||
A partir del JSON, céntrate en:
|
||||
- `page.tlsIssuer`, `page.tlsValidFrom`, `page.tlsAgeDays` para detectar certificados muy nuevos usados en dominios lookalike
|
||||
- `task.source` valores como `certstream-suspicious` para vincular los hallazgos con el monitoreo CT
|
||||
|
||||
### Edad del dominio vía RDAP (automatizable)
|
||||
|
||||
RDAP devuelve eventos de creación legibles por máquina. Útil para marcar **dominios recién registrados (NRDs)**.
|
||||
```bash
|
||||
# .com/.net RDAP (Verisign)
|
||||
curl -s https://rdap.verisign.com/com/v1/domain/suspicious-example.com | \
|
||||
jq -r '.events[] | select(.eventAction=="registration") | .eventDate'
|
||||
|
||||
# Generic helper using rdap.net redirector
|
||||
curl -s https://www.rdap.net/domain/suspicious-example.com | jq
|
||||
```
|
||||
Enriquece tu pipeline etiquetando dominios por rangos de edad de registro (p. ej., <7 días, <30 días) y prioriza el triage en consecuencia.
|
||||
|
||||
### TLS/JAx fingerprints para detectar infraestructura AiTM
|
||||
|
||||
El credential-phishing moderno utiliza cada vez más reverse proxies Adversary-in-the-Middle (AiTM) (p. ej., Evilginx) para robar session tokens. Puedes añadir detecciones en el lado de la red:
|
||||
|
||||
- Registra TLS/HTTP fingerprints (JA3/JA4/JA4S/JA4H) en egress. Algunas builds de Evilginx se han observado con valores JA4 cliente/servidor estables. Genera alertas por fingerprints known-bad solo como una señal débil y confirma siempre con contenido y domain intel.
|
||||
- Registra proactivamente TLS certificate metadata (issuer, SAN count, wildcard use, validity) para lookalike hosts descubiertos vía CT o urlscan y correlaciónalo con DNS age y geolocation.
|
||||
|
||||
> Nota: Trata los fingerprints como enriquecimiento, no como bloqueadores únicos; los frameworks evolucionan y pueden aleatorizarse u ofuscarse.
|
||||
|
||||
### Domain names using keywords
|
||||
|
||||
La página padre también menciona una técnica de variación de nombres de dominio que consiste en insertar el **nombre de dominio de la víctima dentro de un dominio más grande** (p. ej., paypal-financial.com para paypal.com).
|
||||
|
||||
#### Transparencia de certificados
|
||||
|
||||
No es posible tomar el enfoque anterior de "Brute-Force", pero en realidad sí es **posible descubrir estos intentos de phishing** también gracias a Certificate Transparency. Cada vez que una CA emite un certificado, los detalles se hacen públicos. Esto significa que al leer Certificate Transparency o incluso monitorizarlo, es **posible encontrar dominios que usan una palabra clave dentro de su nombre**. Por ejemplo, si un atacante genera un certificado de [https://paypal-financial.com](https://paypal-financial.com), al ver el certificado es posible encontrar la palabra clave "paypal" y saber que se está usando un email sospechoso.
|
||||
|
||||
La entrada [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) sugiere que puedes usar Censys para buscar certificados que afecten a una palabra clave específica y filtrar por fecha (solo certificados "nuevos") y por la CA emisora "Let's Encrypt":
|
||||
|
||||
.png>)
|
||||
|
||||
Sin embargo, puedes hacer "lo mismo" utilizando la web gratuita [**crt.sh**](https://crt.sh). Puedes **buscar la palabra clave** y **filtrar** los resultados **por fecha y CA** si lo deseas.
|
||||
Sin embargo, puedes hacer "lo mismo" usando la web gratuita [**crt.sh**](https://crt.sh). Puedes **buscar la palabra clave** y **filtrar** los resultados **por fecha y CA** si lo deseas.
|
||||
|
||||
.png>)
|
||||
|
||||
Usando esta última opción, incluso puedes usar el campo Identidades Coincidentes para ver si alguna identidad del dominio real coincide con alguno de los dominios sospechosos (ten en cuenta que un dominio sospechoso puede ser un falso positivo).
|
||||
Usando esta última opción incluso puedes usar el campo Matching Identities para ver si alguna identidad del dominio real coincide con alguno de los dominios sospechosos (nota: un dominio sospechoso puede ser un falso positivo).
|
||||
|
||||
**Otra alternativa** es el fantástico proyecto llamado [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067). CertStream proporciona un flujo en tiempo real de certificados recién generados que puedes usar para detectar palabras clave especificadas en (casi) tiempo real. De hecho, hay un proyecto llamado [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) que hace exactamente eso.
|
||||
**Otra alternativa** es el fantástico proyecto llamado [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067). CertStream proporciona un flujo en tiempo real de certificados recién generados que puedes usar para detectar palabras clave especificadas en tiempo (casi) real. De hecho, existe un proyecto llamado [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) que hace precisamente eso.
|
||||
|
||||
### **Nuevos dominios**
|
||||
Consejo práctico: al triagear los hits de CT, prioriza NRDs, registradores no confiables/desconocidos, privacy-proxy WHOIS y certs con tiempos `NotBefore` muy recientes. Mantén una allowlist de tus dominios/marcas para reducir ruido.
|
||||
|
||||
**Una última alternativa** es reunir una lista de **dominios recién registrados** para algunos TLDs ([Whoxy](https://www.whoxy.com/newly-registered-domains/) proporciona tal servicio) y **verificar las palabras clave en estos dominios**. Sin embargo, los dominios largos suelen usar uno o más subdominios, por lo tanto, la palabra clave no aparecerá dentro del FLD y no podrás encontrar el subdominio de phishing.
|
||||
#### **Nuevos dominios**
|
||||
|
||||
**Una última alternativa** es recopilar una lista de **dominios recién registrados** para algunos TLDs ([Whoxy](https://www.whoxy.com/newly-registered-domains/) proporciona ese servicio) y **comprobar las palabras clave en estos dominios**. Sin embargo, los dominios largos normalmente usan uno o más subdominios, por lo que la palabra clave no aparecerá dentro del FLD y no podrás encontrar el subdominio de phishing.
|
||||
|
||||
Heurística adicional: trata ciertos **file-extension TLDs** (p. ej., `.zip`, `.mov`) con mayor sospecha en las alertas. Estos suelen confundirse con nombres de archivo en los lures; combina la señal del TLD con brand keywords y NRD age para mayor precisión.
|
||||
|
||||
## Referencias
|
||||
|
||||
- urlscan.io – Search API reference: https://urlscan.io/docs/search/
|
||||
- APNIC Blog – JA4+ network fingerprinting (incluye ejemplo Evilginx): https://blog.apnic.net/2023/11/22/ja4-network-fingerprinting/
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
@ -24,13 +24,15 @@
|
||||
/* 2 — load a single index (remote → local) */
|
||||
async function loadIndex(remote, local, isCloud=false){
|
||||
let rawLoaded = false;
|
||||
try {
|
||||
const r = await fetch(remote,{mode:'cors'});
|
||||
if (!r.ok) throw new Error('HTTP '+r.status);
|
||||
importScripts(URL.createObjectURL(new Blob([await r.text()],{type:'application/javascript'})));
|
||||
rawLoaded = true;
|
||||
} catch(e){ console.warn('remote',remote,'failed →',e); }
|
||||
if(!rawLoaded){
|
||||
if(remote){
|
||||
try {
|
||||
const r = await fetch(remote,{mode:'cors'});
|
||||
if (!r.ok) throw new Error('HTTP '+r.status);
|
||||
importScripts(URL.createObjectURL(new Blob([await r.text()],{type:'application/javascript'})));
|
||||
rawLoaded = true;
|
||||
} catch(e){ console.warn('remote',remote,'failed →',e); }
|
||||
}
|
||||
if(!rawLoaded && local){
|
||||
try { importScripts(abs(local)); rawLoaded = true; }
|
||||
catch(e){ console.error('local',local,'failed →',e); }
|
||||
}
|
||||
@ -40,13 +42,41 @@
|
||||
return data;
|
||||
}
|
||||
|
||||
async function loadWithFallback(remotes, local, isCloud=false){
|
||||
if(remotes.length){
|
||||
const [primary, ...secondary] = remotes;
|
||||
const primaryData = await loadIndex(primary, null, isCloud);
|
||||
if(primaryData) return primaryData;
|
||||
|
||||
if(local){
|
||||
const localData = await loadIndex(null, local, isCloud);
|
||||
if(localData) return localData;
|
||||
}
|
||||
|
||||
for (const remote of secondary){
|
||||
const data = await loadIndex(remote, null, isCloud);
|
||||
if(data) return data;
|
||||
}
|
||||
}
|
||||
|
||||
return local ? loadIndex(null, local, isCloud) : null;
|
||||
}
|
||||
|
||||
(async () => {
|
||||
const MAIN_RAW = 'https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/refs/heads/master/searchindex.js';
|
||||
const CLOUD_RAW = 'https://raw.githubusercontent.com/HackTricks-wiki/hacktricks-cloud/refs/heads/master/searchindex.js';
|
||||
const htmlLang = (document.documentElement.lang || 'en').toLowerCase();
|
||||
const lang = htmlLang.split('-')[0];
|
||||
const mainReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks/releases/download';
|
||||
const cloudReleaseBase = 'https://github.com/HackTricks-wiki/hacktricks-cloud/releases/download';
|
||||
|
||||
const mainTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master']));
|
||||
const cloudTags = Array.from(new Set([`searchindex-${lang}`, 'searchindex-en', 'searchindex-master']));
|
||||
|
||||
const MAIN_REMOTE_SOURCES = mainTags.map(tag => `${mainReleaseBase}/${tag}/searchindex.js`);
|
||||
const CLOUD_REMOTE_SOURCES = cloudTags.map(tag => `${cloudReleaseBase}/${tag}/searchindex.js`);
|
||||
|
||||
const indices = [];
|
||||
const main = await loadIndex(MAIN_RAW , '/searchindex.js', false); if(main) indices.push(main);
|
||||
const cloud= await loadIndex(CLOUD_RAW, '/searchindex-cloud.js', true ); if(cloud) indices.push(cloud);
|
||||
const main = await loadWithFallback(MAIN_REMOTE_SOURCES , '/searchindex.js', false); if(main) indices.push(main);
|
||||
const cloud= await loadWithFallback(CLOUD_REMOTE_SOURCES, '/searchindex-cloud.js', true ); if(cloud) indices.push(cloud);
|
||||
|
||||
if(!indices.length){ postMessage({ready:false, error:'no-index'}); return; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user