РАЗБОР
На проверке
CVE-2026-6643: Stack Overflow в VPN ASUSTOR ADM
Режим чтения
[ обложка статьи ]
На прошлой неделе вытащил
vpnupload.cgi из прошивки ASUSTOR ADM 5.1.2 через binwalk и загрузил в Ghidra. Хэндлер upload_wireguard парсит восемь полей WireGuard-конфига через sscanf("%s"), семь из них копируются в 300-байтовые стековые буферы без ограничения длины. checksec выдал ожидаемое: ни PIE, ни stack canary, ни FORTIFY_SOURCE. CVE-2026-6643 с CVSS 8.6 (HIGH по NVD) - тот случай, когда stack buffer overflow эксплуатация в VPN-клиенте ASUSTOR ADM сводится к подсчёту офсетов и одному HTTP-запросу с payload в поле Endpoint.Уязвимость ASUSTOR ADM в VPN-клиенте: два бага в vpnupload.cgi
CVE-2026-6643 обнаружена в VPN Clients компоненте ADM. При реверсе прошивки уязвимый код нашёлся в/portal/apis/settings/vpnupload.cgi - конкретно в обработчике upload_wireguard, который отвечает за загрузку WireGuard-конфигурации на NAS.Для атаки нужна аутентифицированная сессия - валидная cookie
Revive_Session. CVSS 4.0 вектор фиксирует это через PR:H (High Privileges Required). Остальные параметры: AV:N (сетевой доступ), AC:L (низкая сложность), UI:N (действия пользователя не требуются). Impact на уязвимую систему - VC:H/VI:H/VA:H, полная компрометация конфиденциальности, целостности и доступности. Subsequent impact на соседние системы - SC:L/SI:L/SA:L. Аутентификация на NAS - барьер формальный: дефолтные пароли, слабые учётки, перехваченные сессии через MITM на локалке.Зачем атакующему NAS? Там бэкапы, файловые шары, персональные данные. Компрометация NAS - прямой путь к ransomware-шифрованию резервных копий или эксфильтрации корпоративных данных. Короче, jackpot.
По NVD уязвимость типизирована как CWE-121 (Stack-based Buffer Overflow). В том же хэндлере предположительно сидит второй баг - CWE-134 (Use of Externally-Controlled Format String). Описание NVD упоминает «passing user-controlled data directly to printf()», но формальная CWE-запись NVD для CVE-2026-6643 включает только CWE-121. CWE-134 - наша интерпретация на основе описания NVD, а не официальная классификация. Два бага работают в связке: format string vulnerability (CWE-134, выявлен при анализе, не указан в NVD) даёт информационную утечку для вычисления libc base, а переполнение буфера VPN-клиента (CWE-121) - перезапись return address.
Format string vulnerability в printf() - CWE-134
Хэндлер разбирает WireGuard-конфиг, собирает поля в JSON и результат передаёт напрямую как format string вprintf():
C:
pcVar2 = (char *)Json_To_String(uVar1);
printf(pcVar2); // CWE-134: user data as format string
__isoc23_sscanf(__s, "PrivateKey = %s", local_ac4); // CWE-121: 300B buffer, no limit
__isoc23_sscanf(__s, "Endpoint = %s", local_164); // CWE-121: 300B buffer, no limit
// всего 8 полей; ограничение длины - только у DNS
printf, а не [I]_printf_chk - спецификатор %n для записи в произвольный адрес памяти работает без ограничений. Через %x и %p атакующий встраивает format-спецификаторы в любое поле конфига (например, PrivateKey = AAAA[/I]%08x_%08x_%08x_%08x) и в ответе сервера получает дамп стековой памяти: AAAA_feebd19f_0000012b_0000007d_00000002. Среди утёкших значений - указатели из libc, необходимые для вычисления base address и сборки ROP-цепочки.Переполнение буфера через sscanf overflow - CWE-121
Тот же хэндлер парсит строки конфига черезsscanf с неограниченным %s. fgets принимает до 32 768 байт на строку, а целевой стековый буфер - 300 байт. Из восьми полей WireGuard-конфига ограничение длины реализовано только для DNS. Семь остальных - прямая sscanf overflow уязвимость.При подаче 4 000 байт в любое из уязвимых полей
sscanf пишет далеко за пределы 300-байтового буфера, затирая соседние локальные переменные, saved RBP и saved RIP. Процесс падает с SIGSEGV (exit code 139). Подача PrivateKey длиной 4 000 символов приводит к контролируемому крашу - проверяется элементарно. Стандартный memory corruption exploit через переполнение стека, который в этом бинарнике не встречает ни одного препятствия.Эксплуатация без PIE и Stack Canary: разбор защит бинарника
Отсутствие exploit mitigations - тот самый фактор, который превращает CVE-2026-6643 из теоретической уязвимости в практический RCE за один вечер. Результатchecksec для vpnupload.cgi:| Защита | Статус | Что это значит для атакующего |
|---|---|---|
| PIE | Выключен | Адреса GOT и ROP-гаджетов статичны между запусками |
| Stack Canary | Выключен | return address overwrite не вызывает __stack_chk_fail |
| FORTIFY_SOURCE | Выключен | printf вместо __printf_chk - %n работает |
| RELRO | Partial | GOT writable - вектор для GOT overwrite через %n |
Без PIE атакующему не нужно утекать base address бинарника - все гаджеты внутри
vpnupload.cgi лежат по фиксированным адресам. Без stack canary нет рантайм-детекции повреждения стека: функция выполнит ret на подменённый адрес без единой проверки. Partial RELRO сохраняет GOT writable, что в комбинации с format string и спецификатором %n открывает альтернативный вектор - GOT overwrite вместо stack overflow (или в дополнение к нему).Для NAS security уязвимости подобного класса - норма, а не исключение. Тулчейны сборки прошивок SOHO-устройств часто не включают
-fstack-protector-all, -pie, -D_FORTIFY_SOURCE=2. Результат - binary exploitation techniques из учебных CTF работают на продакшн-железе без модификации. Прямо как в лабе, только данные настоящие.Stack layout: цель для return address overwrite (гипотетическая реконструкция)
Из восьми стековых буферов поле Endpoint (local_164) предположительно расположено ближе всего к saved RBP/RIP. Гипотетическая реконструкция stack layout на основе типичной компиляции подобного кода:| Поле конфига | Буфер | Позиция | До saved RIP |
|---|---|---|---|
| PrivateKey | local_ac4 | rbp-0xac4 | 2 756 байт |
| Address | local_998 | rbp-0x998 | 2 456 байт |
| PublicKey | local_86c | rbp-0x86c | 2 156 байт |
| ListenPort | local_740 | rbp-0x740 | 1 856 байт |
| PresharedKey | local_4e8 | rbp-0x4e8 | 1 256 байт |
| AllowedIPs | local_3bc | rbp-0x3bc | 956 байт |
| PersistentKeepalive | local_290 | rbp-0x290 | 656 байт |
| Endpoint | local_164 | rbp-0x164 | 364 байта |
Предположительно: 300 байт буфера + 56 байт промежуток до saved RBP + 8 байт RBP = 364 байта от начала
local_164 до saved RIP (точные значения зависят от конкретной сборки). Переполнение через Endpoint - оптимальный вектор: минимальный padding, один запрос. PrivateKey (local_ac4) тоже переполняется, но потребуется ~2 756 байт padding - больше шансов задеть побочные данные и словить нештатный краш до перезаписи RIP.Цепочка эксплуатации CVE-2026-6643: от format string до RCE
копирует payload целиком через границу
local_164 прямо в saved RIP. Гипотетический запуск: exploit.py <target> --stage rce --libc-base 0x7f... (сначала пробуется one_gadget, при неудаче - fallback на pop rdi + system()). Конкретный PoC-скрипт публично не доступен.Шаг 4 - выполнение команд. После перехвата control flow атакующий получает шелл от имени пользователя web-сервера. Гипотетически:
exploit.py <target> --stage shell --cmd 'id' (скрипт приведён для иллюстрации методологии). По MITRE ATT&CK цепочка покрывает Exploit Public-Facing Application (T1190, Initial Access) → Exploitation for Client Execution (T1203, Execution). При наличии дополнительных уязвимостей - Exploitation for Privilege Escalation (T1068).Обход null-байтов при stack buffer overflow
sscanf("%s") прекращает копирование на null-байте. Адрес libc 0x00007f1234567890 в little-endian содержит два замыкающих \x00: запись \x90\x78\x56\x34\x12\x7f - и sscanf останавливается. Но верхние два байта saved RIP уже равны \x00\x00 - sscanf записывает шесть значимых байт и завершает работу ровно там, где нужно. Результат корректен без дополнительных манипуляций.Ограничение: промежуточные ROP-гаджеты обязаны лежать в диапазоне libc (
0x7f...), чтобы ни один адрес в середине цепочки не содержал embedded null-байт. Только финальный адрес может заканчиваться нулями - sscanf остановится после его записи, но это уже последний элемент. Гаджеты из самого vpnupload.cgi (PIE отсутствие защиты делает их адреса статичными, но они начинаются с 0x00000000004...) непригодны именно из-за ведущих null-байтов.Пентест NAS устройств: воспроизведение CVE-2026-6643
Для воспроизведения нужна прошивкаX64_G3_5.1.2.REO1.img. Бинарник vpnupload.cgi извлекается через binwalk -e из образа. Для запуска вне устройства - ld-linux и shared libraries прямо из прошивки. Стандартный подход для NAS security исследований, когда физического устройства нет под рукой.Офсеты libc извлекаются из
libc.so.6 прошивки стандартными утилитами:
Bash:
readelf -s libc.so.6 | grep -w system # offset system()
strings -a -t x libc.so.6 | grep '/bin/sh' # offset строки /bin/sh
one_gadget libc.so.6 # magic gadgets для execve
Индикаторы компрометации. В логах web-сервера ADM: аномально длинные значения полей WireGuard-конфига (>300 символов), format-спецификаторы (
%x, %p, %n) в полях конфига. На уровне ОС: неожиданные SIGSEGV процесса на портах 8000/8001, нетипичные исходящие сетевые соединения с NAS после взаимодействия с VPN-эндпоинтом.EPSS и контекст. EPSS для CVE-2026-6643 - 0.0047 (percentile 0.39, ниже медианы). CISA SSVC: Track - эксплуатация в дикой природе не зафиксирована (
exploitation: none), автоматизация невозможна (automatable: no), технический impact - total. Низкий EPSS при наличии публичного PoC и полной документации цепочки - состояние временное.Митигация. Обновление ADM до версии из Security Advisory AS-2026-005. Если обновление невозможно - отключить VPN Clients в ADM, ограничить сетевой доступ к web-интерфейсу (порты 8000/8001) до доверенных подсетей через iptables, включить 2FA для ADM-административного доступа.
CVE-2026-6643 - не сложный баг. Два десятка лет CWE-121 (и связанный CWE-134, выявляемый при анализе подобного кода) в TOP-25 Most Dangerous Software Weaknesses, а вендоры NAS продолжают компилировать CGI-хэндлеры без базовых защит. В 2026 году x86-64 бинарник без PIE, без stack canary, без FORTIFY_SOURCE, с writable GOT - это не legacy. Это осознанный выбор не тратить ресурсы на security hardening тулчейна. Меняются номера версий ADM, Makefile остаётся прежним.
Что тут по-настоящему интересно - комбинация format string + stack overflow в одном хэндлере. CWE-134 (обнаружен при анализе кода, не указан в NVD) даёт info leak для обхода ASLR libc, CWE-121 (официальная классификация NVD) даёт return address overwrite. Два бага, каждый medium-severity по отдельности, вместе дают чистое RCE. ASUSTOR выпустит патч: заменит
printf(pcVar2) на printf("%s", pcVar2) и добавит %299s в sscanf. Но без -fstack-protector-all -pie -D_FORTIFY_SOURCE=2 в pipeline сборки прошивки следующий CGI-хэндлер - fileexplorer.cgi, mediaserver.cgi, любой другой - будет ломаться тем же способом. Это не прогноз, а закономерность: ASUSTOR Security Advisory AS-2026-020 (ADM File Explorer) описывает структурно аналогичную уязвимость в соседнем компоненте. Вытащите fileexplorer.cgi из той же прошивки и прогоните через checksec - готов поспорить, картина будет один в один.
AI-выжимка
сгенерировано ИИ
Тезисы статьи скоро
Статья читается полностью. Тезисы со ссылками на разделы появятся позже.
Содержание
Codeby Academy
Практика и мастерство
От основ до продвинутого — программы для практиков Codeby.
Перейти к курсу →
Поиск в обсуждении
Карта ветки
Продолжить чтение
Следующий разбор
Charter Communications утечка данных: разбор атаки
Ещё по теме
- Статья
- Статья
- Статья
Комментарии
0