最近需要参考下易企秀H5的json配置文件,发现已经做了加密,其实前端的加密分析起来只是麻烦点。

抓包分析

先看一个H5: https://h5.eqxiu.com/s/XvEn30op

F12可以看到,配置json地址是:https://s1-cdn.eqxiu.com/eqs/page/142626394?code=XvEn30op&time=1542972816000

对应的json:

{"success":true,"code":200,"msg":"操作成功","obj":"加密后的字符串"}

obj对应的是正式的配置信息

解码分析

需要对加密信息进行解密,首先可以定位到解密代码

function _0x230bc7(_0x2fb175) {return _0x3c31('0xee') == typeof _0x2fb175[_0x3c31('0x25')] && _0x2fb175['\x6f\x62\x6a'][_0x3c31('0xe')] > 0x64 ? _0x54c90c[_0x3c31('0x31f')]()['\x74\x68\x65\x6e'](function() {_0x249a60();var _0x5ab652 = null, _0x2cf0a4 = null, _0x4d1175 = null;try {var _0x3dbfaa = _0x2fb175[_0x3c31('0x25')]['\x73\x75\x62\x73\x74\x72\x69\x6e\x67'](0x0, 0x13), _0x360e25 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](0x13 + 0x10);_0x2cf0a4 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](0x13, 0x13 + 0x10),_0x4d1175 = _0x2cf0a4,_0x5ab652 = _0x3dbfaa + _0x360e25,_0x2cf0a4 = CryptoJS['\x65\x6e\x63'][_0x3c31('0x320')][_0x3c31('0x6b')](_0x2cf0a4),_0x4d1175 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')]['\x70\x61\x72\x73\x65'](_0x4d1175);var _0x57e61a = CryptoJS[_0x3c31('0x322')][_0x3c31('0x323')](_0x5ab652, _0x2cf0a4, {'\x69\x76': _0x4d1175,'\x6d\x6f\x64\x65': CryptoJS[_0x3c31('0x324')][_0x3c31('0x325')],'\x70\x61\x64\x64\x69\x6e\x67': CryptoJS[_0x3c31('0x326')][_0x3c31('0x327')]});return _0x2fb175[_0x3c31('0x36')] = JSON[_0x3c31('0x6b')](CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x267')](_0x57e61a)),_0x2fb175;} catch (_0x36fffe) {_0x5ab652 = _0x2fb175[_0x3c31('0x25')]['\x73\x75\x62\x73\x74\x72\x69\x6e\x67'](0x0, _0x2fb175[_0x3c31('0x25')][_0x3c31('0xe')] - 0x10),_0x2cf0a4 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](_0x2fb175[_0x3c31('0x25')][_0x3c31('0xe')] - 0x10),_0x4d1175 = _0x2cf0a4,_0x2cf0a4 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x6b')](_0x2cf0a4),_0x4d1175 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x6b')](_0x4d1175);var _0x4ff7de = CryptoJS[_0x3c31('0x322')][_0x3c31('0x323')](_0x5ab652, _0x2cf0a4, {'\x69\x76': _0x4d1175,'\x6d\x6f\x64\x65': CryptoJS['\x6d\x6f\x64\x65'][_0x3c31('0x325')],'\x70\x61\x64\x64\x69\x6e\x67': CryptoJS[_0x3c31('0x326')][_0x3c31('0x327')]});return _0x2fb175[_0x3c31('0x36')] = JSON[_0x3c31('0x6b')](CryptoJS[_0x3c31('0x321')]['\x55\x74\x66\x38'][_0x3c31('0x267')](_0x4ff7de)),_0x2fb175;}}) : Promise[_0x3c31('0x1e')](_0x2fb175);

这个代码基本不可读,简单分析下可以发现,_0x3c31('0x321')对应一个字符串,'\x6f\x62\x6a'等也可以转义:

先转义:

function decode(xData) {return xData.replace(/\\x(\w{2})/g, function (_, $1) { return String.fromCharCode(parseInt($1, 16)) });
}

然后替换下:

Function.prototype.getMultiLine = function () {var lines = new String(this);lines = lines.substring(lines.indexOf("/*") + 3, lines.lastIndexOf("*/"));return lines;
}function decode(xData) {return xData.replace(/\\x(\w{2})/g, function (_, $1) { return String.fromCharCode(parseInt($1, 16)) });
}var str1 = function () {/* var _0x5ab652 = _0x50019d(_0x3c31('0x30c'))
, _0x2cf0a4 = _0x50019d('\x63\x6f\x6d\x70\x4b\x65\x79')
, _0x5cba8a = {'\x74\x79\x70\x65': _0x3c31('0x16c'),'\x75\x72\x6c': _0x8aa6f1()
}
, _0xfca4af = {'\x74\x79\x70\x65': _0x3c31('0x16c'),'\x75\x72\x6c': _0xefaeb()
};
_0x31f1b8 && (_0x5cba8a[_0x3c31('0x2cb')] = {'\x70\x61\x73\x73\x77\x6f\x72\x64': _0x31f1b8
});
var _0x11871b = null
, _0x170c7e = Promise[_0x3c31('0x1e')](null);var _0x256cd0 = _0x2cf0a4(0x16)
, _0x36150e = _0x2cf0a4(0x15)
, _0x42a8d9 = _0x36150e['\x61\x6a\x61\x78']
, _0xdc46dc = _0x36150e[_0x3c31('0x1ef')]
, _0xcca797 = _0x2cf0a4(0x18)
, _0x50019d = _0xcca797[_0x3c31('0x5f')]
, _0x5c77e3 = _0xcca797['\x70\x61\x72\x73\x65\x55\x72\x6c']
, _0x36d54a = _0x2cf0a4(0x3a)['\x70\x65\x72\x66\x65\x63\x74\x4d\x65\x74\x61']
, _0x4c6a9e = _0x2cf0a4(0x2c)[_0x3c31('0x328')]
, _0x296a9b = _0x2cf0a4(0x2c)[_0x3c31('0x329')]
, _0x54c90c = _0x2cf0a4(0x17)
, _0x50f238 = _0x2cf0a4(0x3d)[_0x3c31('0x32a')]
, 0x13 = 0x13
, 0x0 = 0x0
, 0x10 = 0x10
, CryptoJS = null;function _0x230bc7(_0x2fb175) {return _0x3c31('0xee') == typeof _0x2fb175[_0x3c31('0x25')] && _0x2fb175['\x6f\x62\x6a'][_0x3c31('0xe')] > 0x64 ? _0x54c90c[_0x3c31('0x31f')]()['\x74\x68\x65\x6e'](function() {_0x249a60();var _0x5ab652 = null, _0x2cf0a4 = null, _0x4d1175 = null;try {var _0x3dbfaa = _0x2fb175[_0x3c31('0x25')]['\x73\x75\x62\x73\x74\x72\x69\x6e\x67'](0x0, 0x13), _0x360e25 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](0x13 + 0x10);_0x2cf0a4 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](0x13, 0x13 + 0x10),_0x4d1175 = _0x2cf0a4,_0x5ab652 = _0x3dbfaa + _0x360e25,_0x2cf0a4 = CryptoJS['\x65\x6e\x63'][_0x3c31('0x320')][_0x3c31('0x6b')](_0x2cf0a4),_0x4d1175 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')]['\x70\x61\x72\x73\x65'](_0x4d1175);var _0x57e61a = CryptoJS[_0x3c31('0x322')][_0x3c31('0x323')](_0x5ab652, _0x2cf0a4, {'\x69\x76': _0x4d1175,'\x6d\x6f\x64\x65': CryptoJS[_0x3c31('0x324')][_0x3c31('0x325')],'\x70\x61\x64\x64\x69\x6e\x67': CryptoJS[_0x3c31('0x326')][_0x3c31('0x327')]});return _0x2fb175[_0x3c31('0x36')] = JSON[_0x3c31('0x6b')](CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x267')](_0x57e61a)),_0x2fb175;} catch (_0x36fffe) {_0x5ab652 = _0x2fb175[_0x3c31('0x25')]['\x73\x75\x62\x73\x74\x72\x69\x6e\x67'](0x0, _0x2fb175[_0x3c31('0x25')][_0x3c31('0xe')] - 0x10),_0x2cf0a4 = _0x2fb175[_0x3c31('0x25')][_0x3c31('0xeb')](_0x2fb175[_0x3c31('0x25')][_0x3c31('0xe')] - 0x10),_0x4d1175 = _0x2cf0a4,_0x2cf0a4 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x6b')](_0x2cf0a4),_0x4d1175 = CryptoJS[_0x3c31('0x321')][_0x3c31('0x320')][_0x3c31('0x6b')](_0x4d1175);var _0x4ff7de = CryptoJS[_0x3c31('0x322')][_0x3c31('0x323')](_0x5ab652, _0x2cf0a4, {'\x69\x76': _0x4d1175,'\x6d\x6f\x64\x65': CryptoJS['\x6d\x6f\x64\x65'][_0x3c31('0x325')],'\x70\x61\x64\x64\x69\x6e\x67': CryptoJS[_0x3c31('0x326')][_0x3c31('0x327')]});return _0x2fb175[_0x3c31('0x36')] = JSON[_0x3c31('0x6b')](CryptoJS[_0x3c31('0x321')]['\x55\x74\x66\x38'][_0x3c31('0x267')](_0x4ff7de)),_0x2fb175;}}) : Promise[_0x3c31('0x1e')](_0x2fb175);
}"*/
}
var js1 = decode(str1.getMultiLine());
js1 = js1.replace(/_0x3c31\('([^\']+)'\)/g, function ($v, $g) { return _0x3c31($g); })

得到

var _0x5ab652 = _0x50019d(userKey)
, _0x2cf0a4 = _0x50019d('compKey')
, _0x5cba8a = {'type': GET,'url': _0x8aa6f1()
}
, _0xfca4af = {'type': GET,'url': _0xefaeb()
};
_0x31f1b8 && (_0x5cba8a[data] = {'password': _0x31f1b8
});
var _0x11871b = null
, _0x170c7e = Promise[resolve](null);var _0x256cd0 = _0x2cf0a4(0x16)
, _0x36150e = _0x2cf0a4(0x15)
, _0x42a8d9 = _0x36150e['ajax']
, _0xdc46dc = _0x36150e[$ajax]
, _0xcca797 = _0x2cf0a4(0x18)
, _0x50019d = _0xcca797[getUrlParam]
, _0x5c77e3 = _0xcca797['parseUrl']
, _0x36d54a = _0x2cf0a4(0x3a)['perfectMeta']
, _0x4c6a9e = _0x2cf0a4(0x2c)[isVipScene]
, _0x296a9b = _0x2cf0a4(0x2c)[isTgScene]
, _0x54c90c = _0x2cf0a4(0x17)
, _0x50f238 = _0x2cf0a4(0x3d)[setJsCrypto]
, 0x13 = 0x13
, 0x0 = 0x0
, 0x10 = 0x10
, CryptoJS = null;function _0x230bc7(_0x2fb175) {return string == typeof _0x2fb175[obj] && _0x2fb175['obj'][length] > 0x64 ? _0x54c90c[$loadCryptoJS]()['then'](function() {_0x249a60();var _0x5ab652 = null, _0x2cf0a4 = null, _0x4d1175 = null;try {var _0x3dbfaa = _0x2fb175[obj]['substring'](0x0, 0x13), _0x360e25 = _0x2fb175[obj][substring](0x13 + 0x10);_0x2cf0a4 = _0x2fb175[obj][substring](0x13, 0x13 + 0x10),_0x4d1175 = _0x2cf0a4,_0x5ab652 = _0x3dbfaa + _0x360e25,_0x2cf0a4 = CryptoJS['enc'][Utf8][parse](_0x2cf0a4),_0x4d1175 = CryptoJS[enc][Utf8]['parse'](_0x4d1175);var _0x57e61a = CryptoJS[AES][decrypt](_0x5ab652, _0x2cf0a4, {'iv': _0x4d1175,'mode': CryptoJS[mode][CFB],'padding': CryptoJS[pad][NoPadding]});return _0x2fb175[list] = JSON[parse](CryptoJS[enc][Utf8][stringify](_0x57e61a)),_0x2fb175;} catch (_0x36fffe) {_0x5ab652 = _0x2fb175[obj]['substring'](0x0, _0x2fb175[obj][length] - 0x10),_0x2cf0a4 = _0x2fb175[obj][substring](_0x2fb175[obj][length] - 0x10),_0x4d1175 = _0x2cf0a4,_0x2cf0a4 = CryptoJS[enc][Utf8][parse](_0x2cf0a4),_0x4d1175 = CryptoJS[enc][Utf8][parse](_0x4d1175);var _0x4ff7de = CryptoJS[AES][decrypt](_0x5ab652, _0x2cf0a4, {'iv': _0x4d1175,'mode': CryptoJS['mode'][CFB],'padding': CryptoJS[pad][NoPadding]});return _0x2fb175[list] = JSON[parse](CryptoJS[enc]['Utf8'][stringify](_0x4ff7de)),_0x2fb175;}}) : Promise[resolve](_0x2fb175);
}"

基板上可以读了,使用CryptoJS做的前端解密,然后直接给最后的代码:


// 依赖: https://lib.eqh5.com/CryptoJS/1.0.1/cryptoJs.js
function decrypt(result) {var ciphertext = null, key = null, iv = null;try {var part0 = result.obj.substring(0x0, 0x13), part1 = result.obj.substring(0x13 + 0x10);key = result.obj.substring(0x13, 0x13 + 0x10),iv = key,ciphertext = part0 + part1,key = CryptoJS.enc.Utf8.parse(key),iv = CryptoJS.enc.Utf8.parse(iv);var decryptData = CryptoJS.AES.decrypt(ciphertext, key, {'iv': iv,'mode': CryptoJS.mode.CFB,'padding': CryptoJS.pad.NoPadding});return CryptoJS.enc.Utf8.stringify(decryptData);} catch (_0x36fffe) {ciphertext = result[obj]['substring'](0x0, result.obj.length - 0x10),key = result[obj][substring](result.obj.length - 0x10),iv = key,key = CryptoJS.enc.Utf8.parse(key),iv = CryptoJS.enc.Utf8.parse(iv);var decryptData = CryptoJS.AES.decrypt(ciphertext, key, {'iv': iv,'mode': CryptoJS.mode.CFB,'padding': CryptoJS.pad.NoPadding});return CryptoJS.enc.Utf8.stringify(decryptData)}
}

