关于前端动态调试解密签名校验的分享

admin 2024年10月7日23:23:45评论10 views字数 2428阅读8分5秒阅读模式

首先我们先来看一下,下面这张图是笔者近期测试遇到的问题,那就是程序每次生成请求都会生成signature的验签,该验签生成方式暂不可知,唯一知道的就是用一次就失效,这对测试的成本造成了很不好的影响,那么我们想要突破防护,最起码也要知道,这个signature是怎么生成的,他的算法是什么?

关于前端动态调试解密签名校验的分享

暂且忽略加密,因为实际上网站后面的内容加密部分并不多,我们主要是突破requestid、signature即可;想要知道requestid的生成、signature的生成,我们就需要对程序进行动态调试,动态调试我们建议使用google浏览器,火狐浏览器会出现卡顿......
首先F12打开调试器,然后全局搜索signature即可

关于前端动态调试解密签名校验的分享

双击选中的结果,然后代码格式化一下

关于前端动态调试解密签名校验的分享

CTRL + F 在当前app.xxx.js文件内再次搜索signature关键字,寻找我们觉得像的

关于前端动态调试解密签名校验的分享

此时,我们发现有个东西很像了

e.headers.signature = Object(u["a"])(encodeURIComponent(c.join(";"))),

我们直接在这里打断点看看

关于前端动态调试解密签名校验的分享

我们暂时无视上面的值,我们直接定位到这个代码的位置,该代码由多个函数组成,我们可以在控制台看一下他们是干什么的
首先看一下e里的内容

关于前端动态调试解密签名校验的分享

可以看到,e.headers里是没有signature的,说明此时signatuer还没来得及生成

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

继续程序(F10),观察signature

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

此时signature生成,说明我们的断点没问题;
此时回顾一下整个函数内容

关于前端动态调试解密签名校验的分享

我们拆分一下函数内容,首先是c   c现在是一个数组类型,暂时里面包含了两个内容,一个是URL一个是Requestid;这两个是怎么来的我们稍后看;
c.join(“;”)   是将两个字符串拼接,用分号分割
encodeURIComponent(c.join(";"))    其实就是将特殊符号抓换成url编码,这样json类型就变成了字符串类型了
最后一步,u["a"](encodeURIComponent(c.join(";")))     u[“a”]()是关键函数,这个函数将收到的两个字符串合并在一起进行加密,最后生出了signature这个东西,但是我们并不知道里面的算法是什么
但是看他的位数,我们可以猜测大致的算法,这里推荐大家可以去调试,也可以猜解
随便打开一个在线的sha1加密,将我们拿到的字符串放进去,发现生出来的值与调试器里的验签值是一样的,那么我们可以确定,程序是sha1加密的

关于前端动态调试解密签名校验的分享

获取到了算法,我们接下来就需要知道,c的值是怎么来的(就是URL/Request),因为该程序会根据不同的场景,即登陆前、登录后(登陆后产生token)、有body和无doby
因为我们知道,关键的参数其实就是c,恰巧我们看到了程序上面有很多的c.push 看字面也能才出来这是再往里面加参数,所以这里可以将所有的c.push打断点

关于前端动态调试解密签名校验的分享

此时重新走一遍,这一次我们将分为3个场景对程序进行调试
登陆前
登录后
存在token且有body参数
登陆前的调试,我们需要确定requsetid、url怎么来的

关于前端动态调试解密签名校验的分享

第一步,程序首先生成了一个l ,这个l 其实就是数据包请求中的requestid;大家可以跟进这个d[“w”]()函数,核心代码如下,大家如果不知道是干啥的也不要紧,现在chatgpt这么现金,大家可以直接把代码粘进去生成一个python代码就行,这个代码其实就是生成requestid的,在python中有一个标准的库,uuid库

关于前端动态调试解密签名校验的分享

此时第一个被压入的就是l 也就是我们随机生成的requestid

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

我们步过后,此时程序进入下一步

if (c.push(Object(d["i"])()),e.data && c.push(JSON.stringify(e.data))

不知道这个程序是干啥的,那么就直接放到控制台里
我们可以看出来,此时d[“i”]() 函数返回空,因为token现在是没有的
e.data() 其实就是我们的登录请求数据包体,JSON.string其实就是将数据包转换成了字符串类型
接下来进入到下一步

t.queryVal(f)t.queryVal(a)

这两步应该是判断,url参数后边有没有东西,比如说 xxx/login?id=1
有的话就会给过滤掉,t.queryVal(a) 就是拿到url

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

我们现在查看一下c的内容

此时c里有3条,分别是requestid、body、url

关于前端动态调试解密签名校验的分享

c.sort() 其实就是将c重新排序

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

我们发现此时的顺序是
url  +  requestid  +  body
对应程序的就是

t.queryVal(a)   + d[“w”]()  +e.body && JSON.stringify(e.data)

最后回到

e.headers.signature = Object(u["a"])(encodeURIComponent(c.join(";")))

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

我们可以看出来,正如我们所想的那样,那么这个时候我们就可以看到,signature生成规则如下

关于前端动态调试解密签名校验的分享

这里面没有看到token,不过不要紧,我们现将登录请求通过,然后再看看登录后的请求

登录后生成token后,我们直接略过前面的调试过程
c.push(l)
Object(d["i"])()    获取token

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

c.push(JSON.stringify(e.data)

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

c.push(t.queryVal(a))

关于前端动态调试解密签名校验的分享

一直走到e.headers.signature

关于前端动态调试解密签名校验的分享

c.sort()

关于前端动态调试解密签名校验的分享

e.headers.signature = Object(u["a"])(encodeURIComponent(c.join(";")))

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

至此,全部捋顺
sha1(URL + token + requestid + body)

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

带token、带body

关于前端动态调试解密签名校验的分享

关于前端动态调试解密签名校验的分享

写在末尾:

致谢:AirSky  

感谢来自实验室的好兄弟的指点

本文由AirSky  、Vlan911联合输出

原文始发于微信公众号(每天一个入狱小技巧):关于前端动态调试解密签名校验的分享

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年10月7日23:23:45
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   关于前端动态调试解密签名校验的分享https://cn-sec.com/archives/1938588.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息