Hacking Tutorial

Abusing Zoom Webinar/Meeting Software to Steal Windows Credentials

A vulnerability exists within Zoom with the way that it handles UNC paths in its chat feature. UNC (Universal Naming Convention) paths are used by computer systems to reference network resources and typically look like the following:


As you can see from the above text, this path is listed out in this blog post as text, but isn’t a clickable link. The vulnerability that exists in Zoom is the fact that these paths are clickable links that will automatically attempt to take users that click on them to the share, whether it exists or not.

Why is this a problem? Most webinars/meetings in Zoom will allow all attendees to type in the chat. This would allow a nefarious actor to place a malicious UNC path into the chat and direct users to interact with it.

The exploit we’re going to use isn’t new. In fact, I’ve already written about it in a previous blog post! I highly recommend that you check it out, as I’m not going to go as in depth as I did in that post; Abusing LLMNR/NBT-NS in Active Directory Domains: Part 1 (Capturing NTLMv2 Hashes).

Table of Contents:

  • Performing the attack
  • But wait.. You need local network access?
  • Mitigation Strategies

Performing the attack

To begin, let’s ensure our Responder tool is configured with all servers on.

sudo gedit /opt/Responder/Responder.conf

With all servers active, let’s go ahead and Run Responder on our primary interface (note yours may differ depending on your environment).
sudo python Responder.py -I eth0

So what’s happening here? Responder.py is listening for all incoming requests in the three listed Poisoners (LLMNR, NBT-NS, DNS/MDNS).

Why does this matter? Computers will send their username & passwords (in hashed format) to any SMB shares when trying to connect. They do this by design so that the SMB server can determine whether or not the user is allowed to access this share.

What do we need to do? Now we just need a way to get machines to reach out and request to connect to a server of ours, such as an SMB share. If only there was a way to share a clickable link to a SMB share with multiple users all at once.. Enter Zoom!

From within a Zoom webinar/meeting, let’s go ahead and place a UNC path to see the vulnerability in action.

As you can see, the path lights up and is clickable. With Responder.py running on our attacking machine, let’s go ahead and click the link from the victim machine. Clicking the link from the victim machine doesn’t appear to do anything at all, but let’s check the output of our Responder.py window..

Check it out, we’ve got a NTLMv2 hash along with its username. From here, we could utilize additional tools to relay this hash to other machines on the network or even crack it to obtain the password in clear-text. Tutorials on these topics are coming in the future.

Note: This above example is abusing LLMNR in the network in order for Responder.py to receive the request. This is because the share \\infinitelogins\share doesn’t actually exist. If LLMNR is disabled in the network, a UNC path that directly points to the attacking machine is necessary.

But wait.. You need local network access?

Everything I’ve shown you up to this point DOES require that your attacking machine is on the same local network as the victims. With that said, it is possible to leverage this same technique to have machines connect to a publically routable address that is running Responder.py (assuming that SMB is allowed out of your network and over your internet provider).

Mitigation Strategies

Don’t allow everybody to chat within Zoom. You should be able to limit chat capabilities to specific users of panelists-only. If a UNC share can’t be shared, the exploit can’t take place.

Perform egress filtering on port 445. If outbound SMB requests are denied in your network, or at the gateway, Responder.py will never see the request come in and will never ask for the machine’s NTLM credentials.

Educate users. User awareness training will help prevent attacks like this along with other common phishing techniques. If users know what not to click on, they won’t click.

Disable LLMNR/NBT-NS. You should really just disable LLMNR in your network for a number of reasons, but this won’t prevent the attack if the UNC path provided in the chat points directly to the attacking box. It will stop the attack if the share entered within the chat window doesn’t exist however.

Hacking Tutorial, Pentesting

How to Brute Force Websites & Online Forms Using Hydra

Encrypt and Anonymize Your Internet Connection for as Little as $3/mo with PIA VPN. Learn More

While working through NINEVAH on HackTheBack (Write-Up on this coming in a future post), I came across a couple web forms that I needed to break into. In my opinion, using the Intruder feature within BurpSuite is an easier way to run brute-force attacks, but the effectiveness of the tool is greatly reduced when using the free community version. Instead of dealing with slow brute-force attempts, I decided to give Hydra a try.

What we’re breaking into

If you’re unfamiliar with https://hackthebox.eu, I highly recommend checking them out. Click here to check out my HackTheBox related content.

NINEVAH sits on HackTheBox servers at IP address I found a couple login pages at the following URLs. These are the addresses we’re going to attempt to break into.

1st Address:

This image has an empty alt attribute; its file name is image-34.png

2nd Address:

