记一次对Tp二开的源码审计(Php审计)

  • A+
所属分类:代码审计

冷水师傅投稿的xz 

  • 概述
    一款某单子Tp二开平台,开发者嚷嚷着要找人审计一下源码,说有预算,洞审出来之后人就没了,感觉审都审了,不做点什么不是浪费时间了,于是就发出来顺便讲一下在Tp二开情况下如何对源码进行审计,一般在拿到Tp二开的源码,首先要做的事,确认系统版本,然后利用搜索引擎寻找当前框架版本的漏洞,这次拿到手之后在确认下是Tp3.2.3的系统,其次就是查看TP的路由是默认还是说更改了,然后找到web类,对类中的代码一行一行的仔细审计,Tp3.2.3爆出的漏洞挺多的,结合前辈的各种经验,成功寻找到了开发中的雷区,这里直接贴代码。

    记一次对Tp二开的源码审计(Php审计)

  • 任意文件包含代码执行
    在ApplicationHomeControllerVueController.class.php下,可以看到这里是这样写的。

    记一次对Tp二开的源码审计(Php审计)


  • 但是在TP3.2.3中,这是个大问题,因为display方法会直接包含这个变量中的文件,并且在Controller.class.php中的_Call类定义了如果存在_empty方法,就会优先调用,这里methed_name就是a方法类的传值,但是如果我们另调用的a类直接为我们要包含的文件的绝对路径,那么就会直接包含掉我们所给的文件。

    记一次对Tp二开的源码审计(Php审计)


    这里贴出详情漏洞代码


    public function _empty($methed_name){
    $this->display($methed_name);
    exit(0);
    }

    我们这里可以看到,当把A设置为日志的绝对路径时,会直接包含掉这个日志,从而造成任意代码执行。



记一次对Tp二开的源码审计(Php审计)

  • Sql注入
    在ApplicationApiControllerAreaController.class.php下,先铺上代码。

    记一次对Tp二开的源码审计(Php审计)


  • 这里没有使用I方法,而是直接通过$_REQUEST['pid']去取得Pid的值,我们这里可以构造Exp表达式用于Where条件,然后对代码进行注入,也不知道是不是留的后门,前面都写了I,就这里非要用$_REQUEST['pid']去接受参数,构造pid[0]=exp&pid[1]= and updatexml(1,concat(0x7e,(select user())),0)可以看到成功爆出来了用户名。


    public function ajax() {
    $pid = $_REQUEST['pid'];
    $list = D('Area')->where(array('pid'=>$pid))->select();
    $html = '';
    foreach( $list as $k=>$v ) {
    $html .= '<option value="'.$v["area_id"].'">'.$v["title"].'</option>';
    }
    echo $html;
    }

记一次对Tp二开的源码审计(Php审计)

Session操控

在ApplicationApiControllerCodePayController.class.php中,就更离谱了,铺上代码。

记一次对Tp二开的源码审计(Php审计)


这里的$key,$value值都是经过$_REQUEST传参进来的,也就是说,我们可以任意的对Session进行操控,结合判断的Check_login来看,发现只是判断Session里面是否存在值。


public function setsession()
{

$key = (isset($_REQUEST['key']) && !empty($_REQUEST['key']) ) ? $_REQUEST['key'] : '';

$value = (isset($_REQUEST['value']) && !empty($_REQUEST['value']) ) ? $_REQUEST['value'] : '';

session($key,$value);

}

```php
function check_login(){
if (!empty($_SESSION['user']['id'])){
return true;
}else{
return false;
}
}

还有这里写入的,我们就可以自己构造出相应的变量,从而达到未授权登录的目的。

记一次对Tp二开的源码审计(Php审计)


番外

其实在TP3.2.3中,还有一种情况,可以直接调用Dispaly。

  • 记一次对Tp二开的源码审计(Php审计)


    当ThinkPHPLibraryThinkController.class.php中的Display为Public的情况下(默认为Protected),可以从前台控制器中直接调用Display造成执行任意代码,当然一般情况下遇不到,不过如果当一个后门还是挺好用的。


    protected function display($templateFile='',$charset='',$contentType='',$content='',$prefix='') {
    $this->view->display($templateFile,$charset,$contentType,$content,$prefix);
    }



记一次对Tp二开的源码审计(Php审计)

  • 总结
    如果遇到TP二开的系统,确认版本,找到控制类,结合前辈们的经验,站在巨人肩膀上对其进行审计,要是类中的代码没问题,我建议尝试寻找Tp的0day(好像某个大佬手上有Tp3.2.3的代码执行)。


本文始发于微信公众号(None安全团队):记一次对Tp二开的源码审计(Php审计)

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: