Introdução
No dia 19 de março de 2026, o Grupo de Inteligência de Ameaças da Google (GTIG) e análises simultâneas do Lookout e do iVerify divulgaram o DarkSword, que é um kit de exploração iOS de um clique que liga six vulnerabilidades para levar um iPhone totalmente atualizado até recentemente da condição de “clicou em um link malicioso” para a situação de “o atacante tem acesso de leitura e gravação no kernel” em segundos. Três das seis falhas eram zero-days no momento da divulgação. A cadeia inteira é escrita em JavaScript, sem nenhum shellcode nativo, o que era suficientemente incomum para merecer um post separado por isso.
Este artigo é o primeiro de dois. Aqui nós caminhamos através da parte da exploração do navegador do DarkSword com as etapas 1 até 3, terminando no momento em que o atacante consegue sair do processo de renderização do Safari. A escalada para o kernel (etapas 4 e 5) será abordada em um post subsequente.
O público-alvo ao qual estamos escrevendo: engenheiros de segurança móvel, pentesters e estudantes que estão confortáveis com fundamentos de segurança móvel mas nunca sentaram para trabalhar com uma cadeia de exploração do navegador antes. Vamos ser específicos sobre as partes com fatos como nomes de processos, níveis WebKit, instruções ARM reais, quais arquivos no kit de exploração fazem o quê e tudo isso sem assumir conhecimento prévio dos detalhes internos do renderizador. Se um termo te atrapalhar, a glossário abaixo tem você coberto.
Glossário Rápido
Reliça uma vez e volte para ele conforme necessário.
- WebContent — o processo iOS Safari (
com.apple.WebKit.WebContent) que realmente renderiza a página: analisa HTML, aplica CSS, executa JavaScript. Muito sandboxado. Frequentemente chamado de renderer. - GPU process — o processo separado Safari (
com.apple.WebKit.GPU) para desenho acelerado por hardware e WebGL. Sandbox mais flexível do que WebContent; o alvo da fuga de estágio 3. - JavaScriptCore (JSC) — o motor JavaScript open-source da Apple, executando dentro de cada instância WebContent.
- JIT (Just-In-Time compilador) — componente que transforma JavaScript frequentemente executado em código nativo ARM64 em tempo real.
- Tiers do JSC: LLInt → Baseline → DFG → FTL — os quatro níveis de execução do JSC, desde interpretação lenta mas segura até código nativo altamente otimizado. As falhas JIT DarkSword vivem no nível DFG.
- Type confusion — uma classe de bug onde o motor trata um valor como sendo do tipo errado; em um JIT, caminho clássico para R/W de memória bruta.
addrof/fakeobj— duas primitivas que toda exploração de motor JS constrói primeiro.addrof(x)vaza o endereço de memória do objeto JSx.fakeobj(a)faz com que o motor trate o endereçoacomo se fosse um objeto JS.- Sandbox — gaiola restritiva impulsionada pelo SO limitando o que um processo pode fazer (filesystem, rede, IPC, syscalls). Cada processo WebKit roda sob um perfil de sandbox dedicado.
- Fuga do Sandbox — mudança de um processo mais sandboxado para outro menos sandboxado (ou sem sandbox), geralmente através de uma falha em um ponto final de IPC exposto pelo alvo.
- XPC / Mach messages — a infraestrutura de IPC que os sistemas Apple usam para comunicação interprocesso. WebContent se comunica com o processo GPU por XPC.
- PAC (Pointer Authentication Codes) — um recurso do ARMv8.3-A usado amplamente na silício A12+. Ponteiros de função carregam uma assinatura criptográfica (incorporada em seus bits mais altos); a CPU recusa-se a pular por meio de um ponteiro cuja assinatura não confere.
- PPL / SPTM — Page Protection Layer e Secure Page Table Monitor. Mitigações que tornam caro demais executar código nativo introduzido pelo atacante. São a razão pela qual DarkSword permanece em JavaScript puro.
- ANGLE — Almost Native Graphics Layer Engine. A camada de tradução open-source que transforma chamadas WebGL 1/2 no verdadeiro API gráfica da plataforma (Metal no iOS). Originalmente do projeto Chromium da Google; usado também pelo Safari/WebKit.
- OOB (Out-of-Bounds) write — escrita de memória que você não possui. Primitiva clássica de corrupção de memória.
- Zero-click vs one-click — as explorações zero-click disparam sem interação do usuário (por exemplo, iMessage). One-click requer um único toque, geralmente em um link — que é o que DarkSword faz.
- Watering hole — o atacante compromete, spoofa ou compra tráfego para um site onde a audiência-alvo provavelmente visitará e planta a exploração lá em vez de ir atrás dos alvos individualmente.
O que é DarkSword?
DarkSword é um kit de watering hole one-click, onde uma vítima toca em um link para um site comprometido ou parecido, a página carrega silenciosamente um carregador JavaScript obfuscado e, antes que o carregador termine de sondar o dispositivo, já escolheu e disparou a carga útil correta da exploração.
- Atingido: iOS 18.4 até 18.7, com iOS 18.4 – 18.6.2 sendo mais afetado (esses dispositivos não tinham as primeiras correções do WebKit e kernel lançadas no final de 2025). iOS 18.7 foi inicialmente parcialmente vulnerável, e um módulo separado
rce_worker_18.7.jsera necessário para alvejá-lo. - Distribuição: site comprometido →
<iframe>oculto →frame.html→rce_loader.js→ explotação específica da versão. - Atrito único: cada etapa é escrita em puro JavaScript. A maioria das cadeias de exploração do iOS eventualmente carrega shellcode nativo ARM64, o que significa que elas precisam derrotar as mitigações da Apple PPL e SPTM que fiscalizam a execução de código nativo. Os autores do DarkSword decidiram que era mais barato permanecer em JavaScript durante todo o processo e evitar completamente essa categoria de defesa.
- Atores: pelo menos três grupos distintos estão usando isso no mundo real — UNC6748, PARS Defense da Turquia e UNC6353. Seus alvos foram observados na Arábia Saudita, Turquia, Malásia e Ucrânia.
- Pacotes finais: três implantes iOS — GHOSTBLADE (minerador de dados em massa), GHOSTKNIFE (backdoor) e GHOSTSABER (backdoor com execução arbitrária de JS).
Um detalhe fácil de perder: o DarkSword é um “kit de exploração democrático”, onde o código foi vazado ou vendido para vários grupos independentes (UNC6353, PARS Defense e outros). É por isso que você vê tantos atores não relacionados atingindo a mesma versão do iOS ao mesmo tempo. Eles não estão descobrindo essas falhas independentemente; todos adquiriram o mesmo kit, e ele foi construído para alvejar o que era comum e sem correção durante o inverno de 2025-2026.

Crédito da imagem: Grupo de Inteligência de Ameaças da Google Cloud, “A proliferação do DarkSword: cadeia de exploração do iOS adotada por múltiplos atores de ameaça” (19 de março de 2026). Captura de tela do cabeçalho do post no blog público.
O fluxo de distribuição, do início ao fim:
Os atacantes não hackearam o Snapchat. Eles apenas construíram uma página de compartilhamento semelhante (snapshare[.]chat) e espalharam links para ela. Aqui está um screenshot da própria armadilha capturada pelo Grupo de Inteligência de Ameaças da Google:

Crédito da imagem: Grupo de Inteligência de Ameaças da Google Cloud, “A proliferação do DarkSword: cadeia de exploração do iOS adotada por múltiplos atores de ameaça” (19 de março de 2026). Reproduzido sob uso justo para comentário técnico.
Como um navegador não é realmente construído
Antes que possamos falar sobre “uma exploração de navegador”, precisamos esclarecer uma ideia: um navegador moderno não é um único programa. É vários processos cooperativos, cada um em seu próprio sandbox, se comunicando entre si por IPC.
No iOS, o Safari funciona mais ou menos assim:
- Processo UI — o “lobby”. Desenha a barra de abas, a barra de endereços, os favoritos. Este é o processo que você vê no Activity Monitor como
Safariem macOS ou o aplicativo em primeiro plano no iOS. Ele não executa, por si só, JavaScript da página. - WebContent (
com.apple.WebKit.WebContent) — o renderer. Um por aba (aproximadamente). Analisa HTML, aplica CSS, executa JavaScript através do JSC e posiciona os pixels. Tudo que não é confiável vive aqui. Ele tem a configuração de sandbox mais restritiva de qualquer processo WebKit. - Processo GPU (
com.apple.WebKit.GPU) — desenho acelerado por hardware, WebGL via ANGLE, decodificação de vídeo. Intermedia o acesso ao GPU porque WebContent não é permitido tocar diretamente nele. - Processo de Rede (
com.apple.WebKit.Networking) — efetivamente faz as solicitações HTTP; WebContent pede educadamente por XPC. Não relevante diretamente para DarkSword, mas vale a pena saber que existe. mediaplaybackd— demônio de mídia do sistema. Não faz parte do Safari propriamente dito, mas acaba sendo um alvo atrativo de pivô stage-4 porque tem acesso mais amplo ao sistema de arquivos e IPC do que o processo GPU.- XNU kernel — abaixo de tudo.
Os processos se comunicam quase exclusivamente por XPC, que viaja sobre Mach messages no nível do kernel. Os pontos finais XPC são a superfície natural de ataque para escapes de sandbox: WebContent não pode ler seus arquivos, mas pode enviar mensagens ao processo GPU, e se o processo GPU maltrata uma dessas mensagens, é fim de jogo.
Entre cada um desses componentes está um sandbox que é efetivamente uma porta fechada definida por um perfil em Sandbox Profile Language (.sb). O sandbox WebContent é o mais restritivo dos lotes, porque WebContent é o apartamento onde o código não confiável (seu JavaScript, o deles, o do ad network) realmente roda. Seu perfil assume que tudo com o qual ele entra em contato é hostil.

