Skip to content

Syscall execution method for fileless ELF execution #19990

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

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

Conversation

msutovsky-r7
Copy link
Contributor

@msutovsky-r7 msutovsky-r7 commented Mar 28, 2025

This PR solves the existing issue with fileless ELF execution option for fetch payloads. In certain conditions (i.e Docker enviroment, gui-less systems or any system with lack of existing anonymous handles) the original approach did not work, when it couldn't find existing anonymous file handle and there was no other option for user. There's PR in progress #19943, which adds Python option for fileless execution. This PR adds Bash alternative. The solution lies within /proc/*/mem file, procfs and memfd_create syscall. The original PoC works in following way:

cd /proc/$$;read a<syscall;exec 3>mem;base64 -d<<<McBIu9GdlpHQjJf/SPfbU1RfmVJXVF6wOw8F|dd bs=1 seek=$[`echo $a|cut -d" " -f9`]>&3

The Poc will first change directory to /proc/ directory for its PID. Then it will read from syscall file and create file handle pointing to mem file. The syscall file will contain an address somewhere into read libc function. The idea is to overwrite that address with payload and achieve shellcode execution. This PoC will successfully spawn /bin/bash shell. This introduces some issues:

  • while spawning shell will work, the process will die as soon as shell exists - same for any other syscall, the process cannot continue as soon as syscalls ends, so any syscall such as memfd_create will not work right away
  • too long shellcode might overwrite some additional functions, which also leads to crash

The current solution works in two steps: first, copy shellcode into vdso section, then write mov rax, [vdso address]; jmp rax into the address from syscall file. This ensures that dd will not overwrite anything important. The shellcode itself will create file handle using memfd_create, call ftruncate and pause syscall to stop the process. This will create anonymous file handle, which can be later used. Next, the bash code will search for that file handle and copy the code as original approach. It should be noted that from shellcode perspective, it might be easier to do more stuff inside shellcode, however, this approach will make it more difficult to use existing structure for final payload delivery. Currently, the curl/wget/.. use parameter $f as destination where payload is saved. Creating anonymous file handle is a approach to keep and use this existing functionality.

Architectures to implement

  • x64
  • x86
  • armle
  • armbe
  • aarch64
  • mips64
  • mipsle
  • mipsbe
  • ppc
  • ppc64

Other tasks:

  • Implement removal of modified bash process

@msutovsky-r7 msutovsky-r7 force-pushed the feat/fetch_fileless_update branch from 885eeac to 62cbb79 Compare April 21, 2025 14:29
@msutovsky-r7 msutovsky-r7 reopened this Apr 21, 2025
@msutovsky-r7 msutovsky-r7 marked this pull request as ready for review April 28, 2025 03:27
@dledda-r7 dledda-r7 self-assigned this May 27, 2025
@dledda-r7 dledda-r7 moved this to Todo in Metasploit Kanban May 27, 2025
@dledda-r7 dledda-r7 added the rn-payload-enhancement release notes for enhanced payloads label May 27, 2025
@dledda-r7
Copy link
Contributor

dledda-r7 commented May 28, 2025

Testing

x64

Options

  • FETCH_FILELESS shell
  • FETCH_PIPE true
msf6 payload(cmd/linux/http/x64/meterpreter/reverse_tcp) >
[*] Sending stage (3045380 bytes) to 172.28.39.226
[*] Meterpreter session 2 opened (172.28.39.226:4444 -> 172.28.39.226:43778) at 2025-05-28 08:07:25 -0400

msf6 payload(cmd/linux/http/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 2...

meterpreter > sysinfo
Computer     : 172.28.39.226
OS           : Debian  (Linux 6.12.25-amd64)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
meterpreter > getuid
Server username: kali
meterpreter > ps

NOTE

SO, using the fileless works good however due to the technique we are using, when we start our Meterpreter session we will get an error because the file results deleted:

meterpreter > ls
[-] stdapi_fs_getwd: Operation failed: 2
meterpreter >

This problem is fixed by changing directory to something else.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement payload rn-payload-enhancement release notes for enhanced payloads
Projects
Status: Todo
Development

Successfully merging this pull request may close these issues.

2 participants