本文最后更新于:2020 , 八月 23日 星期日, 11:37 晚上

OA - 任意文件删除

实测影响版本:通达OA V11.6(其他版本未测)

根据网上的exp直接定位到漏洞文件MYOA\webroot\module\appbuilder\assets\print.php

通达OA的文件需要进行解密才可以进行查看源码,否则是乱码

解密后,内容如下:

可以看到该页面并没有何的需要登录验证的文件包含

并且$s_tmp的并没进行任何的过滤直接带入了unlink()删除文件函数中

导致了任意文件的删除!

起始目录:/../../../../logs/appbuilder/logs/

漏洞验证:删除一个txt文件

至于文件上传,看的有点糊涂就不写了


深信服任意文件登录

  • 漏洞文件:ui/login.php

看构造进行Session前的if语句

if((isset($_SERVER["REMOTE_ADDR"]) && ("127.0.0.2" == $_SERVER["REMOTE_ADDR"] || "127.0.0.1" == $_SERVER["REMOTE_ADDR"]))
            || $docker)
        {
            //构造session
            if(isset($_GET["user"]))
            {
                $auth_value["auth_user"] = $_GET["user"];
            }
            elseif($docker)
            {
                $auth_value["auth_user"] = $username;
            }
            else
            {
                //$auth_value["auth_user"] = "SCLOUDE";
                //免密登录后,人为loginout,还是需要密码登录,url不一样
                return;
            }
            session_start();

先判断了$_SERVER["REMOTE_ADDR"]是否存在,接着判断了$_SERVER["REMOTE_ADDR"]是否等于127.0.0.2127.0.0.1以及$docker

不知道哪里出了问题,导致了$_SERVER["REMOTE_ADDR"] == 127.0.0.1为真

所以等于这个判断为永真,直接就进入到了构造session的环节

//构造session
if(isset($_GET["user"]))
{
    $auth_value["auth_user"] = $_GET["user"];
}
elseif($docker)
{
    $auth_value["auth_user"] = $username;
}
else
{
    //$auth_value["auth_user"] = "SCLOUDE";
    //免密登录后,人为loginout,还是需要密码登录,url不一样
    return;
            }
session_start();

如果存在$_GET["user"]则直接写入到$auth_value["auth_user"]中,没有进行任何的过滤

$_SESSION["auth_user_info"] = $auth_value;

也就是说用户名是直接带入到$_SESSION["auth_user_info"]中的,并且是可以控制的

调用了一些函数,但是该php中并没有定义,跟进文件开始时包含的platform查看相应函数的代码

  • ui/platform.php

user_logined_get()

有问题的if判断:条件为真,则$login_user获取登录到后台管理员的用户名

if (isset($_SESSION["auth_user_info"]["authed"]) and $_SESSION["auth_user_info"]["authed"] === true )
{
    $login_user = $_SESSION["auth_user_info"]["auth_user"];
}

先判断了isset($_SESSION["auth_user_info"]["authed"])是否存在

接着判断$_SESSION["auth_user_info"]["authed"] === true是否全等于true

这两个判断条件是有问题的

因为在login.php$_SESSION["auth_user_info"]["authed"]已经默认设置为true

所以该判断条件是为永真的,像当于直接就执行了$login_user = $_SESSION["auth_user_info"]["auth_user"];

Ps:$_SESSION["auth_user_info"]["auth_user"]是在login.php中由$_GET["user"]可控参数获取的

接着查看判断是否为超级管理员的函数

admin_login_check()

和前面函数判断一样,都是if判断出现了逻辑问题,并且用户名是可控的

即:$_GET["user"]= admin即为超级管理员权限

// login.php
header('Location: index.php');

login.phpcheck_free_loginbyscl()执行到最后,跳转到了index.php页面

  • ui/index.php

查看获取用户权限的函数:ui/platform.php文件中

发现该函数过度信任admin用户,只要是admin用户则一直为管理员

接着查看index.php获取用户权限函数后的两个if语句

$_SESSION["is_bbs_login"]login.php中已经默认设置为true

所以这个判断也是为永真状态

也就是说无论什么用户,$dev0ption['isAdmin']一定是为true的

并且user_permission设置为true,并带入到其他变量中

不再往下分析,简单的说就是判断逻辑不严谨并且用户名参数可控导致了漏洞存在!


该文章仅为自己的看法,如有错误,请告知


代码审计   PHP      PHP代码审计

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

CVE-2021-3156 Sudo提权漏洞复现
VulnHub:Me-and-My-Girlfriend-1