Home TryHackMe Writeup - VulnNet:Roasted

TryHackMe Writeup - VulnNet:Roasted

VulnNet:Roasted is an easy Windows Active Directory room. First, we had to enumerate the exposed SMB shares to obtain more information about the system. There, we also had to perform a RID cycling attack to find usernames. These usernames were then used for an AS-REP Roasting attack to obtain a password hash for an existing user. Once cracked, these credentials were used to perform a Kerberoasting attack to obtain the password hash for an existing service. Again, we had to crack the password of that service account to obtain inital access to the system. For privilege escalation, we just had to do another round of SMB share enumeration to find the credentials of a privileged user. This privileged user was then used to dump the user hashes from the SAM and SYSTEM files. Using this obtained information, we were then able to capture the root flag.

Note: The target machine stopped responding several times during the assessment. Therefore, the IP addresses in the report might change from time to time, even though we are always looking at the same machine.


As always, we start by scanning the target machine’s open ports:

rustscan --ulimit 5000 vulnnet-rst.local -- sV -sC -oN nmap_scan

53/tcp   open  domain        Simple DNS Plus
88/tcp   open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-06-17 08:10:10Z)
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: vulnnet-rst.local0., Site: Default-First-Site-Name)
445/tcp  open  microsoft-ds?
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: vulnnet-rst.local0., 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
Service Info: Host: WIN-2BO8M1OE1M1; OS: Windows; CPE: cpe:/o:microsoft:windows

Here, we can clearly see that we are dealing with a Domain Controller for the AD Domain vulnnet-rst.local0. Let’s continue with the enumeration.

Enumeration of Port 139/445 (SMB)

First, we use smbmap to determine the available shares. However, it does not seem to give us any output. Next, we try to establish a guest session to see if the server allows connections as anonymous user. And indeed, it does! We can now see the shares.

Three of them, the VulnNet-Business-Anonymous and VulnNet-Enterprise-Anonymous and the IPC$, seem to be worthy to investigate further, as we do have READ permissions on them.

So first, we use smbclient to connect to those non-standard (…-Business… and …-Enterprise..) shares as anonymous user. Both of these shares contain a few .txt files, that we can download to our local attacker machine.

Files located in the business share.

Files located in the enterprise share.

Looking at the content of those files, we can gather some information about possible existing users on the system:

Business texts: Leak “Alexa Whitehat” and “Jack Goldenhand” as possible usernames.

Enterprise texts: Leak “Tony Skid” and “Johnny Leet” as possible usernames.

With this information, we can now try to guess the usernames, since they are probably some sort of variation of the usernames. E.g. firstname-lastname or first letter of firstname + lastname etc. This would most likely work but is rather guessy.

However, there is a much easier method to obtain the usernames! Remember that there was a 3rd readable share - the IPC$ share. This allows us to anonymously enumerate for usernames on the system. The key idea here is that we can bruteforce the SIDs. If such a SID exists, the system will return the related username to that SID. This way, we can obtain a full list of available usernames.

A tool to automate this, is Impacket's lookupsids.py. It can be used as follows:

In the output, we see that our first method - guessing the usernames - would have worked as well. All leaked usernames are included in the output (format: first letter of firstname-lastname). We can now use those usernames for the Kerberos enumeration.

Enumerating Kerberos - AS-REP Roasting

“AS-REP Roasting is an attack against Kerberos for user accounts that do not require preauthentication. This is explained in pretty thorough detail in Harmj0y’s post here, so I’ll focus on summarizing it. Pre-authentication is the first step in Kerberos authentication, and is designed to prevent brute-force password guessing attacks. During preauthentication, a user will enter their password which will be used to encrypt a timestamp and then the domain controller will attempt to decrypt it and validate that the right password was used and that it is not replaying a previous request. From there, the TGT will be issued for the user to use for future authentication. If preauthentication is disabled, an attacker could request authentication data for any user and the DC would return an encrypted TGT that can be brute-forced offline. Luckily, preauthentication is required by default in Active Directory.” https://stealthbits.com/blog/cracking-active-directory-passwords-with-as-rep-roasting/

While the source states: “Luckily, preauthentication is required by default in Active Directory”, it is still a common security issues in windows systems/networks. So let’s see if we are lucky. We use Impacket's GetNPUsers.py to perform the AS-REP Roasting:

Perfect! The user t-skid had no preauthentication enabled and thus we got an ASREP for the user t-skid. This ASREP includes the TGT and a part which contains the session key for the communication between the user and the TGS. The latter part is encrypted with the provided user’s password hash.

The Kerberos Protocol Message Formats - ASREP highlighted

As we are now in possession of that ASREP, we can try to bruteforce the user’s password! We use the tool hashcat for that purpose.

└─$ hashcat -m 18200 tskid_asrep /usr/share/wordlists/rockyou.txt

Great! We now have valid credentials: t-skid:tj072889*.

Initial Foothold

During the inital port enumeration, we found the port 5985 to be open. Now that we also have valid credentials, we can try to use EVIL-WINRM to establish a shell connection to the system. Unfortunately that does not work with the current credentials … so what can we do now? Well, since these credentials are supposedly valid in the AD domain, we can try to perform a Kerberoasting attack.


“Kerberoasting is an attack that abuses the Kerberos protocol to harvest password hashes for Active Directory user accounts with servicePrincipalName (SPN) values — i.e., service accounts. A user is allowed to request a ticket-granting service (TGS) ticket for any SPN, and parts of the TGS may be encrypted with RC4 using the password hash of the service account that is assigned the requested SPN as the key. Therefore, an adversary who is able to steal TGS tickets (either from memory or by capturing them by sniffing network traffic) can extract the service account’s password hash and attempt an offline brute force attack to obtain the plaintext password.” https://www.netwrix.com/cracking_kerberos_tgs_tickets_using_kerberoasting.html

The Kerberoasting attack is very similar to the AS-REP Roasting attack. The only difference is, that we need valid credentials and that we are targeting services instead of users (message 4 instead of message 2 in the Kerberos protocol).

Once we have requested access to a service, we can start cracking the service’s password hash offline. The tool we use for obtaining the TGS ticket is Impacket's GetUserSPNs.py:

└─$ GetUserSPNs.py 'VULNNET-RST.local/t-skid:tj072889*' -dc-ip -outputfile kerberoasting_hashes

We are able to identify a service called enterprise-core-vn. Further, we have a TGS ticket that contains its password hash (Kerberos 5, etype 23, TGS-REP - hashcat mode 13100). So let’s try to crack is using hashcat.

└─$ hashcat -m 13100 enterprise_password_hash /usr/share/wordlists/rockyou.txt

After a few seconds, we got a hit! We now have the password for a service account in the AD domain. Let’s again try to use evil-winrm to log in. This time it works! We got access to the system.

Privilege Escalation - User a-whitehat

Now that we got access to the system, it’s time for some enumeration! … Or is it? When we try to run normal commands for enumeration such as systeminfo, we always get the error message Program 'systeminfo.exe' failed to run: Access is denied. Also other commands seem to fail. So let’s take a step back and think about what we can do. We got a new set of credentials. We can use them to again enumerate the existing shares.

Doing that, we can see that we now have access to two additional shares NETLOGON and SYSVOL.

The SYSVOL folder is shared on an NTFS volume on all the domain controllers within a particular domain. SYSVOL is used to deliver the policy and logon scripts to domain members. By default, SYSVOL includes 2 folders:

  • Policies - Default location: %SystemRoot%\SYSVOL\SYSVOL<domain_name>\Policies
  • Scripts - Default location: %SystemRoot%\SYSVOL\SYSVOL<domain_name>\scripts https://social.technet.microsoft.com/wiki/contents/articles/8548.active-directory-sysvol-and-netlogon.aspx

In the SYSVOL share’s vulnnet-rst.local\scripts\ directory we find something interesting! A file called ResetPassword.vbs. We download that file for further investigation on our local machine.

When we open that file, we can immediately spot the credentials for the user a-whitehat.

Using evil-winrm once again to connect to the system, we can now finally run useful commands for enumeration!

Privilege Escalation - NT AUTHORITY\SYSTEM

Now that we finally have access to the system as privileged user (what seems to be a local administrator), we can start enumerating the Domain Controller in order to find a way to become NT AUTHORITY\SYSTEM.

As we already have Administrator privileges, we can simply create a backup of the SYSTEM and the SAM files (move to C:\Windows\system32):

reg.exe save HKLM\SAM sam.bak
reg.exe save HKLM\SYSTEM system.bak

Then, once transferred to our local machine, we can use Impacket's secretsdump.py to locally dump the SAM hashes.

While the hashcat cracking process does not reveal any plaintext for the hash, the Pass-the-Hash technique with evil-winrm just works fine. So by providing the Administrator’s hash as authentication input, we can successfully login to the system and obtain the root flag!

$ evil-winrm -u ‘a-whitehat’ -p ‘bNdKVkjv3RR9ht’ -i
$ evil-winrm -u ‘enterprise-core-vn’ -p ‘ry=ibfkfv,s6h,’ -i

This post is licensed under CC BY 4.0 by the author.