Bạn có thể tràn bộ đệm Python không?

Lỗi tràn bộ đệm rất khó phát hiện và mặc dù vậy, khi bạn phát hiện ra lỗi này, nhìn chung rất khó để khai thác

https. // vi. wikipedia. org/wiki/Stack_[abstract_data_type]

Vì vậy, một stackframe là gì?

Đầu tiên, ngăn xếp cuộc gọi về cơ bản là mã trình biên dịch chương trình cho một chương trình cụ thể. Đó là một chồng các biến và khung xếp chồng cho máy tính biết thứ tự thực hiện các lệnh. Sẽ có một khung ngăn xếp cho mỗi chức năng chưa thực thi xong, với chức năng hiện đang thực thi ở trên cùng của ngăn xếp

Để theo dõi điều này, một máy tính giữ một số con trỏ trong bộ nhớ

  • Con trỏ ngăn xếp. Trỏ tới đỉnh ngăn xếp lời gọi tiến trình [hoặc mục cuối cùng được đẩy vào ngăn xếp]
  • Con trỏ hướng dẫn. Trỏ tới địa chỉ của lệnh CPU tiếp theo sẽ được thực hiện
  • Con trỏ cơ sở [BP]. [còn được gọi là con trỏ khung] Chỉ vào cơ sở của khung xếp chồng hiện tại. Nó không đổi miễn là chương trình đang thực thi stackframe hiện tại [mặc dù con trỏ ngăn xếp sẽ thay đổi]

Ví dụ, đưa ra chương trình sau

int main[] {
    int j = firstFunction[5];
    return 0;
}
    
int firstFunction[int z] {
    int x = 1 + z;
    return x;
}

Ngăn xếp cuộc gọi sẽ trông như thế này, ngay sau khi FirstFunction được gọi và câu lệnh int x = 1+z đã được thực thi

Ở đây, main được gọi là firstFunction [hiện đang được thực thi], do đó, nó nằm ở đầu ngăn xếp cuộc gọi. Địa chỉ trả về là địa chỉ bộ nhớ của hàm đã gọi nó [địa chỉ này được giữ bởi con trỏ lệnh khi khung ngăn xếp được tạo]. Các biến cục bộ vẫn còn trong phạm vi cũng nằm trong ngăn xếp cuộc gọi. Khi chúng được thực thi và vượt ra ngoài phạm vi, chúng sẽ được 'đẩy' ra khỏi đầu ngăn xếp

Do đó, máy tính có thể theo dõi lệnh nào cần được thực hiện và theo thứ tự nào. Tràn ngăn xếp được thiết kế để ghi đè lên một trong những địa chỉ trả về đã lưu này bằng địa chỉ độc hại của chính nó

Ví dụ lỗ hổng tràn bộ đệm [C]

int main[] {
    bufferOverflow[];
 }
 
 bufferOverflow[] {
    char textLine[10];
    printf["Enter your line of text: "];
    gets[textLine];
    printf["You entered: ", textLine];
    return 0;
 }

Ví dụ đơn giản này đọc một lượng dữ liệu tùy ý [get sẽ đọc cho đến khi kết thúc tệp hoặc ký tự xuống dòng]. Nghĩ về ngăn xếp cuộc gọi mà chúng tôi đã trình bày ở trên, bạn có thể thấy tại sao điều này lại nguy hiểm. Nếu người dùng nhập nhiều dữ liệu hơn số lượng mà biến được chỉ định, chuỗi mà người dùng đã nhập sẽ ghi đè lên các vị trí bộ nhớ tiếp theo trên ngăn xếp cuộc gọi. Nếu nó đủ dài, nó thậm chí có thể ghi đè địa chỉ trả về của hàm gọi

Cách máy tính sẽ phản ứng với điều này tùy thuộc vào cách các ngăn xếp được triển khai và cách phân bổ bộ nhớ trong một hệ thống cụ thể. Phản ứng đối với tràn bộ đệm có thể khá khó đoán, từ lỗi chương trình, sự cố, thực thi mã độc

Tại sao tràn bộ đệm xảy ra?

Lý do tràn bộ đệm trở thành một vấn đề nghiêm trọng là do nhiều hàm thao tác bộ nhớ trong C và C++ không thực hiện bất kỳ kiểm tra giới hạn nào. Mặc dù lỗi tràn bộ đệm hiện đã khá phổ biến, nhưng chúng cũng thường bị khai thác [ví dụ: WannaCry đã khai thác lỗi tràn bộ đệm]

Tràn bộ đệm phổ biến nhất khi mã dựa trên dữ liệu đầu vào bên ngoài, quá phức tạp để lập trình viên có thể dễ dàng hiểu hành vi của nó hoặc khi mã có các phụ thuộc bên ngoài phạm vi trực tiếp của mã

Máy chủ web, máy chủ ứng dụng và môi trường ứng dụng web đều dễ bị tràn bộ đệm

Ngoại lệ là các môi trường được viết bằng ngôn ngữ thông dịch, mặc dù bản thân trình thông dịch có thể dễ bị tràn

