NFsec Logo

Szybka identyfikacja procesów podsłuchujących ruch sieciowy

16/09/2025 (3 tygodnie temu) w Administracja, Bezpieczeństwo Możliwość komentowania Szybka identyfikacja procesów podsłuchujących ruch sieciowy została wyłączona

P

odsłuchiwanie ruchu sieciowego najczęściej kojarzy się nam z systemami typu: IDS/IPS lub narzędziami takimi, jak: tcpdump. Głównie programy te wykorzystywane są z różnych uzasadnionych powodów np. ochrona sieci lub rozwiązywanie problemów sieciowych. Czasami jednak proces ten może zostać użyty przez złośliwe oprogramowanie lub atakującego w celu kradzieży informacji, czy też aktywacji uśpionych tylnych wejść do systemu. Na szczęście za pomocą bezpośredniego dostępu do pliku /proc/net/packet możemy szybko zidentyfikować procesy powiązane z gniazdami pakietów. Tego typu gniazda (ang. sockets) służą do odbierania lub wysyłania surowych pakietów na poziomie sterownika urządzenia sieciowego (warstwa 2 OSI ; najczęściej karty sieciowej) pozwalając na bardziej bezpośrednią interakcję ze stosem sieciowym niż standardowe gniazda Berkeley w warstwie 4’tej (np. AF_INET / AF_INET6 + SOCK_STREAM / SOCK_DGRAM). Nas będzie interesować typ gniazda albo SOCK_RAW (dla surowych pakietów zawierających nagłówek warstwy łącza), albo SOCK_DGRAM (dla pakietów przetworzonych z usuniętym nagłówkiem warstwy łącza):

root@darkstar:~# cat /proc/net/packet
sk               RefCnt Type Proto  Iface R Rmem   User   Inode
ffff8f34c7d7d000 3      3    88cc   2     1 0      998    6666
ffff8f34c7d7c000 3      3    88cc   3     1 0      998    6685
ffff8f34c0b80000 3      3    0003   0     1 0      0      8767
ffff8f34c5243800 3      2    0003   0     1 0      0      9350

Nas będzie interesować ostatnia kolumna, czyli Inode, która pozwoli nam na identyfikację procesów i ich właścicieli. Pozostaje nam przeszukanie procfs pod numerach ze wspomnianej kolumny, aby otrzymać numery identyfikacyjne procesów odpowiedzialnych za otwarte gniazda pakietów:

root@darkstar:~# ls -al /proc/*/fd/* 2> /dev/null | egrep '(6666|6685|8767|9350)'
lrwx------ 1 root            root            64 Sep 1 19:44 /proc/1053/fd/3 -> socket:[8767]
lrwx------ 1 root            root            64 Sep 1 19:44 /proc/1067/fd/5 -> socket:[9350]
lrwx------ 1 systemd-network systemd-network 64 Sep 1 19:44 /proc/404/fd/18 -> socket:[6666]
lrwx------ 1 systemd-network systemd-network 64 Sep 1 19:44 /proc/404/fd/19 -> socket:[6685]

Powyżej widzimy dwa procesy (ID: 404) systemd przechwytujące ruch sieciowy (często są to protokoły wykrywania sieci i urządzeń sieciowych – tutaj LLDP [88cc]). Mamy również dwa kolejne podejrzane procesy (ID: 1053 oraz 1067), które wymagają zbadania – tym bardziej, że ich właścicielem jest administrator systemu i mają wartość protokołu 0003, który reprezentuje ETH_P_ALL. Oznacza to, że tego typu gniazdo pakietów skonfigurowane jest do przechwytywania każdego pakietu przechodzącego przez dany interfejs sieciowy (tryb promiscuous). Kiedy program tworzy gniazdo pakietów z protokołem ETH_P_ALL, w zasadzie mówi jądru systemu: „- Daj mi kopię wszystkich surowych ramek danych, które widzisz na tej karcie sieciowej”. Jest to podstawowa funkcja wykorzystywana przez narzędzia do analizy sieci:

root@darkstar:~# ls -al /proc/1053/cwd
lrwxrwxrwx 1 root root 0 Sep 16 19:57 /proc/1053/cwd -> /root

root@darkstar:~# ls -al /proc/1053/exe
lrwxrwxrwx 1 root root 0 Sep 16 19:57 /proc/1053/exe -> /usr/sbin/netsniff-ng

root@darkstar:~# cat /proc/1053/comm
netsniff-ng

root@darkstar:~# cat /proc/1053/cmdline
netsniff-ng--inany--filterport 80--jumbo-support--ascii-V

root@darkstar:~# cat /proc/1053/maps
62484cd10000-62484cd15000 r--p 00000000 08:02 533368  /usr/sbin/netsniff-ng
75fc96400000-75fc966c5000 r--p 00000000 08:02 683102  /usr/share/GeoIP/GeoIP.dat
75fc91c00000-75fc95c00000 rw-s 00000000 00:08 8767    socket:[8767]

root@darkstar:~# ls -al /proc/1067/cwd
lrwxrwxrwx 1 root root 0 Sep 16 20:10 /proc/1067/cwd -> /root

root@darkstar:~# ls -al /proc/1067/exe
lrwxrwxrwx 1 root root 0 Sep 16 20:10 /proc/1067/exe -> /usr/bin/tcpflow

root@darkstar:~# cat /proc/1067/comm
tcpflow

root@darkstar:~# cat /proc/1067/cmdline
tcpflow-iany-cport80

root@darkstar:~# cat /proc/1067/maps
60590f0bd000-60590f0c5000 r--p 00000000 08:02 531829  /usr/bin/tcpflow
7c0bf2b0a000-7c0bf2d0a000 rw-s 00000000 00:08 9350    socket:[9350]

Oczywiście, aby przyśpieszyć ten proces, możemy użyć takich poleceń jak lsof oraz ss. Programy te są przydatne, jeśli są już zainstalowane w systemie, ale istnieją pewne zastrzeżenia. Po pierwsze – jeśli ich nie ma w systemie nie możemy ich zainstalować, ponieważ zmienimy stan badanego systemu i możemy nadpisać dowody kompromitacji systemu. Po drugie niektóre warianty złośliwego oprogramowania często przechwytują wywołania systemowe i filtrują wyniki programów, aby ukryć się przed takimi narzędziami, więc istnieje ryzyko, że nic nie ustalimy. Niemniej warto znać ich zastosowanie:

root@darkstar:~# lsof -p 1053
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF   NODE NAME
netsniff- 1053 root  cwd    DIR    8,2     4096 655362 /root
netsniff- 1053 root  txt    REG    8,2   250136 533368 /usr/sbin/netsniff-ng
netsniff- 1053 root  mem    REG    0,8            8767 socket:[8767]
netsniff- 1053 root    3u  pack   8767      0t0    ALL type=SOCK_RAW

root@darkstar:~# lsof -p 1067
tcpflow 1067 root  cwd       DIR    8,2     4096 655362 /root
tcpflow 1067 root  txt       REG    8,2   581064 531829 /usr/bin/tcpflow
tcpflow 1067 root  mem       REG    0,8            9350 socket:[9350]
tcpflow 1067 root    5u     pack   9350      0t0    ALL type=SOCK_DGRAM

root@darkstar:~# ss -0 -p
Netid  Recv-Q  Send-Q  Local Address:Port  Peer Address:Port  Process
p_raw  0       0              LLDP:enp0s3              *      users:(("systemd-network",
                                                                       pid=404,fd=18))
p_raw  0       0              LLDP:enp0s8              *      users:(("systemd-network",
                                                                       pid=404,fd=19))
p_raw  0       0                 *:*                   *      users:(("netsniff-ng",
                                                                       pid=1053,fd=3))
p_dgr  0       0                 *:*                   *      users:(("tcpflow",
                                                                       pid=1067,fd=5))

Teraz już wiemy, jak /proc/net/packet może pomóc nam ujawnić podsłuchujące ruch sieciowy procesy, a nawet może ujawnić rozbieżność z tym, co widzimy w wynikach ze standardowych narzędzi.

Więcej informacji: Detecting Packet Sniffing Malware on Linux, List packet sniffers

