FlawOpen

flawopen.com/Incidents/moveit-transfer-sql-injection-may-2023

● Progress Software · CVE-2023-34362 · May 2023 · CVSS 9.8 · Crítica
Investigación · FlawOpen

MOVEit Transfer: SQL injection y robo masivo de datos

CVE-2023-34362 era una inyección SQL sin autenticación en MOVEit Transfer. Mandiant observó explotación desde el 27 de mayo de 2023, seguida de web shells LEMURLOOT y robo de datos.[4], [3]

💡 Explicación en Lenguaje Sencillo (ELI5)

Imagina un formulario con un campo «número de carpeta», pero el empleado copia ese campo directamente en una instrucción para el sistema de archivo. Si el campo puede cambiar la instrucción en vez de indicar una carpeta, quien lo rellena puede hacer que el sistema vaya más allá de lo previsto. La inyección SQL cruza ese mismo límite: una entrada no confiable se interpreta como sintaxis SQL, no como un valor.[5]

Conceptos Clave y Términos

Inyección SQL (CWE-89)
Una entrada concatenada en una consulta a la base de datos cambia lo que hace la consulta, en vez de tratarse como un valor.[5]
Transferencia gestionada de ficheros (MFT)
Software que las organizaciones usan para intercambiar ficheros grandes o sensibles con socios. Un solo servidor puede guardar datos de muchas organizaciones.[3]
Web shell
Un script que el atacante coloca en un servidor web para mantener el acceso. Mandiant denominó LEMURLOOT al usado aquí.[3]
Consulta parametrizada
Una consulta cuyos valores se envían por separado del texto, de modo que la base de datos nunca interpreta los datos como SQL.[5]
Versiones afectadas y corregidas
Progress indica como afectadas, en sus respectivas ramas, las versiones anteriores a 2021.0.6, 2021.1.4, 2022.0.4, 2022.1.5 y 2023.0.1; esas versiones indicadas incluyen la corrección. Confirma tu rama y la ruta de actualización vigente en el aviso de Progress.[1]

Mapeos de marcos

Cronología del Incidente

2023-05-27

Mandiant sitúa el 27 de mayo de 2023 la primera evidencia de explotación de MOVEit Transfer que observó.[3]

2023-05-31

Progress revela la vulnerabilidad y pide a los clientes que corten el tráfico HTTP y HTTPS hasta aplicar el parche.[1]

2023-06-02

CISA añade CVE-2023-34362 a su catálogo Known Exploited Vulnerabilities.[9]

2023-06-07

CISA y el FBI publican el aviso conjunto AA23-158A, que describe la campaña como actividad del ransomware CL0P. Más tarde, Mandiant actualiza la atribución e integra UNC4857 en FIN11 por sus coincidencias.[2], [3]

Flujo de Ataque Paso a Paso

Paso 1

Una petición sin autenticar

Mandiant observó peticiones POST manipuladas a guestaccess.aspx de MOVEit Transfer antes de que apareciera LEMURLOOT; la actividad no requería un inicio de sesión normal.[3]

Paso 2

La entrada cambia el significado de la consulta

La petición alcanzaba una operación SQL vulnerable. CISA describió el fallo como acceso sin autenticación a la base de datos, incluida la inferencia o alteración/eliminación según el motor utilizado.[2], [5]

Paso 3

Se instala un web shell

Tras la explotación, Mandiant observó el web shell LEMURLOOT. Podía enumerar y recuperar archivos y manipular un usuario concreto de la aplicación; las fuentes no demuestran un control administrativo genérico.[3]

Paso 4

Se roban ficheros en masa

Mandiant observó el robo de grandes volúmenes de archivos. CISA y el FBI describieron la campaña general como actividad del ransomware CL0P; la atribución posterior de Mandiant vinculó la actividad con FIN11.[2], [3]

Código Fuente: Vulnerable vs. Seguro

C# ilustrativo, no es código fuente de MOVEit. El método reforzado convierte el identificador al tipo que realmente guarda la columna y rechaza cualquier otra cosa; después lo envía como parámetro tipado, de modo que el valor nunca forma parte del texto SQL. Cualquiera de los dos controles basta para frenar esta inyección; juntos, además, rechazan identificadores mal formados antes de ejecutar la consulta.[5]

IMPLEMENTACIÓN VULNERABLE
using System.Data.SqlClient;

public static class FolderLookup
{
    public static SqlDataReader Find(SqlConnection conn, string folderId)
    {
        // El texto de la consulta y los datos de la solicitud se concatenan, por lo que la base de datos
        // no puede distinguir qué parte quería tratar como dato el desarrollador.
        string sql = "SELECT id, name FROM folders WHERE id = '" + folderId + "'";
        var cmd = new SqlCommand(sql, conn);
        return cmd.ExecuteReader();
    }
}
PARCHE SEGURO Y ROBUSTO
using System;
using System.Data;
using System.Data.SqlClient;

public static class FolderLookup
{
    public static SqlDataReader Find(SqlConnection conn, string folderId)
    {
        if (!long.TryParse(folderId, out long id) || id <= 0)
            throw new ArgumentException("folderId must be a positive integer");

        // El valor se envía como parámetro tipado, separado del texto de la consulta.
        var cmd = new SqlCommand("SELECT id, name FROM folders WHERE id = @id", conn);
        cmd.Parameters.Add("@id", SqlDbType.BigInt).Value = id;
        return cmd.ExecuteReader();
    }
}

Lista de Verificación de Seguridad para Ingeniería

Fuentes