Skip to content

Stageless Mettle with Malleable C2 profile support#294

Open
OJ wants to merge 8 commits into
rapid7:masterfrom
OJ:feature/mc2-all
Open

Stageless Mettle with Malleable C2 profile support#294
OJ wants to merge 8 commits into
rapid7:masterfrom
OJ:feature/mc2-all

Conversation

@OJ
Copy link
Copy Markdown
Contributor

@OJ OJ commented May 20, 2026

This PR modifies Mettle so that it supports the following:

  • The new TLV-based configuration block.
  • Stageless payloads, which for Mettle isn't super helpful yet.
  • Transport commands.
  • Malleable C2 support.

This code relies on the changes that are part of the Metasploit Framework PR. Discussion and more details can be found over there.

I'm PR'ing against main, but should probably be part of the 6.5 release.

OJ added 8 commits March 25, 2026 08:48
Replace the CLI-argument-only configuration path with a TLV config
block that the framework patches into the binary at generation time.
This brings mettle in line with the Windows, Python, Java, and PHP
Meterpreter implementations that all use Rex::Payloads::Meterpreter::Config.

- Add C2 TLV constants (700-725 series) to tlv_types.h
- Add 8KB CONFIG_BLOCK placeholder in main.c with signature-based
  patching, checked before CLI args and injection detection at startup
- Add tlv_packet_from_raw() to tlv.c for wrapping GROUP TLV children
- Parse UUID, session GUID, session expiry, debug log, and C2
  transport groups from the config packet
- Add c2_transport_config and c2_verb_config structs to c2.h
- Add c2_add_transport_uri_config() to attach parsed config to
  transports
- Parse C2 GET/POST profile sub-groups including URI, encoding flags,
  prefix/suffix, prefix/suffix skip, and UUID placement options
- Implement profile-aware HTTP transport: per-verb URL building,
  Base64/Base64URL encode/decode, prefix/suffix wrapping on egress,
  prefix/suffix stripping and decoding on ingress, UUID in query
  param/header/cookie
- Apply TLV transport config (UA, custom headers) during HTTP
  transport init alongside legacy pipe-separated URI args
- Update mettle.rb to patch CONFIG_BLOCK into binaries
- Fix json-c calloc argument order for modern GCC

The legacy DEFAULT_OPTS CLI path is preserved as a fallback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant