lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
From: lcamtuf at ghettot.org (Michal Zalewski)
Subject: Re: No Subject

On Tue, 21 Oct 2003, Frank Knobbe wrote:

> just to clarify, you mean on machines with a paged memory addressing
> scheme, right? I mean, byte-order itself is not the catalyst, but the
> fact that an address is formed by a page and a pointer within that page,
> right? (I'm not nit-picking, just trying to visualize...)

I'm not quite sure what you mean by "paged memory addressing" - but if you
mean a CPU feature, nope, it has nothing to do with it. Memory allocation
is done on a higher level.

The issue is that malloc structures are often created like this:

      .--- user data - pointer returned by malloc() --------.
      |                                                     |
      |         CHUNK 1                                     |  CHUNK 2
  .--.--------------------------------.   freed chunk   .--.------------
  `--`--------------------------------'   empty space   `--`------------
   |                                                     |
   `--- control data (pointers to next and --------------'
        previous chunks)

Chunks are of arbitrary length in linear memory space, one level above
paging, and have a tiny piece of control data just before the pointer
returned by malloc() that points to previous and next chunks, or stores
some other information that makes it easy to create and unlink chunks as
they get allocated or released.

The process of unlinking chunk number X is nothing more than writing to
the control structure of X-1 so that it points to X+1 as the next chunk,
and of X+1, so that it points to X-1 as a previous chunk. The empty space
is then added to the pool of space available for use.

Now, if you can cause zeros to be written past one of the chunks, you can
sometimes partly overwrite control structures of the next chunk, should
there be any, and make 'prev' or 'next' somewhat different. On big endian,
most significant bytes go first, and you are not likely to get a sane
pointer just by overwriting parts of it with zeros. On low endian, you can
change a pointer such as:

  0x08049648

...to be one of the following:

  0x08049600
  0x08040000
  0x08000000

...with some luck, one of the areas will contain either user-dependent
data, or something that suits us well for other reasons. When this next
chunk is then freed, free() can be tricked into thinking the previous or
next chunk has its control structures at this "evil" address. This region
will be written (which is a possible attack vector if it is used for
anything interesting later on), and will be used in the future; if it
contains user-dependent or otherwise interesting data, you can hope for
the subsequent pages to be freed, this time writing not to a partly
overwritten on-heap pointer, but to, for example, stack.

But then, some implementations use guarded free() and malloc() - OpenBSD
is a good example, IIRC. And not always there is something to overwrite,
any interesting data in the memory - in OpenSSH case, there is very
little code executed past the fault condition, and if you can't exploit a
number of free()s or something near libc exit() handler, no such luck.

Zero overwrites are a tricky business.

> The million dollar question is: Looking at the code in question for the
> SSH heap-0-overwrite, does it appear to be feasible or not?

It's not as much about looking at the code, but looking at the library
malloc() implementation, and then figuring out what can be put on heap and
where. I am way too lazy / too busy to give it much thought - I don't see
any benefit from writing an exploit or proving (?) it is not exploitable.

At first sight, it does not seem to be exploitable on some platforms, on
others, is uncertain at best. Quite frankly, I would expect the exploit to
leak already, or be developed independently, so I am sort of skeptical.

If it is exploitable and there is an exploit, the public will sooner or
later find out, don't force it if there is no good reason...

-- 
------------------------- bash$ :(){ :|:&};: --
 Michal Zalewski * [http://lcamtuf.coredump.cx]
    Did you know that clones never use mirrors?
--------------------------- 2003-10-21 18:17 --

   http://lcamtuf.coredump.cx/photo/current/


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