• JavaScript-Obfuscator4.0.0字符串阵列化Bug及修复方法


    JavaScript-Obfuscator4.0.0字符串阵列化Bug及修复方法

    Javascript-obfuscator是全球知名的开源JavaScript代码混淆加密工具,由俄罗斯程序员Timofey Kachalov开发维护。

    在2022年2月15日发布的4.0.0版本中,其存在一个字符串阵列化Bug,某些情况下会导致混淆结果异常。本文对Bug情况进行说明并提供修复方法。

    注:此bug由JShaman团队发现,并已提交作者修复。

    JShaman是国内专业的javascript源代码安全研究组织,与Javascript-obfuscator保持着友好联络与技术交流。

    Bug描述:


    Javascript-obfuscator4.0.0,其字符串阵列功能,对async函数中的成员对象进行阵列化处理,会导致代码异常。

    例如,一段NodeJS代码:

    1. async function waitPage(page) {
    2. await page.evaluateHandle(function(){
    3. return window.renderdone;
    4. });
    5. }
    6. (async () => {
    7. const puppeteer = require('puppeteer');
    8. puppeteer.launch().then(
    9. async browser => {
    10. console.log('...');
    11. const [page] = await browser.pages();
    12. await page.goto('https://www.baidu.com');
    13. await waitPage(page);
    14. }
    15. )
    16. })();

    使用Javascript-obfuscator进行混淆加密,保护选项只选择了字符串阵列化这一个功能:

    混淆加密后的代码,运行时发生异常,提示有变量未定义:

    注意图中命令行中所显示,第一次执行是在未加密前,可正常使用。第二次是执行加密后的代码,出现错误。

    Bug原因:

    上述JS代码混淆加密后出现错误的原因,是由于进行字符串的阵列化处理时,未考虑是否处于async函数中。导致阵列化时MemberExpression字面量放置到了函数不可访问的外部区域中。如下图所示:

    注:绿线上方是原始代码,做对比用。参考上面图中的错误提示变量,可以看出错误原因。

    Bug修复方案:

    阵列化功能,在JavaScript-Obfuscator目录下的StringArrayTransformer.ts文件中。

    以下为临时修复代码:

    1. //原始: return this.transformNode(node, parentNode);
    2. //修复bug后的代码:
    3. //是否是异步函数的标识
    4. var in_async_function = false;
    5. //递归函数,检测节点所有上级节点,判断是否处于异步函数中
    6. var point = "-";
    7. function detect_async_function(node:ESTree.Node){
    8. console.log(point, node.type);
    9. if(node.type == "FunctionDeclaration"){
    10. console.log(point, node.id?.name);
    11. }
    12. //是函数定义,并且是异步函数
    13. if((node.type == "ArrowFunctionExpression" || node.type == "FunctionDeclaration" || node.type == "FunctionExpression") && node.async == true){
    14. in_async_function = true;
    15. return;
    16. }
    17. //是否达到节点顶部。测试中发现node.parentNode永远存在,达顶点后上级顶点依然是Program
    18. if(node.type == "Program"){
    19. return;
    20. }
    21. if(node.parentNode){
    22. point = point + "-";
    23. detect_async_function(node.parentNode)
    24. }else{
    25. //不能获得父节点,是异常的代码,跳过
    26. in_async_function = true;
    27. return;
    28. }
    29. }
    30. detect_async_function(node);
    31. console.log(node.value,node.loc);
    32. //没有检测出异步函数,正常处理
    33. if(in_async_function == false){
    34. return this.transformNode(node, parentNode);
    35. }

    即:在处理字面量时,判断是否处于async函数体中,如是,则跳过。

    用此方法修复后,运行混淆加密后的代码正常,如下图所示:

  • 相关阅读:
    伙伴匹配(后端)-- 用户注册功能
    Ansible——template模块
    UL 458-2021(2021最新版)陆地车辆和船舶用功率转换器 逆变器和功率转换器逆变器系统
    zookeeper选举机制
    从一文中了解SSRF的各种绕过姿势及攻击思路
    单独用HTML javascript CSS 写三版99乘法表,我就是班里最靓的仔
    005利用Socket.io实现Node.js后端服务与Web前端实时交互的功能
    VR技术的应用与发展_华锐互动
    关于一些网络的概述
    如何理解Spring的IOC和AOP
  • 原文地址:https://blog.csdn.net/w2sft/article/details/125473014