Năm 1988, một sự cố máy tính đã thu hút sự chú ý của toàn thể cộng đồng sử dụng mạng internet, đó là sự ra đời của sâu internet (Internet Worm).
Bạn đang xem: Buffer overflow attack là gì
Con sâu này đã làm hơn 6000 máy chủ phải ngưng hoạt động bởi một lỗi ít được biết đến là “tràn bộ đệm” (buffer overflow). Cho đến nay, lỗi tràn bộ đệm vẫn tiếp tục được tìm thấy trong nhiều phần mềm trên nhiều hệ điều hành khác nhau. Đó thực sự là một nguy cơ nghiêm trọng, một vấn đề đã tồn tại khá lâu và cần được quan tâm một cách nghiêm túc.Đa phần các lỗi tràn bộ đệm dẫn đến việc chiếm quyền điều khiển toàn bộ trên hệ thống nên đây thực sự là một lỗi chết người. Tràn bộ đệm xảy ra trên nhiều hệ điều hành, đặc biệt là trên UNIX và Windows, và trên nhiều ứng dụng khác nhau như web, mail, ftp, dns, telnet, ssh, database, … Tháng 8-2001, sâu máy tính Code Red đã khiến thế giới thiệt hại hàng tỉ USD cũng bắt nguồn từ một lỗ hổng tràn bộ đệm trong phần mềm máy chủ Microsoft Internet Information Server (IIS). Vậy thế nào là tràn bộ đệm? Tại sao xảy ra tràn bộ đệm? Tại sao tràn bộ đệm tạo ra lỗ hổng bảo mật? Làm thế nào để ngăn chặn lỗi tràn bộ đệm?Bộ đệm và tràn bộ đệm Để giải thích việc tràn bộ đệm xảy ra như thế nào, chúng ta sẽ đề cập đến một loại tràn bộ đệm thường gặp nhất gọi là “tràn bộ đệm stack”. Hãy hình dung bạn có một chiếc bình nước 5 lít, bạn chỉ có thể đựng được tối đa 5 lít nước trong chiếc bình đó. Nếu bạn đổ 7 lít nước vào bình, nước sẽ bị tràn và chảy ra ngoài. Khái niệm tương tự cũng được áp dụng cho các biến bên trong chương trình. Ví dụ, một chương trình cần nhập dữ liệu của người dùng với kích thước tối đa 256 bytes. Hệ điều hành sẽ cấp phát một vùng trong bộ nhớ máy tính (đó chính là một bộ đệm – buffer) dành cho chương trình để lưu trữ 256 bytes hoặc ít hơn. Nếu người dùng nhập vào quá 256 bytes và chương trình không kiểm tra điều này, tràn bộ đệm sẽ xảy ra. Vì chương trình máy tính cần không gian để lưu trữ những byte dư ra, nó sẽ chứa lên những vùng nhớ kế cạnh và ghi đè lên những dữ liệu có sẵn tại đó.Còn có một bộ đệm khác trên bộ nhớ máy tính dùng để lưu trữ địa chỉ cho lệnh máy kế tiếp sẽ được thực thi sau khi gọi hàm. Vùng nhớ này được cấp phát trên stack và được gọi là con trỏ lệnh (instruction pointer). Tiếp tục ví dụ trên, giả sử sau khi đọc vào dữ liệu nhập của người dùng, chương trình sẽ thực hiện lệnh in ra nội dung. Con trỏ lệnh khi đó sẽ có giá trị là địa chỉ vùng nhớ của lệnh in. Máy tính sẽ thực hiện các thao tác tuần tự như sau: đọc dữ liệu nhập của người dùng, lưu trữ nó vào bộ đệm, kiểm tra con trỏ lệnh để biết lệnh thực thi kế tiếp, tìm địa chỉ vùng nhớ của lệnh in, đọc nội dung của bộ đệm và in nó ra màn hình.Bây giờ hãy kết hợp lại, nếu một kẻ xấu có thể làm tràn bộ đệm sao cho thay đổi nội dung của con trỏ lệnh bằng cách trỏ đến đoạn mã lệnh của mình, anh ta có thể làm được nhiều chuyện khác. Và đó là những gì diễn ra trong thực tế. Hacker làm tràn bộ đệm sao cho con trỏ lệnh sẽ trỏ đến một đoạn mã tạo ra một giao tiếp dòng lệnh (command line, ví dụ /bin/sh). Sau khi chương trình thực hiện làm tràn bộ đệm, nó sẽ tìm đến địa chỉ của đoạn mã trên để thực thi tiếp.Xem thêm: Bộ Từ Vựng Tiếng Anh Về Vũ Trụ Tiếng Anh Là Gì ? Từ Vựng Tiếng Anh Về Vũ Trụ
Nếu chương trình được chạy dưới quyền của người quản trị, hacker đã có được một giao tiếp dòng lệnh với quyền tương đương và có thể điều khiển toàn bộ hệ thống.Có thể thấy khái niệm tràn bộ đệm khá rõ ràng và hoàn toàn không có gì phức tạp. Để khai thác được lỗ hổng tràn bộ đệm cần có một số kiến thức về lập trình C, hợp ngữ và công cụ gỡ rối. Có vẻ khá nhiều, tuy nhiên với những tài liệu đã công bố rộng rãi, đi kèm đó là các công cụ hỗ trợ và thông tin trên internet ngày càng nhiều, việc khai thác lỗ hổng trở nên dễ dàng hơn. Những gì xảy ra là, một người nào đó có kiến thức và thành thạo kỹ thuật tạo ra chương trình khai thác lỗi tràn bộ đệm, công bố nó trên Internet trước khi chúng lọt vào tay nhiều kẻ tấn công khác.Tại sao vẫn tồn tại lỗi tràn bộ đệm và làm thế nào để ngăn chặn?Đa phần lỗi tràn bộ đệm tồn tại là do thói quen lập trình tồi, đặc biệt là đối với các chương trình được viết bằng ngôn ngữ C (ngôn ngữ lập trình phổ biến nhất hiện nay). Khi chương trình yêu cầu dữ liệu nhập có kích thước tối đa hoặc sao chép một mảng sang mảng khác, cần phải có sự cấp phát hợp lý để không vượt quá giới hạn về kích thước. Điều này gọi là “kiểm tra giới hạn” (bounds checking). Ngôn ngữ C cung cấp nhiều hàm thư viện không thực hiện việc kiểm tra giới hạn, ví dụ như strcpy(), strcat(), sprinf(). Các lập trình viên sử dụng các hàm này mà không thực hiện việc kiểm tra giới hạn nào khác chính là nguyên nhân gây lỗi tràn bộ đệm.Thế thì tạo sao không viết các phần mềm có kiểm tra giới hạn đầy đủ? Nghe có vẻ dễ dàng. Tuy nhiên, một số lập trình viên không quan tâm đến việc kiểm tra giới hạn. Một số khác không muốn sử dụng vì nó có thể làm giảm tốc độ xử lý của chương trình. Một lý do nữa là lỗi tràn bộ đệm chỉ mới được biết đến rộng rãi trong khoảng 7 năm trở lại đây, trong khi đó có nhiều phần mềm kế thừa (ở dạng thư viện lập trình) đã được viết từ trước, khi các lập trình viên còn chưa nhận thức được việc kiểm tra giới hạn là bắt buộc. Đa phần các phần mềm này không được viết lại để đảm bảo an toàn hơn, nó chỉ được viết lại khi phát hiện ra lỗ hổng bảo mật. Một khi lỗi tràn bộ đệm được phát hiện, các công ty đều cung cấp bản sửa lỗi, tuy nhiên chương trình có được sửa lỗi hay không còn phụ thuộc vào người quản trị hệ thống có chịu cài đặt nó hay không.Đó cũng là lý do tại sao cần có nhận thức nghiêm túc về vấn đề này và phải làm hết sức để ngăn chặn lỗi tràn bộ đệm. Có một số việc mà các lập trình viên, các nhà quản trị hệ thống có thể làm để giúp ngăn chặn và bảo vệ hệ thống khỏi các cuộc tấn công tràn bộ đệm. Dưới đây là một số đề xuất, hướng dẫn và tiện ích có thể sử dụng:Luôn sử dụng kiểm tra giới hạn khi viết chương trìnhXem xét lại tính bảo mật của mã nguồn các phần mềm kế thừa Tránh sử dụng các hàm không cung cấp kiểm tra giới hạn trong ngôn ngữ C, thay vào đó là các hàm tương đương. Thay các hàm gets, strcpy, strcat, sprintf, scanf, sscanf bằng các hàm tương đương fgets, strncpy, strncat, bcopy, bzero, memcpy. Sử dụng các vùng nhớ được cấp phát động. Cẩn thận khi sử dụng các vòng lặp để sao chép dữ liệu từ giữa các biến, cần đảm bảo giới hạn đã được kiểm tra. Sử dụng các tiện ích như StackGuard, StackShield để bảo vệ vùng bộ nhớ stack khỏi tràn bộ đệm. Sử dụng các công cụ và hướng dẫn để đánh giá mức độ an toàn của chương trình như Slint, rats, its, flawfinder. Cài đặt ngay các bản sửa lỗi.Kết luận“Tràn bộ đệm” là một thuật ngữ đã trở nên quá quen thuộc trong lĩnh vực bảo mật hệ thống. Chúng là một mối đe doạ thực sự và nên được ngăn chặn tối đa có thể. Các lập trình viên và quản trị hệ thống cần hành động tích cực hơn khi viết các phần mềm và khi bảo vệ hệ thống, cũng như chú trọng đến việc giáo dục và nhận thức về những gì cần làm.Video demo: