某企业管理系统审计小结

1@ 前言

md 国庆睡的太爽了,睡爽了起来审一审 : p

这次拿到的 youdiancms 是基于 tp 开发的一套简单的企业网站管理系统。cnvd 上收录关于其系统的漏洞只有星星点点的几个,故拿来复现练手,同时看看能不能再审出点自己的小洞~

2@ CNVD-2019-21447 前台 sql 注入

条件:

  • 开启会员注册功能.
  • 用已经注册过得会员登录.

由于基于 tp 开发,所以其路由规则就是类于 /功能模块/类/方法/参数 的 PATH_INFO 的模式.

在运行过程中,会动态生成一个主文件 —> yunxingshi.php,由于写入的时候并没有考虑到排版问题,所以为了便于审计,我们可以在这里进行代码格式的美化.

这里我们省去路由传入参数的过程,着重来学习下在框架开发的模式下,从数据库中存取数据的流程.为了方便调试演示,直接给出存在问题的方法:

  • App/Lib/Action/Member/CustomerAction/ 下的 saveModify 的方法

  • 演示 url : http://cms.test1/index.php/Member/Customer/saveModify

    POST : MemberName=root1&MemberID=1 and sleep(5);#

1
2
3
4
5
6
7
function saveModify(){
header("Content-Type:text/html; charset=utf-8");
$this->_checkPost( $_POST );
unset( $_POST['InviterID'], $_POST['IsEnable']);
$m = D('Admin/Member');
$inviterID = $m->where("MemberID={$_POST['MemberID']}")->getField('InviterID');
......

可以看到,传入的 MemberID 参数,经过简单的处理,就直接带到了类的 where 方法里面进行查询了,如果包装类的方法再没有处理过程,那么很有可能产生注入,我们跟进观察.

1、首先跟进到 _checkPost() 方法中

1
2
3
4
5
6
7
8
9
10
11
private function _checkPost($p){
if( empty($p['MemberName']) ){
$this->ajaxReturn(null, '昵称不能为空' , 0);
}

if( $_POST['MemberPassword'] != ''){
$_POST['MemberPassword'] = md5($_POST['MemberPassword']);
}else{
unset( $_POST['MemberPassword'] );
}
}

没有进行传 入参数的过滤,只是提醒我们必须传入 MemberName 这个参数,否则返回错误提示信息.

2、接着 D() 方法大致流程就是新建一个模型类实例,然后返回

3、然后就到了关键的带入到实例中 where 方法中,我们来着重看看整个数据的流动过程:

  • 没有 where 方法,首先调用到 __call() 这个魔术方法,