Research on Security cookie stack protection
06.10 by flyingkisser
Here we mainly discuss the stack, not the heap.
First, security cookie is not a built-in protection mechanism in windows, not to say that a vulnerability exists.
And put it in an environment protected by security cookies.
So what is security cookie?
I think in a broad sense, it should be a mechanism to protect stacks. What provides this protection is the program itself, which is compiled into the program itself.
The code is provided, rather than a thread running in the dark corner of the system.
Therefore, since it is the program itself, in order not to bring additional burden to the programmer, this job is handed over to the compiler.
The cl.exeof vc6.0does not include this function. Only cl.exe of vc.nettakes this function later. It is called the/GS option.
When the CL compiler of vc.net is used, the/GS option is enabled by default.
Now that we know the provider of this mechanism, what exactly is this mechanism?
Those familiar with function calls and assembly instructions before and after return must be clear. On the Win32 platform, for function calls of the stdcall type,
After the call command is run, the current stack structure is basically as follows:
Bureau change 2 ebp-8 low address
Bureau Change 1 EBP-4
EBP
Returned address: EBP + 4
Parameter 1 EBP + 8
Parameter 2 EBP + c
Parameter 3 EBP + 10
Parameter 4 EBP + 14 high address
The first column is the content of DWORD stored in the stack, and the second column is the value corresponding to EBP when EBP is used as the index of the stack address,
To put it bluntly, the EBP stores an address of the stack (the stack is actually a piece of memory, and the EBP only points to one of the internal comparisons of the current function ).
An important address is actually quite important). other positions in the stack are addressed through this EBP, that is, we give the function the first form parameter.
The address is EBP + 8, the second is EBP + C, we define the address of the local variable, the first local variable is the ebp-4, the second local variable
The address is the ebp-8, and so on. But this is not certain. The above is an ideal situation. If we set an array in the function,
For example, char Buf [8]; and is the first local variable defined, then its address is certainly not a ebp-4, or a ebp-8. So, array
The structure is special. The root cause is that the stack grows from high address to low address, while our array, structure,
But it grew from low to high. The result of the conflict between the two is the subtle change in addressing.
Of course, for convenience, all the variables are defined by default. The input parameters are 4-byte aligned and one variable is
Double-character. You can understand an array as a 4-byte char, that is, a double character.
When the call operation is complete, the current stack structure has been provided. If strcpy () is called in the function
Something, the length is not tested, then the ebp-4, EBP, EBP + 4, there is a back address, the content will be overwritten. Here
Overflow occurs. We control the returned address of RET, and then...
Well, in order to prevent this, how do I add the so-called "Security cookie" to the/GS option of the new Cl compiler? Where to join
What about it?
First, let's take a look at the changes in the stack after the call command is executed after "Security cookie" is added.
Bureau change 2 EBP-c Low address
Bureau Change 1 ebp-8
XXXXX ebp-4
EBP
Returned address: EBP + 4
Parameter 1 EBP + 8
Parameter 2 EBP + c
Parameter 3 EBP + 10
Parameter 4 EBP + 14 high address
The change is obvious. On EBP, a new value is entered under the first local variable. This value is called "Security cookie"
According to the overflow process described above, the EBP-4 content is overwritten, that is, the security cookie value is modified, and the RET is executed when the function returns.
Before the command, will call another function, this function is used to compare the value of the ebp-4 and the value pushed to the stack is not the same, not the same
Then the process is terminated.
Then, you may have the following problems:
1. How is this security cookie calculated?
Security cookie is a dual character, or an int, Which is saved in a global variable and created by the compiler during compilation.
It is created in the phase and then written into the. Data Segment, that is, the value is saved in the PE.
However, this value is changed. After the Windows loader completes necessary preparations (such as creating a process, allocating memory to the stack, and waiting)
Set the EIP to the code entry in the PE. The first command to be executed is a call, which is used to initialize
The cookie value. Of course, this code is also public, but it does not matter. This algorithm ensures that the cookie value is random, and hacker also
It cannot be guessed in a shellcode.
I am not going to explain the specific algorithm here. Interested readers can compile the algorithm and disassemble it.
2. When is it written into the stack?
We know the calculation and initialization process of this security cookie, so it must be written into the ebp-4 when the function call is useful.
Therefore, the code without such protection in the past is generally like this at the function entrance:
Push EBP
MoV EBP, ESP
Sub EBP, N; this command may be different, but in most cases it is used to allocate space for local variables.
Then, we will start executing our code later,
After this protection is added, a command like this will be added after sub EBP and N:
MoV dword ptr [ebp-4], xxx
XXX is the value of security cookie. This value is stored in the global variable. It can also be said to be
It is referenced by an absolute address.
Here, the security cookie value is written to the stack, and then it can be checked before the function returns.
Here, you may have a new problem,
Must Security cookies be written to every function call for protection?
The answer is no. Otherwise, the execution efficiency of our program will be affected, and it may not be small.
Therefore, there should be certain rules, such as when to implement such protection and when not required.
Of course, the basis is also very simple. If there is a possibility of overflow, this protection should be added. If there is no possibility of overflow, it will not be added.
Then how can this problem be deemed as a possibility of overflow?
This is determined by the compiler. For example, if the char array is defined in the function, some operations are performed using the string operation function.
Overflow may exist. The compiler adds security cookie protection when compiling this function.
Of course, there are some other very specific rules here, which are described in more detail in msdn.
Other problems are not described here. You can leave these questions to everyone.
1. Is there any way to deal with security cookie detection? (The answer is yes, but it does not seem very elegant)
2. Exception Handling functions related to security exceptions
3./safeseh changes to seh Processing