Skip to main content

Game of Active Directory (GOAD)

Props!

Huge shout out to @M4yFly for all the hard work to create GOAD!

GOAD Network Map

1. Add the Windows 2019 and 2016 server templates to Ludus

git clone https://gitlab.com/badsectorlabs/ludus
cd ludus/templates
ludus templates add -d win2016-server-x64
[INFO] Successfully added template
ludus templates add -d win2019-server-x64
[INFO] Successfully added template
ludus templates build
[INFO] Template building started - this will take a while. Building 1 template(s) at a time.
# Wait until the templates finish building, you can monitor them with `ludus templates logs -f` or `ludus templates status`
ludus templates list
+----------------------------------------+-------+
| TEMPLATE | BUILT |
+----------------------------------------+-------+
| debian-11-x64-server-template | TRUE |
| debian-12-x64-server-template | TRUE |
| kali-x64-desktop-template | TRUE |
| win11-22h2-x64-enterprise-template | TRUE |
| win2022-server-x64-template | TRUE |
| win2019-server-x64-template | TRUE |
| win2016-server-x64-template | TRUE |
+----------------------------------------+-------+

2. Set and deploy the following range configuration

config.yml
ludus:
- vm_name: "{{ range_id }}-GOAD-DC01"
hostname: "{{ range_id }}-DC01"
template: win2019-server-x64-template
vlan: 10
ip_last_octet: 10
ram_gb: 4
cpus: 2
windows:
sysprep: true
- vm_name: "{{ range_id }}-GOAD-DC02"
hostname: "{{ range_id }}-DC02"
template: win2019-server-x64-template
vlan: 10
ip_last_octet: 11
ram_gb: 4
cpus: 2
windows:
sysprep: true
- vm_name: "{{ range_id }}-GOAD-DC03"
hostname: "{{ range_id }}-DC03"
template: win2016-server-x64-template
vlan: 10
ip_last_octet: 12
ram_gb: 4
cpus: 2
windows:
sysprep: true
- vm_name: "{{ range_id }}-GOAD-SRV02"
hostname: "{{ range_id }}-SRV02"
template: win2019-server-x64-template
vlan: 10
ip_last_octet: 22
ram_gb: 4
cpus: 2
windows:
sysprep: true
- vm_name: "{{ range_id }}-GOAD-SRV03"
hostname: "{{ range_id }}-SRV03"
template: win2019-server-x64-template
vlan: 10
ip_last_octet: 23
ram_gb: 4
cpus: 2
windows:
sysprep: true
- vm_name: "{{ range_id }}-kali"
hostname: "{{ range_id }}-kali"
template: kali-x64-desktop-template
vlan: 10
ip_last_octet: 99
ram_gb: 4
cpus: 2
linux: true
testing:
snapshot: false
block_internet: false
vim config.yml
# paste in the config above (adjust cpus and ram_gb values if you have the resources to allocate more)
ludus range config set -f config.yml
ludus range deploy
# Wait for the range to successfully deploy
# You can watch the logs with `ludus range logs -f`
# Or check the status with `ludus range status`

3. Update the SRV02 machine

ludus testing update -n JD-GOAD-SRV02 # replace "JD" with your user ID
ludus range logs -f
# Wait for all updates to be installed.
# Be patient, this will take a long time.
# This required for the IIS install to work during GOAD setup.

# When you see the following, the updates are complete:
localhost : ok=5 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
JD-GOAD-SRV02 : ok=8 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

4. Install ansible and its requirements for GOAD on your local machine

# You can use a virtualenv here if you would like
python3 -m pip install ansible-core
python3 -m pip install pywinrm
git clone https://github.com/Orange-Cyberdefense/GOAD
cd GOAD/ansible
ansible-galaxy install -r requirements.yml

5. Create the following inventory file and replace RANGENUMBER with your range number with sed (commands provided below)

inventory.yml
[default]
; Note: ansible_host *MUST* be an IPv4 address or setting things like DNS
; servers will break.
; ------------------------------------------------
; sevenkingdoms.local
; ------------------------------------------------
dc01 ansible_host=10.RANGENUMBER.10.10 dns_domain=dc01 dict_key=dc01
;ws01 ansible_host=10.RANGENUMBER.10.30 dns_domain=dc01 dict_key=ws01
; ------------------------------------------------
; north.sevenkingdoms.local
; ------------------------------------------------
dc02 ansible_host=10.RANGENUMBER.10.11 dns_domain=dc01 dict_key=dc02
srv02 ansible_host=10.RANGENUMBER.10.22 dns_domain=dc02 dict_key=srv02
; ------------------------------------------------
; essos.local
; ------------------------------------------------
dc03 ansible_host=10.RANGENUMBER.10.12 dns_domain=dc03 dict_key=dc03
srv03 ansible_host=10.RANGENUMBER.10.23 dns_domain=dc03 dict_key=srv03

[all:vars]
; domain_name : folder inside ad/
domain_name=GOAD

force_dns_server=yes
dns_server=10.RANGENUMBER.10.254

two_adapters=no
; adapter created by vagrant and virtualbox (comment if you use vmware)
nat_adapter=Ethernet
domain_adapter=Ethernet

; adapter created by vagrant and vmware (uncomment if you use vmware)
; nat_adapter=Ethernet0
; domain_adapter=Ethernet1

; winrm connection (windows)
ansible_user=localuser
ansible_password=password
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
ansible_winrm_operation_timeout_sec=400
ansible_winrm_read_timeout_sec=500

; proxy settings (the lab need internet for some install, if you are behind a proxy you should set the proxy here)
enable_http_proxy=no
ad_http_proxy=http://x.x.x.x:xxxx
ad_https_proxy=http://x.x.x.x:xxxx
vim inventory.yml
# paste in the inventory file above
export RANGENUMBER=$(ludus range list --json | jq '.rangeNumber')
# `sudo apt install jq` if you don't have jq
sed -i "s/RANGENUMBER/$RANGENUMBER/g" inventory.yml

6. Deploy GOAD

note

You must be connected to your Ludus wireguard VPN for these commands to work

vim build.yml
# Edit the keyboard layout to your preferred layout (or remove that whole line)
export ANSIBLE_COMMAND="ansible-playbook -i ../ad/GOAD/data/inventory -i ./inventory.yml"
export LAB="GOAD"
../scripts/provisionning.sh

Now you wait. [WARNING] lines are ok, and some steps may take a long time, don't panic!

This will take a few hours. You'll know it is done when you see:

your lab: GOAD is successfully setup ! have fun ;)
It's always DNS...

If you encounter errors with TASK [groups_domains : synchronizes all domains] or similar, manually remove the 10.ID.10.254 entry from the DNS servers for the host. You can do this via the GUI (Network and Internet -> Change Adaptor Options -> Right-click -> Properties -> Internet Protocol Version 4 (TCP/IPv4) -> Properties) or via Powershell:

# Run this on the failing host
$adapter = Get-WmiObject Win32_NetworkAdapterConfiguration | Where-Object { $_.IPAddress -ne $null }
$dnsServers = $adapter.DNSServerSearchOrder
$newDnsServers = $dnsServers | Where-Object { $_ -notmatch ".*\.254$" }
$adapter.SetDNSServerSearchOrder($newDnsServers)

7. Snapshot VMs

Take snapshots via the proxmox web UI or SSH into ludus and as root run the following

export RANGEID=JD # <= change to your user ID
vms=("$RANGEID-GOAD-DC01" "$RANGEID-GOAD-DC02" "$RANGEID-GOAD-DC03" "$RANGEID-GOAD-SRV02" "$RANGEID-GOAD-SRV03")
COMMENT="Clean GOAD setup after ansible run"
# Loop over the array
for vm in "${vms[@]}"
do
echo "[+] Create snapshot for $vm"
id=$(qm list | grep $vm | awk '{print $1}')
echo "[+] VM id is : $id"
qm snapshot "$id" 'snapshot-'$(date '+%Y-%m-%d--%H-%M') --vmstate 1 --description "$COMMENT"
done

8. Hack!

Access your Kali machine at https://10.RANGENUMBER.10.99:8444 using the creds kali:password.

Follow the GOAD guide or explore the network on your own.