
Exploit de cadeia completa para Android Chromium que combina a fuga de informação CVE-2026-11057 e o use-after-free CVE-2026-5281 para alcançar sequestro de vtable e execução arbitrária de código.
Pixel 7 Android 16 ARM64
commit 994c846bbd7a35241ba7c08158c13d66412a6993 (HEAD -> 146.0.7680.111, tag: 146.0.7680.111)
Author: Roger McFarlane <[email protected]>
Date: Mon Mar 9 12:48:07 2026 -0700
Este repositório combina CVE-2026-11057 (memória de imagem de glifo não inicializada no Skia) e CVE-2026-5281 (use-after-free de DeviceInfo no servidor wire do Dawn) em uma cadeia completa. Todas as modificações são do lado do renderer; o código do processo GPU permanece inalterado:
Vazamento de informações (CVE-2026-11057) — Aciona um buffer de imagem de glifo não inicializado por meio da renderização de texto em canvas, lê de volta ponteiros do heap do processo GPU, valida-os com execuções aritméticas, deriva a base do pool do PartitionAlloc e calcula o alvo falso do Server M = POOL + 0x202A08000 (offset calibrado).
Spray de CC — createBuffer(label="CCM:<m>:<n>") aciona a injeção de 3000 ChunkedCommands incompletos (bucket de 10KB, remainingSize=1, mantidos vivos no mChunkedCommands do servidor wire). O payload preenche a região ao redor de M com um Server falso disposto para Android arm64: vptr de MutexProtected em +0xB20, ChunkedCommandSerializer em +0xB50/+0xB58, CommandSerializer/vtable falsos em +0xC00/+0xD00.
Acionamento do 5281 + ocupação — queue.writeBuffer(buffer, 0x414141, ...) primeiro chama Unregister(Device) para liberar o DeviceInfo de 16 bytes, depois injeta um ChunkedCommand de ocupação de 16 bytes para recuperar esse slot e sobrescrever info->server com M, e por fim aciona um erro de validação com um offset fora dos limites.
Callback pendente → sequestro de vtable — O callback de erro não capturado desreferencia info->server = M (Server falso): os mutexes zerados passam, a execução chega a OnUncapturedError → SerializeCommand, e a chamada indireta por vtable relativa atinge nossa vtable falsa, resultando em pc = fake_vtable + offset int32 controlado, demonstrado por pc = 0x7641414141.
Nota: O Chromium para Android arm64 usa vtables relativas (
-fexperimental-relative-c++-abi-vtables); as entradas da vtable são offsets relativos de 32 bits em vez de ponteiros de função absolutos, portanto o PoC usa um offset int32 controlado como marcador no ponto de sequestro da vtable.
No dispositivo de teste, a cadeia completa atinge o crash de sequestro de vtable com uma taxa de sucesso de quase 100%; o estágio de vazamento pode ocasionalmente exigir vários recarregamentos automáticos antes de ter sucesso.
SkStrike.cpp.patch — Gatilho de vazamento da CVE-2026-11057. FlattenGlyphsByType() reescreve o payload da strike para que o processo GPU crie um SkGlyph com fImage == nullptr, eventualmente lendo um buffer de imagem não inicializado para vazar ponteiros do heap.Device.cpp.patch — Spray de CC do cliente wire do Dawn. APICreateBuffer() analisa o rótulo CCM:, constrói o payload falso do Server para Android arm64 e injeta N ChunkedCommands incompletos que permanecem vivos no processo GPU.ApiProcs.cpp.patch — Acionamento da CVE-2026-5281 + ocupação. No offset mágico 0x414141 de QueueWriteBuffer, chama Unregister(Device) para liberar o DeviceInfo, injeta um ChunkedCommand de 16 bytes para recuperar o slot e definir info->server = M, e então prossegue com um offset fora dos limites para disparar o callback pendente.exploit.html — Orquestração da página: primitiva de vazamento (groom/draw/readCell/verifyRuns/derivePoolBase), spray de CC e um gatilho autônomo exploit5281(); em caso de falha, limpa o estado do spray e recarrega para que os estágios não interfiram entre si.Este ExP é divulgado apenas até a etapa de sequestro de vtable (alvo de chamada indireta controlado, pc = base+0x41414141). As etapas a partir do salto controlado, bem como a implementação de RCE, são mantidas confidenciais e não estão incluídas neste repositório.
Meu exploit difere da abordagem do pesquisador original de uma forma fundamental. O exploit original foi obtido modificando o código-fonte do PartitionAlloc no processo GPU para desativar a randomização de endereços. Essa abordagem é adequada apenas para fins de prova de conceito. Em contrapartida, meu exploit combina uma vulnerabilidade de divulgação de informações para contornar a randomização de endereços, viabilizando um exploit totalmente funcional que funciona em ambientes do mundo real.
# Set build arguments here. See `gn help buildargs`.
is_official_build = true
is_debug = false
symbol_level = 0
v8_symbol_level = 0
blink_symbol_level = 0
is_component_build = false
proprietary_codecs = true
ffmpeg_branding = "Chrome"
dcheck_always_on =false
optimize_webui = true
android_static_analysis = "off"
target_os = "android"
target_cpu = "arm64"
# Disable PartitionAllocEventuallyZeroFreedMemory
disable_fieldtrial_testing_config = true
treat_warnings_as_errors = false
adb logcat | grep DEBUG no PC