JS逆向学习之JS语法(一)

目录
1.前言:
为什么在渗透测试/安全领域要熟悉 JS 逆向?
▪ 典型场景与案例分析
2. JavaScript 基础语法概览
2.1变量
2.1.1 变量声明方式
2.1.2 常用数据类型
2.2运算符
2.3函数
2.3.1 函数声明 & 表达式
2.3.2 箭头函数
2.3.3 作用域与闭包
2.4流程控制
3.逆向相关核心语法点
1.常见对象与原型链
2. 字符串相关
3. 动态代码执行
4. 常用加密与数据序列化API
5. 异步与网络相关
6. 事件与 DOM 相关
7. 调试相关要点

1.前言:

为什么在渗透测试/安全领域要熟悉 JS 逆向?

在黑盒渗透测试实践中,我们频繁遭遇各类请求加解密场景。这是由于为满足等保合规要求,大量行业系统(如金融、政务领域)开始对 HTTP 请求体进行加密处理,并引入动态签名、时间戳校验、随机 RequestId 等防御机制。这些技术手段直接导致传统渗透方式(如暴力破解、数据包重放/篡改)失效——攻击者无法直接解析请求结构,更难以构造有效攻击载荷。
典型困境示例

  • 无法爆破登录接口:密码字段被前端 RSA/AES 加密,原始字典直接发包将被服务端拒绝
  • 难以批量测试越权:请求需携带动态生成的 HMAC 签名,但签名逻辑完全封装在前端 JS 中
  • 无法绕过风控拦截:请求头需附加由 JS 生成的设备指纹/行为轨迹加密参数
    此时,JS逆向分析便成为突破此类防御体系的核心技术手段——通过逆向加密算法、解析签名规则、提取关键参数生成逻辑,攻击者可精准复现合法请求构造流程,进而穿透前端防护实现深度渗透。

▪ 典型场景与案例分析

这里我介绍一个靶场https://github.com/0ctDay/encrypt-decrypt-vuls/,这是一个本地JS逆向靶场,当我们需要练习JS逆向时,可以在这上面进行练习。
这里我推荐使用fofa在网上搜索一个

body="encrypt-labs" && country="CN"

随便打开一个就可以了,之所以这里我推荐使用fofa寻找靶场,是因为JS靶场不用拿到flag,不用担心目录乱改和后端魔改,只需要在前端成功逆向出来即可,这时完全可以使用网上的靶场。(因为不知道网上的靶场过段时间还能不能连接,所以就不放链接了)
图片
这时可能有人会有疑问,这不就是一个普通的登录页面吗?为什么会用上js呢?别急,我们抓包来看看。
首先请求体这里可以看到一大串加密数值,这种情况根本无法从burp进行爆破,这时就需要还原其加密及预处理机制了。
图片
你以外就仅仅只有这点吗?再来看看这个
这是0佬写的靶场vue/_demo,点进去是这样
图片
抓个包来看看
图片
你可能会说,这不是和上一个一样吗?不不不,我们可以放到repeater里重放试试
图片
这里可以看到相同的数据造成了不同的回显结果,这是因为其携带动态生成的requestID,在这个数据包中,同时拥有签名认证sign和requestID,当requestID中的值重复或者不满足格式时,便会被waf拦截。所以js逆向好啊,得学啊。

2. JavaScript 基础语法概览

2.1变量

每一种语言都是从变量开始学的,js也不例外,因为主要学习的是js逆向,所以这里仅对js语法进行简单说明。

2.1.1 变量声明方式
  • var:函数作用域,可被重复声明,变量提升(重点了解“提权”问题);
  • let:块级作用域,不可重复声明,不变量提升;
  • const:块级作用域,声明后不可重新赋值,常用于常量。
    练习js的工具我们需要用到vscode和node.js,相信大家都已经安装过了吧,如果没有可以看这个帖子。
    //这里附之前js环境搭建帖子链接//
    图片
2.1.2 常用数据类型
  • 原始类型:String, Number, Boolean, null, undefined, Symbol, BigInt
  • 引用类型:Object, Array, Function, Date
    示例:用typeof测试各类型变量(typeof检测变量类型)
console.log(
    typeof "abc",
     typeof 5, 
     typeof true, 
     typeof {}, 
     typeof [], 
     typeof function(){});

图片

2.2运算符

到了运算符环节了,其实js和大多数语言一样,运算符也是来来回回那么几样,这里也不再多说了。

2.3函数

学习js逆向就是和各种函数打交道,所以函数也是必须要了解的。

2.3.1 函数声明 & 表达式

函数的声明有两种方式,表达式和函数声明。

  • 声明:function foo(){}
  • 表达式:const foo = function(){}
    区别:
  1. 函数声明会被提升到当前作用域顶部,因此可以在声明前调用
  2. 函数表达式中的命名,只在函数内部可用,外部无法访问
  3. 函数声明必须有函数名称,而表达式可以匿名
sayHello(); // 函数调用,声明函数可在声明前调用
function sayHello() {
  console.log("Hello!");
}
// 2. 函数表达式 - 不会提升
try {
  sayGoodbye(); // 先尝试调用,报错: sayGoodbye is not a function
} catch (e) {
  console.log("错误:", e.message);
}
const sayGoodbye = function() {
  console.log("Goodbye!");
};
sayGoodbye();//这里正常调用
// 3. 匿名函数表达式
const multiply = function(a, b) {//这里没有函数名称
  return a * b;
};
console.log("乘法结果:", multiply(3, 4));
// 4. 命名函数表达式(有名称标识符)
const calculate = function factorial(n) {//函数名称是factorial
  return n <= 1 ? 1 : n * factorial(n - 1);
};
console.log("阶乘结果:", calculate(5));
// 尝试访问函数表达式内部名称(外部不可访问)
try {
  console.log(factorial(5)); //尝试直接使用函数名称调用函数,报错: factorial is not defined
} catch (e) {
  console.log("错误:", e.message);
}

