1 điểm bởi GN⁺ 1 giờ trước | 1 bình luận | Chia sẻ qua WhatsApp
  • CVE-2024-YIKES là một sự cố trong đó việc chiếm đoạt dependency JavaScript lan sang chuỗi cung ứng Rust và Python
  • Chiêu lừa đảo left-justify đã làm rò rỉ thông tin xác thực .npmrc, .pypirc, cũng như credential của Cargo và Gem
  • build.rs độc hại của vulpine-lz4 tải xuống và thực thi shell script trên các host CI
  • Mã độc snekpack 3.7.0 đã lan tới khoảng 4,2 triệu máy và thêm SSH key cùng reverse shell
  • Sâu cryptobro-9000 vô tình nâng cấp lên snekpack 3.7.1 nên mã độc bị gỡ bỏ

Tổng quan sự cố

  • CVE-2024-YIKES là một sự cố bảo mật trong đó một dependency bị xâm phạm trong hệ sinh thái JavaScript dẫn đến đánh cắp thông tin xác thực, rồi lan thành tấn công chuỗi cung ứng vào thư viện nén Rust và phát tán mã độc qua công cụ build Python
  • Sự cố được tiếp nhận lúc 03:47 UTC, trạng thái chuyển thành “được giải quyết một cách tình cờ”, còn mức độ nghiêm trọng đổi từ “Critical → Catastrophic → Somehow Fine”
  • Thời lượng kéo dài 73 giờ, và các hệ thống bị ảnh hưởng vẫn được ghi là “Yes”
  • Chuỗi package và toolchain bị xâm phạm kéo dài từ left-justify, vulpine-lz4 đến snekpack, phát tán mã độc tới khoảng 4 triệu nhà phát triển
  • Cuối cùng, một sâu đào tiền mã hóa riêng biệt là cryptobro-9000 đã chạy cập nhật trên các máy bị nhiễm, vô tình nâng snekpack lên phiên bản bình thường và nhờ đó gỡ bỏ mã độc

Diễn biến sự cố

  • Ngày 1: Đánh cắp thông tin xác thực từ package JavaScript

    • Lúc 03:14 UTC, maintainer của left-justify là Marcus Chen đăng trên Twitter rằng anh bị mất thẻ giao thông, một chiếc laptop cũ và “một thứ có vẻ quan trọng do Kubernetes nôn ra”, nhưng chuyện này chưa ngay lập tức bị xem là vấn đề bảo mật package
    • Lúc 09:22 UTC, khi Chen cố đăng nhập vào registry nmp, anh phát hiện mình không còn khóa 2FA phần cứng, còn AI Overview đứng đầu kết quả tìm kiếm Google lại dẫn tới trang lừa đảo yubikey-official-store.net được đăng ký từ 6 giờ trước
    • Lúc 09:31 UTC, Chen nhập credential nmp vào trang lừa đảo đó, và trang này cảm ơn vì đơn hàng, hứa giao trong vòng 3~5 ngày làm việc
    • Lúc 11:00 UTC, [email protected] được phát hành với changelog là “performance improvements”
    • Package đó bao gồm script chạy sau khi cài đặt, dùng để lấy trộm .npmrc, .pypirc, ~/.cargo/credentials, ~/.gem/credentials về máy chủ do kẻ tấn công chọn
    • Lúc 13:15 UTC, một ticket hỗ trợ được mở cho left-justify với nội dung “why is your SDK exfiltrating my .npmrc”, nhưng bị gắn nhãn “low priority - user environment issue” rồi tự động đóng sau 14 ngày không có hoạt động
  • Ngày 1: Tấn công chuỗi cung ứng lan sang thư viện Rust

    • Trong số các credential bị rò rỉ có thông tin xác thực của maintainer thư viện Rust vulpine-lz4
    • vulpine-lz4 là thư viện cho “blazingly fast Firefox-themed LZ4 decompression”, có 12 sao trên GitHub nhưng lại là dependency bắc cầu của chính cargo
    • Lúc 22:00 UTC, vulpine-lz4 0.4.1 được phát hành với commit message “fix: resolve edge case in streaming decompression”
    • Thay đổi thực tế là thêm script build.rs, tải về và thực thi một shell script nếu hostname chứa “build”, “ci”, “action”, “jenkins”, “travis” hoặc “karen”
  • Ngày 2: Phát hiện và ứng phó thất bại

    • Lúc 08:15 UTC, nhà nghiên cứu bảo mật Karen Oyelaran phát hiện commit độc hại sau khi payload chạy trên laptop cá nhân của cô
    • Karen Oyelaran mở một issue với nội dung “your build script downloads and runs a shell script from the internet?” nhưng không nhận được phản hồi
    • Maintainer hợp pháp thì vừa trúng €2.3 million từ EuroMillions và đang ở Bồ Đào Nha khảo sát một trang trại dê
    • Lúc 10:00 UTC, VP of Engineering của một khách hàng Fortune 500 dùng snekpack biết đến sự cố qua một bài đăng LinkedIn có tiêu đề “Is YOUR Company Affected by left-justify?”, rồi muốn biết vì sao mình không được đưa vào sớm hơn, dù thực tế đã bị đưa vào sớm hơn rồi
    • Lúc 10:47 UTC, kênh Slack #incident-response tạm chuyển thành một luồng 45 tin nhắn bàn xem từ “compromised” theo kiểu Mỹ có nên viết bằng chữ ‘z’ hay không
  • Ngày 2: Công cụ build Python snekpack bị lây nhiễm

    • Lúc 12:33 UTC, shell script nhắm cụ thể vào pipeline CI của snekpack
    • snekpack là công cụ build Python được 60% package PyPI có chữ “data” trong tên sử dụng
    • snekpack đã vendoring vulpine-lz4 vì “Rust is memory safe”
    • Lúc 18:00 UTC, snekpack 3.7.0 được phát hành và mã độc bắt đầu được cài lên máy của các nhà phát triển trên toàn thế giới
    • Mã độc thêm SSH key vào ~/.ssh/authorized_keys, cài reverse shell chỉ kích hoạt vào thứ Ba, và đổi shell mặc định của người dùng sang fish
    • Việc đổi shell mặc định sang fish được xem là một lỗi
    • Lúc 19:45 UTC, một nhà nghiên cứu bảo mật khác đăng bài blog dài 14.000 từ với tiêu đề “I found a supply chain attack and reported it to all the wrong people”, trong đó cụm “in this economy?” xuất hiện 7 lần
  • Ngày 3: Bản vá tình cờ và kết thúc sự cố

    • Lúc 01:17 UTC, một lập trình viên junior ở Auckland phát hiện mã độc khi đang debug một vấn đề khác và mở PR hoàn tác vulpine-lz4 được vendoring trong snekpack
    • PR đó cần 2 lượt phê duyệt, nhưng cả 2 người phê duyệt đều đang ngủ
    • Lúc 02:00 UTC, maintainer của left-justify nhận được YubiKey từ yubikey-official-store.net, nhưng đó là một USB 4 đô với file README ghi “lol”
    • Lúc 06:12 UTC, một sâu đào tiền mã hóa riêng biệt là cryptobro-9000 bắt đầu lây lan qua lỗ hổng jsonify-extreme
    • jsonify-extreme được mô tả là package “makes JSON even more JSON, now with nested comment support”
    • Bản thân payload của cryptobro-9000 không quá đặc biệt, nhưng cơ chế lây lan của nó bao gồm chạy npm updatepip install --upgrade trên máy bị nhiễm để mở rộng bề mặt tấn công trong tương lai
    • Lúc 06:14 UTC, cryptobro-9000 vô tình nâng snekpack lên 3.7.1
    • snekpack 3.7.1 là một bản phát hành bình thường do một đồng maintainer đang hoang mang phát hành, và nó hoàn tác vulpine-lz4 được vendoring về phiên bản trước đó
    • Lúc 06:15 UTC, reverse shell thứ Ba được kích hoạt, nhưng máy chủ command-and-control đã bị cryptobro-9000 làm hỏng nên không thể phản hồi
    • Lúc 09:00 UTC, các maintainer của snekpack phát hành một advisory bảo mật dài 4 câu, có các cụm “out of an abundance of caution” và “no evidence of active exploitation”
    • Cụm “no evidence of active exploitation” được xem là đúng về mặt kỹ thuật vì không ai đi tìm bằng chứng
    • Lúc 11:30 UTC, một nhà phát triển tweet “I updated all my dependencies and now my terminal is in fish???” và nhận được 47.000 lượt thích
    • Lúc 14:00 UTC, credential bị xâm phạm của vulpine-lz4 được thay mới
    • Maintainer hợp pháp nhận email ở trang trại dê mới của mình và trả lời rằng “2 năm nay tôi chưa động vào repository đó” và “Tôi tưởng 2FA của Cargo là tùy chọn”
    • Lúc 15:22 UTC, sự cố được tuyên bố đã được giải quyết, còn lịch họp retrospective thì được lên rồi dời ba lần

Gán CVE và quy mô thiệt hại

  • Tuần thứ 6, CVE-2024-YIKES được cấp chính thức
  • Advisory vẫn ở trạng thái embargo trong khi MITRE và GitHub Security Advisories tranh cãi về phân loại CWE
  • Trước khi CVE được công khai, đã có 3 bài viết trên Medium và một bài trình bày tại DEF CON phân tích chi tiết sự cố
  • Tổng thiệt hại vẫn được để là không xác định
  • Số máy bị xâm phạm được ước tính là 4,2 triệu
  • Số máy được sâu tiền mã hóa cứu cũng được ước tính là 4,2 triệu
  • Thay đổi ròng về tư thế bảo mật vẫn được ghi là “bất tiện”

Nguyên nhân gốc rễ và các yếu tố góp phần

  • Nguyên nhân gốc rễ

    • Con chó tên Kubernetes ăn mất YubiKey được xem là nguyên nhân gốc rễ
  • Các yếu tố góp phần

    • Registry nmp vẫn cho phép xác thực chỉ bằng mật khẩu với các package có dưới 10 triệu lượt tải mỗi tuần
    • Google AI Overviews đã tự tin dẫn tới một URL lẽ ra không nên tồn tại
    • Triết lý “small crates” của hệ sinh thái Rust bị sao chép trong hệ sinh thái npm, khiến các package như is-even-number-rs có 3 sao GitHub vẫn có thể trở thành dependency bắc cầu bốn tầng của hạ tầng quan trọng
    • Các công cụ build Python vendoring thư viện Rust vì “hiệu năng”, rồi không cập nhật nữa
    • Dependabot tự động merge PR sau khi CI pass, còn CI pass vì mã độc đã cài volkswagen
    • Sâu đào tiền mã hóa có vệ sinh CI/CD tốt hơn phần lớn startup
    • Không có một cá nhân chịu trách nhiệm duy nhất, nhưng PR của Dependabot đã được duyệt bởi một contractor mà hôm đó là ngày làm việc cuối cùng
    • Hôm xảy ra sự cố là thứ Ba

Biện pháp cải thiện và các lựa chọn còn lại

  • Việc triển khai ký artifact là action item từ sự cố Q3 2022 nhưng vẫn còn nằm trong backlog
  • Việc triển khai 2FA bắt buộc đã được yêu cầu từ trước nhưng cũng không giúp được gì
  • Việc audit dependency bắc cầu bị gạch bỏ vì có tới 847 mục
  • Pin toàn bộ phiên bản dependency thì sẽ chặn việc nhận bản vá bảo mật
  • Không pin phiên bản dependency thì lại tạo điều kiện cho tấn công chuỗi cung ứng
  • Lựa chọn viết lại bằng Rust được gạch bỏ và trỏ thẳng tới vulpine-lz4
  • Những việc còn lại chỉ là hy vọng có một sâu thiện chí hoặc cân nhắc chuyển nghề sang làm trang trại dê

Ảnh hưởng tới khách hàng và phản ứng của tổ chức

  • Một số khách hàng có thể đã gặp “kết quả bảo mật không tối ưu”
  • Tổ chức đã chủ động liên hệ để cung cấp khả năng quan sát tình hình cho các bên liên quan bị ảnh hưởng
  • Niềm tin của khách hàng vẫn được giữ làm “north star”
  • Một nhóm công tác liên chức năng đã được lập để rà soát lại tư thế bảo mật, nhưng vẫn chưa họp lần nào
  • Sau khi bộ phận pháp lý rà soát, có thêm câu rằng shell fish không phải là mã độc, dù đôi lúc có thể khiến người ta cảm thấy như vậy
  • Đây là báo cáo sự cố thứ ba trong quý đó
  • Yêu cầu tăng nhân sự cho đội bảo mật đã nằm trong backlog từ Q1 2023

Lời cảm ơn

  • Karen Oyelaran đã phát hiện vấn đề vì hostname của cô khớp với regex
  • PR do lập trình viên junior ở Auckland mở được duyệt sau khi sự cố đã được giải quyết 4 giờ
  • Một số nhà nghiên cứu bảo mật đã phát hiện vấn đề sớm nhưng báo nhầm người
  • Tác giả của cryptobro-9000 không muốn nêu tên, nhưng yêu cầu nhắc tới SoundCloud của mình
  • Con chó tên Kubernetes từ chối bình luận
  • Đội bảo mật, bất chấp mọi chuyện, vẫn đáp ứng SLA cho báo cáo này

1 bình luận

 
Ý kiến trên Hacker News
  • Nói cho những ai bị rối: bài này là một tác phẩm hư cấu viết khá hay về một sự cố chuỗi cung ứng
    Lúc mới lướt qua tôi tưởng là thật nên khá lo và vì thế đọc kỹ hơn :)

    • Tôi cười sặc ở đoạn left-justify :)
    • Lúc đầu thật sự tôi không phân biệt ra được, cảm giác kiểu này: https://github.com/bitcoin/bips/blob/master/bip-0042.mediawi...
    • Nếu tìm CVE-2024-YIKES thì còn ra cả một bộ sưu tập blog rác do AI viết lại nội dung bài này rồi giả vờ cực kỳ nghiêm túc
    • nmp
  • Tôi tò mò về đoạn được trích rằng “vulpine-lz4 với 12 sao trên GitHub là phụ thuộc bắc cầu của chính cargo”, nên thử liệt kê sơ vài crate có thể chen vào quá trình build của cargo và đã sẵn có build.rs nên sẽ ít bị chú ý hơn: flate2, tar, curl-sys, libgit2-sys, openssl-sys, libsqlite3-sys, blake3, libz-sys, zstd-sys, cc
    Ngoài ra, nếu chiếm được xz2 thì còn có thể làm nhiễm rustup
    Dù sao thì ít nhất họ cũng có theo dõi Cargo.lock

    • Các crate -sys vốn chỉ là binding thôi, nên nếu chúng làm thêm việc khác thì sẽ trông khá đáng ngờ
      Còn lại thì theo tôi biết là do các maintainer Rust như alexcrichton hoặc chính rustlang sở hữu
  • Rất dễ trở nên yếm thế, vì sau khi mọi chuyện qua đi thì vấn đề và cách giải quyết đều trông quá hiển nhiên
    Nhưng trong một thời gian rất dài, và có lẽ cả bây giờ nữa, tín điều của văn hóa hacker là move fast and break things
    Tín hiệu cho thấy ngày càng có nhiều nỗ lực sửa các vấn đề quá rõ ràng của những hệ thống chuỗi cung ứng như npm là điều đáng mừng, nhưng tôi lo chúng ta đang bước vào một thời kỳ có những vấn đề bảo mật mới mà phát triển kiểu agent gây ra phần lớn
    Không chỉ vì các câu chuyện như Mythos/Glasswing phơi bày lỗ hổng ở gần như mọi thứ chúng đụng vào, mà còn vì cách chúng ta xây dựng phần mềm, kéo phụ thuộc vào và đánh mất mô hình tư duy của con người về các hệ thống phức tạp sẽ tạo ra rất nhiều phần mềm và hạ tầng chắp vá mà chẳng ai thực sự hiểu nổi
    Mong là vài năm nữa nhìn lại hôm nay chúng ta sẽ không phải hối tiếc vì đã ngây thơ đến vậy, vì đã không chuẩn bị nghiêm túc cho cái đuôi dài của phát triển AI mà lại cố giải quyết vấn đề bằng cách xây lại các hệ thống phức tạp bằng AI
    Dù sao thì bài viết vẫn buồn cười

    • Câu đó thực sự đã là tín điều từ rất lâu rồi à? Tôi cứ tưởng khẩu hiệu kinh khủng đó là do Zuckerberg nghĩ ra
  • Là một người mê Fish, câu này khiến tôi vừa thấy bị công kích vừa thấy được thấu hiểu: “hãy nói rõ rằng fish shell không phải là malware, chỉ là đôi khi nó tạo cảm giác như vậy”
    Bỏ qua chuyện shell, đoạn “yêu cầu tăng nhân sự cho đội bảo mật đã nằm trong backlog từ quý 1 năm 2023” cũng thấy quen thuộc một cách đau lòng

    • Một phương án khác là cài figlet bằng apt-get hoặc dnf, rồi ghi đè nội dung /etc/motd bằng dòng all your base are belong to us với font ASCII art cỡ lớn
  • Tôi đã cười rất to ở đoạn maintainer của left-justify nhận được YubiKey từ yubikey-official-store.net, mà hóa ra đó là một USB 4 đô với chữ “lol” trong README
    Đúng là trò troll đỉnh cao

    • Ừ, đoạn đó hay thật
      Tôi thích ở chỗ việc cắm một thiết bị USB nhận từ trang phishing tự nó cũng là một đường tấn công khác
    • Bình thường nhận từ trang phishing đâu được nhiều thế. Hẳn hoi một USB còn dùng được nữa chứ!
  • Không phải SCP thật, nhưng đây là thứ giống SCP nhất tôi từng đọc gần đây

    • À đúng rồi, một ca Supply Chain Problem(SCP) cực kỳ hiếm gặp
  • Tôi cười lớn ở đoạn Karen :D ;)
    Nó làm tôi nhớ đến một script build dựa trên make mà tôi nhận được khi review project của một bạn cùng lớp, trong đó nếu hostname chứa bpavuk thì nó sẽ thử rm -rf thư mục home của tôi
    Chuyện đó xảy ra từ hồi tôi học lớp 7 cơ!!

  • Sự cố chuỗi cung ứng thực sự rất đau đầu và chúng ta phải làm tốt hơn
    Cá nhân tôi ủng hộ việc quỹ Rust hỗ trợ một số crate cốt lõi để chúng phải trải qua quy trình kiểm toán như chính ngôn ngữ Rust, đồng thời tài trợ cho các dự án nhằm giảm các lỗ hổng trong chuỗi cung ứng
    Tôi không nghĩ câu trả lời là xóa bỏ những hệ thống như crates hay npm. cratesnpm giúp ích rất nhiều cho nhiều lập trình viên

    • crates cũng đã có nỗ lực đưa rustsec vào, nhưng ngoài chuyện đó ra tôi vẫn muốn thấy cộng đồng chuyển từ kiểu có rất nhiều phụ thuộc nhỏ sang ít phụ thuộc lớn hơn như tokio
    • Khá nhiều crate phổ biến nhất trên crates.io thực ra đã là crate bên thứ nhất do tổ chức Rust cung cấp
      Điểm này thường bị bỏ qua khi người ta lo lắng về đồ thị crate của Rust
      Nếu nhìn top 10 lượt tải trên trang đầu crates.io, crate duy nhất không do tổ chức Rust hoặc maintainer cốt lõi của Rust tạo ra là base64
    • Có lẽ nên chuyển các crate có giá trị cao vào thư viện chuẩn chăng?
    • Nhưng thật sự có cần cả npm lẫn nmp không vậy
    • Thành thật mà nói, tôi đã nghĩ mục tiêu cuối cùng của blessed.rs là chuyện này
  • “Maintainer chính thức đã trúng 2,3 triệu euro từ EuroMillions và đang tìm hiểu nghề nuôi dê ở Bồ Đào Nha”, còn “nguyên nhân gốc rễ: một con chó tên Kubernets đã ăn mất YubiKey”
    À, đúng rồi. Bị dính một kiểu tấn công kinh điển nổi tiếng như thế thì thật là vô trách nhiệm
    Chính là chiêu “làm ai đó mất tập trung bằng tiền trúng xổ số, rồi khiến dongle của người khác trông ngon không thể cưỡng lại với thú cưng của họ” ấy mà
    Bao giờ con người mới chịu học đây

  • May quá là tôi không dùng npm hay pip, mà chỉ dùng cách được khuyến nghị là curl ... | bash

    • Phải là curl | sudo bash chứ
      Đúng dân nghiệp dư