When running a Game of Active Directory (GOAD) lab, having a robust list of candidate usernames is critical. The GOAD architecture uses characters from Game of Thrones, making HBO's official cast page an ideal source for generating a username list.
However, modern web architecture rarely serves simple, static HTML lists. In this runbook, we document how to handle HTTP redirects, parse serialized Next.js application data using basic command-line tools, normalize the output, and—crucially—cross-reference it with our Active Directory domain to yield only confirmed lab accounts for authorized security testing.
The Recon: Following the 301
We begin by targeting the legacy HBO cast and crew URL. Setting up our Kali working directory first ensures a clean workspace:
mkdir -p ~/labs/goad/got-user-enum
cd ~/labs/goad/got-user-enum
We test the URL response headers to see what we are dealing with:
curl -I https://www.hbo.com/game-of-thrones/cast-and-crew
https://www.hbomax.com/show/.../cast-and-crew. Never assume an old URL structure remains intact; always follow the redirect to analyze the current payload.
We use curl -L to follow the redirect and save the actual HTML response:
curl -L -A 'Mozilla/5.0' -s \
https://www.hbo.com/game-of-thrones/cast-and-crew \
-o got.html
The Hunt: Finding the Embedded Data
A simple grep for known characters like Jon Snow or Daenerys reveals that the data isn't in standard HTML anchor tags anymore.
grep -oiE '.{0,100}(Jon Snow|Tyrion|Daenerys).{0,150}' got.html | head -30
This exposes the application's underlying data serialization format. Instead of traditional href links, the cast list is embedded as JSON-like key-value pairs within the page data:
primaryText":"Daenerys Targaryen"
urlSlug":"daenerys-targaryen"
Understanding this structure is key. Scraping must adapt to what the server actually returns, not what we expect it to return.
The Extraction: Generating Candidates
We construct a targeted extraction pipeline using grep and sed to pull out just the urlSlug values, producing a clean, deduplicated list.
grep -oE 'urlSlug\\?":\\?"[^"]+' got.html |
sed -E 's/.*urlSlug\\?":\\?"//' |
sort -u > users.txt
This successfully extracts 97 unique candidates (e.g., arya-stark, jon-snow).
To match our GOAD Active Directory naming conventions (which typically uses a first.last format), we normalize these hyphens into periods, creating our final candidate file:
sed 's/-/./g' users.txt | sort -u > users-dot.txt
The Convergence: Validating against AD
A list of GoT characters does not guarantee they exist in the target AD. To strictly limit our scope to authorized lab username validation, we must compare our candidates against the actual directory.
On the Windows Domain Controller, we extract the authoritative list of AD accounts:
Get-ADUser -Filter * |
Select-Object -ExpandProperty SamAccountName |
Set-Content C:\Temp\ad-users.txt
After transferring ad-users.txt back to our Kali machine, we normalize it to lowercase and compute the intersection of our candidates with the actual AD users using comm:
tr '[:upper:]' '[:lower:]' < ad-users.txt |
sort -u > ad-users-clean.txt
comm -12 \
<(sort users-dot.txt) \
<(sort ad-users-clean.txt) \
> confirmed-users.txt
confirmed-users.txt file now contains the exact intersection of HBO characters and provisioned GOAD AD accounts. This ensures subsequent password spraying or Kerberoasting is highly targeted and reduces unnecessary noise.
The Automation: Bash Scripting
To make this repeatable, the entire workflow can be codified into a single script: extract-got-users.sh.
#!/usr/bin/env bash
set -euo pipefail
URL="https://www.hbo.com/game-of-thrones/cast-and-crew"
HTML="got.html"
USERS="users.txt"
NORMALIZED="users-dot.txt"
echo "[+] Downloading page..."
curl -L -A 'Mozilla/5.0' -sS "$URL" -o "$HTML"
echo "[+] Extracting urlSlug values..."
grep -oE 'urlSlug\\?":\\?"[^"]+' "$HTML" |
sed -E 's/.*urlSlug\\?":\\?"//' |
sort -u > "$USERS"
echo "[+] Creating normalized candidate usernames..."
sed 's/-/./g' "$USERS" | sort -u > "$NORMALIZED"
COUNT=$(wc -l < "$USERS")
if [ "$COUNT" -lt 10 ]; then
echo "[!] Suspiciously small result: $COUNT"
exit 1
fi
echo "[+] Results: $COUNT Raw, $(wc -l < "$NORMALIZED") Normalized."
🎯 Conclusion & Methodology
The most important lesson here is methodological resilience. Scraping tools built on static assumptions fail when modern web architectures update their data serialization formats (like migrating to Next.js or changing routing patterns).
The robust approach:
Don't scrape what you expect. Download what the server actually returns → Inspect the structure → Identify stable data fields → Extract → Validate against the authorized target.
This disciplined approach cleanly transitions from open-source intelligence (OSINT) gathering directly into authorized, targeted Active Directory enumeration for our GOAD lab.