一、熟悉 JavaScript 基础语法。
需要对 JavaScript 的语法,数据类型,运算符等有一定了解,这是理解 JavaScript 逆向的基础。
JavaScript 逆向的基础是对 JavaScript 语言本身有较深入的理解。主要需要熟悉以下内容:
1. 数据类型:理解 NUMBER、STRING、BOOLEAN、NULL、UNDEFINED 等原始数据类型,以及 OBJECT、ARRAY 等引用数据类型。
-
运算符:熟悉算数运算符、比较运算符、逻辑运算符、赋值运算符等各种运算符的用法。 -
流程控制:理解 IF/ELSE、SWITCH、FOR、WHILE、DO/WHILE 等流程控制语句的执行逻辑。 -
函数:理解函数的定义、调用、参数传递、作用域链等与函数相关的概念。 -
原型与继承:理解原型对象的作用,以及 JavaScript 中基于原型的继承模式。 -
作用域与闭包:理解作用域的概念,理解闭包的生成机制以及应用。 -
对象与数组:熟悉对象和数组的创建、访问、增删改等操作。 -
字符串与正则:理解字符串和正则表达式的使用,以及基本的匹配逻辑。 -
事件:理解事件的注册、监听和触发流程。 -
DOM 与 BOM:理解 HTML 文档的基本结构,理解 JavaScript 操纵 DOM 和 BOM 的方法。
以上这些知识点构成 JavaScript 语言的基石。在学习 JavaScript 逆向前,需要对这些内容有扎实的理解,特别是对其中涉及到的执行逻辑和机制有深刻的领会。只有这样,在分析一段 JavaScript 代码时,才能根据语法理解其中的 meaning,找到关键点,推导出变量和函数的作用等。
所以,建议把以上知识点在学习逆向前好好复习一遍,并结合大量的练习进行巩固。这将有助于更高效地学习 JavaScript 逆向工程。
二:了解抽象语法树AST
JavaScript 代码会被解析成 AST,逆向过程就是分析 AST,所以需要对 AST 有所了解。
AST(Abstract Syntax Tree),抽象语法树,它是一个树状结构,用来表示程序的语法结构。
在 JavaScript 中,每个 JavaScript 程序在解析执行前,都会被语法分析器解析成 AST 树 form 的结构表示。
AST 是 JavaScript 解释器(例如 V8 引擎)进行执行前内部使用的主要数据结构。
为什么需要了解 AST?
-
调试改进 JavaScript 程序:你可以在 AST 树上进行各种操作(变形、替换子树等),改进优化你的源代码。 -
JavaScript 编译成其他语言:通过转化 AST 树成其他语言的语法树,可以将 JavaScript 编译成 C/C++、Java 等语言。 -
静态分析:通过分析 AST 树,可以做出控制流分析、数据流分析、语义分析等,对代码进行静态检查。 -
字面转换:可以在 AST 树上进行大小写转换、按要求添加、去掉注释等操作,修改 code 的某些特性。 -
语法检查:可以通过对 AST 的分析,进行语法错误检查、类型检查等。
AST 树的主要节点类型有:
-
Program: 整个 JavaScript 程序 -
FunctionDeclaration: 函数声明 -
FunctionExpression: 函数表达式 -
ArrowFunctionExpression: 箭头函数 -
ClassDeclaration: 类声明 -
ClassExpression: 类表达式 -
MethodDefinition: 类方法定义 -
Property: 类属性定义 -
AssignmentExpression: 赋值表达式 -
ConditionalExpression:条件(三元)操作符 -
LogicalExpression: 逻辑 expression -
CallExpression: 函数 call -
等等...
你可以通过查看 AST 树来更好地理解一个JavaScript 程序的结构和语义。
三、常见的加密算法及特点
-
MD5: 加密后有16位和32位,以0-9和小写a-f组成。其中16位的就是截取中间的第9至第24位,判断是否以MD5加密,主要看一下两点:是否符合16位或32位,加密后的结果是否是0-9,A-F。 -
AES:对称加密算法,加密和解密用同一个秘钥,密钥长度主要有128位,192位,256位。没法直接通过密文判断是否是AES加密,加密后的结果通过Base64编码,主要可以推断:例如密文长度是否为16的倍数。对于前端来说,可以找到加密源码来判断一下。 -
Base64: 准确来说,Base64是一种编码。以a-z,A-Z,0-9和+/=组成。 -
RSA: 非对称加密,有公钥和私钥两种秘钥。加密后的结果同样是经过Base64编码的。 -
**SHA:**常见的有SHA1,SHA256,SHA512。组成以0-9和a-f组成。加密后分别为sha1(40位),sha256(64位),sha512(128位)。
四、禁用Debugger的一些方法
主要针对无限Debugger的一些处理方法
1.暴力禁用法:
直接禁用所有断点,这样其实也无法调试了,不推荐。
点击“停用断点”,所有断点都不生效。
2.利用条件断点
在debugger处打上条件断点,置为false,debugger就不执行了
3.中间人工具
-
利用fidder拦截并改写含有debugger语句的js文件 -
浏览器自带的Overrides本地覆盖改写JS文件等方式
4.改写函数法
置空含有debugger语句的函数:
控制台进行变量覆盖,重新声明一下函数,直接置空。缺点是刷新页面就失效
还有另外一种方式,直接重置构造器:
js
Function.prototype.constructor = function(){}
5.无限Debugger
一打开F12就无限debugger,这时无法调试其他代码,可以通过call stack调用栈层层找到最开始的调用者:
虽然是加密过的,不过不影响,直接重写函数:
这时debugger已经失效了。
小提示:一般无限debugger都会配合定时器无限复活,把setInterval干掉就行。
五、定位技巧
1.搜索
搜索分为全局搜索,局部搜索。
在开发者工具中,当处于任意一个面板中,按Ctrl + F即为局部搜索,也就是说搜索的内容仅限于当前面板范围内,例如:
在【元素】面板下,搜索的内容就是html标签或者类名,字符串等。
在【日志】面板下,搜索的内容就是打印出来的日志
【源代码】 【网络】面板也是如此道理。
如果想要进行全局搜索,那么按Ctrl + shift + F即可,或者点击三个点,然后选中搜索
搜索技巧在JS逆向过程中非常重要,灵活的使用搜索可以更快的定位到代码中
2.定位
这里以百度页面为例
DOM断点: 例如我在百度输入了查询的内容后,这时将鼠标放在“百度一下”按钮上,它会变一下颜色,那么我如何知道是哪段程序修改了我的样式呢?这时,DOM断点就派上用场了。
[按Ctrl+shift+c定位到具体上的DOM元素上后,然后打上断点:
[DOM断点有三种类型,这里我们只需选择“属性修改”即可,然后DOM断点就已经下上了。
这时鼠标放在“百度一下”就会定位到相关代码,
[这里要注意一点,要沿着调用堆栈找到具体的代码位置才行。很明显,这里jquery的地方都是第三方库,不是我们自己写的代码,所以要观察并一层一层网上找。
当然了,在元素面板里,你可以看到当前页面所有的事件监听,不过这里不是很方便罢了。
XHR断点: 某个请求被发出了,那么我如何知道发起者是谁呢?可以利用xhr断点:
这里以CSDN为例,点击分页,会调用getCourseList接口,这时在【源代码】选项卡中,添加一个xhr断点,输入想要包含的url:
然后点击页码,重新请求时,会被断住:
说明我们的XHR断点已经生效了,只不过这里断住的地方是到了发送请求的最底层方法,如果想知道是那个业务逻辑调用了,还需沿着Call Stack继续往上寻找。
当然了,也可以鼠标悬浮这里,简单的看一下调用顺序:
其他的还有全局侦听器,事件侦听器断点,这里就不在详细说明了。
六、JS HOOK
hook就是钩子函数,劫持原有函数并做一些操作,由于网络上相关教程有很多,这里贴上几个链接:
1.0基础入门通用型 js hook:https://zhuanlan.zhihu.com/p/414106631
2.JS hook大全:https://www.jianshu.com/p/9d6a11c521fd
3.详解JavaScript常用的Hook脚本:https://www.jb51.net/article/241736.htm
一些常见的hook
//解析json的时候断点
(function(){
var parse_ = JSON.parse;
JSON.parse = function(jp){
debugger;
return parse_(jp);
};
})();
//当参数有哪个字段 断点
(function(){
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function(method,url,async){
if(url.indexof("userMark") != -1){
debugger;
}
return open.apply(this,arguments);
};
})();
//请求头有enc字段 断点
(function(){
var sh = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function(key,value){
if(key == 'enc'){
debugger;
}
return sh.apply(this,arguments);
};
})();
//cookie中有(包含)v断点
(function(){
var cookieTemp = ''
Object.defineProperty(document,'cookie',{
set:function (val) {
if(val.indexof('v') != -1){
debugger;
}
console.log('Hook捕获到cookie设置->',val);
cookieTemp = val;
return val;
},
get: function(){
return cookieTemp;
}
});
})();
原文始发于微信公众号(网安知识库):网络安全必学技能-JS逆向基础
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论