Security Enhancements in Red Hat Enterprise Linux (Beside Selinux)
Total Page:16
File Type:pdf, Size:1020Kb
Security Enhancements in Red Hat Enterprise Linux (beside SELinux) Ulrich Drepper Red Hat, Inc. [email protected] December 9, 2005 Abstract Bugs in programs are unavoidable. Programs developed using C and C++ are especially in danger. If bugs cannot be avoided the next best thing is to limit the damage. This article will show improvements in Red Hat Enterprise Linux which achieve just that. 1 Introduction These problems are harder to protect against since nor- mally2 all of the OS’s functionality is available and the Security problems are one of the biggest concerns in the attacker might even be able to use self-compiled code. industry today. Providing services on networked comput- ers which are accessible through the intranet and/or Inter- Remotely exploitable problems are more serious since net potentially to untrusted individuals puts the installa- the attacker can be anywhere if the machine is available tion at risk. A number of changes have been made to the through the Internet. On the plus side, only applications Linux OS1 which help a lot to mitigate the risks. Up- accessible through the network services provided by the coming Red Hat Enterprise Linux versions will feature machine can be exploited, which limits the range of ex- the SELinux extensions, originally developed by the Na- ploits. Further limitations are the attack vectors. Usually tional Security Agency (NSA), with whom Red Hat now remote attackers can influence applications only by pro- collaborates to productize the developed code. SELinux viding specially designed input. This often means cre- means a major change in Linux and is a completely sep- ating buffer overflows, i.e., situations where the data is arate topic by itself. written beyond the designated memory area and over- writing other data. Here, we are going to concentrate on extensions Red Hat made to the OS which increase security but are not part One way to avoid buffer overflow problems is to use con- of, and do not require SELinux. The goal for these exten- trolled runtimes where memory access is first checked sions was to have no negative impact on existing code, for validity. This is not part of the standard C and C++ if possible, to work without recreating binaries, and to runtime, which means many applications are in danger require minimal changes to the process of building ap- of these problems. Intruders can misuse these bugs in a plications. The remainder of this paper introduces three number of ways: separate extensions Red Hat made. It is not meant to be a complete list but rather should serve individuals who • if the overwritten buffer on the stack is carefully want to increase security of the Red Hat Enterprise Linux crafted, overflow can cause a naturally occurring based systems as a guideline to adjust their code and in- jump to a place the intruder selected by overwrit- stallation to take advantage of the new development. Be- ing the original return address. The target of the fore we start with this, some words about exploiting se- return might also be in the data written onto the curity problems. stack by the overflow; • a pointer variable might be overwritten. Such a 2 Exploiting Security Problems variable, if located in memory in front of the over- flowed buffer, could then be referenced and maybe When attempting to categorize security problems, one written to. This could allow the intruder to write should first distinguish between remotely and locally ex- a value, which might also be controlled by the in- ploitable problems. The latter can only be exploited if the truder, into a specific address; attacker already can execute code on the target machine. • a normal variable might be overwritten, altering 1“OS” as in the whole system, not just the kernel. the state of the program. This might result in per- mission escalation, wrong results (think transfer of money to wrong accounts), etc. Copyright c 2004, 2005 Ulrich Drepper All rights reserved. No redistribution allowed. 2SELinux changes this. 1 Although these possible effects of an overflow might seem ers. nothing but a good way to crash the application, attackers The mechanisms developed by Red Hat automatically often find ingenious ways in which the application does cause many of the common exploits to fall only in the not crash, but instead does something to the attacker’s last, and least dangerous category. liking. This is aided by the fact that identical binaries are widely available and used in many places. This allows the attacker to study the binary locally before the attacks. 4 Exec-Shield Randomness in the binaries would be beneficial but for various reasons it is unpractical that end users recreate We start with an concrete example of some broken code the binaries which differ sufficiently. For one, vendors which in one form or another far too often appears in will violently protest since it throws attempts to provide deployed programs: service and maintenance completely off the track. 3 The Plan int match (const char *passwd) The best protection against these problems is, of course, { auditing the code and fixing the problems. Given suffi- char tmp[MAXPASSWD]; cient resources these will have some positive effect, but if (gets (tmp) == NULL) being human, programmers will always miss one or an- return 1; other problem. And there is always new code written. return strcmp (passwd, tmp); Besides, the investment to audit all relevant code is pro- } hibiting. Finally, this will not at all protect against prob- lems in 3rd party programs. A second line of defense is needed. The worst intruders There are two factors which make this code especially can achieve is circumventing the security of the system. dangerous. First, the use of gets which is always wrong. If this happens, all guards of the system have no effect. The function does not allow specification of the size of Achieving this is very difficult with SELinux properly set the buffer, so uncontrolled input can overflow the buffer. up. Each application has been assigned a domain which This is exactly what happens here, but what is it that is gives it limited capabilities. Changing domains can only overflown? The answer is of course the array tmp, but be done under the control of the kernel and only in ways there is more to it. The second point is that the array the system adminstrator allows. Ideally, there is no all- is allocated on the stack. On machines where the stack powerful super user anymore. As stated before, we will grows downward in the address space (for all common not discuss SELinux here. architectures other than HP/PA) the array tmp is located below the data generated for the function call and data the One notch down the list of dangers is the possibility for callers put on the stack. For many architectures, the data the intruder to take over the process or thread. This re- generated for the function includes the return address. quires that the intruder inject code of his own choosing Now all together this means that the input on stdin, read into the running process and cause this code to be exe- by gets, can be used to overwrite the return address of cuted. the function call and even set up the frame for the code to which the fake return address points. In other words, The next level down would be an intruder changing the this code allows an attacker to redirect the execution of behavior of an application, not to enable further security the code to an arbitrary place. escalation, but instead to cause havoc by changing the outcome of the computation (for instance, the aforemen- It varies where this code is that the attacker wants to ex- tioned transfer to a wrong account). ecute. It could be a known address in the address space. We will handle this case in the next section. The more Since C and C++ applications are usually not written to dangerous case is where the code comes along with the cope gracefully with bugs, the best one can hope for is buffer overflow. Note that the standard I/O functions of to end the infected run of the application. This is the the C runtime work equally well for arbitrary binary data. best to do if the state of the program must be assumed Often only the byte values representing newline (’\n’, to be contaminated. If the application provides mecha- 0x0a) and NUL (0x00) are special. All other values can nisms to shut down only one thread or perhaps drop only be used freely. So an attacker could fill the array tmp the client connection which caused the problem, this can with arbitrary data. be done as well. But this requires highly sophisticated programming which is found only in applications with extreme uptime or security requirements. If the applica- low high tion is shut down, the worst possible outcome is that the intruder attacks again and again, causing one shutdown after the other. This can be prevented with higher-level tmp return security, by configuring the firewall or protocol analyz- address 2 Version 1.6 Security Enhancements in RHEL We could find ourselves in a situation as in this figure. It To address the code written to the stack, the address of represents the stack memory when the example function the stack has to be known. An attacker could potentially match is called. The green area, the array tmp, is filled try several times and hope to get some kind of feedback with data (e.g., program code) by the attacker and the allowing him to determine the actual address.