Resolute is a Medium Windows box created by egre55. It was released on December 7th, 2019 and retired on May 30th, 2020. The users rated the difficulty of this box 4.8/10 and gave it an appreciation score of 4.7/5.
TL;DR
We can bind anonymously to a Windows 2016 Active Directory where we find a comment in a user object that contains the default password used when creating new users. We do a Password Spraying and find that the password works for the user melanie
. As the user is as well part of the Remote Management Users
, we can log in through WinRM and grab the user flag. The user ryan
is part of the same group plus the DnsAdmins
group which has some known escalation path to SYSTEM
. We find a hidden Powershell transcript file that leaks his password. We escalate privileges by injecting a malicious DLL into the DNS service.
Reconnaissance & Enumeration
Open Ports
An NMAP scan shows the following (partial) output:
$ sudo nmap -sS -sV -p- 10.10.10.169
PORT | STATE | SERVICE | VERSION |
---|---|---|---|
53/tcp | open | domain? | |
88/tcp | open | kerberos-sec | Microsoft Windows Kerberos (server time: 2020-05-27 19:50:22Z) |
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 | Microsoft Windows Server 2008 R2 - 2012 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 | |
5985/tcp | open | http | Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) |
9389/tcp | open | mc-nmf | .NET Message Framing |
[…] |
We discover:
- the common open ports in a Windows Domain Controller. The domain name is
megabank.local
, - WinRM management service over HTTP on port 5985.
LDAP discovery
We can start to list the domain users with GetADUsers.py
from Impacket:
We get results, which means that the Active Directory (AD) instance allows anonymous binding. The list is pretty long and only the Administrator
account has previously logged in.
We can explore the AD with JXplorer and the following configuration:
We retrieve the following information:
- the domain controller FQDN:
Resolute.megabank.local
which is a Windows Server 2016 Standard, - a server
MS02.megabank.local
as well a Windows Server 2016 Standard, - a security group
Contractors
that is member of the groupsDnsAdmins
andRemote Management Users
. The userryan
is part of this group and can, therefore, log in through WinRM and manage the DNS service, - the user
melanie
is as well part of theRemote Management Users
group.
Gaining Access
Without any credentials, but with a list of user accounts, we can try AS-REP Roasting. This attack is explained in detail in this blog post. To make it short, if a user is configured to not require Kerberos pre-authentication, anyone can send a request (AS_REQ) to the KDC and receive a response (AS_REP). The response contains an encrypted chunk of data related to that user that can be cracked offline to retrieve the user password. This can be automatized with GetNPUsers.py
, another Impacket tool:
This does not leak anything…
Going back to AD enumeration, we find the following comment in marko
user object:
It is not marko
password though. Let’s do some Password Spraying to check if this default password was set to another user:
And there we have a hit! As melanie
is part of the group Remote Management Users
, we use Evil-WinRM to log in and grab the user flag:
Local Reconnaissance & Enumeration
As there are known privilege escalation methods with users in the DnsAdmins
group, we will try to move laterally to the user ryan
.
We find an uncommon hidden folder PSTranscripts
in the root folder:
This folder contains another hidden folder 20191203
which contain a hidden file PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
.
Privilege Escalation
User pivoting
We can retrieve this text file with the download
command of Evil-WinRM. This file happens to be a Windows PowerShell transcript, a recorded Powershell session to text. This can be achieved with the Start-Transcript cmdlet.
As we can read in the header, this transcript has been generated by the user ryan
:
Windows PowerShell transcript start
Start time: 20191203063201
Username: **MEGABANK\ryan**
RunAs User: MEGABANK\ryan
Machine: RESOLUTE (Microsoft Windows NT 10.0.14393.0)
Host Application: C:\Windows\system32\wsmprovhost.exe -Embedding
Process ID: 2800
PSVersion: 5.1.14393.2273
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.14393.2273
BuildVersion: 10.0.14393.2273
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
Below that, we see the commands that have been recorded and one of them is:
which leaks ryan
password. As he is as well part of the Remote Management Users
group, we can kill melanie
session and switch to ryan
.
Root escalation
We find a note.txt
file on ryan
desktop. It contains:
Email to team:
- due to change freeze, any system changes (apart from those to the administrator account) will be automatically reverted within 1 minute
As said before, there is a known way from users in the DnsAdmins
group to SYSTEM
. This leverages DNS plugin DLL to inject a malicious payload. The attack is described in this article and we will mainly be paraphrasing it.
We first have to compile a DNS plugin DLL. We will use the skeleton code found here. We open the project in Visual Studio Community 2019 and simply add a system
call in the DnsPluginInitialize
function. The first payload will be a simple ping home:
We compile the DLL and upload it on the box by serving it through a local HTTP listener:
We test that the payload works with rundll32.exe
:
It works! The next step is to inject the DLL in the DNS service. This is accomplished with the DNS management tool dnscmd
:
Seems successful. Let’s verify the DNS registry key:
Now we only need to restart the DNS service to trig our payload:
*Evil-WinRM* PS C:\tmp> sc.exe start dns
But…nothing! And the registry parameter disappeared. This must be due to what was mentioned in the note.txt
. Let’s do it in one go:
And we get our ping once again. We can now replace the command with a reverse shell payload. We are going to use a Nishang reverse Powershell:
If we run it as is from the command line, it works perfectly. However, from our DLL, we will need to launch it with the powershell -c
command and unfortunately, this triggers the antivirus:
Encoding the payload with base64 does still trigger the antivirus. What about a TCP bind shell? We are again using a Nishang payload. Let’s encode it to avoid messing with special characters:
And this works like a charm! Let’s replace our ping
command in our DLL with our encoded payload:
We rebuild the DLL, redo the whole steps to inject it into the DNS service and fire it to get the root flag:
Conclusion
This was an enjoyable box with a new path to SYSTEM
for me. The privilege escalation was well documented on the web so there were no particular difficulties here.
As usual, here are some takeaways:
- disable Active Directory anonymous binding and avoid using objects attributes to store credentials and other secrets,
- on Domain Controllers, closely monitor any DNS service action,
dnscmd
calls and DNS setting changes in the registry…particularly theServerLevelPluginDll
value.
Resources
[1] Impacket collection scripts
https://github.com/SecureAuthCorp/impacket
[2] JXplorer
http://jxplorer.org/
[3] AS-REP Roasting
https://www.harmj0y.net/blog/activedirectory/roasting-as-reps/
[4] Password Spraying
https://doubleoctopus.com/security-wiki/threats-and-tools/password-spraying/
[5] Evil-WinRM
https://github.com/Hackplayers/evil-winrm
[6] Start-Transcript cmdlet
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.host/start-transcript?view=powershell-7
[7] DNS plugin DLL injection
https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-dnsadmins-to-system-to-domain-compromise
https://blog.3or.de/hunting-dns-server-level-plugin-dll-injection.html
https://github.com/dim0x69/dns-exe-persistance
[8] Visual Studio Community 2019
https://visualstudio.microsoft.com/vs/community/
[9] Nishang reverse Powershell
https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLine.ps1
[10] Nishang bind shell
https://github.com/samratashok/nishang/blob/master/Shells/Invoke-PowerShellTcpOneLineBind.ps1