High Performance Linux

Thursday, March 15, 2012

GCC Inline Assembly: Easy Way to Build-in Your Shellcode Into Exploit

In most cases when developing an exploit people independently develop the shell code, compile it and only after that build it into the exploit in hex format as a string. So usually you can find following in an exploit code:

char shell_code[] =
    "\xeb\x24\x5e\x8d\x1e\x89\x5e\x0b\x33\xd2\x89\x56\x07"
    "\x89\x56\x0f\xb8\x1b\x56\x34\x12\x35\x10\x56\x34\x12"
    "\x8d\x4e\x0b\x8b\xd1\xcd\x80\x33\xc0\x40\xcd\x80\xe8"
    "\xd7\xff\xff\xff/bin/sh";

int main()
{
    // Do something with shell_code
}


This is easier can be done with GCC inline assembly. You just need to define the shell code as a function and one other, dummy, function just after it:

__asm__ (
        ".p2align 4, 0x90\n"
        ".local shellcode\n"
        ".type shellcode,@function\n"
        "shellcode:\n"
            /* The function body */
        "\n"
        ".p2align 4, 0x90\n"
        ".local end_of_shellcode\n"
        ".type end_of_shellcode,@function\n"
        "end_of_shellcode:\n"      /* just empty function */
);

The shellcode is defined as shellcode() function. The function end_of_shellcode() is required only to get the shellcode length. You can work with the shellcode exactly the same way as for string. E.g. to get the shellcode address:

printf("shellcode address is %p\n", &shellcode);

Or to get length of the shellcode:

printf("shellcode length is %lu\n",
    (unsigned long)&shellcode - (unsigned long)&end_of_shellcode);

This way you just need to use inline assembly instead of compile and decode the shellcode separately. This is a common practice and Linux kernel widely uses such mixing of assembly and C function declarations.

No comments:

Post a Comment