Home Hack The Box Writeup - Fuse
Post
Cancel

Hack The Box Writeup - Fuse

Fuse is a medium Windows box. During the enumeration of the target machine, we found a webserver running an instance of Papercut Printer Logger. The logs of the software revealed a few usernames that were then used to enumerate the RPC/SMB servers. Unfortunately, the server did not support null sessions thus we first had to find a valid password. Fortunately for us, the password was set to the name of the company. At this point, we were finally able to further enumerate the SMB shares and the RPC server. While the SMB shares were not that helpful, we were able to obtain an extended list of usernames as well as password through the issued RPC commands. As it turned out, one of the service users was indeed using that leaked password, which allowed us to get initial access to the system. Once we had access to the system, we discovered that our user had the SeLoadDriverPrivilege privilege enabled. We exploited that privilege by uploading our own vulnerable device driver (capcom) and then used EoPLoadDriver to exploit a vulnerability in that driver. This ultimately gave us access to the system as nt authority\system.

Enumeration

As always, we start by scanning the target machine’s open ports:

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
32
33
34
rustscan --ulimit 5000 fuse.htb -- sV -sC -oN nmap_scan

PORT      STATE SERVICE      REASON  VERSION                                                                      
53/tcp    open  domain       syn-ack Simple DNS Plus                                                              
80/tcp    open  http         syn-ack Microsoft IIS httpd 10.0                                                     
|_http-server-header: Microsoft-IIS/10.0                                                                          
| http-methods:                                                                                                   
|   Supported Methods: OPTIONS TRACE GET HEAD POST                                                                
|_  Potentially risky methods: TRACE                                                                              
|_http-title: Site doesn't have a title (text/html).                                                              
88/tcp    open  kerberos-sec syn-ack Microsoft Windows Kerberos (server time: 2022-06-27 10:56:48Z)               
135/tcp   open  msrpc        syn-ack Microsoft Windows RPC                                                        
139/tcp   open  netbios-ssn  syn-ack Microsoft Windows netbios-ssn                                                
389/tcp   open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: fabricorp.local, Site: Defau
lt-First-Site-Name)                                                                                               
445/tcp   open  microsoft-ds syn-ack Windows Server 2016 Standard 14393 microsoft-ds (workgroup: FABRICORP)       
464/tcp   open  kpasswd5?    syn-ack                                                                              
593/tcp   open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0                                          
636/tcp   open  tcpwrapped   syn-ack                                                                              
3268/tcp  open  ldap         syn-ack Microsoft Windows Active Directory LDAP (Domain: fabricorp.local, Site: Defau
lt-First-Site-Name)                                                                                               
3269/tcp  open  tcpwrapped   syn-ack                                                                              
5985/tcp  open  http         syn-ack Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)                                      
|_http-server-header: Microsoft-HTTPAPI/2.0                                                                       
|_http-title: Not Found                                                                                           
9389/tcp  open  mc-nmf       syn-ack .NET Message Framing                                                         
49666/tcp open  msrpc        syn-ack Microsoft Windows RPC                                                        
49667/tcp open  msrpc        syn-ack Microsoft Windows RPC                                                        
49675/tcp open  ncacn_http   syn-ack Microsoft Windows RPC over HTTP 1.0                                          
49676/tcp open  msrpc        syn-ack Microsoft Windows RPC
49678/tcp open  msrpc        syn-ack Microsoft Windows RPC
49698/tcp open  msrpc        syn-ack Microsoft Windows RPC
49754/tcp open  msrpc        syn-ack Microsoft Windows RPC
Service Info: Host: FUSE; OS: Windows; CPE: cpe:/o:microsoft:windows

The output of the port scan tells us that we are most likely dealing with a Windows Server, as it exposes a Kerberos service, RCP, LDAP, SMB and many other Windows Server typical ports. Our main targets will be:

  • Port 80 - Microsoft IIS
  • Port 88 - Kerberos
  • Port 135 - RPC
  • Port 139/445 - SMB
  • Port 3268 - LDAP
  • Port 5985 - WinRM

Enumeration Port 80 - IIS 10.0

Let’s start with the enumeration of the Microsoft IIS web server. Looking at the website, we can see that we are being redirected to the domain fuse.fabricorp.local. As the DNS server cannot resolve this domain, we get the error ...cannot connect to the server at....

A way to fix this issue is to add an entry in the /etc/hosts file which maps the IP to the domain name. Afterwards, we can access the web page as intended.

Here, we see an instance of PaperCut Print Logger. A quick lookup in the offical documentation reveals some interesting behaviour:

1
2
3
The software will keep detailed activity log/logs of all user printing activity including information such as: 
  1) The user who printed (ie. their network user ID) 
  ...

This means, by looking at the logs we might be able to gather existing usernames. And indeed! We can find a bunch of usernames in the User field as well as in the Document field.

The discovered usernames are:

1
2
3
4
5
6
sthompson
bhult
administrator
pmerton
tlavel
bnielson

Enumeration Kerberos - ASREP-Roasting

Now that we have a list of potential usernames, we can check if one of them has the Kerberos PREAUTH disabled. To check that, we can use Impacket's GetNPUsers.py. Unfortunaly, our findings show that all of them require PREAUTH.

Getting Access to SMB/RPC

The next step is to check if we can access the SMB shares and the RPC service. However, running enum4linux-ng shows that we can neither of these services. Apparently the server does not allow anonymous sessions nor null sessions. This means, we must find a password for the found usernames. First, let’s try a small, common password list such as xato-net-10-million-passwords-10000.txt.

1
2
┌──(kali㉿kali)-[~/HTB/machines/fuse]
└─$ crackmapexec smb 10.129.2.5 -u usernames -p /usr/share/seclists/Passwords/xato-net-10-million-passwords-10000.txt 

