通达OA最近悄咪咪的更新了一次,以下所发漏洞在新版基本已经失效

超全局变量覆盖导致SQL注入

首先是全局初始化参数:


if (0 < count($_GET)) {
    foreach ($_GET as $s_key => $s_value ) {
        if (!is_array($s_value)) {
            $_GET[$s_key] = addslashes(strip_tags($s_value));
        }

        $s_key = $_GET[$s_key];
    }

    reset($_GET);
}

上面的代码会将GET所接受的参数自动注册为变量,如下demo所示:

<?php

foreach($_GET as $key => $v){
    $$key=$v;
}

echo $admin;
?>

直接在GET中传递admin:

clipboard.png

在查看如下代码:

<?php

if (0 < count($_GET)) {
    foreach ($_GET as $s_key => $s_value ) {
        if (!is_array($s_value)) {
            $_GET[$s_key] = addslashes(strip_tags($s_value));
        }

        $$s_key = $_GET[$s_key];
    }

    reset($_GET);
}
echo $_GET['admin'];
?>

假如我们走通达OA正常的流程:

clipboard (1).png

如果我们覆盖$_GET超全局变量:

clipboard (2).png

可以轻而易举的绕过GPC,那么思路有了接下来就是找调用$_GET或者$_POST传参的地方:

clipboard (3).png

这种地方很多,但是我们需要寻找未授权的地方,因为通达OA是面向过程的程序,所以只需要定位到验证权限文件,然后查找没有包含他的地方。

include_once "inc/auth.inc.php";

最后找到很多,拿一个比较简单的出来 retrieve_pwd.php:

include_once "inc/conn.php";
include_once "inc/utility_all.php";
$username = $_GET["username"];
$email = $_GET["email"];
$query = "SELECT UID,USER_ID,USER_NAME,USEING_KEY FROM USER WHERE BYNAME='$username'";
$cursor = exequery(TD::conn(), $query);

clipboard (4).png
clipboard (5).png

urldecode利用不当导致SQL注入:

go.php:

include_once "inc/session.php";
$OA_USER = str_replace(array(",", "\\\"", "\'", "\"", "'", "\t", "\\", "\\\\", "%27", "%22"), array("", "", "", "", "", "", "", "", "", ""), $OA_USER);
$APP_UNIT = str_replace(array(",", "\\\"", "\'", "\"", "'", "\t", "\\", "\\\\", "%27", "%22"), array("", "", "", "", "", "", "", "", "", ""), $APP_UNIT);
$OA_USER = urldecode($OA_USER);
$APP_UNIT = urldecode($APP_UNIT);
$query = "select MEMBER_ID from CONNECT_CONFIG where MEMBER_NAME='$APP_UNIT'";
$cursor = exequery(TD::conn(), $query);

首先使用str_replace绕过过滤危险字符:

$APP_UNIT = str_replace(array(",", "\\\"", "\'", "\"", "'", "\t", "\\", "\\\\", "%27", "%22"), array("", "", "", "", "", "", "", "", "", ""), $APP_UNIT);

然后使用urldecode解码:

$OA_USER = urldecode($OA_USER);

所以我们只需要传:

%25%252727

clipboard (6).png

当然通达OA还有其他WAF,但是因为漏洞影响暂且不提。