本文为很早之前在知乎写的,但现在流程几乎没什么变动,只是多了h5st参与登录,h5st参数百度一下就有很多教程,不再细说。


大眼一扫就一个jsep.html请求的d参数加密,和两个疑似和验证有关的请求s.html和g.html

先找d,追栈很快就找到位置

断点发现可能跟鼠标事件有绑定,鼠标一动就弹过去,直接加个log断点

发现一次滑动对应两次jseq请求,依次为focus/blur,加密前的文本并没有用到轨迹,先把这个扒下来,找eid:

在第一次请求页面时fcf请求的response中找到eid,这个请求有a, d, g三个加密参数,先记下来一会儿再看,找C(a)中的加密函数C:

再来看s和g两个请求

s请求

d = h.getCoordinate(g)

c为验证码id,请求验证码时返回

e为eid

g请求

只有一个eid,返回的是新的验证码信息,这时候发现一个问题,密码在哪传给服务器的?

修改几次输入框的密码后发现,密码每一次都是单独的发送的

展开发现这些只是埋点的日志(也很有可能是风控),并没有提交密码操作。正确滑动一次后发现是正确滑动才会提交另一条登录请求loginService

loginService

U:

简单看了下,基本没有检测环境,直接把文件复制下来,稍微补一下

本地生成结果在网页替换后发现没有问题,再看B:

使用原生JSEncrypt替换后提示账号密码错误,直接把整个文件复制下来,补少量环境即可运行

fcf请求

只剩最后一个请求就OK了,也就是开头说的response返回eid的fcf请求,共有三个参数,url中的a,请求体中的d和g

追栈发现d和g:

先看g:

再看d:

是个比较全面的环境检测,直接拉到最后:

发现还是调用的tdencrypt,根据g去构造环境就OK了,不需要大并发登录直接复制粘贴

最后看fcf请求url中的a参数

同样的tdencrypt,参数有这些:

fc为eid,初始为空,下面找fp和jtb。先看jtb:

对比后发现r的sha1加密和w结果一致,JDDSecCryptoJS sha1是原算法,其他应该也是,但是保险起见还是扣一下

最后一个参数,fp:

扣下来,简单补一下环境

总结

登录流程就完成了,简单总结一下:

第一步fcf请求拿eid,包括a, g, d三个加密参数,均为环境检测参数,都是使用tdencrypt加密,其中a内部又包括fp和jtb两个参数,fp通过(new JdJrTdRiskFinger).get获得,jtb(即jd_shadow__)通过JDDSecCryptoJS获得。

第二步init请求拿公钥,后续使用

第三步g请求拿验证码(这一步之前)

第四步s请求滑块轨迹验证以及提交账号,加密参数为d,原始文本为轨迹数组,加密方法为getCoordinate

第五步loginService请求提交密码,加密参数分别为aksParamsU和aksParamsB,U原始文本为uuid, url param, 随机数拼接,B原始文本为密码、防跨站token、盐、公钥等拼接,其中密码使用了魔改的JsEncrypt加密,入口getEntryptPwd,U和B的加密使用的魔改过的Cryptico,入口encrypte,公钥为前面init请求得到的response。

整个流程就是这样,没有说到的参数基本都能在网页或者response上找到,cookie方面简单瞄了一眼应该没什么加密,需要注意的是jseq请求,虽然没用过,但是很有可能是风控手段,尽量也模拟一下。