Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2026-76071 — Оригинальное исследование и неразрушающий PoC для переполнения буфера стека до аутентификации через неограниченный scanset в sscanf в обработчике ipFilterList на Netis NC63 | Kitploit
Инструменты/GitHubGitHub/ozcanpng/cve-2026-76071
Безопасность IoTАнализ уязвимостейЭксплуатацияОбратная инженерияАнализ Бинарных ФайловАнализ Прошивок
GitHubozcanpng/cve-2026-76071

CVE-2026-76071

Оригинальное исследование и неразрушающий PoC для переполнения буфера стека до аутентификации через неограниченный scanset в sscanf в обработчике ipFilterList на Netis NC63

Репозиторий
14 дней назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2026-76071: Неаутентифицированное переполнение буфера стека до аутентификации через sscanf %[^,] в обработчике ipFilterList в skk_set.cgi в Netis NC63

Исследователь: Özcan Ersan (@ozcanpng)

Статус раскрытия

  • CVE: CVE-2026-76071
  • Производитель: Netis Systems Co., Ltd.
  • Продукт: маршрутизатор Netis NC63 AC1200 Wireless Dual Band Gigabit MU-MIMO
  • Протестированная прошивка: NC63_V3.0.0.3327
  • Затронутый компонент: /bin/netis.cgi
  • Конечная точка: POST /cgi-bin/skk_set.cgi
  • Триггер: ipFilterList=mod
  • Динамически подтверждённый параметр: destHost
  • Тот же парсер статически достижим через: srcHost
  • Аутентификация: не наблюдалась и не требовалась в проверенном пути
  • Архитектура: MIPS32r2 little-endian, o32 ABI, uClibc
  • Класс уязвимости: переполнение буфера на стеке с контролем сохранённого обратного адреса
  • Проверка: продакшн CGI с оригинальным хэшем в изолированном QEMU user-mode окружении
  • Состояние записи CVE на момент подготовки: присвоено; детали записи CNA ожидают заполнения

Краткое описание

Универсальный парсер MIB/значений в прошивке Netis NC63 V3.0.0.3327 разбирает поле destHost в ipFilterList с помощью двух наборов сканирования %[^,], но без максимальной ширины поля. Каждое преобразование записывает в 16-байтовый локальный буфер стека. Таким образом, HTTP-клиент может отправить длинный компонент без запятых и перезаписать сохранённые управляющие данные функции.

Для динамически протестированного второго компонента destHost сохранённый ra находится ровно в 112 байтах от локального буфера. Трассировка QEMU для CGI с оригинальным хэшем подтвердила третий вход, выбранный атакующим, по адресу 0x0040f7f4. В отдельном тесте только наблюдения возврат был перенаправлен на исходный путь PLT функции system() по адресу 0x00423ab0 с сохранением управляемых атакующим данных запроса в качестве точного аргумента MIPS a0. Защищённый /bin/sh записал маркер и не выполнил ни одной команды.

Публичный PoC намеренно содержит только слишком длинный шаблон B. Он не включает приватное значение передачи управления или конструкцию командной границы.

Целостность затронутых артефактов

root@kitploit:~
193f6a5e2ce65972b1805bf076f8d3521379a8441c8aaeb5ad0ba174bbee0792  netis_NC63_V3.0.0.3327.bin
eb298774c27070dc595fefcabb4e8c12a46cb5f4fd08f91c3ca92282c3a289a2  squashfs-root/bin/netis.cgi
23faa747b7d2f067aa5431bcc227ceca97a7977cf3e7c372f715cbba57f9209b  squashfs-root/bin/boa
e3fd0ee3013014d59b14a409fb4ee5bb546e7d32413758ab3ad4fb0f0d3dcc47  squashfs-root/lib/libapmib.so

Оригинальные производственные хэши

Поверхность атаки и статус аутентификации

Фронтенд производителя формирует srcHost и destHost как три компонента, разделённых запятыми, и отправляет их вместе с ipFilterList на /cgi-bin/skk_set.cgi:

