1 điểm bởi GN⁺ 2024-03-31 | 1 bình luận | Chia sẻ qua WhatsApp
  • Thay đổi trong CMakeLists.txt của xz.git là một trường hợp ký tự . đơn lẻ xuất hiện trong mã kiểm tra, trong quá trình chuyển cơ chế phát hiện sandbox Landlock từ việc kiểm tra sự tồn tại của header sang kiểm tra biên dịch thực tế
  • Kiểm tra mới được thêm vào để loại bỏ các hệ thống có linux/landlock.h nhưng thiếu các định nghĩa syscall cần thiết
  • Bài kiểm tra biên dịch bao gồm <linux/landlock.h>, <sys/syscall.h>, <sys/prctl.h> và tham chiếu tới prctl, SYS_landlock_create_ruleset, SYS_landlock_restrict_self, LANDLOCK_CREATE_RULESET_VERSION
  • Tiêu chí cũ HAVE_LINUX_LANDLOCK_H được đổi thành HAVE_LINUX_LANDLOCK, và các thiết lập SANDBOX_COMPILE_DEFINITION cùng SANDBOX_FOUND cũng dựa theo kết quả này
  • Commit này sửa Linux Landlock feature test của cả bản dựng Autotools và CMake, và diff được cung cấp cho thấy thay đổi ở phía CMake

Thay đổi cách phát hiện Landlock trong CMake

  • Tệp mục tiêu là CMakeLists.txt trong xz.git, và vị trí thay đổi là khối # Sandboxing: Landlock
  • Logic CMake trước đây khi ENABLE_SANDBOXON hoặc landlockSANDBOX_FOUND chưa được đặt sẽ chỉ kiểm tra sự tồn tại của header bằng check_include_file(linux/landlock.h HAVE_LINUX_LANDLOCK_H)
  • Sau thay đổi, nó dùng check_c_source_compiles để biên dịch thực tế một đoạn mã C nhỏ nhằm xác nhận có thể sử dụng Landlock hay không
    • Một số hệ thống có thể có linux/landlock.h nhưng lại không có các định nghĩa syscall cần cho Linux Landlock
    • Mã kiểm tra bao gồm <linux/landlock.h>, <sys/syscall.h>, <sys/prctl.h>
    • Bên trong my_sandbox(), nó tham chiếu prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0), SYS_landlock_create_ruleset, SYS_landlock_restrict_self, LANDLOCK_CREATE_RULESET_VERSION

Ký tự đơn lẻ và thay đổi tên biến

  • Sau khối include của mã kiểm tra biên dịch được chèn vào có một dòng . đứng riêng
  • Biến kết quả được đổi từ HAVE_LINUX_LANDLOCK_H thành HAVE_LINUX_LANDLOCK
  • Câu điều kiện cũng được đổi từ if(HAVE_LINUX_LANDLOCK_H) sang if(HAVE_LINUX_LANDLOCK)
  • Giá trị SANDBOX_COMPILE_DEFINITION dùng "HAVE_LINUX_LANDLOCK" thay cho "HAVE_LINUX_LANDLOCK_H"
  • Thiết lập SANDBOX_FOUND ON sau đó vẫn được giữ nguyên

1 bình luận

 
GN⁺ 2024-03-31
Ý kiến trên Hacker News
  • Đáp án: https://git.tukaani.org/?p=xz.git;a=commitdiff;h=f9cf4c05edd...
    Nếu chưa rõ về hệ thống kiểm soát truy cập Landlock của Linux, phần giải thích ở đây: https://docs.kernel.org/userspace-api/landlock.html
    Trang ứng phó sự cố chính thức (có lẽ...) của xz: https://tukaani.org/xz-backdoor/

    • Vậy tức là hàm đó kiểm tra xem đoạn mã C theo sau có biên dịch được không, và chỉ khi đó mới bật Landlock à?
      Nhưng chỉ vì một dấu chấm nhỏ nằm sát mép trái của diff, rất khó nhận ra, mà mã C luôn trở nên không hợp lệ, nên Landlock luôn bị tắt?
      Ấn tượng đến mức đê tiện, và đê tiện đến mức ấn tượng. Lần đầu đọc tôi cũng không thấy
    • Cái này có khả năng phủ nhận hợp lý
      Nếu muốn giấu thì còn có những cách tốt hơn như thay bằng ký tự Unicode trông tương tự. Một số ký tự tùy phông chữ còn giống đến từng pixel
      Có thể tôi bỏ lỡ mạch chuyện, nhưng ở đây đã xác định được là cố ý chưa?
    • Cái này ác đến mức nếu bị bắt quả tang ngay trong PR thì vẫn có thể lấp liếm “À, IDE của tôi tự format như vậy” rồi cho qua
    • Lasse Collin đã xuất hiện trở lại, và có lẽ đang tức giận
    • Tôi có cảm giác hệ thống quản lý phiên bản của mình làm nổi bật ký tự bị thay đổi tốt hơn mấy chuỗi xanh/đỏ nguyên khối kiểu này
  • Tôi đang lướt qua thật cẩn thận thì thấy một dấu chấm ở chỗ rõ ràng không nên có, nên nghĩ “cũng không khó như mình tưởng”
    Chạm nhẹ vào màn hình thì dấu chấm đó di chuyển
    Bụi màn hình chết tiệt

  • Không thể tin được bảo mật hệ thống lại phụ thuộc vào một chuỗi đúng đắn lỏng lẻo như thế này. Có vô số điểm có thể chặn được
    + # A compile check is done here because some systems have
    + # linux/landlock.h, but do not have the syscalls defined
    + # in order to actually use Linux Landlock.
    Nên sửa header của những hệ thống như vậy để loại trừ một cách rõ ràng. Header mà không khai báo chức năng của chính nó thì còn ý nghĩa gì?
    Và tôi cũng không hiểu vì sao sau khi blob nhị phân được tạo ra (dù được biên dịch từ mã nguồn mở), lại không có bài test nào kiểm tra xem bảo mật còn nguyên vẹn không
    Ngay cả chức năng thanh toán của website cũng sẽ không được triển khai nếu không có test đầu-cuối cho chức năng cốt lõi. Có vẻ có sự lệch pha về ưu tiên, khi thêm tính năng được đặt cao hơn độ ổn định
    Hy vọng bản sửa không chỉ đơn giản là xóa dấu .. Tôi vừa thấy ở một bài khác trên HN có đoạn cho thấy việc xóa dấu .

    • Hắn đã đưa vào một framework kiểm thử hoàn toàn mới, rồi âm thầm cài backdoor trong suốt 2 năm
    • Phần bạn trích là lời của Jia Tan [1]. Đó là chú thích do chính tác nhân độc hại viết khi cố ý phá hỏng kiểm tra ngay từ đầu
      Sửa header hay thêm test cũng sẽ không ngăn được. Vì ngay từ đầu không có dấu hiệu nào cho thấy header bị hỏng, và các test bổ sung cũng có thể bị phá theo cách khác hoặc bị bỏ qua trong release tarball
      [1] https://git.tukaani.org/?p=xz.git;a=commit;h=328c52da8a2bbb8...
    • Hơi lạc đề một chút, nhưng GCC 9.4.0 từng phát hành header arm_acle.h bị hỏng [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100985] — mã nào include header đó đều luôn biên dịch thất bại
      Vì người dùng có thể cố biên dịch bằng GCC 9.4.0, và tính năng phụ thuộc vào header đó không phải là cốt lõi đối với ứng dụng, nên nếu build phát hiện header bị hỏng thì nó chỉ tắt tính năng đó và đưa ra cảnh báo
      Quay lại xz, nếu bảo mật không phải ưu tiên cao nhất thì việc bỏ qua lỗi của tính năng tùy chọn rồi tiếp tục cũng có vẻ hợp lý. Tất nhiên nhìn lại sau sự cố thì rất dễ chỉ trích, nhưng nếu bỏ qua bối cảnh đó, đây không phải là quyết định hoàn toàn vô lý
    • Là người dùng mã nguồn mở, tôi không đủ hiểu biết để đưa ra đề xuất kiểu này, nên nếu bạn tự phát triển và đóng góp thì chắc sẽ rất đáng cảm ơn
    • Bạn có biết đoạn mã chú thích mà bạn trích có chính xác không?
  • Ôi, commit cuối cùng của hắn đang làm cho báo cáo bảo mật tệ hơn: https://git.tukaani.org/?p=xz.git;a=commitdiff;h=af071ef7702...

    • Tại sao cái này lại được chấp nhận nhỉ? Tôi thật sự tò mò
  • Landlock vốn được thiết kế để dùng ở đâu/như thế nào?
    Có vẻ khó dùng trong thực tế với các thư viện đa dụng như nén/giải nén. Thư viện không thể biết chương trình cần làm gì, hay cần hạn chế gì
    Nếu là chương trình thì có thể rõ ràng hơn
    Vụ tấn công sshd dùng liblzma như một thư viện. Vậy việc tắt Landlock có vẻ không liên quan? Đây có phải là dấu hiệu cho thấy còn mã độc chưa bị phát hiện, hoặc họ định thêm vào sau không?

    • Có lẽ bản thân sshd dùng nó để tự khóa quyền của mình sau một thời điểm nhất định trong quá trình thực thi
      Nếu gỡ Landlock, daemon sẽ không tự khóa, nên khi đến giai đoạn khai thác thì việc chạy payload sẽ dễ hơn
      Tôi không cho rằng hai việc này không liên quan. Có vẻ họ đã tính đến payload và nhận ra đây sẽ là một chướng ngại
    • Lạ thật. Làm hai việc kiểu backdoor không liên quan trong cùng một dự án thì tôi thấy thật sự cẩu thả. Lợi ích thu được ít mà rủi ro bị phát hiện lại tăng mạnh
      Vụ này rất rối rắm. Có phần tinh vi đến khó tin, nhưng có phần lại trông khá sơ hở
    • Có thể dùng được và là ý hay, nhưng mục đích là để chặn khai thác lỗ hổng hơn là backdoor có chủ ý
      Ý tưởng là thư viện khởi chạy tác vụ phức tạp trong một luồng riêng, còn mã người dùng thì chờ luồng đó trong API đã gọi. Luồng tự áp dụng Landlock rồi mới bắt đầu làm việc. Nếu có gì sai, mã sẽ bị cô lập
      Tất nhiên trong trường hợp này sandbox bị kẻ tấn công kiểm soát nên không hiệu quả. Vì kẻ tấn công chỉ cần tắt nó hoặc làm cho nó yếu hơn ban đầu. Dù vậy vẫn có thể làm theo cách khác
  • Rốt cuộc họ nhắm đến điều gì ở đây? Định sau này cài thêm nhiều backdoor hơn, những backdoor có thể phủ nhận một cách hợp lý hơn à? Theo tôi, cả oss-fuzz lẫn thay đổi này đều có lẽ sẽ không thật sự tìm ra backdoor đã bị phát hiện
    Nhưng tại sao lại bỏ hết trứng backdoor vào cùng một giỏ, tức là một thư viện?

    • Thư viện đó đã cắm rễ đủ sâu, được tin cậy đủ nhiều, và maintainer chính từng nghỉ internet lâu vì vấn đề sức khỏe tinh thần
      Hơn nữa, cách làm không phải là backdoor hóa chính thư viện, mà nhắm vào công cụ dùng nó. Kiểu “Reflections on trusting trust”
      Nghe như một kế hoạch hoàn hảo cho đến khi nó thất bại
    • Nhưng ai nói được rằng đó chỉ là một thư viện?
  • Tôi thắc mắc vì sao việc ngăn Landlock được bật trong xz lại hữu ích. Có phải họ định ở giai đoạn sau sẽ tiêm nội dung độc hại vào archive xz không? Nếu vậy tại sao không cứ nhét thẳng hành vi độc hại vào chính xz?

    • Vì một lỗ hổng có chủ ý dễ che giấu hơn nhiều so với nội dung độc hại thật sự
      Lén đưa buffer overflow hoặc use-after-free vào một dự án C đang bảo trì có thể làm mà không bị phát hiện. Phân phối một trojan thật sự thì khó hơn nhiều, và backdoor xz-to-sshd đã cho thấy điều đó
    • Ngoài việc nhắm vào ssh, cũng có thể còn một backdoor tinh vi hơn nhắm vào chính xz. Rõ ràng mục tiêu là tính bí mật
  • Cái này bất ngờ là quá lộ liễu. Kỹ thuật tắt tính năng khá thông minh và commit cũng khá có vẻ hợp lý. Nhưng tại sao lại chọn một lỗi cú pháp rõ ràng thay vì chỉ viết sai chính tả đơn giản? Ví dụ nếu lỗi là PR_SET_NO_NEW_PRIV thì liệu có ai nhận ra không?
    Cách đó còn dễ phủ nhận hơn

  • Nhân tiện, nhóm malware này đã tạo ra một bộ dữ liệu tuyệt vời để huấn luyện AI nhận diện vấn đề bảo mật. Vì mọi commit đều có vấn đề bảo mật, và cộng đồng open source sẽ rà từng cái để tìm ra
    Cảm ơn các maintainer đang làm công việc dọn dẹp. Chắc chắn đây không phải việc thú vị

    • Tôi không nghĩ nó sẽ khái quát hóa tốt. Cùng lắm cũng chỉ là một cuộc chạy đua vũ trang
    • Đây là một trong những cách dùng AI khá hay mà tôi từng thấy
    • Tôi mới nghe chuyện này lần đầu, có thể đăng thêm thông tin liên quan không?
  • Vì vậy tôi thật sự không thích các hệ thống build kiểu configure tự động bật tắt tính năng. Nếu muốn thứ gì, tôi muốn bật nó một cách rõ ràng. Nếu có lý do đủ tốt để để một tính năng làm mặc định, thì thay vào đó cũng phải cho phép tắt nó một cách rõ ràng

    • Khi đóng gói thì chuyện này cực kỳ đau đầu. Bạn cấu hình gói, thêm dependency cho đến khi build được rồi nghĩ là xong. Nhưng tính năng X lại bị thiếu. Sao vậy? À, vì không có libY nên nó bị tắt âm thầm. Quay lại thêm vào. Rồi người dùng báo là thiếu tính năng Z
      Cứ có một nhóm tính năng mặc định rồi cho phép --enable-a --disable-b khi cần là được
      Việc lặng lẽ nuốt mất lỗi trong quá trình kiểm tra lại là một vấn đề khác