Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
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.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
proftpd-CVE-2026-42167-poc — POCs para demostrar CVE-2026-42167 en ProFTPD | Kitploit
Herramientas/GitHubGitHub/zeropathai/proftpd-cve-2026-42167-poc
Autenticación y AutorizaciónEscalada de PrivilegiosAnálisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebPost-ExplotaciónPruebas de PenetraciónAprendizaje y EducaciónSeguridad de Bases de Datos

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
GitHubzeropathai/proftpd-cve-2026-42167-poc

proftpd-CVE-2026-42167-poc

POCs para demostrar CVE-2026-42167 en ProFTPD

Ver Repositorio
235hace 3 mesesRevisado por Kitploit

POCs de Vulnerabilidad en ProFTPD

Demostraciones de prueba de concepto para CVE-2026-42167, una vulnerabilidad de inyección SQL en el pipeline de registro mod_sql de ProFTPD que permite a un atacante no autenticado ejecutar SQL arbitrario — e inyectar usuarios puerta trasera en la base de datos de autenticación FTP o lograr ejecución remota de código en el host de la base de datos.

Todos los POCs son específicos de PostgreSQL, pero los de usuarios puerta trasera funcionan con backends MySQL y SQLite con algunas modificaciones a la consulta inyectada (lo cual dejamos como ejercicio para el lector).

  • Esta vulnerabilidad fue descubierta por ZeroPath Research. Nuestro blog técnico contiene más detalles.

Vulnerabilidad

Bypass de is_escaped_text() en mod_sql SQLLog (CVE-2026-42167, CWE-89)

El mod_sql de ProFTPD registra cada comando FTP a través del mecanismo SQLLog / SQLNamedQuery. Al resolver variables de formato como %U (nombre de usuario original) o %{basename} (componente de nombre de archivo), el framework llama a is_escaped_text() para decidir si es necesario escapar — y omite el escape por completo para cualquier valor que comience y termine con una comilla simple y no contenga comillas simples internas (por ejemplo, '|| (SELECT 1) ||'). La verificación es puramente sintáctica y se ejecuta sobre la entrada sin procesar controlada por el atacante, por lo que no puede distinguir "pre-escapado por código confiable" de "diseñado por un atacante para parecer pre-escapado".

El patrón estándar documentado envuelve las variables de formato entre comillas simples para seguridad SQL:

root@kitploit:~
SQLNamedQuery log_activity INSERT "'%U', '%r', '%m'" activity_log
SQLLog        *           log_activity
SQLLog        ERR_*       log_activity

Cuando un atacante proporciona un valor de la forma '<payload>', la sustitución produce ''<payload>'' en el SQL final — los literales de cadena vacía cierran las comillas circundantes y el payload se ejecuta como SQL sin procesar. Con PostgreSQL (PQexec) o SQLite (sqlite3_exec), el soporte de consultas apiladas significa que el payload puede ser una declaración completa INSERT, UPDATE, CREATE TABLE o COPY TO PROGRAM.

¿Cuándo es explotable un servidor?

El código vulnerable está en contrib/mod_sql.c (el framework SQL compartido), no en ningún backend específico, por lo que todos los backends SQL están afectados — pero la superficie de ataque depende de cómo el administrador haya configurado el registro. Un servidor es explotable cuando se cumplen ambas de las siguientes condiciones:

  1. El administrador ha definido un SQLNamedQuery INSERT (o UPDATE) cuya cadena de formato interpola una de estas variables controlables por el atacante envuelta en comillas simples — por ejemplo, "'%U', '%m'". Las variables que provienen de la entrada del atacante son:

¿Qué puede hacer un atacante?

El bypass convierte la ruta de registro en una primitiva SQL arbitraria en el backend. Los dos escenarios de mayor impacto:

  • Inyectar un usuario puerta trasera con privilegios arbitrarios (bypass de autenticación). El backend de autenticación SQL de ProFTPD lee nombres de usuario, hashes de contraseñas, uid, gid, homedir y shell de la misma tabla users en la que el INSERT de registro ahora puede escribir. Un INSERT INTO users apilado introduce una cuenta elegida por el atacante — uid=0, homedir=/, contraseña en texto plano — y luego el atacante inicia sesión normalmente con acceso completo al sistema de archivos a través del daemon FTP. Alcanzable pre-autenticación a través de la ruta %U + SQLLog ERR_*, o post-autenticación a través de cualquier variable controlada por el atacante vinculada a un comando que el atacante pueda emitir (por ejemplo, %{basename} + SQLLog STOR). Funciona en PostgreSQL y SQLite (ambos soportan consultas apiladas).

  • Ejecución remota de código en el host de la base de datos mediante COPY TO PROGRAM. COPY (SELECT …) TO PROGRAM '<cmd>' de PostgreSQL ejecuta <cmd> a través de un shell en el servidor de base de datos. Una inyección de consulta apilada que emite otorga ejecución arbitraria de comandos del sistema operativo como el usuario postgres del sistema, que es suficiente para exfiltración de credenciales, movimiento lateral y persistencia. Alcanzable a través de las mismas rutas de activación que el caso de puerta trasera (pre-autenticación mediante o post-autenticación mediante , etc.). Específico de PostgreSQL, y requiere que el rol de base de datos de ProFTPD tenga privilegios de superusuario (el requisito previo para ) — común en implementaciones de un solo inquilino donde el rol es el propietario de la base de datos.

Opciones de POC

Los POCs en este repositorio apuntan específicamente a PostgreSQL — el caso más fuerte, ya que PQexec() soporta consultas apiladas y COPY TO PROGRAM proporciona ejecución directa de comandos del sistema operativo. El bypass en sí está en el framework SQL compartido y afecta a todos los backends:

  • PostgreSQL (cubierto aquí): consultas apiladas mediante PQexec, RCE mediante COPY TO PROGRAM.
  • SQLite: consultas apiladas mediante sqlite3_exec, se ejecuta bajo PRIVS_ROOT en el worker de proftpd — la inyección de puerta trasera funciona de la misma manera; la primitiva RCE difiere (no hay equivalente a COPY TO PROGRAM, pero una tabla users escribible en un backend SQL de proceso raíz es suficiente).
  • MySQL: el bypass se activa de la misma manera, pero llegar a la tabla users o a la ejecución del sistema operativo desde dentro del único INSERT de registro es más difícil. La manipulación de una sola declaración (exfiltración de subconsultas en un espacio de VALUES, ciego basado en tiempo, ciego basado en errores) es directa; convertir eso en una escritura en una tabla diferente requiere sortear varios obstáculos:
    • mod_sql_mysql llama a mysql_real_query() sin CLIENT_MULTI_STATEMENTS, por lo que un ; INSERT INTO users … final es rechazado por la conexión.

Dentro de la configuración de PostgreSQL, los POCs demuestran dos rutas de activación representativas. Otras combinaciones de la tabla anterior son equivalentes en principio:

  • Pre-autenticación mediante %U + USER. SQLLog ERR_* hace que esto sea completamente no autenticado.
  • Post-autenticación mediante %{basename} + STOR. Requiere cualquier credencial FTP pero ningún privilegio más allá de la capacidad de subir un archivo.

Contenido del Repositorio

  • setup/ — Configuración automatizada del entorno. Clona el árbol fuente de ProFTPD fijado al commit contra el cual se reportaron estos hallazgos, compila el daemon con mod_sql + mod_sql_postgres, y levanta un clúster de Docker Compose (ProFTPD + PostgreSQL) con datos de semilla y la configuración vulnerable de SQLLog.

  • pocs/ — Cinco scripts de exploit. Todos son scripts de Python autónomos que solo requieren la biblioteca estándar.

    • preauth_user_backdoor.py — Disparador %U pre-autenticación → usuario puerta trasera (uid=0, homedir=/) inyectado en la DB de autenticación. Sin credenciales, no se requiere superusuario de DB. Este POC es específico de PostgreSQL, pero el problema puede explotarse también con backend mysql o sqlite.
    • preauth_user_rce.py — Disparador %U pre-autenticación → RCE en el host PostgreSQL mediante COPY TO PROGRAM. Sin credenciales. Requiere que el rol DB de ProFTPD sea un superusuario de PostgreSQL.
    • postauth_stor_backdoor.py — Disparador post-autenticación → usuario puerta trasera inyectado. Requiere cualquier usuario FTP autenticado. Este POC es específico de PostgreSQL, pero el problema puede explotarse también con backend mysql o sqlite.

Instrucciones

Prerrequisitos: Docker, Git, Python 3.10+, y uv.

root@kitploit:~
cd setup
./setup.sh

La primera ejecución clona el código fuente de ProFTPD y compila el servidor (~2-3 min). Las ejecuciones posteriores reutilizan la caché de compilación y se inician en segundos.

Cuando la configuración se complete, imprime todos los detalles del entorno (puntos finales FTP y DB, credenciales de prueba y comandos POC listos para copiar). Sigue esas instrucciones para ejecutar los POCs.

Para desmontar:

root@kitploit:~
cd setup
./teardown.sh
Descargar herramienta
VarSignificado
%Acadena de contraseña de inicio de sesión anónimo
%Jparámetros del comando (todo después del verbo)
%Scadena del mensaje de respuesta (puede incluir entrada del atacante reflejada en errores)
%Unombre de usuario original de USER (establecido antes de la autenticación, disponible incluso en inicio de sesión fallido)
%dnombre del directorio (último componente de la ruta)
%lrespuesta ident RFC 1413 (controlada por el atacante si ejecutan identd)
%mmétodo/verbo FTP (el atacante elige qué comando enviar)
%rcomando FTP completo (verbo + args)
%unombre de usuario autenticado
%{basename}componente del nombre de archivo del argumento de ruta, sin prefijo de directorio

%f, %F y %D parecen controlados por el atacante pero siempre se resuelven a rutas absolutas que comienzan con /, por lo que no pueden cumplir con el requisito de comenzar con ' de is_escaped_text().

  • El administrador ha vinculado ese SQLNamedQuery a una directiva SQLLog para un comando FTP (o clase de comando) al que el atacante puede acceder. Los comodines ampliamente documentados SQLLog * y SQLLog ERR_* son el caso más amplio y lo que hace que la ruta %U sea pre-autenticación: ERR_* se activa en un USER fallido, por lo que no se necesitan credenciales. Directivas por comando como SQLLog STOR cubren a cualquier usuario autenticado.

  • COPY TO PROGRAM
    %U
    %{basename}
    COPY TO PROGRAM
  • Un atacante tendría que descubrir cómo sortear esta limitación para escribir en la tabla users o en un archivo en disco.
  • %{basename}
  • postauth_stor_rce.py — Disparador %{basename} post-autenticación → RCE en el host PostgreSQL. Requiere cualquier usuario FTP autenticado y un rol DB superusuario de PostgreSQL.
  • postgres_blind_dump.py — Disparador %U pre-autenticación → extracción ciega basada en tiempo de la tabla users de autenticación. No usa consultas apiladas, por lo que funciona en implementaciones donde el rol DB de proftpd tiene solo privilegios mínimos (solo INSERT en la tabla de registro) y los POCs de puerta trasera / RCE anteriores fallarían en modo cerrado. Extrae cada byte de cada columna — incluida la columna passwd — buscando binariamente un bit a la vez mediante pg_sleep(). Refleja lo que sqlmap automatizaría, hecho a mano sin dependencias de terceros.