AI智能
改变未来

PHP审计之WeEngine审计


PHP审计之WeEngine审计

前言

审计该CMS加深一下对于MVC架构的php审计流程

梳理路由

打开代码看到index.php文件

if($_W[\'os\'] == \'mobile\' && (!empty($_GPC[\'i\']) || !empty($_SERVER[\'QUERY_STRING\']))) {header(\'Location: ./app/index.php?\' . $_SERVER[\'QUERY_STRING\']);} else {header(\'Location: ./web/index.php?\' . $_SERVER[\'QUERY_STRING\']);}

web端会跳转到

/web/index.php

,来看到

web/index.php

if (($_W[\'setting\'][\'copyright\'][\'status\'] == 1) && empty($_W[\'isfounder\']) && $controller != \'cloud\' && $controller != \'utility\' && $controller != \'account\') {$_W[\'siteclose\'] = true;if ($controller == \'account\' && $action == \'welcome\') {template(\'account/welcome\');exit;}if ($controller == \'user\' && $action == \'login\') {if (checksubmit()) {require _forward($controller, $action);}template(\'user/login\');exit;}isetcookie(\'__session\', \'\', -10000);message(\'站点已关闭,关闭原因:\' . $_W[\'setting\'][\'copyright\'][\'reason\'], url(\'account/welcome\'), \'info\');}

这里

$controller

$action

接收是从

bootstrap.inc.php

$controller = $_GPC[\'c\'];$action = $_GPC[\'a\'];$do = $_GPC[\'do\'];

上面接收

$controller

$action

account

welcome

调用

template(\'account/welcome\');

function template($filename, $flag = TEMPLATE_DISPLAY) {global $_W;$source = IA_ROOT . "/web/themes/{$_W[\'template\']}/{$filename}.html";$compile = IA_ROOT . "/data/tpl/web/{$_W[\'template\']}/{$filename}.tpl.php";if(!is_file($source)) {$source = IA_ROOT . "/web/themes/default/{$filename}.html";$compile = IA_ROOT . "/data/tpl/web/default/{$filename}.tpl.php";}...

这段代码实际上就是加载一个模板渲染。

继续往下看

$controllers = array();$handle = opendir(IA_ROOT . \'/web/source/\');if(!empty($handle)) {while($dir = readdir($handle)) {if($dir != \'.\' && $dir != \'..\') {$controllers[] = $dir;}}}if(!in_array($controller, $controllers)) {$controller = \'account\';}$init = IA_ROOT . "/web/source/{$controller}/__init.php";if(is_file($init)) {require $init;}$actions = array();$handle = opendir(IA_ROOT . \'/web/source/\' . $controller);if(!empty($handle)) {while($dir = readdir($handle)) {if($dir != \'.\' && $dir != \'..\' && strexists($dir, \'.ctrl.php\')) {$dir = str_replace(\'.ctrl.php\', \'\', $dir);$actions[] = $dir;}}}if(empty($actions)) {header(\'location: ?refresh\');}if(!in_array($action, $actions)) {$action = $acl[$controller][\'default\'];}if(!in_array($action, $actions)) {$action = $actions[0];}

遍历读取

/web/source/

,所有内容。

遍历读取

/web/source/\' . $controller

,并且把内容中的

.ctrl.php

去掉。

if(is_array($acl[$controller][\'direct\']) && in_array($action, $acl[$controller][\'direct\'])) {require _forward($controller, $action);exit;

判断是否为数组并且判断

$acl[$controller][\'direct\']

,并且查看

$action

是否在

$acl

截取对应

$controller

direct

逻辑其实就是

$acl

中定义了大量的数组,如

\'account\' => array(\'default\' => \'welcome\',\'direct\' => array(\'welcome\',\'auth\')

$controller=account

direct=array(\’welcome\’,\’auth\’)

direct这个数组对应的是account下面的路由

访问welcome的路由的访问策略即

/web/index.php?c=account&a=welcome

漏洞审计

定位到漏洞位置

web/source/site/category.ctrl.php

定位到176行

if (!empty($navs)) {foreach ($navs as $row) {file_delete($row[\'icon\']);}pdo_query("DELETE FROM ".tablename(\'site_nav\')." WHERE id IN (".implode(\',\', array_keys($navs)).")");}

file_delete($row[\'icon\']);

,这里的

$row[\'icon\']

是通过遍历

$navs

$navs

是通过一下这个sql语句查询得来的

$navs = pdo_fetchall("SELECT icon, id FROM ".tablename(\'site_nav\')." WHERE id IN (SELECT nid FROM ".tablename(\'site_category\')." WHERE id = {$id} OR parentid = \'$id\')", array(), \'id\');

找看数据库中的这两个字段是否可控

site_nav数据库表中对应的数据是

$nav

变量内容,发现

$nav[\'icon\']

变量是从

$_GPC[\'iconfile\']

来的,即参数可控。这里的

$nav[\'icon\']

变量,其实就是我们文章开头分析的传入

file_delete

函数的参数

if(!empty($nav_exist)) {pdo_update(\'site_nav\', $nav, array(\'id\' => $category[\'nid\'], \'uniacid\' => $_W[\'uniacid\']));} else {pdo_insert(\'site_nav\', $nav);

这里需要先把文件名插入到数据库中,然后调用该功能将文件上传,代码会从数据库从查找该文件名,然后删除对应文件。

参考

https://github.com/hongriSec/PHP-Audit-Labs/tree/master/Part1/Day6/files

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » PHP审计之WeEngine审计