Cách giảm thiểu lỗi tràn bộ đệm

  • Sử dụng ngôn ngữ được giải thích không dễ gặp phải những vấn đề này
  • Tránh sử dụng các chức năng không thực hiện kiểm tra bộ đệm [ví dụ: trong C, thay vì get[] hãy sử dụng fgets[]]
  • Sử dụng trình biên dịch có thể giúp xác định các chức năng hoặc lỗi không an toàn
  • Sử dụng Canaries, một 'giá trị bảo vệ' có thể giúp ngăn tràn bộ đệm. Chúng được chèn trước địa chỉ trả về trong ngăn xếp và được kiểm tra trước khi truy cập địa chỉ trả về. Nếu chương trình phát hiện một thay đổi đối với giá trị canary, nó sẽ hủy bỏ quá trình, ngăn không cho kẻ tấn công thành công. Giá trị canary hoặc là ngẫu nhiên [vì vậy kẻ tấn công rất khó đoán] hoặc là một chuỗi ký tự mà vì lý do kỹ thuật, không thể ghi đè lên
  • Sắp xếp lại các biến cục bộ sao cho các biến vô hướng [các đối tượng dữ liệu có kích thước cố định riêng lẻ] nằm trên các biến mảng [chứa nhiều giá trị]. Điều này có nghĩa là nếu các biến mảng tràn, chúng sẽ không ảnh hưởng đến các biến vô hướng. Kỹ thuật này, khi được kết hợp với các giá trị canary, có thể giúp ngăn chặn các cuộc tấn công tràn bộ đệm thành công
  • Làm cho ngăn xếp không thể thực thi được bằng cách đặt bit NX [No-eXecute], ngăn kẻ tấn công chèn shellcode trực tiếp vào ngăn xếp và thực thi nó ở đó. Đây không phải là một giải pháp hoàn hảo, vì ngay cả các ngăn xếp không thể thực thi cũng có thể là nạn nhân của các cuộc tấn công tràn bộ đệm, chẳng hạn như cuộc tấn công quay trở lại libc. Cuộc tấn công này xảy ra khi địa chỉ trả về của khung xếp chồng được thay thế bằng địa chỉ của thư viện đã có trong không gian địa chỉ của quy trình. Ngoài ra, không phải tất cả các CPU đều cho phép thiết lập bit NX
  • ASLR [ngẫu nhiên hóa bố cục không gian địa chỉ], có thể đóng vai trò phòng thủ chung [cũng như phòng thủ cụ thể chống lại các cuộc tấn công quay trở lại thư viện]. Điều đó có nghĩa là bất cứ khi nào một tệp thư viện hoặc chức năng khác được gọi bởi một quy trình đang chạy, địa chỉ của nó sẽ được thay đổi theo một số ngẫu nhiên. Nó làm cho gần như không thể liên kết một địa chỉ bộ nhớ tiến trình cố định với các chức năng, nghĩa là kẻ tấn công có thể gặp khó khăn, nếu không muốn nói là không thể biết được từ đâu để gọi các chức năng cụ thể. ASLR được bật theo mặc định trong nhiều phiên bản Linux, OS X và Android [có thể tắt trong dòng lệnh]

Lưu ý về Stack Underflow

Cũng có thể có lỗ hổng tràn bộ đệm, khi hai phần của cùng một chương trình xử lý khác nhau đối với cùng một khối bộ nhớ. Ví dụ: nếu bạn cấp phát một mảng có kích thước X, nhưng lại lấp đầy nó bằng một mảng có kích thước x < X, và sau đó bạn cố truy xuất tất cả các byte X, thì bạn có khả năng nhận được dữ liệu rác cho các byte X - x

Về cơ bản, bạn có thể đã lấy dữ liệu còn sót lại từ cách sử dụng bộ nhớ đó trước đó. Trường hợp tốt nhất đó là rác không có ý nghĩa gì, trong khi trường hợp xấu nhất là dữ liệu nhạy cảm mà kẻ tấn công có thể sử dụng sai mục đích

Nguồn/Đọc thêm

  • Bài giảng An ninh Mạng và Máy tính, Avinash Kak
  • Tràn bộ đệm OWASP
  • Ngăn xếp so với đống

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

QUẢNG CÁO

Megan Kaczanowski

Bảo mật & Tình báo về Mối đe dọa @megansdoingfine

Nếu bạn đọc đến đây, hãy tweet cho tác giả để cho họ thấy bạn quan tâm. Tweet một lời cảm ơn

Học cách viết mã miễn phí. Chương trình giảng dạy mã nguồn mở của freeCodeCamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu

Tại sao tràn bộ đệm không phải là vấn đề với Java hoặc Python?

Điều này là do đây là những ngôn ngữ cấp thấp dựa vào nhà phát triển để phân bổ bộ nhớ . Hầu hết các ngôn ngữ phổ biến được sử dụng trên web như PHP, Java, JavaScript hoặc Python ít bị khai thác lỗi tràn bộ đệm hơn vì chúng quản lý cấp phát bộ nhớ thay mặt cho nhà phát triển.

Ngôn ngữ lập trình nào dễ bị tấn công tràn bộ đệm nhất?

C và C++ là hai ngôn ngữ rất dễ bị tấn công tràn bộ đệm vì chúng không có các biện pháp bảo vệ tích hợp chống lại việc ghi đè hoặc truy cập dữ liệu trong bộ nhớ của chúng. Mac OSX, Windows và Linux đều sử dụng mã được viết bằng C và C++.

Có phải tràn bộ đệm chỉ trong C?

While C, C++ và Objective-C là những ngôn ngữ chính có lỗ hổng tràn bộ đệm [vì chúng xử lý bộ nhớ trực tiếp hơn .

Tràn bộ đệm vẫn là một vấn đề?

Ngày nay, tràn bộ đệm vẫn xảy ra trong các ứng dụng phần mềm và khả năng khai thác của chúng có thể phụ thuộc vào một số yếu tố khác nhau, bao gồm trình biên dịch và/hoặc các tùy chọn trình biên dịch được sử dụng, cùng với các tính năng bảo mật của .

Chủ Đề