Skip to content

Commit 1762966

Browse files
author
HD Moore
committed
Fix heartbleed cert parsing, lands rapid7#4338, closes rapid7#4309
2 parents ec53498 + 9165033 commit 1762966

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

modules/auxiliary/scanner/ssl/openssl_heartbleed.rb

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -339,15 +339,15 @@ def jabber_connect_msg(hostname)
339339

340340
def tls_jabber
341341
sock.put(jabber_connect_msg(xmpp_domain))
342-
res = sock.get_once(-1, response_timeout)
342+
res = get_data
343343
if res && res.include?('host-unknown')
344344
jabber_host = res.match(/ from='([\w.]*)' /)
345345
if jabber_host && jabber_host[1]
346346
disconnect
347347
establish_connect
348348
vprint_status("#{peer} - Connecting with autodetected remote XMPP hostname: #{jabber_host[1]}...")
349349
sock.put(jabber_connect_msg(jabber_host[1]))
350-
res = sock.get_once(-1, response_timeout)
350+
res = get_data
351351
end
352352
end
353353
if res.nil? || res.include?('stream:error') || res !~ /<starttls xmlns=['"]urn:ietf:params:xml:ns:xmpp-tls['"]/
@@ -356,14 +356,14 @@ def tls_jabber
356356
end
357357
msg = "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>"
358358
sock.put(msg)
359-
res = sock.get_once(-1, response_timeout)
359+
res = get_data
360360
return nil if res.nil? || !res.include?('<proceed')
361361
res
362362
end
363363

364364
def tls_ftp
365365
# http://tools.ietf.org/html/rfc4217
366-
res = sock.get_once(-1, response_timeout)
366+
res = get_data
367367
return nil if res.nil?
368368
sock.put("AUTH TLS\r\n")
369369
res = get_data
@@ -383,18 +383,25 @@ def tls_ftp
383383
# Get data from the socket
384384
# this ensures the requested length is read (if available)
385385
def get_data(length = -1)
386-
387-
return sock.get_once(-1, response_timeout) if length == -1
388-
389386
to_receive = length
390387
data = ''
391-
while to_receive > 0
392-
temp = sock.get_once(to_receive, response_timeout)
388+
done = false
389+
while done == false
390+
begin
391+
temp = sock.get_once(to_receive, response_timeout)
392+
rescue EOFError
393+
break
394+
end
395+
393396
break if temp.nil?
394397

395398
data << temp
396-
to_receive -= temp.length
399+
if length != -1
400+
to_receive -= temp.length
401+
done = true if to_receive <= 0
402+
end
397403
end
404+
398405
data
399406
end
400407

@@ -417,8 +424,7 @@ def establish_connect
417424

418425
vprint_status("#{peer} - Sending Client Hello...")
419426
sock.put(client_hello)
420-
421-
server_hello = sock.get_once(-1, response_timeout)
427+
server_hello = get_data
422428
unless server_hello
423429
vprint_error("#{peer} - No Server Hello after #{response_timeout} seconds...")
424430
return nil
@@ -777,19 +783,19 @@ def parse_certificate_data(data)
777783
cert_len_padding = unpacked[0]
778784
cert_len = unpacked[1]
779785
vprint_debug("\t\tCertificates length: #{cert_len}")
786+
vprint_debug("\t\tData length: #{data.length}")
780787
# contains multiple certs
781788
already_read = 3
782789
cert_counter = 0
783790
while already_read < cert_len
784-
start = already_read
785791
cert_counter += 1
786792
# get single certificate length
787-
single_cert_unpacked = data[start, 3].unpack('Cn')
793+
single_cert_unpacked = data[already_read, 3].unpack('Cn')
788794
single_cert_len_padding = single_cert_unpacked[0]
789795
single_cert_len = single_cert_unpacked[1]
790796
vprint_debug("\t\tCertificate ##{cert_counter}:")
791797
vprint_debug("\t\t\tCertificate ##{cert_counter}: Length: #{single_cert_len}")
792-
certificate_data = data[(start + 3), single_cert_len]
798+
certificate_data = data[(already_read + 3), single_cert_len]
793799
cert = OpenSSL::X509::Certificate.new(certificate_data)
794800
# First received certificate is the one from the server
795801
@cert = cert if @cert.nil?

0 commit comments

Comments
 (0)