# MeterpreterHeader::TCP

A plugin that detects meterpreter formatted headers in TCP connections by sampling packets in each connection. This relies on the specific XOR encoding used in these headers, as well as the finite number of possible values of some fields. 

 
## Usage

Install the plugin using instructions from [here](https://docs.zeek.org/en/current/devel/plugins.html).

The `meterpreter_header_detected` event will be triggered once for each detected Meterpreter TCP session.
The `meterpreter_header_content` event will be triggered once for each detected Meterpreter TCP session. The difference with the first event is that it contains information about the session, but might be triggered later.



## Header structure

![Meterpreter header structure](./docs/meterpreter_packet.png)
The header is XOR-encoded with the key from the first 4 bytes of the payload. It is relevant to note that even when meterpreter encrypts its contents, it leaves the header in plaintext, but sets the encrypt flag to 1.

## Possible header values

While the GUID is random, we have the following possible values for the encrypt flag and the type :

	ENC_FLAG_NONE = 0;
	ENC_FLAG_AES256 = 1;

	PACKET_TLV_TYPE_REQUEST = 0;
	PACKET_TLV_TYPE_RESPONSE = 1;
	PACKET_TLV_TYPE_PLAIN_REQUEST = 10;
	PACKET_TLV_TYPE_PLAIN_RESPONSE = 11;

## Detection strategy

If we consider randomly distributed values over 4 bytes, we have about a chance in 2e18 to have both a valid encryption flag and type field. However, in case there is some other protocol that has a similar header, we use the length field to triple check that this is a meterpreter header. 
 
To avoid taking up too much memory, this plugin uses filtering and sampling to avoid having to do a potentially costly xor on each packet

### Filtering

#### TCP

The plugin filters out TCP connections for which zeek has identified a service, by using the `HookQueueEvent` hook to detect `protocol_confirmation` events. 

### Sampling

The plugin samples only part of the packets it sees for each connection, and raises an event for a connection if one of those packets passed the tests. 

## Packets vs Messages

A potential issue comes from the fact that meterpreter messages, e.g. writes to the network socket, can be (and often are) longer than the MTU of a TCP packet. This means only part of the packets on the wire will have this header, meaning that we might miss the information if we only sample a few.

However, meterpreter communication is synchronous (a part from some specific streaming commands), so the only packets that will contain the header are the ones that come first in a sequence of contiguous packets. We can identify these by looking at the sequence and acknowledgment numbers : They are always the first non-empty packets for which the acknowledgment number has increased. 

![Packets vs Messages](./docs/packets_and_messages.png)

On this diagram of a synchronous TCP exchange, we only show the non-empty packets. The red arrows represent the first packet of each message

## Performance and Issues

The plugin performs significantly better than the script that was previously written to perform this task. Enabling the plugin increases computation time by 1.5% on a 84Gb CTF pcap.

This has not been tested for false positives on a Polaris site yet.

## Further reading

See the paper I wrote on this and similar ideas for detection Metasploit and other C2 frameworks - [https://ieeexplore.ieee.org/abstract/document/8659361/](https://ieeexplore.ieee.org/abstract/document/8659361/)
