一、某高考资讯网逆向分析

某网站的js加密分析,安全签名signsafe + HmacSHA1 + AES

一年前分析过网站数据还没有加密,最近需要获取新的数据发现原先的爬虫失效,请求和响应都经过加密。于是重新分析,记录下分析思路以及分析过程中遇到的问题。

二、signsafe分析

2.1 抓包请求

打开谷歌浏览器,f12开发者模式抓包,分析请求参数:

抓包请求
local_province_id:省份idlocal_type_id:可类型,固定参数,可以忽略page:当前页数school_id:学校idsignsafe:安全签名,动态变化size:响应返回数据数量url:固定值,可以忽略year:年份
2.2 寻找signsafe加密算法

一般遇到这种明确的加密参数,例如 signsafe=xxx这种,通常做法都是尝试搜索参数名。按住ctrl+shift+f,调出搜索框,搜索关键词signsafe。

搜索signsafe

这里只搜索到一条包含signsafe关键字的文件,main.75.js文件,跟进去。格式化代码,按住ctrl+f调出文件内搜索框,继续搜索定位signsafe的位置。

signsafe加密函数

定位到疑似函数,打断点测试该函数是否就是我们需要的加密函数。

断点分析

断下来的数据可以看到,t就是请求中的signsafe参数。而且,函数中也出现了HmacSHA1、base64等方法。由此可知,定位的加密位置是正确的。接下来需要将加密函数抠下来改写,方便调用。下断点继续跟踪方法调用。跟踪v.a.enc.Utf8.parse方法,如下:

v.a.enc.Utf8.parse方法

单步步入,继续跟c.parse方法,如下:

c.pars方法

这里又出现了一个i.init方法,继续跟进去,如下:

i.init方法

跟完v.a.enc.Utf8.parse之后,继续跟踪外层v.a.HmacSHA1方法,如下:

v.a.HmacSHA1方法

跟到这里能看出,很容易的定位加密函数位置,而且关键函数代码量不多,但是代码可读性较差,断点跟踪的方式反而将问题复杂化,反思有可能是分析的方式有误。由于网站应该是经过webpack或类似的工具打包,将多个js文件打包成一个,导致代码文件冗长。仔细想想,如果是自己开发网站,也不可能手写各种加密算法,极大可能是调用第三方现成的加密库。如果是未压缩前的代码文件,必然会引用第三方的加密库。所以转换思路,直接搜索关键字require,尝试找到引用的加密库。ctrl+f 搜索 require,如下:

搜索关键字require

通过搜索发现,代码中确实引用了Crypto文件,而且查阅Crypto文档,发现api函数名与加密函数中的方法一致。初步证实猜想是正确的,那么接下来安装CryptoJs库,照着仿写加密流程。

加密流程

梳理一下加密流程:

  • v.a为Crypto-js的引用对象;
  • 第一步:v.a.enc.Utf8.parse(e),参数e为请求的get链接,将utf8字符串转换为WordArray;
  • 第二步:v.a.HmacSHA1(result, M),result为上一步中的WordArray,M为加密密钥,打断点可知M="D23ABC@#56",为固定值。

HMACSHA1 是从 SHA1 哈希函数构造的一种键控哈希算法,被用作 HMAC(基于哈希的消息验证代码)。它将任意长度的字符串生成 28位长的字符串。

HMACSHA1加密返回结果
  • 第三步:v.a.enc.Base64.stringify(t).toString(),将第二步的结果进行一次base64编码。

base64编码
  • 第四步:t = C()(t),直观看上去不知道函数作用,打断点跟进去函数内部发现是进行了一次md5运算。

md5加密

至此,signsafe参数加密过程分析结束。先将get请求链接转utf8,然后将utf8字符串转WordArray,再进行一次HMACSHA1加密,又将结果进行base64编码,最后再进行一次md5得到最终的signsafe结果。

2.3 代码实现

弄清楚加密流程,直接调用CryptoJs库,照着流程实现即可:

// e get请求链接, M 为加密密钥function initSignSafe(e, M) { let t = CryptoJS.enc.Utf8.parse(e); let a = CryptoJS.HmacSHA1(t, M); let b = CryptoJS.enc.Base64.stringify(a).toString(); let c = CryptoJS.MD5(b).toString(); return c;}

三、响应解码

这个网站还是做了一些防护的,请求参数和响应数据都进行了加密。上面我们分析了请求中的安全签名加密,接下来分析响应数据解密方法。照例抓包进行分析,抠出解密代码。

3.1 抓包查看响应

返回响应抓包

这一长串就是加密后的数据,乍一看无从下手,但有意思的是,响应中method的值说明响应是通过aes-256-cbc的方式进行加密。百度解释:

高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥。AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。

看多了太复杂,这里只需要知道使用的加密方法是aes-256,密钥长度256位,cbc指的是在加密和解密是需要一个初始化向量(Initialization Vector, IV),在每次加密之前或者解密之后,使用初始化向量与明文或密文异或。说白了,就是设定的密钥,添加一个初始化偏移量。加密时,明文先与iv偏移量异或,再将结果进行256位的块加密,得到的输出就是密文,同时本次的输出密文作为下一个块加密的IV。

3.2 响应解密分析

分析思路跟signsafe参数类似,按住ctrl+shift+f,搜索关键字aes。

搜索aes关键字

按住ctrl+f,文件内搜索aes关键字:

文件内搜索aes关键字

有11个结果,对可疑的函数段下断点找到加密函数:

断点找到加密函数

梳理一下加密流程:

  • 第一步:将响应中的数据赋值到变量中保存,s为安全签名的密钥;
  • 第二步:将两个原始密钥s("D23ABC@#56")和l("apidata/api/gk/plan/special")进行PBKDF2加密;

PBKDF2(Password-Based Key Derivation Function)是一个用来导出密钥的函数,常用于生成加密的密码。它的基本原理是通过一个伪随机函数(例如HMAC函数),把明文和一个盐值作为输入参数,然后重复进行运算,并最终产生密钥。

  • 第三步:将密文初始化为一个cipher params 对象;
  • 第四步:进行aes-256-cbc加密,传入cipher params 对象,密钥是经过PBKDF2加密的s("D23ABC@#56"),偏移量lv为经过PBKDF2加密的l("apidata/api/gk/plan/special");
  • 第五步:将aes加密后的结果WordArray转换为字符串g.toString(v.a.enc.Utf8)。

简而言之,将两个密钥进行PBKDF2加密,需要加密的数据初始化为cipher params 对象。进行一次aes256cbc加密,加密结果转换为字符串,最终获得解密后的响应内容。

3.3 代码实现

复制加密流程代码,将v.a替换为CryptoJs引用对象进行改写:

function decodeRes(e, _s, _l) { let a = e, s = _s, l = _l; if (e.data && e.data.text) {  let c = e.data.text;  let u = CryptoJS.PBKDF2(s, "secret", {   keySize: 8,   iterations: 1e3,   hasher: CryptoJS.algo.SHA256  }).toString();  let f = CryptoJS.PBKDF2(l, "secret", {   keySize: 4,   iterations: 1e3,   hasher: CryptoJS.algo.SHA256  }).toString();  let m = CryptoJS.lib.CipherParams.create({   ciphertext: CryptoJS.enc.Hex.parse(c)  });  let g = CryptoJS.AES.decrypt(m, CryptoJS.enc.Hex.parse(u), {   iv: CryptoJS.enc.Hex.parse(f)  });  a = {   code: "0000",   data: JSON.parse(g.toString(CryptoJS.enc.Utf8)),   message: ""  }  return JSON.stringify(a); } return undefined;}

解密后的内容如下:

解密后的响应内容

四、总结

  • 加密参数优先通过搜索的方式进行定位;
  • 现在的js文件一般都经过压缩,可读性较差,可以通过搜索require等关键字转换思路;
  • 抠出加密函数的方法可以通过断点一步一步跟踪,查缺补漏,或者手动仿写;
  • 逆向的技巧性很强,要善于利用搜索引擎。

js aes加密_某高考咨询网js逆向分析笔记相关推荐

  1. AES加密_ js与C#互通

    为什么80%的码农都做不了架构师?>>> javascript部分 npm install crypto-js --save 定义文件jm.js const CryptoJS = r ...

  2. js aes加密_nodejs中使用Crypto-JS对图片进行加解密

    在用nodejs开发后台的时候,为了安全的需要,经常会有加密的需求,对前端传入的图片进行AES加密后存储,然后在前端调用的时候,对图片进行解密,并返回Base64编码格式的图片. Crypto-JS这 ...

  3. aes 加密_结合RSA与AES实现前后端加密通信

    结合RSA与AES实现前后端加密通信 一.思路 使用RSA秘钥生成工具生成一对公钥(A)和私钥(B),前端保留A,后端保留B. 前端发送数据时,先生成一串随机16位字符串作为AES的秘钥(C),然后使 ...

  4. 前端aes加密_前端安全攻防解析

    知识点列表: CSRF 攻击 XSS攻击 HTTPS 程序员必须要了解的web安全 - 掘金 若愚:「每日一题」CSRF 是什么? [基本功] 前端安全系列之一:如何防止XSS攻击? [基本功] 前端 ...

  5. 什么标准规定了aes加密_高级加密标准(AES)分析

    原标题:高级加密标准(AES)分析 0×00 前言 在密码学中,block(分组)密码的工作模式被广泛使用,使用同一个分组密码密钥对很多称之为块的数据加密,在优于很多诸如RSA.ECC密码的性能的情况 ...

  6. 构建node.js基础镜像_我如何使用Node.js构建工作抓取网络应用

    构建node.js基础镜像 by Oyetoke Tobi Emmanuel 由Oyetoke Tobi Emmanuel 我如何使用Node.js构建工作抓取网络应用 (How I built a ...

  7. js observer 添加_简单了解4种JS设计模式

    阅读本文约需要5分钟 大家好,我是你们的导师,我每天都会在这里给大家分享一些干货内容(当然了,周末也要允许老师休息一下哈).上次老师跟大家分享了15款有用前端开发的ST插件的知识,今天跟大家分享下4种 ...

  8. ISE网表逆向分析与使用技巧

    当自己的编译器将设计文件编译成一块板砖时,必须掌握这些ISE使用技巧以便于做逆向分析.将自己的编译结果转化到ISE的软件中来验证与定位还是挺复杂的过程,涉及一系列网表的逆向与转换问题,首先得根据布局与 ...

  9. JS AES加密与PHP解密(转)

    网页端(在没有https情况下)给密码之类的加密传输,虽然多此一举,也好过直接监控软件就能看到密码 思路 在传输密码的时候,先向后台获取一个随机码或者验证码,作为秘钥,网页端根据这个秘钥,加密要传输的 ...

最新文章

  1. JAVA的StringBuffer类
  2. python搭建django框架,Python之Web框架Django项目搭建全过程
  3. weblogic概览下的上下文根配置_Weblogic服务下获取上下文路劲问题
  4. 电脑QQ能登上,网页打不开的解决办法
  5. 对比 SQL Server 2005 和 Oracle
  6. echarts 关系 两个多个关系_情感归宿:异性聊天时,常用这些结束语的两个人,关系很难清白...
  7. html让文本框左剧中对齐_Python—Text:功能强大的文本框
  8. 小说的逻辑与反逻辑_以理性的数学逻辑构筑推理小说
  9. SQL_delete删除数据
  10. 自学python还是c4d_C4D到底需要学多久?要学到什么程度?
  11. 这些有趣的人,带你打开世界另一面!
  12. vue-table-with-tree-grid的使用(黑马笔记)
  13. Vmprotect 驱动加壳踩坑
  14. excel身份证号提取出生日期
  15. 盘点:54款真正耐玩的独立游戏
  16. 汇编jnl_汇编指令 JO、JNO、JB、JNB、JE、JNE、JBE、JA、JS、JNS、JP、JNP、JL
  17. python批量请求url_python批量请求注册接口爬虫相关问题记录
  18. java实现docx文档下载
  19. 川土微电子 | 超小型封装隔离式半双工485收发器
  20. Error creating bean with name ‘sqlSessionFactory‘ defined in class path reso...报错的解决方法

热门文章

  1. Spring Cloud Config 规范
  2. “百变”Redis带你见识不同场景下的产品技术架构
  3. 对话阿里云:开源与自研如何共处?
  4. 让服务器突破性能极限 阿里云神龙论文入选计算机顶会ASPLOS
  5. 从零单排HBase 02:全面认识HBase架构(建议收藏)
  6. android ndk 9,Android NDK:警告:APP_PLATFORM android-9大于android:minSdkVersion 8
  7. ElasticSearch 从安装开始_01
  8. ***error*** (zip#Browse) unzip not available on your system
  9. linux mysql5.7启动失败/tmp/mysql.sock ?
  10. html-网页基本信息