Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c83334b
First pass of python meterpreter C2 profiles
OJ Mar 21, 2026
b332db9
Move towards TLV config
OJ Mar 24, 2026
bcb581f
First pass of C2 for java
OJ Mar 24, 2026
e0f3b60
Always use config block in python
OJ Mar 24, 2026
2ac49f0
Update PHP to make use of TLV configuration
OJ Mar 24, 2026
aecfefb
Add UUID cookie and proxy user/pass support to python
OJ May 13, 2026
cc28515
Proxy, debuglog, custom headers for java
OJ May 13, 2026
9e717dd
Add debug log and proxy config to PHP
OJ May 13, 2026
2c0b3d2
Multi-transport rotation & transport commands for PHP
OJ May 13, 2026
db2567b
Use TLV_TYPE_C2_UUID over URL-path in PHP/Python/Java
OJ May 13, 2026
d7971d9
Restore stageless for Android
OJ May 13, 2026
90c664b
Stagless entry point for java
OJ May 13, 2026
35aee2b
Fix debugging and UUID handling in python
OJ May 19, 2026
695986c
Fix PHP stageless with MC2
OJ May 19, 2026
1f29fd8
Correctly handle encoding of in/out bound data
OJ May 20, 2026
55d1d2e
Handle encoding correctly in windows meterp
OJ May 20, 2026
876374d
Remove trans_* defines from python extension
OJ May 20, 2026
a6c162c
Correctly handle id/meta encoding in PHP
OJ May 20, 2026
096c3e5
Python UUID encoding fixes
OJ May 20, 2026
a768921
Move to STRING instead of RAW for UUID prefix/suffix
OJ May 20, 2026
ea44513
Support MC2 and stageless in java properly
OJ May 20, 2026
0725b8d
Add extension support to stageless PHP
OJ May 20, 2026
4eeded1
Add stageless extension support to Python
OJ May 20, 2026
bc06ce0
Add extension support to stageless Java
OJ May 20, 2026
c72d32b
Remove debug lines from Java
OJ Jun 3, 2026
cc62367
Re-enable debug stream in java
OJ Jun 3, 2026
23cd419
Set redirectErrors to true to catch erros internally
OJ Jun 3, 2026
ddd8976
Skip compressed types for extensions
OJ Jun 3, 2026
595ff94
Use correct getParam
OJ Jun 3, 2026
68407d2
Allow restricted headers to be set in java
OJ Jun 9, 2026
0686ca2
Support multi-URI C2 profiles and add C2 debug logging in Python
OJ Jun 16, 2026
51735a0
Handle multiple C2 URIs in PHP payload
OJ Jun 16, 2026
ebcc62d
Handle multiple C2 URIs in Java payload + add docker build target
OJ Jun 16, 2026
cf1e363
Handle multiple C2 URIs in Windows meterpreter
OJ Jun 16, 2026
b632aef
fix: issue with stageless reverse tcp in python
dledda-r7 Jul 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion c/meterpreter/source/common/common_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,11 @@ typedef enum
TLV_TYPE_C2_CERT_HASH = TLV_VALUE(TLV_META_TYPE_RAW, 717), ///! Expected SSL certificate hash
TLV_TYPE_C2_PREFIX = TLV_VALUE(TLV_META_TYPE_RAW, 718), ///! Data to prepend to the outgoing payload
TLV_TYPE_C2_SUFFIX = TLV_VALUE(TLV_META_TYPE_RAW, 719), ///! Data to append to the outgoing payload
TLV_TYPE_C2_ENC = TLV_VALUE(TLV_META_TYPE_UINT, 720), ///! Request encoding flags (Base64|URL|Base64url)
TLV_TYPE_C2_ENC_INBOUND = TLV_VALUE(TLV_META_TYPE_UINT, 720), ///! Server->client (response) body encoding flags
TLV_TYPE_C2_ENC_OUTBOUND = TLV_VALUE(TLV_META_TYPE_UINT, 728), ///! Client->server (request) body encoding flags
TLV_TYPE_C2_ENC_UUID = TLV_VALUE(TLV_META_TYPE_UINT, 729), ///! Encoding applied to the UUID before placement
TLV_TYPE_C2_UUID_PREFIX = TLV_VALUE(TLV_META_TYPE_STRING, 730), ///! String to prepend to the encoded UUID
TLV_TYPE_C2_UUID_SUFFIX = TLV_VALUE(TLV_META_TYPE_STRING, 731), ///! String to append to the encoded UUID
TLV_TYPE_C2_PREFIX_SKIP = TLV_VALUE(TLV_META_TYPE_UINT, 721), ///! Size of prefix to skip (in bytes)
TLV_TYPE_C2_SUFFIX_SKIP = TLV_VALUE(TLV_META_TYPE_UINT, 722), ///! Size of suffix to skip (in bytes)
TLV_TYPE_C2_UUID_COOKIE = TLV_VALUE(TLV_META_TYPE_STRING, 723), ///! Name of the cookie to put the UUID in
Expand Down
9 changes: 7 additions & 2 deletions c/meterpreter/source/common/common_remote.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ typedef struct _NamedPipeTransportContext

typedef struct _HttpRequestOptions
{
STRTYPE uri;
STRTYPE* uris; ///! Request URIs (base, or profile candidates); one chosen at random per request.
UINT uri_count; ///! Number of entries in uris.
STRTYPE ua;
STRTYPE headers; ///! Custom headers, including accept types or referrer if required.
PBYTE payload_prefix; ///! Bytes to prepend to outgoing payloads.
Expand All @@ -83,7 +84,11 @@ typedef struct _HttpRequestOptions
UINT payload_suffix_size; ///! Size of the payload suffix
UINT payload_prefix_skip; ///! Size of the incoming prefix to ignore
UINT payload_suffix_skip; ///! Size of the incoming suffix to ignore
UINT encode_flags; ///! Flags to indicate what kind of encoding to apply, if any.
UINT encode_flags_inbound; ///! Flags to indicate how server->client (response) bodies are encoded.
UINT encode_flags_outbound; ///! Flags to indicate how client->server (request) bodies are encoded.
UINT encode_flags_uuid; ///! Flags to indicate how the UUID is encoded before placement.
STRTYPE uuid_prefix; ///! String to prepend to the (encoded) UUID before placement.
STRTYPE uuid_suffix; ///! String to append to the (encoded) UUID after placement.
STRTYPE uuid_get; ///! The name of the GET/query string parameter to put the UUID in (optional).
STRTYPE uuid_cookie; ///! The name of the cookie to put the UUID in (optional).
STRTYPE uuid_header; ///! The name of the HTTP Header to put the UUID in (optional).
Expand Down
14 changes: 0 additions & 14 deletions c/meterpreter/source/extensions/python/Lib/meterpreter/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,20 +93,6 @@
TLV_TYPE_LIBRARY_PATH = TLV_META_TYPE_STRING | 400
TLV_TYPE_TARGET_PATH = TLV_META_TYPE_STRING | 401

TLV_TYPE_TRANS_TYPE = TLV_META_TYPE_UINT | 430
TLV_TYPE_TRANS_URL = TLV_META_TYPE_STRING | 431
TLV_TYPE_TRANS_UA = TLV_META_TYPE_STRING | 432
TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_META_TYPE_UINT | 433
TLV_TYPE_TRANS_SESSION_EXP = TLV_META_TYPE_UINT | 434
TLV_TYPE_TRANS_CERT_HASH = TLV_META_TYPE_RAW | 435
TLV_TYPE_TRANS_PROXY_HOST = TLV_META_TYPE_STRING | 436
TLV_TYPE_TRANS_PROXY_USER = TLV_META_TYPE_STRING | 437
TLV_TYPE_TRANS_PROXY_PASS = TLV_META_TYPE_STRING | 438
TLV_TYPE_TRANS_RETRY_TOTAL = TLV_META_TYPE_UINT | 439
TLV_TYPE_TRANS_RETRY_WAIT = TLV_META_TYPE_UINT | 440
TLV_TYPE_TRANS_HEADERS = TLV_META_TYPE_STRING | 441
TLV_TYPE_TRANS_GROUP = TLV_META_TYPE_GROUP | 442

TLV_TYPE_MACHINE_ID = TLV_META_TYPE_STRING | 460
TLV_TYPE_UUID = TLV_META_TYPE_RAW | 461

Expand Down
Original file line number Diff line number Diff line change
@@ -1,68 +1,11 @@
import meterpreter_bindings
import datetime

from meterpreter.core import *
from meterpreter.tlv import *
from meterpreter.command import *
# Transport list/add helpers used to rely on TLV_TYPE_TRANS_* TLVs, which
# have been removed. Reimplement on the new C2 TLV shape before exposing
# these functions again.

def list():
resp = invoke_meterpreter(COMMAND_ID_CORE_TRANSPORT_LIST, True)
if resp == None:
return []

if packet_get_tlv(resp, TLV_TYPE_RESULT)['value'] != 0:
return []

transports = []
for transport in packet_enum_tlvs(resp, TLV_TYPE_TRANS_GROUP):
t = transport['value']
transports.append({
'URL': packet_get_tlv(t, TLV_TYPE_TRANS_URL)['value'],
'CommTimeout': packet_get_tlv(t, TLV_TYPE_TRANS_COMM_TIMEOUT)['value'],
'RetryTotal': packet_get_tlv(t, TLV_TYPE_TRANS_RETRY_TOTAL)['value'],
'RetryWait': packet_get_tlv(t, TLV_TYPE_TRANS_RETRY_WAIT)['value'],
'UA': packet_get_tlv_default(t, TLV_TYPE_TRANS_UA, None)['value'],
'ProxyHost': packet_get_tlv_default(t, TLV_TYPE_TRANS_PROXY_HOST, None)['value'],
'ProxyUser': packet_get_tlv_default(t, TLV_TYPE_TRANS_PROXY_USER, None)['value'],
'ProxyPass': packet_get_tlv_default(t, TLV_TYPE_TRANS_PROXY_PASS, None)['value'],
'CertHash': packet_get_tlv_default(t, TLV_TYPE_TRANS_CERT_HASH, None)['value']
})

expiry_secs = packet_get_tlv(resp, TLV_TYPE_TRANS_SESSION_EXP)['value']
expiry = datetime.datetime.now() + datetime.timedelta(seconds=expiry_secs)
return {
'SessionExpiry': expiry,
'Transports': transports
}
raise NotImplementedError("transport.list() pending rewrite onto C2 TLVs")

def add(url, session_expiry=None, comm_timeout=None, retry_total=None,
retry_wait=None, ua=None, proxy_host=None, proxy_user=None,
proxy_pass=None, cert_hash=None):

tlv = tlv_pack(TLV_TYPE_TRANS_URL, url)

if session_expiry:
tlv += tlv_pack(TLV_TYPE_TRANS_SESSION_EXP, session_expiry)
if comm_timeout:
tlv += tlv_pack(TLV_TYPE_TRANS_COMM_TIMEOUT, comm_timeout)
if retry_total:
tlv += tlv_pack(TLV_TYPE_TRANS_RETRY_TOTAL, retry_total)
if retry_wait:
tlv += tlv_pack(TLV_TYPE_TRANS_RETRY_WAIT, retry_wait)
if ua:
tlv += tlv_pack(TLV_TYPE_TRANS_UA, ua)
if proxy_host:
tlv += tlv_pack(TLV_TYPE_TRANS_PROXY_HOST, proxy_host)
if proxy_user:
tlv += tlv_pack(TLV_TYPE_TRANS_PROXY_USER, proxy_user)
if proxy_pass:
tlv += tlv_pack(TLV_TYPE_TRANS_PROXY_PASS, proxy_pass)
if cert_hash:
tlv += tlv_pack(TLV_TYPE_TRANS_CERT_HASH, cert_hash)

resp = invoke_meterpreter(COMMAND_ID_CORE_TRANSPORT_ADD, True, tlv)
if resp == None:
return False

return packet_get_tlv(resp, TLV_TYPE_RESULT)['value'] == 0

raise NotImplementedError("transport.add() pending rewrite onto C2 TLVs")
5 changes: 5 additions & 0 deletions c/meterpreter/source/metsrv/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,11 @@ DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type, Tlv *
return packet_find_tlv_buf(packet, group->buffer, group->header.length, 0, type, entry);
}

DWORD packet_get_tlv_group_entry_n(Packet *packet, Tlv *group, DWORD index, TlvType type, Tlv *entry)
{
return packet_find_tlv_buf(packet, group->buffer, group->header.length, index, type, entry);
}

PCHAR packet_get_tlv_group_entry_value_string(Packet *packet, Tlv *group, TlvType type, DWORD* size)
{
Tlv entry = { 0 };
Expand Down
1 change: 1 addition & 0 deletions c/meterpreter/source/metsrv/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ TlvMetaType packet_get_tlv_meta(Packet *packet, Tlv *tlv);
DWORD packet_get_tlv(Packet *packet, TlvType type, Tlv *tlv);
DWORD packet_get_tlv_string(Packet *packet, TlvType type, Tlv *tlv);
DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type,Tlv *entry);
DWORD packet_get_tlv_group_entry_n(Packet *packet, Tlv *group, DWORD index, TlvType type, Tlv *entry);
DWORD packet_enum_tlv(Packet *packet, DWORD index, TlvType type, Tlv *tlv);
DWORD packet_enum_group_tlv(Packet* packet, Tlv* group, DWORD index, TlvType type, Tlv* tlv);

Expand Down
Loading
Loading