<<< Date Index >>>     <<< Thread Index >>>

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