JS逆向实战:优雅去除PVE“无效订阅”提示

admin 2026-04-16 04:03:34 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文介绍利用JSHook技术优雅去除ProxmoxVirtualEnvironment(PVE)无订阅提示弹窗的实战方法。通过分析PVE前端代码定位弹窗函数Ext.Msg.show,编写油猴脚本在特定标题时拦截弹窗调用,并解决脚本注入时机问题。相较于直接修改源码,该方法具有版本兼容性强、维护成本低的优势,并提供了完整可用的代码实现。 综合评分: 82 文章分类: WEB安全,逆向分析,安全工具,实战经验,应用安全


cover_image

JS逆向实战:优雅去除 PVE “无效订阅”提示

原创

LLLibra146 LLLibra146

LLLibra146

2025年8月8日 08:01 北京

在小说阅读器读本章

去阅读

大家好,好久不见了,今天分享一种利用 JS Hook 技术去除 Proxmox Virtual Environment (PVE) “无效订阅”弹窗的方法。相较于直接修改源码,此方案更为优雅,可避免因 PVE 版本更新导致修改失效的问题。

PVE

首先,为不熟悉 PVE 的小伙伴简单介绍一下:

PVE(Proxmox Virtual Environment)是一个开源的服务器虚拟化管理平台。它基于Debian Linux,集成了KVM(Kernel-based Virtual Machine)用于虚拟机管理和LXC(Linux Containers)用于容器管理。PVE允许你在同一台物理服务器上运行多个独立的操作系统实例,无论是Windows、Linux虚拟机还是轻量级容器。它提供了一个直观的Web界面,方便用户创建、配置、监控和管理这些虚拟资源,是构建私有云或虚拟化环境的理想选择。

为什么会有这个需求呢?因为我之前在家里搭了一个 PVE 服务端,开了一堆虚拟机和容器,顺便也可以把它当做 nas 来使用,开几个 smb 文件夹,还是很香的。

PVE 完全开源免费,它的商业模式是提供增值服务,如果不订阅也不会影响任何功能的使用。对于个人用户而言,免费的无订阅模式已足够使用,其主要区别在于更新源的稳定性——无订阅源可能包含未充分测试的更新,不建议用于生产环境。

image-20250807214052171

目前我使用 2000 多块的硬件跑了 2 年+也挺稳定的,除非有更新否则不用关机,完全满足我的需求。

尽管功能不受影响,但使用无订阅源会在每次登录成功后弹出一个“无有效订阅”的提示框。有时该弹窗的“确定”按钮甚至无法点击,必须刷新页面才能关闭,这在日常使用很是烦人。

传统解决方案是直接修改 PVE 的前端 JS 源码,但这种方式的缺点在于,一旦 PVE 面板更新,就需要重新修改,操作较为繁琐。因此,我采用 JS 逆向的思路,通过编写油猴(Tampermonkey)脚本来 Hook 关键函数,从而一劳永逸地屏蔽该弹窗。

寻找 hook 点

image-20250807220716721

要 hook 弹窗,首先要找到弹窗的地方,这里可以直接参考网上其他人的方法,使用关键字 data.status 来搜索,基本上第一个结果就是我们要找的地方。

image-20250807221832486

image-20250807220849422

或者可以完整的执行一遍登录的流程,查看所有的接口请求,根据关键字找到 URL,然后搜索 URL 也可以找到弹窗的地方。

hook 弹窗

找到 hook 点以后,就要思考如何让弹窗无法弹出来,先分析一下代码。

image-20250807222020657

首先请求使用了一个工具函数 Proxmox.Utils.API2Request 发出,这里是第一个 hook 点,可以判断 URL 是否是特定的 URL,然后直接忽略请求,也就不会执行请求的 callback 代码了。继续往下看,弹窗是由另一个工具函数 Ext.Msg.show 弹出来的,这里是第二个 hook 点,可以 hook 弹窗的工具函数,让它在某个 title 的时候不执行。

继续往下看,请求成功以后会执行一个 orig_cmd 方法,为了不影响正常的调用流程,我这里选择的第二个 hook 点,在弹窗的时候判断是否是无订阅的弹窗,然后让其不再执行。

hook 代码

新建一个油猴脚本,写入以下代码:

// ==UserScript==
// @name         PVE 移除订阅按钮
// @namespace    http://tampermonkey.net/
// @version      2025-08-06
// @description  try to take over the world!
// @author       You
// @match        https://xxxxx:8006/
// @icon         https://www.google.com/s2/favicons?sz=64&domain=233.27
// @grant        none
// @run-at       document-idle
// ==/UserScript==

(function () {
    'use strict';
    console.log('loaded!');
    let s = Ext.Msg.show;
    Ext.Msg.show = function (a) {
        if (a.title === '无有效订阅') {
            console.log('return!')
            return;
        } else {
            s(a);
        }
    }
})();

代码很简单就不多解释了,别忘了添加:// @run-at       document-idle,它的作用是让油猴脚本在页面加载完成后再注入,因为过早的注入可能工具函数还没有初始化完成,会导致注入失败。

hook 尝试

image-20250807222756063

刷新页面会发现报错了,提示没有找到 show 属性,油猴注入的时机已经很晚了,在页面加载后才执行,为什么还会报错呢?猜测可能是因为有些代码不是立马就初始化的,可能使用了 settimeout 之类的方案使得初始化被延迟执行了。

分析具体的执行逻辑比较麻烦,我这里选择一个比较简单的方案,同样使用 settimeout 延迟执行,因为我测试了一下在页面加载完成后手动执行 hook 脚本是可以正常执行的。

修改后的代码(此代码会丢失 this,最新代码详见评论区):

(function () {
    'use strict';
    setTimeout(function () {console.log('loaded!');
        let s = Ext.Msg.show;
        Ext.Msg.show = function (a) {
            if (a.title === '无有效订阅') {
                console.log('return!')
                return;
            } else {
                s(a);
            }
        }},2000)
})();

刷新页面重新测试。

image-20250807225651735

image-20250807225754448

可以看到,控制台成功打印了加载信息,登录后的弹窗也不再出现。至此,问题完美解决!

总结

以上就是本次利用 JS Hook 去除 PVE 订阅提示的全过程。相较于直接修改源码,这种方式无疑更加灵活和持久,感兴趣的小伙伴可以自己试一下。

我创建了一个逆向交流群,想要进群的小伙伴可以在后台点击“联系我”菜单或者扫码,添加微信并且备注“交流群”,我会拉你进群。

推荐阅读:

AST 技巧:还原逗号表达式

AST 技巧:压缩变量定义

JS调试技巧:避免控制台卡死的日志断点使用技巧

0基础1分钟解密任何HTTPS加密流量

JS调试技巧:如何让时间和随机数“听你指挥”?升级版!

AST 技巧:模版(template)的高级用法

如何在浏览器中使用 AST 实时反混淆?(附AST模版可直接使用)

AST 使用技巧:如何快速分析混淆代码结构

在 JS逆向时如何 hook 属性?

如何 “正确” hook JS方法


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:LLLibra146 LLLibra146 LLLibra146《JS逆向实战:优雅去除 PVE “无效订阅”提示》

评论:0   参与:  0