1. Overview: http://blog.csdn.net/chengyun_chu/article/details/4644227
In the previous security coding practices, we introduced the GS compilation options, cache overflow, and data protection dep. First, the direct consequence of cache overflow is remote execution of malicious code, so the compiler provides GS protection. However, the GS option has its own limitations, and there are several ways to bypass the protection of the GS option. Therefore, the operating system provides Data Execution Protection, that is, DEP, and the corresponding nxcompat compilation options.
So now we can rest assured? In the security field, System Attack and Defense is a process of continuous development and evolution. After Dep was proposed, there was a ret2libc attack against dep. This is a simple reference at the end of DEP's security coding practices article.
Aslr (address space layout randomization) is another important security feature used to prevent ret2libc attacks. So what is the ret2libc attack, what is the aslr principle, and how developers use this security feature is what we will discuss in this article.
2. Dep and ret2libc attacks
2.1 Dep protection of Stack Overflow
In the stack overflow introduction, we mentioned the function STACK layout in the Windows architecture (from high to low) as follows:
Call Parameters |
Return address |
Base Address of the upper layer function stack of EBP |
Exception Handling Code entry address (If function settings handle exceptions) |
Local variable |
Table 1: function stack structure in Windows
In case of stack overflow, malicious code overwrites local variables on the stack to modify the return address of the function, resulting in malicious code execution. The following is a typical example of the stack structure of this type of attacks.
Call Parameters |
Overwrite-> |
Malicious Code |
Return address |
Malicious code entry address |
Base Address of the upper layer function stack of EBP |
Overflow variables overwrite the region, usually including the necessary padding bytes. |
Exception Handling Code entry address (If function settings handle exceptions) |
Local variable |
Table 2: stack structure during Stack Overflow
When the DEP protection mechanism is used, because the malicious code is stored on the system data page (stack page), when the function returns, the instruction register EIP will jump to the malicious code entry address. In this case, the page is non-executable, so Dep triggers a system exception and causes the program to stop.
2.2 ret2libc attack
In the preceding Dep protection mechanism, we can see that the key is that when the EIP jumps to the non-executable page when the function returns, it is detected by dep. The ret2libc attack principle is that the return address of the function set by the attacker does not directly point to malicious code, but to the entry address of an existing system function. Because the page permission of the system function is executable, the DEP exception is not triggered.
So, should attackers direct the EIP to the special system entry function? In a UNIX system, libc is a shared dynamic C execution library with many useful functions, such as system functions. It is defined as follows:
INT system (const char * string );
Function System () can execute other programs through the running environment, such as starting a shell. Then, attackers can construct the following stack structure [1 ]:
Call Parameters |
Overwrite-> |
/Bin/sh |
False return address |
Return address |
System Function entry address |
Base Address of the upper layer function stack of EBP |
Overflow variables overwrite the region, usually including the necessary padding bytes. |
Exception Handling Code entry address (If function settings handle exceptions) |
Local variable |
Table 3: ret2libc attack stack structure
In this way, when a function with Stack Overflow returns, the EIP jumps to the system function. Because the system function itself is executable, there will be no Dep exception. Attackers can initiate other programs by constructing system function call parameters. In the attack process, the key is to return the function to the libc library (return to libc), which is the reason for the ret2libc name.
Careful readers may have discovered that no malicious code is inserted in table 3. Although attackers can execute many sensitive operations through system or other system functions, they still want to execute their own customized malicious code in most cases. How can we achieve this? So on the basis of the initial ret2libc attack method, we developed a method specifically for Windows system attacks. It uses the virtualprotect function to modify the execution permission of the memory page where the malicious code is located, and then transfer the control to the malicious code.
Virtualprotect is a function provided by kernel32.dll in windows. Its function is to modify the protection permission for the memory area of the virtual address space where the calling process is located. It is defined as follows:
Bool winapi virtualprotect (
_ In lpvoid lpaddress,
_ In size_t dwsize,
_ In DWORD flnewprotect,
_ Out pdword lpfloldprotect
);
Attackers construct the following stack structure [2] to call virtualprotect:
Call Parameters |
Overwrite-> |
Malicious Code |
Lpfloldprotect Value |
Set executable permission Parameters |
Malicious code page size |
Base Address of the memory page where the malicious code is located |
Malicious code entry address |
Return address |
Entry address of the virtualprotect Function |
Base Address of the upper layer function stack of EBP |
Overflow variables overwrite the region, usually including the necessary padding bytes. |
Exception Handling Code entry address (If function settings handle exceptions) |
Local variable |
Table 4: stack structure attacked by virtualprotect
First, when a function with Stack Overflow returns, the EIP jumps to the virtualprotect function. Note that the attacker specially constructs the entry address of malicious code as the return address when the virtualprotect function exits. During the execution of virtualprotect, the page where the malicious code is located is modified to the executable permission, so when virtualprotect returns, the EIP jumps to the malicious code and no Dep exception is triggered.
In addition to the virtualprotect function, attackers can also use other functions, such as ntsetinformationprocess.
3. aslr and/dynamicbase link options
In the introduction to the ret2libc attack method, we can see that the most important thing is that the attacker knows the specific function in advance, such as the system or virtualprotect entry address. On Windows XP or Windows 2000, the entry addresses of these functions are fixed, that is, the attacker can determine in advance.
The aslr security feature is introduced in Windows Vista. The principle is that when an application or dynamic link library, such as kernel32.dll, is loaded, if it is selected to be protected by aslr, then the system randomly sets the base address it loads. In this way, attackers cannot predict the dynamic library in advance, such as the base address of kernel32.dll, and thus cannot determine the entry address of a specific function, such as virtualprotect.
Aslr is a system-level feature. The system dynamic library, such as kernel32.dll, is randomly set at each startup of the system.
The following is a simplified aslr demo [3 ].
// Aslr. cpp: Demo the dynamic base of DLLs due to aslr
//
# Include "stdafx. H"
# Include <windows. h>
# Include <stdio. h>
Void Foo (void)
{
Printf ("Address of function Foo = % P/N", foo );
}
Int _ tmain (INT argc, _ tchar * argv [])
{
Hmodule hmod = loadlibrary (L "kernel32.dll ");
// Note-this is for release builds
Hmodule hmodmsvc = loadlibrary (L "msvcr90.dll ");
Void * pvaddress = getprocaddress (hmod, "loadlibraryw ");
Printf ("Kernel32 loaded at % P/N", hmod );
Printf ("Address of loadlibrary = % P/N", pvaddress );
Pvaddress = getprocaddress (hmodmsvc, "system ");
Printf ("msvcr90.dll loaded at % P/N", hmodmsvc );
Printf ("Address of system function = % P/N", pvaddress );
Foo ();
If (hmod) freelibrary (hmod );
If (hmodmsvc) freelibrary (hmodmsvc );
Return 0;
}
The purpose of this program is to output the base address of kerner32.dll and msvcr90.dll, the entry address of loadlibrary and system functions, and the entry address of a function Foo () of the application itself.
It is very easy to use aslr. The/dynamicbase link option has been added since Visual Studio 2005 SP1. The/dynamicbase option can be set through project property-> Configuration properties-> linker-> advanced-> randomized base address, or directly modify the linker command line compilation option. See.
Figure 1:/dynamicbase link option Configuration
In the Visual Studio 2008 environment, use the Win32 console application type to compile and link the demo program. NOTE: If Visual Studio 2005 SP1 is used, change msvcr90.dll to msvcr80.dll.
If the program does not use the aslr function, run it in Windows Vista. The output result is:
Kernel32 loaded at 763f0000
Address of loadlibrary = 7641361f
Msvcr90.dll loaded at 671f0000
Address of system function = 6721c88b
Address of function fool = 00401800
Restart the system
Kernel32 loaded at 76320000
Address of loadlibrary = 7634361f
Msvcr90.dll loaded at 6a340000
Address of system function = 6a36c88b
Address of function fool = 00401800
We can see that even if the program itself does not use aslr, the loading address of kernel32.dll and msvcr90.dll has also changed. This is because both databases have been protected by aslr. However, the address of the Foo () function of the application itself is fixed.
If the program uses the aslr function, it runs in Windows Vista. The output result is:
Kernel32 loaded at 763f0000
Address of loadlibrary = 7641361f
Msvcr90.dll loaded at 671f0000
Address of system function = 6721c88b
Address of function Foo = 003b1800
Restart the system
Kernel32 loaded at 76320000
Address of loadlibrary = 7634361f
Msvcr90.dll loaded at 697a0000
Address of system function = 697cc88b
Address of function fool = 00871800
The loading address of the application's own function Foo () also changes with the system restart. That is, once the/dynamicbase option is used, the generated program will be protected by the aslr Mechanism during runtime.
4. Limitations of aslr
First, aslr security features are only implemented in Windows Vista and later Windows versions (such as Windows Server 2008.
Second,
Aslr must be used with dep. If the CPU does not provide hardware support for DEP, or the application is not protected by DEP, once malicious code can be executed, the program access table structure can be used to obtain the loading base address of a specific DLL.
Performance and
CompatibilityFor example,
The implementation of aslr has been taken into consideration, and there is not much impact. One example is Microsoft Office 2007. Office 2007 programs fully use the aslr function and have not found anyPerformance and
Compatibility has a huge impact [4]。
5. Summary
Aslr security features are implemented in Windows Vista and later Windows versions (such as Windows Server 2008. It can prevent Dep attacks based on ret2libc. The combination of aslr and Dep can effectively prevent attackers from running malicious code on the stack. It is recommended that developers use the/dynamicbase link option to enable the aslr function for the developed application or dynamic link library.
6. References
Bypassing non-executable-stack during exploitation using Return-to-libc, http://www.infosecwriters.com/text_resources/pdf/return-to-libc.pdf,c0ntex
[2]A brief history of exploitation Techniques & mitigations on windows,
Http://hick.org /~ Mmiller/presentations/MISC/exploitation_techniques_and_mitigations_on_windows.pdf,Matt Miller
[3] writing secure code for Windows Vista, Michael Howard, David Leblanc
[4] use of aslr, NX, etc, http://blogs.msdn.com/david_leblanc/archive/2008/03/14/use-of-aslr-nx-etc.aspx,David Leblanc