AI智能
改变未来

PHP审计之BEESCMS审计案例


PHP审计之BEESCMS审计案例

审计流程

任意文件包含

文件存在即包含该文件,而包含的这个文件名可控,则需要找这个文件创建的地方

function creat_inc($fl,$str){if(file_exists($fl)){@unlink($fl);}if(!$fp=@fopen($fl,\'w\')){msg(\'文件打开失败,请检查是否有足够的权限操作文件\');}flock($fp,LOCK_EX);if(!fwrite($fp,$str)){msg(\'写入文件失败,请检查是否有足够的权限操作文件\');}flock($fp,LOCK_UN);unset($fp);}

lang是request接受过来的值,可控。

跟踪到这只要$cate_list可控,那么就是一个妥妥的任意文件包含漏洞。而这里的实际代码是

$cate_list =.var_export($rel,true)

发现这个$rel这个参数大部分都是数据库查询获取的值。

找了几个目录可控的,继续来看代码

\\admin\\admin_db.php\\admin\\admin_index.php\\admin\\admin_info.php\\admin\\admin_sq_code.php

admin_db.php文件

elseif($action==\'save_back\'){if(!check_purview(\'data_backup\')){msg(\'<span style="color:red">操作失败,你的权限不足!</span>\');}$db = $_POST[\'db\'];$init = isset($_POST[\'init\'])?$_POST[\'init\']:0;$sql_size = 1048;$dir = isset($_GET[\'dir\'])?$_GET[\'dir\']:\'\';//缓存所有表if($init){if(empty($db)){msg(\'请选择要备份的表\');}$str="<?php\\n\\$table_arr=".var_export($db,true).";\\n?>";$file=DATA_PATH.\'cache/db_cache.php\';creat_inc($file,$str);//创建备份目录$dir = \'db\'.date(YmdHms,time());@mkdir(DATA_PATH.\'backup/\'.$dir);}@include(DATA_PATH.\'cache/db_cache.php\');

发现转义单引号,代码中并没有发现有过滤函数,看到包含过来的init.php文件

if (!get_magic_quotes_gpc()){if (isset($_REQUEST)){$_REQUEST  = addsl($_REQUEST);}$_COOKIE   = addsl($_COOKIE);$_POST = addsl($_POST);$_GET = addsl($_GET);}

检测没开启魔术引号,则启用自己的过滤方法进行全局的过滤。

/**转义函数**@param   $value   array || string*@return  array || string*/function addsl($value){if (empty($value)){return $value;}else{return is_array($value) ? array_map(\'addsl\', $value) : addslashes($value);}}

过滤操作

注入

login.php

elseif($action==\'ck_login\'){global $submit,$user,$password,$_sys,$code;$submit=$_POST[\'submit\'];$user=fl_html(fl_value($_POST[\'user\']));$password=fl_html(fl_value($_POST[\'password\']));$code=$_POST[\'code\'];.....check_login($user,$password);

fl_html跟踪查看发现是过滤xss的,也就是实例化html。fl_value方法是一个正则过滤sql的方法。

function fl_value($str){if(empty($str)){return;}return preg_replace(\'/select|insert | update | and | in | on | left | joins | delete |\\%|\\=|\\/\\*|\\*|\\.\\.\\/|\\.\\/| union | from | where | group | into |load_file|outfile/i\',\'\',$str);}
unction check_login($user,$password){$rel=$GLOBALS[\'mysql\']->fetch_asc("select id,admin_name,admin_password,admin_purview,is_disable from ".DB_PRE."admin where admin_name=\'".$user."\' limit 0,1");$rel=empty($rel)?\'\':$rel[0];

updatexml没被过滤,可以使用updatexml。

session覆盖

Extract()

该函数使用数组键名作为变量名,使用数组键值作为变量值。但是当变量中有同名的元素时,该函数默认将原有的值给覆盖掉。这就造成了变量覆盖漏洞。

如果能覆盖(添加)这几个$_SESSION值 就能绕过这个检查

$_SESSION

覆盖有个必须前提,

session_start()

必须出现在覆盖之前,不然就算覆盖了

$_SESSION

变量,一旦session_start() 变量就会被初始化掉。没有使用

EXTR_SKIP

参数导致任意变量覆盖,又由于执行的时候已经session_start()了所以可以覆盖(添加)任意$_SESSION值

if(!is_login()){header(\'location:login.php\');exit;}

查看is_login的方法

function is_login(){if($_SESSION[\'login_in\']==1&&$_SESSION[\'admin\']){if(time()-$_SESSION[\'login_time\']>3600){login_out();}else{$_SESSION[\'login_time\']=time();@session_regenerate_id();}

发现验证了三个值,主要伪造着三个值即可登录。

if (!get_magic_quotes_gpc()){if (isset($_REQUEST)){$_REQUEST  = addsl($_REQUEST);}$_COOKIE   = addsl($_COOKIE);$_POST = addsl($_POST);$_GET = addsl($_GET);}if (isset($_REQUEST)){$_REQUEST  = fl_value($_REQUEST);}$_COOKIE   = fl_value($_COOKIE);$_GET = fl_value($_GET);@extract($_POST);@extract($_GET);@extract($_COOKIE);

而在这里,init.php代码中,使用Extract方法未使用

EXTR_SKIP

参数,并且未过滤

_session

字符,导致可以同名变量覆盖。

_SESSION[login_in]=1&_SESSION[admin]=1&_SESSION[login_time]=99999999999

结尾

类似这种非MVC的架构,可以省略看路由这步骤,直接定位危险函数/方法,还有的就是鉴权实现。

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