root labs rdist

March 29, 2007

Chain, defense-in-depth, and mesh models again

Filed under: Crypto,Network,Security,Software protection — Nate Lawson @ 2:50 pm

Richard Bejtlich recently discussed my posts on the mesh design model. Thomas Ptacek added a post comparing the three terms I’ve described. Since there is still some confusion, let me try to summarize.

Chain: break one of N mechanisms, all equally compromise your system. Example: SSL load-balancers that terminate and then re-encrypt a session. Attack: extract the private key from the load balancer OR the backend server, whichever is easier.

Defense-in-depth: break all N mechanisms (often in order: 1, 2, 3, …) to compromise the system. Example: multiple separately-configure firewalls (i.e. DMZ). Attack: traverse firewall 1, then firewall 2, then access database server.

Mesh: break all N mechanisms at exactly the same time. Sequential, incremental compromise is not possible as it is with a purely defense-in-depth approach. Example: cryptographic key where each bit is independent of all the others. Attack: guess all bits correctly (i.e. brute force).

Each of these models has its strengths and weaknesses and should be used where appropriate. SSH public key authentication is a chain model. The server trusts your public key signature which was generated from a key that you decrypted using your passphrase. This is a useful chain since it’s much easier to remember a passphrase than a 256-byte random string. But it also means the server is equally compromised if you type in your passphrase from a public terminal, use a weak passphrase and the attacker does a dictionary attack on your private key file, or the private key is hijacked from RAM of a persistent SSH connection. That’s a series of risks that I understand and am willing to accept in order to avoid memorizing my DSA key.

Also, defense-in-depth can be used to provide multiple layers of mesh when each layer cannot be interlinked with the others to form a single mesh. For example, the mesh model can be applied to a set of self-checks that my network game client performs on itself to make sure it hasn’t been trojaned. And my server can implement extra interleaved protocol steps (another mesh) to verify that it’s talking to my self-checking game client, and not a generic one that has been swapped in by a cheater. The combination of applying the mesh model in both places is defense-in-depth since both can be attacked independently.

All this semantics isn’t useful without concrete examples. Next, I’ll be providing examples of applying the mesh model to solving common security problems.

March 28, 2007

Mesh approach versus defense-in-depth

Filed under: Crypto,Network,Security,Software protection — Nate Lawson @ 3:04 pm

A commenter suggested by email that the mesh concept in my previous post is very similar to defense-in-depth. While they are similar, there are some critical differences that are especially important when you apply them to software protection.

Defense-in-depth comes from military history where a defender would build a series of positions and then fall back each time the enemy advanced forward through the first positions.   This works in security as well.  For instance, a web server may be run in a restricted chroot environment so that if the web server is compromised, damage is limited to the files in the restricted directory, not the whole system.

The mesh model, on the other hand, involves a series of interlocking checks and enforcement mechanisms.  There is nothing to fall back to because all the defenses are active at the same time, mutually reinforcing each other.  This concept is less common than defense-in-depth for network security use due to the difficulty of incorporating it into system designs.  However, it is extremely common in cryptography.

A block cipher, say AES, is a good example of a mesh design.  Plaintext data is encrypted with a 128-bit key and output as ciphertext.  Any good block cipher is designed so that even a 1 bit change in the key or plaintext will result in a 50% chance of a bit flip for each ciphertext bit.  This is called the “avalanche effect.” What does this mean for an attacker trying to guess the key by brute force to decrypt the data?  If he is incorrect by even 1 bit, on average half the plaintext bits will be incorrect.  Another way to state this is that incrementally guessing the bits of an AES key is useless since guessing 127 of the bits correctly still gives you no information about the 128th bit.

An attacker facing a defense-in-depth challenge can break down each wall in order, picking appropriate attacks for each wall.  He only has to be smart enough at any one time to compromise the next wall (i.e., O(n) where n is the number of walls).  However, for a system designed with the mesh model, the attacker has to compromise all the walls at the same time to compromise the system (i.e., O(2^n)).  This is a significant difference in effort.

Of course, the best approach is to use the mesh model plus defense-in-depth.  For example, a protocol designer that encrypts data with AES and performs integrity checking with SHA-256 HMAC (instead of an AES CBC MAC) is using defense-in-depth since a flaw in either algorithm or construction is not likely to affect the other.

March 26, 2007

Building a mesh versus a chain

Filed under: Crypto,Network,Security,Software protection — Nate Lawson @ 3:26 pm

When explaining the desired properties of a security system, I often use the metaphor of a mesh versus a chain. A mesh implies many interdependent checks, protection measures, and stopgaps. A chain implies a long sequence of independent checks, each assuming or relying on the results of the others.

With a mesh, it’s clear that if you cut one or more links, your security still holds. With a chain, any time a single link is cut, the whole chain fails. Unfortunately, since it’s easier to design with the chain metaphor, most systems never last when individual assumptions begin to fail. There are surprisingly few systems that are designed with the mesh model, despite it clearly being stronger.

link_mesh.png

An example of a chain design is SSL accelerators that implement “split termination.” In this system, the server’s private key is moved to a middle box that decrypts the SSL session, load balances it or modifies it in some way, and then re-encrypts the data with the server’s public key and delivers it.

There are a number of weaknesses in this design beyond the obvious one that the data is in the clear while being processed by the SSL appliance. If you keep your private key in an HSM, you’ve just downgraded its security to “stored in flash and RAM of a front-end network device.” Also, now there are two places to compromise the key. Even if both offered equal security but different implementations (i.e., different bugs), you’ve reduced the private key’s security by 50% because an attacker can choose between the two targets based on their bag of exploits. But obviously, they do not offer equal security since most network devices do not include an HSM for cost reasons.

Another weakness is insertion or downgrade attacks. Insertion attacks involve the attacker connecting to the middle box and sending data to the server. The SSL appliance happily encrypts the data and delivers it to the server. If your fraud-prevention software checks for potentially phished connections by checking SSL parameters, the middle box just lied to it about the original level of security. Because the fraud prevention application’s original assumption that the other endpoint is a client was violated, it no longer can say anything meaningful about the client’s SSL connection. A downgrade attack is similar in that SSL v2 (which had trivial flaws) might be allowed on the client side but this wouldn’t show up in the connection on the server side.

The long chain of independent links introduces many potential or actual flaws. Each link has to be checked for each flaw that exists (m * n), and a failure of any link fully compromises the data.

An example of a mesh design is TLS/SSLv3 session key derivation. The two aspects that are particulary nice are the cipher downgrade prevention and combined HMAC algorithm. In SSLv2, the per-session cipher could be downgraded by a man-in-the-middle. When each side advertised its crypto capabilities, he could lie to both, saying that neither one had anything very strong and neither side could detect that this occurred. Each message in the protocol was like a link in the chain, depending on the values of the previous ones without any way to verify the previous messages hadn’t been tampered with.

SSLv3 changed this by making each side hash all the messages it had seen and use the hash as part of the generated session key. If an attacker deleted or modified messages (i.e., to reduce the advertised list of ciphers to the weakest possible), the session key for one or both sides would be incorrect. This would be detected when the Finished message was received and then both would drop the connection or try again.

The hashing primitive used for deriving keys in SSLv3 is a bit strange. It is similar to the modern HMAC construction but uses two separate hash functions, MD5 and SHA-1. At the time, this seemed insane since an attacker would have to perform a pre-image attack (even harder than a collision attack) against the hash function to find a result that would allow him to insert or modify handshake messages. Paul Kocher, the author of SSLv3, chose to use an HMAC that combined two different hash functions so that an attacker would have to find a pre-image for both. This seemed like it was going too far, increasing complexity in an area that was already quite safe. Implementers also complained at having to include two hash functions.

When the collision in MD5 and then an expected collision in SHA-1 appeared a few years ago, it didn’t seem so crazy although SSLv3 would still be secure even if it only used one hash function. I recently asked Paul why he was so focused on hash functions back in 1996 and he said, “I just didn’t trust them. MD5 hadn’t had much scrutiny and SHA-1 was brand new. So I took a conservative approach.” Of course, the genius is in knowing where it is most necessary to apply mesh principles to a design.

Email subscriptions now available

Filed under: Misc — Nate Lawson @ 11:04 am

Now with LISTSERV+Web 2.0 you can receive posts via email. See this link in the right side bar. If the provider (Feedburner) gives you any problems, let me know and I’ll remove it.

March 23, 2007

Protecting the protection code

Filed under: Crypto,Hacking,Security,Software protection — Nate Lawson @ 2:16 pm

Now that we’ve prevented casual copying using media binding, the next step is to protect the protection code itself. This is the largest and hardest task in software protection and is typically why most attackers first try to separate the prize (video/audio or software functionality) from the protection code.

The first two techniques we’ll consider are obfuscation and code encryption.

  1. Obfuscation uses non-standard combinations of data/code to make it difficult for an attacker (or attack software) to understand or target specific components of the software in order to compromise them
  2. Encryption uses cryptography (often block ciphers) to prevent the data/code from being analyzed without first obtaining the key necessary to decrypt it

Obfuscation techniques include misleading symbol names, linking code as data segments (or vice versa), jump tables, self-modifying code, randomization of memory allocation, and interrupts/exceptions. The goal is to perform the normal software functionality and protection code in a convoluted way that makes it difficult to understand or reliably modify the program flow. Typically, obfuscation is done at the assembly language level after the main software has been compiled although it can be done at other stages also. This transforms the original program P into P’, which should perform the same functions as P but in a very different way.

Encryption involves pre-processing code/data in the program with a cipher (e.g., AES, RC4) and then adding a routine to perform the decryption before executing or processing the protected data. Encryption with a standard cipher is theoretically much stronger than obfuscation if the attacker does not have the key. However, the key often needs to be stored in the program or transmitted to the program at some point so it can decrypt the data. At that point, the decrypted data or the key can be grabbed by the attacker.

These two techniques are very different, and it’s important to understand why. Obfuscation, if done properly, has the advantage of having no single point of failure. The code/data is always protected during processing until the attacker carefully unwinds the obfuscation. However, it is often slower than straightforward processing, requires manual intervention to design and insert, and is rarely integrated with the rest of the software protection well enough that an attacker can’t just go around it. Encryption offers strong theoretical security, but has a single point of failure: the key. If the key is not present in the software (i.e., a PIN to unlock add-on features), encryption offers very strong protection. However, often weak encryption like XOR is used or the key is not protected very well when stored in the program itself.

The best approach is to combine obfuscation and encryption, along with all the other techniques, offsetting the weaknesses of each with the strengths of the others. For example, the traditional approach to implementing software decryption would be to take a stock C implementation of AES and call it with the key and a flag indicating it should perform decryption.

aes1.png

The weakness here is that the key is stored separately from the decryption routine and thus may be easy to isolate and extract. Since this function is not being used for encryption or with different sets of keys, it makes sense to combine the key and cipher implementation into a single primitive: an obfuscated hard-coded decryption function.

aes2.png

One approach is to take a set of random bijections and combine it with the key and cipher to produce this fixed decryption function. Specifically, each component of the cipher is replaced with an equivalent, randomized function that computes one stage of the decryption using the fixed key. This is possible because block ciphers are composed of a number of small functions (substitute, permute or shuffle around, add key material), run over and over for a number of rounds. As long as each modified function still produces the correct results for the fixed key and variable data, the combination of them will still compute the same result as stock AES. (More details on this technique, called “white-box cryptography,” can be found in these papers on DES and AES.)

Of course, if an attacker can just isolate and enslave this decryption function to recover arbitrary data from the program, it isn’t very effective. That’s why other techniques are needed to tie the decryption function to the entire software protection.

Next, we’ll cover anti-debugging and anti-tampering techniques.

March 22, 2007

Media binding techniques

Filed under: Hacking,Security,Software protection — Nate Lawson @ 3:12 pm

Media binding is the first step of copy protection, a specific type of software protection. If the attacker can’t just duplicate the media itself, he will have to attack the software’s implementation of media binding. Media binding is a set of techniques for preventing access to the protected software without the original media.

Content protection (a specific form of copy protection) starts by encrypting the video/audio data with a unique key, and then uses media binding and other software protection techniques to regulate access to that key. Since the protected data is completely passive (i.e., stands alone as playable once decrypted), managing access to the key is critical. However, software copy protection is more flexible since software is active and its copy protection can be integrated throughout its runtime.

The Blu-ray content protection system, BD+, is more of a software protection scheme (versus a content protection scheme) since the per-disc security code is run throughout disc playback to implement the descrambling process. Thus, each disc is more of a unique software application instead of passive video/audio data. AACS is more of a traditional, key-based content protection system.

There are three ways to bind software to media:

  1. Verify unique characteristics of the original media
  2. Encode data in a form that can’t be written by consumer equipment
  3. Attack particular copying processes and equipment involved

Verifying the media involves one or more checks for physical aspects that are difficult to duplicate. Checks involve intentional errors, invalid filesystem data, data layout alignment, and timing of drive operations or media. The key point is that some logic in the software is making a decision (i.e., if/then) based on the results of these checks. So attackers will often go after the software protection if they can’t easily duplicate the media characteristics.

Encoding data involves modifying the duplication equipment, consumer drive, and/or recordable media such that the real data cannot be read or written on unmodified consumer equipment and media. This is usually more powerful than verification alone because attackers have to modify their drives or circumvent the software protection before getting access to the software in the first place. Game consoles often use this approach since they can customize their drives and media, even though they usually start with consumer designs (i.e., DVD). Custom encodings can be used with verification of the encoded data for increased strength.

Attacking the copying process involves analyzing the equipment used to make copies and exploiting its flaws. For example, most DVD ripping software uses UDF filesystem information to locate files while hardware DVD players use simpler metadata. So phantom files can be provided that only the copying software sees that corrupt the rip. The problem with attacking the copying process is that it is relatively easy to update copying software, so usually this technique has a short shelf life. However, it can be useful as part of an overall strategy of increasing an attacker’s costs.

Obviously, if the attacker has access to the same duplication equipment that the author uses, nothing can prevent them from making their own media. Other mechanisms, such as revocation, must handle this case farther down the chain.

Next, we’ll discuss protecting the protection code itself.

Next Page »

The Rubric Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 89 other followers