This image has an empty alt attribute; its file name is image-36.png

Using Hydra to Brute-Force Our First Login Page

Hydra is a fairly straight forward tool to use, but we have to first understand what it needs to work correctly. We’ll need to provide the following in order to break in:

  • Login or Wordlist for Usernames
  • Password or Wordlist for Passwords
  • IP address or Hostname
  • HTTP Method (POST/GET)
  • Directory/Path to the Login Page
  • Request Body for Username/Password
  • A Way to Identify Failed Attempts

Let’s start piecing together all the necessary flags before finalizing our command.

Specifying Username

In our particular case, we know that the username Admin exists, which will be my target currently. This means we’ll want to use the -l flag for Login.
-l admin

Note: If you don’t know the username, you could leverage -L to provide a wordlist and attempt to enumerate usernames. This will only be effective if the website provides a way for you to determine correct usernames, such as saying “Incorrect Username” or “Incorrect Password”, rather than a vague message like “Invalid Credentials”.

Specifying Password

We don’t know the password, so we’ll want to use a wordlist in order to perform a Dictionary Attack. Let’s try using the common rockyou.txt list (by specifying a capital -P) available on Kali in the /usr/share/wordlists/ directory.
-P /usr/share/wordlists/rockyou.txt

IP Address to Attack

This one is easy!

Specifying Method

This is where we need to start pulling details about the webpage. Let’s head back into our browser, right-click, and Inspect Element.

A window should pop-up on the bottom of the page. Go ahead and select the Network tab.

Right away, we see a couple GET methods listed here, but let’s see what happens if we attempt a login. Go ahead and type in a random username/password, and click Log In.

Of course our login attempt will fail, but we’re able to see that this website is using a POST method to log-in by looking at the requests.

Easy enough, now we know what method to specify in our command!
Note: You’ll need to enter https if you’re attacking a site on port 443.

Specifying the Path to Attack

So far, we’ve only told the tool to attack the IP address of the target, but we haven’t specified where the login page lives. Let’s prepare that now.

Finding & Specifying Location of Username/Password Form(s)

This is the hardest part, but it’s actually surprisingly simple. Let’s head back over to our browser window. We should still have the Inspect Element window open on the Network Tab. With our Post request still selected, let’s click Edit and Resend.

Now we see a section called Request Body that contains the username and password you entered earlier! We’ll want to grab this entire request for Hydra to use.

In my case, the unmodified request looks like this:

Because we know the username we’re after is “admin”, I’m going to hardcode that into the request. I’ll also replace the “Password” I entered with ^PASS^. This will tell Hydra to enter the words from our list in this position of the request. My modified request that I’ll place into my Hydra command looks like this:

Note: If we desired, we could also brute-force usernames by specifying ^USER^ instead of admin.

Identifying & Specifying Failed Attempts

Finally, we just need a way to let Hydra know whether or not we successfully logged-in. Since we can’t see what the page looks like upon a successful login, we’ll need to specify what the page looks like on a failed login.

Let’s head back to our browser and attempt to login using the username of admin and password of password.

As we saw before, we’re presented with text that reads “Invalid Password!” Let’s copy this, and paste it into our command:
Invalid Password!

Piecing the Command Together

Let’s take all of the components mentioned above, but place them into a single command. Here’s the syntax that we’re going to need.

sudo hydra <Username/List> <Password/List> <IP> <Method> "<Path>:<RequestBody>:<IncorrectVerbiage>"

After filling in the placeholders, here’s our actual command!
sudo hydra -l admin -P /usr/share/wordlists/rockyou.txt http-post-form "/department/login.php:username=admin&password=^PASS^:Invalid Password!"

Note: I ran into issues later on when trying to execute this copied command out of this WordPress site. You may need to delete and re-enter your quotation marks within the terminal window before the command will work properly for you.

After a few minutes, we uncover the password to sign in!

Using Hydra to Brute-Force Our Second Login Page

Go through the exact same steps as above, and you should end up with a command that looks like this.
sudo hydra -l admin -P /usr/share/wordlists/rockyou.txt https-post-form "/db/index.php:password=^PASS^&remember=yes&login=Log+In&proc_login=true:Incorrect password"

So what’s different between this command and the one we ran earlier? Let’s make note of the things that changed.

  • Method was switched to https-post-form
  • Path was updated to /db/index.php
  • Request Body is completely different, but we still hard-code admin and replace the password with ^PASS^
  • Finally, the text returned for a failed attempt reads Incorrect password

After running the command, we uncover the password after just a couple minutes.

Let me know if you found this at all helpful, or if something didn’t quite work for you!