Lỗ hổng sử dụng sau khi miễn phí (UAF) là gì?
Use-after-free (UAF) là một lỗ hổng tham nhũng bộ nhớ nguyên thủy tiếp tục gây ra mối đe dọa đáng kể cho tất cả các loại phần mềm từ hệ điều hành đến phần mềm ứng dụng. Lỗ hổng bảo mật nghiêm trọng này xảy ra khi một thành phần ứng dụng cố gắng truy cập dữ liệu trong một địa chỉ bộ nhớ đã được giải phóng, do đó có tên là – use-after-free.
Các lỗ hổng UAF có thể dẫn đến nguy cơ khai thác phần mềm hoặc thậm chí xâm phạm hệ thống. Đây là lỗ hổng UAF là gì, tại sao nó xảy ra và cách bạn có thể bảo mật phần mềm của mình khỏi lỗ hổng UAF.
Mục Lục
Lỗ hổng sử dụng sau khi miễn phí (UAF) là gì?
Trước khi đi sâu vào lỗ hổng Use-after-free, chúng ta hãy lùi lại một bước và hiểu một số điều cơ bản về quản lý bộ nhớ. Khi một chương trình được thực thi, dữ liệu và mã của nó được nạp vào bộ nhớ.
Quản lý bộ nhớ là quá trình quản lý cách lưu trữ (gọi là cấp phát bộ nhớ) và xóa (gọi là cấp phát bộ nhớ) dữ liệu và mã trong bộ nhớ theo cách tối ưu. Hai phân đoạn bộ nhớ chính nơi dữ liệu chương trình được lưu trữ là ngăn xếp và đống.
Các chương trình có thể được cấp phát không gian bộ nhớ tĩnh trên ngăn xếp và động trên heap. Lỗ hổng sử dụng sau khi miễn phí xảy ra khi các lập trình viên không quản lý cấp phát và hủy cấp phát bộ nhớ động đúng cách trong các chương trình của họ. Điều này có nghĩa là lớp lỗ hổng UAF là một kiểu khai thác đống. Để hiểu lỗ hổng này tốt hơn, cần hiểu rõ hơn về cách hoạt động của con trỏ trong lập trình.
Use-after-free (UAF) như tên cho thấy, là một loại lỗ hổng tham nhũng bộ nhớ nguyên thủy xảy ra khi một đối tượng đã được giải phóng khỏi bộ nhớ được truy cập lại dẫn đến sự cố hoặc hậu quả không mong muốn như rò rỉ bộ nhớ, leo thang đặc quyền (EOP) hoặc thực thi mã tùy ý. Đầu tiên chúng ta hãy tìm hiểu xem điều kiện này xảy ra như thế nào và nó được khai thác như thế nào.
Sử dụng sau khi miễn phí (UAF) được khai thác như thế nào?
Use-after-free (UAF), như tên gợi ý, là một lỗ hổng hỏng hóc bộ nhớ nguyên thủy xảy ra khi một chương trình tiếp tục truy cập các vị trí bộ nhớ mà nó đã giải phóng. Hãy xem một mã ví dụ:
#include <stdio.h>
#include <stdlib.h>int main() {
int *MUO = malloc(sizeof(int));
*MUO = 69420;
printf("Value: %dn", *MUO);
free(MUO);
printf("Value?: %dn", *MUO);
return 0;
}
Có thể phát hiện lỗ hổng? Như bạn có thể thấy, trong mã này, MUỘN con trỏ được giải phóng khỏi bộ nhớ bằng cách sử dụng miễn phí() chức năng, nhưng nó được gọi lại trong dòng tiếp theo bằng cách sử dụng printf() chức năng. Điều này dẫn đến hành vi không mong muốn của chương trình và tùy thuộc vào vị trí lỗ hổng bảo mật xuất hiện trong phần mềm, lỗ hổng này có thể được tận dụng để leo thang đặc quyền và rò rỉ bộ nhớ.
Làm thế nào để giảm thiểu việc sử dụng sau khi miễn phí?
UAF xảy ra do lỗi lập trình ứng dụng. Có một vài biện pháp phòng ngừa mà bạn có thể thực hiện để tránh các lỗ hổng Sử dụng Sau khi Miễn phí trong phần mềm của mình.
Dưới đây là một số phương pháp hay nhất mà bạn có thể áp dụng để giảm thiểu lỗ hổng hỏng hóc bộ nhớ trong phần mềm của mình:
- Sử dụng các ngôn ngữ lập trình an toàn cho bộ nhớ như Rust với các cơ chế tích hợp để ngăn chặn các lỗ hổng làm hỏng bộ nhớ nguyên thủy như UAF, Tràn bộ đệm, v.v. Nếu bạn sử dụng các ngôn ngữ lập trình như C/C++, bạn có nhiều khả năng đưa ra các lỗi bộ nhớ trong mã của mình. Vì lý do tương tự, ngay cả các hệ điều hành như Windows và Linux cũng đang dần chuyển sang Rust. Bạn cũng nên xem xét việc học về Rust nếu bạn tạo các chương trình cấp thấp.
- Bên cạnh việc sử dụng ngôn ngữ an toàn cho bộ nhớ, bạn nên tuân theo các phương pháp hay nhất như đặt con trỏ thành giá trị NULL sau khi nó được giải phóng để tránh bất kỳ sự xuất hiện nào của lỗ hổng Sử dụng Sau khi Miễn phí.
- Bạn cũng có thể triển khai các kỹ thuật như Phân bổ một lần (OTA) để ngăn kẻ tấn công truy cập vào các đối tượng bộ nhớ được giải phóng và Chính sách vòng đời đối tượng nghiêm ngặt, giúp theo dõi từng đối tượng bộ nhớ được phân bổ và giải phóng. Hãy nhớ rằng những triển khai này có thể làm tăng chi phí hoạt động và bộ nhớ.
Các ví dụ trong thế giới thực về lỗ hổng sử dụng sau khi miễn phí (UAF)
Lỗ hổng Use-after-free (UAF) đã được phát hiện và khai thác trong nhiều tình huống thực tế khác nhau từ trình duyệt web đến nhân Android cho đến các ứng dụng hàng ngày. Điều này cho thấy sự cần thiết của các biện pháp bảo mật chủ động. Một số ví dụ thực tế về UAF bao gồm:
- Trình duyệt Internet: Các lỗ hổng UAF trong trình duyệt web đã bị khai thác để thực thi mã tùy ý, xâm phạm quyền riêng tư của người dùng và thực hiện các cuộc tấn công thực thi mã từ xa. Một ví dụ gần đây là CVE-2021-38008, đã khai thác lỗ hổng UAF trong Google Chrome, cho phép các tác nhân đe dọa thực thi mã tùy ý từ xa trên máy nạn nhân.
- Hệ điều hành: Các lỗ hổng UAF được tìm thấy trong nhân Windows/Linux/Android đã cho phép kẻ tấn công giành được các đặc quyền nâng cao, bỏ qua các cơ chế bảo mật và có được sự bền bỉ. Có rất nhiều lỗ hổng UAF đã được tìm thấy và vẫn được tìm thấy trong các nhân hệ điều hành cho đến ngày nay. Tại thời điểm viết bài này, CVE-2023-3269, một lỗ hổng UAF khác trong nhân Linux dẫn đến leo thang đặc quyền đã được phát hành công khai. CVE-2022-23270 là một ví dụ về lỗ hổng UAF trong nhân Windows.
- Ứng dụng phần mềm: Các lỗ hổng UAF trong ứng dụng phần mềm đã bị khai thác để thao túng hành vi của chương trình, dẫn đến tiết lộ thông tin, thực thi mã tùy ý, sự cố chương trình và trong trường hợp xấu nhất là leo thang đặc quyền. Nhiều ứng dụng phần mềm đã và vẫn dễ bị tấn công bởi UAF. Phần mềm này chủ yếu là các chương trình C/C++ đã được phát triển với các phương pháp quản lý bộ nhớ không hiệu quả và không an toàn.
Để tìm hiểu thêm về các lỗ hổng Sử dụng Sau khi Miễn phí trong các ứng dụng trong thế giới thực, bạn có thể kiểm tra trang danh sách MITRE CVE chính thức và sắp xếp theo từ khóa Sử dụng Sau khi Miễn phí.
Phân bổ bộ nhớ hiệu quả giúp bảo mật phần mềm
Việc phân bổ bộ nhớ được cân nhắc kỹ lưỡng và tối ưu sẽ giúp bảo vệ các ứng dụng của bạn khỏi trở thành con mồi của các lỗ hổng hỏng hóc bộ nhớ nguyên thủy phổ biến.
UAF cùng với Thời gian kiểm tra Thời gian sử dụng (TOCTOU), điều kiện chủng tộc và Tràn bộ đệm (BOF) là một số lỗ hổng bộ nhớ được khai thác phổ biến nhất. Tất cả những điều này có thể tránh được bằng cách tìm hiểu cách bộ nhớ chương trình của bạn được quản lý bởi nền tảng mà nó chạy trên đó. Điều này giúp bạn hiểu rõ cách hệ điều hành phân bổ chương trình của bạn trong bộ nhớ và trang bị cho bạn các công cụ để thiết kế phần mềm nhằm đạt được hiệu suất và bảo mật tối ưu.
Nếu chưa, bạn có thể bắt đầu bằng cách tìm hiểu cách quản lý bộ nhớ được thực hiện trên Linux, hệ điều hành máy chủ được sử dụng nhiều nhất trên thế giới.