Knight cms- read the text - code audit

Version: 3.5.1

Download: http://103.45.101.75:66/2/201412/74cms.rar

1. Auditing Methods

Read audit

1.1 View File Structure

First need to see which files and folders to find there is no name with api, admin, manage, include a class key files and folders, these files are usually more important in this program, you can see and nothing PHP files on a index.php, saw a file folder named include, generally more core files are placed in this folder, we take a look about what files

 
image.png

 

1.2 View key documents
in which include, common.fun.php is the core of this program, most functions are implemented here.

We look inside what are the key functions

We are beginning to see the SQL injection filter function

function addslashes_deep($value)
{
    if (empty($value))
    {
        return $value;
    }
    else
    {
    if (!get_magic_quotes_gpc())
    {
    $value=is_array($value) ? array_map('addslashes_deep', $value) : mystrip_tags(addslashes($value));
    }
    else
    {
    $value=is_array($value) ? array_map('addslashes_deep', $value) : mystrip_tags($value);
    }
    return $value;
    }
}

 

The function of the variable descendant use addslashes () function to filter, it filters out the single quotes, double quotes, NULL character and slash, and now we have to remember that during the excavation SQL injection and other vulnerabilities, as long as the parameters are spliced ​​to before the SQL statement, unless there is a wide byte injection or other special circumstances, the use of this function can not be injected.

Xiazou XSS is a filter function mystrip_tags

function mystrip_tags($string)
{
   $string = new_html_special_chars($string);
   $string = remove_xss($string);
   return $string;
}

 

The following calls new_html_special_chars and remove_xss function to deal with.

Can be seen in new_html_special_chars () function, this function ampersands, double quotes and angle brackets the html coding entity, and using striptags () function of the second filter. The remove_xss () function is the label for some keywords, events, keywords and keyword sensitive function replacement.

function new_html_special_chars($string) {

   $string = str_replace(array('&amp;', '&quot;', '<', '>'), array('&', '"', '<', '>'), $string);

   $string = strip_tags($string);

   return $string;

}

function remove_xss($string) {

   $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);


   $parm1 = Array('javascript', 'union','vbscript', 'expression', 'applet', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');


   $parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange '' onfinish "," onfocus "," onfocusin '' onfocusout '' onhelp '' onkeydown '' OnKeyPress '' onkeyup '' onlayoutcomplete ',' onload ', onlosecapture' 'onmousedown' , onmouseenter '' onmouseleave '' OnMouseMove '' onMouseOut '' onmouseover '' onmouseup '' onmousewheel '' onmove '' onmoveend '' onmovestart '' onpaste '' onpropertychange '' onreadystatechange ", onreset '' onresize '' onresizeend '' onresizestart '' onrowenter '' onrowexit '' onrowsdelete '' onrowsinserted '' onscroll '' onselect '' onselectionchange '' onselectstart ' ,onstart', 'onstop', 'onsubmit', 'onunload','style','href','action','location','background','src','poster');

   

   $parm3 = Array('alert','sleep','load_file','confirm','prompt','benchmark','select','update','insert','delete','alter','drop','truncate','script','eval');


   $parm = array_merge($parm1, $parm2, $parm3);


   for ($i = 0; $i < sizeof($parm); $i++) {

       $pattern = '/';

       for ($j = 0; $j < strlen($parm[$i]); $j++) {

           if ($j > 0) {

               $pattern .= '(';

               $pattern .= '(&#[x|X]0([9][a][b]);?)?';

               $pattern .= '|($#0([9][10][13]);?)?';

               $pattern .= ')?';

           }

           $pattern .= $parm[$i][$j];

       }

       $pattern .= '/i';

       $string = preg_replace($pattern, '****', $string);

   }

   return $string;

}

 

Further down there to obtain an IP function, where you can fake IP. No other program verification IP format acquiring IP, which may be performed using the acquired IP injection.

function getip()
{
  if (getenv('HTTP_CLIENT_IP') and strcasecmp(getenv('HTTP_CLIENT_IP'),'unknown')) {
    $onlineip=getenv('HTTP_CLIENT_IP');
  }elseif (getenv('HTTP_X_FORWARDED_FOR') and strcasecmp(getenv('HTTP_X_FORWARDED_FOR'),'unknown')) {
    $onlineip=getenv('HTTP_X_FORWARDED_FOR');
  }elseif (getenv('REMOTE_ADDR') and strcasecmp(getenv('REMOTE_ADDR'),'unknown')) {
    $onlineip=getenv('REMOTE_ADDR');
  }elseif (isset($_SERVER['REMOTE_ADDR']) and $_SERVER['REMOTE_ADDR'] and strcasecmp($_SERVER['REMOTE_ADDR'],'unknown')) {
    $onlineip=$_SERVER['REMOTE_ADDR'];
  }
  preg_match("/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/",$onlineip,$match);
  return $onlineip = $match[0] ? $match[0] : 'unknown';
}

 

Here is inserttable and updatetable function, there are a large number of SQL statements to query, mainly to see there is no filtration problems.

Xiazou is wheresql () function is the query's SQL statement Where condition stitching place, we can see that the parameters are used in single quotes wrapped.

function wheresql($wherearr='')

{

   $wheresql="";

   if (is_array($wherearr))

       {

       $where_set=' WHERE ';

           foreach ($wherearr as $key => $value)

           {

           $wheresql .=$where_set. $comma.$key.'="'.$value.'"';

           $comma = ' AND ';

           $where_set=' ';

           }

       }

   return $wheresql;

}

 

There is also a function asyn_userkey access token generated (), splicing user name, password, salt and password once md5, as long as the time of the visit in which the value of GET parameters plus key generated by the key authority to verify whether there is used in registration, password recovery and so the verification process, which is the password recovery link inside the key we can see.

function asyn_userkey($uid)

{

   global $db;

   $sql = "select * from ".table('members')." where uid = '".intval($uid)."' LIMIT 1";

   $user=$db->getone($sql);

   return md5($user['username'].$user['pwd_hash'].$user['password']);

}

 

Specific functions under the same directory file, you can not look at

 

 
image.png

1.3 View Profile

config file in the directory lookup

 

 
image.png

 

Found cache_config and config under / data is the configuration file.

<?php

$dbhost   = "localhost";

$dbname   = "74cms";

$dbuser   = "root";

$dbpass   = "root";

$pre    = "qs_";

$QS_cookiedomain = '';

$QS_cookiepath =  "/74cms/";

$QS_pwdhash = "H@g24Q6xa:AewjJD";

define('QISHI_CHARSET','gb2312');

define('QISHI_DBCHARSET','GBK');

?>

 

Can be seen, QISHI_DBCHARSET GBK encoding is constant, and therefore the upper double quotes parsing code and related data, there may be injection bytes wide. But it needs to look at the database connection encoding settings

Then look for the database connection file /include/mysql.class.php the connect function

function connect($dbhost, $dbuser, $dbpw, $dbname = '', $dbcharset = 'gbk', $connect=1){
  $func = empty($connect) ? 'mysql_pconnect' : 'mysql_connect';
  if(!$this->linkid = @$func($dbhost, $dbuser, $dbpw, true)){
    $this->dbshow('Can not connect to Mysql!');
  } else {
    if($this->dbversion() > '4.1'){
      mysql_query( "SET NAMES gbk");
      if($this->dbversion() > '5.0.1'){
        mysql_query("SET sql_mode = ''",$this->linkid);
  mysql_query("SET character_set_connection=".$dbcharset.", character_set_results=".$dbcharset.", character_set_client=binary", $this->linkid);
      }
    }
  }
  if($dbname){
    if(mysql_select_db($dbname, $this->linkid)===false){
      $this->dbshow("Can't select MySQL database($dbname)!");
    }
  }
}

 

That is 4.1 execute "set names gbk" When MySQL version is greater than, but less than 5.0.1, the following is not executed.

Perform only set names gbk.

But set names gbk equivalent to
setting client code

set character_set_client = gbk
setup Encoder
set character_set_connection = gbk
set the return value is encoded
SET The character_set_results = GBK
Client (client), connection (connector), results (return value)

Therefore, there are between MySQL4.1-5.0.1 injection bytes wide.

1.4 Home reading file

By a rough idea of ​​the file system, we have some understanding of the overall structure of this program, but not enough, so we have to repeat what index.php file to see which files when the program is running and function calls .

Follow up to see common.inc.php

require_once(QISHI_ROOT_PATH.'data/config.php');

header("Content-Type:text/html;charset=".QISHI_CHARSET);

require_once(QISHI_ROOT_PATH.'include/common.fun.php');

require_once(QISHI_ROOT_PATH.'include/74cms_version.php');

 

Can be seen as a reference to the config.php configuration file, common.fun.php is the core function file, 74cms_version.php is the version of the file

Continue down, we can be seen to filter the data transmission

if (!empty($_GET))

{

$_GET  = addslashes_deep($_GET);

}

if (!empty($_POST))

{

$_POST = addslashes_deep($_POST);

}

$_COOKIE   = addslashes_deep($_COOKIE);

$_REQUEST  = addslashes_deep($_REQUEST);

 

To see down the operation of a file that contains

require_once(QISHI_ROOT_PATH.'include/tpl.inc.php');

 

Follow-up to tpl.inc.php file

include_once(QISHI_ROOT_PATH.'include/template_lite/class.template.php');

$smarty = new Template_Lite;

$smarty -> cache_dir = QISHI_ROOT_PATH.'temp/caches/'.$_CFG['template_dir'];

$smarty -> compile_dir =  QISHI_ROOT_PATH.'temp/templates_c/'.$_CFG['template_dir'];

$smarty -> template_dir = QISHI_ROOT_PATH.'templates/'.$_CFG['template_dir'];

$smarty -> reserved_template_varname = "smarty";

$smarty -> left_delimiter = "{#";

$smarty -> right_delimiter = "#}";

$smarty -> force_compile = false;

$smarty -> assign('_PLUG', $_PLUG);

$smarty -> assign('QISHI', $_CFG);

$smarty -> assign('page_select',$page_select);

 

You can see be a template file mapping, and smarty be assigned to the property.

Now back to the index.php file

if(!$smarty->is_cached($mypage['tpl'],$cached_id))

{

require_once(QISHI_ROOT_PATH.'include/mysql.class.php');

$db = new mysql($dbhost,$dbuser,$dbpass,$dbname);

unset($dbhost,$dbuser,$dbpass,$dbname);

$smarty->display($mypage['tpl'],$cached_id);

}

else

{

$smarty->display($mypage['tpl'],$cached_id);

}

 

Determine whether there is a cache, and then display the page display.

Here we discovered the existence of a specific database versions byte wide injection, and Knight learned more about the CMS code.

 

Guess you like

Origin www.cnblogs.com/x00c/p/12629110.html