Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Linux Stageless Payload to be Shellcodes #19799

Open
wants to merge 28 commits into
base: master
Choose a base branch
from

Conversation

dledda-r7
Copy link
Contributor

@dledda-r7 dledda-r7 commented Jan 10, 2025

This PR Fixes the issue of linux stageless meterpreter.
Issue: #19670

Issue Description

The stageless linux meterpreters are ELF files that cannot be used as standard stageless shellcode payload.

Staged vs Stageless Linux Meterpreter

Staged

The Linux staged meterpreter is divided in 3 component

  • A stager (connect back to msf to download the next stage)
  • an intermediate stager that download the ELF on a RWX mmap, setup the stack and and jump on the e_entry of the ELF
  • the Process Hollowing Friendly version of mettle's ELF

This version of the ELF is generated when we build mettle using the following tool: elf2bin

Stageless

The stageless mettle payload is the ELF file (standard elf) with the patched args.

Code Handling Staged vs Stageless

Mettle main.c

	/*
	 * Check to see if we were injected by metasploit | staged
	 */
	if (strcmp(argv[0], "m") == 0) {
		flags |= PAYLOAD_INJECTED;

		/*
		 * There is a fd sitting here, trust me
		 */
		int fd = (int)((long *)argv)[1];
		char *uri;
		if (asprintf(&uri, "fd://%d", fd) > 0) {
			struct c2 *c2 = mettle_get_c2(m);
			c2_add_transport_uri(c2, uri);
			free(uri);
		}
		parse_default_args(m, flags);
	} else {

#ifndef HAVE_SETPROCTITLE
		/* Prepare for later setproctitle emulation */
		saved_argv = calloc(argc + 1, sizeof(*saved_argv));
		for (int i = 0; i < argc; i++) {
			saved_argv[i] = strdup(argv[i]);
		}
		compat_init_setproctitle(argc, argv);
		argv = saved_argv;
#endif

		parse_default_args(m, flags);    // <- MSFVENOM REPLACE THE DEFAULT OPTION PARSED HERE
		if (parse_cmdline(argc, argv, m, flags)) {
			return -1;
		}
	}

Solution

For each architecture, a shellcode implementing this technique was made.
NOTE: This technique works only with Kernel >= 3.17

Instead of delivering the ELF only, the raw shellcode will be composed by the in-memory-loader arch specific shellcode and the elf file at the end of it.

Super thanks to @msutovsky-r7

What architectures fix this pr:

  • linux/x86
  • linux/x64
  • linux/armle
  • linux/armbe
  • linux/aarch64
  • linux/mips
  • linux/mipsel
  • linux/mips64
  • linux/ppc
  • linux/ppc64le
  • linux/ppce500v2
  • linux/zarch

Sorry, something went wrong.

@msutovsky-r7 msutovsky-r7 self-assigned this Jan 14, 2025
@dledda-r7 dledda-r7 force-pushed the fix/mettle-stageless-payload branch from b3f3b8c to 128ac84 Compare February 10, 2025 08:11
@smcintyre-r7 smcintyre-r7 added enhancement rn-payload-enhancement release notes for enhanced payloads labels Feb 14, 2025
@dledda-r7 dledda-r7 marked this pull request as ready for review February 14, 2025 11:36
@dledda-r7 dledda-r7 changed the title [WIP] Fix Linux Stageless Payload to be Shellcodes Fix Linux Stageless Payload to be Shellcodes Feb 14, 2025
@msutovsky-r7 msutovsky-r7 removed their assignment Feb 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement rn-payload-enhancement release notes for enhanced payloads
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants