Akamai字符串解混淆
公司要搞一个网站,然后就开始了我的akm痛苦之旅,顺便分享一下字符串解混淆的思路
目标网站:aHR0cHM6Ly93d3cucmFkaXNzb25ob3RlbHMuY29tL2VuLXVzLw==
1、首先抓包看一下登录接口,是一个post,账号密码都是明文, 当时内心os:这不是手拿把掐!
然后复制curl,requests测试,ok,他不行,报403
2、 看参数, 请求头没什么加密,cookie有一个_abck,网上曾听闻这个参数,再次确认一下
第一次 get,set一次cookie
第二次post,更新一次cookie
第三次post,再次更新一次cookie
第四次post,更新 ~0~的cookie(需要手动点击页面,猜测检测了鼠标轨迹)
3、确诊:就是akm,看sensor_data, 是akm3.0 版本的
4、调试加密参数,在最后一次发包的地方,打断点
Ov是我们要搞的参数, 他是上方定义的
var Ov = nQ()[Lm(d4)](mb, nw)[NQ()[U5(ml)].apply(null, [nw, J8, qP, sY(vO)])](cXJ, lY(typeof Js()[r5(Ft)], Qx('', [][[]])) ? Js()[r5(BHJ)](sY(vO), qx, Ct) : Js()[r5(pY)](Uq, WLJ, RV));
对他进行拆解
nQ()[Lm(d4)](mb, nw) ==> '{"sensor_data":'NQ()[U5(ml)].apply(null, [nw, J8, qP, sY(vO)]) ==> 'concat'cXJ, 就是我们要搞的参数lY(typeof Js()[r5(Ft)], Qx('', [][[]])) ? Js()[r5(BHJ)](sY(vO), qx, Ct) : Js()[r5(pY)](Uq, WLJ, RV) ===> '}'
5、可以看到有很多的混淆代码
第一种,函数调用类型: JS()[x(AA)](XX, XX, XX)
第二种,绑定调用类型,有apply那么一定有.call,毕竟他们是兄弟
第三种,问号表达式
6、梳理思路:把目标函数解密为字符串,转换为逗号表达式,不影响原函数的运行
7、先搭建基础的AST基础框架
8、看节点的特征,拿第一个函数调用来说,节点类型是CallExpression,再分别判断属性类型
网址:https://astexplorer.net/
types.isMemberExpression(node.callee) && types.isMemberExpression(node.callee.object) && (node.callee.property.name ===“apply” || node.callee.property.name ===“call”)
&& types.isCallExpression(node.callee.object.object) && types.isCallExpression(node.callee.object.property)
问号表达式的特征:ConditionalExpression,每一个都是CallExpression,再分别对三个进行判别
types.isCallExpression(node.test) && types.isCallExpression(node.consequent) && types.isCallExpression(node.alternate) && node.test.arguments.length === 2
&& is_string_decrypted(node.consequent) && is_string_decrypted(node.alternate)
9、创建obj[‘xxx’] = xxx, obj[‘xxx’], 首先看整体节点,是sequenceExpression,首字母记得要小写
types.sequenceExpression([
types.assignmentExpression(“=”, types.memberExpression(types.identifier(‘obj’), types.stringLiteral(path +“”), computed=true),
node),types.memberExpression(types.identifier(‘obj’), types.stringLiteral(path +“”), computed=true)
])
10、然后会将全部的代码,保存为这样格式的
11、替换原js文件,注意: 一定有tostring 检测(别问,大家都这么说的!)
在js头部,加下边的代码,断到后,会
!function () {let toString_ = Function.prototype.toString;Function.prototype.toString = function () {let res = toString_.call(this);debugger;return res;};
}();
hook它的原逻辑,然后直接返回原代码就可以了,下边的代码就可以换成我们处理过的代码
别忘了声明一个 obj = {}
12、让代码执行完成,看结果返回 0 的cookie, ok那我们代码已经没问题了
13、copy obj的所有json,写一个replace代码
然后我们就得到解混淆以后的代码
我自己尝试过,把混淆后的代码放上去,不能发包了,应该是检测了JS()函数的调用吧
不管了, 放在本地,和网站上的慢慢对比吧~~