Can you hear me now?

Translators allow agents to send beacons across any network protocol and Operator will accept them as native connections

One of the most common requests we receive in Operator is: can you add a listening post to the app which accepts beacons through the __ protocol? Fill in the blank with any of the dozens of popular network protocols, from DNS to RPC.

We thought long and hard about how to do this.

We didn’t want to bloat Operator with dozens of listening posts and ports which take resources on the installed machine. The code would be squirrely and tough to maintain. You’d also have to wait for us to design and test protocols, which seems silly. We also didn’t want to built them into plugins because listening posts often require administrative privileges, as you probably need to serve privileged ports and support multiple interfaces. Also, the code would be squirrely.

Operator - by default - supports three native protocols: TCP, UDP and HTTP(s). These are basic building blocks of how network communication occurs, so we want to keep these as the foundational listening posts in the application.

So we tucked away the concept of additional listening posts and decided to address the problem later.

Well, later is now! We’d like to take this opportunity to announce the latest Operator feature, called translators.

A translator is a simple server, written in Python, which can be deployed on any computer or server as a proxy between agents and your Operator instance. Each translator is designed to accept beacons over a specific protocol, then proxy it to one of Operator’s native protocols and pong the response back to the agent via the original translated protocol.

Why Python? Three reasons: it is a popular language in security engineering, it can be deployed with minimal dependencies on any computer, it is a concise language allowing us to create translator servers in only a few dozen lines of code.

To prove out the concept, we wrote, and subsequently published open-source, two translators: FTP and gRPC.

FTP translator

The FTP translator was our first one. We started by creating a quick module, which serves FTP over the default port 21.

Next, we ensured that the translator would accept beacons - in file format - over FTP’s STOR endpoint. Upon receipt, the translator converts the file into an HTTP beacon and proxies it to Operator, where it is processed, and returned to the translator, which in turn saves the resulting instructions to a file where the agent can pick it up later via the RETR endpoint.

To accompany the server, we wrote an example agent, which works end-to-end with the translator. We decided to write the agent in Python as well, not because we had to, but because it was a quick and easy way to provide a working example.

gRPC translator

Next up was gRPC.

A few months back we added gRPC as the 4th native protocol supported in Operator. This decision always made us uncomfortable for the reasons above: we didn’t want to get in the habit of adding requested protocols into the core Operator code base. So with the birth of translators, we decided to rip it out of Operator core (as of version 1.1.0) and pop it into a brand new gRPC translator.

Again, we started with the server.

gRPC uses something called protocol buffers, which is a language agnostic way to structure data (think JSON or XML), designed by Google who also wrote gRPC (as a way to add structure to the unstructured way RPC communicates). We converted the protocol buffer we were using inside Operator core into a protobuffer we could use in the translator. Then we wrote a simple server - in Python - which accepts traffic over gRPC, converts it into an HTTP beacon, proxies the translated beacon to Operator, and pongs the response back via gRPC to the agent who sent it in.

Since the Pneuma agent already supports gRPC we didn’t need to write a new agent to accompany this translator. You can use Pneuma against the gRPC translator by starting the agent with the gRPC contact and pointed at the address of your (running) translator server:

./pneuma-darwin -contact grpc -address localhost:50051

So where do we go from here? We want to support a series of new network protocols - in the form of translators - including DNS and RPC, which are at the top of our list. We’d also love to see translators which allow us to accept beacons from other popular agents in the wild, such as Meterpreter (Metasploit) or Beacon (Cobalt Strike).

We made translators open source, to encourage others to write and contribute them back to the community. We encourage you to join our Discord server and let us know which translators you’re interested in using - or writing - yourself.