O Monitor de Atividade do macOS filtrado por “WebKit” é uma prova viva que o Safari não é um único programa. Cada com.apple.WebKit.WebContent é um processo renderizador separado sandboxado; com.apple.WebKit.GPU é o intermediário compartilhado do GPU; com.apple.WebKit.Networking lida com HTTP para todas as abas.
Dentro de WebContent vive JavaScriptCore (JSC), que é o motor JavaScript da Apple, disponibilizado sob licença em Source/JavaScriptCore/ na árvore do WebKit. JSC é a parte que realmente toma o JavaScript na página e o transforma em código de máquina ARM64 que seu CPU pode executar. Essa tradução é onde nossa história começa.
Stage 1 — Obtendo código executando: o bug do JIT
A primeira pergunta que toda exploração de navegador tem que responder é: como faço para fazer meu JavaScript controlado pelo atacante se comportar no nível de memória crua?
A resposta, quase sempre, é o compilador JIT.
O que é um JIT e por que ele é vulnerável a explorações?
Imagine uma intérprete simultânea na ONU. As primeiras vezes em que você diz uma frase ela traduz palavra por palavra — lenta, cuidadosa, segura. Mas se você continuar repetindo a mesma frase ela memoriza um código curto e entrega instantaneamente. Isso é um JIT (Just-In-Time compilador) em um parágrafo: observe qual código roda muito e compile esse “código quente” diretamente para instruções de máquina nativa para velocidade.
O JSC tem quatro níveis que uma função pode passar enquanto executa:
- LLInt (Interpretador de Nível Baixo) — um interpretador portátil e lento. Cada função começa aqui.
- Baseline JIT — geração simples de código em formato de modelo. Poucas otimizações; suficiente para o código quente.
- DFG JIT (Grafo de Fluxo de Dados) — um JIT otimizador. Constrói um grafo de fluxo de dados, realiza especulação (“esta variável sempre é um Int32, então vou pular a verificação de tipo”) e insere guardas para reverter para camadas inferiores se a suposição não for mantida.
- FTL JIT (Mais Rápido que a Luz) — um otimizador mais pesado construído sobre o backend B3 da JSC (e historicamente LLVM). Executa no código mais quente.
A camada relevante para DarkSword é o DFG. É lá que a especulação acontece, e a especulação é o que as explorações JIT geralmente visam. Se um atacante puder convencer o DFG a emitir código sob uma suposição falsa e, em seguida, na execução, alterar a forma da memória de modo que a suposição não seja mais válida. O código compilado será executado sem verificações de segurança nos dados que já não são o que foram prometidos ser.
Isto é uma confusão de tipos, e é um caminho direto para a leitura e escrita de memória dentro do processo WebContent.
As falhas JIT DarkSword
O DarkSword envia duas explorações separadas de JIT e escolhe a correta com base na versão iOS da vítima (ele faz um teste via navigator.userAgent no carregador):
- CVE-2025-31277 — uma falha de otimização JIT / confusão de tipos em JavaScriptCore. Usada contra iOS 18.4 – 18.5. Corrigida em iOS 18.6.
- CVE-2025-43529 — uma zero-day falha de coleta de lixo no nível DFG. Usada contra iOS 18.6 – 18.7. Corrigida em iOS 18.7.3 e iOS 26.2.
Por que duas explorações? Porque a disposição exata da memória e os IDs de estrutura nos quais as primitivas dependem mudam entre builds do WebKit. O kit de exploração compila uma exploração por cada WebKit suportado e escolhe a correta em tempo real.
As duas explorações terminam construindo os dois componentes que todas as explorações de motores JS que você lerão sobre constroem primeiro:
// conceitual, não é código funcional
// addrof — diga-me onde este objeto JS reside na memória
const leakedAddr = addrof(victimObject);
// fakeobj — fingir que esta parte da memória É um objeto JS
const puppet = fakeobj(attackerControlledAddress);
// combinar os dois e você pode ler e escrever em qualquer lugar
// no processo WebContent.
No nível de detalhe, addrof e fakeobj são geralmente construídos explorando um desacordo entre como o JSC armazena os dados do objeto (seu “butterfly”) e como ele tipifica valores (palavras 64-bit etiquetadas em linha). Ao fazer com que um array seja tipificado para conter doubles enquanto um adjacente é tipificado para conter objetos, e então escrevendo uma escolhida bit pattern no primeiro, de modo que você possa ler a bit pattern como um ponteiro de objeto (fakeobj) ou observar um ponteiro de objeto como um 64-bit double (addrof). É o esboço; a verdadeira exploração é muito mais complicada e depende da falha DFG exata usada para criar a confusão de tipos.
Aqueça esses dois componentes e você efetivamente tem um depurador anexado à sua própria guia do navegador: leitura arbitrária de memória, escrita arbitrária de memória, tudo dentro do processo WebContent.
Isso é a primeira vitória. Mas não é suficiente por si só. Tudo até agora vive no WebContent e o WebContent é o sandbox mais apertado da construção.
Fase 2 — Chamando código real: desabilitando PAC
A capacidade de leitura e gravação arbitrárias dentro do renderizador é poderosa, mas limitada. Você pode ler memória, alterar memória, mas em Apple silicon moderno você não pode chamar nada. Não se pode chamar uma função do sistema, nem rotina da biblioteca C e certamente não um syscall. A CPU simplesmente recusa-se a pular através de um ponteiro que você não ganhou.
O mecanismo é o PAC (Pointer Authentication Codes), introduzido no ARMv8.3-A e incorporado em todos os chips Apple A12 ou posteriores.
Como PAC funciona, em um parágrafo
Os ponteiros de funções no iOS carregam uma assinatura criptograficamente calculada nos bits mais altos. Para o iOS, isso usa um PAC de 11 bits ou maior, dependendo da largura VA. A assinatura é derivada a partir de uma chave secreta per-processo, um modificador, que geralmente é um valor de contexto como um endereço do stack, e o ponteiro em si, calculado pelas instruções da família PACIA/PACIB/PACDA/PACDB. Antes que a CPU siga uma ramificação autenticada (BLRAA, RETAA, etc.), ela usa AUTIA/AUTIB para verificar a assinatura; se a verificação falhar, o ponteiro é envenenado com um padrão não canônico e a próxima referência gera uma interrupção. Efeito geral: um atacante com leitura/gravação arbitrárias ainda não pode forjar um alvo de chamada válido porque eles não sabem as chaves PAC per-processo.
O PAC é uma grande parte do motivo pelo qual “leitura e gravação arbitrárias no iOS” não significa imediatamente “execução de código arbitrária.”
O bypass de PAC do DarkSword
A fase 2 do DarkSword é CVE-2026-20700, um zero-day no dyld (o carregador dinâmico em modo usuário), corrigido na iOS 26.3. Sem dar a primitiva completa, a ideia é esta: o dyld realiza muito assinamento por conta própria durante o normal processo de resolução de vinculação preguiçosa e stubs. O bug permite que um atacante engane o dyld para emitir um ponteiro PAC-assinado para um endereço sob seu controle, efetivamente transformando o dyld em uma oráculo de assinatura PAC.
Com isso em mãos, a primitiva anterior de leitura/gravação arbitrárias se torna chamada de função nativa arbitrária: o atacante pode sintetizar um ponteiro assinado válido para qualquer função no processo, instalá-lo onde JSC irá referenciar-o e ter a CPU felizmente seguindo através dele. Eles podem agora chamar APIs reais do iOS a partir de sua base JavaScript.
Fase 3 — Quebrando a saída do renderizador (WebContent → GPU)
Vamos fazer um balanço. Agora temos:
- Leitura e gravação arbitrárias dentro de WebContent.
- Chamada de função nativa arbitrária, graças ao oráculo PAC do
dyld.
O que não temos é a capacidade de fazer algo interessante. O perfil da sandbox de WebContent nega-nos o sistema de arquivos, a maioria dos sockets, quase todos os syscalls e a grande maioria dos serviços Mach. Os designers do Safari esperavam que terminássemos aqui. Então precisamos abrir um buraco em uma vizinhança com mais privilégios.
Isso é o escape da sandbox, e é a fase na qual uma exploração de navegador se torna uma arma.
Por que WebGL, e o que ANGLE é
O primeiro escape do DarkSword alvo o processo GPU. WebContent fala com o processo GPU sempre que uma página faz algo pesado em gráficos, e a maneira mais comum de uma página fazer isso é WebGL, a API JavaScript para gráficos 3D no navegador.
O WebKit implementa WebGL por cima do ANGLE (Almost Native Graphics Layer Engine) que originalmente é um projeto Google/Chromium que traduz chamadas de WebGL 1/2 em APIs reais de gráficos da plataforma. No iOS, o ANGLE traduz WebGL para Metal. Quando uma página chama gl.drawElements(...), uma cadeia de eventos é disparada:
- JSC chama a ligação WebGL no WebKit em WebContent.
- WebContent empacota a chamada em uma mensagem XPC.
- A mensagem é enviada ao processo GPU por meio de um serviço XPC dedicado.
- O processo GPU passa a chamada para sua cópia do ANGLE, que valida os argumentos, traduz a chamada para Metal e a envia para o driver.
A etapa 3 é uma barreira de IPC entre sandboxes. A validação de argumentos na etapa 4 é a barreira de segurança que precisa estar correta, porque o processo GPU está executando com privilégios elevados em relação ao WebContent, e portanto qualquer corrupção de memória dentro dele é uma fuga do sandbox.
O bug ANGLE DarkSword
CVE-2025-14174 é um zero-day no ANGLE: uma operação específica do WebGL falhou ao validar seus parâmetros antes de passá-los para a camada Metal. Ao emitir uma chamada forjada do JavaScript, o atacante dispara uma escrita fora dos limites dentro do processo GPU.
No código DarkSword, o carregador para esta etapa é chamado sbx0_main.js. Este é um payload JavaScript separado que a ferramenta recupera apenas após os estágios anteriores terem sido bem-sucedidos. Essa modularidade em estágios é uma padrão comum: manter cada etapa pequena, versão-gatilhada e independentemente substituível para poder trocar CVEs individuais conforme a Apple os corrigir.
No final da etapa 3, o atacante tem execução de código dentro do com.apple.WebKit.GPU, que é um sandbox mais flexível em relação ao WebContent, embora ainda seja significativamente sandboxado e esteja pronto para se deslocar mais profundamente no mediaplaybackd e então no kernel.
A cadeia completa à primeira vista
| Etapa | CVE | Componente | O que você obtém com isso | Patchado em |
|---|---|---|---|---|
| 1a | CVE-2025-31277 | JIT JavaScriptCore | RCE no WebContent (iOS 18.4 – 18.5) | iOS 18.6 |
| 1b | CVE-2025-43529 | JIT DFG (GC) — zero-day | RCE no WebContent (iOS 18.6 – 18.7) | iOS 18.7.3 / 26.2 |
| 2 | CVE-2026-20700 | dyld — zero-day | Bypass do PAC no modo usuário → chamadas nativas arbitrárias | iOS 26.3 |
| 3 | CVE-2025-14174 | ANGLE / WebGL — zero-day | Fuga do sandbox WebContent → GPU | iOS 18.7.3 / 26.2 |
| 4 | CVE-2025-43510 | XNU (cópia-on-write) | GPU → mediaplaybackd | iOS 18.7.2 / 26.1 |
| 5 | CVE-2025-43520 | XNU VFS (race) | Leitura/escrita no kernel | iOS 18.7.2 / 26.1 |
Six bugs. Três eram zero-days ao tempo da divulgação.
O próprio diagrama de cadeia de infecção do Google Cloud Threat Intelligence Group descreve o mesmo fluxo em um nível mais baixo, incluindo os nomes dos arquivos JavaScript para cada estágio:

