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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2021-34730 — Cisco RV110w UPnP stack overflow | Kitploit
Инструменты/GitHubGitHub/badmonkey7/cve-2021-34730
Embedded Systems SecurityIoT SecurityVulnerability AnalysisExploitationReverse EngineeringDebuggersNetwork SecurityHardware HackingFirmware AnalysisBinary Exploitation
GitHubbadmonkey7/cve-2021-34730

CVE-2021-34730

2874 лет назадПроверено Kitploit

Популярное

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

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

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

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

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

Cisco RV110w UPnP stack overflow

Репозиторий

Анализ 0day UPnP для Cisco RV110W

Предисловие

В последнее время UPnP стал очень популярен, и у меня как раз есть Cisco RV110W. В августе 2021 года Cisco официально объявила об уязвимости 0day для серии RV, связанной с UPnP, но конкретные детали не были раскрыты. Поэтому я решил с помощью имеющегося устройства отладить и исследовать эту уязвимость. Уведомление об уязвимости можно увидеть на официальном сайте.

Подготовка

Сначала обновим прошивку до последней версии 1.2.2.8. Следующая проблема – как отлаживать и локализовать уязвимость. Сначала решаем вопрос отладки. Первоочередная задача отладки – получить shell устройства, но последняя прошивка не предоставляет отладочного интерфейса. Автор получил права отладки последней прошивки через UART-порт и модификацию пакета прошивки. Подробный метод описан в предыдущей статье Отладка роутера: getshell.

Подготовка к отладке

Cisco RV110W основана на архитектуре mipsel, поэтому сначала нужно найти подходящий gdb-server. Можно собрать кросс-компиляцией самостоятельно или использовать уже собранный кем-то. Здесь рекомендуется gdb-static-cross.

Локализация уязвимости

Официальное уведомление указывает, что уязвимость существует в службе UPnP. Сначала заходим в панель управления, в FireWall -> Basic Settings включаем конфигурацию UPnP.

Untitled

Затем сканируем порты с помощью nmap – порт UPnP не обнаружен, но тестирование показало, что UPnP действительно включен.

Untitled

Здесь автор использует UPnPy для тестирования и эксплуатации уязвимости.

root@kitploit:~
import socket
msg = \
    b'M-SEARCH * HTTP/1.1\r\n' \
    b'HOST:239.255.255.250:1900\r\n' \
    b'ST:upnp:rootdevice\r\n' \
    b'MX:2\r\n' \
    b'MAN:"ssdp:discover"\r\n' \
    b'\r\n'

# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((b"192.168.2.100",23333)) #本机IP
s.settimeout(2)
s.sendto(msg, (b'239.255.255.250', 1900))
addr = ('192.168.2.1', 1900) # 网关IP
try:
    while True:
        data, addr = s.recvfrom(65507)
        print(addr,data)

except socket.timeout:
    pass

Мы действительно получили ответ UPnP, и в процессах устройства существует соответствующий процесс UPnP.

Untitled

Анализ служб

UPnP – это общий стандарт протокола, производители в основном реализуют его по стандарту, то есть многие actions одинаковы, но также необходимо проанализировать службы, предоставляемые устройством, для локализации и эксплуатации уязвимости. Аналогично используем UPnPy для сбора информации.

root@kitploit:~
import upnpy
import socket

import requests
from upnpy.ssdp.SSDPDevice import SSDPDevice
msg = \
    b'M-SEARCH * HTTP/1.1\r\n' \
    b'HOST:239.255.255.250:1900\r\n' \
    b'ST:upnp:rootdevice\r\n' \
    b'MX:2\r\n' \
    b'MAN:"ssdp:discover"\r\n' \
    b'\r\n'

# Set up UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.bind((b"192.168.2.100",23333))
s.settimeout(2)
s.sendto(msg, (b'239.255.255.250', 1900))
addr = ('192.168.2.1', 1900)
data = b""
try:
    while True:
        data, addr = s.recvfrom(65507)
        print(addr,data)
except socket.timeout:
    pass

# data = b'HTTP/1.1 200 OK\r\nCache-Control: max-age=120\r\nDate: Fri, 01 Jan 2010 00:44:16 GMT\r\nExt: \r\nLocation: http://192.168.2.1:1780/InternetGatewayDevice.xml\r\nServer: POSIX UPnP/1.0 linux/5.70.48.16\r\nST: upnp:rootdevice\r\nUSN: uuid:31474a87-67ea-dae4-2f73-f157fb06d22b::upnp:rootdevice\r\n\r\n'
# data = b'HTTP/1.1 200 OK\r\nCache-Control: max-age=3600\r\nST: upnp:rootdevice\r\nUSN: uuid:824ff22b-8c7d-41c5-a131-8c3bad401726::upnp:rootdevice\r\nEXT:\r\nServer:  Unspecified, UPnP/1.0, Unspecified\r\nLocation: http://192.168.3.1:56688/rootDesc.xml\r\n\r\n'

