
Раскрытие информации и PoC для уязвимости чтения/записи корневых файлов в отладочном канале TP-Link Deco XE75 Pro V3 (опкоды tmpsvr 0xC456/0xF0), с анализом CVSS и декомпиляцией обработчика.
Сопутствующий проект VLAN: экспериментальный исходный код alpha с фиксированным VLAN 30 для конкретной прошивки/профиля XE75 Pro V3. Требует предоставленных оператором стоковых файлов и не имеет универсального установщика или прошиваемого образа. Гостевой VLAN 591 остаётся нерешённым; финальная приёмка трёх устройств с холодной загрузкой, UI и изоляцией клиентов не завершена. См. текущий статус.
Раскрытие результатов исследования, TP-Link Deco XE75 Pro V3, прошивка 1.5.0 Build
20260603 Rel.15804. Подготовлено для [email protected] и публичного релиза вместе с нашей реализацией IoT VLAN на 802.1Q (deco-iot-vlan).
Отладочный SSH-канал Deco с аутентификацией владельца (Dropbear на TCP 20001,
только переадресация direct-tcpip, парольная аутентификация) достигает внутреннего
сервиса tmpsvr на 127.0.0.1:20002. Один из его обработчиков Lua,
inner_file_push (опкод 0xC456), открывает params.file в режиме "w" и
записывает params.content дословно от имени root, без белого списка путей, без ограничения
размера и без понижения привилегий. Парный опкод (0xF0) обеспечивает
соответствующее чтение файлов от имени root. Вместе: аутентифицированные чтение + запись всей
корневой файловой системы, что на роутере означает всё устройство.
SSH :20001 (username = SHA1(owner_email), password = TP-Link account password)
-> direct-tcpip -> 127.0.0.1:20002 (TMPv2)
-> 0xC456 inner_file_push : io.open(file,"w"); write(content); close() [root]
-> 0x00F0 root file read : byte-exact file read [root]
/etc/config — это живая записываемая ramfs → измените ключ, и роутер его применит./www отдаётся по HTTPS через uhttpd → загруженные файлы немедленно доступны./tp_data/user_data — это постоянная флеш-память ubifs → переживает перезагрузку.GET /cgi-bin/luci → выполнение Lua от root → io.popen → выполнение произвольного
бинарника от root.Все четыре шага были выполнены и отменены на собственном основном устройстве владельца.
tmpsvr всё ещё не исправлен спустя 2 года после CCS'24 / Black Hat '24Команда UCR SecLab публично задокументировала отладочный канал :20001 -> 127.0.0.1:20002 (tmpsvr) два года назад в CCS 2024 — "Untangling the Knot: Breaking Access Control in Home Wireless Mesh Networks" (а также Black Hat USA 2024 — "Fallen Tower of Babel"). Их точкой входа на более старых моделях Deco (X55, FW 1.2.2) был факторинг 512-битных RSA hostkey и злоупотребление непроверяемыми обработчиками tmpsvr.
Наблюдаемые отличия и оставшиеся обработчики на этой конкретной прошивке:
ssh-rsa hostkey с 512 бит до 2048 бит (один общий наблюдаемый ключ на всех трёх mesh-устройствах, SHA256:9feb3ac4...932a36, плюс отдельный для каждого устройства ecdsa-sha2-nistp521), закрыв путь факторинга 512-битного ключа из доклада 2024 года.1.5.0 присутствуют следующие обработчики уровня root:
:20001 (svr_auth_uci) остаётся активной с использованием SHA1(owner_email) + общего пароля TP-Link ID.0xC456 (inner_file_push) по-прежнему открывает любой указанный вызывающей стороной путь в режиме "w" от имени root без какой-либо проверки пути.0x00F0 по-прежнему читает любой файл в файловой системе от имени root.0xC505 (tty2tcp/start) — тот самый обработчик внедрения команд через неэкранированный /bin/sh -c, выделенный в докладе 2024 года — по-прежнему присутствует в прошивке июня 2026 года (1.5.0) и полностью не исправлен.luci/controller/admin/mobile_app/iot_device,
inner_file_push).Продемонстрирована только доступность из LAN. Для наблюдаемого профиля «только LAN» мы используем варианты AV:A: v3.1 6.8 / v4.0 8.5. Приведённые ниже оценки AV:N являются условными и зависят от продемонстрированного сетевого пути; доступность из облака не проверена.
Это пост-аутентификационное повышение привилегий владельца до root — не
неаутентифицированный RCE — оценки для наблюдаемого профиля ниже составляют 6.8 (v3.1) и 8.5 (v4.0). Полное обоснование и
отклонённые завышения приведены в docs/cvss-analysis.md.
CVSS v3.1 — оценка только для LAN 6.8 (Medium); условный удалённый вариант 7.2 (High):
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H = 7.2 (High)
CVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H = 6.8 (Medium) # if LAN-only
Решающие оценки: PR:H (владелец / учётная запись TP-Link-ID является административным субъектом устройства) и S:U (обработчик уже выполняется от имени root — граница полномочий не пересекается). Более ранний черновик получил оценку 9.9 через PR:L + S:C; обе отклонены.
CVSS v4.0 — оценка только для LAN 8.5 (High); условный удалённый вариант 8.6 (High):
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N = 8.6 (High)
CVSS:4.0/AV:A/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N = 8.5 (High) # if LAN-only
CVSS:4.0/AV:N/AC:L/AT:N/PR:H/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:L = 9.3 (Critical) # with Subsequent-System LAN/mesh impact
Реальный риск — украденный/повторно используемый пароль TP-Link-ID, преобразующийся в
постоянный root по всей mesh-сети плюс MITM клиентского трафика — относится к
описанию (и метрикам v4.0 SC:H/SI:H/SA:L Subsequent-System), а не к
раздутому базовому вектору v3.1.
poc/deco_filepush_poc.py — самодостаточный (stdlib + paramiko). Учётные данные
только через переменные окружения DECO_EMAIL / DECO_PASSWORD. Живые режимы требуют
DECO_HOSTKEY, проверенного независимо: необработанный base64, строка публичного ключа или одна
строка ключа из ssh-keyscan (комментарии поддерживаются). Одно лишь сканирование не аутентифицирует
устройство. Проверка HTTPS сравнивает передаваемые байты, но не проверяет его сертификат.
Требуется ровно один режим; при неудачной проверке выход с ненулевым кодом.
python3 poc/deco_filepush_poc.py --selftest # offline framing sanity
[email protected] DECO_PASSWORD=*** DECO_HOSTKEY="$TRUSTED_DECO_HOSTKEY" \
python3 poc/deco_filepush_poc.py --run # write marker + readback + HTTPS check
[email protected] DECO_PASSWORD=*** DECO_HOSTKEY="$TRUSTED_DECO_HOSTKEY" \
python3 poc/deco_filepush_poc.py --cleanup <nonce> # overwrite marker with empty content
PoC записывает единственный инертный маркер в /www/log_export (ramfs; также
очищается при перезагрузке), затем требует побайтово точного обратного чтения через
собственный root-опкод чтения устройства и неизменённой отдачи по HTTPS перед тем, как сообщить
об успехе.