https://www.mps.gov.cn/n2254098/n4904352/index.html
直接访问的话,返回的是一段js代码,主要是对cookie进行赋值
直接复制出来,到控制台执行
执行的结果先不管,我们这次逆向的目标,主要是cookies中两个值的生成
其中,__jsluid_s 是第一次请求的时候服务器返回的
那 __jsl_clearance_s 会不会是第一次返回的那段js执行后的结果呢?对比一下:
1 2 3 4 5 # 执行结果 __jsl_clearance_s=1654493484.607|-1|eU3CZr0IIIZOWUJfz3vNntOeewo%3D # cookies __jsl_clearance_s=1654493484.979|0|70p4p0lk5rF59kkzj6oslUuf8Qk%3D
看来不是,如果那么简单我也不会写这篇博客了 😬
还是看一下抓包,第二次请求的时候也返回了一段js
注意到开头是一段大数组,很明显的ob混淆的特诊,先解一下混淆:
复制结果放到浏览器执行,跳到代码最后:
可以确定,就是最后的go函数,对cookie进行了修改,那就先进入函数内部加密逻辑理清
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 function _0x3ee693 ( ) { var window_userAgent = window .navigator .userAgent ; var _0x459673 = ["Phantom" ]; for (var index = 0 ; index < _0x459673["length" ]; index++) { if (window_userAgent.indexOf (_0x459673[index]) != -1 ) { return true ; } } if (window .callPhantom || window ._phantom || window .Headless || window .navigator .webdriver || window .navigator .__driver_evaluate || window .navigator .__webdriver_evaluate ) { return true ; } } ; if (_0x3ee693 ()) { return ; }
这里主要是检测是否使用了 phantom 和 webdriver的,直接不管跳过
最重要的是后面这一句,对cookie进行了修改
1 document .cookie = _0x463d2c.tn + "=" + _0x59651f[0 ] + ";Max-age=" + _0x463d2c.vt + "; path = /" ;
分析一下,_0x463d2c 是开头传入的那一个大字典,所以 tn 和 vt 的值都可以确定
_0x59651f[0] 则是由下面的代码生成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var date = new Date ();function _0x14f692 (_0x59297c, _0x117587 ) { var _length = _0x463d2c.chars .length ; for (var index = 0 ; index < _length; index++) { for (var index = 0 ; index < _length; index++) { var _0x428069 = _0x117587[0 ] + _0x463d2c.chars .substr (index, 1 ) + _0x463d2c.chars .substr (index, 1 ) + _0x117587[1 ]; if (hash (_0x428069) == _0x59297c) { return [ _0x428069, new Date () - date ]; } } } } ; var _0x59651f = _0x14f692 (_0x463d2c.ct , _0x463d2c.bts );
这一段好像没什么好讲的,就是传入 ct bts 两个参数给 _0x14f692函数 ,然后拿到返回结果,由两个地方需要注意:
substr(start, length) 主要用来截取子字符串,比如
1 2 3 4 "cxs" .substr (1 , 2 )>>> 'xs' "cxs" .substr (0 , 2 )>>> 'cx'
if (hash(_0x428069) == _0x59297c) 中 hash函数已经在字典中指定了哈希算法,这里的话就是 sha256 ,不过每次返回都是不同的,经过多次测算,网站总共使用了三种哈希算法:md5 sha1 和 sha256
代码整理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 import jsonimport refrom urllib.parse import urljoinimport execjsimport js2pyimport requestsfrom hashlib import md5, sha1, sha256session = requests.session() default_headers = { "Accept-Language" : "zh-CN,zh;q=0.9" , "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36" , "Accept-Encoding" : "gzip, deflate, br" , } session.headers.update(default_headers) def go (params ): chars = params["chars" ] if params["ha" ] == "md5" : hash_md = md5 elif params["ha" ] == "sha1" : hash_md = sha1 elif params["ha" ] == "sha256" : hash_md = sha256 def _0x179e62 (bts, ct ): char_len = len (chars) for i in range (char_len): for j in range (char_len): _0x3b8d5f = bts[0 ] + chars[i] + chars[j] + bts[1 ] hash_val = hash_md(bytes (_0x3b8d5f, encoding="utf-8" )).hexdigest() if hash_val == ct: return _0x3b8d5f _0x3d9242 = _0x179e62(params["bts" ], params["ct" ]) return _0x3d9242 def get_jsl_cl1 (html_text ): js_script1 = re.search(r"cookie=(.+);location" , html_text).group(1 ) jsl_cl = execjs.eval (js_script1) jsl_cl_s = re.search("_s=(.+?);" , jsl_cl).group(1 ) return jsl_cl_s def get_jsl_cl2 (html_text ): params_txt = re.search(r";go\((.+?)\)</script>" , html_text).group(1 ) params = json.loads(params_txt) jsl_cl_s = go(params) return jsl_cl_s def main (): url = "https://www.mps.gov.cn/n2254098/n4904352/index.html" html1 = session.get(url).text jsl_cl_s = get_jsl_cl1(html1) session.cookies.update({"__jsl_clearance_s" : jsl_cl_s}) html2 = session.get(url).text jsl_cl_s = get_jsl_cl2(html2) session.cookies.update({"__jsl_clearance_s" : jsl_cl_s}) print (session.get(url).content.decode()) if __name__ == "__main__" : main()