© Copyright O’Reilly & Associates. All rights reserved.
What is an Attack?
In a general sense, an attack on a system is any maliciously intended act against a system or a population of systems. There are two very important concepts in this definition that are worth pointing out. First, we only say that the act is performed with malicious intent, without specifying any goals or objectives. Second, some attacks are directed at a particular system, while others have no particular target or victim.1 Let’s look at these concepts and terms one by one:
- The immediate goal of an attack can vary considerably. Most often, though, an attack goal is to damage or otherwise hurt the target, which may include stealing money, services, and so on.
- Achieving one or more of the goals above may require first reaching a subgoal, such as being granted elevated privileges or authorizations on the system.
- The activities that an attacker engages in are the things that he does that could help him achieve one or more of his subgoals. These could include using stolen login credentials (e.g., username and password); masquerading as a different computer, user, or device; flooding a network with malformed packets; and so on.
- The activities mentioned above may result in attack events—improper access could be granted, request processing could be suspended, storage space could be exhausted, or a system or program could be halted.
- A further concept, often confused with an attack event, is the business consequence. By this term we mean the direct result of the events, such as financial balance sheets being incorrect, or a computer system being unavailable for a business process.
- Lastly, the impact of the attack is the business effect. This could include the tarnishing of a company’s reputation, lost revenue, and other effects.
The distinction between the attack event and its business consequence is an important one. The business consequence of an attack depends on the business purpose of the affected system, not on the specific attack actions or events. A direct consequence, for example, might be an inability to process a business transaction, resulting in an impact of loss of revenue. An indirect impact might be the tarnishing of the reputation of the business owner, resulting in an erosion of customer confidence. Figure 1-3 illustrates an example attack, showing the goals, subgoals, and activities of the attacker, along with the events, consequences, and impacts from the perspective of the target enterprise.
We’ve trotted out this terminology because we’ve found that it’s critical to think clearly and precisely about attacks if we are to prevent them. Does it surprise you to hear that the potential business impact of an attack may be relevant to its prevention? It is. Knowing what is at stake is an essential part of making good design decisions about which defense mechanisms you will use.
How Would You Attack?
How do attackers attack systems? Part of the how depends on the why. Some want to probe, but do no harm. Others are out to steal. Some seek to embarrass. A few want only to destroy or win bragging rights with their cronies. While we can’t anticipate all possible motivations, we will try to think with you about how someone only moderately clever might approach the problem of compromising the security of your application.
Consider a safecracker. If he is a professional, he probably owns specialized safecracking tools (a stethoscope—we are told—comes in handy). He probably also has a thorough knowledge of each target vault’s construction and operation, and access to useful technical documentation. He uses that knowledge to his advantage in manipulating the safe’s combination knob, its internal tumblers, and so on, until he manages (or fails) to open the safe.
Figure 1-3. Attack activities, events, goals, and business consequences
In an analogous attack on an application system, the miscreant arms himself with knowledge of a system (and tools to automate the application of the knowledge) and attempts to crack the target system.
Ah, but there are so many ways into a safe! A bank robber who doesn’t have the finesse of a safecracker can still put on a ski mask and enter the bank during business hours with a gun. If we were planning such an attack, we might masquerade as a pair of armored car security officers and enter the vault with the full (albeit unwitting) assistance of the bank staff. Bribery appeals to us—hypothetically, of course—as well. How about you? Would you blast your way in?
There have been many good studies about the motivations and mind-sets of the kinds of people and personalities who are likely to attack your software. That’s a book in itself, and in the Appendix, we point you to a few good ones. In this chapter, we’ll simply encourage you to keep in mind the many facets of software and of the minds of your attackers. Once you have begun to ask what can happen, and how (and maybe why), we believe you’re on your way to enforcing application security. In the case studies at the end of this chapter, we’ll provide examples of constructive worrying we encourage you to do, as well as examples of what could happen if you don’t worry enough.
Attacks and Defenses
In the following sections, we’ll list quite a few types of attacks that your applications may have to withstand. We’ve divided the discussion into three categories, according to which stage of development the vulnerability relates:
- While you are thinking about the application
- While you are writing the application
- After the application is in production
The attacks, of course, will usually—not always—take place while the program is running. In each case, we’ll try to make a clear distinction.
At the end of each description, we’ll discuss briefly how an application developer might approach defending against the attack. We’ll develop these ideas in greater depth in subsequent chapters, as we make our case that application security is an essential element at every stage of development.
|In these sections we describe only a very few of the many, many ways that security can be breached. We refer you again to the Appendix for pointers to more complete discussions, as well as pointers to formal attack taxonomies.|
As a general rule, the hardest vulnerabilities to fix are those resulting from architectural or design decisions. You may be surprised at how many of the vulnerabilities you have heard of we ascribe to errors at “pure think” time.
At the end of this section we list two types of attacks, session hijacking and session killing, that are unusually difficult to defend against from within an application. What’s the point of mentioning them? As we argue in Chapter 3, the fact that you as a developer may not be able to institute adequate defenses against an attack does not relieve you of responsibility for thinking about, planning for, and considering how to minimize the impact of such an occurrence.
It’s worth mentioning that architectural and design-level attacks are not always based on a mistake per se. For example, you may have used the telnet program to move from one computer to another. It does well what it was designed to do. The fact that its design causes your username and password to be sent along the cables between computers, unencrypted, is not a “flaw” in and of itself. Its design does make it an unattractive choice for using in a hostile environment, however. (We use ssh instead.).
The following are the main attacks we’ve observed at the architecture/design level:
- Man-in-the-middle attack
- A man-in-the-middle (or eavesdropping) attack occurs when an attacker intercepts a network transmission between two hosts, then masquerades as one of the parties involved in the transaction, perhaps inserting additional directives into the dialogue.
Defense: Make extensive use of encryption—in particular, strong cryptographic authentication. In addition, use session checksums and shared secrets such as cookies. (You might, for example, use ssh instead of telnet, and encrypt your files using utilities such as PGP or Entrust.)
- Race condition attack
- Certain operations common to application software are, from the computer’s point of view, comprised of discrete steps (though we may think of them as unitary). One example is checking whether a file contains safe shell (or “batch”) commands and then (if it does) telling the host system to execute it. Sometimes, the time required to complete these separate steps opens a window during which an attacker can compromise security. In this example, there may be a very brief window of opportunity for an attacker to substitute a new file (containing attack code) for the previously checked file. Such a substitution can trick an application into running software of the attacker’s choosing. Even if the resulting window of opportunity is too short for a human to reliably exploit it, a program might well be able to repeatedly test and then execute the attacker’s program at just the right moment in time. Because the result often depends upon the order in which two or more parallel processes complete, this problem is known as a “race” condition.2
Defense: Understand the difference between atomic (indivisible) and non-atomic operations, and avoid the latter unless you are sure there are no security implications. (Sample actions that do have security implications include opening a file, invoking a subprogram, checking a password, and verifying a username.) If you are not sure whether an operation is atomic, assume that it is not—that is, that the operating system may execute it in two or more interruptible steps.
- Replay attack
- If an attacker can capture or obtain a record of an entire transaction between, say, a client program and a server, it might be possible to “replay” part of the conversation for subversive purposes. Impersonating either the client or the server could have serious security implications.
Defense: Same as for the man-in-the-middle attack; in addition,consider introducing into any dialog between software elements some element (e.g., a sequence identifier) that must differ from session to session, so that a byte-for-byte replay will fail.3
- Sniffer attack
- A program that silently records all traffic sent over a local area network is called a sniffer. Sniffers are sometimes legitimate diagnostic tools, but they are also useful to attackers who wish to record usernames and passwords transmitted in the clear along a subnet.
Defense: This attack is best addressed at the network level, where its impact can be diminished (but not removed) by careful configuration and the use of “switched” network routers. Still, as an application writer, you can render sniffers fairly harmless by making maximal effective use of encryption.
- Session hijacking attack
- By exploiting weaknesses in the TCP/IP protocol suite, an attacker inside the network might be able to hijack or take over an already established connection. Many tools have been written and distributed on the Internet to implement this rather sophisticated technical attack.
Defense: This network-level attack is quite difficult to defend against from within application software. Encryption, of course, is a help (although a discussion of its limitations is beyond our scope here). And some operational procedures can help detect a hijacking after the fact, if careful logging provides enough information about the session.
- Session killing attack
- Legitimate TCP/IP sessions can be terminated when either of the communicating parties sends along a TCP reset packet. Unfortunately, an attacker inside the network might be able to forge the originating address on such a packet, prematurely resetting the connection. Such an attack could be used either to disrupt communications or, potentially, to assist in an attempt to take over part of a transaction (see the description of session hijacking above).4
Defense: Like session hijacking attacks, session killing attacks are difficult to defend against from within an application. Unfortunately, we believe that deterrence from within the application is not possible. However, your application may be able to compensate after the fact by either reasserting the connection or reinitializing the interrupted transaction.
1Note also that in this definition we don’t limit ourselves to events that take place in an electronic realm. An attack against an application could well involve a physical act, such as carrying a hard drive out of a data center in a briefcase. For the most part, though, we’ll concentrate on electronic attacks in this book.
2The example would also be described in the technical literature as a “late binding” problem.
3You might consider, for example, using the (trustworthy) current time as an example of a sequence identifier, such as the Kerberos 5-minute overlap requirement.
4Note, too, that such attacks can be successful even if the attacker is not on the local segment, if the network is not doing any ingress filtering—that is, if there’s no check to see if a data packet is really coming from the destination listed inside the packet.
About the Authors
Mark Graff is Chief Cyber Security Officer for Lawrence Livermore National Lab and was formerly Network Security Architect and Security Coordinator at Sun Microsystems. He has been a Congressional expert witness, has lectured on network security topics at the Pentagon, and has appeared before the Presidential Commission on Infrastructure Survivability.
Ken van Wyk is Director of Technology for Tekmark Global Service’s Technology Risk Management (TGS-TRM) practice, and was Chief Technology Officer and Co-Founder of security firm Para-Protect Services. He was one of the founders of the Computer Emergency Response Team (CERT), and is also the co-author of O’Reilly’s Incident Response and Secure Coding: Principles & Practices
Source of this material
|This is an excerpt from Chapter 1: No Straight Thing from the book Secure Coding (ISBN: 0-596-00242-4) written by Mark G. Graff and Kenneth R. van Wyk, published by O’Reilly & Associates.|
To access the full Table of Contents for the book