NFsec Logo

Zabawy z Socket Cat i TCP/IP Gender Changer

Wczoraj w Administracja, Bezpieczeństwo Brak komentarzy.  (artykuł nr 944, ilość słów: 1218)

S

Ocket CAT, czyli socat to uniwersalne narzędzie dla systemów *nix służące do dwukierunkowego transferu danych pomiędzy dwoma niezależnymi kanałami danych. Tymi kanałami mogą być: pliki, potoki, urządzenia, gniazda (SSL, Unix, IPv4, IPv6, surowe, UDP, TCP), proxy, deskryptory plików (standardowe wejścia, wyjścia itp.). Można go używać jako potężniejszy odpowiednik netcat, umożliwiający przekierowywanie portów, tworzenie i ograniczanie bezpiecznych połączeń, rozwiązywanie problemów sieciowych, czy realizację zaawansowanych scenariuszy przesyłania danych – działając jak „szwajcarski scyzoryk” do obsługi gniazd sieciowych i strumieni do komunikacji między procesami. Poniżej znajduje się kilka przykładów jego zastosowania:

socat TCP4-LISTEN:31337,bind=127.0.0.1,fork TCP4:nfsec.pl:80

Przekazujemy komunikację na adresie IPv4 127.0.0.1 i porcie 3137 do portu 80 serwera nfsec.pl. Zezwalamy na wiele połączeń (fork) za pomocą procesów potomnych. Jego działanie możemy sprawdzić za pomocą narzędzia curl:

root@darkstar:~# curl -v -H 'Host: nfsec.pl' http://localhost:31337 -A "Linux Terminal"
* Host localhost:31337 was resolved.
* Connected to localhost (127.0.0.1) port 31337
> GET / HTTP/1.1
> Host: nfsec.pl
> User-Agent: Linux Terminal
> Accept: */*
>
< HTTP/1.1 301 Moved Permanently

Możemy też wykonać tunel HTTP do HTTPS:

socat TCP4-LISTEN:31337,bind=127.0.0.1,fork OPENSSL:nfsec.pl:443,verify=0

Przekazujemy komunikację na adresie IPv4 127.0.0.1 i porcie 3137 do portu 443 serwera nfsec.pl. Narzędzie curl wykonuje żądanie HTTP otrzymując dane z HTTPS:

root@darkstar:~# curl -I -H 'Host: nfsec.pl' http://localhost:31337 -A "Linux Terminal"
HTTP/1.1 200 OK

Kolejnym przykładem jest udostępnienie gniazda domeny Unix (ang. Unix Domain Socket) serwera MySQL, które służy do lokalnej komunikacji międzyprocesowej (IPC – Inter-Process Communication) w obrębie tego samego systemu jako port TCP:

socat TCP4-LISTEN:31337,fork,range=127.0.0.1/32 UNIX-CONNECT:/var/run/mysqld/mysqld.sock

Warto zauważyć, że zezwalamy tylko na łączność z adresu localhost (range=127.0.0.1/32):

root@darkstar:~# mysql --user root --host 127.0.0.1 --port 31337
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11

Jeśli nie chcemy tworzyć tunelów możemy nadać czemuś kształt na wzór własnego serwera WWW, który będzie logował wszystkie żądania HTTP do pliku:

socat -T5 -u TCP4-LISTEN:80,fork,su=www-data OPEN:/tmp/requests.log,creat,append

Ustawiamy czas braku aktywności na 5 sekund (-T5), ponieważ nasz serwer nie będzie odpowiadać żadnymi danymi, tym samym wiele klientów HTTP zostanie „uwięzionych” za pomocą własnych ustawień dotyczących czasu braku odpowiedzi:

root@darkstar:~# time curl http://localhost:80
curl: (52) Empty reply from server

real    0m5.053s
user    0m0.009s
sys     0m0.008s

root@darkstar:~# ls -al /tmp/requests.log
-rw-r--r-- 1 www-data www-data 984 Jan 23 21:31 /tmp/requests.log

root@darkstar:~# cat /tmp/requests.log
GET / HTTP/1.1
Host: localhost
User-Agent: curl/8.5.0
Accept: */*

Nic też nie stoi na przeszkodzie, aby tworzyć bardziej zaawansowane połączenia, jak zaszyfrowany tunel do powłoki, który będzie weryfikował certyfikat klienta. Na początku tworzymy certyfikat i dystrybuujemy go zarówno na serwer, jak i klienta:

openssl req -newkey rsa:2048 -nodes -keyout server.key \
        -x509 -days 365 -out server.crt -subj "/CN=p0wned"

Na serwerze uruchamiamy „usługę https”, która w rzeczywistości jest bramką do interaktywnej powłoki:

socat OPENSSL-LISTEN:443,fork,cert=server.crt,key=server.key,cafile=server.crt \
      EXEC:"bash -i",pty,stderr,setsid,sigint,sane

Na kliencie używamy tych samych certyfikatów, aby się do niej dostać i otrzymać prompt powłoki:

socat stdio,raw,echo=0 \
OPENSSL:darkstar:443,cert=server.crt,key=server.key,cafile=server.crt,commonname=p0wned

A może mały IDS (ang. Intrusion Detection System) ? Ktokolwiek połączy się na wybrany port zostanie zablokowany na dwie godziny:

ipset create scanners_ip hash:ip timeout 7200
iptables -I INPUT -m set --match-set scanners_ip src -j DROP
for port in 8080 8181 3128; do
  socat -u TCP4-LISTEN:$port,fork SYSTEM:'ipset add scanners_ip $SOCAT_PEERADDR -exist' &
done

Ponieważ nie chcemy zwracać żadnych błędów klientowi dodaliśmy parametr -u – tryb jednokierunkowy (ang. unidirectional. Oznacza to, że socat na pierwszym adresie prowadzącym nasłuch będzie tylko odbierać / czytać dane, a na drugim je zapisywać. Cokolwiek zwróci polecenie ipset lub socat nie zostanie to zaprezentowane klientowi.

TCP/IP Gender Changer:

Zanim zaczniemy to warto wytłumaczyć sam termin, ponieważ nie odnosi się on do: płci, adapteru, czy przejściówki umożliwiającej połączenie dwóch złączy tego samego typu, np. męski-męski lub żeński-żeński. W poruszanym kontekście odnosi się do żartobliwego określenia zamiany ról klienta i serwera. Zazwyczaj serwer „nasłuchuje” (jest pasywny), a klient „łączy się” (jest aktywny). Technika „gender changer” pozwala dwóm podmiotom, które działają jako klienci (lub oba działają jako serwery), komunikować się ze sobą za pomocą pośrednika, który odwraca logikę uzgadniania połączenia. Najczęstszym przypadkiem jej użycia jest przejście przez mechanizm NAT (ang. NAT Traversal) lub zaporę sieciową (ang. firewall). Jeśli znajdujemy się za restrykcyjnym „ogniomurkiem”, który blokuje połączenia przychodzące, nie możemy sobie po prostu „nasłuchiwać” usługą i oczekiwać połączenia z zewnątrz – podobna technika dla protokołu UDP została opisana tutaj. Potrzebujemy wówczas pośrednika (ang. relay) w środku, który zaakceptuje dwa połączenia przychodzące i połączy je ze sobą w dwustronną komunikację. Poniżej mała demontracja jak przeprowadzić wspomnianą technikę za pomocą socat:

[ wingzero ]---[ mikrotik (NAT, Firewall) ]---[ darkstar (Relay) ]---[ heavyarms ]

Na maszynie wingzero nasłuchuje prosty serwer HTTP na porcie 8000 (python3 -m http.server). Nie jest on w żaden sposób udostępniony na routerze mikrotik, który zajmuje się NATowaniem adresów i ochroną sieci LAN. Dlatego klient heavyarms nie jest w stanie się do niego w żaden sposób dostać. Kluczową rolą będzie tutaj serwer darkstar, który połączy nam je ze sobą. Na nim uruchamiamy socat w trybie nasłuchu na dwóch różnych portach. To jest właśnie ten „gender changer” (podwójny serwer na zewnętrznym kliencie), który będzie czekać, aż obie strony (wingzero i heavyarms) same się do niego zgłoszą:

agresor@darkstar:~$ socat TCP4-LISTEN:8000,reuseaddr,fork TCP4-LISTEN:8080,reuseaddr,fork

Teraz na wingzero uruchamiamy podobny zestaw (podwójny klient na wewnętrznym serwerze), ale łączymy się do darkstar na porcie 8000 oraz localhost na porcie 8000 (gdzie nasłuchuje nasz serwer HTTP):

agresor@wingzero:~$ socat TCP4:darkstar.nfsec.pl:8000,forever,interval=10,fork \
                          TCP4:localhost:8000,fork

Flagi: forever i interval=10 powodują, że będziemy w nieskończoność, co 10 sekund próbować nawiązywać połączenie, a po każdym sukcesie tworzyć proces potomny, który połączy się również z wewnętrznym serwerem HTTP i rozpocznie przesyłanie danych. Czas na heavyarms! Jego rola jest bardzo prosta – musi uruchomić klienta HTTP, który połączy się z portem 8080 darkstar, a ten go „sparuje” z wingzero:

agresor@heavyarms:~$ curl -v darkstar.nfsec.pl:8080
* Host darkstar.nfsec.pl:8080 was resolved.
* Trying 147.135.209.161:8080...
* Connected to stardust.nfsec.pl (147.135.209.161) port 8080
> GET / HTTP/1.1
> Host: darkstar.nfsec.pl:8080
> User-Agent: curl/8.5.0
> Accept: */*
>
> HTTP/1.0 200 OK
> Server: SimpleHTTP/0.6 Python/3.13.5
> Date: Wed, 28 Jan 2026 21:28:22 GMT
> Content-type: text/html; charset=utf-8
> Content-Length: 964

agresor@wingzero:~ $ python3 -m http.server
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
127.0.0.1 - - [28/Jan/2026 21:28:22] "GET / HTTP/1.1" 200 -

Wszystko przebiegło pomyślnie – uzyskaliśmy komunikację z serwerem wewnątrz sieci LAN stojącym za zaporą ogniową. Oczywiście możemy jeszcze bardziej uprościć ten schemat i wyeliminować z tej komunikacji host heavyarms, ponieważ port 8080 na darkstar jest osiągalny z tej samej maszyny i nie potrzebujemy kolejnego serwera, aby uruchomić polecenie curl:

agresor@darkstar:~$ curl -I localhost:8080
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/3.13.5
Date: Wed, 28 Jan 2026 21:44:16 GMT
Content-type: text/html; charset=utf-8
Content-Length: 964

Niemniej dzięki heavyarms osiągnęliśmy wyróżnienie roli darkstar jako pośrednika, który „skleił” to wszystko i zaoferował nam dwustronną komunikację pomiędzy różnymi maszynami znajdującymi się w rożnego rodzaju sieciach. I ten oto sposób klienci zostali zamienieni w serwery, a serwery w klientów. Pamiętajmy również, że takie połączenia TCP nie są szyfrowane. Jeśli chcemy w ten sposób przesyłać wrażliwe dane, lepiej jest użyć OPENSSL(:|-LISTEN).

Podsumowanie:

Podczas, gdy narzędzia typu netcat od dawna uznawane są za niezbędnik sieciowca, socat wyłania się tutaj jako bardziej zaawansowana złączka wielofunkcyjna. Oczywiście prostota netcat sprawia, że idealnie nadaje się do wielu zadań przy podstawowych połączeniach TCP/UDP. Natomiast socat rozszerza te możliwości o solidne szyfrowanie SSL/TLS, zaawansowane łańcuchy proxy i skomplikowane translacje różnych protokołów połączonych w tunele.

Więcej informacji: TCP/IP Gender Changer, Example for TCP 'GENDER CHANGER’ using SoCAT, socat examples

Kategorie K a t e g o r i e : Administracja, Bezpieczeństwo

Tagi T a g i : , , , , ,

Brak nowszych postów

Komentowanie tego wpisu jest zablokowane.