root@kitploit:~
param.destHost = $("#dest_host").val();
param.destHost += "," + $("#dest_ip_1").val();
param.destHost += "," + $("#dest_ip_2").val();
param.ipFilterList = $("#ip_action").val();

request({
    url: "/cgi-bin/skk_set.cgi",
    data: param
});

Формирование запроса фронтенда производителя

Проверенный CGI-запрос в форме HTTP не содержал заголовков Cookie или Authorization. /tmp/boa_auth отсутствовал, однако выполнение продолжилось в ветке парсера ipFilterList=mod и destHost. Дефект повреждения памяти — набор сканирования без ширины в FUN_0040f7f4; более широкая ошибка авторизации CGI — это условие, которое открывает доступ к этому привилегированному обработчику до аутентификации.

Граница неаутентифицированного root CGI

Трассировка от источника к приёмнику

root@kitploit:~
Unauthenticated HTTP client
  |
  | POST /cgi-bin/skk_set.cgi
  | ipFilterList=mod
  | destHost=1,0.0.0.0,<long comma-free component>
  v
FUN_004138a0
  v
FUN_004134c8 (ipFilterList trigger row)
  v
FUN_00410898(request, "ipFilterList")
  v
FUN_0040f7f4(request, trigger, mib_table, pMib)
  |
  | get_request_param("destHost")
  v
sscanf(value, "%d,%[^,],%[^,]", ...)
  |
  | second destination: char[16]
  | no maximum scanset width
  v
saved fp overwrite -> saved ra overwrite -> controlled PC

Метаданные исходного libapmib.so сопоставляют и srcHost, и destHost с типом 0x0c, который выбирает эту ветку парсера. Динамическая проверка выполнялась с destHost; srcHost включён как статическое покрытие того же парсера, а не как отдельное динамическое утверждение.

Маршрут обработчика и исходные метаданные MIB

Уязвимый код

Нормализованный псевдокод, полученный из Ghidra:

root@kitploit:~
case 0x0c:
    value = get_request_param(request, metadata_name);
    sscanf(value,
           "%d,%[^,],%[^,]",
           &selector,
           first_ip_component,   /* char[16] */
           second_ip_component); /* char[16] */

    *(char *)(destination + field_offset) = selector;
    inet_aton(first_ip_component, destination + field_offset + 1);
    inet_aton(second_ip_component, destination + field_offset + 5);
    break;

Неограниченные преобразования наборов сканирования

sscanf() сам по себе не является уязвимостью. Дефект в том, что %[^,] не имеет максимальной ширины поля, поэтому sscanf не знает, что каждый приёмник имеет размер всего 16 байт. Формат с учётом ёмкости использовал бы ширину, например %15[^,], проверял, что успешно выполнены ровно три преобразования, а затем проверял разобранные значения адресов. Это пример смягчения, а не исправление от производителя.

Анализ повреждения стека

FUN_0040f7f4 начинается по адресу 0x0040f7f4 и создаёт кадр размером 0x1d0 байт:

root@kitploit:~
0040f7f4  addiu sp,sp,-0x1d0
0040f7f8  sw    ra,0x1cc(sp)
0040f7fc  sw    fp,0x1c8(sp)
0040f800  sw    s0,0x1c4(sp)

Приёмники типа 0x0c находятся по адресам fp+0x14c и fp+0x15c. Сохранённый ra находится по адресу fp+0x1cc, что даёт точное расстояние от второго буфера:

root@kitploit:~
0x1cc - 0x15c = 0x70 = 112 bytes

Структура стека и смещение сохранённого ra

Динамическая проверка

Управление счётчиком команд

Изолированное доказательство PC использовало 112 байт заполнения, за которыми следовали три младших байта 0x0040f7f4 в little-endian; завершитель sscanf предоставил четвёртый нулевой байт. QEMU наблюдал два обычных входа в парсер, за которыми последовал третий вход, вызванный перезаписанным обратным адресом:

root@kitploit:~
parser_entry_hit=3 pc=0x0040f7f4
GPR28: ... s8 41414141 ra 0040f7f4
total_parser_entry_hits=3
PASS: third parser entry is the overwritten saved RA.

