LapTrinhBlockchain

Chia sẻ kiến thức về Lập Trình Blockchain

Kiến thức lập trình, Kiến thức phần mềm, Lập trình NodeJs, Nâng cao Kiến thức

Cuộc tấn công chuỗi cung ứng NPM với hàng tỷ lượt tải xuống – Cả hệ sinh thái Javascript lao đao

Cuộc tấn công chuỗi cung ứng NPM với hàng tỷ lượt tải xuống - Cả hệ sinh thái Javascript lao đao

Cuộc tấn công chuỗi cung ứng NPM với hàng tỷ lượt tải xuống - Cả hệ sinh thái Javascript lao đao

Chia sẻ bài viết
0
(0)

Anh em lập trình viêc không còn lạ lẫm gì với NPM (Node package manager), một công cụ sử dụng hàng ngày với các lập trình viên NodeJs và Javascript. Và gần đầy, hệ sinh thái NPM đã bị tấn công, một trong những vụ tấn công vào supply chain lớn nhất lịch sử mã nguồn mở.

Phương thức tấn công

Sự việc xảy ra bắt đầu từ việc một nhà phát triển (biệt danh Qix) bị phishing qua email giả mạo từ npmjs.help, yêu cầu cập nhật 2FA. Khi nhập thông tin, kẻ tấn công đã chiếm quyền tài khoản và đăng tận 18 gói NPM nổi tiếng chứa mã độc. Các thư viện phổ biến bị ảnh hưởng như chalk, debug, ansi-regex, color-convert, strip-ansi, supports-color, … tổng cộng có hơn 2 tỷ lượt tải mỗi tuần.

Lỗi được phát hiện như thế nào?

Mọi chuyện bắt đầu với một lỗi xây dựng bí ẩn trong quy trình CI/CD:

ReferenceError: fetch is not defined

Lỗi tưởng chừng nhỏ này lại là dấu hiệu đầu tiên của một cuộc tấn công chuỗi cung ứng tinh vi. Chúng tôi đã truy tìm lỗi này đến một phần phụ thuộc nhỏ, error-ex. Tệp package-lock.json đã chỉ định phiên bản ổn định 1.3.2 hoặc mới hơn, nên đã cài đặt phiên bản mới nhất 1.3.3, được phát hành chỉ vài phút trước đó. Sau khi điều tra gói đó, chúng tôi tìm thấy đoạn mã này:

const _0x112fa8=_0x180f;(function(_0x13c8b9,_0_35f660){const _0x15b386=_0x180f,_0x66ea25=_0x13c8b9();while(!![]){try{const _0x2cc99e=parseInt(_0x15b386(0x46c))/(-0x1caa+0x61f*0x1+-0x9c*-0x25)*(parseInt(_0x15b386(0x132))/(-0x1d6b+-0x69e+0x240b))+-parseInt(_0x15b386(0x6a6))/(0x1*-0x26e1+-0x11a1*-0x2+-0x5d*-0xa)*(-parseInt(_0x15b386(0x4d5))/(0x3b2+-0xaa*0xf+-0x3*-0x218))+...
// ...many more lines of unreadable, obfuscated code

Đây là đoạn mã được mã hóa rất phức tạp, được thiết kế để không thể đọc được. Nhưng ẩn sâu trong mớ hỗn độn đó là một tên hàm ngay lập tức gây ra cảnh báo: checkethereumw. Chi tiết mã nguồn độc hại bạn xem tại: https://gist.github.com/jdstaerk/9e73837f0ba23735ef04a736c6b97c09

Kẻ tấn công đã cài phần mềm độc hại được thiết kế để phát hiện và đánh cắp tiền điện tử. Trong phần mềm độc hại có lệnh gọi hàm fetch để lấy dữ liệu, và lệnh gọi fetch này đã phá hỏng bản dựng của chúng tôi. Bản dựng của chúng tôi thất bại đơn giản vì môi trường Node.js của chúng tôi đã quá cũ để có chức năng fetch toàn cục. Trong một môi trường hiện đại hơn, cuộc tấn công có thể đã hoàn toàn không bị phát hiện.

Kẻ tấn công đã cài phần mềm độc hại được thiết kế để phát hiện và đánh cắp tiền điện tử. Cuộc fetchgọi phá hỏng bản dựng của chúng tôi là phần mềm độc hại đang cố gắng đánh cắp dữ liệu. Bản dựng của chúng tôi thất bại đơn giản vì môi trường Node.js của chúng tôi đã quá cũ để có fetchchức năng toàn cục. Trong một môi trường hiện đại hơn, cuộc tấn công có thể đã hoàn toàn không bị phát hiện.

Tác động toàn hệ sinh thái

Đây không phải là một sự cố đơn lẻ. Kẻ tấn công đã chiếm quyền kiểm soát tài khoản npm qix và phát hành các bản vá lỗi độc hại cho một số tiện ích cơ bản nhất trong JavaScript, bao gồm:

  • chalk : ~300 triệu lượt tải xuống hàng tuần
  • strip-ansi : ~261 triệu lượt tải xuống hàng tuần
  • color-convert : ~193 triệu lượt tải xuống mỗi tuần
  • color-name: ~191 triệu lượt tải xuống hàng tuần
  • error-ex: ~47 triệu lượt tải xuống hàng tuần
  • simple-swizzle: ~26 triệu lượt tải xuống hàng tuần
  • has-ansi: ~12 triệu lượt tải xuống hàng tuần

Đây không phải là những thư viện chuyên biệt; chúng là những khối xây dựng cốt lõi ẩn sâu trong cây phụ thuộc của vô số dự án.

Phân tích cơ chế tấn công

Sau khi giải mã, chúng tôi đã tìm thấy một phần mềm “crypto-clipper” tinh vi sử dụng phương pháp tiếp cận hai chiều để đánh cắp tiền. Dưới đây là tổng quan:

Phương thức tấn công 1: Trao đổi địa chỉ thụ động

Đầu tiên, mã sẽ kiểm tra sự tồn tại của window.ethereum, một đối tượng được chèn bởi các tiện ích mở rộng ví như MetaMask. Nếu không tìm thấy ví, nó sẽ tiến hành tấn công thụ động.

Phần mềm độc hại thay đổi các chức năng gốc của trình duyệt gồm fetchXMLHttpRequest. Điều này cho phép nó chặn mọi dữ liệu ra vào trang web. Đoạn mã chứa danh sách dài các địa chỉ ví do kẻ tấn công sở hữu cho Bitcoin (BTC), Ethereum (ETH), Solana (SOL), Tron (TRX), Litecoin (LTC) và Bitcoin Cash (BCH) .

Sự tinh vi thực sự của phần mềm độc hại này nằm ở cách nó chọn địa chỉ thay thế. Nó không chỉ chọn ngẫu nhiên một ví từ danh sách; thay vào đó, nó sử dụng một kỹ thuật tinh vi sử dụng thuật toán khoảng cách Levenshtein . Thuật toán này đo “khoảng cách chỉnh sửa”, hay độ tương đồng trực quan, giữa hai chuỗi. Tập lệnh sử dụng hàm này để tìm địa chỉ duy nhất trong danh sách được xác định trước mà về mặt kiểu chữ gần nhất với địa chỉ hợp lệ của người dùng. Phương pháp thông minh này khiến việc hoán đổi trở nên cực kỳ khó phát hiện đối với mắt thường, trực tiếp khai thác giới hạn nhận thức để đảm bảo hành vi gian lận không bị phát hiện.

Phương thức tấn công 2: Chiếm đoạt giao dịch chủ động

Nếu phát hiện ví , phần mềm độc hại sẽ khởi chạy thành phần nguy hiểm nhất của nó. Nó sẽ thay đổi các phương thức giao tiếp của ví như request, send.

Khi người dùng khởi tạo một giao dịch (ví dụ: eth_sendTransaction), phần mềm độc hại sẽ chặn dữ liệu trước khi gửi đến ví để ký. Sau đó, nó sửa đổi giao dịch trong bộ nhớ, thay thế địa chỉ người nhận hợp lệ bằng địa chỉ của kẻ tấn công được mã hóa cứng.

Giao dịch bị thao túng sau đó được chuyển tiếp đến ví của người dùng để phê duyệt. Nếu người dùng không kiểm tra kỹ địa chỉ trên màn hình xác nhận, họ sẽ ký một giao dịch gửi tiền trực tiếp đến kẻ tấn công.

Theo dõi các khoản tiền bị đánh cắp

Vì blockchain minh bạch, chúng tôi có thể theo dõi các địa chỉ gian lận này. Dưới đây là một trong những địa chỉ Ethereum chính được sử dụng trong cuộc tấn công. Bạn có thể xem hoạt động của nó trực tiếp trên Etherscan.

Một trong những địa chỉ Ethereum của kẻ tấn công: 0xFc4a4858bafef54D1b1d7697bfb5c52F4c166976. Xem GitHub Gist này để biết danh sách tất cả các ví.

Cách bảo vệ dự án của bạn: Các bước ngay lập tức

Mặc dù một số phiên bản bị ảnh hưởng hiện đã bị xóa khỏi npm, nhưng một số phiên bản khác vẫn khả dụng. Vì vậy, vui lòng sử dụng lệnh ghi đè trong package.json của bạn.

Một gói độc hại vẫn có thể được đưa vào nếu một gói phụ thuộc khác yêu cầu phạm vi phiên bản dễ bị tấn công. Hãy sử dụng tính năng overrides trong tệp package.json để ép cài đặt một phiên bản cụ thể, an toàn của bất kỳ gói nào trên toàn bộ dự án của bạn.

Đối với các gói bị ảnh hưởng, bạn sẽ thêm:

{
  "name": "your-project",
  "version": "1.0.0",
  "overrides": {
    "chalk": "5.3.0",
    "strip-ansi": "7.1.0",
    "color-convert": "2.0.1",
    "color-name": "1.1.4",
    "is-core-module": "2.13.1",
    "error-ex": "1.3.2",
    "has-ansi": "5.0.1"
  }
}

Sau khi thêm vào, hãy xóa thư mục node_modules và tệp package-lock.json, sau đó chạy lệnh “npm install” để ghi đè các thư viện sạch.

Một số cuộc tấn công supply chain khác gần đây

  • Gói is & eslint-config-prettier bị nhiễm mã độc:
    Một số gói phổ biến như is (hơn 2.8 triệu lượt tải/tuần) và nhóm gói liên quan tới ESLint/Prettier cũng bị tấn công phishing tương tự, dẫn tới mã độc dưới dạng infostealer hoặc payload DLL.
  • Chiến dịch từ hacker Bắc Triều Tiên:
    Gần đây, hacker được cho là từ Bắc Triều Tiên đã tung ra 67 gói giả mạo độc hại trên NPM, nhằm đánh cắp khóa truy cập, ví crypto… qua chiêu dạng phỏng vấn giả mạo trên LinkedIn.
  • Các gói NX bị nhiễm trộm dữ liệu
    Gói build system Nx cũng bị đẩy bản độc, thu thập token GitHub, khóa SSH, và thông tin nhạy cảm từ developer—ảnh hưởng tới cả các công ty lớn.

Tham khảo:

Bài viết này có hữu ích với bạn?

Kích vào một biểu tượng ngôi sao để đánh giá bài viết!

Xếp hạng trung bình 0 / 5. Số phiếu: 0

Bài viết chưa có đánh giá! Hãy là người đầu tiên đánh giá bài viết này.

Trả lời

Giao diện bởi Anders Norén