2012-03-10 20 views
21

Tôi đã cố gắng tìm hiểu các khái niệm cơ bản về tấn công tràn vùng heap. Tôi chủ yếu quan tâm đến việc sử dụng một tham nhũng hoặc sửa đổi siêu dữ liệu đoạn cho cơ sở của cuộc tấn công, nhưng tôi cũng mở cho các đề xuất khác. Tôi biết rằng mục tiêu của tôi về khai thác nên được ghi đè lên con trỏ hàm printf() với con trỏ hàm challenge(), nhưng tôi không thể tìm ra cách để đạt được điều đó. Tôi có đoạn mã sau đây mà tôi muốn khai thác, đó là sử dụng malloc từ glibc 2.11.2:Sử dụng tràn bộ nhớ để ghi dữ liệu tùy ý

void challenge() 
{ 
     puts("you win\n"); 
} 

int main(int argc, char **argv) 
{ 
     char *inputA, *inputB, *inputC; 

     inputA = malloc(32); 
     inputB = malloc(32); 
     inputC = malloc(32); 

     strcpy(inputA, argv[1]); 
     strcpy(inputB, argv[2]); 
     strcpy(inputC, argv[3]); 

     free(inputC); 
     free(inputB); 
     free(inputA); 

     printf("execute challenge to win\n"); 
} 

Rõ ràng, việc đạt được một ghi đè thực tế của siêu dữ liệu một đoạn phân bổ là tầm thường. Tuy nhiên, tôi đã không thể tìm ra cách để khai thác mã này bằng cách sử dụng bất kỳ kỹ thuật chuẩn nào. Tôi đã đọc và cố gắng thực hiện các kỹ thuật từ:

  • Bài viết: w00w00 trên Heap Overflows
    • Mặc dù giấy là rất rõ ràng, kỹ thuật unlink đã lỗi thời trong một thời gian.
  • Malloc Maleficarum.txt
    • Bài viết này được cải tiến từ khai thác kỹ thuật từ những ngày w00w00, và chiếm các phiên bản mới hơn của glibc. Tuy nhiên, tôi đã không thấy rằng với 5 kỹ thuật chi tiết trong bài báo, mã ở trên phù hợp với bất kỳ điều kiện tiên quyết nào cho những kỹ thuật đó.
  • Understanding the Heap By Breaking it(pdf)
    • Các pdf cho một bài đánh giá khá tốt về cách thức hoạt động của heap, nhưng tập trung vào các kỹ thuật miễn phí kép.

tôi ban đầu đã cố gắng để khai thác mã này bằng cách điều chỉnh giá trị kích thước của đoạn cho inputC, do đó nó chỉ trở lại vào đầu của đoạn inputC. Khi điều đó không hiệu quả, tôi đã cố gắng chỉ trở lại phần đầu vàoB. Đó là khi tôi nhận ra rằng glibc mới thực hiện kiểm tra độ chính xác về giá trị kích thước.

Làm cách nào người dùng có thể khai thác để tận dụng miễn phí, giả sử anh có khả năng chỉnh sửa siêu dữ liệu của phân đoạn được phân bổ thành giá trị tùy ý và người dùng ghi đè giá trị trong GOT hoặc ghi vào bất kỳ địa chỉ tùy ý nào khác ?

Lưu ý: Khi tôi viết 'địa chỉ tùy ý', tôi hiểu rằng các trang bộ nhớ có thể chỉ đọc hoặc được bảo vệ, ý tôi là địa chỉ mà tôi có thể giả sử tôi có thể ghi vào.

+0

Bạn có thể làm rõ siêu dữ liệu nào bạn đang đề cập đến không? – ose

+0

Nhận kết quả có thể dự đoán được (chỉ đơn giản là đâm ứng dụng) ra khỏi một cuộc tấn công tràn bộ nhớ heap là hầu như không thể. Về cơ bản bạn cần phải biết thứ tự của các thứ trong đống, và đó là chỉ có thể dự đoán được trong một vài trường hợp hạn chế. Tốt nhất bạn có thể sử dụng một số loại "peek" chương trình để tìm thấy rằng bạn đang tìm kiếm, nhưng sau đó nó sẽ cần phải có một chữ ký đáng tin cậy "" để tìm kiếm. Trong trường hợp của bạn, bạn có thể tìm kiếm văn bản "Thực hiện thử thách để giành chiến thắng", nhưng thậm chí việc tìm kiếm văn bản đó cũng không giúp được gì nhiều vì nó có khả năng lưu trữ được bảo vệ. –

+0

@ tôi đã chỉnh sửa câu hỏi để làm cho nó rõ ràng hơn một chút. Tôi quan tâm đến việc sửa đổi siêu dữ liệu của đoạn được phân bổ (hoặc miễn phí, nếu có thể).Những thứ như kích thước, cờ A | M | P hoặc con trỏ tiến và lùi cho khi đoạn đó được hợp nhất. – amccormack

Trả lời

10

Lưu ý: Tôi sẽ nói trước khi tôi trả lời rằng đây hoàn toàn là câu trả lời học tập, không nhằm mục đích sử dụng cho mục đích độc hại. Tôi biết các bài tập mà OP đang làm và chúng là nguồn mở và không có ý định khuyến khích bất kỳ người dùng nào sử dụng các kỹ thuật này trong các trường hợp không được chấp thuận.

tôi sẽ nêu chi tiết kỹ thuật dưới đây nhưng để bạn tham khảo tôi sẽ xem xét các thủ thuật malloc Vudo (Nó tham chiếu trong một trong các liên kết của bạn ở trên) vì cái nhìn tổng quan của tôi sẽ là một đoạn ngắn một: http://www.phrack.com/issues.html?issue=57&id=8

Nó chi tiết cách malloc xử lý việc tạo khối bộ nhớ, kéo bộ nhớ từ danh sách và những thứ khác. Đặc biệt là cuộc tấn công unlink là mối quan tâm cho cuộc tấn công này (lưu ý: bạn đã chính xác rằng glibc bây giờ thực hiện kiểm tra sanity về kích thước cho lý do cụ thể này, nhưng bạn nên ở trên libc cũ cho bài tập này ... legacy bro).

Từ giấy, một khối được phân bổ và một khối miễn phí sử dụng cùng một cấu trúc dữ liệu, nhưng dữ liệu được xử lý khác nhau. Xem tại đây:

chunk -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
     | prev_size: size of the previous chunk, in bytes (used | 
     | by dlmalloc only if this previous chunk is free)  | 
     +---------------------------------------------------------+ 
     | size: size of the chunk (the number of bytes between | 
     | "chunk" and "nextchunk") and 2 bits status information | 
    mem -> +---------------------------------------------------------+ 
     | fd: not used by dlmalloc because "chunk" is allocated | 
     | (user data therefore starts here)      | 
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 
     | bk: not used by dlmalloc because "chunk" is allocated | 
     | (there may be user data here)       | 
     + - - - - - - - - - - - - - - - - - - - - - - - - - - - - + 
     |               | 
     |               | 
     | user data (may be 0 bytes long)       | 
     |               | 
     |               | 
next -> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 
     | prev_size: not used by dlmalloc because "chunk" is  | 
     | allocated (may hold user data, to decrease wastage)  | 
     +---------------------------------------------------------+ 

Khối phân bổ không sử dụng con trỏ fd hoặc bk, nhưng sẽ không có con trỏ tự do. Điều này sẽ quan trọng sau này.Bạn nên biết đủ lập trình để hiểu rằng "khối" trong malloc Doug Lea được tổ chức thành một danh sách liên kết gấp đôi; có một danh sách cho các khối miễn phí và một danh sách cho những người được phân bổ (về mặt kỹ thuật có một số danh sách miễn phí tùy thuộc vào kích thước nhưng nó không liên quan ở đây vì mã phân bổ các khối có cùng kích thước). Vì vậy, khi bạn đang giải phóng một khối cụ thể, bạn phải sửa các con trỏ để giữ cho danh sách không đổi.

ví dụ: nói rằng bạn đang giải phóng khối y khỏi danh sách bên dưới:

x <-> y <-> z 

Lưu ý rằng trong biểu đồ ở trên các điểm bk và fd chứa các con trỏ cần thiết để lặp lại trong danh sách. Khi malloc muốn mất một khối p tắt của danh sách mà họ gọi, trong số những thứ khác, một macro để sửa danh sách:

#define unlink(y, BK, FD) {    
    BK = P->bk;       
    FD = P->fd;       
    FD->bk = BK;       
    BK->fd = FD;       
} 

vĩ mô chính nó là không khó hiểu, nhưng điều quan trọng cần lưu ý trong phiên bản cũ hơn của libc là nó không thực hiện kiểm tra sanity trên kích thước hoặc con trỏ được ghi vào. Điều đó có nghĩa là trong trường hợp của bạn là không ngẫu nhiên địa chỉ bạn có thể dự đoán và xác định một cách đáng tin cậy trạng thái của heap và chuyển hướng con trỏ tùy ý đến địa chỉ bạn chọn bằng cách tràn đống (thông qua strncopy tại đây) theo cách cụ thể .

Có một vài điều cần thiết để có được những cuộc tấn công để làm việc:

  • con trỏ fd cho khối của bạn được trỏ đến địa chỉ mà bạn muốn ghi đè lên trừ 12 byte. Việc bù đắp đã làm với malloc làm sạch sự liên kết khi nó sửa đổi danh sách
  • Con trỏ bk của khối của bạn đang trỏ đến mã shell của bạn
  • Kích thước cần phải là -4. Điều này hoàn thành một vài điều, cụ thể là nó đặt các bit trạng thái trong khối

Vì vậy, bạn sẽ phải chơi với các khoảng trống trong ví dụ cụ thể của bạn, nhưng định dạng độc hại chung mà bạn đang cố gắng chuyển strcpy ở đây có định dạng:

| rác để lấp đầy bộ đệm hợp pháp | -4 | -4 | addr bạn muốn ghi đè -12 (0x0C) | addr bạn muốn gọi thay vì

Lưu ý số âm đặt trường prev_size thành -4, làm cho định tuyến miễn phí tin rằng đoạn prev_size thực sự bắt đầu trong đoạn hiện tại mà bạn kiểm soát/đang bị hỏng.

Và có, một lời giải thích thích hợp sẽ không hoàn thành nếu không đề cập đến cuộc tấn công này không hoạt động trên các phiên bản hiện tại của glibc; kích thước có một kiểm tra sanity thực hiện và phương pháp unlink chỉ sẽ không hoạt động. Điều đó kết hợp với các giảm nhẹ như ngẫu nhiên địa chỉ làm cho cuộc tấn công này không thể thực hiện được trên bất kỳ thứ gì ngoài các hệ thống kế thừa. Nhưng phương pháp được mô tả ở đây là cách tôi đã thử thách đó;)

+2

Như bạn đã nói cách tiếp cận này đã lỗi thời cho nhiều thứ. Chẳng hạn như kiểm tra sanity và giới thiệu nhiều đấu trường (do đó kích thước -4 sẽ không hoạt động). Nếu bạn biết tiếng Tây Ban Nha bạn có thể đọc một bài báo tôi đã phát triển giải thích tất cả những điều này và cách bạn có thể bỏ qua chúng bằng các phiên bản glibc hiện đại: http://overflowedminds.net/Papers/Newlog/linux_heap_exploiting_revisited.pdf Bạn có thể đọc một số trang trình bày bằng tiếng Anh tại đây : http://prezi.com/wcnbbokuousb/linux-heap-exploiting-revisited-en/?kw=view-wcnbbokuousb&rc=ref-2251669 – newlog

-2

Heap tràn là khó khăn để kéo ra, và phụ thuộc vào đống phụ thuộc rất nhiều, mặc dù có vẻ như bạn đang đi sau Windows CRT đống, trong đó có rất nhiều giảm nhẹ tại chỗ đặc biệt để ngăn chặn loại tấn công. Nếu bạn thực sự muốn làm điều này, bạn cần phải nhảy vào WinDbg và bước vào các chức năng như tự do để xem chính xác những gì đang diễn ra bên trong, và do đó bạn có thể kiểm soát được loại điều khiển nào đạt được thông qua tràn heap của giá trị trước đó.

Tôi sẽ không cung cấp cho bạn bất kỳ trợ giúp cụ thể nào hơn vì lý do đơn giản chứng minh tràn bộ nhớ thường đủ cho các chuyên gia bảo mật phòng thủ có thể báo cáo tràn bộ nhớ mà không cần khai thác triệt để nó. Những người duy nhất làm cần khai thác triệt để toàn bộ quá trình thực hiện mã từ xa là những người khai thác lỗi vi phạm và nếu bạn muốn làm điều đó, bạn sẽ tự thực hiện.

+3

Chương trình này được viết cho GNU/Linux và đang sử dụng glibc 2.11.2. Trong khi lợi ích của tôi là viết một khai thác hoàn toàn là học thuật, lý do tôi đã liên hệ với cộng đồng StackOverflow để được trợ giúp về vấn đề này là bởi vì bất kể hàng giờ tìm kiếm, tôi đã tìm thấy giải thích không đầy đủ về vấn đề này. Trong khi tôi đánh giá cao ý kiến ​​của bạn về các chuyên gia an ninh phòng thủ, tôi quan tâm đến việc hiểu cách thức hoạt động của cuộc tấn công này và không phải là chủ đề của các hoạt động và kỳ vọng chuyên nghiệp. – amccormack

3

Lưu ý rằng hầu hết các kỹ thuật được giải thích trong Malloc Malleficarum hiện được bảo vệ. Các glibc đã cải thiện rất nhiều tất cả các kịch bản miễn phí đôi.

Nếu bạn muốn cải thiện kiến ​​thức của bạn về kỹ thuật Malloc Malleficarum đọc Malloc Des-Malleficarum và House of Lore: Reloaded được viết bởi blackngel. Bạn có thể tìm thấy các văn bản này trong phrack.

Malloc Des-Malleficarum

Tôi cũng đang làm việc trên nó, và tôi có thể nói với bạn rằng, ví dụ, House of Tâm là không còn có thể khai thác, ít nhất, như được giải thích trong văn bản. Mặc dù có thể bỏ qua các hạn chế mới được thêm vào mã. Thêm rằng cách dễ nhất để thực thi mã của bạn là ghi đè địa chỉ .dtors do đó mã của bạn sẽ luôn được thực hiện sau khi chương trình kết thúc.

Nếu bạn tải xuống mã glibc và nghiên cứu các khu vực phê bình của malloc., V.v. bạn sẽ tìm thấy các kiểm tra mã không được ghi trong tài liệu đã đề cập trước đây. Những kiểm tra này đã được bao gồm để ngăn chặn các bên miễn phí đôi.

Mặt khác, trình bày của Justin N. Ferguson (Hiểu Heap bằng cách phá vỡ nó) mà bạn có thể tìm thấy trong youtube (BlackHat 2007) là hoàn hảo để hiểu tất cả các cơ chế heap, nhưng tôi phải thừa nhận rằng các kỹ thuật được hiển thị là xa đáng tin cậy, nhưng ít nhất, ông mở ra một lĩnh vực mới để khai thác đống.

Understanding the heap by breaking it

Anyways, tôi cũng đang làm việc trên nó, vì vậy nếu bạn muốn liên hệ với tôi, chúng tôi có thể chia sẻ những tiến bộ của chúng tôi. Bạn có thể liên hệ với tôi trong miền overflowedminds.net dưới dạng newlog (tự xây dựng địa chỉ email^^).