Управляемый третий вход в парсер

Граница команды только для наблюдения

Отдельная приватная проверка сформировала сохранённый ra=0x00423ab0 — путь PLT функции system() исходного бинарного файла. Суффикс управляемого ключа запроса остался в MIPS a0 при возврате. Временное окружение заменило /bin/sh на статический регистратор:

root@kitploit:~
argv[0]=</bin/sh>
argv[1]=<-c>
argv[2]=<NC63_IPFILTER_RCE_PROOF>
CONTROLLED_MARKER_PREFIX_REACHED
PASS: attacker-controlled request data reached system() as exact a0.
PASS: guarded /bin/sh recorded argv and executed no command.

Это устанавливает примитив RCE в изолированном пути продакшн-кода. Точная надёжность эксплуатации физического маршрутизатора, поведение рандомизации ядра и доступность по WAN по умолчанию не тестировались.

Адаптация среды выполнения и границы доказательной базы

Протестированный netis.cgi побайтно идентичен продакшн-артефакту. Поскольку состояние MIB, хранящееся во флэш-памяти, недоступно в qemu-user, временная корневая ФС использовала раскрытую лабораторную адаптацию libapmib.so, которая выделяла обнулённое состояние MIB и корректировала одно выравнивание упакованного поля. Это не меняло CGI, парсер запросов, уязвимый sscanf, кадр стека, смещение сохранённого возврата, эпилог или путь system(). Статические метаданные получены из исходного libapmib.so производителя.

Исходный исполняемый файл имеет фиксированный базовый адрес, не содержит стековой канарейки и RELRO, а также имеет исполняемый стек и RWX-сегмент. Эти свойства поддерживают анализ эксплуатируемости, но не заменяют динамические тесты PC и защищённой границы.

Состояние защитных механизмов бинарного файла

Безопасный публичный PoC

Пробный запуск генерации URL-закодированного тела:

root@kitploit:~
python3 poc/poc.py

Явная передача авторизованной временной цели:

root@kitploit:~
python3 poc/poc.py --target http://192.168.1.1 --send

Публичный скрипт использует 115-байтовый компонент B для демонстрации условия переполнения. Его отправка может вызвать сбой CGI-процесса. Он не содержит строки команд, шеллкода, адреса возврата к system, реверс-шелла или механизмов персистентности.

Воздействие

Успешная эксплуатация может выполнять выбранные атакующим команды в контексте управления маршрутизатором. Исходная конфигурация Boa запускает CGI от имени root. Возможные последствия включают раскрытие конфигурации маршрутизатора и секретов, манипуляцию DNS/межсетевым экраном/ маршрутизацией, перенаправление трафика, нарушение обслуживания и полную компрометацию устройства.

Устранение

  1. Используйте %15[^,] для каждого 16-байтового приёмника и требуйте трёх успешных преобразований.
  2. Отклоняйте слишком большие сериализованные значения хоста перед разбором.
  3. Проверяйте оба IP-значения на стороне сервера перед сохранением.
  4. Обеспечьте авторизацию администратора перед диспетчеризацией привилегированного CGI.
  5. Проведите аудит каждой ветки парсера метаданных на наличие %s и %[...] без ширины.
  6. Пересоберите со стековыми канарейками, PIE, NX и RELRO.

Индекс доказательств

См. evidence/README.md. Нормализованный псевдокод и доказательства инструкций находятся в attachments/decompiled-functions/.

Хронология раскрытия

  • 2026-08-16: обнаружение и изолированная проверка продакшн-бинарного файла завершены.
  • Август 2026: сообщено в VulnCheck.
  • 2026-08-20: VulnCheck присвоил CVE-2026-76071 и разрешил публичное раскрытие.
  • 2026-08-20: опубликован пакет публичного раскрытия.

Ссылки

  • CVE-2026-76071
  • VulnCheck
  • Страница поддержки Netis NC63
  • CVE-2026-73673

Ни один физический маршрутизатор не был прошит. Не использовались реальные команды, шеллкод, реверс-шелл, персистентность, внешние сетевые подключения или деструктивные операции.

Скачать инструмент