前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JS逆向:D象滑动验证码加密分析

JS逆向:D象滑动验证码加密分析

作者头像
前端小tips
发布2021-12-08 17:08:13
2.8K0
发布2021-12-08 17:08:13
举报
文章被收录于专栏:前端文章小tips

前言

好久没发文章了,最近一直在忙工作和一些零零散散的事,逆向碰的比较少。。也是没什么素材,毕竟我已经码前端有一段时间了~~这次就带来个D象的简单分析吧。ding象、shu美、ji验、yi盾等等。。这些专业的验证码反爬,可以说是非常毒瘤了(虽然我们在他们眼里也是毒瘤,就互相伤害呗。。),各种验证码的花样也是层出不穷。有空想学学深度学习,断断续续也有一阵子了,连个完整的点选还没写出来,他居然搞出了这么多花样了。。。

这里有一些验证码还是有难度的。。。至少我这种渣渣水平是想不到解决办法。一时也想不起哪个网站在用D象,所以直接用D象官网示例入手吧。

开干

先打开Fiddler,走一遍完整流程,看看都有什么参数需要找。

倒着看,首先是这个v1的:

响应是返回success:true和token,就是最后的验证请求了。参数。。

哎好大一坨,就不能像某盾一样搞一小段吗。。看着都头大。这个ac不用猜,肯定是和轨迹相关的,这么长不可能是别的。不过当初我看见它的时候,看见前面1914#心头一紧,让我想起了被140#,也就是某里的UA支配的恐惧。。这里应该和他同行们差不多,好多都是可以写死固定的。那就换个浏览器再抓一次看看:

除了ac以外,sid、aid、x、y也都是变化的。首先是sid:

图片地址也在这里了,请求中又是一大坨参数,不过仔细观察参数都是一样的。x、y、aid暂时没有找到。 顺手搜了下ak,这个请求应该也是一个重要的请求。

ak,JS里的,这个是可以直接写死的,和验证类型有关:

大概就是这些东西了。重要的请求:c1(第一次验证环境)、a(获取验证图片)、v1(请求验证结果)。参数:param、ac、aid、x、y。 按照顺序来呗,先从c1开始走一遍。

下个XHR断点,刷新:

这个混淆。。好吧看着是有点难受。跟着调用栈一步步找,走到这里的时候

就是这了。

是对这个对象处理而来的。 下断点,清cookie继续刷新。。。跟到这个n.ZqRHlZD里看看:

。。。算了,我还是用AST先还原一下吧。AST还原的代码在最后面讲,这里先走逻辑。还原后也就是这个方法:

也就是对r里的每个参数循环处理:

传到M中:

进行一些位运算,直接扣就行了。最后得出来的t:

再把t传到前面那个P的方法群里,拼接上version版本号+“#”就是param了。

这个地方如果你觉得他这么写比较迷惑。。可以自己写个示例。

(0, func)()等价于func()。

P.encode方法依旧是位运算。这个方法就很清晰了,然后我们向上找r是哪来的,这个r里的东西,除了lid我们目前不知道以外,其他的都知道。于是不断的下断、调试,找到了这里:

在这里下断,再刷新向上找。

不方便看,去反混淆好的代码里对照着看。

I的话,各种特征显示他就是Cookie..所以这里的逻辑是,先到Cookie里找Lid,也就是

这个Cookie,有就直接返回,否则生成一个。

再经过下面的方法加密,这段代码也非常简单,略过。第一次验证就结束了。 接下来请求验证码图片。initiator直接定位

就是他,下断!

顺着往上找:

Very EASY,下一个。

可以看到验证码图片格式是webp,图片也是做了切片混淆的:

如果不知道啥是webp,可以百度查查。

查了半天不知所云,这句是重点了。可以用canvas导出,也就是可以在前端对图片进行修改。 我们去看看他怎么还原的。依旧是追initiator,因为这里是对响应处理,所以要找靠后一点的位置,最终发现这里十分可疑:

又canvas又math,是不是非常像,下断!跟了一会没什么收获。。于是继续向上不断的找,这里各种异步很恶心。

然后找到了这里。这个32位数组有一点点惊喜。。因为他就是正确的切片还原顺序。他是从一个变量r来的,r是什么?

明白了吗。然后对图片切割还原的代码,其实在上面已经找到了,就是那个canvas所在的整个代码段:

这里可以看看他的逻辑,真正去做的时候也尽量不要用js搞。。。 最后是验证,也就是轨迹了。还是initiator,xhr断点也可以,找到这里下断,不解释原因了,参数都在这。

进到这个JS里,接下来要去研究他的混淆了。

依旧AST,这里我自己尝试写了一份,效果不大好,替换之后验证过不了,于是找了一份大神写的来用了。

还原之后还是相当清晰的。我们来看一下大神是怎么写的吧。为方便理解,我加了一些注释:

这段代码是针对数组类型的字面量混淆,比如下面这种:

这个r啊,t啊实际就是最上面的自执行函数传进来的参数:

两个大数组:

然后下面这段,也是处理字面量,这里做的非常好的一点是根据作用域也就是binding.constantViolations判断该节点值是否被修改过,如果被修改过则不对该节点修改。binding.constantViolations会返回对该节点的修改情况。

这一段是对所有的字符串混淆还原,不得不说这里我没想到居然可以用一个插件直接搞定,D象的字符串混淆函数还是很多的。

处理这一类的混淆:

非常大胆,且有效。其余的大家可以自己去看看,大佬的github地址:https://github.com/daisixuan/dingxiangAST/blob/main/dx.js 然后我们把还原好的用fd替换:

这里URL是会变的,所以用正则。 autoresponser操作一波以后你会发现:

嗯?报错了?此时你可能会首先怀疑是代码出了错,但是仔细看看就会发现,不是代码的问题。是一个同源跨域的问题。我们看一下他正确的请求是什么样的:

再看看我们替换的:

其实就是差了一个头。在浏览器中,加载JS代码是不受跨域限制的,所以也就有了jsonp这种钻空子的跨域方式。但是这里是一个标准的JS,为什么会出现这个问题?其实,加载非当前域名的JS不受跨域限制限通过script标签加载,他可能用了一些奇奇怪怪的方式去加载这个JS,让我们不能顺利的替换响应。所以这里,我们要么改响应头,要么继续改代码。我查了一会资料,并没有找到怎么给fd添加响应头,于是乎。。

你既然是这两个域名不一样,我就改你的代码让你变成一样不就完了。反正我的fd可以构造任意请求的响应,哪怕是不存在的。搜green,找到这里:

把URL改成这样:

再构造一个rule:

现在知道为啥前面那个我要用正则了吗,哈哈~完活,清缓存,刷新。

这个getUA,是返回已经生成好的UA,ua根本不是在这里生成的。需要在其他地方找找。反正js已经被我们反混淆了,直接搜ua就好了。出来的结果不多,可疑的地方也只有这里了:

感觉跟之前param的套路很像:

跟着调用栈往上走,验证浏览器指纹了:

在上面一行一行的往下走,验证不同的浏览器信息:

这些都走完以后,再移动鼠标。他又断下来了,这里就来到了生成轨迹的地方了。D象绑定了很多鼠标事件,每次鼠标动都会生成一小段密文,最后加在一起就是完整的ac:

他取了鼠标事件的ClientX、ClientY,与浏览器的scrollLeft/Top做计算得到PageX、PageY:

下面那几个bs也是加密的方法,

绑定鼠标事件的地方有很多,真正的做滑动轨迹验证的地方是这里:

移动鼠标不断的向sa里push轨迹,至于加密前的是什么,不必太在意。。本身他也更改过数据,要拿到真正的轨迹的话还是要通过hook。

这里代码就在我本地,所以我也就不废那力气了,直接改代码打印出来。。分别打印出时间,X,Y:

这个时间有点怪,不过他既然能过,也就没啥说的了,可能是也有其他事件走了这个方法:

最后就生成了很多的这样的不可见字符数组。。

再加密做处理拼到ua中去。 所以,这些东西是重点。。。都要按他给的监听上。

后记

据说顶象的算法是每天更新2次,所以想扣算法去解决也可以,需要找出每次他改变的地方,不过是否可行不知道,毕竟我这边没有业务上的需求,只是自己找找玩玩,也就没有细抠每一行代码。不过大佬们都是补环境模拟事件监听来调用的,应该是补环境调用比较方便吧。具体大家可以试一试。这次就到这里了,后面分析的有点毛草,没有每一行都细看,这些监听都是一个套路,补对东西就可以了,细心调试,不行就hook,还不行每个生成ua的地方都插桩。目前看D象的JS难度还好。这次从AST上学到了不少知识,看来我的AST水平还是太弱了。

本文分析过程仅供学习交流,并无任何个人以及商业或其他用途。如有不慎侵权,请联系我删除。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
作者已关闭评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 开干
  • 后记
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档