11

In the past, I have managed to overflow my own vulnerable programs, and those of others, but only ever in a 32bit environment. Every time I try even a simple stack smash on a 64bit machine, I run into issues. An address I am trying to write always contains null bytes.

A simple example from a problem yesterday; I was trying to overwrite the GOT to cause a later call to printf() to become a call to system() I had all the addresses I needed (ASLR off, DEP on).

I became stuck when I tried to overwrite a stackland pointer (high memory address) with a heapland (low memory address) value.

0x7fffffff_ff480a90 -> 0x00000000_0068a9a0

My overflow ended with \xa0\xa9\x68, which with the null terminator left the pointer looking like;

0x7fffffff_0068a9a0

Which was no good, I looked at this for hours and couldn't figure a way around it. Like I say I have run into this null byte problem many times. I always thought it was just one of those things, but it seems to make it completely impossible to hack a 64bit system, as the addresses so often contain null bytes.

Am I just unlucky? Am I missing something obvious? I haven't heard anyone talking about this issue in terms of 32 vs 64.

lynks
  • 10,636
  • 5
  • 29
  • 54
  • Just ran into this myself. Surely somebody has a solution for this? Googling comes up blank except for this question. – Rushyo Aug 17 '12 at 14:08

2 Answers2

4

You might want to read this http://www.x86-64.org/documentation/abi.pdf

Essentially x86 and x64 are different in the way that they work. The new ABI describes the new ways in which it does with Leaf and Non Leaf calls, exception handling and unwinding.

Since the purpose is to essentially overflow - you need to understand the new ABI how its working and where stuff is as its now in slightly different places to be able to "insert" and "alter".

Scott Pack
  • 15,167
  • 5
  • 61
  • 91
  • LongTime, welcome to [security.se]. Can you add some more information to your answer? Maybe summarize the link (which may go dead), if their license allows it. Please see [answer], and review the [FAQ#deletion] about posting just links. – AviD Aug 24 '12 at 09:51
  • yeah kind of forgot - was in a rush and wanted to get something there. >) – Madison Cat Aug 24 '12 at 12:29
3

First, there is something weird with your example. Current processors which implement the amd64 mode (aka x86_64 aka x64 aka a bunch of other names) don't use the full 64 bits of address registers. They use 48-bit addresses, and make it mandatory that bits 48 to 63 are identical (as if it was "sign extension"). Thus, an address like 7fffffff_ff480a90 will not be accepted by any currently produced CPU. More likely, you have 00007fff_ff480a90. This reduces your problem to two bytes instead of four.

One generic method is to perform several successive overflows; depending on the exact conditions with which you can overflow data, this may or may not be possible. With several overflows, you replace your target slot with 00000054_54545454, then 00000000_54545454, then finally 00000000_0068a9a0. Each overflow lets you write a single terminating null byte, you want to write three null bytes, hence three overflows.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949