-1

I created an environment variable SHELLCODE which contains a 200-byte long NOP sled and a shellcode. It is stored at 0x7fffffffe285, but I'll try to access 0x7fffffffe2e5, which is around the middle of the NOP sled.

Then I wrote the following code to try to access the variable.

#include <stdlib.h>

int main() {
    char *pointer = 0x00007fffffffe2e5;
    printf("%s\n", *pointer);
}

I used gdb to see the memory

(gdb) list 1
1   #include <stdio.h>
2   
3   int main() {
4       char *pointer = (char *) 0x00007fffffffe2e5;
5       printf("%s\n", *pointer);
6   }
(gdb) break 5
(gdb) run
(gdb) p pointer
$1 = 0x7fffffffe2e5 '\220' <repeats 119 times>, "\061\300\061\333\061ə\260\244̀j\vXQh//shh/bin\211\343Q\211\342S\211\341̀"
(gdb) p *pointer
$2 = -112 '\220'
(gdb) p/x *pointer
$3 = 0x90
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a5bcc0 in _IO_vfprintf_internal (
    s=0x7ffff7dd2620 <_IO_2_1_stdout_>, format=<optimized out>, 
    ap=ap@entry=0x7fffffffdc58) at vfprintf.c:1632
1632    vfprintf.c: No such file or directory.

The pointer was clearly pointing to the middle of the NOP sled, and gdb could access and see what was at that address. But I keep getting this Segmentation fault error.

Is this because C programs are not allowed to access memory where environment variables are stored? If so, is there a way to allow it to access the memory?

I'm using Ubuntu 16.04 and gcc 5.4.0. Thanks in advance.

sotanishy
  • 15
  • 1
  • 6
  • 2
    you want `getenv` – Christian Gibbons Jul 10 '18 at 17:26
  • 2
    What do you intend to print? Your shellcode? Then you have to print `pointer`, not `*pointer`. If you dereference it first, you give `0x90` as address where your string to print is located to `printf()`, which of course results in a segv. – Ctx Jul 10 '18 at 17:32
  • In some environments, you can also access environment variables by adding [`*envp[]`](https://stackoverflow.com/q/10321435/1679849) as a third argument to `main()`. – r3mainer Jul 10 '18 at 17:38
  • @Ctx That's true. Thanks for your help. – sotanishy Jul 10 '18 at 17:53
  • Normally when the OS create a new processo it maps in the process virtual memory a copy of environment block. Such an address is valid only in that process. Even for 2 identical instances of same process the address can be different due to ASLR mechanism. – Frankie_C Jul 10 '18 at 21:56

1 Answers1

1

The getenv function is used to retrieve the values of environment variables:

const char *shellcode = getenv("SHELLCODE");
dbush
  • 205,898
  • 23
  • 218
  • 273
  • Your code worked, thank you, but I don't know why my code still doesn't work. I replaced the getenv("SHELLCODE") with the address it gave me (which was 0x7fffffffe294), and this time it worked in gdb. But when I run it from the command line, it gives segmentation fault. – sotanishy Jul 10 '18 at 18:03
  • @sotanishy It probably has to do with ASLR (Address Space Layout Randomization), meaning there's no guarantee a variable or string will live at the same memory address each time. That's one of the things you need to work around to execute a buffer overflow. – dbush Jul 10 '18 at 18:07
  • It makes so much more sense. I'll try to figure that out. I really appreciate your help. – sotanishy Jul 10 '18 at 18:27