FollowWeChat公众号:BrotherKCrawler,continuetosharetechnicaldrygoodssuchascrawleradvancement,JS/Androidreverseengineering!Itisdeclaredthatallthecontentinthisarticleisforlearningandcommunicationonly.Thecapturedcontent,sensitiveURLs,anddatainterfaceshavebeendesensitized,andarestrictlyprohibitedfrombeingusedforcommercialorillegalpurposes.Otherwise,allconsequencesarisingtherefromhavenothingtodowiththeauthor.Infringement,pleasecontactmetodeleteimmediately!逆向目标目标:某投资领域SAAS系统PEDATAMAX资讯,返回结果加密主页:aHR0cHM6Ly9tYXgucGVkYXRhLmNuL2NsaWVudC9uZXdzL25ld3NmbGFzaA==接口:aHR0cHM6Ly9tYXgucGVkYXRhLmNuL2FwaS9xNHgvbmV3c2ZsYXNoL2xpc3Q=逆向参数:请求返回的加密结果,data:"L+o+YmIyNDE..."抓包分析我们Onthehomepage,clicktoviewall24-hourinformation,andpulldown,theinformationisloadedintheformofAjax,weselectthedevelopertoolXHRtofilter,itiseasytofindalistrequest,andthereturnvaluedataisastringofencryptedstrings,Idon’tknowwhatexoris,butitmaybeusefullater,tsisatimestamp,asshowninthefigurebelow:theparametersinPayloadarenothingspecial,justsomepageturninginformation,let’slookattherequestheaderagain,payattentiontoCookieandHTTP-X-TOKENtwoparameters,accessingthispagerequiresaloginaccount,generallyspeaking,cookiesareusedtoidentifydifferentusers,butaftertestingbyBrotherK,itwasfoundthatinthiscase,theHTTP-X-TOKENparameterisusedtoidentifyItisuser’s,soyoudon’tneedcookies.Let’sjustmentionit.WeoftenseeHm_lvt_xxxandHm_lpvt_xxxincookies,whichareusedforstatisticsofBaiduallianceadvertisements,andhavenothingtodowithcrawlers.加密逆向我们注意到返回的是一个字典。得到加密数据后,必然有一个取值的过程,所以我们直接搜索key,exor的搜索结果只有一个:这里的e.data就是返回的字典,e。data.data,e.data.exor依次取加密值和exor,这里可以猜到是取出加密值进行解密操作,我们也在这个函数的最后打了一个断点,可以看到这段代码是执行完之后,data的值是否变成明文:不出所料,Object(p["y"])(e.data.data,e.data.exor)就是解密函数,Object(p["y"])其实就是调用M方法,跟进看:传入的t和n分别是加密后的值和exor,最后返回的JSON.parse(c)是解密结果:关键代码:functionM(t,n){vara=L(Object(s["a"])(),n),r=Y(B(t),a),c=o.a.gunzipSync(e.from(r))。toString("utf-8");returnJSON.parse(c)}函数一一推导,就不简单说了。其中,Object(s["a"]),当你选择它的时候,其实是调用了c方法,后续的c方法其实是取了loginToken,也就是我们前面分析的请求头中的HTTP-X-TOKEN,其中包含您的登录信息。扩展知识:window.localStorage属性用于在浏览器中以键值对的形式存储数据。localStorage类似于sessionStorage,不同的是localStorage中的数据可以长期保留,不会过期,直到被手动删除。sessionStorage中的数据只保存在当前会话中,关闭窗口或标签页后会被删除。再往下看,有o.a.gunzipSync(),先放着,先看传入的参数e.from(r),跟进看可能看不到的,直接对比r和e.from(r),你会发现都是Uint8Array的数据,一模一样,如下图所示:我们看一下o.a.gunzipSync(),其实调用的是chunk-vendors.js中的匿名函数。不懂这个JS也没关系。我们注意到chunk-vendors.js里面有14万多行代码,再加上这个奇怪的名字,什么模块供应商,不难想到这是系统或者第三方生成的JS,在其实它是在构建vue应用的时候创建的对于我们爬虫工程师来说,大致理解为类似jquery.js的东西是可以的。我们一般不扣jquery.js里的代码,这个chunk-vendors.js也不可能傻傻的去扣。让我们关注这个函数的名字,gunzipSync。其他的我不知道,但是如果你知道zip,你可以认为它应该与压缩有关。看不懂也没关系。随便百度大法:这个直接给出了nodejs中的实现方法,使用的是zlib模块,随便找个例子看看用法:varzlib=require('zlib');varinput="Nidhi";vargzi=zlib.gzipSync(input);vardecom=zlib.gunzipSync(newBuffer.from(gzi)).toString();控制台日志(分解);进一步研究可知,zlib.gunzipSync()方法是zlib模块内置的API,用于使用Gunzip解压数据块。传入的数据可以是Buffer、TypedArray、DataView、ArrayBuffer和string类型。在官方文档中,我们可以看到更新历史。v8.0.0之后,传入的数据支持Uint8Array:结合之前的r值所以在nodejs中,直接将r值传入zlib.gunzipSync()方法即可,扣除使用的L、V、B三个方法,然后配合zlib库重写。获取解压数据:functiongetDecryptedData(encryptedData,exor,loginToken){vara=L(loginToken,exor);varr=Y(B(encryptedData),a)vardecryptedData=zlib.gunzipSync(r)。toString();returndecryptedData}完整代码GitHub关注K的爬虫,继续分享爬虫相关代码!欢迎加星!https://github.com/kgepachong/下面只是演示了部分关键代码,不能直接运行!完整代码仓库地址:https://github.com/kgepachong...JavaScript加密代码/*=====================================#@Time:2021-12-31#@Author:WeChat公众号:K哥爬虫#@FileName:main.js#@Software:PyCharm#=====================================*/varzlib=require('zlib');functionL(e,t){如果("1"==t)返回[7,65,75,31,71,101,57,0];对于(varn=[],a=0,r=t.length;a
