Buffer overflows typically represent one of the most common vulnerabilities that exist in today's software, and hackers can use malicious input to change the program's execution flow, thereby invading the corresponding process, computer, or entire domain. If the process runs under a highly trusted account, such as an administrator or a local system account, the damage caused by hackers will be extremely severe and potentially widespread. In recent years, some of the "well-known" viruses, such as red Code, Shock wave, shock waves, and so on, are derived from the C + + code buffer overflow results.
From a procedural point of view, a buffer overflow is simply a simple programming error--All about replicating the contents of one memory area to another, while the target memory area is too small to fit. The following code makes a simple demo:
char* source = "A reasonably long string";
char dest[10];
::strcpy(dest, source);
In this case, the length of the source string is 25 characters (including the null terminator), which is undoubtedly too large for the target memory block, and the target memory block is declared on the stack, and when this code executes, the original stack is destroyed, and the program crashes because of an access violation. If this source memory block is provided by an external third party, there is a possibility that a vulnerability exists because it allows the memory block passing in the function to modify the stack in a particular way.
When a function is called in C + +, the return address of the calling function is stored on the stack, so the execution process can return to its original place when the called function completes. If a function that might contain a potential buffer overflow is invoked, the return address may be modified and the execution process will jump to the location specified in the buffer data. By changing the return address of a function, an attacker can obtain code from anywhere in the process to execute, in general, and can be exploited mainly in two ways:
• If a vulnerable program is known and accessible, an attacker can find the address of a function, which is usually found at a fixed address of all process instances, and modifies the stack, waiting for the function to be invoked.
• The instruction to be executed can be passed as part of the buffer to the process address space, which is used by an attacker to complete the attack.
Guard against Buffer Overflow
The simplest way to guard against buffer overflows is to limit the size of replicated data so that it cannot be larger than the target buffer capacity. While this approach may seem trivial, in fact, experience has shown that it is a daunting task to completely eliminate the pitfalls of buffer overflows in those large, C + + code. In addition, use such as. Managed technologies such as NET or Java can significantly reduce the risk of buffer overflows, but porting large projects to this technology is unlikely and inappropriate.
A stack-based buffer overflow can be exploited so simply because the compiler-generated instruction stores the return address of the function on the stack, but realizes that the compiler plays only a small role in the problem. from Visual C + +. NET (7.0), the Visual C + + development team took the approach of reducing the probability of such problems from the compiler, by inserting a cookie with a given value under the data of the function return address in the stack, If the buffer overflow changes the return address value of the function, this cookie is also overwritten, and when the function returns, the cookie is typically instrumented, and if a cookie has been modified, a security exception is thrown, and if the exception is not processed, the process terminates. The following code demonstrates a simple program with a secure exception handling method:
void _cdecl sec_handler( int code, void *)
{
if ( code == _SECERR_BUFFER_OVERRUN )
{
printf("检测到一个缓冲区溢出。\n");
exit(1);
}
}
int main()
{
_set_security_error_handler( sec_handler );
//主程序代码在此省略。
}
Visual c++.net 2003 (7.1) enhances buffer overflow protection by moving vulnerable data structures-such as the address of an exception-handling method-to a location in the stack below the buffer. In the 7.0 version of the compiler, you can break the sensitive data between the buffer and the cookie. Bypassing the protection provided by the security cookie; however, in a new version of the compiler, the data has been moved to an area under the buffer, and now it seems unlikely that you would want to overflow by modifying the data.
Figure 1 illustrates the stack concept layout in C + + compilers 6, 7.0, and 7.1, and demonstrates that the stack grows from a high address to a low address space, which is also the direction in which the stack grows when the program executes. The downward growth of the stack is the main cause of the buffer overflow, because the overflow is overridden in a higher memory address space than the buffer, which is where the vulnerable data structure resides.
Figure 1: Stack logic layout
In addition to moving information such as exception handling to the data buffer in the stack, the Visual c++.net 2003 linker also places the address of the structured exception handling method in the header of the executable file. When an exception occurs, the operating system can examine the exception information address in the stack and conform to the exception handling method that is recorded in the header information, and the exception handling method will not execute if the situation does not match. For example, Windows Server 2003 can check for structured exception information, and this technology is also ported to Windows XP in service Pack 2.
and Visual C + + 2005 (8.0) is a step further on this basis, typically, when a function call occurs, if one of the local buffers is out of bounds, an attacker could overwrite anything on this stack, including exception handling, secure cookies, frame pointers, return addresses, and function arguments. Most of these values are protected by different mechanisms (such as safe exception handling), but there is still a chance of overflow for a function that has a function pointer as a parameter. If a function accepts a function pointer (or struct, class contains a function pointer) as an argument, it is possible for an attacker to overwrite the value in the pointer so that the code executes any function he wants. In view of this, the Visual C + + 2005 compiler analyzes all function parameters that may have this vulnerability and copies a function argument--without using the original function argument, and placing it under the local variable in the stack. If the original function parameter is overwritten, the entire function will not be breached as long as the value in the copy remains unchanged.