龙空技术网

前端JS加密浅析

区块软件开发 1494

前言:

如今各位老铁们对“js实现简单的hash算法”大致比较着重,你们都需要了解一些“js实现简单的hash算法”的相关内容。那么小编也在网摘上搜集了一些有关“js实现简单的hash算法””的相关知识,希望我们能喜欢,我们快快来了解一下吧!

前言

本文主要记录常规JS加密方法的判断以及如何定位加密方法,并进行扣取执行的方法等,如果有错误的地方,还望指正,不喜勿喷;

在日常渗透测试中,当遇到登录接口时,通常会进行弱口令以及注入等方法进行安全测试,然而当目标站点对敏感参数进行加密后,会增加我们安全测试的难度,因此需要对前端JS进行分析,跟踪加密过程、判断加密方法、判断是否加盐,从而编写脚本对接口进行安全测试。

在Burp Suite中有一些HASH的算法以及其他大佬编写的加密插件,可以满足一部分测试需求,但对于JS中加密方法DES、AES、RSA以及一些自研加密方法还是需要自己动手调试找key等操作,因此我也去学了一下,以下内容算是学习记录。

快速判断加密/散列算法1、通过密文判断

仅列出常用的,以下为密文123456的密文(未加盐的情况下):

//散列MD5:e10adc3949ba59abbe56e057f20f883eSHA1:7c4a8d09ca3762af61e59520943dc26494f8941b(40位)SHA256:8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92(64位)SHA512:ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413(128位)//编码BASE64:MTIzNDU2BASE32:GEZDGNBVGY======Unicode:\u0031\u0032\u0033\u0034\u0035\u0036​//加密算法(DES/AES/RSA)一般密文无规律,常见在前端输出时会进行base64编码后在输出,对称和非对称都是16进制的形式,最大的字母只到了F那就说明可能是。
2、通过F12

访问站点F12,当提交数据时查看network加载资源,有时会看到加密方法,如下:

还有一些加密库jsencrypt、crypto-js等都可用做判断加密算法。

如何快速定位加密JS代码位置1、搜索关键字

使用浏览器自带的search功能,定位的位置比较准确, 搜到的位置比较多, 要自己进行筛选, 容易搜不到;

在搜索一个对象时可以使用以下定义方法进行搜索,可以过滤掉一些不必要的结果:

var objectfunction objectobject:object :object = object=   //代码没格式化之前的样子

其他关键字:encrypt、passwd、password、MD5、AES、DES,登录加密的参数名是什么就先搜参数名,搜不到在搜其他关键字,框架的js文件(jquery等)可以不用看,重点看自写的JS文件,定位到大概位置后下断点跟值查看;

2、XHR断点

代码运行时间轴:加载html--加载js --运行js初始化 --用户触发了某个事件--调用了某段js--明文数据--调用加密函数 --加密数据--send请求(XHR--send)

执行比较靠后,距离加密函数相对比较近,可以根据栈快速定位,但是非XHR发送的数据包是断不住的。

example

将后面固定的路径 adminlogin,添加到XHR/fetch Breakpoints中,在提交请求,此时会被断住,就可以通过栈进行分析;

方法栈(从下往上运行),它遵从后进先出(LIFO——Last In First Out)原则,通过跟栈可以快速定位到加密点,找到密文和明文之间的代码,大概率为加密方法的位置。

3、dom事件断点

代码运行时间轴:用户输入明文 -》经过一些方法 -》加密函数 -》拼接封包 -》发包函数 -》浏览器的发包函数

定位的位置比较靠前,定位到的通常是用户输入的明文,需要跟值才能跟到;

在event Listeners中查看事件,找到登录事件(找不到时候可以通过删除事件,点击登录查看是否登录按钮有效进行排查找出事件),从后面指向的js文件跟进去,简单分析后在比较像加密的地方下断点,点击登录后跟值。

定位以及扣取案例

找了几个站发现都是基于加密库jsencrypt、crypto-js的案例不太好,这里只做练习,不在乎有没有意义,苦笑;

提取的时候通常会直接把整个js先提取到本地,然后再提取加密方法出来,然后本地运行缺什么在补什么,另外webpack 框架的提取方式和常规的还有一定区别。

需要注意的点:

作用域的问题

