Having recently passed the CRTO course by RastaMouse, I felt it was only right to write a little review on it. Typically, the course has changed slightly since I sat it, with the labs now using Elastic Security in place of Splunk. Aside from this I believe the course is practically the same.
TL:DR
Go and buy it now! It is the best qualification out there if you are looking to break into offensive security. The labs & coursework are great and will teach you a range of techniques used in real-world red teaming.
In the past few days since writing this, CRTO has been listed as a ‘Trusted Training Partner’, showing how good this course is.
Labs
The course works via Apache Guacamole, in a very similar way to ImmersiveLabs and a few other online training providers. All of the labs can be spun up on request, but you only have a limited amount of lab time.
I went for the 120 hour option, which I felt was just right, though I would recommend reading through the material first and then approaching the labs. This will reduce the amount of time the labs are running whilst you try to understand the more complex attacks (cough cough resource–based constrained delegation).
I believe CRTO is the cheapest way you can legitimately use Cobalt Strike, without having to pass the licencing checks or use a cracked version. This is really handy as Cobalt Strike is used so widely for red teaming.
Lab Issues
Running the labs through a browser does have its limitations, with no drag-and-drop and less keyboard shortcuts available. I would say this is preferable to having to create your own VMs and VPN into a network, as you can begin learning straight away.
The labs I had came with a version of Office and Splunk, both of which reverted to a trial mode after a few uses, whilst there was a fix for that issue, it did feel a little hacky to me.
Importantly, these are dedicated labs and you wont accidentally get any spoilers from other users. As with most online labs, it is worth giving them 5-10 minutes to fully load before beginning any testing or activity.
Learning Material
As mentioned previously, the content of this course is EXCELLENT. It covers a wide range of different attacks, as well as covering off the paperwork & reporting side of red teaming. The material is written in the style of a technical blog post, with code snippets throughout. Handily there are some videos included for the more complicated techniques, which helped to solidify my understanding. There are also hints and tips for OPSEC considerations, which is a nice touch.
The exam gives you 48 hours of lab time over a span of 4 days, with a mock network for you to break into. This basically the same format as the labs, with the ability to reset your Kali and Windows boxes.
Scoring is structured like a CTF, where you only have to obtain a flag on the machine to prove you have compromised it. There are 8 machines, and you need to obtain 6 flags to pass. Importantly there is no reporting requirements, which makes this exam feel far less stressful than OSCP.
The exam can be booked at really short notice – I booked mine with only 6 hours of notice. When your exam starts, you will have another course option within SnapLabs which contains the lab environment.
One thing which surprised me was the smaller toolset available in the exam – something which I hadn’t seen anyone else mention in the other reviews. Effectively you have a subset of the tools from the training labs, which required me to think on my feet a bit! Whilst it pointed out some gaps in my knowledge, I think it would have been handy to have the full toolset for the exam, or at least have knowledge of which tools wouldn’t be provided in the exam.
The exam lab was also really well laid out, allowing you to easily regain your access without having to recompromise every machine in turn. There are some quirks with the exam labs though, with one of my flags failing to generate. This can be resolved by chatting to RastaMouse on the dedicated Discord channel.
CRTO vs OSCP
OSCP has been a fairly ubiquitous qualification within cyber security for a number of years. I would personally say that OSCP does have its place, and is still worth the effort if you are wanting to pursue a penetration testing route. Despite that, I feel that there is more to be gained from completing CRTO and paying for VIP+ on HackTheBox, than shelling out for OSCP.
OSCP was a great learning experience for me, but most of the machines were severely outdated and used exploits from the 00’s. In comparison, CRTO uses Windows 10/Server 2016+ everywhere, making it far more representative of the real-world. The majority of CRTO is misconfiguration-based, whereas OSCP is vulnerability-based.
The exam experience for CRTO was also significantly better, with far less lead time and a less stringent approach. There is no proctoring or report writing, and the 4 day timespan means you can still have a life whilst taking the test.
Improvements
I would change very little about the CRTO course personally. I think VPN access would be handy so that you can bring your own tooling, but it isn’t a big issue at all.
Update 23/2/22: RastaMouse confirmed that the lack of VPN access is a requirement of the licencing with Cobalt Strike (HelpSystems). Therefore the lack of VPN makes total sense in order to get a CS licence in this training!
As mentioned about 10 times a day on Discord, RTO 2.0 would be the main improvement I can think of. A course focused more on AV/EDR evasion or simply more advanced/complex attacks would be a great addition to this course. I think a greater focus on maintaining long term access to the target network would also be a nice improvement, as CRTO only briefly touched on it.
I also think a course which required you to use Splunk/Elastic in combination with Cobalt Strike would be quite interesting and could be aimed more at threat hunters or SOC analysts.
Overall
As you have probably guessed, I really enjoyed this course. I am not aware of any other courses which offer the combination of great labs and content like CRTO does. I think it is a great introduction into red teaming methodology, and will help many people to up their skills.
Below are some other blog posts I found handy before taking my exam, which are also worth checking out:
Toy Workshop was a 1 star rated ‘Web’ challenge from the HackTheBox “Cyber Santa is Coming to Town” CTF. This was an interesting challenge, with the flag coming from a blind stored-XSS which led to the leakage of the flag from a cookie value in a Puppeteer instance.
After that mouthful, lets take a look at my solution to this problem.
Tooling Used
I made use of a number of new tools for this challenge. Rather than spinning up an Azure VM, I wanted to try and use free online resources. In particular, I used:
I performed initial recon with my go-to combination of nikto -host x.x.x.x and gobuster dir -u http://x.x.x.x. These returned nothing interesting, so I moved to digging through the resources on the site. At this point I remembered that we can download the files for the server from the CTF site. This reveals a POST request to /api/submit.
Initially, I thought the vulnerability would be within the logic for the /queries endpoint. Due to this checking for a localhost address, I suspected that spoofing the X-Forwarded-For header could allow this check to be bypassed. As Express is known to have issues when relying on the value from the req.ip parameter.
After many attempts, I decided to look elsewhere as I wasnt making progress. After a short search, I discovered the bot.js file, which had some unusual behaviour.
Bot.js
The bot.js file uses puppeteer to load the site. As shown on line 24 of the file, the flag is included in the cookies when it loads the site. My initial thought here was to either obtain command execution or a reverse shell. With no obvious routes to achieve this, I decided to try and inject HTML into the web page.
As you can see from the logic of the server, it uploads our data to the database and then queries it using puppeteer. This means we could upload HTML and it should be processed by the bot. The code for the database actions are shown below:
Canary Tokens
To test this theory, I created a CanaryToken web bug to test that I could perform two different actions.
The ability to inject HTML into the /queries endpoint
The server can reach out to an arbitrary web resource (i.e no firewalls)
Using a temporary email address, I registered this token. I then created a basic payload to inject an image into the webpage. Using Burp Suite I was able to insert it to the database.
This then returned a hit to my temporary mailbox, as shown below.
Final Payload
To convert this into a working payload, I decided to redirect the /queries endpoint to a postb.in page I controlled. This allowed me to POST the value of the cookies out. In the end, my complete payload for /api/submit was as follows:
This post will cover the attacks detailed in the white-paper produced by SpecterOps. The most well-known of which is the ‘ESC8’ attack – where a standard domain user can escalate to Domain Admin, given a vulnerable environment. If AD CS is a new concept to you, then I have a post covering the basics, as well as what can be misconfigured in an AD CS environment.
Before we begin with the main ‘Domain Escalation’ attacks (p. 54-81), we will quickly cover the THEFT5 attack, which is a technique we can use to obtain the current NTLM hash of a user, so long as we have a valid certificate.
All of the examples covered here will use either the WADE_PARKS or LAURI_ROTH users to represent low-privilege users within my test domain. (Thanks to davidprowe for the excellent BadBlood project which I used to populate an AD environment).
This post will show how we can make an AD CS environment vulnerable to the following attacks.
THEFT5 – Obtaining An NTLM Hash From A Certificate
Assuming we have managed to steal a certificate, or requested one through the default User template, then we can use Kekeo to request the NTLM hash of the target account. This is covered on page 49.
For example, say we have managed to steal a certificate for WADE_PARKS. We can then use LAURI_ROTH‘s account to request Wade’s NTLM hash, with just his certificate!
To perform this, we must import the stolen certificate into our certificate store (i.e. via MMC). Kekeo will use the imported certificate and request the NTLM hash from the KDC via PKINIT. This is a pretty technical exploit, and takes a while to fully get your head around! From Lauri’s machine, the command to perform this attack is:
As we can see, Wade has a very strong password here:
A nice strong 10 character password from Wade
The key part of this attack is that we can continue to obtain passwords for Wade, so long as the certificate is valid. By default this is for 1 year from the certificate being issued.
With this attack, we will request a certificate through MMC as normal. With this specific misconfiguration, we can specify a User Principal Name (UPN) to request the certificate for. For example, as a low privilege user we could request a certificate for the Domain Admin. In this example, we will request a certificate for Wade using Lauri’s account as a demonstration.
To set the UPN we want to target, use the Alternative Name section of the wizard, using the User Principal Name field.
Requesting a certificate for WADE_PARKS
After completing this wizard, we get a certificate for Wade added to our certificate store (On Lauri’s computer!).
We now have a certificate for Wade, even though we aren’t on his machine!
Using Rubeus, we can use this certificate to obtain a TGT as Wade now, which expands what we can do with this attack. To do this, we will use the following command. Note that the password below is the password we applied to the exported certificate.
This misconfiguration is similar to ESC1, but two settings are changed:
The ability to supply any UPN in the request is removed (VULN6)
The EKU OID is either set to ‘Any Purpose’ or ‘None’
The ‘Any Purpose’ OID is interesting, as it allows for a certificate to make use of any of the potential uses of certificates. For example, it could be used for Domain Authentication or signing code. This is obviously seriously bad news if it is used by a skilled attacker. One of the potential OIDs which could be leveraged is the SubCA (i.e. A child certification authority) OID.
In theory the SubCA OID could allow a machine to create a child CA, which an attacker would have full control over. This could lead to an attacker enabling dangerous settings such as VULN3, VULN6 or VULN7. In reality, it is unlikely an attacker could do this, as the SubCA certificate would not be trusted by the root CA by default (Page 62).
We can configure a template with the Any Purpose policy by editing a Certificate Template on the AD CS server.
As a PoC, we can then obtain a TGT as the requesting principal. This is because the Domain Authentication policy would be included within the Any Purpose policy.
We can also do the same by removing all the Application Policies from the template, as shown in the ESC2a template below:
ESC2a template configuration
ESC3 – Enrolment Agent Templates
This attack relies on being able to get a certificate as an Enrollment Agent. This will allow us to approve requests for certificates. For this, we will create 2 vulnerable templates which must be used together:
This template will allow the Client Authentication policy to allow us to sign in as the requesting user.
A standard Client Authentication template
Notably, this ESC3b template can require a signature before issuance – as we can leverage the certificate from ESC3a to sign the request.
To perform this attack, we will request a certificate for ESC3a. This certificate needs to be added to our certificate store – something which MMC will do by default. You could always import a stolenRequest Agent certificate if you find one on the estate.
To obtain a certificate for ESC3b, we will need to use the ‘Enroll on Behalf of’ option in MMC.
Starting to leverage the ESC3a certificate
Thanks to ESC3a, we can choose that certificate when requesting ESC3b.
We can then set our user details in the wizard
The wizard will allow for multiple requests, so click on Cancel when you have obtained your ESC3b certificate. We can now see both of our certificates in the certificate store.
This attack relies on poor access control to the template object in AD. This will be based on the User template, but I have enabled the ability to specify an arbitrary SAN to demonstrate the risk posed by this attack. This would require an extra step of misconfiguration, and is slightly different to how ESC4 is described in the whitepaper. Without this, we could still perform an attack such as ESC2, where we can get a certificate for the current principal.
In this example, we will remove the Enroll permission, and instead enable the ‘Write‘ permission. By default we will not be able to enroll in this certificate, but we can edit the object to grant ourselves the Enroll permission.
When we go to our standard domain user, we are unable to enroll in ESC4 due to a permissions error.
Using PowerView, we can find our permissions on the ESC4 template
Recall that *-513 is the Domain Users SID. This SID now has GenericWrite, WriteDacl and WriteOwner permisisons. We will use the Add-DomainObjectAcl in PowerView to grant us all permissions on the object. This is pretty noisy and not especially subtle, but it demonstrates the risk! The command used for my environment is below:
Add-DomainObjectAcl -TargetSearchBase "CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=forest,DC=com" -Rights All -PrincipalIdentity 'S-1-5-21-4011496586-3104324443-3246812018-513'
We can run the Get-DomainObjectAcl command from above to check we have successfully gained additional privileges.
Going into MMC we can now enroll on the ESC4 template. Remember we set this one up to have a vulnerable SAN – so we could now get a cert as DA. Being able to set a SAN is not a requirement of this attack.
We can see that the setting was successfully changed.
If we run the reg query command from above, we can see the flag has changed to 0x15014e.
Exploiting this is slightly different from VULN6 and ESC1, where we could specify a SAN in the request. This attack relies on specifying the SAN via a certificate attribute, rather than a certificate extension (Such as in ESC1). Therefore, we need to use certreq rather than MMC, this is described on page 71 in more detail.
To do this, we must create a .req file for us to create a CSR from. To do this, we can use MMC to create a ‘Custom Request’
Click through the wizard, and select the template you want to abuse, I will use the User template as it allows for domain authentication.
Export the file as a .req file. This might officially be a .inf file – either way, certreq will be happy with either extension!
Then save your file – I will use the filename esc6.req.
Now we have a .req file, we can alter this CSR to add a SAN in our certificate request. At this point we have to set the SAN via a certificate attribute, rather than a certificate extension (Like we abused in ESC1). To do this, we must use certreq with the -attrib parameter. For my environment, we would use the following command from a low-privilege command line:
We now have a .cer (Public certificate only), which we will import into MMC. The private key is stored on the computer – when we import into MMC it will join them together and allow us to form our .pfx file (Public and Private key).
Requesting our certificate with certreq.
Double click on the .crt file we just got via certreq and we can install it by clicking on Install Certificate.
Click through the wizard, I personally select it to be installed to an automatically chosen location. We now have a certificate for ‘WADE_PARKS’, but if we look closer we can see it is actually valid for the Administrator account
MMC showing that we have a certificate for ‘WADE_PARKS’, but it really is for the Domain Admin!
If we double click on the certificate in MMC, we can view the Subject Alternative Name field within the Details tab, showing who we can authenticate as with this certificate.
Here is the proof it is for the Domain Admin
After exporting, we can now get a TGT for the Administrator user with Rubeus.
Lets reset our value for EDITF_ATTRIBUTESUBJECTALTNAME2 so we don’t accidentally leverage it later on!
First off, lets check the permissions on the CA object, by using certsrv. Right click on the CA, then Properties, then Security
Lets enable the ‘Manage CA’ option on the Authenticated Users group. Obviously this is a really bad idea in the real world!
We can use PSPKI 3.7.2 to edit this value, as shown on page 76 of the whitepaper. This can be downloaded from the PSPKIAudit repo. We will use a built in PSPKI PowerShell function here, rather than editing DCOM as shown in the whitepaper.
Now we need to install RSAT. this isn’t very stealthy and requires local admin privileges to install. I believe that Certify doesn’t require these privileges.
Run DISM.exe /Online /Get-Capabilities to get the DISM images
Here is the CertificateServices.Tools image we want to install
We can then install the image with the following code:
Now we have RSAT, we can run PSPKI. The following commands will get the current setting for EDITF_ATTRIBUTESUBJECTALTNAME2 and then configure it to be vulnerable.
As we can see, EditFlags is now set to 0x15014e which is 1376590. From ESC6, we know this means we have set EDITF_ATTRIBUTESUBJECTALTNAME2 to be true.
From this point, we can follow ESC6 to gain further access.
PSPKI Import: HRESULT: 0x80131515
I had issues getting PSPKI to run, as it often threw “Exception from HRESULT: 0x80131515” errors. To solve this, refer to StackOverflow! It turns out that the DLL is being blocked by Defender. If we navigate to the PSPKIAudit folder, we can run the following command to unblock all the files.
Get-ChildItem *.* -Recurse | Unblock-File
Whilst testing this, I found the code from this site was handy for checking which DLLs we have successfully imported into our PowerShell session. The code for checking this is as follows:
Due to my lab setup, there were issues getting PetitPotam and the NTLM relaying working to the AD CS HTTP Endpoint. This is due to DC’s requiring message signing for all requests, which breaks the attack from what I can tell.
To bypass this, I have created another AD CS server (CAServer) and demoted my old one (DC01) used in ESC1-7. This is a standalone AD CS server, leaving DC01 to perform DC duties.
Details of the new CAServer (192.168.47.102)
Using PetitPotam we can elicit an NTLM hash from a target, then use Responder to take that NTLM hash and attempt to gain a cert. I used the following commands to do this:
On my environment, this would trigger an NTLM relay (Showing PetitPotam is working), but I could not obtain a certificate.
Thanks to a tweet by Fragsh3ll, it looks like we might have to manually specify the ‘Domain Controller’ certificate. We can do this with the --template 'Domain Controller' argument in impacket. As shown below, this will return a certificate.
We can then import this base64 encoded certificate onto our low privilege user’s account. This certificate can then be used with Rubeus, using the /certificate: parameter.