PDA

Bekijk Volledige Versie : Is DEP easily evadable?



John Richard Moser
12/01/05, 23:25
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'm no security expert, so bear with me here; I just kind of tripped
over something interesting that I'd like to ask about.

I was blogging about DEP based on MS' technical documentation and came
up with a quick and dirty way to use a buffer overflow (we'll assume no
stackguarding, or that you found a way around it i.e. using a format
string bug) to kick DEP out of the way. This is pretty much based on
the PaX documentation and justification for mprotect() restrictions.

In a normal shellcode attack, you have a simple process involving:
- - Overwrite the return address
- - Spew in some executable code
- - Let RET take PC to that code and hand you control of the program

With executable protections preventing the stack from being executable,
such as with DEP, a different process (hopefully) occurs:
- - Overwrite the return address
- - Spew in some executable code
- - Segmentation fault (memory not executable)
- - Program exits, attack fails

I looked at the fact that Virtual*() functions (similar to mprotect() on
POSIX systems) can be used to make any area of memory executable. So,
here's my way:
- - Overwrite the return address
- - Overwrite the stack frame pointer
- - Spew in a stack frame with a return pointer to the code you injected
- - Spew in some executable code
- - Return to a Virtual*() function (don't know nor care which, I'm not
doing the attack)
- - Mark the code you injected executable
- - Let RET take PC to the code you injected. You win.

Without mprotect() restrictions OR ASLR, this should be trivial to do,
right?

I can't comment on SafeSEH, although I don't see screwing with exception
handlers as being more interesting to a cracker than injecting your own
code.

- --
All content of all messages exchanged herein are left in the
Public Domain, unless otherwise explicitly stated.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFB5XtEhDd4aOud5P8RAolKAJ9q4Z5htGYLS/bF0qbUUSx5PjAmlgCfVh1B
HDB+A/rTAdAUM2/hP42Iy24=
=6Z7n
-----END PGP SIGNATURE-----

Florian Weimer
13/01/05, 19:55
* John Richard Moser:

> I'm no security expert, so bear with me here; I just kind of tripped
> over something interesting that I'd like to ask about.
>
> I was blogging about DEP based on MS' technical documentation and came
> up with a quick and dirty way to use a buffer overflow (we'll assume no
> stackguarding, or that you found a way around it i.e. using a format
> string bug) to kick DEP out of the way. This is pretty much based on
> the PaX documentation and justification for mprotect() restrictions.

Look for return-into-libc exploits. There are quite a few.

Even with non-executable stack and heap, no one guarantees that buffer
overflows aren't exploitable. Randomization of load addresses is
intended to provide additional protection, but the number of available
bits is fairly low on 32 bit machines (problably less than 16). I
don't know if Windows is doing it.

John Richard Moser
13/01/05, 20:35
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



Florian Weimer wrote:
> * John Richard Moser:
>
>
>>I'm no security expert, so bear with me here; I just kind of tripped
>>over something interesting that I'd like to ask about.
>>
>>I was blogging about DEP based on MS' technical documentation and came
>>up with a quick and dirty way to use a buffer overflow (we'll assume no
>>stackguarding, or that you found a way around it i.e. using a format
>>string bug) to kick DEP out of the way. This is pretty much based on
>>the PaX documentation and justification for mprotect() restrictions.
>
>
> Look for return-into-libc exploits. There are quite a few.
>
> Even with non-executable stack and heap, no one guarantees that buffer
> overflows aren't exploitable. Randomization of load addresses is
> intended to provide additional protection, but the number of available
> bits is fairly low on 32 bit machines (problably less than 16). I
> don't know if Windows is doing it.
>

I don't see anything in the docs about it, but I don't have XP (I think
I have an XP license. . . yeah here it is, taped to the bottom of my
laptop; but I don't have a CD, and don't feel like finding . . what are
those things. . . a torrent of it)

PaX does pretty nice randomization. I think 15/16 for heap and stack
and 24 for mmap(), though I could be overshooting the 24. I'm on amd64
so I can't just run paxtest and see; though I could read the source code.

Also, there appears to be a UUDecode() function available! :) Looks
like you might be able to do attacks with NULLs in the shellcode and such?

Oh well, I guess this is just redundant white noise then; I was just
struck dumb a bit when it appeared that HW-DEP provided nothing in the
way of real protection; I'm too used to security enhancements being real.


- --
All content of all messages exchanged herein are left in the
Public Domain, unless otherwise explicitly stated.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFB5sCYhDd4aOud5P8RAn+VAKCKTEfka1sMzEdL9xliKE DJDsGxEgCgkFI4
ph+fJOcB0ELonMpX/Px2RxY=
=Mctm
-----END PGP SIGNATURE-----

Ben Pfaff
13/01/05, 21:15
John Richard Moser <nigelenki@comcast.net> writes:

> PaX does pretty nice randomization. I think 15/16 for heap and stack
> and 24 for mmap(), though I could be overshooting the 24. I'm on amd64
> so I can't just run paxtest and see; though I could read the source code.

In some fairly reasonable circumstances, this may not be enough.
I wonder whether the security community is generally aware of a
paper I co-authored on defeating PaX and address space
randomization in general on 32-bit systems, titled "On the
Effectiveness of Address Space Randomization". It was presented
at CCS 2004 and available on my webpage, among other places:
http://www.stanford.edu/~blp/papers/asrandom.pdf
--
"To prepare for the writing of Software,
the writer must first become one with it,
sometimes two."
--W. C. Carlson

John Richard Moser
14/01/05, 18:55
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1



Ben Pfaff wrote:
> John Richard Moser <nigelenki@comcast.net> writes:
>
>
>>PaX does pretty nice randomization. I think 15/16 for heap and stack
>>and 24 for mmap(), though I could be overshooting the 24. I'm on amd64
>>so I can't just run paxtest and see; though I could read the source code.
>
>
> In some fairly reasonable circumstances, this may not be enough.
> I wonder whether the security community is generally aware of a
> paper I co-authored on defeating PaX and address space
> randomization in general on 32-bit systems, titled "On the
> Effectiveness of Address Space Randomization". It was presented
> at CCS 2004 and available on my webpage, among other places:
> http://www.stanford.edu/~blp/papers/asrandom.pdf

Brad says he's seen it, and that at the time of that writing he'd
already solved that problem.

Apparently in grsecurity, once you've caused a program to segfault or
get a PaX kill, it's flagged to delay all future forks by 30 seconds, or
something like that. I don't know the exact details.

- --
All content of all messages exchanged herein are left in the
Public Domain, unless otherwise explicitly stated.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFB52D2hDd4aOud5P8RAgxVAJ9NMAhRPFwAyQ0gC9/SA8AD4NpwkQCgiCuM
bNddcz3FHs0b41VNnHOezMk=
=Khb9
-----END PGP SIGNATURE-----

Ben Pfaff
14/01/05, 19:25
John Richard Moser <nigelenki@comcast.net> writes:

> Ben Pfaff wrote:
>> John Richard Moser <nigelenki@comcast.net> writes:
>>>PaX does pretty nice randomization. I think 15/16 for heap and stack
>>>and 24 for mmap(), though I could be overshooting the 24. I'm on amd64
>>>so I can't just run paxtest and see; though I could read the source code.
>>
>> In some fairly reasonable circumstances, this may not be
>> enough. [...]
>
> Brad says he's seen it, and that at the time of that writing he'd
> already solved that problem.
>
> Apparently in grsecurity, once you've caused a program to segfault or
> get a PaX kill, it's flagged to delay all future forks by 30 seconds, or
> something like that. I don't know the exact details.

That's acceptable if you can afford to transform a (potentially
non-exploitable) segfault-inducing bug into a full-scale DoS.
It's a trade-off that in my opinion each site has to evaluate for
itself. We talked about this in the paper. Let me excerpt (this
is from tag-stripped LaTeX sources so it doesn't have the
references in the full paper):

Monitoring and Catching Errors

The PaX developers suggest that ASLR be combined with "a
crash detection and reaction mechanism", which we call a
"watcher". An attacker who attempts to discover addresses
within ASLR-protected executables will, in the process,
trigger segmentation violations through his inevitably
incorrect guesses. The watcher can detect these segmentation
violations and take action to impede the attacker; for
example, shut down the program under attack.

We do not believe that the crash watcher is a viable defense
mechanism because of the limited actions the crash watcher
can undertake when it discovers that a PaX-protected forking
daemon is experiencing segmentation faults. Either the
watcher alerts an administrator or it acts on its own. If it
acts on its own, it can either shut down the daemon entirely
or attempt to prevent the attacker from exploiting it.

If the watcher alerts an administrator, then it is difficult
to see how the administrator can react in time. Our
demonstrated attack can be completed in 216 seconds on the
average, less time than would be necessary to diagnose the
network traffic, read BugTraq, assess the severity of the
situation, and take corrective measures. The administrator
could also shut down the daemon before attempting a
diagnosis, but in this case he would be acting no more
intelligently than the watcher might.

If, indeed, the watcher shuts down the daemon altogether
pending an administrator's attention, then it in effect acts
as a force multiplier for denial of service. If Amazon.com's
Apache servers are PaX-protected and watched, and a
vulnerability is discovered in Apache that allows a
segmentation violation to be induced, then Amazon can be
taken offline persistently, with a minimum of attacker
effort. Being taken offline persistently can be costly;
reports in 2000 show that Amazon loses about $180,000 per
hour of downtime.

While it may be true that Amazon would do better with
disabled servers than compromised servers--that, in the end,
is an economic question--it is, nevertheless, also true that
it is difficult to distinguish exploitable vulnerabilities
from mere (segfault-inducing) denial of service. Neither an
automated watcher program nor a system administrator working
under time pressure can be expected to make the correct
determination.

It is worth illustrating how difficult these two cases are to
distinguish, even for expert programmers. The Apache
chunked-encoding vulnerability was for several days believed,
by the Apache developers themselves, not to be exploitable on
32-bit platforms: "Due to the nature of the overflow on
32-bit Unix platforms this will cause a segmentation
violation and the child will terminate". After the release
of a working exploit for 32-bit BSD platforms, the Apache
developers revised their analysis: "Though we previously
reported that 32-bit platforms were not remotely exploitable,
it has since been proven by Gobbles that certain conditions
allowing exploitation do exist".

Furthermore, unless the segfault watcher shuts down the
daemon permanently after a single segmentation violation, an
attacker can still slip under the radar. For example, if the
watcher acts after observing ten crashes in a one-minute
period, the attacker can seek addresses by brute force at the
rate of nine attempts per minute. The same holds if the
watcher keeps a daemon shut down for several seconds after a
crash. Such a watcher is, furthermore, as much a force
multiplier for denial of service as one that shuts down the
watched daemon after a single crash.

Finally, a watcher could attempt to prevent an attacker from
exploiting a vulnerability while allowing the daemon to
continue running. It might, for example, attempt to
determine the network source of the offending requests and
selectively firewall the source away from the daemon. But
this assumes that the attacker can be effectively localized.
With zombie networks numbering hundreds of thousands of
compromised hosts available for use as launchpads, attackers
can design and deploy worms that attack vulnerable daemons in
a coordinated fashion: no source machine needs to connect to
the attacked machine more than once, so a firewalling watcher
is of no value. Properly-engineered automated threats,
therefore, are capable of bypassing even firewalling watchers
unimpeded.

Sites that run large numbers of servers often load-balance
incoming requests. In such situations clients are not always
guaranteed persistent sessions with a single server, but
instead get a different server assigned to each
request. (Load balancing slows down our attack only by a
factor of 2.) A watcher running locally on one of these
servers would be unable to detect an attack, since subsequent
segfault-inducing requests are likely to be routed to
different servers. In order to detect such an attack, a
networked watcher is required that can correlate
segfault-inducing requests. Such a networked watcher would
be difficult to implement and would not be much better at
making watcher decisions than a host based watcher, due to
the inherent difficulty of implementing a realistic watcher
strategy.

In summary, the discussion above suggests that any reasonable
implementation of the crash watcher suggested by the PaX
documentation cannot prevent an attack such as we describe
above from succeeding, except at the cost of facilitating and
exacerbating denial-of-service vulnerabilities in the watched
daemon.

--
Ben Pfaff
email: blp@cs.stanford.edu
web: http://benpfaff.org