Đã có thời đặc quyền quản trị là “đích” cho kẻ tấn công trên Windows. Nạp một driver kernel với tư cách quản trị, dump bộ nhớ của tiến trình LSASS, và bạn có hash mật khẩu cùng vé Kerberos. Từ đó chỉ còn việc bước sang máy khác với các hash đã đánh cắp.
Trên Windows 11 hiện tại với Credential Guard đang chạy — trạng thái mặc định từ 22H2 trở đi trên các thiết bị đáp ứng yêu cầu giấy phép như Enterprise và Education, cộng yêu cầu phần cứng — kịch bản đó không còn hiệu lực. Một kẻ tấn công đã chiếm hoàn toàn kernel có thể lục bộ nhớ thoải mái, và các hash thật của thông tin xác thực miền được bảo vệ không được tìm thấy “bên trong hệ điều hành đó”. Nếu nó không chạy, mối nguy cũ vẫn còn, nên hãy đọc bài này cùng các phương pháp xác nhận ở phần sau.
Vậy chúng ở đâu? Câu trả lời là “một thế giới khác, được tạo bên trong cùng một PC”. Như chúng ta đã thấy ở Phần 1, Windows máy chủ chạy trong phân vùng gốc trên hypervisor (“Windows của bạn thực sự chạy ở đâu?”). Bài này tiếp tục từ đó và lần theo thêm một đường ranh giới mà hypervisor vẽ bên trong cùng một phân vùng.
Câu hỏi Phần 2 trả lời chỉ có một.
Windows đặt những bí mật mà cả quản trị viên lẫn kernel đều không đọc được ở đâu?
Đối tượng là các nhà phát triển và vận hành đã thấy những từ như Core isolation, Memory integrity và Credential Guard trên màn hình cài đặt hoặc trong một vụ xử lý sự cố, và muốn hiểu vật thật từ cơ chế lên. Điều kiện tiên quyết là x64 Windows 10/11 hoặc Windows Server hiện hành (như Phần 1, phần thảo luận về ring và SLAT giả định x64; Arm64 dùng cơ chế khác như mức ngoại lệ). Nền tảng cần có là các khái niệm phân vùng và SLAT đã đề cập ở Phần 1. Độ khó là trung cấp. Mục tiêu là giải thích cấu trúc, không phải hướng dẫn cấu hình các tính năng bảo mật.
1. Kết luận trước
Windows thêm một trục đặc quyền gọi là VTL (Virtual Trust Level) và đặt các bí mật vào VTL1. Bộ nhớ trong VTL1 không đọc được từ kernel thông thường chạy ở VTL0. Thứ canh gác ranh giới không phải bản thân kernel, mà là hypervisor giữ các bảng dịch SLAT.
Đó là khung xương của bảo mật dựa trên ảo hóa (VBS). VBS dùng hypervisor để tạo môi trường cô lập và đặt các tính năng bảo mật vào đó. Nó được thiết kế với giả định rằng môi trường cô lập vẫn được bảo vệ ngay cả khi kernel bị xâm phạm.1
flowchart TB
accTitle: Hai thế giới mà VBS tạo ra
accDescr: VTL0 và VTL1 nằm trong cùng một phân vùng; VTL0 giữ kernel thông thường và ứng dụng, VTL1 giữ Secure Kernel và các tính năng bảo mật cô lập, và hypervisor canh gác ranh giới
subgraph vtl0 ["VTL0(thế giới thông thường)"]
apps["Ứng dụng(ring 3)"]
ntk["Kernel NT và driver(ring 0)"]
end
subgraph vtl1 ["VTL1(thế giới cô lập)"]
ium["Các tính năng bảo mật cô lập"]
sk["Secure Kernel"]
end
hv["Hypervisor(thực thi ranh giới qua SLAT)"] --- vtl0
hv --- vtl1
ntk -.->|Không đọc được| ium
Hình 1: Có hai thế giới bên trong một Windows, và kernel VTL0 không thể truy cập bộ nhớ VTL1.
Điểm quan trọng là đây không phải “dựng thêm một VM khác”. VTL0 và VTL1 nằm bên trong cùng một phân vùng, bên trong cùng một Windows. Chúng ta sẽ lần lượt xem sự tách này được thực hiện như thế nào.
2. Giới hạn của mô hình ring — Người canh và vật được canh ngồi cùng độ cao
Bảo mật Windows truyền thống được xây trên thang các ring (mức đặc quyền). Chế độ user (ring 3) được chế độ kernel (ring 0) canh. Vậy ai canh ring 0 — không ai cả. Ring 0 là đặc quyền cao nhất.
Cấu trúc này có hai điểm yếu cấu trúc.
- Kernel không phải một khối nguyên. Ở ring 0, không chỉ bản thân Windows mà rất nhiều driver bên thứ ba chạy. Nếu bất kỳ cái nào có lỗ hổng, kẻ tấn công có được thực thi mã ở ring 0.
- Từ ring 0, mọi thứ đều thấy được. Dù một tiến trình chế độ user như LSASS tự vệ đến đâu, bộ nhớ của nó tự do đọc với kẻ tấn công đã chiếm kernel. Thuộc tính bảo vệ và bảng trang cũng đều do chính kernel quản lý.
flowchart TB
accTitle: Đường đánh cắp thông tin xác thực trong mô hình ring truyền thống
accDescr: Kẻ tấn công chiếm ring 0 qua một driver có lỗ hổng có thể đọc bộ nhớ tiến trình LSASS với toàn quyền của kernel và lấy hash mật khẩu
mal["Mã kẻ tấn công"] -->|Khai thác driver có lỗ hổng| r0["Chiếm quyền điều khiển ring 0"]
r0 --> readall["Có thể đọc toàn bộ bộ nhớ vật lý"]
readall --> lsass["Lấy hash từ bộ nhớ LSASS"]
lsass --> lateral["Bị lạm dụng để di chuyển ngang sang máy khác"]
Hình 2: Vì người canh (kernel) và vật được canh (các bí mật) ngồi cùng độ cao, điểm yếu căn bản là nếu ring 0 sụp thì mọi thứ sụp.
Vậy cái cần là “một chỗ cao hơn ring 0”. Chỗ đó đã xuất hiện ở Phần 1. Hypervisor chạy ở đặc quyền cao hơn kernel và độc quyền kiểm soát quyền truy cập bộ nhớ của CPU (SLAT) từ sớm. Một vùng cô lập mà hypervisor canh được bảo vệ ngay cả trước truy cập từ phần mềm hệ điều hành ring-0 (chế độ supervisor).2
3. VSM và VTL — Thêm một trục đặc quyền nữa
3.1. Virtual Trust Level (VTL)
Họ tính năng hypervisor cung cấp sự cô lập này được gọi là VSM (Virtual Secure Mode). VSM là nền tảng cho Device Guard, Credential Guard, TPM ảo, và tương tự.2
Khái niệm trung tâm của VSM là VTL (Virtual Trust Level). Các điểm chính như sau.2
- VTL có thứ bậc, và số càng cao, đặc quyền càng cao. VTL0 là thấp nhất; VTL1 đặc quyền hơn VTL0.
- Về kiến trúc tối đa 16 mức được định nghĩa, nhưng những gì hiện được triển khai là hai: VTL0 và VTL1.
- Mỗi VTL có các bảo vệ truy cập bộ nhớ độc lập. Các bảo vệ này được hypervisor quản lý đối với không gian địa chỉ vật lý của phân vùng, nên phần mềm hệ thống bên trong phân vùng không thể thay đổi chúng.
- Một bộ xử lý ảo có trạng thái thanh ghi và bộ máy ngắt riêng theo từng VTL, và một VTL thấp hơn không thể nhìn trộm trạng thái của VTL cao hơn.
flowchart TB
accTitle: Ba sự độc lập tạo nên cô lập VTL
accDescr: Bảo vệ truy cập bộ nhớ, trạng thái thanh ghi bộ xử lý ảo, và bộ máy ngắt độc lập theo từng VTL, và một VTL thấp hơn không thể chạm bất kỳ thứ nào ở VTL cao hơn
vtl["Những gì độc lập theo từng VTL"] --> m1["Bảo vệ truy cập bộ nhớ"]
vtl --> m2["Trạng thái thanh ghi bộ xử lý ảo"]
vtl --> m3["Bộ máy ngắt"]
m1 -.-> rule["VTL thấp hơn không chạm được VTL cao hơn"]
m2 -.-> rule
m3 -.-> rule
Hình 3: Làm không chỉ bộ nhớ mà cả trạng thái CPU và ngắt thành một thế giới riêng là bộ ba không để lại lỗ nhìn trộm.
Nếu các ring (0 và 3) là trục tách “hệ điều hành và ứng dụng”, VTL là trục thứ hai tách “thế giới thông thường và thế giới cô lập”. Hai trục trực giao, và bên trong VTL1 cũng có chế độ kernel và chế độ user.
flowchart TB
accTitle: Bốn vùng được tạo bởi hai trục ring và VTL
accDescr: Trục ring tách chế độ kernel và chế độ user, trục VTL tách thế giới thông thường và thế giới cô lập, và sự kết hợp tạo bốn vùng: ứng dụng thông thường, kernel NT, trustlet IUM, và Secure Kernel
subgraph ax0 ["VTL0(thế giới thông thường)"]
a0["Ring 3: ứng dụng thông thường"]
k0["Ring 0: kernel NT và driver"]
end
subgraph ax1 ["VTL1(thế giới cô lập)"]
a1["Ring 3: IUM(trustlet)"]
k1["Ring 0: Secure Kernel"]
end
a0 --- k0
a1 --- k1
k0 ~~~ a1
Hình 4: Giờ có hai trục đặc quyền, và “có phải kernel không?” cùng “có phải thế giới cô lập không?” trở thành các câu hỏi tách biệt.
3.2. Thực chất của ranh giới là SLAT
Ở Phần 1 chúng ta nói rằng các bảng dịch cấp hai ánh xạ địa chỉ vật lý của khách (GPA) lên RAM thật (SPA) — SLAT — do hypervisor giữ. VSM dùng đúng thuộc tính này. Cô lập VTL được tạo bằng hypervisor Hyper-V và SLAT.3
Khi VTL1 tuyên bố “bộ nhớ này không được hiện cho VTL0”, hypervisor gỡ quyền truy cập tới trang đó khỏi các bảng dịch của VTL0. Từ đó trở đi, dù kernel VTL0 cố chạm địa chỉ đó, nó bị từ chối ở giai đoạn dịch địa chỉ của CPU. Việc kernel viết lại bảng trang của riêng nó thế nào cũng vô ích. Các bảng trang (GVA→GPA) có thể thuộc về kernel, nhưng lần dịch phía sau (GPA→SPA) và quyền truy cập cuối cùng thuộc về hypervisor.
flowchart TB
accTitle: Luồng truy cập từ VTL0 tới bộ nhớ VTL1 bị từ chối
accDescr: Khi kernel VTL0 cố đọc bộ nhớ VTL1, nó có thể vượt bảng trang của riêng mình nhưng bị từ chối bởi bảo vệ truy cập SLAT, và quyền điều khiển chuyển cho hypervisor
try["Kernel VTL0 cố đọc một trang VTL1"] --> pt["Vượt bảng trang của chính kernel"]
pt --> slat{"Bảo vệ truy cập SLAT có cho phép?"}
slat -->|Không cho phép| deny["Hypervisor can thiệp và từ chối truy cập"]
slat -->|Cho phép| ok["Truy cập bộ nhớ thông thường"]
deny -.-> point["Được bảo vệ ở lớp mà kernel không đổi được"]
Hình 5: Rào chắn nằm ngoài kernel, và các bảo vệ SLAT không thể bị phần mềm bên trong phân vùng thay đổi.
Ở Phần 1 của loạt bài bộ nhớ chúng ta viết rằng “VAD, PTE và thuộc tính bảo vệ quyết định truy cập có được phép không”. Trong môi trường VBS bạn có thể sắp xếp như sau: sau khi tất cả những thứ đó đã được vượt qua, một trạm kiểm soát SLAT vẫn còn chờ.
3.3. Secure Kernel và IUM
Thứ chạy bên trong VTL1 không phải kernel NT thông thường mà là một kernel nhỏ gọi là Secure Kernel. Chế độ user trong VTL1 được gọi là IUM (Isolated User Mode), và các chương trình chạy ở đó được gọi là trustlet (tiến trình đáng tin).3
Một trustlet không thể làm mọi thứ như một tiến trình thông thường. Hầu hết lời gọi hệ thống được marshall sang kernel NT phía VTL0 và công việc được yêu cầu ở đó.3 VTL1 không phải “thế giới trên có thể làm mọi thứ”; nó được xây cố ý nhỏ, như một két giữ bí mật. Càng ít mã bạn đưa vào két, bề mặt tấn công càng nhỏ.
flowchart TB
accTitle: Luồng lời gọi hệ thống của một trustlet
accDescr: Một trustlet ở VTL1 không tự xử lý hầu hết lời gọi hệ thống; nó marshall chúng sang kernel NT VTL0 và chỉ nhận kết quả, điều giữ VTL1 nhỏ
tl["Trustlet(IUM ở VTL1)"] --> sc{"Cần một lời gọi hệ thống"}
sc -->|Hầu hết trường hợp| mar["Yêu cầu được marshall sang kernel NT VTL0"]
mar --> res["Chỉ kết quả trở về"]
res -.-> small["VTL1 giữ nhỏ, thu hẹp bề mặt tấn công"]
Hình 6: Cái két không có tiện nghi riêng; nó khoán việc vặt và chỉ tiếp tục canh các bí mật.
4. HVCI — Xác minh tính toàn vẹn mã kernel trong két
4.1. Thứ đang được xác minh
Tính năng đại diện đầu tiên ngồi trên VBS là Memory integrity — HVCI (hypervisor-protected code integrity). Windows có cơ chế tính toàn vẹn mã kiểm tra các driver và nhị phân chế độ kernel trước khi chúng khởi động và không nạp những cái không chữ ký hoặc không đáng tin. HVCI chạy xác minh này bên trong môi trường cô lập của VBS.1
Lý do chuyển chính logic xác minh vào VTL1 chính là điểm yếu ở Mục 2. Nếu mã xác minh ngồi bên trong kernel VTL0, kẻ tấn công đã chiếm kernel có thể đổi xác minh ra. Nếu nó ở VTL1, bàn tay đổi không với tới.
flowchart TB
accTitle: Khác biệt do chỗ mã xác minh sống
accDescr: Nếu mã xác minh ngồi bên trong kernel VTL0 nó có thể bị vô hiệu bằng cách chiếm kernel, nhưng nếu ở VTL1 thì ngay cả kẻ tấn công đã chiếm kernel cũng không với tới và xác minh được bảo vệ
atk["Kẻ tấn công đã chiếm kernel"] --> q{"Xác minh tính toàn vẹn mã sống ở đâu?"}
q -->|"Bên trong kernel VTL0(cổ điển)"| bad["Logic xác minh có thể bị đổi ra"]
q -->|"Môi trường cô lập ở VTL1(HVCI)"| good["Việc đổi nằm ngoài tầm với"]
bad --> res1["Mã không chữ ký có thể chạy trong kernel"]
good --> res2["Xác minh vẫn hoạt động sau khi kernel bị xâm phạm"]
Hình 7: Đừng đặt trạm kiểm soát bên trong phía có thể bị đột phá — việc dời logic xác minh đó là bản chất của HVCI.
4.2. Các quy tắc cho trang thực thi được
Hiệu quả của HVCI không chỉ giới hạn ở “kiểm tra lúc khởi động”. Nó cũng ràng buộc việc cấp phát bộ nhớ kernel.4
- Một trang kernel trở nên thực thi được chỉ sau khi đã vượt xác minh tính toàn vẹn mã.
- Một trang thực thi được không trở nên ghi được (cái gọi là W^X).
Khi hai điều này có mặt, dù một lỗ hổng như tràn bộ đệm cho phép bạn viết lại bộ nhớ kernel, bạn không thể đưa nội dung đã viết lại vào thực thi. Một trang thực thi được không thể viết lại, và một trang viết lại được không thể thực thi.4 Hậu thuẫn cuối cùng của quyền thực thi là quyền thực thi phía SLAT, thứ kernel VTL0 không thể thao tác.
flowchart TB
accTitle: Cho tới khi một trang kernel trở nên thực thi được trong môi trường HVCI
accDescr: Yêu cầu nạp driver nhận xác minh tính toàn vẹn mã trong môi trường cô lập của VBS; nếu vượt thì được phép như trang thực thi được, không ghi được, và nếu thất bại thì bị chặn và ghi vào nhật ký CodeIntegrity
load["Yêu cầu nạp và thực thi mã kernel"] --> verify{"Xác minh tính toàn vẹn mã trong môi trường cô lập"}
verify -->|Vượt| exec["Được phép như trang thực thi(cấm ghi)"]
verify -->|Thất bại| block["Việc nạp bị chặn"]
block --> log["Ghi vào nhật ký CodeIntegrity Operational(event ID 3087)"]
exec -.-> wx["Các trang ghi được vẫn không thực thi được"]
Hình 8: Việc xác minh quy tắc không để thực thi và ghi cùng tồn tại được làm phía VTL1, và kernel VTL0 không thể lật ngược.
Lần theo điều này từ góc nhìn kẻ tấn công làm rõ cách quy tắc có hiệu lực.
flowchart TB
accTitle: Luồng tiêm mã thất bại trong môi trường HVCI
accDescr: Dù một lỗ hổng cho phép bạn viết lại bộ nhớ kernel, một trang bạn viết được thì không thực thi được, và một trang thực thi được thì không thể viết lại ngay từ đầu, nên mã đã tiêm không thể được đưa vào thực thi
inj["Cố giả mạo bộ nhớ kernel qua lỗ hổng"] --> which{"Trang mục tiêu là trang nào?"}
which -->|Một trang ghi được| wok["Lần ghi thành công"]
which -->|Một trang thực thi được| xfail["Bản thân lần ghi là không thể"]
wok --> nx["Nhưng trang đó không thực thi được"]
nx --> dead["Mã đã tiêm không thể được thực thi"]
xfail --> dead
Hình 9: Ý nghĩa của việc không cho trang ghi được cắt với trang chạy được là dù bạn vào cửa nào, bạn cũng đụng ngõ cụt.
4.3. Cái giá ở tính tương thích driver
Quy tắc này va với các driver thiết kế cũ. Những cái viết lại mã của chính chúng lúc chạy, không có chữ ký, hoặc đòi bộ nhớ vừa thực thi được vừa ghi được — các driver như vậy không thể được nạp trong môi trường HVCI. Sự thật của việc chặn có thể xác nhận trong Event Viewer dưới Applications and Services Logs\Microsoft\Windows\CodeIntegrity\Operational (event ID 3087 là đại diện).5
“Sau khi tôi bật Memory integrity, một thiết bị ngoại vi ngừng hoạt động” — trong nhiều trường hợp, đó chính là danh tính thật của sự cố. Phản ứng đúng là cập nhật sang driver tương thích HVCI; tắt Memory integrity nên được nghĩ như biện pháp cuối cùng từ bỏ toàn bộ lớp bảo vệ. Nếu bạn tham gia xác minh này từ góc độ phát triển driver, xem thêm bài về filter driver (“Driver minifilter Windows”).
flowchart TB
accTitle: Tách trường hợp thiết bị ngoại vi ngừng hoạt động dưới Memory integrity
accDescr: Xác định driver bị chặn trong nhật ký CodeIntegrity Operational; phản ứng đúng là cập nhật sang phiên bản tương thích HVCI, hỏi nhà cung cấp nếu không có, và coi việc tắt là biện pháp cuối không biến thành thiết lập lâu dài
sym["Một thiết bị ngừng hoạt động sau khi bật Memory integrity"] --> log2["Xác định driver bị chặn trong nhật ký CodeIntegrity"]
log2 --> upd{"Có driver tương thích HVCI không?"}
upd -->|Có| fix2["Cập nhật và giải quyết trong khi giữ HVCI bật"]
upd -->|Không| ask2["Hỏi nhà cung cấp phiên bản tương thích"]
ask2 -.-> temp["Tắt là biện pháp cuối, không phải thiết lập lâu dài"]
Hình 10: Việc đầu tiên cần nhìn không phải màn hình cài đặt mà là nhật ký, và event ID 3087 biết ai đã chặn việc nạp.
5. Credential Guard — Các hash nằm trong LSAIso
5.1. LSASS và LSAIso
Tính năng đại diện thứ hai ngồi trên VBS là câu trả lời cho bí ẩn mở đầu: Credential Guard.
Windows truyền thống giữ hash NTLM và vé Kerberos trong bộ nhớ của tiến trình LSA (lsass.exe). Khi Credential Guard được bật, việc lưu các bí mật được bảo vệ trong số này — hash NTLM của thông tin xác thực miền và TGT Kerberos (Ticket Granting Ticket) — chuyển sang LSAIso.exe, một trustlet chạy ở IUM trong VTL1.6
- lsass.exe (VTL0) tiếp tục chạy như quầy lễ tân cho xử lý xác thực, như trước.
- Các bí mật thật do LSAIso.exe (VTL1) giữ và không thể truy cập từ VTL0.
- Hai bên giao tiếp qua RPC (Remote Procedure Call).
- LSAIso không chứa bất kỳ driver thiết bị nào, và chỉ chứa tối thiểu các nhị phân có chữ ký. Các chữ ký được xác minh bằng chứng chỉ mà VBS tin.6
flowchart TB
accTitle: Thông tin xác thực ngồi ở đâu khi Credential Guard được bật
accDescr: lsass ở VTL0 giao tiếp với LSAIso ở VTL1 qua RPC như quầy lễ tân xác thực; các hash và TGT thật của thông tin xác thực miền được bảo vệ do LSAIso giữ, nên kẻ tấn công có được đặc quyền quản trị ở VTL0 rồi dump lsass vẫn không lấy được thực chất được bảo vệ
subgraph v0 ["VTL0"]
lsassP["lsass.exe(quầy lễ tân xác thực)"]
att["Kẻ tấn công(đặc quyền quản trị)"]
end
subgraph v1 ["VTL1"]
iso["LSAIso.exe(két giữ bí mật)"]
end
lsassP <-->|RPC| iso
att -->|Dump bộ nhớ| lsassP
att -.->|Không với tới| iso
Hình 11: Vì quầy lễ tân và cái két được tách, dump lsass không còn cho ra các hash thật của thông tin xác thực miền được bảo vệ.
Từ Windows 11 phiên bản 22H2 trở đi, trên các thiết bị đáp ứng yêu cầu giấy phép (Enterprise E3/E5, Education A3/A5) và yêu cầu phần cứng, VBS và Credential Guard được bật mặc định. Trên các phiên bản như Pro, Credential Guard không được bật tự động (có ngoại lệ, chẳng hạn khi một máy từng được bật dưới giấy phép đủ điều kiện sau đó bị hạ cấp).7 “Kịch bản không còn hiệu lực” ở phần mở đầu không phải câu chuyện về một sản phẩm bổ trợ đặc biệt; đó là trạng thái chuẩn của Windows hiện tại trên các phiên bản mục tiêu.
flowchart TB
accTitle: Luồng thông tin xác thực từ đăng nhập tới xác thực
accDescr: Sau khi đăng nhập các bí mật thật được lưu trong LSAIso ở VTL1; mỗi lần cần xác thực, lsass ở VTL0 yêu cầu tính toán qua RPC, và chỉ kết quả xử lý xác thực trở về VTL0 mà bản thân các bí mật dài hạn được bảo vệ không được trả về
signin["Người dùng đăng nhập"] --> front["lsass xử lý như quầy lễ tân"]
front --> store["Các bí mật thật được lưu trong LSAIso"]
auth["Các yêu cầu xác thực sau"] --> front
front -->|"Yêu cầu tính toán qua RPC"| store
store -->|"Trả về kết quả(không trả về bí mật)"| front
Hình 12: Bản thân các bí mật dài hạn được bảo vệ không bao giờ rời két; thứ trở về VTL0 là kết quả xử lý xác thực, chẳng hạn một vé.
5.2. Biết chính xác những gì không được bảo vệ
Credential Guard không phải lá chắn vạn năng. Thứ được bảo vệ là hash NTLM của thông tin xác thực miền, TGT Kerberos (Ticket Granting Ticket), và những thứ được lưu như thông tin xác thực miền. Những thứ sau nằm ngoài phạm vi.8
- Vé dịch vụ Kerberos (TGT được bảo vệ)
- Thông tin xác thực của tài khoản cục bộ và tài khoản Microsoft
- Việc đánh cắp đầu vào bằng keylogger, và tấn công vật lý
- Thông tin xác thực trên các đường dùng NTLMv1, MS-CHAPv2, Digest hoặc CredSSP
- Phần bên trong của phần mềm bên thứ ba tự quản lý thông tin xác thực
Ngoài ra, khi Credential Guard được bật, NTLMv1, ủy quyền Kerberos không ràng buộc và tương tự trở nên không dùng được, nên các hệ thống nghiệp vụ phụ thuộc xác thực cũ cần kiểm tra tương thích.8 Không phải “bật xong là xong”, mà nắm những gì nằm trong và ngoài phạm vi phòng thủ rồi lấp phần còn lại bằng các kiểm soát khác — đó là cách dùng đúng trong thực tế.
flowchart TB
accTitle: Phạm vi phòng thủ của Credential Guard
accDescr: Hash NTLM miền và TGT, cùng thông tin xác thực miền đã lưu, được bảo vệ, trong khi vé dịch vụ, tài khoản cục bộ, keylogger, tấn công vật lý, và thông tin xác thực mà ứng dụng tự lưu nằm ngoài phạm vi
scope{"Bí mật này nằm phía nào của ranh giới bảo vệ?"} --> inA["Hash NTLM miền và TGT"]
scope --> outA["Vé dịch vụ và tài khoản cục bộ"]
inA --> prot["Được bảo vệ trong LSAIso"]
outA --> unprot["Không được bảo vệ(cần kiểm soát khác)"]
unprot -.-> outB["Phím bấm, tấn công vật lý, và kho riêng của ứng dụng cũng ngoài phạm vi"]
Hình 13: Phạm vi phòng thủ được vẽ bằng một đường rõ, và phía ngoài đường được lấp bằng xác thực đa yếu tố và thiết kế phía ứng dụng.
6. Tự xem trên máy của bạn
Bạn có thể xác nhận trạng thái chạy của VBS và từng tính năng trên máy mình.
Get-CimInstance -Namespace root/Microsoft/Windows/DeviceGuard `
-ClassName Win32_DeviceGuard |
Select-Object VirtualizationBasedSecurityStatus,
SecurityServicesConfigured,
SecurityServicesRunning
Cách đọc như sau.9
- Nếu
VirtualizationBasedSecurityStatuslà 2, VBS được bật và đang chạy. - Nếu
SecurityServicesRunningchứa 1, Credential Guard đang chạy; nếu chứa 2, Memory integrity (HVCI) đang chạy.
Để xác nhận trạng thái chạy trong GUI, nhìn trường “Virtualization-based security” trong msinfo32 (các dịch vụ đang chạy được liệt kê, chẳng hạn “Hypervisor enforced Code Integrity”). Công tắc “Memory integrity” dưới “Device security > Core isolation” trong ứng dụng Windows Security là màn hình phản ánh thiết lập; nó có thể trông như bật trong khi HVCI thực sự chưa chạy — đang chờ khởi động lại ngay sau khi bật, hoặc vấn đề tương thích lúc khởi động — nên hãy phán liệu nó có đang chạy từ msinfo32 hoặc từ SecurityServicesRunning của Win32_DeviceGuard.5
Cũng có một dấu vết trên tab Details của Task Manager. Trên máy VBS đang chạy bạn sẽ thấy một tiến trình gọi là “Secure System”. LsaIso.exe là tiến trình xuất hiện khi dịch vụ Isolated LSA được đặt trong VTL1, và nó thường không xuất hiện ở cấu hình chỉ bật HVCI. Tuy nhiên sự có mặt hay vắng mặt của một tiến trình chỉ là dấu vết, nên hãy phán liệu Credential Guard có đang chạy từ SecurityServicesRunning (nó có chứa 1 không), như trên. Cả hai đều là cửa sổ nhìn thấy từ VTL0 tương ứng với thế giới phía VTL1.
flowchart TB
accTitle: Cách kiểm tra các tính năng liên quan VBS đang chạy
accDescr: Xác nhận VBS đang chạy bằng cách truy vấn Win32_DeviceGuard, phán Credential Guard và HVCI từ các giá trị SecurityServicesRunning, và nhìn nhật ký CodeIntegrity khi có vấn đề driver
q0["Win32_DeviceGuard"] --> q1{"VBS Status 2?"}
q1 -->|Không| off["VBS không chạy"]
q1 -->|Có| q2{"Chứa 1 hay 2?"}
q2 -->|1| cg["Credential Guard bật"]
q2 -->|2| hvciR["HVCI bật"]
hvciR -.-> ev["CodeIntegrity 3087"]
Hình 14: Xác nhận trạng thái tiến hành theo ba giai đoạn: bản thân VBS, từng dịch vụ trên đó, và nhật ký khi có vấn đề.
7. Ba cách đọc sai cần tránh trong thực tế
7.1. “Bảo vệ đặc quyền quản trị là đủ. VBS là chuyện phía máy chủ”
Thứ Credential Guard ngăn là thiệt hại lan sau khi đặc quyền quản trị đã bị chiếm (rút hash và di chuyển ngang). Nói cách khác VBS là một lớp phòng thủ theo chiều sâu giả định xâm phạm, và chính trên PC client nó có hiệu quả. Trên Windows 11 đáp ứng yêu cầu, bật-mặc-định là chuẩn, nên tư thế đúng không phải “chuyện này chẳng liên quan tới chúng tôi” mà là “quản lý tính tương thích với giả định nó đã đang chạy”.
flowchart TB
accTitle: Các giai đoạn xâm phạm và chỗ VBS có hiệu lực
accDescr: Truy cập ban đầu được các kiểm soát khác như xác thực đa yếu tố và đào tạo bao phủ; HVCI chặn tiêm mã vào kernel sau leo thang đặc quyền; Credential Guard chặn đánh cắp bí mật miền được bảo vệ và di chuyển ngang, nhưng không với tới các bí mật ngoài phạm vi
s1["Truy cập ban đầu(lừa đảo và tương tự)"] --> s2["Leo thang đặc quyền"]
s2 --> s3["Tiêm mã vào kernel"]
s3 --> s4["Đánh cắp bí mật miền được bảo vệ và di chuyển ngang"]
s1 -.-> d1["MFA, đào tạo và EDR bao phủ chỗ này"]
s3 -.-> d2["HVCI chặn bước này"]
s4 -.-> d3["Credential Guard chặn chỗ này(chỉ bí mật được bảo vệ)"]
Hình 15: VBS không phải công nghệ “đừng để chúng vào”; đó là công nghệ “đừng để chúng thắng sau khi đã vào”, và giai đoạn nó canh khác.
7.2. “Nếu Memory integrity gây vấn đề, cứ tắt đi”
Tắt sẽ làm mọi thứ chạy được tạm thời, nhưng nó hạ toàn bộ rào chắn chống tiêm mã vào kernel. Phản ứng đúng là trước hết xác định driver bị chặn trong nhật ký CodeIntegrity rồi áp dụng phiên bản cập nhật của nhà cung cấp. Dù bạn tắt tạm thời để xác thực, chúng tôi khuyến nghị một cách vận hành không biến điều đó thành thiết lập lâu dài.
7.3. “Có Credential Guard thì mật khẩu không thể bị đánh cắp”
Đó là sự tự tin thái quá từ việc nhầm phạm vi phòng thủ. Vé dịch vụ, tài khoản cục bộ, bản thân các phím bấm, và thông tin xác thực mà ứng dụng tự lưu nằm ngoài phạm vi.8 Lừa đảo và keylogger cần các kiểm soát khác (xác thực đa yếu tố, Windows Hello, và rà soát quản lý thông tin xác thực phía ứng dụng).
8. Tóm tắt
- VBS dùng hypervisor để tạo môi trường cô lập và bảo vệ các tính năng bảo mật với giả định kernel có thể bị xâm phạm.1
- Đơn vị cô lập là VTL; hiện hai mức được triển khai, VTL0 (thế giới thông thường) và VTL1 (Secure Kernel và IUM).2
- Thực chất của ranh giới là bảo vệ truy cập bộ nhớ SLAT, thứ phần mềm bên trong phân vùng — kể cả kernel — không thể thay đổi.2
- HVCI chạy xác minh tính toàn vẹn mã trong môi trường cô lập và thực thi “không thực thi được cho tới khi xác minh vượt” cùng “một trang thực thi được thì không ghi được”.4 Cái giá là bạn phải quản lý tính tương thích driver.5
- Credential Guard cô lập hash NTLM của thông tin xác thực miền và TGT vào LSAIso ở VTL1. Từ Windows 11 22H2 trở đi nó được bật mặc định trên các thiết bị đáp ứng yêu cầu giấy phép (Enterprise, Education) và yêu cầu phần cứng (hãy dùng điều này cùng một lần kiểm tra trạng thái chạy).67
- Bạn có thể xác nhận trạng thái chạy từ SecurityServicesRunning của
Win32_DeviceGuard(1 = Credential Guard, 2 = HVCI).9
Tiếp theo ở Phần 3, “Máy ảo khởi động trong vài giây — WSL2, Windows Sandbox và container“.
Đến đây chúng ta đã nhìn ảo hóa từ phía “độ mạnh của cô lập”. Kỳ cuối nhìn từ phía ngược lại, “độ nhẹ”, và lần theo chỗ các VM nhẹ đã bỏ đi sức nặng của một VM đầy đủ đang cắt góc.
Bài viết liên quan
- Bên trong ảo hóa Windows (Phần 1) — Windows của bạn thực sự chạy ở đâu? Hypervisor và phân vùng
- Chiều sâu bộ nhớ Windows (Phần 1) — Khoảnh khắc một địa chỉ ảo trở thành RAM vật lý: Page fault từ đầu tới cuối
- Chiều sâu I/O của Windows (Phần 6, cuối) — Filter driver và minifilter: Vì sao Procmon và trình quét diệt virus có thể chặn I/O
- Giải mã mã lỗi Windows — Cấu trúc ba lớp của lỗi Win32, HRESULT và NTSTATUS
Lĩnh vực tư vấn liên quan
KomuraSoft LLC đảm nhận điều tra tính tương thích giữa ứng dụng Windows và các tính năng bảo mật, phân tích sự cố do driver, và xác thực kỹ thuật môi trường PC nội bộ.
- Phát triển ứng dụng Windows
- Điều tra lỗi và phân tích nguyên nhân gốc rễ
- Tái sử dụng và di chuyển tài sản hiện có
- Liên hệ với chúng tôi
Liên kết tham khảo
-
Microsoft Learn, Virtualization-based Security (VBS). Về việc VBS dùng ảo hóa phần cứng và hypervisor Windows để tạo môi trường cô lập và coi đó là gốc tin cậy của hệ điều hành với giả định kernel có thể bị xâm phạm; Memory integrity chạy xác minh tính toàn vẹn mã chế độ kernel bên trong môi trường cô lập đó; và SLAT là yêu cầu cứng cho VBS. ↩ ↩2 ↩3
-
Microsoft Learn, Virtual Secure Mode. Về việc VSM là nền tảng cho Device Guard, Credential Guard, TPM ảo và tương tự; truy cập tới vùng cô lập chỉ được kiểm soát qua hypervisor và được bảo vệ ngay cả trước phần mềm hệ điều hành ring-0; VTL có thứ bậc với 2 trong tối đa 16 mức được triển khai; và các bảo vệ truy cập bộ nhớ theo từng VTL không thể bị phần mềm hệ thống bên trong phân vùng thay đổi. ↩ ↩2 ↩3 ↩4 ↩5
-
Microsoft Learn, Isolated User Mode (IUM) Processes. Về việc VSM tạo VTL bằng hypervisor Hyper-V và SLAT; Secure Kernel và IUM chạy ở VTL1; trustlet marshall lời gọi hệ thống sang kernel VTL0; và LSAIso chạy ở VTL1 rồi giao tiếp với lsass qua RPC. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and virtualization-based security. Về việc Memory integrity (HVCI) chạy xác minh tính toàn vẹn mã trong môi trường cô lập, và về việc các trang bộ nhớ kernel chỉ trở nên thực thi được sau khi vượt xác minh và các trang thực thi được không trở nên ghi được. ↩ ↩2 ↩3
-
Microsoft Learn, Memory integrity and VBS enablement. Về việc Memory integrity được bật mặc định khi cài sạch Windows 11 nếu phần cứng tương thích; xác nhận trạng thái trong msinfo32 và ứng dụng Windows Security; và xác nhận driver bị chặn qua event ID 3087 trong nhật ký CodeIntegrity Operational. ↩ ↩2 ↩3
-
Microsoft Learn, How Credential Guard works. Về việc LSA giao tiếp với tiến trình Isolated LSA (LSAIso.exe) để lưu bí mật khi Credential Guard được bật; dữ liệu đã lưu được VBS bảo vệ và không truy cập được từ phần còn lại của hệ điều hành; và tiến trình Isolated LSA không chứa driver thiết bị nào và chỉ chứa tối thiểu các nhị phân đã xác minh chữ ký. ↩ ↩2 ↩3
-
Microsoft Learn, Credential Guard overview. Về việc Credential Guard được bật mặc định từ Windows 11 phiên bản 22H2 trở đi trên các thiết bị đáp ứng yêu cầu giấy phép, phần cứng và phần mềm và chưa bị tắt tường minh; các phiên bản/giấy phép đủ điều kiện là Enterprise (E3/E5) và Education (A3/A5), với Pro nằm ngoài phạm vi; và một máy Pro từng được bật dưới giấy phép đủ điều kiện vẫn là mục tiêu bật mặc định sau khi hạ cấp. ↩ ↩2
-
Microsoft Learn, Credential Guard protection limits. Về việc vé dịch vụ, tài khoản cục bộ, keylogger, tấn công vật lý và tương tự nằm ngoài phạm vi bảo vệ của Credential Guard; TGT được bảo vệ trong khi vé dịch vụ thì không; và NTLMv1 cùng ủy quyền không ràng buộc trở nên không dùng được khi nó được bật. ↩ ↩2 ↩3
-
Microsoft Learn, Enable virtualization-based protection of code integrity. Về cách xác nhận trạng thái của VBS và Memory integrity qua lớp Win32_DeviceGuard, và về ý nghĩa các giá trị SecurityServicesRunning (1 là Credential Guard, 2 là Memory integrity). ↩ ↩2
Bài viết liên quan
Các bài viết gần đây có cùng thẻ để tìm hiểu sâu hơn những chủ đề lân cận.
Bên trong ảo hóa Windows (Phần 3) — Máy ảo khởi động trong vài giây: Vì sao WSL2, Windows Sandbox và container lại nhẹ
Vì sao WSL2 và Windows Sandbox khởi động trong vài giây và cảm giác nhẹ đến vậy? Bài viết này giải thích các cơ chế, từ ảnh cơ sở động và...
Bên trong ảo hóa Windows (Phần 1) — Windows của bạn thực sự chạy ở đâu? Hypervisor và phân vùng
Khi bạn bật Hyper-V, chính Windows máy chủ chạy trên hypervisor như phân vùng gốc. Bài viết này giải thích nền tảng ảo hóa qua vai trò củ...
Named pipe trong thực tiễn — IPC chuẩn của Windows, từ thiết kế đến bảo mật
Hướng dẫn thực tiễn về named pipe, cơ chế giao tiếp giữa các tiến trình chuẩn của Windows. Bài viết sắp xếp, từ nguồn gốc, việc chọn giữa...
API thread pool Win32 — Đồng thời mà không tạo luồng, với CreateThreadpoolWork
Bạn đang rải các lời gọi CreateThread khắp mã native? Bài viết này giải thích API thread pool Win32 được thiết kế lại từ Vista — bốn đối ...
Giúp website xuất hiện khi khách tìm theo tên khu vực — Hướng dẫn Local SEO thực tiễn cho doanh nghiệp vừa và nhỏ (trang khu vực và Google Business Profile)
Dành cho các doanh nghiệp vừa và nhỏ có website không xuất hiện khi ai đó tìm kiếm "tên khu vực + ngành nghề". Bài viết này trình bày thứ...
Chủ đề liên quan
Các trang này đặt chủ đề trong bối cảnh rộng hơn của dịch vụ và quyết định.
Chủ đề kỹ thuật Windows
Cổng vào phát triển Windows, điều tra lỗi và khai thác tài sản hiện có.
Dịch vụ liên quan đến chủ đề này
Bài viết liên quan trực tiếp đến các dịch vụ sau.
Phát triển ứng dụng Windows
Ứng dụng nghiệp vụ, tích hợp thiết bị và công cụ liên lạc, từ yêu cầu đến phát triển.
Câu hỏi thường gặp
Các câu hỏi thường gặp khi tư vấn về chủ đề của bài viết.
- VBS (bảo mật dựa trên ảo hóa) và Core isolation có phải cùng một thứ không?
- Nói chặt thì chúng khác nhau. VBS là công nghệ nền tảng tạo môi trường cô lập bằng hypervisor, còn "Core isolation" trong ứng dụng Windows Security là tên một màn hình gom vài lớp bảo vệ xây trên VBS. Đại diện là "Memory integrity", chỉ HVCI (hypervisor-protected code integrity). Hãy xác nhận trạng thái chạy của từng dịch vụ bằng cách truy vấn Win32_DeviceGuard, không từ hiển thị trên màn hình.
- Bộ nhớ VTL1 thật sự không đọc được, ngay cả với đặc quyền quản trị hoặc từ driver kernel?
- Không đọc được. Các bảo vệ truy cập bộ nhớ theo từng VTL được hypervisor quản lý đối với không gian địa chỉ vật lý của phân vùng, và phần mềm chạy bên trong phân vùng không thể thay đổi chúng. Ngay cả mã chạy trong kernel (ring 0) cũng không được phép truy cập bộ nhớ VTL1 từ VTL0.
- Vì sao bật Memory integrity (HVCI) có thể làm một driver ngừng hoạt động?
- Trong môi trường HVCI, một trang kernel chỉ trở nên thực thi được sau khi đã vượt xác minh tính toàn vẹn, và việc ghi vào các trang thực thi được không được phép. Một driver không chữ ký, hoặc driver thiết kế cũ viết lại bộ nhớ thực thi được, không thỏa ràng buộc này và việc nạp bị chặn. Bạn có thể xác nhận việc chặn trong nhật ký CodeIntegrity Operational (event ID 3087 và tương tự).
- Credential Guard bảo vệ gì, và không bảo vệ gì?
- Nó bảo vệ hash mật khẩu NTLM của thông tin xác thực miền, TGT Kerberos, và những thứ một ứng dụng đã lưu như thông tin xác thực miền, trong một môi trường cô lập. Vé dịch vụ Kerberos, thông tin xác thực của tài khoản cục bộ và tài khoản Microsoft, việc đánh cắp đầu vào bằng keylogger, và tấn công vật lý nằm ngoài phạm vi.
- Tôi có thể kiểm tra VBS đang chạy ở đâu?
- Nhìn trường "Virtualization-based security" trong msinfo32, hoặc truy vấn lớp Win32_DeviceGuard trong không gian tên root/Microsoft/Windows/DeviceGuard từ PowerShell. Nếu SecurityServicesRunning chứa 1, Credential Guard đang chạy; nếu chứa 2, Memory integrity (HVCI) đang chạy.