2011-09-05 21 views
10

Tôi muốn hiểu sự khác biệt chính xác giữa hai loại tấn công này. Từ những gì tôi đã đọc:Sự khác biệt giữa - tràn bộ đệm và trở về cuộc tấn công libc

Tràn bộ đệm: Nó ghi đè địa chỉ ret trên ngăn xếp để trỏ đến một phần khác của mã nơi mã độc hại được chèn vào. Vì vậy, hiệu quả - ở đây chúng ta cần phải sửa đổi mã nguồn của chương trình để thực sự thực hiện các cuộc tấn công.

Quay lại Libc- Tại đây thay vì sửa đổi mã nguồn, các cuộc gọi hàm thời gian chạy được cung cấp bởi thư viện C được sử dụng (để mở trình bao). Ở đây các tham số được sử dụng cho các cuộc gọi chức năng cũng được thông qua trong bộ đệm ghi đè, kết thúc sau khi phần ret của ngăn xếp.

Mô tả ở trên có chính xác không?

Và một câu hỏi liên quan khác - liệu có thể có một cuộc tấn công tràn bộ đệm mà không thực sự sửa đổi mã nguồn của chương trình gốc không? Có lẽ nếu chúng ta viết một chương trình mới và cho phép sửa đổi một số phần bộ nhớ (đó là địa chỉ ret mới trong ngăn xếp bị hỏng của chương trình gốc). Sau đó, một lần nữa, tôi nghĩ rằng điều này có thể không thực hiện được do việc bảo vệ bộ nhớ được cung cấp giữa các tiến trình trong nhân.

Trả lời

12

Trong quá trình khai thác tràn bộ đệm cổ điển, bộ đệm ngăn xếp bị tràn đầy cả mã máy được thực thi (gọi là shellcode, vì nó thường gọi một quá trình shell) và địa chỉ trả về mới. Địa chỉ trả về mới sẽ được tạo thủ công để trỏ ngược lại trong bộ đệm ngăn xếp tràn. Rõ ràng, điều này đòi hỏi phải biết hoặc đoán địa chỉ của bộ đệm ngăn xếp đó trong quá trình bị tấn công.

Trong những ngày này, bố trí bộ nhớ của các quy trình thường rất xác định - vị trí của bộ đệm ngăn xếp thường có thể được dự đoán khá tốt bởi kẻ tấn công (đặc biệt nếu họ biết chính xác phiên bản phần mềm đích nào đang bị tấn công). Để cải thiện cơ hội thành công khi có một số phỏng đoán liên quan, shellcode hoạt động thường được đặt trước bởi một số lượng lớn mã máy thực thi không hoạt động hữu ích - gọi là "NOP sled" hoặc "NOP slide", trong đó "NOP" là tên điển hình cho lệnh mã máy thực hiện "Không hoạt động". Quay trở lại một điểm bất cứ nơi nào trong NOP sled sẽ có hiệu quả mong muốn.

Khai thác "trở về libc", mặt khác, không làm cho quá trình bị xâm nhập trở lại trực tiếp vào shellcode. Thay vào đó, nó làm cho quá trình trả về, từng cái một, để bắt đầu một chuỗi các hàm thư viện. Các hàm thư viện này có thể trực tiếp thực hiện các hoạt động mà kẻ tấn công muốn, nhưng thông thường chúng sẽ được sử dụng để gián tiếp thực thi shellcode của kẻ tấn công.

0

Thực ra, trong một cuộc tấn công tràn bộ đệm, bạn chèn mã độc hại trong khi ghi đè con trỏ. Bạn không cần phải sửa đổi bất cứ điều gì cho điều này, do đó, như một kết luận tôi không thể thấy sự khác biệt giữa cả hai cuộc tấn công được đề cập.

Ví dụ:

char* str[5];
cin << str;

Đây là mã có thể được exploided, nếu người dùng chèn một chuỗi lớn hơn 5 ký tự, tất cả mọi thứ trên stack mà sau này sẽ được ghi đè. Và do thực tế là ret-ptr là "thấp hơn" trên stack, bạn có thể ghi đè lên nó, nếu bạn nhận được khoảng cách bên phải. Ý định của bạn trong khi ghi đè là để cho nó điểm vào đầu của đầu vào của bạn, trong đó bạn chèn mã độc hại (assembler), mà sẽ được thực hiện ngay sau khi ret-ptr được gọi là và "nhảy" thực hiện.

4

Phần ghi đè địa chỉ ret được chia sẻ giữa cả hai cuộc tấn công. Như câu trả lời ở trên cho biết, bạn đã sử dụng chỉ đơn giản là trả về mã assembly mà bạn đã viết. Sau đó, mã assembly này sẽ sinh ra một shell người dùng root.

Trong cả hai cuộc tấn công, bạn sẽ 'ghi đè lên' mã nguồn. Xem nó từ một phối cảnh lắp ráp, mã nguồn nằm trong phân đoạn .text và luôn luôn (hoặc ít nhất là tất cả thời gian tôi biết) được bảo vệ chống ghi. Những gì bạn sử dụng để tận dụng lợi thế là viết mã mà bạn đã lắp ráp trước vào các phân đoạn bộ nhớ, và sau đó chuyển sang mã này. Mã này thường được đặt trong hoặc gần 'phân đoạn ngăn xếp' và bằng cách làm tràn bất kỳ thứ gì bạn chọn để quá mức, bạn sẽ chuyển hướng lưu lượng truy cập từ địa chỉ ret (nói) tại đó. Các địa điểm tấn công khác bao gồm một biến môi trường mà bạn đã tạo trước đó và chứa đầy shellcode của bạn; hoặc cũng là heap hoặc các con trỏ hàm hoặc PLT. Mã được chèn vào thường sẽ sử dụng lệnh system() để thực thi những gì được mong muốn - nhưng với điều này, bạn cần có khả năng 'thực thi' trên vùng bộ nhớ (hoặc có các mục định vị lại mà bạn dự định sử dụng được khai báo).

Sự khác biệt giữa hai cuộc tấn công là một khi bộ nhớ đã được thực hiện phần lớn không thể thực thi, loại tấn công một (ngăn xếp tràn) đã được khá nhiều hơi say. Một nỗ lực để bỏ qua kiểu tấn công này, khi bạn viết, thay vào đó truy cập các hàm thư viện được chia sẻ trực tiếp - aka, bạn không còn cần phải viết mã của mình trước vào phân đoạn ngăn xếp hoặc ở nơi khác và thực thi nó ở đó. Tuy nhiên, tôi tin rằng các cuộc tấn công kiểu libc cũng bị vá nhiều; Tôi không có chi tiết tiện dụng; và có lẽ tôi sai.

Nếu bạn muốn xem bất kỳ cuộc tấn công nào trong số này bị cản trở trong những ngày này, hoặc ít nhất hãy đọc về một số ý tưởng chính, google 'Smashing the Stack in 2011' (hoặc 2010) để bắt đầu.

+0

Bạn có thể giải thích ý của bạn bằng cách - làm cho bộ nhớ thực thi (hoặc không thể thực thi được). Và nghi ngờ khác (một phần của câu hỏi ban đầu của tôi) là - tôi tin rằng một mã C sẽ không có quyền truy cập vào tất cả các bộ phận của bộ nhớ chính. Vì vậy, làm thế nào là nó xác định được nơi mã lắp ráp độc hại được đặt trong bộ nhớ. Bởi vì tôi nghĩ cho hầu hết các vùng bộ nhớ - nó sẽ chỉ gắn cờ một lỗi phân đoạn khi quay trở lại đó. – Hari

+0

Cốt lõi của mã khai thác bạn chèn thường sử dụng và hàm exec() kiểu gia đình. Điều này có nghĩa, bằng cách cho nó các thông số thích hợp, bạn có thể có nó, nói, sinh ra một/bin/sh shell là người dùng root. Đây là * thực hiện * một chương trình, và bạn không thể nữa. Có nhiều biện pháp bảo mật khác nhau, nhưng điều này sẽ được mô tả, ví dụ: trong – gnometorule

+0

http://en.wikipedia.org/wiki/NX_bit – gnometorule

4

Tôi có thể nói tràn bộ đệm là một lớp lỗi lập trình và quay lại libc là kỹ thuật khai thác. Tốt nhất là không trộn lẫn các khái niệm với nhau.

Ví dụ, bạn có thể sử dụng trở lại libc để khai thác một tràn bộ đệm dễ bị tổn thương. Hoặc bạn có thể sử dụng các kỹ thuật khác như quay lại .tiếp theo hoặc quay lại shellcode. Ngược lại, bạn cũng có thể sử dụng quay lại libc để khai thác các lỗi khác như chuỗi định dạng.