Translated ['src/binary-exploitation/ios-exploiting/ios-physical-uaf-ios

This commit is contained in:
Translator 2025-09-29 23:33:16 +00:00
parent dc8e5cc941
commit 6754a9fdc6
4 changed files with 203 additions and 80 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ book
book/*
hacktricks-preprocessor.log
hacktricks-preprocessor-error.log
searchindex.js

View File

@ -3,15 +3,29 @@
{{#include ../../banners/hacktricks-training.md}}
## iOS Exploit Mitigations
- **Code Signing** no iOS funciona exigindo que cada trecho de código executável (apps, libraries, extensions, etc.) seja criptograficamente assinado com um certificado emitido pela Apple. Quando o código é carregado, o iOS verifica a assinatura digital contra a raiz confiável da Apple. Se a assinatura for inválida, estiver ausente ou tiver sido modificada, o SO se recusa a executá-lo. Isso impede que atacantes injetem código malicioso em apps legítimos ou executem binários não assinados, efetivamente bloqueando a maioria das cadeias de exploit que dependem da execução de código arbitrário ou adulterado.
- **CoreTrust** é o subsistema do iOS responsável por impor a assinatura de código em tempo de execução. Ele verifica diretamente as assinaturas utilizando o certificado raiz da Apple sem depender de caches de confiança, o que significa que apenas binários assinados pela Apple (ou com entitlements válidos) podem ser executados. O CoreTrust garante que mesmo que um atacante tampe com um app após a instalação, modifique libraries do sistema ou tente carregar código não assinado, o sistema bloqueará a execução a menos que o código ainda esteja corretamente assinado. Essa aplicação rígida fecha muitos vetores pós-exploração que versões mais antigas do iOS permitiam através de verificações de assinatura mais fracas ou contornáveis.
- **Data Execution Prevention (DEP)** marca regiões de memória como não-executáveis a menos que contenham explicitamente código. Isso impede que atacantes injetem shellcode em regiões de dados (como stack ou heap) e o executem, forçando-os a depender de técnicas mais complexas como ROP (Return-Oriented Programming).
- **ASLR (Address Space Layout Randomization)** randomiza os endereços de memória de código, libraries, stack e heap a cada execução do sistema. Isso torna muito mais difícil para atacantes preverem onde instruções úteis ou gadgets estão, quebrando muitas cadeias de exploit que dependem de layouts de memória fixos.
- **KASLR (Kernel ASLR)** aplica o mesmo conceito de randomização ao kernel do iOS. Ao embaralhar o endereço base do kernel a cada boot, impede que atacantes localizem de forma confiável funções ou estruturas do kernel, aumentando a dificuldade de exploits em nível de kernel que visariam obter controle total do sistema.
- **Kernel Patch Protection (KPP)** também conhecido como **AMCC (Apple Mobile File Integrity)** no iOS, monitora continuamente as páginas de código do kernel para garantir que elas não foram modificadas. Se qualquer adulteração for detectada — como um exploit tentando patchar funções do kernel ou inserir código malicioso — o dispositivo entrará imediatamente em panic e reiniciará. Essa proteção torna exploits persistentes no kernel muito mais difíceis, pois atacantes não podem simplesmente hookar ou patchar instruções do kernel sem causar um crash do sistema.
- **Kernel Text Readonly Region (KTRR)** é uma funcionalidade de segurança baseada em hardware introduzida em dispositivos iOS. Ela usa o controlador de memória da CPU para marcar a seção de código (text) do kernel como permanentemente somente leitura após o boot. Uma vez bloqueada, até o próprio kernel não pode modificar essa região de memória. Isso impede que atacantes — e mesmo código privilegiado — façam patchs nas instruções do kernel em tempo de execução, fechando uma grande classe de exploits que dependiam de modificar diretamente o código do kernel.
- **Pointer Authentication Codes (PAC)** usam assinaturas criptográficas embutidas em bits não utilizados de pointers para verificar sua integridade antes do uso. Quando um pointer (como um endereço de retorno ou function pointer) é criado, a CPU o assina com uma chave secreta; antes de desreferenciar, a CPU verifica a assinatura. Se o pointer tiver sido adulterado, a verificação falha e a execução é interrompida. Isso impede que atacantes forjem ou reutilizem pointers corrompidos em exploits de corrupção de memória, tornando técnicas como ROP ou JOP muito mais difíceis de executar com confiabilidade.
- **Privilege Access never (PAN)** é uma funcionalidade de hardware que previne que o kernel (modo privilegiado) acesse diretamente a memória do user-space a menos que ative explicitamente esse acesso. Isso impede que atacantes que obtiveram execução de código no kernel leiam ou escrevam facilmente na memória do usuário para escalar privilégios ou roubar dados sensíveis. Ao reforçar a separação estrita, o PAN reduz o impacto de exploits no kernel e bloqueia muitas técnicas comuns de escalonamento de privilégios.
- **Page Protection Layer (PPL)** é um mecanismo de segurança do iOS que protege regiões críticas gerenciadas pelo kernel, especialmente aquelas relacionadas a code signing e entitlements. Ele aplica proteções rígidas de escrita usando a MMU (Memory Management Unit) e verificações adicionais, garantindo que mesmo código privilegiado do kernel não possa modificar arbitrariamente páginas sensíveis. Isso impede que atacantes que obtenham execução em nível de kernel temperem com estruturas críticas de segurança, tornando persistência e bypasses de code-signing significativamente mais difíceis.
## Physical use-after-free
Este é um resumo do post [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html); mais informações sobre exploits que usam esta técnica podem ser encontradas em [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
Este é um resumo do post em [https://alfiecg.uk/2024/09/24/Kernel-exploit.html](https://alfiecg.uk/2024/09/24/Kernel-exploit.html); além disso, mais informações sobre exploits que usam esta técnica podem ser encontradas em [https://github.com/felix-pb/kfd](https://github.com/felix-pb/kfd)
### Gerenciamento de memória no XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
### Memory management in XNU <a href="#memory-management-in-xnu" id="memory-management-in-xnu"></a>
O **espaço de endereçamento de memória virtual** para processos de usuário no iOS vai de **0x0 até 0x8000000000**. No entanto, esses endereços não mapeiam diretamente para memória física. Em vez disso, o **kernel** usa **page tables** para traduzir endereços virtuais em endereços **físicos** reais.
O **espaço de endereço de memória virtual** para processos de usuário no iOS vai de **0x0 a 0x8000000000**. No entanto, esses endereços não mapeiam diretamente para memória física. Em vez disso, o **kernel** usa **page tables** para traduzir endereços virtuais em endereços **físicos** reais.
#### Níveis das page tables no iOS
#### Levels of Page Tables in iOS
As page tables são organizadas hierarquicamente em três níveis:
@ -20,76 +34,76 @@ As page tables são organizadas hierarquicamente em três níveis:
* Cobre **0x1000000000 bytes** (ou **256 GB**) de memória virtual.
2. **L2 Page Table (Level 2)**:
* Uma entrada aqui representa uma região menor de memória virtual, especificamente **0x2000000 bytes** (32 MB).
* Uma entrada L1 pode apontar para uma tabela L2 se não puder mapear toda a região por si só.
* Uma entrada L1 pode apontar para uma tabela L2 se não conseguir mapear toda a região por si só.
3. **L3 Page Table (Level 3)**:
* Este é o nível mais fino, onde cada entrada mapeia uma única página de memória de **4 KB**.
* Este é o nível mais fino, onde cada entrada mapeia uma única página de **4 KB**.
* Uma entrada L2 pode apontar para uma tabela L3 se for necessário controle mais granular.
#### Mapeamento de virtual para memória física
#### Mapping Virtual to Physical Memory
* **Direct Mapping (Block Mapping)**:
* Algumas entradas em uma page table mapeiam diretamente uma faixa de endereços virtuais para uma faixa contígua de endereços físicos (como um atalho).
* **Pointer to Child Page Table**:
* Se for necessário controle mais fino, uma entrada em um nível (por exemplo, L1) pode apontar para uma **child page table** no próximo nível (por exemplo, L2).
#### Exemplo: Mapeando um endereço virtual
#### Example: Mapping a Virtual Address
Digamos que você tente acessar o endereço virtual **0x1000000000**:
Suponha que você tente acessar o endereço virtual **0x1000000000**:
1. **L1 Table**:
* O kernel verifica a entrada correspondente na L1. Se ela contiver um **pointer to an L2 page table**, vai para essa L2.
* O kernel verifica a entrada da L1 page table correspondente a esse endereço virtual. Se ela tiver um **pointer para uma L2 page table**, o kernel vai para essa L2.
2. **L2 Table**:
* O kernel verifica a L2 para um mapeamento mais detalhado. Se essa entrada apontar para uma **L3 page table**, prossegue para lá.
* O kernel verifica a L2 page table para um mapeamento mais detalhado. Se essa entrada apontar para uma **L3 page table**, ele prossegue até lá.
3. **L3 Table**:
* O kernel consulta a entrada final L3, que aponta para o **endereço físico** da página de memória real.
* O kernel procura a entrada final L3, que aponta para o **endereço físico** da página de memória real.
#### Exemplo de mapeamento de endereço
#### Example of Address Mapping
Se você escrever o endereço físico **0x800004000** no primeiro índice da tabela L2, então:
* Endereços virtuais de **0x1000000000** a **0x1002000000** mapeiam para endereços físicos de **0x800004000** a **0x802004000**.
* Endereços virtuais de **0x1000000000** a **0x1002000000** mapeiam para endereços físicos de **0x800004000** a **0x802004000**.
* Isso é um **block mapping** no nível L2.
Alternativamente, se a entrada L2 apontar para uma tabela L3:
* Cada página de 4 KB na faixa virtual **0x1000000000 -> 0x1002000000** seria mapeada por entradas individuais na tabela L3.
* Cada página de 4 KB no intervalo virtual **0x1000000000 -> 0x1002000000** seria mapeada por entradas individuais na tabela L3.
### Physical use-after-free
Um **physical use-after-free** (UAF) ocorre quando:
1. Um processo **aloca** alguma memória como **readable and writable**.
1. Um processo **aloca** alguma memória como **readable e writable**.
2. As **page tables** são atualizadas para mapear essa memória para um endereço físico específico que o processo pode acessar.
3. O processo **desaloca** (libera) a memória.
3. O processo **desaloca** (free) a memória.
4. Porém, devido a um **bug**, o kernel **esquece de remover o mapeamento** das page tables, mesmo marcando a memória física correspondente como livre.
5. O kernel pode então **realocar essa memória física "liberada"** para outros fins, como **kernel data**.
5. O kernel pode então **realocar essa memória física "liberada"** para outros propósitos, como **dados do kernel**.
6. Como o mapeamento não foi removido, o processo ainda pode **ler e escrever** nessa memória física.
Isso significa que o processo pode acessar **páginas de memória do kernel**, que podem conter dados sensíveis ou estruturas, potencialmente permitindo que um atacante **manipule memória do kernel**.
Isso significa que o processo pode acessar **páginas de memória do kernel**, que podem conter dados sensíveis ou estruturas, potencialmente permitindo que um atacante **manipule a memória do kernel**.
### IOSurface Heap Spray
Como o atacante não controla quais páginas do kernel serão alocadas para a memória liberada, ele usa uma técnica chamada **heap spray**:
1. O atacante **cria um grande número de objetos IOSurface** na memória do kernel.
2. Cada objeto IOSurface contém um **magic value** em um de seus campos, tornando-o fácil de identificar.
3. Eles **varrem as páginas liberadas** para ver se algum desses objetos IOSurface caiu em uma página liberada.
4. Quando encontram um objeto IOSurface em uma página liberada, podem usá-lo para **ler e escrever memória do kernel**.
2. Cada objeto IOSurface contém um **valor mágico** em um de seus campos, tornando-o fácil de identificar.
3. Eles **escaneiam as páginas liberadas** para ver se algum desses objetos IOSurface caiu em uma página liberada.
4. Quando encontram um objeto IOSurface em uma página liberada, podem usá-lo para **ler e escrever a memória do kernel**.
Mais informações sobre isso em [https://github.com/felix-pb/kfd/tree/main/writeups](https://github.com/felix-pb/kfd/tree/main/writeups)
> [!TIP]
> Tenha em mente que dispositivos iOS 16+ (A12+) trazem mitigações de hardware (como PPL ou SPTM) que tornam técnicas de physical UAF muito menos viáveis.
> PPL aplica proteções MMU estritas em páginas relacionadas a code signing, entitlements e dados sensíveis do kernel; assim, mesmo que uma página seja reutilizada, escritas vindas do userland ou de código do kernel comprometido para páginas protegidas por PPL são bloqueadas.
> Secure Page Table Monitor (SPTM) estende o PPL ao endurecer as próprias atualizações de page tables. Ele garante que até mesmo código privilegiado do kernel não possa remapear silenciosamente páginas liberadas ou manipular mapeamentos sem passar por checagens seguras.
> KTRR (Kernel Text Read-Only Region) tranca a seção de código do kernel como read-only após o boot. Isso previne modificações em tempo de execução do código do kernel, fechando um vetor de ataque majoritário que exploits de physical UAF costumam explorar.
> Além disso, alocações de `IOSurface` são menos previsíveis e mais difíceis de mapear em regiões acessíveis por usuário, o que torna o truque de “magic value scanning” muito menos confiável. E `IOSurface` agora é protegido por entitlements e restrições de sandbox.
> Esteja ciente de que dispositivos iOS 16+ (A12+) trazem mitigations de hardware (como PPL ou SPTM) que tornam técnicas de physical UAF muito menos viáveis.
> PPL impõe proteções MMU estritas em páginas relacionadas a code signing, entitlements e dados sensíveis do kernel, então, mesmo que uma página seja reutilizada, writes vindos do userland ou de código de kernel comprometido para páginas protegidas por PPL são bloqueados.
> Secure Page Table Monitor (SPTM) estende o PPL endurecendo as próprias atualizações de page table. Ele garante que mesmo código privilegiado do kernel não possa remapear silenciosamente páginas liberadas ou tamperar com mapeamentos sem passar por verificações seguras.
> KTRR (Kernel Text Read-Only Region) tranca a seção de código do kernel como somente leitura após o boot. Isso previne qualquer modificação em tempo de execução ao código do kernel, fechando um grande vetor de ataque que exploits de physical UAF frequentemente exploram.
> Além disso, alocações de `IOSurface` são menos previsíveis e mais difíceis de mapear para regiões acessíveis ao usuário, o que torna o truque de "escaneamento por valor mágico" muito menos confiável. E `IOSurface` agora é protegido por entitlements e restrições de sandbox.
### Processo passo a passo do Heap Spray
### Step-by-Step Heap Spray Process
1. **Spray IOSurface Objects**: O atacante cria muitos objetos IOSurface com um identificador especial ("magic value").
2. **Scan Freed Pages**: Eles verificam se algum dos objetos foi alocado em uma página liberada.
3. **Read/Write Kernel Memory**: Ao manipular campos no objeto IOSurface, obtêm a capacidade de realizar **arbitrary reads and writes** na memória do kernel. Isso permite:
3. **Read/Write Kernel Memory**: Manipulando campos no objeto IOSurface, eles obtêm a habilidade de realizar **reads e writes arbitrários** na memória do kernel. Isso permite:
* Usar um campo para **ler qualquer valor 32-bit** na memória do kernel.
* Usar outro campo para **escrever valores 64-bit**, alcançando um primitivo estável de **kernel read/write**.
@ -114,7 +128,7 @@ io_connect_t id = result.surface_id;
}
}
```
Procurar por objetos **`IOSurface`** em uma página física liberada:
Buscar objetos **`IOSurface`** em uma página física liberada:
```c
int iosurface_krw(io_connect_t client, uint64_t *puafPages, int nPages, uint64_t *self_task, uint64_t *puafPage) {
io_connect_t *surfaceIDs = malloc(sizeof(io_connect_t) * 0x4000);
@ -148,25 +162,25 @@ free(surfaceIDs);
return 0;
}
```
### Alcançando Leitura/Escrita no Kernel com IOSurface
### Obtendo Leitura/Escrita no Kernel com IOSurface
Depois de obter controle sobre um objeto IOSurface na memória do kernel (mapeado para uma página física liberada acessível a partir do userspace), podemos usá-lo para operações arbitrárias de leitura e escrita no kernel.
Depois de obter controle sobre um objeto IOSurface na memória do kernel (mapeado para uma página física liberada acessível do userspace), podemos usá-lo para **operações arbitrárias de leitura e escrita no kernel**.
**Key Fields in IOSurface**
**Campos-chave no IOSurface**
O objeto IOSurface possui dois campos cruciais:
O objeto IOSurface tem dois campos cruciais:
1. **Use Count Pointer**: Permite uma leitura de **32 bits**.
2. **Indexed Timestamp Pointer**: Permite uma escrita de **64 bits**.
1. **Use Count Pointer**: Permite uma **leitura de 32 bits**.
2. **Indexed Timestamp Pointer**: Permite uma **escrita de 64 bits**.
Ao sobrescrever esses ponteiros, os redirecionamos para endereços arbitrários na memória do kernel, habilitando operações de leitura/escrita.
Ao sobrescrever esses ponteiros, redirecionamos-os para endereços arbitrários na memória do kernel, habilitando capacidades de leitura/escrita.
#### Leitura de kernel de 32 bits
#### Leitura de 32 bits no Kernel
Para realizar uma leitura:
1. Sobrescreva o **use count pointer** para apontar para o endereço alvo menos um deslocamento de 0x14 bytes.
2. Use o método `get_use_count` para ler o valor naquele endereço.
1. Sobrescreva o **Use Count Pointer** para apontar para o endereço alvo menos um deslocamento de 0x14 bytes.
2. Use o método `get_use_count` para ler o valor nesse endereço.
```c
uint32_t get_use_count(io_connect_t client, uint32_t surfaceID) {
uint64_t args[1] = {surfaceID};
@ -184,11 +198,11 @@ iosurface_set_use_count_pointer(info.object, orig);
return value;
}
```
#### Escrita no kernel de 64 bits
#### Escrita de 64 bits no kernel
Para realizar uma escrita:
1. Sobrescreva o **indexed timestamp pointer** com o endereço alvo.
1. Sobrescreva o **ponteiro de timestamp indexado** com o endereço de destino.
2. Use o método `set_indexed_timestamp` para escrever um valor de 64 bits.
```c
void set_indexed_timestamp(io_connect_t client, uint32_t surfaceID, uint64_t value) {
@ -203,13 +217,13 @@ set_indexed_timestamp(info.client, info.surface, value);
iosurface_set_indexed_timestamp_pointer(info.object, orig);
}
```
#### Recapitulação do Fluxo do Exploit
#### Resumo do fluxo do exploit
1. **Trigger Physical Use-After-Free**: Páginas liberadas ficam disponíveis para reutilização.
2. **Spray IOSurface Objects**: Alocar muitos objetos IOSurface com um "magic value" único na memória do kernel.
3. **Identify Accessible IOSurface**: Localizar um IOSurface em uma página liberada que você controla.
4. **Abuse Use-After-Free**: Modificar ponteiros no objeto IOSurface para permitir **kernel read/write** arbitrários via métodos do IOSurface.
4. **Abuse Use-After-Free**: Modificar ponteiros no objeto IOSurface para habilitar **leitura/escrita no kernel** arbitrária via métodos do IOSurface.
Com essas primitivas, o exploit fornece **32-bit reads** controladas e **64-bit writes** para a memória do kernel. Passos adicionais do jailbreak podem envolver primitivos de leitura/escrita mais estáveis, os quais podem requerer contornar proteções adicionais (por exemplo, PPL em dispositivos arm64e mais novos).
Com esses primitivos, o exploit fornece **leituras de 32 bits** controladas e **gravações de 64 bits** na memória do kernel. Passos subsequentes de jailbreak podem envolver primitivas de leitura/gravação mais estáveis, que podem requerer contornar proteções adicionais (por exemplo, PPL em dispositivos arm64e mais novos).
{{#include ../../banners/hacktricks-training.md}}

View File

@ -4,66 +4,144 @@
## Introdução
Para detectar uma tentativa de phishing, é importante **entender as técnicas de phishing que estão sendo usadas atualmente**. Na página principal deste post, você pode encontrar essas informações, então, se você não está ciente de quais técnicas estão sendo usadas hoje, recomendo que você vá para a página principal e leia pelo menos essa seção.
Para detectar uma tentativa de phishing é importante **entender as técnicas de phishing que estão sendo usadas atualmente**. Na página pai deste post, você pode encontrar essa informação, então se você não está ciente de quais técnicas são usadas hoje eu recomendo que vá à página pai e leia pelo menos essa seção.
Este post é baseado na ideia de que os **atacantes tentarão de alguma forma imitar ou usar o nome de domínio da vítima**. Se seu domínio se chama `example.com` e você é alvo de phishing usando um nome de domínio completamente diferente, como `youwonthelottery.com`, essas técnicas não vão descobri-lo.
Este post é baseado na ideia de que os **atacantes tentarão de alguma forma imitar ou usar o nome de domínio da vítima**. Se o seu domínio se chama `example.com` e você é phishado usando um nome de domínio completamente diferente por alguma razão como `youwonthelottery.com`, essas técnicas não irão revelar.
## Variações de nomes de domínio
É meio **fácil** **descobrir** aquelas tentativas de **phishing** que usarão um **nome de domínio similar** dentro do e-mail.\
Basta **gerar uma lista dos nomes de phishing mais prováveis** que um atacante pode usar e **verificar** se está **registrado** ou apenas verificar se há algum **IP** usando-o.
É meio **fácil** **descobrir** aquelas tentativas de **phishing** que vão usar um **domínio similar** dentro do email.\
Basta **gerar uma lista dos nomes de phishing mais prováveis** que um atacante pode usar e **verificar** se ele está **registrado** ou apenas checar se há algum **IP** usando-o.
### Encontrando domínios suspeitos
Para isso, você pode usar qualquer uma das seguintes ferramentas. Observe que essas ferramentas também realizarão solicitações DNS automaticamente para verificar se o domínio tem algum IP atribuído a ele:
Para esse propósito, você pode usar qualquer uma das seguintes ferramentas. Note que essas ferramentas também irão realizar requisições DNS automaticamente para checar se o domínio tem algum IP atribuído:
- [**dnstwist**](https://github.com/elceef/dnstwist)
- [**urlcrazy**](https://github.com/urbanadventurer/urlcrazy)
Dica: Se você gerar uma lista de candidatos, também alimente-a nos seus logs de resolver DNS para detectar buscas NXDOMAIN de dentro da sua org (usuários tentando alcançar um erro de digitação antes do atacante realmente registrá-lo). Faça sinkhole ou bloqueie preventivamente esses domínios se a política permitir.
### Bitflipping
**Você pode encontrar uma breve explicação dessa técnica na página principal. Ou ler a pesquisa original em** [**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/)
**Você pode encontrar uma breve explicação desta técnica na página pai. Ou leia a pesquisa original em** [**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 exemplo, uma modificação de 1 bit no domínio microsoft.com pode transformá-lo em _windnws.com._\
**Os atacantes podem registrar o maior número possível de domínios de bit-flipping relacionados à vítima para redirecionar usuários legítimos para sua infraestrutura**.
**Atacantes podem registrar quantos domínios bit-flipping relacionados à vítima quanto possível para redirecionar usuários legítimos para sua infraestrutura**.
**Todos os possíveis nomes de domínio de bit-flipping também devem ser monitorados.**
**Todos os possíveis nomes de domínio bit-flipping também devem ser monitorados.**
Se você também precisa considerar lookalikes homoglyph/IDN (por exemplo, misturar caracteres Latin/Cyrillic), verifique:
{{#ref}}
homograph-attacks.md
{{#endref}}
### Verificações básicas
Uma vez que você tenha uma lista de nomes de domínio potencialmente suspeitos, você deve **verificá-los** (principalmente as portas HTTP e HTTPS) para **ver se estão usando algum formulário de login similar** ao de algum domínio da vítima.\
Você também pode verificar a porta 3333 para ver se está aberta e executando uma instância de `gophish`.\
É interessante saber **quão antigos são cada um dos domínios suspeitos descobertos**, quanto mais jovem, mais arriscado é.\
Você também pode obter **capturas de tela** da página da web suspeita em HTTP e/ou HTTPS para ver se é suspeita e, nesse caso, **acessá-la para dar uma olhada mais profunda**.
Uma vez que você tenha uma lista de nomes de domínio potencialmente suspeitos você deve **verificá-los** (principalmente as portas HTTP e HTTPS) para **ver se estão usando algum formulário de login similar** ao de algum domínio da vítima.\
Você também poderia checar a porta 3333 para ver se está aberta e rodando uma instância de `gophish`.\
Também é interessante saber **quão antigo cada domínio suspeito descoberto é**, quanto mais jovem, mais arriscado.\
Você também pode obter **capturas de tela** da página web HTTP e/ou HTTPS suspeita para ver se é suspeita e, nesse caso, **acessá-la para olhar mais a fundo**.
### Verificações avançadas
Se você quiser ir um passo além, eu recomendaria que você **monitore esses domínios suspeitos e busque mais** de vez em quando (todo dia? só leva alguns segundos/minutos). Você também deve **verificar** as **portas** abertas dos IPs relacionados e **procurar instâncias de `gophish` ou ferramentas similares** (sim, os atacantes também cometem erros) e **monitorar as páginas da web HTTP e HTTPS dos domínios e subdomínios suspeitos** para ver se copiaram algum formulário de login das páginas da web da vítima.\
Para **automatizar isso**, eu recomendaria ter uma lista de formulários de login dos domínios da vítima, rastrear as páginas da web suspeitas e comparar cada formulário de login encontrado dentro dos domínios suspeitos com cada formulário de login do domínio da vítima usando algo como `ssdeep`.\
Se você localizou os formulários de login dos domínios suspeitos, pode tentar **enviar credenciais falsas** e **verificar se está redirecionando você para o domínio da vítima**.
Se você quiser ir um passo além eu recomendaria **monitorar esses domínios suspeitos e procurar por mais** de vez em quando (todo dia? leva apenas alguns segundos/minutos). Você também deveria **verificar** as **portas abertas** dos IPs relacionados e **procurar por instâncias de `gophish` ou ferramentas similares** (sim, atacantes também cometem erros) e **monitorar as páginas HTTP e HTTPS dos domínios e subdomínios suspeitos** para ver se copiaram algum formulário de login das páginas da vítima.\
Para **automatizar isso** eu recomendaria ter uma lista de formulários de login dos domínios da vítima, spiderar as páginas suspeitas e comparar cada formulário de login encontrado dentro dos domínios suspeitos com cada formulário de login do domínio da vítima usando algo como `ssdeep`.\
Se você localizou os formulários de login dos domínios suspeitos, você pode tentar **enviar credenciais inválidas** e **checar se está redirecionando você para o domínio da vítima**.
## Nomes de domínio usando palavras-chave
---
### Hunting by favicon and web fingerprints (Shodan/ZoomEye/Censys)
Many phishing kits reuse favicons from the brand they impersonate. Internet-wide scanners compute a MurmurHash3 of the base64-encoded favicon. You can generate the hash and pivot on it:
Python example (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
```
- Consultar o Shodan: `http.favicon.hash:309020573`
- Com ferramentas: use ferramentas da comunidade como favfreak para gerar hashes e dorks para Shodan/ZoomEye/Censys.
Notas
- Favicons são reutilizados; trate correspondências como pistas e valide o conteúdo e os certificados antes de agir.
- Combine com heurísticas de idade do domínio e palavras-chave para maior precisão.
### Investigação de telemetria de URL (urlscan.io)
`urlscan.io` armazena capturas de tela históricas, DOM, requisições e metadados TLS das URLs submetidas. Você pode investigar abuso de marca e clones:
Example queries (UI or API):
- Encontre similares excluindo seus domínios legítimos: `page.domain:(/.*yourbrand.*/ AND NOT yourbrand.com AND NOT www.yourbrand.com)`
- Encontre sites que fazem hotlink aos seus ativos: `domain:yourbrand.com AND NOT page.domain:yourbrand.com`
- Restrinja a resultados recentes: acrescente `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 do JSON, foque em:
- `page.tlsIssuer`, `page.tlsValidFrom`, `page.tlsAgeDays` para identificar certificados muito novos usados em lookalikes
- `task.source` com valores como `certstream-suspicious` para vincular as descobertas ao monitoramento CT
### Idade do domínio via RDAP (scriptável)
O RDAP retorna eventos de criação legíveis por máquina. Útil para sinalizar **domínios recém-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
```
Enriqueça seu pipeline marcando domínios com faixas de idade de registro (por exemplo, <7 dias, <30 dias) e priorize a triagem de acordo.
### TLS/JAx fingerprints to spot AiTM infrastructure
O phishing de credenciais moderno usa cada vez mais **Adversary-in-the-Middle (AiTM)** reverse proxies (por exemplo, Evilginx) para roubar session tokens. Você pode adicionar detecções no lado da rede:
- Registre TLS/HTTP fingerprints (JA3/JA4/JA4S/JA4H) na saída de rede. Algumas builds do Evilginx foram observadas com valores JA4 cliente/servidor estáveis. Gere alertas apenas para fingerprints conhecidos como maliciosos como um sinal fraco e sempre confirme com análise de conteúdo e inteligência de domínio.
- Registre proativamente metadados de certificados TLS (issuer, contagem de SAN, uso de wildcard, validade) para hosts lookalike descobertos via CT ou urlscan e correlate com idade do DNS e geolocalização.
> Nota: Trate fingerprints como enriquecimento, não como bloqueadores exclusivos; frameworks evoluem e podem randomizar ou ofuscar.
### Domain names using keywords
A página principal também menciona uma técnica de variação de nome de domínio que consiste em colocar o **nome de domínio da vítima dentro de um domínio maior** (por exemplo, paypal-financial.com para paypal.com).
### Transparência de Certificado
#### Certificate Transparency
Não é possível adotar a abordagem anterior de "Força Bruta", mas é **possível descobrir tais tentativas de phishing** também graças à transparência de certificado. Sempre que um certificado é emitido por uma CA, os detalhes são tornados públicos. Isso significa que, ao ler a transparência de certificado ou até mesmo monitorá-la, é **possível encontrar domínios que estão usando uma palavra-chave dentro de seu nome**. Por exemplo, se um atacante gera um certificado de [https://paypal-financial.com](https://paypal-financial.com), ao ver o certificado, é possível encontrar a palavra-chave "paypal" e saber que um e-mail suspeito está sendo usado.
Não é possível adotar a abordagem anterior "Brute-Force", mas na verdade é **possível descobrir essas tentativas de phishing** também graças ao Certificate Transparency. Toda vez que um certificado é emitido por uma CA, os detalhes são tornados públicos. Isso significa que, ao ler o Certificate Transparency ou mesmo monitorá-lo, é **possível encontrar domínios que estão usando uma palavra-chave dentro do seu nome**. Por exemplo, se um atacante gera um certificado de [https://paypal-financial.com](https://paypal-financial.com), ao ver o certificado é possível encontrar a palavra-chave "paypal" e saber que um e-mail suspeito está sendo usado.
O post [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) sugere que você pode usar o Censys para procurar certificados que afetam uma palavra-chave específica e filtrar por data (apenas "novos" certificados) e pelo emissor CA "Let's Encrypt":
O post [https://0xpatrik.com/phishing-domains/](https://0xpatrik.com/phishing-domains/) sugere que você pode usar Censys para buscar certificados contendo uma palavra-chave específica e filtrar por data (apenas certificados "novos") e pelo emissor CA "Let's Encrypt":
![https://0xpatrik.com/content/images/2018/07/cert_listing.png](<../../images/image (1115).png>)
No entanto, você pode fazer "o mesmo" usando o site gratuito [**crt.sh**](https://crt.sh). Você pode **procurar pela palavra-chave** e **filtrar** os resultados **por data e CA**, se desejar.
No entanto, você pode fazer "o mesmo" usando a web gratuita [**crt.sh**](https://crt.sh). Você pode **buscar pela palavra-chave** e **filtrar** os resultados **por data e CA** se quiser.
![](<../../images/image (519).png>)
Usando essa última opção, você pode até usar o campo Identidades Correspondentes para ver se alguma identidade do domínio real corresponde a algum dos domínios suspeitos (note que um domínio suspeito pode ser um falso positivo).
Usando essa última opção você pode até usar o campo Matching Identities para ver se alguma identidade do domínio real bate com algum dos domínios suspeitos (note que um domínio suspeito pode ser um falso positivo).
**Outra alternativa** é o fantástico projeto chamado [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067). O CertStream fornece um fluxo em tempo real de certificados recém-gerados que você pode usar para detectar palavras-chave especificadas em (quase) tempo real. De fato, há um projeto chamado [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) que faz exatamente isso.
**Outra alternativa** é o fantástico projeto chamado [**CertStream**](https://medium.com/cali-dog-security/introducing-certstream-3fc13bb98067). CertStream fornece um stream em tempo real de certificados recém-gerados que você pode usar para detectar palavras-chave especificadas em (quase) tempo real. Na verdade, existe um projeto chamado [**phishing_catcher**](https://github.com/x0rz/phishing_catcher) que faz exatamente isso.
### **Novos domínios**
Dica prática: ao triar hits de CT, priorize NRDs, registrars não confiáveis/desconhecidos, WHOIS com proxy de privacidade e certs com `NotBefore` muito recentes. Mantenha uma allowlist dos seus domínios/marcas para reduzir ruído.
**Uma última alternativa** é reunir uma lista de **domínios recém-registrados** para alguns TLDs ([Whoxy](https://www.whoxy.com/newly-registered-domains/) fornece tal serviço) e **verificar as palavras-chave nesses domínios**. No entanto, domínios longos geralmente usam um ou mais subdomínios, portanto, a palavra-chave não aparecerá dentro do FLD e você não conseguirá encontrar o subdomínio de phishing.
#### **Novos domínios**
**Uma última alternativa** é coletar uma lista de **domínios recém-registrados** para alguns TLDs ([Whoxy](https://www.whoxy.com/newly-registered-domains/) fornece esse serviço) e **verificar palavras-chave nesses domínios**. No entanto, domínios longos geralmente usam um ou mais subdomínios, portanto a palavra-chave não aparecerá dentro do FLD e você não conseguirá encontrar o subdomínio de phishing.
Heurística adicional: trate certos **file-extension TLDs** (por exemplo, `.zip`, `.mov`) com suspeita adicional nos alertas. Estes costumam ser confundidos com nomes de arquivo em iscas; combine o sinal do TLD com palavras-chave da marca e idade NRD para melhor precisão.
## References
- urlscan.io Search API reference: https://urlscan.io/docs/search/
- APNIC Blog JA4+ network fingerprinting (includes Evilginx example): https://blog.apnic.net/2023/11/22/ja4-network-fingerprinting/
{{#include ../../banners/hacktricks-training.md}}

View File

@ -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; }