前言
这是在FreeBuf的第二篇审计文章,不是想讲漏洞分析,更多是想写下整个审计的过程,在我最开始学代码审计时,拿到一套cms,却无从下手,想从网上找找实战案例,但找到的大都是案例分析,没见过几篇是把整个审计过程写下来的。经过一番摸索,终于从小白进阶到菜鸟,于是想着写几篇带完整过程的代码审计文章,尽管这些过程在大佬们看来跟后面的漏洞关系不大、并不重要;但对于新手朋友来说,这可能是一篇把他从迷茫中拉出来的文章。
虽然我只写了两篇,但每篇都是我审计时的完整过程,算不是什么深度好文,但只希望能给新手朋友一点点帮助。我只是位菜鸟,写出让大佬满意的文章,我不是小说主角,做不出越级的操作,但我的文章兴许能对新人朋友有帮助呢?毕竟我也是刚从新手过来的,我知道那时候的我想要什么,但找不到;如果后来人也这么想,也像当初的我那样想,那这两篇就没白写~
通读全文
跟进index.php
define('PHPCMS_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
include PHPCMS_PATH.'/phpcms/base.php';
pc_base::creat_app();
将phpcms/base.php
包含进来,然后调用pc_base::creat_app
函数,跟进phpcms/base.php
define('IN_PHPCMS', true);
//PHPCMS框架路径
define('PC_PATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
if(!defined('PHPCMS_PATH')) define('PHPCMS_PATH', PC_PATH.'..'.DIRECTORY_SEPARATOR);
//缓存文件夹地址
define('CACHE_PATH', PHPCMS_PATH.'caches'.DIRECTORY_SEPARATOR);
//主机协议
define('SITE_PROTOCOL', isset($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://');
//当前访问的主机名
define('SITE_URL', (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ''));
//来源
define('HTTP_REFERER', isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '');
//系统开始时间
define('SYS_START_TIME', microtime());
//加载公用函数库
pc_base::load_sys_func('global');
pc_base::load_sys_func('extention');
pc_base::auto_load_func();
pc_base::load_config('system','errorlog') ? set_error_handler('my_error_handler') : error_reporting(E_ERROR | E_WARNING | E_PARSE);
//设置本地时差
function_exists('date_default_timezone_set') && date_default_timezone_set(pc_base::load_config('system','timezone'));
define('CHARSET' ,pc_base::load_config('system','charset'));
//输出页面字符集
header('Content-type: text/html; charset='.CHARSET);
define('SYS_TIME', time());
//定义网站根路径
define('WEB_PATH',pc_base::load_config('system','web_path'));
//js 路径
define('JS_PATH',pc_base::load_config('system','js_path'));
//css 路径
define('CSS_PATH',pc_base::load_config('system','css_path'));
//img 路径
define('IMG_PATH',pc_base::load_config('system','img_path'));
//动态程序路径
define('APP_PATH',pc_base::load_config('system','app_path'));
//应用静态文件路径
define('PLUGIN_STATICS_PATH',WEB_PATH.'statics/plugin/');
......
9-60
行,定义常量,加载通用函数库
继续跟进pc_base::creat_app
方法,phpcms/base.php
67行
/**
* 初始化应用程序
*/
public static function creat_app() {
return self::load_sys_class('application');
}
这里介绍几个比较常用的方法,都在pc_base类中
load_sys_class
//加载系统类
load_app_class
//加载应用类
load_model
//加载数据模型load_config
//加载配置文件
/**
* 加载系统类方法
* @param string $classname 类名
* @param string $path 扩展地址
* @param intger $initialize 是否初始化
*/
public static function load_sys_class($classname, $path = '', $initialize = 1) {
return self::_load_class($classname, $path, $initialize);
}
/**
* 加载应用类方法
* @param string $classname 类名
* @param string $m 模块
* @param intger $initialize 是否初始化
*/
public static function load_app_class($classname, $m = '', $initialize = 1) {
$m = empty($m) && defined('ROUTE_M') ? ROUTE_M : $m;
if (empty($m)) return false;
return self::_load_class($classname, 'modules'.DIRECTORY_SEPARATOR.$m.DIRECTORY_SEPARATOR.'classes', $initialize);
}
/**
* 加载数据模型
* @param string $classname 类名
*/
public static function load_model($classname) {
return self::_load_class($classname,'model');
}
对比三个方法发现,相同的是核心都是调用_load_class
方法,跟进_load_class
方法
/**
* 加载类文件函数
* @param string $classname 类名
* @param string $path 扩展地址
* @param intger $initialize 是否初始化
*/
private static function _load_class($classname, $path = '', $initialize = 1) {
static $classes = array();
if (empty($path)) $path = 'libs'.DIRECTORY_SEPARATOR.'classes';
$key = md5($path.$classname);
if (isset($classes[$key])) {
if (!empty($classes[$key])) {
return $classes[$key];
} else {