2013-07-11 22 views
6

xem xét mã dễ bị tổn thương/chương trình sau đây:Khai thác một lỗi tràn bộ chuỗi dựa trên x86-64 với NX (DEP) và ASLR kích hoạt

#include <string.h> 

int main(int argc, char *argv[]) { 
    char buf[16]; 
    strcpy(buf, argv[1]); 

    return 0; 
} 

On IA-32 (x86, 32-bit) chạy Linux với NX và ASLR kích hoạt, tôi sẽ khai thác này sử dụng kỹ thuật GOT-ghi đè lên, trong đó chủ yếu bao gồm các bước sau:

  1. tràn bộ đệm cho đến khi RIP
  2. Overwrite RIP với địa chỉ của [email protected]
  3. Sử dụng tiện ích sạch từ .text, ví dụ: pop edi ; pop ebp ; ret, như địa chỉ trả lại cho strcpy
  4. Viết luận cho strcpy: &bss -Địa chỉ là điểm đến và một byte của /bin/sh sử dụng .text
  5. Lặp lại các bước 2-4 cho đến khi /bin/sh là hoàn toàn bằng văn bản cho &bss
  6. Overwrite GOT-nhập cảnh của strcpy với system (sử dụng bù đắp, yêu cầu kiến ​​thức về phiên bản đã sử dụng của Libc - hãy bỏ qua điều này tại đây)
  7. Viết [email protected] trên ngăn xếp, theo sau là đoạn 4 byte và địa chỉ cuối cùng là &bss whi điểm ch để /bin/sh
  8. Lợi nhuận

tôi muốn khai thác này trên x86-64 với các biện pháp giảm nhẹ cùng kích hoạt. Nhưng điều này là khó khăn hơn như tưởng tượng. Về cơ bản vì những lý do sau đây:

  1. x86-64 register-based gọi ước: đối số chức năng được thông qua sử dụng đăng ký, không phải là chồng. Do đó, một số tiện ích ROP bổ sung được yêu cầu chuyển các đối số từ ngăn xếp vào thanh ghi thích hợp. Đây là một vấn đề nhỏ, nhưng cũng bị ảnh hưởng bởi sự cố sau:
  2. Địa chỉ trả lại 64 bit: RIP trong x86-64 trỏ tới .text thậm chí không dài 32 bit. Do đó, NULL-byte phải được viết trên stack để gọi hàm chuỗi. Về cơ bản người ta có thể viết nhiều NULL-byte như mong muốn bằng cách sử dụng các cuộc gọi chuỗi đến strcpy và tận dụng các ký tự NULL-chấm dứt strcpy luôn luôn viết. Nhưng người ta chỉ có thể gọi strcpy một lần bằng cách chỉ ghi đè các byte ít quan trọng nhất của RIP.

    |0x00000000|  (most significant bytes) 
    |0x00deadbe| <- RIP (least significant bytes) 
    |0x41414141| 
    |0x41414141| <- SFP 
    | ... | 
    

Đây là những vấn đề lớn tôi nhận với khai thác các chương trình trên x86-64 với NX và ASLR kích hoạt. Có bất kỳ kỹ thuật nào giải quyết những vấn đề này không? Hoặc x86-64 có thực sự ngăn chặn một khai thác đang hoạt động, mở vỏ không?

+1

Nếu RIP được cho là phù hợp với địa chỉ trả lại, bạn cần thuật ngữ mới cho x86-64. Giống như EAX được mở rộng thành RAX, EIP (Con trỏ Chỉ thị hiện tại) được mở rộng thành RIP. Vì vậy, trong x86-64, RIP là một tên đăng ký, và không (tự nó) tạo một tên tốt cho địa chỉ trả về mà RET sẽ đọc. –

Trả lời

0

x86-64 không ngăn các loại khai thác này. Xem này tutorial.

+1

Khi câu hỏi này giả định x86-64 với cả ASLR và NX được kích hoạt, liên kết của bạn không cung cấp giải pháp: "Tôi đã phải lừa một chút bằng cách tắt ASLR. Do tính chất giải quyết trên 64 bit hệ thống, null byte trở thành một vấn đề thực sự lớn. Đối với thử thách đặc biệt này, thật dễ dàng để ghi đè lên RIP, nhưng tôi chỉ có thể quay trở lại một công cụ duy nhất do các byte rỗng. " – Propantriol

Các vấn đề liên quan