爬虫网络请求之JS解密四(中国裁判文书网下)

-前言:

之前对中国裁判网文书网关于JS加密过程进行了详细的讲解,但是还留下了一些问题,关于文书ID和RunEval的加密还未解开,这里分开上下来讲,也是因为最后这边关于文书ID的解密会比之前参数加密要复杂和麻烦一些,上下并不关联,所以即使单看这一章也没有问题。

一、介绍

我们上一章爬虫网络请求之JS解密三(中国裁判文书网上)讲到获取到网页List中文书ID后,或者打开裁判文书网抓到的数据报文找到获取list数据的接口返回的数据,可以看到如图1-1所示:

图1-1 获取到的RunEval与文书ID

我们能得到的就是一个RunEval的参数和加密了的文书ID,而我们需要的文书ID应该是如图1-2所示:
图1-2 DocID

真实DocID是有数字加字母和‘-’组成,所以我们需要想办法加密获取到的文书ID

二、页面分析

我们先在网页上找到链接获取位置,发现如图2-1所示:


图2-1 DocID加密位置

我们发现在一个id=dataItem1的div标签中属性key为我们获取到的DocID密文,在下面有一个点击触发的JS函数,函数名Navi。所以我们需要获取Navi的JS代码才能清楚,如何解密DocID。

三、JS解密

我们同样通过浏览器的抓包发现在Lawyee.CPWSW.List.js下发现Navi函数,代码如下:

function Navi(id,keyword){
    var unzipid=unzip(id);
        try{
                var realid=com.str.Decrypt(unzipid);    
                if(realid==""){
                  setTimeout("Navi('"+id+"','"+keyword+"')",1000)}
                else{
                   var url="/content/content?DocID="+realid+"&KeyWord="+encodeURI(keyword);
                    openWin(url)
                        }
                                  }
         catch(ex){
                setTimeout("Navi('"+id+"','"+keyword+"')",1000)}
              }

Navi函数定义中我们可以看到里面定义了一个url,url="/content/contentDocID="+realid+"&KeyWord="+encodeURI(keyword)
其中DocID=realid,我们读这个代码知道,realid=com.str.Decrypt(unzip(id)),id获取位置在这个js文件中找到如图3-1所示:


图3-1 id定义位置

id就等于dataitem属性中key的值,这就如我们想的一样,我们获取到加密的文书ID就是这里的id参数。所以我们只需要得到com.str.Decrypt和unzip函数就可以解开Navi加密的DocID。
我们接下来找unzip函数定义位置,在数据报文/Assets/Js/pako.min.js中找到我们要找的函数,代码如下:

    function unzip(b64Data){
    var strData;if(!window.atob){}else{}
    var charData;
    if(!Array.prototype.map){}else{}
    strData=Base64_Zip.btou(RawDeflate.inflate(Base64_Zip.fromBase64(b64Data)));
    return strData
    }
    var com={};com.str={_KEY:"12345678900000001234567890000000",_IV:"abcd134556abcedf",
    Encrypt:function(str){var key=CryptoJS.enc.Utf8.parse(this._KEY);
    var iv=CryptoJS.enc.Utf8.parse(this._IV);var encrypted="";
    var srcs=CryptoJS.enc.Utf8.parse(str);encrypted=CryptoJS.AES.encrypt(srcs,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7});
    return encrypted.ciphertext.toString()},
    Decrypt:function(str){var result=com.str.DecryptInner(str);
    try{var newstr=com.str.DecryptInner(result);if(newstr!=""){result=newstr}}catch(ex){var msg=ex}return result},
    DecryptInner:function(str){var key=CryptoJS.enc.Utf8.parse(this._KEY);var iv=CryptoJS.enc.Utf8.parse(this._IV);var encryptedHexStr=CryptoJS.enc.Hex.parse(str);var srcs=CryptoJS.enc.Base64.stringify(encryptedHexStr);var decrypt=CryptoJS.AES.decrypt(srcs,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7});
    var decryptedStr=decrypt.toString(CryptoJS.enc.Utf8);
    var result=decryptedStr.toString();try{result=Decrypt(result)}catch(ex){var msg=ex}return result
    }};
    function iemap(myarray,callback,thisArg){
    var T,A,k;if(myarray==null){throw new TypeError(" this is null or not defined")}var O=Object(myarray);var len=O.length>>>0;
    if(typeof callback!=="function"){throw new TypeError(callback+" is not a function")}if(thisArg){T=thisArg}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue}k++}return A};

这里的函数很重要,因为很多东西只能猜,我们能看懂的是这里有一个unzip函数定义,下面有一个com={},定义了一个字典类型(dict)参数com,它有两个个默认值_KEY、_IV。其中_Key为我们需要解密DocID用的秘钥,另一个_IV应该是解开KeyWord参数的秘钥,但是我们这里只需要DocID就可以了,所以只需要这个_KEY,这里有个坑,一定要留意,大家如果用这里的_KEY作秘钥,即使最后获得了解密方法也无法解出来DocID ,因为这里给的秘钥是一个默认密钥,只能解最开始默认的那一页。
同样我们需要改写这里的函数,我们知道com.str下面定义了Encrypt,Decrypt,DecryptInner函数,并且传入了参数this._KEY,我们在这些函数头增加新的参数str_key,这样来传入我们获取的秘钥。改写如下所示:

    function unzip(b64Data){
    var strData;if(!window.atob){}else{}
    var charData;
    if(!Array.prototype.map){}else{}
    strData=Base64_Zip.btou(RawDeflate.inflate(Base64_Zip.fromBase64(b64Data)));
    return strData
    }
    var com={};com.str={_KEY:"12345678900000001234567890000000",_IV:"abcd134556abcedf",
    Encrypt:function(str,str_key){var key=CryptoJS.enc.Utf8.parse(str_key);
    var iv=CryptoJS.enc.Utf8.parse(this._IV);var encrypted="";
    var srcs=CryptoJS.enc.Utf8.parse(str);encrypted=CryptoJS.AES.encrypt(srcs,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7});
    return encrypted.ciphertext.toString()},
    Decrypt:function(str,str_key){var result=com.str.DecryptInner(str,str_key);
    try{var newstr=com.str.DecryptInner(result,str_key);if(newstr!=""){result=newstr}}catch(ex){var msg=ex}return result},
    DecryptInner:function(str,str_key){var key=CryptoJS.enc.Utf8.parse(str_key);var iv=CryptoJS.enc.Utf8.parse(this._IV);var encryptedHexStr=CryptoJS.enc.Hex.parse(str);var srcs=CryptoJS.enc.Base64.stringify(encryptedHexStr);var decrypt=CryptoJS.AES.decrypt(srcs,key,{iv:iv,mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7});
    var decryptedStr=decrypt.toString(CryptoJS.enc.Utf8);
    var result=decryptedStr.toString();try{result=Decrypt(result)}catch(ex){var msg=ex}return result
    }};
    function iemap(myarray,callback,thisArg){
    var T,A,k;if(myarray==null){throw new TypeError(" this is null or not defined")}var O=Object(myarray);var len=O.length>>>0;
    if(typeof callback!=="function"){throw new TypeError(callback+" is not a function")}if(thisArg){T=thisArg}A=new Array(len);k=0;while(k<len){var kValue,mappedValue;if(k in O){kValue=O[k];mappedValue=callback.call(T,kValue,k,O);A[k]=mappedValue}k++}return A};

改写完后,我们需要做的就是找到之前讲的秘钥_KEY,这个也是解开DocID的关键。
我们回忆之前获取到图1-1中数据报,除了文书ID外还有一个参数RunEval,这个就是我们需要的用来解开_KEY的关键。
在Lawyee.CPWSW.List.js文件下也就是找到Navi函数定义那,检索RunEval会发现如图3-2所示:

图3-2 RunEval参数

之前也是在想这个参数有什么作用,每次请求一次Listcontent都会有一个新的RunEval值,所以怀疑这里会是KEY,这也就是需要靠点直觉,毕竟这么多js文件 也不能全看明白。如果你能找到这里,会看到它会用到unzip(RunEval),我们继续用谷歌控制后台(console)运行这一步。发现如图3-3所示:
图3-3 unzip(RunEval)

这里发现$hidescript=string,fromCharCode()函数,string,fromCharCode()作用是接受一个指定的 Unicode 值,然后返回一个字符串。里面全是一个加密的东西。这个就是使用了JSFuck的加密手段,只用六个字符 [ ] ( ) ! +来表示一段代码,据说是黑客为了防止js注入代码被过滤所开发的。附上源码地址jsfuck源码git地址 感兴趣可以去看看。这里被加密了。
这里其实有jsfuck之外,还进行了一些额外的操作,如果单独运行这段代码,会发现只有一小部分代码,如图3-4 所示

图3-4 直接运行返回jsfuck代码

这里其实就是返回了$hidescript的值,这里jsfuck后半段代码,如图3-5所示:


图3-5 jsfuck后半段代码

在jsfuck中_="constructor"; _ [ _ ] [ _ ]()就是执行一个匿名函数,后面有很多$hidescript混在jsfuck代码中,我们其实只需要翻译出执行的匿名函数,提取这段代码,分为两部分,第一部分得出$hidescript的值,第二部分代码中用第一部分得出$hidescript的值替换所有$hidescript,同时去掉最末尾括号。最后运行并返回被隐藏的js代码运行结果,如图3-6所示:


图3-6 隐藏js代码运行结果

这样我们就发现了com.str._KEY,然后我们改写代码Navi函数,加入我们解密的_key。

function Navi(id,str_key){
    var unzipid=unzip(id);
    var realid=com.str.Decrypt(unzipid,str_key);    
    return realid
}

将我们解开的_Key带入,加入我们得到的一段DocID密文进去,运行结果如3-7所示:


图3-7 DocID密文解密

这里我们关于DocID的解密工作就完成了( ^ - ^)~!

结语:

关于裁判文书网的js内容就全部总结完了,我之前写的裁判爬虫网络请求之JS解密裁判文书网上,一直被简书网管给锁定发不出来,不知道是不是写了代码原因,所以这里也就不贴我的测试代码了。写关于js解密的初衷也只是总结自己对JS加密研究和解密手段并分享一些心得,感兴趣的朋友一起探讨和学习。并没有想让大家都去爬这个网站。所以一直也没有写一个完整的爬虫代码出来。还是那句话,仅供学习参考,切勿用于商业用途。

如果您喜欢我的文章,请关注或点击喜欢,您的支持是我最大的动力 ^ ^~!
仅供学习参考,切勿用于商业用途
转载请注明作者及其出处

黑羊的皇冠 简书主页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350