Análisis de Técnicas de Inyección en Plantillas de Servidor para PHP y Python

Introducción a las Inyecciones de Plantillas (SSTI)

La Inyección de Plantillas del Lado del Servidor ocurre cuando una aplicación permite que la entrada del usuario sea tratada como parte de una plantilla lógica. Esto puede permitir a un atacante ejecutar código arbitrario en el servidor.

Vulnerabilidades en Motores Smarty (PHP)

Smarty es un motor de plantillas ampliamente utilizado en aplicaciones PHP para separar la lógica de presentación de la lógica de negocio. Versiones anteriores a la 3.1.42 y 4.0.2 son susceptibles si se procesan cadenas matemáticas o expresiones dinámicas provenientes de entradas no confiables.

Causa Técnica

El problema surge cuando los parámetros de la solicitud HTTP se pasan directamente a funciones de renderizado sin sanitización. A continuación, un ejemplo simplificado de cómo se introduce la falla:

Estrategias de Explotación

Extracción de Versión

Un primer paso común es confirmar la presencia del motor identificando su versión.

Las versiones heredadas permitían la ejecución de PHP nativo dentro de las plantillas usando bloques específicos. Aunque esta funcionalidad ha sido descontinuada en favor de la seguridad en versiones modernas, sigue siendo un vector conocido en entornos legacy.

Uso de Literales y Condicionales

El bloque literal evita el análisis de las plantillas, útil para proteger scripts externos, pero también puede ser abusado para inyectar etiquetas HTML o JS.

Inyección de Plantillas en Flask y Jinja2 (Python)

Los frameworks basados en Python, como Flask, utilizan generalmente Jinja2 como su mecanismo de renderizado. Este motor es potente y permite lógica compleja dentro de los archivos de vista, lo que lo convierte en un objetivo frecuente para ataques SSTI.

Configuración Básica de Renderizado

Flask ofrece métodos principales para mostrar contenido: renderizar un archivo físico o renderizar una cadena dinámica.

app = Flask(name)

@app.route('/saludo') def saludar_usuario(): mensaje_bienvenida = 'Hola Mundo' # Se retorna la cadena interpretada por Jinja2 return render_template_string(mensaje_bienvenida)


</div>La distinción crítica está entre `render\_template` (carga desde disco) y `render\_template\_string` (interpreta cadena de memoria). El segundo es el principal foco de vulnerabilidad cuando se combina con interpolación de cadenas insegura.

### Escenario de Explotación

Si la estructura de la plantilla incluye variables controladas por el usuario sin escapado adecuado, o si la propia cadena de la plantilla se construye mediante concatenación con datos externos, ocurre el fallo.

<div>```
@app.route('/perfil')
def perfil_publico():
    nombre_incorrecto = request.args.get('alias')
    # Construcción insegura de la plantilla
    molde_vulnerable = f"<p>Bienvenido {{nombre_incorrecto}}</p>"
    return render_template_string(molde_vulnerable)

Exploración Introspectiva del Objeto

Jinja2 en Python expone ciertos atributos dunder (doble guion bajo) que permiten navegar por la jerarquía de clases para encontrar objetos globales o builtin.

  • __class__: Obtiene la clase del objeto actual.
  • __mro__: Muestra el recorrido de resolución de método (herencia).
  • __bases__: Accede a las clases base.
  • __subclasses__: Lista subclases disponibles.
  • __globals__: Referencia al diccionario global del módulo.
  • __builtins__: Accede a las funciones incorporadas de Python.

Técnicas de Búsqueda de Clase Base

Para saltar hacia arriba en la jerarquía y alcanzar el espacio de nombres de built-ins, existen varias cadenas de acceso comunes:

Accesando bases desde diccionarios

{}.class.bases[0].subclasses()


</div>Una vez obtenida una referencia a `\_\_globals\_\_` o `\_\_builtins\_\_`, es posible importar módulos críticos del sistema y ejecutar comandos remotos. Por ejemplo, accediendo a la función `eval` o `open` desde el contexto recuperado.

Etiquetas: SSTI Jinja2 Flask Smarty PHP

Publicado el 8-1 21:02