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