Xzbot: ghi chú, honeypot và demo khai thác cho backdoor xz
(github.com/amlweems)- 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
sshdcá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 quasystem() - 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ạyautoreconf,configure,make - Các nỗ lực kết nối sẽ xuất hiện trong log
sshddưới dạngxzbot: 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.1có 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ạypatch.py liblzma.so.5.6.1sẽ tạo raliblzma.so.5.6.1.patch - Sau đó chạy
sshdbằng shared object đã chỉnh sửaliblzma.so.5.6.1.patch
- Một nguồn ví dụ được nêu là Debian snapshot của
- 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 bitb: 32 bitc: 64 bitciphertext: 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
ciphertextsau khi giải mã có chữ ký 114 byte, các trường 1 bitxvày, độ dài, chuỗi lệnh, v.v.- Nếu đặt
xhoặcy, luồng sẽ đi vào các nhánh mã hơi khác nhau
- Nếu đặt
- 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
lengthbyte của lệnh, và 32 byte đầu của băm SHA-256 của hostkey máy chủ
- Đầ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
CLI demo khai thác
- CLI được cài bằng Go
go install github.com/amlweems/xzbot@latest
xzbot -hhiển thị ba tùy chọn chính-addr: địa chỉ máy chủ SSH, mặc định127.0.0.1:2222-seed: ED448 seed phải khớp với khóa của backdoor xz, mặc định0-cmd: lệnh sẽ được chạy bằngsystem(), mặc địnhid > /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ệnhid > /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ìnhsshdthực thiid > /tmp/.xz - Sau khi chạy, có ví dụ cho thấy
/tmp/.xzchứa đầu rauid=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ệnsshd: 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
1 bình luận
Ý 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
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
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
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
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
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
Đặ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
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
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
Đ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
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
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 đã đọ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
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
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
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
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 khiliblzma.so.5.6.1được load vào bộ nhớ, nó đã lần ngược lên tớiopenssh_RSA_verifyđể hook hoặc patch ra saoNế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
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
DISPLAYvàWAYLAND_DISPLAYhttps://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
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
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
Thực thi mã từ xa xảy ra ở giai đoạn kết nối, trước khi log được ghi
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
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