瑞数6逆向
仅用作学习研究,请遵循法律!凡造成事故者,请自行承担后果。
如果任何问题,请联系作者删除博客。
逆向地址:aHR0cDovL2VwdWIuY25pcGEuZ292LmNuL0luZGV4
我们先来看看结果
Node.js (V8)<Response [202]>Session中的Cookie: {'NOh8RTWx6K2dS': '607Qz4Eip54Bvyli5jB8dyAd_5NKO2Bbe7y3.a1pZ5DZvw6EGSVSExdGWRFvSF9Ov2zVgX5edTSSzZ55aLES3LVG'}完整URL: http://epub.cnipa.gov.cn/z5gPWiiwO6ht/2h9AIDg9eZgY.b4c45da.js<Response [200]>Session中的Cookie: {'NOh8RTWx6K2dS': '607Qz4Eip54Bvyli5jB8dyAd_5NKO2Bbe7y3.a1pZ5DZvw6EGSVSExdGWRFvSF9Ov2zVgX5edTSSzZ55aLES3LVG', 'NOh8RTWx6K2dT': '0X_oeYv0T.F..9XrRhF2RwFYZ8qbr0eW1BDNLpgftmLkxpb.7AQPwovjf.LspSXCmpBafDaoZYEYROKeLJ8x0LXKfW0j8hS43bF_2AEarNwfTsMLb2FIL6.pSrotGIVbRvrckW5mh2aUDVhIH1__xsZ0EG0UQPommpW6oJSTMFhz40nz0NjsUMeklh5RIfro8RFM5mZK_3TexS2QyE.JASyBgZOZ.Q26s_.6cGaKRa5gSgUMzG.eaEUQKqzTO3Gr_TJ2qj.0om80dy4wHoEyp.G'}瑞数6很经典的一个特征就是cookie。
第一次请求,服务器返回一个setcookie,两个js文件,html文件。
通过js文件和html里的信息,他会再生成一个cookie。携带两个cookie再去请求网站才能拿到结果。
了解完这个情况,我们直接去网页上拿到相应js文件。
无限debugger

这个无限debugger可以不管,处理起来挺麻烦的。但我们可以直接跳过。

扣js文件
删掉cookie后,打上断点,并刷新页面。

这是第一个要拿下来的文件,我们把他命名为encrypt.js

