add ability to use arbitrary certs with SSL server sockets.
git-svn-id: file:///home/svn/framework3/trunk@12675 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
9003622af3
commit
d1e2f274f9
|
@ -31,7 +31,8 @@ module Exploit::Remote::HttpServer
|
|||
OptBool.new('HTTP::header_folding', [false, 'Enable folding of HTTP headers', 'false']),
|
||||
OptBool.new('HTTP::junk_headers', [false, 'Enable insertion of random junk HTTP headers', 'false']),
|
||||
OptEnum.new('HTTP::compression', [false, 'Enable compression of HTTP responses via content encoding', 'none', ['none','gzip','deflate']]),
|
||||
], Exploit::Remote::HttpServer)
|
||||
], Exploit::Remote::HttpServer
|
||||
)
|
||||
|
||||
@service_path = nil
|
||||
end
|
||||
|
@ -73,8 +74,8 @@ module Exploit::Remote::HttpServer
|
|||
# Uri => The URI to handle and the associated procedure to call.
|
||||
#
|
||||
def start_service(opts = {})
|
||||
check_dependencies
|
||||
|
||||
check_dependencies
|
||||
|
||||
comm = datastore['ListenerComm']
|
||||
if (comm.to_s == "local")
|
||||
|
@ -100,7 +101,8 @@ module Exploit::Remote::HttpServer
|
|||
'Msf' => framework,
|
||||
'MsfExploit' => self,
|
||||
},
|
||||
opts['Comm']
|
||||
opts['Comm'],
|
||||
datastore['SSLCert']
|
||||
)
|
||||
|
||||
self.service.server_name = 'Apache'
|
||||
|
@ -422,7 +424,7 @@ module Exploit::Remote::HttpServer
|
|||
#
|
||||
def send_not_found(cli)
|
||||
resp_404 = create_response(404, 'Not Found')
|
||||
resp_404.body = %Q{
|
||||
resp_404.body = %Q{\
|
||||
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
|
||||
<html><head>
|
||||
<title>404 Not Found</title>
|
||||
|
|
|
@ -286,6 +286,7 @@ module Exploit::Remote::TcpServer
|
|||
[
|
||||
OptBool.new('SSL', [ false, 'Negotiate SSL for incoming connections', false]),
|
||||
OptEnum.new('SSLVersion', [ false, 'Specify the version of SSL that should be used', 'SSL3', ['SSL2', 'SSL3', 'TLS1']]),
|
||||
OptPath.new('SSLCert', [ false, 'Path to a custom SSL certificate (default is randomly generated)']),
|
||||
OptAddress.new('SRVHOST', [ true, "The local host to listen on. This must be an address on the local machine or 0.0.0.0", '0.0.0.0' ]),
|
||||
OptPort.new('SRVPORT', [ true, "The local port to listen on.", 8080 ]),
|
||||
|
||||
|
@ -372,6 +373,7 @@ module Exploit::Remote::TcpServer
|
|||
'LocalHost' => srvhost,
|
||||
'LocalPort' => srvport,
|
||||
'SSL' => ssl,
|
||||
'SSLCert' => ssl_cert,
|
||||
'Comm' => comm,
|
||||
'Context' =>
|
||||
{
|
||||
|
@ -450,6 +452,12 @@ module Exploit::Remote::TcpServer
|
|||
datastore['SSL']
|
||||
end
|
||||
|
||||
#
|
||||
# Returns the SSLCert option
|
||||
#
|
||||
def ssl_cert
|
||||
datastore['SSLCert']
|
||||
end
|
||||
|
||||
#
|
||||
# Re-generates the payload, substituting the current RHOST and RPORT with
|
||||
|
|
|
@ -163,7 +163,7 @@ module ReverseTcp
|
|||
begin
|
||||
handle_connection(client)
|
||||
rescue ::Exception
|
||||
elog("Exception raised from handle_connection: #{$!}\n\n#{$@.join("\n")}")
|
||||
elog("Exception raised from handle_connection: #{$!.class}: #{$!}\n\n#{$@.join("\n")}")
|
||||
end
|
||||
end
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ class Handler::Proc < Handler
|
|||
rescue Errno::EPIPE
|
||||
elog("Proc::on_request: Client closed connection prematurely", LogSource)
|
||||
rescue
|
||||
elog("Proc::on_request: #{$!}\n\n#{$@.join("\n")}", LogSource)
|
||||
elog("Proc::on_request: #{$!.class}: #{$!}\n\n#{$@.join("\n")}", LogSource)
|
||||
if self.server and self.server.context
|
||||
exploit = self.server.context['MsfExploit']
|
||||
if exploit
|
||||
|
|
|
@ -99,15 +99,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)
|
||||
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
|
||||
self.ssl = ssl
|
||||
self.comm = comm
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -134,6 +136,7 @@ class Server
|
|||
'LocalPort' => self.listen_port,
|
||||
'Context' => self.context,
|
||||
'SSL' => self.ssl,
|
||||
'SSLCert' => self.ssl_cert,
|
||||
'Comm' => self.comm
|
||||
)
|
||||
|
||||
|
@ -256,7 +259,7 @@ class Server
|
|||
cli.send_response(resp)
|
||||
end
|
||||
|
||||
attr_accessor :listen_port, :listen_host, :server_name, :context, :ssl, :comm
|
||||
attr_accessor :listen_port, :listen_host, :server_name, :context, :ssl, :comm, :ssl_cert
|
||||
attr_accessor :listener, :resources
|
||||
|
||||
protected
|
||||
|
|
|
@ -63,6 +63,10 @@ class Rex::Socket::Parameters
|
|||
#
|
||||
# Specify SSL2, SSL3, or TLS1 (SSL3 is default)
|
||||
#
|
||||
# SSLCert
|
||||
#
|
||||
# A file containing an SSL certificate (for server sockets)
|
||||
#
|
||||
# Proxies
|
||||
#
|
||||
# List of proxies to use.
|
||||
|
@ -139,6 +143,14 @@ class Rex::Socket::Parameters
|
|||
self.ssl_version = hash['SSLVersion']
|
||||
end
|
||||
|
||||
if (hash['SSLCert'] and ::File.file?(hash['SSLCert']))
|
||||
begin
|
||||
self.ssl_cert = ::File.read(hash['SSLCert'])
|
||||
rescue ::Exception => e
|
||||
elog("Failed to read cert: #{e.class}: #{e}", LogSource)
|
||||
end
|
||||
end
|
||||
|
||||
if hash['Proxies']
|
||||
self.proxies = hash['Proxies'].split('-').map{|a| a.strip}.map{|a| a.split(':').map{|b| b.strip}}
|
||||
end
|
||||
|
@ -325,6 +337,10 @@ class Rex::Socket::Parameters
|
|||
#
|
||||
attr_accessor :ssl_version
|
||||
#
|
||||
# The SSL certificate, in pem format, stored as a string. See +SslTcpServer#make_ssl+
|
||||
#
|
||||
attr_accessor :ssl_cert
|
||||
#
|
||||
# Whether we should use IPv6
|
||||
#
|
||||
attr_accessor :v6
|
||||
|
|
|
@ -47,7 +47,7 @@ module Rex::Socket::SslTcpServer
|
|||
|
||||
def initsock(params = nil)
|
||||
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
||||
self.sslctx = makessl()
|
||||
self.sslctx = makessl(params.ssl_cert)
|
||||
super
|
||||
end
|
||||
|
||||
|
@ -99,43 +99,52 @@ module Rex::Socket::SslTcpServer
|
|||
end
|
||||
|
||||
|
||||
def makessl
|
||||
key = OpenSSL::PKey::RSA.new(1024){ }
|
||||
#
|
||||
# Create a new ssl context. If +ssl_cert+ is not given, generates a new
|
||||
# key and a leaf certificate with random values.
|
||||
#
|
||||
def makessl(ssl_cert=nil)
|
||||
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.version = 2
|
||||
cert.serial = rand(0xFFFFFFFF)
|
||||
# name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]])
|
||||
subject = OpenSSL::X509::Name.new([
|
||||
["C","US"],
|
||||
['ST', Rex::Text.rand_state()],
|
||||
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["CN", Rex::Text.rand_hostname],
|
||||
])
|
||||
issuer = OpenSSL::X509::Name.new([
|
||||
["C","US"],
|
||||
['ST', Rex::Text.rand_state()],
|
||||
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["CN", Rex::Text.rand_hostname],
|
||||
])
|
||||
if ssl_cert
|
||||
cert = OpenSSL::X509::Certificate.new(ssl_cert)
|
||||
key = OpenSSL::PKey::RSA.new(ssl_cert)
|
||||
else
|
||||
key = OpenSSL::PKey::RSA.new(1024){ }
|
||||
cert = OpenSSL::X509::Certificate.new
|
||||
cert.version = 2
|
||||
cert.serial = rand(0xFFFFFFFF)
|
||||
# name = OpenSSL::X509::Name.new([["C","JP"],["O","TEST"],["CN","localhost"]])
|
||||
subject = OpenSSL::X509::Name.new([
|
||||
["C","US"],
|
||||
['ST', Rex::Text.rand_state()],
|
||||
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["CN", Rex::Text.rand_hostname],
|
||||
])
|
||||
issuer = OpenSSL::X509::Name.new([
|
||||
["C","US"],
|
||||
['ST', Rex::Text.rand_state()],
|
||||
["L", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["O", Rex::Text.rand_text_alpha(rand(20) + 10)],
|
||||
["CN", Rex::Text.rand_hostname],
|
||||
])
|
||||
|
||||
cert.subject = subject
|
||||
cert.issuer = issuer
|
||||
cert.not_before = Time.now - (3600 * 365)
|
||||
cert.not_after = Time.now + (3600 * 365)
|
||||
cert.public_key = key.public_key
|
||||
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
||||
cert.extensions = [
|
||||
ef.create_extension("basicConstraints","CA:FALSE"),
|
||||
ef.create_extension("subjectKeyIdentifier","hash"),
|
||||
ef.create_extension("extendedKeyUsage","serverAuth"),
|
||||
ef.create_extension("keyUsage","keyEncipherment,dataEncipherment,digitalSignature")
|
||||
]
|
||||
ef.issuer_certificate = cert
|
||||
cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
|
||||
cert.sign(key, OpenSSL::Digest::SHA1.new)
|
||||
cert.subject = subject
|
||||
cert.issuer = issuer
|
||||
cert.not_before = Time.now - (3600 * 365)
|
||||
cert.not_after = Time.now + (3600 * 365)
|
||||
cert.public_key = key.public_key
|
||||
ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
|
||||
cert.extensions = [
|
||||
ef.create_extension("basicConstraints","CA:FALSE"),
|
||||
ef.create_extension("subjectKeyIdentifier","hash"),
|
||||
ef.create_extension("extendedKeyUsage","serverAuth"),
|
||||
ef.create_extension("keyUsage","keyEncipherment,dataEncipherment,digitalSignature")
|
||||
]
|
||||
ef.issuer_certificate = cert
|
||||
cert.add_extension ef.create_extension("authorityKeyIdentifier", "keyid:always,issuer:always")
|
||||
cert.sign(key, OpenSSL::Digest::SHA1.new)
|
||||
end
|
||||
|
||||
ctx = OpenSSL::SSL::SSLContext.new()
|
||||
ctx.key = key
|
||||
|
|
Loading…
Reference in New Issue