But…. we do not find any matching password. I then replaced the small password list with rockyou.txt. After several hours of trying different passwords: Still no match!

Generating a password-list using cewl

Hmmmm, maybe we missed something on the website. However instead of looking for the password manually, we can use the tool cewl to crawl for all words on the website and convert them into a password list.

1
2
┌──(kali㉿kali)-[~/HTB/machines/fuse]
└─$ cewl http://fuse.fabricorp.local/papercut/logs/html/index.htm --with-numbers > wordlist

Here’s an excerpt of the generated wordlist.

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~/HTB/machines/fuse]
└─$ head wordlist                                                                                                                                                                   130 ⨯
CeWL 5.5.2 (Grouping) Robin Wood (robin@digi.ninja) (https://digi.ninja/)
Print
2020
PaperCut
Logs
MFT01
PCL6
CSV
Excel
Logger

Let’s try it again. Maybe the password is somewhere hidden on the website without us ever noticing.

1
2
┌──(kali㉿kali)-[~/HTB/machines/fuse]
└─$ crackmapexec smb 10.129.122.50 -u usernames -p wordlist --continue-on-success | tee crackmapexec_bruteforce

This time we get 3 matches (for the users: bhult, tlavel and bnielson)!! The password is the name of the company Fabricorp01! But, the interesting thing here is that the password does not result in a successful login but returns the error code STATUS_PASSWORD_MUST_CHANGE. This means the password was once used as the password for those users (probably some default password for new employees) but expired and must now be re-newed.

Obtain valid credentials

As we are the good guys, we will of course be more than happy to do this task for them. To change their passwords, we can use the tool smbpasswd.

Now we can use these credentials to enumerate the SMB shares. But wait… why do we get an Authentication error?

Let’s manually check what’s going on:

1
2
3
4
┌──(kali㉿kali)-[~/HTB/machines/fuse]
└─$ smbclient -L //10.129.122.50 -U 'bhult'
Password for [WORKGROUP\bhult]:
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE

Huh?? NT_STATUS_PASSWORD_MUST_CHANGE? Didn’t we just do that? Alright. Let’s do it again for one user and check if it works:

That’s weird. It works for some time after the password reset but apparently the password resets back to the original password every minute. Nevertheless, in general it seems be to working. Let’s see if we can automate things so that we can enumerate the system without being forced to change the password every minute.

The following bash script should do that task for us. First, we check if the password can still be used to login as user bhult. If not, we set the password to password!1234 and pipe that in combination with the old password into smbpasswd to change the password for us. Afterwards, we use that password once again for the authentication to the SMB server.

1
if echo "$pass" | smbclient -L //10.129.2.5 -U bhult 2>/dev/null >/dev/null; then echo "OK"; else pass='password!1234' && (echo 'Fabricorp01'; echo "$pass"; echo "$pass";) | smbpasswd -r 10.129.122.50 -s -U bhult; fi; smbclient -L //10.129.2.5 -U "bhult"

The script can then be used as follows:

However, after some time, when we use the script again, it fails:

It seems like we cant re-use passwords. So we have to find a way to make the passwords unique. My first thought was to include the date in the password, so we will never have the same password twice.

The idea of the new script is the same. But this time, instead of hard-coding the password to password!1234, we dynamically create the password using the current date.

1
if echo "$pass" | smbclient -L //10.129.2.5 -U bhult 2>/dev/null >/dev/null; then echo "OK"; else pass="password\!$(date +'%N%S%M')";echo "Password changed to: $pass";(echo 'Fabricorp01'; echo "$pass"; echo "$pass";) | smbpasswd -r 10.129.2.5 -s -U bhult; fi; smbclient -L //10.129.2.5 -U "bhult"

Enumerating the SMB Share

Great, this time it works flawlessly! Now we can use it to check out the print$ share.

However, the share does not contain any interesting files. Just lots of default files which do not provide us any additional information.

Enumerating the RPC service

Next, we check out the RPC service. Now that we have valid credentials, we should be able to enumerate other existing users and especially printers (as there should be at least one printer in the network).

Using the command: enumdomusers, we obtain a list of all available users. Most of them are already part of our username list but some of them are new. Let’s add them to the list.

Going through the list of available commands, we find something called getprinter.

1
2
rpcclient $> getprinter
Usage: getprinter <printername> [level]

Hmmm… we need a printer name for that. Fortunately, we have a way to get that name! Remember the web interface showing the Printer Logs? One of the columns was named Printer which contained the name of the printer:

We can now use that name for the command:

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

There, we also get a password: $fab@s3Rv1ce$1.

Let’s check if one of the found users (presumably the svc-print or svc-scan users) uses this password! (with the help of crackmapexec)

As expected. Both users that are related to the printer, use the password!

Inital Foothold

Now that we have a bunch of valid credentials, we can try to access the server via WinRM (using Evil-WinRM).

First, we try the user bhult:

Unfortunately, it fails. Next is the user svc-print:

This time it works! We got access to the system! Here, we also get the user flag:

Privilege Escalation

First, we do some basic enumeration on the system and our current user.

Looking at the whoami /all output we discover something interesting:

Our user has the privilege SeLoadDriverPrivilege. This privilege enables our current user to load and unload kernel drivers and execute code with kernel privileges aka NT\SYSTEM. Now the question is: how do we create our own malicious drivers? Fortunately, there are plenty of articles that already describe how to do such things.

To be honest, at this point I was a bit too lazy to compile everything from scratch (C++ files) as described in the article so I simply searched for pre-compiled binaries and found this Github repository.

I simply transferred all the needed files to the target machine and executed the binaries:

This immediately gave me access to the system as NT AUTHORITY\SYSTEM:

This post is licensed under CC BY 4.0 by the author.