Re: Is DEP easily evadable?
John Richard Moser <nigelenki@xxxxxxxxxxx> writes:
> Ben Pfaff wrote:
>> John Richard Moser <nigelenki@xxxxxxxxxxx> 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@xxxxxxxxxxxxxxx
web: http://benpfaff.org