FlawOpen

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

● Progress Software · CVE-2023-34362 · May 2023 · CVSS 9.8 · Критический
Исследования · FlawOpen

MOVEit Transfer: SQL-инъекция и массовая кража данных

CVE-2023-34362 позволяла внедрять SQL в MOVEit Transfer без аутентификации. Mandiant наблюдала эксплуатацию с 27 мая 2023 года, за которой последовали веб-шеллы LEMURLOOT и кража данных.[4], [3]

💡 Простыми словами (ELI5)

Представьте форму с полем «номер папки», которое сотрудник напрямую копирует в команду для системы хранения. Если значение может изменить команду, а не только указать папку, отправитель сможет заставить систему выполнить лишнее. SQL-инъекция пересекает ту же границу: недоверенный ввод обрабатывается как синтаксис SQL, а не как значение.[5]

Ключевые понятия и термины

SQL-инъекция (CWE-89)
Ввод, вставленный в запрос к базе данных склейкой строк, меняет смысл запроса, а не воспринимается как значение.[5]
Управляемая передача файлов (MFT)
ПО, через которое организации обмениваются большими или конфиденциальными файлами с партнёрами. Один сервер может хранить данные многих организаций.[3]
Веб-шелл
Скрипт, который злоумышленник оставляет на веб-сервере, чтобы сохранить доступ. Mandiant назвала использованный здесь LEMURLOOT.[3]
Параметризованный запрос
Запрос, значения которого передаются отдельно от текста, поэтому база данных никогда не разбирает данные как SQL.[5]
Уязвимые и исправленные версии
Progress указывает, что в соответствующих ветках уязвимы версии до 2021.0.6, 2021.1.4, 2022.0.4, 2022.1.5 и 2023.0.1; перечисленные версии содержат исправление. Сверьте свою ветку и актуальный путь обновления с рекомендациями Progress.[1]

Связи со стандартами

Хронология инцидента

2023-05-27

Mandiant датирует 27 мая 2023 года самые ранние наблюдавшиеся ею признаки эксплуатации MOVEit Transfer.[3]

2023-05-31

Progress раскрывает уязвимость и призывает клиентов отключить трафик HTTP и HTTPS до установки патча.[1]

2023-06-02

CISA вносит CVE-2023-34362 в каталог Known Exploited Vulnerabilities.[9]

2023-06-07

CISA и ФБР публикуют совместное предупреждение AA23-158A, описывая кампанию как деятельность вымогательской группы CL0P. Позже Mandiant обновляет атрибуцию и объединяет UNC4857 с FIN11 на основании совпадений.[2], [3]

Пошаговый сценарий атаки

Шаг 1

Запрос без аутентификации

Mandiant наблюдала поддельные POST-запросы к guestaccess.aspx в MOVEit Transfer до появления LEMURLOOT; обычный вход пользователя для этой активности не требовался.[3]

Шаг 2

Ввод меняет смысл запроса

Запрос достигал уязвимой SQL-операции. CISA описала уязвимость как доступ к базе без аутентификации, включая получение сведений или изменение/удаление данных в зависимости от используемой СУБД.[2], [5]

Шаг 3

Устанавливается веб-шелл

После эксплуатации Mandiant наблюдала веб-шелл LEMURLOOT. Он мог перечислять и получать файлы, а также изменять запись определённого пользователя приложения; источники не подтверждают общий административный контроль.[3]

Шаг 4

Файлы похищаются массово

Mandiant наблюдала массовую кражу файлов. CISA и ФБР описали более широкую кампанию как деятельность вымогательской группы CL0P; более поздняя атрибуция Mandiant связала эту активность с FIN11.[2], [3]

Исходный код: Уязвимый vs Защищённый вариант

Иллюстративный пример на C#, а не исходный код MOVEit. Защищённый метод преобразует идентификатор в тип, который на самом деле хранит столбец, отклоняет всё остальное и передаёт его типизированным параметром, так что значение не становится частью текста SQL. Любая из этих двух мер по отдельности останавливает инъекцию; вместе они также отклоняют некорректные идентификаторы до выполнения запроса.[5]

УЯЗВИМАЯ РЕАЛИЗАЦИЯ
using System.Data.SqlClient;

public static class FolderLookup
{
    public static SqlDataReader Find(SqlConnection conn, string folderId)
    {
        // Текст запроса и данные запроса объединяются, поэтому база данных
        // не может определить, какую часть разработчик намеревался считать данными.
        string sql = "SELECT id, name FROM folders WHERE id = '" + folderId + "'";
        var cmd = new SqlCommand(sql, conn);
        return cmd.ExecuteReader();
    }
}
БЕЗОПАСНЫЙ ИСПРАВЛЕННЫЙ ВАРИАНТ
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");

        // Значение передаётся как типизированный параметр отдельно от текста запроса.
        var cmd = new SqlCommand("SELECT id, name FROM folders WHERE id = @id", conn);
        cmd.Parameters.Add("@id", SqlDbType.BigInt).Value = id;
        return cmd.ExecuteReader();
    }
}

Чек-лист по защите системы для инженеров

Источники