Wednesday, April 5, 2017

Hunting Red Team Empire C2 Infrastructure

Introduction

While playing around with setting up my C2 nodes and redirectors for an engagement, I decided to start poking around at both Empire and Meterpreter's default setups. The end goal of this project was to be able to positively identify nodes on the Internet that are being used actively by attackers or Red Teams with little to no scope filtering. The results were interesting, and the first time investigating revealed over twenty easy to find C2 nodes running stock Empire or Meterpreter reverse http/s sessions.

History of Failure

Coding is difficult, even for hackers. Both Empire, and Metasploit projects have a history of Remote Code Execution vulnerabilities. Red Teams need to go to great lengths in order to keep people from compromising their crown jewels which includes active agents and client data.

Empire RCE
Metasploit RCE

Empire

Empire, now in beta for 2.0 includes both Powershell Empire as well as the python version Empyre. The Empire listener is based on BaseHTTPServer in Python and provides an extraction layer on top of it. Let's take a look at the HTTP headers that are present in default Empire configuration.

Empire Headers

Using the HTTP request of GET / HTTP/1.1, the following headers were returned.

HTTP/1.0 200 OK
Server: Microsoft-IIS/7.5
Date: Wed, 05 Apr 2017 18:26:10 GMT

The thing that stands out here is the general lack of headers that would normally be present in a request. Also, the fact that we used HTTP/1.1 as the protocol, but the reply is still for HTTP/1.0

Empire default page

<html><body><h1>It works!</h1><p>This is the default web page for this server.</p><p>The web server software is running but no content has been added, yet.</p></body></html>

Hashes of defaul page

MD5: 885ecd7910c988f1f15fcacca5e1734e
SHA1: b642227fbc703af1a67edb665241fc709ecd6f6e
SHA2: a58fb107072d9523114a1b1f17fbf5e7a8b96da7783f24d84f83df34abc48576

Finding Empire Listeners with Shodan

Shodan is a search engine for Security Researchers. They routinely scan common ports across the Internet, and make the data publicly available, and easily searchable. APIs are also provided for automating a lot of the tasks required.

Using the common headers, and default web page listed above, we are able to narrow down the list of possible Empire C2 nodes on the Internet with a simple query.

'Microsoft-IIS/7.5' 'It works!' -'Content-Type' -'Set-Cookie'

You'll notice that the results returned all are HTTP/1.0 with matching profiles that we scoped out above.

Finding an exception in Empire

The HTTP module in Empire is located in lib/common/http.py. Go ahead and use your favorite text editor to open that up, and have a look around at the code.

In the class RequestHandler and method do_GET we have the following piece of code for handling parsing of cookie data.

if cookie:
            # search for a SESSIONID value in the cookie
            parts = cookie.split(";")
            for part in parts:
                if "SESSIONID" in part:
                    # extract the sessionID value
                    name, sessionID = part.split("=")

Interesting.
name, sessionID = part.split("=")
If there is more than one equal sign in the cookie field, it'll continue to split on equal signs. That line should be this.
name, sessionID = part.split("=", 1)
In order to limit the number of items to one.

Let's go ahead and try to exploit this from the client side with the following request.

curl http://target:port --Cookie 'SESSIONID=id=id'

Curl will return the following error, because Python threw an exception upon parsing the cookies.

curl: (52) Empty reply from server

Changing default values

While executing a Red Team engagement, it's always a good idea to change the default values of tools that you use, whether it be a scanner or C2 infrastructure. This will make it harder for Blue Team elements to detect portions of your activity. You should also either utilize Empire's whitelisting feature or setup a Firewall in order to keep your test within scope. There is no excuse for leaving your C2 node exposed to the entire Internet.

You should have noticed while browsing http.py that the default page served is also located in that file in the function named default_page.

In order to change the default server name, you must edit the configuration in the empire.db file located in data/. Open it up by using sqlite3 data/empire.db. You can view the current setting by typing SELECT server_version from config;
In order to update it, something like the following will do the job.

update config set server_version = 'nginx' where server_version = 'Microsoft-IIS/7.5';

Going beyond Shodan

Scans.io is another great resource for looking at Internet-wide scans including those for HTTPS sites. The scan sets are huge, but offer a very current view of HTTPs servers across the globe. Data is in JSON format, and the default page is saved in base64 format within each node.

zgrep 'PGh0bWw+PGJvZHk+PGgxPkl0IHdvcmtzITwvaDE+PHA+VGhpcyBpcyB0aGUgZGVmYXVsdCB3ZWIgcGFnZSBmb3IgdGhpcyBzZXJ2ZXIuPC9wPjxwPlRoZSB3ZWIgc2VydmVyIHNvZnR3YXJlIGlzIHJ1bm5pbmcgYnV0IG5vIGNvbnRlbnQgaGFzIGJlZW4gYWRkZWQsIHlldC48L3A+PC9ib2R5PjwvaHRtbD4=' 20170221-https.gz > /tmp/results.json

This may take several minutes to run, as the datasets are generally several gigabytes in size. The result will be a file containing JSON data for each host that returned the default Empire HTML. You can parse this file and extract each IP address that should be tested, and then feed them into the script below.

Automating detection with Python

Use the following to run this script.

python3 empire_identifier.py 

Happy hunting, a future post will detail similar experiences with Meterpreter.

No comments:

Post a Comment