0

I got the following code from the lecture-slides of a security course.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
extern char shellcode;
#define VULN "./vuln"

int main(int argc, char **argv) {
    void *addr = (char *) 0xc0000000 - 4 
                 - (strlen(VULN) + 1)
                 - (strlen(&shellcode) + 1);
    fprintf(stderr, "Using address: 0x%p\n", addr);

    // some other stuff        

    char *params[] = { VULN, buf, NULL };
    char *env[] = { &shellcode, NULL };
    execve(VULN, params, env);
    perror("execve");
}

This code calls a vulnerable program with the shellcode in its environment. The shellcode is some assembly code in an external file that opens a shell and VULN defines the name of the vulnerable program.

My question: how is the shellcode address is computed

The addr variable holds the address of the shellcode (which is part of the environment). Can anyone explain to me how this address is determined? So:

  • Where does the 0xc0000000 - 4 come from?
  • Why is the length of the shellcode and the programname substracted from it?

Note that both this code and the vulnerable program are compiled like this:

$ CFLAGS="-m32 -fno-stack-protector -z execstack -mpreferred-stack-boundary=2"
$ cc $CFLAGS -o vuln vuln.c
$ cc $CFLAGS -o exploit exploit.c shellcode.s
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
0

So address space randomization is turned off.

I understood that the stack is the first thing inside the process (highest memory address). And the stack contains, in this order:

  1. The environment data.
  2. argv
  3. argc
  4. the return address of main
  5. the framepointer
  6. local variables in main
  7. ...etc...

Constants and global data is not stored on the stack, that's why I also don' t understand why the length of the VULN constant influence the address at which the shellcode is placed.

Hope you can clear this up for me :-)

Note that we're working with a unix system on a intel x86 architecture

Maricruzz
  • 405
  • 3
  • 7
  • 14
  • See: http://stackoverflow.com/questions/12437391/whats-inside-the-stack – ninjalj Mar 12 '14 at 23:08
  • Thanks, but It doesn't mention where the 0xc0000000-4 comes from and (strlen(VULN) + 1). Note that we're working with a unix system on a intel x86 architecture – Maricruzz Mar 13 '14 at 08:55
  • 1
    4 comes from the size of NULL in a 32bit arch. strlen(VULN) + 1 comes from the filename for the program. The stack starts just below 0xc0000000 in a x86 machine with a 3Gb/1Gb userspace/kernelspace split with no ASLR. – ninjalj Mar 13 '14 at 10:02

0 Answers0