Skip to content

Adds migrate command for Linux x64/x86 - #287

Open
msutovsky-r7 wants to merge 19 commits into
rapid7:masterfrom
msutovsky-r7:feat/linux/migrate
Open

msutovsky-r7 wants to merge 19 commits into
rapid7:masterfrom
msutovsky-r7:feat/linux/migrate

Conversation

@msutovsky-r7

@msutovsky-r7 msutovsky-r7 commented Oct 23, 2025 •

Copy link
Copy Markdown
Contributor

This adds support for migrate command on Mettle side for Linux x64/x86. This PR only adds support for Mettle to inject migrate stub and execute payload, session handling needs to be taken care in Framework. Currently, the migrate needs privilege to use ptrace syscall.

@dledda-r7 dledda-r7 self-assigned this Nov 6, 2025
Comment thread mettle/src/base_inject.c Resolved
@msutovsky-r7 msutovsky-r7 changed the title [WIP] Migrate command for Linux meterpreter Migrate command for Linux meterpreter Feb 23, 2026
@msutovsky-r7 msutovsky-r7 changed the title Migrate command for Linux meterpreter Adds migrate command for Linux x64/x86 Feb 23, 2026
@msutovsky-r7
msutovsky-r7 marked this pull request as ready for review February 23, 2026 16:34
@msutovsky-r7
msutovsky-r7 requested a review from Copilot March 27, 2026 10:26

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Linux x64/x86 support for the migrate command in mettle by introducing a ptrace-based injector and exposing transport/socket details needed to stage the new session.

Changes:

  • Adds new TLV fields and core TLV handlers for core_migrate and core_transport_list.
  • Introduces a new ptrace-based injection implementation (base_inject.*) and wires it into the build.
  • Adds APIs to retrieve the underlying socket FD from the active C2 transport.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 17 comments.

Show a summary per file
File Description
mettle/src/tlv_types.h Adds migrate-related TLVs and adjusts transport-group TLV ID.
mettle/src/network_client.h Exposes network_client accessors for bufferev and socket FD.
mettle/src/network_client.c Implements the new network_client accessor functions.
mettle/src/coreapi.c Adds core_migrate and core_transport_list handlers and registers them.
mettle/src/c2_tcp.c Adds c2_transport_get_socket_fd() implementation (currently TCP-specific).
mettle/src/c2.h Exposes c2_get_next_transport() and c2_transport_get_socket_fd() prototypes.
mettle/src/c2.c Implements c2_get_next_transport() (and introduces an extra c2_get_fd stub).
mettle/src/bufferev.h Adds bufferev_get_socket_fd() declaration.
mettle/src/bufferev.c Implements bufferev_get_socket_fd().
mettle/src/base_inject.h Introduces injector header/API for migrate support.
mettle/src/base_inject.c Adds ptrace-based injector implementation for Linux migrate.
mettle/src/Makefile.am Adds base_inject.c to libmettle sources.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread mettle/src/c2.c Resolved
Comment thread mettle/src/base_inject.c Resolved
Comment thread mettle/src/base_inject.c Resolved
Comment thread mettle/src/base_inject.c Resolved
Comment thread mettle/src/base_inject.h Resolved
Comment thread mettle/src/coreapi.c Resolved
Comment thread mettle/src/c2.c Resolved
Comment thread mettle/src/base_inject.c Resolved
Comment thread mettle/src/coreapi.c
struct c2_transport * transport = c2_get_current_transport(c2);
int fd = c2_transport_get_socket_fd(transport);

if(migrate(pid, migrate_stub, stub_length, payload, payload_length, uuid, fd))

Copilot AI Mar 27, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

c2_transport_get_socket_fd() is assumed to work for the current transport, but mettle supports non-TCP transports (e.g. http/https). The current implementation of c2_transport_get_socket_fd() casts the transport ctx to tcp_ctx, which will be invalid for HTTP and can crash or leak memory. Either (a) move this API behind transport callbacks so each transport type can implement it safely, or (b) explicitly restrict migrate to fd/tcp transports and fail cleanly for others; also handle fd == -1 before calling migrate().

Suggested change
if(migrate(pid, migrate_stub, stub_length, payload, payload_length, uuid, fd))
/* Only attempt migration when we have a valid transport file descriptor. */
if (fd >= 0 && migrate(pid, migrate_stub, stub_length, payload, payload_length, uuid, fd))

Copilot uses AI. Check for mistakes.
Comment thread mettle/src/c2_tcp.c Resolved
Comment thread mettle/src/coreapi.c Resolved
Comment thread mettle/src/tlv_types.h Resolved
Comment thread mettle/src/base_inject.c Resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants