Speaking with Cryptographic Oracles
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Crowley, Daniel
Cryptography is often used to secure data, but few people have a solid understanding of cryptography. It is often said that if you are not strictly a cryptographer, you will get cryptography wrong. For that matter, if you ARE a cryptographer, it is still easy to make mistakes. The algorithms might be peer reviewed and unbroken for 15 years, but if you use them incorrectly, they might leak information. Cryptographic oracles are systems which take user-controlled input and leak part or all of the output, generally leading to an attacker being able to defeat the cryptography, in part of in whole. In this talk, methods for finding and exploiting encryption, decryption, and padding oracles with minimal cryptographic knowledge will be discussed. Daniel Crowley is an Application Security Consultant for Trustwave's SpiderLabs team. He has been working in the information security industry for over 6 years and has been focused on penetration testing, specifically on Web applications. Daniel is particularly interested in vulnerabilities caused by a failure to account for little known or even undocumented properties of the platforms on which applications run. He especially enjoys playing around with Web based technologies and physical security technologies and techniques. Dan also rock climbs and makes a mean chili.
 My name is Daniel Crowley. I work for spider labs. Let's just dive in. So one quick note, I'm a web application security guy. That's what my focus is. So this talk is going to be sort of centered around applying these concepts inside sort of a web application centric world. I'm not a cryptographer, but that's okay because these attacks can be used in such a way where you don't need to know about the underlying crypto. Although obviously if you know more about it, it's going to help you. Should you want to contact me? My contact information can be found here. And these slides should be on the CD as well. So groovy. So the presentation topic is about encryption or about cryptographic oracles. We're going to be talking a little bit about encryption oracles, decryption oracles and padding oracles, which are generally used as decryption oracles and also as encryption oracles in certain circumstances. So like I said, little to no cryptographic knowledge is required. I'm going to be going over some basic terminology, some basic concepts. So if you don't know anything about crypto, well, I'm kind of surprised you decided to show up at this talk, but thank you. But I'm going to try to cater to you as well. So good stuff. So let's talk about something that are not the presentation topic. So we're not talking about the oracle. We're not being harvested for energy by robot overlords, possibly. We're not talking about the company oracle. Fun fact, if you Google for any crypto word followed by oracle, you'll probably find oracle users asking how to encrypt their database. We're also not talking about Google, the internet oracle. We're not talking about cryptographic gurus like Eddie Shamir. If you don't know who Shamir is, he's the S in RSA. Also awesome, but not the topic. We're not talking about new attacks on old crypto. I will be clarifying some details on the default encryption algorithm in cold fusion, but that's not exactly a new attack that's already known. I've never seen it made public. I wasn't able to find any public details on why Adobe says this is a weak cipher. No, stay away. We're also not going to be talking about how Patagon oracle attacks work. Now if you would like to know the presentation from Echo party, patting oracles everywhere is a fantastic resource and it talks about the implementation of patting oracles as decryption oracles and using that against a couple different things, Java server faces, ASP.net, so groovy stuff. I'm also going to drop a little bit of Ode on the DEF CON drinking game, which is where you listen for buzzwords in presentations and then drink when you hear them. So APT iPad, APT China cyber war, cloud mobile botnet, cloud cloud, cyber twilight, APT SunSu, RSA HB Gary, PCI Skeda in the cloud, cyber war, LOLSEC, APT China cyber war, weaboo, WikiLeaks mobile, LOLSEC. So now that you're nice and primed for this talk, let's get into a primer on cryptographic terms. So very basic stuff here. So a cipher is just a system for mathematically scrambling data that you want to be hidden from certain parties. So cipher is a system for scrambling and unscrambling data. The key is the one part that you keep secret. The key is the part that sort of missing variable that somebody needs to know in order to be able to unscramble the data. The initialization vector is used in a similar way, but it's not always necessarily private. The idea of the initialization vector is so, on says a second key, which doesn't necessarily need to be private, although in a lot of cases it should be. The point of the initialization vector is so that when you encrypt the same thing with the same key, you can change up the initialization vector and the cipher text won't look the same. Now getting on to that term, plain text and cipher text are the unencrypted and encrypted versions of the message, the human readable and unreadable. An encryption and decryption are turning plain text to cipher text and vice versa. So we can split the set of ciphers into stream and block ciphers. Now if there are any cryptographers out there, maybe there's something else that I'm unaware of and I'm apologizing about that. But as for stream and block ciphers, with a block cipher you take a chunk of the data, you take the message in chunks and encrypt each of them one by one. So the key is used directly to transform the plain text into the cipher text. Whereas with stream ciphers, you're encrypting one character at a time, one byte at a time. And the key is used as a seed to a pseudo random number generator. It might be worth mentioning what a pseudo random number generator is. It generates numbers that look random but are not. For instance, you can use hashing algorithms as pseudo random number generators. So you can use MD5 and hash something repeatedly to generate a series of very predictable but random looking numbers, things that are hard to predict but feed the same password in and iterate through MD5 1,000 times, you're still going to end up with the same hash, the same set of numbers. And then those numbers are used to transform the plain text into cipher text. So let's talk about some basic mistakes. One, using a keyless cipher. If you're using a keyless cipher, it is not secure unless it's totally private, unless nobody else knows how the algorithm works. And even then it's probably not very secure. Also, reusing keys and initialization vectors, that's a bad idea and we'll see that shortly. It makes oracle attacks far more dangerous and it can also seriously weaken the integrity of stream ciphers. Web is an example of this. And leaking data from crypto operations, that sort of builds the foundation for oracle attacks. So I said the word oracle several times and now I'm going to give you a vague and generalized definition and then clarify a little bit. So an oracle is any system that takes in user input, processes it and gives the output. Now when we're talking about that in the sense of cryptography, we're talking about taking in plain text or cipher text and then usually encrypting or decrypting and leaking something about that operation. Whether that's the corresponding plain text to an input cipher text, whether that's the cipher text to an input plain text, whether it's info about the operation, maybe it's success or failure, or maybe it could be just simply a sample from a pseudo random number generator, a random number generator, which is referred to as a random oracle. We're not really talking about that but thought I'd mention it. So now let's talk about how you can find oracles in web applications anyway. So first thing you're going to want to do is try to identify input. Now when we're trying to identify oracles, it's easier for us to identify encrypted data. It's a lot easier to find than data that's going to be encrypted because how can we tell? So when we're looking for decryption oracles, we're going to look for cipher text being passed in as some sort of input. So you're going to want to look for all points of user input, get post URL, anything in the cookie field or in HTTP headers which is a little bit rare but can happen. And then identify those which might be encrypted. Usually when you have encrypted data, it spans a pretty wide character set so it's not really possible to put that through the majority of systems and something might be interpreted as a Merida character. So usually you have some sort of encoding scheme whether that's URL encoding or base 64 encoding or just putting it to ASCII hex. So if you decode that data and it looks random and there are some tools out there for doing entropy analysis to see how random is this. So another thing that you can do is modify the values. Sometimes this will generate, this will give you decryption related errors. The other thing is if you modify a value in the middle of some piece of cipher text, you might see some resulting text on the response that is fucked up beyond a certain point. So here's a little bit more on that. So when you're looking for the decrypted output, it might be reflected immediately to you in the HTTP response, again still talking about web apps. Or it might be in an error. And this is something that's a little trickier. There's a lot of systems where the data might be processed but it's never going to be given to the user. Which is probably the proper way to do things. But some errors will leak information. I'm sure many of you are aware of that fact but this is also important in the context of oracles. So it might be given a later response. So your data might be processed and then put somewhere where it's not going to be given back to you immediately. You need to find it somewhere else. It might be inferred from modified output. So maybe based on what the plain text is, you are getting different things. It might be stored and not shown. So encrypted data is often written to files or into databases. One example of where you might find an encryption oracle is through the use of an SQL injection flaw. So if you find an SQL injection flaw, you can find some piece of data that's encrypted in the database and then as long as you can add data or change data, let's say that passwords are being encrypted in the database. Then you can change your password repeatedly and use the SQL injection flaw to look at what your password has become every time you change it. So this allows you to use it as a sort of encryption oracle. And I've actually done this before and we'll talk a little bit more about the instance where I've seen that. So here's an example of where you might find a decryption oracle. So when novices are writing web applications, they frequently write one particular kind of file inclusion flaw in a script that's supposed to just make their lives easier. So essentially what they're doing is including a header, some page that gets passed in by user input, and then a footer so that they don't have to put the header in the footer and everything and they can change the header and footer for all the pages arbitrarily at any time they wish. So let's say that this developer found out, oh crap, I've got a file inclusion flaw. I know all sprinkle magic encryption dust on it. So you encrypt the input and that way you expect nobody is going to be able to do anything with this. Now maybe. So let's assume that the errors are verbose. So if you take some cipher text from somewhere else, let's say that they're using the same key and initialization vector and same cipher in some other place, you can take that cipher text and plug it in here and if it's not going to point to some valid file, the application is going to respond by saying hey, I tried to open this path here and it didn't work. And that path will of course include the decrypted output from this operation. So that's an example of where you might find a decryption oracle. I put a picture of a kitten in here so that it wouldn't be just such a wall of text. It really has no relation whatsoever to the content. Thank you. I like the cat too. So again, we're looking for encrypted data when we're talking about encryption oracles but in this particular case we're looking for it as output as opposed to as input. You'll frequently find this sort of thing in cookies and hidden variables in databases and file resident data. And then the next thing you're going to need to do is to determine the point of entry. So when you're looking at this encrypted output, usually it'll say, you know, it'll have some identifying information. Like maybe it'll be a variable that's in a hidden field and that variable will be named pet's name. So you really don't want to be exposing people's pet's names. It's very important. Very, okay, maybe not sensitive. But let's say it's pet's name. So you're going to look for where you can input a pet's name and then whatever. So you'll be, you can see, you can try modifying that and seeing if you get different cipher text. So some frequently encrypted data is client side state variables. So if you're keeping track of a user's session, certain things about their login, you want to store that on the session to keep it out of the client's hands. But once you start to experience more traffic, that's not really a scalable thing. You know, you start to store too much data and have too much session data. Actually there's an OOS page on a DOS attack involving creating large numbers of sessions when people are storing too much session data. So this causes its own problems. So some people will say, okay, we'll let's encrypt the data and then give it to the client and they'll pass it every time they are making a request. And that way we'll keep the state, we'll keep the session variables, but we won't have to hold on to them. So if you control part or all of that, you have an encryption oracle. So for instance, the view state in ask.net is frequently a partial encryption oracle. Now its usefulness is somewhat limited in that the key being used is only used for several other things inside ask.net. But I have seen people who just want to use one key for everything and will actually go to great lengths to use the machine key as the same key for encryption. So another frequently encrypted piece of data is passwords, financial data is also frequently encrypted. Anything sensitive is often subject to encryption. So trying to modify these things and then look for any of those encrypted pieces of data changing is a good idea. But being encrypted is not enough, we also need to be able to manipulate it. So here's an example of where you might find an encryption oracle. Let's say that you have an authentication cookie. So this is a situation where you have session data that you want to store on the client, with the client encrypted and not store as session variables and hold down the server. So consider an authentication cookie that's the username concatenated with a colon, password hash, colon and a time stamp. So we can't do any sort of replay attacks because of the time stamp. And we'll assume that the usernames can't include a colon character so we don't have delimiter injection, no field injection stuff. But this does mean that we have a partial encryption oracle. We can't control the whole thing but we control the username. If the only restriction is that we can't control the colon, then we can do a lot of interesting things. We can encrypt a lot except we just can't control what goes at the end of it. Now there are definitely ways to get around this. Does anyone know what null byte injection is? Poison null byte. Okay, so we've got some. The poison null byte is an issue where the null byte, hex zero, is seen as some frameworks, seen by some frameworks as just another character and others, it's a string delimiter. So for instance when you're doing file inclusion attacks, if you're tacking dot html onto the end of everything and thinking, well, this is fine, this is no problem, everything's good here, they can only include html files, you put a null byte on there. Most web application frameworks will see that as just another character but once it gets passed back to the file system, pretty much every operating system is going to truncate at the null byte because they're C based and C is the language in which the null byte is a string terminator. So it cuts off the end. So we can do some similar attacks here. So the fact that we can't control the end is actually just fine for a lot of attacks. So that's interesting. So we can register with some username and log in and take a look at that cookie and we register with the username of whatever it is we want to encrypt. So groovy stuff there. So I wanted to mention padding oracles as well. So with a padding oracle, the input has to be encrypted and it has to be with a padded block cipher. With stream ciphers, you're encrypting one byte by one byte so the end of the cipher text, sorry, the end of the plain text is just where the text ends and not where you've put some arbitrary marker. So it also has to be distinguishable when you've passed something in that has valid padding or invalid padding. And this is the essence of a padding oracle. Now, I know that with a padding oracle, you can do all sorts of crazy things and you can take over an old ASP.NET installation. But really, all a padding oracle allows you to do is to tell whether or not the padding was actually valid. Now, in the case of the cipher block chaining mode, where the cipher text for each block in a block cipher is used as the initialization vector for the next one. So as to prevent repetitive plain text from producing repetitive cipher text, you know, to remove any sort of distinguishable patterns that might allow you to see that this is one, this is this message and this is that message when they're encrypted. That's actually going to allow you to change the padding bytes and then change the corresponding bytes in the previous block until you get valid decryption again. So until you get to the point where the padding is valid again. So, like I said, I don't want to go too much into how padding oracle attacks work. But padding oracles can in that way be converted to decryption oracles. Now, the interesting thing is, Duong and Rizzo who presented the padding oracles everywhere presentation also talked about an attack where you can use this decryption oracle functionality of a padding oracle in this particular type of situation to encrypt data. Where you're just changing the data until you get the output that you really want. The way that it works, it might be limited in that the first block is garbled. So if you end up finding a padding oracle and using it as an encryption oracle, you can't control the first block. And again, there are some situations where that's not a problem, but it's something to be aware of. So let's talk a little bit more about exploiting these crypto oracles. So, to convert one oracle into another, most of this involves brute forcing. So we talked about padding oracles and using them to decrypt and encrypt data. Decryption oracles can be converted to encryption oracles. The idea is that you just brute force, guess a whole bunch of cipher text until it decrypts to what you want it to. And that way you have the plain text you want and your input is really what you're looking for. Now, since block ciphers do this several characters at a time, you need to guess all of the characters in that block at the same time. So you need to keep doing that until you get it right. So that's a little bit more complex, a little bit more heavy on the queries. Whereas if you're talking about a stream cipher, that's one byte at a time. So you can just guess even one bit at a time until you get exactly what you're looking for. So encryption oracles can be converted to decryption oracles in a very similar way. And again, the same difference between the effectiveness when you're talking about stream and block ciphers applies. So we're going to talk about doing a little bit of crypto recon using oracles. So let's say you have an encryption oracle. If you encrypt the same plain text twice and it comes out to the same cipher text, you know you have the same key, same initialization vector and a deterministic cipher being used to encrypt the data. So if the cipher texts are identical, you know all of these things are true. You can also check for stream versus block ciphers. It's pretty easy to tell. So you can encrypt some piece of plain text and if the size is dependent on, you know, the size of the plain text divided by 8 or 16 or something like that, then it's a block cipher. And if it just grows and with the plain text, no matter how many bytes you're tacking onto the end of it, you know, linear relationship, you have a stream cipher. You can also check for ECB block mode. So this is a little bit different from CBC, which I described earlier, in that each block is independent of other blocks and are encrypted independently. So if you have repetitive plain text like 8 uppercase A's, 8 uppercase B's, 8 uppercase A's, 8 uppercase B's, and that's your plain text, your cipher text is going to have blocks 1 and 3 being identical and blocks 2 and 4 being identical. So you can see those patterns. So you can try to show that, you can try to, you know, guess that behavior. You can try to get it to produce that behavior with an encryption oracle. And ECB, you know, you can obviously see how that's a problem because we can then take those blocks and rearrange them however we like. So we can also check for stream cipher feedback. So when you're working with a stream cipher, sometimes the encryption of some particular bit, whether or not it gets flipped, is dependent on earlier bits in the plain text or the cipher text. What we can do to check on that is to encrypt some plain text and then modify the beginning of it and see if the rest gets screwed up. So let's talk about using oracles to attack some bad algorithms. So occasionally people try to write their own crypto and it doesn't work out too well. Unless you're a cryptographer and even then sometimes it doesn't work out so well. So let me show you some real homespun crypto that I've seen in the wild during a pen test. So here's a plain text, hello, and it's corresponding cipher text which is a bunch of what looks like gibberish. So I found an SQL injection flaw but it didn't allow me to do anything but read data from the database. So I said, okay, well, I'll get all the credentials from the database. Turns out the passwords were all encrypted. And it was this bizarre looking stuff that doesn't really look like strong crypto. So I thought, okay, well, let's play with this. So the first thing, I want to know if there's substitution. Are we switching characters for others? And that's definitely true. But if we put in four uppercase A's, we can see, yeah, there are no uppercase A's in that. There is definitely substitution here. We can already start to see patterns in this as well. The plain text is repetitive, the cipher text is repetitive as well. So the next thing we're looking for is if there's transposition, if characters are being switched around before or after the substitution occurs. So we'll submit AABB. And we see something similar to what we saw last time. And you can already start to see patterns in this very, very quickly. So there doesn't seem to be any transposition. And we can see more patterns. The K also seems to be a delimiter. So one thing that you'll notice if you look at this, there are a couple different ‑‑ you can have different lengths with these characters. So the K is just standing in to separate characters so that even with variable lengths for the cipher text version of different characters. Well, let's move on. So it also doesn't seem to change on position. So next thing we do is we submit a variation on the last pattern. And we notice that, you know, more of our assumptions are proving to be true. That, you know, A, like this ABE is uppercase B and LO is A. So this is pretty much exactly what we expected. The substitution doesn't seem to change no matter where the character is in the plain text. So next thing we'll do is just submit every character. And we get back the entire key. So we see what every character is substituted to. So this is a trivially weak cipher. And the oracle has helped us just totally destroy this cipher. So more bad algorithm stuff. Some people use ZOR to encrypt data. The funny thing about ZOR is that it has this weird property. So if we use an XOR operation between a plain text and its corresponding cipher text, we get the key. So that's ugly. And you really don't want to be using ZOR. So another thing about ZOR, for some simple ciphers like ZOR, the encryption routine is the decryption routine. Thus, an encryption oracle is also a decryption oracle. Which means that I can encrypt or decrypt any data that you're using. Which essentially means that this encryption is totally useless as soon as an encryption oracle is introduced. And even before that actually. So please don't use ZOR. So now I'm going to do a demonstration. We're going to take a look at the default encryption algorithm in cold fusion. The CFMX compact algorithm. Now, I did a little bit of Googling on this and found that everyone said, hey, don't use this algorithm. This is weak. Adobe says this is the weakest cipher that we have. But for some reason they make it the default one that you use. So, okay. So I have... So, I have a little bit of a bit of a... Oops. What? Oh, hey. Thanks guys. So, I have a little bit of a... So, I have a little bit of a... So, this is a simple script I wrote in cold fusion to take a plain text. And let me turn intercept off here for a moment. And it will return to me the cipher text of whatever I put in. So, this is just a very contrived example of an encryption oracle. So, here's something interesting. I've changed the end of this and we immediately see modification in the cipher text. And if I continue to delete characters here, you can see that this is chopping off more and more of the cipher text. Which means that this is a stream cipher. And also because we can see this changing... But the prefix remains the same. That this is also a stream... That this is also using the same key, same IV and a deterministic cipher. So, next thing that we can do is change the beginning here. And we can see that the end doesn't change. So, we're not talking about any sort of feedback going on, apparently. So, this is interesting. Now, what this actually means, because stream ciphers, essentially, once it comes down to it, are just crosswise or with a nice and complex key generation algorithm. And the only thing separating it from that in essence is this feedback. So, not having feedback is really bad. So, we're going to see why, right, about now. Now, here's something interesting. So, can anybody tell me what X crosswise door with null is? X. So, if we're essentially... If we have a cipher that's essentially crosswise or and we put in null as the plain text, what are we going to get as the cipher text? The key, the key stream. So, I'm going to get the first six bytes of the key stream here. And I'm going to copy this into burp, which is a lovely tool. And decode this as base 64. So, we have the first six bytes of the key stream here, which is great. So, we're going to stick that into... Oh, no, I don't want that. All right. Lovely. Okay. So, next thing we'll do here, we'll get a cipher text sample. What are you doing? So, here's the encrypted version of the word DEF CON. So, let's copy that, put that into decoder. And now, I'm going to do a little bit of ZOR here. So, we're going to copy this into the decoder. And now, we're going to copy this into the decoder. And we're going to copy this into the decoder. So, hex 42, crosswise OR with hex 26. So, we have a D. And then, an E. And then, an E. And then, we can go on and on like this and crosswise OR this key stream with whatever cipher text we have and decrypt it. So, groovy stuff. Because we already have an encryption oracle, that's nice. Now, one funny thing is that if we... Like I said, since this comes down to essentially just crosswise OR, if we have plain text and corresponding cipher text, we can actually just crosswise OR those two together and get the key stream anyway. So, we don't even need an encryption oracle now that we figured all of this out. So, in case the point hasn't been made clear yet, if you're using cold fusion, pick a different algorithm than the default. Right. So, now, let's say that we don't have a shitty cipher. Let's say that we're using something like AES. And let's say we're even using it in a really, really decent way. So, the thing is people tend to reuse keys in IV. So, let's say that the only mistake we're making here is to reuse the same key in IV in multiple places. And a lot of people do that because they figure, well, if somebody can break in and figure out the key, then I... You know, what's the big deal? So what? So what if I'm using it? It's the same stuff in different places. The other thing is that if developers don't think that you can mess with input, if they don't think that you can fiddle with it at all, they might not sanitize it. And the fact they probably won't sanitize it. And you would think that if you're using a message authentication code, which I won't go into explaining that, but essentially it provides protection against modification, you would think that this is tamper proof, that there is no way that this needs to be sanitized. So why bother? Why spend the cycles? So let's say that you have an encrypted password, Mac, in a cookie, like this auth cookie that we're talking about. And that's checked against the database on each request needing authentication. You find an encryption oracle somewhere else that allows you to encrypt arbitrary data. So you encrypt single quote or one equals one. Let's say it's just a password that's in this cookie and then plug the resulting value into the cookie. Well, that's ugly. So let's take a look at this in action. So here we have a little login script that takes a username and a password. And this is what it looks like when you log in successfully. So let's take a look at this in the history here. This resolution is killing me. So this is ugly because it passes in the URL and that's terrible, but ignore that. Ignore me. Thank you. So you can see that this sets a username and password cookie. Now if we stay on this page, if we just go back to it, you'll note two things. We're still logged in here, but it still shows us the login prompt. Now something else that's interesting, the username field is populated. And if we look at the response, all we saw was the cookies. Hold on a second. Yeah. So all we see as for the parameters in the request are this encrypted username and password cookie. So this is actually decrypting the cookie and then sticking it in the output. So we've got a decryption oracle here, but it's not what we're talking about right now. Now let's try some SQL injection here. Let's clear the cookies. And then try admin or double single quote equals double single quote. And we'll put the same thing in the password. So we take a look at the username here and notice that these single quotes are filtered out. They're removed. Now people will generally filter the username but not the password because it's going, you know, if it's going to be hashed and then stuck in a database, then who cares? The thing is though, but in this particular scenario, just a spoiler, this password parameter is not being filtered before it gets hashed. So we see that the username and password fields are the same and in the response, we get different ciphertext for the username and the password. So we can say to ourselves, maybe this password parameter is not being filtered. So let's copy that and use that as our username cookie as well. If it works, we should have SQL injection. Maybe. So we go back to the index and let's turn intercept on and burp so I can actually catch this as it goes. So we'll grab the password cookie which contains the SQL injection string encrypted and stick that into the username parameter. Hit forward. Oh, that's ugly. Well, that's what I get for doing a live demo, I guess. Let's try this again. Yeah, that's ugly. So we can see that the password is not being filtered. All right, well, I'm not going to waste any more time on this live demo. It works. So we get logged in and it bypasses the SQL injection checks where we would not have been able to by simply putting the strings directly into the username or password field. So groovy stuff. I'm sorry, it didn't work. So let me just log in with the valid credentials and I'll show you the next portion. So we have a couple different URLs here that we now have access to. And if we take a look at the input here, we have some sort of ciphertext being passed to a file parameter in get files.cfm. And I wish the resolution was a bit bigger because it would be easy to see that the beginning of the ciphertext, so here we see 9 slash f, 9 slash f. So these ciphertexts are starting with the same thing. Now, I wonder what would happen if we were to plug that data in here. So we get an error which decrypts that ciphertext for us. So we have another decryption oracle here. We also can encrypt arbitrary data so we can just stick anything into the password field and then grab the cookie and put it somewhere else. So let's do that. So what I'm going to do is to access a file in this test bed called secretdata.txt which is in the root. And so I'm going to put a whole bunch of dot dot slash secretdata.txt and then we can just plug it in here. So we can just plug it in here and then we'll have this attack string as our password cookie. All right, everybody think good thoughts. Well, that's ugly as well. But you can see what I was trying to do here. Apparently I needed more dot dot slashes. But you can see how this was working and you would have seen my secret love for Moxie Marlin's bike. Also a little sec APT return on investment. So I'm going to go ahead and do that. Exactly. I encrypt whatever password I like and in the cookie I get the cipher text for it. Yeah. It absolutely would. Yeah, the user name field is another decryption oracle. And actually, let's, and I think let's see that real quick. That's a demo I know will work. I say that now. So intercept on fire. Okay. So we'll take this password cookie and put that into the user name field. Hit forward and then we can put that in the user name field. And now we can see the decrypted version of that cipher text. Thanks for mentioning that by the way. I nearly forgot about that one. So that's a nice way to point out this next portion which is that with a decryption oracle any cipher text that uses that same key initialization vector cipher is subject to decryption if you can just find a decryption oracle. And maybe you've seen already that this is not too hard to do. It's a matter of making the right mistakes. So we already saw that. So that demo is done. So one last take home point that I want to make is that if you can find an encryption oracle and a decryption oracle, it doesn't matter what you're using. As long as keys and IVs are reused by the way that cryptography works, anything that's encrypted and decrypted with the same key IV cipher is going to be the plain text. So whatever cipher you're using, whatever key you're using, whatever padding you're using, whatever cipher mode you're using, it doesn't matter if you can find an encryption or decryption oracle. Anything with that same key IV and cipher is now as good as plain text. So what can you do? I don't want to make too many suggestions because like I said, not a cryptographer and the suggestion I might give you might be vulnerable to some other attack. Right now, I think there's a problem in that it's hard to do crypto right. Unless you're a cryptographer. I think keys are as nice because it just says, hey, encrypt, decrypt, and you don't have to specify an algorithm in a padding mode and have to know what all that entails. But there's still some, obviously giving out information is bad. Leaking output from cryptographic operations is bad. Try not to give the output. Now, in certain circumstances like the example of the encrypted session data, that's ugly and there's not really a great way that you can do that right. One thing that you can do, however, is to use a different IV. Don't reuse keys and IVs if you can help it. So that's good stuff. Try to suppress any indication of success or failure if you can. Again, that's not really terribly plausible in a lot of situations. And timing, if you really want to go the extra mile, try to suppress that. But that's, I think, more trouble than it's worth. It's worth noting, however, that timing information can give away the success or failure of an operation. Also authenticating your crypto is a good idea. Encryption is good, but if people can fiddle around with the message and end up with a valid output, a valid cipher text, it will still be subject to whatever operation it was going through before. And in some cases, it doesn't matter what the plain text actually is. So, for instance, if you have an encrypted value which represents the amount of money you have in your bank account, your chances are pretty good of getting something better than zero. So if you're at zero and you just mess around with the cipher text and you can produce a valid cipher text, it's probably better than zero. So authentication is good because it doesn't, it prevents people from messing with that, at least to some degree. Also, you want to encrypt and then MAC, if you MAC and then encrypt, it still allows for padding oracle attacks. So that's it. If you have any questions, I'd like you to come to the Track 2 QA room and ask them there. So no questions right now. Thank you.
 My name is Daniel Crowley. I work for spider labs. Let's just dive in. So one quick note, I'm a web  application security guy. That's what my focus is. So this talk is going to be sort of centered  around applying these concepts inside sort of a web application centric world. I'm not a  cryptographer, but that's okay because these attacks can be used in such a way where you don't need to  know about the underlying crypto. Although obviously if you know more about it, it's going to help  you. Should you want to contact me? My contact information can be found here. And these slides  should be on the CD as well. So groovy. So the presentation topic is about encryption or about  cryptographic oracles. We're going to be talking a little bit about encryption oracles, decryption  oracles and padding oracles, which are generally used as decryption oracles and also as encryption  oracles in certain circumstances. So like I said, little to no cryptographic knowledge is  required. I'm going to be going over some basic terminology, some basic concepts. So if you  don't know anything about crypto, well, I'm kind of surprised you decided to show up at this talk,  but thank you. But I'm going to try to cater to you as well. So good stuff. So let's talk about  something that are not the presentation topic. So we're not talking about the oracle. We're not  being harvested for energy by robot overlords, possibly. We're not talking about the company  oracle. Fun fact, if you Google for any crypto word followed by oracle, you'll probably find  oracle users asking how to encrypt their database. We're also not talking about Google, the internet  oracle. We're not talking about cryptographic gurus like Eddie Shamir. If you don't know who  Shamir is, he's the S in RSA. Also awesome, but not the topic. We're not talking about new  attacks on old crypto. I will be clarifying some details on the default encryption algorithm in  cold fusion, but that's not exactly a new attack that's already known. I've never seen it made  public. I wasn't able to find any public details on why Adobe says this is a weak cipher. No,  stay away. We're also not going to be talking about how Patagon oracle attacks work. Now if you  would like to know the presentation from Echo party, patting oracles everywhere is a fantastic  resource and it talks about the implementation of patting oracles as decryption oracles and using  that against a couple different things, Java server faces, ASP.net, so groovy stuff. I'm also  going to drop a little bit of Ode on the DEF CON drinking game, which is where you listen for  buzzwords in presentations and then drink when you hear them. So APT iPad, APT China cyber war,  cloud mobile botnet, cloud cloud, cyber twilight, APT SunSu, RSA HB Gary, PCI Skeda in the cloud,  cyber war, LOLSEC, APT China cyber war, weaboo, WikiLeaks mobile, LOLSEC. So now that you're nice  and primed for this talk, let's get into a primer on cryptographic terms. So very basic stuff  here. So a cipher is just a system for mathematically scrambling data that you want to be hidden  from certain parties. So cipher is a system for scrambling and unscrambling data. The key is the  one part that you keep secret. The key is the part that sort of missing variable that somebody  needs to know in order to be able to unscramble the data. The initialization vector is used  in a similar way, but it's not always necessarily private. The idea of the initialization vector  is so, on says a second key, which doesn't necessarily need to be private, although in a lot  of cases it should be. The point of the initialization vector is so that when you encrypt the  same thing with the same key, you can change up the initialization vector and the cipher  text won't look the same. Now getting on to that term, plain text and cipher text are the  unencrypted and encrypted versions of the message, the human readable and unreadable. An  encryption and decryption are turning plain text to cipher text and vice versa. So we can  split the set of ciphers into stream and block ciphers. Now if there are any cryptographers  out there, maybe there's something else that I'm unaware of and I'm apologizing about that. But  as for stream and block ciphers, with a block cipher you take a chunk of the data, you take the  message in chunks and encrypt each of them one by one. So the key is used directly to  transform the plain text into the cipher text. Whereas with stream ciphers, you're encrypting  one character at a time, one byte at a time. And the key is used as a seed to a pseudo random  number generator. It might be worth mentioning what a pseudo random number generator is. It  generates numbers that look random but are not. For instance, you can use hashing algorithms  as pseudo random number generators. So you can use MD5 and hash something repeatedly to  generate a series of very predictable but random looking numbers, things that are hard to  predict but feed the same password in and iterate through MD5 1,000 times, you're still  going to end up with the same hash, the same set of numbers. And then those numbers are  used to transform the plain text into cipher text. So let's talk about some basic mistakes.  One, using a keyless cipher. If you're using a keyless cipher, it is not secure unless it's  totally private, unless nobody else knows how the algorithm works. And even then it's  probably not very secure. Also, reusing keys and initialization vectors, that's a bad idea  and we'll see that shortly. It makes oracle attacks far more dangerous and it can also  seriously weaken the integrity of stream ciphers. Web is an example of this. And leaking data from  crypto operations, that sort of builds the foundation for oracle attacks. So I said the  word oracle several times and now I'm going to give you a vague and generalized definition and  then clarify a little bit. So an oracle is any system that takes in user input, processes it  and gives the output. Now when we're talking about that in the sense of cryptography, we're  talking about taking in plain text or cipher text and then usually encrypting or decrypting and  leaking something about that operation. Whether that's the corresponding plain text to an input  cipher text, whether that's the cipher text to an input plain text, whether it's info about  the operation, maybe it's success or failure, or maybe it could be just simply a sample from a  pseudo random number generator, a random number generator, which is referred to as a random  oracle. We're not really talking about that but thought I'd mention it. So now let's talk about  how you can find oracles in web applications anyway. So first thing you're going to want to  do is try to identify input. Now when we're trying to identify oracles, it's easier for us to  identify encrypted data. It's a lot easier to find than data that's going to be encrypted because  how can we tell? So when we're looking for decryption oracles, we're going to look for  cipher text being passed in as some sort of input. So you're going to want to look for all  points of user input, get post URL, anything in the cookie field or in HTTP headers which is a  little bit rare but can happen. And then identify those which might be encrypted. Usually when  you have encrypted data, it spans a pretty wide character set so it's not really possible to  put that through the majority of systems and something might be interpreted as a Merida  character. So usually you have some sort of encoding scheme whether that's URL encoding or  base 64 encoding or just putting it to ASCII hex. So if you decode that data and it looks  random and there are some tools out there for doing entropy analysis to see how random is  this. So another thing that you can do is modify the values. Sometimes this will generate,  this will give you decryption related errors. The other thing is if you modify a value in the  middle of some piece of cipher text, you might see some resulting text on the response that is  fucked up beyond a certain point. So here's a little bit more on that. So when you're looking  for the decrypted output, it might be reflected immediately to you in the HTTP response,  again still talking about web apps. Or it might be in an error. And this is something that's a  little trickier. There's a lot of systems where the data might be processed but it's never going  to be given to the user. Which is probably the proper way to do things. But some errors will  leak information. I'm sure many of you are aware of that fact but this is also important in the  context of oracles. So it might be given a later response. So your data might be processed and  then put somewhere where it's not going to be given back to you immediately. You need to find  it somewhere else. It might be inferred from modified output. So maybe based on what the plain  text is, you are getting different things. It might be stored and not shown. So encrypted data is  often written to files or into databases. One example of where you might find an encryption  oracle is through the use of an SQL injection flaw. So if you find an SQL injection flaw, you can  find some piece of data that's encrypted in the database and then as long as you can add data or  change data, let's say that passwords are being encrypted in the database. Then you can change  your password repeatedly and use the SQL injection flaw to look at what your password has become  every time you change it. So this allows you to use it as a sort of encryption oracle. And I've  actually done this before and we'll talk a little bit more about the instance where I've seen that.  So here's an example of where you might find a decryption oracle. So when novices are writing  web applications, they frequently write one particular kind of file inclusion flaw in a  script that's supposed to just make their lives easier. So essentially what they're doing is  including a header, some page that gets passed in by user input, and then a footer so that they  don't have to put the header in the footer and everything and they can change the header and  footer for all the pages arbitrarily at any time they wish. So let's say that this developer found  out, oh crap, I've got a file inclusion flaw. I know all sprinkle magic encryption dust on it. So  you encrypt the input and that way you expect nobody is going to be able to do anything with  this. Now maybe. So let's assume that the errors are verbose. So if you take some cipher text from  somewhere else, let's say that they're using the same key and initialization vector and same cipher  in some other place, you can take that cipher text and plug it in here and if it's not going to  point to some valid file, the application is going to respond by saying hey, I tried to open this  path here and it didn't work. And that path will of course include the decrypted output from this  operation. So that's an example of where you might find a decryption oracle. I put a picture of a  kitten in here so that it wouldn't be just such a wall of text. It really has no relation  whatsoever to the content. Thank you. I like the cat too. So again, we're looking for encrypted  data when we're talking about encryption oracles but in this particular case we're looking for it as  output as opposed to as input. You'll frequently find this sort of thing in cookies and hidden  variables in databases and file resident data. And then the next thing you're going to need to do is  to determine the point of entry. So when you're looking at this encrypted output, usually it'll  say, you know, it'll have some identifying information. Like maybe it'll be a variable that's in a  hidden field and that variable will be named pet's name. So you really don't want to be exposing  people's pet's names. It's very important. Very, okay, maybe not sensitive. But let's say it's pet's  name. So you're going to look for where you can input a pet's name and then whatever. So you'll  be, you can see, you can try modifying that and seeing if you get different cipher text. So some  frequently encrypted data is client side state variables. So if you're keeping track of a user's  session, certain things about their login, you want to store that on the session to keep it out of  the client's hands. But once you start to experience more traffic, that's not really a  scalable thing. You know, you start to store too much data and have too much session data. Actually  there's an OOS page on a DOS attack involving creating large numbers of sessions when people are  storing too much session data. So this causes its own problems. So some people will say, okay,  we'll let's encrypt the data and then give it to the client and they'll pass it every time they are  making a request. And that way we'll keep the state, we'll keep the session variables, but we  won't have to hold on to them. So if you control part or all of that, you have an encryption  oracle. So for instance, the view state in ask.net is frequently a partial encryption oracle. Now  its usefulness is somewhat limited in that the key being used is only used for several other  things inside ask.net. But I have seen people who just want to use one key for everything and  will actually go to great lengths to use the machine key as the same key for encryption. So  another frequently encrypted piece of data is passwords, financial data is also frequently  encrypted. Anything sensitive is often subject to encryption. So trying to modify these things  and then look for any of those encrypted pieces of data changing is a good idea. But being  encrypted is not enough, we also need to be able to manipulate it. So here's an example of where  you might find an encryption oracle. Let's say that you have an authentication cookie. So this  is a situation where you have session data that you want to store on the client, with the  client encrypted and not store as session variables and hold down the server. So consider an  authentication cookie that's the username concatenated with a colon, password hash, colon and a  time stamp. So we can't do any sort of replay attacks because of the time stamp. And we'll  assume that the usernames can't include a colon character so we don't have delimiter  injection, no field injection stuff. But this does mean that we have a partial encryption  oracle. We can't control the whole thing but we control the username. If the only restriction is  that we can't control the colon, then we can do a lot of interesting things. We can encrypt a lot  except we just can't control what goes at the end of it. Now there are definitely ways to get  around this. Does anyone know what null byte injection is? Poison null byte. Okay, so we've  got some. The poison null byte is an issue where the null byte, hex zero, is seen as some  frameworks, seen by some frameworks as just another character and others, it's a string  delimiter. So for instance when you're doing file inclusion attacks, if you're tacking dot  html onto the end of everything and thinking, well, this is fine, this is no problem, everything's  good here, they can only include html files, you put a null byte on there. Most web application  frameworks will see that as just another character but once it gets passed back to the file  system, pretty much every operating system is going to truncate at the null byte because  they're C based and C is the language in which the null byte is a string terminator. So it cuts  off the end. So we can do some similar attacks here. So the fact that we can't control the end  is actually just fine for a lot of attacks. So that's interesting. So we can register with  some username and log in and take a look at that cookie and we register with the username of  whatever it is we want to encrypt. So groovy stuff there. So I wanted to mention padding  oracles as well. So with a padding oracle, the input has to be encrypted and it has to be with  a padded block cipher. With stream ciphers, you're encrypting one byte by one byte so the end of  the cipher text, sorry, the end of the plain text is just where the text ends and not where you've  put some arbitrary marker. So it also has to be distinguishable when you've passed something  in that has valid padding or invalid padding. And this is the essence of a padding oracle. Now,  I know that with a padding oracle, you can do all sorts of crazy things and you can take over  an old ASP.NET installation. But really, all a padding oracle allows you to do is to tell whether  or not the padding was actually valid. Now, in the case of the cipher block chaining mode, where  the cipher text for each block in a block cipher is used as the initialization vector for the next  one. So as to prevent repetitive plain text from producing repetitive cipher text, you know, to  remove any sort of distinguishable patterns that might allow you to see that this is one, this is  this message and this is that message when they're encrypted. That's actually going to allow you to  change the padding bytes and then change the corresponding bytes in the previous block until  you get valid decryption again. So until you get to the point where the padding is valid again. So,  like I said, I don't want to go too much into how padding oracle attacks work. But padding oracles  can in that way be converted to decryption oracles. Now, the interesting thing is, Duong and  Rizzo who presented the padding oracles everywhere presentation also talked about an attack where  you can use this decryption oracle functionality of a padding oracle in this particular type of  situation to encrypt data. Where you're just changing the data until you get the output that you  really want. The way that it works, it might be limited in that the first block is garbled. So if  you end up finding a padding oracle and using it as an encryption oracle, you can't control the  first block. And again, there are some situations where that's not a problem, but it's  something to be aware of. So let's talk a little bit more about exploiting these crypto oracles. So,  to convert one oracle into another, most of this involves brute forcing. So we talked about  padding oracles and using them to decrypt and encrypt data. Decryption oracles can be converted  to encryption oracles. The idea is that you just brute force, guess a whole bunch of cipher  text until it decrypts to what you want it to. And that way you have the plain text you want and  your input is really what you're looking for. Now, since block ciphers do this several characters  at a time, you need to guess all of the characters in that block at the same time. So you need to  keep doing that until you get it right. So that's a little bit more complex, a little bit more  heavy on the queries. Whereas if you're talking about a stream cipher, that's one byte at a time.  So you can just guess even one bit at a time until you get exactly what you're looking for. So  encryption oracles can be converted to decryption oracles in a very similar way. And again, the  same difference between the effectiveness when you're talking about stream and block ciphers  applies. So we're going to talk about doing a little bit of crypto recon using oracles. So  let's say you have an encryption oracle. If you encrypt the same plain text twice and it comes  out to the same cipher text, you know you have the same key, same initialization vector and a  deterministic cipher being used to encrypt the data. So if the cipher texts are identical, you  know all of these things are true. You can also check for stream versus block ciphers. It's pretty  easy to tell. So you can encrypt some piece of plain text and if the size is dependent on, you  know, the size of the plain text divided by 8 or 16 or something like that, then it's a block cipher.  And if it just grows and with the plain text, no matter how many bytes you're tacking onto the end  of it, you know, linear relationship, you have a stream cipher. You can also check for ECB block  mode. So this is a little bit different from CBC, which I described earlier, in that each block is  independent of other blocks and are encrypted independently. So if you have repetitive plain text  like 8 uppercase A's, 8 uppercase B's, 8 uppercase A's, 8 uppercase B's, and that's your plain text,  your cipher text is going to have blocks 1 and 3 being identical and blocks 2 and 4 being  identical. So you can see those patterns. So you can try to show that, you can try to, you know,  guess that behavior. You can try to get it to produce that behavior with an encryption oracle.  And ECB, you know, you can obviously see how that's a problem because we can then take those blocks  and rearrange them however we like. So we can also check for stream cipher feedback. So when  you're working with a stream cipher, sometimes the encryption of some particular bit, whether or not  it gets flipped, is dependent on earlier bits in the plain text or the cipher text. What we can do to  check on that is to encrypt some plain text and then modify the beginning of it and see if the rest  gets screwed up. So let's talk about using oracles to attack some bad algorithms. So occasionally  people try to write their own crypto and it doesn't work out too well. Unless you're a  cryptographer and even then sometimes it doesn't work out so well. So let me show you some real  homespun crypto that I've seen in the wild during a pen test. So here's a plain text, hello, and  it's corresponding cipher text which is a bunch of what looks like gibberish. So I found an SQL  injection flaw but it didn't allow me to do anything but read data from the database. So I said,  okay, well, I'll get all the credentials from the database. Turns out the passwords were all  encrypted. And it was this bizarre looking stuff that doesn't really look like strong crypto. So I  thought, okay, well, let's play with this. So the first thing, I want to know if there's  substitution. Are we switching characters for others? And that's definitely true. But if we put  in four uppercase A's, we can see, yeah, there are no uppercase A's in that. There is definitely  substitution here. We can already start to see patterns in this as well. The plain text is  repetitive, the cipher text is repetitive as well. So the next thing we're looking for is if  there's transposition, if characters are being switched around before or after the substitution  occurs. So we'll submit AABB. And we see something similar to what we saw last time. And you can  already start to see patterns in this very, very quickly. So there doesn't seem to be any  transposition. And we can see more patterns. The K also seems to be a delimiter. So one thing  that you'll notice if you look at this, there are a couple different ‑‑ you can have different  lengths with these characters. So the K is just standing in to separate characters so that even  with variable lengths for the cipher text version of different characters. Well, let's move on. So  it also doesn't seem to change on position. So next thing we do is we submit a variation on the  last pattern. And we notice that, you know, more of our assumptions are proving to be true.  That, you know, A, like this ABE is uppercase B and LO is A. So this is pretty much exactly what we  expected. The substitution doesn't seem to change no matter where the character is in the plain  text. So next thing we'll do is just submit every character. And we get back the entire key. So we  see what every character is substituted to. So this is a trivially weak cipher. And the oracle has  helped us just totally destroy this cipher. So more bad algorithm stuff. Some people use ZOR to  encrypt data. The funny thing about ZOR is that it has this weird property. So if we use an XOR  operation between a plain text and its corresponding cipher text, we get the key. So that's  ugly. And you really don't want to be using ZOR. So another thing about ZOR, for some simple  ciphers like ZOR, the encryption routine is the decryption routine. Thus, an encryption oracle is  also a decryption oracle. Which means that I can encrypt or decrypt any data that you're  using. Which essentially means that this encryption is totally useless as soon as an  encryption oracle is introduced. And even before that actually. So please don't use ZOR. So now I'm  going to do a demonstration. We're going to take a look at the default encryption algorithm in  cold fusion. The CFMX compact algorithm. Now, I did a little bit of Googling on this and found  that everyone said, hey, don't use this algorithm. This is weak. Adobe says this is the weakest  cipher that we have. But for some reason they make it the default one that you use. So, okay. So I  have... So, I have a little bit of a  bit of a... Oops. What? Oh, hey. Thanks guys. So, I have a little bit of a... So, I have  a little bit of a... So, this is a simple script I wrote in cold fusion to take a plain text. And  let me turn intercept off here for a moment. And it will return to me the cipher text of whatever I  put in. So, this is just a very contrived example of an encryption oracle. So, here's  something interesting. I've changed the end of this and we immediately see modification in the  cipher text. And if I continue to delete characters here, you can see that this is chopping off more  and more of the cipher text. Which means that this is a stream cipher. And also because we can  see this changing... But the prefix remains the same. That this is also a stream... That this is  also using the same key, same IV and a deterministic cipher. So, next thing that we can do is  change the beginning here. And we can see that the end doesn't change. So, we're not talking about  any sort of feedback going on, apparently. So, this is interesting. Now, what this actually  means, because stream ciphers, essentially, once it comes down to it, are just crosswise or with a  nice and complex key generation algorithm. And the only thing separating it from that in essence  is this feedback. So, not having feedback is really bad. So, we're going to see why, right,  about now. Now, here's something interesting. So, can anybody tell me what X crosswise door with  null is? X. So, if we're essentially... If we have a cipher that's essentially crosswise or and we  put in null as the plain text, what are we going to get as the cipher text? The key, the key  stream. So, I'm going to get the first six bytes of the key stream here. And I'm going to copy this  into burp, which is a lovely tool. And decode this as base 64. So, we have the first six bytes of the  key stream here, which is great. So, we're going to stick that into... Oh, no, I don't want that. All  right. Lovely. Okay. So, next thing we'll do here, we'll get a cipher text sample. What are you  doing? So, here's the encrypted version of the word DEF CON. So, let's copy that, put that into  decoder. And now, I'm going to do a little bit of ZOR here. So, we're going to copy this into  the decoder. And now, we're going to copy this into the decoder. And we're going to copy this into the  decoder. So, hex 42, crosswise OR with hex 26. So, we have a D. And then, an E. And then, an E. And then,  we can go on and on like this and crosswise OR this key stream with whatever cipher text we have and  decrypt it. So, groovy stuff. Because we already have an encryption oracle, that's nice. Now, one  funny thing is that if we... Like I said, since this comes down to essentially just crosswise OR, if  we have plain text and corresponding cipher text, we can actually just crosswise OR those two  together and get the key stream anyway. So, we don't even need an encryption oracle now that we  figured all of this out. So, in case the point hasn't been made clear yet, if you're using cold  fusion, pick a different algorithm than the default. Right. So, now, let's say that we don't have a  shitty cipher. Let's say that we're using something like AES. And let's say we're even using it in a  really, really decent way. So, the thing is people tend to reuse keys in IV. So, let's say that the  only mistake we're making here is to reuse the same key in IV in multiple places. And a lot of  people do that because they figure, well, if somebody can break in and figure out the key, then  I... You know, what's the big deal? So what? So what if I'm using it? It's the same stuff in  different places. The other thing is that if developers don't think that you can mess with  input, if they don't think that you can fiddle with it at all, they might not sanitize it. And the  fact they probably won't sanitize it. And you would think that if you're using a message  authentication code, which I won't go into explaining that, but essentially it provides  protection against modification, you would think that this is tamper proof, that there is no way  that this needs to be sanitized. So why bother? Why spend the cycles? So let's say that you have an  encrypted password, Mac, in a cookie, like this auth cookie that we're talking about. And that's  checked against the database on each request needing authentication. You find an encryption  oracle somewhere else that allows you to encrypt arbitrary data. So you encrypt single quote or  one equals one. Let's say it's just a password that's in this cookie and then plug the resulting  value into the cookie. Well, that's ugly. So let's take a look at this in action. So here we  have a little login script that takes a username and a password. And this is what it looks like  when you log in successfully. So let's take a look at this in the history here. This resolution is  killing me. So this is ugly because it passes in the URL and that's terrible, but ignore that.  Ignore me. Thank you. So you can see that this sets a username and password cookie. Now if we  stay on this page, if we just go back to it, you'll note two things. We're still logged in here,  but it still shows us the login prompt. Now something else that's interesting, the username  field is populated. And if we look at the response, all we saw was the cookies. Hold on a  second. Yeah. So all we see as for the parameters in the request are this encrypted username and  password cookie. So this is actually decrypting the cookie and then sticking it in the output.  So we've got a decryption oracle here, but it's not what we're talking about right now. Now  let's try some SQL injection here. Let's clear the cookies. And then try admin or double single  quote equals double single quote. And we'll put the same thing in the password. So we take a look at the  username here and notice that these single quotes are filtered out. They're removed. Now  people will generally filter the username but not the password because it's going, you know, if  it's going to be hashed and then stuck in a database, then who cares? The thing is though, but in  this particular scenario, just a spoiler, this password parameter is not being filtered  before it gets hashed. So we see that the username and password fields are the same and in the  response, we get different ciphertext for the username and the password. So we can say to  ourselves, maybe this password parameter is not being filtered. So let's copy that and use that as  our username cookie as well. If it works, we should have SQL injection. Maybe. So we go back to the  index and let's turn intercept on and burp so I can actually catch this as it goes. So we'll  grab the password cookie which contains the SQL injection string encrypted and stick that into  the username parameter. Hit forward. Oh, that's ugly. Well, that's what I get for doing a live  demo, I guess. Let's try this again. Yeah, that's ugly. So we can see that the password is  not being filtered. All right, well, I'm not going to waste any more time on this live demo. It  works. So we get logged in and it bypasses the SQL injection checks where we would not have been  able to by simply putting the strings directly into the username or password field. So groovy  stuff. I'm sorry, it didn't work. So let me just log in with the valid credentials and I'll show  you the next portion. So we have a couple different URLs here that we now have access to. And if we  take a look at the input here, we have some sort of ciphertext being passed to a file parameter in  get files.cfm. And I wish the resolution was a bit bigger because it would be easy to see that the  beginning of the ciphertext, so here we see 9 slash f, 9 slash f. So these ciphertexts are starting  with the same thing. Now, I wonder what would happen if we were to plug that data in here. So we get an  error which decrypts that ciphertext for us. So we have another decryption oracle here. We also can  encrypt arbitrary data so we can just stick anything into the password field and then grab the cookie  and put it somewhere else. So let's do that. So what I'm going to do is to access a file in this  test bed called secretdata.txt which is in the root. And so I'm going to put a whole bunch of dot dot  slash secretdata.txt and then we can just plug it in here. So we can just plug it in here and then  we'll have this attack string as our password cookie. All right, everybody think good thoughts.  Well, that's ugly as well. But you can see what I was trying to do here. Apparently I needed more dot  dot slashes. But you can see how this was working and you would have seen my secret love for Moxie  Marlin's bike. Also a little sec APT return on investment. So I'm going to go ahead and  do that. Exactly. I encrypt whatever password I like and in the cookie I get the cipher text for  it. Yeah. It absolutely would. Yeah, the user name field is another decryption oracle. And actually, let's, and I think  let's see that real quick. That's a demo I know will work. I say that now. So intercept on fire. Okay. So we'll  take this password cookie and put that into the user name field. Hit forward and then we can put that  in the user name field. And now we can see the decrypted version of that cipher text. Thanks for  mentioning that by the way. I nearly forgot about that one. So that's a nice way to point out this next  portion which is that with a decryption oracle any cipher text that uses that same key initialization  vector cipher is subject to decryption if you can just find a decryption oracle. And maybe you've seen  already that this is not too hard to do. It's a matter of making the right mistakes. So we already saw  that. So that demo is done. So one last take home point that I want to make is that if you can find an  encryption oracle and a decryption oracle, it doesn't matter what you're using. As long as keys and  IVs are reused by the way that cryptography works, anything that's encrypted and decrypted with the  same key IV cipher is going to be the plain text. So whatever cipher you're using, whatever key you're  using, whatever padding you're using, whatever cipher mode you're using, it doesn't matter if you  can find an encryption or decryption oracle. Anything with that same key IV and cipher is now as  good as plain text. So what can you do? I don't want to make too many suggestions because like I  said, not a cryptographer and the suggestion I might give you might be vulnerable to some other  attack. Right now, I think there's a problem in that it's hard to do crypto right. Unless you're a  cryptographer. I think keys are as nice because it just says, hey, encrypt, decrypt, and you don't  have to specify an algorithm in a padding mode and have to know what all that entails. But there's  still some, obviously giving out information is bad. Leaking output from cryptographic operations is  bad. Try not to give the output. Now, in certain circumstances like the example of the encrypted  session data, that's ugly and there's not really a great way that you can do that right. One thing  that you can do, however, is to use a different IV. Don't reuse keys and IVs if you can help it. So  that's good stuff. Try to suppress any indication of success or failure if you can. Again, that's not  really terribly plausible in a lot of situations. And timing, if you really want to go the extra  mile, try to suppress that. But that's, I think, more trouble than it's worth. It's worth noting,  however, that timing information can give away the success or failure of an operation. Also  authenticating your crypto is a good idea. Encryption is good, but if people can fiddle around  with the message and end up with a valid output, a valid cipher text, it will still be subject to  whatever operation it was going through before. And in some cases, it doesn't matter what the plain  text actually is. So, for instance, if you have an encrypted value which represents the amount of  money you have in your bank account, your chances are pretty good of getting something better than  zero. So if you're at zero and you just mess around with the cipher text and you can produce a  valid cipher text, it's probably better than zero. So authentication is good because it doesn't, it  prevents people from messing with that, at least to some degree. Also, you want to encrypt and then  MAC, if you MAC and then encrypt, it still allows for padding oracle attacks. So that's it. If you  have any questions, I'd like you to come to the Track 2 QA room and ask them there. So no  questions right now. Thank you.
DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_0_3023.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_3024_3455.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_3456_9323.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_9324_10343.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_10344_11687.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_11688_19235.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_19236_19835.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_19836_30743.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_30744_36131.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_36132_40595.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_40596_41279.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_41280_42119.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_42120_42359.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_42360_42407.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_42408_42551.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_42552_43535.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_43536_43715.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_43716_44435.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_44436_48623.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_48624_51443.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_51444_53903.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_53904_53951.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_53952_54083.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_54084_54599.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_54600_55163.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_55164_55283.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_55284_55751.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_55752_56207.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_56208_56291.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_56292_57443.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_57444_58571.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_58572_60107.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_60108_61391.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_61392_62711.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_62712_63395.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_63396_64739.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_64740_64967.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_64968_65555.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_65556_65963.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_65964_66155.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_66156_66791.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_66792_67991.png DEF_CON_19_-_Daniel_Crowley_-_Speaking_with_Cryptographic_Oracles_pq6s757Lj7E_1_67992_72747.png