JS逆向技巧总结

news2024/12/29 8:13:33

总的来说,JavaScript 逆向可以分为三大部分:寻找入口、调试分析和模拟执行。下面分别进行介绍。

一,寻找入口

一个网站加载了很多 JavaScript 文件,那么怎么从这么多 JavaScript 里面找到关键的位置,那就是一个关键问题。这就是寻找入口。

但开始寻找前,建议先做以下工作:

  • 判断参数是否需要逆向,可不可以直接复制参数

  • 加密参数是否由之前的请求返回

  • 按加密字符串的特征进行尝试,也许会有意外收获

下面介绍寻找入口时常用的手段。

1.1 巧用搜索

搜索是有一定技巧的,比如加密关键词是 signature,可以搜索 signature、“signature”、signature=、signature: 、sign、URL、headers[ 等。

1.2 Ajax断点+调用栈

它可以在发生 Ajax 请求的时候触发断点。要设置断点,就要先观察 Ajax 请求,假设请求的 URL 为:https://spa2.scrape.center/api/movie/?limit=xxx&page=99

可以看到,URL 中包含 /api/movie ,因此可以填写 /api/movie ,当 Ajax 请求的 URL 包含填写的内容时,就会进入断点停止。

在这里插入图片描述

1.3 Initiator call stack

Initiator 主要是为了监听请求是怎样发起的,通过它可以快速定位到调用栈中。栈的调用顺序为从下到上。

在这里插入图片描述

1.4 事件监听+调用栈

有的时候找不到参数位置,但是知道它的触发条件,此时可以使用事件监听器进行断点。然后结合调用栈进行定位。

1.5 Hook 关键方法

Hook 技术又叫钩子技术,指在程序运行的过程中,对其中的某个方法进行重写,在原先的方法前后加入我们自定义的代码。相当于在系统没有调用该函数之前,钩子程序就先捕获该消息,得到控制权,这时钩子函数既可以加工处理该函数的执行行为,也可以强制结束消息的传递。

要对 JavaScript 代码进行 Hook 操作,就需要额外在页面中执行一些有关 Hook 逻辑的自定义代码,这里推荐一个浏览器插件,叫做 Tampermonkey,中文叫 油猴,利用它,可以在浏览器加载页面时自动执行某些 JavaScript 脚本。由于执行的是 JavaScript ,所以我们几乎可以在网页中完成任何我们想实现的效果,如自动爬虫、自动修改页面、自动响应事件等。

下面以 https://login1.scrape.center/ 网址为例,进行 base64 方法的 hook,以下为油猴中的脚本:

// ==UserScript==
// @name         HookBase64
// @namespace    https://login1.scrape.center/
// @version      0.1
// @description  Hook Base64 encode function
// @author       Vahan
// @match        https://login1.scrape.center/
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    function hook(object, attr){
        var func = object[attr]
        object[attr] = function(){
            console.log('hooked',object,attr)
            var ret = func.apply(object,arguments)
            debugger
            return ret
        }
    }
    hook(window,'btoa')
})();

如果观察出一些门道,可以多使用这种方法来尝试,如 Hook encode 方法,decode 方法,stringify 方法,log 方法,alert 方法等。

二,调试分析

找到入口之后,我们需要搞清楚里面的逻辑是怎样的、里面调用了多少加密算法,经过了多少变量赋值和转换等,以便后面进行模拟调用或者逻辑改写。在这个过程中,我们主要借助浏览器的调试工具进行断点调试分析,或者借助于一些反混淆工具进行代码的反混淆等。

以下总结了一些调试分析时有用的技巧:

扣代码:扣代码时,同级目录的代码要扣全;

调试按钮:用的最多是逐行调试:

在这里插入图片描述

调用栈:可以看到 $_CCBk 的上一步是 $_CGII ,再上一步是 (anonymous)

在这里插入图片描述

改写 JavaScript 文件:

我们知道,一个网页里面的 JavaScript 是从对应服务器上下载下来并在浏览器执行的。有时,可能想要在调试的过程中对 JavaScript 做一些更改,比如说有以下需求:

  • 发现 JavaScript 文件中包含很多阻扰调试的代码或者无效代码、干扰代码,想要将其删除
  • 调试到某处,想要加一行 console.log 输出一些内容,以便观察某个变量或方法在页面加载过程中的调用情况。在某些情况下,这种方法比打断点调试更方便
  • 调试过程遇到某个局部变量或方法,想要把它赋值给 window 对象以便全局可以访问或调用
  • 在调试的时候,得到的某个变量中可能包含一些关键的结果,想要加一些逻辑将这些结果转发到对应的目标服务器

浏览器中的 Sources 面板的 Overrides 功能可以支持实现。在 Overrides 上选定一个本地的文件夹,用于保存需要更改的 JavaScript 文件。更改后保存,可以发现在选定的文件夹下生成了新的 JavaScript 文件,它用于在浏览器加载该 JavaScript 文件时进行替换。

在这里插入图片描述

注意:若使用其他网站调试时生成的本地文件夹,则对于这个网页来说可能不能成功保存 JavaScript 文件,需要新创建一个文件夹。

三,模拟执行

搞清楚整个逻辑后,就需要对整个加密过程进行逻辑复写或者模拟执行,以把整个加密流程模拟出来。

3.1 Python 改写或模拟执行

如果整体逻辑不复杂的话,可以尝试用 python 把整个加密流程实现一遍。

如果整体逻辑较复杂,可以使用 python 来模拟调用 JavaScript 的执行。这种方法需要抠出加密代码及需要的运行环境(可能需要补浏览器环境)。

# pip install PyExecJS
# 前提是已经安装nodejs,相当于通过python来调用nodejs执行js文件
import execjs

#1.实例化一个node对象
node = execjs.get()

#2.js源文件编译
ctx = node.compile(open('./wechat.js',encoding='utf-8').read())

#3.执行js函数,wechat.js 文件中有 getpwd() 函数
funcName = 'getpwd("{}")'.format('123456')
pwd = ctx.eval(funcName)
print(pwd)

3.2 Nodejs 模拟执行 + API

与 python 调用几乎一样,都是将算法代码与调用代码抠出来放在一个 js 文件中,但 nodejs 调用的兼容性更好,需要修改调整的地方较 python 调用少,只是为了让 python 代码能使用,还需要通过 express 暴露成 HTTP 服务,从而实现跨语言的调用。

有了方式一,这种方式作用不大。

3.3 浏览器模拟执行

在算法难以实现时,可以使用 playwright 改写 js 文件,然后进行调用。这种方法只需定位到算法的位置,然后将加密函数挂到全局 window ,当作黑盒调用即可。

安装 playwright :

pip3 install playwright 
playwright install

在这里插入图片描述

案例:https://spa2.scrape.center/

想要获取电影数据,就需要分析出 token 的加密逻辑:
在这里插入图片描述

使用 XHR 断点,定位到核心加密算法的位置如下:
在这里插入图片描述

将修改后的整个 js 文件保存到本地,命名为 chunk.js:
在这里插入图片描述
在这里插入图片描述

python 调用代码如下:

from playwright.sync_api import sync_playwright
import time
import requests

BASE_URL = 'https://spa2.scrape.center/'
INDEX_URL = BASE_URL + '/api/movie?limit={limit}&offset={offset}&token={token}'
MAX_PAGE = 10
LIMIT = 10

context = sync_playwright().start()
browser = context.chromium.launch(headless=True)
page = browser.new_page()
page.route( # 指定路由
    "**/js/chunk-10192a00.243cb8b7.js",
    lambda route: route.fulfill(path="./chunk.js")
)
page.goto(BASE_URL)

def get_token(offset):
    result = page.evaluate('''() => {
    return window.encrypt("%s","%s")
    }''' % ('/api/movie', offset))
    return result

for i in range(MAX_PAGE):
    offset = i * LIMIT
    token = get_token(offset)
    index_url = INDEX_URL.format(limit=LIMIT,offset=offset,token=token)
    response = requests.get(index_url)
    print('response',response.json())

在这里插入图片描述

BASE_URL的值来自下图位置:

在这里插入图片描述

这种方法似乎是一种神技,以后实操用起来。

emm,在对今日头条案例的_signature使用这种方法时,未成功,返回None。暂时没有找到是哪里出了问题。

下面这种形式更加通用:

from playwright.sync_api import sync_playwright


BASE_URL = 'https://static.geetest.com/static/js/slide.7.9.2.js'

context = sync_playwright().start()
browser = context.chromium.launch(headless=True)
page = browser.new_page()
page.route(
    "**/static/js/slide.7.9.2.js",
    lambda route: route.fulfill(path="chunk.js")
)
page.goto(BASE_URL)


result = page.evaluate('''() => {
return window.vahan;
}''')
print(result)

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Outlook发送大文件的问题是什么?怎么解决?

Outlook不仅是一款电子邮件客户端,还包括日历、任务、笔记、联系人等功能,同时与Microsoft Office套件中的其他应用程序(如Word、Excel、PowerPoint等)集成紧密,方便用户在不同应用程序之间切换,提高工作效…

计算机毕业设计Python+Spark股票基金推荐与预测系统 股票基金可视化 股票基金推荐系统 股票基金可视化系统 股票基金数据分析 股票基金爬虫大数据

目 录 摘 要 Abstract 第1章 前 言 1.1 项目的背景和意义 1.2 研究现状 1.3 项目的目标和范围 1.4 论文结构简介 第2章 技术与原理 2.1 开发原理 2.2 开发工具 2.3 关键技术 第3章 需求建模 3.1 系统可行性分析 3.2 功能需求分析 3.3 非功能性…

Kafka-服务端-副本同步-源码流程

杂 在0.9.0.0之前,Kafka提供了replica lag.max.messages 来控制follower副本最多落后leader副本的消息数量,follower 相对于leader 落后当超过这个数量的时候就判定该follower是失效的,就会踢出ISR,这里的指的是具体的LEO值。 对…

为Stable Diffusion换件新衣服

你是不是已经看腻Stable Diffusion默认的webui了,想要换件新衣服。Lobe Theme这个插件就可以帮助你。 首先,我们启动 SD,如果没有安装,可以参考https://mp.csdn.net/mp_blog/creation/editor/139196688。 然后找到扩展选项卡&…

网络安全--计算机网络安全概述

文章目录 网络信息系统安全的目标网络安全的分支举例P2DR模型信息安全模型访问控制的分类多级安全模型 网络信息系统安全的目标 保密性 保证用户信息的保密性,对于非公开的信息,用户无法访问并且无法进行非授权访问,举例子就是:防…

鸿蒙OS开发者高级学习第2课:自由流转(含习题答案)

自由流转两种形态:相继使用(跨端迁移);同时使用( 多端协同) 习题:

linux 用户、用户组操作

一、用户组操作 用户组(group)就是具有相同特征的用户(user)的集合体;比如有时我们要让多个用户具有相同的权限,比如查看、修改某一文件或执行某个命令,这时我们需要用户组,我们把用…

8种数据迁移工具

前言 最近有些小伙伴问我,ETL数据迁移工具该用哪些。 ETL(是Extract-Transform-Load的缩写,即数据抽取、转换、装载的过程),对于企业应用来说,我们经常会遇到各种数据的处理、转换、迁移的场景。 今天特地给大家汇总了一些目前…

Ubuntu 22.04 安装中文字体

笔者在用OpenCV4.9处理图片加水印时,中文乱码。原来是Ubuntu 22.04发行版缺少中文字体支持,因此,笔者就找资料安装了需要的中文字体,特此记录,以备后查。 1、打开终端: 2、更新软件包列表: su…

7基于SpringBoot的SSMP整合案例-表现层开发

目录 1.基于Restfu1进行表现层接口开发 1.1创建功能类 1.2基于Restful制作表现层接口 2.接收参数 2使用Apifox测试表现层接口功能 保存接口: 分页接口: 3.表现层一致性处理 3.1先创建一个工具类,用作后端返回格式统一类:…