Ograniczenie SSH do konkretnego portu źródłowego klienta

17/07/2025 w Administracja, Bezpieczeństwo Możliwość komentowania Ograniczenie SSH do konkretnego portu źródłowego klienta została wyłączona

N

aszym zadaniem jest wystawienie usługi SSH do internetu, ale nie chcemy by ktoś oprócz naszej wiedzy tajemnej mógł się do niej połączyć. Nie będziemy używali rozwiązań typu VPN, port knocking, czy zmiany portu nasłuchu z 22 na inny. Secure Shell będzie nasłuchiwać na standardowym porcie i umożliwiała połączenie z dowolnego adresu IP. Jedynym warunkiem, jaki musi spełnić klient SSH to nawiązanie połączenia z konkretnego, tylko nam znanego portu źródłowego – w przeciwnym wypadku firewall nie dopuści do połączenia:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -p tcp --dport 22 --sport 31337 -m state --state NEW -j ACCEPT
iptables -A INPUT -j DROP

Jeśli spróbujemy teraz połączyć się ze standardowej puli źródłowych portów (1024:65535) klientem SSH – nasze połączenie zostanie odrzucone:

heavyarms:~ agresor$ ssh 192.168.254.2 -v
OpenSSH_9.9p2, LibreSSL 3.3.6
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files
debug1: /etc/ssh/ssh_config line 54: Applying options for *
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: Connecting to 192.168.254.2 [192.168.254.2] port 22.

Zupełnie inaczej będzie to wyglądało kiedy wykorzystamy opcję klienta SSH o nazwie ProxyCommand, która wykorzysta pośrednie połączenie przez program netcat, który będzie miał ustawiony port źródłowy połączenia na stały numer 31337:

heavyarms:~ agresor$ ssh -o ProxyCommand="nc -p 31337 %h %p" 192.168.254.2 -v
OpenSSH_9.9p2, LibreSSL 3.3.6
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/* matched no files
debug1: /etc/ssh/ssh_config line 54: Applying options for *
debug1: Authenticator provider $SSH_SK_PROVIDER did not resolve; disabling
debug1: Executing proxy command: exec nc -p 31337 192.168.254.2 22
debug1: Next authentication method: password
agresor@192.168.254.2's password:

Ten prosty mechanizm Security Through Obscurity pozwala nam na zdalny dostęp do serwera z dowolnego adresu IP jednocześnie trzymając zautomatyzowane boty atakujące SSH z daleka.

Więcej informacji: How can I set the source port for an SSH command-line client?, How does SSH’s ProxyCommand actually work?

Fałszywy rozmiar pliku /var/log/lastlog

19/05/2025 w Administracja, Debug Możliwość komentowania Fałszywy rozmiar pliku /var/log/lastlog została wyłączona

P

lik lastlog, znajdujący się w ścieżce /var/log/lastlog, jest plikiem typu „niegęstego” (ang. sparse file), który próbuje wykorzystać przestrzeń systemu plików bardziej efektywnie, gdy sam plik jest częściowo pusty. Osiąga się to poprzez zapisywanie krótkich informacji (metadanych) reprezentujących puste bloki na nośniku danych zamiast rzeczywistej „pustej” przestrzeni, która tworzy blok, zużywając w ten sposób mniej miejsca. Pełny blok jest zapisywany na nośniku jako rzeczywisty rozmiar tylko wtedy, gdy blok zawiera „rzeczywiste” (niepuste) dane. Dla codziennego użytkowania systemu Linux oznacza to, że jego zgłaszany rozmiar (np. przez polecenie ls) może być znacznie większy niż rzeczywista przestrzeń, jaką zajmuje na dysku.
[ czytaj całość… ]

Podpisywanie plików za pomocą certyfikatów TLS

21/05/2024 w Administracja, Bezpieczeństwo Możliwość komentowania Podpisywanie plików za pomocą certyfikatów TLS została wyłączona

J

akiś czas temu dowiedzieliśmy się, że klucze OpenSSH mogą posłużyć do podpisywania plików lub commitów git. Do tego samego celu możemy wykorzystać klucze używane w certyfikatach SSL/TLS (pozyskane z dowolnej strony, która jest dostępna za pomocą protokołu HTTPS). Pierwszym krokiem jest stworzenie pliku z wiadomością:

echo 'TOP Secret Message' > msg.txt

Drugim jest podpisanie pliku za pomocą prywatnego klucza, który znajduje się na serwerze:

openssl dgst -sha256 -sign /etc/apache2/ssl/server.key -out msg.txt.sig msg.txt

Trzecim jest konwersja pliku msg.txt.sig z formatu binarnego do tekstowego używając BASE64:

openssl base64 -in msg.txt.sig -out msg.txt.sig.asc

Jeśli teraz opublikujemy plik z wiadomością msg.txt oraz jego podpis: msg.txt.sig.asc, każdy posiadający dostęp do strony będzie mógł zweryfikować jej autentyczność. W pierwszym kroku użytkownik musi uzyskać klucz publiczny:

openssl s_client -connect nfsec.pl:443 | openssl x509 -pubkey -noout > pubkey.key

Następnie użytkownik musi ponownie zamienić opublikowaną sygnaturę tekstową do formy binarnej:

openssl base64 -d -in msg.txt.sig.asc -out msg.txt.sig

i zweryfikować poprawność wiadomości za pomocą pobranego klucza:

user@user:~$ openssl dgst -keyform pem -verify pubkey.key -signature msg.txt.sig msg.txt
Verified OK

Ale to nie wszystko. Skoro użytkownik może bardzo prosto pozyskać klucz publiczny serwera to jest w stanie szyfrować wiadomości przeznaczone do jego administratora lub właściciela:

openssl pkeyutl -in msg.txt -out to_agresor.enc -pubin -inkey pubkey.key -encrypt

Tak przesłana wiadomość może zostać odczytana za pomocą klucza prywatnego, który został użyty w certyfikacie TLS/SSL danego serwera:

root@stardust:~# openssl pkeyutl -in to_agresor.enc -out msg.txt -inkey \
                 /etc/apache2/ssl/server.key -decrypt
root@stardust:~# cat msg.txt
TOP Secret Message

W ten sposób każdy użytkownik może zaszyfrować wiadomość dla właścicieli swoich ulubionych stron internetowych – nawet jeśli nie publikują one jawnie klucza publicznego.

Więcej informacji: Using HTTPS certificates to sign/encrypt arbitrary data

Przyśpieszanie procesu budowania obrazów kontenerów

25/04/2024 w Administracja Możliwość komentowania Przyśpieszanie procesu budowania obrazów kontenerów została wyłączona

W

procesie budowy obrazów kontenerów wykorzystywanych do uruchamiania aplikacji lub serwerów najbardziej czasochłonną częścią jest instalacja zależności w postaci paczek systemowych. Proces ten jest z reguły powolny, ponieważ menedżery pakietów są stworzone w taki sposób, aby przedkładać stabilność instalacji nad jej wydajnością. I to ma sens: jeśli podczas instalacji wydarzy się niezapowiedziana awaria zasilania lub zawieszenie procesu, system musi pozostać w stanie nadającym się do użytku. Jednak w przypadku budowania obrazów kontenerów stabilność nie stanowi priorytetu. Jeśli proces instalacji pakietów lub kompilacji źródeł się nie powiedzie – system budujący obraz go odrzuci, zakończy proces błędem i będziemy musieli zacząć od nowa. Dlatego gdybyśmy mogli zasugerować menedżerowi pakietów, że nie przejmujemy się zbytnio integralnością danych, moglibyśmy przyspieszyć nasze kompilacje.
[ czytaj całość… ]

Hartowanie (sub)domen nieużywanych do wysyłki i odbioru poczty

14/03/2024 w Administracja, Bezpieczeństwo Możliwość komentowania Hartowanie (sub)domen nieużywanych do wysyłki i odbioru poczty została wyłączona

W

internecie możemy być właścicielem wielu domen, a w ramach nich rejestrować wiele subdomen. Nasze (sub)domeny mogą być używane do bardzo wielu zastosowań: obsługi strony (aplikacji) internetowej, poczty, serwera plików, serwera DNS, ochrony marki, działalności w wielu krajach itd. Wiele z tych (sub)domen będzie uniwersalna – zawierając pod sobą większość z wymienionych usług, a jeszcze większa ilość (licząc z subdomenami) będzie ukierunkowana na świadczenie konkretnej usługi. Jeśli nasza (sub)domena nie jest przeznaczona do obsługi poczty e-mail, niezależnie od tego, czy jest to poczta przychodząca (chcemy ją odbierać), czy wychodząca (chcemy ją wysyłać), również musimy zadbać o jej prawidłową konfigurację, aby zapobiec wykorzystywaniu tej (sub)domeny do nieuczciwych działań w internecie (czyt. podszywaniu się i wysyłaniu phishingu).
[ czytaj całość… ]

Wykrywanie skażonych modułów jądra

15/01/2024 w Administracja, Bezpieczeństwo Możliwość komentowania Wykrywanie skażonych modułów jądra została wyłączona

I

nformację o modułach załadowanych w systemie Linux znajdziemy w kopalni wiedzy o systemie, czyli wirtualnym systemie plików procfs. W celu wyświetlenia aktualnie zarejestrowanych (nie ukrywających się) modułów wystarczy wykonać polecenie: cat /proc/modules. Naszym oczom powinny ukazać się linie zawierające od sześciu do siedmiu kolumn:

x_tables 45056 3 xt_owner,xt_tcpudp,ip6_tables, Live 0xffffffffc044b000

  • x_tables – pierwsza kolumna wyświetla tytuł / nazwę modułu,
  • 45056 – druga kolumna to wielkość modułu (podana w bajtach) – nie mylić z używaną pamięcią,
  • 3 – trzecia kolumna podaje liczbę załadowanych instancji danego modułu – moduł z zerową wartością jest uważany za niezaładowany, a gdy liczba referencyjna modułu jest dodania (różna od zera), zwolnienie go za pomocą rmmod staje się niemożliwe, ponieważ polecenie wyświetli komunikat błędu: rmmod: ERROR: Module x_tables is in use by: xt_tcpudp xt_owner ip6_tables,
  • xt_owner,xt_tcpudp,ip6_tables – w czwartej kolumnie znajdują się moduły odwołujące się / zależne, które wymagają tego modułu do swojego funkcjonowania – w przypadku braku odniesień wyświetlany jest znak „-„,
  • Live – stan załadowania modułu wyrażony jest w piątej kolumnie, które może przyjmować tylko jedną z wartości: Live (żywy / aktywny), Loading (w trakcie ładowania), Unloading (w trakcie pozbywania się),
  • 0xffffffffc044b000 – szósta kolumna wyświetla aktualne przesunięcie pamięci jądra wykorzystywane przez załadowany moduł, co może być przydatne przy procesie debugowania lub profilowania.

W niektórych przypadkach możemy również trafić na wpisy, które będą posiadały siódmą kolumnę – tzw. skażone stany (ang. tainted states) . Kiedyś reprezentowane przez nią symbole znajdowały się w pliku panic.c (aktualnie zostały przeniesione do sekcji dokumentacji kernel.rst):

======  =====  ==============================================================
     1  `(P)`  proprietary module was loaded
     2  `(F)`  module was force loaded
     4  `(S)`  kernel running on an out of specification system
     8  `(R)`  module was force unloaded
    16  `(M)`  processor reported a Machine Check Exception (MCE)
    32  `(B)`  bad page referenced or some unexpected page flags
    64  `(U)`  taint requested by userspace application
   128  `(D)`  kernel died recently, i.e. there was an OOPS or BUG
   256  `(A)`  an ACPI table was overridden by user
   512  `(W)`  kernel issued warning
  1024  `(C)`  staging driver was loaded
  2048  `(I)`  workaround for bug in platform firmware applied
  4096  `(O)`  externally-built ("out-of-tree") module was loaded
  8192  `(E)`  unsigned module was loaded
 16384  `(L)`  soft lockup occurred
 32768  `(K)`  kernel has been live patched
 65536  `(X)`  Auxiliary taint, defined and used by for distros
131072  `(T)`  The kernel was built with the struct randomization plugin
======  =====  ==============================================================

Dlatego, jeśli trafimy na wpis podobny do:

suspicious_module 110592 2 - Live 0xffffffffc0724000 (OE)

Możemy go odczytać, jako załadowanie modułu zewnętrznego (O) – spoza aktualnego drzewa modułów uruchomionego jądra systemu, który w dodatku nie jest podpisany (E). Wszystkie takie „skażone” moduły możemy wyświetlić poprzez polecenie:

grep \(.*\) /proc/modules

Podobnie możemy szukać wyrażenia taint w poleceniu dmesg lub journalctl --dmesg.

Więcej informacji: Tainted kernels, What is OE+ in Linux?, Craig Rowland on Twitter

Krótkie wprowadzenie do bibliotek w systemie Linux

28/07/2023 w Administracja Możliwość komentowania Krótkie wprowadzenie do bibliotek w systemie Linux została wyłączona

W

programowaniu biblioteka jest zbiorem wstępnie skompilowanych fragmentów kodu. Bibliotekę programistyczną możemy ponownie wykorzystać w różnych programach, które mają mieć zaimplementowane obsługę tych samych zadań. Są bardzo przydatne, ponieważ zapewniają funkcje, klasy i struktury danych wielokrotnego użytku. Niektóre przykłady bibliotek w systemie Linux to glibc (wersja GNU standardowej biblioteki C), libc (standardowa biblioteka C). Biblioteki możemy podzielić na dwie główne kategorie: biblioteki statyczne (ang. static libraries) – związane statycznie z programem w czasie kompilacji; biblioteki współdzielone (ang. shared libraries) – ładowane podczas uruchamiania programu i ładowane do pamięci w czasie wykonywania.
[ czytaj całość… ]

Apache – kompresja brotli z awaryjnym powrotem do deflate

16/05/2023 w Administracja Możliwość komentowania Apache – kompresja brotli z awaryjnym powrotem do deflate została wyłączona

O

d wersji Apache 2.4.26 dostępny jest moduł umożliwiający kompresję statycznych elementów strony za pomocą algorytmu brotli. Jego szybkość jest podobna do gzip, ale zapewnia wyższą kompresję. Aktualnie algorytm ten jest już obsługiwany przez wszystkie główne przeglądarki, takie jak: Chrome, Firefox, Safari i Edge. W poniższej konfiguracji włączymy kompresję brotli dla reprezentatywnej grupy statycznych plików, ale zapewnimy również powrót do kompresji gzip, gdyby klient nie obsługiwał tej pierwszej.
[ czytaj całość… ]

Podpisywanie plików za pomocą kluczy SSH

09/05/2023 w Administracja, Bezpieczeństwo Możliwość komentowania Podpisywanie plików za pomocą kluczy SSH została wyłączona

O

podpisywaniu commitów przez SSH już wiemy. Ale czy wiesz, że możesz użyć polecenia ssh-keygen do podpisywania i weryfikowania podpisów na dowolnych danych, takich jak pliki w wypuszczane wersje oprogramowania? Funkcja ta została dodana wraz w wersją OpenSSH 8.0, dlatego jeśli używasz Debian Bullseye / Ubuntu 20.04 lub nowsze – masz już zainstalowaną wystarczająco nową wersję SSH, aby korzystać z tej funkcjonalności. W dodatku jeśli korzystasz z serwisu GitHub lub jakiejkolwiek innej usługi, która używa kluczy SSH do uwierzytelniania to pewnie masz już klucz SSH, którego można użyć do generowania podpisów (jeśli nie to zajmiemy się tym później). Dystrybucja kluczy SSH jest łatwa, ponieważ publiczne klucze SSH to krótkimi jednowierszowymi ciągami, które łatwo skopiować. W dodatku możemy użyć wspomnianego serwisu GitHub jako dystrybutora kluczy – możesz pobrać klucze publiczne SSH dla dowolnego użytkownika odwiedzając adres URL w postaci: https://github.com/$nazwa_użytkownika.keys np. NFsec.
[ czytaj całość… ]