某网站JS加密、OB混淆与CSS反爬实战分析

article/2025/10/3 18:11:43

1. 写在前面

  最近一段时间接触了一些小说网站的业务。发现很多的小说网站,甚至一些小站它们的安全防护措施做的都很到位!例如上次说到的的五秒盾也是存在于一个小说小站。今天要讲的这个网站它集JS加密ob混淆CSS反爬于一体

目标站点

aHR0cHM6Ly93d3cuaG9uZ3NodS5jb20vY29udGVudC8xMTM3NzIvMjA1NDI1LTE0NTU1NzIuaHRtbA==

2. 分析

  

这次主要说的就是小说内容这块,打开这个网站的你会发现内容是不允许复制的。其次页面呈现的内容里面有一部分数据是隐藏的,虽然在页面你看它显示都正常,但在原代码中是没有的,而是由类似span标签代替的

这种反爬虫的手段主要先限制我们对页面的一些操作,然后将某些内容进行加密,最后在网页加载的时候通过解密算法进行解密从而渲染加载到网页

首先,碰到这种情况,我们可以先假设它这个页面的内容是经过二次请求,从接口拿到数据在进行渲染的

所以,我们可以先刷新页面看看XHR下的请求,简单的分析一波

在这里插入图片描述

可以看到某个请求的响应中有一个content字段,一看就知道它是经过加密处理的。这个字段的字面意思倒是可以让我们怀疑它是网页需要呈现的内容数据

在JS逆向中,可以记住大致的主流程,当然主流程里面涉及到的各种技巧与手法又可以开枝散叶,本文不做过多的描述。以后慢慢覆盖讲解:
在这里插入图片描述

3. 定位

  这里我们其实已经知道content字段很有可能是经过加密后的小说内容。所以到这一步我们还是有比较多的方法进行定位,可以直接点击Initiator跟一下请求的调用栈

  同样根据你的经验进行一些预判!如全局搜索一下可疑的关键字。这里我们可以看上面的加密肯定与base64有关,加密的数据也必然会走解密decrypt逻辑,这些可疑的关键词对象都可以是我们入手的点
在这里插入图片描述
上述通过分析定位找到可疑的JS代码,可以看到这里大概率是一个解密函数的调用,我们埋一个断点重新刷新请求一下:

在这里插入图片描述
断点到此处后,我们可以看到content字段,就是一串密文,而这段密文依次调用了utf8to16hs_decryptbase64decode这三个函数。这里我们可以大胆的猜想它们就是解密函数

3. 扣代码

现在我们可以去印证我们最开始的猜想,content字段到底是不是解密后的小说内容,我们将上面几个函数的js代码扣出来

function base64decode(str) {var c1, c2, c3, c4, base64DecodeChars = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,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,-1,-1,-1,-1,-1,-1,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,-1,-1,-1,-1,-1);var i, len, out;len = str.length;i = 0;out = "";while (i < len) {do {c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while (i < len && c1 == -1);if (c1 == -1)break;do {c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];} while (i < len && c2 == -1);if (c2 == -1)break;out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));do {c3 = str.charCodeAt(i++) & 0xff;if (c3 == 61)return out;c3 = base64DecodeChars[c3];} while (i < len && c3 == -1);if (c3 == -1)break;out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));do {c4 = str.charCodeAt(i++) & 0xff;if (c4 == 61)return out;c4 = base64DecodeChars[c4];} while (i < len && c4 == -1);if (c4 == -1)break;out += String.fromCharCode(((c3 & 0x03) << 6) | c4);}return out;
}function str2long(s, w) {var len = s.length;var v = [];for (var i = 0; i < len; i += 4) {v[i >> 2] = s.charCodeAt(i) | s.charCodeAt(i + 1) << 8 | s.charCodeAt(i + 2) << 16 | s.charCodeAt(i + 3) << 24;}if (w) {v[v.length] = len;}return v;
}function hs_decrypt(str, key) {if (str == "") {return "";}var v = str2long(str, false);var k = str2long(key, false);var n = v.length - 1;var z = v[n - 1], y = v[0], delta = 0x9E3779B9;var mx, e, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;while (sum != 0) {e = sum >>> 2 & 3;for (var p = n; p > 0; p--) {z = v[p - 1];mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);y = v[p] = v[p] - mx & 0xffffffff;}z = v[n];mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);y = v[0] = v[0] - mx & 0xffffffff;sum = sum - delta & 0xffffffff;}return long2str(v, true);
}function long2str(v, w) {var vl = v.length;var sl = v[vl - 1] & 0xffffffff;for (var i = 0; i < vl; i++) {v[i] = String.fromCharCode(v[i] & 0xff, v[i] >>> 8 & 0xff, v[i] >>> 16 & 0xff, v[i] >>> 24 & 0xff);}if (w) {return v.join('').substring(0, sl);} else {return v.join('');}
}function utf8to16(str) {var out, i, len, c;var char2, char3;out = "";len = str.length;i = 0;while (i < len) {c = str.charCodeAt(i++);switch (c >> 4) {case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:out += str.charAt(i - 1);break;case 12:case 13:char2 = str.charCodeAt(i++);out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));break;case 14:char2 = str.charCodeAt(i++);char3 = str.charCodeAt(i++);out += String.fromCharCode(((c & 0x0F) << 12) | ((char2 & 0x3F) << 6) | ((char3 & 0x3F) << 0));break;}}return out;
}function decrypt(content,key){return utf8to16(hs_decrypt(base64decode(content), key))
}

decrypt函数是自己定义的,为了更好的调用上面的解密函数。同时可以看到,解密函数调用的时候不光是传了content参数,还有一个key,那么我们现在需要分析key这个值是什么

回到接口请求分析那一步,之前第一次分析的时候,就把所有的请求都看了一遍,自然有发现这个key也是在XHR请求响应中的
在这里插入图片描述
现在,我们只需要从这两个接口当中请求拿到contentkey值就能调用我们的JS解密算法进行解密

这里我们可以在Console控制台把js代码放进去再构造一下contentkey即可验证,得到的结果正如我们猜想,它就是加密后的内容,如下是解密后的数据:

在这里插入图片描述

4. CSS反爬绕过

  现在我们已经得到了页面加密的内容、解密算法。但是可以看到解密出来后的数据是不完整的,被隐藏了。现在要做的就是拿到被隐藏的那些文字内容,这样整个页面的内容才是全的

我们再回过头看之前的请求分析,这个图里面除了content字段还有一个ohter字段的值貌似也是经过加密处理的
在这里插入图片描述
不要考虑那么多,现在为止我们只要这么想,所有的数据在呈现到前端页面时,必定是有迹可循的。不管是后端加密还是前端加密,都是一样,我们直接用解密函数在控制台看看,如下:
在这里插入图片描述
很可惜这并不是所缺失的那些内容,倒像是一段JS代码,不过好像也并不是正常的JS代码,显然经过了混淆。但是好在结构还算清晰

我们不用管这里面的具体加密与解密算法是怎样的,只需要分析它的加密跟解密的逻辑最后调用即可

ob混淆里面有一个大数组

var _0x09d1 = ['uJtRs', 'RyzMW', 'wkLRG', 'prototype', 'endWith', 'GIvaF', 'test', 'enc', '0767CD2FAAF99E58', 'window', 'location', 'href', 'Latin1', 'parse', 'D063F0602455077D', '146385F634C9CB00', 'ZeroPadding', 'toString', 'Utf8', 'split', 'createElement', 'style', 'setAttribute', 'type', 'async', 'head', 'cqrvw', 'link', 'nNyBj', 'length', 'parentNode', 'insertBefore', 'appendChild', '4|1|5|3|2|0', 'fromCharCode', 'tMLmi', 'OAWFf', 'KUtvo', 'KgGRl', 'qBUPd', 'addRule', '.context_kw', '::before', 'styleSheets', 'cssRules', 'pad', 'ZFebI', 'clamp', 'qVUkH', 'sigBytes', 'words', 'xsbdD', 'ouYQw']

这个数组基本是明文的,很多大厂网站这个数组全是跟变量_0x09d1一样全是十六进制的,其实经过分析就能发现words就是被打散隐藏的缺失内容

在这里插入图片描述
到了这一步,我们第一种方案则可以根据span标签里的class的数字索引去取words数组里面的值了
在这里插入图片描述

5. 内容还原

当然还有另外一种还原内容的方案,这里我建议使用JS注入然后渲染

html = '<!DOCTYPE html><html><head><meta charset="UTF-8"><script>'+js+'</script></head><body>'+content+'</body></html>'r = HTML(html=html)script_code = '''var span_list = document.getElementsByTagName("span");for (var i=0; i<span_list.length; i++) {var content = window.getComputedStyle(span_list[i], ':before').getPropertyValue('content');span_list[i].innerText = content.replace('"', '').replace('"', '');}'''r.render(script=script_code, reload=False)print(r.find('body', first=True).text)

上面的font color=#ff0033 size=3>ohter就是我们解密出来的那段js混淆代码,也就是用来还原缺失内容的关键函数,它就是我们上面的js参数,然后content就是我们上面还原的第一阶段解密出来的content

解密后的网页内容
在这里插入图片描述

解密后的JS混淆代码
在这里插入图片描述

注入后拿到的页面完整内容
在这里插入图片描述

  好了,到这里又到了跟大家说再见的时候了。创作不易,帮忙点个赞再走吧。你的支持是我创作的动力,希望能带给大家更多优质的文章


http://chatgpt.dhexx.cn/article/fah5aD2o.shtml

相关文章

前端JavaScript代码混淆加密原理介绍

因为JavaScript大都是运行在浏览器端,这就导致任何人都可以直接对网站的代码进行查看&#xff0c;如果代码没有进行任何处理就会导致直接暴露源码&#xff0c;他人便可轻而易举的复制你的劳动成果,但是由于没有纯粹的加密方案,所以能做的就是让代码变得更加的难以阅读,他人难以…

JS常见加密混淆一览

参考文章&#xff1a; https://www.cnblogs.com/guyouyin123/p/13804700.html 常见js混淆加密 JSFUCKAAEncodeJJEncode JSFUCK 特征为由[]{}()!组成的看不懂的代码 AAEncode 俗称aa混淆&#xff0c;特征为网络表情符号 JJEncode jj混淆&#xff0c;特点是特别多的$混淆 虽然…

JS常见加密混淆方式

目录 前端js常见混淆加密保护方式 eval方法等字符串参数emscriptenWebAssemblyjs混淆实现 JSFuckAAEncodeJJEncode代码压缩变量名混淆字符串混淆自我保护&#xff0c;比如卡死浏览器控制流平坦化僵尸代码注入对象键名替换禁用控制台输出调试保护&#xff0c;比如无限Debug,定时…

JS逆向之常见编码和混淆加密方式(一)

一般情况下&#xff0c;js的代码加密用来加密混淆代码&#xff0c;降低代码的可读性&#xff0c;如果一段没有经过任何加密混淆的代码&#xff0c;很容易被第三方或者脚本破解利用&#xff0c;引发许多的安全问题&#xff0c;本文将从以下多个角度讲解&#xff0c;代码加密的一…

最常用的js混淆加密解

JS混淆加密是一种用于保护JS代码的技术&#xff0c;它能够将代码变得难以理解和修改&#xff0c;从而提高代码的安全性。但是&#xff0c;当我们需要修改和维护这些代码时&#xff0c;我们就会面临困难。因此&#xff0c;在某些情况下&#xff0c;我们需要解这些JS代码。 下面…

PS操作小技巧

PS操作小技巧 如何查看psd文件指定图层图片的大小&#xff1f; 如何查看psd文件指定图层图片的大小&#xff1f; 首先你需要找到你的指定图层&#xff1a;点击小眼睛 然后再配合使用**Ctrl 左键 ** 这个时候图片会被选中&#xff0c;效果如下&#xff1a;

PS的简单操作!

PS的简单操作&#xff01; ctrld:取消选择区域的线、 ctrlr:标尺线、 ctrlaltz:返回最初步骤、 ctrlz:返回上一步、 注&#xff1a;在有交叉线处&#xff0c;按alt键可以拖出以“交叉点”为中心的“矩形”或者“椭圆”如果想使矩形变正方形&#xff0c;椭圆变圆形则altshift键。…

PhotoShop 基本操作介绍, 附带图文解说

一篇适合小白学习的教程,主要介绍PS的界面和基本操作,及分享一些常用的快捷键。 首次打开PS首先需要修改PS内的预设值 ①打开常规面板(也可以在菜单栏里打开,windows电脑在“文件菜单”下点击“常规”快捷键ctrl+k) <点图片看大图>www.16xx8.com 性能一般设为70%,…

简单的ps

1、快捷键 command n 创建文档 f7 图层 M 选框工具 v 移动工具 Command j 提取图层 shift f5 填充颜色 Ctrl t 自由变换尺寸 Ctrl 选中多个图层一起移动 Shift 选中多个图层可以选择连接 Alt 可以单看蒙版 ctrl d 取消选择 ctrl i 反选 2、注意事项 1、蒙版…

PS(一)PS基础从0开始,感兴趣的可以来看看

目录 一、PS基础知识和操作 2、调整页面 界面是不是太繁琐了 在右上角有个小列表&#xff08;我已经给大家标出来了&#xff09;点开有个关闭选项卡组&#xff0c;点击一下界面就会简洁了 ​编辑 有的界面打开少了什么工具啊可以点击窗口-工作区-复位基本功能 3、认识基本的位…

PS~了解PS的第一步,基本操作

1、PS如何新建画布 ①选择文件—新建—修改参数—确定 ②CtrlN 新建的快捷键—修改参数—确定 名称&#xff1a;自己修改宽高&#xff1a;自己修改&#xff0c;我们通常使用像素来定义分辨率&#xff1a;72颜色模式&#xff1a;RGB背景&#xff1a;自己选择白色或者透明 2、在…

PS_01_基本操作

贺叶铭_PS公开课_笔记 ctrl shift u :去掉颜色,去色 ctrl i 直接填充该选区的颜色的补色 例如&#xff1a; 第一天&#xff1a; 界面构成 1 菜单栏 2 工具箱 3 工具属性栏 4 悬浮面板 5 画布 ctrl N 新建对话框&#xff08;针对画布进行设置&#xff09; 如果只说数…

PS基本操作介绍与下载

文章目录 学习视频教程pj版PS下载 以及 视频教程相关素材链接Photoshop基本使用PS界面组成&#xff1a;图层操作(重点)图层编组图层上下位置移动Photoshop 切图切片工具辅助线和切片使用及清除切图插件 学习视频教程 http://2565.replace.favo.tyouai.com/ pj版PS下载 以及 视…

photoShop日常操作教程、PS

目录 提亮 改背景色 替换颜色 智能抠图并更换背景色 提亮 打开或者拖入一张照片复制原图片&#xff1a;CommandJ&#xff08;MacOS上的快捷键&#xff0c;Windows是CtrlJ&#xff09;提取高亮&#xff1a;Commandalt2&#xff08;MacOS上的快捷键&#xff0c;Windows是Ctrla…

PS基础操作及常用快捷键

文章目录 1. PS界面2. PS基础操作3. 图层4. 填充颜色5. 选框工具6. 自由变化 ctrlT7. 常用快捷键 1. PS界面 窗口菜单&#xff1a;管理&#xff08;显示/隐藏&#xff09;工具栏、属性栏、面板 将ps界面恢复到初始状态&#xff1a;窗口——工作区——复位基本功能自定义窗口设…

PS-简单操作工具介绍

PS有历史记录&#xff0c;可以返回之前的操作 图像的放大缩小可以使用&#xff1a;Ctrl &#xff0c;ctrl - 选中图层后&#xff0c;按住“alt”&#xff0c;用鼠标拖动可以实现图层复制 目录 调整输出图像的尺寸 多图拼接 3D模式 选区工具 裁减工具 套索工具 钢笔工…

PS知识点大总结(一)——基础操作

PS的界面&#xff1a; 菜单栏、属性栏、工具栏、编辑区、活动面板 PS的功能&#xff1a; 图像处理&#xff08;影楼后期、人像修复美化&#xff09;&#xff1b;排版&#xff08;书籍、杂志、喷绘、广告&#xff09;&#xff1b;网页、APP版面设计。 PS版本&#xff…

PS基础概念和操作

PS基础概念和操作 1、基础概念(1) 色彩空间RGB --> HSB/HSVRGB --> HSL (2) 相邻色和互补色(3) 混合模式 2、基础操作&#xff08;1&#xff09;选区、通道和蒙版的相互转换&#xff08;2&#xff09;HSL面板调色 3、基础功能&#xff08;1&#xff09;皮肤美白调色&…

Photoshop(PS)基础操作

♥️作者&#xff1a;奇妙的大歪 ♥️个人名言&#xff1a;但行前路&#xff0c;不负韶华&#xff01; ♥️个人简介&#xff1a;云计算网络运维专业人员 目录 &#xff08;一&#xff09;ps的基础操作 &#xff08;二&#xff09;画布操作 &#xff08;三&#xff09;图层基…

C语言文件操作(含代码+例题)

为什么使用文件&#xff1f; 使用文件可以将数据直接存放在电脑的硬盘上&#xff0c;做到数据的持久化。 一般来说&#xff0c;做到数据持久化的方法有把数据放在磁盘文件、存放到数据库等方式。 什么是文件&#xff1f; 文件的分类 磁盘上显示的文件就是文件。一般有数据文件和…