当前位置:首页 > 技术 > 正文内容

瑞数6 反向工程实战:深圳大学附属医院站点绕过分析

访客 技术 2026年8月17日 2

目标站点地址:https://sghu.sz.edu.cn/HTML/News/Main/102.html

初步分析与环境准备

进入页面后直接打开开发者工具,会发现持续触发 debugger 指令,此为常规干扰手段,可忽略。清除浏览器缓存与所有 Cookie 后重新加载页面。

通过事件监听器追踪脚本执行流程,刷新页面后可定位到关键的 TypeScript 脚本文件(.ts)、启动加载脚本(tsload.js)以及动态内容注入部分(content)。这三个组件是瑞数 v6 防护体系的核心组成部分。

将上述三部分内容分别保存为独立文件,并构建一个基础运行环境:

// env.js
require('./ts.js');
require('./tsload.js');

function get_cookie() {
    console.log(document.cookie);
    return document.cookie;
}
get_cookie();

代理监控与全局对象模拟

为实现对核心对象的完整行为捕获,引入自定义代理机制,用于监听所有属性读写操作:

let setProxyArr = function (proxyObjArr) {
    for (let i = 0; i < proxyObjArr.length; i++) {
        const handler = `{
            get: function(target, property, receiver) {
                console.log("访问:", "get", "对象:", "${proxyObjArr[i]}", "属性:", property, "类型:", typeof property, "值:", target[property], "值类型:", typeof target[property]);
                return Reflect.get(...arguments);
            },
            set: function(target, property, value, receiver) {
                console.log("设置:", "set", "对象:", "${proxyObjArr[i]}", "属性:", property, "值:", value, "值类型:", typeof target[property]);
                return Reflect.set(...arguments);
            }
        }`;
        try {
            eval(`${proxyObjArr[i]} = new Proxy(${proxyObjArr[i]}, ${handler});`);
        } catch (e) {
            eval(`${proxyObjArr[i]} = new Proxy({}, ${handler});`);
        }
    }
};

function watch(object) {
    const handler = {
        get: function (target, property, receiver) {
            if (!['isNaN', 'encodeURI', 'Uint8Array', 'undefined', 'JSON'].includes(property)) {
                console.log("获取属性:", property, "来源:", target, "值:", target[property]);
            }
            return Reflect.get(...arguments);
        },
        set: function (target, property, value, receiver) {
            console.log("设置属性:", property, "值:", value, "来源:", target);
            return Reflect.set(...arguments);
        }
    };
    return new Proxy(object, handler);
}

// 安全函数封装
const safeFunction = function(func) {
    Function.prototype.$call = Function.prototype.call;
    const $toString = Function.toString;
    const symbol = Symbol('native code');
    
    const myToString = function() {
        return typeof this === 'function' && this[symbol] || $toString.call(this);
    };

    const defineProp = function(obj, key, val) {
        Object.defineProperty(obj, key, {
            enumerable: false,
            configurable: true,
            writable: true,
            value: val
        });
    };

    delete Function.prototype.toString;
    defineProp(Function.prototype, 'toString', myToString);
    defineProp(Function.prototype.toString, symbol, 'function toString() { [native code] }');

    defineProp(func, symbol, 'function () { [native code] }');
    return func;
};

全局上下文重建

由于目标环境在沙箱中运行,需手动还原常见全局对象结构:

window = global;
window.Buffer = Buffer;
window.top = window;
window.self = window;
window.window = window;

// 基础定时器
window.setInterval = function setInterval() {};
window.clearInterval = function clearInterval() {};
window.setTimeout = function setTimeout() {};

// MutationObserver 补丁(谨慎使用)
window.MutationObserver = function MutationObserver() {};
window.MutationObserver.prototype.observe = function observe() {};

// 文档对象模拟
function HTMLDocument() {}
Object.setPrototypeOf(HTMLDocument.prototype, window.Document.prototype);
HTMLDocument.prototype.constructor = HTMLDocument;
document = new HTMLDocument();
window.HTMLDocument = HTMLDocument;

// Navigator、Screen、History、Location 等也需类似处理
function Navigator() {}
navigator = new Navigator();
window.Navigator = Navigator;

function Screen() {}
screen = new Screen();
window.Screen = Screen;

function History() {}
history = new History();
window.History = History;

function Location() {}
location = new Location();
window.Location = Location;

// 应用代理
setProxyArr(['window', 'document', 'location', 'history', 'screen', 'navigator']);

DOM API 伪造与检测点绕过

针对文档对象中的关键方法进行模拟,避免因缺失而引发异常:

  • createElement:需支持 divaforminput 等标签创建
  • getElementById:返回一个 <meta> 元素实例
  • getElementsByTagName:需识别 basescriptmeta 标签

特别关注以下两个元素的属性检测:

  • script:检查 innerTextsrcgetAttribute(r="m")parentElement.removeChild
  • meta:检查 getAttributeparentNode.removeChildcontent 属性

请求流程自动化

利用 Python 构建自动化请求流程,抓取并替换原始资源:

import requests
import execjs
from lxml import etree

session = requests.Session()

# 加载补环境脚本
with open("env.js", "r", encoding="utf-8") as f:
    js_code = f.read()

# 第一次请求获取初始响应
headers = {}
response = session.get("https://sghu.sz.edu.cn/HTML/News/Main/102.html", headers=headers)

cookie = list(response.cookies)[0]
cookies = {cookie.name: cookie.value}

# 解析 HTML 提取资源
html = etree.HTML(response.text)
ts_script = html.xpath('//script')[0].text
tsload_url = 'https:' + html.xpath('//script')[1].attrib['src']
tsload_script = session.get(tsload_url, headers=headers).text
content_value = html.xpath('//meta')[1].attrib['content']

# 替换占位符
js_code = js_code.replace('ts文件', ts_script)
              .replace('tsload文件', tsload_script)
              .replace('content文件', content_value)

# 写入新脚本
with open("now.js", "w", encoding="utf-8") as f:
    f.write(js_code)
    print("脚本已生成")

# 执行环境并提取最终 Cookie
cookie_result = execjs.compile(js_code).call('get_cookie')
name, value = cookie_result.split('; path')[0].split('=', 1)
cookies[name] = value

print("最终请求参数:", cookies)

# 发起二次请求
final_response = session.get("https://sghu.sz.edu.cn/HTML/News/Main/102.html", headers=headers, cookies=cookies)
print(final_response.status_code)
print(final_response.text)

成功绕过瑞数 v6 的反爬机制,完成数据获取。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

linux screen 用法详情 (nohup 的替代方案)

一、screen 是什么?能干嘛?screen 是一个终端复用器,可以:在一个 SSH 会话中开多个“虚拟终端”SSH 断线后,程序仍然在后台运行随时重新连接到原来的会话特别适合:nohup 的替代方案跑脚本 / 爬虫 / 训练模型运维、远程开发二、安装 screen# CentOS / Rocky / Almayum install -y screen# Debian / Ubuntuapt i...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。