Survivability From a Sow s Ear: The Retrofit Security Requirement Crispin Cowan and Calton Pu Department of Computer Science and Engineering Oregon Graduate Institute of Science & Technology (crispin@cse.ogi.edu) http://www.cse.ogi.edu/disc/projects/immunix Abstract This paper considers the survivability requirement for production operating systems that underlie typical information systems. Since economic incentives give competitive advantages to imperfect and therefore insecure software, it seems inevitable to consider retrofitting some form of security to existing systems. This approach has long been anathema in the security community. We outline the pragmatic alternative of retrofitting security to achieve information survivability. 1 Introduction: the Survivability Imperative This paper makes the case for increasing operating system survivability by retrofitting a form of security to software systems that were not designed to be secure. A reader from the security community may consider this statement unorthodox. After examining the alternatives, we conclude that most other possibilities are even less likely to achieve the goal of widespread deployment of highly survivable information systems. We consider operating system survivability to be a necessary building block of information survivability. Operating system survivability per se is not specific to any particular domain of information processing. Rather, it comprises cross-cutting issues that affect all domains of information survivability. If an application s host operating systems fails to survive, then the application will also fail to survive. This paper pertains to issues involving the survivability of host operating systems, and by transitivity also the survivability of the information systems that run on them. Broadly speaking, the survivability imperative is that the information infrastructure should survive attacks. While attacks can take many forms (including the dread back hoe attack :-) we consider only computer security attacks. To achieve high survivability of the information infrastructure, many of the systems in that infrastructure must be able to survive security attacks. How then can host systems survive computer security attacks? The attacks must somehow be prevented from succeeding. Section 2 discusses the approach of using high security systems, which by dint of rigorous engineering, are not vulnerable to security attacks. Section 2 also discusses the costs of high security systems, which have the unfortunate effect of making them not economically viable. Section 3 discusses the alternative: retrofitting existing common systems, which are not secure and thus are vulnerable, with a a semblance of security such that they can survive attack. 1
2 The Cost of Security: Too High to Pay The traditional security approach applies a high degree of rigor to system design and implementation. This preserves system security by stopping all potential attacks, and consequently increases system survivability. A highly secure design provides for precise specification of who may access what, preventing an attacker from gaining unintended privileges by exploiting bugs in the access specifications. A highly secure implementation similarly prevents an attacker from gaining unintended privileges by exploiting bugs in the implementation, regardless of access specifications. High security systems can survive security attacks because they contain few (if any) security vulnerabilities. But the rigor required to remove all or most of the vulnerabilities comes at a high price in terms of development and maintenance, which the commercial marketplace appears to be unwilling to pay. Most customers, and consequently most vendors, have chosen the low cost alternative where imperfection is tolerated, producing security weaknesses. Current production operating systems are becoming increasingly dominated by admittedly imperfect but low cost systems. Decades of security research show that completely securing a system is difficult, requiring near perfection in the implementation. Ordinary system debugging is relatively simple, because it is only needed to the point where users are rarely troubled by bug manifestations. Security is different: if security bugs exist in the security perimeter and the attackers learn of the bugs, then the attackers can cause the bugs to manifest at will by deploying a security attack. Thus security requires not just making bug manifestation rare, but rather eliminating bugs from the security perimeter. Debugging is often viewed as the most costly phase of software development. The last few remaining bugs are the most expensive to excise, because they are the most subtle to make manifest. Removing bugs can also introduces new bugs, making it even more difficult to render a system bugfree. Thus the goal of a bug-free security perimeter can be exceptionally difficult to achieve. The imperative to develop products on internet time further squeezes precious debugging time from the development cycle, making future products even less likely to be survivable. Secure systems can be built if enough resources are brought to bear, and especially if security is a primary goal. However, the difficulties of securing a system slows down development efforts relative to those in which security is a lesser concern. The result is systems that are less optimized, less featureful, and later to market. The debugging process also needs to be repeated for each software maintenance cycle. Since modern operating systems are under constant development due to market pressure for new functionality, slowdown in each product cycle becomes fatal very quickly. The result is that most vendors choose not to emphasize correctness. This is a rational decision, borne not out of recklessness, but rather from a clear understanding of most customer s desires. Software customers appear to be insensitive to a tolerable degree of imperfection in their software, preferring new features over correctness. Consider the calls to Microsoft s support line [2,10, 11 ]: most calls request help on how to do some particular task, 5% of calls request some new feature, and less than 1% of calls are to report bugs. Advertisements, where software vendors promote their products, compare features, and occasionally speed, but rarely correctness. Even ads for security products rarely mention correctness. In fact, the standard software disclaimer makes it clear that bugs should be expected by consumers. 2
Since correctness is hard to achieve, and seems to offer little competitive advantage in the market place, it seems unlikely that vendors will produce correct software in quantity, or for long periods of time. As long as feature lists, time-to-market, and a little bit of performance matter more to customers than correctness, systems with a tolerable number of bugs (as defined by the majority of consumers) will be a normal state of affairs. Such systems are unlikely to be highly survivable. 3 The Remaining Alternative: Post-hoc Security Existing systems are buggy by choice, and therefore not secure and not survivable against attack. The main response of the survivability imperative is to retrofit some security features onto existing systems. Unfortunately, the security community has long known that it is not feasible to add security post hoc, because it requires reviewing the entire system with the degree of diligence that would have been required to secure system in the first place. Furthermore, the finished product will have made irreversible design and implementation decisions that compromise security for expedience, making it more difficult to secure an existing system than to build it securely from the start. We can ease the burden of retrofitting security onto existing systems by exploring the requirement differences between survivability and security. Security requires that the system preserves integrity, privacy, and continuation of service in the presence of attacks, i.e. attacks must be stopped completely. Survivability, in contrast, requires only that the system survive attacks to some degree, preserving integrity, privacy, and continuation of service to the maximum extent possible. We propose a general approach to the problem of retrofitting survivability. We exclude surviving attacks to which the system is not vulnerable, because that is precisely the security problem. Rather, we consider techniques to allow a system to survive an attack that exploits a vulnerability in the current system implementation. We call this security bug tolerance [5]. Security bug tolerance does not seek to identify and eliminate vulnerabilities. Rather, it seeks to minimize the degree of vulnerability implied by a security bug. Akin to classical fault tolerance, security bug tolerance minimizes exposure by replicating security checks within the system. An attacker may exploit a vulnerability resulting from a bug in the implementation, but because of additional security checks, the attacker does not gain very much additional privileges, and likely trips an intrusion alert, preventing additional exploitation of vulnerabilities. Wrappers [1, 12, 13] are a prominent form of security bug tolerance that adapts existing programs by making their vulnerabilities more difficult to exploit, enhancing their survivability. A wrapper is a program wrapped around a program suspected of having bugs. The wrapper filters input intended for the subject program, passing only the safe data to the subject program. We have identified several other forms of security bug tolerance. They adapt an existing vulnerable program or system to make vulnerabilities more difficult to exploit, or to limit the potential damage in the event of a successful attack. We have classified these security bug tolerance techniques along two dimensions, as shown in Table 1: what is adapted, and how it is adapted. What is either the program s interface or its implementation, and how is either a permutation or a restriction of the adapted piece of software. The classification scheme is further developed elsewhere [5]. Our research has focused on interface and implementation restrictions. For instance, the Stack- Guard compiler [6, 4] is a tool for automatically installing implementation restrictions within the executable code of a program. These restrictions prevent the program from performing operations 3
Interface Restrictions Wrappers [1, 12, 13] Permutation Deception Tool Kit [3] Random code or data layout [7] that are clearly not part of the program s intended behavior, such as changing the return address of a currently executing program, or altering a function pointer in a type-unsafe way. They can be thought of as specializations of the more general notion of type safety, which is also an implementation restriction. These restrictions are specialized to preserve performance and transparency for legacy programs written in C, which does not readily support type checking. 4 Summary Creating systems secure enough to resist attack is sufficiently difficult and expensive that most customers choose not to purchase them. As a direct result, security is not a high priority for most vendors, and most systems in use in the information infrastructure are vulnerable to attack. To make the information infrastructure survivable, we must develop tools and techniques that can adapt existing vulnerable systems with a form of retrofit security that will make them able to resist attack. References Firewalls Table 1: Implementation Array bounds checking [8, 9] Stackguard [6] [1] AUSCERT. overflow_wrapper.c Wrap Programs to Prevent Command Line Argument Buffer Overrun Vulnerabilities. ftp://ftp.auscert.org.au/pub/ auscert/tools/overflow_wrapper, May 1997. [2] Klaus Brunnstein. Mr. Bill Gates: MS Software Essentially Bug-free. comp.risks 17.43, October 1995. http://catless.ncl.ac.uk/risks/17.43.html#subj5. [3] Fred Cohen. The Deception Toolkit. comp.risks 19.62, March 1998. http:// all.net/dtk.html. [4] Crispin Cowan, Steve Beattie, Ryan Day, Calton Pu, and Perry Wagle. Protecting Systems from Stack Smashing Attacks with StackGuard. Submitted for review, June 1998. [5] Crispin Cowan, Calton Pu, and Heather Hinton. Death, Taxes, and Imperfect Software: Surviving the Inevitable. In Proceedings of the New Security Paradigms Workshop, September 1998. To appear. [6] Crispin Cowan, Calton Pu, Dave Maier, Heather Hinton, Peat Bakke, Steve Beattie, Aaron Grier, Perry Wagle, and Qian Zhang. StackGuard: Automatic Adaptive Detection and Prevention of Buffer-Overflow Attacks. In 7th USENIX Security Conference, San Antonio, TX, January 1998. [7] Stephanie Forrest, Anil Somayaji, and David. H. Ackley. Building Diverse Computer Systems. In HotOS-VI, May 1997. [8] Reed Hastings and Bob Joyce. Purify: Fast Detection of Memory Leaks and Access Errors. In Proceedings of the Winter USENIX Conference, 1992. http:// 4
www.rational.com/support/techpapers/fast_detection/. [9] Richard Jones and Paul Kelly. Bounds Checking for C. http://wwwala.doc.ic.ac.uk/ phjk/boundschecking.html, July 1995. [10] Nathan Myers. FOCUS Magazine Interview with Bill Gates: Microsoft Code Has No Bugs. http://www.cantrip.org/nobugs.html. [11] Unknown. Interview with Bill Gates. FOCUS, (43):206 212, October 23 1995. [12] Wietse Venema. TCP WRAPPER: Network Monitoring, Access Control, and Booby Traps. In Proceedings of the Third Usenix UNIX Security Symposium, pages 85 92, Baltimore, MD, September 1992. ftp://ftp.win.tue.nl/pub/security/ tcp_wrapper.ps.z. [13] Joe Zbiciak. wrapper.c Generic Wrapper to Prevent Exploitation of suid/sgid Programs. Bugtraq mailing list, http://geek-girl.com/bugtraq/, May 19 1997. http://cegt201.bradley.edu/ im14u2c/wrapper/. 5