var _hex_md5;    //将局部变量导出才能在全局使用!(function(){var j = {hex_md5:function(){console.log("1");}}_hex_md5 = j;   //导出})() //自执行
提取代码完整
var class = {name:"test"md5:function(args) //不能光扣md5这部分需要把this一起提取出来才有用,var开始到最后才是一个整体{console.log(args)}}
RSA

RSA特征:

new JSEncrypt();a.setPublicKey("key");a.encrypt(passwd);​new rsa的加密对象xxx.set设置publickey     //设置公钥xxx.调用加密方法(“明文”)  //加密以上三步是RSA加密必须的,跟值得时候也需要在这三个地方打上断点,扣代码运行也要这三点;

在登录时,查看network可以看到password参数是加密的

个人觉得XHR定位比较方便,但是这里可以看到type是document,因此无法使用XHR断点进行跟栈;

使用搜索进行定位,使用network左下的search搜索关键字encrypt,可以看到有五个结果,最后一个JS文件中的是我们想要拿到的;

点击169行跟到JS文件中查看,并在三个特征处下断点,再次点击登录跟值查看,可以看到在166行的时候还是明文,在173行就输出了密文,因此加密方法是处于166-173行,当然这里也能很清楚的看到e.encrypt(passwd)方法对明文进行加密,可以使用console调用这个方法尝试一下加密(只有在断住后才能使用console进行调用),可以看到加密成功。

那么这里已经很清晰了,e调用了encrypt进行加密,而e = ze{},我们这里把ze取出来就可以了,选中JSEncrypt,根据指向的文件进入js文件中;

进入jsencrypt.min.js后,查看,注意在var的前面还有空格,那就说明它是在一个大方法中,不出意外的话,我们把这个大方法抠出来,在按照上诉特征三个步骤去调用就可以了;

鼠标放到var上,然后一直往上滑,直到看到一个顶格的function,然后扣出来就可以了,另外正常的RSA代码在2000行左右;

大方法拿出来后在JS调试工具中运行,运行会提示navigator is not defined以及window is not defined,我们在首行增加以下代码即可:

navigator = {},window = this;

接下来构造调用函数,比较方便的是学着目标网站构造调用函数就行了,网站怎么写你就怎么写,不会错:

function rsaPass(passwd){var e = new JSEncrypt();  //RSA三大步e.setPublicKey("key");return e.encrypt(passwd);}

构造出来后我们发现此处还缺少key,我们在到网站的JS里去找一下看看对方是怎么传的,找到调用位置,可以看到170行,它的含义是将ID为"e"的HTML元素的值作为公钥,并将其设置为某个对象的公钥。

我们可以到前端HTML进行查找,搜索#e,定位到key

最后调用测试,RSA加密同一字符串时,每次生成的密文通常是不一样的,这是因为RSA加密算法中,每次使用的随机数都是不同的,而随机数会影响到加密过程中的一些计算,从而导致密文的差异。

DES

DES特征

(function () { // 定义一个立即执行函数const message = "123456"; // 要加密的明文const key = "ffffffffffff"; // 密钥​// 将密钥从字符串转换为字节数组const keyBytes = CryptoJS.enc.Utf8.parse(key); ​// 使用 DES 加密算法加密消息const encrypted = CryptoJS.DES.encrypt(message, keyBytes, {mode: CryptoJS.mode.ECB, // 使用 ECB 模式padding: CryptoJS.pad.Pkcs7, // 使用 PKCS#7 填充方式});

填充方式以及加密模式不一致也会导致密文不一致;

URL:

请求类型是XHR

admin 123456的密文

这里使用XHR方法进行定位,在XHR/fetch Breakpoints添加adminlogin路径,再次提交请求,此时会被断住

根据栈往下看,先找到密文,在找到明文,在第三个栈(querySessionAttr)找到了密文,第二个栈(login)找到了明文以及密文,还有一串字符,那么加密代码的位置大概可能在这之间,但是这里比较清晰,我们直接在57、58行下断点,然后跟进去看;

跟进encryptByDES后可以看到DES的特征以及key,实际上到这里就可以将key拿到其他的DES算法环境中进行加密测试,看看密文是否相同,相同基本上就没有在跟下去的必要了。

这里我将key拿出来后,在自己的环境进行加密,密文相同。

AES

特征:

function Encrypt(xxx){  var xxx  = xxx.enc.Utf8.parse('key');var xx = xxx.enc.Utf8.parse(xxx);  var xxx = xxx.AES.encrypt(xxx);  } 

其他操作也可des差不多。

测试脚本

代码功底太差,写了几个渗透测试用的简单小脚本,需要自己先把目标网站的key拿出来在使用脚本,不同的场景需要对脚本进行微调,主要实现功能如下:

DES、AES、RSA批量加密脚本,DES、AES解密AES、DES 配合sqlmap的SQL注入脚本

项目地址:

后记

加密库的JS代码,提取出来放到VSvode里面用node运行时候会各种报错,比如ASN1 is not defined,我在目标网站找了半年都没有找到ASN,在里找到了,但是在一些JS调试工具里面却能运行,不会报ASN1 is not defined,可能是环境问题,js代码拿出来调试时候需要注意。

使用加密库的网站只需要找到加密的key以及确认加密方式、填充方式是否有IV,就可以在自己的环境中运行,一般使用加密库也不太会改代码;

from

标签: #js实现简单的hash算法 #jsdes加密解密