浅析绕过js加密
source link: https://mp.weixin.qq.com/s?__biz=MzAwMzYxNzc1OA%3D%3D&%3Bmid=2247487871&%3Bidx=1&%3Bsn=ea41a5a56e5ba272a544a7dc8561b0d5
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
这是 酒仙桥六号部队 的第 104 篇文章。
全文共计3191个字,预计阅读时长9分钟 。
前言:在渗透测试过程中,我们经常会碰到登录处用 js 加密字段的情况。在大多数情况下,看到这种加密方式,我们都会放弃对该登录处进行暴力破解。本文主要讲解对 js 加密进行绕过,以达到爆破或绕反爬的目的!
案例一:对登录处使用sm2国密加密算法的某网站进行爆破
抓包分析
该网站图形验证码失效,只要能对密码字段进行相应的加密,就可以爆破!
访问网站,输入用户名:admin、密码:123456 以及正确的图形验证码进行登录。
抓包,可以看到密码字段被加密为很长的一段字符。
实战绕过
F12打开开发者调试模式,切换到 Network
选项卡。
重新登录一遍,可以看到 password
字段进行了加密。
切换到Source选项卡, ctrl+shift+F
调出全局搜索框,全局搜索 password
字段。
跳到 checkuser.js
文件,我们看看 password
字段经过哪些加密。
password
经过两次加密:
var password = hex_md5($("#password").val());
password = sm2Encrypt(password, publicKey_).toLocaleUpperCase();
第一步的加密很简单,就是调用 hex_md5
加密函数对 password
进行加密。通过全局搜索 hex_md5
,在 md5.js
文件中找到了该函数。如下:
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
然后我们看第二步加密,第二步加密调用了 sm2Encrypt()
函数对第一步加密后的字符串再进行加密。
我们在全局搜索 sm2Encrypt
,最终在 sm2.js
文件中找到了该加密函数。通过百度搜索 sm2
加密算法,发现该算法是国密加密算法。
SM2国密加密算法
SM2是国家密码管理局于2010年12月17日发布的椭圆曲线公钥密码算法。SM2算法和RSA算法都是公钥密码算法,SM2算法是一种更先进安全的算法,在我们国家商用密码体系中被用来替换RSA算法。
随着密码技术和计算机技术的发展,目前常用的1024位RSA算法面临严重的安全威胁,我们国家密码管理部门经过研究,决定采用SM2椭圆曲线算法替换RSA算法。
更多的关于椭圆曲线的加密方法就不细讲。
所以,现在我们需要对 sm2Encrypt
加密函数进行模拟。我使用 nodejs
来进行模拟。本地创建 sm2.js
文件,把网站上 sm2.js
文件中的 sm2Encrypt()
加密函数复制进来。末尾加一个 console.log()
打印,便于我们查看结果。再把网站的 md5.js
文件拷贝到 sm2.js
同目录下。而 publickey
则在 sm2.js
全局定义了。
运行该js文件,提示 CryptoJS is not defined
。于是在开头加入 var CryptoJS = require("crypto-js");
并且安装crypto-js模块:
cnpm install crypto-js
安装完之后,再次运行。提示 SM2Cipher is not defined
。提示这个报错是因为该函数里面用到的一些其他函数我们没有复制出来。所以得一个个把相关的依赖函数复制出来。
在加密的地方打断点,F11进行跟进。
一步一步跳,找到了 SM2Cipher
函数,将其复制到我们的 js 文件中。
再次运行,这次提示 KJUR is not defined
百度了下发现需要安装 jsrsasign
于是安装该模块,并且在脚本的开头加入引入语句 var KJUR=require("jsrsasign");
再次运行,提示 unregistered EC curve name: sm2
,这是引入的 jsrsasign.js
文件报的异常。
于是猜测需要去注册sm2曲线名称。我们继续翻阅网站的sm2.js文件,终于找到了注册该sm2曲线名称的代码。将其复制到我们的代码中。
再次运行,则提示如下的错: TypeError: ECPointFp.decodeFromHex is not a functio
n
我们在导入的模块里面全局搜索该函数 ECPointFp.decodeFromHex
,发现导入的模块中其实是有该函数的。
于是我们将之前的这条语句 var KJUR=require("jsrsasign");
改为 var jsrsasign=require("jsrsasign");
。然后再次运行,对运行报错的函数,全局搜索。如果在导入的模块中含有该函数,则在其前面加上jsrsasign.
如果到导入的模块中不含有该函数,则说明该函数是该网站自己定义的,我们到网站的 sm2.js
中把该函数复制下来就行。比如 function SM3Digest
函数,我们导入的模块中不含有该函数,但是在网站中是定义了该函数的,我们将其复制下来到我们自己的代码中即可。
经过一个函数一个函数的跟踪其依赖,最终将其加密算法模拟了出来,运行截图如下:
sm2.js
代码如下:
最终我们可以使用burpsuite的插件对这个 js 加密函数进行调用爆破,如下:
至此,js解密完成,我们可以对该登录接口进行爆破了!
案例二:对某漏洞平台反爬进行绕过
以下是针对某漏洞平台反爬进行绕过,最终可以通过脚本爬取该漏洞平台的漏洞列表。
直接使用爬虫脚本爬去漏洞,返回的是一段加密后的js代码,且返回状态码为521。
于是百度了下响应状态码521,果然,是反爬措施。
抓包分析
接着,就需要开始绕过反爬了。
首先F12调试模式查看访问网站时的各种资源。我这里使用的是火狐浏览器。
查看网络—>html,访问网站分两步。
先看第一步521请求
返回的是 521 状态码,然后返回的数据是加密的js代码。
再看请求头和响应头,发现响应头有一个set-cookie参数值 。
再看第二个200请求
返回的是 200 状态码,然后返回的数据是网页的数据。
再看请求头和响应头,发现请求头的参数值有两个。其中一个参数 __jsluid_s
是第一步521请求响应包设置的,而另一个参数 __jsl_clearance
则是第一步 521请求响应的 js 数据解密后的值。
我们来梳理一下流程:
所以,现在要想绕过反爬措施,最主要的是解密第一步 521 返回的 js 代码。以下是美化后返回的js代码。
实战绕过
我们来分析一下js代码。
首先设置了 x 变量和 y 变量。还设置了函数 f 和函数 z。我们现在姑且不看x、y、f 和 z的内容到底是什么。我们看最后的一个while 循环,循环里面执行了 eval函数。
我们暂且不看eval函数里的内容是啥意思。我们将eval函数里的内容赋值给 test,然后控制台输入这个内容最后调用eval函数执行这个test。这样,我们就可以在控制台看到最后执行的是啥东西了。
while (z++) try {
var test=y.replace(/\b\w+\b/g,
function(y) {
return x[f(y, z) - 1] || ("_" + y)
});
console.log(test);
eval(test);
break
} catch(_) {}
将以下js代码保存为后缀为 .html 的文件。
然后用浏览器打开该html文件,打开控制台输出以下js代码,并且一直在刷新。
将控制台输出的js代码美化,如下:
我们发现cookie是通过如下函数生成的。
我们直接在控制台执行该函数,如下,得到了生成的cookie。但是因为该cookie是有一定的时效性的。所以,我们得写一个脚本,快速的获取生成的cookie,然后访问网站。
最终的反爬脚本运行截图如下 :
总结
无论是案例一还是案例二,都是网站为了加强安全性使用js加密做的防护。所以需要我们对网站的js代码进行深入分析,才能进行绕过。在工作中,碰到了js加密的网站不用慌,慢慢细心的分析,总会有意想不到的收获!
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK