How I Built (And Broke) My Own Windows Server
Hey everyone!
I decided to build a Windows Server lab from scratch to see how Active Directory actually works under the hood. This post covers the basic setup and getting the domain running. Once the foundation is solid, I’m going to try and find some weak spots and see if I can break into it.
The Goal
Active Directory is pretty much everywhere in the corporate world. By building the whole thing myself, I can see how everything connects and, more importantly, what kind of small mistakes lead to a network getting compromised.
The Lab Layout
+----------------------------------+
| Domain: lab.local |
| (Subnet: 10.0.0.0/24) |
+----------------+-----------------+
|
+---------------------+---------------------+
| | |
+---------+---------+ +---------+---------+ +---------+---------+
| [ DC01 ] | | [ WKSTN01 ] | | [ ATTACKER ] |
| Windows Server 22 | | Windows 11 Pro | | Arch Linux |
| Domain Controller | | Target PC | | My Main Machine |
| IP: 10.0.0.10 | | IP: 10.0.0.20 | | IP: 10.0.0.50 |
+-------------------+ +-------------------+ +-------------------+
Lab Architecture
I’m running everything in a virtual environment to keep it safe and separate from my main files:
- Hypervisor: VMware Workstation
Phase 1: Basic Config
The first thing I had to do was give the server a permanent IP and a clear name. I used SConfig to handle the basics:
- Static IP: I assigned 10.0.0.10/24 so the server always stays in the same spot.
- Hostname: I renamed the server to DC01 so it’s easy to recognize.
Phase 2: Active Directory Setup
Now that the name and IP are set, it’s time to actually turn the server into a Domain Controller. I used PowerShell for this because it’s a lot quicker than clicking through a bunch of menus.
- Installing AD Tools: I jumped into PowerShell (Option 15 in SConfig) and ran this to get the Active Directory files installed:
PS C:\> Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
- Promoting to Forest: Once the tools were ready, I promoted the server to a Domain Controller for lab.local.
PS C:\> Install-ADDSForest -DomainName "lab.local" -InstallDns:$true -Force:$true
Phase 3: Populating the Domain
A Domain Controller without users is pretty boring, so I needed to add some life to the network.
- Organizational Units: I created a folder called Lab_Users to keep things organized.
PS C:\> New-ADOrganizationalUnit -Name "Lab_Users" -Path "DC=lab,DC=local"
- Creating Test Users: I added a few different roles. To make things easier, I stored the password in a variable first:
# Storing the password securely in a variable PS C:\> $password = ConvertTo-SecureString "Password123!" -AsPlainText -Force
Then, I used that variable to create the actual accounts in one go:
# Creating the accounts using the variable PS C:\> New-ADUser -Name "SQL Service" -SamAccountName "sql_svc" -UserPrincipalName "sql_svc@lab.local" -Path "OU=Lab_Users,DC=lab,DC=local" -AccountPassword $password -Enabled $true PS C:\> New-ADUser -Name "IT Admin" -SamAccountName "it_admin" -UserPrincipalName "it_admin@lab.local" -Path "OU=Lab_Users,DC=lab,DC=local" -AccountPassword $password -Enabled $true PS C:\> New-ADUser -Name "HR Manager" -SamAccountName "hr_user" -UserPrincipalName "hr_user@lab.local" -Path "OU=Lab_Users,DC=lab,DC=local" -AccountPassword $password -Enabled $true
- Setting Up Targets: I added the it_admin to the Domain Admins group for future testing.
PS C:\> Add-ADGroupMember -Identity "Domain Admins" -Members "it_admin"
Phase 4: Setting up the Workstation
Now that we have a system in which we can integrate and implement the users in, its time to set up a Workstation.
For this I will simulate another virtual environment using Windows 11 Pro. This machine will be joined to the lab.local domain.
Step 1: Networking & DNS Configuration
The most critical part of joining a domain is DNS. Without pointing the Workstation to our Domain Controller, it will never find lab.local. I manually configured the IPv4 settings to use 10.0.0.10 as the primary DNS server.
Step 2: Troubleshooting the Connection
Initially, I couldn’t ping the Domain Controller. This was due to two issues:
- Network Isolation: One VM was set to NAT and the other to Host-Only. I had to move both to the same Host-Only adapter to allow them to communicate.
- Firewall Blocking: Windows Server blocks ICMP (Ping) by default. I used the following command on the DC to enable it:
PS C:\> Enable-NetFirewallRule -DisplayName "File and Printer Sharing (Echo Request - ICMPv4-In)"
Once the firewall was open, the pings started flowing perfectly!
Step 3: Joining the Domain
With connectivity established, it was time for the final step. I went into the system settings, changed the membership from a Workgroup to the lab.local domain, and authenticated with the Administrator credentials.
Success!
The machine is now officially part of the lab. A quick reboot and a “Welcome” message later, I am ready to start testing my Active Directory users on a real target machine.
Phase 5: Vulnerability Engineering
Now that the foundation is solid and the workstation is joined, the “Building” part is over. It’s time to intentionally weaken the security of this domain to simulate real-world misconfigurations. My first target: Kerberoasting.
Setting the Bait (SPN)
Hacker look for accounts with a Service Principal Name (SPN) because these accounts can be “roasted” to request Kerberos tickets, which can then be cracked offline. I assigned a fake SQL service name to the sql_svc user I created earlier:
PS C:\> setspn -a MSSQLSvc/sql01.lab.local:1433 sql_svc
Why this matters
In a professional environment, service accounts often have weak passwords. By setting this SPN, I’ve created a path for an attacker to move from a standard user to cracking a service account password without even touching the Domain Controller directly.
Phase 6: Reconnaissance & Connectivity
Now that the Windows environment is “vulnerable,” I need to step into the shoes of the attacker. Since my main OS is Arch Linux, I’m using it as the attack platform. However, there was one final hurdle: getting my host machine to talk to the isolated Host-Only network.
Bringing the Attacker into the Network
My VMs were living in the 10.0.0.0/24 subnet, but my Arch host’s virtual interface (vmnet1) was on a completely different range. To bridge this gap, I manually assigned an IP to my host within the lab’s subnet:
$ sudo ip addr add 10.0.0.50/24 dev vmnet1
The Handshake
With the IP set, I performed a simple connectivity test. Pinging the Domain Controller (10.0.0.10) from my Arch terminal confirmed that the “Attacker” now has a direct line of sight to the target.
Mapping the Target (Nmap Scan)
With connectivity confirmed, it was time for the first real “hacker” move: Network Scanning. I ran nmap against the Domain Controller to see exactly what services were exposed.
$ nmap -Pn -sV 10.0.0.10
The Loot: Important Ports
The scan confirmed these main entry points for the upcoming AD attacks:
| Port | Service | Pentest Use |
|---|---|---|
| 53 | DNS | Enumerating hosts in the domain. |
| 88 | Kerberos | Kerberoasting & AS-REP Roasting. |
| 445 | SMB | Lateral movement & file shares. |
| 389 | LDAP | AD database queries. |
What’s Next?
The reconnaissance is done. I have a map of the target, and I know exactly where the vulnerabilities lie. In the next post, I’ll finally pull the trigger on the Kerberoasting attack using Impacket to grab that service account hash. Stay tuned!