声明:文章内容仅供参考学习,如有侵权请联系作者进行删除。
之前写过一篇selenium自动化的思路:京东滑块
本次介绍下js逆向的思路
js逆向步骤:
通过接口获取两张验证码图片 ——> 在内存里面处理图片 ——> 通过opencv计算出缺口的距离 ——> 模拟封装滑块的轨迹参数 ——> 逆向加密轨迹的参数 ——> 加密并请求验证接口。
首先,在京东登录页面输入任意的账号密码点击登录,即可触发滑块
在F12下,随意拖动滑块,可以获取到以下3个接口
通过接口返回值可以判断出第二个接口是获取图片的接口,第三个接口是验证滑块的接口。
图片接口的bg是背景图,patch是滑块都是base64编码的
和之前不同的是网页上面的base64编码多了一个头
opencv测算滑块距离代码如下
def img_test(self, x, y):
# 以前的版本,多了一个头部的处理
# x = base64.b64decode(x.split(",")[-1])
x = base64.b64decode(x)
img_array = np.frombuffer(x, np.uint8)
img = cv2.imdecode(img_array, cv2.COLOR_RGB2BGR)
y = base64.b64decode(y)
y = np.frombuffer(y, np.uint8)
template = cv2.imdecode(y, cv2.COLOR_RGB2BGR)
res = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED)
value = cv2.minMaxLoc(res)[2][0]
# 获取的图片和显示的验证码图片大小有差
distance = int(value * 278 / 360+25)
有一个需要注意的是,js逆向里面距离是需要额外加上一个初始值的,在23-25之间。
回到第三个接口,从参数上面看,很明显d是滑块轨迹加密的参数
通过多次触发接口,我们可以发现,除了d外,c和s也是会变化的;
通过参数搜索,可以确定c是图片接口返回值里challenge的值
s 是某个接口返回值里_jdtdmap_sessionId的值
虽然e的值不变,但是值挺长的(没办法忽视0_0),后面查了下发现是cookie里面的
接下来就轮到加密d上面了
从堆栈里面寻找运行了哪些js文件,这个接口只运行一个js文件,从submit可以推测第二个可能就是我们需要的断点位置
进入里面发现过于简单,直接断点,重新触发滑块
可以知道b就是我们要封装的轨迹,前面a['getCoordinate']就是加密方法
进入加密里面
结合之前堆栈的内容,可以知道,加密都在这个文件里面,可以整个文件直接拿(也可以扣取出加密的部分⊙ˍ⊙)
通过js运行的部分
发现结构简单(这京东是把所有验证都扔给轨迹识别了是吧 Σ(っ °Д °;)っ
直接上代码
def get_slide(self, slide_value):
node = execjs.get()
js = node.compile(open('kkk.js', encoding='utf-8').read())
func_name = f'JDJRValidate["prototype"].getCoordinate({slide_value})'
keys = js.eval(func_name)
return self.sub_verify(keys)
关于滑块轨迹的模拟,这个网上的代码挺多的,我直接参考翻译了一个python的版本出来
源码底下自己拿
我来简要说下思路≡ω≡
首先,复制参数b的轨迹,这个轨迹需要正常滑动和最后来回晃动两个种
注意:晃动的轨迹x是要从0开始的,可以通过扩大F2的大小,压缩页面的大小
然后,将计算得到的距离 + 复制的正常滑动轨迹的初始距离来截取正常滑动的区间
重点,取当前时间戳前9位和复制下的正常轨迹的时间后4位,拼接成完整的时间
之后,通过复制的晃动轨迹 + 最终轨迹的值来模拟晃动;时间处理和上面差不多
结果如下
以下是源码链接