易企秀H5 json配置文件解密分析相关推荐

  1. h5 表单居中_3分钟学会易企秀H5操作(基础篇)

    说起当下流行的微信朋友圈广告,H5广告可以说是最具有代表性意义的一种.目前H5制作平台有很多,今天主要给他家分享下易企秀H5平台,教你3分钟学会易企秀H5. 我知道大家时间很宝贵,这里我们就长话短说, ...

  2. html5互动场景制作系统,春哥技术博客高仿易企秀H5场景应用制作平台源码V1.0正式版发布...

    经过一个月的艰苦努力,春哥团队最新作品即将与大家见面了,<2015年6月春哥技术博客高仿易企秀H5场景应用制作平台源码V1.0正式版>即将来临, 现在春哥接受预定啦,春哥技术博客依然走价格 ...

  3. 最新易企秀h5场景秀制作源码 含几百套模板+详细搭建教程

    分享一个最新易企秀h5场景秀制作源码,含几百套模板和详细搭建教程,开发语言是PHP+MySQL,H5页面适合在微信朋友圈传播,传播能力较强. 企业及个人运用各种H5页面进行营销,用H5搭建的站点与应用 ...

  4. 易企秀前端压缩源码分析与还原

    你是否想知道易企秀炫酷的H5是如何实现的,原理是什么,本文会为你揭秘并还原压缩过的源代码. 易企秀是一款h5页面制作工具,因方便易用成为业界标杆.后续一个项目会用到类似易企秀这样的自定义H5的功能,因 ...

  5. 如何搭建易企秀H5平台?

    导读 易企秀如何开启伪静态支持? 一秀如何开启伪静态? 下载易企秀源码 oschina: http://git.oschina.net/jsper/html5Editor Windows下搭建环境 安 ...

  6. h5 nan_易企秀资深前端架构师袁飞:移动H5开发如何避坑

    2020年10月24日,正值程序员节,第二届全球移动开发技术峰会在北京隆重举行.易企秀资深前端架构师袁飞应邀出席峰会,并分享了移动H5开发技术要点和避坑指南. 本次峰会,来自微软.阿里巴巴.小米.腾讯 ...

  7. 易企秀资深前端架构师袁飞分享:移动H5开发如何避坑?

    2020年10月24日,正值程序员节,第二届全球移动开发技术峰会在北京隆重举行.易企秀资深前端架构师袁飞应邀出席峰会,并分享了移动H5开发技术要点和避坑指南. 本次峰会,来自微软.阿里巴巴.小米.腾讯 ...

  8. 如何实现类似易企秀的可视化 H5 编辑器?

    易企秀H5项目架构梳理 现有一款 可视化的 H5 编辑器 (类似易企秀, 使用 React 开发) 提供私有化部署, 绑定域名, 定制开发, 源码售卖培训 等服务 主要面向 对数据要求高, 需要私有化 ...

  9. 易企秀更换模板里的音乐_易企秀黄金:探索中国 SaaS 企业走向成功的路径

    天气炎热的午后,远离了水泥墙壁和反光玻璃,在一间视角开阔且满视野幽深僻静的会议室里,易企秀创始人兼 CEO 黄金为这次媒体交流会打开了话匣子-- 01 征"名"夺"利&q ...

最新文章

  1. vector大小为1,如果直接输出它-2,为何不是-1?
  2. Spark性能优化:对RDD持久化或CheckPoint操作
  3. 一图读懂《北京市数据中心统筹发展实施方案(2021-2023年)》
  4. libevent 1.4.13 / 源代码文件组织
  5. fianl属性 java_在Java中使用Final关键字可以提高性能吗?
  6. 如何在Debian上安装配置ownCloud
  7. OOB套接字传输实例(达不到预期结果)
  8. 用户界面和逻辑应该分离
  9. 如何配置RadASM
  10. Skyline软件二次开发初级——9如何在WEB页面中的三维地图上进行交互
  11. 解析美团联盟,美团分销联盟,美团福利宝,外卖美天赚区别和玩法
  12. 《Shopify从入门到精通》笔记(4~6章)
  13. 基于spring boot的婚纱摄影约拍系统
  14. matlab圆锥曲线,圆锥曲线:MATLAB绘制椭圆方程的图像 来充电吧
  15. 计算机研究生要发论文,电子科大毕业计算机研究生需要发表论文吗
  16. Android 怎么防止多并发请求?比如说一个页面需要请求多个接口,可以跟后台网络交互能做哪些性能优化
  17. DevStack环境搭建
  18. 利用python下载哨兵1号轨道数据
  19. XMLHttpRequest cannot load http://xxxxxx. No 'Access-Control-Allow-Origin' header i
  20. 3-搜索某网站的职位

热门文章

  1. [转载] 晓说——第1期:揭秘游戏规则奥斯卡走下“神坛“
  2. Java算法实现 BAT公司为什么要考算法 github
  3. html5 按钮css样式修改,css样式制作的漂亮按钮
  4. 如何自定义文档工程师绩效考核标准? | 职场杂谈
  5. uniapp小程序实现开屏页
  6. Nirvana-Nevermind
  7. 苹果IOS企业开发者账号怎么申请——苹果账号申请记录(未完待续)
  8. QQ工具手机软件+实用小软件+恶搞小软件合集
  9. python 日历热力图_pyecharts日历热力图
  10. 计算机cmos参数的设置,设置CMOS参数让电脑从光驱启动