Lỗ hổng tràn bộ đệm (Buffer Overflow) là một lỗ hổng phổ biến trong lập trình, cho phép dữ liệu bị ghi vào một buffer và có thể tràn ra ngoài buffer đó. Điều này dẫn đến việc ghi đè lên dữ liệu khác và có thể gây ra hoạt động bất thường cho chương trình.
Lỗ hổng tràn bộ đệm trên stack và trên heap
Lỗ hổng tràn bộ đệm có hai dạng chính: trên stack và trên heap. Có nhiều cơ chế bảo vệ được phát triển để ngăn chặn lỗ hổng này, nhưng cũng có nhiều kỹ thuật khai thác được sử dụng.
Hậu quả của lỗ hổng tràn bộ đệm
Lỗi tràn bộ đệm có thể làm cho một tiến trình đổ vỡ hoặc cho ra kết quả sai. Các lỗi này có thể được kích hoạt bởi các dữ liệu được thiết kế đặc biệt để thực thi các đoạn mã phá hoại hoặc làm cho chương trình hoạt động không như mong đợi.
Lỗ hổng tràn bộ đệm gây ra nhiều lỗ hổng bảo mật đối với phần mềm và tạo điều kiện cho các kỹ thuật khai thác. Việc kiểm tra biên (bounds checking) được thực hiện bởi lập trình viên hoặc trình biên dịch có thể ngăn chặn các lỗi tràn bộ đệm.
Cách khai thác lỗ hổng tràn bộ đệm
Có nhiều cách để khai thác lỗ hổng tràn bộ đệm, ví dụ như ghi đè lên biến cục bộ, ghi đè địa chỉ trả về, hoặc trở về thư viện chuẩn. Trong bài viết này, chúng ta sẽ hướng dẫn cách đơn giản nhất để khai thác lỗ hổng này, đó là ghi đè lên biến cục bộ.
Ghi đè biến cục bộ
Dưới đây là đoạn mã nguồn ví dụ:
#include <stdio.h>
int main() {
int cookie=0;
char buf[16];
printf("Your name: ");
gets(buf);
if(cookie == 0x41424344)
puts("You win!");
else
puts("Try again!");
return 0;
}
Đoạn mã trên cho phép người dùng nhập vào một chuỗi kí tự, sau đó kiểm tra biến cookie với giá trị 0x41424344. Nếu hai giá trị bằng nhau, chương trình sẽ in ra “You win!”, ngược lại sẽ in ra “Try again!”. Tuy nhiên, trong trường hợp này, biến cookie được gán giá trị ban đầu là 0 và không có đoạn mã nào thay đổi giá trị của nó. Do đó, chương trình luôn chạy vào nhánh “Try again!”.
Đoạn mã trên bị lỗi buffer overflow do sử dụng hàm gets. Hàm này lưu toàn bộ những gì người dùng nhập vào biến buf, nếu người dùng nhập số ký tự lớn hơn số ô nhớ được cấp phát cho biến buf, lỗi buffer overflow sẽ xảy ra.
Chúng ta cần khai thác lỗi này để chương trình chạy vào nhánh “You win!”.
Ghi đè lên biến cục bộ
Từ đoạn mã nguồn trên, chúng ta có thể thấy:
- Biến buf nằm ở stack với địa chỉ [ebp-14h], biến cookie nằm ở stack với địa chỉ [ebp-4h].
- Buffer nằm thấp hơn cookie, vì vậy ta có thể ghi đè giá trị của biến buf lên biến cookie.
- Khoảng cách từ buf đến cookie là 16 bytes.
Để khai thác lỗ hổng trên, chúng ta cần nhập 16 bytes bất kỳ để tiếp cận và sau đó là dữ liệu muốn ghi đè lên biến cookie.
Ví dụ: nhập chuỗi “0123456789abcdefDCBA”. Kết quả sẽ là chương trình in ra “You win!”.
Cảm ơn bạn đã đọc bài viết này. Hy vọng bạn có một ngày vui vẻ!
Được chỉnh sửa bởi HEFC