Tài liệu
/
Công thức
/

Telemetry & phản ứng phòng thủ của VM

Telemetry & phản ứng phòng thủ của VM

Pro
v7.1.0+

Báo cáo các phát hiện phòng thủ của VM về backend của bạn bằng vmDefenseHook, và tinh chỉnh cách từng nhóm phát hiện phản ứng bằng vmDefenseReaction - từ một bản build chỉ ghi nhận telemetry hoàn toàn không phá vỡ gì, đến một bản build hỏng cứng khi gặp một bundle bị đánh cắp.

Vấn đề

Các lớp phòng thủ của VM - vmSelfDefending, vmDebugProtectionvmDomainLock - hoạt động cục bộ: khi phát hiện một trình gỡ lỗi, công cụ tự động hóa, môi trường bị can thiệp, hoặc tên miền chưa được cấp phép, mã được bảo vệ sẽ hỏng hoặc âm thầm làm hỏng kết quả của chính nó. Điều đó chặn được kẻ tấn công, nhưng theo mặc định bạn không bao giờ nghe được tin gì về nó. Bạn không thể biết bundle của mình bị dò xét thường xuyên đến mức nào, bộ phát hiện nào đã kích hoạt, hay liệu một lớp phòng thủ có đang làm hỏng một người dùng hợp lệ hay không.

Kể từ v7.1.0, hai tùy chọn thu hẹp khoảng cách đó. Cả hai đều không bật bất kỳ lớp phòng thủ nào - chúng chỉ quan sát và điều hướng các lớp phòng thủ mà bạn đã bật:

  • vmDefenseHook - một callback toàn cục nhận một đối tượng signal mỗi khi một lớp phòng thủ phát hiện điều gì đó. Hãy dùng nó để gửi telemetry về backend của bạn.
  • vmDefenseReaction - một map theo từng nhóm để chọn cách một lớp phòng thủ đang bật phản ứng: hỏng, đầu độc, hay không làm gì cục bộ.

Công thức 1 - báo cáo các phát hiện về backend của bạn

Bước 1 - đăng ký một hàm hook toàn cục, trước khi bundle đã làm rối được nạp

Runtime của VM và các lớp phòng thủ của nó chạy trước chương trình được bảo vệ của bạn, nên nhiều phát hiện được kích hoạt trong lúc khởi động. Hãy định nghĩa hook như một biến toàn cục thuần trong trang chủ, đứng trước thẻ script đã làm rối:

<script>
    // In your page, BEFORE the obfuscated script:
    window.__vmDetection = function (signal) {
        navigator.sendBeacon('/api/vm-defense', JSON.stringify(signal));
    };
</script>
<script src="/app.obfuscated.js"></script>

Bước 2 - trỏ vmDefenseHook đến nó

Tùy chọn là một đối tượng mà name của nó là hàm toàn cục cần gọi (aliases là không bắt buộc - xem bên dưới):

JavaScriptObfuscator.obfuscate(source, {
    vmObfuscation: true,
    // the hook alone enables nothing - a defense must be on for detectors to run:
    vmSelfDefending: true,
    vmDebugProtection: true,
    vmDefenseHook: { name: '__vmDetection' }
});

Dạng chuỗi thuần (vmDefenseHook: '__vmDetection') vẫn được chấp nhận như cách viết tắt cho { name: '__vmDetection' } nhưng đã không còn được khuyến nghị - hãy ưu tiên dạng đối tượng.

Trong bảng điều khiển, trường VM Defense Hook xuất hiện trong bảng tùy chọn VM một khi có ít nhất một lớp phòng thủ (vmSelfDefending, vmDebugProtection, hoặc vmDomainLock) được bật.

Bước 3 - nhận signal trên backend của bạn

Mỗi phát hiện gọi hook với một đối tượng signal duy nhất:

  • source - bộ phát hiện cụ thể: headless, node, agent, domain, debugger, sandbox, nativeHook, timing, hoặc integrity. Kể từ v7.4.0, các bộ phát hiện envinspector trước đây báo cáo dưới source: 'debugger'.
  • category - automation, debugger, sandbox, domain, tamper, hoặc integrity. Nguồn node báo cáo dưới category: 'debugger' (v7.4.0+).
  • score, threshold - điểm phát hiện và ngưỡng mà nó đã vượt qua

Một endpoint nhận tối giản (ví dụ dùng Express; bất kỳ backend nào chấp nhận một POST đều được). Nó chuẩn hóa phần thân thành một mảng để cũng xử lý được dạng gộp lô được post bởi mẫu bộ đệm bên dưới:

app.post('/api/vm-defense', express.text({ type: '*/*' }), (req, res) => {
    // a signal: { source: 'headless', category: 'automation', score: 7, threshold: 4 }
    const signals = [].concat(JSON.parse(req.body));
    for (const signal of signals) {
        console.warn('vm-defense', { ...signal, ip: req.ip, ua: req.get('user-agent') });
    }
    res.sendStatus(204);
});

Đổi tên các trường của signal (aliases) v7.4.0+

Các giá trị source / category mặc định là những tên mô tả, nên bất kỳ ai đo đạc callback (hoặc đọc đầu ra) đều có thể nhận ra lớp bảo vệ và bộ phát hiện nào đã kích hoạt. aliases đổi tên các trường của signal thành những token mờ đục mà bạn tự chọn, được áp dụng bên trong VM trước khi signal được phát ra, nên những tên đó không bao giờ xuất hiện trong đầu ra hay đến được callback. Ứng dụng của bạn biết ánh xạ của riêng nó và chuyển tiếp các token về backend của bạn.

Aliases áp dụng theo từng trường: mỗi trường nhận một key (tên thuộc tính mà callback nhận được); các trường tên dạng chuỗi sourcecategory cũng nhận một map values, còn score / threshold là số và chỉ nhận một key. Các mục không được đặt sẽ giữ tên mặc định của chúng.

vmDefenseHook: {
    name: '__vmDetection',
    aliases: {
        source:    { key: 'a8Qm', values: { headless: 'xP4m9Q' } },
        category:  { key: 'p3Tx', values: { automation: 'bQ7s1M' } },
        score:     { key: 's1' },
        threshold: { key: 't1' }
    }
    // the callback now receives e.g. { a8Qm: 'xP4m9Q', p3Tx: 'bQ7s1M', s1: <score>, t1: <threshold> }
}

Trong bảng điều khiển, phần Signal aliases nằm dưới trường VM Defense Hook.

Công thức 2 - điều chỉnh các phản ứng mặc định

vmDefenseReaction cấu hình cách mỗi nhóm phát hiện phản ứng. Nó không bật thứ gì cả - bản thân các lớp phòng thủ được bật bởi vmSelfDefending, vmDebugProtection, và vmDomainLock; tùy chọn này chỉ chọn cách một lớp phòng thủ đang bật phản ứng. Nhóm là đơn vị kiểm soát: mọi bộ phát hiện trong một nhóm đều thực thi phản ứng của nhóm đó, và một phản ứng được đặt cho một nhóm mà tùy chọn của nó đang tắt thì đơn giản là không có tác dụng.

NhómĐược bật bởiPhản ứng khi
automationvmSelfDefending hoặc vmDebugProtectionMã đang bị điều khiển bởi phần mềm thay vì một con người: một trình duyệt headless hoặc tự động hóa, một framework thu thập / kiểm thử, hoặc một AI coding-agent đang từng bước điều khiển trang.
debuggervmDebugProtection hoặc vmSelfDefendingAi đó đang mở một trình gỡ lỗi hoặc trình kiểm tra của developer-tools trong trình duyệt và đang từng bước xem xét mã đang chạy để hiểu nó.
sandboxvmDebugProtectionMã hoàn toàn không chạy trong một trình duyệt thật - nó đã bị đưa vào một môi trường JavaScript được giả lập hoặc điều khiển bằng script để chạy và nghiên cứu ngoại tuyến.
domainvmDomainLockMã đang chạy trên một site mà bạn chưa cấp phép: một host không nằm trong danh sách cho phép vmDomainLock của bạn (ví dụ, bundle của bạn bị sao chép sang tên miền của người khác).
tampervmSelfDefendingMôi trường JavaScript xung quanh VM đã bị chỉnh sửa để theo dõi hoặc chiếm quyền nó, chẳng hạn các builtin gốc của trình duyệt bị tráo đổi bằng các phiên bản đã bị đo đạc.
integrityvmSelfDefendingChính mã của bundle được bảo vệ đã bị chỉnh sửa hoặc vá kể từ khi bạn tạo ra nó.

Các key là sáu tên nhóm này, hoặc default (một phương án dự phòng cho các nhóm chưa được chỉ định). Các giá trị là:

  • break - hỏng ngay lập tức
  • decoy - tiếp tục chạy trên trạng thái đã bị đầu độc, âm thầm tạo ra kết quả sai
  • none - không làm gì cục bộ (chỉ telemetry)

Một nhóm mà bạn không đặt sẽ quay về các giá trị mặc định dựng sẵn:

// built-in defaults
vmDefenseReaction: {
    automation: 'break',
    debugger: 'decoy',
    sandbox: 'decoy',
    domain: 'break',
    tamper: 'break',
    integrity: 'break'
}

default áp dụng cho mọi nhóm, kể cả những nhóm đúng-theo-thiết-kế (integrity, tamper), nên { default: 'none' } là một bản build thực sự không phá vỡ gì, chỉ ghi nhận telemetry:

vmDefenseReaction: { default: 'none' } // never break - pair with vmDefenseHook
vmDefenseReaction: { automation: 'none' } // tolerate automation FPs; the rest keep their defaults (a bad domain still breaks)

Trong bảng điều khiển, các ô chọn VM Defense Reactions xuất hiện trong bảng tùy chọn VM một khi một lớp phòng thủ được bật; mỗi nhóm chỉ có thể chỉnh sửa khi một lớp phòng thủ phát ra các bộ phát hiện của nó đang bật.

Từ telemetry đến thực thi

Bạn không phải chọn giữa khả năng quan sát và việc thực thi ngay từ ngày đầu. Hãy triển khai các lớp phòng thủ trong hai bản build: một bản chỉ báo cáo, rồi - một khi telemetry trông sạch sẽ - một bản có phản ứng.

Bước 1 - phát hành một bản build chỉ quan sát

Hãy bật mọi lớp phòng thủ bạn định dùng, trỏ vmDefenseHook đến endpoint của bạn, và tắt hết các phản ứng. Mọi bộ phát hiện vẫn chạy và báo cáo từng lần trúng về backend của bạn - nó chỉ không bao giờ làm hỏng bất cứ thứ gì:

JavaScriptObfuscator.obfuscate(source, {
    vmObfuscation: true,
    vmSelfDefending: true,
    vmDebugProtection: true,
    vmDomainLock: ['example.com'],
    vmDefenseHook: '__vmDetection',
    vmDefenseReaction: { default: 'none' } // observe only
});

Bước 2 - xem lại các signal đã thu thập

Sau khi bản build đã gặp lưu lượng thực tế, hãy tìm những phát hiện mà việc sử dụng hợp lệ đã kích hoạt. Hai trường hợp phổ biến nhất:

  • Các lần trúng automation từ chính các bài kiểm thử đầu-cuối hoặc giám sát uptime của bạn - hãy tạo những tạo phẩm đó mà không có các lớp phòng thủ thay vì dung túng nhóm này trong môi trường production.
  • Các lần trúng domain từ một host staging hoặc preview mà bạn quên đưa vào danh sách cho phép vmDomainLock - hãy thêm host đó vào.

Hãy ưu tiên sửa nguyên nhân hơn là làm nhẹ một phản ứng: mỗi nhóm bị để ở none là một bộ phát hiện mà kẻ tấn công không còn phải lo lắng nữa.

Bước 3 - bật các phản ứng lên

Hãy bỏ giá trị ghi đè default: 'none' để các phản ứng dựng sẵn theo từng nhóm được áp dụng - toàn bộ việc chuyển đổi chỉ gói gọn trong một dòng đó. Nếu một nhóm cứ tiếp tục tạo ra các dương tính giả mà bạn không thể loại bỏ, hãy giữ riêng nhóm đó ở none (ví dụ vmDefenseReaction: { automation: 'none' }) và thực thi phần còn lại.