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

[WIP] Fix Linux Stageless Payload to be Shellcodes #19799

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from

Conversation

dledda-r7
Copy link
Contributor

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

This is a draft pr to fix the big issue we have with Linux stageless payload.
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

Write a loader based on this: in-memory-elf-execution.

If we don't want to lose any compatibility we currently have, however, we should keep the standard elf generation of elf payload (what we have doing generate -f elf -o mettle.elf or with msfvenom) for all the architecture we are not sure we can implement these changes (osx, apple_ios, linux/powerpc, linux/armbe, linux/zarch, linux/mips64)

Tasks

  • linux/x86
  • linux/x64
  • linux/armle
  • linux/armbe
  • linux/aarch64
  • linux/mips
  • linux/mipsel

Missing template format for:

@msutovsky-r7 msutovsky-r7 self-assigned this Jan 14, 2025
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.

2 participants