Kỹ thuật Zenbleed
(lock.cmpxchg8b.com)- Zenbleed là một lỗ hổng trên dòng AMD Zen 2, khai thác quá trình khôi phục
vzeroupperbị dự đoán sai để có thể đọc dữ liệu còn sót lại trong tệp thanh ghi vector của cùng một lõi vật lý - Được đăng ký là CVE-2023-20593, phạm vi ảnh hưởng bao gồm các sản phẩm Zen 2 như Ryzen 3000/4000/5000 with Radeon Graphics/7020 with Radeon Graphics, Ryzen PRO, Threadripper 3000, EPYC “Rome”
- Cuộc tấn công xảy ra khi XMM Register Merge Optimization, đổi tên thanh ghi và
vzeroupperbị dự đoán sai nối tiếp nhau trong một cửa sổ thời gian hẹp; ngay cả các phép toán cơ bản nhưstrlen,memcpy,strcmpcũng có thể trở thành đối tượng bị quan sát - Biến thể đã tối ưu hóa có thể rò rỉ khoảng 30KB mỗi giây trên mỗi lõi, và việc cùng chia sẻ tệp thanh ghi của một lõi vật lý khiến ranh giới VM, sandbox, container và tiến trình đều trở thành vấn đề
- Khuyến nghị áp dụng bản cập nhật microcode của AMD; tạm thời có thể đặt chicken bit
DE_CFG[9], nhưng có thể phải trả giá về hiệu năng và chỉ vô hiệu hóa SMT thôi là không đủ
Đơn vị thực thi mà Zenbleed nhắm tới
- CPU x86-64 có các thanh ghi vector XMM 128-bit, và CPU hiện đại mở rộng chúng lên YMM 256-bit và ZMM 512-bit
- Thanh ghi vector không chỉ dùng cho tính toán số mà còn được dùng trong các hàm thư viện C chuẩn của glibc như
strcmp,memcpy,strlen strlentối ưu bằng AVX2 trong glibc kết hợp nhiều lệnh vector để tìm vị trí byte nul đầu tiên trong chuỗivpxor xmm0,xmm0,xmm0đặt phần thấp củaymm0về 0vpcmpeqb ymm1,ymm0,[rdi]so sánh các byte của chuỗi với byte 0vpmovmskb eax,ymm1chuyển kết quả so sánh sang thanh ghi thông thườngtzcnt eax,eaxtính vị trí của byte nul đầu tiên
vzeroupper và tệp thanh ghi
vzeroupperlà lệnh đặt các bit cao của thanh ghi vector về 0- Khi trộn cách dùng thanh ghi
XMMvàYMM, thanh ghiXMMsẽ được nâng lên toàn bộ độ rộng, và trong quá trình này có thể phát sinh phụ thuộc vào các bit cao - glibc dùng
vzeroupperđể tránh các stall không cần thiết, nhờ đó các kết quả về sau không còn phụ thuộc vào các bit cao - CPU không đặt mỗi thanh ghi ở một vị trí vật lý cố định mà quản lý việc cấp phát thanh ghi vật lý bằng Register File và Register Allocation Table
- Khi đưa thanh ghi
XMMvề 0, CPU có thể không lưu các bit thực tế mà chỉ đặt cờ z-bit trong RAT- Cờ này có thể được áp dụng độc lập cho phần cao và phần thấp của thanh ghi
YMM vzerouppercó thể đặt z-bit rồi giải phóng tài nguyên tương ứng trong tệp thanh ghi
- Cờ này có thể được áp dụng độc lập cho phần cao và phần thấp của thanh ghi
Lỗ hổng phát sinh trong quá trình khôi phục thực thi suy đoán
- CPU hiện đại dùng thực thi suy đoán, nên các phép toán được thực hiện trên nhánh dự đoán sai phải được hoàn tác
- Vấn đề là khi
vzeroupperbị dự đoán sai đã được thực thi rồi được khôi phục, việc chỉ hoàn nguyên z-bit là không đủ để khôi phục chính xác trạng thái tài nguyên tệp thanh ghi đã bị giải phóng - Với lịch trình đủ chính xác, có thể khiến một số bộ xử lý khôi phục không chính xác từ
vzeroupperbị dự đoán sai - Kỹ thuật này là CVE-2023-20593 và ảnh hưởng đến toàn bộ dòng Zen 2
- AMD Ryzen 3000 Series Processors
- AMD Ryzen PRO 3000 Series Processors
- AMD Ryzen Threadripper 3000 Series Processors
- AMD Ryzen 4000 Series Processors with Radeon Graphics
- AMD Ryzen PRO 4000 Series Processors
- AMD Ryzen 5000 Series Processors with Radeon Graphics
- AMD Ryzen 7020 Series Processors with Radeon Graphics
- AMD EPYC “Rome” Processors
Điều kiện tấn công và phạm vi rò rỉ
- Để kích hoạt lỗi, XMM Register Merge Optimization, đổi tên thanh ghi và
vzeroupperbị dự đoán sai phải diễn ra liên tiếp trong một cửa sổ thời gian chính xác - Chuỗi lệnh ví dụ dùng cấu trúc sau
vcvtsi2s{s,d}để kích hoạt merge optimizationvmovdqađể kích hoạt đổi tên thanh ghi- Nếu nhánh điều kiện thực tế là taken nhưng CPU dự đoán theo đường not-taken,
vzerouppersẽ bị thực thi do dự đoán sai và lỗi sẽ xuất hiện
- Vì các phép toán cơ bản như
strlen,memcpy,strcmpcũng dùng thanh ghi vector, nên chúng có thể trở thành đối tượng bị quan sát ở bất kỳ đâu trong hệ thống - Do tệp thanh ghi được chia sẻ trên cùng một lõi vật lý, các VM, sandbox, container và tiến trình khác cũng nằm trong phạm vi ảnh hưởng
- Hai hyperthread chia sẻ cùng một tệp thanh ghi vật lý
- Biến thể tấn công đã tối ưu có thể rò rỉ khoảng 30KB mỗi giây trên mỗi lõi, đủ nhanh để theo dõi khóa mã hóa và mật khẩu của người dùng đang đăng nhập
- Tư vấn kỹ thuật và mã liên quan đã được công bố trong security research repository của Google
- Mã thử nghiệm được cung cấp cho Linux, nhưng lỗi này không phụ thuộc vào hệ điều hành cụ thể nên mọi hệ điều hành đều bị ảnh hưởng
Cách phát hiện: fuzzing CPU và Oracle Serialization
- Lỗ hổng được phát hiện bằng fuzzing
- Ngành CPU cũng thực hiện kiểm chứng sau silicon (Post-Silicon Validation) để tìm lỗi phần cứng sau khi sản xuất chip
- Khác với fuzzing dựa trên coverage thông thường, CPU không có chỉ số nào tương ứng trực tiếp với code coverage
- Thay vào đó, người ta dùng performance counters để cung cấp phản hồi về các sự kiện kiến trúc đáng chú ý cho fuzzer
- Cách này cho phép khám phá những chuỗi lệnh khó có thể tìm ra bằng ngẫu nhiên
- Các tính năng như merge optimization cũng có thể được phát hiện tự động
- Fuzzing phần mềm thường tìm crash, nhưng với các chương trình CPU được sinh ngẫu nhiên, bản thân crash đôi khi lại là hành vi đúng
- Một cách tiếp cận trước đây là reversi, tạo phép toán ngược cho từng lệnh ngẫu nhiên rồi kiểm tra xem trạng thái cuối có khác trạng thái ban đầu hay không
- Trên các kiến trúc CISC như x86, việc sinh test case trở nên phức tạp hơn
- Một cách khác là dùng oracle để so sánh kết quả của CPU đang kiểm thử với CPU khác hoặc trình mô phỏng
- Oracle Serialization kết hợp hai ý tưởng này
- Tạo chương trình ngẫu nhiên rồi tự động chuyển đổi sang dạng được tuần tự hóa
- Thêm các thành phần tuần tự hóa như store/load barrier, speculation fence, cache line flush
- Chương trình gốc và chương trình đã tuần tự hóa phải tạo ra cùng đầu ra dù đặc tính hiệu năng có khác nhau
- Nếu trạng thái cuối không khớp, đó có thể là lỗi thực thi vi kiến trúc, và chính sự sai khác này đã dẫn tới việc phát hiện Zenbleed
Ứng phó và giới hạn phát hiện
- Lỗ hổng đã được báo cho AMD vào ngày 15/5/2023
- AMD đã phát hành bản cập nhật microcode cho các bộ xử lý bị ảnh hưởng
- Nhà cung cấp BIOS hoặc hệ điều hành có thể đã phát hành bản vá kèm theo bản cập nhật này
- Biện pháp được khuyến nghị là áp dụng bản cập nhật microcode
- Khi không thể áp dụng bản cập nhật, có thể dùng biện pháp giảm thiểu ở mức phần mềm bằng cách đặt chicken bit
DE_CFG[9]- Có thể gây tổn thất hiệu năng
- Trên Linux có thể đặt cho mọi lõi bằng
msr-tools - Trên FreeBSD dùng
cpucontrol(8) - Nếu không biết cách thiết lập MSR trên hệ điều hành khác, cần nhờ hỗ trợ từ nhà cung cấp
- Chỉ vô hiệu hóa SMT là không đủ
- Chưa có kỹ thuật phát hiện tấn công đáng tin cậy nào được biết đến
- Vì không cần system call đặc biệt hay quyền đặc biệt nào
- Cũng không thể phát hiện tĩnh việc sử dụng
vzeroupperkhông phù hợp
1 bình luận
Ý kiến trên Hacker News
Vụ này thực sự rất đáng chú ý, và có thể trở thành ví dụ kinh điển cho việc chạy trong VM không có nghĩa là an toàn
Việc thoát VM từ lâu đã được biết đến, nhưng lần này là một lỗ hổng quy mô lớn, dễ khai thác mà không cần thoát, trong khi phần thưởng lại rất lớn
Việc lỗi này được sửa bằng microcode không có nghĩa là không tồn tại các lỗi tương tự khác. Nhiều 0-day thường đã được các nhóm black hat đánh thuê biết tới từ rất lâu trước khi bị công bố rộng rãi
Các lỗ hổng CPU được phát hiện trong vài năm gần đây:
https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)
https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)
https://aepicleak.com/
https://en.wikipedia.org/wiki/Software_Guard_Extensions#SGAxe
https://en.wikipedia.org/wiki/Software_Guard_Extensions#LVI
https://en.wikipedia.org/wiki/Software_Guard_Extensions#Plundervolt
https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
https://en.wikipedia.org/wiki/Software_Guard_Extensions#Enclave_attack
https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
https://www.vusec.net/projects/crosstalk/
https://en.wikipedia.org/wiki/Hertzbleed
https://securityweek.com/amd-processors-expose-sensitive-data-new-squi…
Thay vì diễn giải lệnh bằng một câu
switchlớn, nó chạy lệnh trên CPU thật và dựa vào một số cờ phần cứng để CPU đảm bảo dữ liệu hay lệnh không chồng lấn lên nhau. CPU có hứa như vậy, nhưng trong thực tế thì rất khó để giữ đúng lời hứa đóBên đó là một kiểu tấn công hoàn toàn mới, khả thi nhờ timing-based, dù CPU đã làm chính xác điều nó phải làm; còn Zenbleed lần này gần với một lỗi truyền thống hơn, nơi dữ liệu không được phép tồn tại lại bị lưu trong thanh ghi
Tôi cho rằng nhiều lỗ hổng kiểu này xuất phát từ việc phía phần mềm và phía phần cứng không thực sự trao đổi đúng mức với nhau. Phía phần mềm mặc định giả định có đảm bảo cô lập, còn phía phần cứng thì không cảnh báo đủ mạnh khi các giả định như vậy xuất hiện
Hoặc là branch prediction vốn phức tạp đến mức về bản chất sẽ luôn dễ dính các lỗ hổng kiểu này, hoặc nó khác quá xa với cách chúng ta trực quan hiểu về đường đi mã và việc thực thi lệnh, nên rất khó hình dung ra các điều kiện biên trước khi đã quá muộn
Liệu có lúc nào độ phức tạp của kiến trúc CPU trở nên khó suy luận đến mức chúng ta chấp nhận đánh đổi hiệu năng để giữ nó đơn giản hơn không?
Tôi đã chỉ ra điều này và khuyên rằng nên air-gap chúng bằng hypervisor riêng biệt, nhưng lúc nào cũng bị phớt lờ. Rốt cuộc thì có lẽ họ sẽ tự chịu thiệt thôi
README trong tệp tar của exploit có thêm chi tiết và lịch công khai
2023-05-09Một thành phần của pipeline kiểm chứng CPU tạo ra kết quả bất thường2023-05-12Cô lập và tái hiện thành công vấn đề, tiếp tục điều tra2023-05-14Xác định phạm vi và mức độ nghiêm trọng của vấn đề2023-05-15Viết báo cáo trạng thái ngắn gọn và chia sẻ với AMD PSIRT2023-05-17AMD xác nhận báo cáo và thừa nhận có thể tái hiện được2023-05-17Hoàn tất phát triển PoC đáng tin cậy và chia sẻ với AMD2023-05-19Bắt đầu thông báo cho các nhà cung cấp kernel và hypervisor lớn2023-05-23Nhận bản cập nhật microcode beta cho Rome từ AMD2023-05-24Xác nhận bản cập nhật đã khắc phục vấn đề và thông báo cho AMD2023-05-30AMD thông báo đã gửi thông báo bảo mật cho các đối tác2023-06-12Họp với AMD để thảo luận về trạng thái và chi tiết2023-07-20AMD công khai bản vá sớm hơn ngày embargo đã thống nhất mà không báo trước2023-07-21Vì bản sửa lỗi đã được công khai, đề xuất thông báo riêng cho các bản phân phối lớn chuẩn bị cập nhật gói firmware2023-07-24Công bố disclosureHọ đã công khai bản vá sớm hơn embargo đã thỏa thuận, rồi sau đó mới chuyển sang hướng đề nghị thông báo riêng cho các bản phân phối lớn rằng cần chuẩn bị gói firmware
amd-ucode 20230625.ee91452d-5của Arch Linux có bao gồm bản cập nhật microcode sửa lỗi này hay khônghttps://archlinux.org/packages/core/any/amd-ucode/ được cập nhật lần cuối vào 2023-07-25 11:48 UTC, còn https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin... thì ghi phiên bản sửa lỗi là 2023-07-18
Ban đầu tôi tưởng nó vẫn đang dùng firmware 20230625 vì trong PKGBUILD có
_tag=20230625vàsource=("git+[https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...](<https://git.kernel.org/pub/scm/…;)")Nhưng trong mảng
_backportscó hai commit cherry-pick được chỉnh sửa cách đây 20 giờ, vàb250b32ab1d044953af2dc5e790819a7703b7ee6tại https://gitlab.archlinux.org/archlinux/packaging/packages/li... chính là commit trên kernel.org đã được liên kết trước đó, nên hy vọng Arch mới nhất không còn dễ bị ZenbleedCái này thực sự đáng sợ. Trên thiết bị Zen 2 của tôi là Ryzen 3600, tôi chạy exploit với tư cách người dùng không có đặc quyền, rồi sao chép và dán một chuỗi vào trình soạn thảo văn bản chạy nền (Kate), và chỉ trong vài giây các mảnh của chuỗi đó đã được ghi lại trong đầu ra zenbleed
May mắn là exploit này có vẻ phụ thuộc rất nhiều vào một routine assembly cụ thể nên việc lạm dụng từ JS hay WASM trong trình duyệt có lẽ sẽ rất khó. Nếu không thì chỉ cần mở một tab độc hại ở nền trong vài giờ cũng đã có thể rò rỉ dữ liệu dễ dàng
Đang chờ maintainer Fedora phát hành microcode mới để kernel có thể cập nhật trong quá trình khởi động
Đồng thời hy vọng các bản vá phần mềm trong V8 và SpiderMonkey sẽ đến sớm hơn và giảm nhẹ thêm
Tuy nhiên exploit JS cũng sẽ cần một cách để đưa dữ liệu ra ngoài, mà việc che giấu hoàn toàn điều đó có lẽ khá khó
"No such file or directory"và error 127Có cảm giác việc OpenBSD vừa bổ sung tải microcode AMD trong vòng 3 ngày gần đây không phải là ngẫu nhiên
https://news.ycombinator.com/item?id=36838511
Có vẻ cách diễn đạt rằng AMD đã phát hành bản cập nhật microcode cho các bộ xử lý bị ảnh hưởng là chưa thật chính xác
AMD đã phát hành bản cập nhật microcode[0] cho family 17h model
0x31và0xa0, và theo WikiChip[1] thì các mã này tương ứng với Rome, Castle Peak, MendocinoCho đến nay có vẻ vẫn chưa có bản cập nhật microcode cho Renoir, Grey Hawk, Lucienne, Matisse, Van Gogh. May mắn là kernel mới có thể chỉ cần đặt chicken bit cho các dòng này, và thực tế cũng làm như vậy[2]
[0] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...
[1] https://en.wikichip.org/wiki/amd/cpuid#Family_23_.2817h.29
[2] https://github.com/torvalds/linux/commit/522b1d69219d8f08317...
good_revstheo phía kernel nằm ở đây: https://github.com/torvalds/linux/commit/522b1d69219d8f08317...Các revision (
Patch) hiện đã được công khai có thể xem ở đây theo git HEAD: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...Tại thời điểm viết bài này, trong năm
good_revchỉ mới công khai hai cáiDòng Celeron đó nổi tiếng vì có thể ép xung 50%: https://ark.intel.com/content/www/us/en/ark/products/codenam...
Xem phần liên quan thì kỹ thuật này là CVE-2023-20593, hoạt động trên mọi bộ xử lý cấp Zen 2, ít nhất bao gồm các sản phẩm sau
AMD Ryzen 3000 Series Processors
AMD Ryzen PRO 3000 Series Processors
AMD Ryzen Threadripper 3000 Series Processors
AMD Ryzen 4000 Series Processors with Radeon Graphics
AMD Ryzen PRO 4000 Series Processors
AMD Ryzen 5000 Series Processors with Radeon Graphics
AMD Ryzen 7020 Series Processors with Radeon Graphics
AMD EPYC “Rome” Processors
Có thể cùng kỹ thuật đó hoặc kỹ thuật tương tự cũng hoạt động trên các lõi Zen/Zen+ cũ hơn hoặc Zen 3 mới hơn, chỉ là chưa chứng minh được hay không?
AMD Ryzen 9 5950x Desktop Processorcủa tôi cũng có vẻ là Zen 3 nên chắc ổnTôi không chạy tác vụ không đáng tin cậy, nhưng vẫn cứ nên cẩn thận thì hơn
Trang web đang sập vì quá tải lưu lượng: https://web.archive.org/web/20230724143835/https://lock.cmpx...
Trong đa số trường hợp, traffic từ HN còn chẳng đạt nổi 100 pageview mỗi giây
https://www.amd.com/en/resources/product-security/bulletin/a...
Theo thông báo bảo mật của AMD, bản cập nhật firmware cho CPU không phải EPYC sẽ không có cho tới cuối năm. Vậy đến lúc đó người dùng phải tắt chicken bit và chấp nhận tổn thất hiệu năng sao?
Vừa ấn tượng vừa đáng sợ. Sau khi chạy mẫu 10MB trong 1 phút, tôi đã có thể “rò rỉ” được một phần mật khẩu Bitwarden của mình, mật khẩu đăng nhập ssh, các mảnh thông tin xác thực ngân hàng, và có thể dễ dàng ghép lại
Bài viết thực sự rất hay. Tôi đặc biệt thích phần bàn về cách có thể xác định liệu một chương trình được sinh ngẫu nhiên có chạy đúng hay không
Cách tiếp cận hiển nhiên là chạy nó trên một oracle như bộ xử lý khác hoặc trình mô phỏng để xem nó có hoạt động theo cùng một cách hay không
Nhưng để kiểm tra các hiệu ứng vi kiến trúc trong những cửa sổ thời gian hẹp, người ta cũng có thể viết cùng một chương trình với nhiều
stall,fence,nopv.v. được chèn vào. Trong mã đơn luồng, điều đó không được ảnh hưởng đến đầu ra, nhưng bên trong CPU thì vi kiến trúc sẽ thực hiện những việc khá khác nhau. Nhờ vậy CPU có thể trở thành oracle của chính nóTôi cũng thích cả chicken bit