Nike登录的acw_sc__v2参数逆向详细思路分析(非常简单,建议入手)含AST解混淆代码

本文主要是介绍Nike登录的acw_sc__v2参数逆向详细思路分析(非常简单,建议入手)含AST解混淆代码,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

分析目录

  • 前言
  • 一、分析
  • 三、总结
  • 四、番外
    • 1.AST解混淆

前言

最近周末闲着无事,看了一下Nike的登录,发现连环境都不用补acw_sc__v2这个参数,分享出来给大家趣味性娱乐一下
在这里插入图片描述

一、分析

打开F12抓包看看登录
在这里插入图片描述
老样子复制curl给抓到Postman里面去分析一下
在这里插入图片描述
具体的参数查找就不演示了(就是简单的删参数看看啥需要啥不需要)。
最后可以发现,cookie只需要这个acw_sc__v2就可以完成登录了。
在这里插入图片描述
这是没有acw_sc__v2参数得到的结果
在这里插入图片描述

此刻回到登录页面的控制台把之前登录获得的acw_sc__v2给干掉
在这里插入图片描述
使用祖传hook代码来hook出cookie(因为鼠标移动也会对cookie造成影响,所以做了一个小小的过滤筛选)

cookie_cache = document.cookie;
Object.defineProperty(document, "cookie", {get: function () {console.log(cookie_cache);// 在获取document.cookie时,执行你想要的操作return cookie_cache; // 返回原始的cookie值},set: function(value) {// 在设置document.cookie时,执行你想要的操作if(value.includes('acw_sc__v2')){debugger;}}
});

断点断上后,往上一找,简单明了的发现了acw_sc__v2参数(arg3)
在这里插入图片描述
接着往上瞅瞅,可以发现arg3是和arg2有关的,那就再往上找找arg2的相关逻辑
在这里插入图片描述
到这里可以发现arg2又是由arg1得来的,那就再往上看看arg1是从哪里来的。
在这里插入图片描述
一直翻到函数的开头,可以发现arg1是作为参数被传进来的在这里插入图片描述
那就调用栈继续往上翻,可以发现arg1是从一段<html><script>...的代码里面提取出来的,这个代码很熟悉啊,不就是我们之前没有带acw_sc__v2参数去请求登录的代码吗,那这个arg1我们就可以暂时固定住,去解决arg2生成的问题了。
在这里插入图片描述
回到调用栈_0x4818,给他重启一下
在这里插入图片描述
再arg2处打上断点
在这里插入图片描述
把arg1加密生成arg2这段逻辑给copy下来

arg1="1029C3D5A2B9A15E217ED61D1C74843F834237A1"
var posList = [15, 35, 29, 24, 33, 16, 1, 38, 10, 9, 19, 31, 40, 27, 22, 23, 25, 13, 6, 11, 39, 18, 20, 8, 14, 21, 32, 26, 2, 30, 7, 4, 17, 5, 3, 28, 34, 37, 12, 36];
var mask = _0x1e8e("0x0");
var outPutList = [];
var arg2 = "";
var arg3 = "";
for (var i = 0; i < arg1[_0x1e8e("0x1")]; i++) {var this_i = arg1[i];for (var j = 0; j < posList[_0x1e8e("0x1")]; j++) {if (posList[j] == i + 1) {outPutList[j] = this_i}}
}
arg2 = outPutList[_0x1e8e("0x2")]("");
console.log(arg2)

然后没有的函数给他补齐一下。
在这里插入图片描述
秉承着缺啥补啥的思想,补了两个参数进去。但是运行起来居然溢出了,在这里,我们就需要跟进去看看什么操作导致了这个代码溢出。
在这里插入图片描述
根据去对照着浏览器的参数值可以发现,这两边明显的不同,_0x3e9e这个数组明显是不一样的,回到浏览器可以发现,在这两个参数之间,还有一个自执行函数,对_0x3e9e这个数组进行了一个操作,应该就是移位操作了
在这里插入图片描述
直接弄下来
在这里插入图片描述
可是一运行,之前的断点都到不了了,可以发现,这个自执行函数里面还是出了问题,经验而谈,应该就是格式化检测这种问题了,老样子跟进去看看,跟了没几步就可以发现,是这里导致了无法正常运行,为什么不往下跟了,因为我看到了RegExp,这不就是正常的正则化检测么
在这里插入图片描述
把对应的参数打印一下,就能看到了,这里是对removeCookie这个进行了正则化检测,这还不简单,直接把_0x981158["test"](_0x3e4c21["removeCookie"]["toString"]())变成true,就可以正常运行到我们之前的断点了,并且_0x3e9e数组也变成和浏览器一样了。

在这里插入图片描述
那我们举一反三想一下,会不会之前这里溢出,也是因为正则化检测呢,直接开搜
在这里插入图片描述
经过排除其余两个RegExp(因为是在补的那个自执行函数里面,不会对下面的结果造成影响了),可以发现上图这里还存在一个RegExp,但是和上面写法又不大一样,那我们这里还是先下一个断点看看是什么情况
在这里插入图片描述
结果怎么说呢,还是大同小异,直接给他改成true,看看还会不会溢出
在这里插入图片描述
可以看到arg2是成功被打印出来了
在这里插入图片描述
和浏览器对比也是一样的效果
在这里插入图片描述
那么就可以着手arg3的事情了,也没什么要分析的了,直接放在arg2后面,一运行就出结果了。

for (var i = 0; i < arg2[_0x1e8e("0x1")] && i < mask[_0x1e8e("0x1")]; i += 2) {var GxjQsM = _0x1e8e("0x3")[_0x1e8e("0x4")]("|"), QoWazb = 0;while (!![]) {switch (GxjQsM[QoWazb++]) {case "0":if (xorChar[_0x1e8e("0x1")] == 1) {xorChar = "0" + xorChar}continue;case "1":var strChar = parseInt(arg2[_0x1e8e("0x5")](i, i + 2), 16);continue;case "2":arg3 += xorChar;continue;case "3":var xorChar = (strChar ^ maskChar)[_0x1e8e("0x6")](16);continue;case "4":var maskChar = parseInt(mask[_0x1e8e("0x5")](i, i + 2), 16);continue}break}
}
console.log(arg3)

在这里插入图片描述
在这里插入图片描述

三、总结

其实没啥难度,主要是一个对正则化的检测,甚至环境都不需要补。主要是给一个思路。

四、番外

当然不仅仅是上面这种方法,还记得不带cookie去访问得到的js代码吗
在这里插入图片描述

1.AST解混淆

如果不想自己手写的,可以直接使用猿人学自带的一键解混淆,不过效果肯定没有自己想要的随心所欲,但是速度快呀。
不过我这里给出我手写的AST解混淆代码,bianhhua.js就是不带cookie去访问得到的js代码,具体每行什么作用,使用gpt自己理解噢~

const {parse} = require("@babel/parser");
const generator = require("@babel/generator").default;
const traverse = require("@babel/traverse").default;
const types = require("@babel/types");
const fs = require("fs");
var AST_code = fs.readFileSync('bianhhua.js', {encoding: 'utf-8'});let AST_parse = parse(AST_code);
traverse(AST_parse, {//  字符串美化,便于观察"StringLiteral|NumericLiteral"(path){path.node.extra && delete path.node.extra;},
})
const js_code = generator(AST_parse, {compact:true}).code;
let AST_parse_1 = parse(js_code);// 获取解密函数,并写入内存
let memory_decode_js = '';
for(let i=0;i<=3;i++){memory_decode_js += generator(AST_parse_1.program.body[i], {compact:true}).code
}
AST_parse_1.program.body[3] = ""
eval(memory_decode_js);
traverse(AST_parse_1, {//  替换加密字符参数"CallExpression"(path){if(path.node.callee.name === '_0x55f3'){path.replaceInline(types.valueToNode(eval(path.toString())));}},
})const js_code_1 = generator(AST_parse_1, {compact:true}).code;
console.log(js_code_1)

在这里插入图片描述

这篇关于Nike登录的acw_sc__v2参数逆向详细思路分析(非常简单,建议入手)含AST解混淆代码的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/725551

相关文章

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

Python itertools中accumulate函数用法及使用运用详细讲解

《Pythonitertools中accumulate函数用法及使用运用详细讲解》:本文主要介绍Python的itertools库中的accumulate函数,该函数可以计算累积和或通过指定函数... 目录1.1前言:1.2定义:1.3衍生用法:1.3Leetcode的实际运用:总结 1.1前言:本文将详

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Spring Boot整合log4j2日志配置的详细教程

《SpringBoot整合log4j2日志配置的详细教程》:本文主要介绍SpringBoot项目中整合Log4j2日志框架的步骤和配置,包括常用日志框架的比较、配置参数介绍、Log4j2配置详解... 目录前言一、常用日志框架二、配置参数介绍1. 日志级别2. 输出形式3. 日志格式3.1 PatternL

Springboot 中使用Sentinel的详细步骤

《Springboot中使用Sentinel的详细步骤》文章介绍了如何在SpringBoot中使用Sentinel进行限流和熔断降级,首先添加依赖,配置Sentinel控制台地址,定义受保护的资源,... 目录步骤 1: 添加 Sentinel 依赖步骤 2: 配置 Sentinel步骤 3: 定义受保护的

linux进程D状态的解决思路分享

《linux进程D状态的解决思路分享》在Linux系统中,进程在内核模式下等待I/O完成时会进入不间断睡眠状态(D状态),这种状态下,进程无法通过普通方式被杀死,本文通过实验模拟了这种状态,并分析了如... 目录1. 问题描述2. 问题分析3. 实验模拟3.1 使用losetup创建一个卷作为pv的磁盘3.

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

Java通过反射获取方法参数名的方式小结

《Java通过反射获取方法参数名的方式小结》这篇文章主要为大家详细介绍了Java如何通过反射获取方法参数名的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、前言2、解决方式方式2.1: 添加编译参数配置 -parameters方式2.2: 使用Spring的内部工具类 -