这是第二个文件,用作解密第一个js。我们命名为decrypt.js。另外观察可以发现,他是在一个文件夹里的,这个文件夹是固定的。
继续跟,拿到html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta id="K5MK4FPPNWrv" content="qxEjocu1Lmm3q3OvKPDUZgjTjXapwFtrXXBf_NyJ_Ptl4vDFXiiJH39Z6vp37lOaK4SNzZ4uYYcpLWhVCaLoXG" r='m'> <!--[if lt IE 9]><script r='m'>document.createElement("section")</script><![endif]--> <script type="text/javascript" r='m'> $_ts = window['$_ts']; if (!$_ts) $_ts = {}; $_ts.nsd = 13209; $_ts.cd = "qWwErpAltrAqcqVEqOEAmqqEqqGrWfqVqqlEcrAqcq3EruEAcqEntqWEtGGrWkVErcqVqqGmcqEnlkgqcqqEqsEAmqqEraGlWfqPquELrqGqJA9ltAGlWPGmEGEntqWVqqGqcqlnlrAqcc0ErkEAcqEQcrAqcqqEqsE_qGVTcGAzcqqntqVVqqGkEGqnlrAqq1EhmqqEqGGkWOLVqqGrcq3nlrAqcqAErsE_qGVTcaA3cqVntqEVqqGkEGqnlrAqcq3EruEAcEVTtx9rJOlcrsE6b1W_lfumGWEbm.HjyQNKmknjZ6HcA4q5CORBMsdgS0kgqAqlWaQlqyG7qERRIc3C0KyJJ2Ncpustw2pkYVSspBlTJkTOxsy3aOW7xnq.JY4lhnxdwkxDFIS28me.wUSh42rkITwAAsHgEsN8KsQLEM7BWmfI8Pfz4De7tY2QJcd6wbSNhb2SMdVBMvrXFnfz4De7KcyQJcd6wbSNhb2SMdVBMvrXFnfz4De7KmeFkGtSQUYPW0Y5RFagsTxWYVGSCv34HmrA1lvisD95iC3T8QzYFDAyH9Rz6CrSsV3Z19uSiTxpYUZn1tzvi6Z63mpVZDN61OpBQkPjVuwrYUQaJ52AMoVyJKa_ClNl3OzPUbsqhKES3sWSRdGzFv3yJVScjomipkzVJV4ThKES3sWSRdGzFv3yV0f9ZKx.pTJaUbMphKES3sWSRdGzFv3yJOJ0dORn1Vz0R0szhKNCisxfJefhYKJjpswPeufhFkNEs0vIRYJWWUldVXrcRmepJ0y9alSTHvYNwKPBADNfWuqTR.wfJD3CWbrPzC2uH2fA1mU.A2xvQkmYF4wfJD3CWbrPzC2uHPS2WDczJbp9hDT6iJECsVgCAYpsTTpnQu2OMDU4RkfuWlmURz3kqqVkJaAcjqWpMURuwkbjJOECJkA6JF7yikVcqK365OQT3AElWO1zqaL0WOqaJtquJk3araW4jOLnWOEurricsenPeH72bLYE5cevKzpxbpHFwTejXKEV6qiQqAQrqRgoqcV1Eryov29Wg3tCmcU2joDhNxPP4PNbPywxqnAf7hx3WaEJJsjBJuVZJOZuWN9cWAVEJOW0Lk3gJuAnWainV0ePJlYTptLnK2YA3OTM4YY_KbpuIssdp9TZsDxhKXfpwUxT1vg4jn0awqEorqtzqalTqG3uqbg08P2ORbQB5DyntKJ0F1dgwK9N3DRBhdzPwc2GFvAB5CNXtKl.RCh4hCJCQ1zvQiZB3CNBtCwu_1e9Ro3.3DdThCpj31zGMi0BRDNfInfbgK373DTutDUT3PSOMbALRIRzhDJzQnf2ebT0tKYORPd5Fb3NRU0LRHm7hDTXwnf._UW7MUR9tD._McS7MDgLFBw2hDS7wcfj_ba7M6l.Mbh.hCNTR1zXQdS9hDeSFDLBZCxCRcy.MKDTMCePhbNzR4YXQklXFvpPzKg0RcyjwkcTMvrPhbNBwMYXMClXFbzTzKyNFcyjwoiTMvJ7hbN0RBgBMCwLtCzGg1eB3bV.FCd4hCeNRnz.wdZBQoaXw6TGzUJfwPy63C_TQ6rLhvw0QhYuQolXwCr2zUJaQUL.wD65h6r731z0MdqBQoRbt6YjdneSQUL.wbtTQK0NQDRNh5zXwbQXwKm9zUm2wPyTQDKTQKm6hvp.h5NfMc2S3UaB_vpftUma3PdjwKQNQUy6h5TPQP2CRvgB4KNbtURX3bKTwCe6QDxjw4Y68olXQ6r2zUYu31ySw6cTwUJnhvmZR4Y0MCJ9t6J7dCVntUYjQPdXMblNwKRnh5yuQn2_RK9BgUJztUN.wndfM6Jehve6M4Y4MK9XI1fyZoW7Rox7toHTFvJShby03N9kqqmwETzYbAwIE1RUrqIDxCxoqGJMxZRJqqQuHaAr.OqqrkWorstRqaqmqGQlrIEyAVpspApMaPmCRoqvMDMgRCY6QYpaQIrzRTR6R1E2B6m2wvxLFvkZhKfG3CJfQ8LzRbNaAbYGZ17LQCJ.QKFTECzG8ngPxMe.RKpb3vRanvwnMDSGxcP9ECzG8nYRcR9cWA"; if ($_ts.lcd) $_ts.lcd(); </script> <script type="text/javascript" charset="utf-8" src="/z5gPWiiwO6ht/2h9AIDg9eZgY.b4c45da.js" r='m'></script> </head> <body></body></html><script type="text/javascript" r='m'> _$cT();</script>阅读一下这个html的结构,我们可以了解为啥要拿那两个文件。
第16行的script标签对应decrypt.js。第7行对应encrypt.js。
同时,这个html里还有个<meta id="K5MK4FPPNWrv" content="qxEjocu1Lmm3q3OvKPDUZgjTjXapwFtrXXBf_NyJ_Ptl4vDFXiiJH39Z6vp37lOaK4SNzZ4uYYcpLWhVCaLoXG" r='m'>
这个我们后面会用到,现在不清楚没关系,代理会把它测出来。
补环境
最新一代的瑞数6检测了很多环境,原型链检测也很多。补了差不多一千行(我菜,大佬轻喷),累的一批💢
这里我大致说一下,一些比较恶心的监测点。
一、文件检测
首先这两个
delete __filenamedelete __dirname藏得很深,但是你打断点能追到,加在开头就好。
二、window
这个挑一些说说,太多了。
首先是top,self。这些都指向window本身。
window = globalThis;window.top = windowwindow.self = window这里可能被检测,因为
console.log(window.top.toString())输出:[object global]正常是 [object Window]不过瑞数没检测这个,我们就不说了。
然后是对象=>window,读取属性:ActiveXObject,值为:undefined,类型为:undefined
这个很恶心,虽然是undefined,但是也要补,后面他的js会用到。
对象=>window.localStorage,读取属性:Symbol(Symbol.toPrimitive),这是一个名为 value 的函数
symbol也要补,这个套个方法省事。
window.DOMParser = function(){}window.XMLHttpRequest = function(){}window.attachEvent=function(){}//window上不该有的属性window.clearImmediate=undefinedwindow.setImmediate=undefined一一补吧,window没啥说的了。
二、函数
首先是toString检测,这个没啥说的,模拟一下即可。
对象=>createElement.div,读取属性:getElementsByTagName,这是一个名为 getElementsByTagName 的函数
返回值对着网站上即可。
console.log("createElement设置了————",tagname) if(tagname==="div"){ newdiv = new HTMLDivElement({ style:watch(new CSSStyleDeclaration({},null,"fatdog"),'div————style'), addBehavior:undefined },null,'fatdog'); return watch(newdiv,"createElement.div") } if(tagname==="script"){ newscript = new HTMLScriptElement({ parentElement: watch(new HTMLBodyElement({},null,'fatdog'),'script.parentElement') },null,"fatdog") return watch(newscript,"Document的createElement————script") } if(tagname==='media'){ newmedia = new HTMLUnknownElement({},null,"fatdog") return watch(newmedia,"Document的createElement————media") } if(tagname==="canvas"){ newcanvas = new HTMLCanvasElement({},null,"fatdog") return watch(newcanvas,"Document的createElement————canvas") }getItem: function(key) { console.log('localStorage.getItem获取', key); if(key==="_$rc"){ return ".UKKtb.H2PscONI9xfCccezbS1Nca.q9cl2b8S_qE0DqrTPJ4xMjeFEmtZ9rhFa6nqIYgKpkoA55_BxyWVLCNTw3IN7AYgX5U7Jxy04Pwjiz3TbLGNN72ji8bl0Hf18X_rW_4O0FFjPEarj7WVOSQMpZ0_BhOUMieKWbcGEkVRYoVQydrKHfiIqZRGOxljGdxBw36SHGCjOMjpbf8hwzvcTxEvVP5NIXMiJzB96a.7qjFu.pvESgvQ2ps19Kf5s0jt2QdqNSTnPMVmD1MGxs6PnW5fN2zHiVXD4MhszlQ72B0NEiAN.xR5mxVltC6fbxuw1Rgr7q0h0cEQQxpUhxDNqR6rHd_cCDhFa70JrH.I3MW4GhOYNHKGODp1KGzIH8A7DR.VBf8QD8oyjZAHZnTkLBohlaODnLhST4lf9wqhU3Sh48vVhCbnOxje2zw8mN7p52fIwBPuYTQPp6kMxBfijLFwscFx7w5Nxpsx2JQCa055nm6w2hRuW1zLQ8LdDWfB3ctuqOaKDc.XDkdtx2HBy27rQ4IHCrE_T7W.O8infAVOiwIweip0MamzvSRqrbfVuvEO9t.X.mXGRu1keI_crdI0Klqa10rbMEUndJ5feDOzNZMI7gOLBa43DcafK5hkFLcEK9Plmob70q39N_WHlgASgs7ZWpsbSVt0ZqAgPfhSR9BZ7rYwnIQG9pw6Gls4rxDtejoQvj6xnVeGsOoXEQPuenJaaIY6TYbyox22Yt7ZTBmixbtcIq0OFAei0uV3Y_hq" } if(key==='$_YWTU'){ return "Joe4xOav_FW3MoVBdxofXRWV7wZXvJLeKqGfP3J6mSq" } return this[key] || null; }, setItem: function(key, value) { console.log('localStorage.setItem设置', key, value); this[key] = String(value); }, removeItem: function(key) { console.log('localStorage.removeItem删除', key); // delete this._data[key]; delete this[key];
},都得补在原型链上,以防万一。
Document的getElementById访问———— K5MK4FPPNWrv对象=>window,读取属性:__meta_content,值为:undefined,类型为:undefined还记得K5MK4FPPNWrv这个嘛,这个就是之前说的content。
网站通过getAttribute拿到这个。
getElementById:function(id){ console.log("Document的getElementById访问————",id) if(id==='K5MK4FPPNWrv'){ return { tagName: 'META', nodeName: 'META', nodeType: 1, id: 'K5MK4FPPNWrv',
getAttribute: function(name) { console.log('meta.getAttribute:', name); if (name === 'content') return window.__meta_content || ''; if (name === 'r') return 'm'; return null; },我们在html上把他解析进来。
三、location
对象=>window.location,读取属性:protocol,值为:http:,类型为:string对象=>window.location,读取属性:port,值为:,类型为:string对象=>window.location,读取属性:pathname,值为:/Index,类型为:string对象=>window.location,读取属性:href,值为:http://epub.cnipa.go...,类型为:string对象=>window.location,读取属性:hostname,值为:epub.cnipa.gov.cn,类型为:string对象=>window.location,读取属性:host,值为:epub.cnipa.gov.cn,类型为:string对象=>window.location,读取属性:hash,值为:,类型为:string没啥说的,缺啥补啥。
四、navigator
这个是个大坑。node22新增了navigator,导致我们toString()覆盖不了,所以会出现这种情况。即便你重写了tostring也是一样的结果。
console.log(navigator.toString())[object Object]
正常浏览器则是:[object Navigator]解决方案
delete globalThis.navigator;提前干掉再重写tostring然后跟着补就行,比较恶心的就是下面几个,有原型检测,但是并不需要补的太全。
对象=>navigator.mimetypes,读取属性:Symbol(Symbol.toPrimitive),这是一个名为 value 的函数对象=>window.navigator,读取属性:mimeTypes,值为:[MimeTypeArray Insta...,类型为:object对象=>navigator.mimetypes,读取属性:application/x-shockwave-flash,值为:undefined,类型为:undefined五、history
对象=>window,读取属性:history,值为:[History Instance],类型为:object这个也被检测了。
六、其他
对象=>window,枚举属性,共 246 个属性:Object, Function, Ar...对象=>window,读取属性:chrome,值为:[object Object],类型为:object对象=>window,读取属性:innerHeight,值为:937,类型为:number对象=>window,读取属性:innerWidth,值为:1920,类型为:number对象=>window,读取属性:outerHeight,值为:1080,类型为:number对象=>window,读取属性:outerWidth,值为:1920,类型为:number还有一堆,就不说了。照着补就行。恶心的都说过了。
七、python调用
from requests import sessionimport subprocessfrom functools import partialfrom lxml import etree# 解决 Windows 编码问题subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')import execjsprint(execjs.get().name) # 确保能正常运行session = session()
headers = { "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7", "Accept-Language": "zh-CN,zh;q=0.9", "Cache-Control": "no-cache", "Connection": "keep-alive", "Pragma": "no-cache", "Referer": "http://epub.cnipa.gov.cn/Index", "Upgrade-Insecure-Requests": "1", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/148.0.0.0 Safari/537.36"}cookies = { ".AspNetCore.Antiforgery.VJ9V3gR6RkM": "CfDJ8GGednQOsIdApgbnJzxrfmpElwAs9LpOHnRvKT9pguad0a86F-_7Ely7LiH0-hqNexhyJvRoAd4N6wWRbLLLRMqN4DzjAfibTTyA8CZSReecclfaeTYjnZMuBKdOaMedO8NvAkgKh3EevB29uhuuIrQ", "WEB": "20111132", }old_url ='http://epub.cnipa.gov.cn'url = "http://epub.cnipa.gov.cn/Index"response = session.get(url, headers=headers, cookies=cookies, verify=False)html = response.text# print(response.text)print(response)print("Session中的Cookie:", session.cookies.get_dict())# 解析HTMLtree = etree.HTML(html)
code = ''# ✅ 用XPath精确提取content = tree.xpath('//meta[@id="K5MK4FPPNWrv"]/@content')if content: content = content[0] # print("提取到content:", content)
# 找到包含 $_ts.cd 的script标签,提取全部文本内容scripts = tree.xpath('//script[contains(text(), "$_ts.cd")]/text()')if scripts: script_content = scripts[0] # print(script_content)# 提取包含 "z5gPWiiwO6ht" 的script的srcjs_src = tree.xpath('//script[contains(@src, "z5gPWiiwO6ht")]/@src')[0]# print("JS src:", js_src)
# 拼接完整URLfull_js_url = old_url + js_srcprint("完整URL:", full_js_url)
res = session.get(full_js_url, headers=headers, cookies=cookies, verify=False)code=code+script_content+'\n'+res.text
# print(code)
with open('./main.js', 'r', encoding='utf-8') as f: js_code = f.read()ctx = execjs.compile(js_code.replace('"{{meta_content}}"', f'"{content}"').replace('debugger;',code))cookie_d = ctx.call('get_cookie')
parts = cookie_d.split(';')[0] # "NOh8RTWx6K2dT=0HMyeuSMq..."name, value = parts.split('=', 1) # 只按第一个=分割
session.cookies.update({name: value})response = session.get(url, headers=headers, cookies=cookies, verify=False)# print(response.text)print(response)总结
瑞数6最近这次更新对环境强校验,挺麻烦的。
还有个无限debugger的事,或者后缀。找个时间水水吧(
部分信息可能已经过时