图形编辑器基于Paper.js教程05:鼠标画矩形与正方形

优化矩形绘制:在Paper.js中有效管理鼠标事件 在图形应用开发中,准确和高效地处理用户输入,如鼠标事件,是提升用户体验的关键。本文通过一个使用Paper.js的示例,展示如何优化矩形绘制过程,特别是处理不同方…

【大模型】基于ChatGLM进行微调及应用 [更新中......]

文章目录 一、前言二、说明2.1 代码结构2.2 依赖包版本 三、启动对话演示3.1 命令行交互 cli_demo.py3.2 网页交互 web_demo.py 四、微调模型4.1 基于 P-Tuning v2 微调模型4.1.1 软件依赖4.1.2 下载数据集4.1.3 下载模型文件4.1.4 操作步骤 4.2 基于 Full Parameter 微调模型4…

大模型简介

大模型框架 大模型基于深度学习,利用大量数据和计算资源训练具有大量参数的神经网络模型。通过不断地调整模型参数,使得模型能够在各种任务中取得最佳表现。 通常说的大模型的“大”的特点体现在:参数数量庞大、训练数据量大、计算资源需求…

记一次EasyExcel的错误使用导致的频繁FullGC

记一次EasyExcel的错误使用导致的频繁FullGC 一、背景描述二、场景复现三、原因分析四、解决方案五、思考复盘 一、背景描述 繁忙的校招结束了,美好的大学四年也结束了,作者也有10个月没有更新了。拿到心仪的offer之后也开始了苦B的打工生活。 最近接到…

Python爬取豆瓣电影+数据可视化,爬虫教程!

1. 爬取数据 1.1 导入以下模块 import os import re import time import requests from bs4 import BeautifulSoup from fake_useragent import UserAgent from openpyxl import Workbook, load_workbook1.2 获取每页电影链接 def getonepagelist(url,headers):try:r reque…

JAVA里的BigDecimal用法

public class BigDecimaldemo1 {public static void main(String[] args) {System.out.println(0.090.01);//为什么不是0.10呢?} }在使用float或者double类型的数据在进行数学运算的时候,很有可能会产生精度丢失问题。我们都知道计算机底层在进行运算的时候&#x…

SpringBoot中整合ONLYOFFICE在线编辑

SpringBoot整合OnlyOffice SpringBoot整合OnlyOffice实现在线编辑1. 搭建私有的OnlyOffice的服务2. SpringBoot进行交互2.1 环境2.2 我们的流程2.3 接口规划2.3.1 获取编辑器配置的接口2.3.2 文件下载地址2.3.3 文件下载地址 3. 总结4. 注意4.1 你的项目的地址一定一定要和only…

详细django框架+SIMPLEUI+import_export设计web管理后台(四)

目录 1.项目简介 2.搭建django框架 3.引入 SIMPLEUI插件 3.1安装simpleui 3.2 修改设置 3.3 克隆静态资源 3.4登陆测试 4.优化页面 4.1 修改后台名称显示 4.2 增加页面LOGO图标 4.3增加网址图标:目前主要的浏览器都支持favicon.ico图标 4.4 修改APP名称显…

用摄像头实现识别道路中的车道线、行人与车辆检测(级联分类器、HOG+SVM、行人检测)

基于树莓派的智能小车,用摄像头实现识别道路中的车道线识别、行人检测与车辆检测。 本项目旨在开发一套基于摄像头的智能道路环境感知系统,该系统能够实时识别道路中的车道线、行人与车辆,为自动驾驶汽车、智能交通管理以及辅助驾驶系统提供关…

Go语言数据类型--常量、iota枚举、数据类型分类

变量:程序运行期间,可以改变的量,变量声明需要var关键字。 常量:程序运行期间,不可以改变的量,变量声明需要const关键字。 自动推导 常量的自动推导不能加:; 不同类型数据的声明 可以使用…