Análisis: librtmp AMF3 + mini_httpd htpasswd

Dos hallazgos que son primitivas reales pero de impacto limitado:
un OOB read en el decoder AMF3 de librtmp y un command injection en el helper htpasswd de mini_httpd. Este análisis documenta las cadenas, el alcance real y por qué no llegan a ejecución de código en un despliegue remoto típico.

/librtmp_minihttpd +

00. Resumen de Ambos Casos

CasoClasePrimitiva¿Cadena a RCE?Conclusión
librtmp AMF3CWE-125OOB read (fuga)NoInfo-leak, sin ejecución
mini_httpd htpasswdCWE-78Command injectionSí (local)Utilidad CLI, no alcanzable remota

01. Caso A — librtmp OOB read AMF3

librtmp es la librería del cliente RTMP usada por rtmpdump y, a través de él, por muchísimos reproductores y utilidades de streaming. El protocolo RTMP encapsula mensajes AMF (Action Message Format) y el tipo 0x14 corresponde a AMF3 INVOKE. El parser de estructuras AMF3 lee valores con un rango mal acotado, produciendo una lectura fuera de límites.

// AMF3_ReadNumber / AMF3_ReadString: lectura sin validar el rango double AMF3_ReadNumber(AMFObject *obj) { ... // avanza el buffer según la longitud declarada sin comprobar // que quede dentro del payload => OOB READ (CWE-125) } // Vía de entrada: un servidor RTMP malicioso envía packet type 0x14 // (AMF3 INVOKE) con una longitud que empuja la lectura fuera del buffer packet_type = 0x14; // AMF3 invoke, from server -> client

El desencadenante es que el cliente (rtmpdump/aplicación) procesa un mensaje del servidor RTMP. Al ser una lectura fuera de límites, el resultado es una fuga de memoria del heap y, en el mejor caso, un crash del cliente. No hay una cadena directa a ejecución de código arbitraria en las compilaciones típicas. Además, esta zona del código pertenece a una familia de bugs previos de librtmp (por ejemplo el strcpy sin bound en el handler de metadata), que ya fueron corregidos; este sumidero concreto repite el patrón de validación ausente.

Alcance real

Es una primitiva de fuga de memoria en el lado cliente, alcanzable solo contra una aplicación que se conecte a un servidor RTMP malicioso. No escala a RCE, y es variante de un patrón ya corregido en la misma librería.

02. Caso B — mini_httpd htpasswd

mini_httpd es un servidor HTTP mínimo muy usado en sistemas embebidos y routers. Distribuye, junto al daemon, utilidades auxiliares —entre ellas htpasswd, que genera los ficheros de autenticación. El argumento (normalmente el nombre de archivo de passwords) llega a un system() sin validar:

// htpasswd.c:214-215 — el argumento del usuario se inyecta en un comando sprintf(command, "cp %s %s", argv[1], ...); // argv[1] sin validar system(command); // /bin/sh -c "cp <argv[1]> ..." // Con argumento"; touch /tmp/pwned;#" se inyecta ejecución local ./htpasswd ";touch /tmp/pwned;#" # command injection local

Es un command injection real: el input del usuario llega a sh -c. La limitación crítica es que htpasswd es una utilidad de línea de comandos local —no un daemon que escuche. Para explotarla, un atacante ya necesita ejecución local en el sistema o un servidor CGI/helper que derive su invocación de input remoto, que no es el patrón de despliegue por defecto.

Alcance real

Inyección genuina pero con superficie local: requiere un deploy donde un helper invoque htpasswd con input influenciable, o acceso local previo. No es alcanzable desde internet contra el daemon por defecto.

03. La Lección: Primitiva vs Impacto

Lo que estos dos casos enseñan, junto a los demás de la serie, es que la gravedad de un hallazgo no depende solo de la clase (CWE), sino del encadenamiento a ejecución de código y del despliegue real:

En contraste, CoovaChilli, wifidog y libuhttpd demostraron ejecución de código verificada. La diferencia no es el CWE, es la cadena completa y el alcanzamiento del código vulnerable desde una superficie real. Para evaluar un hallazgo hay que preguntarse: ¿el código vulnerable es alcanzable desde donde un atacante puede estar, y convierte eso en ejecución?

04. Referencias

ReferenciaDescripción
librtmpLibrería cliente RTMP (rtmpdump)
AMF3_ReadNumber/StringSink del OOB read (packet type 0x14)
htpasswd.c:214Sink sprintf + system en mini_httpd
CWE-125Out-of-bounds Read
CWE-78Improper Neutralization in OS Command

← Volver al índice de la serie