Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

SAST

Описание уязвимого ПО

Для анализа была выбрана уязвимость CVE-2023–48702. Она связана с open-source проектом Jellyfin, в котором была выявлена возможность удаленного выполнения кода (RCE) из-за отсутствия проверки загружаемого файла.

Уязвимость скрывалась в эндпоинте /System/MediaEncoder/Path. Его обработка начинается в файле ConfigurationController.cs путем вызова метода UpdateEncoderPath:

public ActionResult UpdateMediaEncoderPath([FromBody, Required] MediaEncoderPathDto mediaEncoderPath)
        {
            _mediaEncoder.UpdateEncoderPath(mediaEncoderPath.Path, mediaEncoderPath.PathType);
            return NoContent();
        }

Метод UpdateEncoderPath файла MediaEncoder.cs обрабатывает запрос администратора на смену пути к FFmpeg (внешний сервис для обработки мультимедиа). Если переданный path — это существующая папка, функция пытается найти внутри неё исполняемый файл с именем ffmpeg (или ffmpeg.exe). Проверка выполняется путем запуска исполняемого файла (вызов ValidateVersion файла EncoderValidator.cs):

public void UpdateEncoderPath(string path, string pathType)
        {
…

                if (!new EncoderValidator(_logger, newPath).ValidateVersion())
                {
                    throw new ResourceNotFoundException();
                }
            }
…
        }

Метод ValidateVersion в свою очередь запускает функцию GetProcessOutput, которая уже непосредственно запускает процесс (ProcessStartInfo):

public bool ValidateVersion()
        {
            string output;
            try
            {
                output = GetProcessOutput(_encoderPath, "-version", false, null);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error validating encoder");
                return false;
            }

            if (string.IsNullOrWhiteSpace(output))
            {
                _logger.LogError("FFmpeg validation: The process returned no result");
                return false;
            }

            _logger.LogDebug("ffmpeg output: {Output}", output);

            return ValidateVersionInternal(output);
        }
…

private string GetProcessOutput(string path, string arguments, bool readStdErr, string? testKey)
        {
            using (var process = new Process()
            {
                StartInfo = new ProcessStartInfo(path, arguments)
                {
                    CreateNoWindow = true,
                    UseShellExecute = false,
                    WindowStyle = ProcessWindowStyle.Hidden,
                    ErrorDialog = false,
                    RedirectStandardInput = !string.IsNullOrEmpty(testKey),
                    RedirectStandardOutput = true,
                    RedirectStandardError = true
                }
            })
            {
                _logger.LogDebug("Running {Path} {Arguments}", path, arguments);

                process.Start();

                if (!string.IsNullOrEmpty(testKey))
                {
                    process.StandardInput.Write(testKey);
                }

                return readStdErr ? process.StandardError.ReadToEnd() : process.StandardOutput.ReadToEnd();
            }

Воспроизведение уязвимости

Для воспроизведения уязвимости необходимо выполнить следующие шаги:

1.    Войти под учетной записью администратора

2.    Перейти в раздел Dashboard->Playback

3.    Ввести в поле FFmpeg path путь к исполняемому файлу с эксплойтом (для демонстрации была выбрана программа калькулятора)

4.    Сохранить изменения

изображение

CodeQL

Запуск CodeQL с поиском описанных ранее CWE выявил уязвимость Command Line Injection:

изображение

Также в рамках задания было реализовано собственное правило для выявления уязвимости. CodeQL правила пишутся на языке QL. Для поиска уязвимости был использован Taint tracking (анализ заражения) — техника отслеживания пути "опасных" данных через программу.

изображение

Semgrep

Программа не выявила уязвимость Command Line Injection, только потенциальные проблемы, связанные с Path Traversal:

изображение

Выполнить taint-анализ для выявления уязвимости оказалось нельзя, так как поток данных в Jellyfin проходит через несколько файлов, а межфайловый анализ (interfile: true) доступен только в платной версии.

Правило основано на структурном сопоставлении с шаблоном (pattern matching). Первое условие (pattern) описывает уязвимый паттерн: метод контроллера, принимающий данные из тела HTTP-запроса через атрибут [FromBody], внутри которого поле полученного объекта без какой-либо промежуточной обработки передаётся в метод UpdateEncoderPath.

Второе условие (pattern-not) является исключением: если перед вызовом UpdateEncoderPath в методе присутствует хотя бы один условный блок if, правило не срабатывает. Это позволяет снизить количество ложных срабатываний в тех случаях, когда разработчик добавил явную проверку входного значения перед его использованием.

изображение

SonarQube

Встроенные правила SonarQube не обнаружили данную уязвимость. Тем не менее, был выявлен обширный список потенциальных уязвимостей и проблем качества кода.

изображение

Было реализовано собственное правило на C# с использованием Roslyn API. Правило реализует сигнатурный анализ без отслеживания потоков данных. Логика основана на двух последовательных проверках, применяемых к каждому объявлению метода в анализируемом коде.

Анализатор обходит список параметров метода и проверяет наличие атрибута [FromBody] или [FromBodyAttribute]. Присутствие этого атрибута означает, что метод является HTTP-эндпоинтом, принимающим данные из тела HTTP-запроса, то есть потенциально контролируемые злоумышленником данные. Если атрибут не обнаружен, дальнейшая проверка не выполняется.

Если первая проверка пройдена, анализатор перебирает все токены-идентификаторы внутри тела метода и сравнивает их с заранее заданным списком имён:

  • ProcessStartInfo — стандартный класс .NET для запуска внешних процессов;

  • UpdateEncoderPath — внутренний метод Jellyfin, устанавливающий путь к исполняемому файлу кодировщика.

Обнаружение любого из этих идентификаторов в методе с [FromBody]-параметром расценивается как потенциальная уязвимость командной инъекции.

изображение

About

Лабораторная работа по работе с инструментами статического анализа кода (SAST)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages