【JavaScript 逆向】猿人学 web 第十八题:jsvmp,洞察先机

news/2024/5/5 11:08:51/文章来源:https://blog.csdn.net/Yy_Rose/article/details/126973147

案例目标

网址:第十八题 jsvmp 洞察先机 - 猿人学

本题目标:抓取 5 页数字,计算加和并提交结果

常规 JavaScript 逆向思路

一般情况下,JavaScript 逆向分为三步:

  • 寻找入口:逆向在大部分情况下就是找一些加密参数到底是怎么来的,关键逻辑可能写在某个关键的方法或者隐藏在某个关键的变量里,一个网站可能加载了很多 JavaScript 文件,如何从这么多的 JavaScript 文件的代码行中找到关键的位置,很重要;

  • 调试分析:找到入口后,我们定位到某个参数可能是在某个方法中执行的了,那么里面的逻辑是怎么样的,调用了多少加密算法,经过了多少赋值变换,需要把整体思路整理清楚,以便于断点或反混淆工具等进行调试分析;

  • 模拟执行:经过调试分析后,差不多弄清了逻辑,就需要对加密过程进行逻辑复现,以拿到最后我们想要的数据

接下来开始正式进行案例分析:

寻找入口

F12 打开开发者人员工具,刷新网页进行抓包,在 Network 中可以看到数据接口为 18data?page=1,响应预览中可以看到当前页面各数字数据:

但是并没有看到类似加密的字段,通过对比,点击第二页的后,数据接口变成了 18data?page=2&t=XXX&v=XXX,请求 url 中多出了两个参数 t 和 v:

t 看起来像是时间戳,不过时间戳一般为 13 位,这里只有 10 位,v 是一串加密内容,从 Initiator 处跟栈到 getdata 中,逆向分析以下加密逻辑:

调试分析

会跳转到 18 文件的第 764 行,点击左下角的 { } 对其进行格式化操作,在第 1453 行 send 处打下断点调试分析,在第 1423 行创建了一个 XMLHttpRequest 对象,XMLHttpRequest 用于在后台与服务器交换数据,后面通过 xml.open( ) 建立链接,一个 HTTP 请求,xml.send( ) 发送请求,连接对象为当前接口的 url:

在第 1427 行定义了个 data 参数,在第 1429 行打断点调试,data 传入了当前页面所有数字:

  • responseText:将响应信息作为字符串返回

  • responseXML:将响应信息格式化为 XML 文档格式返回

在第 1452 行建立连接处打断点,鼠标选中 xml.open 进入到 y__ 中:

在第 1365 行,这块就是 jsvmpzl 框架混淆过的代码,全是大小写的 v、u、y 和下划线,非常不便于调试分析,第 1415 行能看到该框架的版本,在第 1385 行打下断点:

先分析一下,_U__ 函数有四个参数,后三个定义在第 771 行:

  • ___:判断是 node 环境还是浏览器环境

  • v__:window 环境和鼠标点击事件(argument)

  • V__:返回指定 unicode 编码对应的字符

_ 参数在这一块并没有定义,鼠标选中后查看,展开后发现了特别的字段 AES、mode、pad,这里就看起来是数组中的对象经过了 AES 加密,并且加密模块为 CBC,填充方式为 Pkcs7:

并且这里类似于鼠标滑点坐标,断点调试时也发现只要鼠标在页面晃动断点就能断住:

在第 1385 行打断点,向上跟栈,跟到 _y__ 处,这里将 __ 数组作为参数传递给了 yU[_v] 函数:

return yU_[_v].apply(yU_, __)

在第 1338 行,在控制台打印输出一下,_v 为 createEncryptor,是个加密方法,yU_ 有个 encryptBlock,跟进去发现又跳转回了 y__ 函数位置:

__ 中看到了关键字 iv、mode、padding,更确定了这里有过 AES 加密处理:

在该行插桩打下日志断点,鼠标在网页中滑动控制台会打印出如下内容,与 _[1][0]['mouse'] 中的鼠标坐标一致:

这部分和 _U__ 函数都囊括在第 979 行的 __V 函数体中,往后跟栈,所有的堆栈都走到其中,可以尝试 hook 该函数中的 _ 参数的加密内容,找找突破口__V 函数有五个参数,hook 内容如下:

encrypt = _[1][0]['CryptoJS']['AES']['encrypt']
_[1][0]['CryptoJS']['AES']['encrypt']=function(a,b,c,d,e){var result = encrypt(a,b,c,d,e);console.log(result.toString())debugger;return a;
}

先在第 1385 行打断点断住后,将以上内容输入到控制台中进行 hook,不然会报错显示 _ 未定义,双击打印出的结果,即可进入到虚拟机中:

取消其他断点,点击第二页,即会在虚拟机中 hook 代码的 debugger;处断住,并会在控制台打印出如下内容:

通过与 v 参数对比,内容相似,长度匹配,即 __V 函数完成了对 v 参数的加密,且使用了 AES 加密,向上跟栈到 _y 中,又会跳转到第 1338 行,此处为加密位置:

上文讲过 __ 数组作为参数传递给了 yU[_v] 函数,__ 数组中的三个对象分别对应 hook 函数中的 a、b、c:

一般的 AES 加密方式如下,需要传入 text、key、iv,即对应 a、b、c.iv:

function aesEncrypt() {var key = CryptoJS.enc.Utf8.parse(aesKey),iv = CryptoJS.enc.Utf8.parse(aesIv),srcs = CryptoJS.enc.Utf8.parse(text),encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: iv,mode: CryptoJS.mode.ECB,padding: CryptoJS.pad.Iso10126});return encrypted.toString();
}
​
var aesKey = 'YyRose',aesIv = 'YyRose',text = 'YyRose';
​
console.log(aesEncrypt())

打印一下这三部分内容:

可以看出来 a 是页码加上 | 符再加上鼠标坐标组成的,那 b 和 c.iv 偏移量呢,在第 1338 行插桩打印下日志:

取消其他断点,点击第二页,打印出来的内容中有如下部分,第四行样式与 b 和 c.iv 一致,第四行是由第二行和第三行两个一样的内容组合而成的,第二行是由十三位时间戳去掉后三位转换为十六进制后,去掉前两位得到的结果,至此分析完成:

完整代码

JavaScript 代码

// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')function vEncrypt(text_num) {var text = text_num + "|67m508,66m509,66d509,66m509,66u509"var timestamp = Math.round(Date.parse(new Date())/1000);var aesIv = timestamp.toString(16) + timestamp.toString(16);var key = CryptoJS.enc.Utf8.parse(aesIv),iv = CryptoJS.enc.Utf8.parse(aesIv),srcs = CryptoJS.enc.Utf8.parse(text),encrypted = CryptoJS.AES.encrypt(srcs, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});return encrypted.toString();
}// console.log(vEncrypt(2));

Python 代码

sessionid 要改为自己的:

import timeimport execjs
import requests
import redef yrx18_demo():num_sum = 0for page_num in range(1, 6):with open('yrx18.js', 'r', encoding='utf-8') as f:encrypt = f.read()v = execjs.compile(encrypt).call('vEncrypt', page_num)headers = {"user-agent": "yuanrenxue.project",}cookies = {"sessionid": " your sessionid ",}params = {"t": str(int(time.time() * 1000))[:-3],"v": v}url = "https://match.yuanrenxue.com/match/18data?page=%s" % page_numresponse = requests.get(url, headers=headers, cookies=cookies, params=params)for i in range(10):value = response.json()['data'][i]num = re.findall(r"'value': (.*?)}", str(value))[0]num_sum += int(num)print(num_sum)if __name__ == '__main__':yrx18_demo()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_11477.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Redis】arm64架构,docker的Redis出现Failed to test the kernel for a bug that could lead to data corruption

一、问题说明在运行docker的redis镜像,log打印 # Failed to test the kernel for a bug that could lead to data corruption during background save. Your system could be affected, please report this error.# Redis will now exit to prevent data corruption. Note tha…

Replication(下):事务,一致性与共识

本文主要介绍事务、一致性以及共识,首先会介绍它们怎么在分布式系统中起作用,然后将尝试描述它们之间的内在联系,让大家了解,在设计分布式系统时也是有一定的“套路”可寻。最后将介绍业界验证分布式算法的一些工具和框架。希望能…

告别if else,试试这款轻量级流程引擎吧,自带IDEA插件真香

在我们平时做项目的时候,经常会遇到复杂的业务逻辑,如果使用if else来实现的话,往往会很冗长,维护成本也很高。今天给大家推荐一个轻量级流程引擎 LiteFlow ,可以优雅地实现复杂的业务逻辑,本文将以电商项目…

HashSet的存储机制

文章目录HashSet类内部存储机制实验1.不重写hashcode equals方法2.重写,但改写equals3.重写参考:HashSet类 HashSet是Set接口的典型实现,大多数时候使用Set集合时就是使用这个实现类。HashSet按Hash算法来存储集合中的元素,因此具…

PID控制算法

闭环控制(反馈回路close loop): 闭环控制系统需要目标量,执行器,传感器 通过偏差量获得执行量是最为重要的 目标量和传感器获得的执行器数据都需要是连续的; 偏差量来自于传感器和目标量数据和执行量不是同一个单位,需要一个比例P系数进行规整; 偏差量=目标量-当前位置量…

Java项目:JSP宠物店管理系统

作者主页:夜未央5788 简介:Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前后台,主要分为管理员与用户两种角色,管理员登录后台,普通用户登录前台; 管理员角色包含…

【LeetCode每日一题】——面试题17.16.按摩师

