Hiểu sâu về Metldown attack và cách bảo vệ máy tính của bạn khỏi Meltdown attack?
Chỉ trong những ngày đầu tiên của năm 2018, giới bảo mật cũng như toàn thể người dùng trên thế giới đã bị “sốc” nặng trước 2 lỗ hổng bảo mật hết sức nguy hiểm mới được công bố mang tên: Meltdown và Spectre. Hai lỗ hổng bảo mật này nguy hiểm bởi chúng rất khó phát hiện ...
Chỉ trong những ngày đầu tiên của năm 2018, giới bảo mật cũng như toàn thể người dùng trên thế giới đã bị “sốc” nặng trước 2 lỗ hổng bảo mật hết sức nguy hiểm mới được công bố mang tên: Meltdown và Spectre. Hai lỗ hổng bảo mật này nguy hiểm bởi chúng rất khó phát hiện và quan trọng hơn là nó ảnh hưởng đến tất cả các thiết bị điện tử sử dụng chip xử lí Intel được sản xuất từ năm 1995 đến nay.
Vậy 2 lỗ hổng này hoạt động như nào? Các thiết bị nào chịu ảnh hưởng? Chúng ảnh hưởng tới ngưởi sử dụng như thế nào? Và cách để người dùng có thể bảo vệ thiết bị của mình? Trong bài viết này, SecurityBox sẽ cố gắng diễn giải một cách dễ hiểu, khái quát nhất về lỗ hổng Meltdown giúp để người dùng có thể nhận thức được rõ ràng về lỗ hổng này. Về lỗ hổng Spectre, chúng tôi sẽ thông tin tới bạn đọc trong một bài viết khác.
Bạn có biết Lỗ hổng trong hàng trăm dịch vụ theo dõi vị trí GPS có thể bị Hacker lợi dụng
Một số cơ chế tăng hiệu năng của các vi xử lí hiện đại
Đầu tiên, để hiểu được về lỗ hổng Meltdown, chúng ta cần biết một chút về kiến trúc của các vi xử lí hiện đại, cách các vi xử lí hoạt động để thực thi các chương trình.
Pipeline
Chúng ta cùng giả sử một chương trình thực thi các câu lệnh có dạng như sau:
Một cách logic, chúng ta tin rằng các câu lệnh trên sẽ được thực hiện tuần tự từ phép tính 1, phép tính 2, đến phép tính 3 rồi tới phép tính 4, sau đó sẽ cho ra một kết quả nào đó mà chúng ta mong đợi. Tuy nhiên, đó không phải cách mà các vi xử lí hiện đại hoạt động, để tăng hiệu năng tính toán thì các phép tính sẽ không hoạt động một cách tuần tự như vậy. Thay vào đó, chúng sẽ được tối ưu hóa, chia thành các khối nhỏ thực hiện song song để có thể tận dụng tối đa các tài nguyên của vi xử lí và thực thi nhiều lệnh cùng một lúc. Kĩ thuật này gọi là kỹ thuật đường ống (pipeline). Cách thức hoạt động của nó có dạng như sau:
Nhờ có kĩ thuật này mà vi xử lí có thể tận dụng các tài nguyên đang rảnh rỗi của mình để phục vụ cho các lệnh tiếp theo, thay vì phải đợi tới khi lệnh hiện tại hoàn toàn kết thúc. Nhờ đó hiệu năng của vi xử lí được tăng lên đáng kể.
Xem thêm: Những xu hướng tấn công mạng được dự báo năm 2018
Branch Predictor
Kĩ thuật Pipeline tương đối dễ hiểu và dễ thực hiện trong trường hợp các phép tính được lập trình một cách tuần tự. Vấn đề trở nên phức tạp hơn khi xét tới các chương trình có sử dụng các lệnh điều kiện/lệnh rẽ nhánh, tức là khi việc thực thi các câu lệnh sau phụ thuộc vào kết quả của câu lệnh trước. Cùng xét tới chương trình sau:
Trong chương trình này, nếu thực hiện một cách tuần tự, thì các câu lệnh 1, 2 sẽ chỉ được thực hiện nếu giá trị của biến a thỏa mãn điều kiện của biểu thức x, tức là chương trình sẽ phải đợi kết quả của phép so sánh điều kiện trước khi thực hiện bất kì thao tác xử lí nào tiếp theo. Sẽ ra sao nếu biểu thức x cũng như các câu lệnh bên trong đều yêu cầu nhiều thời gian để xử lí? Chúng ta sẽ phải chờ rất lâu, trong khi nhiều tài nguyên của vi xử lí thì lại rảnh rỗi.
Vậy các bộ vi xử lí tối ưu cho những trường hợp này như thế nào? Đơn giản là đoán. Các vi xử lí sẽ có các khối dự đoán rẽ nhánh (branch-predictor) để dự đoán xem một điều kiện sẽ có kết quả True hay False, từ đó tính toán trước các khối lệnh tương ứng với trường hợp đó. Nếu đoán đúng, thì tốc độ xử lí chương trình sẽ nhanh hơn rất nhiều so với việc ngồi đợi mà không làm gì cả. Còn nếu đoán sai? Cũng không sao cả. Các kết quả tính toán “thừa” sẽ bị bỏ đi, cũng không khác gì việc vi xử lí ngồi đợi kết quả mà không làm gì. Các khối dự đoán rẽ nhánh có khả năng “học” từ kết quả của các lệnh rẽ nhánh trước đó, để giúp cho việc dự đoán có độ chính xác cao hơn, giúp hiệu năng của vi xử lí tốt hơn.
Nếu bạn đang có định theo Pentest hoặc muốn đánh giá an ninh cho hệ thống thì có thể tìm hiểu thêm tại bài viết: “Checklist Pentest hệ thống mạng” và “Checklist Pentest ứng dụng web“.
Cache
Cache là một vùng nhớ đặc biệt tốc độ cao nằm rất gần với lõi của vi xử lí. Cache được thiết kế để chứa các dữ liệu thường được sử dụng, hoặc có khả năng sắp được sử dụng để khi chương trình cần tới thì có thể đọc ngay ra, giảm thời gian đọc dữ liệu do việc truy cập vào các vùng nhớ trên RAM, ổ cứng để đọc dữ liệu sẽ tốn rất nhiều thời gian.
Ví dụ đoạn code nhỏ sau
Giả sử thời gian truy cập vào vùng nhớ chứa mảng mem mất khoảng 100ns. Nếu không có cache thì sẽ mất 200ns để thực hiện cả 2 lệnh đọc dữ liệu, bởi mỗi câu lệnh, bộ xử lí lại phải truy cập lại vào bộ nhớ để dọc dữ liệu ra. Khi có cache, thay vì chỉ đọc dúng giá trị mem[0], thì một khối bộ nhớ, ví dụ là 32 phần tử của mem, từ mem[0] tới mem[31] sẽ được nạp vào vùng nhớ cache. Lúc này, câu lệnh tiếp theo sẽ chỉ mất 1 khoảng thời gian rất ngắn, giả sử chỉ 1s để đọc dữ liệu vì dữ liệu đã được nạp sẵn trong bộ nhớ tốc độ cao cache thay vì phải thực hiện truy cập vào vùng nhớ ban đầu.
Tóm lại, vi xử lí hiện đại áp dụng nhiều phương pháp khác nhau để đẩy hiệu năng xử lí lên mức cao nhất. Trong đó có ba phương pháp liên quan tới lỗ hổng Meltdown
– Pipeline: thực hiện song song nhiều câu lệnh
– Branch Predictor: dự đoán trước kết quả các lệnh điều kiện
– Cache: nạp sẵn vào bộ nhớ tốc độ cao các dữ liệu có khả năng sắp được sử dụng
Lỗ hổng Meltdown
Sau khi đã hiểu một số cơ chế tăng hiệu năng vi xử lí của các bộ vi xử lí hiện đại, chúng ta cùng xem lỗ hổng Meltdown xảy ra như thế nào. Xét ví dụ sau:
Chương trình này thực hiện công việc như sau:
- Khởi tạo giá trị cho biến a
- So sánh biến a với biểu thức x
- Nếu phép so sánh cho kết quả đúng thì thực hiện khối lệnh bên trong
- Đọc nội dung bộ nhớ ở địa chỉ vùng 1, lưu giá trị đọc được vào biến b
- Đọc nội dung bộ nhớ ở địa chỉ có giá trị là b và lưu vào biến c
- …
- Kết thúc
Như đã giải thích ở trên, trong chương trình này, bộ vi xử lí sẽ tìm cách dự đoán kết quả của phép so sánh và chuyện gì xảy ra nếu nó dự đoán biểu thức này là đúng? Lệnh đọc bộ nhớ sẽ được thực thi. Nhưng vấn đề ở đây là: Nếu vùng nhớ đó không hợp lệ thì sao? Giả sử nó là một vùng nhớ không tồn tại, hoặc tệ hơn, là một vùng nhớ mà chương trình không được phép truy cập thì sao?
Với các vi xử lí Intel, nếu chương trình muốn truy cập vào một vùng nhớ tồn tại, nhưng không có đủ quyền hạn truy cập, thì vi xử lí sẽ đưa vào hàng đợi một cờ báo lỗi để thông báo tới chương trình, nhưng trong khi chờ cờ báo lỗi được đưa ra thì câu lệnh đọc bộ nhớ vẫn sẽ được thực thi. Chỉ khi nào cờ báo lỗi được xử lí, thì các kết quả của lệnh đọc bộ nhớ trước đó mới bị hủy bỏ, các thanh ghi trở lại giá trị trước khi thực thi lệnh đọc bộ nhớ. Nếu chương trình hoạt động tuần tự bình thường thì sẽ không có vấn đề gì xảy ra cả, các dữ liệu vượt quyền sẽ không bao giờ có thể hiển thị lên dù chúng thực sự đã được đọc ra, vì chương trình sẽ báo lỗi và kết quả thu được sẽ bị xóa ngay lập tức.
Quay lại với ví dụ của chúng ta, khi vi xử lí dự đoán kết quả của biểu thức so sánh là đúng và thực thi lệnh đọc bộ nhớ với địa chỉ là một vùng nhớ mà chương trình không được phép truy cập. Bạn nghĩ kết quả sẽ là chương trình bị báo lỗi và kết thúc ngay? Nhưng không, vì việc đọc bộ nhớ này chỉ là dự đoán, nếu kết quả của biểu thức so sánh ở trên là sai thì sẽ thật vô lí nếu đưa ra một thông báo lỗi cho một khối lệnh đáng lẽ không được thực thi. Thông báo lỗi sẽ không được đưa ra ngay lập tức, mà sẽ phải đợi tới khi có kết quả của phép so sánh ở trên. Trong khi chờ kết quả của phép so sánh thì các lệnh theo sau lệnh đọc bộ nhớ có thể được thực thi và các lệnh đó sử dụng nội dung dữ liệu ở trên, những dữ liệu truy cập trái phép, điều đáng ra không được phép. Và đây chính là lỗ hổng Meltdown.
Khai thác lỗ hổng Meltdown
Việc khai thác lỗ hổng Meltdown thực ra rất phức tạp, nhưng về cơ bản ta có thể tóm gọn nó thành 3 bước:
- Huấn luyện bộ dự đoán rẽ nhánh để đảm bảo chúng sẽ đưa ra kết quả dự đoán sai
- Sắp xếp một câu lệnh điều kiện sẽ bị dự đoán sai, với các khối lệnh bên trong truy cập vào các vùng nhớ hạn chế
- Xử lí nội dung thu được để có thể truy ngược được chúng một cách gián tiếp, bởi các nội dung đọc được sẽ bị xóa ngay khi bộ xử lí phát hiện kết quả dự đoán là sai
Chúng ta sẽ dùng tiếp ví dụ ở trên để minh họa cho bước 3.
Sau khi thực hiện dòng lệnh số 4, biến b lúc này chứa một nội dung bí mật thuộc vùng nhớ hạn chế. Cái ta cần chính là làm sao để có thể biết được giá trị của b sau khi bộ xử lí phát hiện ra mình đã dự đoán sai và xóa hết các kết quả liên quan.
Phương pháp được sử dụng ở đây là lợi dụng khả năng cache của vi xử lí.
Ở dòng lệnh thứ 5, giá trị b được sử dụng làm địa chỉ để đọc dữ liệu ra. Mà theo cơ chế cache của vi xử lí, nó sẽ đọc ra không chỉ giá trị của vùng nhớ được yêu cầu, mà sẽ đọc cả một khối vùng nhớ xung quanh vùng nhớ đó. Nếu như ta thực hiện xóa sạch vùng nhớ cache trước khi thực hiện đoạn code trên, và không thực hiện lệnh đọc vùng nhớ nào khác, thì ta có thể đảm bảo dữ liệu duy nhất tồn tại trong cache lúc này là vùng nhớ có địa chỉ là b. Sau khi vi xử lí phát hiện ra dự đoán của nó là sai và thực hiện toàn tác tất cả, thì dữ liệu trong cache vẫn còn đó. Lúc này, ta thực hiện một chuỗi các lệnh truy cập bộ nhớ, đồng thời đo thời gian thực hiện các lệnh truy cập bộ nhớ đó. Dựa vào thời gian thực hiện, ta có thể biết được vùng nhớ nào đã được lưu trong cache. Từ địa chỉ vùng nhớ được cache đó, ta sẽ suy ra được giá trị của b. Và b chính là giá trị bí mật được lưu trong vùng nhớ hạn chế. Lặp lại quá trình này nhiều lần, ta có thể vượt quyền, truy cập trái phép nội dung vào các vùng nhớ hạn chế.
Người dùng bị ảnh hưởng thế nào từ lỗ hổng Meltdown? Phải làm gì để bảo vệ máy tính của mình trước các nguy cơ tấn công?
Nếu bạn là người dùng bình thường, tức là chỉ dùng máy tính vào những tác vụ nhẹ nhàng như xem phim, đọc báo, check mail, soạn thảo văn bản,… thì thực ra bạn sẽ không bị ảnh hưởng gì nhiều. Các bản vá sẽ nhanh chóng được các nhà cung cấp như Microsoft, Apple, Google,… gửi tới người dùng. Người dùng chỉ cần cài đặt các bản vá và hệ thống của họ sẽ an toàn. Tuy nhiên, như đã phân tích ở trên, lỗ hổng Meltdown lợi dụng các cơ chế tăng hiệu năng của vi xử lí, nên để vá lỗi này, chắc chắn hiệu năng của các máy tính sẽ bị giảm ít nhiều, nhưng đổi lại, là sự an toàn.
Trong khi đó, những đối tượng cần đặc biệt lưu ý trong việc cài đặt các bản vá liên quan tới lỗ hổng Meltdown là những nhà cung cấp các dịch vụ cloud, ảo hóa, cũng như những người sử dụng các dịch vụ này. Bởi lỗ hổng này có thể hỗ trợ hacker từ một máy ảo, truy cập vượt quyền vào máy chủ cũng như các máy ảo khác.
XEM THÊM: Chuyên đề phân tích mã độc của chuyên gia Ngô Cao Đại TẠI ĐÂY