猿人学攻防赛之第十题:重放攻击对抗分析

前言

    应该是这个系列的最后一篇了。剩下的第11题,我拿不到App,所以没办法了。。第8题深度学习/生成对应汉字图片转矩阵算乘积,略过。这第十题确实卡了我好几天,十题完全是某数的套路,出题人进行了一番修改,比如动态的地方不同,某数的$_ts和meta content是每次都变的,题目中变化的只有几个参数,不过原理还是差不多的。之前虽然有调试过某数,然而是瞎调一派的,并没有什么实质性的结果。。最终跟着大佬lin(没错就是那个第一名)给的思路找到了一些突破口。这道题如果熟悉某数的套路的话,还是会轻松不少的,否则确实会肝到人想吐。。

    这道题的话,依旧是分析一些关键点。代码我自己其实已经抠出来了,并且验证了确实有效,考虑到一些原因确实不太适合全部放出来,这样不仅会影响到一些网站,也会触及部分人的利益。

相关性知识

    算是某数的一些特性吧,也是我从各方搜集来的资料加上自己调试得到的一些点,不感兴趣的可以跳过。

  1.首先题目里用到的是某数四代加密,这个可以看加密结果的第一位数字是几,4就是4代,5就是5代,3代目前应该没有网站在用了。通过版本号可以快速了解该版本下的一些特征,只能说愿意分享某数资料的人不多,多利用互联网。。

  2.某数标志性的代码就是页面源代码中一大长串的meta与js中一大长串的5维数组。真正的某数,meta中的这段值与这个数组的内容每次刷新都会变,下面的代码也会变,但是变的只有变量名,作用还是一样的。

  除此以外,还会加载一个一堆乱码,而且相当之长的JS,这段就是后面几千行到一万多行的eval的内容,代码量视网站和版本不同而不同,这段代码一般不会变,变的话参数有可能会改变。本题里这些都是固定不变的。

  3.在首页源代码中的代码,运行会生成一个window.$_ts对象,里面是后面要用到的参数和方法,这段可以抠出来运行,只需要补少量环境。那个5维数组的作用是生成eval代码中最大的while循环的节点。

  4.四代的加密中首先会用meta的content生成一个大概200位左右的cookie,这个是假的,长度与真正的cookie相同,并且首位有代表其版本的标识,作用暂时不明,总之没办法参与url参数加密拿到正确结果。后面在while循环里得到的才是真正的cookie。

   5.请求的步骤,清掉cookie,请求主页,服务器返回80Scookie,拿到80S,进行第一次更新值,得到80T。随后每50秒更新一次80T,貌似更新的时候也会用到前一次生成的80T。并且每次加密得到的参数只能用一次。这个部分和本题基本无关,不展开谈了,相信调试过某数的也都知道。

   6.eval中会hook所有fecth、ajax等请求的方法,只要是xhr请求,发出去的时候就会添加尾缀的加密参数。这也就是请求中m的来源,如果忽略掉jquery等第三方模块,确实是不太好找。有一些网站的尾缀和业务无关,只需要单独算出尾缀参数,随便这个网站的什么url填上都可以请求。本题中,很遗憾,url会作为一个参数传入进行加密。

  如下图,很明显你这_yrx2LR的方法就特喵不是jquery的open方法。这也是这道题里加密的入口,添加url后面m的地方。

  7.怎么进到eval中调试,eval中每次的代码都不一样,直接下断再刷新是肯定不会断下来的。第一种方法,找到入口,在入口处F11或者添加debugger进去;第二种,通过一些手段让断点触发在当前、是当前运行的VM中(XHR断点或他自带的debugger或其他断点),下断,点下一页发起请求,通过这个方法下的所有断点在网页刷新之后失效。也就是想要知道他完整的流程,必须通过在进入的时候就下好断点。那么eval的入口在哪里?快速方法是在首页的代码中搜索ret,如下图

    如果你调试的话,会发现这个_$Dg,可能在你们那里他不叫这个名,所以说变量名是会变的(敲黑板),他也不一定就会在这行,位置也会相对变个几行的,这个东西就是eval,通过eval.call调用。断在到这里的时候,F11进去就行了。Hook eval应该也可以,下个条件debugger就OK。

   8.某数4代应该是6 7 8000行代码,5代一万多行代码,这里有绝大部分的代码是和加密无关的,都是在检测浏览器和系统环境,如果你够肝,够强,可以把真正的加密代码分离出来,据大大大佬所说,真正的加密代码就1000行。如果你更肝,还可以改写成其他语言的代码。。但是指纹的问题请不要忽略,某数必然会检测指纹的。

    然后就是如果你环境补的好,你也可以直接把他所有代码都拿到node中运行。传统思路本地浏览器联调或者根据报错补,对于这个集各类反爬的大成者,这么做可能要掉不少头发。最理想的方法还是让他自己把检测环境吐出来,这个地方我还在研究可行性,如果后面有进展也会发出来。

  9.某数算时间戳的办法,先是会藏在meta里一个时间戳,也就是请求这段代码时候的时间,在eval中会对meta解密,把它取出来。然后后面会取一个假时间,和meta里的时间相加 减去当前时间。这个在这道题目里也有所体现,不一样的是这个时间戳不是在eval里解密的,是在首页解密的。同时首页会有一个计时器每次调用执行的时间,如果大于12秒,你懂得。

正文 开始分析

   其实一些点上面已经说的差不多了。。。算了还是开始吧,老规矩,F12,抓。。。

    多重无限debugger,过的方法曾经整理过。这里我只推荐用hook过掉,不要试图在debugger的地方打条件断点,否则这个页面会卡到你无法想象,而且过不了多久就会爆内存。经过一番观察,爆内存的来源是首页里那段sojson导致的。我个人来讲是非常讨厌sojson这类混淆,真的是恶心,不是指什么程度上的难易与否,就是单纯的恶心想吐,你调他半天,除了让你学会一堆新脏话外没什么别的。相反某数的虽然也恶心,毕竟加密方案不在一个层面,研究某数你会学到很多。扯远了,直接贴代码了:

 m是加密参数,响应里的k是个重点,会影响后面的加密值。

 关于加密的地方,可以xhr断点,也可以Initiator,总之就是这里:

   进去以后,这里就是了。

  再跟进去以后,加密是在这里做的:

   他会组合两段值,需要慢慢调试得到。这个过程可能会非常非常非常漫长。

    第一个参数是meta值,

    第二个是$_ts,其他网站中这个值是动态生成的,这里这个值写死在最上面

    第三个和第四个就在这行代码上方。也就是这段值,其实就是固定不变的。通过这个方法拿到的这段值,长度为217,而在抓包中的m值长度为281。如果这是在你本地环境里,可以高度怀疑环境补错了,代码走了不一样的分支。但是浏览器里也这样,只能说明他还有另外一段加密参数。

     然后咋办,慢慢跟呗。跟丢了就重来。。。

    当你过了100年以后,跟到这里的时候:

    哎,这个不就是m吗,前面的一段是上面得到的第一段值,后面的就是新加入的了。看看参数,第一个779,第二个是$_ts中的_yrxQZs,也就是url,第三个长度16的数组,来源不明,第四个undefined。

    具体可以自己找下。毫无疑问这个数组是重点,他是哪来的?请出wacth面板,把这个参数填进去。断点打早一点跟着走,看他什么时候变成16位数组,什么时候就是了。先找到一个具体范围,确定了以后再进到里面找。这数组不太好找,慢慢来

     然后你就得到了所有的加密点了。既然说是动态了,哪里是动的?前面第6点说过,url会参与加密。那个16位数组生成的关键之一,就是url,其实改的也就是个页数而已。然后第9点提到的时间戳,也是一个变化的,代码里直接正则摸吧,不刷新页面这个值是不会变的。响应里返回的两个值,他这里是一个,你要切开啊。。

    与此参数有关的都是变化的。每次加密的时候,把这些变化的值替换进去就行了。既然后面的我知道了,那么第一次的是哪来的?首页里sojson还记得不?他想藏的就是重要的。

    补个结果,唯二的不得不写代码验证的一道题。。。

其余

      没了,所有重要的点都列出来了,后面的就剩肝了。代码怎么处理,第8点里二选一,第4点题目里有没有我没有验证,算是补充的一点东西。


牢骚

     工作的重心改变等原因,自己接下来将不再JS逆向上花过多精力了,最近对于职业生涯依然是很迷茫。。对某数的研究也就算是自己对阶段性学习的检验吧。写文章这种事,其实是个吃力不讨好的活,辛辛苦苦写一篇,往往要多花出几个小时,然而并不会有多少人去研究。所以也就导致了我在这阶段学习里,很难找到或者根本找不到资料。当时怀疑,这些技术这么值钱吗,都没人愿意分享分享?现在看来也并不是,很多原因。。

    快节奏的生活,很少人愿意花自己的时间研究技术。而且对于任何一个网站的分析、逆向,对普通人而言,公布出来对自己的坏处是永远比好处要多的,将来都有可能给自己不合适的行为提供不利证据,反正搞逆向的都懂。。。当然,想搞公众号或其他方式赚些外快的并不在我所指的范围内。但是技术不该是封闭性的,闭门造车的后果谁也都知道,还是该找个合适的团体一起进步才是。

推荐阅读更多精彩内容