1

I programmed a little C program that is vulnerable to a buffer overflow. Everything is working as expected, though I came across a little problem now:

I want to call a function which lies on address 0x00007ffff7a79450 and since I am passing the arguments for the buffer overflow through the bash terminal (like this:

./a "$(python -c 'print "aaaaaaaaaaaaaaaaaaaaaa\x50\x94\xA7\xF7\xFF\x7F\x00\x00"')" )

I get an error that the bash is ignoring the nullbytes.

/bin/bash: warning: command substitution: ignored null byte in input

As a result I end up with the wrong address in memory (0x7ffff7a79450instead of0x00007ffff7a79450).

Now my question is: How can I produce the leading 0's and give them as an argument to my program?

Tejas Kale
  • 415
  • 8
  • 18
  • 2
    with *another* program ... –  Jun 12 '17 at 09:32
  • `NULL` is a macro with a _null pointer constant_. Never use it for `char`. And there is no problem with your code. You intentional invoke undefined behaviour and that's exactly what you get. Case closed. – too honest for this site Jun 12 '17 at 09:32
  • See [this answer](https://stackoverflow.com/a/19229243/8051589) and also [this one](https://stackoverflow.com/a/10770953/8051589) on SO. The bash is handling null bytes as space. – Andre Kampling Jun 12 '17 at 09:42
  • You are trying to fix the problem in wrong place. Fix the little C program vulnerable to a buffer overflow. – ArturFH Jun 12 '17 at 09:53
  • @ArturR.Czechowski: It is his intention to make his program vulnerable to a buffer overflow, for training/demo purposes. He just want to parse the address of a function containing null bytes. – Andre Kampling Jun 12 '17 at 09:55
  • Don't. Use a tool such as [`xxd`](http://www.manpagez.com/man/1/xxd/) (with -r option), pass it hexadecimal to decode and pipe its output where you want it. That will do away with the bash+arbitrary binary combination. – spectras Jun 12 '17 at 10:12
  • @Andre Kampling yes exactly. thanks I will check xxd out – user7981924 Jun 12 '17 at 10:32
  • @spectras: I think pipe won't work, because a pipe goes to stdin and is not passed as an argument. For his vulnerability he needs it as argument, doesn't he? – Andre Kampling Jun 12 '17 at 11:22
  • @Andre Kampling yeah. I need it as an argument. Tried to use xxd with xargs, but that didn't work either – user7981924 Jun 12 '17 at 11:27
  • @AndreKampling> written as such yes, but I assumed he could modify his vulnerable code to `read(STDIN_FILENO, buf, 2*sizeof(buf))` instead of copying from an argument. Not to mention, `strcpy` won't work anyway because it will also stop when it sees a `\0` and won't copy the whole argument even if you manage to put NULs in it. – spectras Jun 12 '17 at 12:02
  • @spectras: Right but maybe he does not has the possibility to do that, because maybe he needs the address that he wants at the specific address where the arguments of the program are lie. For me it seems impossible to do that, because a bash' string will end where `\0` occurs, like the SO answers saying that I'm posted above.. – Andre Kampling Jun 12 '17 at 12:08
  • @AndreKampling well since I made up my program to just play around with it, it is highly possible that I made it unsolvable (atleast when I need NULL bytes for padding). The reason I need that specific address is, because the system function lies on this address – user7981924 Jun 12 '17 at 12:10

1 Answers1

2

I'll take a bold move and assert what you want to do is not possible in a POSIX environment, because of the way arguments are passed.

Programs are run using the execve system call.

int execve(const char *filename, char *const argv[], char *const envp[]);

There are a few other functions but all of them wrap execve in the end or use an extended system call with the properties that follow:

  • Program arguments are passed using an array of NUL-terminated strings.

That means that when the kernel will take your arguments and put them aside for the new program to use, it will only read them up to the first NUL character, and discard anything that follows.

So there is no way to make your example work if it has to include nul characters. This is why I suggested reading from stdin instead, which has no such limitation:

char buf[256];
read(STDIN_FILENO, buf, 2*sizeof(buf));

You would normally need to check the returned value of read. For a toy problem it should be enough for you to trigger your exploit. Just pipe your malicious input into your program.

spectras
  • 13,105
  • 2
  • 31
  • 53