Các phương pháp chống tràn bộ nhớ đệm

chong-tran-bo-nho-1

Nhiều kỹ thuật đa dạng với nhiều ưu nhược điểm đã được sử dụng để phát hiện hoặc ngăn chặn hiện tượng tràn bộ nhớ đệm. Cách đáng tin cậy nhất để tránh hoặc ngăn chặn tràn bộ nhớ đệm là sử dụng bảo vệ tự động tại mức ngôn ngữ lập trình. Tuy nhiên, loại bảo vệ này không thể áp dụng cho mã thừa kế (legacy code), và nhiều khi các ràng buộc kỹ thuật, kinh doanh hay văn hóa lại đòi hỏi sử dụng một ngôn ngữ không an toàn. Các mục sau đây mô tả các lựa chọn và cài đặt hiện có.

 

buffer-Overflow

Lựa chọn ngôn ngữ lập trình trong chống tràn bộ nhớ đệm

Lựa chọn về ngôn ngữ lập trình có thể có một ảnh hưởng lớn đối với sự xuất hiện của lỗi tràn bộ đệm. Năm 2006, C và C++ nằm trong số các ngôn ngữ lập trình thông dụng nhất, với một lượng khổng lồ các phần mềm đã được viết bằng hai ngôn ngữ này. C và C++ không cung cấp sẵn các cơ chế chống lại việc truy nhập hoặc ghi đè dữ liệu lên bất cứ phần nào của bộ nhớ thông qua các con trỏ bất hợp lệ; cụ thể, hai ngôn ngữ này không kiểm tra xem dữ liệu được ghi vào một mảng cài đặt của một bộ nhớ đệm) có nằm trong biên của mảng đó hay không.

Tuy nhiên, cần lưu ý rằng các thư viện chuẩn của C++, thử viện khuôn mẫu chuẩn – STL, cung cấp nhiều cách an toàn để lưu trữ dữ liệu trong bộ đệm, và các lập trình viên C cũng có thể tạo và sử dụng các tiện ích tương tự. Cũng như đối với các tính năng bất kỳ khác của C hay C++, mỗi lập trình viên phải tự xác định lựa chọn xem họ có muốn chấp nhận các hạn chế về tốc độ chương trình để thu lại các lợi ích tiềm năng (độ an toàn của chương trình) hay không.

Một số biến thể của C, chẳng hạn Cyclone, giúp ngăn chặn hơn nữa các lỗi tràn bộ đệm bằng việc chẳng hạn như gắn thông tin về kích thước mảng với các mảng. Ngôn ngữ lập trình D sử dụng nhiều kỹ thuật đa dạng để tránh gần hết việc sử dụng con trỏ và kiểm tra biên do người dùng xác định.

Nhiều ngôn ngữ lập trình khác cung cấp việc kiểm tra tại thời gian chạy, việc kiểm tra này gửi một cảnh báo hoặc ngoại lệ khi C hoặc C++ ghi đè dữ liệu. Ví dụ về các ngôn ngữ này rất đa dạng, từ pythol tới Ada, từ Lisp tới Modula-2, và từ Smalltalk tới OCaml. Các môi trường bytecode của Java và .NET cũng đòi hỏi kiểm tra biên đối với tất cả các mảng. Gần như tất cả các ngôn ngữ thông dịch sẽ bảo vệ chương trình trước các hiện tượng tràn bộ đệm bằng cách thông báo một trạng thái lỗi định rõ (well-defined error). Thông thường, khi một ngôn ngữ cung cấp đủ thông tin về kiểu để thực hiện kiểm tra biên, ngôn ngữ đó thường cho phép lựa chọn kích hoạt hay tắt chế độ đó. Việc phân tích tĩnh (static analysis) có thể loại được nhiều kiểm tra kiểu và biên động, nhưng các cài đặt tồi và các trường hợp rối rắm có thể giảm đáng kể hiệu năng. Các kỹ sư phần mềm phải cẩn thận cân nhắc giữa các phí tổn cho an toàn và hiệu năng khi quyết định sẽ sử dụng ngôn ngữ nào và cấu hình như thế nào cho trình biên

dịch.

Sử dụng các thư viện an toàn

Vấn đề tràn bộ đệm thường gặp trong C và C++ vì các ngôn ngữ này để lộ các chi tiết biểu diễn mức thấp của các bộ nhớ đệm với vai trò các chỗ chứa cho các kiểu dữ liệu. Do đó, phải tránh tràn bộ đệm bằng cách gìn giữ tính đúng đắn cao cho các phần mã chương trình thực hiện việc quản lý bộ đệm. Việc sử dụng các thư viện được viết tốt và đã được kiểm thử, dành cho các kiểu dữ liệu trừu tượng mà các thư viện này thực hiện tự động việc quản lý bộ nhớ, trong đó có kiểm tra biên, có thể làm giảm sự xuất hiện và ảnh hưởng của các hiện tượng tràn bộ đệm. Trong các ngôn ngữ này, xâu ký tự và mảng là hai kiểu dữ liệu chính mà tại đó các hiện tượng tràn bộ đệm thường xảy ra; do đó, các thư viện ngăn chặn lỗi tràn bộ đệm tại các kiểu dữ liệu này có thể cung cấp phần chính của sự che chắn cần thiết. Dù vậy, việc sử dụng các thư viện an toàn một cách không đúng có thể dẫn đến tràn bộ đệm và một số lỗ hổng khác; và tất nhiên, một lỗi bất kỳ trong chính thư viện chính nó cũng là một lỗ hổng. Các cài đặt thư viện “an toàn” gồm The Better String Library, Arri Buffer API và Vstr. Thư viện C của hệ điều hành OpenBSD cung cấp các hàm hữu ích strlcpy strlcat nhưng các hàm này nhiều hạn chế hơn nhiều so với các cài đặt thư viện an toàn đầy đủ.

Tháng 9 năm 2006, Báo cáo kỹ thuật số 24731 của hội đồng tiêu chuẩn C đã được công bố, báo cáo này mô tả một tập các hàm mới dựa trên các hàm vào ra dữ liệu và các hàm xử lý xâu ký tự của thư viện C chuẩn, các hàm mới này được bổ sung các tham số về kích thước bộ đệm.

 

chong-tran-bo-nho-1

Chống tràn bộ nhớ đệm trên stack

Stack-smashing protection là kỹ thuật được dùng để phát hiện các hiện tượng tràn bộ đệm phổ biến nhất. Kỹ thuật này kiểm tra xem stack đã bị sửa đổi hay chưa khi một hàm trả về. Nếu stack đã bị sửa đổ, chương trình kết thúc bằng một lỗi segmentation fault. Các hệ thống sử dụng kỹ thuật này gồm có Libsafe, StackGuard và các bản vá lỗi (patch) Propolicy.

Chế độ Data Execution Prevention (cấm thực thi dữ liệu) của Microsoft bảo vệ thẳng các con trỏ tới SEH Exception Handler, không cho chúng bị ghi đè. Có thể bảo vệ stack hơn nữa bằng cách phân tách stack thành hai phần, một phần dành cho dữ liệu và một phần cho các bước trả về của hàm. Sự phân chia này được dùng trong ngôn ngữ lập trình Forth, tuy nó không phải một quyết định thiết kế dựa theo tiêu chí an toàn. Nhưng dù sao thì đây cũng không phải một giải pháp hoàn chỉnh đối với vấn đề tràn bộ đệm, khi các dữ liệu nhạy cảm không phải địa chỉ trả về vẫn có thể bị ghi đè.

Bảo vệ không gian thực thi trong chống tràn bộ nhớ đệm

Bảo vệ không gian thực thi là một cách tiếp cận đối với việc chống tràn bộ đệm. Kỹ thuật này ngăn chặn việc thực thi mã tại stack hay heap. Một kẻ tấn công có thể sử dụng tràn bộ đệm để chèn một đoạn mã tùy ý vào bộ nhớ của một chương trình, nhưng với bảo vệ không gian thực thi, mọi cố gắng chạy đoạn mã đó sẽ gây ra một ngoại lệ (exception).

Một số CPU hỗ trợ một tính năng có tên bit NX (“No eXecute” – “Không thực thi”) hoặc bit XD (“eXecute Disabled” – “chế độ thực thi đã bị tắt” ). Khi kết hợp với phần mềm, các tính năng này có thể được dùng để đánh dấu các trang dữ liệu (chẳng hạn các trang chứa stack và heap) là đọc được nhưng không thực thi được.

Một số hệ điều hành Unix (chẳng hạn OpenBSD, Mac OS X) có kèm theo tính năng bảo vệ không gian thực thi. Một số gói phần mềm tùy chọn bao gồm:

PaX

Exec Shield

Openwall

Các biến thể mới của Microsoft Windows cũng hỗ trợ bảo vệ không gian thực thi, với tên gọi Data Execution Prevention (ngăn chặn thực thi dữ liệu). Các phần mềm gắn kèm (Add-on) bao gồm: SecureStack OverflowGuard BufferShield StackDefender Phương pháp bảo vệ không gian thực thi không chống lại được tấn công return-to-libc.

Ngẫu nhiên hóa sơ đồ không gian địa chỉ

Ngẫu nhiên hóa sơ đồ không gian địa chỉ (Address space layout randomization – ASLR) là một tính năng an ninh máy tính có liên quan đến việc sắp xếp vị trí các vùng dữ liệu quan trọng (thường bao gồm nơi chứa mã thực thi và vị trí các thư viện, heap và stack) một cách ngẫu nhiên trong không gian địa chỉ của một tiến trình.

Việc ngẫu nhiên hóa các địa chỉ bộ nhớ ảo mà các hàm và biến nằm tại đó làm cho việc khai thác một lỗi tràn bộ đệm trở nên khó khăn hơn, nhưng phải là không thể được. Nó còn buộc kẻ tấn công phải điều chỉnh khai thác cho hợp với từng hệ thống cụ thể, điều này làm thất bại cố gắng của các con Sâu internet Một phương pháp tương tự nhưng kém hiệu quả hơn, đó là kỹ thuật rebase đối với các tiến trình và thư viện trong không gian địa chỉ ảo.

Kiểm tra sâu đối với gói tin

Biện pháp kiểm tra sâu đối với gói tin (deep packet inspection – DPI) có thể phát hiện các cố gắng từ xa để khai thác lỗi tràn bộ đệm ngay từ biên giới mạng. Các kỹ thuật này có khả năng chặn các gói tin có chứa chữ ký của một vụ tấn công đã biết hoặc chứa một chuỗi dài các lệnh No-Operation (NOP – lệnh rỗng không làm gì), các chuỗi như vậy thường được sử dụng khi vị trí của nội dung quan trọng (payload) của tấn công hơi có biến đổi.

Việc rà các gói tin không phải là một phương pháp hiệu quả vì nó chỉ có thể ngăn chặn các tấn công đã biết, và có nhiều cách để mã hóa một lệnh NOP. Các kẻ tấn công có thể đã sử dụng mã alphanumeric, metamorphic, và Shellcode tự sửa để tránh bị phát hiện bởi việc rà gói tin.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *