From 9b55f5143a01ad4375264b660a51f12201b02396 Mon Sep 17 00:00:00 2001 From: jvazquez-r7 Date: Mon, 9 Jun 2014 17:38:11 -0500 Subject: [PATCH] Add module for CVE-2014-0224 --- modules/auxiliary/scanner/ssl/openssl_ccs.rb | 204 +++++++++++++++++++ 1 file changed, 204 insertions(+) create mode 100644 modules/auxiliary/scanner/ssl/openssl_ccs.rb diff --git a/modules/auxiliary/scanner/ssl/openssl_ccs.rb b/modules/auxiliary/scanner/ssl/openssl_ccs.rb new file mode 100644 index 0000000000..434d3d9ffa --- /dev/null +++ b/modules/auxiliary/scanner/ssl/openssl_ccs.rb @@ -0,0 +1,204 @@ +## +# This module requires Metasploit: http//metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +require 'msf/core' + +class Metasploit3 < Msf::Auxiliary + + include Msf::Exploit::Remote::Tcp + include Msf::Auxiliary::Scanner + include Msf::Auxiliary::Report + + CIPHER_SUITES = [ + 0xc014, # TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + 0xc00a, # TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + 0xc022, # TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA + 0xc021, # TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA + 0x0039, # TLS_DHE_RSA_WITH_AES_256_CBC_SHA + 0x0038, # TLS_DHE_DSS_WITH_AES_256_CBC_SHA + 0x0088, # TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + 0x0087, # TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA + 0x0087, # TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + 0xc00f, # TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + 0x0035, # TLS_RSA_WITH_AES_256_CBC_SHA + 0x0084, # TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + 0xc012, # TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA + 0xc008, # TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA + 0xc01c, # TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA + 0xc01b, # TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA + 0x0016, # TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA + 0x0013, # TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA + 0xc00d, # TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA + 0xc003, # TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA + 0x000a, # TLS_RSA_WITH_3DES_EDE_CBC_SHA + 0xc013, # TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + 0xc009, # TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + 0xc01f, # TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA + 0xc01e, # TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA + 0x0033, # TLS_DHE_RSA_WITH_AES_128_CBC_SHA + 0x0032, # TLS_DHE_DSS_WITH_AES_128_CBC_SHA + 0x009a, # TLS_DHE_RSA_WITH_SEED_CBC_SHA + 0x0099, # TLS_DHE_DSS_WITH_SEED_CBC_SHA + 0x0045, # TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + 0x0044, # TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA + 0xc00e, # TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + 0xc004, # TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + 0x002f, # TLS_RSA_WITH_AES_128_CBC_SHA + 0x0096, # TLS_RSA_WITH_SEED_CBC_SHA + 0x0041, # TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + 0xc011, # TLS_ECDHE_RSA_WITH_RC4_128_SHA + 0xc007, # TLS_ECDHE_ECDSA_WITH_RC4_128_SHA + 0xc00c, # TLS_ECDH_RSA_WITH_RC4_128_SHA + 0xc002, # TLS_ECDH_ECDSA_WITH_RC4_128_SHA + 0x0005, # TLS_RSA_WITH_RC4_128_SHA + 0x0004, # TLS_RSA_WITH_RC4_128_MD5 + 0x0015, # TLS_DHE_RSA_WITH_DES_CBC_SHA + 0x0012, # TLS_DHE_DSS_WITH_DES_CBC_SHA + 0x0009, # TLS_RSA_WITH_DES_CBC_SHA + 0x0014, # TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA + 0x0011, # TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA + 0x0008, # TLS_RSA_EXPORT_WITH_DES40_CBC_SHA + 0x0006, # TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 + 0x0003, # TLS_RSA_EXPORT_WITH_RC4_40_MD5 + 0x00ff # Unknown + ] + + HANDSHAKE_RECORD_TYPE = 0x16 + CCS_RECORD_TYPE = 0x14 + ALERT_RECORD_TYPE = 0x15 + TLS_VERSION = { + 'SSLv3' => 0x0300, + '1.0' => 0x0301, + '1.1' => 0x0302, + '1.2' => 0x0303 + } + + def initialize + super( + 'Name' => 'OpenSSL CCS Injection Scanner', + 'Description' => %q{ + This module allows to check for the OpenSSL CCS Injection attack. The problem + exists in the handling of early ChangeCipherSpec messages, with OpenSSL + accepting them. + }, + 'Author' => [ + 'Masashi Kikuchi', # Vulnerability discovery + 'Craig Young ', # Original Scanner. This module is based on it. + 'juan vazquez' # Msf module + ], + 'References' => + [ + ['CVE', '2014-0224'], + ['URL', 'http://ccsinjection.lepidum.co.jp/'], + ['URL', 'http://ccsinjection.lepidum.co.jp/blog/2014-06-05/CCS-Injection-en/index.html'], + ['URL', 'http://www.tripwire.com/state-of-security/incident-detection/detection-script-for-cve-2014-0224-openssl-cipher-change-spec-injection/'], + ['URL', 'https://www.imperialviolet.org/2014/06/05/earlyccs.html'] + ], + 'DisclosureDate' => 'Jun 5 2014', + 'License' => MSF_LICENSE + ) + + register_options( + [ + Opt::RPORT(443), + OptEnum.new('TLS_VERSION', [true, 'TLS/SSL version to use', '1.0', ['SSLv3','1.0', '1.1', '1.2']]), + OptInt.new('RESPONSE_TIMEOUT', [true, 'Number of seconds to wait for a server response', 10]) + ], self.class) + end + + def peer + "#{rhost}:#{rport}" + end + + def response_timeout + datastore['RESPONSE_TIMEOUT'] + end + + def run_host(ip) + ccs_injection + end + + def ccs_injection + connect_result = establish_connect + return if connect_result.nil? + + vprint_status("#{peer} - Sending CCS...") + sock.put(ccs) + alert = sock.get_once(-1, response_timeout) + if alert.blank? + print_good("#{peer} - No Alert after invalid CSS message, probably vulnerable") + report + elsif alert.unpack("C").first == ALERT_RECORD_TYPE + vprint_error("#{peer} - Alert record as response to the invalid CCS Message") + elsif alert + vprint_warning("#{peer} - Unexpected response...") + end + end + + def report + report_vuln({ + :host => rhost, + :port => rport, + :name => self.name, + :refs => self.references, + :info => "Module #{self.fullname} successfully detected CCS injection" + }) + end + + def ccs + payload = "\x01" # Change Cipher Spec Message + + ssl_record(CCS_RECORD_TYPE, payload) + end + + def client_hello + # Use current day for TLS time + time_temp = Time.now + time_epoch = Time.mktime(time_temp.year, time_temp.month, time_temp.day, 0, 0).to_i + + hello_data = [TLS_VERSION[datastore['TLS_VERSION']]].pack("n") # Version TLS + hello_data << [time_epoch].pack("N") # Time in epoch format + hello_data << Rex::Text.rand_text(28) # Random + hello_data << "\x00" # Session ID length + hello_data << [CIPHER_SUITES.length * 2].pack("n") # Cipher Suites length (102) + hello_data << CIPHER_SUITES.pack("n*") # Cipher Suites + hello_data << "\x01" # Compression methods length (1) + hello_data << "\x00" # Compression methods: null + + data = "\x01\x00" # Handshake Type: Client Hello (1) + data << [hello_data.length].pack("n") # Length + data << hello_data + + ssl_record(HANDSHAKE_RECORD_TYPE, data) + end + + def ssl_record(type, data) + record = [type, TLS_VERSION[datastore['TLS_VERSION']], data.length].pack('Cnn') + record << data + end + + def establish_connect + connect + + vprint_status("#{peer} - Sending Client Hello...") + sock.put(client_hello) + server_hello = sock.get(response_timeout) + + unless server_hello + vprint_error("#{peer} - No Server Hello after #{response_timeout} seconds...") + disconnect + return nil + end + + unless server_hello.unpack("C").first == HANDSHAKE_RECORD_TYPE + vprint_error("#{peer} - Server Hello Not Found") + return nil + end + + true + end + +end +