1 điểm bởi GN⁺ 2024-04-02 | 1 bình luận | Chia sẻ qua WhatsApp
  • xzbot là một kho lưu trữ để nghiên cứu backdoor xz (CVE-2024-3094), đồng thời cung cấp honeypot, bản vá khóa công khai ED448, định dạng payload của backdoor và demo thực thi mã từ xa
  • Honeypot áp dụng một bản vá đơn giản cho OpenSSH để ghi lại vào log sshd các nỗ lực kết nối đi vào với giá trị N của khóa công khai khớp với định dạng backdoor
  • Bản vá ED448 thay khóa công khai hardcode mà backdoor dùng để xác minh chữ ký và giải mã payload bằng khóa do người dùng tạo, nhờ đó có thể kích hoạt backdoor
  • Payload của backdoor được đặt trong giá trị N của khóa ký CA của chứng chỉ SSH, tạo loại yêu cầu bằng a * b + c, và Type 2 sẽ thực thi lệnh kết thúc bằng null thông qua system()
  • CLI demo cho thấy luồng kết nối tới máy chủ SSH dễ bị tấn công để thực thi lệnh, và việc khai thác thành công không tạo log ở mức INFO trở lên

Phạm vi và cấu thành của xzbot

  • xzbot là một dự án để nghiên cứu CVE-2024-3094, backdoor trong xz
  • Có bốn thành phần đi kèm
    • honeypot: máy chủ giả lập dễ bị tấn công để phát hiện các nỗ lực khai thác
    • ed448 patch: vá liblzma.so để dùng khóa công khai ED448 của riêng bạn
    • backdoor format: tổng hợp định dạng payload của backdoor
    • backdoor demo: CLI kích hoạt RCE với giả định biết khóa riêng ED448

Honeypot: phát hiện nỗ lực bằng bản vá OpenSSH

  • openssh.patch là một bản vá đơn giản áp dụng cho OpenSSH để ghi lại các nỗ lực kết nối đi vào với giá trị N của khóa công khai khớp định dạng backdoor
  • Quy trình là clone openssh-portable, sau đó áp dụng bản vá và chạy autoreconf, configure, make
  • Các nỗ lực kết nối sẽ xuất hiện trong log sshd dưới dạng xzbot: magic 1 [preauth] cùng chuỗi byte của payload

Bản vá khóa công khai ED448

  • Backdoor sử dụng khóa công khai ED448 hardcode để xác minh chữ ký và giải mã payload
  • Nếu thay khóa công khai này bằng khóa mà người dùng sở hữu, có thể kích hoạt backdoor
  • Kho lưu trữ đưa ra cả khóa công khai ED448 của kẻ tấn công lẫn giá trị khóa công khai thay thế được tạo với seed=0
  • Bước khởi đầu là chuẩn bị shared object liblzma.so.5.6.1 có chứa backdoor
    • Một nguồn ví dụ được nêu là Debian snapshot của xz-utils 5.6.1-1
    • Sau khi cài pwntools, chạy patch.py liblzma.so.5.6.1 sẽ tạo ra liblzma.so.5.6.1.patch
    • Sau đó chạy sshd bằng shared object đã chỉnh sửa liblzma.so.5.6.1.patch
  • Có ví dụ trong assets

Định dạng payload của backdoor

  • Backdoor có thể được kích hoạt bằng cách đặt payload vào bên trong giá trị N của khóa ký CA khi kết nối bằng chứng chỉ SSH
  • Payload này phải được mã hóa và ký bằng khóa ED448 của kẻ tấn công
  • Cấu trúc ngoài cùng gồm các trường sau
    • a: 32 bit
    • b: 32 bit
    • c: 64 bit
    • ciphertext: 240 byte
  • Loại yêu cầu được suy ra từ a * b + c
    • Nếu giá trị lớn hơn 3, backdoor sẽ bỏ qua xử lý
    • Type 1: chưa rõ mục đích và mong đợi 0 byte
    • Type 2: thực thi payload kết thúc bằng null bằng system()
    • Type 3: chưa rõ mục đích và mong đợi dữ liệu chữ ký 48 byte
  • ciphertext được mã hóa bằng chacha20, dùng 32 byte đầu của khóa công khai ED448 làm khóa đối xứng
    • Vì thế, các nỗ lực khai thác có thể được giải mã bằng khóa 32 byte đã được nêu
  • Bên trong ciphertext sau khi giải mã có chữ ký 114 byte, các trường 1 bit xy, độ dài, chuỗi lệnh, v.v.
    • Nếu đặt x hoặc y, luồng sẽ đi vào các nhánh mã hơi khác nhau
  • Chữ ký là chữ ký ED448 theo RFC-8032
    • Đầu vào bao gồm giá trị magic 32 bit, trường 5 byte trước lệnh, tùy chọn thêm length byte của lệnh, và 32 byte đầu của băm SHA-256 của hostkey máy chủ

CLI demo khai thác

  • CLI được cài bằng Go
    • go install github.com/amlweems/xzbot@latest
  • xzbot -h hiển thị ba tùy chọn chính
    • -addr: địa chỉ máy chủ SSH, mặc định 127.0.0.1:2222
    • -seed: ED448 seed phải khớp với khóa của backdoor xz, mặc định 0
    • -cmd: lệnh sẽ được chạy bằng system(), mặc định id > /tmp/.xz
  • Ví dụ sẽ kết nối tới máy chủ SSH dễ bị tấn công tại 127.0.0.1:2222 để chạy lệnh id > /tmp/.xz
  • Nếu đặt watchpoint tại vị trí gọi system() trên máy chủ dễ bị tấn công, có thể thấy tiến trình sshd thực thi id > /tmp/.xz
  • Sau khi chạy, có ví dụ cho thấy /tmp/.xz chứa đầu ra uid=0(root) gid=0(root) groups=0(root)

Cây tiến trình và đặc tính log

  • Cây tiến trình của một kết nối SSH bình thường sẽ nối tiếp tới phiên người dùng và shell của sshd
  • Ví dụ chạy backdoor là sau xzbot -cmd 'sleep 60', sẽ xuất hiện sshd: root [priv], sshd: root [net], sh -c sleep 60, sleep 60
  • Việc khai thác thành công không tạo mục log ở mức INFO trở lên

Tài liệu tham khảo

1 bình luận

 
GN⁺ 2024-04-02
Ý kiến trên Hacker News
  • Điều khá thú vị là nó không phải là thực thi mã từ xa mà ai cũng có thể lạm dụng, mà lại yêu cầu khóa riêng của kẻ tấn công
    Trớ trêu thay, nó trông giống một lỗ hổng có ý thức bảo mật rất cao

    • Có lẽ ý định ban đầu là kéo dài tuổi thọ của backdoor
      Nếu mở một lỗ hổng lớn để ai cũng vào được thì sẽ nhanh chóng bị phát hiện và vá lại; nếu không có suy giảm hiệu năng, rất có thể nó đã âm thầm tồn tại lâu dài với lý do không thể bị khai thác rộng rãi
    • Nếu nhìn như một cuộc tấn công được nhà nước hậu thuẫn, việc cài một lỗ hổng an toàn vào các hệ thống mà cả công dân nước mình cũng có thể dùng là khá hợp lý
      Toàn bộ đóng góp cho xz rốt cuộc trông như công việc nhằm đưa backdoor này vào, chẳng hạn còn tạo cả framework kiểm thử có thể che giấu payload độc hại
      Trước khi làm với xz, người này cũng đã đóng góp cho libarchive của BSD, và ở đó đã xuất hiện lỗ hổng
    • Nó thật sự trông giống một exploit được nhà nước hậu thuẫn
      Thiết kế và triển khai cực kỳ tinh vi, và việc vấn đề hiệu năng trở thành manh mối phát hiện gần như hoàn toàn là may mắn
    • Cái này được gọi là NOBUS: https://en.wikipedia.org/wiki/NOBUS
    • Tôi đọc thấy có vẻ chữ ký payload bao gồm khóa host SSH của mục tiêu, không biết có đúng không
      Nếu vậy thì không thể rải bừa lên các máy chủ, và bản thân việc gửi tới một host đã là cấu trúc có chi phí tính toán khá đáng kể
  • Vụ này cứ quanh quẩn trong đầu tôi suốt cả cuối tuần
    Cơ chế thì thú vị và là một tập hợp kỹ thuật obfuscation xuất sắc, còn phần social engineering thì quen thuộc đến mức đáng xấu hổ đối với maintainer mã nguồn mở
    Điều thú vị nhất là việc chọn dữ liệu kiểm thử xấu làm vector tấn công: nếu chuẩn bị một archive tốt, thao túng có cấu trúc rồi dùng nó làm dữ liệu xấu cho fuzz test, các bước còn lại trở nên cực kỳ dễ dàng
    Nói để sau này tham khảo, kiểu thao túng này có lẽ phải hiện ra trong đồ thị mẫu nhị phân
    Các kỹ thuật còn lại, sau khi payload đã được xác định, phần lớn gần với obfuscation thông thường; nhưng nước đi xuất sắc nhất là với cùng mẫu đó, họ có thể âm thầm thêm “bản vá” hoặc thậm chí một backdoor mới vào các file kiểm thử khác mà không bị nhận ra
    Việc GitHub ẩn và gỡ kho lưu trữ chẳng giúp ích gì, mà còn cản trở việc phân tích vụ này

    • Tôi bắt đầu nghi ngờ các phụ thuộc tại thời điểm build của các công cụ mã nguồn mở mà chúng tôi dùng
      Chúng tôi phát hiện phụ thuộc đó đặc biệt ưu ái xz, và nếu chưa được cài thì còn cài cả xz lên máy host như một tính năng tiện lợi
      Nó không làm vậy với các phụ thuộc khác, nên hơi lạ
      Những cuộc chơi dài hơi kiểu này thật đáng sợ, và cho đến khi “điều ác” thực sự được thực thi thì không thể biết cái gì là độc hại, cái gì chỉ là kỳ quặc
    • Một nguyên nhân cốt lõi có vẻ là việc thêm file nhị phân vào kho lưu trữ để dùng làm input kiểm thử
      Đặc biệt nếu đó là file “rác nhị phân” để chứng minh lỗi kiểm thử, thì đây là nơi quá lý tưởng để giấu nội dung độc hại
    • Vì kho lưu trữ đã bị gỡ bỏ, rốt cuộc chỉ kẻ tấn công mới có quyền truy cập vào mã và bí quyết
  • Rất ấn tượng khi cộng đồng, đặc biệt là amlweems, đã triển khai và tài liệu hóa mã chứng minh khái niệm nhanh đến vậy
    Nếu không có thêm lỗ hổng trong chức năng mật mã hoặc nạp payload, có thể nó cũng chưa mở lỗi bảo mật cho tất cả kẻ tấn công khác cho tới khi khóa bị phá
    Bước tiếp theo là tìm cách phát hiện các bản phân phối dễ bị tấn công, nhưng có vẻ không dễ; upstream cũng có thể đưa vào cách giám sát xem có ai đang chủ động dò quét máy chủ SSH bằng khóa hardcode hay không

    • Đó không phải exploit gốc, mà là chứng minh khái niệm cho phiên bản đã thay khóa
      Chứng minh khái niệm cho phiên bản gốc cần khóa riêng của kẻ tấn công, vốn chưa được công khai
    • Việc phát hiện bản phân phối dễ bị tấn công qua mạng mà không có khóa riêng của kẻ tấn công trông không phải là khó mà gần như bất khả thi
      Điều tốt nhất có thể làm là benchmark tinh vi hơn, nhưng không thể biết một host Internet bất kỳ chậm vì dễ bị tấn công, vì ở xa, hay vì bản thân máy tính chậm
      Cũng không thể truy cập thời gian các lần thử kết nối trước đây tới host đó, và định tuyến cũng thay đổi
  • Tôi tò mò liệu đã có ai chạy chứng minh khái niệm này qua các công cụ phát hiện hành vi tiến trình bất thường chưa
    Các sản phẩm như Carbon Black, AWS GuardDuty, Sysdig thuộc nhóm này, và đây có vẻ là ca rất phù hợp để thử xem liệu khi nó được triển khai thật, có ai phát hiện tương đối nhanh hay không

    • Tôi nghĩ còn tùy exploit bắt chước hành vi nén bình thường giống đến mức nào hoặc ẩn trong đó ra sao
      GuardDuty không nhìn vào tiến trình như EDR kiểu CrowdStrike hay Carbon Black, nên có lẽ khó bắt; Sysdig thì quan sát container và hạ tầng cloud, nên có vẻ khó bắt chính exploit
      Tuy vậy, sau khi leo thang đặc quyền, vẫn có khả năng bắt được dấu hiệu bất thường trong các hành động tiếp theo của tác nhân đe dọa
      Rốt cuộc, thứ có khả năng bắt chính exploit cao nhất có lẽ là EDR giám sát tiến trình endpoint, hoặc đánh giá chuỗi cung ứng phần mềm giám sát vấn đề bảo mật trong phần mềm tự do/mã nguồn mở upstream
      Điều thú vị là chuyện này dẫn tới một chủ đề bảo mật lớn hơn
      Đội phát triển có thể không thích cài EDR lên server vì suy giảm hiệu năng và vấn đề trải nghiệm người dùng khi cách ly, và cũng có thể không thích chính sách hạn chế sử dụng phần mềm tự do/mã nguồn mở
      Exploit này đâm thẳng vào giữa “lỗ hổng” ở cấp tổ chức; tùy vị trí mà sẽ xuất hiện cả lập luận để duy trì mức phơi nhiễm lẫn lập luận để khắc phục
    • Sysdig đã đăng blog vào thứ Sáu
      Họ nói: “Một cách phát hiện runtime là giám sát xem SSHD có tải thư viện độc hại hay không. Các thư viện chia sẻ như vậy thường chứa phiên bản trong tên file”
      Blog cũng có nội dung quy tắc phát hiện thực tế mà tôi chưa thấy ở các hãng bảo mật khác
      https://sysdig.com/blog/cve-2024-3094-detecting-the-sshd-bac...
    • Tôi cho rằng gần như toàn bộ nhóm sản phẩm đó phần lớn chỉ là sản phẩm bảo mật thổi phồng
  • Tôi đã đọc nhầm liên kết bên dưới, và để lại nội dung gốc nhằm mục đích ghi lại
    Nếu xem phần dưới trong cùng luồng mail, có nói rằng người đã commit backdoor gần đây dường như cũng đã đóng góp cho kernel, nhưng bản phân tích gốc thực sự rất xuất sắc nên bài kiểu này rất đáng đọc
    https://www.openwall.com/lists/oss-security/2024/03/29/10

    • Loạt patch đó là do Lasse đăng, không phải Jia Tan
      Bản thân Lasse cũng nói việc này hoàn toàn không khẩn cấp và sẽ không vào cửa sổ merge lần này; người bình thường không ai quy kết Lasse là tác nhân độc hại
    • Cho đến khi có bằng chứng ngược lại, Lasse Collin không phải là Jia Tan
    • Loạt patch được tham chiếu vẫn chưa được đưa vào kernel
    • Có thể chỉ là trùng hợp, nhưng JiaT75 trông khá giống mã transponder 7500, mã chỉ việc không tặc trong hàng không
  • Vụ này có quá nhiều điểm giống vụ Audacity vài năm trước đến mức khó tin
    Cookie guy từng tuyên bố mình bị đâm và cảnh sát liên bang đã tham gia vụ việc; điều này gợi ý khả năng vụ đó có liên quan tới một tác nhân lớn hơn 4chan rất nhiều
    Khi đó nhiều người nghĩ chỉ có Muse Group liên quan, nhưng có thể đó là một tác nhân nhà nước Nga
    Trước đó, họ từng tuyên bố Audacity có nhiều telemetry và backdoor nên đã fork rồi loại bỏ trong commit đầu tiên
    Có lẽ Audacity thực sự cũng có backdoor, nên cần kiểm tra mã nguồn

    • Cần cẩn thận, APT28 khá nguy hiểm
      Dạo này họ đang gộp hoạt động với APT29, và nếu là tôi thì sẽ không đánh thức cozy bear
    • Cookie guy là ai?
  • Tôi thắc mắc exploit thật đã làm việc này ở runtime như thế nào, khi không có openssh.patch honeypot tại thời điểm biên dịch https://github.com/amlweems/xzbot/blob/main/openssh.patch
    Chuỗi là opensshd -> thông báo systemd -> xz được đưa vào như phụ thuộc tạm thời, nhưng tôi muốn biết sau khi liblzma.so.5.6.1 được load vào bộ nhớ, nó đã lần ngược lên tới openssh_RSA_verify để hook hoặc patch ra sao

    • Khi load liblzma, nó patch địa chỉ mã độc vào GOT của ELF
      Nếu được load trước libcrypto, nó đăng ký một trình xử lý kiểm toán symbol; có vẻ đây là tính năng riêng của glibc, cho phép nhận thông báo khi symbol của libcrypto được resolve và trì hoãn việc patch GOT
    • Đó là ifunc
  • Tôi thắc mắc liệu exploit này chỉ hoạt động khi có kết nối SSH đi vào hay không
    Danh sách chuỗi trên GitHub có chứa DISPLAYWAYLAND_DISPLAY
    https://gist.github.com/q3k/af3d93b6a1f399de28fe194add452d01
    Những thứ này không có liên quan rõ ràng tới SSH, nên có khả năng nó đã làm gì đó cả khi không có kết nối
    Điều này có thể quan trọng với những người cho rằng mình an toàn vì đã chạy mã nhưng không để lộ SSH server ra Internet

    • Nhiều khả năng đó là kill switch để exploit không hoạt động nếu có terminal đang mở hoặc nếu đang chạy trong phiên GUI
      Tức là cơ chế để tránh các tình huống ai đó đang cố phát hiện, tái hiện hoặc debug
    • Cũng có thể liên quan đến X11 session forwarding
      Nếu không tắt khi kết nối tới máy không đáng tin cậy, nó sẽ trở thành lỗ hổng bảo mật phổ biến ở phía người kết nối
  • Tôi thắc mắc câu “khai thác thành công không tạo ra mục log” có nghĩa là, nếu exploit này không bị phát hiện, kẻ tấn công có thể chạy lệnh tùy ý với quyền root trên host bị xâm nhập mà không có một dòng log sshd nào cho “kết nối” đó hay không

    • Đúng vậy
      Thực thi mã từ xa xảy ra ở giai đoạn kết nối, trước khi log được ghi
    • Dù vậy vẫn sẽ còn lưu lượng SSH không đi kèm đăng nhập tương ứng
      Tôi thắc mắc kiểu phát hiện bất thường nào có thể bắt được việc này
  • Tôi thắc mắc nếu tách các file test sang một kho riêng để không thể dùng ở thời điểm build thì có làm cuộc tấn công này khó hơn không
    Lập luận là bất cứ thứ gì tham gia vào build thì con người phải đọc được

    • “Bất cứ thứ gì tham gia vào build thì con người phải đọc được” nhìn chung là một nguyên tắc nên được áp dụng
      Cần đối xử với cuộc tấn công này như một tai nạn hàng không và đưa ra các quy tắc mới để giảm khả năng nó thành công lần nữa
      Dù không thể xác minh từng cộng tác viên một, dữ liệu test nhiễu thì nên dễ dàng được tách riêng