device = SSDPDevice(addr, data.decode())
services = device.get_services()

services_id = [services[i].id.split(":")[-1] for i in range(len(services))]

for id in services_id:
    service = device[id]
    actions = service.get_actions()
    for action in actions:
        for argument in action.arguments:
            print(id,action.name,argument.name)

Можно получить ряд информации о службах, часть информации показана ниже:

root@kitploit:~
WANIPConn1 AddPortMapping NewRemoteHost
WANIPConn1 AddPortMapping NewExternalPort
WANIPConn1 AddPortMapping NewProtocol
WANIPConn1 AddPortMapping NewInternalPort
WANIPConn1 AddPortMapping NewInternalClient
WANIPConn1 AddPortMapping NewEnabled
WANIPConn1 AddPortMapping NewPortMappingDescription
WANIPConn1 AddPortMapping NewLeaseDuration
WANIPConn1 DeletePortMapping NewRemoteHost
WANIPConn1 DeletePortMapping NewExternalPort
WANIPConn1 DeletePortMapping NewProtocol
WANIPConn1 GetExternalIPAddress NewExternalIPAddress

Эти службы можно примерно разделить на типы get, set и небольшое количество delete. Поскольку одна из основных целей UPnP – предоставлять доступ к устройствам внутренней сети из внешней, требуется определенная конфигурация (проброс портов и т.д.). Раз требуется конфигурация, необходимы параметры и информация, и эти параметры фактически являются параметрами служб типа set.

Локализация службы

Поскольку не все службы реализованы производителем, необходимо самостоятельно реверсировать прошивку. Сначала находим upnp_mainloop.

Untitled

Вся логика обработки реализована в upnp_dispatch. При дальнейшем анализе были обнаружены части обработки запросов ssdp и http.

Untitled

ssdp_process соответствует запросам M-Search при обнаружении, upnp_http_process – обработка HTTP-запросов. Поскольку обычные вызовы служб – это HTTP-запросы, можно предположить, что upnp_http_process может содержать уязвимость. Пример вызова службы показан на рисунке ниже.

Untitled

В upnp_http_process дополнительно вызывается upnp_http_fsm_emgine.

Untitled

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

Untitled

Эти функции включают инициализацию и разбор заголовков протокола. Последняя функция – upnp_http_fsm_dispatch, предполагается, что она выполняет соответствующую функцию службы.

Untitled

Заходим в upnp_http_fsm_dispatch и видим, что действительно вызываются функции, но вызов осуществляется на основе a1 и a2, поэтому нельзя определить конкретную вызываемую функцию без динамической отладки.

Untitled

Если это обычный ssdp-запрос обнаружения, вызываются SUB_405B34, description_process. Если запрос связан со службой, вызывается soap_process. В soap_process в зависимости от информации заголовка запроса вызывается query_process или action_process.

Основное внимание уделяем action_process. Исходя из заголовков запросов вызова служб, предполагаем, что soap_control в action_process соответствует вызову службы.

Untitled

В soap_control по-прежнему требуется динамическая отладка для определения конкретной информации о функциях.

Untitled

В конечном итоге с помощью динамической отладки было определено, что sub_414C28 соответствует action AddPortMapping, его цепочка вызовов:

root@kitploit:~
sub_414c28->upnp_portmap_add->upnp_osl_nat_config->strcpy(stack overflow)

Однако в upnp_portmap_add проверяется адрес WAN-интерфейса устройства. Поскольку во время тестирования WAN-интерфейс не был настроен, автор напрямую задал IP WAN через nvram.

Untitled

При переполнении стека необходимо направить поток выполнения в красный блок, потому что функция синего блока обращается к переполненному стеку, что приводит к краху программы до RCE. Поэтому нужно, чтобы значение *(a2+11) было равно 0. К счастью, это значение контролируемо.

Untitled

Эксплуатация уязвимости

Поскольку в последней прошивке нет telnetd, можно получить обратный shell, затем загрузить utelnetd и включить telnet.

display-exploit.gif

См. Способы получения обратного shell

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