Skip to content

Commit 1869977

Browse files
author
Brent Cook
committed
Land rapid7#4962: OJ adjusts MSF to new metsrv needs
bump meterpreter bins to 0.0.17
2 parents 809bc52 + afe17e1 commit 1869977

File tree

13 files changed

+173
-110
lines changed

13 files changed

+173
-110
lines changed

.gitignore

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,7 @@ external/source/exploits/**/Release
6767

6868
# Avoid checking in Meterpreter binaries. These are supplied upstream by
6969
# the meterpreter_bins gem.
70-
data/meterpreter/elevator.*.dll
71-
data/meterpreter/ext_server_espia.*.dll
72-
data/meterpreter/ext_server_extapi.*.dll
73-
data/meterpreter/ext_server_incognito.*.dll
74-
data/meterpreter/ext_server_kiwi.*.dll
75-
data/meterpreter/ext_server_lanattacks.*.dll
76-
data/meterpreter/ext_server_mimikatz.*.dll
77-
data/meterpreter/ext_server_priv.*.dll
78-
data/meterpreter/ext_server_stdapi.*.dll
79-
data/meterpreter/metsrv.*.dll
80-
data/meterpreter/screenshot.*.dll
70+
data/meterpreter/*.dll
8171

8272
# Avoid checking in Meterpreter libs that are built from
8373
# private source. If you're interested in this functionality,

Gemfile.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ PATH
99
json
1010
metasploit-concern (~> 0.3.0)
1111
metasploit-model (~> 0.29.0)
12-
meterpreter_bins (= 0.0.16)
12+
meterpreter_bins (= 0.0.17)
1313
msgpack
1414
nokogiri
1515
packetfu (= 1.1.9)
@@ -132,7 +132,7 @@ GEM
132132
pg
133133
railties (< 4.0.0)
134134
recog (~> 1.0)
135-
meterpreter_bins (0.0.16)
135+
meterpreter_bins (0.0.17)
136136
method_source (0.8.2)
137137
mime-types (1.25.1)
138138
mini_portile (0.6.1)

lib/msf/core/handler/reverse_http.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
require 'rex/sync/ref'
44
require 'msf/core/handler/reverse_http/uri_checksum'
55
require 'rex/payloads/meterpreter/patch'
6+
require 'rex/parser/x509_certificate'
7+
require 'msf/core/payload/windows/verify_ssl'
68

79
module Msf
810
module Handler
@@ -16,6 +18,7 @@ module ReverseHttp
1618

1719
include Msf::Handler
1820
include Msf::Handler::ReverseHttp::UriChecksum
21+
include Msf::Payload::Windows::VerifySsl
1922

2023
#
2124
# Returns the string representation of the handler type
@@ -291,20 +294,23 @@ def on_request(cli, req, obj)
291294

292295
blob = obj.stage_payload
293296

297+
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
298+
datastore['HandlerSSLCert'])
294299
#
295300
# Patch options into the payload
296301
#
297-
Rex::Payloads::Meterpreter::Patch.patch_passive_service! blob,
302+
Rex::Payloads::Meterpreter::Patch.patch_passive_service!(blob,
298303
:ssl => ssl?,
299304
:url => url,
305+
:ssl_cert_hash => verify_cert_hash,
300306
:expiration => datastore['SessionExpirationTimeout'],
301307
:comm_timeout => datastore['SessionCommunicationTimeout'],
302308
:ua => datastore['MeterpreterUserAgent'],
303309
:proxy_host => datastore['PayloadProxyHost'],
304310
:proxy_port => datastore['PayloadProxyPort'],
305311
:proxy_type => datastore['PayloadProxyType'],
306312
:proxy_user => datastore['PayloadProxyUser'],
307-
:proxy_pass => datastore['PayloadProxyPass']
313+
:proxy_pass => datastore['PayloadProxyPass'])
308314

309315
resp.body = encode_stage(blob)
310316

lib/msf/core/handler/reverse_https.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ def initialize(info = {})
4343

4444
register_advanced_options(
4545
[
46-
OptPath.new('HandlerSSLCert', [false, "Path to a SSL certificate in unified PEM format"])
46+
OptPath.new('HandlerSSLCert', [false, "Path to a SSL certificate in unified PEM format"]),
47+
OptBool.new('StagerVerifySSLCert', [false, "Whether to verify the SSL certificate in Meterpreter"])
4748
], Msf::Handler::ReverseHttps)
4849

4950
end

lib/msf/core/payload/windows/reverse_winhttp.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,7 @@ def asm_generate_wchar_array(str)
108108
# @option opts [String] :url The URI to request during staging
109109
# @option opts [String] :host The host to connect to
110110
# @option opts [Fixnum] :port The port to connect to
111-
# @option opts [Bool] :verify_ssl Whether or not to do SSL certificate validation
112-
# @option opts [String] :verify_cert_hash A 20-byte raw SHA-1 hash of the certificate to verify
111+
# @option opts [String] :verify_cert_hash A 20-byte raw SHA-1 hash of the certificate to verify, or nil
113112
# @option opts [String] :exitfunk The exit method to use if there is an error, one of process, thread, or seh
114113
# @option opts [Fixnum] :retry_count The number of times to retry a failed request before giving up
115114
#
@@ -121,7 +120,7 @@ def asm_reverse_winhttp(opts={})
121120
encoded_url = asm_generate_wchar_array(opts[:url])
122121
encoded_host = asm_generate_wchar_array(opts[:host])
123122

124-
if opts[:ssl] && opts[:verify_cert] && opts[:verify_cert_hash]
123+
if opts[:ssl] && opts[:verify_cert_hash]
125124
verify_ssl = true
126125
encoded_cert_hash = opts[:verify_cert_hash].unpack("C*").map{|c| "0x%.2x" % c }.join(",")
127126
end

lib/msf/core/payload/windows/reverse_winhttps.rb

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
require 'msf/core'
44
require 'msf/core/payload/windows/reverse_winhttp'
5-
require 'rex/parser/x509_certificate'
5+
require 'msf/core/payload/windows/verify_ssl'
66

77
module Msf
88

@@ -17,6 +17,7 @@ module Msf
1717
module Payload::Windows::ReverseWinHttps
1818

1919
include Msf::Payload::Windows::ReverseWinHttp
20+
include Msf::Payload::Windows::VerifySsl
2021

2122
#
2223
# Register reverse_winhttps specific options
@@ -49,27 +50,13 @@ def generate_reverse_winhttps(opts={})
4950
#
5051
def generate
5152

52-
verify_cert = false
53-
verify_cert_hash = nil
54-
55-
if datastore['StagerVerifySSLCert'].to_s =~ /^(t|y|1)/i
56-
unless datastore['HandlerSSLCert']
57-
raise ArgumentError, "StagerVerifySSLCert is enabled but no HandlerSSLCert is configured"
58-
else
59-
verify_cert = true
60-
hcert = Rex::Parser::X509Certificate.parse_pem_file(datastore['HandlerSSLCert'])
61-
unless hcert and hcert[0] and hcert[1]
62-
raise ArgumentError, "Could not parse a private key and certificate from #{datastore['HandlerSSLCert']}"
63-
end
64-
verify_cert_hash = Rex::Text.sha1_raw(hcert[1].to_der)
65-
print_status("Stager will verify SSL Certificate with SHA1 hash #{verify_cert_hash.unpack("H*").first}")
66-
end
67-
end
53+
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
54+
datastore['HandlerSSLCert'])
6855

6956
# Generate the simple version of this stager if we don't have enough space
7057
if self.available_space.nil? || required_space > self.available_space
7158

72-
if datastore['StagerVerifySSLCert'].to_s =~ /^(t|y|1)/i
59+
if verify_cert_hash
7360
raise ArgumentError, "StagerVerifySSLCert is enabled but not enough payload space is available"
7461
end
7562

@@ -78,7 +65,6 @@ def generate
7865
host: datastore['LHOST'],
7966
port: datastore['LPORT'],
8067
url: generate_small_uri,
81-
verify_cert: verify_cert,
8268
verify_cert_hash: verify_cert_hash,
8369
retry_count: datastore['StagerRetryCount'])
8470
end
@@ -89,7 +75,6 @@ def generate
8975
port: datastore['LPORT'],
9076
url: generate_uri,
9177
exitfunk: datastore['EXITFUNC'],
92-
verify_cert: verify_cert,
9378
verify_cert_hash: verify_cert_hash,
9479
retry_count: datastore['StagerRetryCount']
9580
}

lib/msf/core/payload/windows/stageless_meterpreter.rb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#-*- coding: binary -*-
22

33
require 'msf/core'
4+
require 'rex/payloads/meterpreter/patch'
45

56
module Msf
67

@@ -75,11 +76,8 @@ def generate_stageless_meterpreter(url = nil)
7576

7677
# the URL might not be given, as it might be patched in some other way
7778
if url
78-
url = "s#{url}\x00"
79-
location = dll.index("https://#{'X' * 256}")
80-
if location
81-
dll[location, url.length] = url
82-
end
79+
# Patch the URL using the patcher as this upports both ASCII and WCHAR.
80+
Rex::Payloads::Meterpreter::Patch.patch_string!(dll, "https://#{'X' * 512}", "s#{url}\x00")
8381
end
8482

8583
# if a block is given then call that with the meterpreter dll
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# -*- coding: binary -*-
2+
3+
require 'msf/core'
4+
require 'rex/parser/x509_certificate'
5+
6+
module Msf
7+
8+
###
9+
#
10+
# Implements SSL validation check options
11+
#
12+
###
13+
14+
module Payload::Windows::VerifySsl
15+
16+
#
17+
# Get the SSL hash from the certificate, if required.
18+
#
19+
def get_ssl_cert_hash(verify_cert, handler_cert)
20+
unless verify_cert.to_s =~ /^(t|y|1)/i
21+
return nil
22+
end
23+
24+
unless handler_cert
25+
raise ArgumentError, "Verifying SSL cert is enabled but no handler cert is configured"
26+
end
27+
28+
hash = Rex::Parser::X509Certificate.get_cert_file_hash(handler_cert)
29+
print_status("Meterpreter will verify SSL Certificate with SHA1 hash #{hash.unpack("H*").first}")
30+
hash
31+
end
32+
33+
end
34+
35+
end
36+

lib/rex/parser/x509_certificate.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,36 @@ def self.parse_pem_file(ssl_cert_file)
5656
parse_pem(data)
5757
end
5858

59+
#
60+
# Parse a certificate in unified PEM format and retrieve
61+
# the SHA1 hash.
62+
#
63+
# @param [String] ssl_cert
64+
# @return [String]
65+
def self.get_cert_hash(ssl_cert)
66+
hcert = parse_pem(ssl_cert)
67+
68+
unless hcert and hcert[0] and hcert[1]
69+
raise ArgumentError, "Could not parse a private key and certificate"
70+
end
71+
72+
Rex::Text.sha1_raw(hcert[1].to_der)
73+
end
74+
75+
#
76+
# Parse a file that contains a certificate in unified PEM
77+
# format and retrieve the SHA1 hash.
78+
#
79+
# @param [String] ssl_cert_file
80+
# @return [String]
81+
def self.get_cert_file_hash(ssl_cert_file)
82+
data = ''
83+
::File.open(ssl_cert_file, 'rb') do |fd|
84+
data << fd.read(fd.stat.size)
85+
end
86+
get_cert_hash(data)
87+
end
88+
5989
end
6090

6191
end

0 commit comments

Comments
 (0)