灰产-如何破解请求验签(下)
写在前面
再来个前情提要:灰产-如何破解请求验签(上)
以下都是情节模拟,并非具体情况,请细加甄别
阿哈!Showmak……啊不,是新的 Sign 替换后不久就,两周左右就又被破解了呢——
“我们新的加签,可是从多个随机数池取值生成的 sign1,然后把sign1和多个参数混合在一起按时间戳不同取模排列生成的sign2,怎么可能……”
啊,虽然很想吐槽这反派一般被反击了感叹自己部署被打乱了的感觉,但是来不及为已经逝去的 sign2 感到悲伤了,接下来赶到战场的是……
是我这个苦力!
我打灰产?真的假的?要上吗?
总而言之
总而言之,在解释了旧 Sign 是怎么泄露的后,调查新 Sign 是怎么泄露的这个任务又又又落到我这里了= =,已经不想吐槽了
实现漏洞
“怎么实现的……额,实际上我们等于是接了一个生成库,你可以理解为类似SDK,里面有各种 Sign1 和 Sign2 的实现方式,什么移位啊取模啊都多久前的了,我都快忘了,你想看的话文档给你你可以看一下”
“有没有可能是这个实现的模块泄露了或者可以被调用啥的?”
“我觉得没有吧,感觉也有可能是 Hook 了,但就不知道是怎么弄的”
然后直到最后我除了在研发显示屏上看到了一眼实现文档,我再也没看到那实现方式一眼了
摸索开始了——
首先通过请求日志我发现,灰产用到的 sign1 有一批量重复的(说好的随机池随机取呢),但是生成的 sign2 是不重复的(sign1 只作为一个参数参与生成 sign2 的计算),我们并没有对 sign1 进行校验,所以导致这个 sign1 可以在请求中被替换,重复利用。
顺带一提的是,在其他应用里很早就出现这个情况了,不是我的话都还没发现……
定向Hook
sign1 的问题因为没有校验可以重复利用解决了,那 sign2 呢?
前端没有找到泄露 sign2 计算点,因为前端都可能没用新的 Sign;
应用端源码没看到 sign2 的计算方式,因为做了较好的混淆;
……
那选择就只有一个了!
(折断拐杖)对它使用 Hook 吧!
早在 MobSF移动安全测试框架|自动化静动态app分析框架 的使用中,我就接触了 Frida,why?因为一开始装不上,并且因为种种原因(MobSF 自带证书冲突等)执行动态分析的效果很差,虽然后来还是能试出来。
扯远了,回到现在,利用 Frida 对应用进行 Hook,我是在 Genymotion 上做的,当然,由于应用配置的关系,你可能需要先:
- 进行 ARM - X86 的转换才能跑起来应用,低版本 Android 不可运行要换成高版本转译:Genymotion_A11_libhoudini
- 高版本 Android 可以开启 SSL pinning 等,需要 Magisk + TrustMeAlready :How to install Xposed/EdXposed/LSPosed + Magisk with Genymotion Desktop?
- 安装 Frida:brida从0配置
这里就要说了,为什么涉及到 Brida?
因为一开始是想用 Brida 直接 Hook 调用函数,传到 BurpSuite 直接修改请求,但是后来发现你根本不知道是哪个函数计算 sign2 ,别说改了,Hook 都不知道 Hook 谁,怎么办?
java.security.MessageDigest
还记得旧 Sign 最后的加密算法吗?SHA1-Hash
再看看新 Sign,尤其是 sign2 的样式,分明也是 SHA1!
嘛,灵光一现:不如利用 js 跟踪“java.security.MessageDigest”的调用,并输出加密入参与之后的值,js 参考:
入参值反解出来是一堆字节码,需要用 java 重新转一下回去:
1 | public class exchange { |
sign1×tamp
ok,入参也出来了,现在只剩一个问题:sign1 在入参中的位置。
其实到这里直接去遍历都可以,但是我还是采集了几份 sign1 在 sign2 生成位置与 timestamp 的关系进行比对,然后发现比对了个寂寞——差一位数的时间戳里 sign1 的插入位置可以相同的 = =:
所以不整了,收工!
写在后面
下篇也写完了,感觉好像也就这样,后续把加固啥的弄上议程吧,不然好像还有些硬编码问题也是头疼,但还要验证一下效果。
沉默,然后……事已至此,先吃(pao)饭(lu)吧
参考引用
How to install Xposed/EdXposed/LSPosed + Magisk with Genymotion Desktop?