Search code examples
cassemblyshellcode

Desiging Shellcode gives incorrect results


I made this simple assembly program:

.text
    .globl _start
    _start:
        mov %20, %rbx
        mov %1, %rax
        int $0x80

This is obviously running on a 64 bit OS (Linux). I then compiled it as follows:

as -o ExitShellcode.o ExitShellcode.s
ld -o ExitShellcode ExitShellcode.o

And finally after running the program, It exits with a status of 20

echo $?
20

Using objdump to dump the shellcode for the file gives:

objdump -d ExitShellcode

ExitShellcode:     file format elf64-x86-64


Disassembly of section .text:

0000000000400078 <_start>:
400078: 48 c7 c3 14 00 00 00    mov    $0x14,%rbx
40007f: 48 c7 c0 01 00 00 00    mov    $0x1,%rax
400086: cd 80                   int    $0x80

However, after putting the shellcode in this program:

#include <stdio.h>

char shellcode[] = "\x48\xc7\xc3\x14\x00\x00\x00"
                   "\x48\xc7\xc0\x01\x00\x00\x00"
                   "\xcd\x80";

int main()
{
    int *ret;

    ret = (int *)&ret +2;

    *ret = (int)shellcode;

}

and compiling:

gcc -g -o Shellcode Shellcode.c
Shellcode.c: In function ‘main’:
Shellcode.c:13:9: warning: cast from pointer to integer of different        size     [-Wpointer-to-int-cast]
*ret = (int)shellcode;

and running, the program exits with a 0 status:

echo $?
0

What's the proplem? Shouldn't it exit with a 20?


Solution

  • Your code incorrectly assumes that the compiler will put the variable ret at a certain place on the stack relative to the return address of main. Instead the compiler put it somewhere else, as it is allowed to do, and so your code does nothing. Your probably following a badly designed example you found on the Internet.

    If you want to execute the "shellcode" in the shellcode array you can try casting to it a pointer to function and then calling it:

    char shellcode[] = "\x48\xc7\xc3\x14\x00\x00\x00"
                   "\x48\xc7\xc0\x01\x00\x00\x00"
                   "\xcd\x80";
    
    int main()
    {
        ((void (*)()) shellcode)();
    }
    

    However this will still probably fail because the .data section where shellcode is placed isn't executable and so the program will crash when run. To fix that problem use the -zexecstack option when linking your program. For example:

    gcc -zexecstack -g -o Shellcode Shellcode.c