Crédito da imagem: Google Cloud Threat Intelligence Group, “A proliferação do DarkSword: cadeia de exploração iOS adotada por múltiplos atores ameaça” (19 de março de 2026). Reproduzido sob uso justo para comentários técnicos.
Por que esta cadeia é pura JavaScript
A escolha de design mais significativa em DarkSword é uma negativa: os autores nunca se tornam nativos. Nenhum shellcode ARM64 é carregado na memória e convertido para executável. Cada linha que o atacante executa, desde a primeira etapa até a carga de kernel, é JavaScript sendo executado dentro do pipeline JIT normal da JSC, que a CPU já confia porque o JIT é um componente assinado pela Apple operando em memória assinada pela Apple.
Do ponto de vista da mitigação, isso é enorme. A Apple gastou quase uma década construindo defesas específicas contra código nativo introduzido pelo atacante:
- W^X (write-xor-execute) enforcement torna impossível ter memória que seja escritável e executável ao mesmo tempo.
- Code Signing Enforcement recusa-se a executar páginas que não remetem a um binário assinado pela Apple.
- Page Protection Layer (PPL) protege a visão do kernel sobre as páginas de código executável de um kernel comprometido.
- Secure Page Table Monitor (SPTM), introduzido em silício A15 e posterior / M-series, impede mesmo um atacante privilegiado do kernel de reescrever tabelas de páginas para remapear páginas como executáveis.
Cada uma dessas defesas existe para matar o padrão clássico: carregar shellcode, torná-lo executável e pular para ele. DarkSword simplesmente não faz isso, então essas defesas não têm nada a policiar.
Como o kit se apresenta dentro
Em vez de shellcode, DarkSword embarca um puro-JavaScript post-exploitation runtime que fica em cima das primitivas das etapas 1 e 2 (leitura/escrita arbitrária e o oráculo PAC do dyld). A análise dos arquivos do kit revela uma biblioteca modular estratificada que não pareceria fora de lugar em um aplicativo legítimo:
| Módulo | Papel |
|---|---|
Chain/Native.js | Acesso à memória de nível baixo — read8, read64, write*, envolvido com ArrayBuffer / typed-array helpers. |
Chain/OffsetsStruct.js | Ofsets de campos estruturais versão-gatilhados para internos do iOS (WebCore, JSC, libSystem). |
TaskRop/VM.js | Manejo Mach VM — vm_allocate, vm_protect, mach_vm_remap invocados nativamente do JS. |
TaskRop/RemoteCall.js | Ligação arbitrária de função nativa, montada sobre a passagem PAC da etapa 2. |
TaskRop/PAC.js | Auxiliares para assinar, desfazer e forjar ponteiros PAC’d via o oráculo dyld. |
FileUtils | API de sistema de arquivos POSIX estilo (open, read, stat, unlink) — implementada como wrappers de chamadas nativas, não shellcode syscall(). |
Driver/Driver.js | Orquestrador top-level colando as etapas juntas. |
InjectJS.js | Carrega o próximo módulo JS na qual quer que seja o processo em que a etapa anterior escapou. |
MigFilterBypassThread.js | Circunvai o filtro de mensagem MIG aplicado pela Apple sobre permissões XPC sensíveis — necessário para alcançar certos serviços Mach privilegiados do renderizador. |
Em outras palavras: o atacante nunca executa código que a CPU trata como “introduzido pelo atacante.” Eles executam código que a CPU trata como JavaScriptCore, porque é literalmente isso — emitido pela própria JSC do JIT de um fluxo de JavaScript fornecido pelo atacante que o motor foi enganado para confiar.
A contrapartida
Nada é gratuito. Ficar em JavaScript amarra a exploração fortemente aos internos específicos da JSC: formas de objetos, IDs de estrutura, geometria do butterfly, layout do cache JIT — tudo isso muda entre as builds WebKit. Cada mudança requer reajuste das primitivas, que é por que DarkSword embarca trabalhadores por versão (rce_worker_18.6.js, rce_worker_18.7.js e assim por diante): o bug pode atravessar builds, mas a construção primitiva sobre ele não faz isso. O que o kit compra com essa carga de manutenção é um contorno limpo da pilha inteira de defesas nativas da Apple, e os autores do kit claramente decidiram que era um negócio valendo a pena fazer.
No contexto histórico, isso é uma verdadeira ruptura. A vulnerabilidade FORCEDENTRY (NSO Group, 2021) entregava shellcode nativo através de um bug no parser JBIG2 do CoreGraphics e grande parte da complexidade do exploit estava em derrotar o sandbox BlastDoor e a assinatura de código do iMessage para que o shellcode realmente pudesse ser executado. A Operação Triangulação (2023) executava código nativo do iMessage e precisava de abuso de recursos hardware para alcançar o kernel. O DarkSword demonstra um caminho completamente diferente: permanecer em JavaScript, e tudo acima da fronteira JIT é um problema que alguém já resolveu por você.
E continua — etapas 4 e 5
A partir do processo GPU, o DarkSword dispara CVE-2025-43510, que é um bug de copy-on-write no kernel XNU, para pivotar para mediaplaybackd, um daemon do sistema com acesso mais amplo ao filesystem e IPC. A partir daí, CVE-2025-43520 (uma condição de corrida em modo kernel na camada VFS do XNU) dá ao atacante leitura/gravação arbitrária no kernel. Nesse ponto, o jogo está terminado. Ambos os bugs e sua exploração serão detalhados em um post subsequente.
Defesa e conclusões
O cronograma do Google sobre as observações de DarkSword e o patch das vulnerabilidades dá uma boa noção da janela durante a qual os dispositivos não atualizados estavam expostos. A atividade começou em novembro de 2025 e as últimas correções foram lançadas na versão iOS 26.3 em março de 2026:

Crédito da imagem: Google Cloud Threat Intelligence Group, “A proliferação do DarkSword: Cadeia de exploração do iOS adotada por múltiplos atores maliciosos” (19 de março de 2026). Reproduzido sob uso justo para comentários técnicos.
-
Atualize seu telefone. Os dois alvos “conhecidos como bons” são iOS 18.7.7 (a correção legada que a Apple retroportou especificamente para o ramo 18.x, lançado em março / abril de 2026) e iOS 26.3 (o ramo moderno). Qualquer coisa abaixo desses dois deve ser tratada como potencialmente vulnerável a pelo menos parte da cadeia, e versões intermediárias como 18.7.2 e 18.7.3 fecharam a maioria dos CVEs, mas não todos. Se você está verificando uma frota, “≥ 18.7.7 ou ≥ 26.3” é a regra a ser seguida.
-
Não pode atualizar agora? Ative o Modo Bloqueio. Mesmo em um iOS não atualizado de 18.4 – 18.7.x, o Modo Bloqueio supostamente bloqueia o DarkSword e desativa suficientes características do JavaScriptCore (notavelmente o JIT) para que os exploits da etapa 1 tenham nada aonde pousar. É uma ferramenta bruta que quebra ou degrada algumas funcionalidades legítimas, mas é o interruptor de emergência certo para quem não pode corrigir imediatamente.
-
O que procurar como defensor ou pesquisador. Do lado da rede: iframes ocultos carregando scripts de domínios não relacionados, e loaders que fazem a verificação de versão em
navigator.userAgent/navigator.platformantes de buscar um payload de segunda etapa. Do lado do dispositivo: padrões anômalos XPC / Mach IPC entrecom.apple.WebKit.WebContentecom.apple.WebKit.GPU, especialmente mensagens muito grandes no caminho do serviço WebGL. -
O que estudar se você está aprendendo. Escolha uma camada e fique confortável antes de seguir para a próxima! O nível DFG do JavaScriptCore é um ótimo ponto de partida para os detalhes internos do JIT; o código de validação do ANGLE é curto e legível (github.com/google/angle); perfis de sandbox iOS são uma boa maneira de entender o que “sandboxed” significa concretamente. Nosso post anterior sobre ler perfis de sandbox do iOS é um leitor complementar excelente.
Exploits de navegador parecem misteriosos do lado de fora, mas seguem um arco previsível: execute código no renderizador, transforme leitura/escrita em execução real, escape da sandbox, escalone. DarkSword é um exemplo didático — escrito com elegância, em pura JavaScript, ao longo de seis CVEs e três atores ameaça. Os bugs específicos serão substituídos à medida que a Apple os corrigir. A forma da cadeia não será.
Referências
Disclosure principal
- Google Cloud Threat Intelligence Group — “A proliferação do DarkSword: Cadeia de exploração iOS adotada por múltiplos atores ameaça” (19 de março de 2026) — cloud.google.com
- Lookout Threat Intel — “Atacantes armados com DarkSword ameaçam usuários iOS” — lookout.com
- iVerify — “Dentro do DarkSword: Um novo kit de exploração iOS entregue por meio de sites legítimos comprometidos” — iverify.io
Avisos da Apple
- Apple — Notas de segurança do iOS 18.7.7 — support.apple.com/en-us/126793
- Apple Platform Security — “Códigos de autenticação de ponteiro” — support.apple.com