文章目录一【题目类别】二【题目难度】三【题目编号】四【题目描述】五【题目示例】六【解题思路】八【时间频度】九【代码实现】十【提交结果】一【题目类别】 动态规划 二【题目难度】 简单 三【题目编号】 面试题17.16.按摩师 四【题目描述】 一个有名的按摩师会收到…

App移动端测试(10)—— Monkey自定义脚本案例

01、前言 Monkey自定义脚本案例:QQ的操作 02、Monkey API LaunchActivity(pkg_name, cl_name)启动应用的Activity。参数:包名和启动的 Tap(x, y, tapDuration)模拟一次手指单击事件。参数:x,y为控件坐标,tapDuration为点击的持续…

你到底是前端人还是搬砖人?推荐一款国产摸鱼神器!

☀️ 前言 大家好我是小卢,前几天在群里见到有群友抱怨一周内要完成这么一个大概20~30页的小程序。 群友: 这20多个页面一个星期让我开发完,我是不相信😮‍💨。群友1: 跑吧,这公司留着没用了,不…

【Python 技能树共建】Beautiful Soup

Beautiful Soup 模块是什么 初学 Python 爬虫,十之八九你采集的目标是网页,因此快速定位到网页内容,就成为你面临的第一道障碍,本篇博客就为你详细说明最易上手的网页元素定位术,学完就会系列。 本文核心使用到的是 …

Spring Security 中的RBAC角色和权限

在这篇文章中,我们将看看使用 Spring boot的R ole B ased A ccess Control ( RBAC )。 了解 RBAC 在 RBAC 模型中存在三个关键实体。他们是, 用户或主题 ——执行操作的系统参与者。它可以代表一个自然人、一个自动帐户,甚至是另一个应用程…

专业思维导图软件 Mindjet MindManager 2021下载

Mindjet MindManager 2021 是一款专业的思维导图软件,美国Mindjet公司开发,一款视觉工作管理的思维导图软件,界面友好功能强大,头脑风暴、会议管理及项目管理工具帮您轻松创建思维导图,有序组织思维、资源和项目进程。…

win10+cuda+cudnn+anconda+pytorch+pycharm全家桶安装

1、下载安装cuda: 网址:CUDA Toolkit 11.7 Update 1 Downloads | NVIDIA Developer 网址下方可以找到以前版本 安装完后,可以在命令行窗口输入nvcc --version查看cuda版本是否正确 显卡驱动版本与cuda版本对应关系: 2、安装cud…

操作系统实验四 进程间通信

★观前提示:本篇内容为操作系统实验内容,代码等内容经测试没有问题,但是可能会不符合每个人实验的要求,因此以下内容建议仅做思路参考。 目录一、实验目的二、实验内容三、具体实现四、实验总结一、实验目的 多道程序设计中&…

【前端面试】-- 必知必会的promise题

Promise 想必大家都十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗? 请迎接测试: 以下 promise 均指代 Promise 实例,环境是 Node.js 题目一: const promise new Promise((resolve, reject) > {conso…

ES8JC-ASEMI快恢复二极管ES8JC

编辑:ll ES8JC-ASEMI快恢复二极管ES8JC 型号:ES8JC 品牌:ASEMI 封装:SMC 特性:快恢复二极管 正向电流:8A 反向耐压:600V 恢复时间:35ns 引脚数量:2 芯片个数:1 芯片尺寸:84MIL 浪涌电流:125A 漏电流:<5ua 工作温度:-40℃~150℃ 包装方式:30/管;3000/箱 备受…

华为云各Region网络延迟实测

一、测试综述 测试内容&#xff1a; 序号 评测内容 测试日期 1 华为云各大区公网接入网络延迟 2022-09-20 2 华为云各大区之间网络延迟&#xff08;通过公网&#xff09; 2022-09-20 3 华为云各大区之间网络延迟&#xff08;通过云连接&#xff09; 2022-09-20 测…

【Linux】聊聊删文件的那些破事

聊聊删文件的那些破事前言正文rm命令find命令perl方式10w文件删除对比50w文件删除对比100w文件删除对比结语前言 在操作系统的日常运维中&#xff0c;我们经常会做文件的创建、删除、修改操作&#xff0c;尤其是删除&#xff0c;无论是定期清理日志文件&#xff0c;还是做完一…

传统光流方法汇总

又搬运了一个3d视觉相关的~~ 还是先道歉 就是学习用 还是公交上回家看那种 ~~ 这次分享传统光流方法汇总及其在深度学习中的应用&#xff01;&#xff08;基于相位/能量/匹配/变分&#xff09; 回望传统光流估计方法 近年来&#xff0c;随着深度学习技术的快速发展&#xff…

嵌入式分享合集63

一、PCB为什么一定要做阻抗 在具有电阻、电感和电容的电路里&#xff0c;对交流电所起的阻碍作用叫做阻抗。阻抗常用Z表示&#xff0c;是一个复数&#xff0c;实部称为电阻&#xff0c;虚部称为电抗。 其中电容在电路中对交流电所起的阻碍作用称为容抗&#xff0c;电感在电路…