Exploiting stack buffer overflows[edit]The canonical method for exploi dịch - Exploiting stack buffer overflows[edit]The canonical method for exploi Việt làm thế nào để nói

Exploiting stack buffer overflows[e

Exploiting stack buffer overflows[edit]
The canonical method for exploiting a stack based buffer overflow is to overwrite the function return address with a pointer to attacker-controlled data (usually on the stack itself).[3][6] This is illustrated in the example below:

An example with strcpy
#include

void foo (char *bar)
{
char c[12];

strcpy(c, bar); // no bounds checking
}

int main (int argc, char **argv)
{
foo(argv[1]);
}
This code takes an argument from the command line and copies it to a local stack variable c. This works fine for command line arguments smaller than 12 characters (as you can see in figure B below). Any arguments larger than 11 characters long will result in corruption of the stack. (The maximum number of characters that is safe is one less than the size of the buffer here because in the C programming language strings are terminated by a zero byte character. A twelve-character input thus requires thirteen bytes to store, the input followed by the sentinel zero byte. The zero byte then ends up overwriting a memory location that's one byte beyond the end of the buffer.)

The program stack in foo() with various inputs

A. - Before data is copied.

B. - "hello" is the first command line argument.

C. - "A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​A​x08​x35​xC0​x80" is the first command line argument.
Notice in figure C above, when an argument larger than 11 bytes is supplied on the command line foo() overwrites local stack data, the saved frame pointer, and most importantly, the return address. When foo() returns it pops the return address off the stack and jumps to that address (i.e. starts executing instructions from that address). Thus, the attacker has overwritten the return address with a pointer to the stack buffer char c[12], which now contains attacker-supplied data. In an actual stack buffer overflow exploit the string of "A"'s would instead be shellcode suitable to the platform and desired function. If this program had special privileges (e.g. the SUID bit set to run as the superuser), then the attacker could use this vulnerability to gain superuser privileges on the affected machine.[3]

The attacker can also modify internal variable values to exploit some bugs. With this example:

#include
#include

void foo (char *bar)
{
float My_Float = 10.5; // Addr = 0x0023FF4C
char c[28]; // Addr = 0x0023FF30

// Will print 10.500000
printf("My Float value = %f
", My_Float);

/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Memory map:
@ : c allocated memory
# : My_Float allocated memory

*c *My_Float
0x0023FF30 0x0023FF4C
| |
@@@@@@@@@@@@@@@@@@@@@@@@@@@@#####
foo("my string is too long !!!!! XXXXX");

memcpy will put 0x1010C042 (little endian) in My_Float value.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

memcpy(c, bar, strlen(bar)); // no bounds checking...

// Will print 96.031372
printf("My Float value = %f
", My_Float);
}

int main (int argc, char **argv)
{
foo("my string is too long !!!!! x10x10xc0x42");
return 0;
}
Platform related differences[edit]
A number of platforms have subtle differences in their implementation of the call stack that can affect the way a stack buffer overflow exploit will work. Some machine architectures store the top level return address of the call stack in a register. This means that any overwritten return address will not be used until a later unwinding of the call stack. Another example of a machine specific detail that can affect the choice of exploitation techniques is the fact that most RISC style machine architectures will not allow unaligned access to memory.[7] Combined with a fixed length for machine opcodes this machine limitation can make the jump to ESP technique almost impossible to implement (with the one exception being when the program actually contains the unlikely code to explicitly jump to the stack register).[8][9]

Stacks that grow up[edit]
Within the topic of stack buffer overflows, an often discussed but rarely seen architecture is one in which the stack grows in the opposite direction. This change in architecture is frequently suggested as a solution to the stack buffer overflow problem because any overflow of a stack buffer that occurs within the same stack frame can not overwrite the return pointer. Further investigation of this claimed protection finds it to be a naive solution at best. Any overflow that occurs in a buffer from a previous stack frame will still overwrite a return pointer and allow for malicious exploitation of the bug.[10] For instance, in the example above, the return pointer for foo will not be overwritten because the overflow actually occurs within the stack frame for strcpy. However, because the buffer that overflows during the call to strcpy resides in a previous stack frame, the return pointer for strcpy will have a numerically higher memory address than the buffer. This means that instead of the return pointer for foo being overwritten, the return pointer for strcpy will be overwritten. At most this means that growing the stack in the opposite direction will change some details of how stack buffer overflows are exploitable, but it will not reduce significantly the number of exploitable bugs.

Protection schemes[edit]
Main article: Buffer overflow protection
Over the years a number of schemes have been developed to inhibit malicious stack buffer overflow exploitation. These may usually be classified into three categories:

Detect that a stack buffer overflow has occurred and thus prevent redirection of the instruction pointer to malicious code.
Prevent the execution of malicious code from the stack without directly detecting the stack buffer overflow.
Randomize the memory space such that finding executable code becomes unreliable.
Stack canaries[edit]
Stack canaries, named for their analogy to a canary in a coal mine, are used to detect a stack buffer overflow before execution of malicious code can occur. This method works by placing a small integer, the value of which is randomly chosen at program start, in memory just before the stack return pointer. Most buffer overflows overwrite memory from lower to higher memory addresses, so in order to overwrite the return pointer (and thus take control of the process) the canary value must also be overwritten. This value is checked to make sure it has not changed before a routine uses the return pointer on the stack.[2] This technique can greatly increase the difficulty of exploiting a stack buffer overflow because it forces the attacker to gain control of the instruction pointer by some non-traditional means such as corrupting other important variables on the stack.[2]

Further information: Canary value
Nonexecutable stack[edit]
Main article: Data Execution Prevention
Another approach to preventing stack buffer overflow exploitation is to enforce a memory policy on the stack memory region that disallows execution from the stack (W^X, "Write XOR Execute"). This means that in order to execute shellcode from the stack an attacker must either find a way to disable the execution protection from memory, or find a way to put her/his shellcode payload in a non-protected region of memory. This method is becoming more popular now that hardware support for the no-execute flag is available in most desktop processors.

While this method definitely makes the canonical approach to stack buffer overflow exploitation fail, it is not without its problems. First, it is common to find ways to store shellcode in unprotected memory regions like the heap, and so very little need change in the way of exploitation.[11]

Even if this were not so, there are other ways. The most damning is the so-called return to libc method for shellcode creation. In this attack the malicious payload will load the stack not with shellcode, but with a proper call stack so that execution is vectored to a chain of standard library calls, usually with the effect of disabling memory execute protections and allowing shellcode to run as normal.[12] This works because the execution never actually vectors to the stack itself.

A variant of return-to-libc is return-oriented programming, which sets up a series of return addresses, each of which executes a small sequence of cherry-picked machine instructions within the existing program code or system libraries, sequence which ends with a return. These so-called gadgets each accomplish some simple register manipulation or similar execution before returning, and stringing them together achieves the attacker's ends. It is even possible to use "returnless" return-oriented programming by exploiting instructions or groups of instructions that behave much like a return instruction.[13]

Randomization[edit]
Instead of separating the code from the data another mitigation technique is to introduce randomization to the memory space of the executing program. Since the attacker needs to determine where executable code that can be used resides, either an executable payload is provided (with an executable stack) or one is constructed using code reuse such as in ret2libc or ROP (Return Oriented Programming) randomizing the memory layout will as a concept prevent the attacker from knowing where any code is. However implementations typically will not randomize everything, usually the executable itself is loaded at a fixed address and hence even when ASLR (Address Space Layout Randomization) is combined with a nonexecutable stack the attacker can use this fixed region of memory. Therefore all programs should be compiled with PIE (position-independent executables) such that even this region of memory is randomized. The entropy of the randomization is different from implementation to implementation and a low e
0/5000
Từ: -
Sang: -
Kết quả (Việt) 1: [Sao chép]
Sao chép!
Khai thác ngăn xếp bộ đệm tràn [sửa]Phương pháp kinh điển cho khai thác lỗi tràn bộ đệm ngăn xếp dựa là ghi đè địa chỉ trả lại chức năng với một con trỏ đến kẻ tấn công kiểm soát dữ liệu (thường là vào ngăn xếp chính nó).[3][6] điều này được minh họa trong ví dụ dưới đây:Một ví dụ với strcpy#include void foo (char * bar){ Char c [12]; strcpy (c, bar); không có giới hạn kiểm tra} int chính (int argc, char ** argv){ foo(argv[1]);}Mã này cần một đối số từ dòng lệnh và sao chép nó vào một ngăn xếp địa phương biến c. Điều này hoạt động tốt cho đối số dòng lệnh nhỏ hơn 12 ký tự (như bạn có thể nhìn thấy trong hình B dưới đây). Bất kỳ đối số lớn hơn 11 ký tự dài sẽ dẫn đến tham nhũng của ngăn xếp. (Số ký tự tối đa là an toàn là một ít hơn so với kích thước của bộ đệm ở đây bởi vì trong dây ngôn ngữ lập trình được chấm dứt bằng một ký tự byte không. Một đầu vào mười hai ký tự như vậy đòi hỏi mười ba byte để lưu trữ, đầu vào theo sentinel byte không. Các byte không sau đó kết thúc lên ghi đè lên một vị trí bộ nhớ là một byte vượt ra ngoài sự kết thúc của bộ đệm.)Stack chương trình foo() với nhiều đầu vàoA. - trước khi dữ liệu được sao chép.Sinh - các "Xin chào" là đối số dòng lệnh đầu tiên.Kh - "một A A A A A A A A A A A A A A A A A A x08 x35 xC0 x80" là đối số dòng lệnh đầu tiên.Thông báo trong hình C ở trên, khi một cuộc tranh cãi lớn hơn 11 byte được cung cấp trên dòng lệnh foo() ghi đè dữ liệu ngăn xếp địa phương, đã lưu khung con trỏ, và quan trọng nhất, địa chỉ trả lại. Khi foo() trở về nó hiện địa chỉ trả lại ra ngăn xếp và nhảy đến địa chỉ đó (tức là bắt đầu thực hiện hướng dẫn từ địa chỉ đó). Do đó, kẻ tấn công đã ghi đè địa chỉ trả lại với một con trỏ đến ngăn xếp bộ đệm char c [12], mà bây giờ chứa kẻ tấn công cung cấp dữ liệu. Trong một khai thác lỗi tràn bộ đệm thực tế ngăn xếp chuỗi "A" của thay vào đó sẽ shellcode phù hợp với nền tảng và mong muốn chức năng. Nếu chương trình này có các đặc quyền đặc biệt (ví dụ như SUID bit thiết lập để chạy như là siêu người dùng), sau đó những kẻ tấn công có thể sử dụng lỗ hổng này để đạt được quyền siêu người dùng trên máy tính bị ảnh hưởng.[3]Những kẻ tấn công cũng có thể sửa đổi nội bộ thay đổi giá trị để khai thác một số lỗi. Với ví dụ này:#include #include void foo (char * bar){ nổi My_Float = 10,5; Địa chỉ = 0x0023FF4C Char c [28]; Địa chỉ = 0x0023FF30 Sẽ in 10.500000 printf ("My nổi giá trị = %f
", My_Float); /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Bản đồ bộ nhớ: @: c cấp phát bộ nhớ #: My_Float cấp phát bộ nhớ * c * My_Float 0x0023FF30 0x0023FF4C | | @@@@@@@@@@@@@@@@@@@@@@@@@@@@##### foo ("chuỗi của tôi là quá dài! XXXXX"); memcpy sẽ đặt 0x1010C042 (về cuối nhỏ) trong giá trị My_Float. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ memcpy (c, thanh, strlen(bar)); không có giới hạn kiểm tra... Sẽ in 96.031372 printf ("My nổi giá trị = %f
", My_Float);} int chính (int argc, char ** argv){ foo ("chuỗi của tôi là quá dài! x10x10xc0x42 "); trở về 0;}Nền tảng liên quan đến sự khác biệt [sửa]Một số nền tảng có sự khác biệt tinh tế trong thực hiện của ngăn xếp cuộc gọi có thể ảnh hưởng đến cách một khai thác lỗi tràn bộ đệm ngăn xếp sẽ làm việc. Một số kiến trúc máy tính lưu trữ địa chỉ trả lại cấp cao nhất của ngăn xếp cuộc gọi trong một đăng ký. Điều này có nghĩa rằng bất kỳ ghi đè địa chỉ trả lại sẽ không được sử dụng cho đến sau đó quấn cuộn của cuộc gọi stack. Một ví dụ khác của một máy cụ thể chi tiết mà có thể ảnh hưởng đến sự lựa chọn của kỹ thuật khai thác là một thực tế rằng hầu hết RISC phong cách kiến trúc máy sẽ không cho phép chiếm quyền truy cập vào bộ nhớ.[7] kết hợp với một chiều dài cố định cho máy mã này giới hạn máy có thể làm cho nhảy ESP kỹ thuật gần như không thể để thực hiện (với một ngoại lệ là khi chương trình thực sự có chứa mã không để nhảy một cách rõ ràng để đăng ký ngăn xếp).[8][9]Ngăn xếp lớn lên [sửa]Trong chủ đề của ngăn xếp tràn bộ đệm, một kiến trúc thường thảo luận nhưng hiếm khi là một trong đó ngăn xếp phát triển theo hướng đối diện. Sự thay đổi này trong kiến trúc thường xuyên được đề nghị như là một giải pháp cho vấn đề tràn bộ đệm ngăn xếp vì bất kỳ tràn của một bộ đệm ngăn xếp xảy ra trong cùng một ngăn xếp khung có thể không ghi đè lên con trỏ trở lại. Các điều tra thêm này bảo vệ tuyên bố tìm thấy nó là một giải pháp ngây thơ lúc tốt nhất. Bất kỳ tràn xảy ra trong một bộ đệm từ một khung stack trước vẫn sẽ ghi đè lên một con trỏ trở lại và cho phép cho khai thác độc hại của các lỗi.[10] Ví dụ, trong ví dụ trên, con trỏ trở lại cho foo sẽ không được ghi đè bởi vì tràn thực sự xảy ra trong khung stack cho strcpy. Tuy nhiên, bởi vì các bộ đệm tràn trong các cuộc gọi đến strcpy nằm trong một khung stack trước, con trỏ trở lại cho strcpy sẽ có một địa chỉ bộ nhớ số lượng cao hơn bộ đệm. Điều này có nghĩa rằng thay vì con trỏ trở lại cho foo được ghi đè, con trỏ trở lại cho strcpy sẽ được ghi đè. Nhất điều này có nghĩa rằng ngày càng tăng ngăn xếp theo hướng đối diện sẽ thay đổi một số chi tiết về làm thế nào ngăn xếp bộ đệm tràn được khai thác, nhưng nó sẽ không làm giảm đáng kể số lượng khai thác lỗi.Chương trình bảo vệ [sửa]Bài chi tiết: bộ đệm tràn bảo vệTrong những năm qua một số đề án đã được phát triển để ức chế độc hại ngăn xếp khai thác lỗi tràn bộ đệm. Chúng thường có thể được phân thành ba loại:Phát hiện rằng một lỗi tràn bộ đệm ngăn xếp đã xảy ra và do đó ngăn chặn chuyển hướng của con trỏ hướng dẫn đến mã độc hại.Ngăn chặn việc thực hiện các mã độc hại từ các ngăn xếp mà không trực tiếp phát hiện lỗi tràn bộ đệm ngăn xếp.Ngẫu nhiên không gian bộ nhớ như vậy mà tìm thực thi mã trở nên không đáng tin cậy.Chim hoàng yến ngăn xếp [sửa]Ngăn xếp chim hoàng yến, đặt theo tên của họ tương tự để một canary tại mỏ than, được sử dụng để phát hiện một lỗi tràn bộ đệm ngăn xếp trước khi thực hiện các mã độc hại có thể xảy ra. Phương pháp này hoạt động bằng cách đặt một số nguyên nhỏ, giá trị trong đó chọn ngẫu nhiên bắt đầu chương trình, trong bộ nhớ ngay trước khi con trỏ trở lại ngăn xếp. Hầu hết các tràn bộ đệm ghi đè lên các bộ nhớ từ thấp đến cao hơn bộ nhớ địa chỉ, do đó, để ghi đè lên con trỏ trở lại (và do đó kiểm soát của quá trình) giá trị canary phải cũng được ghi đè. Giá trị này được kiểm tra để đảm bảo rằng nó đã không thay đổi trước khi một thói quen sử dụng con trỏ trở lại vào ngăn xếp.[2] kỹ thuật này đáng kể có thể làm tăng khó khăn trong việc khai thác lỗi tràn bộ đệm ngăn xếp vì nó buộc kẻ tấn công để giành quyền kiểm soát của con trỏ hướng dẫn bởi một số phương tiện phòng không truyền thống như corrupting biến quan trọng khác vào ngăn xếp.[2]Xem thêm thông tin: Canary giá trịNgăn xếp nonexecutable [sửa]Bài chi tiết: ngăn cản thực thi dữ liệuMột cách tiếp cận đến việc phòng chống khai thác lỗi tràn bộ đệm ngăn xếp là để thực hiện một chính sách bộ nhớ trên vùng bộ nhớ ngăn xếp mà không cho phép thực hiện từ ngăn xếp (W ^ X, "Viết XOR Execute"). Điều này có nghĩa là để thực hiện shellcode từ ngăn xếp một kẻ tấn công phải hoặc tìm một cách để vô hiệu hóa bảo vệ thực hiện từ bộ nhớ, hoặc tìm một cách để đưa cô tải trọng shellcode trong một khu vực bảo vệ phòng không của bộ nhớ. Phương pháp này đang trở nên phổ biến hơn bây giờ mà hỗ trợ phần cứng cho cờ no-execute là có sẵn trong hầu hết các bộ vi xử lý máy tính để bàn.Trong khi phương pháp này chắc chắn làm cho phương pháp tiếp cận kinh điển để ngăn xếp thất bại khai thác lỗi tràn bộ đệm, nó không phải là không có vấn đề của nó. Đầu tiên, nó là phổ biến để tìm cách để lưu trữ shellcode trong khu vực bộ nhớ không được bảo vệ như heap, và vì vậy rất ít cần sự thay đổi trong cách của khai thác.[11]Ngay cả nếu điều này là không phải như vậy, có những cách khác. Tổn thương nhất là cái gọi là quay trở lại libc phương pháp để shellcode tạo. Trong cuộc tấn công này trọng độc hại sẽ tải ngăn xếp không với shellcode, nhưng với một cuộc gọi đúng ngăn xếp để thực hiện trán để một chuỗi thư viện chuẩn cuộc gọi, thường với các hiệu ứng của vô hiệu hóa bộ nhớ thực hiện bảo vệ và cho phép shellcode để chạy như bình thường.[12] điều này hoạt động vì thực hiện không bao giờ thực sự vector để ngăn xếp chính nó.Một biến thể của trở lại libc là theo định hướng trở về lập trình, trong đó thiết lập một loạt các trở lại địa chỉ, mỗi trong số đó thực hiện một chuỗi nhỏ của anh đào đã chọn máy hướng dẫn trong các hiện có chương trình mã hoặc hệ thống thư viện, trình tự mà kết thúc với sự quay trở lại. Những cái gọi là tiện ích mỗi thực hiện một số thao tác đơn giản đăng ký hoặc thực hiện tương tự như trước khi trở về, và stringing chúng với nhau đạt được kết thúc của kẻ tấn công. Ta thậm chí có thể sử dụng "returnless" lập trình theo định hướng trở lại bằng cách khai thác hướng dẫn hoặc nhóm hướng dẫn cư xử giống như một hướng dẫn trở lại.[13]Ngẫu nhiên [sửa]Thay vì tách mã từ các dữ liệu kỹ thuật giảm nhẹ khác là để giới thiệu ngẫu nhiên với không gian bộ nhớ của chương trình executing. Kể từ khi những kẻ tấn công phải xác định nơi cư trú của mã thực thi có thể được sử dụng, hoặc là một tải trọng thực thi được cung cấp (với một ngăn xếp thực thi) hoặc một được xây dựng bằng cách sử dụng mã tái sử dụng, chẳng hạn như trong ret2libc hoặc ROP (trở về hướng lập trình) randomizing bố trí bộ nhớ sẽ là một khái niệm ngăn chặn kẻ tấn công từ biết bất kỳ mã ở đâu. Tuy nhiên việc triển khai thông thường sẽ không ngẫu nhiên tất cả mọi thứ, thông thường tập tin thực thi chính nó được nạp tại một địa chỉ cố định và do đó ngay cả khi ASLR (địa chỉ Space giao diện ngẫu nhiên) kết hợp với một chồng nonexecutable những kẻ tấn công có thể sử dụng khu vực cố định này của bộ nhớ. Do đó tất cả chương trình nên được biên soạn với bánh (vị trí độc lập thực thi) như vậy mà ngay cả khu vực này của bộ nhớ ngẫu nhiên. Entropy của ngẫu nhiên là khác nhau từ thực hiện để thực hiện và một e thấp
đang được dịch, vui lòng đợi..
Kết quả (Việt) 2:[Sao chép]
Sao chép!
Khai thác ngăn xếp lỗi tràn bộ đệm [sửa]
Phương pháp kinh điển cho việc khai thác một chồng dựa tràn bộ đệm là để ghi đè lên địa chỉ trả lại chức năng với một con trỏ để kẻ tấn công kiểm soát dữ liệu (thường là trên stack chính nó). [3] [6] Điều này được minh họa trong ví dụ dưới đây: Ví dụ với strcpy #include




void foo (char * bar)
{
char c [12]; strcpy (c, quán bar); // Không có giới hạn kiểm tra } int main (int argc, char ** argv) { foo (argv [1]); } Đoạn mã này có một đối số từ dòng lệnh và sao chép nó vào một địa phương ngăn xếp biến c. Này làm việc tốt cho các đối số dòng lệnh nhỏ hơn 12 ký tự (như bạn có thể thấy trong hình B bên dưới). Bất kỳ đối số lớn hơn 11 ký tự dài sẽ dẫn đến tham nhũng của stack. (Số lượng tối đa của nhân vật đó là an toàn là một trong ít hơn kích thước của bộ đệm ở đây bởi vì trong lập trình C chuỗi ngôn ngữ được chấm dứt bởi một nhân vật không byte. Một đầu vào mười hai ký tự do đó đòi hỏi mười ba byte để lưu trữ, đầu vào tiếp theo các byte trọng điểm zero. Các byte không kết thúc sau đó ghi đè lên một vị trí bộ nhớ đó là một byte vượt ra ngoài cuối của bộ đệm.) Các chương trình ngăn xếp trong foo () với các đầu vào khác nhau A. -. Trước khi dữ liệu được sao chép B. - "Hello" là đối số dòng lệnh đầu tiên. C. - là đối số dòng lệnh đầu tiên. Lưu ý trong hình C ở trên, khi một cuộc tranh cãi lớn hơn 11 byte được cung cấp trên dòng lệnh foo () ghi đè dữ liệu địa phương stack, con trỏ khung lưu, và quan trọng nhất, địa chỉ trả lại. Khi foo () trả về nó hiện ra địa chỉ trở lại ra khỏi ngăn xếp và nhảy đến địa chỉ đó (tức là bắt đầu thực hiện những lệnh từ địa chỉ đó). Do đó, kẻ tấn công đã ghi đè địa chỉ trở lại với một con trỏ để ngăn xếp đệm char c [12], mà bây giờ chứa dữ liệu kẻ tấn công cung cấp. Trong một tràn bộ đệm thực tế khai thác chuỗi "A" 's thay vào đó sẽ là shellcode phù hợp với nền tảng và chức năng mong muốn. Nếu chương trình này có ưu đãi đặc biệt (ví dụ như bit SUID được thiết lập để chạy như superuser), sau đó những kẻ tấn công có thể sử dụng lỗ hổng này để đạt được các đặc quyền superuser trên máy tính bị ảnh hưởng. [3] Những kẻ tấn công cũng có thể thay đổi giá trị biến nội bộ để khai thác một số lỗi . Với ví dụ này: #include






















#include

void foo (char * bar)
{
nổi My_Float = 10,5; // Địa chỉ = 0x0023FF4C
char c [28]; // Địa chỉ = 0x0023FF30 // Sẽ in 10,500000 printf ("giá trị nổi của tôi =% f n", My_Float); / * ~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ bản đồ bộ nhớ: @: c cấp phát bộ nhớ #: My_Float cấp phát bộ nhớ * c * My_Float 0x0023FF30 0x0023FF4C | | @@@@@@@@@@@@@@@@@@@@@@@@@@##### foo ("chuỗi của tôi quá dài !!!!! XXXXX") ; memcpy sẽ đặt 0x1010C042 (về cuối nhỏ) trong My_Float giá trị. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~ * / memcpy (c, bar, strlen (bar)); // Không có giới hạn kiểm tra ... // Sẽ in 96.031372 printf ("My giá trị Float =% f n", My_Float); } int main (int argc, char ** argv) { foo ("chuỗi của tôi quá dài !!!!! x10 x10 xc0 x42 "); return 0; } khác biệt Platform liên quan [sửa] Một số nền tảng có sự khác biệt tinh tế trong việc thực hiện các cuộc gọi stack có thể ảnh hưởng đến cách một tràn bộ đệm khai thác sẽ làm việc. Một số kiến trúc máy tính lưu trữ các địa chỉ trở lại mức đỉnh của stack trong một đăng ký. Điều này có nghĩa rằng bất kỳ địa chỉ trả lại ghi đè sẽ không được sử dụng cho đến khi thư giãn sau của cuộc gọi stack. Một ví dụ khác của một chi tiết cụ thể máy có thể ảnh hưởng đến sự lựa chọn của các kỹ thuật khai thác là một thực tế rằng hầu hết các phong cách kiến trúc RISC máy sẽ không cho phép truy cập unaligned vào bộ nhớ. [7] Kết hợp với một chiều dài cố định cho các opcodes máy hạn chế máy tính này có thể thực hiện chuyển để ESP kỹ thuật hầu như không thể thực hiện (với một ngoại lệ là khi chương trình thực sự chứa mã không để nhảy một cách rõ ràng để ngăn xếp đăng ký). [8] [9] Stacks rằng lớn lên [sửa] Trong chủ đề của stack tràn bộ đệm , một kiến trúc thường được thảo luận nhưng hiếm thấy là một trong đó ngăn xếp phát triển theo hướng ngược lại. Thay đổi trong kiến trúc này thường được đề xuất như là một giải pháp cho vấn đề tràn bộ đệm bởi vì bất kỳ tràn của một chồng đệm xảy ra trong stack frame cùng không thể ghi đè lên con trỏ trở lại. Tiếp tục điều tra của bảo vệ tuyên bố này tìm thấy nó là một giải pháp ngây thơ lúc tốt nhất. Bất kỳ tràn xảy ra trong một bộ đệm từ một stack frame trước đó vẫn sẽ ghi đè lên một con trỏ trở lại và cho phép khai thác nguy hiểm của lỗi này. [10] Ví dụ, trong ví dụ trên, con trỏ trở lại cho foo sẽ không được ghi đè bởi vì tràn thực sự xảy ra trong khung stack cho strcpy. Tuy nhiên, do bộ đệm mà tràn trong các cuộc gọi đến cư trú strcpy trong một stack frame trước đó, con trỏ trở lại cho strcpy sẽ có một địa chỉ bộ nhớ số lượng cao hơn so với bộ đệm. Điều này có nghĩa rằng thay vì con trỏ trở lại cho foo được ghi đè, con trỏ trở lại cho strcpy sẽ được ghi đè. Tại hầu hết các này có nghĩa là phát triển các ngăn xếp theo hướng ngược lại sẽ thay đổi một số chi tiết về cách thức ngăn xếp tràn bộ đệm là khai thác được, nhưng nó sẽ không làm giảm đáng kể số lượng các lỗi có thể khai thác. Bảo vệ các chương trình [sửa] Bài chi tiết: Buffer overflow bảo vệ Trong những năm qua một số đề án đã được phát triển để ngăn chặn khai thác tràn bộ đệm độc hại. Chúng thường có thể được phân loại thành ba loại: Phát hiện một tràn bộ đệm đã xảy ra và do đó ngăn chặn chuyển hướng của con trỏ hướng dẫn để mã độc. Ngăn chặn việc thực thi mã độc từ ngăn xếp mà không cần trực tiếp phát hiện tràn bộ đệm. Chọn ngẫu nhiên không gian bộ nhớ như vậy mà việc tìm kiếm mã thực thi trở nên không đáng tin cậy. Ngăn xếp chim hoàng yến [sửa] stack chim hoàng yến, được đặt tên tương tự của họ đến một con chim hoàng yến trong mỏ than, được sử dụng để phát hiện một tràn bộ đệm trước khi thực hiện các mã độc hại có thể xảy ra. Phương pháp này hoạt động bằng cách đặt một số nguyên nhỏ, giá trị được lựa chọn ngẫu nhiên tại chương trình bắt đầu, trong bộ nhớ ngay trước khi con trỏ ngăn xếp trở lại. Hầu hết các lỗi tràn bộ đệm ghi đè lên bộ nhớ từ thấp đến địa chỉ bộ nhớ cao hơn, do đó, để ghi đè lên con trỏ trở lại (và do đó kiểm soát quá trình) giá trị con chim hoàng yến cũng phải được ghi đè. Giá trị này được kiểm tra để chắc chắn rằng nó đã không thay đổi trước khi một thói quen sử dụng con trỏ trở lại trên stack. [2] Kỹ thuật này rất có thể làm tăng sự khó khăn của việc khai thác một tràn bộ đệm bởi vì nó buộc những kẻ tấn công giành quyền kiểm soát con trỏ chỉ dẫn bởi một số phương tiện phi truyền thống như làm hư biến quan trọng khác trên stack [2]. Thông tin thêm: giá trị Canary Nonexecutable chồng [sửa] Bài chi tiết: Data Execution Prevention Một cách khác để ngăn chặn khai thác lỗi tràn bộ đệm ngăn xếp là để thực thi một chính sách bộ nhớ trên các khu vực bộ nhớ ngăn xếp không cho phép thực hiện từ stack (W ^ X, "Viết XOR Thực hiện"). Điều này có nghĩa rằng để thực hiện shellcode từ stack kẻ tấn công phải thể tìm thấy một cách để vô hiệu hóa bảo vệ thực hiện từ bộ nhớ, hoặc tìm một cách để đưa cô ấy / tải trọng shellcode của mình trong một khu vực không được bảo vệ bộ nhớ. Phương pháp này đang trở nên phổ biến hơn bây giờ mà hỗ trợ phần cứng cho không thực hiện lá cờ là có sẵn trong hầu hết các bộ vi xử lý máy tính để bàn. Trong khi phương pháp này chắc chắn sẽ khiến các phương pháp kinh điển để ngăn xếp khai thác lỗi tràn bộ đệm không, nó không phải là không có vấn đề của nó. Đầu tiên, người ta thường tìm cách để lưu trữ shellcode trong vùng bộ nhớ được bảo vệ như đống, và do đó rất ít thay đổi cần thiết trong cách khai thác. [11] Ngay cả nếu điều này là không phải như vậy, có những cách khác. Các tổn thương nhất là cái gọi là trở lại với phương pháp libc để tạo shellcode. Trong cuộc tấn công này payload độc hại sẽ được tải stack không phải với shellcode, nhưng với một cuộc gọi stack thích hợp để thực hiện được vectored đến một chuỗi các cuộc gọi thư viện chuẩn, thường là với các hiệu ứng vô hiệu hóa bộ nhớ thực hiện bảo vệ và cho phép shellcode để chạy như bình thường. [12] Điều này làm việc vì việc thực hiện không bao giờ thực sự vector vào stack chính nó. Một biến thể của trở lại-to-libc là trở về lập trình hướng, trong đó thiết lập một loạt các địa chỉ trở lại, mỗi trong số đó thực hiện một dãy nhỏ của anh đào hái hướng dẫn máy trong mã hiện chương trình hoặc hệ thống thư viện, trình tự mà kết thúc với sự trở lại. Những cái gọi là mỗi tiện ích thực hiện một số thao tác đăng ký đơn giản hoặc thực hiện tương tự như trước khi trở về, và xâu chuỗi chúng lại với nhau đạt được mục đích của kẻ tấn công. Nó thậm chí có thể sử dụng "returnless" lập trình lại theo định hướng bằng cách khai thác hướng dẫn hoặc nhóm các hướng dẫn mà cư xử giống như một hướng dẫn trở lại. [13] ngẫu nhiên [sửa] Thay vì tách mã từ các dữ liệu kỹ thuật giảm nhẹ khác được giới thiệu ngẫu nhiên để không gian bộ nhớ của chương trình thực hiện. Kể từ khi những kẻ tấn công cần phải xác định mã nơi thực thi mà có thể được sử dụng cư trú, hoặc một tải trọng thực thi được cung cấp (với một đống thực thi) hoặc một được xây dựng sử dụng tái sử dụng mã như trong ret2libc hoặc ROP (Return Oriented Programming) ngẫu nhiên bố trí bộ nhớ sẽ là một khái niệm ngăn chặn sự tấn công từ biết nơi nào đang. Tuy nhiên việc triển khai thường sẽ không ngẫu nhiên tất cả mọi thứ, thường là thực thi chính nó được nạp tại một địa chỉ cố định và do đó ngay cả khi ASLR (Address Space Layout Randomization) được kết hợp với một chồng nonexecutable kẻ tấn công có thể sử dụng cố định vùng bộ nhớ này. Do đó tất cả các chương trình cần được biên soạn với PIE (file thực thi độc lập vị trí) như vậy mà ngay cả khu vực này của bộ nhớ là ngẫu nhiên. Entropy của ngẫu nhiên là khác nhau từ việc thực hiện để thực hiện và một e thấp

























































đang được dịch, vui lòng đợi..
 
Các ngôn ngữ khác
Hỗ trợ công cụ dịch thuật: Albania, Amharic, Anh, Armenia, Azerbaijan, Ba Lan, Ba Tư, Bantu, Basque, Belarus, Bengal, Bosnia, Bulgaria, Bồ Đào Nha, Catalan, Cebuano, Chichewa, Corsi, Creole (Haiti), Croatia, Do Thái, Estonia, Filipino, Frisia, Gael Scotland, Galicia, George, Gujarat, Hausa, Hawaii, Hindi, Hmong, Hungary, Hy Lạp, Hà Lan, Hà Lan (Nam Phi), Hàn, Iceland, Igbo, Ireland, Java, Kannada, Kazakh, Khmer, Kinyarwanda, Klingon, Kurd, Kyrgyz, Latinh, Latvia, Litva, Luxembourg, Lào, Macedonia, Malagasy, Malayalam, Malta, Maori, Marathi, Myanmar, Mã Lai, Mông Cổ, Na Uy, Nepal, Nga, Nhật, Odia (Oriya), Pashto, Pháp, Phát hiện ngôn ngữ, Phần Lan, Punjab, Quốc tế ngữ, Rumani, Samoa, Serbia, Sesotho, Shona, Sindhi, Sinhala, Slovak, Slovenia, Somali, Sunda, Swahili, Séc, Tajik, Tamil, Tatar, Telugu, Thái, Thổ Nhĩ Kỳ, Thụy Điển, Tiếng Indonesia, Tiếng Ý, Trung, Trung (Phồn thể), Turkmen, Tây Ban Nha, Ukraina, Urdu, Uyghur, Uzbek, Việt, Xứ Wales, Yiddish, Yoruba, Zulu, Đan Mạch, Đức, Ả Rập, dịch ngôn ngữ.

Copyright ©2024 I Love Translation. All reserved.

E-mail: