Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between declaring shellcode as a char[] array and char*?

Hi all,

I'm trying to learn basic shellcoding and I've run across something curious that I hope someone can explain to me. I've compiled the following code two ways: declaring the shellcode as an array and as a char*. When I declare shellcode as an array, linux detects that I am trying to execute data and I get a segfault on the first instruction. However, when I declare shellcode as a char* all of the shellcode executes and I get a "Hello world!". How does the compiler treat these two declarations differently and why does one end in shellcode that lives in memory that is unprotected? Thanks in advance.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* This declaration ends in a segfault */
//char shellcode[] =

/* This declaration ends in successful execution */
char* shellcode = 

/* Shellcode prints "Hello world!" and exits */    
"\xeb\x1f\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\xb0\x04\xb3\x01\x59\xb2\x0c\xcd\x80\x48\x31\xc0\xb0\x01\x48\x31\xdb\xcd\x80\xe8\xdc\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x21";

int main()
{
    void (*f)();
    f = (void (*)())shellcode;
    (void)(*f)();
}
like image 651
dani Avatar asked Dec 17 '11 05:12

dani


People also ask

What is the difference between char and char *?

The main difference between them is that the first is an array and the other one is a pointer.

What does char * array mean?

A character array is a sequence of characters, just as a numeric array is a sequence of numbers.

What is the difference between char array and char pointer?

char[] is a character array whereas char* is a pointer reference. char[] is a specific section of memory in which we can do things like indexing, whereas char* is the pointer that points to the memory location.

What is a char * array in C?

In C, an array of type char is used to represent a character string, the end of which is marked by a byte set to 0 (also known as a NUL character)


2 Answers

When you declare it as a char[], the memory is on the stack. When you declare it as a char* and assign it a string literal, the memory is in the executable image itself. Linux doesn't like you executing code on the stack, but is fine with you executing memory in that part of the executable image. That is because it is trying to avoid a certain type of stack overflow attack where people can overflow the stack with some arbitrary instructions and then execute them.

You can use mprotect on Linux to set the permissions for a region of memory or VirtualProtectEx on Windows. That way you can explicitly set the permissions of the memory to be executable.

like image 105
Seth Carnegie Avatar answered Oct 23 '22 09:10

Seth Carnegie


In your first case:

char shellcode[] =

This puts the string literal on the stack as a local array. The stack and heap memory usually does not have execute permissions (for obvious reasons of security).

In your second case:

char* shellcode = 

The string lives in static memory - typically in the same region as the rest of the program binary - which is executable.

like image 32
Mysticial Avatar answered Oct 23 '22 08:10

Mysticial