图片

2.3.2 箭头函数
  • 相比普通函数语法更简洁,只能作为表达式,常规用法不能用作构造函数(不支持 new)。
  • 箭头函数不会创建自己的 this,其 this 绑定在定义时所在的外层作用域。
    示例:使用this访问箭头函数和普通函数的对象
const obj = {
  name: 'Object',
  normal: function() { console.log(this.name); },
  arrow: () => { console.log(this.name); }
};
obj.normal(); // 输出: "Object" (this 指向 obj)
obj.arrow();  // 输出: undefined (因为 window.name 未定义,this 指向全局 window 对象)

图片

2.3.3 作用域与闭包
  • 作用域:变量的有效范围,包括全局/函数/块级作用域。
  • 闭包:闭包指“函数可以记住并访问其定义时的作用域”,即使在其外部执行。其常见于函数内部返回一个内部函数,内部函数能访问外部函数的变量,常用于隐藏变量/敏感数据,对逆向极为重要。
    示例:实现一个基本闭包计数器
function makeCounter(){
  let count = 0;
  return function(){
    return ++count;
  }
}
let counter = makeCounter();
console.log(counter()); //1
console.log(counter()); //2

图片

2.4流程控制

到了典型的流程控制了,条件语句:ifswitch循环语句:forwhiledo...while跳转语句:breakcontinuereturn等等,这些想必在其它语言时已经学习过了,因语法格式相同,就不在过多讲述了。

3.逆向相关核心语法点

想必到了这里你已经可以看懂大部分的js代码了,进入这一步已经可以开始最初的加密函数定位操作了,在渗透测试中,我们所需要的js知识到这一步已经差不多了,剩下的可以在实战中进行提升。当然,如果你的最终目的不是渗透测试,或者非常高级的渗透测试,想要达到通过反混淆–分析代码逻辑–研究参数作用–添加补环境–最终通过本地运行JS来加解密,那可能你还需要很多逆向相关的知识点,这里我举一些例子:
这里你还需要学习

1.常见对象与原型链

对象的创建:字面量、new Object()、构造函数
属性访问与操作:点/中括号访问,增删改查属性,delete 用法
对象枚举遍历:for…in、Object.keys()、Object.values()、Object.entries()
原型链与继承:proto、prototype、构造函数继承、Object.create
方法与 this:对象方法定义,this 的多种指向情况、箭头函数不绑定 this
hasOwnProperty:属性归属判断,混淆常避开此方法
对象 API 常用:Object.assign()、Object.defineProperty、JSON.stringify/parse
getter/setter:调试时常见属性访问拦截
对象解构、剩余参数:混淆时常用于分散变量
属性特性:可枚举性、可写性、可配置性(Object.getOwnPropertyDescriptor)
类型判断:typeof/instanceof、Array.isArray()

2. 字符串相关

常用方法:split、substring、substr、slice、replace、charCodeAt、fromCharCode
编码/解码:decodeURIComponent、encodeURIComponent、unescape、escape
拼接与拆解:字符串拼接混淆、模板字符串、Unicode/十六进制转义

3. 动态代码执行

eval / new Function:动态执行字符串中的代码,常被用做混淆和运行时还原
setTimeout/setInterval:传递匿名函数或字符串另类动态执行途径

4. 常用加密与数据序列化API

Base64:atob/Btoa,手写和常见第三方库
CryptoJS等调用:如何识别并断点调试加密运算过程
常见加密算法识别:md5, sha1, aes等在源码中的实现模式
JSON:JSON.stringify/parse,体会序列化/反序列化过程

5. 异步与网络相关

异步实现方式:回调、Promise、async/await
定时器:setTimeout/setInterval,影响代码流程
XHR/Fetch:识别和定位加密请求参数的生成与发送位置

6. 事件与 DOM 相关

事件绑定:addEventListener/onclick,常作为逆向入口埋点
常见 API 监听点:window.onload、表单提交、按钮点击等
DOM 读取/设置:getElementById、querySelector、innerText/innerHTML 等,与反爬有关的字段捕获

7. 调试相关要点

断点下标查找:所有动态加解密出现地
代码插桩:console/alert/log注入,随时打点观察关键变量变化
异常处理:try…catch拦截隐藏流程

《网络安全从零到精通全套学习大礼包》

96节从入门到精通的全套视频教程免费领取

如果你也想通过学网络安全技术去帮助就业和转行,我可以把我自己亲自录制的96节 从零基础到精通的视频教程以及配套学习资料无偿分享给你。

请添加图片描述

网络安全学习路线图

想要学习 网络安全,作为新手一定要先按照路线图学习方向不对,努力白费。对于从来没有接触过网络安全的同学,我帮大家准备了从零基础到精通学习成长路线图以及学习规划。可以说是最科学最系统的学习路线,大家跟着这个路线图学习准没错。

请添加图片描述

配套实战项目/源码

所有视频教程所涉及的实战项目和项目源码

在这里插入图片描述

学习电子书籍

学习网络安全必看的书籍和文章的PDF,市面上网络安全书籍确实太多了,这些是我精选出来的

在这里插入图片描述

面试真题/经验

请添加图片描述

以上资料如何领取?

img

fb5d4309b20.jpeg#pic_center)

面试真题/经验

请添加图片描述

以上资料如何领取?

img

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